1.数组名的值是一个【指针常量】,也就是数组第一个元素的地址。它的类型取决于数组元素的类型:如果它们是int类型,那么数组名的类型就是“指向int的常量指针”。下列两种情况:数组名并不用指针常量表示———就是当数组名作为siziof操作符或单目运算&的操作数是。【注意】:数组名是指针常量,所以不能被修改。
2.下标引用:通过一个例子来讲解下标引用.
int a[10] = { 2, 45, 3, 4, 8, 9, 7, 56, 25, 89};
int *p = a + 2;
下面关于p能否写出关于a的表达式。
p:对等表达式:a + 2.另外 &a[2] 也与之对等。
*p: 对等表达式:*(a + 2).另外 a[2] 也与之对等。
p[0]:记住c的下标引用和间接访问表达式是一样的。目前情况下,对等的表达式是*(p + (0)),除去0和(),其结果与前面的一样。
#include<iostream>
using namespace std;
void main()
{
inta[10] = { 2, 45, 3, 4, 8, 9, 7, 56, 25, 89};
int *p= a + 2;
printf("p= 0x%x\n", p);
printf("*p= %d\n", *p);
printf("p[0]= %d\n", p[0]);
printf("p+ 6 = 0x%x\n", p + 6);
printf("*(p+ 6) = %d\n", *(p + 6));
printf("p[6]= %d\n", p[6]);
printf("&p= 0x%x\n", &p);
printf("p[-1]= %d\n", p[-1]);
printf("p[10]= 0x%x\n",p[10]);
}
结果如下2:
3.指针和下标:
下标:int array[10], a;
for(a = 0; a < 10; a ++)
array[a] = 0;
指针:int array[10], *ap;
for(ap = array;ap < array + 10; ap ++)
*ap = 0;
以上两种用法的区别:1.下标表达式求值,编译器在程序中插入指令,取得a的值,并把它与整型的长度(也就是4)相乘。乘法执行的次数与循环次数-1相等。2.指针表达式求值,乘法是在循环中执行,只需要执行一次。
4.数组与指针:
inta[5];
int *b;
以上两个声明都可以进行间接访问和下标引用操作。但是,存在很大区别:
声明一个数组时,编译器将根据声明所指定的元素的数量为数组保留内存空间,然后在创建数组名,它的值是常量,指向这段空间的起始位置。声明指针变量时,编译器只为指针本身保留内存空间,它不为任何整型值分配内存空间。以下是用图示法说明两个声明:
a
b
上述声明之后,表达式*a是合法的,但是表达式*b是非法的。*b访问的内存是不确定的。另一方面,表达式b++可以通过编译,a++却不行,因为a是常量。
5.声明数组参数:
如果你把数组名参数传递给函数,那么正确的函数形参是咋样的呢?实际,调用函数时实际传递的是一个指针,所以形参实际上是个指针,但是编译器也接受数组形式的函数参数,因此,下面两种函数原型的声明是相等的:
intstrlen(char *string);
intstrlen(char string[]);
为什么函数原型中一维数组形参无需写明它的元素数目,因为函数并不为数组参数分配内存空间,形参只是指针而已。
6.字符数组的初始化,有两种方法:
1. charmessage[] = {'q','a','b', 'c'}; 2. charmessage[] = "qabc";两者对等的。