Q1:当数组出现在一个表达式中时,它和指向数组中的第一个元素的指针是等价的。但要注意头文件与源文件要进行相应的定义。
例如:假如在源文件里进行如下定义:
char a[max];
但是在头文件中说明如下:
extern char *a;
就会导致可怕的后果。所以应当在对应头文件中进行如下说明:
extern char a[];
Q2:数组的下标总是从0开始吗?
是的。但在其他语言中,情况可能所有不同。
Q3:可以使用数组后面第一个元素的地址吗?
你可以使用数组后面第一个元素的地址,但你不可以查看该地址中的值。
int a [max];
因为假如你将某些数据存入a[max]中,往往就会破坏原来紧跟在数组a后面的数据。
Q4:为什么要小心对待位于数组后面的那些元素的地址呢?
1.在有些计算机上,地址由两部分组成:第一部分是一个指向某一块内存的起始点的指针(即基地址),第二部分是相对于这块内存的起始点的地址偏移量。这种地址被称为段地址结构。
2.假如基地址处刚好存放着数组a0(即基地址指针和&a0[0]相同),那么基地址无法有效的改变,而偏移量也不能为负值,那么说法“位于a0前面的元素”就毫无意义了。同样,假如数组a(其元素个数为MAX)刚好存放在某段内存的尾部,那么地址&a[MAX]就是没有意义的。
Q5:数组作为参数差UN递给函数时,可以通过sizeof得到数组的大小吗?
答案是不可以。因为数组参数相当于指向该数组第一个元素的指针。
Q6:如何告诉函数数组的参数的大小呢?
通常有两种方法:
1.第一种方法是将数组和表示数组大小的额值一起传递给函数,例如,memcpy()函数就是这样做的:
char source[MAX].dest[MAX];
/*....*/
memcpy(dest,source,MAX);
2.第二种方法是引入某种规则来结束一个数组。请看下述函数,它的参数是以空指针结束的字符指针数组,这个空指针告诉函数什么时候停止工作。
void printMany(char *strings[])
{
int i;
i=0;
while(string[i]!=NULL)
{
puts(strings[i]);
++i;
}
}
Q7: 指针或带下标的数组名都可以访问元素,哪一种更好呢?
区别在于“x=a[]”和“x=*p”,前者要确定a[i]的地址,因此需要将i和类型x的大小相乘后再与数组a中第一个元素的地址相加。后者只需间接引用指针p。间接引用快,而乘法运算比较慢。
Q8:指针数组和数组指针
指针数组“typename *p[n]”定义了一个数组,数组包含了n个指针变量p[0]、p[1]…p[n-1]。
例如:
*p[3]={"abc","defg"};//sizeof(p)=3*4=12(p为数组名代表整个数组)
*p[1]="abc";
p = &p[0] (p+1)=&p[1];
符合一般数组的特性,除了数组中的元素是指针外,和一般的数组没什么区别。
http://www.cnblogs.com/mq0036/p/3382732.html