声明types的指针?

我刚刚读到,我们需要指定types的指针,而在C(或C ++)中声明它们,即:

int *point ; 

据我所知,指针存储variables的地址,地址占用相同数量的内存,无论types如何。 那么,为什么我们需要声明它的types呢?

types安全。 如果你不知道p应该指向什么,那么就没有什么可以防止类似的错误

 *p = "Nonsense"; int i = *p; 

静态types检查是防止这种types的错误的一个非常强大的工具。

C和C ++也支持指针运算 ,只有在目标types的大小已知时才能运行。

地址占用相同数量的内存,无论我是什么types

对于当今stream行的平台来说,情况是如此。 但是有些情况并非如此。 例如,指向多字节字的指针可能小于指向单个字节的指针,因为它不需要表示字中字节的偏移量。

因为:

  1. 不同types的地址不需要具有相同的大小 。 标准明确规定了( C 2011标准 (在线草案),6.2.5 / 28)。
  2. types安全性:这允许编译器检测何时提供不兼容的函数指针或赋值。 这反过来可以防止丑陋的情况下,你弄乱了函数的参数顺序。
  3. 当指针被解除引用时,编译器需要知道types。
  4. 做指针算术,指向的对象的大小需要知道,因此它的types。

最后两点不适用于void指针,这就是为什么它们不能被解除引用,并且不能对它们进行指针运算。 该标准指定一个void指针必须足够大以容纳任何types的指针(除了函数指针,这是完全不同的故事),并且可以在没有强制转换的情况下进行void指针的分配(至less在C中,在C ++中总是需要投)

一个原因是在指针运算。 除非知道p指向的元素的大小 – 即p是指针的types的大小,否则不能执行p+1 。 如果你想在一个void *p上尝试p+1 ,你很可能会得到一个不好的答案(就像在char *上做的一样),但也许你不想要这个;它被抓住了,作为错误的警告和错误)。

另一个原因是types安全。 如果一个函数接收到一个int *参数,那么你不能在这里传递一个指向char (一个string)的指针。 你会得到一个警告(一个错误-pedantic-errors / -pedantic-errors )。 考虑这个(虚拟)代码:

 void test(int *x) { } int main() { char *x = "xyz"; test(x); return 0; } 

编译(使用gcc (GCC) 4.8.2 20131017 (Red Hat 4.8.2-1) )给出:

 1.c: In function 'main': 1.c:8:2: warning: passing argument 1 of 'test' from incompatible pointer type [enabled by default] test(x); ^ 1.c:1:6: note: expected 'int *' but argument is of type 'char *' void test(int *x) ^ 

那么,为什么我们需要声明它的types呢?

你想知道指针的types,所以你可以做静态types检查 。

我们还需要知道types,以便使指针运算起作用,例如,当我们索引到不同大小types的数组( 相当于指针运算 )时,指针将按types相关的数量进行调整。 如果我们看看C99标准的草案部分6.5.6 添加剂操作员说( 强调我的 ):

另外,两个操作数都应该有算术types,或者一个操作数应该是一个指向对象types的指针 […]

所以指针需要是一个对象types ,这意味着不完整或无效。

你还说:

地址占用相同数量的内存,无论types如何。 那么,为什么我们需要声明它的types呢?

这在C ++中并不总是正确的,指向成员函数的指针的大小可以根据类的types而改变,其中涵盖了这个指向成员函数的指针是非常奇怪的动物之一 。

此外,我们可以看到,C99标准草案部分6.2.5 types的27段说:

[…]指向其他types的指针不需要具有相同的表示或alignment要求。

和C ++标准草案部分3.9.2 复合types3段说:

[…]指针types的值表示是实现定义的。 指向布局兼容types的cv-qualified和cv-unqualified版本(3.9.3)的指针应具有相同的值表示和alignment要求(3.11)。 […]

除特殊情况外,不要求指针具有相同的表示

您需要按照标准要求来指定types。 而且,当您尝试执行像加法或减法这样的指针运算时,没有任何问题。

虽然处理器通常具有“从地址加载字节”,“从地址加载16位半字”和“从地址加载32位字”的不同指令,对于“存储”操作,C使用相同的语法从地址加载一个字节,以加载任何其他大小的值。 鉴于声明:

 int n = *p; 

编译器可以生成从p中的地址加载字节,半字或字并将其存储到n中的代码; 如果p是一个* float,它可能会产生一个更复杂的代码序列来加载c中的浮点值,截断它,转换为int,并将转换后的值存储到n中。 不知道p的types,编译器不知道哪个操作是合适的。

同样,语句p++可能会增加p++的地址一个,两个,四个或其他数字。 地址增加的数量将在声明的p的types上。 如果编译器不知道p的types,它将不知道如何调整地址。

可以声明一个指针而不指定它指向的东西的types。 这种指针的types是void* 。 然而,在做任何有用的事情之前,必须将void*转换为真正的指针types。 void*的主要用处在于,如果一个指针被转换为void* ,那么它可以作为一个void*被代码传递,这个代码对指针的实际types一无所知。 如果指针最终被赋予了知道其types的代码,并且该代码将指针转换回该types,则结果将与已转换为void*的指针相同。

必须处理指向它一无所知事物的代码的代码通常可以有用地将void*用于这样的目的,但是知道指针指向的事物的代码通常应该声明适当types的指针。

在解引用和指针算术的时候,指针的types就会起作用。 例如

 int x=10; //Lets suppose the address of x=100 int *ptr=&x; //ptr has value 100 printf("The value of x is %d", *ptr); ptr++; // ptr has value 104(if int is 4bytes) 

在上面的例子中,指针types是int,因此编译器将从内存地址100开始查找存储在接下来的4个字节(如果int是4字节)中的值。所以指针的types告诉编译器它应该有多less字节寻找解引用。 如果指针types不存在,那么编译器将如何知道在解引用时要查看多less个字节。 而当我们做了ptr ++的指针types告诉多lessptr应该增加。 这里ptr增加4。

 char c='a'; //Lets suppose the address of c = 200 char* ptr=&c; //ptr has value 200 ptr++; //ptr has value 201(char assumed to be 1 byte) 

指针types告诉ptr增加1个字节。

这样它可以执行算术和其他操作。 考虑这两个例子:

 int* p; /* let the address of the memory location p pointing to be 1000*/ p++; printf("%u",p); /* prints 1004 since it is an integer pointer*/ char *p; /* let the address of the memory location p pointing to be 1000*/ p++; printf("%u",p); /* prints 1001 since it is an char pointer*/ 

我希望这可以帮助你 !

我们实际上不需要 (见下文)来声明types,但我们应该 。 指针存储关于对象位置的信息,而types定义了在内存中占用多less空间。

存储在指针内存中的对象的大小在各种情况下都是需要的 – 创build数组,创build,分配内存,最后使用new创build对象。

但是你仍然可以定义一个void指针,如果你想隐藏(出于任何原因)types:

 void* dontKnowWhatTypeIsHere; 

一个空指针被认为是一个普遍的指针。 它可以指向任何对象,当我们想要使用它的types,我们只会做reinterpret_cast

很多前面的陈述,但是apan纯粹是正确的。 现在你的问题为什么我们定义types的指针? 指针的第一个定义一个可以容纳另一个variables地址的指针。 以上定义是部分的。 确切的定义是指针是一个variables,它可以保存一个variables的地址,如果我们去引用(取值),它将返回该地址上的当前值。 如果指针无法在解引用上返回一个值,那么它不是一个指针。 你可以尝试,即使在gcc编译器中,一个简单的variables也可以保存另一个variables的地址,但是在解引用的时候会给你一个错误。 现在的大小无论数据types如何,指针的大小总是等于特定编译器的整数大小。 所以gcc编译器中指针的大小是4字节(整数的大小),在turboc中它的大小是2字节(整数的大小)。 现在问题是为什么等于整数的大小。 什么将是任何variables的地址,它可能是int,char,float等地址总是一个整数,整数的整数存储在int中。 这就是为什么指针的大小等于int的大小,因为它也存储始终是纯整数数据的地址。 那么int和char之间的区别是什么其他数据types的指针。 在检索的时候,你的编译器会根据你的数据types提取字节数,否则你会得到错误或者不是错误,但是对于你来说有些不可预知的结果,但是对我来说却不是这样。 同样的规则适用于递增和递减指针,它总是根据指针数据types递增和递减。 指针的大小并不取决于数据types,因此你的链接列表出现的原因是因为如果你试图在同一个variables中声明结构,那么你会得到编译时错误,因为你的编译器的大小不是结构之前,它的完整的声明,但同样的结构的自我指针指针允许为什么? 唯一的答案是因为指针的大小不取决于数据types的大小。 如果你有任何疑问,然后请问我。 感谢asif aftab