sizeof和strlen求类型中以及指针中地址和元素所占用的字节

1.sizeof和strlen

sizeof是操作符
sizeof计算操作数计算的是所占空间的大小,单位是字节,不关注内存中所存放的是什么数据,只关注空间有多大。
要知道每个类型的地址所占空间是不同的
在这里插入图片描述

可以看到我们可以用sizeof求一下各类型所占的字节

了解这些根据我们对指针的了解和sizeof开始做这些练习

1.sizeof练习

int a[] = {0, 1, 2, 3};
    // 32位平台与64位平台占用字节不同,32位机器占4个字节,64位为8个字节
    printf("%d\n",sizeof(a));// sizeof求的是整个数组大小为16字节
    printf("%d\n",sizeof(a+0));//这里a+0表示首元素地址,所以为一个地址大小为4/8个字节
    printf("%d\n",sizeof(*a));//a是首元素地址,*a是对首元素进行解引用,计算的是首元素的大小(int类型)如果单有一个a的sizeof取的是整个数组的空间大小)
    printf("%d\n",sizeof(a+1));//a+1为首元素地址+1为跳过后的第二个地址大小,第二个首元素地址字节为4/8
    printf("%d\n",sizeof(a[1]));//0为首元素,第二个元素的大小4个字节
    printf("%d\n",sizeof(&a));//取地址a为取出数组的地址,都是地址,单位是4/8个字节
    printf("%d\n",sizeof(*&a));//取地址a为取数组的地址,*&a相当于拿到了整个数组,计算的是整个数组的大小单位是16
    //*&两个在一起的话因为一个是取地址,然后解引用,互相抵消,还是数组a,整个数组的大小,单位是16
    printf("%d\n",sizeof(&a+1));//取数组地址+1跳过整个数组,还是地址,是地址单位为4/8个字节
    //因为&a[0]=a;两个都是取的数组首元素的地址他们的类型为int*
    //而&a来说它是数组的地址,不是单一的地址,类型为指针数组int(*)[4]
    printf("%d\n",sizeof(&a[0]));//地址为首元素的地址,单位为4/8个字节
    printf("%d\n",sizeof(&a[0]+1));//&a[0]为首元素地址+1跳过首元素地址为第二个元素地址,还是4/8个字节
    char a[] = "abcdef";//  a b c d e f '\0'
    printf("%zd\n", sizeof(a));//sizeof为整个数组大小加'\0'为7字节
    printf("%zd\n", sizeof(a+0));//a+0位首元素地址+0,单位为4/8字节
    printf("%zd\n", sizeof(*a));//*a为首元素地址解引用为首元素,首元素的字符为1个字节
    printf("%zd\n", sizeof(a[1]));//a[1]为第二个元素,元素占用1字节
    printf("%zd\n", sizeof(&a));//取地址a为数组的地址,数组地址也是地址占用4/8字节
    printf("%zd\n", sizeof(&a+1));//取地址a+1为整个数组地址+1,跳过整个数组占用4/8个字节
    printf("%zd\n", sizeof(&a[0]+1));//取地址a[0]为首元素地址+1指向第二个元素地址,单位4/8个字节
char 类型的元素大小为1个字节
    char a[] = {'a','b','c','d','e','f'};
    printf("%d\n", sizeof(a));//因为a是整个数组,占6个字节
    printf("%d\n", sizeof(a+0));//因为a为首元素地址,a+0还是首元素地址,占用4/8个字节
    printf("%d\n", sizeof(*a));//*a为数组的首元素,占用1个字节
    printf("%d\n", sizeof(a[1]));//a[1]为第二个元素,占用1个字节
    printf("%d\n", sizeof(&a));//取地址a为整个数组的地址,为4/8个字节
    printf("%d\n", sizeof(&a+1));//取地址a为整个数组的地址+1,跳过整个a数组,还是地址也是4/8字节
    printf("%d\n", sizeof(&a[0]+1));//取地址a[0]为首元素地址+1为第二个地址,占4/8个字节
    return 0;

2.strlen练习

strlen是库函数需要包含头文件string.h
strlen需要求得从’\0’之前的所有字符长度,字符串必须要要有***’\0***’,只有找到’\0’才会停止,否则导致会越界
strlen函数的参数为strlen(const char* str)当数组穿参后会强制转换为(const char* str)类型,因为传入的是首元素的地址,

    char a[] = {'a','b','c','d','e','f'};
    printf("%zd\n", strlen(a));//这里的a代表的是首元素地址,从a开始寻找到'\0'停止,为随机值无法预测
    printf("%zd\n", strlen(a+0));//a+0还是从从首元素寻找,知道遇到'\0'停止,为随机值无法预测
    printf("%zd\n", strlen(*a));//*a首元素,首元素解引用为'a',ASICC码值为97,97传给strlen,97作为地址来统计字符串长度,空间不一定属于当前的程序,会引发异常
    printf("%zd\n", strlen(a[1]));//a[1]也是输入的元素不是地址,a[1]元素为'b',为98,出现非法访问
    printf("%zd\n", strlen(&a));//&a访问的是整个数组的地址,数组开始位置的编号,传给strlen后,它的类型为char(*)[6],strlen依旧从首元素开始向后数字符,还是随机值
    printf("%zd\n", strlen(&a+1));//&a访问整个数组+1还是随机值,没有'\0'
    printf("%zd\n", strlen(&a[0]+1));//&a[0]首元素地址+1指向‘b',第二个元素地址依然是随机值,因为没有'\0'
    
 char a[] = "abcdef";//  a b c d e f '\0'
    //字符串长度
    printf("%zd\n", strlen(a));//strlen从首元素地址开始向后找\0,长度为6字节
    printf("%zd\n", strlen(a+0));//a为首元素地址+0还是首元素地址,长度为6字节
    printf("%zd\n", strlen(*a));//*a为首元素地址解引用为首元素’a',会出现非法访问
    printf("%zd\n", strlen(a[1]));//a[1]为第二个元素‘b',会出现非法访问
    printf("%zd\n", strlen(&a));//取地址a为数组的地址,传入strlen后参数为首元素,长度为6
    printf("%zd\n", strlen(&a+1));//取地址a+1为整个数组地址+1,随机值
    printf("%zd\n", strlen(&a[0]+1));//取地址a[0]为首元素地址+1指向第二个元素地址,从第二个元素地址开始找'\0',长度为5个字节

2.指针中存储占用大小和长度

一级指针和二级指针的指向

 int a = 10;
    int *b = &a;//*b指向a的地址,int为类型
    int* *c = &b;//*c指向b的地址,int*为类型
    printf("a=%d b=%d c=%d", a, *b, **c);//结果都为10

1.指针存放字符串求大小

    char *p = "abcdef";//将a的地址赋给了p
    printf("%zd\n", sizeof(p));//p是指针变量,计算为4/8字节
    printf("%zd\n", sizeof(p+1));//p存放a的地址+1(char类型字节为1)跳过一个字节为b的地址4/8
    printf("%zd\n", sizeof(*p));//p为首元素a的地址,解引用为’a‘,大小1字节
    printf("%zd\n", sizeof(p[0]));//p[0]首元素a把常量字符串看成数组
    printf("%zd\n", sizeof(&p));//取地址p为二级指针地址大小为4/8字节
    printf("%zd\n", sizeof(&p+1));//4/8个字节&p可以理解为用二级指针来接收,类型为(char*)*p为指针,和字符串没关系
    printf("%zd\n", sizeof(&p[0]+1));//&p[0]为a地址+1为b地址,为4/8个字符

2.指针存放字符串的长度

    char *p = "abcdef";
    printf("%zd\n", strlen(p));//p存放的是a的地址,长度为6
    printf("%zd\n", strlen(p+1));//p+1指向的是b,长度为5
    printf("%zd\n", strlen(*p));//*p是指向的字符a,传入‘97’
    printf("%zd\n", strlen(p[0]));//p[0]为*p,指向的也是a元素
    printf("%zd\n", strlen(&p));//取地址p取的是p中不清楚'\0'在哪里,为随机值
    printf("%zd\n", strlen(&p+1));//取地址+1也为随机值
    printf("%zd\n", strlen(&p[0]+1));//&p[0]为a的地址+1指向b地址长度为5

3.二维数组

  int a[3][4] = {0};
    printf("%zd\n", sizeof(a));//a为48个字节,取的是整个数组的大小(int)类型占用4个字节
    printf("%zd\n", sizeof(a[0][0]));//数组首元素,为4个字节
    printf("%zd\n", sizeof(a[0]));//为第0行的所有元素,16个字节
    printf("%zd\n", sizeof(a[0]+1));//a[0]作为数组名没有单独在sizeof里,代表的首元素地址+1为第二个元素的地址4/8字节
    printf("%zd\n", sizeof(*(a[0]+1)));//第一行第二个数组的地址解引用,类型为int占用4字节
    printf("%zd\n", sizeof(a+1));//a作为二维数组数组名并没有放在sizeof里,所以表示的首元素地址,第一行地址
    //二维数组首元素地址代表第一行的地址,a+1跳过第一行指向第二行的地址4/8字节
    printf("%zd\n", sizeof(*(a + 1))); // a+1为第二行地址解引用占用16个字节=a[1];
    printf("%zd\n", sizeof(*(&a[0] + 1)));//取地址a[0]是首元素的地址第一行地址+1,为第二行地址解引用为16字节
    printf("%zd\n", sizeof(&a[0]+1));//取地址a[0]是第一行地址+1指向第二行的地址,地址为4/8个字节
    printf("%zd\n", sizeof(*a));     //*a为对首元素地址,对a进行解引用第一行大小为16个字节
    //*a=a[0]=*(a+0);
    printf("%zd\n", sizeof(a[3]));   //sizeof只计算大小,数组已经固定了,字节占用16

4.指针运算笔试试题

第一题

#include<stdio.h>
#include<string.h>
int main()
{
    int a[5] = {1, 2, 3, 4, 5};//a[5]中的五个元素
    int *ptr = (int *)(&a + 1);//&a+1跳过整个元素
    printf("%d %d", *(a + 1), *(ptr - 1));//a+1为首地址+1指向第二个元素地址解引用为2
    //ptr存放的是&a+1跳过的元素-1为5
    return 0;
}

第二题

#include<stdio.h>
#include<string.h>
//在x86环境下
//假设结构体的大小是20个字节
//程序输出的结果是什么?
struct Test
{
    int Num;
    char *pcName;
    short sDate;
    char cha[2];
    short sBa[4];
}*p = (struct Test *)0x100000;
int main()
{
    printf("%p\n", p + 0x1);//P指向结构体0下100000+1(跳过20个字节),因为0x100000为16进制+20位0x100014
    printf("%p\n", (unsigned long)p + 0x1);//被强制转换为unsigned long类型为整形,整形+1就是+1为100001
    printf("%p\n", (unsigned  int*)p + 0x1);
    // 被转换为(unsigned int*)无符号整形长度为4个字节+1,为0100004;
    return 0;
}

第三题

#include<stdio.h>
#include<string.h>
int main()
{
    int a[3][2] = {(0, 1),(2, 3),(4, 5)};
    //逗号为表达式从左向右开始最后为结果,左边操作数不起任何的结果
    int *p;
    p = a[0];//*p指向第一行数组的元素
    printf("%d", p[0]);//如果可以输出的话值为1,3,第二行为5,0,第三行为0,0
    return 0;
}

第四题

#include<stdio.h>
#include<string.h>
int main()
{
    int aa[2][5] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
    int *ptr1 = (int *)(&aa + 1);
    //取地址aa整个数组地址+1为跳过首个元素
    int *ptr2 = (int *)(*(aa + 1));
    //aa为首元素地址+1为另一行的首元素地址解引用为6
    printf("%d %d", *(ptr1 - 1), *(ptr2 - 1));
    //跳过的首元素-1为10,ptr2-1为5
}

第五题

#include<stdio.h>
int main()
{
    int a[5][5];
    int(*p)[4];
    p = a;
    printf("%p\n%ld", &p[4][2] - &a[4][2], &p[4][2] - &a[4][2]);
    //a数组中的第一行地址赋值了给了p,a中一行为5个元素,p指向为4个元素
    //%d打印出来是原码
    //%p内存中的补码直接以16进制的形式打印
    //指针-指针得到元素个数
    //因为a赋值给p,p以一行4个的形式来访问a小地址减去大地址为负数,差为4个元素
    //-4的原码为
    //100000000000000000000000000100
    //111111111111111111111111111011取反
    //111111111111111111111111111100//取反+1
    //内存中的地址的补补码直接当成原码,以16进制打印
    //每4个二进制位为一个F
    //0xfffffffc
    return 0;
}

第六题

#include<stdio.h>
int main()
{
    char *a[] = {"work", "at", "alibaba"};
    //*a数组指向为3行的数组
    char **pa = a;//*pa指向a首元素地址w
    pa++;         // pa++,跳过一行,指向a
    printf("%s\n", *pa);//输出结果为第二行到\0位置
    return 0;
}

第七题

#include<stdio.h>
int main()
{
    char *c[] = {"ENTER", "NEW", "POINT", "FIRST"};
    char **cp[] = {c + 3, c+2, c + 1, c};
    //*cp指向为FIRST,POINT,NEW,ENTER;
    char ***cpp = cp;
    //**cpp指向为cp首元素地址,F
    printf("%s\n", **++cpp);
    //*cpp++指向第P,这时候cpp为POINT
    printf("%s\n", *--* ++cpp+3);
    //++优先级高,++cpp指向了N,*解引用后拿到了N首元素地址中的内容
    //然后--,cpp由原先的c+1--变为c,指向E解引用拿到ENTER,然后+3为ER
    printf("%s\n", *cpp[-2]+3);
    //*cpp还是在NEW[-2]为指向f解引用为FIRST+3,ST
    printf("%s\n", cpp[-1][-1]+1);
    //cpp[-1][-1]=*(*cpp(-1)-1)+1
    //*(cpp-1)找到P地址之后解引用,找到p地址中的内容,然后-1,c+2-1后为c+1之后解引用+1为EW
    return 0;
}
1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。
1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值