文章程式碼顯示

2018年12月8日 星期六

《筆記》C語言 - 補充_4:char* 與 char[] 用來定義字串時的不同與坑


當你使用 char* string1 = "STR123456"; 來建立一個指標字串時,電腦本身的作為如下

1. 在記憶體中的某個位置產生一個字串 STR123456 (例如稱這個地址為 addressA)
2. 在記憶體中的另一個位置產生一個指向 char 的指標 string1 ( 4Bytes )
3. 將 string1 指向 addressA

一般而言我們使用

printf( "string1 + 2 = %c\n",*(string1 + 2) );

來取用字串中的某個字元

但使用指標來指向一個字串時,很 tricky 的是你可以使用取陣利元素的方式來取出某個字元
printf( "string1[2] = %c\n",string1[2] );

但你不得企圖用取陣列元素的方法來強制修改字串中的某個文字(會造成程式崩潰)

所以建議在宣告 string1 時就使用 const char* 來宣告,如此一來當你有如上的操作時,編譯器就會報錯來提醒你做了非法操作

string1[2] = "Z";   // 不得使用

雖然你不能修改某個字元,但把 string1 指向另一個字串是可行的,例如

string1 = "ZXY";



const char* string2 = "ABC7891";
string1 = string2;

使用指標來定義字串以及使用字元陣列來定義字串的不同

當我們使用 char string3[] = "ABCDEF"; 來建立一個字串時,其電腦本身的作為又會不太一樣

1. 在記憶體中的某個位置產生一個字串 ABCDEF
2. 在記憶體中的另一個位置開始將 'A' 、 'B' 、 .... 'E'、'F'、'\0'   依序複製過去

因使用字元陣列來定義字串時,是將各個字元複製過去的,所以你就可以去修改某個字元

string3[2] = "Z";


除此之外,我們在程式中時常會需要知道一個字串的長度

如果我們使用字元陣列的方式來定義一個字串的話,可以使用 sizeof 來得到字串的長度,如

sizeof(string3)/sizeof(string3[0])

如果你使用指標來定義字串時,就無法利用 sizeof 來取得字串的長度,其原因為當你對一個指標進行 sizeof 時,你永遠都會得到 "4" 的結果

也就是說不管你得到的是 "一個指標所佔據的記憶體長度" 而 "不是它所指向的字串的長度"


相關程式碼

#include "stdio.h"
#include "stdlib.h"
int main(void) {

 /* 當你使用 char* string1 = "STR123456"; 來建立一個指標字串時,電腦本身的作為如下
  * 1. 在記憶體中的某個位置產生一個字串 STR123456 (例如稱這個地址為 addressA)
  * 2. 在記憶體中的某個位置產生一個指向 char 的指標 string1
  * 3. 將 string1 指向 addressA
  */
 const char* string1 = "STR123456";
 printf( "string1 = %s\n",string1 );
 printf( "string1 content = 0x%x\n",(int)string1); //即為 STR123456 在記憶體中的位址

 printf( "string1 + 2 = %c\n",*(string1 + 2) ); //使用指標的相加減來取出某個字元
 printf( "string1[2] = %c\n",string1[2] ); //亦可以用 取陣列某元素的方法來取得某個字元(特殊用法,不建議使用)
 /* string1[2] = "Z"; 不得企圖用取陣列元素的方法來強制修改字串中的某個文字(會造成程式崩潰) , 建議在宣告 string1 時就使用 const char* 來宣告*/

 string1 = "ZXY"; // 因string1本身是一個指標,所以你可以將它指向另一個字串
 printf( "string1 content = 0x%x\n",(int)string1); //即為 ZXY 在記憶體中的位址
 printf( "string1 = %s\n",string1 );
 printf( "string1 + 2 = %c\n",*(string1 + 2) );

 const char* string2 = "ABC7891";
 printf( "string2 = %s\n",string2 );
 printf( "string2 content = 0x%x\n",(int)string2); //即為 ABC7891 在記憶體中的位址
 string1 = string2; // 或將 string1 改指向 string2
 printf( "string1 content = 0x%x\n",(int)string1);
 printf( "string1 = %s\n",string1 );
 printf( "string1[2] = %c\n",string1[2] );

 char string3[] = "TTT";
 printf( "string3 = %s\n",string3 );
 string3[1] = 'B';
 printf( "string3 = %s\n",string3 );

 return 0;
}



↓↓↓ 連結到部落格方針與索引 ↓↓↓

Blog 使用方針與索引