每日一练!从零开始学习。。。。。。
本帖最后由 oggplay 于 2014-7-4 20:25 编辑记录自己学习的过程。这取决于自己的时间!
ASCII镇楼。
本帖最后由 oggplay 于 2014-7-4 20:27 编辑
第二章 信息的表示和处理
#include <stdio.h>
typedef unsigned char *byte_pointer;
void show_bytes(byte_pointer start, int len) {
int i;
for (i=0; i < len; i++)
printf(" %.2x",start);
printf("\n");
}
void show_int(int x) {
show_bytes((byte_pointer) &x, sizeof(int));
}
void show_float(float x) {
show_bytes((byte_pointer) &x, sizeof(float));
}
void show_pointer(void * x) {
show_bytes((byte_pointer) &x, sizeof(void *));
}
思考对show_bytes的三次调用的结果:
int val=0x87654321;
byte_pointer valp=(byte_pointer) &val;
show_bytes(valp,1);//第一次
show_bytes(valp,2);//第二次
show_bytes(valp,3);//第三次
以上是小端法机器输出结果!
能坚持???? 祝坚持!厚积薄发~ 本帖最后由 oggplay 于 2014-4-7 19:40 编辑
下面对show_bytes的调用将输出什么结果?(自己先查了查strlen()的作用:sweat:) strlen()返回值不包含\n的长度!!
const char *s="abcdef";
show_bytes((byte_pointer) s,strlen(s));
本帖最后由 oggplay 于 2014-4-11 19:59 编辑
20世纪70年代,Digital Equipment的VAX计算机是一种非常流行的机型。它没有布尔运算AND和OR指令,只有bis(位设置)和bic(位清除)指令。两种指令的输入都是一个数据字x和一个掩码字m。他们生成一个结果z,z是由根据掩码m的位来修改x的位得到的。使用bis指令,这种修改就是在m为1的每个位置上,将z对应的位设置为1。使用bic指令,这种修改就是在m为1的每个位置,将z对应的位设置为0,。
为了弄清楚因为这些运算与c语言位级运算的关系,假设我们有两个函数bis和bic来实现位设置和位清除操作。只用这两个函数,而不使用任何其他C语言运算,来实现按位|和^运算。填写下列代码中缺失的代码。
(第2个空思考良久,唉)
/*declarations of functions implementing operations bis and bic*/
int bis (int x, int m);
int bic (int x, int m);
/*compute x|y using only calls to functions bis and bic*/
int bool_or (int x, int y){
int result =__________;
retrun result;
}
/*compute x^y using only calls to functions bis and bic*/
int bool_xor (int x, int y){
int result=__________;
return result;
}先写出这2个函数C语言表达式:
int bis (int x, int m) {x|m;}
int bic (int x,int m) {x&~m;}
第一空:bis (x, y)
第二空:x^y=(x&~y)|(~x&y),根据这个公式答案为:bis (bic(x,y), bic(y, x))
本帖最后由 oggplay 于 2014-4-12 20:24 编辑
以下采用补码32位机器上对表达式求值(0或者1),并写出编译器默认运算类型(有、无符号)
| 表达式 | 强制转换类型 | 求值 |
| -2147483647-1==2147483648U| | |
| -2147483647-1< 2147483647 | | |
|-2147483647-1U<2147483647 | | |
|-2147483647-1<-2147483647 | | |
|-2147483647-1U<-2147483647 | | |
-2147483647-1==2147483648U 无符号1
-2147483647-1< 2147483647 有符号1
-2147483647-1U<2147483647 无符号0
-2147483647-1<-2147483647 有符号1
-2147483647-1U<-2147483647 无符号1
如果有任何一个运算数是无符号的,那么在比较之前将有符号数先转换为无符号数。
第一次来到鱼c论坛有很多不明白的问题希望大家帮帮忙 菜鸟学汇编
:loveliness: LZ精神,向LZ学习 感谢楼主分享!,,,,,,, 厉害 支持一下了。 本帖最后由 oggplay 于 2014-4-12 20:23 编辑
考虑以下输出结果:(show_bytes函数在二楼)short sx= -12345;
unsigned uy= sx;
printf("uy=%u:\t", uy);
show_bytes((byte_pointer)& uy, sizeof(unsigned));该结果是C语言标准要求的!C语言标准:有符号数转换为无符号数时,先转换大小再转换为无符号数。
+++++++++++++++++++++++++++++罗嗦一句+++++++++++++++++++++++++++
典型的32位机器整数范围:
C语言标准规定保证的取值范围:
典型的64位系统取值范围:
*ISO C99引入long long类型
本帖最后由 oggplay 于 2014-4-12 21:30 编辑
阶段学习总结:
1、所有计算机都是用补码表示有符号数么?答案是否定的,但几乎是这样的。
2、有符号数补码表示形式:,表示权重,表示向量。
简单例子:
3、有符号数与无符号数计算时,编译器将有符号数强制转换为无符号数。字长不等时,先转换大小,再转换为无符号数。比如:short sx= -12345;
unsigned uy= sx;等价于:(unsigned)(int) sx,而不等于(unsigned)(unsigned short) sx
4、相同字长的有、无符号数转换规则:数值可能改变,但位模式不变,利用这一规则来进行转换,具体转换算法就不罗嗦了。看教程吧。
5、为什么不将上边例子的-2147483647-1直接写为-2147483648或者0x80000000?看一下头文件<limits.h>采用同样的手法:
#define INT_MAX2147483647
#define INT_MIN (-INT_MAX - 1)
这是由于补码的不对称性和C语言的转换规则之间会产生奇怪的交互,是C语言比较隐晦的地方,值得注意。
祝楼主 早日成功 本帖最后由 oggplay 于 2014-4-21 16:55 编辑
写出下列函数原型:
int uadd_ok(unsigned x, unsigned y);
如果参数x和y相加不会产生溢出,这个函数就返回1
int tadd_ok(int x, int y);
如果参数x和y相加不会产生溢出,这个函数就返回1
int uadd_ok(unsigned x, unsigned y){
unsigned sum=x+y;
return sum>=x;
}
int tadd_ok(int x, int y){
int sum = x+y;
int neg_over = x < 0 && y < 0 && sum >=0;
int pos_over = x>=0 && y>= 0 && sum < 0;
return !neg_over && !pos_over;
}
========================补码加法=============================
=======================无符号数加法============================
=========================补码的非==============================
催帖来了,好几天了 啊 没有看懂!!!!还没有学到这里。 打字太累,偷懒一下
本帖最后由 oggplay 于 2014-4-30 10:37 编辑
1、给你一个任务,开发函数tmult_ok,该函数判断两数相乘是否溢出。下面是解决方案:看是否正确
int tmult_ok(int x, int y){
int p= x*y;
return !x || p/x == y;
}
2、对于int是32位的情况,设计一个tmult_ok函数,不使用除法来判断两数相乘是否溢出并写出该函数代码(使用long long类型)。
看看是什么