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

隨筆-145  評論-173  文章-70  trackbacks-0

綜述

本節課的主要內容是關于泛型數據的拷貝,雖然是使用C語言實現,并且沒有用到C++中的模板這種泛型編程技術,但是效果卻非常好。本節內容緊接上節所將的字節位拷貝的知識,充分利用了字節拷貝技術。

筆記

由于內容和例子不斷深入,實際核心內容則比較集中,因此這里只進行總結討論。

引例

本節所有的例子都是針對于數據交換來進行的,從最簡單的例子開始,不斷深入。 開始是關于一個最簡單的整數數據的交換實例:

void swap(int a, int b){
        int tmp = a;
        a = b;
        b = tmp;
}
 

此例子非常簡單,只需要構造一個簡單的中間臨時變量tmp用來存放a的值,并且交換賦值相關的數據,就可以達到交換的目的。

但是,此實例有一個缺陷,就是值傳遞,而不是引用傳遞,這樣,傳遞的值雖然改變,但是只想原始變量的單元卻沒有改變,具體來說就是:

a = 23;
b = 34
swap(a, b);
 

執行上面一段語句會發現,其實a,b的值并沒有交換,原因和C/C++的參數的值傳遞以及指針傳遞有關系。函數調用的時候,只會拷貝a,b的值,因此調用swap的時候,交換的是形參,實際參數的值并沒有改變。

要實現真正參數傳遞的效果,需要用指針的形式來實現:

void swap(int *vp1, int *vp2) {
    int a = *vp1;
    *vp1 = *vp2;
    *vp2 = *vp1;
}
 

再次調用swap(&a, &b)的時候,就會修改掉原來的值,因為這里傳遞過去的就是指針,所以,對vp1,vp2的操作 就是對指向單元a,b的操作,所以能夠修改對應的值。

泛型交換與拷貝

上面的例子,只是對某種特定的類型進行交換,比如int類型,如果想對double類型等進行交換,只需要修改其類型為double即可,其他類型類似。 但是考慮到需要對多種不同類型進行交換,是否存在一種通用的方法呢? 在C++中,可以用模板template技術,然而這里,回想起上節課中講到的字節操作,能否利用字節的拷貝來實現呢?答案是肯定的。

void swap(void *vp1, void *vp2, int size){
    char buffer[size];
    memcpy(buffer, vp1, size);
    memcpy(vp1, vp2, size);
    memcpy(vp2, buffer, size);
}
 

調用的時候,字號需要給定某個類型,即可實現。比如,通過:

double a = 23.0, b = 34.0;
swap(&a, &b, sizeof(double));
 

當然,對于結構體也可以通過這種形式來進行拷貝。

關于上面例子的幾點說明:

  1. 這里聲明數組的方式,使用的大小size是可變的,這只在某些編譯器中支持,這里只是為了說明字符拷貝的方式,例子的重點在于交換。當然可以使用malloc或者new來動態分配大小可變的空間。
  2. 這里使用memcpy(dest, src, size)這個函數來進行內存單元的拷貝,注意此函數并不關心你的數據類型,單純的進行單元的拷貝而已,所以雖然編譯可能通過,但是還需要自己進行判斷和控制。
  3. 這個例子的亮點就在于void*的使用,通過它能夠實現泛型,即針對于int,short,char,struct等類型都能夠保證能夠拷貝交換成功。
  4. template和這里的區別和優缺點。注意到使用模板的話,編譯后,會為每種類型都生成一種代碼,比如int對應的,float對應的,這樣如果調用次數很多的話,代碼體積會增大,冗余過多。而這里編譯出來就一套代碼,更加簡潔。
  5. 這里傳遞一個參數大小size是因為,由于泛型指針void*的存在,所以編譯器并不知道要拷貝多少個字節,所以,需要你手動控制并指定一個大小。

存在的問題

由于編譯器會很容易的放過void*帶來的錯誤,所以如果兩個類型不同的數據調用此函數,就會出現問題:

    double a = 23.0;
    int b = 345;
    swap(&a, &b, sizeof(double));
 

這里,double和int類型占據的數據空間的大小是不同的,因此,如果單純的直接調用這個函數,就會出錯,簡單的結果就是,截斷拷貝或者多拷貝數據。 比如,int類型拷貝到double數據空間的時候,只有前面2個字節拷貝了,后面的原來double數據的兩個字節仍然保留了;或者說double拷貝到int的時候,可能會多拷貝兩個字節到int后面的數據,造成出錯。具體的方式,與后面一個參數sizeof(double)或者sizeof(int)有關系。

初學者容易犯的錯誤

  1. 使用void * tmp = vp1,而不是前面鎖講到的char buffer[size],這個錯誤的原因是由于不理解void不是一個類型,不像int,double等屬于一個類型,所以錯誤。void 只能用作函數參數,返回值才可行。但是可以使用 void * tmp = (int )&a這類的用法,因為具體的類型即可以賦值給一般的類型,你只有給定了一個具體的類型,才能讓編譯器知道規則,才能編譯通過。
  2. 指針的拷貝,何時使用引用地址的問題。一個簡單的例子出發,

char * husband = strdup("Fred"); char * wife = strdup("Wilma");

如果想交換兩人所指向的空間內容,正確的做法是:

swap(&hustband, &wife, sizeof(char *))
 

也就是說,這里要交換的是指針的地址,交換之后,husband的內容發生了變化,內容變成了原來wife的內容,由于本身是地址,所以內容變了,實際上所只想的地址也變了,現在husband指向原來wife所指向的地址,而wife指向原來husband指向的地址。

一個錯誤的例子就是,swap(husband, wife, &sizeof(char *)),這樣,交換的實際上是他們鎖指向的內容,即存放Fred和Wilama的單元中的內容會交換,而且,由于char *是四個字節,因此交換的就只有四個字節的內容。 為何會如此呢?因為上面的例子,比如要交換a,b單元的內容,傳入的就是a,b的地址&a, &b,同樣,這里我直接傳入指針,當然交換的是他們指向的單元的內容,即兩個字符串。 所以要交換兩個指針的內容,就要交換他們的地址,即指針的地址,指針的指針。

另外一個例子

思考一個下面線性搜索的例子,

int * lsearch(int key ,int* array, int size){
    for (int i = 0; i < size; i++)  
    {
        if(array[i] == key)
            return i;
    }
}
 

上面的這段代碼,直接返回的就是找到索引的那個下標。

利用位比較的方式來實現

同樣,為了應用上面我們學到的知識,這里想要泛型比較,搜索,如何實現? 例如,對于這里的int,能否用一個struct,一個double或者其他類型。 答案仍然是肯定的,只不過,我們需要對其中編譯器的工作,比較的大小進行控制而已。

int *lsearch(void *key, void *base, int size, int elementSize){
    for (int i = 0; i < size; i++) {
      void * elemeAddr = (char *)base + i * elementSize; 
      if (memcmp(key, elemeAddr, elementSize) == 0)
        return elemeAddr;
    }       
}
 

這里的幾個說明點就是,首先,傳入參數的size就是要比較的數組的大小,類型我們不知道,就用void *類型,然后要傳入每一個類型的大小,elementSize,這個標記了每一個數組成員的大小,正因為有這個我們才可以精準的定位到具體的單元,利用for循環來比較每一個單元和key的關系。而這里比較用的memcmp來進行,比較的字節數就是elementSize,傳入兩個指針即可,而比較的指針就是數組的每一個單元的地址,即elemeAddr而已。

                                                                                                   ---Written by markdown and HTML file is generated by markdown.

posted on 2012-06-24 16:57 deercoder 閱讀(3302) 評論(0)  編輯 收藏 引用 所屬分類: 大學公開課
青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品
  • <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>
            久久久久九九九| 亚洲精品综合久久中文字幕| 亚洲视频一区| 国产精品扒开腿做爽爽爽视频| 最新日韩欧美| 亚洲人成网站影音先锋播放| 欧美高清视频一二三区| 亚洲国产福利在线| 亚洲另类视频| 国产精品视频| 老鸭窝毛片一区二区三区| 久久亚洲图片| 亚洲一区二区在| 亚洲欧美日韩成人| 亚洲电影在线播放| 日韩一区二区精品视频| 国产精品日韩精品欧美精品| 久久久久久久久久码影片| 久热综合在线亚洲精品| 亚洲网址在线| 久久成人免费网| 日韩视频免费大全中文字幕| 亚洲性视频h| 亚洲国产精品电影在线观看| 亚洲最新在线视频| 一区久久精品| 在线综合亚洲欧美在线视频| 狠狠色综合网| 一级日韩一区在线观看| 今天的高清视频免费播放成人| 亚洲国产午夜| 国产在线乱码一区二区三区| 亚洲人成啪啪网站| 狠狠综合久久av一区二区老牛| 亚洲精品一区二区三区蜜桃久 | 久久噜噜噜精品国产亚洲综合 | 中日韩男男gay无套| 国内精品嫩模av私拍在线观看| 亚洲国产精品一区二区三区| 国内成+人亚洲+欧美+综合在线| 亚洲精品国产品国语在线app| 宅男噜噜噜66国产日韩在线观看| 在线播放亚洲一区| 先锋影音国产一区| 亚洲视频电影图片偷拍一区| 久久亚洲电影| 久久九九国产精品| 欧美日韩午夜剧场| 亚洲国产精品电影| 在线精品视频一区二区| 欧美亚洲一区在线| 欧美在线91| 国产精品免费一区二区三区观看| 亚洲人成网站精品片在线观看 | 国产亚洲欧美激情| 这里只有精品丝袜| 日韩天堂av| 欧美va亚洲va香蕉在线| 久久在线免费| 精品99一区二区| 久久精品系列| 久久人人爽爽爽人久久久| 国产香蕉97碰碰久久人人| 亚洲一区二区三区在线| 亚洲欧美日本国产专区一区| 欧美日韩中文字幕| 夜夜狂射影院欧美极品| 亚洲免费视频网站| 国产精品欧美一区喷水| 亚洲一区日韩在线| 欧美专区在线播放| 国产一区二区视频在线观看| 亚洲综合精品四区| 久久久免费av| 亚洲高清av| 欧美大片在线观看一区| 亚洲精选久久| 亚洲欧美日韩一区二区| 国产亚洲网站| 久久一区二区三区四区| 亚洲激情欧美| 一区二区久久久久| 国产精品丝袜白浆摸在线| 午夜在线观看免费一区| 六月婷婷久久| 一本一本久久a久久精品综合妖精 一本一本久久a久久精品综合麻豆 | 亚洲午夜激情在线| 欧美视频日韩视频在线观看| 亚洲一区精品在线| 久久精品国产亚洲高清剧情介绍| 黄色小说综合网站| 欧美华人在线视频| 亚洲香蕉视频| 免费亚洲电影在线| 亚洲视频高清| 国内精品视频久久| 欧美日韩大片一区二区三区| 亚洲综合日韩中文字幕v在线| 久久综合中文色婷婷| 亚洲毛片一区| 国产欧美日韩视频一区二区三区| 久久精品国产2020观看福利| 亚洲国产99精品国自产| 亚洲欧美日本在线| 亚洲激情六月丁香| 国产老女人精品毛片久久| 久久五月天婷婷| 一本一本久久a久久精品综合妖精 一本一本久久a久久精品综合麻豆 | 亚洲午夜电影网| 欧美成人伊人久久综合网| 亚洲一区二区黄| 亚洲高清在线精品| 国产精品美腿一区在线看| 麻豆精品视频| 午夜视频在线观看一区二区三区| 亚洲国内高清视频| 久久久久久国产精品mv| 亚洲一区二区成人| 亚洲韩国青草视频| 韩日欧美一区二区| 国产精品日韩专区| 欧美另类久久久品| 久久全球大尺度高清视频| 亚洲免费婷婷| 一卡二卡3卡四卡高清精品视频| 欧美国产高潮xxxx1819| 久久久视频精品| 亚洲欧美视频在线观看| 一本色道久久综合精品竹菊| 亚洲成色www8888| 国产综合欧美在线看| 在线亚洲伦理| 欧美日韩国产成人| 欧美11—12娇小xxxx| 久久阴道视频| 久久国产精品久久w女人spa| 亚洲欧美精品中文字幕在线| 亚洲最黄网站| 日韩一级大片在线| 日韩午夜激情| 日韩一区二区久久| 一本色道久久综合亚洲精品按摩 | 亚洲精品黄色| 亚洲国产精品免费| 好吊视频一区二区三区四区| 国产亚洲一区精品| 国产自产2019最新不卡| 国际精品欧美精品| 影音先锋日韩精品| 亚洲国产精品成人精品| 亚洲第一色在线| 亚洲国产精品一区二区第四页av| 精品成人免费| 亚洲国产日本| 亚洲精品影院| 亚洲一区二区毛片| 亚洲欧美精品在线| 久久国产精品久久久久久电车| 久久精品道一区二区三区| 久久精品一区二区| 蜜桃av一区二区三区| 欧美激情精品久久久久久大尺度| 亚洲国产精品一区二区第四页av | 亚洲女同精品视频| 欧美亚洲综合在线| 久久久久久综合| 欧美成人影音| 99精品欧美一区二区蜜桃免费| 亚洲一二三区在线| 久久久国产精品亚洲一区| 欧美.www| 国产精品自拍网站| 韩曰欧美视频免费观看| 亚洲人妖在线| 欧美影院视频| 亚洲电影自拍| 亚洲在线观看免费视频| 久久亚洲图片| 国产精品毛片在线| 亚洲国产aⅴ天堂久久| 亚洲永久免费观看| 久久亚洲图片| 99成人在线| 蜜臀久久99精品久久久久久9 | 韩国精品久久久999| 亚洲欧洲精品一区二区三区不卡 | 一区二区欧美国产| 久久久精品国产一区二区三区| 欧美福利视频| 亚洲午夜伦理| 欧美高清视频在线| 国产亚洲一区精品| 亚洲素人一区二区| 欧美大片专区| 欧美在线免费观看视频| 欧美性猛交视频| 亚洲日本中文字幕| 麻豆精品一区二区综合av| 中文av字幕一区| 欧美精品在线观看播放|