精华内容
下载资源
问答
  • 二级指针与二维数组

    2019-08-10 22:19:38
    二级指针与二维数组容易搞混,二级指针做函数参数
    • 二级指针:
      指向指针变量的指针

    • 二级数组
      例如对于二维数组a[3][4],应该注意的是用矩阵表示二维数组是逻辑上的概念,能形象地表示出列关系.而在内存中,各元素都是连续地存放的,地址不是的,而是线性的.
      如下图所示:
      在这里插入图片描述

    因此二维数组不同于二级指针,由定义反而可以知晓,二维数组是可以当成一维数组对待的.

    看这个面试题目:

    void func1(int **a)
    {
    	printf("a[0][0]=%d\n", a[0][0]);
    	printf("a[0][1]=%d\n", a[0][1]);
    	printf("a[1][0]=%d\n", a[1][0]);
    	printf("a[1][1]=%d\n", a[1][1]);
    }
    
    void fun2(int *a)
    {
    	printf("a[0][0]=%d\n", a[0]);
    	printf("a[0][1]=%d\n", a[1]);
    	printf("a[1][0]=%d\n", a[2]);
    	printf("a[1][1]=%d\n", a[3]);
    }
    
    
    
    
    
    
    void main_01()
    {
    	int a[2][2] = { 0, 1, 2, 3 };
    	func1(a);   // 运行会报错
    	fun2(a);    // 正确
    
    	system("pause");
    	return;
    }
    

    分析原因:

    当把二维数组名a作为实参传入func1时,参数传进去的只不过是二维数组元素的首地址;此时指针实则退化成为一级指针了,即二维数组当成了一维数组对待
    二维数组地址本身是线性的,要想当成矩阵来使用,必须知道数组的列元素个数,但是列信息并没有传入给func1
    所以此时想按照二维数组的方式输出原数组的内容是不可能的,因为列信息丢失了,但是如果按照一维数组输出是可以的.


    那么如果我仍想希望可以按照二维数组输出呢?由上述分析可知,只需要传入列元素信息的指针即可,此时需要用到指向一维数组的指针变量,这才是二维数组对应的指针形式,而不是二级指针.

    void func3(int (*a)[2])
    {
    	printf("a[0][0]=%d\n", a[0][0]);
    	printf("a[0][1]=%d\n", a[0][1]);
    	printf("a[1][0]=%d\n", a[1][0]);
    	printf("a[1][1]=%d\n", a[1][1]);
    }
    

    参考博客:
    https://blog.csdn.net/u010275850/article/details/49556399

    展开全文
  • 只有6行代码,非常简洁,这是char二级指针给char二维数组赋值的逻辑。二级指针需要先赋值操作,加断点就可以看见二维数组里的值了。
  • 在理解二级指针二维数组的关系时,我们先来回顾一下一维数组与指针的关系:一维数组是由已知数目的相同类型的元素组合而成,每个元素依次连续排列在内存某一个空间中,因此每相邻两个元素的地址相差为同一个常数。...

    以下是我对二级指针与二维数组的理解。如有误,请告知作者!感激不尽!

    在理解二级指针与二维数组的关系时,我们先来回顾一下一维数组与指针的关系:一维数组是由已知数目的相同类型的元素组合而成,每个元素依次连续排列在内存某一个空间中,因此每相邻两个元素的地址相差为同一个常数。数组名就是该数组的地址,数组取第一个元素的地址作为地址。此时我们可以用指针访问一维数组。实现过程如下:

    #include<stdio.h>
    
    int main(void)
    {
    	int a[3]={0};
    	int* p=NULL;
    	int i=0;
    	p=a;
    	printf("&a[i]:");
    	for(i=0;i<3;++i)
    		printf("%d ",&a[i]);
    	printf("\np+i:");
    	for(i=0;i<3;++i)
    		printf("%d ",p+i);
    	printf("\na[i]:");
    	for(i=0;i<3;++i)
    		printf("%d ",a[i]);
    	printf("\np[i]:");
    	for(i=0;i<3;++i)
    		printf("%d ",p[i]);
    	printf("\n*(p+i):");
    	for(i=0;i<3;++i)
    		printf("%d ",*(p+i));
    	return 0;
    }
    
    &a[i]:921511572 921511576 921511580 
    p+i:921511572 921511576 921511580 
    a[i]:0 0 0 
    p[i]:0 0 0 
    *(p+i):0 0 0 
    
    

    从上面我们可以得出一些结论:&a[i]与p+i等价,p[i]与a[i]与(*(p+i))等价。且在数值上a=&a[0], a[i]=*(p+i)

    现在我们来回顾二维数组:

    #include <stdio.h>
    
    int main(void)
    {
    	int i,j;
    	char board[3][3] = {
    						{'1','2','3'},
    						{'4','5','6'},
    						{'7','8','9'}
    						};
    
    for(i = 0 ; i < 3; ++i)
    	for(j=0;j<3;++j)
    printf(" board[%d][%d]: %c\n", i,j,*(*(board+i)+j));
    return 0;
    }
    

    运行结果:

     board[0][0]: 1      board[0][1]: 2        board[0][2]: 3
    
     board[1][0]: 4       board[1][1]: 5       board[1][2]: 6
    
     board[2][0]: 7       board[2][1]: 8       board[2][2]: 9

    此时在数值上*board=board=board[0] = &board[0][0]=&board[0]=第一个元素的地址。board[0]相当于是每一个一维数组的数组名!

    那么用malloc创建的“二维数组”是否具有这样的特性吗?

    malloc创建“二维数组”的实现过程如下:

    #include <stdio.h>
    
    #include<stdlib.h>
    
    
    int main(void)
    
    {
    
           int i,j;
    
           int row=3;
    
           int column=3;
    
           int **a;
    
           a=(int**)malloc(row*sizeof(int*));
    
           for(i=0;i<row;++i)
    
           a[i]=(int*)malloc(column*sizeof(int));
    
           for(i=0;i<row;++i)
    
                  for(j=0;j<column;++j)
    
                         scanf("%d",&a[i][j]);
    
           for(i=0;i<row;++i)
    
                  for(j=0;j<column;++j)
    
                         printf("%d ",a[i][j]);
    
          
    
           return 0;
    
    }

    也许此时会有疑问:二维数组为什么不能当作二级指针?上面这幅图貌似可以说明二维数组是二级指针?

    其实上面这幅图正好能说明二维数组不是二级指针。我们知道数组中的每个元素依次连续排列在内存某一个空间中,因此相邻两个元素的地址值相差为同一个常数,因此我们可以看一下上面这幅图中相邻两个元素地址相差值:

    36667440 36667444 36667448
    
    36667472 36667476 36667480
    
    36667504 36667508 36667512

    而二维数组每个元素地址相差值:

    886410672 886410676 886410680
    
    886410684 886410688 886410692
    
    886410696 886410700 886410704

    我们再看一下是否满足a=&a[0]=a[0]=&a[0][0]:

    #include <stdio.h>
    #include<stdlib.h>
    
    int main(void)
    
    {
    
           int i,j;
           int row=3;
           int column=3;
           int **a;
    	
           a=(int**)malloc(row*sizeof(int*));
           for(i=0;i<row;++i)
           a[i]=(int*)malloc(column*sizeof(int));
    	   printf("a=%d,&a[0]=%d,a[0]=%d,&a[0][0]=%d",a,&a[0],a[0],&a[0][0]);
    
           return 0;
    
    }

    运行结果如下:

    a=8261160, &a[0]=8261160,a[0]=8261216,&a[0][0]=8261216

    从上面可再次看出二维数组不是二级指针!

    通过malloc创建的“二维数组”其实是指针数组,指针能代表内存中一块连续空间,因此要使用两次malloc。第一次用malloc分配一块空间,里面存放指针,因此返回的指针类型应该是二级指针,这样就可以使用二级指针a指向每一个一级指针a[i](也可以写成*(a+i)),每个一级指针a[i]又分别指向内存中一块连续空间的首地址,所以在使用一次malloc。这样所谓的动态"二维数组"就创建完成。此时a[i][j]相当于是 *(*(p+i)+j) 注意这里与二维数组的去引用意思是不同的!

    因为数组中的元素依次排列在内存的一块空间里,且数值上*board=board=board[0] = &board[0][0]=&board[0]=第一个元素的地址所以我们也可以这样访问二维数组里的每一个元素:

    #include <stdio.h>
    
    int main(void)
    {
    	int i,j;
    	char board[3][3] = {
    						{'1','2','3'},
    						{'4','5','6'},
    						{'7','8','9'}
    						};
    
    for(i = 0 ; i < 9; ++i)
    printf(" board: %c\n",*(*board+i)); //board一定要加星号!*board相当于是*(board+0)=board[0]
    return 0;
    }

    运行结果:

     board[0][0]: 1      board[0][1]: 2        board[0][2]: 3
    
     board[1][0]: 4       board[1][1]: 5       board[1][2]: 6
    
     board[2][0]: 7       board[2][1]: 8       board[2][2]: 9

     

     

     

    展开全文
  • c语言二级指针与二维数组

    千次阅读 2019-05-20 15:00:56
    一、二维数组的地址不能赋给二级指针的原因 int arr[][3] = { { 1,2,3 },{ 4,5,6 },{ 7,8,9 } }; int** p = arr; 二、指针遍历二维数组 int* p1 = arr; for (int i = 0; i < sizeof(arr)/sizeof(arr[0][0]); ...

    一、二维数组的地址不能赋给二级指针的原因

    int arr[][3] = { { 1,2,3 },{ 4,5,6 },{ 7,8,9 } };
    int** p = arr;
    

    在这里插入图片描述
    二、指针遍历二维数组

    int* p1 = arr;
    
    	for (int  i = 0; i < sizeof(arr)/sizeof(arr[0][0]); i++)
    	{
    		printf("%d ",*p1++);
    	}
    

    结果:
    在这里插入图片描述

    展开全文
  • 指针:C语言二级指针与二维数组

    千次阅读 2019-04-09 21:25:59
      最近用C语言写LeetCode 有的题目给的函数把二维数组二级指针传进来 并传入行数和列数 引起一些疑惑 本来以为C语言学得海星,查了一些资料后,觉得自己还是个弟弟 : ( 按一维数组的思路处理二维数组,将二维...

    前言

      最近用C语言写LeetCode 有的题目给的函数把二维数组用二级指针传进来 并传入行数和列数 引起一些疑惑

    本来以为C语言学得海星,查了一些资料后,觉得自己还是个弟弟 : (


    按一维数组的思路处理二维数组,将二维数组名作为二级指针传入
    在这里插入图片描述

    出现异常(图示运行在DEVC++中)

    在这里插入图片描述

    二维数组名+1相当于在行上+1
    然而传入的二级指针

    在这里插入图片描述

    按二维指针指针传入的num失去了二维数组的性质,相当于仅进行了数组首地址的传递,和一个普通的int *指针没有区别

    在这里插入图片描述
    仅进行了地址值的传递,甚至可凭借数组的连续性按一维数组的方式来访问元素



    那怎么传递二维数组呢?

    如果行列数已知,可以用如下方法
    在这里插入图片描述
    这里列下标是必填的,因为只有确定了列下标,程序才知道计算num[i]这种地址时该以多少个元素作为一行,由num+1的结果也可以看出num已经是正常的二维数组名了

    也可以用int (*num)[3],效果与int num[ ][3]等价
    int (*num)[3] 说明num是一个指向有三个int元素数组的指针,所以步长也为3 × sizeof(int),同用一维数组访问的方式类似



    那如何以指针形式进行访问呢?
    除了上面以一维数组的方式进行访问外,还可以将二维数组还原回来

    void test(int **num, int row, int col) {
    	int **p = (int **)malloc(sizeof(int *)*row);
    	或者int *p[2];//int *p[row];
    	for(int i = 0;i<row;i++){
    		p[i] = num+i*col;
    	}
    	printf("num[1][1] = %d\n", p[1][1]);//输出为4
    	free(p);
    }
    
    int main() {
    	int num[2][3]= {{0,1,2},{3,4,5}};
    	test(num,2,3);
    	return 0;
    }
    


    2019/04/09

    会再更新指针的博客的

    展开全文
  • 比上一个版本添加二级指针size获取函数,有需要的朋友可以看一下
  • 先总结一下:对于上面定义的的二维数组,他们与指针有着这样的关系 等价于 解释 a int型二维数组 代表变量a的起始地址 a+i &a[i] 代表第i行起始地址 *(a+i) a[i] 第i行首元素的...
  • 它实际上是一个数组,只不过数组的每个元素存放的都是一个指针类型的元素,所以可以通过取两次地址来得到存放的内容,所以可以说指针数组二级指针是有联系的,因为二级指针就是用来存放地址的。 定义int *p[3]; #...
  • 解析二级指针与二维数组之间的关系 今日在论坛上看到有人问到指针的问题,我想通过这样的例子来阐述几个常见的错误,并加深对二级指针二维数组之间关系的理解.我们知道char array[]=”abcdef”; array是数组的首...
  • C语言的二级指针与二维数组

    千次阅读 2014-09-11 15:41:54
    指针是C语言的一大特色,它就像一把双刃剑:使用得当能够给程序带来极大的灵活性和高效性;反之,程序就会变得难以调试,漏洞百出!...我们都知道,数组名和函数名就是它们的入口地址。同理,一个变量名其
  • 指针是C语言的一大特色,它就像一把双刃剑:使用得当能够给程序带来极大的灵活性和高效性;反之,程序就会变得难以调试,漏洞百出!...我们都知道,数组名和函数名就是它们的入口地址。同理,一个变量名其实也是此
  • 2】二维数组与指针 3】指针数组 4】数组指针 5】二级指针 1】一维数组与指针: #include <stdio.h> #include <stdlib.h> #include <string.h> int main(void) { //一维数组与...
  • 二级指针与二维数组使用误区

    千次阅读 2010-02-21 11:14:00
    当了好长时间的程序员,以为对指针已经有较好的认识,没想到照样出错。以下是我写错的代码,你能看出什么问题吗?应该怎么写才对呢? #include void func(int count, char **coln, char **colv){ int i; for( i=0; ...
  • 对于二维数组 二级指针以及数组指针的讨论。对于二维数组 二级指针以及数组指针的讨论
  • 今日在论坛上看到有人问到指针的问题,我想通过这样的例子来阐述几个常见的错误,并加深对二级指针二维数组之间关系的理解.我们知道char array[]=”abcdef”; array是数组的首地址,那么在二维数组中array当然也是...
  • 文章目录指针数组,数组指针,二维数组二级指针答案答案的论证必备知识存储结构:不同操作的输出结果: 指针数组,数组指针,二维数组二级指针 答案 无需纠结C语言是如何定义的,因为这样太花时间了。当然有时间...
  • 二维数组名指向一个一维数组 √ 二维数组的数组名是二级指针 × 二维数组的数组名是数组指针 √
  • 1、指针数组与数组指针 详细:http://c.biancheng.net/view/335.html 1.1指针数组 int *p1[5]; 指针数组 首先,因为"[ ]" 的优先级要比" * "的优先级要高,所以所以p1[5]首先是一个数组,然后其元素类型为整型指针...
  • 二级指针作为函数形参时,能作为函数实参的是二级指针,指针数组,一级指针的地址 b.当数组指针作为函数形参时,能作为函数实参的是二维数组,数组指针 c.当二维数组作为函数形参时,能作为函数实参的是二维数组...
  • 一个函数形如:void f(float **p){/* 想要在函数体中按二维数组的方式访问*/ p[1][1] = 0;//c++用vc编译ok,运行出错(非法访问),我记得C语言中是可以的,不知道为什么, 怎么才能实现我这种访问方式,谢谢...
  • 指针数组:array of pointers,即用于存储指针数组,也就是数组元素都是指针 数组指针:a pointer to an array,即指向数组指针 int* a[4] 指针数组  表示:数组a中的元素都为int型指针([]优先级高于*)  ...
  • 数组指针,指向一个一维数组的指针,又称行指针,被二维数组赋值后可当作二维数组操作。 例: int a[2][3]; a[1][2]=5; int (*b)[3]=a; cout<<a[1][2]; cout<<(*(b+1))[2]; cout<<b[1][2]; ...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 32,521
精华内容 13,008
关键字:

二级指针与二维数组