指针
1.指针变量
代码块
int i = 10;
int *p = &i;
内存分析
2.指针变量的使用
使用解引用符 * 对该指针指向的内存进行操作
代码块
利用指针变量改变i的值
int i = 10;
int *p = &i;
*p = 20;
数组
1.数组的定义
代码块
int arr[4];
内存分析
2.数组名
1.数组名作为参数,传过去的不是整个数组,而是该数组首元素的地址
2.数组名只有在以下两种情况下表示整个数组:
1)单独放在sizeof()的括号中
2)&数组名
指针和数组的恩怨
指针和数组本身没有任何关系,只是在访问指针或数组的时候有两种访问方法:
1).以指针的形式访问
2).以下标的形式访问
char *p = "abcde";
char p[] = "12345";
1.访问指针
读取字符c
1).以指针的形式访问:*(p+2)
先取出p中的地址值,再加上2个字符的偏移量,得到新的地址,然后取出这个地址存放的值
2).以下标的形式访问:p[2]
编译器会将下标的形式转化为指针的形式然后进行才操作
2.访问数组
读取字符‘4’
1).以指针的形式访问:*(p+3)
这时p代表的是数组首元素的地址,再加上3个元素大小(这里是字符)的偏移量,得到新的地址,然后取出这个地址存放的值
2).以下标的形式访问:p[3]
编译器会将下标的形式转化为指针的形式然后进行才操作
所以两种访问形式在本质上是相同的
3.指针数组和数组指针
1)指针数组是一个数组,它里面的元素都是指针
int *arr[5] ;
2)数组指针是一个指针,它指向的是一个数组
int (*p) [5];
&arr 与 arr的区别
arr表示数组首元素的地址,&arr表示数组的地址,两者在数值上是相同的,但意义不同
4.函数指针
函数指针的定义
int fun(int x ,int y);//fun函数的声明
int (*p)(int x,int y);//fun函数对应类型的函数指针p的定义
p的类型为int (*)(int,int),这表示p是一个函数指针,函数的参数有两个类型都是int,函数的返回值类型为int
函数指针的使用
int fun(int x ,int y)
int a,b;
int (*p)(int x,int y) = fun;
(*p)(a,b);//与fun(a,b)相同
注意:函数指针的可赋的值只能是与之类型相对应的指针
5.函数指针数组
这是一个数组,其中的元素是函数指针
下面分别是实现加减乘除功能的四个函数的声明,他们的函数参数个数类型即函数返回值的类型均相同,故可以将他们的函数地址都放在同一个函数指针数组中
int add(int x ,int y);
int sub(int x ,int y);
int mul(int x ,int y);
int div(int x ,int y);
int (*p[4])(int x,int y);
pf[0] = add;//可直接用函数名赋值
pf[1] = ⊂//也可以用取地址符&加上函数名
//函数调用
pf[0](a,b);
pf[1](a,b);
6.函数指针数组的用途—转移表
将在同一时刻可能调用相同类型的不同函数的代码简化
#define _CRT_SECURE_NO_WARNINGS
#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;
}
int meau()
{
int input = 0;
printf("1.add 2.sub\n");
printf("3.mul 4.div\n");
printf(" 0.exit \n");
printf("请选择->");
scanf("%d", &input);
return input;
}
int main()
{
int input;
int a = 0;
int b = 0;
int ret = 0;
int(*pf[5])(int x, int y) = { 0,Add, Sub, Mul, Div };
char ch[4] = "+-*/";
do
{
input = meau();
switch (input)
{
case 1:
printf("请输入要参与运算的两个数\n");
scanf("%d%d", &a, &b);
ret = Add(a,b);
printf("%d+%d=%d\n", a, b, ret);
break;
case 2:
printf("请输入要参与运算的两个数\n");
scanf("%d%d", &a, &b);
ret = Sub(a, b);
printf("%d-%d=%d\n", a, b, ret);
break;
case 3:
printf("请输入要参与运算的两个数\n");
scanf("%d%d", &a, &b);
ret = Mul(a, b);
printf("%d*%d=%d\n", a, b, ret);
break;
case 4:
printf("请输入要参与运算的两个数\n");
scanf("%d%d", &a, &b);
ret = Div(a, b);
printf("%d/%d=%d\n", a, b, ret);
break;
default:
printf("输入错误\n");
break;
}
} while (input);
return 0;
}
上面代码可通过转移表转化为下面的代码
#define _CRT_SECURE_NO_WARNINGS
#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;
}
int meau()
{
int input = 0;
printf("1.add 2.sub\n");
printf("3.mul 4.div\n");
printf(" 0.exit \n");
printf("请选择->");
scanf("%d", &input);
return input;
}
int main()
{
int input;
int a = 0;
int b = 0;
int ret = 0;
int(*pf[5])(int x, int y) = { 0,Add, Sub, Mul, Div };//函数指针数组
char ch[4] = "+-*/";
do
{
input = meau();
if ((input >= 1) && (input <= 4))
{
printf("请输入要参与运算的两个数\n");
scanf("%d%d", &a, &b);
ret = pf[input](a, b);//利用函数指针数组调用函数
printf("%d%c%d=%d\n", a,ch[input-1], b, ret);
}
else if (input == 0)
{
printf("exit\n");
return 0;
}
else
{
printf("输入错误\n");
}
} while (input);
return 0;
}
7.指向函数指针数组的指针
这句话看起来很难理解,其实这就是一个指针,只不过它指向的是一个函数指针数组
上面已经定义了一个函数指针数组,再定义一个指针指向这个数组,这个指针即为函数指针数组指针
int (*pf[4])(int x,int y);
int (*(*p)[4])(int x,int y) = &pf;//p即为函数指针数组指针