Следующая программа должна копировать элементы исходного массива в в целевых массивах, используя различные опорные указатель нотации в каждой функции:необъяснимые побочные эффекты функции на других несвязанных единиц в C
#include <stdio.h>
void copy_arr(double [], const double [], int);
void copy_ptr(double *, const double *, int);
void copy_ptrs(double *, const double *, double *);
void print_arr(const double *, const double *);
int main(void)
{
double source[5] = { 0.1, 2.2, 4.3, 6.4, 8.5};
double target1[5];
double target2[5];
double target3[5];
copy_arr(target1, source, 5);
copy_ptr(target2, source, 5);
copy_ptrs(target3, source, source + 5);
print_arr(target1, target1 + 5);
print_arr(target2, target2 + 5);
print_arr(target3, target3 + 5);
return 0;
}
void copy_arr(double target[], const double source[], int num)
{
for (int i = 0; i < num; ++i)
target[i] = source[i];
}
void copy_ptr(double *target, const double *source, int num)
{
for (int i = 0; i < num; ++i)
*(target+i) = *(source+i);
}
void copy_ptrs(double *target, const double *source, double *end)
{
for (; target < end; ++target, ++source)
*target = *source;
}
void print_arr(const double *start, const double *end)
{
while (start < end)
printf("%.1lf, ", *start++);
printf("\n");
}
Это производит выходы как :
0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.1, 2.2, 4.3, 6.4, 8.5,
или мусор на месте нулей.
Однако, когда я случайно изменил функцию copy_ptrs на:
void copy_ptrs(double *target, const double *source, double *end)
{
for (; *target < *end; ++target, ++source) // notice the asterisks
*target = *source;
}
Я получаю следующий вывод:
0.1 2.2 4.3 6.4 8.5 0.1 2.2 4.3 6.4 8.5 0.0 0.0 0.0 0.0 0.0
Видимо «ошибка» приводит к тому, copy_arr
и copy_ptr
функционировать должным образом, но когда Я удаляю звездочки из имен переменных в цикле for copy_ptrs
, он вызывает две предыдущие функции, чтобы сбой, а сам он работает.
Для повторной итерации: разыменование переменных target
и end
дает правильный выход для третьей функции, но «разрывает» предыдущие; и не делает этого нарушает свою соответствующую функцию. Я думаю, что разыменование указателей start
и end
- это правильный путь, потому что print_arr
не разыгрывает их, а ведет себя так, как ожидалось (и, согласно моему пониманию, является правильным способом).
Как это изменение может повлиять на код, который предположительно запускается до, он должен быть доступен. И вообще, что случилось с программой?
Я использую GCC 4.8.5 для Linux.
Вы читаете неинициализированные данные из '* target'; все ставки не учитывают то, что вы получаете. –
к моменту, когда цели будут прочитаны 'print_arr', они были скопированы с помощью функций' copy_'. –
Проблема заключается во втором 'copy_ptrs()' и использовании '* target <* end'. Вы читаете '* target', прежде чем ему присваивается значение, и на самом деле' * end' также не имеет определенного значения. –