[go: up one dir, main page]

0% found this document useful (0 votes)
8 views21 pages

CS 10

This document is a lecture on the anatomy of a C++ program, covering topics such as pre-processing, variable scope, and namespaces. It explains the compilation process, including the roles of header files, object files, and the pre-processor. Additionally, it discusses the importance of namespaces in avoiding naming conflicts within the standard library.

Uploaded by

soham.work08
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
8 views21 pages

CS 10

This document is a lecture on the anatomy of a C++ program, covering topics such as pre-processing, variable scope, and namespaces. It explains the compilation process, including the roles of header files, object files, and the pre-processor. Additionally, it discusses the importance of namespaces in avoiding naming conflicts within the standard library.

Uploaded by

soham.work08
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 21

AN INTRODUCTION TO PROGRAMMING

THROUGH C++

with
Manoj Prabhakaran

Lecture 10
Anatomy of a Program
Pre-Processor, Scopes, Namespaces

Based on material developed by Prof. Abhiram G. Ranade


Today
¥ Pre-processing
¥ In particular, header files
¥ Scope of variables
¥ Namespaces
Reference: Chapter 11 (except 11.7)
Compiling a Program

Write Source Code Compile Executable Run


Compiling a Program

Library
Header files Object files

Compile into Object files


Source code Executable
Write Pre-processor Compiler Linker Run

Compilation

¥ Header files typically have the declarations of the functions (and more) in the library
¥ Object files are the binary compiled version of functions
¥ It saves time to have the library functions pre-compiled
Compiling a Program
Compile into Object files
Creating the
Write Library Pre-processor Compiler Library
Header files Object files

Compile into Object files


Source code Executable
Write Pre-processor Compiler Linker Run

Compilation

¥ Header files typically have the declarations of the functions (and more) in the library
¥ Object files are the binary compiled version of functions
¥ It saves time to have the library functions pre-compiled
Pre-Processing Steps
¥ Some text transformations
¥ Line ending with a \ is merged with the following line (example later)
¥ Comments are stripped
¥ Line comments: // comment till end of line
¥ Block comments: /* comment spread
over multiple lines */
¥ #include and other pre-processor directives (coming up) are processed,
line-by-line
¥ Processing one directive can result in the appearance of another
directive. They are processed until no more directives are present.
¥ But same directive is not applied twice (to avoid infinite invocations)
numbers.h #include Demo
int GCD(int, int); // contents of file iostream
int LCM(int, int); // tens of thousands of
// lines ...
bool coprimes(int,int);
bool covers(int w, int x);
int GCD(int, int);
bool PFE(int w, int x);
int LCM(int, int);
int reduce(int w, int x);
bool coprimes(int,int);
main.cpp bool covers(int w, int x);
#include <iostream> bool PFE(int w, int x);
$ g++ -E -P main.cpp
#include "numbers.h" int reduce(int w, int x);

Pre-processor
int main() { int main() {
... ...
} }
iostream Headers Containing Headers
// contents of file iostream
// tens of thousands of
... ¥ Need to be // lines ...
#include <ios> careful to avoid
// has content from files
#include <istream> an infinite cycle // included by iostream
#include <ostream> of inclusions! // and files included in
#include <streambuf> // those files, and so on.
... int main() {
...
main.cpp }

#include <iostream> Pre-processor


int main() {
...
}
Headers Containing Headers

¥ Need to be
careful to avoid
inc.h an infinite cycle
#include "inc.h" of inclusions!

main.cpp
Pre-processor error: #include nested too deeply
#include "inc.h"
int main() {
...
¥ There are pre-processor directives that can
} be used for conditional inclusion: coming up
#define
¥ #define VARIABLE value
makes the pre-processor replace the text VARIABLE with the text value
(when appearing as a ÒtokenÓ Ñ e.g., not inside a string literal)
#define DELTA 1e-6
#define main_program int main()
#define DEBUG_ENABLED

¥ ÒMacrosÓ with parameters can be defined too.

#define CLOSE(x,y) (abs((x)-(y)) <= DELTA)

#define repeat(X) for(int _RPT_i = 0, _RPT_n = X; \


_RPT_i < _RPT_n; ++ _RPT_i )
#ifdef and friends
¥ #ifdef (alt: #if defined) or #ifndef (alt: #if !defined) to conditionally
include code based on whether a macro has been defined
#define DEBUG_ENABLED // value is optional
...
#ifdef DEBUG_ENABLED
#define LOG(x) cerr << x << endl
#else
#define LOG(x) // ignore
#endif
...
LOG("Some problem");
¥ Also: #if expression where expression is an integer constant expression
#if __cpluscplus < 201103 // __cpluscplus gives C++ version
#error Please use -std=c++11 option while compiling // Compilation aborts
#endif
iostream Header Guards
... // including <istream>
#include <istream> // including <ostream> as
// required in <istream>
#include <ostream>
... istream
// remaining contents of
... // istream included
#include <ostream>
... ostream // including <ostream> as
// required in <iostream>
// remaining contents of
// contains definitions of // <iostream> included
// data types, which if
// repeated would result in
// compiler errors! Cannot redeclare same
Stop! variables, data types (structs)
default arguments, etc.!
iostream Header Guards
... // including <istream>
#include <istream> // including <ostream> as
// required in <istream>
#include <ostream>
... istream
// define _LIBCPP_OSTREAM
... // and include contents of
#include <ostream> // ostream
... ostream // remaining contents of
// istream included
#ifndef _LIBCPP_OSTREAM
#define _LIBCPP_OSTREAM // _LIBCPP_OSTREAM is defined
// so #ifndef,,,#endif skipped
// actual contents
... // remaining contents of
// <iostream> included
#endif // _LIBCPP_OSTREAM
Header Guards
inc.txt

#ifndef _INC_DONE
#ifdef _INC_ALMOST_DONE
#define _INC_DONE
#else
#define _INC_ALMOST_DONE
#endif Exercise: Explain how this happens
hello
#include "inc.txt"
bye Testing preprocessor.
#endif Not a valid program.
hello
main.cpp
hello
Testing preprocessor. Pre-processor
bye
Not a valid program.
bye
#include "inc.txt"
Source File after Pre-Processing
¥ After pre-processing a source file has any number of:
¥ Declarations (global variables and functions)
¥ Struct definitions
¥ Function definitions (and templates)
¥ (More later)
¥ A function definition has:
¥ Return type, function name, and parameter list
¥ Followed by statements enclosed in { É }
¥ Different kinds of statements (declaration with or without initialisation,
expression; , conditional statement, conditional loop statement, break,
continue, and return statements, É)
¥ Compiler produces a single object file for each such source file
Scope of Variables
{
¥ In C++, a variable can be used only {
// not visible here (before declaration)
where its declaration is ÒvisibleÓ int x;
// visible here
¥ Visible only within the ÒblockÓ

scope of x
{
// visible here
it is declared in }
// visible here
¥ And only after it is declared }
// not visible here (outside the block)
¥ Scope of a variable: region in }

the code where it is visible


¥ A variable cannot be declared twice within the same block
¥ However can declare a new variable with the same name (but possibly
a different type) in a Òsub-blockÓ
¥ In its scope, the new variable ÒshadowsÓ the old one
Scope of Variables
void f(int x) { { {
... ... {
} } // not visible here (before declaration)
int x;
for(int x=0;;) { while(condition) { // visible here

scope of x
{
... ...
// visible here
} } }

if(condition) { // visible here


}
...
// not visible here (outside the block)
} }
¥ A few different kinds of blocks (more later):
¥ A functionÕs body (including parameter declarations)
¥ A block of statements enclosed in braces
¥ A for loop (including declarations in the initialisation)
¥ A while or do-while statement (condition can have declarations)
¥ If-Else statement (condition can have declarations; visible in both if & else parts)
Scope of Variables Demo

int g; // a global variable. remains visible till the end of the file
...
void f(int x) { // x is visible inside the body of the function
int y; // visible from here till the end of the function
for(int g=x; g<3; gÑ) { // a new local g! visible till
...
... // the end of the for statement.
} // now this g goes out of scope. global g visible again.
{ // start of a new scope
g = x + 1; // this refers to the global g
float g; // this is a different g! global g not visible.
} // now this g goes out of scope. global g visible again.

g++; // global g
} // here x, y go out of scope.
Namespaces
¥ Standard library contains useful functions (swap, max, min, distance,
begin, end, sort, move, É), data types (string, vector, list, É) and global
variables (cout, cin, É), many with common names
¥ But this can be problematic, especially due to function overloading!
¥ Suppose you write a function to_string as follows:
#include <simplecpp>
string to_string(short x) { return x==0 ? "zero" : "non-zero"; }
int main() {
short a = 1; int b = 1;
cout << to_string(a) << " vs. " << to_string(b) << endl;
}
invokes our invokes to_string non-zero vs. 1
to_string from the standard
library!
Namespaces
¥ To keep entities (functions, types, variables) in a library separate from ours
¥ to_string vs. std::to_string
¥ <simplecpp> has a statement using namespace std; which made
all the entities in std namespace available without the qualifier std::
¥ We shall instead use the standard header <iostream>
Risky!

#include <iostream>
std::string to_string(short x) { return x==0 ? "zero" : "non-zero"; }
int main() {
short a = 1; int b = 1;
std::cout << to_string(a) << " vs. " << to_string(b) << std::endl;
}
Invokes our to_string, with b cast into a short.
Only std::to_string invokes the one from the library.
numbers.h Example numbers.cpp
Demo
namespace num { #include "numbers.h"
int GCD(int, int); #include <cmath>

int LCM(int, int); int num::LCM(int a, int b) {

bool coprimes(int,int); return std::abs(a*b)/GCD(a,b); // GCD is num::GCD

bool covers(int w, int x); }


bool num::coprimes(int a, int b) {
bool PFE(int w, int x);
return GCD(a,b) == 1;
int reduce(int w, int x);
}
prog.cpp } ...

#include <iostream>
#include "numbers.h"
using std::cout; using std::cin; using std::endl;
int main() { $ g++ -c prog.cpp # this produces prog.o
cout << "Enter 2 positive numbers: ";
$ g++ -c numbers.cpp # this produces numbers.o
int a, b; cin >> a >> b;
$ g++ prog.o numbers.o # this produces a.out
if (a<=0 || b<=0) return -1;
cout << (num::PFE(a,b) ? "":"Not ") << "PFE" << endl;
cout << "GCD(a,b) = " << num::GCD(a,b) << endl;
}

You might also like