朗朗空间

我知道并不是 所有鸟儿都飞翔

  C++博客 :: 首页 :: 联系 :: 聚合  :: 管理
  16 Posts :: 0 Stories :: 6 Comments :: 0 Trackbacks

常用链接

留言簿(1)

我参与的团队

搜索

  •  

最新随笔

最新评论

阅读排行榜

评论排行榜

1.指针变量的声明和初始化
指针就是把内存地址做为其值的变量。
(1)指针是一个变量
(2)普通变量直接引用了一个值
如:

int a = 3;

那么a的值就是3。
(3)指针变量只存放内存地址
(4)指针存放的内存地址往往存放有实际的值,但也可能是另外一个指针
如:

int a = 3;
int * aptr = &a;//把a的地址通过取地址运算符赋给指针变量 aptr
printf ("%p", aptr);//打印出指针的值,用16进制的方式
printf ("%p", &a);//打印出a的地址,用16进制的方式

(5)指针变量名间接应用了一个值,我们使用间接引用运算符来取得具体的值
printf (”%d”, *aptr);

(6)指针必须初始化,可以把指针初始化为NULL
NULL在中定义,它的值是0
使用NULL使程序具有可读性。

注意:
& 取地址运算符 取得任何变量的地址
如:

int a;
int *aptr;
int c[5];
//使用&运算符取得地址,并打印出来
printf ("%p\n", &a);//取得整型变量a的内存地址
printf ("%p\n", &aptr);//取得指针变量aptr的内存地址
printf ("%p\n", &c[0]);//取得数组第一个元素的内存地址

* 比较让大家迷惑的是它在这里有两种不同的用法,但实际上它们并不是同样的
(1)和具体的数据类型一起构成对应的指针类型
*在声明语句表示变量是一个指针

int *
float *
char *
double *

(2)间接引用运算符

int a = 3;
int * aptr = &a;//把a的地址通过取地址运算符赋给指针变量 aptr
 
printf ("%d", *aptr);//通过a的地址间接引用变量a的值

思考:
仔细分析下面的语句的结果。

int a = 8;
int * aPtr;
aPtr = &a;
 
printf ("%p\n", & * aPtr);
printf ("%p\n", * & aPtr);

提示,一层层分析,可以看做 &(*aPtr)
答案在最下面。

二、指针的传引用调用
1.C语言中所有的函数都是传值调用
为什么,难道指针不是传引用调用吗?
不是,C语言只是把指针的值拷贝一份,传如函数内部。
2.那么传递数组呢?

void printArray (int *nPtr);

void printArray (int array[]);

的效果都是一样的,都是传一个地址进去。
另外,要注意:
数组名本身就是地址。
3.指针的传引用调用我们也可称之为模拟传引用调用,因为我们传的是一个地址,
函数调用时,函数的参数会拷贝这个地址,然后通过复引用来操作变量。

int cubeByReference (int * nPtr)//计算立方
{
    *
nptr = *nptr * *nptr * *nptr;
}

注意这里,
(1)*(复引用运算符)比*(乘法运算符)优先级要高。
所以可以不适用括号,但是推荐你使用下面的语句,这样程序更加清晰。
(2)nPtr是占用堆栈的,函数cubeByReference会给nPtr这个指针变量分配空间,
然后把传入的指针变量的值赋给它。

int cubeByReference (int * nPtr)//计算立方
{
    
(*nptr) = (*nptr) * (*nptr) * (*nptr);
}

4.传值为什么不改变传入变量的值
因为它是在堆栈中生成一个新的变量,然后把存放的值拷贝过来,最后函数结束的时候把该变量从堆栈中释

放掉,所以并不会改变传入变量的值。
就像你用一张新的纸把一张纸上的东西复制一遍,然后在新的纸上写写画画,然后丢掉,并不会影响到原来

的纸上的内容。
5.传指针(也就是传引用为什么会改变)
因为指针给出了原来变量的地址,使得*(复引用指针)可以通过这个地址找到这个变量并对它进行修改。

三、指针的const限定
(1)指向非常量数据的非常量指针

int a;
int b;
int *aPtr;
aPtr = &a;//OK
aPtr = &b;//OK
*
aptr = 3;//OK

(2)指向常量数据的非常量指针(不能修改指向变量中的数据)

const int * aPtr;

注意:const 修饰int

int a;
int b;
const int *aPtr;
aPtr = &a;//OK
aPtr = &b;//OK
*
aptr = 3;//ERROR 不能修改指向的变量中的数据

(3)指向非常量数据的常量指针(不能东指西指)

int * const aPtr;

注意: const 修饰指针变量 aptr;
数组名是一个很好的例子。(参见字符串数组中的说明。)

int a;
int b;
const int *aPtr = &a;
aPtr = &b;//ERROR  不能再指向另外一个变量
*
aptr = 3;//OK

(4)指向常量数据的常量指针(不能修改指向变量中的数据,不能东指西指)
const int * const aPtr;

int a;
int b;
const int * const aPtr = &a;
aPtr = &b;//ERROR  不能再指向另外一个变量
*
aptr = 3;//ERROR  不能修改指向的变量中的数据

答案:
1.实际上*aPtr相当于a, &*aPtr就取得a的地址
2.&aPtr取得aPtr的直至,而*&aPtr就取得aPtr存放的值,也就是a的地址
3.&*会相互抵消,实际上&*aPtr == aPtr == *&aPtr

posted on 2008-05-21 22:35 聂元朗 阅读(446) 评论(0)  编辑 收藏 引用 所属分类: C语言学习笔记

只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   博问   Chat2DB   管理