Summary
1)数组是一段连续的内存空间
,数组的元素个数为 #define DIM(a) (sizeof(a) / sizeof(*a))
2)指针是一种特殊的变量
,与整数的运算规则为
: p + n;
<--> (unsigned int)p + n * sizeof(*p)
当指针p指向一个数组里的元素时,p + 1将指向当前元素的下一元素
;p - 1将指向当前元素的上一元素
。
3)指针之间只支持减法运算
;参与减法运算的指针必须类型相同
:
注意:只有当2个指针指向同一个数组中的元素时,指针相减才有意义
,意义为指针所指元素的下标差
;当2个指针指向的元素不在同一个数组时
,未定义
。p1 - p2;
<--> ((unsigned int)p1 - (unsigned int)p2) / sizeof(type);
4)char* pEnd = s + DIM(s);
pEnd指向了数组s中最后一个元素的后一位置
,虽然这个位置不属于数组,但在C语言中,仍然认为这个边界位置是属于数组的
,这个知识点在STL中也有应用。
5)指针也可以进行关系运算
(<, <=, >, >=),但前提是同时指向同一个数组中的元素
;
两个指针间可以进行比较运算
(==,!=),但两个指针的类型必须相同
;
【【C进阶】28、指针和数组分析】6)for (p = pBegin;
p < pEnd
;
p++) ,p指向了数组的首元素,pEnd在C语言中被认为是数组的元素,所以p和pEnd都指向了同一个数组里的元素,类型相同,能够进行比较
。
指针和数组分析
数组是一段连续的内存空间
数组的空间大小为 sizeof(arr_type) * arr_size
数组名可看做指向数组第一个元素的指针常量
1、指针的运算
问题:对于数组int a[5],a + 1的意义是什么?结果是什么?指针运算的意义是什么,结果又是什么?
结论:
指针是一种特殊的变量
,与整数的运算规则为
: p + n;
<--> (unsigned int)p + n * sizeof(*p)
当指针p指向一个数组里的元素时,p + 1将指向当前元素的下一元素
;p - 1将指向当前元素的上一元素
。
#include int main()
{
int a[5] = {0};
int* p = NULL;
printf("a = 0x%X\n", (unsigned int)(a));
printf("a = 0x%X\n", (unsigned int)(a + 1));
printf("p = 0x%X\n", (unsigned int)(p));
printf("p = 0x%X\n", (unsigned int)(p + 1));
return 0;
}输出:
a = 0xBFCEEF78
a = 0xBFCEEF7C
p = 0x0
p = 0x4
指针之间
只支持减法运算
;参与减法运算的指针必须类型相同
:p1 - p2;
<--> ((unsigned int)p1 - (unsigned int)p2) / sizeof(type);
注意:只有当2个指针
指向同一个数组中的元素时,指针相减才有意义
,意义为指针所指元素的下标差
;当2个指针指向的元素不在同一个数组时
,未定义
#include int main()
{
char s1[] = {'H', 'e', 'l', 'l', 'o'};
char s2[] = {'H', 'e', 'l', 'l', 'o'};
char* p0 = s1;
char* p1 = &s1[3];
char* p2 = s2;
int i = 0;
int* p = &i;
printf("%d\n", p0 - p1);
// 下标差:-3
printf("%d\n", p0 + p2);
// error
printf("%d\n", p0 - p2);
// undefined behavior
printf("%d\n", p0 - p);
// error
printf("%d\n", p0 * p2);
// error
printf("%d\n", p0 / p1);
// errorreturn 0;
}
输出:(指针之间的+ * / 都不允许,不同类型指针的减法运算也不允许)
test.c:17: error: invalid operands to binary + (have ‘char *’ and ‘char *’)
test.c:19: error: invalid operands to binary - (have ‘char *’ and ‘int *’)
test.c:20: error: invalid operands to binary * (have ‘char *’ and ‘char *’)
test.c:21: error: invalid operands to binary / (have ‘char *’ and ‘char *’)p0 - p2的输出为5,但并不知道这是什么意思
#include // 计算数组的大小
#define DIM(a) (sizeof(a) / sizeof(*a))int main()
{
int s1[] = {'H', 'e', 'l', 'l', 'o'};
int s2[] = {'H', 'e', 'l', 'l', 'o'};
int* p0 = s1;
int* p1 = &s1[3];
printf("p1 - p0 = %d\n\n", p1 - p0);
// 3char s[] = {'H', 'e', 'l', 'l', 'o'};
char* pBegin = s;
char* pEnd = s + DIM(s);
char* p = NULL;
printf("pBegin = %p\n", pBegin);
printf("pEnd = %p\n", pEnd);
printf("Size: %d\n", pEnd - pBegin);
// 5for (p = pBegin;
p < pEnd;
p++)// 指针比较,指针运算
{
printf("%C", *p);
}
printf("\n");
return 0;
}输出:
p1 - p0 = 3pBegin = 0xbf9ff2a7
pEnd = 0xbf9ff2ac
Size: 5
Hello
分析:
- char* pEnd = s + DIM(s);
pEnd指向了
数组s中最后一个元素的后一位置
,虽然这个位置不属于数组,但在C语言中,仍然认为这个边界位置是属于数组的
,这个知识点在STL中也有应用。 - for (p = pBegin;
p < pEnd;
p++) ,p指向了数组的首元素,pEnd在C语言中被认为是数组的元素,所以
p和pEnd都指向了同一个数组里的元素,类型相同,能够进行比较
。
关系运算
(<, <=, >, >=),但前提是同时指向同一个数组中的元素
;两个指针间可以进行
比较运算
(==,!=),但两个指针的类型必须相同
;#includeint main()
{
int a[5] = {0};
int* p0 = a;
int* p1 = &a[1];
char* p2;
printf("%d\n", p1 < p0);
// ok, 0
printf("%d\n", p1 < p2);
// undefinedprintf("%d\n", p1 != p0);
// ok, 1
printf("%d\n", p1 == p2);
// undefinedreturn 0;
}
以上代码在编译时已经warning:
test.c:14: warning: comparison of distinct pointer types lacks a cast
test.c:17: warning: comparison of distinct pointer types lacks a cast
本文总结自“狄泰软件学院”唐佐林老师《C语言进阶课程》。
如有错漏之处,恳请指正。
推荐阅读
- c/c++|有感 Visual Studio 2015 RTM 简介 - 八年后回归 Dot Net,终于迎来了 Mvc 时代,盼走了 Web 窗体时代...
- C/C++|C/C++ basis 02
- Qt实战|Qt+OpenCV联合开发(二十一)--图像翻转与旋转
- Qt实战|Qt+OpenCV联合开发(十四)--图像感兴趣区域(ROI)的提取
- Qt实战|Qt+OpenCV联合开发(十三)--通道分离与合并
- opencv|Qt+OpenCV联合开发(十六)--图像几何形状绘制
- Qt实战|Qt+OpenCV联合开发(十七)--随机数与随机颜色
- SNAT的MASQUERADE地址选择与端口选择
- IPTABLES的连接跟踪与NAT分析
- IPVS分析