在 C 中,为什么不能像将字符串值分配给 char* 一样将整数值分配给 int*?

In C, why can't an integer value be assigned to an int* the same way a string value can be assigned to a char*?

我一直在浏览网站,但还没有找到这个问题的答案。

用一个例子来解释这个问题是最简单的(至少对我而言)。

我不明白为什么这是有效的:

#include <stdio.h>

int main(int argc, char* argv[])
{
  char *mystr = "hello";
}

但这会产生编译器警告 ("initialization makes pointer from integer without a cast"):

#include <stdio.h>

int main(int argc, char* argv[])
{
  int *myint = 5;
}

我对第一个程序的理解是,创建一个名为mystr的变量,类型为pointer-to-char,其值是字符串字面量的第一个字符('h')的地址"hello"。换句话说,通过此初始化,您不仅可以获取指针,还可以定义指针指向的对象(在本例中为 "hello")。

那么,为什么 int *myint = 5; 似乎没有实现与此类似的东西,即创建一个名为 myint 的指针类型变量,其值是值“5”的地址?为什么这个初始化既不给我指针又定义指针指向的对象?

问题是您正试图将地址 5 分配给指针。在这里,您没有取消引用指针,而是将其声明为指针并将其初始化为值 5(作为地址,这肯定不是您打算做的)。您可以执行以下操作。

#include <stdio.h>

int main(int argc, char* argv[])
{
  int *myint, b;
  b = 5;
  myint = &b;
}

当您执行 char* mystr = "foo"; 时,编译器将在您的可执行文件的特殊只读部分创建字符串 "foo",并有效地将语句重写为 char* mystr = address_of_that_string;

任何其他类型(包括整数)都没有实现相同的方法。 int* myint = 5; 将设置 myint 指向地址 5

事实上,您可以使用 复合文字,这是 1999 年 ISO C 标准添加到语言中的一项功能。

字符串文字的类型为 char[N],其中 N 是字符串的长度加 1。与任何数组表达式一样,它隐式 converted ,在大多数但不是所有情况下,指向数组第一个元素的指针。所以这个:

char *mystr = "hello";

向指针 mystr 分配内容为 "hello" 的数组的初始元素的地址(后跟终止 '[=18=]' 空字符)。 顺便说一下,这样写更安全:

const char *mystr = "hello";

整数没有这样的隐式转换——但您可以这样做:

int *ptr = &(int){42};

(int){42} 是一个复合字面量,它创建一个初始化为 42 的匿名 int 对象; & 获取该对象的地址。

但要注意:由字符串文字创建的数组始终具有静态存储持续时间,但由复合文字创建的对象可以具有静态或自动存储持续时间,具体取决于它出现的位置。这意味着如果从函数返回 ptr 的值,则具有值 42 的对象将不复存在,而指针仍指向它。

至于:

int *myint = 5;

尝试将值 5 分配给类型 int* 的对象。 (严格来说是初始化而不是赋值,但是效果是一样的)。由于没有从 intint* 的隐式转换(除了 0 被视为空指针常量的特殊情况),这是无效的。

我会将我的回答分为两部分:

1、为什么char* str = "hello";有效:

char* str 为指针声明一个space(代表当前架构上的内存地址的数字)

当你写 "hello" 时,你实际上用 6 个字节的数据填充了堆栈
(不要忘记空终止)让地址 0x1000 - 0x1005.

str="hello" 将那 5 个字节 (0x1000) 的起始地址分配给 *str

所以我们拥有的是:
1. str,在内存中占用 4 个字节,保存数字 0x1000(仅指向第一个字符!)
2. 6字节 'h' 'e' 'l' 'l' 'o' '\0'

2、为什么 int* ptr = 0x105A4DD9; 无效:

嗯,这不完全正确!
如前所述,指针是代表地址的数字,
所以 为什么我不能分配那个号码?

这并不常见,因为大多数情况下您提取数据地址而不是手动输入地址。
但如果你需要,你可以!!!...
因为这不是通常做的事情,
编译器希望确保您在提议时这样做,而不是错误地强制您将数据转换为
int* ptr = (int*)0x105A4DD9;
(主要用于内存映射硬件资源)

希望这一切都清楚。
干杯

"In C, why can't an integer value be assigned to an int* the same way a string value can be assigned to a char*?"

因为连类似的情况都没有,更不用说"the same way"了。

字符串文字是 char 的数组,作为数组,它可以隐式转换为指向其第一个元素的指针。所说的指针是一个char *.

但是 int 本身既不是指针,也不是数组,也不是任何其他可隐式转换为指针的对象。这两种情况只是没有任何共同点。