【C进阶】-- 字符串函数(1)(上)

简介: 【C进阶】-- 字符串函数(1)(上)

0. 前言


这篇文章是关于strlen,strcpy,strcat,strcmp,strncpy,strncat,strncmp,strstr的知识点总结,花了不少精力与时间,文章整体超过一万字,可以用来快速查找字符串函数的功能和实现

C语言中对字符和字符串的处理很是频繁,但是C语言本身是没有字符串类型的,字符串通常放在

常量字符串中或者字符数组中。

字符串常量适用于那些对它不做修改的字符串函数


1. 函数介绍


1.1 strlen

size_t strlen ( const char * str );

0d19d1067447495586fe2b045eff7166.png

字符串末尾是隐藏着一个'\0'的

#include<stdio.h>
#include<string.h>
int main()
{
  char arr1[] = "abcdef";
  int len1 = strlen(arr1);
  printf("%d\n", len1);
  return 0;
}


2fb20ffb655e4b5580bc154519a670a1.png

1.1.1主动改变'\0'的位置

#include<stdio.h>
#include<string.h>
int main()
{
  char arr1[] = "abc\0def";
  int len1 = strlen(arr1);
  printf("%d\n", len1);
  return 0;
}


6d8cf196396b43a7834d75c63b21bebf.png

  • 字符串已经 '\0' 作为结束标志,strlen函数返回的是在字符串中 '\0' 前面出现的字符个数(不包 '\0' )

不知道'\0'的位置

#include<stdio.h>
#include<string.h>
int main()
{
  char arr2[3] = { 'a','b','c'};
  int len2 = strlen(arr2);
  printf("%d\n", len2);
  return 0;
}


2a73ee150da6474fb9e0806f59588c6e.png

原因:

没有'\0',一直从'a'的位置往后数,内存里面一直往后找,什么时候找到'\0',什么时候停下,所以得出的结果是一个随机值


    ✅"strlen函数的返回类型是size_t - 无符号整型"

以下代码函数相减结果为-3,(因为无符号数减无符号数为无符号数),但是-3作为一个无符号整型来看待,那就是说内存中的补码直接当成了一个数字来看待了,而不是转换成原码来看待,那将是一个正整数

#include<string.h>
int main()
{
  if (strlen("abc") - strlen("abcdef") > 0)
  {
    printf(">\n");
  }
  else
  {
    printf("<=\n");
  }
}

下面的出现现象是我发现的一些问题:


                   当使用strlen函数但不引用头文件时,执行结果超出预料:

不引用头文件,但是使用它的库函数,这种行为,编译器连警告也没有,正常执行

1. #incl


54ae00f1b5bc4b59a1fa4d4e9aefabbb.png

个人反思:永远记住一个点,就是使用头文件,使用库函数的时候一定要包含正确的头文件,否则它可能会有一些异常的情况。

这就是一次异常啊,因为正常情况下:size_t 返回的值是unsigned int类型的,即使算出负数,它也是会转换成一个>=0的数字。


求字符串长度的方法💥


1.计数器

#include<stdio.h>
#include<string.h>
#include<assert.h>
int my_strlen(const char* str)
{
  int count = 0;
  assert(str);//断言一下是不是NULL指针
  while (*str != '\0')
  {
    count++;
    str++;
  }
  return count;
}
int main()
{
  char arr[] = "bit";
  int len = my_strlen(arr);
  printf("%d\n", len);
  return 0;
}


2.递归

题目要求:不创建临时变量,求字符串长度

思路:当第一个字符‘b’不为‘\0’,那整个字符串长度就是1+my_strlen(str+1)

要是第一个字符串(从str指向的首地址开始)为‘\0’,那就return 0

#include<stdio.h>
int my_strlen(char *str)
{
  if (*str != '\0')
    return 1 + my_strlen(1 + str);
  else
    return 0;
}
int main()
{
  char arr[] = "bit";
  int len = my_strlen(arr);
  printf("%d\n", len);
  return 0;
}


3.指针 - 指针

指针- 指针 == 地址 - 地址

前提:

  1. 两个指针指向同一块空间,指针的类型是一致的
  2. 指针 - 指针得到的是指针和指针之间的元素个数(这是语法规定的)
#include<stdio.h>
int main()
{
  int arr[10] = { 1,2,3,4,5,6,7,8,9};
  int n = &arr[9] - &arr[0];
  printf("%d\n", n);
  return 0;
}

7f95e73b26e24876945f847a421aadfa.png


1.2 strcpy

char* strcpy(char * destination, const char * source);

56ef1bbf40114e22bbf80d7adaafdbd4.png

  • 源字符串必须以 '\0' 结束。
  • 会将源字符串中的 '\0' 拷贝到目标空间。
  • 目标空间必须足够大,以确保能存放源字符串。
  • 目标空间必须可变。

1️⃣常量字符串:

char* p = "abcdefghi"

2️⃣字符串初始化数组本身:

char arr2[] = "hehe\n";


正常的普通操作

#include<stdio.h>
#include<string.h>
int main()
{
  char arr1[] = "abcdef";
  char arr2[] = { 0 };
  strcpy(arr2, arr1);
  printf("%s\n", arr2);
    return 0;
}

86ace108169d4a81b08208b54a7af679.png


错误操作:🧨

1.arr1数组名是一个地址,赋给一个地址arr2。

是错误的。正确操作应该是把数据放在地址所指向的空间里面去,而不是放到地址上

#include<stdio.h>
#include<string.h>
int main(){
  char arr1[] = "qwertyuiop";
  char arr2[] = arr1;//err
  char arr2[20] = { 0 };
  arr2 = arr1;//err
  return 0;
}


2.数组没有'\0'

#include<stdio.h>
#include<string.h>
int main()
{
  char arr1[3] = { 'a','b','c' };
  char arr2[20] = "xxxxxxxx";
  strcpy(arr2, arr1);
  printf("%s\n", arr2);
    return 0;
}


可以看到字符'c'后面还有其它不是数组的元素,那是因为'c'的后面没有'\0',所以它会从'c'的后面一直往后找‘\0’, 直到找到为止

affe08776d924344af9f02cd266b63a3.png

3.错误示范 - 目标空间不够大

#include<stdio.h>
#include<string.h>
int main(){
    char arr1[20] = "abcdefgh";
  char arr2[3] = "";//错误示范 - 目标空间必须足够大
  strcpy(arr2,arr1);
  printf("%s\n", arr2);
    return 0;
}


e750e63ad7864ece9a644f1c3587904a.png

相关文章
|
编译器 C++
【C进阶】-- 字符串函数(1)(中)
【C进阶】-- 字符串函数(1)(中)
【C进阶】-- 字符串函数(1)(下)
【C进阶】-- 字符串函数(1)(下)
|
算法 C++
C基础知识(字符串函数)
C基础知识(字符串函数)
47 0
|
26天前
|
C语言
C语言常见字符函数和字符串函数精讲
C语言常见字符函数和字符串函数精讲
|
5月前
|
存储 编译器 C语言
C primer plus 学习笔记 第11章 字符串和字符串函数
C primer plus 学习笔记 第11章 字符串和字符串函数
|
6月前
|
Go C语言
【C语言】字符+字符串函数精讲
【C语言】字符+字符串函数精讲
|
6月前
|
C语言 存储 编解码
C语言(进阶)—字符函数和字符串函数
C语言(进阶)—字符函数和字符串函数
|
C语言
C语言进阶字符函数和字符串函数(下)
C语言进阶字符函数和字符串函数(下)
38 0
|
C语言
C语言进阶字符函数和字符串函数(上)
C语言进阶字符函数和字符串函数(上)
69 0
|
12月前
|
算法 编译器 C语言
【C进阶】字符串函数
【C进阶】字符串函数
61 0