精华内容
下载资源
问答
  • 在看 <... 第二版时,看到1.5.1节第18页这样一段从输入拷贝到输出的代码: #include <stdio.h> /* copy input to output; 2nd version */ main() { int c; c = getchar()...

    在看 <<The C Programming Language>> 第二版时,看到1.5.1节第18页有这样一段从输入拷贝到输出的代码:

    复制代码
    #include <stdio.h>
    
    /* copy input to output; 2nd version */
    main()
    {
        int c;
        c = getchar();
        while(c != EOF){
            putchar(c);
            c = getchar();
        }
    }    
    复制代码

      直觉告诉我getchar返回值应该是char类型的,这个地方为什么不能用char类型来存储getchar()的返回值呢?

      其实文中解释的很清楚,可当时没有看明白:

      在键盘或者屏幕上的字符都是用char类型存储的,当然也可以用int类型来存储。这个地方使用int来存储字符有一个微妙但很重要的原因:为了把有效数据和输入的结束(EOF)区分开来。getchar()在没有更多输入数据时返回一个特殊值,这个值不会跟任何实际的字符混淆。这个值称为 EOF(end of file,文件结束)。我们必须把c变量声明成一个大到足够存储任何getchar()返回的值的类型。我们不能用char类型,因为c必须大到足够容纳任意可能的char还有EOF。因此我们使用int类型。

      如果你看到这里就明白了,或者早就知道原因,那可以不用接着看了。下面是我理解这个原因的思路。

      1.  getchar的函数声明

      虽然看着getchar(),直觉告诉我这应该返回char类型吧,但还是让我们看看C语言中 getchar() 的函数声明:  

    int getchar ( void );

      嗯?返回值是int?(不靠谱的直觉啊)在Linux下输入命令:man getchar(),结果更加详细:

    复制代码
        NAME
           fgetc, fgets, getc, getchar, gets, ungetc - input of characters and strings
    [...]
        DESCRIPTION
           fgetc()  reads  the  next character from stream and returns it as an unsigned char cast to an int, or EOF on
           end of file or error.
    复制代码

      这样我们就明白了,getchar()从标准输入(stdin)流中读取一个字符,把它当作一个unsigned char,然后强制转化成int类型来做为返回值,如果遇到文件末尾或者错误,返回EOF。

      2. EOF是什么

      用google搜索时,首先看到了这样的一个帖子: EOF的定义和如何有效的使用它

      EOF不是:

    •  一个char类型 (a char)
    •     不是一个在文件末尾出现的值 (a value that exists at the end of a file)
    •     不是一个可能在文件中间出现的值(a value that could exist in the middle of a file)

      C99标准规定(见 7.19.1 Introduction):  

    EOF
        which expands to an integer constant expression, with type int and a negative value, that
    is returned by several functions to indicate end-of-file,that is, no more input from a
    stream;

      好,我们明白了 EOF 是一个宏,展开后为一个整型常量表达式(integer constant expression),是int类型(C语言中整数常量是int类型的),而且值是负值。一些函数用它作为返回值,表示流中没有更多的输入。

      让我们去定义它的头文件<stdio.h>中去看看:  

    #define EOF     (-1)

      那么 EOF 在计算机中十六进制表示形式是 0xFFFFFFFF(有符号数在计算机中是一般用补码(two's-complement)表示)。通过getchar函数的定义,我们知道getchar() 从标准输入(stdin)流中读取一个unsigned char类型的字符0xXX,然后强制转化成int 类型 0x000000XX(对无符号数,进行零扩展),此时这个值是大于等于零的。

      所以,EOF(0xFFFFFFFF)不可能出现在文件中间(文本文件中),它与字符(character)是截然不同的值。

      3.使用char类型存储getchar()这类函数的返回值  

    复制代码
    /* copy input to output; 2nd version */
    main()
    {
        char c;
        c = getchar();
        while(c != EOF){
            putchar(c);
            c = getchar();
        }
    }    
    复制代码

      上述这段代码中,c = getchar(); 会将getchar()的返回值int强制转化为char类型,就将32位的int截断为8位的char。之后的 c != EOF,又会将c强制转化为int类型,就将8位的char类型进行扩展,扩展为32位int类型。在扩展时,如果char类型为无符号数,进行零扩展,如果char类型为有符号数,进行符号扩展。下面的两个表分别展示了上面的这两个转换过程。为了制表方便,假设int是16位。  

    复制代码
    ---------------------------------      ----------------------------------------------
    |    int到char转化(截断)                |      |              char到int转化(扩展)      |
    ---------------------------------      ----------------------------------------------
    | 十进制   |  int        |  char |      |  char |unsigned char=>int| signed char=>int|
    |---------|-------------|-------|      |-------|------------------|-----------------|
    |  2      |00 00 00 02  |  02   |      |  02   |  00 00 00 02     |00 00 00 02      |
    |  1      |00 00 00 01  |  01   |      |  01   |  00 00 00 01     |00 00 00 01      |
    |  0      |00 00 00 00  |  00   |      |  00   |  00 00 00 00     |00 00 00 00      |
    | EOF(-1) |FF FF FF FF  |  FF   |      |  FF   |  00 00 00 FF     |FF FF FF FF      |
    |  -2     |FF FF FF FE  |  FE   |      |  FE   |  00 00 00 FE     |FF FF FF FE      |
    --------------------------------       ----------------------------------------------
    复制代码

      可见,如果char是无符号的,那么上面那段代码中,当getchar()返回EOF时,c!=EOF 条件仍然满足。此时程序不能正常终止。

      大家能不能自己写代码验证一下C语言中从char到int的、int到char的强制类型转化呢?

     PS:

      MSVC中char类型默认是有符号的char类型,可以在编译时加入 /J 参数来把默认的char类型从signed char 改变到 unsigned char

      gcc中,char类型默认也是有符号的,可以在编译时加入参数 -funsigned-char 或者 -fsigned-char 来指定char的符号类型。

    参考资料:

      深入理解计算机系统 第二章 2.2 整数表示

     

    转自:http://www.cnblogs.com/Jack47/archive/2012/12/23/2819111.html

    转载于:https://www.cnblogs.com/loongqiang/p/3561093.html

    展开全文
  • c语言中的return 0有什么用?

    千次阅读 多人点赞 2020-03-03 13:55:34
    c语言中的return 0有什么用? 用return这种形式就能定义返回值, return 0可以 终止 main() 函数,并返回值 0。 return 0 代表程序正常退出,return 1代表程序异常退出! 使用return 语句可以返回一个变量内的值或一个...

    C语言为什么要return 0(个人看法)

    c语言中的return 0有什么用?

    用return这种形式就能定义返回值, return 0可以 终止 main() 函数,并返回值 0。
    return 0 代表程序正常退出,return 1代表程序异常退出!
    使用return 语句可以返回一个变量内的值或一个指针,也可用return0,表示返回为空。
    return 代表调到函数外,
    return 0代表函数正常终止
    return 1代表函数非正常终止
    而我觉得还有一个作用就是return之后你至少知道代码成功运行到最后一行,中间没有异常中止,并且return 关键字的还有一个作用是返回程序流程的控制权!其副作用是返回一个值。

    展开全文
  • 麻烦看下我函数里边的注释,即我直接string1做返回值,而不用string。返回的结果不一样。这里个疑问,string2不是已经被存在string1里面了吗,为什么还要string? 代码如下: #include char *strncpy(char *, ...
  • 在C里,malloc动态分配内存时,是不推荐强转其返回值的。例如 int *arr = malloc(sizeof(int) * 5); 而不是 int *arr = (int *)malloc(sizeof(int) * 5); 为什么呢?原因2: 1. C里面从void *到其它...
    在C里,用malloc动态分配内存时,是不推荐强转其返回值的。例如
    int *arr = malloc(sizeof(int) * 5);

    而不是
    int *arr = (int *)malloc(sizeof(int) * 5);

    为什么呢?原因有2:

    1. C里面从void *到其它类型的指针是自动转换的。例如
    int n = 1;
    int *pn = &n;
    void *pv = pn;
    int *pn2 = pv;
    这里并不需要任何强制类型转换。

    2. 在旧式的C编译器里,如果一个函数没有原型声明,那么编译器会认为这个函数返回int。那么,如果碰巧代码里忘记包含头文件<stdlib.h>或者<malloc.h>,那么编译器看到malloc调用时,会认为它返回一个int。

    在实际运行时,malloc的返回值(一个void*指针),会被直接解释成一个int。如果这时强制转换这个值,实际就是将int直接转换为(void*)。这里有2个问题:a) (void*)和int可能不能“无损”地相互转换,例如它们长度压根就不同,或者编译器就不支持这种转换。b) 即使可以相互转换,它们的表示也可能不同,即需要显示转换。而直接将(void*)当成int来用,然后再把这个int转换回(void*),在这种情况下肯定是会有问题的。

    如果这时没有强转malloc的返回值,编译器看到要把int转换为(int*),就会发出一条警告。而如果强转了malloc的返回值,编译器就不会做警告了。在运行时就可能出问题。





    使用 malloc 函数,请包含 stdlib.h(C++ 中是 cstdlib),而不是 malloc.h .因为 malloc.h 从来没有在 C 或者 C++ 标准中出现过!因此并非所有编译器都有 malloc.h 这个头文件。但是所有的 C 编译器都应该有 stdlib.h 这个头文件。

        在 C++ 中,强制转换 malloc() 的返回值是必须的,否则不能通过编译。但是在 C 中,这种强制转换却是多余的,并且不利于代码维护。

        起初,C 没有 void 指针,那时 char* 被用来作为泛型指针(generic pointer),所以那时 malloc 的返回值是 char* .因此,那时必须强制转换 malloc 的返回值。后来,ANSI C(即C89) 标准定义了void 指针作为新的泛型指针。void 指针可以不经转换,直接赋值给任何类型的指针(函数指针除外)。从此,malloc 的返回值变成了 void* ,再也不需要强制转换 malloc 的返回值了。以下程序在 VC6 编译无误通过。
      #include <stdlib.h>
            int main( void )
            {
                double *p = malloc( sizeof *p ); /* 不推荐用 sizeof( double ) */
                free(p);
                return 0;
            }
     


        当然,强制转换malloc的返回值并没有错,但画蛇添足!例如,日后你有可能把double *p改成int *p.这时,你就要把所有相关的 (double *) malloc (sizeof(double))改成(int *)malloc(sizeof(int))。如果改漏了,那么你的程序就存在 bug .使用以下代码,无论以后指针改成什么类型,都不用作任何修改。

        double *p = malloc( sizeof *p );

        类似地,使用 calloc ,realloc 等返回值为 void* 的函数时,也不需要强制转换返回值。


    展开全文
  • c语言中的return 0有什么用

    万次阅读 多人点赞 2018-02-01 11:42:05
    return 0是正常退出,return 非零是异常... main()可以不用返回值。 记得return 接的是一个表达式,可以是一个立即数,一个变量,一个计算式,前面我们就看到 return a+b;的例子。 return 甚至也可以接一个函数。

    return 0是正常退出,return 非零是异常退出,这是返回给控制台的,不在编的程序的控制范围内,是给操作系统识别的,对你的程序无影响。如果是C中,定义void main()可以不用返回值。

    记得return 接的是一个表达式,可以是一个立即数,一个变量,一个计算式,前面我们就看到 return a+b;的例子。 return 甚至也可以接一个函数。


    展开全文
  • 前言 因为C语言中文网中第7章是C语言函数,01表示这一章的第一篇...2、的人说:这是死记概念,没什么用。 3、博雅觉得:我是从面试的过程中才悟出了这个作用,因为你编写编写一个函数的时候,功能除外,你首要考...
  • 返回值,这个返回值是和函数的类型有关的,函数的类型是什么,他的返回值就是什么 比方主函数int main() {}这里就必须一个return,只有void时可以不用返回值。 功能函数 int fun() { return 1; } 这个时候fun...
  • 目录 1. C 语言中的指针和内存泄漏 5 2. C语言难点分析整理 10 3. C语言难点 18 4. C/C++实现冒泡排序算法 32 ...83. C语言有头结点链表的经典实现 419 84. C语言惠通面试题 428 85. C语言常用宏定义 450
  • 事实上,C语言函数用什么样的返回值表示成功或者失败,只是一种人为的约定,函数的调用者遵守这个“约定”就可以了。 不过,对于一般的函数,大多数C语言程序员常常使用返回值 0 表示成功,非零值表示失败。因此...
  • 数据结构有没有什么简洁,标准的C语言源码实现参考下! 还有就是我看到很多数据结构的书都在实现操作...很奇怪这些返回值有什么用? 直接printf出操作结果不更直观吗? 很多人的主函数里也都没把这些返回值用上。
  • C语言错误处理

    千次阅读 2019-01-13 19:59:58
    C语言错误处理 1、什么是错误处理? 程序错误是指在软件运行中因为程序本身错误而造成的功能不正常、死机、数据...C程序员没有异常机制,一般用返回值标识错误,判断返回值进行错误的处理。 2.1 返回值表示出...
  • // Status 是函数返回值类型,其值是函数结果状态代码。 #define OK 1 #define ERROR 0 #define OVERFLOW -2 #define List_Init_Size 100 //线性表存储空间初始分配量 #define Listincerment 10 //线性表存储...
  • 编写多个返回值的函数是所有C语言教材里均没有提到的知识点,但在实际教学与应用的过程中我们都可能会遇到这样的问题。学生也尝试了不少方法:如把多个需要返回的值作相应的处理后变成一个可以return语句...
  • C语言编程要点

    2017-09-18 00:10:37
    9.8. 为什么用const说明的常量不能用来定义一个数组的初始大小? 145 9.9. 字符串和数组有什么不同? 145 第10章 位(bit)和字节(byte) 147 10.1. 用什么方法存储标志(flag)效率最高? 147 10.2. 什么是“位屏蔽(bit ...
  • 高级C语言详解

    2012-08-18 09:49:27
    目录 1. C 语言中的指针和内存泄漏 5 2. C语言难点分析整理 10 3. C语言难点 18 4. C/C++实现冒泡排序算法 32 ...83. C语言有头结点链表的经典实现 419 84. C语言惠通面试题 428 85. C语言常用宏定义 450
  • C语言编程练习

    2019-12-06 22:30:32
    一、问题描述 5位运动员参加了10米台跳水比赛,人让他们预测比赛结果;...每个人说对了一半,因此逻辑操作符可以进行判断,还要注意逻辑操作符返回值什么,当逻辑为真,返回值为1,逻辑为假,返回...
  • 免费下载:C语言难点分析整理.doc

    千次下载 热门讨论 2012-02-29 15:30:53
    1. C 语言中的指针和内存泄漏 5 2. C语言难点分析整理 10 3. C语言难点 18 4. C/C++实现冒泡排序算法 32 ...83. C语言有头结点链表的经典实现 419 84. C语言惠通面试题 428 85. C语言常用宏定义 450
  • c语言学习笔记_4

    千次阅读 热门讨论 2021-05-20 16:49:17
    函数就是在c语言当中对一段代码的封装,它负责完成某项特定的任务,具备相对的独立性,一个函数一般会输入的参数和函数的返回值,提供对过程的封装和细节的隐藏。 2.c语言中函数的分类 2.1库函数 库函数的存在意义...
  • C语言难点分析整理

    2013-07-19 15:09:14
    目录 1. C 语言中的指针和内存泄漏 5 2. C语言难点分析整理 10 3. C语言难点 18 4. C/C++实现冒泡排序算法 32 ...83. C语言有头结点链表的经典实现 419 84. C语言惠通面试题 428 85. C语言常用宏定义 450
  • //author hernoforgot//本次简单模拟栈和队列的操作,其中大多数我以无返回值实现,如果考虑优化和特殊情况,可稍微修改//建议使用笔画一下操作流程,可以有助于您理解//如果有错,或者有什么意见,欢迎留言,...
  • C语言》关于return

    2018-10-09 20:43:37
    return和return 0 有什么区别? return返回值为void类型的函数中,在执行到某种状态时不需要再执行后续代码了就return直接结束函数的执行返回至主调函数。 return 0返回值为int类型(以及兼容的类型)的...
  • C++中这么一种特殊的函数,它在类里,与类名同名,且没有返回值的一个函数,只要我们定义一个类的对象,系统就会自动调用它,进行专门的初始化对象,而大多数情况下,因为我们没有定义构造函数,系统会默认生成...
  • C语言链表2

    2021-06-01 15:07:41
    (1)只能头指针,不能各个节点自己的指针。因为在实际当中我们保存链表的时候是不会保存各个节点的指针的,只能通过头指针来访问链表节点。 (2)前一个节点内部的pNext指针能帮助我们找到下一个节点。 2.2、将创建...
  • C语言中的sizeof是一个很有意思的关键字,经常不对,搞不清不是什么。我以前也有用错的时候,现在写一写,也算是提醒一下自己吧。  sizeof是什么 sizeof是C语言的一种单目操作符,如C语言的其他操作符++、–...
  • 简单讲,就是一个函数前面用virtual声明的函数,一般形式如下:virtual 函数返回值 函数名(形参){函数体}那它有什么用呢? 虚函数的出现,允许函数在调用时与函数体的联系在运行的时候才建立,即所谓的动态联编。...

空空如也

空空如也

1 2 3 4 5 ... 10
收藏数 190
精华内容 76
关键字:

c语言返回值有什么用

c语言 订阅