C指针:8 个关于指针的用法
C指针:8 个关于指针的用法一、前言二、八个示例 1. 修改主调函数中的数据 2. 在被调用函数中,分配系统资源 3. 传递函数指针 4. 指向结构体的指针 5
一、前言
二、八个示例
1. 修改主调函数中的数据
2. 在被调用函数中,分配系统资源
3. 传递函数指针
4. 指向结构体的指针
5. 函数指针数组
6. 柔性数组
7. 通过指针来获取结构体中成员变量的偏移量( offsetof 宏定义)
8. 通过结构体中成员变量的指针,来获取该结构体的指针(container_of 宏定义)
三、总结
一、前言
半个月前写的那篇关于指针最底层原理的文章,得到了很多朋友的认可(链接: C语言指针-从底层原理到花式技巧,用图文和代码帮你讲解透彻),特别是对刚学习C语言的小伙伴来说,很容易就从根本上理解指针到底是什么、怎么用,这也让我坚信一句话;用心写出的文章,一定会被读者感受到!在写这篇文章的时候,我列了一个提纲,写到后面的时候,发现已经超过一万字了,但是提纲上还有最后一个主题没有写。如果继续写下去,文章体积就太大了,于是就留下了一个尾巴。
今天,我就把这个尾巴给补上去:主要是介绍指针在应用程序的编程中,经常使用的技巧。如果之前的那篇文章勉强算是“道”层面的话,那这篇文章就属于“术”的层面。主要通过 8 个示例程序来展示在 C 语言应用程序中,关于指针使用的常见套路,希望能给你带来收获。
记得我在校园里学习C语言的时候,南师大的黄凤良老师花了大半节课的时间给我们解释指针,现在最清楚地记得老师说过的一句话就是:指针就是地址,地址就是指针!
二、八个示例
1. 开胃菜:修改主调函数中的数据// 交换 2 个 int 型数据void demo1_swap_data(int *a, int *b){ int tmp = *a; *a = *b; *b = tmp;}
void demo1(){ int i = 1; int j = 2; printf("before: i = %d, j = %d ", i, j); demo1_swap_data(&i, &j); printf("after: i = %d, j = %d ", i, j);}
这个代码不用解释了,大家一看就明白。如果再过多解释的话,好像在侮辱智商。
2. 在被调用函数中,分配系统资源
代码的目的是:在被调用函数中,从堆区分配 size 个字节的空间,返回给主调函数中的 pData 指针。
void demo2_malloc_heap_error(char *buf, int size){ buf = (char *)malloc(size); printf("buf = 0x%x ", buf);}
void demo2_malloc_heap_ok(char **buf, int size){ *buf = (char *)malloc(size); printf("*buf = 0x%x ", *buf);}
void demo2(){ int size = 1024; char *pData = NULL;
// 错误用法 demo2_malloc_heap_error(pData, size); printf("&pData = 0x%x, pData = 0x%x ", &pData, pData);
// 正确用法 demo2_malloc_heap_ok(&pData, size); printf("&pData = 0x%x, pData = 0x%x ", &pData, pData); free(pData);}2.1 错误用法
刚进入被调用函数 demo2_malloc_heap_error 的时候,形参 buff 是一个 char* 型指针,它的值等于 pData 变量的值,也就是说 buff 与 pData 的值相同(都为 NULL),内存模型如图:
在被调用函数中执行 malloc 语句之后,从堆区申请得到的地址空间赋值给 buf,就是说它就指向了这个新的地址空间,而 pData 里仍然是NULL,内存模型如下:
从图中可以看到,pData 的内存中一直是 NULL,没有指向任何堆空间。另外,由于形参 buf 是放在函数的栈区的,从被调函数中返回的时候,堆区这块申请的空间就被泄漏了。
2.2 正确用法
刚进入被调用函数 demo2_malloc_heap_error 的时候,形参 buf 是一个 char* 型的二级指针,就是说 buf 里的值是另一个指针变量的地址,在这个示例中 buf 里的值就是 pData 这个指针变量的地址,内存模型如下:
在被调用函数中执行 malloc 语句之后,从堆区申请得到的地址空间赋值给 *buf,因为 buf = &pData,所以 *buf 就相当于是 pData,那么从堆区申请得到的地址空间就赋值 pData 变量,内存模型如下:
从被调函数中返回之后,pData 就正确的得到了一块堆空间,别忘了使用之后要主动释放。
首页 下一页 上一页 尾页上一篇:北京现代用实力诠释“技术为王”!
无相关信息