Users Online

· Guests Online: 2

· Members Online: 0

· Total Members: 185
· Newest Member: meenachowdary055

Forum Threads

Newest Threads
No Threads created
Hottest Threads
No Threads created

Latest Articles

FAQ: C Concepts & Statements

FAQ (Frequently Asked Questions) >C Concepts & Statements
01 What are Escape Sequences (Character Escapes) in C Language02 What are the Differences Between ANSI C and K&R C03 What is the Difference Between Declaration and Definition of a Variable in C04 Explain Different Phases of Compilation of a C Program with Examples
05 What is the Difference Between Macro and Const Declaration in C Language06 Explain Run-time Stack in C Programming with Examples07 Explain Conditional Statements in C Language with Examples08 What is the Output When if statement in C has Empty Statement “;” as Conditional Expression
09 What is Dangling “else” Statement in C Language10 Explain While, For and Do-While Loop Statements in C with Examples11 What are the Differences Between while and for Loop in C?12 How to Choose Between do-while and while Loops in C Programming
13 Describe goto Statement and its Pros and Cons in C Programming14 Explain Storage Classes in C Language with Examples15 Does a Function have any Storage Class in C Language16 Explain Linkage and Scope of Variables and Functions in C with Examples
01 What are Escape Sequences (Character Escapes) in C Language
This C Tutorial explains Escape Sequences/Character Escapes and why they are needed.

One or more characters following ‘\’ (the backslash) is considered to be a single character and is called the escape sequence. For example:

\? used to write multiple question marks from being interpreted as trigraphs in printf() statements
\” used to get the quotation marks inside the string literals
\’ used to write a character literal for a character
\\ used to write a backslash from being interpreted as a character escape
\a \b etc.

Escape sequences are used in a program to override the special meaning of characters in particular contexts! For example:

printf("What is your name? Are you \"some Xyz\"?");
/*
* OUTPUT: What is your name? Are you "some XYZ"?
* Note the Name in output enclosed in Quotation Marks
*/


Trigraphs

Trigraphs are all three-lettered characters, all begin with ?? (double question marks) followed by a character, represent some other character. Basically, they are used to complement a Character Set lacking for some characters. For example:

??( represent [
??) represent ]

Top
02 What are the Differences Between ANSI C and K&R C
This C Tutorial explain the differences between ANSI C and K&R C and Why ANSI C.
The ANSI C Standard has tightened the definition of many of the vague areas of K&R C. This results in a much clearer definition of a correct C program. In the following sections, we present a list of what we consider to be the major language differences between ANSI C and K&R C.

Lexical Elements

1. In ANSI C, the ordering of phases of translation is well defined. Of special note is the preprocessor which is conceptually token-based (which does not yield the same results as might naively be expected from pure text manipulation, because the boundaries between juxtaposed tokens are visible).

2. A number of new keywords have been introduced into ANSI C: The type qualifier volatile means that the qualified object may be modified in ways unknown to the implementation, or that access to it may have other unknown side effects. Examples of objects correctly described as volatile include device registers, semaphores and data shared with asynchronous signal handlers. In general, expressions involving volatile objects cannot be optimized by the compiler.

3. The type qualifier const indicates that an object’s value will not be changed by the executing program (and in some contexts permits a language system to enforce this by allocating the object in read-only store).

4. The type specifier void indicates a non-existent value for an expression.

5. The type specifier void * describes a generic pointer to or from which any pointer value can be assigned, without loss of information.

6. The signed type specifier may be used wherever unsigned is valid (e.g. to specify signed char explicitly).

7. There is a new floating-point type: long double.

8. The K&R C practice of using long float to denote double is outlawed in ANSI C.

9. The following lexical changes have also been made: Each struct and union has its own distinct name space for member names. Suffixes U and L (or u and l), can be used to explicitly denote unsigned and long constants (e.g. 32L, 64U, 1024UL etc.). The U suffix is new to ANSI C.

10. Literal strings are considered read-only, and identical strings may be stored as one shared value. For example, given:

char *p1 = "hello";
char *p2 = "hello";
p1 and p2 will point at the same store location, where the string “hello” is held. Programs must not, therefore, modify literal strings, (beware of Unix’s tmpnam() and similar functions, which do this).

11. Variable functions (those which take a variable number of actual arguments) are declared explicitly using an ellipsis (…). For example:

int printf(const char *fmt, ...);

12. Empty comments /**/ are replaced by a single space, (use the preprocessor directive ## to do token-pasting if you previously used /**/ to do this).

Arithmetic

1. ANSI C uses value-preserving rules for arithmetic conversions (whereas K&R C implementations tend to use unsigned-preserving rules). Thus, for example:

int f(int x, unsigned char y)
{
return (x+y)/2;
}
does signed division, where unsigned-preserving implementations would do unsigned division. Aside from value-preserving rules, arithmetic conversions follow those of K&R C, with additional rules for long double and unsigned long int. It is now also allowable to perform float arithmetic without widening to double.

2. Floating-point values truncate towards zero when they are converted to integral types. It is illegal to assign function pointers to data pointers and vice versa. An explicit cast must be used. The only exception to this is for the value 0, as in:

int (*pfi)();
pfi = 0;
3. Assignment compatibility between structs and unions is now stricter. For example, consider the following:

struct {char a; int b;} v1;
union {char a; int b;} v2;
v1 = v2; /* illegal because v1 and v2 have different types */

Expressions

1. Structs and unions may be passed by value as arguments to functions. Given a pointer to a function declared as e.g. int (*pfi)(), the function to which it points can be called either by pfi(); or (*pfi)().

2. Because of the use of distinct name spaces for struct and union members, absolute machine addresses must be explicitly cast before being used as struct or union pointers. For example:

((struct io_space *)0x00ff)->io_buf;

Declarations

1. Perhaps the greatest impact on C of the ANSI Standard has been the adoption of function prototypes. A function prototype declares the return type and argument types of a function. For example:

int f(int, float);
declares a function returning int with one int and one float argument. This means that a function’s argument types are part of the type of the function, giving the advantage of stricter type-checking, especially between separately-compiled source files.

2. A function definition (which is also a prototype) is similar except that identifiers must be given for the arguments. For example:

int f(int i, float f)
3. It is still possible to use old-style function declarations and definitions, but it is advisable to convert to the new style. It is also possible to mix old and new styles of function declaration. If the function declaration which is in scope is an old style one, normal integral promotions are performed for integral arguments, and floats are converted to double. If the function declaration which is in scope is a new-style one, arguments are converted as in normal assignment statements.

4. Empty declarations are now illegal.
5. Arrays cannot be defined to have zero or negative size.

Statements

1. A value returned from main() is guaranteed to be used as the program’s exit code. Values used in the controlling statement and labels of a switch can be of any integral type.

Preprocessor

1. Preprocessor directives cannot be redefined. There is a new ## directive for token-pasting.

2. There is a stringize directive # which produces a string literal from its following characters. This is useful when you want to embed a macro argument in a string.

3. The order of phases of translation is well defined and is as follows for the preprocessing phases:

3.1. Map source file characters to the source character set (this includes replacing trigraphs).
3.2. Delete all newline characters which are immediately preceded by .
3.3. Divide the source file into preprocessing tokens and sequences of white space characters (comments are replaced by a single space).
3.4. Execute preprocessing directives and expand macros.

NOTE: Any #include files are passed through steps 1-4 recursively.

4. The macro __STDC__ is predefined to 1 by ANSI-conforming compilers.

Why ANSI C?

ANSI C is a Systems Programming Language but now becoming popular as General Purpose Computing Language as well! Supported across various platforms because of availability of C Compilers for them! Therefore, Programs written in ANSI C are PORTABLE across various platforms! Portability of a Program is the ability of the same to be able to run without or with least modifications on the other platforms!


Top
03 What is the Difference Between Declaration and Definition of a Variable in C
Answer: Declaration specifies the properties of a variable. For example:

int x; /* x is an integer */
int roll_no[]; /* roll_no is an array of integers */


Definition declares a variable and causes the storage to be allocated. For example:

int x = 10; /* x is declared as an integer and allocated space and initialized to 10 */
int roll_no[100]; /* roll_no is declared as an array of integers, allocated space for 100 integers */
Top
04 Explain Different Phases of Compilation of a C Program with Examples
This C Tutorial explains different phases of Compilation of a C Program with examples.
Compilers

1. Compilers translate source files containing high level language statements like our C language program to object files containing machine instructions.
2. As syntax of each high level language differs from one another,a separate compiler is needed for each high level language.
3. The output of a compiler i.e. object file with machine instructions corresponds to a particular microprocessor.This implies that object file generated for ARM processor will not work for Intel Processor or some other one as instruction format differs from processor to processor.

Compilation process is conversion of C source file to object file. Normally this translation takes place in four stages.

1. Pre-processing
2. Compilation
3. Optimization
4. Assembling

Preprocessing

Pre-processor is responsible for including all the include files into a C file, removing the comments, expanding all the macros and expanding inline functions. It also takes care of conditional compilation and as a include guard.

Example of header file inclusion is like

#include <stdio.h>
Example of removing the comments

/* This function is used to find area of the triangle */
Example of expanding macros

#define NoOfRows 4
Example of inline function

inline int max(int a, int b) { return a > b ? a : b ; }

Example of Conditional compilation

# if 0
some code
#endif


Example of include guard

#ifndef FILE_NAME
#define FILE_NAME
#endif

Compilation

The output of preprocessor is given to the compiler. Compiler will generate pseudo assembly language code which does not correspond to any microprocessor.

Optimization

The output of the compiler i.e. pseudo assembly language code is given to optimization process, which will optimize the code based on the registers of the microprocessor, and finally generates assembly language instructions for a particular microprocessor.

Assembling

The output of the optimization process i.e. assembly language code is given to the assembler and it converts to a object file which contains machine op-codes (Operation Codes) for the equivalent assembly instructions.
Top
05 What is the Difference Between Macro and Const Declaration in C Language
This C Tutorial explains the difference between Macro and Const Declaration. Lets start with: what is/are the difference/s between the following two statements and which of these two is efficient and meaningful?
#define SIZE 50
int const size = 50;

Answer:

MACROS

1. The statement “#define SIZE 50” is a preprocessor directive with SIZE defined as a MACRO. The advantage of declaring a MACRO in a program is to replace the MACRO name with the Value given to the MACRO in the #define statement wherever MACRO occurs in the program.

2. No memory is allocated to the MACROS. Program is faster in Execution because of no trade-offs due to allocation of memory!

3. Their Primary use in the program is where constant values viz. characters, integers, floating point is to be used. For example: as an array subscripts

#define MAX 50 /* Declaring a MACRO MAX */

/*
* MAX is a MACRO which is replaced with value 50 wherever
* occurs in the program
*/

int roll_no[MAX];
4. A MACRO Statement does not terminate with a semicolon ” ; ”

CONSTANTS

1. The statement “int const size = 50;” declares and defines size to be a constant integer with the value 50. The const keyword causes the identifier size to be allocated in the read-only memory. This means that the value of the identifier can not be changed by the executing program.

MACROS are efficient than the const statements as they are not given any memory, being more Readable and Faster in execution!
Top
06 Explain Run-time Stack in C Programming with Examples
This C Tutorial explains run time stack in C with examples.
Lets dig deeper into details in order to unfurl the essentials of “Run-Time Stack” rather simply defining what Stack is and where is it used? Well! If we try to recollect ours’ memory during studying in college, we will find the concept of Stack we have had learnt about is somewhat similar to “every time a function is called, a Stack is created and used for temporary storage of variables local to function, arguments passed to function, return address etc. And when function exits, stack associated with it gets dismantled.” Of course, this is true! Yet, it’s incomplete!

Let’s begin with ‘a.out’, a default object file for any C Program we compile on Linux or Unix System! This file can be in ELF (Executable and Linking Format), COFF (Common-Object File Format) or simply as ‘a.out’ format. Albeit these file formats are different but they have one thing in common ‘concept of Segment’! A segment is an area within binary file ‘a.out’ which contains information of a particular type, for example, entries in a ‘Symbol Table’. Every segment can have various sections. Sections are the smallest units of organisation in an ELF file. Every segment contains related stuff in binary!

Let’s write a simple “hello world” program, compile it and run ‘size’ command on executable ‘a.out’ to see which different segments take up what amounts of space.

#include <stdio.h>

int main(void)
{
printf("Hello World!n");
return 0;
}
Output is put below:

[sanfoundry]# gcc helloworld.c
[sanfoundry]# size a.out
text data bss dec hex filename
1144 492 16 1652 674 a.out
As is clear, text segment takes 1144 bytes, data segment takes 492 bytes bss segment takes 16 bytes! Interestingly, you can make experiment with above program by further including initialized or uninitialized global or static or local data and compile program and run ‘size’ command on it to ensure which types of statements end up in which segments! For example,

#include <stdio.h>

/* Global and Static Initialized Data */
char fruit_tree[100] = {1};
static int shots = 100;

int main(void)
{
printf("Hello Worldn");
return 0;
}
Output is given below:

[sanfoundry]# gcc helloworld.c
[sanfoundry]# size a.out
text data bss dec hex filename
1143 624 16 1783 6f7 a.out
Notice that text segment didn’t change while data segment changed corresponding to adding up of two global and static initialized instructions. Similarly, you can perform several more interesting tests to sure you about which statements in your C Program go into which different segments in executable!

Below given is a figure showing instructions in a C program corresponding to which particular segments in ‘a.out’ file:
































Notice here that local variables declared in a function don’t go into ‘a.out’ file. Instead, they are created at run-time when program is executed. Also, observe here that uninitialized global and static data correspond to BSS segment. BSS is an abbreviation from ‘Block Started by Symbol’. Unlike the data segment, BSS segment doesn’t hold the image of uninitialized data instead it only records amount of desired space required at run-time. Text segment contains the executable instructions in your C program.

So, guys, until now we have seen how instructions in a C program after having been compiled correspond to which different segments in the executable. As we know when a program is run it executes in it’s own address space allocated to it. This means that executable file has to be put into program’s address space for execution. But how does this happen? Who does this? Here, at this point, linker and loader come into picture! Indeed, they do this! Let’s see, how?

Segments in ‘a.out’ file conveniently map into objects that the run-time linker can load directly! Loader just takes each segment image in the file and puts it directly into memory. The segments essentially become the memory areas of an executing program, each with a dedicated purpose.

Below is a figure showing how Different Segments in ‘a.out’ file are Laid out in Memory.



































The text segment contains the program instructions. The loader copies that directly from the file into memory typically with ‘mmap()’ system call and never worries about it again because program text typically never changes in value nor size.

Data segment contains initialized global and static variables, complete with their assigned values. The size of the BSS segment is then obtained from the executable, and the loader obtains block of this size, putting it right after the data segment. This block is zeroed out immediately as soon as it’s put in the program’s address space. The entire stretch of data and BSS segment is usually referred to jointly as the data segment at this point. This is because a segment, in the OS memory management terms, is simply a range of consecutive virtual addresses, so adjacent segments are coalesced. The data segment is typically the largest segment in any process!

Now, it’s turn to consider storage for local variables, parameters passing in function calls, return addresses, temporaries etc. Therefore, we still need some memory space which is allocated as Stack segment! We may also need Heap space for dynamic memory allocation. This is set up as soon as first call to ‘malloc()’ is made.

Notice in the fig-2 that lowest part of the address space isn’t mapped i.e. it’s within the range of the processes’ address space but has not been assigned to any physical address, so any reference to it will be illegal! This is typically a few K bytes of memory from address zero up. It catches references through null pointers, pointers which have small integer values etc.







































By this time, program is in memory and executing. Now, here let’s see how C organizes the data structures of a running program. There are several run-time data structures: Stack, Activation Records, Heap and so on. We’ll consider ‘Stack Segment’ here…

The Stack Segment:

The stack segment contains a single data structure, the stack. We are already familiar with the classic concept of how stack is implemented, if we recall, it’s implemented as LIFO, last-in-first-out queue. There are two different operations performed on the stack, viz. PUSH pushes an element onto top of stack while other POP removes an item from the top of stack. PUSH operation makes the stack grow larger.

advertisements

A function can access variables local to its calling function via parameters or global pointers. The run-time maintains a pointer, often in a register and usually called as SP (Stack Pointer) that indicates the current top of the stack. The stack segment has three major uses, two concerned with functions and the last one deals with expression evaluation.

1. The stack provides storage for local variables declared inside the function. These variables are called ‘automatic variables’ in C Programming.

2. The stack stores the “housekeeping” information involved when a function call is made. This housekeeping information is known as stack frame or, more generally, a procedure activation record. This includes the address from which the function was called (i.e. where to jump back to when the called function is finished execution), any parameters that won’t fit into registers, any saved values of registers.

3. The stack also works as scratch-pad area… every time the program needs some temporary storage, perhaps to evaluate a lengthy arithmetic expression, it can push partial results onto the stack, popping them when needed.

Remember that a stack would not be needed except for “Recursive Calls”. If not for these, a fixed amount of storage for local variables, parameters, return addresses etc. would be known at the compile time and could be allocated in the BSS segment. What do we mean by requiring the stack for Recursive Calls? Allowing recursive calls means we must find some way to allow multiple instances of local variables to be in existence at one time, though only the most recently created will be accessed.

On most processors, stack grows downwards towards memory addresses with lower values. A function calls to itself recursively is a special case of a function calls another function; this function calls another function and so on. Let’s see what happens when a function gets called that is how does C run-time manages the program within its own address space.

This is done via a service which is automatically provided and keeps track of call chain… which routines have called which others, and where control will pass back to, on the next “return” statement. The classic mechanism that takes care of this is called “procedure activation record” on the stack. There’s always a procedure activation record or something like this for each call statement executed. The procedure activation record is a data structure that supports an invocation of a procedure, and also records everything needed to get back to where you came from before the call.

Fig-4 Procedure Activation Record

On x86 architecture, the frame is somewhat smaller. The runtime maintains a pointer, often in a register called FP (Frame Pointer) indicates the active stack frame. This will be the stack frame nearest to or at the top of stack.

Of course, your concept of “run-time stack”, now, as I think, must not be vague any more! So, wouldn’t you like to trace the execution of “flow control” of a special case of function calling another function…, I mean, “recursive function” as a practice! For example:

int call_me(int);

int main(void)
{
int i = 10;

printf("%dn", call_me(i));
return 0;
}

/* call_me() defined here */
int call_me()
{
if (x == 1)
return x;
else
return call_me(x - 1);
}
Top
07 Explain Conditional Statements in C Language with Examples
This C Tutorial explains various conditional statements in C Language with example usage.
Answer: Conditional statements in C programming language are

1. if statement
2. if-else statement
3. ternary statement or ternary operator
4. nested if-else statement
5. switch statement

Usage

Conditional statements cause variable flow of execution of the same program, each time the program is run, based on certain condition to be true or false! For example:

if Statement: Syntax

1. if condition is true, then single statement or multiple statements inside the curly braces executes, otherwise skipped and control is transferred to statement following the if clause

2. conditional expression can be exploited to be any expression, function call, literal constant, string functions, MACROs which results in some numerical value

3. numerical values other than zero is considered true while zero is false


/* single statement following the if clause */

if (condition)
statement;
statement;

/* block of statements following the if clause */

if (condition) {
statement;
----
statement;
}
statement;
if-else Statement: Syntax


/*
* if condition is evaluated true, statement following if executes,
* otherwise else clause executes.
*/

if (condition)
statement;
else
statement;

/* control is passed here after if-else construct executed */

statements;
Ternary Statement

Ternary statement or Ternary operator is like if-else statement in its functioning. However, its syntax differs from if-else’s syntax. For example:


z = a > b ? a : b;

/*
* 1. This is interpreted as: if a > b, then a is assigned
* to z else b is assigned to z
* 2. operator ">" greater than, is a Relational Operator.
* Other Relational Operators that can be used are
* <, >=, <=, ==, !=
*/
Try out the following Examples & Observe their Outputs


#include <stdio.h>
int main(void)
{
if (33444.5556656) /* floating point constant */
printf("Inside if: floating point constant val but 0.0 is"
" treated as TRUE i.e NON-ZERO VALUE in if condition!!\n");
return 0;
}

#include <stdio.h>
int main(void)
{
float x = 00.556678;
int y;

/* floating point val x is explicitly promoted to integer */

if (y = (int)x)
printf("Inside if: floating point val but 0.0 is treated"
" as TRUE i.e NON-ZERO VALUE in if condition!!\n");

printf("the values: x is %f and y is %d\n", x,y);
return 0;
}

#include <stdio.h>
int main(void)
{
if (;)
printf("Inside if: how does the semicolon or any other character"
" but digits as a condition in if statement treated? or"
" cause COMPILATION ERROR!\n");
return 0;
}

#include <stdio.h>

/* function definition: function defined here */

int hello(void)
{
return 0;
}

/*
* function prototype: return-type fun_name(arguments number & their type);
*/

void call_fun(void);

int
main(void)
{
if (hello())
printf("function call as a condition in if statement returns"
" non-zero value!\n");
else
printf("hello() returns 0, so else executed!\n");

/*
* 1. Try yourself: Analyse output of the following if-else construct
* 2. Here, I called a function what(), whose return type is void,
* as if condition
*/

if (call_fun())
printf("function call possible as a condition in if statement!\n");
else
printf("call_fun() returns nothing because its return type is"
" void, so else executed!\n");

return 0;
}
void call_fun(void)
{
printf("Inside call_fun() function!\n");
}

#include <stdio.h>
int main()
{
int number;
int *iptr;

/*
* iptr, pointer to integer, follows the location of variable
* number in the memory
*/

iptr = &number;

if (*iptr = 0)
printf("used pointer in the if condition! number is %d\n", *iptr);
else
printf("assigned number value 0 in the if condition using pointer"
" iptr, so else executed!\n");

return 0;
}

#include <stdio.h>
int main()
{
/*
* 1. printf() function prints hello
* 2. printf() function returns no of characters printed successfully
* as integer, here 5
* 3. Conditional Expression in if evaluated to 5 which is TRUE
*/

if (printf("hello\n"))
printf("printf prints hello and returns no of characters printed,"
" here 5\n");
else
printf("function call if returns 0 then else executed!\n");

return 0;
}

#include <stdio.h>
int main()
{
/*
* 1. scanf() function stores input value at specified address
* 2. scanf() function returns no of successfully input values
* as integer, here 1
* 3. Conditional Expression in if evaluated to 1 which is TRUE
*/

if (scanf("%d", &number))
printf("scanf() as a condition used in the if statement!\n");
else
printf("function call if returns 0 then else executed!\n");

return 0;
}


#include <stdio.h>
#include <ctype.h>

/* function prototype: function returns Integer */

int recursive_display(int);

int main(void)
{
int char_dec_val,ret;

if (ret = recursive_display(char_dec_val = getchar()))
printf("\nrecursive fun. implemented successfully!\n");
else
printf("recursive fun. returns 0, so else executed!\n");

printf("recursive_display() returns %d\n", ret);
return 0;
}
int recursive_display(int counter)
{
if (counter == 1) {
printf("Recursion Count is %d\n", counter);
return 1;
}
else {
printf("Recursion Count is %d\n", counter--);
return recursive_display(counter);
}
}

/*
* 1. Try to analyze the output of the following program
* 2. main() is called as conditional expression in if-else construct
*/

#include
int main(void)
{
if (main())
printf("main() fun called!\n");
else
printf("else executed!\n");

return 0;
}
nested if-else Statement: Syntax


/*
* 1. nested if statements with single else clause
* 2. else clause associates with the inner most if
* statement which is incomplete
*/

/* innermost if clause to which single else associates */

if (condition1)
if (condition2)
if (condition3)
if (condition4)
statements;
else
statements;

/*
* Above, the else statement is associated with if (condition4)
*/
switch statement: Syntax

1. expression in the switch must result in integer value.
2. Maximum one of the label values match the expression value in order for the corresponding statements to execute. Otherwise default statement executes if present in the switch statement.
3. break statement must be in the end in each case.
4. break causes the execution to jump out of the switch to the statement immediately following the switch.
5. break statement following the default clause is optional if default clause is placed as the LAST statement. However, break is must with default clause if the same is placed elsewhere within the switch!


switch (expression) {
case label: statements;
break;
case label: statements;
break;
case label: statements;
break;
case label: statements;
break;
default : statements;
break;
}
Use of continue statement in switch

1. switch statement is not a loop statement, therefore use of continue statement within the switch results compilation error!
2. Actually continue statement in loop causes the iteration to go over again preventing the statements following the continue to execute. For Example:

/*
* 1. Use of continue in for loop
* 2. value of i is not displayed in the following for loop when
* i is 8 or 9 or 10 because of continue statement
*/

for (i = 5; i <= 10; i++){
if (i == 8 || i == 9 || i == 10)
continue;
printf("i is %d ", i);
}
Top
08 What is the Output When if statement in C has Empty Statement “;” as Conditional Expression
Question: What is the output for the following code snippet? Will the program get compiled? If not, can you correct the condition in the if statement?
if (;)
printf("empty statement ; is considered true!");
else
printf("empty statement ; is considered false");
Answer: COMPILATION ERROR! Well! if the empty statement ” ; ” in the if statement is placed in the character literals ‘ ‘, program will compile and run successfully to display the first massage. Reason is characters are INTEGERS INTERNALLY. ; has decimal value 59 in ASCII Character Set. So, the working code would be:

if (';')
printf("empty statement ; is considered true!");
else
printf("empty statement ; is considered false");
Top
09 What is Dangling “else” Statement in C Language
This C Tutorial explains “Dangling else” in C. It explains the association of single else statement in a nested if statement.
In nested if statements, when a single “else clause” occurs, the situation happens to be dangling else! For example:

if (condition)
if (condition)
if (condition)
else
printf("dangling else!\n"); /* dangling else, as to which if statement, else clause associates */

1. In such situations, else clause belongs to the closest if statement which is incomplete that is the innermost if statement!
2. However, we can make else clause belong to desired if statement by enclosing all if statements in block outer to which if statement to associate the else clause. For example:

if (condition) {
if (condition)
if (condition)
} else
printf("else associates with the outermost if statement!\n");
Top
10 Explain While, For and Do-While Loop Statements in C with Examples
This C Tutorial explains various loop statements in C with example usage.
A loop statement is one which repeatedly executes, ensuring a given condition to be true prior to execution of each iteration, to perform some computations/work. As the condition turns false, loop terminates.

In C programming Language, loops are while statement, for statement, do-while statement

In while and for loops, conditional expression is tested a priory the execution of each iteration while in the do-while loop, condition is tested after execution of each iteration. This means in do-while loop, first iteration always executes even if condition happens to be false in first iteration!

Syntax

/*
* In while, condition is tested in the beginning of each iteration
*/

while (condition) {
statements;
}

for (initialization; condition; adjustment) {
statements;
}

/*
* In do-while: condition is tested in the end of each iteration
*/

do {
statements;
} while(condition);
Examples:


while loop

/* echo.c -- repeats input */

#include <stdio.h>
int main(void)
{
int ch;

/*
* 1. getchar() function reads-in one character from the keyboard
* at a time
* 2. return type of getchar() is int
* 3. getchar() returns integer value corresponding to char read
* from the keyboard
*/

/*
* ch is checked if it is not same as '!', and as match occurs,
* loop terminates.
*/

while ((ch = getchar()) != '!')
putchar(ch);
return 0;
}

for loop

/* echo_eof.c --- repeating input to end-of-file */

#include <stdio.h>
int main(void)
{
int ch;

/*
* EOF is a character defined, as a Macro, in the stdio.h header file
* EOF is a unique invisible character marks end of every file
* adjustment statement not required so left blank
*/

for (ch = getchar(); ch != EOF; ) {
putchar();
ch = getchar();
}
return 0;
}

do-while loop

/* echo.c -- repeats input */

#include <stdio.h>
int main(void)
{
int ch;

/*
* 1. ch is checked if it is not same as '!', as match occurs,
* loop terminates.
* 2. Even if the first character reads-in is '!', it is printed
* on the screen & then loop terminates!
*/

do {
ch = getchar();
putchar(ch);
} while(ch != '!')

return 0;
}
This is important to note that any Non-Zero value, integer, floating point values, as a condition is considered to be true while 0 is false! For examples:

while loop

/* echo.c -- repeats input Indefinitely */

#include <stdio.h>
int main(void)
{
int ch;

/*
* 1. getchar() function reads-in one character from the keyboard
* at a time
* 2. return type of getchar() is int
* 3. getchar() returns integer value corresponding to char read
* from the keyboard
*/

/*
* Non-Zero value as a condition causes loop to Indefinitely
* Iterate Over.
* key-in ctrl+c on Linux to terminate the program.
*/

while (500.345) {
ch = getchar();
putchar(ch);
}

return 0;


for loop

/* echo_eof.c --- repeating input Indefinitely */

#include <stdio.h>
int main(void)
{
int ch;

/*
* 1. initialization & adjustment statements not required so left blank
* 2. By default, initialization, conditional & adjustment statements,
* all three are Optional. If not given, they are considered TRUE.
*/

for ( ; 200 ; ) {
putchar();
ch = getchar();
}
return 0;
}


do-while loop

/* echo.c -- repeats input indefinitely */

#include <stdio.h>
int main(void)
{
int ch;

do {
ch = getchar();
putchar(ch);
} while(1)

return 0;
}
Top
11 What are the Differences Between while and for Loop in C?
This C Tutorial explains the differences between the while and for loop in C.

Basically, there are two major differences between these two loops.

1. In for loop, initialization, condition and adjustment statements are all put together in one line which make loop easier to understand and implement. While in the while loop, initialization is done prior to the beginning of the loop. Conditional statement is always put at the start of the loop. While adjustment can be either combined with condition or embedded into the body of the loop. For example:

/*
* for loop
*/

for (initialization; condition; adjustment) {

}

/*
* while loop
*/

initialization;
while (condition) {
statements;
adjustment;
}

Example:


#include <stdio.h>

int main(void)
{
int count;

count = 0;

/*
* adjustment is put together with condition
*/

while (count < 10 && (count += 1))
printf("count is %d\n", count);

return 0;
}


2. When using “continue;” statement in for loop, control transfers to adjustment statement while in while loop control transfers to the condition statement. For example:


for (initialization; condition; adjustment) {
statements;
continue;
- - - -;
statements;
}

initialization;
while (condition) {
statements;
continue;
adjustment;
}
Examples:

int main(void)
{
int count;

count = 0;

/*
* 1. adjustment is with the condition
* 2. continue; statement transfers control to the
* "condition + adjustment" in the first line
* 3. continue; statement like break; statement should
* be put under decision-control statements
* 4. observe the output of the program
*/

while (count < 10 && (count += 1)) {
if (count <= 5)
continue;

printf("count is %d\n", count);
}
return 0;
}


int main(void)
{
int count;

/*
* 1. adjustment is embedded into the body of the loop
* 2. continue; statement transfers control to the "condition and not
* to the adjustment" in the first line
* 3. continue; statement like break; statement should be put under
* decision-control statements
* 4. observe the output of the program, how it differs from the previous example
*/

count = 0;
while (count < 10)) {
count += 1;
if (count <= 5)
continue;

printf("count is %d\n", count);
}
return 0;
}
1. continue; statement is only used in loops.
2. This is to note that “continue;” statement if used in loops causes the loop to iterate over again preventing the normal execution after the continue statement.
Top
12 How to Choose Between do-while and while Loops in C Programming
How to Choose Between do-while and while Loops in

C Programming

This C Tutorial explains the difference between do-while and while loops in C Programming.

In do-while loop, condition is always tested after the the execution of the iteration and if condition fails, loop terminates. Therefore, do-while loop executes at least one iteration before termination if condition fails in first iteration! For example:

#include <stdio.h>

int main(void)
{
int counter = 0;

do {
/* loop executes just once printing the value 0 */

printf("counter is %dn", counter);
} while(counter++ != 0);

return 0;
}

In while loop, condition is checked before execution of each iteration and as condition fails, loop terminates. For example:

#include <stdio.h>

int main(void)
{
int counter = 0;

/* loop terminates in the beginning of first iteration */

while (counter++ != 0)
printf("counter is %dn", counter);

/* here counter val is printed as 1 */

printf("counter is %dn", counter);
return 0;
}
Top
13 Describe goto Statement and its Pros and Cons in C Programming
Question: What is a goto statement in C Programming Language? Specify Pros & Cons of goto statement.

Answer:

Syntax of goto

goto label-name;
- - -
- - -
- - -
label-name: statement;
1. Both “goto label-name;” statement and its “label-name:” must be in the same function because outside the function goto does not work! However, these two can be used anywhere in the same function i.e. label-name can come either before or after the goto statement!

2. A goto statement causes program control to jump to a statement bearing the indicated label. A colon is used to separate a labeled statement from its label. Label names follow the rules for variable names. For example:

top : ch = getchar();

.
.
.

if (ch != 'y')
goto top;
2. By using gotos excessively, you create a labyrinth of program flow. If you aren’t familiar with gotos, keep it that way. If you are used to using them, try to train yourself not to. Ironically, C, which doesn’t need a goto, has a better goto than most languages because it enables you to use descriptive words for labels instead of numbers.



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

int main(void)
{
display();

return 0;
}

int display()
{
int whattodo;

printf("user, enter 1 or 0n");
scanf("%d", &whattodo);

if (whattodo == 1)
goto hello;

if (whattodo == 0)
printf("bye display() funn");
return 0;

hello : printf("HELLOn");
goto bye;

bye : printf("BYEn");

return 0;
}
3. There is one use of goto practiced by many C programmers—getting out of a nested set of loops if trouble shows up (a single break gets you out of the innermost loop only). For example:

while (funct > 0) {
for (i = 1; i <= 100; i++) {
for (j = 1; j <= 50; j++) {
statements;
if (bit trouble)
goto help;
statements;
}
more statements;
}
yet more statements;
}
and more statements;

help : out;
Alternatives to goto

As we have seen earlier, using gotos excessively causes program flow a labyrinth. We have two alternatives, one is we can set a flag & test the flag in every loop & the other is we put the set of nested loops in a separate function & use return; statement when some problem happens. For example:

/*
* 1. status, an enumerated variable, can take values EXIT, OK
* 2. EXIT, OK are symbolic names which are internally Integers
* 3. symbolic constants are assigned values as Integers from 0
* to successive integers starting from left to right
*/

enum { EXIT, OK } status;

status = OK;
while (status == OK && condition1) {
while (status == OK && condition2) {
while (status == OK && condition3) {
if (some problem)
status = EXIT;
break;
}
}
}
Other way: using the return statement; in a function



loop_fun();

/*
* 1. set of nested loops are put inside a separate function
* 2. when some problem happens, return; statement causes exiting
* the function
*/

int loop_fun()
{
while (condition1) {
while (condition2) {
while (condition3) {
if (some problem)
return 0;
}
}
}
}
PROS and CONS of goto statement:

1. This makes easy writing the programs.
2. Excessive use of gotos causes program flow a labyrinth. Therefore, Programs with goto statements are DIFFICULT to understand and DIFFICULT to maintain.
3. Try to avoid practicing goto statements. Use alternatives for goto statement.
Top
14 Explain Storage Classes in C Language with Examples
This C Tutorial explains Storage Class in C Language as well as their types. It also explains the relationship with the scope of the variables/identifiers in the program with examples.
Storage class of a variable refers to the type of memory allocated to a variable. For example

int num = 10; /* num, an integer is allocated the automatic memory */
There are four types of storage classes viz. automatic, registers, static and global or extern.

Variables which are declared inside the blocks, inside the curly braces {}, are called the local variables and are given automatic storage. For example:

int index;
char colour;

/*
* index is an automatic variable, automatic keyword is not necessary.
* colour is also an automatic variable of type character, characters are internally INTEGERS
*/

Register variables store values in the hardware registers. However they behave exactly as the automatic variables in that they are created and destroyed when the function is called & exited respectively. For example:

register int x = 10;
When a variable is declared static, it is given memory allocation, at the compile time, in the static area before the program begins to execute and exists throughout the execution of the program. Also, static variables retain their last modified values. Variables declared outside of any blocks are allocated statically. When declared inside some function, exists during entire program for that particular function whenever called. Static variable is initialized to 0 by default! For example:

static int sum = 0;
Global variables are declared outside of all functions. They are also allocated memory statically. Remain in existence during the entire execution of the program. Initialized to 0 by default. If they are to be accessed across other source files than the file in which they are defined, use extern keyword.


Relation of Storage Class to Scope of the Variables

Automatic and register variables have their life from the point of declaration till the end of the block in which they are declared!

Static variables have their scope from the point of declaration till the end of the file! In cases, if defined inside a block, their access is within the block!

Global variables can be accessed throughout the source file from their declaration and across other source files with extern keyword.
Top
15 Does a Function have any Storage Class in C Language
Question: Does a function have any storage class in C Language? In what type of memory does the program code store?
Answer: Functions do not have any storage class. Actually, storage class is not an issue for the functions because Program Code is stored in the static memory. At run time, executable image (an ELF image on Linux) is loaded into the the physical memory area called the Process Address Space. Process Address Space comprises of three Segments viz. Text Segment, Stack Segment and Data Segment.

Program code is stored in the Text Segment, automatic/local variables, function’s return addresses etc. in the Stack Segment and Data, initialized and uninitialized in the Data Segment.

Top
16 Explain Linkage and Scope of Variables and Functions in C with Examples
This C Tutorial explains Linkage/Scope of variables and functions in C with examples and defines the type of Linkages.
Linkage of any variable and/or function defines the Area of the Program in which they are accessible. There are three types of Linkages for the variables & functions. These are as follows

1. EXTERNAL
2. INTERNAL
3. NONE

External linkage defines that the variable, function can be accessed throughout the program, across the multiple source files if program comprises of several source files with the use of Keyword extern.


#include <stdio.h>
int counter;
extern float marks;

/*
* External linkage: counter is an integer accessible across entire program
* External linkage: marks which is of float type defined in some other source file & used here
*/

void hello(void);
int main()
{
printf("the marks are %f\n", marks = 55.9);

return 0;
}
Static Keyword changes Linkage from External to Internal meaning that any variable, function declared globally with static keyword can only be accessed within the source file from the point of declaration until the end of the program in which it is declared.

#include <stdio.h>

/*
* Internal Linkage: counter can only be accessed within this source file from this point till the end of the file
* Internal Linkage: function hello can only be accessed within this source file
*/

static int counter;
static void hello(void);

int main(void)
{
hello();
}
Automatic and register variables neither have external nor internal linkages. They are accessed only within the blocks in which they are declared. For example:


#include <stdio.h>
void hello(void);
int main(void)
{
hello();

return 0;
}

void hello()
{
int counter = 1; /* counter is an automatic variable i.e. ONLY accessible within this block! */

printf("the value of counter is %d\n",counter);
}
Top
Render time: 0.36 seconds
7,457,218 unique visits