程序设计与C语言引论笔记——字符数组与字符串

程序设计与C语言引论笔记——字符数组与字符串,第1张

程序设计与C语言引论笔记——字符数组字符串 字符数组与字符串 字符串字面量

C语言规定了字符串字面量的描述方式:用一对双引号括起的任意字符序列就是一个字符串(字面量)。

这里唯一的限制是一个字符串不能跨越两行。如果顺序写出多个字符串,他们之间仅由空白字符分隔,这些字符串将被编译程序连接在一起,形成一个长的字符串。

printf("In 1983," " the American National Standards " 
 "Institute (ANSI) established a committee whose " 
 "goal was to produce "an unambiguous and machine-" 
 "independent definition of the language C," while " 
 "still retaining its spirit." "The result is the " 
 "ANSI standard for C."); 

在一个字符串里面不能直接出现双引号,因为这将被认为是字符串的结束。读者可以看到,在上面的例子里双引号用转义序列“"” 表示

字符数组

字符数组就是以字符作为元素的数组。由于人们常用 C 语言写与处理字符序列或文本的程序,而字符序列理所当然地应该存放在字符数组中,所以C为处理字符数组提供了特别支持。

对于程序中写出的字符串字面量,系统将用字符数组的形式对其进行存储他们:分配连续的若干个存储单元,顺序存入字符串中的各个字符,每个字符占据一个字节。在存储了字符串常量的所有字符之后,还要另外存一个空字符 '’作为字符串的结束标志。

例如下面的字符串虽然只有7个字符,其内部却要占据8个字节的存储。

用这种方式表示字符串是为了处理方便。字符串数据与基本类型的数据不同,不同的字符串可能有不同长度。这种情况下,程序怎么才能从字符串的内部表示确定字符串结束的位置呢?

有了字符串末尾的空字符,处理字符串的程序就可以顺序检查,遇到空字符就知道遇到了字符串结束。虽然空字符不是字符串内容的一部分, 但却是字符串表示中不可缺少的部分。

标准库的字符串处理函数都是基于这种表示定义的, 我们自己写字符串处理程序时也应该遵守这种规则。

下面的问题是:能在自己定义的字符数组里存放字符串吗?回答是肯定的,根据字符串存储形式的规定,只要在数组里顺序存入所需字符,随后存一个空字符,这个字符数组里的数据就有了字符串的表现形式,这个数组也就可以当作字符串使用了。在这种情况下,人们也说这个数组里存了一个字符串。例如有下面定义:

char a[5] = {'i', 's', 'n', 'o', 't'}, //数组a里存的不是字符串,因为缺少表示串结束的空字符。

 b[5] = {'g', 'o', 'o', 'd'}, 
 
 
 c[5] = {'f', 'i', 'n', 'e', ''}, //c 初始化时已在有效字符后加了一个空字符,所以它也存了一个字符串。
 
 d[5] = {'o', 'k', ''}; //数组 d 最后两个字符未给,同数组b一样,将自动设为空字符,对d作为字符串没有影响。
 
 e[5] = {'o', 'k', '', '?', '?'};
 

为了方便使用,C 语言为字符数组提供了特殊的初始化形式:允许以字符串形式为字符数组的一系列元素指定初值。这种初始化形式应看成一般形式的简写,例如可以写:

char a1[20] = "Peking University";


char a3[] = "Peking University"; 
//这定义了一个 18 个元素的数组,其中依次存放各字符,最后元素存入一个空字符。

如a [3],用字符串做字符数组初始化时也允许不直接给出数组元素个数。这时的数组大小规定为初始化字符串的字符数加 1,因为需要在数组最后存一个空字符。

字符数组可以用在各种需要字符串的地方。例如,如果程序里许多输出语句都用同样输出格式,一种可能方法就是定义一个公用的格式描述数组。例如下面例子:

 char outform1[] = "Two reals: %f, %fn";   
 printf(outform1, x, y);  

这样可以减少重复定义。对输入格式也可以采用同样技术。

字典序

简单地说,字典序就是普通英语词典里排列单词词条时所用的顺序。

字符串字典序的定义是:逐个比较两个串中对应的字符,字符大小按照字符编码(作为一个整数)大小确定。从左向右比较,

  1. 如果遇到不同字符,所遇第一对不同字母的大小关系就确定了两个字符串的大小关系;
  2. 如果未遇到不同字符而某个字符串首先结束,那么这个字符串是较小的;
  3. 否则,两个字符串相等
程序实例

例 1(字符串复制),写一个函数,将一个字符串复制到一个字符数组里(同样做成字符串) 的工作。

这里有个隐含条件:假定复制用的字符串数组足够大,足以存放被复制字符和空字符。

void str_copy (char s[], const char t[]) { //t 用 const 标记是想了把函数中不修改它的事实表示清楚
 int i = 0; 
 while (s[i] = t[i]) ++i; 
 
} 

例 2(二进制转换),写一个函数,给它一个表示二进制数的 0/1 字符串,它计算出这个串所表示的整数值。

函数中的计算很简单,二进制数 bnbn-1…b2b1b0的值可以用下面方式计算(与前面计算多 项式值的方式同出一辙):(((…((bn×2) +bn-1)×2 +…)×2 + b2)×2 + b1)×2 + b0,据此可以直接写出一个循环,循环条件判断二进制数是否结束。由于二进制数的各个位只能是 0 和 1, 只要在遇到 1 时加一就可以了 .

int bin2int(const char s[]) { 
//将这一函数命名为 bin2int,这里取 2 的英文为 two(作为 to 的谐音,这种命名方式很常见)。
//由于假定字符数组里保存的是字符串,可以利用空字符判断结束,因此不必知道数组长度。
 int i, n = 0; 
 for (i = 0; s[i] != '' && (s[i] == '0' || s[i] == '1'); ++i) //
     n = n * 2 + (s[i] - '0'); 
 return n; 
} 
标准库字符串处理函数

字符串是 C 程序的重要处理对象,标准库提供了许多与此有关的函数,这些函数的原型在头文件 string.h 里说明。要使用标准字符串处理函数,程序前部应写:

#include

下面介绍几个最常用的函数

  1. 字符串长度函数strlen(const char s[])。本函数求出字符串的长度,也就是字 符串里的字符个数。在计算字符个数时不计表示字符串结束的空字符。参数说明前面加 了 const 修饰符说明函数执行中不会修改参数

  2. 字符串复制函数strcpy(char s[], const char t[])。本函数与前面定义 str_copy 类似。第二个实参的应是字符串。strcpy 把字符串 t 复制到 s,s 应是一 个足够大的字符数组,以保证字符串复制不越界。

    标准库还提供了一个字符串限界复制函数 strncpy,使用形式与 strcpy 类似,增加 了第三个 int 类型的限界参数,用于限制复制的最大长度。字符串复制完毕或者达到限界长度时复制工作结束。

  3. 字符串比较函数int strcmp(const char s1[], const char s2[])。在两个 字符串 s1 和 s2 相同时返回 0;字符串 s1 大于字符串 s2 时返回一个正值(并没有规 定采用什么值),否则就返回负值。判断字符串大小的标准是字典序。

    标准库还提供了一个限界比较函数,它只在给定范围内判断字符串的大小: int strncmp(const char s1[], const char s2[], int n); 返回值的规定与 strcmp 相同.

  4. 字符串连接函数strcat(char s[], const char t[])。第二个实参应当是一个字符串,对应第一个参数 s 的实参应是一个存放着字符串的字符数组。strcat 把作为第二个实参的字符串复制到这个实参字符数组中已有字符的后面,形成相当于两个串 连在一起的字符串。这里也要求第一个实参数组足够大,使复制工作能合法完成。

    标准库里还提供了一个限界连接函数 strncat。

参考书籍

《从问题到程序——程序设计与C语言引论》裘宗燕著,北京大学出版社,1999.4

《从问题到程序——程序设计与C语言引论》2003,2004年修订

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/zaji/4951429.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-11-13
下一篇 2022-11-13

发表评论

登录后才能评论

评论列表(0条)

保存