AL控制组——C语言字符串笔记

说明:笔记内容是观看翁恺老师的C语言课程视频中记录的,笔记内容有部分来自于原文内容,有部分来自于自身的思考实验。

以下排列顺序以一个视频为一个片段(内容比较多,可能不适合喜欢快餐方式的朋友):

根据测试,目录有时可能没法跳转准确(可能是因为内容太多的原因,可以考虑用左下方侧的目录跳转)

目录

一、字符串

字符数组

字符串

特性:

定义变量及初始化;

其中两个相邻的字符串常量会自动连接起来(两种连接方法)

二、字符串变量

指针形式定义字符串变量:

数组形式定义字符串变量:

总结:

三、字符串输入输出

四、字符串数组,以及程序参数

五、单字符输入输出

putchar

getchar

部分指令:

六、字符串函数

strlen

使用方法:

其中也可自己定义一个与strlen函数作用相同的函数。

strcmp

同样的,也可自己写出一个与strcmp函数作用相同的函数。(如果想更改返回值为-1、0、1的话,只需要在最后加入判断并返回即可)

strcpy

同样,也可制作类似效果的函数。(仅制作简单的拷贝字符串)

strcat

同样的,也可制作具有类似效果的函数。

strcpy的安全版本:

strcat的安全版本:

strcmp也有带n版本,但目的不为了安全,为了减少判断数

strchr和strrchr

套路一:寻找第二甚至其他地方的字符位置时,可以将第一个字符返回值加一。

套路二:进行拷贝字符串的部分内容时,可以通过改变其中字符为’\0’,最后恢复回去。

strstr与strcasestr

strstr

strcasestr


一、字符串

字符数组

 

不是C语言的字符串,因为不能像字符串方式做运算。

字符串

 

与字符数组的区别:结尾有’\0’使得它成为在C语言中可以使用字符串的运算方式进行运算。(其中’\0’可替换为0,但是不可用’0’,因为后者是一个字符)

特性:

  • 0标志字符串的结束,但不属于字符串的一部分;
  • 计算字符串长度的时候不包括0;
  • 字符串以数组形式存在,但以数组和指针形式访问(后者居多);
  • string.h里有很多处理字符串的函数(用法:加入include<string.h>在代码头上);
  • 不能用运算符对字符串做运算(其他一些语言可以,例如用+号连接两个字符串);
  • 可通过数组方式遍历字符串;
  • 唯一特殊点在可以用字符串字面量初始化字符数组;

定义变量及初始化;

 

其中里面的内容代表字符串的字面量(或者叫字符串常量),最终结尾会有’/0’存在,但不可见。 

 

 

其中两个相邻的字符串常量会自动连接起来(两种连接方法)

法一:

 

此时前后两个里面内容会合并为一个内容,如: 

 

法二:

 

此时会将第二行的内容接上第一行,但会从起始点位置接收所有内容,如:

 

二、字符串变量

指针形式定义字符串变量:

如果字符串变量定义时,以指针形式定义,将会变成只读的形式,此时对字符串里面的内容做修改,编译器会出错。

如:

 

这一段的代码会使编译器出问题,出现报错或者无法正常输出值。

原因:char *a实际上是从const  char *a,但是由于历史原因,编译器接受不带const,

但试图写入仍会出错。

当两个指针字符串字面量相同时,它们地址相同,均指向同一片地方。

如:

 

 

数组形式定义字符串变量:

如果以数组形式定义,那么字符串将可以改变其中值。

如:

 

总结:

构造字符串—>数组

①作为本地变量空间自动被回收;

②知道字符串位置。

处理字符串—>指针

①不知道字符串位置;

②处理函数参数时;

③用malloc动态分配空间时。

三、字符串输入输出

①scanf读入字符串时(到空格、tab或回车为止),存在局限。

解法:可利用如gets( )来读入字符串,此时仅当回车时结束读取,并用puts( )输出。

②scanf在读取字符串时,因为没规定上界,可能会导致读取内容超过字符串数组存储空间,存在危险。(虽然一时没事,但之后一定会出问题)

解法:可在%s读取时,在%与s间加入数组长度减一的数字,限制读取个数。

  如:

③对字符串变量使用前,要做初始化。

如:

 

这个字符串为空字符串,。 

因此,对于,该数组长度仅为1,且。 

 

四、字符串数组,以及程序参数

字符串数组几种定义方式:

1.char **a指的是定义时a为一个指针,指向另一个指针,那个指针指向一个字符(串)。

因此它无法做到储存多个字符串。

2.char a[ ][ ]代表a是一个二维数组,而在数组定义里面,必须给出列数。

例:a[ ][10]的储存

 

如图,第三行的字符串显然超出了数组的储存列数,会使得编译出错或存在危险。

因此它无法做到储存不定上限长度的字符串。

3.char *a[ ]代表a为一个数组,数组里每一个单元都是指针,指向一片空间。

如:

 

此时可以做到储存未知字节数的字符串(不超过计算机内部最大储存空间情况下)。

因此它可以做到储存多个不定上限长度的字符串。

用途之一:

 

完善之前月份英语的代码,使其变为单一出口,增加安全性。

程序参数:

 

main的函数括号里面的内容,便是它的程序参数。

其中argv[0]是命令本身。

在windows运行时:

 

运行结果:

 

因此在Windows运行时显示的是其目录名。

在Unix中,当使用Unix的符号链接时,反映符号链接的名字。

例如,可以在输入a.out之后,接入my,此时my相当于是a.out的一个快捷方式,其指向的便是a.out。(感兴趣的可以搜busybox查找)

五、单字符输入输出

putchar

形式:int putchar(int c);

作用:像标准输出写入一个字符。

返回类型:返回写了几个字符,EOF(-1)表示写失败。//根据视频描述

Ps:在自己试验时,发现putchar返回值实际是第一个字符的Ascll码(%d方式输出,且写成功情况下)。

下面为测试代码:

 

运行结果:

 

根据查询Ascll码表,发现h对于的值正好为104。

后面根据查询结果,根据试验后发现printf函数的返回值,才是返回的字符数(且一个汉字对应两个字符数)

下面为测试代码:

 

运行结果:

 

getchar

形式:int getchar(void);

作用:从标准输入读一个字符。

返回类型:int,作用是为了返回EOF(-1)。

部分指令:

一、

Windows—>Ctrl + Z

Unix—>Ctrl + D

上面二者方式均为输入EOF(-1)

二、

Ctrl + C指令表示强制关闭程序。

运行原理:

 

其中shell相当于一个中间商,将电脑输入的东西进行处理转换。

例如:

1.当我们输入Ctrl + D(或Z)时,shell会将该指令接受,并给行编辑填入EOF或-1(不同的电脑系统,对于shell填入不一样)。

2.对于填入的多个字符,如123,每次getchar只会读取一个字符交给putchar,但是剩下的字符会留在缓冲区等待下一次输出,直到缓冲区没有下一个字符读取时,才开始下一次读入输出。

六、字符串函数

strlen

形式:size_t strlen(const char *s);

作用:返回s的字符串长度(不包括结尾的0)。

使用方法:

法一:(利用变量储存长度)

 

法二:(直接输出长度)

其中也可自己定义一个与strlen函数作用相同的函数。

如:

strcmp

形式:int strcmp(const char *s1,const char *s2);

作用:比较两个字符串,返回:

  0:s1==s2

  1:s1>s2

  -1:s1<s2

作用原理:

 

在字符串数组s1与s2里,前三个的字符相等,第四个字符的Ascll值,l<m,因此返回值为-1(尽管第五个字符o>m,且s1的字符和的Ascll码值大于s2,依然返回为-1)。

Ps:不同的电脑处理器,对应的返回值可能不一样,例如视频中翁恺老师演示的返回值为二者Ascll码差值,而本人试验后发现返回值依然为1,0,-1这三个数字,具体原因与编译器处理有关。)

同样的,也可自己写出一个与strcmp函数作用相同的函数。(如果想更改返回值为-1、0、1的话,只需要在最后加入判断并返回即可)

如:

法一:(利用数组形式)

 

法二:(利用指针形式)

strcpy

形式:char *strcpy (char *restrict dst , const char *restrict src);

  (其中restrict表示src与dst不重叠( C99里的关键词))

  (为了避免掩盖dst的内容,从而提高运行效率(与多核线程有关))

作用:1、把src的字符串拷贝到dst中;

           2、为了能链起代码。

返回值:返回dst。(以便将结果用于继续做其他运算)

同样,也可制作类似效果的函数。(仅制作简单的拷贝字符串)

如:

法一:(利用数组形式)

 

法二:(利用指针形式)

 

精简版:(最终编译效果可能一样)

strcat

形式:char *strcat (char *restrict s1,const char *restrict s2);

作用:把s2拷贝到s1后面,接成一个长的字符串。

返回值:返回s1。

条件:s1必须有足够空间。

同样的,也可制作具有类似效果的函数。

如:

但使用strcpy跟strcat时,可能出现安全问题,如无空间时会出现越界。因此尽量使用安全版本。

strcpy的安全版本:

strncpy

形式:char *strncpy (char *restrict dst ,const char *restrict src ,size_t n);

其中n代表最多拷贝的上限。

strcat的安全版本:

strncat

形式:char *strncat (char *restrict s1,const char *restrict s2,size_t n);

其中n同样代表最多拷贝的上限。

strcmp也有带n版本,但目的不为了安全,为了减少判断数

 strncmp

 形式:int strncmp (const char *s1,const char *s2,size_t n);

 其中n代表只判断前n个。

strchr和strrchr

strchr

形式:char *strchr (const char *s,int c);

作用:在s中从左往右找c所在的位置。

返回:如果存在,返回指针(指向该字符地址);如果没有,返回NULL。

strrchr

形式:char *strrchr (const char *s,int c);

作用:在s中从右往左找c所在的位置。

返回:如果存在,返回指针(指向该字符地址);如果没有,返回NULL。

二者区别仅在于从左开始还是从右开始。

套路一:寻找第二甚至其他地方的字符位置时,可以将第一个字符返回值加一。

如:

 

此时最后一个p对应的地址便是第二个l的地址。

套路二:进行拷贝字符串的部分内容时,可以通过改变其中字符为’\0’,最后恢复回去。

如:

 

其中利用C来储存原先的字符,最后在还原回去即可。

strstr与strcasestr

strstr

形式:char *strstr (const char *s1,const char *s2);

作用:在字符串s1中里找一个字符串s2。

strcasestr

形式:char *strcasestr (const char *s1,const char *s2);

作用:寻找字符串时,忽略大小写(其他作用与strstr相同)。

  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值