C++2

指针,在C/C++语言中一直是很受宠的;几乎找不到一个不使用指针的C/C++应用。用于存储数据和程序的地址,这是指针的基本功能。用于指向整型数,用整数指针(int*);指向浮点数用浮点数指针(float*);指向结构,用对应的结构指针(struct xxx *);指向任意地址,用无类型指针(void*)。
    有时候,我们需要一些通用的指针。在C语言当中,(void*) 可以代表一切;但是在C++中,我们还有一些比较特殊的指针,无法用(void*)来表示。事实上,在C++中,想找到一个通用的指针,特别是通用的函数指针简直是一个“不可能任务”。
   
    C++是一种静态类型的语言,类型安全在C++中举足轻重。在C语言中,你可以用void*来指向一切;但在C++中,void*并不能指向一切,就算能,也失去了类型安全的意义了。类型安全往往能帮我们找出程序中潜在的一些BUG。
   
    下面我们来探讨一下,C++中如何存储各种类型数据的指针。
 
    1.  数据指针
     数据指针分为两种:常规数据指针和成员数据指针
     
    1.1 常规数据指针
     这个不用说明了,和C语言一样,定义、赋值是很简单明了的。常见的有:int*, double* 等等。
     如:

     int value = 123 ;
     
int * pn = &
value;

   
     
    1.2 成员数据指针
     有如下的结构:

     struct  MyStruct
     {
       
int
 key;
       
int
 value;
     };

   
     现在有一个结构对象:

     MyStruct me;
     MyStruct* pMe = &me;

   
     我们需要 value 成员的地址,我们可以:

     int * pValue = & me.value;
     //
     int * pValue = &pMe->value;

   
     当然了,这个指针仍然是属于第一种范筹----常规数据指针。
     
     好了,我们现在需要一种指针,它指向MyStruct中的任一数据成员,那么它应该是这样的子:

     int MyStruct::* pMV = & MyStruct::value;
     
//

     int MyStruct::* pMK = & MyStruct::key;

   
     这种指针的用途是用于取得结构成员在结构内的地址。我们可以通过该指针来访问成员数据:

     int value = pMe->*pMV; // 取得pMe的value成员数据。
     int key = me.*pMK; //  取得me的key成员数据。

   
     那么,在什么场合下会使用到成员数据指针呢?
     确实,成员指针本来就不是一种很常用的指针。不过,在某些时候还是很有用处的。我们先来看看下面的一个函数:

  int sum(MyStruct* objs, int MyStruct::* pm, int  count)
  {
      
int result = 0
;
      
for(int i = 0; i < count; ++
i)
          result 
+= objs[i].*
pm;
      
return
 result;
  }

     
     这个函数的功能是什么,你能看明白吗?它的功能就是,给定count个MyStruct结构的指针,计算出给定成员数据的总和。有点拗口对吧?看看下面的程序,你也许就明白了:
     

     MyStruct me[10=
     {
      {
1,2},{3,4},{5,6},{7,8},{9,10},{11,12},{13,14},{15,16},{17,18},{19,20 }
     };
     
     
int sum_value = sum(me, &MyStruct::value, 10
);
     
//计算10个MyStruct结构的value成员的总和: sum_value 值 为 110     (2+4+6+8++20)

     
     
int sum_key = sum(me, &MyStruct::key, 10
);
     
//
计算10个MyStruct结构的key成员的总和:   sum_key 值 为 100       (1+3+5+7++19)

   
     
     也许,你觉得用常规指针也可以做到,而且更易懂。Ok,没问题:

     int sum(MyStruct* objs, int  count)
     {
      
int result = 0
;
      
for(int i = 0; i < count; ++
i)
       result 
+=
 objs[i].value;
      
return
 result;
     }

 

函数生命周期

一个常量的生命周期在于本函数空间结束时结束。

void main()

{

    int a=1;

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

{

int a=9;

cout<<a<<endl;

}

cout<<a<<endl;

}

结果:

9

9

 

2

如果 void main()

{

int a=2;

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

{

cout<<a<<endl;

}

cout<<a<<endl;

}

结果:

2

2

2

如果 void main()

{

 

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

{

int a=2;

cout<<a<<endl;

}

cout<<a<<endl;

}

结果错误;因为在for(int i=0;i<2;i++)表达式之前a还没有生命,int  a在for结束时也结束了;

第二个a还没声明;

在函数中子常量可以在父常量中的到声明;父不可以在子中的到;

 

1,返回函数。

int GetMin(int a,int b)

{

}

int GetMin(void){
}

2.函数体

int GetMin(int a,int b){

if(a>b)

{return b;}

else

{

return a;

}

}

不能在函数体中定义别的一个函数;

void func1()

{

int func2(int a,int b)

{}

}

是错的;

函数的声明

int GetMin(int a,int b);

void main(){

int a=10;

int b=20;

cout<<GetMin(a,b)<<endl;

}

int GetMin(int a,int b)

{

if(a>b)

{return b:}

else

{
return a;

}

}

}

可以在定义在main()之前,可以省略声明;

3,函数调用

#include<iostream>

using namespace std;

int GetMax(int a,int b)

{

if(a>b)

{

return b;}

esle

{

return b;

}

}

void main()

{

int a=10;

int b=20;

int c=GetMax(a,b);

cout<<C<<endl;

}

4,参数的值专递调用;

#include <iostream>
using namespace std;
void func(int a,int b);
void main()
{  
     int a=10;
 int b=20;
 func(a,b);
 cout<<"a="<<a<<"b="<<b<<endl;
}
void func(int a,int b)
{
 a=30;
 b=40;
 cout<<"a="<<a<<"b="<<b<<endl;
}

结果30,40

10,20

5,变量及作用域

(1)全局数据区:存放全局变量、静态数据和变量。

(2)代码区:函数。

(3)伐区;函数运行时分配的局部变量、函数参数、返回数据、返回地址。

(4)堆区:内存中剩下的空间由程序员负责申请和释放。

5,静态局部变量static int nCout;

6.变量与作用域。

(1)语句块级

void main()

{

int a=10;

if(a>0)

{int a=20: cout<<a<<endl;}

cout<<a<<endl:

}

(2)函数级

作用在于所定义的函数体里

(3)文件级

Examplel.cpp

static int a;

static int b;

Example2.cpp

statac int a;

static int b;

作用在于文件里

(4)程序级

#include<iosetream>

using namespace std;

void func();//函数声明

int a=0;

void main()

{

func();

cout<<aendl;

}

extetn int a;//声明外部变量

void func()

{

a=10;

}

7。内部函数和外部函数

外部:[extern]可以作用在其他文件里

内部:static 不可以作用在其他文件里

1,一维数组的定义

int a[6];

不能是void main(){

int size=10;

int array[size];

}常量表达式中可以包括数字常量和符号常量,不能包括变量。

可以void main()

{

const int size =10;//声明为常量

int array[zisz];

}

2,一维数组的初始化

(1)int a[10]={1,2,3,4,5,6,7,8,9,0}

(2)int [5];

a[0]=1;a[1]=2;a[2]=3;a[3]=4;a[4]=5;

3,二维数组的定义

int  a[2][3],b[3][4];

4,二维数组的初始化

int  a[2][3]={{1,2,3},{4,5,6,};

int a[2][3]={1,2,3,4,5,6};

int a[][3]={1,2,3,4,5,6};

错误有:int a[2][3];

a[2][3]={1,2,3,4,5,6}

int a[][]={1,2,3,4,5,6}

5,字符数组的定义和初始化

char c[10];

c[0]='h';c[1]='e';c[2]='l';c[3]='l';c[4]='o';c[5]='w';c[6]='o';c[7]='r';c[8]='l';c[9]='d';

char c[10]={'h','e','l','l','o','w','o','r','l','d'}

char c[11]={"helloworld"};

1,指针变量的定义

char *pc;

int *pc;

float *cp1,*cp2;

 2,指针的使用

(1)指针赋值

int a;

int *pa;

pa=&a;

int *pa1,*pa2;

pa1=&a;

pa2=pa1;

指针地址不能运算

指针的初始化

int *pa=0;

3,使用指针访问变量

#include<iostream>

void main()

{

int a=10;

int *pa=&a;定义指向变量的整数指针;

cout<<*pa<<endl;通过间接访问得到指针指向的地址数据

*pa=20;间接给指向的地址数据改写数据

cout<<*pa<<endl;

}

4  void指针

int a;

int *pa=&a;

void *pv=pa;

int *p=(int *)pv;

5.const指针

1)指向常量的指针

不能通过指针改变它指向的值,可以改变的本身的值

const int a=10;

 int *pa=&a;

const int  b=20;

pa=&b;

常量指针不能指向其他变量

const int *pa=&a;

pa=&b;//错

6,指针与数组

#include<iostream>

using namespace std;

void main()

{

cout int nsize=10;

int i;

int a[nsize]={1,2,3,4,5,6,7,8,9,0}

int *p=a;

for(i=0;i<nsize;i++)

{cout<<*p<<";";

p++;

}

for(i=0;i<nsize;i++)

{cout<<p[i]<<";";

}

cout<<end;

}

6,动态内存分配(new与delete)

#include<iostream>

using namespace std;

void main()

{

char*pc;

int *p;

pc=new char;

pi=new int(8);

*pc='a';

cout<<*pc<<endl;

cout<<*pi<<endl;

if(pc)

delete pc;

if(pi)

delete pi;

char *pstr =new char[20];

char ste[20];

strcpy(pstr,"ti is a string");

strcpy(str,"ti is a string, too);

cout<<pstr<<endl;

cout<<str<<endl;

if(pstr)

delete pstr;

}

6,引用

int a=10;

int &ra=a;

引用操作

#includes<iostream>

using namespace std;

void main(){

int a=10;

cout<<&a<<endl;//地址

int *pa=&a;

cout<<*pa<<endl;

int &ra=a;

cout<<&ra<<endl;//地址

cout<<ra<<endl;

int *&rpa=pa;

cout<<rpa<<endl;

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值