TreeMind树图在线AI思维导图
当前位置:树图思维导图模板资格考试计算机C语言知识点思维导图

C语言知识点思维导图

  收藏
  分享
免费下载
免费使用文件
U332074408 浏览量:362023-04-18 10:57:01
已被使用5次
查看详情C语言知识点思维导图

C语言知识点

树图思维导图提供 C语言知识点 在线思维导图免费制作,点击“编辑”按钮,可对 C语言知识点  进行在线思维导图编辑,本思维导图属于思维导图模板主题,文件编号是:8bb448fca6d241d8d0096adcb6cd2e00

思维导图大纲

C语言知识点思维导图模板大纲

1、基础

1、数据类型

基本类型

整型

int、short、long、unsigned int、unsigned short、unsigned long

实型

float、double、long double

字符型

char

构造类型

数组

结构体

共用体

枚举

指针类型

空类型

自定义类型

2、常量

在程序执行过程中值不发生改变的量叫做常量

整型常量

如:int a = 10; short s = 20; unsigned long = 65535;等

实型常量

如:float f = 3.1415f;

字符常量

只能使用单引号将单个字符包括进来

字符串常量

由0-多个字符组成

符号常量

用标识符表示的常量,例如:define PI 3.1415926

2、运算符

位运算符

&

都是1结果为1,有一个为0结果为0

|

只要有一个为1,结果为1,两个为0,结果为0

~

~1为0,~0为1

^

相同为0,不同为1

<<

将二进制位全部左移若干位,左边的二进制位丢弃,右边的补0

>>

将二进制为全部右移若干位,右边的二进制位全部丢弃,左边负数补1,正数补0

https://blog.csdn.net/weixin_45743799/article/details/104531619

3、二进制

为什么计算机中全部都是用二进制?

数据在磁盘或者内存中最本质上是二进制,不同的编码集(ASCII、UTF8、GB2312)解析出来的字符是不一样的

5_蚂蚁软件C语言课件.pptx

2、分支结构

1、顺序结构

2、选择结构

3、循环结构

3、数组

1、数组声明&初始化

2、排序算法

插入排序

思想:将第一待排序序列第一个元素看做一个有序序列,把第二个元素到最后一个元素当成是未排序序列。 从头到尾依次扫描未排序序列,将扫描到的每个元素插入有序序列的适当位置。(如果待插入的元素与有序序列中的某个元素相等,则将待插入元素插入到相等元素的后面。) #include <stdio.h> #define LEN 5 int a[LEN] = {10, 5, 2, 4, 7}; void insertion_sort(void) { int i, j, key; for (j = 1; j < LEN; j++) { printf("%d, %d, %d, %d, %d\n", a[0], a[1], a[2], a[3], a[4]); key = a[j]; i = j - 1; while (i >= 0 && a[i] > key) { a[i + 1] = a[i]; i--; } a[i + 1] = key; } printf("%d, %d, %d, %d, %d\n", a[0], a[1], a[2], a[3], a[4]); } int main(void) { insertion_sort(); return 0; }

冒泡排序

思想:升序时,第一次:将最大的值放到数组的最后一个;第二次:将次大值放到数组的倒数第一个位置 void bubble(int arr[],int n) { int i ,j ,tmp; for(i =0;i < n-1;++i) { for(j =0; j < n-i-1;++j) { if(arr[j]>arr[j+1]) { tmp = arr[j]; arr[j] = arr[j+1]; arr[j+1] = tmp; } } } }

选择排序

思路:选一个数字和后边的数字进行依次比较,记录本次最小下标后,内层循环完成后再进行交换: void select (int arr[],int n) { int i ,j,min,tmp; for(i = 0 ;i < n-1;++i) { min = i; for(j = i+1;j < n;++j) { if(arr[min]>arr[j]) { min = j; } } if(i!=min) { tmp = arr[i]; arr[i] = arr[min]; arr[min] = tmp; } } }

快速排序

1、选定一个数字,作为中心点

2、将小于中心点的数字放在左边

3、将大于中心点数字的放在右边

4、对左右子序列重复1-3步

核心思想: 1、选择中心点(一般情况下选择第一个点) 2、将大于中心点值的元素放在中心点的右侧,右侧的点称为右子序列 3、将小于中心点值的元素放在中心点的左侧,左侧的点称为左子序列 4、分别对左右子序列进行上述1-3步的排序 void quick_sort(int arr[], int left, int right) { if (left >= right) return; int l = left; int r = right; int key = arr[l]; while (l < r) { while (l < r && arr[r] >= key) { r--; } if (l < r) { arr[l] = arr[r]; l++; } while (l < r && arr[l] <= key) { l++; } if (l < r) { arr[r] = arr[l]; r--; } } arr[l] = key; quick_sort(arr, left, l - 1); quick_sort(arr, r + 1, right); } int main() { int nums[] = {8, 4, 3, 2, 10, 2}; int len = sizeof(nums) / sizeof(int); quick_sort(nums, 0, len-1); for (int i = 0; i < len; ++i) { printf("%d ", nums[i]); } }

归并排序

归并操作的工作原理如下: 第一步:申请空间,使其大小为待排序数列排序,该空间用来存放合并后的序列 第二步:设定两个指针,最初位置分别为两个已经排序序列的起始位置 第三步:比较两个指针所指向的元素,选择相对小的元素放入到合并空间,并移动指针到下一位置 重复步骤3直到某一指针超出序列尾 将另一序列剩下的所有元素直接复制到合并序列尾 稳定性 : 稳定 时间复杂度 : O(N*logN) 空间复杂度 : O(N)

#include<stdio.h> #include<stdlib.h> #include<time.h> #define N 100 void dealMergeSort(int* src, int* tmp, int start, int end) { if (start >= end) {//前后指针交替, 已经二分完毕 return; } int mid = (start + end) / 2; dealMergeSort(src, tmp, start, mid); dealMergeSort(src, tmp, mid + 1, end); int a = start;//分后前一部分数组的起始坐标 int b = mid + 1;//分后后一部分数组的起始坐标 int c = start;//临时数组起始坐标, 将存储前后两个有序数组归并后的有序数组 while (a <= mid && b <= end) { if(src[a]<src[b]){ tmp[c] = src[a]; ++a; } else { tmp[c] = src[b]; ++b; } ++c; } //循环跳出时不一定左右两个有序数组同时遍历结束 , 但未遍历完的一个数组盛夏的肯定是比另一个遍历完的数组最大值还大的有序数列 //直接给临时数组tmp //以下两个for循环只进一个 for (; a <= mid; ++a,++c) { tmp[c] = src[a]; } for (; b <= end; ++b, ++c) { tmp[c] = src[b]; } //将存在临时数组中的合并的有序数列再给待排序数组src for (int i = start; i <= end; ++i) { src[i] = tmp[i]; } } void MergeSort(int* src, int size) { int* tmp = (int*)malloc(size * sizeof(src[0])); dealMergeSort(src, tmp, 0, size - 1); free(tmp); } void PrintArray(int* src, int size) { for (int i = 0; i < size; ++i) { printf("%d ", src[i]); } putchar('\n'); } int main() { srand((unsigned int)time(0)); int src[N]; int src1[10] = { 8,7,10,2,3,5,6,1,4,9 }; for (int i = 0; i < N; ++i) { src[i] = rand() % N + 1; } //printf("排序前:\n"); //PrintArray(src, N); MergeSort(src, N); MergeSort(src1, 10); PrintArray(src1, 10); //printf("排序后:\n"); PrintArray(src, N); system("pause"); return 0; }

二分法查找

前提是数组必须是有序的,使用二分查找速度会快很多 int main() { int arr[10] = { 1,2,3,4,5,6,7,8,9,10 }; int sz = (sizeof(arr) / sizeof(arr[0])); int left = 0; int right = sz - 1; int num = 7; while (left <= right) { int mid = (left + right) / 2; if (arr[mid] < num) { left = mid + 1; } else if (arr[mid] > num) { right = mid - 1; } else { printf("找到了,下标是:%d", mid); break; } } if (left > right) { printf("没有找到"); } return 0; }

内存管理

https://blog.csdn.net/qq_41070511/article/details/114059719

五大分区

代码区

存放代码,不允许修改,但可以执行(类似于常量存储区,不可修改但可以执行)

全局/静态存储区

全局和静态变量被分配到同一个内存中

未初始化静态全局区(bss段)

静态变量(定义变量时,前面添加static修饰),或者全局变量,没有初始化,存在此区

初始化的静态全局区(data段)

全局变量、静态变量、赋过初值的,存放在此区

动态申请的内存,由程序员申请并释放,如果不及时释放会造成内存泄漏

由编译器自动维护,在不需要时自动清除,存放局部变量,函数参数及方法地址等。

常量存储区

存放常量,不允许修改

C程序编译过程

linux C编译过程.png

内存函数

malloc

在堆中开辟一块size大小的内存空间

申请内存失败时,返回为NULL,所以一定要进行判断是否为NULL,否则程序会执行异常

执行一次,申请的内存是连续的。如果多次malloc申请内存,第一次和第二次申请的内存不一定是连续的

申请的内存返回值为void*,所以使用时需要进行强制类型转化

calloc

在堆中开辟一块n个长度为size的练习内存空间数组

realloc

改变ptr指针指向空间大小

free

使用由指针ptr指向的内存区,释放内存

free函数只能释放堆区的空间,其他区域的空间无法使用free

为了防止野指针,会在free完毕之后对申请的指针赋为NULL

malloc等内存操作函数.txt

头文件在stdlib.h中

memset

函数原型:void *memset(void *s, int ch, size_t n);

作用:将malloc动态申请的内存的随机数初始化为指定的值

头文件:string.h

内存泄漏

概念:首地址丢了,找不到,再也没法使用了 ,也没法释放了,这块内存就被泄露了。

案例:

1: int *pOld = (int*)malloc(sizeof(int)); int *pNew = (int*)malloc(sizeof(int)); pOld = pNew; free(pOld) //free(pOld)释放的是pOld所指向的内存空间即原来pNew,但pOld原来指向的内存空间还没有被释放。

2: int main() { char *p; p = (char *)malloc(100); p = "hello world"; // p指向其他地方,把字符串的首地址赋给p;这样子导致原本堆区的空间找不到了 //从此刻起,再也找不到申请的100个字节的空间,动态申请的100个字节被泄漏了 return 0; }

3: void test1() { char *p; p =(char *)malloc(100); //接下来,可以用p指向内存了 , //... //没有释放,没有返回,这样导致这个函数执行完后不知道这个申请的内存空间在哪了 } void main() { //每次用一次fun泄露100个字节 test1(); test1(); }

4、函数

存储类型

动态存储

auto

register

静态存储

static

局部变量

静态局部变量

被分配到全局区,整个程序生命周期中都存在,不过只能被局部变量访问

局部变量和形参

被分配到栈中,函数调用完成后会被释放内存

局部函数

只能在.c文件中访问,其他.c文件不能访问

extern

全局变量

在多个文件中可以使用这个全局变量,默认不加extern也是全局变量

如果在全局变量定义之前想使用此全局变量,可以在使用时使用extern进行声明(如:extern int num 并不分配内存空间)

全局函数

在多个文件中可以使用这个全局函数,默认不加extern也是全局变量

是指在程序运行期间根据需要进行动态的分配存储空间的方式

是指在是在程序编译期间分配固定的存储空间

函数分类

内部函数

即使用static修饰的函数,只能在所定义的.c中函数调用

好处:避免了函数重名,因为内部函数只在.c文件中使用,所以不会在多个文件中重名

外部函数

使用extern修饰的函数,默认不加extern的函数都是外部的, 在所有地方都可以调用

可以将函数原型写到.h文件中,在别的文件中想调用此函数时,引用头文件即可完成调用。

5、指针

常量指针和指针常量

https://blog.csdn.net/qq_42695024/article/details/115272377

const与define区别: 1、define是预编译指令,只是对值进行简单的替换,不能进行类型检查 2、编译器通常不为普通const常量分配存储空间,而是将它们保存在符号表中,这使得它成为一个编译期间的常量,没有了存储与读内存的操作,使得它的效率也很高。 3、定义数组长度时,只可以用define,不能使用const 类型的变量进行定义。

1、修饰基本数据类型时:表示num的值不能被修改

1、以下两种方式是一样的: const int num=10; int const num=10; 2、char *p = "china"; p[2] = 'a';//编译错误

2、修饰指针类型时:

常量指针,不能改变指向存储单元的值,但可以修改指针的指向

int b=1; const int *a = &b; //常量指针 *a = 2;//错误,不能通过指针变量a来修改变量b的值

指针常量,不能改变指针的地址,指向的存储单元值可以修改

int b=1; int * const a = &b; //指针常量

既不能修改值也不能修改地址的写法: int b = 1; const int *const a = &b;

函数指针和指针函数

指针函数

指的是一个函数的返回值为指针类型

注意:局部变量的地址以及局部变量指针不能返回,否则结果可能出现问题

函数指针

指的是函数的入口地址(存储在代码区中的代码)

1、c语言在编译时,为每一个函数都设置了一个入口地址,该地址就是函数指针

2、通过函数指针可以调用它所指向的函数

3、函数指针的定义、初始化及调用

int getMax(int x,int y){ return x > y? x:y; } int main(){ //定义函数指针 int (*p)(int a,int b); //int (*p)(int,int); //int (*p)();//这种方式不建议使用,因为不好理解 //函数指针的初始化 p = getMax; //函数指针的调用 int ret = p(10,20); //int ret = getMax(10,20); //int ret = *p(10,20);//这种方式不建议使用,会增加内存消耗 printf("%d ",ret); }

函数指针数组

calc.c

回调函数

概念:通过函数指针调用的函数(回过头来调用函数)

把函数指针作为函数参数传递给另外一个函数,当这个指针被用来调用其所指向的函数时,我们就说这是回调函数

回调函数不是由该函数的实现方直接调用,而是在特定的事件或者条件发生时由另外一方调用,用于对该事件或者条件进行响应

回调函数的实现流程

1、定义一个回调函数

2、提供函数调用的另一方在初始化时,将回调函数的函数指针传递给调用者

3、当特定的事件或条件发生的时候,调用者使用函数指针调用所指向的回调函数对事件进行处理。

案例

leader.c

teacher.c

teacher.h

优点

维护性好

void*(通用指针、万能指针)

无类型指针,指针是一个地址,一般有两个属性,一个是地址,一个是长度,void*只有地址,没有长度(因为它没有类型,不知道一次读取多少个字节)

例如: int a = 10; void *p = &a;

使用场景: 1、传参:通用类型 ,可以作为函数模板,链表等参数的通用参数。在使用时,只需要强制类型转换就可以。 2、返回值:有很多系统函数,例如malloc返回值不太清楚应该返回什么类型的指针给程序员,故返回为void*,在使用时由程序员强制类型转换为需要的类型 3、void*作为函数指针 4、内存函数操作时,例如: void * memcpy ( void * dest, const void * src, size_t num ); memcpy() 会复制 src 所指的内存内容的前 num 个字节到 dest 所指的内存地址上。 memcpy() 并不关心被复制的数据类型,只是逐字节地进行复制,这给函数的使用带来了很大的灵活性,可以面向任何数据类型进行复制。

注意事项:1、如果要通过void*指针去获取所指向的变量值时,需要先将void*强制类型转化为和变量类型相同的类型指针后再进行取值,否则会出错 2、任何void*都可以直接赋值给void*,且无须进行强制类型转换

二级指针

二级指针也是一个普通的指针变量,只是它里面保存的值是另外一个一级指针的地址,也称为指针的指针

https://blog.csdn.net/weixin_42616791/article/details/106737245

指针与数组

int a[10], *pa; pa=a; pa是一个可以变化的指针变量,而a是一个常数。因为数组一经被说明,数组的地址也就是固定的,因此a是不能变化的,不允许使用a++、++a或语句a+=10,而pa++、++pa、pa+=10则是正确的

数组指针和指针数组

指针数组

指针的数组,数组的所有元素都是指针类型

定义形式:int *a[10]; 说明:[]的优先级高于*,该定义形式应该理解为:int * (a[10]);括号里面说明a是一个数组,包含了10个元素,括号外面说明每个元素的类型为int *。

样例1: int main(){ char *str[3] = { "123", "456", "789" }; printf("%s\n%s\n%s\n", str[0], str[1], str[2]); /* 运行结果: 123 456 789 */ return 0; }

样例2: /* * 指针数组的使用demo * 指针数组:指的是数组中的每一个元素都是指针(地址) */ int main() { int a = 1, b = 2, c = 3; //定义一个指针数组 int *arr[3] = {&a, &b, &c};//也可以不指定长度,直接写作 int *arr[] //parr 是指向数组 arr 的指针,确切地说是指向 arr 第 0 个元素的指针, //它的定义形式应该理解为int *(*parr),括号中的*表示 parr 是一个指针,括号外面的int *表示 parr 指向的数据的类型。 //arr 第 0 个元素的类型为 int *,所以在定义 parr 时要加两个 *。 int **parr = arr; printf("%d, %d, %d\n", *arr[0], *arr[1], *arr[2]);//1, 2, 3 printf("%d, %d, %d\n", **(parr+0), **(parr+1), **(parr+2));//1, 2, 3 return 0; }

数组指针

数组的指针,指针存放着一个数组的首地址

定义形式:int (*p)[10] 说明:括号中的*表明 p 是一个指针,该指针变量保存的是一个数组的首地址,它指向一整个数组(),数组的类型为int[10],这正是 a 所包含的每个一维数组的类型

一维数组指针: int main(void) { char a[5]={'A','K','C','G','L'}; char (*p)[5]=&a;//&a代表的是整个数组的首地址 //char (*p)[5]=a;这样是错误的,因为a代表第一个元素的首地址 printf("%c %c %c",**p,*(*p+1),*(*p+3));//输出:A K G return 0; } 说明:a代表的是第一个元素的地址,即:&a[0],而&a代表的是整个数组的地址。a+1代表的是下一个元素的地址,即&a[1],而&a+1代表的是向后移动5个字节的地址。这里为什么用的二级指针呢?因为p=&a,*p即为第一个元素的地址,再**p即输出了第一个元素。同理,*(*p+1),*(*p+3)输出第二个元素,第四个元素。

二维数组指针:(例子:https://blog.csdn.net/HelloNiGeSB/article/details/51705317) 二维数组用行指针定义 p++操作会使p指向下一行的首地址,这是因为p是行指针,指向的是一行。我们可以用sizeof(*p)测试p指向的内容的大小: #include <stdio.h> int main() { int a[3][4] = { {0, 1, 2, 3}, {4, 5, 6, 7}, {8, 9, 10, 11} }; int(*p)[4];//p指向数组 a 的开头,也即第 0 行;p+1前进一行,指向第 1 行。 int i,j; p=a; for(i=0; i<3; i++) { for(j=0; j<4; j++) printf("%2d ",*(*(p+i)+j));//*(*(p+i)+j)表示第 i 行第 j 个元素的值。 printf("\n"); } /* 0 1 2 3 4 5 6 7 8 9 10 11 */ return 0; }

指向数组和指向数组首元素区别

指向数组和指向数组首元素的地址是两码事,概念上是不一样的

int arr[3]; int *p = arr; p指针指向数组第0个元素的地址

int arr[10]; int (*p)[] = &arr; p指针指向整个数组,它与指向一个元素的指针不同的概念 p指针指向数组中的10个整数。由于[]的优先级高于*,为防止定义指针数组,应加小括号。p的类型是“指向数组中10个整数的指针”。 指向数组第0个元素的指针和指向整个数组的指针完全不同。它们的类型不同,当p为int型指针,p++移动4个字节;当p为int (*p)[10]型指针时,p++移动40个字节

int main() { //一维数组 int a[5] = { 1, 2, 3, 4, 5 }; //步长为5的数组指针,即数组里有5个元素 int (*p)[5]; //把数组a的地址赋给p,则p为数组a的地址,则*p表示数组a本身 p = &a; //%p输出地址, %d输出十进制 //\n回车 //在C中,在几乎所有使用数组的表达式中,数组名的值是个指针常量,也就是数组第一个元素的地址,它的类型取决于数组元素的类型。 printf("%p\n", a); //输出数组名,一般用数组的首元素地址来标识一个数组,则输出数组首元素地址 printf("%p\n", p); //根据上面,p为数组a的地址,输出数组a的地址 printf("%p\n", *p); //*p表示数组a本身,一般用数组的首元素地址来标识一个数组 printf("%p\n", &a[0]); //a[0]的地址 printf("%p\n", &a[1]); //a[1]的地址 printf("%p\n", p[0]); //数组首元素的地址 *p+0 printf("%d\n", **p); //*p为数组a本身,即为数组a首元素地址,则*(*p)为值,当*p为数组首元素地址时,**p表示首元素的值1 printf("%d\n", *p[0]); //根据优先级,p[0] 表示首元素地址,则*p[0]表示首元素本身,即首元素的值1 printf("%d\n", *p[1]); //*(p+1)为一个绝对值很大的负数,不表示a[1]...表示什么我还不知道 //将二维数组赋给指针 int b[3][4]; int(*pp)[4]; //定义一个数组指针,指向含4个元素的一维数组 pp = b; //将该二维数组的首地址赋给pp,也就是b[0]或&b[0],二维数组中pp=b和pp=&b[0]是等价的 pp++; //pp=pp+1,该语句执行过后pp的指向从行b[0][]变为了行b[1][],pp=&b[1] return 0; }

二维数组与指针

行地址: a:表示第1行的行地址 &a[0]:表示第1行的行地址 &*(a+0) &a[1]:表示第2行的行地址 &*(a+1) 列地址: a[0]:表示第1行第1列的列地址 *(a+0) a[1]:表示第2行第1列的列地址 *(a+1) *a:拿到的是第1行第1列的列地址 *(a)+1:拿到的是第1行第2列的列地址 *(a+1)+1:拿到的是第2行第2列的列地址

行指针&列指针.png

1、每行的行地址与每行第1列地址是相同的,虽然值相同,但是两者是不一样的含义。行地址代表的是行的地址用来确定第几行,而列地址用来表示某行某列的地址。

二维数组遍历方式

6、结构体&联合体

6.1结构体初始化.txt

大小端

https://blog.csdn.net/weixin_45137562/article/details/115047607

大小端的判断

联合体是能干什么

柔性数组

多文件

调试程序

gdb:https://note.youdao.com/s/BBGbL6c3

cmake:https://note.youdao.com/s/BBGbL6c3

7、文件

fopen

fclose

fflush

ftell

feof

fgets

fputs

fprintf

fseek

frewind

fread

fwrite

系统函数

c语言函数大全:https://zhuanlan.zhihu.com/p/451192455

随机数

http://c.biancheng.net/view/2043.html

sprintf(stdio.h)

int sprintf(char *string, char *format [,argument,...]); 参数说明: string-- 这是指向一个字符数组的指针,该数组存储了 C 字符串。 format-- 这是字符串,包含了要被写入到字符串 str 的文本。它可以包含嵌入的 format 标签,format 标签可被随后的附加参数中指定的值替换,并按需求进行格式化。format 标签属性是%[flags][width][.precision][length]specifier [argument]...:根据不同的 format 字符串,函数可能需要一系列的附加参数,每个参数包含了一个要被插入的值,替换了 format 参数中指定的每个 % 标签。参数的个数应与 % 标签的个数相同。 功能: 把格式化的数据写入某个字符串缓冲区。 返回值: 如果成功,则返回写入的字符总数,不包括字符串追加在字符串末尾的空字符。如果失败,则返回一个负数。 sprintf 返回以format为格式argument为内容组成的结果被写入string的字节数,结束字符‘\0’不计入内。即,如果“Hello”被写入空间足够大的string后,函数sprintf 返回5

sscanf

字符串处理

strstr

strcpy

strncpy

strcat

strtok

strlen

strlwr

strupr

puts

gets

数据结构&算法

数据结构与算法v1.4.ppt

滑动窗口

滑动窗口leetcode.png

https://blog.csdn.net/Lucky_mzc/article/details/124186667

应用场景

计算出现次数,如最长/最短子串、子数组、子序列等问题,例如:长度最小的子数组

动态规划

https://blog.csdn.net/vx539413949/article/details/124025530

https://zhuanlan.zhihu.com/p/384179122

https://zhuanlan.zhihu.com/p/385698213

什么是动态规划

dynimac programming 简称DP,一般情况下动态规划需要使用数组,所以也叫DP数组。 简单来说,动态规划其实就是,给定一个问题,我们把它拆成一个个子问题,直到子问题可以直接解决。然后把子问题答案保存起来,以减少重复计算。再根据子问题答案反推,得出原问题解的一种方法

动态规划核心思想

动态规划最核心的思想,就在于拆分子问题,记住过往,减少重复计算。

常见问题

什么是段错误

空指针,野指针,万能指针

结构体字节对齐,为什么要进行字节对齐

多文件操作,extern的使用,有参宏和无参宏,static关键的用法,c语言的编译过程,string.h的常用函数,memset,memcpy函数,stoi,atoi函数,scanf函数和gets函数的区别,printf函数和puts函数的区别

堆和栈的区别

五大分区

联合体是能干什么

其他

VC6闪退问题:https://www.jianshu.com/p/6a3fe8e549f4

VC6编译失败问题(win11中不通过).png

32位和64位意味着处理器一次能处理的最大位数

clion中文乱码修改

在clion中ctrl+alt+shift+/

clion中文乱码修改.png

clion常用插件

https://blog.csdn.net/weixin_39510813/article/details/127132572

C&C++常见面试题整理.txt

有参宏和无参宏:https://blog.csdn.net/weixin_36049506/article/details/92798290 typedef和define区别: https://blog.csdn.net/qq_41850194/article/details/105593818 C语言常用函数:https://blog.csdn.net/weixin_43202635/article/details/97672092

柔性数组:https://blog.csdn.net/chenxiyuehh/article/details/88185789

相关思维导图模板

舞蹈思维导图

树图思维导图提供 舞蹈 在线思维导图免费制作,点击“编辑”按钮,可对 舞蹈  进行在线思维导图编辑,本思维导图属于思维导图模板主题,文件编号是:972db6b7c6c77920e111ee48e70af8de

糖类分类思维脑图思维导图

树图思维导图提供 糖类分类思维脑图 在线思维导图免费制作,点击“编辑”按钮,可对 糖类分类思维脑图  进行在线思维导图编辑,本思维导图属于思维导图模板主题,文件编号是:a4fb083960178a1e77d1e149650b11fb