Указатель на массив
|
|
JSent | Дата: Воскресенье, 21 Сентября 2014, 17:17 | Сообщение # 1 |
постоянный участник
Сейчас нет на сайте
| Запутался с указателями. Проблема такая: Допустим у нас есть указатель на массив int *mas = new int[n]; Но нужно обращаться к элементам массива без использования квадратных скобок. Например:
Код int main() { int n=5; int *mas = new int[n]; *mas = 1; *(mas+1) = 2; printf("%d %d",*mas, *(mas+1)); getch(); return 0; }
Работает прекрасно, записывает значения в 1 и 2 элемент и выводит их.
Проблемы появляются с двумерным массивом:
Код int main() { int n=5; int **mas = new int*[n]; *(*mas) = 1; printf("%d",*(*mas)); getch(); return 0; }
Сделал по аналогии, но программа крашится. В чём я не прав?
Программист — человек, больной тяжёлой формой поражения коры головного мозга — интеллектом, который выражается в маниакально-деструктивном стремлении писать непонятные и бессмысленные наборы символов и словосочетаний.
|
|
| |
pelmenka | Дата: Воскресенье, 21 Сентября 2014, 17:30 | Сообщение # 2 |
Драгоценный Тунеядец
Сейчас нет на сайте
| Зачем тебе так извращаться? А вообще *(*(mas+i)+j) И да, это не двумерный массив, а просто массив указателей
Сталина в каждый дом!
Сообщение отредактировал pelmenka - Воскресенье, 21 Сентября 2014, 17:31 |
|
| |
JSent | Дата: Воскресенье, 21 Сентября 2014, 17:31 | Сообщение # 3 |
постоянный участник
Сейчас нет на сайте
| pelmenka, не знаю, препод в универе так требует. Сейчас попробую.
Программист — человек, больной тяжёлой формой поражения коры головного мозга — интеллектом, который выражается в маниакально-деструктивном стремлении писать непонятные и бессмысленные наборы символов и словосочетаний.
|
|
| |
pelmenka | Дата: Воскресенье, 21 Сентября 2014, 17:35 | Сообщение # 4 |
Драгоценный Тунеядец
Сейчас нет на сайте
| Вообще двумерный массив делается так: Код int **arr = new int*[n]; for(int i = 0; i < n; i++) arr[i] = new int[m];
Сталина в каждый дом!
Сообщение отредактировал pelmenka - Воскресенье, 21 Сентября 2014, 17:36 |
|
| |
JSent | Дата: Воскресенье, 21 Сентября 2014, 17:41 | Сообщение # 5 |
постоянный участник
Сейчас нет на сайте
| pelmenka, это само собой Просто пока разбираюсь, как без [ ] обойтись.
Программист — человек, больной тяжёлой формой поражения коры головного мозга — интеллектом, который выражается в маниакально-деструктивном стремлении писать непонятные и бессмысленные наборы символов и словосочетаний.
|
|
| |
MrAkakuy | Дата: Воскресенье, 21 Сентября 2014, 17:59 | Сообщение # 6 |
участник
Сейчас нет на сайте
| JSent, вы, сударь, на этом моменте Код int *mas = new int[n]; выделяете память под n переменных типа int.
На этом моменте, мсье, Код int **mas = new int*[n]; вы выделяете память под n указателей на память, которую вам использовать запрещено. Так как указатели вы не инициализировали, их использовать низя.
А потому делается это так: Код int main() { int n=5; int **mas = new int*[n]; for(int i = 0; i < n; i++) mas[i] = new int[n]; *(*mas) = 1; printf("%d",*(*mas)); getch(); return 0; }
Пользуйтесь-с.
|
|
| |
Lightsoft | Дата: Воскресенье, 21 Сентября 2014, 18:04 | Сообщение # 7 |
частый гость
Сейчас нет на сайте
| В си / c++ двумерный массив - это массив массивов. Выделяем память под M указателей, каждый из которых будет указывать на одномерный массив из N элементов. Код int _tmain(int argc, _TCHAR* argv[]) { const size_t M = 5; const size_t N = 4;
int** _array = new int*[ M ];
for ( size_t i = 0; i < M; i++ ) { *( _array + i ) = new int[ N ]; }
int count = 0;
for ( size_t i = 0; i < M; i++ ) { for ( size_t j = 0; j < N; j++ ) { *( *( _array + i ) + j ) = ++count;
std::cout << ( *( *( _array + i ) + j ) ) << " "; } std::cout << std::endl; }
for ( size_t i = 0; i < M; i++ ) { delete[] *( _array + i ); }
delete[] _array;
return 0; }
Сообщение отредактировал Lightsoft - Воскресенье, 21 Сентября 2014, 21:04 |
|
| |
pelmenka | Дата: Воскресенье, 21 Сентября 2014, 18:05 | Сообщение # 8 |
Драгоценный Тунеядец
Сейчас нет на сайте
| Ты не понял. Все в принципе было ок, ты присваивал mas[0][0] 1 и выводил mas[0][0] Но память под этот самый mas[0][0] не была выделена, поэтому все и падало.
Сталина в каждый дом!
|
|
| |
JSent | Дата: Воскресенье, 21 Сентября 2014, 19:55 | Сообщение # 9 |
постоянный участник
Сейчас нет на сайте
| Теперь всё работает, но не всё понятно. Почему мы можем написать **mas=1;, но не можем *mas=1; ? Ведь в обоих случаях указатель указывает на первый элемент первого массива.
Программист — человек, больной тяжёлой формой поражения коры головного мозга — интеллектом, который выражается в маниакально-деструктивном стремлении писать непонятные и бессмысленные наборы символов и словосочетаний.
|
|
| |
Lightsoft | Дата: Воскресенье, 21 Сентября 2014, 20:36 | Сообщение # 10 |
частый гость
Сейчас нет на сайте
| Цитата JSent ( ) Почему мы можем написать **mas=1;, но не можем *mas=1; Потому что у первой конструкции **mas тип int, а у второй int * ( указатель на переменную типа int ) т.е. вы пытаетесь записать в указатель свое значение. Ваше значение становится адресом вместо того, который был выделен через new в цикле for под каждый одномерный массив.
это аналог Код * ( * ( mas + 0) + 0 ) = 1; или
это или
Сообщение отредактировал Lightsoft - Воскресенье, 21 Сентября 2014, 20:57 |
|
| |
LetsOffBrains | Дата: Воскресенье, 21 Сентября 2014, 21:16 | Сообщение # 11 |
Project SoRDeLKa
Сейчас нет на сайте
| *mas указатель на указатель жеж. без второй звездочки-декодирования(хз как назвать) не в тот участок памяти смотрит.
|
|
| |
Lightsoft | Дата: Воскресенье, 21 Сентября 2014, 22:05 | Сообщение # 12 |
частый гость
Сейчас нет на сайте
| LetsOffBrains, это разыменованием указателя называется.
Сообщение отредактировал Lightsoft - Воскресенье, 21 Сентября 2014, 22:06 |
|
| |
JSent | Дата: Воскресенье, 21 Сентября 2014, 23:10 | Сообщение # 13 |
постоянный участник
Сейчас нет на сайте
| Ещё один момент со считыванием данных. Вот так работает без проблем:
Код for(int i=0;i<2;i++) (*(*mas+i)) = getchar();
А здесь начинает ругаться компилятор, наверное, слагаемое к в левой части ему не нравится: Код for(int i=0;i<2;i++) for(int k=0;k<2;k++) (*(*mas+i)+k) = getchar();
Как ещё в *(*mas+i)+k можно записать данные?
Программист — человек, больной тяжёлой формой поражения коры головного мозга — интеллектом, который выражается в маниакально-деструктивном стремлении писать непонятные и бессмысленные наборы символов и словосочетаний.
|
|
| |
Xakep | Дата: Воскресенье, 21 Сентября 2014, 23:17 | Сообщение # 14 |
めちゃくちゃちゃ
Сейчас нет на сайте
| наверное правильнее так будет:
Код for (int i = 0; i < 2; i++) for (int k = 0; k < 2; k++) *(*(mas+i)+k) = getchar(); Добавлено (21.09.2014, 23:17) --------------------------------------------- т.к. у тебя mas указатель на указатель, мы задаем смещение указателю, а у тебя получается прибавляется уже к разыменовоному на второй раз указателю прибавляешь k и пытаешься этому выражению присвоить getchar(); так нельзя )
|
|
| |
JSent | Дата: Воскресенье, 21 Сентября 2014, 23:22 | Сообщение # 15 |
постоянный участник
Сейчас нет на сайте
| Xakep, так компилятор не ругается, но данные записываются куда-то не туда( Вот так всё точно работает (*(*mas+i)), просто +к добавлять не получится, так как к сумме присваивать нельзя.
Программист — человек, больной тяжёлой формой поражения коры головного мозга — интеллектом, который выражается в маниакально-деструктивном стремлении писать непонятные и бессмысленные наборы символов и словосочетаний.
|
|
| |
Xakep | Дата: Воскресенье, 21 Сентября 2014, 23:25 | Сообщение # 16 |
めちゃくちゃちゃ
Сейчас нет на сайте
| Цитата JSent ( ) Вот так всё точно работает (*(*mas+i)), просто +к добавлять не получится, так как к сумме присваивать нельзя. во первых если тебе нужен двумерный массив, то так не првильно делать, ты разыменовывешь указатель и прибавляешь смещение, а нужно сначала прибавить смещение, а потом уже разыменовывать, чтобы можно было работать с другим указателем, который лежит в ячейке памяти mas+i. Если у тебя не работает, значит где-то в другом месте напортачил.
|
|
| |
JSent | Дата: Воскресенье, 21 Сентября 2014, 23:40 | Сообщение # 17 |
постоянный участник
Сейчас нет на сайте
| Логично. Надо будет на свежую голову всё проверять.
Программист — человек, больной тяжёлой формой поражения коры головного мозга — интеллектом, который выражается в маниакально-деструктивном стремлении писать непонятные и бессмысленные наборы символов и словосочетаний.
|
|
| |
Xakep | Дата: Воскресенье, 21 Сентября 2014, 23:45 | Сообщение # 18 |
めちゃくちゃちゃ
Сейчас нет на сайте
| Цитата JSent ( ) Логично. Надо будет на свежую голову всё проверять. можешь сюда кинуть код, поправлю и ошибки расскажу.
|
|
| |
Lightsoft | Дата: Воскресенье, 21 Сентября 2014, 23:55 | Сообщение # 19 |
частый гость
Сейчас нет на сайте
| Еще могу посоветовать обратиться к таблице приоритетов операторов. Хакер правильно сказал, что сначала по приоритету идет разыменование, а потом сложение, по этому необходимы скобки для указания смещения, а после уже разыменование.
|
|
| |
JSent | Дата: Понедельник, 22 Сентября 2014, 00:00 | Сообщение # 20 |
постоянный участник
Сейчас нет на сайте
| Код int main() { int length,countString,ind; char c; //задаём размеры printf("Enter the length of the string and the number of rows:\n"); scanf("%d %d", &length,&countString); //выбор сортировки (по возрастанию или убыванию) printf("Ascending or descending? (0 or 1)\n"); scanf("%d", &ind); //создаём динамический массив char **mas = new char*[countString]; for(int count = 0; count<countString; count++) *(mas+count) = new char[length]; //заполняем массив printf("Enter the values of the array:\n"); for(int i = 0; i<countString; i++) for(int k = 0; k<length; k++) *(*(mas+i)) = getchar(); //тест putchar(**mas); putchar(*(*(mas+1))); //функция сортировки строк методом Шелла //вывод результата getch(); return 0; }
Программист — человек, больной тяжёлой формой поражения коры головного мозга — интеллектом, который выражается в маниакально-деструктивном стремлении писать непонятные и бессмысленные наборы символов и словосочетаний.
Сообщение отредактировал JSent - Понедельник, 22 Сентября 2014, 00:02 |
|
| |