关于C中指针和字符串的问题
可能重复:关于C中指针和字符串的问题,c,arrays,string,pointers,C,Arrays,String,Pointers,可能重复: 我有一些令我困惑的代码 #include <stdio.h> #include <stdlib.h> int main(int argc, char *argv[]) { char* string1 = "this is a test"; char string2[] = "this is a test"; printf("%i, %i\n", sizeof(string1), sizeof(string2)); system("PAUS
我有一些令我困惑的代码
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char *argv[])
{
char* string1 = "this is a test";
char string2[] = "this is a test";
printf("%i, %i\n", sizeof(string1), sizeof(string2));
system("PAUSE");
return 0;
}
#包括
#包括
int main(int argc,char*argv[])
{
char*string1=“这是一个测试”;
char string2[]=“这是一个测试”;
printf(“%i,%i\n”、sizeof(string1)、sizeof(string2));
系统(“暂停”);
返回0;
}
当它输出string1的大小时,它会打印4,这是预期的,因为指针的大小是4字节。但当它打印string2时,输出15。我认为数组是指针,所以string2的大小应该与string1相同,对吗?那么为什么它会为同一类型的数据(指针)打印出两种不同的大小呢?数组不是指针。在某些情况下,数组名称会衰减为指向数组第一个元素的指针:当您将其传递给函数时,当您将其分配给指针时,等等。但在其他情况下,数组是数组-它们存在于堆栈上,具有可由
sizeof
确定的编译时大小,以及所有其他好东西。string1
是指针,而string2
是数组
第二行类似于inta[]={1,2,3}
将a
定义为长度为3的数组(通过初始值设定项)
string2
的大小是15,因为初始值设定项是nul终止的(因此15是字符串的长度+1)。编译器知道test2
是一个数组,所以它会打印分配给它的字节数(14个字母加上null终止符)。请记住,sizeof
是一个编译器函数,因此它可以知道堆栈变量的大小。出于sizeof的目的,未知大小的数组相当于指针。出于sizeof的目的,静态大小的数组将作为其自己的类型计数,sizeof报告该数组所需的存储大小。即使string2
是在没有显式大小的情况下分配的,C编译器也会神奇地处理它,因为它是由带引号的字符串直接初始化的,并将其转换为具有静态大小的数组。(因为内存不是以任何其他方式分配的,所以它毕竟不能做任何其他事情。)静态大小数组与指针(或动态数组!)在sizeof
行为方面是不同的类型,因为C就是这样
似乎是sizeof行为的一个不错的参考。数组不是指针。指针是指向内存位置的变量,而数组是顺序内存分配的起点。数组和指针是完全不同的动物。在大多数上下文中,指定数组的表达式被视为指针 首先,一点标准语言(): 6.3.2.1左值、数组和函数指示符
…
3除非它是
sizeof
运算符或一元&
运算符的操作数,或者是用于初始化数组的字符串文字,否则类型为“array of type”的表达式将转换为类型为“pointer to type”的表达式,该表达式指向数组对象的初始元素,而不是左值。如果数组对象具有寄存器存储类,则行为未定义。字符串文字“thisatest”是一个15个元素的数组,包含
char
。在声明中
char *string1 = "this is a test";
string1
被声明为指向char
的指针。根据上述语言,“这是一个测试”表达式的类型从char[15]
转换为char*
,并将结果指针值分配给string1
在宣言中
发生了一些不同的事情。更标准的语言:
6.7.8初始化
…
14字符类型的数组可以由字符串文字(可选)初始化 用大括号围起来的。字符串文字的连续字符(包括 如果有空间或数组大小未知,则终止空字符)初始化数组的元素。
…
22如果初始化了未知大小的数组,则其大小由具有显式初始值设定项的最大索引元素确定。在初始值设定项列表的末尾,数组不再具有不完整的类型。 在这种情况下,
string2
被声明为char
的数组,其大小根据初始值设定项的长度计算,字符串文本的内容被复制到数组中
下面是一个假设的内存图来说明发生了什么:
请注意,
sizeof
是一个运算符,而不是函数调用;当操作数是一个表示对象的表达式时,括号是不必要的(尽管它们不会造成伤害) 是因为
基本上,C编译器对这两种语言的设置是不同的。这里解释得很好。另外,
sizeof
返回一个size\u t
,它与%i
所期望的int
不同,是无符号的。size\t
变量的正确格式是%zu
。数组不是品脱!记住这一点!哇!谢谢你的详细回答!这真的帮了我大忙。
char string2[] = "this is a test";
Item Address 0x00 0x01 0x02 0x03
---- ------- ---- ---- ---- ----
no name 0x08001230 't' 'h' 'i' 's'
0x08001234 ' ' 'i' 's' ' '
0x08001238 'a' ' ' 't' 'e'
0x0800123C 's' 't' 0
...
string1 0x12340000 0x08 0x00 0x12 0x30
string2 0x12340004 't' 'h' 'i' 's'
0x12340008 ' ' 'i' 's' ' '
0x1234000C 'a' ' ' 't' 'e'
0x1234000F 's' 't' 0
C89: printf("%lu, %lu\n", (unsigned long) sizeof string1, (unsigned long) sizeof string2);
C99: printf("%zu, %zu\n", sizeof string1, sizeof string2);