9指针

指针:具有确定属性的地址

属性决定了以该地址为起始地址的存储空间(数据单元)大小以及可以存放什么类型的数据

指针变量:可以存放指针的变量

 

指针的定义

指针变量声明

      int *myPtr;

说明了一个指向int类型的指针变量myPtr

      int *myPtr1,i,*myPtr2, j;

可以说明指向任何数据类型的指针

指针变量声明时可以初始化为 0,NULL或某个地址(指针)0 或 NULL: 不指向任何数据单元 (推荐使用NULL)。

 

指针运算

&  (一元运算,地址运算符)  //注意&的其它用法

运算结果为操作数(“左值性质”,非register)的地址(是一个指向操作数的指针),如

int  y = 5; int *yPtr; yPtr = &y; 使 yPtr 指向 y

 

 

* (一元运算,间接引用运算符,其操作数表达式的值必须是指针),如

    int *yPtr,y;

    yptr = &y;

*yptr = 7;

*yptr = *yptr + 7;

运算结果为操作数指向的数据单元(“左值性质”)

 

注意:

*  和 & 互为 逆运算,如

 int *yptr,y;

 yptr = &y;     

*yptr = 7;

*yptr = *yptr + *&y;

*&*&y = *yptr + *&y;

 

示例:

#include   <stdio.h>  

   int  main(  )

   { int  n;        /* n is an integer */

     int  *nPtr;    /* nPtr is a pointer to an integer */

     n = 7;

     nPtr = &n;    /* nPtr set to address of n */

     printf( "The address of n is %p"  

                  "\nThe value of nPtr is %p", &n, nPtr );  

     printf( "\n\nThe value of n is %d"  

                 "\nThe value of  *nPtr is %d", n, *nPtr );

     printf( "\n\n&*aPtr = %p \n*&nPtr = %p\n",

                   &*nPtr, *&nPtr );  

     return 0;

   }

 

 

指针的算术运算

1.指针变量可以自增/自减  (++ 或 --)

2.指针可以加/减一个整数( + 或 += ,- 或 -=)

3.同类型指针可以相减

 

一元运算符sizeof( )

1.操作数为变量名、类型名或常量

2.运算结果为操作数所需存储单元的字节数

特例:当操作数为数组名时,运算结果为该数组所需存储单元的总字节数

3.如 sizeof(int)、 sizeof(int *)均为4,      

在声明 int myArray[10],*p=myArray;后   sizeof(myArray)为40、 sizeof(p)为4

 

5 个元素的 int 数组v

int  v[5], * vPtr = v ; // vPtr 为3000

vPtr += 2; // 赋值后 vPtr 为3008

把 vPtr的值当作整数和 n *sizeof(int)相加,得到 vPtr + n  的实际值,其它情况同理

同类型指针相减

  int  v[5], * vPtr , * vPtr2;

vPtr = &v[0];

vPtr2 = &v[2];

// vPtr2 - vPtr 结果为 2.

把 vPtr2和vPtr的值当作整数相减后除以 sizeof(int)

 

指针的关系运算

同类型指针可以进行各种关系运算

可以判断指针是否为 0或NULL

 如

  int  v[5], * vPtr , * vPtr2;

vPtr = &v[0];

vPtr2 = &v[2];

while( vPtr < vPtr2 )

 vPtr++;

 

指针的赋值运算

1.同类型指针可以赋值(需满足“左值性质”)

2.不同类型的指针,赋值运算前必须对赋值运算符右边的指针表达式进行强制类型转换   (不是隐式)

  如     int * nPtr;

      float  f=0.5,* fPtr= &f;

      nPtr = (int *) fPtr;

3.特例:指向 void 的指针(类型 void *),一般指针,指向任何类型的数据

任何指针可以不用类型转换,直接赋值给void *类型的指针,

如 void * vPtr; float * fPtr;vPtr = fPtr;

注意:void *类型的指针不能被复引用 

 

 

指针和数组的关系

1.数组名是指向该数组第一个元素的常量指针

2.指针可以做数组下标运算

  如: int   b[5], *bPtr;

  bPtr = b; //等价于bPtr = &b[0];

  *( bPtr + 2 )=5; //等价于b[2]=5;

 //等价于*(b+2)=5;等价于bPtr[2]=5;

 //等价于(b+2)[0]=5;等价于(bPtr+1)[1]=5;

 注:C++编译器把形如指针表达式[下标表达式]的下标运算转化为表达式  *(指针表达式+下标表达式 )。特别要注意理解数组形参和多维数组下标运算的含义

 

数组元素可以是指针

 如:int *array[10],i; array[5]=&i;

 又如:char *suit[4] = 

                {"Hearts","Diamonds",

                 "Clubs", "Spades" };

字符串的值:指向该串第一个字符的指针

suit 的每个元素是一个字符(char)指针

字符串中的字符并没有存放在数组中,数组中存放的是指向字符串的指针

suit 数组的元素数目是固定的,但字符串的长度可以不相等

 

 

const 限定符

在声明变量或形式参数时使用,明确地说明哪些数据是不会改变的。声明变量时通常要给出初值,如 const int studNum = 100 ;  

指向常量数据的非常量指针

  int i, j, *q;

 const int  * p;

 p = &j;      // 允许

 p = &i;      // 允许

 i = 10; // 允许

 *P = 5 ;    // 不允许

 

指向非常量数据的常量指针

  int var1,var2 ;

    int * const p = &var1 ;

    *P = 5 ;      // 允许

   P = &var2 ;   // 不允许

 注:非常量数据的常量指针的初值有限制,如

  const int var ;

int * const p = &var ;      // 错误!

 

指向常量数据的常量指针

  const int val = 10;

  const int *const p = &val ;

  *P = 5 ;     // 不允许

 或

  int var ;

  const int *const p = &var ;

 *P = 5 ; // 不允许

  var = 5 ;    // 允许

 

用于限定函数形式参数,以保护实参

  void output(const double * pd)

 {    cout << *pd ;   // 允许

       *pd = 15.5 ;  // 不允许!

 }

  void output(const double &d)

 {    cout << d ; // 允许

       d = 15.5 ;  // 不允许!

 }

 

 

常用字符串处理函数(库文件string.h)

函数原型:

  int strlen(const char *s);

函数原型:

  char* strcpy(char* dest,

               const char* src);

函数原型:

  char* strcat(char* dest,

               const char* src);

函数原型:

  int strcmp(const char* s1,

               const char* s2);

函数原型:

  char* strchr(const char* s, int c);

函数原型:

  char* strrchr(const char* s, int c);

函数原型:

  char* strstr(const char* s1,

               const char* s2);

函数原型:

  char *strtok(char *s, char *delim);

 

两种分配内存的方式:静态和动态

静态内存分配

通过变量声明实现。所用内存空间(的大小)在编译时决定

 

动态内存分配

1.通过调用malloc函数或利用运算符new实现。所用内存空间在程序运行时分配

2.和malloc函数对应的释放内存函数是free

3.和new对应的释放内存运算符是delete

4.有可能因为系统内存缺少导致动态内存分配失败

 

函数malloc的原型是:

 void *malloc(unsigned size);

 例如:

 int *p=(int *) malloc ( sizeof ( int ) ); (*p )++;

  int *score=(int *) malloc ( sizeof ( int ) * studNum );

 if (score != NULL )

   for ( int  j = 0 ;  j < studNum ;  j++ )  cin  >> score [ j ];

函数free的原型是:

 void free(void *ptr);

如:free(p);  free(score);

 

使用new运算符分配内存,如

   int *p= new  int ; (*p )++;

        int * score= new  int [ studNum ];

   for ( int  j = 0 ;  j < studNum ;  j++ )

        cin  >> score [ j ];

 

使用delete运算符释放内存,如

     delete  p ;

     delete  [ ]  score ;

 

 

例子一:指针与引用

#include <iostream.h> 

void swap(int *, int *); 

int main()

{int x = 10, y = 20;

 swap(&x, &y);    // 传递x和y的地址

 cout<<"x:"<< x <<" y:" << y << endl;

 return 0;

void swap(int * a, int * b)

{int temp;  

 temp = *a;

 *a = *b;

 *b = temp;

}

 

例子二:指针实现冒泡排序

void bubbleSort(int *array, int size)

{void swap( int *, int * );

 int pass, j;

 for ( pass=0; pass<size-1; pass++ )

  for ( j = 0; j < size-pass-1; j++ )

   if ( array[j] < array[j+1] )

    swap( &array[j], &array[j+1] );

}

void swap(int * a, int * b)

{int temp;

 temp = *a; *a = *b; *b = temp;

}

 

例子三:动态分配实现整数排序

#include <stdlib.h>

#include <iostream.h> 

void  sortArray ( int [ ], int );

void  displayArray( int [ ], int ); 

int main()

{ int  * a;

   int  i, num; 

  // 输入要排序的整数的数目

  cout << "Please enter the number of integers: ";

  cin >> num; 

  // 动态分配数组,以保存输入的整数

  a =  new  int [ num ]; 

  if (a == NULL)

  { cout << "malloc error! exit." << endl;

     return  1;

  } 

  // 输入拟排序的整数

  for ( i = 0; i < num; i ++ )

        cin >> a[i]; 

  // 调用函数sortArray对 num 个整数进行排序

  sortArray ( a, num ); 

  // 输出a排序后的结果

  cout << "After sorting:" << endl;

  for (i = 0; i < num; i ++ )

    cout << a[i] << "  ";

  cout << endl ; 

  // 释放动态分配的空间

  delete  [ ] a ; 

  return 0; 

void sortArray( int b[ ], int  len )

{ for (int  pass = 0; pass < len – 1 ; pass ++ )   

    for ( int  i = pass + 1; i <= len – 1 ; i ++ )  

             if ( b[ pass ] > b[ i ] )

             { int hold; hold = b[ pass ];                  

                b[ pass ] = b[ i ]; b[ i ] = hold; }

}

 

posted @ 2018-01-09 16:46  gd_沐辰  阅读(208)  评论(0编辑  收藏  举报