指针使用灵活,但也最易犯错,当指针指定到错误的地址往往很不容易调试.因此掌握指针的正确使用是C++编程的一门基本功. 本文有关的指针操作: //*1**********使用指针与地址运算符************* //*p表示p地址内指示的内容,p表示存储地址. //赋值时*p赋予所指变量的内容信息*p=a; //p用来赋予所指变量的地址信息p=&a. //输出时p用来输出所指变量的内容信息,&p用来输出p的地址信息. //指针类型在使用时,不可指向不存在的(void)位置,否则会造成不可预料的结果, //基本上指针遵循下述两种情况: //1.指向已存在的措针 //2.要求分配内存自行使用(或内存管理) UsePoints(); //*2**********指针地址运算********************* //char *ch ; ch++;ch--;char类型在内存中占一个字节空间,地址增减量为1. //int *ptr; 4 //float *f; 4 //double *d; 8 //*p++;p++;*--p;*++p;(*p)++;(*p)--; CalAddressOfPointer(); //*3**********指针的内存配置******************** //配置单一内存 //配置单一内存并赋值 //配置多个内存,此种方式以指针当数组使用,又有固定大小或弹性大小. PointerMemSet(); //*4*********指针变量与二维数组***************** ArrayAndPointer(); //*5*********指针与函数************************* //一般变量传递参数给指针,再返回来. VariMemberAndPointer(); //传址方式传参数 //使用地址运算符"&"也可实现,将数据从函数的参数部分返回参数. VariAddAndFunction(); //前两种方法的混合使用 VariAndPointer(); //指针传给指针 //大家都是指针,避免传递参数时使用地址运算符"&"不留神时造成的错误. PointerAndPointer(); //函数名称以指针返回 PointerFunction(); //*6******指针与结构****************************** PointerAndStruct(); //*7******指针的指针(双指针)********************** DoublePointer(); //*8******以双重指针来赋值二维数组**************** DoublePointerAndArray(); //*9******指针指向函数**************************** PointerToFunction(); //*10*****指针数组******************************** PointerArray(); //*11*****字符数组与字符串的常数设置************** CharArrayAndString(); //*12*****类的指针传递**************************** UseDataHelperArray(); 详细代码://***********使用指针与地址运算符*************//*p表示p地址内指示的内容,p表示存储地址. //赋值时*p赋予所指变量的内容信息*p=a; //p用来赋予所指变量的地址信息p=&a.//输出时p用来输出所指变量的内容信息,&p用来输出p的地址信息.//指针类型在使用时,不可指向不存在的(void)位置,否则会造成不可预料的结果,//基本上指针遵循下述两种情况://1.指向已存在的措针//2.要求分配内存自行使用(或内存管理)void UsePoints(){ int x=10; int *p4; cout<<"**********************************"<<endl; //p4=x; //错误.将数值10赋给存储地址的指针是不对的. //*p4=x; //错误,p4还没有指向内存的地址,不能给它赋值. p4=&x; //p4指向x的地址 cout<<"x中的值 :"<<x<<endl; //10 cout<<"x的地址 :"<<&x<<endl; //0x0012FF28 cout<<"p4中的内容:"<<p4<<endl; //p4中保存了x在内存中的地址.即&x与p4值相同.p4保存了x的地址. cout<<"p4的地址 :" <<&p4<<endl; //p4的地址.与x的地址不同. cout<<"取出p4所指地址中的内容:"<<*p4<<endl; cout<<"**********************************"<<endl; //指针赋值. //指针类型之间可以互相赋值,即可以使许多指针指向同一个地址. int *p1; p1=p4; cout<<"p1=p4操作"<<endl; cout<<"p1中的内容:"<<p1<<endl; //p1中保存了x在内存中的地址.即&x与p1值相同.p1保存了x的地址. cout<<"p1的地址 :" <<&p1<<endl; //p1的地址.与x,p4的地址不同. cout<<"取出p1所指地址中的内容:"<<*p1<<endl; cout<<"P4要求分配4个字节的内存空间自行使用"<<endl; p4=new int; //P4要求分配4个字节的内存空间自行使用. *p4=x; cout<<"p4:"<<*p4<< " &x: "<<&x <<" &p4: "<<&p4<<endl; //值:10,0x0012FF28,0x0012FF24 cout<<"**********************************"<<endl;}//***********指针地址运算********************* //char *ch ; ch++;ch--;char类型在内存中占一个字节空间,地址增减量为1. //int *ptr; 4 //float *f; 4 //double *d; 8 //*p++;p++;*--p;*++p;(*p)++;(*p)--;void CalAddressOfPointer(){ cout<<"**********************************"<<endl; int *p,a=10; p=&a; (*p)++; //表示先输出*p的内容后,再而p++.其主要原因是*运算符拥有最高优先级; cout<<"*p,a: "<< *p<<", "<<a<<endl; //11,11 均增1. *p++; //表示先输出*p中内容11后,再p中的地址加1. cout<<"*p++:"<<*p<<endl;//1244968(p+1地址中的数,因机而异.) *p--; cout<<"*p--:"<<*p<<endl;//11. *++p; cout<<"*++p:"<<*p<<endl;//1244968(p+1地址中的数,因机而异.) *--p; cout<<"*--p:"<<*p<<endl;//11 cout<<"**********************************"<<endl; //数组访问, p1++的使用. int b[6]={1,2,3,4,5,6}; int *p1=b; for(int i=0;i<6;i++) { cout<<"各元素地址:"<<endl; cout<<"b["<<i<<"]"<<&b[i]<<endl; cout<<"*p1内容:"<<*p1<<endl; cout<<"p1地址:"<<p1<<endl; cout<<"++(*p1):"<<++(*p1)<<endl; //先*p取出数据,然后对取出的数据加1. cout<<"(*p1)++:"<<(*p1)++<<endl; cout<<"p1地址:"<<p1<<endl; p1++; //通过指针中的地址递增访问数组b中的数据. } cout<<endl; //p1=b; //或 p1=&b[0]; for(int w=0;w<6;w++) cout<<p1++<<" "<<*p1<<endl; cout<<"**********************************"<<endl; //字符数组的访问,*p3++的使用. char s2[10]="Morning"; char *p3=s2; cout<<"一次输出一个字符"<<endl; int ilen=strlen(s2); //for(int j=0;j<ilen;j++) //或 while(*p3) cout<<*p3++<<","; //M,o,r,n,i,n,g, cout<<endl; cout<<"**********************************"<<endl; p3=s2; for(int j=0;j<ilen;j++) cout<<p3++<<endl; //输出p3所指的内容,非地址值; //Monrning,onrning,g; cout<<"**********************************"<<endl; char s[10]="Howareyou"; char *p2=s; //*p2中存储s的内容. //指针p2变量占用4个字节的存储空间,用来存储s的地址信息; cout<<"p2指原内容:"<<p2<< " &p2地址:"<<&p2<<" &s地址:"<<&s<<endl; //Howareyou,OX0012FEF4,OX0012FEF8 p2++; //p2中存储的s地址信息加1. cout<<"p2++后内容:"<<p2<<" &p2地址:"<<&p2<<" &s地址:"<<&s<<endl; //owareyou,OX0012FEF4,OX0012FEF8 cout<<"**********************************"<<endl; char *str; if((str=(char*)malloc(21))==NULL) { cout<<"内存不足"<<endl; exit(1); } strcpy(str,"goodMorning"); //将goodMorning复制给str. strcpy(s,str); cout<<"所复制的数据为:"<<str<< endl; cout<<"长度:"<<strlen(str)<<endl; cout<<"**********************************"<<endl; //p2=str; //指针p2变量占用4个字节的存储空间,用来存储s的地址信息; cout<<"p2指原内容:"<<p2<< " &p2地址:"<<&p2<<" &s地址:"<<&s<<"s现在的值: "<<s<<endl; //oodMorning,OX0012FEF4,OX0012FEF8,goodMoning p2++; //p2中存储的s地址信息加1. cout<<"p2++后内容:"<<p2<<" &p2地址:"<<&p2<<" &s地址:"<<&s<<"s现在的值: "<<s<<endl; //odMorning,OX0012FEF4,OX0012FEF8,goodMoning free(str); cout<<"**********************************"<<endl;} //***********指针的内存配置******************** //配置单一内存 //配置单一内存并赋值 //配置多个内存,此种方式以指针当数组使用,又有固定大小或弹性大小.void PointerMemSet(){cout<<"**********************************"<<endl;//配置单一内存 int *a,b; a=new int; cout<<"a的地址:"<<a<<endl; cout<<"b的地址:"<<&b<<endl; *a=2; *a+=6; cout<<setw(6)<<"*a+6="<<setw(6)<<*a<<endl; delete a;cout<<"**********************************"<<endl;//配置多个内存int n;n=16;int *b3;b3=new int[n];int i=0;for(i=0;i<n;i++){ *(b3+i)=rand()%16; cout<<*(b3+i)<<",";}delete [] b3;cout<<endl;cout<<"**********************************"<<endl;//c语言中的malloc与free写法,#include<stdlib.h> 或#include<alloc.h>//要注意内存大小的匹配 char: 1; int: 4;float: 4;int *a2;if((a2=(int *)malloc(6*sizeof(int)))==NULL){ cout<<"内存不足"<<endl; exit(1);} //对//a2=(int *)malloc(17);//错误,配置17个字节的内存,非int类型所占内存的倍数.for(i=0;i<6;i++){ *(a2+i)=rand()%16; cout<<*(a2+i)<<",";}cout<<endl;free(a2);cout<<"**********************************"<<endl;}//**********指针变量与二维数组*****************void ArrayAndPointer(){ cout<<"**********************************"<<endl; //指针变量与二维数组 const int w=3,y=4; //注意要定义为const,以便后面的int a[i][j]使用; int a[w][y],*p; int i=w,j=y; p=&a[0][0]; //p中只保存有a[0][0]的地址,p+m是地址值增加. int m=0; cout<<"&p="<<&p<<endl; for(m=0;m<w*y;m++) { *(p+m)=rand()%12; cout<<*(p+m)<<" "; } cout<<endl<<"数组内容为"<<endl; for(m=0;m<3;m++) for(int n=0;n<4;n++) { cout.width(3); //设置输出的字符宽度 cout<<*(*(a+m)+n)<<" "; } cout<<endl<<"&p="<<&p<<endl; //delete p; cout<<"**********************************"<<endl;}//*5*********指针与函数*************************//函数与指针的可能组合声明 调用 函数定义 说明int a; fc1(&a,); void fc1(int *a,) 指针参数返回int a; fc1(a,); void fc1(int &a,) 指针参数返回int *a; fc1(a,); void fc1(int *a,) 指针参数返回int *a; a=fc1(); int *fc1() 函数名返回int *a,*b; a=fc1(b,); int *fc1(int *b,) 函数名返回,指针参数返回//一般变量传递参数给指针,再返回来.int Cal_data(int *a,int *b){ int t; t=*a+100; *a=*b; *b=t+200; return *b;}int VariMemberAndPointer(){ int a,b; a=10; b=16; cout<<"运算前: a="<<a<<" b= "<<b<<endl; cout<<Cal_data(&a,&b)<<endl ; //将两个变量的地址传给参数. cout<<"运算后: a="<<a<<" b= "<<b<<endl; //a=16,b=310; return 1;}//***********************************//传址方式传参数//使用地址运算符"&"也可实现,将数据从函数的参数部分返回参数.//通过指针与引用进行数据传递,可使程序在调用函数上更为灵活,但必须注意//传递参数的相互关系/**//////////////////////////////////////////////////主程序调用 函数定义int a,*b;fc1(&a); -> void fc1(int *a)fc1(a); -> VOID fc1(int &a) fc1(b); -> VOID fc1(int *b) /**//////////////////////////////////////////////////int Cal_data(int &,int &);//先声明 int VariAddAndFunction() { int a,b; a=10; b=16; cout<<"运算前: a="<<a<<" b= "<<b<<endl; cout<<Cal_data(a,b)<<endl ; //将两个变量的地址传给参数. cout<<"运算后: a="<<a<<" b= "<<b<<endl; //a=16,b=310; return 1; } int Cal_data(int &a,int &b) { int t; t=a+100; //不能使用t=*a+100; *a为指针类型. a=b; b=t+200; return b; }//*********************************************//前两种方法的混合使用int Cal_data(int &a,int *b); VariAndPointer() { int a,b; a=10; b=16; cout<<"运算前: a="<<a<<" b= "<<b<<endl; cout<<Cal_data(a,&b)<<endl ; //将两个变量的地址传给参数. cout<<"运算后: a="<<a<<" b= "<<b<<endl; //a=16,b=310; return 1; } int Cal_data(int &a,int *b) { int t; t=a+100; //不能使用t=*a+100; *a为指针类型. a=*b; *b=t+200; return *b; } //指针传给指针 //大家都是指针,避免传递参数时使用地址运算符"&"不留神时造成的错误. int Get_Data(int *a,int *b) { *a=10; *b=20; return *b; }int PointerAndPointer(){ int *a,*b; a=new int; b=new int; cout<<Get_Data(a,b); cout<<"取出a,b的值"<<*a<<" "<<*b<<endl; delete a; delete b; return 1;}//函数名称以指针返回int *Get_data1(int ,int);int *Get_Array();char *Get_String();int PointerFunction(){ int a=10,b=20,*p; p=Get_data1(a,b); cout<<"p="<<*p<<endl; delete p; int *p2=new int[11]; cout<<"&p2="<<&p2<<endl; p2=Get_Array(); cout<<"p2="; for(int i=0;i<9;i++) cout<<*p2++<<","; cout<<"&p2="<<&p2<<endl; cout<<endl; int j=0; for ( j=0;j<9;j++) //*p2--; cout<<"&p2="<<*p2--<<endl; //一定要加上此句. delete [] p2; char *p3=new char[13]; cout<<"&p3="<<&p3<<endl; p3=Get_String(); cout<<"p3="<<p3<<endl; cout<<"&p3="<<&p3<<endl; int x=sizeof(p3); cout<<"p3长度"<<x<<endl; for (j=0;j<13;j++) cout<<"&p3="<<p3--<<endl; //delete [] p3; return 1;}int *Get_data1(int a,int b){ int *p=new int(a+b); return p;}int *Get_Array(){ int *p=new int[11]; for(int i=0;i<9;i++) *(p+i)=i*2; return p;}char *Get_String(){ char *p=new char[13]; p="good morning"; return p;}//指针与结构typedef struct student{char name[4];char sex;int age;}_student;void get_student(student *a){ a->name[0] ='b'; a->name[1] ='l'; a->name[2] ='g'; a->name[3] ='c'; a->sex ='f'; a->age =23;}int PointerAndStruct(){ student blgc;get_student(&blgc);cout<<"name="<<blgc.name <<endl;cout<<"sex="<<blgc.sex <<endl;cout<<"age="<<blgc.age <<endl;return 1;}//指针的指针(双指针)int DoublePointer(){ //*p 地址->内容 //**p 地址->地址->内容 int x,*p,**p2; x=100; p=&x; p2=&p; cout<<"*p="<<*p<<endl; //100 cout<<"&p="<<&p<<endl; //0x0012FF24 cout<<"*p2="<<*p2<<endl; //0x0012FF28 cout<<"**p2="<<**p2<<endl; //100 return 1;}//以双重指针来赋值二维数组//先要求行的指针,再以行的指针来赋值列的指针,使行为第一指针,//列为第二指针,形成数组的数组,其访问方式可用一般数组的访问方式.const int row=2;const int col=3;int Get_Array(float **data){ srand((unsigned)time(NULL));//启动随机函数生成器 randomize(); int temp=0; for(int i=0;i<row;i++) for(int j=0;j<col;j++) { temp=random(10); //产生0-9的随机数 data[i][j]=(float)temp; } return 1;}void Display(float **data){for(int i=0;i<row;i++){ for(int j=0;j<col;j++) cout<<data[i][j]<<" ";cout<<endl;}}void Dispose(float **data){ for(int i=0;i<row;i++) { delete [] data[i]; //释放列 } delete [] data; //释放行} int DoublePointerAndArray(){float **data;try{ data=new float *[row]; //配置行 for(int j=0;j<row;j++) data[j]=new float[col]; //配置列 throw(1); //自定义抛出一个异常数字1.}catch(int err){ if(err!=1) { cout<<"内存不足,"<<endl; exit(-1); }}Get_Array(data);Display(data);Dispose(data); //释放内存return 1;}//指针指向函数//函数虽然不是变量,但它仍然在内存中有实际地址,故可以将指针指向该地址.//要取得函数地址,只要将函数名称赋值给指针变量,而不用任何括号或参数,就//象数组的地址赋值给指针变量一样.double xpowxy(double,double,double(*xy)(double,double));double add(double x ,double y);int PointerToFunction(){ //指针指向pow函数,用以求x的y次方值. double x,y; double (*p)(double,double); //p=pow; p=add; x=10; y=2; //cout<<"x^y="<<xpowxy(x,y,p)<<endl; cout<<"x+y="<<xpowxy(x,y,p)<<endl; return 1;}double xpowxy(double x,double y,double(*xy)(double ,double)){ return xy(x,y);}double add(double x ,double y){ return x+y;}//指针数组int PointerArray(){ int *p[6],i=0; for(i=0;i<6;i++) { p[i]=new int(i*2); //分配内存空间,赋初值. } for(i=0;i<6;i++) { cout<<*p[i]<<endl; //输出结果 } for(i=0;i<6;i++) { delete p[i]; //释放资源 } return 1;}//字符数组与字符串的常数设置const int N=6;int CharArrayAndString(){ int i; char s[N]={'a','b','c','d','e'}; //纯字符数组非字符串,没有结束符'\0' char st[N+1]={'A','B','C','D','E','\0'}; //纯字符数组的字符串 char str[]="ABCDE"; char *string="ABCDE"; cout<<"字符数组输出s[N]="; for (i=0;i<N;i++) cout << s[i]; cout << endl; cout <<"字符串输出st[N+1]="<<st<<endl; cout <<"字符串输出str[]="<<str<<endl; cout <<"字符串输出*string="<<string<<endl; return 1;}class DataHelper{private : int x; int a[10]; public : int *Group1[20]; static int Group2[20]; int Group3[20]; int y; static int z; DataHelper(); int GetGroup1(); int SetGroup2(int b[20]);};int DataHelper::z ; //静态成员声明,切记.int DataHelper::Group2[20]; DataHelper::DataHelper(){ x=10; y=-1; z=-1; for(int i=0;i<20;i++) { Group1[i]=new int(-1); Group2[i]=-1; } memset(Group3,-1,sizeof(Group3));}DataHelper::SetGroup2 (int b[20]){ for(int i=0;i<20;i++) { Group2[i]=b[i]; } return 1;}int UseDataHelperArray(){ DataHelper *dh; dh=new DataHelper(); *(dh->Group1[0])=10; *(dh->Group1[0])=20; dh->y=20; DataHelper::z=100; int a[20]; memset(a,100,sizeof(a)); dh->SetGroup2(a) ; DataHelper::Group2[0]=100; cout<<"dh->y="<<dh->y <<endl; cout<<"dh->Group1[0]="<<*(dh->Group1[0])<<endl; cout<<"dh->Group1[1]="<<dh->Group1[1]<<endl; cout<<"DataHelper::z"<<DataHelper::z<<endl; cout<<endl<<endl; cout<<"dh2->Group2[0]="<<DataHelper::Group2[0]<<endl; DataHelper *dh2; dh2=new DataHelper; cout<<endl<<endl; cout<<"dh2->Group1[1]="<<dh2->Group2[1]<<endl; return 1;}#include <iostream.h>//cout,cin#include <iomanip.h>//setw()#include <conio.h> //getch()# include <stdio.h># include <stdlib.h># include <string.h># include <time.h># include <math.h> //pow(x,y)#define randomize() srand((unsigned) time(NULL))#define random(x) rand()%x//#include <alloc.h>#include <process.h>//#include <except.h>//指针使用灵活,但也最易犯错,当指针指定到错误的地址往往很不容易调试.//因此掌握指针的正确使用是C++编程的一门基本功.//**************//指针类型在使用时,不可指向不存在的(void)位置,否则会造成不可预料的结果,//基本上指针遵循下述两种情况://1.指向已存在的措针//2.要求分配内存自行使用(或内存管理)//***************//指针下标超出数组范围