理解常量指针与指针常量?

constant

*前面的是对被指向对象的修饰,*后面的是对指针本身的修饰

常量指针(被指向的对象是常量)

定义:

又叫常指针,可以理解为常量的指针,指向的是个常量

关键点:

  1. 常量指针指向的对象不能通过这个指针来修改,可是仍然可以通过原来的声明修改;
  2. 常量指针可以被赋值为变量的地址,之所以叫常量指针,是限制了通过这个指针修改变量的值;
  3. 指针还可以指向别处,因为指针本身只是个变量,可以指向任意地址; 

代码形式:

int const* p;  const int* p;
//
// Created by zhangrongxiang on 2018/3/25 22:16
// File constant4
//
#include <stdio.h>

// 常量指针(被指向的对象是常量)
int main() {
    int i = 10;
    int i2 = 11;
    const int *p = &i;
    printf("%d\n", *p);//10
    i = 9; //OK,仍然可以通过原来的声明修改值,
    //Error,*p是const int的,不可修改,即常量指针不可修改其指向地址
    //*p = 11;  //error: assignment of read-only location ‘*p’
    p = &i2;//OK,指针还可以指向别处,因为指针只是个变量,可以随意指向;
    printf("%d\n", *p);//11
    return 0;
}

指针常量(指针本身是常量)

定义:

本质是一个常量,而用指针修饰它。指针常量的值是指针,这个值因为是常量,所以不能被赋值。

关键点:

  1. 它是个常量!
  2. 指针所保存的地址可以改变,然而指针所指向的值却不可以改变;
  3. 指针本身是常量,指向的地址不可以变化,但是指向的地址所对应的内容可以变化;

代码形式:

int* const p;
//
// Created by zhangrongxiang on 2018/3/25 22:30
// File constan5
//
//指针常量(指针本身是常量)
#include <stdio.h>

int main() {
    int i = 10;
    int *const p = &i;
    printf("%d\n", *p);//10
    //Error,因为p是const 指针,因此不能改变p指向的内容
    //p++;//error: increment of read-only variable ‘p’
    (*p)++;    //OK,指针是常量,指向的地址不可以变化,但是指向的地址所对应的内容可以变化
    printf("%d\n", *p);//11
    i = 9;//OK,仍然可以通过原来的声明修改值,
    return 0;
}

指向常量的常指针

定义:

指向常量的指针常量就是一个常量,且它指向的对象也是一个常量。

关键点:

  1. 一个指针常量,指向的是一个指针对象;
  2. 它指向的指针对象且是一个常量,即它指向的对象不能变化;

代码形式:

const int* const p;
//
// Created by zhangrongxiang on 2018/3/25 22:38
// File constant6
//
#include <stdio.h>

int main() {
    int i = 10;
    const int *const p = &i;
    printf("%d\n", *p);//10
    //p++;//error: increment of read-only variable ‘p’
    //(*p)++;//increment of read-only location ‘*p’
    i++;//OK,仍然可以通过原来的声明修改值
    printf("%d\n", *p);//11
    return 0;
}

const int a / int const a

如果我们给出 const int a;你应该知道这是将a常量化了,但是为什么那?那是因为intconst都作为一个类型限定词,有相同的地位。所以你也可以写成 int const a;似乎这样更加好理解!当然这都不难,难点在哪里哪?当然此时你如果定义指针也是可以修改的,但是会报警告!当然强制类型转换后警告也不会报了!

//
// Created by zhangrongxiang on 2018/3/25 21:38
// File constant3
//
#include <stdio.h>
int main() {
    const int a;
    int const a2;
    int *pi = (int *) &a;
    *pi = 19;
    printf("%d\n", a);//19
    pi = (int *) &a2;
    *pi = 20;
    printf("%d\n", a2);//20
    return 0;
}

const修饰的变量真的不能改吗?

  • const修饰的变量其实是可以改的(前提是gcc环境下)。
  • 在某些单片机环境下,const修饰的变量是不可以改的。const修饰的变量到底能不能真的被修改,取决于具体的环境,C语言本身并没有完全严格一致的要求。
  • gcc中,const是通过编译器在编译的时候执行检查来确保实现的(也就是说const类型的变量不能改是编译错误,不是运行时错误。)所以我们只要想办法骗过编译器,就可以修改const定义的常量,而运行时不会报错。
  • 更深入一层的原因,是因为gccconst类型的常量也放在了data段,其实和普通的全局变量放在data段是一样实现的,只是通过编译器认定这个变量是const的,运行时并没有标记const标志,所以只要骗过编译器就可以修改了。

const究竟应该怎么用

const是在编译器中实现的,编译时检查,并非不能骗过。所以在C语言中使用const,就好象是一种道德约束而非法律约束,所以大家使用const时更多是传递一种信息,就是告诉编译器、也告诉读程序的人,这个变量是不应该也不必被修改的。

如何区分常量指针和指针常量

那如何区分这几类呢? 带两个const的肯定是指向常量的常指针,很容易理解,主要是如何区分常量指针和指针常量:

  • 一种方式是看 * 和 const 的排列顺序,比如

    int const* p;   //const * 即常量指针
    const int* p;   //const * 即常量指针
    int* const p;   //* const 即指针常量
  • 还一种方式是看const离谁近,即从右往左看,比如
    int const* p;   //const修饰的是*p,即*p的内容不可通过p改变,但p不是const,p可以修改,*p不可修改;
    const int* p;   //同上
    int* const p;   //const修饰的是p,p是指针,p指向的地址不能修改,p不能修改,但*p可以修改;
  1. const int p;
  2. const int* p;
  3. int const* p;
  4. int * const p;
  5. const int * const p;
  6. int const * const p;

第一种是常量整数,没什么好说的。后面五种是指针,有一个简便的办法记忆。从右往左读,遇到p就替换成“p is a ”遇到, *就替换成“point to”。比如说②,读作:p is a point to int const.p是一个指向整型常量的指针。③读作:p is a point to const int.意思跟②相同。④读作:p is a const point to int.p是一个常量指针,指向整型。⑤读作:p is a const point to int const.⑥读作:p is a const point to const int.⑤和⑥的意思相同,p都是常量指针,指向整型常量。

See

All rights reserved

原文地址:https://www.cnblogs.com/zhangrxiang/p/8647602.html

时间: 2024-10-10 23:08:18

理解常量指针与指针常量?的相关文章

10深入理解C指针之---指针和常量

该系列文章源于<深入理解C指针>的阅读与理解,由于本人的见识和知识的欠缺可能有误,还望大家批评指教. 指针作为C语言的左膀右臂,使用方便,修改容易,引用数据快速都是很有前景的应用.C语言中常量是值不能改变的量,由于在某些应用中,想要阻止没有授权的数据的修改时,就需要将指针和常量结合起来. 一.指向常量的非常量指针:指针值可以改变,但是指针解引用值不能改变 1.特征: 1).提供一种可移植的方式来声明与系统中可寻址的内存区域一致的长度 2).用作sizeof操作符的返回值的类型 3).用作内存相

常量指针与指针常量的区别(转帖)

三个名词虽然非常绕嘴,不过说的非常准确.用中国话的语义分析就可以很方便地把三个概念区分开. 一) 常量指针. 常量是形容词,指针是名词,以指针为中心的一个偏正结构短语.这样看,常量指针本质是指针,常量修饰它,表示这个指针乃是一个指向常量的指针(变量). 指针指向的对象是常量,那么这个对象不能被更改. 在C/C++中,常量指针是这样声明的: 1)const int *p; 2)int const *p; 常量指针的使用要注意,指针指向的对象不能通过这个指针来修改,可是仍然可以通过原来的声明修改,也

常量指针、指针常量、指向常量的指针常量

三个名词虽然非常绕嘴,不过说的非常准确.用中国话的语义分析就可以很方便地把三个概念区分开. 一) 常量指针. 常量是形容词,指针是名词,以指针为中心的一个偏正结构短语.这样看,常量指针本质是指针,常量修饰它,表示这个指针乃是一个指向常量的指针(变量). 指针指向的对象是常量,那么这个对象不能被更改. 在C/C++中,常量指针是这样声明的: 1)const int *p; 2)int const *p; 常量指针的使用要注意,指针指向的对象不能通过这个指针来修改,可是仍然可以通过原来的声明修改,也

C语言学习笔记 (001) - 常量指针与指针常量的区别(转帖)

三个名词虽然非常绕嘴,不过说的非常准确.用中国话的语义分析就可以很方便地把三个概念区分开. 一) 常量指针. 常量是形容词,指针是名词,以指针为中心的一个偏正结构短语.这样看,常量指针本质是指针,常量修饰它,表示这个指针乃是一个指向常量的指针(变量). 指针指向的对象是常量,那么这个对象不能被更改. 在C/C++中,常量指针是这样声明的: 1)const int *p; 2)int const *p; 常量指针的使用要注意,指针指向的对象不能通过这个指针来修改,可是仍然可以通过原来的声明修改,也

指针常量;常量指针;指向常量的指针常量

三个名词虽然非常绕嘴,不过说的非常准确.用中国话的语义分析就可以很方便地把三个概念区分开. 一) 常量指针. 常量是形容词,指针是名词,以指针为中心的一个偏正结构短语.这样看,常量指针本质是指针,常量修饰它,表示这个指针乃是一个指向常量的指针(变量). 指针指向的对象是常量,那么这个对象不能被更改. 在C/C++中,常量指针是这样声明的: 1)const int *p; 2)int const *p; 常量指针的使用要注意,指针指向的对象不能通过这个指针来修改,可是仍然可以通过原来的声明修改,也

常量指针与指针常量的区别

三个名词虽然非常绕嘴,不过说的非常准确.用中国话的语义分析就可以很方便地把三个概念区分开. 一) 常量指针. 常量是形容词,指针是名词,以指针为中心的一个偏正结构短语.这样看,常量指针本质是指针,常量修饰它,表示这个指针乃是一个指向常量的指针(变量). 指针指向的对象是常量,那么这个对象不能被更改. 在C/C++中,常量指针是这样声明的: 1)const int *p; 2)int const *p; 常量指针的使用要注意,指针指向的对象不能通过这个指针来修改,可是仍然可以通过原来的声明修改,也

【转】const int *p和int * const p的区别(常量指针与指向常量的指针)

[转]作者:xwdreamer   出处:http://www.cnblogs.com/xwdreamer 对于指针和常量,有以下三种形式都是正确的: const char * myPtr = &char_A;//指向常量的指针 char * const myPtr = &char_A;//常量的指针 const char * const myPtr = &char_A;//指向常量的常量指针 下面依次对这三种类型进行介绍. 因为*操作符是左操作符,左操作符的优先级是从右到左,对于

常量指针、指针常量、指向常量的指针常量 的区别(转帖)

转自:常量指针与指针常量的区别(转帖)  建议直接访问原网址,查看下面的评论 三个名词虽然非常绕嘴,不过说的非常准确.用中国话的语义分析就可以很方便地把三个概念区分开. 一) 常量指针. 常量是形容词,指针是名词,以指针为中心的一个偏正结构短语.这样看,常量指针本质是指针,常量修饰它,表示这个指针乃是一个指向常量的指针(变量). 指针指向的对象是常量,那么这个对象不能被更改. 在C/C++中,常量指针是这样声明的: const int *p; int const *p; 常量指针的使用要注意,指

C++ 常量指针与指针常量

一.常量指针(constant pointers):指针自身是常量,const关键字出现在星号右边.如: 1 char greeting[] = "Hello";2 char* const p = greeting; // const pointer, non-const data 二.指针常量(pointers to constants):指针所指物是常量,const关键字出现在星号左边.如: 1 char greeting[] = "Hello"; 2 cons