Wednesday 28 January 2015

Macros - Features of C Preprocessor

Welcome to Logically Proven Blog.
This post teaches you one of the important features of C preprocessor - Macro Expansion.

C preprocessor is a special program that processes source program before it is passed to the compiler. The preprocessor commands also known as directives. Each of these preprocessor directives begin with a # symbol. These directives can be placed anywhere in a source program but are most often placed at the beginning of a source program.

A million dollar question - Why Macro?
To made the program easier to read and understand.


Macro:

Have a look at the following program.
#include <stdio.h>
#define max 100
int main()
{
 printf("max is %d", max);
 return 0;
}
// Output: max is 100
// Note that the max inside "" is not replaced

In this program instead of writing 100 in the printf statement we are writing in the form of max, which has already defined before main() through the statement,
#define max 100
This statement is called macro. 

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. In the above program max is defined as 100.


A #define directive could be used even to replace a condition as shown below -
#include <stdio.h>
#define AND &&
#define ARANGE ( a > 25 AND a < 50 )
int main()
{
 int a = 30;
 if (ARANGE)
  printf("within range");
 else
  printf("out of range");
 
 return 0;
}
// Output: within range
Note:
1. Macro template and macro expansion are separated by blanks or tabs.
2. A macro definition is never to be terminated by a semicolon.

Macro with Arguments:

The macros can take arguments like function, 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 = "LogicallyProven";
 int x = 10;
 printf("%s  ", INCREMENT(ptr));
 printf("%d", INCREMENT(x));
 return 0;
}
// Output: ogicallyProven 11
An another example of macro with arguments which is checking for a condition -

#define ISDIGIT(x) ( x >= 48 && x <= 57 )

Note:

1. Do not leave a blank between the macro template and its argument while defining the macro.
    For example there is no blank between ISDIGIT and (x) in the definition above.

2. The entire macro expansion should be enclosed within parantheses.
     Consider a statement in a program: i= 64/SQUARE(4)

     Macro:    #define SQUARE(n) n*n        - Wrong  //output is 64 (64/4*4)
                      #define SQUARE(n) (n*n)      - Correct //output is 4 (64/(4*4))

     The macro arguments are not evaluated before macro expansion.


     This can be corrected using "inline functions".
   
   inline int square(int n) { return n*n; }
   int main()
   {
      int n = 64 / square(4);
      printf("%d", n);
      return 0;
   }
   // Output: 4

3. The macro can be written in multiple lines using '\'. The last line doesn't need to have '\'.

     Example:
                     #include <stdio.h>
            #define PRINT(i, limit) while (i < limit) \
                      { \
                             printf("GeeksQuiz "); \
                             i++; \
                      }
Token-Pasting operator:

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
String converter:

A token passed to macro can be converted to a string by appending # before it.
#include <stdio.h>
#define get(a) #a
int main()
{
 // LogicallyProven is changed to "LogicallyProven"
 printf("%s", get(LogicallyProven));
}
// Output: LogicallyProven
Standard macros:

There are some standard macros which can be used to print the program file, date of compilation, time of compilation and line number in C code.

#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 :D:\myCB\ifcondition\LogicallyProven\main.c
Current Date :Jan 28 2015
Current Time :17:45:45
Line Number :7 */

Please write comments if you find anything incorrect, or you want to share more information about the topic discussed above.

Logically Proven
learn, teach, share

Tuesday 27 January 2015

C Programming - Common mistakes while using the "if" statement

This post demonstrates common mistakes while using the if statement. The recent IDEs and compilers issues a warning if the code encounters such mistakes. One way to resolve such mistakes is to force the IDEs and compilers to show warnings as errors. This way you can build your application more robust.

if -


The if statement is used to check a condition and if the condition is true, we run a block of statements (called if-block), else we process another block of statements (called the else-block). The else clause is optional.

 

Mistake 1: Using the assignment operator = instead of the relational operator ==


int main()
{
     int i;
     printf("Enter value of i ");
     scanf("%d", &i);
     if (i = 10)
          printf("You entered 10");
          else
             printf("You entered other than 10");
     return 0;
}
/*output:
Enter value of i 499
You entered 10
Enter value of i 9999
You entered 10 
*/
 

 Every time the output is You entered 10. This is because of

using assignment operator = instead of relational operator ==.
So whatever value you supply, the above program prints You entered 10. In C, other than zero is considered as TRUE in if statement. So the program prints You entered 10.


How to Resolve?


This mistake can be easily avoid by interchanging the variable and constant in a if statement.
Write the condition like this if(10 = a) , so you will receive the compiler error, you cannot assign a variable to a constant.

 

Mistake 2: if statement followed by a semicolon (;)


Consider the following program.
int main()
{
     int i;
     printf("Enter value of i ");
     scanf("%d",&i);
     if (i == 10);
          printf("You entered 10");
     return 0;
}
/*output:
Enter value of i 499
You entered 10
Enter value of i 9999
You entered 10 
*/
 

The ; makes the compiler to interpret the statement as follows -

if (i == 10)     
;
printf("You entered 10");
 
consider the condition returns true;
the ; (null statement, which does nothing on execution) gets executed, following the printf() gets executed.
Consider the condition returned false;
then straight-away the printf() gets executed.
Thus, irrespective of whether the condition evaluates to true or false the printf() gets executed. Both example one and two contain so-called semantic errors. This type of error is also called logical errors and is not discovered by the compiler when the syntax is correct. Therefore, there is a plethora of tools you can use to examine the source code before going ahead and compile it.


How to Resolve?


You can resolve these mistakes using the Splint tool.
Splint is a tool for statically checking C programs for security vulnerabilities and coding mistakes. With minimal effort, Splint can be used as a better lint. If additional effort is invested adding annotations to programs, Splint can perform stronger checking than can be done by any standard lint.
For more details on Splint - Click here

Please share your thoughts on this post in the comments section.

Monday 26 January 2015

C/C++ programming - Difference between “int main()” and “int main(void)”

This post demonstrates the 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 definitions 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, but the following program fails in compilation -

// 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 program 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.


Try yourself -


//Question 1:
#include <stdio.h>
int main()
{
 static int i = 5;
 if (--i){
  printf("%d ", i);
  main(10);
 }
}

//Question 2: 
#include <stdio.h>
#include <stdio.h>
int main(void)
{
 static int i = 5;
 if (--i){
  printf("%d ", i);
  main(10);
 }
}
 

Please share your thoughts on this post in the comments section.

Friday 23 January 2015

What is 'C'? Why it is important to learn 'C' now-a-days?

This post demonstrates why it is important to learn C programming now-a-days before you learn any high-level programming languages (C++, Java, C#...).

What is C?

 

C is a programming language developed by Dennis Ritchie at AT & T's Bell Laboratories of USA in 1972. In the late seventies C has began to replace the more familiar languages of that time like FORTRAN, ALGOL and many more. C has proven to be a powerful and flexible language that can be used for a variety of applications, ranging from business programs to engineering.
Possibly why C is a particularly popular language because it is reliable, simple, relatively small and easy to use.
Moreover, in this technical industry where newer languages, tools and technologies emerge and vanish, a language that has proven and survived for more than 4 decades. The first major program written in C was the UNIX operating system. Now, however, C is an important language independent of UNIX. Although it is a high-level language, C is much closer to an assembly language than are most other high-level languages. This closeness to the underlying machine language allows C programmers to write very efficient code.

Why it is important to learn?

 

There are several reasons why it is much important to learn 'C' today.
  • You can ask anyone who are working on C++ or Java, whether they have learned Java or C++ directly without learning 'C'. The answer is No. I believe that nobody can learn C++ or Java directly. This is because while learning these languages you have things like classes, objects, inheritance, polymorphism, templates, exception handling, references, etc. do deal with apart from knowing the actual language elements. Learning these complicated concepts when you are not even comfortable with the basic language elements is like putting the cart before the horse. Hence one should first learn all the language elements very thoroughly using C language before migrating to C++, C# or Java. Though this two step learning process may take more time, but at the end of it you will definitely find it worth the trouble.
  • C++, C# or Java make use of a principle called Object Oriented Programming (OOP). This organizing principle has lots of advantages to offer. But even while using this organizing principle you would still need a good hold over the language elements of C and the basic programming skills.
  • Though many C++ and Java based programming tools and frameworks have evolved over the years the importance of C is still unchallenged because knowingly or unknowingly while using these frameworks and tools you would be still required to use the core C language elements—another good reason why one should learn C before C++, C# or Java.
  • Major parts of popular operating systems like Windows, UNIX, Linux is still written in C. This is because even today when it comes to performance (speed of execution) nothing beats C. Moreover, if one is to extend the operating system to work with new devices one needs to write device driver programs. These programs are exclusively written in C.
  • Mobile devices like cellular phones and palmtops are becoming increasingly popular. Also, common consumer devices like microwave oven, washing machines and digital cameras are getting smarter by the day. This smartness comes from a microprocessor, an operating system and a program embedded in this devices. These programs not only have to run fast but also have to work in limited amount of memory. No wonder that such programs are written in C. With these constraints on time and space, C is the language of choice while building such operating systems and programs.
  • You must have seen several professional 3D computer games where the user navigates some object, like say a spaceship and fires bullets at the invaders. The essence of all such games is speed. Needless to say, such games won't become popular if they takes a long time to move the spaceship or to fire a bullet. To match the expectations of the player the game has to react fast to the user inputs. This is where C language scores over other languages. Many popular gaming frameworks have been built using C language.
  • At times one is required to very closely interact with the hardware devices. Since C provides several language elements that make this interaction feasible without compromising the performance it is the preferred choice of the programmer.

Please share your thoughts on this post in the comments section.

Thursday 22 January 2015

C Programming - Integer to Binary

Convert an integer to binary irrespective of platform. The size of an integer varies from platform to platform. We assume the size of an integer either 32 bit or 64 bits in an application with respect to the working platform which leads to unexpected output.

The ideal solution is converting without assuming the size of an integer.
Don't forget to include the standard library stdlib.h which supports malloc and free functions. Else you will get a warning incompatible implicit declaration of built-in function 'malloc'.
#include <stdio.h>
#include <stdlib.h>
 
//function declaration
char *integer2binary(int n);
 
int main()
{
 
    //find how many bits are needed for the integer type.
    //sizeof() returns in bytes. So convert into bits.
    printf("Your integers are %u bits wide.\n\n", sizeof(int)*8);
 
    //An Array with integers
    int nums[13] = { 0, 1, 2, 3, -1, -2, -3, 255, 256, 1023, 1024, 8191, 8192 };
    int index;
 
    for (index = 0; index < 13; index++) {
 
        //A character pointer which stores the converted binary number
        char *s = integer2binary(nums[index]);
 
        //Printing the binary number
        printf("%d -> %s\n", nums[index], s);
 
        //Free the memory for the next conversion
        free(s);
    }
    return 0;
} 
 

char *integer2binary(int n) -


char *integer2binary(int n) {
 
    // determine the number of bits needed ("sizeof" returns bytes)
    int nbits = sizeof(n) * 8;
 
    //malloc function is used to allocate a certain amount of memory
    char *s = malloc(nbits+1);  // +1 for '' terminator
 
    s[nbits] = '';
 
    // forcing evaluation as an unsigned value prevents complications
    // with negative numbers at the left-most bit
    unsigned int u = *(unsigned int*)&n;
 
    //declaring a temporary variable
    int temp; 
 
    //left shift operator (<<)
    unsigned int mask = 1 << (nbits-1); // fill in values right-to-left
 
    for (temp = 0; temp < nbits; temp++)
    {
            s[temp] = ((u & mask) != 0) + '0';
 
            //right shift operator (>>)   
            mask >>= 1;
    }
    return s;
} 
   

Output -

integer to binary  
Your result may not be same as in the screenshot shown here. Depends on number of bits wide of integer on your machine.
 

Please share your thoughts on this post in the comments section.

Wednesday 21 January 2015

C Programming - Switch statement - Interesting

This post demonstrates not well-known features of switch statement in any programming language that makes use of switch-case structure.

Switch Statement -

When the program encounters the situation to choose a particular statement among many statements, then the programmer decides to choose one block of statement depending on the problem statement.
This can be achieved with alternatives like if, if-else, nested if-else. But this makes no program readability and makes programming logic complex. So, this type of problem can be handled in C programming using switch statement.


Syntax -


switch(expression){
    case constant-expression  :
       statement(s);
       break; /* optional */
    case constant-expression  :
       statement(s);
       break; /* optional */
  
    /* you can have any number of case statements */
    default : /* Optional */
       statement(s);
}
 


Flowchart Representation -


 

switch-case    
Note – Consider every code block contains the break statement except the defaultcode block at the end.
break statement is optional.
break statement breaks the execution and exits the switch once the matched case statements are executed.
 


Not Well-Known Features -


A switch statement’s case labels can occur inside
  • if-else statements
  • loops (for, while)


Sample Code -


#include <stdio.h>
#include <stdlib.h>

int main()
{
    int a,b;
    a=1;
    b=1;
    switch(a)
    {
        case 1: printf("Hello\n");

                if(b==2)
                {
                    case 2: printf("Printing the case statement from if\n");
                }
                else case 3:
                {
                    for(b=1;b<=10;b++)
                    {
                        case 5: printf("Printing the case statement from for loop\n");
                    }
                }

                break;

        case 4: printf("World\n");
                break;
    }       
return 0;
 


Output -


Hello
Printing the case statement from for loop
Printing the case statement from for loop
Printing the case statement from for loop
Printing the case statement from for loop
Printing the case statement from for loop
Printing the case statement from for loop
Printing the case statement from for loop
Printing the case statement from for loop
Printing the case statement from for loop
Printing the case statement from for loop
 

Summary -

It is 100% allowed to include if-else and loops inside the switch statement.

Please share your thoughts on this post in the comments section.

Tuesday 20 January 2015

A puzzle and a logic behind - C and C++ programming

Hi Friends.

Today I am going to ask you the puzzle in 'C' programming. Of course I am going to explain the logic behind the puzzle.

I doubt that most of them know the answer or partial answer to the puzzle. But friends it gives me immense pleasure to share my knowledge with you all.

This question was asked by my professor. I have enhanced the question a bit and puzzling you.

Let get into the puzzle. Look at the picture below.















You have to update the if condition, so the program prints "Hello World" and numbers should Swap as
shown in the picture (I achieved this with one warning. You have to think on this, because it is a hint too).

One more hint friends, you can see the post "Swap in a single statement" in this blog.

So guys I hope some of them already figured out the answer or at least a part of answer. If you not yet don't worry let walk into the remaining post.

Explanation:

 Whenever I think about IF condition in 'C' language, I always remember one small small thing about IF. This is the reason behind this puzzle.

Are you thinking what it is. Okay! I don't make you wait. It is IF condition executes the ELSE loop only when the condition or expression returns the value "ZERO" (0). Other than ZERO, IF statement returns TRUE.

And one more important thing is if statement executes all expressions in case of AND operation until it encounters FALSE (T && T && F && anything leads to FALSE). In case of OR operation if statement executes until it encounters TRUE (F || F|| T || anything leads to TRUE).

Note - Here FALSE means ZERO. TRUE means other than ZERO.

So, I have updated the IF condition with an EXPRESSION other than LOGICAL EXPRESSION.

Following are the two answers to the puzzle.

1. if(printf("Hello ",a=(a+b)-(b=a)))
2. if((printf("Hello ")) && (a=(a+b)-(b=a)))

You can use either of these.

In the first answer, it prints "Hello " and swap the values. The IF condition is not leading to ZERO. So the TRUE block will be executed.

In the second answer, it prints "Hello ". The first condition is TRUE (because not zero) and evaluates the second condition where it swaps the values and evaluates the TRUE block of IF statement.

Please comment if you have any questions or do you know any other way of achieving this puzzle.

Hope you enjoyed this article. Will meet in the next article.

Learning made easy.




Monday 19 January 2015

Swap numbers in a single statement

This post demonstrates how to swap numbers in a single statement without using a temporary variable.

For your reference, representing all the forms of how to swap numbers without using a temporary variable.


Using addition and subtraction operators -


int main()
{
 int a,b;

 a = 10;
 b = 9;

 a = b-a;
 b = b-a;
 a = a+b;

 return 0;
}
 


Using XOR operator -


int main()
{
 int a,b;

 a = 10;
 b = 9;

 a = a^b;
 b = a^b;
 a = a^b;

 return 0;
}
 


In a single line -


int main()
{
 int a,b;

 a = 10;
 b = 9;

 a = (a+b) - (b=a);

 return 0;
}

 The above code throws the following warning if you are using any IDEs like codeblocks etc. Ignore the warning, the code just works fine.
warning: operation on 'b' may be undefined [-Wsequence-point]

Please share your thoughts on this post in the comments section.

C Operator Precedence table with Associativity

This post demonstrates the list of operators available and their precedence with associativity in C.

What is Operator Precedence?

 

Operator precedence determines how operators are grouped, when different operators appear close by in one expression. For example, '*' has higher precedence than '+'. Thus, the expression a+b*c means to multiply b and c, and then add a to the product (i.e., a+(b*c)). You can overrule the precedence of the operators by using parenthesis. For example, consider the expression a+b*c, you want to first add and then multiply. In this case, write the expression as (a+b)*c.

What is Associativity?

 

If two operators has the same precedence, then associativity tells you in which direction the expression will be carried out by grouping operators. For example, '+' and '-' have the same precedence. Thus the expression a+b-c means to add a and b, and then subtract c from the addition (i.e., (a+b)-c). The expression is carried out from left to right direction.
Precedence - How operators are grouped in an expression. Associativity - In what order operators of equal precedence are grouped in an expression.

List of C operators in order of precedence (highest to lowest) -

 

Operator
Description
Associativity
( ) [ ] . -> ++ -- Parentheses (function call) (see Note 1) Brackets (array subscript) Member selection via object name Member selection via pointer Postfix increment/decrement (see Note 2) left-to-right
++ -- + - ! ~ (type) * & sizeof Prefix increment/decrement Unary plus/minus Logical negation/bitwise complement Cast (convert value to temporary value of type) Dereference Address (of operand) Determine size in bytes on this implementation right-to-left
* / % Multiplication/division/modulus left-to-right
+ - Addition/subtraction left-to-right
<> Bitwise shift left, Bitwise shift right left-to-right
< >= Relational less than/less than or equal to Relational greater than/greater than or equal to left-to-right
== != Relational is equal to/is not equal to left-to-right
& Bitwise AND left-to-right
^ Bitwise exclusive OR left-to-right
| Bitwise inclusive OR left-to-right
&& Logical AND left-to-right
| | Logical OR left-to-right
? : Ternary conditional right-to-left
= += -= *= /= %= &= ^= |= <>= Assignment Addition/subtraction assignment Multiplication/division assignment Modulus/bitwise AND assignment Bitwise exclusive/inclusive OR assignment Bitwise shift left/right assignment right-to-left
,
Comma (separate expressions) left-to-right
Note 1:
Parentheses are also used to group sub-expressions to force a different precedence; such parenthetical expressions can be nested and are evaluated from inner to outer.
Note 2:
Postfix increment/decrement have high precedence, but the actual increment or decrement of the operand is delayed (to be accomplished sometime before the statement completes execution). So in the statement y = x * z++; the current value of z is used to evaluate the expression (i.e., z++ evaluates to z) and z only incremented after all else is done. See postinc.c for another example.

Please share your thoughts on this post in the comments section.

 
biz.