-
语法和语义
变量定义
基本数据类型:定义整型(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++语言中涉及的语法和语义、指针、结构体与联合体、函数指针等基础知识,特别关注了在嵌入式开发环境下的应用和注意事项。