C语言常量指针与指针常量

邮差的信 提交于 2019-11-28 14:41:38

常量指针,表述为“是常量的指针”,就是指向常量的指针,关键字 const 出现在 * 左边,表示指针所指向的地址的内容是不可修改的,但指针自身可变。

指针常量,表述为 "是指针的常量", 指针吱声是一个常量,关键字 const 出现在 * 右边,表示指针自身不可变,但其所指向的地址的内容是可以被修改的。

例:

                常量指针:const char* ptr = "hello"

                指针常量:char* const ptr = "hello"

    这里看关键字靠着谁近,const靠着ptr近说明就是指针常量,就是指针自身不能改变,但所指向的数据可以变;const靠着类型近,说明指针所指向的内容不可变,但指针可以变。

常量指针有两种写法:const既可以写在类型前,又可以写在类型后。如上面的例子,常量指针: char const* ptr = "hello" 也是正确的。

最后在举个例子,与迭代器经常在一起用。若希望迭代器所指向的东西不可变,则需要的是 const_iterator。例:

std::vector<int>::const_iterator iter = vec.begin();
*iter = 10; //错误,iter是常量指针
iter++;//正确,iter本身可变

若希望迭代器本身不可变,指向的内容可变,则可以这样写:

const std::vector<int>::iterator iter = vec.beign();
*iter = 10;//正确,指针常量
iter++;  //错误,指针本身不可变

指针常量定义时必须初始化,否则报编译错误,因为此时不赋值便没有机会赋值了。

下面看几个简单的例子,可以说明他们的区别:

第一个

#include <iostream>
using namespace std;
int main()
{
    char *str1 = {"hello"};
    char *str2 = {"hello world"};
    char * const ptr1 = str1;
    //指针常量--指针本身是常量,指向的地址
    //不可以变化,但是指向的地址所对应的内容
    //可以变化
    ptr1 = str2; //错误,因为这是一个指针常量
    //改变指向的地址了
    cout << *ptr1 << endl;
    return 0;
}
//编译错误 error: assignment of read-only variable 'ptr1'

第二个

#include <iostream>
using namespace std;
int main()
{
    char *str1 = {"hello"};
    char *str2 = {"hello world"};
    char * const ptr1 = str1;
    //指针常量--指针本身是常量,指向的地址
    //不可以变化,但是指向的地址所对应的内容
    //可以变化
    ptr1 = "A";
    //错误,显示内存错误,因为"hello"为常量
    //不得修改,意指指针常量中,指针不得改
    //常量也不得改
    cout << *ptr1 << endl;
    return 0;
}

第三个

#include <iostream>
using namespace std;
int main()
{
    char *str1 = {"hello"};
    char *str2 = {"hello world"};
    const char *ptr1 = str1;
    //常量指针--指向字符串常量,所指向的字符串
    //内容不能变,但是指向的地址可以变化
    //相当于在此处将前边的str1追加定义为常量
    ptr1 = str2;//正确 因为指向的地址是可以变化的
    cout << ptr1;
    return 0;
}
//输出 hello world
#include <iostream>
using namespace std;
int main()
{
    char *str1 = {"hello"};
    char *str2 = {"hello world"};
    const char *ptr1 = str2;
    //常量指针--指向字符串常量,所指向的字符串
    //内容不能变,但是指向的地址可以变化
    //相当于在此处将前边的str1追加定义为常量
    ptr1 = 'A';//错误,因为指向的地址的内容是不可以变化的
    cout << ptr1;
    return 0; 
}

相信从上面四个简单的例子可以看出他们不一样的地方吧,在这里要请大家注意一下的地方是:

指针常量的申明:const 放在*和指针名之间 Type* const   pointer;

常量指针的申明:const放在类型说明符之前 const Type*  pointer;

实际分两部分: type* 为指针 const 为常量 自由组合便成为指针常量,常量指针

常量指针、指针常量,我的判断原则是 const 和 * 的先后顺序。const在前常量指针,常量内容不可变,指针可变

*号在前,指针常量,指针不可变,内容可变

const 还可以修饰函数:

如果给以“指针传递”方式的函数返回值加 const修饰,那么函数返回值(即指针)的内容不能被修改,该返回值只能被赋给加const修饰的同类型指针。例如函数

const char * GetString(void);

如下语句将出现编译错误:

char *str = GetString();

正确的用法是

const char *str = GetString();

如果函数返回值采用 “值传递方式”,由于函数会把返回值复制到外部临时的存储单元中,加const修饰没有任何价值。

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!