C++ 指针经典应用




指针经典应用:

1.

#include <stdio.h>
int main(void)  
{  
  char str[]="hello world";
  for(int i=0;i <sizeof(str);i++)
  cout<<i[str]<<'\n'; 
  getchar(); 
} 


结果:hello world
 
/*在表达式中数组被隐式转换为指针
str[i]  为 *(str + i)
i[str]  为 *(i + str)
0[str+i]为 *(0+str+i)      */


2.

#include<iostream>
using namespace std;
int main()
{
 char *str[]={"welcome","to","Fortemedia","Nanjing"};
 char**p=str+1;
 str[0]=(*p++)+2;
 str[1]=*(p+1);
 str[2]=p[1]+3;
 str[3]=p[0]+(str[2]-str[1]);
 cout<<str[0]<<endl;
 cout<<str[1]<<endl;
 cout<<str[2]<<endl;
 cout<<str[3]<<endl;
 system("pause");
}


结果:
     Nanjing
     jing
     g

/* str的值就是数组的起始地址值,str的值被默认解析成char **变量的值。

char**p=str+1;str指向的类型是char *型的,所以p的值是(int)str+sizeof(char*),显然p指向了str的第二个元素即str[1]的地址。

(*p++)+2;,p的值变为(int)p+sizeof(char*),,显然此时p指向了str[2]的地址,再进行*运算,由于后置是++返回未变化的p的值,取到了str[1]的值,即指向字符串"to"的指针的值,由于*p类型是char*的所以](*p++)+2;最终str[0]指向了“to”结尾的'/0'所以输出str[0]时为空。

str[1]=*(p+1);,显然str[1]指向了字符串"Nanjing"的首地址。cout<<str[1]<<endl;输出字符串Nanjing

很显然cout<<str[2]<<endl;输出jing

p指向了str[2]的地址,由于line9中,把&str[2]~&str[2]+3里的数据修改成了字符创"jing"的首地址。所以最终cout<<str[3]<<endl; 输出g。*/



3.

#include<iostream>
using namespace std;
int main()
{
 int i[2]={1073741824,-1073741824};
 int *p1=&i[0];
 char *p2=(char*)&i[0];
 float *p3=(float*)&i[0];
 cout<<*p1<<'\n'<<*p2<<'\n'<<*p3<<endl;
 p1++;
 p2++;
 p3++;
 cout<<*p1<<'\n'<<*p2<<'\n'<<*p3<<endl;
 system("pause");
}



/*
上述代码中指针变量p1,p2,p3指向相同的地址值,都是i[0]所标识的内存的地址值,但由于指针的类型不同,导致用*运算符进行提领时,*p1,*p2,*p3的值不一样。当p1用*提领p1所指向的内存里的数据时,由于p1是int*型的,所以会从地址值为&i[0]开始,往下涵盖四个字节(sizeof(int))的内存,然后把里面的数据安照int变量的存储方式解析成一个int型数值。1073741824在内存&i[0]~&i[0]+3中存储是0x00,0x00,0x00,0x40,(小段机 补码存储),所以*p1的值是1073741824。而p2是char*型的,所以仅从地址值为&i[0](sizeof(char))的内存把里面的数据按照char变量的存储方式解析成一个char型数值,由于地址值为&[i]的内存里是0x00,所以*p2为0.同样由于p3是float*型的,所以会从地址值为&i[0]开始,往下涵盖四个字节(sizeof(float))的内存,然后把里面的数据安照float变量的存储方式解析成一个float型数值。由于float型变量的存储方式不同于整型,c/c++浮点数存储遵循ieee标准,按照标准*p3的值为2.0(具体请参见本博客里一篇关于float内存布局的博文,不再赘述)。另外从上述代码我们可以看到,指针变量的类型还影响着指针变量算术运算时的跨度,即指针变量+1时,指针变量的值会增加sizeof(指针所指向变量的类型)。
*/



4.

#include <iostream>
using namespace std;
void arrayTest(char str[])
{
 cout << sizeof(str) << endl;
}
int main(int argc, char* argv[])
{
 char str1[10] = "I Love U";
 arrayTest(str1); 
 system("pause");
} 

结果:4

/*
(1)数组名作为函数形参时,在函数体内,其失去了本身的内涵,仅仅只是一个指针;

  (2)很遗憾,在失去其内涵的同时,它还失去了其常量特性,可以作自增、自减等操作,可以被修改。

  所以,数据名作为函数形参时,其全面沦落为一个普通指针!它的贵族身份被剥夺,成了一个地地道道的只拥有4个字节的平民。

*/


1.通过指针改变值:

#include <iostream.h>
void main()
{
int nNumber;
int *pPointer;
nNumber=15;
pPointer=&nNumber;
cout<<"nNumber is equal to :"<<nNumber<<endl;
*pPointer=25;
cout<<"nNumber is equal to:"<<nNumber<<endl;
}



2.传递指针到函数

#include <iostream.h>
void AddFive(int* Number)
{
*Number += 5;
}
void main()
{
int nMyNumber = 18;
cout<<"My original number is "<<nMyNumber<<endl;
AddFive(&nMyNumber);
cout<<"My new number is "<<nMyNumber<<endl;
}


3.指向类的指针

class MyClass
{
public:
int m_Number;
char m_Character;
};
void main()
{
MyClass *pPointer;
pPointer = new MyClass;
pPointer->m_Number = 10;
pPointer->m_Character = 's';
delete pPointer;
}


4.指向数组的指针
int *pArray;
pArray = new int[6];
或者:
int *pArray;
int MyArray[6];
pArray = &MyArray[0];
//最后一行等价于:pArray = MyArray;



5.利用指针变量访问数组元素

#include <iostream.h>
void main()
{
int size;
double array[] = {5.5,4.3,5.2,6.2,7.5};
double *p_array;
p_array=array;
size = sizeof(array)/sizeof(*array);
for(int i=0;i<size;i++)
{
cout<<*(p_array+i)<<endl;
cout<<*(array+i)<<endl;
cout<<array[i]<<endl;
}
}


6.二维数组表示

a[i][j]
*(a[i]+j)
*(*(a+i)+j)
(*(a+i))[j]
*(&a[0][0]+2*i+j)

int a[3][2]={3,4,5};
int *pi;
pi=&a[0][0];//pi=a[0]
//pi=a;错误


int a[3][4],(*p)[4];
p=a;


7.数组的结束标识符识别数组的长度

#include <iostream.h>
void sum(int *);
void main()
{
int a[]={10,20,30,40,50,NULL};
int i=0;
sum(a);
while(a[i]!=NULL)
{
cout<<a[i]<<" ";
i++;
}
}
void sum(int *p)
{
int total=0;
int i=0;
while(p[i]!=NULL)
{
total+=p[i];
p[i]=0;
i++;
}
cout<<total<<endl;
}

8.const与指针

const int *pci;
pci=&a;
*pci=55;//error!

int *const cpi=&a;
*cpi=5;
cpi=&b;//error!

const int *const cpc=&b;
cpc=&a;//error!
*cpc=44;//error!


9.字符串指针

#include <iostream.h>
void main()
{
char *p="Language";
cout<<p<<endl;
for(int i=7;i>=0;i--)
cout<<*(p+i);
cout<<endl;
}


char *p;
cin>>p;

char *p="fortran";
cout>>"p=">>p;

#include <iostream.h>
void main()
{
int len=0;
char a[10],*p=a;
cin>>p;
while(*(p+len)!='\0')
len++;
cout<<"p="<<p<<endl;
cout<<"len="<<len<<endl;
}

#include <iostream.h>
void main()
{
int len=0;
char a[20],*p=a;
cin.get(p,20);
while(*(p+len)!='\0')
len++;
cout<<p<<endl;
cout<<len<<endl;
}


10.引用

int a;
int &r=a;

#include <iostream.h>
void swap(int *,int *);
void main()
{
int x=5,y=10;
cout<<"Main--(1)<<"x="<<x<<",y="<<y<<endl;
swap(&x,&y);
cout<<"Main--(2)"<<"x="<<x<<",y="<<y<<endl;
}
void swap(int *px,int *py)
{
int temp;
cout<<"Sub--(1)"<<"x="<<*px<<",y="<<*py<<endl;
temp=*px;
*px=*py;
*py=temp;
cout<<"Sub--"<<"x="<<*px<<",y="<<*py<<endl;
}




#include <iostream.h>
int& f(int,int*);
void main()
{
int a[]={1,3,5,7,9};
cout<<f(2,a)<<endl;
}
int& f(int index,int *a)
{
int &r=a[index];
return r;
}


11.数组指针
第i个元素地址的表示方法:
&a[i],a+i,p+i,&p[i];
第i个元素的表示方法:
a[i],*(a+i),*(p+i),p[i];

*p++等价于*(p++)


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
指向类的成员的指针C++中,可以说明指向类的数据成员和成员函数的指针。 指向数据成员的指针格式如下: ::* 指向成员函数的指针格式如下: (::*)() 例如,设有如下一个类A: class A { public: int fun (int b) { return a*c+b; } A(int i) { a=i; } int c; private: int a; }; 定义一个指向类A的数据成员c的指针pc,其格式如下: int A:: *pc = &A::c; 再定义一个指向类A的成员函数fun的指针pfun,其格式如下: int (A:: *pfun)(int) = A::fun; 由于类不是运行时存在的对象。因此,在使用这类指针时,需要首先指定A类的一个对象,然后,通过对象来引用指针所指向的成员。例如,给pc指针所指向的数据成员c赋值8,可以表示如下: A a; a.*pc = 8; 其中,运算符.*是用来对指向类成员的指针来操作该类的对象的。 如果使用指向对象的指针来对指向类成员的指针进行操作时,使用运算符->*。例如: A *p = &a; //a是类A的一个对象,p是指向对象a的指针。 p ->* pc = 8; 让我们再看看指向一般函数的指针的定义格式: *() 关于给指向函数的指针赋值的格式如下: = 关于在程序中,使用指向函数的指针调用函数的格式如下: (*)() 如果是指向类的成员函数的指针还应加上相应的对象名和对象成员运算符。 下面给出一个使用指向类成员指针的例子: #include class A { public: A(int i) { a=i; } int fun(int b) { return a*c+b; } int c; private: int a; }; void main() { A x(8); //定义类A的一个对象x int A::*pc; //定义一个指向类数据成员的指针pc pc=&A::c; //给指针pc赋值 x.*pc=3; //用指针方式给类成员c赋值为3 int (A::*pfun)(int); //定义一个指向类成员函数的指针pfun pfun=A::fun; //给指针pfun赋值 A *p=&x; //定义一个对象指针p,并赋初值为x cout<*pfun)(5)<<endl; //用对象指针调用指向类成员函数指针pfun指向的函数 } 以上程序定义了好几个指针,虽然它们都是指针,但是所指向的对象是不同的。p是指向类的对象;pc是指向类的数据成员;pfun是指向类的成员函数。因此它们的值也是不相同的。 对象指针和对象引用作函数的参数 1. 对象指针作函数的参数 使用对象指针作为函数参数要经使用对象作函数参数更普遍一些。因为使用对象指针作函数参数有如下两点好处: (1) 实现传址调用。可在被调用函数中改变调用函数的参数对象的值,实现函数之间的信息传递。 (2) 使用对象指针实参仅将对象的地址值传给形参,而不进行副本的拷贝,这样可以提高运行效率,减少时空开销。 当形参是指向对象指针时,调用函数的对应实参应该是某个对象的地址值,一般使用&后加对象名。下面举一例子说明对象指针作函数参数。 #include class M { public: M() { x=y=0; } M(int i, int j) { x=i; y=j; } void copy(M *m); void setxy(int i, int j) { x=i; y=j; } void print() {
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值