您的位置:首页 > 编程语言 > C语言/C++

【C语言进阶深度学习记录】三十八 C/C++语言中的函数声明与函数定义

2019-03-05 23:45 302 查看
版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。 本文链接:https://blog.csdn.net/qq_37375427/article/details/88213312

文章目录

  • 2 总结
  • 1 函数的声明和定义

    • 声明的意义在于告诉编译器程序单元的存在。只是告诉编译器它存在但是不在声明这里定义,有可能在当前文件中的其他地方或者其他文件中定义。如果在它还没有被定义之前就使用它,会导致编译错误
    • 定义则明确表示程序单元的意义
    • C语言中,通过关键字extern进行程序单元的声明。现在的编译器可以省略不写,大多时候都是直接省略。

    注意:在C语言中,当有多个源文件的时候,编译器共同编译这些源文件的顺序是不确定的。有可能先编译A文件,也有可能先编译B文件。这一点在下面的代码中会有体现。

    1.1 代码分析

    • 代码 lyy.c
    #include <stdio.h>
    #include <malloc.h>
    
    extern int g_var;
    
    extern struct Test;
    
    int main()
    {
    extern void f(int i, int j);
    extern int g(int x);
    
    struct Test* p = NULL; // (struct Test*)malloc(sizeof(struct Test));
    
    printf("p = %p\n", p);
    
    //g_var = 10;
    
    printf("g_var = %d\n", g_var);
    
    f(1, 2);
    
    printf("g(3) = %d\n", g(3));
    
    free(p);
    
    return 0;
    }
    • global.c
    #include <stdio.h>
    
    int g_var = 10;
    
    struct Test
    {
    int x;
    int y;
    };
    
    void f(int i, int j)
    {
    printf("i + j = %d\n", i + j);
    }
    
    int g(int x)
    {
    return (int)(2 * x + g_var);
    }

    分析:

    上述代码中,g_var和Test都是在global.c中定义的。在lyy.c中只是声 7ff7 明。上述代码编译运行会是正确的结果。

    • 问题1:

    但是,如果将g_var在global.c中的定义改为:float g_var = 10;的话,再编译运行上述代码的结果就是打印g_var的值是一个很大的随机值。这是为什么呢?

    因为g_var 的定义是float类型,float类型在内存的存储方式与int类型在内存的存储方式是不一样。具体参见float的内存存储方式:【C语言进阶深度学习记录】三 浮点数(float) 在内存中的表示方法 .所以最终以int的方式打印g_var的时候,由于它本身在内存的存储方式导致打印出一个很大的数。

    • 问题2:

    如果将lyy.c中的这一行:

    struct Test* p = NULL;
    改为:
    struct Test* p = (struct Test*)malloc(sizeof(struct Test));
    那么再次编译程序就会报错:

    这个错误是说Test是不完整类型。为什么会这样呢?在本文的刚开始已经说明:多个源文件一起编译,各个源文件的编译顺序是不确定的。在这里,很明显,在编译lyy.c的13行的时候,使用了sizeof求解Test结构体的大小,但是Test结构体此时由于编译器还没有编译到global.c,那么Test就是未定义的,根本无法使用sizeof求解它的大小所以编译器报错。

    2 总结

    • 声明和定义是不同的
    内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
    标签: 
    相关文章推荐