C Vs C++
C++ is an extension of the C language, combining the power and efficiency of C with object-oriented programming (OOP) features. While C is a procedural programming language, C++ supports both procedural and object-oriented paradigms, making it a hybrid language. Understanding their differences is crucial for choosing the right tool for a task.
Key Concept: C++ is often called "C with Classes" because it extends C by adding features like classes, objects, inheritance, polymorphism, and abstraction, which are fundamental to OOP.
| Feature | C | C++ |
|---|---|---|
| Programming Paradigm | Procedural/Structured Programming | Object-Oriented, Procedural, Generic |
| Approach | Top-down approach | Bottom-up approach |
| Data Security | Less secure (data can be accessed globally) | More secure (data hiding via classes/objects) |
| Memory Management | Uses malloc(), calloc(), free() | Uses new and delete operators (also supports C-style) |
| Error Handling | Functions like setjmp() and longjmp() | Exception handling (try, catch, throw) |
| Input/Output | scanf(), printf() | cin, cout (via iostream library) |
| Support | Does not support function overloading, operator overloading, or namespaces | Supports function overloading, operator overloading, and namespaces |
A Simple C++ Program
Let's begin with the classic "Hello, World!" program to understand the basic structure of a C++ program.
#include <iostream> int main() { std::cout << "Hello, World!" << std::endl; return 0; }
Explanation of the Simple C++ Program:
#include <iostream>: This is a preprocessor directive. It tells the compiler to include theiostream(input-output stream) library. This library contains functionalities for performing input and output operations, such as printing text to the console (std::cout) and reading input (std::cin).int main() { ... }: This is the main function where the execution of any C++ program begins. Every C++ program must have amainfunction.intindicates that the function will return an integer value upon completion.main()is the name of the function. Parentheses()mean it takes no arguments in this simple case.- The curly braces
{ }define the body of the function, containing the statements to be executed.
std::cout << "Hello, World!" << std::endl;: This line performs the output operation.std::coutis an object used to display output to the standard output device (usually the console).<<is the insertion operator, used to send data tostd::cout."Hello, World!"is a string literal that will be printed.std::endlis a manipulator that inserts a newline character and flushes the output buffer. It effectively moves the cursor to the next line.
return 0;: This statement indicates that themainfunction has successfully completed its execution. A return value of0conventionally signifies successful program termination.
Compiling & Linking
Before a C++ program can be executed, it needs to be translated from human-readable source code into machine-executable code. This process involves two main stages: compiling and linking.
The Compilation Process:
- Preprocessing: The preprocessor handles directives (like
#include,#define). It expands macros, includes header files, and removes comments. The output is an expanded source file. - Compilation: The compiler translates the preprocessed code into assembly language. This is architecture-specific code that is still human-readable to some extent.
- Assembly: An assembler translates the assembly code into machine code, which is a stream of instructions that the CPU can directly understand. This machine code is stored in an object file (e.g.,
.oor.obj). Object files are not directly executable because they often contain references to external functions or libraries that are not yet resolved.
Linking:
The linker takes one or more object files generated by the compiler/assembler and combines them with necessary library code (e.g., standard libraries like iostream, user-defined libraries) to produce a single, executable program. The linker resolves all symbol references between the different object files and libraries.
Example Command (using g++ compiler):This command compilesg++ myprogram.cpp -o myprogrammyprogram.cppand links it to create an executable file namedmyprogram. If there are multiple source files, e.g.,file1.cppandfile2.cpp:Or compile separately and then link:g++ file1.cpp file2.cpp -o myprogramg++ -c file1.cpp // Compiles to file1.o g++ -c file2.cpp // Compiles to file2.o g++ file1.o file2.o -o myprogram // Links object files
Tokens
Definition: In C++, a token is the smallest individual unit of a program that is meaningful to the compiler. The compiler breaks down a program into these tokens during the initial phase of compilation.
C++ tokens can be broadly classified into six types:
Keywords
These are reserved words that have a predefined meaning and purpose in C++. They cannot be used as identifiers (names for variables, functions, etc.).
- Examples:
int,float,char,if,else,while,for,return,class,public,private,protected,void,const,new,delete.
- Examples:
Identifiers
These are user-defined names given to various program elements such as variables, functions, classes, objects, structures, unions, and namespaces.
- Examples:
myVariable,calculateSum,MyClass,age.
- Examples:
Constants (Literals)
These are fixed values that do not change during program execution. They are raw data assigned to variables or used directly.
- Examples:
10(integer),3.14(floating-point),'A'(character),"Hello"(string),true(boolean).
- Examples:
Strings
A sequence of characters enclosed in double quotation marks. They are treated as constant character arrays.
- Examples:
"Programming","C++ is fun!".
- Examples:
Operators
Symbols that perform specific mathematical, relational, logical, or bitwise operations on operands.
- Examples:
+(addition),-(subtraction),*(multiplication),/(division),%(modulo),=(assignment),==(equality),>(greater than),<(less than),&&(logical AND),||(logical OR).
- Examples:
Special Symbols (Separators/Punctuators)
Symbols that have syntactic or semantic meaning to the compiler, used for structuring code.
- Examples:
{ }(block delimiters),( )(function arguments, grouping),[ ](array indexing),;(statement terminator),,(separator),:(scope resolution, labels),#(preprocessor directive),.(member access),->(pointer to member access).
- Examples:
Identifiers & Constants
Identifiers
Definition: An identifier in C++ is a user-defined name given to a program entity, such as a variable, function, class, or object, to uniquely identify it within the program.
Rules for Naming Identifiers:
- Identifiers must begin with a letter (
a-z,A-Z) or an underscore (_). - After the initial character, identifiers can contain letters, digits (
0-9), or underscores. - Identifiers are case-sensitive. For example,
myVarandmyvarare treated as two different identifiers. - Keywords (reserved words) cannot be used as identifiers.
- No special characters (like
!,@,#,%,^,&,*,-,+) are allowed, except for the underscore. - There is no specific limit on the length of an identifier, but it's good practice to keep them reasonably short and meaningful.
Examples of Valid Identifiers:
scoretotal_amount_userNamevariable123MyFunction
Examples of Invalid Identifiers:
1stNumber(starts with a digit)if(is a keyword)my-variable(contains a hyphen)sum&total(contains an ampersand)
Constants (Literals)
Definition: Constants, also known as literals, are fixed values that are directly embedded into the program's source code. Their values cannot be changed during the execution of the program.
C++ supports various types of constants:
Integer Literals
Whole numbers without a fractional part.
- Decimal:
10,-5,1000 - Octal (prefix
0):012(decimal 10),077 - Hexadecimal (prefix
0xor0X):0xA(decimal 10),0xFF - Suffixes:
Lorlforlong,LLorllforlong long,Uoruforunsigned. (e.g.,100L,200ULL)
- Decimal:
Floating-Point Literals
Numbers with a fractional part, or numbers expressed in exponential form.
- Examples:
3.14,-0.001,2.5e-3(2.5 × 10-3),1.23E+5(1.23 × 105) - Suffixes:
forFforfloat,lorLforlong double(e.g.,3.14f)
- Examples:
Character Literals
A single character enclosed in single quotation marks.
- Examples:
'A','x','5','\n'(newline escape sequence)
- Examples:
String Literals
A sequence of characters enclosed in double quotation marks.
- Examples:
"Hello","C++ Programming"
- Examples:
Boolean Literals
Represent truth values.
- Examples:
true,false
- Examples:
Defining Named Constants (using
constkeyword)The
constkeyword is used to declare variables whose values cannot be changed after initialization. This is the preferred method for creating named constants in modern C++.const int MAX_ATTEMPTS = 3; const double PI = 3.14159; // MAX_ATTEMPTS = 5; // This would result in a compilation error.
Data Types
Definition: A data type specifies the type of data that a variable can hold. It determines the size and layout of the variable's memory, the range of values it can store, and the set of operations that can be applied to it.
C++ data types are categorized into three main types:
Built-in (Fundamental) Data Types
These are basic data types provided by the language itself.
int: Used to store whole numbers (integers).- Size: Typically 4 bytes (can vary based on system architecture).
- Range: Approx. -2 × 109 to 2 × 109.
char: Used to store single characters or small integers.- Size: 1 byte.
- Range: -128 to 127 or 0 to 255 (depending on signed/unsigned).
float: Used to store single-precision floating-point numbers (numbers with decimal points).- Size: Typically 4 bytes.
- Precision: Approx. 7 decimal digits.
double: Used to store double-precision floating-point numbers. Offers more precision thanfloat.- Size: Typically 8 bytes.
- Precision: Approx. 15 decimal digits.
bool: Used to store boolean values (trueorfalse).- Size: 1 byte (can be optimized to less).
- Values:
true(usually 1),false(usually 0).
void: An incomplete type meaning "no type" or "absence of type". It is used in specific contexts, such as function return type when no value is returned, or as a generic pointer (void*).wchar_t: Wide character type, used for characters that require more storage than a typicalchar(e.g., Unicode characters).
Data Type Modifiers: These keywords can alter the range and/or size of fundamental data types.
signed: Can store both positive and negative values (default forint,char).unsigned: Can store only non-negative (zero or positive) values. Doubles the positive range.short: Guarantees at least 2 bytes (forint).long: Guarantees at least 4 bytes (forint) or 8 bytes (fordouble).
Common Combinations:
short int(or simplyshort)long int(or simplylong)long long int(or simplylong long)unsigned intunsigned charlong double
Derived Data Types
These data types are built upon or derived from fundamental data types.
- Arrays: A collection of elements of the same data type stored at contiguous memory locations.
- Pointers: Variables that store memory addresses of other variables.
- References: Aliases to existing variables (discussed in the next section).
- Functions: Blocks of code designed to perform a specific task.
User-Defined Data Types
These data types are created by the programmer.
- Classes: Blueprints for creating objects, encapsulating data and functions.
- Structures (
struct): Similar to classes but members are public by default. - Unions (
union): Allow different data types to share the same memory location. - Enumerations (
enum): Assign names to integer constants, making code more readable.
Reference Variables
Definition: A reference variable in C++ is an alias (an alternative name) for an already existing variable. It provides another way to access the same memory location as the original variable. Once a reference is initialized to a variable, it cannot be reseated to refer to another variable.
Declaring and Initializing Reference Variables:
References are declared using the ampersand symbol (&) after the type, and they must be initialized at the time of declaration with an existing variable.
int originalVar = 10; int &refVar = originalVar; // refVar is now an alias for originalVar // You cannot do this: // int &anotherRef; // Error: references must be initialized // int yetAnotherVar = 20; // refVar = yetAnotherVar; // This assigns the VALUE of yetAnotherVar to originalVar, not reseating refVar
Key Characteristics of Reference Variables:
- Alias: A reference is simply another name for an existing variable. Any operation performed on the reference variable is actually performed on the original variable.
- Initialization is Mandatory: A reference must be initialized when it is declared. It cannot be declared without being bound to a variable.
- Cannot be Reseated: Once a reference is initialized to an object, it cannot be changed to refer to another object. It will always refer to the object it was initially bound to. (Attempting to assign a different variable to a reference will assign the *value* of that variable to the original variable the reference points to).
- No Null References: A reference cannot be null. It must always refer to a valid memory location.
- No Address-of Operator on References: You cannot take the address of a reference variable using
&to get the address of the reference itself; instead,&refVargives the address of the original variable.
Example Usage:
int score = 100; int &playerScore = score; // playerScore is now an alias for score std::cout << "Original score: " << score << std::endl; // Output: 100 std::cout << "Reference score: " << playerScore << std::endl; // Output: 100 playerScore = 150; // Changing playerScore also changes score std::cout << "Updated original score: " << score << std::endl; // Output: 150 std::cout << "Updated reference score: " << playerScore << std::endl; // Output: 150 std::cout << "Address of score: " << &score << std::endl; std::cout << "Address of playerScore: " << &playerScore << std::endl; // Notice that both addresses will be the same, confirming they refer to the same memory location.
Difference from Pointers:
While references provide indirect access to variables like pointers, they have key distinctions:
- Syntax: References use
&, pointers use*. - Initialization: References must be initialized; pointers can be declared without initialization (but should be initialized to
nullptror a valid address to avoid undefined behavior). - Reseating: References cannot be reseated; pointers can be made to point to different variables.
- Null Value: References cannot be null; pointers can be null.
- Dereferencing: References are used directly (like the original variable); pointers require dereferencing (
*ptr) to access the value they point to. - Memory: Compilers might implement references using addresses internally, but from a programmer's perspective, references directly access the variable without needing a separate memory address variable.