嵌入式0基础开始学习 ⅠC语言(1)数据类型

想学好嵌入式,那么就从c语言开始学习!

0.问题引入

        面对过程(c语言)
            程序组成:
                      程序 = 算法 + 数据结构
                计算机首先要解决数据保存的问题,在数据保存之前,
                我们是不是要知道这个数据的大小,取值的范围。。。。
                不然我们怎么知道要开辟多大的空间呢?
                
                数据的大小,取值范围。。。都是我们数据类型要讨论的问题。  

1.数据类型


        typeof(x) => 求对象x的类型 //typeof(运算符)
             x:可以是常量,变量,函数。。。
                 如: 3,3.0,a,func
            
            例子:
                  typeof(3) =>求常量3的类型
                            => int
                  typeof(3.0) =>求常量3.0的类型
                             => double
                            
                #include <stdio.h>
                int main()
                {
                   int a;
                   //定义一个和a一样类型的变量b,该如何定义?
                   typeof(a)  b; // int b;
                }
        
        在c语言中,有如下数据类型:

                (1)基本类型:

                                 c语言已经为我们定义好了的类型
                                  主要用来保存数(整数/浮点数)
                            a,整数类型
                                    signed char/unsigned char (字符型 -保存的是字符对应的ASCII的值)
(什么是ASCII码? 是字符的整数形式,是另外的一种标准吗,任意一个字符都对应一个整数)
                                    short / unsigned short (短整型)
                                    long /unsigned long  (长整型)
                                    int /unsigned int  (整型)
                            
                                上面的这些类型都是用来保存整数值的,
                                那么他们之间有什么区别呢?
                                
                                1) signed/unsigned
                                          有符号(signed) :符号位(最高位) +数值位
                                                                              1 - 负数
                                                                              0 - 正数    
                                          无符号位(unsigned): 没有符号位的区别,所有的bit都是数值位
                                2)char /short /int ....
                                        所占的内存空间大小不一样
                                        那么他们的取值范围也是不一样
                                            char : 8bits ->1Bytes
                                                   取值范围                             
                                                            [-128,127]
                                                        127:0111 1111
                                                        -128:1000 0000
                                                        
                                            unsigned char:8bits ->1Bytes
                                                   取值范围:
                                                            [0,255]
                                                        255:1111 1111
                                                        0:  0000 0000
                                                        
                                            short /unsigned short:一般占16bits(一般是2个字节)
                                            
                                            int / unsigned int:占4个字节
                                                        int :
                                                                [-2^31,2^31-1]
                                                            -2^31:
                                                                  10000000 00000000 00000000 00000000
                                                            2^31-1:
                                                                  01111111 11111111 11111111 11111111
                                            
                                                        unsigned int:
                                                                [0,2^32-1]
                                                            0:  00000000 00000000 00000000 00000000
                                                            2^32-1:
                                                                11111111 11111111 11111111 11111111    
                                            
                                            long /unsigned long:
                                                        32bits的机器上面,一般占4个字节,32bits
                                                        64bits的机器上面,一般占8个字节,64bits    
                                
                                3)在不同编译器下面,同一类型的范围(所占空间)可能不一样
                                            如:
                                                    keil:
                                                            int 16bits
                                                    ubuntu:
                                                            int 32bits

                                            sizeof(x):求类型x的所占字节数, 1Byte = 8bits
                                                        sizeof(char) == 1
                                                        sizeof(short) ==2
                                                        sizeof(int)  == 4
                                                        sizeof(long) == 4/8

                                4)在GCC编译器,整数默认类型
                                        整数默认类型: int
                                        int a;
                                        typeof(a) => int
                                        typeof(3+4) => int
                                        typeof(3+4.0) =>double
                                                        "自动向高精度转换" =>自动向所占空间大的转换

                               b,浮点类型:用来保存小数的
                                        
                                        float :     单精度浮点类型
                                        double :    双精度浮点类型
                                        long double:  长双精度浮点类型
                                        
                                        上面的这些类型都是用来保存小数值的,
                                         那么他们之间有什么区别呢?
                                        
                                         所占空间大小不一样,保存的小数的精度也不一样
                                        
                                         一般来说:
                                                   sizeof(float) == 4
                                                   sizeof(double) == 8
                                                   sizeof(long double) ==16
                                                   
                                        练习:
                                                请大家讲上述所学的基本类型,
                                                在ubuntu(64bits)中所占的字节数打印出来!
                                                注意:打印sizeof的返回值时使用 %ld 打印!!!
                                                
                                                #include <stdio.h> --->头文件,包含了printf,scanf等函数
                                                int main()
                                                {
                                                    
                                                       printf("typeof(int)=%ld\n",sizeof(int));
                                                       printf("typeof(char)=%ld\n",sizeof(char));
                                                        printf("typeof(long int)=%ld\n",sizeof(long int));
                                                       printf("typeof(short)=%ld\n",sizeof(short));
                                                       printf("typeof(float)=%ld\n",sizeof(float));
                                                       printf("typeof(double)=%ld\n",sizeof(double));
                                                       printf("typeof(long double)=%ld\n",sizeof(long double));

                                                    return 0; ---->返回给计算机看的,有没有return 0,都没有关系
                                                }                           

                (2)构造类型:

c语言允许程序员自定义类型
                        数组:  一组相同类型元素的数据集合,用一组连续的存储空间来保存的
                                int a[10];//定义了一个数组,数组名为a,里面有10个int类型的元素
                                          //定义a的同时,其实也声明了一个新的类型(像a一样的类型)
                                          typeof(a[0]) => int
                                          typeof(a):求数组a的类型
                                                   a是一个里面含有十个int类型数据元素的数组
                                                   在笔记中,咱们可以这样来描述a的类型:
                                                             typeof(a)
                                                                    ==> int[10]
                        结构体
                        联合体/共用体
                        枚举
                
                (3)指针类型
                          先wait,wait,后面的专题讲

                (4)void类型
                            void在c语言中,有三个作用
                                   a,void*
                                            通用指针,用来存放任何数据类型的指针

                                   b,void当作函数的参数
                                            表示此函数无需参数
                                           如:
                                            int func(void)
                                            {
                                            
                                            }    
                                        调用:函数名 (实际函数)
                                              func()
                                    c,void当作函数的返回值的时候
                                           表示此函数没有返回值
                                         
                                        如:
                                              void func(int a,int b)
                                              {
                                                 int sum;
                                                 sum = a+b;
                                                 return sum;//???ERROR ,因为void作为函数的返回值类型,表示此函数没有返回值
                                              }        
                                            
                在研究了数据类型后,下面要保存数据
                在C语言中,数据分为两大类:
                        (1) 变量
                        (2) 常量

2.变量

     what is 变量?
                在程序运行期间,可以改变其值的数据对象!
            保存一个变量,那么这个变量就需要一个对应的存储单元
            当然这个存储单元一定是可写(因为我们需要去改变这个变量的值)
            任何一个对象的名字,必须要在定义这个对象之后才能去使用
            所以咱们想要使用一个变量的话,首先就应该去定义它。
          

    2.1变量的定义

           语法:
                  变量的类型   变量名 ; //没有初始化
                    int a;
                  变量的类型   变量名 = 变量的初始值 ; //初始化了的
                
                例子:
                      char c;
                      or
                      char c = 'A';
                “变量的类型” :只要是合法的c语言类型都可以
                 变量名 :   一个对象的名字,标识符
                    标识符其实是一个对象的名字

                    标识符的规则;
                                只能由字母,下划线和数字组成,并且不能做开头
                                float 2E3;  //2乘以10的3次幂
                            例子:
                                    A,CAIXUNKUN_666  //OBJK
                                    B,666_CAIXUNKUN  //不可以
                                    C,_CAIXUNKUN-666 //不可以                                    
                                    D,-CAIXUNKUN666 //不可以
                                    
                                ”名如其意“
                                        int sum; // 求和
                                        int sum_array ; //求数组元素之和
                                        
                                        int he;
                                        int shuzu_he;
                                        
                    变量的初始值:
                                 定义变量时,赋值给变量的值,初始值
                                 例子:
                                      int a;
                                      printf("a==%d\n",a); // a==? undefine 未知的
                                                           //现在的编译器聪明了,要是你没有初始化,他会自动给你初始化为0.               

    2.2变量的属性

        变量的类型
        变量名

            变量的存储单元(变量的地址)
                        在程序运行时,系统会给每一个变量分配一个存储空间,
                        用来保存这个变量的值,并且这个存储空间会有一个唯一
                        的编号,这个编号,称之为变量的地址

            变量的值:
                        变量的存储单元中的内容,
                        每一个变量都会有一个确定的值(不管你对这个变量有没有进行赋值)
                          因为在存储单元中,bit要么是1/0

    2.3变量的访问

           读/写
           读:从变量的存储单元中读取变量的内容
           写:把一个数值写到变量所对应的存储单元中去。
                    ”赋值“
   
                如:
                       int a =5; //将5,写道变量a对应的存储单元中去
                       int b = a; //读取变量a的值,赋值给b
                     上面的两个语句中的a都是同一个,但是他们所表达的含义是不一样的!!!

                    结论:
                            在c语言中,任何的变量,都有且只有两层含义:
                                    (1)代表变量的地址
                                            lvalue:
                                                    左值
                                                    left value
                                    (2)代表变量的值
                                            rvalue
                                                    右值
                                                    right value
                                        变量的左值:
                                                    变量的地址,一般是在”=“的左边
                                        变量的右值:
                                                    变量的值,一般是在”=“的右边
 
                                             例子;
                                                    int a =5; //a代表的是lvalue
                                                    printf("%d\n",a);//a代表的是右值 rvalue   

3.整数的存储问题

    整数在计算机中是如何存放的呢?
       整数是以二进制的补码形式存放的

        正数/0;

                正数的补码就是其原码本身
                原码:
                      就是把对应的数值转换成二进制形式
                      
                      13:
                            00000000 00000000 00000000 00001101 <- 13的原码,也是13的补码,也就是13在计算机中的
                                                                   存放形式

                      9:用8bits
                            0000 100

        负数:

                负数的补码是其 绝对值的原码 取反 +1 得到
                     -13:8bits
                        |-13|=13的原码
                              0000 1101 -> 绝对值的原码
                              1111 0010 -> 取反(0->1,1->0)
                              1111 0011 -> +1
                        
                        就是-13的补码,也就是-13在计算机中的存储形式
                    
                    一个有趣的现象,假设8bits来保存一个整数
                        -2的存放形式
                        254的存放形式  
                        1111 1110
                        
                        -3的存放形式
                        253的存放形式
                        1111 1101
                        
                        -4的存放形式
                        252的存放形式
                        1111 1100
                        
                    结论1:
                           一个负数会和一个比较大的正整数的补码形式一样。
                           说白了就是他们在计算机中的存储形式是一样的
                              -x 和 (2^n -x)一样
                              n:表示用多少个bits来存储一个整数
                              
                    结论2;
                           CPU内部是没有符号位的概念的,对于CPU来说,所有的
                           bit位都是数值位,都参与运算,至于是有符号的,还是无符号的
                           就看编译器。(意思就是说,你把它当作是一个有符号的还是无符号的)
                           
                        例子       
                            int a = -4;
                            a在计算机中的存储形式; 2^32 -4
                                       11111111 11111111 11111111 11111100
                            printf("%d\n",a);// -4
                                         %d:有符号输出
                
                练习:分析如下程序输出结果
                    1.
                        int a = -2;
                        printf("%d\n",a); // -2    
                            %d :
                                 有符号的数
                                                                
                        printf("%u\n",a); //2^32 -2
                            %u :
                                 无符号的数
                                
                                
                        

                    2.
                        int a =-56;
                        printf("%d\n",a); // -56
                        printf("%u\n",a); // 2^32-56           

4.整数之间赋值的问题

        C语言中,允许不同类型之间的整数进行赋值
                char ->int
                int ->char
                char ->unsigned short

            不同类型的整数,存储空间大小是不一样的
                char 8bits      
                short 16bits     
            这个问题该怎么解决呢?

        C标准建议:

                (1)长->短

                            长的赋值给短的,低字节直接拷贝,
                            高字节全部丢弃,
                            
                           例子:
                                   char c =250;
                                   typeof(250) => int
                                   typeof(c)  =>char
                        250:
                            00000000 00000000 00000000 11111010
                        c:  11111010

                (2)短->长

                            短的赋值给长的,低字节直接拷贝
                            高字节补什么?
                                    如果短的是无符号的数,高位就直接补0
                                    如果短的是有符号的数,高位补符号位

                            例子:
                                  int d;
                                  char c =250;
                                  d = c+8;
                                        typeof(c+8) =>int
                                        c(char) ->int;
                                                c:11111010
                                                   ->11111111  11111111  11111111 11111010    
                                                8:
                                                     00000000  00000000  00000000 00001000
                  

         
5.常量


        常量是指在程序运行期间,其值不能够改变的数据对象
        常量在代码中有几种情况出现:

              (1)整型常量:

                             在代码中,代表整数的常量值
                            
                             八进制常量:
                                      0[0-7]
                                            以字符0开头后面接0个或者多个0~7字符
                                        如:
                                             0123
                                             0777
                                             0128 ->不是
                                            
                                         八进制与二进制对应的一个关系
                                                一个八进制的位  对应三个二进制位
                                                     0                000
                                                     1                001
                                                     7                111
                            十六进制:
                                      0[xX][0-9  a-f/A-F]
                                      以0x 或者0X开头,后面接一个或者是多个0~9 A~F/a~f
                                      int a=83;
                                        <=> int a= 0x53;//十六进制
                                         
                                         十六进制与二进制对应的一个关系
                                                一个十六进制的位   对应   四个二进制位
                                                    a(A)                       1010
                                                    b(B)                       1011
                    
                        在c语言代码中,不可能出现二进制形式                    
                            int a =01010011;//计算机会将其认为是 八进制形式
                            int a =11111111;//计算机会将其认为是 十进制形式
                          

              (2)字符型常量

                    字符型常量是用  ‘’(单引号)引起来的一个或者多个字符的序列
                     如:
                          ‘a’ =>97
                          'A' =>65
                          '\n'  换行符
                          ‘\r’  回车符
                          
                    
                        人为把字符分成了两类:
                                   a.普通字符
                                         可以打印的字符,有形状的字符
                                         ‘0’ -‘9’
                                         ‘A’ -‘Z’
                                         ‘a’ -‘z’
                                        
                                   b.特殊字符(转义字符)
                                        如:
                                            ‘\n’ :换行符
                                            ‘\r’ : 回车符
                                            ‘\t’ : 制表符
                                            ....

              (3)浮点常量

                    由整数部分,小数点,小数部分;一个e/E,一个可以选的带符号的整数指数 和
                    一个可选的表示类型的后缀(f/l)
                                f/F :  float
                                l :   long double
                                
                     如;
                            float f = 2.3E3;  //OBJK  2.3乘以10^3
                            float f = .3E3;   //OBJK  0.3乘以10^3
                         

             (4)枚举常量

                        wait wait 等等
                        
        练习:
             1.
               char c = 250;
               int d;
               d = c+8;
               250(int):
                    00000000 00000000 00000000 11111010
                c:
                   长->短 , 1111 1010
                   
               printf("%d\n",c); //-6
               
               d=c+8;
                c+8 =>int:
                      c(char) ->c(int):
                                        11111111 11111111 11111111 11111010
                                     8:
                                        00000000 00000000 00000000 00001000
                                     +
                                        1 00000000 00000000 00000000 00000010

                                    d(int)
                                         :00000000 00000000 00000000 00000010  <---d的最终存放形式                                  
               printf("%d\n",d);//2
               
               printf("%u\n",d);//2
            
             2.            
                unsigned char c=250;
                int d;
                d = c+8;
                      250:
                           00000000 00000000 00000000 11111010
                      c : 长 ---> 短
                               1111 1010
                    c+8 ==> int
                         c(u char) --> c(int)
                              00000000 00000000 00000000 11111010
                        8:
                            00000000 00000000 00000000 00001000
                        +
                            00000000 00000000 00000001 00000010
                            
                        d(int):00000000 00000000 00000001 00000010 <----最终存放形式
                      
                printf("%d\n",d);//258
                printf("%u\n",d);//258
                
            3.
               char c = -3;
               printf("%d\n",c);//-3
               printf("%u\n",c);//2^32-3
               
            4.
               unsigned char c = -3;
                 -3(int):
                          11111111 11111111 11111111 11111101
                 c(u char):
                            长--> 短
                                     11111101
                        %d : int
                        %u : unsigned int
                             c(u char)->c(int):短--->长
                                               00000000 00000000 00000000 11111101 <---c的最终存放形式
                                               
               printf("%d\n",c);//253
               printf("%u\n",c);//253          

6.总结

        (1)c语言中数据类型   64位机器下
                a,基本类型
                        整数类型
                                   char /unsigned char      8bits                                  
                                   short                    16bits
                                   int                      32bits
                                   long                     64bits
                                   
                                 有符号和无符号的区别
                                          最高位!!!
                                    每一个类型对应的取值范围
                                    
                                    整数默认的类型:
                                                     int
                        浮点类型
                                  float         32bits
                                  double        64bits
                                  long double   128bits
                                  
                                     浮点数的默认类型:
                                                       double
                
                b,构造类型
                        数组
                        结构体
                        共用体
                        枚举
                        
                c,指针类型
                
                d,void类型
                        a,void* 通用指针
                        b, void当作函数的参数
                        c, void当作函数的返回值
                        
        (2)变量
                2.1变量的定义
                
                2.2变量的属性
                
                2.3变量的访问
                        read/write
                        read:读变量的值,(rvalue)
                        write: 写到变量的地址中去,代表的是变量的地址(lvalue)
                        
        (3)整数的存储问题
                正数
                负数
                    结论一;
                          -x和2^n-x的补码形式一致
                          
                    结论二
                           在CPU内部没有符号位的概念
                           
        (4)整数之间赋值的问题
               长->短:
                        低字节直接拷贝,高字节舍弃
                短->长:
                        低字节拷贝,空余的高字节部分补
                        看短的数据是无符号的数,还是有符号的数
                            如果是无符号的数,直接补 0
                            如果是有符号的数,直接补符号位
        (5)常量
                a,整型常量
                   八进制以0开头
                   十六进制以0x开头
                   十进制
                   
                b,字符常量
                     保存的不是字符的形状,而是这个字符对应的ASCII码的值!
                      1)普通字符
                      2)转义字符
                c,浮点常量    
                d,枚举常量                  
                
小练习:假设是在64bits机器下面
           分析如下程序的输出结果
           
           (1)
                 printf("%d\n",-1);//-1
                 printf("%u\n",-1);//2^32 -1
                
                 printf("%d\n",(char)-1);//-1
                  (char)-1 ==>将-1(int)强制转换为char
                  长-->短的(低字节直接拷贝,高字节舍弃)
                 printf("%u\n",(char)-1);//2^32 -1
                
                 printf("%d\n",(unsigned char)-1); //255
                 printf("%u\n",(unsigned char)-1); //255
                
                
                
           (2)
                 printf("%d\n",255); //255
                 printf("%u\n",255); //255
                
                 printf("%d\n",(char)255); // -1
                 printf("%u\n",(char)255); // 2^32 -1
                
                 printf("%d\n",(unsigned char)255); // 255
                 printf("%u\n",(unsigned char)255); // 255
                

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值