匿名使用者
匿名使用者 發問時間: 電腦與網際網路程式設計 · 1 0 年前

c++ 的七個問題 希望可以幫幫我

1. 這是一個自行實做String類別的函式,目的是將兩個string接在一起,我照著課本打這個成員函式,但是不太懂為什麼newLength要宣告成 size_t ?

const String &String : : operator + = ( const String &right )

{

size_t newLength = length + right . length ;

char *tempPtr = new char [ newLength + 1 ] ;

strcpy ( tempPtr , sPtr ) ;

strcpy ( tempPtr + length , right . sPtr) ;

delete [] sPtr ;

sPtr = tempPtr ;

length = newLength ;

return *this ;

}

2. 為什麼有些類別前面要加

#ifndef TIME_H

#define TIME_H

課本上寫說是在標頭檔中使用前置處理包裝,避免在原始檔中重複包括同一個標頭檔,類別只能定義一次,故技巧能必免發生重複定義的錯誤,意思是Time這個類別只能定義一次的意思嗎?看不太懂....

3.下面兩段從課本引出的敘述,我看的頭昏眼花。我學過繼承和樣版,但是就是不懂他在寫什麼,看的好暈~

iostream函式庫提供許多處理常見I/O操作的樣版。例如,類別樣版basic_istream支援串流輸入操作,類別樣版basic_ostream支援串流輸出操作,而類別樣版basic_iostream會支援串流輸出和串流輸入操作。每個樣版均有一個預先定義的特殊化樣版,可執行char I/O。此外,iostream函式庫提供一組typedef,作為這些特殊化樣版的別名。

typedef ifstream代表basic_ifstream的特殊化,這個特殊化樣版讓字元能從檔案輸入。同樣地,typedef ofstream代表特殊化的basic_ofstream,他讓程式可以將char輸出到檔案。

4. setbase是黏著性(設定後後面跟著是這個設定),那麼dec、oct、hex這些串流操作子也是嗎?

5. ostream& endLine(ostream& output)

{

return output << ' \ n ' << flush ;

}

flush是什麼東西?詳細低敘述一下。

6.我在課本看到這段

ios_base : : ftmflags originalFormat = cout . flags ( ) ;

為什麼前面要寫ios_base呢?ftmflags又是什麼?函式flags ( ) 又是什麼呢?

7.下面這個為什麼rdstate是2呢?

Before a bad input operation:

cin . rdstate ( ) : 0 ; cin . eof ( ) : 0 ; cin . fail ( ) : 0 ; cin . bad ( ) : 0 ; cin . good ( ) : 1 ;

Expects an integer , but enter a character : A

After a bad input operation :

cin . rdstate ( ) : 2 ; cin . eof ( ) : 0 ; cin . fail ( ) : 1 ; cin . bad ( ) : 0 ; cin . good ( ) : 0 ;

3 個解答

評分
  • 1 0 年前
    最佳解答

    1.

    size_t 在 c 中一般是定義為unsigned int 形態,

    為什麼要這樣用,

    就是避免在其它的平台上編譯時的問題,

    每個平台上的size_t可能會定義的不一樣,

    所以最好是寫size_t,

    比較不會造成跨平台編譯及閱讀上的問題。

    2.

    /*這行是指如果沒有定義TIME_H 的話,有定義就跳到endif下一行*/

    #ifndef TIME_H

    /*就開始定義*/

    #define TIME_H

    /*定義處*/

    /*endif是結束定義區段*/

    #endif

    這樣的寫法是要給編譯器看的,

    如果在同一個地方include兩次同樣的檔案,

    第一次編譯器裡會有記錄TIME_H,

    第二次include的話,

    編譯器有看到TIME_H已經有了,

    就不會再將相同的定義區段讀進來,會直跳到 #endif下一行,

    所以說用這個方法就可以避免掉重複定義問題。

    3.

    其實如果你清楚C standard Library的話應該就不會被搞混了!

    template<typename _CharT, typename _Traits>

    class basic_istream : virtual public basic_ios<_CharT, _Traits>

    先看上面的宣告,

    然後再看

    extern template class basic_istream<char>;

    extern template class basic_ostream<char>;

    這兩行,

    最後再看,

    typedef basic_istream<char> istream;

    typedef basic_ostream<char> ostream;

    應該就可以看出個所以然了!XD

    特殊化指得就是給base_istream一個typename叫char而已,

    然後再typedef basic_istream<char>為 istream這樣,

    以後之後要使用 basic_istream<char> 的話,

    就可以不用打basic_istream<char>這樣,

    而直接打 istream 就行了,

    當然你也可以在寫程式的時候直接打

    typedef basic_istream<int> n_istream 這樣,

    然後就可以直接使用n_istream了@@"

    就是這樣生的!^^~

    4.

    我不知道你說的黏著性是什麼意思,

    是指

    cin<<setbase(16)<<15<<setbase(8);

    這個意思嗎?

    如果是的話,

    這個因為其實是他有定義operator << 這個運算子,

    請看下面這行的程式碼

    template<typename _CharT, typename _Traits>

    inline basic_ostream<_CharT,_Traits>&

    operator<<(basic_ostream<_CharT,_Traits>& __os, _Setprecision __f)

    {

    __os.precision(__f._M_n);

    return __os;

    }

    他回傳的回傳是basic_ostream物件,

    所以當然可以一直串下去,

    其它的dec、oct、hex等等都是有這個特性的。

    5.

    這點其實跟第四點是一模一樣的,

    請下面宣告就知了,

    template <class charT, class traits>

    basic_ostream<charT,traits>& flush ( basic_ostream<charT,traits>& os );

    我用下面的例子說明,

    cout<<'a'<<flush;

    他會先將a丟到cout裡,

    然後再執行 flush ,

    而flush有一個參數,

    那個就是要準備傳進去的cout

    6.

    不好意思,

    想請問你一下是不是有打錯字@@"

    應該是ios_base : : fmtflags 吧!

    好像m跟t相反了!@@"

    這個也很簡單請看下面程式碼,

    class ios_base

    {

    typedef _Ios_Fmtflags fmtflags;

    /*中間一大串全部省略不po,太長了!XD*/

    };

    他是屬於iso_base裡的所宣告的資料型態,

    要使用當然是要加上class scope運算子,

    這個我想你應該是知道啦!@@"

    可能是一時沒想到而已吧!^^~

    7.

    這個也蠻簡單的,

    請看下面程式碼

    你的上面有寫 a bad input operation ,

    那就會產生error,

    rdstate()有狀態碼,請看下面:

    0x00 沒有錯誤

    0x01 到了檔尾 EOF

    0x02 讀或寫失敗

    0x04 錯誤的運算 (如開啟不存在的檔案)

    0x08 硬體錯誤

    你那個應該是讀失敗,

    所以是2

    就是這樣生的^^~

    有問題再發問吧!

    雖然我覺得我的c++沒多強,

    但這種問題勉強可以應付!^^~

    2008-08-09 17:32:50 補充:

    抱歉~我好像打錯一個小地方,

    C standard Library

    應該是

    C++ Standard Library才對。^^|||

    2008-08-09 18:02:47 補充:

    cout<<'a'<

    );

    這個函式,

    奇摩說字太長了!@@"

    要分段@@"

    2008-08-09 18:05:24 補充:

    不知道為什麼字不見了@@"

    可能有那個小於的符號!@@"

    cout>>'a'>> flush;

    似乎講不夠詳細,

    我再講一下,

    他一開始會先執行

    operator >> ( cout, 'a');

    也就是

    ostream& operator >> (ostream&, _Setfill );

    這個函式,

    2008-08-09 18:05:44 補充:

    疑~~你應該會發現跟上面不一樣,

    因為template如果有sepcialization的話,

    會自己去找最符合的那個,

    這就是c++ template蠻神奇的一點,

    然後執行完以後會回傳ostream,

    目前的ostream,就是我們的cout,

    他會變成像下面這樣

    cout>>flush;

    然後再進入最後的flush階段,

    執行 flush(cout),

    就會將資料將緩衝區的資料全寫到你的儲存裝置了!^^~

    2008-08-09 18:22:17 補充:

    抱歉!

    我又錯了!囧TL

    那個 大於小於的方向打錯了!

    cout&gt&gt'a'&gt&gt flush;

    operator &gt&gt ( cout, 'a');

    ostream& operator &gt&gt (ostream&, _Setfill );

    改成下面那樣

    cout &lt&lt 'a' &lt&lt flush;

    operator &lt&lt ( cout, 'a');

    ostream& operator &lt&lt (ostream&, _Setfill );

    2008-08-09 18:23:20 補充:

    天啊!錯第三次了!XD~~~~~~~~``

    cout>>'a'>> flush;

    operator >> ( cout, 'a');

    ostream& operator >> (ostream&, _Setfill );

    改成下面那樣

    cout << 'a' << flush;

    operator << ( cout, 'a');

    ostream& operator << (ostream&, _Setfill );

    這次應該可以了吧!^^~

    2008-08-09 18:43:38 補充:

    抱歉我又漏了!XD

    第六題太短,

    我還以為只有一個問題@@"

    成來還有!現在補上

    下面這題沒回答到

    函式flags ( ) 又是什麼呢?

    這個是跟我上面回答第六題有關,

    因為flags()這個函式是直接從ios_base繼承的,

    他會回傳ios_base : : fmtflags這個資料型態

    所以要使用使用io_base::fmtflags來接,

    不然會有型別錯誤。

    先分個段好了!以免又有問題@@"

    2008-08-09 18:52:58 補充:

    ios_base::fmtflags是指用來控制格式化動作的細節,

    像是整數的進位表示法或浮點數的精準度等等,

    而你用setbase其實也是設定 fmtflags,

    只不過是使用函式的方式。

    用flags()是取得目前的值,

    用setf() 就是設定控制格式狀態的值,

    顯示出的效果會跟第四題一樣,

    我舉個例子好了!

    2008-08-09 18:58:19 補充:

    例如下面的程式:

    cout.setf ( ios::hex, ios::basefield );

    cout.setf ( ios::showbase );

    cout << 100 << endl;

    cout.setf ( 0, ios::showbase );

    cout < 100 < endl;

    輸出的結果如下:

    0x64

    64

    後面講解。

    2008-08-09 19:06:18 補充:

    上面好像有兩個小於漏掉了!請無視!^^|||||

    ios::hex 這個被宣告為class裡的常數,

    這次為什麼是叫 iso 而不是叫 base_iso 呢?

    我現在才發現一開始 base_iso 好像就打錯了的樣子!

    這點也請視無^^|||||

    當然是跟前面的問題一樣,

    因為在標頭檔已經typedef了!

    所以 iso 現在就代表 base_iso<char>

    使用時一樣是要加class scope

    2008-08-09 19:15:08 補充:

    小補一下

    fmtflags setf ( fmtflags fmtfl );

    fmtflags setf ( fmtflags fmtfl, fmtflags mask );

    他是有多載的,

    fmtlfl 和 mask 是有對應的,

    left, right, internal 是使用 adjustfield

    dec, oct, hex是使用 basefield

    scientific ,fixed 是使用 floatfield

    2008-08-09 19:16:25 補充:

    如果fmtfl設成0,寫像下面這樣

    cout.setf ( 0, ios::showbase );

    就代表不要使用ios::showbase這個控制狀態。

    ios::showbase 這個指得是要不要顯示資料時在開頭的地方顯示進位基底。

    例如上面的例子就有顯示 0x64,而0x就是指進位基底。

    講得好多啊!

    我打得好累的說@@"

    如果有問題再發問吧!^^~

    2008-08-09 19:33:28 補充:

    我再補充一下,

    剛才不小心發現的@@"

    ios_base 是對的@@"

    base_ios也確實有這個東西,

    只是base_iso是template,

    而 ios_base 是 class而已@@"

    ios 是定義為 base_ios<char>

    就是這樣XD

    猛然發現這個差別我自己也嚇了一跳,

    如果前面的 ios 有不小心打成 iso 也請見諒 囧

    已經打到昏了!XD

    還以為打錯了!@@"

  • 匿名使用者
    6 年前

    到下面的網址看看吧

    ▶▶http://qoozoo09260.pixnet.net/blog

  • 1 0 年前

    size_t 在某個Include 的檔有定義成 unsigned int~印象中

    #ifndef 這些是編譯指令~詳細的太久沒碰~忘光了~

    ....

    .....

    .....

    rdstate 傳回的是狀態碼 2表示讀或寫失敗

    已從頭說明到尾了~

還有問題?馬上發問,尋求解答。