二、数据类型:变量、常量;整型、浮点型;格式输入输出符;转义字符'\';sizeof;进制与转换;原码反码补码;数值溢出;类型限定符:extern、const、Volatile、


标识符;声明和定义区别;常量;变量;使用示例
========================================================================================================
标识符:
    变量和常量的统称。
    命名规则:    
        1. 通常常量使用大写、变量使用小写。大小写严格区分。
        
        2. 只能使用字母、数组、下划线(_)命名标识符。且,数字不能开头。 a-z/A-Z/0-9/_
            int a5ir = 10; 
            int _34F = 6; 
            float s2_i85c = 5.4f;  
            int 98ti_54 = 4;  //error.
            
        3. 禁止使用关键字和系统函数作为标识符名称。  main/system/printf/sleep....

-----------------------------------------------------------------------------------
声明和定义区别
    声明变量不需要建立存储空间,如:extern int a;
    定义变量需要建立存储空间,如:int b;

-----------------------------------------------------------------------------------
常量:不会变化的数据。不能被修改。
    1. “hello”、'A'、-103.1415926(浮点常量)    
    2. #define PI 3.1415    【强调】:没有分号结束标记。 【推荐】 定义宏: 定义语法: #define 宏名 宏值
    3. const int a = 10;    定义语法:const 类型名 变量名 = 变量值。
        const关键字: 被该关键字修饰的变量,表示为只读变量。

-----------------------------------------------------------------------------------
变量:会变化的数据。能被修改。(变量在使用前必须先定义,定义变量前必须有相应的数据类型)

    定义语法:类型名 变量名 = 变量值。(一般方法)
        变量三要素:类型名、变量名、变量值。    int r = 3;    float s = PI*r*r;(变量值是一个表达式)
        
    变量的定义:int a = 40;
    变量的声明:1) int a;     没有变量值的变量定义 叫做声明;2extern int a; 添加了关键字 extern1. 变量定义会开辟内存空间。变量声明不会开辟内存空间。
    2. 变量要想使用必须有定义。
        当编译器编译程序时,在变量使用之前,必须要看到变量定义。如果没有看到变量定义,编译器会自动找寻一个变量声明提升成为定义。
        如果该变量的声明前有 extern 关键字,无法提升。

    【建议】:定义变量时。尽量不要重名。
    //注意:变量的定义和声明是不一样的,只声明变量而不定义变量,是无法使用这个变量的!
    //平时使用“int a;”这种形式,实际上隐式地进行了变量提升,提升为定义。


-----------------------------------------------------------------------------------
示例:变量、常量的定义与使用.c
#include 

#define PI 3.141592654      //定义常量

int main() {
    const float a = 3.14f;
    float r ;                       //声明变量
    r = 5.5 ;                       //隐式地将变量声明提升为变量定义
    float s = PI * r * r;
    float l = PI * r * 2;

    printf("圆面积为%f\n",s);   //圆面积为95.033180
    printf("圆周长为%f\n",l);   //圆周长为34.557518
    printf("圆面积为%.3f\n",s); //圆面积为95.033
    printf("圆周长为%.3f\n",l); //圆周长为34.558
    return 0;
}
标识符;声明和定义区别;常量;变量;使用示例
整型(有符号整型与无符号整型);字符变量
=============================================================================
有符号数是最高位为符号位,0代表正数,1代表负数。
无符号数最高位不是符号位,而就是数的一部分,无符号数不可能是负数。

数据类型                占用空间
short(短整型)            2字节
int(整型)                4字节
long(长整形)            Windows为4字节,Linux为4字节(32位),8字节(64位)
long long(长长整形)        8字节
signed int        #数据默认为有符号整型,signed可以省略
unsigned int
unsigned short
unsigned long
unsigned long long


char 类型:1字节 8个bit位。 数值位有7个。
        不要超出该数据类型的存储范围。
    有符号取值范围: -128 ~ 127
    无符号取值范围:  0~255

short类型:2字节  16bit
    有符号:  -32768 ~ 32767
    无符号:  0~65535        

int 类型:4字节            -2^(32-1) -- 2^(32-1)-1
    有符号:-2147483648 ~ 2147483647    
    无符号: 0~4294967295

long类型:4字节
    有符号:-2147483648 ~ 2147483647    
    无符号:0~4294967295    

longlong 类型:8字节
    有符号: -2^(63) ~ 2^(63)-1    
    无符号: 0~2^63-1
        
--------------------------------------------------------------------------------------
字符变量 char字符类型:1字节
    字符变量实际上并不是把该字符本身放到变量的内存单元中去,而是将该字符对应的 ASCII 编码放到变量的存储单元中。char的本质就是一个1字节大小的整型。
    存储一个字符。本质是ASCII码。 ‘A’、‘a’、‘%’、‘#’、‘0’
    格式匹配符: %c
    ‘A’:65
    ‘a’:970’:48
    ‘\n’:10
    ‘\0’: 0

#include 

int main()
{
    char ch = 'a';
    printf("sizeof(ch) = %u\n", sizeof(ch));    //字符占用1字节

    printf("打印字符 %c\n", ch); //打印字符
    printf("'a'的ASCII码:%d\n", 'a'); //打印‘a’ ASCII的值 97
    printf("'A'的ASCII码:%d\n", 'A'); //打印‘A’ ASCII的值 65

    printf("A = %c\n", 'a' - 32); //小写a转大写A
    printf("a = %c\n", 'A' + 32); //大写A转小写a

    ch = ' ';
    printf("空字符:%d\n", ch); //空字符ASCII的值为32
    printf("A = %c\n", 'a' - ' '); //小写a转大写A
    printf("a = %c\n", 'A' + ' '); //大写A转小写a
    
    return 0;
}
整型(有符号整型与无符号整型)int、long等;字符变量char
浮点型变量(实型变量);使用示例
==================================================================================================
浮点型变量(实型变量)
    浮点型变量是用来存储小数数值的。在C语言中, 浮点型变量分为两种: 单精度浮点数(float)、 双精度浮点数(double), 但是double型变量所表示的浮点数比 float 型变量更精确。
        由于浮点型变量是由有限的存储单元组成的,因此只能提供有限的有效数字。在有效位以外的数字将被舍去,这样可能会产生一些误差。
    注意:不以f结尾的常量是double类型,以f结尾的常量(如3.14f)是float类型。

    float:    单精度浮点型。        4字节
        float v1 = 4.345;
        %f格式匹配符。 默认保留 6 位小数。

    double:双精度浮点型。        8字节        【默认】
        double v2 = 5.678;

    unsigned float v1 = 4.345;    无符号的 float 数据
    unsigned double v2 = 5.678;    无符号的 float 数据

    printf("n = %08.3f\n", n);
        输出的含义为:显示8位数(包含小数点), 不足8位用0填充。并且保留3位小数。对第4位做四舍五入。

--------------------------------------------------------------------------------------------
#include 

int main()
{
    //传统方式赋值
    float a = 3.14f; //或3.14F
    double b = 3.14;

    printf("a = %f\n", a);  //a = 3.140000
    printf("a = %.3f\n", a);    //a = 3.140
    printf("a = %6.3f\n", a);   //a =  3.140    #注意:6表示输出的总字符数,这里隐含了一个空格
    printf("a = %06.3f\n", a);   //a = 03.140    #注意:6表示输出的总字符数,不足6位用0进行补位
    printf("b = %lf\n", b); //

    //科学法赋值
    a = 3.2e3f; //3.2*1000 = 3200,e可以写E
    printf("a1 = %f\n", a);

    a = 100e-3f; //100*0.001 = 0.1
    printf("a2 = %f\n", a);

    a = 3.1415926f;
    printf("a3 = %f\n", a); //结果为3.141593

    return 0;
}
浮点型变量(实型变量);使用示例
格式输入输出符
===========================================================================================
打印格式    含义
%d    输出一个有符号的10进制int类型
%o    输出8进制的int类型
%x    输出16进制的int类型,字母以小写输出
%X    输出16进制的int类型,字母以大写输出
%u    输出一个10进制的无符号数

打印格式    含义
%hd        输出short类型
%d        输出int类型
%ld        输出long类型
%lld    输出long long类型
%hu        输出unsigned short类型
%u        输出unsigned int类型
%lu        输出unsigned long类型
%llu    输出unsigned long long类型

--------------------------------------------------------------------------------------------
#include 

int main()
{
    int a = 123;    //定义变量a,以10进制方式赋值为123
    int b = 0567;    //定义变量b,以8进制方式赋值为0567
    int c = 0xabc;    //定义变量c,以16进制方式赋值为0xabc

    printf("a = %d\n", a);
    printf("8进制:b = %o\n", b);
    printf("10进制:b = %d\n", b);
    printf("16进制:c = %x\n", c);     //16进制:c = abc
    printf("16进制:c = %X\n", c);     //16进制:c = ABC
    printf("10进制:c = %d\n", c);     //10进制:c = 2748;支持定义时使用十六进制,使用时用十进制

    unsigned int d = 0xffffffff; //定义无符号int变量d,以16进制方式赋值
    //有符号数是最高位为符号位,0代表正数,1代表负数。
    printf("有符号方式打印:d = %d\n", 0xffffffff);  //有符号方式打印:d = -1;
    //因为计算机存储是按照补码来存储的! 补码为正数取反,然后+1;那么这里要显示为十进制的话,就需要-1,然后再取反,所以此处显示为-1
    printf("有符号方式打印:d = %d\n", 0xfffffffe);  //有符号方式打印:d = -2
    printf("有符号方式打印:d = %d\n", 0xfffffffd);  //有符号方式打印:d = -3
    printf("有符号方式打印:d = %d\n", 0xfffffffc);  //有符号方式打印:d = -4
    printf("无符号方式打印:d = %d\n", d);  //有符号方式打印:d = -1
    printf("无符号方式打印:d = %u\n", d);  //无符号方式打印:d = 4294967295
    return 0;
}
格式输入输出符
转义字符'\';转义字符使用示例
=============================================================================================
转义字符    含义                                    ASCII码值(十进制)
\a            警报                                    007
\b            退格(BS) ,将当前位置移到前一列            008
\f            换页(FF),将当前位置移到下页开头        012
\n            换行(LF) ,将当前位置移到下一行开头        010
\r            回车(CR) ,将当前位置移到本行开头        013
\t            水平制表(HT) (跳到下一个TAB位置)        009
\v            垂直制表(VT)                            011
\\            代表一个反斜线字符"\"                    092
\'            代表一个单引号(撇号)字符                039
\"            代表一个双引号字符                        034
\?            代表一个问号                            063
\0            数字0                                    000
\ddd        8进制转义字符,d范围0~7    3位8进制
\xhh        16进制转义字符,h范围0~9,a~f,A~F    3位16进制

-----------------------------------------------------------------------------------------------
#include 

int main()
{
    printf("abc");
    printf("\refg\n"); //\r切换到句首, \n为换行键

    printf("abc");
    printf("\befg\n");//\b为退格键, \n为换行键

    printf("%d\n", '\123');// '\123'为8进制转义字符,0123对应10进制数为83
    printf("%d\n", '\x23');// '\x23'为16进制转义字符,0x23对应10进制数为35

    return 0;
}
转义字符'\';转义字符使用示例
sizeof关键字及示例
===================================================================================================
sizeof关键字:
    sizeof不是函数,所以不需要包含任何头文件,它的功能是计算一个数据类型的大小,单位为字节
    sizeof的返回值为size_t(其实是unsigned __int64的别名,所以使用 %u 接收返回值)
    size_t类型在32位操作系统下是unsigned int,是一个无符号的整数
        方法1: sizeof(类型名)    -- sizeof(int)
        方法2: sizeof(变量名)        --- int a = 20sizeof(a)

    【其他用法】: sizeof 变量名/类型名        
        举例1: sizeof int
        举例2: sizeof a

#include 

int main()
{
    int a;
    int b = sizeof(a);                                          //sizeof得到指定值占用内存的大小,单位:字节
    printf("int类型占用空间:%d字节\n", sizeof(int));       //int类型占用空间:4字节
    printf("int类型变量占用空间:%d字节\n", sizeof(a));    //int类型变量占用空间:4字节

    size_t c = sizeof(a);                                           //sizeof的返回值为size_t
    printf("size_t类型占用空间:%u字节\n", sizeof(size_t));      //size_t类型占用空间:8字节
    printf("size_t类型变量占用空间:%u字节\n", sizeof(a));      //size_t类型变量占用空间:4字节
    printf("size_t类型变量占用空间:%u字节\n", c);             //size_t类型变量占用空间:4字节

    return 0;
}
sizeof关键字及示例
进制(2进制、8进制、10进制、16进制);进制转换;原码、反码、补码;数值溢出
===================================================================
十进制        以正常数字1-9开头,如123
八进制        以数字0开头,如0123
十六进制    以0x开头,如0x123
二进制        C语言不能直接书写二进制数


当前的计算机系统使用的基本上是二进制系统,数据在计算机中主要是以补码的形式存储的。

-----------------------------------------------------------------------------------------------
进制和转换:
    十进制转2进制。    --- 除2反向取余法。 【重点】
    十进制转8进制。    --- 除8反向取余法。
    十进制转16进制。--- 除16反向取余法。
    2进制转10进制。

8进制:
    8进制转2进制。
        按421码将每个八进制位展开。

    2进制转8进制:
    
16进制:
    语法: 以0x开头,每位 取 0-9/A-F/a-f


总结:
    int m = 0x15F4;
    int n = 345;
    int var = 010011; // 不允许。 不能给变量直接复制 二进制数据。
    编程时,可以直接赋值十进制、八进制、十六进制;但是不能直接赋值二进制!!!
    输出格式:
        %d %u %o %x %hd %hu %ld %lu %lld %llu %c %f %lf
        常用:%d %u %x %c %s 


#include 

int main()
{
    int a = 123;        //十进制方式赋值
    int b = 0123;        //八进制方式赋值, 以数字0开头
    int c = 0xABC;    //十六进制方式赋值

    //如果在printf中输出一个十进制数那么用%d,八进制用%o,十六进制是%x
    printf("十进制:%d\n",a );      //十进制:123
    printf("八进制:%o\n", a);          //八进制:173     //%o,为字母o,不是数字
    printf("十六进制:%x\n", a);     //十六进制:7b

    printf("十进制:%d\n",b );      //十进制:83
    printf("八进制:%o\n", b);            //八进制:123   //%o,为字母o,不是数字
    printf("十六进制:%x\n", b);     //十六进制:53

    printf("十进制:%d\n",c );      //十进制:2748
    printf("八进制:%o\n", c);            //八进制:5274   //%o,为字母o,不是数字
    printf("十六进制:%x\n", c);     //十六进制:abc
    return 0;
}


------------------------------------------------------------------------------------------------
源码反码补码:

    原码(原始的二进制码):
        43 ->     00101011
        -43 --> 10101011
    反码(通常用来作为求补码的中间过渡):        
        43 ->     00101011
        -43 --> 11010100    #负数在储存时,数值位取反
                
    
    补码:(在计算机系统中,数值一律用补码来存储。)
        43 ->     00101011    : 正数不变
        -43 --> 11010101    : 负数,最高位表符号位, 其余取反+1
    
    人为规定: 10000000 --》 -128


补码特点:
?    对于正数,原码、反码、补码相同
?    对于负数,其补码为它的反码加1
?    补码符号位不动,其他位求反,最后整个数加1,得到原码


在计算机系统中,数值一律用补码来存储,主要原因是:
?    统一了零的编码
?    将符号位和其它位统一处理
?    将减法运算转变为加法运算
?    两个用补码表示的数相加时,如果最高位(符号位)有进位,则进位被舍弃



------------------------------------------------------------------------------------------------
数值溢出
    当超过一个数据类型能够存放最大的范围时,数值会溢出。
    有符号位最高位溢出的区别:符号位溢出会导致数的正负发生改变,但最高位的溢出会导致最高位丢失。
#include 

int main()
{
    char ch;

    //符号位溢出会导致数的正负发生改变
    ch = 0x7f + 2; //127+2
    printf("%d\n", ch);
    //    0111 1111
    //+2后 1000 0001,这是负数补码,其原码为 1111 1111,结果为-127

    //最高位的溢出会导致最高位丢失
    unsigned char ch2;
    ch2 = 0xff+1; //255+1
    printf("%u\n", ch2);
    //      1111 1111
    //+1后 10000 0000, char只有8位最高位的溢出,结果为0000 0000,十进制为0

    ch2 = 0xff + 2; //255+1
    printf("%u\n", ch2);
    //      1111 1111
    //+1后 10000 0001, char只有8位最高位的溢出,结果为0000 0001,十进制为1

    return 0;
}

进制(2进制、8进制、10进制、16进制);进制转换;原码、反码、补码;数值溢出
进制(2进制、8进制、10进制、16进制);进制转换;原码、反码、补码;数值溢出
类型限定符:externconst、Volatile、register;字符串常量
======================================================================================
类型限定符                    含义
extern    声明一个变量,extern声明的变量没有建立存储空间。
    extern int a;//变量在定义的时候创建存储空间
        
const    定义一个常量,常量的值不能修改。
    const int a = 10;
    
Volatile    防止编译器优化代码
    volatile int flg = 0; 
    
register    定义寄存器变量,提高效率。register是建议型的指令,而不是命令型的指令,如果CPU有空闲寄存器,那么register就生效,如果没有空闲寄存器,那么register无效。
    register int a = 10;    

--------------------------------------------------------------------------------------
字符串常量:
    C语言中,字符串是用双引号引着的一串字符,字符串是内存中一段连续的char空间,以'\0'(数字0)结尾。
    char ch = ‘A’;  一个字节
    "abc"  --> 'a''b''c''\0'
    ‘a’ 不等价 “a”('a''\0'
类型限定符:extern、const、Volatile、register;字符串常量
printf;putchar;scanf;getchar
==================================================================================
printf是输出一个字符串,putchar输出一个char。
putchar函数:
    常用putchar('\n');来打印换行。
    printf("\n");
    
打印格式    对应数据类型            含义
%s            char *                 字符串。输出字符串中的字符直至字符串中的空字符(字符串以'\0‘结尾,这个'\0'即空字符)
%d            int                    接受整数值并将它表示为有符号的十进制整数
%c            char                字符型。可以把输入的数字按照ASCII码相应转换为对应的字符
%x,%X        unsigned int        无符号16进制整数,x对应的是abcdef,X对应的是ABCDEF
%%            %                    输出一个百分号
%hd            short int            短整数
%hu            unsigned short         无符号短整数
%o            unsigned int        无符号8进制整数
%u            unsigned int        无符号10进制整数
%f            float                单精度浮点数
%lf            double                双精度浮点数
%e,%E        double                科学计数法表示的数,此处"e"的大小写代表在输出时用的"e"的大小写
%p            void *                以16进制形式输出指针

%Ns:    显示N个字符的字符串。不足N用空格向左填充。
%0Ns:   显示N个字符的字符串。不足N用0向左填充。
%-Ns:   显示N个字符的字符串。不足N用空格向右填充。

printf附加格式:
字符                含义
l(字母l)            附加在d,u,x,o前面,表示长整数
-                    左对齐
m(代表一个整数)        数据最小宽度
0(数字0)            将输出的前面补上0直到占满指定列宽为止不可以搭配使用-
m.n(代表一个整数)    m指域宽,即对应的输出项在输出设备上所占的字符数。n指精度,用于说明输出的实型数的小数位数。对数值型的来说,未指定n时,隐含的精度为n=6位。

---------------------------------------------------------------------------------------------
scanf函数:
    scanf通过%转义的方式可以得到用户通过标准输入设备输入的数据。
    从键盘接收用户输入。
    1. 接收 整数 %d
        int a, b, c;  创建变量空间, 等待接收用户输入。
        scanf("%d %d %d", &a, &b, &c);

    2. 接收 字符 %c
        char a, b, c;
        scanf("%c %c %c", &a, &b, &c);
    
    3. 接收 字符串 %s
        char str[10];    // 定义一个数组,用来接收用户输入的 字符串。
        scanf("%s", str);    // 变量名要取地址传递给 scanf, 数组名本身表示地址,不用 & 符。

    接收字符串:
        1) scanf 具有安全隐患。如果存储空间不足,数据能存储到内存中,但不被保护。【空间不足不要使用】
        2) scanf 函数接收字符串时, 碰到 空格 和 换行 会自动终止。不能使用 scanf 的 %s 接收带有空格的字符串。
                scanf函数不能接受有空格,制表符,换行符等空白字符的出现
                
    将 #define _CRT_SECURE_NO_WARNINGS  添加到程序 第一行。 解决scanf 4996错误


getchar()函数:
    从键盘获取用户输入的 一个字符。
    返回该获取的字符的 ASCII 码。

----------------------------------------------------------------------------------------------------
#include 
#include 
#define _CRT_SECURE_NO_WARNINGS

int main() 
{
    int a = 100;
    printf("a = %d\n", a);        //格式化输出一个字符串   a = 100
    printf("%p\n", &a);            //输出变量a在内存中的地址编号   00000056FBEFFA24
    printf("%%d\n");            //%d

    char c = 'a';
    putchar(c);                    //putchar只有一个参数,就是要输出的char ‘a’
    long a2 = 100;
    printf("%ld, %lx, %lo\n", a2, a2, a2);        //100, 64, 144

    long long a3 = 1000;
    printf("%lld, %llx, %llo\n", a3, a3, a3);    //1000, 3e8, 1750

    int abc = 10;
    printf("abc = '%6d'\n", abc);    //abc = '    10'
    printf("abc = '%-6d'\n", abc);    //abc = '10    '
    printf("abc = '%06d'\n", abc);    //abc = '000010'
    printf("abc = '%-06d'\n", abc);    //abc = '10    '

    double d = 12.3;
    printf("d = \' %-10.3lf \'\n", d);        //d = ' 12.300     '

    //-------------------------------------------------
    char ch1;
    char ch2;
    char ch3;
    int aa;
    int bb;

    printf("请输入ch1的字符:");
    ch1 = getchar();
    printf("ch1 = %c\n", ch1);

    getchar(); //测试此处getchar()的作用

    printf("请输入ch2的字符:");
    ch2 = getchar();
    printf("\'ch2 = %ctest\'\n", ch2);

    getchar(); //测试此处getchar()的作用
    printf("请输入ch3的字符:");
    scanf("%c", &ch3);//这里第二个参数一定是变量的地址,而不是变量名
    printf("ch3 = %c\n", ch3);

    printf("请输入a的值:");
    scanf("%d", &aa);
    printf("a = %d\n", aa);

    printf("请输入b的值:");
    scanf("%d", &bb);
    printf("b = %d\n", bb);

    return EXIT_SUCCESS;
}
printf;putchar;scanf;getchar