【C语言笔记】关于数组的一个陷阱!

问题

两个数组元素的地址相减得到什么?

我们先看一段代码:

  1. #include <stdio.h>

  2. int main(void)

  3. {

  4. int a[]={0,1,2,3,4,5};

  5. printf("&a[0] = %d, &a[2] = %d\n", &a[0], &a[2]);

  6. return 0;

  7. }

这段代码以十进制的形式打印出第0号元素的地址和第2号元素的地址,输出结果为:

  1. &a[0] = 2686760, &a[2] = 2686768

所以, &a[2]-&a[0]的结果是8?但是,事实不是这样的!!让我们把其结果打印出来:

竟然是 2!我们把 &a[5]-&a[2]的结果输出来看看有什么规律:

陷阱

事实证明,两个数组元素的地址相减,其值并不是等于两个地址数值上的差,而是等于这两个地址之间内存单元的个数。本例中数组的类型是 int 类型,并且在 32bit 编译环境下编译,因此这里的内存单元的大小是4字节。所以本例中 &a[2]-&a[0]的值为:

  1. (2686768 - 2686760)/4

当然,若是低号元素地址减去高号元素地址,得到的结果是负数:

网上看到了一篇博客也是印证了这一点:

  1. https://blog.csdn.net/harvic880925/article/details/8953854

这是个很容易出错的问题,需要特别注意!

学以致用

我们的C语言每日一练(004)中的题目是

寻找数组元素第一次出现的位置

之前已经提供了两种方法,函数的返回值都是要寻找的元素的下标。这里可以稍微修改一下得到第三种方法,我们的第三种方法返回的是寻找的元素的指针:

  1. // 函数返回找到元素的指针

  2. int *serch(int *arr,// 已知数表的首元指针

  3. int n, // 数表中元素个数

  4. int key) // 要寻找的值

  5. {

  6. int *p;

  7. for (p = arr; p < arr+n; p++)

  8. {

  9. if (*p == key)

  10. {

  11. return p; // 返回找到元素的指针

  12. }

  13. }

  14. return NULL; // 未查找到key

  15. }

完整的验证代码为

  1. /*******************************************************************************************************

  2. ** 题 目: 同一个数组中两个元素的地址相减

  3. ********************************************************************************************************/

  4. #include <stdio.h>

  5. // 函数返回找到元素的指针

  6. int *serch(int *arr,// 已知数表的首元指针

  7. int n, // 数表中元素个数

  8. int key) // 要寻找的值

  9. {

  10. int *p;

  11. for (p = arr; p < arr+n; p++)

  12. {

  13. if (*p == key)

  14. {

  15. return p; // 返回找到元素的指针

  16. }

  17. }

  18. return NULL; // 未查找到key

  19. }

  20. // 定义一个全局数组

  21. int a[]={5,2,0,13,14,999,666, 55, 66, 88, 1, 5, 9};

  22. // 主函数

  23. int main(void)

  24. {

  25. int i, key;

  26. int *p_a;

  27. printf("The elements of array a is:\n");

  28. for (i = 0; i < sizeof(a)/sizeof(a[0]); i++)

  29. {

  30. printf(" %d",a[i]);

  31. }

  32. puts("\nPlease input the key number you want to search:");

  33. scanf("%d", &key);

  34. p_a = serch(a, sizeof(a)/sizeof(a[0]), key);

  35. printf("\nThe index of the key number %d in the array is: %d.", key, p_a-a);

  36. return 0;

  37. }

运行结果:

可见,得到的结果与我们C语言每日一练(004)中的验证结果一样。


转发、点在看就是对小编最大的支持!

(0)

相关推荐

  • C语言中数组的总结

    #目录 # 一维数组的创建和初始化 一维数组的使用 一维数组在内存中的存储 指针的初步介绍 一维数组的指针访问 二维数组的创建和初始化 二维数组的使用 二维数组在内存中的存储 二维数组的指针访问 有关 ...

  • Go 与 C 的指针

    C 和 Go 都是有指针概念的语言,这篇文章主要借这两者之间的异同来加深对 Go 指针的理解和使用. 运算符 C 和 Go 都相同: & 运算符取出变量所在的内存地址 * 运算符取出指针变量所 ...

  • 数组越界及其避免方法,C语言数组越界详解

    所谓的数组越界,简单地讲就是指数组下标变量的取值超过了初始定义时的大小,导致对数组元素的访问出现在数组的范围之外,这类错误也是 C 语言程序中最常见的错误之一. 在 C 语言中,数组必须是静态的.换而 ...

  • C/C++编程笔记:数组部分!三分钟弄懂C语言重点知识

    C或C ++中的数组是存储在连续内存位置的项目的集合,可以使用数组的索引随机访问元素.它们用于存储相似类型的元素,因为所有元素的数据类型必须相同.它们可用于存储原始数据类型的集合,例如任何特定类型的i ...

  • C语言二维数组作为函数参数?(陷阱)

    大家有构建过二维数组作为函数的参数吗?有没有遇到什么问题呢?现在,我们先来看一个函数: void func1(int **array, int m, int n) {  int i = 0, j = ...

  • 【C语言笔记】分享一个C语言测试程序模板

    前言 平时需要测试一些比较模糊的知识点,或则想要验证一些函数时,我们常常会建一个test.c文件,然后在这个文件里写我们的测试代码,测试完毕后常常会删掉该文件.下次再遇到同样的问题的时候,可能又是记不 ...

  • 如何构建自己的笔记系统?打造一个高效可复用的知识体系?

    笔记系统的构建,或者说知识体系的搭建,所使用到的工具,目前市面上比较流行的无非就是印象笔记.有道云笔记.石墨文档.幕布.Xmind.OneNote,当然还有Notion.为知笔记等等. 但不建议使用过 ...

  • 读史笔记04︱汉文帝刘恒:一个“护士”皇帝

    看历史,女人有自己的逻辑和态度 揣着对人性的怀疑,怀着对权力的恐惧,24岁的刘恒坐在了皇帝宝座上. 前往长安当皇帝的路上,他一定计算过一组数字,一组因权力而丧生的人数:高祖刘邦八个儿子,有5个或直接或 ...

  • 傅佩荣:道德经暗藏一个陷阱,很多人中招,看过才懂老子的真意

    人生的一切不过就是一句话:过去就算了.但这句话也误导了很多人-精品教材已上架国学馆~

  • 沪指突破隐藏着一个陷阱

    本人唯一行情直播群开播啦!群里每天行情直播,教你如何快速选牛股!!认准群号  631358224 声明:休市日吹牛版,纯属草根人士瞎BB,欢迎专业观点批评. 沪指8月25.28连续两个交易日在大金融. ...

  • 回顾 KARNOX 游戏椅 GINIE! 20,000日元班的新标准! | 一个陷阱博客

    赞助随着电子竞技和家庭工作的普及,对高性能电竞椅的需求不断增加.电竞椅的价格从低价的 10,000 日元左右到高价的接近 100,000 日元不等.与此同时,一家新制造商已经进入日本,生产 20,00 ...

  • 警惕白塞病:临床各学科常见的一个陷阱

    白塞病是一个看似简单,其实非常复杂的疾病.常常成为临床各个学科常见的一个陷阱,这几天总结出来,供大家参考.也敬请医学同行们补充.