走进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;//默认初始化 ...
随机推荐
- 剑指offier77页
/* * 输入字母判断第几列 */ import java.util.Scanner; public class JudgeClumns { public static void main(Strin ...
- 创建SDE表空间
创建空间数据存储类型为ST_Geometry的要素类有2种方法:1)使用SDE创建要素类从9.3 开始,默认创建的要素类都使用ST_Geometry存储空间数据,9.3 版本之前,可以通过配置dbtu ...
- Android SQLite系列
转:http://blog.csdn.net/liuhe688/article/details/6715983 Android中如何使用SQLite. 现在的主流移动设备像Android.iPhone ...
- 练习-checkbox 全选 ,反选, 单选,以及取值
1.方法1 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w ...
- 刷爆github小绿点
转载请注明出处:https://ahangchen.gitbooks.io/windy-afternoon/content/kit/git/green_blush.html 工程地址,欢迎star!! ...
- Apache开启expires响应头,优化缓存
apache开始expires响应头输出 expires是什么 指示资源什么时候过期的时间值(GMT时间),在指定的过期时间前,浏览器可以直接使用自身缓存的版本,而不用向服务器发请求,大大减轻服务器压 ...
- openssl编译(VC6.0)
官网:http://www.openssl.org/ 得到源码: git clone https://github.com/openssl/openssl 一.用vc编译器编译: 1.下载nasm: ...
- 「python」: arp脚本的两种方法
「python」: arp脚本的两种方法 第一种是使用arping工具: #!/usr/bin/env python import subprocess import sys import re de ...
- poj2578---三个数中找出第一个大于168的
#include <stdio.h> #include <stdlib.h> int main() { int a,b,c; scanf("%d %d %d" ...
- 面向对象程序设计-C++_课时18内联函数
使用inline说明的函数称内联函数. 在C++中,除具有循环语句.switch语句的函数不能说明为内联函数外,其他函数都可以说明为内联函数. #include <iostream> us ...