1) Functions in C/C++

Download as docx, pdf, or txt
Download as docx, pdf, or txt
You are on page 1of 40

Functions:

1)Functions in C/C++
A function is a set of statements that take inputs, do some specific computation and produces output.
The idea is to put some commonly or repeatedly done task together and make a function so that instead of writing
the same code again and again for different inputs, we can call the function.
The general form of a function is:

return_type function_name([ arg1_type arg1_name, ... ]) { code }  


 
Example:
Below is a simple C/C++ program to demonstrate functions.

#include <stdio.h>
  
// An example function that takes two parameters 'x' and 'y'
// as input and returns max of two input numbers
int max(int x, int y)
{
    if (x > y)
      return x;
    else
      return y;
}
  
// main function that doesn't receive any parameter and
// returns integer.
int main(void)
{
    int a = 10, b = 20;
  
    // Calling above function to find max of 'a' and 'b'
    int m = max(a, b);
  
    printf("m is %d", m);
    return 0;
}

C++

#include <iostream>
using namespace std;
  
int max(int x, int y) 

    if (x > y) 
    return x; 
    else
    return y; 

  
int main() {
    int a = 10, b = 20; 
  
    // Calling above function to find max of 'a' and 'b' 
    int m = max(a, b); 
  
    cout << "m is " << m; 
    return 0; 
}

Output:

m is 20

Why do we need functions?


 Functions help us in reducing code redundancy. If functionality is performed at multiple places in
software, then rather than writing the same code, again and again, we create a function and call it
everywhere. This also helps in maintenance as we have to change at one place if we make future
changes to the functionality.
 Functions make code modular. Consider a big file having many lines of codes. It becomes really
simple to read and use the code if the code is divided into functions.
 Functions provide abstraction. For example, we can use library functions without worrying about
their internal working.
Function Declaration
A function declaration tells the compiler about the number of parameters function takes, data-types of parameters
and return type of function. Putting parameter names in function declaration is optional in the function declaration,
but it is necessary to put them in the definition. Below are an example of function declarations. (parameter names
are not there in below declarations)

// A function that takes two integers as parameters


// and returns an integer
int max(int, int);
  
// A function that takes a int pointer and an int variable as parameters
// and returns an pointer of type int
int *swap(int*,int);
  
// A function that takes a charas parameters
// and returns an reference variable
char *call(char b);
  
// A function that takes a char and an int as parameters
// and returns an integer
int fun(char, int);

It is always recommended to declare a function before it is used (See this, this and this for details)


In C, we can do both declaration and definition at the same place, like done in the above example program.
C also allows to declare and define functions separately, this is especially needed in case of library functions. The
library functions are declared in header files and defined in library files. Below is an example declaration.
 
Parameter Passing to functions
The parameters passed to function are called actual parameters. For example, in the above program 10 and 20 are
actual parameters.
The parameters received by function are called formal parameters. For example, in the above program x and y are
formal parameters.
There are two most popular ways to pass parameters.
Pass by Value: In this parameter passing method, values of actual parameters are copied to function’s formal
parameters and the two types of parameters are stored in different memory locations. So any changes made inside
functions are not reflected in actual parameters of caller.

Pass by Reference Both actual and formal parameters refer to same locations, so any changes made inside the
function are actually reflected in actual parameters of caller.
Parameters are always passed by value in C. For example. in the below code, value of x is not modified using the
function fun().

#include <stdio.h>
void fun(int x)
{
   x = 30;
}
  
int main(void)
{
    int x = 20;
    fun(x);
    printf("x = %d", x);
    return 0;
}

C++
#include <iostream>
using namespace std;
  
void fun(int x) {
    x = 30;
}
  
int main() {
    int x = 20;
    fun(x);
    cout << "x = " << x;
    return 0;
}

Output:
x = 20
However, in C, we can use pointers to get the effect of pass by reference. For example, consider the below
program. The function fun() expects a pointer ptr to an integer (or an address of an integer). It modifies the value
at the address ptr. The dereference operator * is used to access the value at an address. In the statement ‘*ptr = 30’,
value at address ptr is changed to 30. The address operator & is used to get the address of a variable of any data
type. In the function call statement ‘fun(&x)’, the address of x is passed so that x can be modified using its
address.

# include <stdio.h>
void fun(int *ptr)
{
    *ptr = 30;
}
   
int main()
{
  int x = 20;
  fun(&x);
  printf("x = %d", x);
   
  return 0;
}

C++

#include <iostream>
using namespace std;
  
void fun(int *ptr)
{
    *ptr = 30;
}
  
int main() {
    int x = 20;
    fun(&x);
    cout << "x = " << x;
      
    return 0;
}

Output:
x = 30
 
Following are some important points about functions in C.
1) Every C program has a function called main() that is called by operating system when a user runs the program.
2) Every function has a return type. If a function doesn’t return any value, then void is used as return type.
Moreover, if the return type of the function is void, we still can use return statement in the body of function
definition by not specifying any constant, variable, etc. with it, by only mentioning the ‘return;’ statement which
would symbolise the termination of the function as shown below:

void function name(int a)


{
.......  //Function Body
return;  //Function execution would get terminated
}             
3) In C, functions can return any type except arrays and functions. We can get around this limitation by returning
pointer to array or pointer to function.
4) Empty parameter list in C mean that the parameter list is not specified and function can be called with any
parameters. In C, it is not a good idea to declare a function like fun(). To declare a function that can only be called
without any parameter, we should use “void fun(void)”.
As a side note, in C++, empty list means function can only be called without any parameter. In C++, both void
fun() and void fun(void) are same.
5)If in a C program, a function is called before its declaration then the C compiler automatically assumes the
declaration of that function in the following way:
int function name();
And in that case if the return type of that function is different than INT ,compiler would show an error.
 
Main Function:
The main function is a special function. Every C++ program must contain a function named main. It serves as the
entry point for the program. The computer will start running the code from the beginning of the main function.

Types of main Function:


1) The first type is – main function without parameters :

// Without Parameters
int main()
{
   ...
   return 0;
}
2) Second type is main function with parameters :
// With Parameters
int main(int argc, char * const argv[])
{
   ...
   return 0;
}
The reason for having the parameter option for the main function is to allow input from the command line.
When you use the main function with parameters, it saves every group of characters (separated by a space) after
the program name as elements in an array named argv.
Since the main function has the return type of int, the programmer must always have a return statement in the
code. The number that is returned is used to inform the calling program what the result of the program’s execution
was. Returning 0 signals that there were no problems.
Importance of function prototype in C
Function prototype tells compiler about number of parameters function takes, data-types of parameters and return
type of function. By using this information, compiler cross checks function parameters and their data-type with
function definition and function call. If we ignore function prototype, program may compile with warning, and
may work properly. But some times, it will give strange output and it is very hard to find such programming
mistakes. Let us see with examples

#include <errno.h>

#include <stdio.h>

  

int main(int argc, char *argv[])

    FILE *fp;

  

    fp = fopen(argv[1], "r");

    if (fp == NULL) {

        fprintf(stderr, "%s\n", strerror(errno));

        return errno;

    }

  

    printf("file exist\n");

  

    fclose(fp);

  

    return 0;

Above program checks existence of file, provided from command line, if given file is exist, then the program
prints “file exist”, otherwise it prints appropriate error message. Let us provide a filename, which does not exist in
file system, and check the output of program on x86_64 architecture.
[narendra@/media/partition/GFG]$ ./file_existence hello.c
Segmentation fault (core dumped)
Why this program crashed, instead it should show appropriate error message. This program will work fine on x86
architecture, but will crash on x86_64 architecture. Let us see what was wrong with code. Carefully go through
the program, deliberately I haven’t included prototype of “strerror()” function. This function returns “pointer to
character”, which will print error message which depends on errno passed to this function. Note that x86
architecture is ILP-32 model, means integer, pointers and long are 32-bit wide, that’s why program will work
correctly on this architecture. But x86_64 is LP-64 model, means long and pointers are 64 bit wide. In C
language, when we don’t provide prototype of function, the compiler assumes that function returns an integer. In
our example, we haven’t included “string.h” header file (strerror’s prototype is declared in this file), that’s why
compiler assumed that function returns integer. But its return type is pointer to character. In x86_64, pointers are
64-bit wide and integers are 32-bits wide, that’s why while returning from function, the returned address gets
truncated (i.e. 32-bit wide address, which is size of integer on x86_64) which is invalid and when we try to
dereference this address, the result is segmentation fault.
Now include the “string.h” header file and check the output, the program will work correctly.
[narendra@/media/partition/GFG]$ ./file_existence hello.c
No such file or directory
Consider one more example.

#include <stdio.h>

  

int main(void)

    int *p = malloc(sizeof(int));

  

    if (p == NULL) {

        perror("malloc()");

        return -1;

    }

  

    *p = 10;

    free(p);

  

    return 0;

Above code will work fine on IA-32 model, but will fail on IA-64 model. Reason for failure of this code is we
haven’t included prototype of malloc() function and returned value is truncated in IA-64 model.

Functions that are executed before and after main() in C

With GCC family of C compilers, we can mark some functions to execute before and after main(). So some
startup code can be executed before main() starts, and some cleanup code can be executed after main() ends. For
example, in the following program, myStartupFun() is called before main() and myCleanupFun() is called after
main().

#include<stdio.h>

  

/* Apply the constructor attribute to myStartupFun() so that it

    is executed before main() */

void myStartupFun (void) __attribute__ ((constructor));

  

  

/* Apply the destructor attribute to myCleanupFun() so that it

   is executed after main() */

void myCleanupFun (void) __attribute__ ((destructor));

  

  

/* implementation of myStartupFun */

void myStartupFun (void)

    printf ("startup code before main()\n");

  

/* implementation of myCleanupFun */

void myCleanupFun (void)

    printf ("cleanup code after main()\n");

  

int main (void)

    printf ("hello\n");

    return 0;

Output:
startup code before main()
hello
cleanup code after main()

return statement vs exit() in main()


In C++, what is the difference between exit(0) and return 0 ?
When exit(0) is used to exit from program, destructors for locally scoped non-static objects are not called. But
destructors are called if return 0 is used.

Program 1 – – uses exit(0) to exit

#include<iostream>

#include<stdio.h>

#include<stdlib.h>

  

using namespace std;

  

class Test {

public:

  Test() {

    printf("Inside Test's Constructor\n");

  }

  

  ~Test(){

    printf("Inside Test's Destructor");

    getchar();

  }

};

  

int main() {

  Test t1;

  

  // using exit(0) to exit from main

  exit(0);

Output:
Inside Test’s Constructor
Program 2 – uses return 0 to exit

#include<iostream>
#include<stdio.h>

#include<stdlib.h>

  

using namespace std;

  

class Test {

public:

  Test() {

    printf("Inside Test's Constructor\n");

  }

  

  ~Test(){

    printf("Inside Test's Destructor");

  }

};

  

int main() {

  Test t1;

  

   // using return 0 to exit from main

  return 0;

Output:
Inside Test’s Constructor
Inside Test’s Destructor
Calling destructors is sometimes important, for example, if destructor has code to release resources like closing
files.
Note that static objects will be cleaned up even if we call exit(). For example, see following program.
#include<iostream>

#include<stdio.h>

#include<stdlib.h>

  

using namespace std;

  

class Test {
public:

  Test() {

    printf("Inside Test's Constructor\n");

  }

  

  ~Test(){

    printf("Inside Test's Destructor");

    getchar();

  }

};

  

int main() {

  static Test t1;  // Note that t1 is static

  

  exit(0);

Output:
Inside Test’s Constructor
Inside Test’s Destructor

How to Count Variable Numbers of Arguments in C?


C supports variable numbers of arguments. But there is no language provided way for finding out total number of
arguments passed. User has to handle this in one of the following ways:
1) By passing first argument as count of arguments.
2) By passing last argument as NULL (or 0).
3) Using some printf (or scanf) like mechanism where first argument has placeholders for rest of the arguments.
Following is an example that uses first argument arg_count to hold count of other arguments.

#include <stdarg.h>

#include <stdio.h>

  

// this function returns minimum of integer numbers passed.  First 

// argument is count of numbers.

int min(int arg_count, ...)

  int i;
  int min, a;

    

  // va_list is a type to hold information about variable arguments

  va_list ap; 

  

  // va_start must be called before accessing variable argument list

  va_start(ap, arg_count); 

     

  // Now arguments can be accessed one by one using va_arg macro

  // Initialize min as first argument in list   

  min = va_arg(ap, int);

     

  // traverse rest of the arguments to find out minimum

  for(i = 2; i <= arg_count; i++) {

    if((a = va_arg(ap, int)) < min)

      min = a;

  }   

  

  //va_end should be executed before the function returns whenever

  // va_start has been previously used in that function 

  va_end(ap);   

  

  return min;

  

int main()

   int count = 5;

     

   // Find minimum of 5 numbers: (12, 67, 6, 7, 100)

   printf("Minimum value is %d", min(count, 12, 67, 6, 7, 100));

   getchar();

   return 0;

}
Output:
Minimum value is 6

What is evaluation order of function parameters in C?


It is compiler dependent in C. It is never safe to depend on the order of evaluation of side effects. For example, a
function call like below may very well behave differently from one compiler to another:
Does C support function overloading?
First of all, what is function overloading? Function overloading is a feature of a programming language that
allows one to have many functions with same name but with different signatures.
This feature is present in most of the Object Oriented Languages such as C++ and Java. But C (not Object
Oriented Language) doesn’t support this feature. However, one can achieve the similar functionality in C
indirectly. One of the approach is as follows.
Have a void * type of pointer as an argument to the function. And another argument telling the actual data type of
the first argument that is being passed.
int foo(void * arg1, int arg2);
Suppose, arg2 can be interpreted as follows. 0 = Struct1 type variable, 1 = Struct2 type variable etc. Here Struct1
and Struct2 are user defined struct types.
While calling the function foo at different places…
foo(arg1, 0); /*Here, arg1 is pointer to struct type Struct1 variable*/
foo(arg1, 1); /*Here, arg1 is pointer to struct type Struct2 variable*/
Since the second argument of the foo keeps track the data type of the first type, inside the function foo, one can
get the actual data type of the first argument by typecast accordingly. i.e. inside the foo function

if(arg2 == 0)

  struct1PtrVar = (Struct1 *)arg1;

else if(arg2 == 1)

  struct2PtrVar = (Struct2 *)arg1;

else

  /*Error Handling*/

}
There can be several other ways of implementing function overloading in C. But all of them will have to use
pointers – the most powerful feature of C.
In fact, it is said that without using the pointers, one can’t use C efficiently & effectively in a real world program!
How can I return multiple values from a function?
We all know that a function in C can return only one value. So how do we achieve the purpose of returning
multiple values.
Well, first take a look at the declaration of a function.

int foo(int arg1, int arg2);

So we can notice here that our interface to the function is through arguments and return value only. (Unless we
talk about modifying the globals inside the function)
Let us take a deeper look…Even though a function can return only one value but that value can be of pointer type.
That’s correct, now you’re speculating right!
We can declare the function such that, it returns a structure type user defined variable or a pointer to it . And by
the property of a structure, we know that a structure in C can hold multiple values of asymmetrical types (i.e. one
int variable, four char variables, two float variables and so on…)
If we want the function to return multiple values of same data types, we could return the pointer to array of that
data types.
We can also make the function return multiple values by using the arguments of the function. How? By providing
the pointers as arguments.

Usually, when a function needs to return several values, we use one pointer in return instead of several pointers as
arguments.
What is the purpose of a function prototype?
The Function prototype serves the following purposes –

1) It tells the return type of the data that the function will return.
2) It tells the number of arguments passed to the function.
3) It tells the data types of the each of the passed arguments.
4) Also it tells the order in which the arguments are passed to the function.
Therefore essentially, function prototype specifies the input/output interlace to the function i.e. what to give to the
function and what to expect from the function.
Prototype of a function is also called signature of the function.
What if one doesn’t specify the function prototype?
Output of below kind of programs is generally asked at many places.

int main()

   foo();

   getchar();
   return 0;

void foo()

   printf("foo called");

If one doesn’t specify the function prototype, the behavior is specific to C standard (either C90 or C99) that the
compilers implement. Up to C90 standard, C compilers assumed the return type of the omitted function prototype
as int. And this assumption at compiler side may lead to unspecified program behavior.

Later C99 standard specified that compilers can no longer assume return type as int. Therefore, C99 became more
restrict in type checking of function prototype. But to make C99 standard backward compatible, in practice,
compilers throw the warning saying that the return type is assumed as int. But they go ahead with compilation.
Thus, it becomes the responsibility of programmers to make sure that the assumed function prototype and the
actual function type matches.
To avoid all this implementation specifics of C standards, it is best to have function prototype.

Static functions in C
Prerequisite : Static variables in C
In C, functions are global by default. The “static” keyword before a function name makes it static. For example,
below function fun() is static.

static int fun(void)

  printf("I am a static function ");

Unlike global functions in C, access to static functions is restricted to the file where they are declared. Therefore,
when we want to restrict access to functions, we make them static. Another reason for making functions static can
be reuse of the same function name in other files.
For example, if we store following program in one file file1.c

/* Inside file1.c */ 

static void fun1(void)

  puts("fun1 called");

And store following program in another file file2.c

/* Inside file2.c  */ 


int main(void)

  fun1(); 

  getchar();

  return 0;  

Now, if we compile the above code with command “gcc file2.c file1.c”, we get the error “undefined reference to
`fun1’” . This is because fun1() is declared static in file1.c and cannot be used in file2.c.
Please write comments if you find anything incorrect in the above article, or want to share more information about
static functions in C.
exit(), abort() and assert()
exit()

void exit ( int status ); 

exit() terminates the process normally.


status: Status value returned to the parent process. Generally, a status value of 0 or EXIT_SUCCESS indicates
success, and any other value or the constant EXIT_FAILURE is used to indicate an error. exit() performs
following operations.
* Flushes unwritten buffered data.
* Closes all open files.
* Removes temporary files.
* Returns an integer exit status to the operating system.
The C standard atexit() function can be used to customize exit() to perform additional actions at program
termination.
Example use of exit.

/* exit example */

#include <stdio.h>

#include <stdlib.h>

   

int main ()

  FILE * pFile;

  pFile = fopen ("myfile.txt", "r");

  if (pFile == NULL)

  {

    printf ("Error opening file");

    exit (1);

  }
  else

  {

    /* file operations here */

  }

  return 0;

When exit() is called, any open file descriptors belonging to the process are closed and any children of the process
are inherited by process 1, init, and the process parent is sent a SIGCHLD signal.
The mystery behind exit() is that it takes only integer args in the range 0 – 255 . Out of range exit values can result
in unexpected exit codes. An exit value greater than 255 returns an exit code modulo 256.
For example, exit 9999 gives an exit code of 15 i.e. (9999 % 256 = 15).
Below is the C implementation to illustrate the above fact:

#include <stdio.h>

#include <stdlib.h>

#include <unistd.h>

#include <sys/types.h>

#include <sys/wait.h>

  

int main(void)

    pid_t pid = fork();

      

    if ( pid == 0 )

    {

       exit(9999); //passing value more than 255

    }

  

    int status;

    waitpid(pid, &status, 0);

  

    if ( WIFEXITED(status) )

    {

        int exit_status = WEXITSTATUS(status);

          

        printf("Exit code: %d\n", exit_status);


    }

  

return 0;

Output:
Exit code: 15
Note that the above code may not work with online compiler as fork() is disabled.
Explanation: It is effect of 8-bit integer overflow. After 255 (all 8 bits set) comes 0.
So the output is “exit code modulo 256”. The output above is actually the modulo of the value 9999 and 256 i.e.
15.

abort()

void abort ( void );

Unlike exit() function, abort() may not close files that are open. It may also not delete temporary files and may not
flush stream buffer. Also, it does not call functions registered with atexit().

This function actually terminates the process by raising a SIGABRT signal, and your program can include a
handler to intercept this signal (see this).
So programs like below might not write “Geeks for Geeks” to “tempfile.txt”

#include<stdio.h>

#include<stdlib.h>

int main()

  FILE *fp = fopen("C:\\myfile.txt", "w");

    

  if(fp == NULL)

  {

    printf("\n could not open file ");

    getchar();

    exit(1);

  }  

    

  fprintf(fp, "%s", "Geeks for Geeks");

    
  /* ....... */

  /* ....... */

  /* Something went wrong so terminate here */  

  abort();

    

  getchar();

  return 0;  

}    

If we want to make sure that data is written to files and/or buffers are flushed then we should either use exit() or
include a signal handler for SIGABRT.

assert()

void assert( int expression );

If expression evaluates to 0 (false), then the expression, sourcecode filename, and line number are sent to the
standard error, and then abort() function is called. If the identifier NDEBUG (“no debug”) is defined with #define
NDEBUG then the macro assert does nothing.
Common error outputting is in the form:
Assertion failed: expression, file filename, line line-number

#include<assert.h>

  

void open_record(char *record_name)

    assert(record_name != NULL);

    /* Rest of code */

  

int main(void)

   open_record(NULL);

Implicit return type int in C


Predict the output of following C program.

#include <stdio.h>
fun(int x)

    return x*x;

int main(void)

    printf("%d", fun(10));

    return 0;

Output: 100
The important thing to note is, there is no return type for fun(), the program still compiles and runs fine in most of
the C compilers. In C, if we do not specify a return type, compiler assumes an implicit return type as int. However,
C99 standard doesn’t allow return type to be omitted even if return type is int. This was allowed in older C
standard C89.
In C++, the above program is not valid except few old C++ compilers like Turbo C++. Every function should
specify the return type in C++.
What happens when a function is called before its declaration in C?
In C, if a function is called before its declaration, the compiler assumes return type of the function as int.
For example, the following program fails in compilation.

#include <stdio.h>

int main(void)

    // Note that fun() is not declared 

    printf("%d\n", fun());

    return 0;

  

char fun()

   return 'G';

if the function char fun() in above code is defined before main() then it will compile and run perfectly.
for example, the following program will run properly.

#include <stdio.h>

  
char fun()

   return 'G';

  

int main(void)

    // Note that fun() is not declared 

    printf("%d\n", fun());

    return 0;

The following program compiles and run fine because function is defined before main().

#include <stdio.h>

  

int fun()

   return 10;

  

int main(void)

    printf("%d\n", fun());

    return 0;

What about parameters? compiler assumes nothing about parameters. Therefore, the compiler will not be able
to perform compile-time checking of argument types and arity when the function is applied to some arguments.
This can cause problems. For example, the following program compiled fine in GCC and produced garbage value
as output.

#include <stdio.h>

  

int main (void)

    printf("%d", sum(10, 5));

    return 0;
}

int sum (int b, int c, int a)

    return (a+b+c);

There is this misconception that the compiler assumes input parameters also int. Had compiler assumed input
parameters int, the above program would have failed in compilation.
Noreturn function specifier in C
After the removal of “noreturn” keyword, C11 standard (known as final draft) of C programming language
introduce a new “_Noreturn” function specifier that specify that the function does not return to the function that it
was called from. If the programmer try to return any value from that function which is declared as _Noreturn type,
then the compiler automatically generates a compile time error.

// C program to show how _Noreturn type 

// function behave if it has return statement.

#include <stdio.h>

#include <stdlib.h>

  

// With return value

_Noreturn void view()

    return 10;

int main(void)

    printf("Ready to begin...\n");

    view();

  

    printf("NOT over till now\n");

    return 0;

Output:
Ready to begin...
After that abnormal termination of program.
compiler error:[Warning] function declared 'noreturn' has a 'return' statement
// C program to illustrate the working 

// of _Noreturn type function.

#include <stdio.h>

#include <stdlib.h>

  

// Nothing to return

_Noreturn void show()

    printf("BYE BYE");

int main(void)

    printf("Ready to begin...\n");

    show();

  

    printf("NOT over till now\n");

    return 0;

Output:
Ready to begin...
BYE BYE

exit() vs _Exit() in C and C++


In C, exit() terminates the calling process without executing the rest code which is after the exit() function.
Example:-
// C program to illustrate exit() function.

#include <stdio.h>

#include <stdlib.h>

int main(void)

    printf("START");

  

    exit(0); // The program is terminated here

  
    // This line is not printed

    printf("End of program");

Output:
START
Now the question is that if we have exit() function then why C11 standard introduced _Exit()? Actually exit()
function performs some cleaning before termination of the program like connection termination, buffer flushes
etc. The _Exit() function in C/C++ gives normal termination of a program without performing any cleanup tasks.
For example it does not execute functions registered with atexit.
Syntax:
// Here the exit_code represent the exit status
// of the program which can be 0 or non-zero.
// The _Exit() function returns nothing.
void _Exit(int exit_code);

// C++ program to demonstrate use of _Exit()

#include <stdio.h>

#include <stdlib.h>

int main(void)

    int exit_code = 10;

    printf("Termination using _Exit");

    _Exit(exit_code);

  

Output:

Showing difference through programs:

// A C++ program to show difference

// between exit() and _Exit()

#include<bits/stdc++.h>

using namespace std;

  

void fun(void)

{
   cout << "Exiting";

  

int main()

   atexit(fun);

   exit(10);

Output
Exiting
If we replace exit with _Exit(), then nothing is printed.

// A C++ program to show difference

// between exit() and _Exit()

#include<bits/stdc++.h>

using namespace std;

  

void fun(void)

   cout << "Exiting";

  

int main()

   atexit(fun);

   _Exit(10);

Output
Predefined Identifier __func__ in C
Before we start discussing about __func__, let us write some code snippet and anticipate the output:

#include <stdio.h>

  

int main()

{
   printf("%s",__func__);

   return 0;

Will it compile error due to not defining variable __func__ ? Well, as you would have guessed so far, it won’t give
any compile error and it’d print main!
C language standard (i.e. C99 and C11) defines a predefined identifier as follows in clause 6.4.2.2:
“The identifier __func__ shall be implicitly declared by the translator as if, immediately following the opening
brace of each function definition, the declaration
static const char __func__[] = “function-name”;
appeared, where function-name is the name of the lexically-enclosing function.”
It means that C compiler implicitly adds __func__ in every function so that it can be used in that function to get
the function name. To understand it better, let us write this code:

#include <stdio.h>

void foo(void)

   printf("%s",__func__);

void bar(void)

   printf("%s",__func__);

  

int main()

   foo();

   bar();

   return 0;

And it’ll give output as foobar. A use case of this predefined identifier could be logging the output of a big
program where a programmer can use __func__ to get the current function instead of mentioning the complete
function name explicitly. Now what happens if we define one more variable of name __func__

#include <stdio.h>

  

int __func__ = 10;

int  main()

{
   printf("%d",__func__);

   return 0;

Since C standard says compiler implicitly defines __func__ for each function as the function-name, we should not
defined __func__ at the first place. You might get error but C standard says “undefined behaviour” if someone
explicitly defines __func__ .
Just to finish the discussion on Predefined Identifier __func__, let us mention Predefined Macros as well (such as
__FILE__ and __LINE__ etc.) Basically, C standard clause 6.10.8 mentions several predefined macros out of
which __FILE__ and __LINE__ are of relevance here.
It’s worthwhile to see the output of the following code snippet:

#include <stdio.h>

  

int main()

   printf("In file:%s, function:%s() and line:%d",__FILE__,__func__,__LINE__);

  

   return 0;

Instead of explaining the output, we will leave this to you to guess and understand the role
of __FILE__ and __LINE__!

Callbacks in C
A callback is any executable code that is passed as an argument to other code, which is expected to call back
(execute) the argument at a given time [Source : Wiki]. In simple language, If a reference of a function is passed
to another function as an argument to call it, then it will be called as a Callback function.
In C, a callback function is a function that is called through a function pointer.
Below is a simple example in C to illustrate the above definition to make it more clear:
// A simple C program to demonstrate callback

#include<stdio.h>

  

void A()

    printf("I am function A\n");

  

// callback function

void B(void (*ptr)())


{

    (*ptr) (); // callback to A

  

int main()

    void (*ptr)() = &A;

      

    // calling function B and passing

    // address of the function A as argument

    B(ptr);

  

   return 0;

I am function A
In C++ STL, functors are also used for this purpose.

Nested functions in C
Last Updated: 05-09-2017

Some programmer thinks that defining a function inside an another function is known as “nested function”. But
the reality is that it is not a nested function, it is treated as lexical scoping. Lexical scoping is not valid in C
because the compiler cant reach/find the correct memory location of the inner function.
Nested function is not supported by C because we cannot define a function within another function in C. We can
declare a function inside a function, but it’s not a nested function.
Because nested functions definitions can not access local variables of the surrounding blocks, they can access only
global variables of the containing module. This is done so that lookup of global variables doesn’t have to go
through the directory. As in C, there are two nested scopes: local and global (and beyond this, built-ins).
Therefore, nested functions have only a limited use. If we try to approach nested function in C, then we will get
compile time error.

// C program to illustrate the

// concept of Nested function.

#include <stdio.h>

int main(void)

    printf("Main");

    int fun()

    {
        printf("fun");

  

        // defining view() function inside fun() function.

        int view()

        {

            printf("view");

        }

        return 1;

    }

    view();

Output:
Compile time error: undefined reference to `view'
An extension of the GNU C Compiler allows the declarations of nested functions. The declarations of nested
functions under GCC’s extension need to be prefix/start with the auto keyword.

// C program of nested function

// with the help of gcc extension

#include <stdio.h>

int main(void)

    auto int view(); // declare function with auto keyword

    view(); // calling function

    printf("Main\n");

  

    int view()

    {

        printf("View\n");

        return 1;

    }

  

    printf("GEEKS");

    return 0;

Output:
view
Main
GEEKS

Parameter Passing Techniques in C/C++

There are different ways in which parameter data can be passed into and out of methods and functions. Let us
assume that a function B() is called from another function A(). In this case A is called the “caller
function” and B is called the “called function or callee function”. Also, the arguments which A sends to B are
called actual arguments and the parameters of B are called formal arguments.
Terminology
 Formal Parameter : A variable and its type as they appear in the prototype of the function or method.
 Actual Parameter : The variable or expression corresponding to a formal parameter that appears in the
function or method call in the calling environment.
 Modes:
 IN: Passes info from caller to calle.
 OUT: Callee writes values in caller.
 IN/OUT: Caller tells callee value of variable, which may be updated by callee.
Important methods of Parameter Passing
1. Pass By Value : This method uses in-mode semantics. Changes made to formal parameter do not get
transmitted back to the caller. Any modifications to the formal parameter variable inside the called function
or method affect only the separate storage location and will not be reflected in the actual parameter in the
calling environment. This method is also called as call by value.

// C program to illustrate

// call by value

#include <stdio.h>

  

void func(int a, int b)


{

    a += b;

    printf("In func, a = %d b = %d\n", a, b);

int main(void)

    int x = 5, y = 7;

  

    // Passing parameters

    func(x, y);

    printf("In main, x = %d y = %d\n", x, y);

    return 0;

Output:

In func, a = 12 b = 7
In main, x = 5 y = 7
Languages like C, C++, Java support this type of parameter passing. Java in fact is strictly call by
value.
Shortcomings:
 Inefficiency in storage allocation
 For objects and arrays, the copy semantics are costly
2. Pass by reference(aliasing) : This technique uses in/out-mode semantics. Changes made to formal
parameter do get transmitted back to the caller through parameter passing. Any changes to the formal
parameter are reflected in the actual parameter in the calling environment as formal parameter receives a
reference (or pointer) to the actual data. This method is also called as <em>call by reference. This method
is efficient in both time and space.
// C program to illustrate

// call by reference

#include <stdio.h>

  

void swapnum(int* i, int* j)

    int temp = *i;

    *i = *j;

    *j = temp;

  

int main(void)

    int a = 10, b = 20;

  

    // passing parameters


    swapnum(&a, &b);

  

    printf("a is %d and b is %d\n", a, b);

    return 0;

Output:
a is 20 and b is 10
C and C++ both support call by value as well as call by reference whereas Java does’nt support call
by reference.
Shortcomings:
 Many potential scenarios can occur
 Programs are difficult to understand sometimes
Other methods of Parameter Passing
These techniques are older and were used in earlier programming languages like Pascal, Algol and Fortran. These
techniques are not applicable in high level languages.
1. Pass by Result : This method uses out-mode semantics. Just before control is transfered back to the caller,
the value of the formal parameter is transmitted back to the actual parameter.T his method is sometimes
called call by result. In general, pass by result technique is implemented by copy.
2. Pass by Value-Result : This method uses in/out-mode semantics. It is a combination of Pass-by-Value and
Pass-by-result. Just before the control is transferred back to the caller, the value of the formal parameter is
transmitted back to the actual parameter. This method is sometimes called as call by value-result
3. Pass by name : This technique is used in programming language such as Algol. In this technique, symbolic
“name” of a variable is passed, which allows it both to be accessed and update.
Example:
To double the value of C[j], you can pass its name (not its value) into the following procedure.
4. procedure double(x);
5. real x;
6. begin
7. x:=x*2
8. end;
In general, the effect of pass-by-name is to textually substitute the argument in a procedure call for
the corresponding parameter in the body of the procedure.
Implications of Pass-by-Name mechanism:
 The argument expression is re-evaluated each time the formal parameter is passed.
 The procedure can change the values of variables used in the argument expression and hence
change the expression’s value.

Power Function in C/C++


Last Updated: 06-11-2019

Given two numbers base and exponent, pow() function finds x raised to the power of y i.e. xy. Basically in C
exponent value is calculated using the pow() function.
Example:
Input: 2.0, 5.0
Output: 32
Explanation:
pow(2.0, 5.0) executes 2.0 raised to
the power 5.0, which equals 32

Input: 5.0, 2.0


Output: 25
Explanation:
pow(5.0, 2.0) executes 5.0 raised to
the power 2.0, which equals 25
Syntax:
double pow(double x, double y);
Parameters: The method takes two arguments:
 x : floating point base value
 y : floating point power value
Program:

// C program to illustrate

// power function

#include <math.h>

#include <stdio.h>

  

int main()

    double x = 6.1, y = 4.8;

  

    // Storing the answer in result.

    double result = pow(x, y);

    printf("%.2lf", result);

  

    return 0;

C++

// CPP program to illustrate

// power function
#include <bits/stdc++.h>

using namespace std;

  

int main()

    double x = 6.1, y = 4.8;

  

    // Storing the answer in result.

    double result = pow(x, y);

  

    // printing the result upto 2

    // decimal place

    cout << fixed << setprecision(2) << result << endl;

  

    return 0;

Output:

5882.79
Working of pow() function with integers
The pow() function takes ‘double’ as the arguments and returns a ‘double’ value. This function does not always
work for integers. One such example is pow(5, 2). When assigned to an integer, it outputs 24 on some compilers
and works fine for some other compilers. But pow(5, 2) without any assignment to an integer outputs 25.
 This is because 52 (i.e. 25) might be stored as 24.9999999 or 25.0000000001 because the return type is
double. When assigned to int, 25.0000000001 becomes 25 but 24.9999999 will give output 24.
 To overcome this and output the accurate answer in integer format, we can add 0.5 to the result and typecast
it to int e.g (int)(pow(5, 2)+0.5) will give the correct answer(25, in above example), irrespective of the
compiler.

// C program to illustrate

// working with integers in

// power function

#include <math.h>

#include <stdio.h>
  

int main()

    int a;

  

    // Using typecasting for

    // integer result

    a = (int)(pow(5, 2) + 0.5);

    printf("%d", a);

  

    return 0;

C++

// CPP program to illustrate

// working with integers in

// power function

#include <bits/stdc++.h>

using namespace std;

int main()

    int a;

  

    // Using typecasting for

    // integer result

    a = (int)(pow(5, 2) + 0.5);

    cout << a;

  

    return 0;

Output:
25
tolower() function in C
Last Updated: 01-10-2018

The tolower() function is defined in the ctype.h header file. If the character passed is a uppercase alphabet then
the tolower() function converts a uppercase alphabet to an lowercase alphabet.
Syntax:
int tolower(int ch);
Parameter: This method takes a mandatory parameter ch which is the character to be converted to lowercase.
Return Value: This function returns the lowercase character corresponding to the ch.
Below programs illustrate the tolower() function in C:

Example 1:-

// C program to demonstrate

// example of tolower() function.

  

#include <ctype.h>

#include <stdio.h>

  

int main()

  

    // Character to be converted to lowercase

    char ch = 'G';

  

    // convert ch to lowercase using toLower()

    printf("%c in lowercase is represented as = %c", ch, tolower(ch));

  

    return 0;

Output:
G in lowercase is represented as = g
Example 2:-

// C program to demonstrate
// example of tolower() function.

  

#include <ctype.h>

#include <stdio.h>

  

int main()

    int j = 0;

    char str[] = "GEEKSFORGEEKS\n";

  

    // Character to be converted to lowercase

    char ch = 'G';

  

    // convert ch to lowercase using toLower()

    char ch;

  

    while (str[j]) {

        ch = str[j];

  

        // convert ch to lowercase using toLower()

        putchar(tolower(ch));

  

        j++;

    }

  

    return 0;

Output:
geeksforgeeks

time() function in C
The time() function is defined in time.h (ctime in C++) header file. This function returns the time since 00:00:00
UTC, January 1, 1970 (Unix timestamp) in seconds. If second is not a null pointer, the returned value is also
stored in the object pointed to by second.
Syntax:
time_t time( time_t *second )
Parameter: This function accepts single parameter second. This parameter is used to set the time_t object which
store the time.
Return Value: This function returns current calender time as a object of type time_t.
Program 1:

// C program to demonstrate

// example of time() function.

#include <stdio.h>

#include <time.h>

  

int main ()

    time_t seconds;

      

    seconds = time(NULL);

    printf("Seconds since January 1, 1970 = %ld\n", seconds);

      

    return(0);

Output:
Seconds since January 1, 1970 = 1538123990
Example 2:

// C program to demonstrate

// example of time() function.

   

#include <stdio.h>

#include <time.h>

   

int main()

    time_t seconds;
   

     // Stores time seconds

    time(&seconds);

    printf("Seconds since January 1, 1970 = %ld\n", seconds);

   

    return 0;

Output:
Seconds since January 1, 1970 = 1538123990

You might also like