在很多标准的开源代码中,我在不同的地方看到使用不同的指针类型,如:
uint32 fooHash (uint8 *str, uint32 len)
我没有得到以下内容: - 为什么要将int声明为uint32,uint8? 所有这些都将在用户空间本身运行,那么为什么不留下自己呢? 以后便携性不是一个问题吗?
答案 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
'元素的地址。如果T
为int
,则p + i
会向我们提供i
之后的p
'整数的地址。如果T
为struct 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 int
。 uint8*
可用于多种用途:字符串,二进制数据(例如网络数据包或文件的一部分)。
有时您只需要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