代码之家  ›  专栏  ›  技术社区  ›  Arctic Pi

C-将代码正确地划分为多个文件

  •  0
  • Arctic Pi  · 技术社区  · 7 年前

    我正在用C编写一个程序,并将各个部分分离到不同的.C文件(模块)中。

    如。

    vec3.c

    #include <math.h>
    
    typedef struct {
        float x, y, z;
    } vec3;
    
    float dot(vec3 v1, vec3 v2) {
        return v1.x*v2.x + v1.y*v2.y + v1.z*v2.z;
    }
    
    /* ... other stuff ... */
    

    射线c

    #include "vec3.c"
    
    typedef struct {
        vec3 A, B;
    } ray;
    
    vec3 origin(ray r) {
        return r.A;
    }
    
    /* ... other stuff ... */
    

    #include "ray.c"
    
    typedef struct {
        float t;
        vec3 p;
        vec3 n;
    } record;
    
    typedef struct {
        vec3 center;
        float radius;
    } sphere;
    
    typedef enum {false, true} bool;
    
    bool hit_sphere(sphere s, ray r, float tmin, float tmax, record *rec) {
        /* ... do stuff ... */
    }
    
    /* ... other stuff ... */
    

    摄像机c

    #include "ray.c"
    
    typedef struct {
        vec3 origin;
        vec3 lower_left_corner;
        vec3 horizontal;
        vec3 vertical;
    } camera;
    
    /* ... other stuff ... */
    
    vec3 origin = {0.0, 0.0, 0.0};
    vec3 lower_left_corner = {-2.0, -1.0, -1.0};
    vec3 horizontal = {4.0, 0.0, 0.0};
    vec3 vertical = {0.0, 2.0, 0.0};
    
    camera cam = {origin, lower_left_corner, horizontal, vertical};
    

    主要c

    #include <stdio.h>
    #include <float.h>
    #include "sphere.c"
    #include "camera.c"
    
    /* ... other stuff ... */
    
    int main() {
        /* ... do stuff ... */
    }
    

    在这种情况下,出现问题的原因是两个摄像头。c和球体。c包括射线。因此,在这些模块中定义的结构和功能有双重定义。

    谢谢

    2 回复  |  直到 7 年前
        1
  •  3
  •   user2742371 user2742371    7 年前

    你不应该包括 .c

    c .h

    然后使用包含头文件的函数。

    头文件示例(示例.h):

    #ifndef EXAMPLE_H
    #define EXAMPLE_H
    
    /* Function declarations */
    void example();
    
    #endif /* EXAMPLE_H */
    

    实现文件示例(示例c):

    #include "example.h"
    
    void example() {
        /* TODO: add logic */
    }
    
        2
  •  1
  •   Swift - Friday Pie    7 年前

    #include

    一种经典的方法是使用预处理器的#ifndef指令。大多数编译器支持指令 #pragma once

    公认的做法是将包含可重用声明和定义的文件称为“头文件”,并将其命名为.h(有时为.hpp)。C++标准头同意根本没有扩展,以避免将它们与C头混合。E、 g.stdio。h被cstdio取代,前者不应在C++中使用。有时需要包含大的重复定义,这样可以得到不同的扩展名。

    标头不应定义函数或变量等对象,它们可以声明这些对象以进行外部链接。为什么?如果将定义了变量的头文件包含到多个编译单元中,则链接器会出错,因为所有单元都包含相同的符号。所以,定义应该是唯一的,否则程序被认为是格式错误的。默认情况下,始终假设函数具有外部链接

    /* myheader.h */
    #ifndef ___MYHEADER_H
    #define ___MYHEADER_H
    
    extern int globalVariable;
    
    typedef struct MyType {
    
    };
    
    int foo(MyType);
    
    #endif
    
    /* myheader.cpp */
    #include "myheader.h"
    
    int globalVariable = 5;
    
    int foo(MyType param)
    {
    /* body of foo */
    }
    

    如何在项目中组织文件取决于设计师。如果您是团队的一员,您应该遵循该团队首席设计师的建议或他们批准的文档。