概述
二、指针变量的声明和使用
指针变量的类型
指针变量和指针是两个概念,为了方便记忆,读者可以把指针理解为地址,指针变量则是存储地址值的变量。
指针变量的声明
int *pn,*pi; //pn和pi是两个指向int型变量的指针;
float *pl; //pl是一个指向float 型变量的指针;
char *pc; //pc是一个指向char型变量的指针
int *(pf)(); //pf是一个指向函数的指针,该函数返回值为int型数值;
int **pp; //pp是一个指向指针的指针,即二维指针;
notice:在声明指针变量后,系统便给指针变量分配一个内存单元,各种不同类型的指针变量所占用的内存空间的大小是相同的,因为不同类型的指针变量存放的数据值都是内存地址值,是unsigned long 型的。
获得地址并对指针变量进行初始化
int *pa=&a; //将a的地址赋给存放地址的变量(指针)
int *pb=&b[3]; //将b[3]的地址赋给存放地址的变量(指针)
----pa中保存的是变量a的地址值,也可以说pa指向了变量a。因为指针变量只能保存地址,所以不要将任何其他非地址值赋给一个指针变量,例如这样的赋值时不合法的:int *p=100;
特殊的值NULL
int *p=NULL(C++区分大小写),即指针没有指向任何地址,相当于房间建立好了,还没有装修,还不能住人。
指针变量的使用
#include <iostream>
#include<math.h>
#include<string.h>using namespace std;
int main(){
int n=10;
int *pn=&n; //初始化指针变量pn,其值为变量n的地址,*pn现在代表变量n,对于*pn的任何操作都相当于对变量n的操作
cout<<"n="<<n<<endl;
cout<<"pn指向的值为:"<<*pn<<endl;
n+=25;
cout<<"n="<<n<<endl;
cout<<"pn指向的值为:"<<*pn<<endl;
*pn=*pn*10;
cout<<"n="<<n<<endl;
cout<<"pn指向的值为:"<<*pn<<endl;
return 0;
}
指向指针变量的指针
int i=0; //定义一个变量i
int *p=&i; //定义一个指针变量p,并赋初值为i的地址;
int **pp=&p; //定义一个指向指针变量的指针pp,赋初始值为p的地址。
三、指针变量的操作
指针变量的加减运算
#include <iostream>
using namespace std;
int main()
{
int array[5]={1,2,3,4,5},n=1;
int *p=&array[0]; //把数据元素array[0]的地址赋值给p
for(int i=0;i<5;i++)
{
cout<<"p中的地址为:"<<p<<"t其数值为:"<<*p<<endl;
p=p+n; //指针p的值加一 指针同整数n相加减,其实是把指针向前或向后移动n个对应类型的存储单元。公式为:新地址=旧地址+n*指针指向的变量所占用的内存字节数 32位机,int占用4个字节
}
return 0;
}
指针变量的关系运算
四、数组,字符串和指针
数组和指针
#include <iostream>
using namespace std;
int main()
{
int array[5]={1,3,5,7,9};
int *p=array;
for(int i=0;i<5;i++){
*(p+i)=i*2; // 把指针指向的数组元素的值改变
cout<<array[i]<<" ";
}
cout<<endl;
return 0;
}
一维数组中元素的指针表示法
int array[5]
用下标的方法来表示为:array[i] //i=0,1,2,3,4
用指针的方法来表示为 *(array+i) //i=0,1,2,3,4
二维数组的指针表示法
int array[3][3]
用下标的方法表示为:array[i][j] //i=0,1,2;j=0,1,2
用指针的方法表示为:*(*(array+i)+j) //i=0,1,2;j=0,1,2
指针数组的声明为:数据类型 *数组名[数组大小]
字符串和指针
char str[]="this is C++ program";
char *pStr;
char *pStr="this is C++ program";
程序中:
char *pStr=NULL;
pStr="this is C++ program"; 给字符指针赋值,将在内存中自动开辟的字符串数组的首地址赋值给字符指针变量pStr。
cout<<"pStr="<<pStr<<endl;输出字符串指针指向数据时,可以不用加*,因为其会自动从字符串指针指向的首地址开始输出
字符指针如果指向字符串常量,其内容是不能修改的,但如果指向字符数组是可以修改的。
五、常量指针和指针常量
常量指针格式:const 数据类型 *指针变量名
指针常量格式:数据类型 * const 指针变量名=&变量名
常量指针是保证通过指针间接访问的内存中的数据不被修改;指针常量是保证指针本身不会被修改。
六、指针和函数
指针作为参数:
例子:对于两个变量的值进行交换
#include <iostream>
using namespace std;
void swap(int *pa,int *pb);
int main()
{
int a=88,b=208;
cout<<"a="<<a<<"tb="<<b<<endl;
swap(&a,&b); //调用交换函数,传递参数的地址值 把a和b的地址值(取a的地址,b的地址传给函数)赋值给形参
cout<<"a="<<a<<"tb="<<b<<endl;
return 0;
}
void swap(int *pa,int *pb){ //定义交换函数 (接收到的参数为两个指针,即两个变量的地址)
int temp;
temp=*pa;
*pa=*pb;
*pb=temp;}
指针作为函数参数时,可以修改函数外的数据,和引用差不多,为了避免指针作为函数参数导致函数外数据被意外修改,就需要使用const来保护指针指向的数据不被意外修改。例如:
#include <iostream>
void myCopy(int *pDst,const int *pSrc,int slen);
void disp(const int *p,int len);
using namespace std;int main()
{
int array1[20];
int array2[10]={1,3,5,7,9,0,2,4,6,8};
myCopy(array1,array2,sizeof(array2));
disp(array1,10);
return 0;
}
void myCopy(int *pDst,const int *pSrc,int slen) //这个函数。。是乃个。。类似于字符串。。的strcpy函数。。。
{
for(int i=0;i<slen;i++)
{
*pDst++=*pSrc++;
}}
void disp(const int *p,int len){
for(int i=0;i<len;i++)
cout<<*(p+i)<<" ";
cout<<endl;
}
如果在函数myCopy中对源数组pSrc中的数据进行修改的话,代码就会产生编译错误,无法执行。这样就通过使用const来保护了指针指向的数据不被意外修改。
指针作为返回值:
指针函数:声明格式为:数据类型 *函数名(参数表)
如:int *func(int *a,int b);函数名为func,调用其后可以得到一个指向整数的指针。
例子:求数组中的最小数
#include <iostream>
int *min(int *array,int len);
using namespace std;int main()
关于静态指针变量:是为了保证函数返回后,函数中的变量的值还存在,在函数内除了静态变量外,其他存储类型的变量都不能保证函数调用结束后仍然是有效的。
{
int array[]={333,22,400,11,38};
int *pMin=NULL; //初始化指针变量pMin;
pMin=min(array,5); //调用min得到最小值的地址值;
cout<<"min="<<*pMin<<endl;
return 0;
}
int *min(int *array,int len){
static int *p=array; //定义静态指针变量p,并初始化为数组array首地址
for(int i=1;i<len;i++){
if(*p>*(array+i)){ //比较是否当前元素值大于数组中其他元素值
p=array+i; //如果大于,而把较小的一个元素的地址
}
}
return p; //返回指针给主调函数,把静态指针指向的地址值返回
}
七、C++中灵活的空间---堆内存
堆内存也成为动态内存,C++在程序运行时,根据需求申请一定的内存空间来使用,这种内存环境随着程序运行的进展而时大时小,这种内存就是堆内存。
如何获得和使用堆内存
申请时格式为:
new 数据类型[表达式] ;
new是关键字,表明这是一个申请堆内存的操作。申请连续空间时,表达式的值是一个确定的正整数,可以是常量,也可以是变量。类似于声明数组时,给定的元素个数。方括号[ ]是不可省略的。如果只申请一个变量大小的空间,而表达式和方括号[]都可以省略,格式为:
new 数据类型 ;
例子:
#include <iostream>
using namespace std;
int main()
{
int *p=NULL; //声明一个指针
int size=0; //声明一个整型变量,用来接收申请堆空间大小
int i=0;
cout<<"请输入需要生成的长度:";
cin>>size; //接收对空间大小变量
p=new int[size]; //申请堆内存空间,并把返回值赋值给p
if(p==NULL){
cout<<"申请空间失败"<<endl; //申请失败,退出程序
return -1;
}
for(i=0;i<size;i++)
{
*(p+i)=i; //把堆内存中申请的空间每一个进行初始化;
}
for(i=0;i<size;i++){
cout<<*(p+i)<<" "; //输出堆内存中申请的空间的数据值;
}
cout<<endl;
return 0;
}
如何释放堆内存
只申请空间不释放空间的情况称为内存泄露,所以申请内存空间后,应使用delete操作符来释放内存空间,格式为:
delete [ ]指针;
其中delete是关键字,表明是一个释放堆内存的操作,方括号“ [ ] ”表示释放的是堆内存中的连续内存空间。如果申请的只是一个堆内存变量,则会造成内存泄露的情况发生。
现在通过一个求n个数的和的例子,来理解堆内存的申请和释放。
#include <iostream>
using namespace std;
int main()
{
int *p=NULL;
int size=0,i=0,sum=0;
cout<<"请输入需要计算的数字个数n:";
cin>>size;
p=new int[size]; //申请堆内存 申请之后一定要释放。
if(p==NULL){
cout<<"申请空间失败"<<endl;
return -1;
}
cout<<"请连续输入n个整数:"<<endl;
for(i=0;i<size;i++){
cin>>*(p+i);
sum+=*(p+i);
}
cout<<"sum="<<sum<<endl;
delete p; //释放堆内存
return 0;
}
最后
以上就是体贴长颈鹿为你收集整理的C++---基础篇(指针)的全部内容,希望文章能够帮你解决C++---基础篇(指针)所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复