Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/68.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C 为什么使用不同的指针类型?_C_Pointers_Kernel - Fatal编程技术网

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

C 为什么使用不同的指针类型?,c,pointers,kernel,C,Pointers,Kernel,在许多标准开源代码中,我看到在不同的地方使用了不同的指针类型,如: uint32 fooHash (uint8 *str, uint32 len) 我不明白的是: -为什么要将int声明为uint32、uint8? 所有这些都将在用户空间本身中运行,那么为什么不作为uint本身呢? 可移植性不是以后的问题吗 另外,如果您想在32位系统上运行开源代码,为什么要将指针作为 uint8*ptr 指针的类型指的是它包含的数据类型,而不是指针本身的大小。实际上,所有指针的大小都相同。([*]但请参见下

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

uint32 fooHash (uint8 *str, uint32 len)
我不明白的是: -为什么要将int声明为uint32、uint8? 所有这些都将在用户空间本身中运行,那么为什么不作为uint本身呢? 可移植性不是以后的问题吗

  • 另外,如果您想在32位系统上运行开源代码,为什么要将指针作为 uint8*ptr

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

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


要回答你问题的另一面。。。这些类型之所以显式,是因为并非所有编译器都同意
int
的大小。这是一种可移植性。

并非所有数据都要存储为
签名int
uint8*
有很多用途:字符串、二进制数据(如网络数据包或文件片段)

有时您只需要uint8,因为您要在那里存储的值的范围位于
[0256[


不要忘记,我们谈论的不是指针的类型,而是指针数据的类型。指针是指针(根据体系结构,其大小正确)。它指向任何类型。

这一切都取决于您使用的硬件和编译器

如果只使用int,可以得到不同的大小。在unix和windows上也可以得到不同的大小

编译器所需的一切都来自C99标准

sizeof(short) <= sizeof(int) <= sizeof(long) < sizeof(long long)
你应该看看

以下保证是它们命名的大小

int8_t
int16_t
int32_t
int64_t
int8_t 
另外,如果您想在32位系统上运行开源代码,为什么要将指针设为uint8*ptr

uint8\u t
是指针指向的对象的大小,而不是指针本身的大小;
*ptr
表达式的类型是
uint8\u t
。对象的类型
ptr
uint8\u t*
,它与系统需要的大小一样大(32位、64位,随便什么)

在计算指针算法时,基类型很重要

T *p;
表达式
p+i
的计算结果是
p
之后
T
类型的
i
第个元素的地址。如果
T
int
,那么
p+i
给我们
p
之后的
i
第个整数的地址。如果
T
struct
,那么
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;
}
#包括
#包括
内部主(空)
{
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));
返回0;
}
产出

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

“所有指针实际上都是相同的大小。”-实际上,大多数情况下(但并不总是如此)。但标准没有规定。指向数据的指针的大小很少不同(但正如H2CO3所说,这不是标准所规定的)。但是,指向数据的指针和指向函数(或成员函数)的指针……感谢您的澄清。我习惯于认为所有指针的大小都与
void*
…相同,这可能是错误的。=)由于
ptr+1
(或
ptr[1]
)。在内部,编译器必须知道从
ptr
(1字节用于
uint8*
,4字节用于
uint32*
,42字节用于
struct fortytwo*
,…)使用uint8而不是字符有价值吗?如果你存储的是无符号值,那么肯定有价值。谢谢,但我有另一个基本问题…不敢相信我问的是如此基本的问题,但我真的很困惑。所以对于uint8_t*p0的情况,我们有p0=0x4000和(p0+1)在32位体系结构上=0x4001。现在,p0和(p0+1)应该相差1字节或8位。但是0x4000将是0100 0000,0x4001将是0100 0000 0001。我无法理解它们如何相差8位或1字节:(:(我在这里遗漏了什么?@user999755:记住0x4000和0x4001是地址,x86是字节寻址体系结构。0x4000是一个字节的地址,0x4001是下一个字节的地址。 p0 = 0x4000, (p0 + 1) = 0x4001 p1 = 0x4000, (p1 + 1) = 0x4004