我了解指针工作原理的基础知识,但以下示例让我感到困惑。
int *myNum = 10; // Produces an error
char *myChar = "Something"; // Works fine
为什么分配 char 有效但整数不起作用(也许导致 char 被视为数组)?
以及直接分配指针变量时让我感到困惑的地方,它会自动获得地址吗?
char *myChar = "Something";
和
char myChar = "Something";
char *charAddr = &myChar;
这里有什么区别,或者等于什么?
"Something"
本质上是以下的缩写:
static const char some_hidden_array[] = {'S', 'o', 'm', 'e', 't', 'h', 'i', 'n', 'g', ' '};
some_hidden_array
也就是说,当您编写 "Something"
时,编译器会在后台生成一个数组,并为您提供指向该数组开头的指针。由于这已经是指向字符的指针,因此将其分配给"指向字符的指针"类型的变量(写为 char*
)没有问题。
10
不是类似内容的缩写。它只是数字 10 - 它不是指向包含数字 10 的数组的指针,或者类似的东西。
请注意,char
是单个字符,而不是字符串,这就是为什么字符串语法与大多数其他类型的语法相比不寻常的原因 - 字符串是几个字符,而不仅仅是一个字符。如果您尝试使用普通的旧char
,您将看到相同的内容:
char *myChar = 'a'; // error
或任何其他类型:
float *myFloat = 42.1f; // error
换句话说,10
给出错误并不奇怪——如果有的话,"Something"
没有给出错误是很奇怪的。(至少,在你知道字符串文字如何工作之前,这很奇怪)
这是一回事(编译器没有发生魔法)。默认情况下,像 10 这样的文字是 int 值,而不是 int*。
您需要投射:
int *myNum = (int*)10; // Need to cast
char *myChar = "Something"; // No need to cast "..." is already a char*
请注意,像这样引用指向绝对值的指针是危险的,因为最终会在 CPU 内存中获得地址 10。
关于你的第二个问题,"..."被视为内存中 char 的连续序列,类似于数组,等效于 char*。
为了深入理解 C、指针以及数组和指针之间的差异,您应该阅读以下内容:Peter van der Linden 的 Expert C Programming: Deep C Secrets。
为什么分配 char 有效但整数不起作用(也许导致 char 被视为数组)?
你是对的,"Something"
是一个字符串文字,可以被视为字符数组。char *myChar = "Something";
之后,会发生以下事情:它被分配长度+1字节的内存,"Something"
将在其中存储,myChar
指向该内存的起始地址。字符串文本有些特殊。
以下是使用常量值初始化数组的通用方法:
// valid initializations;
char s2[] = { 'a', 'b', 'c' };
int a[] = { 1, 2, 3 };
char s1[] = "123";
以及直接分配指针变量时让我感到困惑的地方,它会自动获得地址吗?
是的。
看看 8.5.2 c++ 文档的字符数组
当你执行char *myChar = "Something";
时,你在内存中的某个地方创建一个只读字符串文本,它以空字符结尾。现在,这是编译器的特殊之处,它将连续存储的"char"变量块解释为字符串,并以空字符结尾。所以基本上你创建了一个字符数组,当你执行*myChar*
时,它返回字符串。
对于整数或任何其他数据类型,它区分int *ptr
作为整数的指针和int ptr
作为整数。您收到错误可能是因为您输入的地址可能无效/不可用。
另外,做
char myChar = "Something"; //this is an error, since char can hold one character
char *charAddr = &myChar;
请注意,myChar
和 &myChar
是相同的,因为myChar
是一个指针!
编辑:请参阅此处有关字符串文本的信息:是否可以修改 C 中的字符字符串?
虽然理论上第一个int *myNum = 10
是有意义的——特别是如果你知道地址十有一个有用的int
——但一般来说,它很少有用,而且可能非常危险。
但是,有一些指针赋值被广泛使用且非常安全:
int *myNum = 0;
在 99.9+% 的现代 CPU 架构上,这与
int *myNum = NULL;
请参阅此处<stddef.h>
中 NULL 的定义。
作为一般规则,指针变量的赋值最好通过设置为其他内容的地址来完成。
int k, *p = &k;