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


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

    • 函数的构成部分:返回类型、函数名称、参数、函数主体
    • 参数:函数调用时传入的参数称为实参,函数定义时出现的参数为形参
      • 形参的作用在于接收实参传入的值,形参和函数内部的其他局部变量相同,在进入函数创建,退出函数销毁
      • 值传递:实参的实际值复制给形式参数。修改形参不会改变实际参数
      • 引用传递:指针传递,将实参地址复制给形参,修改形参指向的值时,实参也会发生改变
      • 由此,可以得知无论是形式结合还是return语句返回时,都存在一个拷贝的过程。值传递的过程是将这个值拷贝一份在函数内部使用,引用传递的过程是将地址拷贝一份使用。同样在return返回时,返回一个值,函数会将该值拷贝一份供主函数使用,返回指针,自然拷贝的就是一个地址,供主函数使用。
    • 下面是一个错误示例
    •   #include <stdio.h>
        #include <string.h>
      
        char * retstring();
        int main()
        {
            char * name2;
            name2 = retstring();
            printf("%s
      ",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++)!='');
              return des;
          }
        

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

    •   #include <stdio.h>
        #include <string.h>
        #include <stdlib.h>
      
        char * retstring();
        int main()
        {
            char * name2;
            name2 = retstring();
            printf("%s
      ",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
      ",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
  • 相关阅读:
    【STM32 .Net MF开发板学习19】DHT11温湿度传感器通信(上)
    【STM32 .Net MF开发板学习18】GPRS遥控智能小车
    【STM32 .Net MF开发板学习21】蓝牙遥控智能小车(PC模式)
    【STM32 .Net MF开发板学习17】Wifi遥控智能小车
    【STM32 .Net MF开发板学习15】红外遥控智能小车
    【STM32 .Net MF开发板学习20】蓝牙遥控智能小车(手机模式)
    研华物联网论坛和ARM技术研讨会随笔
    STM32F103ZE和STM32F207ZG的芯片区别
    Microsoft .NET Gadgeteer 简介及其它
    Windows Phone_学习第三天 简单
  • 原文地址:https://www.cnblogs.com/Black-Cobra/p/9122451.html
Copyright © 2020-2023  润新知