C语言字符串指针(指向字符串的指针)详解
C语言中没有特定的字符串类型,我们通常是将字符串放在一个字符数组中。如下代码:
#include <stdio.h>
#include <string.h>
int main(){
char str[] = "http://c.biancheng.net";
int len = strlen(str), i;
//直接输出字符串
printf("%s\n", str);
//每次输出一个字符
for(i=0; i<len; i++){
printf("%c", str[i]);
}
printf("\n");
return 0;
}
运行结果:
http://c.biancheng.net
http://c.biancheng.net
字符数组当然是数组,那么我们就可以利用指针对字符数组进行操作。
#include <stdio.h>
#include <string.h>
int main(){
char str[] = "http://c.biancheng.net";
char *pstr = str;
int len = strlen(str), i;
//使用*(pstr+i)
for(i=0; i<len; i++){
printf("%c", *(pstr+i));
}
printf("\n");
//使用pstr[i]
for(i=0; i<len; i++){
printf("%c", pstr[i]);
}
printf("\n");
//使用*(str+i)
for(i=0; i<len; i++){
printf("%c", *(str+i));
}
printf("\n");
return 0;
}
运行结果:
http://c.biancheng.net
http://c.biancheng.net
http://c.biancheng.net
除了字符数组以外,c语言还支持另外一种表示字符的方法,就是直接使用一个指针指向字符串,例如:
char *str = "http://c.biancheng.net";
或者:
char *str;
str = "http://c.biancheng.net";
下面演示如何输出这种字符串:
#include <stdio.h>
#include <string.h>
int main(){
char *str = "http://c.biancheng.net";
int len = strlen(str), i;
//直接输出字符串
printf("%s\n", str);
//使用*(str+i)
for(i=0; i<len; i++){
printf("%c", *(str+i));
}
printf("\n");
//使用str[i]
for(i=0; i<len; i++){
printf("%c", str[i]);
}
printf("\n");
return 0;
}
运行结果:
运行结果:
http://c.biancheng.net
http://c.biancheng.net
http://c.biancheng.net
这样看起来,字符数组和使用一个指针指向字符串是非常相似的。那么这两种表示字符串的区别是什么?
特别注意:
字符数组和指针字符串的区别是内存中的存储区域不一样,字符数组存储在全局数据区或栈区,指针字符串存储在常量区。
全局区和栈区的字符串(包括其它数据)有读取和写入的权限,而常量区的字符串只有读取权限,没有写入权限。
内存权限不同导致一个明显的结果就是,字符数组在定义后可以读取和修改每个字符,而对于指针字符串来说,一旦被定义
后就只能读取而不能修改,任何对它的赋值都是错误的。
1 #include <stdio.h>
2 int main(){
3 char *str = "Hello World!";
4 str = "I love C!"; //正确
5 str[3] = 'P'; //错误
6
7 return 0;
8 }
这段代码能够正常编译和链接,但是在运行时会出现段错误(Segment Fault)或者写入错误。
第四行代码是正确的,可以更改指针变量本身的指向;第5行代码是错误的,不能修改字符串中的字符。
那么到底使用字符数组还是字符串常量?
在编程过程中,如果只涉及到对字符串的读取,那么字符数组和字符串常量都可以满足要求;如果有写入(修改)的操作,
那么只能使用字符数组,不能使用字符串常量。
获取用户输入的字符串就是一个典型的写入操作,只能使用字符数组,不能使用字符串常量,请看下面的代码:
1 #include <stdio.h>
2 int main(){
3 char str[30];
4 gets(str);
5
6 char *ptr;
7 gets(ptr);//错误
8 printf("%s\n", str);
9
10 return 0;
11 }