C Structure and Function

In this tutorial, you’ll learn to pass struct variables as arguments to a function. You will learn to return struct from a function with the help of examples.

Similar to variables of built-in types, you can also pass structure variables to a function.


Passing structs to functions

We recommended you to learn these tutorials before you learn how to pass structs to functions.

Here’s how you can pass structures to a function

#include <stdio.h>
struct student {
   char name[50];
   int age;
};

// function prototype
void display(struct student s);

int main() {
   struct student s1;

   printf("Enter name: ");

   // read string input from the user until \n is entered
   // \n is discarded
   scanf("%[^\n]%*c", s1.name);

   printf("Enter age: ");
   scanf("%d", &s1.age);

   display(s1); // passing struct as an argument

   return 0;
}

void display(struct student s) {
   printf("\nDisplaying information\n");
   printf("Name: %s", s.name);
   printf("\nAge: %d", s.age);
}

Output

Enter name: Bond
Enter age: 13

Displaying information
Name: Bond
Age: 13  

Here, a struct variable s1 of type struct student is created. The variable is passed to the display() function using display(s1); statement.


Return struct from a function

Here’s how you can return structure from a function:

#include <stdio.h>
struct student
{
    char name[50];
    int age;
};

// function prototype
struct student getInformation();

int main()
{
    struct student s;

    s = getInformation();

    printf("\nDisplaying information\n");
    printf("Name: %s", s.name);
    printf("\nRoll: %d", s.age);
    
    return 0;
}
struct student getInformation() 
{
  struct student s1;

  printf("Enter name: ");
  scanf ("%[^\n]%*c", s1.name);

  printf("Enter age: ");
  scanf("%d", &s1.age);
  
  return s1;
}	

Here, the getInformation() function is called using s = getInformation(); statement. The function returns a structure of type struct student. The returned structure is displayed from the main() function.

Notice that, the return type of getInformation() is also struct student.


Passing struct by reference

You can also pass structs by reference (in a similar way like you pass variables of built-in type by reference). We suggest you to read pass by reference tutorial before you proceed.

During pass by reference, the memory addresses of struct variables are passed to the function.

#include <stdio.h>
typedef struct Complex
{
    float real;
    float imag;
} complex;

void addNumbers(complex c1, complex c2, complex *result); 

int main()
{
    complex c1, c2, result;

    printf("For first number,\n");
    printf("Enter real part: ");
    scanf("%f", &c1.real);
    printf("Enter imaginary part: ");
    scanf("%f", &c1.imag);

    printf("For second number, \n");
    printf("Enter real part: ");
    scanf("%f", &c2.real);
    printf("Enter imaginary part: ");
    scanf("%f", &c2.imag);

    addNumbers(c1, c2, &result); 
    printf("\nresult.real = %.1f\n", result.real);
    printf("result.imag = %.1f", result.imag);
    
    return 0;
}
void addNumbers(complex c1, complex c2, complex *result) 
{
     result->real = c1.real + c2.real;
     result->imag = c1.imag + c2.imag; 
}

Output

For first number,
Enter real part:  1.1
Enter imaginary part:  -2.4
For second number, 
Enter real part:  3.4
Enter imaginary part:  -3.2

result.real = 4.5
result.imag = -5.6  

In the above program, three structure variables c1c2 and the address of result is passed to the addNumbers() function. Here, result is passed by reference.

When the result variable inside the addNumbers() is altered, the result variable inside the main() function is also altered accordingly.

C Storage class

In this tutorial, you will learn about scope and lifetime of local and global variables. Also, you will learn about static and register variables.

Every variable in C programming has two properties: type and storage class.

Type refers to the data type of a variable. And, storage class determines the scope, visibility and lifetime of a variable.

There are 4 types of storage class:

  1. automatic
  2. external
  3. static
  4. register

Local Variable

The variables declared inside a block are automatic or local variables. The local variables exist only inside the block in which it is declared.

Let’s take an example.

#include <stdio.h>

int main(void) {
  
  for (int i = 0; i < 5; ++i) {
     printf("C programming");
  }
  
 // Error: i is not declared at this point
  printf("%d", i);  
  return 0;
}

When you run the above program, you will get an error undeclared identifier i. It’s because i is declared inside the for loop block. Outside of the block, it’s undeclared.

Let’s take another example.

int main() {
    int n1; // n1 is a local variable to main()
}

void func() {
   int n2;  // n2 is a local variable to func()
}

In the above example, n1 is local to main() and n2 is local to func().

This means you cannot access the n1 variable inside func() as it only exists inside main(). Similarly, you cannot access the n2 variable inside main() as it only exists inside func().


Global Variable

Variables that are declared outside of all functions are known as external or global variables. They are accessible from any function inside the program.


Example 1: Global Variable

#include <stdio.h>
void display();

int n = 5;  // global variable

int main()
{
    ++n;     
    display();
    return 0;
}

void display()
{
    ++n;   
    printf("n = %d", n);
}

Output

n = 7

Suppose, a global variable is declared in file1. If you try to use that variable in a different file file2, the compiler will complain. To solve this problem, keyword extern is used in file2 to indicate that the external variable is declared in another file.


Register Variable

The register keyword is used to declare register variables. Register variables were supposed to be faster than local variables.

However, modern compilers are very good at code optimization, and there is a rare chance that using register variables will make your program faster.

Unless you are working on embedded systems where you know how to optimize code for the given application, there is no use of register variables.


Static Variable

A static variable is declared by using the static keyword. For example;

static int i;

The value of a static variable persists until the end of the program.


Example 2: Static Variable

#include <stdio.h>
void display();

int main()
{
    display();
    display();
}
void display()
{
    static int c = 1;
    c += 5;
    printf("%d  ",c);
}

Output

6 11

During the first function call, the value of c is initialized to 1. Its value is increased by 5. Now, the value of c is 6, which is printed on the screen.

During the second function call, c is not initialized to 1 again. It’s because c is a static variable. The value c is increased by 5. Now, its value will be 11, which is printed on the screen.

C Keywords and identifiers

In this tutorial, you will learn about keywords; reserved words in C programming that are part of the syntax. Also, you will learn about identifiers and how to name them.

Character set

A character set is a set of alphabets, letters and some special characters that are valid in C language.

Alphabets

Uppercase: A B C ................................... X Y Z
Lowercase: a b c ...................................... x y z

C accepts both lowercase and uppercase alphabets as variables and functions.

Digits

0 1 2 3 4 5 6 7 8 9

Special Characters

,<>._
();$:
%[]#?
&{}
^!*/|
\~+ 

White space Characters

Blank space, newline, horizontal tab, carriage, return and form feed.


C Keywords

Keywords are predefined, reserved words used in programming that have special meanings to the compiler. Keywords are part of the syntax and they cannot be used as an identifier. For example:

int money;

Here, int is a keyword that indicates money is a variable of type int (integer).

As C is a case sensitive language, all keywords must be written in lowercase. Here is a list of all keywords allowed in ANSI C.

autodoubleintstruct
breakelselongswitch
caseenumregistertypedef
charexternreturnunion
continueforsignedvoid
doifstaticwhile
defaultgotosizeofvolatile
constfloatshortunsigned

All these keywords, their syntax, and application will be discussed in their respective topics. However, if you want a brief overview of these keywords without going further, visit List of all keywords in C programming.


C Identifiers

Identifier refers to name given to entities such as variables, functions, structures etc.

Identifiers must be unique. They are created to give a unique name to an entity to identify it during the execution of the program. For example:

int money;
double accountBalance;

Here, money and accountBalance are identifiers.

Also remember, identifier names must be different from keywords. You cannot use int as an identifier because int is a keyword.


Rules for naming identifiers

  1. A valid identifier can have letters (both uppercase and lowercase letters), digits and underscores.
  2. The first letter of an identifier should be either a letter or an underscore.
  3. You cannot use keywords as identifiers.
  4. There is no rule on how long an identifier can be. However, you may run into problems in some compilers if the identifier is longer than 31 characters.

You can choose any name as an identifier if you follow the above rule, however, give meaningful names to identifiers that make sense. 

C Input &Output (I/O)

In this tutorial, you will learn to use scanf() function to take input from the user, and printf() function to display output to the user.

C Output

In C programming, printf() is one of the main output function. The function sends formatted output to the screen. For example,


Example 1: C Output

#include <stdio.h>    
int main()
{ 
    // Displays the string inside quotations
    printf("C Programming");
    return 0;
}

Output

C Programming

How does this program work?

  • All valid C programs must contain the main() function. The code execution begins from the start of the main() function.
  • The printf() is a library function to send formatted output to the screen. The function prints the string inside quotations.
  • To use printf() in our program, we need to include stdio.h header file using the #include <stdio.h> statement.
  • The return 0; statement inside the main() function is the “Exit status” of the program. It’s optional.

Example 2: Integer Output

#include <stdio.h>
int main()
{
    int testInteger = 5;
    printf("Number = %d", testInteger);
    return 0;
}

Output

Number = 5

We use %d format specifier to print int types. Here, the %d inside the quotations will be replaced by the value of testInteger.


Example 3: float and double Output

#include <stdio.h>
int main()
{
    float number1 = 13.5;
    double number2 = 12.4;

    printf("number1 = %f\n", number1);
    printf("number2 = %lf", number2);
    return 0;
}

Output

number1 = 13.500000
number2 = 12.400000

To print float, we use %f format specifier. Similarly, we use %lf to print double values.


Example 4: Print Characters

#include <stdio.h>
int main()
{
    char chr = 'a';    
    printf("character = %c.", chr);  
    return 0;
} 

Output

character = a

To print char, we use %c format specifier.


C Input

In C programming, scanf() is one of the commonly used function to take input from the user. The scanf() function reads formatted input from the standard input such as keyboards.


Example 5: Integer Input/Output

#include <stdio.h>
int main()
{
    int testInteger;
    printf("Enter an integer: ");
    scanf("%d", &testInteger);  
    printf("Number = %d",testInteger);
    return 0;
}

Output

Enter an integer: 4
Number = 4

Here, we have used %d format specifier inside the scanf() function to take int input from the user. When the user enters an integer, it is stored in the testInteger variable.

Notice, that we have used &testInteger inside scanf(). It is because &testInteger gets the address of testInteger, and the value entered by the user is stored in that address.


Example 6: Float and Double Input/Output

#include <stdio.h>
int main()
{
    float num1;
    double num2;

    printf("Enter a number: ");
    scanf("%f", &num1);
    printf("Enter another number: ");
    scanf("%lf", &num2);

    printf("num1 = %f\n", num1);
    printf("num2 = %lf", num2);

    return 0;
}

Output

Enter a number: 12.523
Enter another number: 10.2
num1 = 12.523000
num2 = 10.200000

We use %f and %lf format specifier for float and double respectively.


Example 7: C Character I/O

#include <stdio.h>
int main()
{
    char chr;
    printf("Enter a character: ");
    scanf("%c",&chr);     
    printf("You entered %c.", chr);  
    return 0;
}   

Output

Enter a character: g
You entered g.

When a character is entered by the user in the above program, the character itself is not stored. Instead, an integer value (ASCII value) is stored.

And when we display that value using %c text format, the entered character is displayed. If we use %d to display the character, it’s ASCII value is printed.


Example 8: ASCII Value

#include <stdio.h>
int main()
{
    char chr;
    printf("Enter a character: ");
    scanf("%c", &chr);     

    // When %c is used, a character is displayed
    printf("You entered %c.\n",chr);  

    // When %d is used, ASCII value is displayed
    printf("ASCII value is % d.", chr);  
    return 0;
}

Output

Enter a character: g
You entered g.
ASCII value is 103.

I/O Multiple Values

Here’s how you can take multiple inputs from the user and display them.

#include <stdio.h>
int main()
{
    int a;
    float b;

    printf("Enter integer and then a float: ");
  
    // Taking multiple inputs
    scanf("%d%f", &a, &b);

    printf("You entered %d and %f", a, b);  
    return 0;
}

Output

Enter integer and then a float: -3
3.4
You entered -3 and 3.400000

Format Specifiers for I/O

As you can see from the above examples, we use

  • %d for int
  • %f for float
  • %lf for double
  • %c for char

Here’s a list of commonly used C data types and their format specifiers.

Data TypeFormat Specifier
int%d
char%c
float%f
double%lf
short int%hd
unsigned int%u
long int%li
long long int%lli
unsigned long int%lu
unsigned long long int%llu
signed char%c
unsigned char%c
long double%Lf