sizeof和strlen的对比
sizeof
在学习操作符的时候,我们学习了 sizeof
, sizeof
计算变量所占内存内存空间⼤⼩的,单位是字节,如果操作数是类型的话,计算的是使⽤类型创建的变量所占内存空间的⼤⼩。
sizeof
只关注占用内存空间的大小,不在乎内存中存放什么数据。
strlen
strlen
函数会⼀直向后找 \0 字符,直到找到为⽌,所以可能存在越界查找。
sizeof 和 strlen的对比
sizeof
- sizeof是操作符
- sizeof计算操作数所占内存的⼤⼩,单位是字节
- 不关注内存中存放什么数据
strlen
- strlen是库函数,使⽤需要包含头⽂件 string.h
- srtlen是求字符串⻓度的,统计的是 \0 之前字符的隔个数
- 关注内存中是否有 \0 ,如果没有 \0 ,就会持续往后找,可能
会越界
数组和指针笔试题解析
先复习一点:
数组名就是数组⾸元素(第⼀个元素)的地址,但是有两个例外:
sizeof(数组名)
,sizeof中单独放数组名,这里的数组名表示整个数组,计算的是整个数组的⼤⼩,
单位是字节&数组名
,数组名表示整个数组,取出的是整个数组的地址(整个数组的地址和数组首元素
的地址是有区别的)
除此之外,任何地方使用数组名,数组名都表示首元素的地址。
一维数组
#include<stdio.h>
int main()
{
int a[] = { 1, 2, 3, 4 };
printf("%d\n", sizeof(a));// 整个数组的大小 16
printf("%d\n", sizeof(a + 0));// 首元素地址大小 4/8
printf("%d\n", sizeof(*a));// 首元素大小 4
printf("%d\n", sizeof(a + 1));// 第二个元素地址大小 4/8
printf("%d\n", sizeof(a[1]));// 第二个元素大小 4
printf("%d\n", sizeof(&a));// 数组地址大小 4/8
printf("%d\n", sizeof(*&a));// 整个数组大小 16
printf("%d\n", sizeof(&a + 1));// 跳过数组后的地址大小 4/8
printf("%d\n", sizeof(&a[0]));// 首元素地址大小 4/8
printf("%d\n", sizeof(&a[0] + 1));// 第二个元素地址 4/8
return 0;
}
字符数组
代码一
#include<stdio.h>
int main()
{
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
return 0;
}
代码二
#include<stdio.h>
int main()
{
char arr[] = { 'a', 'b', 'c', 'd', 'e', 'f' };
printf("%d\n", strlen(arr));// 首元素到\0的大小 随机值
printf("%d\n", strlen(arr + 0));// 首元素到\0的大小 随机值
printf("%d\n", strlen(*arr));// ‘a’->97 非法访问-err
printf("%d\n", strlen(arr[1]));// 'b’->98 非法访问-err
printf("%d\n", strlen(&arr));// 首元素到\0的大小 随机值
printf("%d\n", strlen(&arr + 1));// 数组后一个元素到\0的大小 随机值
printf("%d\n", strlen(&arr[0] + 1));// 第二个元素到\0的大小 随机值
return 0;
}
代码三
#include<stdio.h>
int main()
{
char arr[] = "abcdef";
printf("%d\n", sizeof(arr));// 整个数组大小(包括\0) 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
return 0;
}
代码四
#include<stdio.h>
int main()
{
char arr[] = "abcdef";
printf("%d\n", strlen(arr));// a-\0(不包括\0) 6
printf("%d\n", strlen(arr + 0));// a-\0(不包括\0) 6
printf("%d\n", strlen(*arr));// 'a'->97 非法访问-err
printf("%d\n", strlen(arr[1]));// 'b'->98 非法访问-err
printf("%d\n", strlen(&arr));// a的地址-\0(不包括\0) 6
printf("%d\n", strlen(&arr + 1));// 数组后一个值到\0 随机值
printf("%d\n", strlen(&arr[0] + 1));// b的地址-\0(不包括\0) 5
return 0;
}
代码五
#include<stdio.h>
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]));// 首元素 1
printf("%d\n", sizeof(&p));// p的地址 4/8
printf("%d\n", sizeof(&p + 1));// 跳过p的地址 4/8
printf("%d\n", sizeof(&p[0] + 1));// 第二个元素地址 4/8
return 0;
}
代码六
#include<stdio.h>
int main()
{
char *p = "abcdef";
printf("%d\n", strlen(p));// a的地址-\0 6
printf("%d\n", strlen(p + 1));// b的地址-\0 5
printf("%d\n", strlen(*p));// 'a'->97 err
printf("%d\n", strlen(p[0]));// 'b'->98 err
printf("%d\n", strlen(&p));// p的地址-\0 随机值
printf("%d\n", strlen(&p + 1));// p的后一个地址-\0 随机值
printf("%d\n", strlen(&p[0] + 1));// b的地址-\0 5
return 0;
}
二维数组
#include<stdio.h>
int main()
{
int a[3][4] = { 0 };
printf("%d\n", sizeof(a));// 整个二维数组大小 48
printf("%d\n", sizeof(a[0][0]));// a[0][0]的大小 4
printf("%d\n", sizeof(a[0]));// 第一行数组的大小 16
printf("%d\n", sizeof(a[0] + 1));// 第一行第二个元素地址大小 4/8
printf("%d\n", sizeof(*(a[0] + 1)));// 第一行第二个元素大小 4
printf("%d\n", sizeof(a + 1));// 第二行地址大小 4/8
printf("%d\n", sizeof(*(a + 1)));// 第二行元素大小 16
printf("%d\n", sizeof(&a[0] + 1));// 第二行地址大小 4/8
printf("%d\n", sizeof(*(&a[0] + 1)));//第二行元素大小 16
printf("%d\n", sizeof(*a));// 第一行元素大小 16
printf("%d\n", sizeof(a[3]));// 与a[0]等价 16
return 0;
}