可以为char指针分配任意字符串,但不能为整数指针分配整数。由于它们都是指针,并且包含地址。在动态分配之前,为什么在C中将字符串分配给指针有效而整数却给指针无效。
#include<stdio.h>
int main()
{
char *s = "sample_string"; // valid
printf("%s\n", s);
int *p = (int)5; // invalid
printf("%d\n", *p);
return 0;
}
哪个输出:
sample_string
Segmentation fault (core dumped)
背后的原因是什么?尽管它们在C ++中都是无效的。
C中没有“字符串类型”。根据C的定义,“字符串”是char
的数组,末尾为零字节。
"sample_string"
的类型是char[14]
,可以将其分配给指针。
(int)5
的类型是int
,不能。
分割错误是由于您正在访问地址 0x00000005,这是无效的。
char *s = "sample_string";
这里"sample_string"
是字符串文字,在C ++中是const char[]
。它隐式转换为const char *。由于您已将其分配给char *,因此会收到警告。
int *p = (int)5;
这里5
只是一个整数。由于您要为其分配一个指针,这意味着它是无效的指针值。因此,当引用它时,您会遇到段错误。
约定是字符串是char的数组(char[]
),指向字符串的指针指向此char数组的第一个元素,就像指向数组的指针始终指向其第一个元素一样默认值,即用于int数组
int a[10];
int *p;
p=&a
指向a
的第一个元素,即索引符号中的a[0]
这很简单:
char
对象可以包含char
值:char x = 'a';
。int
对象可以包含int
值:int x = 3;
。char *
对象可能指向char
:char *p = "abc";
的数组。int *
对象可能指向int
:int *p = (int []) {1, 2, 3};
的数组。(在此答案中,“指向数组”是“指向数组的第一个元素”的缩写。)
在C中,字符串文字,例如"abc"
,实际上是char
的数组,在末尾包含空字符。另外,上面的文本(int []) {1, 2, 3}
是创建int
数组的复合文字。因此"abc"
和(int []) {1, 2, 3}
都是数组。将数组分配给指针后,C实现会自动将其转换为指向其第一个元素的指针。 (只要将数组用在除sizeof
的操作数,一元&
的操作数之外的任何表达式中,或者如果它是字符串文字,则作为数组的初始化程序,就会发生此转换。)
但是不能为整数指针分配整数。
不完全是。在C语言中,将整数can分配给指针-在某些条件下。但这仅将指针设置为5,而不是p
指向值为5的int
。*p
尝试读取地址5的内容并将该位置解释为int
。当然,对地址5的访问是无效的,并且会导致段错误。
即使满足这些条件(请参阅下文),也肯定不是OP所寻求的,我假定将其设置为指向p
/ 5
的值/类型的指针int
它。
(int) {5}
是复合文字,自C99起可用。这是一个int
,其值为5,代码将获取该对象的地址,并将该地址分配给p
。
// int *p = (int)5;
int *p = & ((int) {5});
printf("%d\n", *p); // prints 5
整数可以转换为任何指针类型。除非先前指定,否则结果是实现定义的,可能未正确对齐,可能未指向引用类型的实体,并且可能是陷阱表示。 C17dr§6.3.2.3 5