In the sequel we present some short C++ programs to demonstrate the use of pointers in C++. You should not spend more than a few minutes on this part of the TD.
For each one of the following programs, predict the output of the program, then compile the code and test it to check your prediction.
#include <iostream> int main() { int x = 10; int *ptr = &x; int *ptr1 = ptr; std::cout << "x = " << x << std::endl; std::cout << "&x = " << &x << std::endl; std::cout << "ptr =" << ptr << std::endl; std::cout << "*ptr =" << *ptr << std::endl; std::cout << "ptr1 =" << ptr1 << std::endl; std::cout << "*ptr1 =" << *ptr1 << std::endl; std::cout << "&*ptr1 =" << &*ptr1 << std::endl; return 0; }
#include <iostream> void swap(char * &str1, char * &str2) { char *temp = str1; str1 = str2; str2 = temp; } int main() { char *str1 = "INF442"; char *str2 = "TD2"; std::cout << "str1 is "<< str1 << std::endl; std::cout << "str2 is "<< str2 << std::endl; swap(str1, str2); std::cout << "str1 is "<< str1 << std::endl; std::cout << "str2 is "<< str2 << std::endl; return 0; }
Replace the second line of the program with: void swap(char * str1, char * str2). What it is the effect of this change?
#include <iostream> int main () { int numbers[5]; int *p; p = numbers; *p = 10; p++; *p = 20; p = &numbers[2]; *p = 30; p = numbers + 3; *p = 40; p = numbers; *(p+4) = 50; std::cout << numbers[0]; for (int n = 1; n < 5; n++) { std::cout << ", " << numbers[n]; } std::cout << std::endl; return 0; }
#include <iostream> void array(int c, char *tabArg[]) { // Declare and initialise an array int val[3] = { 10, 20, 30 }; // Declare a pointer variable int *ptr; // Assign the address of val[0] to ptr // We could equivalently use ptr=&val[0]; ptr = val; std::cout << "In function array: Elements of the array val[] are: "<< std::endl; std::cout << ptr[0] << " " << ptr[1] << " " << ptr[2]<< std::endl; std::cout << " "<< std::endl; std::cout << "In function array: Elements of the array argv[] : "<< std::endl; for (int i=0; i < c; i++){ std::cout << " " << tabArg[i] << " " ; } std::cout << " "<< std::endl; } //Driver program int main(int argc, char *argv[]) { std::cout << "In Main: argc = "<< argc << std::endl; std::cout << "In Main: Elements of the array argv[] : "<< std::endl; for (int i=0; i < argc; i++){ std::cout << " " << argv[i] << " " ; } std::cout << " "<< std::endl; array(argc, argv); }
Note that the main function in the above program has two arguments, namely argc and argv: these are used to retrieve the arguments from the command line when the program is executed. For instance, assuming the program name is program, if we execute the program using the following instruction in a terminal:
./program a b c d e f
then we will have argc = 7 (6 arguments + 1, the name of the program) and argv = {"./program", "a", "b", "c", "d", "e", "f"}.
Execute now the program with 8 arguments, for instance:
./program A 12 Z ed 5 S U Hellothen we have argc = 9 (8 + 1) and argv = {"./program", "A", "12", "Z", "ed", "5", "S", "U", "Hello"} in the main function.
#include <iostream> void increment_all (int* start, int* stop) { int * current = start; while (current != stop) { ++(*current); // increment the value pointed to by current ++current; // increment the pointer } } void print_all (const int* start, const int* stop) { const int * current = start; while (current != stop) { std::cout << *current << '\n'; ++current; // increment pointer } } int main () { int numbers[] = {10,20,30}; increment_all (numbers,numbers+3); print_all (numbers,numbers+3); return 0; }
Note that print_all uses pointers that point to constant elements, but they are not constant themselves, i.e., the pointers can still be incremented or assigned different addresses, although they cannot modify the content they point to.