C语言_9 字符串

简介: 是翁恺老师的132p C语言程序设计网课。

10.1.1 字符串

char word[]={'H','e','l','l','o','!'};

得到的字符数组应该是这样子的

word[0] H
word[1] e
word[2] l
word[3] l
word[4] o
word[5] !

不过这只是字符数组而不是字符串。因为他不能用字符串的方式做运算。
定义一个C语言的字符串,结尾要加上word[6]='\0'。
对C语言来说,字符串就是以0(整数0)结尾的一串字符数组。
0和'\0'是一样的,但是和'0'不同。0标志着字符串的结束,但他自己不是字符串的一部分,计算字符串长度的时候不包含这个0。
字符串以数组的形式存在,以数组或指针的形式访问(更多以指针的形式)
PS:string.h里有很多处理字符串的函数。

char *str="Hello";//一个指针指向了一个字符数组
char word[]="Hello";//字符数组,结尾0
char line[10]="Hello";//字符数组,结尾0

字符串常量
"Hello"双引号括起来的叫做字符串的字面量/常量,我们在scanf和printf里已经见过很多次了。"Hello"会被编译器变成一个(长度为6的)字符数组放在某处,结尾自动添上个0。
两个相邻的字符串常量会被自动连接起来。
比如printf里出现连续两个" " " ",会接起来输出。

printf("123456789"
"10111213");

另一种连接方法:

printf("123456789\
10111213");

会输出12345678910111213,回车可以用反斜杠的方式搞定。不过这种方法连换行开头的Tab也会输出,要小心使用。
人的眼睛横向是有极限的hh。所以程序员喜欢把显示器转过来
C语言的字符串是以字符数组的形态存在的,因为是个数组,所以不能用运算符对字符串做运算。但可以通过数组的方式遍历字符串。(后面会有很多应用)
字符串唯一特殊的地方是字符串字面量可以用来初始化字符数组。

10.1.2 字符串变量

char *s="Hello";
s[0]='B';//尝试把H替换为B,然后输出s[0]

编译无问题,但是运行时没法输出s[0],出错了。
再做另一个尝试

int i=0;
char *s="Hello";
char*s1="Hello";//两个一样的字符串变量
printf("i的地址是%p\n",&i);
printf("s的地址是%p\n",s);
printf("s1的地址是%p\n",s1);

比较得到的地址结果我们可以得出的结论:

1.i的地址相对很大,s和s1的地址相对很小。
2.s和s1的指向了同一个地址。

其实s和s1指向的地址是程序的代码端,他是只读的
因此,实际上s是const char*s;由于历史的原因,编译器接受不带const的写法(所以编译通过了)。但试图对s所指的字符串做写入会导致严重的后果。
如果需要修改字符串,应该用数组:

char s[]="Hello!";

尝试输出s的地址会发现,s的地址和上例中的i的地址一样较大(也就是说在本地变量那里),而且s可以修改。
需要使用字符串的时候,我们要把它写成指针的形式还是数组的形式呢?
数组:

  1. 字符串有确定的地址;
  2. 作为本地变量,空间会自动被回收。

指针:这个字符串不知道在哪;所以通常用来

  1. 只读的,不可写的字符串
  2. 处理函数的参数(前面知道如果数组作为指针,函数的参数实际上和指针是一样的);
  3. 动态分配空间malloc。

因此,如果要构造一个字符串:数组
如果要处理一个字符串:指针。

因此,字符串可以表示为char*的形式,而char*不一定是字符串。
他可能是指向字符的指针,可能指向的是字符的数组。只有当char*所指的字符数组有结尾的0,才能说他所指的是字符串。

10.1.3 字符串输入输出

所以字符串的地位如此。尽管相较之前的语言,C语言有很多处理字符串的方法,但比起现在的新语言,C语言对字符串的处理还是不足。

char *t="title";
char *s;
s=t;

只是让指针s指向指针t所指的字符串,并没有产生新的字符串。
至于如何真的复制一个字符串给s,等到以后字符串函数会学到的。
字符串的输入输出:%s

char string[8];
scanf("%s",string);
printf("%s",string);

输入不再是简单的整数、一个字符,这时候,我们就要考虑下scanf的停止条件了。
scanf()只能读入一个单词,因为碰到空格、tab键或回车就会终止。空格、回车是分隔符,是用来分隔两个单词的。
如果用这种方法读入两个单词可以连续两次scanf:

scanf("%s",str1);
scanf("%s",str2);
printf("%s%s",str1,str2);

空格不会被读入,输出是没有中间的分隔符(空格)的。
scanf()是不安全的,因为不知道读入的长度。

char str1[8],str2[8];
scanf("%s",str1);
scanf("%s",str2);

输入12345678 12345678,结果第一个字符串为空,第二个字符串却是12345678读了八个字符。(运气好没有崩溃)
为什么?涉及到在内存中是怎么排列的。
安全的方法:scanf("%7s%7s",str,str1);意思是:最多只能读七个字符。多出的部分会分配给下一个字符串。
这样输入12345678,8就会分配给下一个字符串。
加入的这个数字,最多应该比定义字符串的个数小1( 比如上例最多为7)
C语言中常见的错误:误以为char*就是定义了字符串类型。其实是一个需要初始化的指针。不初始化可能会出错。(可能会出现:程序在一个地方没问题,到了其他地方就出错了)

char zero[100]="";

空的字符串,zero[0]='\0',不过仍然是有效的字符串。
但是如果写成:char zero[]="";长度就是1了。

10.1.4 字符串数组,以及程序参数

如果我们想写一个数组来表示很多个字符串?
char **a:a是个指针,指向另一个指针,另一个指针指向一个字符串
char a[][]:a是个二维数组的变量,第二维(后面的括号)一定要有确定的大小,否则编译不能通过。

char a[][10]={
    "hello",
    "world"
};//每个字符串长度不要超过n,即10

还有一种写法:char *a[],a[0]相当于char*,像矩阵的排列方法想的话,a[i]就是指向每一行的字符串的指针。
这和二维数组不一样,二维数组a[0]就是第一行的字符串。
填坑:以前做的一道题:输入数字月份,输出对应的月份英文单词。现在可以用数组做。
现在回归到int main()主函数,之前说过括号里面什么都不用写,要写也就写个void
其实里面是是int main(int argc,char const*argv[])
argc告诉我们,后面的数组有多少个字符串。
然后我们试着输出后面字符串的内容

for(i=0;i<argc;i++){
    printf("%d:%s\n",i,argv[i]);
}

然后./a.out运行,只输出了0:./a.out
第二次输入./a.out 123,输出了
`0:./a.out
1:123`
然后随便输入,./a.out 123 asd asd asd asd这些字符串都会被一个个记录下来。
它从第2个字符串开始记录所有你输入的字符串,而第一个参数,即argv[0],则是输入的这个文件的名字(./a.out)即可执行程序的名字。
如果将a.out 称之为my,ln -s a.out my ,然后我们看my,ls -l my 发现my是个指向a.out 的链接。如果执行my ./my 123 输出的字符串argv[0]也是./my而不是./a.out了。
关于到底是怎样运行程序的,建议搜索busybox,看看别的box是怎么做的。(蒙……)等做快捷方式的时候会更理解。

目录
相关文章
|
3月前
|
NoSQL 程序员 Redis
C语言字符串的设计缺陷
C语言字符串的设计缺陷
38 1
|
5天前
|
存储 C语言
【C语言基础考研向】10 字符数组初始化及传递和scanf 读取字符串
本文介绍了C语言中字符数组的初始化方法及其在函数间传递的注意事项。字符数组初始化有两种方式:逐个字符赋值或整体初始化字符串。实际工作中常用后者,如`char c[10]=&quot;hello&quot;`。示例代码展示了如何初始化及传递字符数组,并解释了为何未正确添加结束符`\0`会导致乱码。此外,还讨论了`scanf`函数读取字符串时忽略空格和回车的特点。
|
5天前
|
存储 Serverless C语言
【C语言基础考研向】11 gets函数与puts函数及str系列字符串操作函数
本文介绍了C语言中的`gets`和`puts`函数,`gets`用于从标准输入读取字符串直至换行符,并自动添加字符串结束标志`\0`。`puts`则用于向标准输出打印字符串并自动换行。此外,文章还详细讲解了`str`系列字符串操作函数,包括统计字符串长度的`strlen`、复制字符串的`strcpy`、比较字符串的`strcmp`以及拼接字符串的`strcat`。通过示例代码展示了这些函数的具体应用及注意事项。
|
8天前
|
存储 人工智能 C语言
C语言程序设计核心详解 第八章 指针超详细讲解_指针变量_二维数组指针_指向字符串指针
本文详细讲解了C语言中的指针,包括指针变量的定义与引用、指向数组及字符串的指针变量等。首先介绍了指针变量的基本概念和定义格式,随后通过多个示例展示了如何使用指针变量来操作普通变量、数组和字符串。文章还深入探讨了指向函数的指针变量以及指针数组的概念,并解释了空指针的意义和使用场景。通过丰富的代码示例和图形化展示,帮助读者更好地理解和掌握C语言中的指针知识。
|
13天前
|
C语言
C语言 字符串操作函数
本文档详细介绍了多个常用的字符串操作函数,包括 `strlen`、`strcpy`、`strncpy`、`strcat`、`strncat`、`strcmp`、`strncpy`、`sprintf`、`itoa`、`strchr`、`strspn`、`strcspn`、`strstr` 和 `strtok`。每个函数均提供了语法说明、参数解释、返回值描述及示例代码。此外,还给出了部分函数的自实现版本,帮助读者深入理解其工作原理。通过这些函数,可以轻松地进行字符串长度计算、复制、连接、比较等操作。
|
29天前
|
C语言
【C语言】字符串及其函数速览
【C语言】字符串及其函数速览
22 4
|
29天前
|
C语言
【C语言篇】字符和字符串以及内存函数详细介绍与模拟实现(下篇)
perror函数打印完参数部分的字符串后,再打印⼀个冒号和⼀个空格,再打印错误信息。
|
29天前
|
存储 安全 编译器
【C语言篇】字符和字符串以及内存函数的详细介绍与模拟实现(上篇)
当然可以用scanf和printf输入输出,这里在之前【C语言篇】scanf和printf万字超详细介绍(基本加拓展用法)已经讲过了,这里就不再赘述,主要介绍只针对字符的函数.
|
3月前
|
C语言
C语言学习笔记之初识字符串
C语言学习笔记之初识字符串
35 5
|
3月前
|
C语言
c语言左旋字符串问题(不同方法超详细解答)
c语言左旋字符串问题(不同方法超详细解答)
21 1