C语言进阶:指针的进阶(3)

 更新时间:2021年09月02日 14:42:16   作者:AKA你的闺蜜  
这篇文章主要介绍了C语言指针详解及用法示例,介绍了其相关概念,然后分享了几种用法,具有一定参考价值。需要的朋友可以了解下

数组传参和指针传参

实践之中不免会碰到数组和指针作函数参数而如何设计形参的问题。

一维数组传参

一维数组传参,下列接收方式是否可行呢?

//1.
void test(int arr[]) 
{}
//2.
void test(int arr[10]) 
{}
//3.
void test(int* arr) 
{}
int main()
{	
	int arr[10] = { 0 };
	test(arr);
	return 0;
}

1.数组传参数组接收,可行但其实都会降级优化成指针,编译器不会真正创建一个数组。

2.由于形参数组形同虚设,所以数组大小无意义,任意大小或无。(有歧义)

3.数组传参本质就是首元素地址,首元素类型为int,所以指针的类型为int*。

所以可以看出[]和*()是等价的。我愿称之为*和[]的爱恨情仇!(‐^▽^‐)

//1.
void test2(int* arr[2])
{}
//2.
void test2(int** arr) 
{}
int main()
{	
	int* arr2[10] = { 0 };
	test2(arr2);
	return 0;
}

指针数组,每个元素类型为int*,故用二级指针接收数组名。

一维数组传参,数组和指针接收。

二维数组传参

//1.
void test(int arr[3][5]) 
{}
//2.
void test(int arr[][])
{}
//3.
void test(int arr[][5])
{}
int main() {
	int arr[3][5] = { 0 };
	test(arr);
}
  • 二维数组传参用二维数组接收,行可省略,但列不可以
//4.
void test(int* arr)
{}
//5.
void test(int* arr[5])
{}
//6.
void test(int(*arr)[5])
{}
//7.
void test(int** arr)
{}
int main() {
	int arr[3][5] = { 0 };
	test(arr);
}

4.整型指针接收的应该是整型变量的地址,而二维数组数组名为首行的数组地址。

5.指针数组和二维数组无关。

6.二维数组传参用首行数组大小的数组指针接收。

7.二级指针和二维数组无关。

  • 二维数组数组名arr为首行“一维数组”的地址,数组的地址用数组指针接收。

int(*)[5]型数组指针指向元素个数为5的一维数组。指针+1访问到下一行,每次跳一行。再解一层引用访问一行里每个元素。

一级指针传参

反向思考,若函数形参为指针,传参时实参可以如何设计呢?

void test(int* ptr, int sz)
{}
void test(int arr[],int sz)
{}
int main()
{
    //1.
    int a = 10;
    test(&a);
    //2.
	int arr[10] = { 0 };
	test(arr);
	return 0;
}
  • 一级指针传参,形参用指针和数组都行,但不提倡用一维数组。
  • 若形参为指针,实参也可以是指针(地址),也可以是数组。

二级指针传参

当二级指针作参数时,形参如何设计呢?

void test(int** pp) {
	printf("%d\n", **pp);
}
void test(int* arr[]) {//用法不好
	printf("%d\n", *arr[0]);
}
int main() {
	int a = 10;
	int* p = &a;
	int** pp = &p;
	test(pp);
	return 0;
}
  • 当二级指针作函数参数时,形参可以是二级指针和指针数组。

当形参为二级指针,实参可以传什么呢?

void test(int** pp) {
	printf("%d\n", **pp);
}
int main() {
	int a = 10;
	int* p = &a;
	int** pp = &p;
	int* arr[10] = { &a };
    //1.
	test(&p);
    //2.
	test(pp);
    //3.
	test(arr);
	return 0;	
}
  • 当形参为二级指针时,实参可以是:二级指针(一级指针地址),指针数组首元素的地址。

总结

本篇文章就到这里了,希望能够给你带来帮助,也希望您能够多多关注脚本之家的更多内容!

相关文章

  • c++核心编程之函数的重载

    c++核心编程之函数的重载

    这篇文章主要介绍了c++核心编程之函数的重载,函数可以重复使用,提高了复用性,但前提是必须在一个作用域并且函数名称相同,下面附代码详细介绍,需要的小伙伴可以参考一下
    2022-03-03
  • 详解C语言初阶之函数

    详解C语言初阶之函数

    这篇文章主要介绍了C语言中的初阶函数,介绍了其相关概念,具有一定参考价值。需要的朋友可以了解下,希望能够给你带来帮助
    2021-11-11
  • C语言递归思想实现汉诺塔详解

    C语言递归思想实现汉诺塔详解

    大家好,本篇文章主要讲的是C语言递归思想实现汉诺塔详解,感兴趣的同学赶快来看一看吧,对你有帮助的话记得收藏一下
    2022-01-01
  • C++高性能服务器框架之协程调度模块

    C++高性能服务器框架之协程调度模块

    这篇文章主要介绍了C++高性能服务器框架中的协程调度模块,文中通过代码示例介绍的非常详细,对我们的学习或工作有一定的帮助,需要的朋友可以参考下
    2023-06-06
  • 解析C++中的5个存储类的作用

    解析C++中的5个存储类的作用

    这篇文章主要介绍了C++中的5个存储类的作用,存储类是管理对象的生存期、链接和内存位置的类型说明符,需要的朋友可以参考下
    2016-05-05
  • C语言简明讲解变量的属性

    C语言简明讲解变量的属性

    我们知道以在 C 语言中的变量有自己的属性,只要在定义变量的时候加上“属性”关键字即可。“属性”关键字指明变量的特有意义,但是 register 关键字只是请求寄存器变量,所以不一定会成功
    2022-04-04
  • C++ 使用 new 创建二维数组实例

    C++ 使用 new 创建二维数组实例

    这篇文章主要介绍了C++ 使用 new 创建二维数组实例的相关资料,需要的朋友可以参考下
    2023-01-01
  • C++实现LeetCode(36.验证数独)

    C++实现LeetCode(36.验证数独)

    这篇文章主要介绍了C++实现LeetCode(36.验证数独),本篇文章通过简要的案例,讲解了该项技术的了解与使用,以下就是详细内容,需要的朋友可以参考下
    2021-07-07
  • C++ Virtual关键字的具体使用

    C++ Virtual关键字的具体使用

    这篇文章主要介绍了C++ Virtual关键字的具体使用,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2020-11-11
  • C++STL函数和排序算法的快排以及归并排序详解

    C++STL函数和排序算法的快排以及归并排序详解

    这篇文章主要为大家详细介绍了C++STL函数和排序算法的快排以及归并排序,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下,希望能够给你带来帮助
    2022-03-03

最新评论