指针是什么?
通过地址我们可以找到所需要的变量单元
指针变量是用来存放地址的变量int a =10;int *p = &a;
类型为int *,在32位机器上是4个字节,在64位机器上是8个字节
printf("%d",sizeof(char *));
printf("%d",sizeof(short *));
printf("%d",sizeof(int *));
printf("%d",sizeof(double *));//输出都为4
int a=0x11223344;
int* pa=&a;
char* pc=&a;
printf("%p",pa);
printf("%p",pc);
//结果都是一样的
所以基类型的区别在哪?
int* pa=&a;
*pa=0;//更改了四个字节的内存值,*p能访问4个字节
char* pa=&a;
*pa=0;//只改变了一个字节的内存值,*p能访问1个字节
--所以指针应该选择合适的类型去引用
指针类型决定了指针的步长(字节)
int main ()
{
int a = 0x11223344;
int* pa=&a;
char* pc=&a;
printf("%p",pa);//
printf("%p",pa+1);//向后偏移了4个字节
printf("%p",pc);
printf("%p",pc+1);//向后偏移了1个字节
}
野指针
指针指向的位置是不可知的
int *p;//未指向明确的地址
*p = 20//未指向初始化后的地址,将20随机地址储存
指针越界访问也会导致野指针
指针指向的空间被释放
检查指针的有效性
if(pa!=NULL)
{
}
指针的运算
int main()
{
int arr[10] = {1,2,3,4,5,6,7,8,9,10};
int i = 0;
int sz = sizeof(arr)/sizeof(arr[0]);
int* p = arr;
for(i=0; i<sz;i++)
{
printf("%d",*p);
p=p+1;//p++同
}
return 0;
}
指针求字符串长度
int my_strlen(char* str)
{
char* start =arr;
char* end=arr;
while(*end !='\0')
{
end++;
}
return end-start;
}
int main ()
{
char arr[]="bit";
int len = my_strlen(arr);
printf("%d",len);
return 0;
}
二级指针
int main()
{
int a =10;
int* pa=&a;
int** ppa =&pa;//ppa就是二级指针
}
指针数组==数组,存放指针的数组
数组指针==指针
int a=10;
int b=20;
int c=30;
int* arr[3]={&a,&b,&c};
int i=0;
for(i=0;i<3,i++)
{
printf("%d",*(arr[i]));
}
字符指针
char ch = 'w';
char* p = &ch;
char* p2="abcdef";//字符的值不可更改
数组指针--实际上是一个指针
int *p = NULL;//整型指针,指向整型的指针,可以存放整型的地址
int *pc=NULL//pc是字符指针,指向字符的指针,可以存放字符的地址
int arr[10]={1,2,3,4,5,6,7,8,9,10}
int(*p)[10]=&arr
指向数组指针的指针
char * arr[5];
char*(*pa)[5]=&arr;
用于二维数组
void print1(int arr[3][5],int x,int y)
{
int i=0;
int j=0;
for(i=0;i<x;i++)
{ for(j=0;j<y;j++)
{
printf("%d",arr[i][j]);
}
printf("\n");
}
}
void print2(int(*p)[5],int x,int y)
{
int i=0;
int j=0;
for(i=0;i<x;i++)
{ for(j=0;j<y;j++)
{
printf("%d",*(*(p+i)+j));//p+i是找到这一行的地址,*解引用是真的找到了这一行的值,然后+j是找到第几列的地址,最后*解引用是找到了i行j列的值。
}
printf("\n");
}
}
int main()
{
int arr[3][5]={{1,2,3,4,5},{2,3,4,5,6},{3,4,5,6,7}};
print1(arr,3,5);//arr为首元素地址
print2(arr,3,5);
return 0;
}
这里二维数组arr为首元素地址,指的是第一行的地址(想象为一维数组 )
四个printf结果一致
数组参数,指针参数
一维数组传参
二维数组传参
二级指针传参--传一级指针的地址或二级指针
函数指针
是指向函数的指针
int Add(int x,int y)
{
int z = 0;
z= x+y;
return z;
}
int main()
{
int a = 10;
int b = 20;
printf("%d\n",Add(a,b));
return 0;
}
函数指针的数组
int(*arr[4])(int ,int)={Add,Sub,Mul,Div}
用途:转移表
char* my_strcpy(char* dest,const char* src);
//写一个函数指针pf,能够指向my_strcpy
char* (*pf)(char*,const char*);
//写一个函数指针数组pfarr,能够存放4个my_strcpy函数指针的数组
char*(*pfarr[4])(char*,const cahr*);
写一个计算器
void menu()
{
printf("*************************\n");
printf("***1.add 2.sub****\n");
printf("***3.mul 4.div****\n");
printf("***5.xor 0.exit***\n");
printf("*************************\n");
}
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 Xor(int x,int y)
{
return x^y;
}
int main()
{
int input = 0;
int x=0;
int y=0;
int(*pfArr[6])(int,int)={0, Add,sub,Mul,Div,Xor};
//pfArr是一个数组指针,指针指向的数组有4个元素,
//指向的数组的每个元素的类型是一个函数指针int(*)(int,int)
do
{
menu();
printf("请选择:>");
scanf("%d",&input);
if(input>=1&&input<=5)
{
printf("请输入两个操作数:>");
scanf("%d%d",&x,&y);
int ret=pfArr[input](x,y);
printf("%d\n",ret);
}
else if(input==0)
{
printf("退出\n");
}
else
{
printf("选择错误\n");
}
}while(input);
}
qsort库函数---可以排任意类型的数据
(快速排序)void qsort(void *base,//排序对象
size_t num,//元素个数
size_t width,//每个元素的字节大小
int(*cmp)(const void *e1,const void *e1));//是函数指针,两个参数 //是待比较的两个元素的地址
void* 类型的指针不能进行解引用操作,也不能进行++ --操作
#include <stdlib.h>
#include <stdio.h>
int cmp_int(const void* e1,const void* e2)
{
return *(int*)e1-*(int*)e2;//比较两个整型值,返回1,0,-1
}
int main()
{
int arr[10]={9,8,7,6,5,4,3,2,1,0};
int sz=sizeof(arr)/sizeof(arr[0]);
qsort(arr,sz,sizeof(arr[0]),cmp_int);
int i;
for(i=0;i<sz;i++)
{
printf("%d ",arr[i]);
}
return 0;
}
冒泡排序
#include <stdio.h>
bubble_sort(int arr[],int sz)
{
int i,j;
for(i=0;i<sz-1;i++)
{
for(j=0;j<sz-1-i;j++)
{
if(arr[j]>arr[j+1])
{
int tmp=arr[j];
arr[j]=arr[j+1];
arr[j+1]=tmp;
}
}
}
}
int main()
{
int arr[10]={9,8,7,6,5,4,3,2,1,0};
int sz=sizeof(arr)/sizeof(arr[0]);
bubble_sort(arr,sz);
int i;
for(i=0;i<sz;i++)
{
printf("%d ",arr[i]);
}
return 0;
}
如何给结构体数组排序?
void Swap(char* buf1,char* buf2,int width)
{
int i=0;
for(i=0;i<width;i++)
{
char tmp=*buf1;
*buf1=*buf2;
*buf2=tmp;
buf1++;
buf2++;
}
}
//未来实现这个函数的人,不知道函数类型,所以用void*
void bubble_sort(void*base,int sz,int width,int (*cmp(void* e1,void* e2)))
{
int i =0;
for(i=0;i<sz-1;i++)
{
int j=0;
for(j=0;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);
}
}
}
}