c语言数据类型

0.问题的引入

计算机(computer)只是我们人类用来解决某些问题的一种工具而已。 "某些问题"是指哪些问题呢? 就是那些可以通过 计算来解决的问题。 计算机是通过“计算”来解决这些问题的。

计算:计算机通过把问题域中的数据抽象出来,保存,然后对这些数据进行一系列的有目的的计算从而得出结果。 如: 3 + 5 => 8

计算机首先要保存数据,在保存数据前,我们首先要知道这些数据的大小、取值范围等数据属性。 不然我怎么知道要开辟多大的空间,去存储它们呢?

数据的大小、取值范围、类型等等属性: 数据类型

数据类型:

描述数据对象的类型的。 “给数据分类” 不同类型的数据,属性不一样。

1. C语言中的数据类型

(1) 基本类型

C语言内置的,已经为我们定义好的类型,程序员可以直接用,称之为“基本类型” "基本类型"主要是用来描述“数”:整数、浮点数

  • 整数 (signed) char/unsigned char: 8bits整数类型(或字符类型) (signed) short/unsigned short: 一般来说, short占16bits (signed) int /unsigned int: (signed) long/unsigned long: 区别在哪里呢? sizeof(char) == sizeof(unsigned char) = 1 byte sizeof(char) <= sizeof(short) <= sizeof(int) <= sizeof(long)

  • 浮点数

用来保存有小数的数字 float: 4bytes(一般来说) double: 8bytes(一般来说) <<<<<< long double: 10 bytes(一般来说) 区别: 用来保存浮点数位数不一样,精度不一样!!! sizeof(long double) >= sizeof(double) >= sizeof(float) 在代码中,浮点数默认的类型是 double

(2) 构造类型

C语言中,允许程序员自定义类型, 自定义 复合/组合类型,称之为构造类型。 数组

    int a[10]; //a是一个含有10个int类型元素的数组。
            //上面那个定义中, int不是数组的类型,而是数组元素的类型!!!
​
    typeof(a[0]): int
    typeof(a): int[10]
​
    float b[200]; //b是一个含有200个float类型元素的数组。
    typeof(b): float[200]

结构体 联合体 枚举

(3) 指针类型

先 wait wait, 后面有专题讲

(4) void

空类型,在C语言中,有且仅有 三个地方可以用 void

  • void 可以做函数的返回值类型, 表示该函数无返回值

​
//函数func没有返回值
void func(int a)
{
    ....
}
​
// b = func(3) ; ERROR
​
​
//函数sum是有返回值的,返回值是一个int
int sum(int a, int b)
{
    //...
}
​
int b = sum(3,5); //OK的
  • void 可以做函数的形式参数,表示该函数无参数

​
//函数abc不要参数
int abc(void)
{
    //...
}
​
abc(5); ERROR
abc();Ok的
​
  • void*

“通用指针”

有了数据类型后,我们在程序中,就可以定义数据对象了。 数据对象:

  • 变量:在程序运行期间,其值可以被改变的数据对象,称之为变量。

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

2. 变量

"先定义,后使用"

2.1 变量的定义

定义变量的格式,如下:

    数据类型  变量名  {= 初始值} ; {}内表示可选的

数据类型:

代表该变量的类型,系统会根据这个类型来分配合理的空间去存储这个变量。 数据类型是任意合法的类型都可以(基本类型 或 构造类型 或 指针类型)

变量名:

就是你给变量取的一个名字。但是在C语言中,你给任何东西取名,都必须符合“C语言标识符”的规定.

标识符(“取的名字”): 必须要 字母、下划线、数字组成,并且第一个字符必须是字母或下划线

如:

    sb 可以
    sb250  可以
    ssb 也可以
    250 不可以
    _250 可以
    fdfdf9090=  不可以
    int 不可以。 不能和C语言已经有的关键字相同
​
    "见名知其意"
        sum ; //用来保存数据的和
​

2.2 变量的属性

    int a = 5;

在程序运行时,系统会为变量a分配一个四个字节(假设int占4bytes)的存储空间,并且把数值5存入到这个空间中去。 "存储单元":系统会为每一个存储单元(以字节为单位)分配一个唯一的编号,用于区分这些存储单元,这个存储单元的编号 称之为 存储单元的地址。

变量的属性:

变量名 变量的地址: 变量存储单元的地址(首地址) 变量的值: 变量存储单元中的内容

练习:

  1. 分析如下代码的输出结果

​
int main()
{
    int a;
​
    printf("a = %d\n", a); //输出变量a的值
​
    return 0;
}
​

以下描述正确的是:__B_ A. 变量a没有值 B. 变量a一定有一个值,只是这个值,你不知道而已

2.3 变量的左值和右值

对一个变量的操作:

  • read

读一个变量的值:是从变量的存储单元中,取内容

  • write

把一个值 写入到变量的存储单元中去 C语言中,提供一个 赋值= ,把右边的值 赋值 给左边的变量

把右边的值 写入到 左边的变量的存储单元中去

如:

    int a = 250;
    int b;
​
    a = 1024; //把数值 1024 写入到变量a的地址中去
                //a: "变量a的地址"
​
    b = a; //把变量a的值,赋值给 b
          //a: "变量a的值"
​
  

上面两条语句,同样是a, 含义是不一样的!!! 由此得出结论: 在C语言中,任何变量都有且仅有两层含义: (1)右值

rvalue: readable value 可读的值 rvalue: 变量的值

(2)左值

lvalue: location value 可寻址的地址,可写的地址 lvalue: 变量的地址

请问:

  1. 变量何时代表变量的值(右值,rvalue), 何时代表变量的地址(左值,lvalue)呢?

"在赋值号= 的左边",代表地址(lvalue,左值) “其他情况,赋值号= 的右边”,代表的是变量的值(rvalue, 右值)

例子:

    int a;
    int b;

    a = 1024;//a的左值: 变量a的地址
    a + 3;  //a右值: 变量a的值
        // => {int tmp = a + 3;}

    a = a * 3;
        //左边的a: a的左值,变量a的地址
        //右边的a: a的右值, 变量a的值

    //...

3. 整型变量

    // char/short/int/long
int a = 5;

在程序运行时,系统会为a分配空间,并存储“数值5” 整数值 在计算机中是如何存放的呢?

3.1 整数在存储器(计算机)中的存放形式

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

  • 正整数的补码

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

//假设以 8bits 来存放整数
13: 8bits
    把十进制的13转换成二进制即可
    13 = 8 + 4 + 1

    00001101  13的原码/13的补码

255: 8bits
    255 = 256 - 1
    11111111 255的原码/255的补码

  • 负整数的补码

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

//以8bits来存放整数
    -13的补码
     13的原码
        00001101     13的原码
        11110010     取反
        11110011   +1
            11110011   -> -13在计算机中的表示形式(8bits)

练习:

  1. 假设计算机中用 32bits 来存放整数,请写出 123和 -123的存放形式。

    123: 64 + 32 + 16  + 8 + 2 + 1
         00000000 00000000 00000000 01111011 <-   123在计算机中的存放形式(32bits)
    -123
    123:  00000000 00000000 00000000 01111011
    取反: 11111111 11111111 11111111 10000100
    +1:   11111111 11111111 11111111 10000101  <-   -123在计算机中的存放形式(32bits)
  1. 假设计算机中用8bits来存放整数 请写出 -1 和 255 的存放形式 请写出 -2 和 254 的存放形式 请写出 -3 和 253 的存放形式 请写出 -4 和 252 的存放形式 .... 直到你找到规律为止。

  • 结论1

一个负整数在计算机中的存放形式,会和另外一个正整数的存放形式相同。 -x 与 2^n - x (2的n次幂 - x) n为存放整数的bit位数

练习:

  1. 假设一个整数在计算机中的存放形式(32bits)为: 11111111 11111111 11111111 11111111 请问这个整数是多少? -1 或 2^32 -1

  • 结论2

> 在CPU底层是没有符号位的概念的,都是数值位,都参与运算,至于这个数到底是正数还是负数,
> 就得看你编译器的词义啦,意思是说,你把这个数当作是一个有符号(signed),还是无符号(unsigned)来解释。


编辑器(逻辑层面)
有符号的(signed)
    符号位(最高位)  + 数值位(其他位)
        1  负数
        0  正数 or 0
无符号的(unsigned)
    所有的bit位,都是数值位

练习:假设 int 占 32bits

  1. 分析如下程序的输出结果

int main()
{
    int a = -3;
    printf("%d\n", a); // -3
    printf("%u\n", a); // 2^32 -3

    return 0;

        // %d: 把后面那个玩意当作是一个 有符号的数,按十进制输出
        // %u: 把后面那个玩意当作是一个 无符号的数,按十进制输出
}

  1. 分析如下程序的输出结果

int main()
{
    int a = 4;
    printf("%d\n", a);  //4
    printf("%u\n", a);  //4
    return 0;
}

3.分析如下程序的输出结果

int main()
{
    unsigned int  a = -4u;

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

// -4/-4u
//     4  00000000 00000000 00000000 00000100
//        11111111 11111111 11111111 11111011

//        11111111 11111111 11111111 11111100  -4/-4u 在计算机中的存放形式(32bits)


// typeof(-4): int
// typeof(-4u): unsigned int
  1. 分析如下程序的输出结果

int main()
{
    unsigned char c = 250;
    char d;
    d = c + 9;

    printf("%d\n", d);
    printf("%u\n", d);
}

3.2 不同整型之间的赋值问题

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

    char a; //8bits
    short b; //16bits
    int c; //32bits
    long d; //32 or 64bits

    a = b;
    d = c;
    c = a; 
    //....

    //允许不同整数类型之间相互赋值

有人提出:

长度都不一样,如何来赋值呢?

C语言标准委员会建议采用如下策略:

  • (1) 长的 -> 短的

低字节直接拷贝,高字节直接 discards(丢弃、抛弃)

  • (2) 短的 -> 长的

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

如果短的是无符号数,高位就全部补0 如果短的是有符号数,高位 就全部补 符号位!!!

练习:

  1. 分析如下程序的输出结果,假设机器(int)是32bits

int main()
{
    // char c;
    // signed char c;
    char c = 250;
    printf("%d\n", c); //-6
    printf("%u\n", c); //2^32 - 6

    typeof(250): int
    250: 00000000 00000000 00000000 11111010
    c = 250   int -> char 长->短
    c:           11111010

    %d: int
    %d:  c -> int 短->长
       11111111 11111111 11111111  11111010
    -1 11111111 11111111 11111111  11111001
  取反 00000000 00000000 00000000  00000110

    c:           11111010
    %u: unsigned int
        c -> unsigned int 短->长
          11111111 11111111 11111111   11111010

    return 0;
}
  1. 分析如下程序的输出结果,假设机器(int)是32bits

1. 分析如下程序的输出结果,假设机器(int)是32bits
```c++
int main()
{
    unsigned   char c = 250;
    printf("%d\n", c);  //250
    printf("%u\n", c);  //250


    typeof(250): int
    250: 00000000 00000000 00000000 11111010
    c = 250   int -> char 长->短
    c:           11111010

    %d: c -> int 短->长
        00000000 00000000 000000000    11111011

    %u: c-> unsigned int 短->长
        00000000 00000000 00000000 11111011
    return 0;
}

思考:

C程序中,有些时候需要定义一个 8bits的整数, char/unsigned char 有些时候需要定义一个 16bits or 32bits or 64bits,这个时候怎么办呢? 16bits: short/unsigned short ??? sizeof(char) == sizeof(unsigned char) == 1 byte short 不一定就是 16bits的,int也不一定是 32bits, ... 因为这些类型(short,int,long)的长度是跟机器和编译器相关(Machine Dependent)

那这个问题怎么解决呢?

3.3 GNU下标准的整数类型

有哪些系统或环境是符合GNU:

Linux Unix GNU有一个标准的头文件: stdint.h, 这个头文件 定义GNU下标准的整型。 在头文件 stdint.h 中定义如下整数类型

    int8_t  //有符号的8bits的整数类型  char
    uint8_t //无符号的8bits的整数类型  unsigned char

    int16_t //有符号的16bits的整数类型
    uint16_t //无符号的16bits的整数类型

    int32_t
    uint32_t

    int64_t
    uint64_t

    // ...

这些整数类型的最值:

            MIN                  MAX
uint8_t     0                    255
int8_t     -128                  127
uint16_t    0                    65535
int16_t    -32768                32767 
uint32_t   ... 
int32_t    ...

在头文件 stdint.h 中,已经为我们定义了这些“最值”的宏,你直接用就可以啦

    INT8_MAX   //8bits有符号整数的最大值
    INT8_MIN   //8bits有符号整数的最小值

    INT16_MAX  //16bits有符号整数的最大值
    INT16_MIN  //16bits有符号整数的最小值
    
    INT32_MAX  //32bits有符号整数的最大值
    INT32_MIN  //32bits有符号整数的最小值
    ...


    UINT8_MAX
    UINT16_MAX
    UINT32_MAX
    UINT64_MAX
    ...

4.常量

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

4.1 整型常量

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

  • 八进制整型常量 0 1 2 3 4 5 6 7

0[0-7]*: 以数字0开头,后面接0个或多个01234567 如: 0123 //八进制的123 07777 //八进制的 7777 012345677777 088 //ERROR

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

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

八进制 二进制 0 000 1 001 2 010 3 011 4 100 5 101 6 110 7 111

  • 十六进制整型常量 0 1 2 3 4 5 6 7 8 9 a(A) b(B) c(C) d(D) e(E) f(F)

0xX+ : 以0x或0X开头,后面接至少一个16进制字符 如: 0xff 0x ERROR 0x0 0x123 0x2356G //ERROR

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

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

十六进制 二进制 0 0000 1 0001 2 0010 3 0011 4 0100 5 0101 6 0110 7 0111 8 1000 9 1001 a/A 1010 b/B 1011 c/C 1100 d/D 1101 e/E 1110 f/F 1111

  • 十进制整型常量 [0-9]+

4.2 字符型常量

字符常量是用 单引用 '' 引起来的一个或多个字符的序列。表示一个字符!! 用来表示字符的。

如:

    'A' 字符A
    '\n' 换行符
    '\x12' 也代表的是一个字符,哪个字符呢? wait wait

    'fdlkjfhd' 错误,没有这个字符!!!
    ...

问题1:

我们要在计算机中保存 字符a b c d ..., 计算机保存字符是保存字符的形状吗? 字符保存的是 字符的ASCII码.

ASCII码: American Standard Code for Information Interchange 美国标准信息交换码

给每一个英文字符一个唯一的整数值,这个整数值就是字符的ASCII码 美国人用的所有字符加起来不超过256个,编码 0-255,这个整数值就只需要 8bits整数类型就可以保存啦。 char/unsigned char

    Oct   Dec   Hex   Char                        Oct   Dec   Hex   Char
   ────────────────────────────────────────────────────────────────────────
   000   0     00    NUL '\0' (null character)   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  '\b' (backspace)        110   72    48    H
   011   9     09    HT  '\t' (horizontal tab)   111   73    49    I
   012   10    0A    LF  '\n' (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  '\r' (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
   024   20    14    DC4 (device control 4)      124   84    54    T
   025   21    15    NAK (negative ack.)         125   85    55    U
   026   22    16    SYN (synchronous idle)      126   86    56    V
   027   23    17    ETB (end of trans. blk)     127   87    57    W
   030   24    18    CAN (cancel)                130   88    58    X
   031   25    19    EM  (end of medium)         131   89    59    Y
   032   26    1A    SUB (substitute)            132   90    5A    Z
   033   27    1B    ESC (escape)                133   91    5B    [
   034   28    1C    FS  (file separator)        134   92    5C    \  '\\'
   035   29    1D    GS  (group separator)       135   93    5D    ]
   036   30    1E    RS  (record separator)      136   94    5E    ^
   037   31    1F    US  (unit separator)        137   95    5F    _
   040   32    20    SPACE                       140   96    60    `
   041   33    21    !                           141   97    61    a
   042   34    22    "                           142   98    62    b
   043   35    23    #                           143   99    63    c
   044   36    24    $                           144   100   64    d
   045   37    25    %                           145   101   65    e
   046   38    26    &                           146   102   66    f
   047   39    27    '                           147   103   67    g
   050   40    28    (                           150   104   68    h
   051   41    29    )                           151   105   69    i
   052   42    2A    *                           152   106   6A    j
   053   43    2B    +                           153   107   6B    k
   054   44    2C    ,                           154   108   6C    l
   055   45    2D    -                           155   109   6D    m
   056   46    2E    .                           156   110   6E    n

   057   47    2F    /                           157   111   6F    o
   060   48    30    0                           160   112   70    p
   061   49    31    1                           161   113   71    q
   062   50    32    2                           162   114   72    r
   063   51    33    3                           163   115   73    s
   064   52    34    4                           164   116   74    t
   065   53    35    5                           165   117   75    u
   066   54    36    6                           166   118   76    v
   067   55    37    7                           167   119   77    w
   070   56    38    8                           170   120   78    x
   071   57    39    9                           171   121   79    y
   072   58    3A    :                           172   122   7A    z
   073   59    3B    ;                           173   123   7B    {
   074   60    3C    <                           174   124   7C    |
   075   61    3D    =                           175   125   7D    }    
...

'A' ~ 'Z' ASCII码是连续的 'A' 65 'B' 66 'a' ~ 'z' ASCII码是连续的 'a' 97 'b' 98

'0' ~ '9' ASCII码是连续的 '0' 48

把字符分为两类:

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

如:
    'a' - 'z'
    'A' - 'Z'
    '0' - '9'
    ...

    普通字符的赋值
    char c = '一个普通字符'
    or
    char c = 普通字符的ASCII码(十进制/十六进制/八进制)


    char c = 'A';
    char c = 65;
    char c = 0x41;
    char c = 0101;
    上面四行代码,是没有任何区别的


    char a = 0;
    char a = '0';
    上面这两行代码,有“天壤之别”。你们知道为什么吗?



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

如:

    '\n'  : 换行符
    '\r'  : 回车符
    '\t'  : 制表符
    ...

    还有一些,键盘都不对应的字符,怎么弄?

    '\ooo': 由\后跟1个、2个、3个八进制数字组成,这些八进制数字用来代表所期望的那个字符的ASCII码
        如: 'A' 的ASCII码的八进制为 101
            'A' 和  '\101' 是一个意思!!!!
    '\xhh': 由\x后面跟1个、2个十六进制数字组成,这些十六进制数字用来代表所期望的那个字符的ASCII码
        如:  'A' 的ASCII码的十六进制为 0x41
            'A' 和 '\x41' 是一个意思
    char a = 'A';
    char a = '\101';
    char a = '\x41';
    char a = 65;
    char a = 0101;
    char a = 0x41;

    //上面这几行代码是一个意思!!!(从CPU底层存储上来讲)

注意:

  1. null字符: ASCII码为0的那个字符, 一般用来表示字符串的结束。 在C代码中,如何描述 null字符呢?

    char c = '\0'; //'\0'代表一个字符,该字符的ASCII码的八进制为 0
    char c = 0;

    // char c = '0'; <=> char c = 48;

    要区分 '\0' 和 '0' 是两个完全不同的字符!!!!
  1. 字符常量 和 字符串常量 不一样的

字符常量表示的是一个字符,是用 ''(单引用) 引起来的 字符串常量表示的是一串字符,是用 " "(双引用) 引起来的

    '0'   '\101'  ->  单个字符, 字符常量
    "0" "abc" "" => 字符串

    char c = "0"; //ERROR

4.3 浮点型常量

浮点型常量是由 整数部分、小数点、小数部分、一个e/E、一个可选的带符号的整型指数 和 一个可选的表示类型的后缀(f/F/l/L) 整数部分:可以省略 小数部分:也可以省略 但是整数部分和小数部分不能同时省略。 e/E: 可以省略,在没有指数的情况 后缀 f/F: float 后缀 l/L: long double 没有后续: double 默认类型为 double

    typeof(1.0): double
    typeof(1.0f): float
    typeof(1.0l): long double
    typeof(1): int

来看一个例子:

int main()
{
    // double f = 0.345; //ok

    // float f = .3e3; //正确(整数部分省略  0.3e3)
    // float f = 5e3; //正确的(小数部分省略 5.0e3)
    // float f = e3; //不正确。 整数部分和小数部分不能同时省略,这个时候,编译器会把
    // //                //e3当作是一个变量名
    // float f = 3; //正确的

    int a = 3.5; //C语言中,也可以的
                //编译器会隐含把  int a = (int)3.5;


    // double  f = 15.10000;

    // %f:  double   .6
    // %lf: double
    // %g : 输出浮点数,但是不输出末尾多余的0
    printf("%lf\n", f);
    printf("%g\n", f);

    return 0;

}

4.4 枚举常量和宏常量

后面再讲

练习:

  1. 分析如下程序的输出结果,假设机器32bits

    char ch = 253;
    ch = ch  + 7;

        ch:  11111101
             11111111 11111111 11111111 11111101
             00000000 00000000 00000000 00000111
           1 00000000 00000000 00000000 00000100

        ch: 00000100

    printf("%d\n",ch); //4
    printf("%u\n",ch); //4
    printf("%c\n",ch); //%c把字符形状打印出来
    printf("%x\n",ch); //4 //%x按十六进制输出
    unsigned  char ch = 253;
    ch = ch  + 7;

    printf("%d\n",ch);
    printf("%u\n",ch);
    printf("%c\n",ch); //%c把字符形状打印出来
    printf("%x\n", ch); //%x按十六进制输出

作业:

  1. 分析如下程序的输出结果,假设 int 占32bits

#include <stdio.h>
int main()
{
    char c = 253;
    char d;
    d = c + 192;

    253: 00000000 00000000 00000000 11111101
    c :  11111101
(int)c:  11111111 11111111 11111111 11111101
    192: 00000000 00000000 00000000 11000000
       1 00000000 00000000 00000000 10111101
    d:   10111101

    %d: d -> int  短 -> 长
        11111111 11111111 11111111  10111101
    -1  11111111 11111111 11111111  10111100
    取反 00000000 00000000 00000000  01000011


    %u: d -> unsigned int 短 -> 长
        11111111 11111111 11111111  10111101

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

    return 0;
}
  1. 分析如下程序的输出结果,假设 int 占32bits

#include <stdio.h>
​
int main()
{
    printf("%d\n", -1); //-1
    printf("%u\n", -1); //2^32 - 1
​
    // -1:  11111111 11111111 11111111 1111111
    // %d: int 有符号数
    // %u: unsigned int 无符号数
​
​
    printf("%d\n", 255); //255
    printf("%u\n", 255); //255
​
    255: 00000000 00000000 00000000 11111111
    %d:
    %u:
​
    printf("%d\n",(char) -1); //-1
    printf("%u\n", (char)-1); //2^32 - 1
​
    -1: 11111111 11111111 11111111 1111111
    (char)-1: int -> char 长->短
    (char)-1:  11111111
​
    %d: (char)-1 -> int 短->长
        11111111 11111111 11111111 1111111
​
    %u: (char)-1 -> unsigned int 短->长
        11111111 11111111 11111111 1111111
​
    printf("%d\n", (unsigned char) -1); //255
    printf("%u\n", (unsigned char)-1); //255
    
    -1: 11111111 11111111 11111111 1111111
(unsigned char)-1:  int -> unsigned char 长->短
    (unsigned char)-1: 11111111
    %d: (unsigned char)-1 -> int 短->长
        00000000 00000000 00000000 11111111
    %u: (unsigned char)-1 -> unsigned int 短->长
        00000000 00000000 00000000 11111111
​
    printf("%d\n",(char) 255); //-1
    printf("%u\n", (char)255); //2^32 - 1
​
​
    255: 00000000 00000000 00000000 11111111
(char )255: int -> char
        11111111
    %d: (char)255 -> int 短->长
        11111111 11111111 11111111 11111111
​
    %u: (char)255 -> int 短->长
        11111111 11111111 11111111 11111111
​
    printf("%d\n",(unsigned char) 255); //255
    printf("%u\n", (unsigned char)255); //255
​
    255: 00000000 00000000 00000000 11111111
(unsigned char)255:  11111111
    %d: (unsigned char)255 -> int 短->长
        00000000 00000000 00000000 11111111
    %u: (unsigned char)255 -> unsigned int 短->长
        00000000 00000000 00000000 11111111
    return 0;
}
​
  • 19
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值