数组的本质
数组是一段连续的内存空间;
数组的空间大小为sizeof(array_type)* array_size;
数组名可看做指向数组第一个元素的常量指针;
示例1如下:
#include <stdio.h>
int main()
{
int a[5] = {0};
int* p = NULL;
printf("a = 0x%X\n", (unsigned int)(a));
printf("a + 1 = 0x%X\n", (unsigned int)(a + 1));
printf("p = 0x%X\n", (unsigned int)(p));
printf("p + 1 = 0x%X\n", (unsigned int)(p + 1));
return 0;
}
指针的运算
指针是一种特殊的变量,与整数的运算规则为
p + n; == (unsigned int)p + n*sizeof(*p);
结论
当指针p指向一个同类型的数组的元素时:
p +1将指向当前元素的下一个元素;
p-1将指向当前元素的上一个元素。
指针之间只支持减法运算
参与减法运算的指针类型必须相同
p1-p2; == ((unsigned int)p1 - (unsigned int)p2) / sizeof(type);
注意
1.只有当两个指针指向同一个数组中的元素时,指针相减才有意义,其意义为指针所指元素的下标差;
2.当两个指针指向的元素不在同一个数组中时,结果未定义;
指针的比较
指针也可以进行关系运算(<,<=,>,>= );
指针关系运算的前提是同时指向同一个数组中的元素;
任意两个指针之间的比较运算(==,!=)无限制;
参与比较运算的指针类型必须相同;
示例2如下
#include <stdio.h>
int main()
{
char s1[] = {'H', 'e', 'l', 'l', 'o'};
int i = 0;
char s2[] = {'W', 'o', 'r', 'l', 'd'};
char* p0 = s1;
char* p1 = &s1[3];
char* p2 = s2;
int* p = &i;
printf("%d\n", p0 - p1);
printf("%d\n", p0 + p2);
printf("%d\n", p0 - p2);
printf("%d\n", p0 - p);
printf("%d\n", p0 * p2);
printf("%d\n", p0 / p2);
return 0;
}
示例3如下
#include <stdio.h>
#define DIM(a) (sizeof(a) / sizeof(*a))
int main()
{
char s[] = {'H', 'e', 'l', 'l', 'o'};
char* pBegin = s;
char* pEnd = s + DIM(s); // Key point
char* p = NULL;
printf("pBegin = %p\n", pBegin);
printf("pEnd = %p\n", pEnd);
printf("Size: %d\n", pEnd - pBegin);
for(p=pBegin; p<pEnd; p++)
{
printf("%c", *p);
}
printf("\n");
return 0;
}
小结
数组声明时编译器自动分配一片连续的内存空间;
指针声明时只分配了用于容纳地址值的4字节空间;
指针和整数可以进行运算,其结果为指针;
指针之间只支持减法运算,其结果为数组元素下标差;
指针之间支持比较运算,其类型必须相同;