自助式网站建设 济南,网站续费会计分录怎样做,微官网系统架构,阿里巴巴官网国际站文章目录1 函数的声明和定义1.1 代码分析2 总结1 函数的声明和定义
声明的意义在于告诉编译器程序单元的存在。只是告诉编译器它存在但是不在声明这里定义#xff0c;有可能在当前文件中的其他地方或者其他文件中定义。如果在它还没有被定义之前就使用它#xff0c;会导致编… 文章目录1 函数的声明和定义1.1 代码分析2 总结 1 函数的声明和定义
声明的意义在于告诉编译器程序单元的存在。只是告诉编译器它存在但是不在声明这里定义有可能在当前文件中的其他地方或者其他文件中定义。如果在它还没有被定义之前就使用它会导致编译错误定义则明确表示程序单元的意义C语言中通过关键字extern进行程序单元的声明。现在的编译器可以省略不写大多时候都是直接省略。 注意在C语言中当有多个源文件的时候编译器共同编译这些源文件的顺序是不确定的。有可能先编译A文件也有可能先编译B文件。这一点在下面的代码中会有体现。 1.1 代码分析
代码 lyy.c
#include stdio.h
#include malloc.hextern 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.hint 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中只是声明。上述代码编译运行会是正确的结果。
问题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 总结
声明和定义是不同的