前言
了解掌握有关sizeof,strlen在指针与数组的结合使用下的求值
一、sizeof和strlen的区别?
sizeof
sizeof是运算符,参数可以是数组、指针、数据类型、对象、函数等。
它的功能是:获得保证能容纳实现所建立的最大对象的字节大小。
sizeof不能用来返回动态分配的内存空间的大小
数组 int arr[ 6] | 编译时分配的数组空间大小 |
指针char * p | 存储该指针所需要的空间大小,根据32/64位不同出现4/8两种情况 |
类型 int | 对应该数据类型的字节大小 |
对象 sizeof(val) | 对象的实际占用空间大小 |
函数sizeof(add) | 函数的返回类型,返回类型不能是void |
strlen
strlen()是函数要在运算时才能够计算
参数必须是字符型指针(char *),且必须是‘\0’结尾
当数组名作为参数传入时,实际上数组就退化成为指针了
strlen的作用是:返回字符串的长度,该字符串可能是自己定义的,也可能是内存中随机的,该函数的实际完成的功能是从代表字符串的第一个地址开始遍历,直到遇到结束符‘\0’,返回的长度大小不包括‘\0’
二、案例
1.sizeof计算整型数组的几种情况
代码如下(示例):
#include <stdio.h>
int main(void)
{
int a[] = {1, 2, 3, 4};//16 4 4 4 4 4 16 4 4 4
printf("一维数组计算:\n");
printf("%d\n", sizeof(a));
//16 sizeof(数组名)-数组名表示整个数组的-计算整个数组的大小
printf("%d\n", sizeof(a + 0));
// 4/8 a+0是首元素的地址,首元素的地址+0 sizeof(a + 0)计算的是地址的大小随着32/64位电脑改变
printf("%d\n", sizeof(*a));
//4 此处a表示首元素的地址,1的地址被解引用,表示的是第一个元素的大小
printf("%d\n", sizeof(a + 1));
//4/8 a+1表示的是第二个元素的地址,sizeof(a+1)计算地址的大小随着32/64位电脑改变
printf("%d\n", sizeof(a[1]));
//4 计算第二个元素的大小
printf("%d\n", sizeof(&a));
// 4/8 &数组名-数组名表示整个数组-取出的是整个数组的大小,&a虽然是数组的地址,但也是地址,sizeof(&a)也是地址的大小 4/8
printf("%d\n", sizeof(*&a));
// 16 //&a int(*p)[4] = &a;解引用(*)&a找到的是数组的大小
printf("%d\n", sizeof(&a + 1));
//4/8 &a + 1是跳过整个数组之后,数组后面的空间的大小
printf("%d\n", sizeof(&a[0]));
//4/8 取出第一个元素的地址
printf("%d\n", sizeof(&a[0] + 1));
//4/8 取出第一个元素地址 + 1也就是第二个元素的地址
2.sizeof计算字符数组的几种情况
//sizeof计算字符数组:sizeof计算所占空间大小
printf("字符数组计算:\n");
char arr[] = {'a', 'b', 'c', 'd', 'e', 'f'};
printf("%d\n", sizeof(arr)); //6 不包括/0
printf("%d\n", sizeof(arr + 0));
// 4/8 此处arr没有取地址符号,也没有单独放到sizeof里面,因此求的是地址,字符的地址也是地址,只是char所占的空间是1但不是地址大小
printf("%d\n", sizeof(*arr)); // 1 解引用是a
printf("%d\n", sizeof(arr[1])); //1 b的大小
printf("%d\n", sizeof(&arr)); // 4/8 数组的地址
printf("%d\n", sizeof(&arr + 1)); //4/8 数组的地址+1 还是地址
printf("%d\n", sizeof(&arr[0] + 1)); // 4/8 b的地址
3.strlen计算字符数组的几种情况
//strlen计算字符数组:strlen求字符串长度直到\0
char arr1[] = {'a', 'b', 'c', 'd', 'e', 'f'};
printf("字符数组计算:\n");
printf("%d\n", strlen(arr1)); //0 随机值 首元素地址 一直 找\0
printf("%d\n", strlen(arr1 + 0)); //0 随机值 首元素地址+0
printf("%d\n", strlen(*arr1));//出错 找到a对应的ASCII值97,此处会出错
printf("%d\n", strlen(arr1[1]));//出错 找到strlen(b)即 strlen(98)未知内存会出错
printf("%d\n", strlen(&arr1));// &arr取出数组的地址往后找 得到随机值
printf("%d\n", strlen(&arr1 + 1)); //随机值
printf("%d\n", strlen(&arr1[0] + 1));//随机值
4.sizeof计算字符串长度的几种情况
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));//1
printf("%d\n", sizeof(arr[1]));//1
printf("%d\n", sizeof(&arr));//4/8
printf("%d\n", sizeof(&arr + 1));//4/8
printf("%d\n", sizeof(&arr[0] + 1));//4/8 首元素地址+1 = 第二个元素的地址
5.strlen计算字符串长度的几种情况
printf("strlen计算字符串长度\n");
char arr[] = "abcdef";
//[a b c d e f \0]
printf("%d\n", strlen(arr));
//6 此处的arr为首元素的地址
printf("%d\n", strlen(arr + 0));
//6 此处的arr为首元素的地址
printf("%d\n", strlen(*arr));
//错误 给的是a的ASCII码值,从97开始数
printf("%d\n", strlen(arr[1]));
//错误 给的是b的ascii码值,从98开始数
printf("%d\n", strlen(&arr));//6
printf("%d\n", strlen(&arr + 1));
//错误 从a的地址直接跳过整个数组的地址,得到随机值
printf("%d\n", strlen(&arr[0] + 1));
//5 从b开始往后数到\0得到5
6.sizeof计算指针字符串长度的几种情况
char* p = "abcdef";// a b c d e f \0 指针p指向起始位置a的地址
printf("%d\n", sizeof(p));//4/8
printf("%d\n", sizeof(p + 1));//4/8
printf("%d\n", sizeof(*p));//1
printf("%d\n", sizeof(p[0]));//1 p[0] = *(p + 0)
printf("%d\n", sizeof(&p));//4/8
printf("%d\n", sizeof(&p + 1));//4/8
printf("%d\n", sizeof(&p[0] + 1));//4/8
7.strlen计算指针字符串长度的几种情况
char* p = "abcdef";
printf("%d\n", strlen(p));//6
printf("%d\n", strlen(p + 1));//5
printf("%d\n", strlen(*p));// 97 错误
printf("%d\n", strlen(p[0]));// 98 错误
printf("%d\n", strlen(&p));//随机 不知p的地址为何
printf("%d\n", strlen(&p + 1)); //随机 不知p的地址为何
printf("%d\n", strlen(&p[0] + 1)); //5
总结
针对strlen和sizeof运算做的学习笔记,欢迎指正