为什么在C语言中可以将字符串赋值给字符指针,但不能将整数值赋值给整数指针。

5

为什么在下面的代码中 int *p = 22 会导致编译时错误,而 ptr 成功打印出值。

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;
}
3个回答

0

因为字符串实际上是char数组,当将数组分配给变量时,数组将作为指向数组第一个元素的指针行事。这可能会令人困惑。更多信息请参见此处:

何时在C中将数组视为指针?

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


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*


如果我们提供一些有效的地址,那么整数指针将会接受,例如 int *ptr = 0xc0563321。 - Divya Prakash
如果该地址被分配来保存一个int,理论上应该可以工作。如果该地址未被分配,则您的程序将崩溃。话虽如此,这不是您应该或应该做的事情。如果您尝试编译该行,您会注意到编译器警告“int*与int的间接级别不同”,其中22是int。出于很好的原因,发出了该警告!您只应使用callocmalloc或使用&运算符来分配指针。 - Nik
@Vlad有一个很好的解释,为什么char *ptr = "Stackoverflow"可以工作。 - Nik

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); 

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接