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

C 语言中函数可以根据情况判定是按照数组处理还是按照指针处理吗?

  •  
  •   Newyorkcity · 2017-02-11 11:59:59 +08:00 · 1617 次点击
    这是一个创建于 2839 天前的主题,其中的信息可能已经有所发展或是发生改变。


    看的是C 程序设计语言,在第五章第三小节比较靠近第四小节标题的地方,看到这么一句。。
    请问根据情况判定按照数组处理,是指的什么情况?有没有可能实现传入数组名 a 之后通过 sizeof(a)来实现读到这个数组的长度呢?谢谢

    17 条回复    2017-02-13 14:21:54 +08:00
    Lonely
        1
    Lonely  
       2017-02-11 12:03:02 +08:00
    你不会敲两代码验证下?
    Newyorkcity
        2
    Newyorkcity  
    OP
       2017-02-11 12:11:45 +08:00 via Android
    @Lonely 当然试过了啊。但是我没有找到函数处理传入的数组名是当做数组处理的情况。我的办法是让他们输出那个东西的 sizeof ,但输出的全为 8 ,没有一个是数组长度。
    am241
        3
    am241  
       2017-02-11 12:29:08 +08:00   ❤️ 1
    int main(int argc, char** argv)
    int main(int argc, char* argv[])
    kmyzzy
        4
    kmyzzy  
       2017-02-11 12:34:13 +08:00   ❤️ 2
    函数内部能看到的只有指针,即使你传递的实参是数组,它也会被求值成指向首元素的指针,所以函数内部无法得知这个数组的长度。

    所谓的“根据情况判定是按照数组处理还是按照指针处理”指的是,你可以写成 fun(char *s),也可以写成 fun(char s[]),可以通过 *(s + 1) 这样去操作,也可以通过 a[1] 这样去操作,就看你自己的业务逻辑,怎么直观、怎么方便就怎么来。
    yuchting
        5
    yuchting  
       2017-02-11 12:43:38 +08:00 via Android   ❤️ 1
    判断不出来。怎么都可以转换传进去。

    不过有种不推荐的方法。
    如果是数组,可能判定其值在栈上。如果是指针,在堆上。
    确定堆和栈的地址空间,比较即可。
    yuchting
        6
    yuchting  
       2017-02-11 12:44:53 +08:00 via Android
    @Newyorkcity sizeof 是编译期行为,运行期不顶用,哈哈。
    Newyorkcity
        7
    Newyorkcity  
    OP
       2017-02-11 12:45:26 +08:00
    @am241
    能帮忙看一下为何这里会报错么?谢谢
    #include <stdio.h>

    void test(int **pnum){
    printf("sizeof(*pnum) = %d\n", sizeof(*pnum));
    }

    int main(){
    int num[3] = {1,2,3};
    test(&num); //在这一行报错[Error] cannot convert 'int (*)[3]' to 'int**' for argument '1' to 'void test(int**)'

    return 0;
    }


    @kmyzzy 把数组名的地址作为指针传入(二级指针)也不可以吗?比如我上面那种代码。谢谢
    Newyorkcity
        8
    Newyorkcity  
    OP
       2017-02-11 12:47:38 +08:00
    @yuchting 堆栈没学 QAQ ,只是想学到可以之后去看用 C 语言写的数据结合算法书的水平,应该不用去学那个吧?另外第一句是想说怎么都不可以转换传进去吧?谢谢
    scnace
        9
    scnace  
       2017-02-11 12:50:49 +08:00 via Android
    建议楼主去看下《征服 C 指针》 里面写的挺详细的…
    Newyorkcity
        10
    Newyorkcity  
    OP
       2017-02-11 12:53:07 +08:00
    @scnace 好的,谢谢推荐
    am241
        11
    am241  
       2017-02-11 12:58:04 +08:00


    是这样贴图吗?
    XiaoxiaoPu
        12
    XiaoxiaoPu  
       2017-02-11 12:58:31 +08:00
    @Newyorkcity 数组是数组,指针是指针;虽然数组可以自动类型转换为相应类型的指针,用法上看起来也很像,但是二者绝不是一种类型。我记得《 C 专家编程》里有相关的章节,可以找来看看。
    kmyzzy
        13
    kmyzzy  
       2017-02-11 12:59:12 +08:00
    @Newyorkcity 二级指针和你这个问题没有任何关系,总之只要记住,数组作为参数传递时,它被求值成指向首元素的指针。

    void test(int **p) { ... }
    int x, y , z;
    int *a[3] = {&x, &y, &z};
    test(a);

    这样是可以的。
    Cbdy
        14
    Cbdy  
       2017-02-11 15:22:36 +08:00 via Android
    试过多维数组、行指针的情况了吗?
    我记得行指针和指针数组内存布局是有点不同的
    ryd994
        15
    ryd994  
       2017-02-12 16:26:24 +08:00
    与其说是按照情况处理,不如说本来就是一样的
    数组 等于是 首元素的指针
    充分理解这一点后,可以有各种乱飞指针的玩法
    当然,乱飞指针是作大死
    aheadlead
        16
    aheadlead  
       2017-02-13 14:20:59 +08:00 via iPad
    @Newyorkcity 绝不可认为数组名是指针 相信我
    数组名只是一个地址 严格说连指针常量都不是

    你这样思考 比如我对一个 int 型字面量 233 取地址会发生什么
    显然会编译错误…
    aheadlead
        17
    aheadlead  
       2017-02-13 14:21:54 +08:00 via iPad
    16# 回复 @Newyorkcity 7#
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   1781 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 23ms · UTC 16:34 · PVG 00:34 · LAX 08:34 · JFK 11:34
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.