#include
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;
}
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个字符
实际 只要是形如 a 形式的基本上都可以看成是数组 其中 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 的数组的功能 就是访问给定地址单元 的值
如果能从汇编语言的角度考虑就更好理解了 即 如果你要访问某个元素 你首先要知道这个元素所在的内存地址 数组的功能就是找到这个地址(自动把基址与偏移量相加)
""里面的字符串 是由单个字符组成的序列(注:必须是字符,否则也不叫字符串) 字符分为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)来表示他们
本站仅提供存储服务,所有内容均由用户发布,如发现有害或侵权内容,请
点击举报。