c语言二维数组和二级指针

在做这到道题目时,使用到了二维数组和二级指针,直接将二维数组num赋值给二级指针moves,编译过程会报如下告警:

warning: assignment to ‘int **’ from incompatible pointer type ‘int (*)[2]’ [-Wincompatible-pointer-types]

于是将二维数组进行类型强制转换:moves=(int **)num; 再次编译告警消失,但是运行会报段错误“Segmentation fault (core dumped)”。

力扣 

int main()
{

	char *res;
    int num[9][2]={{0,0},{1,1},{2,0},{1,0},{1,2},{2,1},{0,1},{0,2},{2,2}};
	int movesSize = 9;
	int size[9]={2,2,2,2,2,2,2,2,2};
	int ** moves;
	
	moves=(int **)num; 
	
	int *movesColSize;
	movesColSize=size;
	res = tictactoe(moves, movesSize, movesColSize);
	printf("tic_tac_toe_game result is %s\n",res);
	return 0;
}

于是开始考虑二维数组和二级指针的关系。

二维数组:

根据以上告警内容可知,二维数组类型为 int (*)[2],即一个指针数组,数组内容为指向int类型的指针,指针大小为2。num就是num[0]的地址,把二者进行输出,可以看出指向的地址是一样的。也就是二维数组的数组名是一个一维数组的首地址。

int main()
{

	char *res;
    int num[9][2]={{0,0},{1,1},{2,0},{1,0},{1,2},{2,1},{0,1},{0,2},{2,2}};
	int movesSize = 9;
	int size[9]={2,2,2,2,2,2,2,2,2};
	int ** moves;
	
	printf("num is %x, num[0] is %x, num[0][0] is %d\n", num,num[0],num[0][0]); 
//num is ffffcbc0, num[0] is ffffcbc0, num[0][0] is 0
	printf("num add is %x, num[0] add is %x, num[0][0] add is %x\n", &num,&num[0],&num[0][0]); 
//num add is ffffcbe0, num[0] add is ffffcbe0, num[0][0] add is ffffcbe0

	return 0;
}

此时可以定义一个指针数组与二维数组进行一一对应:

注意num和num[0]虽然地址相同,但是类型不同,num是 int (*)[2]类型,而num[0]是int *类型,不同类型表示指向的内存大小和对内存的取址方式不同,例如num[0]是int *类型,num[0]是没法取值到num[1]所指向的内存范围的,而num是可以的。

如果int *p=num[0],是没有方法通过p获取到num[1]的。

而下面的方法是可以通过p获取到num[1]的,即*(p+1)。

int main()
{
	char *res;
    int num[9][2]={{0,0},{1,1},{2,0},{1,0},{1,2},{2,1},{0,1},{0,2},{2,2}};
	int movesSize = 9;
	int size[9]={2,2,2,2,2,2,2,2,2};
	int ** moves;
	
	int (* p)[2];
	p = num;
	//p = num[0] warning: assignment to ‘int (*)[2]’ from incompatible pointer type ‘int *’ [-Wincompatible-pointer-types]
	printf("*(p+0) is %x\n",*(p+0)); // *(p+0) is ffffcbd0 
	printf("*(p+8)[0] is %x\n",*(p+8)[0]); // *(p+8)[0] is 2
	
	return 0;
}

如果要使用二级指针,就需要对多个一级指针进行一一赋值:

int main()
{
	char *res;
    int num[9][2]={{0,0},{1,1},{2,0},{1,0},{1,2},{2,1},{0,1},{0,2},{2,2}};
	int movesSize = 9;
	int size[9]={2,2,2,2,2,2,2,2,2};
	int ** moves;
	
	moves = (int **)malloc(movesSize*sizeof(int *));
	int i;
	for(i=0;i<movesSize;i++){
		moves[i]=num[i];
	}
	printf("&moves is %x,moves is %x,*moves is %x,**moves is %x\n",&moves,moves,*moves,**moves); 
	//&moves is ffffcb98,moves is 3c0,*moves is ffffcbd0,**moves is 0
	printf("moves is %x,moves[0] is %x,moves[0][0] is %d\n",moves,moves[0],moves[0][0]);
    //moves is 3c0,moves[0] is ffffcbc0,moves[0][0] is 0
	
	printf("moves[7] is %x,moves[8] is %x\n",moves[7],moves[8]);
	//moves[7] is ffffcc08,moves[8] is ffffcc10

	int *movesColSize;
	movesColSize=size;
	res = tictactoe(moves, movesSize, movesColSize);
	printf("tic_tac_toe_game result is %s\n",res);
	free(moves);
	return 0;
}

对应关系如下图:

最后附上所有题解代码:

#include "stdio.h"
#include "string.h"
#include "stdlib.h"


#define MAX 5
char res[4][10]={"A","B","Draw","Pending"};

//num=[0,0] in A=[[0,0],[1,1],[0,1],[0,2],[1,0],[2,0]] or not
int inOrNot(int *num, int **A, int Asize){
    int i;
    for(i=0;i<Asize;i++){
        if(num[0]==A[i][0] && num[1]==A[i][1])return 1;// num in A
    }
    return 0;
}

//num of '1' in [1,1,1,0]
int countNum(int num, int *nums, int numsSize){
    int i,cnt=0;
    for(i=0;i<numsSize;i++){
        if(num==nums[i])cnt++;
    }
    return cnt;
}

char * tictactoe(int** moves, int movesSize, int* movesColSize){
    if(movesSize<5)return res[3];
    int i;
    int **A=(int **)malloc(MAX*sizeof(int *));
    for(i=0;i<MAX;i++){
        A[i]=(int *)malloc(movesColSize[0]*sizeof(int));
        if(A[i]==NULL)return NULL;
        memset(*(A+i),-1,movesColSize[0]*sizeof(int));
    }

    int **B=(int **)malloc(MAX*sizeof(int *));
    for(i=0;i<MAX;i++){
        B[i]=(int *)malloc(movesColSize[0]*sizeof(int));
        if(B[i]==NULL)return NULL;
        memset(*(B+i),-1,movesColSize[0]*sizeof(int));
    }

    int A0[5]={-1,-1,-1,-1,-1};
    int A1[5]={-1,-1,-1,-1,-1};
    int B0[5]={-1,-1,-1,-1,-1};
    int B1[5]={-1,-1,-1,-1,-1};

    int a=0,b=0;
    for(i=0;i<movesSize;i++){
        if(i%2==0){
            A[a][0]=moves[i][0];
            A[a][1]=moves[i][1];
            a++;
        }else{
            B[b][0]=moves[i][0];
            B[b][1]=moves[i][1];
            b++;
        }
    }

    for(i=0;i<a;i++){
        A0[i]=A[i][0];
        A1[i]=A[i][1];
    }

    for(i=0;i<b;i++){
        B0[i]=B[i][0];
        B1[i]=B[i][1];
    }
    
    int num[5][2]={{0,0},{1,1},{2,2},{2,0},{0,2}};
    
    if(inOrNot(num[0],A,a)==1 && inOrNot(num[1],A,a)==1 && inOrNot(num[2],A,a)==1)
    {
        free(A);
        free(B);
        return res[0];
    }
    
    
    if(inOrNot(num[3],A,a)==1 && inOrNot(num[4],A,a)==1 && inOrNot(num[1],A,a)==1)
    {
        free(A);
        free(B);
        return res[0];
    }
    if(countNum(0,A0,a)==3 || countNum(1,A0,a)==3 || countNum(2,A0,a)==3)
    {
        free(A);
        free(B);
        return res[0];
    }
    
    if(countNum(0,A1,a)==3 || countNum(1,A1,a)==3 || countNum(2,A1,a)==3)
    {
        free(A);
        free(B);
        return res[0];
    }
    
    if(b<3)
    {
        free(A);
        free(B);
        return res[3];
    }

    if(inOrNot(num[0],B,b)==1 && inOrNot(num[1],B,b)==1 && inOrNot(num[2],B,b)==1)
    {
        free(A);
        free(B);
        return res[1];
    }
    if(inOrNot(num[3],B,b)==1 && inOrNot(num[4],B,b)==1 && inOrNot(num[1],B,b)==1)    
    {
        free(A);
        free(B);
        return res[1];
    }
    if(countNum(0,B0,b)==3 || countNum(1,B0,b)==3 || countNum(2,B0,b)==3)    
    {
        free(A);
        free(B);
        return res[1];
    }
    if(countNum(0,B1,b)==3 || countNum(1,B1,b)==3 || countNum(2,B1,b)==3)    
    {
        free(A);
        free(B);
        return res[1];
    }

    if(movesSize>=9)    
    {
        free(A);
        free(B);
        return res[2];
    }
    free(A);
    free(B);
    return res[3]; 
}

//测试函数
int main()
{
	char *res;
    int num[9][2]={{0,0},{1,1},{2,0},{1,0},{1,2},{2,1},{0,1},{0,2},{2,2}};
	int movesSize = 9;
	int size[9]={2,2,2,2,2,2,2,2,2};
	int ** moves;
	
	moves = (int **)malloc(movesSize*sizeof(int *));
	int i;
	for(i=0;i<movesSize;i++){
		moves[i]=num[i];
	}

	int *movesColSize;
	movesColSize=size;
	res = tictactoe(moves, movesSize, movesColSize);
	printf("tic_tac_toe_game result is %s\n",res);
	free(moves);
	return 0;
}

  • 2
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值