C++中字符數組和字符串string


字符數組

C++中字符數組用char str[]能夠用來表示一個字符串。

(1)   數組的大小和字符串的長度。

數組的大小一定要大於字符串的長度,由於系統會自己主動補上一個’\0’作為字符串的結束標志。

當然對於未初始化的也補’\0’.

#include <iostream>
#include <string>

using namespace std;

int main()
{
	char str[11] = "I am happy";   //  系統會自己主動補上'\0'空字符作為結束標志,,未有初始化的也補'\0'
	//char str[10] = "I am happy";    // 出錯  系統自己主動補上'\0' 此時字符數組長度不夠
	//char str[13] = "I am happy";    //  后面未有初始化的也補上'\0' 為 I am happy\0\0\0
	if(str[10] == '\0')
	{
		cout << "hello world!!" << endl;
	}

	cin >> str;      //  輸入輸出  
	cout << str << endl;
	return 0;
}

另外注意:

(1)

char *val = "abcdef";   // 在棧上存放了一個指針變量val,使其指向常量區的abcdef。。普通情況下常量區比較大,大多數情況下f后面常量區沒有分配出去,即為NULL,有時會遇到不為NULL。就會出現故障。
cout << val << endl;   //  輸出結果為abcdef  直到空指針為止  

(2)

char b[2]={'b','a'};    
char a[4]={"abc"};     
cout << b <<endl;  // 輸出為ba亂碼   因為沒有\0  不會截止
cout << a << endl; /// 輸出結果為abc 直到\0為止
cout << strlen(a) << endl;    // 結果為3

(3)

char *val = "abcdef";
cout << val << endl;   //  輸出結果為abcdef  直到空指針為止  
cout << strlen(val) << endl;
char *new_val = new char[strlen(val)+1];      //  new_val 為val的值 最后一位以\0填充
strncpy(new_val, val, strlen(val)+1);
cout << new_val<< endl;    // 輸出為abcdef  直到\0截止

函數原型char*strncpy(char*dest,char*src,size_t n);

(c/c++)復制字符串src中的內容(字符。數字、漢字....)到字符串dest中,復制多少由size_tn的值決定。

假設src的前n個字節不含NULL字符。則結果不會以NULL字符結束。

假設src的長度小於n個字節,則以NULL填充dest直到復制完n個字節。src和dest所指內存區域不能夠重疊且dest必須有足夠的空間來容納src的字符長度+'\0'。來自:http://baike.baidu.com/link?

url=lxi_91JHsW-4omg_8DcV_3APvcwUL9oFFtku6V-VR_t9-Pf5DJzVu886fvGCM_YzXhd-hXdwqMyiGcZwWGXR-_

(4)

int *pa = '\0';
int *pb = 0;
int *pc = NULL;  // 三者等效


(5)

int a[5];  sizeof(a) 就等於5*sizeof(int) = 20;

假設 是 int*p = new int[5]; 此時p為一個指針那么sizeof(p) 就等於4 == sizeof(int*)   包含double*,void* 或者類類型指針等的字節數都為4 

 

char *p = "abc"  那么sizeof(p) == 4 由於p是一個指針。

char p[4] = "abc", 那么sizeof(p) == sizeof(char) * 4 = 4;;;此時為數組


char *p[5];   由於[]優先級高於*,所以把它看做類似於int p[5],,那么就是定義了一個長度為5的數組。僅僅只是數組中的元素都是char*指針,即指向char類型的指針。

所以sizeof(p) = sizeof(char*)*5 = 20,。而*p是一個指針,所以sizeof(*p) == 4 == sizeof(指針)————————一個數組  類比於char p[5][]  第二維不確定

char (*p)[5];  類比於 int a[5],此時*p等於a,那么就是說p是一個指針。指向一個指向字符數組的指針。,相當於char p[][5],,

所以sizeof(p) == sizeof(指針) = 4,,而*p是一個數組的首地址,。所以sizeof(*p) == sizeof(char)*5 = 5.————p是一個指針,類比於char p[][5]  第一位不確定

假設p的值為0x00的話 那么p++的值就為0x05, p盡管是一個指針。但所指向的對象為一個數組的首地址,其大小為sizeof(char)*5,,所以p+1,這里加的是一個數組的字節數即為sizeof(char)*5;;;;;;; 而假設 int *px= new int,。, 此時px指向的對象為int,其大小為sizeof(int), 所以p+1加的是sizeof(int)字節。

。。如p(int*類型)所指的內存地址為0x0000,,即p值為0x0000。那么p+1所在的內存地址就為0x0004,通常我們將一個字節作為一個內存單元進行存放。。

一個指針變量加(減)一個整數並非簡單地將原值加(減)一個整數,而是將該指針變量的原值(是一個地址)和它指向的變量所占用的內存單元字節數加(減)。

下面代碼會輸出hello world

#include <stdio.h>
#define TESTSIZE 20
int main(void)
{
    char szTest[][TESTSIZE] = {"hello", "world"};
    char (*p)[TESTSIZE];

    p = szTest;
    for(int i = 0; i < sizeof(szTest)/TESTSIZE; i++)
    {
        printf("%s ", p + i);
    }
}


strlen與sizeof

int main(){
	
	char dog[] = "wang\0miao";
	cout << strlen(dog) << " " << sizeof(dog) << endl;   // 4, 10  strlen遇到\0就結束了且不包含\0
	
	char xx[] = {"hello"};
	cout << strlen(xx) << " " << sizeof(xx) << endl;    // 5, 6  

	char *val = "abcde";
	cout << strlen(val) << " " << sizeof(val) << endl;  // 5, 4  val是一個指針。大小為4個字節

	cout  << sizeof(long) << sizeof(bool) << endl;      // 4, 1
	return 0;
}

strlen遇到\0就結束了,且不包含\0 這個字符。

即使char a[10]={"hello"}; strlen(a)返回的仍然是5。 而sizeof(a)會等於10

char a[]="ABCDEF";char b[]={'A','B','C','D','E','F'};  a的長度比b的長。。多了一個\0,,可是strlen(b)會是一個任意值。由於b沒有以\0結束

(6) char *val; val = "helloworld"; 是正確的;; 而char val[10]; val= "helloworld"; 是錯誤的。

char b[]={'A','B','C'};
	cout << strlen(b) <<" "<< sizeof(b) << endl;    // 15 3
	char d[]="ABC";
	cout << strlen(d) << " " << sizeof(d) << endl;  //3 4





(2)getline()

getline函數能夠讀取文本或者輸入流的一行,此時包含前面輸入的空格,僅僅到回車換行才結束

#include <fstream>
#include <iostream>
#include <string>

using namespace std;
int main()
{
     ifstream in("E:\\algorithmZack\\testString\\input.txt");
     if(!in)
     {
          cerr << "some errors happened";
          return -1;
     }
     string str;
	 while(getline(in, str)) ///  getline 從文件input.txt中按行讀取文件
    // while(getline(cin, str))   //  從輸入流中按行讀取  不包含換行符
     {
            cout << str << endl;
     }
     return 0;
}



(3)比較,連接,賦值。實際長度用函數strcmp, strcat, strcpy,strlen

參見blog:http://see.xidian.edu.cn/cpp/biancheng/view/158.html

字符串string

(1)String能夠看做一個類庫。須要有包括頭文件#include <string>.

操作包含:連接(+=,append) 賦值(=, assign) 比較(>=,compare) 查找(find)

              替換(replace)  刪除(erase) 插入(insert) 字串(substring) 交換(swap)

              特性(length sizec_str)  正反向迭代器(interator reverse_iterator)

當中使用append,assign,compare的優點在於參數能夠為字符數組

具體見blog:http://www.cnblogs.com/xFreedom/archive/2011/05/16/2048037.html

(2)一個簡單的樣例

從txt中讀入以空格為單位的字符串,並對其進行去重排序輸出

#include <iostream>
#include <fstream>
#include <string>
#include <vector>
#include <algorithm>
#include <iterator>
using namespace std;
int main()
{
	ifstream in("E:\\algorithmZack\\testString\\name.txt");   // fstream
	string str;           
	vector<string> vec;     //vector
	while(getline(in, str))       // string
	{
		int pos = 0;
		while((pos = str.find_first_of(' ', pos)) != string::npos)
		{
			vec.push_back(str.substr(0, pos));
			pos ++;
		}
		vec.push_back(str.substr(str.find_last_of(' ')+1));    //  將最后一個字符放入進來
	}
	sort(vec.begin(), vec.end());           // algorithm
	/*注意這里去掉了相鄰的反復元素。因此在調用unique之前須要排序 但vec大小沒變。在其后面加入了兩個空格。

可是對於int,則將反復的元素放在后面 */ vector<string>::iterator it = unique(vec.begin(), vec.end()); // algorithm 返回去重后最后一個元素 copy(vec.begin(), it, ostream_iterator<string>(cout, "\n")); // iterator ostream_iterator<string> iterator cout << endl; copy(vec.begin(), vec.end(), ostream_iterator<string>(cout, "\n")); /*for(vector<string>::iterator iter = vec.begin(); iter != vec.end(); iter++) { cout << *iter << " "; } cout << endl;*/ return 0; }



注意:這里的unique去掉了vector<string>中反復元素,但其大小沒有變。反復的元素用空格取代放在其后面。可是對已vector<int>,則將反復的元素放在后面。

(3)copy函數

Copy函數包括在頭文件#include<iterator>頭文件里。

主要有三個經常使用的使用方法

copy(IteratorInput it1, IteratorInput it2, IteratorOnput it3)  // algorithm

1: 用數組對vector<T>進行賦值

2:用cin對vector<T>進行賦值

3:將vector<T> 進行輸出

copy函數原型解釋見blog:http://blog.csdn.net/jerryjbiao/article/details/7376088

#include <iostream>
#include <vector>
#include <iterator>
#include <algorithm>
#include <string>
using namespace std;


int main()
{
	vector<int> vec;
	cout << "hello world!!" << endl;
	//int a[] = {3,2,1,1,2,3};
	//copy(a, a+6, back_inserter(vec));
	//vec.resize(6);
//	copy(a, a+6, vec.begin());
	copy(istream_iterator<int>(cin), istream_iterator<int>(), back_inserter(vec));
	copy(vec.begin(), vec.end(), ostream_iterator<int>(cout, " "));
	cout << endl;
	sort(vec.begin(), vec.end());
	vector<int>::iterator it = unique(vec.begin(), vec.end());
	copy(vec.begin(), it, ostream_iterator<int>(cout, " "));   // 輸出
	return 0;
}


(4)一個簡單的樣例

過濾一行開頭和結尾的全部的非英文字符。這里僅僅是為了說明find函數find_first_of函數的差別。Find是從pos開始查找字符串s在當前串中的位置;而find_first_of是從pos開始查找當前串中第一個在s的前n個字符組成的數組里的字符的位置。

如: str.find(str1) 是返回字符串str1 第一次出現字符串str中的位置,假設找不到則返回string::npos(結束標志).   str.find_first_of(ch)是返回字符ch第一次出如今字符串str中的位置,假設找不到則返回string::npos.   str.find_first_of(str1)是返回str的第一個能夠在字符串str1中找到的字符在str中的下標

 如str=“-------hello,world------------”;  str1 = "abcdefghidklmnopk";  則str.find_first_of(str1) ,從str第一個字符開始。發現第一個字符h能夠在str1中找到。因此返回字符h在str中的下標7

#include <string>
#include <iostream>
using namespace std;

int main()
{
	string strinfo = "//*----Hello world!.....----";
	string strset = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";

	int first = strinfo.find_first_of(strset);
	if(first == string::npos)
	{
		cout << "not find any characters" << endl;
		return -1;
	}

	int last = strinfo.find_last_of(strset);

	if(last == string::npos)         //string::npos =-1  沒有找到 結束標志
	{
		cout << "not find any characters" << endl;
		return -1;
	}
	cout << strinfo.substr(first, last - first +1) << endl;


	string str = "hello world!!!";
	string str2 = "hlo";
	// 注意 find和find_first_of()差別非常大
	int j = str.find(str2);  // 從pos開始查找字符串str2在當前串str中的位置 
	int i = str.find_first_of(str2);  // 從pos開始查找當前串str中第一個字符在str2的前n個字符組成的數組里的字符的位置。
	cout << i << endl;


	return 0;
}


參見其他blog:1:http://www.cplusplus.com/reference/string/string/:

2:http://blog.csdn.net/yangtrees/article/details/7577263

3:http://www.cnblogs.com/uniqueliu/archive/2011/07/28/2119328.html

4:http://blog.csdn.net/jerryjbiao/article/details/7376088

5:http://www.cnblogs.com/zkliuym/articles/909245.html


32位和64位系統差別及int字節數

一)64位系統和32位有什么差別? 

1、64bit CPU擁有更大的尋址能力,最大支持到16GB內存,而32bit僅僅支持4G內存

2、64位CPU一次可提取64位數據。比32位提高了一倍,理論上性能會提升1倍。

但這是建立在64bit操作系統,64bit軟件的基礎上的。

 

什么是64位處理器?

之所以叫做“64位處理器”,是由於電腦內部都是實行2進制運算,處理器(CPU)一次處理數據的能力也是2的倍數。8位處理器、16位處理器、32位處理器和64位處理器,其計數都是2的倍數。一次處理的數據越大,該電腦處理信息的能力越來越大;因此64位處理在先天就比32位處理器具有高速的能力。

那為什么不用更高級的128位處理器呢?由於位數越高。處理器芯片的設計也就越復雜,眼下的技術水平臨時無法制造這么復雜的芯片。

 

64位處理器之失

※硬件———缺乏驅動程序,非常多現有硬件無法使用

※軟件———操作系統不是問題。可是軟件出現不兼容難題

 

64位處理器之得

※硬件———更快的運行速度,更大的內存管理

※軟件———最新的尖端軟件首先出如今64位平台

 

(二)數據類型相應字節數

程序執行平台
      不同的平台上對不同數據類型分配的字節數是不同的。


      個人對平台的理解是CPU+OS+Compiler。是由於: 
      1、64位機器也能夠裝32位系統(x64裝XP); 
      2、32位機器上能夠有16/32位的編譯器(XP上有tc是16位的。其它常見的是32位的)。 
      3、即使是32位的編譯器也能夠弄出64位的integer來(int64)。

 
      以上這些是基於常見的wintel平台,加上我們可能非常少機會接觸的其他平台(其他的CPU和OS)。所以個人覺得所謂平台的概念是三者的組合。

 
      盡管三者的長度能夠不一樣,但顯然相互配合(即長度相等。32位的CPU+32位的OS+32位的Compiler)發揮的能量最大。

 
      理論上來講 我認為數據類型的字節數應該是由CPU決定的,可是實際上主要由編譯器決定(占多少位由編譯器在編譯期間說了算)。

經常使用數據類型相應字節數
  可用如sizeof(char),sizeof(char*)等得出

 32位編譯器:

      char :1個字節
      char*(即指針變量): 4個字節(32位的尋址空間是2^32, 即32個bit。也就是4個字節。同理64位編譯器)
      short int : 2個字節
      int:  4個字節
      unsigned int : 4個字節
      float:  4個字節
      double:   8個字節
      long:   4個字節
      long long:  8個字節
      unsigned long:  4個字節

  64位編譯器:

      char :1個字節
      char*(即指針變量): 8個字節
      short int : 2個字節
      int:  4個字節
      unsigned int : 4個字節
      float:  4個字節
      double:   8個字節
      long:   8個字節
      long long:  8個字節
      
unsigned long:  8個字節

16位操作系統中,int 占16位;在32位操作系統中,int 占32位。

可是如今人們已經習慣了 int 占32位,因此在64位操作系統中,int 仍為32位。64位整型用 long long 或者 __int64



免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM