Data Types:
Basic data types:
• char, signed char, unsigned char
• short, unsigned short
• int, unsigned int
• long, unsigned long
• float, double, void
• struct tag, union tag, enum tag
• long long, unsigned long long, long double
• char, signed char, unsigned char
• short, unsigned short
• int, unsigned int
• long, unsigned long
• float, double, void
• struct tag, union tag, enum tag
• long long, unsigned long long, long double
derived types :
• * pointer to
• [] array of
• () function returning
Points needs to remember...
1. Enum declaration - enum [<tag_name>]{<enum_constanat_name> [=<integer_ value>],
…
} [<var_name>,…]
- Enum is primitive data type
- Nesting of enum constant is not possible in c.
2. Signed is higher data type than unsigned int
Ex: signed x;
x = 10 +- 10u + 10u +- 10;
= 10 + (-10u) + 10u -10 (unsigned value also becomes sign value).
= 10 -10 +10-10
= 0
Note : Lower data type operand always automatically typecast into the operand of higher data type before performing the operation and result will be higher data type.
3. In c char is integral data type. It stores the ASCII value of any character constant.
4. volatile int a=11;
printf("%d",a);
Here output will be cannot be predict
Note: We cannot predict the value of volatile variable because its value can be changed by any microprocessor interrupt.
5. Cannot specify two storage class in variables declaration
Ex: auto and register in the declaration of any variable.
unsigned auto long register i=10;
6.Cannot use signed or unsigned modifiers with float data type. In c float data type by default signed and it cannot be unsigned.
7. "void" type can be used only for "pointers to", "function returns" and function arguments if it has no argument. but not for variables or arrays declarations...
Ex: void a ; // wrong declaration
void *a; // correct
void a[10]; //wrong
Operators Precedence:
Working your way out from the variable name, honor the precedence rules and consume derived-type tokens to the right as far as possible without bumping into a grouping parentheses. Then go left to the matching parenthesis.
Example:
We'll approach this systematically, focusing on just one or two small part as we develop the description in English. how to read each declaration focus of our attention in red.
Example 1:
> long **foo [7];
Start with the variable name and end with the basic type:
foo is ... long
> long ** foo[7];
At this point, the variable name is touching two derived types: "array of 7" and "pointer to", and the rule is to go right when you can, so in this case we consume the "array of 7"
foo is array of 7 ... long
> long ** foo[7];
Now we've gone as far right as possible, so the innermost part is only touching the "pointer to" - consume it.
foo is array of 7 pointer to ... long
> long * *foo[7];
The innermost part is now only touching a "pointer to", so consume it also.
foo is array of 7 pointer to pointer to long
- Example 2:
- To really test our skills, we'll try a very complex declaration that very well may never appear in real life (indeed: we're hard-pressed to think of how this could actually be used). But it shows that the rules scale to very complex declarations.
- > char *(*(**foo [][8])())[];
- All declaration start out this way: "variable name is .... basic type"
- foo is ... char
- > char *(*(**foo[] [8])())[];
- The innermost part touches "array of" and "pointer to" - go right.
- foo is array of ... char
- > char *(*(**foo[][8])())[];
- It's common in a declaration to alternate right and left, but this is not the rule: the rule is to go as far right as we can, and here we find that the innermost part still touches "array of" and "pointer to". Again, go right.
- foo is array of array of 8 ... char
- > char *(*(** foo[][8])())[];
- Now we've hit parenthesis used for grouping, and this halts our march to the right. So we have to backtrack to collect all the parts to the left (but only as far as the paren). This consumes the "pointer to":
- foo is array of array of 8 pointer to ... char
- > char *(*(* *foo[][8])())[];
- Again we are backtracking to the left, so we consume the next "pointer to":
- foo is array of array of 8 pointer to pointer to ... char
- > char *(*(**foo[][8])())[];
- After consuming the "pointer to" in the previous step, this finished off the entire parenthesized subexpression, so we "consume" the parens too. This leaves the innermost part touching "function returning" on the right, and "pointer to" on the left - go right:
- foo is array of array of 8 pointer to pointer to function returning ... char
- > char *(* (**foo[][8])() )[];
- Again we hit grouping parenthesis, so backtrack to the left:
- foo is array of array of 8 pointer to pointer to function returning pointer to ... char
- > char * (*(**foo[][8])())[];
- Consuming the grouping parentheses, we then find that the innermost part is touching "array of" on the right, and "pointer to" on the left. Go right:
- foo is array of array of 8 pointer to pointer to function returning pointer to array of ... char
- > char * (*(**foo[][8])())[];
- Finally we're left with only "pointer to" on the left: consume it to finish the declaration.
- foo is array of array of 8 pointer to pointer to function returning pointer to array of pointer to char
p = p1; //Error should not change the address
*p++ = 'u'; //allowed value at the location changed
*p1++ = 'u'; //not allowed to change value
p1 = p; // allowed address can be changed but value cannot be changed.