Chapter 8 - Chapter 8 Chapter Technicalities: Functions,...

Info iconThis preview shows page 1. Sign up to view the full content.

View Full Document Right Arrow Icon
This is the end of the preview. Sign up to access the rest of the document.

Unformatted text preview: Chapter 8 Chapter Technicalities: Functions, etc. Bjarne Stroustrup Bjarne www.stroustrup.com/Programming www.stroustrup.com/Programming Abstract Abstract This lecture and the following present some technical This details of the language to give a slightly broader view of C++’s basic facilities and to provide a more systematic view of those facilities. This also acts as a review of many of the notions presented so far, such as types, functions, and initialization, and provides an opportunity to explore our tool without adding new programming techniques or concepts. programming Stroustrup/Programming 2 Overview Overview Language Technicalities Declarations Functions Definitions Headers and the preprocessor Scope Declarations and definitions Arguments Call by value, reference, and const reference Call const Namespaces “Using” statements Stroustrup/Programming 3 Language technicalities Language Are a necessary evil A programming language is a foreign language When learning a foreign language, you have to look at the grammar and When vocabulary vocabulary We will do this in this chapter and the next We Because: Programs must be precisely and completely specified So we must know the rules A computer is a very stupid (though very fast) machine A computer can’t guess what you “really meant to say” (and shouldn’t try to) Some of them (the C++ standard is 782 pages) However, never forget that What we study is programming Our output is programs/systems A programming language is only a tool Stroustrup/Programming 4 Technicalities Technicalities Don’t spend your time on minor syntax and semantic issues. Don’t There is more than one way to say everything There Most design and programming concepts are universal, or at Most least very widely supported by popular programming languages least Just like in English So what you learn using C++ you can use with many other languages Language technicalities are specific to a given language But many of the technicalities from C++ presented here have obvious But counterparts in C, Java, C#, etc. counterparts Stroustrup/Programming 5 Declarations Declarations A declaration introduces a name into a scope. A declaration also specifies a type for the named object. Sometimes a declaration includes an initializer. A name must be declared before it can be used in a C++ program. Examples: int a = 7; const double cd = 8.7; double sqrt(double); vector<Token> v; // an int variable named ‘a’ is declared // an // a double-precision floating-point constant // double-precision // a function taking a double argument and // // returning a double result // returning // a vector variable of Tokens (variable) Token // Stroustrup/Programming 6 Declarations Declarations Declarations are frequently introduced into a program through Declarations “headers” “headers” A header is a file containing declarations providing an interface to other header parts of a program parts This allows for abstraction – you don’t have to know the details This of a function like cout in order to use it. When you add cout #include "../../std_lib_facilities.h" to your code, the declarations in the file std_lib_facilities.h std_lib_facilities.h become available (including cout etc.). cout etc.). Stroustrup/Programming 7 Definitions Definitions A declaration that (also) fully specifies the entity declared is called a definition declared Examples int a = 7; int b; // an int with the default value (0) // an vector<double> v; // an empty vector of doubles // an double sqrt(double) { … }; // i.e. a function with a body double i.e. struct Point { int x; int y; }; Examples of declarations that are not definitions double sqrt(double); // function body missing // function struct Point; // class members specified elsewhere // class extern int a; // extern means “not definition” extern // “extern” is archaic; we will hardly use it Stroustrup/Programming 8 Declarations and definitions Declarations You can’t define something twice You define A definition says what something is Examples int a; // definition // definition int a; // error: double definition // error: double sqrt(double d) { … } // definition // definition double sqrt(double d) { … } // error: double definition // error: You can declare something twice You declare A declaration says how something can be used int a = 7; // definition (also a declaration) // definition extern int a; // declaration // declaration double sqrt(double); // declaration // declaration double sqrt(double d) { … } // definition (also a declaration) // definition Stroustrup/Programming 9 Why both declarations and definitions? Why To refer to something, we need (only) its declaration Often we want the definition “elsewhere” Later in a file In another file Declarations are used to specify interfaces To your own code To libraries preferably written by someone else Libraries are key: we can’t write all ourselves, and wouldn’t want to In larger programs Place all declarations in header files to ease sharing Stroustrup/Programming 10 Header Files and the Preprocessor Header A header is a file that holds declarations of functions, types, header constants, and other program components. The construct #include "../../std_lib_facilities.h" #include "../../std_lib_facilities.h" is a “preprocessor directive” that adds declarations to your is program program Typically, the header file is simply a text (source code) file A header gives you access to functions, types, etc. that you header want to use in your programs. want Usually, you don’t really care about how they are written. The actual functions, types, etc. are defined in other source code files Often as part of libraries Stroustrup/Programming 11 Source files Source // declarations: token.h: Class Token { … }; Class Token_stream { Token get(); … }; token.cpp: … #include "token.h" //definitions: Token Token_stream::get() { /* … */ } … use.cpp: #include "token.h" … Token t = ts.get(); … A header file (here, token.h) defines an interface between user code header token.h defines and implementation code (usually in a library) and The same #include declarations in both .cpp files (definitions and #include .cpp uses) ease consistency checking uses) Stroustrup/Programming 12 Scope Scope A scope is a region of program text Examples A name in a scope can be seen from within its scope name and within scopes nested within that scope and Global scope (outside any language construct) Class scope (within a class) Local scope (between { … } braces) Statement scope (e.g. in a for-statement) After the declaration of the name (“can't look ahead” rule) A scope keeps “things” local Prevents my variables, functions, etc., from interfering with yours Remember: real programs have many thousands of entities Remember: many Locality is good! Keep names as local as possible Stroustrup/Programming 13 Scope Scope // no r, i, or v here // no or class My_vector { vector<int> v; public: int largest() { int r = 0; for (int i = 0; i<v.size(); ++i) r = max(r,abs(v[i])); max(r,abs(v[i])); // no i here return r; } // no r here // here }; // no v here // here Stroustrup/Programming // v is in class scope // is // largest is in class scope // is // r is local is // i is in statement scope // is 14 Scopes nest Scopes int x; int y; // global variable – avoid those where you can // global // another global variable // another int f() { int x; // local variable (Note – now there are two x’s) // x = 7; // local x, not the global x // not { int x = y; // another local x, initialized by the global y // initialized // (Now there are three x’s) // (Now x++; // increment the local x in this scope // increment } } // avoid such complicated nesting and hiding: keep it simple! // avoid Stroustrup/Programming 15 Functions Functions General form: // a definition // definition void increase_power(int level); void Here, void means “don’t return a value” means A body is a block or a try block // a Formal arguments are often called parameters If you don’t want to return a value give void as the return If void type type return_type name (formal arguments); return_type name ); declaration declaration return_type name (formal arguments) body return_type name body For example double f(int a, double d) { return a*d; } For example { /* code */ } // a block /* code // block try { /* code */ } catch(exception& e) { /* code */ } // a try block try code code // try Functions represent/implement computations/calculations Stroustrup/Programming 16 Functions: Call by Value Functions: // call-by-value (send the function a copy of the argument’s value) // call-by-value int f(int a) { a = a+1; return a; } a: 0 copy the value int main() { 0 xx: int xx = 0; cout << f(xx) << endl; // writes 1 // cout << xx << endl; // writes 0; f() doesn’t change xx cout writes doesn’t int yy = 7; cout << f(yy) << endl; // writes 8; f() doesn’t change yy cout writes doesn’t cout << yy << endl; // writes 7 cout writes } yy: Stroustrup/Programming a: 7 copy the value 7 17 Functions: Call by Reference Functions: // call-by-reference (pass a reference to the argument) // call-by-reference int f(int& a) { a = a+1; return a; } a: 1st call (refer to xx) int main() { xx: 0 int xx = 0; cout << f(xx) << endl; // writes 1 // // f() changed the value of xx // changed cout << xx << endl; // writes 1 cout writes int yy = 7; 2nd call (refer to yy) cout << f(yy) << endl; // writes 8 cout writes // f() changes the value of yy // changes yy: cout << yy << endl; // writes 8 cout writes 7 } Stroustrup/Programming 18 Functions Functions Avoid (non-const) reference arguments when you can They can lead to obscure bugs when you forget which They arguments can be changed arguments int incr1(int a) { return a+1; } void incr2(int& a) { ++a; } int x = 7; x = incr1(x); // pretty obvious // pretty incr2(x); // pretty obscure // pretty So why have reference arguments? Occasionally, they are essential E.g., for changing several values E.g., for For manipulating containers (e.g., vector) e.g., vector) const reference arguments are very often useful Stroustrup/Programming 19 Call by value/by reference/ Call by const-reference void f(int a, int& r, const int& cr) { ++a; ++r; ++cr; } // error: cr is const error: const void g(int a, int& r, const int& cr) { ++a; ++r; int x = cr; ++x; } // ok void ok int main() { int x = 0; int y = 0; int z = 0; g(x,y,z); // x==0; y==1; z==0 // x==0; g(1,2,3); // error: reference argument r needs a variable to refer to // error: needs g(1,y,3); // ok: since cr is const we can pass “a temporary” // const } // const references are very useful for passing large objects // references Stroustrup/Programming 20 References References “reference” is a general concept Not just for call-by-reference r int i = 7; int& r = i; r = 9; // i becomes 9 // becomes cr const int& cr = i; // cr = 7; // error: cr refers to const // error: refers i = 8; cout << cr << endl; // write out the value of i (that’s 8) // 7 You can i: think of a reference as an alternative name for an object You can’t modify an object through a const reference modify const make a reference refer to another object after initialization Stroustrup/Programming 21 Guidance for Passing Variables Guidance Use call-by-value for very small objects Use call-by-const-reference for large objects Return a result rather than modify an object through a reference Return argument argument Use call-by-reference only when you have to For example class Image { /* objects are potentially huge */ }; class objects */ void f(Image i); … f(my_image); // oops: this could be s-l-o-o-o-w void oops: void f(Image& i); … f(my_image); // no copy, but f() can modify my_image void f() my_image void f(const Image&); … f(my_image); // f() won’t mess with my_image void won’t Stroustrup/Programming 22 Namespaces Namespaces Consider this code from two programmers Jack and Jill class Glob { /*…*/ }; */ class Widget { /*…*/ }; // in Jack’s header file jack.h // in // also in jack.h // jack.h class Blob { /*…*/ }; */ class Widget { /*…*/ }; // in Jill’s header file jill.h // in // also in jill.h // jill.h #include "jack.h"; #include "jill.h"; // this is in your code this // so is this so void my_func(Widget p) { // … // } // oops! – error: multiple definitions of Widget oops! Stroustrup/Programming 23 Namespaces Namespaces The compiler will not compile multiple definitions; such clashes The can occur from multiple headers. can One way to prevent this problem is with namespaces: namespace Jack { // in Jack’s header file class Glob{ /*…*/ }; class */ class Widget{ /*…*/ }; class } #include "jack.h"; #include #include "jill.h"; // this is in your code this // so is this so void my_func(Jack::Widget p) // OK, Jack’s Widget class will not OK, { // clash with a different Widget // clash // … // Stroustrup/Programming 24 } Namespaces Namespaces A namespace is a named scope The :: syntax is used to specify which namespace you are using The and which (of many possible) objects of the same name you are referring to referring For example, cout is in namespace std, you could write: For cout std std::cout << "Please enter stuff… \n"; Stroustrup/Programming 25 using Declarations and Directives Declarations To avoid the tedium of std::cout << "Please enter stuff… \n"; std::cout you could write a “using declaration” you or you could write a “using directive” using std::cout; // when I say cout, I mean std::cout” // when cout mean std::cout cout << "Please enter stuff… \n"; // ok: std::cout cout ok: cin >> x; // error: cin not in scope // error: using namespace std; // “make all names from namespace std std available” available” cout << "Please enter stuff… \n"; // ok: std::cout cout ok: cin >> x; // ok: std::cin // ok: More about header files in chapter 12 Stroustrup/Programming 26 Next talk Next More technicalities, mostly related to classes Stroustrup/Programming 27 ...
View Full Document

Ask a homework question - tutors are online