1.指针和数组笔试题解析

关键:数组名在两种情况下是指整个数组:
(1)sizeof(数组名)(2)&数组名
其它的情况下,都是代表数组的首元素地址。

例题 1 :一维数组

int main()
{
//一维数组
int a[] = { 1,2,3,4 };

printf("%d\n", sizeof(a));
//此时的表达式只是数组名a,代表的是整个数组,sizeof计算的是整个数组的大小,为4*4=16个字节。printf("%d\n", sizeof(a + 0));
//a+0是表达式,数组名a代表的是数组的首元素地址,为int型指针变量,
//+0后还是int型指针变量,大小是4/8个字节。printf("%d\n", sizeof(*a));
//*a不是单纯的数组名,a表示的首元素的地址,解引用后为int整数1,其大小是4个字节。printf("%d\n", sizeof(a + 1));
//a+1是表达式,数组名a表示的是首元素的地址,为int型指针变量,
//+1后还是int型指针变量,大小是4/8个字节。printf("%d\n", sizeof(a[1]));
//a[1]表示的整型2,为int变量,其大小是4个字节printf("%d\n", sizeof(&a));
//此时的数组名a表示的整个数组,&a后表示的数组指针,是指针,占4/8个字节printf("%d\n", sizeof(*&a));
//此时的数组名a表示的是整个数组,&a后解引用后是数组名a,此时单纯的数组a,表示的整个数组
//其大小是4*4=16个字节printf("%d\n", sizeof(&a + 1));
//&a是整个数组的地址,+1后还是表示地址,是地址,其大小是4/8printf("%d\n", sizeof(&a[0]));
//数组首元素取地址,是地址,其大小是4/8printf("%d\n", sizeof(&a[0] + 1));
//数组首元素取地址后+1还是表示地址,是地址,其大小是4/8。return 0;

}

例题 2 :字符数组

int main()
{
//字符数组
char arr[] = { ‘a’,‘b’,‘c’,‘d’,‘e’,‘f’ };

printf("%d\n", sizeof(arr));
//数组名表示这个数组,计算的整个数组的大小,为1*6=6printf("%d\n", sizeof(arr + 0));
//此时为表达式,数组名表示的首元素的地址,+0之后还是地址,是地址,其大小为4/8printf("%d\n", sizeof(*arr));
//数组名arr此时为数组首元素,解引用后为字符‘a’,其大小为1个字节printf("%d\n", sizeof(arr[1]));
//此时计算的数组第二元素‘b’,其大小为1个字节printf("%d\n", sizeof(&arr));
//此时数组名为整个数组,&arr 代表是数组指针,是指针,是地址,其大小为4/8printf("%d\n", sizeof(&arr + 1));
//此时数组名为整个数组,&arr代表的是数组指针,加一后还是指针,是地址,其大小为4/8个字节printf("%d\n", sizeof(&arr[0] + 1));
//&a[0]是char*类型的指针,加一后还是指针,是地址,其大小为4/8个字节。return 0;

}
#include<string.h>
int main()
{
char arr[] = { ‘a’,‘b’,‘c’,‘d’,‘e’,‘f’ };

printf("%d\n", strlen(arr));
//此时的数组名是首元素的地址,但是该数组没有以'\0'结尾,所得的值是随机的printf("%d\n", strlen(arr + 0));
//同上printf("%d\n", strlen(*arr));
//此时的数组名是首元素的地址,解引用后是‘a’->97 ,此时非法访问地址97,errorprintf("%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;

}

int main()
{
char* p = “abcdef”;

printf("%d\n", sizeof(p));
//p是一个char *类型的指针,是地址,其大小为4/8个字节printf("%d\n", sizeof(p + 1));
//同上printf("%d\n", sizeof(*p));
//p指向的是字符串的首元素a的地址,解引用后得到字符a,其大小为1个字节。printf("%d\n", sizeof(p[0]));
//同上printf("%d\n", sizeof(&p));
//&p是得到变量p的地址,是二级指针,是地址,其大小为4/8printf("%d\n", sizeof(&p + 1));
//同上printf("%d\n", sizeof(&p[0] + 1));
//&p[0]得到的是字符a的地址,加一后还是地址,是地址,其大小为4/8printf("%d\n", strlen(p));
//得到整个字符串的长度6printf("%d\n", strlen(p + 1));
//得到5printf("%d\n", strlen(*p));
//*p得到字符‘a’==97,非法访问  errorprintf("%d\n", strlen(p[0]));
//同上printf("%d\n", strlen(&p));
//&p得到的是变量p的地址,不知道结束符在哪,是随机值printf("%d\n", strlen(&p + 1));
//同上printf("%d\n", strlen(&p[0] + 1));
//&p[0]得到的是字符a的地址,加1后得到的是字符b的地址,得到5return 0;

}

int main()
{
char arr[] = “abcdef”;
printf(“%d\n”, sizeof(arr));
//此时数组名arr是整个数组的地址,其大小为7*1=7

printf("%d\n", sizeof(arr + 0));
//此时数组名是首元素的地址,是char*类型的数据,其大小为4/8个字节printf("%d\n", sizeof(*arr));
//此时数组名为首元素的地址,解引用后是a,char类型,其大小为1个字节printf("%d\n", sizeof(arr[1]));
//arr[1]为字符b,为char类型,其大小为1个字节printf("%d\n", sizeof(&arr));
//此时的数组名是整个数组的地址,是数组指针,是地址,其大小为4/8printf("%d\n", sizeof(&arr + 1));
//此时的数组名是整个数组的地址,,是数组指针,加1后还是数组值,是地址,其大小为4/8个字节printf("%d\n", sizeof(&arr[0] + 1));
//&arr[0]是字符a的地址,是char*类型的指针,+1后还是指针,是地址,其大小为4/8个字节printf("%d\n", strlen(arr));
//此时数组名是首元素的地址,得到6printf("%d\n", strlen(arr + 0));
//同上printf("%d\n", strlen(*arr));
//*arr指的是字符a,非法访问--errorprintf("%d\n", strlen(arr[1]));
//同上printf("%d\n", strlen(&arr));
//此时的数组名是整个数组的地址,是首元素的地址,可得到6printf("%d\n", strlen(&arr + 1));
//此时数组名是整个数组的地址,+1跳过整个数组,不知道结束符在哪里,得到的值是随机的printf("%d\n", strlen(&arr[0] + 1));
//&arr[0]+1是字符b的地址,得到5return 0;

}

例题3 :二维数组

int main()
{
//二维数组
int a[3][4] = { 0 };

printf("%d\n", sizeof(a));
//此时的数组名是整个数组,其大小为3*4*4=48printf("%d\n", sizeof(a[0][0]));
//是整数0,是int类型,其大小为4个字节printf("%d\n", sizeof(a[0]));
//此时a[0]首行的数组名,是整行的数组,大小为4*4=16printf("%d\n", sizeof(a[0] + 1));
//此时a[0]是首行数组首元素的地址,+1后还是int*类型的指针,是地址,其大小为4/8printf("%d\n", sizeof(*(a[0] + 1)));
//由上知道,解引用后是int类型的整数,其大小为4printf("%d\n", sizeof(a + 1));
//此时数组名a是首元素的地址,首元素是int [4]类型的数组,
//加1后是第二行的数组地址,是地址其大小就是4/8printf("%d\n", sizeof(*(a + 1)));
//由上知,a+1是第二行的地址,解引用后int [4]类型的数组,其大小为4*4=16printf("%d\n", sizeof(&a[0] + 1));
//此时a[0]是第一行数组名,&a[0]取得是第一行数组的地址,+1后是第二行数组的地址,是地址其大小就是4/8printf("%d\n", sizeof(*(&a[0] + 1)));
//由上知&a[0] + 1是第二行的地址,解引用后是int [4]类型的数组,其大小为4*4=16printf("%d\n", sizeof(*a));
//*a得到首元素a[0],是第一行数组的数组名,此时是第一行数组的整个数组,其大小为4*4=16printf("%d\n", sizeof(a[3]));
//如果数组存在第四行,a[3]就是第四行的数组名,
//数组名单独放在sizeof内部,计算的是第四行的大小4*4=16return 0;

}

总结

数组名在两种情况下是指整个数组:
(1)sizeof(数组名)(2)&数组名
其它的情况下,都是代表数组的首元素地址。

2.指针笔试题

题目 1:

int main()
{
int a[5] = { 1, 2, 3, 4, 5 };
int *ptr = (int *)(&a + 1);
printf( “%d,%d”, *(a + 1), *(ptr - 1));
return 0;
}
//程序的结果是什么?

题目 2:

//结构体的大小是20个字节
struct Test
{
int Num;
char *pcName;
short sDate;
char cha[2];
short sBa[4];
}*p;
//假设p 的值为0x100000。 如下表表达式的值分别为多少?
//已知,结构体Test类型的变量大小是20个字节
int main()
{
printf(“%p\n”, p + 0x1);
printf(“%p\n”, (unsigned long)p + 0x1);
printf(“%p\n”, (unsigned int *)p + 0x1);
return 0;
}

题目 3:

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;
}

题目 4:

#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;
}

注意逗号表达式

题目 5:

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;
}

题目 6:

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;
}

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);

关键是画出图

c语言进阶(3)——指针进阶笔试题详解相关推荐

  1. 蘑菇街2015校招 Java研发笔试题 详解,2015java

    蘑菇街2015校招 Java研发笔试题 详解,2015java 1. 对进程和线程描述正确的是( ) A.  父进程里的所有线程共享相同的地址空间,父进程的所有子进程共享相同的地址空间. B.  改变 ...

  2. 必看:C语言高效学习方法(附经典试题详解)

    C试题100例详解 写在前面 C语言高效学习方法 正片开始: 问题描述 课题分析 算法描述 自然语言方式描述 流程图方式描述 源代码 试验结果分析与讨论 写在前面 本专栏提供多于100道C试题解答,并 ...

  3. mysql 笔试题_MySQL笔试题详解(一)(中等难度)

    有一位学生在找数据分析工作的时候,遇到一个笔试题,内容如下: 现有注册用户表table_user,有两个字段:user_id(用户id).reg_tm(注册时间).有订单表table_order,有三 ...

  4. 微软2013年笔试题详解及深入

    Microsoft 下面哪些调用转换支持可变长度参数: A. cdecl  B. stdcall  C. pascal  D. fastcall 几种函数调用方式: __cdecl 是C Declar ...

  5. 2018 年百度校招笔试题详解

    C++ 后置++ 重载 只会调用A的func() 记住大端是反过来的,小端是正的 虚函数不能申请为构造函数 C++ 多态 仔细看,C选项是C语言的内存分配. 注意是选错误的,注意一定是 剑指offer ...

  6. 剑指XX游戏(二) - 网易2011笔试题详解

    网上弄到的一份题,不是很完整,边猜边做. 1.写出运行结果 char array[] = "abcde"; char* s = array; cout<<sizeof( ...

  7. 网易2011笔试题详解

    http://blog.csdn.net/silangquan/article/details/18051675 网上弄到的一份题,不是很完整,边猜边做. 1.写出运行结果 char array[] ...

  8. 【这些题我一拿到手就会】C指针和数组试题详解(上)

    文章目录 前言 一.数组专项训练 1.一维数组 1.1.整型数组 1.2.字符数组 2.二维数组 二.指针专项训练 前言   首先感谢各位的支持!让我感受到第一次上热榜的开心,朦胧的睡意瞬间被清洗一空 ...

  9. 2019 快手校招笔试题详解

    可以理解为把5本书插到14本书的中间,即加头尾的15个空格里,有多少种组合.因为不能相邻,所以是有C(15, 5) = 3003 种方法 实际做的时候可以先计算C(19,5),可以在A,B中选一个,大 ...

最新文章

  1. 这可能是2018年IT界规模最大的裁员事件了
  2. mysql 分组排序_MySQL如何实现Excel分组排序功能?
  3. ML之HMM:HMM算法相关论文、关键步骤、测试代码配图集合
  4. 【公开课预告】百度语言与知识最新技术成果详解
  5. flex 下对齐_CSS3中Flex弹性布局该如何灵活运用?
  6. SpringMVC源码解析(四)——请求处理
  7. 软件项目管理第三课—如何应对投标书的软件功能报价
  8. IE7下position:relative的问题
  9. ui-sref与$state.go()的使用
  10. C++ ——Qt的信号和槽的详解
  11. echarts官网在线编辑的图表如何导出svg
  12. DCMTK3.6.5+cmake3.7.1+VS2017配置过程
  13. 第二章 Hadoop序列化
  14. AutoCAD Civil 3D 中缓和曲线的定义
  15. web前端开发技术实验与实践(第三版)储久良编著 项目6 文本与段落标记的应用
  16. java fillrect_Java graphics2D fillRect无法使用半透明颜色正常...
  17. 草图实时生成动漫角色!太秀了
  18. 服务器重启后jar包自动重启
  19. 数据集大小与模型性能的敏感性分析
  20. 做毕设|墨墨背单词+单词本(小程序)01

热门文章

  1. js中实现截取数组的后几个元素作为一个新数组的方法
  2. Media-媒介(媒体、介质)【译】
  3. 女生学计算机有困难吗,女生学计算机,没出路吗?
  4. android 环信发送名片,环信自定义消息类型——名片
  5. VCL界面开发必备装备!DevExpress VCL v19.1.5你值得拥有
  6. 2023.3.6-3.12 AI行业周刊(第140期):AI视觉算法开发平台
  7. C++ 迭代器 Iterator
  8. android+百度地图围栏,地理围栏
  9. 让HTTPS简单易懂
  10. if null java_IFNULL函数