C语言语义缺陷(一)

前言

在一个句子,哪怕其中的每个单词都拼写正确,而且语法也无懈可击,仍然可能有歧义或者并非书写者希望表达的意思。程序也有可能表面上是一个意思,而实际上的意思却相差甚远。本篇讲述了几种可能引起上述歧义的程序书写方式

1、指针与数组

C语言中,指针与数组这两个概念之间的联系是十分密切的

C语言中的数组有两个需要注意的方面:

1、C语言中只有一维数组,而且数组大小在声明数组时就需要确定下来,不过数组中的元素可以是任何类型的对象,当然也可以是另外一个数组,这样要"仿真"出一个多维数组就不是一件难事

C99标准允许变长数组(VLA),GCC编译器中实现了变长数组,但细节与C99标准不完全一致

2、对于一个数组,我们只能做两件事:确定该数组的大小以及获得指向该数组首元素(下标为零)的指针其它有关数组的操作,哪怕它们乍看上去是以数组下标进行运算的,实际上都是通过指针进行的。换句话说,任何一个数组下标运算都等同于一个对应的指针运算,因此我们完全可以依据指针行为定义数组下标的行为。

指针与数组的关系

1、如果一个指针指向的是数组中的第一个元素,那么我们只要给这个指针加/减1,就能够得到指向该数组中下/上一个元素的指针,其它数字同理类推

这句话暗示了这样一个事实:给一个指针加上一个整数,与给该指针的二进制表示加上同样的整数,二者的含义截然不同。如果指针ip指向一个整数,那么ip+1指向的是该计算机内存中的下一个整数,在大多数现代计算机中,它都不同于ip所指向地址的下一个内存位置

2、如果两个指针指向同一数组中的元素,这两个指针相减的结果是有意义的:

cpp 复制代码
int *q = p + i;

p指针与q指针的差值就是两指针指向的元素之间的位置的差值(意思是这个意思) ,但是如果它们指向的不是同一个数组,那么即使它们所指向的地址在内存中的位置正好间隔一个数组元素的整数倍,所得的结果仍然无法保证其正确性

**3、如果我们在该出现指针的地方,采用了数组名代替,**数组名就是该数组首元素的地址:

cpp 复制代码
//正确,将数组a中下标为0的元素的地址赋值给了指针p
p = a
//错误
p = &a

p=&a这种写法在ANSI C标准中是非法的,因为**&a是一个指向数组的指针此时取出的地址是整个数组的地址而非数组首元素的地址,而p是一个指向整型变量(数组中某个整型元素)的指针,它们的类型不匹配。**

4、p是一个指向数组的指针,p = p + 1 == p++

5、*数组名,此时的数组名表示数组首元素地址,该语句可以将数组首元素的值替换

cpp 复制代码
*a = 84;

它等价于*(a+0),同理,*(a+1)是数组a中下标为1的元素的引用,依次类推。概而言之,*(a+i)即数组a中下标为i的元素的引用,由于这种写法十分常用,所以C语言将它变为了另一种形式a[i],

a[i] == *(a+i)
~未完待续~

2、非数组的指针

3、作为参数的数组声明

4、避免"穷隅法"

5、空指针并非空字符串

~over~

相关推荐
L_autinue_Star1 小时前
手写vector容器:C++模板实战指南(从0到1掌握泛型编程)
java·c语言·开发语言·c++·学习·stl
元气小嘉1 小时前
前端技术小结
开发语言·前端·javascript·vue.js·人工智能
怀旧,1 小时前
【数据结构】8. 二叉树
c语言·数据结构·算法
励志的大鹰哥2 小时前
V少JS基础班之第七弹
开发语言·javascript·ecmascript
AI360labs_atyun2 小时前
Java在AI时代的演进与应用:一个务实的视角
java·开发语言·人工智能·科技·学习·ai
凤年徐3 小时前
【数据结构与算法】203.移除链表元素(LeetCode)图文详解
c语言·开发语言·数据结构·算法·leetcode·链表·刷题
学废了wuwu3 小时前
深度学习归一化方法维度参数详解(C/H/W/D完全解析)
c语言·人工智能·深度学习
nbsaas-boot3 小时前
多租户架构下的多线程处理实践指南
java·开发语言·spring
无小道3 小时前
c++--typedef和#define的用法及区别
c语言·开发语言·汇编·c++
SoniaChen334 小时前
Rust基础-part2-变量和可变类型
开发语言·后端·rust