CS代考 CITS2002 Systems Programming

CITS2002 Systems Programming
1 next → CITS2002 CITS2002 schedule
A slow introduction to pointers in C
The ISO-C99 programming language has a very powerful feature for addressing and modifying memory which, for now, we’ll casually term “pointers in C”.
If used correctly pointers can enable very fast, efficient, execution of C programs.
If misunderstood or used incorrectly, pointers can make your programs do very strange, incorrect things, and result in very hard to diagnose and debug programs.
The primary role of pointers – to allow a program (at run-time) to access its own memory – sounds like a useful feature, but is often described as a very dangerous feature.
There is much written about the power and expressiveness of C’s pointers, with general agreement that C’s pointers are a threshold concept in Computer Science.
(Recently much has been written about Java’s lack of pointers. More precisely, Java does have pointers, termed references, but the references to Java’s objects are so consistently and carefully constrained at both compile- and run-times, that little information about the run-time environment is exposed to the running program, and little can go wrong).
CITS2002 Systems Programming, Lecture 13, p1, 13th September 2021.
Pointers on C, , Addison-Wesley, 636pp, 1998.
Understanding and Using C Pointers, , O’ , 226pp, 2013.
CITS2002 Systems Programming
←prev 2 next→ CITS2002 CITS2002schedule
What are pointers?
We know that C has both ”standard” variables, holding integers, characters, and floating-point values, also described as scalar variables.
In addition, we’ve seen arrays of these variables.
Let’s follow this simplified explanation:
We understand that variables occupy memory locations (1 or more bytes) of a computer’s memory.
Each variable requires enough bytes to store the values the variable will (ever) need to hold. For example, on our CSSE labs’ computers, a simple C integer will require 4 bytes of memory.
Similarly, an array of 100 integers, will require 400 bytes of contiguous memory – there is no padding between elements.
Computers have a large amount of memory, e.g. our lab computers have 8 gigabytes of memory (8GB), or nearly 8.6 billion bytes.
Each of a computer’s memory bytes is uniquely numbered, from 0 to some large value. Each such number is termed the byte’s memory address.
We often refer to memory locations as just addresses and the action of identifying an address as addressing.
With these points in mind, we can make 3 simple statements:
1. Pointers are variables that hold the address of a memory location.
2. Pointers are variables that point to memory locations.
3. Pointers (usually) point to memory locations being used to hold variables’ values/contents.
CITS2002 Systems Programming, Lecture 13, p2, 13th September 2021.
CITS2002 Systems Programming
←prev 3 next→ CITS2002 CITS2002schedule
The & operator, the address-of operator, the ampersand operator
The punctuation character &, often pronounced as theaddress-of operator, is used to find a
variable’s address.
For example, we’d pronounce this as:
“the address of total”, and if the integer variabletotal was located at memory address 10,000 then the value of &total would be 10,000.
We can now introduce a variable named p, which is a pointer to an integer
(pedantically, p is a variable used to store the address of a memory location that we expect to hold an integer value).
If the integer variable total was located at memory address 10,000 then the value ofp would be 10,000.
If necessary (though rarely), we can print out the address of a variable, or the value of a pointer, by first casting it to something we can print, such as anunsigned integer, or to an”generic” pointer:
int total;
…. &total ….
int total; int *p ;
p = &total ;
int total;
int *p = &total ;
printf(“address of variable is: %lu\n”, (unsigned long)&total ); printf(” value of pointer p is: %lu\n”, (unsigned long)p ); printf(” value of pointer p is: %p\n”, (void *)p );
CITS2002 Systems Programming, Lecture 13, p3, 13th September 2021.
CITS2002 Systems Programming
←prev 4 next→ CITS2002 CITS2002schedule
Dereferencing a pointer
We now know that a pointer may point to memory locations holding variables’ values.
It should also be obvious that if the variable’s value (contents) changes, then the pointer will
keep pointing to the same variable, (which now holds the new value).
We can use C’s concept of dereferencing a pointer to determine the value the pointer points to:
int total;
int *p = &total ;
total = 3;
printf(“value of variable total is: %i\n”, total );
printf(“value pointed to by pointer p is: %i\n”, *p ); ++total; // increment the value that p points to
printf(“value of variable total is: %i\n”, total ); printf(“value pointed to by pointer p is: %i\n”, *p );
Even though the variable’s value has changed (from 3 to 4), the pointer still points at the variable’s location.
The pointer first pointed at an address containing 3, and the pointer kept pointing at the (same) address which now contains 4.
CITS2002 Systems Programming, Lecture 13, p4, 13th September 2021.
CITS2002 Systems Programming
←prev 5 next→ CITS2002 CITS2002schedule
Dereferencing a pointer, continued
We now know that changing the value that a pointer points todoes not change the pointer
Now we’d like to change the value held in the address that the pointer points to. Similarly, this will not change the pointer itself.
int total;
int *p = &total ; int bigger;
total = 8;
printf(“value of variable total is: %i\n”, total );
printf(“value pointed to by pointer p is: %i\n\n”, *p );
*p = *p+2; //increment,by2,thevaluethatppointsto
printf(“value of variable total is: %i\n”, total ); printf(“value pointed to by pointer p is: %i\n\n”, *p );
bigger = *p + 2 ; // just fetch the value that p points to
printf(“value of variable total is: %i\n”, total ); printf(“value of variable bigger is: %i\n”, bigger ); printf(“value pointed to by pointer p is: %i\n”, *p );
CITS2002 Systems Programming, Lecture 13, p5, 13th September 2021.
CITS2002 Systems Programming
←prev 6 next→ CITS2002 CITS2002schedule
An array’s name is an address
When finding the address of a scalar variable (or a structure), we precede the name by the address of operator, the ampersand:
However, when requiring the address of an array, we’re really asking for the address of the first element of that array:
int total;
int *p = &total ;
#define N 5
int totals[N];
int *first = &totals[0]; int *second = &totals[1]; int *third = &totals[2];
// the first element of the array // the second element of the array // the third element of the array
As we frequently use a pointer to traverse the elements of an array (see the following slides on pointer arithmetic), we observe the following equivalence:
That is: “an array’s name is synonymous with the address of the first element of that array.”
CITS2002 Systems Programming, Lecture 13, p6, 13th September 2021.
int *p = &totals[0] ; // and:
int *p = totals ;
CITS2002 Systems Programming
←prev 7 next→ CITS2002 CITS2002schedule
Pointer Arithmetic
Another facility in C is the use of pointer arithmetic with which we may change a pointer’s value so that it points to successive memory locations.
We specify pointer arithmetic in the same way that we specify numeric arithmetic, using the symbols ++ and – – to request pre- and post- increment and decrement operators.
We generally use pointer arithmetic when accessing successive elements of arrays. Consider the following example, which initializes all elements of an integer array:
#define N 5
int totals[N];
int *p = totals; // p points to the first/leftmost element of totals
for(int i=0 ; i