Language Introduction
Language Introduction
C is a procedural programming language. It was initially developed by Dennis Ritchie between 1969 and
1973. It was mainly developed as a system programming language to write operating system. The main features
of C language include low-level access to memory, simple set of keywords, and clean style, these features make
C language suitable for system programming like operating system or compiler development.
Many later languages have borrowed syntax/features directly or indirectly from C language. Like syntax of Java,
PHP, JavaScript and many other languages is mainly based on C language. C++ is nearly a superset of C
language (There are few programs that may compile in C, but not in C++).
Beginning with C programming:
1. Structure of a C program:
After the above discussion, we can formally assess the structure of a C program. By structure, it is meant that
any program can be written in this structure only. Writing a C program in any other structure will hence lead to a
Compilation Error.
The structure of a C program is as follows:
is not and never has been C++, nor has it even been C. See the ISO C++ standard 3.6.1[2] or the ISO C standard
5.1.2.2.1. A conforming implementation accepts
int main() { /* ... */ }
and
int main(int argc, char* argv[]) { /* ... */ }
A conforming implementation may provide more versions of main(), but they must all have return type int. The
int returned by main() is a way for a program to return a value to “the system” that invokes it. On systems that
doesn‟t provide such a facility the return value is ignored, but that doesn‟t make “void main()” legal C++ or
legal C. Even if your compiler accepts “void main()” avoid it, or risk being considered ignorant by C
programmers.
Note also that neither ISO C++ nor C99 allows you to leave the type out of a declaration. That is, in contrast to
C89 and ARM C++ ,”int” is not assumed where a type is missing in a declaration. Consequently:
#include <iostream>
main() { /* ... */ }
is an error because the return type of main() is missing.
To summarize above, it is never a good idea to use “void main()” or just “main()” as it doesn‟t confirm
standards. It may be allowed by some compilers though.
#include <stdio.h>
int main()
{
static int i = 5;
if (--i){
printf("%d ", i);
main(10);
}
}
Question 2
#include <stdio.h>
int main(void)
{
static int i = 5;
if (--i){
printf("%d ", i);
main(10);
}
}
#include<stdio.h>
#define max 100
int main()
{
printf("max is %d", max);
return 0;
}
// Output: max is 100
// Note that the max inside "" is not replaced
3) The macros can take function like arguments; the arguments are not checked for data type. For example, the
following macro INCREMENT(x) can be used for x of any data type.
#include <stdio.h>
#define INCREMENT(x) ++x
int main()
{
char *ptr = "C Programming";
int x = 10;
printf("%s ", INCREMENT(ptr));
printf("%d", INCREMENT(x));
return 0;
}
// Output: eeksQuiz 11
4) The macro arguments are not evaluated before macro expansion. For example consider the following program
#include <stdio.h>
#define MULTIPLY(a, b) a*b
int main()
{
// The macro is expended as 2 + 3 * 3 + 5, not as 5*8
printf("%d", MULTIPLY(2+3, 3+5));
return 0;
}
// Output: 16
5) The tokens passed to macros can be concatenated using operator ## called Token-Pasting operator.
#include <stdio.h>
#define merge(a, b) a##b
int main()
{
printf("%d ", merge(12, 34));
}
// Output: 1234
6) A token passed to macro can be converted to a string literal by using # before it.
#include <stdio.h>
#define get(a) #a
int main()
{
// C Programming is changed to "C Programming"
printf("%s", get(C Programming));
}
// Output: C Programming
7) The macros can be written in multiple lines using „\‟. The last line doesn‟t need to have „\‟.
#include <stdio.h>
#define PRINT(i, limit) while (i < limit) \
{ \
printf("C Programming "); \
i++; \
}
int main()
{
int i = 0;
PRINT(i, 3);
return 0;
}
// Output: C Programming C Programming C Programming
8) The macros with arguments should be avoided as they cause problems sometimes. And Inline functions
should be preferred as there is type checking parameter evaluation in inline functions. From C99 onward, inline
functions are supported by C language also.
For example consider the following program. From first look the output seems to be 1, but it produces 36 as
output.
#define square(x) x*x
int main()
{
int x = 36/square(6); // Expanded as 36/6*6
printf("%d", x);
return 0;
}
// Output: 36
9) Preprocessors also support if-else directives which are typically used for conditional compilation.
int main()
{
#if VERBOSE >= 2
printf("Trace Message");
#endif
}
10) A header file may be included more than one time directly or indirectly, this leads to problems of re-
declaration of same variables/functions. To avoid this problem, directives like defined, ifdef and ifndef are used.
11) There are some standard macros which can be used to print program file (__FILE__), Date of compilation
(__DATE__), Time of compilation (__TIME__) and Line Number in C code (__LINE__)
#include <stdio.h>
int main()
{
printf("Current File :%s\n", __FILE__ );
printf("Current Date :%s\n", __DATE__ );
printf("Current Time :%s\n", __TIME__ );
printf("Line Number :%d\n", __LINE__ );
return 0;
}
/* Output:
Current File :C:\Users\GfG\Downloads\deleteBST.c
Current Date :Feb 15 2014
Current Time :07:04:25
Line Number :8 */
#include <stdio.h>
#define LIMIT 100
int main()
{
printf("%d",LIMIT);
//removing defined macro LIMIT
#undef LIMIT
//Next line causes error as LIMIT is not defined
printf("%d",LIMIT);
return 0;
}
//This code is contributed by Santanu
Following program is executed correctly as we have declare LIMIT as an integer variable after removing
previously defined macro LIMIT
#include <stdio.h>
#define LIMIT 1000
int main()
{
printf("%d",LIMIT);
//removing defined macro LIMIT
#undef LIMIT
//Declare LIMIT as integer again
int LIMIT=1001;
printf("\n%d",LIMIT);
return 0;
}
//This code is contributed by Santanu
/*Output is :
1000
1001
*/
int main()
{
//use of macro div. Note: %0.2f for taking two decimal value after point
printf("%0.2f",div(10.0,5.0));
//removing defined macro div
#undef div
//function div is called as macro definition is removed
printf("\n%0.2f",div(10.0,5.0));
return 0;
}
/*Output is :
2.00
0.50
*/
precompiler
Expanded source
compiler
Assembly source
assembler
Library file
Object file
linker
Executable code
To debug a program with the debugger (gdb) you should compile it with –g option.
$ gcc –g source.c
Some options may be combined to get the effect of all those options.
In the above output, source file is filled with lots and lots of info, but at the end our code is preserved.
Analysis:
printf contains now a + b rather than add(a, b) that‟s because macros have expanded.
Comments are stripped off.
#include<stdio.h> is missing instead we see lots of code. So header files has been expanded and included
in our source file.
Compiling
The next step is to compile filename.i and produce an; intermediate compiled output file filename.s. This file is
in assembly level instructions. Let‟s see through this file using $vi filename.s
The snapshot shows that it is in assembly language, which assembler can understand.
Assembly
In this phase the filename.s is taken as input and turned into filename.o by assembler. This file contains
machine level instructions. At this phase, only existing code is converted into machine language, the function
calls like printf() are not resolved. Let‟s view this file using $vi filename.o
Linking
This is the final phase in which all the linking of function calls with their definitions are done. Linker knows
where all these functions are implemented. Linker does some extra work also, it adds some extra code to our
program which is required when the program starts and ends. For example, there is a code which is required for
setting up the environment like passing command line arguments. This task can be easily verified by using $size
filename.o and $size filename. Through these commands, we know that how output file increases from an
object file to an executable file. This is because of the extra code that linker adds with our program.
Note that GCC by default does dynamic linking, so printf() is dynamically linked in above program.
Riding on these advantages, C became dominant and spread quickly beyond Bell Labs replacing many well-
known languages of that time, such as ALGOL, B , PL/I, FORTRAN etc. C language has become available on a
very wide range of platforms, from embedded microcontrollers to supercomputers.
The C language has formed the basis for many languages including C++, C–, C#, Objective-C, BitC, C-shell,
csh, D, Java, JavaScript, Go, Rust, Julia, Limbo, LPC, PHP, Python, Perl, Verilog, Rust, Seed7, Vala, Verilog
and many more other languages are there.
Escape Sequences in C
In C programming language, there are 256 numbers of characters in character set. The entire character set is
divided into 2 parts i.e. the ASCII characters set and the extended ASCII characters set. But apart from that,
some other characters are also there which are not the part of any characters set, known as ESCAPE characters.
Line Splicing in C
While writing a program, sometimes we give comment about the working of the code in the comment
section with the help of single/double comment line. But we had never thought that if at the end of this
comment line if we use \(backslash) character then what will happen?
The answer of the above question is line Splicing. Lines terminated by a \ are spliced together with the
next line very early in the process of translation. §2.2 Phases of translation.
Actually whenever at the end of the comment line if we use \(backslash) character then it deletes the
backslash character and the preceding next line of code only from the entire program or we can say
that the ending \(backslash) makes the new line also as a comment for the compiler.
// C program to illustrate the concept of Line splicing.
#include <stdio.h>
int main()
{
// Line Splicing\
printf("Hello GFG\n");
printf("welcome");
return (0);
}
Output:
welcome
Explanation: In the above program as we can see when we use the \(backslash) character at the end of
comment line. Then the next line of code is treated as comment in the program and the output is
welcome.
C Tokens
A token is the smallest element of a program that is meaningful to the compiler. Tokens can be
classified as follows:
1. Keywords
2. Identifiers
3. Constants
4. Strings
5. Special Symbols
6. Operators
2. Identifiers: Identifiers are used as the general terminology for naming of variables, functions and
arrays. These are user defined names consisting of arbitrarily long sequence of letters and digits
with either a letter or the underscore(_) as a first character. Identifier names must differ in
spelling and case from any keywords. You cannot use keywords as identifiers; they are reserved
for special use. Once declared, you can use the identifier in later program statements to refer to
the associated value. A special kind of identifier, called a statement label, can be used in goto
statements.
There are certain rules that should be followed while naming c identifiers:
They must begin with a letter or underscore(_).
They must consist of only letters, digits, or underscore. No other special character is
allowed.
It should not be a keyword.
It must not contain white space.
It should be up to 31 characters long as only first 31 characters are significant.
Some examples of c identifiers:
NAME REMARK
_A9 Valid
Temp.var Invalid as it contains special character other than the
underscore
void Invalid as it is a keyword
C program:
void main()
{
int a = 10;
}
In the above program there are 2 identifiers:
main: method name.
a: variable name.
3. Constants: Constants are also like normal variables. But, only difference is, their values cannot
be modified by the program once they are defined. Constants refer to fixed values. They are also
called as literals.
Constants may belong to any of the data type.
Syntax:
const data_type variable_name; (or) const data_type *variable_name;
Types of Constants:
Integer constants – Example: 0, 1, 1218, 12482
Real or Floating point constants – Example: 0.0, 1203.03, 30486.184
Octal & Hexadecimal constants, Example: octal: (013 )8 = (11)10, Hexadecimal: (013)16 = (19)10
Character constants -Example: „a‟, „A‟, „z‟
String constants -Example: “CProgramming”
4. Strings: Strings are nothing but an array of characters ended with a null character („\0‟).This null
character indicates the end of the string. Strings are always enclosed in double quotes. Whereas, a
character is enclosed in single quotes in C and C++.Declarations for String:
char string[20] = {„C‟, ‟P‟, „r‟, „o‟, „g‟, „r‟, „a‟, „m‟, „m‟, ‟i‟, „n‟, „g‟,
„\0‟};
char string[20] = “CProgramming”;
char string [] = “CProgramming”;
5. Special Symbols: The following special symbols are used in C having some special meaning and
thus, cannot be used for some other purpose.[] () {}, ; * = #
Brackets[]: Opening and closing brackets are used as array element reference. These
indicate single and multidimensional subscripts.
Parentheses(): These special symbols are used to indicate function calls and function
parameters.
Braces{}: These opening and ending curly braces marks the start and end of a block of code
containing more than one executable statement.
comma (, ): It is used to separate more than one statements like for separating parameters
in function calls.
semi colon : It is an operator that essentially invokes something called an initialization list.
asterick (*): It is used to create pointer variable.
assignment operator: It is used to assign values.
pre processor(#): The preprocessor is a macro processor that is used automatically by the
compiler to transform your program before actual compilation.
6. Operators: Operators are symbols that trigger an action when applied to C variables and other
objects. The data items on which operators act upon are called operands.
Depending on the number of operands that an operator can act upon, operators can be classified
as follows:
Unary Operators: Those operators that require only single operand to act upon are known
as unary operators. For Example increment and decrement operators
Binary Operators: Those operators that require two operands to act upon are called binary
operators. Binary operators are classified into :
1. Arithmetic operators
2. Relational Operators
3. Logical Operators
4. Assignment Operators
5. Conditional Operators
6. Bitwise Operators
Ternary Operators: These operators require three operands to act upon. For Example
Conditional operator (?:).