【问题标题】:int c = getchar()?int c = getchar()?
【发布时间】:2011-10-30 11:21:45
【问题描述】:

好的,我正在阅读这本书:The C Programming Language - Kernighan 和 Ritchie(第二版),其中一个示例让我无法理解事物的工作原理。

#include <stdio.h>

#define MAXLINE 1000

int getline(char line[], int maxline);
void copy(char to[], char from[]);

int main(int argc, char *argv[])
{
    int len;

    int max;
    char line[MAXLINE];
    char longest[MAXLINE];

    max = 0;
    while((len = getline(line, MAXLINE)) > 1)
    {
        if(len > max)
        {
            max = len;
            copy(longest, line);
        }
    }
    if(max > 0)
        printf("%s", longest);

    getchar();
    getchar();
    return 0;   
}

int getline(char s[], int lim)
{
    int c, i;

    for(i = 0; i < lim - 1 && (c = getchar()) != EOF && c != '\n'; ++i)
        s[i] = c;
    if(c == '\n')
    {
        s[i] = c;
        ++i;     
    }
    s[i] = '\0';

    return i;
}

void copy(char to[], char from[])
{
    int i;

    i = 0;
    while((to[i] = from[i]) != '\0')
        ++i;
}

线路:for(i = 0; i &lt; lim - 1 &amp;&amp; (c = getchar()) != EOF &amp;&amp; c != '\n'; ++i) 它说c = getchar(),如何从命令行输入整数=字符?整数是的,但是我输入的字符是如何存储的?

提前致谢

【问题讨论】:

标签: c getchar


【解决方案1】:

现在让我们来玩一个逻辑游戏。

char 也是一种整数类型,它的范围比 int 更小,更具体地说是 8 位,即 1 个字节。众所周知,整数类型包括有符号(默认)和无符号。至于char,有符号的范围是-127~128,无符号的范围是0~255。现在我们知道有符号和无符号字符的类型和“能力”了。

我们人类理解字符,而计算机只识别二进制序列。因此各种程序设计语言都必须提供一个模型来处理从字符到二进制序列的转换。 ASCII 码是应用于 C 和许多其他编程语言的映射标准。编码 0-9、a-z 和 A-Z 等基本字符以及通常的特殊字符需要 0 - 255。

您可能想知道 unsigned char 是正确的选择。但是,编程应该知道何时停止。最简单的方法是满足特殊值,负值是一个不错的选择,因为更大的正值可能用于其他语言。最后,C选择了-1,也就是通常所说的EOF。

现在我们明白了。带符号的 char 不足以编码 ASCII 字符,而无符号则没有为终止值留下空间。我们需要更大的范围来平衡这一点,也就是 int 类型。萨维?

感谢@cdhowie 的回答,真的让我很兴奋。

【讨论】:

    【解决方案2】:

    getchar() 函数返回一个整数,表示输入的字符。如果您输入字符A,您将返回'A'0x41(升级为int,当然假设您使用的是ASCII 系统)。

    它返回 int 而不是 char 的原因是因为它需要能够存储任何字符加上输入流关闭的 EOF 指示符。

    而且,就其价值而言,这对于初学者来说并不是一本真正的好书。从那时起,效率比可读性和可维护性更重要。

    虽然它显示了 K&R 之类的公司有多么聪明,但您可能应该看看更适合新手的东西。

    无论如何,它的上一版本涵盖了 C89,并且从那时起发生了很多变化。我们经历了 C99,现在有了 C11,而且这本书还没有更新以反映其中任何一个,所以它已经过时了。

    【讨论】:

    • 但是如何在接近尾声时打印出输入的字符呢?
    • 哦,好的。所以 s[i] = c;在 for 循环中抓取每个字符并将其存储在“s”中,同时仍确保它不是 EOF 或 \n
    • 你能推荐一本现代的 C 书,它实际上有什么好处,从某种意义上说,它的严谨性接近于我们从 K&R 之类或 20 或SO 上有 30 位经常回答 C 题的人比普通教科书更正确地回答问题?
    • 我用的书没有错,Dennis Ritchie 创造了 C 语言。跟随内容是合理的。我相信随着时间的推移,我会得到这一切并理解这一切。不过老实说,这本书适合初学者。
    • 我不同意:这本书适合初学者,你应该学习如何编写可读、可维护的代码,而不是像那个例子那样不必要地复杂的单行代码。一个像样的编译器会给你相同的底层机器代码,无论你是给它那个怪物还是等价的五行像样的源代码。如果您产生类似的东西,请在您的第一次代码审查时告诉我情况如何:-)
    【解决方案3】:

    C char 类型是 8 位,这意味着它可以存储整数的范围(取决于它是否有符号,如果你不指定它,C 标准也不会规定它是什么) -128 到 127 或 0 到 255(255 个不同的值;这是 ASCII 的范围)。 getchar() 返回int,它将至少为 16 位(在现代机器上通常为 32 位)。这意味着它可以存储char的范围,以及更多的值。

    返回类型之所以为int,是因为到达输入流末尾时返回了特殊值EOF。如果返回类型是char,那么就没有办法表明遇到了流的结尾(除非它使用了一个指向记录此条件的变量的指针)。

    【讨论】:

    • C char 类型不能保证是有符号的,它没有符号也不是什么不寻常的事。例如,使用 gcc 和其他编译器的 ARM 上的默认设置。
    • 据我了解,也不能保证未签名。
    • 正确,也不能保证未签名。它保证与signed charunsigned char 之一的表示相同,因此其范围与其中之一相同。你不能肯定它是-128到127。你也不能肯定它是8位,但它是8位很时髦,例外是古老的9位主机和一些DSP芯片具有 16 位或 32 位字符。
    • 你不需要发送指针,有 feof() 和 ferror(),但遗憾的是没有它们的快速宏版本。将字符扩展为 int 只是为了能够挤入特殊的 EOF 返回值似乎是一个非常糟糕的优化选择,使 C 更加复杂和受限。像 NULL 和 '\0' 终止的字符串。 C++ 修复了 EOF/char/int 错误:您测试的是流,而不是“字符”。
    • C char 类型不能保证正好是 8 位。保证至少 8位,但CHAR_BIT可能不完全是8位。
    【解决方案4】:

    已回答您的问题。但只需再添加 1 项即可。

    当您将变量 c 声明为 int 时。很明显,您从0 to 9 获取值,其ascii 值为48-57。 因此,您可以在代码中再添加 1 行-

    c = c-48.

    【讨论】:

      【解决方案5】:

      与您可能使用过的其他一些语言不同,C 中的字符 整数。 char 只是另一种整数类型,通常为 8 位,小于 int,但仍然是整数类型。

      因此,您不需要在您可能使用过的其他语言中存在的ord()chr() 函数。在 C 中,您可以使用强制转换或仅通过分配在 char 和其他整数类型之间进行转换。

      除非出现 EOF,否则 getchar() 被定义为返回“一个无符号字符转换为 int”(same as fgetc),所以如果它帮助你可以想象它读取了一些字符,c,然后返回 @987654329 @。

      您可以通过强制转换或分配将其转换回unsigned char,如果您愿意稍微损失理论上的可移植性,您可以通过强制转换或分配将其转换为char发送到char

      【讨论】:

      • 所以在 C 中,字符和整数可以说是“相同的”。当做类似 myInt = myChar;因为有 ascii 值所以有效?
      • @Flyphe:差不多,是的。就 C 而言,字符就是它的数值。事实上,C 中的字符文字,如@9​​87654333@,具有int 类型而不是char 类型。数值并非严格必须为 ASCII,C 实现实际上允许使用另一种编码,如 EBCDIC,但您不太可能遇到这种情况。
      • 请注意,char 类型是它自己的类型:可能的最小整数类型,通常为 1 字节宽。所以它不仅用于存储 ASCII 字母,也常用于处理 0-255(无符号)或 -128 至 127(有符号)的小数字,以节省内存。如果您使用 int,您将需要 2 或 4 个字节而不是 1。
      【解决方案6】:

      在命令行中输入的每个字符(包括数字)都被读取为一个字符,并且每个字符都有一个基于其 ASCII 码 http://www.asciitable.com/ 的整数值。

      【讨论】:

      • C 标准实际上并不能保证 ASCII 是实现所使用的字符集,尽管您可能会走很长的路,可能去博物馆,才能找到不存在的 C 实现.
      • 是的,但为简单起见,我认为这是假设的
      • @Steve:错了,我们每天都在使用 EBCDIC 的机器上工作。事实上,我保证你的每一笔银行交易都会在这样一台机器上结束。久负盛名的 System z 大型机,几十年后仍在运行着地球的财务 :-)
      • @paxdiablo:很好,没有意识到。希望他们不要让人们只是走进门并开始对那些运行银行系统的特定程序进行编程。我的意思是你必须努力摆脱 ASCII,它可能不会在你不注意的时候偶然发生。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2016-04-13
      • 2022-01-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多