我写的memchr:

 void *memchr(const void *buf, char ch, unsigned count){
unsigned int cnt = ;
while(*(buf++) != ch && cnt <= count){cnt++;}
if(cnt > count)
return NULL;
else
return buf;
}

红色部分报错。

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

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

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

则上述代码修改为:

 void *memchr(const void *buf, char ch, unsigned count){
unsigned int cnt = ;
while(*((char *)buf++) != ch && cnt <= count){cnt++;}
if(cnt > count)
return NULL;
else
return buf;
}

使用测试程序测试:

 int main(void)
{
char *s = "hello world";
char *ptr = memchr(s,'w',);
printf("%x\n%x\n%c",s,ptr,*ptr);
return ;
}

输出结果为:

403000
403007
o

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

循环条件上多加了1

最终的程序:

 void *memchr(const void *buf, char ch, unsigned count){
unsigned int cnt = ;
while(*((char *)buf++) != ch && cnt <= count){cnt++;}
if(cnt > count)
return NULL;
else
return (char *)buf - ;
}

microsoft visual C 中的memchr的实现为:

 void * __cdecl memchr (
const void * buf,
int chr,
size_t cnt
)
{
while ( cnt && (*(unsigned char *)buf != (unsigned char)chr) ) {
buf = (unsigned char *)buf + ;
cnt--;
} return(cnt ? (void *)buf : NULL);
}

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

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

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

走进C标准库(6)——"string.h"中函数的实现memchr的更多相关文章

  1. 走进C标准库(8)——"string.h"中函数的实现相关字符串操作函数

    我的strcat: char *strcat(char *dest,char *src) { char * reval = dest; while(*dest) dest++; while(*src) ...

  2. 走进C标准库(7)——"string.h"中函数的实现memcmp,memcpy,memmove,memset

    我的memcmp: int memcmp(void *buf1, void *buf2, unsigned int count){ int reval; while(count && ...

  3. 走进C标准库(3)——"stdio.h"中的getc和ungetc

    接前文. 再来看看getc和ungetc的实现.在看这两个函数的实现之前,我们先来想一想这两个函数分别需要做的工作. int getc(FILE *stream) 说明:函数getc从stream指向 ...

  4. 走进C标准库(2)——"stdio.h"中的fopen函数

    其他的库文件看起来没有什么实现层面的知识可以探究的,所以,直接来看stdio.h. 1.茶余饭后的杂谈,有趣的历史 在过去的几十年中,独立于设备的输入输出模型得到了飞速的发展,标准C从这个改善的模型中 ...

  5. 走进C标准库(4)——"stdio.h"中的putc

    花了点时间把园子弄得好看了点,现在继续. 函数名: putc 功  能: 输出一字符到指定流中 用  法: int putc(int ch, FILE *stream); #define _putc_ ...

  6. 走进C标准库(5)——"stdio.h"中的其他部分函数

    函数介绍来自:http://ganquan.info/standard-c/ 函数名: freopen 功  能: 替换一个流 用  法: FILE *freopen(char *filename, ...

  7. 走进C标准库(1)——assert.h,ctype.h

    默默觉得原来的阅读笔记的名字太土了,改了个名字,叫做走进C标准库. 自己就是菜鸟一只,第一次具体看C标准库,文章参杂了对<the standard C library>的阅读和对源码的一些 ...

  8. 谈谈两种标准库类型---string和vector

    两种最重要的标准库---string和vector string和vector是两种最重要的标准库类型,string表示可变长的字符序列,vector存放的是某种给定类型对象的可变长序列. 一.标准库 ...

  9. C++ Primer 第三章 标准库类型string运算

    1. 标准库类型 string string表示可变长的字符序列,使用string必须首先包含string头文件.如何初始化类的对象是由类本身决定的. int n; string s1;//默认初始化 ...

随机推荐

  1. iOS坐标转换

    // 将像素point由point所在视图转换到目标视图view中,返回在目标视图view中的像素值 - (CGPoint)convertPoint:(CGPoint)point toView:(UI ...

  2. Java SE基础部分——常用类库之NumberFormat(数字格式化)

    数字格式化常用方法:DecimalFormat和NuberFormat. //2016060524 数字格式化学习 //数字格式化 两种方法 一种直接使用NumberFormat,另一种Decimal ...

  3. php7 install script

    ./configure --prefix=/home/admin/local/php7 --with-gd=/home/admin/local/libgd-2.1.1/ --with-jpeg-dir ...

  4. Vim配置 终端背景色配置

    在终端下使用vim进行编辑时,默认情况下,编辑的界面上是没有显示行号.语法高亮度显示.智能缩进 等功能的.为了更好的在vim下进行工作,需要手动设置一个配置文件:.vimrc.在启动vim时,当前用户 ...

  5. 航频之声APP截图

    上传github的APP截图......

  6. 通过innerHTML简化脚本

    <!doctype html> <html lang="en"> <head>   <meta charset="UTF-8&q ...

  7. charset

    <meta charset="UTF-8" /> 这是html5的写法. <meta http-equiv=“content-type” content=“tex ...

  8. Oracle EBS-SQL (BOM-3):检查期间新增Bom数量.sql

    --本周系统BOM汇总记录 SELECT         ITM.SEGMENT1  物料编码, ITM.DESCRIPTION   物料描述, bom2.CREATION_DATE   创建日期, ...

  9. 这才是正确删除 office 的方式

    https://support.office.com/zh-cn/article/%E9%80%9A%E8%BF%87%E5%9C%A8%E9%87%8D%E6%96%B0%E5%AE%89%E8%A ...

  10. Office 2010 Toolkit and EZ-Activator

    “Office 2010 Toolkit 2.0.1”是“迷你KMS”的更新换代版本.虽然是单一可执行程序,但一身承担两大职能:“KMS服务器”和“客户激活端”.“Office 2010 Toolki ...