Понедельник, 09 Декабря 2019, 14:00

Приветствую Вас Гость

[ Новые сообщения · Игроделы · Правила · Поиск ]
  • Страница 1 из 2
  • 1
  • 2
  • »
Форум игроделов » Программирование » C/C++ » Указатель на массив (Help)
Указатель на массив
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, это само собой smile Просто пока разбираюсь, как без [ ] обойтись.

Программист — человек, больной тяжёлой формой поражения коры головного мозга — интеллектом, который выражается в маниакально-деструктивном стремлении писать непонятные и бессмысленные наборы символов и словосочетаний.
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=1;
это аналог
Код
* ( * ( mas + 0) + 0 ) = 1;
или
Код
mas[0][0] = 1;


Код
*mas=1;
это
Код
*( mas + 0 ) = 1;
или
Код
mas[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
Форум игроделов » Программирование » C/C++ » Указатель на массив (Help)
  • Страница 1 из 2
  • 1
  • 2
  • »
Поиск:

Все права сохранены. GcUp.ru © 2008-2019 Рейтинг