在C中,为什么不能将整数值赋给int *,就像将字符串值赋给char *一样?
我一直在浏览网站,但尚未找到答案。
用一个例子来解释这个问题是最容易的(至少对我来说)。
我不明白为什么这是有效的:
#include int main(int argc, char* argv[]) { char *mystr = "hello"; }
但是这会产生一个编译器警告(“初始化使整数从没有强制转换的整数中生成”):
#include int main(int argc, char* argv[]) { int *myint = 5; }
我对第一个程序的理解是创建一个名为mystr的变量,类型为pointer-to-char,其值是字符串文字“hello”的第一个字符(’h’)的地址。 换句话说,使用此初始化,您不仅可以获取指针,还可以定义指针指向的对象(在本例中为“hello”)。
那么,为什么int *myint = 5;
看似没有实现与此类似的东西,即创建一个名为myint的变量类型指针指向int,其值是值’5’的地址? 为什么这个初始化既不给我指针也定义指针所指向的对象?
实际上,您可以使用复合文字 ,即1999 ISO C标准添加到该语言中的function。
字符串文字的类型为char[N]
,其中N
是字符串的长度加1.与任何数组表达式一样,它在大多数但不是所有上下文中都隐式转换为指向数组第一个元素的指针。 所以这:
char *mystr = "hello";
为指针mystr
分配内容为"hello"
的数组的初始元素的地址(后跟终止'\0'
空字符)。 顺便说一句,写起来更安全:
const char *mystr = "hello";
整数没有这种隐式转换 – 但你可以这样做:
int *ptr = &(int){42};
(int){42}
是复合文字,它创建一个初始化为42
的匿名int
对象; &
获取该对象的地址。
但要小心:由字符串文字创建的数组始终具有静态存储持续时间,但复合文字创建的对象可以具有静态或自动存储持续时间,具体取决于它出现的位置。 这意味着如果从函数返回ptr
的值,则指针仍指向它时,具有值42
的对象将不再存在。
至于:
int *myint = 5;
尝试将值5
分配给int*
类型的对象。 (严格来说,这是初始化而不是赋值,但效果是一样的)。 由于没有从int
到int*
隐式转换(除了0
的特殊情况被视为空指针常量),这是无效的。
当你做char* mystr = "foo";
,编译器将在可执行文件的特殊只读部分中创建字符串"foo"
,并有效地将语句重写为char* mystr = address_of_that_string;
对于任何其他类型,包括整数,都没有实现相同的function。 int* myint = 5;
将myint
设置为指向地址5
。
“在C中,为什么不能将整数值赋给int *,就像将字符串值赋给char *一样?”
因为它甚至不是类似的情况,更不用说“同样的方式”。
字符串文字是一个char
数组,它是一个数组,可以隐式转换为指向其第一个元素的指针。 所述指针是char *
。
但是, int
既不是指针本身,也不是数组,也不是任何其他可隐式转换为指针的东西。 这两种情况没有任何共同之处。
我将我的答案分成两部分:
1,为什么char* str = "hello";
已validation:
char* str
为指针声明一个空格(表示当前体系结构上的内存地址的数字)
当你写"hello"
你实际上用6个字节的数据填充堆栈
(不要忘记空终止)让我们说地址0x1000 - 0x1005
。
str="hello"
将该5个字节(0x1000)的起始地址分配给*str
所以我们拥有的是:
1. str
,在内存中占用4个字节 ,保存数字0x1000
(仅指向第一个字符!)
2. 6字节 ‘h”e”””””’0’
2,为什么int* ptr = 0x105A4DD9;
无效:
好吧,这不完全正确!
如前所述,指针是一个代表地址的数字,
那么为什么我不能分配这个号码?
它并不常见,因为大多数情况下您提取数据地址而不是手动输入地址。
但你可以,如果你需要! …
因为它不是常见的东西,
编译器希望确保您在建议中这样做,而不是错误地强制您将数据作为CAST
int* ptr = (int*)0x105A4DD9;
(主要用于内存映射的硬件资源)
希望这清楚的事情。
干杯
第一个程序实际上是创建一个指向字符串的指针,该字符串是一个字符数组。 在这种情况下,数组实际上将是一个指针。 在第二个程序中,您将一个标量整数值赋给指针。
你应该试试这个:
int main(int argc, char* argv[]) { int temp = 5; int * my_int_pointer = &temp; }
问题是您正在尝试将地址5分配给指针。 在这里你不是解引用指针,你将它声明为指针并将其初始化为值5(作为一个肯定不是你打算做的地址)。 您可以执行以下操作。
#include int main(int argc, char* argv[]) { int *myint, b; b = 5; myint = &b; }