一盏黄黄旧旧的灯

一盏黄黄旧旧的灯

  1. 语法和语义

变量定义

基本数据类型:定义整型(int、long、short)、浮点型(float、double)、字符型(char)等基本数据类型的变量。

自定义类型:定义结构体、联合体、枚举等自定义类型变量。

指针类型:定义指向特定类型数据的指针变量,如int *p表示一个整型指针。

数据类型

基本数据类型:整型、浮点型、字符型、布尔型(C++中为bool,C中可使用整型模拟)。

复合数据类型:数组、结构体、联合体、枚举。

指针类型:指向任何数据类型的指针,包括指向函数的指针。

空类型void:用于表示无返回值的函数、无类型指针(如通用指针void *)。

运算符

算术运算符:加法(+)、减法(-)、乘法(*)、除法(/)、求余(%)。

关系运算符:等于(==)、不等于(!=)、小于(<)、大于(>)、小于等于(<=)、大于等于(>=)。

逻辑运算符:逻辑与(&&)、逻辑或(||)、逻辑非(!)。

位运算符:按位与(&)、按位或(|)、按位异或(^)、按位取反(~)、左移(<<)、右移(>>)。

赋值运算符:简单赋值(=)及复合赋值运算符(如+=、-=、*=、/=、%=等)。

条件运算符(三目运算符):condition ? expr1 : expr2。

sizeof运算符:计算类型或变量所占内存大小。

取地址运算符:&,用于获取变量的内存地址。

解引用运算符:*,用于访问指针所指向的数据。

流程控制语句

条件语句:

if语句:根据条件执行相应代码块。
if…else语句:提供两种情况的选择性执行。
switch语句:根据表达式的值匹配多个case标签,执行相应的代码块。
循环语句:

for循环:具有初始化、条件检查、迭代更新三个部分的循环结构。
while循环:只要条件为真就持续执行循环体。
do…while循环:先执行一次循环体,然后在每次循环末尾检查条件。
跳转语句:

break语句:跳出当前循环或switch语句。
continue语句:跳过本次循环剩余部分,进入下一轮循环。
goto语句:无条件转移到同一函数内的标号处。

函数定义与调用

函数定义:指定函数返回类型、函数名、参数列表(含参数类型和顺序)及函数体。

函数声明:在函数调用前提供函数原型,以便编译器进行类型检查和链接。

函数调用:通过函数名、实参列表调用已定义或声明的函数。

参数传递:了解传值、传址(通过指针)、传引用(C++特有)的区别和适用场景。

返回值:函数可以返回一个值给调用者,也可以选择不返回值(void返回类型)。

2. 指针

指针声明

基础声明:声明一个指向特定类型数据的指针变量,如int *p;声明一个整型指针p。

指针初始化:为指针赋予一个合法的地址值,如int *p = &x;使p指向整型变量x。

指针运算

解引用:使用*运算符访问指针所指向的数据,如int val = *p;获取p指向的整数值。

自增自减:p++、p–使指针向前或向后移动到下一个(同类型)数据的地址。

指针间的关系运算:比较两个指针的地址关系,如p1 == p2、p1 < p2等。

动态内存管理

内存分配:

malloc(size_t size):分配size字节未初始化的内存,返回指向该内存的指针。
calloc(size_t num, size_t size):分配num个大小为size字节的连续内存块,并将其初始化为零,返回指向首块的指针。
内存重分配:

realloc(void *ptr, size_t new_size):调整已分配内存ptr的大小为new_size,返回新分配内存的指针。若调整失败,返回NULL,原内存保持不变。
内存释放:

free(void *ptr):释放由malloc、calloc或realloc分配的内存。
通过指针操作复杂数据结构
数组:使用指针遍历数组、修改数组元素、传递数组作为函数参数等。

结构体:通过指针访问结构体成员、传递结构体指针作为函数参数、动态分配结构体内存等。

联合体:类似结构体,但同一时刻只能存储一个成员,通过指针访问其当前活跃成员。

3. 结构体与联合体

结构体

定义:使用struct关键字定义结构体类型,包含若干成员(变量)及其类型。

struct Point {
    int x;
    int y;
};

变量声明:声明结构体类型变量,可使用类型名或typedef后的别名。

struct Point p1;            // 直接使用结构体类型名
typedef struct Point Point;  // 创建类型别名
Point p2;                   // 使用类型别名声明变量

成员访问:通过.或->运算符访问结构体变量的成员。

p1.x = 10;                  // . 运算符,用于普通结构体变量
Point *ptr = &p2;
ptr->y = 20;                // -> 运算符,用于指向结构体的指针

初始化:
常规初始化:在声明时为结构体变量的所有成员赋初值。

  struct Point p = {1, 2};

指定成员初始化:仅初始化部分成员,其余成员默认初始化。

  struct Point p = {.x = 1}; // 初始化x成员,y成员默认初始化

结构体数组:声明和使用结构体类型的数组。

struct Point points[3];
points[0] = {1, 2};
points[1] = {3, 4};
points[2] = {5, 6};

联合体

定义:使用union关键字定义联合体类型,其成员共享同一块内存空间。

union Value {
    int integer;
    float floating;
    char character;
};

变量声明:与结构体类似,声明联合体类型变量。

union Value v;

成员访问:与结构体类似,通过.或->运算符访问联合体变量的成员。

v.integer = 42;
v.floating = 3.14f;
v.character = 'A';

初始化:为联合体变量的某个成员赋初值。

union Value v = {.integer = 10};

注意:联合体在同一时刻只能存储一种类型的成员,对其中一个成员赋值会覆盖其他成员的值。使用联合体时需确保正确跟踪当前存储的是哪种类型的值。

4. 函数指针

定义:声明一个指向特定函数类型的指针变量,函数类型包括返回类型和参数列表

int (*func_ptr)(int, int); // 定义一个指向接受两个整数参数并返回整数的函数的指针

初始化:将函数指针指向实际的函数。

int add(int a, int b) {
    return a + b;
}

func_ptr = add; // 将func_ptr指向add函数

调用:通过函数指针调用对应的函数。

int result = (*func_ptr)(5, 3); // 等价于调用add(5, 3)

应用场景:
回调函数:将函数指针作为参数传递给另一个函数,供后者在适当时候调用。
事件处理/中断服务:在嵌入式系统中,使用函数指针注册中断处理函数或其他事件响应函数。
函数表:创建一个函数指针数组,实现基于索引来调用不同功能的函数。
以上内容详述了C/C++语言中涉及的语法和语义、指针、结构体与联合体、函数指针等基础知识,特别关注了在嵌入式开发环境下的应用和注意事项。

04-05 10:56