C语言复习-基础篇

摘要

简单复习一下C语言。

进阶篇:C语言复习-进阶篇

1.C程序的构成

1
2
3
4
5
6
7
#include<stdio.h> //头文件、预处理

void main(){ //定义主函数(主函数只能有一个)
//定义变量(C语言的变量要定义后才能使用)
//程序主体
printf("hello word\n"); //输出结果(每一行结束都要有分号)
}

编译过程:源程序(.c)--编译-->目标程序(.obj)--链接-->可执行程序(.exe)

2.关键字

大部分内容参考自知乎文章C语言中32个关键字详解

2.1 基本数据类型(5个)

注:括号内字节数指在32位arm处理器下

  • void:声明函数无返回值或无参数,声明无类型指针,显式丢弃运算结果
  • char:字符型类型数据,属于整型数据的一种(1个字节)
  • int:整型数据,通常为编译器指定的机器字长(4个字节)
  • float:单精度浮点型数据,属于浮点数据的一种(4个字节)
  • double:双精度浮点型数据,属于浮点数据的一种(8个字节)

注:C中没有string类型,要使用需要头文件里定义#include<string.h>,C++里的定义是#include<string>,字符串的结尾为'\0'

注:指针都是4个字节

2.2 修饰关键字(4个)

  • short:修饰int,短整型数据,可省略被修饰的int(2个字节)
  • long:修饰int,长整形数据,可省略被修饰的int(4个字节 long long 8个字节)
  • signed:修饰整型数据,有符号数据类型
  • unsigned:修饰整型数据,无符号数据类型

2.3 复杂类型关键字(5个)

  • struct:结构体声明
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    //自定义数据类型,一些类型集合组成的一个类型
    //语法 struct 类型名称 {成员列表}
    struct student
    {
    //成员列表

    //姓名
    string name;
    //年龄
    int age;
    //分数
    int score;
    }s3;
  • union:共用体声明
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    //一个联合变量(共用体)的长度等于各成员中最长的长度
    union StateMachine
    {
    char character;
    int number;
    char *str;
    double exp;
    };
    //StateMachine 的空间大小就是double 数据类型的大小
    //在C++里,union 的成员默认属性页为public。
    //union 主要用来压缩空间。如果一些数据不可能在同一时间同时被用到,则可以使用union。
    //一种常见的手法是使用union判断存储方式是大端还是小端。
  • enum:枚举声明
    1
    2
    3
    enum season { spring, summer, autumn, winter };
    //默认情况下spring为0,summer为1,依此类推。也可以自行赋值
    //可以默认安排值,主要是阅读方便
  • typedef:声明类型别名
  • sizeof:得到特定类型或特定类型变量的大小

2.4 存储级别关键字(6个)

  • auto:指定为自动变量,由编译器自动分配及释放。通常在栈上分配
  • static:指定为静态变量,分配在静态变量区。修饰函数时,指定函数作用域为文件内部。
  • register:指定为寄存器变量,建议编译器将变量存储到寄存器中使用,也可以修饰函数形参,建议编译器通过寄存器而不是堆栈传递参数
  • extern:指定对应变量为外部变量,即在另外的目标文件中定义,可以认为是约定由另外文件声明的对象的一个“引用”
  • const:与volatile合称“cv特性”,指定变量不可被当前线程/进程改变(但有可能被系统或其他线程/进程改变)
    1
    //在防御性编程中可以多用const
  • volatile:与const合称“cv特性”,指定变量的值有可能会被系统或其他进程/线程改变,强制编译器每次从内存中取得该变量的值
    1
    2
    3
    4
    //volatile通常用于如下三种情况
    //1.程序使用RTOS,多线程中都会读写的全局变量
    //2.中断和主函数中都要读写的全局变量
    //3.单片机的寄存器定义

2.5 跳转结构关键字(4个)

  • return:用在函数体中,返回特定值(或者是void值,即不返回值)
  • continue:结束当前循环,开始下一轮循环
  • break:跳出当前循环或switch结构
  • goto:无条件跳转语句

2.6 分支结构关键字(5个)

  • if:条件语句
  • else:条件语句否定分支(与if连用)
  • switch:开关语句(多重分支语句)
  • case:开关语句中的分支标记
  • default:开关语句中的“其他”分治,可选

2.7 循环结构关键字(3个)

  • for:for(1;2;3)4;的执行顺序为1->2->4->3->2...循环,其中2为循环条件
  • do:do 1 while(2);的执行顺序是1->2->1...循环,2为循环条件
  • while:while(1) 2;的执行顺序是1->2->1...循环,1为循环条件

3.输入输出

3.1 转义字符表

转义字符 含义
\' 单引号
\" 双引号
\\ 反斜杠
\n 换行符
\r 回车符
\t 制表符
\b 退格符
\f 换页符
\v 垂直制表符
\a 响铃符
\0 空字符

3.2 printf()函数

这个函数用于将格式化的字符串输出到标准输出流(通常是终端)。printf()函数的常见用法如下:

1
2
printf("Hello, world!");  // 输出简单的字符串
printf("My age is %d", age); // 输出格式化的字符串

其中,%d是一个占位符,用于表示将要输出的变量的数据类型。例如,上面的代码中,%d表示将要输出一个整数类型的变量age。

下面是类型符号及其含义

1
2
3
4
5
6
7
8
9
%d - 整型格式说明符,用于输出整数值。
%f - 浮点型格式说明符,用于输出浮点数值。
%c - 字符型格式说明符,用于输出单个字符。
%s - 字符串格式说明符,用于输出字符串值。
%p - 指针型格式说明符,用于输出内存地址。
%x 或 %X - 十六进制格式说明符,用于以十六进制格式输出整数值。
%o - 八进制格式说明符,用于以八进制格式输出整数值。
%e 或 %E - 科学计数法格式说明符,用于以科学计数法格式输出浮点数值。
%g 或 %G - 自动格式说明符,根据输出变量的大小决定使用 %f 或 %e 格式。

通过在百分号后面加指令可以控制固定精度输出,如%.2f指输出小数点后2位的浮点数。

1
2
3
4
5
6
7
8
9
10
//输入
float pi = 3.1415926535;
printf("pi = %.3f\n", pi);
printf("pi = %.*f\n", 3, pi);
printf("pi = %g\n", pi);

//输出
pi = 3.142
pi = 3.142
pi = 3.14159

3.3 scanf()函数

这个函数用于从标准输入流中读取数据。scanf()函数的常见用法如下:

1
2
3
scanf("%d", &num);  // 读取一个整数类型的变量
scanf("%f", &score); // 读取一个浮点数类型的变量
scanf("%s", str); // 读取一个字符串类型的变量

scanf()函数中的%符号也是一个占位符,用于表示将要读取的变量的数据类型。&符号用于表示将要读取的变量的地址。在使用scanf()函数时,需要注意数据类型匹配和错误处理等问题。

3.4 getchar()函数和putchar()函数

1
2
char c = getchar();  // 读取一个字符
putchar('A'); // 输出一个字符

getchar()函数会等待用户输入一个字符,并将该字符作为返回值返回,而putchar()函数则将给定的字符输出到标准输出流。

3.5 gets()函数和puts()函数

gets()函数用于从标准输入流中读取一行字符串,直到遇到换行符为止。

puts()函数则将给定的字符串输出到标准输出流,并在字符串末尾自动添加一个换行符。它们的常见用法如下:

1
2
3
char str[100];
gets(str); // 读取一行字符串
puts(str); // 输出字符串并添加一个换行符

gets()函数的安全性不高,容易引发缓冲区溢出等安全问题,因此建议使用fgets()函数代替gets()函数进行字符串输入。

3.6 文件读写

1
2
3
4
5
6
7
8
9
FILE *fp = fopen("file.txt", "r");  // 打开文件
if (fp == NULL) {
printf("File does not exist."); // 检查文件是否打开成功
exit(1); // 如果文件打开失败,则终止程序
}

char str[100];
fgets(str, 100, fp); // 从文件中读取一行字符串
fclose(fp); // 关闭文件

4.符号运算优先级

优先级 运算符 结合性
1 ( ) 左右
2 ! ~ - 右到左
3 * / % 左到右
4 + - 左到右
5 << >> 左到右
6 < <= > >= 左到右
7 == != 左到右
8 & 左到右
9 ^ 左到右
10 | 左到右
11 && 左到右
12 || 左到右
13 ? : 右到左
14 = += -= *= /= %= &= ^= |= <<= >>= 右到左

5.数组

在C语言中,数组是一组相同数据类型的元素的集合。数组中的每个元素都可以通过下标来访问,下标从0开始计数。数组的定义方式如下:

1
type array_name[array_size];

其中,type表示数组中元素的数据类型,array_name表示数组的名称,array_size表示数组中元素的个数。在数组中,第一个元素的下标为0,最后一个元素的下标为array_size-1。可以通过下标来访问数组中的元素。

6.指针

在C语言中,指针是一种特殊的变量类型,它可以存储变量的地址。指针的定义方式如下:

1
type *pointer_name;

其中,type表示指针所指向变量的数据类型,pointer_name表示指针的名称。指针变量需要指向某个内存地址才能使用,可以通过取地址运算符&来获取变量的地址,例如:

1
2
3
int a = 1;
int *p = &a; // 将指针p指向变量a的地址
int b = *p; // 将b赋值为指针p所指向的变量的值
1
2
3
4
5
int a[5] = {1, 2, 3, 4, 5};
int *p = a; // 将指针p指向数组a的第一个元素
for (int i = 0; i < 5; i++) {
printf("%d ", *(p+i)); // 通过指针访问数组中的元素
}