数组的运算,不同类型中的 sizeof()和 strlen()的情况

sizeof(数组名)

1.括号内只有数组名,没有其他内容,即不对数组名进行运算 表示整个数组,sizeof(数组名)计算的是整个数组的大小,单位是字节
2. &数组名 &后面直接跟数组名 得到的是数组的地址 除了上面两种情况,数组名表示的都是数组首元素的地址
3.!!!数组的地址和数组首元素的地址的意义(区别)在,+1时才体现出来!!!!

strlen()

1.strlen() 求字符串的长度,遇到 \0 停止 ,\0 是停止的标志,不计入总字符串长度中 ()内放入地址 长度 字符串
2.”abcdef” 在双引号中,隐藏了一个字符 \0, 数组的地址 和 数组首元素的地址是相同, 但是因为数组中的元素 会在首元素地址的基础上,往后依次排列,所以数组的地址+1 和 数组首元素地址+1 所指向的不是同一份空间

  • 整型数组
#include<string.h>
#include<stdio.h>
int main()
{
    int a[] = { 1,2,3,4 };
    printf("%d\n", sizeof(a));      //16    sizeof() 数组名单独放在()内,求得是数组的大小,单位是字节。 数组有4个元素,每个元素都是整型,整型是4个字节
    printf("%d\n", sizeof(a + 0));  //4     括号内不是单纯的数组名,对数组名+1   表示的是首元素的地址,首元素的地址 占4个字节
    printf("%d\n", sizeof(*a));     //4     括号内除了数组名之外,还有别的操作符,所以括号内的数组名表示的不是整个数组,而是首元素的地址 *对数组名解引用,取出的是 首元素, 数组中的元素都是整型,所以是4字节
    printf("%d\n", sizeof(a + 1));  //4     括号内除了数组名之外, 进行了+1操作,所以括号内的数组名表示的是首元素的地址,首元素地址+1 表示第二个元素的地址, 地址存放在指针中,故4个字节
    printf("%d\n", sizeof(a[1]));   //4     a[1] 表示第二个元素, 因为是整型数组,所以数组中的元素都是整型,故 4个字节
    printf("%d\n", sizeof(&a));     //4     & 后面直接+数组名,表示的是整个数组的地址,  但是无论是首元素地址 还是 首元素的地址,都是地址 ,地址用指针接收,都是4个字节
    printf("%d\n", sizeof(*&a));    //16    &后面直接跟数组名,取出的是 数组的地址, 对数组的地址解引用, 取出的是数组里面的内容,即整型的 1,2,3,4 故占16个字节
    printf("%d\n", sizeof(&a + 1)); //4     &后面直接跟数组名, 取出的是 数组的地址, +1 表示跳过整个数组的地址,来到整个数组地址 的下一个地址,但是最终结果落脚到 地址 身上,所以地址的字节为4
    printf("%d\n", sizeof(&a[0]));  //4     []的优先级高于 & ,所以,取出第一个元素的地址,所以4字节   
    printf("%d\n", sizeof(&a[0] + 1));//4    优先级 []  > & > + , 表示的是取出第一个元素的地址,在第一个元素的地址的基础上+1, 即表示的是第二个元素的地址。 所以4字节 
  • 字符型数组
int main()
{
    char arr[] = { 'a','b','c','d','e','f' };
    printf("%d\n", sizeof(arr));                // 6 sizeof()  括号中只有数组名,表示的是整个数组的大小,虽然数组在下表引用符中没有定义元素个数,但是通过后面{} 可知道 元素个数有6个,有因为每个元素字符型,字符型占1个字节,所以大小是 6 
    printf("%d\n", sizeof(arr + 0));            //4  括号内除了数组名还有 +0,所以表示得是 首元素的地址,地址在32位平台上占4个字节
    printf("%d\n", sizeof(*arr));               //1   括号内除了数组名还有别的操作符 * ,所以数组名表示的是首元素的地址,对首元素的地址解引用,取出第一个元素,因为是字符型数组,所以首元素是字符,占1个字节
    printf("%d\n", sizeof(arr[1]));             //1   表示第二个元素,字符型元素,所以占1个字节
    printf("%d\n", sizeof(&arr));               //4   &后面直接跟数组名,表示的是整个数组的地址,地址在32位平台上占4个字节
    printf("%d\n", sizeof(&arr + 1));           //4   取出整个数组的地址,地址+1,结果仍是地址,故4个字节
    printf("%d\n", sizeof(&arr[0] + 1));        //4   取出第一个元素的地址,地址在+1,故4个字节
    printf("%d\n", strlen(arr));                //随机值   strlrn() 遇到\0 才会停止,题目上是字符型数组,每个元素都占1个字节,并且元素中没有\0 所以相当于数组大小未定义,会一直寻找,直到  遇见\0, 才停止,其间一共找了多少个元素,随机。 
    printf("%d\n", strlen(arr + 0));            //随机值     首元素的地址,依据首元素的地址向后寻找,一直找到\0停止, 所以是随机值
//  printf("%d\n", strlen(*arr));               //err(错误)  ??//*arr?  strlen() 是根据地址查找字符串长度的,*对数组名解引用结果拿到的是元素内容,是个值。strlen 就把97 当做是地址进行访问,造成了访问冲突。
//  printf("%d\n", strlen(arr[1]));             //err         原因同上
    printf("%d\n", strlen(&arr));               //随机值    拿出整个数组的地址,也相当于拿出首元素的地址,所以往后寻找\0,故随机值
    printf("%d\n", strlen(&arr + 1));           //随机值,但是比strlen(&arr) 小6   因为(&arr + 1),是跳过整个数组,来到元素'f' 后面的地址
    printf("%d\n", strlen(&arr[0] + 1));        //随机值      先得到a的地址, 再+1, 得到b的地址,根据b的地址向后寻找,一直找到\0停止, 所以是随机值
char arr[] = "abcdef"; 
    printf("%d\n", sizeof(arr));            //   答案不是4,答案是7!!!               4  括号中 只有数组名,表示的是整个数组的地址,地址的大小是4个字节                                                    /*7   sizeof()计算 括号中的类型或者变量的大小,与是否遇到 \0 无关,"abcdef"中隐藏了字符串结束的标志,即 \0,转义字符\0 算一个字符,所以 数组中一共有7个元素,因为每个元素都是字符型的,所以 大小为7 字节*/
    printf("%d\n", sizeof(arr + 0));        //4  括号中 除了数组名 还有运算+1 所以表示的是首元素的地址,首元素的地址+1,仍然是首元素的地址,故是4个字节
    printf("%d\n", sizeof(*arr));           //1  括号中 除了数组名 还有操作符* 所以是arr 表示的是首元素的地址, 对首元素地址解引用。拿出的是第一个元素,因为是字符型数组,所以,元素占1个字节 
    printf("%d\n", sizeof(arr[1]));         //1   取出第二个元素,元素是字符型的,所以是1个字节
    printf("%d\n", sizeof(&arr));           //4   &后面直接跟数组名,取出的是整个数组的地址,地址占4个字节
    printf("%d\n", sizeof(&arr + 1));       //4   &后面直接跟数组名,取出整个数组的地址,整个数组的地址+1,则跳过这个数组,来到数组最后一个元素 后面所指向的地址
    printf("%d\n", sizeof(&arr[0] + 1));    //4   不是&后面直接跟数组名的情况(arr[0]不是数组名!),最终结果是第二个元素的地址,故4个字节
    printf("%d\n", strlen(arr));            //6   拿到整个数组的地址,"abcdef"中隐藏了字符串结束的标志,即 \0, 遇到\0就停止,所以字符串的长度是6
    printf("%d\n", strlen(arr + 0));        //6   拿到首元素地址
//  printf("%d\n", strlen(*arr));           //err  数组名不是单独放在()中的还有操作符,所以数组名表示的是首元素的地址,对首元素地址地址进行解引用,得到a,a表示的是值97,所以错误
//  printf("%d\n", strlen(arr[1]));         //err   拿到第二个元素b,代表值98
    printf("%d\n", strlen(&arr));           //6    取出数组的地址,也就是首元素的地址,依次往后查找,所以长度是6
    printf("%d\n", strlen(&arr + 1));       //随机值   &后面直接跟数组名,所以取出的是整个数组的地址,整个数组的地址+1,来到整个数组的后面的一个地址,因为不知道地址的内容,所以不确定何时能遇到\0,故是随机值
    printf("%d\n", strlen(&arr[0] + 1));    //5       &后面不是  不是直接跟数组名, 所以取出的是第一个元素的地址,地址再+1, 取出第二个元素的地址,向后查找,故长度是5   

  • 指针类型
char *p = "abcdef";       //指针变量p,p里面存的是是首元素的地址(存的不是abcdef!!!),就说通过p指向首元素     

    printf("%d\n", sizeof(p));              //4   p是个指针变量,指向首元素的地址,32位平台上是4个字节
    printf("%d\n", sizeof(p + 1));          //4   p指向首元素的地址 +1 则指向第二个元素的地址 
    printf("%d\n", sizeof(*p));             //1    p指向首元素地址,解引用的结果是字符a  
    printf("%d\n", sizeof(p[0]));           //1    等价于 *(p+0),指向第一个元素,元素a的字节是1
    printf("%d\n", sizeof(&p));             //4    p是指针变量,能把别的变量的地址放到自己的内容里面,对&p 是把p自身的地址取出来,故4个字节
    printf("%d\n", sizeof(&p + 1));         //4    !!指向p的空间的下属空间,即跳过4个字节后的内容的地址
    printf("%d\n", sizeof(&p[0] + 1));      //4    p[0] 得到的是 元素a, 在对元素a取地址,然后+1   得到的仍然是地址,是元素b对应的地址
    printf("%d\n", strlen(p));              //6    p是指针变量 存储的内容是字符串的 首字符的地址,strlen()根据地址一直往后数,遇到\0停止
    printf("%d\n", strlen(p + 1));          //5    从b开始数
    //printf("%d\n", strlen(*p));             //err  括号中是具体的值,而不是地址,会发生访问冲突
    //printf("%d\n", strlen(p[0]));           //err   理由同上
    printf("%d\n", strlen(&p));             //随机值  从p的地址开始向后面数,直到遇到\0
    printf("%d\n", strlen(&p + 1));         //随机值
    printf("%d\n", strlen(&p[0] + 1));      //5      对第一个元素去地址 再+1得到 b的地址,然后往后数
  • 二维数组
int a[3][4] = { 0 };                      //将二维数组想象成一个一位数组,首元素就是第一行,二维数组有几行,对应一维数组就有几个元素
                                              //对于二维数组来说,数组名如果不是单独放在括号中的话,会降级    比如说sizeof(arr)->单独放在括号内,表示的是整个二维数组;  sizeof(arr+1)->数组名不是单独放在括号内,表示的是第一行的数组+1,即第二行的数组;
                                                                                                         //sizeof(arr[0])->数组名(把一行当做是一个元素,arr[1]表示二维数组的第二行,看做第二个元素,arr[3]表示二维数组的第三行,看做第三个元素),单独放在括号里,表示的是二维数组的第1行; sizeof(a[0]+1)-> 数组名不是单独放在括号内,所以 由第一行的地址 变成第一行的第一个元素的地址,+1 表示第一行第二个元素的地址。        1
    printf("%d\n", sizeof(a));               //48   数组名单独放在括号内 ,表示整个数组  整个数组 有12个i 整型元素
    printf("%d\n", sizeof(a[0][0]));         //4    第一行第一个元素
    printf("%d\n", sizeof(a[0]));            //16   第一行的数组名 ,单独放在括号里表示第一行的所有元素
    printf("%d\n", sizeof(a[0] + 1));        //4    第一行的数组名,没有单独放在括号中,第一行第一个元素的地址
    printf("%d\n", sizeof(a + 1));           //4   数组名没有单独放在括号内,要降级,表示第一行的地址,第一行的地址+1,表示第二行的第二行的地址。
    printf("%d\n", sizeof(&a[0] + 1));       //4    对第一行取地址,地址+1  表示第一行第二个元素的地址 
    printf("%d\n", sizeof(*a));              //16   !!数组名没有单独放在括号中,在一维数组表示首元素的地址,在二维数组中表示一整行的地址。 对第一行的地址解引用,就是第一行的内容
    printf("%d\n", sizeof(a[3]));            //16   表示第四行,二维数组中没有第四行的内容,但是因为操作符sizeof(),是在编译阶段进行的,程序并没有到达执行阶段,所以只是判断过程。一行有4个元素,故16字节
    system("pause");
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值