【C语言】关于指针与sizeof和strlen关系的学习笔记

数组和指针

数组 - 能够存放一组相同类型的元素,数组的大小取决于数组的元素个数和元素类型

指针 - 地址/指针变量,大小是4/8个字节

数组是数组,指针是指针,二者不等价

数组名是元素首地址,可以存放在指针变量中

就可以使用指针来遍历数组

数组名

大部分情况下是首元素地址

两个例外

sizeof(数组名) - 数组名表示整个数组,计算的是整个数组的大小

&数组名,数组名表示整个数组,取出的是数组的地址

//int main()
//{
//    int a[] = { 1,2,3,4 };
//    printf("%d\n", sizeof(a));//16   4x4
//    //sizeof(a)就是数组名单独放在sizeof内部,计算的数组总大小,单位是字节
//    printf("%d\n", sizeof(a + 0));// 4/8
//    //a+0不是单独将数组名放到sizeof内部,所以表示首元素地址
//    //所以是4/8个字节
//    printf("%d\n", sizeof(*a));// 4
//    //a是数组首元素地址 - &a[0]
//    //*a(解引用) -> *&a[0] -> a[0],这里是一个整型元素的大小,不是地址大小
//    printf("%d\n", sizeof(a + 1));// 4/8
//    //a是数组首元素地址 -- int*
//    //a+1 跳过一个元素,是第二个元素的地址
//    printf("%d\n", sizeof(a[1]));// 4
//    //第二个元素
//    printf("%d\n", sizeof(&a));// 4/8
//    //&a - 取出的是数组的地址,但是数组的地址也是地址,是地址大小就是4/8个字节
//    //int (*pa)[4] = &a 
//    printf("%d\n", sizeof(*&a));// 16
//    //sizeof(a)
//    //int(*)[4] 数组的指针类型
//    printf("%d\n", sizeof(&a + 1));// 4/8
//    //&a --> int(*)[4]
//    //&a+1 跳过一个数组
//    printf("%d\n", sizeof(&a[0]));// 4/8 
//    //取出首元素的地址
//    printf("%d\n", sizeof(&a[0] + 1));//4/8
//    //取出第二个元素的地址
//    return 0;
//}
//sizeof计算的是占用内存空间的大小,单位是字节,不关注内存中到底存放的是什么
//sizeof不是函数,是操作符
//strlen是函数
//strlen是针对字符串的,求的是字符串的长度,其实本质上统计的是'\0'之前出现的字符个数
//int main()
//{
//    char arr[] = { 'a','b','c','d','e','f' };
//    printf("%d\n", sizeof(arr));// 6
//    printf("%d\n", sizeof(arr + 0));// arr+0是数组首元素的地址 4/8
//    printf("%d\n", sizeof(*arr));//*arr是首元素,计算的是首元素的大小 1
//    printf("%d\n", sizeof(arr[1]));// 1
//    printf("%d\n", sizeof(&arr));// &arr是数组的地址 4/8
//    printf("%d\n", sizeof(&arr + 1));//&arr+1跳过一个数组过后的地址 4/8
//    printf("%d\n", sizeof(&arr[0] + 1));// 4 / 8
//    printf("%d\n", strlen(arr));//随机值 因为不知道\0的位置
//    printf("%d\n", strlen(arr + 0));//随机值
//    printf("%d\n", strlen(*arr));//这里是地址,传进去的是'a' --> 97,将97作为地址编号查找,形成非法访问
//    printf("%d\n", strlen(arr[1]));// 'b'--> 98 非法访问
//    printf("%d\n", strlen(&arr));//随机值
//    printf("%d\n", strlen(&arr + 1));//随机值-6 比上一个少6
//    printf("%d\n", strlen(&arr[0] + 1));//随机值-1
//    return 0;
//}

//int main()
//{
//    char arr[] = "abcdef";//[a b c d e f \0]
//    printf("%d\n", sizeof(arr));// 7
//    printf("%d\n", sizeof(arr + 0));// 4/8
//    printf("%d\n", sizeof(*arr));// *arr - 是数组首元素 1
//    //arr[0]  *(arr+0)
//    //int sz = sizeof(arr)/sizeof(*arr)
//    //int sz=sizeof(arr)/sizeof(arr[0])
//    printf("%d\n", sizeof(arr[1]));//1
//    printf("%d\n", sizeof(&arr));//数组的地址,4
//    printf("%d\n", sizeof(&arr + 1));// 4/8
//    printf("%d\n", sizeof(&arr[0] + 1));// 4/8
//
//    printf("%d\n", strlen(arr));//6
//    printf("%d\n", strlen(arr + 0));//6
//    printf("%d\n", strlen(*arr));//error 非法访问
//    printf("%d\n", strlen(arr[1]));//error 非法访问
//    printf("%d\n", strlen(&arr));//6
//    //&arr - char(*)[7] 与strlen的类型不同
//    printf("%d\n", strlen(&arr + 1));//随机值
//    printf("%d\n", strlen(&arr[0] + 1));//5
//    return 0;
//}

//int main()
//{
//    char* p = "abcdef";//可以想象成数组
//    printf("%d\n", sizeof(p));// 4/8 计算的是指针变量的大小
//    printf("%d\n", sizeof(p + 1));//'b'    的地址 4/8
//    printf("%d\n", sizeof(*p));// 1
//    printf("%d\n", sizeof(p[0]));//等价于*(p+0)--'a' 1
//    printf("%d\n", sizeof(&p));// 4/8 是p变量的地址
//    printf("%d\n", sizeof(&p + 1));// 4/8 p-- char*  &p -- char**
//    printf("%d\n", sizeof(&p[0] + 1));//b的地址 4/8
//    printf("%d\n", strlen(p));// 6
//    printf("%d\n", strlen(p + 1));//5
//    printf("%d\n", strlen(*p));//非法访问
//    printf("%d\n", strlen(p[0]));//非法访问
//    printf("%d\n", strlen(&p));//p的地址,随机值
//    printf("%d\n", strlen(&p + 1));//随机值
//    printf("%d\n", strlen(&p[0] + 1));// 5
//    return 0;
//}

//int main()
//{
//    int a[3][4] = { 0 };//可当成三个一维数组,数组名为a[0],a[1]...
//    printf("%d\n", sizeof(a));// 48 4x3x4 这个二维数组的数组名单独放在sizeof内部,计算整个数组的大小
//    printf("%d\n", sizeof(a[0][0]));//第一行第一个元素 4个字节
//    printf("%d\n", sizeof(a[0]));// 16 4x4
//    //a[0]第一行的数组名,这时数组名单独放在sizeof内部了,计算的是数组的大小,单位是字节
//    printf("%d\n", sizeof(a[0] + 1));//
//    //a[0]不是单独放在sizeof内部,a[0]表示首元素的地址,即第一行第一个元素的地址 - &a[0][0]
//    //+1是第一行第二个元素的地址 - &a[0][1]
//    printf("%d\n", sizeof(*(a[0] + 1)));//a[0][1] 大小是 4个字节
//    printf("%d\n", sizeof(a + 1));//
//    //a作为二维数组的数组名并非单独放在sizeof内部,所以表示首元素的地址
//    //二维数组的首元素是第一行,a就是第一行的地址---int (*)[4]
//    // a+1是跳过第一行,指向了第二行,是第二行的地址,数组指针
//    //
//    printf("%d\n", sizeof(*(a + 1)));//第二行解引用,第二行大小 4x4 16
//    //*(a+1)-->a[1]
//    printf("%d\n", sizeof(&a[0] + 1));//
//    //&a[0]是第一行的地址
//    //&a[0]+1是第二行的地址
//    printf("%d\n", sizeof(*(&a[0] + 1)));// 16 等价于a[1]
//    printf("%d\n", sizeof(*a));// 16 *a -- 就是第一行
//    //*啊-- *(a+0) -- a[0]
//    printf("%d\n", sizeof(a[3]));
//    return 0;
//}
//sizeof内部不会计算,只要类型

//int main()
//{
//    int a[5] = { 1, 2, 3, 4, 5 };
//    int* ptr = (int*)(&a + 1);//跳过了一个数组
//    printf("%d,%d", *(a + 1), *(ptr - 1));//解引用为5
//    //前面是2
//    return 0;
//}

//由于还没学习结构体,这里告知结构体的大小是20个字节
//struct Test
//{
//    int Num;
//    char* pcName;
//    short sDate;
//    char cha[2];
//    short sBa[4];
//}*p;
假设p 的值为0x100000。 如下表表达式的值分别为多少?
已知,结构体Test类型的变量大小是20个字节
//int main()
//{
//    printf("%p\n", p + 0x1);
//    printf("%p\n", (unsigned long)p + 0x1);//不是指针,该加多少加多少
//    printf("%p\n", (unsigned int*)p + 0x1);//指针加一
//    //0x100004
//    return 0;
//}
结构体20个字节,指针加一跳过20个字节变成0x100014
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值