int a[10];
int *c;
a=c;这句是错误的,a是指针常量所指向的内存中数组的起始地址,如果修改了这个指针常量唯一可行的就是把整个数组移动到内存其他位置。但是,在程序完成链接后内存中数组的位置是固定的,所以当程序运行时,再移动数组就有点晚了,所以,数组名是一个指针常量,所以不能修改,所以不能赋值,所以是错误的。
int array[10];
int *ap=array+2;//ap指向array[2]
ap:为array+2的地址即&array[2]
*ap为array[2]的值,写出*(array+2)即可知道
ap[0]:为array[2]的值(和数组一样)对等的表达式为*(ap+(0))所以可以知道
ap+6:为array[8]的地址
*ap+6:注意先解除引用,所以它相当于表达式array[2]+6
*(ap+6):为array[8]的值
ap[6]:为array[8]的值
ap[-1]:为array[1]
2[array]:是对的,因为它转化成为*(2+(array))即与*(array+2)一样都是array[2]的值
指针和下标都能访问元素,若两种方法都访问正确的时候,下标绝不会比指针更有效率,但指针有时会比下标更有效率。
指针有时候比下标更有用,前提是它们被正确的使用如下面两条语句:
下标方案:
int x[50],y[50];
for(int i=0;i<50;i++)
x[i]=y[i];
指针方案:
for(int i=0;i<50;i++)
*p1++=*p2++;
当你根据某个固定的数目的增量在一个数组中移动时,使用指针变量比下标产生更高的代码,当这个增量是1并且机器具有地址自动增量模型时,这点表现的更为突出。当指针声明为regester int* p1,p2;这样的寄存器指针时,效率更高。
指针和数组:
int a[5];
int *b;
声明一个是数组时,编译器将根据数组指定的元素数量为数组保留内存空间,然后再创建数组名,数组名a是一个常量,值向这段空间的起始位置。声明一个指针时,编译器只为指针本身保留内存空间,并不为任何整型值分配内存空间
多维数组:
int a[3][10];
a[1][5];为第2行第6个元素(从0开始计数)
a;为指向包含了10个整型元素的数组的指针(指针的指针),*p才为第1行的指针
a+1;为指向包含了10个整型元素的数组的指针(指针的指针),*(p+1)才为第2行的指针
*(a+1);为指向数组第2行的指针,相当于a[1]
*(a+1)+5;为指向第二行第6个元素的指针(仍然为指针,对其解除引用(如下面)才为值,即为指向a[1][5]的指针(仍为指针,解除引用才为值)
*(*(a+1)+5)为第二行第6个值,作为右值则取得该值,作为左值则设置该值的值
a[4,3]是允许的,但逗号操作符会对第一个表达式求值,但随着就丢弃这个值,整个表达式的值为第二个值,所以它相当于a[3]
指向数组的指针:
int v[10],*vp=v;
int a[3][10],*ap=a;
第一个是合法的,vp是一个指向整型的指针,并把它声明为指向数组第一个元素的指针。
第二个是非法的,因为ap的初始化不正确,a不是一个指向整型的指针,而是一个指向指针数组的指针。而我们声明一个指向整型数组的指针可以用下面方式:
int (*ap)[10];ap是一个指向拥有10个整型数组的指针,则加上初始化后为下面:
int (*ap)[10]=a;它指向a的第一行
作为函数参数的多维数组:
作为函数参数的多维数组名的传值方式和一维数组名相同,都是传递指向数组第一个元素的指针,不同在于多维是数组的每个元素本身是另外一个数组,编译器需要知道它的维数。
int vector[10];
func1(vector);
vector是一个指向整型的指针,则func1的原型可以是下面两种:
func1(int *vec);
func1(int vec[]);
下面是二维数组的:
int matrix[3][10];
func2(matrix);
matrix是一个包含10个整型元素的数组的指针,原型如下:
func2(int *(mat)[10]);//必须知道维数,但第一维的维数不需要知道,计算时用不到它
func2(int mat[][10]);//必须知道维数,但第一维的维数不需要知道,计算时用不到它
若写成func2(int **mat);是错误的,mat是一个指向指针的指针,它和指向整型的指针是不一样的。
初始化:
int a[2][3]={
{1,2,3},
{4,5,6}
};
int a[2][3][4]={
{
{1,2,3,4},
{5,6,7,8},
{9,10,11,12}
},
{
{13,14,15,16},
{17,18,19,20},
{21,22,23,24}
}
}
数组长度自动计算:
int a[]={1,2,3},则自动计算出a的长度为3,但只有一维才能提供初始化列表缺省参数,剩余的几个维必须写出维数:
int a[][5]={
{1,2,3,4,5},
{6,7,8,9,10}
};
这里的第一维没有写出,但第二维的5必须写出。
指针数组:
int *api[10];数组的每一个值都是一个指针。
char const *keyword[]={
''do'',
''for'',
''if'',
''while''
};
#define n_keyword (sizeof(keyword)/sizeof(key[0]);
第一个sizeof计算的是整个数组占用的字节数,第二个sizeof计算的是数组每个元素占用的字节数,所以相除得到数组元素个数。