------Java培训、Android培训、iOS培训、.Net培训、期待与您交流! -------
在学习C语言基础知识时,老师对内存的分析很重视,几乎每个知识点都会帮我们分析内存存储情况,透过内存的分析也让我们对C语言有了更深的一些了解,C语言跟其他计算机语言相比,对内存的分析和要求更高,下面我们一起来了解和学习一下C语言的内存剖析,是我个人的在学习中的一些总结,如果问题或者不到位的地方也希望大家能够一起交流和指正。
第一讲 进制
进制是一种计数的方式,数值的表示形式,一般我们C语言主要学习的包括十进制、二进制、八进制、十六进制。也就是说,同一个整数,我们至少有4种表示方式。在C语言的程序运行之前,我们都知道先要进行编译和链接,而数据在计算机中的表现形式都是0跟1,编译就是将程序代码转换成计算机能读懂的0跟1的过程。一个int类型数据占据四个字节,32bit,例如0000 0000 0000 0000 0000 0000 0000 1100,变量在内存中的存储细节问题,内存寻址由大到小,变量分配字节也是由大到小,且变量的地址就是其占据的最小的字节地址
1.二进制
特点:只有0和1,逢2进1
书写格式:0b或者0B开头
使用场合:二进制指令或者二进制文件,变量在内存中就是二进制存储
二进制和十进制的相互转换:举例:0b1100=0*2的0次方+0*2的1次方+1*2的2次方+1*2的3次方,十进制转二进制则是除2
n位二进制位所能表示的数据范围(不考虑负数):0~2的n次方-1
2.八进制
特点:0~7,逢八进一
书写格式:0开头
八进制和二进制之间的互相转换
3.十六进制
特点:0~F,逢十六进一
书写格式:0x或者0X开头
十六进制和二进制之间的相互转换
4.一些常用格式符的总结
%d或%i是以带符号十进制整数的形式输出一个数值
%o以不带符号的八进制形式输出整数
%x以不带符号的十六进制形式输出整数
%c输出一个字符,%s输出一个或者多个字符
%f以小数形式输出单,双精度数,默认输出六位小数,%p输出地址
5.类型说明符
int 4个字节%d
short 2个字节%d
long 8个字节%ld
long long 8个字节%lld
signed和unsigned的区别:
signed 最高位要当作符号位 有符号,正数,0,负数 其实就等价于int
unsigned 最高位不要当作符号位 无符号,正数,0
第二讲 位运算
之前也学习过很多C语言的基本运算,包括算数运算,赋值运算,自增自减运算,关系运算,逻辑运算还有三目运算等等,而这里的位运算跟数据在计算机内存中的表现形式密不可分,因为数据在计算机中是以0和1的形式存在,而位运算也是基于此形式上进行的运算。
1.按位与 & :只有对应的两个二进位均为1时,结果位才为1,否则为0
比如9的二进制1001,5的二进制是0101,,9&5=1
规律:二进制中,与1相&就保持原位,与0相&就为0
2.按位或 | :只要对应的两个二进制位有一个为1时,结果就为1,否则为0
3.按位异或 ^ :当对应的两个二进制位相异(不相同)时,结果为1,否则就为0
规律:相同数值进行异或,结果肯定是0,比如9^9==0
交换:9^5^6==9^6^5
任何数值跟0进行异或,结果还是原来的数值,9^0==9
可以推出a^b^a==b
关于异或有个跟之前可以联系上的小例子:(省略了#include<stdio.h>和主函数)
1 //不引入第三个变量的情况下交换两个变量的值 2 int a=10; 3 int b=11; 4 5 a=a^b; 6 b=a^b; 7 a=a^b; 8 printf("a=%d,b=%d\n",a,b);//利用异或的特性可以得到a^b^a==b
4.按位取反 ~ : 二进制0变1,1变0,符号位也会取反
5.左移 << : 把整数a的各个二进制位全部左移n位,高位丢弃,低位补0,左移n位其实就是乘以2的n次方, a<<n
9<<1 ->9*2的1次方 ==18
9<<2 ->9*2的2次方== 36
9<<n ->9*2的n次方
6.右移 >> : 把整数a的各个二进制位全部右移n位,保持符号位不变,右移n位其实就是除以2的n次方, a>>n
8>>n ->8除以2的n次方
以上是些关于进制以及位运算的一些知识,可能有些生硬和枯燥,下面我们来看一个位运算的练习题更深入了解一些内存的表现形式:
1 //编写一个函数,用来输出整数在内存中的二进制形式 2 #include<stdio.h> 3 4 void printBinary(int number);// 进行函数的声明 5 6 int main() 7 { 8 9 printBinary(15); // 调用此函数并赋值15 10 return 0; 11 12 } 13 14 void printBinary(int number) 15 { 16 int temp=(sizeof(number)<<3) - 1;//纪录现在挪到第几位,换成sizeof(number) *8-1==31,其实还是 17 18 while (temp >= 0) { 19 20 int value= number>>temp & 1;//右移将每位与上1可以得到此位数 21 22 printf("%d",value); 23 temp --; 24 25 if ((temp+1)%4==0) { // 每四位隔一个空格 26 printf(" "); 27 } 28 29 } 30 printf("\n"); 31 32 }
总结:可能这个知识点有点枯燥和生硬,但是C语言中对内存的分析是很重要的,学会了分析内存对今后的数组指针等知识的学习很有帮助,因此还是需要好好巩固这一块的基础知识的学习。