指针数组,数组指针,函数指针、指针函数、函数指针数组
曾经的我是一个摆男,一言不合就开摆,直到我遇见了电子厂。。。。发生了一些不可描述的事,让我看清了社会的真相。。。
进入正题!
分析时的两个步骤:是什么?怎么用?
是什么?
1、指针数组:本质是数组,数组中存储的每个元素是指针
怎么用?
以遍历数值指针数组为例,int* arr[4] = { &num1,&num2,&num3,&num4 };就是数值指针数组
void t1(){int num1 = 10;int num2 = 20;int num3 = 30;int num4 = 40;int* arr[4] = { &num1,&num2,&num3,&num4 };int n = sizeof(arr) / sizeof(arr[0]);int i = 0;for (i = 0;i < n;i++){printf("%3d", *arr[i]);}printf("\n");}int main(int argc,char *argv[]){t1();return 0;}
输出的时候为:*arr[i] 因为*()等价于[],所以也可以写成:**(arr + i)
这里讲一下:&arr[i] == (arr + i) 然后*arr[i] == **(arr + i)
不要搞混了
以遍历字符串指针数组为例,int* arr[4] = { "tienan","nuoshou","wanhao","jianmo" };就是字符串指针数组
#include <stdio.h>void t2()
{char *arr[4] = {"tienan","nuoshou","wanhao","jianmo",};char* brr[4] = { "铁男","诺手","腕豪","剑魔" };int n = sizeof(arr) / sizeof(arr[0]);int i = 0;for (i = 0;i < n;i++){printf("%10s", arr[i]);//printf("%10s",*(arr + i));//选一种输出即可}printf("\n");for (i = 0;i < n;i++){printf("%10s", brr[i]);}printf("\n");//想把tienan的e打印出来怎么办?/***************难点******************///第一种,数组的方式printf("%10c\n",*(arr[0] + 2));
//解析:arr[0]是“tienan”这个首元素的首字母地址,直接指向t,+2之后指向e,把e的打出来取*//第二种,指针的方式printf("%10c\n",*(*arr + 2));
//解析:arr是数组首元素地址,指向第一个元素,也就是”tienan“,*arr是取到第一个元素的第一个字母内容,也就是t,也就是*arr 和arr[0]等价,再+2之后指向e,把e打印出来再取*//思考:下面这个输出什么?printf("%10c\n",**arr + 2);printf("\n");
}
int main(int argc,char *argv[])
{t2();return 0;
}
输出的时候为:arr[i]
因为字符串输出的时候是给首地址,所以输出少一个 *
为什么输出的是v? 因为*arr是取到 t 嘛,再取 * 是把它打印出来,**arr + 2就是打印 t 后面ASCII码值 +2 的字母。
arr是数组的首元素地址,&arr是数组的首地址,它们两个表示的地址相同,但是概念不同。对首地址取 * ,得到数组首元素地址。也就是说 *&arr 和 arr 等价。所以,对首地址 +1 ,偏移一个数组;对首元素 +1 ,偏移一个元素,对 *(首元素) +1 ,偏移一个字母。BUT!!对于数组指针来说,数组名只代表第0行的行地址(有些人说是第一行,无所谓,就是最开始的那一行),接下来要讲的是数组指针
继续!
2、数组指针:本质是指针,指向一个数组,指针的值是数组的地址
以数组指针遍历数值数组元素为例
#include <stdio.h>
void t3()
{int arr[2][3] = {1,2,3,4,5,6};int (*p)[3] = arr;//写成int (*p)[3] = &arr;也行,但是要报警告//写成int (*p)[3] = NULL;p = arr也行,这个不报警告//下面输出0行1列元素,也就是2,两种方式可任选一种printf("arr[0][1] = %d\n",*(*(p + 0) + 1));//*(*(p+0) + 1) == *(arr[0] + 1) == arr[0][1]//printf("arr[0][1] = %d\n",arr[0][1]);//这种是数组的方式//下面看+1后偏移多少printf("arr[0][0] = %d\n",**p);printf("arr[a][b] = %d\n",*(*(p+0)+0) + 1);//(**p + 1)printf("arr[c][d] = %d\n",**(p + 1));printf("arr[e][f] = %d\n",*(*p + 1));//下面看指向的地址printf("%p\n",**p);printf("%p\n",**p + 1);printf("%p\n",**(p + 1));printf("%p\n",*(*p + 1));//下面是数组指针遍历数组元素int i,j;for(i = 0;i < 2;i++){for(j = 0;j < 3;j++){printf("%3d",*(*(p + i) + j));//printf("%3d",arr[i][j]);}}printf("\n");//也可以用这种方式连续输出for(i = 0;i < 6;i++){printf("%3d",*(*p + i));}printf("\n");
}
int main(int argc, char *argv[])
{ t3();return 0;
}
继续!
3、函数指针:本质是指针,指向一个函数,指针的值是函数的地址
以下是函数指针普通用法
#include <stdio.h>int fun_jia(int a,int b){return a+b;}void t4(){int (*p)(int,int) = fun_jia;//写成int (*p)(int a,int b)也行//写成int (*p)(int x,int y) = &fun_jia;也行//写成int (*p)(int x,int y) = fun_jia;也行//写成int (*p)(int,int) = NULL;p = fun_jia;也行printf("%d\n",fun_jia(1,2));//输出的fun_jia(1,2)不能取地址!}int main(int argc, char *argv[]){ t4();return 0;}
以下是函数指针进阶用法
#include <stdio.h>int fun_jia(int a,int b){int c = a + b;return c;//或者直接写成return a + b;}int fun_jian(int a,int b){return a - b;}
//新定义一个函数,用函数指针调用上面定义的函数int func(int a,int b,int(*p)(int,int)){return p(a,b);}void t4(){printf("%2d\n",func(1,2,fun_jia));printf("%2d\n",func(1,2,fun_jian));}int main(int argc, char *argv[]){t4();return 0;}
注意:上面我没写函数申明,但依然没有问题。是因为主函数在最下面。
继续!
4、指针函数:本质是函数,函数的返回值是指针。
#include <stdio.h>#include <stdlib.h>//malloc要用#include <string.h>//memset要用int *fun_jia(int a,int b);int *fun_jia(int a,int b){ int *p = (int *)malloc(sizeof(int));//在堆区申请空间,但不自动清0if(p == NULL)//预防空间申请失败,堆区满了就可能失败{return 0;//如果没有这个判断语句,如果p == NULL,就会报错} memset(p,0,sizeof(int));//手动清0*p = a + b;return p;free(p);//释放堆区空间,不想用了就释放} void t5(){int *p = fun_jia(1,2);//int *p = NULL;//p = fun_jia(1,2);//写成int *p = fun_jia(1,2);也行printf("%d\n",*p);}int main(int argc, char *argv[]){t5();return 0;}
继续!
5、函数指针数组:本质是数组,每个元素是函数地址,指针指向一个函数,指针的值是函数的地址,相当于函数指针int(*p)(int,int) = fun_jia;组合成数组的形式!而函数指针数组指针(指向函数指针数组的指针),它的每个元素是函数指针。别搞混了。。。
#include <stdio.h>int fun_jia(int a,int b);int fun_jian(int a,int b);int fun_jia(int a,int b){return a+b;}int fun_jian(int a,int b){return a-b;}void t6(){int (*p[2])(int,int) = {fun_jia,fun_jian};//定义函数指针数组//数组肯定要遍历嘛int i;for(i = 0;i < 2;i++){printf("%3d",p[i](1,2));}printf("\n");}int main(int argc, char *argv[]){t6();return 0;}
这里输入写成:int (*p[2])(int,int) = {&fun_jia,&fun_jian}; 也行。
这里输出写成:printf("%3d",(*(p + i))(1,2)); 也行。
难吗,不难!只写了4个小时。睡觉!
指针数组,数组指针,函数指针、指针函数、函数指针数组相关推荐
- c++函数内部可以返回函数内部定义的指针 但是不能返回函数内部定义的数组...
1.返回数组 // demo.cpp : 定义控制台应用程序的入口点. // #include "stdafx.h" #include<stdio.h> char *m ...
- 【C 语言】二级指针作为输入 ( 二维数组 | 抽象业务函数 | 二维数组打印函数 | 二维数组排序函数 )
文章目录 一.抽象 二维数组 业务函数 1.二维数组 打印函数 2.二维数组 排序函数 二.完整代码示例 一.抽象 二维数组 业务函数 1.二维数组 打印函数 注意 , 二维数组 作为 函数参数 输入 ...
- 【C 语言】一级指针 易犯错误 模型 ( 判定指针合法性 | 数组越界 | 不断修改指针变量值 | 函数中将栈内存数组返回 | 函数间接赋值形参操作 | 指针取值与自增操作 )
文章目录 一.判定指针合法性 二.数组越界 三.不断修改指针变量值 四.函数中将栈内存数组返回 五.函数间接赋值形参操作 六.指针取值与自增操作 一.判定指针合法性 判定指针合法性时 , 必须进行如下 ...
- 指针数组的初始化和遍历,并且通过for循环方式、函数传参方式进行指针数组的遍历...
1 /************************************************************************* 2 > File Name: messa ...
- 剖析数组名、函数名(不是指针常量,更不是指针)
对于一个数组,如 int a[4]; 如果只是给出数组名a,编译器不知道该取该数组的第几个元素,因此编译器不会自动取值,而是返回该数组的首地址(第一个元素的地址).其实,数组名a就是数组本身,并不是 ...
- 【C语言进阶深度学习记录】三十一 数组作为函数参数时退化为指针
之前的学习数组的文章中,已经知道一维数组作为函数参数的时候,最终会被编译器编译为指针.今天来看看二维数组的情形 文章目录 1 为什么C语言中的数组作为函数参数会退化为指针? 2 二维数组作为函数参数如 ...
- C++(12)--函数基础:按值传递、传递数组、函数指针
模块化编程--函数 1. 函数基本知识 2. 函数的参数 2.1 按值传递机制(小议按引用传递) 2.2 使用数组做函数参数(用户头文件,const的防改) 2.3 使用二维数组作为函数的参数 2.4 ...
- 常量 数组 函数 枚举 结构体与指针
与指针括起来的是指针(*a) int const *a = &b; /* 常量指针 */ int (*a)[5]; /* 数组指针 */ int (*add)(int a, int b); / ...
- 【C语言指针】 回调函数、冒泡函数模拟实现qsort、指针和数组笔试题解析
目录 一.回调函数 定义: 用回调函数形式实现加法运算 二.qsort 函数参数: void指针 用qsort排序整型和结构体 用冒泡函数模拟实现qsort,排序整型和结构体 三.指针和数组笔试题解析 ...
- 函数指针,函数指针数组,函数返回值为函数指针
函数的名字就是函数的首地址:定义函数指针; int (*p)(int ) p为函数指针变量名字,int 为函数的返回值类型为int型:(int)为函数的形参类型为int型, 注:因为优先级所以 ...
最新文章
- 3D Touch介绍: 一个数字压力器App和Quick Actions
- 树莓派连接显示器不亮屏的解决方案
- javascript的族家族史
- Magic Leap大举进军AR医疗:新品率先与医疗机构合作,挖走HoloLens老客户
- 基本概念,BGP协议的特征和消息类型,状态转换?
- UBUNTU安装 Rabbitvsc可视化版本控制客户端软件
- ArcGIS实验教程——实验十三:栅格空间插值分析
- 【汇编语言】王爽实验8,分析一个奇怪的程序,学习笔记(20200517)
- 小米又给员工发福利了! 逾3亿港元457人分
- 数字资产价值巨大,GMQGroup深入布局挖掘数字财富
- 12bit的图像如何向8bit转化_光端机该如何配置?
- OBS 录制黑屏的解决方法
- Infor SyteLine ERP 安装后中文语言设置
- 支配树 Dominator Tree
- Edge检查更新时出错:无法连接到Internet。如果使用防火墙,请将 MicrosoftEdgeUpdate.exe 加入允许列表中。
- 关于模拟京东二维码登录失败的解决方案
- 天之博特 多车协同:Waiting for subscriber to connect to /tianbot_1/cmd_vel 解决办法
- post-processing effects HDR
- FlatBuffer
- AnyTXT 一款强大的本地文件内容搜索软件