• 数据类型学习


    问题的引入

    直到计算机的是用来解决问题的一种工具

    计算机通过把问题域的数据保存起来,然后通过某些运算得到想要的结果

    程序 = 算法 + 数据结构

    计算机首要解决的就是数据的保存问题,在数据保存之前。

    首先要知道这个数据的大小,取值范围...

    1。数据类型

    C语言中,有如下类数据型

    1)基本类型 ,C语言已经定义好的类型

    主要是用来存储 数(整数,小数)

    整数:

    (signed)char/unsigned char 8bits

    (signed)short/unsigned short  16bits

    (signed)int/unsigned int

    (signed)long/unsigned long

    上面的这些基本类型有什么区别?

    a :

    signed/unsigned

    有符号 :符号位(最高位)+数值位

    无符号:数值位

    b:

    所占内存空间不一样 =》取值范围不一样

    在不同的编译器下,同一类型所占的空间大小不一样

    int  =>C51 16bits

    int  ->ubuntu 14.04 32bits

    long ->ubuntu 14.04 32bits

    long ->ubuntu 16.04 64bits

    sizeof(1)

    C语言中整数默认的类型int

    typeof(2)  =>int

    int a;

    typeof(a) =>int

    typeof(3+2) =>int

    typeof  某某的类型

    typeof(a) b;

    浮点数:

    float :单精度浮点数

    double:双精度浮点数

    long double:长双精度浮点数

    区别:

    所占空间大小不一样,保存的精度不一样

    sizeof(double) =>8

    sizeof(float) =>4

    C语言中小数的默认类型是double

    typeof(2.0)  =>double

    typeof(2.0f) =>float

    typeof(2.0+3) =>double

    C语言中自动向高精度转(向存储空间大的转)

    2)构造类型:C语言中允许程序员自定义的类型

    数组:一组相同元素的数据集合

    int a[10];//定义了一个数组,数组名为a,里面有10int型元素

    结构体

    联合体

    枚举

    3)指针类型

    4void类型

    voidC语言中,有三个作用

    1void*

    通用指针

    2void当做函数形参,表示该函数不需要带参数

    eg:

    int func(void)

    {

    }

    (3)void当做函数的返回值类型,表示该函数无返回值

    eg:

    void func()

    {

    return ;

    }

    ===

    void func()

    {

    }

    C语言中的数据,从(可写的)属性上分

    变量:可以改变的数据对象

    常量:不可以改变的数据对象

    2.变量

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

    存储变量的时候聚会开辟一个存储单元

    变量在使用前,必须先定义

    2.1 变量的定义

    语法:

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

    {} 可选·

    变量的类型:指定数据对象的类型,所有C语言合法的数据类型都可以

    变量名:一个对象的名字,标识符

    C语言规定:标识符是一串字符,由字母,下划线,数字三类组成,并且第一个字符必须是字母或下划线

    “见其名知其意”

    int sum;

    eg:

    int a = 5;//定义并初始化

    2.2变量的属性

    变量的类型

    变量名

    变量的值

    变量的存储单元中的内容(值)

    每一个变量都有一个值,无论是否赋值

    变量的存储单元

    在程序运行时,系统会为每一个变量分配一个空间用来保存变量的值。

    并且这个空间有一个唯一的地址,这个地址就是变量的地址

    eg:

    int a;

    printf("gfuri%d ",a);

    //没有任何语法错误

    2.3变量的访问

    /

    读:从变量的存储单元中读取它的内容

    读变量的值

    写:把一个数值写到变量所对应的存储单元中

    “赋值”

    eg:

    int a = 5;

    a = 1024;//写操作 把1024这个值写到a所对应的地址中

    b = a*4;//读操作 把a的值乘以4赋值给b

    =>任意一个变量,有且仅有两层含义

    1)代表变量的地址

    lvalue 左值  可写的地址

    2)代表变量的值

    rvalue  右值 可读的值

    3.常量

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

    常量有多种情况:

    1)整型常量:在代码文本中,代表整数的常量值

    八进制整型常量

    0[0-7]*

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

    eg:

    0123

    0777

    088 //error

    int a = 0123;

    printf("%d ",a);

    八进制与二进制对应的关系

    一个八进制对应三个二进制

    八进制 二进制

    0 000

    1 001

    ..

    7 111

    十六进制

    0[xX][0-9a-fA-F]+

    eg:

    int a = 0xf3;

    十六进制与二进制对应的关系

    一个十六进制对应四个二进制

    十六进制 二进制

    0 0000

    1 0001

    ..

    f 1111

    十进制

    [0-9]+

    (2)字符常量

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

    eg:

    普通字符:有形状可以打印

    'a'

    转义字符:没有形状可以打印

    ' ' =>换行符

    ' ' =>tab

    ' ' =>回车符

    'v' =>垂直制表

    '' =>退格

    '' =>空字符

    'ddd'   任意字符  三位八进制

    'xhh'  任意字符  二位十六进制

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

    美国吧每一个字符给一个唯一的整数来标识。美国使用字符是不超过256个字符,

    整数值只需要8bits保存

    char ,unsigned char

    man ascii

    '0' ~'9'  48 ~57

    'a'~'z'   97 ~122

    'A'~'Z'   65 ~ 90

    ================================

      Oct   Dec   Hex   Char                        Oct   Dec   Hex   Char

           ────────────────────────────────────────────────────────────────────────

           000   0     00    NUL ''                    100   64    40    @

           001   1     01    SOH (start of heading)      101   65    41    A

           002   2     02    STX (start of text)         102   66    42    B

           003   3     03    ETX (end of text)           103   67    43    C

           004   4     04    EOT (end of transmission)   104   68    44    D

           005   5     05    ENQ (enquiry)               105   69    45    E

           006   6     06    ACK (acknowledge)           106   70    46    F

           007   7     07    BEL 'a' (bell)             107   71    47    G

           010   8     08    BS  '' (backspace)        110   72    48    H

           011   9     09    HT  ' ' (horizontal tab)   111   73    49    I

           012   10    0A    LF  ' ' (new line)         112   74    4A    J

           013   11    0B    VT  'v' (vertical tab)     113   75    4B    K

           014   12    0C    FF  'f' (form feed)        114   76    4C    L

           015   13    0D    CR  ' ' (carriage ret)     115   77    4D    M

           016   14    0E    SO  (shift out)             116   78    4E    N

           017   15    0F    SI  (shift in)              117   79    4F    O

           020   16    10    DLE (data link escape)      120   80    50    P

           021   17    11    DC1 (device control 1)      121   81    51    Q

           022   18    12    DC2 (device control 2)      122   82    52    R

           023   19    13    DC3 (device control 3)      123   83    53    S

    ......

    eg:

    printf("%c ",65);//A

    printf("%c ",0101);//A 1+64*1=65

    printf("%c ",0x41);//A 4*16+1=64+1=65

    printf("%c ",'a');//a

    printf("%c ",'103');//C

    printf("%c ",'x46');//F

    (3)浮点型常量

    由整数部分,小数点,小数部分,一个e/E,一个可选的带符号的整数指数和一个

    可选的表示类型的后缀(f/F/l/L

    f/F =>float

    l/L =>long double

    没有后缀  double

    整数部分 :可以省略

    小数部分 :也可以省略

    但是不可以同时省略

    eg:

    float f = 2.3E3;//正确

    float f = .3E3 ;//正确

    float f = 5E4;//正确

    float f = 2.3E-3;//正确

    float f = E5;//不正确

    (4)void常量

    4.整数的存储问题

    整数在计算机中是如何存放?

    整数是以二进制的补码形式存放

    为什么要以补码?

    正数

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

    “原码”:把相应的数值转换为二进制

    13 8bits

    00001101

    9 :bits

    00001001

    负数

    负数的补码是 绝对值的原码 取反 +1

    -13  8bits

    |-13| = 13 原码

    00001101

    11110010

    11110011  =-13在计算机中的存储形式

    8bits来存一个整数

    -2的存放形式

    11111110

    254的存放形式

    11111110

    结论:一个负整数会和一个比较大的正整数的补码形式(在计算机中的存放形式)一样的

    -x  (2^n-x) 一样

    n表示存放的bit位数

    11111101

    既可以是-3又可以是253

    unsigned  =>253

    signed =>-3

    符号位+数值位

    符号位

    1 =》负数

    0 =》正数

    结论:CPU内部是没有正负之分,对于CPU来说,所有的bit位都是数值位

    都参与运算。至于是有符号位还是无符号位,就看编译器的词义

    练习:

    分析如下程序的输出结果

    (1)

    int a = -3;

    //程序运行时,会a分配32bits的存储单元

    并且把数值-3 按照补码存放到a的存储单元中

    |-3| 原码

    00000000 00000000 00000000 00000011   3

    11111111 11111111 11111111 11111100   取反

    11111111 11111111 11111111 11111101   +1

    =-3的存放形式

    %d

    11111111 11111111 11111111 11111101  (x)

    最高位是符号位,并且是1,负数

    那么负多少?

    求这个数的绝对值原码

    数的绝对值原码

    -1 =》取反

    11111111 11111111 11111111 11111101  x

    11111111 11111111 11111111 11111100   -1

    00000000 00000000 00000000 00000011   取反

    |x| = 3

    %u

    11111111 11111111 11111111 11111101

    无符号数,全部都是数值位

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

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

    (2)

    int a = -56;

    printf("a = %d ",a);//-56

    printf("a = %u ",a);//2^32-56

    (3)

    int a = 2048;

    printf("a = %d ",a);//2048

    printf("a = %u ",a);//2048

    (4)

    unsigned int a = -1u;

    -1 -1u的区别?

    typeof(-1)  =>int

    typeof(-1u)  =>unsigned int

    printf("a = %d ",a);//-1

    printf("a = %u ",a);//2^32-1

    char : -128~127

    unsigned char : 0~255

    正数

    0 1111111  =>127

    1 0000000

    1 1111111

    1 0000000   =128   x= -128

    无符号:0

    11111111   255

    GNU有一个标准的头文件 stdint.h

    int8_t  //有符号8bits整数类型

    uint8_t  //无符号8bits整数类型

    ...

    有符号8bits整数的最小值和最大值

    INT8_MIN

    INT8_MAX

    INT16_MIN

    INT16_MAX

    INT32_MIN

    INT32_MAX

    ...

    ===============

    char c = 250;

    char d;

    d = c+8;

    c:

    11111010

    00001000

    d: 00000010

    printf("d = %d ",d);//2

    printf("d = %u ",d);//2

    5.整型变量的赋值问题

    C语言中,允许不同类型的整数之间相互赋值

    char =>int

    long =>short

    c标准:

    1)长-》短

    长的赋值给短的,低字节直接拷贝

    高字节全部丢弃

    2)短-》长

    短的赋值给长的,低字节直接拷贝

    高字节补?

    如果短的无符号的,高位全部补0

    如果短的有符号的,高位全部补符号位

    练习:

    1char c = -3;

    printf("c = %d ",c);//-3

    printf("c = %u ",c);//2^32-3

    c:

    1111 1101

    %d :int

    =》长

    有符号数

    11111111 11111111 11111111 11111101

    -1  11111111    11111111 11111111 11111100

    取反 00000000 00000000 000000000 00000011

    %u

    11111111 11111111 11111111 11111101

    =============

    2unsigned char c = -3;

    printf("c = %d ",c);//253

    printf("c = %u ",c);//253

    c:

    1111 1101

    %d :int

    =》长  短的无符号的,高位直接补0,低字节直接拷贝

    00000000 00000000 00000000 11111101

    %u:int

    =》长  短的无符号的,高位直接补0,低字节直接拷贝

    00000000 00000000 00000000 11111101

    6."溢出问题"

    char c = 253;

    char d;

    d = c+192;

    c11111101

    192 00000000     00000000 000000000 11000000

    char + int =>int (自动升级为int)

    dchar,8bits,在计算时,192只取低8bits

    11111101

    11000000

       110111101

    11111111 11111111 11111111 10111101

    printf("d = %d ",d);//-67

    printf("d = %u ",d);//2^32-67

    ======

    char c = 253;

    unsigned char d;

    d = c+192;

    c :

    11111101

    192:11000000

    d : 10111101

    char =>int

    00000000 00000000 00000000 10111101

    printf("d = %d ",d);//255-2-64 = 189

    printf("d = %u ",d);//189

    ======

    char c = 253;

    int d;

    d = c+192;

    c :11111101

    19200000000 00000000 00000000 11000000

    c+192:

    c =>int

    11111111 11111111 11111111 11111101

    00000000 00000000 00000000 11000000

       100000000 00000000 00000000 10111101

    printf("d = %d ",d);//189

    printf("d = %u ",d);//189

    =====

    char c = 253

    char c1 = 192;

    int d;

    d = c+c1;

    printf("d = %d ",d);//-67

    printf("d = %u ",d);//2^32-67

    c :

    c1:

    c+c1:

    c->int

    c1->int

    7.总结

    数据类型

    基本类型

    构造类型

    指针类型

    void

    变量的属性:

    变量的类型

    变量名

    变量的值

    变量的存储单元

    变量的访问:

    /

    lvalue

    rvalue

    常量

    整数在计算机中的存放形式

    补码

    -x 2^n-x补码形式一样

    整数之间的赋值问题

    =》短

    =》长

    作业:

    分析如下程序的输出结果

    printf("%d ",-1);

    printf("%u ",-1);

    printf("%d ",(char)-1);

    printf("%u ",(char)-1);

    printf("%d ",(unsigned char)-1);

    printf("%u ",(unsigned char)-1);

    printf("%d ",-1u);

    printf("%u ",-1u);

    printf("%d ",255);

    printf("%u ",255);

    printf("%d ",(char)255);

    printf("%u ",(char)255);

    printf("%d ",(unsigned char)255);

    printf("%u ",(unsigned char)255);

    #include<stdio.h>

    //share文件夹,测试程序

    int main()

    {

    printf("j1=%d ", -1);

    printf("j1=%u ", -1);

    // -1 2^32-1

    //1的绝对值的原码为0000 0001 补码为1111 1111 扩展为36位为 24181

    printf("j1=%d ", (char)-1);

    printf("j1=%u ", (char)-1);

    //感觉与上题目一致,测试的确一致

    printf("j1=%d ", (unsigned char)-1);

    printf("j1=%u ", (unsigned char)-1);

    //255 255

    //只要将1111 1111全部扩展到32位,跟着前面的符号位进行变化,因为是无符号,所以前面全部加0,所以理解

    printf("j1=%d ", -1u);

    printf("j1=%u ", -1u);

    //-1 2^32-1

    //因为开始加u就是无符号的所以,全部已经进行了扩展

    printf("j1=%d ", 255);

    printf("j1=%u ", 255);

    //255 255

    //直接是整型的,所以不需要怎么样的

    printf("j1=%d ", (char)255);

    printf("j1=%u ", (char)255);

    //-1 2^32-1

    //81,之后因为首部为1,判定为负数,扩展之后是全1,所以判定为负数,最后减数1,取反

    printf("j1=%d ", (unsigned char)(255));

    printf("j1=%u ", (unsigned char)(255));

    //255 255

    //全为1,然后因为无符号,所以全部补上0,符号位判定为0,直接计算

    }

    作业答案:

    printf("%d ",-1);

    printf("%u ",-1);

    -1 :int

    -1的补码:11111111 11111111 11111111 11111111

    %d: (第一个1当做符号位)

    1 11111111 11111111 11111111 11111110

    取反:00000000 00000000 00000000 00000001

    其值为-1

    %u:(没有符号位)

    11111111 11111111 11111111 11111111

    其值为2^32-1

    printf("%d ",(char)-1);

    printf("%u ",(char)-1);

    -1 :int

    -1的补码:11111111 11111111 11111111 11111111

    转换成char

    11111111

    再转换成int:

    11111111 11111111 11111111 11111111

    %d: (第一个1当做符号位)

    1 11111111 11111111 11111111 11111110

    取反:00000000 00000000 00000000 00000001

    其值为-1

    %u:(没有符号位)

    11111111 11111111 11111111 11111111

    其值为2^32-1

    printf("%d ",(unsigned char)-1);

    printf("%u ",(unsigned char)-1);

    -1 :int

    -1的补码:11111111 11111111 11111111 11111111

    转换成unsigned char

    11111111

    再转换成int:

    00000000 00000000 00000000 11111111

    %d: (第一个1当做符号位)

    00000000 00000000 00000000 11111111

    其值为255

    %u:(没有符号位)

    00000000 00000000 00000000 11111111

    其值为255

    printf("%d ",-1u);

    printf("%u ",-1u);

    -1u :unsigned int

    -1的补码:

    11111111 11111111 11111111 11111111

    %d:(第一个1当做符号位)

    1 11111111 11111111 11111111 11111110

    取反:00000000 00000000 00000000 00000001

    其值为-1

    %u:(没有符号位)

    11111111 11111111 11111111 11111111

    其值为2^32-1

    printf("%d ",255);

    printf("%u ",255);

    255 :int

    补码 00000000 00000000 00000000 11111111

    %d: (第一个0当做符号位)

    00000000 00000000 00000000 11111111

    其值为255

    %u:(没有符号位)

    00000000 00000000 00000000 11111111

    其值为255

    printf("%d ",(char)255);

    printf("%u ",(char)255);

    255int

    补码 00000000 00000000 00000000 11111111

    转化成char

    11111111

    再转换成int

    11111111 11111111 11111111 11111111

    %d:(第一个1当做符号位)

    1 11111111 11111111 11111111 11111110

    取反:00000000 00000000 00000000 00000001

    其值为-1

    %u:(没有符号位)

    11111111 11111111 11111111 11111111

    其值为2^32-1

    printf("%d ",(unsigned char)255);

    printf("%u ",(unsigned char)255);

    255int

    补码 00000000 00000000 00000000 11111111

    转化成char

    11111111

    再转换成int

    00000000 00000000 00000000 11111111

    %d:(第一个0当做符号位)

    00000000 00000000 00000000 11111111

    其值255

    %u:(没有符号位)

    00000000 00000000 00000000 11111111

    其值255

    算生日代码

    #include <stdio.h>

    int main()

    {

    int n,sum = 16;

    int year,month,day;

    //输入出生年月日

    scanf("%d%d%d",&year,&month,&day);

    //去掉尾年,把整年总天数算出来

    for(n = year;n<=2018;n++)

    {

    if((n%4 == 0 && n%100 != 0) || (n%400 == 0))//判断是否为闰年

    {

    sum += 366;//年数加366

    }

    else

    {

    sum += 365;

    }

    }

    //去掉出生那日之间的天数

    int monthday[] = {0,31,28,31,30,31,30,31,31,30,31,30,31};

    for(n = 1; n < month;n++)

    {

    sum -= monthday[n];

    }

    sum -= day;

    if(((year%4 == 0 && year%100 != 0) || (year%400 == 0))&& (month > 2))//判断是否为闰年

    {

    sum -= 1;//年数加366

    }

    printf("sum = %d ",sum);

    }

    END

  • 相关阅读:
    产品经理之路(八)
    产品经理之路(七)
    产品经理之路(六)
    产品经理之路(五)
    产品经理之路(四)
    产品经理之路(三)
    产品经理之路(二)
    react-admin-plus 正式开源, 欢迎star
    uni-app—从安装到卸载
    vue项目使用websocket技术
  • 原文地址:https://www.cnblogs.com/qihuanye-229110/p/11147288.html
Copyright © 2020-2023  润新知