1年后我在回忆我的C编程技能。所以我决定从零开始。我被指针缠住了
why I can do:
char *string="Hello";
printf ("%s",string);
但是我不能:
int *pt=23;
printf("%d",*pt);
指针不需要是地址吗?但是为什么第一个例子有效呢?
因为使用字符串字面值初始化字符指针或数组是一种特殊的允许语法,具有特定的规则。在你的例子中,你设置了一个指针指向字符串字面值的地址,字符串字面值本身的类型是char[]
,并且存在于只读内存中。
对于整型的情况,是的,它需要是一个地址,或者更具体地说是另一个整型指针。不能用整数初始化指针。参见:
"来自整数的指针/来自没有强制类型转换的指针的整数;问题
字符串字面值"Hello"作为字符数组存储在内存中,如
char unnamed_literal[] = { 'H', 'e', 'l', 'l', 'o', ' ' };
那么在这个声明中
char *string="Hello";
指针字符串被赋给已经存在的数组的第一个字符的地址。它可以像
char unnamed_literal[] = { 'H', 'e', 'l', 'l', 'o', ' ' };
char *string = unnamed_literal;;
对于这个声明
int *pt=23;
则值23
不是指向程序中定义的有效对象的有效地址。编译器应该发出一条消息,告诉您正在尝试将整数赋值给指针。因此调用
printf("%d",*pt);
调用未定义行为。
与用字符串字面值初始化指针类似,可以这样写:
int a[] = { 1, 2, 3 };
int *pt = a;
这是标准C中的合成糖:
实际上存储在char指针中的是在启动程序时将字符串加载到内存中的地址。
对于整数,它将尝试将指针的地址设置为23
,这是(并且应该是)无效的。
例如整数,如:
int VAL = 10;
int *ptr = &VAL; /* ptr now points to val */
*ptr = DESIRED_VALUE; /* *(asterisk) here means dereference, meaning that the value of VAL will change */
或
int *&VAL = DESIRED_VALUE;
int variable_1 = 23;
int *pointer_to_int = &variable_1;
第一行是一个整型变量,初始化为整数值。
第二行是指向整型变量的指针,初始化为整型变量的地址(变量variable_1
的地址,在前面的声明中定义)。
char *p = "Charles Dickens";
这是一个char
指针变量,初始化为字符串字面值的地址,字符串字面值是一个常量数组,由引号之间的字符和一个额外的