【C生万物】 指针篇 (进级) 下(一)

简介: 【C生万物】 指针篇 (进级) 下

前言


370e28d82132798f78a90e533d2c4256_e6510fde102248338c249440750db93e.png


承接上篇,这期继续C语言指针的学习。


目录


Part4:数组参数&指针参数

1.一维数组传参

2.二维数组传参

3.一级指针传参

4.二级指针传参

Part5:函数指针

1.引入

2.表示

Part6:函数指针数组

1.引入

2.表示

3.应用

Part7:回调函数

1.定义

2.应用


正文


Part4:数组参数&指针参数


在敲代码时经常会有这样的情景:把【数组】或者【指针】传递给函数,那么函数该如何设计呢?这一部分会解答这个问题。


1.一维数组传参


我将用这段代码来测试传参的正确姿势:


int main()
{
  int arr1[10] = { 0 };
  int* arr2[20] = { 0 };
  test1(arr1);
  test2(arr2);
  return 0;
}


看下列传参方式是否可行:


1. void test1(int arr[])
2. {}
3. // 可行:传数组,用数组接收,可以不指定大小


void test1(int arr[10])
{}
// 可行:传数组,用数组接收,大小保持一致


void test1(int* arr)
{}
// 可行:数组名代表首元素地址,用指针接收


void test2(int* arr[])
{}
// 可行:传递指针数组,用指针数组接收,可以不指定大小


void test2(int* arr[20])
{}
// 可行:传递指针数组,用指针数组接收,大小保持一致


void test2(int** arr)
{}
// 可行:数组名代表首元素地址,首元素类型是 int* ,地址类型是二级指针 int** 


总结:一维数组传参,要么用数组接收, 要么用指针接收


2.二维数组传参


测试代码:


int main()
{
  int arr[3][5] = { 0 };
  test(arr);
}


看下列传参方式是否可行:


void test(int arr[3][5])
{}
// 可行:相同形式接收


void test(int arr[][5])
{}
// 可行:指定列必须,行可以省略


void test(int arr[][])
{}
// 不可行:没有指定列



void test(int* arr)
{}
// 不可行:传递的二维数组,起码用首行的地址接收


void test(int* arr[5])
{}
// 不可行:形参表示指针数组,与实参数组的类型不匹配


void test(int(*arr)[5])
{}
// 可行:表示第一行的地址


void test(int** arr)
{}
// 不可行:形参表示二级指针,不可接受二维数组


总结:


二维数组传参,函数形参若为数组类型,其设计只能省略第一个[ ] 的数字,

因为对一个二维数组,可以不知道有多少行,但是必须知道一行多少元素。

若为指针类型,是第一行的地址


3.一级指针传参


一级指针传参简单,用一级指针接收就好了。


下面是例子:


#include <stdio.h>
void print(int *p, int sz)
{
 int i = 0;
 for(i=0; i<sz; i++)
 {
 printf("%d\n", *(p+i));
 }
}
int main()
{
 int arr[10] = {1,2,3,4,5,6,7,8,9};
 int *p = arr;
 int sz = sizeof(arr)/sizeof(arr[0]);
 //一级指针p,传给函数
 print(p, sz);
 return 0;
}


👁️‍🗨️输出结果:


c06abbc5832b5ad6ada9db6cca313422_734df73c4cac493c8f72a5152f70432f.png


没意思吧?


那我们反过来想:当形参是一级指针的时候,函数能接收什么参数?


void test(int *p)
{}
// test函数能接收什么参数?


int a = 10;
int* p = &a;
int arr[10];
// 接收以下参数
test(&a);
test(p);
test(arr);


4.二级指针传参


同一级指针,二级指针传参,二级指针接收就行了。


例子:


void test(int** ptr)
{
  printf("num = %d\n", **ptr);
}
int main()
{
  int n = 10;
  int* p = &n;
  int** pp = &p;
  test(pp);
  test(&p);
  return 0;
}


👁️‍🗨️输出结果:


bfed81bf18f197941155d9c74fb90668_48cb08ae67df49f2b318aed2e0e2bc30.png


反过来想: 当形参是二级指针的时候,函数能接收什么参数?


void test(int** pp)
{}
// 能接收什么参数?


int a = 10;
int* pa = &a;
int** ppa = &pa;
int* arr[10];
// 接收以下参数
test(&pa);
test(ppa);
test(arr);



目录
相关文章
C生万物 | 从浅入深理解指针【最后部分】(二)
C生万物 | 从浅入深理解指针【最后部分】(二)
|
6月前
|
存储 C++
C生万物 | 从浅入深理解指针【第三部分】(转移表的实现)
C生万物 | 从浅入深理解指针【第三部分】(转移表的实现)
C生万物 | 从浅入深理解指针【第二部分】(二)
C生万物 | 从浅入深理解指针【第二部分】(二)
|
6月前
|
编译器
C生万物 | 从浅入深理解指针【第二部分】(一)
C生万物 | 从浅入深理解指针【第二部分】 前言: 如果没有看过第一部分的话,推荐先看第一部分,然后再来看第二部分~~
|
6月前
|
存储 C语言 C++
C生万物 | 从浅入深理解指针【第一部分】(一)
C生万物 | 从浅入深理解指针【第一部分】
|
6月前
|
机器学习/深度学习 安全 程序员
C生万物 | 从浅入深理解指针【第一部分】(二)
C生万物 | 从浅入深理解指针【第一部分】(二)
|
6月前
|
C语言 C++
C生万物 | 从浅入深理解指针【最后部分】(一)
C生万物 | 从浅入深理解指针【最后部分】(一)
C生万物 | 从浅入深理解指针【第四部分】(qsort的使用和模拟实现)
C生万物 | 从浅入深理解指针【第四部分】(qsort的使用和模拟实现)
|
11月前
|
存储 编译器 C语言
C生万物 | 指针进阶 · 炼狱篇-3
C生万物 | 指针进阶 · 炼狱篇
67 0
|
11月前
C生万物 | 指针进阶 · 炼狱篇-2
C生万物 | 指针进阶 · 炼狱篇
51 0