char字串指標
字串常數
字串常數是包在二個雙引號之間””
"http://www.google.com"
以下皆為字串常數
-
例1
s指標指向字串常數,常數占在記憶體唯讀空間,常數是放在code segment 記憶體區塊,只能讀取,無法修改。
1
char * s = "http://www.google.com";
-
例2
程式碼中的”abcdefg”是字串常數。
1
2
3
4
5
6
7
8
//使用new動態配置記憶體空間,new會傳回char陣列記憶體區塊的開始記憶體位址。
char* message = new char[100];
//把字串常數abcdefg拷貝至char陣列
strcpy(message, "abcdefg");
//記憶體回收
delete[] message;
//將指標指向null,代表不指向任何記憶體位址
message = nullptr;
無法透過*取值運算子,把字串常數指派給指標
無法透過*取值運算子,把字串常數指派給指標,以下會編譯錯誤,只能使狦strcpy複製字串常數。
1
2
char* message = new char[100];
*message = "abcdefg";//編輯錯誤
字串常數記憶體大小
因為常數非動態記憶空間,所以要透過strlen來計算記憶體空間大小,注意!strlen不包含結尾\0的大小,所以計算記憶體空間要再+1,加上結尾\0的大小
1
2
3
char* s = "http://www.google.com";//21個字元(不含結尾\0)
//因為常數非動態記憶空間,所以要透過strlen來計算記憶體空間大小
size_t s_size = strlen(s) + 1;//strlen不包含結尾\0的大小
字元陣列不是常數
字元陣列不是常數,以下寫法不是常數,是有占stack堆疊的記憶體空間
1
2
3
char s1[] = "http://www.google.com";
cout << "s1堆疊記憶體大小=" << sizeof(s1) << endl;
cout << "s1長度=" << strlen(s1) << endl;
s1記憶體大小=22
s1長度=21
指向字串常數的指標
參考
以下程式分別為字串陣列與指標初始化字串常數,不可以使用字串陣列名++
,因為陣列名是指向陣列記憶體的開始位址,到程式結束前都不會改變,陣列名是常數,就像我們不可能寫成7++
的意思是一樣的,而指標是變數,變數就是可以改變值(在這裡是改變存放的記憶體位址)。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
#include <iostream>
using namespace std;
int main() {
//cstr1陣列名是記憶體起始位址
char cstr1[] = "Hello World!";
//cstr2是指標變數,指向字串常數"Hello World!"
//常數是放在code segment 記憶體區塊,不可以使用指標指向常數記憶體位址
char* cstr2 = "Hello World!";
cout << "cstr1 = " << cstr1 << endl;
cout << "cstr2 = " << cstr2 << endl;
//cstr1陣列名是記憶體起始位址,是常數,不可以++
//cstr1++;
//指標是變數,可以修改
//指標原本指向起始位址"H",++移動1byte,指標指向"e"的記憶體位址
cstr2++;
//印出ello World!,直到遇到\0結尾字元,就停止輸出
cout << "cstr2 = " << cstr2 << endl;
return 0;
}
cstr1 = Hello World!
cstr2 = Hello World!
cstr2 = ello World!
字串指標與函式
參考
寫一個傳進指標的函式,函式是把來源字串(src)拷貝到目標字串(desc)。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
#include <iostream>
using namespace std;
void copystr(char* desc, char* src) {
//若指標指向的記憶體位址的值是\0就離開while
//若指標指向的記憶體位址的值不是\0就進入while
while(*src) {
//取出src指標指向的記憶體位址的內容
//使用*取值運算子修改desc指向記憶體位址的*
*desc = *src;
desc++;//指標往下一個位址移動,移動1byte
src++;//指標往下一個位址移動,移動1byte
}
//目標字串放上結尾字元,代表字串結束
*desc = '\0';
}
int main() {
//拷貝的來源字串
char* src = "Hello World!";
//+1是為了加上結尾空字元\0,strlen預設是不含\0
size_t len = strlen(src) + 1;
//拷貝的目標字串
char* desc = new char[len];
copystr(desc, src);
cout << "desc = " << desc << endl;
//記憶體釋放陣列
delete[] desc;
//desc指標不指向任何記憶體位址
desc = nullptr;
return 0;
}
desc = Hello World!
另一種寫法
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
#include <iostream>
using namespace std;
void copystr(char* desc, char* src) {
//若指標指向的記憶體位址的值是\0就離開while
//若指標指向的記憶體位址的值不是\0就進入while
while(*src) {
//取出src指標指向的記憶體位址的內容
//使用*取值運算子修改desc指向記憶體位址的*
//desc與src指標往下一個位址移動,移動1byte
*desc++ = *src++;
}
//目標字串放上結尾字元,代表字串結束
*desc = '\0';
}
int main() {
//拷貝的目標字串
char desc[100];
//拷貝的來源字串
char* src = "Hello World!";
copystr(desc, src);
cout << "desc = " << desc << endl;
return 0;
}
指標字串拷貝
參考
char * strcpy ( char * destination, const char * source );
使用函式庫strcpy來進行字串拷貝,參數2指標前面有const,代表strcpy()函式不能修改source指標所指向的字元,因為指向的字元是常數,但可以改變指標src指向的位址。
1
2
3
4
5
6
7
8
9
10
11
#include <iostream>
using namespace std;
int main() {
//拷貝的目標字串
char desc[100];
//拷貝的來源字串
char* src = "Hello World!";
strcpy(desc, src);
cout << "desc = " << desc << endl;
return 0;
}
desc = Hello World!
指標陣列存放多個字串常數位址
參考
之前二維陣列字串的範例中,定義陣列的大小是7個字串陣列,每個字串固定10byte,記憶體空間就會是70byte,但每個字母有長有短,就會造成記憶體空間上的浪費。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#include <iostream>
using namespace std;
const int DAYS = 7; //字串數,7個字串
const int MAX = 10; // 每個字串最大長度,包含\0
int main() {
char str[DAYS][MAX] = {"Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"};
//印出二維陣列字串的記憶體大小
//7個字串 * 每個字串最大長度10byte
cout << "str size = " << sizeof(str) << endl;
for (int i = 0; i < DAYS; i++) {
//印出字串
cout << str[i] << endl;
}
return 0;
}
str size = 70
Sunday
Monday
Tuesday
Wednesday
Thursday
Friday
Saturday
使用指標陣列,存放多個字串常數的記憶體位址,每個字串常數都有起始記憶體位址,即字串常數的第一個字元的位址,就不用定義二維陣列大小去存放字元。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
#include <iostream>
using namespace std;
const int DAYS = 7; //陣列裡的指標個數
int main() {
//陣列存放7個指標,每個指標指向字串常數的第一個字元的位址
char *arr_ptrs[DAYS] =
{"Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"};//字串指標陣列
//指標的固定大小是8byte,指標陣列存放7個指標,總共大小為8byte*7
cout << "arr_ptrs size = " << sizeof(arr_ptrs) << endl;
for (int i = 0; i < DAYS; i++)
cout << arr_ptrs[i] << endl;
return 0;
}
arr_ptrs size = 56
Sunday
Monday
Tuesday
Wednesday
Thursday
Friday
Saturday