您的位置:首页 > 编程语言 > C语言/C++

深入浅出 C语言指针 一

2005-06-17 16:29 190 查看
   指针是什么? 是地址。这个大家都知道。但是理解得未必深刻。我们以一条条活生生的代码来分析。
   int *pointer;
  
声明一个指针。 pointer是一个指向Int型的指针的变量。
而变量里面的值是一个内存地址(在大部分操作系统中不是物理地址,是经过地址映射后的虚拟地址)。
而这个pointer只在程序文件(.c,.cpp)里存在,当编译成可执行文件后,它被替换成一个难看的符号,比如LLC012什么的。这点与java相反,所以C程序是没有办法反编译的。
当运行一个C程序时,操作系统分配给LLC012一块32位大小内存地址,以后你改变指针的值时,改变的就是这块内存地址的值了。
int 是指针的类型,刚才说过,指针变量占用的内存空间永远是32位,相当于一个int的大小。但是,指针是有类型的,它不是用来给指针变量本身分配内存,它是用来做什么的呢? 它是 用来寻址 的。看下面的代码。
(int*)pointer = malloc(sizeof(int) * 5);
printf("%d",*(pointer + 1));
这段代码中先申请5个int大小的内存空间,把这段内存空间的首地址付给pointer。然后打印出第2个int元素的值。
如果这里的pointer是char类型的,那么pointer+1指向的不是第2个Int,而是第一个int的中间部分。也就是说对于不同变量类型的指针来说,+1跨过的内存单元数是不同的。指针的类新也可以是自定义的结构的类型。
    与java不同,C语言的函数是不允许以引用的方式传值的,也就是说对于所有的C函数,传入的参数都是一个复制的值。
    比如这样一个交换数值的函数
void switch(int a ,int b)
{
        int c =a;
        a = b;
        b = c;
}
这个函数调用后实际上并没有交换两个参数的值,因为是传值的,而非传地址(引用)的。
 那么我们如何实现累类似引用传值的功能呢? 答案是,用指针。
void switch(int* a ,int* b)
{
        int c =*a;
        *a = *b;
      
a4dc
  *b = c;

从本质上说指针也是被复制后传到函数体内的。
我们以上面这个函数为例分析一下
函数一 :  当调用 switch(intA,intB)时
假设   :
        intA  地址  0X0000000A  值 1
        intB  地址  0X0000000B  值 2
经过复制之后实际上传入函数的是另外两个。
        a  地址  0X000000AA  值 1
        b  地址  0X000000BB  值 2
当函数执行后,intA,intB的值没变,他们从头到尾都没进入函数,进入的是他们的副本。变的是a , b的值(如下),但是函数执行结束后a , b都已经被丢弃了。没有达到预期目的。
        a  地址  0X000000AA  值 2
        b  地址  0X000000BB  值 1
函数二 :  当调用 switch(*intA,*intB)时
假设   :
        intA  地址  0X0000000A  值 0X00000A0A
        intB  地址  0X0000000B  值 0X00000B0B
              地址 0X00000A0A   值 1
              地址 0X00000B0B   值 2
当函数执行时,先复制参数,结果如下
        a  地址  0X000000AA  值 0X00000A0A
        b  地址  0X000000BB  值 0X00000B0B
  而地址0X00000A0A 和 0X00000B0A 的值没有变化
传入函数后用的都是指针变量的值,也就是说改变的是0X00000A0A 和0X00000B0B的值,而指针intA和intB的值没有变化,始终指向0X00000A0A 和0X00000B0B 所以最终达到交换数值的预期效果。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  语言 c java