【C 陷阱与缺陷】(三)语义陷阱

本文深入探讨了C语言中的数组与指针的关系,包括数组的声明、指针的用法、数组与指针的转换、二维数组的操作,以及在编程中可能出现的陷阱,如边界计算错误、指针运算的误解等。通过实例解析了常见的编程错误,强调了正确理解和使用数组和指针的重要性。
摘要由CSDN通过智能技术生成

码字不易,对你有帮助 点赞/转发/关注 支持一下作者

微信搜公众号:不会编程的程序圆

看更多干货,获取第一时间更新

代码,练习上传至:https://github.com/hairrrrr/C-CrashCourse

0. 指针与数组

C 语言中数组与指针这两个概念之间的联系密不可分。

关于数组:
  • C 语言中只有一维数组,而且数组大小必须在编译期就作为一个常数确定下来。数组元素可以是任何类型的对象,也可以是另外一个数组。(C99 允许变长数组)
  • 对于一个数组,我们只能够做两件事:确定该数组的大小,以及获得指向该数组下标为 0 的元素的指针。

任何一个数组下标运算都等同于一个对应的指针运算。

声明数组

int a[3];

声明了一个拥有 3 个整型元素的数组。

struct{
   
    int p[4];
    double x;
}b[14];

声明了一个拥有 17 个元素的数组,且每个元素都是一个结构。

int calendar[12][31];

声明了拥有 12 个数组类型的元素,其中每个元素都是拥有 31 个整型元素的数组。因此 sizeof(calendar)的值是 12x31 与 sizeof(int)的乘积。

关于指针

任何指针都是指向某种类型的变量。

int *ip;

表明 ip 是一个指向整型变量的指针。

我们可以将整型变量 i 的地址赋值给指针 ip :

int i;
ip = &i;

如果我们给 *ip 赋值,就可以改变 i 的取值:

*ip = 17;
数组与指针

如果一个指针指向的是数组中的一个元素,那么我们只要给这个指针加 1,就能够得到指向该数组中下一个元素的指针。减法同理。

如果两个指针指向的是同一个数组中的元素,那么两个指针相减是有意义的:

int *q = p + i;

我们可以通过 q - p 得到 i 的值。

int a[3];
int* p = a;

数组名被当作指向数组下标为 0 的元素的地址。

注意,我们没有写成:

p = &a;

这样的写法在 ANSI C 中是非法的,因为 &a是一个指向数组的指针,而 p 是指向整型变量的指针,它们了类型并不匹配。

继续我们的讨论,现在 p 指向数组 a 中下标为 0 的元素,p + 1 指向下标为 1 的元素,以此类推。如果希望 p 指向下标为 1 的元素,可以这样写:

p = p + 1;

当然,也可以这样写:

p++;

*a 是数组 a 中下标为 0 的元素的引用。同理,*(a + 1)是数组中下标为 1 的元素的引用,*(a + i)是数组中下标为 i 的元素的引用,简写为 a[i]

由于 a + ii + a的含义一致,因此a[i]i[a]也具有相同的含义。但我们绝不推荐这种写法。

二维数组
int calendar[12][31];

请思考,calendar[4]含义是什么?

calender[4]是 calendar 数组第 5 个元素,是 calendar 数组 12 个拥有着 31 个整型元素的数组之一。sizeof(calendar[4])大小为 31 与 sizeof(int)的乘积。

p = calendar[4];

这个语句使 p 指向了数组 calendar 下标为 0 的元素。

如果 calendar 是数组,我们可以:

i = calender[4][7];

上式等价于:

i = *(calender[4] + 7);

等价于:

i = *(*(calender + 4) + 7);

下面我们再看:

p = calender;

这个语句是非法的。因为 calendar 是一个二维数组,即数组的数组,calendar 是一个指向数组的指针,而 p 是指向整型变量的指针。

我们需要声明

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值