为什么必须将int指针绑定到变量而不是char指针?

我不确定我是否正确地提出了这个问题,但在这里它是明确的:

char * cp = "this is a char pointer"; 

基于我目前有限的理解,上面的代码似乎是可以接受的。 但是,下面的代码似乎不可接受:

 int * ip; // UPDATED *ip = 5; // UPDATED 

相反,我必须说:

 int x; int * ip; ip = &x; x = 5; 

因此,使用字符串,我可以在拼写出来时立即将指针初始化为指向字符串文字。 我不必用任何其他变量识别该字符串文字……但是这可能是因为指针和数组之间的密切关系,而我实际上是同时使用同名的隐式数组来识别它? (我试图部分回答我自己的问题)

但是对于整数,我不能只指向浮动在内存中的整数值。 我必须给整数值一个变量名并指向变量位置。

我猜这可能与堆栈与堆存储的差异有关? 我仍然有点弱……

任何进一步的见解将不胜感激! 谢谢!

你的理解是正确的。 字符串文字实际上是一个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}; 

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! 

简化的原因是字符串是一个“浮在内存中”的值。 编译器实际上接受字符串并将其放入可执行文件(或库)中,当您将程序加载到内存中时,字符串有一个地址,当您使用该字符串时,您实际上获得了指向该地址的指针。

但对于整数,编译器不会自动将值放入内存中。 如果你明确告诉它(使用赋值变量然后获取变量的地址),它可能会这样做。 但在某些情况下,它可能会选择将其存储在没有地址的寄存器中。 根据优化选项,它也可以选择不存储它。

任何有效的非空指针都必须指向某个对象 。 该对象不必是声明的命名变量。

字符串文字指定存在于程序内存中某处的匿名静态数组对象。 在大多数情况下,评估字符串文字的结果是该数组的第一个元素的地址。 所以给定

 char *cp = "this is a char pointer"; 

cp指向的对象是该匿名数组的初始(第0个)元素。

C99引入了复合文字,因此您实际上可以编写如下内容:

 int *ip = (int[]){ 5 }; 

虽然行为与字符串文字略有不同。 特别是,如果复合文字出现在函数内部,则匿名对象的生命周期仅限于封闭块。 而你的编译器可能会或可能不会(还)支持复合文字。

字符串文字作为字符数组存储在内存中。 您标识一个数组,其起始地址为C.但是您不能这样做

 int * ip = 5; 

买你可以做(​​编辑:)

 int ip[] = {5, 6, 4}; 

例如。

如果声明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 x;

你可以用int *ip2 = (int*)malloc(sizeof(int))分配内存,然后你不必将指针与变量相关联。 int可以用*ip2 = 3;改变*ip2 = 3;

在C中,字符串是指向以null结尾的字符序列的指针。 这就是为什么:

 char * cp = "this is a char pointer"; 

被接受了。 另一方面,如果:

 int * ip = 5; 

被接受(你可以强制它,如果你坚持),它会声明“ ip是指向int的指针,其地址为5”。

字符串本质上是字符数组。 数组类型(例如char[] )变量通常可以称为指针( char* ,指向数组开头的指针)。 这意味着字符串文字的类型为char* ,这就是为什么你可以将该字符串分配给指针。 另一方面,整数文字(如’5’)的类型为int ,因此您无法将其指定给指针。