@xudongh
2016-11-13T22:17:02.000000Z
字数 1641
阅读 1485
计算机
C库提供大量的函数用于读写字符串、拷贝字符串、比较字符串、合并字符串、查找字符串等。
字符串是以空字符(\0)结尾的char类型数组。
puts()
函数只显示字符串,而且自动在显示的字符串末尾加上换行符。
字符串字面量(字符串常量)
用双引号括起来的内容称为字符串字面量,也叫作字符串常量。
字符串常量属于静态存储类别,这说明如果在函数中使用字符串常量,该字符串只会被储存一次,在整个程序的生命期内存在,及时函数被调用多次。用双引号括起来的内容被视为指向该字符串储存位置的指针,这类似于把数组名作为指向该数组位置的指针。
在制定数组大小时,要确保数组的元素个数至少比字符串长度多1(为了容纳空字符)。所有未被使用的元素都被自动初始化为0(这里的0指的是char
形式的空字符,不是数字字符0)。
const char pets[10] = "nice cat.";
如果省略数组初始化声明中的大小,编译器会自动计算数组的大小。
const char pets[] = "nice cat.";
让编译器计算数组的大小只能用在初始化数组是,如果创建一个稍后再填充的数组,就必须在声明是时指定大小。
字符数组名和其他数组名一样,是该数组首元素的地址,因此,对于以下初始化:
char car[10] = "Tata";
那么,以下表达式都为真:
car == &car[0];
*car == 'T';
*(car+1) == car[1] == 'a';
还可以使用指针表示法创建字符串:
const char * pt1 = "this is a array.";
该声明和下面的数组表示法声明几乎相同:
cons char ae1[] = "this is a array.";
数组形式ar1[]
和指针形式*pt1
的区别
数组形式ar1[]
在计算机的内存中分配为一个内含n+1个元素(末尾空字符'\0')的数组,每个元素被初始化为字符串字面量对应的字符。通常,字符串都作为可执行文件的一部分储存在数据段中。当把程序载入内存时,也载入了程序中的字符串,字符串储存在静态存储区。但是,程序在开始运行时才会为该数组分配内存。此时,才讲字符串拷贝到数组中。注意,此时字符串有两个副本,一个是在静态内存中的字符串字面量,另一个是储存在ar1
数组中的字符串。不允许进行++ar1
的操作。
指针形式*pt1
也使得编译器为字符串在静态存储区预留n+1个元素的空间。另外,一旦开始执行程序,它会为指针变量pt1
留出一个储存位置,并把字符串的地址储存在指针变量中。该变量最初指向该字符串的首字符,但是它的值可以改变。因此可以使用递增运算符。
字符串字面量被视为const数据。由于pt1指向这个const数据,所以应该把pt1声明为指向const数据的指针。这意味着不能用pt1改变它所指向的数据,但是仍然可以改变pt1的值。
初始化数组把静态存储区的字符串拷贝到数组中,而初始化指针只把字符串的地址拷贝给指针。
二者的区别
- 数组形式拷贝字符串副本到数组;指针形式是把字符串的地址拷贝到指针变量。
- 数组形式不可使用递增操作;指针形式可以使用递增操作,改变的是指针变量的值,指向字符串的其他位置,但并没有改变字符串数据。
- 数组形式可以通过
ar1[i]=**
来修改字符串;指针形式不能修改字符串。
#include <stdio.h>
#define MSG "apple"
int main(){
char ar[] = MSG;
char *pt = MSG;
printf("address of \"apple\": %p \n", "apple");
printf("address of MSG: %p\n",MSG);
printf("address ar: %p\n", ar);
printf("address pt: %p\n", pt);
return 0;
}
输出为:
address of apple: 0x100000f10
address of MSG: 0x100000f10
address ar: 0x7fff5fbff858
address pt: 0x100000f10