2023.08.20
字符指针
使用字符指针变量指向一个字符串常量,通过字符指针变量引用字符串常量。
int main()
{
char string[] = "I love China!";//定义一个字符数组
char* ch = &string;
int sz = sizeof(string) / sizeof(string[0]);
int i = 0;
for (i = 0; i < sz; i++)
{
printf("%c", *(string + i));
}
return 0;
}
注意:字符指针变量只能指向一个字符类型数据,而不是指向多个字符类型数据,更不是把整个字符串都赋给 *string,而是把首个字符的地址赋给字符指针变量。
数组指针
顾名思义,数组指针就是指针变量,是存放数组的地址的指针,指向的变量为数组。
指针的命名格式为: 类型名 * 指针变量名
数组指针当然也按照这个格式: 类型名 (*指针变量名)[常量表达式]
例如:int (*p) [10] p先和*结合,说明p是一个指针变量,然后指着的是一个数组大小为10的整型数组。([ ]的优先级是要高于*的,加上( )才能保证p先和*结合成指针变量p)
数组指针变量的初始化
数组首元素的地址:数组名 或 &数组名[0]
数组的地址:&数组名
则数组指针变量初始化: int (*p) [10]=&arr
二维数组的地址
int arr[3][5]={{1,2,3,4,5},{2,3,4,5,6},{3,4,5,6,7}};
arr 是二维数组数组名,代表二维数组首元素的地址,这里的首元素不是一个整型元素,而是由五个整型元素组成的一维数组,所以arr 代表的是首行(即a[0])的起始地址(同理,arr[1]代表的是第二行的起始地址)。
arr[0],arr[1],arr[2] 是一维数组名,代表一维数组中首元素的地址,即第0列元素的地址(即为&a[0][0])。
函数指针
在调用函数时,会从它的起始地址开始执行这段函数代码。函数名代表函数的起始地址,函数名就是函数的指针。
可以定义一个指向函数的指针变量,用来存放某一函数的起始地址,这个指针变量成为函数指针变量,可以指向该函数。
定义:类型名 (*指针变量名)(函数参数列表)
例如:int (*p) (int ,int ) 定义一个指针变量,指向类型为整型(函数返回值的类型),有两个整型参数的函数。
函数指针的初始化:
① int (*p) (int ,int ) = &max; //取函数max的地址赋给指针变量
② int (*p) (int ,int ) = max; //函数名就是函数的地址,直接赋给指针变量也可以
*p 两边的括号必须加上,如果不加上则为int * p (int ,int ) = max; 即定义一个函数p,函数的返回值为指向整型变量的指针。
int Max(int x, int y)
{
int z = 0;
if (x > y) z = x;
else z = y;
return z;
}
int main()
{
int a, b, c;
int(*p)(int x, int y)=Max;//定义函数指针并初始化
//p=Max 为将函数入口地址赋给p
//p=Max(a,b) 为将函数返回值赋给p
printf("Please enter a and b:");
scanf("%d %d", &a, &b);
c = (*p)(a, b);//等价于c=Max(a,b)
printf("max is %d", c);
return 0;
}
另外,对于指向函数的指针变量,进行加减运算时无意义的,p++,p--等都不能实现。运用函数指针可以先后指向不同的函数(必须是指针在定义时指定好的类型),先后调用不同的函数。
编写一个简单的四则运算法则计算器,用户输入两数,得到结果。
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 calculate(int (*p)(int,int))//形参定义一个函数指针,接收函数名(地址)
{
int a, b;
int res = 0;
printf("Please enter a and b:");
scanf("%d %d", &a, &b);
res = (*p)(a, b);//使用函数指针,调用对应的函数
printf("The result is %d\n", res);
}
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 choice = 0;
menu();
do
{
printf("Please enter your choice:");
scanf("%d", &choice);
switch(choice)
{
case 1:calculate(Add); break;
case 2:calculate(Sub); break;
case 3:calculate(Mul); break;
case 4:calculate(Div); break;
case 0:printf("Ok,exit it right now.\n"); break;
default:printf("Your choice is wrong!\n");
}
} while (choice);
return 0;
}
使用函数指针,具有现实价值,制作一个菜单,根据输入的数字不同,调用的函数也不同(使用if语句实现),实现不同的功能(调用函数的不同),就不用在下次调用的时候修改调用函数,使得程序变得更加的简洁。
有两个整数a和b,输入1,2或者3。输入1程序求大数,输入2程序求小数,输入3程序执行求和。
void Max(int x, int y)
{
int z = 0;
if (x > y) z = x;
else z = y;
printf("Max=%d", z);
}
void Min(int x, int y)
{
int z = 0;
if (x > y) z = y;
else z = x;
printf("Min=%d", z);
}
void Add(int x, int y)
{
printf("Add=%d", x + y);
}
int calculate(int(*p)(int, int),int x,int y)
{
int temp = (*p)(x, y);
return temp;
}
int main()
{
int input=0;
int a = 2;
int b = 7;
printf("输入操作:");
scanf("%d", &input);
switch (input)
{
case 1:calculate(Max,a,b); break;
case 2:calculate(Min,a,b); break;
case 3:calculate(Add,a,b); break;
default:printf("选择错误。");
}
return 0;
}
由调用calculate函数将所需函数地址,a,b两数作为实参传递,在calculate函数中再次调用函数时,将形参a,b又作为实参传递给执行的函数。