C/C++ Concepts
Setup
To start working with C/C++ you need to install few application in your system, such as IDE's or Text Editors, Compilers etc.
You can use any IDE or Text editor, some of the are listed below:
For Windows (uses MinGW Compiler):
- Vim: Text editor or Neovim: Vim-based text editor
- Visual Studio
- Visual Studio Code: Text editor
- Code::Blocks
- Dev-Cpp: Download the with Mingw/GCC version so that compiler will also be included
Dev-Cpp Setup:
Make the below changes in Tools --> Compiler Options:
In the Compiler section, tick mark Add the following commands when calling compiler: and add
-g
in the text available below. This helps while debugging the codeNow, in Programs section, append
-std=c++99
to gcc: and g++: likegcc.exe -std=c++11
andg++.exe -std=c++11
. To use the C++ 11 standards (by default it will be set to latest)
Types and objects
A type defines a set of possible values and a set of operations (for an object).
An object is some memory that holds a value of a given type.
A value is a set of bits in memory interpreted according to a type.
A variable is a named object.
A declaration is a statement that introduces an identifier (name) and describes its type, be it a type, object or function. The compiler uses this to reference that identifier and dose not set aside any memory for it.
cppextern int bar; extern int g(int, int); double f(int, double); // extern can be omitted for function declarations class foo; // no extern allowed for type declarations double f(int, double); // in C/C++ an identifier can be declared as often as you want double f(int, double); extern double f(int, double); // the same as the two above extern double f(int, double);
A definition actually instantiates/implements the identifier, the compiler asks memory manager to set aside memory for that object or function. You can only define exactly once.
cppint bar; int g(int lhs, int rhs) {return lhs*rhs;} double f(int i, double d) {return i+d;} class foo {};
NOTE
If something is declared but not defined, then the linker doesn't know what to link references to and complains about a missing symbols. If you define something more than once, then the linker doesn't know which of the definitions to link references to and complains about duplicated symbols.
Operations on data types:
Struct (Structure)
Definition: It's a physically grouped list of dissimilar data items under one name in a block of memory, allowing the different data items to be accessed via a single pointer. It's used for defining user-defined data types, apart from the primitive data types.
- Group of related data items
struct
is the keyword used to define a structure..
(dot operator) is used to access the members of the structure- Its size will the sum of sizes consumed by all of its elements
- Structure Padding is used to allocate memory for a structure
Example: Define a struct
called Rectangle
// DEFINITION
struct Rectangle
{
int length;
int breadth;
} r1, r2; // GLOBAL STRUCT VARIABLES
int main()
{
// DECLARATION (MEMORY IS ALLOCATED)
struct Rectangle r;
struct Rectangle r1={10,5};
// INITIALISATION
r.length=25;
printf("Area of the Rectangle is %d", r.length * r.breadth);
}
struct Card
{
int face;
int shape;
int color;
};
int main()
{
struct Card deck[52]={{1,0,0}, {0,0,1}, .... };
deck[0].face=2;
}
In C++:
int main()
{
Rectangle r; // IN C++ NO NEED TO PROVIDE struct KEYWORK
struct Rectangle r1={10,5};
}
NOTE
C structs do not have member functions. C++ allows struct to have member functions and by default all members are public as compared to class where by default all members are private.
Pointers
Definition: Pointer is an address variable that is meant for storing the address of another variable.
- The size of a pointer will always be equal to size the of its type.
Pointers are used for:
Accessing heap memory. The program will not automatically access the heap. Heap memory is external to the program.
Accessing resources, such as files, keyboard, monitor, etc.:
- Like access files, files are stored in hard disks and are external to the program. File pointers are used to access these files.
- Similarly to interact with any external device we use the pointer.
Functions use Pointers as parameters while using call by reference method.
Example:
int main()
{
// data variable
int a=10;
// pointer variable
int *p;
// save address of `a`
p=&a;
// print data present in `a`
printf("%d", a);
printf("%d", *p); // also know as dereferencing
}
Array variable actually points to the first element of the array:
int main()
{
int A[5]={2,4,6,8,10};
int *p;
// A ITSELF POINTS TO THE FIRST ELEMENT OF THE ARRAY
p=A;
printf("%d", *p); // 2
printf("%d", *A); // 2
}
NOTE
Pointers consume the same amount of memory (8 bit) irrespective of the type of pointer
Accessing heap memory:
- In C
malloc
is used to get memory in heap. Its present in<stdlib.h>
and takes size as a parameter. malloc
returns avoid
pointer (generic pointer), so we have to type-caste it and say it's aninteger
pointer.- We need to free the memory allocated to the variables after they are no more required using
free()
in C anddelete
in C++ - Heap memory must be de-allocated
Example:
// REQUIRED FOR malloc
#include<stdlib.h>
int main()
{
int *p;
p=(int *)malloc(5 * sizeof(int));
// TYPE-CASTE AS malloc RETURNS A void POINTER, malloc WILL NOW PROVIDE MEMORY FOR
// AN ARRAY OF LENGTH 5 AND EACH ELEMENT OF SIZE INT
free(p); // CLEARING MEMORY ALLOCATED TO p
}
In C++:
int main()
{
int *p;
p=new int[5]; // SIMILAR TO USING malloc
delete [] p; // CLEARING MEMORY ALLOCATED TO p
// ADD EMPTY [] AS p IS POINTING TO AN ARRAY
}
Pointer to a Structure:
Example:
struct Rectangle
{
int length;
int breadth;
};
int main()
{
struct Rectangle r={10,5};
struct Rectangle *p=&r;
r.length=15;
(*p).breadth=25; // *p IS ENCLOSED INSIDE A BRACKET BECAUSE `.` HAS HIGHER PRIORITY THAN `*`
p->length=25; // ALTERNATIVE METHOD
printf("%d %d\n", r.length, r.breadth); // 25 25
printf("%d %d\n", (*p).length, (*p).breadth); // 25 25
printf("%d %d\n", p->length, p->breadth); // 25 25
}
Dynamic allocation of Pointer (in heap memory):
Example:
// struct FROM THE ABOVE EXAMPLE
int main()
{
struct Rectangle *p;
p=(struct Rectangle *)malloc(sizeof(struct Rectangle));
p->length=22;
p->breadth=10;
}
Void Pointer: Type-less memory
cint main() { int a=4; int *pA = &a; printf("%d\n", *pA); void *vA = &a; printf("%d\n", *vA); // Error }
Reference
Definition: An alias given to a variable
- Must be initialized during declaration
- While referencing both the variable and its reference have the same address
Example:
int main()
{
int a=10;
int &r=a;
// r IS REFERRING TO a
cout<<a; // 10
r++;
cout<<r; // 11
cout<<a; // 11
}
NOTE
Reference is not a part of the C language.
Functions
Definition: A function is a named sequence of statements. A function can return a result (also called a return value).
Also called subroutine, modules, procedures
Example:
// ADDITION FUNCTION
int add(int a, int b) // THIS LINE IS KNOWN AS THE PROTOTYPE OR SIGNATURE OF THE FUNCTION
{
// DECLARATION AND DEFINITION OF THE FUNCTION
int c;
// int a AND b ARE KNOWN AS FORMAL PARAMETERS
c = a + b;
return(c);
}
// MAIN FUNCTION
int main()
{
int x, y, z;
x = 10;
y = 5;
// INVOCATION OF THE FUNCTION
y = add(x, y); // HERE int z AND x ARE KNOWN AS ACTUAL PARAMETERS
printf("Sum is %d", y);
}
Parameter Passing
There are three ways of passing the parameters to a function.
Pass/Call by Value: In pass by value, changes in formal parameters do not reflect in the actual parameters. Refer to the above examples.
Pass/Call by Address: In pass by address, changes in formal parameters reflect in actual parameters.
Example:
cvoid swap(int *x, int *y) // TO USE VARIABLE ADDRESS, DEFINE POINTERS { int temp; temp=*x; *x=*y; *y=temp; } int main() { int a; int b; swap(&a, &b); // PASS THE VARIABLE ADDRESS NOT THE VALUE printf("A == %d, B == %d", a, b); }
Pass/Call by Reference: In pass by reference also, changes in formal parameters reflect in actual parameters. Present only in C++.
Example:
cppvoid swap(int &x, int &y) // USING & WE REFERENCE THE VARIABLES a AND b { int temp; temp=*x; *x=*y; *y=temp; } int main() { int a; int b; swap(a, b); // NO CHANGES printf("A == %d, B == %d", a, b); }
NOTE
Pass by Reference should be used very carefully as it converts the modular code into monolithic code.
Arrays as Parameters:
Arrays cannot be passed by value, they are passed by address.
Example:
cvoid fun(int A[], int n) // HERE A[] IS A POINTER TO AN ARRAY, int *A IS THE SAME AS int A[] { int i; for(i=0; i<n; i++) { printf("%d", A[i]); } } int main() { int A[5] = {1,2,3,4,5}; fun(A, 5); }
Function that returns a Pointer:
Example:
cint [] fun(int n) { int *p; p = (int *)malloc(n * sizeof(int)); return(p); } int main() { int *A; A = fun(5); }
Structure as parameter:
Pass/Call by Value:
Example:
cstruct Rectangle { int length; int breadth; } int area(struct Rectangle r1) { return r1.length * r1.breath; } int main() { struct Rectangle r = {1, 2}; printf("Area of the Rectangle is %d", area(r)); }
Pass/Call by Address:
Example:
cstruct Rectangle { int length; int breadth; } int changeLength(struct Rectangle *p, int l) { p->length = l; } int main() { struct Rectangle r = {1, 2}; changeLength(&r, 20); }
NOTE
Even when a struct
has an array member, it can be passed by value even though array alone cannot be passed by value.
WARNING
- Confirm if true or false: C does not have any built-in data structures.
- As part of the code activation record of the function, all the variables are created in the stack.
Structure of the Code
Similarly in C++, OOP's concepts are used to organize the code.
All the variables and functions related to them are grouped together as a class.
Example:
cppclass Rectangle { int length; int breadth; public: // INSTEAD OF INITIALIZE FUNCTION WE USE A constructor FOR INITIALIZATION Rectangle(int l, int b) { length = l; breadth = b; } int area() { return length * breadth; } void changeLength(int l) { length = l; } }; int main() { Rectangle r(10, 5); cout << "Area of the Rectangle is " << r.area() << endl; r.changeLength(20); cout << "Area of the Rectangle is " << r.area() << endl; return 0; }
Example:
cpp#include<iostream> // .h DEPENDS ON COMPILER (CHECK) using namespace std; // IF ONLY iostream IS USED class Rectangle { private: int length; int breadth; public: // DEFAULT CONSTRUCTOR Rectangle() { length = 1; breadth = 1; } // PARAMETERIZED CONSTRUCT (USING CONSTRUCTOR OVERLOADING) Rectangle(int l, int b); // PROTOTYPE OR SIGNATURE OF THE FUNCTION // BELOW TWO FUNCTIONS ARE FACILITATORS WHICH PERFORM SOME // OPERATIONS ON DATA MEMBERS int area(); int perimeter(); // THIS IS accessor/getter (get()) FUNCTION int getLength() { return length; } // THIS IS mutator/setter (set()) FUNCTION void setLength(int l) { length = l; } // DESTRUCTOR (CALL WHENEVER DYNAMIC MEMORY IS ALLOCATED BY THE CLASS) ~Rectangle(); }; Rectangle::Rectangle(int l, int b) { length = l; breadth = b; } int Rectangle::area() { return length * breadth; } int Rectangle::perimeter() { return 2 * (length + breadth); } Rectangle::~Rectangle() { // FREE THE DYNAMICALLY ALLOCATED MEMORY } int main() { Rectangle r(10, 5); cout<<r.area(); cout<<r.perimeter(); r.setLength(20); cout<<r.getLength(); // NOW DESTRUCTOR WILL AUTOMATICALLY CALLED // WHEN THE OBJECT GOES OUTSIDE THE SCOPE }
C++ program supports generic (template) functions and generic(template) classes.
cpptemplate <class T> class Arithmetic { private: T a; T b; public: Arithmetic(T a, T b); T add(); T sub(); }; template <class T> Arithmetic<T>::Arithmetic(T a, T b) { // THIS REFERS TO CLASS MEMBER VARIABLES NOT THE FUNCTION VARIABLES this->a = a; this->b = b; } template <class T> T Arithmetic<T>::add() { T c; c = a + b; return c; } template <class T> T Arithmetic<T>::sub() { T c; c = a - b; return c; } int main() { Arithmetic<int> ar(10, 5); cout<<ar.add(); Arithmetic<double> ar1(1.5, 2.3); cout<<ar1.add(); }