指针进阶的哪些复杂概念可以组合成一个长尾词?

2026-04-11 22:421阅读0评论SEO资讯
  • 内容介绍
  • 文章标签
  • 相关推荐

本文共计1171个文字,预计阅读时间需要5分钟。

指针进阶的哪些复杂概念可以组合成一个长尾词?

使用数组参数、指针参数以及一维数组传递参数进行函数调用。

03数组参数、指针参数

一维数组传参

#include <stdio.h> //形参写成数组形式 void test(int arr[]) {} void test(int arr[10]) {} /形参写成指针形式 void test(int *p) {} void test2(int *arr[]) {} void test2(int *arr[20]) {} void test2(int** p) {} int main() { int arr[10] = {0}; int *arr2[20] = {0}; test(arr); test2(arr2); return 0; }

二维数组传参

//形参写成数组的形式 void test(int arr[3][5]) {} //1. 行可以省略,但列不能省略 void test(int arr[][5]) {} //形参写成指针形式 //1. 列不可省略 //2. *p指向的是第一行的地址,5代表一行有多少个元素 //3. int *p[5]是错误的,它是一个指针数组 void test(int(*p)[5]) {} //错误写法 //1. 一级指针接受普通变量的地址 void test(int *arr) {} //2. 第一行的地址放在了一个数组里,错误 void test(int* arr[5]) {} //3. 二级指针是用来存放一级指针地址 void test(int** arr) {} int main() { int arr[3][5] = {0}; test(arr) return 0; }

一级指针传参

案例:一级指针传参遍历数组并打印;

void test(int* ptr, int sz) { int i = 0; for(i = 0; i < sz; i++) { printf("%d ", *ptr); ptr++; } } int main() { int arr[10] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10}; int* p = arr; int sz = sizeof(arr)/sizeof(arr[0]); test(p, sz); //p是一级指针 retuen 0; }

当形参是一级指针的时候 int* ptr,实参有以下情况:

//一级指针 int a = 10; test(&a); int *p = &a; test(p); //数组 int arr[10]; test(arr)

二级指针传参

void test(char** ppc) {} int main() { char a = 'w'; char* pa = &a; char** ppa = &pa; test(ppa); return 0; }

当函数的参数为二级指针的时候test(char** ppc),实参有如下情况:

char ch = 'a'; char* pc = &ch; char** ppc = &pc; char* arr[4]; test(arr); test(&pc); test(ppc);

函数指针

指向函数的指针,

指针进阶的哪些复杂概念可以组合成一个长尾词?

int Add(int x, int y) { return x + y; } int test(char* str) {} int main() { int arr[10]; int (*p)[10] = &arr; //p是一个数组指针变量 //函数地址 printf("%p\n", &Add); printf("%p\n", Add); int (*pf)(int int) = Add; //pf就是函数指针变量 int (*pt)(char*) = test; //调用函数 int ret = (*pf)(2,3); //int ret = pf(2,3); //int ret = Add(2,3); printf("%d\n", ret); return 0; }

来自《C陷阱与缺陷》的一个例子:如何解释

  1. (*(void(*)())0)()
  2. void(* signal(int, void(*)(int)))(int)

int main() { //代码1: //void(*)() 是一个函数指针类型 //(void(*)()())0 对0进行强制类型转换 //(*(void(*)()())0)() //1. 首先是把0强制类型转换为一个函数指针类型,这就意味着0地址处放一个返回类型是void,无参的一个函数 //2. 调用0地址处的这个函数 //代码2: //函数声明:int Add(int, int) //signal是一个函数声明 //signal函数的参数,第一个是int类型,第二个是void(*)(int)的函数指针类型 //signal函数的返回值类型也是:void(*)(int)的函数指针 //简化: //typedof void(* pf_t)(int); //给函数指针类型void(*)(int)重新起名叫:pf_t //pf_t signal(int,pf_t); return 0; }

函数指针数组

int Add(int x, int y) { return x+y; } int Sub(int x, int y) { return x-y; } int Mul(int x, int y) { return x*y; } int Div(int x, int y) { return x/y; } int main() { //指针数组 //字符指针数组 char* arr[5]; //整形指针数组 int* arr2[4]; int (*pf1)(int, int) = Add; int (*pf2)(int, int) = Sub; int (*pf3)(int, int) = Mul; int (*pf4)(int, int) = Div; //函数指针数组 int (*pf[4](int, int)) = {Add, Sub, Mul, Div}; int i = 0; for(i = 0; i<4; i++) { pf[i](8,2); printf("%d\n", ret); } return 0; }

案例:设计一个简单的计算器

#include <stdio.h> int Add(int x, int y) { return x + y; } int Sub(int x, int y) { return x - y; } int Mul(int x, int y) { return x * y; } int Div(int x, int y) { return x / y; } void menu() { printf("**************************\n"); printf("**** 1.add 2.sub ****\n"); printf("**** 3.mul 4.div ****\n"); printf("**** 0.exit ****\n"); printf("**************************\n"); } int main() { int input = 0; int x = 0; int y = 0; int ret = 0; //转移表 int (*pfArr[])(int, int) = {0, Add, Sub, Mul, Div}; do { menu(); printf("请选择:>"); scanf("%d", &input); if(input == 0) { printf("退出计算器\n"); } else if(input >= 1 && input <=4) { printf("请输入两个操作数:>"); scanf("%d %d", &x, &y); ret = pfArr[input](x, y); printf("ret = %d\n", ret); } else { printf("选择错误\n"); } }while(input); return 0; }

03-10



本文共计1171个文字,预计阅读时间需要5分钟。

指针进阶的哪些复杂概念可以组合成一个长尾词?

使用数组参数、指针参数以及一维数组传递参数进行函数调用。

03数组参数、指针参数

一维数组传参

#include <stdio.h> //形参写成数组形式 void test(int arr[]) {} void test(int arr[10]) {} /形参写成指针形式 void test(int *p) {} void test2(int *arr[]) {} void test2(int *arr[20]) {} void test2(int** p) {} int main() { int arr[10] = {0}; int *arr2[20] = {0}; test(arr); test2(arr2); return 0; }

二维数组传参

//形参写成数组的形式 void test(int arr[3][5]) {} //1. 行可以省略,但列不能省略 void test(int arr[][5]) {} //形参写成指针形式 //1. 列不可省略 //2. *p指向的是第一行的地址,5代表一行有多少个元素 //3. int *p[5]是错误的,它是一个指针数组 void test(int(*p)[5]) {} //错误写法 //1. 一级指针接受普通变量的地址 void test(int *arr) {} //2. 第一行的地址放在了一个数组里,错误 void test(int* arr[5]) {} //3. 二级指针是用来存放一级指针地址 void test(int** arr) {} int main() { int arr[3][5] = {0}; test(arr) return 0; }

一级指针传参

案例:一级指针传参遍历数组并打印;

void test(int* ptr, int sz) { int i = 0; for(i = 0; i < sz; i++) { printf("%d ", *ptr); ptr++; } } int main() { int arr[10] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10}; int* p = arr; int sz = sizeof(arr)/sizeof(arr[0]); test(p, sz); //p是一级指针 retuen 0; }

当形参是一级指针的时候 int* ptr,实参有以下情况:

//一级指针 int a = 10; test(&a); int *p = &a; test(p); //数组 int arr[10]; test(arr)

二级指针传参

void test(char** ppc) {} int main() { char a = 'w'; char* pa = &a; char** ppa = &pa; test(ppa); return 0; }

当函数的参数为二级指针的时候test(char** ppc),实参有如下情况:

char ch = 'a'; char* pc = &ch; char** ppc = &pc; char* arr[4]; test(arr); test(&pc); test(ppc);

函数指针

指向函数的指针,

指针进阶的哪些复杂概念可以组合成一个长尾词?

int Add(int x, int y) { return x + y; } int test(char* str) {} int main() { int arr[10]; int (*p)[10] = &arr; //p是一个数组指针变量 //函数地址 printf("%p\n", &Add); printf("%p\n", Add); int (*pf)(int int) = Add; //pf就是函数指针变量 int (*pt)(char*) = test; //调用函数 int ret = (*pf)(2,3); //int ret = pf(2,3); //int ret = Add(2,3); printf("%d\n", ret); return 0; }

来自《C陷阱与缺陷》的一个例子:如何解释

  1. (*(void(*)())0)()
  2. void(* signal(int, void(*)(int)))(int)

int main() { //代码1: //void(*)() 是一个函数指针类型 //(void(*)()())0 对0进行强制类型转换 //(*(void(*)()())0)() //1. 首先是把0强制类型转换为一个函数指针类型,这就意味着0地址处放一个返回类型是void,无参的一个函数 //2. 调用0地址处的这个函数 //代码2: //函数声明:int Add(int, int) //signal是一个函数声明 //signal函数的参数,第一个是int类型,第二个是void(*)(int)的函数指针类型 //signal函数的返回值类型也是:void(*)(int)的函数指针 //简化: //typedof void(* pf_t)(int); //给函数指针类型void(*)(int)重新起名叫:pf_t //pf_t signal(int,pf_t); return 0; }

函数指针数组

int Add(int x, int y) { return x+y; } int Sub(int x, int y) { return x-y; } int Mul(int x, int y) { return x*y; } int Div(int x, int y) { return x/y; } int main() { //指针数组 //字符指针数组 char* arr[5]; //整形指针数组 int* arr2[4]; int (*pf1)(int, int) = Add; int (*pf2)(int, int) = Sub; int (*pf3)(int, int) = Mul; int (*pf4)(int, int) = Div; //函数指针数组 int (*pf[4](int, int)) = {Add, Sub, Mul, Div}; int i = 0; for(i = 0; i<4; i++) { pf[i](8,2); printf("%d\n", ret); } return 0; }

案例:设计一个简单的计算器

#include <stdio.h> int Add(int x, int y) { return x + y; } int Sub(int x, int y) { return x - y; } int Mul(int x, int y) { return x * y; } int Div(int x, int y) { return x / y; } void menu() { printf("**************************\n"); printf("**** 1.add 2.sub ****\n"); printf("**** 3.mul 4.div ****\n"); printf("**** 0.exit ****\n"); printf("**************************\n"); } int main() { int input = 0; int x = 0; int y = 0; int ret = 0; //转移表 int (*pfArr[])(int, int) = {0, Add, Sub, Mul, Div}; do { menu(); printf("请选择:>"); scanf("%d", &input); if(input == 0) { printf("退出计算器\n"); } else if(input >= 1 && input <=4) { printf("请输入两个操作数:>"); scanf("%d %d", &x, &y); ret = pfArr[input](x, y); printf("ret = %d\n", ret); } else { printf("选择错误\n"); } }while(input); return 0; }

03-10