[转贴]char s[]字串和char *s字串有什么差別?
C語言有兩種字串宣告方式char s[]和char *s,兩者有什麼差異呢?
Introduction
char s[] = "Hello World";
char *s = "Hello World";
char *s = "Hello World";
皆宣告了s字串,在C-style string的函數皆可使用,但兩者背後意義卻不相同。
char s[] = "Hello World";
的s是個char array,含12個byte(包含結尾\0),"Hello World"對s來說是initializer,將字元一個一個地copy進s陣列。
char *s = "Hello World";
的s是一個pointer指向char,由於"Hello World"本身就是一個string literal,所以s指向"Hello World"這個string literal的起始記憶體位置。
做個簡單的實驗證明兩者不同
 1 #include <iostream>
#include <iostream>
2
3 using namespace std;
using namespace std;
4
5 int main() {
int main() {
6 char s1[] = "Hello World";
 char s1[] = "Hello World";
7 char *s2  = "Hello World";
 char *s2  = "Hello World";
8 
 
9 cout << "size of s1: " << sizeof(s1) << endl;
 cout << "size of s1: " << sizeof(s1) << endl;
10 cout << "size of s2: " << sizeof(s2) << endl;
 cout << "size of s2: " << sizeof(s2) << endl;
11 }
}
 #include <iostream>
#include <iostream>2

3
 using namespace std;
using namespace std;4

5
 int main() {
int main() {6
 char s1[] = "Hello World";
 char s1[] = "Hello World";7
 char *s2  = "Hello World";
 char *s2  = "Hello World";8
 
 9
 cout << "size of s1: " << sizeof(s1) << endl;
 cout << "size of s1: " << sizeof(s1) << endl;10
 cout << "size of s2: " << sizeof(s2) << endl;
 cout << "size of s2: " << sizeof(s2) << endl;11
 }
}
執行結果
 size of s1: 12
size of s1: 12 size of s2: 4
size of s2: 4
s1是陣列,所以占了12 byte,而s2只是pointer,所以占了4 byte,實驗結果與預期相同。
實際使用有什麼不同嗎?兩種寫法皆可使用substring和pointer寫法,但只有char *s可以直接使用*s++寫法。
char s[]
 1 #include <iostream>
#include <iostream>
2
3 using namespace std;
using namespace std;
4
5 int main() {
int main() {
6 char s[] = "Hello World";
 char s[] = "Hello World";
7 
 
8 for(int i = 0; i != 11; ++i) {
 for(int i = 0; i != 11; ++i) {
9 cout << s[i];
  cout << s[i];
10 }
 }
11 cout << endl;
 cout << endl;
12 
 
13 for(int i = 0; i != 11; ++i) {
 for(int i = 0; i != 11; ++i) {
14 cout << *(s + i);
  cout << *(s + i);
15 }
 }
16 cout << endl;
 cout << endl;
17 }
}
18
 #include <iostream>
#include <iostream>2

3
 using namespace std;
using namespace std;4

5
 int main() {
int main() {6
 char s[] = "Hello World";
 char s[] = "Hello World";7
 
 8
 for(int i = 0; i != 11; ++i) {
 for(int i = 0; i != 11; ++i) {9
 cout << s[i];
  cout << s[i];10
 }
 }11
 cout << endl;
 cout << endl;12
 
 13
 for(int i = 0; i != 11; ++i) {
 for(int i = 0; i != 11; ++i) {14
 cout << *(s + i);
  cout << *(s + i);15
 }
 }16
 cout << endl;
 cout << endl;17
 }
}18

執行結果
 Hello World
Hello World Hello World
Hello World
char *s
 1 #include <iostream>
#include <iostream>
2
3 using namespace std;
using namespace std;
4
5 int main() {
int main() {
6 char *s = "Hello World";
 char *s = "Hello World";
7 
 
8 for(int i = 0; i != 11; ++i) {
 for(int i = 0; i != 11; ++i) {
9 cout << s[i];
  cout << s[i];
10 }
 }
11 cout << endl;
 cout << endl;
12 
 
13 for(int i = 0; i != 11; ++i) {
 for(int i = 0; i != 11; ++i) {
14 cout << *(s + i);
  cout << *(s + i);
15 }
 }
16 cout << endl;
 cout << endl;
17 }
}
 #include <iostream>
#include <iostream>2

3
 using namespace std;
using namespace std;4

5
 int main() {
int main() {6
 char *s = "Hello World";
 char *s = "Hello World";7
 
 8
 for(int i = 0; i != 11; ++i) {
 for(int i = 0; i != 11; ++i) {9
 cout << s[i];
  cout << s[i];10
 }
 }11
 cout << endl;
 cout << endl;12
 
 13
 for(int i = 0; i != 11; ++i) {
 for(int i = 0; i != 11; ++i) {14
 cout << *(s + i);
  cout << *(s + i);15
 }
 }16
 cout << endl;
 cout << endl;17
 }
}
執行結果
 Hello World
Hello World Hello World
Hello World
但卻只有char *s可以使用*s++寫法。
 1 #include <iostream>
#include <iostream>
2
3 using namespace std;
using namespace std;
4
5 int main() {
int main() {
6 char *s = "Hello World";
 char *s = "Hello World";
7 
 
8 while(*s)
 while(*s) 
9 cout << *s++;
  cout << *s++;
10 }
}
11
12
 #include <iostream>
#include <iostream>2

3
 using namespace std;
using namespace std;4

5
 int main() {
int main() {6
 char *s = "Hello World";
 char *s = "Hello World";7
 
 8
 while(*s)
 while(*s) 9
 cout << *s++;
  cout << *s++;10
 }
}11

12

執行結果
 Hello World
Hello World
理由何在呢?
char s[]為陣列,雖然s = &s[0],但s是『常數』,恆等於&s[0]無法改變,但char *s為pointer,指向s[0],但卻是變數,可以任意改變,故可用*s++任意更改pointer值。
Conclusion
一般人很少分辨char s[]和char *s的差異,大部分狀況下用法相同,但char *s速度略快,因為不需copy的動作,且*s++為C語言常用的寫法,只有char *s才支援。
Reference
C Primer Plus 5/e中文版 p.480
 
                    
                     
                    
                 
                    
                
 


 
  
                
            
         
         浙公网安备 33010602011771号
浙公网安备 33010602011771号