43-函数的意义

注:博客中内容主要来自《狄泰软件学院》,博客仅当私人笔记使用。

测试环境:Ubuntu 10.10

GCC版本:4.4.5

 

一、C语言中的函数

1) 函数的由来

43-函数的意义_第1张图片

 

二、函数的意义

1) 模块化程序设计

43-函数的意义_第2张图片

 

2) C语言中的模块化

43-函数的意义_第3张图片

三、面向过程的程序设计

1) 面向过程是一种以过程(解决问题的过程)为中心的编程思想

2) 首先将复杂的问题分解为一个个容易解决的问题

3) 分解过后的问题可以按照步骤一步步完成

4) 函数是面向过程在C语言中的体现

5) 解决问题的每个步骤可以用函数来实现 

 

四、声明和定义

43-函数的意义_第4张图片

1) 声明的意义在于告诉编译器程序单元的存在

程序单元:是指在程序中执行某一特定任务的具有一定独立性的代码模块

2) 定义则明确指示程序单元的意义

3) C语言中通过extern进行程序单元的声明

4) 一些程序单元在声明时可以省略extern

        严格意义上的声明和定义并不相同!

 

实例分析
声明和定义不同
global.c
#include 

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);
}

43-1.c
#include 
#include 

extern int g_var;    //声明g_var,g_var的内存分配在别的空间

extern struct Test;  //声明结构体,这里的extern可以省略

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;
}

操作:

1) gcc 43-1.c global.c -o 43-1.out编译有警告:

43-1.c:6:15: warning: useless storage class specifier in empty declaration [enabled by default]
 extern struct Test;
               ^
警告:在空的类型申明中,说明符没有意义

打印结果:

p = (nil)
g_var = 10
i + j = 3
g(3) = 16

2) 修改代码:

#include 
#include 

extern int g_var;    //声明g_var,g_var的内存分配在别的空间

extern struct Test;  //声明结构体,这里的extern可以省略

int main()
{
    extern void f(int i, int j);    //声明函数,告诉编译器不要报错
    extern int g(int x);            //声明函数
    
    struct Test* p = (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;
}

gcc 43-1.c global.c -o 43-1.out编译错误:

43-1.c:6:15: warning: useless storage class specifier in empty declaration [enabled by default]
 extern struct Test;
               ^               
43-1.c: In function ‘main’:
43-1.c:13:47: error: invalid application of ‘sizeof’ to incomplete type ‘struct Test’
  struct Test* p = (struct Test*)malloc(sizeof(struct Test));
                                               ^
错误:非法应用sizeof在不完全类型'struct Test'

分析:

        struct Test只是被声明,虽然在其它地方被定义,但是编译时有先后顺序(定义struct Test的文件被先编译后,才能在申明的struct Test的地方被使用),我们不能依赖于编译文件的顺序设计代码。

 

3) 修改g_var类型为float类型,代码如下:

global.c
#include 

float 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);
}

43-1.c
#include 
#include 

extern int g_var;    //声明g_var为int类型,以定义时不符

extern struct Test;  //声明结构体,这里的extern可以省略

int main()
{
    extern void f(int i, int j);    //声明函数,告诉编译器不要报错
    extern int g(int x);            //声明函数
    
    struct Test* p = NULL;
    
    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;
}

gcc 43-1.c global.c -o 43-1.out编译有警告:

43-1.c:6:15: warning: useless storage class specifier in empty declaration [enabled by default]
 extern struct Test;
               ^

运行结果:

p = (nil)
g_var = 1092616192
i + j = 3
g(3) = 16

分析:

        定义时g_var为float类型,但是打印时按照整型解释g_var,因此会产生这么大的数据。

 

注:

1. C语言中的声明不分配内存,仅仅是告诉编译器这里有这个东西;定义才分配内存。

 

小结:

1) 函数是面向过程思想在C语言中的体现

2) 面向过程是由上至下分解问题的设计方法

3) 程序中的定义和声明完全不同

4) C语言中通过extern对程序单元进行声明

你可能感兴趣的:(C)