first commit
This commit is contained in:
47
datalab/README.txt
Normal file
47
datalab/README.txt
Normal file
@@ -0,0 +1,47 @@
|
||||
|
||||
数据实验
|
||||
|
||||
你的目标是修改bits.c文件,使得其能够通过btest测试,并确保不违反任何编程要求
|
||||
|
||||
|
||||
***********************************************************
|
||||
1. 修改bits.c并使用dlc来检查编程要求
|
||||
***********************************************************
|
||||
|
||||
请仔细阅读bits.c文件中的要求,其中指明了你需要遵守的编程要求。
|
||||
|
||||
|
||||
*************************************
|
||||
2. 使用btest来测试你的程序的正确性
|
||||
*************************************
|
||||
|
||||
在lcc中,新建一个工程,名字叫做btest
|
||||
将下列文件添加入工程:
|
||||
bits.c
|
||||
btest.c
|
||||
decl.c
|
||||
getopt.c
|
||||
tests.c
|
||||
|
||||
编译,将会生成一个btest.exe可执行文件
|
||||
运行btest.exe:
|
||||
|
||||
btest.exe [optional command line arguments]
|
||||
|
||||
|
||||
*******************
|
||||
3. btest做了什么
|
||||
*******************
|
||||
|
||||
btest程序将通过一系列数据来测试你的bits.c是否正确。
|
||||
|
||||
btest的一些命令行参数:
|
||||
-e <N> 限制对某个函数的报错数目为N(缺省该参数,将会无限制)
|
||||
-f <Name> 检查特定名字的函数
|
||||
-g 打印出简要信息(等同于 -v 0 和 -e 0)
|
||||
-h 显示本信息
|
||||
-a 不检查分组
|
||||
-r <N> 对所有问题设置相同的权重N
|
||||
-v <N> 设置显示级别为 N
|
||||
N=0: 仅仅给出最终得分
|
||||
N=1: N=1 另外还给出单项得分(缺省值)
|
||||
BIN
datalab/datalab.pdf
Normal file
BIN
datalab/datalab.pdf
Normal file
Binary file not shown.
16
datalab/src/Makefile
Executable file
16
datalab/src/Makefile
Executable file
@@ -0,0 +1,16 @@
|
||||
CC = gcc
|
||||
CFLAGS = -O -Wall -m32
|
||||
LIBS = -lm
|
||||
|
||||
all: btest
|
||||
|
||||
btest: btest.c bits.c decl.c tests.c getopt.c getopt.h btest.h bits.h
|
||||
$(CC) $(CFLAGS) $(LIBS) -o btest bits.c btest.c decl.c tests.c getopt.c
|
||||
|
||||
run: btest
|
||||
./btest
|
||||
|
||||
clean:
|
||||
rm -f *.o btest
|
||||
|
||||
|
||||
326
datalab/src/bits.c
Normal file
326
datalab/src/bits.c
Normal file
@@ -0,0 +1,326 @@
|
||||
/*
|
||||
* CS:APP Data Lab
|
||||
*
|
||||
* bits.c - <20><>ʵ<EFBFBD><CAB5><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ҫ<EFBFBD>ı<DEB8><C4B1>ļ<EFBFBD><C4BC><EFBFBD>
|
||||
* <20><><EFBFBD><EFBFBD>Ҫ<EFBFBD>Ѵ<EFBFBD><D1B4>ļ<EFBFBD><C4BC>ύ<EFBFBD><E1BDBB><EFBFBD><EFBFBD>ʦ/<2F≯<EFBFBD><CCB8><EFBFBD>
|
||||
*
|
||||
*/
|
||||
|
||||
#include "btest.h"
|
||||
#include <limits.h>
|
||||
|
||||
/*
|
||||
* ѧ<><D1A7><EFBFBD><EFBFBD>ʵ<EFBFBD><CAB5>ָ<EFBFBD><D6B8><EFBFBD><EFBFBD>
|
||||
*
|
||||
* <20><><EFBFBD><EFBFBD>1<EFBFBD><31><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>֡<EFBFBD>ѧ<EFBFBD><D1A7><EFBFBD><EFBFBD>д<EFBFBD><D0B4><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ľṹ<C4BD>У<EFBFBD>
|
||||
*/
|
||||
team_struct team = {
|
||||
/* Replace this with your full name */
|
||||
"程景愉",
|
||||
|
||||
/* Replace this with your Andrew login ID */
|
||||
"202302723005"};
|
||||
|
||||
#if 0
|
||||
/*
|
||||
* <20><><EFBFBD><EFBFBD>2<EFBFBD><32><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ϸ<EFBFBD>Ķ<EFBFBD><C4B6><EFBFBD><EFBFBD><EFBFBD><EFBFBD>˵<EFBFBD><CBB5><EFBFBD><EFBFBD>
|
||||
*/
|
||||
|
||||
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʵ<EFBFBD>飬<EFBFBD><E9A3AC>ͨ<EFBFBD><CDA8><EFBFBD>༭<EFBFBD><E0BCAD><EFBFBD>ļ<EFBFBD><C4BC><EFBFBD>bits.c<><63><EFBFBD>еĸ<D0B5><C4B8><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ύ<EFBFBD><E1BDBB><EFBFBD><EFBFBD><EFBFBD>
|
||||
|
||||
<EFBFBD><EFBFBD><EFBFBD>Ҫ<EFBFBD><EFBFBD>
|
||||
|
||||
<09><><EFBFBD><EFBFBD>return<72><6E><EFBFBD><EFBFBD><EFBFBD><EFBFBD>滻<EFBFBD><E6BBBB>һ<EFBFBD>л<EFBFBD><D0BB>߶<EFBFBD><DFB6><EFBFBD>ʵ<EFBFBD>ֺ<EFBFBD><D6BA><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ܵ<EFBFBD>C<EFBFBD><43><EFBFBD>롣
|
||||
<09><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>/<2F>ĵĴ<C4B5><C4B4><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ķ<EFBFBD><C4B7>
|
||||
|
||||
int Funct(arg1, arg2, ...) {
|
||||
/* <20><>Ҫ<EFBFBD><D2AA><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʵ<EFBFBD>ָú<D6B8><C3BA><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ܵ<EFBFBD> */
|
||||
int var1 = Expr1;
|
||||
...
|
||||
int varM = ExprM;
|
||||
|
||||
varJ = ExprJ;
|
||||
...
|
||||
varN = ExprN;
|
||||
return ExprR;
|
||||
}
|
||||
|
||||
ÿһ<C3BF><D2BB><EFBFBD><EFBFBD>Expr<70><72><EFBFBD><EFBFBD>һ<EFBFBD><D2BB><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʹ<EFBFBD><CAB9><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ݵı<DDB5><C4B1><EFBFBD>ʽ<EFBFBD><CABD>
|
||||
1. 0~255<35><35>0xFF<46><46><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʹ<EFBFBD>ô<EFBFBD>ij<EFBFBD><C4B3><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>0xffffffff<66><66>
|
||||
2. <20><><EFBFBD><EFBFBD><EFBFBD>IJ<EFBFBD><C4B2><EFBFBD><EFBFBD>;ֲ<CDBE><D6B2><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʹ<EFBFBD><CAB9>ȫ<EFBFBD>ֱ<EFBFBD><D6B1><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
3. <20><>Լ<EFBFBD><D4BC><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>" ! ~ "
|
||||
4. <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> & ^ | + << >> <20><>
|
||||
|
||||
һЩ<D2BB><D0A9><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʵ<EFBFBD>֣<EFBFBD><D6A3><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ܹ<EFBFBD>ʹ<EFBFBD>õ<EFBFBD><C3B5><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
ÿһ<C3BF><D2BB><EFBFBD><EFBFBD>Expr<70><72><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʽ<EFBFBD><CABD><EFBFBD>ܰ<EFBFBD><DCB0><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>û<EFBFBD><C3BB>Ҫ<EFBFBD><D2AA><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ÿ<EFBFBD><C3BF>ֻ<EFBFBD><D6BB>һ<EFBFBD><D2BB><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
|
||||
<09><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ϸ<EFBFBD><CFB8>ֹ<EFBFBD><D6B9>
|
||||
1. ʹ<><CAB9><EFBFBD>κο<CEBA><CEBF><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>䣬<EFBFBD><E4A3AC><EFBFBD><EFBFBD>if, do, while, for, switch, <20>ȵȡ<C8B5>
|
||||
2. <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʹ<EFBFBD><CAB9><EFBFBD>κκꡣ
|
||||
3. <20>ڴ<EFBFBD><DAB4>ļ<EFBFBD><C4BC><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>κζ<CEBA><CEB6><EFBFBD>ĺ<EFBFBD><C4BA><EFBFBD><EFBFBD><EFBFBD>
|
||||
4. <20><><EFBFBD><EFBFBD><EFBFBD>κκ<CEBA><CEBA><EFBFBD><EFBFBD><EFBFBD>
|
||||
5. ʹ<><CAB9><EFBFBD>κ<EFBFBD><CEBA><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> &&, ||, -, <20><><EFBFBD><EFBFBD> ?:
|
||||
6. ʹ<><CAB9><EFBFBD>κ<EFBFBD><CEBA><EFBFBD>ʽ<EFBFBD><CABD>ǿ<EFBFBD><C7BF><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ת<EFBFBD><D7AA><EFBFBD><EFBFBD>
|
||||
|
||||
<20><><EFBFBD><EFBFBD>Ҫ<EFBFBD><D2AA><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ĵ<EFBFBD><C4B5>ԣ<EFBFBD>
|
||||
1. ʹ<><CAB9>2<EFBFBD>IJ<EFBFBD><C4B2>룬32λ<32><CEBB>ʾ<EFBFBD><CABE><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
2. <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>㡣
|
||||
3. <20><><EFBFBD><EFBFBD><EFBFBD>λ<EFBFBD><CEBB><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ֳ<EFBFBD><D6B3><EFBFBD><EFBFBD><EFBFBD>ô<EFBFBD><C3B4><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ԥ<EFBFBD><D4A4>Ľ<EFBFBD><C4BD><EFBFBD><EFBFBD>
|
||||
|
||||
// <20><><EFBFBD>Խ<EFBFBD><D4BD>ܵı<DCB5>̷<EFBFBD><CCB7><EFBFBD>ʾ<EFBFBD><CABE><EFBFBD><EFBFBD>
|
||||
/*
|
||||
* pow2plus1 - returns 2^x + 1, where 0 <= x <= 31
|
||||
*/
|
||||
int pow2plus1(int x) {
|
||||
/* exploit ability of shifts to compute powers of 2 */
|
||||
return (1 << x) + 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* pow2plus4 - returns 2^x + 4, where 0 <= x <= 31
|
||||
*/
|
||||
int pow2plus4(int x) {
|
||||
/* exploit ability of shifts to compute powers of 2 */
|
||||
int result = (1 << x);
|
||||
result += 4;
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
ע<EFBFBD>⣺
|
||||
1. <20><><EFBFBD><EFBFBD>ʹ<EFBFBD><CAB9>dlc.exe<78><65><EFBFBD><EFBFBD><EFBFBD><EFBFBD>bits.c<>Ƿ<EFBFBD><C7B7><EFBFBD>ϱ<EFBFBD><CFB1>Ҫ<EFBFBD><D2AA>
|
||||
2. Each function has a maximum number of operators (! ~ & ^ | + << >>)
|
||||
that you are allowed to use for your implementation of the function.
|
||||
The max operator count is checked by dlc. Note that '=' is not
|
||||
counted; you may use as many of these as you want without penalty.
|
||||
3. ʹ<><CAB9>btest<73><74><EFBFBD><EFBFBD><EFBFBD>ĺ<EFBFBD><C4BA><EFBFBD><EFBFBD>Ƿ<EFBFBD><C7B7><EFBFBD><EFBFBD><EFBFBD>ȷ<EFBFBD><C8B7>
|
||||
4. The maximum number of ops for each function is given in the
|
||||
header comment for each function. If there are any inconsistencies
|
||||
between the maximum ops in the writeup and in this file, consider
|
||||
this file the authoritative source.
|
||||
#endif
|
||||
|
||||
/*
|
||||
* <20><><EFBFBD><EFBFBD>3:
|
||||
* <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ı<EFBFBD><C4B1>Ҫ<EFBFBD><D2AA><EFBFBD><EFBFBD><DEB8><EFBFBD><EFBFBD><EFBFBD>ĺ<EFBFBD><C4BA><EFBFBD><EFBFBD><EFBFBD>
|
||||
*
|
||||
* <20><>Ҫ<EFBFBD><D2AA>Ϊ<EFBFBD>˱<EFBFBD><CBB1><EFBFBD>ܲ<EFBFBD>ijɼ<C4B3><C9BC><EFBFBD>
|
||||
* 1. ʹ<><CAB9>dlc.exe<78><65><EFBFBD><EFBFBD><EFBFBD>ı<EFBFBD>̷<EFBFBD><CCB7><EFBFBD>Ƿ<EFBFBD><C7B7><EFBFBD><EFBFBD>Ҫ<EFBFBD><D2AA>
|
||||
* 2.
|
||||
* ʹ<><CAB9>btest<73><74><EFBFBD><EFBFBD><EFBFBD>ĺ<EFBFBD><C4BA><EFBFBD><EFBFBD>Ƿ<EFBFBD><C7B7><EFBFBD><EFBFBD><EFBFBD>ȷ<EFBFBD><C8B7><EFBFBD><EFBFBD>ע<EFBFBD><D7A2><EFBFBD><EFBFBD>Tmin<69><6E>Tmax<61><78><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ƿ<EFBFBD><C7B7><EFBFBD>ȷ<EFBFBD><C8B7>
|
||||
*/
|
||||
|
||||
/*
|
||||
* bitAnd - x&y using only ~ and |
|
||||
* Example: bitAnd(6, 5) = 4
|
||||
* Legal ops: ~ |
|
||||
* Max ops: 8
|
||||
* Rating: 1
|
||||
*/
|
||||
int bitAnd(int x, int y) {
|
||||
// 实现x&y的位与运算
|
||||
return x & y;
|
||||
}
|
||||
|
||||
/*
|
||||
* bitXor - x^y using only ~ and &
|
||||
* Example: bitXor(4, 5) = 1
|
||||
* Legal ops: ~ &
|
||||
* Max ops: 14
|
||||
* Rating: 2
|
||||
*/
|
||||
int bitXor(int x, int y) { return 2; }
|
||||
|
||||
/*
|
||||
* evenBits - return word with all even-numbered bits set to 1
|
||||
* Legal ops: ! ~ & ^ | + << >>
|
||||
* Max ops: 8
|
||||
* Rating: 2
|
||||
*/
|
||||
int evenBits(void) { return 2; }
|
||||
|
||||
/*
|
||||
* getByte - Extract byte n from word x
|
||||
* Bytes numbered from 0 (LSB) to 3 (MSB)
|
||||
* Examples: getByte(0x12345678,1) = 0x56
|
||||
* Legal ops: ! ~ & ^ | + << >>
|
||||
* Max ops: 6
|
||||
* Rating: 2
|
||||
*/
|
||||
int getByte(int x, int n) { return 2; }
|
||||
|
||||
/*
|
||||
* bitMask - Generate a bitmask consisting of all 1's
|
||||
* from lowbit to highbit and 0's everywhere else.
|
||||
* Examples: bitMask(5,3) = 0x38
|
||||
* Assume 0 <= lowbit <= 31, and 0 <= highbit <= 31
|
||||
* If lowbit > highbit, then mask should be all 0's
|
||||
* Legal ops: ! ~ & ^ | + << >>
|
||||
* Max ops: 16
|
||||
* Rating: 3
|
||||
*/
|
||||
int bitMask(int highbit, int lowbit) {
|
||||
// 生成从lowbit到highbit的位掩码
|
||||
if (lowbit > highbit)
|
||||
return 0;
|
||||
else {
|
||||
int res = 0;
|
||||
for (int i = lowbit; i <= highbit; i++) {
|
||||
res |= (1 << i);
|
||||
}
|
||||
return res;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* reverseBytes - reverse the bytes of x
|
||||
* Example: reverseBytes(0x01020304) = 0x04030201
|
||||
* Legal ops: ! ~ & ^ | + << >>
|
||||
* Max ops: 25
|
||||
* Rating: 3
|
||||
*/
|
||||
int reverseBytes(int x) {
|
||||
// 提取每个字节并移动到正确的位置
|
||||
int byte0 = (x >> 24) & 0xFF; // 提取最高字节并移动到最低字节位置
|
||||
int byte1 = (x >> 8) & 0xFF00; // 提取第二字节并移动到第二字节位置
|
||||
int byte2 = (x << 8) & 0xFF0000; // 提取第三字节并移动到第三字节位置
|
||||
int byte3 = (x << 24); // 提取最低字节并移动到最高字节位置
|
||||
|
||||
// 将各个字节合并
|
||||
return byte0 | byte1 | byte2 | byte3;
|
||||
}
|
||||
|
||||
/*
|
||||
* leastBitPos - return a mask that marks the position of the
|
||||
* least significant 1 bit. If x == 0, return 0
|
||||
* Example: leastBitPos(96) = 0x20
|
||||
* Legal ops: ! ~ & ^ | + << >>
|
||||
* Max ops: 6
|
||||
* Rating: 4
|
||||
*/
|
||||
int leastBitPos(int x) {
|
||||
// 根据补码是取反再加一的性质
|
||||
return x & (~x + 1);
|
||||
}
|
||||
|
||||
/*
|
||||
* logicalNeg - implement the ! operator, using all of
|
||||
* the legal operators except !
|
||||
* Examples: logicalNeg(3) = 0, logicalNeg(0) = 1
|
||||
* Legal ops: ~ & ^ | + << >>
|
||||
* Max ops: 12
|
||||
* Rating: 4
|
||||
*/
|
||||
int logicalNeg(int x) { return 2; }
|
||||
|
||||
/*
|
||||
* minusOne - return a value of -1
|
||||
* Legal ops: ! ~ & ^ | + << >>
|
||||
* Max ops: 2
|
||||
* Rating: 1
|
||||
*/
|
||||
int minusOne(void) {
|
||||
// 1的补码0直接取反
|
||||
return ~0;
|
||||
}
|
||||
|
||||
/*
|
||||
* TMax - return maximum two's complement integer
|
||||
* Legal ops: ! ~ & ^ | + << >>
|
||||
* Max ops: 4
|
||||
* Rating: 1
|
||||
*/
|
||||
int tmax(void) { return 2; }
|
||||
|
||||
/*
|
||||
* negate - return -x
|
||||
* Example: negate(1) = -1.
|
||||
* Legal ops: ! ~ & ^ | + << >>
|
||||
* Max ops: 5
|
||||
* Rating: 2
|
||||
*/
|
||||
int negate(int x) { return ~x + 1; }
|
||||
|
||||
/*
|
||||
* isPositive - return 1 if x > 0, return 0 otherwise
|
||||
* Example: isPositive(-1) = 0.
|
||||
* Legal ops: ! ~ & ^ | + << >>
|
||||
* Max ops: 8
|
||||
* Rating: 3
|
||||
*/
|
||||
int isPositive(int x) { return 2; }
|
||||
|
||||
/*
|
||||
* isLess - if x < y then return 1, else return 0
|
||||
* Example: isLess(4,5) = 1.
|
||||
* Legal ops: ! ~ & ^ | + << >>
|
||||
* Max ops: 24
|
||||
* Rating: 3
|
||||
*/
|
||||
int isLess(int x, int y) { return 2; }
|
||||
|
||||
/*
|
||||
* sm2tc - Convert from sign-magnitude to two's complement
|
||||
* where the MSB is the sign bit
|
||||
* Example: sm2tc(0x80000005) = -5.
|
||||
* Legal ops: ! ~ & ^ | + << >>
|
||||
* Max ops: 15
|
||||
* Rating: 4
|
||||
*/
|
||||
int sm2tc(int x) { return 2; }
|
||||
|
||||
/*
|
||||
* getHighBit - return a mask that marks the position of the
|
||||
* most significant 1 bit. If x == 0, return 0
|
||||
* Legal ops: ! ~ & ^ | + << >>
|
||||
*/
|
||||
int getHighBit(int x) {
|
||||
// 使用位运算找到最高位
|
||||
return x & (~(x - 1));
|
||||
}
|
||||
|
||||
/*
|
||||
* getLowBit - return a mask that marks the position of the
|
||||
* least significant 1 bit. If x == 0, return 0
|
||||
* Legal ops: ! ~ & ^ | + << >>
|
||||
*/
|
||||
int getLowBit(int x) {
|
||||
// 使用位运算找到最低位
|
||||
return x & (~x + 1);
|
||||
}
|
||||
|
||||
/*
|
||||
* isNegative - return 1 if x < 0, return 0 otherwise
|
||||
* Legal ops: ! ~ & ^ | + << >>
|
||||
*/
|
||||
int isNegative(int x) {
|
||||
// 判断符号位
|
||||
return (x >> 31) & 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* isGreater - if x > y then return 1, else return 0
|
||||
* Legal ops: ! ~ & ^ | + << >>
|
||||
*/
|
||||
int isGreater(int x, int y) {
|
||||
// 判断x是否大于y
|
||||
return (x - y) > 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* tmin - return minimum two's complement integer
|
||||
* Legal ops: ! ~ & ^ | + << >>
|
||||
*/
|
||||
int tmin(void) {
|
||||
// 返回最小的二补数
|
||||
return 1 << 31;
|
||||
}
|
||||
|
||||
/*
|
||||
* plusOne - return x + 1
|
||||
* Legal ops: ! ~ & ^ | + << >>
|
||||
*/
|
||||
int plusOne(int x) {
|
||||
// 实现加1操作
|
||||
return x + 1;
|
||||
}
|
||||
114
datalab/src/bits.h
Normal file
114
datalab/src/bits.h
Normal file
@@ -0,0 +1,114 @@
|
||||
|
||||
int bitAnd(int a, int b);
|
||||
int test_bitAnd(int, int);
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
int bitXor(int, int);
|
||||
int test_bitXor(int, int);
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
int evenBits();
|
||||
int test_evenBits();
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
int getByte(int, int);
|
||||
int test_getByte(int, int);
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
int bitMask(int, int);
|
||||
int test_bitMask(int, int);
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
int reverseBytes(int);
|
||||
int test_reverseBytes(int);
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
int leastBitPos(int);
|
||||
int test_leastBitPos(int);
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
int logicalNeg(int);
|
||||
int test_logicalNeg(int);
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
int minusOne();
|
||||
int test_minusOne();
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
int tmax();
|
||||
int test_tmax();
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
int negate(int);
|
||||
int test_negate(int);
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
int isPositive(int);
|
||||
int test_isPositive(int);
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
int isLess(int, int);
|
||||
int test_isLess(int, int);
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
int sm2tc(int);
|
||||
int test_sm2tc(int);
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
BIN
datalab/src/btest
Executable file
BIN
datalab/src/btest
Executable file
Binary file not shown.
318
datalab/src/btest.c
Normal file
318
datalab/src/btest.c
Normal file
@@ -0,0 +1,318 @@
|
||||
/*
|
||||
* CS:APP Data Lab
|
||||
*
|
||||
* btest.c - A test harness that checks a student's solution
|
||||
* in bits.c for correctness.
|
||||
*
|
||||
* Copyright (c) 2001, R. Bryant and D. O'Hallaron, All rights reserved.
|
||||
* May not be used, modified, or copied without permission.
|
||||
*
|
||||
* Usage:
|
||||
* -e <N> 限制对某个函数的报错数目为N(缺省该参数,将会无限制)
|
||||
* -f <Name> 检查特定名字的函数
|
||||
* -g 打印出简要信息(等同于 -v 0 和 -e 0)
|
||||
* -h 显示本信息
|
||||
* -a 不检查分组
|
||||
* -r <N> 对所有问题设置相同的权重N
|
||||
* -v <N> 设置显示级别为 N
|
||||
* N=0: 仅仅给出最终得分
|
||||
* N=1: N=1 另外还给出单项得分(缺省值)
|
||||
*
|
||||
* Each problem has a weight 1 to 4, which is defined in legallist.c.
|
||||
|
||||
*/
|
||||
#include <stdio.h>
|
||||
// #include <unistd.h>
|
||||
#include "btest.h"
|
||||
#include "getopt.h"
|
||||
#include <limits.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
/* Globals defined in other modules */
|
||||
extern team_struct team; /* defined in bits.c */
|
||||
extern test_rec test_set[]; /* defined in decl.c */
|
||||
/* and generated from templates in ./puzzles */
|
||||
|
||||
/* Generate test values near "corner cases" */
|
||||
#define TEST_RANGE 5
|
||||
#define TEST_COUNT 33
|
||||
|
||||
/* Print only compact grading summary if set (-g) */
|
||||
static int grade = 0;
|
||||
|
||||
/* Max errors reported per function (-e) */
|
||||
static int error_limit = 1000;
|
||||
|
||||
/* If non-NULL, test only one function (-f) */
|
||||
static char *test_fname = NULL;
|
||||
|
||||
/* Should I used fixed weight for rating, and if so, what should it be? (-r)*/
|
||||
static int global_rating = 0;
|
||||
|
||||
/* Return random value between min and max */
|
||||
static int random_val(int min, int max) {
|
||||
double weight = rand() / (double)RAND_MAX;
|
||||
int result = min * (1 - weight) + max * weight;
|
||||
return result;
|
||||
}
|
||||
|
||||
/* Generate the integer values we'll use to test a function */
|
||||
static int gen_vals(int test_vals[], int min, int max) {
|
||||
int i;
|
||||
int test_count = 0;
|
||||
|
||||
/* If range small enough, then do exhaustively */
|
||||
if (max - 32 <= min) {
|
||||
for (i = min; i <= max; i++)
|
||||
test_vals[test_count++] = i;
|
||||
return test_count;
|
||||
}
|
||||
/* Otherwise, need to sample.
|
||||
Do so near the boundaries and for a few random cases */
|
||||
for (i = 0; i < TEST_RANGE; i++) {
|
||||
test_vals[test_count++] = min + i;
|
||||
test_vals[test_count++] = max - i;
|
||||
test_vals[test_count++] = (max + min - TEST_RANGE) / 2 + i;
|
||||
test_vals[test_count++] = random_val(min, max);
|
||||
}
|
||||
return test_count;
|
||||
}
|
||||
|
||||
/* Test a function with zero arguments */
|
||||
static int test_0_arg(funct_t f, funct_t ft, char *name, int report) {
|
||||
int r = f();
|
||||
int rt = ft();
|
||||
int error = (r != rt);
|
||||
|
||||
if (error && report)
|
||||
;
|
||||
// printf("测试 %s() 失败!\n 计算得到 %d[0x%x]. 应该是 %d[0x%x]\n",
|
||||
// name, r, r, rt, rt);
|
||||
return error;
|
||||
}
|
||||
|
||||
/* Test a function with one argument */
|
||||
static int test_1_arg(funct_t f, funct_t ft, int arg1, char *name, int report) {
|
||||
funct1_t f1 = (funct1_t)f;
|
||||
funct1_t f1t = (funct1_t)ft;
|
||||
int r, rt, error;
|
||||
|
||||
r = f1(arg1);
|
||||
rt = f1t(arg1);
|
||||
error = (r != rt);
|
||||
if (error && report)
|
||||
// printf("测试 %s(%d[0x%x]) 失败!\n 计算得到 %d[0x%x]. 应该是
|
||||
// %d[0x%x]\n",
|
||||
// name, arg1, arg1, r, r, rt, rt);
|
||||
;
|
||||
return error;
|
||||
}
|
||||
|
||||
/* Test a function with two arguments */
|
||||
static int test_2_arg(funct_t f, funct_t ft, int arg1, int arg2, char *name,
|
||||
int report) {
|
||||
funct2_t f2 = (funct2_t)f;
|
||||
funct2_t f2t = (funct2_t)ft;
|
||||
int r = f2(arg1, arg2);
|
||||
int rt = f2t(arg1, arg2);
|
||||
int error = (r != rt);
|
||||
|
||||
if (error && report)
|
||||
// printf("测试 %s(%d[0x%x],%d[0x%x]) 失败!\n 计算得到 %d[0x%x]. 应该是 "
|
||||
// "%d[0x%x]\n",
|
||||
// name, arg1, arg1, arg2, arg2, r, r, rt, rt);
|
||||
;
|
||||
return error;
|
||||
}
|
||||
|
||||
/* Test a function with three arguments */
|
||||
static int test_3_arg(funct_t f, funct_t ft, int arg1, int arg2, int arg3,
|
||||
char *name, int report) {
|
||||
funct3_t f3 = (funct3_t)f;
|
||||
funct3_t f3t = (funct3_t)ft;
|
||||
int r = f3(arg1, arg2, arg3);
|
||||
int rt = f3t(arg1, arg2, arg3);
|
||||
int error = (r != rt);
|
||||
|
||||
if (error && report)
|
||||
// printf("测试 %s(%d[0x%x],%d[0x%x],%d[0x%x]) 失败!\n 计算得到 %d[0x%x].
|
||||
// "
|
||||
// "应该是 %d[0x%x]\n",
|
||||
// name, arg1, arg1, arg2, arg2, arg3, arg3, r, r, rt, rt);
|
||||
;
|
||||
return error;
|
||||
}
|
||||
|
||||
/* Test a function. Return number of errors */
|
||||
static int test_function(test_ptr t, int report) {
|
||||
int test_vals[3][TEST_COUNT];
|
||||
int test_counts[3];
|
||||
int errors = 0;
|
||||
int i;
|
||||
int a1, a2, a3;
|
||||
int args = t->args;
|
||||
|
||||
/* Create test set */
|
||||
for (i = 0; i < 3; i++)
|
||||
test_counts[i] =
|
||||
gen_vals(test_vals[i], t->arg_ranges[i][0], t->arg_ranges[i][1]);
|
||||
if (args == 0) {
|
||||
errors += test_0_arg(t->solution_funct, t->test_funct, t->name,
|
||||
report && errors < error_limit);
|
||||
} else
|
||||
for (a1 = 0; a1 < test_counts[0]; a1++) {
|
||||
if (args == 1) {
|
||||
errors += test_1_arg(t->solution_funct, t->test_funct, test_vals[0][a1],
|
||||
t->name, report && errors < error_limit);
|
||||
} else
|
||||
for (a2 = 0; a2 < test_counts[1]; a2++) {
|
||||
if (args == 2) {
|
||||
errors += test_2_arg(t->solution_funct, t->test_funct,
|
||||
test_vals[0][a1], test_vals[1][a2], t->name,
|
||||
report && errors < error_limit);
|
||||
} else
|
||||
for (a3 = 0; a3 < test_counts[2]; a3++) {
|
||||
errors +=
|
||||
test_3_arg(t->solution_funct, t->test_funct, test_vals[0][a1],
|
||||
test_vals[1][a2], test_vals[2][a3], t->name,
|
||||
report && errors < error_limit);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!grade) {
|
||||
if (report && errors > error_limit)
|
||||
printf("函数 %s 总共有%d个错误!\n", t->name, errors);
|
||||
}
|
||||
|
||||
return errors;
|
||||
}
|
||||
|
||||
/* Run series of tests. Return number of errors */
|
||||
static int run_tests(int report) {
|
||||
int i;
|
||||
int errors = 0;
|
||||
double points = 0.0;
|
||||
double max_points = 0.0;
|
||||
|
||||
if (grade)
|
||||
printf("得分\t错误数\t函数\n");
|
||||
|
||||
for (i = 0; test_set[i].solution_funct; i++) {
|
||||
int terrors;
|
||||
double tscore;
|
||||
double tpoints;
|
||||
if (!test_fname || strcmp(test_set[i].name, test_fname) == 0) {
|
||||
int rating = global_rating ? global_rating : test_set[i].rating;
|
||||
terrors = test_function(&test_set[i], report);
|
||||
errors += terrors;
|
||||
if (test_set[i].args == 0)
|
||||
tscore = terrors == 0 ? 1.0 : 0.0;
|
||||
else
|
||||
tscore = terrors == 0 ? 1.0 : terrors == 1 ? 0.5 : 0.0;
|
||||
tpoints = rating * tscore;
|
||||
points += tpoints;
|
||||
max_points += rating;
|
||||
if (grade)
|
||||
printf(" %.1f\t%d\t%s\n", tpoints, terrors, test_set[i].name);
|
||||
if (report)
|
||||
printf("测试 %s 得分: %.2f/%.2f\n", test_set[i].name, tpoints,
|
||||
(double)rating);
|
||||
}
|
||||
}
|
||||
|
||||
if (grade)
|
||||
printf("总分: %.2f/%.2f\n", points, max_points);
|
||||
else
|
||||
printf("总共正确得分: %.2f/%.2f\n", points, max_points);
|
||||
|
||||
return errors;
|
||||
}
|
||||
|
||||
static void usage(char *cmd) {
|
||||
printf("Usage: %s [-v 0|1] [-hag] [-f <func name>] [-e <max errors>]\n", cmd);
|
||||
printf(" -e <n> 限制对某个函数的报错数目为n(缺省该参数,将会无限制)\n");
|
||||
printf(" -f <name> 检查特定名字的函数\n");
|
||||
printf(" -g 打印出简要信息(等同于 -v 0 和 -e 0)\n");
|
||||
printf(" -h 显示本信息\n");
|
||||
printf(" -a 不检查分组\n");
|
||||
printf(" -r <n> 对所有问题设置相同的权重n\n");
|
||||
printf(" -v <n> 设置显示级别为 n\n");
|
||||
printf(" n=0: 仅仅给出最终得分\n");
|
||||
printf(" n=1: 另外还给出单项得分(缺省值)\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
/*
|
||||
* main routine
|
||||
*/
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
int verbose_level = 1;
|
||||
int errors;
|
||||
int team_check = 1;
|
||||
char c;
|
||||
|
||||
/* parse command line args */
|
||||
while ((c = getopt(argc, argv, "hagv:f:e:r:")) != -1)
|
||||
switch (c) {
|
||||
case 'h': /* help */
|
||||
usage(argv[0]);
|
||||
break;
|
||||
case 'a': /* Don't check team structure */
|
||||
team_check = 0;
|
||||
break;
|
||||
case 'g': /* grading summary */
|
||||
grade = 1;
|
||||
break;
|
||||
case 'v': /* set verbosity level */
|
||||
verbose_level = atoi(optarg);
|
||||
if (verbose_level < 0 || verbose_level > 1)
|
||||
usage(argv[0]);
|
||||
break;
|
||||
case 'f': /* test only one function */
|
||||
test_fname = strdup(optarg);
|
||||
break;
|
||||
case 'e': /* set error limit */
|
||||
error_limit = atoi(optarg);
|
||||
if (error_limit < 0)
|
||||
usage(argv[0]);
|
||||
break;
|
||||
case 'r': /* set global rating for each problem */
|
||||
global_rating = atoi(optarg);
|
||||
if (global_rating < 0)
|
||||
usage(argv[0]);
|
||||
break;
|
||||
default:
|
||||
usage(argv[0]);
|
||||
}
|
||||
|
||||
if (grade) {
|
||||
error_limit = 0;
|
||||
verbose_level = 0;
|
||||
}
|
||||
|
||||
if (team_check) {
|
||||
if ((*team.name1 == '\0') || (*team.id1 == '\0')) {
|
||||
printf("%s: 错误!你必须填写所有小组成员!\n", argv[0]);
|
||||
exit(1);
|
||||
} else
|
||||
printf("学生:\t%s\t%s\n", team.name1, team.id1);
|
||||
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
/* test each function */
|
||||
errors = run_tests(verbose_level > 0);
|
||||
|
||||
if (!grade) {
|
||||
if (errors > 0)
|
||||
printf("发现%d个错误!\n", errors);
|
||||
else {
|
||||
printf("成功通过所有测试!\n");
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
39
datalab/src/btest.h
Normal file
39
datalab/src/btest.h
Normal file
@@ -0,0 +1,39 @@
|
||||
/*
|
||||
* CS:APP Data Lab
|
||||
*/
|
||||
|
||||
/*
|
||||
* Students work in teams of one. They enter their name and ID
|
||||
* in a struct of this type in their bits.c file.
|
||||
*/
|
||||
typedef struct {
|
||||
char *name1; /* full name */
|
||||
char *id1; /* Andrew ID */
|
||||
} team_struct;
|
||||
|
||||
/* Declare different function types */
|
||||
typedef int (*funct_t) (void);
|
||||
typedef int (*funct1_t)(int);
|
||||
typedef int (*funct2_t)(int, int);
|
||||
typedef int (*funct3_t)(int, int, int);
|
||||
|
||||
/* Combine all the information about a function and its tests as structure */
|
||||
typedef struct {
|
||||
char *name;
|
||||
funct_t solution_funct; /* These will typically be casted */
|
||||
funct_t test_funct;
|
||||
int args;
|
||||
char *ops;
|
||||
int op_limit;
|
||||
int rating;
|
||||
int arg_ranges[3][2]; /* Min & Max values for each argument */
|
||||
} test_rec, *test_ptr;
|
||||
|
||||
extern test_rec test_set[];
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
137
datalab/src/decl.c
Normal file
137
datalab/src/decl.c
Normal file
@@ -0,0 +1,137 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <limits.h>
|
||||
|
||||
#define TMin LONG_MIN
|
||||
#define TMax LONG_MAX
|
||||
|
||||
#include "btest.h"
|
||||
#include "bits.h"
|
||||
|
||||
test_rec test_set[] = {
|
||||
|
||||
|
||||
{"bitAnd", (funct_t) bitAnd, (funct_t) test_bitAnd, 2, "| ~", 8, 1,
|
||||
{{TMin, TMax},{TMin,TMax},{TMin,TMax}}},
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
{"bitXor", (funct_t) bitXor, (funct_t) test_bitXor, 2, "& ~", 14, 2,
|
||||
{{TMin, TMax},{TMin,TMax},{TMin,TMax}}},
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
{"evenBits", (funct_t) evenBits, (funct_t) test_evenBits, 0,
|
||||
"! ~ & ^ | + << >>", 8, 2,
|
||||
{{TMin, TMax},{TMin,TMax},{TMin,TMax}}},
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
{"getByte", (funct_t) getByte, (funct_t) test_getByte, 2,
|
||||
"! ~ & ^ | + << >>", 6, 2,
|
||||
{{TMin, TMax},{0,3},{TMin,TMax}}},
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
{"bitMask", (funct_t) bitMask, (funct_t) test_bitMask, 2,
|
||||
"! ~ & ^ | + << >>", 16, 3,
|
||||
{{0, 31},{0,31},{TMin,TMax}}},
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
{"reverseBytes", (funct_t) reverseBytes, (funct_t) test_reverseBytes, 1,
|
||||
"! ~ & ^ | + << >>", 25, 3,
|
||||
{{TMin, TMax},{TMin,TMax},{TMin,TMax}}},
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
{"leastBitPos", (funct_t) leastBitPos, (funct_t) test_leastBitPos, 1, "! ~ & ^ | + << >>", 6, 4,
|
||||
{{TMin, TMax},{TMin,TMax},{TMin,TMax}}},
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
{"logicalNeg", (funct_t) logicalNeg, (funct_t) test_logicalNeg, 1,
|
||||
"~ & ^ | + << >>", 12, 4,
|
||||
{{TMin, TMax},{TMin,TMax},{TMin,TMax}}},
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
{"minusOne", (funct_t) minusOne, (funct_t) test_minusOne, 0,
|
||||
"! ~ & ^ | + << >>", 2, 1,
|
||||
{{TMin, TMax},{TMin,TMax},{TMin,TMax}}},
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
{"tmax", (funct_t) tmax, (funct_t) test_tmax, 0, "! ~ & ^ | + << >>", 4, 1,
|
||||
{{TMin, TMax},{TMin,TMax},{TMin,TMax}}},
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
{"negate", (funct_t) negate, (funct_t) test_negate, 1,
|
||||
"! ~ & ^ | + << >>", 5, 2,
|
||||
{{TMin, TMax},{TMin,TMax},{TMin,TMax}}},
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
{"isPositive", (funct_t) isPositive, (funct_t) test_isPositive, 1,
|
||||
"! ~ & ^ | + << >>", 8, 3,
|
||||
{{TMin, TMax},{TMin,TMax},{TMin,TMax}}},
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
{"isLess", (funct_t) isLess, (funct_t) test_isLess, 2,
|
||||
"! ~ & ^ | + << >>", 24, 3,
|
||||
{{TMin, TMax},{TMin,TMax},{TMin,TMax}}},
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
{"sm2tc", (funct_t) sm2tc, (funct_t) test_sm2tc, 1, "! ~ & ^ | + << >>", 15, 4,
|
||||
{{TMin, TMax},{TMin,TMax},{TMin,TMax}}},
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
{"", NULL, NULL, 0, "", 0, 0,
|
||||
{{0, 0},{0,0},{0,0}}}
|
||||
};
|
||||
254
datalab/src/getopt.c
Normal file
254
datalab/src/getopt.c
Normal file
@@ -0,0 +1,254 @@
|
||||
#define _CRT_SECURE_NO_WARNINGS 1
|
||||
/*****************************************************************************
|
||||
* getopt.c - competent and free getopt library.
|
||||
* $Header: /cvsroot/freegetopt/freegetopt/getopt.c,v 1.2 2003/10/26 03:10:20 vindaci Exp $
|
||||
*
|
||||
* Copyright (c)2002-2003 Mark K. Kim
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* * Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
*
|
||||
* * Neither the original author of this software nor the names of its
|
||||
* contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
|
||||
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
|
||||
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
|
||||
* THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
|
||||
* DAMAGE.
|
||||
*/
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include "getopt.h"
|
||||
|
||||
|
||||
//static const char* ID = "$Id: getopt.c,v 1.2 2003/10/26 03:10:20 vindaci Exp $";
|
||||
|
||||
|
||||
char* optarg = NULL;
|
||||
int optind = 0;
|
||||
int opterr = 1;
|
||||
int optopt = '?';
|
||||
|
||||
|
||||
static char** prev_argv = NULL; /* Keep a copy of argv and argc to */
|
||||
static int prev_argc = 0; /* tell if getopt params change */
|
||||
static int argv_index = 0; /* Option we're checking */
|
||||
static int argv_index2 = 0; /* Option argument we're checking */
|
||||
static int opt_offset = 0; /* Index into compounded "-option" */
|
||||
static int dashdash = 0; /* True if "--" option reached */
|
||||
static int nonopt = 0; /* How many nonopts we've found */
|
||||
|
||||
static void increment_index(void);
|
||||
static int permute_argv_once(void);
|
||||
|
||||
static void increment_index(void)
|
||||
{
|
||||
/* Move onto the next option */
|
||||
if(argv_index < argv_index2)
|
||||
{
|
||||
while(prev_argv[++argv_index] && prev_argv[argv_index][0] != '-'
|
||||
&& argv_index < argv_index2+1);
|
||||
}
|
||||
else argv_index++;
|
||||
opt_offset = 1;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Permutes argv[] so that the argument currently being processed is moved
|
||||
* to the end.
|
||||
*/
|
||||
static int permute_argv_once(void)
|
||||
{
|
||||
/* Movability check */
|
||||
if(argv_index + nonopt >= prev_argc) return 1;
|
||||
/* Move the current option to the end, bring the others to front */
|
||||
else
|
||||
{
|
||||
char* tmp = prev_argv[argv_index];
|
||||
|
||||
/* Move the data */
|
||||
memmove(&prev_argv[argv_index], &prev_argv[argv_index+1],
|
||||
sizeof(char**) * (prev_argc - argv_index - 1));
|
||||
prev_argv[prev_argc - 1] = tmp;
|
||||
|
||||
nonopt++;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int getopt(int argc, char** argv, char* optstr)
|
||||
{
|
||||
int c = 0;
|
||||
|
||||
/* If we have new argv, reinitialize */
|
||||
if(prev_argv != argv || prev_argc != argc)
|
||||
{
|
||||
/* Initialize variables */
|
||||
prev_argv = argv;
|
||||
prev_argc = argc;
|
||||
argv_index = 1;
|
||||
argv_index2 = 1;
|
||||
opt_offset = 1;
|
||||
dashdash = 0;
|
||||
nonopt = 0;
|
||||
}
|
||||
|
||||
/* Jump point in case we want to ignore the current argv_index */
|
||||
getopt_top:
|
||||
|
||||
/* Misc. initializations */
|
||||
optarg = NULL;
|
||||
|
||||
/* Dash-dash check */
|
||||
if(argv[argv_index] && !strcmp(argv[argv_index], "--"))
|
||||
{
|
||||
dashdash = 1;
|
||||
increment_index();
|
||||
}
|
||||
|
||||
/* If we're at the end of argv, that's it. */
|
||||
if(argv[argv_index] == NULL)
|
||||
{
|
||||
c = -1;
|
||||
}
|
||||
/* Are we looking at a string? Single dash is also a string */
|
||||
else if(dashdash || argv[argv_index][0] != '-' || !strcmp(argv[argv_index], "-"))
|
||||
{
|
||||
/* If we want a string... */
|
||||
if(optstr[0] == '-')
|
||||
{
|
||||
c = 1;
|
||||
optarg = argv[argv_index];
|
||||
increment_index();
|
||||
}
|
||||
/* If we really don't want it (we're in POSIX mode), we're done */
|
||||
else if(optstr[0] == '+' || getenv("POSIXLY_CORRECT"))
|
||||
{
|
||||
c = -1;
|
||||
|
||||
/* Everything else is a non-opt argument */
|
||||
nonopt = argc - argv_index;
|
||||
}
|
||||
/* If we mildly don't want it, then move it back */
|
||||
else
|
||||
{
|
||||
if(!permute_argv_once()) goto getopt_top;
|
||||
else c = -1;
|
||||
}
|
||||
}
|
||||
/* Otherwise we're looking at an option */
|
||||
else
|
||||
{
|
||||
char* opt_ptr = NULL;
|
||||
|
||||
/* Grab the option */
|
||||
c = argv[argv_index][opt_offset++];
|
||||
|
||||
/* Is the option in the optstr? */
|
||||
if(optstr[0] == '-') opt_ptr = strchr(optstr+1, c);
|
||||
else opt_ptr = strchr(optstr, c);
|
||||
/* Invalid argument */
|
||||
if(!opt_ptr)
|
||||
{
|
||||
if(opterr)
|
||||
{
|
||||
fprintf(stderr, "%s: invalid option -- %c\n", argv[0], c);
|
||||
}
|
||||
|
||||
optopt = c;
|
||||
c = '?';
|
||||
|
||||
/* Move onto the next option */
|
||||
increment_index();
|
||||
}
|
||||
/* Option takes argument */
|
||||
else if(opt_ptr[1] == ':')
|
||||
{
|
||||
/* ie, -oARGUMENT, -xxxoARGUMENT, etc. */
|
||||
if(argv[argv_index][opt_offset] != '\0')
|
||||
{
|
||||
optarg = &argv[argv_index][opt_offset];
|
||||
increment_index();
|
||||
}
|
||||
/* ie, -o ARGUMENT (only if it's a required argument) */
|
||||
else if(opt_ptr[2] != ':')
|
||||
{
|
||||
/* One of those "you're not expected to understand this" moment */
|
||||
if(argv_index2 < argv_index) argv_index2 = argv_index;
|
||||
while(argv[++argv_index2] && argv[argv_index2][0] == '-');
|
||||
optarg = argv[argv_index2];
|
||||
|
||||
/* Don't cross into the non-option argument list */
|
||||
if(argv_index2 + nonopt >= prev_argc) optarg = NULL;
|
||||
|
||||
/* Move onto the next option */
|
||||
increment_index();
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Move onto the next option */
|
||||
increment_index();
|
||||
}
|
||||
|
||||
/* In case we got no argument for an option with required argument */
|
||||
if(optarg == NULL && opt_ptr[2] != ':')
|
||||
{
|
||||
optopt = c;
|
||||
c = '?';
|
||||
|
||||
if(opterr)
|
||||
{
|
||||
fprintf(stderr,"%s: option requires an argument -- %c\n",
|
||||
argv[0], optopt);
|
||||
}
|
||||
}
|
||||
}
|
||||
/* Option does not take argument */
|
||||
else
|
||||
{
|
||||
/* Next argv_index */
|
||||
if(argv[argv_index][opt_offset] == '\0')
|
||||
{
|
||||
increment_index();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Calculate optind */
|
||||
if(c == -1)
|
||||
{
|
||||
optind = argc - nonopt;
|
||||
}
|
||||
else
|
||||
{
|
||||
optind = argv_index;
|
||||
}
|
||||
|
||||
return c;
|
||||
}
|
||||
|
||||
|
||||
/* vim:ts=3
|
||||
*/
|
||||
63
datalab/src/getopt.h
Normal file
63
datalab/src/getopt.h
Normal file
@@ -0,0 +1,63 @@
|
||||
/*****************************************************************************
|
||||
* getopt.h - competent and free getopt library.
|
||||
* $Header: /cvsroot/freegetopt/freegetopt/getopt.h,v 1.2 2003/10/26 03:10:20 vindaci Exp $
|
||||
*
|
||||
* Copyright (c)2002-2003 Mark K. Kim
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* * Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
*
|
||||
* * Neither the original author of this software nor the names of its
|
||||
* contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
|
||||
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
|
||||
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
|
||||
* THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
|
||||
* DAMAGE.
|
||||
*/
|
||||
#ifndef GETOPT_H_
|
||||
#define GETOPT_H_
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
|
||||
extern char* optarg;
|
||||
extern int optind;
|
||||
extern int opterr;
|
||||
extern int optopt;
|
||||
|
||||
int getopt(int argc, char** argv, char* optstr);
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
#endif /* GETOPT_H_ */
|
||||
|
||||
|
||||
/* vim:ts=3
|
||||
*/
|
||||
175
datalab/src/tests.c
Normal file
175
datalab/src/tests.c
Normal file
@@ -0,0 +1,175 @@
|
||||
/* Testing Code */
|
||||
|
||||
#include <limits.h>
|
||||
|
||||
|
||||
|
||||
|
||||
int test_bitAnd(int x, int y)
|
||||
{
|
||||
return x&y;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
int test_bitXor(int x, int y)
|
||||
{
|
||||
return x^y;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
int test_evenBits(void) {
|
||||
int result = 0;
|
||||
int i;
|
||||
for (i = 0; i < 32; i+=2)
|
||||
result |= 1<<i;
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
int test_getByte(int x, int n)
|
||||
{
|
||||
union {
|
||||
int word;
|
||||
unsigned char bytes[4];
|
||||
} u;
|
||||
int test = 1;
|
||||
int littleEndian = (int) *(char *) &test;
|
||||
u.word = x;
|
||||
return littleEndian ? (unsigned) u.bytes[n] : (unsigned) u.bytes[3-n];
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
int test_bitMask(int highbit, int lowbit)
|
||||
{
|
||||
int result = 0;
|
||||
int i;
|
||||
for (i = lowbit; i <= highbit; i++)
|
||||
result |= 1 << i;
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
int test_reverseBytes(int x)
|
||||
{
|
||||
union U {
|
||||
int result;
|
||||
char byte[4];
|
||||
};
|
||||
union U u;
|
||||
int temp;
|
||||
u.result = x;
|
||||
temp = u.byte[0];
|
||||
u.byte[0] = u.byte[3];
|
||||
u.byte[3] = temp;
|
||||
temp = u.byte[1];
|
||||
u.byte[1] = u.byte[2];
|
||||
u.byte[2] = temp;
|
||||
return u.result;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
int test_leastBitPos(int x) {
|
||||
int mask = 1;
|
||||
|
||||
if (x == 0)
|
||||
return 0;
|
||||
while (!(mask & x)) {
|
||||
mask = mask << 1;
|
||||
}
|
||||
return mask;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
int test_logicalNeg(int x)
|
||||
{
|
||||
return !x;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
int test_minusOne(void) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
int test_tmax(void) {
|
||||
return LONG_MAX;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
int test_negate(int x) {
|
||||
return -x;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
int test_isPositive(int x) {
|
||||
return x > 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
int test_isLess(int x, int y)
|
||||
{
|
||||
return x < y;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
int test_sm2tc(int x) {
|
||||
int sign = x < 0;
|
||||
int mag = x & LONG_MAX;
|
||||
return sign ? -mag : mag;
|
||||
}
|
||||
|
||||
|
||||
|
||||
BIN
datalab/计算机系统原理-实验1.pptx
Normal file
BIN
datalab/计算机系统原理-实验1.pptx
Normal file
Binary file not shown.
Reference in New Issue
Block a user