目录
- 一、sizeof
- 1.1一维数组与sizeof
- 例一:(详解)
- Summary:
- 1.2字符数组与sizeof
- 例二:(练习)
- 例三:(练习)
- 1.3字符指针与sizeof
- 例四:(练习)
- 1.4二维数组与sizeof
- 例五:(提高)
- 二、strlen
- 2.1字符数组与strlen
- 例六:(详解)
- 例七:(练习)
- 2.2字符指针与strlen
- 例八:(练习)
一、sizeof
sizeof:操作符
作用:
- 求变量所占空间的大小
- 求类型创建的变量所占空间的大小
1.1一维数组与sizeof
例一:(详解)
int a[] = { 1,2,3,4 };
printf("%d\n", sizeof(a[1]));//第二个元素
printf("%d\n", sizeof(&a[0]));//第一个元素的地址(4/8)
printf("%d\n", sizeof(&a[0] + 1));//第二个元素的地址(4/8)
printf("%d\n", sizeof(a));
printf("%d\n", sizeof(a + 0));
printf("%d\n", sizeof(a + 1));
printf("%d\n", sizeof(&a));
printf("%d\n", sizeof(*a));
printf("%d\n", sizeof(*&a));
printf("%d\n", sizeof(&a + 1));
- a表示首元素地址,*a就是首元素
- sizeof(数组名),表示整个数组的大小
- sizeof(数组名+数字),数组名此时表示首元素的地址
X86
下
X64
下
- &a整个数组的地址
- *(&a)对整个数组取地址后解引用后再次得到数组,等价于a
- &a+1虽然跳过了整个数组但是本质仍然是地址
Summary:
数组名表示整个数组的情况:
- sizeof(数组名)
- &数组名
( )内容 | sizeof()计算结果 |
---|---|
只有数组名 | 整个数组的空间大小 |
数组名+数字 | 地址:4/8 |
&数组名(+数字) | 地址:4/8 |
*数组名,数组名[0] | 第一个元素的字节大小 |
1.2字符数组与sizeof
例二:(练习)
由例一得出的summary可以轻松解决下面这个问题,就不再赘述。
char arr[] = { 'a','b','c','d','e','f' };
printf("%d\n", sizeof(arr));//整个数组 6
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
例三:(练习)
char arr[] = "abcdef";
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));//跳出整个数组(包括\0),但还是一个地址 4/8
printf("%d\n", sizeof(&arr[0] + 1));//第二个元素的地址 4/8
Tip:
- char arr[] = { ‘a’,‘b’,‘c’,‘d’,‘e’,‘f’ };与char arr[] = “abcdef”;的区别
1.3字符指针与sizeof
字符指针相关知识请戳👉深度剖析指针👈
例四:(练习)
char* p = "abcdef";
printf("%d\n", sizeof(p));//p为指针变量,存放着a的地址 4/8
printf("%d\n", sizeof(p + 1));//p+1是字符b的地址 4/8
printf("%d\n", sizeof(*p));//解引用找到a的值 1
printf("%d\n", sizeof(p[0]));//相等于*(p+0)得到a 1
printf("%d\n", sizeof(&p));//(1) 指针p的地址 4/8
printf("%d\n", sizeof(&p + 1));//(2) 跳过一个指针p的地址 4/8
printf("%d\n", sizeof(&p[0] + 1));//第二个元素b的地址 4/8
- (1)取指针p的地址
- (2)跳过一个指针p的地址
1.4二维数组与sizeof
例五:(提高)
int a[3][4] = { 0 };
printf("%d\n", sizeof(a));//整个数组 12*4=48
printf("%d\n", sizeof(a[0][0]));//第1行第1列的元素 4
printf("%d\n", sizeof(a[0]));//第1行数组的数组名 4*4=16 (只有数组名的情况)
printf("%d\n", sizeof(a[0] + 1));//数组名+数字表示a[0][1]的地址 4/8
printf("%d\n", sizeof(*(a[0] + 1)));//表示a[0][1] 4
printf("%d\n", sizeof(a + 1));//二维数组的首元素的地址是第一行,a+1第2行的地址 4/8
printf("%d\n", sizeof(*(a + 1)));//第2行的地址解引用 4*4=16
printf("%d\n", sizeof(&a[0] + 1));//取到第1行的地址,+1得到第2行的地址 4/8
printf("%d\n", sizeof(*(&a[0] + 1)));//第2行地址解引用得到第2行数组 16
printf("%d\n", sizeof(*a));//整个数组解引用得到首元素 16
printf("%d\n", sizeof(a[3]));//第4行(假象的一行并没有访问)数组的数组名 16
二、strlen
strlen:库函数
作用:求字符串的长度
2.1字符数组与strlen
例六:(详解)
char arr[] = { 'a','b','c','d','e','f' };
printf("%d\n", strlen(arr));//(1)
printf("%d\n", strlen(arr + 0));//(2)
printf("%d\n", strlen(*arr));//(3)
printf("%d\n", strlen(arr[1]));//(4)
printf("%d\n", strlen(&arr));//(5)
printf("%d\n", strlen(&arr + 1));//(6)
printf("%d\n", strlen(&arr[0] + 1));//(7)
- (1)(2)遇到
\0
才会停下
-
(3)(4)*arr取出首元素,将首元素a的ASCII码值97传给strlen()
-
(5)(6)&arr的类型为char ( * )[6]但是strlen()接收的是char * 类型,虽然类型不匹配,但是strlen将&arr转换成char*类型,所以strlen()接收了首元素的地址
- (7)&arr[0]首元素地址,&arr[0]+1第二个元素地址
例七:(练习)
char arr[] = "abcdef";
printf("%d\n", strlen(arr));//遇到\0就停止 6
printf("%d\n", strlen(arr + 0));//6
printf("%d\n", strlen(*arr));//ASCII码值给strlen 随机值
printf("%d\n", strlen(arr[1]));//同上 随机值
printf("%d\n", strlen(&arr));//6
printf("%d\n", strlen(&arr + 1));//跳出整个数组 随机值
printf("%d\n", strlen(&arr[0] + 1));//5
2.2字符指针与strlen
例八:(练习)
char* p = "abcdef";
printf("%d\n", strlen(p));//p存放着a的地址 6
printf("%d\n", strlen(p + 1));//p+1是b的地址 5
printf("%d\n", strlen(*p));//*p是aASCII码值给strlen 随机值
printf("%d\n", strlen(p[0]));//同上
printf("%d\n", strlen(&p));//在指针变量p中找\0 随机值
printf("%d\n", strlen(&p + 1));//跳过整个p的地址 随机值
printf("%d\n", strlen(&p[0] + 1));//第二个元素b的地址 5