CRun
确定特定字符是否为ASCII字符。
int _ _ isascii(
int c
);
int is ascii(
wint _ t c
);
测试程序:
# include " STD afx . h "
# include " ctype . h "
# include " locale . h "
# include " stdio . h "[/br void CheckCharAndPrint(char acChar)
{
if(_ _ isascii(acChar))
{
printf(" char % c是ascii字符。\n”,acChar);
}
else
{
/中文在这里无法正常输出,所以
printf ("char% c不是ascii字符。\ n ",AC char)没有深入研究;
}
}
void CheckWCharAndPrint(wchar _ t awcChar)
{
if(isw ascii(awcChar))
{
wprintf(L " wchar % c是ascii字符。\n ",awcChar);
}
else
{
setlocale(LC _ ALL," ");
wprintf(L"wchar %c不是ascii字符。\n ",awcChar);
}
}
int _ tmain(int argc,_ TCHAR * argv[])
{
char lcC = ' a ';
char lcD = ' medium ';
CheckCharAndPrint(lcC);
CheckCharAndPrint(lcD);
wchar _ t lwcC = L ' a ';
wchar _ t lwcD = L ' medium ';
CheckWCharAndPrint(lwcC);
CheckWCharAndPrint(lwcD);
返回0;
}
描述:
__isascii是一个特殊的函数,因为它以两个前导下划线开头。这在C语言中很少见。(至少我看的比较少)
这个函数应该不属于标准库函数。在TCPL中,C语言参考中没有描述,但在gcc中有。也就是说这个功能在linux下是可以正常使用的。
is ascii,宽字节版的_ __isascii函数和很多宽字节版的函数一样,都是MS自己扩展的,所以。。linux下不能用这个功能。要用,只能自己去实现。
实现:
ms:
# define _ _ isascii(_ char)((unsigned)(_ char)< 0x 80)
inline int _ _ cdeclisw ascii(wint _ t _ c){ }
gcc:
# define _ _ isascii(c)((c)& ~ 0x7f)= = 0)/*如果c是7位值*/
_ _ isascii是一个简单的宏MS的iswascii原理和它的_ __isascii一样,只是一个内联函数。
微软的实现依赖于字符小于128(0x80)。这里做了一个很强的转折,不太理解,因为实际的char可以直接作为一个整数来比较。也许只是为了屏蔽警告?
GCC的实现依赖于除了低七位以外没有其他值的字符。即127(0x7f)先反相,然后与字符位为and。就是实际得到字符c的值,除了低七位。然后比较这个值是否为零。
这么简单的功能我想不到。MS和gcc的实现是如此不同。相对来说,MS的实现相对容易理解,但是GCC这么复杂的实现应该更高效。
就分析来看,强转+小于运算的运行时间比一次反转一位等于运算的运行时间要长。不容易知道谁的效率真的更高。然后测试它
效率测试:
# include " jtianling . h "
# define _ _ isascims(_ char)((unsigned)(_ char)< 0x 80)
# define _ _ is & ~ 0x7f)= = 0)/*如果C是7位值*/
const int DEF _ TEST _ TIMES = 10000000;
void CheckMS(char AC)
{
double ldtime last = jtianling::GetTime();
for(int I = 0;I {
_ _ isasciims(AC);
}
double ldtime past = jtianling::GetTime()-ldtime last;
printf("__isasciims %c运行%d次,花费%lf秒。\n ",ac,DEF_TEST_TIMES,ldtime past);
}
void check gcc(char AC)
{
double ldtime last = jtianling::GetTime();
for(int I = 0;I {
_ _ isasciigcc(AC);
}
double ldtime past = jtianling::GetTime()-ldtime last;
printf(" _ _ isasciigcc % c run % d times cost % lf secs。\n ",ac,DEF_TEST_TIMES,ldtime past);
}
int _tmain(int argc,_ TCHAR * argv[])
{
char LC = ' a ';
char lc2 = ' medium ';
支票(信用证);
check gcc(LC);
支票(信用证);
check gcc(lc2);
返回0;
}
至于GetTime函数的含义,可以参考我之前写的库,无非就是获取当前时间。不知道也没关系。可以用time(NULL)代替,但是精度没有这个函数高。
实际测试结果非常令人失望。经过几乎无数次的测试,MS和gcc的执行效率相差无几。10亿级别,gcc有时候只快0.1秒,跑了很多次也不稳定。看来如果不是复杂的实现一定是好的。。。
相关函数:
msdn:
转换器字符。
int _ _ toas CII(
int c
);
这个函数也是一个双前置下划线的函数,在MS和GCC中实现。在这一点上,实现是相同的。
# define _ _ to ASCII(_ char)(_ char)& 0x7f)
gcc注释“屏蔽掉高位。”
这和前面GCC中_ __isascii函数实现的部分很像,一个是去掉低七位,一个是保留低七位。看了这个才知道为什么gcc会想到用这种方式实现__isascii。
考试提示:这两个函数我都没实际用过。如果我的工作范围不是太窄,那么这两个功能的可用性不强。确实,我没事把一个值转换成ascii码?如果是ascii,那就没有意义。如果不是,还能保留原意吗?至于__isascii函数,在某些情况下可能还是有用的,但我没用过。有人能告诉我实际使用这两个函数的代码吗?
考试总结就是C运行时库MS虽然也有源代码,但是完全没有注释。相对来说,gcc的评论丰富而详细。呵呵,毕竟开源代码不一样。它是做给人们看的。如果你思考这个分析,仅仅看源代码并不会有太大的收获。
0条评论