How to pass array of pointers to structures using functions in C?

#include<stdio.h>
#define dept_count 3
struct employee
 {
   char name[20],
    post[20];
   int emp_no;
   int basic_pay;
 };
void search( struct employee * , char , int );
  void main()
 {
    struct employee *deptt[dept_count];
    int i,j,emp_count[10],dep_srch;
    char emp_srch[20];

    clrscr();

    for(i = 0 ; i < dept_count ; i ++)
    {
    printf("\nenter the number of employees in dept %d : ",i+1);
    scanf("%d",&emp_count[i]);
    for(j = 0 ; j < emp_count[i] ; j ++)
    {
     printf("\nEnter Employee Number : ");
     scanf("%d",&deptt[i]->emp_no);
     printf("\nEnter Employee's name : ");
     scanf("%s",deptt[i]->name);
     printf("\nEnter Employees post: ");
     scanf("%s",deptt[i]->post);
     printf("\nEnter Employees basic pay: ");
     scanf("%d",&deptt[i]->basic_pay);
    }
    }


      for(i = 0 ; i < dept_count ; i ++)
       {
     printf("\n\t\tDepartment %d: \n\n", i+1);
     printf("\n\nEmp_no ");
     printf("\tName  ");
     printf("\tPost  ");
     printf("\tBasic pay ");

    for(j = 0 ; j < emp_count[i] ; j ++)
    {
     printf("\n\n%d",deptt[i]->emp_no);
     printf("\t%s",deptt[i]->name);
     printf("\t%s",deptt[i]->post);
     printf("\t%d",deptt[i]->basic_pay);
    }

    }

    printf("\n\nEnter the Deptt. No in which employee is to be searched:");
    scanf("%d",&dep_srch);
    printf("\nEnter the employee name:");
    scanf("%s",emp_srch);

    search(deptt[dep_srch],emp_srch[20],emp_count[dep_srch]);
 getch();

 }


void search (struct employee &dept , char name[], int emp_count)
 {
   int i,j;
  for(i= 0 ; i < emp_count ; i++)
     {
           j = 0;
         while(dept[i] == name[j]  && name[j] != '\0')
          {
             j++;
          }

        if(name[j]=='\0')
          {
             printf("\n\tString found at index %d",i+1);
             break;
        }

         }

           if(name[j]!='\0')
           printf("\n\tString not found....");


 }

Edited 3 Years Ago by Dani: Formatting fixed

Why didn't you use CODE TAGs? Information is posted all over this site about CODE tags, like
1) in the Rules you were asked to read when you registered
2) in the text at the top of this forum
3) in the announcement at the top of this forum titled Please use BB Code and Inlinecode tags
4) in the sticky post above titled Read Me: Read This Before Posting
5) any place CODE tags were used, even in responses to your posts
6) Even on the background of the box you actually typed your message in!

How to pass array of pointers to structures using functions in C?

Pointers are very regular. Once you know the basics, you can apply those basics to any level of indirection and everything will work the same way. Start with the two basic rules:

  1. A pointer variable is declared by appending * to the type.
  2. A pointer value is acquired by using the & unary operator.

Obviously things like this follow those rules, and you can find tons of examples in books or online:

int obj = 5;
int* p = &obj; /* p is a pointer to int and refers to obj's adress */

Pointers are used to pass large objects around without copying them, to dynamically manage blocks of memory, and to simulate pass-by-reference semantics. Pass-by-reference basically means that changes to a function parameter will affect the original object and not just a copy of it.

The two rules are recursive within limits, so you can add another level of indirection and get a pointer to a pointer:

int obj = 5;
int* p = &obj;
int** pp = &p; /* &&obj will not work because &obj is not an object with an address */

Pointers to pointers are usually used to simulate pass-by-reference semantics on pointers or to manage dynamic multidimensional arrays. The lesson to take away from this is pointers are just another type, and you can add a level of indirection to almost any type.

Arrays are an anomaly on the surface because they have weird rules until you learn that in almost all cases, an array decays into a pointer. If you have an array int arr[10]; then in all but two general cases, any use of arr will be equivalent to &arr[0] . That is why arrays can be changed when passed to a function. Pass-by-reference is simulated by default. It is also why the sizeof operator does not work on array parameters:

#include <stdio.h>

void Function(char a[])
{
    printf("%lu\n", (unsigned long)sizeof a); /* will not print 20 */
    a[0] = 'B';
}

int main()
{
    char a[20] = "Test";

    printf("%lu\n", (unsigned long)sizeof a); /* prints 20 */
    Function(a);
    puts(a); /* prints "Best" instead of "Test" */

    return 0;
}

Because array parameters are always pointers, you can replace the array notation with pointer notation in the parameter list and the functionality is exactly the same:

void Function(char *a)
{
    printf("%lu\n", (unsigned long)sizeof a); /* will not print 20 */
    a[0] = 'B';
}

All of this brings me to the part that is relevant for your question. An array of pointers follows the two basic rules too. Add a * to the type of the array and it becomes an array of pointers:

int arr[10]; /* array of 10 int */
int* arr[10]; /* array of 10 pointers to int */

Function parameters have the same declaration rules as regular variables, so to pass an array of pointers to a function, you do the same thing as declaring an array of pointers. But do not forget that an array parameter is still a pointer:

#include <stdio.h>

void Function(int* a[], size_t sz)
{
    size_t x;

    for (x = 0; x < sz; ++x) printf("%d\n", *a[x]);
}

int main()
{
    int obj[] = {1, 2, 3, 4, 5};
    int* ap[sizeof obj / sizeof *obj];
    size_t x;

    for (x = 0; x < 5; ++x) ap[x] = &obj[x];

    Function(ap, 5);

    return 0;
}

The array notation can still be condensed into pointer notation, and the result is a pointer to whatever the underlying type is. In this case, a pointer to a pointer:

void Function(int** a, size_t sz)
{
    size_t x;

    for (x = 0; x < sz; ++x) printf("%d\n", *a[x]);
}

Now a struct is just another type, so it should be easy to jump from passing an array of pointers to int to passing an array of pointers to struct. The same rules apply:

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

struct Test
{
    int value;
};

void TestFunction(struct Test* a[], size_t sz)
{
    size_t x;

    for (x = 0; x < sz; ++x)
    {
        if (a[x]) printf("%d\n", a[x]->value);
    }
}

int main()
{
    struct Test* test[5];
    const size_t sz = 5;
    size_t x;

    for (x = 0; x < sz; ++x)
    {
        test[x] = malloc(sizeof test[x]);
        test[x]->value = x;
    }

    TestFunction(test, sz);

    for (x = 0; x < sz; ++x) free(test[x]);

    return 0;
}

The array notation can still be condensed, if you feel so inclined:

void TestFunction(struct Test** a, size_t sz)
{
    size_t x;

    for (x = 0; x < sz; ++x)
    {
        if (a[x]) printf("%d\n", a[x]->value);
    }
}

I should also note that multidimensional arrays are not the same as n-ary pointers. int a[5][5]; is not the same type as int** a; when decaying. Only the first dimension decays into a pointer, so when decaying, int a[5][5]; is equivalent to int (*a)[5]; . This is a pointer to an array of 5 ints. The first dimension decaying rule is important to remember because it trips up a lot of programmers when they want to pass multidimensional arrays to functions.

I did not go into all of the details where they are not relevant to your question, but this should be enough to help you with your code now and give you a good foundation in how pointers work for the future. :)

Comments
Another great post :)
This article has been dead for over six months. Start a new discussion instead.