数组指针、指针数组以及二位数组的深入解析

int *p[3]与int (*p)[3]的区别
*p[3]这个是一个指针数组,它所代表的意思是数组中的每一个元素都是一个指针变量,而(*p)[3],p是一个指针变量,表示指向一个含有3个整型元素的一维数组。


代码如下:

int i,j;
    int a[2][3]={3,4,5,6,7,8}; //
    int *p[3] ;  //表示一个数组,数组中的元素是指针类型,一共有三个元素
    int (*q)[3]; //是一个指针,指向一个含有三个int型的数组(q+1)会跳三个数组元素

//把第一行三个元素地址存放在p指针数组中
    for( i=0;i<3;++i)
        p[i]=&a[0][i];

//输出指针数组中地址所对应值
    for( j=0;j<3;++j)
        cout<< *p[j]<<" ";//输出结果为:3,4,5
    cout<<endl;

q=a;//把数组a开始地址赋给指向一维数组q;
    for(i=0;i<2;i++)
        for(j=0;j<3;j++)
            cout<< *(*(q+i)+j)<<" "; //输出数组中元素

system("pause");

参考《c++ primer》
严格的将,c++中没有多维数组,通常所指的多维数组其实就是数组的数组,比如int arry[3][4];表示一个长度为3的数组,数组中的每个元素是一个长度为4的数组。在使用多维数组时,记住这一点有利于理解其应用。

下面来讲讲多维数组与指针的关系。与普通数组一样,使用多维数组时,实际上将其自动转换为指向该数组第一个元素的指针。也就是说,数组的名字是一个指向该数组中第一个元素的指针,在一维数组中,arry==&arry[0],这两个地址是一样的。在二维数组中,数组名称指向第一个元素,第一个元素是一个长度为4的数组。我们定义一个指向长度为4的数组的指针 int (*p)[4],然后可以将二维数组的首地址赋值给它,p=arry。这样是可以进行赋值的。这里同样满足arry==&arry[0]。

知道了二维数组名字与指针的关系,那么我们在进行二维数组传参的时候就会好理解很多,以前二维数组传参是一直让人头疼的问题。这里我们还是将二维数组名字作为实参来传递,在接受函数的形参中,我们只需要定义一个指向具体长度为数组的指针即可,比如我们这里使用 int (*p)[4]来接受arry这样的参数。下面给出代码实例。


代码如下:

#include<iostream>
#include<stdlib.h>
using namespace std;

//数组名字是一个指向数组首元素的指针,这里我们定义一个指向数组的指针来接受arry
//r表示二位数组的行数,c表示二维数组的列数。
void PrintArry(int (*arry)[4],int r,int c)
{
    for(int i=0;i<r;i++)
    {
        for(int j=0;j<c;j++)
        {
            cout<<arry[i][j]<<" ";
        }
        cout<<endl;
    }
}

void main()
{
    int arry[3][4]={{1,2,8,9},{2,4,9,12},{4,7,10,13}};
    PrintArry(arry,3,4);//等价于PrintArry(&arry[0],3,4);
    system("pause");
}

上述一个简单的打印二维数组的简单例子,重点是二维数组的传参。

更优化的方法
在上述示例中,形参必须指明这个arry指针是指向一个长度为多少的数组,如int (*arry)[4]必须指明为4,有一定的局限性,那么有没有更好的方法呢。答案是有的。考虑到二维数组在内存中占据连续的空间这一个特性,我们可以用以为数组来表达二位数组。将上述PrintArry方法进行改写,改写结果如下:


代码如下:

#include<iostream>
#include<stdlib.h>
using namespace std;

//传入数组的指针,二维数组的行数与列数
void PrintArry2(int *arry,int r,int c)
{
    for(int i=0;i<r*c;i++)
    {
        cout<<arry[i]<<" ";
    }
    cout<<endl;
}

void main()
{
    int arry[4][4]={{1,2,8,9},{2,4,9,12},{4,7,10,13},{6,8,11,15}};
    PrintArry2(&arry[0][0],4,4);//传入数组中的第一个数组中的第一个元素的地址

system("pause");
}

(0)

相关推荐

  • C++中一维数组与指针的关系详细总结

    对于数组int a[10];a表示数组的第一个元素的地址,即&a[0]; 如果使指针p,指向数组的首元素,可以进行操作:int * p=a;或者int *p=&a[0]; 那么p++,是指向数组中的先一个元素,即a[1];此时*p则是a[1]中所放的值.此时,a[i]=p[i]=*(a+i)=*(p+i) 下面举一个例子:直接用a[i]来输出 复制代码 代码如下: #include<iostream>using namespace std;int main(){ int a[1

  • 指针操作数组的两种方法(总结)

    指针操作数组,方法一是p+index,方法二是p[index],第二种方法跟数组访问方法是一样的. 数组引用返回的是数组的第一个元素的指针地址. 可以将指针指向数组的任意元素,然后从那里开始访问,只要注意不越界就行了,这说明数组只是将元素连续堆叠,并不需要也没有其他的配置信息存放在数组元素之外的地方或者在头尾等等任何地方,都没有,他只是连续的存储而已. #include <iostream> using namespace std; int main() { const int ARRAY_L

  • C语言 指针数组详解及示例代码

    如果一个数组中的所有元素保存的都是指针,那么我们就称它为指针数组.指针数组的定义形式一般为: dataType *arrayName[length]; [ ]的优先级高于*,该定义形式应该理解为: dataType *(arrayName[length]); 括号里面说明arrayName是一个数组,包含了length个元素,括号外面说明每个元素的类型为dataType *. 除了每个元素的数据类型不同,指针数组和普通数组在其他方面都是一样的,下面是一个简单的例子: #include <stdi

  • 深入理解双指针的两种用法

    好久没有用过C/C++的二级指针了,总觉的它就是指针的指针,没什么大不了的,但是今天看到一道面试题,感觉自己对二级指针的理解还是不够深刻.于是,从网上找资料,学习了一番--题目是这样的: 复制代码 代码如下: #include "stdafx.h"#include <iostream>using namespace std;void GetMemory(char *p, int num){ p = (char *)malloc(sizeof(char) * num); //

  • C语言 数组指针详解及示例代码

    数组(Array)是一系列具有相同类型的数据的集合,每一份数据叫做一个数组元素(Element).数组中的所有元素在内存中是连续排列的,整个数组占用的是一块内存.以int arr[] = { 99, 15, 100, 888, 252 };为例,该数组在内存中的分布如下图所示: 定义数组时,要给出数组名和数组长度,数组名可以认为是一个指针,它指向数组的第 0 个元素.在C语言中,我们将第 0 个元素的地址称为数组的首地址.以上面的数组为例,下图是 arr 的指向: 下面的例子演示了如何以指针的方

  • C语言 指针与数组的详解及区别

    C语言 指针与数组的详解及对比 通俗理解数组指针和指针数组 数组指针: eg:int( *arr)[10]; 数组指针通俗理解就是这个数组作为指针,指向某一个变量. 指针数组: eg:int*arr[10]; 指针数组简言之就是存放指针的数组: --数组并非指针&&指针并非数组 (1)定义一个外部变量: eg:int value=10; int *p=&value; 举例:当需要在一个函数中用这个变量时:externa int*p;而非extern int p[]; 分析:当用:e

  • 详解C语言中的函数、数组与指针

    1.函数:当程序很小的时候,我们可以使用一个main函数就能搞定,但当程序变大的时候,就超出了人的大脑承受范围,逻辑不清了,这时候就需要把一个大程序分成许多小的模块来组织,于是就出现了函数概念:   函数是C语言代码的基本组成部分,它是一个小的模块,整个程序由很多个功能独立的模块(函数)组成.这就是程序设计的基本分化方法: (1) 写一个函数的关键: 函数定义:函数的定义是这个函数的实现,函数定义中包含了函数体,函数体中的代码段决定了这个函数的功能: 函数声明:函数声明也称函数原型声明,函数的原

  • C++指针数组、数组指针、数组名及二维数组技巧汇总

    本文较为详细的分析了关于理解C++指针数组,数组指针,数组名,二维数组的一些技巧.是比较重要的概念,相信对于大家的C++程序设计有一定的帮助作用. 一.关于数组名 假设有数组: int a[3] = {1, 2, 3} 1.数组名代表数组第一个元素的地址,注意,不是数组地址(虽然值相等),是数组第一个元素地址,a 等同于 &a[0]; a+1是第二个元素的地址.比第一个元素地址a(或者&a[0])超出了一个整型指针的大小,在这里是4个字节(byte) cout << a <

  • 详解C++中的指针、数组指针与函数指针

    C++中一个重要的特性就是指针,指针不仅具有获得地址的能力,还具有操作地址的能力.指针可以用于数组.或作为函数的参数,用来访问内存和对内存的操作,指针的使用使得C++很高效,但是指针也非常危险,使用不当会带来比较严重的问题. 1.指针 程序中所有的变量和常量都存在一个内存地址中,当然,函数也有对应的内存地址,内存地址的不同会导致程序执行时有所不同. 指针就是用来控制和存储内存地址的变量,它指向单个对象的地址,除了void之外,指针的数据类型与所指向地址的变量数据类型保持一致. 2.如何定义指针.

  • 数组指针、指针数组以及二位数组的深入解析

    int *p[3]与int (*p)[3]的区别*p[3]这个是一个指针数组,它所代表的意思是数组中的每一个元素都是一个指针变量,而(*p)[3],p是一个指针变量,表示指向一个含有3个整型元素的一维数组. 复制代码 代码如下: int i,j;    int a[2][3]={3,4,5,6,7,8}; //    int *p[3] ;  //表示一个数组,数组中的元素是指针类型,一共有三个元素    int (*q)[3]; //是一个指针,指向一个含有三个int型的数组(q+1)会跳三个

  • js中一维数组和二位数组中的几个问题示例说明

    js中的数组,可以存放各种数据类型(数值,字串) js中的数组没有越界,当输出的数组下标越界了,会显示undefined. js中的数组是默认动态增长的 遍历数组的一种简单方式. for(var key in arr){ window.alert(key+"= "+arr[key]); } 在给一个空的二维数组赋值的时候出现的问题: var arr2=[]; arr2[1][1]=45;//js不支持这种赋值方法 解决方法: //在这之前需要初始化定义arr2有多少行. for(var

  • 直观理解C语言中指向一位数组与二维数组的指针

    一维数组和指针: 对于一位数组和指针是很好理解的: 一维数组名: 对于这样的一维数组:int a[5];  a作为数组名就是我们数组的首地址, a是一个地址常量 . 首先说说常量和变量的关系, 对于变量来说, 用箱子去比喻再好不过了, 声明一个变量就声明一个箱子,比如我们开辟出一个苹果类型的箱子, 给这个变量赋值就是把盛放苹果的箱子中放入一个实实在在的苹果, 这就是变量的赋值.  而对于数组来说, 就是一组类型相同的箱子中,一组苹果箱子, 可以放入不同的苹果. 一维数组空间: 变量被声明后, 我

  • C语言 指针与二维数组详解

    二维数组在概念上是二维的,有行和列,但在内存中所有的数组元素都是连续排列的,它们之间没有"缝隙".以下面的二维数组 a 为例: int a[3][4] = { {0, 1, 2, 3}, {4, 5, 6, 7}, {8, 9, 10, 11} }; 从概念上理解,a 的分布像一个矩阵: 0   1   2   3 4   5   6   7 8   9  10  11 但在内存中,a 的分布是一维线性的,整个数组占用一块连续的内存: C语言中的二维数组是按行排列的,也就是先存放 a[

  • 举例理解C语言二维数组的指针指向问题

    之前对数组的概念一直没有理解透彻,只觉得数组名就是个常量指针而已,用法和基本的指针差不多.所以当我尝试用二级指针去访问二维数组时,就经常会出错.下面就是刚开始写的一个错误的程序: #include <stdio.h> int main() { int iArray[2][3] = {{1,2,3},{4,5,6}}; int **pArray = NULL; pArray = iArray; printf("array[0][0] = %d\n", pArray[0][0]

  • 详解C++ 指针与二维数组名

    和一维数组类似,C++ 将二维数组名解释为其第一个元素的地址,而二维数组的第一个元素为一维数组,下面详细总结下二维数组名的性质. 和一维数组类似,C++ 将二维数组名解释为其第一个元素的地址,而二维数组的第一个元素为一维数组,以下面的程序为例,二维数组名 array2d 和 &array2d[0] 等效,它们的类型都为 short (*)[5]:对数组名应用地址运算符时,得到的是整个数组的地址,它的类型为 short (*)[5][5],假设 short 宽 2 字节,系统为 32 位,数组首地

  • C语言二维数组指针的概念及使用

    目录 二维数组 指针数组和二维数组指针的区别 二维数组 二维数组在概念上是二维的,有行和列,但在内存中所有的数组元素都是连续排列的,它们之间没有“缝隙”.以下面的二维数组 a 为例: int a[3][4] = { {0, 1, 2, 3}, {4, 5, 6, 7}, {8, 9, 10, 11} }; 从概念上理解,a 的分布像一个矩阵: 0 1 2 34 5 6 78 9 10 11 但在内存中,a 的分布是一维线性的,整个数组占用一块连续的内存: C语言中的二维数组是按行排列的,也就是先

  • C++数组指针和二维数组详情

    目录 1.二维数组 2.数组指针和二维数组 1.二维数组 对于一维数组,int arr[10]; arr是数组名,也是首元素的地址,&arr是数组的地址,那么对于二维数组 int arr[3][3], arr可以肯定是数组名,那么他是不是首元素的地址呢?如果是首元素的地址,那么arr[0]又该是什么呢?通过以下代码进行验证: #include <stdio.h> #define ROW 3 #define COLUMN 3 int main() { int arr[ROW][COLUM

  • C++中用指向数组的指针作函数参数

    1.一维数组名作为函数参数传递一位数组名,就相当于该数组的首个元素的地址: 复制代码 代码如下: int a[10];int *p;p=a;//p=a与p=&a[0]是等价的 实例代码: 复制代码 代码如下: #include<iostream>using namespace std;int main(){ int a[10]={1,2,3,4,5,6,7,8,9,10}; void Print(int *p ,int n); Print(a,10); cout<<endl

  • C++ 二维数组参数传递的实现方法

    C++ 二维数组参数传递的实现方法 int a[2][2]={ {4, 6}, {9, 11} }; 我定义了这样一个数组,我想把这个数组作为参数,传递到一个函数中,并要在函数中能引用该二维数组的元素,我该怎么做? 第一种方式是直接传递二维数组,但是必须标明第二维的值,因为如果只是传递a[][],编译器无法分配这样的数组,所以要这样传int a[][3] 第二种方法是传递指针数组方式,即int (*a)[3] 第三种是传递指针方法. 具体实施见代码: 方法1:传递数组,注意第二维必须标明 //二

随机推荐