版本比较

标识

  • 该行被添加。
  • 该行被删除。
  • 格式已经改变。

基本数据类型

C语言的基本数据类型如下图所示:
Alt textImage Removed

基本数据类型是C语言提供的不可再分割的数据类型,有以下几类:

  • int 整型,表示整数
  • char字符型,表示单个字符,占1字节,可当作1字节整型来使用
  • float单精度浮点型
  • double双精度浮点型

在基本数据类型之上,C语言还提供了限定符,用于修饰基本数据类型,限制符包含以下分类:

  • 符号限定符,包括signedunsigned,表示有符号和无符号
  • 长度限定符,包括short, longlong long,用于修饰整数,表示短整数型,长整型和超长整型。long也可以修饰double,但这并不常用。


int与char统称为整型,都可以用于表示整数,区别是char只占1字节,而int一般占4字节。这里注意一点,C语言标准只规定了char占用一个字节,而未规定int占几个字节,具体的字节数由编译器与机器架构实现,比如在32位的机器上,int占4字节,但是在8位单片机上,int可能只占2字节。

char除了可以表示1字节的整数外,还可以表示单个字符,C语言中,字符用单引号表示,如'a','#'。字符的实际存储形式是字符对应的ASCII值,如'a'的ASCII值是97,那么,在程序中,所有出现'a'的地方都可以用数值97代替。int与char统称为整型,都可以用于表示整数,区别是char只占1字节,而int一般占4字节(注意!C语言标准只规定了char占用一个字节,而未规定int占几字节,具体的字节数由编译器与机器架构实现,在32位的机器上,int一般占4字节)。
char除了可以表示1字节的整数外,还可以表示字符,C语言中,字符用单引号表示,如’a’,‘#’。字符的实际存储形式是字符对应的ASCII值,如’a’的ASCII值是97,那么,在程序中,所有出现’a’的地方都可以用数值97代替。

在int与char类型的前面可以加上signed或unsigned限定数据的符号,表示数据的正负。signed与unsigned的区别在于数据的最高位,signed数据的最高位用0表示数据为正,用1表示数据为负,剩下的位数用于表示数据的数值大小,而unsigned数据则全部位都用于表示数值大小。所以,相同类型的数据,unsigned比signed所表示的数据范围要大。以char型数据为例,signed char表示的范围为 -128-127,unsigned char表示的范围为0-255。

short与long可以用于修饰int,用于获取不同长度的整型。在32位的Ubuntu14.04系统中,int一般占用4字节,而short占用2字节,long占用4字节,long long占用8字节。(注意!C语言同样未规定short与long的具体长度,C语言只规定了,short的长度不能大于int,long的长度不能小于int,具体的长度还是由编译器与机器架构实现。)04系统中,int占用4字节,而short占用2字节,long int占用4字节,long long int占用8字节。这里同样要注意,C语言标准并未规定short与long的具体长度,标准只规定了short的长度不能大于int,long的长度不能小于int,具体的长度还是由编译器与机器架构实现。

signed/unsigned可以和short/long一起使用,比如unsigned short表示无符号短整型。float与double统称实型,它们都可以用于表示浮点数。浮点数都是有符号数,不可以用限定符进行限定,像unsigned

float与double统称实型,它们都可以用于表示浮点数。浮点数都是有符号数,不可以用符号限定符进行修饰,像unsigned short float这样的写法是错误的。在32位的Ubuntu14.04系统中,float一般占用4字节,double一般占用8字节。长度不一样导致两者所能表示的数据范围和精度不一样,float型数据能得到6位有效数字,而double型数据能得到15位有效数字。此外,long可与double构成long 04系统中,float占用4字节,double占用8字节。长度不一样导致两者所能表示的数据范围和精度不一样,float型数据能得到6位有效数字,而double型数据能得到15位有效数字。此外,long可与double构成long double类型,表示高精度浮点型,经验证,long double类型的长度可以达到16字节!

格式化输入输出函数

标准C语言提供两个用于标准输入输出的函数printf和scanf。printf可以向标准输出(一般是屏幕)按指定格式输出内容。scanf可以从标准输入(一般是键盘)按指定格式接收数据。C语言标准库提供了两个用于从进行输入输出的函数printf和scanf。printf可以向标准输出(一般是屏幕终端)按指定格式输出内容。scanf可以从标准输入(一般是键盘)按指定格式接收数据。

格式化输出函数printf

printf

函数原型:

代码块
int printf(
格式化控制字符串,输出参数1,输出参数2,…
格式化控制字符串, 输出参数1, 输出参数2, ...);

返回值:
成功返回打印的字符个数,失败返回一个负数
举例:
printf(“%d add %d is %d\n”, 3, 1, 4);
输出:
3 add 1 is 4

格式控制字符

可以通过不同的格式控制字符来控制数据的输出格式,采用不同的格式控制字符,即使相同的数据,也可以有不同的输出形式,具体的格式控制格式如下:

  • %c:打印单个字符。
  • %d:打印有符号的十进制整数。
  • %u:打印无符号的十进制整数。
  • %x:打印无符号十六进制整数,使用0~f。
  • %X:打印无符号十六进制整数,使用0~F。
  • %o:打印无符号八进制整数。
  • %f :打印十进制浮点数。
  • 成功返回打印的字符个数,失败返回一个负数。

    格式控制字符

    使用printf、scanf的关键是格式控制字符,可以通过不同的格式控制字符来控制数据的输入输出,采用不同的格式控制字符,即使相同的数据,也可以有不同的输入输出形式,参考下表:

    格式控制字符描述
    %c单个字符
    %d有符号的十进制整数
    %u无符号的十进制整数
    %x无符号十六进制整数,使用0~f
    %X无符号十六进制整数,使用0~F
    %o无符号八进制整数
    %f十进制浮点数
    %e浮点数的指数形式,比如 1
    %e:打印浮点数。指数的形式1
    .23e+001
    %E:打印浮点数。1
    %E浮点数的指数形式,比如 1.23E+001
    %s字符串
    %s:打印字符串。

    长度与对齐控制

    输出长度与对齐方式控制

    可以在格式控制字符中指定长度与对齐方式,一般用于整数的输入输出。

    可以在格式化控制字符中限定字符的输出长度与对齐方式,以%X长度与对齐方式的设置形式是%x.Y□举例(□表示对应的格式化控制字符),X用于限定输出的长度,在该长度以内,默认按照右对齐,可以前面加上“-”表示左对齐,超出该长度时,该参数无效。Y用于限定浮点数的打印精度,默认是小数点后6位。举例说明:y,其中x用于限定输出长度,在该长度以内,默认按照右对齐,可以前面加上“-”表示左对齐,超出该长度时,该参数无效。y用于限定浮点数的打印精度,默认是小数点后6位。

    举例说明:

    代码块
    printf("%6d\n",123); //输出长度6位,右对齐

    
    printf("%6d\n",1234);

    
    printf("%6d\n",12345);

    
    printf("%6d\n",123456);

    输出:
    Alt textImage Removed
    
    printf("%6d\n",1234567);
    
    printf("%-6d\n",123); //
    输出长度为6位,左对齐
    输出长度6位,左对齐
    printf("%-6d\n",1234);

    
    printf("%-6d\n",12345);

    
    printf("%-6d\n",123456);

    输出:
    Alt textImage Removed
    
    printf("%-6d\n",1234567);

    效果:

    代码块
       123
      1234
     12345
    123456
    1234567
    123
    1234
    12345
    123456
    1234567


    浮点数:

    代码块
    printf("%f\n", 3.1415926);   //默认格式输出,小数点后6位

    
    printf("%.3f\n", 3.1415926); //小数点后保留3位

    
    printf("%.4f\n", 3.1415926); //小数点后保留4位

    
    printf("%.5f\n", 3.1415926); //小数点后保留5位

    
    printf("%6.2f\n", 3.1415);   //小数点后保留两位,宽度为6字节,右对齐

    
    printf("%7.2f\n", 3.1415);   //小数点后保留两位,宽度为7字节,右对齐

    效果:输出:
    Alt textImage Removed

    使用限定符

    对于使用unsigned或long修饰的类型,打印时还需要加上对应的限定符描述,否则打印的结果也是不对的,规则列表如下 :
    Alt textImage Removed

    格式化输入函数scanf

    函数原型:
    int scanf(格式控制字符串,输入参数1,输入参数2,…);
    返回值:
    成功返回读取的参数个数,失败返回EOF
    举例:
    scanf(“%d %c”, &a, &c);
    关于使用scanf有以下注意点:

    1. 格式控制字符用于说明输入数据的类型,与printf的控制格式字符遵循一样的对应关系。
    2. 输入参数是地址
    3. 格式控制字符串中的非占位符也要按原样进行输入,比如“%d,%d”,那么在输入的时候,两个数之间要以逗号间隔。
    4. 在输入数据时,如输入空间、回车、tab键或者遇到非法字符时,则认为输入数据结束。
    5. scanf函数返回成功输入的数据个数。

    运算符与表达式

    运算符是可以对数据进行运算的符号,比如sizeof以及+ - * / %等符号。
    运算符操作的对象称为操作数,运算符与操作数组合成表达式。表达式结尾没有分号,如果在表达式两边加上一个括号,那么表达式最终可以得到一个值,这是表达式与语句的区别。
    Alt textImage Removed

    使用运算符与表达式的时候,以下几点要注意:

    • 操作数个数
    • 具有一个操作数的被称之一元运算符,两个操作数的称为二元运算符,三个操作数的称为三元运算符。对于二元运算符,位于运算符左侧的称为左值,位于运算符右侧的称为右值。
    • 操作数类型
    • 运算结果的类型
    • 运算符优先级
    • 结合方向

    C语言中的运算符定义很宽,除数值运算符外,取地址,解地址,赋值(=)等都可以看成运算符,以下是C语言中运算符的总结:

    • 算术运算符:
      • 五则运算:+ - * / %
      • 取反运算符:-
      • 自增与自减运算符:++ –
    • 关系运算符:
      • 大于、大于等于:> >=
      • 小于、小于等于:< <=
      • 等于: ==
      • 不等于: !=
    • 逻辑运算符:
      • 逻辑与: &&
      • 逻辑或: ||
      • 逻辑非: !
    • 赋值运算符:=及其扩展赋值运算符
    • 条件运算符:? :
    • 指针运算符:
      • 取地址:&
      • 解地址:*
    • 求字节运算符:sizeof
    • 位运算符:
      • 左移:<<
      • 右移:>>
      • 按位与:&
      • 按位或:|
      • 按位取反:~
      • 按位异或:^
    • 成员运算符:.
    • 下标运算符:[]
    • 逗号运算符: ,

    运算符优先级表

    表格来自《C语言深度解剖(第2版)》
    Alt textImage Removed
    Alt textImage Removed

    注:同一优先级的运算符,运算次序由结合方向所决定。解决优先级与运算方向困惑的最好办法是使用括号,推荐多使用括号。

    赋值 < 逻辑 < 相等 < 关系 < 算术运算 < 一元运算

    算术运算符

    包括:

    1. 五则运算:+ - * / %
    2. 取反运算符:-
    3. 自增与自减运算符:++ –

    注意点:

      • / %具有同一优先级,+ - 具有同一优先级,前者优先级高于后者,同一优先级下,运算顺序从左向右。
    1. %(取模运算)的操作数不可以是浮点数
    2. 自增自减运算符只能用于变量,不能用于常量和表达式,类似5--,(a+b)++的写法都是不对的。
    3. 自增自减运算符作前缀与后缀时是有区别的:
      1. c = a+; ==> c = a; a+;
      2. c = +a; ==> a+; c = a;

    关系运算符

    包括:

    1. 大于、大于等于:> >=
    2. 小于、小于等于:< <=
    3. 等于: ==
    4. 不等于: !=

    注意点:

    1. 只可以对标量类型进行关系运算。(标量类型包括算术类型与指针,与之对应的是聚合类型,包括数组与结构体)
    2. 关系运算的结果是真或假。C语言中,假用数值0来表示,真则可以用任何非0的值来表示,特殊地,对于关系运算,真用1来表示,既关系运算的结果只能是0或1。

    逻辑运算符

    注意点:

    1. 赋值用 ‘=’ 号表示,判断相等用 ’==’ 表示,注意区分两者。
    2. 赋值运算的结果是右值,即 (a = 3) 的结果是3。
    3. 赋值运算的结合方向是从右向左,类似 a = b = c = 3 的计算方式是 a = (b = (c = 3))。

    逗号运算符

    C语言中,逗号也是运算符的一种,类似下面这样的表达式是允许的:
    (3, 4)
    (a > 0, a = 1)
    (printf(“hello”), 1, 3)
    逗号运算是C语言中优先级最低的运算符,所有表达式从左往右依次计算,逗号运算的结果是最后一个表达式的值。

    选择运算符

    表达式1?表达2:表达3
    a > b? a: b

    分支语句

    if语句

    Alt textImage Removed

    使用if语句的注意事项:

    1. if语句的判断条件,只要计算出来的结果是非0,那么条件就成立。计算的方式可以是函数调用或是任何运算符所构成的表达式,以下方式都是合理的:
    2. if(( 3, 4)) if( a = 3) if(printf(“hello”)) if(&a)
    3. 在写注意判断条件中赋值与相等的区别,赋值是“=”,相等是"=="。 谨慎的做法是,在相等判断的时候,把常量写在前面,形如“3 == a”,这样,即使错写成“3 = a”,编译器也能检查出错误,避免程序出现逻辑错误。
    4. if与else的配对原则:从最内层开始,else总是与它上面最接近的、未曾配对的if匹配。
    5. 避免if与else配对错位的最佳方法是使用括号和缩进,良好的编程网络是即使if或者else的语句只有一条,也要另起一行加上括号和缩进。

    switch语句

    代码块
    languagec++
    themeConfluence
    linenumbersfalse
    collapsefalse
    switch(表达式1)
    {
    case 常量表达式1:
         语句1;
         break;
    case 常量表达式2:
         语句2;
         break;
     ......
    case 常量表达式n:
         语句n;
         break;
    default:
         语句n+1;
         break;
    }
    

    使用switch语句的注意事项:

    1. switch后面的表达式计算结果必须为int型或char型,浮点型与地址类型及其他构造类型都是不合法的。
    2. case后面必须为可以精确进行比较的int型或char型常量或常量表达式,使用变量表达式是不合法的。
    3. case后面的常量表达式必须的互不相同,否则编译无法通过。
    4. 每个case的结尾绝对不要忘了加break,否则将导致多个分支重叠(除非有意使多个分支重叠)。
    5. case与default的出现顺序不影响执行结果。
    6. 必须使用default分支,即便程序不需要default,也应该保留default语句并加上break。保留的目标是让程序来解释,编程者已经考虑到了default情况并认为可以不加处理,从而避免让人误以为你忘了default处理。

    if语句与switch语句的比较

    理论上,使用switch的语句都可以用if语句来改写,但是,在纯粹进行数字或字符比较且比较的分支较多时,使用switch语句的代码逻辑性和可读性都要优于if语句,自行体会。

    流程图

    除了用程序直接来表现程序流程之外,我们还可以用流程图的形式来表现程序的流程,常用的流程表示有以下这么几种。
    Alt textImage Removed

    使用流程图表示求一个数的绝对值的过程:
    Alt textImage Removed

    代码块
    3.141593
    3.142
    3.1416
    3.14159
      3.14
       3.14

    类型限定符

    对于使用unsigned或long修饰的类型,打印时还需要加上对应的类型限定符,否则打印的结果也是不对的,规则列表如下 :

    数据类型格式控制字符
    char/short/int%d
    long int

    %ld

    long long int%lld
    unsigned char/short/int%u
    unsigned long int%lu
    unsigned long long int%llu
    float/double%f或%lf
    long double%Lf

    scanf

    函数原型:

    代码块
    int scanf(格式控制字符串, 输入参数1, 输入参数2, ...);

    返回值:

    成功返回读取的参数个数,失败返回EOF。


    示例:

    代码块
    #include<stdio.h>
    int main(void) 
    { 
        int a,b,c; 
     
        printf("请输入三个数字:");
        scanf("%d%d%d",&a,&b,&c); 
        printf("%d,%d,%d\n",a,b,c);
    }

    关于使用scanf有以下注意点:

    1. 格式控制字符用于说明输入数据的类型,与printf的控制格式字符遵循一样的对应关系。
    2. 输入参数是地址
    3. 格式控制字符串中的非占位符也要按原样进行输入,比如“%d,%d”,那么在输入的时候,两个数之间要以逗号间隔。
    4. 在输入数据时,如输入空间、回车、tab键或者遇到非法字符时,则认为输入数据结束。
    5. scanf函数返回成功输入的数据个数。

    另外,scanf还支持在格式控制字符串中加入正则表达式,这算是scanf的高级用法,参考:sscanf 和正则表达式 | 不积小流,无以成江海

    转义字符

    用于表示无法输入的字符或不可见的字符,比如换行符,制表符,也用于表示一些在C语言中有特殊作用的字符,比如单引号和双引号。

    形式:“\”后面跟一个字符或数字。

    Image Added使用流程表图表示求1+2+3+…+100:
    Alt textImage Removed


    目录