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

时间:2011-12-03 23:44:04

标签: c

我不确定我是否正确地提出了这个问题,但是这里有详细说明:

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

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

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

相反,我必须说:

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

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

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

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

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

8 个答案:

答案 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”。