当前位置: 首页 > news >正文

应用——C语言基础知识2

多级指针

1. 什么是二级指针?请举例说明

二级指针:指向指针的指针

int a = 10; int* p = &a; // 一级指针 int** pp = &p; // 二级指针 printf("%d\n", **pp); // 10

2. 如何定义和使用二级指针?

int** pp; // 定义 int* p = malloc(sizeof(int)); pp = &p; // 赋值 **pp = 100; // 使用

函数指针

1. 什么是函数指针?如何定义和使用函数指针?

函数指针:指向函数的指针

// 定义:返回类型 (*指针名)(参数列表) int (*func_ptr)(int, int); // 赋值 int add(int a, int b) { return a + b; } func_ptr = add; // 使用 int result = func_ptr(3, 4); // 7

2. 如何通过函数指针调用函数?

// 直接调用 (*func_ptr)(3, 4); // 简写调用 func_ptr(3, 4);

3. 如何定义和使用指向函数指针的数组?

// 定义函数指针数组 int (*ops[4])(int, int) = {add, sub, mul, div}; // 使用 for(int i = 0; i < 4; i++) { result = ops[i](a, b); }

回调函数

1. 什么是回调函数?应用场景有哪些?

回调函数:通过函数指针调用的函数
应用场景:事件处理、排序比较、线程回调

2. 如何定义和使用回调函数?

// 定义回调类型 typedef void (*Callback)(int); // 使用回调的函数 void process(int data, Callback cb) { // 处理... cb(data); // 调用回调 } // 回调函数 void print_data(int x) { printf("%d\n", x); } // 使用 process(10, print_data);

指针数组与数组指针

1. 什么是指针数组?

// 指针数组:元素是指针的数组 int* arr[3]; // 3个int指针 int a=1,b=2,c=3; arr[0] = &a; arr[1] = &b; arr[2] = &c;

2. 什么是数组指针?

// 数组指针:指向数组的指针 int (*ptr)[3]; // 指向有3个int的数组 int matrix[2][3]; ptr = matrix; // 指向第一行

指针函数与函数指针

1. 什么是指针函数?

// 指针函数:返回指针的函数 int* create_array(int size) { return malloc(size * sizeof(int)); }

2. 指针函数和函数指针的区别

  • 指针函数:返回指针的函数

  • 函数指针:指向函数的指针

结构体与共用体

1. 如何定义和使用结构体指针?

typedef struct { int x, y; } Point; Point p = {1, 2}; Point* ptr = &p; printf("%d\n", ptr->x); // 1

2. 如何将结构体作为函数参数?

// 值传递(拷贝整个结构体) void func1(Point p); // 指针传递(推荐) void func2(Point* p);

3. 结构体的内存对齐

对齐规则:成员按自身大小对齐

struct A { // 大小8字节 char a; // 1字节 int b; // 从第4字节开始 }; // 指定对齐方式 #pragma pack(1) // 1字节对齐

共用体

1. 共用体和结构体的区别

  • 结构体:各成员有独立存储空间

  • 共用体:所有成员共享同一存储空间

2. 共用体的存储特点

union Data { // 大小4字节(最大成员的大小) int i; float f; char str[4]; };

3. 如何用共用体判断大小端?

union EndianTest { int num; char bytes[4]; }; union EndianTest test; test.num = 0x12345678; if(test.bytes[0] == 0x78) { printf("小端\n"); }

位域

1. 什么是结构体位域?

struct { unsigned int flag1 : 1; // 1位 unsigned int flag2 : 3; // 3位 unsigned int flag3 : 4; // 4位 } flags;

2. 位域的应用场景

  • 硬件寄存器映射

  • 协议字段定义

  • 节省内存空间

编译与链接

1. 编译过程的四个阶段

  1. 预处理:处理宏、头文件

  2. 编译:生成汇编代码

  3. 汇编:生成目标文件

  4. 链接:合并目标文件和库

2-5. GCC命令

# 只预处理 gcc -E test.c -o test.i # 只编译(生成汇编) gcc -S test.c -o test.s # 只汇编 gcc -c test.c -o test.o # 链接 gcc test.o -o test

存储类

1. auto存储类

  • 默认存储类,局部变量

  • 作用域:函数内,生命周期:函数执行期间

2. static存储类

static int count = 0; // 保持值,作用域限制

3. extern存储类

extern int global_var; // 引用其他文件的变量

4-5. register存储类

register int i; // 建议编译器存寄存器 // 不保证,不能取地址

6. volatile关键字

volatile int flag; // 告诉编译器每次从内存读取

变量的作用域与生命周期

1. 作用域类型

  • 局部作用域

  • 全局作用域

  • 块作用域

2. 生命周期

  • 局部变量:函数执行期间

  • 全局变量:程序运行期间

3. 静态变量

static int counter = 0; // 只初始化一次,保持值

预处理器

1. 宏定义

#define PI 3.14159 #define MAX(a,b) ((a)>(b)?(a):(b))

2. #include的区别

  • #include <>:系统头文件

  • #include "":用户头文件

3. 避免重复包含

#ifndef HEADER_H #define HEADER_H // 头文件内容 #endif

4. 条件编译

#ifdef DEBUG printf("调试信息\n"); #endif

内存管理

1. malloc使用

int* arr = (int*)malloc(10 * sizeof(int)); if(arr != NULL) { // 使用... free(arr); }

2. malloc和calloc的区别

// malloc:不初始化 int* p1 = malloc(10 * sizeof(int)); // calloc:初始化为0 int* p2 = calloc(10, sizeof(int));

3. 释放内存的重要性

  • 避免内存泄漏

  • 提高资源利用率

4. 堆和栈的区别

特性
分配方式自动手动
大小有限
管理编译器程序员
速度

5-7. 内存问题

  • 内存溢出:超出分配空间

  • 内存泄漏:分配未释放

  • 内存碎片:空间浪费

其他

1. const和#define的区别

  • const:有类型检查,作用域

  • #define:无类型,全局替换

2. sizeof和strlen的区别

char str[] = "hello"; sizeof(str); // 6(包括'\0') strlen(str); // 5

3. 静态变量和局部变量的区别

  • 静态局部变量:保持值,只初始化一次

  • 普通局部变量:每次函数调用重新初始化

数据结构部分

1. 常见数据结构

  • 线性:数组、链表、栈、队列

  • 树形:二叉树、堆、哈夫曼树

  • 图形:邻接表、邻接矩阵

2. 顺序表和链表的区别

特性顺序表链表
存储连续离散
访问O(1)O(n)
插入O(n)O(1)
扩容麻烦容易

3. 单向和双向链表

  • 单向:只有next指针

  • 双向:有prev和next指针

4. 内存泄漏排查

  • 使用valgrind

  • 检查malloc/free配对

  • 使用智能指针(C++)

5. 内存碎片避免

  • 使用内存池

  • 避免频繁分配释放

  • 使用合适的数据结构

6. 查找链表倒数第k个节点

// 快慢指针法 Node* slow = head; Node* fast = head; for(int i=0; i<k && fast; i++) fast = fast->next; while(fast) { slow = slow->next; fast = fast->next; } return slow;

7. 双向链表操作

// 插入 new_node->next = current->next; new_node->prev = current; current->next->prev = new_node; current->next = new_node; // 删除 prev = node->prev; next = node->next; prev->next = next; next->prev = prev; free(node);

8. 判断链表是否有环

// 快慢指针法 Node* slow = head; Node* fast = head; while(fast && fast->next) { slow = slow->next; fast = fast->next->next; if(slow == fast) return true; } return false;

9. 队列和栈的区别

  • 队列:FIFO(先进先出)

  • :LIFO(后进先出)

10. 系统栈和数据结构栈

  • 系统栈:函数调用、局部变量

  • 数据结构栈:后进先出的数据结构

11. 二叉树遍历

// 深度优先 void dfs(Node* root) { if(!root) return; dfs(root->left); dfs(root->right); } // 广度优先(队列实现) void bfs(Node* root) { queue q; enqueue(q, root); while(!empty(q)) { Node* n = dequeue(q); // 处理... enqueue(q, n->left); enqueue(q, n->right); } }

12. 满二叉树节点数

  • 第k层:2^(k-1)个节点

  • 总节点数:2^k - 1

13. 排序算法实现(简要)

14-15. 复杂度分析

  • 时间复杂度:算法执行时间随数据规模增长的趋势

  • 空间复杂度:算法所需内存空间

16. 排序算法复杂度

算法平均时间最坏时间是否稳定
冒泡O(n²)O(n²)
选择O(n²)O(n²)
插入O(n²)O(n²)
快速O(nlogn)O(n²)

17. 二分查找

  • 前提:有序数组

  • 时间复杂度:O(logn)

http://www.jsqmd.com/news/189500/

相关文章:

  • HuggingFace镜像网站加速下载腾讯混元OCR模型的方法
  • 腾讯混元OCR模型在复杂票据识别中的应用效果实测
  • 使用FastStone Capture注册码截图后,用HunyuanOCR提取文字内容
  • 词汇奥术师:以汝之名,铸吾咒文-第1集:卷轴上的第一道光
  • 终极实时BPM分析工具:如何在网页中快速检测音乐节拍
  • 基于Arduino IDE的ESP32开发:超详细版烧录配置说明
  • 华为云WeLink:HunyuanOCR集成到智能会议室系统
  • 联合国文件处理:HunyuanOCR支持六种官方语言混合识别
  • 零代码门槛!腾讯混元OCR网页推理界面让OCR变得如此简单
  • 电力巡检报告生成:杆塔编号识别后关联GIS地理信息系统
  • 一文搞懂腾讯HunyuanOCR:轻量1B参数为何能超越传统OCR方案
  • 边检证件快速核验:HunyuanOCR读取护照签证页信息比对数据库
  • S32DS安装教程:汽车电子开发环境完整指南
  • 1000元以下的激光雷达?马斯克嗤笑,那是即将被淘汰的雷达罢了!
  • 如何进行网站运营?
  • 集体好奇心在团队创新实践中的应用
  • 树莓派项目实现Modbus通信协议:工业自动化通俗解释
  • ESP32 IDF连接AP模式下的异常处理完整指南
  • 如何访问7860端口进行腾讯混元OCR网页推理?详细操作指南
  • LUT调色包与图像增强技术对HunyuanOCR识别精度的影响研究
  • 救命神器8个AI论文写作软件,研究生轻松搞定毕业论文!
  • Smartsheet报表整合:HunyuanOCR提取纸质报表数据填入表格
  • 京东外卖:品质与速度的终极对决 - 智慧园区
  • 环保包装倡议书:响应全球可持续发展趋势
  • 终极实时BPM分析工具:Realtime BPM Analyzer完整指南
  • 游戏本地化破解研究:HunyuanOCR提取未汉化游戏内文本资源
  • VideoDownloadHelper终极教程:三步搞定网络视频下载完整指南
  • OneSignal推送通知:HunyuanOCR识别节日图片触发限时优惠
  • OBS源录制插件深度解析:精准掌控单个视频源录制
  • 使用LwIP协议栈搭建ModbusTCP从站:实战案例