List two reasons why it would be preferable to write a program in C rather than in machine language

High-level languages allow programmers to write instructions in a language that is easier to understand than low-level languages. Translators are needed to translate programs written in high-level languages into the machine code that a computer understands.

C is amongst the oldest programming languages out there. Every advanced programming language that you use today has some of its roots in the C programming language. Isn’t that reason enough to get yourself familiarised with the C programming basics?

We give you 7 more reasons C is the best programming language for those planning to learn to code.

C is the preferred language for building a strong programming foundation

Programming has many concepts that you need to be clear about like classes, objects, polymorphism, and inheritance among others. Other advanced languages build upon these concepts. C is the language where you can find the basis for these concepts. Hence, it is the best language for those who are new to programming.

It is simple to understand

C programming language uses blocks to separate pieces of code performing different tasks. This helps make programming easier and keeps the code clean. Thus, the code is easy to understand even for those who are starting out.

It is used in embedded programming

C is used in embedded programming, which is used to control micro-controllers. These micro-controllers are used in robotics, computers, and automation. Learning C can help you here as well.

It forms the basis for C++ and Java

Java and C++ are amongst the most widely used programming languages today. They derive their syntax, and concepts from the C programming language. Being acquainted with the C programming basics will thus make learning C++ and Java easier. 

It is fast  

The programs that you write in C compile and execute much faster than those written in other languages. This is because it does not have garbage collection and other such additional processing overheads. Hence, the language is faster as compared to most other programming languages. This is one of the reasons why C is used even today for programming.  

It is used to build PC games  

C finds use in many PC games. It has been used to code various small games and some tasks in bigger games as well. Thus, learning C can be beneficial if you are aspiring to make a career in game development.

It gives you the best of both worlds

There are three levels of programming languages- Low-level, Mid-level and High-level. Low-level languages process programs faster, while High-Level languages are more user and developer-friendly. The C is a mid-level language that combines the best of both. It is simple to understand, easy to use, and processes programs faster.

Just learning the language is not enough; You must ensure that you learn it from the best. You can learn C programming online or opt for a classroom course from NIIT.

With years of experience in teaching, NIIT has the perfect course for helping you learn the C programming basics. This C programming course with certification meets the industry standards and is taught by experts with significant experience. 

This course with dedicated theory and practical sessions is perfect for beginners who want to learn this language and make a career in the IT industry. Whereas this is a beginner-level certification, NIIT, in accordance with its Edtech subsidiary StackRoute is offering the PGP in Full Stack Software Engineering. Designed for aspiring full-stack developers with a future-ready aptitude, this program will cultivate on-the-job instincts in students within 18 weeks and guarantees placement following the successful completion of the course. 
 

If you were waiting for a sign from above to take control of your professional life, the time is now!
 

C is a general-purpose computer programming language which can be used in wide variety of applications. Operating systems, application software for computers ranging from supercomputers to embedded systems are written in C. While C has been a versatile programming language, it has been the most suitable one when it comes to Embedded Systems. In spite of being invented more than 30 years ago, when it comes to Embedded Systems, there is no other programming language which even comes close to C. Let us try to understand the reasons behind why is C the most preferred language for embedded systems, as a part of this blog post.

Embedded Systems

A computer system with a specific function within a larger system (mechanical or electrical system) is an embedded system. It is also possible that the Embedded Systems has real time computing constraints, thereby making them as Real-Time-Systems (RTS). Today Embedded Systems are everywhere starting from wearable devices to high-speed transportation systems.

Practically we can view Embedded Systems as a customized software running on a customized hardware. Since the hardware is very specific, software also needs to be tuned, which puts additional constraint on developer. Along with that, Embedded Systems are typically resource constrained systems, where usage of every other HW resource (ex: memory) must be done efficiently. C language is a killer when it comes to all these aspects!

Before use of C language

At first, micro-controller based systems, programs were developed using assemblers and fused into EEPROMs. There was no mechanism to find what the program was doing. LED, switches etc., were used to check the correct execution of program. As time proceeded, microprocessor specific and assembly-only as programming language got reduced. Embedded systems moved onto C.

Why C

There are specific reasons for why is C the most preferred language for Embedded Systems. Let us look into top-5 of them as follows.

1.Processor independent

C language is not specific to any microprocessor/micro-controller or any system. It can work on various hardware configuration. C doesn’t require same set of hardware to run a program. C language is platform independent whereas the applications written in C are not. Hence the concept “Write once Compile anywhere” came.

Example

We can compile and execute a C program written for one hardware in another hardware with little to no change. If there is a change required, it is only in terms of platform (Operating System) specific functions and system calls. This is said to be machine independent. While writing a program in C, user doesn’t have to know the underlying hardware specific details of the machine, since the compiler takes care of it. When developers compile a C program for a particular hardware, respective assembly code is generated. It is then linked with libraries (static and dynamic) to give an executable file. It should be noted that only C code is machine independent, the executable file generated is Machine as well as Platform (OS) dependent. So, whenever a code written in C must be used in another machine, it should be compiled and executed again.

2.Portability

Portability of a language is mainly important when an application program must be moved to other operating systems. Code developed in C is more portable and user can compile it on other platforms with least modifications. C code is efficient, easy to understand, maintain and debug. A program can be written in one machine and can be run on other machines.

Example

Let us consider simple example of two integer addition!

The size of integer variable depends on the underlying machine architecture. Popularly called as “Word Size” the size can be different. For example, in a 32-bit machine occupies 2 bytes whereas an integer variable in 64-bit machine takes 4-bytes.

The max value stored in a 4 byte (unsigned integer) can vary between 0 to 4,294,967,295 whereas in case of 2 byte the range reduces to 0 to 65535. In case of sum of two numbers (say A and B) exceeding 65535 it will create integer overflow in a 32-bit machine by giving incorrect output. Sample code snippet is given below.

In order to avoid or deduct the issue early, developer can use “typedef” and create a synonym (ex: 32 for int). This will be helpful when program is ported to another machine and the developer can make appropriate changes in the code, thereby making the program portable and avoid error.

#include<stdio.h> int main() { typedef int u32; // u32 is a synonym for unsigned integer u32 a = 200000, b = 280000, c; // a, b and c are variables of type int c = a + b; printf("\nSum is %d",c); return 0; }

Fig 1: Example for Portability using typedef

Output

List two reasons why it would be preferable to write a program in C rather than in machine language

Fig 2: Sum of variables a and b displayed

3.Performance

C code gets compiled into raw binary executable which can be directly loaded into memory and executed. C provides optimized machine instructions for the given input, which increases the performance of the embedded system. Most of the high-level languages rely on libraries, hence they require more memory which is a major challenge in embedded systems.

For example, In Java, we need JVM (Java Virtual Machine) in addition to the jar files (Executable) which adds additional overhead in terms of performance and memory consumption. Newer languages provide support for garbage collection, dynamic typing etc., which degrades their performance. Since C does none of that, there is little to no overhead.

4.Bit manipulation

C is more flexible, structured language that provides “low level bit wise data manipulation” using the bit-wise operators. Using bit-wise operators, one could play with available bits, which comes handy when it comes to Embedded Systems (Ex: Handling registers).

Let us understand a basic example.

Example 1 – Setting or clearing a bit

To set a bit in a particular number, developers can use bitwise operators. In the below code,

number to be set and bit-position is provided by the user. By generating appropriate mask required results are generated.

Assuming the same case of registers, developer can set or clear a bit in a similar manner thereby getting the ability to program the hardware. Such facilities having in a high-level language like C gives lot of power to developer.

#include<stdio.h> int main() { int number, bit_position, newnumber; printf("enter the number to be set\n"); scanf("%d",&number); printf("enter the bit to be set\n"); scanf("%d",&bit_position); /* set-bit logic, where(1 << bit_position) is the mask */ newnumber = (1 << bit_position) | number; printf("Result after seeing the bit is %d\n",newnumber); return 0; }

Fig 3: Bit-manipulation – example to set bit

Output

The third bit (whereas bit position is 2, representing bit b2) in number 11 has to be set high. 15 is the decimal answer after set bit operation is performed on 11.

List two reasons why it would be preferable to write a program in C rather than in machine language

Fig 4: Output -set bit

Example 2 – Encoding Algorithms

Encoding can be taken as another example for bit manipulation. If an important text or image has to be sent to others, we can encode the data and send it. Encoding will help in securing the data from hackers, since the original message will not be seen even if it is hacked. At the receiving end, decoding should be done by the receiver to obtain the original data. This is a boon to developers. And this is why C is the most preferred language for embedded systems than other languages.

In the below given encoding example, if the data bit is 1, then bitwise OR is performed with integer 1 and encoding is done. If the data bit is 0, then bit-wise AND is performed with (~1) and encoding is done. Hence original data is changed and encoded. Such encoding algorithm implementation is done with use in C language thanks to bit-wise operators.

//Encode function Status encode(char data, FILE *source, FILE *destination) { int idx; char ch; for( idx = 0; idx < 8; idx ++) // loop to encode all 8 bits of a data byte { ch = fgetc(source); // gets a byte from source which is to be encoded,in ch if (data & (1 << idx)) // checks for bit value 1 { ch = ch | 1; } else // condition for bit 0 { ch = ch &(~1); } fputc(ch,destination); // stores encoded bit in destination } return 0; }

Fig 5: Encoding function – example code

5.Memory management

It provides direct memory control without sacrificing benefits of high-level languages. We can directly access memory using pointers and perform various operations using them. When memory requirement is not known, we can allocate it dynamically and when memory requirement is known, we can allocate the memory statically. This is one of the main reasons for why is C the most preferred language for embedded systems.

Example 1 – Simple dynamic memory allocation

When amount of memory required is unknown, dynamic memory allocation is used, which also helps in optimized memory usage. In the below code, memory to pointer ptr is dynamically allocated during run time and malloc() returns a void pointer which can be type casted into pointer.

After allocating and performing appropriate operations (ex: addition in this case) the memory is freed up using the free() function.

#include<stdio.h> #include<stdlib.h> int main() { int number, idx, *ptr, sum_of_elements = 0; printf("Enter number of elements: "); scanf("%d",&number); ptr = (int*) malloc(number * sizeof(int)); printf("Enter elements of array: "); for(idx = 0; idx < number; ++ idx) { scanf("%d", ptr + idx); sum_of_elements += *(ptr+idx); // adds array elements } printf("sum_of_elements = %d", sum_of_elements); free(ptr); return 0; }

Fig 6: Array and dynamic memory allocation

Output

List two reasons why it would be preferable to write a program in C rather than in machine language

Fig 7: Output for memory management in array

Example 2 – User defined memory management

The pointer facility in C allows user to manage the memory in his own way. For example (in the code given below) we are allocating 100 bytes of memory and storing it into void pointer, as returned by the malloc() function.

Now these 100 bytes can be used the way the developer wants it. For example let us consider a requirement where the user wants to store a length and string contents continuously in memory like (len1,string1) | (len2,string2) | (len3,string3) …. (lenN,stringN) and print them.

Since the malloc() returns a void pointer, the user can do typecasting and assign them to character or integer pointers to access appropriate values. Pointer typecasting combined with pointer arithmetic features of C makes such things possible, which will be very difficult in other programming languages.

In case of Embedded systems, developers constantly need to manage and manipulate memory (ex: A frame of memory returned by the device driver from the hardware) where such powerful aspects of C comes handy for the developer.

#include<stdio.h> #include<stdlib.h> #include<string.h> #define MAX_LEN 100 int main() { void *ptr; char str[MAX_LEN]; int option, len = 0, idx, string_count = 0, *iptr; char *sptr; /* allocate 100 Bytes of memory dynamically */ ptr = malloc(100); /* type cast the target memory as integer pointer*/ iptr = (int*)ptr; printf("please enter your strings one by one\n"); option = 1; while (option == 1 ) { printf("Enter your string\n"); scanf("%s",str); /* store the length of the string in the beginning */ len = strlen(str); string_count ++; *iptr = len; /* Increment integer pointer by 4 Bytes */ iptr ++; /* Type cast the address as character pointer and copy the string */ sptr = (char *)iptr; strcpy(sptr,str); /* Increment the string pointer so that next integer can be stored */ sptr = sptr + strlen(str) + 1; /* Typecast it back to integer to store length */ iptr = (int *)sptr; printf("\n Do you have more strings to enter? enter 1 for yes, else 0\n"); scanf("%d",&option); } iptr = (int*)ptr; /* Print the contents of memory- length and string */ for(i = 1; i <= string_count; i ++) { len = *iptr; printf("Length of string[%d] is %d\n",i,len); iptr++; printf("The string is \"%s\"\n",(char*)iptr); iptr = (int *)((char *)iptr + len + 1); } return 0; }

Fig 8: Memory management (string and integer getting stored in same heap)

Output


List two reasons why it would be preferable to write a program in C rather than in machine language

Fig 9: Output- (string and integer)

Conclusion

Embedded Systems development has different set of challenges for developer as it is a resource constraint system. Also programming Embedded Systems involves dealing with actual hardware by controlling them via software.

Even though many languages existed previously and many are still evolving, C has emerged as the number of language when it comes to Embedded Systems programming. This article covered some of the feature of C that helps Embedded Systems developer to program it better. There are still many similar features that needs to be explored, will share them in future blog posts.

Happy learning and happy reading!