目录
一、思维导图
1.1 二维数组和指针
1.1.1 二维数组地址
1.2 数组指针
1.3 指针数组
1.4 字符指针数组
1.5 指针函数
1.6 函数指针
1.7 函数指针数组
1.8 多级指针、通用类型指针
二、课堂练习
2.1 二维数组地址
打印值、地址:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
int main(int argc, const char *argv[])
{
int arr[2][3]={11,22,33,44,55,66};
/*
printf("&arr[0][0]=%p\t&arr[0][0]+1=%p\n",&arr[0][0],&arr[0][0]+1);
printf("arr[0]=%p\tarr[0]+1=%p\n",arr[0],arr[0]+1);
printf("&arr[0]=%p\t&arr[0]+1=%p\n",&arr[0],&arr[0]+1);
printf("arr=%p\tarr+1=%p\n",arr,arr+1);
printf("&arr=%p\t&arr+1=%p\n",&arr,&arr+1);
printf("\n");
*/
//int *p=arr; 运行会出现警告,原因:*p是一级指针,arr是二级地址
int (*p)[3]=arr;//p=arr
/*
printf("&p[0][0]=%p\t&p[0][0]+1=%p\n",&p[0][0],&p[0][0]+1);
printf("p[0]=%p\tp[0]+1=%p\n",p[0],p[0]+1);
printf("&p[0]=%p\t&p[0]+1=%p\n",&p[0],&p[0]+1);
printf("p=%p\tp+1=%p\n",p,p+1);
printf("&p=%p\t&p+1=%p\n",&p,&p+1);
*/
for(int i=0;i<2;i++)
{
for(int j=0;j<3;j++)
{
//值
// printf("arr[%d][%d]=%d\t",i,j,arr[i][j]);
// printf("*(*(arr+%d)+%d)=%d\t",i,j,*(*(arr+i)+j));
// printf("*(*(&arr[0]+%d)+%d)=%d\t",i,j,*(*(&arr[0]+i)+j));
// printf("*(arr[%d]+%d)=%d\t",i,j,*(arr[i]+j));
// printf("p[%d][%d]=%d\t",i,j,p[i][j]);
// printf("*(*(p+%d)+%d)=%d\t",i,j,*(*(p+i)+j));
// printf("*(*(&p[0]+%d)+%d)=%d\t",i,j,*(*(&p[0]+i)+j));
// printf("*(p[%d]+%d)=%d\t",i,j,*(p[i]+j));
//地址
// printf("%p\t",&arr[i][j]);
// printf("%p\t",*(arr+i)+j);
// printf("%p\t",*(&arr[0]+i)+j);
// printf("%p\t",arr[i]+j);
// printf("%p\t",&p[i][j]);
// printf("%p\t",*(p+i)+j);
// printf("%p\t",*(&p[0]+i)+j);
// printf("%p\t",p[i]+j);
}
printf("\n");
}
return 0;
}
2.2 计算数组第二大的值
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
int Max_2(int line,int row,int (*p)[row])
{
int max,min,maxi,maxj;
for(int i=0;i<line;i++)
{
for(int j=0;j<row;j++)
{
if(i==0&&j==0)
{
max=*(*(p+i)+j);//给max赋初值
min=*(*(p+i)+j);//给min赋初值
maxi=i;//记录max的行标
maxj=j;//记录max的列标
}
if(max<*(*(p+i)+j))//循环比较
{
max=*(*(p+i)+j);
maxi=i;
maxj=j;
}
if(min>*(*p+i)+j)//把min也求出来,以便底下的max2赋初值
{
min=*(*(p+i)+j);
}
}
}
int max2,max2i,max2j;//定义第二大值,以及其行标列标
max2=min;//max2赋初值
for(int i=0;i<line;i++)
{
for(int j=0;j<row;j++)
{
if(i==maxi&&j==maxj)//当i,j循环到等于最大值的行标列标时,跳过本次循环
{ continue;}
if(max2<*(*(p+i)+j))
{
max2=*(*(p+i)+j);
}
}
}
return max2;//将第二大值返回给主汗珠
}
int main(int argc, const char *argv[])
{
int arr[][3]={9,1,4,99,100};
int line=sizeof(arr)/sizeof(arr[0]);
int row=sizeof(arr[0])/sizeof(arr[0][0]);
int max2=Max_2(line,row,arr);//定义一个值接第二大值
printf("该数组的第二大值为:%d\n",max2);
return 0;
}
2.3 指针数组(定义、输出)
int main(int argc, const char *argv[])
{
//指针数组
int a[3]={1,2,3},b[3]={4,5,6},c[3]={7,8,9};
int *p[3]={a,b,c};
for(int i=0;i<3;i++)
{
for(int j=0;j<3;j++)
{
printf("%d\t",*(*(p+i)+j));
}
printf("\n");
}
return 0;
}
2.4 字符数组指针
int main(int argc, const char *argv[])
{
//字符数组指针
char a[]="ABCD",b[]="1234",c[]="eqwer";
char *p[3]={a,b,c};
*(*p+1)='b';
int len=sizeof(p)/sizeof(p[0]);
for(int i=0;i<len;i++)
{
printf("%s\t",*(p+i));
printf("\n");
}
char *q[]={"ASDF","abcde","12","!@#"};
// *(*q+1)='s';段错误
len=sizeof(q)/sizeof(q[0]);
for(int i=0;i<len;i++)
{
printf("%s\n",*(q+i));
}
return 0;
}
2.5 练习主函数:在终端输入,使用【字符指针数组】
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
int main(int argc, const char *argv[])
{
//argc:命令行输入字符串的个数
//argc:存储命令行输入的每一个字符串
printf("argc=%d\n",argc);
for(int i=0;i<argc;i++)
{
printf("%s\n",*(argv+i));
}
return 0;
}
2.6 多级指针
#include <stdio.h>
int main(int argc, const char *argv[])
{
//多级指针
int a=100;
int *p=&a;
int **q=&p;
int ***m=&q;
printf("p=%ld q=%ld m=%ld\n",sizeof(p),sizeof(q),sizeof(m));
printf("a=%d *p=%d **q=%d ***m=%d\n",a,*p,**q,***m);
printf("&a=%p p=%p **q=%p ***m=%p\n",&a,p,*q,**m);
return 0;
}
2.7 通用类型指针
#include <stdio.h>
int main(int argc, const char *argv[])
{
//通用类型指针
int a=100;
void *p=&a;//void型的指针为通用类型指针
printf("*p=%d\n",*(int *)p);//在输出时需要进行强制转换类型(int *)
return 0;
}
2.8 指针函数
//需求:
/*返回局部变量的地址:段错误
int *fun()
{
int a=100;
int b=1;
int arr[2];//局部变量 调用fun函数arr分配空间,函数调用结束arr空间释放 0x10-0x17
arr[0]=a;
arr[1]=b;
return arr;//0x10
}*/
// 解决方法:
/*
*方法1:
int arr[2];//数组定义为全局变量
int *fun()
{
int a=100;
int b=1;
arr[0]=a;
arr[1]=b;
return arr;//0x10
}*/
/*
* 常使用 方法2:
int *fun(int arr[2])//arr=0x20
{
int a=100;
int b=1;
arr[0]=a;
arr[1]=b;
return arr;//0x20
}*/
方法3:
int *fun()//arr=0x20
{
int a=100;
int b=1;
int *p=(int *)malloc(10);//p指向堆区10个字节的首地址 0x10-0x19
*p=a;
*(p+1)=b;
return p;//0x10
}
int main(int argc, const char *argv[])
{
int arr[2];//0x20
int *p=fun();//0x20
printf("a=%d\n",*p);
printf("a=%d\n",*(p+1));
return 0;
}
2.9 【指针函数】字符串拷贝
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
char *My_strcpy(char *dest,char *src)
{
int i=0;
while(*(src+i)!='\0')
{
*(dest+i)=*(src+i);
i++;
}
*(dest+i)='\0';
return dest;
}
int main(int argc, const char *argv[])
{
//【指针函数】字符串拷贝
char dest[20]="";
char src[10]="";
gets(dest);
gets(src);
printf("拷贝后的结果为:%s\n",My_strcpy(dest,src));
return 0;
}