第11章 字符串和字符串函数

11.1字符串表示和字符串I/O

11.1.1在程序中定义字符串

字符串定义:

char s[10]="iamaboy!";//这是字符串

char s[]="uareagirl";//这是字符串

char *ps="heishandsome.";  //这是字符串

char s[3]={'A','b','x'};  //这是字符数组,而非字符串

char s[3]={'A','b','x','\0'};  //增加字符串标志符,表示字符串

一、字符串常量

字符串常量属于静态存储类(static storage),是指如果在一个函数中使用字符串常量,即使多次调用了这个函数,该字符串在程序的整个运行过程只存储一份。定义中引号的内容作为指向该字符串存储位置的指针。

例11.2

#include<stdio.h>
int main(void)
{printf("%s,%p,%c\n","We","are",*"student wang");return0;
}
//输出:
//We,内存单元地址编号,s

二、字符串数组及其初始化

const char m[40]="limit yuorself to one line's worth.";

//const表明变量m只读,不可写入。

//这小节想说明啥?字符串数组?标题写错了估计,应该是字符数组。

三、数组和指针

对于:

const char *m3[]="I am chinese.";

char m1[]="I am chinese.";

数组形式m1[]在内存中被分配“实际字符串内字符数量+1(字符串结束标志符)”个元素的数组空间(这里因为数组元素为字符),最后一个数组内存放'\0'。通常,被引用的字符串存储在可执行文件的数据段部分,当程序被加载到内存中时,字符串也被加载到内存中。被引用的字符串位于静态存储区。但是程序运行后才开始为数组分配存储空间,并把静态存储区的字符串数据依次复制到该数组存储区。此后,编译器会把数组名m1看成数组收元素的地址&m1[0]的同义词,即一个地址常量,无法更改。

而指针形式(*m3)也在静态存储区为字符串预留“实际字符串内字符数量+1(字符串结束标志符)”个元素的空间;并且在程序执行后,系统要为变量m3预留一个存储位置,变量m3初始指向静态存储区中字符串的首地址。m3为变量,可改变,如m3+=2;即使得m3指向了字符串第三个字符。另外,对于const char *m3[]...表示的含义是“指针变量m3指向的目标区域内的数值不能被修改”。

//重要的一个知识点

四、数组和指针的差别

对于:

char s1[]="...";

char *s2="...";

s1和s2均可以使用数组符号和指针加法:*(s1+1),s2[3];

区别在于s1如前面所说,为常量,不能改变,如不能进行自增减操作。

而s2是变量,是可以改变的。

五、字符串数组

对于:

const char *p[3]={"ts1","ts22","ts333"};   //定义方法1

//每个数组元素均为指向字符串首地址的指针

//而字符串又类似于一个字符数组,因此字符串数组也类似于二维字符数组,只不过各行的列数未必一致

p[0]="ts1";p[1]="ts22";p[2]="ts333";

*p[0]='t';*p[1]='t';

p[0][0]='t';p[2][2]='3';//这里也可看出与二维数组的类似。

同样也可以用二维数组方式定义字符串数组:

char p[3][6]={"ts1","ts22","ts333"};   //定义方法2

方法1中各行的列数不一致,而这也可以节省存储空间,因为每个字符串内部的字符在内存中连续存放,而各个字符串之间在内存空间中未必是连续的,这不影响逻辑关系上的依序。而方法二用二维数组方式的定义,一方面,各个字符串之间在内存空间里是连续的;另外一方面,为满足列数的一致,对不足的列数要用‘\0'进行填充。

引申:为何两种方式在各个字符串的存储连续与否有区别?回顾前面数组和指针的区别,可以注意到:第一种方法是指针,指针引用的是静态存储区的地址;而数组方法是程序运行到数组定义时候分配一段连续空间以存放该数组,再将静态存储区中的字符串复制。

11.2字符串输入

11.2.1创建存储空间

例:

char *name;

scanf("%s",name);

//上述有问题么?

//有。第一句定义了字符指针变量,但未赋值,未赋值的指针是不能使用的;尽管这两句也许可以通过编译。

//正确方法如下:

char name[81];   //之前说到在程序运行到这句时,系统会给分配81个数组元素空间,一旦分配,即name的地址是确定的。

scanf(“%s”,name);

11.2.2gets()函数

gets()函数的返回值是字符串的地址。

11.2.3fgets()函数

gets()函数不检查预留存储区是否有足够容纳字符串的空间。fgets()提供参数可指定最大读入字符数。

gets()函数读取到换行符时则停止读入,并丢弃换行符。而fgets()结束的标志是指定的读取最大数-1个字符或者读取到换行符则停止,但不丢弃换行符。

gets()函数是针对基本输入文件,即键盘的读入;而fgets()是针对文件的操作。因键盘也是属于文件(基本输入文件),fgets()也可对键盘读入,只是要在第三个参数中明确为stdin(键盘文件);

11.2.4scanf()函数

11.3字符串输出

puts()/fputs()/printf()

11.4自定义输入输出

11.5字符串函数

ANSI C用头文件string.h给出字符串操作库函数:

11.5.1 strlen()

返回值为字符串实际长度,不含结束标识符’\0'。

11.5.2strcat()

将第二个参数指向的字符串加到第一个结尾,返回值为第一个参数,即新字符串的首地址(其实该地址不变)。

11.5.3strncat()

与strcat()功能相同,只是多个参数指定最多添加的字符数量。

strncat(s1,s2,5);//将s2加到s1结尾处,当加了5个字符后或s2已结束后结束。

11.5.4strcmp()

若两相比的字符串完全相同,则返回0;

若依序比较,直到第一对不相同的字符出现时候,若第一个字符串对应字符在ASCII码表中顺序位于第二个字符串对应字符之后(即大于),则返回正数,反之则负数。

11.5.5strncmp()

例:strcmp(s1,s2,int m)  仅针对两字符串中前m个字符进行比较。

*更多字符串函数详见P307-308

转载于:https://www.cnblogs.com/tsembrace/p/3144921.html

C Primer+Plus(十一)相关推荐

  1. C++primer第十一章 关联容器 11.3关联容器操作 11.4 无序容器

    11.3关联容器操作 除了表9.2(第295页)中列出的类型,关联容器还定义了表11.3中列出的类型.这些类型表示容器关键字和值的类型. 对于set类型,key_type和value type是一样的 ...

  2. C++primer第十一章 关联容器 11.1使用关联容器 11.2 关联容器概述

    关联容器和顺序容器有着根本的不同:关联容器中的元素是按关键字来保存和访问的.与之相对,顺序容器中的元素是按它们在容器中的位置来顺序保存和访问的. 虽然关联容器的很多行为与顺序容器相同,但其不同之处反映 ...

  3. C++Primer第五版——习题答案+详解(完整版)

     C++Primer第五版--习题答案详解 新手入门必看的书.知识是一个系统化并且相互关联的体系,零散的东西每天收获如果不形成自己的体系的话,那将是毫无意义的,所以我觉得有必要将这本书先啃一遍,消化其 ...

  4. C++ Primer读书摘要(二)

    C++ Primer 第八章 标准IO库 学习本章内容之前有必要对缓冲区的概念做一个基本了解,我引用了网上一片文章<C++编程对缓冲区的理解>,内容如下: 什么是缓冲区    缓冲区又称为 ...

  5. C primer plus(第六版)第十一章源代码

    C primer plus(第六版)第十一章源代码 /* 11.1 */ #include<stdio.h> #define MSG "I am a symbolic strin ...

  6. 【c++primer第五版】第十一章习题答案

    第十一章 关联容器 练习11.1 描述map和vector的不同. 解: 顺序容器中的元素是"顺序"存储的,对于vector,元素在其中按顺序存储,每个元素都有唯一对应 的位置编号 ...

  7. C++ Primer Plus(十一)—— 使用类

    为什么80%的码农都做不了架构师?>>>    不要返回指向局部变量或临时对象的引用,函数执行完毕后,局部变量和临时对象都将消失,引用将指向不存在的数据. C++对用户定义的运算符重 ...

  8. 记录——《C Primer Plus (第五版)》第十一章编程练习第5-12题

    5.编写一个函数is_within(),它接受两个参数,一个是字符,另一个是字符串指针.其功能是如果字符在字符串中,就返回一个非0值(真):如果字符不在字符串中,就返回0值(假).在一个使用循环语句为 ...

  9. 记录——《C Primer Plus (第五版)》第十一章编程练习第四题

    4.设计并测试一个函数,其功能是搜索由函数的第一个参数指定的字符串,在其中查找由函数的第二 个参数指定的字符的第一次出现的位置.如果找到,返回指向这个字符的指针,如果没有找到,返回 空字符(这种方式和 ...

最新文章

  1. hdu1412 {A} + {B}(TreeSet和Iterator的使用)
  2. Word2007 设置Tab键的默认缩进距离
  3. Oracle下scott用户无法登录
  4. java多线程绘图_菜鸟学Java之 Java2D 多线程绘图
  5. 小米android系统耗电量大,小米手机耗电快的解决方法,亲测有效~
  6. 【转】.NET平台开发Mongo基础知识
  7. java 控制 sortedset_Java集合的checkedSortedSet()方法和示例
  8. 解决 IntelliJ IDEA 读取不了 datasource.properties
  9. windows下SVN日志反馈中文乱码的解决方法
  10. Oracle11g数据库审计功能的关闭和开启
  11. 如何在PHP中使用cURL连接到Tor隐藏服务?
  12. 基于SSM的社区消毒防疫物资系统
  13. 激光打标机不能刻字的处理
  14. SnapGene如何设计sgRNA,构建载体,对靶基因进行敲除
  15. kotlin-android-extensions过时了,迁移到ViewBinding
  16. 我们公司使用了 5 年的系统限流方案 ,从实现到部署实战详解,稳的一B
  17. 全新安装Windows10系统(PE下)
  18. 使用PADS绘制排线的细节笔记
  19. html5播放加速,html5倍速播放插件
  20. 区块链NFT之OpenSea

热门文章

  1. mysql存储过程或函数中传入参数与表字段名相同引发的悲剧
  2. #tomcat#生成的jsp转换问题
  3. Vue.js项目构建
  4. java.math.BigDecimal()的用法
  5. spring各种邮件发送
  6. dfs-Rank the Languages
  7. 解释型语言与编译型语言的区别
  8. 视频直播技术详解(5)延迟优化
  9. 深度学习——你需要了解的八大开源框架
  10. 更新词汇至Unigram词表进行识别