生如夏花2017

  博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

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
posted on 2018-06-01 16:55  生如夏花2017  阅读(2997)  评论(0编辑  收藏  举报