一,指针
1.1指针和一维数组
int *p=NULL;
&arr[0]=arr;
p=arr;
&arr:整个数组的首地址,偏移量为整个数组的大小
值得等价关系: arr[i] <====> *(arr+i)<====> p[i] <====>*(p+i) <====>*p++
地址的等价关系:&arr[i] <====>arr+i<====>&p[i]<=====>p+i
#include <stdio.h>
int main(int argc,const char *argv[])
{
int a[5]={1,2,3,4,5};
int *p=&a+1;//数组的首地址 偏移一个数组
printf("%d %d",*(a+1),*(p-1));//结果:2 5
return 0;
}
补充:
1.2 指针和一维字符数组
char str[]="hello";
printf("%s",str);
1> 指针指向一维字符数组的首地址【可以通过指针修改数组的内容】
char str[]="hello";
char *p =str;//p==str
scanf("%s",str);
scanf("%s",p);
2>指针直接指向字符串的首地址【不可以通过指针修改字符串的内容】
char *p="hello";
*(p+1)=‘k’//错误,字符串常量在.ro段
char str[]="hello";//注意:数组长度在输入时防止越界
char *p=str;//p==str
char *p1="hello";
printf("str=%p,p=%p,p1=%p\n",str,p,p1);//p和str的地址相同(字符串复印件的地址),p1指的是.ro段的地址
1.3 指针和二维数组
int arr[3][4]:
&arr[0][0]:第一行第一列元素的地址
arr[0]:等价于一维数组arr的数组名,偏移的列(一个)
&arr[0]:等价于一维数组数组名去地址,偏移的一整行
&arr:偏移整个二维数组
arr:表示偏移的一整行
int a[2][3]={1,2,3,4,5,6};
//列偏移
printf("&a[0][0]=%p\n&a[0][0]+1=%p\n",&a[0][0],&a[0][0]+1);
printf("a[0]=%p\na[0]+1=%p\n",a[0],a[0]+1);
//行偏移
printf("&a[0]=%p\n&a[0]+1=%p\n",&a[0],&a[0]+1);
printf("a=%p\na+1=%p\n",a,a+1);
//整个数组偏移
printf("&a=%p\n&a+1=%p\n",&a,&a+1);
地址等价:&arr[i][j]====>>*(arr+i)+j====>>arr[i]+j
值的等价:arr[i][j]====>>*(*(arr+i)+j)====>>*(arr[i]+j)
1.3.1 指针和二维数组结合
1.4 数组指针
本质就是一个指针,主要用来指向二维数组的地址,或者做参数
定义格式:数据类型(*指针变量名)[常量表达式] 等价于二维数组数组名arr
数据类型:基本数据类型[int float char..],构造数据类型[结构体],指针类型,void
指针变量名:满足命名规范
( ) [ ]:不可以省略
常量表达式:二维数组的列数
int arr[line][row];
1.用指针数组求最大值和第二大的值
#include <stdio.h>
int main(int argc,const char *argv[])
{
int a[2][3]={11,22,33,44,55,66};
int (*p)[3]=a;//数组指针:指向二维数组地址指针
int i,j,max=**p,sec=**p;
for(i=0;i<2;i++)
{
for(j=0;j<3;j++)
if(*(*(p+i)+j)>max)
{
max=*(*(p+i)+j);
}
}
for(i=0;i<2;i++)
{
for(j=0;j<3;j++)
if(*(*(p+i)+j)>sec&&(*(*(p+i)+j))<max)
{
sec=*(*(p+i)+j);
}
}
printf("max=%d\nsec=%d\n",max,sec);
return 0;
}
1.5指针数组
本质上是一个数组,表示存储多个指针,满足数组的使用方式
定义格式:数据类型 *数组名[常量表达式] 突出是一个指针数组 [ ]>*
常量表达式:表示指针的个数
int a,b,c,d,e;
int *p=&a;int *p1=&b;int *p2=&c;...
指针数组存放变量地址
int *q[5]={&a,&b,&c,&d,&e};
指针数组存放数组地址
int *s[3]={str1, str2 ,str3};
int str1[] ,str2[] ,str3[];
指针数组表示字符串常量
char *str[3]={"hello","sdja","sdas"};
for(int i=0;i<3;i++)
printf("%s\n",str[i]);
1.6 多级指针
定义格式:数据类型 **指针变量名
注意:*的个数不限
1.7 void和指针
定义格式:void * 指针变量名
通用类型指针,它可以指向任何一种类型的地址,可以指向任何一种空间
在使用时,必须要进行强制转换
#include <stdio.h>
int main(int argc,const char *argv[])
{
int a=11;
float b=1.1;
char c='a';
void *p=&a;
printf("%d\n",*(int *)p);
p=&b;
printf("%f\n",*(float *)p);
p=&c;
printf("%c\n",*(char *)p);
return 0;
}
1.8 const和指针
1>const 修饰的变量不可以改变值
2>const 修饰的全局变量在.ro段
3>const修饰的局部变量在栈区
4>const和指针
const int *p:*在const右边,const修饰的是值,值不能变,地址可以改变
int const *p:*在const右边,const修饰的是值,值不能变,地址可以改变
int * const p:*在const左边,const修饰的是地址,值能变,地址不可以改变
const int *const p:const修饰的是值和地址,值不能变,地址也不可以改变
argc:命令行输入参数的个数
argv:指针数组,接受命令行输入的字符串
作业:
练习1:使用指针实现两个字符串的比较
#include <stdio.h>
int main(int argc,const char *argv[])
{
char arr[]="Jrc";
char brr[]="JrcLAICAILAI";
char *p=arr;
char *p1=brr;
int ret;
while(arr)
{
if(*p==*p1)
{
p++;
p1++;
}else
{
break;
}
}
ret=*p-*p1;
printf("%d\n",ret);
return 0;
}
2.使用指针实现字符串连接
#include <stdio.h>
#include <string.h>
int main(int argc,const char *argv[])
{
char arr[100]="Jrc";
char brr[]=" handsome";
char *p=arr;char *p1=brr;
int len=strlen(arr);
p=p+len;
while(*p1)
{
*p=*p1;
p++;
p1++;
}
*p='\0';
p=arr;
printf("%s",p);
return 0;
}
3.使用指针实现转置
#include <stdio.h>
#include <string.h>
int main(int argc,const char *argv[])
{
char str[]="shuaige JRC";
char *head=str;
char *tail=str;
char temp;
while(*tail)
tail++;
tail--;
while(tail>head)
{
temp=*tail;
*tail=*head;
*head=temp;
head++;
tail--;
}
printf("%s\n",str);
return 0;
}
4.实现杨辉三角:
#include <stdio.h>
int main(int argc,const char *argv[])
{
int a[10][10],i,j;
int (*p)[10]=a;
for(i=0;i<10;i++)
{
for(j=0;j<10;j++)
if(j==0||i==j)
{
*(*(p+i)+j)=1;
}else
{
*(*(p+i)+j)=0;
}
}
for(i=1;i<10;i++)
{
for(j=1;j<i;j++)
*(*(p+i)+j)=*(*(p+i-1)+j)+*(*(p+i-1)+j-1);
}
for(i=0;i<10;i++)
{
for(j=0;j<=i;j++)
printf("%d\t",*(*(p+i)+j));
putchar('\n');
}
return 0;
}
5.通过数组指针实现二维数组转置
#include <stdio.h>
int main(int argc,const char *argv[])
{
int arr[2][3]={1,2,3,4,5,6};
int brr[3][2];
int (*p)[3]=arr;
int (*p1)[2]=brr;
int i,j;
for(i=0;i<2;i++)
{
for(j=0;j<3;j++)
*(*(p1+j)+i)=*(*(p+i)+j);
}
for(i=0;i<3;i++)
{
for(j=0;j<2;j++)
printf("%d\t",*(*(p1+i)+j));
putchar('\n');
}
return 0;
}