注册 登录  
 加关注
   显示下一条  |  关闭
温馨提示!由于新浪微博认证机制调整,您的新浪微博帐号绑定已过期,请重新绑定!立即重新绑定新浪微博》  |  关闭

Mister.Hu(巷里人家)

Go abroad!

 
 
 

日志

 
 
关于我

A campus photograph palyer,an enthusiastic reader,a solitary writer,a future traffic engineer.

网易考拉推荐

C++强化【6】  

2015-08-22 17:17:11|  分类: Senior |  标签: |举报 |字号 订阅

  下载LOFTER 我的照片书  |

实例71:坐标指针

#include <iostream>

using namespace std;

#include <stdio.h>

 

//071

int main()

{

         int array_071[5][6];

         int (*point)[6]=array_071;//数组指针

         int *pointp[5];//指针数组

         for(int i=0;i<5;i++)

         {

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

                            array_071[i][j]=i+j;//初始化

         }

        

         cout<<"*(*(point+2)+4)的元素为:"<<*(*(point+2)+4)<<endl;

         cout<<"*(point[2]+4)的元素为:"<<*(point[2]+4)<<endl;

         cout<<"(*(point+2))[4]的元素为:"<<(*(point+2))[4]<<endl;

         cout<<"point[2][4]的元素为:"<<point[2][4]<<endl;

 

         for(int k=0;k<5;k++)

                   pointp[k]=array_071[k];

 

         cout<<"*(*(pointp+2)+4)的元素为:"<<*(*(pointp+2)+4)<<endl;

         cout<<"*(pointp[2]+4)的元素为:"<<*(pointp[2]+4)<<endl;

         cout<<"(*(pointp+2))[4]的元素为:"<<(*(pointp+2))[4]<<endl;

         cout<<"pointp[2][4]的元素为:"<<pointp[2][4]<<endl;

         return 0;

}

注:本例主要讲诉了数组指针和指针数组。两者的区别在于,指针数组的每一个元素都是指针,其每个指针指向原数组的一行,本质是数组。而数组指针只有整个数组为指针,其首元素指向原数组,本质为指针。两者的定义形式如下:

int (*point)[6]=array_071;//数组指针

int *pointp[5];//指针数组

不论是数组指针还是指针数组,其关键是赋值和输出,对于赋值,数组指针直接将数组的首地址赋值给指针即可:

int (*point)[6]=array_071;//数组指针(其中,array_071为二维数组array_071[5][6]的首地址。)

而指针数组的赋值则类似于数组的赋值,且定义和赋值是分开的:

定义:int *pointp[5];//指针数组

赋值:for(int k=0;k<5;k++)

                   pointp[k]=array_071[k];

对于输出。两者的输出是一致的,可以用下面四种方式输出数组的某个坐标:(p为定义的名称,i,j表示数组第i行第j)

1*(*(p+i)+j)

2*(p [i]+j)

3(*(p+i))[j]

4p [i][j]

 

实例72:强制修改常量的值

#include <iostream>

using namespace std;

 

//072强制修改常量的值

int main()

{

         int *point;//指针

         const int changliang=12;//常量

         point=(int*)&changliang;//changliang的地址

         *point=34;//改变指针指向内存的值

         cout<<"changliang值:"<<changliang<<endl;

         cout<<"point指向changliang内存的值:"<<*point<<endl;

         return 0;

}

注:首先温习一下指针的含义,诸如*pointpoint代表的是地址,*point代表的才是该内存地址指向的值。故,在进行地址替换是,是用point,如point=(int*)&changliang,而在进行值替换的时候,是用*point,如*point=34

对于point=(int*)&changliang;前面加上(int*)的原因是&changliangconst int型的,而pointint型的,所以需要强制将&changliang转化为int

由最后的输出结果可以看出,changliang的值实际未被改变,但其内存指向的值却发生了改变,原因在于,编译器中,常量的值一旦被定义,就不会再从内存中取值。

 

实例73:通信录(动态申请内存)

#include <malloc.h>

#include <iostream>

using namespace std;

int main() 

         int n; //,表示通信录中有几个联系人

         int m=2; //列,表示名字和其对应通信号

         cout<<"请输入要键入的通信录个数:";

         cin>>n;

         int  **memo; 

         memo=(int**)malloc(sizeof(int *)*n); 

         for(int k=0;k<n;k++) 

                   memo[k]=(int *)malloc(sizeof(int)*m); 

 

         for(int i=0;i<n;i++) 

         { 

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

                            cin>>memo[i][j]; 

         }

         cout<<"通信录编号-------------通信号"<<endl;

         for(int i=0;i<n;i++) 

         { 

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

                            cout<<memo[i][j]<<"                   "; 

                   cout<<endl; 

         }    

         free(memo); 

         return 0; 

}

注:动态申请内存一共有两种方法,上面介绍的是第一种方法,用malloc()动态申请内存。

1、  malloc方式

当申请一维内存时,它的格式是:

类型标识符*变量名

变量名=(类型标识符*malloc(sizeof(类型标识符)*数组大小)

在使用完后,需要用free()函数及时释放,格式如下:

Free(变量名)

变量名=NULL

当申请二维内存时,格式如下:

类型标识符**变量名;

变量名=(类型标识符**malloc(sizeof(类型标识符*)*数组大小)

for(int k=0;k<数组行大小;k++) 

                   变量名[k]=( 类型标识符*)malloc(sizeof(类型标识符)* 数组大小); 

它的释放格式与一维的相同。

2、  new方式

当申请一维内存时,他的格式为:

类型标识符*变量名;

变量名=new 类型标识符[数组大小]

释放时:delete[]变量名;

变量名=NULL;

当申请二维内存时,格式如下:

类型标识符**变量名;

变量名=new类型标识符*[数组大小];

for(int k=0;k<数组行大小;k++) 

           变量名[k]=new 类型标识符[数组大小];

它的释放格式同一维。

实例74:万能箱子(void*

#include <iostream>

using namespace std;

void decrease(void* data, int psize)

{

         switch(psize)

         {

         case 1://a的内存地址赋值给data

                   char* pchar;//定义一个char型指针

                   pchar=(char*)data;//data的内存地址赋值给pchar

                   (*pchar)--;//pchar内存指向的值减1

                   break;

         case sizeof(int):

                   int *pint;

                   pint=(int*)data;

                   (*pint) --;

         }

}

int main()

{

         char a='d';

         int b=102;

         decrease(&a,sizeof(a));

         decrease(&b,sizeof(b));

         cout<<a<<","<<b<<endl;

 

         return 0;

}

注:主要看点在于decrease函数。首先了解一个void*指针,它可以指向任何类型的数据,即任何类型的指针都可以赋值给void*,但反过来,void*需要采用强制类型转化才能赋值给其他类型的指针。本例子便很好演示了这两个过程。

首先,主函数中定义了两种类型的变量,charint,然后,这两种类型都可以直接赋值给decrease函数中的void* data。该函数内是一个switch函数,判断的依据为sizeof(类型),若为1,则是字符,否则,则是int型的。

判断完成后,将主函数中的数据内存地址载赋值给一个对应的类型变量,注意在此是通过void*进行转化的,所以需要对其进行强制转化,即如:pchar=(char*)data;

最后,对该类型变量进行减1,由于是在内存地址层次上操作,所以,将pchar内存指向的值减1,就是将a对应的字符减1.

实例75:指向结构体变量的指针

//075指向结构体变量的指针

#include <iostream>

#include <string>

using namespace std;

struct newtype

{

         int a;

         char ch;

         string str;

};

int main()

{

         newtype *new_type_point, new_type;

         new_type_point=&new_type;

         new_type.a=1;

         new_type.ch='p';

         new_type.str="jkdas";

         cout<<(*new_type_point).a<<endl;//指向结构体成员a

         cout<<new_type_point->ch<<endl;//指向结构体成员a

         //new_type_point.a;//错误形式

         string *str_point;

         str_point=&new_type.str;//指向结构体中元素ch的指针

         cout<<*str_point<<endl;

         return 0;

}

注:主函数中,首先定义了两个newtype结构,一个是指针型的*new_type_point,一个则是普通的new_type;然后,在第二步中将两种内存地址相等处理。

然后函数给普通型的结构new_type内的变量赋值,接着,函数试图通过指针变量输出。这里实际上介绍了三种输出的方法:

1(*new_type_point).a,可输出new_type.a的值

2new_type_point->ch,可输出new_type.ch的值

3string *str_point;

         str_point=&new_type.str;

         cout<<*str_point<<endl;

可输出new_type.str的值

第三种方法,其实是再定义了结构内一个变量的指针,然后将地址做相等处理,最后,通过指针输出该变量的值。

 

实例76:打印内存数据

#include <iostream>

#include <string>

using namespace std;

int main()

{

         int aa=1234

         for(int i=0;i<sizeof(int);i++)

                   cout<<((char*)&aa)[i]<<endl;

         return 0;

}

注:一个int型占有4个字节,打印时,会一次性打印4字节的内存,而不会打印每个字节对应的数据。本例子可以实现一字节一字节的打印内存数据。采用(char*)aa的内存强制转化为char型,然后依次输出。

实例77:错误的释放指针

#include <iostream>

using namespace std;

void main()

{

         int *aa=new int[10];

         int *copy_aa=aa;

         cout<<hex;//十六进制输出

         for(int i=0;i<10;i++)

         {

                   *aa=i;

                   cout<<aa<<" "<<*aa<<endl;

                   aa++;

         }

         cout<<endl<<"当前指针指向内存的地址为:"<<aa<<endl;

         aa=copy_aa;

         delete[] aa;

         aa=NULL;

}

注:本例aa数组首先申请了一个动态内存,然后将aa的首地址赋值给指针copy_aa。接下来是对数组aa的初始化,在这里通过对内存的推移进行赋值,因此在退出循环时,aa的内存已经不是原来的首地址了,因此,此时如果不将copy_aa的地址赋值给aa,而直接释放内存即delete[] aa;则会出现错误,因此,本例主要需要大家注意,在释放指针前必须判断当前指针是否指向内存的首地址。

实例78:防止野指针的代码

#include <iostream>

using namespace std;

 

void main()

{

         int *a;

         int *b=new int[2];

         int aa=10;

         a=&aa;

         *b=2;

         cout<<a<<" "<<*a<<endl;

         cout<<b<<" "<<*b<<endl;

         delete[] b;

        if(b!=NULL)

                 b=NULL;

}

注:在防止野指针产生前,需要了解野指针的成因。主要有三种原因。

第一是指针创建后没有初始化,解决方法是初始化为NULL或者指向合法的内存,在例子中,指针a则通过a=&aa将地址指向了合法的内存。

第二是指针在释放时只是释放了内存,但没有释放指针,解决方法是将指针也设为NULL,例子中的b即是这种解决方法。

第三是指针的创建和操作不在同一个作用域。


  评论这张
 
阅读(18)| 评论(0)
推荐 转载

历史上的今天

在LOFTER的更多文章

评论

<#--最新日志,群博日志--> <#--推荐日志--> <#--引用记录--> <#--博主推荐--> <#--随机阅读--> <#--首页推荐--> <#--历史上的今天--> <#--被推荐日志--> <#--上一篇,下一篇--> <#-- 热度 --> <#-- 网易新闻广告 --> <#--右边模块结构--> <#--评论模块结构--> <#--引用模块结构--> <#--博主发起的投票-->
 
 
 
 
 
 
 
 
 
 
 
 
 
 

页脚

网易公司版权所有 ©1997-2016