190 likes | 340 Views
PHYS707: Special Topics. C++ Lectures. Lecture 3. Summary of Today’s lecture:. Functions (call-by-referencing) Arrays Pointers More Arrays! More pointers!. But First: Namespaces. Typical program: #include< iostream > using namespace std ; int main() { [program goes here]
E N D
PHYS707: Special Topics C++ Lectures Lecture 3
Summary of Today’s lecture: Functions (call-by-referencing) Arrays Pointers More Arrays! More pointers!
But First: Namespaces Typical program: #include<iostream> using namespace std; int main() { [program goes here] return 0; } The "#include<…>" just includes a library of routines, but what the heck is that "using" stuff??
A "namespace" is where definitions of names are kept. "std" is the name of a particular namespace. In there, for example, are kept the names cin and cout. If you don't want to use "using namespace std;" you can still use the names it contains, including cin and cout: std::cout << "this is a sample output\n"; std::cin >> x; // this is a sample input Note the syntax: namespace_name::name_in_that_namespace (If you look on the web, you'll often see sample programs that do this instead of using the std namespace.) Q: Why NOT use "using namespace std;"? A: What if you want to use your own definition of cout (or some other defined name)?? Q: Can I create my own namespace? A: Yes!! Here's an example from the text:
#include<iostream> using namespace std; // this namespace is used "globally" namespace savitch1 { void greeting(); } namespace savitch2 { void greeting(); // note: function has same name in both namespaces!! } void big_greeting(); int main() { { using namespace savitch2; // only valid within this "block" greeting(); } { using namespace savitch1; // only valid within this "block" greeting(); } big_greeting(); return 0; }
namespace savitch1 { void greeting() { cout << "Hello from namespace savitch1.\n"; } } namespace savitch2 { void greeting() { cout << "Greetings from namespace savitch2.\n" } } void big_greeting() { cout << "A Big Global Hello!\n"; } Output when program is executed: Greetings from namespace savitch2. Hello from namespace savitch1. A Big Global Hello!
Functions, Part 2 Passing arguments by reference: #include<iostream> using namespace std; void get_numbers (int& input1, int& input2); // reads two integers from keyboard int main() { get_numbers(first_num, second_num); cout << first_num << " " << second_num << endl; return 0; } void get_numbers(int& input1, int& input2) { cout << "input 2 integers\n"; cin >> input1 >> input 2; } Note the “&” Note the “&” Note: No “&”!
NOTE: • Values of input1 and input2 change! • Use call-by-reference when you want the value of the argument to change • Use call-by-reference when passing dynamic arrays or pointers* • Can your function modify a parameter and return a value? SURE!! • Can a function have some parameters call-by-position and others call-by-reference? SURE!! • Can a function call another function? SURE!! But the function declaration MUST precede the function use. * But just a tad different format
Overloading Functions C++ is really smart! Can use the same name for related (but different) functions: double avg(double n1, double n2) { return (n1+n2)/2.0; } double avg(double n1, double n2, double n3) { return (n1+n2+n3)/3.0; } #include<iostream> using namespace std; double avg(double n1, double n2); // averages 2 numbers double avg(double n1, double n2, double n3); // averages 3 numbers int main() { cout << avg(1.0,2.0) << endl; cout << avg(1.0,2.0,3.0) << endl; return 0; }
Arrays Declaring 1-D arrays: int score[5]; double mydata[25]; This is legal: constintmaxdim = 5; double data[maxdim]; This is NOT: intmaxdim = 5; double data[maxdim]; Using the array: for(i = 0; i < maxdim; i++) { data[i] = 2*i+4; } Warning: data[maxdim] = 3; // wrong!!
Arrays in Functions double fct(double a[], intnumdim); int main() { [some code] x = fct(a, 5); // Note: no array brackets when calling the fct! } double fct(double z[], int dim) { double sum = 0; for(int i = 0, i < dim; i++) { sum += z[i]; } return sum; } Too bad: we have to know how big an array we need at the time we write the program
Multi-Dimensional Arrays Correct: int a[3][4]; double c[4][12][2]; Wrong! int a[3,4]; double c(4,12,2);
Pointers • A pointer variable “points to” (contains) the address of a variable • When you declare a pointer variable, its “type” should be the same asthe type of the variable that the pointer points to. int *p1, *p2, v1, v2; // p1 and p2 are pointers to integers. v1 and v2 are just integers. p1 = &v1; /* p1 now contains the address of v1 “&” means “give the address of the variable that follows”*/ Consider this code fragment: v1 = 0; p1 = &v1; *p1 = 42; cout << v1 << endl; cout << *p1 << endl; This gives: 42 42 Try it!!
Variables?! We don’t need no stinkin’ variables!! int *p1 // declare pointer variable p1 = new int; // a new “nameless” variable is now pointed to by p1!! cin >> *p1; // put a value into the nameless variable pointed to by p1 *p1 = *p1 + 7; // add 7 to the nameless variable’s value cout << *p1 // the output is what you input, plus 7!! delete p; // frees up that memory location again (Important!!) • The type of the nameless variable must match the type spec’d for the pointer • We do this ALOT in C++ • Good to free up the memory pointed to by p. (Memory returned to the “freestore” or “heap”) • But don’t “kill” that spot until you’re done with it! If another pointer is pointing to that location and you delete p1, than the second pointer is left pointing to some random spot in memory!! (You told the computer you were done reserving that spot. It gave the spot away to some other needy customer.)
Dynamic Arrays It’s very inconvenient to have to know your array size at the time you write your program. Wouldn’t it be nice to let the array fit your needs at runtime? int main() { double *mydata; intarray_size; cout << “How many data points do you have?\n”; cin >> array_size; mydata = new double [array_size]; for ( i = 0; i < array_size; i++) { mydata[i] = 2.0*double(i) +3.0; // Use just like any other array } [more code goes here…] delete [] mydata; // note the brackets!! return 0; } But why don’t I need the “*”???
Because an ordinary array variable is just a pointer!! // program to show an array variable is a pointer #include<iostream> using namespace std; int main() { int *p, a[10], index; for (index = 0; index < 10; index++) a[index] = index; p= a; for (index = 0; index < 10; index++) cout << p[index] << “ “; cout << endl; for (index = 0; index < 10; index++) p[index] = p[index]+1; // changes to p => changes to a! for (index = 0; index < 10; index++) cout << a[index] << “ “; cout << endl; return 0; } Output: 0 1 2 3 4 5 6 7 8 9 1 2 3 4 5 6 7 8 9 10 Since an array variable is a pointer, you treat it like one -- and, if your pointer points to an array, treat your pointer variable like an array variable!
Pointer Arithmetic double *d; intarraysize = 10; d = new double[array_size]; [ put some value into the array…] for (i = 0; i < array_size; i++) cout << *(d + i) << “ “; for (i = 0; i < array_size; i++) cout << d[i] << “ “; d now contains the address of d[0]; d+1 points to d[1], etc. Output the contents of the memory at locations d+i using “normal” pointer notation This does the same thing! • Can do addition and subtraction (with integers only); NO mult or div! (Why would you??) • Can also subtract two pointers to the same variable. This gives the number of indexed variables between the two. • C++ is smart: it figures out the number of variable spots, not bytes, between two pointers!
Passing Pointers as Function Arguments #include<iostream> using namespace std; void swap(double *a, double *b); // function just swaps values of the 2 inputs int main() { double *a, *b; a = new double; b = new double; *a = 5.0; *b = 10.0; cout << *a << “ “ << *b << endl; swap(a, b); cout << *a << “ “ << *b << endl; return 0; } void swap(double *a, double *b) { double tmp; tmp = *a; *a = *b; *b = tmp; } Function declaration Note the “*” Function call No “*” (just like array) Function definition Note the “*”
Homework! Write (and test) a function that takes 3 arguments: R, Area, and Circumference. When you call the function, you’ve only defined R, but when the function is executed, Area and Circumference now contain the area and circumference of a circle of radius R. Write a program that asks you for the number of inputs you want to give it. Then have it ask you for those N inputs. Now call a function that returns the average of those N inputs. [Hint: put the inputs into an array, then pass that array to a function that takes the average of the array’s elements.]