Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/69.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中指针和字符串的问题_C_Arrays_String_Pointers - Fatal编程技术网

关于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
是一个运算符,而不是函数调用;当操作数是一个表示对象的表达式时,括号是不必要的(尽管它们不会造成伤害)

是因为

  • string1保存指针,其中指针具有连续字符及其 不变的
  • string2是您的角色所在的位置

  • 基本上,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);