《C與指針》第十章練習


本章問題

1.成員和數組元素有什么區別?

answer:Structure members can be all different types;they are accessed by name;and unused memory may be between adjacent(鄰近的) members to enforce(強制) boundary alignment requirements.Array elements must all be the same type;they are accessed with a subscript;and no space is ever lost between elements for boundary alignment.

(結構成員可能是完全不同的類型,它們通過名字訪問並且在相鄰的兩個成員之間不使用內存而強制執行邊界對齊的要求,數組元素必須是相同類型,它們通過下標訪問,並且在任意兩個邊界對齊元素之間都沒有內存空隙)

 

2.結構名和數組名有什么不同?

answer:A Structure is a scalar(標量).Like any other scalar,when the name of a structure is used as an R_value in an expression it refers to the values stored in the structure.when used as an L_value,the name refers to the place in which die structure is stored.when an array name is used as an R_value in an expression,however,its value is a pointer to the first element in the array,because its value is a constant pointer,an array name cannot be used as an L_value.

(結構是一個標量,像其他任何標量一樣,當結構的名字在表達式中作為一個左值時它代表把值存儲到結構中,當它作為一個右值使用時,它是指存儲在芯片結構中的地方,當一個數組名在表達式中作為一個右值使用時,然而,它的值實際是一個指針,這個指針指向數組的第一個元素,因為它的值是一個常量指針,一個數組名不能被作為左值使用)

 

3.結構聲明的語法有幾個可選部分?請列出所有合法的結構聲明形式,並解釋每一個是如果實現的。

answer:

First,a declaration where all components are given:(首先,給出一個聲明的所有組成成分)

This declares x to be a stucture having two members,a and b,In addition,the structure tag S is created for use in future declarations.

(聲明了x這個結構有兩個成員a和b,除此之外,結構標簽S在以后的聲明中用來創建這個結構)

Omitting(省略) the tag field gives:(省略標簽)

which has the same effect as before,except that no tag is created.while other declarations may created more structure variables with indentical(相同的) members,it is possible to create any more variable with the samp type as z.

(這跟前面那個產生的結果相同,除了沒有標簽,然而其他聲明使用相同的成員創建更多的結構時,不可能創建一個和z相同類型的變量)

Omitting the member list gives:(省略成員列表)

which declares another structure variable y with the same type as x.

(聲明了另一個結構變量y與x的類型相同)

Omitting the variable list gives:(省略變量列表)

which simply defines the tag S for use in later declarations.

(簡單定義一個標簽S用於以后的聲明)

Finally,there is the incomplete declaration

(最后,這是一個不完整聲明)

which informs the compiler that S is a sturcture tag to be defined later.

(告訴編譯器S是一個結構標簽並且它將在后面定義的信息)

 

4.下面的程序段有沒有錯誤?如果有,錯誤在哪里?

struct abc{
        int a;
        int b;
        int c;
};
...
abc.a = 25;
abc.b = 15;
abc.c = -1;

answer: abc is the structure tag,not the name of a variable,so the assignment statement are illegal.

(abc是一個結構標簽而不是一個變量的名字,所以賦值語句是非法的)

 

5.下面的程序段有沒有錯誤?如果有,錯誤在哪里?

typedef struct{
        int a;
        int b;
        int c;
}abc;
...
abc.a = 25;
abc.b = 15;
abc.c = -1;

answer:abc is a type name,not the name of a variable,so the assignment statements are illegal.

(abc是一個類型名而不是一個變量的名字,所以賦值語句非法)

 

6.完成下面聲明中對x的初始化,使成員a為3,b為字符串"hello",c為0.你可以假設x存儲於靜態內存中。

struct {
        int a;
        char b[10];
        float c;
} x = 

answer:

struct {
        int a;
        char b[10];
        float c;
} x = {
        3,"hello"
};

 

7.考慮下面這些聲明和數據。

struct NODE{
    int a;
    struct NODE *b;
    struct NODE *c;
};

struct NODE nodes[5] = {
    {5, nodes + 3, NULL},
    {15, nodes + 4, nodes + 3},
    {22, NULL, nodes + 4},
    {12, nodes + 1, nodes},
    {18, nodes + 2, nodes + 1}
};
(other declarations...)
struct NODE *np = nodes + 2;
struct NODE **npp = &nodes[1].b;

 對下面的表達式求值,並寫出它的值,同時,寫明任何表達式求值過程中可能出現的副作用,你應該用最初顯示的值對每個表達式求值(也就是說,不要使用某個表達式的結果來對下一個表達式求值)。假定nodes數組在內存中的起始位置為200,並且在這台機器上整數和指針的長度都是4個字節。

answer:

 

 

expression value expression value
nodes 200 &node[3].c->a 200
nodes.a illegal &nodes->a 200
nodes[3].a 12 np nodes[2]
nodes[3].c 200 np->a 22
nodes[3].c->a 5 np->c->c->a 15
*nodes nodes[0] npp 216
*nodes.a illegal npp->a illegal
(*nodes).a 5 *npp 248
nodes->a 5 **npp nodes[4]
nodes[3].b->b 248 *npp->a illegal
*nodes[3].b->b nodes[4] (*npp)->a 18
&nodes 200 &np --
&nodes[3].a 236 &np->a 224
&nodes[3].c 244 &np->c->c->a 212

 

 

 

 

 

 

 

 

 

 

 

 

8.在一個16位的機器上,下面這個結構由於邊界對齊浪費了多少空間?在一個32位機器上又是如何?

struct{
        char a;
        int b;
        char c;
};

answer:With 16 bit integers,two bytes are wasted,one after each character,with 32 bit integers,six are wasted,Note that sapce is lost after c in order to guarantee that the structure ends at the most stringent(嚴格的) boundary,if this were not done,the next variable allocated(分配) might not begin at the proper boundary.

(在16位機器上浪費2個字節,在每個字符后面浪費一個字節,在32位機器上浪費6個字節,注意c后面的空間被浪費是為了確保結構末尾的嚴格邊界對齊,如果沒有對齊,下一個變量分配時可能不是從一個合適的邊界開始的)

 

9.至少說出兩個位段為什么不可移植的理由?

answer:

a  whether the field are allocated right to left or left to right

(分配內存是從左向右還是從右向左)

b  whether field too large to fit in the remaining bits of a word begin there anyway and cross the boundary to the next word or begin in the next word;

(字段是否太大而無法放入剩余的位中,可能穿單元邊界也可能從下一個單元開始)

c  whether signed or unsigned arithmetic is used for fields declared signed;

(聲明類型是為signed還是unsigned)

d the maxinum size of an individual field.

(單個區域的最大值不同)

 

10.編寫一個聲明,允許根據下面的格式方便的訪問一個浮點值的單獨部分。

 answer:

struct FLOAT{
        unsigned fraction    : 24;
        unsgined exponent    : 7;
        unsgined sign        :1;
};
//or
struct FLOAT{
        unsgined sign        :1;
        unsgined exponent    : 7;
        unsigned fraction    : 24;
};

 

11.如果不使用位段,你怎樣實現下面這段代碼的功能?假定你使用的是一台16位的機器,它從左向右為位段分配內存。

answer:

x &= 0x0fff;
x |= (aaa & 0xf) << 12;
x &= 0xf00f;
x |= (bbb & 0xff) << 4;
x &= 0xfff1;
x |= (ccc & 0x7) <<1;
x &= 0xfffe;
x |= (ddd & 0x1);
//or
x = (aaa & 0xf) << 12 | (bbb & 0xff) << 4 | (ccc & 0x7) << 1 | (ddd & 0x1);
//or
x = aaa & 0xf;
x <<= 8;
x = bbb & 0xff;
x <<= 3;
x = ccc & 0x7;
x <<= 1;
x = ddd & 0x1;

 

12,下面這個代碼段將打印出什么?

struct {
        int a    :2;
}x;
...
x.a = 1;
x.a += 1;
printf("%d\n",x.a);

answer:

It can either be 2 or -2,depending on whether the compiler uses signed or unsigned arithmetic.

(可能是2或者-2,依賴於編譯器使用的是有符號運算還是無符號運算)

 

13.下面這個代碼段有沒有錯誤?如果有?錯誤在哪里?

union{
        int a;
        float b;
        char c;
}x;
...
x.a = 25;
x.b = 3.14;
x.c = 'x';
printf("%d %g %c\n",x,a, x.b, x.c);

answer: A union is being used as if it were a structure,On a machine with 32 bit integers and floats,the second assignment will completely replace the value stored by the first,and the last assignment will replace the first eight bits of the value stored by the second,the integer and floating-point members therefore print as garbage,but the character prints correctly.

(一個聯合被當作結構使用,在一台32位機器上,第二個賦值表達式將會覆蓋第一個表達式,最后一個賦值表達式將會取代第二個表達式存儲的前八個位,所以整型和浮點型的成員將會打印一個垃圾值,不過字符的打印值是對的)

 

14.假定有些信息已經賦值給一個聯合變量 ,我們該如何正確的提取這個信息呢?

answer:The same member that was used to store the data must also be used to read it.

(用於讀取它的成員必須要跟用於存儲它的成員相同)

 

15.下面的結構可以被一個BASIC解釋器使用,用於記住變量的類型和值:

struct VARIABLE{
    enum {INT,FLOAT,STRING} type;
    union{
        int i;
        float f;
        char *s;
    }value;
};

如果結構改寫成下面這種形式,會有什么不同呢?

struct VARIABLE{
    enum {INT,FLOAT,STRING} type;
    union{
        int i;
        float f;
        char s[MAX_STRING_LENGTH];
    }value;
};

answer:

First,the member s would store the actual value of the string rather than a pointer to the value,this means that the value would not have to be allocated elsewhere,which is an advantage,but this entails a terrible disadvantage:the structure now contain enough space to store the largest possible string,and nearly all of this space is wasted when integer and floating-point values are sotred,the original stucture did not have this problem because it only contained a pointer to the string value,not the value itself.

(首先,成員s將存儲為一個實際的字符串值而不是一個指針,這意味着字符串的值將不會被分配到其他地方去,這是一個優點,不過這也帶來了一個缺點,這個結構體現在包含了一個足夠大的空間可以存儲可能最大的字符串,當使用整型和浮點型存儲的時候幾乎全部的空間都被浪費,原來的結構體則不會有這個問題,因為它僅僅存儲的是一個字符指針,而不是字符串本身)

 

本章練習

1.當你撥打一個長途電話的時候,電話公司所保存的信息包括你撥打電話的時間和日期。它還包括三個號碼,你使用的那個號碼,你呼叫的那個號碼,以及你付賬的那個號碼,這些號碼的每一個都由三個部分組成:區號,交換台和站號碼,請為這些記帳信息編寫一個結構聲明。

answer:

struct PHONE_NUMBER{
    short area;
    short exchange;
    short station;
};

struct LONG_DISTANCE_BILL{
    short month;
    short day;
    short year;
    int time;
    struct PHONE_NUMBER called;
    struct PHONE_NUMBER calling;
    struct PHONE_NUMBER billed;
}

 

2.為一個信息系統編寫一個聲明,它用於記錄每個汽車零售商的銷售情況。每份銷售記錄必須包括下列數據。字符串值的最大長度不包括其結尾的NUL字節。

銷售時可能出現三種不同類型的交易:全額現金銷售,貸款銷售和租賃.對於全額現金銷售,你還必須保存下面這些附加信息:

對於租賃,你必須保存下面這些附件信息:

對於貸款銷售,你必須保存下面這些附件信息:

answer:

struct INFO1{
    char cust_name[21];
    char cust_addr[41];
    char model[21];
    enum {PURE_CASH, CASH_LOAN, LEASE} type;
    union{
        struct{
            float msrp;
            float sales_price;
            float sales_tax;
            float licensing_fee;
        }pure_cash;
        struct{
            float msrp;
            float sales_price;
            float sales_tax;
            float licensing_fee;
            float down_payment;
            int loan_duration;
            float interest_rate;
            float monthly_payment;
            char bank[21];
        }cash_loan;
        struct{
            float msrp;
            float sales_price;
            float down_payment;
            float security_deposit;
            float monthly_payment;
            float lease_term;
        }lease;
    }info;
};
//or
struct INFO2{
    char cust_name[21];
    char cust_addr[41];
    char model[21];
    float msrp;
    float sales_price;
    enum {PURE_CASH, CASH_LOAN, LEASE} type;
    union{
        struct{
            float sales_tax;
            float licensing_fee;
        }pure_cast;
        struct{
            float sales_tax;
            float licensing_fee;
            float down_payment;
            int loan_duration;
            float interest_rate;
            float monthly_payment;
            char bank[21];
        }cash_loan;
        struct{
            float down_payment;
            float security_deposit;
            float monthly_payment;
            float lease_term;
        }lease;
    }info;
};

 

3.計算機的任務之一就是對程序的指令進行解碼,確定采取何種操作.在許多機器中,由於不同的指令具有不同的格式,解碼過程被復雜化了,在某個特定的機器上,每個指令的長度都是16位,並實現了下列各種不同的指令格式.位是從右向左進行標記的.

你的任務是編寫一個聲明,允許程序用這些格式中的任何一種形式對指令進行解釋.你的聲明同時必須有一個名叫addr的unsigned short類型字段,可以訪問所有的16位值,在你的聲明中使用typedef來創建一個新類型,稱為machine_inst.給定下面的聲明:

machine_inst x;

下面的表達式應該訪問它所指定的位.

answer: 

typedef union{
    unsigned short addr;
    struct{
        unsigned opcode : 10;
        unsigned dst_mode : 3;
        unsigned dst_reg : 3;
    }sql_op;
    struct{
        unsigned opcode : 4;
        unsigned src_mode : 3;
        unsigned src_reg : 3;
        unsigned dst_mode : 3;
        unsigned dst_reg : 3;
    }dbl_op;
    struct{
        unsigned opcode : 7;
        unsigned src_reg : 3;
        unsigned dst_mode : 3;
        unsigned dst_reg : 3;
    }reg_src;
    struct{
        unsigned opcode : 8;
        unsigned offset : 8;
    }branch;
    struct{
        unsigned opcode : 16;
    }misc;
}machine_inst;


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM