Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/vba/17.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C 何时';尺寸';应用于字符串,为什么返回其大小(作为strlen)?_C - Fatal编程技术网

C 何时';尺寸';应用于字符串,为什么返回其大小(作为strlen)?

C 何时';尺寸';应用于字符串,为什么返回其大小(作为strlen)?,c,C,如果我有一个字符串: char s1[]="hello, how are you?"; printf("%d\n",sizeof(s1)); 它打印准确的字符数,20。但如果我有一个由指针初始化的字符串: char *s2; s2=(char*)malloc(sizeof(char)); strcpy(s2,s1); printf("%d\n",sizeof(s2)); 它打印指针的大小,这取决于机器(在我的机器上,8)。 既然它们是相同的字符串,为什么s2是8字节,s1是20字节呢?它们不

如果我有一个字符串:

char s1[]="hello, how are you?";
printf("%d\n",sizeof(s1));
它打印准确的字符数,20。但如果我有一个由指针初始化的字符串:

char *s2;
s2=(char*)malloc(sizeof(char));
strcpy(s2,s1);
printf("%d\n",sizeof(s2));
它打印指针的大小,这取决于机器(在我的机器上,8)。
既然它们是相同的字符串,为什么s2是8字节,s1是20字节呢?

它们不是相同的字符串,甚至不是相同的类型
chars2[]
是一个数组,它的大小等于其元素大小之和
char*s2
是一个指针,大小与指针相同


sizeof()。由于指针可以来自任何地方,
sizeof()
无法知道分配内存的大小,但是数组总是在编译时指定大小(C99的VLA除外),然后
sizeof()
可以返回该内存的大小。

记住数组不是指针;在一种情况下,得到数组的大小,在另一种情况下得到指向它的指针的大小

应用于字符串的
sizeof
运算符将生成包括尾随空字符在内的字符串的字符数

在第二种情况下,您不是计算字符串的大小,而是计算指向字符串的指针的大小,因此它生成指针类型的大小

char *s2;
s2=(char*)malloc(sizeof(char));
strcpy(s2,s1);
这个代码是错误的;您正在为一个字符分配空间。您需要为整个字符串分配空间:

char *s2;
s2 = malloc(sizeof s1);
strcpy(s2, s1);

最后,关于
strlen
函数(因为您提到了它):字符串的长度与字符串的大小不同。字符串的长度是尾随终止空字符之前的字符数,而字符串的大小是包括空字符在内的字符串的字符数。

sizeof
返回传入的数据类型的大小。当您传入
char[20]
时,该数据类型占用20个字节,但当传入带有机器字的
char*
时。

char s2[]
是一个静态分配的数组,它都在堆栈上,并且操作符
sizeof
有一个重载版本,可以测量静态分配数组的大小,正如德尔南评论的那样


char*s2
是指针,分配的字符串(带有
malloc
)位于堆上。

这是定义。当
sizeof
运算符应用于数组时,编译器将用数组的长度替换它(在编译阶段)。当它应用于指针时,编译器会将其替换为指针的大小。

忽略第二种情况下没有分配足够内存的事实(应该是
malloc(+1)
),这两种
s2
不是一回事

在第一种情况下,您有一个数组;您正在使用特殊的字符串初始化语法,该语法会导致已初始化为该字符串的正确大小的数组<数组上的code>sizeof
会正确地生成其大小(以
char
为单位)


在第二种情况下,您有一个指针,它不知道它指向的对象有多大<指针上的code>sizeof返回指针的大小,在32位机器上,指针的大小为4字节=32位,因为32位是在32位地址空间中存储指向每个可能内存位置的指针所需的全部空间。

我不会说
char
数组有特殊的“重载”。
char
数组没有什么特别之处,数组相对于指针唯一“特别”的地方是前者有一个(编译时,如果我们忽略VLAs)大小,当然
sizeof
使用了这个信息。明白了,所以s2[]的大小在编译时是已知的,但它的内存位置无法更改。事实上,如果我尝试将s2重新分配到另一个内存位置,它会给出一个错误。相反,指针是动态的,位置是在运行时确定的。这就是为什么,我现在明白了。