一、Xmind整理:
二、课上练习:
练习1:二维数组和指针(打印地址和值)
int main(int argc, const char *argv[])
{
int arr[2][3]={11,22,33,44,55,66};
//int *p=arr; 原因:arr是二级地址,p是一级指针,不等价
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);
}
//arr: 第一行的行地址
//2行3列
//arr+1 第二行行地址
//
//*(arr+1) 地二行第一列的列地址
//*(arr+1)+2 第二行地三列的列地址
//*( *(arr+1)+2 ) 2行3列的元素
//i+1行i+1列的元素: *(*(arr+i)+j)
//&arr[0][0]===arr[0]
//&arr[0]====arr
for(int i=0;i<2;i++)
{
for(int j=0;j<3;j++)
{
// printf("%d\t",arr[i][j]);
// printf("%d\t",*(*(arr+i)+j));//*(arr+i)-->arr[i]
// printf("%d\t",*(*(&arr[0]+i)+j));
// printf("%d\t",*(arr[i]+j));
// printf("%d\t",p[i][j]);
// printf("%d\t",*(*(p+i)+j));//*(arr+i)-->arr[i]
// printf("%d\t",*(*(&p[0]+i)+j));
// printf("%d\t",*(p[i]+j));
}
printf("\n");
}
//值:arr[i][j]-->*(*(arr+i)+j)-->*(*(&arr[0]+i)+j)-->*(arr[i]+j)
//:p[i][j]-->*(*(p+i)+j)-->*(*(&p[0]+i)+j)-->*(p[i]+j)
for(int i=0;i<2;i++)
{
for(int j=0;j<3;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");
}
//地址:&arr[i][j]-->*(arr+i)+j-->*(&arr[0]+i)+j-->arr[i]+j
//:&p[i][j]-->*(p+i)+j-->*(&p[0]+i)+j-->p[i]+j
return 0;
}
练习2:自定义函数,计算二维数组的和,要求使用数组指针做参数
int Sum(int line,int row,int (*p)[row])
{
int sum=0;
for(int i=0;i<2;i++)
{
for(int j=0;j<3;j++)
{
//sum+=p[i][j];
sum+=*(*(p+i)+j);
}
}
return sum;
}
int main(int argc, const char *argv[])
{
int arr[][3]={11,33,5,6,7};
int line=sizeof(arr)/sizeof(arr[0]);
int row=sizeof(arr[0])/sizeof(arr[0][0]);
int s=Sum(line,row,arr);
printf("s=%d\n",s);
return 0;
}
练习3: 自定义函数,计算第二大值并返回,要求使用数组指针做参数
思路:计算最大值以及最大值下表 计算第二大值,如果下表等于第一大值行列下表, 则跳过, 否则进行计算第二大值
#include
#include
#include
int Second_Max(int line,int row,int(*p)[row])
{
int maxi,maxj,second;
for(int i=0;i
练习4: 自定义函数,实现杨辉三角,要求使用数组指针做参数
void YangHui(int (*p)[6],int line)
{
int i,j;
for(i=0;i
练习5:指针数组
int main(int argc, const char *argv[])
{
/*
int a=1,b=2,c=3,d=4;
int *p1=&a,*p2=&b,*p3=&c,*p4=&d;
int *p[4]={&a,&b,&c,&d};
//p[0]=&a
//p[1]=&b
printf("a=%p b=%p c=%p d=%p\n",&a,&b,&c,&d);
for(int i=0;i<4;i++)
{
printf("%d\t",*p[i]);
}
printf("%ld\n",sizeof(p));*/
int a[3]={1,2,3},b[]={4,5,6},c[]={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;
}
练习6:字符指针数组存储多个字符数组的地址
char str1[]="ASDF",str2[]="abcde",str3[]="12",str4[]="!@#";
char *p[]={str1,str2,str3,str4};
//
printf("%s\t",str1);
*(*p+1)='s';//可以发生更改
int len=sizeof(p)/sizeof(p[0]);
for(int i=0;i
练习7:字符指针数组存储多个字符串常量的地址
char *q[]={"ASDF","abcde","12","!@#"};
// *(*q+1)='s';段错误
len=sizeof(q)/sizeof(q[0]);
for(int i=0;i
练习8: 在终端输入,使用字符指针数组
int main(int argc, const char *argv[])
{
//argc: 命令行输入字符串的个数
//argv: 存储命令行输入的每一个字符串
printf("argc=%d\n",argc);
for(int i=0;i
练习9:指针函数
需求:
/*返回局部变量的地址:段错误
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;
}
练习10:字符串拷贝,返回拷贝后的地址
char *strcpy(char *dest, char *src)
{
int i;
for(i=0;*(src+i)!='\0';i++)
{
*(dest+i)=*(src+i);
}
*(dest+i)='\0';
return dest;
}
练习11: 函数指针
#include
#include
void Sum()
{
int a=100,b=10;
printf("a+b=%d\n",a+b);
}
int main(int argc, const char *argv[])
{
Sum();//0x10 直接使用函数的地址调用函数
(*Sum)(); //通过地址存储的值进行调用函数
(*******Sum)();
printf("SUm=%p\n",Sum);
// printf("sizeof(SUm)=%ld\n",sizeof(Sum));
printf("*Sum=%p\n",*Sum);
printf("**Sum=%p\n",**Sum);
printf("*****Sum=%p\n",*****Sum);
void (*p)()=Sum;//p=Sum
p();//通过函数指针调用函数
(*p)();//通过函数指针指向地址对应的值调用函数
return 0;
}
练习12:函数指针数组
#include
#include
#include
int add(int a,int b)//100 10
{
return a+b;
}
int sub(int a,int b)
{
return a-b;
}
int mul(int a,int b)
{
return a*b;
}
int divs(int a,int b)
{
return a/b;
}
int main(int argc, const char *argv[])
{
int a=100,b=10;
//需要使用4个函数指针
int (*p1)(int,int)=add;
int (*p2)(int,int)=sub;
int (*p3)(int,int)=mul;
int (*p4)(int,int)=divs;
//定义一个
double a;
int *p=&a;
int (*p[4])(int,int)={add,sub,mul,divs};
for(int i=0;i<4;i++)
{
int s=(*(p+i))(a,b);
printf("s=%d\n",s);
}
return 0;
}
练习13 :多级指针
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;
}
练习14:通用类型指针
int a=100;
void *p=&a;
printf("*p=%d\n",*(int *)p);
int arr[3]
memset(arr,0,sizeof(arr));