我們來談談C 裡面的字串

2021-07-03 03:38:33 字數 2987 閱讀 3542

1、char * 與 char 的區別

對於很多人來說, char * 與 char 好像沒什麼區別,我以前也這麼覺得,不都是char的指標嗎?仔細翻閱資料後,發現區別可大了。現在就來看看吧。

#include 

#include

using

namespace

std;

int main()

/**/;

//這個地方如果不用'h'初始化,c3的輸出會是亂七八糟的資料。

//因為不給初始化,則這片記憶體不會被置為'\0';輸出就是亂的。如果用初始化也會報錯,因為這不是乙個char型。

cout

<< c1 << endl << c2 << endl << c3 << endl;

cout

<< endl;

//*(c1 + 1) = 'e'; //vs2013 編譯時並未報錯,也沒提示錯誤,但是程式執行時崩潰了。

//c1指向的內容其實是被放置在常量區的

//雖然vs不報錯,但是執行時修改常量區內容,程式會崩潰。這裡需要說明的是c1這個指標指向的內容是不能變的,

//但是c1本身可以變,如:

c1 = c2;

cout

<< "把c2賦值給c1"

<< endl;

cout

<< c1 << endl << c2 << endl << c3 << endl;

cout

<< endl;

c2[1] = 'e'; //這個是沒問題的

cout

<< c1 << endl << c2 << endl << c3 << endl;

cout

<< endl;

//c2[8] = '?'; //這個地方有問題,因為陣列只有9個單元,最後乙個需要保留且置為'\0',才能表示結束

//這裡把它用了,那麼在cout裡面會一直往下讀取,直到有個單元是'\0',所以後面出現亂碼。

//c2[9] = '?'; //錯誤,陣列越界!編譯通過,執行出錯。

//*(c2 + 9) = '?';//錯誤,陣列越界!編譯通過,執行出錯。

cout

<< c1 << endl << c2 << endl << c3 << endl;

cout

<< endl;

c3[36] = 'e'; //這個地方就算越界了,編譯和執行都沒有報錯

//因為c3是在堆上分配的記憶體

cout

<< c1 << endl << c2 << endl << c3 << endl; //這裡c3仍然正常輸出,沒有任何問題。

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

cout

<< endl;

memset(c3, 'a', 64 * sizeof(char)); // memset() 把 c3所指向的記憶體給賦值,

//但是64超出陣列太多,會報錯,如果是38,還是正常執行,而且一直輸出到出現'\0'

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

cout

<< endl;

/* 總結一下這裡,c2 和 c3 型別是一樣的,都是指向char型陣列的指標,而且輸出的時候,都是遇到'\0'時才結束,

但是c2一旦越界就會報錯,c3就算越界,還要看情況,如果越界影響了程式,會導致程式崩潰,但是不會報錯。

c1是最特殊的,它指向的內容是常量型,不可更改,但是它本身可以更改, 相當於 const char * c1;

*/const

char *c4 = "hello c4";

cout

<< c4 << endl;

/*c4[1] = 'e'; //error: c4必須是可修改的左值,也就是c4指向的內容在記憶體中的常量區,不可修改,但是 c4 本身是可以更改的。*/

cout

<< c4 << endl;

return

0;}

2、char 與 string之間的轉換

string 型別的定義包含在 < string >標頭檔案中。在現在標準c++裡面, string 已經是stl了,包含了眾多函式可以呼叫。我們可以使用 typeid().name()檢視乙個string 物件,

#include 

#include

using

namespace

std;

int main()

輸出為:class

std::basic_stringstd::char_traits,class

std::allocator<

char> >

string包含的方法非常多,在這裡可以看到全部函式。

我們重點關注string與char的轉換。

首先是string轉換為char,這個相對簡單,直接可以使用.c_str或者.data。

#include 

#include

using

namespace

std;

int main()

這段**可以在g++3.4.5下面正常編譯,但是vs2013就是編譯不通過,說引數不安全,莫名其妙。

除了上面的方法,我們當然可以直接使用for迴圈來乙個乙個的拷貝資料,因為我們知道string的長度,但是顯然這個效率實在太低。下面我們嘗試一下乙個有趣的方法。

#include 

#include

using

namespace

std;

int main()

;

這個地方c3+4指向的位置剛好就是s1所存放的字串的起始位址。使用c3作為乙個中間變數是為了將s1的位址型別更改為char型。

js裡面的字串擷取

substr 方法可在字串中抽取從 start 下標開始的指定數目的字元。使用 substr start num 栗子1 var str sxswnspcx var result str.substr 3 start,num console.log result 得到 wnspcx 栗子2 var ...

Google 迴圈字串裡面的獨立子串

自九章演算法 位址 題目 假設s是乙個無限迴圈的字串 abcdefghijklmnopqrstuvwxyz s就是乙個 zabcdefghijklmnopqrstuvwxyza.這樣的字串,現在給你另外乙個字串p,求p中存在多少個截然不同的子串,使得它們也是s的子串。p只包括英語的小寫字母並且p的長...

python爬蟲字元問題 爬蟲裡面的字串編碼的坑

初學python寫爬蟲程式,上手很快,但字串的編碼問題卻一直困擾著我,我相信每乙個學習爬蟲的人都有過和我一樣的困惑。一旦走上了程式設計之路,如果你不把編碼問題搞清楚,那麼它就像幽靈一般糾纏你整個職業生涯,所以,今天就談談python的字串編碼。0.前言 大家都知道,我們的計算機只能處理數字,而計算機...