來源於C Primer Plus
定義字符串
字符串字面量
- 用雙引號括起來的內容爲字符串字面量,也叫字符串常量
- 雙引號中的字符,編譯器自動加入末尾的\0字符,作爲字符串儲存在內存中
- 字符串常量屬於靜態存儲類別,用雙引號擴起來的內容被視爲指向該字符串儲存位置的指針。這類似於把數組名作爲指向該數組的指針
- demo
/*strptr.c*/
#include<stdio.h>
int main(void)
{
printf("%s, %p ,%c\n", "We", "are", *"space fares");
return 0;
}
- 給space fares指針解引用得到首地址,即對應的第一個字符
字符串數組 初始化
- 用指定字符出啊初始化數組,必須讓編譯器知道需要多少空間:
const char m1[40] = "limit yourself to";
- 如果用
{‘a’,‘b’...,'\0'}
字符初始化,必須有\0
,如果沒有,那麼這個數組不是字符串,而只是字符數組;但“”
會自動加\0 - 指定數組大小,要確保數組的元素個數至少比字符串長度大1,未使用的元素被自動初始化爲\0
- 也可讓編譯器自己數數組大小
char m2[] = "asdfa"
,但必須在初始化完成,不能先聲明一個[]的,再稍後填充;對於char a[n];
在c99前不可,之後增加了變長數組
數組和指針
- 對於
const char ar1[] = "asfdalk1";
- 字符串都作爲可執行文件的一部分儲存在數據段中,當把程序載入內存,纔會爲該數組分配內存,載入字符串到數組中,因此字符串有兩個副本,一個是靜態內存中的字符串字面量,另一個是儲存在數組的字符串
- 要注意ar1在此後會被編譯器識別爲數組首元素地址的別名,ar1是地址常量,不可以自加自減。
- 而對於
const char *ptr1 = "asfalk1";
編譯器也會爲字符串在靜態存儲區預留空間,一旦程序開始執行,會將字符串的地址儲存在指針變量中,該變量指向字符串首字符,可以改變。 - 字符串字面量(“”)被視爲const數據,由於Ptr1指向const數據,所以不能改變他指向的數據,但是指針本身可以自增自減,如果把字符串字面量賦值給數組,可以隨意修改數據,除非數組聲明爲const
初始化數組把靜態存儲區的字符串拷貝到數組中,而初始化指針只把字符串的地址拷貝給指針
指針和數組的區別
對於:
char heart[] = "I love sss";
const char *head = "I love zzz";
數組名heart是常量,指針名head是變量
- 可以
head = heart
使得head指向heart數組 - 不可以
heart = head
因爲heart是常量 不可能5=x
- 數組的元素是變量(除非數組是const),但是數組名不是變量
- 而對於
char *head = " i love zzz";
我們建議如果用字符串字面量對指針初始化,那麼就用const進行限定,否則,如果你head[2]=a
,那麼將影響所有使用該字符串的代碼(回想下指針初始化的方式,拷貝靜態空間的地址),有可能無法預測編譯器的反應 - 所以說如果打算修改字符串,就不要用指針指向字符串字面量,而是用非const數組,而如果用指針指向字符串字面量,建議增加const限定
字符串數組
對於
const char *mytalents[5] = {
"faskjha",
"1j2iljklfds",
"ajmlkfjla"
"fasfda",
"a sdkl"
};
char yourtalents[5][20] = {
"faskjha",
"1j2iljklfds",
"ajmlkfjla"
"fasfda",
"a sdkl"
};
- mytalents數組是一個內含5個指針的數組,每個指針指向一個字符串,共佔40字節,而字符串字面量都存儲在靜態控件
- yourtalents則佔用5*20字節的內存,是二維字符數組
- 總之,指針數組比二維字符效率高
- 但是指針數組指向的字符串字面量不可以更改,而二維字符數組可以更改,且可以預留控件
指針和字符串
看一個Demo:
/*p_and_s.c--指針和字符串*/
#include<stdio.h>
int main(void)
{
const char * mesg ="hhhhhh";
const char * copy ;
copy = mesg;
printf("mesg = %s, &mesg = %p , value of mesg = %p\n" , mesg, &mesg, mesg);
printf("copy = %s, © = %p , value of copy = %p\n" , copy, ©, copy);
return 0;
}