1 / 52

Chapter 7 Pointers ( 指针 )

Chapter 7 Pointers ( 指针 ). §7.1 Pointer Basics §7.2 Some Special Pointers §7.3 Pointer in Function §7.4 Pointer and String §7.5 “struct” and Linked List §7.6 Function Pointer. §7.1 Pointer Basics. Memory Space. Memory space A “continuous” space Three regions Memory address

tuwa
Download Presentation

Chapter 7 Pointers ( 指针 )

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. Chapter 7 Pointers (指针) §7.1 Pointer Basics §7.2 Some Special Pointers §7.3 Pointer in Function §7.4 Pointer and String §7.5 “struct” and Linked List §7.6 Function Pointer

  2. §7.1 Pointer Basics Memory Space • Memory space • A “continuous” space • Three regions • Memory address • Each memory unit has an address • Variable address • The initial address of the memory allocated for the variable int i=0; Code Region Static Region (Static variables, global variables, ...) Dynamic Region (local variables, parameters, ...) Heap ( used by programmer) Stack (used by system)

  3. …… What’s a Pointer? • Pointer: • the variable to hold memory addresses as its value Value Pointed 30606 32820 30 Pointer’s name 30606 ptr Pointer’s addr. Pointer’s value

  4. Declare a Pointer • Pointer is a composite data type • Syntax: dataType * pointerName; • For example, a pointer named pCount that can point to an int value: int *pCount; Pointer type Pointer symbol “*” Pointer name

  5. Initialize a Pointer • Implicit initialization • A local pointer is assigned an arbitrary value • A global pointer is assigned to NULL (pointing nothing) • NULL is in fact “00000000” Not recommended! May cause fatal runtime error or accidental data modification!

  6. Initialize a Pointer • Explicit initialization (recommended) int count=5; int *pCount = &count; int *ptr = NULL; Address-of operator “&”. The value of “&i” is the address of i. TestPointer Run

  7. Indirect Reference • Indirection: referencing a value through a pointer. For example: int count=5; int *pCount = &count; count++; //direct reference (*pCount)++; //indirect reference Indirection operator “*”. The value of “*ptr” is the valued pointed by ptr.

  8. p vs. *p vs. &a int age; int *age_ptr = &age; Then, age_ptr  &age *age_ptr  age *age_ptr = 50  age = 50; (*age_ptr)++; age++; \ *age_ptr++; *(age_ptr++);

  9. Operations of Pointer • Operations on the address, not the value pointed • Several specific operations • Assignment • Movement • Subtraction • Comparison • The pointer type determines the unit of the operation results For example: p±n;// move n*sizeof( pionter type)

  10. Examples void main() { int a =10, b = 20; int *pa, *pb; pa = &a; //Assign the address directly pb = pa+2; cout <<"a in: "<< &a <<endl; cout <<"b in: "<< &b <<endl; cout <<"pa is: "<< pa <<endl; cout <<"pa points to: "<< *pa <<endl; cout <<"pb is: "<< pb <<endl; cout <<"pb points to: "<< *pb <<endl; if(pa != pb) cout <<"pa and pb are not equal!"<<endl; cout<<"pb - pa is "<<pb-pa<<endl; }

  11. Cautions • The type of the address assigned to a pointer must be consistent with the pointer type. For example, int area = 1; double *pArea = &area; • The white space besides “*” is optional int*ptr; int *ptr; int* ptr; int * ptr; • One “*” for one pointer int *ptr1, *ptr2; //two pointers int* ptr1, ptr2; // one pointer, one integer

  12. §7.2 Some Special Pointers • Constant Pointer (指针常量) • A pointer whose value can not be changed double radius = 5; double * const pValue = &radius; (*pValue) = 3.0; pValue ++; • Pointer of Constant (常量指针) • A pointer that points to a constant double radius = 5; const double * pValue = &radius; (*pValue) = 3.0; raidus = 3.0

  13. Pointer vs. Reference • Reference is alias • No separate memory, address • Bound with the variable • Must be initialized • Pointer is variable • Memory, address (of itself) • Independent of the variable pointed • Can be reassigned different values

  14. Pointer and Array • The name of an array represents the starting address • An array variable is essentially a pointer “myList” &myList[0]

  15. Pointer and Array You can access city or pCity using the array syntax or pointer syntax. For example, char city[5]=“GZ”; char *pCity=city;//char *pCity=&city[0]; cout << city[1] << endl; cout << *(city + 1) << endl; cout << pCity[1] << endl; cout << *(pCity + 1) << endl; Run ArrayPointer Run PointerWithIndex

  16. Pointer and Array • Array variable is different from a pointer • Array name is a constant (not variable) address int array[10]; int*ptr=array; for (k=0; k<5; k++){ cout<< *(ptr++); cout<< *(array++); }

  17. §7.3 Pointer in Function • Pointer as parameter • The address stored in the pointer is passed to the function • A kind of pass-by-reference Run TestPointerArgument void swap(int *p1, int *p2) { int temp; temp = *p1; *p1 = *p2; *p2 = temp; } void swap(int *p1, int *p2) { int *temp; temp = p1; p1 = p2; p2 = temp; }

  18. Pointer as parameter p2, 0028F711 对指针本身来讲,是“值传递”; 对指针指向的目标来讲,是“引用传递”。 0028F820 p1, 0028F51D 0028F814 void myswap(int *p1, int *p2){ int *temp; temp = p1; p1 = p2; p2 = temp; } pt2, 0028F7EC pt1, 0028F808 main(){ int *pt1, *pt2; … myswap(pt1, pt2); … } b, 0028F814 5 a, 0028F820 8 BottomofStack栈底

  19. Pointer as Return Value • The address stored in a pointer is returned int max=0; int *getMax(); void main(){ int *p; p=getMax(); cout<<"Max is “<<*p); } int *getMax(){ int tmp=max, i; for(i=0;i<3;i++){ cout<<"Please enter No. "<<i<<endl; cin>>tmp; if(tmp>max) max=tmp; } return &max; } Don’t return a local pointer! --it becomes invalid after the return! WrongReverse

  20. Dynamic Memory Allocation • The method allowing programmers to allocate storage • Dynamically (during the execution time) and • “Manually” (using explicit statement) • “new” operator: to allocate memory int *pValue = new int; int *mylist = new int[10]; Allocate memory for an int variable; The address is assigned to “pValue”. Allocate memory for an array of 10 int elements; The address is assigned to “mylist”. CorrectReverse

  21. The “delete” Operator • The memory allocated by “new” remains available until • you explicitly free it or • the program terminates. • “delete”: to free memory reserved by “new”. delete pValue; delete [] mylist; • Memory leak • The memory space becomes inaccessible due to the loss of pointing int *p = new int; p = new int; It’s good manner to always explicitly free memory allocated by “new”. (0x00001234) p delete p; (0x00001267)

  22. Case Study: Counting the Occurrences of Each Letter • Generate 100 lowercase letters randomly and assign to an array of characters. • Count the occurrence of each letter in the array. CountLettersInArray Run

  23. §7.4 Pointer and C-string • Two ways to process strings • To treat strings as arrays of characters • known as pointer-based strings or C-strings • To process strings using the string class • The string class will be introduced in Chapter 9

  24. C-string • Two ways to declare C-string • Using an array variable char city[7] = "Dallas"; char city[] = {'D', 'a', 'l', 'l', 'a', 's', '\0' }; char city[] = "Dallas"; cout << city; char city[7]; city= "Dallas";

  25. C-string using Pointer • Declare a string variable using a pointer char *pCity = "Dallas"; cout<<pCity;

  26. Reading Strings • Using “cin”: can’t read in white space char city[10]; cin >>city; • Using “getline” : can read any character. • a function defined in iostream cin.getline(char array[], int size, char delimitChar) char *city2; cin>>city2; No memory is allocated to store the content of city2. Where to store? The last character is reserved for '\0'. Where to stop? delimitChar is read but not stored. Default delimitChar is ‘\n’.

  27. String Functions

  28. Character Functions

  29. §7.5 “struct” and Linked List • 结构体类型 • 复合数据类型 • 包含多个并列成员 struct Student{ intstd_no; char name[10]; int sex; int age; char dept[10]; }; Struct Name{ 类型 变量名;……   类型 变量名; };

  30. Variable of struct struct Student{ intstd_no; char name[10]; int sex; int age; char dept[10]; }; struct Student stu1, stu2; int main(){ struct Student liu; struct Student zhang= {20010346, ”Zhang” , 1, 18, ”Computer” }; liu.std_no = 0818976; strcpy(liu.name,“Liu Xiang”); cout<<liu.name<<“, “<<liu.std_no<<endl; }

  31. More Declarations struct data { int day, month, year; } ; struct student { char name[20]; long num; struct data birthday; //结构体嵌套 } ; struct student *pst; struct student st[2]; pst = new struct student;

  32. Typedef • to assign alternative names to existing types typedef int km_per_hour ; typedef int points ; km_per_hour current_speed ; points high_score ; ... struct var { int data1; char data2; }; struct var a; typedef struct var newtype; newtype b;

  33. void swapStd(Std st[], int size){ struct student *pst; pst = new struct student; for(int i =1; i<size; i+=2){ strcpy(pst->name,st[i-1].name); pst->num = st[i-1].num; pst->birthday.year = st[i-1].birthday.year; pst->birthday.month = st[i-1].birthday.month; pst->birthday.day = st[i-1].birthday.day; …… } delete pst; } Case study #include <iostream> #include <iomanip> using namespace std; struct data { int day, month, year; }; struct student{ char name[20]; long num; struct data birthday; //结构体嵌套 }; typedef struct student Std; int main(){ Std st[2]; for(int i =0; i<2;i++){ cout<<"Input …:\n"; cin>>st[i].name; cin>>st[i].num; cin>>st[i].birthday.year; … } swapStd(st, 2); cout<<“…\n"; }

  34. Linked List • 链表:a data structure consisting of a group of nodes which together represent a sequence. • 逻辑关系用指针表示。 • 单链表、双向链表和循环链表等。

  35. 单链表 • 一个单链表结点,其结构类型分为两部分: • 数据域:用来存储本身数据 • 链域或称为指针域:用来存储下一个结点地址 struct Node{ char ch; struct Node *next; } Head Tail

  36. Head 5 8 12 30 26 struct Node{ char ch; struct Node *next; } 链表的操作 • 查找 • 插入 • 删除 • 先查找 • 再删除 相等? Tail 链表节点的访问都是通过指针!!

  37. 25 29 25 25 18 76 76 455 18 455 455 18 25 455 25 ∧ ∧ ∧ ∧ ∧ 建立链表 ∧ L • 在链表的头部插入结点建立单链表 • 每个结点的存储空间是运行时系统根据需求而生成的 • 从空表开始,每读入一个数据,申请一个结点,然后插在链表的头部

  38. 建立链表—头插入 typedef struct node{ datatype data; struct node *next; } LNode,*LinkList; LinkList Create_LinkList1( ){ LinkList lst=NULL;/*空表*/ LNode *s; int x; /*设数据元素的类型为int*/ cin>>x; while (x!=flag){ s=new LNode; s->data=x; s->next=lst; lst=s; cin>>x; } return lst; }

  39. 29 76 12 365 89 建立链表—尾插入 • 保持节点生成顺序与链表顺序一致 • 每次是将新结点插入到链表的尾部 • 需加入一个指针 r 用来始终指向链表中的尾结点 L ∧ • 头指针H=NULL,尾指针 r=NULL; • 将新结点插入到 r 所指结点的后面; • 然后 r 指向新结点;

  40. 建立链表—尾插入 LinkList Creat_LinkList2( ){ LinkList L=NULL; Lnode *s,*r=NULL; int x; /*设数据元素的类型为int*/ cin>>x; while (x!=flag){ s=new LNode; s->data=x; if (L==NULL) L=s; /*第一个结点的处理*/ else r->next=s; /*其它结点的处理*/ r=s; /*r 指向新的尾结点*/ cin>>x; } if ( r!=NULL) r->next=NULL; /*最后结点的指针域放空指针*/ return L; }

  41. 节点查找 • get_Linklist(L, i) • 算法思路:从链表的第一个元素结点起,判断当前结点是否是第i个,直到表结束为止。 • 算法如下: Lnode * get_LinkList(LinkList L, inti){ Lnode * p=L; int j=0; while (p->next !=NULL && j<i ) p=p->next; j++; if (j==i) return p; else return NULL; } To search a key value?

  42. p ② ① s × 节点插入—当前指针位置 • p指向插入位置,s指向新节点 • 后插节点 • 将*s插入到*p的后面 ①s->next=p->next; ②p->next=s; //两个指针的操作顺序不能交换。 前插节点?

  43. 节点插入—位置序号 int Insert_LinkList( LinkList L, int i, datatype x){ /*在单链表L的第i个位置上插入值为x的元素*/ Lnode * p,*s; p=get_LinkList(L,i-1); /*查找第i-1个结点*/ if (p==NULL) cout<<“error\n”; else { s=new LNode; /*申请、填装结点*/ s->data=x; s->next=p->next; /*新结点插入在第i-1个结点的后面*/ p->next=s; } return 1; }

  44. p q × 节点删除 • 设p指向单链表中某结点,删除*p。 • 首先要找到*p的前驱结点*q,然后完成指针操作。 q->next=p->next; delete p;

  45. int Del_LinkList(LinkList L,int i) { /*删除单链表L上的第i个数据结点*/ LinkList p,s; p=get_LinkList(L,i-1); /*查找第i-1个结点*/ if (p==NULL) { cout<<“第i-1个结点不存在\n”; return -1; } if (p->next==NULL){ cout<<“第i个结点不存在\n”; return 0; } else{ s=p->next; /*s指向第i个结点*/ p->next=s->next; /*从链表中删除*/ delete s; /*释放*s */ return 1; } }

  46. Notes • 在单链表上插入、删除一个结点,必须知道其前驱结点。 • 单链表不具有按序号随机访问的特性,只能从头指针开始,一个个顺序进行访问。 • 查找及删除时,无需进行元素的移动操作。

  47. §7.6 Function Pointer (函数指针) • Entry address of function (入口地址) • Address of the first instruction • Represented by function name • Pointer of function • Pointing to a function • Containing the entry address of the function

  48. Declaration of function pointer • Syntax functionType (*nameOfPointer)(ParameterList) E.g.: • Pointing to functions with matching header: • Same parameter list and return type • E.g. int (*p1)(int); int max(int, int);int min(int,int);int (*p)(int, int); p = max; p = min;

  49. Invocation via function pointer • Similar to invocation via function name • Syntax: (*functionPointer)(acutualParameterList); *functionPointer(acutualParameterList) • 另外一种格式-不推荐 函数指针名(实参表); p =max;c = (*p)(a,b);  c = max(a,b);

  50. 函数指针示例 void print_stuff(float dtoi){ cout<<"This is the print stuff function.\n“;} void print_message(float ltd){cout<<"The data to be listed is "<<ltd<<endl;} void print_float(float dtp){cout<<"The data to be printed is "<<dtp<<endl;} int main(){ float pi = (float) 3.14159; float two_pi = (float)2.0*pi; void (*function_pointer)(float); function_pointer = print_stuff; *function_pointer(pi); function_pointer = print_message; *function_pointer(two_pi); *function_pointer(13.0); function_pointer = print_float; *function_pointer(pi); return 0; } This is the print stuff function. This is the print stuff function. The data to be listed is 6.28318 The data to be listed is 13 The data to be printed is 3.14159

More Related