-2

Let there be a structure called Employee :

struct Employee
{
    int basicsalary;
    int bonus;
    int netsalary;
};

Let there be a function prototype as follows :

int calc_NetSalary(struct Employee**,int);

Let the variable for an array of structures be declared in main function as follows :

struct Employee emp[100];

Let the function be called in main as follows :

for (i = 0; i < n; i++)
{
    emp[i].netsalary = calc_NetSalary(emp[i],n);    // Warning is here
}

Let the function definition be as follows :

int calc_NetSalary(struct Employee** emp,int n)
{
    int i;
    for(i = 0; i < n; i++)
    {
        emp[i]->netsalary = emp[i]->basicsalary + emp[i]->bonus;
    }
    return emp[i]->netsalary;
}

I don't know what to pass as an argument to the function that expects a parameter with two asterisks (in place of emp above). I am getting a warning as passing argument 1 of ‘calc_NetSalary’ from incompatible pointer type. I know it must be a silly mistake I did or I am not clear about the concepts of pointers. Please help !

Rahul
  • 143
  • 1
  • 17
  • 5
    `parameter type has two asterisks`....run, grab a book a start reading it. – Sourav Ghosh Jul 25 '17 at 12:18
  • 4
    You *do* know what an asterisk in a declaration means? Perhaps you should get a couple of [good beginners books](http://stackoverflow.com/questions/562303/the-definitive-c-book-guide-and-list) and read more about *pointers*? – Some programmer dude Jul 25 '17 at 12:18
  • and do not use markup in pre-formatted blocks. – Sourav Ghosh Jul 25 '17 at 12:19
  • Were you given these definitions, or are you trying to work this out for yourself? – John Bode Jul 25 '17 at 12:19
  • I was very confused by what the heck does `Emp* **emp**` means – Abhinav Gauniyal Jul 25 '17 at 12:20
  • ** emp **, are you inventing a new language (C, C++, C# and now ** C **) ?? – Ryan B. Jul 25 '17 at 12:21
  • 3
    @RyanB. No, just trying to use bold within a code block. – melpomene Jul 25 '17 at 12:25
  • 2
    When passing the array `emp` as a function parameter, it will decay to a pointer to the first element, which will be of type `struct Employee*`. So the current function parameter type of `struct Employee**` doesn't make much sense here. Perhaps it is a mistake in the exercise. Ask your supervisor. – Ian Abbott Jul 25 '17 at 12:25
  • Do you store the result of the whole array as a member of a single element? – BLUEPIXY Jul 25 '17 at 12:27
  • This is a kind of test where the function prototype has to be written as it is. Please tell me what should I put in the first argument of function call so that the type of argument it expects is matched – Rahul Jul 25 '17 at 12:45
  • @RahulPakhare That depends entirely on what the function does with it. – melpomene Jul 25 '17 at 12:50
  • I have added the function code... please take a look – Rahul Jul 25 '17 at 12:56
  • So the function in question seems to expect an array of *pointers* to `struct Employee`: `struct Employee * pemp[100];` – alk Jul 25 '17 at 13:02
  • `void calc_netsalary(struct Employee *emp, int n){ int i; for(i = 0; i < n; i++){ emp[i].netsalary = emp[i].basicsalary + emp[i].bonus; } }` and Call `calc_netsalary(emp, n);` – BLUEPIXY Jul 25 '17 at 13:20
  • or `int calc_netsalary(struct Employee *emp){ return emp->basicsalary + emp->bonus; }` and Call `for (i = 0; i < n; i++) { emp[i].netsalary = calc_NetSalary(&emp[i]); }` in this case You can set within function without setting a return value. – BLUEPIXY Jul 25 '17 at 13:23
  • or `int calc_netsalary(struct Employee emp){ return emp.basicsalary + emp.bonus; }` and Call `for (i = 0; i < n; i++) { emp[i].netsalary = calc_NetSalary(emp[i]); }` in this case You can't set within function. You must use return values. – BLUEPIXY Jul 25 '17 at 13:28
  • 1
    @RahulPakhare: The conditions you have been given do not make sense. The `calc_netSalary` function expects an array of *pointers* to `struct Employee`, but you've been told to declare `emp` as an array of `struct Employee`. It's not just a matter of mismatched types, the *structure* of the data that `calc_netSalary` expects does not match the structure of `emp` in `main`. There's no way you can bash `emp` into the shape that `calc_netSalary` expects. Ask your instructor/supervisor if that's what they really meant. – John Bode Jul 25 '17 at 14:41
  • @BLUEPIXY typo. sorry. – Rahul Jul 25 '17 at 18:10

2 Answers2

5

Expanding on my comment:

The calc_netSalary function expects the data in emp to be laid out like this:

     +---+                 +-------------+-------+-----------+
emp: |   | emp[0] -------> | basicsalary | bonus | netsalary |
     +---+                 +-------------+-------+-----------+
     |   | emp[1] ----+
     +---+            |    +-------------+-------+-----------+
     |   | emp[2] -+  +--> | basicsalary | bonus | netsalary |
     +---+         |       +-------------+-------+-----------+
      ...          |      
                   |       +-------------+-------+-----------+ 
                   +-----> | basicsalary | bonus | netsalary |
                           +-------------+-------+-----------+

That is, each emp[i] is a pointer to an instance of struct Employee.

However, your declaration of emp in main looks like this:

     +-------------+-------+-----------+
emp: | basicsalary | bonus | netsalary | emp[0]
     +-------------+-------+-----------+
     | basicsalary | bonus | netsalary | emp[1]
     +-------------+-------+-----------+
     | basicsalary | bonus | netsalary | emp[2]
     +-------------+-------+-----------+
      ...

That is, each emp[i] is an instance of struct Employee.

Either the declaration of emp in main is wrong, or the definition of calc_netSalary is wrong; they cannot be made to work together. To make emp in main match up with what calc_netSalary expects, it needs to be declared an initialized in one of the following ways:

struct Employee **emp = malloc( sizeof *emp * 100 );
if ( emp )
  for ( size_t i = 0; i < 100; i++ )
    emp[i] = malloc( sizeof *emp[i] );

or

struct Employee *emp[100];
for ( size_t i = 0; i < 100; i++ )
  emp[i] = malloc( sizeof *emp[i] );

If emp is really supposed to be declared as an array of struct Employee, then the calc_netSalary function needs to be changed as follows:

int calc_netSalary(struct Employee* emp,int n)
{
    int i;
    for(i = 0; i < n; i++)
    {
        emp[i].netsalary = emp[i].basicsalary + emp[i].bonus;
    }
    return emp[i].netsalary;
}

If you were told to declare emp as an array of struct Employee and figure out a way to pass it to calc_netSalary such that it would be treated as an array of pointers to struct Employee, then you were given an impossible task. Something is deeply wrong with the assignment.

Edit

Actually, there is a third way around this, but it involves declaring a second array in main and passing that as the argument:

struct Employee emp[100];
struct Employee *emp2[100];
for ( size_t i = 0; i < 100; i++ )
  emp2[i] = &emp[i];
...
calc_netSalary( emp2, 100 );

but I'm assuming the assignment requires you to use emp.

John Bode
  • 119,563
  • 19
  • 122
  • 198
2

Because the use of calc_NetSalary is unclear, the following is one possible scenario.

#include <stdio.h>
#include <stdlib.h>

struct Employee{
    int basicsalary;
    int bonus;
    int netsalary;
};

//This prototype can not be changed!!
//OK, But What kind of use is it?
int calc_NetSalary(struct Employee**, int);

//One scenario

void make_employee(struct Employee **emp, int n);

int main(void){
    struct Employee *emp;
    int n = 100;//It is decided at runtime by user input or something..

    make_employee(&emp, n);
    //.. basicsalary and bonus are determined..
    if(calc_NetSalary(&emp, n))
        puts("done..");
    free(emp);
}

void make_employee(struct Employee **emp, int n){
    *emp = calloc(n, sizeof(struct Employee));
}

int calc_NetSalary(struct Employee** emp,int n){
    if(n < 1 || *emp == NULL)
        return 0;//return false;//Inoperable

    for(int i = 0; i < n; ++i){
        (*emp)[i].netsalary = (*emp)[i].basicsalary + (*emp)[i].bonus;
    }
    return 1;//normal end
}
BLUEPIXY
  • 39,699
  • 7
  • 33
  • 70