проблема с указателями в C - PullRequest
5 голосов
/ 04 апреля 2011

Итак, у меня есть этот код:

#include <stdio.h>
int arraySum (int *a, int n);
int main(void){
    int values[3] = {1, 2, 3};
    printf("The sum is %i\n", arraySum(values, 3));
    return 0;
}
int arraySum(int *a, int n){
    int sum = 0;
    int arrayEnd = *a + n;
    for ( ; *a < arrayEnd; *a++)
        sum += *a;
    return sum;
}

По какой-то причине он выводит это:

roman@lmde64 ~/Dropbox/Practice $ gcc practice.c 
roman@lmde64 ~/Dropbox/Practice $ ./a.out
The sum is -421028781
roman@lmde64 ~/Dropbox/Practice $ ./a.out
The sum is -362865581
roman@lmde64 ~/Dropbox/Practice $ ./a.out
The sum is -1046881197
roman@lmde64 ~/Dropbox/Practice $ ./a.out
The sum is 6
roman@lmde64 ~/Dropbox/Practice $ ./a.out
The sum is 6

Почему вывод странных чисел иногда и правильный ответ в других случаях? Что я делаю неправильно? Спасибо за любую помощь.

Ответы [ 5 ]

14 голосов
/ 04 апреля 2011

В arraySum() вы не понимаете, когда использовать a в качестве указателя и когда разыменовывать его, чтобы получить то, на что он указывает.Когда вы вычисляете пределы цикла и т. Д., Вы хотите работать с указателем сам :

int arraySum(int *a, int n){
    int sum = 0;
    int *arrayEnd = a + n;
    for ( ; a < arrayEnd; a++)
        sum += *a;
    return sum;
}
2 голосов
/ 04 апреля 2011

Вы хотите перебрать массив:

int arraySum(int *a, int n){
    int sum = 0;
    int * arrayEnd = a + n; // arrayEnd points to the first element after your array a
    for ( ; a != arrayEnd; ++a)  // Iterate over the array until you reach arrayEnd
        sum += *a; // Dereference the pointer to current array element in order to retrieve a value
    return sum;
}
1 голос
/ 04 апреля 2011

В исходном коде

  • *a + n оценивается как 1+3 = 4
  • В каждой итерации цикла for значение, на которое указывает *a, сравнивается с 4.
  • Если значение *a меньше 4, то вычисляется sum.
  • После 3 итераций a указывает на values[2], что составляет 3. Позже, когда a увеличивается, он указывает на адрес за пределами value[2] - этот адрес может содержать любое значение мусора. Если значение мусора меньше 4, оно вычислит sum. Такое поведение продолжается до встречается значение больше 4. Следовательно, значение sum иногда 6 или какое-то другое значение мусора
1 голос
/ 04 апреля 2011
int arraySum(int *a, int n) {
   int sum = 0;
   for (int i = 0; i < n; ++i)
      sum += a[i];
   return sum;
}

или

int arraySum(int *a, int n) {
   int sum = 0;
   for (int i = 0; i < n; ++i)
      sum += *a++;
   return sum;
}
1 голос
/ 04 апреля 2011
  • *a++ совпадает с *(a++);* ничего не делает в этом случае
  • arrayEnd устанавливается в *a + 3, или 1 + 3, или 4
  • Ваш цикл for не завершается, пока массив не будет исчерпан.Доступ вне пределов массива вызывает неопределенное поведение
  • ваша программа может также вывести «Могучую сумму не то, что вы ожидаете! \ N»
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...