• <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>

            旅途

            如果想飛得高,就該把地平線忘掉

            指針變量的儲單元的大小

            main()
            {
            int i;
            int *p = &i;
            printf("%d",sizeof(p));
            }
            我32位CPU,
            在VC測試: 4
            在TC測試: 2
            請問,指針變量存儲單元的大小與什么有關(guān)?
            指針大小和當(dāng)前系統(tǒng)的地址總線位數(shù)一樣,TC運行在16位模擬器中,所以指針大小是16位即2個字節(jié),vc就是32位的,int類型的大小也和這個一樣是變的,其它類型的大小不會變的
            TC和VC所支持的語言標(biāo)準(zhǔn)不同,跟16位和32位編程無關(guān)。
            TC支持純C語言,純C語言里的6種int型數(shù)據(jù)中只有l(wèi)ong和unsigned long型長度是4字節(jié),另外4種長度是2字節(jié),而VC里支持的C語言全部6種int型數(shù)據(jù)長度全部是4字節(jié)。我們知道,指針的長度和其相應(yīng)的數(shù)據(jù)類型長 度相等,所以int型指針在TC里是2字節(jié),在VC里是4字節(jié)。

            指針的大小是問:一個指針變量占用多少內(nèi)存空間?

             

            分析:既然指針只是要存儲另一個變量的地址,。注意,是存放一變量的地址,而不是存放一個變量本身,所以,不管指針指向什么類型的變量,它的大小總是固定的:只要能放得下一個地址就行!(這是一間只有煙盒大小的“房間”,因為它只需要入一張與著地址的紙條)。

             

            存放一個地址需要幾個字節(jié)?答案是和一個 int 類型的大小相同:4字節(jié)。

             

            所以,若有:

            int* pInt;

            char* pChar;

            bool* pBool;

            float* pFloat;

            double* pDouble;

             

            :sizeof(pInt)、sizeof(pChar)、sizeof(pBool)、sizeof(pFloat)、sizeof(pDouble)的值全部為:4。

             

            (你敢拆電腦嗎?拆開電腦,認得硬盤數(shù)據(jù)線嗎?仔細數(shù)數(shù)那扁寬的數(shù)據(jù)線由幾條細線組成?答案:32條,正是 4 * 8)。





            指向數(shù)組的指針

             

            現(xiàn)在,來說說指針指向一個數(shù)組的情況。

             

            int arr[] = {1,2,3,4,5}; //一個數(shù)組

             

            int* parr; //一個指針。

             

            parr = arr; //沒有&?對啊,對數(shù)組就是不用取址符。

             

            cout << *parr << endl;? //輸出 *parr

             

            先猜想一下,輸出結(jié)果是什么?

             

            最“直覺”的想法是:parr 指向一個數(shù)組,那么輸出時,自然是輸出數(shù)組中的所有元素了。所以答案應(yīng)該是:“12345”了?

            不過,我想,學(xué)過前面的數(shù)組,我們就能知道這種想法錯誤。

             

            正確答案是輸出數(shù)組中的第一個元素: 1 。

             

            接下來,如果是這樣輸出呢?

             

            parr = arr;

            cout << parr << endl;

             

            答案是輸出了arr的地址。就等同于輸出 arr

            cout << arr << endl; 的作用

             

            在這里,難點是要記住,數(shù)組變量本身就是地址。所以有:

             

            1、想讓指針變量存儲一個數(shù)組的地址(想讓指針變量指向一個數(shù)組)時,不用取址符。

            2、解析一個指向數(shù)組的指針,得到的是數(shù)組的第一個元素



            偏移指針


            int* parr2;

             

            parr2 = parr + 1;

            加1后,指針指向了下一個元素。由于這是一個 int 類型的數(shù)組,每個元素的大小是4個字節(jié)。所以第二個元素的地址是10000014。

             

            重點 & 易錯點:對指針 進行加1操作,得到的是下一個元素的地址,而不是原有地址值直接加1。

             

            知到了如何“加”,也就知道了如何“減”。減以后,得到的是上一個元素的大小。

             

            所以,一個類型為 T 的指針的移動,以 sizeof(T) 為移動單位。

            所以,一個類型為 T 的指針的移動,以 sizeof(T) 為移動單位。

             

            比如:

            int* pInt; 移動單位為 sizeof(int) 。即:4。而 char* pChar; 移動單位為 sizeof(char)。即1。



            指針的最小移動單位

             

            int arr[6] = {101,102,103,104,105,106};

            int* pI = arr;

             

            cout << "pI 是一個指向整型數(shù)組的指針,移動單位:4字節(jié)" << endl;

             

            for (int i = 0; i < 6; i++)

            ?? cout << "pI + " << i << " ----> " << pI + i << ", *(pI + i) = "? << *(pI + i) << endl;??

             

            cout << "------------------------------------" << endl;

             

            //接下 來是一個指向char類型數(shù)組的指針:

            char str[4] = {'a','b','c','d'}

             

            char*? pC = str;

             

            cout << "pC 是一個指向字符數(shù)組的指針,移動單位:1字節(jié)" << endl;

            for (int i=0; i < 4; i++)

            ??? cout << "pC + " << i << " ----> " << (int)(pC + i) << ", *(pC + i) = "? << *(pC + i) << endl;??

             

            system("PAUSE");

             

            輸出結(jié)果:

            (指針的最小移動單位)

            每一行中,程序先輸出指針加上偏移量以后的值(地址),比如:1245024、1245028;然后輸出偏移后指針指向的值,比如101,102。

            查看移動前后指針存儲的地址,我們就可以計算出移動單位。1245028 - 1245024 = 4 (byte)。

             


            * (地址解析符)與 ++ 的優(yōu)先級


            指針的前置++與后置++的區(qū)別

             

            //代碼片段一:

            int arr[] = {1,2,3,4,5,6,7,8,9,10};

            int* parr1 = arr;

             

            int A = *parr1++;

            int B = *parr1;

             

            cout << "A = " << A << endl;

            cout << "B = " << B << endl;

             

            輸出結(jié)果:

             

            A = 1;

            B = 2;

             

            代碼片段二:

             

            int arr[] = {1,2,3,4,5,6,7,8,9,10};

            int* parr1 = arr;

             

            int A = *++parr1;

            int B = *parr1;

             

            cout << "A = " << A << endl;

            cout << "B = " << B << endl;

             

            輸出結(jié)果:

             

            A = 2;

            B = 2;

             

             

            19.8.7* (地址解析符)與 ++ 的優(yōu)先級

             

            從上例中我們可以看到。當(dāng) * (作為地址解析符) ++ 同時作用在指針時,不管是前置還是++,都要比*有更高的優(yōu)先級。比如代碼中的:

             

            int A = *parr++;

             

            我們來一個反證:假設(shè)*的優(yōu)先級比++高,那么,應(yīng)先計算:

             

            *parr 結(jié)果為: 1 (第一個元素)

            然后計算? 1++ ,結(jié)果為:2。

             

            但實驗發(fā)現(xiàn)結(jié)果為 1,這個1 又是如何來的呢?有點復(fù)雜。

            首先,++優(yōu)先計算,所以應(yīng)先計算:parr++

            結(jié)果是parr指向了下一個元素:2。因為這是后置++,所以,它必須返回自己計算之前的值;所以,在改變parr之前,編譯程序會生成一個臨時變量,計算原先parr的值。我們假設(shè)為 old_parr 。下面是第二步操作:

            A = *old_parr

            由于 old_parr parr 原來的值,指向第一個元素,所以 A 得到值: 1 。

             

            可見,后置 ++ 或 后置-- 操作,需要系統(tǒng)生成一個臨時變量。

            如果這個變量占用的內(nèi)存空間很小(比如指針類型總是只有4字節(jié)),則該操作帶來的,對程序速度的負面影響可以不計,如果變量很大,并且多次操作。則應(yīng)在可能的情況下,盡量使用前置++或前置--操作。

             

            你自然會問,前置++就不會產(chǎn)生臨時變量嗎?我們來試試。

             

            int A = *++parr;

             

            同樣,++優(yōu)先級大于*,所以先計算:++parr

            結(jié)果parr 指向下一個元素。因為這是前置++,所以,它只需要返回的,正是自己計算之后的值。下一步是:

            A = *parr;

            由于 parr 此時已完成++操作,指向下一個元素。所以 A 得到值: 2

             

            19.8.8上機實驗六:指針的 ++與--操作

             

            int arr [] = {1,2,3,4,5};

             

            int* parr = arr;

             

            //前進 ++

            for (int i=0; i < 5; i++) //如果為了優(yōu)化,你可以寫成: ++i :)

            {

            ?? cout << *parr << endl;

            ?? parr++;?? //如果為了優(yōu)化,你可以寫成:++parr :D

            ?

            ?? /*

            ???? 上面兩句你還可以寫成一句:?

            ???? cout << *parr++ << endl;? //這里,你可不能為了優(yōu)化寫成: *++parr.

            ? */

            }

             

            //后退 --:

            for (int i=0; i < 5; i++)

            {

            ?? parr--;

            ?? cout << *parr << endl;

            }

             

            輸出結(jié)果:

            (指針的++與--)

             


            posted on 2007-09-06 01:23 旅途 閱讀(1395) 評論(0)  編輯 收藏 引用 所屬分類: C/C++

            伊人久久精品影院| 国产精品美女久久久久网| 亚洲午夜精品久久久久久浪潮 | 77777亚洲午夜久久多喷| 99精品久久精品一区二区| jizzjizz国产精品久久| 国内精品久久久久久久久电影网| 久久人人爽人人精品视频| 欧美牲交A欧牲交aⅴ久久| 久久精品无码一区二区三区日韩 | 亚洲人成网站999久久久综合| 一级做a爰片久久毛片免费陪| 久久99中文字幕久久| 7777精品伊人久久久大香线蕉 | 久久久亚洲裙底偷窥综合| 国产精品热久久无码av| 日韩人妻无码一区二区三区久久| 伊人色综合久久| 久久精品亚洲精品国产色婷| 精品久久久久久久中文字幕| 国产精品无码久久综合| 久久香综合精品久久伊人| 99久久无码一区人妻| 久久超碰97人人做人人爱| 2021久久精品免费观看| 久久精品一区二区影院| 草草久久久无码国产专区| 999久久久免费精品国产| 婷婷久久久亚洲欧洲日产国码AV| 久久婷婷色综合一区二区| 国产成人99久久亚洲综合精品 | 欧美激情精品久久久久| 精品国产乱码久久久久久郑州公司| 久久亚洲中文字幕精品一区| 亚洲精品美女久久久久99小说 | 亚洲成av人片不卡无码久久| 狠狠人妻久久久久久综合| 伊人丁香狠狠色综合久久| 99久久综合国产精品二区| 久久精品国产精品亚洲人人 | 99热都是精品久久久久久|