我不确定我是否正确地提出了这个问题,但是这里有详细说明:
char * cp = "this is a char pointer";
基于我目前有限的理解,上面的代码似乎是可以接受的。但是,下面的代码似乎不可接受:
int * ip; // UPDATED
*ip = 5; // UPDATED
相反,我必须说:
int x;
int * ip;
ip = &x;
x = 5;
因此,使用字符串,我可以在拼写出来时立即将指针初始化为指向字符串文字。我不必用任何其他变量来识别字符串文字...但是这可能是因为指针和数组之间的密切关系,而我实际上同时用同名的隐式数组来识别它? (我试图部分回答我自己的问题)
但是对于整数,我不能只指向浮动在内存中的整数值。我必须给整数值一个变量名并指向变量位置。
我猜这可能与堆栈与堆存储的差异有关?我仍然有点弱......
任何进一步的见解将不胜感激!谢谢!
答案 0 :(得分:8)
您的理解是正确的。字符串文字实际上是一个char数组,并且它的值实际上产生了指向其第一个元素的指针。你可以为任何文字数组做这个(但没有你有char数组的语法糖)。
char *s = "String"; // right side is array of char
int *x = (int []){1, 2}; // right side is array of int
同样,以下是不正确。
char *s = 'S';
int *x = 1;
注意“String”和“S”之间的区别。前者是一个char数组,但后者只是一个int。
然而(正如Keith首次提到的),字符串文字和文字数组(通常称为复合文字)具有不同的存储持续时间。特别是,字符串文字总是具有静态存储持续时间;但复合文字具有自动或静态存储持续时间,具体取决于它是否出现在函数中。这意味着如果从函数中获取指向复合文字的指针:
在这方面,获取一个文字数组的指针非常类似于声明一个数组(例如,sizeof()除外):
int x[] = {1, 2};
答案 1 :(得分:2)
已经解释了char [],但我认为在int示例中要记住的最重要的事情是:
int x; // memory space created for an int
int *ip; // pointer
ip = &x; // assigning a pointer
x = 5; // assigning a value to the memory space referenced by x
尽管
int *ip; // this is a pointer - no space in memory has been allocated for an int
*ip = 5; // hence why you can't assign a value here - there's nowhere to put it!
答案 2 :(得分:1)
字符串文字作为字符数组存储在内存中。您标识一个数组,其起始地址为C.但是您无法执行
int * ip = 5;
买你可以做(编辑:)
int ip[] = {5, 6, 4};
例如。
答案 3 :(得分:1)
简化的原因是字符串是“浮在内存中”的值。编译器实际上接受字符串并将其放入可执行文件(或库)中,当您将程序加载到内存中时,字符串有一个地址,当您使用该字符串时,您实际上获得了指向该地址的指针。 / p>
但是对于整数,编译器不会自动将值放入内存中。如果你明确告诉它(使用赋值变量然后获取变量的地址),它可能会这样做。但在某些情况下,它可能会选择将其存储在没有地址的寄存器中。根据优化选项,它也可以选择不存储它。
答案 4 :(得分:1)
任何有效的非空指针都必须指向某个对象。该对象不必是声明的命名变量。
字符串文字指定存在于程序内存中某处的匿名静态数组对象。在大多数情况下,评估字符串文字的结果是该数组的第一个元素的地址。所以给出了
char *cp = "this is a char pointer";
cp
指向的对象是该匿名数组的初始(第0个)元素。
C99引入了复合文字,因此您实际上可以编写如下内容:
int *ip = (int[]){ 5 };
虽然行为与字符串文字略有不同。特别是,如果复合文字出现在函数内,则匿名对象的生命周期仅限于封闭块。并且您的编译器可能(或可能)不支持复合文字。
答案 5 :(得分:1)
如果声明char*
或int*
,编译器不会为字符串分配内存。
仅在您指定内存时才分配内存:char* p1 = "string";
表示const字符串; char* p2 = (char*)malloc(5*sizeof(char));
表示正常动态分配的char数组(可以修改)或char p3[10];
表示char数组可以用作字符串。
然后你可以用你想要的字符串填充p2和p3:strcpy (p2 , "Hi");
你不能对p1做同样的事情:strcpy(p1 , "Hi");
肯定会使程序崩溃。
然后当您编写int* ip;
,int x;
,p=&x;
时:您使用行int x;
为int分配内存。
你可以用int *ip2 = (int*)malloc(sizeof(int))
分配内存,然后你不必将指针与变量相关联。可以使用*ip2 = 3;
更改int。
答案 6 :(得分:0)
字符串本质上是字符数组。数组类型(例如char[]
)变量通常可以称为指针(char*
,指向数组开头的指针)。这意味着字符串文字的类型为char*
,这就是为什么你可以将该字符串分配给指针。另一方面,整数文字(如'5')的类型为int
,因此您无法将其指定给指针。
答案 7 :(得分:-1)
在C中,字符串是指向以null结尾的字符序列的指针。这就是原因:
char * cp = "this is a char pointer";
被接受。另一方面,如果:
int * ip = 5;
被接受(如果你坚持的话你可以强制它),它会声明“ip
是指向int的指针,其地址是5”。