C语言函数的调用参数说明

2023年 8月 14日 35.5k 0

  • 在函数中修改函数参数的值,使其能够影响到函数外部的变量

    如果你想要自定义函数的参数能够在函数内部进行修改,并且这些修改能够影响到函数外部的变量,你需要将函数的参数改为指针类型,并在调用函数时传递变量的地址。

    以下是一个示例:

    void modifyValue(int *ptr) {
        *ptr = 1;
    }
    
    int main(void) {
        int value = 0;
    
        modifyValue(&value); // 通过传递变量的地址来修改变量的值
    
        printf("%d\n", value); // 输出修改后的值
    
        return 0;
    }
    

    在这个示例中,modifyValue 函数的参数被声明为指针类型 int *,它接收一个指向整数的指针。在函数内部,通过解引用指针 *ptr 来修改指针所指向的变量的值。

    在 main 函数中,我们定义了一个整数变量 value,并通过 & 运算符获取了它的地址,将地址传递给 modifyValue 函数。这样,在函数内部修改指针所指向的变量的值,就能够影响到 main 函数中的 value 变量。

    如果不采取这样的做法,函数的形参将只是实参的一个副本,对形参的修改不会影响到实参的值。因此,通过将参数改为指针类型,并传递变量的地址,可以实现在函数内部修改函数外部变量的值的目的。

    请注意,如果**调用函数需要传递的变量是一个指针,并且需要满足改变这个指针的需求,**那我们在调用这个指针时候,**也应该在指针前添加&,但是不能省略符号,**比如p这个指针在这种需求调用时候应该是hanshu(&*p);

    但当你传递一个数组作为参数时,实际上传递的是数组的地址(即数组的首地址)。因此,在函数中对数组进行修改时,会直接影响到原始数组,而无需使用取地址符 &

    这是因为数组名在传递给函数时会被转换为指向数组首元素的指针。函数参数使用的是指针来引用数组,因此对数组元素的修改会直接反映在原始数组中。

    以下是一个示例:

    void modifyArray(int arr[], int length) {
        arr[0] = 1;
    }
    
    int main(void) {
        int array[3] = {0, 0, 0};
    
        modifyArray(array, 3); // 传递数组给函数
    
        printf("%d\n", array[0]); // 输出修改后的数组首元素
    
        return 0;
    }
    

    在这个示例中,modifyArray 函数接受一个整型数组 arr[] 和数组的长度作为参数。在函数内部,我们直接通过数组名 arr 来修改数组的第一个元素,即 arr[0]。

    在 main 函数中,我们定义了一个整型数组 array,并将其作为参数传递给 modifyArray 函数。由于传递的是数组的地址,所以在 modifyArray 函数中对数组进行的修改会直接反映在 array 数组中。

  • 让函数调用数组作为参数

    想要让函数调用数组作为参数时,我们应该使用以下方式定义函数的参数:

    int hanshu(int str[]) {
        // 函数体
        // ...
    }
    

    而不是使用以下方式:

    int hanshu(int str) {
        // 函数体
        // ...
    }
    

    原因是,当我们将数组作为函数参数传递时,数组的名称实际上是数组在内存中的首地址。因此,在函数定义中,我们需要通过指定数组的名称,并使用方括号 [] 来表示该参数是一个数组。

    在第一个示例中,int hanshu(int str[]) 表示 hanshu 函数接受一个整型数组作为参数。我们可以在函数体内使用 str 参数来访问和操作数组元素。

    而在第二个示例中,int hanshu(int str) 表示 hanshu 函数接受一个整型变量作为参数,而不是数组。这意味着我们无法直接访问和操作数组的元素,因为这里的 str 只是一个整型变量,而不是数组的首地址。

    因此,为了能够正确地传递和操作数组作为函数参数,我们应该使用 int hanshu(int str[]) 的方式来定义函数参数。

  • 让函数调用结构体作为参数

    当我们想要将结构体作为函数参数传递时,我们应该使用以下任意一种方式定义函数的参数:

    void functionName(structName *structVar) {
        // 函数体
        // ...
    }
    void functionName(structName structVar[]) {
        // 函数体
        // ...
    }
    

    而不是使用以下方式:

    void functionName(structName structVar) {
        // 函数体
        // ...
    }
    

    这是因为结构体作为参数传递时,我们通常会使用指针的方式来传递结构体的地址,而不是直接传递结构体本身。通过使用指针,我们可以避免在函数调用时产生结构体的副本,从而提高性能和节省内存。

    在第一个示例中,void functionName(structName *structVar) 表示 functionName 函数接受一个指向 structName 类型结构体的指针作为参数。我们可以在函数体内使用 structVar 参数来访问和操作结构体的成员。

    在第二个示例 void functionName(structName structVar[]) 也是一种正确的方式来定义函数参数。这种方式表示 functionName 函数接受一个 structName 类型的结构体数组作为参数。我们可以在函数体内使用 structVar[] 参数来访问和操作结构体数组的元素。

    因此,为了能够正确地传递和操作结构体作为函数参数,我们可以使用 void functionName(structName *structVar) 或 void functionName(structName structVar[]) 的方式来定义函数参数。

    而在错误示例中,void functionName(structName structVar) 表示 functionName 函数接受一个 structName 类型的变量作为参数,而不是结构体的指针。这意味着我们只能访问和操作结构体参数的副本,而无法对原始结构体进行修改。

    为了能够正确地传递和操作结构体作为函数参数,请使用 void functionName(structName *structVar) 或void functionName(structName structVar[])的方式来定义函数参数。

  • C语言中函数数组参数中需要明确指定除第一个维度外的维度大小

    概述:

    在C语言中,处理多维数组时,除了第一个维度外,其他维度必须明确指定大小。这是因为C语言不支持以数组形式传递多维数组,而是通过指针来处理。在函数参数中,可以省略第一个维度的大小,但对于其他维度,必须指定具体的大小。

    具体步骤:

  • 在函数声明或定义时,使用 数组名[][大小] 的形式来明确指定除第一个维度外的维度大小。
  • 在调用函数时,将数组的行数和列数作为参数传递给函数。
  • 在函数内部,通过指针来访问多维数组的元素,确保正确处理数组。
  • 示例代码:

    #include 
    
    void functionName(int rows, int cols, int array[][cols]) {
        // 使用指针访问多维数组的元素进行相应操作
    }
    
    int main() {
        int array[rows][cols];
        // 初始化或输入数组的值
    
        functionName(rows, cols, array);
    
        return 0;
    }
    

    注意事项:

    • 除第一个维度外的维度大小必须在函数参数中明确指定,以便进行正确的内存访问。
    • 在函数定义之前需要声明函数的参数类型,以便编译器知道传入的数组的大小。
    • 确保在函数调用时将正确的行数和列数传递给函数,以便正确处理多维数组。

    这种明确指定除第一个维度外的维度大小的方式,使得在函数中能够正确处理多维数组的元素,并提供了更灵活和通用的函数设计。

    以下是一个更复杂的示例代码,展示了如何处理三维数组:

    #include 
    
    void printMatrix(int rows, int cols, int depth, int matrix[][cols][depth]) {
        for (int i = 0; i < rows; i++) {
            for (int j = 0; j < cols; j++) {
                for (int k = 0; k < depth; k++) {
                    printf("%d ", matrix[i][j][k]);
                }
                printf("\n");
            }
            printf("\n");
        }
    }
    
    int main() {
        int matrix[2][3][4] = {
            {
                {1, 2, 3, 4},
                {5, 6, 7, 8},
                {9, 10, 11, 12}
            },
            {
                {13, 14, 15, 16},
                {17, 18, 19, 20},
                {21, 22, 23, 24}
            }
        };
    
        printMatrix(2, 3, 4, matrix);
    
        return 0;
    }
    

    在上述示例中,我们定义了一个 printMatrix 函数,用于打印三维整数数组。函数参数中,我们除了第一个维度外,还明确指定了第二个和第三个维度的大小。

    在 main 函数中,我们声明了一个 2 页 3 行 4 列的三维整数数组 matrix。然后,我们调用 printMatrix 函数,并将数组的页数(2)、行数(3)、列数(4)和数组本身作为参数传递进去。

    在 printMatrix 函数内部,我们使用 matrix 参数来访问传入的三维数组,并通过三个嵌套循环打印数组的元素。通过明确指定除第一个维度外的维度大小,我们可以正确处理三维数组的元素,并进行相应的操作。

    这个示例展示了如何处理更复杂的多维数组,并说明了在函数参数中明确指定除第一个维度外的维度大小的重要性。通过这种方式,我们可以处理任意维度的多维数组,并在函数内部使用它们进行各种操作。

  • 使得函数返回一系列文字

    当我们这样编写函数时:

    char* hanshu() {
        char str[100] = "123";
        return str[];
    }
    

    实际上是无法返回一组文字的。这是因为在函数结束后,局部数组 str 的内存将被释放,导致返回的指针指向无效的内存地址。

    为了使函数能够返回一组文字(字符串),我们需要进行一些修改和补充:

    char* hanshu() {
        char* str = malloc(4); // 分配足够的内存空间来存储字符串和结束符
        strcpy(str, "123"); // 将字符串复制到分配的内存中
        return str; // 返回字符串的地址
    }
    

    在这个示例中,我们使用动态内存分配函数 malloc 来分配足够的内存空间来存储字符串 "123" 和一个结束符。我们分配了 4 个字节的内存,其中 3 个字节用于存储字符串的字符,最后一个字节用于存储字符串的结束符。

    然后,我们使用 strcpy 函数将字符串 "123" 复制到动态分配的内存中。注意不能是str=“123”;这样会导致str不再指向之前的动态地址,而是指向一个静态地址并且在函数结束后仍然会释放。

    最后,我们返回动态分配内存的地址,这样就可以在调用函数后访问和使用返回的字符串。

    请注意,在使用完返回的字符串后,应该使用 free 函数来释放动态分配的内存,以避免内存泄漏。

相关文章

JavaScript2024新功能:Object.groupBy、正则表达式v标志
PHP trim 函数对多字节字符的使用和限制
新函数 json_validate() 、randomizer 类扩展…20 个PHP 8.3 新特性全面解析
使用HTMX为WordPress增效:如何在不使用复杂框架的情况下增强平台功能
为React 19做准备:WordPress 6.6用户指南
如何删除WordPress中的所有评论

发布评论