目的是要求输入一个二维数组,指针与数组运算C++

请问怎么修改,目的是要求输入一个二维数组,指针与数组运算。输出p

void menu6()
{
    int n, m, i, j, a[50][50], t,p,*t;
    printf("请输入二维数组的行数:");
    scanf("%d", &n);
    printf("请输入二维数组的列数:");
    scanf("%d", &m);
    printf("请输入二维数组:\n");
    for(i=0; i<n; i++)
    {
        for(j=0; j<m; j++)
        {
            scanf("%d", &a[i][j]);
        }
    }
    for(i=0; i<n; i++)
    {
        for(j=i; j<m; j++)
        {
            t = a[i][j];
            *t=&a[0][0];
            p=(*t)*(*(t+2))*(*(t+4));
        }
    }
    printf(p);
}

该回答通过自己思路及引用到GPTᴼᴾᴱᴺᴬᴵ搜索,得到内容具体如下:
您可以将指针 t 的类型修改为 int*,然后将其指向数组元素 a[i][j],然后进行指针运算和数组访问即可。

另外,您需要将 printf(p) 修改为 printf("%d", p),因为 printf 函数需要一个格式化字符串作为第一个参数,用于指定输出格式。

下面是修改后的代码:

void menu6()
{
    int n, m, i, j, a[50][50], p, *t;
    printf("请输入二维数组的行数:");
    scanf("%d", &n);
    printf("请输入二维数组的列数:");
    scanf("%d", &m);
    printf("请输入二维数组:\n");
    for(i=0; i<n; i++)
    {
        for(j=0; j<m; j++)
        {
            scanf("%d", &a[i][j]);
        }
    }
    for(i=0; i<n; i++)
    {
        for(j=i; j<m; j++)
        {
            t = &a[i][j];
            p = (*t) * (*(t+2)) * (*(t+4));
        }
    }
    printf("%d", p);
}

在上述代码中,我们将指针 t 的类型修改为 int*,然后将其指向数组元素 a[i][j]。在计算 p 的值时,我们使用了指针运算和数组访问,即 (*t) * (*(t+2)) * (*(t+4))。最后,我们使用 printf 函数输出 p 的值。


如果以上回答对您有所帮助,点击一下采纳该答案~谢谢

这个是要求什么?

  • 帮你找了个相似的问题, 你可以看下: https://ask.csdn.net/questions/206408
  • 你也可以参考下这篇文章:【C++】函数如何传递二维数组?二维数组是怎么通过指针进行传递?
  • 除此之外, 这篇博客: C/C++中的二维数组,以及多维数组及其指针中的 C语言 通过指针访问一维数组,二维数组,三维数组。 部分也许能够解决你的问题, 你可以仔细阅读以下内容或跳转源博客中阅读:
  • /**
    通过指针来访问一维数组,二维数组,多维数组
    */
     
    #include<stdio.h>
    const int COLS=3;
    const int COUNT=4;
    //通过一级指针,计算偏移量来遍历一维数组
    void printSingleDimensionalArray(int *data,int data_len);
    //通过一级指针,计算偏移量来遍历二维数组:
    void printDoubleDimensionalArray(int *array,int rows,int cols);
    //通过一级指针,计算偏移量来遍历三维数组:
    void printThreeDimensionalArray(int *array_3,int rows,int cols,int count);
    //使用指向二维数组的指针来遍历三维数组
    void printThreeDimensionalArray2(int (*p)[COLS][COUNT],int rows);
     
    void main()
    {
        int data[]={1,2,3,4,5,6,7,8,9};
        int data_len=sizeof(data)/sizeof(data[0]);
        printf("data[6]=%d\n",*(data+6));//7
        printf("一维数组data:\n");
        printSingleDimensionalArray(data,data_len);
        int array[2][3]={{1,2,3},{4,5,6}};
        printf("二维数组array:\n");
        printDoubleDimensionalArray(array,2,3);
        int count=0;
        int array_3[2][3][4];
        int i,j,k;
        for(i=0;i<2;i++)
        {
            for(j=0;j<3;j++)
            {
                for(k=0;k<4;k++)
                {
     
                    array_3[i][j][k]=count++;
                }
     
            }
        }
        printf("三维数组array_3:\n");
        printThreeDimensionalArray(array_3,2,3,4);
        //三维数组的初始化
        int array_33[2][3][4]=
        {
            {
                {1,2,3,4},
                {5,6,7,8},
                {9,10,11,12},
            },
            {
                {13,14,15,16},
                {17,18,19,20},
                {21,22,23,24},
            }
        };
        printf("三维数组array_33:\n");
        printThreeDimensionalArray(array_33,2,3,4);
        printf("三维数组array_33:\n");
        printThreeDimensionalArray2(array_33,2);
    }
    //通过一级指针,计算偏移量来遍历一维数组
    void printSingleDimensionalArray(int *data,int data_len)
    {
        int i;
        for(i=0;i<data_len;i++)
            printf("%4d",*(data+i));//7
        printf("\n");
    }
    //通过一级指针,计算偏移量来遍历二维数组:
    void printDoubleDimensionalArray(int *array,int rows,int cols)
    {
        int i,j;
        for(i=0;i<rows;i++)
        {
            for(j=0;j<cols;j++)
            {//通过一位指针,计算偏移量来遍历二维数组:
                printf("%4d",*(array+i*cols+j));
            }
            printf("\n");
        }
    }
    //通过一级指针,计算偏移量来遍历三维数组:
    void printThreeDimensionalArray(int *array_3,int rows,int cols,int count)
    {
        int i,j,k;
        for(i=0;i<rows;i++)
        {
            printf("{\n");
            for(j=0;j<cols;j++)
            {
                for(k=0;k<count;k++)
                {
     
    //                array[i][j][k]=count++;
    //                printf("%4d",array_3[i][j][k]);
                    printf("%4d",*(array_3+i*3*4+j*4+k));
                }
                printf("\n");
            }
            printf("}\n");
        }
    }
    //使用指向二维数组的指针来遍历三维数组
    void printThreeDimensionalArray2(int (*p)[COLS][COUNT],int rows)
    {
        int i,j,k;
        for(i=0;i<rows;i++)
        {
            printf("{\n");
            for(j=0;j<COLS;j++)
            {
                for(k=0;k<COUNT;k++)
                {
     
    //                array[i][j][k]=count++;
                    printf("%4d",p[i][j][k]);
    //                printf("%4d",*(array_3+i*3*4+j*4+k));
                }
                printf("\n");
            }
            printf("}\n");
        }
    
    }
    

    结果:

    data[6]=7
    一维数组data:
       1   2   3   4   5   6   7   8   9
    二维数组array:
       1   2   3
       4   5   6
    三维数组array_3:
    {
       0   1   2   3
       4   5   6   7
       8   9  10  11
    }
    {
      12  13  14  15
      16  17  18  19
      20  21  22  23
    }
    三维数组array_33:
    {
       1   2   3   4
       5   6   7   8
       9  10  11  12
    }
    {
      13  14  15  16
      17  18  19  20
      21  22  23  24
    }
    三维数组array_33:
    {
       1   2   3   4
       5   6   7   8
       9  10  11  12
    }
    {
      13  14  15  16
      17  18  19  20
      21  22  23  24
    }
    
    Process returned 2 (0x2)   execution time : 0.312 s
    Press any key to continue.
    

    讲真,他这个讲的其实挺好,但是确实错的。。运行了会报错。。可能是c++标准不同,或者是他代码写露了什么。。

    但是为了简便,或者想使用多级指针的时候怎么办。或者想使用计算机内存更大的静态栈区,而不是常用的数据区,你就需要更深一步了解了。

    比如:

    定义二维指针数组与定义一维指针数组差不多,只是矩阵的维度增加了一维而已。

    下面通过具体的实例来说明如何定义一个二维数组

    int *p[2][3];  // 定义一个二维数组,只是定义,并没有分配地址空间
    int i,j;  // 数组的行数和列数
    // 下面的2个for循环是用来对二维指针数组进行初始化的,也即分配地址。如果不进行初始化操作,就会使指针变为野指针(即指向不明)。
    for(i=0; i<2; i++)
        for(j=0; j<3; j++)
            p[i][j] = (int *)malloc(sizeof(int));
    *p[0][1] = 2; // 对指针数组中指针所指向的内存单元进行赋值操作
    printf("%d\n", *p[0][1]);  // 输出结果
    

    也有人说,指针就是数组,其实这个是可以正确理解的。一个二维数组的数组名就代表一个二级指针,可以用指针来操作二维数组,这是到处都找的到的可以这样:

    int **p=NULL;
    int a[i][j];
    p=a;
    a[i][j]=*(*(p+i)+j);
    动态定义一个二维数组:
    需要用两次循环,free的时候也是得用循环;
    

    先给出结论:第一种是对的,第二种是错的,一定要记住,二级指针是二级指针,但是关于二维数组,有专门定义的数组指针,等级一样,但是使用不同,那个叫二维数组的行指针,参考:
    https://blog.csdn.net/edward_zcl/article/details/89100600
    https://www.cnblogs.com/zou107/p/4909847.html (行指针三维形式)

    实际上这里应该这样描述:
    有两种方式(假设数组是a[3][4]):
    一、一个一个的取元素

    int a[3][4]; int *p; p=a[0];
    

    则将指针指向了数组a的第一个元素
    二、一行一行的取元素

    int a[3][4];
    int (*p)[4];
    p=a;
    

    则创建了一个指向包含4个元素的指针,它可以一次指向数组的一行”

    更高维形式:

    int array[2][2]={{1,2},{3,4}};
    int* p[2][2];//here...
    int (*p)[2][2];
    

    实际上用不完。。

    或者你再看一个例子:
    问题描述:怎么让一个二维指针指向一个二维数组
    如: **p=a[M][N]

    二级指针的原理
    它是指向内存地址的地址,简单说就是取两次地址,一维数组,二维数组它们的元素都对应拥有一个暂时分配的内存地址,就是说只需要一个一级指针就可以完成取址,如果你用一个二级指针去取址是会取到乱值,如果是系统的地址系统就会崩溃(我就是试过用指针把编译器搞崩溃了),我下面例子说明一下:
    一级指针取址:

    char a[10];
    char *p;
    p=a/*将a[10]首地址赋值给一级指针*/
    scanf("%s",p)/*编译系统会移动自动指针*/
    char a[10][10];
    char *p;
    p=a[0]/*将a[10][10]首地址赋值给一级指针*/
    scanf("%s",p)/*编译系统会移动自动指针*/
    

    二级指针:

    char *a[]={"12","34","56"};/*定义一个指针数组*/
    char **p;/*二级指针*/
    p=a;
    printf("%s",*p);/*输出12*/
    

    C语言严格区分字符串数组与字符数组,实际上一个字符串就等价于一个一维字符数组,并且结尾以/0结束,给出的也是字符串首地址,%s输出会直接全部输出,直到/0结束。
    参考:https://blog.csdn.net/lemon_jay/article/details/82917000

    这里我解释一下,定义一个指针数组,就是数组里面又有地址,你仔细看看,数组有地址,指针数组里面的字符串如(“12”)也是有地址的,这样就需要用一个二级指针指向它了,就是二级寻址,这是*p就不再是元素,就变成字符串"12"的首地址,由于系统自动移动指针,所以就输出12
    呵呵,如果你明白,那么三级指针也是同样道理,定义一个指向指针的指针数组,用一个
    三级指针实现三级寻址,就是找三次地址,这里我就不举例了,怕你不明白了,呵呵……你现在明白了吗?

    另外,这是通过以为的形式访问高维数组,这个才是对的。。
    实现代码:

    int a[m][n];
    int *p = &a[0][0];
    

    通过p[i*n+j]访问a[i][j]
    在C语言和C++语言中,数组元素全为指针的数组称为指针数组。
    一维指针数组的定义形式为:“类型名 *数组标识符[数组长度]”。
    例如,一个一维指针数组的定义:int *ptr_array[10]。

    这个人就更加高级,采取了取巧的方法,这种方式避免的类型兼容。

    #define N 2
    typedef char T_Array[N][N];
    T_Array aa;
    T_Array * p = &aa;
    



    不止我一个人发现了这个问题,比如:https://blog.csdn.net/Bennett2251/article/details/74854406
    果然谭浩强那本C语言的书某些知识点是错误的,今天在用代码实现的时候发现了错误。比如如何用指针变量引用二维数组,书中写的是定义指针变量和定义一维的时候一样,只是引用的时候不同而已,但实际去写代码的时候是错误的。举例引用二维整形数组。
    int a[col]; //定义一个row行col列的二维数组
    int (*p)[col]; //定义引用二维数组的指针变量,p为指针变量名,col为二维数组的列大小(书中写的是int *p 即可,但是实际上是错误的)
    p=a; //让指针变量指向二维数组
    ((p+i)+j) //引用二维数组中的i行j列的元素
    这只是我发现书中的某一个错误点,希望其他学习者在学习的时候能够注意。




    最后,给出一个通用的,最适合处理大型的,多维的数组数据的方法。
    请教在C语言中如何定义三维动态数组?

    和二维类似, 只不过再多一层。 比如三维int 数组, 定义动态3 4 5

    那么代码可以是:

    int *** a;
    int i,j;
    a=(int***)malloc(sizeof(int **)*3);
    for(i = 0; i < 3; i ++)
    {
        a[i] = (int **) malloc(sizeof(int *) *4);
        for(j = 0; j < 4; j ++)
            a[i][j] = (int *)malloc(sizeof(int)*5);
    }
    

    这样得到的a
    类似于int aa[3][4][5];

    又或者:用C语言怎么实现三维以上动态数组
    和二维类似 一层层申请就好。

    以下是一个三维的例子

    int i,j,k;
    int m,n,p;
    int ***a;
    scanf("%d%d%d",&m,&n,&p);//make a array[m][n][p]
    a=(int***)malloc(sizeof(int **) * m);
    for(i = 0; i < m ; i ++)
    {
        a[i] = (int **)malloc(sizeof(int*)*n);
        for(j = 0; j < n; j ++)
        {
            a[i][j] = (int *)malloc(sizeof(int) *p);
            for(k = 0; k < p; k ++)
                scanf("%d",&a[i][j][k]);
        }
    }
    

    又比如:
    用C语言,动态三维数组
    编写一个函数CreateGrid(int m, int n, int t),用来创建一个动态的三维数组,其中m、n、t分别表示该数组每一维的长度。要求整个数组的存储空间都是用用C语言的库函数malloc函数动态申请的。另外编写一个FreeGrid函数,用来释放这个三维数组。

    1、先说二维,可以这么理解:int n[3]有3个int那么,int m[5][3]有5个int[3]赋值时:n[1]=3把3给1号m[4]={5,9,4}m[4]是个int[3]类型,这么赋值,也就是这么赋值:m[4]的[0]是5:m[4][0]=5m[4][1]=9m[4][2]=4懂了吗?三维甚至更多维大同小异,比如int k[4][5][3]有4个int[5][3]

    2、例程:

    int*** CreateGrid(int m,int n,int t)
    {
        int*** tt = NULL; 
        tt = (int***)malloc(sizeof(int)*m);
        for(int i=0;i<m;i++)
        {
            tt[i] = (int**)malloc(sizeof(int)*n);;
            for (int k=0;k<n;k++)
            {
                tt[i][k] = (int*)malloc(sizeof(int)*t);
            }
        }
        return tt;
    }
    void FreeGrid(int*** tt,int m,int n,int t)
    {
        if(tt != NULL)
        {
            for(int i=0;i<m;i++)
            {
                for (int j=0;j<n;j++)
                                                        {
                    free((tt[i][j]));
                }
                free(tt[i]);
            }
            free(tt);
            tt = NULL;
        }
    }
    

    或者这样写:

       int*** CreateGrid(int m,int n,int t)
        {
        int*** tt = NULL;
        tt = (int***)malloc(sizeof(int)*m);
        for(int i=0;i<m;i++)
        {
        tt[i] = (int**)malloc(sizeof(int)*n);;
        for (int k=0;k<n;k++)
        {
        tt[i][k] = (int*)malloc(sizeof(int)*t);
        }
        }
        return tt;
        }
        void FreeGrid(int*** tt,int m,int n,int t)
        {
        if(tt != NULL)
        {
        for(int i=0;i<m;i++)
        {
        for (int j=0;j<n;j++)
        {
        free((tt[i][j]));
        }
        free(tt[i]);
        }
        free(tt);
        tt = NULL;
        }
        }
    

    又或者这样写:

    #include <stdlib.h>
    int *** CreateGrid(unsigned m, unsigned n, unsigned t);/*创建整形三维数组*/
    void FreeGrid(int *** c1,unsigned m,unsigned n);/*释放整形三维数组*/
    static void free1(int *** c1,unsigned n);
    static void free2(int *** c1,unsigned m,unsigned n,unsigned k);
    int *** CreateGrid(unsigned m, unsigned n, unsigned t)/*创建整形三维数组*/
    {
    int ***c1;
    int i,j;
    c1=( int ***)malloc(sizeof( int **) * m);/*分配第一维*/
    if(!c1)/*第一维分配失败*/
    return (int ***)NULL;
    for(i=0;i!=m;++i)/*分配第二维*/
    {
    c1[i]=(int **)malloc(sizeof(int*) *n);
    if(!c1[i])
    break;
    }
    if(i!=m)/*第二维分配失败,释放以前分配到的内存*/
    {
    free1(c1,i);
    return (int ***)NULL;
    }
    for(i=0;i!=m;++i)/*分配第三维*/
    {
    for(j=0;j!=n;++j)
    {
    c1[i][j]=(int *)malloc(sizeof(int) * t);
    if(!c1[i][j])
    break;
    }
    if(j!=n)
    break;
    }
    if(j!=n)/*第三维分配失败,释放以前分配到的内存*/
    {
    free2(c1,m,n,j);
    return (int ***)NULL;
    }
    return c1;
    }
    static void free1(int *** c1,unsigned m)/*释放前m个指针*/
    {
    int i;
    for(i=0;i!=m;++i)
    free(c1[i]);
    free(c1);
    }
    static void free2(int *** c1,unsigned m,unsigned n,unsigned k)
    {
    int i,j;
    for(i=0;i!=m;++i)
    for(j=0;j!=n;++j)
    free(c1[i][j]);
    for(i=0;i!=k;++i)
    free(c1[m][i]);
    free1(c1,m);
    }
    void FreeGrid(int *** c1,unsigned m,unsigned n)/*释放内存*/
    {
    free2(c1,m,n,0);
    }
    

    最笨的办法是采用C自带的数组类型,但是可能会遇到内存不足的问题,而且它的访问,讲真不是那直观。
    如某人说:推荐定义一个一维数组,按三维结构进行存储

    int limit[20][2]={{3,8}, {4,9}, {5,0}, {1,6}, {2,7},
    {2,7}, {3,8}, {4,9}, {5,0}, {1,6},
    {1,6}, {2,7}, {3,8}, {4,9}, {5,0},
    {1,6}, {2,7}, {3,8}, {4,9}, {5,0}};
    
    
    int limit[4][5][2]={ {{3,8}, {4,9}, {5,0}, {1,6}, {2,7}},
    {{2,7}, {3,8}, {4,9}, {5,0}, {1,6}},
    {{1,6}, {2,7}, {3,8}, {4,9}, {5,0}},
    {{1,6}, {2,7}, {3,8}, {4,9}, {5,0}} };
    

    注意:c语言的数组是连续存储的,而且有自己的默认值,程序存储区,数据存储区,常量存储区,静态与动态内存,自己的初始化数据格式。

    如果想从内存的角度理解多维数组,多级指针,可以参见:
    https://blog.csdn.net/zjy900507/article/details/80858800
    https://www.zhihu.com/question/50738576?sort=created
    https://www.cnblogs.com/hwli/p/10745446.html
    http://c.biancheng.net/view/227.html
    https://blog.csdn.net/theusProme/article/details/55656806
    https://blog.csdn.net/mytzs123/article/details/77916958

  • 您还可以看一下 林男老师的小学生c++趣味编程入门视频教程 少儿C十十信息学奥赛竞赛网课课程中的 变量、表达式与赋值语句——教室面积小节, 巩固相关知识点