1.指针是什么?
在计算机科学中,指针(Pointer)是编程语言中的一个对象,利用地址,它的值直接指向(points to)存在电脑存储器中另一个地方的值。由于通过地址能找到所需的变量单元,可以说,地址指向该变量单元。因此,将地址形象化的称为”指针”。意思是通过它能找到以它为地址的内存单元。
#include<stdio.h>
int main()
{
int a=10; //在内存开辟一块空间
int *p=&a; //这里我们对变量a,取出它的地址
//将a的地址存放在p变量中,p就是一个指针变量
*p=20; //通过指针我们可以改变a的值
return 0;
}
2.数组是什么?
所谓数组,是有序的元素序列。 若将有限个类型相同的变量的集合命名,那么这个名称为数组名。组成数组的各个变量称为数组的分量,也称为数组的元素,有时也称为下标变量。用于区分数组的各个元素的数字编号称为下标。数组是在程序设计中,为了处理方便, 把具有相同类型的若干元素按无序的形式组织起来的一种形式。 这些无序排列的同类数据元素的集合称为数组。数组是用于储存多个相同类型数据的集合
数组的两种初始化
char arr[]={'a','b','c','d','e'} //末尾无'\0'
cahr arr[]="abcde" //末尾有‘\0'
3.指针数组和数组指针
**指针数组**:指针数组是数组,是一个存放指针的数组。 |
int *p[10] //p和[10]先结合(组成数组),再和*结合(形成数组指针)
**数组指针**:数组指针是指针,这个指针是指向数组的。 |
int (*p)[10] //由于()的参与*和p先结合,p是一个指针变量,然后指向一个10个整数的数组
//[]优先级高于*
4.函数指针
void test()
{
printf("hello\n")
}
//下面pfun1和pfun2谁能存放test函数的地址?
void (*pfun1)();
void *pfun2();
我们先来分析一下,能够存储地址,这就要求是一个指针,通过上面(数组指针和指针数组)的判断,我们发现*pfun1是指针。指针指向一个无参数的函数,返回类型是void
下面我们再来分析两个有意思的代码
(*(void(*)()0)()
我们从内往外一步一步来分析:
1、(void(*)()0 将0强制转换为数组指针 假设 a=(void(*)()0 2 、 *a 将a解引用 3、整体是个函数 |
void (*signal(int,void(*)(int)))(int);
1、signal是一次函数声明 2、signal函数的参数:第一个是int(整形),第二个是函数指针,该函数指针指向的函数参数为int,返回类型是void |
5、函数指针数组
函数指针数组:数组是存放相同类型数据的存储空间,当我们把函数的地址存到一个数组中,这个数组就叫做函数指针数组。
通过指针数组 :int *arr[10]
得到函数指针数组:int (*arr[10])()
函数指针的用途举例:计算器的实现
#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 ret = 0;
int input = 1;
int(*arr[])(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 = (*arr[input])(x, y);
}
else
printf("操作有误");
printf("ret=%d\n", ret);
}
return 0;
}
结果如下:
6、指向函数指针数组的指针
指针指向一个数组,数组的元素都是函数指针
通过函数指针数组:int (*arr[10])()
得到函数指针数组:int (*(*arr)[10])()
指向函数指针数组的指针的用途举例:回调函数
回调函数:如果你把函数的指针(地址)作为参数传递给另外一个函数,当这个指针被用来条用其他所指向的函数时,我们就说这是回调函数
#include<stdio.h>
int int_cmp(const void* p1, const void* p2)
{
return (*(int*)p1 > *(int*)p2);
}
void _swap(void* p1, void* p2, int size)
{
int i = 0;
for (i = 0; i < size; i++)
{
char tmp = *((char*)p1 + i);
*((char*)p1 + i) = *((char*)p2 + i);
*((char*)p2 + i) = tmp;
}
}
void bubble_sort(void* base, int count, int size, int(*cmp)(void*, void*))
{
int i = 0;
int j = 0;
for (i = 0; i < count - 1;i++)
{
for (j = 0; j < count - 1 - i; j++)
{
if ((cmp((char*)base + j*size, (char*)base + (j+1)*size))>0)
{
_swap((char*)base + j*size, (char*)base + (j + 1)*size, size);
}
}
}
}
int main()
{
int arr[] = { 9,4,5,71,3,5,6,1,0};
int i = 0;
bubble_sort(arr, sizeof(arr) / sizeof(arr[0]), sizeof(int), int_cmp);
for (i = 0;i< sizeof(arr) / sizeof(arr[0]);i++)
{
printf("%d ",arr[i]);
}
printf("\n");
return 0;
}
完