第28课 指针和数组分析(上)
1. 数组的本质
(1)数组是一段连续的内存空间
(2)数组的空间大小: sizeof(array_type)*array_size;
(3)数组名可看做指向数组第一个元素的常量指针
【编程实验】a + 1的结果是什么? (答案是第2个元素的地址)
1 #include <stdio.h> 2 3 4 5 int main(){ 6 7 8 9 //将数组每个元素初始化为0 10 11 int a[5] = {0}; 12 13 int* p = NULL; 14 15 16 17 printf("a = 0x%X\n",(unsigned int)(a));//首元素的地址 18 19 printf("a + 1 = 0x%X\n",(unsigned int)(a + 1));//第2个元素地址 20 21 22 23 //p + 1 ==(unsigned int)p + n*sizeof(*p); 24 25 printf("p = 0x%X\n",(unsigned int)(p));//0x0 26 27 printf("p + 1 = 0x%X\n",(unsigned int)(p + 1));//0x4 28 29 30 31 return 0; 32 33 }
2. 指针的本质
(1)指针是C语言中一种特别的变量
(2)指针所保存的值是内存的地址
(3)可以通过指针修改内存中的任意地址内容
3. 指针的运算
(1)指针是一种特殊的变量,与整数的运算规则为:
p + n == (unsigned int)p + n * sizeof(*p);
//当指针p指向一个同类型的数组的元素时,p+1指向当前元素的下一个元素,p-1指向上一个元素。
(2)指针之间只支持减法运算且参与减法运算的指针类型必须相同
p1 - p2 = ((unsigned int)p1 – (unsigned int)p2)/sizeof(type)
▲注意:
①只有当两个指针指向同一个数组中的元素时,指针相减才有意义,其意义为指针所指元素的下标差
②当两个指针指向的元素不在同一个数组中时,结果未定义
4. 指针的比较
(1)指针也可以进行关系运算(<、<=、>、>=)
(2)指针关系运算的前提是同时指向同一个数组中的元素
(3)任意两个指针之间的比较运算(==、!=)无限制。
(4)参与比较运算的指针类型必须相同
【实例分析】指针运算初探
1 #include <stdio.h> 2 3 4 5 int main(){ 6 7 8 9 char s1[]={'H','e','l','l','o'};//栈 10 11 int i=0; 12 13 char s2[]={'W','o','r','l','d'}; 14 15 char* p0 = s1; 16 17 char* p1= &s1[3];//p1指向s1数组的第3个元素,即'l' 18 19 char* p2 = s2; 20 21 int* p = &i; 22 23 24 25 printf("%d\n",p0 - p1); //-3 26 27 //printf("%d\n",p0 + p2); //编译错误,指针不支持相加操作 28 29 printf("%d\n",p0 - p2); //指向两个不同数组,结果未定义,gcc下为12 30 31 //printf("%d\n",p0 - p); //编译错误,不同类型指针不能相减! 32 33 //printf("%d\n",p0 / p2); //编译错误,不同类型指针进行除法运算! 34 35 36 37 return 0; 38 39 } 40 41
【实例分析】指针运算的应用
1 #include <stdio.h> 2 3 4 5 //统计元素的个数 6 7 #define DIM(a) (sizeof(a) / sizeof(*a)) 8 9 10 11 int main(){ 12 13 14 15 char s[]={'H','e','l','l','o'};//栈 16 17 char* pBegin = s; 18 19 char* pEnd = s + DIM(s); //关键点,数组名 + n 20 21 char* p = NULL; 22 23 24 25 printf("pBegin = %p\n",pBegin); //第1个元素的地址 26 27 printf("pEnd = %p\n",pEnd); //最后1个元素的地址 28 29 30 31 32 33 printf("Size: %d\n",pEnd - pBegin); //5 34 35 36 37 //在同一行中打印出:Hello 38 39 for (p = pBegin;p < pEnd; p++) 40 41 { 42 43 printf("%c",*p); 44 45 } 46 47 48 49 printf("\n"); 50 51 52 53 return 0; 54 55 }
5. 小结
(1)数组声明时编译器自动分配一片连续的内存空间
(2)指针声明时只分配了用于容纳地址值的4字节空间
(3)指针和整数可以进行运算,其结果为指针(指针的运算)
(4)指针之间只支持减法运算,其结果为数组元素下标差(指针的运算)
(5)指针之间支持比较运算,其类型必须相同(指针的比较)