关于C/C++语言中 '/xxx' 的用法

我叫RT 2020-04-06 01:18:07
图一:此图为使用 '/xxx' 方式,int 类型和char 类型的接收结果对比图

图二:此图为上图的16进制整数输出图。

图三:此图为使用 '/' 除号 和 '\' 转义符 赋值的对比图。


如题,在翻阅以前的博客时,发现自己曾偶然发现使用 char ch = '/123' 的方式可以成功将 ch 赋值为3。而后在进过一系列测试发现,实际上从 ‘/0’开始返回的是一个很大的整数,用16进制表示就是 0x2f30。而后逐次往上加。但是这么久以来始终没搞懂原因。

并且,使用 '/xxx' 除号的方式可以与 '\'转义字符+8进制('\xxx')的方式给char型变量赋值有同等的效果。但他们又有不同点,主要区别有下:
使用 '\xxx' 给char型变量赋值,实际上是把8进制转换成10进制,在根据相应的10进制数ascii转换为对应字符。如:ch='\12',此时ch的值为'/n'。换行符(\n)的ascii值为10.
使用 '/xxx' 返回的是一个很大的整数,使用这种方式给char类型赋值,会得到 '/xxx' 中最后一个字符。如: ch='/abc',此时ch的值为字符'c'。
另外,'\xxxxxx' 使用转义字符+8进制的方式,如果超出3为8进制数或前三位中有非8进制数就会停止转换,直接取最后一位元素的值。
如:ch1='\a1'; ch2='\0001'; 这两种方式得到的ch都为ascii值 1。
而 '/xxx' 最多只支持输入3位,并且不论输入什么内容,char类型变量ch都值保留最后一位元素,并且是以字符的形式存储。

网上也没找到啥有用的资料,只能求助bss的大神了。
...全文
290 11 打赏 收藏 转发到动态 举报
写回复
用AI写文章
11 条回复
切换为时间正序
请发表友善的回复…
发表回复
我叫RT 2020-04-06
  • 打赏
  • 举报
回复
引用 2 楼 GKatHere 的回复:
有意思的是,系统有大小端之分。比如windows是小端模式。如果你要用‘0123’来表示字符串,实际windows上字符串是 "3210".
确实有趣。不过这里有一点不懂。如果str存储‘0123’,保存方式为 ‘3210’那么在srt[0]就应该被解析成 '3' 了不是吗。还是说是因为str在栈上开辟,所以在解析str[0]的时候栈顶指针的偏移实际上是偏移到str内存地址的最后一个位置。
昵称名为昵称 2020-04-06
  • 打赏
  • 举报
回复
学习了,mark。
我叫RT 2020-04-06
  • 打赏
  • 举报
回复
引用 1 楼 lin5161678 的回复:
多字节字符常量 这个数值是多个字节组合出来的 实现定义 你可以用%x输出 可以比较清楚的看到多个字节的痕迹 比如 printf("%#X\n", '0123');//输出0X30313233 十六进制30 就是'0' 十六进制31 就是'1' 十六进制32 就是'2' 十六进制33 就是'3' '0123' 就是 这四个字符组合出来的
懂了,多谢。原来是多个字符拼接出来的效果。这么一说我就懂了,我还傻乎乎的分析了半天。
我叫RT 2020-04-06
  • 打赏
  • 举报
回复
引用 3 楼 coo135 的回复:
楼主想歪了哈,重点已框出,供参考。cppreference 链接:https://zh.cppreference.com/w/cpp/language/character_literal
确实一开始就想歪了,当时老师讲课时把 '\' 错用成了 '/' ,但是运行居然没问题。然后自己查资料没有找到,就自己测试了半天。结果原理这么简单。。我还分析了半天它的赋值规律呢
我叫RT 2020-04-06
  • 打赏
  • 举报
回复
好像有点懂了,使用 '/xxx' 的方式其实是一个宽字节的字符 'xxx' ,而c语言中存储变量时是以小端的方式存储,也就是先存储了最后一个字符的一个字节,在存储第二位的,最后在存储第一位的。比如 ch = 'ABC'; 那么,问题来了。如果使用 ch='xxx' 的赋值会不会对栈上其他变量的值进行非法修改呢? 我测试了一下好像是不会修改栈上其他变量的值,应该是char类型在地址解析时只按照char的方式只解析了一个字节。 不知道我这样理解对不对。
coo135 2020-04-06
  • 打赏
  • 举报
回复
楼主想歪了哈,重点已框出,供参考。cppreference 链接:https://zh.cppreference.com/w/cpp/language/character_literal
GKatHere 2020-04-06
  • 打赏
  • 举报
回复
有意思的是,系统有大小端之分。比如windows是小端模式。如果你要用‘0123’来表示字符串,实际windows上字符串是 "3210".
lin5161678 2020-04-06
  • 打赏
  • 举报
回复
多字节字符常量
这个数值是多个字节组合出来的
实现定义
你可以用%x输出 可以比较清楚的看到多个字节的痕迹
比如
printf("%#X\n", '0123');//输出0X30313233
十六进制30 就是'0'
十六进制31 就是'1'
十六进制32 就是'2'
十六进制33 就是'3'
'0123' 就是 这四个字符组合出来的
我叫RT 2020-04-06
  • 打赏
  • 举报
回复
引用 10 楼 lin5161678 的回复:
[quote=引用 8 楼 我叫RT 的回复:] [quote=引用 2 楼 GKatHere 的回复:] 有意思的是,系统有大小端之分。比如windows是小端模式。如果你要用‘0123’来表示字符串,实际windows上字符串是 "3210".
确实有趣。不过这里有一点不懂。如果str存储‘0123’,保存方式为 ‘3210’那么在srt[0]就应该被解析成 '3' 了不是吗。还是说是因为str在栈上开辟,所以在解析str[0]的时候栈顶指针的偏移实际上是偏移到str内存地址的最后一个位置。 [/quote]你的图画错了 是char str = '0123' 单引号 [/quote] 好吧,我会错意了。刚开始你回复的是 存储'0123'字符串,我以为你说的是字符串的存储方式,所以我说咋想都不对。其实你说的是单个字符的存储方式吧。这个我知道,就像 char ch = '0123' 。因为是采用小端存储方式,先存储低位,把3存储到ch,然后因为ch是char类型所以只能容纳一个字节,然后就存储了一个字节,因此 ch = '3' 。 在比如,存放int类型,int a = 10; , 十进制10的16进制为 0x0000 000A,用小端的方式存先存低位的 0A,然后存00 00 00。 如果我们把a强转修改其中的数值,就能验证。 int a = 10; // 0x0000 000A 修改a的第一字节的数据。 *(char*)&a = 1; // 0x0000 0001 可以看到,我们修改的第一字节的数据,却把低位的 0A修改成了 01 修改第四字节的数据。 *((char*)&a+3) = 1; // 0x0100 0001 可以看到,我们修改第四字节的数据,却把高位的00 修改成了 01. 你看是不是这个意思。
lin5161678 2020-04-06
  • 打赏
  • 举报
回复
引用 8 楼 我叫RT 的回复:
[quote=引用 2 楼 GKatHere 的回复:]
有意思的是,系统有大小端之分。比如windows是小端模式。如果你要用‘0123’来表示字符串,实际windows上字符串是 "3210".

确实有趣。不过这里有一点不懂。如果str存储‘0123’,保存方式为 ‘3210’那么在srt[0]就应该被解析成 '3' 了不是吗。还是说是因为str在栈上开辟,所以在解析str[0]的时候栈顶指针的偏移实际上是偏移到str内存地址的最后一个位置。
[/quote]你的图画错了
是char str = '0123'
单引号
lin5161678 2020-04-06
  • 打赏
  • 举报
回复
引用 8 楼 我叫RT 的回复:
[quote=引用 2 楼 GKatHere 的回复:]
有意思的是,系统有大小端之分。比如windows是小端模式。如果你要用‘0123’来表示字符串,实际windows上字符串是 "3210".

确实有趣。不过这里有一点不懂。如果str存储‘0123’,保存方式为 ‘3210’那么在srt[0]就应该被解析成 '3' 了不是吗。还是说是因为str在栈上开辟,所以在解析str[0]的时候栈顶指针的偏移实际上是偏移到str内存地址的最后一个位置。
[/quote]str的值是一个溢出结果

69,382

社区成员

发帖
与我相关
我的任务
社区描述
C语言相关问题讨论
社区管理员
  • C语言
  • 花神庙码农
  • 架构师李肯
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧