字符类型名称是char,这个类型里一共包含256个不同的整数,每个整数代表一个字符(例如'a', '&'等),这些整数和字符可以互相替代,ASCII码表记录了所有整数和字符之间的对应关系
  'a' 97
  'A' 65
  '0' 48

ASCII码表里所有小写英文字母是连续排列的,'a'对应的整数最小,'z'对应的整数最大,所有大写英文字母和阿拉伯数字字符也符合这个规律
  'd' - 'a' 等于 'D' - 'A'
  'd' - 'a' 等于 '3' - '0' 等于 3 - 0

所有字符数据可以分成两组,每组128个,其中一组字符对应的整数在所有计算机上都一样,这些整数的范围从0到127,另外一组字符对应的整数在不同计算机上可能不同,这些整数的范围可能从-128到-1也可能从128到255

'\n' 换行,'\r' 回车,'\\' 代表字符\,'\'' 代表字符','\"' 代表字符"

短整数类型名称是short,这个类型里包含65536个不同的整数,其中一半是负数,另外一半是非负数,这些数字以0为中心向两边扩展

长整数类型名称是long,这个类型里包含2的32次方个不同的整数,其中一半是负数另外一半是非负数,这些数字以0为中心向两边扩展

整数类型名称是int,在我们的计算机上整数类型和长整数类型完全一样

以上类型里都包含非负数和负数,所以它们叫做有符号类型,每个有符号类型都有一个对应的无符号类型,无符号类型的名称就是在对应有符号类型名称前加unsigned关键字(例如unsigned char,unsigned int等),无符号类型包含的数字个数和对应的有符号类型一样,但是无符号类型里不包含负数

整数相关数据类型表示的数字范围是互相重叠并逐渐扩大的

程序中不带小数点的数字后面加u表示数字的类型是无符号整数类型

C语言程序里使用浮点类型表示带小数点的数字,浮点类型分为单精度浮点类型和双精度浮点类型,双精度浮点类型可以记录更多小数点后面的数位,单精度浮点类型名称是float,双精度浮点类型名称是double

程序里带小数点的数字默认是双精度浮点类型的,程序里带小数点的数字后加f表示数字的类型是单精度浮点类型

/*
 * 字符演示
 * */
#include <stdio.h>
int main() {
    printf("abc\nde\n");
    printf("abc\rde\n");
    printf("%f  %g\n", 3.2f, 3.2f);
    return 0;
}

C语言里允许程序员扩展新的数据类型,这些新的数据类型叫复合数据类型,复合数据类型需要先声明然后才能使用

C99规范里引入布尔类型,这个类型里只包含0和1两个整数,其中0叫假1叫真,真和假都叫做布尔值

任何一个整数都可以当作布尔值使用,整数0当布尔值,使用的时候是假,其他整数当布尔值使用的时候都是真

一般在程序里不要使用布尔类型,直接把整数当布尔值使用就可以了

数据类型和占位符的对应关系
  char和unsigned char %c
  short %hd
  unsigned short %hu
  long %ld
  unsigned long %lu
  int %d
  unsigned int %u
  float %f和%g
  double %lf和%lg
  %f和%lf会保留小数点后面
  无效的0,%g和%lg不会保留

不同类型的存储区里包含的字节个数不同,sizeof关键字可以用来计算一个存储区里包含的字节个数
  char和unsigned char 1个字节
  short和unsigned short 2个字节
  int和unsigned int 4个字节
  long和unsigned long 4个字节
  float 4个字节
  double 8个字节

sizeof关键字的小括号里可以写任何能当作数字使用的内容,sizeof关键字的小括号里对任何存储区内容的修改不会真正发生

/*
 * sizeof关键字演示
 * */
#include <stdio.h>
int main() {
    int num = 0;
    printf("sizeof(int)是%d\n", sizeof(int));
    printf("sizeof(num)是%d\n", sizeof(num));
    printf("sizeof(3 + 6)是%d\n", sizeof(3 + 6));
    sizeof(num = 10);
    printf("num是%d\n", num);
    return 0;
}

scanf标准函数可以把用户在键盘上输入的数字记录到存储区里,为了使用这个标准函数需要包含stdio.h头文件,scanf函数调用语句里应该使用存储区的地址表示存储区.需要在双引号里使用占位符表示存储区的类型,如果双引号里有不是占位符的内容用户就必须按顺序把它们输入,这样程序才能得到正确数字,如果用户输入的格式和程序要求的格式不一样就无法获得正确数字,可以在一条scanf函数调用语句里得到多个数字

/*
 * scanf标准函数演示
 * */
#include <stdio.h>
int main() {
    int num = 0, num1 = 0;
    printf("请输入两个整数:");
    scanf("%d%d", &num, &num1);
    printf("num是%d\n", num);
    printf("num1是%d\n", num1);
    return 0;
}

一个字节分为八段,每段可以记录一个0或者1,要想把一个数字记录到一个字节里必须首先把它拆分成八个0或者1,采用一组0或者1表示数字的方式叫二进制,任何数字既可以采用二进制方式表示也可以采用十进制方式表示.计算机里只能用二进制方式表示数字,二进制表示方式中每个数位有一个编号,最右边数位的编号是0,向左依次递增,某个数位里的1单独代表的数字就是2的数位编号次方.二进制表示方式中如果两个相邻数位的内容一样,则左边数位代表的数字是右边数位代表数字的2倍.用二进制表示的非负数符合以上规律,二进制加一的时候把最右边数位开始的连续多个1都变成0,把最右边的0变成1

/*
 * 二进制演示
 *
 * */
#include <stdio.h>
int main() {
    char ch = 300;
    int num = ch;
    printf("num是%d\n", num);
    ch = 128;
    num = ch;
    printf("num是%d\n", num);
    return 0;
}

二进制表示的非负数转换成十进制的时候只需要把内容是1的数位单独转换,然后把所有转换结果相加就可以了

  0000 0101 = 2的2次方 + 2的0次方
  = 4 + 1
  = 5

  0010 0100 = 2的5次方 + 2的2次方
  = 32 + 4
  = 36

十进制表示的非负数转换成二进制的方法
  12 *******0
  6 ******0
  3 *****1
  1 ****1
  0 ****

  转换结果是0000 1100

把十进制表示的非负数转换成二进制的时候先对数字不停做除以2并保留整数部分的操作就可以得到一组数字,用这组数字里的每一个除以2取余就得到一个数位的内容。把得到的所有数位内容按照从后向前的顺序倒着写就得到转换结果。

  91    1
  45    1
  22    0
  11    1
  5     1
  2     0
  1     1
  0     0

  转换结果是0101 1011

/*
 * 二进制练习
 * */
#include <stdio.h>
int main() {
    int num = 0;
    printf("请输入一个数字:");
    scanf("%d", &num);
    printf("        %d\r", num % 2);
    num = num / 2;
    printf("       %d\r", num % 2);
    num = num / 2;
    printf("      %d\r", num % 2);
    num = num / 2;
    printf("     %d\r", num % 2);
    num = num / 2;
    printf("   %d\r", num % 2);
    num = num / 2;
    printf("  %d\r", num % 2);
    num = num / 2;
    printf(" %d\r", num % 2);
    num = num / 2;
    printf("%d\n", num % 2);
    return 0;
}

负数的二进制和十进制之间不能直接转换,必须要借助相反的非负数

转换过程需要先计算相反数,然后把得到的结果进行转换,最后根据转换结果再计算相反数

把二进制数字每个数位的内容变成相反数然后再加一就得到相反数的二进制

  -14
  14
  0000 1110
  1111 0001 + 1 = 1111 0010 (-14的二进制)

有符号类型二进制最左边的数位叫做符号位,它可以用来判断数字的符号。符号位内容是0表示数字是非负数,符号位内容是1表示数字是负数。

  1100 0101
  0011 1010 + 1 = 0011 1011
  59
  -59

把二进制的所有数位从右向左每三个数位分成一组,每组用一个0到7之间的数字替换。替换以后的结果叫做数字的八进制表示方式。

  0110 1010 01 101 010 152(八进制)

可以在程序里直接使用八进制方式表示的数字,这种数字必须以0做开头,可以使用%o做占位符把数字的八进制表示方式显示在屏幕上

把二进制的所有数位从右向左每四个数位分成一组,每组用一个字符替换。(用a到f之间的字母替换10到15之间的数字)。替换以后的结果叫做数字的十六进制表示方式。

  1100 1011 cb(十六进制)

/*
 * 八进制和十六进制演示
 * */
#include <stdio.h>
int main() {
    printf("%d   0%o\n", 0152, 0152);
    printf("%d   0x%x   0X%X\n", 0xcb, 0xcb, 0xcb);
    return 0;
}

可以在程序里直接使用十六进制方式表示的数字,这种数字必须以0x做开头,可以使用%x或者%X做占位符把数字的十六进制表示方式显示在屏幕上,用%x做占位符的时候显示结果里所有字符都是小写的,用%X做占位符的时候显示结果里所有字符都是大写的显示结果里不包含0x开头