《C和指针》读书笔记(第九章 字符串、字符和字节)(上)

简介: 《C和指针》读书笔记(第九章 字符串、字符和字节)(上)

0 简介

在C语言中,字符串和数组有很多相似之处,且官方提供了很多的库函数可供调用。那么字符串和数组这对姐妹花,究竟有着什么样的亲密关系,而作为我们本期的重点角色,字符串又有何独特之处呢?

C语言并没有显式的字符串数据类型,因为字符串以字符串常量的形式出现或者存储于字符数组中。字符串常量很适用于那些程序不会对它们进行修改的字符串。所有其他字符串都必须存储于字符数组或动态分配的内存中

本篇着重介绍了一些字符串常用的库函数,使大家在不同的情况下去选择最适合的库函数。下面是本文的内容概览

1 字符串基础

字符串就是一串0个多个字符,并且以一个位模式全为0NUL字节结尾。

例如:

char message[] = "hello word";

2 字符串长度

字符串的长度就是字符串所包含的字符个数,并不包括最后一个终止符。这个在面试中会经常考查。

可以通过库函数strlen()来自动计算字符串的长度。

例如:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main()
{
  char message[] = "hello word";
  printf("字符串的长度为:%d\n",strlen(message));
  system("pause");
  return 0;
}

打印输出:

需要注意的是,该函数返回的是无符号数,因此通过该函数比较两个字符串的长度的时候需要格外注意:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main()
{
  char message1[] = "hello word";
  char message2[] = "hello Shanghai";
  //比较方式1 
  if(strlen(message1) >= strlen(message2))
    printf("字符串1更长\n");
  else
    printf("字符串2更长\n");
  //比较方式2 
  if (strlen(message1) - strlen(message2) >= 0)
    printf("字符串1更长\n");
  else
    printf("字符串2更长\n");
  system("pause");
  return 0;
}

打印输出:

因为返回的是无符号数,所以比较方式2中,条件判断的结果永远为真,导致判断结果出现错误。

3 不受限制的字符串函数

所谓的不受限制的字符串函数,是指在使用的时候,不需要指定字符串(实参)的长度,函数即可顺利运行。

3.1 复制字符串

复制字符串在开发中经常会用到,但是在复制到新的字符串中时,会覆盖掉原来的部分,所以需要格外注意。

例如:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main()
{
  char message1[] = "hello word";
  char message2[] = "hello Shanghai";
  int message2_len = strlen(message2);
  printf("字符串2的长度为:%d\n", strlen(message2));
  strcpy(message2,message1);
  printf("字符串2的长度为:%d\n",strlen(message2));
  for(int i = 0; i < message2_len; i++)
    printf("%c",message2[i]);
  system("pause");
  return 0;
}

打印输出:

可以看到,在将字符串message1复制到message2之后,message2的长度居然都不一样了,这是为什么呢?

这是因为,在复制字符串的时候,顺便也将终止符复制了过来,在strlen()函数进行处理的时候,肯定就会返回10,从打印结果来看,message2的其余部分仍然被保留了下来。

而将较长字符串复制到较短的字符串中时,常常会报错,这是因为没有足够的空间去容纳需要复制的字符。

3.2 连接字符串

连接字符串的时候,可以使用strcat()函数。它的原型如下:

char *strcat(char *dst, char const *src);

举个例子:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main()
{
  char message1[] = "hello word";
  char message2[] = "hello Shanghai";
  strcat(message1,message2);
  printf("%s\n", message1);
  system("pause");
  return 0;
}

打印输出:

可以看到,直接将两个字符串进行了拼接。新字符串的长度值是原来两个字符串的长度之和

3.3 函数的返回值

这些函数的返回值有时候是第一个参数的一份拷贝,因此可以嵌套使用,因为当字符串做实参的时候,传递的也是第一个元素的地址。所以这些函数经常可以嵌套地调用。

例如:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main()
{
  char message1[] = "hello ";
  char message2[] = "word ";
  char message3[] = "Shanghai";
  strcat(strcat(message1, message2), message3);
  printf("%s\n", message1);
  system("pause");
  return 0;
}

打印输出:

但是为了程序的可读性,不嵌套也可以。

3.4 字符串比较

字符串比较,常用的库函数只有一个,就是strcmp。它的原型如下:

int  strcmp(char  const  *s1,  char  const  *s2);

这个函数的比较规则比较 有意思,该函数对两个字符串的字符逐个进行比较,直到发现不匹配为止,这里有两种情况:

  1. 最先不匹配的字符中在ASCII中排名靠前的那个字符所在的字符串被认为是较小的字符串;
  2. 如果开始部分的两个字符串都相等,那么较短的字符串被认为是较小的字符串。

字符串发现有不匹配的某个字符,即可得到对比结果,而无须比较剩余部分。

如下图所示:

看看实际的代码:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main()
{
  char temp1[] = "hello";
  char temp2[] = "hello world";
  char temp3[] = "hello worLd";
  //字符串temp1和temp2作比较
  if(strcmp(temp1,temp2) == 0)
  {
    printf("temp1 = temp2\n");
  }
  else if (strcmp(temp1, temp2) > 0)
  {
    printf("temp1 > temp2\n");
  }
  else if (strcmp(temp1, temp2) < 0)
  {
    printf("temp1 < temp2\n");
  }
  printf("------------------\n");
  //字符串temp2和temp3作比较
  if (strcmp(temp2, temp3) == 0)
  {
    printf("temp2 = temp3\n");
  }
  else if (strcmp(temp2, temp3) > 0)
  {
    printf("temp2 > temp3\n");
  }
  else if (strcmp(temp2, temp3) < 0)
  {
    printf("temp2 < temp3\n");
  }
  printf("\n");
  system("pause");
  return 0;
}

打印输出:

相关文章
|
4月前
|
存储 编译器 C语言
函数指针&&数组指针&&数组传参的本质&&字符指针(进阶篇)
函数指针&&数组指针&&数组传参的本质&&字符指针(进阶篇)
105 0
|
4月前
|
存储 C++
使用字符指针变量和字符数组的比较
使用字符指针变量和字符数组的比较
40 0
C4.
|
4月前
|
存储 程序员 C语言
C语言中如何通过指针引用字符串
C语言中如何通过指针引用字符串
C4.
46 0
|
4月前
|
C语言
C语言----字符数组&&指针
C语言----字符数组&&指针
40 0
|
4月前
【每日一题Day301】LC2337移动片段得到字符串 | 双指针 计分
【每日一题Day301】LC2337移动片段得到字符串 | 双指针 计分
41 0
|
4月前
|
算法 C语言
通过指针引用字符串
通过指针引用字符串
46 1
|
10天前
|
存储 人工智能 C语言
C语言程序设计核心详解 第八章 指针超详细讲解_指针变量_二维数组指针_指向字符串指针
本文详细讲解了C语言中的指针,包括指针变量的定义与引用、指向数组及字符串的指针变量等。首先介绍了指针变量的基本概念和定义格式,随后通过多个示例展示了如何使用指针变量来操作普通变量、数组和字符串。文章还深入探讨了指向函数的指针变量以及指针数组的概念,并解释了空指针的意义和使用场景。通过丰富的代码示例和图形化展示,帮助读者更好地理解和掌握C语言中的指针知识。
|
4月前
|
存储 C语言
字符指针变量与字符数组的比较
字符指针变量与字符数组的比较
38 3
|
4月前
|
存储 C语言
字符指针作为函数参数
字符指针作为函数参数
44 2
|
4月前
DAY-2 | 哈希表、指针与区间划分:字符种数统计问题
```markdown ## 题干 [牛客网链接](https://www.nowcoder.com/practice/eb94f6a5b2ba49c6ac72d40b5ce95f50) ## 题解 1. **查表法(哈希表)**:利用数组标记出现过的 ASCII 值小于127的字符,首次出现计数,重复则忽略。 2. **指针与区间划分(回头法)**:遍历字符串,对每个字符检查其前所有字符是否重复,重复则不计数。 ## 方法总结 - 哈希表在去重问题中非常实用,可多做相关练习。 - 使用`continue`时注意避免死循环,确保循环变量会改变。 - 多回顾此类问题以巩固理解。 ```
37 2