C Programming Language

Basics .  Variable Declaration, Definition and Scope .  Data Types .  Storage Classes .  Input/Output .  Operators .  Preprocessor .  Array & Strings .  Control Statements .  Functions .  Pointers .  Enum, Struct and Union .  Memory Management .  File Handling .  Puzzles .  Misc . 

C is a procedural programming language. 
It was initially developed by Dennis Ritchie 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.
Basics: 
  1. C Language Introduction
  2. C Programming Language Standard
  3. int (1 sign bit + 31 data bits) keyword in C
  4. Is it fine to write “void main()” or “main()” in C/C++?
  5. Difference between “int main()” and “int main(void)” in C/C++?
  6. Macros and Preprocessors in C
  7. Compiling a C program:- Behind the Scenes
  8. Benefits of C over other languages
  9. Program error signals
  10. Escape sequences in C
  11. Line Slicing in C
  12. C/ C++ Tokens
Variable Declaration, Definition and Scope:
  1. Variables and Keywords in C
  2. How are variables scoped in C – Static or Dynamic?
  3. Scope rules in C
  4. How Linkers Resolve Multiply Defined Global Symbols?
  5. Quiz on Variable Declaration and Scope
  6. Complicated declarations in C
  7. Redeclaration of global variable in C
  8. Internal and External Linkage
  9. Declare variable as constant
  10. Why variables doesn’t start with numbers
  11. Redeclaration of global variables
  12. Initialization of global and static variables
Data Types:
  1. Data Types in C
  2. Use of bool in C
  3. Integer Promotions in C
  4. Quiz on Data Types in C
  5. Comparison of a float with a value in C
  6. Need of long data type in C
  7. size_t data type in C
  8. Interesting facts about data-types and modifiers
  9. Float and Double in C
  10. Character arithmetic in C
  11. Typecasting in C
Storage Classes:
  1. Storage Classes in C
  2. Static Variables in C
  3. Understanding “extern” keyword in C
  4. What are the default values of static variables in C?
  5. Understanding “volatile” qualifier in C
  6. Const Qualifier in C
  7. Initialization of static variables in C
  8. Understanding “register” keyword in C
  9. Quiz on Storage Classes in C
  10. Understanding volatile qualifier in C- Set 1
Input/Output:
  1. Returned values of printf() and scanf()
  2. What is return type of getchar(), fgetc() and getc() ?
  3. Scansets in C
  4. puts() vs printf() for printing a string
  5. What is use of %n in printf() ?
  6. How to print % using printf()?
  7. Quiz on Input Output in C
  8. Difference between printf, sprintf and fprintf?
  9. Difference between getc(), getchar(), getch() and getche()
  10. Difference between %d and %i format specifier
  11. Use of fflush(stdin) in C
  12. Clearing input buffer in C/C++
  13. scanf() and fscanf() in C
  14. getchar_unlocked() in C
  15. Problem with scanf()
  16. Differentiate printable and control character
  17. rand() and srand() in C/C++
Operators:
  1. Introduction to operators in C and Arithmetic Operators
  2. Relational and Logical Operators in C
  3. Bitwise Operators in C
  4. Operator Precedence and Associativity in C
  5. Evaluation order of operands
  6. Comma in C and C++
  7. sizeof operator in C
  8. Operands for sizeof operator
  9. A comma operator question
  10. Result of comma operator as l-value in C and C++
  11. Order of operands for logical operators
  12. Increment (Decrement) operators require L-value Expression
  13. Precedence of postfix ++ and prefix ++ in C/C++
  14. Modulus on Negative Numbers
  15. C/C++ Ternary Operator – Some Interesting Observations
  16. Pre-increment (or pre-decrement) in C++
  17. Difference between ++*p, *p++ and *++p
  18. Results of comparison operations in C and C++
  19. To find sum of two numbers without using any operator
  20. Sequence Points in C
  21. Execution of printf with ++ operators
  22. Anything written in sizeof() is never executed
  23. Difference between strlen() and sizeof()
  24. Stringizing and Token-pasting operator
Preprocessor:
  1. Write a C macro PRINT(x) which prints x
  2. Variable length arguments for Macros
  3. Multiline macros in C
  4. CRASH() macro – interpretation
  5. The OFFSETOF() macro,
  6. Branch prediction macros in GCC
  7. Diffference between #define and const in C?
  8. A C Programming Language Puzzle
  9. What’s difference between header files “stdio.h” and “stdlib.h” ?
  10. How to print a variable name in C?
  11. Constants in C
  12. How a Preprocessor works
  13. Preprocessor Directives : Behind the scene-1
  14. Preprocessor Directives : Behind the scene-2
  15. isgraph() library function
  16. write your own header file in C
  17. difftime() library function
  18. tmpnam() library function
  19. _Generic keyword in C
  20. math.h library functions
  21. typedef versus #define in C
  22. strftime() library function
  23. exec family of functions
Arrays & Strings:
  1. Introduction to Arrays in C Language
  2. Strings in C Language
  3. Properties of array in C Language
  4. Do not use sizeof for array parameters
  5. Initialization of variables sized arrays in C
  6. Are array members deeply copied?
  7. What is the difference between single quoted and double quoted declaration of char array?
  8. Initialization of a multidimensional arrays in C/C++
  9. Write one line functions for strcat() and strcmp()
  10. What’s difference between char s[] and char *s in C
  11. gets() is risky to use!
  12. C function to Swap strings,
  13. Storage for Strings in C
  14. Difference between array and pointer
  15. How to dynamically allocate a 2D array in C?
  16. How to pass a 2D array as a parameter in C?
  17. How to write long strings in Multi-lines C/C++?
  18. What are the data types for which it is not possible to create an array?
  19. Variable Length Arrays in C and C++
  20. Short hand array notation
  21. Accessing array out of bounds
  22. strcpy() in C/C++
  23. strcmp() in C/C++
  24. strdup() and strdndup() in C/C++
  25. Pass an array by value
  26. Reverse a string in C/C++
  27. strpbrk() in C
  28. strcoll() in C/C++
  29. ispunct() in C
  30. strspn() in C
  31. isalpha() and isdigit() in C/C++
Control Statements:
  1. What should be data type of case labels of switch statement in C?
  2. For Versus While
  3. A nested loop puzzle
  4. switch statement in C
  5. Difference between while(1) and while(0)
  6. goto statement
  7. Continue Statement
  8. Break Statement
  9. Using range in switch case
Functions:
  1. Functions in C
  2. Importance of function prototype in C
  3. Functions that are executed before and after main() in C
  4. return statement vs exit() in main()
  5. How to Count Variable Numbers of Arguments in C?,
  6. What is evaluation order of function parameters in C?
  7. Does C support function overloading?
  8. How can we return multiple values from a function?
  9. What is the purpose of a function prototype?
  10. Static functions in C
  11. exit(), abort() and assert()
  12. Implicit return type int in C
  13. What happens when a function is called before its declaration in C?
  14. _Noreturn function specifier in C
  15. exit() vs _Exit()
  16. __func__ identifier in C
  17. Callback function in C
  18. Nested functions in C
  19. Parameter Passing Techniques
  20. pow() function in C
  21. tolower() function in C
  22. time() function in C
Pointers:
  1. Introduction to pointers in C and C++
  2. Double Pointer (Pointer to Pointer) in C
  3. Why C treats array parameters as pointers?
  4. Output of the program | Dereference, Reference, Dereference, Reference
  5. Dangling, Void , Null and Wild Pointers
  6. An Uncommon representation of array elements
  7. How to declare a pointer to a function?
  8. Pointer vs Array in C
  9. void pointer in C
  10. NULL pointer in C !
  11. Function Pointer in C
  12. near, far and huge pointers
  13. Generic Linked List in C
  14. restrict keyword in C
  15. const char *p, char * const p and const char * const p
  16. Pointer to an Array
Enum, Struct and Union:
  1. Enum in C
  2. Structures in C
  3. Union in C
  4. Struct Hack
  5. Structure Member Alignment, Padding and Data Packing
  6. Operations on struct variables in C
  7. Bit Fields in C
  8. Structure Sorting (By Multiple Rules) in C++
  9. Flexible array members in structure
  10. Difference between Structure and Union
  11. Difference between C structures and C++ structures
  12. Anonymous Union and Structure in C
  13. Compound Literals in C
Memory Management:
  1. Memory Layout of C Programs,
  2. How to deallocate memory without using free() in C?
  3. calloc() versus malloc()
  4. How does free() know the size of memory to be deallocated?
  5. Use of realloc()
  6. What is Memory Leak? How can we avoid?
File Handling:
  1. fseek() vs rewind() in C
  2. EOF, getc() and feof() in C
  3. fopen() for an existing file in write mode
  4. Read/Write structure to a file
  5. fgets() and gets() in C
  6. Basics of File Handling
  7. fsetpos() in C
  8. rename function in C/C++
  9. tmpfile() function in C
  10. fgetc() and fputc() in C
  11. fseek() in C/C++
  12. ftell() in C
  13. lseek() in C/C++
  14. remove function in C/C++
  15. Merge contents of two files into a third file
  16. Print contents of file in C
Puzzles:
  1. C Program to print numbers from 1 to N without using semicolon?
  2. How to find sum of two numbers without using any operator
  3. How will you show memory representation of C variables?
  4. Condition To Print “HelloWord”
  5. Change/add only one character and print ‘*’ exactly 20 times
  6. How can we sum the digits of a given number in single statement?

  7. What is the best way in C to convert a number to a string?
  8. Calculate Logn in one line
  9. Print “Even” or “Odd” without using Conditional statement
  10. How will you print numbers from 1 to 100 without using loop?
  11. How can we sum the digits of a given number in single statement?
  12. How will you print “Geeks for Geeks” without using a semicolon
  13. Write a one line C function to round floating point numbers
  14. How will implement Your Own sizeof
  15. How to count set bits in a floating point number in C?
  16. How to change the output of printf() in main() ?
  17. How to find length of a string without string.h and loop in C?
  18. Implement your own itoa()
  19. Write a C program that does not terminate when Ctrl+C is pressed
  20. How to measure time taken by a function in C?
  21. Print a long int in C using putchar() only
  22. Convert a floating point number to string in C
  23. How to write a running C code without main()?
  24. Write your own memcpy()
  25. C program to print characters without using format specifiers
  26. C program to print a string without any quote (singe or double) in the program
  27. Execute both if and else statements simultaneously
  28. Print “Hello World” without using any header file
Misc:
  1. Quine – A self-reproducing program
  2. Complicated declarations in C
  3. Use of bool in C
  4. Sequence Points in C | Set 1
  5. Optimization Techniques | Set 2 (swapping),
  6. ASCII NUL, ASCII 0 (’0?) and Numeric literal 0
  7. Little and Big Endian Mystery,
  8. Comparator function of qsort() in C
  9. Program to validate an IP address
  10. Multithreading in C
  11. Assertions in C/C++
  12. fork() in C
  13. Interesting Facts in C Programming
  14. Precision of floating point numbers in C++ (floor(), ceil(), trunc(), round() and setprecision())
  15. setjump() and longjump() in C
  16. nextafter() and nexttoward() in C/C++
  17. pthread_cancel() in C
  18. pthread_equal() in C
  19. pthread_self() in C
  20. Local Labels in C
  21. lvalue and rvalue in C
  22. Get and set the stack size of thread attribute
  23. Difference between fork() and exec()
  24. Errors in C/C++
  25. Why is C considered faster than other languages
  26. Incompatibilities between C and C++
  27. Convert C/C++ code to assembly language
  28. Error Handling in C
  29. Executing main() in C/C++ : Behind the scene
  30. Hygienic Macros in C
  31. Command line arguments in C/C++
  32. scanf(), fscanf(), sscanf(), scanf_s(), fscanf_s(), sscanf_s()
  33. Some Interesting Facts in C Programming
  34. Database Connectivity using C/C++
  35. Function Interposition in C
  36. Macros vs Functions
  37. Write your own memcpy() and memmove()









C Language Introduction

C is a procedural programming language. It was initially developed by Dennis Ritchie in the year 1972. It was mainly developed as a system programming language to write an operating system. The main features of C language include low-level access to memory, a simple set of keywords, and clean style, these features make C language suitable for system programmings like an 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 are 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: The components of the above structure are:
    1. Header Files Inclusion: The first and foremost component is the inclusion of the Header files in a C program.
      A header file is a file with extension .h which contains C function declarations and macro definitions to be shared between several source files. Some of C Header files:
      • stddef.h – Defines several useful types and macros.
      • stdint.h – Defines exact width integer types.
      • stdio.h – Defines core input and output functions
      • stdlib.h – Defines numeric conversion functions, pseudo-random network generator, memory allocation
      • string.h – Defines string handling functions
      • math.h – Defines common mathematical functions
      Syntax to include a header file in C:
      #include 
      
    2. Main Method Declaration: The next part of a C program is to declare the main() function. The syntax to declare the main function is: Syntax to Declare main method:
      int main()
      {}
      
    3. Variable Declaration: The next part of any C program is the variable declaration. It refers to the variables that are to be used in the function. Please note that in the C program, no variable can be used without being declared. Also in a C program, the variables are to be declared before any operation in the function. Example:
      int main()
      {
          int a;
      .
      .
      
    4. Body: Body of a function in C program, refers to the operations that are performed in the functions. It can be anything like manipulations, searching, sorting, printing, etc. Example:
      int main()
      {
          int a;
          printf("%d", a);
      .
      .
      
    5. Return Statement: The last part in any C program is the return statement. The return statement refers to the returning of the values from a function. This return statement and return value depend upon the return type of the function. For example, if the return type is void, then there will be no return statement. In any other case, there will be a return statement and the return value will be of the type of the specified return type. Example:
      int main()
      {
          int a;
          printf("%d", a);
          return 0;
      }
      
  2. Writing first program:
    Following is first program in C #include <stdio.h> int main(void) {     printf("GeeksQuiz");     return 0; } Let us analyze the program line by line.
    Line 1: [ #include <stdio.h> ] In a C program, all lines that start with # are processed by preprocessor which is a program invoked by the compiler. In a very basic term, preprocessor takes a C program and produces another C program. The produced program has no lines starting with #, all such lines are processed by the preprocessor. In the above example, preprocessor copies the preprocessed code of stdio.h to our file. The .h files are called header files in C. These header files generally contain declaration of functions. We need stdio.h for the function printf() used in the program. Line 2 [ int main(void) ] There must to be starting point from where execution of compiled C program begins. In C, the execution typically begins with first line of main(). The void written in brackets indicates that the main doesn’t take any parameter (See this for more details). main() can be written to take parameters also. We will be covering that in future posts.
    The int written before main indicates return type of main(). The value returned by main indicates status of program termination. See this post for more details on return type. Line 3 and 6: [ { and } ] In C language, a pair of curly brackets define a scope and mainly used in functions and control statements like if, else, loops. All functions must start and end with curly brackets. Line 4 [ printf(“GeeksQuiz”); ] printf() is a standard library function to print something on standard output. The semicolon at the end of printf indicates line termination. In C, semicolon is always used to indicate end of statement. Line 5 [ return 0; ] The return statement returns the value from main(). The returned value may be used by operating system to know termination status of your program. The value 0 typically means successful termination.
  3. How to excecute the above program:
    Inorder to execute the above program, we need to have a compiler to compile and run our programs. There are certain online compilers like https://ide.geeksforgeeks.org/, http://ideone.com/ or http://codepad.org/ that can be used to start C without installing a compiler.
    Windows: There are many compilers available freely for compilation of C programs like Code Blocks  and Dev-CPP.   We strongly recommend Code Blocks. Linux: For Linux, gcc comes bundled with the linux,  Code Blocks can also be used with Linux.

C Programming Language Standard

The idea of this article is to introduce C standard. What to do when a C program produces different results in two different compilers?
For example, consider the following simple C program. void main() {  } The above program fails in gcc as the return type of main is void, but it compiles in Turbo C. How do we decide whether it is a legitimate C program or not? Consider the following program as another example. It produces different results in different compilers. #include<stdio.h> int main() {     int i = 1;     printf("%d %d %d\n", i++, i++, i);     return 0; }
2 1 3 - using g++ 4.2.1 on Linux.i686
1 2 3 - using SunStudio C++ 5.9 on Linux.i686
2 1 3 - using g++ 4.2.1 on SunOS.x86pc
1 2 3 - using SunStudio C++ 5.9 on SunOS.x86pc
1 2 3 - using g++ 4.2.1 on SunOS.sun4u
1 2 3 - using SunStudio C++ 5.9 on SunOS.sun4u
Source: Stackoverflow Which compiler is right? The answer to all such questions is C standard. In all such cases we need to see what C standard says about such programs. What is C standard?
The latest C standard is ISO/IEC 9899:2011, also known as C11 as the final draft was published in 2011. Before C11, there was C99. The C11 final draft is available here. See this for complete history of C standards. Can we know behavior of all programs from C standard?
C standard leaves some behavior of many C constructs as undefined and some as unspecified to simplify the specification and allow some flexibility in implementation. For example, in C the use of any automatic variable before it has been initialized yields undefined behavior and order of evaluations of subexpressions is unspecified. This specifically frees the compiler to do whatever is easiest or most efficient, should such a program be submitted. So what is the conclusion about above two examples?
Let us consider the first example which is “void main() {}”, the standard says following about prototype of main().
The function called at program startup is named main. 
The implementation 
declares no prototype for this function. 
It shall be defined with a return 
type of int and with no parameters:
       int main(void) { /* ...*/ }
or with two parameters (referred to here as argc and argv, though any names 
may be used, as they are local to the function in which they are declared):
       int main(int argc, char *argv[]) { /* ...*/ }
or equivalent;10) or in some other implementation-defined manner.
So the return type void doesn’t follow the standard and it’s something allowed by certain compilers. Let us talk about second example. Note the following statement in C standard is listed under unspecified behavior.
The order in which the function designator, arguments, and 
subexpressions within the arguments are evaluated in a function 
call (6.5.2.2). 
What to do with programs whose behavior is undefined or unspecified in standard?
As a programmer, it is never a good idea to use programming constructs whose behaviour is undefined or unspecified, such programs should always be discouraged. The output of such programs may change with compiler and/or machine.

int (1 sign bit + 31 data bits) keyword in C

In C programming language a most common keyword ‘int’ is used to define any positive or negative integer. But there is a difference between an integer and the numbers which can be represented with the help of the keyword ‘int’. Not every integer can be represented with the keyword ‘int’. According to MinGW the size of one ‘int’ is 4 bytes which is equal to 32 bits (1 byte=8 bits). It is still a myth somewhere that ‘int’ can represent an integer or ‘int’ is used to represent integers. Integer is a very vast category of numbers where as one ‘int’ has limited and exact amount of memory (size of ‘int’ is 4 bytes or 32 bits) to store what is being represented by it. An ‘int’ type variable in C language is able to store only numbers till 2147483647. Beyond this number ‘int’ fails to store precisely and even not correctly. ‘int’ is a 32 bit data type. Whenever a number is being assigned to an ‘int’ type variable, it is first converted to its binary representation (that is in 0’s and 1’s) then it is kept in memory at specific location. An ‘int’ is actually 1 sign bit + 31 data bits, that is 31 bits are available for storing the number being assigned to a ‘int’ type variable and 1 bit is reserved for maintaining the sign of the number which is either + or – . The sign is also represented by binary digits, 0 for positive sign and 1 for negative sign. Let us understand this by an example.
Example – Consider,
int num=2147483647; 
At this point first 2147483647 will be converted into its binary form which is equal to:
1111111111111111111111111111111. 1111111111111111111111111111111 is a 31 digit binary number which will be assigned to variable num’s right most 31 bits and the 32nd bit will have a zero(0) as the number being assigned to variable num is a positive number. If we try to store any number greater than 2147483647 into an ‘int’ type variable then we will lose information.

Is it fine to write “void main()” or “main()” in C/C++?

The definition void main() { /* ...*/ } 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 and C++ programmers.
In C++, main() need not contain an explicit return statement. In that case, the value returned is 0, meaning successful execution.
For example: #include <iostream> int main() {     std::cout << "This program returns the integer value 0\n"; } 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. Source: http://www.stroustrup.com/bs_faq2.html#void-main 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.

Difference between “int main()” and “int main(void)” in C/C++?

Consider the following two definitions of main(). int main() {    /*  */    return 0; } and int main(void) {    /*  */    return 0; } What is the difference? In C++, there is no difference, both are same. Both definitions work in C also, but the second definition with void is considered technically better as it clearly specifies that main can only be called without any parameter.
In C, if a function signature doesn’t specify any argument, it means that the function can be called with any number of parameters or without any parameters. For example, try to compile and run following two C programs (remember to save your files as .c). Note the difference between two signatures of fun(). // Program 1 (Compiles and runs fine in C, but not in C++) void fun() {  }  int main(void) {     fun(10, "GfG", "GQ");     return 0; } The above program compiles and runs fine (See this), but the following program fails in compilation (see this) // Program 2 (Fails in compilation in both C and C++) void fun(void) {  } int main(void) {     fun(10, "GfG", "GQ");     return 0; } Unlike C, in C++, both of the above programs fails in compilation. In C++, both fun() and fun(void) are same. So the difference is, in C, int main() can be called with any number of arguments, but int main(void) can only be called without any argument. Although it doesn’t make any difference most of the times, using “int main(void)” is a recommended practice in C. Exercise:
Predict the output of following C programs. Question 1 #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);     } }

Interesting Facts about Macros and Preprocessors in C

In a C program, all lines that start with # are processed by preprocessor which is a special program invoked by the compiler. In a very basic term, preprocessor takes a C program and produces another C program without any #. Following are some interesting facts about preprocessors in C.
1) When we use include directive,  the contents of included header file (after preprocessing) are copied to the current file.
Angular brackets < and > instruct the preprocessor to look in the standard folder where all header files are held.  Double quotes and instruct the preprocessor to look into the current folder (current directory).
2) When we use define for a constant, the preprocessor produces a C program where the defined constant is searched and matching tokens are replaced with the given expression. For example in the following program max is defined as 100. #include<stdio.h> #define max 100 int main() {     printf("max is %d", max);     return 0; } Output:
max is 100
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 = "GeeksQuiz";     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 Output:
16
The previous problem can be solved using following program #include <stdio.h> //here, instead of writing a*a we write (a)*(b) #define MULTIPLY(a, b) (a)*(b) int main() {     // The macro is expended as (2 + 3) * (3 + 5), as 5*8     printf("%d", MULTIPLY(2+3, 3+5));     return 0; } //This code is contributed by Santanu Output:
40
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() {     // GeeksQuiz is changed to "GeeksQuiz"     printf("%s", get(GeeksQuiz)); } Output:
GeeksQuiz
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("GeeksQuiz "); \                             i++; \                         } int main() {     int i = 0;     PRINT(i, 3);     return 0; } Output:
GeeksQuiz GeeksQuiz GeeksQuiz
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. #include <stdio.h>    #define square(x) x*x int main() {     // Expanded as 36/6*6     int x = 36/square(6);      printf("%d", x);     return 0; } Output:
36
If we use inline functions, we get the expected output. Also, the program given in point 4 above can be corrected using inline functions. #include <stdio.h>    static inline int square(int x) { return x*x; } int main() { int x = 36/square(6); printf("%d", x); return 0; } Output:
1
9) Preprocessors also support if-else directives which are typically used for conditional compilation. int main() { #if VERBOSE >= 2   printf("Trace Message"); #endif } Output:
No Output
10) A header file may be included more than one time directly or indirectly, this leads to problems of redeclaration 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 :/usr/share/IDE_PROGRAMS/C/other/081c548d50135ed88cfa0296159b05ca/081c548d50135ed88cfa0296159b05ca.c
Current Date :Sep  4 2019
Current Time :10:17:43
Line Number :9
12) We can remove already defined macros using :
#undef MACRO_NAME #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 declared 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; } Output:
1000
1001
Another interesting fact about macro using (#undef) #include <stdio.h> //div function prototype float div(float, float); #define div(x, y) x/y    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; }    //div function definition float div(float x, float y){ return y/x; } //This code is contributed by Santanu Output:
2.00
0.50
You may like to take a Quiz on Macros and Preprocessors in C

Compiling a C program:- Behind the Scenes

C is a high-level language and it needs a compiler to convert it into an executable code so that the program can be run on our machine.

How do we compile and run a C program?

Below are the steps we use on an Ubuntu machine with gcc compiler.

What goes inside the compilation process?

Compiler converts a C program into an executable. There are four phases for a C program to become an executable:
  1. Pre-processing
  2. Compilation
  3. Assembly
  4. Linking
By executing below command, We get the all intermediate files in the current directory along with the executable.
 $gcc –Wall –save-temps filename.c –o filename 
The following screenshot shows all generated intermediate files.
compil4 Let us one by one see what these intermediate files contain.

Pre-processing

This is the first phase through which source code is passed. This phase include: The preprocessed output is stored in the filename.i. Let’s see what’s inside filename.i: using $vi filename.i
compil5
compile6
In the above output, source file is filled with lots and lots of info, but at the end our code is preserved.
Analysis:

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 image 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 contain 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 compil7

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.
compil8
Note that GCC by default does dynamic linking, so printf() is dynamically linked in above program. Refer this, this and this for more details on static and dynamic linkings.

Benefits of C language over other programming languages

C is a middle-level programming language developed by Dennis Ritchie during the early 1970s while working at AT&T Bell Labs in the USA. The objective of its development was in the context of the re-design of the UNIX operating system to enable it to be used on multiple computers. Earlier the language B was now used for improving the UNIX system. Being a high-level language, B allowed much faster production of code than in assembly language. Still, B suffered from drawbacks as it did not understand data-types and did not provide the use of “structures”. These drawbacks became the driving force for Ritchie for development of a new programming language called C. He kept most of language B’s syntax and added data-types and many other required changes. Eventually, C was developed during 1971-73, containing both high-level functionality and the detailed features required to program an operating system. Hence, many of the UNIX components including UNIX kernel itself were eventually rewritten in C.

Benefits of C language

  1. As a middle-level language, C combines the features of both high-level and low-level languages. It can be used for low-level programming, such as scripting for drivers and kernels and it also supports functions of high-level programming languages, such as scripting for software applications etc.
  2. C is a structured programming language which allows a complex program to be broken into simpler programs called functions. It also allows free movement of data across these functions.
  3. Various features of C including direct access to machine level hardware APIs, the presence of C compilers, deterministic resource use and dynamic memory allocation make C language an optimum choice for scripting applications and drivers of embedded systems.
  4. C language is case-sensitive which means lowercase and uppercase letters are treated differently.
  5. C is highly portable and is used for scripting system applications which form a major part of Windows, UNIX, and Linux operating system.
  6. C is a general-purpose programming language and can efficiently work on enterprise applications, games, graphics, and applications requiring calculations, etc.
  7. C language has a rich library which provides a number of built-in functions. It also offers dynamic memory allocation.
  8. C implements algorithms and data structures swiftly, facilitating faster computations in programs. This has enabled the use of C in applications requiring higher degrees of calculations like MATLAB and Mathematica.
  9. 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, Seed7, Vala, Verilog and many more other languages are there.

    Program error signals

    Signals in computers are a way of communication between the process and the OS. When a running program undergoes some serious error then the OS sends a signal to the process and the process further may not execute. Some processes may have a signal handler which does some important tasks before the process leaves the CPU. Signal and interrupt are basically same but a small distinction exists i.e interrupts are generated by the processor and handled by the kernel but signals are generated by the kernel and handled by the process. Error signals generally causes termination of the program and a core dump file is created named core, which stores the state of the process at the moment of termination. This file can be investigated using debugger to know the cause of program termination. Error signals: Refer for – Segmentation Fault (SIGSEGV) vs Bus Error (SIGBUS)

    Line Splicing in C/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/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
      1. Keyword: Keywords are pre-defined or reserved words in a programming language. Each keyword is meant to perform a specific function in a program. Since keywords are referred names for a compiler, they can’t be used as variable names because by doing so, we are trying to assign a new meaning to the keyword which is not allowed. You cannot redefine keywords. However, you can specify text to be substituted for keywords before compilation by using C/C++ preprocessor directives.C language supports 32 keywords which are given below:
        
        auto         double      int        struct
        break        else        long       switch
        case         enum        register   typedef
        char         extern      return     union
        const        float       short      unsigned
        continue     for         signed     void
        default      goto        sizeof     volatile
        do           if          static     while
         
        While in C++ there are 31 additional keywords other than C Keywords they are:
        
        asm          bool        catch          class
        const_cast   delete      dynamic_cast   explicit 
        export       false       friend         inline 
        mutable      namespace   new            operator 
        private      protected   public         reinterpret_cast
        static_cast  template    this           throw
        true         try         typeid         typename 
        using        virtual     wchar_t 
        
      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:
        1. main: method name.
        2. a: variable name.
      3. Constants: Constants are also like normal variables. But, only difference is, their values can not 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:
        1. Integer constants – Example: 0, 1, 1218, 12482
        2. Real or Floating point constants – Example: 0.0, 1203.03, 30486.184
        3. Octal & Hexadecimal constants – Example: octal: (013 )8 = (11)10, Hexadecimal: (013)16 = (19)10
        4. Character constants -Example: ‘a’, ‘A’, ‘z’
        5. String constants -Example: “GeeksforGeeks”
      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] = {‘g’, ’e’, ‘e’, ‘k’, ‘s’, ‘f’, ‘o’, ‘r’, ‘g’, ’e’, ‘e’, ‘k’, ‘s’, ‘\0’};
        • char string[20] = “geeksforgeeks”;
        • char string [] = “geeksforgeeks”;
        Difference between above declarations are:
        1. when we declare char as “string[20]”, 20 bytes of memory space is allocated for holding the string value.
        2. When we declare char as “string[]”, memory space will be allocated as per the requirement during execution of the program.
      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 triggers 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 requires three operands to act upon. For Example Conditional operator(?:). For more information about operators click

    Variables and Keywords in C

    A variable in simple terms is a storage place which has some memory allocated to it. Basically, a variable used to store some form of data. Different types of variables require different amounts of memory, and have some specific set of operations which can be applied on them. Variable Declaration:
    A typical variable declaration is of the form:
      type variable_name;
        or for multiple variables:
      type variable1_name, variable2_name, variable3_name;
    A variable name can consist of alphabets (both upper and lower case), numbers and the underscore ‘_’ character. However, the name must not start with a number. Difference b/w variable declaration and definition
    Variable declaration refers to the part where a variable is first declared or introduced before its first use. Variable definition is the part where the variable is assigned a memory location and a value. Most of the times, variable declaration and definition are done together. See the following C program for better clarification: #include <stdio.h> int main() {     // declaration and definition of variable 'a123'     char a123 = 'a'        // This is also both declaration and definition as 'b' is allocated     // memory and assigned some garbage value.        float b;          // multiple declarations and definitions     int _c, _d45, e;         // Let us print a variable     printf("%c \n", a123);        return 0; } Output:
    a
    Is it possible to have separate declaration and definition?
    It is possible in case of extern variables and functions. See question 1 of this for more details.  
     
    Keywords are specific reserved words in C each of which has a specific feature associated with it. Almost all of the words which help us use the functionality of the C language are included in the list of keywords. So you can imagine that the list of keywords is not going to be a small one! There are a total of 32 keywords in C:
       auto       break    case     char     const     continue
       default    do       double   else     enum      extern
       float      for      goto     if       int       long
       register   return   short    signed   sizeof    static
       struct     switch   typedef  union    unsigned  void
       volatile   while 
    Most of these keywords have already been discussed in the various sub-sections of the C language, like Data Types, Storage Classes, Control Statements, Functions etc. Let us discuss some of the other keywords which allow us to use the basic functionality of C: const: const can be used to declare constant variables. Constant variables are variables which, when initialized, can’t change their value. Or in other words, the value assigned to them cannot be modified further down in the program.
    Syntax:
    const data_type var_name = var_value; 
    Note: Constant variables must be initialized during their declaration. const keyword is also used with pointers. Please refer the const qualifier in C for understanding the same. extern: extern simply tells us that the variable is defined elsewhere and not within the same block where it is used. Basically, the value is assigned to it in a different block and this can be overwritten/changed in a different block as well. So an extern variable is nothing but a global variable initialized with a legal value where it is declared in order to be used elsewhere. It can be accessed within any function/block. Also, a normal global variable can me made extern as well by placing the ‘extern’ keyword before its declaration/definition in any function/block. This basically signifies that we are not initializing a new variable but instead we are using/accessing the global variable only. The main purpose of using extern variables is that they can be accessed between two different files which are part of a large program.
    Syntax:
    extern data_type var_name = var_value;
    static: static keyword is used to declare static variables, which are popularly used while writing programs in C language. Static variables have a property of preserving their value even after they are out of their scope! Hence, static variables preserve the value of their last use in their scope. So we can say that they are initialized only once and exist till the termination of the program. Thus, no new memory is allocated because they are not re-declared. Their scope is local to the function to which they were defined. Global static variables can be accessed anywhere within that file as their scope is local to the file. By default, they are assigned the value 0 by the compiler.
    Syntax:
    static data_type var_name = var_value;
    void: void is a special data type. But what makes it so special? void, as it literally means, is an empty data type. It means it has nothing or it holds no value. For example, when it is used as the return data type for a function it simply represents that the function returns no value. Similarly, when its added to a function heading, it represents that the function takes no arguments.
    Note: void also has a significant use with pointers. Please refer to the void pointer in C for understanding the same. typedef: typedef is used to give a new name to an already existing or even a custom data type (like a structure). It comes in very handy at times, for example in a case when the name of the structure defined by you is very long or you just need a short-hand notation of a per-existing data type. Let’s implement the keywords which we have discussed above. Take a look at the following code which is a working example to demonstrate these keywords: #include <stdio.h>    // declaring and initializing an extern variable extern int x = 9;     // declaring and initializing a global variable // simply int z; would have initialized z with // the default value of a global variable which is 0 int z=10;    // using typedef to give a short name to long long int  // very convenient to use now due to the short name typedef long long int LL;     // function which prints square of a no. and which has void as its // return data type void calSquare(int arg)  {     printf("The square of %d is %d\n",arg,arg*arg); }    // Here void means function main takes no parameters int main(void {     // declaring a constant variable, its value cannot be modified     const int a = 32;         // declaring a  char variable     char b = 'G';        // telling the compiler that the variable z is an extern variable      // and has been defined elsewhere (above the main function)     extern int z;        LL c = 1000000;        printf("Hello World!\n");        // printing the above variables     printf("This is the value of the constant variable 'a': %d\n",a);     printf("'b' is a char variable. Its value is %c\n",b);     printf("'c' is a long long int variable. Its value is %lld\n",c);     printf("These are the values of the extern variables 'x' and 'z'"     " respectively: %d and %d\n",x,z);        // value of extern variable x modified     x=2;         // value of extern variable z modified     z=5;         // printing the modified values of extern variables 'x' and 'z'     printf("These are the modified values of the extern variables"     " 'x' and 'z' respectively: %d and %d\n",x,z);        // using a static variable     printf("The value of static variable 'y' is NOT initialized to 5 after the "             "first iteration! See for yourself :)\n");        while (x > 0)     {         static int y = 5;         y++;         // printing value at each iteration         printf("The value of y is %d\n",y);         x--;     }        // print square of 5     calSquare(5);         printf("Bye! See you soon. :)\n");        return 0; } Output:
    Hello World
    This is the value of the constant variable 'a': 32
    'b' is a char variable. 
    Its value is G
    'c' is a long long int variable. 
    Its value is 1000000
    These are the values of the extern variables 'x' and 'z' respectively: 9 and 10
    These are the modified values of the extern variables 'x' and 'z' respectively: 2 and 5
    The value of static variable 'y' is NOT initialized to 5 after the first iteration! See for yourself :)
    The value of y is 6
    The value of y is 7
    The square of 5 is 25
    Bye! See you soon. 
    :)

    How are variables scoped in C – Static or Dynamic?

    In C, variables are always statically (or lexically) scoped i.e., binding of a variable can be determined by program text and is independent of the run-time function call stack. For example, output for the below program is 0, i.e., the value returned by f() is not dependent on who is calling it. f() always returns the value of global variable x. # include <stdio.h>    int x = 0; int f() {    return x; } int g() {    int x = 1;    return f(); } int main() {   printf("%d", g());   printf("\n");   getchar(); }

    Scope rules in C

    Scope of an identifier is the part of the program where the identifier may directly be accessible. In C, all identifiers are lexically(or statically) scoped. C scope rules can be covered under the following two categories. There are basically 4 scope rules:
    Scope Meaning
    File Scope Scope of a Identifier starts at the beginning of the file and ends at the end of the file. It refers to only those Identifiers that are declared outside of all functions. The Identifiers of File scope are visible all over the file Identifiers having file scope are global
    Block Scope Scope of a Identifier begins at opening of the block / ‘{‘ and ends at the end of the block / ‘}’. Identifiers with block scope are local to their block
    Function Prototype Scope Identifiers declared in function prototype are visible within the prototype
    Function scope Function scope begins at the opening of the function and ends with the closing of it. Function scope is applicable to labels only. A label declared is used as a target to goto statement and both goto and label statement must be in same function
    Let’s discuss each scope rules with examples.
    1. File Scope: These variables are usually declared outside of all of the functions and blocks, at the top of the program and can be accessed from any portion of the program. These are also called the global scope variables as they can be globally accessed.
      Example 1: #include<stdio.h>    int main() {   {       int x = 10, y  = 20;       {           // The outer block contains declaration of x and y, so            // following statement is valid and prints 10 and 20           printf("x = %d, y = %d\n", x, y);           {               // y is declared again, so outer block y is not accessible                // in this block               int y = 40;       // Changes the outer block variable x to 11               x++;       // Changes this block's variable y to 41               y++;                        printf("x = %d, y = %d\n", x, y);           }              // This statement accesses only outer block's variables           printf("x = %d, y = %d\n", x, y);       }   }   return 0; } Output:
      Before change within main: 5
      After change within main: 10
      Example 2: // C program to illustrate  // function prototype scope    #include <stdio.h>     // function prototype scope //(not part of a function definition) int Sub(int num1, int num2);    // file scope int num1;    // Funntion to subtract int Sub(int num1, int num2) {     return (num1-num2); }    // Driver method int main(void) {     printf("%d\n", Sub(10,5));     return 0; } void func1() {    {           // label in scope even         // though declared later        goto label_exec;    label_exec:;    }       // label ignores block scope    goto label_exec;  }     void funct2() {        // throwserror:      // as label is in f() not g()     goto label_exec;  } Note: To restrict access to the current file only, global variables can be marked as static.
    2. Block Scope: A Block is a set of statements enclosed within left and right braces i.e. ‘{‘ and ‘}’ respectively. Blocks may be nested in C(a block may contain other blocks inside it). A variable declared inside a block is accessible in the block and all inner blocks of that block, but not accessible outside the block. Basically these are local to the blocks in which the variables are defined and are not accessible outside. int main() {   {       int x = 10;   }   {       // Error: x is not accessible here       printf("%d", x);     }   return 0; } Output:
      x = 10, y = 20
      x = 11, y = 41
      x = 11, y = 20
      
    3. Function Prototype Scope: These variables range includes within the function parameter list. The scope of the these variables begins right after the declaration in the function prototype and runs to the end of the declarations list. These scope doesnot include the function definition, but just the function prototype.
      Example: // C program to illustrate scope of variables    #include<stdio.h>    int main() {     // Initialization of local variables     int x = 1, y = 2, z = 3;        printf("x = %d, y = %d, z = %d\n",     x, y, z);     {            // changing the variables x & y         int x = 10;         float y = 20;                    printf("x = %d, y = %f, z = %d\n",         x, y, z);         {                // changing z             int z = 100;             printf("x = %d, y = %f, z = %d\n",             x, y, z);         }     }     return 0; } Output:
      5
    4. Function Scope: A Function scope begins at the opening of the function and ends with the closing of it. Function scope is applicable to labels only. A label declared is used as a target to go to the statement and both goto and label statement must be in the same function.
      Example:
    Now various questions may arise with respect to the scope of access of variables:
    What if the inner block itself has one variable with the same name?
    If an inner block declares a variable with the same name as the variable declared by the outer block, then the visibility of the outer block variable ends at the pint of the declaration by inner block. What about functions and parameters passed to functions?
    A function itself is a block. Parameters and other local variables of a function follow the same block scope rules. Can variables of the block be accessed in another subsequent block?
    No, a variable declared in a block can only be accessed inside the block and all inner blocks of this block. For example: the following program produces a compiler error. int main() {   {       int x = 10;   }   {       // Error: x is not accessible here       printf("%d", x);     }   return 0; } Error:
    prog.c: In function 'main':
    prog.c:8:15: error: 'x' undeclared (first use in this function)
      printf("%d", x); // Error: x is not accessible here
                   ^
    prog.c:8:15: note: each undeclared identifier is 
    reported only once for each function it appears in
    
    Example: // C program to illustrate scope of variables    #include<stdio.h>    int main() {     // Initialization of local variables     int x = 1, y = 2, z = 3;        printf("x = %d, y = %d, z = %d\n",     x, y, z);     {            // changing the variables x & y         int x = 10;         float y = 20;                    printf("x = %d, y = %f, z = %d\n",         x, y, z);         {                // changing z             int z = 100;             printf("x = %d, y = %f, z = %d\n",             x, y, z);         }     }     return 0; } Output:
     
    x = 1, y = 2, z = 3
    x = 10, y = 20.000000, z = 3 
    x = 10, y = 20.000000, z = 100 
    

    How Linkers Resolve Global Symbols Defined at Multiple Places?

    At compile time, the compiler exports each global symbol to the assembler as either strong or weak, and the assembler encodes this information implicitly in the symbol table of the relocatable object file. Functions and initialized global variables get strong symbols. Uninitialized global variables get weak symbols.
    For the following example programs, buf, bufp0, main, and swap are strong symbols; bufp1 is a weak symbol. /* main.c */  void swap();  int buf[2] = {1, 2};  int main()  {    swap();    return 0;  }      /* swap.c */  extern int buf[];      int *bufp0 = &buf[0];  int *bufp1;      void swap()  {    int temp;        bufp1 = &buf[1];    temp = *bufp0;    *bufp0 = *bufp1;    *bufp1 = temp; } Given this notion of strong and weak symbols, Unix linkers use the following rules for dealing with multiple defined symbols:
    Rule 1: Multiple strong symbols (with same variable name) are not allowed.
    Rule 2: Given a strong symbol and multiple weak symbols, choose the strong symbol.
    Rule 3: Given multiple weak symbols, choose any of the weak symbols.
    For example, suppose we attempt to compile and link the following two C modules: /* foo1.c */        int main()           {                      return 0;        }                       /* bar1.c */ int main() {   return 0; } In this case, the linker will generate an error message because the strong symbol main is defined multiple times (rule 1):
    $ gcc foo1.c bar1.c
    /tmp/cca015022.o: In function ‘main’:
    /tmp/cca015022.o(.text+0x0): multiple definition of ‘main’
    /tmp/cca015021.o(.text+0x0): first defined here
    
    Similarly, the linker will generate an error message for the following modules because the strong symbol x is defined twice (rule 1): /* foo2.c */ int x = 15213; int main() {   return 0; }     /* bar2.c */ int x = 15213; void f() { } However, if x is uninitialized in one module, then the linker will quietly choose the strong symbol defined in the other (rule 2) as is the case in following program: /* foo3.c */ #include <stdio.h> void f(void); int x = 15213; int main() {   f();   printf("x = %d\n", x);   return 0; }     /* bar3.c */ int x; void f() {   x = 15212; } At run time, function f() changes the value of x from 15213 to 15212, which might come as a unwelcome surprise to the author of function main! Notice that the linker normally gives no indication that it has detected multiple definitions of x.
    $ gcc -o gfg foo3.c bar3.c
    $ ./gfg
    x = 15212
    
    The same thing can happen if there are two weak definitions of x (rule 3): /*a.c*/ #include <stdio.h> void b(void);    int x; int main() {     x = 2016;     b();     printf("x = %d ",x);     return 0; } /*b.c*/ #include <stdio.h>    int x;    void b() {     x = 2017;        } The application of rules 2 and 3 can introduce some insidious run-time bugs that are incomprehensible to the unwary programmer, especially if the duplicate symbol definitions have different types.
    Example : “x” is defined as an int in one module and a double in another. /*a.c*/ #include <stdio.h> void b(void);     int x = 2016; int y = 2017; int main() {     b();     printf("x = 0x%x y = 0x%x \n", x, y);     return 0; } /*b.c*/ double x;    void b() {     x = -0.0; } Execution:
    $ gcc a.c b.c -o geeksforgeeks
    $ ./geeksforgeeks
    x = 0x0 y = 0x80000000
    
    This is a subtle and nasty bug, especially because it occurs silently, with no warning from the compilation system, and because it typically manifests itself much later in the execution of the program, far away from where the error occurred. In a large system with hundreds of modules, a bug of this kind is extremely hard to fix, especially because many programmers are not aware of how linkers work. When in doubt, invoke the linker with a flag such as the gcc -fno-common flag, which triggers an error if it encounters multiple defined global symbols. Source : http://csapp.cs.cmu.edu/public/ch7-preview.pdf

    C Variable Declaration and Scope

    12