|
常用鏈接
留言簿(3)
隨筆分類
隨筆檔案
Friends
My Links
搜索
最新隨筆
最新評論

閱讀排行榜
評論排行榜
Powered by: 博客園
模板提供:滬江博客
|
|
|
|
|
發新文章 |
|
|
#include<iostream> #include<cstring> #include<cassert> #include<iomanip>
using namespace std; class String; istream& operator>>(istream&, String&); ostream& operator<<(ostream&,const String&);
class String { public: ?//構造函數 ?//String s1(); ?//String s1("abc"); ?//String s2(s1); ?String(); ?String(const char*); ?String(const String&); ?//析構函數 ?~String(); ?//賦值操作 ?String& operator=(const char*); ?String& operator=(const String&); ?//等于操作 ?bool operator==(const char*); ?bool operator==(const String&); ?//加操作 ?String operator+(const String&) const; ?//下標操作 ?char& operator[](int); ?//成員操作 ?int size(){return _size;} ?char* c_str(){return _string;} ?//記數操作 ?int count(const char) const; private: ?int? _size; ?char *_string; };
inline String::String()??????????????????????????????????? //構造函數 { ?_size=0; ?_string=0; }
inline String::String(const char* str)???????????????????? //構造函數 { ?if(!str) ?{ ??_size=0; ??_string=0; ?} ?else ?{ ??_size=strlen(str); ??_string=new char[_size+1]; ??strcpy(_string,str); ?} }
inline String::String(const String& str)????????????????? //拷貝構造函數 { ?if(!str._size) ?{ ??_size=0; ??_string=0; ?} ?else ?{ ??_size=strlen(str._string); ??_string=new char[_size+1]; ??strcpy(_string,str._string); ?} }
inline String::~String()????????????????????????????????? //析構函數 { ?delete[] _string; }
inline String& String::operator=(const char* str)???????? //賦值操作 { ?if(!str) ?{ ??_size=0; ??delete[] _string; ??_string=0; ?} ?else ?{ ??_size=strlen(str); ??delete[] _string; ??_string=new char[_size+1]; ??strcpy(_string,str); ?} ?return *this; }
inline String& String::operator=(const String &str)????? //賦值操作 { ?if(this!=&str) ?{ ??_size=str._size; ??delete[] _string; ??_string=new char[_size+1]; ??strcpy(_string,str._string); ?} ?return *this; }
inline bool String::operator==(const String &rhs)????????? //等于操作符重載 { ?if(_size!=rhs._size) ??return false; ?return strcmp(_string,rhs._string)?false:true; }
inline bool String::operator==(const char *str)??????????? //等于操作符重載 { ?return strcmp(_string,str)?false:true; }
inline char& String::operator[](int n)???????????????????? //下標訪問符 { ?assert(n>=0 && n<_size); ?return _string[n]; }
inline int String::count(const char s) const?????????????? //記數操作 { ?int tempCount=0; ?for(int i=0;i<_size;i++) ?{ ??? ?if(_string[i]==s) ???++tempCount; ?} ?return tempCount; }
inline String String::operator+(const String& str) const? //加操作 { ?String tempStr; ?tempStr._size=_size+str._size; ?tempStr._string=new char[tempStr._size+1]; ?strcpy(tempStr._string,_string); ?strcat(tempStr._string,str._string); ?return tempStr; }
inline istream& operator>>(istream &io,String &str)?????? //輸入流 { ?const int limit_string_size =4096; ?char inBuf[limit_string_size]; ?io>>setw(limit_string_size)>>inBuf; ?str=inBuf; ?return io; }
inline ostream& operator<<(ostream &os,String &str)?????? //輸出流 { ?return os<<str.c_str(); }
int main() { ?String str1="abc"; ?String str2="def"; ?str1.size(); ?cout<<"size :"<<str1.size()<<endl; ?cout<<"b count :"<<str1.count('b')<<endl; ?String str3=str1+str2; ?cout<<str3;????? //該處不能為String&,只能為String。見String operator+()和ostream& operator<<(ostream &os,String &str) ?return 0; }
SO GOOD!
對于文字常量,列出如下關鍵信息,都是以前自己不太清楚的部分 文字常量類型: 1、整型 2、浮點型 3、bool型 4、字符型 5、字符串型 6、轉移序列 =========================================== 1、整型:有short,int,long int。默認情況下都是有符號型的:1024。最左邊為符號位,1表示負數,0表示正數。如果要表示無符號型,則為:1024U。如果要表示長整型,則為:1024L。 2、浮點型:默認情況下都是double型的:3.141592。如果要表示為float型,則為3.141592F。如果要表示長雙精度(即擴展精度),則為3.141592L。 4、字符型:'A' ,數據類型為char。L'A' 為寬字符型,數據類型wchar_t。 5、字符串型:"hello,world",數據類型為const常量數組。特別需要注意的是:編譯后的字符串長度=編譯前的字符串長度+編譯器為表示字串結束而自動為其在最后位加入的NULL(即'\0'),這在字符型里是不會出現的。 L"hello,world":寬字符串型。 6、轉移序列: 常見的有\"(雙引號)? \'(單引號) \\(反斜杠)等 (自己太懶了,都不想寫了)
對于1、2有特別需要注意的地方,有符號型的只能是整型數據,不能用在浮點型上。 如果要讓一行未結束的字串換行繼續寫,則可以用如下表示: "hello?,my \ ?girlfirend" 也就是說,要在最后一個字符后面加"\"反斜杠。
? 鍵盤、顯示器、打印機、磁盤驅動器等邏輯設備, 其輸入輸出都可以通過文 件管理的方法來完成。而在編程時使用最多的要算是磁盤文件, 因此本節主要以 磁盤文件為主, 詳細介紹Turbo C2.0提供的文件操作函數, 當然這┒暈募牟? 作函數也適合于非磁盤文件的情況。 ??? 另外, Turbo C2.0提供了兩類關于文件的函數。一類稱做標準文件函數也稱 緩沖型文件函數, 這是ANSI標準定義的函數; 另一類叫非標準文件函數, 也稱非 緩沖型文件函數。這類函數最早公用于UNIX操作系統, 但現在MS-DOS3.0 以上版 本的操作系統也可以使用。下面分別進行介紹。 ? ??? 1.2.1? 標準文件函數 ??? 標準文件函數主要包括文件的打開、關閉、讀和寫等函數。不象BASIC 、 FORTRAN語方有順序文件和隨機文件之分,?? 在打開時就應按不同的方式確定。 Turbo C2.0并不區分這兩種文件, 但提供了兩組函數, 即順序讀寫函數和隨機讀 寫函數。 ??? 一、文件的打開和關閉 ??? 任何一個文件在使用之前和使用之后, 必須要進行打開和關閉, 這是因為操 作系統對于同時打開的文件數目是有限制的, DOS操作系統中,??? 可以在DEVICE .SYS中定義允許同時打開的文件數n(用files=n定義)。其中n 為可同時打開的文 件數, 一般n<=20。因此在使用文件前應打開文件, 才可對其中的信息進行存取。 用完之后需要關閉, 否則將會出現一些意想不到的錯誤。Turbo C2.0提供了打開 和關閉文件的函數。
??? 1. fopen()函數 ??? fopen函數用于打開文件, 其調用格式為: ???? FILE *fopen(char *filename, *type); ??? 在介紹這個函數之;前, 先了解一下下面的知識。 ??? (1) 流(stream)和文件(file) ??? 流和文件 在Turbo C2.0中是有區別的, Turbo C2.0 為編程者和被訪問的設 備之間提供了一層抽象的東西, 稱之為"流", 而將具體的實際設備叫做文件。 流是一個邏輯設備, 具有相同的行為。因此, 用來進行磁盤文件寫的函數也同樣 可以用來進行打印機的寫入。在Turbo C2.0中有兩種性質的流:?? 文字流( text stream)和二進制(binary stream)。對磁盤來說就是文本文件和二進制文件。本 軟件為了便于讓讀者易理解Turbo C2.0語言而沒有對流和文件作特別區分。 ??? (2) 文件指針FILE ??? 實際上FILE是一個新的數據類型。它是Turbo C2.0的基本數據類型的集合, 稱之為結構指針。有關結構的概念將在第四節中詳細介紹, 這里只要將FILE理解 為一個包括了文件管理有關信息的數據結構, 即在打開文件時必須先定義一個文 件指針。 ??? (3) 以后介紹的函數調用格式將直接寫出形式參數的數據類型和函數返回值 的數據類型。例如: 上面打開文件的函數, 返回一個文件指針, 其中形式參數有 兩個, 均為字符型變量(字符串數組或字符串指針)。本軟件不再對函數的調用格 式作詳細說明。 ??? 現在再來看打開文件函數的用法。 ??? fopen()函數中第一個形式參數表示文件名, 可以包含路徑和文件名兩部分。 如: ???? "B:TEST.DAT" ???? "C:\\TC\\TEST.DAT" ??? 如果將路徑寫成"C:\TC\TEST.DAT"是不正確的, 這一點要特別注意。 ??? 第二個形式參數表示打開文件的類型。關于文件類型的規定參見下表。 ?????????????????????? 表? 文件操作類型 ??? ━━━━━━━━━━━━━━━━━━━━━━━━━━━━ ????????? 字符??????????????? 含義 ??? ──────────────────────────── ?????????? "r"?????????? 打開文字文件只讀 ?????????? "w"?????????? 創建文字文件只寫 ?????????? "a"?????????? 增補, 如果文件不存在則創建一個 ?????????? "r+"????????? 打開一個文字文件讀/寫 ?????????? "w+"????????? 創建一個文字文件讀/寫 ?????????? "a+"????????? 打開或創建一個文件增補 ?????????? "b"?????????? 二進制文件(可以和上面每一項合用) ?????????? "t"?????????? 文這文件(默認項) ??? ━━━━━━━━━━━━━━━━━━━━━━━━━━━━ ??? 如果要打開一個CCDOS子目錄中, 文件名為CLIB的二進制文件, 可寫成: ???? fopen("c:\\ccdos\\clib", "rb"); ??? 如果成功的打開一個文件, fopen()函數返回文件指針,?? 否則返回空指針 (NULL)。由此可判斷文件打開是否成功。 ??? 2. fclose()函數 ??? fclose()函數用來關閉一個由fopen()函數打開的文件 , 其調用格式為: ????? int fclose(FILE *stream); ??? 該函數返回一個整型數。當文件關閉成功時, 返回0, 否則返回一個非零值。 可以根據函數的返回值判斷文件是否關閉成功。 ??? 例10: ???? #iclude<stdio.h> ???? main() ???? { ????????? FILE *fp;??????????????? /*定義一個文件指針*/ ????????? int i; ????????? fp=fopen("CLIB", "rb");? /*打開當前目錄名為CLIB的文件只讀*/ ????????? if(fp==NULL)???????????? /*判斷文件是否打開成功*/ ???????????? puts("File open error");/*提示打開不成功*/ ????????? i=fclose(fp);??????????? /*關閉打開的文件*/ ????????? if(i==0)???????????????? /*判斷文件是否關閉成功*/ ??????????? printf("O,K");???????? /*提示關閉成功*/ ????????? else ??????????? puts("File close error");/*提示關閉不成功*/ ???? }
??? 二、有關文件操作的函數 ??? 本節所講的文件讀寫函數均是指順序讀寫, 即讀寫了一條信息后, 指針自動 加1。下面分別介紹寫操作函數和讀操作函數。
??? 1. 文件的順序寫函數 ??? fprintf()、fputs()和fputc()函數 ??? 函數fprintf()、fputs()和fputc()均為文件的順序寫操作函數,? 其調用格 式如下: ??? int fprintf(FILE *stream, char *format, <variable-list>); ??? int fputs(char *string, FILE *steam); ??? int fputc(int ch, FILE *steam); ??? 上述三個函數的返回值均為整型量。fprintf() 函數的返回值為實際寫入文 件中的字罕個數(字節數)。如果寫錯誤, 則返回一個負數, fputs()函數返回0時 表明將string指針所指的字符串寫入文件中的操作成功, 返回非0時,? 表明寫操 作失敗。fputc()函數返回一個向文件所寫字符的值, 此時寫操作成功,? 否則返 回EOF(文件結束結束其值為-1, 在stdio.h中定義)表示寫操作錯誤。 ???? fprintf( ) 函數中格式化的規定與printf( ) 函數相同,?? 所不同的只是 fprintf()函數是向文件中寫入。而printf()是向屏幕輸出。 ??? 下面介紹一個例子, 運行后產后一個test.dat的文件。 ??? 例11: ???? #include<stdio.h> ???? main() ???? { ????????? char *s="That's good news");? /*定義字符串指針并初始化*/ ????????? int i=617;??????????????????? /*定義整型變量并初始化*/ ????????? FILE *fp;???????????????????? /*定義文件指針*/ ????????? fp=fopne("test.dat", "w");??? /*建立一個文字文件只寫*/ ????????? fputs("Your score of TOEFLis", fp);/*向所建文件寫入一串字符*/ ????????? fputc(':', fp);?????????????? /*向所建文件寫冒號:*/ ????????? fprintf(fp, "%d\n", i);?????? /*向所建文件寫一整型數*/ ????????? fprintf(fp, "%s", s);???????? /*向所建文件寫一字符串*/ ????????? fclose(fp);?????????????????? /*關閉文件*/ ???? } ??? 用DOS的TYPE命令顯示TEST.DAT的內容如下所示: ??? 屏幕顯示 ????? Your score of TOEFL is: 617 ????? That's good news
??? 2. 文件的順序讀操作函數 ??? fscanf()、fgets()和fgetc()函數 ??? 函數fscanf()、fgets()和fgetc()均為文件的順序讀操作函數, 其調用格式 如下: ???? int fscanf(FILE *stream, char *format, <address-list>); ???? char fgets(char *string, int n, FILE *steam); ???? int fgetc(FILE *steam); ??? fscanf()函數的用法與scanf()函數相似,?? 只是它是從文件中讀到信息。 fscanf()函數的返回值為EOF(即-1), 表明讀錯誤, 否則讀數據成功。fgets()函 數從文件中讀取至多n-1個字符(n用來指定字符數), 并把它們放入string指向的 字符串中, 在讀入之后自動向字符串未尾加一個空字符, 讀成功返回string指針, 失敗返回一個空指針。fgetc()函數返回文件當前位置的一個字符,? 讀錯誤時返 回EOF。 ??? 下面程序讀取例11產生的test.dat文件, 并將讀出的結果顯示在屏幕上。 ??? 例12 ???? #include<stdio.h> ???? main() ???? { ????????? char *s, m[20]; ????????? int i; ????????? FILE? *fp; ????????? fp=fopen("test.dat", "r");??? /*打開文字文件只讀*/ ????????? fgets(s, 24, fp);???????????? /*從文件中讀取23個字符*/ ????????? printf("%s", s);????????????? /*輸出所讀的字符串*/ ????????? fscanf(fp, "%d", &i);???????? /*讀取整型數*/ ????????? printf("%d", i);????????????? /*輸出所讀整型數*/ ????????? putchar(fgetc(fp));?????????? /*讀取一個字符同時輸出*/ ????????? fgets(m, 17, fp);???????????? /*讀取16個字符*/ ????????? puts(m);????????????????????? /*輸出所讀字符串*/ ????????? fclose(fp);?????????????????? /*關閉文件*/ ????????? getch();????????????????????? /*等待任一鍵*/ ???? } ??? 運行后屏幕顯示: ??? Your score of TOEFL is: 617 ??? That's good news ??? 如果將上例中fscanf(fp, "%d", &i)改為fscanf(fp, "%s", m),? 再將其后 的輸出語句改為printf("%s", m), 則可得出同樣的結果。由此可見Turbo C2. 0 中只要是讀文字文件, 則不論是字符還是數字都將按其ASCII值處理。 另外還要 說明的一點就是fscanf()函數讀到空白符時, 便自動結束, 在使用時要特別注意。
??? 3. 文件的隨機讀寫 ??? 有時用戶想直接讀取文件中間某處的信息, 若用文件的順序讀寫必須從文件 頭開始直到要求的文件位置再讀, 這顯然不方便。Turbo C2.0提供了一組文件的 隨機讀寫函數, 即可以將文件位置指針定位在所要求讀寫的地方直接讀寫。 ??? 文件的隨機讀寫函數如下: ??? int fseek (FILE *stream, long offset, int fromwhere); ??? int fread(void *buf, int size, int count, FILE *stream); ??? int fwrite(void *buf, int size, int count, FILE *stream); ??? long ftell(FILE *stream); ??? fseek()函數的作用是將文件的位置指針設置到從fromwhere開始的第offset 字節的位置上, 其中fromwhere是下列幾個宏定義之一: ??? 文件位置指針起始計算位置fromwhere ━━━━━━━━━━━━━━━━━━━━━━━━━━━ ??? 符號常數??????? 數值?????????? 含義 ─────────────────────────── ??? SEEK_SET????????? 0??????? 從文件開頭 ??? SEEK_CUR????????? 1??????? 從文件指針的現行位置 ??? SEEK_END????????? 2??????? 從文件末尾 ━━━━━━━━━━━━━━━━━━━━━━━━━━━ ??? offset是指文件位置指針從指定開始位置(fromwhere指出的位置)跳過的字 節數。它是一個長整型量, 以支持大于64K字節的文件。fseek()函數一般用于對 二進制文件進行操作。 ??? 當fseek()函數返回0時表明操作成功, 返回非0表示失敗。 ??? 下面程序從二進制文件test_b.dat中讀取第8個字節。 ??? 例13: ???? #include<stdio.h> ???? main() ???? { ????????? FILE *fp; ????????? if((fp=fopen("test_b.dat", "rb"))==NULL) ??????????? { ????????????? printf("Can't open file"); ????????????? exit(1); ??????????? } ????????? fseek(fp, 8. 1, SEEK_SET); ????????? fgetc(fp); ????????? fclose(fp); ???? } ??? fread()函數是從文件中讀count個字段, 每個字段長度為size個字節, 并把 它們存放到buf指針所指的緩沖器中。 ??? fwrite()函數是把buf指針所指的緩沖器中, 長度為size個字節的count個字 段寫到stream指向的文件中去。 ??? 隨著讀和寫字節數的增大, 文件位置指示器也增大, 讀多少個字節, 文件位 置指示器相應也跳過多少個字節。讀寫完畢函數返回所讀和所寫的字段個數。 ??? ftell()函數返回文件位置指示器的當前值,? 這個值是指示器從文件頭開始 算起的字節數, 返回的數為長整型數, 當返回-1時, 表明出現錯誤。 ??? 下面程序把一個浮點數組以二進制方式寫入文件test_b.dat中。 ??? 例14: ???? #include <stdio.h> ???? main() ???? { ????????? float f[6]={3.2, -4.34, 25.04, 0.1, 50.56, 80.5}; ???????????????????????? /*定義浮點數組并初始化*/ ????????? int i; ????????? FILE *fp; ????????? fp=fopen("test_b.dat", "wb"); /*創建一個二進制文件只寫*/ ????????? fwrite(f, sizeof(float), 6, fp);/*將6個浮點數寫入文件中*/ ????????? fclose(fp);?????????????????? /*關閉文件*/ ???? } ??? 下面例子從test_b.dat文件中讀100個整型數, 并把它們放到dat數組中。 ??? 例15: ???? #include <stdio.h> ???? main() ???? { ????????? FILE *fp; ????????? int dat[100]; ????????? fp=fopen("test_b.dat", "rb");/*打開一個二進制文件只讀*/ ????????? if(fread(dat, sizeof(int), 100, fp)!=100) ??????????????????????????????????????? /*判斷是否讀了100個數*/ ??????????? { ?????????????? if(feof(fp)) ???????????????? printf("End of file"); /*不到100個數文件結束*/ ?????????????? else ???????????????? printf("Read error");? /*讀數錯誤*/ ????????? fclose(fp);?????????????????? /*關閉文件*/ ???? } ??? 注意: ??? 當用標準文件函數對文件進行讀寫操作時, 首先將所讀寫的內容放進緩沖區, 即寫函數只對輸出緩沖區進行操作, 讀函數只對輸入緩沖區進行操作。例如向一 個文件寫入內容, 所寫的內容將首先放在輸出緩沖區中, 直到輸出緩沖區存滿或 使用fclose()函數關閉文件時, 緩沖區的內容才會寫入文件中。若無fclose() 函數, 則不會向文件中存入所寫的內容或寫入的文件內容不全。有一個對緩沖區 進行刷新的函數, 即fflush(), 其調用格式為: ??? int fflush(FILE *stream); ??? 該函數將輸出緩沖區的內容實際寫入文件中, 而將輸入緩沖區的內容清除掉。
??? 4. feof()和rewind()函數 ??? 這兩個函數的調用格式為: ???? int feof(FILE *stream); ???? int rewind(FILE *stream); ??? feof()函數檢測文件位置指示器是否到達了文件結尾,? 若是則返回一個非0 值, 否則返回0。這個函數對二進制文件操作特別有用, 因為二進制文件中,? 文 件結尾標志EOF也是一個合法的二進制數,? 只簡單的檢查讀入字符的值來判斷文 件是否結束是不行的。如果那樣的話, 可能會造成文件未結尾而被認為結尾, 所 以就必須有feof()函數。 ??? 下面的這條語句是常用的判斷文件是否結束的方法。 ???? while(!feof(fp)) ??????? fgetc(fp); ??? while為循環語句, 將在下面介紹。 ??? rewind()函數用于把文件位置指示器移到文件的起點處, 成功時返回0,? 否 則, 返回非0值。 ?
??? 1.2.2? 非標準文件函數 ??? 這類函數最早用于UNIX操作系統, ANSI標準未定義,?? 但有時也經常用到, DOS 3.0以上版本支持這些函數。它們的頭文件為io.h。 ??? 一、文件的打開和關閉 ??? 1. open()函數 ??? open()函數的作用是打開文件, 其調用格式為: ???? int open(char *filename, int access); ??? 該函數表示按access的要求打開名為filename的文件, 返回值為文件描述字, 其中access有兩部分內容: 基本模式和修飾符, 兩者用" "("或")方式連接。修 飾符可以有多個, 但基本模式只能有一個。access的規定如表3-2。 ?????????????? 表 access的規定 ━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 基本模式??? 含義??? 修飾符???????? 含? 義 ──────────────────────────── O_RDONLY??? 只讀?? O_APPEND?? 文件指針指向末尾 O_WRONLY??? 只寫?? O_CREAT??? 文件不存在時創建文件, ????????????????????????????? 屬性按基本模式屬性 O_RDWR????? 讀寫?? O_TRUNC??? 若文件存在, 將其長度 ????????????????????????????? 縮為0, 屬性不變 ?????????????????? O_BINARY?? 打開一個二進制文件 ?????????????????? O_TEXT???? 打開一個文字文件 ━━━━━━━━━━━━━━━━━━━━━━━━━━━━ ??? open()函數打開成功, 返回值就是文件描述字的值(非負值), 否則返回-1。
??? 2. close()函數 ??? close()函數的作用是關閉由open()函數打開的文件, 其調用格式為: ???? int close(int handle); ??? 該函數關閉文件描述字handle相連的文件。
??? 二、讀寫函數 ??? 1. read()函數 ??? read()函數的調用格式為: ???? int read(int handle, void *buf, int count); ??? read()函數從handle(文件描述字)相連的文件中, 讀取count個字節放到buf 所指的緩沖區中, 返回值為實際所讀字節數, 返回-1表示出錯。返回0 表示文件 結束。
??? 2. write()函數 ??? write()函數的調用格式為: ???? int write(int handle, void *buf, int count); ??? write()函數把count個字節從buf指向的緩沖區寫入與handle相連的文件中, 返回值為實際寫入的字節數。 ? ??? 三、隨機定位函數 ??? 1. lseek()函數 ??? lseek()函數的調用格式為: ???? int lseek(int handle, long offset, int fromwhere); ??? 該函數對與handle相連的文件位置指針進行定位, 功能和用法與fseek() 函 數相同。
??? 2. tell()函數 ??? tell()函數的調用格式為: ???? long tell(int handle); ??? 該函數返回與handle相連的文件現生位置指針, 功能和用法與ftell()相同。
完美世界游戲可以說代表這目前國內完全自主研發的游行引擎的最高水品!先感嘆下,等會兒去玩下
這次在工作上分別遇到過strcpy、memset、memcpy,也在網絡上看到過一些關于三者區別的文章,羅列大概內容如下: strcpy()來自C語言,在C++里得以保留。首先,要指明的是,C++里strcpy()里接受的參數是C-串,并非string,更不可能是其他類型的數據。它表示一個字串的內容拷貝到另一個字串。拷貝會在源字串里第一個'\0'時停止拷貝.
strcpy(目標字串,源字串);
ex: char *temp1,*temp2="test"; strcpy(temp1,temp2);
memset()主要用于對一個內存區域初始化。一般用在字符數組上,至少我現在工作上遇到的多為這樣的情況。
memset(目標內存空間,拷貝內容,限制);
ex: char temp[30]; memset(temp,'\0',sizeof(temp)); 正如上面所見,char temp[30]只是分配了一定的內存空間給該字符數組,但并未初始化該內存空間,即數組。所以,需要使用memset()來進行初始化。
memcpy() 除了和strcpy()一樣能拷貝字串外,還可以拷貝其他任何類型的數據.
ex: int a[3],b[4]; b[4]={0,1,2,3}; memcpy(a,b,sizeof(a)); //若為sizeof(b),則會造成數組a[]內存外溢
================================ 如下內容為網絡“原版”內容 Memset? 用來對一段內存空間全部設置為某個字符,一般用在對定義的字符串進行初始化為‘ ’或‘\0’;
例
:char a[100];memset(a, '\0', sizeof(a));
?
??? memset
可以方便的清空一個結構類型的變量或數組。
如:
struct sample_struct { ?char ? csName[16]; ?int ? ?iSeq; ?int ? ?iType; };
對于變量
struct sample_strcut ?stTest;
一般情況下,清空
stTest
的方法:
stTest.csName[0]='\0'; stTest.iSeq=0; stTest.iType=0;
用
memset
就非常方便:
memset(&stTest,0,sizeof(struct sample_struct));
如果是數組:
?struct sample_struct ? TEST[10];
則
memset(TEST,0,sizeof(struct sample_struct)*10);
memcpy?
用來做內存拷貝,你可以拿它拷貝任何數據類型的對象,可以指定拷貝的數據長度。
例:
char a[100],b[50]; memcpy(b, a, sizeof(b));
注意如用
sizeof(a)
,會造成
b
的內存地址溢出。
Strcpy??
就只能拷貝字符串了,它遇到
'\0'
就結束拷貝。
例:
char a[100],b[50];strcpy(a,b);
如用
strcpy(b,a)
,要注意
a
中的字符串長度(第一個
‘\0’
之前)是否超過
50
位,如超過,則會造成
b
的內存地址溢出。
str
也可以用用個參數的
strncpy(a,b,n)
========================================================
memset
主要應用是初始化某個內存空間。
memcpy
是用于
copy
源空間的數據到目的空間中。
strcpy
用于字符串
copy,
遇到
‘\0’
,將結束。
如果你理解了這些,你應該知道他們的區別:例如你初始化某塊空間的時候,用到
memcpy
,那么應該怎么寫,是不是顯得很笨。
? int ?m[100] ->memset((void*)m,0x00,sizeof(int)*100);//Ok
!
…memcpy((void*)m,"\0\0\0\0....",sizeof(int)*100);//it’s wrong.
來自CSDN的問題
舉個例子 ======================= Name *name1=new Name[4]; Name *name2=new Name(); 假設Name類有一方法void show(); ====================== 我一直以為由于都是由new 構成的,所以,第一個name 和第二個name都是指針。今天剛好用第一個類對象的方法:name1[0]->show(); 編譯器就報錯,當我換成name1[0].show();時候,就能正確運行了 想請問下大家,既然動態內存是由new分配的,那name1應該也是指針啊,因為name1前有個*(即*name1),并且又是又new分配空間的。但是它調用方法時候卻又只是表現出只是個Name[]的數組元素。 有朋友能告訴下我到底什么樣的new 才算真正的動態內存分配,才算指針嗎??? 謝謝!!!
以下為解答內容,各段為一個解答。
name1是數組指針,name1[0]就是數組中的值了.
你可以直接用name1->來調用. name1就是指針,它和name2并沒有什么不同,同樣你也可以用name2[0].來調用函數.
Name[0]指的是數組中的第一個元素,不是個指針~~~~~~~ 在定義Name *name1=new Name[4]時name1確實是個指針,他指向了數組Name[] 而用name1->show()應該是正確的,這樣的話就相當于將函數show的首地址給了name1, Name *name2=new Name();表示開辟了一個函數Name的內存地址,name2表示了這個函數的首地址
我一直以為由于都是由new 構成的,所以,第一個name 和第二個name都是指針。 -------------------- 正是如此! 都是指針,但是,name1[0]就是值了 ... 同樣,name2[0]也是一個值,樓主自己試試就知道了 ..
Name *name2=new Name(); //首先構造Name()默認構造函數對象然后new出對象拷貝構造出來 Name *name2=new Name[3]; //是先分配空間然后構造對象
Name1[0]是個對象(如果你拷貝了其他對象給他,當然你是要拷給他才能用) Name1,Name2都是指針
和 int* p1 = new int[4]; int* p2 = new int; 一樣
指針是這樣用滴~~~ for(int i = 0;i < 4; i++) { (name1+i)->show(); }
name2 是構造單個對象指針 name1是構造四個對象的指針。具體到每一個對象就不是指針,而是數組
//#include class A { public: int a; int& get(){return a;}; void set(int i){ a=i;}; A() { a=1; }; }; int main() { // A* a1=new A(); A* a2=new A(); A* pA[2]={a1,a2}; int b=pA[0]->get(); // int pI[2]={1,2}; int sum=pI[1]+pI[2]; // A* pB=new A[2]; pB[1].set(1); int x=pB[1].a; return 0;
}
是指針,但是是數組的指針 比如這樣 name *p = new name[4]; p->show()相當于p[0].show(); 通俗的說,你在定義的時候的那個name*中的*號指的是對象數組,并不是對象指針
name1[0]->show();里的name1[0]改成name1就OK了。樓主可以補一補數組的有關知識。
======================================================== copy了這篇文章,其實我只想說下我的看法。 Name *p=new Name[4]; p->show();????? //正確 p[0].show();??? //正確 第一個可以這樣理解:指針P指向數組首地址,其實就是P指向Name[4]數組中第一個元素的地址,所以,如果使用p->show(),則意思其實就是讓數組中第一個元素,即第一個對象name調用自身show(),再說白點,就是name.show(); 第2個可以這樣理解:p[0]可以理解成P指向數組中第[0]個元素,所以就有了p[0],所以更會有了p[0].show();
C++內存分配有兩種:靜態分配和動態分配。 舉個簡單的例子如下 int a=1024; 對象a的內存空間就是靜態分配的,是在編譯器對程序進行編譯時分配的,當然對它空間的回收也是編譯器自動完成的,開發者只需要知道這個事實就好,不需要我們顯示的回收。
int *p=new int(1024); 先來說下這句程序的意思:現在分配一個新的空間給一個沒有名字的Int型對象,并且為這個空間賦予初始化數值為1024。由于該Int型對象沒有名字,所以如果需要訪問它的話,就需要使用指針來指向該對象所在的內存地址。注意,new int(1024)這個表達式返回的是該沒有名字的對象的內存地址。
int *p=new int[1024]; 這個和上面的就有點不一樣了。可以看的出,這個是動態分配數組,這個P叫數組指針。意思是什么呢:現在分配新的空間給數組里面的1024個元素,但是這1024個元素我們沒有辦法顯式的為它們分配初始化數值。并且這個指針只指向這個數組第一個元素的地址。如果想要訪問其他數組元素,可以用*p++來實現。
既然上面兩個new 都是動態分配的,那么自然需要手動刪除所分配的空間了。 第一個是 delete p; 第二個是 delete[] p;
其實這個問題我已經想過很多時候了,但是,目前的結果仍然是:寫程序容易,做人太累,且太難。所以,我更愿意我成為一個象傳說中的那種頭發蓬松到另人發指仍然去參加全球C++研討會的程序員。
可能是我眼拙,普遍受歡迎的C++ 編程思想(II)我居然看著覺得很普通,寫的思路是有點新鮮,但是所敘述的內容卻有點泛泛而談,讓人不能完全過癮的感覺。有的文字居然還不通,讓人看了覺得有點莫名其妙。這可能就是大家普遍認為的中文版不好的地方吧。 于是轉向去看C++ Primer(III)這本大部頭,感覺寫的很不錯,雖然提前講解了OOP方面的內容,或許會讓很多新手覺得一頭霧水,但是確實是講的都是精華的東西(聽說有些人因為看了C++ Primer后居然投奔JAVA去了,因為大多覺得自己連Primer這樣的書都看的不懂 )。個人感覺錢能老師的C++程序設計(II)寫的so good,雖然有些方面沒有編程思想和Primer寫的詳細,甚至沒有涉及,但是確實為一本入門級好書。還有一本就是SAMS的21天學通C++(V),可以說是對錢能老師書內容的相對部分的補充,大家可以去看下 ?:P?? 希望自己能努力看完網絡上提到的很多經典書籍,提高自己在C++思想方面的認識,早日進入C++中級者行列(雖然本人現在還是新手 )。 +U!
|
|