指向二维数组的指针学习笔记

二维数组与一维数组的关系
二维数组的指针指向一维数组的指针
一维数组的情况下:数组名代表数组首地址*(a+i)=a[i]
二维数组与指针

int a[3][4]={{1,2,3,4},{5,6,7,8},{9,10,11,12}};
              a[0]         a[1]         a[2]

说明:
二维数组的行指针指向一维数组 a,a+1,a+2 行指针的移动单位是以数组为单位进行移动   
列指针指向数组的元素a[0]、a[1]、a[2]列指针的移动单位是以数组元素为单位进行移动
A:二维数组是一个特殊的一维数组。
B:对于int a[3][4]而言3表示二维数组中有三个一维数组,每个一维数组里面又含有4个元素。
C:定义了一个一维数组为a,它里面含有三个元素a[0]a[1]a[2],而每个元素,又是一个含有4个元素的一维数组
D:对于一维数组,a[i]就代表一个数
对于二维数组而言,a[i]本身还是一个数组,a[i]是数组名
所以a[i]它依然是一个地址(指针)
E:对于二维数组里面a,a+1,a+i而言,a+i是指向a[i]的而a[i]它本身也是一个数组,所以a+i是指向一维数组的指针
也被称为行指针,而且行指针的移动单位是以数组为单位进行移动
F:对于二维数组里面的a[i]而言,a[i]是指向元素a[i][0],换句话说,a[i]是指向一维数组元素的指针(列指针),而且列指针是以元素为单位来移动的
G:二维数组中的列指针a[i]这个指针可以越界
H:二维数组中的a,a+1,a+2 虽然是行指针,但是他们都是常量,不能自加,为了让行指针能够实现移动,就要定义一个行指针变量。所以需要定义一个指向一维数组指针变量。
I:以后只能把a,a+1.....a+i的值赋给该指针,因为它们都是行指针
k:如果把指向一维数组的指针,赋给二维数组的数组名,那么这个指针,就可以当成二维数组来使用

int a[3][4],(*p)[4]=a;
a[i][j]=p[i][j]=*(*(a+i)+j))=*(*(p+i)+j))
格式:
 int (*p)[数组长度];
 int (*p)[4];  定义了一个指针为p  这个指针,是一个行指针,那么以后这个指针只能够指向一个一维整型数组的,
并且它所指向的一维整型数组,里面要含有4个元素
  
int a[3][4]       
a-->    a[0]--->a[0][0]      **a=*a[0]=a[0][0]
a[0][1]
a[0][2]
a[0][3]
a移动一个是移动了一行,是指向一维数组的指针
a[0]是指向一维数组元素的指针(列指针,移动一个元素)
a+1--> a[1]--->a[1][0]      **(a+1)=*a[1]=a[1][0]
    a[1][1]
    a[1][2]
    a[1][3]

a+2--> a[2]--->a[2][0]
    a[2][1]
    a[2][2]
    a[2][3]

*a=a[0]
*a[0]=a[0][0]
**a=a[0][0]

**(a+1)=*a[1]=a[1][0]
*(*(a+1)+2)=*(a[1]+2)=a[1][2]

*(*(a+i)+j)=*(a[i]+j)=a[i][j]    //这个结论很重要

例子:

main()//这里的每一个main()函数都是一个单独的例子
{
		
	int a[3][4]={{1,2,0,1},{1,1,0,2},{3,2,0,1}},k1,k2,k3;
	k1=**a***a+1;                   //**a=a[0][0]=1 *  1+1=   2
	k2=**a**(*a+**a+1);             //1* *(*a+1+1)=*(a[0]+2)=a[0][2]=0
	k3=**a*(*(*a+*(*(a+1)+2)));     //*(*(a+1)+2)=a[1][2]=0     **a*(*(*a+0))=1*1=1
        printf("k1=%d,k2=%d,k3=%d",k1,k2,k3);			
	
}	

main()//这里的每一个main()函数都是一个单独的例子
{
		
     int a[3][4]={{1,2,0,1},{1,1,0,2},{3,2,0,1}},k1,k2,k3;
     k1=**a***a+1;                   //**a=a[0][0]=1 *  1+1=   2
     k2=**a**(*a+**a+1);             //1* *(*a+1+1)=*(a[0]+2)=a[0][2]=0
     k3=**a*(*(*a+*(*(a+1)+2)));     //*(*(a+1)+2)=a[1][2]=0     **a*(*(*a+0))=1*1=1
     k4=*a[2];//a[2][0]=3
     k5=(*a)[2]//a[0][2]
     k6=*(a[0]+6)//a[1][2]
//二维数组中的a[i]这个指针可以越界(非常重要)
     printf("k1=%d,k2=%d,k3=%d",k1,k2,k3);			
	
}

数组名是常量,不能自加

int a[3][4],*p[4];

定义了一个指针为p  这个指针,是一个行指针,那么以后这个指针只能够指向一个一维整型数组的,
                  并且它所指向的一维整型数组,里面要含有4个元素
p=a[0];//这是错的
p=a//p 是行指针   a,a+1...a+i

以后只能把a,a+1.....a+i的值赋给该指针,因为它们都是行指针,行指针是以数组为单位进行移动的
 

main()
	{
		
		int a[3][4]={{1,2,3,4},{5,6,7,8},{9,10,11,12}},*p[4],k1;
		p=a+1;
		k1=**p+*(*p+1)+*(*(p+1)+1)//a[1][0]+a[1][1]+a[2][1]=21
		 printf("k1=%d",k1);
	}
	
	
	main()//这里的每一个main()函数都是一个单独的例子
	{
		
		int a[3][4]={{1,2,3,4},{5,6,7,8},{9,10,11,12}},(*p1)[4]=a,*p2=a[1],k;
		k=*(*p1+1)**p2;     //*(a[0]+1) *  a[1][0]=a[0][1]*a[1][0]=2*5=10
	        printf("k1=%d",k1);
	}		
		
		main()
		{
		
			int a[3][3]={{2},{4},{6}},i,*p=&a[0][0];//这边的p是列指针
			for(i=0;i<2;i++)
			{
				if(i==0)
				{
					a[i][i+1]=*p+1;
				}
				else
				{
					++p;
					
				}
				printf("%d",*p);
			}
				
		}        key //23
		
		
			
		main()//这里的每一个main()函数都是一个单独的例子
		{
		
			int a[3][4]={{1,2,3,4},{5,6,7,8},{9,10,11,12}};
			int (*p)[4]=a,i,j,k=0;
			for(i=0;i<3;i++)
			{
				for(j=0;j<2;j++)
				{
					k+=*(*(p+i)+j);//k+=p[i][j];
				}
				printf("k=%d",k);//把前两列加起来33
			}
		}
		

如果把指向一维数组的指针,赋给二维数组的数组名,那么这个指针,就可以当成二维数组来使用

int a[3][4],(*p)[4]=a;
a[i][j]=p[i][j]=*(*(a+i)+j))=*(*(p+i)+j))

main()
{
    int a[][3]={{1,2,3},{4,5,0}},(*pa)[3],i;
    pa=a;
    for(i=0;i<3;i++)
   {
       if(i<2)
       pa[1][i]=pa[1][i]-1;
       else pa[1][i]=1;

   }
   printf("%d",a[0][1]a[1][1]+a[1][2]);//7
}

指向一维数组的指针,一般会与二维数组配合使用,实际上就是对二维数组进行编程,
实际就是以二维数组作为函数参数。
 A:型参用数组,实参也用数组
   函数定义 : fun(int a[][4])
函数调用: fun(a)
 B:型参用指针,而实参用数组:
   函数定义: fun(int (*p)[4])
函数调用: fun(a)
 C:型参用指针,而实参用指针:
    函数定义: fun(int (*p)[4])
函数调用: fun(指针a)
 
//编写一个函数,目的是为了求出二维数组中所有元素的和

 

int sum(int (*p)[4])
{
	int s,i,j;
	for(i=0;i<3;i++)
	{
		for(j=0;j<4;j++)
		{
			s+=p[i][j];
		}
	}
	return s;
	}
int sum(int a[][4])
{
	int s,i,j;
	for(i=0;i<3;i++)
	{
		for(j=0;j<4;j++)
		{
			s+=a[i][j];
		}
	}
		return s;
	}
		
main()
{
	int a[3][4]={{1,2,3,4},{5,6,7,8},{9,10,11,12}};
	printf("sum=%d",sum(a));
}
			 

例子:
把二维数组的第一行元素与最后一行的元素调换,把第二行与倒数第二行的元素调换,以此类推

1   2   3   4                    17  18  19  20
5   6   7   8                    13  14  15  16 
9   10  11  12    转换成    9   10  11  12
13  14  15  16                   5   6   7   8
17  18  19  20                   1   2   3   4 

a[i][0] >  a[j][0]
a[i][1] >  a[j][1]
a[i][2] >  a[j][2]
a[i][3] >  a[j][3]
第0行与第4行的元素交换

void funhuan(int (*p)[4])
{
	int i,j,n,t;
	for(i=0,j=4;i<j;i++,j--)//实现行的互换
	{
		for(n=0;n<4;n++)//每行的4个元素
		{
			t=p[i][n];
			p[i][n]=p[j][n];
			p[j][n]=t;
		}
	}
}

main()
{
	int a[5][4]={1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20};
	int i,j;
	for(i=0;i<5;i++)
	{
		for(j=0;j<4;j++)
		{
			printf("%5d",a[i][j]);
		}
		printf("\n");
	}
	printf("\n");
	funhuan(a);
	for(i=0;i<5;i++)
	{
		for(j=0;j<4;j++)
		{
			printf("%5d",a[i][j]);
		}
		printf("\n");
	}
}
	

编写一个程序,它的功能是把一个二维数组中周边元素都置为零

void setZero(int (*p)[4])
{
	int i,j;
	for(i=0;i<4;i++)
	{
		p[0][i]=0;//*(*(a)+i)=0;
		p[3][i]=0;
		p[i][0]=0;
		p[i][3]=0;
	}
}	
main()
{
	int a[5][4]={1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16};
	setZero(a);
	int i,j;
	for(i=0;i<4;i++)
	{
		for(j=0;j<4;j++)
		{
			printf("%5d",a[i][j]);
		}
		printf("\n");
	}
	

给一个一维数组,中所有行的元素的值都向右移m个位置,左边置零。

  void move0(int *a,int n)
	{
			 for(int i=0;i<n;i++)
			{
				a[n-i]=a[n-i-1];
			}
			a[0]=0;
	}
	
	
	
	main()
	{
      int a[4]={1,2,3,4},i,m;
		
		for(i=0;i<4;i++)
	   {
		   printf("%5d",a[i]);
		}	
			printf("\n");
			scanf("%d",&m);
		for(i=0;i<m;i++)
		{
			move0(a,4);
		}		
		for(i=0;i<4;i++)
	   {
		   printf("%5d",a[i]);
	   }
	}

编写一个函数,把N*N的一个二维数组,根据给定的M值将这个二维数组中所有行的元素的值都向右移m个位置,左边置零。
1   2   3   4                 0   0   1   2   
5   6   7   8                 5   6   7   8    
9   10  11  12    转换成      9   10  11  12   
13  14  15  16                13  14  15  16   
 
若m=1

为了方便思考,假设先移动一行,移动第i行

先看第一行,  1  下标为2开始移
,2  下标为1开始移   
 3  下标为0开始移
 i  下标为3-i开始移
 
m=2时  
 a[i][3]=a[i][1]
 a[i][2]=a[i][0]
 下标隔2, 因为m=2
 j=3-m//从该位置开始移
for(j=3-m;j>=0;j--)
{
a[i][j+m]=a[i][j];//右移m个位置
}
 for(j=0;j<m;j++)//左边置零
 {
 a[i][j]=0;
 }

程序实现: 

void fun(int (*a)[4],int m)//m右移多少位
{
	int i,j;
	//每一行都要移位,假设先移第i行
	for(i=0;i<4;i++)
	{
		for(j=3-m;j>=0;j--)//表示在移动
		{
			a[i][m+j]=a[i][j];
		}
		for(j=0;j<m;j++)//把前面剩下的元素设为0
		{
			a[i][j]=0;
		}
	}
}
				  
 main()
{
	int a[5][4]={1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16},m;
	printf("输入一个整数给m:");
		scanf("%d",&m);
		fun(a,m);
		for(i=0;i<4;i++)
	{
		for(j=0;j<4;j++)//表示在移动
		{
			printf("%5d",a[i][j]);
		}
		printf("\n");
	}
	
//编写一个函数,可以求出二维数组每一行的最大值,并存放在数组num里面返回
void fun(int (*a)[4],int *num)
{
	int i,j,max,k=0;
	for(i=0;i<4;i++)
	{
		max=a[i][0];
		for(j=1;j<4;j++)
		{
			if(max<a[i][j])
				max=a[i][j];
		}
		num[k++]=max;
		printf("\n");
	}
}
 main()
{
	int a[4][4]={1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16},num[4]={0};
	
	
		for(i=0;i<4;i++)
	{
		for(j=0;j<4;j++)
		{
			printf("%5d",a[i][j]);
		}
		printf("\n");
	}
	fun(a,num);
		for(i=0;i<4;i++)
	{
		
			printf("%5d",num[i]);
		
		printf("\n");
	}


 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

aFakeProgramer

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值