【C编程问题集中营】使用数组指针时容易踩得坑
【C编程问题集中营】使用数组指针时容易踩得坑
文章目录
- 【C编程问题集中营】使用数组指针时容易踩得坑
- 一、获取数组首地址
- 二、应用场景举例
- 2.1 正常场景
- 2.2 异常场景
- 三、总结
一、获取数组首地址
一维数组的首地址即数组第一个元素的指针,常用的获取一维数组首地址的方式有如下几种,以unsigned char
类型的TestArray[4]
数组举例:
TestArray
;&TestArray[0]
;&TestArray
;
代码中通过以上三种方式中的任意一种方式均可获取到TestArray[4]
数组的首地址,通过第三种方式获取数组首地址时,与其他两种在对首地址使用时表现有可能是不一样的,需要特别注意下,下面会对其应用场景进行举例;
二、应用场景举例
2.1 正常场景
正常场景的代码实现举例如下所示:
#include "stdio.h"
unsigned char TestArray[4] = {11u, 22u, 44u, 55u};
unsigned char TestArray_1[4] = {66u, 77u, 88u, 99u};
void TestArrayDataFun(unsigned char *Data)
{
if (Data != NULL)
{
printf("TestArrayDataFun: %d %d\r\n", *Data, *(Data + 1));
}
}
int main(void)
{
TestArrayDataFun(TestArray);
TestArrayDataFun(&TestArray[0]);
TestArrayDataFun(&TestArray);
return 0;
}
从功能上来看,TestArrayDataFun
函数会输出打印传入指针的第一个和第二个数组元素,对应的就是想输出TestArray
数组的第一个和第二个元素,代码输出结果如下所示:
TestArrayDataFun: 11 22
TestArrayDataFun: 11 22
TestArrayDataFun: 11 22
从输出结果来看,三种获取数组首地址的方式是一样的。
2.2 异常场景
异常场景的代码实现举例如下所示:
#include "stdio.h"
unsigned char TestArray[4] = {11u, 22u, 44u, 55u};
unsigned char TestArray_1[4] = {66u, 77u, 88u, 99u};
void TestArrayDataFun(unsigned char *Data)
{
if (Data != NULL)
{
printf("TestArrayDataFun: %d %d\r\n", *Data, *(Data + 1));
}
}
int main(void)
{
TestArrayDataFun(TestArray);
TestArrayDataFun(&TestArray[0]);
TestArrayDataFun(&TestArray);
TestArrayDataFun(TestArray + 1);
TestArrayDataFun(&TestArray[0] + 1);
TestArrayDataFun(&TestArray + 1);
return 0;
}
从上述代码的逻辑来看,想要实现的功能是分别采用三种获取数组首地址的方式来打印出数组的第一个和第二个元素以及数组的第二个和第三个元素,最终代码执行后的结果如下所示:
TestArrayDataFun: 11 22
TestArrayDataFun: 11 22
TestArrayDataFun: 11 22
TestArrayDataFun: 22 44
TestArrayDataFun: 22 44
TestArrayDataFun: 66 77
前5个输出的结果与我们预期的一致,但是最后一个输出的结果与我们预期的不一致,大家可以仔细看下代码逻辑,输出的66和77是TestArray_1
数组的第一个和第二个元素,并非TestArray
数组的第二个和第三个元素,这是因为什么呢?
三、总结
直接说结论,以&TestArray
方式获取数组首地址指针,其指针类型为整个数组大小对应的指针类型,在对其指针进行+1操作时,其指针偏移直接偏移了整个数组的大小,即偏移到了TestArray_1
数组的首地址位置,所以再去提取数据时就取到了TestArray_1
数组的第一个和第二个元素。
而为什么调用 TestArrayDataFun(&TestArray);
函数,在函数内部进行+1操作就没有问题呢,是因为传参时相当于进行的强制类型转换,将其指针类型强转为unsigned char *
,因此后续对其进行+1操作时只偏移了一个字节的地址;