第43课 函数的意义

1. C语言中的函数

(1)函数的由来:

  程序 = 数据 + 算法    →   C程序 = 数据 + 函数

(2)模块化程序设计

(3)C语言中的模块化

2. 面向过程的程序设计

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

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

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

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

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

3. 声明和定义

(1)声明的意义在于告诉编译器程序单元(以下均指变量或函数)的存在

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

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

(4)一些程序单元在声明时可以省略extern(如结构体)

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

【实例分析】声明和定义不同

//global.c ——注意不是头文件

#include <stdio.h>

float g_var = 10.0f; //注意,这里定义为float型的

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以float型处理
}

//43-1.c

#include <stdio.h>
#include <malloc.h>

//这里只是声明,告诉编译器该全局变量在外部的global.c文件己经存在!(注意,不是头文件)
extern int g_var;  //注意,这里声明为int。但外部定义为float型。在处理这个.c文件时,编译器会处g_var当成整型来处理,但实际上内存中是以float存储的!
                   //这里声明为int是为了说明,声明和定义是不同的!

struct Test; //在global.c文件中,对于结构体声明无须加extern。

int main()
{
    extern void f(int,int); //这里只是声明,相当于告诉编译器,这个函数在外部文件中己经存在。

    extern int g(int);

    struct Test* p = NULL; //这里合法的

    //这里是错误的,因为结构体是在外部定义的,虽然在编译global.c时编译器是知道这个结构体的大小的。
    //但由于文件是分别编译的,编译只会按本文件中定义的类型来编译。由于本文件中找不到他的定义。
    //所以也就无法知道该结构体实际的大小,因此会报错。这就是声明和定义的区别!
    //struct Test* p = (struct Test*)malloc(sizeof(struct Test));//编译器提示这是一个不完全的类型

    printf("p = %p\n", p);

    //g_var = 10;  //这里可以取消注释来观察g_var值的变化!

    printf("g_var = %d\n", g_var);//会把内存中浮点型的g_var当成int型来处理!

    f(1, 2);

    printf("g(3) = %d\n",g(3)); //g()函数(在global.c中),把g_var当成float型处理。

    free(p);

    return 0;
}

4. 小结

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

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

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

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

时间: 2024-10-13 23:30:33

第43课 函数的意义的相关文章

第9课 - 函数定义及调用

第9课 - 函数定义及调用 1. makefile中的函数 (1)make 解释器提供了一系列的函数供 makefile 调用 (2)在 makefile 中支持自定义函数实现,并调用执行 (3)通过 define 关键字实现自定义函数 2. 在makefile中自定义函数 (1)自定义函数的语法 其中,$(0) 代表被调用的函数名,$(1) , $(2) , $(3) ... 代表调用函数时后面的传参 (2)深入理解自定义函数 - 自定义函数是一个多行变量,无法直接调用 - 自定义函数是一种过

抽象类,虚函数,纯虚函数的意义

C语言是面向过程的语言,C++是面向对象的语言,区分它们面向什么的重要区别在于C++比C多个类.那么在我看来,抽象就是类的升华. 一般刚学习C++的时候,抽象这个东西给人最大的感觉就是太抽象,很难理解.心里总是想着,其实这样或那样就能解决这个问题了,为什么要学这个?增加一个抽象类还增加一段代码,费事不说还不容易理解,所以当时我对抽象还是很抗拒的.但是当工作中真正用到这个的时候,就觉得这个东西真是太好了,任何其它的方案都无法代替抽象. 为什么这样说呢?首先C++是强类型语言,对于一个数组或链表来讲

C语言-第36课 - 函数递归与函数设计技巧

第36课 - 函数递归与函数设计技巧 一. 递归 递归概述 (1) 递归是数学领域中的概念在程序设计中的应用. (2) 递归是一种强有力的程序设计的方法. (3) 递归的本质为函数内部在适当的时候调用自身. 组成部分 (1)递归点:以不同参数调用自身. (2)出口:不在递归调用 下面就是求一个数的阶乘的函数: #include <stdio.h> int func(int x) { if( x > 1 ) { return x * func(x - 1);  //递归点 } else {

第七课 函数的嵌套调用【项目1-4】

第七课 函数的嵌套调用 项目一[k次方之和] 设计程序,计算: 请在下面的程序结构基础上完成设计. [cpp] view plain copy print? #include<stdio.h> int power(int m,int n); //求m的n次方(m^n) int sum_of_power(int k,int n);  //从1^k到n^k的累加和 int main( ) { int k, n; scanf("%d %d", &k, &n); p

telnetlib 中各种 read 函数的意义

基本原理 要明白 telnetlib 中各个 read 函数的意义,首先要了解 telnetlib 的工作原理. telnetlib 首先通过 socket 连接从网络接收数据,把数据存储到自己的 raw queque 中,然后对其进行(telnet 协议相关的)处理(cook).处理结果存放在 cooked queue 中供应用程序取用.整个过程如下图. ---------, ,----------, ,-----, ,--------, ,-----------, network |====

第43课 继承的概念和意义

面向对象的高端课程都是和继承相关的,例如设计模式. 思考: 类与类之间是否存在直接的关联关系? 生活中的例子: 组合关系的程序描述: 1 #include <iostream> 2 #include <string> 3 4 using namespace std; 5 6 class Memory 7 { 8 public: 9 Memory() 10 { 11 cout << "Memory()" << endl; 12 } 13 ~

第43课 继承的概念及意义

1. 类之间的组合关系 (1)组合关系:整体与部分的关系 [实例分析]组合关系的描述 #include <iostream> using namespace std; //内存类 class Memory { public: Memory() { cout << "Memory()" << endl; } ~Memory() { cout << "~Memory()" << endl; } }; //硬盘类

第56课 函数模板的概念和意义

1. 发散性问题:C++中的几种交换变量的方法 (1)宏代码块 VS 函数 [编程实验]变量的交换 #include <iostream> #include <string> using namespace std; //宏定义代码块 #define SWAP(t, a, b) do { t c = a; a = b; b = c; }while(0); //定义函数方式 void Swap(int& a, int& b) { int c = a; a = b; b

php中$t=date()函数参数意义及时间更改

php中date()函数用的最多的是:date('Y-m-d H:i:s', time());  这里面的参数意义分别是:Y - 年,四位数字; 如: "2016":m - 月份,二位数字,若不足二位则在前面补零; 如: "01" 至 "12":d - 几日,二位数字,若不足二位则前面补零; 如: "01" 至 "31":H - 24 小时制的小时; 如: "00" 至 "23