首页 / 操作系统 / Linux / 比较分析与数组相关的sizeof和strlen
首先,我们要清楚sizeof是C/C++中的一个操作符,其作用就是返回一个对象或者类型所占的内存字节数。而,strlen是一个函数,函数原型为:size_t strlen(const char *string); strlen函数的作用是:计算给定字符串的长度,不包括" "在内// 数组形如: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
", p[4]);printf("%d
", sizeof(p));//20printf("%d
", 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
", sizeof(a + 0));//4因为数组名a参与运算发生了降级,变为首元素的地址,a+0依旧是首元素的地址,相当于求sizeof(&a[0]) ,而一个地址本身是四个字节int a[] = { 1, 2, 3, 4 };printf("%d
", sizeof(*a)); //4对首元素的地址进行解引用取到首元素的值,为int型printf("%d
", sizeof(a + 1));//4sizeof(&a[1])printf("%d
", sizeof(a[1])); //4数组的每个元素都是整型printf("%d
", sizeof(&a)); //4 取到整个数组的地址(地址为四个字节存储)printf("%d
", sizeof(&a + 1)); //4地址的大小为四个字节printf("%d
", sizeof(&a[0]));//4地址的大小为四个字节printf("%d
", sizeof(&a[0] + 1));//4地址的大小为四个字节printf("%d
", 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]; //定义全局性数组 系统默认初始化为" "int main(){ char name[10]; printf("%d
" , sizeof(name));// 10 printf("%d
" , strlen(name)); // 随机值printf("%d
" , sizeof(name1));// 10 printf("%d
" , strlen(name1)); // 0 system("pause" ); return 0;} 定义在全局的数组,及时你没有初始化,系统也会默认初始化为0,而name1在这里是char类型,所以编译器会自动把它初始化为" ".sizeof(name)依旧算的是数组的大小,而strlen是遇到" "就结束由于name没有初始化,strlen(name)的结果是个随机值,什么时候遇到" ",就什么时候停下来。 //***********************************************************************************// char name[] = "abcdef" ; // 6个字符还有一个" "printf("%d
" , sizeof(name[0]));// 1name[0]="a"char一个字节存储printf("%d
" , sizeof(&name));// 4取到整个数组的地址地址为四字节存储printf("%d
" , sizeof(*name));// 1 printf("%d
" , sizeof(&name + 1));// 4地址! (把整个数组都跳过去了)printf("%d
" , sizeof(name + 1)); // 4数组名参与运算降级为地址 ==> sizeof(&a[1])printf("%d
" , sizeof(name)); // 10数组的大小printf("%d
" , strlen(name)); // 6 遇到" "就结束printf("%d
" , strlen(&name));// 6 //printf("%d
", strlen(*name)); // 无效,不能strlen字符printf("%d
" , strlen(&name + 1));// 随机值 printf("%d
" , strlen(name + 1)); // 5为跳过首元素后的"bcdef"的长度 //***********************************************************************************//strlen(&name) :strlen函数一个字符一个字符跳转,直到遇到" "才结束。 这里编译器进行隐式的强制类型转换成char*,相当于在求strlen(name)strlen(&name + 1):这是一个随机值,因为&name + 1把整个数组都跳过去了,传给strlen的参数是name数组后面未可知的地址,strlen会一直走下去,直到遇到" "sizeof(*name):name发生降级,变为首元素的首地址,再解引用取到字符"a"(*name="a"),输出12016-04-12 16:24:56本文永久更新链接地址:http://www.linuxidc.com/Linux/2016-04/130284.htm