为什么使用不同的指针类型

时间:2013-01-09 21:09:18

标签: c pointers kernel

在很多标准的开源代码中,我在不同的地方看到使用不同的指针类型,如:

uint32 fooHash (uint8 *str, uint32 len)

我没有得到以下内容: - 为什么要将int声明为uint32,uint8?   所有这些都将在用户空间本身运行,那么为什么不留下自己呢?   以后便携性不是一个问题吗?

  • 另外,如果你想在32位系统上运行开源代码,为什么有一个指针 uint8 * ptr?

4 个答案:

答案 0 :(得分:5)

指针的类型是指它包含的数据类型,而不是指针本身的大小。所有指针实际上都是相同的大小。 ([*]但请参阅下面的评论)

如果您有uint8*,则指针指向uint8值的数组。这与uint32*不同,后者引用uint32值数组。

回答你问题的另一面......明确这些类型的原因是因为并非所有编译器都同意int的大小。这是一种便携性的东西。

答案 1 :(得分:3)

  

另外,如果你想在32位系统上运行开源代码,为什么指针为uint8 * ptr?

uint8_t是指针指向的大小,而不是指针本身的大小; 表达式 *ptr的类型为uint8_t对象 ptr的类型是uint8_t *,它与系统需要的大小一样大(32位,64位,无论如何)。

计算指针算术时基类型很重要。给出一个指针声明

T *p;

表达式p + i计算i之后T类型的p'元素的地址。如果Tint,则p + i会向我们提供i之后的p'整数的地址。如果Tstruct humongous,那么p + i会向我们提供i之后p'庞大结构的地址。例如:

#include <stdio.h>
#include <stdint.h>

int main(void)
{
  uint8_t  *p0 = (uint8_t *)  0x00004000;
  uint32_t *p1 = (uint32_t *) 0x00004000;

  printf("p0 = %p, (p0 + 1) = %p\n", (void *) p0, (void *)(p0 + 1));
  printf("p1 = %p, (p1 + 1) = %p\n", (void *) p1, (void *)(p1 + 1));

  return 0;
}

产生输出

p0 = 0x4000, (p0 + 1) = 0x4001
p1 = 0x4000, (p1 + 1) = 0x4004

指针不一定都是相同的大小,或具有相同的表示。例如,在哈佛架构中,指令和数据存储在不同的内存区域中,并且可能具有不同大小的总线,因此对象指针(int *char *float *)可能是一个大小(比如8位)和函数指针(int (*foo)(void))可以是不同的大小(比如16位)。类似地,在字寻址架构上,char *可能比其他指针类型宽几位,以指定字中的偏移量。

答案 2 :(得分:2)

并非所有数据都要存储为signed intuint8*可用于多种用途:字符串,二进制数据(例如网络数据包或文件的一部分)。

有时您只需要uint8,因为您要存储的值范围位于[0,256[

不要忘记我们不是在谈论指针的类型,而是关于指向数据的类型。无论指向何种类型,指针都是一个指针(根据架构尺寸正确)。

答案 3 :(得分:0)

这完全取决于您使用的硬件和编译器。

如果您只使用int,则可以获得不同的大小。你也可以在unix vs windows上获得不同的大小。

编译器所需的全部内容来自C99标准

sizeof(short) <= sizeof(int) <= sizeof(long) < sizeof(long long)

以下是Windows平台的int类型大小(位):

Type           C99 Minimum     Windows 32bit
char           8               8
short          16              16
int            16              32
long           32              32
long long      64              64

你应该看看

以下内容保证为

命名的大小
int8_t
int16_t
int32_t
int64_t
int8_t