为什么我们使用C语言中的指针来存储变量的地址?似乎可以简单地将unsigned int声明为存储地址。
我的问题和下面的问题之间的区别是,他们询问具有不同指针类型的原因,而我询问语言中仅存在指针的原因。
已经很清楚地址是引用内存位置的数字,因此不清楚为什么仅访问数字是不够的。
相关但不同的问题:
答案 0 :(得分:6)
完全有可能没有指针的语言。实际上,可以编写一个C程序,在其中将地址存储在常规整数变量中,然后将其转换为指针。调用指针,以及类型的一般概念,语法糖可以稍微扩展它,但它也不是完全不正确的。
原因是拥有不同的类型非常有价值。这使编译器可以进行类型检查和自动转换。它还允许编译器在您执行可能不是您想要的操作时警告您。例如,看下面的C代码:
int x;
int *p;
// Init x and p somehow
int y = p + x; // Legal, but you probably meant y = *p + x
早于C的早期语言B只有一种叫做“单词”的类型。它用于整数,指针,浮点数或其他任何东西。由程序来解释位模式。
考虑以下C代码:
int i=5;
float f=3.5;
float x=f+i;
在最后一条语句中,将在执行浮点加法之前将i
提升为float
。没有类型信息,这将是不可能的。现在x
的值为8.5
(舍入误差被忽略),但是现在考虑这个伪代码,它说明了使用B等语言时可能遇到的问题:
word i, f, x;
i = 5;
f = 3.5;
x = i + f;
您期望变量x
包含什么?那个位模式应该代表什么类型?
当涉及到指针时,这是非常有价值的。考虑到您有两个指针char *cptr
和int *iptr
。现在让我们看一下一些指针算法。当将整数添加到指针时,我们将相对于类型的大小偏移指针 。因此,*(cptr + 1)
将返回cptr
之后一个字节的值,而*(iptr + 1)
将(通常)返回iptr
之后4或8个字节的地址上的值。
这是一个非常接近您的问题的示例。考虑下面的C代码:
float *p = malloc(10 * sizeof (*p));
for(int i=0; i<10; i++)
p[i]= i * 1.2;
for(int i=0; i<10; i++)
printf("%f\n", p[i]);
如果没有指针类型,那么我们将不得不编写如下代码:
unsigned p = malloc(10 * sizeof(float));
for(int i=0; i<10; i++)
*(p + i*sizeof(float)) = i * 1.2;
for(int i=0; i<10; i++)
printf("%f\n", (float) *(p + i*sizeof(float)));
如果您确实想要,您实际上可以在C中做类似的事情。这是一个可以编译和运行的示例,尽管带有警告并且可能具有未定义的行为,但是它在我的计算机上产生了预期的结果:
unsigned p = malloc(10 * sizeof(float));
for(int i=0; i<10; i++)
*((float*)p + i*sizeof(float)) = i * 1.2;
for(int i=0; i<10; i++)
printf("%f\n", *((float*)p + i*sizeof(float)));
答案 1 :(得分:1)
因为它通过提供有关该变量的用途,它可以具有的值以及可以对其执行哪些操作的提示,对程序员您有所帮助。
计算机不在乎。
答案 2 :(得分:1)
如其他答案所述,为指针使用单独的类型可以澄清意图,并允许编译器执行与使用指针有关的检查。
即使没有这种情况,对指针使用整数类型也是有意义的。假设,将内存引用为字节的平面数组。但是,并非所有系统都必须用单个整数表示内存地址。
一个值得注意的例子是实模式下的x86处理器。这些处理器之一启动时,它将以实模式启动。此模式一直返回到原始的16位8086处理器。在此模式下,存储器以16位段和16位偏移量寻址,这两个地址共同构成20位地址。通过将段左移4位并加上偏移量来组合它们。例如:
segment: 0x1111
offset: 0x2222
address: 0x13332
在这样的布局中,也可能有两个具有不同数值的指针,它们引用相同的地址:
segment: 0x1110
offset: 0x2232
address: 0x13332
因此,一个值为0x1111:0x2222的指针和另一个值为0x1110:0x2232的指针指向同一地址。
此寻址模型还具有近指针和远指针的概念,其中近指针仅包含偏移量(并假定CS寄存器中的当前段),而远指针同时包含段和偏移量。
因此您不能仅用整数来表示指针,因为对于某些体系结构而言,这还不够。
答案 3 :(得分:0)
因为用不同的方式表示它们很有用。您还希望通过写出字符的十六进制值来指定字符串吗?