Showing posts with label c. Show all posts
Showing posts with label c. Show all posts

Tuesday, September 1, 2020

Gentle Introduction to C : Array

Originally Posted on SeedBx 


Welcome to the ninth part of the Gentle Introduction to C series. As said before this series aims to provide you a brief introduction to C language.

In this post, we will learn about a very basic data structure, namely single-dimensional array, often just called array.


Interesting Fact : Array is at the base of computer memory. Computer memory is just a very big array.


Array

Array is a collection of similar objects or items which are stored in a contiguous fashion.

Let us understand this definition by breaking it into two parts.


Collection of Similar Items

Array can be used to store almost any data type. However given the data type, we cannot store data items of any other kind in it.

Example :

Sample Valid Array


The above array is valid and is an example of an int type array.

Sample Invalid Array


However, the above array is invalid because the array contains more than one type, namely char, float and int.


Stored in Contiguous Manner

Array elements, in the computer memory, are stored in contiguous memory locations. Hence by knowing the memory address of any of the elements of an array, we can reach to any other array element by just traversing the memory addresses in a linear fashion.


Note : Array elements in C (and most of the programming languages) can be accessed using their index. Indexes are like placeholder which can be used to get information or value at any position in the array. In C, 0-based indexing is used i.e. the first element is at the 0th index position.

Example :

Indexing in Array


Declaring an Array

An array in C can be declared in three different ways.

1.    Declaration by Specifying Size

  datatype arr_name[size];

2.    Declaration by Initialising Array

  datatype arr_name[]={items, in, a, comma, seperated, list};

3.    Declaration by Specifying Size and Initialising Array

  datatype arr_name[size]={size, items, in, a, comma, seperated, list};

For example,

int a[10];

char name[]={'a', 'a', 'y', 'u', 's', 'h'};

char foo[6]={'r', 'a', 'n', 'd', 'o','m'};

In the above code snippet, three arrays have been declared one, a, of int type of size 10 and the others, name and foo, of char type and size 6.


Note : An array declaration like,

char bar[1]={'m', 'o', 'h', 'a', 'n'};

will not give a compiler error and rather will just give a warning. However this declaration is not encouraged.


Accessing Array Elements

As said above, array elements can be accessed using indexes. In C (and many similar programming languages), indexes start at 0 and are always positive.

To access the nth element in an array arr_name we will write the array name followed by the index in square brackets i.e.

     arr_name[n-1]

For example, in the above given array name, if we want to access the first char, we can do so by

    name[0];


Note :

     arr[-1];

arr[100];

In C, there is no index out of bound checking i.e. if for a given array, arr of size 10, the above code snippet will not give any error, however the results returned will be unexpected and totally garbage.


Array is a data structure that is not only limited to C and rather is fundamental to almost all programming languages. There are some flaws in array, particularly it's static nature, which are overcame in many other array-like data structures. However array is often the starting point for many applications.

There is still much to be said about arrays, in particular of it's other variant i.e. multi-dimensional array but I will leave that for another post.


Thanks for reading.


Also See : Function, Pointers

Tuesday, August 18, 2020

Gentle Introduction to C : extern Keyword

Originally Posted on SeedBx


Welcome to the seventh part of the Gentle Introduction to C series. As said before this series aims to provide you a brief introduction to C language.

In this part, we will be talking about the keyword extern.

However before talking about about extern keyword, let us just refresh our mind with the understanding of declaration and definition.

Declaration : Declaration of a variable or a function, as the name suggests, declares the variable or the function. However, during the declaration of a variable or function no memory is allocated for the entities. The sole purpose of declaration is to tell the compiler or the program about the type of variable or number of arguments, type of each argument,return type (in case of functions).

Definition : Definition of a variable or function, as the name suggests, defines the variable or the function. Definition of a variable or function, in addition to what declaration does, allocates memory for the entities. Hence, you can consider definition as a super set of declaration i.e. all definitions are declarations but all declarations are not definitions.

Note : Declaration of a variable or function can occur many times. However, a variable or function can only be defined once. This is due to the fact that a single variable  or function cannot be defined at multiple memory locations.

Now let's talk about extern keyword.

extern Keyword

The sole purpose of extern keyword is to extend the visibility of a variable or function. By visibility here I mean the scope of the variable or the function.

In case of variables, extern keyword can also be used to declare a variable.

Let us try to understand this using an example.

        int a;
In the line above the variable a is defined i.e. memory has been allocated to the variable a.

        extern int a;
In the line above the variable a is declared only i.e. memory has not been allocated to the variable 'a'.

So, if write a code like,
        extern int a;
        int main()
        {
            a=0;
            return 0;
        }
The code above will throw an error, as the variable a is only declared and not defined. So the code above essentially is trying to change the value of a memory location which doesn't exists.

So, we can modify the code as,
        #include "fileContainingDefinitionOfa.h"
        extern int a;
        int main()
        {
            a=0;
            return 0;
        }
Assuming that the file fileContainingDefinitionOfa.h contains the definition of variable a, the above code will compile successfully.

Note : If the variable declared using extern keyword is initialised, then the compiler allocates memory to the variable and hence implicitly defines the variable.

Example :
        extern int a=0;
        int main()
        {
            a=100;
            return 0;
        }
The above code will not throw any errors.

In case of functions, extern keyword is used to extend the visibility of the function. 
Since, the extern extends the visibility of the function to the whole program, the function can be called from any files provided that those files contains the declaration of the function.
With functions, the extern keyword is implicitly assumed whenever a function is declared or defined i.e.
        int foo (int a, int b)
is treated by the compiler as
        extern int foo (int a,int b)


At last, using extern keyword is a great way to define and declare global variables and often useful when certain functionalities and variables are to be shared among several files.


Thanks for reading.

As usual your suggestions and feedback are always welcome.


Also See : Pointers, Function, void Pointer

Monday, July 20, 2020

Gentle Introduction to C : void Pointer

Originally Posted on SeedBx

 

Welcome to the sixth part of the Gentle Introduction to C series. As said before this series aims to provide you a brief introduction to C language.

In this part we will be talking about a specific and special pointer, void pointer.


void Pointer

Each pointer has a data-type associated with it which specifies about the type of variable which the pointer will point to. A void pointer, unlike others, is a pointer which has no data-type associated with it. Due to this, a void pointer can be used to hold memory address of any data-type and can be type casted into any type.

Example -

          void *ptr;

          int a=1;

          ptr=&a;

          char c=’z’;

          ptr=&c;

As shown in the above example, the void pointer variable ‘ptr’ is at first, used to store the memory address of an int variable ‘a’ and later used to store the memory address of char variable ‘c’.


Uses :

  • malloc() and calloc() functions, which are used to dynamically allocate memory, return a void pointer allowing these functions to be used to allocate memory for any data-type.

Example -

             int *a=malloc(sizeof(int)*n);

In the above example, we have used malloc() to dynamically allocate memory for an int type array ‘a’ of size ‘n’. This behaviour is only possible due to the fact that malloc() returns a void pointer.

Note : The above example will not work with C++, as it requires the return void pointer to be explicitly type casted to the desired type.

Hence the above example in C++ will be written as,

            int *a=(int *)malloc(sizeof(int)*n);

  • void pointers are generally used to implement generic functions.

Facts : 

  • void pointers cannot be dereferenced.

Example-

            int a=21;

            void *ptr=&a;

            printf(“%d, *ptr);  //-(i)

            printf(“%d, *(int *)ptr);  //-(ii)

In the example given above, the printf() function at line-(i) will give an error like “Compiler Error : ‘void*’ is not a pointer-to-object type”. However if we run the program without line-(i), the printf() function at line-(ii) will display the value of the int variable ‘a’, which is 10, due to the fact that void pointer variable ‘ptr’ was explicitly type-casted into an int pointer.

  • The C-Standard doesn’t allow pointer arithmetic with void pointers.

Note : In GNU C pointer arithmetic is allowed by considering the size of void to be 1. However this might not be the case with other compilers.

 

At last, void pointers provide a sense of generality in the field of pointers. However this freedom is often accompanied by certain restrictions to make things efficient and let operations be under control.

 

Thanks for reading.

As usual your suggestions and feedback are always welcome.


Also See : Pointers, Function, extern Keyword


Friday, July 17, 2020

Gentle Introduction to C : Pointers

Originally Posted on SeedBx


Welcome to the fifth part of the Gentle Introduction to C series. As said before this series aims to provide you a brief introduction to C language.

In this part we will be talking about one of the powerful features of C, pointers.


Before starting with pointers, let’s first start by looking at how data is actually stored in the computer memory.

Representation of Variables in Memory

For every variable defined, at the run-time, the compiler assigns/allocates a particular unit of memory (depending on the type of the variable) to the variable which can be uniquely identified with the help of an address id. The address simply specifies the location where a particular variable is stored in memory. If you like, you can even think of the computer memory as a huge array in which the address is simply the index of the position at which the variable is stored.


Note : The allocation behavior is totally compiler dependent, and therefore certain irregularities might be experienced across various compilers usually due to the fact that different compilers may use different techniques to optimise working.

Pointers

The primary job of pointers is to store addresses of other variables or memory location. Each pointer has a particular data type which just specifies the type of data to which the pointer will point to. However there is some uniqueness about void data type.

For example, a typical definition of a pointer will look like,

datatype *var_name;

The asterisk (*) there specifies that the variable defined is a not a normal variable and rather it is a pointer.

The pointer is basically intended to do two operations, namely access the address of a variable and store it, which is done using the ‘address of’ unary operator & (ampersand) and to access the value stored at the location which the pointer points to which can be done using the ‘at address’ unary operator * (asterisk). The latter operation is also called Dereferencing.


Note : The dereferencing operator * and the asterisk (*) at the declaration should not be confused with each other. It is just a typical situation of overloading of an operator and the two operators have no relation among them.


& Operator

The & operator is used to access the address of a variable.

Example -

          int *ptr;

          ptr=&a;

In the given example, the address of the variable ‘a’ (assumed to be declared somewhere before) is stored in the pointer variable ‘ptr’.

* Operator

The * operator is used to access the value stored at the address which the pointer points to.

Example -

          int *ptr;

          ptr=&a;

          int b;

          b=*ptr;

In the given example, the value of the variable ‘a’ is actually assigned to the variable ‘b’ using the pointer variable ‘ptr’.

Illustration specifying the basic working of Pointers

Note : The size of a pointer variable is typically 4 bytes or 8 bytes. The size of a pointer variable is compiler dependent and it often varies from one compiler to the other.

At last, pointers are a pretty powerful tool to manipulate and play with the addresses of different variables in order to optimise various workings and often handle dynamically defined structures.

 

Thanks for reading.

As usual your suggestions and feedback are always welcome.


Also See : Header Files, Functions, Call by Value and Reference


Monday, June 22, 2020

Gentle Introduction to C : Call by Value and Reference

Originally Posted on SeedBx


Welcome to the fourth part of the Gentle Introduction to C series. As said before this series aims to provide you a brief introduction to C language.

In this part we will be looking at call by value and call by reference.


Before talking about call by value and call by reference let’s get some more terminologies under our belt.

Function Call : It is a request made by the program by using the function name and a list of parameters (if any) enclosed in braces.

Formal Parameters :  These are the parameters which are defined in the function.

Actual Parameters : These are the parameters that the caller location passes to the function.

Interesting Fact : C is case-sensitive

 

Call By Value

Call by Value is a function calling technique in which the formal parameters and actual parameters are different independent variables, more so the formal parameters are separate variables which share the same value. Internally what happens is when a function is called by value the values of the actual parameters are copied to the formal parameters (dummy variables). As the formal parameters and actual parameters are different, any changes made to formal parameters are not reflected in actual parameters.

Example-

    Code :

    #include<stdio.h>
    void callByValue(int a)
    {
        a=3;
        printf("Value of Formal Parameter = %d\n", a);
    }
    int main()
    {
        int a;
        a=2;
        callByValue(a);
        printf("Value of Actual Parameter = %d", a);
        return 0;
    }

    Output :

        Value of Formal Parameter = 3
        Value of Actual Parameter = 2

As you can notice above, the value of 'a' in the main() function is not affected by the change in the value of 'a' in callByValue() function.

 

Call By Reference

Call by reference is a function calling technique in which the formal parameters and actual parameters are actually identical variables, i.e. they share the same memory location internally. Call by reference can be initiated by passing either pointers to the variable or passing reference to the variable. As the formal and actual parameter share the same memory location, any changes to the formal parameters is actually reflected in the actual parameters.

Example-

    Code :

    #include<stdio.h>
    void callByReference(int &a)
    {
        a=3;
        printf("Value of Formal Parameter = %d\n", a);
    }
    int main()
    {
        int a;
        a=2;
        callByReference(a);
        printf("Value of Actual Parameter = %d", a);
        return 0;
    }

    Output :

        Value of Formal Parameter = 3
        Value of Actual Parameter = 3

 

As you can notice above, the value of 'a' in the main() function is affected by the change in the value of 'a' in callByReference() function.

Both of these function calling techniques have their fair share of uses in actual applications, however the calling technique to be used totally depends on the use case.

 

As always your suggestions are welcome. 

Do comment out what are some interesting ways in which you use these calling techniques.

 

Wednesday, June 17, 2020

Gentle Introduction to C : main() Function

Originally Posted on SeedBx


Welcome to the third part of the Gentle Introduction to C series. As said before this series aims to provide you with a brief introduction to C language.

In this part we are going to look at one of the most important function in C, the main() function.

 

main()

The main() function, as many like to say, is the entry point of a C program. It is the function that is executed at the beginning of any program. Intuitively you can also understand the main() function as an user-defined function.

 

Note : Technically the main function is not the actual entry point as the entry point is compiler depended.

 

At the basic level, the main() function is similar to a normal function, having its own return value, parameters and definition. But unlike any other function, the main function is called by the operating system ( all other functions are actually called by the main function or any other function). This happens primarily because whenever a program runs, the operating system has to pass the control of the computer over to the program. The main() function is just what the operating system looks for in a C program to pass its control to. So technically if any parameter that’s needed to be passed on to the main() function must be passed during runtime. Also as the main() function is the part that receives the operating system’s control it is required to be present in the program (some exceptions do occur).

 

Interesting Fact : Despite its importance, main is not a keyword in C.

 

Example -

      Code :

    #include<stdio.h>

    // Defining a main function with int return type

    int main()

    {

        printf("Hello you are in the main function");

        return 0;

     }

      Output : 

     Hello you are in the main function

 

Lastly main() function is an important component of almost every C program and writing a good main() function is a very crucial and important step.

 

Thanks for reading. 

As always your valuable comments and suggestions are welcome.

Also See : Function, Call by Value and Reference, Recursion

 

Saturday, June 13, 2020

Gentle Introduction to C : Function

Originally Posted on SeedBx


Welcome to the second part of the Gentle Introduction to C series. As said before this series aims to provide you a brief introduction to C language.

In this part we will look into the one of the basic components of C, namely functions and how using it can improve your programming experience.

Function

Function is a block of statements that performs a specific functionality. Mainly its aim is to divide a complex routine in hand to simpler subroutines which can then be later combined to perform the more complex routine.

There are basically two types of function :

  1. Standard-library functions
  2. User-defined functions

We will delve more into these types at a later part, but for now you can intuitively understand them as predefined and as the name suggests user-defined functions respectively.

Interesting Fact : C is the only programming language to have not lost its popularity even after such a long duration.


Given below are some basic components related to functions.

Common Terminologies

Function Name : It is the name/identity of the function which is used to call the function.

Parameters/Arguments : It is the list of data items (variables, pointers, references etc.) that the function take as input in its block of statements to either do computation on it or to facilitate the computation. The number of parameters can be any finite integer (possibly zero). The process of passing the parameters can be done in two ways : by value or by reference.

 Function Declaration : It is an introductory statement which is used to inform the compiler of the number of the parameters and the type of each individual parameter associated with the given function name. It also specifies about the type ( int, char, float, double, void)  of the return value of the function.

Function Definition : It is a sequence of statements that define the functionality of the function along with all details such as the names of parameter variables. It starts with a statement like a function declaration (except that it is now also compulsory to provide with parameter's name)  and followed by curly braces which contain the function in itself.

Return Value : The return value is a data item (possibly void) that the functions returns to the caller. The value is returned using the return keyword

Example : Let us consider a function add which will return the sum of the two parameters.

    int add(int,int);   ---------------------> Function Declaration

    /* some code */

    int add(int num1,int num2)  -------------> Function Definition

    {

        int sum;

        sum = num1 + num2;

        return sum;

    }

Note :

1.     The use of function declaration can be skipped if the function definition comes before the statement(s) in which it is called. However it is a good practice to include function declaration (and is a must when the calling statement(s) precedes the function definition).

2.     The return statement is optional in case of void return type.

3.     The parameters should be separated by commas.

4.      It is not necessary to provide with parameter name in the function declaration.

So you may be wondering why will you ever use a function in the first place. However there are following advantages which you shouldn't overlook :

1.     It improves readability and makes the code look cleaner.

2.     This saves you from writing a block of code multiple times

Although for now you might be wondering these advantages are not at all significant but as you will start designing bigger and complex code these advantages of functions will save you a lot of time while debugging. Also as C is a relatively low level programming language in comparison to C++ or python, functions becomes a powerful tool to do low level stuff like memory management etc.

 

There is still more to be said about functions but I will keep them for different parts.

 

Side Note : 

People also often classify functions on the basis of arguments and return type.

1.     Functions with no arguments and no return type.

2.     Functions with arguments and no return type.

3.     Functions with no arguments and return type.

4.     Functions with arguments and a return type.

 

Do write in comments what other advantages you see of using functions.

Your suggestions as always are welcome.