• <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>
            posts - 16,  comments - 34,  trackbacks - 0

            本文概括敘述了一篇老文的內(nèi)容,并且總結對malloc返回值的3種轉(zhuǎn)型方式,(相對于原文)更全面的總結其各自的應用范圍。

            1. 原文內(nèi)容
            2. 對malloc的3種轉(zhuǎn)型方式
            3. 各自的應用范圍

             


             

            以前有篇文章叫《C/C++ 誤區(qū) —— 強制轉(zhuǎn)換 malloc() 的返回值》。
            文章大致內(nèi)容是:

            1. malloc函數(shù)在<stdlib.h> 或者 <cstdlib>頭文件中,而不是<malloc.h>。


            2. 由于C語言最初沒有void類型,所以是使用char*來代表通用指針。

            /* the old declaration of malloc */
            char* malloc(size_t size);

            char* p = malloc(size * sizeof(*p) );
            /* 可以, 不需要轉(zhuǎn)型 */

            T1
            * p1 = malloc(size1 * sizeof(*p1) );
            /* (T1!=char不可以,char*不能隱式轉(zhuǎn)換成T1*  */

            T2
            * p2 = (T2*)malloc(size2 * sizeof(*p2) );
            /* (T2!=char) 可以,顯示類型轉(zhuǎn)換 */

             

            3.C語言后來引入了void類型,就可以使用void*代表通用指針,同時規(guī)定void*可以隱式轉(zhuǎn)換任意指針類型。

            /* the new declaration of malloc */
            void* malloc(size_t size);

            char* p = malloc(size * sizeof(*p) );
            /* 仍然可以,void*可以隱式轉(zhuǎn)換到任意指針類型 */

            T1
            * p1 = malloc(size1 * sizeof(*p1) );
            /* 現(xiàn)在可以,void*可以隱式轉(zhuǎn)換到任意指針類型 */

            T2
            * p2 = (T1*)malloc(size2 * sizeof(*p2) );
            /* 仍然可以,但不再必須 */


            4. 在引入了void之后的C語言中,再使用強制轉(zhuǎn)換是畫蛇添足,同時影響代碼維護。
            并且說這是一個C/C++的誤區(qū)

             



            原文概述完畢,開始說本文章的內(nèi)容:
            對malloc返回值的轉(zhuǎn)型,大致有以下三種方式:

             

            1. 僅在C中

            /* legal only in C */

            /* 新頭文件 */
            T
            * p = malloc(size * sizeof(*p) ); /* T!=void */


            /* 舊頭文件 */

            T* p = (T*)malloc(size* sizeof(*p) ); /* T!=void */


            2.僅在C++中
            C++天然支持void,但是不允許void*隱式轉(zhuǎn)換到任意類型指針,需要static_cast。

            // legal only in C++

            // 新頭文件
            T* p = static_cast<T*>( malloc(size * sizeof(*p) ));

            // 舊頭文件(目前還有這種編譯器嗎?)
            T* p = reinterpret_cast<T*>( malloc(size * sizeof(*p) ));

            // 當然在C++中應該考慮
            T* p = new T[size];
            // 或者
            std::vector<T> p(size);
            // 但這不是文章討論重點


            3.在C/C++中

            /* legal in both C and C++ */
            /* legal in both new  and old header */
            T
            * p = (T*)malloc(size * sizeof(*p) );

             



            第1種對新頭文件的轉(zhuǎn)型方式,如同代碼第1行所說,在C編譯器中合法。
            因為C++不支持void*到其他指針類型的隱式轉(zhuǎn)換。
            所以,原文章說這是C/C++的誤區(qū),并不準確。
            這僅僅是(引入void類型之后的)C語言中的“非必須”的動作,是否是誤區(qū),還有待考量。

            第2種對新舊頭文件的轉(zhuǎn)型方式,代碼第1行也說了,在C++編譯器中合法。

            因為C編譯器不認識static_cast或者reinterpret_cast。


            第3種,是一種中庸的寫法。
            如同代碼第1行所說:此代碼無論是在C還是C++編譯器,無論是新頭文件還是舊頭文件,都是合法的代碼。是可移植性最好的代碼。

            因為代碼中使用的(C風格的)轉(zhuǎn)型、malloc——C/C++都支持。

            所以,這種寫法并不一定是誤區(qū)或者畫蛇添足
            因為代碼的作者也許比原文章的作者對移植性(C和C++的新舊編譯器)考慮更多。


            一個排版比較好的原文轉(zhuǎn)載鏈接
            http://programmingart.blog.51cto.com/213782/43503

            posted on 2009-03-06 10:16 OwnWaterloo 閱讀(4107) 評論(4)  編輯 收藏 引用

            FeedBack:
            # re: 對malloc的返回值應該如何轉(zhuǎn)型
            2009-03-17 19:01 | C++ Beginner
            學長,問您個很基礎的問題,C風格的強制類型轉(zhuǎn)換會觸發(fā)對應的構造函數(shù)么?static_cast和reinterpret_cast會么?另外這兩個轉(zhuǎn)換符具體做了些什么?  回復  更多評論
              
            # re: 對malloc的返回值應該如何轉(zhuǎn)型
            2009-03-17 21:10 | OwnWaterloo
            @C++ Beginner
            強制轉(zhuǎn)換都不會觸發(fā)構造函數(shù)。

             
            static_cast用于隱式轉(zhuǎn)換過程,如:
            short s; int i;
            = s; //可以,向更寬整數(shù)類型進行隱式轉(zhuǎn)換。
            = i; //警告,向更窄整數(shù)類型轉(zhuǎn)換。
            = static_cast<short>(i); //過程,明確表明代碼作者的意圖,警告消除。
             
            base* b; derived* d;
            = d; // 可以,向上轉(zhuǎn)型,隱式轉(zhuǎn)換。
            = b; // 錯誤,向下轉(zhuǎn)型,不允許。
            = static_cast<derived*>(b); // 可以,向上轉(zhuǎn)型的過程。但不保證正確
             
            object* o; void* p;
            = o; // 可以,任何指針類型都可以隱式轉(zhuǎn)換到void*
            = p; // 過程是錯誤,除非
            = static_cast<object*>(o); // 可以,但不保證正確
             
             
            reinterpret_cast用于整數(shù)和指針之間,無繼承關系的指針之間的轉(zhuǎn)換。
            按照其二進制表示,重新解釋(Re-Interpret),如:
            T* p; intptr_t i;
            = reinterpret_cast<intptr_t>(p);
            // 將p的地址,解釋成一個整數(shù)。
            = reinterpret_cast<T*>(i);
            // 將i的值,解釋成一個指向T的指針。
             
            T1* p1; T2* p2;
            p1 
            = reinterpret_cast<T1*>(p2);
            // 將p2中保存的地址的值,復制到p1。
            // 因為p1是T1*類型的指針,以后對p1的操作,將按T1*來解釋

            // 另外一種方式:
            p1 = static_cast<T1*>static_cast<void*>(p2) );
              回復  更多評論
              
            # re: 對malloc的返回值應該如何轉(zhuǎn)型
            2009-03-17 22:33 | C++ Beginner
            學長,我以碰到過到一個ansi字符串轉(zhuǎn)CString類型的問題,當時發(fā)現(xiàn)可以直接這樣來:

            char a[100] = "123";
            CString str = (CString)a;

            我當初認為是這樣強轉(zhuǎn)觸發(fā)了CString的構造函數(shù),構造了一個CString temp變量,然后賦給str。因為我當時查看反匯編時,發(fā)現(xiàn)它call了一個很長很奇怪的函數(shù),并且看下來確實是構造函數(shù)。

            看了學長的解釋,我忽然發(fā)現(xiàn)難道自己一直以來對強制類型轉(zhuǎn)換理解錯了?額……到底是怎么回事?學長賜教!  回復  更多評論
              
            # re: 對malloc的返回值應該如何轉(zhuǎn)型
            2009-03-17 22:56 | OwnWaterloo
            @C++ Beginner
            如果一個用戶自定義類型C,
            有一個可以通過單個類型為T的參數(shù)進行調(diào)用的構造函數(shù),
            那么,該構造函數(shù)就定義了一個T到C的轉(zhuǎn)換。

            如果該構造函數(shù)是explicit的,T到C的轉(zhuǎn)換是顯式轉(zhuǎn)換。
            如果該構造函數(shù)不是explicit,T到C的轉(zhuǎn)換是隱式轉(zhuǎn)換。

            例如:
            class string {
            char* content_;
            explicit string(const char* source,int length=-1)
            :content_(0)
            {
            if (length==-1)
            length = static_cast<int>(strlen(source));
            content_ = new char[length+1];
            strcpy(source,content_);
            }
            };

            這個構造函數(shù)可以通過單個參數(shù)調(diào)用(第2個參數(shù)有默認值),所以這個構造函數(shù)定義了一個 const char* 到 string 的轉(zhuǎn)換。

            如果有explicit,那么該轉(zhuǎn)換必須是顯式轉(zhuǎn)換:
            string s = static_cast<string>("hello");

            如果沒有explict,該轉(zhuǎn)換可以是隱式轉(zhuǎn)換:
            string s = "hello";


            上面說錯了,這種轉(zhuǎn)換確實會調(diào)用構造函數(shù)。  回復  更多評論
              
            <2025年5月>
            27282930123
            45678910
            11121314151617
            18192021222324
            25262728293031
            1234567

            常用鏈接

            留言簿(8)

            隨筆檔案(16)

            鏈接

            搜索

            •  

            積分與排名

            • 積分 - 197903
            • 排名 - 133

            最新隨筆

            最新評論

            閱讀排行榜

            評論排行榜

            一本久久久久久久| 亚洲一本综合久久| 中文国产成人精品久久不卡| 中文成人久久久久影院免费观看| 伊人久久精品无码二区麻豆| 国产精品久久久久AV福利动漫| 精品无码久久久久久久动漫| 国产精品久久久久久久久久影院| 亚洲国产美女精品久久久久∴| 青草影院天堂男人久久| 久久久久99这里有精品10| 久久精品免费观看| 精品一二三区久久aaa片| 国内精品伊人久久久久网站| 伊人久久综合成人网| 久久久久无码精品国产app| 欧美熟妇另类久久久久久不卡| 青青草原综合久久大伊人导航| 99久久精品毛片免费播放| 久久亚洲精品国产亚洲老地址| 伊人久久综在合线亚洲2019 | 一级做a爱片久久毛片| 亚洲精品无码专区久久同性男| 91秦先生久久久久久久| 久久99国产综合精品女同| 精产国品久久一二三产区区别 | 久久久久久A亚洲欧洲AV冫| 国产成人久久激情91| 久久久无码一区二区三区| 久久亚洲精品国产精品婷婷 | 青青草国产精品久久| 97久久精品人妻人人搡人人玩| 久久久久久久久久久| 亚洲欧美另类日本久久国产真实乱对白| 色偷偷888欧美精品久久久| 97久久精品人妻人人搡人人玩| 国产亚洲欧美精品久久久| 久久99国内精品自在现线| 精品久久久久久久久午夜福利| 久久久久亚洲Av无码专| 久久超乳爆乳中文字幕|