Форум программистов, компьютерный форум CyberForum.ru

С++ для начинающих

Войти
Регистрация
Восстановить пароль
 
Lyosha12
6 / 6 / 0
Регистрация: 02.04.2016
Сообщений: 135
#1

Не могу определить причину "магической" операции присвоения - C++

02.04.2016, 18:11. Просмотров 228. Ответов 9
Метки нет (Все метки)

Суть такая: написал посимвольный парсер для консоли. До недавнего времени работал как часы. Обращаюсь сюда по тому, что понять не могу причину такой магии:

При присвоении значения элементу массива [0][1], значение присваивается и [0][1], и [1][0]. Как? Я не вижу, чтобы я то увеличивал индекс строк и уменьшал индекс столбцов, то возвращал их обратно (я бы такую конструкцию заметил -_-)

Моё творение:
Кликните здесь для просмотра всего текста
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
#include <stdio.h>
#include <math.h>
#include <iostream>
using namespace std;
 
#define size 50
bool isNegative = false;
 
int invert_number(int current){
    int newCurrent = 0, F = current, number_count = 0;
    while(abs(F) > 0){
        F /= 10;
        number_count++;
    }
 
    int i = --number_count; int j = 0;
    while(abs(current) > 0){
        newCurrent += (current/pow(10,(double)i))*pow(10,(double)j++);
        current %= (int)pow(10,(double)i--);
    }
    if(isNegative == true){
        isNegative = false;
        return -newCurrent;
    }
    else
        return newCurrent;
}
 /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
void main(){setlocale (0,"");
    int MN1[size][1], MN2[size][1], countMN1, countMN2;
 
    for(int i = 0; i < size; i++){
        MN1[i][0] = 0; MN1[i][1] = 0; 
        MN2[i][0] = 0; MN2[i][1] = 0;
    }
    cout<< " Введите количество заданных точек первого множества (<" << size << "): ";
        cin >> countMN1; 
    cout<< " Введите количество заданных точек второго множества (<" << size << "): ";
        cin >> countMN2; 
 
                for(int i = 0; i < countMN1; i++) {
                if(i%3 == 0) 
                    cout<< endl << "\tТочка A" << i << ": (" << MN1[i][0] << "," << MN1[i][1] << "); ";
                else 
                    cout<< "\tТочка A" << i << ": (" << MN1[i][0] << "," << MN1[i][1] << "); "; 
            }
            cout<< endl;
 
    cout<< " Введите " << countMN1 << " точек первого множества в формате "x1,y2 x2,y2 ...":\n -> ";
 
 
    /* -------------------------- Парсер -------------------------- */
    int number_pos = 0, index_x = 0; char this_char = 0, x_or_y_next = 'X';
 
 
    while(index_x < countMN1){
        /* Получение символ слева направо */
        this_char = getchar();
        
        /* Если символ - минус */
        if(this_char == '-'){ 
            isNegative = true; continue;
        }
 
        /* Получение цифр из символов для координат X1 и Y1 точки A */
        if(this_char >= '0'  &&  this_char <= '9'  &&  x_or_y_next == 'X'){ MN1[index_x][0] += (-'0' + this_char) * pow(10,(double)number_pos); number_pos++; continue; }
        if(this_char >= '0'  &&  this_char <= '9'  &&  x_or_y_next == 'Y'){ 
            MN1[index_x][1] = MN1[index_x][1] + (-'0' + this_char) * pow(10,(double)number_pos); 
            number_pos++; 
            continue; }
 
        /* Обработка запятой после коордиаты X1 */
        if(this_char == ',' && x_or_y_next == 'X') {
            MN1[index_x][0] = invert_number(MN1[index_x][0]); 
            x_or_y_next = 'Y'; number_pos = 0; continue; }
 
        /* Обработка пробела и новой строки после координаты Y1 */
        if((this_char == ' ' || this_char == 10) && x_or_y_next == 'Y') {
            MN1[index_x][1] = invert_number(MN1[index_x][1]);
            number_pos = 0; index_x++; x_or_y_next = 'X'; 
            continue; }
 
        /* Обработка перевода строки \ подтверждения ввода */
        if(this_char == 10) continue;
 
    }
 
    cout<< endl;
 
            for(int i = 0; i < countMN1; i++) {
                if(i%3 == 0) 
                    cout<< endl << "\tТочка A" << i << ": (" << MN1[i][0] << "," << MN1[i][1] << "); ";
                else 
                    cout<< "\tТочка A" << i << ": (" << MN1[i][0] << "," << MN1[i][1] << "); "; 
            }
            cout<< endl;
 
    /* ---------------------------- Конец парсера -------------------------- */
    system("pause");
}


Проблема наблюдается в этом участке:
C++
1
2
3
        if(this_char >= '0'  &&  this_char <= '9'  &&  x_or_y_next == 'Y'){ 
            MN1[index_x][1] = MN1[index_x][1] + (-'0' + this_char) * pow(10,(double)number_pos); 
            number_pos++;
Могу даже видео прикрепить, если не верите .-.
Кликните здесь для просмотра всего текста
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
02.04.2016, 18:11     Не могу определить причину "магической" операции присвоения
Посмотрите здесь:

C++ Уменьшение значений элементов матрицы(перегрузка операции "--")
Определить "Y" с точностью до члена ряда меньшего "e"(допустим: 0.001) C++
Определить, каких букв в тексте больше: "м" или "н" C++
C++ Описать класс "множество", позваляющий выполнять основные операции
C++ Определить, сколько в строке символов "*", ":", ";"
C++ Ввести имя фамилию и отчество как одно данное типа строка. Определить длину строки и количество гласных в нем. Удалить все буквы "а" и "о" в фамилии.
C++ Определить количество слов, которые содержат ровно четыре буквы "о", "О"
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
yrceus
81 / 81 / 54
Регистрация: 25.08.2013
Сообщений: 326
02.04.2016, 18:57     Не могу определить причину "магической" операции присвоения #2
Потому что с массивами не разобрались Строки, столбцы, его лучше так не представлять. Массив это подряд идущие адреса памяти, каким бы он многомерным не был. То есть если есть двумерный массив, как говорят, из пяти строк и например семи столбцов arr[5][7], то это просто отрезок памяти подряд идущих пяти массивов по семь элементов. [0][1][2][3][4][5][6][0][1][2][3][4][5][6]... и т.д. еще три массива.
И если вы промахнетесь с индексом "в первой строке", например arr[0][9] то попадете на следующую "строку" arr[1][2].
А у вас же совсем интересно, фактический одномерный массив из 50 элементов называется двумерным массивом из 50 "строк" по одному элементу MN1[50][1]
Поэтому MN1[0][1] и MN1[1][0] это один и тот же элемент массива, одна ячейка памяти)))))

Добавлено через 5 минут
вот так выглядит ваш массив MN1[0][1][2][3][4][5][6]...[49]

MN1[1][2] это вот этот элемент MN1[0][1][2][*][4][5][6]...[49] и MN1[2][1] это тоже этот элемент MN1[0][1][2][*][4][5][6]...[49]
Lyosha12
6 / 6 / 0
Регистрация: 02.04.2016
Сообщений: 135
02.04.2016, 19:19  [ТС]     Не могу определить причину "магической" операции присвоения #3
Цитата Сообщение от yrceus Посмотреть сообщение
Поэтому MN1[0][1] и MN1[1][0] это один и тот же элемент массива, одна ячейка памяти)))))
Почему? О_О
Если массивы нумеруются от нуля, то, да, у меня должен быть массив из 50 строк. Но я же и указываю, что в этих пятидесяти строках будут сидеть только 2 элемента, то есть таблица будет иметь размер "50 строк на 2 столбца". И я обращаюсь к i-ой строке нулевого или первого столбца. Разве нет?
yrceus
81 / 81 / 54
Регистрация: 25.08.2013
Сообщений: 326
02.04.2016, 19:23     Не могу определить причину "магической" операции присвоения #4
В каждой строке у вас сидит только один элемент
C++
1
int MN1[size][1], MN2[size][1],
Lyosha12
6 / 6 / 0
Регистрация: 02.04.2016
Сообщений: 135
02.04.2016, 19:24  [ТС]     Не могу определить причину "магической" операции присвоения #5
Так, окей. Поставил количество столбцов 2 в определении. Теперь вернулся к изначальному варианту без магии. Но почему? Я не понимаю! Объясните, пожалуйста, подробнее: почему я не могу обратиться к элементу массива MN[0][1], не затронув MN[1][0]? Индексы же нумеруются с нуля! о_О
yrceus
81 / 81 / 54
Регистрация: 25.08.2013
Сообщений: 326
02.04.2016, 19:24     Не могу определить причину "магической" операции присвоения #6
Индексируются от нуля, а вот резервируются(определяются) от единицы
Lyosha12
6 / 6 / 0
Регистрация: 02.04.2016
Сообщений: 135
02.04.2016, 19:27  [ТС]     Не могу определить причину "магической" операции присвоения #7
Значит, если я пишу, что хочу массив 50x2, то в определении я должен написать [51][2]?
yrceus
81 / 81 / 54
Регистрация: 25.08.2013
Сообщений: 326
02.04.2016, 19:30     Не могу определить причину "магической" операции присвоения #8
Сообщение было отмечено автором темы, экспертом или модератором как ответ
Если создадите двумерный массив из пятидесяти массивов по два элемента
C++
1
int MN1[size][2], MN2[size][2],
то MN[0][1] и MN[1][0] будут разные элементы

Добавлено через 2 минуты
Если хотите 50х2 то и пишите 50х2, а если хотите 50 массивов по одному элементу пишите 50х1... и колдуете MN[0][1] == MN[1][0]
Lyosha12
6 / 6 / 0
Регистрация: 02.04.2016
Сообщений: 135
02.04.2016, 19:41  [ТС]     Не могу определить причину "магической" операции присвоения #9
Хоть я это пока ещё не понимаю, но запомню, что указав количество строк 50, я получу строки с индексами 0...49. А указав количество столбцов 2, я получу 0...1. Или это неправильно и нужно обращаться к ним как 1...2?

Добавлено через 9 минут
Понятно. Просто отниму единицу от указанного размера массива и получу количество созданного, включая ноль. Спасибо. Шарики за ролики в какой-то момент точно заехали, в поисках "производительности" xD
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
02.04.2016, 19:45     Не могу определить причину "магической" операции присвоения
Еще ссылки по теме:

C++ Определить длину каждого слова. Удалить все буквы "а" и "о" с фамилии
C++ Перегрузка операции "*" для умножения одномерных массивов
Шаблонный класс "множества". Операции над множествами C++
Определить длину каждого слова строки, и если она четная, то вставить в середину слова "aa", иначе "а" C++
Не понимаю причину ошибки "Statement missing ;" C++

Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
yrceus
81 / 81 / 54
Регистрация: 25.08.2013
Сообщений: 326
02.04.2016, 19:45     Не могу определить причину "магической" операции присвоения #10
Сообщение было отмечено автором темы, экспертом или модератором как ответ
Повторюсь, выражение "строки" сбивает с толку. Представляйте не строку, а массив, если есть 50 строк по 1 столбцу, это пятьдесят массивов по одному элементу, которые находятся непрерывно в памяти(подряд). И если вы обращаетесь например к первому и единственному элементу третьего массива, то это выглядит так arr[2][0], но в случае если вы случайно обратитесь ко второму элементу третьего массива arr[2][1](которого якобы нет) ошибки не будет, вы получите доступ уже к третьему массиву(строке) из одного элемента. Ошибка будет если вы уже выйдете из границ памяти этого двумерного массива массивов.
Yandex
Объявления
02.04.2016, 19:45     Не могу определить причину "магической" операции присвоения
Ответ Создать тему
Опции темы

Текущее время: 17:40. Часовой пояс GMT +3.
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2017, vBulletin Solutions, Inc.
Рейтинг@Mail.ru