c语言的内存分析

1、 进制

1. 什么是进制
● 是一种计数的方式,数值的表示形式  

汉字:十一   十进制:11  二进制:1011  八进制:13 

● 多种进制进制、二进制、八进制、十六进制。也就是说,同一个整数,我们至少有4种表示方式

4种主要的进制:

①. 十进制:0~9 

②. 二进制:0和1

③. 八进制:0~7

④. 十六进制:0~9+a b c d e f

● 软件开发,肯定要了解这个
 
2. 二进制
1> 特点:只有01,逢21
2> 书写格式:0b或者0b开头
3> 使用场合:二进制指令\二进制文件,变量在内存中就是二进制存储
4> 二进制和进制的互相转换
5> n为二进制位所能表示的数据范围(不考虑负数)0~2n次方-1

 

3. 八进制
1> 特点:0~7,逢八进一
2> 书写格式:0开头
3> 八进制和二进制的互相转换

 

4. 十六进制
1> 特点:0~F,逢十六进一
2> 书写格式:0x或者0X开头
3> 十六进制和二进制的互相转换

 

5. 总结
1> Mac中计算器的使用
2> printf以不同进制形式进行输出
 
%d和%i    :以十进制整数的形式输出一个值

%o :以不带符号的八进制输出

%x :以不带符号的十六进制输出

%u :以不带符号的十进制输出

%c : 输出字符

%p : 输出地址

%f : 输出小数

%s : 输出字符串

 

6. 习题

1> 判断下列数字是否合理

00011   0x0011  0x7H4  10.98  0986  .089  -109

+178    0b325  0b0010   0xFFdc  96f  96.0f   96.0F

-.003    15.4e6  10e8.7  7.6e-6

2> 分别写出它们的十进制、八进制、十六进制

0b0011 1101      0b0111 1011

3> 写出它们的二进制

67   056  0x004f 

 

2、 变量的内存分析

研究变量在内存中的具体存储情况

1. 字节和地址

为了更好地理解变量在内存中的存储细节,先来认识一下内存中的字节地址

1> 内存以“字节为单位”

 

2> 不同类型占用的字节是不一样的

 

2. 变量的存储
1> 所占用字节数跟类型有关,也跟编译器环境有关
2> 变量实例

int b = 10;

int a = 134;

● 内存由大到小寻址
● 只存储二进制形式
● 每个变量都有地址:第一个字节的地址就是变量的地址
3> 查看内存地址的两种方式%x%p
4> 查看整数的二进制形式

// 输出整数的二进制形式

 1 #include <stdio.h>
 2 int main()
 3 {
 4     void putBinary(int);
 5     
 6     putBinary(-12);
 7     
 8     putBinary(13);
 9     
10     return 0;
11 }
12 void putBinary(int n)
13 {
14     int bits = sizeof(n) * 8;
15     while (bits-->0) {
16         printf("%d", n>>bits&1);
17         if (bits%4==0) printf(" ");
18     }
19     printf("\n");
20 }

 

 

3. 负数在内存中的存储
1> 一个字节的取值范围
2> 负数的表示形式
3> 原码、反码、补码

 

4. 取值范围

 n位二进制的取值范围

 2位二进制位的取值范围:0~3  0~2的2次方-1

 3位二进制位的取值范围:0~7  0~2的3次方-1

 n位二进制位的取值范围:0~2的n次方-1

 

 

5. 习题

写出下列变量在内存中的存储情况

int a = 134;

int b = 0;

int c = -10;

 

3、 类型说明符
1. shortlong
● 100l100ll100的区别
● longlong long的输出
● 不同类型所占用的存储空间

1> shortlong可以提供不同长度的整型数,也就是可以改变整型数的取值范围。在64bit编译器环境下,int占用4个字节(32bit),取值范围是-2的31次方~2的31次方-1short占用2个字节(16bit),取值范围是-2的15次方~2的15次方-1long占用8个字节(64bit),取值范围是-2的63次方~2的63次方-1

2> 总结一下:在64位编译器环境下,short2个字节(16)int4个字节(32)long8个字节(64)。因此,如果使用的整数不是很大的话,可以使用short代替int,这样的话,更节省内存开销。

3> 世界上的编译器林林总总,不同编译器环境下,intshortlong的取值范围和占用的长度又是不一样的。比如在16bit编译器环境下,long只占用4个字节。不过幸运的是,ANSI \ ISO制定了以下规则:

● shortint至少为16(2字节)
● long至少为32(4字节)
● short的长度不能大于intint的长度不能大于long
● char一定为为8(1字节)毕竟char是我们编程能用的最小数据类型

4> 可以连续使用2long,也就是long long。一般来说,long long的范围是不小于long的,比如在32bit编译器环境下,long long占用8个字节,long占用4个字节。不过在64bit编译器环境下,long longlong是一样的,都占用8个字节。

5> 还有一点要明确的是:short int等价于shortlong int等价于longlong long int等价于long long

 

2. signedunsigned

1> 首先要明确的:signed int等价于signedunsigned int等价于unsigned

2> signedunsigned的区别就是它们的最高位是否要当做符号位,并不会像shortlong那样改变数据的长度,即所占的字节数。

● signed表示有符号也就是说最高位要当做符号位所以包括正数负数和0其实int的最高位本来就是符号位已经包括了正负数和0因此signedint是一样的signed等价于signed int也等价于intsigned的取值范围是-231 ~ 231 - 1
● unsigned表示无符号也就是说最高位并不当做符号位 以不包括负数64bit编译器环境下面int占用4个字节32bit),因此unsigned的取值范围是0000 0000 0000 0000 0000 0000 0000 0000 ~ 1111 1111 1111 1111 1111 1111 1111 1111也就是0 ~ 2的32次方 - 1

 

4、 位运算
1. 按位与
1> 功能

只有对应的两个二进位均为1结果位才为1否则为0

2> 举例: 比如9&5其实就是1001&101=1因此9&5=1
3> 规律
● 二进制中1&保持原位0&就为0

 

2. 按位或
1> 功能

只要对应的二个二进位有一个为1结果位就为1否则为0

2> 举例: 比如9|5其实就是1001|101=1101因此9|5=13

 

3. 按位异或

1> 功能

当对应的二进位相异不相同结果为1否则为0

2> 举例: 比如9^5其实就是1001^101=1100因此9^5=12

3> 规律

● 相同整数相^的结果是0比如5^5=0
● 多个整数相^的结果跟顺序无关比如5^6^7=5^7^6
● 因此得出结论a^b^a = b

 

4. 取反

对整数a的各二进位进行取反,符号位也取反0110

 

5. << 左移
● 把整数a的各二进位全部左移n高位丢弃低位补0左移n位其实就是乘以2n次方
● 由于左移是丢弃最高位0补最低位所以符号位也会被丢弃左移出来的结果值可能会改变正负性

 

6. >> 右移
● 把整数a的各二进位全部右移n保持符号位不变右移n位其实就是除以2n次方
● 为正数时 符号位为0最高位补0
● 为负数时符号位为1最高位是补0或是补取决于编译系统的规定

 

7. 习题
1> 在不用引入其他变量的情况下,使用位异或^运算符实现两个变量值的
 1 #include <stdio.h>
 2 int main()
 3 {
 4     int a = 10;
 5     int b = 11;
 6     a = a ^ b;
 7     b = a ^ b;
 8     a = a ^ b;
 9     
10     printf("a=%d, b=%d\n", a, b);
11     
12     return 0;
13 }

 

2> 使用位与&运算符变量的奇偶性
 1 #include<stdio.h>
 2 int main()
 3 
 4 {
 5     
 6     printf("请输入需要判断的整数:\n");
 7     
 8     int n;
 9     
10     scanf("%d",&n);
11     
12     
13     if((n&1)==1)
14         
15         printf("这个数是奇数\n");
16     
17     else if((n&1)==0)
18         
19         printf("这个数是偶数\n");
20     
21     return 0;
22     
23 }

 

3> 编写一个函数,用来输出整数在内存中的二进制形式

 

 1 #include <stdio.h>
 2 void printBinary(int number);
 3 
 4 int main()
 5 {
 6     printf("这个程序的作用是把你输入的整数以二进制的格式输出\n");
 7     
 8        printf("请输入一个整数:\n");
 9 
10         int n;
11 
12         scanf("%d",&n);
13         printBinary(n);
14     
15         return 0;
16 }
17 
18 void printBinary(int number)
19 {
20     
21     // 记录现在挪到第几位
22     // (sizeof(number)*8) - 1 == 31
23     int temp = ( sizeof(number)<<3 ) - 1;
24     
25     while ( temp >= 0 )
26     {
27         // 先挪位,再&1,取出对应位的值
28         int value = (number>>temp) & 1;
29         printf("%d", value);
30         
31         //
32         temp--;
33         
34         // 每输出4位,就输出一个空格
35         if ( (temp + 1) % 4 == 0 )
36         {
37             printf(" ");
38         }
39     }
40     
41     printf("\n");
42 }

 

5、 char类型
1. 存储细节

ASCII单字节表(双字节GBK\GB2312\GB18030\Unicode

2. 常见错误

char c = A;

char c = "A";

char c = 'ABCD';

char c = ''

3. 当做整型使用

-128~127范围内,可以当做整数来用

4. %c%d\%i的使用

printf(%dA);

printf(%c, 68);

5. 转义字符

转义字符

意义

ASCII码值

\n

将当前位置移到下一行开头(回车换行)

10

\t

跳到下一个TAB位置

9

\\

代表一个反斜线字符

92

\'

代表一个单引号字符

39

\"

代表一个双引号字符

34

\0

空字符

0

 

6. 习题
1. 编写一个函数,将小写字母转为大写
 1 #include <stdio.h>
 2 char upper(char c)
 3 {
 4     // 如果是小写字母,就转成大写
 5     /*
 6      if (c>='a' && c<='z') { // ['a', 'z']
 7      return c - ('a'-'A');
 8      } else {// 如果不是小写字母,返回字母本身
 9      return c;
10      }*/
11     
12     // 如果是小写字母,就转成大写
13     if (c>='a' && c<='z') { // ['a', 'z']
14         return c - ('a'-'A');
15     }
16     // 如果不是小写字母,返回字母本身
17     return c;
18 }
19 
20 int main()
21 {
22     char cc = upper('h');
23     
24     printf("%c\n", cc);
25     return 0;
26 }

 

2. 说出程序的输出结果

int main()

{

   int i = 67 + '4';

   char c = 'c' - 10;

   

   printf("%d - %c\n", i, i);

   printf("%d - %c\n", c, c);

   return 0;

}

        解  119 - w

            89 - Y

         

转载于:https://www.cnblogs.com/zhangxiaomeng1991/p/4150855.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值