【C语言指南】数组传参规则详解

 

          💓 博客主页:倔强的石头的优快云主页 

           📝Gitee主页:倔强的石头的gitee主页

            ⏩ 文章专栏:《C语言指南》

                                  期待您的关注

1b7335aca73b41609b7f05d1d366f476.gif

文章目录

一、数组传参简介

二、数组传参规则

1. 数组传参的实参传递

1.1  特殊情况一:sizeof(数组名)

1.2  特殊情况二:&数组名

2.  数组传参的形参接收

2.1 数组传参使用数组名作为形参接收

形参如果是⼀维数组

形参如果是⼆维数组

2.2 数组传参使用指针作为形参接收


一、数组传参简介

在使⽤函数解决问题的时候,难免会将数组作为参数传递给函数,在函数内部对数组进⾏操作。

数组作为参数传递给函数,不同于普通的变量传参,本篇博客将详细介绍数组传参的规则和实际用法

二、数组传参规则

数组传参,形参是不会创建新的数组的。 形参操作的数组和实参的数组是同⼀个数组

1. 数组传参的实参传递

数组名作为实参传递 ,在通常情况下数组名就是首元素的地址

但是有两个意外

1.sizeof(数组名),数组名单独放在sizeof()内部,这里的数组名表示整个数组,计算的是数组大小,单位是字节

2.&数组名,这里的数组名也是表示整个数组,取出的是整个数组的地址

数组地址和数组首元素地址不同表现在各自地址都是首元素地址,但是各自加1后,前者跳过整个数组,后者跳过第一个元素

除此之外所有遇到的数组名都表示数组首元素的地址。

1.1  特殊情况一:sizeof(数组名)

——此时数组名表示整个数组,函数返回整数的大小,单位是字节

#include<stdio.h>
int main()
{
	int arr[] = { 1,2,3,4,5,6 };
	printf("%d\n", sizeof(arr));
	return 0;
}

1.2  特殊情况二:&数组名

——此时数组名表示整个数组的地址

不同于一般传参时的数组首元素地址,该地址+1后直接跳过整个数组的地址

#include<stdio.h>
int main()
{
	int arr[] = { 1,2,3,4,5 };
	printf("%p\n", arr);
	printf("%p\n", &arr[0]);
	printf("%p\n", &arr);
	return 0;
}

 在这三种情况下,三种输出的结果是相同的,输出的都是数组首元素的地址

但如果是地址+1的话,数组名+1 就不同于&数组名+1

#include<stdio.h>
int main()
{
	int arr[] = { 1,2,3,4,5 };
	printf("%p\n", arr);
	printf("%p\n", &arr[0]);
	printf("%p\n", &arr);

	printf("%p\n", arr + 1);
	printf("%p\n", &arr + 1);

	return 0;
}

2.  数组传参的形参接收

2.1 数组传参使用数组名作为形参接收
形参如果是⼀维数组

数组大小可以省略不写,但是数组作为形参,后面的 [ ] 不可以省略

比如可以写成arr[ ] 或者arr[8]

#include<stdio.h>
void set(int arr[], int sz) //将数组所有元素置为-1
{
	for (int i = 0; i < sz; i++)
	{
		arr[i] = -1;
	}
}
void print(int arr[], int sz)//依次打印数组所有元素
{
	for (int i = 0; i < sz; i++)
	{
		printf("%d ", arr[i]);
	}
	printf("\n");
}
int main()
{
	int arr[] = { 0,1,2,3,4,5,6,7 };
	int sz = sizeof(arr) / sizeof(arr[0]);//计算数组元素的个数
	print(arr, sz);
	set(arr, sz);
	print(arr, sz);
}

形参如果是⼆维数组

行可以省略,但是列不能省略,并且每个[ ]都不能省略

比如可以写成 arr[ ][3] 或者arr[3][3]

#include<stdio.h>
void set(int arr[][3], int sz) //将数组所有元素置为-1
{
	for (int i = 0; i < sz; i++)
	{
		for (int j = 0; j < 3; j++)
		{
			arr[i][j] = -1;
		}
	}
}
void print(int arr[][3], int sz)//依次打印数组所有元素
{
	for (int i = 0; i < sz; i++)
	{
		for (int j = 0; j < 3; j++)
		{
			printf("%d ", arr[i][j]);
		}
		printf("\n");
	}
	printf("\n");
}
int main()
{
	int arr[][3] = {0,1,2,3,4,5,6,7,8};
	int sz = sizeof(arr) / sizeof(arr[0]);//计算数组元素的行数

	print(arr, sz);
	set(arr, sz);
	print(arr, sz);
}

2.2 数组传参使用指针作为形参接收

形参使用指针接收之后,得到的是一个数组首元素的地址

得到数组首元素地址之后,就可以对数组任意元素进行操作

#include<stdio.h>
void set(int* arr,int sz) //将数组所有元素置为-1
{
	for (int i = 0; i < sz; i++)
	{
		arr[i] = -1;
	}
}
void print(int* arr, int sz)//依次打印数组所有元素
{
	for (int i = 0; i < sz; i++)
	{
		printf("%d ", arr[i]);
	}
	printf("\n");
}
int main()
{
	int arr[] = { 0,1,2,3,4,5,6,7 };
	int sz = sizeof(arr) / sizeof(arr[0]);//计算数组元素的个数
	print(arr, sz);
	set(arr, sz);
	print(arr, sz);
}

### 如何在编程语言中传递数组作为函数参数 #### C 语言中的数组传递 当在 C 语言中传递数组作为函数参数时,通常有两种主要的方式:按值传递和按地址传递。对于一维或多维数组而言,实际上传递给函数的是数组首元素的地址。 在一维数组的情况下,可以通过指定数组名称来实现隐式的指针传递: ```c void processArray(int *arr, int size) { for (int i = 0; i < size; ++i) { printf("%d ", arr[i]); } } ``` 上述代码展示了如何接收一个整型数组并打印其中的元素[^2]。 对于多维数组,则需要更具体地说明每一维度的大小(除了最左边的一级外),因为编译器需要知道每行有多少列以便计算偏移量。例如,在处理二维数组时,可以这样定义函数签名: ```c void Print2DArray(int rows, int cols, int array[rows][cols]) { for (int r = 0; r < rows; ++r++) { for (int c = 0; c < cols; ++c) { printf("%d ", array[r][c]); } printf("\n"); } } ``` 这里 `Print2DArray` 接受两个额外的参数用于描述输入矩阵的尺寸,并按照这些信息遍历整个结构[^3]。 另外一种常见的情况是在 C 或者 C++ 中使用双重指针 (`**`) 来表示动态分配的二维数组或其他复杂的数据结构。此时需要注意区分是指向单层还是多层次间接寻址的对象。比如下面的例子展示了一个字符串列表(即字符指针数组)是如何被修改成指向新的内存区域而不影响原始变量本身所指向的位置之外的内容[^4]。 ```c #include <stdio.h> #include <stdlib.h> // 假设 ppStr 是一个已经初始化好的 char* 数组 char **pp; void modifyPointers(char **ppStr) { // 这里创建一个新的字符串并让局部变量 p 指向它 char *newString = malloc(strlen("New String") + 1); strcpy(newString, "New String"); // 修改传入的指针使其指向新分配的空间 *pp = newString; free(ppStr); // 如果有必要释放旧资源的话... } int main() { // 初始化 ppStr ... modifyPointers(&pp); return 0; } ``` 这段程序片段解释了如果想要改变外部作用域内的某个指针的实际位置,就需要传递它的地址进去;而不仅仅是复制一份内部使用的拷贝。 #### 多范式编程下的数组传递 考虑到某些现代编程语言可能支持多种编程风格,如仓颉这样的语言允许混合使用不同类型的编程模型。这意味着即使在一个简单的数组传递场景下也可以利用高级特性简化逻辑或增强安全性。例如,在函数式编程环境中可能会采用不可变数据集合以及纯函数来确保线程安全性和可预测的行为;而在面向对象的设计里面则会倾向于构建专门负责管理特定类型容器类实例的方法[^1]。
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

倔强的石头_

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

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

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

打赏作者

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

抵扣说明:

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

余额充值