C语言中没有特定的字符串类型,我们通常是将字符串放在一个字符数组中,这在《C语言字符数组和字符串》中已经进行了详细讲解,这里不妨再来演示一下:
#include <stdio.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> 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";
字符串中的所有字符在内存中是连续排列的,str 指向的是字符串的第 0 个字符;我们通常将第 0 个字符的地址称为字符串的首地址。字符串中每个字符的类型都是char,所以 str 的类型也必须是char *。
下面的例子演示了如何输出这种字符串:
#include <stdio.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
这一切看起来和字符数组是多么地相似,它们都可以使用%s输出整个字符串,都可以使用*或[ ]获取单个字符,这两种表示字符串的方式是不是就没有区别了呢?
有!它们最根本的区别是在内存中的存储区域不一样,字符数组存储在全局数据区或栈区,第二种形式的字符串存储在常量区。全局数据区和栈区的字符串(也包括其他数据)有读取和写入的权限,而常量区的字符串(也包括其他数据)只有读取权限,没有写入权限。
关于全局数据区、栈区、常量区以及其他的内存分区,我们将在《C语言和内存》专题中详细讲解,相信你必将有所顿悟,从根本上理解C语言。
内存权限的不同导致的一个明显结果就是,字符数组在定义后可以读取和修改每个字符,而对于第二种形式的字符串,一旦被定义后就只能读取不能修改,任何对它的赋值都是错误的。
我们将第二种形式的字符串称为字符串常量,意思很明显,常量只能读取不能写入。请看下面的演示:
#include <stdio.h> int main(){ char *str = "Hello World!"; str = "I love C!"; //正确 str[3] = 'P'; //错误 return 0; }
这段代码能够正常编译和链接,但在运行时会出现段错误(Segment Fault)或者写入位置错误。
第4行代码是正确的,可以更改指针变量本身的指向;第3行代码是错误的,不能修改字符串中的字符。
到底使用字符数组还是字符串常量
在编程过程中如果只涉及到对字符串的读取,那么字符数组和字符串常量都能够满足要求;如果有写入(修改)操作,那么只能使用字符数组,不能使用字符串常量。
获取用户输入的字符串就是一个典型的写入操作,只能使用字符数组,不能使用字符串常量,请看下面的代码:
#include <stdio.h> int main(){ char str[30]; gets(str); printf("%s\n", str); return 0; }
运行结果:
C C++ Java Python JavaScript
C C++ Java Python JavaScript
最后我们来总结一下,C语言有两种表示字符串的方法,一种是字符数组,另一种是字符串常量,它们在内存中的存储位置不同,使得字符数组可以读取和修改,而字符串常量只能读取不能修改。
以上就是对C语言 字符串指针的资料整理,后续继续补充相关资料,谢谢大家对本站的支持!
本文向大家介绍C语言 数组指针详解及示例代码,包括了C语言 数组指针详解及示例代码的使用技巧和注意事项,需要的朋友参考一下 数组(Array)是一系列具有相同类型的数据的集合,每一份数据叫做一个数组元素(Element)。数组中的所有元素在内存中是连续排列的,整个数组占用的是一块内存。以int arr[] = { 99, 15, 100, 888, 252 };为例,该数组在内存中的分布如下图所示
本文向大家介绍C语言 二级指针详解及示例代码,包括了C语言 二级指针详解及示例代码的使用技巧和注意事项,需要的朋友参考一下 指针可以指向一份普通类型的数据,例如 int、double、char 等,也可以指向一份指针类型的数据,例如 int *、double *、char * 等。 如果一个指针指向的是另外一个指针,我们就称它为二级指针,或者指向指针的指针。 假设有一个 int 类型的变量 a,p
本文向大家介绍C语言指针详解及用法示例,包括了C语言指针详解及用法示例的使用技巧和注意事项,需要的朋友参考一下 新手在C语言的学习过程中遇到的最头疼的知识点应该就是指针了,指针在C语言中有非常大的用处。下面我就带着问题来写下我对于指针的一些理解。 指针是什么? 指针本身是一个变量,它存储的是数据在内存中的地址而不是数据本身的值。它的定义如下: 首先我们可以理解 int*
本文向大家介绍C语言中的指针以及二级指针代码详解,包括了C语言中的指针以及二级指针代码详解的使用技巧和注意事项,需要的朋友参考一下 很多初学者都对C中的指针很迷糊,希望这篇blog能帮助到大家: 1.什么是“指针”: 在执行C程序的时候,由于我们的数据是存储在内存中的。所以对于C程序本身来说,如果想找到相应被调用的数据,就要知道存储该数据的内存地址是多少,换言之,C程序通过已知的内存地址到相应的内
本文向大家介绍C语言 位域详解及示例代码,包括了C语言 位域详解及示例代码的使用技巧和注意事项,需要的朋友参考一下 有些数据在存储时并不需要占用一个完整的字节,只需要占用一个或几个二进制位即可。例如开关只有通电和断电两种状态,用 0 和 1 表示足以,也就是用一个二进位。正是基于这种考虑,C语言又提供了一种叫做位域的数据结构。 在结构体定义时,我们可以指定某个成员变量所占用的二进制位数(Bit),
本文向大家介绍C语言 位运算详解及示例代码,包括了C语言 位运算详解及示例代码的使用技巧和注意事项,需要的朋友参考一下 所谓位运算,就是对一个比特(Bit)位进行操作。在《二进制思想以及数据的存储》一节中讲到,比特(Bit)是一个电子元器件,8个比特构成一个字节(Byte),它已经是粒度最小的可操作单元了。 C语言提供了六种位运算符: 运算符 & | ^ ~ << >> 说明 按位与 按位或 按位