一、数组与指针
输出数组中每个元素的值(数组版):
#include <stdio.h>
int main(void)
{
int i;
int array[5];
for(i = 0; i < 5; i++)
array[i] = i;
// 输出数组中每个元素的值(数组版)
for(i = 0; i < 5; i++)
{
printf("array[%d]..%d\n", i, array[i]);
}
return 0;
}
输出数组中每个元素的值(指针版):
#include <stdio.h>
int main(void)
{
int i;
int *p;
int array[5];
for(i = 0; i < 5; i++)
array[i] = i;
// 输出数组中每个元素的值(指针版)
for(i = 0, p = &array[0]; p < &array[5]; p++)
{
printf("array[%d]..%d\n", i++, *p);
}
return 0;
}
输出数组中每个元素的值(指针改进版):
#include <stdio.h>
int main(void)
{
int i;
int *p;
int array[5];
for(i = 0; i < 5; i++)
array[i] = i;
// 输出数组中每个元素的值(指针改进版)
p = &array[0];
for(i = 0; i < 5; i++)
{
printf("array[%d]..%d\n", i, *(p + i));
}
return 0;
}
以上3段代码实现的功能相同,无论是p++,还是*(p + i)其可读性都不强,a[i]的方式最容易理解,所以 抛弃指针运算的写法(?)
在指针改进版的例程中
p = &array[0];
其实也可以写成下面这样:
p = array;
对于这种写法,很多 C 语言的入门书籍是这样说明的: 在 C 中,如果在数组名后不加[ ],单独地只写数组名,那么此名称就表示“指向数组初始元素的指针”。
在这里,我可以负责地告诉你,上面的说明是错误的。
将&array[0] 改写成 array,“改写版”的程序甚至可以写成下面这样:
p = array;
for(i = 0; i < 5; i++)
{
<span style="white-space:pre"> </span>printf("array[%d]..%d\n", i, *(p + i));
}
与下面这段代码进行比较
p = array;
for(i = 0; i < 5; i++)
{
printf("array[%d]..%d\n", i, p[i]);
}
发现p[i]只不过是*(p + i)的简便写法罢了,除此之外,它毫无意义。
也就是说,存在 int array[5] 这样的声明的时候,“一旦后面不追加[ ],只写array”并不代表要使array具有指向数组第1个元素的指针的含义,无论加不加[ ],在表达式中,数组都可以被解读为指针。
要点:
1. 表达式中,数组可以解读为“指向它的初始元素的指针”。尽管有3个小例外,但是这和在后面加不加[ ]没有关系。
2. p[i]是*(p + i)的简便写法。
下标运算符[ ]原本就只有这种用法,它和数组无关。
3.p[i]可以写成i[p],但是不要写成这样。
需要强调的是,认为[ ]和数组没有关系,这里的[ ]是指在表达式中出现的下标运算符[ ]。 声明中的[ ],还是表达数组的意思。
也就是说,声明中的[ ]和表达式中的[ ]意义完全不同。表达式中的*和声明中的*的意义也是完全不同的。这些现象使得 C 语言的声明在理解上变得更加扑朔迷离……
此外,如果将 a + b 改写成 b + a,表达式的意义没有发生改变,所以你可以将*(p + i)写成*(i + p)。其次,因为 p[i]是*(p + i)的简便写法,实际上它也可以写成 i[p]。
引用数组元素的时候,通常我们使用 array[5]这样的写法。其实,就算你写成 5[array],还是可以正确地引用到你想要的元素。
可是,这种写法实在太另类了,它不能给我们带来任何好处。
二、将数组作为函数的参数进行传递
要点:
1.如果试图将数组作为函数参数进行传递,那就传递指向初始元素的指针
2.在迫不得已的情形下,如果你执意要将数组的副本作为参数进行传递,可以使用替代方法——将数组的所有元素整理成结构体的成员
三、声明函数形参的方法
在下面声明的形参,都具有相同的意义。
int func(int *a); /*写法1*/
int func(int a[]); /*写法2*/
int func(int a[10]); /*写法3*/
写法 2 和写法 3 是写法 1 的语法糖。
要点:
只有在声明函数形参时,数组的声明才可以被解读成指针