【编织代码之纵横字符与绚丽字符串](下)

简介: 【编织代码之纵横字符与绚丽字符串]

【编织代码之纵横字符与绚丽字符串](中):https://developer.aliyun.com/article/1424777


1.11、字符分类函数:


函数 如果他的参数符合下列条件就返回非0,不符合就返回0
iscntrl 任何控制字符
isspace 空白字符:空格‘ ’,换页‘\f’,换行'\n',回车‘\r’,制表符'\t'或者垂直制表符'\v'
isdigit 十进制数字 0~9
isxdigit 十六进制数字,包括所有十进制数字,小写字母a~f,大写字母A~F
islower 小写字母a~z
isupper 大写字母A~Z
isalpha 字母a~z或A~Z
isalnum 字母或者数字,a~z,A~Z,0~9
ispunct 标点符号,任何不属于数字或者字母的图形字符(可打印)
isgraph 任何图形字符
isprint 任何可打印字符,包括图形字符和空白字符


1.12、字符转换:


  • int tolower ( int c );
  • int toupper ( int c );


我们来测试一下:


/* isupper example */
#include <stdio.h>
#include <ctype.h>
int main()
{
    int i = 0;
    char str[] = "Test String.\n";
    char c;
    while (str[i])
    {
        c = str[i];
        if (isupper(c))
            c = tolower(c);
        putchar(c);
        i++;
    }
    return 0;
}


运行结果:



1.13、memcpy - 拷贝任意类型的数据


void * memcpy ( void * destination, const void * source, size_t num );


  • 函数memcpy从source的位置开始向后复制num个字节的数据到destination的内存位置。
  • 这个函数在遇到 '\0' 的时候并不会停下来。
  • 如果source和destination有任何的重叠,复制的结果都是未定义的。


#include<stdio.h>
#include<string.h>
int main()
{
  //void * memcpy ( void * destination, const void * source, size_t num );
  int arr1[] = { 1,2,3,4,5,6,7,8,9,10 };
  int arr2[10] = { 0 };
  double arr3[] = { 1.0,2.0,3.0,4.0,5.0,6.0,7.0,8.0,9.0,10.0 };
  double arr4[10] = { 0.0 };
  //将arr1的内容拷贝到arr2中
  memcpy(arr2, arr1, 10 * sizeof(int));
  for (int i = 0; i < 10; i++)
  {
    printf("%d ", arr2[i]);
  }
  printf("\n");
  //将arr3的内容拷贝到arr4中
  memcpy(arr4, arr3, 10 * sizeof(double));
  for (int i = 0; i < 10; i++)
  {
    printf("%f ", arr4[i]);
  }
  return 0;
}


运行结果:



模拟实现mencpy:


void* my_memcpy(void* destination, const void* source, size_t num)
{
  void* dest = destination;
  assert(destination && source);
  while (num--)
  {
    *(char*)destination = *(char*)source;
    destination = (char*)destination + 1;
    source = (char*)source + 1;
    //这里不能使用*((char*)destination)++,因为强制类型转换只改变了看待的形式,
  }
  return dest;
}


如果source和destination有任何的重叠,复制的结果都是未定义的。


#include<string.h>
#include<string.h>
int main()
{
  //void * memcpy ( void * destination, const void * source, size_t num );
  int arr[] = { 1,2,3,4,5,6,7,8,9,10 };
  memcpy(arr+2, arr, 5 * sizeof(int));
  for (int i = 0; i < 10; i++)
  {
    printf("%d ", arr[i]);
  }
  return 0;
}


运行结果:



解释:拷贝第一个数据arr[0] - 1时,arr[2]的位置会被修改为arr[0] - 1的值,拷贝第二个数据arr[1] - 2时,arr[3] - 2的位置会被修改为arr[1]的值,当拷贝第三个数据arr[2] - 1时,arr[4]的位置会被修改为arr[2]的值,但是此时的arr[2]的值已经被修改为arr[0]的值 - 1,不再是原数组的3.


1.14、memmove


void * memmove ( void* destination, const void * source, size_t num );


  • 和memcpy的差别就是memmove函数处理的源内存块和目标内存块是可以重叠的。
  • 如果源空间和目标空间出现重叠,就得使用memmove函数处理。


#include<string.h>
#include<string.h>
int main()
{
  //void * memmove ( void * destination, const void * source, size_t num );
  int arr1[] = { 1,2,3,4,5,6,7,8,9,10 };
  memmove(arr1+2, arr1, 5 * sizeof(int));
  for (int i = 0; i < 10; i++)
  {
    printf("%d ", arr1[i]);
  }
  return 0;
}


运行结果:



模拟实现memmove:


void* my_memmove(void* destination, const void* source, size_t num)
{
  void* dest = destination;
  assert(destination && source);
  if(destination< source)
  {
    //从前向后
    while (num--)
    {
      *(char*)destination = *(char*)source;
      destination = (char*)destination + 1;
      source = (char*)source + 1;
    }
  }
  else
  {
    //从后向前
    while (num--)
    {
      *((char*)destination + num) = *((char*)source + num);
    }
  }
  return dest;
}


代码图解:



1.15、memcmp


int memcmp ( const void * ptr1, const void * ptr2, size_t num );


  • 比较从ptr1和ptr2指针开始的num个字节
  • 返回值如下:


#include<stdio.h>
#include<string.h>
int main()
{
  int arr1[] = { 1,2,3,4,5 };
  int arr2[] = { 1,2,257 };
  int ret = memcmp(arr1, arr2, 9);//比较9个字节
  printf("%d\n", ret);
  return 0;
}


运行结果:



图解:



1.16、memset


void * memset ( void * ptr, int value, size_t num );


  • 将指针ptr指向的内存块的前num个字节设置为指定的值(被解释为无符号字符)。


#include<stdio.h>
#include<string.h>
int main()
{
  int arr[10] = { 0 };
  int i = 0;
  for (i = 0; i < 10; i++)
  {
    memset(arr + i, i, 1);//以字节为单位设置,修改1个字节
    printf("%d ", arr[i]);
  }
  return 0;
}


运行结果:



我们来看看修改4个字节的结果:


#include<stdio.h>
#include<string.h>
int main()
{
  int arr[10] = { 0 };
  int i = 0;
  for (i = 0; i < 10; i++)
  {
    memset(arr + i, i, 4);//以字节为单位设置,修改4个字节
    printf("%d ", arr[i]);
  }
  return 0;
}


运行结果:


相关文章
|
4月前
|
算法
算法编程(二十八):重新排列单词间的空格
算法编程(二十八):重新排列单词间的空格
35 0
|
3月前
【编织代码之纵横字符与绚丽字符串](上)
【编织代码之纵横字符与绚丽字符串]
|
3月前
|
C语言
【编织代码之纵横字符与绚丽字符串](中)
【编织代码之纵横字符与绚丽字符串]
|
2月前
|
监控 API 计算机视觉
OpenCV这么简单为啥不学——1.2、图片截取(数组截取)
OpenCV这么简单为啥不学——1.2、图片截取(数组截取)
17 0
|
4月前
|
算法 索引
算法编程(二十):仅仅反转字母
算法编程(二十):仅仅反转字母
28 0
|
4月前
|
存储 算法 API
☆打卡算法☆LeetCode 151. 颠倒字符串中的单词 算法解析
☆打卡算法☆LeetCode 151. 颠倒字符串中的单词 算法解析
|
9月前
|
Java
字符串变形(字符串大小写切换和变现)
字符串变形(字符串大小写切换和变现)
67 0
|
11月前
|
小程序 索引
如何实现文字逐个出现的打字机效果
今天分享一下如何在微信小游戏制作工具中实现文字逐个出现的打字机效果,这个小功能可以用于游戏中的文字对白的展示,如果你要做的是一个文字类游戏的话,那么肯定用的上。
94 0
|
自然语言处理 算法
☆打卡算法☆LeetCode 68、文本左右对齐 算法解析
“给定单词数组和一个长度maxWidth,重新排版单词,使其成为恰好有maxWWidth个字符,且左右对齐的文本。”
☆打卡算法☆LeetCode 97、交错字符串 算法解析
“给定三个字符串s1、s2、s3,验证s3是否是s1和s2的交错组成的。”

热门文章

最新文章