Module 012 It’s All about Pointers and References 1 “We had to address information technology in the ways we had not before and give the agents the tools that they need to do their job more efficiently and more expeditiously.” – Robert Mueller. Ever wondered if you can do more than just implement things straight forward? Ever wanted to dive into more technical side of C++? Now that we have completed the fundamentals of C++ and set its difference from the original C language, we will explore the low-level details of C++. In this module, we will tackle the more technical workings that made C and C++ more popular compared to the rest of the programming languages in their time. In addition, these concepts are what set C and C++ apart in technical perspective of implementation. At the end of this module, you will be able to: 1. 2. 3. 4. Differentiate high-, low- and mid-level programming languages. Identify the low-level aspects of C++. Differentiate pointers and references. Argue the importance of pointers and references. Again, researching beyond the coverage of this module is highly encouraged to supplement your understanding of the topics covered. And as always, think and see beyond the box. So, what are we waiting for? Let us continue our exploration of the world of Computer Programming. Course Module Recall In the previous module, we continued our discussion about Object-Oriented Programming. This time, we focused on the four (4) principles of ObjectOriented Programming, namely: (a) Encapsulation (b) Abstraction (c) Inheritance (d) Polymorphism In addition, we learned about the two (2) samples under Encapsulation, namely: (a) Assessors (b) Mutators Lastly, we identified the two (2) forms of polymorphism, namely: (a) Overriding (b) Overloading Introduction to Low-level C++ Since the start of the course, we have explored the C++ programming language in its beauty as a high-level programming language. We have altogether explored the conditionals, looping, arrays, functions and the Object-Oriented Programming schemas of C++. Ideally, programming languages are categorized in terms of complexity by: (a) High-level Programming Languages (b) Low-level Programming Languages (c) Mid-level Programming Languages High-level Programming Languages High-level programming languages are the easiest category of programming languages to work with. High-level Programming Languages are programming languages that exhibits the strongest abstraction of its programming schema. High-level programming languages enables developer to focus on the logic of the application they are developing. They take away the obscure details of how to implement the technical aspects of what they are developing. In addition, they automatically manage the memory allocation part and resource disposal aspects of the development. High-level programming languages also limits the control of the developer over the operating system. This is to fully manage the instructions that come and go to the operating systems instruction set. This part of high-level programming languages is essential which allows the developer to construct their logic without bothering with too much about how to manage overflowing memory and proper resource disposal. Low-level Programming Languages Low-level programming languages are, in contrast, the hardest to manage of all the categories of programming languages. Low-level Programming Languages are programming languages that exhibit the weakest abstraction of all the programming languages aside from machine languages themselves. Low-level programming languages also enables the developer to get into detail of how they like their logic to be implemented. Low-level programming languages can give access to even the hardware components of the computer and the inner workings of the operating system. They can manage and manipulate the runtime tasks that the current running operating system is working on. Low-level programming languages also lets the developer explore the world of embedded systems, giving them access to even the smallest component in the environment. Developers are given direct access to the memory of the computer, particularly the random-access memory. They can also manipulate the values stored in other memory sectors. There exist the least limitations passed to low-level programming languages. Mid-level Programming Languages Mid-level programming languages are the go-in-between of the other programming languages. Mid-level Programming Languages are programming languages that exhibit strong abstraction and mid-range access to the memory and operating system. Course Module Mid-level programming languages showcase user-friendly implementations and structures. Majority of the features available to low-level programming languages are hidden in the background and are usually taken for granted. Some of the implementations are hidden from the user. In addition, some of the tasks are designed by the programming language to be abstract. C++ Programming Languages The programming language designed by Bjarne Stroustrup in 1979 was initially proposed as a high-level programming language. The inner workings of C++ are hidden from the developer through its wide range of libraries and features. Even the conditionals and looping statements do not exhibit what will originally be considered a low-level in detail. This is mainly because the developer is limited to the access and conditions that are present when performing such executions. However, due to the advent of the recent high-level programming languages like Java, C# and Visual Basic.NET, C++ are also considered to be a low-level programming language. This is supported by some level of access that C++ give the developers. C++ enables the developers to get in-detail the memory sector of the computer. In addition, there are a lot of memory-specific features that only C++ has. This is further supported by the fact that the original C is a low-level programming language. Since C++ is, by extension, an extended version of C with the support for Object-Oriented Programming. Introduction to Pointers and References Now that we have established the fact that C++ can be considered a low-level programming language, we need to dwell on one of the infamous low-level capability of C++ - the pointers and references. These features of C++, coupled with dynamic memory allocations, form the fundamental of C++ being a low-level programming language. Pointers Pointers are special variables in C++ that "points" to a sector in the memory. These variables are used as companions of the other variables. They extend the coverage of the variables to such a point that the original variables are being accessed from different sections of the code without being recreated and reassigned. In this point, the concept behind pointers might not be too clear. For example, we set a value to an int myID variable. If we create a pointer int *ptrID with the address of int myID, any changes we do to the int myID variable also happens to the int *ptrID pointer. And any changes we do to the int *ptrID pointer also happens to the int myID variable. This is in contrast with the usual workings of variables. For example, if we assign to another variable int yourID the value of int myID, then when changes occur to one of them, that said change is only done to that specific variable. For instance, we assigned the constant 2 to int myID variable, then the value assigned to the int yourID variable will not change. And the same thing happens vice-versa. The change is isolated. Pointers create somewhat like a mirror image of the variable they are pointed to. Changes are shared between the two. It is also possible to create multiple pointers pointing to the same variable. Figure 1. myId Variable and ptrId Pointer As seen in Figure 1, we have declared a variable int myId and a pointer int *ptrId. The pointer is then assigned the value of the address of the variable. More on this later. We then displayed the values of the int myId variable and the int *ptrId pointer. If we run this source code, the value of int myId variable is 19 while the value of the int *ptrId pointer can be any address Course Module value like 0x071Ww1. To retrieve the value of the variable our int *ptrId pointer is pointed to, we append an asterisk (*) to the pointer. In that line, we will have the value of 19. Figure 2. (2013). C++ Programming Language Pointers, References and Dynamic Memory Allocation [Online Lecture]. Retrieved from https://www.ntu.edu.sg/home/ehchua/programming/cpp/cp4_PointerReference.html. A pointer is then assigned with the address of the variable which is done by appending an ampersand (&), the address of operator, before the variable name. The address of the variable is in the format 0xSSSSSS where an S is alphanumeric. As seen in Figure 2, remember though that the address of the variable and pointer differs. The value stored in the variable is the actual value whereas the value stored in the pointer is the address of the variable it is pointing to. References We have used the address of (&) operator to retrieve the address of the variable. In addition to that, we can also use the address of (&) operator like pointers. That is a reference. A reference is a special variable which, like pointers, stores the address of a variable. The main difference is that the address stays permanent, whereas pointers can change the variable where they point to. Like a pointer, changes done to the original variable where a reference was pointed to will also affect the output of the reference. This is also vice -versa. Changes done to the value of the reference will change the value of the variable it points to. Since this is the case, when we assign another variable to the reference, what we are doing there is copying the value of the variable and storing it to the reference and to the original variable the reference is pointing to. Figure 3. Variables myId and yourId, and Reference refId In Figure 3, we can observe the behavior of a reference. The application started with the declaration of int myId and int yourId variables, and a reference int &refId pointed at int myId. In the said figure, when we displayed the values of the variables and reference, we will get 193612, 856091 and 193612 respectively. Later, in the code, we changed the value of the reference int &refId followed by the changing of the value of int yourId variable. If we display the values now, we will get 856091, 756231 and 856091 respectively. Notice how the variable int myId and the reference int &refId changed their values however was unaffected by the change of the value of variable int yourId. Figure 3 demonstrates the behavior of references, especially when compared to pointers in C++. Course Module Glossary High-level Programming Languages: A set of programming languages that exhibits the strongest abstraction and farthest memory and operating system control. Low-level Programming Languages: A set of programming languages that exhibit the weakest abstraction and closest memory and operating system control. Mid-level Programming Languages: A set of programming languages that exhibit strong abstraction and some memory and operating system control. Pointers: Special types of variables that store the address in the memory rather than the actual value or constant wherein the address can change depending on the assignment of another variable. Address Of [Operator]: A unary operator (&) which retrieves the address of a variable. Address (Variable): The logical address of a variable in the memory. References: Special types of variables that store the address in the memory rather than the actual value or constant wherein the address is permanent and unchanging. References and Supplementary Materials Books and Journals Stephen Davis; 2014; Beginning Programming with C++ For Dummies, 2 nd Edition; United States; For Dummies, A Wiley Brand Richard Halterman; 2017; Fundamentals of C++ Programming; United States of America; Southern Adventist University Online Supplementary Reading Materials C++ Programming Language Pointers, References and Dynamic Memory Allocation; https://www.ntu.edu.sg/home/ehchua/programming/cpp/cp4_PointerRefe rence.html; June 27, 2017 VOID Const functions should not return non-const pointers or references; https://www.securecoding.cert.org/confluence/display/cplusplus/VOID+Co nst+functions+should+not+return+non-const+pointers+or+references; June 26, 2017