应该指针在c中签名或未签名

时间:2016-10-25 15:04:55

标签: c int microcontroller

我有一个功能get_picture()可以拍照。它返回一个类型为uint8_t的指针(其中存储了pciture)并获取了一个指向变量的指针 存储图片的长度。

以下是声明:

uint8_t * get_picture(int *piclength)

我在main()

中将其称为
unsigned int address, value;
address = (unsigned int)get_picture((int*)& value);

我的问题是 - 如果我将address实际定义为int,那么sections = [ Section(title: "A", word: []), Section(title: "B", word: []), Section(title: "C", word: []), Section(title: "D", word: []), Section(title: "E", word: []), Section(title: "F", word: []), Section(title: "G", word: []), Section(title: "H", word: []), Section(title: "I", word: []), Section(title: "J", word: []), Section(title: "K", word: []), Section(title: "L", word: []), Section(title: "M", word: []), Section(title: "N", word: []), Section(title: "O", word: []), Section(title: "P", word: []), Section(title: "Q", word: []), Section(title: "R", word: []), Section(title: "S", word: []), Section(title: "T", word: []), Section(title: "U", word: []), Section(title: "V", word: []), Section(title: "W", word: []), Section(title: "X", word: []), Section(title: "Y", word: []), Section(title: "Z", word: []) ] 正在存储一个地址(这是正面的)。

3 个答案:

答案 0 :(得分:10)

我不确定你是否理解指针。

如果你的函数返回uint8_t *,那么你应该将它存储在uint8_t *而不是int。

举个例子:

uint8_t* get_picture(int* piclength);

int piclength;
uint8_t* address;
address = get_picture(&piclength);

答案 1 :(得分:2)

如果您真的想将数据指针转换为整数,请使用专用的typedef而不是一些随机(可能太小)的类型:
uintptr_t / intptr_t<stdint.h>中的可选typedef)

但是,这种需求很少见,我在这里看不到它。

答案 2 :(得分:0)

这取决于你真正追求的是什么。如果您希望地址包含该图片所在的地址,那么您的代码就可以了。同样,您可以使用int,因为位是位,int是与unsigned int相同的位数,并且可以为这些位提供任何消耗地址。将地址视为无符号的人更有意义,但编译器和硬件不关心,位是位。

但是根据您正在做的事情,您可能希望如上所述,使用相同类型的指针保留此地址。请参阅Dragan的回答。

如果你想&#34;看&#34;地址然后取决于你想看到它的方式,将它转换为unsigned int是一种简单而通用的方法。

是的,这是非常依赖于系统的,并且int的大小因工具链和目标而异,并且可能会或可能不会完全保存该系统的地址,因此该变量的使用者可能需要一些屏蔽。

所以你的代码很好,我想我理解这个问题。签名或未签名是在旁观者看来,它只是未签名或签署特定的特定操作。地址本身不是有符号也不是无符号,它们只是地址总线上的位。对于一个理智的编译器unsigned int和int是相同的大小,只要这个编译器将它们定义为至少这个编译器用于指针的地址的大小,就存储相同的位数,那么这对于int可以正常工作或unsigned int。 Int感觉有点不对劲,unsigned int感觉不错,但那些是人类的情感。硬件并不关心,只要这些位在去往地址总线的途中不会改变。现在,如果由于某种原因,我们看不到的代码将此变量打印为小数,例如printf(&#34;%d \ n&#34;,address); (为什么你会在微控制器上打印?)然后它对人类来说可能看起来很奇怪,但仍然是位模式的正确十进制解释而不是地址。的printf(&#34; 0X%X \ n&#34;,地址);会更有意义,更通用。如果你的printf支持它,你可以只是printf(&#34;%p&#34;,地址);使用Dragans uint8_t *地址声明,这是很多人可能会根据经典的C训练思考的。 vs比特是比特,并且在使用之前对硬件没有任何意义,并且仅对于该用例,地址只是地址总线上的地址,当对其进行数学计算以计算另一个地址时,它不是地址它是进入alu,有符号或无符号的位模式可能取决于操作(加和减不知道从无符号,乘法和除法中签名)。

如果您选择不使用uint8_t *地址作为声明,那么unsigned int&#34;感觉&#34;更好,不太可能弄乱你(如果你的(无符号)int中有足够的位用于该编译器首先存储地址)。签名的int感觉有点不对,但技术上应该有效。我的规则只是在你特别需要签名时使用签名,否则在其他地方使用unsigned,节省了很多bug。不幸的是,传统上C库反过来会这样做,在stdint.h之前发生了很大的混乱。

相关问题