【发布时间】:2016-10-11 06:07:36
【问题描述】:
下面的程序应该在每个函数中使用不同的指针引用符号将源数组的元素复制到目标数组中:
#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 正常运行,但是当我从 copy_ptrs 的 for 循环中的变量名中删除星号时,它导致前两个功能故障,而它本身工作。
重新迭代:取消引用target 和end 变量会为第三个函数生成正确的输出,但会“破坏”前两个函数;并且不这样做会破坏其各自的功能。我认为不取消引用 start 和 end 指针是正确的方法,因为 print_arr 不会取消引用它们,而是按预期运行(根据我的理解,这是正确的方法)。
此更改如何影响本应在 应该到达之前运行的代码。总的来说,这个程序有什么问题?
我在 Linux 上使用 GCC 4.8.5。
【问题讨论】:
-
您正在从
*target读取未初始化的数据;关于你得到什么,所有的赌注都没有了。 -
当目标被
print_arr读取时,它们已被copy_函数复制到其中。 -
问题出在第二个
copy_ptrs()和*target < *end的使用上。你在给*target赋值之前阅读它,实际上*end也没有确定的值。
标签: c linux function pointers gcc