1. 程式人生 > >C/C++中,為什麼字串可以賦值給字元指標變數,單引號和雙引號的區別

C/C++中,為什麼字串可以賦值給字元指標變數,單引號和雙引號的區別

本文是通過幾篇轉帖的文章整理而成的:

http://www.slyar.com/blog/c-quotation-marks.html

http://www.cnblogs.com/KingOfFreedom/archive/2012/12/07/2807223.html

1、含義不同。

用單引號引起的一個字元實際上代表一個整數,整數值對應於該字元在編譯器採用的字符集中的序列值。而一般我們的編譯器採用的都是ASCII字符集。因此's'的含義其實和十進位制數115的含義是一致的。

而用雙引號引起的字串,代表的是一個指向無名陣列起始字元的指標。

2、大小不同。

用單引號引起的一個字元大小就是一個位元組。

而用雙引號引起的字串大小是字元的總大小+1,因為用雙引號引起的字串會在字串末尾新增一個二進位制為0的字元'\0'。

具體介紹

為什麼字串可以賦值給字元指標變數

char *p,a='5';
p=&a;                     //顯然是正確的,
p="abcd";              //但為什麼也可以這樣賦值??

問:一直理解不了為什麼可以將字串常量賦值給字元指標變數,請各位指點! 答: 雙引號做了3件事:  
1.申請了空間(在常量區),存放了字串 
2. 在字串尾加上了'/0'    
3.返回地址

你這裡就是 返回的地址  賦值給了  p                      


二、

char *p = “hello”;

上邊的表示式為什麼可以,而把p換成陣列,然後再賦值就不行了

解釋:

字串常量"hello"出現在一個表示式中時"hello"表示式使用的值就是這些字元所儲存的地址(在常量區),而不是這些字元本身。

所以,可以把字串賦值給指向字元的指標p,而不能把字串賦值給一個字元陣列。 

char a[10] = “hello”; //這樣可以,這種情況是c語言初始化所支援的

如果寫成char a[10]

然後 a = “hello” 這樣就錯誤了。 

同樣是a陣列,char a[10] = “hello”;這種是陣列的初始化,和a[0] = ‘h’ a[1] = ‘e’…是一個道理

但是換成char a [10]

然後a = “hello”就不行了 “hello”賦值的值是一個地址,而a雖然也有地址,但是這與指標是不一樣的,指標的值是地址,而陣列的值雖然也是地址,但是卻是一個常量,所以不能給常量賦值。

程式碼測試

#include <stdio.h>

int main()

{

       char *p = "hello";

       printf("%s",p);

       char a[10];

       a = "hello";

       return 0;

}

error C2440: '=' : cannot convert from 'char [6]' to 'char [10]'

        There is no context in which this conversion is possible

看到這樣的錯誤提示,你是否會想到把char a[10]改成char a[6]呢

試一下,

error C2106: '=' : left operand must be l-value

運算子的左邊應該是一個“左值”。所謂“左值”就是指在程式中佔用記憶體空間、可以被修改的量,比如各種變數。 

繼續擴充套件問題:

在使用指標的時候,指標可以自增,而陣列不能自增

編譯器給陣列分配了空間,陣列a的地址就是一個常量了,讓常量自增這肯定是不行的。

繼續擴充套件:

在指標自增的時候,編譯器會自動識別型別比如指標是指向int型的,想獲取下一個的地址時,指標直接p++就行了,不要多此一舉的p+4了

      特別需要注意的是,在void指標使用的時候,不能使用指標運算,應為void型編譯器不能識別型別的長度(即指標所指物件的體積),p++這樣就是不合法的,即不能進行數學運算,也不能使用*取值操作,想使用必須轉換為其它的型別