我有一小段代码试图演示各种标准整数 类型并显示内存似乎在最大的堆栈中分配 数据类型首先。我写的内容似乎合情合理,直到最后一行我开始 太多输出字节。我真的只想(并期望)得到一个字节。
因此:
#include <stdint.h> /* defines the standard integer types */
#include <stdio.h> /* defines all the IO functions */
#include <stddef.h> /* standard definitions */
#include <stdlib.h> /* standard library functions */
int main ( int argc, char *argv[] ) {
int8_t little_i = 11;
int16_t med_i = 12062;
int32_t norm_i = 1991;
int64_t big_i = -3245321806;
/* these next items are pointers */
int8_t *little_p;
printf ( "here is a little 8-bit int : little_i = %02x\n", little_i );
printf ( "here is a medium 16-bit int : med_i = %04x\n", med_i );
printf ( "here is a normal 32-bit int : norm_i = %08x\n", norm_i );
printf ( "here is a big 64-bit int : big_i = %016lx\n", big_i );
printf ( "addr of little_i is %p" , &little_i );
printf ( " and the size is %d\n" , sizeof(little_i) );
printf ( "addr of med_i is %p" , &med_i );
printf ( " and the size is %d\n" , sizeof(med_i) );
printf ( "addr of norm_i is %p" , &norm_i );
printf ( " and the size is %d\n" , sizeof(norm_i) );
printf ( "addr of big_i is %p" , &big_i );
printf ( " and the size is %d\n" , sizeof(big_i) );
/* tell us about the pointer */
printf ( "\n--------------------------------------------------\n" );
printf ( " size of the pointer little_p is %d\n" , sizeof(little_p) );
printf ( " the address of the pointer itself is %p\n", &little_p );
little_p = &little_i;
printf ( "\nthe pointer little_p now contains the addr %p\n", little_p );
printf ( "The data there, in memory, at the addr %p is 0x%02xh\n",
little_p, *little_p );
/* we can point a pointer anywhere we want */
little_p = (void *) &big_i;
printf ( "\n\nthe pointer little_p now has the addr %p\n", little_p );
printf ( "The data there, in memory, at the addr is 0x%02xh\n",
*( (int8_t*) little_p) );
return ( EXIT_SUCCESS );
}
直到最后一行,我得到的输出看起来很棒:
$ ./dtypes
here is a little 8-bit int : little_i = 0b
here is a medium 16-bit int : med_i = 2f1e
here is a normal 32-bit int : norm_i = 000007c7
here is a big 64-bit int : big_i = ffffffff3e9051b2
addr of little_i is ffffffff7ffff56b and the size is 1
addr of med_i is ffffffff7ffff568 and the size is 2
addr of norm_i is ffffffff7ffff564 and the size is 4
addr of big_i is ffffffff7ffff558 and the size is 8
--------------------------------------------------
size of the pointer little_p is 8
the address of the pointer itself is ffffffff7ffff550
the pointer little_p now contains the addr ffffffff7ffff56b
The data there, in memory, at the addr ffffffff7ffff56b is 0x0bh
the pointer little_p now has the addr ffffffff7ffff558
The data there, in memory, at the addr is 0xffffffffh
我希望在最后一行只看到一个字节0xffh,但得到一个完整的32位整数大小的结果。我认为将little_p转换为类型为int8_t *的指针可以解决问题。
我错过了一些明显的东西吗?
-----刚发布此问题后更新:
我将那里的最后一行更改为转换为uint8_t *:
printf ( "The data there, in memory, at the addr is 0x%02xh\n",
*( (uint8_t*) little_p) );
这给了我输出:
The data there, in memory, at the addr is 0xffh
主要是因为内存中的字节一次只能是无符号8位。
似乎合理。
-----------进一步编辑以从64位整数中提取和打印字节------
这是一个更新的代码块:
$ cat dtypes.c
#include <stdint.h> /* defines the standard integer types */
#include <stdio.h> /* defines all the IO functions */
#include <stddef.h> /* standard definitions */
#include <stdlib.h> /* standard library functions */
int main ( int argc, char *argv[] ) {
int8_t little_i = 11;
int16_t med_i = 12062;
int32_t norm_i = 1991;
int64_t big_i = -3245321806;
void *little_p; /* void datatype is no datatype at all really. */
printf ( "here is a little 8-bit int : little_i = %02x\n", little_i );
printf ( "here is a medium 16-bit int : med_i = %04x\n", med_i );
printf ( "here is a normal 32-bit int : norm_i = %08x\n", norm_i );
printf ( "here is a big 64-bit int : big_i = %016lx\n", big_i );
printf ( "addr of little_i is %p" , &little_i );
printf ( " and the size is %d\n" , sizeof(little_i) );
printf ( "addr of med_i is %p" , &med_i );
printf ( " and the size is %d\n" , sizeof(med_i) );
printf ( "addr of norm_i is %p" , &norm_i );
printf ( " and the size is %d\n" , sizeof(norm_i) );
printf ( "addr of big_i is %p" , &big_i );
printf ( " and the size is %d\n" , sizeof(big_i) );
/* tell us about the pointer */
printf ( "\n--------------------------------------------------\n" );
printf ( " size of the pointer little_p is %d\n" , sizeof(little_p) );
printf ( " the address of the pointer itself is %p\n", &little_p );
/* we can point a pointer anywhere we want */
little_p = (void *) &big_i;
printf ( "\n\nthe pointer little_p now has the addr %p\n", little_p );
printf ( "The data there, in memory, at the addr is 0x%02xh\n",
*( (uint8_t*) little_p) );
printf ( " at addr+1 is 0x%02xh\n",
*( (uint8_t*) little_p+1 ) );
printf ( " at addr+2 is 0x%02xh\n",
*( (uint8_t*) little_p+2 ) );
printf ( " at addr+3 is 0x%02xh\n",
*( (uint8_t*) little_p+3 ) );
printf ( " at addr+4 is 0x%02xh\n",
*( (uint8_t*) little_p+4 ) );
printf ( " at addr+5 is 0x%02xh\n",
*( (uint8_t*) little_p+5 ) );
printf ( " at addr+6 is 0x%02xh\n",
*( (uint8_t*) little_p+6 ) );
printf ( " at addr+7 is 0x%02xh\n",
*( (uint8_t*) little_p+7 ) );
return ( EXIT_SUCCESS );
}
这给出了非常好的结果:
$ ./dtypes
here is a little 8-bit int : little_i = 0b
here is a medium 16-bit int : med_i = 2f1e
here is a normal 32-bit int : norm_i = 000007c7
here is a big 64-bit int : big_i = ffffffff3e9051b2
addr of little_i is ffffffff7ffff56b and the size is 1
addr of med_i is ffffffff7ffff568 and the size is 2
addr of norm_i is ffffffff7ffff564 and the size is 4
addr of big_i is ffffffff7ffff558 and the size is 8
--------------------------------------------------
size of the pointer little_p is 8
the address of the pointer itself is ffffffff7ffff550
the pointer little_p now has the addr ffffffff7ffff558
The data there, in memory, at the addr is 0xffh
at addr+1 is 0xffh
at addr+2 is 0xffh
at addr+3 is 0xffh
at addr+4 is 0x3eh
at addr+5 is 0x90h
at addr+6 is 0x51h
at addr+7 is 0xb2h
一切似乎都很好。
答案 0 :(得分:2)
这是因为地址处的数据为0xff
,因此符号位中的数据为1
。这意味着数据在转换为int
时会进行符号扩展,这会在值传递给printf
时发生。符号扩展意味着使用原始值的符号位填充int
的缺失字节。在这种情况下,这意味着用1填充其余的位,产生一串F
s(demo 1)。
答案 1 :(得分:1)
尝试强制转换为(uint8_t *),你的字节值为0xff,在十进制中为-1,它将符号扩展为32位,因此它最终为0xffffffffh(在二进制补码表示法中再次为-1)。因此,对无符号数据使用无符号类型。