C Basics II


In this article I have used of various examples to show how C programs are written.

1.  C program structure

Example 1.
main()

  ;;;;;
  +32;
  23*320+23;
  -34;
  3%3;
  "We love our Counry";
}
The above program would not show you any error message; rather it‘ll warn you by saying that “code has no effect”. All the statements shown here do not have any syntax error and any meaning as well.
Even any C program may not contain any statements at all. Check the following..
main() {   }
But this serves no purpose . We should write purposeful programs.

In the above example 1, we wrote an instruction:  23*320+23;
This instruction does not have any meaning. By the way, computer will perform the calculation and may store the value at some memory location from where we can’t fetch it back…we can’t use it anymore because it’s almost impossible to track the address where in memory the value was stored. That’s why we need variables to store values so that we can use the value later on through that variable.

2.  Datatypes, Variables and Constants

Check for any errors in the programs given below.
Example 2.1
main()

  int 'integer'=90;
  int total_number_of_wickets_is =4, x86cpu=9;
  float cp@hotmail =9;
  char well-being='T';
  int 10$=10;
  float 122;
  int salary per month=3000;
  double abcdefghijklmnopqrstuvwxyz1234567890=12345.54321;
}


Explanation: All the statements except the second & last ones carry errors. There are some general rules for constructing variable names.

a. Variable name should be minimum 1 character long and start with character only. In Turbo C, anything beyond 31 characters are ignored.
b. No ,/’”\][{}+=()#@!`-/>< %^&*$ etc are allowed within a variable name.
c. Variable name may contain special character underscore.
d. Variable name should start with an alphabet. For this reason, statement 5 
    & 6 would give an error while compiling.
e. variable names are case sensitive. “C” is different from “c”.

So, in the 1st statement, variable name contains inverted commas which are not acceptable. The 3rd one has @, 4th has one hyphen, 5th contains ‘$’, 6th statement violates the rule d) shown above. 7th has blank …. All of them are illegal when used within a variable name. The 2nd  statement is right because  
  1. Multiple variable declaration in same line is allowed in C.
  2. The first variable has equal or less than 31 chars and all chars including underscores are valid when used in variable name.
  3. 2nd variable  x86cpu is valid because it doesn’t start with digits.

Similarly the last statement is also right. But one thing will happen and that is first 31 characters will be considered as the name of that variable.

Example 2.2
main()
{  
   int int=90;
   double float, char, int, double;
   char char,double='g';   
}

Explanation:   All the statements in the above example are wrong. C uses a set of 32 keywords. Keywords are those words whose meanings are already explained to the compiler. Using it more than once within a statement may confuse the compiler. So we should not use those words as variable names. Compiler would definitely give error message. Float, char, int double, do, while, if, else etc. are some example of keywords. These keywords are also known as ‘Reserved Words’.

State whether the following statements have errors.
A. int a, b, c, d=12, char ah, bh='c', ch, dh='d', float f1,f2=23.34, double d1,d2=0.9;
B. char ch,ch;
C. int I=12*12;
D. int YEAR, Year, year, YeAr , yEaR=2002;
E. int year; char year; float year; double year; year=123;
F. int Int, INt, inT,Char,Float,Double=0;

Explanation:
A. This statement will show you a Syntax error. The statement has four keywords separated by only commas. It is not acceptable in C. The separation commas should be replaced by  semi-colons. Hence the correct syntax will be…
   int a, b, c, d=12; 
 char ah, bh='c', ch, dh='d'
 float f1,f2=23.34; 
 double d1,d2=0.9;
And C compiler won’t mind anything as we’ve put down 4 statements in one line. That’s why C is called a free-form language.
B. This statement will give a redeclaration error message. We’ve declared variable ch twice which is not legal in C. No two variables  (having same names) can be declared at the same time within same scope and context. We will come to this point once again in future.
C. This statement does not have any syntax error. The variable I ultimately gets a value
of 12x12 i.e 144. 
D. This is a valid statement. Don’t think that it isn’t allowed in C as they have same names. Rather compiler will treat them as different from each other. Yes, they definitely are different from each other, and from this example we know that C variable names are case sensitive.
E. This is another invalid statement. Although all variable’s data types are not same, their names are. Hence the compiler would give an redeclaration error. The compiler won’t allow you to use variables having same names.  
F. This is obviously a valid statement although  it seems that we’re using keywords as variable names. But not really. C compiler knows int as a keyword, not Int or INt or Char. C is very much case sensitive.

Now run this following code.

Example 2.3
main()
{
int hi_guys_we_are_going_to_learn_C_as_it_is_a_good_language=123;
int hi_guys_we_are_going_to_learn_C_for_it_is_strong=1234;
}
Here is the output:

Error: Redeclaration of variable ‘hi_guys_we_are_going_to_learn_C_’

Now notice the error message carefully. Our variable name was truncated without taking our permission. Although we have declared a 56 character variable name in the 1st statement, the compiler would store only the first 32 character. Same thing happens in the second statement. As first 32 characters are same in both the variables, compiler would give redeclaration message.

Example 2.4
main()
{
  a; b; c;
}

Error? Well, it should say “undefined symbols a,b,c in module ‘main’  “ , because it does not know anything named a,b or c. We’ve to declare them as variable. Had this code been like this….

main()
{ 
  'a';'b';'b';
}
the compiler would have shown no error message for those ‘a’,’b’,’c’  were all constants, not variables.

Now check the following code and say whether it is valid or not.
main()
  int a,b,c; 
  a+b+c; 
  'a'+'a'+a-b-c+c+'c'; 
}

Example 2.5
main()
{
 printf(" %d %c",'123','a');
}
output will be:
ERROR: character constant too long.

Explanation:
123 was used as a character constant, but according to rules, any character constant can’t have more than 1 character. Hence the error message.

3. Variable Initialization

Example 3.1
main()

  int i= 12.45;
  float f= 5;
  char ch = 'c';
  printf("\n i=%d ,f=%f, ch=%c",i,f,ch);
}

Explanation: The program does not have any kind of  error. The output will be: i=12,f=5.000000,ch=c. This program does not need any explanation. The first statement assigns a float value to the integer variable i , which actually does not happen. In this type of situations, the portion before the point actually gets assigned . In our case, it is 12. And once again, notice the free-form ness of C language.
Now run the following program.

Example 3.2
main()
{
  int i=j=k=l=m=n=10;
}

Explanation: Error? Well it is because, a variable can be initialized to another variable’s only if the latter has been declared earlier. In the above statement, we are attempting to initialize i to value of j. But j is an entity that hasn’t been declared earlier. So the initialization didn’t take place. All variables except i has not been declared in this case. To use any variable, we should declare it at the top of any block, or function. The program can be rewritten like this…
main()


  int i,j,k,l,m,n; 
  i=j=k=l=m=n;
}

Even like this…
main()

  int i=10;
  int j=i; 
  int k=j; 
  int l=k;  
  int m=l; 
  int n=m;
}
In the last example, when we are trying to initialize j to value of i, i has already been declared there. So the initialization is taking place.

Example 3.3
main()
{
 int i=c;
 int j='c';
 char ch='c';
 float f='c';
 double d='c';
 printf("\n j=%d, ch=%c, f= %f, d=%lf",j,ch,f,d);
}


Well, you will get an error saying that, “ Undefined symbol ‘c’ in function main() “.

Explanation:
The first statement is nothing but a initialization statement. We are trying to assign c’s value to variable i. But we had not declared the variable c earlier. So the error. Now comment out this line by putting  /* & */  at the beginning and end of that line respectively. Commenting the line means, the compiler will ignore it whatever written inside. So we’re ignoring the first statement and now run it again. The output is as follows..
 j=99, ch=c, f=99.000000, d=99.000000
Come to the 2nd statement. This statement has no error. Integer j will store the ASCII number of the character ‘c’ which is 99. Similarly float f and double d will hold same value.

Note: Actually, computer can’t understand alphabets, special characters, punctuation notations etc. It can only understand numbers. ASCII table has such characters along with their corresponding number. For example, character A has an ASCII number of 65. So, whenever you are trying to store a character, computer searches it in ASCII table & the corresponding ASCII number of that character gets stored.

Now check one unusual program;

Example 3.4
main()
{
 int ch;
 float f;
 f=ch="Chandan";
 printf("\n %d %c %f",ch,ch,f);
}

The output could be: Error,Non-portable pointer assignment.

Explanation:
The above code May/may not give you any error message. But most probable is that, you would see an error message. Here, we are just doing mess by storing a long character constant or string to an integer & float at the same time. But mind you, not a single character of that string gets stored in ch & f. C doesn’t allow a long strings to be stored in only 2 bytes Integer.

4. Type Modifiers

 
Check the following example.

Example 4.1
main()
{
int j=23;
int k=23L;
int l=023;
int m=0x23;
printf("\n %d %c",j,j);
printf("\n %d %c",k,k);
printf("\n %d %c",l,l);
printf("\n %d %c",m,m);
}

Here is the output:
23   
23   
19  !!
35  #

Explanation:
The 1st statement is quite easy. The 2nd one  int k=23L; is a bit new. 23L means “23 long”. So, 23 is an integer and would occupy 2 bytes in memory, but 23L is a long integer and would occupy 4 bytes. Here we would not face any problem storing a long number into an int, because an int can store  values upto 32768. So k was assigned 23. The 3rd int l=023; is a bit tweaky. Don’t think that l  will be assigned to 23, rather 19 will be stored to l. Because when you say 023, compiler takes it as an Octal Number. But integer l  would store anything in decimal integer form. Octal 23 is same as 19 in decimal. So, when you print l’s value, it shows you this 19. The 4th one int m=0x23; is same as the previous example except one thing, that is, here 0x23 will be taken as an Hexadecimal number and its decimal equivalent 35 will be actually stored in variable m.

Example 4.2
main()
{
char c1=291,c2=234,c3=-345;
int j=99999;
printf("\n %d %d %d %d ",c1,c2,c3,j);
}
Here is the output:
35 –22 -89 -31073

Explanation:
Notice that, all the variables are assigned with values that are beyond their range. Hence they will store some other values instead which were actually assigned to them. In first case, character variable c1 was assigned to 291 whereas it can hold upto +127. So it will truncate 291 and store only a random value. Actually it shouldn’t be said as random. There are some arithmetic behind it. But we won’t discuss them now.

Check this Example.

Example 4.3
main()
{
char ch='z';
int j=125;
float a=12.55;
printf("\n %c %d %f",ch,ch,ch);
printf("\n %c %d %f",j,j,j);
printf("\n %c %d %f",a,a,a);
}

The output:
Z  122  –9.473883455000000000000000e+61
}  125  9.473883455000000000000000e+61 
   -24576    -0.000000

Explanation:
Here, some format conversions are wrongly done. So this disastrous output. The 1st printf() tries to print a character ‘z’ in character form (%c), integer form (%d) and in  float form (%f). The first 2 prints( z & 122 . 122 is ASCII value of z) are understandable. The last one is very very weird and we should not do this type of things. C compiler does not appreciate any conversion from integer to float or vice-versa.

Now some offbeat things. We already know that, the int variable can hold Integer data. Now this Integer Data can be of different types, like Decimal, Octal or Hexadecimal. Assigning those values to an int varible is a bit different. Check the folowing Example.

Example 4.4
main()
{
int j=000234;
int k=0x300;
int l=345;
printf("\n j=%d, k=%d, l=%d",j,k,l);
}
output: j=156, k=768, l=345

Explanation:
The first statement j=000234; doesn’t store 234 for it has a series of Zeros before that. Rather it stores Octal 234 which is same as Decimal 156. Any integer constant that starts with Zero will be treated as a Octal Number. Similarly  any such constant starting with 0X or 0x will be treated as Hexadecimal Number. Hex 300 is same as Decimal 768.
Never enter following statements as they would give syntax error.

1. int j= 00x005;  /* Use Only 0x before hex */
2. integer j = 10; /* ‘integer’ isn't a C keyword */
3. char ch = i;
    int i = 10; /* i must be declared prior to ch in this case


5. Variable Scopes
Scopes of auto variables are local to the block in which they are defined. We use a keyword called ‘auto’ to create automatic variable. If we do not specify any storage class, then also “auto” is implied.

Example 5.1
main()

 auto int j=1;
 { auto int j=2;
   {  auto int j=3;
      { auto int j=4;
        printf("\n %d",j);
        j=j*3;
        printf("\n %d",j);
      }
      printf("\n %d",j);
   }
   printf("\n %d",j);
 }
 printf("\n %d",j);
}
Here is the output:
4
12
3
2
1

Explanation:
Compiler treats four js as totally different variables as they were defined in different blocks. Each block has its own j. So, once the control comes out of the innermost block, its value 12 gets lost & hence j in next printf() [3rd printf call] shows j with value 3.
Now check the same example with a little bit change..

Example 5.2
main()
{
 auto int j=1;
 { auto int j=2;
   {
        /* we have just deleted this line */
        { auto int j=4;
          printf(
"\n %d",j);
          j=j*3;
          printf(
"\n %d",j);
        }
       printf(
"\n %d",j);
     }
     printf(
"\n %d",j);
  }
printf(
"\n %d",j);
}
 
Here is the output:
4
12
2
2
1

Explanation:
Remember the following words…”When the control comes out of  a block in which the variable is defined, the variable and its value is irretrievably lost”. Now you start from the innermost block of the above program. The variable j has a value of  4, so 4 is printed on screen. Now j gets 4*3=12,so 12 is printed. Now control comes out of the innermost block, hence its j is lost forever. Now the third  printf() has nowhere to go but the upper level local block where j is defined to have a value of 2. So this 2 gets printed. Next 2 outputs are quite easy to understand.
Now check another example .

Example 5.3
main()
{
  {
    {
      { 
          int j=9;
          printf(
"\n %d",j);

       }
       printf(
"\n %d",j);
     }
     printf(
"\n %d",j);
   }
 printf(
"\n %d",j);
}

Here is the output:
Error: Undefined symbol 'j' in module main().

Explanation:
After the control comes out of innermost block, variable j and its value is lost forever. So following printf()s would search j in their local blocks, but they don’t find any. Because, nowhere j was earlier declared…hence this error message.

Example 5.4
int j=12;
main()
{
  {
    {
      {
          int j=9;
          printf(
"\n %d",j);

       }
       printf(
"\n %d",j);
     }
     printf(
"\n %d",j);
   }
 printf("\n %d
",j);
}

Here is the output:
9
12
12
12

Explanation:
Notice, one j has been globally declared, so any block can access this value when needed.  After control comes out of the innermost block, all of the following printf()s now can access this value and so they print 12 thrice.

I hope, the above tutorial would help to understand C  variables, their declarations & initializations and scopes for Automatic variables.

Download: Fast, Fun, Awesome

No comments: