C++ Header File Interaction - c++

Ok, so I am pretty new to C++, I have a couple of questions about header files...
1.) Which variables should you declare, and which should you not in a header file?
2.) When you declare a variable in a header file, should you use extern?
Here is my header file:
#ifndef MAIN_H
#define MAIN_H
class Main
{
public:
int main(); //Constructor
virtual ~Main(); //Destructor
double initialVelocity;
double initialAngle;
private:
double degToRad(double angle);
void simulate(double angle, double velocity);
};
#endif
And here is my Main.cpp
/*******************************************************************
* This program will take input for initial velocity (fps), and a launch angle
* based on this information, the current posotion of the object thrown will be
* calculated until it hits the ground.
*
*
* Date: 30 August 2013
* Version 1.0
*
**/
# include "Main.h"
# include <iostream>
# include <fstream>
# include <cmath>
using namespace std;
/******************************************************************
* General Variables
**/
const int GRAVITY_FACTOR = -16;
const int GROUND = 0;
const double PI = atan(1.0)*4;
double initialVelocity;
double initialAngle;
/******************************************************************
* degToRad function.
*
* This function takes in an angle in degrees, and converts it to
* radians.
*
**/
double degToRad(double angle){
return angle * (PI/180);
}
/******************************************************************
* simulate function.
*
* Takes in the angle in radians, and the velocity. Calculates the
* path of the projectile, and displays it in the terminal.
*
**/
void simulate(double angle, double velocity){
cout << "Entering Simulation" << endl;
double time = 0;
double x = 1;
double y = 1;
double veloUp = 0;
double veloFo = 0;
veloUp = (velocity*sin(angle));
veloFo = (velocity*cos(angle));
cout << "Angle in radians: " << angle << endl;
cout << "Initial velocity upwards (fps): " << veloUp << endl;
cout << "Initial velocity forward (fps): " << veloFo << endl;
while(y >= GROUND){
x = veloFo * time;
y = GRAVITY_FACTOR*(time*time) + (veloUp * time);
cout << "(x, y) at time " << time << " is (" << x << ", " << y << ")" << endl;
++time;
} //while
cout << "Leaving Simulation" << endl;
} //simulate
/***************************************************************************
* The main function.
*
* Produces output to the console in order to coach the user on what to input.
**/
int main()
{
cout << "Execution Beginning" << endl;
cout << "Enter the inital velocity (feet per second):" << endl;
cin >> initialVelocity;
if(initialVelocity > 0){
cout << "Good. " << initialVelocity << " is a valid value for the initial velocity." << endl;
}
else{
cout << "ERROR: " << initialVelocity << " is not a valid value for the initial velocity." <<endl;
return 0;
}
cout << "Enter the initial angle in degrees (from the horizontal):" << endl;
cin >> initialAngle;
if(initialAngle >= 0 && initialAngle <= 90){
cout << "Good. " << initialAngle << " is a valid value for the initial angle." << endl;
}
else{
cout << "ERROR: " << initialAngle << " is not a valid value for the initial angle." << endl;
return 0;
}
simulate(degToRad(initialAngle), initialVelocity);
cout << "Ending Execution" << endl;
return 0;
}
Like I said, I am new to C++, can anyone please explain how these two interact, or what I should do to make them interact more efficiently. The program compiles, and runs correctly, but I am unclear on the protocol and uses of header files with a .cpp file. Also, which functions and variables should be in the private section of the header, and which should go in the public? Thank you.

I think you need to know 2 Things:
Whats the difference between declaration and definition.
you need a declaration to use a class or function (for the compiler to know its there)
the definition is the code that gets compiled (function body, initialization)
What does #include do.
#include just copies the content of the header into the source file including it.
That means, that you probably don’t want definitions in your header files, because if multiple files include your header, you violate the One-Definition-Rule, causing multiple-defintion-errors during the linking stage.
Which variables should you declare, and which should you not in a header file?
The header-file is your interface to other source-files that want to call your functions/use your classes.
So you put in declarations for things which are needed for other source files to work.
When you declare a variable in a header file, should you use extern?
The extern Keyword specifies a declaration for a variable rather than a definition.
Which means that your variable-definition is somewhere else (e.g. your source file).
If you want to use GRAVITY_FACTOR in another source file, which includes your header:
in your source: const int GRAVITY_FACTOR = -16;
in hour header: extern const int GRAVITY_FACTOR;
Remarks:
what you currently have in your header file is a class definition
public and private are accessors to your class’ members
you may rather want a namespace here or plain functions
the main function has nothing to do inside a class definition

In the header file,you can declare all class fields and functions,that you will implement in the cpp file.
You should'nt declare the variables that you will use inside your class functions(because there are like temp variables),But you can declare(and should) const varables,that you will use in your progamm.
You should'nt use extern,extern its for variables that you dont define them,and the compiler doesnt bother you about that,because when its extern,that means that the variable is defined somewhere else in your progamm.
extern is also used for functions that you want to treat your c++ code,as it were in C.
like:
extern "C" { //code. }
or extern "C" int func(int a);
In conclusion-
delcare const variables in .h file,and the classes.else - in cpp(unless its inline).
in your case:
const int GRAVITY_FACTOR = -16;
const int GROUND = 0;
const double PI = atan(1.0)*4;
are better to be in the .h file
+
you shouldnt declare it again:
double initialVelocity;
double initialAngle;
its already in .h file.
Hope it was useful..

Related

static float * myVar initialization

Using C++, I declared the following static variable in a class SavingsAccount
static float *waitingInQueue;
But I'm not able to initialize the data pointed, I'm only able to initialize the address of the pointer as follows : float* SavingsAccount::waitingInQueue=0;
I would like the data of this pointer initialized at 0. I don't want to use a setter because I need to be able to initialized it once without using an object of the class SavingsAccount. I would like to do the following statement outside a function : *waitingInQueue=0;
Here is my header file :
#ifndef SAVINGSACCOUNT_H
#define SAVINGSACCOUNT_H
class SavingsAccount
{
public:
SavingsAccount();
float getInterestDue(){return *interestDue;};
float getAmountDue() {return *amountDue;};
int getArrivalTime() {return *arrivalTime;};
int getFinishTime() {return *finishTime;};
void setFinishTime(int newTime) {*finishTime=newTime;};
float computeInterestDue();
// compute the interest due...
float computeAmountDue();
// compute the total amount due
void waitingClient();
// increment *arrivalTime
void waitingProcess();
// increment *finishTime checking if there is not another client already processing, in that case make him wait during the previous client processing
void display();
// display the information about 1 client
void saveAccounts();
// save the information of the 20 clients
// void setWaitingInQueue(float x) {*waitingInQueue=x;}; <- can't be used
private:
float clientTable[8];
// information about a single client
static float globalTable[20][8];
static int clientCount;
float *customerID;
static float *arrivalTime;
static float *finishTime;
static const float depositType[6];
float *depositAmount;
static const float interestRate[12];
float *interestDue;
float *amountDue;
float *PtrDepType, *PtrRate;
static float *waitingInQueue;
};
#endif /* SAVINGSACCOUNT_H */
Here is my .cpp
#ifndef SAVINGSACCOUNT_CPP
#define SAVINGSACCOUNT_CPP
#include<cstdlib>
#include <iostream>
#include <ctime> // include to get the number of seconds since 1970 (srand))
#include <iomanip> // to set precision of numbers setprecision()
#ifdef WIN32
#include <windows.h> // for windows
#else
#include <unistd.h>
#endif // win32 // for unix
#include "SavingsAccount.h"
using namespace std;
float SavingsAccount::globalTable[20][8];
int SavingsAccount::clientCount=0;
const float SavingsAccount::depositType[6]={0.25, 0.5, 1, 2, 3, 5};
const float SavingsAccount::interestRate[]={1.71, 1.80, 2.07, 2.25, 2.25, 2.52, 2.70, 3.06, 3.24, 3.69, 3.60, 4.14};
float* SavingsAccount::arrivalTime;
float* SavingsAccount::finishTime;
float* SavingsAccount::waitingInQueue=0; // should be *waitingInQueue = 0;
SavingsAccount::SavingsAccount()
{
clientCount++;
int index;
srand(time(NULL)); //
index=rand()%6; //
customerID=&clientTable[0];
arrivalTime=&clientTable[1];
finishTime=&clientTable[2];
PtrDepType=&clientTable[3]; // &depositType[index]
depositAmount=&clientTable[4];
PtrRate=&clientTable[5]; // &interestRate[N]
interestDue=&clientTable[6];
amountDue=&clientTable[7];
*customerID=clientCount;
*PtrDepType=depositType[index];
*depositAmount=(rand()%49+1)*1000;
if (clientCount<=10) *PtrRate=interestRate[2*index]; // N=2*index
else *PtrRate=interestRate[2*index+1]; // N=2*index+1
}
float SavingsAccount::computeInterestDue()
{
*interestDue=*PtrDepType*(*depositAmount)**PtrRate*(1-0.2)/100;
}
float SavingsAccount::computeAmountDue()
{
*amountDue=*depositAmount+*interestDue;
}
void SavingsAccount::waitingClient()
{
if (clientCount==1) *arrivalTime=0;
else {
int milliseconds=(rand()%6+3)*1000; // random time in milliseconds
#ifdef WIN32 // for windows
Sleep(milliseconds);
#else // for unix
usleep(milliseconds * 1000); // nano seconds have to be multiplied by 1000
#endif // win32
*arrivalTime = *arrivalTime+milliseconds/1000;
}
}
void SavingsAccount::waitingProcess()
{
if(*finishTime < *arrivalTime)
{
*waitingInQueue =*arrivalTime-*finishTime;
}
int milliseconds=(rand()%6+2)*1000; // random time in milliseconds
#ifdef WIN32
Sleep(milliseconds);
#else
usleep(milliseconds * 1000);
#endif // win32
*finishTime= *arrivalTime + milliseconds/1000 + *waitingInQueue;
}
void SavingsAccount::saveAccounts()
{
globalTable[clientCount-1][0]=*customerID;
globalTable[clientCount-1][1]=*arrivalTime;
globalTable[clientCount-1][2]=*finishTime;
globalTable[clientCount-1][3]=*PtrDepType;
globalTable[clientCount-1][4]=*depositAmount;
globalTable[clientCount-1][5]=*PtrRate;
globalTable[clientCount-1][6]=*interestDue;
globalTable[clientCount-1][7]=*amountDue;
}
void SavingsAccount::display()
{
cout << setprecision(0) << setw(4) << right << clientTable[0];
cout << setprecision(0) << setw(7) << right << clientTable[1];
cout << setprecision(0) << setw(8) << right << clientTable[2];
cout << setprecision(2) << setw(10) << right << fixed << clientTable[3];
cout << setprecision(2) << setw(12) << right << clientTable[4];
cout << setprecision(2) << setw(7)<< right << clientTable[5];
cout << setprecision(2) << setw(12)<< right << clientTable[6];
cout << setprecision(2) << setw(12)<< right << clientTable[7] << endl;
}
#endif
The idea of the program is to display information about 20 clients that are arriving every x seconds (3static float *waitingInQueue; to increase the finishing time of all the client if needed.
If you have any other idea to easily simulated a queue I would be interested.
Even if *waitingInQueue = 0; were valid outside a function, it would be incorrect because you're initializing the pointer to null.
The easiest way to do what you're asking is something like this:
class SavingsAccount
{
...
private:
static float zero;
static float* waitingInQueue;
};
float SavingsAccount::zero = 0.0f;
float SavingsAccount::waitingInQueue = &SavingsAccount::zero;
You can initialise your static variable in many different ways -- but you should be asking a different question - "How can I get rid of my static variables?". static variables are often a sign that something is not quite right, and in that light I think you have a pretty large design problem here.
I'd group all your static variables into a Branch object. Then have each SavingsAccount have a pointer to their Branch. And add a newAccount() to Branch for creation. Then you have no more statics and everything is neater (and easier to test).
There also seems to be a lot of uses of pointers where non-pointer types would be OK, and cases where fixed length arrays are used, but would be improved by switching to std::vector<>

C++ Can't figure out output for a class that holds player information. It outputs garbage

I've been pulling my hair out trying to figure out this program. The class has to hold 3 player's info and output their info. My output function is not outputting from my set/get functions. Also, if I output the array indexes the program crashes (that's the array indexes are commented out in the Output function).
edit: I'll just show one profile to keep the code smaller
Any help is appreciated.
#include <cstdlib>
#include <iostream>
using namespace std;
class PlayerProfile
{
public:
void output();
void setName1(string newName1); //player's name
void setPass1(string newPass1); //player's password
void setExp1(int newExp1); //player's experience
void setInv1(string newInv1[]); //player's inventory
void setPos1(int newX1, int newY1); //player's position
string getName1();
string getPass1();
int getExp1();
string getInv1();
int getPos1();
private:
string name1;
string pass1;
int exp1;
string inv1[];
int x1;
int y1;
};
int main(int argc, char *argv[])
{
PlayerProfile player;
cout << "This program generates three player objects and displays them." << endl;
cout << endl;
player.output();
system("PAUSE");
return EXIT_SUCCESS;
}
void PlayerProfile::setName1(string newName1)
{
newName1 = "Nematocyst";
name1 = newName1;
}
void PlayerProfile::setPass1(string newPass1)
{
newPass1 = "obfuscator";
pass1 = newPass1;
}
void PlayerProfile::setExp1(int newExp1)
{
newExp1 = 1098;
exp1 = newExp1;
}
void PlayerProfile::setInv1(string newInv1[])
{
newInv1[0] = "sword";
newInv1[1] = "shield";
newInv1[2] = "food";
newInv1[3] = "potion";
inv1[0] = newInv1[0];
inv1[1] = newInv1[1];
inv1[2] = newInv1[2];
inv1[3] = newInv1[3];
}
void PlayerProfile::setPos1(int newX1, int newY1)
{
newX1 = 55689;
x1 = newX1;
newY1 = 76453;
y1 = newY1;
}
string PlayerProfile::getName1()
{
return name1;
}
string PlayerProfile::getPass1()
{
return pass1;
}
int PlayerProfile::getExp1()
{
return exp1;
}
string PlayerProfile::getInv1()
{
return inv1[0], inv1[1], inv1[2], inv1[3];
}
int PlayerProfile::getPos1()
{
return x1, y1;
}
void PlayerProfile::output()
{
cout << "Player Info - " << endl;
cout << "Name: " << name1 << endl;
cout << "Password: " << pass1 << endl;
cout << "Experience: " << exp1 << endl;
cout << "Position: " << x1 << ", " << y1 << endl;
cout << "Inventory: " << endl;
/*cout << inv1[0] << endl;
cout << inv1[1] << endl;
cout << inv1[2] << endl;
cout << inv1[3] << endl; */
}
This is the output that I am getting:
This program generates three player objects and displays them.
Player Info -
Name:
Password:
Experience: -2
Position: 3353072, 1970319841
Inventory:
Press any key to continue . . .
I'm sorry if I sound like an idiot, this is the first time I have programmed with classes and I am very confused.
First:
You do not have a constructor declared or defined in your class so when you compile, the compiler provides you with a default constructor.
The line
PlayerProfile player;
calls the default constructor provided by the compiler. This default constructor only allocates memory for your class member variables, but does not set their values. This is why name1, pass1, exp1, x1, y1 are not outputting what you expect.
Second:
C++ will not call get or set functions for you, and I think you are misunderstanding how c++ functions work.
this
void PlayerProfile::setName1(string newName1)
{
name1 = newName1;
}
is a function definition. You do not need to assign newName1 inside the function. It's value is passed to the function when a line like
setName1("Nematocyst");
is executed.
If you write a constructor, you can use it to call your set functions, and pass them the values you want to set member variables to.
If you do not want to write a constructor, you can call class functions/methods from main with:
player.setName1("Nematocyst");
Third:
Your program crashes because you are not using arrays properly. Here is a tutorial on how to declare an array and access it's contents.
Generally, I think you are trying to run before you know how to walk. Try not to get frustrated. Learn how arrays work, how functions work, and then how classes work. I hope this is not your homework assignment!

Setting Default Parameters in C++

I have a little question about how default values are given to function parameters in C++. The problem I faced is probably due to my lack of understanding as to where the parameters are supposed to be declared/defined in the function prototype or the function header, or both? Codes are below with the errors noted:
#include <iostream>
using namespace std;
float volume(float l, float w, float h);
int main() {
float length;
float width;
float height;
cout << volume() << endl; // Here, with 'volume()' underlined, it says:
//no matching function for call to 'volume()'
cout << "Length: ";
cin >> length;
cout << "Width: ";
cin >> width;
cout << "Height: ";
cin >> height;
cout << "Volume = " << volume(length, width, height) << endl;
}
float volume(float l = 1, float w = 1, float h = 1){
float vol = l * w * h;
return vol;
}
In another attempt, here's what happened:
#include <iostream>
using namespace std;
float volume(float l = 1, float w = 1, float h = 1);
int main() {
float length;
float width;
float height;
cout << volume() << endl;
cout << "Length: ";
cin >> length;
cout << "Width: ";
cin >> width;
cout << "Height: ";
cin >> height;
cout << "Volume = " << volume(length, width, height) << endl;
}
float volume(float l = 1, float w = 1, float h = 1){ //Here, Xcode says that
// that the error is: Redefinition of default argument. < which I believe I understand.
float vol = l * w * h;
return vol;
}
In my last attempt, which is the one that worked, I did this:
#include <iostream>
using namespace std;
float volume(float l = 1, float w = 1, float h = 1);
int main() {
float length;
float width;
float height;
cout << volume() << endl;
cout << "Length: ";
cin >> length;
cout << "Width: ";
cin >> width;
cout << "Height: ";
cin >> height;
cout << "Volume = " << volume(length, width, height) << endl;
}
float volume(float l, float w, float h){
float vol = l * w * h;
return vol;
}
Could someone please explain to me the logic behind why the latter worked while the first two did not? Is there another way that the code would still work in the same way with the parameters specified elsewhere or the default values set in some place else? Are there any conventions or more favored practices in this area?
Adam
C++ and C are parsed top-down. When the compiler interprets a statement, it doesn't know about things it hasn't read yet.
In your first example, you declare a function called "volume", prototyped as taking 3 floats and returning a float. You then try to call a function called "volume" that takes no parameters, which doesn't exist yet (it would be a different function, since C++ supports polymorphism). You later define a function that can take 0, 1, 2, or 3 floats, but it is both too late and has an incompatible prototype to the first.
Your second example intuitively makes sense to be wrong, kind of like defining variables twice, but I don't have any specific information about why it is invalid code when the default values are identical.
Default parameters must be specified in the function prototype, which must occur prior to first usage in order for the compiler to know about it. Typically, you would put the prototypes with their default values in a header file that gets included above the code.
One thing to watch out for when dealing with default parameters from a shared header file, especially if you use it with dynamic libraries: The default values for the parameters are stored with the caller, and not the function being called. That is, if you update the function with new default values and don't rebuild the code calling that function, the old defaults will still be used by the calling code.
Adding to the above answer from Bjarne Stroustrup
A default argument is type checked at the time of the function declaration and evaluated at the time of the call. Default arguments may be provided for trailing arguments only. For example:
int f (int, int =0 , char * =0 ); // ok
int g (int =0 , int =0 , char *); // error
int h (int =0 , int , char * =0 ); // error
A default argument can be repeated in a subsequent declaration in the same scope but not changed.
For example:
void f (int x = 7 );
void f (int = 7 ); // ok
void f (int = 8 ); // error: different default arguments
void g () { void f (int x = 9 ); // ok: this declaration hides the outer one }
Declaring a name in a nested scope so that the name hides a declaration of the same name in an outer scope is error prone.
Default values could be defined in function declaration, as you done in your third attempt. This means usually they're appeared in header files, although this is not a rule.
Note that function declarations are scoped. This means that you could have more than one declaration for a function as long as they have different scopes:
void f(int);
int main() {
f(3); // argument should specified.
void f(int = 1);
f(); // calls f(1)
}
void f(int n = 2) {
}
void g() {
f(); // calls f(2)
}
In your second attempt you put default values on both declaration and definition of the function. This cause the compiler to confused because they are in the same scope.

Compiler error : 'area' not declared in this scope

I've just started learning c++ and am trying to write a program for finding the area of a circle. I've written the program and whenever I try to compile it I get 2 error messages. The first is:
areaofcircle.cpp:9:14: error: expected unqualified-id before numeric constant
and the second is:
areaofcircle.cpp:18:5: error: 'area' was not declared in this scope
What should I do? I would post a picture, but I'm a new user, so I can't.
#include <iostream>
using namespace std;
#define pi 3.1415926535897932384626433832795
int main()
{
// Create three float variable values: r, pi, area
float r, pi, area;
cout << "This program computes the area of a circle." << endl;
// Prompt user to enter the radius of the circle, read input value into variable r
cout << "Enter the radius of the circle " << endl;
cin >> r;
// Square r and then multiply by pi area = r * r * pi;
cout << "The area is " << area << "." << endl;
}
The problem is relatively simple. See below.
#define pi 3.1415926535897932384626433832795
int main()
{
// Create three float variable values: r, pi, area
float r, pi, area;
...
Notice you use a macro expansion for pi. This replaces the variable name pi in your declaration with the text 3.1415926535897932384626433832795. This causes the error seen here:
error: expected unqualified-id before numeric constant
Now, since this caused parsing to fail on that statement, area winds up never being declared (since it's after pi). As a result, you also then recieve the following error:
error: 'area' was not declared in this scope
Note that you also actually assign neither pi nor area... you need to do that first.
As a general rule of thumb, don't use macros for constants in C++.
#include <iostream>
#include <cmath>
int main() {
using std::cin;
using std::cout;
using std::endl;
using std::atan;
cout << "This program computes the area of a circle." << endl;
cout << "Enter the radius of the circle " << endl;
float r;
cin >> r;
float pi = acos(-1.0f);
float area = 2 * pi * r;
cout << "The area is " << area << '.' << endl;
return 0;
}
For starters, you never actually assign anything to 'area', so it remains undefined (effectively contains a random number). Try adding the line area = r * r * pi; before the last cout. You also want to remove the float pi from the variable list since it collides with the #define pi at the top. Later, when you learn about #include <math> you may find an M_PI constant inside so that you don't have to do it yourself.
Modified code that builds and works fine :
///--------------------------------------------------------------------------------------------------!
// file: Area.cpp
//
// summary: console program for SO
#include <iostream>
using namespace std;
const double PI = 3.1415926535897932384626433832795;
int main()
{
// Create three float variable values: r, pi, area
double r, area;
cout << "This program computes the area of a circle." << endl;
// Prompt user to enter the radius of the circle, read input value into variable r
cout << "Enter the radius of the circle " << endl;
cin >> r;
// Square r and then multiply by pi area = r * r * pi;
area = PI*r*r;
cout << "The area is " << area << "." << endl;
return 0;
}

'SalesTaxPct' was not declared in this scope

I am new to C++. I am struggling with the pass by value thing, and no one can explain what I am doing wrong to me in a way I can understand. I know this is my fault, but Ii am asking for help with my code. HELP PLEASE!
#include <iostream>
using namespace std;
double getValues();
double getSalesTax(double SalesTaxPct);
double gettotal_price(double base, double opt);
void PrintFinal(double base,double opt,double SalesTaxPct);
// function to control all other functions
int main()
{
getValues();
getSalesTax(SalesTaxPct);
PrintFinal(base,pt,SalesTaxPct);
}
// function to calculate sales tax percent into decimal
double getSalesTax( double SalesTaxPct )
{
double SalesTax;
SalesTax = SalesTaxPct / 100;
return SalesTax;
}
// function to find total
double gettotal_price(double base, double opt, double SalesTax)
{
return = (base + opt) * (1 + SalesTax);
}
// function to show user all values input and also total
void PrintFinal(double base, double opt, double SalesTaxPct)
{
cout << "Base vehicle price: $" << base << endl;
cout << "Options Price: $" << opt << endl;
cout << "Sales tax pct: " << SalesTaxPct << "%" << endl;
cout << "Total vehicle price: $" << gettotal_price(double base, double opt, double SalesTax) << endl;
}
// function to get input values
void getValues()
{
double base, double opt, double SalesTaxPct;
cout << "Enter a base vehicle price: " << endl;
cin >> base;
cout << "Enter options price: " << endl;
cin >> opt;
cout << "Enter a sales tax percent: " << endl;
cin >> SalesTaxPct;
}
When you are in main, let's go over what the program sees:
int main()
{
getValues();
getSalesTax(SalesTaxPct);
PrintFinal(base,pt,SalesTaxPct);
}
The only variables that your program knows about at this point are: getValues(), getSalesTax(), gettotal_price(), and PrintFinal(). The warning is telling you that at this point of your program, SalesTaxPct was not declared yet, and looking at our list of variables / functions that the program knows about, we see that, indeed, SalesTaxPct is not on the list. Where do we expect the value of SalesTaxPct to come from?
It looks like that comes from the function getValues, and we are getting it from user input. However, any time that you have { ... }, the stuff inside the braces cannot be accessed outside. Therefore, SalesTaxPct is only "in scope" inside the function getValues. If you want it to be accessible outside of that function (which you do), you need to change things around a bit.
int main()
{
double base;
double opt;
double SalesTaxPct;
getValues(base, opt, SalesTaxPct);
getSalesTax(SalesTaxPct);
PrintFinal(base, opt, SalesTaxPct);
}
Now all of our variables still exist when we need them in main. However, there is still a problem here. We want the changes we pass into getValues to change the variables in main. This means we cannot pass "by value" because that will first make a copy, and then change those copies (not what we want). Instead, we need to say that the changes we make need to be returned from the function some how:
void getValues(double & base, double & opt, double & SalesTaxPct);
That little & there means that rather than making a copy and changing that copy, we are telling the function to operate on the variable we pass in directly. This is referred to as "pass by reference".
There are some similar problems in other parts of your code, but perhaps now you can figure out how to fix them.