oggplay 发表于 2014-4-1 22:27:30

每日一练!从零开始学习。。。。。。

本帖最后由 oggplay 于 2014-7-4 20:25 编辑

记录自己学习的过程。这取决于自己的时间!

ASCII镇楼。

oggplay 发表于 2014-4-1 22:28:41

本帖最后由 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);//第三次

以上是小端法机器输出结果!



卡劳动力 发表于 2014-4-2 06:57:45

能坚持????

木耳一道 发表于 2014-4-2 07:59:16

祝坚持!厚积薄发~

oggplay 发表于 2014-4-2 18:38:45

本帖最后由 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-7 19:37:50

本帖最后由 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-11 11:19:04

本帖最后由 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
如果有任何一个运算数是无符号的,那么在比较之前将有符号数先转换为无符号数。

好膽你就來 发表于 2014-4-11 12:04:32

第一次来到鱼c论坛有很多不明白的问题希望大家帮帮忙   菜鸟学汇编
:loveliness:

linwin108 发表于 2014-4-11 12:29:22

LZ精神,向LZ学习

枫界易城 发表于 2014-4-11 12:47:08

感谢楼主分享!,,,,,,,

我不知道。_ 发表于 2014-4-11 13:37:37

厉害 支持一下了。

oggplay 发表于 2014-4-11 13:52:35

本帖最后由 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 20:33:18

本帖最后由 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语言比较隐晦的地方,值得注意。





雪瀛 发表于 2014-4-13 19:25:53

祝楼主 早日成功

oggplay 发表于 2014-4-13 22:40:03

本帖最后由 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;
}
========================补码加法=============================

=======================无符号数加法============================

=========================补码的非==============================







雪瀛 发表于 2014-4-17 16:19:02

催帖来了,好几天了 啊

by024 发表于 2014-4-20 14:55:51

没有看懂!!!!还没有学到这里。

oggplay 发表于 2014-4-30 10:11:48

打字太累,偷懒一下




oggplay 发表于 2014-4-30 10:24:34

本帖最后由 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类型)。

学习编程的 发表于 2014-5-4 08:34:17

看看是什么
页: [1] 2 3
查看完整版本: 每日一练!从零开始学习。。。。。。