比较分析与数组相关的sizeof和strlen
首先,我们要清楚sizeof是C/C++中的一个操作符,其作用就是返回一个对象或者类型所占的内存字节数。
而,strlen是一个函数,函数原型为:
size_t strlen(const char *string);
strlen函数的作用是:计算给定字符串的长度,不包括'\0'在内
// 数组形如:
int a[]={,,,,};
char name[]="abcdef";
无论是整型数组还是字符数组,数组名作为右值的时候都代表数组首元素的首地址。
数组发生降级(数组名退化为数组首元素的地址)的情况:数组传参、数组名参与运算
数组名不会发生降级的情况:sizeof(数组名)、取地址数组名(取到的是整个数组的地址而不是首元素的地址)
(以下结果都经过VS2013验证)
我们先来定义两个整型数组:
int a[] = { , , , };
int p[] = { , , , };
printf("%d\n", p[]);
printf("%d\n", sizeof(p)); //
printf("%d\n", sizeof(a)); //
数组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)); // 10
printf("%d\n" , strlen(name)); // 随机值 printf("%d\n" , sizeof(name1)); // 10
printf("%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)); // 无效,不能strlen字符
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
2016-04-12 16:24:56
比较分析与数组相关的sizeof和strlen的更多相关文章
- C语言中sizeof与strlen区别
本文转载自:http://www.2cto.com/kf/201109/105100.html 1. 以字符串形式出现的,编译器都会为该字符串自动添加一个0作为结束符,如在代码中写"abc& ...
- sizeof、strlen、字符串、数组,整到一块,你还清楚吗?
写在前面 sizeof.strlen.字符串.数组,提到这些概念,相信学过C语言的人都能耳熟能详,也能谈得头头是道,但是,在实际运用中,当这些内容交织在一起时,大家却不一定能搞地清清楚楚,本文的目的正 ...
- c语言中数组相关问题
c语言中数组相关问题: 1.数组基本定义: 相同数据类型的元素按一定顺序排列的集合,就是把有限个类型相同的变量用一个名字命名,然后用编号区分他们的变量的集合,这个名字称为数组名,编号称为下标.组成数组 ...
- TSPL学习笔记(4):数组相关练习
最近研究函数式编程,都是haskell和scheme交互着看的,所以笔记中两种语言的内容都有,练习一般也都用两种语言分别实现. 本篇练习一些数组有关的问题,之所以与数组相关是因为在命令式编程中以下问题 ...
- Scala学习(三)----数组相关操作
数组相关操作 摘要: 本篇主要学习如何在Scala中操作数组.Java和C++程序员通常会选用数组或近似的结构(比如数组列表或向量)来收集一组元素.在Scala中,我们的选择更多,不过现在我们先假定不 ...
- PHP基础系列(二) PHP数组相关的函数分类整理
之前写过一篇介绍 PHP字符串函数 的博文,这里写第二篇,本文主要介绍PHP 数组相关的函数: 一.检查数组中是否存在 array_key_exists — 检查给定的键名或索引是否存在于数组中 ar ...
- c语言数组相关的计算
1.数组的创建:元素类型 数组名 [常量或者常量表达式] 如:int arr1[10];注:即使是被const修饰的变量也不能作为[]中的内容,它本质上依然属于变量,只是具有常量属性2.数组的初始化: ...
- 快学Scala习题解答—第三章 数组相关操作
3 数组相关操作 3.1 编写一段代码.将a设置为一个n个随机整数的数组,要求随机数介于0(包括)和n(不包括)之间 random和yield的使用 import scala.math.rando ...
- 粗暴,干就完了----徐晓冬似的C语言自学笔记---字符数组相关技术
字符串拼接函数 strcat() 字符串----作为很多编程语言的鼻祖C语言,没有字符串类型,取而代之的字符数组,很多数组在声明的时候会给定数组长度,然而我们却可以这样写 char mywords[] ...
随机推荐
- 微软认知服务:QnA Maker使用示例
简介 QnA Maker 从用户提供的内容(包括 FAQ URL.文档和编辑内容)中提取所有可能存在的问答对:利用易于使用的界面编辑.删除和添加问答对,然后将知识库作为 API 终结点进行发布:QnA ...
- 使用AlloyLever来搞定开发调试发布,错误监控上报,用户问题定位
传送门: # gituhbhttps://github.com/AlloyTeam/AlloyLever # 官网https://alloyteam.github.io/AlloyLever/ 下载和 ...
- php序列化&反序列化坑
一: 在php中如果我们统一编码是没有什么问题了,但是很多朋友会发现一个问题就是utf8和gbk编码中返回的值会有所区别: php 在utf8和gbk编码下使用serialize和unserializ ...
- CSS3:选择器
CSS选择器的作用是找出某类元素,以便我们使用style元素或者外部样式表对这类元素设置样式. 基本选择器 选择器 含义 演示样例 描写叙述 * 选择全部元素 * { border: thin bla ...
- sklearn函数白板
#使用make_classification构造500个样本,每个样本有20个feature from sklearn.datasets import make_classification X, y ...
- ConcurrentHashMap的使用和原理
呵呵呵,原理nmb. HashTable,HashMap,ConcurrentHashMap 当你作为一个菜鸡的时候,别人就会那这个来问你. 为什么要用ConcurrentHashMap,因为Hash ...
- 刷脸支付真的来啦!华为nova3带你玩转酷时代~
无论是不愿脱离手套的怕冷手. 或是沾满泥土芬芳的勤劳手. 还是挂着水滴的清洁手…… 每当这些时刻,打开支付宝认证支付, 指纹解锁的能力总是光彩尽失. 不过,就在华为nova 3的发布会上, 一项传说已 ...
- EasyUI分页(前台分页和后台分页)
整理一下以前的总结: 分页包括前台分页和后台分页两种,针对数据量比较小的,比如说单位,角色等,可以使用前台分页,而针对日志文件这些,需要后台分页. 先说说前台分页吧: function pagerFi ...
- win10正式版开始菜单无法打开,右边的网络连接、操作中心也打不开
问题描述: 开机后电脑键盘的win键无响应,鼠标点击菜单栏中的这几个按键也都无响应,但是点击自己固定的应用程序却没有问题,在网上查找尝试了许多资料,终于找到了一个合适的解决方案.现记录如下 解决方案: ...
- 速记const 指针与指向const的指针
指向const的指针.它的意思是指针指向的内容是不能被改动的.它有两种写法. ` const int* p; (推荐) int const* p;` 再说const指针.它的意思是指针本身的值是不能被 ...