Программа на языке Си с ложными значениями приращения указателя

#c #arrays #pointers

#c #массивы #указатели

Вопрос:

Мне интересно, может ли кто-нибудь помочь мне со следующей программой на C, которую я создаю. Код просто создает указатель, которому затем присваивается адрес массива целых чисел. Оттуда указателю присваивается значение, а затем увеличивается. На выходе отображается имя массива, адрес массива и значение массива. Вывод работает так, как ожидалось, за исключением того, что последний элемент в массиве увеличился на 5, а не на единицу.

Код показан ниже :

 #include <stdio.h>

main()
{
    int numar[4];       //integer array
    int x;              //value for loop
    int *p;             //pointer
    p=numar;            //'point' p to address of numar array (no amp; necessary as arrays are pointers)
    for(x=0;x<5;x  )    //loop 0-4
    {
        *p=x;           //assign the value of the first item in array to x
        p  ;            //increment pointer for next iteration 
    }
    for(x=0;x<5;x  )    //loop 0-4
    {
        //display output of array name, array location and array value
        printf("array[%d] is at address %p with value %dn", x,amp;numar[x],numar[x]);
    }
    return 0;
}
  

Результат приведенного выше кода показан ниже :

 array[0] is at address 0061FF18 with value 0
array[1] is at address 0061FF1C with value 1
array[2] is at address 0061FF20 with value 2
array[3] is at address 0061FF24 with value 3
array[4] is at address 0061FF28 with value 8
  

Как вы можете видеть, желаемое значение для array[4] должно быть 4, но вместо этого оно равно 8.

Любая помощь была бы высоко оценена.

Большое спасибо,

Комментарии:

1. int numar[4]; но, похоже, вы обращаетесь к индексу 4 (допустимый максимум равен 3), поэтому вы запускаете конец массива и вызываете неопределенное поведение. А вот и назальные демоны….

2. [4] означает, что массив содержит 4 элемента

3. Массивы не являются указателями. (Под-) выражение, которое преобразуется в массив, «распадается» до указателя на первый элемент этого массива (и поэтому ваше присваивание работает), но это совершенно другое дело.

4. Глупая ошибка. Спасибо.

Ответ №1:

Чтобы заставить ваш код компилироваться, мне пришлось внести одно изменение: я добавил ‘int’ перед ‘main’, чтобы функция main могла корректно возвращать 0.

Проблема в том, что вы создали массив целых чисел размером 4, но хотите, чтобы он содержал 5 элементов.

 int numar[4];
  

Означает, что ваш массив определен для 4 элементов:

 numar[0]
numar[1]
numar[2]
numar[3]
  

Поэтому,

 numar[4]
  

не определено.

Чтобы исправить это, сделайте свой массив на один размер больше:

 int numar[5];
  

Результат, который я получаю, является:

 array[0] is at address 0x7fff557f0730 with value 0
array[1] is at address 0x7fff557f0734 with value 1
array[2] is at address 0x7fff557f0738 with value 2
array[3] is at address 0x7fff557f073c with value 3
array[4] is at address 0x7fff557f0740 with value 4
  

Комментарии:

1. Большое спасибо за ваш ответ. Глупая ошибка с моей стороны.

Ответ №2:

к сожалению, нет способа заставить индексы массива начинаться с 1, чтобы они начинались с 0, поэтому, если у вас массив из 4 элементов, то последним элементом является элемент с индексом 3, а не 4.

в вашем коде вы считываете пять элементов, где у вас есть только массив из 4 элементов.

 for(x = 0; x < 5; x  ) // iterating five times not 4: 0, 1, 2, 3, 4  
    //....
  

* худшее, что можно записать в неэлементы массива, — это использовать ключ для других переменных, например:

 int a = 0; // initialized to avoid compiler complaining later on
int numar[4] = {0, 1, 2, 3}; // ok
numar[4] = 77; // writing to the fifth element which doesn't belong to numar. as you can see variable a right before numar

cout << a << endl; // a: 77!! where did a get this value? because a is right before numar so element five which doesn't belong to numar was allocated to a
  

в этом примере мы непреднамеренно подключили другие переменные (a) abd самое неприятное, что компилятор не жалуется (мы инициализировали a равным 0)
в результате возникает ошибка, которую в огромном коде было бы невозможно зафиксировать.

Ответ №3:

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

Вы создаете массив из 4 элементов с помощью int numar[4] . Это создает массив, который имеет допустимые индексы 0, 1, 2 и 3. Здесь [4] !

Поэтому, когда вы позже будете заполнять массив и обращаться к нему в for циклах, вы должны настроить их следующим образом:

 for(x = 0; x < 4; x  ) {
  

x < **4** , не 5 . В этом цикле будут проверены индексы 0, 1, 2 и 3.

Ваш цикл обращается к элементу [4] , который не принадлежит массиву.