Upload
victoria-odonnell
View
28
Download
0
Embed Size (px)
DESCRIPTION
Structured Programming Instructor: Prof. K. T. Tsang. Lecture 7: Pointer 指针. Memory cells and addresses. Computer memory is a sequential collection of storage-cells for data. Each cell is 1 byte in size and has an address associated with it. - PowerPoint PPT Presentation
Citation preview
Structured Programming Instructor: Prof. K. T. Tsang
Lecture 7: Pointer
指针
1
Memory cells and addresses
Computer memory is a sequential collection of storage-cells for data.
Each cell is 1 byte in size and has an address associated with it.
Typically, the addresses are numbered consecutively, starting from zero. The last address depends on the memory size. A computer with 64k memory will have its last address as 65,535.
2
Address of Variable
When a variable is declared, the C/C++ compiler will allocate a block of cells somewhere in the memory to hold the value of the variable, either during compile-time or in run-time.
The size of this block of cells will depend on the data type of the variable being declared.
The address of the first cell in this block is the address of the variable.
3
ExampleIn a machine with 4-byte integer, when we declare and
initializeint an_int = 789;
4 adjacent memory cells are reserved for the variable an_int and occupied by the integer 789. The address of the first cell in this block is the address of an_int.
19 20 21 22 23 24 25 26 27 28Cell address
4 bytes occupied by an_int
789
Address of an_int
4
4 essential attributes特征of a variable
name (identifier) data type (size of
memory block)
address
value an_int
20020
789
5
Address Operator &The “address of ” operator (&) gives the
memory address of the variable(地址算符 )Usage: &variable_name
int a = 100;//To get the value, use the variable nameprintf(“a=%d\n”, a); //prints 100//To get the memory address, add the address //operator before the variable nameprintf(“address of a: %d\n”, &a); //prints 1024
100100…… …… …… ……Memory address: 1024
……1020
a
6
Address Operator &
#include <stdio.h>void main(){
int a, b;a = 88;b = 100;printf("The address of a is: %x”, &a);printf("The address of b is: %x”, &b);
}
Try the following code to get the addresses of variables.
Address is usually a large number, so print it in hex.
7
Pointer指针• A pointer constant指针常数 is the
memory address of a variable.
• A pointer variable指针变量 is a variable used for storing the address of a variable.
• Using pointer (i.e. data type and memory address), we can access the value of the variable stored in the memory indirectly.
8
Pointer Types
C/C++ has pointer types for each type of data, e.g.• Pointers to int data type• Pointers to char data type• Pointers to user-defined data structure
Even pointers to pointers• Pointers to pointers to int type
9
Pointer Variables• A pointer variable is a specific box for storing a
memory address• Declaration of Pointer variables
type* pointer_name; //style 1 or
type *pointer_name; //style 2 or
type * pointer_name; //style 3
where type is the type of data pointed to (e.g. int, char, double) by the pointer.
10
Declaration of PointersThe style 2 (in previous slide) is more popular
because it is more convenient to have multiple declaration, and accessing the target value, e.g.
int i1, i2, *ip; //ip is a pointer
ip = &i1; //initialize ip by address of i1
*ip = 23; //assign 23 to i1
float f1 = 1.33;
ip = &f1; //error, why?
11
Pointer Variables
int a = 100;int *p = &a;printf(“%d %x\n”, a, &a);printf(“%x %x\n”, p, &p);
The value of pointer p is the address of variable a.A pointer is also a variable, so it has its own memory
address.
1001008888 …… 10241024 ……Memory address: 0x1024 0x1034
……0x1020
a p
12
De-reference Operator * 取值算符We can access to the value stored in the variable pointed to by preceding the pointer with the dereference (indirection) operator (*),
int a = 100;int *p = &a;printf(“%d %x\n”, a, &a);printf(“%d %x %x\n”, *p, p, &p);
1001008888 …… 10241024 ……Memory address: 0xa23b 0xa24b
……a p
Result is:100 a23b100 a23b a24b
13
Example: * operator
int numberA, *p, m;
numberA = 145;
p = &numberA; //initialize p
m = *p; //assign 145 to m
*p = 31; //assign 31 to variable pointed to by p
printf(“%d\n”, numberA ); //31
14
Don’t get confused• Declaring a pointer means only that it is a pointer:
int *p; //p is an integer pointer• Don’t be confused with the de-reference operator, which
is also written with an asterisk (*). They are simply two different tasks represented with the same sign
int a = 100, b = 88, c = 8;int *p1 = &a, *p2, *p3 = &c;p2 = &b; // p2 points to bp1 = p2; // p1 points to bb = *p3; //assign c to b
printf(“%d%d%d\n”, a, b, c); //result is: 888
15
Pointer Example
#include <stdio.h> int main (){
int value1 = 5, value2 = 15; int *p1, *p2; p1 = &value1; // p1 = address of value1p2 = &value2; // p2 = address of value2 *p1 = 10; // value pointed to by p1=10 *p2 = *p1; // value pointed to by p2= value
// pointed to by p1 printf("value1=%d ; value2=%d\n“, value1, value2);
p1 = p2; // p1 = p2 (pointer value copied) *p1 = 20; // value pointed to by p1 = 20 printf("value1=%d ; value2=%d\n“, value1, value2); return 0;
}
Result is:value1=10 ; value2=10value1=20 ; value2=20
16
Pointer vs. reference
• Both are used to indirectly access variables.
• Reference always refers to a data object. It is an error to define a reference without initializing it, while it is OK to do so for a pointer.
• It is an error to define a reference to another reference, but it is OK to define a pointer to another pointer.
17
Pointer vs. reference - 2
• Once initialized, a reference always refers to the same data. Pointer can point to different data by re-assignment.
int i1=17, i2=210;
int &r1=i1, &r2=i2;
r1=r2; //assigns 210 to i1
int *p1=&i1, *p2=&i2;
p1=p2; //p1 now points to i2
18
Pointer to other pointer
Pointer variable has its own address. So we can define a pointer points to another pointer.
int ival = 67;
int *p = &ival; //pointer to ival
int **q; //declaring a pointer to other pointer
q = &p; //pointer to pointer p
19
Pointer to Pointer
What is the output?
58 58 58
20
More Pointer to Pointer
int a = 58;int *p = &a;int **q = &p;int ***r = &q;int ****s = &r;q = &a//illegal!s = &q//illegal!
58 2234 3334 4434 5534
Int a p q r s
Pointer to int Pointer to pointer to int
Pointer topointer to pointer to int
Pointer topointer topointer to pointer to int
2234 3334 4434 5534
addresses
21
Pointer and arrayWhen we use the name of an array in an
expression, that name is automatically converted into a pointer to the first element of the array.
int ia[] = {5, 6, 1, 3};
int *p = ia; //p points to ia[0]
int *q = & ia[4];
//q points to ia[4]
22
Array Name is a pointer constant#include <stdio.h>
void main (){// Demonstrate array name is a pointer
constantint a[5];printf("Address of a[0]: %x\n”, &a[0]);printf("Name as pointer: %x\n“, a);
}
/* example of result (system dependent):Address of a[0]: 0x0065FDE4Name as pointer: 0x0065FDE4*/
23
Pointer Arithmetic -- to compute a pointer to an array element by adding /subtracting an integral value to/from a pointer to another array element
int ia[] = {5, 6, 4, 1, 3}; int *p1 = ia; //p1 points to ia[0]int *p2 = ia + 4; //p2 points to ia[4]
int *p3 = ia + 6; //error: ia + 6 is invalid address
24
Pointer Arithmetic
Given a pointer p, p+n refers to the element that is offset from p by n positions.int a[5] = {2,4,6,8,22};int *p = &a[1];
2
4
8
6
22
a
a + 2
a + 4
a + 3
a + 1 p
p + 2
p + 3
p - 1
p + 1
25
*(a+n) is identical to a[n]
Dereferencing Array Pointers
a[3] or *(a + 3)
24
86
22
a
a + 2
a + 4a + 3
a + 1a[2] or *(a + 2)a[1] or *(a + 1)
a[0] or *(a + 0)
a[4] or *(a + 4)
26
Use of array pointerconst int arr_sz = 6;int ia[arr_sz] = {5, 6, 1, 2, 4, 3}; for (int *p1 = ia; p1 <= ia+arr_sz; ++p1)
printf(“%d ”, *p1); //print current elementprintf(“\n”);
27
Array of Pointers & Pointers to Array
a
b
c
An array of Pointers
p
int a = 1, b = 2, c = 3;
int *p[5];
p[0] = &a;
p[1] = &b;
p[2] = &c;
int list[5] = {9, 8, 7, 6, 5};
int *p;
P = list;//points to 1st entry
P = &list[0];//points to 1st entry
P = &list[1];//points to 2nd entry
P = list + 1; //points to 2nd entry
A pointer to an array
28
NULL pointer
• NULL is a special value that indicates an empty pointer• If you try to access a NULL pointer, you will get an error• “NULL” is defined as a preprocessor constant in cstdlib
int *p = NULL; //okp = 0; //ok, literal ‘0’ for null pointercout << p << endl; //prints 0cout << &p << endl; //prints address of p cout << *p << endl; //Error!
int zero = 0;int *p1 = zero; // error, cannot use integer zero instead of ‘0’int *p2 = 7889; //error, cannot be assigned with a fixed number
29
Good programming practice tips
• Using un-initialized pointer is dangerous.
• If you have to define a pointer without assigning a pointer constant to it, set it to NULL first.
30
String pointerchar s1[ ] = “A string";while (*s1) {
printf(“%c”, *s1);++s1;
}printf(“\n”);
char *s2 = “Another string";char *s3 = s2;printf(“%s %s %s\n”, s1, s2, s3)
This is the old way we learned to declare & initialize a string. S1 is the pointer to the first element of the character array.
This creates a string to hold all the characters and stores the address of the first character in the string pointer variable s2.
Assign s2 to another string pointer variable s3
31
String copy using pointer#include <stdio.h> char* str_copy(char *s1, char *s2);int main() { char *s3 = “This is a string!"; printf(“s3= %s\n”, s3);
char *s4; s4 = str_copy(s4, s3); printf(“s4= %s\n”, s4); return 0;}
char* str_copy(char *s1, char *s2){int i = 0;while (*s2 != '\0') { *s1 = *s2; ++s1; ++s2; i++;}*s1 = *s2;return s1-i;}
32
Using const to protect argumentso that its value cannot be changed
float mean (int n, const float *a){
float sum = 0.0;for (int i=0; i<n; i++) sum += *(a+i);return (sum/(float)n);
}
In general if we prototype:void fun1(const int *p)then inside the definition of fun1 we cannot have a
statement like:*p = 10;
33
Exercise
Following last example, use pointer to write a function with the prototype:
char* strcat(char* s1, const char* s2);
to concatenate(连接 ) 2 strings s1 & s2 together.
Use this function in a program to show that it works.
34
35
36
37
Pointer as function arguments: Compare this with call by reference in Lecture 7 example: swap
void exchange (int *, int *);main(){
int x = 100, y = 28;printf(“before exchange: x=%d y=%d”, x,
y);exchange ( &x, &y);printf(“after exchange: x=%d y=%d”, x, y);
}void exchange (int *a, int *b){
int t = *a;*a = *b; *b = t;
}38
Bubble Sort using pointersvoid sort (int m, int *x){
int i, j, temp;for (i=1; i<m; i++)
for (j=1; j<=m-i; j++) {if (*(x+j-1) >= *(x+j) ) {
temp = *(x+j-1); *(x+j-1) = *(x+j) ; *(x+j) = temp ;
}}
}39
Bubble Sort using pointers
void sort (int m, int *x){
int i, j, temp;for (i=1; i<m; i++)
for (j=1; j<=m-i; j++) {if (*(x+j-1) >= *(x+j) )
exchange(x+j-1, x+j);}
}
40
Using bubble sort with pointer
#include <stdio.h>void sort (int m, int *x);void main(){
int score[ ] = { 11, 9, 19, 15, 22, 7};for (int i=0; i<6; i++) printf(“%d ”, score[i]);printf(“\n”);int *ia = score;sort(6, ia);for (int i=0; i<6; i++) printf(“%d ”, score[i]);printf(“\n”);
}41
Bubble Sort using array
void sort (int m, int x[ ]){
int i, j, temp;for (i=1; i<m; i++)
for (j=1; j<=m-i; j++) {if (x[j-1] >= x[j] ) {
temp = x[j-1]; x[j-1] = x[j] ; x[j] = temp ;
}}
} 42
Using array bubble sort#include <stdio.h>void sort (int m, int x[ ]);void main(){
int score[ ] = { 31, 9, 19, 15, 22, 7};for (int i=0; i<6; i++) printf(“%d ”, score[i]);printf(“\n”);sort(6, score);for (int i=0; i<6; i++) printf(“%d ”, score[i]);printf(“\n”);
}
43
Library function for input - scanf
“scanf” read input data from the keyboard, similar to “printf” output data to the terminal.
First argument to “scanf” is the format string (enclosed by “ ”) similar to the format string used by “printf”.
Second (and 3rd…) argument to “scanf” is an address to the input data.
int number, u, v;printf (“Please input an integer.\n”);scanf ( “%i”, &number);printf (“Please input 2 positive integers.\n”);scanf (“%d%d”, &u, &v);printf (“Got 2 positive integers: %d %d\n”, u, v); 44
Important
scanf (“format string”, arg1, arg2, arg3,…)where arg1…argn are addresses to data.
scanf ( “Enter a number\n%d”, &number);
Input data must be separated by space, tab or newline.
If you forget to put “&” in front of the variables in the arguments of “scanf”, the result could be a “segmentation violation core dumped” or “illegal memory access” error. 45
Example: find greatest common divisor• Given 2 positive integers u & v. • If v equals zero, then the gcd is u.• Find temp=u%v, then set u=v, v=temp, and go back to previous step.
#include <stdio.h>void main () {
int u, v, temp;printf (“Please input 2 positive integers.\n”);scanf (“%i %i”, &u, &v);if(u<v) exchange(&u, &v); //make sure u>v
printf (“2 positive integers are: %d %d\n”, u, v);while (v != 0) {
temp = u%v; u = v; v = temp;}printf (“The greatest common divisor is: %d\n”, u);
} 46
Inputting character string with scanf
“scanf” can be used with %s format to read in a string of characters up to a blank space, tab or newline character.
char str[99];
scanf (“%s”, str); //no ‘&’ needed
The 2 statements above have the effect of reading a character string typed into the terminal and storing it in the array str.
47
More examples: inputting strings
char s1[99], s2[99], s3[33];
scanf (“%s %s %s”, s1, s2, s3);
With the input text line:
“happy new year\n”
results in s1 = “happy”
s2 = “new”
s3 = “year”
48
Summary—what you should have learned
from this Lecture
• Variable address• Pointer uses the variable address to access the
variable value indirectly.• “Address of” operator: &• “De-reference” or “Value contained” operator: *• Array name as a pointer• Pointer arithmetic• Pointer vs. reference• String pointer: char*• Using “scanf” to input data from terminal
49