看完这篇文章一定弄懂C语言数组作为函数参数的用法

看完这篇文章一定弄懂C语言数组作为函数参数的用法

C语言数组作为函数参数

文章目录

一:数组元素作为函数的实参二:数组名作为函数的实参关于数组作为函数参数调用的讨论*将函数参数定义为指针的形式关于函数定义的参数表的讨论

三:二维数组名作为函数参数*将函数参数定义为指针的形式(1)第一维是指针,第二维是数组(2)二维指针并不能达到传递普通二维数组的效果(3)只有动态申请的二维数组才可通过二维指针作为函数参数传递

获取二维数组的行和列

四:更高维数组作为函数参数同二维数组类似五:参考文档

一:数组元素作为函数的实参

数组元素就是变量,与普通变量没有区别,将数组元素传送给形参,实现单向的值传递。 用数组元素作实参时,只要数组类型和函数的形参变量的类型一致,那么作为下标变量的数组元素的类型也和函数形参变量的类型是一致的。 因此,并不要求函数的形参也是下标变量。换句话说,对数组元素的处理是按普通变量对待的。

在普通变量或下标变量作函数参数时,形参变量和实参变量是由编译系统分配的两个不同的内存单元。在函数调用时发生的值传送是把实参变量的值赋予形参变量。

#include

float max(float x,float y)

{

if(x > y)

return x;

else

return y;

}

int main()

{

int a[6] = {3,2,1,4,9,0};

int m = a[0];

for(int i = 1;i < 6; i ++)

{

m = max(m,a[i]);

}

printf("数组中的最大元素是:%d",m);

}

二:数组名作为函数的实参

实质是地址的传递,将数组的首地址传给形参,形参和实参共用同一存储空间,形参的变化就是实参的变化。用数组名作函数参数时,则要求形参和相对应的实参都必须是类型相同的数组,都必须有明确的数组说明。当形参和实参二者不一致时,即会发生错误。在用数组名作函数参数时,不是进行值的传送,即不是把实参数组的每一个元素的值都赋予形参数组的各个元素。因为实际上形参数组并不存在,编译系统不为形参数组分配内存。

那么,数据的传送是如何实现的呢? 数组名就是数组的首地址, 因此在数组名作函数参数时所进行的传送只是地址的传送,也就是说把实参数组的首地址赋予形参数组名(既然如此,那函数参数自然可以为定义成指针的形式,后续会讲)。形参数组名取得该首地址之后,也就等于有了实在的数组。实际上是形参数组和实参数组为同一数组,共同拥有一段内存空间。

举例子: 上图说明了这种情形。图中设a为实参数组,类型为整型。a占有以2000为首地址的一块内存区。b为形参数组名。当发生函数调用时,进行地址传送,把实参数组a的首地址传送给形参数组名b,于是b也取得该地址2000。于是a,b两数组共同占有以2000为首地址的一段连续内存单元。从图中还可以看出a和b下标相同的元素实际上也占相同的两个内存单元(整型数组每个元素占二字节)。例如a[0]和b[0]都占用2000和2001单元,当然a[0]等于b[0]。类推则有a[i]等于b[i]。

举例说明,同时练习冒泡排序,小的数像水泡浮在上面。

#include

//其中形参数组b没有给出长度,而由n值动态地表示数组的长度。n的值由主调函数的实参进行传送。

void sort(int b[], int n)

{

for (int i=0;i

{

for (int j = 0; j < n - 1 - i; j++)

//可以这么理解当大的数沉底后,就不再参与排序了,循环1次,找出此轮中最大的数放在该轮比较的最底部,

//下一轮找出剩下数据中的最大值,并排到该轮最底部,排序了i次后,就有i个数退出排序,就只剩下n-1-i个数待排,这就是n-1-i的由来

{

if (b[j] > b[j + 1])

{

int temp = 0;

temp = b[j];

b[j] = b[j + 1];

b[j + 1] = temp;

}

}

}

}

int main()

{

int a[6] = { 3,2,1,4,9,0 };

sort(&a[0], sizeof(a) / sizeof(a[0]));

for (int i = 0; i < sizeof(a) / sizeof(a[0]); i++)

{

printf("%d ", a[i]);

}

return 0;

}

关于数组作为函数参数调用的讨论

其中数组作为函数参数调用还可以写成如下形式:

sort(a, sizeof(a) / sizeof(a[0]));

sort(&a[0], sizeof(a) / sizeof(a[0]));

测试结果:

*将函数参数定义为指针的形式

可以达到同样的效果 举例:

#include

void sort(int* b, int n)

{

for (int i=0;i

{

for (int j = 0; j < n - 1 - i; j++)

{

if (b[j] > b[j + 1])

{

int temp = 0;

temp = b[j];

b[j] = b[j + 1];

b[j + 1] = temp;

}

}

}

}

int main()

{

int c[6] = { 3,2,1,4,9,0 };

sort(c,6);

for (int i = 0; i < 6; i++)

{

printf("%d ", c[i]);

}

return 0;

}

测试结果:

关于函数定义的参数表的讨论

另外函数定义的参数表可以写成:

void sort(int b[], int n);

void sort(int b[x], int n); //其中x≠0即可

其中x≠0即可,实际编程中写成这样也没必要,直接用void sort(int b[], int n)就行。 测试: x=1 小于a的数组长度 x=100 大于a的数组长度 但是当x为0时,编译都无法进行:

三:二维数组名作为函数参数

第一维的大小可以不指定,第二维的大小必须指定。实参传送的是二维数组的首地址,使得二维数组a与b共用同一存储单元,即a[0][0]与b[0][0]共用同一存储单元,a[0][1]与b[0][1]共用同一存储单元。 测试:

#include

//b[2][3]也正确

int max(int b[][3])

{

int m = 0;

for (int i = 0; i < 2; i++)

{

for (int j = 0; j < 3; j++)

{

if (m < b[i][j])

{

m = b[i][j];

}

}

}

return m;

}

int main()

{

int a[2][3] = { 3,2,1,4,9,0 };

int sizea = sizeof(a);

int maxVal = max(a);

printf("max is %d ", maxVal);

return 0;

}

注意形参二维数组的第二维必须与实参一致,否则会报错,如下图所示: 第一维除了不能为0以外,都可以,实际编程中直接与实参的维度一样,没必要制造麻烦。

*将函数参数定义为指针的形式

可以达到同样的效果

(1)第一维是指针,第二维是数组

且第二维数组的长度必须和实参的长度一样,否则调用该函数时编译无法通过

举例

#include

int max(int (*b)[3], int row, int col)

{

int m = 0;

for (int i = 0; i < row; i++)//sizeof(b) / sizeof(b[0])为行数

for (int j = 0; j < col; j++)

if (m < b[i][j])

m = b[i][j];

for (int i = 0; i < 2; i++)//sizeof(b) / sizeof(b[0])为行数

for (int j = 0; j < 3; j++)

b[i][j]=m;

return m;

}

int main()

{

int a[2][3] = { 3,2,1,4,9,0 };

int maxVal = max(a,2,3);

printf("max is %d \n", maxVal);

for (int i = 0; i < 2; i++)

{

for (int j = 0; j < 3; j++)

{

printf("%d ", a[i][j]);

}

printf("\n");

}

return 0;

}

测试结果

(2)二维指针并不能达到传递普通二维数组的效果

现象: 强转也不行: 原因 参考文档

(3)只有动态申请的二维数组才可通过二维指针作为函数参数传递

代码:

int max1(int **b, int row, int col)

{

int m = 0;

for (int i = 0; i < row; i++)

for (int j = 0; j < col; j++)

if (m < b[i][j]) m = b[i][j];

for (int i = 0; i < 2; i++)

for (int j = 0; j < 3; j++)

b[i][j] = m;

return m;

}

int main()

{

int a[2][3] = { 3,2,1,4,9,0 };

int maxVal = max(a,2,3);

int row = 2,col = 3;

int** a1 = new int*[row];

for (int i = 0; i < row; i++)

a1[i] = new int[col];

for (int i = 0; i < row; i++)

for (int j = 0; j < col; j++)

a1[i][j] = (i+1)*j;

max1(a1,row,col);

for (int i = 0; i < 2; i++)

{

for (int j = 0; j < 3; j++)

{

printf("%d ", a1[i][j]);

}

printf("\n");

}

return 0;

}

测试:

获取二维数组的行和列

获取二维数组的行和列是经常遇到的

定义一个二维数组int array[A][B],可以通过计算sizeof获取行列数。 sizeof(array[0][0])为一个元素占用的空间, sizeof(array[0])为一行元素占用的空间, sizeof(array)为整个数组占用的空间, 行数 = sizeof(array)/sizeof(array[0]); 列数 = sizeof(array[0])/sizeof(array[0][0]); 根本原因:

测试:

四:更高维数组作为函数参数同二维数组类似

举例

#include "conv1.h"

#include

#include

using namespace std;

float max(const float conv1_weight[64][3][3][3][3]);

int main()

{

int a[2][3] = { 0,1,2,

3,4,5 };

cout << a[1][2] << endl;

cout << "numbers of conv1_weight: " << sizeof(conv1_weight) / sizeof(conv1_weight[63][2][2][2][2]) << endl;

cout << "conv1_weight[63][2][2][2][2]: " << setiosflags(ios::fixed) << setprecision(10) << conv1_weight[63][2][2][2][2] << endl;

cout << "max of conv1_weight: " << max(conv1_weight) << endl;

int b = 16;

b >>= 1;

cout << b;

return 0;

}

float max(const float conv1_weight[64][3][3][3][3])

{

float max = 0;

for (int i = 0; i < 64; i++)

for (int j = 0; j < 3; j++)

for (int k = 0; k < 3; k++)

for (int m = 0; m < 3; m++)

for (int n = 0; n < 3; n++)

{

if (max < conv1_weight[i][j][k][m][n])

{

max = conv1_weight[i][j][k][m][n];

}

}

return max;

}

其中conv1_weight[64][3][3][3][3]为下图所示:

测试结果:

五:参考文档

http://c.biancheng.net/cpp/html/61.html https://blog.csdn.net/lishundi/article/details/87906920

猜你喜欢

遗憾!国足2:1胜卡塔尔 积分落后仍无缘2018世界杯
森保一:我执教日本国家队的梦想和目标就是赢得世界杯
来月经为什么不能洗澡
GBT36507-2018

来月经为什么不能洗澡

📅 07-06 ❤️ 405
如何给电风扇换电容?
best365体育正不正规

如何给电风扇换电容?

📅 06-27 ❤️ 12
录好的视频怎么加快速度,这种方法做出快进效果
墨墨背单词APP签到指南
365提款问题

墨墨背单词APP签到指南

📅 07-01 ❤️ 474
blued闪退怎么回事
365提款问题

blued闪退怎么回事

📅 07-05 ❤️ 287
《王者荣耀》李白凤求凰多少钱 李白凤求凰皮肤价格
小红书中我的收藏在哪里找 详细指南:快速定位你在小红书上的所有笔记、商品与合集