V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
V2EX 提问指南
coderluan
V2EX  ›  问与答

一个专科的 C 语言期末考试题,我居然不知道咋做。

  •  
  •   coderluan · 2017-07-03 17:08:40 +08:00 · 5345 次点击
    这是一个创建于 2700 天前的主题,其中的信息可能已经有所发展或是发生改变。

    https://ws2.sinaimg.cn/large/006Svwogly1fh6t12pt42j30ti0sfq4v.jpg

    原谅我标题党,朋友发的,出题者口口声声说这是书上找的,肯定不会错,专科生中能干好这一行的也是不容易。

    第 1 条附言  ·  2017-07-03 18:50:24 +08:00
    吐槽贴变成了讨论帖(虽然槽点还在),感谢大家热心的回复。
    这次是我有点想当然了,看见不常见的写法,在 gcc 上没过,就认为别的编译器都过不了。
    58 条回复    2017-07-05 02:37:22 +08:00
    lany
        1
    lany  
       2017-07-03 17:17:10 +08:00
    瞎了我的眼
    jinhan13789991
        2
    jinhan13789991  
       2017-07-03 17:24:08 +08:00
    没毛病啊,专科的教材都是 2005 年左右的。有些错误页很正常嘛
    ThatIsFine
        3
    ThatIsFine  
       2017-07-03 17:24:19 +08:00
    一个艹字头飞向太空
    mscb
        4
    mscb  
       2017-07-03 17:26:34 +08:00 via Android
    真的难吗?不会吧。除了那个从控制台输入的那个函数需要学生默写出来以外,其他的空好像不难填呀?其他 V 友怎么看
    notes
        5
    notes  
       2017-07-03 17:26:58 +08:00 via Android
    scanf("%d", a[i]) fun(a) max=a[i]
    notes
        6
    notes  
       2017-07-03 17:27:28 +08:00 via Android
    哪有错吗?
    llb123
        7
    llb123  
       2017-07-03 17:31:57 +08:00
    同没看出错误在哪,楼上各位大佬点拨一下?
    hx1997
        8
    hx1997  
       2017-07-03 17:36:34 +08:00 via Android
    除了 &a[i] 之外,不就是 5L 的答案吗。。。有什么难的??
    jarlyyn
        9
    jarlyyn  
       2017-07-03 17:40:52 +08:00
    问题在哪?
    coderluan
        10
    coderluan  
    OP
       2017-07-03 17:45:36 +08:00
    @mscb #4
    @notes #5
    @llb123 #7
    @hx1997 #8
    @jarlyyn #9

    难道 10 几年前这么写是对的?现在编译器都编译不过的。

    不是逻辑问题,是函数声明的写法,去掉逻辑,题目是:

    int main(void) {int fun(int);}
    int fun(int a[5]){}

    这代码当年是规范的?我年纪小别吓我。
    xdeng
        11
    xdeng  
       2017-07-03 17:46:16 +08:00
    第四行是什么鬼?
    zqqian
        12
    zqqian  
       2017-07-03 17:46:41 +08:00
    这个题很简单啊。。、

    没看出来哪里有问题
    coderluan
        13
    coderluan  
    OP
       2017-07-03 17:47:58 +08:00
    @zqqian #12 看 10 楼
    zqqian
        14
    zqqian  
       2017-07-03 17:48:23 +08:00
    @coderluan
    这个在 C89 标准下是没有问题的吧。。
    你用 VC6.0 编译一下试试
    xdeng
        15
    xdeng  
       2017-07-03 17:49:30 +08:00
    函数声明可以写在函数里?参数也不对吧?
    liuhaotian
        16
    liuhaotian  
       2017-07-03 17:53:59 +08:00
    除了 int fun(int); 应该改成 int fun(int*); 或者 int fun(int []); 或者 int fun(int [5]); 以外,好像没啥坑点吧...?
    xrui
        17
    xrui  
       2017-07-03 17:54:20 +08:00 via iPhone
    谭浩强那本书里就是这么写的。
    hx1997
        18
    hx1997  
       2017-07-03 17:55:26 +08:00 via Android
    @coderluan main() 那个是 K&R C 的写法,现在是不规范的。int 和 int[5] 类型都不一样,不知道算不算编译错误,回去试试。
    coderluan
        19
    coderluan  
    OP
       2017-07-03 17:56:01 +08:00
    @zqqian #14 你确定,我没 vc6,拿 gcc 设置 std 是 c89 肯定是过不去的。
    hx1997
        20
    hx1997  
       2017-07-03 17:57:04 +08:00 via Android
    @coderluan 说真的现在的考题都是抄来抄去,有这种错误很正常的。
    coderluan
        21
    coderluan  
    OP
       2017-07-03 17:57:07 +08:00
    @liuhaotian #16 你这么说就好,坑不坑都行,有错就好,上边一堆没错的弄的我胆战心惊。
    xdeng
        22
    xdeng  
       2017-07-03 17:59:42 +08:00
    vc6 报 cannot convert parameter 1 from 'int [5]' to 'int'

    原来声明可以写在函数里的,是我忘了。
    hx1997
        23
    hx1997  
       2017-07-03 18:08:41 +08:00 via Android
    @coderluan 您题目里说不知道怎么做,肯定会让我们以为是空不知道怎么填啊,自然就没注意其他的了。
    coderluan
        24
    coderluan  
    OP
       2017-07-03 18:12:48 +08:00
    @hx1997 #23

    额,我说自己是标题党了,现在这贴已经完全跑题了,我现在也只剩好奇这种写法是不是真的在哪种旧的标准下是可行的。
    hjc4869
        25
    hjc4869  
       2017-07-03 18:16:44 +08:00
    @coderluan MSVC 里写成 fun(int)没有问题(最新的也是),指针 /栈上缓冲区都可以隐式转换成 int。不过 64bit 环境下 int 是 32bit 的,代码不工作。

    如果考题或者教材里说过环境是 MSVC 的话,这个也不算错吧?毕竟 C 语言那么混乱,根本没个事实上的统一标准……
    xrui
        26
    xrui  
       2017-07-03 18:17:16 +08:00
    很不理解,本来就没错啊。函数定义在 main 函数里的办法就是书上写的呀?谭浩强都这么写,有什么错?照着书出了这个题有什么问题?楼主是不相信书上这么写过吗?
    coderluan
        27
    coderluan  
    OP
       2017-07-03 18:21:38 +08:00
    @hjc4869 #25 单独写 fun(int)没问题,但是后面 int fun(int a[5])这个暂时没发现能过的编译器。

    其实这个贴是吐槽贴的,无论是错的还是过时的,都是不影响吐槽的,但是现在已经彻底歪楼成考古帖了。
    hx1997
        28
    hx1997  
       2017-07-03 18:23:46 +08:00 via Android
    @xrui hhhh,高级黑,不过那叫声明吧。
    xrui
        29
    xrui  
       2017-07-03 18:24:26 +08:00 via iPhone
    @hx1997 口误😂
    coderluan
        30
    coderluan  
    OP
       2017-07-03 18:24:33 +08:00
    @xrui #26 尽信书不如无书,何况是谭浩强的书,你想说明没错给我找一个能编过去的编译器的就行。
    hjc4869
        31
    hjc4869  
       2017-07-03 18:25:13 +08:00   ❤️ 1
    @coderluan 既不是错的也不是过时的,VS2017 都能编译
    coderluan
        32
    coderluan  
    OP
       2017-07-03 18:25:32 +08:00
    @xrui #26 你是高级黑,黑谭浩强吗?是的话原谅我没看出来。
    hitmanx
        33
    hitmanx  
       2017-07-03 18:27:52 +08:00
    @coderluan

    #include <stdio.h>

    int func(int a[5])
    {
    return a[0] + a[1];
    }

    int main()
    {
    int a[5];
    a[0] = 3;
    a[1] = 7;
    printf("%d\n", func(a));

    return 0;
    }



    $g++ 1.cpp -o 1
    $./1
    10
    ThatIsFine
        34
    ThatIsFine  
       2017-07-03 18:28:38 +08:00
    @liuhaotian You are right.

    贴出来, 大家可以试一下
    #include <stdio.h>

    main(){
    int a[5];
    int max,i;
    int fun(int a[]);// 或 int fun(int*);

    printf("请输入 5 个数字:");
    for(i=0;i<5;i++){
    scanf("%d", &a[i]);
    }

    max=fun(a);
    printf("%d",max);

    }

    int fun(int a[5]){

    int max,i;

    max=a[0];
    for(i=1;i<5;i++){
    if(a[i]>max){
    max = a[i];
    }
    }

    return max;
    }
    hjc4869
        35
    hjc4869  
       2017-07-03 18:31:09 +08:00
    MSVC 下连这么玩都能过编译

    #include <stdio.h>

    int fun(void);
    int fun(int);
    int fun(long long);
    int fun(float);
    int fun(double);
    int fun(void*);
    int fun(anything);
    int fun(struct does_not_even_exist);

    int main() {
    int test[5] = { 1,2,3,4,5 };
    int fun(int);
    printf("%d", fun(test));
    return 0;
    }

    int fun(int a[5]) {
    return a[0] + a[1] + a[2] + a[3] + a[4];
    }
    coderluan
        37
    coderluan  
    OP
       2017-07-03 18:41:05 +08:00
    @hjc4869 #35 VC 居然真能过,学习了,是我想当然了,gcc 没过就认为有问题了。
    coderluan
        38
    coderluan  
    OP
       2017-07-03 18:42:08 +08:00
    @hitmanx #33 你把函数声明写里面,gcc 就过不去了,g++不确定。
    hitmanx
        39
    hitmanx  
       2017-07-03 18:49:21 +08:00
    @coderluan

    写了还是可以,是我忽略了什么吗?


    $ cat 1.c
    #include <stdio.h>

    int func(int a[5]);

    int main()
    {
    int a[5];
    a[0] = 4;
    a[1] = 7;
    printf("%d\n", func(a));

    return 0;
    }

    int func(int a[5])
    {
    return a[0] + a[1];
    }

    $ gcc 1.c -o 1
    $ ./1
    11
    $ gcc -v
    ...
    gcc version 4.8.4 (Ubuntu 4.8.4-2ubuntu1~14.04.1)
    coderluan
        40
    coderluan  
    OP
       2017-07-03 18:51:59 +08:00
    @hitmanx #39

    int main(void) {int fun(int);}
    int fun(int a[5]){}

    你的 fun 的声明放外面了。
    coderluan
        41
    coderluan  
    OP
       2017-07-03 19:05:10 +08:00
    @hjc4869 #31 亲,你是试的,还是有啥知识,目前 GCC/VC6/2012 过不了,2015/2017 过的去,有啥科学的说法吗?
    vingz
        42
    vingz  
       2017-07-03 19:09:42 +08:00 via Android
    函数声明问题参考十六楼
    coderluan
        43
    coderluan  
    OP
       2017-07-03 19:22:11 +08:00 via Android
    @vingc723 本来我以为是这个问题,但是目前有的编译器居然没问题。31 楼 41 楼
    vingz
        44
    vingz  
       2017-07-03 19:24:09 +08:00 via Android
    @coderluan 难道是 ansi c 和 GNU c 的区别吗?
    wevsty
        45
    wevsty  
       2017-07-03 19:30:32 +08:00
    int main(){return 0;}
    这样的写法才是标准的,不带 int 的写法,不管能不能过编译都不应该提倡。
    函数声明写函数体里面这种做法我查了一下,似乎是取决于编译器的实现,没有明确规定不可以这样做。
    顺便提一句,VS 目前对于 ANSI C 的支持并不是很标准,在 VS2015 里面,即使 fun 函数放到 main 后面并且不写声明也是可以编译过去的。
    coderluan
        46
    coderluan  
    OP
       2017-07-03 19:31:45 +08:00 via Android
    @vingc723 不知道,目前只有实验结果,没啥资料根据,目前我只能理解成不同编译器的不同行为了,原因就不知道了,毕竟大家一般不会这么写代码的。
    hitmanx
        47
    hitmanx  
       2017-07-03 19:38:47 +08:00
    @coderluan

    我现在才注意到这个问题.原文里 f(int)肯定是不对的,退化完了是指针,不是数值类型.如果函数声明改成 int *,放里面还是放外面是没有区别的.
    coderluan
        48
    coderluan  
    OP
       2017-07-03 20:04:10 +08:00
    @hitmanx 你一说我也才注意 gcc 报错是这里,不过按照#25#31 的说法,VC 上是能过的,可是又不是所有的 VC 都能过#22,目前我只能理解为理解成不同编译器的不同行为了
    hjc4869
        49
    hjc4869  
       2017-07-03 23:38:50 +08:00
    @coderluan 我怀疑你在骗我.webp

    MSVC 自古以来就支持这么写
    coderluan
        50
    coderluan  
    OP
       2017-07-03 23:42:45 +08:00
    @hjc4869 我只有 2015 没问题,最开始告诉我这事的朋友是 2012,还有 22 楼的 VC6,他们说编译不过的,从个人情感上来说,我其实偏向于都能跑通,否则也太奇怪了。
    hjc4869
        51
    hjc4869  
       2017-07-03 23:47:12 +08:00
    @coderluan VC6 跑不通的是放到 .cpp 里了吧? .cpp 跟 .c 不一样,这个语法在 MS C++ 里是不正确的,但是 MS C 没有问题
    hjc4869
        52
    hjc4869  
       2017-07-03 23:48:24 +08:00
    @coderluan 22 楼 VC6 确实是 C++的输出,不是 C
    coderluan
        53
    coderluan  
    OP
       2017-07-03 23:59:59 +08:00
    @hjc4869 有可能,cpp 会调用 C++编译器,估计我朋友一个问题,这样我就顺畅很多了
    hsmocc
        54
    hsmocc  
       2017-07-04 07:27:22 +08:00 via iPhone
    除了 int fun(int *);
    lz 大惊小怪确实是因为年纪轻,至少是 90 后吧。
    zhanglintc
        55
    zhanglintc  
       2017-07-04 07:59:22 +08:00 via iPhone
    难道没人提到,双字节的双引号,编译会失败么?[doge]
    sgissb1
        56
    sgissb1  
       2017-07-04 09:28:00 +08:00
    当年的谭浩强 C 语言就是这样的写法,写法还确实一毛一样。

    对于 main 函数,啥时候用 void main,啥时候用 int main,当年的谭大师也没有说。我出来找工作的时候很多笔试题也这样,不过也有部分坑爹的会问,我就不知道了。

    记得嵌入式里面用 void main 会多一些,尤其是汇编到 c 的入口位置。具体忘记为啥了。
    int main 是后来规范后的写法,在 vc 上 void main 可以编,但是 vs 2010 之后就不晓得了。。。。。
    coderluan
        57
    coderluan  
    OP
       2017-07-04 09:52:22 +08:00
    @hsmocc #54 确实年纪小,没见过这种写法,但发这个贴也不是大惊小怪,就是想吐槽下专科老师,他确实没考虑楼上讨论的各种问题,不过这楼已经彻底的歪了。歪的挺好,我也学到了些奇怪的姿势,但是希望将来用不到他们。
    gnaggnoyil
        58
    gnaggnoyil  
       2017-07-05 02:37:22 +08:00
    @sgissb1 从 C89 开始 C 语言标准就从来没保证实现一定支持返回 void 的 main 函数.从 C99 开始标准保证实现一定支持 int main(void)和 int main(int, char **)两种声明.

    顺便说下 main 的返回值不是 int 这种情况在 C++中从 C++98 开始就没合法过.
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   2640 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 33ms · UTC 05:06 · PVG 13:06 · LAX 21:06 · JFK 00:06
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.