C 语言基本语法

前言

  • C 语言是一种通用的高级语言,最初是由丹尼斯·里奇在贝尔实验室为开发 UNIX 操作系统而设计的。C 语言最开始是于 1972 年在 DEC PDP-11 计算机上被首次实现。

  • 在 1978 年,布莱恩·柯林汉(Brian Kernighan)和丹尼斯·里奇(Dennis Ritchie)制作了 C 的第一个公开可用的描述,现在被称为 K&R 标准。

  • UNIX 操作系统,C编译器,和几乎所有的 UNIX 应用程序都是用 C 语言编写的。由于各种原因,C 语言现在已经成为一种广泛使用的专业语言。

  • C 教程

1、数据类型

  

2、常量

  • 1)凡是整数数字常量一律是 int 型。

  • 2)typedef 和 define。

    1
    2
    typedef 定义类型,
    #define 只是字符串替换。
  • 3)在编写整形常量时,可以在常量的后面加上符号 L 或者 U 进行修饰。L 表示该常量是长整形,U 表示该常量为无符号整形,字母可以使用大写,也可以使用小写。

    1
    2
    LongNum = 1000L;                   // L 表示长整形
    UnsignLongNum = 500U; // U 表示无符号整形
    • 在编写实型常量时,可以在常量的后面加上符号 F 或者 L 进行修饰。F 表示该常量是 float 单精度类型,L 表示该常量为 long double 长双精度类型。如果不在后面加上后缀,那么默认情况下,实型常数为 double 双精度类型。例如:

      1
      2
      3
      FloatNum = 1.2345e2F;              // 单精度类型
      LongDoubleNum = 5.458e-1L; // 长双精度类型
      DoubleNum = 1.2345E2; // 双精度类型

3、变量

  • 1)局部变量定义后,如果没有初始化,其值不一定为 0, 全局变量定义后会自动初始化为 0。

  • 2)char 是整型变量,可以存储数字,而且有 unsigned char。

  • 3)变量类型:

    • 自动变量:auto(可省略)修饰的局部变量。
    • 静态变量:全局变量和被 static 修饰的局部变量。
    • 寄存器变量:regiester 修饰的存储在寄存器中的自动变量。
  • 4)变量存储类别:

    • 自动存储:auto ——> 栈 动态存储变量 auto 是可以省略的,如果不特别指定,局部变量的存储方式默认为自动的(auto)。
    • 静态存储:static ——> 数据段 静态存储变量初始化操作时只在第一次执行时起作用。在随后的运行中变量将保持上一次执行时的值。包含全局变量和被 static 修饰的局部变量。
    • 寄存器存储:register ——> 寄存器 存储在寄存器中。
    • 外部声明:extern 只是声明变量,没有开辟存储空间。

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      const 不可变的。

      星前 const,p 可以改变,*p 不可以改变。
      const char *p = &a;
      char const *p = &a;

      星后 const,p 不可以改变,*p 可以改变。
      char * const p = &a;

      volatile 易变的,编译器优化。

      extern 只能用来声明外部变量(可省略)(全局变量),不能用来定义外部变量。
      static 用来定义内部变量(全局变量)。
  • 5)变量类型转换:char, short —> int —> unsigned —> long —> double <— float

4、字符串

  • 1)字符串变量在内存中反向排列,先存储后定义的变量。

  • 2)字符串

    1
    2
    char s[3] = “jhq”,定义的是字符串变量
    char *s = “jhq”, 定义的是字符串常量
  • 3)字符串函数

    1
    2
    3
    4
    5
    6
    7
    8
    strlen(),字符串中字符的长度计算。 strlen(const char *)
    strcpy(),字符串复制。 strcpy(char *, const char *)
    strcat(),字符串连接。 strcat(char *, const char *)
    strcmp(),字符串比较。 strcmp(const char *, const char *)
    strlwr(),将字符串中大写字母转换成小写字母
    strupr(),将字符串中小写字母转换成大些字母
    strstr(),字符串查找
    strtok(),字符串分割
  • 4)字符 输入/输出:

    • 1>、int getchar();

      • C 标准 I/O 函数中最简单的输入函数。每次只能接收一个字符,可接收转义字符,得到的字符可以赋给整型或字符型变量。

      • 如:cChar = getchar();

    • 2>、int putchar(int ch);

      • C 标准 I/O 函数中最简单的输出函数。每次只能输出一个字符,可输出转义字符。

      • 如:putchar(cChar);

  • 5)字符串 输入/输出:

    • 1>、char *gets(char *str);

      • 将读取的字符串保存到形式参数 str 中,读取过程中直到出现新的一行为止。其中新的一行的换行字符将会转换为字符串中的空终止符 “\0”。

      • 如:char cString[30]; gets(cstring);

    • 2>、int puts(char *str);

      • 输出一个字符串后会自动换行操作,puts 函数会在字符串中判断 “\0” 结束符,遇到结束符时,后面的字符不再输出并且自动换行。

      • 如:puts(“I Love China”);

5、数组

  • 1)数组元素的个数必须为常量或常量表达式,不能是变量。

    • 数组名代表数组的地址,为常量,不可改变。
    • 数组作为函数参数时,如果实参为数组名,将会改变原数组元素的值,形参中可以不写数组元素的个数。
  • 2)数组不初始化时,数组元素的值不确定。

6、指针

  • 1)在同一种编译器环境下,一个指针变量所占用的内存空间是固定的,并不会随所指向变量的类型而改变,16 位下为 2 个字节,32 位下为 4 个字节,64 位下为 8 个字节。

  • 2)指向函数的指针

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    int sum(int a, int b) {

    return a + b;
    }

    int main(int argc, const char * argv[]) {

    // 定义指向函数的指针
    int (*p)(int, int);

    // 指针指向函数
    p = sum;

    // 调用函数
    // int c = (*p)(5, 6);
    int c = p(5, 6);

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

    return 0;
    }
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    // 定义函数

    // 加法
    int sum(int a, int b){

    return a + b;
    }

    // 减法
    int sub(int a, int b){

    return a - b;
    }
    • 1> 指向函数的指针的定义

      1
      2
      3
      4
      5
      6
      7
      8
      // 定义指向函数的指针 sump,指向函数 sum
      int (*sump)(int, int) = sum;

      // 调用指向函数的指针(调用函数)
      int sum1 = (*sump)(10, 5);

      // 调用指向函数的指针(调用函数)
      int sum2 = sump(10, 2);
    • 2> 指向函数的指针类型的定义

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      // 定义 指向函数的指针类型 funp
      typedef int (*funp)(int, int);

      // 定义 funp 的变量 fun
      funp fun;

      // 给 funp 的变量 fun 赋值
      fun = sum;

      // 调用 funp 的变量 fun 所指向的函数,做 加法 预算
      int sumValue = fun(10, 6);

      NSLog(@"%d", sumValue);

      // 给 funp 的变量 fun 赋值
      fun = sub;

      // 调用 funp 的变量 fun 所指向的函数,做 减法 运算
      int subValue = fun(10, 6);

7、结构体

  • 1)结构体在定义时不开辟内存空间,使用时才开辟空间。

  • 2)结构体长度:结构体中的元素存储时按照最长的数据类型长度的整数倍对齐存储,且相邻的元素的原有类型的长度之和小于结构体中最长元素的长度时,相邻的元素对齐到一个最长的数据类型。

8、共用体

  • 1)共用体定义了一块为所有数据成员共享的内存。

  • 2)共用体的长度:所包含的数据成员中最大内存长度的大小。

  • 3)共用体初始化时只需要一个初始化值就够了,其类型必须和共用体的第一个成员的类型相一致。

9、枚举

  • 1)枚举中每个标识符都必须是唯一的,而且不能采用关键字或当前作用域内的其他相同的标识符。

10、运算符

  • 1)运算符:

    • 1> 算术运算符:

      +, -, *, /, %

      • 取模(%)运算符的两侧均为整数

      • 自增运算符 ++

      • 自减运算符 --

      • 在表达式内部,作为运算的一部分,如果运算符放在变量前面,那么变量在参加表达式运算之前完成自增运算或者自减运算;如果运算符放在变量后面,那么变量的自增或者自减运算在变量参加了表达式运算之后完成。

    • 2> 关系运算符:

      >, >=, <, <=, ==, !=

    • 3> 逻辑运算符:

      &&, ||, !

    • 4> 位逻辑运算符:

      &(清零), |(设置), ^(取补), ~(取反)

    • 5> 逗号运算符:

      表达式1,表达式2,……,表达式n

    • 6> 问号运算符(条件运算符):

      表达式1?表达式2:表达式3

      • 在运算中,首先对第一个表达式的值进行检验,如果为真,则返回第二个表达式的结果值,如果为假,则返回第三个表达式的结果值。
    • 7> 复合赋值运算符:

      +=, -=, *=, /=, %=

      • 对于简单赋值运算符,如 Func = Func + 1 中,表达式 Func 计算两次;对于复合赋值运算符 Func += 1 中,表达式 Func 仅计算一次。一般来说这种区别对于程序的运行没有太大的影响,但是如果表达式中存在某个函数的返回值,那么函数被调用两次。
  • 2)短路运算:

    • && 运算 短路与运算:第一个表达式的值为假,不再运算第二个表达式的值。
    • || 运算 短路或运算:第一个表达式的值为真,不再运算第二个表达式的值。
  • 3)运算注意精度上升/下降,优先级,边界。

  • 4)截断:长整型数据赋值给短整型变量时会发生截断,即保留低位,舍去存不下的高位。

    • 扩展:短整型数据赋值给长整型变量时发生扩展,正数高位补 0,负数高位补 1。
  • 5)float (单精度浮点),double (双精度浮点)通常使用没区别,不过 float 赋值给 double 精度不会提升,double 赋值给 float,精度会下降。

  • 6)不同类型的数据进行数学运算,遵从以下原则:

    • 不同类型的数据要先转化为同一类型,然后进行运算:

      char, short —> int —> unsigned —> long —> double <— float

    • 短字节向长字节看齐 int + char = int

    • 有符号向无符号看齐
    • 整型向浮点看齐 int + float = float 3 *‘a’+ 4.6f = 295.6f(float)
    • 单精度向双精度看齐
  • 7)

    1
    2
    3
    4
    continue: 	结束一次循环
    break: 结束当前循环
    return: 结束一个函数
    exit: 结束整个程序
  • 8)转移语句

    • 1>、goto 语句

      • goto 标识符;
      • 标识符: 程序语句;

      • goto 语句为无条件转移语句,可以使程序立即跳转到函数内部的任意一条可执行语句。

      • 跳转的方向可以向前,也可以向后,可以跳出一个循环,也可以跳入一个循环。

    • 2>、break 语句

      • break;

      • break 语句终止并跳出循环,继续执行后面的代码。

      • break 语句不能用于循环语句和 switch 语句之外的任何其它语句中。

    • 3>、continue 语句

      • continue;

      • continue 语句结束本次循环,即跳过循环体中尚未执行的部分,返回到循环头部继续执行下一次的循环操作。

      • continue 语句只结束本次循环,而不是终止整个循环的执行;break 语句则是结束整个循环过程,不再判读执行的条件是否成立。

  • 9)在 for 语句中的表达式 1 和表达式 3 处,除了可以使用简单的表达式外,还可以使用逗号表达式。

  • 10)switch 语句的检验条件必须是一个整形表达式,其中可以包含运算符和函数调用,case 语句的检验值必须是一个整形常量,可以是常量表达式或常量运算。其中任意两个 case 语句都不能使用相同的常量值。

    • 如果没有一个 case 语句后面的值能匹配 switch 语句的条件,就执行 default 语句后面的代码。并且每一个 switch 结构只能有一个 default 语句,而且 default 可以省略。

11、表达式

  • 1)由运算符和变量、常量共同组成表达式。如 a 6 a + 3 5 - 2 a / b + 3

  • 2)审视一个表达式分两步

    • 1> 看表达式的功能
    • 2> 看表达式的值

12、函数

  • 1)printf 函数,输出控制符:

    1
    2
    3
    .2 输出 2 位小数,
    2 输出的数据左边空 2 位,
    -2 输出的数据右边空 2 位。
  • 2)scanf 函数,两个输入控制符之间如果是空格或什么也没有,在输入数据时可以用空格、tab 键或回车键区分输入的数据。如果两个输入控制符之间有字符,则在输入数据时需要用相同的字符区分不同的数据。

  • 3)sizeof(),计算数据占用的字节长度,可以是 sizeof(int),sizeof(a),sizeof(10),char d =‘A’ sizeof(d) (计算字符型数据的字节数)。

  • 4)

    • extern 用来修饰(定义或声明)外部函数(可省略)。static 用来修饰(定义或声明)内部函数。
    • extern 只能用来声明外部变量(可省略)(全局变量),不能用来定义外部变量。static 用来定义内部变量(全局变量)。

13、预处理

  • 1)预处理

    • 宏定义可以定义常量或表达式。

    • 条件编译在程序编译之前处理,判断条件不能是变量,可以是宏定义的内容。

    • 文件包含中尖括号只能包含系统自带的库文件,双引号包含自定义的文件也可包含系统自带的库文件。

14、编译

  • 1)c 语言中同一个工程中不能出现相同名字的函数。

    .c — 编译 —> .obj — 链接 —> .exe

    • 编译过程中不同的 .c 文件单独编译成 .obj 的目标文件,链接过程中不同的 .obj 文件与 c 语言库文件链接成 .exe 文件,此过程中会检查函数的唯一性,如果有相同名称的函数会产生链接错误。

15、内存管理

  • 1)内存数据,不看怎么存,只看怎么读。

  • 2)在实际开发中,声明一个无符号数,往往表示这个变量存储的数据理应是正数,如文件大小,工程进度等。但没有强制的约束力。

文章目录
  1. 1. 前言
  2. 2. 1、数据类型
  3. 3. 2、常量
  4. 4. 3、变量
  5. 5. 4、字符串
  6. 6. 5、数组
  7. 7. 6、指针
  8. 8. 7、结构体
  9. 9. 8、共用体
  10. 10. 9、枚举
  11. 11. 10、运算符
  12. 12. 11、表达式
  13. 13. 12、函数
  14. 14. 13、预处理
  15. 15. 14、编译
  16. 16. 15、内存管理
隐藏目录