[关闭]
@xudongh 2016-11-13T22:17:02.000000Z 字数 1641 阅读 1485

字符串和字符串函数

计算机


C库提供大量的函数用于读写字符串、拷贝字符串、比较字符串、合并字符串、查找字符串等。


字符串是以空字符(\0)结尾的char类型数组。

puts()函数只显示字符串,而且自动在显示的字符串末尾加上换行符。


字符串字面量(字符串常量)
用双引号括起来的内容称为字符串字面量,也叫作字符串常量。


字符串常量属于静态存储类别,这说明如果在函数中使用字符串常量,该字符串只会被储存一次,在整个程序的生命期内存在,及时函数被调用多次。用双引号括起来的内容被视为指向该字符串储存位置的指针,这类似于把数组名作为指向该数组位置的指针。


在制定数组大小时,要确保数组的元素个数至少比字符串长度多1(为了容纳空字符)。所有未被使用的元素都被自动初始化为0(这里的0指的是char形式的空字符,不是数字字符0)。

  1. const char pets[10] = "nice cat.";

如果省略数组初始化声明中的大小,编译器会自动计算数组的大小。

  1. const char pets[] = "nice cat.";

让编译器计算数组的大小只能用在初始化数组是,如果创建一个稍后再填充的数组,就必须在声明是时指定大小。


字符数组名和其他数组名一样,是该数组首元素的地址,因此,对于以下初始化:

  1. char car[10] = "Tata";

那么,以下表达式都为真:

  1. car == &car[0];
  2. *car == 'T';
  3. *(car+1) == car[1] == 'a';

还可以使用指针表示法创建字符串:

  1. const char * pt1 = "this is a array.";

该声明和下面的数组表示法声明几乎相同:

  1. 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的值。

初始化数组把静态存储区的字符串拷贝到数组中,而初始化指针只把字符串的地址拷贝给指针。

二者的区别

  1. 数组形式拷贝字符串副本到数组;指针形式是把字符串的地址拷贝到指针变量。
  2. 数组形式不可使用递增操作;指针形式可以使用递增操作,改变的是指针变量的值,指向字符串的其他位置,但并没有改变字符串数据。
  3. 数组形式可以通过ar1[i]=**来修改字符串;指针形式不能修改字符串。
  1. #include <stdio.h>
  2. #define MSG "apple"
  3. int main(){
  4. char ar[] = MSG;
  5. char *pt = MSG;
  6. printf("address of \"apple\": %p \n", "apple");
  7. printf("address of MSG: %p\n",MSG);
  8. printf("address ar: %p\n", ar);
  9. printf("address pt: %p\n", pt);
  10. return 0;
  11. }

输出为:

  1. address of apple: 0x100000f10
  2. address of MSG: 0x100000f10
  3. address ar: 0x7fff5fbff858
  4. address pt: 0x100000f10
添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注