指针

指针是一种数据类型,就像 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语言指针的一些易错点相关推荐

  1. Go语言开发小技巧易错点100例(七)

    往期回顾: Go语言开发小技巧&易错点100例(一) Go语言开发小技巧&易错点100例(二) Go语言开发小技巧&易错点100例(三) Go语言开发小技巧&易错点10 ...

  2. 大学C语言期末考试·选择题·易错点难点总结笔记

    这是我刷的错题,然后错题知识点归纳,每一套题一个编号段 第一套题 1.%二元运算符,左结合性,左右都为整数,不能是双精度型 2.数组[0]第一个和[4]第五个, 3.字符0为NULL 4.结构体变量定 ...

  3. 智能指针之shared_ptr易错点05

    一 shared_ptr易错点 1 慎用裸指针给shared_ptr赋值 例1 class A {public:A() {};A(int i) {m_i=i;cout<<"A&q ...

  4. c语言指针编程易错点,C语言中指针的一些易错点!

    1.字符数组与字符串的使用 注意:数组名是指向数组首个元素的地址. 先看个例子: #include int main() { char *str = "hello"; int le ...

  5. 关于malloc与字符指针的一些易错点

    有如下一段代码,意图把"zhongxiaoming"字符串赋值进以p为首地址的空间为15字节的内存空间,然后释放p所指向的内存,以免出现内存泄露. 该代码出现几个问题,涉及到内存的 ...

  6. C语言指针学习中易犯的错误

    1.向null地址处copy数据 char *str = NULL; strcpy(str,"aaaaabbbbb"); 错误! NULL是操作系统保护的空间,不能往里面拷贝数据: ...

  7. 【C语言指针】一些易混淆的定义

    int p; – 这是一个普通的整型变量 int *p; – 首先从 p 处开始,先与*结合,所以说明 p 是一个指针, 然后再与 int 结合, 说明指针所指向的内容的类型为int 型.所以 p 是 ...

  8. C语言一级指针(char *)易错模型分析

    C语言一级指针char *易错模型分析 char *(字符串)做函数参数出错模型分析 越界 不断修改指针变量的值 你向外面传递什么 重复的错误何时休 char *(字符串)做函数参数出错模型分析 建立 ...

  9. c语言指针易错情况,C语言/C++从入门到精通之指针易错点总结

    指针是C语言的灵魂,所以学好指针很关键,本篇主要介绍了C语言/C++从入门到精通之指针易错点总结,通过具体的内容向大家展现,希望对大家C语言/C++的学习有所帮助. 学习C语言肯定会碰到指针,指针是C ...

最新文章

  1. 程序员会懂的冷笑话:各大编程语言的内心独白
  2. 成功解决.append方法出现错误IndexError: list index out of range
  3. boost::hana模块在无限可迭代对象上测试 hana::index_if
  4. 1个工具,4个技巧,就能高效开发各种报表!
  5. Java无所不能的反射在Android中需要熟练的知识
  6. 操作系统饥饿现象_操作系统试题
  7. 经典SQL语句集锦(收藏版)
  8. _DataStructure_C_Impl:共享栈
  9. 拓端tecdat|tableau的骑行路线地理数据可视化
  10. 通过文件名快速查找电脑中的文件
  11. Windows下sqlmap安装方法
  12. EHOME协议在低功耗场景下使用介绍
  13. 2021-11-02 Kafka、Zookeeper的下载、打开、关闭
  14. android http上传,Android HttpClient上传文件(亲测,成功)
  15. 195-Redigo基本操作mget-mset
  16. dw怎么保存HTML手机可以看,【dw网页制作】如何使用Dreamweaver制作网页?如何用Dreamweaver制作个人虚拟网站?dreamweaver如何制作手机网站?...
  17. 如何写一份优秀的投资计划书
  18. 超级计算机作文230字,我想养小兔子二年级作文230字
  19. iOS 监听手机屏幕旋转
  20. 小米电视4a刷鸿蒙,小米电视4A精简系统教程

热门文章

  1. 实时调度算法之最低松弛度优先算法
  2. 给你了解你所不了解的多摩君
  3. Struts2 S2-016/S2-017 命令执行带回显、看web路径、getshell e...
  4. mysql级联删除报1451 - Cannot delete or update a parent row: a foreign key constrain
  5. 联想Y7000找不到蓝牙,误删了设备管理器的蓝牙解决方法
  6. android仿喜马拉雅APP状态栏,源码分享:高仿喜马拉雅FM
  7. 甲骨文开始审核 Java 许可问题:500 强企业“连夜”卸载 Oracle JDK
  8. 构造一个简单的操作系统内核,详解进程切换细节
  9. Mysql翻页查询数据重复怎么办?
  10. Mysql 密码忘记了,呃呃呃