青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品

聚星亭

吾笨笨且懶散兮 急須改之而奮進
posts - 74, comments - 166, trackbacks - 0, articles - 0
  C++博客 :: 首頁 :: 新隨筆 :: 聯系 :: 聚合  :: 管理

 

       本來這一講是打算講指針的,可是考慮到C++中指針的更多操作,我不想講一個問題分成兩部分,因此,我就先講C++的部分,等需要用到指針的時候,我們專門寫一個專題講述指針部分。    好進入正題。

 

       大家都知道,C++是在C的基礎上擴展了好多東西,其中好多是思想上的轉變,因此,很多C++中的東西,我們都可以用C語言來模擬出來,比如構造、析構等等。       但是也有很多是C++編譯器擴展的東西,我們沒有辦法用C去模擬,因此,我寫了這個小節,重在理解……

 

       C++中,零散的知識點比較多,因此,我每個專題盡量減少其內容,而增加更新頻率,希望大家能有助于大家的理解。

 

              一、宏定義的擴展——constinline

#define 宏定義,是C的知識范疇,由于全都都語法范疇且又僅僅是簡單的查找替換因此我沒有為它單獨的列一個專題,大家可以自己學習一下。我想如果要講這個內容,也得等我們課程進行到MFC或者WTL的時候再捎帶提一下。

 

學習過#define 以后,我們知道,它一般用來定義常量,由于它可以帶參數,且因沒有函數調用時傳參的復雜過程而速度快的優點,因此它經常被當作“函數”使用。

 

但是#define也是有缺點的,比如它定義的常量沒有類型信息,它定義的“函數”(帶參宏)不安全等原因,C++對這個功能進行了擴充,分別用constinline兩個關鍵字來分別代替無參宏定義常量,帶參宏定義函數。下面分別看一下它們的用法及原理。

1.         const 的用法。

const用于定義常量,基礎語法如下:

const      類型             常量名

類型       const            常量名

 

關于const的基礎語法:const 只是對除類型外,緊靠其右邊的元素。

                     比如:

// 這時const右面除了類型就是nCountNum變量,所以,nCountNum的內容不可以改變。

const int nCountNum = 5;

 

// const右邊是*,在指針中*表示內容,所以pnCountNum指針指向的變量內容不可以被改變。

const int *pnCountNum = nCountNum;

 

// const右邊還是*,所以同上

int  const  *pnCountNum = nCountNum;

 

// const右邊是指針變量名,指針變量代表地址,所以pnCountNum中的內容不可以被改變。

int  *  const  pnCountNum = nCountNum;

 

OK,知道了以上的語法知識,我們需要了解,這種常量跟我們用宏定義的常量是有區別的,因為這個是編譯器級別的常量,我們可以通過指針來修改它的內容,當然,若在代碼中使用const變量,則直接在代碼中使用其常量值,如下面的代碼:

    const int nCount = 50;

 

    int tmpNum = 0;

    scanf("%d", &tmpNum);  // 防止編譯器自動優化代碼

 

    printf("%d", tmpNum + nCount);

// 26:       printf("%d", tmpNum + nCount);

//             0040D427   mov         ecx,dword ptr [ebp-8]

//             0040D42A   add         ecx,32h                // 直接當作常量使用

//             0040D42D   push        ecx

//             0040D42E   push        offset string "%d" (0042201c)

//             0040D433   call        printf (0040f900)

 

通過上面的代碼,我們可以知道,nCount這個常量有自己的棧地址,只要有地址,我們肯定是可以用指針來修改它內容的。

                    

                     但是,通過

//             0040D42A   add         ecx,32h                // 直接當作常量使用

這一句,我們清楚,這個代碼是直接將nCount 當做常量使用,所以即使我們更改了nCount 中的內容,這里的值也不會改變了。

 

2.         inline 的用法。

是的,雖然帶參宏的使用提高了編碼的效率,從一定程度上提高了程序的運行效率(因為它少了函數調用的壓棧出棧等操作)而被MFCWTL等廣泛的應用,但是不可否認用帶參宏的不安全性,在C++中引入了inline函數的概念,它用inline函數來代替帶參宏的功能。

 

                     到這里,我們就不難理解,inline函數的特點了:在函數被調用的地方將代碼展開。比如下面的代碼:

/************************************************************************/

/* C++中用內聯函數來代替有參宏,跟有參宏一樣,它在調用的地方原地展開

/* 因此,內聯函數也同有參宏一樣,在同一個代碼中存在多份拷貝。

/* 所以,內聯函數一般聲明在頭文件中就可以了。

 

/*   :

/*         內聯函數中不能包含switchwhile等復雜結構,如果邏輯復雜了編譯器

/*     就將它當做普通函數處理。

/************************************************************************/

inline int add(int a, int b, int c)

{

    return a+b+c;

}

 

int main(int argc, char* argv[])

{

    int a,b,c;

    scanf("%d %d %d", &a, &b, &c);

    printf("%d", add(a,b,c));

       return 0;

}

 

              由于DEBUG方式編譯的程序不做任何優化,所以,我們release方式編譯此代碼,得到如下信息:

/*DEBUG 模式下,內聯就是普通函數,release模式下才真正的內聯。*/

 

// 00401000 >/$  83EC 0C       sub     esp, 0xC                         ;  _main

// 00401003  |.  8D4424 08     lea     eax, dword ptr [esp+0x8]

// 00401007  |.  8D4C24 04     lea     ecx, dword ptr [esp+0x4]

// 0040100B  |.  8D5424 00     lea     edx, dword ptr [esp]

// 0040100F  |.  50            push    eax

// 00401010  |.  51            push    ecx

// 00401011  |.  52            push    edx

// 00401012  |.  68 34804000   push    offset <??_C@_08NNKG@?$CFd?5?$CF>;  ASCII "%d %d %d"

// 00401017  |.  E8 55000000   call    <_scanf>

// 0040101C  |.  8B4424 10     mov     eax, dword ptr [esp+0x10]

// 00401020  |.  8B4C24 14     mov     ecx, dword ptr [esp+0x14]

// 00401024  |.  03C1          add     eax, ecx

// 00401026  |.  8B4C24 18     mov     ecx, dword ptr [esp+0x18]

// 0040102A  |.  03C1          add     eax, ecx

// 0040102C  |.  50            push    eax

// 0040102D  |.  68 30804000   push    offset <??_C@_02MECO@?$CFd?$AA@> ;  ASCII "%d"

// 00401032  |.  E8 09000000   call    <_printf>

// 00401037  |.  33C0          xor     eax, eax

// 00401039  |.  83C4 24       add     esp, 0x24

// 0040103C  \.  C3            retn

        Inline函數的代碼被展開貼到main函數中的,是吧……

        當然,并不是所有的代碼都可以被寫程序inline函數的,它有如下幾點要求:

1、  inline函數中的代碼邏輯不可過于復雜

2、  不能包含如循環,switch等復雜的語句

 

 否則,編譯器會將inline函數當做一個普通函數處理。

 

二、         指針與引用。

我想,雖然我沒有系統的講過指針,但是根據我們第一課中的內容的提示,我相信,大家一定能夠理解指針的概念。所以我這一節不詳細講述指針的概念,

 

       引用,是C++提出來的一個新的概念,不多廢話,看代碼:

/************************************************************************/

/* 引用是C++新增加的運算符。

/* 基本用法如下:

/************************************************************************/

void BaseUse()

{

    printf("/-----------基礎用法---------------/\r\n");

    int nBuf = 0;

    scanf("%d", &nBuf);     // 防止編譯器自動優化

 

    int &a1 = nBuf;     // 引用的用法

    int *pa1 = &nBuf;   // 指針是變量的地址

    printf("%d    %d    %d\r\n", nBuf, a1, *pa1);

}

上面代碼我們給出了引用的最基本的用法,為了我們能夠將它與指針加以區別,我跟一指針一起使用,然后我們通過分析它的反匯編代碼,我們給出他們的區別。

 

由于Release模式下開了O2選項,對代碼進行了優化,所以我們看DEBUG模式的代碼

0040D77F  |.  8D45 FC       lea     eax, dword ptr [ebp-0x4]

0040D782  |.  50            push    eax

0040D783  |.  68 1C204200   push    0042201C               ; /format = "%d"

0040D788  |.  E8 D3210000   call    scanf                    ; \scanf

0040D78D  |.  83C4 08       add     esp, 0x8

0040D790  |.  8D4D FC       lea     ecx, dword ptr [ebp-0x4]    ; 給引用賦值

0040D793  |.  894D F8       mov     dword ptr [ebp-0x8], ecx

0040D796  |.  8D55 FC       lea     edx, dword ptr [ebp-0x4]     ; 指針的用法

0040D799  |.  8955 F4       mov     dword ptr [ebp-0xC], edx

0040D79C  |.  8B45 F4       mov     eax, dword ptr [ebp-0xC]    ; 取內容

       

由此,我們知道,引用時當作指針使用的,他們的傳遞方式一摸一樣,只是,引用在操作的時候,多了一個取內容的操作。

      

       我們得出結論如下:

引用就是指針取內容。

指針就是引用取地址。

 

當然,如果我的這節課程到這里就結束了,似乎有點對不住各位同學,因為我這里似乎只講述了語法的東西,下面呢,我由引用的話題,講一下引用的一些高級用法。

 

// 定義一個學生信息的結構體

typedef struct _DATA_STUDENT_INFO 

{

    int     nID;

    char    *szName;

    char    chsex;

}DATA_STUDENT_INFO, *PDATA_STUDENT_INFO;

 

// 聲明一個全局變量

DATA_STUDENT_INFO g_DSI[2] = {0};

 

// 返回一個結構體的引用

DATA_STUDENT_INFO& GetStudentObj(int nIndex)

{

    return g_DSI[nIndex];

}

 

int ExtendUse()

{

    printf("/-----------擴展用法---------------/\r\n");

    GetStudentObj(0).chsex = 1;

    GetStudentObj(0).szName = "besterChen";

    GetStudentObj(0).nID = 1;

   

    printf("I  D: %d\r\n", GetStudentObj(0).nID);

    printf("Name: %s\r\n", GetStudentObj(0).szName);

    printf(" Sex: %d\r\n", GetStudentObj(0).chsex);

   

    return 0;

}

由于引用時指針取內容,所以,GetStudentObj返回的就是一個對象,因此可以直接對它的成員進行操作。

 

三、         學習小結

我臨時決定講C++的,所以指針的專題等后期再講,因為一來我不想讓指針的話題分成兩部分討論,二來我還沒有準備好講指針將的透徹(其實主要就是沒有信心)。

 

另外,我覺得,我們現在打下的那些基礎足夠我們學C++了,雖然好多朋友都說:沒有必要學習C語言,直接學C++即可,但是我始終相信學習C語言是有必要的,因為C語言著重內存結構(好讓我們把握住程序的本質),C++著重于設計思想(也有好多的語法知識要學)。

 

直到上個專題內存操作,我們幾乎把C語言都講完了(當然僅僅是讓人迷糊的關鍵部分),本專題是C++課程的開始,我也著重于內存,因為我始終相信,掌握了內存結構就掌握了編程的本質。

 
       如果一直讀我的破爛文章到現在的朋友一定會發現,這個系列不是給沒有一點基礎的朋友準備的,也不是為了講述語法知識的,所以,我更新的很慢,這個更新速度足矣讓大家補好自己的基礎。

 

       所以,C++部分我會盡快的更新,因為大家都有基礎了。

 

       最后,祝大家成功。

青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品
  • <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>
            亚洲女人天堂成人av在线| 亚洲精品欧美日韩| 亚洲免费在线| 亚洲人成啪啪网站| 国产午夜精品全部视频在线播放| 欧美激情网友自拍| 久久精品成人欧美大片古装| 亚洲一品av免费观看| 亚洲人成在线观看| 欧美jizz19hd性欧美| 久久久久久**毛片大全| 午夜亚洲福利| 亚洲一级网站| 这里只有精品电影| 夜夜嗨av一区二区三区| 亚洲国产国产亚洲一二三| 国产亚洲网站| 国产一区二区三区免费在线观看 | 欧美freesex交免费视频| 欧美一区二区在线看| 亚洲性色视频| 一区二区三区四区五区视频| 亚洲精品韩国| 亚洲欧洲日韩综合二区| 亚洲国产欧美一区| 亚洲高清自拍| 亚洲国产精品v| 亚洲国产黄色| 亚洲电影免费观看高清完整版在线| 玖玖国产精品视频| 久久免费视频网站| 六十路精品视频| 欧美va亚洲va日韩∨a综合色| 久久综合99re88久久爱| 久久综合亚州| 欧美激情精品久久久久久大尺度| 欧美xx视频| 亚洲第一主播视频| 亚洲国产美女| 99精品视频免费在线观看| 99精品视频一区| 亚洲在线中文字幕| 欧美一区二区三区在线播放| 久久精品免费播放| 噜噜噜在线观看免费视频日韩| 老司机午夜精品视频| 蜜臀av在线播放一区二区三区| 每日更新成人在线视频| 欧美精品亚洲二区| 国产精品高清网站| 国产在线观看91精品一区| **欧美日韩vr在线| 日韩视频国产视频| 午夜精品一区二区三区在线播放| 久久xxxx| 亚洲大胆av| 亚洲美女精品久久| 亚洲一区二区在线| 久久久91精品国产| 欧美日韩国产精品成人| 欧美天堂在线观看| 国产一区二区高清不卡| 亚洲国产美女精品久久久久∴| 99www免费人成精品| 亚洲欧美视频一区| 蜜臀久久99精品久久久久久9| 亚洲国产成人精品久久| 亚洲一区二区三区在线观看视频 | 欧美一区二区三区在线免费观看 | 在线日韩av永久免费观看| 亚洲激情视频| 亚洲欧美日韩区 | 亚洲神马久久| 久久久精品tv| 欧美日韩视频不卡| 国产夜色精品一区二区av| 亚洲蜜桃精久久久久久久| 午夜老司机精品| 欧美激情小视频| 亚洲综合二区| 欧美日本国产| 亚洲午夜高清视频| 久久久久久久综合色一本| 亚洲私拍自拍| 久久频这里精品99香蕉| 亚洲日本激情| 欧美在线视频一区二区三区| 欧美激情中文字幕在线| 国产一区二区三区久久精品| a4yy欧美一区二区三区| 久久中文久久字幕| 亚洲免费久久| 麻豆亚洲精品| 国产日韩一区二区三区| 一区二区黄色| 欧美不卡一区| 欧美一区激情视频在线观看| 欧美日韩黄色一区二区| 亚洲国产91| 久久久久久久久久久久久女国产乱 | 久久精品亚洲精品国产欧美kt∨| 欧美激情网站在线观看| 欧美在线国产| 国产精品一区三区| 中日韩美女免费视频网址在线观看 | 国产精品久久久久久久久久免费 | 一区二区三区黄色| 欧美高清成人| 在线免费观看一区二区三区| 久久成人羞羞网站| 亚洲视频在线一区| 欧美日韩综合在线| 99视频精品| 亚洲国语精品自产拍在线观看| 久久久久免费| 黄色亚洲在线| 久久免费国产精品| 久久riav二区三区| 国产视频久久久久久久| 先锋影音国产一区| 亚洲无线一线二线三线区别av| 欧美日韩一区二区在线| 一本一道久久综合狠狠老精东影业| 亚洲电影免费观看高清完整版在线观看 | 亚洲视频免费在线| 最近看过的日韩成人| 欧美成人性网| 亚洲美女黄网| 亚洲免费av片| 欧美日韩在线免费| 亚洲一二区在线| 一区二区三区国产在线| 国产精品国内视频| 午夜精品久久一牛影视| 亚洲性感激情| 国产日韩专区在线| 久久久综合免费视频| 久久久av网站| 91久久黄色| 亚洲精品国产精品久久清纯直播 | 亚洲欧美日本日韩| 亚洲在线中文字幕| 国产午夜精品久久| 快she精品国产999| 欧美gay视频激情| 一本色道久久99精品综合| 一本一本久久a久久精品牛牛影视| 欧美午夜激情在线| 欧美一区二区三区婷婷月色| 久久精品国产久精国产思思| 亚洲福利国产| 亚洲免费观看在线观看| 国产精品免费小视频| 欧美在线观看你懂的| 久久久久久**毛片大全| 亚洲精品免费在线播放| 一本色道久久综合亚洲精品婷婷| 国产精品一区二区欧美| 久久偷看各类wc女厕嘘嘘偷窃| 美女露胸一区二区三区| 亚洲一区二区久久| 欧美在线观看视频在线| 91久久国产综合久久91精品网站| 日韩午夜免费视频| 国产亚洲欧美在线| 亚洲国产精品日韩| 国产精品普通话对白| 老司机午夜精品视频| 欧美激情精品久久久久久蜜臀| 亚洲欧美日韩区| 久热精品视频在线观看| 亚洲天堂免费在线观看视频| 欧美在线欧美在线| 日韩香蕉视频| 欧美在线观看一区二区| 夜夜爽av福利精品导航| 欧美亚洲系列| 一本色道久久综合亚洲精品不| 午夜欧美大尺度福利影院在线看| 亚洲激情六月丁香| 小嫩嫩精品导航| 亚洲精品一线二线三线无人区| 亚洲在线黄色| 亚洲精品乱码久久久久| 性欧美激情精品| 一区二区三区精品| 久久久久国产精品麻豆ai换脸| 亚洲综合首页| 欧美成人69av| 久久久爽爽爽美女图片| 国产精品黄页免费高清在线观看| 免费黄网站欧美| 国产麻豆视频精品| 亚洲精品久久7777| 亚洲国产经典视频| 香蕉成人伊视频在线观看| 亚洲午夜视频| 欧美激情视频免费观看| 免费在线欧美黄色| 国产视频在线观看一区二区三区|