<em id="0a85b"><option id="0a85b"></option></em>

<abbr id="0a85b"></abbr>

      <nobr id="0a85b"></nobr>
        <tr id="0a85b"></tr>
        9久久伊人精品综合,亚洲一区精品视频在线,成 人免费va视频,国产一区二区三区黄网,99国产精品永久免费视频,亚洲毛片多多影院,精品久久久无码人妻中文字幕,无码国产欧美一区二区三区不卡
        學習啦>學習英語>英語其它>

        c++中是什么意思

        時間: 玉蓮928 分享

          ->在C++中是什么意思?下面是學習啦小編給大家整理的c++中是什么意思,供大家參閱!

          ->在C++中是什么意思

          -> 在c++中為取成員運算符

          對象指針/結構指針->成員變量/成員函數

          該運算符的作用,取得指針所指向的類對象或結構變量的成員變量的值,或者調用其成員函數。

          例如:

          int *p;

          struct student

          { char name[20];

          int num;

          }stu;

          stu={xiaoming,90};

          p=&stu;

          cout<<stu.name<<stu.num<<endl;

          cout<<p->name<<p->num<<endl;

          這兩個cout的效果是一樣的

          ::在c++中的表示含義

          ::在c++中表示作用域,和所屬關系

          比如

          class A

          {

          public:

          int test();

          }

          int A::test()//表示test是屬于A的

          {

          return 0;

          }

          類似的還有其他,就不列舉了

          --------------------

          比如

          int a;

          void test ()

          {

          int a = ::a;//用全局變量a,給本地變量a賦值

          c++中的宏使用

          眾多C++書籍都忠告我們C語言宏是萬惡之首,但事情總不如我們想象的那么壞,就如同goto一樣。宏有

          一個很大的作用,就是自動為我們產生代碼。如果說模板可以為我們產生各種型別的代碼(型別替換),

          那么宏其實可以為我們在符號上產生新的代碼(即符號替換、增加)。

          關于宏的一些語法問題,可以在google上找到。相信我,你對于宏的了解絕對沒你想象的那么多。如果你

          還不知道#和##,也不知道prescan,那么你肯定對宏的了解不夠。

          我稍微講解下宏的一些語法問題(說語法問題似乎不妥,macro只與preprocessor有關,跟語義分析又無關):

          1. 宏可以像函數一樣被定義,例如:

          #define min(x,y) (x<y?x:y) //事實上這個宏存在BUG

          但是在實際使用時,只有當寫上min(),必須加括號,min才會被作為宏展開,否則不做任何處理。

          2. 如果宏需要參數,你可以不傳,編譯器會給你警告(宏參數不夠),但是這會導致錯誤。如C++書籍中所描

          述的,編譯器(預處理器)對宏的語法檢查不夠,所以更多的檢查性工作得你自己來做。

          3. 很多程序員不知道的#和##

          #符號把一個符號直接轉換為字符串,例如:

          #define STRING(x) #x

          const char *str = STRING( test_string ); str的內容就是"test_string",也就是說#會把其后的符號

          直接加上雙引號。

          ##符號會連接兩個符號,從而產生新的符號(詞法層次),例如:

          #define SIGN( x ) INT_##x

          int SIGN( 1 ); 宏被展開后將成為:int INT_1;

          4. 變參宏,這個比較酷,它使得你可以定義類似的宏:

          #define LOG( format, ... ) printf( format, __VA_ARGS__ )

          LOG( "%s %d", str, count );

          __VA_ARGS__是系統預定義宏,被自動替換為參數列表。

          5. 當一個宏自己調用自己時,會發生什么?例如:

          #define TEST( x ) ( x + TEST( x ) )

          TEST( 1 ); 會發生什么?為了防止無限制遞歸展開,語法規定,當一個宏遇到自己時,就停止展開,也就是

          說,當對TEST( 1 )進行展開時,展開過程中又發現了一個TEST,那么就將這個TEST當作一般的符號。TEST(1)

          最終被展開為:1 + TEST( 1) 。

          6. 宏參數的prescan,

          當一個宏參數被放進宏體時,這個宏參數會首先被全部展開(有例外,見下文)。當展開后的宏參數被放進宏體時,

          預處理器對新展開的宏體進行第二次掃描,并繼續展開。例如:

          #define PARAM( x ) x

          #define ADDPARAM( x ) INT_##x

          PARAM( ADDPARAM( 1 ) );

          因為ADDPARAM( 1 ) 是作為PARAM的宏參數,所以先將ADDPARAM( 1 )展開為INT_1,然后再將INT_1放進PARAM。

          例外情況是,如果PARAM宏里對宏參數使用了#或##,那么宏參數不會被展開:

          #define PARAM( x ) #x

          #define ADDPARAM( x ) INT_##x

          PARAM( ADDPARAM( 1 ) ); 將被展開為"ADDPARAM( 1 )"。

          使用這么一個規則,可以創建一個很有趣的技術:打印出一個宏被展開后的樣子,這樣可以方便你分析代碼:

          #define TO_STRING( x ) TO_STRING1( x )

          #define TO_STRING1( x ) #x

          TO_STRING首先會將x全部展開(如果x也是一個宏的話),然后再傳給TO_STRING1轉換為字符串,現在你可以這樣:

          const char *str = TO_STRING( PARAM( ADDPARAM( 1 ) ) );去一探PARAM展開后的樣子。

          7. 一個很重要的補充:就像我在第一點說的那樣,如果一個像函數的宏在使用時沒有出現括號,那么預處理器只是

          將這個宏作為一般的符號處理(那就是不處理)。

          我們來見識一下宏是如何幫助我們自動產生代碼的。如我所說,宏是在符號層次產生代碼。我在分析Boost.Function

          模塊時,因為它使用了大量的宏(宏嵌套,再嵌套),導致我壓根沒看明白代碼。后來發現了一個小型的模板庫ttl,說的

          是開發一些小型組件去取代部分Boost(這是一個好理由,因為Boost確實太大)。同樣,這個庫也包含了一個function庫。

          這里的function也就是我之前提到的functor。ttl.function庫里為了自動產生很多類似的代碼,使用了一個宏:

          #define TTL_FUNC_BUILD_FUNCTOR_CALLER(n) /

          template< typename R, TTL_TPARAMS(n) > /

          struct functor_caller_base##n /

          ///...

          該宏的最終目的是:通過類似于TTL_FUNC_BUILD_FUNCTOR_CALLER(1)的調用方式,自動產生很多functor_caller_base模板:

          template <typename R, typename T1> struct functor_caller_base1

          template <typename R, typename T1, typename T2> struct functor_caller_base2

          template <typename R, typename T1, typename T2, typename T3> struct functor_caller_base3

          ///...

          那么,核心部分在于TTL_TPARAMS(n)這個宏,可以看出這個宏最終產生的是:

          typename T1

          typename T1, typename T2

          typename T1, typename T2, typename T3

          ///...

          我們不妨分析TTL_TPARAMS(n)的整個過程。分析宏主要把握我以上提到的一些要點即可。以下過程我建議你翻著ttl的代碼,

          相關代碼文件:function.hpp, macro_params.hpp, macro_repeat.hpp, macro_misc.hpp, macro_counter.hpp。

          so, here we Go

          分析過程,逐層分析,逐層展開,例如TTL_TPARAMS(1):

          #define TTL_TPARAMS(n) TTL_TPARAMSX(n,T)

          => TTL_TPARAMSX( 1, T )

          #define TTL_TPARAMSX(n,t) TTL_REPEAT(n, TTL_TPARAM, TTL_TPARAM_END, t)

          => TTL_REPEAT( 1, TTL_TPARAM, TTL_TPARAM_END, T )

          #define TTL_TPARAM(n,t) typename t##n,

          #define TTL_TPARAM_END(n,t) typename t##n

          #define TTL_REPEAT(n, m, l, p) TTL_APPEND(TTL_REPEAT_, TTL_DEC(n))(m,l,p) TTL_APPEND(TTL_LAST_REPEAT_,n)(l,p)

          注意,TTL_TPARAM, TTL_TPARAM_END雖然也是兩個宏,他們被作為TTL_REPEAT宏的參數,按照prescan規則,似乎應該先將

          這兩個宏展開再傳給TTL_REPEAT。但是,如同我在前面重點提到的,這兩個宏是function-like macro,使用時需要加括號,

          如果沒加括號,則不當作宏處理。因此,展開TTL_REPEAT時,應該為:

          => TTL_APPEND( TTL_REPEAT_, TTL_DEC(1))(TTL_TPARAM,TTL_TPARAM_END,T) TTL_APPEND( TTL_LAST_REPEAT_,1)(

          TTL_TPARAM_END,T)

          這個宏體看起來很復雜,仔細分析下,可以分為兩部分:

          TTL_APPEND( TTL_REPEAT_, TTL_DEC(1))(TTL_TPARAM,TTL_TPARAM_END,T)以及

          TTL_APPEND( TTL_LAST_REPEAT_,1)(TTL_TPARAM_END,T)

          先分析第一部分:

          #define TTL_APPEND( x, y ) TTL_APPEND1(x,y) //先展開x,y再將x,y連接起來

          #define TTL_APPEND1( x, y ) x ## y

          #define TTL_DEC(n) TTL_APPEND(TTL_CNTDEC_, n)

          根據先展開參數的原則,會先展開TTL_DEC(1)

          => TTL_APPEND(TTL_CNTDEC_,1) => TTL_CNTDEC_1

          #define TTL_CNTDEC_1 0 注意,TTL_CNTDEC_不是宏,TTL_CNTDEC_1是一個宏。

          => 0 , 也就是說,TTL_DEC(1)最終被展開為0。回到TTL_APPEND部分:

          => TTL_REPEAT_0 (TTL_TPARAM,TTL_TPARAM_END,T)

          #define TTL_REPEAT_0(m,l,p)

          TTL_REPEAT_0這個宏為空,那么,上面說的第一部分被忽略,現在只剩下第二部分:

          TTL_APPEND( TTL_LAST_REPEAT_,1)(TTL_TPARAM_END,T)

          => TTL_LAST_REPEAT_1 (TTL_TPARAM_END,T) // TTL_APPEND將TTL_LAST_REPEAT_和1合并起來

          #define TTL_LAST_REPEAT_1(m,p) m(1,p)

          => TTL_TPARAM_END( 1, T )

          #define TTL_TPARAM_END(n,t) typename t##n

          => typename T1 展開完畢。

          雖然我們分析出來了,但是這其實并不是我們想要的。我們應該從那些宏里去獲取作者關于宏的編程思想。很好地使用宏

          看上去似乎是一些偏門的奇技淫巧,但是他確實可以讓我們編碼更自動化。

          

        看過c++中是什么意思的人還看了:

        1.關于c++的面試題

        2.c中bool的用法

        3.java基礎知識java是一門面向對象編程語言,不...

        4.java實習心得感悟

        2674039 主站蜘蛛池模板: 亚洲av成人一区二区三区| 欧美日韩亚洲中文字幕二区| 4虎四虎永久在线精品免费| 真实国产乱啪福利露脸| 国产女人被狂躁到高潮小说| 噜噜综合亚洲av中文无码| 成人白浆一区二区三区在线观看 | 亚洲精品乱码免费精品乱| 久久精品国产福利一区二区| 国产毛片精品av一区二区| 最新日韩精品中文字幕| 无码AV无码免费一区二区| 日本一高清二区视频久二区| 久久精品国产国语对白 | 国内精品视频区在线2021| 亚洲日韩VA无码中文字幕| 熟妇人妻av无码一区二区三区| 亚洲欧美在线观看品| 国产欧美日韩亚洲一区二区三区| 2020最新无码福利视频| 国产精品一二三入口播放| 国产啪视频免费观看视频| 日夜啪啪一区二区三区| 日韩欧美不卡一卡二卡3卡四卡2021免费 | 扒开粉嫩的小缝隙喷白浆视频 | 国产精品视频中文字幕| 日韩中文字幕人妻一区| 狠狠色噜噜狠狠亚洲AV| 亚洲avav天堂av在线网毛片| 强开少妇嫩苞又嫩又紧九色 | 边做边爱完整版免费视频播放| 日韩黄色av一区二区三区| 精品国产一区二区三区大| 国产最新AV在线播放不卡| 日本一区二区三区激情视频| 国产一卡2卡三卡4卡免费网站| 综合亚洲网| 国产一卡2卡三卡4卡免费网站 | 一区二区三区放荡人妻| 国产熟女高潮一区二区三区| 五月国产综合视频在线观看|