C语言允许函数的返回值是一个指针(地址),我们将这样的函数称为指针函数。下面的例子定义了一个函数 strlong(),用来返回两个字符串中较长的一个:

#include
#includechar *strlong(char *str1, char *str2){
if(strlen(str1) >= strlen(str2)){
return str1;
}else{
return str2;
}
}int main(){
char str1[30], str2[30], *str;
gets(str1);
gets(str2);
str = strlong(str1, str2);
printf("Longer string: %s\n", str);return 0;
}

运行结果:

C Language↙
c.biancheng.net↙
Longer string: c.biancheng.net

用指针作为函数返回值时需要注意的一点是,函数运行结束后会销毁在它内部定义的所有局部数据,包括局部变量、局部数组和形式参数,函数返回的指针请尽量不要指向这些数据,C语言没有任何机制来保证这些数据会一直有效,它们在后续使用过程中可能会引发运行时错误。请看下面的例子:

#includeint *func(){
int n = 100;
return &n;
}int main(){
int *p = func(), n;
n = *p;
printf("value = %d\n", n);
return 0;
}

运行结果:

value = 100

n 是 func() 内部的局部变量,func() 返回了指向 n 的指针,根据上面的观点,func() 运行结束后 n 将被销毁,使用 *p 应该获取不到 n 的值。但是从运行结果来看,我们的推理好像是错误的,func() 运行结束后 *p 依然可以获取局部变量 n 的值,这个上面的观点不是相悖吗?

为了进一步看清问题的本质,不妨将上面的代码稍作修改,在第9~10行之间增加一个函数调用,看看会有什么效果:

#includeint *func(){
int n = 100;
return &n;
}int main(){
int *p = func(), n;
printf("c.biancheng.net\n");
n = *p;
printf("value = %d\n", n);
return 0;
}

运行结果:

c.biancheng.net
value = -2

可以看到,现在 p 指向的数据已经不是原来 n 的值了,它变成了一个毫无意义的甚至有些怪异的值。与前面的代码相比,该段代码仅仅是在 *p 之前增加了一个函数调用,这一细节的不同却导致运行结果有天壤之别,究竟是为什么呢?

前面我们说函数运行结束后会销毁所有的局部数据,这个观点并没错,大部分C语言教材也都强调了这一点。但是,这里所谓的销毁并不是将局部数据所占用的内存全部抹掉,而是程序放弃对它的使用权限,弃之不理,后面的代码可以随意使用这块内存。对于上面的两个例子,func() 运行结束后 n 的内存依然保持原样,值还是 100,如果使用及时也能够得到正确的数据,如果有其它函数被调用就会覆盖这块内存,得到的数据就失去了意义。

第一个例子在调用其他函数之前使用 *p 抢先获得了 n 的值并将它保存起来,第二个例子显然没有抓住机会,有其他函数被调用后才使用 *p 获取数据,这个时候已经晚了,内存已经被后来的函数覆盖了,而覆盖它的究竟是一份什么样的数据我们无从推断(一般是一个没有意义甚至有些怪异的值)。

声明:

本文于网络整理,版权归原作者所有,如来源信息有误或侵犯权益,请联系我们删除或授权事宜。

C语言灵魂篇|指针作为函数返回值相关推荐

  1. C语言指针作为函数返回值

    C语言允许函数的返回值是一个指针(地址),我们将这样的函数称为指针函数.下面的例子定义了一个函数 strlong(),用来返回两个字符串中较长的一个: #include <stdio.h> ...

  2. C指针7:指针作为函数返回值

    C语言允许函数的返回值是一个指针(地址),我们将这样的函数称为指针函数.下面的例子定义了一个函数 strlong(),用来返回两个字符串中较长的一个: #include <stdio.h> ...

  3. 使用指针做函数返回值

    使用指针做函数返回值 1.当使用指针做为函数的返回值时,主函数处的char *p;将获得调用函数char *pf;的值,即一个地址值,如oxAE72.此时需要我们注意的是该地址值所指向的空间是否存在( ...

  4. 7 C++指针做函数返回值

    在C++中,函数的返回值出来可以是普通的数据类型,还可以是指针类型,我们将函数的返回值定义为指针类,用来返回一个变量的地址,但我们不能返回局部变量的地址. 用指针作为函数返回值时,需要注意的一点是,函 ...

  5. C语言中未显示声明函数返回值的类型

    C语言中如果未显示声明函数返回值的类型或函数的形式参数类型,它就默认返回整型.这种声明在C语言中叫做隐式声明.例如: / //main.c /#include<stdio.h>divide ...

  6. C语言中连续调用rand函数,返回值不变

    C语言中连续调用rand函数,返回值不变 最近用C语言随机函数编程发现了一个奇怪的现象: 简易版代码: #include<stdio.h> #include<stdlib.h> ...

  7. c语言函数返回值可以是字符串吗,函数返回值可以是字符串吗

    c语言中函数返回值可以是数组.字符串和结构体吗? 因为在C语言中函数不能返回数组,但字符串是存储在字符数组中的,所以能C语言中实现函数返回字符串,首先要确定函数返回的字符串地址的来源,一般分为四种方式 ...

  8. 【C 语言】字符串模型 ( 字符串翻转模型 | 抽象成业务函数 | 形参返回值 | 函数返回值 | 函数形参处理 | 形参指针判空 )

    文章目录 一.字符串翻转模型 业务函数 二.完整代码示例 一.字符串翻转模型 业务函数 将上一篇博客 [C 语言]字符串模型 ( 字符串翻转模型 ) 的代码 , 主要业务逻辑 , 抽象成函数 ; 字符 ...

  9. c语言指针,return以及函数返回值

    指针作为c语言的精华所在所以会多学习几天来扎实的掌握 void* 这不叫空指针,这叫无确切类型指针.这个指针指向一块内存,却没有告诉程序该用何种方式来解释这片内存.所以这种类型的指针不能直接进行取内容 ...

最新文章

  1. cassandra命令
  2. javaswing引入百度地图_【react】React怎么引用百度地图
  3. 机器学习理论《统计学习方法》学习笔记:第九章 EM算法及其推广
  4. 昨晚三巨头聚餐,顺便聊了这三个问题
  5. arduino 上传项目出错_Arduino多核编程:简单例子
  6. ASP.NET Literal控件用法
  7. EM算法极其推广---EM算法的收敛性
  8. 10右键闪退到桌面_windows7多用户远程桌面如何设置
  9. Spring框架----Spring常用IOC注解的分类
  10. C++中实现类似php的UTF8和UrlEncode函数的代码
  11. mongodb的常用增删改查命令:
  12. asp 加密 解密 类
  13. webstorm绝对路径引入echarts_Webstorm+Webpack+echarts构建个性化定制的数据可视化图表两个echarts详细教程(柱状图,南丁格尔图)...
  14. 联想进入bios修复计算机,联想笔记本安装win10后开启界面一直是自动修复,进不了BIOS重装系统...
  15. 创宇云蜜罐成为华为云联营商品,合力提供网络安全服务
  16. Git(二) Git基础入门与实践
  17. 崩坏3服务器修改水晶数量,崩坏3一个月能攒多少水晶_单月水晶数量分析
  18. macOS 安装lrzsz
  19. Vue3+TS 快速上手 (尚硅谷)
  20. 基于javaweb+mysql的农产品水果店销售管理系统

热门文章

  1. 使用Caffeine和Spring Boot的多个缓存配置
  2. spring消息队列_AmazonSQS和Spring用于消息传递队列
  3. netbeans7.4_NetBeans 7.4的本机Java打包
  4. 接口中的默认方法和静态方法
  5. lucene创建索引_Lucene概述第一部分:创建索引
  6. java java se_Java SE 7、8、9 –推动Java前进
  7. k8s secret使用_Java Secret:使用枚举构建状态机
  8. 不可将您的方法命名为“等于”
  9. 生成器设计模式的应用
  10. 通过Spring将继承树加载到List中