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++這樣就是不合法的,即不能進行數學運算,也不能使用*取值操作,想使用必須轉換為其它的型別