char* 与 char []的区别
起源于一次写处理字符串的函数时,使用了char*创建字符串,然后编译运行通过,但是有warning: deprecated conversion from string constant to 'char*' [-Wwrite-strings],然后查了相关资料把这个问题搞懂了。
指针常量与常量指针
首先,我们需要搞懂指针常量与常量指针的区别
指针常量
指针类型的常量
语法:char* const p;
这里的指针p就是一个指针常量,其特点是
也就是说const是作用在p上的
例子:
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
| #include <iostream> #include <cstdlib> using namespace std;
int main() { char ch = 'a'; char c = 'b'; char* const p = &ch; printf("ch : '%c', address : %0x\n",ch,&ch); printf("*p : '%c', address : %0x\n",*p,p); *p = 'm'; printf("ch : '%c', address : %0x\n",ch,&ch); printf("*p : '%c', address : %0x\n",*p,p);
printf("c : '%c', address : %0x\n",c,&c); return 0; }
|
常量指针
指向“常量”的指针
语法:const char *p;或者char const *p;
这里的指针p就是一个常量指针,其特点是
也就是说const是作用在*p上的
例子:
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
| #include <iostream> #include <cstdlib> using namespace std;
int main() { char ch = 'a'; char c = 'b'; const char* p = &ch; printf("ch : '%c', address : %0x\n",ch,&ch); printf("*p : '%c', address : %0x\n",*p,p); p = &c; printf("p的指向修改后\n"); printf("ch : '%c', address : %0x\n",ch,&ch); printf("*p : '%c', address : %0x\n",*p,p); printf("c : '%c', address : %0x\n",c,&c); return 0; }
|
字符串常量保存在哪?
先看例子
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 33 34 35 36 37
| #include <iostream> #include <cstdlib> #include <string> using namespace std; static int num = 10; char *s = "test"; void a(){ char* sa = "test"; printf("指针sa的地址: 0x%0x\n", &sa); printf("指针sa指向的字符串的地址: 0x%0x\n", sa); } int main() { cout<<"static num address: "<<&num<<endl; printf("指针s的地址: 0x%0x\n", &s); printf("指针s指向的字符串的地址: 0x%0x\n", s); a(); char* sb = "test"; printf("指针sb的地址: 0x%0x\n", &sb); printf("指针sb指向的字符串的地址: 0x%0x\n", sb);
char* sc = "test"; printf("指针sc的地址: 0x%0x\n", &sc); printf("指针sc指向的字符串的地址: 0x%0x\n", sc); return 0; }
|
说明:在这个程序中,我们在不同的地方都创建了字符串"test",全局指针变量s,函数a()内的临时指针变量sa,main()函数中的指针变量sb和sc,但是通过输出地址发现它们都指向了同一块内存空间。
而且结合上面的结果和c++中的内存分区模型,我们可以看出,变量num,s,和"test"都被放在了全局区里面。而sa,sb,sc都放在栈区里面。
因此,从上面这个程序我们可以看出
一旦有字符串常量在运行期间被创建出来,就会在内存中一直保持到程序结束,当使用相同的字符串常量的时候,不会再创建字符串常量,而是指向之前创建的那个。因此字符串常量是贯穿整个程序的生命周期的。
字符串变量的保存在哪?
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 33 34 35 36 37 38 39 40 41 42 43
| #include <iostream> #include <cstdlib> #include <string> using namespace std; const char *s = "test"; char ss[] = "test"; void a(){ char ssa[] = "test"; const char* sa = "test"; printf("指针sa的地址: 0x%0x\n", &sa); printf("指针sa指向的字符串的地址: 0x%0x\n", sa); printf("ssa的地址: 0x%0x\n", &ssa); } int main() {
printf("指针s的地址: 0x%0x\n", &s); printf("指针s指向的字符串的地址: 0x%0x\n", s); printf("ss的地址: 0x%0x\n", &ss); cout<<"---"<<endl; a(); char ssb[] = "test"; const char* sb = "test"; cout<<"---"<<endl; printf("指针sb的地址: 0x%0x\n", &sb); printf("指针sb指向的字符串的地址: 0x%0x\n", sb); printf("ssb的地址: 0x%0x\n", ssb); return 0; }
|
这里就可以看出变量和字符串常量的区别了。尽管ss,ssa,ssb它们在内容上都是一样的,但是因为是变量,所以都需要单独开辟空间储存。而不能像常量*s,*sa,*sb一样只用一块儿空间。
关于char *
先看例子:
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
| #include <iostream> #include <cstdlib> using namespace std;
int main() { char *s = "1234"; cout<<s<<endl; printf("%0x\n",s);
cout<<s<<endl; char ch = 'a'; s = &ch; cout<<*s<<endl; printf("%0x\n",s); return 0; }
|
关于char []
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
| #include <iostream> #include <cstdlib> using namespace std;
int main() { char s[] = "1234"; cout<<s<<endl; printf("%0x\n",s); s[0] = 'a';
cout<<s<<endl; char ch = 'a';
cout<<*s<<endl; printf("%0x\n",s); return 0; }
|
总结
目前两种使用方式:
p可改,*p不可改
s不可改,s[]中的内容可改