2013-05-06 92 views
8

我新的编程,启动了与Objective-C的,但已经决定回到基础进一步进展之前。我花了一些时间在C上,并且正在通过指针混淆挣扎。我的问题是关于如何实现fgets的K &(p165,第二版)。下面的代码是直接从我的几条评论的文本。与fgets实现(K&R)

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功能,在其位置,我们存储用户输入。为什么需要声明本地char * cs - 然后将其初始化为s?为什么我们不能在if语句中直接操作/添加到s?看到cs被初始化为s,是不是将cs添加到完全相同的东西?

2)与上述系杆在...在函数返回时,进行测试以查看是否CS ==秒。为什么这是必要的?

我想我可能会丢失一些非常基本的 - 我这样做了检查和谷歌,但不能完全弄清楚。谢谢!

+2

“从Objective-C开始,但决定在进一步发展之前回到基础知识” - 非常好,**每个初学者都应该这样做。** – 2013-05-06 11:31:57

+1

我刚开始觉得我正在步步为营在Obj-C中。自从回到C后,我再次感受到了一个完整的klutz,但是尽管我反复敲打了分段故障和奇怪的程序行为,但这绝对值得。 – drjimmie1976 2013-05-06 18:13:39

+0

这是最值得的。掌握C对于理解Objective-C是不可避免的。 – 2013-05-06 18:28:03

回答

7

这是因为在最后一行,cs == s的检查。该比较检查修改的指针cs与原始s以查看我们是否读过任何字符。如果我们没有,那么我们返回NULL。

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

人们也可以说,这是一个很好的做法,独自离开函数的参数,并把它们作为const。一些程序员遵循这种做法来提高代码清晰度。

+0

非常感谢约翰。这使得意图更清楚,但是如果我可以再提几个问题......当'cs'被赋予'cs = s'时,我认为指针现在指向完全相同的内存区域;因此执行'* cs ++'将完全等同于'* s ++'。这个假设是错误的吗? – drjimmie1976 2013-05-06 17:46:57

+0

对不起,我的评论超时了,我也做了评论标记错误....这就是为什么我不明白最后一行。我认为看到两个指针是“共享”的,那么当c == cs表达式评估时它们将是相同的。提前致谢。 – drjimmie1976 2013-05-06 17:54:52

+0

@ GasMan14他们在作业后指向同一地址,这是正确的。不过,'* cs ++'不会修改's'。确保你理解优先级:'* cs ++'等于'*(cs ++)'而不是'(* cs)++'。 'cs ++'递增'cs',使其指向下一个地址,然后'*'解引用该地址。 's'没有改变,因为's'和'cs'是两个独立的变量。如果语句是'(* cs)++',那么*会*改变'* s'的值。 (请注意,不是''',而是'* s'。) – 2013-05-06 23:00:36