前言
首先我们对于数组名有个理解:
1. 数组名单独放在 sizeof () 内部,数组名表示整个数组,计算的是整个数组的大小,单位是字节;
2. & 数组名,数组名表示的是整个数组,取出的是数组的地址;
3. 除此之外,所有遇到的数组名都表示数组首元素的地址.
其次我们要知晓指针和数组的区别:
1. 数组和指针访问元素的过程不一样。由于数组的名字就是数组第一个元素的地址,而指针的名字是指针的地址,指针地址里的内容 是数组首元素的地址,所以再用指针访问时会多一次间接寻址;
2. 虽然数组名被解释为指向第一个元素的指针,但用 sizeof () 可以看出不同;
3. 指针名是可以被修改的左值,而数组名是不可以被修改的;
4.定义一个字符指针并初始化一个字符串和定义一个数组并初始化一个字符串是不一样的.
指针数组和数组指针
区别:数组指针只是一个指针变量,似乎是C语言里专门用来指向二维数组的,它占有内存中一个指针的存储空间。
指针数组是多个指针变量,以数组形式存在内存当中,占有多个指针的存储空间.
我们先来看一个指针数组的定义:
int(*p)[10];
//解释:p先和*结合,说明p是一个指针变量,然后指着指向的是一个大小为10个整数的数组。所以p是一个指针,指向一个数组,叫做指针数组。
//这里要注意:[]的优先级高于*号,所以必须加上()来保证p先和*结合。
我们再来看一个数组指针的定义:
int *p[n];
//[]优先级高,先与p结合成为一个数组,再由int*说明这是一个整型指针数组,它有n个指针类型的数组元素。
函数指针
首先看一段代码
#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include<Windows.h>
void test()
{
printf("hello world");
}
int main()
{
printf("%p\n", test);
printf("%p\n", &test);
system("pause");
return 0;
}
我们可看到输出的结果:
输出的是两个地址,这两个地址是 test 函数的地址。
那我们的函数的地址想要保存下来,就需要借助我们的函数指针
void (*pf)();
pf先和*结合,说明pf是一个指针,指针指向一个函数,指向的函数无参数,返回值的类型是void.
函数指针数组
把函数的地址存到一个数组中,那这个数组就叫做函数指针数组.
int (*parr1[10])();
int *parr2[10]();
int (*)() parr3[10];
这里选择第一个,这里就定义了一个函数指针数组。
parr1 先和 [] 结合,说明parr1是数组,数组的内容是什么呢? 是 int (*)() 类型的函数指针。
用它来实现一个最简单的计算器了,如下:
#include <stdio.h>
int add(int a, int b)
{
return a + b;
}
int sub(int a, int b)
{
return a - b;
}
int mul(int a, int b)
{
return a*b;
}
int div(int a, int b)
{
return a / b;
}
int main(){
int x, y;
int input=0;
int ret = 0;
int(*p[5])(int x, int y) = { 0, add, sub, mul, div }; //转移 表
printf("选择操作(0~4):>") ;
scanf("%d",&input);
printf("输入2个操作数:>");
scanf("%d %d",&x,&y);
ret = (*p[input])(x, y); //类似数组那样调用就可以了
printf( "ret = %d\n", ret);
return 0;
}
指向函数指针数组的指针
指向函数指针数组的指针是一个 指针 ,指针指向一个 数组 ,数组的元素都是 函数指针 .