力扣如何使用C语言返回数组

问题分析

力扣的题目特点是不需要自己完成输入输出,只需要编写实现算法的函数即可。在刚开始使用C语言在LeetCode刷题碰到的一个问题就是,当题目要求返回一个数组(一维或二维)时,我们写的代码常常发生如下所示的内存错误。
在这里插入图片描述
在LeetCode上使用C语言返回一个数组时,根据返回的数组是一维数组还是二维数组,题目分别会有如下说明:

  1. 当题目要求返回一个一维数组时:
    /**
     * Note: The returned array must be malloced, assume caller calls free().
     */
     int* func(int* returnSize) {
     	// do something
     }
    
    这里要求,返回的数组必须通过动态开辟(malloc,calloc,realloc),并且函数func中都含有一个一级指针参数returnSize,这个参数指向一个值为返回数组大小的整形变量,也就是说,*returnSize就是返回数组中含有元素的个数。

  1. 当题目要求返回一个二维数组时:
    /**
     * Return an array of arrays of size *returnSize.
     * The sizes of the arrays are returned as *returnColumnSizes array.
     * Note: Both returned array and *columnSizes array must be malloced, assume caller calls free().
     */
     int** func(int* returnSize, int** returnColumnSizes) {
     	// do something
     }
    
    这里要求,返回的数组必须通过动态开辟(malloc,calloc,realloc),并且函数func中懂包含两个参数,分别是一级指针returnSize和二级指针returnColumnSizes,其中,returnSize指向一个值为返回二维数组行数的整形变量,也就是说,*returnSize就是返回二维数组的行数,而returnColumnSizes指向一个存储了返回二维数组各行长度的一维数组,也就是说,(*returnColumnSizes)[i]就是返回二维数组第i行的元素个数。

解决方案

那么,为什么LeetCode使用C语言返回数组时需要这样设计呢?LeetCode的输出功能不需要我们完成,但是很好想象,如果我们需要输出得到的数组,那么对于一个一维数组,我们需要知道它的大小,对于一个二维数组,我们需要知道它的行数和各行需要输出的元素个数,如下所示:

  1. 当题目要求返回一个一维数组时:
    int* func(int* returnSize) {
    	int* ans = (int*)malloc(sizeof(int) * 10);
    	*returnSize = 10;
    	return ans;
    }
    
    int main() {
    	int size = 0;
    	int* arr = func(&size);
    	for(int i = 0; i < size; i++) 
    		printf("%d ", arr[i]);
    	free(arr);
    	return 0;
    }
    
    我们需要知道返回数组的大小,由于C语言函数的返回值至多只能为1个,因此可以将某个需要返回的值通过作为函数的参数进行修改,这里需要知道数组的大小size,因此将size的地址传入,在函数内部进行修改,这样size就是返回数组的大小。(形参的改变不影响实参,如果直接将size作为参数那么在函数内对size的修改不影响主函数内size的值)

  1. 当题目要求返回一个二维数组时:

    int** func(int* returnSize, int** returnColumnSizes) {
    	int** ans = (int**)malloc(sizeof(int*) * 10);
    	for(int i = 0; i < 10; i++)
    		ans[i] = malloc(sizeof(int) * 5);
    	*returnColumnSizes = (int*)malloc(sizeof(int) * 10);
    	for(int i = 0; i < 10; i++) 
    		(*returnColumnSizes)[i] = 5;
    	*returnSize = 10;
    	return ans;
    }
    
    int main() {
    	int size = 0;
    	int* ColSizes = NULL;
    	int** ans = func(&size, &ColSizes);
    	for(int i = 0; i < size; i++) {
    		for(int j = 0; j < ColSizes[i]; j++) 
    			printf("%d ", ans[i][j]);
    		printf("\n");
    	}
    	return 0;
    }
    

    与返回一维数组的情况类似,size代表二维数组的行数,而主函数里的指针ColSizes可以理解为一个一维数组,ColSizes[i]为二维数组第i行的元素个数(或者是需要输出的元素个数),而ColSizes的元素个数为二维数组的行数,但是,主函数里的ColSizes只是一个空指针,需要我们在函数func内对其进行修改,类似地,需要传入的是它的地址,也就是一个二级指针。在函数func内部,首先应该为ColSizes开辟一块空间来存放各行的元素个数。

  • 6
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

ChenxuanRao

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值