常量指针与指针常量

这两个概念可以说是很容易就在C语言中弄混淆了;先列举几个例子

(1):const char* p;

(2):char* const p = a;

(3):char* p = "abc";

下面是分析:

语句(1)中定义了一个常量指针,即指向一个常量的指针,指向的内容是常量,不可修改,放在常量区的,但指针本身可以修改,即“*p = 'b'"是非法的,*p是p指向的常量的第一个字符,是个常量,不能改变的。"p = &q"这是可以的,指针可以指向不同的地址。

语句(2)中定义了一个指针常量,即指针本身是个常量,不可修改,但指针指向的内容可以修改,一开始定义时让它指向数组a,“*p = 'b'”这是可以的,但"p = &q"是非法的。

小结:const常量*指针,当const在*之前就是常量指针,而const在*之后,就是指针常量。

例如:“const char *p" 即char *p是个常量,所以内容是常量;

           “char* const p”即指针p是一个常量。

语句(3)中 “char *p” 定义的是一个指针变量p,指针字符串abc的首地址。这里特别要注意,在C语言中,(3)中定义的是一个常量字符串,它被放在静态存储区的常量区存储,而p是一个指针变量,放在栈上。如果“*p = 'b'”在编译时能通过,但在运行时就会出现错误,因为你试图去改变常量区的内容。

下面来看代码实例:

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <fcntl.h>
int main()
{
    char a[] = "ABCDE";
    char b[] = "abcde";
    char* p1 = "abcde";
    const char* p2 = "abcde";
    char* const p3 = p1;
    *p1 = 'A';                    //编译能通过,运行时发生错误,这是因为试图去改变常量区的内容
    *p2 = 'A';                    //编译不能通过,常量指针,p2指向字符串常量,内容不能被改变
     p2 = a;                      //可以,修改的是指针p2的值
    *p3 = 'A';                    //若p3指向数组a,则编译运行都能通过,如果p3指向字符指针变量p1,
                                  //那么编译能通过,运行不通过,因为试图去改变常量区的内容  
     p3 = a;                      //不可以,指针常量,指针本身是一个常量,不可以被修改
     p1 = a;                
     printf("%s\n",p3);           //abcde,p3指向指针变量p1,p1在一开始指向常量区,
                                  //此时,p1指向a,但p3仍然指向p1原来的地址
     
     return 0;
}

 总之,常量指针指向的内容不可改变,但地址可以改变,即指针可以指向别的地址;而指针常量是指指针本身不变,而内容可以修改。在这里,还需要注意两点:

(1):如果指针常量指向的是字符指针变量,那么当修改*p时,原则上能够修改,在编译时能通过,但在运行时不能通过,因为它试图去修改常量区的内容,显示是非法的。

(2):当指针常量指向一个另外一个指针时, 当这个指针指向别的内容时,那么指针常量还是指向原先的内容。例如:

char *p = "123";
char *q1 = "456";
char* const p = q;
q = p1;

下面再来说一说常量指针的应用:

在常量指针中,字符串的值不可修改,这在求字符串长度与字符串复制时是很方便的。指针可以操作,但保证了字符串的不被修改。参考代码如下:

int strlen1(const char* b)
{
    int i = 0;
    while(*b != '\0')
    {
        i++;
        b++;
    }
    return i;
}
char* strcpy1(char* p,const char* q)
{
    char* des = p;
    while((*p=*q) != '\0')
    {
        //不能试图通过改变形参的值来改变实参(即不能试图通过改变地址来改变实参),
        //指针传递传的是地址,改变其地址内的内容,也就改变了原来实参的值
        p++;
        q++;
    }
    *p = '\0';
    return des;
}



 

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值