精华内容
下载资源
问答
  • 二维指针的详解

    2018-06-26 17:28:48
    很好的讲解了二维指针,可以看文档自学,很适合初学者。
  • 一维指针和二维指针

    2020-08-03 10:59:31
    今天从函数传参的角度来理解指针
  • 一维指针其实就相当于一维数组,不用去看书上所说的数组在内存中的首地址这些晦涩的话,以此类推 二维指针就相当于二维数组,新手对一维数组的开辟与释放比较容易熟悉,例如上面的a 释放就是 delete []a;...
  • 关于用指针方式访问二维数组的问题 首先说明几种类型: int a[2][4] = { 1,2,3,4,5,6,7,8 };//二维数组 int **p; //二重指针跨度为sizeof(int *) int(*q)[4]; //该语句是定义一个指向数组的指针,指向含4个...

    关于用指针方式访问二维数组的问题

    发现二维指针和二维数组很容易被混淆。这里详细梳理一遍
    首先说明几种类型:

    
    int a[2][4] = { 1,2,3,4,5,6,7,8 };//二维数组
    	int **p;	//二重指针,跨度为sizeof(int *)
    	int(*q)[4]; //定义一个指向数组的指针,指向含4个int元素的一维数组。跨度为4*sizeof(int)=16;
    	int * q2[4];	//定义了一个数组 里面存有int * 类型的指针 跨度为sizeof(int *)
    

    关于跨度,是指针偏移一个单位,其对应的物理地址的偏移量。举个例子:

    int *p =0 //p 指向地址0
    p2=p+1 //p2指向地址4
    

    这里p的跨度为4,因为p增加一位,对应地址增加4位(int 在计算机中占4个字节的存储量)
    每个指针,在机器中就是一个类型的变量,他所占字节数都是固定的(32位或者64位),但是其不同的类型和跨度完全是编译器阶段赋予他们的含义,比如:

    int a=3
    int *p1=&a;
    float *p2=&a;
    

    他们在存贮在计算机中只是两个数,都指向a的地址,但是你定义的时候一个使用int,一个使用float,所以编译器认定p1跨度为4,p2跨度为8。

    二维数组的在计算机中依然是以一维线性关系排布的

    以二维数组a[2][3]为例,a是由数组a[0]、a[1]组成的一维数组,因此,数组名a可以看作是数组 { a[0], a[1] } 的首地址,即a==&a[0]。

    定义一个二维数组和二级指针变量

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

    这里要是想使用p访问二维数组a,编译器会报错

    p=a;
    

    因为p的定义可以解读为:

    int *(*p);
    

    即指针p的关联类型为int*
    而数组a的定义可以解读为:

     int(a[2])[3];
    

    a是关联类型为int[3]的一维数组。很显然,a与p的关联类型都不一样,故而不能用p去操作a。在这举一个例子来说明:
    p+i的地址偏移量为

    p+sizeof(int*) *i = p+4*i Byte //假定计算机中的用4个字节Byte来存储指针变量
    

    而a+i的地址偏移量为

    a+sizeof(int[3])*i = p+3*4*i Byte
    

    显然二级指针变量与二维数组名的跨度是不同的,所以赋值会导致编译器不能确定其跨度,因为编译器选择报错。 二维数组的在计算机中的空间类型是以一维线性关系排布的,二维数组的指针使用方式本质上来说属于一维指针的调用方式。但是为了与一维指针相区别,所以必须调用两次*号运算符来接引用。但是二维数组指针与二重指针并不一样。 在未加*号之前 a的跨度为(int的大小×列数),在第一次解引用之后*a的跨度为(int 的大小)比如

    a[2][4]**(a+1)+3,**(a+7

    都是对a[2][4]的最后一个元素(第二行第四列)进行访问的操作。
    在这里插入图片描述
    其实*aa 指向的地址是一模一样的,只是编译器理解的含义不用,对于a编译器会将其看成是一个指向数组的指针,而*a编译器则会将其看成某一具体数组的首地址,其跨度也完全不同。
    *a

    重点来了:
    对于使用指针访问2维数组的话,

    Int a[2][4]={12345678};
     Int **p=(int **)a;
     Cout<< *(*(p+1)+2);
     
    

    这种方法是错误的,不可以使用二维指针直接访问,即使p和a的指向地址相同也不可!
    但是如下方法又是可行的:

     Int a[2][4]={12345678};
     Int **p=(int **)a;
     Cout<< (int (*)[4])p;
    

    只要你进行强制类型转换告诉编译器这是个指向4维数组的指针,编译器就可以正确的解码了。这是为什么呢?,
    上文我说过:二维数组本质上其实是一维指针。所以只能进行一次物理地址的访问。*aa指向的是一个地址,第一次取*号其实不是真正的去访问物理地址,只不过的编译器看他的方式改变了(对于a编译器会将其看成是一个指向数组的指针,而*a编译器则会将其看成某一具体数组的首地址),所以第二次取*号才是真正的访问物理地址上数组的元素。
    但是对于二维指针(int **)p来说,这是真正的二维指针,你对它取第一次*号的时候 *p已经真正的访问了物理地址,这时*pa[2][4]中的第一个元素a[0][0],其值为1。那么第二次取*的时候,**p就会要求访问的物理地址为1的单元,很明显这是我们的进程不能访问的地址段,所以程序出错。

    展开全文
  • 一维数组、二维数组 和 一维指针、二维指针的本质区别 数组和指针极其相似,他们的访问、查询、赋值操作是一模一样的,但指针和数组还是有去别的·,就是他的初始化,数组的初始化是自动的,而指针是被动的,数组...

    一维数组、二维数组 和 一维指针、二维指针的本质区别

    数组和指针极其相似,他们的访问、查询、赋值操作是一模一样的,但指针和数组还是有区别的·,就是他的初始化,数组的初始化是自动的,而指针是被动的,数组一定义就自动的获得了一个被定义大小的空间,并和其相关联、不可改变,可以直接用来存储数据;而指针刚定义出来时没有分配储存数据的空间的,要你人为分配空间给它

    像下面的二维指针的定义、使用就和能说明问题

    #include <stdio.h>
    #include <stdlib.h>
    int main()
    {
        int *p;      //一维指针的定义和使用
        int i;
        int size = 10;
        p = (int *)malloc(sizeof(int) * size); //给一维指针分配内存空间
        for(i=0; i<size; i++)
        {
            //*(p + i) = i;//the function is same as below
            p[i] = i;
        }
        for(i=0; i<size; i++)
        {
            printf("%d\n", *(p+i));//the function is same as below
            //printf("%d\n", p[i]);
        }
        return 0;
    }
    
    
    #include <stdio.h>
    #include <stdlib.h>
    int main()
    {
        int **arr;   //二维指针的定义
        int m=3,n=4,i,j;
        arr = (int **)malloc(sizeof(int*)*m);  //给该二维指针的第一维分配一个大小
                                               //为m的空间,即把空间首地址赋给它
                                            //该空间用于储存第二维分配到的空间的首地址
                                            //第一维的空间存地址
        for(i=0; i<m; i++)
            arr[i] = (int *)malloc(sizeof(int)*n);  //给第二位分配大小为n的空间,
                                                   //即把空间的首地址存到第一维刚
                                                   //分配到的内存中。                                        
        for(i=0; i<m; i++)                          //第二维的空间存值
        {
            for(j=0; j<n; j++)
            {
                arr[i][j] = i*10+j;
                //*(*(arr+i)+j) = i*10+j;
                //*(arr[i]+j) = i*10+j;
            }
        }
        for(i=0; i<m; i++)
        {
            for(j=0; j<n; j++)
            {
                //printf("%d ", arr[i][j]);
                //printf("%d ", *(*(arr+i)+j));
                printf("%d ", *(arr[i]+j));
            }
            printf("\n");
        }
        for(i=0; i<m; i++)
            free(arr[i]);
        free(arr);
        return 0;
    }
    
    
    
    #include<bits/stdc++.h>
    using namespace std;
    int main(){
    	int a[10];
    	int **b;
    	b = (int **)malloc(sizeof(int *));  //给第一维分配空间 
    	*b = a;  //把二维指针的第一维成员 *b(即b[0])指向一个一维数组的空间 
    	for(int i = 0; i < 4; i++)
    	cin>>a[i];
    	cout<<endl;
    	for(int i = 0; i < 4; i++){
    //		cout<<b[0][i]<<' ';
    		cout<< *(*(b + 0) + i)<<' ';
    	}
    	
    	cout<<endl;
    }
    
    #include<bits/stdc++.h>
    using namespace std;
    int main(){
    	int a[10];
    	int **b;
    	b = (int **)malloc(sizeof(int *));  //给第一维分配空间 
    	*b = a;  //把二维指针的第一维成员 *b(即b[0])指向一个一维数组的空间 
    	int** c;  
    	c = b;  //让二维指针指向b所指的空间 
    	for(int i = 0; i < 4; i++)
    	cin>>a[i];
    	cout<<endl;
    	for(int i = 0; i < 4; i++){
    //		cout<<b[0][i]<<' ';
    		cout<< c[0][i]<<' ';
    	}
    	
    	cout<<endl;
    }
    
    using namespace std;
    int main(){
    	int a[10][10];
    	int *b;
    	b = *(a + 2);   
    	//b = a[2]效果等同
    	for(int i = 0; i < 4; i++){
    		cin>>a[2][i];
    	}
    	for(int i = 0; i < 4; i++)
    	cout<<b[i]<<' ';
    }
    

    以上这些代码都是合法的
    //
    下面转载大佬的总结,链接:https://blog.csdn.net/kejiazhw/article/details/8263515

    1. 二维数组
    TYPE array[row][column];
    在定义时row可以不指定,但column必须指定。例如:
    int arr1[3][2]={{1,2},{3,4},{5,6}};
    等价于:
    int arr1[][2]={{1,2},{3,4},{5,6}};

    2.指向二维数组的指针:
    TYPE (*parray)[column];
    在定义时,column必须指定,例如定义一个指向上面定义的二维数组的arr1[3][2]的指针:
    int (*parr1)[2];
    parr1=arr1;

    3.指针数组:
    TYPE *array[num];
    例如定义一个指针数组,包含三个int的指针:
    int *parr2[3];
    int a,b,c;
    parr2[0]=&a;
    parr2[1]=&b;
    parr2[2]=&c;

    4.指向二维数组的指针数组:
    TYPE (*parray[num])[column];
    其中column为二维数组的维度。num为指针的个数,定义时如果直接赋值的话,可以不指定num的大小。
    例如定义一个指针arr1的指针数组,数组的大小为5:
    int (*parr1[5])[2];
    parr1[0]=arr1;
    printf("%d",parr1[0][2][1]); // 输出为:6

    另外一个例子:
    static const char _keyboard_lower[4][10]=
    {
    {‘q’,‘w’,‘e’,‘r’,‘t’,‘y’,‘u’,‘i’,‘o’,‘p’},
    {‘a’,‘s’,‘d’,‘f’,‘g’,‘h’,‘j’,‘k’,‘l’},
    {‘z’,‘x’,‘c’,‘v’,‘b’,‘n’,‘m’,LITE_KEYSYM_BACKSPACE},
    {LITE_KEYSYM_INPUT_METHOD,LITE_KEYSYM_INPUT_MODE,’ ‘,LITE_KEYSYM_CAPS_LOCK,LITE_KEYSYM_ENTER},
    };
    static const char _keyboard_upper[4][10]=
    {
    {‘Q’,‘W’,‘E’,‘R’,‘T’,‘Y’,‘U’,‘I’,‘O’,‘P’},
    {‘A’,‘S’,‘D’,‘F’,‘G’,‘H’,‘J’,‘K’,‘L’},
    {‘Z’,‘X’,‘C’,‘V’,‘B’,‘N’,‘M’,LITE_KEYSYM_BACKSPACE},
    {LITE_KEYSYM_INPUT_METHOD,LITE_KEYSYM_INPUT_MODE,’ ‘,LITE_KEYSYM_CAPS_LOCK,LITE_KEYSYM_ENTER},
    };
    static const char _keyboard_num[4][10]=
    {
    {‘1’,‘2’,‘3’,‘4’,‘5’,‘6’,‘7’,‘8’,‘9’,‘0’},
    {’@’,’$’,’%’,’&’,’*’,’-’,’/’,’(’,’)’},
    {’!’,’`’,’:’,’;’,’,’,’?’,’.’,LITE_KEYSYM_BACKSPACE},
    {LITE_KEYSYM_INPUT_METHOD,LITE_KEYSYM_INPUT_MODE,’ ',LITE_KEYSYM_CAPS_LOCK,LITE_KEYSYM_ENTER},
    };

    static const char (*_keyboard_char[])[10]={
    _keyboard_lower,
    _keyboard_upper,
    _keyboard_num,
    };

    展开全文
  • 我们都知道在 C++ 中分配动态数组用的是 new , 撤销动态数组用的是 delete[ ] ,现在让我们来看看怎么利用这两个关键字给二维指针分配内存
  • 二维数组指针分配 形式有多种 可以指定一维 分配一维 也可以不指定都分配
  • 都错误的认为 二维数组 和 二维指针作为函数的参数时是等价的。这种认知是错误的。究其原因,还是对数组和指针理解的不深入。今天把我的理解做一个总结: 假如一个函数的形参是一个二维指针,但是你实参传入的是一...

    不管是在工作上,还是最近在LeetCode上刷题。都错误的认为 二维数组 和 二维指针作为函数的参数时是等价的。这种认知是错误的。究其原因,还是对数组和指针理解的不深入。今天把我的理解做一个总结:

    假如一个函数的形参是一个二维指针,但是你实参传入的是一个二维数组。那么你就会编译报错。

    为什么我会错误的认为二维数组作为函数参数的时候等价于二维指针呢?

    我思考了我为什么会这么想的原因了:一维数组作为函数参数的时候,编译器会把数组名当作指向该数组第一个元素的指针。所以我想当然的以为:既然一维数组和一维指针在函数参数中等价,那二维数组应该就等价于二维指针啊。

    但是很遗憾,二维数组作为函数参数并等价于二维指针。因为数组作为函数参数时转换为指针没有传递性。也就是说你不能认为一维数组和一维指针作为函数参数等价,就认为二维数组和二维指针就等价了。在C语言中没有这样的传递性。

    其实仔细想想,也是很容易明白的。二维数组其实就是一个数组的数组(即它是一个一维数组,只不过它的每个元素又都是一个一维数组)。当二维数组作为函数入参时,比如 int a[3][4]; 它的第一维数组会被转换成指针,相当于是传入了一个指向数组的指针。即作为函数参数, int a[3][4]和 int (*p)[4]等价。那 int (*p)[4]和 int **pp等价吗?肯定不等价呀, p指针指向类型是 int [4],而pp指向的类型是int *。

    展开全文
  • c-二位数组赋值及二维指针使用欢迎使用Markdown编辑器新的改变功能快捷键合理的创建标题,有助于目录的生成如何改变文本的样式插入链接与图片如何插入一段漂亮的代码片生成一个适合你的列表创建一个表格设定内容居中...

    c-二位数组赋值及二维指针使用


    #include <stdio.h>

    void main()
    {
    int test[3][2] = {{1, 1}, {2, 2}, {3, 3}};
    int (*tmp)[2] = test;
    printf(“value = %d\n”, *(tmp+0));
    printf(“value = %d\n”, **(tmp+0));
    printf(“value = %d\n”, (tmp+1));
    printf(“value = %d\n”, **(tmp+1));
    printf(“value = %d\n”, ((tmp+0)+1));
    printf(“value = %d\n”, ((int)tmp+0
    2+1));
    }

    gcc test.c -o test
    ./test

    value = 730373856
    value = 1
    value = 730373864
    value = 2
    value = 1
    value = 1

    tmp是二位数组,同时也可以作为二位指针使用。
    tmp代表的是数组的首地址
    **tmp代表数组首地址存储的值
    (tmp+1)代表第二行首地址
    **(tmp+1)代表第二行首地址存储的值,也就是上例中2
    (tmp)+1是第一行第二个元素的地址值 == (int)tmp+0
    2+1 首地址加上第一行第二个元素的偏移
    同理:
    (tmp+m)+1是第m行第二个元素的地址值 == (int*)tmp+m*2+1 首地址加上第m行第二个元素的偏移

    分享心得,仅此而已

    展开全文
  • 指针: **p 和(*p)[2]都可以指向二维数组 **p是二维指针,系统不知道+1是加多少,(*p)[2]则明确指出每+1是指2(int) //2.实参: function(p , arr) ‘p’指**p (*p)[2]中的p;arr指二维数组 //3.形参: int ...
  • 在代码的定义类型上,(*rp)[3]表示指向含3个元素的一维整形数组的指针变量,通俗的说法是指向指针的指针,也即是二维指针,为了规范,我用强制类型转换的一维指针p与二维指针rp就偏移地址的问题做一个比较。...
  • c++指针、二维指针

    千次阅读 2019-05-13 18:49:44
    一. 先分清三个概念 int *p; int a = 10; p = &...*p:p的值,取p指向的那个...p:p的地址,取p这个指针本身的地址 . 再来看一个例子 #include<iostream> using namespace std; int a= 10; int b ...
  • 二维指针数组初始化 行数为:row 列数为:column 方式一: int **dp1; dp1 = (int **)malloc(sizeof(int *) * row);//分配指针数组,计算行的大小 for(int i=0; i&lt;row; i++) { dp1[i] = (int *)malloc...
  • 指针存储二维数组的首地址 用指针存储指针数组的首地址
  • 初始化二维指针

    千次阅读 2019-07-05 17:56:40
    #include <iostream> using namespace std; int main() { double **a; a=new double *[3]; //初始一个三行列的矩阵 for (int i=0;i<3;i++) { a[i]=new do...
  • 当我们定义一个二维指针时,如果需要存储相应的数据,就需要我们动态的分配内存,这时,有一点是需要注意的,分配内存的方法不同,内存的连续性也是不相同的
  • [C语言]二维指针与一维指针

    千次阅读 2017-11-02 11:44:09
    void test1( char *pt){ pt =( char *) calloc ( 10 , 1 ); memcpy ...函数test1和test2都是尝试将传入的参数做赋值修改, 但是test1无效,而test2成功, 可见要修改传入的指针指向的内容需要二维指针!
  • 二维指针的使用

    千次阅读 2018-10-12 19:50:11
    #include #include #include int main() { ...// p = (int **)malloc(10*...//p指向一个指针 p = new int[10]; for (int i = 0; i &lt; 10; i++) { // *(p + i ) = (int )malloc(10sizeof(int)); *(p...
  • C语言中关于数组指针与指针数组,二维指针二维数组、函数指针的总结知识点敲黑板先看这里注意:如果指针没有搞清楚,请先看我的关于指针与数组的总结那篇。数组指针与指针数组二维指针与二维数组函数指针总结 知识点...
  • int arr[3][3] 的本质是指向数组的指针即 int (*p)[3],所以二维数组名可以传递给foo( int (*arr)[3]) ,或者foo(int [][3]),但是不能传递给foo(int **arr)  传给函数foo(int **arr) 可以是动态二维数组
  • 二维指针与三维指针动态分配内存

    千次阅读 2016-12-19 09:43:26
    /*给二维数组(m*n)分配空间 */ char **a = (char **) malloc(m * sizeof(char * )); for(int i = 0; i ; i++) a[i] = (char * )malloc(n * sizeof(char ));//a[i]即为*(a + i) /* 释放*/ for(int i = 0; i ; ++...
  • C++ 二维指针的内存申请和释放

    千次阅读 2019-05-23 09:52:56
    //=======以二维int型数组为例========= cin >> m >> n; // m,n分别为行数和列数 int ** p; p = new int*[m]; //以一个指针指针指向一个指针数组 for (int i = 0; i <...
  • 二维指针的malloc内存分配

    千次阅读 2016-09-14 16:20:09
    在所写的代码中,有时需要为一个二维数组分配内存,该二维数组的第一维长度不定,而 第二维是固定(类似arr[n][3]的数组)。我们可以想到的是用双指针代替数组,当然可以;也可以直接对n赋值后,直接定义arr[n][3] ...
  • 字符串双指针初始化: char **text = new char*[512]; for (int i = 0; i ; i++) { text[i] = new char[1024]; } 整型双指针初始化: int **temp; int i = 0; //初始化 temp = new int*[100]; ...
  • C 二维数组的参数传递与二维指针

    千次阅读 2018-05-26 21:11:20
    C/C++二维数组的参数传递与二维指针 &amp;amp;amp;amp;lt;div class=&amp;amp;amp;quot;article-info-box&amp;amp;amp;quot;&amp;amp;amp;amp;gt; &amp;amp;amp;amp;lt;div class=&amp;...
  • 二维指针的传递

    2011-09-14 07:25:48
    这是自己写的,测试几种二维指针和二维数组的传递方式
  • 1、二维指针 二维指针也就是指针的指针,动态分配和释放如下: void fun() { int i; X **a; //分配 a = (X **)malloc(sizeof(X *) * m); //也可以写成 a = new X*[m]; for(i = 0; i a[i] = (X *)malloc(sizeof...
  • 二维指针概念讲解,二维指针动态分配和释放练习。 作业:矩阵乘法 用户输入矩阵1行数、列数,然后提示用户输入各元素; 用户输入矩阵2行数、列数,然后提示用户输入各元素; 输入后计算相乘结果矩阵。 要求: 1 自己...
  • 作用:用来练习结构体即结构体的一维和二维指针 **/ #include "stdio.h" #include "stdlib.h" #include "string.h" typedef struct Teacher{ //老师的年龄 int age; //老师的名字 char name[64]; //老师的外号...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 125,735
精华内容 50,294
关键字:

二维指针