学习C语言时,指针的学习是比较难的一部分,常常分辨不了*p p &p 的区别。下面是摘抄别人的一段测试程序。
以下是我的一小段测试用的程序
void test(){
int a=8;
int *p=&a;
p=(int *)malloc(N*sizeof(int));
// printf( "%d/n ",*p);
//a. cout < <&p; //0x0012ff14
//b. cout < <*p; //8
c. cout < <p; //0x000431c50
}
b句输出p所指向的内存单元的值,而a语句和c语句分别输出的是什么呢?
a输出的是p本身所占内存单元的地址么?
c输出的是p所指向的内存单元的地址么?
从测试的结果很容易看出来,*P是一个指针变量,它存储的数据是地址,并且也只能存储地址,所以在给*P赋值时,请您确认等号右边的值是不是一个地址。如果不是,那么您的程序将会出现BUG,(或许您是一位优秀的汇编写手,那么请您处理好该指针变量)。
不错,正如测试者所想的,&p输出的内容是*P指针变量的内存单元地址,而指针变量本身存储的是变量a的内存单元地址;
*P您可以理解为取指向,也就是取指针变量所指向的内存单位的数据,在本例中就是a的值;
而P是一个指针变量,它能存储地址。
另外还要说明的是int *p=&a;等价于int *p ; p = &a;
如果您是用的linux系统,那么您可以测试一下下面这个程序,您能更加明白。
#include <stdio.h>
int main()
{
int a = 8 ;
int *p = NULL;
p = &a;
printf ("p is %p /n",p); //p打印出&a的值,即a的地址。
printf ("*p is %d /n",*p); //打印a的值。
printf ("&p is %p /n",&p); //打印存放指针p的地址
printf ("&a is %p /n",&a); //a的地址。
return (0);
}
应该注意的2点是:
1.给指针只能传地址,不能传值.否则要做强制类型转换.
2.在做类型转换和赋值时候,应该注意赋值的类型匹配.
指针与数组的区别:
很多初学者弄不清指针和数组到底有什么样的关系。我现在就告诉你:他们之间没有
任何关系!只是他们经常穿着相似的衣服来逗你玩罢了。
指针就是指针,指针变量在32 位系统下,永远占4 个byte,其值为某一个内存的地址。
指针可以指向任何地方,但是不是任何地方你都能通过这个指针变量访问到。
数组就是数组,其大小与元素的类型和个数有关。定义数组时必须指定其元素的类型
和个数。数组可以存任何类型的数据,但不能存函数。
既然它们之间没有任何关系,那为何很多人把数组和指针混淆呢?甚至很多人认为指
针和数组是一样的。这就与市面上的C 语言的书有关,几乎没有一本书把这个问题讲透彻,
讲明白了。
#include <stdio.h>
intmain()
{
int a[5]={1,2,3,4,5};
int *ptr1=(int *)(&a+1); //a数组是一个整体,sizeof(a)=20;&a表示数组的首地址,&a+1会相当于加20个字节长度。
int *ptr2=(int *)((int)a+1); //a强制转换为int型后,相当于整数加一,所以这只是相当于地址加了一个字节。
int *ptr3=(int *)(a+1); //这个是大家非常熟悉的了,数组a作为左值时相当于&a[0],它加一相当于加了一个数组类型的长度,即4字节(整形)。a不能作为右值。
printf("%x,%x,%x",ptr1[-1],*ptr2,ptr3);
printf("%x,%x,%x",ptr1,ptr2,ptr3);
return 0;
}