#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]
, который не принадлежит массиву.