C ++ 指针 | 指针与函数_7
函数指针
1、
我们先看一个简单的加法:
#include<iostream>
int Add(int a,int b)
{int c = a + b;return c;
}
int main()
{int x = 2, y = 3;int z = Add(x,y);printf("Sum = %d\n", z);
}
运行结果:
我们使用指针来改变上的代码:
#include<iostream>
int Add(int *a,int *b)
{int c = *a + *b;return c;
}
int main()
{int x = 2, y = 3;int z = Add(&x, &y);printf("Sum = %d\n", z);
}
运行结果:
把返回值,转换成返回地址:
#include<iostream>
int *Add(int* a, int* b)
{int c = (*a) + (*b);return &c;
}
int main()
{int a = 2, b = 3;int* ptr = Add(&a, &b);printf("Sum = %d\n", *ptr);
}
运行结果:
注意:
(1)
int *Add(int* a, int* b)
{int c = (*a) + (*b);return &c;
}
这里的函数Add()前面加了个 *,代表返回指向整数的指针。
上面的代码运行正确,其实有个逻辑错误。
我们来继续看一个例子,我们在 mian()函数 增加一个打印 " hello world "的函数。
#include<iostream>void helloworld()
{printf("hell world!");
}
int *Add(int* a, int* b)
{int c = (*a) + (*b);return &c;
}int main()
{int a = 2, b = 3;int* ptr = Add(&a, &b);helloworld();printf("Sum = %d\n", *ptr);
}
运行结果:
注意:
" hello world!" 可以打印,但 值 现在不能打印了。为什么? 这是因为内存栈的一个问题。怎么说?
用程序的运行来看内存变化:
首先我们的代码是 在内存栈中建立了main()函数,下面就会有变量a,b,还有*ptr,好了,然后开始调用函数Add()函数,内存的栈的位置又划出新的内存来提供给Add()函数,它有指针变量 *a,*b,还有c,而*a ,*b指向main()函数的a和b的值,然后相加得c,输出c的地址。okay,这时程序又回来main()函数,之前的Add()函数已内存释放,我们开始执行helloworld()函数,内存栈又要给hellworld()函数提供内存,这时内存栈提供的内存的位置是之前Add()函数的内存位置,也就是说ptr目前还是指向c的值,但是helloworld()把Add()之前的内存位置给覆盖了,而这时Add()返回的c的地址已经被清空了。所以导致输出提示错误。
我们需要使用 malloc 来解决这个问题:
#include<iostream>void helloworld()
{printf("hell world!\n");
}
int *Add(int* a, int* b)
{int* c = (int*)malloc(sizeof(int));*c = (*a) + (*b);return c;
}int main()
{int a = 2, b = 3;int* ptr = Add(&a, &b);helloworld();printf("Sum = %d\n", *ptr);
}
运行结果:
2、
把函数作为地址:
#include<iostream>int Add(int a,int b)
{return a+b;
}int main()
{int c;int (*p)(int,int);p = &Add;c = (*p)(2,3);printf("a + b = %d\n", c);
}
运行结果:
非常酷,我们只是使用了一个函数指针来引用一个函数。
注意:
(0)
int (*p)(int,int);
因为我要指向Add(int a, int b)函数,这个函数有两个整型类型,我们这里我们必须和它一致,否则运行出错。
另外 Add(int a, int b) 返回的是一个整型int,所以这里也需要这条语句最前面也需要一个int,否则运行出错。
(1)
int (*p)(int,int);
(*p) 如果去掉括号,就变成了一个指向整型的指针。加上括号那就是函数指针。
(2)
p = &Add;
这句语句,去掉 & 符号,也是可以运行的。
(3)
c = (*p)(2,3);
上面的语句可以用这种含有标识符的来引用,下面这句语句也是可以函数变量来引用:
c = p(2,3);
实现一下:
#include<iostream>int Add(int a,int b)
{return a+b;
}int main()
{int c;int (*p)(int,int);p = Add;c = p(2,3);printf("a + b = %d\n", c);
}
运行结果:
算法和数据结构是程序的第一秘诀,缺之算法和数据结构是编程的最大原因。
C ++ 指针 | 指针与函数_7相关推荐
- C++ 笔记(14)— 指针(指针声明、取地址、取值、new/delete、NULL指针、指针运算、指针数组、数组指针、指针传递给函数、从函数返回指针)
1. 声明指针 指针是一个变量,其值为另一个变量的地址,即,内存位置的直接地址.就像其他变量或常量一样,您必须在使用指 针存储其他变量地址之前,对其进行声明. 指针变量声明的一般形式为: type * ...
- C指针6:指针变量作为函数参数
在C语言中,函数的参数不仅可以是整数.小数.字符等具体的数据,还可以是指向它们的指针.用指针变量作函数参数可以将函数外部的地址传递到函数内部,使得在函数内部可以操作函数外部的数据,并且这些数据不会随着 ...
- C++成员变量指针和成员函数指针【The semantics of funcitons】
原文:https://blog.csdn.net/laojiu_/article/details/68946915 (原文有笔误) 1. #include <cstdio> #includ ...
- 用指针、子函数的方法去一维数组中所有元素的平均值,并放在a[0]处
<程序设计基础实训指导教程-c语言> ISBN 978-7-03-032846-5 p142 7.1.2 上级实训内容 [实训内容7]用指针.子函数的方法去一维数组中所有元素的平均值,并放 ...
- 多态指针访问虚函数不能被继承的类快速排序N皇后问题插入排序堆排序merge归并排序栈上生成对象两个栈实现一个队列...
多态 /*1. 要想实现覆盖(重写)父类必须声明为virtual,子类可以不声明为virtual.-->FunB()2. 派生类重写基类的虚函数实现多态,要求函数名.参数列表.返回值完全相同.( ...
- 对C语言 结构指针变量做函数的参数 结构作为函数的参数
一.结构指针变量做函数的参数 /* 用指针变量作函数参数进行传送,这时由实参传向形参的只是地址,从而减少了时间和空间的开销. */ /* 计算一组学生的平均成绩和不及格的人数,用结构指针变量作函数参数 ...
- 【C 语言】指针 与 数组 ( 指针 | 数组 | 指针运算 | 数组访问方式 | 字符串 | 指针数组 | 数组指针 | 多维数组 | 多维指针 | 数组参数 | 函数指针 | 复杂指针解读)
相关文章链接 : 1.[嵌入式开发]C语言 指针数组 多维数组 2.[嵌入式开发]C语言 命令行参数 函数指针 gdb调试 3.[嵌入式开发]C语言 结构体相关 的 函数 指针 数组 4.[嵌入式开发 ...
- c语言键盘回调函数键盘的码,深入浅出剖析C语言函数指针与回调函数(三)
前面两篇文章: http://blog.csdn.net/morixinguan/article/details/65494239 http://blog.csdn.net/morixinguan/a ...
- C++函数指针与回调函数
[转自]cnblogs.com/chenyuming507950417/archive/2012/01/02/2310114.html 今天讨论下C/C++中的回调函数. 在理解"回调函数& ...
- 指针||指针和数组||指针和函数||指针、数组、函数 案例描述:封装一个函数,利用冒泡排序,实现对整型数组的升序排序
指针 指针的基本概念 指针的作用: 可以通过指针间接访问内存 内存编号是从0开始记录的,一般用十六进制数字表示 可以利用指针变量保存地址 指针变量的定义和使用 指针变量定义语法: 数据类型 * 变量名 ...
最新文章
- 巧用二进制,让性能提升100倍,让存储空间减少100倍
- 实力封装:Unity打包AssetBundle(大结局)
- Mac 安装md5sum等
- redhat下给普通用户增加sudo命令,让他可以获得修改等权限
- 浅谈Log4net在项目中如何记录日志
- CCNA-第一篇-基础入门概念
- 当前,我们的DJANGO项目的requirements.txt文件
- 【杂谈】excel列表创建后,怎么删除蓝色边框线?
- 浙江大学-英特尔嵌入式技术中心成立
- yolov5数据集txt解析
- grub4dos挂载iso linux,GRUB4DOS加载ISO启动光盘完美解决方案
- Win10如何将语言栏移回右下角
- Class 类文件结构解析
- 计算机实验小学教导主任,小学教导主任2020年度考核个人总结5篇
- layui中实现动态的cols表头字段
- 基于SVD算法的电影推荐系统实验
- SSH端口转发Forwarding及隧道Tunneling
- solidworks动画制作教程——装配体爆炸动画
- Adobe也封杀中国账号了,技术管理者如何做到有备无患
- Array.of()
热门文章
- python原类、类的创建过程与方法
- linux系统时间和硬件时间的修改,Linux修改日期、时间,系统与硬件时间
- Windows 10下高效工作——快捷键一览
- 【李宏毅机器学习】Brief Introduction of Deep Learning 深度学习简介(p12) 学习笔记
- LeetCode-226. 翻转二叉树
- Centos7配置本地yum安装源出现错误
- libevent c++高并发网络编程_【多线程高并发编程】Callable源码分析
- 360 c语言 笔试,奇虎360校招的笔试真题
- linux mysql df_Linux基础:df命令总结
- ubuntu jdk tomcat mysql_Ubuntu下JDK+Tomcat+MySql环境的搭建