2017-10-14 45 views
3

为什么在下面的代码中int * p = 22会给编译时间错误,并且ptr将成功打印该值。为什么可以将字符串指定给C中的字符指针,但不能将整数值指定给整数指针

int main() 
{ 

/*taking a character pointer and assigning a string to it*/ 
char *ptr = "Stackoverflow" ; //correct 

/*taking a int pointer and assigning a string to it*/ 
int *p = 22 ; //incorrect 

printf("%s",ptr); // correct and print 
printf("%d",p); //incorrect and give compile time error. 

return 0; 
} 

回答

0

如果你有一个字符阵列,例如

char s[] = "Stackoverflow"; 

然后在表达式中它被转换为指针到它的第一元件中使用的阵列的指示符。所以,你可以写

char *ptr = s; 

指针ptr现在指向数组s的第一个字符。

C语言中的字符串文字也被表示为像字符数组,并像静态存储持续时间一样存储在内存中,就像字符数组一样。

因此,例如,字符串文字"Stackoverflow"的类型为char[14](包括终止零)。

,那么你写

char *ptr = "Stackoverflow"; 

那么这种说法其实如果同样会有

static char unnamed[] = "Stackoverflow"; 
char *ptr = unnamed; 

至于这种说法

int *p = 22 ; 

那么整数文字不转换为指向自己的指针。它从字面上代表了数字22,仅此而已。

所以编译器发出一条消息,因为如果你想让指针确实包含整数值22,那么你必须使用一个转换。

表达

22 == 22 

总是产生true

虽然这种表达

"Stackoverflow" == "Stackoverflow" 

是没有必要的产量true因为取决于编译选项编译器可以放置在不同的存储区域巧合字符串文字。在这个表达式中,它是指向比较的字符串文字的第一个字符的指针。

考虑到如果要输出指针指向的整数对象,则需要使用解引用。因此,在任何情况下,而不是

printf("%d",p); 

你应该写

printf("%d", *p); 

或者,如果你想输出存储在一个指针的值,你必须使用另一种格式说明

printf("%p", p); 
0

此行将内存地址分配为22。这是不正确的。尽管此行只会编译一条警告,但在代码中稍后尝试访问内存地址22时,它会在运行时崩溃您的程序。

int *p = 22 ; //incorrect 

这会给你你正在寻找的结果是:

int *p = NULL; 
int val = 22; 
p = &val; 

而且

printf("%d",p); //incorrect and give compile time error. 
printf("%d",*p); //you must derefence the pointer 

%s需要一个字符指针,它在哪里结束的字符串空,而%d需要int,而不是int*

+0

以及如果我们给一些有效的地址,那么整数指针将采取例如int * ptr = 0xc0563321 –

+0

如果该地址被分配来保存一个'int',那应该在理论上起作用。如果该地址未分配,则程序将崩溃。这就是说,这不是你应该做的或者应该做的。如果您尝试编译该行,您会注意到编译器警告“int *与int间的层次不同”,其中22是int。该警告是有充分理由发出的!你只能通过使用'calloc'或'malloc'或者使用'&'运算符来指定指针。 – Nik

+0

@Vlad有一个很好的解释,为什么'char * ptr =“Stackoverflow”'工作。 – Nik

0

因为该字符串实际上是一个char数组,当将一个数组分配给一个变量时,这些数组将作为指向该数组第一个元素的指针行为。这可能会让人困惑。更多关于此这里:

when does a array act as a pointer in c?

,另一方面整数仅仅是一个整数,而不是整数数组。

相关问题