C 指针&&表达式&&常量

来源:互联网 发布:java读取文件Textfile 编辑:程序博客网 时间:2024/05/21 22:44

一、指针


        在计算机语言中,由于通过地址能找到所需的变量,可以说地址指向该变量单元,因此把地址形象的称为‘指针’,意思是能通过它来找到以它为地址的内存单元。


1.1、指针&&变量

        指针变量与普通变量一样,使用之前不仅要定义说明而且必须要赋具体的值,未经赋值的指针变量不能使用;可以对指针变量初始化为NULL,但是不能对值为NULL的指针变量解引用。

    如下定义一个指针变量p指向a,这样就可以通过p访问a并对a进行操作

int a=0;int *p=NULL;p=&a;*p=10;

        指针变量有很多类型,比如int *、char*、float*、void*等等。每种类型的指针可以访问的内存大小不同,如果要访问int类型数据只能使用int*类型指针,以此类推。


    void*类型指针,不能对该类型指针进行算法操作,如++和解引用,这是因为void*指向的内存的大小不确定。既然这样,那么void*类型指针到底有什么用呢?


    在某些时候,为了提高效率,我们需要一个函数既可以处理int类型,又可以处理char类型,还可以处理其它类型数据,这个时候void*类型就非常有必要了。典型的如内存操作函数。

void * memcpy(void *dest, const void *src, size_t count);

#include <stdio.h>#include <stdlib.h>void*my_memcpy(void*dest, void const*src, size_t count){  char*pdest = (char*)dest;  char*psrc = (char*)src;  while (count--)  {*pdest++ = *psrc++;  }  return dest;}int main(){  int i = 0;  int arr[20] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };  my_memcpy(arr + 3, arr, 16);  for (i = 0; i < sizeof(arr) / sizeof(arr[0]); i++)  {printf("%d  ", arr[i]);  }  printf("\n");  system("pause");  return 0;}

        上述代码可以实现数组的移动,移动大小以字节来记。但是memcpy()不处理内存重叠的情况,如果想处理内存重叠应该使用memmove().


        上述内容使用的都是一级指针变量,其实还有二级、三级等等指针变量。我们现来看一下二级指针变量,其它以此类推。

int a=10;int *pa=&a;int *ppa=&pa;

        指针变量ppa就是一个二级指针变量。上述代码形成的指向关系如下图所示:

    变量pa保存的是a的地址,变量ppa保存的是pa的地址;我们可以通过*pa来访问a,同样我们可以通过*ppa来访问pa,那么我们就可以通过 **ppa访问a。也就是说 **ppa就是a,我们可以通过它来操作a。

 


1.2、指针&&常量

        一个常量的地址没有任何意义,我们要讨论的是const修饰的指针。const修饰的指针变量时,这个指针变量便具有了常属性。

   

     1.2.1常量指针

int main(){    int a=10;    int const *pa=&a;//pa指向的内容不可改    const int *pa=&a; //const放到int左边和右边修饰的都是*pa    return 0}

        pa是一个常量指针,const限制了通过这个指针修改变量的值,如果对pa进行 *pa=20;操作,这时编译器会报错,因为const修饰*pa

但是,这并不意味着a不可改,只是不能通过*pa来改而已。我们可以进行如下操作来修改a的值。

int *p=&a;*p=20;

   

    1.2.2指针常量

int main(){    int b=10;    int *const pb=&b;    return 0;}

        pb是一个指针常量,指针常量的值是指针,这个值因为是常量,所以它不能被修改.此时pb是一个指针常量,不能在指向其它的变量。如进行以下操作是非法的。

int _b=15;pb=&_b;

        虽然pb不可改,并不是说pb指向的内容不可改,如*pb=30;这是可以的。

        const 修饰的局部变量仅仅是语法上不可改,其实通过其它变量可以将pb的值改掉,一个指向pb的二级指针,如:

int *ppb=&pb;*ppb=(int*)0x0018ff44;

        

    但是,要注意的是const修饰的全局变量,不管通过什么方法都不可改。因为const修饰的全局变量被存到了只读数据区。  



    1.2.3指向常量的指针常量

    

int main(){    int c=10;    const int *const pc=&c;    return 0;}

        pc是一个指向常量的指针常量,pc是指针常量,指向的内容也是一个常量,即pc不可改,*pc也不可改。 同样这些并不意味着c的值不可改,只是不能通过*pc来改而已;pc不可改也仅仅是语法上的不可改,如想修改请参照1.2.2。


1.3、指针表达式与运算


        不进行运算的指针变量是没有太大的意义的,要使用指针变量进行运算就要知道指针运算的结果和表达式的值。如下所示:

char ch='a';char cp=&ch;

1.4、使用指针注意事项


  • 不能对一个未初始化的指针解引用;

  • 不能对一个NULL指针进行解引用;

  • 不能向函数传递NULL指针;

  • 不能对void*类型指针++和解引用;


本文出自 “牛丽” 博客,请务必保留此出处http://15129279495.blog.51cto.com/10845420/1739462

0 0
原创粉丝点击