C 语言 数组 指针 函数问题,还请不吝赐教 - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
drlalll
V2EX    C

C 语言 数组 指针 函数问题,还请不吝赐教

  •  
  •   drlalll 2017-02-27 22:06:09 +08:00 3124 次点击
    这是一个创建于 3214 天前的主题,其中的信息可能已经有所发展或是发生改变。

    Q :编写一个函数可以将 A 数组和 B 数组的每个元素一一相加赋予 C 数组。


    //c primer plus 第十章课后习题 10.13.9 p218 #include<stdio.h> #define num 4 void sum(int n,int n1,int n2,int ar[],int br[],int cr[]); //函数声明 , ar 和 br 的每一个元素相加存储到 cr 的每个对应元素中 void p(int n,int ar[]); //函数声明,打印一个数组的每个元素 int main(void) { int ar[num] = {1,2,3,4}; int br[num] = {2,3,4,5}; int cr[num]; p(num,ar); putchar("\n"); p(num,br); putchar("\n"); sum(num,num,num,ar,br,cr); p(num,cr); } void sum(int n,int n1,int n2,int ar[],int br[],int cr[]) //函数原型 , ar 和 br 的每一个元素相加存储到 cr 的每个对应元素中 { int a; for(a = 0;a < n;a++) { cr[a] = ar[a] + br[a]; } } void p(int n,int ar[]) //函数原型,打印一个数组的每个元素 { int a; for(a = 0;a < n;a++) { printf("%d",ar[a]); } } 

    ###此函数可以实现 3 个一维数组都有相同数量元素下的运算,请问如果 ar[]或者 br[]元素数不同时要如何进行运算?假设 ar[4] = {...},br[5] = {...} 那么当 ar[4] + br[4]时 ar[4]越界为不确定值,那么此时应该理解为 0 + br[4]吗?函数如何写那?

    16 条回复    2017-02-28 10:08:31 +08:00
    drlalll
        1
    drlalll  
    OP
       2017-02-27 22:08:25 +08:00
    还请对 C 语言有研究的同学指点指点!谢谢!!
    drlalll
        2
    drlalll  
    OP
       2017-02-27 22:45:16 +08:00
    请问一下是 什么原因导致大家不太想回答我的问题 ?是我的 标题写的不够标准 还是 内容太长读起来太费力 或者说 代码写的不标准 亦或者 提问中含有低级错误和常识性错误 ?因为还没入门所以可能有些错误我自己意识不到希望大家能提点提点,我在以后的发表的主题中会尽量避免这些问题,谢谢!!
    franklinyu
        3
    franklinyu  
       2017-02-27 22:49:42 +08:00
    你期望什果?我得「不足 0 」、「多的扔掉」和「」都是合理的
    franklinyu
        4
    franklinyu  
       2017-02-27 22:52:05 +08:00
    外,三函的定之隔空行吧,好看一。另外定的宏最好用大,像「 NUM 」。
    franklinyu
        5
    franklinyu  
       2017-02-27 23:00:57 +08:00
    另外在行末的整代很,建在函明的前面。在函定那就必要再一次了。

    我人喜的是的:

    // 文件做了些和那些……
    <空行>
    #include <foo_lib.h>
    #define BAR_NUMBER 1
    <空行>
    // 行某任
    void do_foo(int bar_count);
    // 入字符串足某件
    int test_bar(int name_len, char[] len);
    <空行>
    int main()
    {
    // 函主
    return 0;
    }
    <空行>
    void do_foo(int bar_count)
    {
    // 函主
    }
    <空行>
    int test_bar(int name_len, char[] len)
    {
    // 函主
    return TRUE;
    }
    visionsmile
        6
    visionsmile  
       2017-02-27 23:57:12 +08:00
    数组下标越界是 undefine behavior.
    >An array subscript is out of range, even ifan object is apparently accessible with the given subscript (as in the lvalue expression a[1][7] given the declaration int a[4][5])

    因为是 UB ,你没办法预测会有什么结果。就算这么写结果正确(取决于你的环境)那也是不可移植的。
    visionsmile
        7
    visionsmile  
       2017-02-27 23:59:09 +08:00
    就这个题而言,我觉得一般逻辑上应该是位数不足就补零吧...
    wevsty
        8
    wevsty  
       2017-02-28 00:26:19 +08:00
    对于 C 来说,任何未指定的空间里所存放的东西都是未知的。
    不能理所当然的认为,未经过初始化的空间值都是 0 。即使有些情况下可能值确实是 0 ,也不能理所当然的这样认为。
    数组这个东西在传递的时候是传递的首地址,函数内没办法 100%准确的确定数组有多长。
    典型例子是 C 风格的字符数组。
    char sz[] = "test"
    char sz1[2] = {'t','e'}
    当 strdup 这样的函数对 sz 进行拷贝的时候,是以 test 后面的 0 值作为结尾标志终止拷贝的。 C 当中约定字符串以 0 结尾,通过字符串常量编译器会自动给字符串末尾加上 0 ,所以 sizeof(sz)得到的结果是 5 而不是 4 。
    sz1 则不同, sz1 的末尾并没有以 0 结尾,如果对 sz1 使用 strdup ,或者 strcpy 这样的函数就会出现明显的问题。 strcpy 会试图拷贝 sz1 后面的一些空间直到某一个这些空间中出现 0 值为止,至于 sz1 后面的空间什么时候会遇见 0 ,这种事情是没办法确定的。
    所以数组的处理过程中,要不然就得约定一个数组末尾的标记,要不然就必须清楚的知道数组的长度。
    msg7086
        9
    msg7086  
       2017-02-28 02:09:23 +08:00
    嗯基本就是 3 楼的做法。

    两个数组大小不同的情况下,怎么处理是「你」 楼主你来决定的。

    另外如果面试的时候遇到面试官出了这样的问题,那你要问面试官,让他来决定。(或者他会让你决定。)
    zhujinliang
        10
    zhujinliang  
       2017-02-28 04:46:02 +08:00 via iPhone
    num 大写
    n 、 n1 、 n2 写成 an 、 bn 、 cn 不更好么,如果是 an 、 bn 、 sn 、 ar 、 br 、 sr 更好
    Andiry
        11
    Andiry  
       2017-02-28 05:44:55 +08:00
    ar[4] = br[0],看看栈空间就知道了
    drlalll
        12
    drlalll  
    OP
       2017-02-28 08:04:54 +08:00
    @zhujinliang
    @Andiry
    @msg7086
    @wevsty
    @franklinyu
    明白了!谢谢大家!
    bp0
        13
    bp0  
       2017-02-28 08:5:49 +08:00 via Android
    如果是往 C 里面放,循环长度应该是 C 的长度。

    然后再循环内判断 A 和 B 是否超过自身的长度,没超取数,超的用 0 。最后相加赋值到 C 对应位置。

    为什么这么做,因为函数原型中并没有返回值。这时是无法正常返回一个错误的。所以使用 0 代替不存在的值,并完成需求。

    如果是面试,需要问面试官,长度不一致的时候如何处理。如果需要报错,则应该注意定义函数原型时需要有返回值。
    drlalll
        14
    drlalll  
    OP
       2017-02-28 08:39:01 +08:00
    @bp0
    这个不是面试题,是我看书时候的练习题。用 cr 的元素数做循环控制好像是最合理的,返回值是要返回一个 bool 值吗?还是我直接做判断当 n1 != n2 != n3 时直接打印 error ?
    谢谢提醒!
    129tyc
        15
    129tyc  
       2017-02-28 09:07:02 +08:00 via Android
    我觉得可以首先根据 n2 初始化 cr 数组,接着以 n,n1, n2 最小值为循环次数进行相加
    bp0
        16
    bp0  
       2017-02-28 10:08:31 +08:00 via Android   1
    这就要看习题上是否给原型了。如果给了,并且没有返回值。我觉得应该是使用 0 填充,不然给 3 个长度就没意义了。

    如果没给的话,我建议你想想这道题考察的是什么知识点。如果是我自己做题,我会按上面说的答。

    在面试的时候问面试官是一种面试策略,让面试官知道你考虑到这个问题而已。

    总结一下,怎么答都没错。只要检查长度,没有内存溢出就行。
    关于     帮助文档     自助推广系统     博客     API     FAQ     Solana     909 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 26ms UTC 21:47 PVG 05:47 LAX 13:47 JFK 16:47
    Do have faith in what you're doing.
    ubao msn snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86