1 / 35

第 5 章 指针、数组和结构

第 5 章 指针、数组和结构. p. c. &c. ‘a’. 5.1 指针. 1 、指针的定义 T T* char c=‘a’; char *p=&c; char c2= * p. 间接引用. 各种类型指针: int *pi; char **ppc; int *ap[15]; int (*fp)(char*); int *fp (char *);. 5.1.1 零 0 可以被用于作为任意类型的常量 const int NULL = 0 ; 0 可以被用于指针常量; int *p=NULL;

Download Presentation

第 5 章 指针、数组和结构

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. 第5章 指针、数组和结构

  2. p c &c ‘a’ 5.1 指针 • 1、指针的定义 T T* char c=‘a’; char *p=&c; char c2=*p 间接引用

  3. 各种类型指针: int *pi; char **ppc; int *ap[15]; int (*fp)(char*); int *fp (char *);

  4. 5.1.1零 0可以被用于作为任意类型的常量 const int NULL=0; 0可以被用于指针常量; int *p=NULL; int *p=0;(C++)

  5. 5.2 数组 • T T[size] float v[3]; char* a[32]; int b[2][3]; size为常量表达式 void f(int i) { int v1[i];//错误 vector<int> v2(i);//可变界数组 int bad[5,2] ;//错误 }

  6. 5.2.1 数组初始化 • 当数组声明中没给出数组大小,有初始化列表,则大小由列表元素个数决定。 int vl[ ]={1,2,3,4} char v2[3]={‘a’,’b’,0}; • 给出大小,则初始化列表给出多于元素就是错误。 char v3[2]= {‘a’,’b’,0}; • 给出大小,如初始化列表的元素太少则由0补。 int v5[8]={1,2,3,4};

  7. 5.2.2 字符串文字量 “this is a string” • 长度: • 存储长度:sizeof(“hello”) • 类型:适当个数的const字符的数组 const char[6]

  8. 可以将字符串文字量给char *赋值,但不能通过该指针修改字符串文字量。 void f() { char* p=“plato” p[4]=‘e’; }

  9. 改为 void f() { char p[]=“zeno”;// char p[5]; p[0]=‘R’; }

  10. 字符串文字量是静态分配的,可作为函数返回值。字符串文字量是静态分配的,可作为函数返回值。 const char* error_message(int i) { //… return “range error”; }

  11. 字符串文字量可有转义符 “asdsfgf\00sdsad”

  12. 5.3 到数组的指针 • 一个数组的名字能够被用作到它的开始元素的指针。 int v[]={1,2,3,4}; int *p1=v; int *p2=&v[0]; int *p3=&v[4]; v 1 2 3 4

  13. 从数组名到这个数组的开始元素的隐式转换在C风格中广泛使用从数组名到这个数组的开始元素的隐式转换在C风格中广泛使用 extern “C” int strlen(const char *);//string.h void f() { char v[]=“Annermarie”; char*p=v; strlen(p); strlen(v); v=p; }

  14. 5.3.1 在数组里漫游 指向数组的指针运算: p1+1; p3-1; p1++; p3--; • 当两个指针指向同一个数组元素时,指针相减才有定义。 • 两个指针相加是不允许的。

  15. 遍历字符数组 void fi(char v[]) { for(int i=0;v[i]!=0;i++) use(v[i]); } void fi(char v[]) { for(char *p=v;*p!=0;i++) use(*(p+i)); }

  16. 数组不具有自述性,遍历时需提供元素个数 void fp(int v[],unsigned int size) { for(int i=0;i<size;i++) use(v[i]); } • 大多数C++实现不提供对数组范围的检查。

  17. 5.4 常量 • 1、定义——“不变化的值” const int model=90; const int v[]={1,2,3,4}; const int x; 常量必须初始化

  18. 将某些东西声明为常量,就保证了其作用域内不能改变它们的值。将某些东西声明为常量,就保证了其作用域内不能改变它们的值。 • 例题: void f() { const int model=90; const int v[]={1,2,3,4}; model=200; v[2]++; }

  19. const改变了类型,但没有描述常量如何分配 void g(const X*p) {*p= ; } void h() { X val; g(&val); }

  20. const最常见的作用是作为数组的界和作为分情况标号。const最常见的作用是作为数组的界和作为分情况标号。 const int max=128; int v[max]; const int a=100; void f(int i) { switch(i){ case a: //… }

  21. 5.4.1 指针和常量 • const char *pc; 到const char的指针 char *const cp; 到char 的const 的指针

  22. void f1(char*p) { char s[]="gorm"; const char *pc=s; pc[3]='g'; pc=p; char *const cp=s; cp[3]='a'; cp=p; const char*const cpc=s; cpc[3]='a'; cpc=p;}

  23. 在参数中使用指向常量的指针做参数,就禁止了这个函数对改参数的修改。在参数中使用指向常量的指针做参数,就禁止了这个函数对改参数的修改。 char *strcpy(char *p,const char *q);

  24. 可以将一个变量的地址赋给一个到常量的指针,但不能将常量的地址赋给一个未加限制的指针。可以将一个变量的地址赋给一个到常量的指针,但不能将常量的地址赋给一个未加限制的指针。 void f4() { int a=1; const int c=2; const int* p1=&c; const int *p2=&a; int *p3=&c;//const_cast<int*>(&c) *p3=7; }

  25. 5.5 引用 • 定义和作用: T& 一个引用就是某对象的另一个名字,主要用途描述函数的参数和返回值。 • 引用必需做初始化。 int i=1; int &r1=i;

  26. pp: &ii void g( ) { int ii=0; int &rr=ii; rr++; int *pp=&rr; } rr: 0 ii:

  27. 普通T&的初始式必须是一个类型T的左值; • const T&的初始值不必是一个左值,甚至可以不是类型T的左值。 double &dr=1; const double &cdr=1; double temp=double(1); const double &cdr=temp

  28. 通过引用描述函数的参数 void increment(int& aa){aa++;} void f() { int x=1; increment(x); std::cout<<x<<‘\n’; }

  29. 5.6 指向void的指针 • 任何类型指针都可以赋值给void*的变量(除到函数的指针及到成员的指针); • 可以显式将void*转换到另一个类型指针; • 其他操作均不安全;

  30. void f(int *pi)//判断 {void *pv=pi; *pv; pv++; int *pi2=static_cast<int*>(pv); double *pd1=pv; double *pd2=pi; double *pd3= static_cast<double*>(pi); }

  31. void的最重要的用途是需要向函数传递一个指针,而又不能对对象类型做任何假设,还用就是作为函数的返回值。void的最重要的用途是需要向函数传递一个指针,而又不能对对象类型做任何假设,还用就是作为函数的返回值。 • 一般用于系统中很低的层次。 void *my_alloc(size_t n);

  32. 5.7 结构 struct address{ char *name; long int number; ….; }; address jd,*pjd=&jd; jd.name;pjd->name;

  33. 结构对象可用初始化列表进行初始化(一般用构造函数)结构对象可用初始化列表进行初始化(一般用构造函数) address jd={“jim Dandy”,61,…}; • 结构类型对象可以被赋值、作为函数参数传递、作为函数返回值返回。

  34. 类型的名字在出现之后就可以使用了,不必等到看到完整的声明之后。类型的名字在出现之后就可以使用了,不必等到看到完整的声明之后。 struct link{ link*pre; link*suc; } • 在完整声明被看到之前,不能声明这个结构类型的新对象。 struct No_good{ No_good member;}

  35. struct是类的简单形式 5.7.1类型等价 • 两个结构总是不同类型,即使它们有相同的成员; struct s1{int a;}; struct s2{int a;};//考虑typedef s1 s2; s1 x; s2 y=x;

More Related