再论指针

(1)平常的调用如果传递的是指针参数的话.比如

void a (int * a)
{
  *a = 3;   //这样则改变了参数的值.
}

因为a代表的是实参中的地址, 改变*a就代表改变实参地址中的值..

但是
void a(int *a)
{
  int i = 2;
  int* t = &i;
  a = t;
}

这样是不会改变的..这样只是改变了指针形参a的指向.注意"形参"两个字..因为当进行函数调用时,都要

进行一次隐含的参数拷贝.其实该参数展开后是这样.
void a(int *a)
{
  int* temp = a;
  int i = 2;
  int *t = &i;
  temp = t; 
}

看到了吧..改变的只是temp的指向..由于temp和i, *t都是临时变量存储于栈上,在函数结束时,系统自动

回收.所以*a的值是不会改变的. 第一种形式中.展开后依然是.


void a (int * a)
{
  int* t = a;
  *temp = 3;  
}
即使是临时变量..但*temp和*a指向的却是同一个地址,因此该变量值是确定的..就是实参的值..所以能改

变其值.

PS:
指针其实是个神秘的东西,它不像一般变量,简单赋值..指针指向的是变量的内存地址,想想,如果一个指针

指向一块变量的首地址,但是这块首地址由于某种原因,被释放掉了,那该指针就变得没用了,也就是所谓的

野指针了..所以指针是灵活使用的.对其赋值后,要同时关注被赋值的那个变量的值..所以C++推出了const

指针.

const <typename T> *p //该指针是一个常量指针,即一旦指针被赋值后,被赋值的那个必须是常量,而且不能

改变,但是指针却能指向其他变量.

<typename T>* const p//该指针是一个指针常量,即指针只能被赋一次值,但赋值后被指向的变量的值可以改

变.

 

更复杂一些的例如:
struct m
{
  int d;
  int c;
};
void a( m* a)
{
   a->d = 2;
   a->c = 4;
}
展开后其实就是
void a(m* a)
{
  m *temp = a;
  temp->d = 2;
  temp->c = 4;   //始终未改变指针的指向..所以*temp和*a其实指向同一块内存区域.因此能操纵同一

变量来达到改变其值的目的.
}


当指针作为数组首地址传递时(平时也可以这么用),指针可以作为数组名来使用
void a(int* p)
{
  for( int i = 0; i< 5; i++)
  cout << a[i] << endl;
}

void a(int* p)
{
  int* temp = p;
  for( int i = 0; i< 5; i++)
  cout << temp[i] << endl;  //同理,未改变指向.
}


(2)

现在再回首看第二种形式,我们再引出来一个新概念,即指向指针的指针.int**p.
void a(int *a)
{
  int i = 2;
  int* t = &i;
  a = t;
}
如果真想改变指针a的值,要怎么做呢.很简单..因为现在是值传递,不要以为指针传递都是传地址,虽然,指

针的值是地址,但是自己也提到了,是指针的"值"啊!!! 所以就是值传递了..呃..
上面的函数展开后其实是这样:
void a(int *a)
{
   int *temp = a;
   int i = 2;
   int *t = &i;
   temp = t;   //临时变量temp销毁..参数值不变..
}

如果现在改成这样定义.
void a(int** a)
{
  int i = 2;
  int *t = &i;
  *a = t;
}

然后在调用时
int main()
{
  int i = 3;
  int* p1 = &i;
  int** pp = &p1;
  a(pp);

  cout << *p<< endl;

  return 0;
}

没错, 这样就会改变p1的值了..将上面的函数展开.

void a(int** a)
{
  int **temp = a;  //同时指向同一块内存地址..即指针p1的地址.
  int i = 2;
  int *t = &i;
  *temp = t;    //现在*temp表示p1所指向的变量的地址...
} //这样一般是不对的,因为在函数结束时,临时变量i销毁,所以该块内存已经没有...最好就是在参数中传递数组的首地址,然后将数组中的地址做为返回值返回..

但是,上面的函数仅仅是改变了指针p1的指向,但却不能改变变量i的值..因为在函数调用时:
a 中装的指针p1的地址
*a中装的是i的起始地址
**a中装的才是变量i的值..

对*a的修改就是对指针p1的内容的修改...
如果想改变变量i的值,修改**a就行了..

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章