向函数传递一维数组和已知大小的二维数组
来源:互联网 发布:js 按钮显示 隐藏 div 编辑:程序博客网 时间:2024/05/13 17:56
一维数组
在C语言中,向函数传递参数只有一种形式——值传递。不管是传递一个整型变量,还是传递一个指针,函数得到的都只是实参的拷贝值。
先定义一个一维整型数组:
int a[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
首先明确一点:数组名和指针是两个不同的概念,尽管数组名在绝大部分情况下被隐式转换成指针使用。
我们没办法真正地把数组传递给函数,我们只能传递一份指向数组起始位置的指针的拷贝。
函数原型:
void func(int *a);void func(int a[]);
在当前这个上下文环境中,二者等价。你可以使用任何一种声明,如果要说哪一种最准确,应该是第一种。因为实参实际上是个指针,而不是数组。
这样我们就把指向数组首元素的指针的拷贝传递给了函数。在实际应用中,我们通常还会传递另一个参数,用来表示数组的长度:
void func(int *a, int len);
通过第二个参数,我们可以很方便地在函数内遍历这个数组:
void func(int *a, int len) { int i = 0; while (i < len) { printf("%d ", a[i]); i++; }}func(a, 10); // 打印数组a的所有元素
二维数组
接下来是二维数组,传递二维数组参数有更多需要注意的点。
先定义一个二维整型数组:
int b[2][3] = { {0, 1, 2}, {3, 4, 5}};
我们实际上要向数组传递一个指向数组首元素的指针的拷贝,首先必须搞清楚数组名b
的类型应该是:
int (*)[3]
数组名的类型取决于数组元素,数组b
长度是2,每个元素是长度为3的整型数组,所以b
的类型是上面那坨(如果这里有疑问可以看我的另一篇文章《彻底弄懂C语言数组名》)。
如果上面的内容没有疑问,那么就来看函数原型:
void func2(int (*p)[3]); // 两种都可以,第一种更准确void func2(int p[][3]);
同样地,我们可以传递另外两个参数,分别表示行数和列数:
void func2(int (*p)[3], int len_i, int len_j);
但是请千万注意:写成二级指针是错误的!
void func2(int **p); // 不可以这样~>_<~
为什么不行呢?因为指向指针的指针和指向数组的指针是不同的。如果这样写,有可能你的程序能正确运行,但也有可能因为寻址错误导致程序崩溃哦!
下面给出完整的例子:
#include <stdio.h>void func2(int (*p)[3], int len_i, int len_j);int main() { int a[2][3] = { {0, 1, 2}, {3, 4, 5} }; func2(a, 2, 3); return 0;}void func2(int (*p)[3], int len_i, int len_j) { int i, j; for (i = 0; i < len_i; i++) { for (j = 0; j < len_j; j++) { printf("%d ", p[i][j]); } printf("\n"); }}
但是,不知道你有没有发现一个问题,我们必须在函数原型中指定第二维的大小,这意味着函数不能复用。为了向函数传递一个大小未知的数组,我将介绍两种技巧。
第一种是通过void *
指针接收一个数组,同时传递两个参数标记行和列,然后在函数内部将void *
指针强制转换成二维数组。
还有一种技巧叫做压扁数组(flattening the array),是通过一级指针遍历二维数组的方法。只要数组在内存中连续,这个技巧就可以用。我将在下一篇文章中详细介绍这个技巧。
- 向函数传递一维数组和已知大小的二维数组
- 向函数传递二维数组
- 一维数组和二维数组传递给函数时的本质
- 向函数传递一维数组
- c和c++中的一维数组和二维数组的动态分配内存,以及参数传递
- 函数传递二维数组
- 二维数组 函数传递
- 一维数组和二维数组空间的内存动态分配、参数传递
- 数组(一维数组和二维数组)的用法
- 向函数传递数组
- C#动态分配一维数组和二维数组函数
- 数组指针和指针数组以及二维数组的函数间传递与返回
- 一维、二维数组向SAFEARRAY转换
- SAFEARRAY向一维、二维数组转换
- 函数传递二维数组的方法
- 如何动态的建立大小已知的二维数组(多维数组)
- 调用函数的一维数组形成二维数组
- 二维数组的传递
- 百度文字识别
- JAVA array,map 转 json 字符串
- js实现的文件树(带选框)
- 基于Spring security 4.2.3 认证+授权源码分析
- java 23种 设计模式
- 向函数传递一维数组和已知大小的二维数组
- jQuery.i18n.properties实现前端国际化
- Shiro进行权限控制
- java中Date类
- Node js 正则
- hive读取es数据
- MySQL+Mybatis批量插入时对已存在的记录进行更新
- DB2 在创建数据库的时候,后面不能加“;”分号
- 知道这20个正则表达式,能让你少写1,000行代码