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. 【Gradle】Android Gradle 多项目构建

    Android Gradle 多项目构建 Android 项目区别 Android项目一般分为库项目,应用项目,测试项目,Android Gradle 根据这些项目分别对应3种插件:com.andro ...

  2. CentOS安装docker-compose

    一.compose简介 compose是一个定义和运行多容器的docker应用的工具.compose 通过yaml文件配置应用服务,然后仅需一个命令就可以创建和运行所有配置中的服务. 二.compos ...

  3. 201871010116-祁英红《面向对象程序设计(java)》第十四周学习总结

    博文正文开头格式:(2分) 项目 内容 <面向对象程序设计(java)> https://home.cnblogs.com/u/nwnu-daizh/ 这个作业的要求在哪里 https:/ ...

  4. 题解:A

    A (a.pas/c/cpp) [题目描述] 对于给定的一个正整数n, 判断n是否能分成若干个正整数之和 (可以重复) , 其中每个正整数都能表示成两个质数乘积. [输入描述] 第一行一个正整数 q, ...

  5. 【洛谷5299】[PKUWC2018] Slay the Spire(组合数学)

    点此看题面 大致题意: 有\(n\)张强化牌\(a_i\)和\(n\)张攻击牌\(b_i\),每张牌有一个权值(强化牌的权值大于\(1\)),每张强化牌能使所有攻击牌的权值乘上这张强化牌的权值,每张攻 ...

  6. 【洛谷4585】[FJOI2015] 火星商店问题(线段树分治)

    点此看题面 大致题意: 有\(n\)家店,每个商品有一个标价.每天,都可能有某家商店进货,也可能有某人去购物.一个人在购物时,会于编号在区间\([L_i,R_i]\)的商店里挑选一件进货\(d_i\) ...

  7. django执行源生的mysql语句

    执行源生sql在python中我们可以借助pymysql模块来进行执行源生sql关于pymysql执行源生sql可以看我的另外一篇博文:pymysql应用 本篇博客只介绍django中执行的源生sql ...

  8. Codeforces Round #602 (Div. 2, based on Technocup 2020 Elimination Round 3) A. Math Problem 水题

    A. Math Problem Your math teacher gave you the following problem: There are n segments on the x-axis ...

  9. "One or more types required to compile a dynamic expression cannot be found. Are you missing references to Microsoft.CSharp.dll and System.Core.dll?"的解决方法

    #事故现场: 在一个.net 4.0 的项目中使用dynamic,示例代码如下: private static void Main(string[] args) { dynamic obj; obj ...

  10. 洛谷P5322 (BJOI 2019) DP

    ### 题目链接 ### 分析: 1.用 vector<int> v[i] 来存 i 城堡, s 个对手所安排的士兵数量. 2.设 dp[i][j] 表示 i 城堡前,在当前最大派兵量为  ...