添加解引用指针时的操作顺序

如何解决添加解引用指针时的操作顺序

我在 c 中得到了这些代码行,并要求我解释其输出:

char  str [50] = "hello \0 worl\bd";
printf("\n %s ",str);
printf("%s \n",str+str[4]-*str);

输出:

 hello   word

根据我的理解,第二行打印字符串直到表示结束的 '\0' 字符。 然后第三个代码添加字符串的其余部分(从 'w' 之前的空格开始,跳过 'l',因为它被退格键覆盖。

我不明白的是表达式中到底发生了什么:

str+str[4]-*str

表达式不是这样执行的:

  1. 添加指向char数组第一个元素的指针:str+str
  2. 将结果指针增加 4 并取消引用它(哪个应该返回一个字符?)
  3. 从2的字符中减去*char返回的字符。?

似乎不是这样。有人可以向我解释这里到底发生了什么吗? 非常感谢!

解决方法

在这个表达式中:

str+str[4]-*str

数组下标运算符[]具有最高优先级,其次是解引用运算符*,其次是具有相同优先级的+-对。所以上面是一样的:

(str+(str[4]))-(*str)

那么会发生什么是数组 str 被转换为指向它的第一个元素的指针,然后将 str[4] 的字符代码添加到该指针,然后是 {{1} 的字符代码}(或等效的 *str)从中减去。

代入有问题的字符,上面是一样的:

str[0]

假设为 ASCII 编码,则与以下内容相同:

(str + 'o') - 'h'

但现在我们遇到了一个问题。

子表达式 (str + 111) - 104 创建一个指针,它远远超过数组的末尾,这样做会调用 undefined behavior,因此您的程序格式不正确。下一个操作似乎会给你一个有效的指针并不重要。只是创建指针值 str + 111 是无效的。

这在 C standard 的第 6.5.6p8 节中关于指针加法/减法的描述:

当一个具有整数类型的表达式与指针相加或相减时,结果具有指针操作数的类型。如果指针操作数指向一个元素或扇形数组对象,并且数组足够大,则结果指向与原始元素的元素偏移量,使得结果和原始数组元素的下标之差等于整数表达式。 ... 如果指针操作数和结果都指向同一个数组对象的元素,或者数组对象的最后一个元素之后,则评估不应产生溢出;否则,行为未定义。

因此,您很“幸运”,程序正在生成输出,乍一看似乎是预期的。

如果是这样写的:

str + 111

该程序会很好地形成。

,
str[4]='o' // 111 in ascii
*str='h'   // 104 in ascii

str+str[4]-*str= str+111-104=&str[7] => ' worl\bd'
,

给定

char  str [50] = "hello \0 worl\bd";

代码

str+str[4]-*str

评估为

str + 'o' - 'h'

因为 str[4] 是字符 'o',而 *str 是字符 'h'

请注意,从指针中添加(或减去)整数类型值的结果是另一个指针值。

但我们不知道 'o''h'是什么,因为问题没有指定字符集。

如果我们不加说明地假设字符集是ASCII,那么字符'o'是整数值111,而'h'是整数值104,所以价值是

str + 111 - 104

(但请参阅@dbush 的 answer,因为 str + 111 - 104 被评估为 ( str + 111 ) - 104 并且 str + 111 调用未定义的行为,因为它远远超过了 str 数组的末尾)

str + 7

所以它是 str - &str[7] 中第七个字符的地址:

printf("\n %s ",str);

会发射

"\n hello "

不带引号(引号用于显示尾随空格),以及

printf("%s \n",str+str[4]-*str);

printf( "%s \n" str + 7 );

并且会发射

" worl\bd \n"

再次没有引号。但是 '\b' 是退格字符,因此您可能会看到

" word \n"

打印在您的屏幕上 - 可能。

但问题中有一些假设阻止任何人明确说明将输出什么:

  • 字符集可能不是 ASCII,在这种情况下,程序可能会调用未定义的行为
  • 显示媒体可能无法按预期处理退格字符

没有这些信息,就无法回答问题。

C 语言中的精确性很重要。像这样的问题如果没有准确指定能够回答问题所需的条件和环境,那是可怕的,而且经过深思熟虑。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


使用本地python环境可以成功执行 import pandas as pd import matplotlib.pyplot as plt # 设置字体 plt.rcParams['font.sans-serif'] = ['SimHei'] # 能正确显示负号 p
错误1:Request method ‘DELETE‘ not supported 错误还原:controller层有一个接口,访问该接口时报错:Request method ‘DELETE‘ not supported 错误原因:没有接收到前端传入的参数,修改为如下 参考 错误2:cannot r
错误1:启动docker镜像时报错:Error response from daemon: driver failed programming external connectivity on endpoint quirky_allen 解决方法:重启docker -> systemctl r
错误1:private field ‘xxx‘ is never assigned 按Altʾnter快捷键,选择第2项 参考:https://blog.csdn.net/shi_hong_fei_hei/article/details/88814070 错误2:启动时报错,不能找到主启动类 #
报错如下,通过源不能下载,最后警告pip需升级版本 Requirement already satisfied: pip in c:\users\ychen\appdata\local\programs\python\python310\lib\site-packages (22.0.4) Coll
错误1:maven打包报错 错误还原:使用maven打包项目时报错如下 [ERROR] Failed to execute goal org.apache.maven.plugins:maven-resources-plugin:3.2.0:resources (default-resources)
错误1:服务调用时报错 服务消费者模块assess通过openFeign调用服务提供者模块hires 如下为服务提供者模块hires的控制层接口 @RestController @RequestMapping("/hires") public class FeignControl
错误1:运行项目后报如下错误 解决方案 报错2:Failed to execute goal org.apache.maven.plugins:maven-compiler-plugin:3.8.1:compile (default-compile) on project sb 解决方案:在pom.
参考 错误原因 过滤器或拦截器在生效时,redisTemplate还没有注入 解决方案:在注入容器时就生效 @Component //项目运行时就注入Spring容器 public class RedisBean { @Resource private RedisTemplate<String
使用vite构建项目报错 C:\Users\ychen\work>npm init @vitejs/app @vitejs/create-app is deprecated, use npm init vite instead C:\Users\ychen\AppData\Local\npm-
参考1 参考2 解决方案 # 点击安装源 协议选择 http:// 路径填写 mirrors.aliyun.com/centos/8.3.2011/BaseOS/x86_64/os URL类型 软件库URL 其他路径 # 版本 7 mirrors.aliyun.com/centos/7/os/x86
报错1 [root@slave1 data_mocker]# kafka-console-consumer.sh --bootstrap-server slave1:9092 --topic topic_db [2023-12-19 18:31:12,770] WARN [Consumer clie
错误1 # 重写数据 hive (edu)> insert overwrite table dwd_trade_cart_add_inc > select data.id, > data.user_id, > data.course_id, > date_format(
错误1 hive (edu)> insert into huanhuan values(1,'haoge'); Query ID = root_20240110071417_fe1517ad-3607-41f4-bdcf-d00b98ac443e Total jobs = 1
报错1:执行到如下就不执行了,没有显示Successfully registered new MBean. [root@slave1 bin]# /usr/local/software/flume-1.9.0/bin/flume-ng agent -n a1 -c /usr/local/softwa
虚拟及没有启动任何服务器查看jps会显示jps,如果没有显示任何东西 [root@slave2 ~]# jps 9647 Jps 解决方案 # 进入/tmp查看 [root@slave1 dfs]# cd /tmp [root@slave1 tmp]# ll 总用量 48 drwxr-xr-x. 2
报错1 hive> show databases; OK Failed with exception java.io.IOException:java.lang.RuntimeException: Error in configuring object Time taken: 0.474 se
报错1 [root@localhost ~]# vim -bash: vim: 未找到命令 安装vim yum -y install vim* # 查看是否安装成功 [root@hadoop01 hadoop]# rpm -qa |grep vim vim-X11-7.4.629-8.el7_9.x
修改hadoop配置 vi /usr/local/software/hadoop-2.9.2/etc/hadoop/yarn-site.xml # 添加如下 <configuration> <property> <name>yarn.nodemanager.res