文章目录

  • 1 回顾--数组的本质
  • 2 指针的运算
    • 2.1 指针运算代码案例分析
  • 3 指针的比较
    • 3.1 指针运算的应用代码案例分析
  • 4 总结

1 回顾–数组的本质

在之前的文章,已经学习了数组的本质分析。下面再来回顾一下:

  • 数组是一段连续的内存空间
  • 数组名可以看做是指向数组第一个元素的常量指针

那么数组名加1的意义是什么?指针运算呢?

看一下代码:

  • 28-1.c
#include <stdio.h>int main()
{int a[5] = {0};int* p = NULL;printf("a = 0x%X\n", (unsigned int)(a));printf("a + 1 = 0x%X\n", (unsigned int)(a + 1));printf("p = 0x%X\n", (unsigned int)(p));printf("p + 1 = 0x%X\n", (unsigned int)(p + 1));return 0;
}
  • 编译运行的结果如下:

从以上的运行结果来看:

  • 数组名加1得到的结果是数组元素首地址的值,加上一个元素类型的大小。如上代码是数组首元素地址加上int类型的大小4
  • 对于指针的运算:指针是一种特殊的变量,与整数的运算规则与数组名很类似,如下图公式(指针p):

当指针p指向一个同类型的数组时:

  • p+1 将指向当前元素的下一个元素
  • p-1 将指向当前元素的上一个元素

2 指针的运算

下面两点非常重要,务必记住;

  • 指针之间只支持减法运算。其他运算例如加法是不支持的
  • 参与减法运算的指针类型必须相同

注意,指针虽然支持减法运算,但是:

  1. 只有当两个指针指向同一个数组中元素的时候,指针相减才有意义。其意义在于指针所指向元素的下标差
  2. 当两个指针所指向元素不在同一个数组中时,指针相减结果未定义。

2.1 指针运算代码案例分析

  • 代码28-2.c
#include <stdio.h>int main(){char s1[] = {'H','e','l','l','o'};int i = 0;    char* p0 = s1;  //相当于 cgar* p0 = &s1[0];char* p1 = &s1[3];    char s2[] = {'W','o','r','l','d'};char* p2 = s2;int* p = &i;printf("%d\n", p0 - p1);//printf("%d\n", p0 + p2);  //errorprintf("%d\n", p0 - p2);//printf("%d\n", p0 - p);    //error//printf("%d\n", p0 * p2);   //error//printf("%d\n", p0 / p2);   //errorreturn 0;
}
  • 编译运行结果为:
    -3
    5
  • 上述代码注释掉的部分编译会出错。说明指针不支持除减法以外的运算
  • 减法运算的意义在于指针所指向元素的下标差
  • 不是指向同一个数组元素的指针相减,结果未定义。如上面的p0-p2=5,这的结果是未定义的.

3 指针的比较

  • 指针也可以进行关系运算(<,<=,>,>=)
  • 指针的关系运算,只有在指针指向的数组元素在同一个数组内才有意义。否则虽然编译不会报错,但是没有什么意义。
  • 参与比较运算的指针类型必须相同,否则编译会给出警告。且这种比较也没有什么意义。

3.1 指针运算的应用代码案例分析

  • 28-3.c
#include <stdio.h>#define DIM(a) sizeof(a) / sizeof(*a)int main(){char s[] = {'H','e','l','l','o'};char* pBegin = s;char* pEnd = s + DIM(s);char* p = NULL;printf("pBegin = %p\n", pBegin);printf("pEnd = %p\n", pEnd);printf("Size = %d\n", pEnd - pBegin);for(p=pBegin; p<pEnd; p++){printf("%c", *p);}    printf("\n");return 0;
}
  • 编译运行结果为:

以上代码比较简单,这里就不再分析了。

4 总结

  • 数组声明时,编译器自动为其分配一片连续的内存空间
  • 指针声明时,只为指针分配了容纳地址值的4字节空间(32位系统)。这足以看出数组并不等于指针,两者差异很大
  • 指针可以和整数进行运算,其结果仍然为指针
  • 两个指向同一个数组内元素的指针的减法运算,代表数组元素的下标差
  • 指针之间的比较运算需要指针的类型相同。

【C语言进阶深度学习记录】二十四 指针与数组的本质分析一相关推荐

  1. 【C语言进阶深度学习记录】十四 C语言中 三目运算符和逗号表达式

    文章目录 1 三目运算符 1.1 三目运算符的返回类型的代码案例分析 2 逗号表达式 2.1 逗号表达式代码案例分析 2.2 如何用一行代码实现 strlen函数 3 总结 1 三目运算符 三目运算符 ...

  2. 【C语言进阶深度学习记录】十九 #pragma使用与分析

    文章目录 1 #pragma 概念简介 1.1 #pragma message 的用法 1.2 #pragma once 的用法 1.3 #pragma pack 的用法 1.31 struct占用的 ...

  3. 【C语言进阶深度学习记录】十六 静态库与动态库的创建与使用

    上一篇文章学习了编译的过程,点击链接查看:[C语言进阶深度学习记录]十五 编译过程简介,每一个C源文件编译后将会生成目标文件,那么这些目标文件,还需要链接起来,生成可执行文件. 文章目录 1 链接的意 ...

  4. 【C语言进阶深度学习记录】二十五 指针与数组的本质分析二

    文章目录 1 数组的访问方式 1.1 数组的访问方式代码分析 2 数组和指针不同 3 a 和 &a 的区别 3.1 指针运算的经典代码案例分析 4 数组作为函数的参数 4.1 数组作为函数参数 ...

  5. 【C语言进阶深度学习记录】九 C语言中const的详细分析

    文章目录 1 const的分析 2 const本质的分析实验 2.1 代码案例分析 3 const修饰函数参数和返回值时的情况 3.1 代码案例分析 4 总结 1 const的分析 不管是C语言还是C ...

  6. 【C语言进阶深度学习记录】十二 C语言中的:字符和字符串

    文章目录 1 C语言中的单引号和双引号 1.1 双引号带来的BUG 2 总结 1 C语言中的单引号和双引号 C语言中的单引号用来表示字符字面量 C语言中的双引号用来表示字符串字面量,存储于全局的只读存 ...

  7. 【C语言进阶深度学习记录】十五 编译过程简介

    文章目录 1 初识编译器 2 总结 1 初识编译器 我们平时口中所说的编译器,是广泛的编译器.实际上,编译器包括了以下四个部分: 一个C代码被编译为可执行代码,包括以下几个过程: 下面就对上述的各个过 ...

  8. 【C语言进阶深度学习记录】十 C语言中:struct的柔性数组和union分析

    本文并不讲C语言的基础 文章目录 1 空struct的大小 2 结构体与柔性数组 2.1 柔性数组的使用方法 2.2 柔性数组使用代码案例分析 3 C语言中的union分析 3.1 使用union判断 ...

  9. 【C语言进阶深度学习记录】十八 条件编译的使用与分析

    文章目录 1 基本概念 1.1 代码分析 1.2 通过命令行定义宏 2 #include 的本质 2.1 解决重复包含头文件的问题 3 条件编译的应用 4 总结 1 基本概念 条件编译的行为类似于C语 ...

最新文章

  1. AS升级3.1 编译报错:The SourceSet 'instrumentTest' is not recognized by the Android Gradle Plugin.
  2. lync 2013 企业版部署 (四)安装office web app server
  3. 在浏览器端调试代码并直接修改原文件、移动端虚拟键盘中实现搜索按钮
  4. powershell 停止正在运行的用户应用
  5. c语言handler指针,typedef与指向函数的指针结合的妙用
  6. 关于用C#编写ActiveX控件2(转)
  7. 福大软工1816:Alpha事后诸葛
  8. C++ 输入输出加速挂(ACM竞赛常用)
  9. session钝化活化
  10. Vue中axios的封装
  11. 自兴人工智能学院有话说,好机构培养好人才!
  12. System.Windows.Freezable 在未被引用的程序集中定义
  13. 已解决selenium.common.exceptions.WebDriverException: Message: unknown error: cannot find Chrome binary
  14. 北京房租大涨?6个维度,数万条数据帮你揭穿(附详情代码)
  15. Java神操作之SpringBoot基础上添加Kotlin混合开发
  16. 中国计算机科学发展,中国计算机的发展趋势
  17. java程序员在交接别人的工作时如何保证顺利交接?
  18. 【电赛】2021年全国电赛设计报告要求
  19. python接口自动化测试的两种思路
  20. Android打开蓝牙的两种方法

热门文章

  1. java面试题32:Java网络程序设计中,下列正确的描述是()
  2. PyTorch系列 | 如何加快你的模型训练速度呢?
  3. bmp怎么编辑底色_非标机械设计这个行业前景怎么样
  4. Rstudio调用plot()函数时,出现错误的处理方法
  5. nodejs+supertest+mocha 接口测试环境搭建
  6. Windows安装zookeeper 单机版
  7. UVALive4256 Salesmen
  8. bzoj3238 [Ahoi2013]差异
  9. 【APIO2015】完跪记
  10. [转]字符串匹配那些事