Fundamental data types are the basic data types and all other data types are made from these basic data types
— char
— int
— float
— double
— void
Fundamental data types are further classified on the basis of –
— size
— sign
size of char is fixed 1 byte so it is not classified on the basis of size but On the basis of the sign, char data type is divided into two categories –
1. signed char: Takes both positive and negative value between the defined range.
signed char and char data type both have a similar meaning.
2. unsigned char: Takes the only positive value between the defined range.
See the table for size, range and other details:
Fundamental type | Memory Size | Range(for 32-bit platform) | Format Specifier |
---|---|---|---|
char | 1 byte | -128 to +127 | %c (%d for Numerical output) |
signed char | 1 byte | -128 to +127 | %c (%d for Numerical output) |
unsigned char | 1 byte | 0 to 255 | %c (%u for Numerical output) |
When a variable has data according to its data type-
1 2 3 4 5 6 7 8 9 10 11 12 13 |
#include <stdio.h> int main(void) { // your code goes here char ch_var1 = 65; signed char ch_var2 = 65; unsigned char ch_var3 = 65; printf("ch_var1=%d\n",ch_var1); printf("ch_var2=%d\n",ch_var2); printf("ch_var3=%u\n",ch_var3); return 0; } |
1 2 3 4 |
Output: ch_var1= -65 ch_var2= -65 ch_var3= 65 |
When a variable has data beyond to its range-
1 2 3 4 5 6 7 8 9 10 11 12 13 |
#include <stdio.h> int main(void) { // your code goes here char ch_var1 = -129; signed char ch_var2 = 130; unsigned char ch_var3 = 259; printf("ch_var1=%d\n",ch_var1); printf("ch_var2=%d\n",ch_var2); printf("ch_var3=%u\n",ch_var3); return 0; } |
1 2 3 4 |
Output: ch_var1= any garbage value ch_var2= any garbage value ch_var3= any garbage value |
When a variable has an incorrect data type for its data-
1 2 3 4 5 6 7 8 9 10 11 12 13 |
#include <stdio.h> int main(void) { // your code goes here char ch_var1 = +130; signed char ch_var2 = +130; unsigned char ch_var3 = -128; printf("ch_var1=%d\n",ch_var1); printf("ch_var2=%d\n",ch_var2); printf("ch_var3=%u\n",ch_var3); return 0; } |
1 2 3 4 |
Output: ch_var1= any garbage value ch_var2= any garbage value ch_var3= any garbage value |
int data type is used to declare an integer variable. It is divided into three categories on the basis of size –
— int
— short int
— long int
all the above three have two categories of the data type to store the data with and without a sign. See below table for detail –
Fundamental types | Memory Size | Range(for 32-bit platform) | Format Specifier |
---|---|---|---|
short int | 2 byte | -32768 to 32767 | %d |
signed short int | 2 byte | -32768 to 32767 | %d |
unsigned short int | 2 byte | 0 to 65535 | %u |
int | 4 byte | -2147483648 to 2147483647 | %d |
signed int | 4 byte | -2147483648 to 2147483647 | %d |
unsigned int | 4 byte | 0 to 4294967295 | %u |
long int | 8 byte | -9223372036854775808 to 9223372036854775807 | %ld |
signed long int | 8 byte | -9223372036854775808 to 9223372036854775807 | %ld |
unsigned long int | 8 byte | 0 to 18446744073709551615 | %lu |
Example | Correct/Incorrect | Remark |
---|---|---|
short int i_var=30000; | correct | value In defined range |
short int i_var=-32769; | Incorrect | defined range for short int is -32768 to +32767 |
unsigned short int i_var=-3890; | Incorrect | unsigned is only for positive values |
unsigned int i_var=70000; | correct | value In defined range |
unsigned int i_var=70000; printf("i_var=%d",i_var); | Incorrect | %d is not valid specifier for range >32767 |
int i_var= -70000; printf("i_var=%u",i_var); | Incorrect | %u is not valid for signed value.%d shall use |
see the table for detail :
Fundamental types | Memory Size | Range(for 32-bit platform) | Format Specifier |
---|---|---|---|
float | 4 byte | 1.175494e-38 to 3.402823e+38 | %f or %e(for exponential output) |
double | 8 byte | 2.225074e-308 to 1.797693e+308 | %lf or %le(for exponential output) |
long double | 16 byte | 3.362103e-4932 to 1.189731e+4932 | %Lf or %Le(for exponential output) |
1 2 3 4 5 6 7 8 9 10 11 12 |
#include<stdio.h> int main() { float f_var=37.4567; double d_var=37.4567; long double ld_var=38965.4567; printf("f_var=%f\n",f_var); printf("d_var=%lf\n",d_var); printf("ld_var=%Lf\n",ld_var); return 0; } |
1 2 3 4 5 |
Output: f_var=37.456699 d_var=37.456700 ld_var=38965.456700 |
Note: we can see float has the least precision compare to double and long double.
void is an empty data type and it is used –
— When the function doesn’t return any output
— When the function doesn’t take any input
— In Generic pointer declaration
1 2 3 4 5 6 7 8 9 10 11 12 13 |
#include<stdio.h> int main() { return 0; } or void main() { ; } |
Note: In c99, main has default return data type 0 to avoid the uncertainty of return type.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
#include<stdio.h> void add(int ,int); //prototype int main() { add(4,5); //calling } void add(int x, int y) /*function output data type is void as no return value */ { int result; result =x+y; } |
void add (int x, int y) —–> void before function name add reflects the data type of function’s return value. here function doesn’t return any value so it is void.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
#include<stdio.h> int add(void); //prototype int main() { int result; result= add(); //calling } int add(void) /*function input data type is void as no input value */ { result =4+5; return result; } |
int add(void)- void in function argument because add takes no input while in output it returns integer value so output type is int.
void data type also
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 |
#include <stdio.h> int main() { int *i_ptr; void *v_ptr; int i_var=30; char c_var=78; /*assign i_var to i_ptr*/ i_ptr=&i_var; /*correct assignment because same data type*/ printf("i_ptr=%d\n",*i_ptr); /*assign c_var to i_ptr*/ //i_ptr=&c_var; /*incorrect assignment because poiter data type is different*/ /*assign c_var to v_ptr*/ v_ptr=&c_var; /*correct assignment because poiter data type is void*/ printf("v_ptr=%d\n",*((char *)v_ptr)); /*assign i_var to v_ptr*/ v_ptr=&i_var; /*correct assignment because poiter data type is void*/ printf("v_ptr=%d\n",*((int *)v_ptr)); return 0; } |
1 2 3 4 5 |
Output: i_ptr=30 v_ptr=78 v_ptr=30 |
Note-Before de-referencing of the void pointer, first do typecast with the respective data type pointer.
v_ptr=&i_var;
*v_ptr will not give the stored value you have to go through typecasting like this –
v_ptr ——–typecast with int * as stored data is int type–> (int )v_ptr ———–de–reference—>((int *)v_ptr )