sizeof: 计算变量所占内存内存空间大小的,单位是字节,如果操作数是类型的话,计算的是使⽤类型创建的变量所占内存空间的大小。
strlen: 统计的是字符串中\0之前的字符的个数。
首先:sizeof数组名和&数组名是两个特例:详见此文章
#include<stdio.h>
int main()
{
int a[] = { 1,2,3,4 };
printf("%zd\n", sizeof(a));//16
printf("%zd\n", sizeof(a + 0));//4/8
printf("%zd\n", sizeof(*a));//4
printf("%zd\n", sizeof(a + 1));//4/8
printf("%zd\n", sizeof(a[1]));//4
printf("%zd\n", sizeof(&a));//4/8
printf("%zd\n", sizeof(*&a));//16
printf("%zd\n", sizeof(&a + 1));//4/8
printf("%zd\n", sizeof(&a[0]));//4/8
printf("%zd\n", sizeof(&a[0] + 1));//4/8
}
#include<stdio.h>
int main()
{
char arr[] = { 'a','b','c','d','e','f' };
printf("%zd\n", sizeof(arr));//6
printf("%zd\n", sizeof(arr + 0));//4/8
printf("%zd\n", sizeof(*arr));//1
printf("%zd\n", sizeof(arr[1]));//1
printf("%zd\n", sizeof(&arr));//4/8
printf("%zd\n", sizeof(&arr + 1));//4/8
printf("%zd\n", sizeof(&arr[0] + 1));//4/8
return 0;
}
#include<stdio.h>
int main()
{
char arr[] = { 'a','b','c','d','e','f' };
printf("%zd\n", strlen(arr));//随机值
printf("%zd\n", strlen(arr + 0));//随机值
printf("%zd\n", strlen(*arr));err
printf("%zd\n", strlen(arr[1]));//err
printf("%zd\n", strlen(&arr));//随机值
printf("%zd\n", strlen(&arr + 1));//随机值-1
printf("%zd\n", strlen(&arr[0] + 1));//随机值-1
return 0;
}
理解了上面两个代码后,用这个思路再来写下以下两个代码
sizeof计算字符串
#include<stdio.h>
int main()
{
char arr[] = "abcdef";
printf("%zd\n", sizeof(arr));//7
printf("%zd\n", sizeof(arr + 0));//4/8
printf("%zd\n", sizeof(*arr));//1
printf("%zd\n", sizeof(arr[1]));//1
printf("%zd\n", sizeof(&arr));//4/8
printf("%zd\n", sizeof(&arr + 1));//4/8
printf("%zd\n", sizeof(&arr[0] + 1));//4/8
return 0;
}
strlen计算字符串
#include<stdio.h>
int main()
{
char arr[] = "abcdef";
printf("%zd\n", strlen(arr));//6
printf("%zd\n", strlen(arr + 0));//6
printf("%zd\n", strlen(*arr));//err
printf("%zd\n", strlen(arr[1]));//err
printf("%zd\n", strlen(&arr));//6
printf("%zd\n", strlen(&arr + 1));//随机值
printf("%zd\n", strlen(&arr[0] + 1));//5
return 0;
}
#include<stdio.h>
int main()
{
char* p = "abcdef";
printf("%zd\n", sizeof(p));//4/8
printf("%zd\n", sizeof(p + 1));//4/8
printf("%zd\n", sizeof(*p));//1
printf("%zd\n", sizeof(p[0]));//1
printf("%zd\n", sizeof(&p));//4/8
printf("%zd\n", sizeof(&p + 1));//4/8
printf("%zd\n", sizeof(&p[0] + 1));//4/8
return 0;
}
#inlude<stdio.h>
int main()
{
char* p = "abcdef";
printf("%zd\n", strlen(p));//6
printf("%zd\n", strlen(p + 1));//5
printf("%zd\n", strlen(*p));//err
printf("%zd\n", strlen(p[0]));//err
printf("%zd\n", strlen(&p));//随机值
printf("%zd\n", strlen(&p + 1));//随机值
printf("%zd\n", strlen(&p[0] + 1));//5
return 0;
}
#include<stdio.h>
int main()
{
int a[3][4] = { 0 };
printf("%zd\n", sizeof(a));//3*4*4=48
printf("%zd\n", sizeof(a[0][0]));//4
printf("%zd\n", sizeof(a[0]));//16
printf("%zd\n", sizeof(a[0] + 1));//4/8
printf("%zd\n", sizeof(*(a[0] + 1)));//4
printf("%zd\n", sizeof(a + 1));//4/8
printf("%zd\n", sizeof(*(a + 1)));//16
printf("%zd\n", sizeof(&a[0] + 1));//4/8
printf("%zd\n", sizeof(*(&a[0] + 1)));//16
printf("%zd\n", sizeof(*a));//16
printf("%zd\n", sizeof(a[3]));//16
return 0;
}
#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));// 2 5
return 0;
}
//在X86环境下
//假设结构体的⼤⼩是20个字节
//程序输出的结果是啥?
#include<stdio.h>
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;
}
#include <stdio.h>
int main()
{
int a[3][2] = { (0, 1), (2, 3), (4, 5) };
// 逗号表达式
// 1 3
// 5 0
// 0 0
int* p;
p = a[0];
printf("%d", p[0]);//1
return 0;
}
#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;
}
//假设环境是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]);
//%p-->FF FF FF FC %d-->-4
//内存中的补码直接以16进制的形式打印
//-4的原码
//10000000 00000000 00000000 00000100 -->原码
//11111111 11111111 11111111 11111011 -->反码
//1111 1111 1111 1111 1111 1111 1111 1100 -->补码
// F F F F F F F C
return 0;
}
#include<stdio.h>
int main()
{
char* a[] = { "work","at","alibaba" };
char** pa = a;
pa++;
printf("%s\n", *pa);//at
return 0;
}
#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;
}
这道考题旨在对指针的理解,我们来逐次分析这段代码。 首先:
接下来一段段剖析接下来代码。
本来cpp指向了cp的首元素的地址,++cpp使其指向了cp的第二个元素的地址,两次解引用则得到了POINT。
++cpp指向了cp的第三个元素的地址,然后解引用再–指向c的首元素的地址==,再次解引用得到ENTER的首元素地址,然后+3得到E的地址。
cpp[-2]等同于*(cpp-2),因此cpp[-2]指向了cp的首元素的地址,再解引用得到c的第四个元素的地址,然后+3指向了S这个元素地址。
cpp[-1][-1]等同于*(*(cpp-1)-1),即得到了NEW的首元素的地址,再+1得到E的地址。