c语言中的数据类型

# 数据类型

## 问题的引入

    电脑 外国人: computer

    计算机是我们人类用来解决某些问题的一种工具而已。那么计算机是通过什么方式来解决我们的问题的呢??

        计算

    计算机是通过把问题域里面数据保存起来,然后对数据进行一系列的操作(计算),从而达到我们的目的。

        程序:数据 + 逻辑

        程序:数据结构 + 算法

    也就是说,计算机实现要解决的是数据的保存问题,在保存数据之前呢???我们要了解这个数据大小,类型,范围.....

    如果我们连这些东西都不知道的话,我们根本没办法在计算机中保存这些数据。

## 最基本的数据类型!

    在C语言中,仅仅就4种数据类型 ---- 整型,浮点型,指针,聚合类型(数组和结构),其他的类型都是从者四种类型种派生出来的

### 基本类型

    C语言中已经为我们定义好的类型,我们可以直接拿过来使用!

        主要针对的是:“数”:整数,浮点数

        char/unsigned char :1 byte = 8 bits  0000 0000

            unsigned char 0 ~ 255

            char : -128 ~ 127

    在不同的编译器 , short int long 他们占的字节数不一样

        short/unsigned short

    int/unsigned int

        long/unsigned long

    sizeof(char) <= sizeof(short) <= sizeof(int) <= sizeof(long)

    eg:

       在gcc ubuntu18.04中

        sizeof(short) = 2

        sizeof(int) = 4

        sizeof(long) = 8

        float 单精度浮点型 一般占4字节

        double 双精度浮点型 一般是占8字节

        long double 长双精度浮点数 >= 10个字节

        在C语言中,整数默认的类型就是int , 小数默认就是double

    typeof(1) = int

       typeof(1.0) = double

练习:

    测试一下你Ubuntu中 int short long 的字节数到底是不是这个!

### 构造类型 : 自定义的类型

    C语言中,允许我们程序员自定义类型!!

    //数组

    int a[4];  //what is a type ???   a 是一个含有4 个 int 类型元素的数组  int[4]

    int b[10];   //int[10]

        那么请问a和b是同一种类型吗???  B

        A   一样

        B   不一样

        C   不知道

    typeof(a) : int[4]

    typeof(b) : int[10]

    typeof(a) : int   nononon

    typeof(1) : int

    //结构体

    //联合体

    //枚举

### 指针类型

    先 wait wait 后面会有专题来讲这个知识

### void

    空类型。 在C语言中,void总共会出现在三个地方:

        (1)、void当函数的返回值类型,表示该函数没有返回值

            void xxx(int a)

            {

    }

            调用:xxx(1);

        (2)、void 当函数的参数,表示该函数没有参数

            void xxx(void)

            {

    }

            调用:xxx();

        (3)、void * 表示通用指针

            void * xxx(void)

            {

    }

## 数据对象之变量

    数据对象分为两类:

    变量:在程序运行期间,其值是可以被改变的数据对象

    常量:在程序运行期间,其值不能被改变的数据对象

### 变量的定义

    变量在使用之前,需要定义。 ”先定义,后使用“

    定义变量的语法:

        变量的类型 变量名 = {初始化};

            {}是可选的!

            变量的类型:

                任何C语言合法的类型都可以

                    基本类型/构造类型/指针类型/void *

            变量名:(见名知其意)

                ”标识符“ : 在C语言的标准里,标识符必须由字母,下划线,数字组成,并且

                第一个字符必须是下划线和字母

                标识符 : 标识某个对象的符号,某个对象的名字,变量名,数组名,函数名.....

            eg:

                zxf520

                520zxf  NO

                _520zxf

                zxf

            eg:

                int sum = 0;

                int int = 0;   //变量名不能是C语言的关键字

                int s ;

    讨论一个问题?

            int s;

            printf("s = %d\n",s);

            请问上面这两行代码,有没有毛病??或者说这两行代码能不能正常的输出一个结果?

                不同的编译器,结果都会不一样!

            一个变量,你没有初始化,不代表他没有值!

                相反他有一个值,只不过这个值你不知道而已!(gcc 是 0)

### 变量的属性

    int a = 5;

        变量名

        变量的存储单元:

            程序的运行期间,会为每一个变量,分配一个大小合适的存储单元。

            存储单元按照字节的大小,编号。这个编号,称之为存储单元的地址

            变量的存储单元会有一个唯一的编号,变量的地址

        变量的值:

            变量存储单元中的内容

            1 byte = 8 bits

                保存其实是一个”电压值“

                    高电平就是 1

                    低电平就是 0

### 变量的访问

    你定义的变量,肯定是想要去使用这个变量的

    read / write

    a = 5 ;  //把数值5 存储到 变量a 的地址中去

    b = a ;  //把变量a的值 赋值给 变量b

    在C语言中,任何一个变量 都有两层意思:

    (1)、左值:代表是变量的地址

            lvalue : left value

                location value :可写的地址

    (2)、右值:代表是变量的值

            rvalue : right value

                readable   value : 可读的值

## 整型变量

### 整型在存储器中是如何存放的??

    int a = 5;

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

    补码:

        正数的补码就是其原码的本身

    eg:

        13 : 8bits

            13 = 8 + 4 + 1

            13 = 2^3 + 2^2 + 2^0

            0000 0000

            0000 1101  -----> 13 在计算机中存放的形式  (8bit)

    负数的补码:

        其 绝对值的原码  取反 +1  得到的

        -13 : 8 bits

            0000 1101

            1111 0010    取反

            1111 0011   -----> 13 在计算机中存放的形式(8bits)

#### 练习

    假设用8bits存储 一个整数

    1、-1和255在计算机中存放的形式是什么??

        -1 :

            1:

                0000 0001

                1111 1110

                1111 1111   ----》 就是-1在我们计算机中存放的形式

        255:

            1111 1111 ----》255 在我们计算机中存放的形式

    2、-2和254在计算机中存放的形式是什么??

        -2 :

            1111 1110

        254:

            1111 1110

    3、-3和253在计算机中存放的形式是什么??

    ......

    结论:

        1、一个负整数会和一个比较大的正整数的补码形式是一样的!

            -4 和 252 的补码形式是一样

            -x 和 2^n-x 的补码形式是一样

        32bit

    11111111    11111111    11111111    11111111

        请问这个整数是多少?

            2^32-1

            -1

        2、在CPU底层是没有符号位的概念,都是数值位,都参与了运算,至于这个数是正数还是负数,都要看编译器的意思

            也就是说你这个小卡拉米想要这个数是一个有符号的数,还是一个无符号的数

    编译器符号数(逻辑层面)

            有符号数

                符号位(最高位) + 数值位(其他位)

                    1 负数

                    0 正数

            无符号数

                数值位(全部)

#### 练习

    假设 int 是32 bits

    (1)、分析如下的程序的输出结果

        int a = -3;

            3:

                00000000    00000000    00000000    00000011

                11111111    11111111    11111111    11111100

                11111111    11111111    11111111    11111101  ---- -3在计算机中存放的形

    式,也就是变量a存储单元里面就是保存的这个小玩意

    printf("%d\n",a);  //-3

        printf("%u\n",a);  //2^32-3

                %d : 把后面那个玩意(a)当成一个signed int 有符号的数来看,输出(十进制)

                %u :把后面那个玩意(a)当成一个unsigned int 无符号的数来看

    (2)、分析如下的程序的结果

        unsigned int a = -4u;

        printf("%d\n",a);  //-4

        printf("%u\n",a);  //2^32-4

    typeof(-4) : int

        typeof(-4u) : unsigned int

    -4/-4u

            00000000    00000000    00000000    00000100

            11111111    11111111    11111111    11111011

            11111111    11111111    11111111    11111100  ===>-4在计算机中存放的形式,也就是变量a存储单元里面就是保存的这个小玩意

## 格式说明符

%d  :  用于打印或者扫描有符号的十进制数(int)

%u  :  用于打印或者扫描无符号的十进制数(unsigned int)

%f  :  用于打印或者扫描浮点数(float)

%lf :  用于打印或者扫描双精度浮点数(double)

%c  :  用于打印或者扫描字符 (char)

%s  :  用于打印或者扫描字符串(char *)

%p  :  用于打印指针的值 (void *)

%x  :  用于打印或者扫描无符号的十六进制的整数(unsigned int)

%o  :  用于打印或者扫描无符号的八进制的整数(unsigned int)

%e  :  用于打印或者扫描以指数表示的浮点数(科学计数法)

%ld :  用于打印或者扫描有符号长整型

%lu :  用于打印或者扫描无符号长整型

%g  :  用于打印或者扫描浮点数,自动选择以指数或者十进制表示(自动选择%e %f)

%10d:  指定你打印一个宽度为10的整数字段

%.2f:  指定打印一个浮点数,并且保留两位小数

## 常量

    在程序运行期间,其值是不可以被改变的

### 常量的形式

#### 整型常量

    在代码文本中,代表整数的常量值

        八进制整型常量

            0[0-7]*

                以字符0开头后面接0个或者多个0-7的字符

                如:

                    0123

                    0777

                    0123456789 ERROR

                    088 ERROR

                    01234567

    int a = 0123;

                printf("%o\n",a);

                printf("%d\n",a);

        八进制和二进制的关系

            一位八进制数字对应三位二进制的数字

                八进制          二进制

                0               000

                1               001

                2               010

                3               011

                4               100

                5               101

                6               110

                7               111

    十六进制整型常量

            0[X/x][0-9a-fA-F]

                以字符0x/0X开头接一个或者多个十六进制的字符

                    如:

                        0xff

                        0x123

                        0x89a

                        0x23G   error

    int a = 0x23;

                        printf("0x%x\n",a);

                        printf("%d\n",a);

                十六进制与二进制的关系

                    一位十六进制对应4位二进制

                        十六进制                   二进制

                            0                      0000

                            1                      0001

                            2                      0010

                            3                      0011

                            4                       ..

                            5

                            6

    7                       ..

                            8

                            9                       ..

                            a                      1010

    b                      1011

    c                      1100

                            d                      1101

    e                      1110

                            f                      1111

            十进制

                略

#### 字符常量

    字符常量是 用 单引号 引起来的一个或者多个字符序列

            eg:

                'a'

                '\n'

                '\x12'

        在计算机中,保存一个字符,保存的是字符的ASCII , 而不是它的形状。

         ASCII: American standard Code information interchange

                英国把每个字符分配一个唯一的整数值来标识他们,这个整数就是我们说的ASCII,

                由于美国使用的字符个数不超过256,所以这个整数值只需要8bit

        ASCII ---》 char unsigned char  8bits

                man ascii

    把我们的字符分为了两类:

            (1)、普通字符:可以打印的字符,有形状

                如:

                    'a'---'z'

                    'A'---'Z'

                    '0'---'9'

                    ....

                    char a = 'a';

                    char c = 'z';

    (2)、特殊字符(转义字符):不可以被打印的字符,没有形状

                    '\n' : 换行符

                    '\r' : 回车符

                    '\t' : 制表符

                    .......

                    '\oooo' : 有\后面跟1个,2个,3个八进制数

    这些八进制数字用来所期望的字符的ASCII码

                                eg:

    'A'  :  101   65    41

                                            'A'

                                            '\101'

                                            '\x41'

                                            65

                                            0101

                                            0x41

    '\xhh' :由\x后面跟一个或者两个十六进制的数字组成

                                这些十六进制的数字用来指定所期望的字符的ASCII

    如:

                                        char ch = 'A'

                                        char ch = '\101'

                                        char ch = '\x41'

                                        char ch = 65;

                                        char ch = 0101;

                                        char ch = 0x41;

                    null字符:ASCII码0的字符 ,一般用来表示字符串的结束

                        '\0' ---- > 0

                          0  -----> 48

    char ch = '\0';   ===> 0

                          char ch = 0;  ===>0

                          char ch = '0' ====> 48

    NOTE:

        (1)、字符常量   和 字符串常量 是不一样的

            字符常量 表示的是单个字符   , 用单引号引起来

                如:

                    '0'

            字符串常量 表示 的是一串字符 用双引号引起来的

                如:

                    "0"

        (2)、‘A’ - ‘Z’   ‘0’ - ‘9’   是连续的

#### 浮点常量(带小数)

    由整数部分,小数点,小数部分,一个e/E,一个可选的带符号的整型指数和可选的表示类型的后缀(F/f/l/L)

        f/F : float

        l/L : long double

        没有后坠的 : double

    float a = 34.567;

            double a = 1.234;

            double a = .123;

                整数部分:可以省略

                小数部分:也可以省略

                    但是整数部分和小数部分不可以同时省略

    例子:

                float f = 2.3E3;     YES

                float f = .3E3;      YES

                float f = 5E3;       YES

                float f = 3e-3;     YES

                float f = E5;       error

#### 枚举常量

    后面讲

##### 练习:

    分析如下结果,机器32bits

    (1)、

        char ch = 65;

        printf("%c\n",ch);   //A

    (2)、

        char ch = 253;

        ch = ch + 7;   ch  = ch + 15   //4

        printf("%c\n",ch); // ascii为4的那个字符   //ascii为12的那个字符

        printf("%d\n",ch); //4  12

        printf("%u\n",ch); //4  12

        printf("%x\n",ch); //4   c

## 总结

    (1)、变量的属性即变量的左值和右值

    (2)、整数在计算机中存放的形式的两个结论

        结论一:

            一个负数会和一个较大的正整数的补码形式相同

        结论二:

            在cpu底层中没有符号位的概念,都是数值位,都参与了运算,至于这个数是 正数还是负数,得看你的脸色来!

ps.不同类型的整型之间的赋值问题:

在C语言中允许不同类型的整数之间可以相互赋值:

    char a;    //8bits
    int  b;    //32bits
    short c;   //16bits

    a = b;      //YY
    c = a;     //YY

    为什么长度,不一样,你如何赋值的!

   

    很标准的一个C语言的建议:

        (1)、长 ------ 短

                高字节直接就pass(丢弃),低字节直接拷贝

        (2)、短 ----- 长

                低字节直接拷贝,高字节我们补什么呢?

                    if 短的是有符号位,高位就全部补符号位

                    if 短的是无符号位,高位就全部补0;

    eg:

        假设运行如下的代码的机器是32bits    

​
 unsigned char c = 250;
        char d;
        d = c+8;
        printf("%d\n",d);  //2
        printf("%u\n",d);  //2


        c : 8bits
            1111 1010
        c+8 :
            c - > 32 bits : 短的----》长的 c:unsigned , 高位全部补 0
            1111 1010
            00000000    00000000    00000000    00001000 8
            00000000    00000000    00000000    11111010 c
            00000000    00000000    00000001    00000010 c+8
        c+8 ---》d      长 ----- 》 短  低字节直接拷贝,高字节字节pass
        d:  
            0000 0010

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值