C++数组,指针,引用以及三者的复合类型

C++数组,指针,引用以及三者的复合类型

这里省去了对这三者的单独介绍,仅仅介绍使用这三者组成的组合类型。

一、两两组合

这三者的两两组合有9种:


数组


指针


引用


数组


数组的数组


数组的指针


数组的引用


指针


指针的数组


指针的指针


指针的引用


引用


引用的数组


引用的指针


引用的引用

1、指针的指针、数组的数组、数组的指针、指针的数组

指针的指针(二维指针),数组的数组(二维数组),数组的指针和指针的数组这里就不介绍了,很多博客文章书籍都有详细的介绍。它们的形式是:

指针的指针: int** a = NULL;

数组的数组: int a[2][3] = {0};

数组的指针:int (*a)[10];//a指向有10个元素的int型数组

指针的数组:int *a[10];//a是一个数组,有10个元素,元素的类型是(int *)

下面才是讨论的主题,C++中引入“引用”类型的时候,事情有点复杂了。我在尝试使用一个指针数组的时候,发现以后会以引用的方式将该数组传入函数,第一次发现自己完全不会定义这三者的组合类型,找了一些资料,将这三者的复合类型总结成这篇文章。

2、数组的引用,引用的数组

引用与数组,引用与指针进行组合的时候,网上还是有一些介绍的,它们的形式是:

数组的引用:

int a[3] = {1,2,3};

int (&b)[3]=a;

和数组的指针是不是很相似??所以引用的数组是不是也应该是以下这样的?

int h = 4;

int &c = h;

int &d = a[1];

int &e = a[1];

int &f[3] = {c,d,e};//error

但这是错误的,C++无法定义引用的数组,编译器不会通过。经典的解释(《C++ Primer》)是:引用不是对象。我自己的想法是:引用传递的不仅仅是值,还有变量的地址信息,多个引用指向的变量内存上不一定是连续的(如上例中的h和a[1]),不一定是不同的地址(如上例中的引用d和e指向同一个变量);但是数组的元素地址必须是连续的。

太好了,下面就不会有由“引用的数组”组成的麻烦的复合类型了!!

3、指针的引用,引用的指针

指针的引用和引用的指针,对这两者的介绍也不少,

指针的引用:

int a = 0;

int * p = &a;

int* &b = p;

引用的指针:和引用的数组一样,没有这种东西,依然采用经典的解释:引用不是对象。

这样我们又去掉了一种组合,以后也不会有由“引用的指针”组成的复合类型了。

4、引用的引用

引用的引用,你当然可以这么做:

int a = 0;

int  &b = a;

int &c = b;

但是不能定义这样的引用:

int  a = 0;

int &&b = a;//error

int &(&b) = a;//error

(指针也不能这么干:int ** p = &&a;//error,不解释)

总之,忘了以上两种错误的方式:

第一种,g++给出的编译信息如下:

error: expected unqualified-id before ‘&&’ token

int &&p = a;

第二种,g++给出的编译信息如下:

error: cannot declare reference to ‘int&’, which is not a typedef or a template type argument

int &(&p) = a;

好了,这样我们进行三者组合的时候就可以去掉了9种中的3种。

我们先列出可以使用的两者组合:


数组


指针


引用


数组


数组的数组


数组的指针


数组的引用


指针


指针的数组


指针的指针


指针的引用


引用

二、三者的组合情况

1、指针的指针的指针、数组的数组的数组


数组


指针


引用


数组的数组


数组的数组的数组


数组的数组的指针


数组的数组的引用


数组的指针


数组的指针的数组


数组的指针的指针


数组的指针的引用


数组的引用


数组的引用的数组


数组的引用的指针


数组的引用的引用


指针的数组


指针的数组的数组


指针的数组的指针


指针的数组的引用


指针的指针


指针的指针的数组


指针的指针的指针


指针的指针的引用


指针的引用


指针的引用的数组


指针的引用的指针


指针的引用的引用

1、不存在的类型

数组的引用的数组,数组的引用的指针,数组的引用的引用,指针的引用的数组,指针的引用的指针,指针的引用的引用这些复合类型不存在,参考两两组合。

2、指针的指针的指针、数组的数组的数组

指针的指针的指针,数组的数组的数组:三维指针和数组,它们的形式分别为:

int *** p = NULL;

int a[2][4][3] = {0};

3、指针的指针的数组

指针的指针的数组:参考指针的数组,毕竟指针的指针也是指针,它的形式如下:

int ** a[2];//a是一个有两个元素的数组,元素的类型是int**

4、指针的指针的引用

指针的指针的引用:参考指针的引用,它的形式如下:

int **&b = a[0];

5、数组的数组的指针

数组的数组的指针:参考数组的指针,毕竟数组的数组也是数组,它的形式如下:

int (*p)[2][3] = NULL;// p是一个指针,指向一个2行3列元素为int型的数组。

6、数组的数组的引用

数组的数组的引用:参考数组的引用,和数组的数组的指针类似,形式如下:

int a[2][3] = {0};

int (&r)[2][3] = a;

7、数组的指针的数组

我读的程序不多,没见过有这么用的程序,我自然也没这么用过,不过依然不妨碍我们给出此类对象的定义:

指针的数组是这么定义的:

int *b[2] = {NULL,NULL};

其实写成这样也没问题:

int *(b)[2] = {NULL,NULL};

这个指针的数组中存放的指针指向int型,现在要改成指向int数组型,比如 int [2],只要将b替换成一个int数组就可以了:

int *(b[2])[2] = {NULL,NULL};

好了,数组的指针的数组类型定义好了,这是一个存放两个指针的数组,这种指针指向有两个int型元素的数组。

我想以后如果你想定义“数组的指针的数组的指针的数组”的时候,也可以这样一步步代入来完成这种复合类型。

int *(*(a[2])[2])[2] = {NULL,NULL};

如果选择从数组的指针开始推导会挺困难的。我是没有推出来。

8、数组的指针的指针

数组的指针类型是这么定义的: int (*a)[2] = NULL;

也可以这么写:int (*(a))[2] = NULL;

所以如果想对a再次取地址,那么使用*a替换a,所以数组的指针的指针对象的定义是这样子的:

int (*(*a))[2] = NULL;

对比上一个数组的指针的数组,你可能会有如下的疑问:

指针的指针是这样的:int ** a = NULL;

根据数组的指针的数组的推导经验,数组的指针的指针应该这样得出:

int ** (a) = NULL;

int ** (a[2]) =NULL; //error

遗憾的是,编译不通过。我暂时不知道什么原因。

比较以上两种复合类型的推导,我们似乎没发现有什么很固定的规律。一切都是经验之谈。再等等,后面应该会看到规律。

9、指针的数组的数组

这个比较容易,因为指针的数组是这样的:int *a[2] = {NULL,NULL};

所以可以很容易就写出来:

int *a[2][2] = {0};

10、指针的数组的指针

指针的数组:int *a[2] = {0};

也即:int *(a)[2] = {0};

所以,指针的数组的指针:int *(*a)[2] = NULL;

规律我也不知道该怎么总结,不过我把我的经验写成一个例子应该比较好理解。

综合以上几种复合类型,我们就可以在c或者c++中组合出非常丧心病狂的复合类型,比如:数组的指针的指针的数组的数组的指针的数组的指针的指针

我的方法是这样的:

从右面数,找到第一个“数组”:

数组的指针的指针的数组的数组的指针的数组的指针的指针

什么样的数组?指针的数组

数组的指针的指针的数组的数组的指针的数组的指针的指针

所以先定义的一个指针的数组

int *(a)[2] = {0};

那么a是一个什么样的指针呢?数组的指针?还是数组的数组的指针?我们把所有的修饰型“数组”全部取完,所以是数组的数组的指针:

数组的指针的指针的数组的数组的指针的数组的指针的指针

int *(a[2][2])[2] = {0};

那么a这个数组的数组中存放的是什么呢?指针?指针的指针?我们把所有的修饰型“指针”全部取完,所以存放的是指针的指针:

数组的指针的指针的数组的数组的指针的数组的指针的指针

int *(**a[2][2])[2] = {0};

那么现在a是一个什么样的指针呢?数组的指针:

数组的指针的指针的数组的数组的指针的数组的指针的指针

int *(**(a[2])[2][2])[2] = {0};

好了,前半部分推完,还有后面一部分:

现在我们知道a是一个数组,我们还要取它的指针的指针呢:

数组的指针的指针的数组的数组的指针的数组的指针的指针

int *(**((**a)[2])[2][2])[2] = NULL;

完成!!!!

好吧我没测试这个写到底对不对。

这个已经够复杂了,但这还没在里面加入函数指针呢……

好了,下面终于到引用了

11、数组的指针的引用

很显然,先写出数组的指针,于是

int (*p)[2] = NULL;

该指针的引用,参考指针的引用,于是

int (*&r)[2] = p;

12、指针的数组的引用

很显然,先写出指针的数组,于是

int *p[2] = {0};

参考数组的引用,于是

int *(&r)[2] = p;//这个括号不能省

总结一下可用的三者组合的复合类型,共12种:


数组


指针


引用


数组的数组


数组的数组的数组


数组的数组的指针


数组的数组的引用


数组的指针


数组的指针的数组


数组的指针的指针


数组的指针的引用


数组的引用


指针的数组


指针的数组的数组


指针的数组的指针


指针的数组的引用


指针的指针


指针的指针的数组


指针的指针的指针


指针的指针的引用


指针的引用

时间: 2024-10-09 14:05:20

C++数组,指针,引用以及三者的复合类型的相关文章

c/c++ 函数指针 指针函数 数组的引用 指针数组 数组指针

1.指针数组数组指针 引用数组 数组的引用 int *a[10] 指针数组 每一个元素都是一个指针 Int (*a)[10] 数组指针 P指向一个含有10个元素的数组 Int (&a)[10] 数组的引用 a是一个数组的引用 Int& a[10] 引用函数 非法 数组的引用:1.在程序体中 int a[10]; Int (&p)[10]=a;//引用数组 2.作为参数 #include <iostream> #include <string> using n

C++ 指针 引用

1.指针和引用为C++的复合类型 2.*.&在声明时称为指针.引用,在表达式中称为解引用符.取地址符,是操作符,不能混淆含义. 引用 1.引用必须初始化,要与声明类型匹配,且必须是对象(不能是字面值或表达式) 2.引用本身不是一个对象,所以不能定义引用的引用 指针 1.不能定义指向引用的指针,因为引用不是对象,没有实际地址 ...未完待续

二维数组指针及二维动态数组的分配问题

在我以前的文章中都有讲过关于数组指针及指针数组的相关问题,但是讲得不够深入,我后来后了别人写的博客后觉得人家的确实写得好, 也学到了不少东西,对以前的问题有深的领悟了,于是准备结合这些博客和文章再稍微深入一点讲讲这些问题.这些指针的问题是C语言中的基础与关键 而且一旦出现这些问题,不太好找bug的来源,有时候不得不借助反汇编. 参考文章: http://c.biancheng.net/cpp/html/476.html       C语言指针数组和数组指针 http://blog.csdn.ne

指针数组、数组指针、函数指针、指针函数总结

指针数组 && 数组指针 char *a[5]; //定义一个指针数组, 数组的元素都是char *指针类型.初始化也可以在里面存放字符或字符串.a的类型是char *[5] //若char *a[5]={"red","white","blue","dark","green"}; //a在这里的类型是char *[],实质上是一个二级指针.也就是说a所代表的那块内存里面存放着的是数组中第一个

指针数组、数组指针、函数指针、指针函数总结C++

指针数组.数组指针.函数指针.指针函数总结 2014-11-11 指针数组 && 数组指针 ? 1 2 3 4 5 6 7 8 9 10 11 12 13 14 char *a[5];      //定义一个指针数组, 数组的元素都是char *指针类型.初始化也可以在里面存放字符或字符串.a的类型是char *[5] //若char *a[5]={"red","white","blue","dark",&qu

数组,引用,指针那些事

数组.指针.引用三者夹杂不清,写法很容易让人记忆混淆,现在做如下总结: 数组的引用和引用的数组 C++中由于数组不允许拷贝和赋值,当我们函数形参设为数组时,编译器会自动将数组形参转换为数组首元素的指针,也就是说: void fun(int data[10]) 其实会被转换为: void fun( int* ptr) 其中,这个ptr指针指向数组首元素,也就是: ptr=data 综上,其实以下几种数组形参的写法其实是没有区别的: void fun(const int a[10]); void f

《C++ Primer》学习 之 返回数组的引用(返回数组的指针,方法与之相同)

/* 返回数组的引用(返回数组的指针,方法与之相同) 共四种方法(在下面示例程序中,调用其中一种方法时,需要将其他三种方法注释掉)*/ 1 #define _CRT_SECURE_NO_WARNINGS 2 #define HOME 3 #include <iostream> 4 #include <stdexcept> 5 #include <ctype.h> 6 #include <locale> 7 #include <iterator>

[C++]数组指针,数组引用,函数指针

数组指针是指一个指向数组的指针,例如有一个数组指针p指向一个数组a[],则 *p是取到这个数组,也就是说 *p=a,因此 **p =a[0], 它的定义为: int a[10]; int (*c)[10]=&a; (*c)表示它是一个指针,若不加括号则变成 指针数组 ,[10]表示指向一个长度为10的数组,int 表示数组元素为int 因为函数不能返回数组,所以可以设置返回一个数组指针,即 auto fo2(int (&a)[10]) -> int (*)[10]{ a[5]=10;

指针和引用(3)指针数组和数组指针

1.知识点 1.1指针数组--存放指针的数组 (1)指针数组本质上是一个数组,指针是数组中的内容,表示数组中的每个元素都是指针,因此指针数组就是存放指针的数组.下面是指针数组的用法: 1 int a = 10, b = 20; 2 int *p[3]; 3 p[0] = &a; 4 p[2] = &b; (2)指针数组的定义可以抽象为:指向变量类型 * 数组名称[数组长度]. (3)[]的优先级高于*,所以[]与p先结合,说明p是一个数组,长度为3,其数组元素的类型是int *. 1.2数