C语言指针的一些易错点
指针
指针
是一种数据类型,就像 int和 float,int 装整型数据,float 装浮点型数据,指针装地址型
数据。
C语言中的地址包括位置信息(内存编号,或称纯地址)
和它所指向的数据的类型信息
,或者说它是“带类型的地址”。
指向是什么意思?简而言之,指针变量装哪块地址,它就指向哪一块空间。指针的类型
决定着指针对存储空间的读写方式
,所以首先指针与被指对象的类型要对应
。
内存操作符“ * ”
:一个指针p
指向一个变量的地址,“ *p ”
,就是这个变量本身。p所指向的空间是什么类型( 如int ),那么 *p 就一次操作多大的内存空间( 4字节 ),或者说指针的读写单位就是多大( 4字节 )。
32位系统最大支持 4字节 指针,64位系统最大支持 8字节 指针。是指针所占空间大小,是装的地址值的空间大小,不是指针操作的空间大小。
指针指向多维数组
指针指向二维数组
二维数组有三个类型的地址:
int a[3][4];&a[0][0] ———— 元素的地址,且等价于a[0](一维数组的名字),数组名字就是首元素的首地址
&a[0] ———— 一维数组的地址,且等价于a,数组名字就是首元素的首地址
&a ———— 二维数组自身的地址a[i] ———— 二维数组的第i-1个元素,是一个一维数组,也是那个一维数组首元素的首地址
如果 a
是一维数组
,则 a[i]
代表 a 数组下标为i
的元素的存储单元。 a[i] 是一个有确定地址的存储单元
。
但如果 a
是二维数组
,则a[i]
仅为一维数组(名)
,它只是一个地址
,并不代表一个存储单元
,也不代表存储单元中的值(如同一维数组名只是一个指针常量一样)。
- 此时的 a[i] 是一维数组名,它是一维数组中起始元素 a[i][0] 的地址,指向的是 a[i][0] 这个整型数据。
- a 是二维数组名,它指向的是 a[0] 这个一维数组。
二者虽然地址相同
,但指向的数据类型
不同(基类型不同)。
如果用一个指针变量 p 来指向一个二维数组的一维数组
元素,应当这样定义:
int a[3][4] = {{0},{0},{0}};// int (*p)[4] = a; 等价于 int (*p)[4] = a[0];int (*p)[4] = a[1];
(*p)
有四个元素,每个元素为整型。也就是 p 所指向的对象是有四个整型元素的数组
,即 p 是指向一维数组
的指针。此时 p 只能指向一个包含 4 个元素的一维数组,不能指向一维数组中的某一元素。
这种情况多用于作函数参数,其他场景使用较少。
指针指向二维数组的数据元素
计算 a[i][j]
在数组中的相对位置(相对于数组起始位置的位移量/偏移量
)的计算公式为:i*c+j
,其中 c 为二维数组的列数(二维数组大小为 r×c
)
#include <stdio.h>int main()
{int a[3][4] = {{1, 2, 3, 4},{5, 6, 7, 8},{9, 10, 11, 12}};//int* p = a; // 左右类型不一致,非法操作,a==&a[0],为int(*)[4]类型//int(*p)[4] = a; // p==a==&a[0],*p==a[0]==&a[0][0],**p==a[0][0]//int* p = a[0]; // p==a[0]==&a[0][0],*p==a[0][0]//int* p = &a[0][0]; // *p==a[0][0],(i*4+j)为指针偏移量for (int i = 0; i < 3; i++){for (int j = 0; j < 4; j++){//printf("%-3d", *(*(p + i) + j) ); //int(*p)[4] = a;//printf("%-3d", *(p + (i*4+j) ) ); //int* p = a[0]; //printf("%-3d", *(p + (i*4+j) ) ); //int* p = &a[0][0]; }}return 0;
}
指针指向字符(串)
可以对字符指针变量赋值,但不能对数组名赋值
。
char* a; //定义a为字符指针变量
a = "I Love You !" //将字符串的第一个元素的地址赋给a//等价于char* a = "I Love You !";
使用字符数组时,只能采取定义数组时初始化
或逐个
对元素赋值
的方法,不能
用赋值语句对字符数组中全部元素整体赋值
。
char str[20]; //开辟20个储存字符数据的空间,并且str=str[0]的地址
str[0] = 'I'; //对字符数组元素赋值,合法
str = "I Love You !"; //数组名是地址,是常量,不能被赋值,非法
str[] = "I Love You !"; //不能用赋值语句对字符数组整体赋值,非法
指针变量的值是可以改变
的,而字符数组名代表一个固定的值
(数组首元素的地址),不能
改变。
char* a = "I Love You !";
a = a + 3;
printf("%s", a); // 输出:ove You ! 从a指向的字符开始的字符串
字符数组中的各元素
的值是可以改变的(可以对它们再赋值),但字符指针变量指向的字符串常量
中的内容是不可以被取代的(不能对它们再赋值)如:
char a[] = "China";
char* b = "Chinese";
a[2] = 'r'; //合法,r取代i
b[2] = 'e'; //非法,字符串常量不能改变
C语言指针的一些易错点相关推荐
- Go语言开发小技巧易错点100例(七)
往期回顾: Go语言开发小技巧&易错点100例(一) Go语言开发小技巧&易错点100例(二) Go语言开发小技巧&易错点100例(三) Go语言开发小技巧&易错点10 ...
- 大学C语言期末考试·选择题·易错点难点总结笔记
这是我刷的错题,然后错题知识点归纳,每一套题一个编号段 第一套题 1.%二元运算符,左结合性,左右都为整数,不能是双精度型 2.数组[0]第一个和[4]第五个, 3.字符0为NULL 4.结构体变量定 ...
- 智能指针之shared_ptr易错点05
一 shared_ptr易错点 1 慎用裸指针给shared_ptr赋值 例1 class A {public:A() {};A(int i) {m_i=i;cout<<"A&q ...
- c语言指针编程易错点,C语言中指针的一些易错点!
1.字符数组与字符串的使用 注意:数组名是指向数组首个元素的地址. 先看个例子: #include int main() { char *str = "hello"; int le ...
- 关于malloc与字符指针的一些易错点
有如下一段代码,意图把"zhongxiaoming"字符串赋值进以p为首地址的空间为15字节的内存空间,然后释放p所指向的内存,以免出现内存泄露. 该代码出现几个问题,涉及到内存的 ...
- C语言指针学习中易犯的错误
1.向null地址处copy数据 char *str = NULL; strcpy(str,"aaaaabbbbb"); 错误! NULL是操作系统保护的空间,不能往里面拷贝数据: ...
- 【C语言指针】一些易混淆的定义
int p; – 这是一个普通的整型变量 int *p; – 首先从 p 处开始,先与*结合,所以说明 p 是一个指针, 然后再与 int 结合, 说明指针所指向的内容的类型为int 型.所以 p 是 ...
- C语言一级指针(char *)易错模型分析
C语言一级指针char *易错模型分析 char *(字符串)做函数参数出错模型分析 越界 不断修改指针变量的值 你向外面传递什么 重复的错误何时休 char *(字符串)做函数参数出错模型分析 建立 ...
- c语言指针易错情况,C语言/C++从入门到精通之指针易错点总结
指针是C语言的灵魂,所以学好指针很关键,本篇主要介绍了C语言/C++从入门到精通之指针易错点总结,通过具体的内容向大家展现,希望对大家C语言/C++的学习有所帮助. 学习C语言肯定会碰到指针,指针是C ...
最新文章
- 程序员会懂的冷笑话:各大编程语言的内心独白
- 成功解决.append方法出现错误IndexError: list index out of range
- boost::hana模块在无限可迭代对象上测试 hana::index_if
- 1个工具,4个技巧,就能高效开发各种报表!
- Java无所不能的反射在Android中需要熟练的知识
- 操作系统饥饿现象_操作系统试题
- 经典SQL语句集锦(收藏版)
- _DataStructure_C_Impl:共享栈
- 拓端tecdat|tableau的骑行路线地理数据可视化
- 通过文件名快速查找电脑中的文件
- Windows下sqlmap安装方法
- EHOME协议在低功耗场景下使用介绍
- 2021-11-02 Kafka、Zookeeper的下载、打开、关闭
- android http上传,Android HttpClient上传文件(亲测,成功)
- 195-Redigo基本操作mget-mset
- dw怎么保存HTML手机可以看,【dw网页制作】如何使用Dreamweaver制作网页?如何用Dreamweaver制作个人虚拟网站?dreamweaver如何制作手机网站?...
- 如何写一份优秀的投资计划书
- 超级计算机作文230字,我想养小兔子二年级作文230字
- iOS 监听手机屏幕旋转
- 小米电视4a刷鸿蒙,小米电视4A精简系统教程
热门文章
- 实时调度算法之最低松弛度优先算法
- 给你了解你所不了解的多摩君
- Struts2 S2-016/S2-017 命令执行带回显、看web路径、getshell e...
- mysql级联删除报1451 - Cannot delete or update a parent row: a foreign key constrain
- 联想Y7000找不到蓝牙,误删了设备管理器的蓝牙解决方法
- android仿喜马拉雅APP状态栏,源码分享:高仿喜马拉雅FM
- 甲骨文开始审核 Java 许可问题:500 强企业“连夜”卸载 Oracle JDK
- 构造一个简单的操作系统内核,详解进程切换细节
- Mysql翻页查询数据重复怎么办?
- Mysql 密码忘记了,呃呃呃