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

时间:2015-07-21 19:46:42

标签: c pointers char int

我一直在浏览网站,但尚未找到答案。

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

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

#include <stdio.h>

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

但是这会产生一个编译器警告(&#34;初始化使得指针来自整数而没有强制转换&#34;):

#include <stdio.h>

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

我对第一个程序的理解是创建一个名为mystr的变量,类型指针指向char,其值是字符串文字的第一个字符(&#39; h&#39;)的地址& #34;你好&#34 ;.换句话说,通过初始化,您不仅可以获取指针,还可以定义指针指向的对象(在这种情况下为#34; hello&#34;)。

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

6 个答案:

答案 0 :(得分:9)

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

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

char *mystr = "hello";

为指针mystr分配内容为"hello"的数组的初始元素的地址(后跟终止'\0'空字符)。 顺便说一句,写起来更安全:

const char *mystr = "hello";

整数没有这种隐式转换 - 但你可以这样做:

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

(int){42}是复合文字,用于创建初始化为int的匿名42对象; &获取该对象的地址。

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

至于:

int *myint = 5;

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

答案 1 :(得分:0)

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

对于任何其他类型,包括整数,都没有实现相同的功能。 int* myint = 5;会将myint设置为指向地址5

答案 2 :(得分:0)

我会将答案分成两部分:

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

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

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

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

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

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

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

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

希望这清楚。“ 干杯

答案 3 :(得分:0)

&#34;在C中,为什么不能将整数值赋给int *,就像将字符串值赋给char *一样?&#34;

因为它的甚至不是类似的情况,更不用说#34;同样的方式&#34;。

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

但是int既不是指针本身,也不是数组,也不能隐式转换为指针。这两种情况只是没有任何共同之处。

答案 4 :(得分:-2)

问题是您正在尝试将地址5分配给指针。在这里你不是解引用指针,你将它声明为指针并将其初始化为值5(作为一个肯定不是你打算做的地址)。您可以执行以下操作。

#include <stdio.h>

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

答案 5 :(得分:-2)

第一个程序实际上是创建一个指向字符串的指针,该字符串是一个字符数组。在这种情况下,数组实际上是指针本身。在第二个程序中,您将标量整数值分配给指针。

你应该试试这个:

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