【学习笔记之我要C】字符串+内存函数(上)

简介: 【学习笔记之我要C】字符串+内存函数

一、strlen函数以及模拟实现

  1. 函数使用
int main() {
  char arr[] = "abc";
  int len = strlen(arr);
  printf("%d\n", len);
  return 0;
}
  1. 函数介绍

  字符串以’\0’作为结束标志,strlen函数返回的是在字符串中’\0’前面出现的字符个数(不包含’\0’);

  参数指向的字符串必须要以 ‘\0’ 结束;

  注意函数的返回值为size_t,是无符号的。

  1. 函数源码

c0299cabb1fb483fa6786a5c6e8ce69f.png

  1. size_t在中定义typedef unsigned int size_t;,是无符号的;
    接收一个char类型的数据,用const修饰,保证指针指向的内容不能通过指针来改变。
  2. 模拟实现
//计数器方式
int my_strlen(const char* str) {
  int count = 0;//计数器
  assert(str != NULL);//指针断言,确保指针的有效性
  while (*str != '\0') {
    count++;
    str++;
  }
  return count;
}
//不能创建临时变量计数器
int my_strlen(const char * str) {
  if(*str == '\0')
    return 0;
  else
    return 1+my_strlen(str+1);
}
//指针-指针的方式
int my_strlen(char *s) {
  char *p = s;
  while(*p != ‘\0’ )
    p++;
  return p-s; 
}
int main() {
  char arr[] = "abc";
  int len = my_strlen(arr);
  printf("%d\n", len);
  return 0;
}
  1. 与strlen函数的区别
int main() {
  //因为strlen返回的是一个无符号数,所以打印 >
  if (strlen("abc") - strlen("abcedf") > 0)
  {
    printf("strlen >\n");
  }
  else
  {
    printf("strlen <\n");
  }
  //我们的模拟的函数返回的是一个int类型是有符号的,所以打印 <
  //如果我们想要和strlen一模一样,那就需要也返回一个无符号数
  //把int改为size_t
  if (my_strlen("abc") - my_strlen("abcedf") > 0)
  {
    printf("my_strlen >\n");
  }
  else
  {
    printf("my_strlen <\n");
  }
  return 0;
}

二、长度不受限制的字符串函数

1、strcpy函数以及模拟实现

  1. 函数使用
int main() {
  char arr[20] = { 0 };
  strcpy(arr, "hello");
  printf("%s\n", arr);
  return 0;
}
  1. 函数介绍

  源字符串必须以’\0’结束;

  会将源字符串中的 ‘\0’ 拷贝到目标空间;

  目标空间必须足够大,以确保能存放源字符串;

  目标空间必须可变。

be1bc6077c234da69b50994b7c5332c5.png

函数源码

2c079c62bfd34725ad18323145ab8663.png


  1. destination是目标的意思,也就是说destination这里放被替换的字符,即目标字符。source的意思是来源,就是source这里放替换字符,即源字符。所以strcpy接收两个参数,第一个参数为需要被替换的字符,第二个参数为替换字符;
  2. 模拟实现
char* my_strcpy(char* dest, char* src) {
  while (*dest++ = *src++) { ; }
}
int main() {
  char arr[20] = { 0 };
  my_strcpy(arr, "hello");
  printf("%s\n", arr);
  return 0;
}

2、strcat函数以及模拟实现

  1. 函数使用
int main() {
  char arr1[20] = "hello";
  char arr2[] = "world";
  strcat(arr1, arr2);//字符串追加(连接)
  printf("%s\n", arr1);
  return 0;
}
  1. 函数介绍

  源字符串必须以’\0’结束;

  目标空间必须有足够的大,能容纳下源字符串的内容;

  目标空间必须可修改;

  strcat函数不能自己追加自己。

image.png

函数源码

image.png

  1. 接收参数与strcpy是一样的。
  2. 模拟实现
char* my_strcat(char* dest, const char* str) {
  char* ret = dest;
  assert(dest && str);//断言,确保指针是有效的
  //找到目标字符串中的\0
  while (*dest) {
    dest++;
  }
  //追加源字符串
  while (*dest++ = *str++) { ; }
  return ret;//strcat返回的是目标空间的起始地址,我们也返回目标空间起始地址
}
int main() {
  char arr1[20] = "hello";
  char arr2[] = "world";
  my_strcat(arr1, arr2);//字符串追加(连接)
  printf("%s\n", arr1);
  return 0;
}

3、strcmp函数以及模拟实现

  1. 函数使用
int main() {
  printf("%d\n", strcmp("abc", "abb"));
  printf("%d\n", strcmp("abc", "abc"));
  printf("%d\n", strcmp("abb", "abc"));
  return 0;
}
  1. 函数介绍

  第一个字符串大于第二个字符串,则返回大于0的数字;

  第一个字符串等于第二个字符串,则返回0;

  第一个字符串小于第二个字符串,则返回小于0的数字。

  1. 函数源码

81127e41c83b4a2ba7f4fbf776b6c9c2.png

  1. 模拟实现
int my_strcmp(const char* s1, const char* s2) {
  assert(s1 && s2);
  while (*s1 == *s2) {
    s1++;
    s2++;
    if ('\0' == *s1 || '\0' == *s2) { 
      break;
    }
  }
  return *s1 - *s2;
}
int main() {
  printf("%d\n", my_strcmp("abc", "abb"));
  printf("%d\n", my_strcmp("abc", "abc"));
  printf("%d\n", my_strcmp("abb", "abc"));
  return 0;
}

三、长度受限制字符串函数

1、strncpy函数以及模拟实现

  1. 函数使用
int main() {
  char arr1[20] = "abcdef";
  char arr2[] = "qwer";
  printf("%s\n", strncpy(arr1, arr2, 2));
  return 0;
}
  1. 函数介绍

  拷贝n个字符从源字符串到目标空间;

  如果源字符串的长度小于num,则拷贝完源字符串之后,在目标的后边追加0,直到num个。

17504a1bd68b4a7fb72ad3f6b9e553f3.png

函数源码

6d1e121ed39f4ab1baec011eba1fc2d3.png

  1. 它比strcpy多了一个Count计数器,用来确定从原字符串中拷贝几个字符到目标空间。所以它被叫做长度受限制字符串函数,而strcpy被叫做长度不受限制的字符串函数。
  2. 模拟实现
char* my_strncpy(char* dest, char* src, int count) {
  while (*dest++ = *src++) { 
    count--;
  }
  int i = 0;
  for (i = 0; i < count - 1; i++) {
    *dest++ = '\0';
  }
}
int main() {
  char arr1[20] = "abcdefdef";
  char arr2[] = "qwer";
  my_strncpy(arr1, arr2, 6);
  printf("%s\n", arr1);
  return 0;
}


目录
相关文章
|
C语言 C++
C语言 之 内存函数
C语言 之 内存函数
123 3
|
3月前
|
安全 C语言
C语言中的字符、字符串及内存操作函数详细讲解
通过这些函数的正确使用,可以有效管理字符串和内存操作,它们是C语言编程中不可或缺的工具。
258 15
|
10月前
|
存储 缓存 算法
【C语言】内存管理函数详细讲解
在C语言编程中,内存管理是至关重要的。动态内存分配函数允许程序在运行时请求和释放内存,这对于处理不确定大小的数据结构至关重要。以下是C语言内存管理函数的详细讲解,包括每个函数的功能、标准格式、示例代码、代码解释及其输出。
366 6
|
11月前
|
缓存 算法 Java
本文聚焦于Java内存管理与调优,介绍Java内存模型、内存泄漏检测与预防、高效字符串拼接、数据结构优化及垃圾回收机制
在现代软件开发中,性能优化至关重要。本文聚焦于Java内存管理与调优,介绍Java内存模型、内存泄漏检测与预防、高效字符串拼接、数据结构优化及垃圾回收机制。通过调整垃圾回收器参数、优化堆大小与布局、使用对象池和缓存技术,开发者可显著提升应用性能和稳定性。
185 6
|
程序员 C++ 容器
在 C++中,realloc 函数返回 NULL 时,需要手动释放原来的内存吗?
在 C++ 中,当 realloc 函数返回 NULL 时,表示内存重新分配失败,但原内存块仍然有效,因此需要手动释放原来的内存,以避免内存泄漏。
|
12月前
|
存储 C语言
【c语言】字符串函数和内存函数
本文介绍了C语言中常用的字符串函数和内存函数,包括`strlen`、`strcpy`、`strcat`、`strcmp`、`strstr`、`strncpy`、`strncat`、`strncmp`、`strtok`、`memcpy`、`memmove`和`memset`等函数的使用方法及模拟实现。文章详细讲解了每个函数的功能、参数、返回值,并提供了具体的代码示例,帮助读者更好地理解和掌握这些函数的应用。
187 0
|
C语言 C++
c语言回顾-内存操作函数
c语言回顾-内存操作函数
151 0
|
3月前
|
存储
阿里云轻量应用服务器收费标准价格表:200Mbps带宽、CPU内存及存储配置详解
阿里云香港轻量应用服务器,200Mbps带宽,免备案,支持多IP及国际线路,月租25元起,年付享8.5折优惠,适用于网站、应用等多种场景。
1003 0
|
3月前
|
存储 缓存 NoSQL
内存管理基础:数据结构的存储方式
数据结构在内存中的存储方式主要包括连续存储、链式存储、索引存储和散列存储。连续存储如数组,数据元素按顺序连续存放,访问速度快但扩展性差;链式存储如链表,通过指针连接分散的节点,便于插入删除但访问效率低;索引存储通过索引表提高查找效率,常用于数据库系统;散列存储如哈希表,通过哈希函数实现快速存取,但需处理冲突。不同场景下应根据访问模式、数据规模和操作频率选择合适的存储结构,甚至结合多种方式以达到最优性能。掌握这些存储机制是构建高效程序和理解高级数据结构的基础。
299 0

热门文章

最新文章