//奇怪的输出
#include<stdio.h>
int main(void){
int data[]={0X636c6557,0X20656d6f,0X78206f74,
0X756f7969,0X6e694c20,0X67207875,
0X70756f72,0X32303220,0X00000a31};
puts((const char*)data);
}
//输出:Welcome to xiyou Linux group 2021
对于初涉C语言的人,看到题目,怎么也不会想到,输出竟然是完整的一句话。
分析:
数组为lnt类型,而输出时把该数组强制转换为char,int与char类型可相互转化,而0x代表16进制,这时我们看出端倪,即ASCII码,每两位对应一个字符,
(20对应空格)
0X63 6c 65 57,0X20 65 6d 6f,0X78 20 6f 74,
c l e w ' ' e m o x ‘ ’ o t
0X75 6f 79 69,0X6e 69 4c 20,0X67 20 78 75,
u o y i n i L ' ' g ' ' x u
0X70 75 6f 72,0X32 30 32 20,0X00 00 0a 3 1
p u o r 2 0 2 ' ' NUl NUL 换行 1
题目有些眉目,
但
·为什么四个字符会有一个逗号呢?
那是因为每个int元素开辟四个字节,而字符占一个字节。
·为什么字符顺序是反的呢?
这就涉及到大小端存储
大端存储模式:是指数据的低位字节序保存在内存的高地址中,而数据的高位字节序保存在内存的低地址中
小端存储模式:是指数据的低位字节序保存在内存的低地址中,而数据的高位字节序保存在内存的高地址中我们常用的X86结构是小端模式,而KEIL C51则为大端模式。很多的ARM,DSP都为小端模式。有些ARM处理器还可以由硬件来选择是大端模式还是小端模式。
例如:变量x在内存中的地址为0x0010,x的值为0x1122,那么0x11为高位字节序,而0x22为低位字节序。对于大端存储,将0x11放在低地址中,既0x0010,0x22则放在高地址中,既0x0011。小端模式刚好相反。
2、又如
unsigned int a = -2;
printf("a = %d\n a = %u\n",a,a);
//-2 4294967294
看到输出后,没有输出-2,你一定又是大吃一惊。
分析:将-2存入unsigned int开辟的四个字节内存中为
10000000 00000000 00000000 00000010
转成补码
11111111 11111111 11111111 11111110
虽然unsigned int表示无符号整型,但输出时%d为有符号的十进制整数,将该四个字节的二进制数转换,故输出-2
而将其转换为%u,即无符号的十进制整数,即直接将其转换为十进制数,则输出为
可见,在声明一种类型,不过是定义一种类型,告知内存的存储空间和存储方式,
如整型以二进制补码的方式,浮点类型以SEM的方式存储
而同一个变量以%d或者是%u输出,其在内存中存储都是相同的,只不过是输出时的显示不同。
那么下面的一个问题就容易理解
printf("%c\n",(char)49);
printf("%c\n",49);
printf("%d\n",(char)49);
//1
//1
//49
分析:十进制49强制转换为char,并以%c输出,ASCII码对应‘1’,其实就是直接将49以%c输出
但若仍以%d输出,还为整型49
新人小白发文,如有不足请指出,O(∩_∩)O谢谢。