// 形如:
int a[]={1,2,3,4,5};
char name[]="abcdef";

无论是整型数组还是字符数组,数组名作为右值的时候都代表数组首元素的首地址。

数组发生降级(数组名退化为数组首元素的地址)的情况:数组传参、数组名参与运算

数组名不会发生降级的情况:sizeof(数组名)、取地址数组名(取到的是整个数组的地址而不是首元素的地址)

(以下结果都经过VS2013验证)

我们先来定义两个整型数组:

int a[] = { 1, 2, 3, 4 };
int p[5] = { 1, 2, 3, 4 };
printf("%d\n", p[4]);
printf("%d\n", sizeof(p));        //20
printf("%d\n", sizeof(a));        //16

数组a未定义数组的大小,sizeof(a)的结果是16;数组p定义了数组的大小,sizeof(p)的结果是20,系统会默认将p[4]初始化为0;不论是a还是p,都求的是整个数组的大小

sizeof(a)其中有四个整型,一个整型4个字节,4*4=16个字节

int a[] = { 1, 2, 3, 4 };
printf("%d\n", sizeof(a + 0));    //4

因为数组名a参与运算发生了降级,变为首元素的地址,a+0依旧是首元素的地址,相当于求sizeof(&a[0]) ,而一个地址本身是四个字节

int a[] = { 1, 2, 3, 4 };
printf("%d\n", sizeof(*a));     //4    对首元素的地址进行解引用取到首元素的值,为int型
printf("%d\n", sizeof(a + 1));  //4    sizeof(&a[1])
printf("%d\n", sizeof(a[1]));   //4    数组的每个元素都是整型
printf("%d\n", sizeof(&a));     //4 取到整个数组的地址(地址为四个字节存储)
printf("%d\n", sizeof(&a + 1));         //4    地址的大小为四个字节
printf("%d\n", sizeof(&a[0]));          //4    地址的大小为四个字节
printf("%d\n", sizeof(&a[0] + 1));      //4    地址的大小为四个字节
printf("%d\n", sizeof(*&a));          //16   &a取到整个数组的地址,再解引用取到整个数组

sizeof(&a)在高版本的编译器下结果都为4,在低版本如VC6.0中为16(这或许是VC6.0的一个BUG)

分析了int型数组的情况,我们再来看看char型数组的情况:

#include<stdio.h>
#include<stdlib.h>
#include<string.h>char name1[10];         //定义全局性数组 系统默认初始化为'\0'
int main()
{char name[10];printf("%d\n" , sizeof(name));    // 10printf("%d\n" , strlen(name));     // 随机值printf("%d\n" , sizeof(name1));    // 10printf("%d\n" , strlen(name1));     // 0        system("pause" );return 0;
}

定义在全局的数组,及时你没有初始化,系统也会默认初始化为0,而name1在这里是char类型,所以编译器会自动把它初始化为"\0".

sizeof(name)依旧算的是数组的大小,而strlen是遇到"\0"就结束

由于name没有初始化,strlen(name)的结果是个随机值,什么时候遇到"\0",就什么时候停下来。 

//***********************************************************************************//char name[] = "abcdef" ;             // 6个字符还有一个"\0"
printf("%d\n" , sizeof(name[0]));    // 1  name[0]='a'  char一个字节存储
printf("%d\n" , sizeof(&name));      // 4  取到整个数组的地址  地址为四字节存储
printf("%d\n" , sizeof(*name));      // 1
printf("%d\n" , sizeof(&name + 1));  // 4  地址! (把整个数组都跳过去了)
printf("%d\n" , sizeof(name + 1));   // 4  数组名参与运算降级为地址 ==> sizeof(&a[1])
printf("%d\n" , sizeof(name));       // 10    数组的大小
printf("%d\n" , strlen(name));       // 6     遇到'\0'就结束
printf("%d\n" , strlen(&name));      // 6
//printf("%d\n", strlen(*name));     // 无效
printf("%d\n" , strlen(&name + 1));  // 随机值
printf("%d\n" , strlen(name + 1));   // 5  为跳过首元素后的"bcdef"的长度//***********************************************************************************//

strlen(&name) :strlen函数一个字符一个字符跳转,直到遇到'\0'才结束。 这里编译器进行隐式的强制类型转换成char*,相当于在求strlen(name)

strlen(&name + 1):这是一个随机值,因为&name + 1把整个数组都跳过去了,传给strlen的参数是name数组后面未可知的地址,strlen会一直走下去,直到遇到"\0"

sizeof(*name):name发生降级,变为首元素的首地址,再解引用取到字符'a'(*name='a'),输出1


转载于:https://blog.51cto.com/iynu17/1757693

比较分析与数组相关的sizeof和strlen相关推荐

  1. [cpp] 字符数组,字符指针,sizeof,strlen总结

    对于字符数组与字符指针: 1. 以字符串形式出现的,编译器都会为该字符串自动添加一个0作为结束符,如在代码中写"abc",那么编译器帮你存储的是"abc\0". ...

  2. 常见语法错误:sizeof和strlen strlen获取指针指向的数组长度

    sizeof不是函数,是一种运算符,所以使用起来不用包含库. strlen获取指针指向的数组长度: sizeof() 和 strlen()的区别,在此不做赘述,详见这位博主的内容:https://ww ...

  3. C语言中sizeof与strlen区别

    本文转载自:http://www.2cto.com/kf/201109/105100.html 1. 以字符串形式出现的,编译器都会为该字符串自动添加一个0作为结束符,如在代码中写"abc& ...

  4. 树状数组相关应用之二元变量结构体组队问题

    一维数组处理组队问题 此类问题的处理方法一般采用定一议二 POJ-1900:Moofest 思路: 树状数组 分析: 1 题目给定n头牛的听力v[i]. 现在规定两头你i和j如果要进行交流的话那么消耗 ...

  5. 树状数组相关应用之多叉树子树问题

    Poj-3321:Apple Tree 题意: 卡卡的房子外面有一棵苹果树.每年秋天,树上都会长出许多苹果.卡卡非常喜欢苹果,所以他一直在精心培育着这棵大苹果树. 这棵树有N个分叉,这些分叉由树枝相连 ...

  6. 树状数组相关应用之区间更新单点查询问题

    区间更新单点查询 树状数组的基本应用是单点更新,区间查询(例如求区间和). 鉴于树状数组的空间复杂度和时间复杂度都比线段树小 而且代码也短 所以就有大神用强大的脑洞YY出了区间修改+单点查询的树状数组 ...

  7. 树状数组相关应用之区间包含问题

    区间包含问题 对于一维区间问题一般是采用定一议二的方法 区间外包含问题:POJ-2481 对于此问题我们可以先按x升序排序(x值相同,y大的排在前面),保证之后输入的区间的左端必在之前输入区间之内,若 ...

  8. 树状数组相关应用之平面范围求和问题

    平面范围求和 此类问题实际上是树状数组推广到二维的情形 平面子矩阵求和:POJ-2352 此题是求[0–x][0–y]矩阵中除自身[x][y]外的求和 二维解法: #include <iostr ...

  9. 树状数组相关应用之逆序对问题

    求逆序对 一元逆序对问题:POJ-2299 此题本质是一个求逆序对问题,对于一个无序数列,我们按照其顺序依次输入,并在每次输入时通过树状数组对已输入数列在其后方的序列进行个数求和,即可得到逆序数(先输 ...

最新文章

  1. Typora入门(2)
  2. [20171124]手工使用Seed_Database.dfb和Seed_Database.ctl建库.txt
  3. 为炒股每天只花3元 MM从贷款上学到掌控千万
  4. Vue.js——60分钟组件快速入门(上篇)
  5. Spring再次涵盖了您:继续进行消费者驱动的消息传递合同测试
  6. 华北电力大学的计算机类专业排名,2018年华北电力大学王牌专业排行榜,考生和家长们都好好看看!...
  7. cisco2950 查看端口流量
  8. 如何使用C#操作WinAPI
  9. 光在参与介质中的传播及辐射传递方程
  10. SQL 判断表是否存在
  11. 简单实现ToolStripMenuItem(菜单栏)的单选效果
  12. 人脸识别及数据流处理
  13. PyQt4--下拉列表QComboBox
  14. 厦门大学信息计算机学院,厦门大学信息科学与技术学院计算机科学系导师介绍:刘向荣...
  15. Python 新手入门必学十大模块之一:sys 和 os
  16. Nginx nginx.conf配置文件详解
  17. CuraEngine源码编译
  18. 费解的开关 Java
  19. 在线观看视频--使用代码倍速播放
  20. 计算机电源出现问题,电源故障引起的电脑问题

热门文章

  1. office2003/2007/2010版本降低宏安全设置方法
  2. 算术运算中隐式类型转换
  3. Linux加入到Windows域 收藏
  4. 合并排序(C语言实现)
  5. 外部样式表声明的样式并不会进入style对象
  6. Android Eclipse之Git插件安装、配置、提交、修改、冲突、查看历史、覆盖。
  7. redis 常用配置
  8. 兰戈 —— Rango
  9. 条件注释判断浏览器!--[if !IE]!--[if IE]!--[if lt IE 6]!--[if gte IE 6]
  10. mysql数据库主从同步过程详述(三)