【问题标题】:C string function calls, pass by value or reference?C字符串函数调用,按值传递还是引用传递?
【发布时间】:2014-03-29 17:04:15
【问题描述】:

我无法弄清楚发生了什么,我认为 C 是按值传递的,但这个简单的函数让我对它的工作原理感到困惑。

 #include <stdio.h>
 #include <string.h>
 #include <stdlib.h>

 void testFunc(char string1[])
 {
   char string2[50] = "the end";
   strcat(string1, string2);
   printf("in func %s \n", string1);
 }

 void main()
 {
    char string1[50] = "the start";
    printf("%IN MAIN %s \n", string1);
    testFunc(string1);
    printf("IN MAIN %s \n", string1);
 }

令人困惑的输出是:

主要是开始

IN FUNC 从头到尾

主要是开始和结束

那么这里发生了什么? C 真的是传递 char 数组的地址而不是复制它的值吗?我认为这就是char* 的行为而不是char[]

【问题讨论】:

  • 请注意,void main() 仅在 Windows 上有效;它在 Unix 系统上无效。
  • 您可能的意思是:void main() 不会在 Windows 上爆炸。只有一些微控制器想要这样。

标签: c string parameter-passing


【解决方案1】:

您不能将数组的副本传递给函数。当您使用数组的名称时,它的计算结果为指向数组中 1. 元素的指针(或者通常所说的,它衰减为指针。)。除了在 sizeof&amp; 运算符中使用数组名称时,这种情况在任何地方都会发生。

因此,您将指向数组 1. 元素的指针传递给您的 testFunc()

 testFunc(string1);

和做的一模一样

 testFunc(&string1[0]);

另外,在函数参数列表中,char[] 实际上意味着char *

这3个声明完全一样

void testFunc(char *string1);
void testFunc(char string1[]);
void testFunc(char string[111]);

如果您不想更改传入的字符串,请使用以下内容:

例如

void testFunc(char string1[])
{  
  char string2[50]; 
  const char *end = "the end"; 
  strcpy(string2, string1); 
  strcat(string2, end);

(并且在使用 strcpy/strcat 时保持清醒,这样做很容易使数组溢出)

【讨论】:

  • 谢谢。如果我想在 main 函数中保留字符串,我如何让它不受影响?我真的必须创建一个新字符串并将其复制到函数中还是有什么方法可以避免这种情况?
  • @PaulthePirate 是的,没错,您必须在某处分配存储空间。例如字符字符串2[50]; char *end = "结束"; strcpy(string2, string1); strcat(string2, end);
【解决方案2】:

C 总是按值传递参数,但字符串与其他数组一样,会转换为指向其第一个元素的指针,然后传递该指针。按价值。

【讨论】:

    【解决方案3】:

    它是按值传递的。

    string1char数组的起始位置的地址,这个值正在被传递。

    void testFunc(char string1[])
    

    相同
    void testFunc(char *string1)
    

    【讨论】:

      【解决方案4】:

      在函数参数的情况下,如果你写,它是等效的:-

      void testFunc(char string1[])
      
       {
         //body 
       }
      

      void testFunc(char *string1)
      
       {
           //body
       }
      

      实际上在C语言中第一个总是转换为第二个函数定义。所以如果函数参数N element array of type T被转换为Array of type T,记住它并享受C编程。

      注意这只发生在函数参数的情况下。

      【讨论】:

        猜你喜欢
        • 2016-03-10
        • 2014-04-08
        • 1970-01-01
        • 2011-04-20
        • 1970-01-01
        • 2019-04-04
        • 2015-06-12
        • 2016-11-28
        相关资源
        最近更新 更多