我对有问题的C程序(arrays-pointers.c
)有很多疑问:
#include <stdio.h>
int main(void) {
char * vowels = {'A', 'E', 'I', 'O', 'U'};
printf("sizeof(vowels): %d\n", sizeof(vowels));
}
我使用gcc(gcc arrays-pointers.c -o arrays-pointers.exe
)进行编译,但收到警告(但不是完全错误):
In function 'main':
warning: initialization of 'char *' from 'int' makes pointer from integer
without a cast [-Wint-conversion]
char * vowels = {'A', 'E', 'I', 'O', 'U'};
^~~
note: (near initialization for 'vowels')
warning: excess elements in scalar initializer
char * vowels = {'A', 'E', 'I', 'O', 'U'};
^~~
note: (near initialization for 'vowels')
warning: excess elements in scalar initializer
char * vowels = {'A', 'E', 'I', 'O', 'U'};
^~~
note: (near initialization for 'vowels')
warning: excess elements in scalar initializer
char * vowels = {'A', 'E', 'I', 'O', 'U'};
^~~
note: (near initialization for 'vowels')
warning: excess elements in scalar initializer
char * vowels = {'A', 'E', 'I', 'O', 'U'};
^~~
note: (near initialization for 'vowels')
尽管有这些警告,但gcc会生成一个可执行文件,该可执行文件始终输出:
sizeof(vowels): 8
我的问题是:
sizeof(vowels)
总是8?答案 0 :(得分:5)
这很容易理解,因为数组在C中是“奇怪的”。仅出于历史原因,它们就是“特殊情况”。
您需要知道的是,数组和指针根本不是一回事。数组是一块具有多个元素的内存块,指针是别的东西的地址。
造成混淆的是,在许多地方,如果使用C语言,而不是使用数组,则C语言会考虑指向数组第一个元素的指针(在法律术语中,用语是“数组衰减为指向数组的指针)。第一个元素”)。
例如
int x[] = {1, 2, 3}; // x is an array
foo(x); // you cannot pass an array, a pointer to x[0] is passed instead
因此您的代码无效是因为
int *x = {1, 2, 3}; // Invalid: {1, 2, 3} is not a valid initializer for a pointer
相反,令人惊讶的是,这是有效的
int x[] = {1, 2, 3}; // An array
int *y = x; // Fine, it's like writing int *y = &x[0];
在第二个示例中,y
的初始化是有效的,因为在这种情况下,有一条规则说该数组会自动“衰减”为指向第一个元素的指针。
之所以会发生这种混乱,是因为数组不是其他对象(出于历史原因),例如,分配数组,从函数返回数组或接受数组参数是非法的(但令人惊讶的是,您可以分配结构,将结构作为参数传递,并从函数返回结构...即使结构包含数组也是如此。现在解决这种不合逻辑的不对称性已成问题,因为通过更改现有代码的含义会破坏大多数现有的C或C ++程序。
不幸的是,C和C ++充满了这些奇怪的不合逻辑的规则,这就是为什么通过实验学习C或C ++是一个坏主意的原因(对于C语言来说,这是一个坏主意,但由于它的体积很小,可能仍然可行,但是对于C ++语言,自杀,因为这实际上是一个不合逻辑的陷阱的雷区,也是一个巨大的陷阱。)
要学习C或C ++,您需要阅读规则。
不要试图太聪明和猜测(正确答案不合逻辑时,猜测无济于事。
答案 1 :(得分:2)
您可以通过创建字符数组,然后为指针分配其地址来对其进行初始化。这种对象称为复合文字。
{{1}}
答案 2 :(得分:0)
如果指针和数组相似,为什么不能初始化数组 这样吗?
从技术上讲,它们并不完全相同。您可以添加手动操作以使指针的行为类似于数组,但它们并不相同。
为什么sizeof(元音)总是8?
它是64位系统上指针的大小。
答案 3 :(得分:0)
首先,因为已经说过sizeof(int)=在32位体系结构中为4个字节,在64位体系结构中为8个字节,这与系统对整数进行编码所需的内存量有关。 话虽如此,您必须了解C中的指针和数组的相似性。数组是保存在内存中连续地址中的相同类型元素的集合。我们可以使用指向它的第一个字节的指针来访问它。例如:
int A [5];不仅是数组的指针,&A或&A [0](在C中表示相同的含义)是指向数组的开始(如果需要,可以将其命名为head)的指针。
A [1]表示数组的第二个元素,它的地址(或指向它的指针)在模拟的32位机器或软件中为&(A + sizeof(int))==&(A + 4)它(例如NetBeans)。
将数组传递给函数:
第一种方式
void readTheTheory(int * Arr) {
}
并将其命名为readTheTheory(A)或readTheTheory(&A [0])
第二种方式
避免readTheTh(int A [])
{
} 并找出如何自行正确调用