0

I can't figure out why this wont run. I am supposed to storehours * payrate in the wages array and then showResults take this info and cout it. The error i get when i run it is

error LNK2019: unresolved external symbol "void __cdecl showResults(int * const,int,double * const,double * const,double * const)" (?showResults@@YAXQAHHQAN11@Z) referenced in function
error LNK2019: unresolved external symbol "void __cdecl getEmployeeData(int * const,int,double * const,double * const,double * const)" (?getEmployeeData@@YAXQAHHQAN11@Z) referenced in function `_main`

Code below:

#include <iomanip>
#include <iostream>
using namespace std;

void getEmployeeData(int[], int, double[], double[], double[]);
void showResults(int[], int, double[], double[], double[]);


int main()
{
const int ARRAY_SIZE = 7;
int empId[ARRAY_SIZE] = {565, 845, 452, 130, 789, 758, 877};

double hoursWorked[ARRAY_SIZE]; // Holds hours worked
double payrate[ARRAY_SIZE]; // Holds pay rate
double wages[ARRAY_SIZE]; // Holds wages

getEmployeeData(empId, ARRAY_SIZE, payrate, hoursWorked, wages);

showResults(empId, ARRAY_SIZE, payrate, hoursWorked, wages);

system("pause");
    return 0;
}

void getEmployeedata(int nums[],int size,double pay[],double hours[],
double wages[])
{

//Hours worked and Pay rate
for(int index = 0; index < size; index++)
{
    cout << "Enter number of hours worked by employee number "
         << nums[index] << ": ";
    cin >> hours[index]; 
    cout << "\nEnter hourly pay rate ";
    cin >> pay[index];
    wages[index] = hours[index] * pay[index]; 
}
}

void showResults(int nums[], int size, double pay, double hours, double wages[])
{
for(int index = 0; index < size; index++)
{
    cout << "Employee Number Gross Wage " << endl
         << nums[index] << " " << wages[index];

}

}
andrew
  • 33
  • 5
user1807815
  • 83
  • 2
  • 12
  • The C++ Standard Library provides a rich set of [container types](http://en.cppreference.com/w/cpp/container). These can easily be passed in and out of functions. You should use these instead of old-school arrays. – moooeeeep Apr 06 '13 at 18:26

4 Answers4

3

The declaration and definition of showResults disagree about argument types. In particular, the pay and hours arguments are double[] in the declaration but only double in the definition.

void showResults(int[], int, double[], double[], double[]) // Declaration
//                                 ↕↕        ↕↕
void showResults(int[], int, double  , double  , double[]) // Definition

It appears that the declaration is correct and the definition is not, since you are passing arrays to them.

Your declaration and definitions of getEmployeeData disagree about the name.

void getEmployeeData(int[], int, double[], double[], double[]) // Declaration
/               ↕
void getEmployeedata(int[], int, double[], double[], double[]) // Definition

You probably want getEmployeeData to be consistent with the rest of your naming.

Joseph Mansfield
  • 108,238
  • 20
  • 242
  • 324
  • Thanks! i must've been overlooking that – user1807815 Apr 06 '13 at 18:24
  • Better yet, `double *`. Having array-types parameters is a convenient lie, they get turned into pointers. (OTOH reference to array is a distinct type) – Ben Voigt Apr 06 '13 at 18:24
  • @Ben Voigt So instead of double[], it should be double*? Why is that? – user1807815 Apr 06 '13 at 18:33
  • @user1807815: Because the language says the actual parameter type is `double*`, even if you write `double[]`. (Implication: If you use `sizeof` inside the function, you get the size of a pointer) – Ben Voigt Apr 06 '13 at 18:44
1

Your function names have typo:

getEmployeeData(empId, ARRAY_SIZE, payrate, hoursWorked, wages);

However, in definition youhave:

getEmployeedata(...);

also mismatch here:

 void showResults(int nums[], int size, double pay, double hours, double wages[])
                                            //^^^^^^^^^^^^^^^^^
andrew
  • 33
  • 5
1

If you want to pass arrays to functions, also try writing functions as

void getEmployeeData(int*, int, double*, double*, double*);
void showResults(int*, int, double*, double*, double*);

because when you pass array, you are passing pointer to the 0th index of that array. Also, as told, there is a typo in your code, replace getEmployeedata with getEmployeeData

Here is the corrected code :

#include <iomanip>
#include <iostream>
using namespace std;

void getEmployeeData(int*, int, double*, double*, double*);
void showResults(int*, int, double*, double*, double*);


int main()
{
const int ARRAY_SIZE = 7;
int empId[7] = {565, 845, 452, 130, 789, 758, 877};

double hoursWorked[ARRAY_SIZE]; // Holds hours worked
double payrate[ARRAY_SIZE]; // Holds pay rate
double wages[ARRAY_SIZE]; // Holds wages

getEmployeeData(empId, ARRAY_SIZE, payrate, hoursWorked, wages);

showResults(empId, ARRAY_SIZE, payrate, hoursWorked, wages);

system("pause");
    return 0;
}

void getEmployeeData(int nums[],int size,double pay[],double hours[],double wages[])
{

//Hours worked and Pay rate
for(int index = 0; index < size; index++)
{
    cout << "Enter number of hours worked by employee number "
         << nums[index] << ": ";
    cin >> hours[index];
    cout << "\nEnter hourly pay rate ";
    cin >> pay[index];
    wages[index] = hours[index] * pay[index];
}
}

void showResults(int *nums, int size, double *pay, double *hours, double *wages)
{
for(int index = 0; index < size; index++)
{
    cout << "Employee Number Gross Wage " << endl
         << nums[index] << " " << wages[index];

}

}
tigerden
  • 728
  • 2
  • 11
  • 28
  • What's the difference between a pointer and the way that i had it? In my book the only way i see it is like []. – user1807815 Apr 06 '13 at 18:35
  • There is no difference apart from syntax, see [this](http://stackoverflow.com/questions/5573310/difference-between-passing-array-and-array-pointer-into-function-in-c) – tigerden Apr 07 '13 at 18:16
0

Since you know exactly how many elements each array has, you can try making ARRAY_SIZE a global constant (so it's in the same scope as your function prototypes), allowing you to do something like this:

void getEmployeeData(int (&)[ARRAY_SIZE], int, double (&)[ARRAY_SIZE], double (&)[ARRAY_SIZE], double (&)[ARRAY_SIZE]);
void showResults(int (&)[ARRAY_SIZE], int, double (&)[ARRAY_SIZE], double (&)[ARRAY_SIZE], double (&)[ARRAY_SIZE]);

void getEmployeeData(int (&nums)[ARRAY_SIZE], int size, double (&pay)[ARRAY_SIZE], double (&hours)[ARRAY_SIZE], double (&wages)[ARRAY_SIZE]) {
// Function body
}
void showResults(int (&nums)[ARRAY_SIZE], int size, double (&pay)[ARRAY_SIZE], double (&hours)[ARRAY_SIZE], double (&wages)[ARRAY_SIZE]) {
// Function body
}

Now, this looks awkward, but what it does is tell the compiler that the function takes references to arrays with exactly ARRAY_SIZE elements. (Specifically, [] has higher precedence than &, so you need the parentheses to tell the compiler that the argument is a reference to an array instead of an array of references.) It also allows you to use the ol' C sizeof(nums)/sizeof(nums[0]) to determine the arrays' size; unlike letting the array decay into a pointer (in which case sizeof would give you useless information because it sees nums as an int* instead of an int[ARRAY_SIZE]), passing it by reference preserves this information.


Alternatively, if you're free to rewrite the code and your compiler supports C++11, you can use std::array instead of C-style arrays.

#include <array>
using namespace std;

void getEmployeeData(array<int, ARRAY_SIZE>, int, array<double, ARRAY_SIZE>, array<double, ARRAY_SIZE>, array<double, ARRAY_SIZE>);
void showResults(array<int, ARRAY_SIZE>, int, array<double, ARRAY_SIZE>, array<double, ARRAY_SIZE>, array<double, ARRAY_SIZE>);


array<int, ARRAY_SIZE> empId = {565, 845, 452, 130, 789, 758, 877};

array<double, ARRAY_SIZE> hoursWorked; // Holds hours worked
array<double, ARRAY_SIZE> payrate; // Holds pay rate
array<double, ARRAY_SIZE> wages; // Holds wages

As a container, std::array can be used with the same syntax as a C-style array (i.e. operator[]), so you shouldn't need to rewrite any of the code that actually uses the arrays. It also lets getEmployeeData() and showResults() check the arrays' size directly, with something like nums.size().

Also note that if you use either of these, you don't actually need to pass int size, since you can use sizeof or std::array.size(). This does have the downside of polluting the global namespace a bit, though, but I personally consider it to be a fair tradeoff for the security of guaranteeing that your code will only compile if the functions are given properly sized arrays.

[Note that if you need to be able to pass differently sized arrays at different times, neither of these methods will be of use to you.]

I apologise for any typoes I may have missed.