走进C标准库(6)——"string.h"中函数的实现memchr
我写的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的更多相关文章
- 走进C标准库(8)——"string.h"中函数的实现相关字符串操作函数
我的strcat: char *strcat(char *dest,char *src) { char * reval = dest; while(*dest) dest++; while(*src) ...
- 走进C标准库(7)——"string.h"中函数的实现memcmp,memcpy,memmove,memset
我的memcmp: int memcmp(void *buf1, void *buf2, unsigned int count){ int reval; while(count && ...
- 走进C标准库(3)——"stdio.h"中的getc和ungetc
接前文. 再来看看getc和ungetc的实现.在看这两个函数的实现之前,我们先来想一想这两个函数分别需要做的工作. int getc(FILE *stream) 说明:函数getc从stream指向 ...
- 走进C标准库(2)——"stdio.h"中的fopen函数
其他的库文件看起来没有什么实现层面的知识可以探究的,所以,直接来看stdio.h. 1.茶余饭后的杂谈,有趣的历史 在过去的几十年中,独立于设备的输入输出模型得到了飞速的发展,标准C从这个改善的模型中 ...
- 走进C标准库(4)——"stdio.h"中的putc
花了点时间把园子弄得好看了点,现在继续. 函数名: putc 功 能: 输出一字符到指定流中 用 法: int putc(int ch, FILE *stream); #define _putc_ ...
- 走进C标准库(5)——"stdio.h"中的其他部分函数
函数介绍来自:http://ganquan.info/standard-c/ 函数名: freopen 功 能: 替换一个流 用 法: FILE *freopen(char *filename, ...
- 走进C标准库(1)——assert.h,ctype.h
默默觉得原来的阅读笔记的名字太土了,改了个名字,叫做走进C标准库. 自己就是菜鸟一只,第一次具体看C标准库,文章参杂了对<the standard C library>的阅读和对源码的一些 ...
- 谈谈两种标准库类型---string和vector
两种最重要的标准库---string和vector string和vector是两种最重要的标准库类型,string表示可变长的字符序列,vector存放的是某种给定类型对象的可变长序列. 一.标准库 ...
- C++ Primer 第三章 标准库类型string运算
1. 标准库类型 string string表示可变长的字符序列,使用string必须首先包含string头文件.如何初始化类的对象是由类本身决定的. int n; string s1;//默认初始化 ...
随机推荐
- 2014.12.06 ASP.NET 三级联动,添加员工,修改员工
(一)三级联动 要实现的效果: 代码: MyDBDataContext context = new MyDBDataContext(); protected void Page_Load(object ...
- oFixed() 方法
oFixed() 方法可把 Number 四舍五入为指定小数位数的数字. 在本例中,我们将把数字舍入为仅有一位小数的数字: Show the number 13.37 with one decimal ...
- java反射获取注解并拼接sql语句
先建两个注解 分别为 Table 和 Column package com.hk.test; import java.lang.annotation.ElementType; import java. ...
- WIN7/8系统下程序接收不到WM_COPYDATA 消息的原因和解决
在WIN7/win8,如果发送消息的程序用户权限低于和接收消息的程序,则消 息无法传递.发送程序必须等于或者等于接收程序的权限.如发送与接收 是同一个用户,或者发送是管理员帐户,接收是是普通用户,这样 ...
- cookie记录用户的浏览商品的路径
在电子商务的网站中,经常要记录用户的浏览路径,以判断用户到底对哪些商品感兴趣,或者哪些商品之间存在关联. 下面将使用cookie记录用户的浏览过的历史页面.该网站将每个页面的标题保存在该页面的$TIT ...
- spoj ONP - Transform the Expression 中缀转后缀
题目链接 将中缀表达式转化为后缀表达式. 数字的话直接放到答案的字符串里. 如果是左括号就进栈, 右括号就让栈里的符号都出来直到第一个左括号. 否则的话比较当前符号的优先级和栈顶符号的优先级. #in ...
- MFC DLL资源动态切换
在MFC使用过程中,遇到DLL资源与主EXE资源冲突问题. 出现这样的Bug,一时无从下手. 报错位置在核心代码中dlgcore.cpp. [cpp] view plaincopy BOOL AFXA ...
- Address already in use: JVM_Bind <null>:8080
解决方法: 1重开eclipse,端口号被占用,或者杀掉进程
- Mac 域名解析
1. 域名解析 如,解析 www.baidu.com 在终端输入, host www.baidu.com 题外话: 转载自:http://hoarn.blog.51cto.com/1642678/14 ...
- STL 源代码剖析 算法 stl_algo.h -- merge sort
本文为senlie原创.转载请保留此地址:http://blog.csdn.net/zhengsenlie merge sort ----------------------------------- ...