0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

C语言指针运算符详解

嵌入式爱好者之家 来源:嵌入式爱好者之家 2024-10-30 11:16 次阅读

概述

C语言中,当你有一个指向数组中某个元素的指针时,你可以对该指针执行某些算术运算,例如加法或减法。这些运算可以用来遍历数组中的元素,如ptr[i]等价于*(ptr + i)。然而,如果你的操作使得指针指向了数组以外的位置(除了数组结束位置之后的一个位置之外),那么这个指针的行为就是未定义的。

例如:

如果ptr指向数组的第一个元素,那么ptr + 1将指向第二个元素。

如果ptr指向数组的最后一个元素,那么ptr + 1将指向数组结束之后的一个虚构位置,这是允许的,但是试图访问该位置(如*(ptr + 1))将导致未定义行为。

如果ptr指向数组的最后一个元素,那么ptr + 2指向的位置超出了数组的范围,这将导致未定义行为。

未定义行为意味着编译器可以做出任何事情,包括但不限于程序崩溃、数据损坏或其他不可预测的结果。因此,在编写涉及指针操作的代码时,确保指针始终在安全范围内是非常重要的。在实际编程中,常常会用到边界检查来防止这类问题的发生。

详述

创建一个指向数组末尾之后的指针在标准中是有明确定义的,并且本规则允许这种操作。但是,引用通过这种方式创建的指针会导致未定义的行为,并且此规则禁止这样做。

本规则适用于所有形式的数组索引

整数表达式 + 整数表达式

指针表达式 + 整数表达式

指针表达式 += 整数表达式

指针表达式 -= 整数表达式

++ 指针表达式

-- 指针表达式

指针表达式++

指针表达式--

整数表达式 [指针表达式]

指针表达式 [整数表达式]

注意:对于指针算术的目的,标准将不是数组成员的对象视为具有单个元素的数组。

理由

虽然一些编译器可以在编译时确定数组边界是否超出,但在运行时通常不会对无效数组下标进行检查。使用无效数组下标可能导致程序出现错误行为。

由于它们不容易通过静态分析或手动审查来检查,因此运行时推导出的数组下标值最令人担忧。如果可能的话,应该提供代码以检查此类下标值的有效性,并根据需要采取适当的行动。

如果从上述表达式之一获得的结果不是一个指向由指针表达式所指向的数组元素或一个超过该数组末尾的一个元素的指针,则其行为是未定义的。有关更多信息,请参阅C90第6.3.6节、C99第6.5.6节。

多维数组是“数组的数组”。本规则不允许导致指针指向不同子数组的指针算术。不应使用数组下标跨越“内部”边界的数组下标,因为这样的行为是未定义的。

示例

使用+运算符也会违反规则18.4。

int32_t f1( int32_t * const a1, int32_t a2[10][1]) 
{
  /* Compliant/non-Compliant depending on the value of a1 */
  int32_t *p = &a1[3];     
return*(a2+9);/*Compliant*/
}


void f2(void)
{
    int32_t data = 0;
    int32_t b = 0;
    int32_t c[10] = {0};
    // 5-element array of 2-element arrays of int32_t
    int32_t d[5][2] = {0}; 
 
    int32_t *p1 = &c[0];    //Compliant
    int32_t *p2 = &c[10];   // Compliant - points to one beyond
    int32_t *p3 = &c[11];   // Non - compliant - undefined, points to two beyond
    
    data = *p2;




    data = f1(&b, c);
    data = f1(c, c);
    
    p1++;         /*Compliant*/
    c[-1] = 0;    /*Non-Compliant - undefined, array bounds exceeded*/
    data = c[10];    /*Non-Compliant - undefined,dereference of address one beyond*/
   
    d[3][1] = 0;         /*Compliant*/
    data = *(*(d + 3) + 1);      /*Compliant*/
    data = d[2][3];      /*Non-compliant - undefined, internal boundary exeeded*/
    
    p1 = d[1];
    data = p1[1];
}


声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • C语言
    +关注

    关注

    180

    文章

    7597

    浏览量

    136114
  • 指针
    +关注

    关注

    1

    文章

    479

    浏览量

    70506
  • 运算符
    +关注

    关注

    0

    文章

    172

    浏览量

    11062

原文标题:Rule18.1 指针运算符的结果应指向与该指针运算符相同的数组元素,否则其行为是未定义的

文章出处:【微信号:嵌入式爱好者之家,微信公众号:嵌入式爱好者之家】欢迎添加关注!文章转载请注明出处。

收藏 人收藏

    评论

    相关推荐

    C语言基础知识(4)--运算符

    C语言中,运算符包括有算术运算符、关系运算符、逻辑运算符和位
    的头像 发表于 06-15 09:38 3367次阅读

    C语言中赋值运算符详解

    C语言中,赋值运算符用于将一个值赋给变量。
    发表于 08-18 16:38 1816次阅读
    <b class='flag-5'>C</b><b class='flag-5'>语言</b>中赋值<b class='flag-5'>运算符</b><b class='flag-5'>详解</b>

    C语言运算符的使用方法

    详细介绍了C语言表达式、算术运算符、赋值运算符、关系运算符、条件结构、逻辑运算符、位
    发表于 11-02 11:30 1474次阅读
    <b class='flag-5'>C</b><b class='flag-5'>语言</b><b class='flag-5'>运算符</b>的使用方法

    【跟我学单片机C语言详解运算符和表达式的位运算符

    【跟我学单片机C语言详解运算符和表达式的位运算符学过汇编的朋友都知道汇编对位的处理能力是很强的,但是单片机C
    发表于 12-07 13:51

    C语言运算符优先级(超详细)

    C语言运算符优先级(超详细) 当想找哪个运算符优先级高时,很多时候总是想找的就没有,真让人气愤!现在,终于有个我个人觉得非常全的,分享给大家,欢迎拍砖!
    发表于 04-27 16:47

    C语言程序设计--运算符与表达式

    c语言对数据有很强的表达能力,具有十分丰富的运算符,利用这些运算符可以组成各种表达式及语句。运算符就是完成某种特定
    发表于 07-14 21:30 46次下载

    C语言入门教程-运算符优先级

    运算符优先级C语言有丰富的运算符。如果不清楚这些运算符的优先级,则在同时使用多个运算符时就容易产
    发表于 07-29 14:21 1298次阅读

    单片机C语言教程-运算符和表达式

    单片机C语言教程-运算符和表达式   单片机C语言教程-运算符和表达式  
    发表于 03-27 17:13 2211次阅读

    C语言运算符的使用

    C语言运算符的使用,感兴趣的小伙伴们可以瞧一瞧。
    发表于 08-23 17:56 0次下载

    C运算符的优先级和结合性详细解决

    运算符是一种告诉编译器执行特定的数学或逻辑操作的符号。 C语言内置了丰富的运算符,大体可分为10类:算术运算符、关系
    的头像 发表于 02-22 17:27 3200次阅读

    C语言总结_语句、运算符

    当前文章复盘C语言的: 位运算运算符、基本运算符、数据类型、变量、for语句、while语句、goto语句、switch语句、
    的头像 发表于 08-14 09:39 975次阅读

    c语言运算符及例题

    C语言中逻辑运算符包含逻辑与&&、逻辑或||、逻辑非!三种。其中逻辑与&&是双目运算符,即需要运算符两边都要有表达式,且两边表达式都为真,此
    发表于 02-16 16:14 0次下载

    C语言运算符

    C语言中,我们常常会用到表达式,在使用表达式的过程中便会使用到运算符C语言中,不同的运算符
    的头像 发表于 02-21 15:12 1151次阅读
    <b class='flag-5'>C</b><b class='flag-5'>语言</b>的<b class='flag-5'>运算符</b>

    C语言中什么是关系运算符

    C语言中,比较称为关系运算符,所谓关系运算就是比较运算,将两个数值进行比较,判断其比较的结果
    的头像 发表于 03-09 10:47 2367次阅读

    c语言从右到左的运算符有哪些

    以下是一些主要的从右到左运算C语言运算符: 函数调用运算符 ( () ):当您调用一个函数时,参数列表是从右到左进行求值的。 后置递增
    的头像 发表于 08-20 11:39 679次阅读