🔥码云GVP开源项目 12k star Uniapp+ElementUI 功能强大 支持多语言、二开方便! 广告
# 基础 ## 关键字 ~~~ typeof int a = 5; typeof(int *) var = &a; ~~~ ![](data:image/gif;base64,R0lGODlhAQABAPABAP///wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==) ## 数据类型变量 ~~~ char 1 unsigned char 1 signed char 1 int 4 unsigned int 4 short 2 unsigned short 2 long 4/8 unsigned long 4/8 long long 8 float 4 double 8 long double 16 double a = 10; void fuction(void); void *ptr = malloc(12); 85 /* 十进制 */ 0213 /* 八进制 */ 0x4b /* 十六进制 */ 30 /* 整数 */ 30u /* 无符号整数 */ 30l /* 长整数 */ 30ul /* 无符号长整数 */ //定义常量 #defined a 100 const int a = 100; ~~~ ![](data:image/gif;base64,R0lGODlhAQABAPABAP///wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==) ## 存储类 ~~~ auto register static extern volatile 变量自动auto 函数自动auto auto int a; == int a; register int a; //每次取值从内存去 编译器不要优化 static int a; //静态变量 生命周期全局 static void fun(); //限制函数名称作用域再本文件别的文件不能引用 避免命名空间污染 extern int a; //变量a引用 extern void fun(); //引用别的文件的函数 volatile 防止编译器优化掉操作变量的语句 ~~~ ![](data:image/gif;base64,R0lGODlhAQABAPABAP///wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==) ## 数组 ~~~ //一维数组 int array[4] = {1, 2, 3, 4} int array[] = {1, 2, 3, 4}; int a = array[0] //二维数组 int array[3][4] = { {0, 1, 2, 3} , /* 初始化索引号为 0 的行 */ {4, 5, 6, 7} , /* 初始化索引号为 1 的行 */ {8, 9, 10, 11} /* 初始化索引号为 2 的行 */ }; int val = array[2][3]; int people[30] = {[0 ... 29] = 1}; //数组传参 1. void fun(int *array) { } 2. void fun(int array[4]) { } 3. void fun(int array[]) { } 常用1和3 //传递二维数组 int array[4][3] = {0}; void fun(int array[][3]) void fun(int (* p)[3]); //数组指针 指向数组 fun(array); 数组相同于指针 一维数组 int array[5]; *(array + 1) == *(&array[0] + sizeof(array)) //*(&array[0] + 5) 二维数组 int array[4][5]; *(array + 1) == *(&array[0] + sizeof(array)) //*(&array[0] + 20) 三维 int array[3][4][5]; *(array + 1) == *(&array[0] + sizeof(array)) //*(&array[0] + 60) //指针+1内存增加指针指向数据类型长度 //函数返回数组 int * fun() { static int array[10]; return array; } //指向数组指针 int array[4] = {1, 2, 3, 4} int *ptr = array; int array[4][4] int *ptr = array; int (*p)[4] = array; ~~~ ![](data:image/gif;base64,R0lGODlhAQABAPABAP///wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==) ## 枚举 ~~~ enum DAY { MON = 1, TUE }; enum season {spring, summer=3, autumn, winter}; 没有指定值的枚举元素,其值为前一元素加 1。也就说 spring 的值为 0,summer 的值为 3,autumn 的值为 4,winter 的值为 5 enum DAY { MON=1, TUE, WED, THU, FRI, SAT, SUN }; enum DAY day; enum DAY { MON=1, TUE, WED, THU, FRI, SAT, SUN } day; ~~~ ![](data:image/gif;base64,R0lGODlhAQABAPABAP///wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==) ## 指针 ~~~ int *p; //一级指针 int **p; //二级指针 int (*p)[4]; //数组指针 就是 指针指向数组 数组存储大小是4个单元 int *p[4]; //指针数组 4个指向int的指针 int a = 10; p[0] = &a; int (*p)(int, int); //函数指针 指向函数 int fun(int a, int b); p = fun; p(1, 2);//执行 typedef int (*fun_ptr)(int, int); fun_ptr p = fun; //别名定义 ~~~ ![](data:image/gif;base64,R0lGODlhAQABAPABAP///wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==) ## 字符串 ~~~ 数组最后一个字节存储 '\0' char greeting[6] = {'H', 'e', 'l', 'l', 'o', '\0'}; char str[] = "hello" //自动添加 '\0' ~~~ ![](data:image/gif;base64,R0lGODlhAQABAPABAP///wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==) ## 结构体 ~~~ //定义 1. struct Books { char title[10]; char author[10]; } book; 2. struct Books book; 3. typedef struct { char title[10]; char author[10]; } Books; Books book; //初始化 Books book = {"c", "my"}; Books book = {.title = "c", .author = "my"}; //C风格 Books book = {title : "c", author : "my"}; //C++风格 结构体大小 1,每个结构体成员的起始地址为该成员大小的整数倍,即int型成员的其实地址只能为0、4、8等 2,结构体的大小为其中最大成员大小的整数倍 ~~~ ![](data:image/gif;base64,R0lGODlhAQABAPABAP///wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==) ## 共用体 ~~~ 共用体是一种特殊的数据类型,允许您在相同的内存位置存储不同的数据类型。您可以定义一个带有多成员的共用体,但是任何时候只能有一个成员带有值。共用体提供了一种使用相同的内存位置的有效方式 union Data { int i; float f; char str[20]; }; int main( ) { union Data data; printf( "Memory size occupied by data : %d\n", sizeof(data)); return 0; } //20 //大小为最大成员大小 big-endian和little-endian格式。在小端模式中,低位字节放在低地址,高位字节放在高地址;在大端模式中,低位字节放在高地址,高位字节放在低地址。 //大小端测试 #include<stdio.h> union var{ char c; int i; }; int main(){ union var data; data.c = 0x04; printf("%x\n",data.i); if(data.i == 0x04) { printf("小端"); } else { printf("大端"); } } REVERSED #if defined(REVERSED) std::cout<< ("大端"); #else std::cout<<("小端"); #endif ~~~ ![](data:image/gif;base64,R0lGODlhAQABAPABAP///wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==) ## 变参数函数 ~~~ double average(int num,...) { va_list valist; double sum = 0.0; int i; /* 为 num 个参数初始化 valist */ va_start(valist, num); /* 访问所有赋给 valist 的参数 */ for (i = 0; i < num; i++) { sum += va_arg(valist, int); } /* 清理为 valist 保留的内存 */ va_end(valist); return sum/num; } int main() { printf("Average of 2, 3, 4, 5 = %f\n", average(4, 2,3,4,5)); printf("Average of 5, 10, 15 = %f\n", average(3, 5,10,15)); } ~~~ ![](data:image/gif;base64,R0lGODlhAQABAPABAP///wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==) ## 预处理器 ~~~ 字符串常量化运算符(#)和标记粘贴运算符(##) #define Conn(x, y) x##y //连接字符 #define ToString(x) #x //转化为字符串 #define message_for(a, b) \ printf(#a " and " #b ": We love you!\n") int main(void) { message_for(Carole, Debra); return 0; } 参数宏 #define square(x) ((x) * (x)) #define eprintf(format, ...) fprintf(stderr, format, ##__VA_ARGS__) #ifdef DEF == #if define(DEF) #else #endif #ifndef DEF #endif 指令 描述 #define 定义宏 #include 包含一个源代码文件 #undef 取消已定义的宏 #ifdef 如果宏已经定义,则返回真 #ifndef 如果宏没有定义,则返回真 #if 如果给定条件为真,则编译下面代码 #else #if 的替代方案 #elif 如果前面的 #if 给定条件不为真,当前条件为真,则编译下面代码 #endif 结束一个 #if……#else 条件编译块 #error 当遇到标准错误时,输出错误消息 #pragma 使用标准化方法,向编译器发布特殊的命令到编译器中 ~~~ ![](data:image/gif;base64,R0lGODlhAQABAPABAP///wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==) ## 内存管理 ~~~ void *calloc(int num, int size); //分配并初始化为 size void free(void * address); //释放内存 void *malloc(int num) //分配内存 void *realloc(void *address, int newsize); //扩展大小 ~~~ ![](data:image/gif;base64,R0lGODlhAQABAPABAP///wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==) ## 位域 ~~~ struct bs { unsigned a:4; unsigned :0; unsigned b:4; unsigned c:4; } 0填充对其 整个结构体的总大小为最宽基本类型成员大小的整数倍 位域变量类型:int unsigned int signed int ~~~ ![](data:image/gif;base64,R0lGODlhAQABAPABAP///wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==) ## 字节对齐方式 ~~~ #pragma pack(1)//单字节对齐 typedef struct{ uint32 ID; uint32 Num; uint32 Type; uint32 lat; uint32 lng; uint32 alt; uint32 speed; }Waypoint;//Payload_Data #pragma pack(pop) ~~~ ![](data:image/gif;base64,R0lGODlhAQABAPABAP///wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==) ## 大小端 ~~~ //方法1 int a = 1; if(*(char *)(&a) == 1) { //小端 } else { //大端 } //方法2 union Endian { int a; char b; } Endian endian; endian.a = 1; if(endian.b == 1) { //小端 } else { //大段 } ~~~ ![](data:image/gif;base64,R0lGODlhAQABAPABAP///wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==) ## extern C ~~~ #ifdef __cplusplus //告诉编译器,这部分代码按C语言的格式进行编译,而不是C++的 extern "C"{ #endif /*…*/ #ifdef __cplusplus } #endif ~~~ ![](data:image/gif;base64,R0lGODlhAQABAPABAP///wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==)