字符串 - C++中字符常量有什么用?
伊谢尔伦
伊谢尔伦 2017-04-17 11:02:23
0
3
738

刚学C++,看书上说几种常量,数值常量我能理解,PI是个好例子。但是字符常量又要作何解?转义字符这个倒还好理解,有个实际用处单独定义出来。但是还有普通的字符常量,这个我就非常理解不能了,请问大家能不能给个例子证明这个有什么用?而且只能单引号什么的其实也挺纠结的。
另外,C++是不是强语言,每个变量都必须定义类型什么的?没办法,从PHP转过去的,挺纠结这些基本问题的╮(╯▽╰)╭...
再来就是定义字符串常量查到好几种方法:

#include<string>
string url = "segmentfault.com";
const char url[] = "segmentfault.com";
const char *url = "segmentfault.com";
const char* url = "segmentfault.com";

请问哪个好点?另外最后两个的*号做何解...新手问题还望大家要淡定,别凌乱就好。。。。

伊谢尔伦
伊谢尔伦

小伙看你根骨奇佳,潜力无限,来学PHP伐。

全部回覆(3)
大家讲道理

先說說這幾個例子的區別吧:
1、

#include<string>
string url = “segmentfault.com”;

url是一個string對象。為了更加容易地操縱字符串,cpp為我們定義了一個string類(string並不是cpp的關鍵字),你可以通過它來定義字符串對象,然後通過調用它的方法來獲取該字符串的信息,例如獲取它的長度:
url.length()
又或者對它進行操縱,例如拚接:

string scheme = “http://”
cout << scheme+url << endl; //输出http://segmentfault

2、
下麵的三種寫法都可以看作是一種:

const char* url = “segmentfault”;

因為 const char url[](字符數組),數組名url在編譯時會被隱式轉為為指針char*,指向字符串的首個字符's'。至於*號的位置,有人喜歡把它放到靠近類型,有人喜歡把它放到靠近變量名,這裏有一個關於這個問題討論的topic

http://topic.csdn.net/u/20101117/10/f...

又因為是常量字符串,所以你不能對它進行修改

url[0]='x';//错误,不可以进行修改,就算没有用const来修饰,也不可以

但是在string中卻可以

string url = “segmentfault.com”;
url[0] = 'x';//OK

這是因為string為我們承擔了管理內存的任務。如果你想要對它進行拚接,你需要自己寫一個函數,又或者調用cstring庫中的strcat或strncat函數。

在c/cpp中,*有兩種作用,一種是用來定義指針類型,char* 就是字符指針。另外一種就是取值,取指針指向的值,想上麵所說的

const char *url = “segmentfault”;

url是指向字符串的首個字符,所以你對指針url取值,得到的就是字符's'

cout << *url << endl;//输出's'

所以,總的來說,string用起來會比較方便,常量字符串在操縱起來就有點麻煩,也可以說是靈活吧,什麼時候用哪個,就需要你自己衡量了。至於性能上,我想我還沒有能力來分析!

伊谢尔伦

補充一下 @Henry 的答案
字符串數組和指針,雖然兩個很相似,數組可以在使用時退化成指針使用,但是兩個概念上就不一樣。
關鍵的一點在於,指針存放的是一個地址
舉個例子:

const char str[] = "segmentfault.com";
const char *str_ptr = "segmentfault.com";

// sizeof(str) == 17
// sizeof(str_ptr), 平台相关, x86的目标文件一般为4(32位), x86_64的目标文件一般为
//   8(4位)

EDIT:

利用這點可以在編譯時就確定出字符串的長度。

理解了指針是地址之後,下麵的錯誤就不會犯了:

define.c

// 定义该字符串常量
const char str[] = "segmentfault.com";

main.c:

// 错误的声明
extern const char *str;
// 正确的声明
//extern const char str[];

int main()
{
    // 产生段错误
    // 原因: str本来是数组,但是声明为了指针
    //   假设目标文件是32位 x86 小端格式
    //   则实际访问的错误地址是 0x6d676573 (刚好就是segm这4个字符的ASCII码)
    printf("%s\n", str);
    return 0;
}
小葫芦

由於曆史原因,c 兼容c的字符串。c風格字符串使用char[]或者const char *來表示。字符串字麵值也被編譯器推導為const char *

windows環境下,字符串編譯後被存在.rsrc區段中(區段是可以隨意改名的,不同編譯器實現也可能不同,可以打開peid去查)。這個區段是隻讀的,你如果強行寫入程序會崩潰,所以為了保險起見給你const char *

但是現代的c 編程不提倡用c風格字符串(就像obj-c也不提倡使用c風格字符串,而是NSString),所以你隻要記住上麵那一點,並且使用std::string就好了。遇到c風格字符串,如果你要使用,應該馬上用string的構造函數轉換為string

記住,你寫的是c ,不是c!

構造函數調用有兩種形式,一種是函數形式,比如string url("segmentfault.com")。但是,特別地,如果構造函數隻有一個參數,可以寫成賦值形式,即:

#include<string>
string url = "segmentfault.com";

隻要這是對象的初始化,而且存在相應的構造函數,就會編譯成構造函數的調用。而不是先創建string,再調用operator =。上麵那句話的實際作用是拿const char *來構造string

或者如果你想讓編譯器推斷為string類型,在它後麵加個s。

auto url = "segmentfault.com"s;

你如果用char []保存字符串,那它是存在棧上的。

是因為原生數組的名字,可以被編譯器推導為低一級的指針,指向數組起始位置,比如char[]在使用時會被當作char *

char[]和別的數組不同的地方還在於可以用字符串字麵值初始化。

如果你這樣寫:

char str[] = "segmentfault.com";

就相當於

char str[] = {'s','e','g','m','e','n','t','f','a','u','l','t','.','c','o','m','rrreee'};
熱門教學
更多>
最新下載
更多>
網站特效
網站源碼
網站素材
前端模板