Chinaunix首页 | 论坛 | 博客
  • 博客访问: 145756
  • 博文数量: 108
  • 博客积分: 10
  • 博客等级: 民兵
  • 技术积分: 940
  • 用 户 组: 普通用户
  • 注册时间: 2012-07-15 20:24
个人简介

反反复复

文章分类

全部博文(108)

文章存档

2014年(72)

2013年(36)

我的朋友

分类: C/C++

2013-03-13 16:43:07

一:指针常量和常量指针

常量指针:常量指针就是指向常量的指针,指针所指向的地址的内容是不可修改的。

指针常量定义"const int * pi=&a;"告诉编译,*pi是常量,不能将*pi作为左值进行操作。

所以这里的指针还是一个变量,它的内容存放的是常量的地址。

例如:

定义常量指针 const int *p

定义两个整型变量int a;  int b;

把 a和b进行赋值 a=0;b=1;

这时我们把 这是我们把a 地址传给指针:p=&a;

输出指针所指向的地址:cout<<"p="<

结果:是a的地址

输出指针所指向的地址的值:cout<<"*p="<<*p<

结果:*p=0

如果这个时候想改变*p的值是不可以的

因为*p现在是一个常量是0,而p现在可以被改变,因为它是一个变量指针,指针始终指向的是地址。

于是我们可以这样做: p=&b;
                                     cout<<"p="<                                     cout<<"*p="<<*p<

结果是:*p=1,p是b的地址,在这里*p被改变了?

其实*p不能被改变是此时"直接被赋值",如果现在你想直接给它赋值是不可以的。所以常量指针不能被改变的是指针所指向的“常量”。

指针常量:指针常量就是是指针的常量,它是不可改变地址的指针,但是可以对它所指向的内容进行修改。

定义" int *const  pi=&a;"告诉编译,pi是常量,不能作为左值进行操作,但是允许修改间接访问值,即*pc可以修改。

例如:int * const ptr=NULL;

           int a=1;

           ptr=&a;//这是指针ptr 的地址就固定不变了,所能改变的就是前面的常量了,也就是指针ptr所指向的地址的值,就是1了。

这个时候我们可以直接改变它指向的常量值:*ptr=2; 

而如果这样就错了:             int b=5;

                                          ptr=&b;

因为ptr是不能被改变的。

二:函数指针和指针函数

指针函数
    当一个函数声明其返回值为一个指针时,实际上就是返回一个地址给调用函数,以用于需要指针或地址的表达式中。
    格式:
         类型说明符 * 函数名(参数)
    当然了,由于返回的是一个地址,所以类型说明符一般都是int。
    例如:int *GetDate();
          int * aaa(int,int);
    函数返回的是一个地址值,经常使用在返回数组的某一元素地址上。 

        int * GetDate(int wk,int dy);

        main()
        {
            int wk,dy;
            do
            {
                printf("Enter week(1-5)day(1-7)//n");
                scanf("%d%d",&wk,&dy);
            }
            while(wk<1||wk>5||dy<1||dy>7);
            printf("%d//n",*GetDate(wk,dy));
        }

        int * GetDate(int wk,int dy)
        {
            static int calendar[5][7]=
            {
               {1,2,3,4,5,6,7},
               {8,9,10,11,12,13,14},
               {15,16,17,18,19,20,21},
               {22,23,24,25,26,27,28},
               {29,30,31,-1}
            };
            return &calendar[wk-1][dy-1];
        }
        程序应该是很好理解的,子函数返回的是数组某元素的地址。输出的是这个地址里的值。

函数指针
    指向函数的指针包含了函数的地址,可以通过它来调用函数。声明格式如下:
        类型 (*函数名)(参数)
    其实这里不能称为函数名,应该叫做指针的变量名。这个特殊的指针指向一个返回整型值的函数。指针的声明笔削和它指向函数的声明保持一致。
        指针名和指针运算符外面的括号改变了默认的运算符。如果没有圆括号,就变成了一个返回整型指针的函数的原型声明。
    例如:
        void (*fptr)();
    把函数的地址赋值给函数指针,可以采用下面两种形式:
        fptr=&Function;
        fptr=Function;
    取地址运算符&不是必需的,因为单单一个函数就表示了它的地址,如果是函数调用,还必须包含一个圆括号括起来的参数表。
    可以采用如下两种方式来通过指针调用函数:
        x=(*fptr)();
        x=fptr();
    第二种格式看上去和函数调用无异。但是有些程序员倾向于使用第一种格式,因为它明确指出是通过指针而非函数名来调用函数的。下面举一个例子:

        void (*funcp)();
        void FileFunc(),EditFunc();

        main()
        {
            funcp=FileFunc;
            (*funcp)();
            funcp=EditFunc;
            (*funcp)();
        }

        void FileFunc()
        {
            printf("FileFunc//n");
        }

        void EditFunc()
        {
            printf("EditFunc//n");
        }

        程序输出为:
            FileFunc
            EditFunc

三:指针数组和数组指针

其实这两种写法主要是因为运算符的优先级, 因为[]的优先级比*高。所以第一种写法,p先和[]结合,所以是一个数组,后与*结合,是指针。后一种写法同理。
    指针数组如下处理就会很清楚:
    typedef int* intPtr;
    intPtr p[2]; 
    一目了然,所以为了避免迷惑,做适当的typedef也是很有必要的。
    同理,数组指针也可以作类似处理:
    typedef int intArray2[2];
    intArray2 * p;
    和原来的声明都是等价的。
    
    个人建议编程过程中采用typedef来进行类型定义,这样程序看起来会清晰很多。举个例子说明:

    数组指针,元素为指向数组的指针:)
    首先,指向数组的指针为:
    typedef intArray2* intArray2Ptr;
    然后是一个数组的元素:
    typede intArray2Ptr intArray2PtrArr3[3];
    最后数组的指针:

    intArray2PtrArr3 *p;

http://blog.csdn.net/gaoxiaowei/article/details/2814295
阅读(442) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~