生存中的计算机思维

生活中的计算机思维

学计算机专业5年了,总有些令人迷惑而在书本上很难找到的问题。有空的时候探索研究总结如下。(同时和大家分享下,遇到问题时重要的不是查阅读资料搜索答案,而是认真的思考后通过程序去验证自己的假设)。持续更新……


问题0(2007):高中毕业,终于可以经常上网了,网上好多神奇的东西,有一个web程序,居然可以猜出你的心事。通过不断的交互,页面不断要求回答一些问题,比如你头脑中闪现的第一个女生等等这样的问题。若干回合过后,页面给出评测,说出你最爱的人,最好的朋友,最铁的哥们种种。

解释:汗颜啊,太小儿科的程序,用于忽悠那些不懂计算机的小朋友们。不解释。

 

问题1(2009):每次考试,都要查阅姓名的汉字编码,班级就那么一份,查起来又不方便又费劲。可不可以写个程序查查呢?

解释:经过查阅资料,学习。

(1.1) 区位码:为汉字制定了一张94*94的二维表,横轴表示区码,纵轴表示位码。一个区码和一个位码组合标识一个汉字。区码和位码都是大小都属于[1,94]。那么可分别用一个字节表示。则一个汉字可用两个字节表示。比如“学”字的区码为49(00110001),位码7(00000111)。合在一起区位码就是4907(00110001 00000111).

(1.2) 区位码不能直接使用。因为它会和ASCII码中的控制字符00H-1FH发生冲突。毕竟人家老美弄得比较早么。所以采取在区位码加上32(00100000)来避免这种冲突。“学”字就变成了5127H(01010001 00100111).

(1.3) 和控制字符不冲突了,可是又和ASCII码中的西文字符冲突了。因此又采取了一个简单办法即最高位置1(ASCII码只用了七位,最高位是0)。即又加上了128(10000000). 这样“学”字的机内码就成了(11010001 10100111). 即D1A7H。这点可以在任意编辑器输入“学”字之后,在转换成16进制查看。就会看到。正好验证了我们的结论。

总结下,其实就是给区位码分别加上160就成了机内码。那么我们可以通过输入汉字之后,获取其机内码,再减去160就是区位码。也就是考试中需要查阅的汉字编码。代码如下:

/**
 * 获得汉字的区位码
 * 输入:一个汉字(占两个字节)
 * 输出:此汉字的区位码串
 */
char* getQuWeiCode(char* word, char q_w_code[]){
	int q_code = 0;
	int w_code = 0;
	char format[10] = "";

	if(256 + word[0] < 128 || 256 + word[1] < 128){//加上256的原因是word[0]由char强转int会位填冲
		return "Wrong word!";                 //高位的1,整型负数会被认作补码参与运算。所以
	}                                              //加上256防止。下同。  

	q_code = 256 + word[0] - 160;
	w_code = 256 + word[1] - 160;
	if(q_code < 10){
		strcat(format, "0");
	}
	strcat(format, "%d");
	if(w_code < 10){
		strcat(format, "0");
	}
	strcat(format, "%d");

	sprintf(q_w_code, format, q_code, w_code);
	return q_w_code;
}

 

问题2(2009).ASCII码中 00000111表示bell响铃,那么输出它会有什么效果?

解释:自己尝试:

printf("%c", 7);


问题3(2009).Windows系统中的任务切换快捷键Alt+Tab是如何实现的?

解释:http://blog.csdn.net/li4951/article/details/6965538


问题4(2010).大端法,小端法,高地址,低地址被这些词都弄晕了?

解释:字节序是多字节值采用的存储方式,从起始地址(一般是低地址端)存某个数,是先存低位字节呢还是是先存高位字节?由于各厂商CPU的架构不同,因此对这个问题处理方式的差异。

A.小端法(Little-Endian)就是低位字节排放在内存的低地址端即该值的起始地址,高位字节排放在内存的高地址端。 
B.大端法(Big-Endian)就是高位字节排放在内存的低地址端即该值的起始地址,低位字节排放在内存的高地址端。 

可以通过下面验证代码来验证本机是那种方式(我的Inter是小端法):

    int a = 0x12345678;
    char *p = (char*)(&a);
    printf("a[0]:0x%x\n", *p++);
    printf("a[1]:0x%x\n", *p++);
    printf("a[2]:0x%x\n", *p++);
    printf("a[3]:0x%x\n", *p++);
字节序是针对数值内部的,而对于一个程序中内存的分配方式,是优先分配出高地址还是低地址呢?

验证代码:

int main(){
    int d;
    int a;
    char c;
    int b[10];

    printf("%x\n", &d);
    printf("%x\n", &a);
    printf("%x\n", &c);
    printf("%x\n", b);
    return 0;
}

输出:

经验证,发现占空间的这些变量都是从高地址开始分配的:12ff47——12ff44是d占用的,12ff43——12ff40是a占用的,12ff3f——12ff3d作为字节对齐用,12ff3c为c占用……

从这可以看出:

1.在栈空间对变量分配空间是从高地址向低地址方向分配

2.起始地址一般就是低地址、

 

问题5(2012.)暑假突发奇想,每次按下空调遥控器,都需要向空调发送那些信息指令?空调遥控器和电视遥控器有什么区别?

我认为空调遥控器每次按键后都会将空调遥控器显示的所有状态都发送给空调主机。包括温度,模式,风量,风向等等。而电视遥控器只会发送一个指令比如下一个台,声音增加等等。原因如下:

空调遥控器保持了操作者认为的各种状态,空调主机需要按遥控器上显示的各种状态工作,必须避免用户认识和主机工作模式不匹配的情况。不像电视机,用户的认知是从电视的展现效果读来的。认为声大了就降低,小了就放大,节目不满意就换台。这也就是带显示屏的遥控器和不带显示屏的遥控器的区别吧。欢迎拍砖。