首先说一下以下性质
a) int a;表示一个内存空间,这个空间用来存放一个整数(int);
b) int* a;表示一个内存空间,这个空间用来存放一个指针,这个指针指向一个存放整数的空间,即a)中提到的空间;
c) int** a;表示一个内存空间,这个空间用来存放一个指针,这个指针指向一个存放指针的空间,并且指向的这个空间中的指针,指向一个整数。也简单的说,指向了一个b)中提到的空间; d) int (*a)[10];表示一个内存空间,这个空间用来存放一个指针,这个指针指向一个长度为10、类型为int的数组;和int** a的区别在于,++、+=1之后的结果不一样,其他用法基本相同。
一、int *a[10] 和 int(*a)[10] 的区别
int *a[10] :数组指针。数组a里存放的是10个int型指针 int (*a)[10] :a是指针,指向一个数组。此数组有10个int型元素
int *a[10]
先找到声明符a,然后向右看,有[]说明a是个数组,再向左看,是int *,说明数组中的每个元素是int *。所以这是一个存放int指针的数组。
int(*a)[10]
先找到声明符a,被括号括着,先看括号内的(优先级高),然后向右看,没有,向左看,是*,说明s是个指针,什么指针?在看括号外面的,先向右看,有[] 是个数组,说明a是个志向数组的指针,再向左看,是int,说明数组的每个元素是int。所以,这是一个指向存放int的数组的指针。
二、int **a 和 int(*a)[10]的区别
分析一下程序
int tt[10];
int (*a)[10] = &tt; // 其实 a是二维指针 **a等于2, 但是不让这样赋值 int **a = &tt; 但让下面这样赋值。
int (*a)[10] = &tt; 类似于int *b = tt, int **a = &b; (因为不能直接这样赋值 int **a = &tt); 但是也不一样。
若 int (*a)[10] = &tt 这样赋值,**a等于2, *a输出 7339472,a也等于7339472。
若这样赋值 int *b = tt, int **a = &b; **a 等于2,*a 等于7339472,a等于 7339512,两者是有差异的。 但是两者这样赋值之后 int *k = *a; 都可以这样输出 printf("%d", *k); 所以我说类似,应该是 数组名的地址想要直接赋值给地址的话,应该只能 int (*a)[10] = &tt;(但是仔细想想,数组名不就是一个地址吗,数组名的地址不就是,地址的地址吗,也就是二维指针了,所以我说和**a类似)
#include<iostream>
#include<string>
#include<string.h>
#include<algorithm>
using namespace std;
int main()
{
int tt[10];
for(int i = 0;i<10;i++)
tt[i] = i+2;
/*
int *b = tt;
int **a = &b;
int *k = *a; // 二维指针变一维指针
*/
// 或者这样赋值
int (*a)[10] = &tt;
int *k = *a; // 二维指针变一维指针
//printf("%d", **a); **a这样输出结果为2 *a输出7339472 一个地址值。
for(int i = 0;i<10;i++)
{
if(i!=0) cout <<" " ;
//printf("%d ", *(*a+i)); // 还可以这样输出
printf("%d", *k);
//a = a + 1;
k++;
}
}
当这样赋值时,int (*a)[10] = &tt; 不管是 a++,还是a+=1,输出的 **a都是乱码(除第一次输出外,第一次输出2);
三 数组引用
(1) 数组引用,arrRef 相对于 arr 的别名
int arr[10];
int (&arrRef)[10] = arr;
(2) 指针数组引用, arry 相当于 ptrs 的别名,arry是一个含有10个int型指针数组的引用
int *ptrs[10];
int *(&arry)[10] = ptrs;