C语言模块化编程中如何正确跨文件传递指针?
解决模块化代码中的指针传递问题
你遇到的核心问题是依赖了全局指针pointerNUM来共享数据,但模块化开发中我们应该尽量避免全局变量(而且你的头文件也不能定义变量)。正确的做法是把动态分配的数组指针作为参数传递给需要它的函数,这样每个函数的依赖关系更清晰,也符合模块化的要求。
下面是修改后的完整代码,我会一步步说明调整点:
1. 更新头文件 my.h
我们需要修改函数原型,让每个操作数组的函数都接收int*类型的指针参数:
#include <stdio.h> #include <stdlib.h> // 更新函数原型,添加指针参数 void insertSORT(int *arr, int numberOfNUM); int* readFile(int argc, char *argv[], int *numberOfNUM); void show(int *arr, int numberOfNUM);
这里我还调整了readFile的设计:让它返回分配好的数组指针,同时通过指针参数numberOfNUM返回数组长度(原来的返回值改成返回指针,这样main里可以直接接收)。
2. 修改 main.c
现在main需要接收readFile返回的数组指针,然后把它传递给show和insertSORT:
#include "my.h" int main(int argc, char *argv[]) { // 存储文件中的数字数量 int numberOfNUM; // 接收readFile返回的数组指针 int *pointerNUM = readFile(argc, argv, &numberOfNUM); // 调用函数显示排序前的数字,传入指针 printf("\n Before sort : "); show(pointerNUM, numberOfNUM); // 调用排序函数,传入指针 insertSORT(pointerNUM, numberOfNUM); // 调用函数显示排序后的数字,传入指针 printf("\n After sort: "); show(pointerNUM, numberOfNUM); // 别忘了释放动态分配的内存! free(pointerNUM); return 0; }
这里额外加了free(pointerNUM),避免内存泄漏,这是之前代码里漏掉的重要步骤。
3. 修改 readFile.c
现在readFile不再依赖全局指针,而是自己分配内存后返回指针,同时通过numberOfNUM指针把数组长度传递回main:
#include "my.h" // 读取文件,返回分配好的数组指针,通过指针参数返回数组长度 int* readFile(int argc, char *argv[], int *numberOfNUM) { FILE *fptr; int cntVAR; fptr = fopen(argv[1], "r"); if (fptr == NULL) { printf("Cannot open file \n"); exit(EXIT_FAILURE); } // 读取数字数量到numberOfNUM指向的内存 fscanf(fptr, "%d", numberOfNUM); // 动态分配内存 int *arr = (int *) calloc(*numberOfNUM, sizeof(int)); if (arr == NULL) { printf("Memory allocation failed \n"); fclose(fptr); exit(EXIT_FAILURE); } for(cntVAR = 0; cntVAR < *numberOfNUM; cntVAR++) { fscanf(fptr, "%d", &arr[cntVAR]); } fclose(fptr); // 原来的fclose在return之后,永远执行不到,现在移到前面 return arr; }
这里修复了原来的bug:fclose(fptr)在return之后,根本不会执行,现在调整到return之前,确保文件被正确关闭。另外加了内存分配失败的判断,更健壮。
4. 修改 insertSORT.c
现在函数接收传入的数组指针arr,用它来操作数组,不再依赖全局变量:
#include "my.h" // 插入排序函数,接收数组指针和长度 void insertSORT(int *arr, int numberOfNUM) { int x, key, y; for (x = 1; x < numberOfNUM; x++) { key = arr[x]; y = x - 1; while (y >= 0 && arr[y] > key) { arr[y + 1] = arr[y]; y = y - 1; } arr[y + 1] = key; } }
5. 修改 show.c
同样,接收传入的数组指针来打印内容:
#include "my.h" // 显示数组内容,接收数组指针和长度 void show(int *arr, int numberOfNUM) { int cntVAR; for(cntVAR = 0; cntVAR < numberOfNUM; cntVAR++) { printf("%4d, ", arr[cntVAR]); } }
为什么这样修改?
- 避免全局变量:全局变量会让模块间的依赖变得模糊,而且容易引发意外的副作用,模块化开发中应该尽量避免。
- 符合头文件要求:头文件里只放函数原型、宏定义和类型声明,不定义变量,这是C语言开发的规范。
- 明确依赖关系:每个函数需要什么参数都清晰可见,代码可读性和可维护性更好。
- 修复潜在bug:比如原来的
fclose执行不到、没有释放内存的问题,现在都解决了。
内容的提问来源于stack exchange,提问作者John Meff
相关产品推荐
相关产品推荐

