Home Interview Questions and AnswersTechnical Interview Questions and AnswersC Programming C Functions Interview Questions and Answers For Freshers Part-1

c-functions1. When should I declare a function?

Functions that are used only in the current source file should be declared as static, and the function’s declaration should appear in the current source file along with the definition of the function. Functions used outside of the current source file should have their declarations put in a header file, which can be included in whatever source file is going to use that function. For instance, if a function named stat_func() is used only in the source file stat.c, it should be declared as shown here:

/* stat.c */

#include <stdio.h>

static

int
stat_func(
int
,
int
);
/* static declaration of stat_func() */

void
main(
void
);

void
main(
void
)

{

rc = stat_func(
1
,
2
);

}

/* definition (body) of stat_func() */

static

int
stat_func(
int
arg1,
int
arg2)

{

return
rc;

}

In this example, the function named stat_func() is never used outside of the source file stat.c. There is therefore no reason for the prototype (or declaration) of the function to be visible outside of the stat.c source file. Thus, to avoid any confusion with other functions that might have the same name, the declaration ofstat_func() should be put in the same source file as the declaration of stat_func().

In the following example, the function glob_func() is declared and used in the source file global.c and is used in the source file extern.c. Because glob_func() is used outside of the source file in which it’s declared, the declaration of glob_func() should be put in a header file (in this example, named proto.h) to be included in both the global.c and the extern.c source files.

/* proto.h */

int
glob_func(
int
,
int
);
/* declaration of the glob_func() function */

/* global.c */

#include <stdio.h>

#include “proto.h”

/* include this proto.h file for the declaration of glob_func() */

void
main(
void
);

void
main(
void
)

{

rc = glob_func(
1
,
2
);

}

/* definition (body) of the glob_func() function */

int
glob_func(
int
arg1,
int
arg2)

{

return
rc;

}

/* extern.c */

#include <stdio.h>

#include “proto.h”

/* include this proto.h file for the declaration of glob_func() */

void
ext_func(
void
);

void
ext_func(
void
)

{

/* call glob_func(), which is defined in the global.c source file */

rc = glob_func(
10
,
20
);

}

In the preceding example, the declaration of glob_func() is put in the header file named proto.h becauseglob_func() is used in both the global.c and the extern.c source files. Now, whenever glob_func() is going to be used, you simply need to include the proto.h header file, and you will automatically have the function’s declaration.

2. Why should I prototype a function?

A function prototype tells the compiler what kind of arguments a function is looking to receive and what kind of return value a function is going to give back. This approach helps the compiler ensure that calls to a function are made correctly and that no erroneous type conversions are taking place. For instance, consider the following prototype:

int some_func(int, char*, long);

Looking at this prototype, the compiler can check all references (including the definition of some_func()) to ensure that three parameters are used (an integer, a character pointer, and then a long integer) and that a return value of type integer is received. If the compiler finds differences between the prototype and calls to the function or the definition of the function, an error or a warning can be generated to avoid errors in your source code.
prototype of some_func():

x = some_func(
1
);
/* not enough arguments passed */

x = some_func(
“HELLO!”
,
1
,
“DUDE!”
);
/* wrong type of arguments used */

x = some_func(
1
, str,
2879
,
“T”
);
/* too many arguments passed */

/* In the following example, the return value expected

from some_func() is not an integer: */

long
* lValue;

lValue = some_func(
1
, str,
2879
);
/* some_func() returns an int,

not a long* */

Using prototypes, the compiler can also ensure that the function definition, or body, is correct and correlates with the prototype. For instance, the following definition of some_func() is not the same as its prototype, and it therefore would be flagged by the compiler:

int
some_func(
char
*
string
,
long
lValue,
int
iValue)
/* wrong order of

parameters */

{

}

The bottom line on prototypes is that you should always include them in your source code because they provide a good error-checking mechanism to ensure that your functions are being used correctly. Besides, many of today’s popular compilers give you warnings when compiling if they can’t find a prototype for a function that is being referenced.

3. How many parameters should a function have?

There is no set number or “guideline” limit to the number of parameters your functions can have. However, it is considered bad programming style for your functions to contain an inordinately high (eight or more) number of parameters. The number of parameters a function has also directly affects the speed at which it is called—the more parameters, the slower the function call. Therefore, if possible, you should minimize the number of parameters you use in a function. If you are using more than four parameters, you might want to rethink your function design and calling conventions.

One technique that can be helpful if you find yourself with a large number of function parameters is to put your function parameters in a structure. Consider the following program, which contains a function namedprint_report() that uses 10 parameters. Instead of making an enormous function declaration and proto- type, the print_report() function uses a structure to get its parameters:

#include <stdio.h>

typedef

struct

{

int
orientation;

char
rpt_name[
25
];

char
rpt_path[
40
];

int
destination;

char
output_file[
25
];

int
starting_page;

int
ending_page;

char
db_name[
25
];

char
db_path[
40
];

int
draft_quality;

} RPT_PARMS;

void
main(
void
);

int
print_report(RPT_PARMS*);

void
main(
void
)

{

RPT_PARMS rpt_parm;
/* define the report parameter

structure variable */

/* set up the report parameter structure variable to pass to the

print_report() function */

rpt_parm.orientation = ORIENT_LANDSCAPE;

rpt_parm.rpt_name =
“QSALES.RPT”
;

rpt_parm.rpt_path =
“C:\REPORTS”
;

rpt_parm.destination = DEST_FILE;

rpt_parm.output_file =
“QSALES.TXT”
;

rpt_parm.starting_page =
1
;

rpt_parm.ending_page = RPT_END;

rpt_parm.db_name =
“SALES.DB”
;

rpt_parm.db_path =
“C:\DATA”
;

rpt_parm.draft_quality = TRUE;

/* Call the print_report() function, passing it a pointer to the

parameters instead of passing it a long list of 10 separate

parameters. */

ret_code = print_report(&rpt_parm);

}

int
print_report(RPT_PARMS* p)

{

int
rc;

/* access the report parameters passed to the print_report()

function */

orient_printer(p->orientation);

set_printer_quality((p->draft_quality == TRUE) ? DRAFT : NORMAL);

return
rc;

}

The preceding example avoided a large, messy function prototype and definition by setting up a predefined structure of type RPT_PARMS to hold the 10 parameters that were needed by the print_report() function. The only possible disadvantage to this approach is that by removing the parameters from the function definition, you are bypassing the compiler’s capability to type-check each of the parameters for validity during the compile stage.

4. What is a static function?

A static function is a function whose scope is limited to the current source file. Scope refers to the visibility of a function or variable. If the function or variable is visible outside of the current source file, it is said to haveglobal, or external, scope. If the function or variable is not visible outside of the current source file, it is said to have local, or static, scope.

A static function therefore can be seen and used only by other functions within the current source file. When you have a function that you know will not be used outside of the current source file or if you have a function that you do not want being used outside of the current source file, you should declare it as static. Declaring local functions as static is considered good programming practice. You should use static functions often to avoid possible conflicts with external functions that might have the same name.

For instance, consider the following example program, which contains two functions. The first function,open_customer_table(), is a global function that can be called by any module. The second function,open_customer_indexes(), is a local function that will never be called by another module. This is because you can’t have the customer’s index files open without first having the customer table open. Here is the code:

#include <stdio.h>

int
open_customer_table(
void
);
/* global function, callable from

any module */

static

int
open_customer_indexes(
void
);
/* local function, used only in

this module */

int
open_customer_table(
void
)

{

int
ret_code;

/* open the customer table */

if
(ret_code == OK)

{

ret_code = open_customer_indexes();

}

return
ret_code;

}

static

int
open_customer_indexes(
void
)

{

int
ret_code;

/* open the index files used for this table */

return
ret_code;

}

You may also like

Leave a Comment