C fgets实施(K&R)

C fgets实施(K&R),c,pointers,C,Pointers,我是编程新手,从Objective-C开始,但决定在继续前进之前回到基础。我花了一些时间在C上,正在努力克服指针的混乱。我的问题是关于K&R说fgets是如何实现的(第165页,第二版)。下面的代码直接来自文本,并附带了我的一些评论 char* fgets(char* s, int n, FILE *iop) { register int c; register char* cs; cs = s; while(--n > 0 && (c =

我是编程新手,从Objective-C开始,但决定在继续前进之前回到基础。我花了一些时间在C上,正在努力克服指针的混乱。我的问题是关于K&R说fgets是如何实现的(第165页,第二版)。下面的代码直接来自文本,并附带了我的一些评论

char* fgets(char* s, int n, FILE *iop)
{
    register int c;
    register char* cs;
    cs = s;

    while(--n > 0 && (c = getc(iop)) != EOF)
    {
    // put the input char into the current pointer position, then increment it
    // if a newline entered, break
    if((*cs++ = c) == '\n')
        break;          
    }

    *cs = '\0';
    return (c == EOF && cs == s) ? NULL : s;
}
1) 我们将char*s传递给fgets函数,在该函数的位置存储用户输入。为什么需要声明本地字符*cs-然后将其初始化为s?为什么我们不能在if语句中直接操作/添加到?鉴于cs被初始化为点s,向cs添加字符不是完全一样吗

2) 当函数返回时,将进行测试以查看cs==s。为什么这是必要的


我想我可能遗漏了一些非常基本的东西——我确实检查了SO和谷歌,但还没有完全弄清楚。谢谢

这是因为最后一行的检查,
cs==s
。此比较将检查修改后的指针
cs
与原始的
s
是否读取了任何字符。如果没有,则返回NULL

通过在整个原始指针中使用
cs
,将保留
s
。如果直接操纵
s
*s++
而不是
*cs++
),那么我们必须找到另一种方法来检查是否读取了任何字符


人们还可以说,最好不要使用函数参数,而是将它们当作
const
。一些程序员遵循这种做法来提高代码的清晰度。

“从Objective-C开始,但决定在进一步开发之前回到基础”-非常好,每个初学者都应该这样做。我刚刚开始觉得我在Obj-C中迈出了一大步。自从回到C之后,我感觉自己又像一个十足的傻瓜,但是,尽管我不断地碰触分割错误和奇怪的程序行为,这绝对是值得的,绝对是值得的。掌握C对于理解Objective-C是不可避免的。非常感谢John。这使得意图更加清晰,但如果可以的话,还有几个问题……当“cs”被赋值为“cs=s”时,我发现指针现在指向的是完全相同的内存区域;因此,执行“*cs++”将完全等同于“*s++”。这个假设错了吗?对不起,我的评论超时了,我的评论标记也错了。。。。这就是为什么我不明白最后一句话的原因。我认为既然两个指针都是“共享的”,那么当计算c==cs表达式时,它们将是相同的。提前谢谢。@Gasman 14作业结束后,他们指向同一地址,没错<代码>*cs++不会修改
s
。确保您了解优先级:
*cs++
等于
*(cs++)
而不是
(*cs++
cs++
递增
cs
,使其指向下一个地址,然后
*
解除对该地址的引用
s
不会更改,因为
s
cs
是两个独立的变量。如果语句是
(*cs)+
,则会更改
*s
的值。(请注意,不是
s
,而是
*s
)感谢您的帮助John。如果
n
为1,则不读取任何输入,
fgets
将第一个字符设置为
'\0'
,并立即返回。字符串始终以null结尾。只有在有空间的情况下,换行符才会留在末尾;否则,新行将保持未读状态,以供下次I/O调用提取<无法更改代码>fgets,因为它是标准C库的一部分。现在改变它的行为已经太晚了。数以百万计的程序期望它以这种方式运行。