1.sizeof和strlen的对比
1.1 sizeof
sizeof是一个操作符,可以用来计算变量和类型所占空间大小,但是并不会真正访问这块空间。
sizeof计算变量大小时也可以不用括号括起来,见上图。
1.2 strlen
strlen是一个库函数,使用之前需要包含头文件<string.h>,他可以用来计算一个字符串的长度。
函数的原型:size_t strlen ( const char * str );
函数的返回值类型是size_t;
这里重点说一下参数 const char * str ,在c++中一个字符串在创建的时候就是const char*类型。
虽然在C语言中这段代码不会报错,但是ch2并不会真正读取这个字符串。
因此在给strlen传参的时候类型就是const char*类型
统计的是从
strlen
函数的参数
str
中这个地址开始向后,
\0
之前字符串中字符的个数。
strlen
函数会⼀直向后找
\0
字符,直到找到为⽌,所以可能存在越界查找。
int main()
{
char arr1[] = "abc";
char arr2[] = { 'a','b','c' };
printf("%zd\n", sizeof(arr1));
printf("%zd\n", sizeof(arr2));
printf("%d\n", strlen(arr1));
printf("%d\n", strlen(arr2));
return 0;
}

1.3sizeof 和 strlen的对比
1.sizeof是操作符
2.sizeof计算的是变量或类型所占字节大小
3.sizeof并不在乎放的是什么数据,也就是不会访问那块空间
1.strlen是库函数,使用要包含头文件<string.h>
2.strlen计算字符串的长度,统计\0之前的元素个数
3.strlen会访问数据,所以在遇到\0前可能会越界访问
2.数组和指针笔试题解析
没错到了我们真正应用我们所学的时候了,别担心这些题很有意思的。
2.1 一维数组
int a[] = {1,2,3,4};
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));
2.2字符数组
代码1:
int main()
{
char arr[] = { 'a','b','c','d','e','f' };
printf("%d\n", strlen(arr));
printf("%d\n", strlen(arr + 0));
printf("%d\n", strlen(*arr));
printf("%d\n", strlen(arr[1]));
printf("%d\n", strlen(&arr));
printf("%d\n", strlen(&arr + 1));
printf("%d\n", strlen(&arr[0] + 1));
return 0;
}
因为非法访问,造成程序提前停止,但是结果还是同上面的分析一样的。
代码2:
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));
代码3:
char arr[] = "abcdef";
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));
代码4:
char arr[] = "abcdef";
printf("%d\n", strlen(arr));
printf("%d\n", strlen(arr+0));
printf("%d\n", strlen(*arr));
printf("%d\n", strlen(arr[1]));
printf("%d\n", strlen(&arr));
printf("%d\n", strlen(&arr+1));
printf("%d\n", strlen(&arr[0]+1));
代码5:
char *p = "abcdef";
printf("%d\n", sizeof(p));
printf("%d\n", sizeof(p+1));
printf("%d\n", sizeof(*p));
printf("%d\n", sizeof(p[0]));
printf("%d\n", sizeof(&p));
printf("%d\n", sizeof(&p+1));
printf("%d\n", sizeof(&p[0]+1));
代码6:
char *p = "abcdef";
printf("%d\n", strlen(p));
printf("%d\n", strlen(p+1));
printf("%d\n", strlen(*p));
printf("%d\n", strlen(p[0]));
printf("%d\n", strlen(&p));
printf("%d\n", strlen(&p+1));
printf("%d\n", strlen(&p[0]+1));
2.3⼆维数组
数组名的意义:(再次拿过来复习一下)1. sizeof(数组名),这⾥的数组名表⽰整个数组,计算的是整个数组的⼤⼩。2. &数组名,这⾥的数组名表⽰整个数组,取出的是整个数组的地址。3. 除此之外所有的数组名都表⽰⾸元素的地址。
int a[3][4] = {0};
printf("%d\n",sizeof(a));
printf("%d\n",sizeof(a[0][0]));
printf("%d\n",sizeof(a[0]));
printf("%d\n",sizeof(a[0]+1));
printf("%d\n",sizeof(*(a[0]+1)));
printf("%d\n",sizeof(a+1));
printf("%d\n",sizeof(*(a+1)));
printf("%d\n",sizeof(&a[0]+1));
printf("%d\n",sizeof(*(&a[0]+1)));
printf("%d\n",sizeof(*a));
printf("%d\n",sizeof(a[3]));
3.指针运算笔试题解析
3.1 题目1:
#include <stdio.h>
int main()
{
int a[5] = { 1, 2, 3, 4, 5 };
int *ptr = (int *)(&a + 1);
printf( "%d,%d", *(a + 1), *(ptr - 1));
return 0;
}
3.2题目2:
//在X86环境下
//假设结构体的⼤⼩是20个字节
//程序输出的结果是啥?
struct Test
{
int Num;
char *pcName;
short sDate;
char cha[2];
short sBa[4];
}*p = (struct Test*)0x100000;
int main()
{
printf("%p\n", p + 0x1);
printf("%p\n", (unsigned long)p + 0x1);
printf("%p\n", (unsigned int*)p + 0x1);
return 0;
}
3.3题目3 :
#include <stdio.h>
int main()
{
int a[3][2] = { (0, 1), (2, 3), (4, 5) };
int *p;
p = a[0];
printf( "%d", p[0]);
return 0;
}
3.4题目4:
//假设环境是x86环境,程序输出的结果是啥?
#include <stdio.h>
int main()
{
int a[5][5];
int(*p)[4];
p = a;
printf( "%p,%d\n", &p[4][2] - &a[4][2], &p[4][2] - &a[4][2]);
return 0;
}
3.5题⽬5 :
#include <stdio.h>
int main()
{
char *a[] = {"work","at","alibaba"};
char**pa = a;
pa++;
printf("%s\n", *pa);
return 0;
}
3.6题目6:
#include <stdio.h>
int main()
{
int aa[2][5] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
int *ptr1 = (int *)(&aa + 1);
int *ptr2 = (int *)(*(aa + 1));
printf( "%d,%d", *(ptr1 - 1), *(ptr2 - 1));
return 0;
}
3.6题目7:
压轴登场
#include <stdio.h>
int main()
{
char *c[] = {"ENTER","NEW","POINT","FIRST"};
char**cp[] = {c+3,c+2,c+1,c};
char***cpp = cp;
printf("%s\n", **++cpp);
printf("%s\n", *--*++cpp+3);
printf("%s\n", *cpp[-2]+3);
printf("%s\n", cpp[-1][-1]+1);
return 0;
}