• 走进C标准库(6)——"string.h"中函数的实现memchr


    我写的memchr:

    1 void *memchr(const void *buf, char ch, unsigned count){
    2      unsigned int cnt = 0;
    3      while(*(buf++) != ch && cnt <= count){cnt++;}
    4      if(cnt > count)
    5         return NULL;
    6      else
    7         return buf;
    8 }

    红色部分报错。

    该错误为为ANSIC中认定的错误,是因为它坚持:进行算法操作的指针必须是确定知道其指向数据类型大小的。

    但是GNU则不这么认定,它指定void * 的算法操作与char * 一致。

    在实际的程序设计中,为迎合ANSI标准,并提高程序的可移植性,我们可以对void指针先进行强制类型转换为特定类型的指针。

    则上述代码修改为:

    1 void *memchr(const void *buf, char ch, unsigned count){
    2      unsigned int cnt = 0;
    3      while(*((char *)buf++) != ch && cnt <= count){cnt++;}
    4      if(cnt > count)
    5         return NULL;
    6      else
    7         return buf;
    8  }

    使用测试程序测试:

    1 int main(void)
    2 {
    3     char *s = "hello world";
    4     char *ptr = memchr(s,'w',10);
    5     printf("%x
    %x
    %c",s,ptr,*ptr);
    6     return 0;
    7 }

    输出结果为:

    403000
    403007
    o

    有错,理论上*ptr应该为w

    循环条件上多加了1

    最终的程序:

    1 void *memchr(const void *buf, char ch, unsigned count){
    2     unsigned int cnt = 0;
    3     while(*((char *)buf++) != ch && cnt <= count){cnt++;}
    4     if(cnt > count)
    5        return NULL;
    6     else
    7        return (char *)buf - 1;
    8 }

    microsoft visual C 中的memchr的实现为:

     1 void * __cdecl memchr (
     2         const void * buf,
     3         int chr,
     4         size_t cnt
     5         )
     6 {
     7         while ( cnt && (*(unsigned char *)buf != (unsigned char)chr) ) {
     8                 buf = (unsigned char *)buf + 1;
     9                 cnt--;
    10         }
    11 
    12         return(cnt ? (void *)buf : NULL);
    13 }

    参考其代码仍有两点可以改进:

    1.可将最后的if语句改为三元表达式的形式。

    2.使用unsigned char保证能接受非常规的字符(如字符¥的ASCII码值在850 (Latin 1)为190),同时保证字符运算时结果的正确性(有符号数的运算结果会受符号位的影响,如0-(-128)=-128)。

  • 相关阅读:
    python学习第18天----属性、类方法、静态方法
    面试总结
    JAVA面试题整理
    Docker-基础
    Shell
    MYSQL
    logstash的使用(ELK)
    (ELK)FileBeat的使用
    Zookeeper的介绍和单机、集群搭建
    Elaticsearch7.7.0的安装(ELK)
  • 原文地址:https://www.cnblogs.com/shijiezhenmei/p/3701090.html
Copyright © 2020-2023  润新知