1.
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;
}
2.
#include <stdio.h>
int main()
{
char *a[] = {"work","at","alibaba"};
char**pa = a;
pa++;
printf("%s\n", *pa);
return 0;
}
char**pa:*pa表示pa是一个指针变量,这个指针变量中存储的数据是一级指针变量的地址。
pa++:因为pa中保存的是地址,而在64位的机器下,pa + 1一次跳过8个字节,那么此时pa中保存的就是a数组的第二个元素的地址,所以结果是at。
其实此时对pa进行操作,可以将这个操作类比为对a这个数组的首元素的地址进行操作。
3.
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;
}
int aa[2][5]:aa[2]表示这是一个有两个元素组成的数组,int [5]表示这个数组中每个元素的类型。
整体表示这是一个由两个元素组成的数组,而其中每个元素又是一个由5个int类型元素组成的数组。
其中&aa表示整个二维数组的地址,(&aa)+ 1一共会跳过40个字节。
sizeof单独处理数组名得到的结果是整个数组所占的字节数。
aa是这个二维数组的数组名,而数组名表示数组首元素的地址,而这个地址的类型是:
从而更加印证了aa的数组元素是一个数组。
*aa,aa[0]表示aa这个二维数组的第一个元素中的数组的数组名。
所以对于int *ptr1 = (int *)(&aa + 1);是对整个二维数组后面的一个地址进行强转。
int *ptr2 = (int *)(*(aa + 1));是对二维数组的第二个元素中的数组的数组名进行强转。
所以最后的结果是10,5.
4.
32位下
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;
}
5.
#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;
}
首先int a[3][2] = { (0, 1), (2, 3), (4, 5) };这里是使用逗号表达式对二维数组进行赋值。
所以只有1 3 5被二维数组接收了。
所以最后的结果是1。
6.
int main()
{
int a[4] = { 1, 2, 3, 4 };
int *ptr1 = (int *)(&a + 1);
int *ptr2 = (int *)((int)a + 1);
printf( "%x,%x", ptr1[-1], *ptr2);
return 0;
}
7.
struct Test
{
int Num;
char *pcName;
short sDate;
char cha[2];
short sBa[4];
}*p;
int main()
{
printf("%p\n", p + 0x1);
printf("%p\n", (unsigned long)p + 0x1);
printf("%p\n", (unsigned int*)p + 0x1);
return 0;
}
8.
int main()
{
int a[5] = { 1, 2, 3, 4, 5 };
int *ptr = (int *)(&a + 1);
printf( "%d,%d", *(a + 1), *(ptr - 1));
return 0;
}
9.
C语言中的表达式具有两个属性:
2 + 3;
a.值属性 5 。
b.类型属性 int 。
sizeof中的表达式的数值计算不会发生只会发生类型计算。
#include <stdio.h>
int main()
{
//一维数组
int a[] = { 1,2,3,4 };
printf("%d\n", sizeof(a));//16 a表示数组名,将数组名单独由sizeof处理得到的是整个数组所占的字节数,
printf("%d\n", sizeof(a + 0));//4/8 a + 0 因为sizeof是在编译阶段被处理的所以sizeof中的表达式的值属性不会被计算,但是类型属性会被计算为int*
printf("%d\n", sizeof(*a));//4 *a 是数组的第一个元素,其数据类型是整型
printf("%d\n", sizeof(a + 1));//4/8 是数组的第二个元素的地址
printf("%d\n", sizeof(a[1]));//4 数组的第一个元素
printf("%d\n", sizeof(&a));//4/8 是整个数组的地址,加1会跳过12个字节
printf("%d\n", sizeof(*&a));//16 sizeof单独处理数组名时才会返回整个数组所占的空间的大小
printf("%d\n", sizeof(&*a));//4/8 只有sizeof单独处理数组名时才会返回整个数组所占的空间的大小,此处显然不是
printf("%d\n", sizeof(&a + 1));//4/8 是整个数组的地址,加1会跳过12个字节,但是依旧是地址
printf("%d\n", sizeof(&a[0]));//4/8 是数组首元素的地址
printf("%d\n", sizeof(&a[0] + 1));//4/8 数组第二个元素的地址
}
10.
//字符数组
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
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));//随机数
11.
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));//4/8
printf("%d\n", sizeof(&arr[0] + 1));//4/8
printf("%d\n", strlen(arr));//6
printf("%d\n", strlen(arr + 0));//6
//printf("%d\n", strlen(*arr));//报错非法访问
//printf("%d\n", strlen(arr[1]));//报错非法访问
printf("%d\n", strlen(&arr));//7
printf("%d\n", strlen(&arr + 1));//随机值
printf("%d\n", strlen(&arr[0] + 1));//5
12.
char* p = "abcdef";
printf("%d\n", sizeof(p));//4/8
printf("%d\n", sizeof(p + 1));//4/8
printf("%d\n", sizeof(*p));//1
printf("%d\n", sizeof(p[0]));//1
printf("%d\n", sizeof(&p));//4/8 是指针变量p的地址
printf("%d\n", sizeof(&p + 1));//4/8
printf("%d\n", sizeof(&p[0] + 1));//4/8
printf("%d\n", strlen(p));//6
printf("%d\n", strlen(p + 1));//5
//printf("%d\n", strlen(*p));//报错非法访问
//printf("%d\n", strlen(p[0]));//报错非法访问
printf("%d\n", strlen(&p));//6 虽然我们传入的地址的数组指针但是会发生强转
printf("%d\n", strlen(&p + 1));//随机值
printf("%d\n", strlen(&p[0] + 1));//5
12.
//二维数组
int a[3][4] = { 0 };
printf("%d\n", sizeof(a));//48
printf("%d\n", sizeof(a[0][0]));//4
printf("%d\n", sizeof(a[0]));//16 a[0]得到的是二维数组的第一行数组的数组名,sizeof在单独处理数组名的时候得到的是整个数组所占的空间的大小
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]));//16 sizeof之对类型进行计算,不会检查具体所占的空间用户是否具有权限
13.