首页 > 其他分享 >指针 + 数组 较为复杂凌乱的 【笔试题】

指针 + 数组 较为复杂凌乱的 【笔试题】

时间:2024-10-10 20:21:02浏览次数:10  
标签:指向 int 笔试 地址 数组 凌乱 cpp cp 指针

2024 - 10 - 10 - 笔记 - 25
作者(Author): 郑龙浩 / 仟濹(CSDN 账号名)

【指针 + 数组】的 各种题型(笔试题)

来自于鹏哥的网课,我做一下笔记

119. 【C语言进阶】笔试题详解(4)_哔哩哔哩_bilibili

① 题
#include <stdio.h>
int main()
{
    int a[5] = { 1, 2, 3, 4, 5 };
    //&a 是整个数组的地址,+1是跳过这个数组,所以该指针指向到了数组后面
    int* ptr = (int*)(&a + 1);
    //*(a + 1): a 为数组的首元素地址(第 0 个元素地址),a + 1 是数组第 1 个元素地址,解引用第 1 个元素地址得出的就是 第 1 个元素
    //ptr - 1: 上面知道了ptr指向的是数组的后边,那么 ptr - 1指向的就是数组的最后一个元素
    printf("%d, %d", *(a + 1), *(ptr - 1) );
    
    return 0;
}

打印结果:

2, 5

② 题

注:结构体大小是按照最大的成员来计算的

//结构体的大小是  4 byte * 5 == 20 byte
struct Test
{
 int Num;
 char *pcName;
 short sDate;
 char cha[2];
 short sBa[4];
}*p = (struct Test*)0x100000;
//这里的p是一个结构体指针变量,是可以指向如上这样结构体的一个指针

假设p 的值为0x100000。 如下表表达式的值分别为多少?
已知,结构体Test类型的变量大小是 20 byte

int main()
{
//结构体指针 + 1 --> 跳过整个结构体
 printf("%p\n", p + 0x1);//0x100000 + 0x1 ==> 0x100000 + 20 ==> 0x100000 + 0x14 ==> 0x100014
    
//长整形 + 1 --> 长整形 + 1(记住,这是一个坑,这里的指针p被强制类型转换为了【无符号长整形】的数据,表示的不是指针了)
 printf("%p\n", (unsigned long)p + 0x1);//0x100000 + 0x1 ==> 1,048,576 + 1 ==> 0x100000 + 0x1 ==> 0x100001
    
//整型指针  + 1 --> 跳过一个int类型的大小
 printf("%p\n", (unsigned int*)p + 0x1);//0x100000 + 0x1 ==> 0x100000 + 4 ==> 0x100000 + 0x4 ==> 0x10004
 return 0;
}

打印结果:

0x100014
0x100001
0x10004

③ 题

int main()
{
    int a[4] = { 1, 2, 3, 4 };
    
    //&a + 1 跳过了整个数组,再将【数组地址】强制类型【元素地址】赋给 ptr1,此时ptr指向数组后边
    int *ptr1 = (int *)(&a + 1);
    
    //a是首元素地址,将元素地址强制转换为【int型的数值】,得出int型的数值 + 1,再强制类型转换为 int*
    int *ptr2 = (int *)((int)a + 1);
    
    //ptr[-1]就是从ptr位置往前走了一个位置
    //从原来a数组的后边位置(可以想成a[5])变成了a[4]
    printf( "%x,%x", ptr1[-1], *ptr2);
    return 0;
}

下面进行逐个分析,因为电脑作图不是很方便,所以在纸上写的:

在这里插入图片描述

打印结果:

4,2000000

④ 题

#include <stdio.h>
int main()
{
    
    //在括号中数字用逗号分隔,那么得出的结果为最后一个逗号后边的数
    int a[3][2] = { (0, 1), (2, 3), (4, 5) };
    int *p;
    
    //p指向首元素地址,所以取出来的值为1
    p = a[0];
    printf( "%d", p[0]);//1
 return 0;
}

打印结果:

1

⑤ 题

int main()
{
    int a[5][5];
    int(*p)[4];
    
    //p为数组指针,指向了a的第一行
    p = a;
    printf( "%p,%d\n", &p[4][2] - &a[4][2], &p[4][2] - &a[4][2]);
    return 0;
}

这个就要画图理解了, 其实和第 ③ 题还是蛮像的,下面为手绘的图:

在这里插入图片描述

FFFFFC,-4

⑥ 题

int main()
{
    int aa[2][5] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
    
    //aa第 0 行的地址,&aa表示整个数组的地址
    //+ 1 就是跨过了整个数组,指向了整个数组的后边
    //然后再将二维数组地址类型的地址强制类型转换为一个元素的地址,或者说是一个变量的地址
    //所以ptr1就是指向了aa数组的后边(挨着)
    int *ptr1 = (int *)(&aa + 1);
    
    //aa是第 0 行的地址
    //aa + 1 就是第 1 行的地址
    //*(aa + 1) 就是第 1 行 第 0 个元素的地址
    //ptr2 指向第 1 行 第 0 个元素的地址,也就是&a[1][0]
    int *ptr2 = (int *)(*(aa + 1));
    
    //因为在二维数组中,所有元素的地址都是连续的,所以-1后,打印的元素是都是原本指向位置的前一个
    printf( "%d,%d", *(ptr1 - 1), *(ptr2 - 1));
    return 0;
}

打印结果:

10,5

⑦ 题

#include <stdio.h>
int main()
{
 char *a[] = {"work","at","alibaba"};
 //pa指向a的首元素地址
 char**pa = a;
 //指向下一个元素
 pa++;
 printf("%s\n", *pa);//at
 return 0;
}

打印结果:

at

⑧ 题 - 挺复杂的

int main()
{
 char *c[] = {"ENTER","NEW","POINT","FIRST"};
 char**cp[] = {c+3,c+2,c+1,c};
 char***cpp = cp;
    
//cpp指向的是cp的首地址,即cp[0],也就是元素 c + 3 的位置,而cpp中存的是&cp[0]
//++cpp,指向cp[1],也就是元素 c + 2 的位置,而cpp中存的是&cp[1]
//*++cpp,是解引用&cp[1],得出cp[1]
//**++cpp,接上文,解引用cp[1],即解引用 c + 2,或者说是*(c + 2),得出来的是POINT
 printf("%s\n", **++cpp);//POINT

//如果cpp前面没有另一个变量或者常量或者地址,那么前面这些符号*--*++就没有所谓的计算顺序,优先级也不存在了,此时哪个符号离cpp最近先算哪一个
//++cpp cpp指向了cp[2],此时cpp中存储的是 &cp[2]
//*++cpp 相当于对&cp[2]进行解引用,得出来的是cp[2]
//--*++cpp 相当于是--cp[2],也就是相当于是--(c + 1),这里更改了cp数组中存储的地址,将cp[2]的元素--后,c + 1后,cp[2]就是c
//*--*++cpp 相当于 *c,是字符串"ENTER"中的第 1 个字符'E'的地址,如果打印格式为“ %s ”,得出来的是ENTER
//*--*++cpp 相当于*(c + 3),此时是字符串"ENTER"中的第 2 个字符'E'的地址
 printf("%s\n", *--*++cpp+3);//ER

//在理解次行代码之前,要先知道前面的运算已经
//1. 将cp[2]变成 c
//2. 将cpp指向了cp[2],即cpp存 &cp[2]

//cpp[-2] 相当于*( cpp - 2 ),由上可得,此时 cpp 指向的是cp[2],也就是 cpp 中存储的是 &cp[2],那么cpp - 2指向的就是cp[0],也就是cpp - 2表示的地址实际上是&cp[0],所以*cpp[2]可以相当于是cp[0] --> 得出 *cpp[-1] 就是 c + 3
//*cpp[-2] 此时将cpp[-2]进行解引用,其实就是*( c + 3 ),解引用后指向的就是字符串"FIRST"中的字符'F'
//*cpp[-2] + 3 此时指向了常量字符串"FIRST"中的字符'f'
 printf("%s\n", *cpp[-2]+3);

//在理解次行代码之前,要先知道前面的运算已经
//1. 将cp[2]变成 c
//2. 将cpp指向了cp[2],即cpp存 &cp[2]

//cpp[-1][-1] 意思其实就相当于 *(  *(cpp - 1) - 1  ),实际上就是*(  *( &cp[2] - 1) - 1  ),得出来就是*(  *cp[1] - 1  ) <   ==   > *(   c + 2 - 1   ) < == > * (   c + 1   ) 此时意思就是指向了常量字符串"NEW"的常量'N'
//cpp[-1][-1] + 1 就是 * ( c + 1 ) + 1,就是指向了常量'N'的下一个常量,即指向了'E'
 printf("%s\n", cpp[-1][-1]+1);//EW
 return 0;
}

打印结果:

POINT
ER
ST
EW

标签:指向,int,笔试,地址,数组,凌乱,cpp,cp,指针
From: https://blog.csdn.net/m0_60605989/article/details/142830562

相关文章

  • 荣耀 10.8 开发笔试 笔经
    我好像是卷1第一题:完善字符串输入字符串(子串数、子串,形如2abc123456789),子串未满8个则填充0使其总长度达到8个字符,超过8个则分割核心部分:for(Stringpart:parts){//处理每8个字符for(inti=0;i<part.length();i+=8){Stringchunk=part.subs......
  • 关于常量指针和指针常量
    关于常量指针和指针常量知乎上看到一篇关于这两个概念的理解,感觉挺通俗易懂的,在此记录一下。①constintp;②constint*p;③intconst*p;④int*constp;⑤constint*constp;⑥intconst*constp;第一种是常量整数,没什么好说的。后面五种是指针,有一个简便的......
  • 43 C 程序动态内存分配:内存区域划分、void 指针、内存分配相关函数(malloc、calloc、re
    目录1 C程序内存区域划分1.1代码区(CodeSection)1.2全局/静态区(Global/StaticSection)1.3栈区(StackSection)1.4 堆区(HeapSection)1.5动态内存分配2void指针(无类型指针)2.1void指针介绍2.2void指针的作用2.3void指针的特点2.4 void指针类......
  • 指针 重点干货2
    小伙伴们,如果没有看指针重点干货1的,可以去我博客里先看那篇,再看这篇哦~目录六.空间大小七.解引用访问字节八.void*指针九.const修饰指针十.野指针1.指针变量没有初始化2.指针越界访问3.避免返回局部变量的地址4.注意开辟的指针释放后要归为空指针十一.重难点分析2......
  • 2024年华为OD笔试机试E卷- 补种未成活胡杨 (java/c++/python)
    华为OD机试E卷2024真题目录(java&c++&python)本人习惯先看输入输出描述,可以明确知道哪些数据已知,需要去得到什么结果,再代入更有目的性地阅读题干内容,快速理解,所以把输入输出描述放在前面,你可以试下这样阅读对你是否有帮助。输入描述N总种植数量1≤N≤100000M......
  • 2024年华为OD笔试机试E卷- 关联子串 (java/c++/python)
    华为OD机试E卷2024真题目录(java&c++&python)本人习惯先看输入输出描述,可以明确知道哪些数据已知,需要去得到什么结果,再代入更有目的性地阅读题干内容,快速理解,所以把输入输出描述放在前面,你可以试下这样阅读对你是否有帮助。输入描述输入两个字符串,分别为题目中描述的......
  • 智能指针的创建
    智能指针是C++中用于自动管理动态分配内存的工具,主要有三种类型:std::unique_ptr、std::shared_ptr和std::weak_ptr。下面是如何创建和使用这些智能指针的详细说明:1.std::unique_ptr用途:std::unique_ptr是一种独占式智能指针,确保指向的对象在同一时间只能被一个指针拥有......
  • 24南邮科协电子部笔试题 模拟基础
    第一题仅用KVL做题步骤:1.规定正方向。不妨规定顺时针为正方向。规定方向的主要目的是确定各个元器件的电压是降压还是升压。2.假设各个未知元器件的电压值和正负方向。如图3.数清回路数量,以回路为单位列KVL方程以回路1列KVL方程,升压为负,降压为正,代数和为0。不妨按照......
  • Java 指针与引用全解析
    (一)Java的发展与指针引用概念Java作为一种广泛应用的编程语言,在发展过程中借鉴了许多其他语言的特性,同时也进行了创新和改进。其中,与C++的关系尤为密切。虽然Java没有像C++那样明确的指针定义,但在底层逻辑上,Java的引用实际上与C++的指针有着相似之处。Java的设......
  • 双指针
    双指针同向指针快慢指针从两端向中间的指针其他922.按奇偶排序数组II#include<vector>usingnamespacestd;classSolution{public://时间复杂度O(n),额外空间复杂度O(1)vector<int>sortArrayByParityII(vector<int>&nums){inteven=0......