C语言指针使用小记 (深入理解C指针 读后小记)
最近正值过年在家,新年初一,闲暇时间无事可做便把以前看过的书籍整理了一下,顺手也把这本“深入理解C指针”的书重新读了一遍,这本书总体感觉比较简单,但是还是不免有些地方是平时没有想到过或者没有注意到的,这里做下记录以便以后需要时再来查看。
1. 自实现 内存 安全释放函数 safeFree
对空地址释放内存 或者 对已经释放内存的 地址释放内存, 报错。
自实现 内存 安全释放函数:
void safeFree(void **pp)
{
if(pp!==NULL && *pp!=NULL)
{
free(*pp);
*pp=NULL;
}
}
具体:
加入宏定义, 函数调用时不需要显示做类型转换 宏定义的前后两个函数名不能相同,宏定义只是简单的文本替换的预编译
#include <iostream>
#include <malloc.h>
using namespace std;
#define safeFree(p) safeFree_2((void **)&(p))
void safeFree_2(void **p)
{
if(p!=NULL && *p!=NULL)
{
free(*p);
*p=NULL;
}
} int main()
{
int *p, **q;
p=(int *)malloc(sizeof(int));
safeFree(p);
safeFree(p);
p=(int *)malloc(sizeof(int));
q=&p;
safeFree(*q);
safeFree(*q);
return ;
}
2. 指针数组 和 数组指针
3. 函数指针 数组
因为函数的地址可以作为函数指针进行传递, 但是函数本身不可以作为参数传递,所以只存在 函数指针数组 不存在 (数组函数 指针)
第一种形式:
typedef int(*operation)(int, int);
operation operations[]={NULL}; 第二种形式:int (*operations[])(int, int)={NULL};
#include <iostream>
using namespace std;
typedef int (*fptr)(int, int);
int (*operations[])(int, int)={NULL}; int add(int x, int y)
{
return x+y;
}
int substract(int x, int y)
{
return x-y;
}
void initializeOperationsArray()
{
operations['+']=add;
operations['-']=sub;
} int evaluateArray(char opcode, int num1, int num2)
{
fptr operation;
operation=operations[opcode];
return operation(num1, num2);
} int main()
{
initializeOperationsArray();
cout<<evaluateArray('+', , )<<endl;
cout<<evaluateArray('-', , )<<endl;
return ;
}
4. 函数指针 的 互换
typedef int (*fptrToSingleInt)(int);
typedef int (*fptrToTwoInts)(int, int);
int add(int, int); fptrToTwoInts fptrFirst=add;
fptrToSingleInt fptrSecond = (fptrSingleInt)fptrFirst;
fptrFirst = (fptrToTwoInts)fptrSecond;
函数指针类型转换 可能会改变指针长度 或 出错, 不过一般情况下会给出正确结果。(C/C++多标准,不同厂商,编译环境所决定)
同时,无法保证 函数指针 和 数据指针 相互转换后正常工作,如:
void *pv=add;
一般情况下进行函数指针交换 可以采用基本函数指针类型。
typedef void(*fptrBase)();
fptrBase basePointer;
fptrFirst=add; basePointer=(fptrToSingleInt)fptrFirst;
fptrFirst=(fptrToTwoInts) basePointer;
C语言指针使用小记 (深入理解C指针 读后小记)的更多相关文章
- 深入理解java虚拟机读后总结(个人总结记录)
1.jvm布局: jdk1.6版本JVM布局分为:heap(堆),method(方法区),stack(虚拟机栈),native stack(本地方法栈),程序计数器共五大区域. 其中方法区包含运行 ...
- 深入理解java虚拟机读后总结
之前看过,很多会遗忘,标记一下,温故知新.(明天的我一定会感谢现在努力的自己. ) 一.运行时数据区域 Java虚拟机管理的内存包括几个运行时数据内存:方法区.虚拟机栈.本地方法栈.堆.程序计数器,其 ...
- 编写高质量代码 改善Python程序的91个建议 (读后 小记)
此书是自己好久之前买的,当时总觉得Python语言中有各种trick, 总是要自己猝不及防的掉入到陷阱之中, 看了一些资料后发现了这本书,感觉很是不错,不过可惜自己平时总是杂事太多,总是找不到整块的时 ...
- 《计算机组成与体系结构:性能设计》读后小记 12、CPU的结构和功能
一.CPU组成 1.组成: ALU:算术逻辑单元,完成数据的实际计算或处理 控制器:控制数据的移入移出CPU 寄存器:由一组存储位置极小的内部存储器组成 CPU内部总线:在各寄存器和ALU之间传送数据 ...
- C语言重点——指针篇(一文让你完全搞懂指针)| 从内存理解指针 | 指针完全解析
有干货.更有故事,微信搜索[编程指北]关注这个不一样的程序员,等你来撩~ 注:这篇文章好好看完一定会让你掌握好指针的本质 C语言最核心的知识就是指针,所以,这一篇的文章主题是「指针与内存模型」 说到指 ...
- 关于C语言的指针数组与指针数组的个人理解
一.指针数组与指针数组 1,指针数组 顾名思义,即一个元素全部是指针的数组,其形式与普通数组相似,形式如 *a[N]. 在理解指针数组的使用方式前,我先来说下我个人对数组的理解. 比如一维整形数组(形 ...
- C语言指针的理解以及指针的指针的理解
指针指向的是内存地址编号,内存地址编号指向的是对应的内容. 我们需要一个变量,来储存内存地址编号,这个变量的值是一个内存地址编号,但是我们可以通过修改变量的值,来不断的改变内存地址编号. 但是,我们如 ...
- C语言学习笔记之成员数组和指针
成员数组和指针是我们c语言中一个非常重要的知识点,记得以前在大学时老师一直要我们做这类的练习了,但是最的还是忘记了,今天来恶补一下. 单看这文章的标题,你可能会觉得好像没什么意思.你先别下这个 ...
- 深入理解C指针之二:C内存管理
原文:深入理解C指针之二:C内存管理 内存管理对所有程序来说都很重要.有时候内存由运行时系统隐式的管理,比如为变量自动分配内存.在这种情况下,变量分配在它所处的函数的栈帧上(每个函数都有它自己的栈帧, ...
随机推荐
- Ubuntu 关闭防火墙
关闭防火墙:service iptables stop
- c++ 查找容器中符合条件的元素,并返回iterator(find_if)
#include <iostream> // std::cout #include <algorithm> // std::find_if #include <vecto ...
- windows服务部署
1.新建windows服务项目 2.编辑业务代码 我这里只写2句记录文本的测试代码 using System; using System.IO; using System.ServiceProcess ...
- table maker's delimma
table maker's delimma是计算机浮点数精度的一个问题. 浮点数的表示方式 计算机能表示的数字都是有理数,所有的有理数都可以归结为下面的模式:1.@@@ × 2#### 其中,@@@ ...
- WPF使用Webbrowser操作网页的主要代码
1,引用mshtml.dll using mshtml; 2,获取元素属性值 IHTMLDocument2 doc2=(IHTMLDocument)webbrowser1.Document; IHTM ...
- English trip -- VC(情景课)9 A Get ready
She is doing homwork He is doing laundry He is drying the dishes She is making lunch She is making t ...
- English trip -- VC(情景课)5 Around Town
Around Town 城市周围 Talk about the picture 看图说话 sentences Where are you? I'm in the Meten classroom. ...
- js下载图片
DownloadImgZP = imgPath => { const image = new Image(); // 解决跨域 Canvas 污染问题 image.setAttribute('c ...
- python-day17--列表推导式,生成器表达式
# for i in range(100):# print(i*i) 列表推导式: # l =[i*i for i in range(100)]# print(l) # l = [{'name':'v ...
- ** exception error: no match of right hand side value
错误发生的情况是模式匹配失败.对于badmatch异常,很难找到单一的原因,但经常性的原因是你无意间尝试绑定已绑定过的变量.