C语言中函数返回字符串的4中方法

  • 函数的构成部分:返回类型、函数名称、参数、函数主体
  • 参数:函数调用时传入的参数称为实参,函数定义时出现的参数为形参
    • 形参的作用在于接收实参传入的值,形参和函数内部的其他局部变量相同,在进入函数创建,退出函数销毁
    • 值传递:实参的实际值复制给形式参数。修改形参不会改变实际参数
    • 引用传递:指针传递,将实参地址复制给形参,修改形参指向的值时,实参也会发生改变
    • 由此,可以得知无论是形式结合还是return语句返回时,都存在一个拷贝的过程。值传递的过程是将这个值拷贝一份在函数内部使用,引用传递的过程是将地址拷贝一份使用。同样在return返回时,返回一个值,函数会将该值拷贝一份供主函数使用,返回指针,自然拷贝的就是一个地址,供主函数使用。
  • 下面是一个错误示例
  •   #include <stdio.h>
    #include <string.h> char * retstring();
    int main()
    {
    char * name2;
    name2 = retstring();
    printf("%s\n",name2);
    return 0;
    } char * retstring()
    {
    char name[10];
    strcpy(name,"汉青");
    return name;
    }
  • 上面这段代码会出现一个警告,这是因为返回了一个局部变量name的地址。在主函数中该局部变量name时处于销毁状态,所以name内存空间还没有被重写的话主函数中name2的值是正确,如果被其他程序重写,就会出现未知异常。
  • 所以返回局部变量的字符串时很可怕的
  • 函数返回字符串的方法:
    1. 将字符串指针作为函数参数传入,并返回该指针
    2. 使用malloc函数动态分配内存,在主调函数中释放
    3. 返回一个静态局部变量
    4. 使用全局变量

将字符串指针作为函数参数传入,并返回

  • 典型的strcpy函数应该采用的就是这种方法:

    •   char* strcpy(char* des,const char* source)
      {
      char* r=des;
      assert((des != NULL) && (source != NULL));
      while((*r++ = *source++)!='\0');
      return des;
      }

使用malloc函数动态分配内存,但是一定要注意在主调函数中将其释放,因为malloc动态分配的内存位于堆区,而堆区的内存是需要自己释放的###

  •   #include <stdio.h>
    #include <string.h>
    #include <stdlib.h> char * retstring();
    int main()
    {
    char * name2;
    name2 = retstring();
    printf("%s\n",name2);
    //记住一定要用free释放,否则会造成内存泄露
    free(name2);
    return 0;
    } char * retstring()
    {
    char * name;
    name = (char *)malloc(10);
    strcpy(name,"张汉青");
    return name;
    }

返回一个静态局部变量

  •   #include <stdio.h>
    #include <string.h>
    #include <stdlib.h> char * retstring();
    int main()
    {
    char * name2;
    name2 = retstring();
    printf("%s\n",name2);
    return 0;
    } char * retstring()
    {
    static char name[10];
    strcpy(name,"张汉青");
    return name;
    }
  • 这种方法在于采用了静态局部变量(位于静态区,程序结束时由系统释放),这会导致,下一次调用会将上次调用产生的结构进行覆盖。
  • 使用这样的函数应该立即将结构拷贝一份

使用全局变量

  •   char   g_s[100];
    char* fun()
    {
    strcpy(g_s, "abc ");
    return g_s;
    }

函数返回字符串问题

  • 归根结底,返回字符串就是要返回一个地址,同时需要保证地址在主调函数有效。
  • 直接定义char*变量,会保存在栈区,变量的作用域外会被立即销毁;malloc申请空间保存在堆区,需要手动销毁;静态区变量程序结束时销毁。
  • 所以返回一个地址要么扩大他的作用域,要么控制其生命周期。
  • 引用自:https://www.cnblogs.com/qingergege/p/6496683.html

C语言中函数返回字符串的4中方法的更多相关文章

  1. C语言中函数返回字符串的四种方法

    在讨论着四种方法之前,首先要对函数有一个简单的认识,无论是在形实结合时,还是在return语句返回时,都有一个拷贝的过程.你传进来的参数是个值,自然函数在工作之前要把这个值拷贝一份供自己使用,你传进来 ...

  2. c语言main函数返回值、参数详解(返回值是必须的,0表示正常退出)

    C语言Main函数返回值 main函数的返回值,用于说明程序的退出状态.如果返回0,则代表程序正常退出:返回其它数字的含义则由系统决定.通常,返回非零代表程序异常退出. 很多人甚至市面上的一些书籍,都 ...

  3. C语言strcat()函数:字符串连接(拼接)

    C语言strcat()函数:字符串连接(拼接)   C语言 strcat() 函数用来将两个字符串连接(拼接)起来. 头文件:string.h 语法/原型: char*strcat(char* str ...

  4. C函数返回字符串

    #include "stdio.h" #define KEY 5; int main() { char password[50] = "123456"; enc ...

  5. Oracle function real_st_astext,解决ArcSDE中st_astext函数返回字符串结构异常问题

    项目过程中发现在Oracle中调用ArcSDE的st_astext函数返回ST_Geometry类型字段的WKT文本有时空间类型前缀没有返回,例如一个点的经度为113.4,纬度为30.6,调用st_a ...

  6. SqlSever基础 Upper函数 返回字符串的大写形式

    镇场诗:---大梦谁觉,水月中建博客.百千磨难,才知世事无常.---今持佛语,技术无量愿学.愿尽所学,铸一良心博客.------------------------------------------ ...

  7. SqlSever基础 lower函数 返回字符串的小写形式

    镇场诗:---大梦谁觉,水月中建博客.百千磨难,才知世事无常.---今持佛语,技术无量愿学.愿尽所学,铸一良心博客.------------------------------------------ ...

  8. Go语言示例-函数返回多个值

    Go语言中函数可以返回多个值,这和其它编程语言有很大的不同.对于有其它语言编程经验的人来说,最大的障碍不是学习这个特性,而是很难想到去使用这个特性. 简单如交换两个数值的例子: package mai ...

  9. C语言之函数和字符串

    二.函数: 2.1.函数的执行: 1.当我们每次进入一个函数的时候,原函数的栈底进行一个备份,之后将当前函数的栈底和栈顶指针分作同一个. 2.此时我们就可以说产生了一个新栈,产生新栈之后会在新栈中申请 ...

随机推荐

  1. Linux日志中出现大量dhclient mesage浅析

    最近检查发现一台Linux服务器,发现其日志里面有大量下面信息,其中部分信息做了脱敏处理.其中一个地址A(192.168.AAA.AAA) 为DNS服务器地址,地址B(192.168.BBB.BBB) ...

  2. 动态构建Lambda表达式实现EF动态查询

    在使用Entity Framework做数据查询的时候,查询条件往往不是固定的,需要动态查询.可以通过动态构建Lamda表达式来实现动态查询. Lamda表达式 使用Lamda表达式可以很方便的按条件 ...

  3. 《数据挖掘导论》实验课——实验一、数据处理之Numpy

    实验一.数据处理之Numpy 一.实验目的 1. 了解numpy库的基本功能 2. 掌握Numpy库的对数组的操作与运算 二.实验工具: 1. Anaconda 2. Numpy 三.Numpy简介 ...

  4. ffmpeg-python 任意提取视频帧

    ▶ 环境准备 1.安装 FFmpeg 音/视频工具 FFmpeg 简易安装文档 2.安装 ffmpeg-python pip3 install ffmpeg-python 3.[可选]安装 openc ...

  5. configparser读取配置文件时的相对路径问题

    学习接口测试时,当我把配置文件xx.config和读取配置文件的模块read_config.py放在项目下的同一个包config里时,只需传入文件名xx.config即可实现对配置文件的读取. 但是当 ...

  6. AcWing 46. 二叉搜索树的后序遍历序列

    地址 https://www.acwing.com/solution/acwing/content/3959/ 题目描述输入一个整数数组,判断该数组是不是某二叉搜索树的后序遍历的结果. 如果是则返回t ...

  7. 分治 FFT

    为啥要叫分治\(fft\)啊,又用不到\(fft--\) 给定长度为\(n-1\)的数组\(g[1],g[2],--,g[n-1]\),求\(f[1],f[2],--,f[n]\),其中 \[f[i] ...

  8. vscode源码分析【三】程序的启动逻辑,性能问题的追踪

    第一篇: vscode源码分析[一]从源码运行vscode 第二篇:vscode源码分析[二]程序的启动逻辑,第一个窗口是如何创建的 启动追踪 代码文件:src\main.js 如果指定了特定的启动参 ...

  9. 源码学习之Spring (系统架构简单解析)

    Spring Framework 系统架构总览图 Spring Framework的模块依赖关系图 Spring Framework各个模块功能说明 Spring核心模块 模块名称 主要功能 Spri ...

  10. Linux内核驱动之GPIO子系统API接口概述

    1.前言 在嵌入式Linux开发中,对嵌入式SoC中的GPIO进行控制非常重要,Linux内核中提供了GPIO子系统,驱动开发者在驱动代码中使用GPIO子系统提供的API函数,便可以达到对GPIO控制 ...