如何解决添加解引用指针时的操作顺序
我在 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
表达式不是这样执行的:
- 添加指向char数组第一个元素的指针:str+str
- 将结果指针增加 4 并取消引用它(哪个应该返回一个字符?)
- 从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 举报,一经查实,本站将立刻删除。