点击蓝字
关注我们
C语言各种数据类型的内存映像(32位平台):
0 signed char
#include <stdio.h>
int main()
{char min = 1<<7;char max = (1<<7)-1;for(int i=min;i<=max;i++)if(i<0)printf("%.2X ",(unsigned char)i);else{printf("%c ",i);if(i%32==0)printf("\n%d ",i);}getchar();
}
output:
1 整型的signed和unsigned
#include <stdio.h>
int main()
{signed int smin = 1<<31;signed int smax = (1<<31)-1;printf("%d\n",smin); // -2147483648printf("%d\n",smax); // 2147483647unsigned int umax = -1;printf("%u\n",umax); // 4294967295umax = (1<<32)-1;printf("%u\n",umax); // 4294967295
}
如果一个表达式同时包含signed和unsigned整型,signed会提升为unsgined,可能会隐藏一些意想不到的错误,特别是用在比较运算时:
unsigned int a=4294967290;int b=-6; printf("%d\n",a==b); // 1 , b promotes to unsigned
2 double的二进制位显示
#include <stdio.h>
void printByte(double d)
{int bs = sizeof d;unsigned char *ch = (unsigned char*)&d;for(int i=0;i<bs;i++)printf("%.2X ",*(ch+i));
}
int main()
{int n = 0x01020304;if(*(char*)&n == 4)printf("小端:");//小端:double d = 15.75; // 1111.11, 指数位值:1023+3//0 100 0000 0010 1111100000000000000000000000000000000000000000000000printByte(d);//00 00 00 00 00 80 2F 40// 40 2F 80// 0100 0000 0010 1111 1000 0000getchar();
}
将double分成4部分显示:
#include <stdio.h>
typedef struct packed_double {unsigned int low32; // 小数位 低32位unsigned int low20:20; // 小数位 低33-52位unsigned int exp11:11; // 指数位 低53-63位,移码1023+二进制整数位-1unsigned int sign:1; // 符号位
} packed_double;typedef union {double d;packed_double b;
} packed;
int main()
{packed pd;pd.d = -15.75;pd.d = 12.3;printf("%u %u %u %u\n",pd.b.sign,pd.b.exp11,pd.b.low20,pd.b.low32);getchar(); return 0;
}
/*
0 1026 1015808 0
*/
3 数组是相同数据类型的依次存储
数组名是一个存储数据首元素地址具有常量性质的特殊指针,成员是相对于基址的偏移:
#include <stdio.h>
void printArr(short arr[],int len)
{for(int i=0;i<len;i++){printf("%d ",*(arr+i));}printf("\n");
}
int main()
{short arr[] = {1,3,2};int len = sizeof arr / sizeof *arr;printArr(arr,len);
}
4 枚举只是枚举可以取值的一些符号常量的一个特殊整型
#include <stdio.h>
int main()
{enum Nm{LOSS,TIE,WIN}nm; // 实质是一个整型,成员只是可能的右值(符号常量)的枚举nm = LOSS;printf("%d ",nm); // 0nm = TIE;printf("%d ",nm); // 1nm = WIN;printf("%d ",nm); // 2nm = (enum Nm)3; printf("%d ",nm); // 3printf("\n%d",sizeof(enum Nm)); // 4getchar();
}
枚举让相关符号常量内聚为一组,相对于#define,枚举对数据的描述性更清晰。
5 共用体成员的起始地址相同,共用一块内存空间,值相互覆盖
#include <stdio.h>
int main()
{union Nn{int a; double b;}nn;// 成员的起始地址相同,值相互覆盖nn.a = 123; // printf("起始地址:%X,内存空间占用:%d\n",&nn.a,sizeof nn.a);nn.b = 12.3;printf("起始地址:%X,内存空间占用:%d\n",&nn.a,sizeof nn.b);nn.a = 12;printf("起始地址:%X,内存空间占用:%d\n",&nn.a,sizeof nn.a);getchar();
}
/*
起始地址:12FF40,内存空间占用:4
起始地址:12FF40,内存空间占用:8
起始地址:12FF40,内存空间占用:4
*/
当一些事物具有更多共性,但有少量差异时,可以只用一个内嵌一个共用体的结构体来描述:
#include <stdio.h>
#include <string.h>
#define MAXPARTS 12struct Parts{ // 零件int cost;char supplier[12];char unit[12] ;
};struct Assembly{ // 装配件int n_parts;struct {char partno[12];short quan;}parts[MAXPARTS];
};struct Inventory{ // 存货类型,或是零件,或是装配件char partno[10];int quan;enum{PART,ASSEMBLY}type; // 存货类型union {struct Parts parts;struct Assembly assembly;}info;
};int main()
{struct Inventory screen;strcpy(screen.partno,"p001");screen.quan = 12;screen.type = Inventory::PART;screen.info.parts.cost = 122;strcpy(screen.info.parts.supplier,"hw");strcpy(screen.info.parts.unit,"pcs");struct Inventory shell;strcpy(shell.partno,"a001");shell.quan = 4;shell.type = Inventory::ASSEMBLY;shell.info.assembly.n_parts=22;strcpy(shell.info.assembly.parts[0].partno,"d001");shell.info.assembly.parts[1].quan = 5;int costs;if(shell.type == Inventory::ASSEMBLY)costs = shell.info.assembly.n_parts;printf("%d\n",costs); //22getchar();return 0;
}
6 结构体是不同数据类型的数据依次存储在一起
结构体各数据成员的引用可以通过其内存大小和字节对齐来相对于基址偏移来计算。结构体通常用于描述某一事物,用其成员来描述该事物的某些关键属性。让该事物既可以用结构体变量整体表示,也可以对其成员分别引用来处理该事物的各个属性。
#include <stdio.h>int main()
{struct demo{char a; short b;int c;} abc; // 成员相对于基址偏移,字节对齐abc.b=12;short *p = (short*)((int)&abc+sizeof(short)); // 模拟编译器计算第2个成员的偏移地址printf("%d %d\n",abc.b,*p); // 12 12printf("%d\n",sizeof(struct demo));// 8getchar();
}
7 位域是对整型数据的按位处理
(一次可以处理n个位,1<=n<=整形长度)
位域(全局)二进制位显示:
#include <stdio.h>
void printBinM(unsigned int n)
{for(int i=31;i>=0;i--)printf("%d",(n & 1<<i)>>i);printf("\n");
}
struct Bf{ unsigned a:3; unsigned b:4; unsigned c:5;
}bf;
int main()
{bf.a =1;bf.b=15;bf.c=3;int *p = (int*)&bf; // 505printf("%d\n",*p);printBinM(*p);//00000000000000000000000111111001getchar();
}
位域(局部)二进制位显示:
#include <stdio.h>
void printBinM(unsigned int n)
{for(int i=31;i>=0;i--)printf("%d",(n & 1<<i)>>i);printf("\n");
}int main()
{struct Bf{ unsigned a:3; unsigned b:4; unsigned c:5;}bf;bf.a =1;bf.b=15;bf.c=3;int *p = (int*)&bf; // -858996231printf("%d\n",*p);printBinM(*p);//11001100110011001100000111111001getchar();
}
*声明:本文于网络整理,版权归原作者所有,如来源信息有误或侵犯权益,请联系我们删除或授权事宜。
戳“阅读原文”我们一起进步