老生常談:char*,char[],strncat,strcpy

寫項目的時候又被最基礎的 char* , char[] , strncat , strcpy卡了一會,太久沒碰老是搞混,索性在這裏做個筆記:

char* ,const char*,const char* const

	const char* str1 = "abc";
	// char* str1="abc";
	// 有些編譯器允許上面這樣子寫
	const char* const str3 = "abc";
	// str3 = "def";  錯誤!!!str3指針不可改變指向!!
	printf_s("st1:%p    str3:%p\n", str1, str3);
	// st1:012E8B30    str3:012E8B30
const char* str1 = "abc";

在這句裏,“abc”,做了3件事:

  1. 申請了內存(全局變量區)
  2. 在字符串尾部添加了’/0’(sizeof(“abc”)因此是4,strlen(“abc”)是3,strlen不統計’/0’)
  3. 返回了字符串的地址,返回類型是const char*,這裏賦值給了str1

所以,const char* str1=“abc” 這句話是正確的(編譯器不同,有時需加上const關鍵字,因爲數組名退化爲的是常量指針)。
如果想限定str1指向,const char* const str3 = “abc” 這樣寫。
而正因爲“abc”申請區域是常量存儲區,很清楚看到printf_s(“st1:%p str3:%p\n”, str1, str3);的地址是一樣的。

分配區域是常量存儲區!!!

char*,char[]

	const char* str1 = "abcdef";
	cout << strlen(str1)<<endl;      // 6
	cout << sizeof(str1) << endl;    // 4
	char str2[7] = "abcdef";
	cout << strlen(str2)<<endl;      // 6 
	cout << sizeof(str2) << endl;    // 7

	printf_s("st1:%p    str2:%p\n", str1, str2);
	// st1:00F48BD0    str2:00BEFA3C

主要注意的就是,“abcdef”是一個常量,

char str2[10] = "abcdef";

“abcdef”先會在常量存儲區存下來,然後會因爲要賦值給str2,會在中開闢一段內存,內存大小爲7個節點(char數組後會自動加一個’\0’),然後又有一個"abc"被保存在中。
因此str1和str2地址是不一樣的。

strncat(),strcpy()

strncat()主要功能是在字符串的結尾追加n個字符。
strcpy是一種C的標準庫函數,strcpy把**含有’\0’*的字符串複製到另一個地址空間,返回值的類型爲char

結合以上:char*,char[]的特性:

	char *str1="abcd";
	// const char*str1="abcd; 等價
	char str2[20] = "1234";

	strncat(str1, str2, 4);

像是某些版本VS或者DEV這樣子是不會報錯,但是是不可行的:首先,str1指向的"abcd"的地址是在常量存儲區的,在存儲的僅僅是指向該區的地址,是無法對str1指向的常量區("abcd"的地址)進行修改。

	char *str1="abcd";
	char str2[] = "1234";

	strncat(str2, str1, 4);
	printf("%s\n", str2);

這樣子反過來就可以了。
strcpy()同理。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章