C语言-指针笔试题详解

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.

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值