码迷,mamicode.com
首页 > 编程语言 > 详细

C++学习笔记(四)

时间:2016-07-19 23:41:42      阅读:269      评论:0      收藏:0      [点我收藏+]

标签:

1.指针(变量的地址):
  指针变量:存放指针(地址)的变量
  直接存取(访问):按变量地址取值
  间接存取(访问):将变量的地址放入指针变量中
  定义指针变量:基类型 *指针变量名

2.与指针有关的运算符:
  &:取地址运算符
  *:指针运算符(间接访问运算符);
  int *pointer_1,*pointer_2;
  int a = 1, b = 2;
  pointer_1 = &a;
  pointer_2 = &b;
  pointer_2 = &*pointer_1;//*,&优先级一样,自右至左结合,所以是先取a的值,再取a的地址&a给指针变量pointer_2
  若有*&a,表示的是先取a的地址,再取a的值。

3.谨记:函数传参:实参->形参 之间的数据是单向传递的“值传递方式”,指针变量也遵守这一原则,调用函数时,不会改变实参指
针变量的值,但可以改变实参指针变量所指向的值。所以可以利用指针来改变主调函数中多个变量的值,不用指针变量来实现这个是
很难实现这一点的。

4.数组元素的指针就是数组元素的地址

  int a[10];
  int *pointer;
  pointer = a[0];与pointer = a; 等价都表示数组的第一个元素的地址。

  如果初始:pointer = a; 以下都为此前提,那么:
  pointer+1 = a+1 = a[1] //实际地址看类型,pointer+1*n 或者 a+1*n 或者&a[1]
  所以有pointer+i = a+i = a[i] pointer+i*n a+i*n &a[i] 例:int型n=4;

  所以可以看出[]是变址运算符,对a[i]的处理是这样的:先按a+i*n计算数组元素的地址,然后由此地址找出所指向的单元的

  指向数组元素的指针变量也可以带下标,如:pointer[i]与*(pointer+i)等价。
  所以引用数组元素有两种方法:
  a.下标法:a[i];
  b.指针法:*(a+i)或者*(pointer+i);使用这种方法能使目标程序质量高(占运行内存小,运行速度快)
  ·注意:指针变量可以指向有效的数组元素,也可以指向数组以后的内存单元。例:
  int a[10], *p = a;
  cout <<*(p+10);//编译不会提示出错。

  5.如果先使p=a,即p指向数组a的首元素:
  (1).p++(或p+=1):使p指向下一元素,即a[1],如果用*p,则得到a[1]的值;
  (2).*p++: ++与*优先级相同,右结合,相当于*(p++),所以是先取*p的值,再使p++。
  例如:
  for(p=a;p<a+10;p++)
  cout <<*p ; //可改写为:
  for(p=a;p<a+10; )
  cout <<*p++;
  (3).*(p++):先取*p值,p再加1
  *(++p):先p加1,再取*p值,二者区别仅在于p++ 与 ++p 的含义。
  (4).(*p)++:先取*p的值,再使取得的值加1.
  (5).如果p当前指向a[i]:
  *(p--): 先取*p的值,即a[i],再使指针变量p指向a[i-1];
  *(++p): 先使指针变量自增1,指向a[i+1],再取*p的值a[i+1];
  *(--p): 先使指针变量自减1,指向a[i-1],再取*p的值a[i-1];

6.使用指针变量作函数参数接收数组地址
因为数组作形参时接收的也是实参数组的首地址,所以可以用指针变量来接收以数组为实参的参数,例如:
  void select(int array[]);//实际上可以表示为
  void select(int *array );/*编译器实际上是将数组名作为指针变量来处理的。所以实际上,在函数调用时并不存在一个
  占有存储空间的形参数组,只有指针变量。*/

7.多维数组与指针:
  int arr[3][4];假设arr起始为2000

  (1)C++中规定了数组名作为首地址,所以
  arr[0]是arr[0][0]的首地址,arr[1]是arr[1][0]的首地址即&arr[1][0],
  arr[0]+1,表示arr[0][1]的地址,arr[0]+2表示的是arr[0][2]的地址;
  *(arr[0]+2) 表示a[0][2]的值。所以有
  arr[i]+j 表示&arr[i][j],
  *(arr[i]+j) 表示arr[i][j]的值。
  (2)arr,表示首行地址&arr[0],则a+1表示第二行起始地址&arr[1],其值为2000+4*4=2016;
  arr[1]+1: 表示 &arr[1][1],所以有
  arr[i]+j: 表示 &arr[i][j],
  *(arr[i]+j):表示 arr[i][j]的值,因为arr[i] = *(arr+i);所以
  *(*(arr+i)+j): 也表示arr[i][j]的值。
  (3)指向数组元素的指针变量:
#include<iostream>
using namespace std;

int main(){

  int array[3][4] = {1,2,3,4,5,6,7,8,9,10,11,12};
  int *p;
  p = array[0];//注意此处是array[0],而不是array,要符合指针类型。
  cout <<"--------------" <<endl;
  for( p; p<array[0]+12;p++ )
  cout <<*p<< ‘ ‘;
  cout <<endl;
  cout <<"--------------" <<endl;
  return 0;
}
(4)指针变量指向由m个元素构成的一维数组
#include<iostream>
using namespace std;

int main(){

  int a[3][4] = {1,2,3,4,5,6,7,8,9,10,11,12};
  int (*p)[4],i,j;/*(*p)[4]是一个指针变量,它指向包含4个整型元素的一维数组,()不可丢,
否则变成*p[4],[]优先级高,变成了指针数组
*/
  p = a;//p指向a[0];
  cout <<"please input i,j:";
  while(1){
    cin >>i >>j;
    if( i>=3||j>=4 )
    cout <<"warning:i must less then 3,j must less then 4,please try a again:" <<endl;
    else break;
  }
  cout <<"---------------------" <<endl;
  cout <<*(*(p+i)+j);
  cout <<endl <<"---------------------" <<endl;
  return 0;
}

8.指向数组的指针作函数参数(一维数组名,多维数组名也可,之前有讲过)
#include<iostream>
using namespace std;

int main(){

  void output(int (*p)[4]);
  int a[3][4] = {1,2,3,4,5,6,7,8,9,10,11,12};
  output(a);//a指向a[0]
  return 0;
}

void output(int (*p)[4]){//注意形参声明为指向一维数组的指针变量,而不是int型指针变量

  int i,j;
  for( i=0;i<3;i++ )
    for( j=0;j<4;j++ )
      cout <<*(*(p+i)+j) <<" ";
  cout <<endl;
}

9.字符指针(C++中共3种方法访问一个字符串,之前已经学习过两种)
(1)用字符指针指向一个字符串
#include<iostream>
using namespace std;

int main(){

  char *str = "I love China!";//对字符指针变量str的初始化其实是把字符串第一个元素的 地址 赋给str
  //等价于 char *str; str = "I love China"; 输出时,系统先输出str指向的第一个字符数据,
  //然后str+1,使之指向下一个字符,然后输出......直至遇到‘\0‘为止,在内存中,字符串的末尾
  //被自动加了一个‘\0‘
  cout <<str<<endl;
  return 0;
}
(2)利用字符指针实现对字符串的存取
#include<iostream>
using namespace std;

int main(){

  char str1[] = "I love liu_xiao_min",str2[20];
  char *p1,*p2;
  p1 = str1;
  p2 = str2;
  for( ;*p1!=‘\0‘;p1++,p2++ )
  *p2 = *p1;//其实string str1 = "I love liu_xiao_min",str2;str2 = str1;最简单快捷
  *p2 = ‘\0‘;
  p1 = str1;
  p2 = str2;
  cout <<p1 <<endl;
  cout <<p2 <<endl;
  return 0;
}

10.函数与指针
(1)用函数指针变量调用函数(原理:一个函数被编译时被分配一个入口地址。这个函数入口地址就称为函数的指针)
函数指针定义:
函数类型 (*指针变量名)(函数形参表);
例:
#include<iostream>
using namespace std;

int main(){

  int max( int x, int y );
  int (*p)( int, int );//(*p)括号不能漏
  int a,b,n;
  p = max; //函数名代表函数入口地址
  cin >>a >>b;
  m = p( a,b );
  cout <<"max=" <<m<<endl;
  return 0;
}
int max( int x, int y ){

  int z;
  if( x>y )
    z = x;
  else
    z = y;
  return z;
}

(2)用指向函数的指针作函数参数
类似:float intern(float a, float b, float (*fun)(float));

11.指针函数(函数返回值为指针的函数)
指针函数定义:
函数类型 *函数名(参数表列);
例:
#include<iostream>
using namespace std;

int main(){
  int *a(int a);
  int i = 10;
  cout <<a( 10 ) <<endl;
  return 0;
}

int *a( int a ){

  return &a;
}

12.指针数组(一个数组,其元素全部为指针类型数据)

一维指针数组:
类型名 *数组名[数组长度];

 

例:int *a[3]; //注意与int (*a)[3];的区别,后者是指向含有3个整型元素的一维数组的指针变量

#include<iostream>
#include<cstring>
using namespace std;

int main(){

void sort( char *name[], int n );//指针数组做函数参数
void print( char *name[], int n );

  char *name[] = { "BASIC","FORTRAN","C++","Pascal","COBOL" };//指针数组
  int n = 5;
  sort( name,n );
  print( name,n );
  return 0;
}

void sort( char *name[], int n ){ //选择法排序

  char *temp;
  int i,j,k;
  for( i=0;i<n-1;i++ ){
    k = i;
     for( j=i+1;j<n;j++ ){
    if( strcmp( name[k],name[j] )>0 )//name[x]中存放各个字符串的首地址
      k = j;
    }
    if( k!=i ){
    temp = name[i];name[i] = name[k];name[k] = temp;
    }
  }
}

void print( char *name[] , int n ){

  int i;
  for( i=0;i<n;i++ )
  cout <<name[i] <<endl;
  }
输出:
BASIC
C++
COBOL
FORTRAN
Pascal

13.指向指针的指针(指向 指针数据 的指针)
如12所述,数组name[x]是一个指针数组,此时设一个指针变量p,它指向指针数组元素的元素,则p就是指向指针型数据的指
针变量。
定义一个指向指针数据的指针:
char *(*p);//可以写成 char **p;
分析:
char *p:表示指向字符型数据的指针变量(即字符指针变量)。
char *(*p):表示p指向的是字符指针数据
例:
#include<iostream>
using namespace std;

int main(){

  char **p;//定义指向 字符指针数据 的指针变量p
  char *name[] = { "BASIC","FORTRAN","C++","Pascal","COBOL" };
  p = name + 2; //指向name[2]
  cout <<*p <<endl;//输出name[2]中指针指向的字符串的值
  cout <<**p <<endl;//输出name[2]指向的字符串中的第一个字符
  return 0;
}
输出:
C++
C
分析:
由于*p代表name[2],它指向字符串"C++",即在name[2]中存放了字符串"C++"的第一个字符串的地址,因此"cout <<*p <<endl;"就
是从第一个字符开始输出字符串"C++"。第二个cout中的**p是*p(值为name[2])指向的"C++"第一个字符元素的内容,即字符"C",所以
第二个cout语句输出"C".

C++学习笔记(四)

标签:

原文地址:http://www.cnblogs.com/ysys/p/5686534.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!