我对指针的了解是,它用于指向特定的位置(内存地址),所以为什么我们甚至还需要与试图指向的变量相同的指针数据类型。 假设我创建了一个整数变量,那么我必须创建一个指向整数的指针以指向它。那么,为什么不能创建一个void指针或float指针来指向存储在该整数变量中的值! 我是否缺少一些指针概念?
答案 0 :(得分:4)
那为什么我不能创建一个空指针[...]来指向存储在该整数变量中的值
您可以做到,没问题:
int x = 10;
double y = 0.4;
void* v = &x;
v = &y;
但是现在想象一下这样的函数:
void print(void* value)
该函数如何知道如何处理指针位置的内存?是整数吗?还是浮点数? float
还是double
?可能是巨大的struct
或一组值?您必须知道这一点才能正确地取消对指针的引用(即读取内存),因此只有对不同类型的指针使用不同的指针类型才有意义:
void print(int* value)
此函数知道指针指向int
,因此它可以很高兴地取消引用以获取int
值。
答案 1 :(得分:2)
在处理数组时,指针类型也很重要,因为数组和指针可以互换。当增加一个指针时(这就是索引的作用),您需要知道该类型的大小(int,long,结构,类)以便访问下一项。
arr [5] == *(arr + 5)但是 5什么?这由类型决定。
答案 2 :(得分:2)
Max Langhof答案的一小部分内容:
重要的是要意识到,最后,变量被简单地存储为一系列位(二进制数字),例如01010101 00011101 1110001011110000。您的程序如何知道此“含义”?它可以是整数(在现代体系结构中通常为4个字节),也可以是浮点值。对于所涉及的内存,这没有什么区别,但是对于您的代码,影响可能是巨大的。因此,如果(使用指针)引用该存储位置,则需要指定如何将其中的字节转换为十进制(或其他)值。
答案 3 :(得分:1)
指针算术是主要原因-如果p
指向类型为T
的对象,则p+1
指向该类型的下一个对象。如果p
指向4字节的int
,则p+1
指向随后的4字节的int
。如果p
指向128字节的struct
,则p+1
指向以下128字节的结构。如果p
指向double
的2 KB数组,则p+1
指向double
的下一个2 KB数组,依此类推。
但是出于同样的原因,我们首先要使用不同的类型-在抽象机器级别,我们要区分不同类型的数据和该数据上允许的操作。指向int
的指针不同于指向double
的指针,因为int
与double
不同。
答案 4 :(得分:0)
你是对的。尽管int
和float
是不同的类型,但它们的指针int*
和float*
之间应该没有区别。在常规中,就是这种情况。但是,int
和float
之间的二进制表示形式有所不同。因此,使用int
指针访问float*
会导致从RAM中读取垃圾。
此外,您的计算机所拥有的不是一般情况,而是取决于硬件和实现。
例如:float
和int
变量通常为32位长。但是,有些系统中int
只有16位。如果您尝试从float
指针中读取int*
,会发生什么? (或者,即使两者都是32位的,如果您尝试从float
读取char*
怎么办?)
答案 5 :(得分:0)
在不知道您要处理哪种数据对象的情况下无法进行内存访问。
想象一些简单的任务:
int a, b=10;
float f;
a = b; // same type => Just copy the integer
f = b; // wrong type => Convert to float.
这很好用,因为编译器知道两个变量都具有某种类型,大小和表示形式。如果类型不匹配,则会应用正确的转换。
现在与键入指针相同:
int a = 10;
float f;
int *pa;
float *pf;
f = a; // Type conversion to float applied
*pa = a; // Just copy
*pf = a; // Type conversion
如果您不了解有关指针指向的内存位置的知识,那么编译器将如何知道是否需要转换? 还是需要整数传播,或者整数被截短为较短的类型?
如果要使用指针寻址数组元素,更多问题就在附近。没有类型,指针算术就不会飞。
类型是必不可少的。对于变量以及指针。