LogoLogo
  • Welcome!
  • Mission Statement
  • Contributing Guidelines
    • Embed CADs in Wiki Articles
  • VEX Worlds Livestream Archive
    • VEX U
    • V5RC High School
    • V5RC Middle School
    • VIQRC Middle School
    • VIQRC Elementary School
    • JROTC
  • ⚙️Hardware
    • Design Fundamentals
      • Gear Ratios
      • Internal Forces (Stress)
      • Torque
      • RPM
      • Center of Mass
    • Introduction to VEX Parts
      • Structure
        • C-Channels and Angles
        • Fasteners
        • Retainers
        • Gussets and Brackets
        • Bearings
        • Plate Metal and Flat Bars
      • Motion
        • High Strength Components
        • Gears and Sprockets
        • Traction Wheels
        • Mecanum Wheels
        • Omnidirectional Wheels
        • Flex Wheels
    • Robot Decorations
      • Part Dyeing
      • Metal Coloring
      • License Plate Holders
    • Lifts
      • Double Reverse Four Bar (DR4B or RD4B)
      • Four Bar
      • Scissor Lift
      • Six Bar
      • Other Lifts
      • Best Practices
    • Shooting Mechanisms
      • Catapult
      • Flywheel
      • Linear Puncher
    • Drivetrains
      • Tank Drive
      • Mecanum Drive
      • Holonomic Drive
      • Designing a Drivetrain
      • Best Practices
    • Pivots & Joints
    • Pneumatics
      • Best Practices - Pneumatics
    • Intakes
    • Flip Out Mechanisms
    • Defensive Mechanisms
    • Misc. Building Techniques
    • VexU
      • Common Manufacturing Techniques
        • 3D Printing
        • Laser Cutting
      • Custom Manufactured Parts Library
      • Commercial Off The Shelf Parts Library
  • 👑Team Administration
    • New Team Resources
      • Creating The Team
      • Gaining Interest for Robotics Teams
      • Attending Competitions
        • Elimination Bracket
    • Team Dynamics
      • Organization Structure and Longevity
      • Member Allocation and Management
      • How *Not* To Run a Team
    • Team Finances
      • One-Year Team Financial Breakdown
      • Funding Your Teams
    • Hosting Competitions
      • Live Streaming
      • Tournament Manager
        • Competition Electronics
        • Creating a Tournament
        • Tools
          • Field Set Control
          • Connecting Mobile Devices
          • Connecting Raspberry Pis
        • Match Control
          • Inputting Match Scores
          • Inputting Skills Scores
          • Inputting Scores on TM Mobile
        • Displays
        • Alliance Selection
      • Additional Event Partner Resources
    • VexU Organization Management
      • Getting Started in VexU
      • Team / Personnel Management
      • Volunteering At Local Events
  • 📚The Judging Process
    • The Engineering Design Process
      • Test and Refine
    • The Engineering Notebook
      • Segments of the Notebook
      • BLRS2 '23-'24 Engineering Notebook
      • Integrating Inventor Models into Documentation
      • Engineering Notebook Rubric Breakdown
    • The Interview
      • Interview Rubric Breakdown
    • Using Notion for an Engineering Notebook
      • How to Setup a Notebook
      • How to Create Entries
      • How to Export a Notebook
      • Purdue SIGBots Notion Template
        • Game Analysis
        • Identify The Problem
        • Brainstorm Solution
        • Select Best Approach & Plan
        • Build Log
        • Programming Log
        • Testing Solution
        • Tournament Recap
        • Innovative Feature
  • 🖥️VEX CAD
    • CAD Programs
      • Inventor
      • Fusion 360
      • Solidworks
      • OnShape
      • Protobot
    • Making a Chassis
      • Inventor Chassis: The Basics
        • Installation
        • User Interface Overview
        • Dark Mode
        • Assemblies
        • Placing Parts
        • Navigating CAD
        • Changing Visual Style
        • Grounding
        • Connecting Two C-Channels
        • Modifying Existing Constraints
        • Toggling Visibility on Existing Parts
        • Completing Half of the Chassis
          • Inner Drive Channel
          • Bearing Flats
          • Motors
          • Wheels
          • Sprockets
          • Spacers, Washers and Standoffs
          • Spacers Cont.
        • Creating Mid-Plane
        • Mirroring
      • Inventor Chassis: Best Practices
        • File Structure
        • Subassemblies
        • Wheel Subassembly
        • Origin Planes
        • Cross Brace
        • Drive Channels
        • Simple Motor iMates
        • Replacing Simple Electronics
        • Completing Half of the Drive
          • Bearing Flats (Best Practice)
          • Wheels
          • Powered Gear
          • Spacer Boxing
          • Spacers, Washers and Standoffs (Best Practice)
        • Model Browser Folders
        • Mirroring (Best Practice)
        • Model Browser Folder (Right)
        • Main Assembly
      • Fusion 360 Chassis
      • Solidworks Chassis, Chain, and Custom Plastic
    • Remembering The Best
      • 62A Skyrise
      • 400X Nothing But Net
      • 2587Z Nothing But Net
      • 365X Starstruck
      • 62A In The Zone
      • 202Z In The Zone
      • 5225A In The Zone
      • 169A Turning Point
      • 929U Turning Point
      • 7K Tower Takeover
      • 5225A Tower Takeover
      • 62A Change Up
    • Scuff Controller
  • 💻Software
    • Odometry
    • Path Planning
    • Robotics Basics
      • Arcade Drive
      • Tank Drive
      • Joystick Deadzones
      • Curvature (Cheesy) Drive
      • Subsystem Toggling
    • Organizing Code
      • Code Style
      • Code Styling Guide
      • Writing Good Comments
      • Version Control
    • Control Algorithms
      • Bang Bang
      • PID Controller
      • Basic Pure Pursuit
      • Flywheel Velocity Control
      • Kalman Filter
      • Take Back Half (TBH) Controller
      • RAMSETE Controller
    • Competition Specific
      • Operator Control
      • Autonomous Control
    • C++ Basics for VEX Robotics
      • Basic Control Flow
      • Enumerations
      • Namespaces (::)
      • Multiple Files (C/C++)
    • VEX Programming Software
      • PROS
        • OkapiLib
      • vexide
      • Robot Mesh Studio (RMS)
      • EasyC
      • RobotC
      • VEXcode
      • Midnight C
    • General
      • Stall Detection
      • Register Programming
      • Sensors and Odometry in Autonomous
      • Embedded Programming Tips
      • Debugging
      • Bit Shift
      • Bit Mask
      • Autoformatting
      • Finite State Machine
      • Data Logging
    • Object Recognition
      • Red Green Buoy
      • AMS
      • OpenCV
      • OpenNI
    • 🤖AI in VRC: Pac-Man Pete
  • ⚡VEX Electronics
    • V5 ESD Protection Board
    • VEX Electronics
      • VEX V5 Brain
        • V5 Electronics Observations and Issues
      • VEX Controller
      • VEXnet and V5 Robot Radio
      • VEX Battery
      • VEX Motors
    • VEX Sensors
      • 3-Pin / ADI Sensors
        • Encoder
        • Potentiometer
        • Limit Switch
        • Bumper Switch
        • Accelerometer
        • Gyroscope
        • Ultrasonic
        • Line Tracker
        • LED Indicator
      • Smart Port Sensors
        • GPS Sensor
        • Rotation Sensor
        • Vision Sensor
        • Optical Sensor
        • Distance Sensor
        • Inertial Sensor (IMU)
        • 3-Wire Expander
    • V5 Brain Wiring Guide
    • Legacy
      • VEX Cortex
      • Power Expander
      • VEX Motor Controller
      • VEX Cortex Wiring Guide
  • General Electronics
    • General Topics
      • External Boards
        • ASUS Tinker Board S
        • Arduino
        • Beagleboard
        • Leaflabs Maple
        • LattePanda
        • Meadow F7 Micro
        • Netduino
        • ODROID-XU4
        • Pandaboard
        • Raspberry Pi
      • Analog-Digital Converter (ADC)
      • Bit-Bang
      • GPIO
      • I2C
      • Jitter
      • Line Noise
      • List of Tools
      • Output Drive
      • Power Consumption
      • Radius Array
      • Resettable Fuse (PTC)
      • SPI
      • Slew Rate
      • Stalling
      • USART
      • UART
      • 5 Volt Tolerant
      • DC Motor Basics
Powered by GitBook
LogoLogo

This work is licensed under a Attribution-ShareAlike 2.0 Generic License

On this page
  • Header vs. Source Files:
  • In Practice:
  • Header Guards
  • Example Usage:
  • Bad Example Usage:
  • Applications for Robotics

Was this helpful?

Edit on GitHub
Export as PDF
  1. Software
  2. C++ Basics for VEX Robotics

Multiple Files (C/C++)

When the code to your robot becomes large enough, splitting it into multiple files can help structure your code and make it easier to find things.

Header vs. Source Files:

In C and C++, you'll commonly find source (implementation) files and header (API) files. Source files contain the actual functionality of your program, and header files define the functions, variables, etc. that are viewable by other files in the code.

Source files typically end .c for C code, or .cpp or .cxx for C++ code.

Header files typically end with .h for C and C++ code, or .hpp or .hxx for C++ code.

Typically, but not always, you'll find one header file per source file.

In Practice:

When using objects in the context of a header and source file, be sure to:

  1. Declare your classes and functions in header files: Define the class structure, its data members, and function prototypes in a header file with a .h or .hpp extension. The same applies for functions not associated with a class.

  2. In the header, be sure to use the extern keyword to declare that the motor, sensor, or other object is initialized somewhere else (see example below).

  3. Implement your class methods in source files: Write the implementation of your class methods in a source file with a .cpp (for C++) or corresponding extension. This keeps your code organized and improves compile time. This is not necessary with built in objects such as motors and other sensors.

Other good practices:

  1. Use #include guards in header files: To prevent multiple inclusions of the same header file, use #include guards or #pragma once at the beginning of your header files (more on this below).

  2. Include the necessary header files in source files: In your source file, include the header file of the class and any other headers necessary for the implementation with the #include directive.

  3. Separate interface from implementation: Keep the class interface in the header file clear and concise, focusing on what the class does. Leave the how to the source file where you implement the methods.

Header Guards

Its important to ensure that headers are only included once in each source file. This is done with header guards:

#ifndef MY_HEADER_HPP
#define MY_HEADER_HPP

// Your public definitions go here

#endif//MY_HEADER_HPP

If header guards aren't present, it may lead to compilation issues when a header file is included multiple times either directly or indirectly through other headers. This can lead to multiple definitions of the same class, function, or variable, causing compilation errors due to redefinition. Additionally, omitting header guards can significantly increase compile times as the same header is processed multiple times.

Under the hood, what #include does is blanket copying and pasting the header file into where the include is. That's why the redefinition may occur.

Example Usage:

To summarize, source files can include a header file to make functions, variables, and other objects that were defined in another source file(such as a motor or a sensor) visible. It helps to keep code organized and readable.

#include "my_functions.hpp"

int main() {
  myFunction();
  m1.stop(); 
  return 0;
}
// my_functions.hpp
#ifndef MY_FUNCTIONS_HPP
#define MY_FUNCTIONS_HPP

void myFunction();

extern pros::Motor m1; 

#endif // MY_FUNCTIONS_HPP
// my_functions.cpp
#include "my_functions.hpp"
#include <iostream>

pros::Motor m1;

void myFunction() {
  m1.move(127); 
  std::cout << "Hello from myFunction!" << std::endl;
}

In most project layouts (such as a pros project), the src directory is used for storing the .cpp files, while the inc directory is used for storing header files.

Bad Example Usage:

IncorrectMain.cpp

#include "bad_example.hpp"

int main() {
  undefinedFunction();
  return 0;
}

bad_example.hpp

#ifndef BAD_EXAMPLE_HPP
#define BAD_EXAMPLE_HPP

// Forget extern keyword, so every time this is included in a src file we are 
// "redefining" the motor object. 
pros::Motor m1; 

// Since we included this header file in both IncorrectMain.cpp and bad_example.cpp,
// we will now get a "multiple declaration error of pros::Motor m1" error when we
// compile.  

// Forgot to declare undefinedFunction here, so it's not visible to other files
// such as Incorrectmain.cpp

// (missing here)

#endif // BAD_EXAMPLE_HPP

bad_example.cpp

#include "bad_example.hpp"
#include <iostream>

void undefinedFunction() {
    std::cout << "This will cause a linker error since it's not declared in the header." << std::endl;
}

This code will result in a linker error because undefinedFunction() is implemented in bad_example.cpp but is not declared in bad_example.hpp, so IncorrectMain.cpp doesn't know about its existence.

Applications for Robotics

A common application for this is branching each of the subsystems into their own files rather than cramming all the subsystems into one.

PROS Project
│
├── src
│   ├── chassis.cpp
│   ├── lift.cpp
│   ├── flywheel.cpp
│   └── main.cpp
│
└── inc
    ├── chassis.hpp
    ├── lift.hpp
    └── flywheel.hpp

This helps making organizing and navigating code a lot easier, as each subsystem is fit nicely into its own file.

Teams Contributed to this Article:

PreviousNamespaces (::)NextVEX Programming Software

Last updated 1 year ago

Was this helpful?

(Purdue SIGBots)

💻
BLRS