1、指针数组
(1)指针数组:可以说成是“指针的数组”,它是一个数组, 用指针来修饰这个,意思是说这个数组的所有元素都是指针类型,在32位的系统中,指针占4个字节;
(2)指针数组的定义
int *arr1[10];//一个存放整形指针的数组
char *arr2[4];
char **arr3[5];
2、数组指针
(1)数组指针:可以说成是”数组的指针“,首先它是一个指针, 用数组修饰它, 意思是说这个指针存放着一个数组的地址,也就是说这个指针指向一个数组
2、数组指针的定义
int (*p) arr[10];
//解释:p 先和 * 结合, 说明p是一个指针变量, 然后p指向的是一个长度为十的一个整形数组;
//注意:[]的优先级要高于 * , 所以要加()来保证p先和*结合;
(3)、数组指针的使用
首先看如下代码:
#include <stdio.h>
#include <stdlib.h>
int main ()
{
int arr[10] = {0};
//arr; ------>表示数组首元素地址
//&arr; ------->表示数组地址
printf ("arr : %p\n", arr);
printf ("&arr : %p\n", &arr);
printf ("arr+1 : %p\n", arr+1);
printf ("&arr+1: %p\n", &arr+1);
system ("pause");
return 0;
}
运行结果:
从运行结果可以看出,虽然数组首元素的地址和数组的地址值是完全相同的, 但是他们的意义却完全不同。
那么数组的地址有事如何来存储的呢???下面这段代p1和p2哪一个更合适呢???
int arr[10] = {0};
int *p1 = &arr;
int (*p2)[10] = &arr;
通过分析:p2是比较合适的, p2是数组指针, 所以存放数组的地址是合适的。
那我们要给一个二维数组传参,又该怎么传呢???
#include <stdio.h>
#include <stdlib.h>
void print1 (int arr[3][5])
{
printf ("hehe\n");
}
void print2 (int arr[][5])
{
printf ("hehe\n");
}
void print3 (int **arr)
{
printf ("hehe\n");
}
void print4 (int (*arr)[5])
{
printf ("hehe\n");
}
int main ()
{
int arr[3][5] = {0};
print1(arr);
print2(arr);
print3(arr);//“函数”:“int **”与“int [3][5]”的间接级别不同
print4(arr);
system ("pause");
return 0;
}
通过测试,print1和、print2(自己给自己传参当然可以)和 print4(print4是一个数组指针也可以)都可以给二维数组传参;
3、函数指针
先看一段代码:
#include <stdio.h>
#include <stdlib.h>
void test()
{
printf ("hehe\n");
}
int main ()
{
printf ("%p\n", test);
printf ("%p\n", &test);
system ("pause");
return 0;
}
运行结果:
输出的这两个地址,是test函数的地址
那如果我们想把这个地址保存起来,该怎么保存呢???
看下面这段代码:
void test()
{
printf ("haha\n");
}
下面定义两个变量,看看哪一个有能力存放test函数的地址:
void (*pfun1)();
void *pfun2 ();
首先,要存放地址,那么那个变量必须是一个指针;
通过分析:pfun1可以存放。 pfun1先和*结合,说明pfun1是一个指针,指向的是一个函数, 并且指向的这个函数没有参数, 返回类型是void。
分析到这里,就可以看一下函数指针的定义了:
(1)函数指针:可以说它是“函数的指针”,首先它是一个指针,用函数来修饰它,意思是说它是一个指向函数的指针;
(2)函数指针的定义
void test()
{
printf ("hehe\n");
}
//下面定义一个变量来存放test函数的地址
void (*pfun1) ();
//pfun1先和*结合, 说明pfun1是一个指针, 指向的是一个函数, 指向的函数无参数, 返回值类型为void;
4、函数指针数组
函数指针数组:数组是一个存放相同类型数据的存储空间,前面我们又学习了指针数组
int *arr[10];//数组中每个元素都是 int *
那要把函数的地址存到数组中,这个数组就叫做函数指针数组,那么函数指针数组又该如何定义呢???
int (*parr[10])();
parr先和[]结合,说明parr是一个数组;
数组的内容就是int (*)()类型的函数指针;
通过函数指针数组,可以实现一个简单的计算器
代码如下:
#include <stdio.h>
#include <stdlib.h>
void menu()
{
printf ("*********************************************\n");
printf ("************ 计算器 ************\n");
printf ("************ 1(+) 2(-) ************\n");
printf ("************ 3(*) 4(\\) ************\n");//此处两个\\才能打印一个
printf ("************ 0(exit) ************\n");
printf ("*********************************************\n");
}
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 input = 1;//作为循环条件,也表示加减乘除
int a = 0, b = 0;//两个操作数
int ret = 0;//计算结果
int (*arr[5]) (int a, int b) = {0, Add, Sub, Mul, Div};//函数指针数组
do
{
menu ();
printf ("请选择你要进行的操作:\n");
scanf ("%d", &input);
if(input>0 && input<5)
{
printf ("请输入两个操作数:\n");
scanf ("%d%d", &a, &b);
ret = (*arr[input]) (a, b);
printf ("ret = %d\n", ret);
}
else if(input == 0)
{
printf ("exit\n");
}
else
{
printf ("输入有误!!\n");
}
}while(input);
system ("pause");
return 0;
}
5、指向函数指针数组的指针
(1)指向函数指针数组的指针:顾名思义,是一个指针, 它指向的内容是一个存放函数指针的数组 ;
(2)关于函数指针, 函数指针数组, 指向函数指针数组的指针的定义:
void test(const char* str)
{
printf ("%s", str);
}
int main ()
{
void (*pfun)(const char*) = test;//函数指针pfun
void (*pfunArr[5]) (const char* str);//函数指针的数组
pfunArr[0] = test;
void (*(*pPfunArr)[5]) (const char* str);//指向函数指针数组的指针
}
最后,新手操作,如果有写的不对的地方希望大家可以指出来。。。