Preprocessor directives are not specific to C++, but are a language feature that enables the manipulation of code before it is processed and compiled. These directives are usually added into the include file, which is the file that includes all of the definitions (functions and constants) needed for another file to compile.
There are several different types of preprocessor directives, some of which enable syntax changes within the code being included and some that simply turn code off.
The #define directive is one that can be used to enable new syntax. This directive allows for the definition of constant values or for the replacement of words with other words.
One example of this is with the use of #define SquareRoot(a) \ \ \> where SquareRoot(a) = a. This replaces the need for sqrt(a) = a with just a = a.
#include
This header file contains definitions for several constants and functions related to mathematical limitations. These constants can be used in place of numerical values that exceed these limits, which can be very helpful when dealing with complex programs.
For example, if you have a program that requires the use of the square root function, but you do not have access to a square root function on your computer system, you can replace it with the max value of a float variable.
The max value of a float variable is 1 less than the largest possible exponent for a float variable. Since there is no such thing as a negative square root, this will work perfectly!
The same goes for the ln (natural log) function- if your program requires this but does not have it enabled, then use the closest possible value with a close enough precision.
#define sqrt(x) _sqrt_p(x)
In this blog post, the author explains how to write a preprocessor directive that enables the use of functions like SQRT and Sin. This is great information to know if you are looking to learn more about C++ programming.
By writing the #define sqrt(x) _sqrt_p(x) preprocessor directive, you are telling the compiler to replace every instance of sqrt(x) with _sqrt_p(x).
The underscore (_) preceding the sqrt() function name indicates that this function is not built into the compiler, but rather provided by a library. The parentheses (()) after _sqrt_p() indicate that this function accepts one argument and returns one value.
This information is important because it tells the compiler how to call the function correctly.
#define sin(x) _sin_p(x)
In this post, the author explains how to write a preprocessor directive that enables the use of functions like SQRT and Sin. This can be done in any language that has preprocessor functionality, but is demonstrated in C in this post.
By writing the #define sin(x) _sin_p(x) line, you are telling the compiler to replace every instance of sin(x) with _sin_p(x). The backslash at the end of sin is there to indicate that it is a keyword, so it needs to be treated differently.
By doing this, you are creating your own function called _sin_p() that takes in a parameter x and returns the sine of x. This function does not actually exist, but instead replaces the variable sin with _sin_p().
This can be helpful if there is not enough memory allocated to create a full sin function, but only enough for the square root function _sin_p().
#define cos(x) _cos_p(x)
In this blog post, the author explains how to write a preprocessor directive that enables the use of functions like cosine and sine. By writing #define cos(x) _cos_p(x) you can allow the use of cos(x) as a function that returns the cosine of x.
By adding _cos_p(x) at the end, you tell the compiler to look for a function named _cos_p, with one argument x, and assume it returns a cosine value.
This way, you do not have to write out all of the calculations needed to obtain the cosine value. The compiler assumes that there is a function named _cos_p that returns a float value and takes in only one argument x.
There are many other functions like sin, tan, and sqrt that can be enabled this way.
#define atan2(y, x) _atan2_p(y, x)\end{verbatim} and . Use these to define the corresponding preprocessor macros.
This ensures that the program will still compile should these functions change in a future version of the standard library.
With this preprocessor directive in place, you may freely use these functions like any other.
You may also use mathematical constants like (PI)
, which is defined in the same include file with many other mathematical constants, such as e and infinity.
You may have noticed the constant PI
in some of the examples, and might be wondering why it is in all caps. All caps constants are defined in a different include file called . This file also contains many other mathematical constants, such as e and infinity.
All of these constants are available for use in your programs!
To conclude this section, here are some tips to remember: first, make sure to include the appropriate headers at the top of your program; second, make sure to define the preprocessor directives that enable functions like SQRT and Sin; third, remember to use all caps constants from the include file like (PI)
and e.
Lastly, remember that you can always look up these things in the documentation if you are still unsure!
Variable Scoping
Variable scoping is one of the most fundamental concepts when learning programming. Scoping refers to which parts of a program have access to a variable (or several) and what it can do with that variable (or them). Variables can only be accessed within certain regions of code called scopes. There are six different scopes in C++: global scope, function scope, block scope, instance scope, nested scope, and default (or) local scope.
Variables declared at global or function level are considered to be declared at global scope. These variables can be accessed by any part of a program that has access to them.
Variables declared within a block or instance are considered to be declared at instance or nested level. These variables can only be accessed by other parts of an object or object type.
Variables declared at local or default level are only accessible within a certain region of code called a “scope”. These variables can only be accessed by other parts inside their own “scope”.
To conclude this section: make sure to remember all six types of scopes and which variables fall into which ones! To help you do so quickly and efficiently, read through these brief reminders below.
Global Scope
Variables declared at global level cannot be modified by functions or instances unless they are passed in as parameters.
Functions cannot modify global-scoped variables nor can they declare them as parameters nor return them. Global-scoped variables must either be constant or must be initialized before being used.
In order to better understand variable scoping in C++ it is important to know what each kind of scope is and what kinds of variables fall into each one.
To begin with , let’s discuss what constitutes “global” level declarations.
“Global” simply means that a variable is accessible anywhere within your program.