(1)int *p[100]是一个指向int型的指针数组,即:p是包含100元素的指针数组,指针指向的是int型。
它可以指向一个【行数确定】而【列数不确定】的二维数组,如下:
为了方便举例,我们姑且讲int *p[2]吧,这样p就可以指向一个2*n的二维整型数组(即行数确定为2,列数为n是不确定的)理解见下面注释:
#include
using namespace std;
void main() {
int* p[2]; // 我们想象它是指向一个二维数组的
int a[3] = {1, 2, 3}; //二维数组的第一行,3列(其实是一个一维数组)
int b[4] = {4, 5, 6, 7}; //二维数组的第二行,4列
p[0] = a; // 指向第一行
p[1] = b; // 指向第二行
for(int i = 0; i < 3; i++) cout << *(p[0] + i);//输出第一行
cout << endl;
for(i = 0; i < 4; i++) cout << *(p[1] + i);//输出第二行
}
(2)int (*p)[100]是一个二维数组的指针,而这个二维数组是一个【行数不确定】而【列数确定】的任何二维数组。我们还是拿int (*p)[2]来举例:
#include
using namespace std;
void main() {
int (*p)[2]; // 可以指向任意行2列的二维数组
// 下面是个3行的二维数组,我们可以写任意行的二维数组,但是列数只能为2
int b[3][2] = {
{1, 2},
{3, 4},
{5, 6}};
p = b;// 指向这个二维数组
for(int i = 0; i < 3; i++) {
for(int j = 0; j < 2; j++) cout << p[i][j]; // 输出一行
cout << endl;
}
}
小结:
int *p[100]和int (*p)[100]都是可以指向二维整型数组的,但一个是指向100*n的二维数组(即列数不定),一个是指向n*100的二维数组
(3)typedef int (* type1_t)(const char *,int) // 定义了一个函数指针类型,这种类型的指针可以指向任何返回值为int类型,两个参数分别为const char*类型及int类型的函数。
(4)typedef int type2_t(const char *,int) // 定义了一种函数声明类型
则下面的声明语句:
type2_t A;
等同于:
int A(const char*, int);
关于(3)(4),理解见下例的注释:
#include
using namespace std;
typedef int (* type1_t)(const char *,int);
typedef int type2_t(const char *,int);
type2_t B; // 声明函数B,函数实现在主函数后面
type2_t A; // 声明函数A,实现在主函数后面
void main()
{
int h = B(NULL,0); //调用函数B,此时h为1
int f = A(NULL,0); // f为2
type1_t C = B; //定义函数指针C,并初始化指向函数B
int g = C(NULL,0); // 使用函数指针调用函数(实际上是调用B),g为1
C = A; // 函数指针C指向函数A
int x = C(NULL,0); //此时x为2
}
int B(const char*, int){return 1;}
int A(const char*, int){return 2;}
如有不清楚的地方,可以hi我
第一个是指针数组 数组里面存放指向整型的指针
第二个是数组指针 指针指向整型数组
指针数组是指针的数组,里边的内容是指针;数组指针是指向数组的指针,具体一点是
指向数组的第一个元素,指针每加一便指向数组的下一个元素。
指针数组,顾名思义,就是说的首先是一个数组吧,然后数组的元素是指针而已。说明形式为:type *pointer_array[constant1][constant2]...[constantn]; 例如:int *pai[3]; 由于‘*’是自右向左结合,因此从右向左看,首先看到[4]说明是一个数组,是一个包含4个元素的数组,然后看到‘*’,显然是指针类型,由此可以看出数组中存放的是指针而不是一般的类型。同理,char *pac[2][3]是包含有6个元素,每一个元素都是一个字符型指针。再来说说他们的初始化: int *pai[3];既然是一个包含4个整形指针的数组那么其对应的将是一个二维整形数组,因为一个整形指针对应一个一维整形数组。那我就用一个二维整形数组来初始化它,事实上一般也都是这么做的,这里有一个二维数组,int arr[3][2]={{1,2},{3,4},{5,6}},一个三行两列的整形数组,注意这里的行必须和你的指针数组的维数一致,否则是不允许的,不信你可以试试。这个初始化有很多种选择,以下只列举常见的两中:第一种也是很好理解的: for(int i=0;i<3;i++) pai[i]=arr[i]; 显然arr[i]是每一行的首地址,相当于一个一维数组的数组名,如是把它送给一个整形指针pai[i]是理所当然的了。
第二种方法:在说明指针数组时就初始化:int (*ap)[2]={{1,2},{3,4},{5,6}};哈哈这个不用说了吧。
注意:不能将二维数组的数组名赋给指针数组的数组名,pai=arr(错),因为两者的类型不一致,二维数组名的类型是指向int[][]型的指针,而指针数组的的数组名是指向int *[]类型的指针。
在c/c++语言中,指针数组最常用的场合就是说明一个字符串数组。即说明一个数组,它的每个元素都是一个字符串。
二:数组指针:指向一个数组的指针。说明形式为:type (*pointer_array)[constant1][constant2]...[constantn]; 注意这里的圆括号是必须就将这是由于方括号[],较指针说明符“*”的优先级高,若无此圆括号,编译器将把上述说明解释成成了一个数组指针。例如:int (*ap)[2]; 这样就说明了一个指向包含有2个元素的整形数组的数组指针,听起来确实有点别扭。不过仔细分析应该还是能理解的,就是说ap是一个指针,而它指向的对象是一个指针,注意不要将它和一个指向一个整形变量的指针搞混了。同样以一个二维数组来说明其初始化问题, int arr[3][2]={{1,2},{3,4},{5,6}};注意这里的列数必须和数组指针所指的数组的列数相同。第一种方法: ap=arr; 为什么这里能这样将二维数组名送给ap呢,你可以这样理解,二维数组不就可以看成是一维数组的数组吗,而一个数组指针它指向的内容就是一个一维数组,那么你就可以把这个数组指针当做是一个数组名,只不过这个数组里的元素不是像int,char之类型的,而是一个数组,这样你就可以把它和二维数组的数组名联系在一起了吧。文笔不行,不知道是否说清楚了。
第二种方法: ap=&arr[0]; 这里arr[0]其实就是一维数组的数组名,将它的地址给ap是很自然的,因为ap本来就是指向一个一维数组的。注意这里不能这样初始化:int (*a)[2]={{1,2},{3,4},{5,6}};大家可以想想为什么。当然他们也可以动态赋值,
第一个是指针数组
第二个是数组指针
指针数组的概念
一个数组的元素值为指针则是指针数组。 指针数组是一组有序的指针的集合。 指针数组的所有元素都必须是具有相同存储类型和指向相同数据类型的指针变量。
指针数组说明的一般形式为:
类型说明符 *数组名[数组长度]
其中类型说明符为指针值所指向的变量的类型。
例如:
int *pa[3]
表示pa是一个指针数组,它有三个数组元素,每个元素值都是一个指针,指向整型变量。
【例】通常可用一个指针数组来指向一个二维数组。指针数组中的每个元素被赋予二维数组每一行的首地址,因此也可理解为指向一个一维数组。
main(){
int a[3][3]={1,2,3,4,5,6,7,8,9};
int *pa[3]={a[0],a[1],a[2]};
int *p=a[0];
int i;
for(i=0;i<3;i++)
printf("%d,%d,%d\n",a[i][2-i],*a[i],*(*(a+i)+i));
for(i=0;i<3;i++)
printf("%d,%d,%d\n",*pa[i],p[i],*(p+i));
}
本例程序中,pa是一个指针数组,三个元素分别指向二维数组a的各行。然后用循环语句输出指定的数组元素。其中*a[i]表示i行0列元素值;*(*(a+i)+i)表示i行i列的元素值;*pa[i]表示i行0列元素值;由于p与a[0]相同,故p[i]表示0行i列的值;*(p+i)表示0行i列的值。读者可仔细领会元素值的各种不同的表示方法。
应该注意指针数组和二维数组指针变量的区别。这两者虽然都可用来表示二维数组,但是其表示方法和意义是不同的。
二维数组指针变量是单个的变量,其一般形式中"(*指针变量名)"两边的括号不可少。而指针数组类型表示的是多个指针(一组有序指针)在一般形式中"*指针数组名"两边不能有括号。
例如:
int (*p)[3];
表示一个指向二维数组的指针变量。该二维数组的列数为3或分解为一维数组的长度为3。
int *p[3]
表示p是一个指针数组,有三个下标变量p[0],p[1],p[2]均为指针变量。
指针数组也常用来表示一组字符串,这时指针数组的每个元素被赋予一个字符串的首地址。指向字符串的指针数组的初始化更为简单。例如在例10.32中即采用指针数组来表示一组字符串。其初始化赋值为:
char *name[]={"Illagal day",
"Monday",
"Tuesday",
"Wednesday",
"Thursday",
"Friday",
"Saturday",
"Sunday"};
完成这个初始化赋值之后,name[0]即指向字符串"Illegal day",name[1]指向"Monday"......。
指针数组也可以用作函数参数。
【例】指针数组作指针型函数的参数。在本例主函数中,定义了一个指针数组name,并对name 作了初始化赋值。其每个元素都指向一个字符串。然后又以name作为实参调用指针型函数day_name,在调用时把数组名name赋予形参变量name,输入的整数i作为第二个实参赋予形参n。在day_ name函数中定义了两个指针变量pp1和pp2,pp1被赋予name[0]的值(即*name),pp2被赋予name[n]的值即*(name+ n)。由条件表达式决定返回pp1或pp2指针给主函数中的指针变量ps。最后输出i和ps的值。
main(){
static char *name[]={ "Illegal day",
"Monday",
"Tuesday",
"Wednesday",
"Thursday",
"Friday",
"Saturday",
"Sunday"};
char *ps;
int i;
char *day_name(char *name[],int n);
printf("input Day No:\n");
scanf("%d",&i);
if(i<0) exit(1);
ps=day_name(name,i);
printf("Day No:%2d-->%s\n",i,ps);
}
char *day_name(char *name[],int n)
{
char *pp1,*pp2;
pp1=*name;
pp2=*(name+n);
return((n<1||n>7)? pp1:pp2);
}
一个数组,若其元素均为指针类型数据,称为指针数组。
也就是说,指针数组中每一个元素都相当于一个指针变量。
一维指针数组的定义形式为:类型名 *数组名[数组长度]
例如:
int *p[4]
由于[]比*优先级更高,因此p先与[4]结合,形成p[4]的形式,这显然是数组形式。
然后再与p前面的*结合,*表示次数组是指针类型的,每个数组元素都指向一个整型变量。
数组指针
数组指针是指向数组的一个指针,如
int (*p)[4]
表示一个指向4个元素的数组的一个指针。
typedef int (* type1_t)(const char *,int)和typedef int type2_t(const char *,int)
前一个声明引入了type1_t类型作为函数指针的同义字,该函数有两个 const char * 类型的参数以及一个 int 类型的返回值
后一个声明引入了type2_t类型作为函数的同义字,该函数有两个 const char * 类型的参数以及一个 int 类型的返回值
不管什么时候,只要为指针声明 typedef,那么都要在最终的 typedef 名称中加一个 const,以使得该指针本身是常量,而不是对象
int *p[100] 定义了:有 100 个元素的数组,其中每个元素都可以保存一个整型数的地址,简单说就是:
有 100 个元素的“指针数组”, p 为这个 “指针数组”的名字(首地址)。
int (*p)[100] 定义了:指针 p ,它可以指向“有 100 个元素的整型数组”,
例如,
已经定义了 int nA[2][100];
就可以让 p 为 nA[0] 的地址; 或 p 为 nA[1] 的地址;
来访问 “二维数组” nA 里的每一行 “一维数组”。
以下为例子:
#include
using namespace std;
// type1_t 类型 被定义为 “指向以下函数签名的指针”
typedef int (* type1_t)(const char *,int);
// type2_t 类型 被定义为 “为以下函数签名提供声明”
typedef int type2_t(const char *,int);
type2_t type2_var; // 声明了一个名为type2_var的函数
int type1(const char *nA, int nI) { return 1; } // 实现 函数type1
int type2_var(const char *nA, int nI) { return 1; } // 实现 函数type2_var
int main() {
int (*p)[100]; // 数组指针
int nA[2][100] = {{0,0,1},{0,0,0}};
type1_t type1_var; // 定义函数指针
type1_var = type1; // 函数指针指向已经声明的函数type1
type1_var(NULL,1); // 函数指针调用已经声明的函数type1
type2_var(NULL,1); // 调用名为type2_var的函数
p = &(nA[0]); // 数组指针
cout << (*p)[2]; // 数组指针访问二维数组的内容
return 0;
}