`
美丽的小岛
  • 浏览: 308863 次
  • 性别: Icon_minigender_1
  • 来自: 大连
社区版块
存档分类
最新评论

C语言的函数返回值

    博客分类:
  • c++
  • c
 
阅读更多

一:背景

谈到C语言的函数返回值,可能会感觉很亲切,不就是一个函数返回值嘛,当初学C语言的时候早就学过了很easy嘛,我曾经也是这么想的。后来要上研究生了,研究生阶段搞得就是C,所以又重新开始学习C,学习C的过程中遇到了很多问题,在此博客中一一记录。实际过程中遇到的第一个问题自然就是函数返回值了。如果有人问你在一个函数中声明一个字符串数组,最后再return这个数组。这可以实现嘛?如果是问我我可能会毫不犹豫的说OK。那事实呢?由此本文诞生了......

 

二:问题

先看几个实际的例子:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
#include<stdio.h>
#include<stdlib.h>
char *return_arry();
int main ( int argc, char *argv[] )
{
 
        printf("%s\n",return_arry());
        printf("%d\n",return_var());
        return EXIT_SUCCESS;
}
/* ----------  end of function main  ---------- */
 
 
char* return_arry ( )
{
        char str[]="zhangyifei";
        return str;
}
/* -----  end of function return_arry  ----- */
 
 
int return_var (  )
{
        int a = 5;
        return a;
}
/* -----  end of function return_var  ----- */
 
linux 下gcc编译报错如下:
return.c: In function ‘return_arry’:
return.c:35:2: warning: function returns address of local variable [-Wreturn-local-addr]
  return str;
  ^

 

可见函数中是无法返回一个局部变量数组的。那为何return_var中没有报错呢。

其原因在于return a 其本质是返回了a的值,而return str则是返回了这个数组的首地址。然后str是一个局部变量,函数结束后这个地址就会被释放掉。所以gcc提示。对于这类问题,我们要明确函数返回的是什么,如果是值的话没有关系,如果是地址的话,要看是局部的还是全局的还是堆的。如果是局部的就不能返回。如果是全局的就没有关系了,如果是堆的那么请记住要记得释放掉。

三:方法

那么对于一个函数来说,我该怎么返回一个字符串呢。

方法如下:

方法一:返回一个指向字符串指针的常量。

1
char *func{return "only works for simple strings"}

http://forlinux.blog.51cto.com/8001278/1440352 参见这篇博文,常量是存放再代码段的,整个程序的执行周期都在不会因为子函数的结束而释放。

这是最简单的解决方案,但是如果你需要对字符串处理那就无能为力了。

 

方法二:使用全局数组

1
2
3
4
char *func(){
    my_global_array[i] = 'a';
    return my_global_array;
}

这种方法也是很简单易用的,但是大量创建这样的全局字符串数组增加了程序的耦合性。并且任何人都可以修改这个全局数组,而且下一次函数调用也会覆盖该数组的内容。

 

方法三:使用静态数组

1
2
3
4
char * func(){
    static char buffer[20];
    return buffer;
}

http://forlinux.blog.51cto.com/8001278/1440352 参见这篇博文,静态变量是存放在数据段的也是整个程序执行周期都不释放的。

这种方法比使用全局数组要好,可以防止任何人修改这个数组的内容,只有拥有该数组的指针函数才能修改这个静态数组。但是函数下一次调用将覆盖这个数组的内容。

 

方法四:显示分配一些内存

1
2
3
4
5
char *func()
{
    char *s = malloc(120);
    return s;
}

http://forlinux.blog.51cto.com/8001278/1440352 参见这篇博文mlloc分配的内存是放在堆段的,只有编程者自己手动通过free来释放内存的。所以不会因为函数执行完毕就释放其内存。

但是这种方法要求编程者谨记要自己手动释放内存,这种写法不太好,因为malloc和free不在同一个代码块中很容易忘记使用free.

 

方法五:也许是最好的解决方案

1
2
3
4
5
6
7
8
void func(char *result,int size)
{
    strcpy(result,"test",size);
}
buffer = malloc(size);
func(buffer,size);
free(buffer);
这种方案只要mallocfree的使用在一个代码块中那么内存管理就显得轻松了。

四:总结

C语言真的很简单,简单到什么都要自己做。

本文出自 “专注linux” 博客,请务必保留此出处http://forlinux.blog.51cto.com/8001278/1530404

分享到:
评论

相关推荐

    详解C语言函数返回值解析

    C语言函数返回值解析 C语言函数返回值解析是指在C语言编程中,函数返回值的处理机制。函数返回值可以是变量、指针、数组、结构体等各种形式,但归根结底,函数返回值都是一个值,或者是一个地址。在C语言中,函数...

    关于函数返回值的讨论

    函数返回值是C语言编程中的重要概念,它不仅涉及到函数的设计和实现,还关联到内存管理、数据类型转换等多个方面。理解函数返回值和参数传递机制,对于编写高效、健壮的程序至关重要。通过本文的介绍,初学者应能...

    C语言 用指针作为函数返回值详解

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

    296-用P0 、P1口显示整型函数返回值(51单片机C语言实例Proteus仿真和代码)

    296-用P0 、P1口显示整型函数返回值(51单片机C语言实例Proteus仿真和代码)296-用P0 、P1口显示整型函数返回值(51单片机C语言实例Proteus仿真和代码)296-用P0 、P1口显示整型函数返回值(51单片机C语言实例Proteus仿真...

    C语言函数选择练习题

    7. **函数返回值类型匹配**:如果主调用函数期望`double`类型的返回值,而被调用函数返回`float`类型,编译器会自动提升`float`到`double`,因此返回值的类型是`double`。选项C(double型)是正确的。 8. **变量...

    嵌入式C语言培训-C编程基础-函数返回值

    下面我们将深入探讨嵌入式系统中的C语言编程基础,特别是关于函数返回值的相关知识点。 1. **函数定义与声明** 在C语言中,函数定义包含函数名、返回类型和参数列表。例如: ```c int add(int a, int b) { ...

    C语言函数的应用例子

    C语言函数的应用例子 C语言函数是程序设计中的一种基本结构单元,它可以实现特定的功能,并且可以重复使用。下面我们将通过几个例子来了解C语言函数的应用。 1. 定义一个函数,求 X 的 n 次方 在这个例子中,我们...

    枚举和函数返回值使用---工作内容之总结

    枚举类型和函数返回值是C语言中非常重要的特性,它们能够帮助开发者更好地组织和管理代码。合理利用枚举类型可以提高代码的可读性和可维护性;而通过使用枚举作为函数返回值,则可以让代码更加健壮和易于调试。掌握...

    C语言中数组作为函数的参数以及返回值的使用简单入门

    在C语言中,当我们声明一个函数并希望接受数组作为参数时,实际上传递的是数组的首元素地址,因为数组名在大多数情况下等价于指向其首元素的指针。有三种常见的方式声明这种函数: 1. 形式参数为指针:`void ...

    C语言bioskey返回值大全

    ### C语言bioskey返回值大全解析 #### 一、引言 在早期的计算机编程环境中,特别是使用C语言进行低级编程时,了解并掌握如何有效地处理键盘输入是非常重要的。`bioskey`函数是一个非常实用的工具,它可以用来读取...

    提供C语言函数查询器

    函数定义由`return_type function_name( parameter_list )`构成,其中`return_type`是函数返回值的类型,`function_name`是函数名,`parameter_list`是函数参数列表。例如,`int add(int a, int b)`定义了一个名为`...

    C语言29:用P0 、P1口显示整型函数返回值.rar

    本教程“C语言29:用P0 、P1口显示整型函数返回值”将重点讲解如何利用这些端口来呈现整型函数的返回值。 首先,我们需要理解P0和P1口的基本工作原理。P0口是8位双向数据口,既可以用作输入也可以用作输出。当作为...

    c语言函数大全及详解 -供大家学习研究参考

    函数原型说明 功能 返回值 说明 int abs( int x) 求整数x的绝对值 计算结果 double fabs(double x) 求双精度实数x的绝对值 计算结果 double acos(double x) 计算cos-1(x)的值 ...

    c函数调用-不使用函数返回值

    本文将深入探讨“C函数调用-不使用函数返回值”的概念,通过分析给定的代码示例,解释不同类型的函数参数传递方式,并讨论其潜在的影响和最佳实践。 ### 函数调用与参数传递 在给定的代码示例中,我们看到了多种...

    C语言函数大全超级完整版

    `return_type`是函数返回值的类型,如果函数不返回值,可以使用`void`。`function_name`是函数名,应遵循标识符的命名规则。`parameters`是函数参数列表,可以为空,也可以包含多个参数,每个参数有自己的类型和名称...

    C语言函数大全 函数例题

    总结来说,“C语言函数大全”这个资源应该涵盖了函数的各个方面,包括但不限于函数的定义、参数传递、返回值、函数指针、递归、函数优化等。通过对这些例题的学习和实践,学习者能更深入地理解C语言函数的使用,并...

    用C语言指针作为函数返回值_C语言中文网1

    指针作为函数返回值能带来灵活性,但也需要遵循一些规则以避免潜在的问题,比如确保返回的指针始终指向有效的内存区域。在编写涉及指针的代码时,应特别注意内存管理,以防止内存泄漏或访问无效内存。通过不断地练习...

    C语言函数大全及详解。

    "C语言函数大全及详解"这份文档详细介绍了C语言中的各种函数,是学习C语言过程中不可或缺的参考资料。下面,我们将深入探讨C语言中的函数概念、分类及其重要性。 1. **函数的基本概念**: 在C语言中,函数是一组...

    C语言函数查询器

    这个工具主要为用户提供了一个全面的C语言函数库,包含了标准库(如stdio.h, string.h, math.h等)中的所有函数,以及它们的参数、返回值、使用示例和详细说明。通过这个查询器,用户可以迅速找到所需函数的相关信息...

Global site tag (gtag.js) - Google Analytics