C语言数组名的理解本文中会从size of 和strlen 两个函数中进行对比理解(看鹏哥C语言进行笔记整理)intmy_strlen(charstr[])//参数部分写成数组的形式intmy_strlen(char*str)//参数部分写成指针的形式文章目录C语言数组名的理解前言size of 和strlen两个函数**size of:****strlen:**总结例一int a[] {1,2,3,4};例二char arr[] { a,b,c,d,e,f };例三char arr[] abcdef;例四char* p abcdef;例五int a[3][4] { 0 };前言size of 和strlen两个函数sizeof只关注占用内存空间的大小不在乎内存中放的是什么 sizeof是操作符 strlen是求字符串长度的关注的是字符串中的\0计算的是\0之前出现的字符的个数 strlen是库函数只针对字符串size of:作用求变量/类型/数组在内存中占的总字节大小本质操作符会把结束符\0算进去注字符串结束标志为\0strlen:作用求字符串有效字符长度本质库函数从开头数遇到\0停止不计算\0例当自编函数中用到下标left 和 right时int arr[] {“abc”};int right strlen(arr)-1;int right size of (arr) / size of (arr[0]) - 2;(因为sizeof会计算\0所以多减1)总结数组名本质是数组首元素地址但有两个例外1.size of数组名数组名表示整个数组–计算整个数组的大小单位字节2.数组名取出的是整个数组的地址例子int arr[] {0,1,2,3,4,5,6,7,8,9};printf(“%p”,arr);----------首元素地址0x12ff40 ----------printf(“%p”,arr1);-----------0x12ff44printf(“%p”,arr[0]);----首元素地址0x12ff40-----------printf(“%p”,arr[0]1);------0x12ff44printf(“%p”,arr);--------数组的地址0x12ff40-----------printf(“%p”,arr1);---------0x12ff680x12ff68-0x12ff400x2840/410个元素a[0] -- aa[0]0 -- a0*a -- a*arr -- arr[0](arr0) -- arr[0]p[0](p0)*p例一int a[] {1,2,3,4};代码如下size ofintmain(){inta[]{1,2,3,4};1.printf(%d\n,sizeof(a));//4*4 16sizeof(数组名)数组名表示整个数组计算的是整个数组的大小单位是字节2.printf(%d\n,sizeof(a0));//4/8a不是单独放在sizeof内部也没有取地址所以a就是首元素的地址a0还是首元素的地址3.printf(%d\n,sizeof(a1));//4/8这里的a是数组首元素的地址 a1是第二个元素的地址sizeof(a1)就是地址的大小4.printf(%d\n,sizeof(*a));//4*a中的a是数组首元素的地址*a就是对首元素的地址解引用找到的就是首元素 首元素的大小就是4个字节5.printf(%d\n,sizeof(a[1]));//4计算的是第二个元素所占空间的大小6.printf(%d\n,sizeof(a));//4/8a取出的是数组的地址7.printf(%d\n,sizeof(*a));//161.a----int(*)[4]a拿到的是数组名的地址类型是int(*)[4],是一种数组指针 数组指针解引用找到的是数组*a---a2.和*抵消了*a---a8.printf(%d\n,sizeof(a1));//4/8a取出的是数组的地址a--int(*)[4]a1是从数组a的地址向后跳过了一个4个整型元素的数组的大小a1还是地址是地址就是4/8字节9.printf(%d\n,sizeof(a[0]));//4/8a[0]就是第一个元素的地址10.printf(%d\n,sizeof(a[0]1));//4/8a[0]1是第二个元素的地址 大小是4/8个字节a[0]1---a[1]return0;}例二char arr[] { ‘a’,‘b’,‘c’,‘d’,‘e’,‘f’ };代码如下size ofintmain(){chararr[]{a,b,c,d,e,f};1.printf(%d\n,sizeof(arr));//6*16sizeof(数组名)2.printf(%d\n,sizeof(arr0));//4/8arr0是数组首元素的地址3.printf(%d\n,sizeof(*arr));//1*arr就是数组的首元素大小是1字节*arr--arr[0]*(arr0)--arr[0]4.printf(%d\n,sizeof(arr[1]));//1第二个元素所占内存空间大小5.printf(%d\n,sizeof(arr));//4/8arr是数组的地址是地址就是4/8个字节6.printf(%d\n,sizeof(arr1));//4/8arr1是数组后的地址7.printf(%d\n,sizeof(arr[0]1));//4/8arr[0]1是第二个元素的地址return0;}代码如下strlenintmain(){chararr[]{a,b,c,d,e,f};1.printf(%d\n,strlen(arr));随机值因为strlen计算的是\0之前所有元素个数2.printf(%d\n,strlen(arr0));随机值3.printf(%d\n,strlen(*arr));*arr--arr[0]strlen(a);--strlen(97);野指针5.printf(%d\n,strlen(arr[1]));strlen(b)--strlen(98);野指针6.printf(%d\n,strlen(arr));随机值7.printf(%d\n,strlen(arr1));随机值-68.printf(%d\n,strlen(arr[0]1));随机值-1return0;}例三char arr[] “abcdef”;代码如下sizeof和strlenintmain(){chararr[]abcdef;[a b c d e f \0]printf(%d\n,strlen(arr));//6printf(%d\n,strlen(arr0));//6printf(%d\n,strlen(*arr));//errprintf(%d\n,strlen(arr[1]));//errprintf(%d\n,strlen(arr));//6arr类型char*arr1跳过一个字节arr类型char(*)[7]arr1跳过一个数组strlen(constchar*)比喻arr客厅门牌号arr房子门牌号 数字一样范围不同 strlen只看门牌号printf(%d\n,strlen(arr1));//随机值printf(%d\n,strlen(arr[0]1));//5[a b c d e f \0]printf(%d\n,sizeof(arr));//7printf(%d\n,sizeof(arr0));//4/8printf(%d\n,sizeof(*arr));//1printf(%d\n,sizeof(arr[1]));//1printf(%d\n,sizeof(arr));//4/8printf(%d\n,sizeof(arr1));//4/8printf(%d\n,sizeof(arr[0]1));//4/8return0;}例四char* p “abcdef”;代码如下sizeof和strlenintmain(){char*pabcdef;首元素地址放到p中1.printf(%d\n,sizeof(p));//4/8首元素地址0x12ff402.printf(%d\n,sizeof(p1));//4/8第二个元素的地址0x12ff413.printf(%d\n,sizeof(*p));//1解引用第一个元素char类型4.printf(%d\n,sizeof(p[0]));//1p[0]*(p0)*p5.printf(%d\n,sizeof(p));//4/8p的指针即二级指针6.printf(%d\n,sizeof(p1));//4/8p指针后的跳过p指针7.printf(%d\n,sizeof(p[0]1));//4/8p[0]p 第二个元素地址1.printf(%d\n,strlen(p));//6首元素地址2.printf(%d\n,strlen(p1));//5第二个元素的地址3.printf(%d\n,strlen(*p));//err4.printf(%d\n,strlen(p[0]));//err5.printf(%d\n,strlen(p));//随机二级指针到\0的字符个数 上下两个随机值没有联系6.printf(%d\n,strlen(p1));//随机跳过二级指针到\0的字符个数7.printf(%d\n,strlen(p[0]1));//5p[0]preturn0;}例五int a[3][4] { 0 };代码如下size ofintmain(){inta[3][4]{0};1.printf(%d\n,sizeof(a));//3*4*4482.printf(%d\n,sizeof(a[0][0]));//4第一行第一列的元素3.printf(%d\n,sizeof(a[0]));//16a[0]是第一行这个一维数组的数组名单独放在sizeof内部a[0]表示第一个整个这个一维数组sizeof(a[0])计算的就是第一行的大小4.printf(%d\n,sizeof(a[0]));//4/8a[0]-对第一行的数组名取地址拿出的是第一行的地址5.printf(%d\n,sizeof(a[0]1));//4/8a[0]并没有单独放在sizeof内部也没取地址a[0]就表示首元素的地址 就是第一行这个一维数组的第一个元素的地址a[0]1就是第一行第二个元素的地址printf(%d\n,sizeof(a1));//4/8跳过整个二维数组6.printf(%d\n,sizeof(*(a[0]1)));//4a[0]1就是第一行第二个元素的地址*(a[0]1))就是第一行第二个元素7.printf(%d\n,sizeof(a1));//4/8a虽然是二维数组的地址但是并没有单独放在sizeof内部也没取地址 a表示首元素的地址二维数组的首元素是它的第一行a就是第一行的地址 a1就是跳过第一行表示第二行的地址8.printf(%d\n,sizeof(*(a1)));//4*416*(a1)是对第二行地址的解引用拿到的是第二行*(a1)--a[1]sizeof(*(a1))--sizeof(a[1])9.printf(%d\n,sizeof(a[0]1));//4/8a[0]-对第一行的数组名取地址拿出的是第一行的地址a[0]1-得到的是第二行的地址10.printf(%d\n,sizeof(*(a[0]1)));//16第二行的元素11.printf(%d\n,sizeof(*a));//16a表示首元素的地址就是第一行的地址*a就是对第一行地址的解引用拿到的就是第一行12.printf(%d\n,sizeof(a[3]));//16a[3]a[0]//int a 10;//sizeof(int);//sizeof(a);return0;}