指针的概念:
在c语言中,将地址称为指针。一个变量的地址称为变量指针。一个专门用来存放另一个变量的地址的变量,称为指针变量。
指针的定义:
数据类型 *指针变量名; int *p;
指针的运算符:
&:取地址符,获取一个变量的地址。
*:在定义一个指针变量时,起到标识作用。
注意:无论什么类型地址,都在存储单元的编号,在32bit下都是4个字节。
指针的引用:
指针变量中只能存放地址。
int *p; //定义一个int型指针变量
int a = 1;
p= &a; //int型指针变量p指向int型变量a的地址
指针和变量的关系:
int a=1;
int *p;
p = &a;printf("%d\n",a);
printf("%p\n",&a);
printf("%d\n",*&a);
printf("%p\n",p);
printf("%p\n",*&p);
printf("%d\n",*p);
printf("%p\n",&*p);
什么是字节序:
大端序:将数据的地位字节存放在内存的高位地址,高位字节存放在低位地址。
小端序:将地位放在低地址处,高位放在高地址处。
判断是否为小端序
int main()
{
int a=0x12345678;
int b=0x78563421;
char *p1,*p2;
p1=(char*)&a;
p2=(char*)&b;
printf("%x %x\n",*p1,*p2);
printf("%p %p\n",p1,p2);
p1++;
p2++;
printf("%x %x\n",*p1,*p2);
printf("%p %p",p1,p2);
return 0;
}
指针与数组之间的关系:
将指针变量放在数组中。
int a[10];
int *p;
p=&a[0];
指针数组与数组指针:
指针数组:
概念:本质是数组,数组中的每一个元素是一个指针变量。
定义方法:类型符 *数组名 【元素个数】
int main()
{
int a[5]={1,3,4,6,7};
int *b[5]={NULL};
int i;
for(i=0;i<5;i++)
{
b[i]=&a[i];
printf("%d\n",*b[i]);
printf("%p\n",b[i]);
}
}
数组指针:
定义:本质是一个指针,这个指针指向一个数组的首地址。
定义方法:类型符 (*指针名)【元素个数】
int arr[3][5];
int (*p)[5];
p=arr;
arr+i == &arr[i]
*(arr+i)== *&arr[i]===arr[i]
arr[i]+j==&arr[i][j]
*(arr[i]+j)==*&arr[i][j]==arr[i][j]==*(*arr+i+j)
int main()
{
int arr[3][5]={1,2,3,4,5,6,7,8,9,10,11,12,13,14,15};
int (*parr)[5];
parr = arr; //数组的首地址
int i, j;
for(i=0;i<3;i++)
{
for(j=0;j<5;j++)
{
printf("%d ",parr[i][j]);
printf("%d ",*(parr[i]+j));
printf("%d ",*(*(parr+i)+j));
printf("%p",&parr[i][j]);
printf("%p",parr[i]+j);
printf("%p",(parr+i)+j);
}
printf("\n");
}
printf("%d\n",parr[0][0]+2*5+2);
printf("%p",&parr[0][0]+2*5+2);
}
说明:arr指向了数组中第0行的地址。
指针变量做函数形参:
一维数组:
int print_arr(int *parr ,int l)
{
int i;
for(i=0;i<l;i++)
{
printf("%d ",parr[i]);
}
return 0;
}int scanf_arr(int *parr,int l)
{
int i;
for(i=0;i<l;i++)
{
scanf("%d",parr[i]);
}
return 0;
}int main()
{
int arr[5]={0};
int *parr;
parr = arr;
scanf_arr(parr,5);
print_arr(parr,5);
}
二维数组:
void print_a(int (*parr)[5],int h,int l)
{
int i,j;
for(i=0;i<h;i++)
{
for(j=0;j<l;j++)
{
printf("%d ",parr[i][j]);
}
printf("\n");
}
}
void pingjun(int (*parr)[5], int h,int l)//总和
{
int i,j;
int sum=0;
for(i=0;i<h;i++)
{
for(j=0;j<l;j++)
{
sum=sum+parr[i][j];
}
}
printf("%d\n",sum);
printf("%d\n",sum/15);
}
void hang(int (*parr)[5],int h,int l)//行之和
{
int i,j;
int sum=0;
for(i=0;i<h;i++)
{
for(j=0;j<l;j++)
{
sum=sum+parr[i][j];
}
printf("%d\n",sum);
sum=0;
}
}
void lei(int (*parr)[5],int h,int l)//列之和
{
int i,j;
int sum=0;
for(j=0;j<l;j++)
{
for(i=0;i<h;i++)
{
sum=sum+parr[i][j];
}
printf("%d\n",sum);
sum=0;
}
}
int main()
{
int arr[3][5]={1,2,3,4,5,6,7,8,9,10,11,12,13,14,15};
int (*parr)[5];
parr=arr;
print_a(parr,3,5);
pingjun(parr,3,5);
printf("\n");
hang(parr,3,5);
printf("\n");
lei(parr,3,5);
return 0;
}
指针函数与函数指针:
指针函数:
本质是一个函数,函数的返回值是一个指针。
格式:类型 *函数名(形参)
char s[140]="hello,world";
char *zzz()
{
return s;
}int main()
{
char *p;
p=zzz();
printf("%s",p);
return 0;
}
函数指针:
本质是指针,指向一个函数
格式:返回值类型 (*函数名)(形参)
int max(int a,int b)
{
return a+b;
}
int cheng(int a ,int b)
{
return a*b;
}int main()
{
int a=10;
int b=20;
int (*pmax)(int a,int b);//声明一个函数指针
int (*pcheng)(int a,int b);
pmax=max;
printf("%d",pmax(a,b));
pcheng=cheng;
printf("%d",pcheng(a,b));
return 0;
}