从五月中旬到今天 , 将近一个星期多两天对着大厂面筋C语言部分的指针和多维数组结构体常见工程化范例工程要求和代码总结和自己的感想结合AI帮助,包括字节PPT腾讯豆包阿里同意前问还有大名鼎鼎的deepseek,一个星期连续每天出至少一篇技术帖的基础上,在今晚12点五十多又完成了这个总结性神文,收录+总结了这一周多收录的代码和自己对常见考点的思路总结现在直接把这篇神文章放在博客大家有喜欢的别忘了给我点赞收藏转发 哈哈哈
还有在开头的最后一句话我直接把这代码和大场面是算法总结的目录直接挂在文末搞了一个链接到时候同步到博客园掘金github还有这些类似的技术网站大家别忘了在这些平台都关注我一波!
引言1:
开发领域三大核心能力需求:
- 硬件级内存管理能力(指针操作)
- 实时系统资源调度能力(多线程/异步)
- 外设交互协议实现能力(结构体/位操作)
一、指针与数组相关知识点扩展
1. 指针运算的更多边界情况
在原代码中已经涉及了部分指针运算,但大厂面试可能会考察更复杂的边界情况。例如,当指针超出数组边界后的运算行为。
#include <stdio.h>
int main() {
int arr[5] = {1, 2, 3, 4, 5};
int *ptr = arr;
// 正常指针运算
ptr = ptr + 2;
printf("正常指针运算结果: %d\n", *ptr);
// 指针超出数组边界
ptr = ptr + 3;
// 此时 ptr 已经超出数组边界,访问该地址是未定义行为
// 不同编译器和环境下可能有不同结果
// 下面的代码仅用于演示,实际编程中应避免
printf("超出边界的指针访问结果(未定义行为): %d\n", *ptr);
return 0;
}
2. 多维数组指针的复杂应用
原代码中使用了二维数组指针,大厂面试可能会考察更高维度数组指针的使用。以下是一个三维数组指针的示例:
#include <stdio.h>
int main() {
int arr[2][3][4] = {
{
{1, 2, 3, 4},
{5, 6, 7, 8},
{9, 10, 11, 12}
},
{
{13, 14, 15, 16},
{17, 18, 19, 20},
{21, 22, 23, 24}
}
};
int (*p)[3][4] = arr;
// 访问三维数组元素
for (int i = 0; i < 2; i++) {
for (int j = 0; j < 3; j++) {
for (int k = 0; k < 4; k++) {
printf("arr[%d][%d][%d] = %d\n", i, j, k, *(*(*(p + i) + j) + k));
}
}
}
return 0;
}
3. 指针数组和数组指针的混合使用
在实际编程中,可能会遇到指针数组和数组指针的混合使用情况。以下是一个示例:
#include <stdio.h>
int main() {
int arr1[3] = {1, 2, 3};
int arr2[3] = {4, 5, 6};
int arr3[3] = {7, 8, 9};
int *ptr_arr[3] = {arr1, arr2, arr3};
int (*arr_ptr)[3] = ptr_arr[0];
// 访问元素
for (int i = 0; i < 3; i++) {
for (int j = 0; j < 3; j++) {
printf("ptr_arr[%d][%d] = %d\n", i, j, ptr_arr[i][j]);
}
}
for (int i = 0; i < 3; i++) {
for (int j = 0; j < 3; j++) {
printf("arr_ptr[%d][%d] = %d\n", i, j, arr_ptr[i][j]);
}
}
return 0;
}
二、内存管理相关知识点扩展
1. 内存池的实现原理
在大厂面试中,可能会考察内存池的实现原理。内存池是一种内存管理技术,用于减少频繁的内存分配和释放带来的开销。以下是一个简单的内存池实现示例:
#include <stdio.h>
#include <stdlib.h>
#define BLOCK_SIZE 1024
#define POOL_SIZE 10
typedef struct MemoryBlock {
struct MemoryBlock *next;
char data[BLOCK_SIZE];
} MemoryBlock;
typedef struct MemoryPool {
MemoryBlock *head;
} MemoryPool;
// 初始化内存池
void init_memory_pool(MemoryPool *pool) {
pool->head = NULL;
for (int i = 0; i < POOL_SIZE; i++) {
MemoryBlock *block = (MemoryBlock *)malloc(sizeof(MemoryBlock));
block->next = pool->head;
pool->head = block;
}
}
// 从内存池分配内存
void* allocate_from_pool(MemoryPool *pool) {
if (pool->head == NULL) {
return NULL;
}
MemoryBlock *block = pool->head;
pool->head = block->next;
return block->data;
}
// 将内存块归还到内存池
void free_to_pool(MemoryPool *pool, void *ptr) {
MemoryBlock *block = (MemoryBlock *)((char *)ptr - offsetof(MemoryBlock, data));
block->next = pool->head;
pool->head = block;
}
// 销毁内存池
void destroy_memory_pool(MemoryPool *pool) {
MemoryBlock *current = pool->head;
MemoryBlock *next;
while (current != NULL) {
next = current->next;
free(current);
current = next;
}
pool->head = NULL;
}
int main() {
MemoryPool pool;
init_memory_pool(&pool);
void *ptr = allocate_from_pool(&pool);
if (ptr != NULL) {
printf("成功从内存池分配内存\n");
free_to_pool(&pool, ptr);
printf("成功将内存块归还到内存池\n");
}
destroy_memory_pool(&pool);
return 0;
}
2. 内存碎片问题及解决方法
内存碎片是内存管理中常见的问题,大厂面试可能会考察对该问题的理解和解决方法。以下是对内存碎片问题的简单解释和一种解决思路:
内存碎片分为内部碎片和外部碎片。内部碎片是指分配给程序的内存块中未被使用的部分,外部碎片是指由于多次分配和释放内存导致的小块空闲内存无法满足大内存需求的情况。
解决方法之一是采用伙伴系统(Buddy System),它通过将内存块按照 2 的幂次方大小进行管理,合并相邻的空闲内存块,减少外部碎片。以下是一个简单的伙伴系统示例代码框架:
#include <stdio.h>
#include <stdlib.h>
#define MAX_LEVEL 10
#define MIN_SIZE (1 << MIN_LEVEL)
typedef struct BuddyNode {
struct BuddyNode *next;
int level;
int used;
} BuddyNode;
typedef struct BuddySystem {
BuddyNode *free_lists[MAX_LEVEL + 1];
char *memory;
} BuddySystem;
// 初始化伙伴系统
void init_buddy_system(BuddySystem *system, size_t size) {
// 初始化空闲链表
for (int i = 0; i <= MAX_LEVEL; i++) {
system->free_lists[i] = NULL;
}
// 分配内存
system->memory = (char *)malloc(size);
if (system->memory == NULL) {
return;
}
// 创建根节点
BuddyNode *root = (BuddyNode *)system->memory;
root->next = NULL;
root->level = MAX_LEVEL;
root->used = 0;
// 将根节点加入空闲链表
system->free_lists[MAX_LEVEL] = root;
}
// 分配内存
void* buddy_allocate(BuddySystem *system, size_t size) {
// 计算所需的最小级别
int level = 0;
while ((1 << level) < size) {
level++;
}
// 查找合适的空闲块
for (int i = level; i <= MAX_LEVEL; i++) {
if (system->free_lists[i] != NULL) {
BuddyNode *block = system->free_lists[i];
system->free_lists[i] = block->next;
// 分割块
while (i > level) {
i--;
BuddyNode *buddy = (BuddyNode *)((char *)block + (1 << i));
buddy->next = system->free_lists[i];
buddy->level = i;
buddy->used = 0;
system->free_lists[i] = buddy;
}
block->used = 1;
return (void *)((char *)block + sizeof(BuddyNode));
}
}
return NULL;
}
// 释放内存
void buddy_free(BuddySystem *system, void *ptr) {
BuddyNode *block = (BuddyNode *)((char *)ptr - sizeof(BuddyNode));
block->used = 0;
int level = block->level;
while (level < MAX_LEVEL) {
// 查找伙伴块
BuddyNode *buddy = (BuddyNode *)((char *)block ^ (1 << level));
if (buddy->level == level && !buddy->used) {
// 合并块
if (buddy < block) {
block = buddy;
}
level++;
// 从空闲链表中移除伙伴块
BuddyNode **prev = &system->free_lists[level - 1];
while (*prev != NULL) {
if (*prev == buddy) {
*prev = buddy->next;
break;
}
prev = &(*prev)->next;
}
} else {
break;
}
}
// 将块加入空闲链表
block->level = level;
block->next = system->free_lists[level];
system->free_lists[level] = block;
}
// 销毁伙伴系统
void destroy_buddy_system(BuddySystem *system) {
free(system->memory);
}
int main() {
BuddySystem system;
init_buddy_system(&system, 1 << MAX_LEVEL);
void *ptr = buddy_allocate(&system, 100);
if (ptr != NULL) {
printf("成功从伙伴系统分配内存\n");
buddy_free(&system, ptr);
printf("成功将内存块归还到伙伴系统\n");
}
destroy_buddy_system(&system);
return 0;
}
三、字符串处理相关知识点扩展
1. 字符串的编码转换
在实际应用中,可能会遇到不同编码格式的字符串转换问题。大厂面试可能会考察对字符串编码转换的理解和实现。以下是一个简单的 ASCII 码和 UTF - 8 编码转换示例:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
// ASCII 转 UTF-8
void ascii_to_utf8(const char *ascii_str, char *utf8_str) {
int i = 0;
int j = 0;
while (ascii_str[i] != '\0') {
if ((unsigned char)ascii_str[i] < 128) {
utf8_str[j++] = ascii_str[i++];
} else {
// 这里简单处理,实际的多字节编码转换更复杂
utf8_str[j++] = 0xC0 | ((ascii_str[i] >> 6) & 0x1F);
utf8_str[j++] = 0x80 | (ascii_str[i] & 0x3F);
i++;
}
}
utf8_str[j] = '\0';
}
// UTF-8 转 ASCII(简单截断)
void utf8_to_ascii(const char *utf8_str, char *ascii_str) {
int i = 0;
int j = 0;
while (utf8_str[i] != '\0') {
if ((unsigned char)utf8_str[i] < 128) {
ascii_str[j++] = utf8_str[i++];
} else {
// 跳过多字节字符
i++;
while ((utf8_str[i] & 0xC0) == 0x80) {
i++;
}
}
}
ascii_str[j] = '\0';
}
int main() {
char ascii_str[] = "Hello, 世界";
char utf8_str[100];
char new_ascii_str[100];
ascii_to_utf8(ascii_str, utf8_str);
printf("ASCII 转 UTF-8: %s\n", utf8_str);
utf8_to_ascii(utf8_str, new_ascii_str);
printf("UTF-8 转 ASCII: %s\n", new_ascii_str);
return 0;
}
2. 字符串的正则表达式匹配
正则表达式是一种强大的字符串匹配工具,大厂面试可能会考察对正则表达式的基本理解和简单实现。以下是一个简单的正则表达式匹配示例,支持 .
和 *
元字符:
#include <stdio.h>
#include <stdbool.h>
bool is_match(const char *s, const char *p) {
if (*p == '\0') {
return *s == '\0';
}
bool first_match = (*s != '\0') && (*s == *p || *p == '.');
if (*(p + 1) == '*') {
return (is_match(s, p + 2)) || (first_match && is_match(s + 1, p));
} else {
return first_match && is_match(s + 1, p + 1);
}
}
int main() {
const char *s = "aab";
const char *p = "c*a*b";
if (is_match(s, p)) {
printf("字符串匹配成功\n");
} else {
printf("字符串匹配失败\n");
}
return 0;
}
四、函数指针相关知识点扩展
1. 函数指针作为回调函数的复杂应用
原代码中涉及了函数指针数组的使用,大厂面试可能会考察函数指针作为回调函数在更复杂场景下的应用。以下是一个简单的事件驱动模型示例,使用函数指针作为回调函数:
#include <stdio.h>
#include <stdlib.h>
// 定义事件类型
typedef enum {
EVENT_BUTTON_CLICK,
EVENT_TIMER_EXPIRE,
EVENT_KEY_PRESS
} EventType;
// 定义事件结构体
typedef struct {
EventType type;
void *data;
} Event;
// 定义回调函数类型
typedef void (*EventHandler)(Event *event);
// 定义事件处理函数
void button_click_handler(Event *event) {
printf("处理按钮点击事件\n");
}
void timer_expire_handler(Event *event) {
printf("处理定时器过期事件\n");
}
void key_press_handler(Event *event) {
printf("处理按键按下事件\n");
}
// 事件分发器
void event_dispatcher(Event *event, EventHandler handlers[]) {
if (event->type < 3) {
handlers[event->type](event);
}
}
int main() {
// 初始化事件处理函数数组
EventHandler handlers[3] = {
button_click_handler,
timer_expire_handler,
key_press_handler
};
// 创建事件
Event event;
event.type = EVENT_BUTTON_CLICK;
event.data = NULL;
// 分发事件
event_dispatcher(&event, handlers);
return 0;
}
2. 函数指针与动态库的结合使用
在大厂面试中,可能会考察函数指针与动态库的结合使用。动态库可以在运行时加载和卸载,使用函数指针可以实现对动态库中函数的调用。以下是一个简单的示例:
#include <stdio.h>
#include <dlfcn.h>
// 定义函数指针类型
typedef int (*AddFunction)(int, int);
int main() {
// 打开动态库
void *handle = dlopen("./libadd.so", RTLD_LAZY);
if (!handle) {
fprintf(stderr, "%s\n", dlerror());
return 1;
}
// 获取函数指针
AddFunction add = (AddFunction)dlsym(handle, "add");
if (!add) {
fprintf(stderr, "%s\n", dlerror());
dlclose(handle);
return 1;
}
// 调用函数
int result = add(3, 4);
printf("3 + 4 = %d\n", result);
// 关闭动态库
dlclose(handle);
return 0;
}
以下是动态库 libadd.so
的实现代码:
// add.c
int add(int a, int b) {
return a + b;
}
编译动态库的命令:
gcc -shared -fPIC add.c -o libadd.so
五、宏与 typedef 相关知识点扩展
1. 宏的条件编译高级应用
原代码中涉及了简单的宏定义和条件编译,大厂面试可能会考察宏的条件编译在更复杂场景下的应用。以下是一个示例,根据不同的编译选项启用不同的功能:
#include <stdio.h>
// 定义编译选项
#define FEATURE_A_ENABLED 1
#define FEATURE_B_ENABLED 0
// 功能 A 的实现
#if FEATURE_A_ENABLED
void feature_a() {
printf("功能 A 已启用\n");
}
#endif
// 功能 B 的实现
#if FEATURE_B_ENABLED
void feature_b() {
printf("功能 B 已启用\n");
}
#endif
int main() {
#if FEATURE_A_ENABLED
feature_a();
#endif
#if FEATURE_B_ENABLED
feature_b();
#endif
return 0;
}
2. typedef 与模板编程的思想
虽然 C 语言没有像 C++ 那样的模板编程,但可以使用 typedef 实现一些类似模板编程的思想。以下是一个简单的示例,使用 typedef 定义不同类型的数组:
#include <stdio.h>
// 定义不同类型的数组
typedef int IntArray[5];
typedef float FloatArray[5];
// 打印数组元素的函数
void print_int_array(IntArray arr) {
for (int i = 0; i < 5; i++) {
printf("%d ", arr[i]);
}
printf("\n");
}
void print_float_array(FloatArray arr) {
for (int i = 0; i < 5; i++) {
printf("%f ", arr[i]);
}
printf("\n");
}
int main() {
IntArray int_arr = {1, 2, 3, 4, 5};
FloatArray float_arr = {1.1, 2.2, 3.3, 4.4, 5.5};
print_int_array(int_arr);
print_float_array(float_arr);
return 0;
}
*附录,2千行源码+详细注释
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>
#include <stdlib.h>
// ??????qsort???é???¤???????
// ====================== ??????é?????é???????? ======================
// 1. é?????é?????????????????§????/??????/????????é?????
void wild_pointer_cause()
{
int a = 10;
int *new_ptr = &a;
// ?????????????????é????????é??
// *new_ptr = 10;
// int *uninit_ptr; // ??????§????é?????é??
// *uninit_ptr = 10; // ???é???????????????é??
int *heap_ptr = (int *)malloc(sizeof(int));
free(heap_ptr); // é????????????????
// *heap_ptr = 20; // ???é??????????????é?????é?????é?????
int arr[5] = {1, 2, 3, 4, 5};
// int *over_ptr = arr + 5; // ??????é????????
// int* yuejie_ptr = arr+10;
// *yuejie_ptr = 200;
// printf("é????????é?????%d\n",*yuejie_ptr);
}
// 2. é?????é??????????????¨???????????¤???????é????¨é???????????
// void wild_pointer_hazard() {
// int* ptr = NULL;
// *ptr = 10; // ??????é???§??????¨??????????é????
// }
// 3. ??????é?????é?????é???????????????ˇ????
void avoid_wild_pointer()
{
int *safe_ptr = NULL; // ???????????é?????NULL
safe_ptr = (int *)malloc(sizeof(int));
if (safe_ptr != NULL)
{
*safe_ptr = 42;
}
free(safe_ptr);
safe_ptr = NULL; // é????????????????????
}
// 4. ??????é??????????¨???????¤???????
void null_pointer_safe()
{
int *p = NULL;
if (p == NULL)
{
p = (int *)malloc(sizeof(int));
// assert(p != NULL);
assert(p != NULL);
// #self VIP ???¨?p!=nULL?????????????????????????????????é???????
*p = 10;
free(p);
// #self ????????é??
p = NULL;
}
}
// 5. ???é??????¤§?°?????????????é??????????°???
void pointer_size()
{
printf("64???????????????int* = %zu?????????char* = %zu??????\n???float?¤§?°????%zu\n",
sizeof(int *), sizeof(char *), sizeof(double *)); // ?????????8 8
}
// ====================== ?????????é???????? ======================
// 6. ???é??????????????????????°????????????é???????????
void pointer_relation()
{
int arr[5] = {1, 2, 3, 4, 5};
int *p1 = arr + 1;
int *p2 = arr + 3;
printf("p1 < p2: %s\n", (p1 < p2) ? "true" : "false"); // true
printf("p1 == arr+1: %s\n", (p1 == arr + 1) ? "true" : "false"); // true
}
// 7. ???é???????????????? - ??¨??????é?????é??????????????
void pointer_arithmetic_warning()
{
int arr[5] = {1, 2, 3, 4, 5};
int *p = arr;
// p -= 1; // ?????????é?????
p += 4; // ????????????????????????????????
printf("?????????é??: %d\n", *p); // 5
}
// 8. ???é???????????????? - ?????¨?????°???é????????
void pointer_arithmetic_application()
{
int arr[5] = {1, 2, 3, 4, 5};
int *p = arr;
for (int i = 0; i < 5; i++)
{
printf("arr[%d] = %d\n", i, *(p + i)); // ?????ˇ???arr[i]
}
}
// ====================== ?????????é???????°??? ======================
// 9. ???é???????°???????????????é??????°??????é?????é?ˇé?????
void array_pointer_question()
{
int arr[5] = {1, 2, 3, 4, 5};
printf("sizeof(arr) = %zu\n", sizeof(arr)); // 20?????°????¤§?°????
// #self ????????????20??? ??????????????
printf("sizeof(arr+0) = %zu\n", sizeof(arr + 0)); // 8??????é???¤§?°????
}
// 10. ???é???????°????????¨??¨??????é??????????????????????????
void array_bound_check()
{
int arr[5] = {1, 2, 3, 4, 5};
int *p = arr;
for (int i = 0; i < 5; i++)
{
printf("%d ", p[i]); // ?????????é??
}
// p[5] = 10; // ?????????é?????
}
// 11. ??°??????é???????¨???????????°????????é??é????????
// #self ??????????????? vip
void array_ptr_application()
{
// int arr[3][3] = {{1, 2, 3}, {4, 5, 6}, {7, 8, 9}};
// int (*row_ptr)[3] = arr; // ??????é????????????????°???
// for (int i = 0; i < 3; i++)
// {
// for (int j = 0; j < 3; j++)
// {
// printf("%d ", (*(row_ptr + i))[j]); // ?????ˇ???arr[i][j]
// }
// }
// #self !!!vip
int arr[3][3] = {{1, 2, 3}, {4, 5, 6}, {7, 8, 9}};
int (*p)[3] = arr;
for (int i = 0; i < 3; i++)
{
for (int j = 0; j < 3; j++)
{
//!!!VIP ˇ???????
printf("1 the numn :%d-%d:%d\n", i, j, *(p + i)[j]);
printf("2 the num: %d -%d : %d\n", i, j, p[i][j]);
}
}
printf("\n");
}
// #self #dachang ?????? ???????????????? ??????vip
void dachang_mianshi1(void)
{
int arr[2][3] = {{1, 2, 3}, {4, 5, 6}};
int (*p1)[3] = arr;
int (*p2)[2][3] = &arr;
printf("%d\n", (*p1)[2]); // ?????3
printf("%d\n", (*p2)[1][2]); // ?????6
}
// ?????????
// p1???????*p1????????????
// p2?????????????????*p2???????????
void dachang_mianshi2(void)
{
int *p1[10]; //???????{-??10??int??????
int (*p2)[10]; // p2???10??int?????????
}
// 12. ??°??????é????????é???????????é???¤§???/????§??????????
void array_ptr_question()
{
int arr[3][3] = {{1, 2, 3}, {4, 5, 6}, {7, 8, 9}};
int (*row_ptr)[3] = arr;
printf("row_ptr?¤§?°?: %zu\n", sizeof(row_ptr)); // 8??????é???¤§?°????
printf("????????????????: %d\n", row_ptr[1][2]); // 6
}
// ====================== ???????????????é????????????? ======================
// 13. ????????é???????????????????¨????????¨??????????????????
void char_ptr_application()
{
// copy string or char* by ptr ????????×?ˇ???
char str1[20] = "Hello";
char *str2 = ", World!";
char *p1 = str1 + strlen(str1); // ??????str1?????
char *p2 = str2;
while (*p2 != '\0')
{
*p1++ = *p2++;
}
*p1 = '\0'; // ?????????????
printf("????????????: %s\n", str1); // Hello, World!
}
// 14. ????????é?????????????????é??????????????????¤???????
// #self vip ?????????????§??????????????
void char_ptr_constant()
{
char *const_str = "abc"; // ?????¨??¨?????????
// #self
const_str[0] = 'A';
printf("\n---->>>>????????????%s\n\n", *const_str);
// const_str[0] = 'A'; // ??????é?????????????????????????
char stack_str[] = "abc"; // ?????¨??¨?????????????????
stack_str[0] = 'A';
}
// 15. ??°??????é????????é????°?????????????????????????????
// #self vip ??????é??
void ptr_array_vs_array_ptr()
{
int arr[3][3];
int *ptr_arr[3]; // ???é????°????????????3???int*?????°???
int (*arr_ptr)[3] = arr; // ??°??????é?????????????????3???int?????°???
// #vip #self
}
// ====================== ???????????????é?????main?????? ======================
// 16. ???é????°??????????????°????????¨???????????°??????
void pointer_array_2d()
{
int *ptr_arr[2];
ptr_arr[0] = (int *)malloc(3 * sizeof(int)); // ??¨??????é????¤?????????
ptr_arr[1] = (int *)malloc(3 * sizeof(int));
ptr_arr[0][0] = 1; // ?¨????????????°??????é??
}
// 18. const???é?????????§????????¤???????
void const_pointer()
{
int val = 10;
const int *cp1 = &val; // ?????????é????????é?????????????????
int *const cp2 = &val; // ???é?????é?????????????????é??
int a = 100;
const int *ptra_1 = &a;
int *const ptra2_2 = &a;
int x = 2100;
const int *ptr1 = &x;
int *const ptr2 = &x;
// *cp1 = 20; // é????
// cp2 = &val; // é????
}
// 19. void???é?????é????¨??????????????
void void_pointer_demo()
{
double d = 3.14;
void *vp = &d;
printf("void???double: %f\n", *(double *)vp); // é???????????????????????
}
// ====================== ??????????°?????°???é?? ======================
// 20. ???é?????é???????¤????????°???
void swap(int *a, int *b)
{
int temp = *a;
*a = *b;
*b = temp;
}
// 21. ??????é?? - ?????¨?????????????????????
void value_pass_application()
{
printf("-->>\nin hte 21 value-pass-func:\n---->>\n");
int x = 5;
void value_pass(int *);
value_pass(&x); // ??????é??
printf("x??????: %d\n", x); // ??????5
}
void value_pass(int *a)
{
*a = 10;
}
// 22. ?????°?????? - ??¨??????é?????????????????¨??????é?????
int global_var = 100;
void global_pass()
{
printf("\n--->>> func22 global-pass!!!\n--->>>\n");
global_var = 200; // ?????????????¨??????é??
}
// ???????????°??????
void test_swap()
{
int a = 5, b = 10;
swap(&a, &b);
printf("??¤??????: a=%d, b=%d\n", a, b); // ??????10, 5
}
void test_global_pass()
{
global_pass();
printf("??¨??????é??: %d\n", global_var); // ??????200
}
// ====================== ??????????????°????????? ======================
// 24. ??????é???????????????????°????????°?????????3???
// #self !!!vip
// ×?????????int (*p)[3] ??×é????
void pass_row_ptr(int (*arr)[3], int rows)
{
for (int i = 0; i < rows; i++)
{
for (int j = 0; j < 3; j++)
{
printf("%d ", arr[i][j]);
}
}
printf("\n");
}
// 25. ?????§???é???????????é????¨????????°??????é?????
void pass_first_ptr(int *arr, int rows, int cols)
{
for (int i = 0; i < rows * cols; i++)
{
printf("%d ", arr[i]);
}
}
// 26. ???????°??????????????????????????é????????
void char_arr_pass(char arr[], int len)
{
int count = 0;
for (int i = 0; i < len; i++)
{
if (arr[i] != '\0')
count++;
}
printf("???????°???é?????: %d\n", count);
}
// ====================== ????????é???????? ======================
// 31. ???é???????° - ????????????????ˇ????????°????
// #self ???ˇ????????????? vip
char *str_copy(const char *src)
{
char *dest = (char *)malloc(strlen(src) + 1);
assert(dest != NULL);
char *p = dest;
while (*src)
{
*p++ = *src++;
}
*p = '\0';
return dest;
}
void test_str_copy()
{
char *copy = str_copy("test");
printf("?¤??????????: %s\n", copy);
free(copy);
}
// 32. ???é???????°???????????????é?????????????????é?????
// #self vip
// char* error_ptr_func() {
// char str[] = "test"; // ??????é??????????°?????????é?????
// return str; // ???é???????????é?????é??
// }
// ====================== ??????qsort????????°?????? ======================
// 33. qsort?q????????????????????????°??°??????
int compare_asc(const void *a, const void *b)
{ // ???????????
return *(int *)a - *(int *)b;
}
int compFunc(const void *a, const void *b)
{
return *((int *)a) - *((int *)b);
}
void qsort_demo()
{
int arr[] = {3, 1, 4, 2};
qsort(arr, 4, sizeof(int), compFunc);
for (int i = 0; i < 4; i++)
{
printf("\n--->>>qsort--->>>\n\n");
printf("%d ", arr[i]); // 1 2 3 4
}
printf("\n");
}
// 34. ?????°???é????°?????????????¨?????????
// #self !!!vip ????????
typedef int (*OpFunc)(int, int);
int add(int a, int b) { return a + b; }
int subtract(int a, int b) { return a - b; }
void func_ptr_array()
{
OpFunc ops[] = {add, subtract};
printf("5+3=%d\n", ops[0](5, 3)); // 8
printf("5-3=%d\n", ops[1](5, 3)); // 2
}
// #self !!!vp
typedef int (*FuncTypeTest)(int, int);
typedef int (*FuncType)(int, int);
int multi(int a, int b)
{
return a * b;
}
int devide(int a, int b)
{
return a / b;
}
void testFuncPtr(void)
{
FuncType funcList[] = {multi, devide};
printf("5*15 = %d \n", funcList[0](5, 15));
printf("5/15 = %d \n", funcList[1](5, 15));
}
// ====================== ??????é??????????° ======================
// 36. é??????????°?????¨?????????é???????°??????
int fibonacci(int n)
{
if (n <= 1)
return n;
return fibonacci(n - 1) + fibonacci(n - 2);
}
void test_fibonacci()
{
printf("fib(5) = %d\n", fibonacci(5)); // ??????5
}
// ====================== ???????????????typedef ======================
// 38. ????????°????????¨???????????°??????
#define MAX(a, b) ((a) > (b) ? (a) : (b))
#define min(a, b) ((a) < (b) ? (a) : (b))
#define CONCAT(a, b) a##b
void macro_usage()
{
int max = MAX(5, 3); // 5
int var12 = CONCAT(var, 12); // ?????????var12
}
// 39. #define???typedef??????????????? vs ???????????????
typedef int IntArray[5]; // ????????°?????????
// #self !!!vip
IntArray a, b;
int a1[5], b1[5];
// #define INT_ARRAY int[5] // é??????????????ˇ??§?é??
void type_compare()
{
IntArray arr1; // ?????????????????????
IntArray arr2; // ?????????????????????
}
// 40. typedef?????¨???
typedef int IntArray[5]; // ????????°?????????
void typedef_usage()
{
IntArray arr; // ?????ˇ??? int arr[5];
arr[0] = 10;
printf("typedef??°???: %d\n", arr[0]);
}
// #self
// 41. ????????????const?????????????????????ˇ???????
const int CONST_NUM = 10; // ???????????????°????
#define MACRO_NUM 10 // ????????????????????????
void const_vs_macro()
{
// CONST_NUM = 20; // é???????const???????????
// MACRO_NUM = 20; // é???????????????????????
}
/// @brief ?ó?§????
/// @param void
// #self : * only attach to the nearest element!!
// !!!!!vip
/// #self
void dachangmianshi3(void)
{
#define PTR_INT int *
typedef int *ptr_int;
PTR_INT a, b;
ptr_int x, y;
printf("--->>> %s %s \n", "int*", "int"); // ??????????????
printf("--->>> %s %s \n", "int*", "int*");
}
// ====================== ???????????????????¤?????????? ======================
// 48. strncpy??????é?????é???????ˇ??????
char *my_strncpy(char *dest, const char *src, size_t n)
{
assert(dest != NULL && src != NULL);
size_t i = 0;
char *tempPtr = dest;
while (i < n && n > 0 && src[i])
{
dest[i] = src[i];
i++;
}
while (i < n)
{
dest[i] = '\0';
// n--;
i++;
}
return tempPtr;
}
void test_strncpy()
{
char dest[10] = {0};
my_strncpy(dest, "hello", 3);
printf("strncpy---?ˇ?ˇ?ˇ?ˇ: %s\n", dest); // ??????"hel"
}
// 47. strncat??????é?????é??????????????
char *my_strncat(char *dest, const char *src, size_t n)
{
// assert(dest != NULL && src != NULL);
// size_t dest_len = strlen(dest);
// for (size_t i = 0; i < n && src[i]; i++)
// {
// dest[dest_len + i] = src[i];
// }
// dest[dest_len + n] = '\0'; // ?????????????
// return dest;
assert(dest != NULL && src != NULL);
size_t len = strlen(dest);
char *res = dest;
size_t i;
for (i = 0; i < n && src[i] != '\0'; i++)
{
dest[len + i] = src[i];
}
dest[i + len] = '\0';
return res;
}
void test_str_cat(void)
{
printf("\n---->>>>>\n strcat??????\n");
// ?????????????ó??????????????#self !!!vip??????????
char dest[10] = {'1', '2', '\0'};
char src[] = {'3', '4', 'a', '\0'};
char *res = my_strncat(dest, src, 3);
printf("--->>> \n str cat func --->>> \n%s", res);
}
// 46. strncmp??????é??????????????
int my_strncmp(const char *s1, const char *s2, size_t n)
{
// assert(s1 != NULL && s2 != NULL);
// for (size_t i = 0; i < n && s1[i] && s2[i]; i++)
// {
// if (s1[i] != s2[i])
// return s1[i] - s2[i];
// }
// return 0;
assert(s1 != NULL && s2 != NULL);
for (size_t i = 0; i < n; i++)
{
char c1 = s1[i] ? s1[i] : '\0';
char c2 = s2[i] ? s2[i] : '\0';
if (c1 != c2)
{
return c1 - c2;
}
}
return 0;
}
void test_strncmp(void)
{
char s1[] = {'1', '2', '3', '5'};
char s2[] = {'1', '2', '3'};
printf("\n--->>>\nstrnCmp??????????\n%d", my_strncmp(s1, s2, 4));
}
// 45. strchr???????????????é?????????°???
char *my_strchr(const char *str, int c)
{
printf("\n___>>>>> in the strchar func!!\n");
assert(str != NULL);
const char *p = str;
while ((*p) != '\0')
{
if (*p == (char)c)
{
return (char *)p;
}
p++;
}
return (char)c == '\0' ? (char *)p : NULL;
}
void test_strchar(void)
{
// #self code robotness 代码健壮性!!!vip
char test[] = {'1', '2', 'a', 'b', 'c', 'f', 'l', '6', '\0'};
char *res = my_strchr(test, '7');
if (!res)
{
printf("not found!!\n");
}
else
{
printf("founded !!!! res is %c \n\n", *res);
}
}
// 44. strstr???????????????é?????????°???
char *my_strstr(const char *haystack, const char *needle)
{
// #self must do it yourself
assert(haystack != NULL && needle != NULL);
if (*needle == '\0')
{
return NULL;
}
while (haystack != NULL && needle != NULL)
{
const char *h = haystack;
const char *n = needle;
while (h && n && h == n)
{
h++;
n++;
}
if (*n == '\0')
{
return (char*)haystack;
}
haystack++;
}
if (*haystack == '\0')
{
return NULL;
}
}
void test_strstr(void)
{
char haystack[] = {'1', 'a', '2', 'b', 'c', '\0'};
char needle[] = {'b', 'c', '\0'};
char* res = strstr(haystack, needle);
printf("-->>>>>>\n now in strstr func, res is :%c \n", (*res));
}
int main(int argc, char *argv[])
{
printf("=== C???¨????é??????????????????????????????? ===\n\n");
// ??????é?????é????????
printf("??????é?????é??????????????:\n");
wild_pointer_cause();
pointer_size();
null_pointer_safe();
printf("\n");
// ?????????é????????
printf("?????????é??????????????:\n");
pointer_relation();
pointer_arithmetic_application();
printf("\n");
// function 1-8
// ?????????é???????°???
// function 9->
printf("?????????é???????°?????????:\n");
// func 9
array_pointer_question();
printf(">>>>>>>> test shuzuPtr!!!\n");
// func 11
array_ptr_application();
printf("\n");
// ???????????????é?????????????
printf("???????????????é???????????????????:\n");
// func 13
char_ptr_application();
// char_ptr_constant();
printf("\n");
// ???????????????é????????
printf("???????????????é????????:\n");
// func 18
const_pointer();
void_pointer_demo();
printf("\n");
// ??????????°?????°???é??
printf("??????????°?????°???é????????:\n");
// func 21
value_pass_application();
// func 22
test_global_pass();
test_swap();
printf("\n");
// ??????????????°?????????
printf("??????????????°???????????????:\n");
// func 24
printf("--->>>in the main: calling func24--->>>\n");
int arr2d[3][3] = {{1, 2, 3}, {4, 5, 6}, {7, 8, 9}};
pass_row_ptr(arr2d, 3);
printf("\n");
// ????????é???????°??????
printf("????????é???????°??????:\n");
test_str_copy();
printf("\n");
// ??????qsort????????°???é????????
printf("??????qsort????????°???é????????:\n");
// func 33
qsort_demo();
func_ptr_array();
// func 34
testFuncPtr();
printf("\n");
// ??????é??????????°??????
// func 36
printf("??????é??????????°??????:\n");
test_fibonacci();
printf("\n");
// ?????????typedef??????
printf("?????????typedef??????:\n");
typedef_usage();
printf("\n");
printf("--->>> \n ?ó?§???? \n");
dachangmianshi3();
// ???????????????????¤?????????°??????
printf("???????????????????¤?????????°??????:\n");
// #self ×??????? str????
test_strncpy();
printf("\n");
test_str_cat();
test_strncmp();
test_strchar();
test_strstr();
printf("=== ?????????????????? ===\n");
return 0;
}