指向数组第一个元素之前的指针

2023-11-27

在 C 语言中据说当指针引用同一个数组或超出该数组末尾的一个元素时,算术和比较就得到了明确的定义。那么数组第一个元素之前的一个呢?只要我不取消引用它就可以吗?

Given

int a[10], *p;
p = a;

(1)这样写是否合法--p?

(2)这样写是否合法p-1在一个表达式中?

(3)如果(2)可以,我可以断言p-1 < a?

对此有一些实际的担忧。考虑一个reverse()反转以结尾的 C 字符串的函数'\0'.

#include <stdio.h>

void reverse(char *p)
{
    char *b, t;

    b = p;
    while (*p != '\0')
        p++;
    if (p == b)      /* Do I really need */
        return;      /* these two lines? */
    for (p--; b < p; b++, p--)
        t = *b, *b = *p, *p = t;
}

int main(void)
{
    char a[] = "Hello";

    reverse(a);
    printf("%s\n", a);
    return 0;
}

我真的需要检查代码吗?

请从语言律师/实践的角度分享您的想法,以及您将如何应对这种情况。


(1)--p这样写合法吗?

正如 C 语法所允许的那样,它是“合法的”,但它会调用未定义的行为。为了查找标准中的相关部分,--p相当于p = p - 1(除了p仅评估一次)。然后:

C17 6.5.6/8

如果两个指针 操作数和结果指向同一个数组对象的元素,或者指向最后一个元素 数组对象的元素,求值不得产生溢出;否则,行为是未定义的。

The 评估调用未定义的行为,这意味着您是否取消引用指针并不重要 - 您已经调用了未定义的行为。

此外:

C17 6.5.6/9:

当两个指针相减时,两个指针都应指向同一个数组对象的元素,或者指向数组对象最后一个元素之后的一个;

如果您的代码违反了 ISO 标准中的“应”,则会调用未定义的行为。

(2) 表达式中写p-1是否合法?

与 (1) 相同,未定义的行为。


至于这在实践中如何导致问题的示例:想象一下数组被放置在有效内存页的最开始处。当您在该页面之外递减时,可能会出现硬件异常或指针陷阱表示。对于微控制器来说,这并不是完全不可能的情况,特别是当它们使用分段内存映射时。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

指向数组第一个元素之前的指针 的相关文章

随机推荐

  • 打开通知后导航到屏幕?

    我正在使用 Firebase 云功能向特定设备发送远程通知 我得到了他的 FCM 令牌 我收到了它并且工作得很好 这是我通过云函数发送通知的代码 const functions require firebase functions cons
  • Selenium WebDriver RuntimeException:进程拒绝在 10 秒后死亡,并且无法执行任务终止它:无法找到可执行文件:taskkill

    public class Second private WebDriver driver private boolean acceptNextAlert true private StringBuffer verificationError
  • 如何在AWS EC2中部署create-react-app

    我正在使用react router 所以我想在AWS Ec2中托管 如何部署应用程序并在后台永久运行或让我知道是否有其他方式 您可以使用亚马逊 S3 在本地实例中执行 npm run build 将文件上传到 S3 存储桶实例 可以选择静态
  • Java 8 DateTimeFormatter 在为零时会丢弃毫秒?

    这看起来很奇怪 Java 8 根据 millis 是否为零来格式化输出 如何强制 Java 8 1 8 0 20 始终输出毫秒 无论它们是否为零 public static void main String args TemporalAcc
  • Ruby BitTorrent 库 [关闭]

    Closed 这个问题需要细节或清晰度 目前不接受答案 我正在考虑用 ruby 编写定制的 torrent 客户端 我找到了以下库 正如马特下面指出的那样 它们相当古老 不过 我想听听我可能错过的任何图书馆 并且我很想听听社区对以下图书馆的
  • LD JSON 中的 Javascript

    我想知道是否可以在 ld json 脚本中执行一些 javascript 例如 window location hostname 不 application ld json 类型的脚本不会被执行 但是 你可以这样做
  • 如何从 Startup.cs 中写入日志?

    为了调试启动时失败的 NET Core应用程序 我想从startup cs文件中写入日志 我在文件中进行了日志记录设置 可以在startup cs 文件之外的应用程序的其余部分使用该设置 但不确定如何从startup cs 文件本身写入日志
  • React 原生 Base64 编码字符串

    我正在尝试使用来自的 base 64 库 https github com mathiasbynens base64 当我运行测试来验证代码时 我没有得到正确的结果 还有其他我可以使用的库吗 这是我运行的代码和得到的结果 import ut
  • 将旋转变换设置为 UIView 或其图层似乎不起作用?

    我试图在我的屏幕中拥有一个子视图 由一个视图控制器拥有 not当设备旋转时旋转 我的视图控制器允许按其应有的方式进行旋转 并且我尝试将 90 度旋转应用于一个 静止 视图以抵消整体旋转 问题是 无论如何 一切似乎都在旋转 而变换似乎没有做任
  • 将字节数组从 Oracle RAW 转换为 System.Guid?

    我的应用程序使用使用 DataReaders 在 ADO NET 中编写的自定义数据访问层与 Oracle 和 SQL Server 数据库进行交互 现在 我在 GUID 我们用作主键 和 Oracle RAW 数据类型之间的转换时遇到问题
  • firebase 部署时出现 NPM 错误 --only 函数的原因是什么

    我最近在尝试部署我的 firebase 功能时收到此错误 但是 自上次成功部署以来我没有更改任何依赖项 functions all necessary APIs are enabled i functions preparing funct
  • AutoFixture CompositeDataAttribute 不适用于 PropertyDataAttribute

    我正在尝试创建AutoPropertyDataAttribute基于CompositeDataAttribute从这个例子AutoFixture PropertyData 和异构参数 它适用于单组参数 但适用于更多组参数 这是代码 publ
  • 在 foreach 循环声明中使用 LINQ

    直接在 foreach 循环声明中声明 LINQ 是一种不好的做法吗 在表现或微妙的行为差异方面 例如 foreach string name in persons Select x gt x name Do something with
  • 获取 OSX 连接的 Wi-Fi 网络名称

    我需要获取 OSX 上当前连接的 Wi Fi SSID 的名称 我搞乱了 SystemConfiguration 框架 我觉得它就在那里 因为我能够获取网络位置的名称 但我并没有真正找到获取 Wi Fi SSID 的方法 将不胜感激任何帮助
  • rvm安装:ruby安装错误

    我想在我的 Linux Mint 12 上安装 ruby 我正在关注本教程 and this one 当我跑步时rvm install 1 9 3我看到这个错误 Installing Ruby from source to usr shar
  • 如何在 Swift 中解码 HTML 实体?

    我正在从网站提取 JSON 文件 收到的字符串之一是 The Weeknd 8216 King Of The Fall 8217 Video Premiere TheWeeknd SoPhi 我怎样才能转换类似的东西 8216变成正确的字符
  • 如何在 Java 中迭代字符串?

    public static Boolean cmprStr String s1 String s2 STUFF 我想迭代 s1 以确保 s1 中的每个字符都包含在 s2 中 public static Boolean cmprStr Str
  • django-allauth 将用户名设置为与电子邮件相同

    我有一个注册表单 只要求提供电子邮件和密码 当用户注册时 django allauth 通过从用户的电子邮件地址中去除 email 后缀来为该用户创建一个用户名 例如 如果用户使用 电子邮件受保护 他的用户名是 某些用户 并且如果另一个用户
  • ggplot 单个条上的透明度

    我目前正在尝试使用 ggplot 创建一个条形图 其中单个条形部分透明 我有以下代码 dt1 lt data table yr c 2010 2010 2011 2011 val c 1500 3000 2000 1100 x c a b
  • 指向数组第一个元素之前的指针

    在 C 语言中据说当指针引用同一个数组或超出该数组末尾的一个元素时 算术和比较就得到了明确的定义 那么数组第一个元素之前的一个呢 只要我不取消引用它就可以吗 Given int a 10 p p a 1 这样写是否合法 p 2 这样写是否合