Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/amazon-s3/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C 试图理解strtok实现中的代码_C_Strtok - Fatal编程技术网

C 试图理解strtok实现中的代码

C 试图理解strtok实现中的代码,c,strtok,C,Strtok,我是一个非常c的新手,我正在跟随斯坦福德的CS107视频学习(我不是那里的学生) 如果有人感兴趣,请点击下面的链接 查看下面的strtok实现,我不知道为什么第一个if语句是这样写的:if(s==NULL&((s=p)==NULL)) 到目前为止,我已经确定了以下内容: 1) 静态p是一个本地静态,因此它一旦成为一个令牌就持续存在 找到,并在找不到更多时重置为NULL 2) strtoken的后续调用将s作为NULL char *strtok(char *s, const char *sep)

我是一个非常c的新手,我正在跟随斯坦福德的CS107视频学习(我不是那里的学生)

如果有人感兴趣,请点击下面的链接

查看下面的strtok实现,我不知道为什么第一个if语句是这样写的:
if(s==NULL&((s=p)==NULL))

到目前为止,我已经确定了以下内容:

1) 静态
p
是一个本地静态,因此它一旦成为一个令牌就持续存在 找到,并在找不到更多时重置为NULL

2)
strtoken
的后续调用将
s
作为
NULL

char *strtok(char *s, const char *sep)
{
    static char *p = NULL;

    if (s == NULL && ((s = p) == NULL))
        return NULL;
    s += strspn(s, sep);
    if (!*s)
        return p = NULL;
    p = s + strcspn(s, sep);
    if (*p)
        *p++ = '\0';
    else 
        p = NULL;
    return s;
}
因此,如果第一张支票写为:

if (s == NULL && p == NULL)
if(s == NULL)
{
    if(p == NULL)
        return NULL;

    s = p;
}
...
还是说它是这样写的有什么原因

最后:
返回p=NULL
;这仅仅是以下内容的简写:

p = NULL;
return p;

因此,如果第一张支票写为:

if (s == NULL && p == NULL)
if(s == NULL)
{
    if(p == NULL)
        return NULL;

    s = p;
}
...
p
为空时,为是。如果
p
不为空,则为否。因为这样就不会发生
s=p
的副作用。当
if
语句为false时,稍后将使用该值
s

最后:返回p=NULL;这仅仅是以下内容的简写:

p = NULL;
return p;

实际上与

if (s == NULL && p == NULL)
虽然它们的结果相同,但当
s
p
NULL

您已经正确地标识了必须传递后续调用的
strtok
使用
NULL
,但是如果仍要返回令牌,
p
将不运行 测试
NULL

因此,
((s=p)==NULL)
是一个聪明的技巧,可以将
s
指定给 字符串的其余部分,其中可能会找到更多标记

在C中,当您计算像
A和&B
这样的表达式时,
A
将被计算,而
B
获取仅当且仅当
A
的计算结果为true时的计算结果,以及 这是我的

如果
s
不是
NULL
,则从不计算
((s=p)==NULL)
s=p
是 从未分配

如果
s
NULL
,则对
((s=p)==NULL)
进行计算。第一个
s=p
是 已评估,这是一项作业。如果
p
不是
NULL
,则
s
指向 当
p
指向(源的其余部分)时,与
NULL
相比,它 计算结果为false,因此不会执行返回NULL的
,并且函数
继续寻找代币

但是,如果
p
也是
NULL
s
被设置为指向
NULL
,并且在比较时 对于
NULL
它的计算结果为true,如果
的计算结果为true,则执行整个
返回NULL
。当
s
最初为
NULL
p
NULL
时 表示已找到并返回所有令牌,因此函数应返回
NULL
。它可以重写为:

if (s == NULL && p == NULL)
if(s == NULL)
{
    if(p == NULL)
        return NULL;

    s = p;
}
...
请注意,赋值的值是赋值本身的值

return a = b;
和做同样的事

a = b;
return b;

如果您只是在学习C,请尽量不要在
If
条件下做作业。我同意,我有很好的
python
经验,我在
python
中没有看到或使用过太多这一点——这就是为什么我第一次阅读此实现时会感到害怕的原因。即使按照C标准,这也是一些异常丑陋的代码,所以这段代码的作者当然不是为了清晰。这是一个很好的答案,但是上面的解释非常好!回答得好!下面是我现在拥有的:在第一次调用时
s+=strspn(s,sep):如果找到
sep
,则
s
指针将移动
1
。然后
p=s+strcspn(s,sep)
p
设置为
s
中的分隔符之后。所以第二次调用
p
不为空。但是在第二次调用中,
s
被设置为
p
,这是在上一次调用中设置的。So
s+=strspn(s,sep)实际上是
p+=strspn(p,sep)s=p
发生在第二次调用中,当
s
为空时;