1. 在拨打长途电话时,电话公司所保存的信息会包括拨打电话的日期和时间。它还包括3个电话号码:使用的那个电话、呼叫的那个电话以及付账的那个电话。这些电话号码的每一个都由3个部分组成:区号、交换台和站号码。请为这些记账信息编写一个结构声明。
解析:虽然这个问题并没有明确要求,但正确的方法是为电话号码声明一个结构,然后使用这个结构表示付账记录结构的3个成员。
/*
** 表示长途电话付账记录的结构。
*/
/* 解决方案10.2a phone1.h */
struct PHONE_NUMBER{
short area;
short exchange;
short station;
};
struct LONG_DISTANCE_BIIL{
short month;
short day;
short year;
int time;
struct PHONE_NUMBER called;
struct PHONE_NUMBER calling;
struct PHONE_NUMBER billed;
};
/*
** 另一种方法是使用一个长度为PHONE_NUMBERS的数组,如下所示:
*/
/*
** 表示长途电话付账记录的结构。
*/
/* 解决方案10.2b phone2.h */
enum PN_TYPE {
CALLED, CALLING, BILLED
};
struct LONG_DISTANCE_BILL{
short month;
short day;
short year;
int time;
struct PHONE_NUMBER numbers[3];
};
2. 为一个信息系统编写一个声明,用于记录每个汽车零售商的销售情况。每份销售记录必须包括下列数据。
字符串的最大长度不包括其结尾的NUL字节。
顾客名字(customer's name) string(20)
顾客地址(customer's address) string(40)
模型(model) string(20)
销售时可能出现3种不同类型的交易:全额现金销售、贷款销售和租赁。对于全额现金销售,还必须保存下面这些附加信息:
生产厂家建议零售价(manufacturer's suggested retail price) float
实际售出价格(actual selling price) float
营业税(sales tax) float
许可费用(licensing fee) float
对于租赁,必须保存下面这些附加信息:
生产厂家建议零售价(manfacturer's suggested retail price) float
实际售出价格(actual selling price) float
预付定金(down payment) float
安全抵押(security deposit) float
月付金额(monthly payment) float
租赁期限(lease term) int
对于贷款销售,必须保存下面这些附加信息:
生产厂家建议零售价(manfacturer's suggested retail price) float
实际售出价格(actual selling price) float
营业税(sales tax) float
许可费用(licensing fee) float
预付定金(down payment) float
贷款期限(loan duration) int
贷款利率(interest rate) float
月付金额(monthly payment) float
银行名称(name of bank) string(20)
struct Full_cash{
float manufacturer_suggested_retail_price;
float actual_selling_price;
float sales_tax;
float licensing_fee;
};
struct Loan{
float manufacturer_suggested_retail_price;
float actual_selling_price;
float down_payment;
float security_deposit;
float monthly_payment;
int lease_term;
};
struct Lease{
float manufacturer_suggested_retail_price;
float actual_selling_price;
float sales_tax;
float licensing_fee;
float down_payment;
int loan_duration;
float interest_rate;
float monthly_payment;
char bank[21];
};
struct Sales{
char customer_name[21];
char customer_addr[41];
char model[21];
enum { FULL_CASH, LOAN, LEASE } transaction;
union{
struct Full_cash full_cash;
struct Loan loan;
struct Lease lease;
};
};
#include <stdio.h>
#include <stdlib.h>
int main( void ){
struct Sales sale;
return EXIT_SUCCESS;
}
3. 计算机的任务之一就是对程序的指令进行解码,确定采取何种操作。在许多机器中,由于不同的指令具有不同的格式,因此解码过程被复杂化了。在某台特定的机器上,每个指令的长度都是16位,并实现了下列各种不同的指令格式。位是从右向左进行标记的。
单操作数指令 双操作数指令 转移指令
位 字段名 位 字段名 位 字段名
0~2 dst_reg 0~2 dst_reg 0~7 offset
3~5 dst_mode 3~5 dst_mode 8~15 opcode
6~15 opcode 6~8 src_reg
9~11 src_mode
12~15 opcode
源寄存器指令 其余指令
位 字段名 位 字符名
0~2 dst_reg 0~15 opcode
3~5 dst_mode
6~8 src_reg
9~15 opcode
你的任务是编写一个声明,允许程序员使用这些格式中的任何一种对指令进行解释。声明同时必须有一个名叫addr的unsigned short类型字段,可以访问所有的16位值。在声明中使用typedef来创建一个新的类型,称为machine_inst。
给定下面的声明:
machine_inst x;
下面的表达式应该能访问它所指定的位。
表达式 位
x.addr 0~15
x.misc.opcode 0~15
x.branch.opcode 8~15
x.sgl_op.dst_mode 3~5
x.reg_src.src_reg 6~8
x.dbl_op.opcode 12~15
struct Sgl_op{
unsigned short int dst_reg: 3;
unsigned short int dst_mode: 3;
unsigned short int opcode: 10;
};
struct Dbl_op{
unsigned short int dst_reg: 3;
unsigned short int dst_mode: 3;
unsigned short int src_reg: 3;
unsigned short int src_mode: 3;
unsigned short int opcode: 4;
};
struct Branch{
unsigned short int offset: 8;
unsigned short int opcode: 8;
};
struct Reg_src{
unsigned short int dst_reg: 3;
unsigned short int dst_mode: 3;
unsigned short int src_reg: 3;
unsigned short int opcode: 7;
};
struct Misc{
unsigned short int opcode: 16;
};
typedef struct {
unsigned short int addr: 16;
enum { SGL_OP, DBL_OP, BRANCH, REG_SRC, MISC } type;
union{
struct Sgl_op sgl_op;
struct Dbl_op dbl_op;
struct Branch branch;
struct Reg_src reg_src;
struct Misc misc;
};
} machine_inst;
#include <stdio.h>
#include <stdlib.h>
int main( void ){
machine_inst x;
printf( "x.addr = %d\n", x.addr );
printf( "x.misc.opcode = %d\n", x.misc.opcode );
printf( "x.branch.opcode = %d\n", x.branch.opcode );
printf( "x.sgl_op.dst_mode = %d\n", x.sgl_op.dst_mode );
printf( "x.reg_src.src_reg = %d\n", x.reg_src.src_reg );
printf( "x.dbl_op.opcode = %d\n", x.dbl_op.opcode );
return EXIT_SUCCESS;
}
/* 输出:

*/