C语言高级笔记
提升方向:
C语言规范问题:
这才是像样的C语言编程规范啊
如何编写美观又规范的嵌入式C代码?
1. 指针部分:
指针的用途说白了就是传递和偏移,还有就是动态内存使用
指针的高级用法,包括指针的指针、函数指针、指针与数组、指针与结构体的深入应用等。
指针数组:本质是数组
1.指针数组的每个元素都是一个一级指针,每个元素都有自己独立的内存地址
2.应用于字符串数组或者动态数组中
const char* str[3] = { "abc", "123", "..." }; for (int i = 0; i < sizeof(str)/sizeof(char *) i++) { cout << str[i] << endl; }数组指针:本质是指针
1.数组指针指向第一个数组,每个元素都是一个数组
2.简化多维数组的操作和访问
3.函数参数传递,使函数能够接收多个维度的参数,如果实参是一个二维数组的话,形参可以用数组指针去接收
void prit(int (*str)[3], int rows) { for (int i = 0; i < rows; ++i) { for (int j = 0; j < 3; ++j) { cout << str[i][j] << " "; } cout << endl; } } int main() { int str[2][3] = { {1,2,34}, {2,3,5}}; prit(str, 2); return 0; }指针函数:本质是函数,返回值类型是指针,修改返回值类型的
1.用于返回动态内存分配的返回内存指针
2.链表操作,用于返回新节点或者链表后的节点
3.字符串操作,返回字符串地址
#include <stdio.h> #include <stdlib.h> int* mymalloc() { int* ptr = (int*)malloc(sizeof(int)*5); if (ptr == NULL) { return NULL; } return ptr; } int main() { int* nptr = mymalloc(); for (int i = 0; i< 5; i++) { nptr[i] = i; printf("%d ", nptr[i]); } free(nptr); nptr = NULL; return 0; }函数指针:本质是指针
1.用于回调函数中,一个函数调用另外一个
2.动态函数选择,可以在运行中动态选择哪个函数运行,配合函数数组使用
3.函数指针可以替代繁琐的Switch-case的使用,简化代码结构
更好的模块化处理,比如形参列表相同的,功能不同的两个函数整合一起,
/*带参数带返回值的函数指针*/ typedef int (*ParamFunction)(int, int); int my_add1(int a, int b) { return (a + b); } int executeGreet(ParamFunction func, int x, int y) { return func(x, y); // 调用函数指针指向的函数 } /*不带参数不带返回值*/ typedef void (*noparamFunction)(); void demo(void) { printf("无参数的函数指针\n"); } //模板 void noparamModel(noparamFunction fun) { fun(); } int main() { int result = executeGreet(my_add1, 5, 3); noparamModel(demo); printf("Result: %d\n", result); return 0; }动态函数选择替代Switch - case 当然对于那种case里面只是一句话的就没必要用了,因为你也要创建大量的函数体 #include <stdio.h> // 定义函数指针类型 typedef int (*operation_func)(int, int); // 各种运算函数 int add(int a, int b) { return a + b; } int subtract(int a, int b) { return a - b; } int multiply(int a, int b) { return a * b; } int divide(int a, int b) { return a / b; } int main() { int a = 10, b = 5; const char operator = '+'; // 函数指针数组 operation_func operations[256] = { NULL }; // 初始化函数指针数组 operations['+'] = add; operations['-'] = subtract; operations['*'] = multiply; operations['/'] = divide; // 选择并调用相应的函数 if (operations[(int)operator] != NULL) { int result = operations[(int)operator](a, b); printf("Result: %d\n", result); } else { printf("Invalid operator\n"); return 1; } return 0; }值传递:
//值传递 void fun(int a, int b) { int temp = 0; temp = a; a = b; b = temp; cout << "a=" << a << endl << "b=" << b << endl; }指针传递:
//指针传递 void fun(int *a, int *b) { int temp = 0; temp = *a; *a = *b; *b = temp; cout << "a=" << *a << endl << "b=" << *b << endl; }结构体指针
77
结构体函数指针:功能函数列表
88
二级指针
00
2. 动态内存部分:
深入了解动态内存分配、管理和优化。掌握 `malloc`, `calloc`, `realloc` 和 `free` 函数的使用,以及如何避免内存泄漏和碎片化。
malloc:
/*用于手动分配一块连续的存储空间,需要手动初始化,也是用的最多的一种,最后记得释放内存*/ int* mymalloc(int num) { int* ptr = (int*)malloc(sizeof(int)*num); if (ptr == NULL) return NULL; return ptr; } int main() { int *pt = mymalloc(10); for (int i = 0; i<10; i++) { pt[i] = i; cout << pt[i] << " " << endl; } free(pt); return 0; }calloc:
/*为某个元素指定分配多大的内存空间,自动分配内存并且初始化为0,适合用于数组和结构体这样的数据结构,最后记得要释放内存*/ / 为N个整型元素分配内存,并初始化为零 array = calloc(n, sizeof(int)); if (array == NULL) { fprintf(stderr, "内存分配失败\n"); return -1; } // 输出数组,检查是否所有元素都初始化为0 for (int i = 0; i < n; i++) { printf("%d ", array[i]); } printf("\n"); // 使用完毕后,释放内存 free(array);realloc:
/*如果原来分配的内存不够用了,需要分配更大的内存,需要使用realloc,通常需要和malloc搭配使用,最后释放内存*/ int* arr = malloc(5 * sizeof(int)); // 最初为5个整数分配内存 if (arr == NULL) { fprintf(stderr, "内存分配失败\n"); return 1; } int newSize = 10; // 假设我们现在需要一个更大的数组 arr = realloc(arr, newSize * sizeof(int)); // 将数组大小更改为10个整数 if (arr == NULL) { fprintf(stderr, "内存重新分配失败\n"); return 1; }3. 结构体部分:
最常见的结构体的用法如下:
typedef struct { uint8_t pi_temp[2]; //无源输入外接温度 uint8_t pi_smoke[2]; //无源输入外接烟感 uint8_t pi_manualwarn;//无源输入模拟报警 uint8_t pi_open;//紧急启动 uint8_t pi_close;//紧急关闭 uint8_t pi_mn_aut; //手自动转换 uint8_t pi_reset;//复位 uint8_t pi_mute;//消音 uint8_t pi_readsata; //无源9 uint8_t pi_readsata2; //消音不再起作用 改为无源反馈 } PASSIVE_IN; PASSIVE_IN pi_in;结构体中套用结构体:
struct Birthday { int year; int month; int day; }; struct Person { char name[50]; struct Birthday birthday; }; struct Person person1 = {"张三", {1990, 5, 20}}; printf("出生年份: %d\n", person1.birthday.year);位域操作机制结构体中,所有成员共用同一个结构体类型,节省内存空间
struct zjio_channel_config{ rt_uint16_t START_IO : 4;// 0000 pin rt_uint16_t SX_MODE : 2;//发送还是接收 rt_uint16_t BUFFER_TYPE : 4;//数据类型 rt_uint16_t EX_MODE : 2; rt_uint16_t END_IO : 4; };其他部分:
运算符 优先级:扩单数,移关位,逻三赋逗
括号,单目运算符(++ -- +- !),数学运算(+-*/),移位运算符(<< >>),关系运算(> < == ),位运算(& | ^) ,逻辑运算符(&& || ~),三目运算(num = a ?1:0;),赋值运算(=),逗号运算(,)
