文章详情

  • 游戏榜单
  • 软件榜单
关闭导航
热搜榜
热门下载
热门标签
php爱好者> php文档>c,长长见识

c,长长见识

时间:2006-11-30  来源:qfox

以文本方式查看主题

- OldLinux论坛 (http://www.oldlinux.org/cgi-bin/leobbs.cgi)
-- C语言 (http://www.oldlinux.org/cgi-bin/forums.cgi?forum=20)
--- 帮忙看看这个诡异的程序,为什么是这个结果 (http://www.oldlinux.org/cgi-bin/topic.cgi?forum=20&topic=350)

-- 作者: jupitercuso4
-- 发布时间: 2006/02/11 03:39pm

#include<stdio.h>
int main(){
       unsigned char result = 1["night"]*2["girls"]+4["allnight"];
       char *of_you = "Though you was strong enough and seem never died";
       printf("You got %s", result+of_you);
       return 0;
}

-- 作者: jequi
-- 发布时间: 2006/02/11 07:32pm

1["night"]就是*("night"+1),也就是'i',ascii码为105
类似,2["girls"]是'l'(114)
4["allnight"]是'i'(105)
result=(105*114+105)%256=43
result+of_you=43+"Though you was strong enough and seem never died"
指向第43个字符

-- 作者: lgr
-- 发布时间: 2006/02/11 07:58pm

great!

-- 作者: lullaby
-- 发布时间: 2006/05/16 09:31pm

[quote][b]下面引用由[u]jequi[/u]在 [i]2006/02/11 07:32pm[/i] 发表的内容:[/b]
1就是*("night"+1),也就是'i',ascii码为105
类似,2是'l'(114)
4是'i'(105)
result=(105*114+105)%256=43
...
[/quote]
太漂亮了!
真是高手啊!

-- 作者: xiaozhi
-- 发布时间: 2006/05/27 02:23am

    这是什么语法,怎么没有见过,能说得具体点吗...?

-- 作者: dabang007
-- 发布时间: 2006/06/14 09:05am

jequi 能否解释一下怎么知道这些语法的?

-- 作者: zql2003
-- 发布时间: 2006/06/14 10:53am

#include<stdio.h>
int main(){
       unsigned char result = "night"[1]*"girls"[2]+"allnight"[4];
       char *of_you = "Though you was strong enough and seem never died";
       printf("You got %s", result+of_you);
       return 0;
}

同样能够得到这个诡异的结果

-- 作者: dabang007
-- 发布时间: 2006/06/15 00:12pm

哦,记起来了,数组元素的下标可以放在[]前面,而数组名放在[]中间
int a[10]={0,1,2,3,4,5,6,7,8,9};
cout<<a[0]<<'\n';与cout<<0[a]]<<'\n';效果是一样的。
这里只不过是把数组换成了常量字符串;

-- 作者: zql2003
-- 发布时间: 2006/06/15 06:10pm

[这个贴子最后由zql2003在 2006/06/15 06:37pm 第 5 次编辑]

实际 只要是形如 a[b] 形式的基本上都可以看成是数组  其中 a为 基址 [] 里面的b 为偏移量  数组里的元素就是靠 index=base + offset 来索引(基址与偏移量都是值,没有差异,所以位置可以互换 index为内存地址) 所以说上面的两种形式 都是这个特例 第一个元素都是基址 而第 二个元素 都是用[]扩起 那么它就是偏移量  只是常量字符串它的值为他的首地址 地址也是一个值(c语言是只是传值) 所以进一步推广 这里的a、b 可以是求值表达式  那么上述两个例子的行为就在情理之中了

下面我再给出 linux/fs/namei.c 中的一个例子 :
#define ACC_MODE(x) ("\004\002\006\377"[(x)&O_ACCMODE])
这个宏 ""里面的就是一个四个元素的字符串 他就是基址 ,后面[]里面的求值表达式即为偏移量 他可以看成一个广义数组  所以就可以根据[]的偏移量索引基址所在地址的值

从这里可以进一步看出 只要你能够以某种方式给出内存的地址 那么那个地址的值就能够访问  形如 a[b] 的数组的功能 就是访问给定地址单元 的值

如果能从汇编语言的角度考虑就更好理解了  即 如果你要访问某个元素 你首先要知道这个元素所在的内存地址 数组的功能就是找到这个地址(自动把基址与偏移量相加)

-- 作者: dabang007
-- 发布时间: 2006/06/16 08:22am

感谢强人zql2003
再请教一下:#define ACC_MODE(x) ("\004\002\006\377"[(x)&O_ACCMODE])
中的"\004\002\006\377"字符串的意思是什么?各位有什么特殊的含义?

-- 作者: zql2003
-- 发布时间: 2006/06/16 01:36pm

[这个贴子最后由zql2003在 2006/06/16 01:50pm 第 2 次编辑]

""里面的字符串 是由单个字符组成的序列(注:必须是字符,否则也不叫字符串) 字符分为7位ASCII码和8位ASCII码 两种(这里就不考虑unicode的宽字符了)  不管你采用哪种形式 字符的最大值不能超过八位,因此字符的十进制值最大值为255

平常我们见到的字符都是以 'a'这种类似形式表示的 实际在计算机里每个字符都对应一个[0-255]十进制数字值   所以既然字符的根本意义就是数字标识 那么使用数字来表示字符就理所当然了  在上面的字符串 "\004\002\006\377"里 如果你把 '\'都去掉 即 "004002006377"那么计算机会把每个数字都当作字符处理 即 0 本来应该为但做0x0处理 但是计算机把它认为字符'0'(ASCII码为 0x40)

那么为了表示真正的字符的ASCII码值 c语言在语法上采用了 '\' 转义字符 默认的情况下 行如 \177 为字符的八进制表示(1-3位,即他表示的范围为:\0 -- \377) 通式为 \ooo
但还有另一种字符表示 那就是以 \x33的形式表示字符的十六进制值 (1-2位,范围:\x0 -- \xff) 通式为 \xhh

从字符的可见性上说 分为:可打印字符 不可打印字符 两种。 基本上说 不可打印字符都是控制字符 。ASCII码值为 0-31 128-159是控制字符
上例字符串里的有一些字符是不可见字符(即为控制字符) 因为这些字符不可见,你只能用他的ASCII码值或者专用符号(比如换行符 \n)来表示他们

-- 作者: dabang007
-- 发布时间: 2006/06/18 08:12am

再次感谢zql2003!

-- 作者: qdynppytey
-- 发布时间: 2006/07/03 09:42am

真是高手啊

-- 作者: 暴雪
-- 发布时间: 2006/09/07 03:23pm

长见识了!哈哈

-- 作者: hlin614
-- 发布时间: 2006/10/14 08:40pm

用于学习是很好的例子
在工作中可要C你咯

© 中文版权所有: OldLinux论坛  版本: LeoBBS X Build060606
相关阅读 更多 +
排行榜 更多 +
风度

风度

游戏工具 下载
大姨妈月经提醒

大姨妈月经提醒

健康医疗 下载
海岸线小说网

海岸线小说网

浏览阅读 下载