百科生活 投稿
关于【c语言数据类型】,c语言中常见的数据类型,今天小编给您分享一下,如果对您有所帮助别忘了关注本站哦。
基础类型子曾经曰过:程序员要对自己所写程序的每个字节都了如指掌。
Talk is cheap,show me the binary code. by 高尔基
对于数据类型的分析,采用二进制文件和运行时的内存2个方面着手。
int / unsigned intintint n = 10; // 全局整型变量n,编译链接后将放到.data段, // 而且只有这一个变量,那它就是放到.data的起始位置int main() // C语言的入口函数{ int n1 = n;}
执行命令:
arm-none-eabi-objdump -h main.elf
得到elf文件各段的信息, 重点看.data段
main.elf: file format elf32-littlearmSections:Idx Name Size VMA LMA File off Algn 0 .text 000000bc 00000000 00000000 00010000 2**2 CONTENTS, ALLOC, LOAD, READONLY, CODE 1 .data 00000004 a0000000 000000bc 00020000 2**2 CONTENTS, ALLOC, LOAD, DATA 2 .comment 00000031 00000000 00000000 00020004 2**0 CONTENTS, READONLY 3 .ARM.attributes 0000002e 00000000 00000000 00020035 2**0 CONTENTS, READONLY
- 其中Size是段的大小,.data就是4,因为int型变量n就是4个字节大小。
- VMA是运行地址0xa0000000。
- LMA是load memory address及加载地址,为0xbc。
- File off为文件中的偏移,为0x20000。
- Algn对为对齐边界位置2**2即2的2次方=4,即4字节对齐。
- 下面的是段的相关属性,暂不表。
注意.data的地方:File off为0x00020000,表示.data段的内容放在main.elf文件的0x00020000开始的位置。
所以我们执行命令:
hexdump -C -s 0x20000 main.elf
得到如图高亮的位置 0a,就是10进制的10。
需要用到qemu命令x和xp命令
x /fmt addr Virtual memory dump starting at addr.xp /fmt addr Physical memory dump starting at addr. fmt is a format which tells the command how to format the data. Its syntax is: /{count}{format}{size} count is the number of items to be dumped. format can be x (hex), d (signed decimal), u (unsigned decimal), o (octal), c (char) or i (asm instruction). size can be b (8 bits), h (16 bits), w (32 bits) or g (64 bits). alt="c语言数据类型,c语言中常见的数据类型" src="http://p3.toutiaoimg.com/large/pgc-image/0b1533c9400d4ec9beff522f825ef39b" />
查看代码段的运行时地址 0xa0000000 处的一个4字节的数据,用10进制的格式显示。执行:
x /1dw 0xa0000000
得到结果:10,如图:
再试一个负数-2:
int n = -2; // 全局整型变量n,编译链接后将放到.data段, // 而且只有这一个变量,那它就是放到.data的起始位置int main() // C语言的入口函数{ int n1 = n;}
我们看到在内存中的16进制表示,这个是-2的补码表示。
综上:将int型变量在的分析完成。
unsigned int对于正整数赋值给unsigned int,和int类似。重点研究一下将负整数赋值给unsigned int有什么特别的。
- 对于无符号整形-2
unsigned int n = -2; // 全局无符号整型变量nint main() // C语言的入口函数{ int n1 = n;}
查看代码段的运行时地址 0xa0000000 处的一个4字节的数据,用16进制的格式显示。执行:
x /1dw 0xa0000000
如图:
说明:将整形的负数赋值给无符号整形变量,是将负数的补码赋给变量。
下面类型的分析就只dump内存的内容来分析,因为内存中的数据就是从二进制文件加载来的。有兴趣的读者可自行验证,方法与int型类似。
(unsigned )long、short、char与int、unsigned int类似,读者可自行实验。
float上代码:
float f = -2.5f; int main() // C语言的入口函数{ }
得到:
如图这个0xc0200000怎么来的呢?
这要从float的IEEE754标准来分析。参考:IEEE754 浮点数的表示方法_Dablelv的博客专栏-CSDN博客_浮点数表示方法
配合IEEE754标准,在网址:https://float.exposed/ 上可以直接查看输入的float数值的各种表示方式,比如本例中的-2.5,高亮的地方就是16进制的表示法:
float收工。
doubledouble d = -2.5; int main() // C语言的入口函数{ }
因为double占8个字节,我们要1个16进制的g,得到:
同float,在网址:https://float.exposed/ 输入double型的-2.5。得到:
上代码:
int n = 0xbabebabe;int * p ; int main() // C语言的入口函数{ p = &n;}
现在我们有2个全局变量n和p,我们把.data段的开头2个32位数据用16进制形式dump出来,得到:
很明显,0xa0000000开始的word值0xbabebabe就是变量n的值,也就是说变量n的地址就是0xa0000000。自然的因为p=&n;那p的值就是n的地址0xa0000000,所以第二个word的内容就是0xa0000000。符合语法中对指针的定义。
数组struct Student{};int n[4] = {1,2,3,4};int main() // C语言的入口函数{}
Dump 4个word出来,每个word用10进制表示:
看起来没啥特别的。
结构体struct Student{ int id; int age; int class_id; char name[32];};char* my_strcpy(char* dst, const char* src, int size){ int i; for ( i = 0; i < size; i ) { dst[i] = src[i]; } return dst;}struct Student std;int main() // C语言的入口函数{ std.id = 123; std.age = 12; std.class_id = 2; my_strcpy(std.name, "zhang san", 10); return 0;}
代码定义了一个全局结构体变量std。又因只有这个变量,那它就放到了数据段的起始地址处。所以我们还是dump 0xa0000000的数据:
可以看到,我分成了2步来dump,显示dump 4个10进制表示的word,前面的3个word就分别表示了这个变量的id, age, class_id,和代码中是匹配的,但是第4个word的值看不出来是啥,那是因为第4个word开始它是字段name的内容,它的大小是32个字节,我们就dump 32个char型的数据,可以看到前面的10个字符就是我们赋值的zhang san,没啥毛病。
联合体对于联合体,我们设想一个需求场景,有一天学校需要限制学生的头发和胡须的长度,那同学胡须不能超出2毫米,女同学头发不能超出500毫米。
那我们就可以这样设计数据结构:用一个联合体表示2种长度:
- 如果是男同学,就表示胡子长度,单位毫米,为了精确点,用float类型;
- 如果是女同学,就表示头发长度,单位毫米,没必要精确到毫米以下,我们就用int型。
如下就是我们的代码,我们用2个变量分别表示男同学和女同学的要求,当然都是union body_hair_len类型:
union body_hair_len // 学生头发或胡须的长度{ float beard_len; // 如果是男同学,就表示胡子长度,单位毫米,为了精确点,用float类型 int hair_len; // 如果是女同学,就表示头发长度,单位毫米,没必要精确到毫米以下,我们就用int型};union body_hair_len male_len1;union body_hair_len female_len2;int main() // C语言的入口函数{ male_len1.beard_len = 2.0f; female_len2.hair_len = 500; return 0;}
我们dump出来4个word吧,第一word是female_len2中存的值500, 第二个word存的是male_len1中 beard_len的值,因它是个浮点数,见上面float的表示方法,可以得到图中的值。
你是不是有个疑问:为啥不是第一个word保存的male_len1,第二个word保存的female_len2?
那是因为该编译器在将这2个变量解析的时候,会按照变量名的字母顺序排序,字母在前的变量就放到前面。f在m前,所以就是这个结果。当然不见得所以的编译器都会按照这个排序的规则来放数据。
本文关键词:c语言数据类型占几个字节,c语言数据类型转换,c语言数据类型的分类,c语言数据类型转换规则,c语言数据类型说明保留字。这就是关于《c语言数据类型,c语言中常见的数据类型》的所有内容,希望对您能有所帮助!
- 上一篇: 英语瘦表示方法,胖英文别总说fat这样表达情商高
- 下一篇: 兆头是什么意思,兆头的解释
- 最近发表