当前位置: 首页 > news >正文

关于C语言指针几个容易混淆的概念

前言:
  大多数学习过C/C++或者正在学习的同学在对指针概念把握时,总是感觉不太明了,小弟我也不例外啊,于是翻开资料复习整理一下,并把自己的学习心得拿出来供大家分享,讨论。 基本概念掠过,主要来探讨一下容易混淆的几个概念。

1.指向常量的指针与指针常量

  a.指向常量的指针
    如const char * pStr是指向常量的指针变量,既此定义的变量是一个指向字符数组的指针变量,我们可以对其进行再次赋值,但该指针指向的地址块的值不能改变。请看  下面的例子:

char ch[5]="lisi“;
const char * pStr=ch;   //pStr 是指向字符数组的指针变量
pStr="wangwu";          //这是没有任何问题的
*pStr="w";              //此处编译时会报错,因为我们通过指向*符找到pStr所指向的内存地址块是常量所占有,所以不能再次赋值。

  指向常量的指针主要用于作为函数的参数,如定义一个画线函数:

void DrawLine(const CPoint *pt1,const CPoint * pt2){
   // .....
}

  通过参数pt1, pt2获得两个点的指针,在函数体中我们可以获取pt1->x,pt1->y,但是我们无法进行 pt1->x=3等赋值操作,从而保证了数据的一致性与安全性。

  b.指针常量
    下面我们对比性地来看指针常量 如:

char * const pStr;

    此处定义的是一个指针常量,有的教材上叫它常量指针,个人觉得还是叫它指针常量比较容易理解记忆既然是常量,在定义时初始化之后,就不能对其再赋值,但其指向的  地址块的值可以改变。

char ch[5]="lisi";
char * const pStr=ch;
pStr="zhangsan";    //错误
*pStr='w';           //正确

    由于const char * pStr与 char * const pStr外观上太相似,所以和容易弄混,我们可以通过下面的方法来记忆,但仅供参考,方便记忆而已,没有理论根据。

    首先看char * const pStr中的 const修饰的是变量名pStr,所以pStr是指针常量而const char * pStr中的const后面是(char * pStr), pStr已经被指向符 * 修饰   过,所以可以理解为const修饰的pStr所指向的地址块,该地址块为常量,所以const char * pStr是指向常量的指针变量
  如果你觉得上面讲还行,那就继续看下面的吧.

2.指针数组和指向数组的指针

  a.数组

    先我们先来探讨一下关于数组的问题,我们先定义一个数组

    char ch[4]="abc"; 

    我们可以对其进行
    *(ch+0)='e';//等价于ch[0]='e';的合法操作
    但是,接下来
    char ch2[4]="123";

    ch=ch2; //编译时会报错

    这是为什么呢?因为,数组名ch其实就是一个指向字符的指针常量,下面我们我们来做一个实验:    

#include <stdio.h>
#include <malloc.h>
static void main()
{ 
    char ch[4]="abc";
    char * const pCh=(char *)malloc(4*sizeof(char));   //申请地址空间 并将说空间首地址赋给pCh
    *(pCh+0)='a';
    *(pCh+1)='b';
    *(pCh+2)='c';
    *(pCh+3)='\0';
    printf("%s   %s",ch,pCh);
}

    如果你一眼看到char * const pCh就能说出pCh是一个指针常量的话,说明天才的你已经理解前面所讲的了,我感到万分荣幸。这个程序的结果是 :abc  abc 

    例子中 char ch[4] 与 char * const pCh=(char *)malloc(5*sizeof(char));  的效果是一样的,c内部处理上,个人认为应该也是一样的,所以说数组名本质就是就是一  个指针常量。

   b.指针数组

    很好理解 就是数组里存放的是指针 如:
    char * week[7]={"Monday","Tuesday","Wednesday","Thursday","Friday","Saturday","Sunday"}
    该数组中存放的是指向字符串的指针

  c.指向数组的指针

    如:
    int  (*p)[3];  // 注意括号可不能丢了 
    那么p就是一个指向大小为3数组的指针变量,我们知道数组名就是指针,指向数组的指针就是一个二级指针。

    int  a[][3]={1,2,3,4,5,6};
    我们知道a是一个二维数组,可以进行以下操作
    printf("%d  ",*(*(a+0)+1));
    printf("%d  ",*(a[0]+2));
    printf("%d  ",a[1][2]);
    结果分别是2  3  6
    这是因为二维数组名是二级指针常量,接下来我们的最后一个小实验

#include <stdio.h>
static void main()
{ 
    int  a[][3]={1,2,3,4,5,6};
    int  (*p)[3]=a;
    printf("%d  ",*(*(p+0)+1));
    printf("%d  ",*(p[0]+2));
    printf("%d  ",p[1][2]);
}

    将会的到同样的结果2  3  6 。

 

转载于:https://www.cnblogs.com/newcooler/p/3603969.html

相关文章:

  • 八一八android开发规范(一种建议)
  • 产品经理:想爱没那么简单
  • 进程ps、kill 、grep
  • 准确修改虚拟机名称方法
  • cacti导入Linux主机模板 Windows主机模板
  • 英文字体免费下载:10款最新的高品质字体
  • sass教程汇总
  • Mark Russinovich 的博客:Windows Azure 主机更新:原因、时间和方式
  • 分享几个响应式开发的代码小技巧
  • adb 使用体验
  • 绝美风景!20幅全球地理风光摄影欣赏【组图】
  • volatile synchronized AtomicInteger的区别
  • JSP/Servlet 获取真实IP地址
  • 已知二叉树先序和中序遍历结果,求后序遍历结果
  • jacob完成word转html功能及注意事项
  • [译]如何构建服务器端web组件,为何要构建?
  • 《Javascript高级程序设计 (第三版)》第五章 引用类型
  • CentOS从零开始部署Nodejs项目
  • emacs初体验
  • Facebook AccountKit 接入的坑点
  • java概述
  • js数组之filter
  • PHP那些事儿
  • Rancher如何对接Ceph-RBD块存储
  • 阿里研究院入选中国企业智库系统影响力榜
  • 可能是历史上最全的CC0版权可以免费商用的图片网站
  • 前端存储 - localStorage
  • 说说动画卡顿的解决方案
  • 深度学习之轻量级神经网络在TWS蓝牙音频处理器上的部署
  • # 达梦数据库知识点
  • #免费 苹果M系芯片Macbook电脑MacOS使用Bash脚本写入(读写)NTFS硬盘教程
  • (二)【Jmeter】专栏实战项目靶场drupal部署
  • (亲测)设​置​m​y​e​c​l​i​p​s​e​打​开​默​认​工​作​空​间...
  • (三分钟)速览传统边缘检测算子
  • (十一)图像的罗伯特梯度锐化
  • (一)Mocha源码阅读: 项目结构及命令行启动
  • **PHP二维数组遍历时同时赋值
  • .h头文件 .lib动态链接库文件 .dll 动态链接库
  • .NET Reactor简单使用教程
  • @JsonFormat与@DateTimeFormat注解的使用
  • @Validated和@Valid校验参数区别
  • @zabbix数据库历史与趋势数据占用优化(mysql存储查询)
  • [2013][note]通过石墨烯调谐用于开关、传感的动态可重构Fano超——
  • [ACTF2020 新生赛]Upload 1
  • [acwing周赛复盘] 第 94 场周赛20230311
  • [Android 数据通信] android cmwap接入点
  • [ANT] 项目中应用ANT
  • [c++] 单例模式 + cyberrt TimingWheel 单例分析
  • [Docker]四.Docker部署nodejs项目,部署Mysql,部署Redis,部署Mongodb
  • [ERROR] Plugin 'InnoDB' init function returned error
  • [Excel]如何找到非固定空白格數列的條件數據? 以月份報價表單為例
  • [HackMyVM]靶场 Quick3
  • [HDOJ4911]Inversion
  • [iOS]中字体样式设置 API
  • [Kubernetes]2. k8s集群中部署基于nodejs golang的项目以及Pod、Deployment详解