主要内容为:
- 字符指针
- 数组指针
- 指针数组
- 函数指针
- 指针函数
- 复杂指针
- 函数指针数组
- 回调函数
1.字符指针(char*)
一般使用方法为:
char ch = 'w';
char *pc = &ch;
printf("%c", *pc);
结果为‘w’
另一种使用方式为:
char *pstr = "hello world";
printf("%s\n", *pstr);
结果为hello world,但是并不是把字符串放进了字符指针中,而是把字符串首元素的地址放在了字符指针中。
char str1[] = "hello world";
char str2[] = "hello world";
char *str3 = "hello world";
char *str4 = "hello world";
if (str1 == str2)
printf("str1 and str2 are same!\n");
else
printf("str1 and str2 are not same!\n");
if (str3 == str4)
printf("str3 and str4 are same!\n");
else
printf("str3 and str4 are not same!\n");
结果为str1 and str2 are not same!,str3 and str4 are same!,因为str3和str4指向同一个常量字符串,c会把常量字符串存储到单独的一个内存环境,当几个指针指向同一个字符串时,它们实际指向同一块内存。
2.数组指针
即为指向数组的指针,实际上是指针,例如 int (*p2)[10]为数组指针,因为[]的优先级高于 *,因此带上括号,表示p先与 * 结合,说明p是一个指针变量,指向一个大小为10个整形的数组。
3.指针数组
即为元素为指针的数组,实际上为数组,例如 int *p2[10]为指针数组。
4.函数指针
即为指向函数的指针,实际上为指针,例如 int (*pfun)(int,int),表示指向有两个整形参数的函数的指针
5.指针函数
即为函数的类型为指针,实际上是函数,例如 int *pfun(int,int).
6.几个复杂指针解读
- int (*func)(int *,int( * )(int *));
解读:func是一个指向函数的指针,函数的返回值为int,函数有两个参数,一个参数为整形指针,另一个参数为指向函数的指针,这个指针指向的函数的参数为整形指针。 - int(* func[5])(int *);
解读:func为具有5个元素的数组,元素为函数类型的指针,函数参数为整形指针,返回值为int。 - int(* (* func)[5])(int *);
解读:func为指针,指向一个数组,数组元素为指向函数的指针,函数的参数为int *,返回值为int。 - int(* (* func)(int *))[5]
解读:func为函数指针,函数的参数为int *,返回值为指向数组的指针,数组的元素为5个整形元素。 - int*(* func(int *))[5]
解读:func是函数,函数的参数为整形指针,返回值为指向数组的指针,数组的元素为5个整形指针。 - (* (void( * )())0)()
解读:是一个函数指针,函数没有参数,返回类型为空,0表示强行转换为函数,是一个地址,放一个函数,最外层的 * 表示解引用。 - void (* signal(int,void( * )(int)))(int)
解读:signal为函数,函数有两个参数,一个参数为int,另一个参数为函数指针,函数的返回类型为函数指针,函数的第二个参数是函数指针,函数参数为int,返回类型为void。
7.函数指针数组
用途:转移表,模拟一个计算器
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 = 1;
int ret = 0;
int(*p[5])(int x, int y) = { 0, Add, Sub, Mul, Div };//转移表
while (input)
{
printf("************************\n");
printf("**1.Add 2.Sub **\n");
printf("**3.Mul 4.Div **\n");
printf("************************\n");
printf("请选择:>");
scanf("%d", &input);
if ((input <= 4 && input >= 1))
{
printf("请输入操作数:>");
scanf("%d %d", &x, &y);
ret = (*p[input])(x, y);
}
else
printf("输入有误!\n");
printf("ret=%d\n", ret);
}
system("pause");
return 0;
}
8.回调函数
1.演示qsort的使用,实现整形数组元素的排序
int int_cmp(const void* p1, const void* p2)
{
return (*(int*)p1 - *(int*)p2);//比较两个整形指针元素
}
int main()
{
int arr[] = { 1, 3, 4, 6, 2, 7, 9, 0 };
int i = 0;
qsort(arr, sizeof(arr) / sizeof(arr[0]), sizeof(int), int_cmp);//实现排序
for (; i < sizeof(arr) / sizeof(arr[0]); i++)
{
printf("%d ", arr[i]);
}
printf("\n");
return 0;
}
其中,qsort的参数为要排序的空间的起始地址,元素个数,元素大小,比较函数,此程序实现数组元素从小到大排列。
2.使用结构体,通过结构体成员排序
//实现一个比较函数
void qsort(void *base, size_t num, size_t width,
int (*cmp)(const void *e1, const void *e2));//函数指针
struct S
{
char name[20];
int age;
};
int cmp_S_by_name(const void *e1, const void *e2)//按照名字排序
{
return strcmp(((struct S*)e1)->name,((struct S*)e2)->name);
}
int cmp_S_by_age(const void *e1, const void * e2)
{
return (((struct S*)e1)->age - ((struct S*)e2)->age);
}
void test1()
{
int i = 0;
struct S arr[3] = { { "x", 20 }, { "l", 10 }, { "w", 30 } };
qsort(arr, 3, sizeof(struct S), cmp_S_by_name);
for (; i < 3; i++)
{
printf("%s ", arr[i].name);
}
printf("\n");
}
void test2()
{
int i = 0;
struct S arr[3] = { { "x", 20 }, { "a", 10 }, { "w", 30 } };
qsort(arr, 3, sizeof(struct S), cmp_S_by_age);
for (; i < 3; i++)
{
printf("%d ", arr[i].age);
}
printf("\n");
}
int main()
{
test1();
test2();
return 0;
}
此程序实现一个结构体,通过回调函数分别按照名字和年龄排序。
3.通过回调函数实现冒泡排序
void swap(char *buf1, char *buf2, size_t width)
{
size_t i = 0;
for (; i < width; i++)
{
char tmp = *buf1;
*buf1 = *buf2;
*buf2 = tmp;
buf1++;
buf2++;
}
}
int cmp_int(const void *e1, const void *e2)//e1,e2要比较的两个元素
{
return *(int*)e1 - *(int*)e2;
}
void bubble_sort(void *base, size_t sz, size_t width,
int(*cmp)(const void *e1, const void *e2))//函数指针
{
size_t i = 0;
for (; i < sz - 1; i++)
{
size_t j = 0;
for (; j < sz - 1 - i; j++)
{
if (cmp((char*)base + j*width, (char*)base + (j + 1)*width)>0)
{
swap((char*)base + j*width, (char*)base + (j + 1)*width, width);
}
}
}
}
int main()
{
int arr[]={1,3,2,4,15,6,7,10,8};
bubble_sort(arr,sizeof(arr)/sizeof(arr[0]),sizeof(int),cmp_int);
size_t i=0;
for(;i<sizeof(arr)/sizeof(arr[0]);++i)
{
printf("%d ",arr[i]);
}
printf("\n");
return 0;
}
在比较时,应该将其转换为字符类型指针类型。