我正在尝试在C中编写一个类似于Numpy的linspace
的简单np.linspace
函数,但我得到了一些我不理解的奇怪行为。
linspace
函数接收起始编号,停止编号和数组中的元素数。 E.g。linspace(0,5,5)
生成一个看起来像[0., 1.25, 2.5, 3.75, 5.]
我的代码如下。 linspace
已定义,然后main
。 main
经历了困扰我的事情的例子。
double *linspace(double start, double stop, int num) {
double a[num];
double spacing = (stop-start)/(num-1);
int i;
printf("Output of function linspace:\n");
for (i=0; i<num; i++){
a[i] = start + i*spacing;
printf("a[%d] = %f, &a[%d] = %p\n", i, a[i], i, &a[i]);
}
return a;
}
int main(int argc, char* argv[]) {
int N = 5;
double start = 1;
double stop = 5;
int i;
/* Testing linspace */
double *a = linspace(start, stop, N);
// double a[N];
// a[0] = 1; a[1]=2; a[2]=3; a[3]=4; a[4]=5;
printf("Printing a line with no \\n does nothing to the array...");
for (i=0; i<N; i++){
printf("a[%d] = %f, &a[%d] = %p\n", i, a[i], i, &a[i]);
}
printf("Printing a line with \\n resets some of the array elements...\n");
for (i=0; i<N; i++){
printf("a[%d] = %f, &a[%d] = %p\n", i, a[i], i, &a[i]);
}
printf("Defining double y[N] prior to the loop modifies array a again:");
double y[N];
for (i=0; i<N; i++){
printf("a[%d] = %f, &a[%d] = %p\n", i, a[i], i, &a[i]);
}
return 0;
}
打印输出看起来像这样,我很困惑,因为打印\n
并定义新变量似乎是将数组a
的值设置为0。
Output of function linspace:
a[0] = 1.000000, &a[0] = 0xbfe7d968
a[1] = 2.000000, &a[1] = 0xbfe7d970
a[2] = 3.000000, &a[2] = 0xbfe7d978
a[3] = 4.000000, &a[3] = 0xbfe7d980
a[4] = 5.000000, &a[4] = 0xbfe7d988
Printing a line with no \n does nothing to the array...a[0] = 1.000000, &a[0] = 0xbfe7d968
a[1] = 2.000000, &a[1] = 0xbfe7d970
a[2] = 3.000000, &a[2] = 0xbfe7d978
a[3] = 4.000000, &a[3] = 0xbfe7d980
a[4] = 5.000000, &a[4] = 0xbfe7d988
Printing a line with \n resets some of the array elements...
a[0] = -0.000000, &a[0] = 0xbfe7d968
a[1] = -0.000000, &a[1] = 0xbfe7d970
a[2] = 3.000000, &a[2] = 0xbfe7d978
a[3] = 4.000000, &a[3] = 0xbfe7d980
a[4] = -0.000000, &a[4] = 0xbfe7d988
Defining double y[N] prior to the loop modifies array a again:a[0] = -0.000000, &a[0] = 0xbfe7d968
a[1] = -0.000000, &a[1] = 0xbfe7d970
a[2] = 0.000000, &a[2] = 0xbfe7d978
a[3] = 4.000000, &a[3] = 0xbfe7d980
a[4] = -0.000000, &a[4] = 0xbfe7d988
(上面y[N]
使用的内存地址与a
不同,我查了一下。)
如果我没有从函数double *a = linspace(start, stop, N);
获取数组,而是手动定义了一个数组(代码中注释掉的行):
double a[N];
a[0] = 1; a[1]=2; a[2]=3; a[3]=4; a[4]=5;
然后每个打印命令打印出类似的输出,我期望:
a[0] = 1.000000, &a[0] = 0xbf85f8a8
a[1] = 2.000000, &a[1] = 0xbf85f8b0
a[2] = 3.000000, &a[2] = 0xbf85f8b8
a[3] = 4.000000, &a[3] = 0xbf85f8c0
a[4] = 5.000000, &a[4] = 0xbf85f8c8
如果我使用数组的方式有问题,你可以解释为什么在从函数返回数组后做某事(例如打印\n
和定义变量)可以改变数组中的元素,并且展示你如何解决它?提前谢谢!
我的背景主要是Python。
答案 0 :(得分:3)
您正在堆栈上分配的数组上返回指针。
double a[num];
在堆栈上分配数组。返回a时,返回指向函数返回时处理的数组的指针。因此,指针地址指向堆栈内部,可能稍后会被覆盖。