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

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

【编织代码之纵横字符与绚丽字符串](中):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;
}


运行结果:


相关文章
|
5月前
字符组成的超级玛丽
字符组成的超级玛丽
|
6月前
|
C语言
c语言编程练习题:7-3 输出带框文字
本题要求编写程序,输出指定的带框文字。
138 0
|
6月前
|
算法
算法编程(二十八):重新排列单词间的空格
算法编程(二十八):重新排列单词间的空格
58 0
|
1月前
|
Python
manim边学边做--形状匹配
【10月更文挑战第2天】在使用Manim进行形状匹配时,需先安装Manim并通过运行简单示例验证。Manim的基本概念包括场景(Stage)、图形(Mobjects)和动画(Animations)。创建形状匹配场景需定义新场景类,并在其中添加形状及变换动画。最后运行场景即可生成从正方形渐变为圆形的动画,适合边学边做。
|
6月前
【编织代码之纵横字符与绚丽字符串](上)
【编织代码之纵横字符与绚丽字符串]
|
6月前
|
C语言
【编织代码之纵横字符与绚丽字符串](中)
【编织代码之纵横字符与绚丽字符串]
|
6月前
|
算法 索引
算法编程(二十):仅仅反转字母
算法编程(二十):仅仅反转字母
44 0
|
小程序 索引
如何实现文字逐个出现的打字机效果
今天分享一下如何在微信小游戏制作工具中实现文字逐个出现的打字机效果,这个小功能可以用于游戏中的文字对白的展示,如果你要做的是一个文字类游戏的话,那么肯定用的上。
146 0
文字到底能玩出多少花样(三)使用background实现花式下划线
文字到底能玩出多少花样(三)使用background实现花式下划线
385 0
文字到底能玩出多少花样(三)使用background实现花式下划线
|
自然语言处理 算法
☆打卡算法☆LeetCode 68、文本左右对齐 算法解析
“给定单词数组和一个长度maxWidth,重新排版单词,使其成为恰好有maxWWidth个字符,且左右对齐的文本。”