永发信息网

C语言 字符串处理函数strtok第二次及以后的调用中第一个参数要用NULL的原因是什么? 能不能解释下原理?

答案:2  悬赏:0  手机版
解决时间 2021-02-10 09:50
  • 提问者网友:疯子也有疯子的情调
  • 2021-02-10 04:09
RT
最佳答案
  • 五星知识达人网友:我住北渡口
  • 2021-02-10 04:47
源码:



#include
#include
#ifdef _MT
#include
#endif



char * __cdecl strtok (
char * string,
const char * control
)
{
unsigned char *str;
const unsigned char *ctrl = control;

unsigned char map[32];
int count;

#ifdef _MT
_ptiddata ptd = _getptd();
#else
static char *nextoken;
#endif


for (count = 0; count < 32; count++)
map[count] = 0;


do {
map[*ctrl >> 3] |= (1 << (*ctrl & 7));
} while (*ctrl++);


if (string)
str = string;
else
#ifdef _MT
str = ptd->_token;
#else
str = nextoken;
#endif


while ( (map[*str >> 3] & (1 << (*str & 7))) && *str )
str++;

string = str;


for ( ; *str ; str++ )
if ( map[*str >> 3] & (1 << (*str & 7)) ) {
*str++ = '/0';
break;
}


#ifdef _MT
ptd->_token = str;
#else
nextoken = str;
#endif

if ( string == str )
return NULL;
else
return string;
}
源码结束!!

str = nextoken;
#endif
××××××××××××××××××××××××××××××××××××××××/
/**************************************************************
以下是算法:
map[*ctrl >> 3] |= (1 << (*ctrl & 7))说明:
map[*ctrl >> 3] |= (1 << (*ctrl & 7));
这句是这样的意思
首先map[32]是个uchar型数组,数组每一个是8位,其中每一位可以表示一个字符,32×8=256,这样的话,map[32]中有256个bit,每个bit表示一个ASCII码,那么可以表示256个ASCII码。
*ctrl >> 3,表示将安ascii码,给其分类,*ctrl >> 3表示,除以8的意思,将ascii每八位分为一组,也就是map[32]中的一个。
1 << (*ctrl & 7),这个是这样的意思,7表示为二进制就是00000111,这样的话,相当于是一个数除以8后剩余的余数。1 << (*ctrl & 7),就是将二进制00000001,向右移动(*ctrl & 7)个位。
map[*ctrl >> 3] |= (1 << (*ctrl & 7)),就是表示将map[*ctrl >> 3]中的(*ctrl & 7)+1位设为1,表示在该位置查询到一个ascii字符。
这样做以后,就相当于简历了一个表,只要查询相应的位是否为1,就知道该字符,在strtok的字符串中是否出现过。

××××××××××××××××××××××××××××××××/
全部回答
  • 1楼网友:掌灯师
  • 2021-02-10 05:12
编程中的NULL 一.NULL字符   在ASCII码的第一个字符是NULL,它的数值是0,占用1字节;C语言把它作为字符串的最后一个字符,以表示字符串到此结束."\0" 二.NULL指针   在C语言的头文件stddef.h中,NULL的定义如下:   #ifndef NULL   #ifdef __cplusplus   #define NULL 0   #else   #define NULL ((void *)0)   #endif   #endif   #interface NULL 0   可见,NULL指针是一个无类型指针,并且值为0。一个指针,拥有2个属性--地址值和指针类型。两者的作用是:1,地址值标识变量的首地址(32位系统下指针的地址值占4字节);2,指针类型告诉编译器,应该怎样进行接下来的数据访问(int型数组和float型数组是不同的;数组访问与结构体访问也是不同的;等等)。   NULL的出现是一种约定俗成,事实上它不是C语言中的关键字;把一个指针赋值为NULL,通常的说法是“将指针悬空”。这样,指针就无法再进行任何数据访问了。编程工作中有一类比较容易犯的错误--指针地址未进行正确的更新赋值就加以使用,这往往会造成很严重的后果(对内存区进行错误的涂抹)。所以一个良好的习惯是,当一个指针的工作稍事休息,先把它赋值为NULL,待到再度使用时,重新对其赋值以及进行指针类型转化。   前面说到“NULL指针无法再进行任何数据访问”,其实是视编译器功能而定的。0位置指向的是程序起始,对于不同的编译器,NULL指针的操作结果是不同的:有些是不准读写,有些是只读,甚至读写都允许。编译器是人定的。引用网友win_hate在话题“关于NULL的不严谨”中的话来说:“如果说有谁不严谨了,那必定是读取0位置的程序员,而不是C。C的设计哲学之一是:‘程序员知道自己在干什么--没有安全带’”。 三.数据库中的NULL   Null在数据库中表示 不知道的数据,主要有3种意思:   1)知道数据存在,但不知道具体值.   2)不知道数据是否存在.   3)数据不存在. 四.NULL与0的疑惑   NULL与0有着扯不断理还乱的关系,其实不那么高深。0本身有着一些原生的特性诸如:起始,没有,正负的分界线,0/1中的0还可以表示否定。NULL正需要这些特性中的一部分。 我们只需要清楚NULL的本质,并在合理的地方才加以利用而非滥用。譬如我想做一个比较某个整数i是否为0,难道写成i==NULL会比i==0更酷一点吗? 五.matlab中的函数   函数null用来求解零空间,即满足方程组A*X=0的解空间。实际上是求出解空间的一组解(基础解系)。   语法:z=null(A) %z的列向量为方程组的正交规范基,满足z‘ x z=I。   z=null(A,'r') %z的列向量是方程A*X=0的有理基。
我要举报
如以上回答内容为低俗、色情、不良、暴力、侵权、涉及违法等信息,可以点下面链接进行举报!
点此我要举报以上问答信息
大家都在看
推荐资讯