数组指针
1.什么是数组指针:
首先它是一个指针,它指向一个数组,在32位系统下任何类型的指针所占内存大小都为4个字节,至于它指向的数组占多少字节,具体要看数组的大小。总之,数组指针即为“指向数组的大小”,例如:int (*p)[4],定义了一个数组指针,该指针变量保存的是一个数组的首地址,它可以指向一个含有4个整型元素的数组。
2.如何使用?
(1)对于一维数组:
int main(void)
{
char a[5]={'A','K','C','G','L'};
char (*p)[5]=&a;//&a代表的是整个数组的首地址
//char (*p)[5]=a;这样是错误的,因为a代表第一个元素的首地址
printf("%c %c %c",**p,*(*p+1),*(*p+3));//输出:A K G
return 0;
}
说明:a代表的是第一个元素的地址,即:&a[0],而&a代表的是整个数组的地址。虽然printf("%p %p",&a,a);输出的值是相同的,但它们代表的意义不同。a+1代表的是下一个元素的地址,即&a[1],而&a+1代表的是向后移动5个字节的地址。这里为什么用的二级指针呢?因为p=&a,*p即为第一个元素的地址,再**p即输出了第一个元素。同理,*(*p+1),*(*p+3)输出第二个元素,第四个元素。
(2)对于二维数组:
int main(void)
{
char a[3][4]={"for","cr","int"};
char (*p)[4]=NULL;
p=&a[0];
printf("%c %c %s %s\n",*(*p+1),*(*(p+1)+1),*p,*(p+1));//输出:o r for cr
return 0;
}
说明:二维数组的传递有两种方式:一种是行指针传递,例如上面的代码(p=&a[0],p指向了第一行的地址);一种是列指针传递(看下面的介绍)。上面代码中p代表二维数组第一行的地址,则*p代表第一行的第一个元素的地址,*p+1代表第一行的第二个元素的地址,再*(*p+1)则输出了第二个元素;同理,p+1代表第二行的地址,*(p+1)代表第二行第一个元素的地址,*(p+1)+1代表第二行第二个元素的地址
指针数组
1.什么是指针数组:
首先它是一个数组,数组的元素都是指针,数组占多少个字节由数组本身的大小决定,每个元素都是一个指针。总之,它是一个"存储指针的数组"。例如:char *msg[]={“Sunday”,“Monday”}。存储了两个指针,第一个指针指向了字符串"Sunday",第二个指针指向了字符串"Monday",sizeof(msg)=8。指针数组最主要的用途是对多个字符串进行处理操作,因为字符指针比二维数组更快更有效。
2.如何使用?
(1):
void print(char *arr[])
{
puts(arr[0]);//输出:Fortran
}
int main(void)
{
char *p[]={"Fortran","C","C++"};
print(p);
return 0;
}
(2):
void print(char **arr)
{
puts(*arr);//输出:Fortran
puts(*(arr+1));//输出:C
}
int main(void)
{
char *p[]={"Fortran","C","C++"};
print(p);
return 0;
}
(3):
//如果一个指针数组大小不确定,则可以在指针数组的末尾设置NULL
char *a[]={"FORTRAN","C","C++",NULL};
void print(char *p[])
{
while(*p!=NULL)
{
puts(*p++);
}
}
二维数组
1.什么是二维数组:
例如:int a[3][4],即定义了一个三行四列的整型二维数组。在初始化时候,第一个中括号的数字可以省略但第二个不可以省略。这些基本知识可以看看大学课本,不再阐述。
2.指针和二维数组的关系:
int a[3][4];
a:代表a[0]的地址,即:a=&a[0],a[0]代表a[0][0]的地址,即a[0]=&a[0][0];
a+1:代表a[1]的地址,即:a+1=&a[1],a[1]代表a[1][0]的地址,即a[1]=&a[1][0];
a+2:代表a[2]的地址,即:a+2=&a[2],a[2]代表a[2][0]的地址,即a[2]=&a[2][0];
a[i][j]=*(a[i]+j)=*(*(a+i)+j)=(*(a+i))[j]
(1):二维数组用行指针定义
int (*p)[4]=NULL;
定义了一个数组指针,可指向含有4个整型元素的指针变量。指向二维数组的行指针,它所指向的二维数组的每一行有4个元素。
初始化:
p=a;
//或
p=&a[0];
p代表第一行的地址。
引用元素:
p[i][j]或者*(p[i]+j)或者*(*(p+i)+j)
(2):二维数组用列指针定义
int *p=NULL;
将这个二维数组看成一个一维数组,具有m*n个元素。
初始化:
p=a[0];
//或
p=*a;
//或
p=&a[0][0];
p代表第一行第一个元素的地址。
引用元素:
*(p+i*n+j)或者p[i*n+j]
3.指针数组和二维数组的区别:
char *p1[]={"FORTRAN","C","C++"};
char p2[][8]={"FORTRAN","C","C++"};
*p1,*(p1+1),*(p1+2):所指向的字符串常量是不规则长度的,且sizeof(p1)=12。
p2[0],p2[1],p2[2]所指向的字符串都是一定长度的,且sizeof(p2)=24。