题
我在结构上问了一个类似的问题 这里 但是我试图弄清楚C处理诸如分配变量之类的内容以及为什么不允许它们在功能上相同的情况下分配它们。
可以说我有两个数组:
int x[10];
int y[10];
为什么x = y编译?如果它们都是这样的“签名”,那么您是否应该可以来回分配它们?
我可以以允许我在C中这样做的方式声明这些吗?对我来说,您将能够做到这一点,但是也许可以做到这一点?结构的Typedef似乎是解决方案,对数组声明和分配是否相同?
感谢你们的帮助,我是Stackoverflow的新手,但到目前为止,这对我来说是一个很好的资源!
解决方案
简而言之,数组无法分配。它们是“不可修道的lvalue”。当然,这是一个问题:为什么?请参阅此问题以获取更多信息:
阵列不是指针。 x
这里 做 请参阅数组,尽管在许多情况下,这“衰减”(隐含地转换为)指向其第一个元素。同样地, y
数组的名称也是指针的名称。
您可以在结构中进行数组分配:
struct data {
int arr[10];
};
struct data x = {/* blah */};
struct data y;
y = x;
但是您不能直接使用数组来做到这一点。利用 memcpy
.
其他提示
int x [sz];
int *y = x;
这个编译和 y
将与 x
.
这里的一些消息说,数组的名称产生了其第一个元素的地址。并非总是如此:
#include <stdio.h>
int
main(void)
{
int array[10];
/*
* Print the size of the whole array then the size of a pointer to the
* first element.
*/
printf("%u %u\n", (unsigned int)sizeof array, (unsigned int)sizeof &array[0]);
/*
* You can take the address of array, which gives you a pointer to the whole
* array. The difference between ``pointer to array'' and ``pointer to the
* first element of the array'' matters when you're doing pointer arithmetic.
*/
printf("%p %p\n", (void*)(&array + 1), (void*)(array + 1));
return 0;
}
输出:
40 4
0xbfbf2ca4 0xbfbf2c80
为了分配数组,您必须在数组中分配值。
IE。 x = y等于
for(int i = 0; i < 10 < ++i)
{
x[i] = y[i];
}
为了补充Blank的答案,我设计了以下程序:
localhost:~ david$ cat test.c
#include <stdlib.h>
#include <stdio.h>
int main (int argc, char * argv [])
{
struct data {
int c [2];
} x, y;
x.c[0] = x.c[1] = 0;
y.c[0] = y.c[1] = 1;
printf("x.c %p %i %i\n", x.c, x.c[0], x.c[1]);
printf("y.c %p %i %i\n", y.c, y.c[0], y.c[1]);
x = y;
printf("x.c %p %i %i\n", x.c, x.c[0], x.c[1]);
printf("y.c %p %i %i\n", y.c, y.c[0], y.c[1]);
return 0;
}
执行后,以下输出:
x.c 0x7fff5fbff870 0 0
y.c 0x7fff5fbff860 1 1
x.c 0x7fff5fbff870 1 1
y.c 0x7fff5fbff860 1 1
关键是说明结构值的副本如何发生。
说“ int x [10]”说:“为10个整数保留一些空间,并将我的指针传递到该位置”。因此,要使副本有意义,您需要在指向的内存上操作,而不是“内存位置的名称”。
因此,要在此处复制,您将使用一个用于循环或memcpy()。
我使用的是C编译器,这些编译器可以很好地编译...运行时,代码将X指向Y的数组。
您会看到,在C中,数组的名称是指向数组开始的指针。实际上,阵列和指针基本上是可以互换的。你可以采取 任何 指针和索引像数组一样。
早在70年代初期开发C时,它是针对相对较小的程序,这些程序在抽象中几乎不在组装语言之上。在那种环境中,能够轻松地在阵列索引和指针数学之间来回走动是非常方便的。另一方面,复制整个数据确实是一件非常昂贵的事情,几乎没有被用户的鼓励或抽象的东西。
是的,在这些现代时代,拥有“整个数组”的阵列的名称是“整个数组”的速记,而不是为“阵列前面的ponter”,这将是更有意义的。但是,C并非在这些现代时期设计。如果您想要一种语言,请尝试ADA。 x:= y确实做了您期望的;它将一个阵列的内容复制到另一个数组的内容。