1️⃣ sizeof和strlen的对⽐
➡️sizeof
C语言中sizeof
不是一个函数,而是一个编译期计算类型大小的内置操作符,所以它没有函数原型。
sizeof没有函数原型,它的语法形式是:
sizeof(类型名) 或 sizeof 变量名
类型名需要括号,变量名可以不需要括号。直接写类型名后面会报错。
sizeof 只关注占⽤内存空间的⼤⼩,不在乎内存中存放什么数据。
int main() { int a = 66; printf("%zd\n", sizeof(a));//4 printf("%zd\n", sizeof(int));//4 printf("%zd\n", sizeof a);//这里可以省略括号 printf("%zd\n", sizeof int);//err,类型名本身不能直接跟在sizeof后面,如sizeof int是错误的 return 0; }
当然,sizeof也可以求数组的大小
数组名就是数组⾸元素(第⼀个元素)的地址。
sizeof(数组名)---->sizeof中单独放数组名,这⾥的数组名表⽰整个数组,计算的是整个数组的⼤⼩,单位是字节.
&数组名(如&a),这⾥的数组名表⽰整个数组,取出的是整个数组的地址(整个数组的地址和数组⾸元素
除此之外,任何地⽅使⽤数组名,数组名都表⽰⾸元素的地址。
int main()int main() { int arr1[4] = { 0 }; char arr2[4] = { 0 }; printf("%zd\n", sizeof(arr1));//16 //单独放数组名,这⾥的数组名表⽰整个数组,计算的是整个数组的⼤⼩ printf("%zd\n", sizeof(int [4]));//16 //int占用4个字节,int[4]数组占用4 * 4 = 16字节 printf("%zd\n", sizeof(arr2));//4 //单独放数组名,这⾥的数组名表⽰整个数组,计算的是整个数组的⼤⼩ printf("%zd\n", sizeof(char [4]));//4 //arr2是char类型的数组,char占1字节,char[4]数组占用4 * 1 = 4字节。 return 0; }
➡️ ➡️ strlen
strlen 是C语⾔库函数,功能是求字符串⻓度。函数原型如下:
size_t strlen ( const char * str );
统计的是从 strlen
函数的参数 str
中这个地址开始向后, \0
之前字符串中字符的个数。
strlen
函数会⼀直向后找\0
字符,直到找到为⽌,所以可能存在越界查找。
int main() { char arr1[20] = "abcdef"; size_t len = strlen(arr1);//不包含结尾'\0',所以长度是6。 printf("len = %zd\n", len); size_t sz = sizeof(arr1);//arr1这个数组变量占用的内存大小,即20字节。 printf("sz = %zd\n", sz); char arr2[] = { 'a', 'b','c' }; printf("%zd\n", strlen(arr2));//随机值,因为找不到\0 char arr3[6] = "abcdef";//err //因为"abcdef"包含7个字符及结尾'\0',大于arr3的空间6字节,会导致越界。 return 0; }
➡️ ➡️ ➡️sizeof 和 strlen的对⽐
2️⃣ 数组和指针笔试题解析
💯 ⼀维数组
数组名就是数组⾸元素(第⼀个元素)的地址。
sizeof(数组名)---->sizeof中单独放数组名,这⾥的数组名表⽰整个数组,计算的是整个数组的⼤⼩,单位是字节.
&数组名(如&a),这⾥的数组名表⽰整个数组,取出的是整个数组的地址(整个数组的地址和数组⾸元素
的地址是有区别的)
除此之外,任何地⽅使⽤数组名,数组名都表⽰⾸元素的地址。
char* arr1[10]; //存放字符指针的指针数组
int* arr2[10]; //存放整型指针的指针数组
int(*arr3[5])[6] ;//存放数组指针的数组指针数组
int(*arr4[5])(int);//存放函数指针的函数指针数组
int main() { int a[] = { 6,7,8,9,10 }; printf("%d\n", sizeof(a)); printf("%d\n", sizeof(a + 0)); printf("%d\n", sizeof(*a)); printf("%d\n", sizeof(a + 1)); printf("%d\n", sizeof(a[1])); printf("%d\n", sizeof(&a)); printf("%d\n", sizeof(*&a)); printf("%d\n", sizeof(&a + 1)); printf("%d\n", sizeof(&a[0])); printf("%d\n", sizeof(&a[0] + 1)); }
细解:
- printf(“%d\n”, sizeof(arr));//20
- sizeof中单独放数组名,这⾥的数组名表⽰整个数组,计算的是整个数组的⼤⼩,单位是字节.
- printf(“%zd\n”, sizeof(a + 0));4/8
- a没有单独放在sizeof内部,也没有&取地址,因此a表示的就是数组首元素的地址,a+0还是首元素的地址 ,是地址,那么大小就是 4/8,地址大小只与环境有关,32位是4个字节,64位就是8个字节
- printf(“%zd\n”, sizeof(*a)); //4
- a表示的就是数组首元素的地址,*a 就是首元素,首元素是6,6的类型是int,大小就是4个字节
- printf(“%zd\n”, sizeof(a + 1));//4/8
- a表示的就是数组首元素的地址,a+1就是第二个元素的地址,这里的计算的是第二个元素的地址的大小,地址大小只与环境有关,32位是4个字节,64位就是8个字节4/8
- printf(“%zd\n”, sizeof(a[1]));//4
- a[1]是数组的第二个元素(7),大小是4个字节
- printf(“%zd\n”, sizeof(&a));//4/8
- &a - 取出的是数组的地址,但是数组的地址也是地址,是地址,大小就是4/8个字节
- printf(“%zd\n”, sizeof(*&a));//20
- 两种方法:1. & 和 * 抵消
- 2.&a 的类型是数组指针,int(*)[5],*&a就是对数组指针解引用访问一个数组的大小,是20个字节
- printf(“%zd\n”, sizeof(&a + 1));//4/8
- &a+1是跳过整个数组后的一个地址,是地址,大小就是4/8个字节
- printf(“%zd\n”, sizeof(&a[0]));//4/8
- &a[0]是数组第一个元素的地址,是地址,大小就是4/8个字节
- printf(“%zd\n”, sizeof(&a[0] + 1));//4/8
&a[0] + 1 是第二个元素的地址,大小就是4/8个字节
🎈字符数组
🎈🎈 sizeof
计算字符
数组
int main() { char arr[] = { 'a','b','c','d','e','f' }; printf("%d\n", sizeof(arr)); printf("%d\n", sizeof(arr + 0)); printf("%d\n", sizeof(*arr)); printf("%d\n", sizeof(arr[1])); printf("%d\n", sizeof(&arr)); printf("%d\n", sizeof(&arr + 1)); printf("%d\n", sizeof(&arr[0] + 1)); return 0; }
【C指针】深入理解指针(最终篇)数组&&指针&&指针运算题解析(一)2: https://developer.aliyun.com/article/1474745