一.你将发现一个内幕!
#include <stdio.h>
#define n 5
int main()
{
unsigned int a[n] = { 123,5,9,11,33 };
printf("%x\n", a);
printf("%x\n", &a[0]);
printf("%d\n", a[0]);
printf("%d\n", *a);
}
运行结果:
135fd94
135fd94
123
123
结论: 数组名,即数组的地址!数组首元素的地址!
二.掌握内幕之后……
1.数组名为数组首元素的地址,可知
① 定义: int a[10] ; int *p ;
② 等价的赋值 : p=&a[0] <=> p=a;
③ 指针变量赋初值: int *p=&a[0]; <=> int *p=a;
④ 指针引用数组元素: printf("%d %d", *p, *(p+1)) <=> printf("%d %d", a[0], a[1]);
⑤ p+i的意义:p之后第i个单元
2.因数组名等同于指向数组首元素的指针,可知
① 设 int a[10] ; int *p=a ;
② a[i]的地址: &a[i] ; a+i; p+i ;
③ a[i]的值为: * (p+i) , * (a+i) , p[i] ;
④ a[i] , * (p+i) , * (a+i) , p[i] 求解过程:
先按 (a+i×d) 计算数组元素的地址;(d为数组类型所占字节数)
再取出此地址所指向的单元的值;
3.引用数组元素的方法
① 下标法 : a[i] , p[i]
② 指针法 : *(a+i) , *(p+i)
三.指针操作数组元素的意义
1.能使目标程序效率提升;
2.另一种操作数组的方法;
四. 实例: 输出数组全部元素的6种方法
1.常规下标法: 最直观
#include <stdio.h>
int main()
{
int a[10] = { 9,8,7,6,5,4,3,2,1,0 };
int i;
for (i = 0; i < 10; i++)
{
printf("%d ", a[i]);
}
}
2.常规指针法
#include <stdio.h>
int main()
{
int a[10] = { 9,8,7,6,5,4,3,2,1,0 };
int i;
for (i = 0; i < 10; i++)
{
printf("%d ", *(a+i));
}
}
3.间接指针法
#include <stdio.h>
int main()
{
int a[10] = { 9,8,7,6,5,4,3,2,1,0 };
int i;
int* p;
for (p=a,i = 0; i < 10; i++)
{
printf("%d ", *(p+i));
}
}
4.指针变量法: 效率高
#include <stdio.h>
int main()
{
int a[10] = { 9,8,7,6,5,4,3,2,1,0 };
int* p;
for (p = a; p < (a + 10); p++)
{
printf("%d ", *p);
}
}
5.指针变量法: 更高效,更有"C味"
#include <stdio.h>
int main()
{
int a[10] = { 9,8,7,6,5,4,3,2,1,0 };
int* p=a;
while (p < a + 10)
printf("%d ", *p++);
}
6.指针变量法: 更稳妥/直观
#include <stdio.h>
int main()
{
int a[10] = { 9,8,7,6,5,4,3,2,1,0 };
int* p = a;
while (p < a + 10)
{
printf("%d ", *p);
p++;
}
}
五.谨慎使用
1.a++为错误写法,在C中数组名默认为指针的常量,不可自增;
2.* (p+10)可能存在越界危险,要谨慎使用;