C语言 -char类型与内存单元理解

⭐基础知识

特点一:C++/C里面整个程序运行中类型不可变
        强转不是转类型,而是数值的转换
        python脚本语言,类型可变 随着数据变化而变化类型
特点二:所有函数和变量都是先定义,再使用 ,不能边定义边使用 question2:
        .c .cpp文件是源文件 (文本文件)
          .c->.cpp 预编译 文本->文本,预编译只处理头文件#
           引入 不执行具体程序指令
        .i 预编译文件 (.i文本文件 )
          .i->.obj 编译过程 处理类型的合法与否 语法 语义 词法
        .obj .o 编译后的目标文件 (二进制文件) linux环境下常用
          .obj ->.exe 链接 最后转为可执行文件
          涉及到后面的静态链接库和动态链接库
        .exe 可执行文件
         可执行文件被调度后 给其分配区域(空间)内存分为四个段
         .code 代码段 .date 数据段
         .heap 堆区 .stack 栈区
     
 口诀:凡是在函数外定义的变量 都是在数据区 .date --全局变量
    凡是在函数内定义的变量 都是在栈区 .stack

    存在例外情况:后续补充
    
    提问:为什么我们会对程序分这四个区域?reason?
    为什么在编译的时候会分为预编译,编译,链接这几个过程?
    在这里插入图片描述

基本数据类型:

分类:
   char; //1 字节 short;//2 字节   int;//4 字节  
   bool;//1字节           float;//4 字节 
                         long int;//4 字节
   double;//8 字节
   long double;//8 //c11标准下 12
  
  1字节 = 1个存储单元 = 8 bit (8个1/0数字)
  注意区分字符与字节;
在这里插入图片描述
  char ch = ‘a’; //存放的不是字符 而是ASCII码
  char ch = 97 ; //char ch 0x61; 0x十六进制
  这两个其实意思是一样的
  究竟输出字符还是数字 由格式控制符决定 由程序员决定
  char => mini_int 字符 1字节整型

char a = ‘0’; //字符0 ASCII码 是48 二进制 => 0011 0000
char b = 0; //数字0 min_int 二进制 0000 0000

进制间的转换:

所有转十进制都是对应数字乘以进制的幂
  128 64 32 16 8 4 2 1 算二进制
  二进制从中间劈开 拆成 8421 8421 算16进制;
  每三位劈开 拆成 421 421 算8进制

  	   int a = 10;//十进制数   10   逢十进一  
 	   int b = 010;//八进制数  8 	逢八进一 
 	   int c = 0x10;//十六进制 16 	逢十六进一 

源码反码补码及其扩展

源码:
反码:符号位不变 在源码基础上 求反
补码: 符号为不变 在反码基础上 求反+1
  正数 源码反码 补码都一样
结论:在内存中按补码存放
  char a = 5; //0 000 0101 0x05
 char b = -5; //1 000 0101 源
       //1 111 1010 反
       //1 111 1011 0xfb 补
  //算16进制的时候不管是不是符号为都算进去
 
 问题:为什么内存中存储数据的时候按照补码来存?
 解释:由于计算机只有加法器 CPU 只做 加法 移位 取反
 在这里插入图片描述

⭐一个字节到底有多大 char为例

有符号数如图

在这里插入图片描述有符号数在魔鬼数字1000 0000时候有重大改变
无符号数则是一条从0-256的直线

⭐魔鬼数字10000000

有符号数:10000000

因为没有负0这个说法
 所以1000 0000是魔鬼数字 这里的1既是符号又是数值
 所以:1000 0000 是-128
    (127)2 + 1 = (-128)2

无符号数:1000000

128 64 32 16 8 4 2 1
 1  000000 为128

从二进制角度理解:

#include<iostream>
using namespace std;
int main() {
	unsigned char a_u = -1;
	/* -1 是有符号数  当是负数时,求反+1
	       1 000 0001 =>-1  原码
	       1 111 1110 =>-126 反码
		   1 111 1111 =>-127 补码
		现在 -1的补码 以无符号a_u数角度看
		   1111 1111 => 255 
	*/
	cout << a_u << endl; //无结果
	printf("%d\n", a_u); //255
	system("pause");
}

从计算角度理解

无符号数 无 负数,见到负数就加上当前类型的范围,把他转化为正数

无符号数在取模运算中的使用

⭐范围转换

整型中:若把范围小的给范围大的:
     自身有符号 扩充符号位 ->因为赋值之后符号不变,数值不变
     自身无符号,扩充0
    若把范围大的给范围小的:切片现象 保留低位
举例:

    char a = 5;  // 00000101
    扩充后://源码=补码:00000000 00000000 00000000 00000101 =>5
    char b = -5;  
    扩充后: //源码:11111111 11111111 11111111 11111011
            //反码:00000000 00000000 00000000 00000100
            //补码:10000000 00000000 00000000 00000101 => -5 

			char a = 100; 0110 0100  //扩充前01100100
			 		//扩充后:00000000 00000000 00000000 01100100
			char b = 200; 1100 1000 //扩充前:11001000
					//扩充后:11111111 11111111 11111111 11001000 

解释:
  正数0~127 有128个数字 char要对127这个数字敏感
  负数-128~-1 有128个数字
  128+128 =256一圈0~255 总共有256个数
   200超过了127 此时相当应该是-56
  200在处理器中属于负数!!!
  所以扩展的时候是前面是111111111……

发布了76 篇原创文章 · 获赞 0 · 访问量 1780

猜你喜欢

转载自blog.csdn.net/AKUANer/article/details/102583545
今日推荐