6.3 大程序结构

1.多个 .c文件,如何编译

  • main()里的代码太长,适合分成几个函数
  • 一个源代码文件太长,适合分成几个文件
  • 两个独立的源代码文件 不能编译成一个可执行程序

之前我们写的代码,是放在一个.c文件中,如果main写在一个.c文件中,max()写在一个.c文件中呢?

2.项目

  • 新建项目: Devcpp中 文件 —— 新建 —— 项目 —— Console Application
  • 对于项目,Devcpp 的编译会把一个项目中的所有源代码文件都编译后,链接起来
  • 有的IDE有 编译 和 构建 两个按钮,编译 是对单个源代码文件编译,构建是对整个项目做链接

3.编译单元

  • 一个.c文件就是一个编译单元
  • 编译器每次编译只处理一个编译单元

4.头文件

把函数原型 放到一个 以.h结尾的头文件中,在需要调用这个函数的 .c 源代码文件中 #include这个头文件,编译器在编译的时候就知道函数的原型了

新建——源代码——max.h
max.h

double max(double a,double b);

max.c

#include "max.h"

double max(double a,double b)
{
    return a > b ? a : b;
}

main.c

#include <stdio.h>
#include "max.h"


int main(void) {

    double a = 5;
    double b = 6;
    printf("max is %f\n", max(5, 6)); // max is 6.000000
    return 0;
}

5.#include

  • #include是一个编译预处理命令,和宏一样,在编译之前就处理了
  • 编译时,把头文件的全部文本内容 原封不动地 插入到 include所在的地方

5.1 “” 还是 <>

  • #include 有两种形式来指出要插入的文件
    • ”“编译时,编译器首先在当前目录(.c文件所在的目录)寻找这个文件,如果没有 就到指定目录去找
    • <>编译时,编译器只在指定的目录去找
  • 编译器知道标准库的头文件在哪里
  • 环境变量 和 编译器命令行参数 也可以指令头文件的目录

5.2 误区

  • #include 不是用来引入库的
  • 现在的C语言编译器默认会引入所有的标准库
#include <stdio.h> 只是为了让编译器知道 printf函数的原型,保证你调用时给出的参数值是正确的类型

stdio.h 里只有printf()的原型,printf的代码在另外的某个 .lib(Windows)或.a(Unix)中

6 头文件

  • 一般的做法是 任何 .c 都有对应的同名的.h,把所有对外公开的函数原型 和 全局变量的生命 都放进去
  • 在使用 和 定义 这个函数的地方都应该 #include 这个头文件

7.声明

7.1 声明与定义

int i; // 变量的定义
extern int i; // 变量的声明
  • 声明是不产生代码的
    • 函数原型
    • 变量原型
    • 结构声明
    • 宏声明
    • 枚举声明
    • 类型声明
    • inline函数
  • 定义是产生代码的

7.2 声明的使用

  • 只有声明可以放在头文件中(是规则不是法律)
  • 否则会造成一个项目中多个编译单元里有重名的实体
    • 某些编译器允许几个编译单元中存在同名的函数,或者用weak修饰符来强调这种存在

7.3 重复声明

  • 同一个编译单元里,同名的结构不能被重复声明
  • 如果头文件里有 结构的声明,很难保证 这个头文件 不会在一个编译单元里 被#include多次
  • 需要“标准头文件结构”
    • 运用条件编译和宏,保证这个头文件在一个编译单元中只会被#include一次
    • #pragma once 也能起到相同的作用,但是不是所有的编译器都支持

错误示例:


struct Node{
    int value;
    char* name;
};

// [Error] redefinition of 'struct Node' 重新定义 struct Node 
struct Node{
    int value;
    char* name;
};

int main(void) {

    return 0;
}

标准写法:
max.h

#ifndef _MAX_H_
#define _MAX_H_ 


double max(double a,double b);
extern int gAll;

struct Node{
    int value;
    char* name;
};

#endif

max.c

#include <stdio.h>
#include "max.h"

int gAll = 12;

int main(void) {

    double a = 5;
    double b = 6;
    printf("max is %f\n", max(5, 6)); // max is 6.000000
    return 0;
}

max.c

#include "max.h"

double max(double a,double b)
{
    return a > b ? a : b;
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
好的,以下是符合要求的学生信息录入可查询系统代码: ```c #include <stdio.h> #include <stdlib.h> #include <string.h> #define MAX_STUDENTS 20 #define NAME_LENGTH 20 typedef struct { char name[NAME_LENGTH]; int age; float grade; } Student; void add_student(Student *students, int *num_students); void search_student(Student *students, int num_students); void display_students(Student *students, int num_students); int main() { Student students[MAX_STUDENTS]; int num_students = 0; int choice; do { printf("\n1. Add student\n2. Search student\n3. Display all students\n4. Exit\n"); printf("Enter your choice: "); scanf("%d", &choice); switch (choice) { case 1: add_student(students, &num_students); break; case 2: search_student(students, num_students); break; case 3: display_students(students, num_students); break; case 4: printf("Exiting program...\n"); break; default: printf("Invalid choice.\n"); } } while (choice != 4); return 0; } void add_student(Student *students, int *num_students) { if (*num_students >= MAX_STUDENTS) { printf("Maximum number of students reached.\n"); return; } Student *new_student = &students[*num_students]; printf("Enter name: "); scanf("%s", new_student->name); printf("Enter age: "); scanf("%d", &new_student->age); printf("Enter grade: "); scanf("%f", &new_student->grade); *num_students += 1; printf("Student added.\n"); } void search_student(Student *students, int num_students) { char name[NAME_LENGTH]; printf("Enter name to search: "); scanf("%s", name); for (int i = 0; i < num_students; i++) { if (strcmp(students[i].name, name) == 0) { printf("Name: %s\nAge: %d\nGrade: %0.2f\n", students[i].name, students[i].age, students[i].grade); return; } } printf("Student not found.\n"); } void display_students(Student *students, int num_students) { for (int i = 0; i < num_students; i++) { printf("Name: %s\nAge: %d\nGrade: %0.2f\n", students[i].name, students[i].age, students[i].grade); printf("---------------------\n"); } } ``` 使用示例: 1. 打开Embarcadero dev-c++ 6.3,创建一个空的C语言项目。 2. 将上述代码复制到新建的源文件中。 3. 点击“编译并运行”,即可在控制台中运行该程序。 4. 按照程序提示,选择相应的功能进行操作,如添加学生信息、查询学生信息或显示所有学生信息等。 注意:本程序中使用了结构体(struct)来存储学生信息,以及指针(*)来表示学生数组和学生数量。如果您对这些概念不熟悉,建议先学习相关的C语言知识。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值