char: variable type which can hold value of single byte.
int: an integer variable type. The size of this variable depends on system, operating system and compiler implementation.C guarantees that int will be at least 16 bits. value of int can be specified in hexadecimal(a leading 0x or 0X means hexadecimal) and octal(leading 0 means octal).
Qualifiers in C are keywords which modify variables or function.They provide extra information on how data should be treated or stored.
short and long: short and long provide different lengths of integers. The actual length will again depend(refer ^928071) with restriction that short will be 16 bits and longs are at least 64 bits.
signed and unsigned: unsigned numbers are always positive. It starts with 0 and always follow the rule of having largest value as 2n−1 where n is number of bits in the type.
// Examples of using qualifiers// The qualifier should precede the type.short int c;// Some qualifiers can be used directly without type.short unsigned int c;
Constants
A long constant will be written with terminal l or L like 12456L. Unsigned integer will be written with terminal u or U. For floats its f or F.
A character constant is an integer written as one character with single quotes like char c = 'O' // the value of c will be 48 i.e its ASCII value. Some character constants are defined with backward slash as its prefix like \n represents newline and \0 represents null character constant.
A string constant or string literal is a sequence of zero or more characters surrounded by double quotes i.e "Hello, World!". Technically, string constant is an array of characters. The string constant always ends with ‘\0’ which is null character.
Fixed size integers
If you do not want the flexibility of size of int to be dependent on system then you can use stdint header to define fixed size int.
#include <stdint.h>int main() { uint32_t i = 12; // defines 32 bit unsigned integer variable int32_t i = 12; // defines 32 bit signed integer variable}
Operators
Bitwise Operators
&: Bitwise AND
|: Bitwise OR
^: Bitwise Exclusive OR
<<: left shift
: right shift
~: one’s complement(unary)
Apart from right shift operator, behaviour of the other operators including left shift operator are consistent with there actual/defined behaviour. Refer Bit-Level Boolean Algebra
In C, right shifting an unsigned quantity is equivalent to logical right shift. For right shifting signed quantity, the right shifting can be logical right shift or arithmetic right shift depending on the system/machine.
For predictable right shifting, only use right shift operators on unsigned quantity.
Relational & Logical Operator
Relational Operators >,>=,<,<=,==,!=
Logical Operator &&, ||
This operators returns numeric value 0 or 1. 0 represents false and 1 represents true in the statements where decisions are expressed like if-else.Using stdbool.h, we can use keywords true and false in the code but they still represents integer value 1 and 0 respectively.
Pointers and Arrays
A pointer is a variable that contains address of a variable. A machine has array of consecutively numbered or addressed memory cells which are manipulated individually or in contiguous groups. Each memory cell will be a byte(Refer Addressing and Byte Ordering. Pointer will occupy two or four memory cells i.e 2-4 bytes.
Syntax for declaring, assigning and dereferencing(get value of the variable pointer is pointing to) pointer
int x = 1;int *p // ip is a pointer pointing to a int variableip = &x; // &x gives address of a variable/objecty = *ip; // y is now 1*ip = 5; // x is now 5 since ip is pointing to x*ip = *ip + 10; // x is now 15y = *ip + 2; // y is now 17++*ip // increments what ip points to i.e x is now 16*ip++ // increment ip to point to next memory cell(*ip)++ // increment what ip points to
Arrays
Array is collection of variable of same type. Arrays must be initialised with concrete length and this does not change in C.
int my_array[5] = {1, 2}; // declaring and intialising array of type int
int a[10] defines an array and when array is initialised to a, a points to address of first element of array. Array name is not a variable unlike pointer, so a cannot be assigned or incremented i.e a = x or a++ are illegal.
a[i] is equal to *(a + i). So does a & &a[0].When array is passed as argument to a function, the address of first element is passed to it. Hence, function accepting an array will define the parameter type as pointer of specific datatype.
int arr_sum(int *s, int len) { int sum = 0; while(len) { sum += *s; s++; } return sum;}int main () { int x[6] = {1,2,3,4,5,6};}
Strings
String is a character array. One significant addition to string is that it will end with \0(called null terminator). So if length of string is defined as 6, it will be 7 due to null terminator.
Syntax
char s[6] = "Hello!";
Void Pointer
A void pointer is a special type of pointer which can point to variable of any type.
void *x;int y = 6;char z = 'T'x = &y;x = &z;
The void pointer cannot be dereferenced directly and arithmetic cannot be performed directly on the pointer. You need to type cast it to dereference it and perform arithmetic on it.
int ab = *(int*)x;int *yz = (int*)x + 1;
void**
Pronounced as void pointer pointer. It is a pointer to void pointer i.e it is pointer pointing to a different pointer which is pointing to variable of any type.
Preprocessor Directives and Macros
Preprocessor directives are commands that start with # and are processed before the compilation of the program. It gives preprocessor instructions to execute. Macros are one of the preprocessor directive which allows us to define constants, functions, code snippets which are replaced with actual code before compilation.
Structures
A structure is a collection of one or more variables of one or more types grouped together under single name for convenient handling.
Syntax for declaring structs in different ways.
Simple declaration of struct
struct System { char *s; int x}struct System s1;s1.s = "Hello";s1.x = 6;struct System s2 = { "Hello2", 8 }; // another way of intialising the struct// another way of intialising a struct and then assiging it a valuestruct System s3;s3 = (struct System){ "Hello3", 64 };struct System s4 = { .s = "Hello3", .x = 64 };
Typedef Declaration(with and without tagged struct)
typedef struct { char *s; int x} Student;Student s1 = { "Hello", 6 };// typedef tagged structtypedef struct Student { char *s; int x;} Student;// can use either code to initialiseStudent s1 = { "Hello", 8 };struct Student s2 = { "Hello", 9 };Student s3;struct Student s3;
Struct can be passed by value and passed by reference to the function. In case of pass by value, a copy of struct is created(if struct is large then it can be memory intensive)
typedef struct { char *name; int age} Student;// pass by valuevoid function x1 (struct Student s) { printf("Name: %s, Age: %d", s.name, s.age);}// pass by referencevoid function x2(struct Student* s) { printf("Name: %s, Age: %d", (s*).name, (s*).age);}
Alternate notation to pointers to structure is provided in C as shorthand
(s*).name // usual pointer syntaxs->name // shorthand// above function x2 can be written asvoid function x2(struct Student* s) { printf("Name: %s, Age: %d", s->name, s->.age);}
malloc and related functions
malloc(n): It allocates contiguous block of memory of size n(bytes) and returns the ptr of first memory address. This memory is usually heap.
free(ptr): It frees the memory allocated by malloc, calloc or realloc.
realloc(ptr, new_size): It resizes memory allocated to ptr to the new_size. If the resizing cannot be accommodated at existing location, it allocates a new block copies the old data to new block and frees the old block.
For internal of mallocs Refer