C语言指针plus版练习

news2024/10/5 17:37:51

        上期我们讲了进阶的指针,本期内容我们来强化一下上期学的内容

一、字符串左旋

       实现一个函数,可以左旋字符串中的k个字符。

        1.1 分析题目

        假设字符串为abcde,左旋一个以后就变成bcdea,就是把第一个字符移到一个新的变量里面,再把后一个字符移到前一个字符上,再把第一个字符放到最后一里就行啦

        1.2 解题代码

void left_move(char arr[], int sz, int n)
{
	while (n % sz)
	{
		//将第一个元素存入tmp
		char tmp = arr[0];
		int i = 0;
		//将后一个元素存入前一个
		for (i = 0; i < sz - 1; i++)
		{
			arr[i] = arr[i + 1];
		}
		//将tmp存入最后一个元素
		arr[i] = tmp;
		n--;
	}
}

int main()
{
	char arr[] = "abcdef";
	int n = 0;
	int sz = strlen(arr);
	scanf("%d", &n);
	left_move(arr,sz, n);
	printf("%s\n", arr);
	return 0;
}

        

        1.3 另解

        聪明的你一定发现了此题另有他法,太聪明了太聪明了!

        只要仔细观察,我们其实可以发现,左旋x个字符,就将前x个字符反过来,再将剩下的字符反过来,最后把全部的字符再反过来就可以得到

        

        所以代码也可以这样写

void left_move(char arr[],int sz, int n)
{
	//反转前n个
	rollback(arr, arr + n - 1);
	//反转剩下的
	rollback(arr + n , arr + sz - 1);
	//反转全部
	rollback(arr, arr + sz - 1);
}

int main()
{
	char arr[] = "abcdef";
	int n = 0;
	int sz = strlen(arr);
	scanf("%d", &n);
	left_move(arr, sz, n % sz);
	printf("%s\n", arr);
	return 0;
}

二、指针和数组试题解析

        除了&数组名和sizeof(数组名),这两个情况表示整个数组,其他都是表示数组首元素地址

        2.1 一维整型数组

        我们一个一个来分析:

        1. sizeof( a ),这里的a表示整个数组,因此他的大小为——>16字节

        2. sizeof( a+0 ),这里的a不是单独放在数组里面的,所以这里的a表示数组首元素地址,a+0也是表示首元素地址,是地址就是4/8个字节

        3. sizeof( *a+0 ),*a表示数组的第一个元素+0以后也是整型的,所以这里是4个字节

        4. sizeof( a+1 ),a是数组首元素地址,a+1就是数组第二个元素的地址,是地址就是4/8个字节

        5. sizeof(a[ 1 ]), a[ 1 ] 等价于 *( a + 1),就是数组中第二个元素的大小,因为是int型,所以是4个字节

        6. sizeof( &a ), &a就是取出数组a的地址,是地址就是4/8个字节

        7. sizeof( *&a ), *&a就是先取出整个数组的地址,然后再解应用,所以和sizeof( a )是一样的,16个字节

        8. sizeof( &a + 1), &a + 1是跳过整个数组取出的地址,是地址就是4/8个字节

        9. sizeof( a[ 0 ]), a[ 0 ] 就是* ( a + 0),也就是数组中第一个元素的地址,是地址就是4/8个字节

        10. sizeof( a[ 0 ] + 1 ),  就是* ( a + 0 ) + 1,也就是数组中第二个元素的地址,是地址就是4/8个字节

        答案如下:

        2.2 一维字符数组

        2.2.1 char arr[] = {'a','b','c','d','e','f'};

        sizeof

        1. sizeof( arr ), 就是数组占用空间的大小,所以为6个字节

        2. sizeof( arr + 0 ),这里arr没有单独放在sizeof中,因此它表示数组中首元素的地址,是地址就是4/8个字节

        3. sizeof( *arr ), 同上,arr表示数组首元素地址,解引用之后就是数组首元素的大小,所以是1个字节

        4. sizeof( arr[ 1 ]), arr[ 1 ]等价于*(arr + 1),就是数组中第二个元素的大小,就是1个字节

        5. sizeof( &arr), &arr表示取出整个数组的地址,是地址就是4/8个字节

        6. sizeof( &arr + 1 ),&arr + 1表示跳过这个数组取出的地址,是地址就是4/8个字节

        7. sizeof( &arr[0] + 1), &arr[ 0 ] + 1,表示数组的第二个元素的地址,是地址就是4/8个字节

          答案如下:

        strlen

        1. strlen( arr ), 表示从数组首元素开始,直到‘\0’出现的字符个数,因此是个随机值

        2.strlen( arr + 0 ), 同上,随机值

        3. strlen( *arr ), 这里的意思为strlen( ‘a’ )就是strlen( 97 ),传给strlen是一个非法的地址,非法访问

        4.strlen( arr[ 1 ]), 同上,非法访问

        5. strlen( &arr ), &arr 虽然是数组的地址,但也是从数组的首元素开始找‘\0’的,所以也是随机值

        6. strlen( &arr + 1), 同上,跳过一整个数组开始找‘\0’ ,随机值

        7.  strlen( &arr[ 0 ] + 1), 同上,从第二个元素的地址开始找‘\0’, 随机值 

        答案如下:

        2.2.2 char arr[] = "abcdef";

        sizeof

        1. sizeof( arr ), 这里数组名单独放在sizeof里面,所以表示的为整个数组,大小就是7(末尾还有‘ \0 ’)

        2. sizeof( arr + 0 ), arr + 0表示首元素地址,是地址就是4/8个字节

        3. sizeof( *arr ), arr表示数组首元素,*arr就是首元素,所以就是1个字节

        4. sizeof( arr[ 1 ] ), arr[ 1 ]等价于 *(arr + 1),就是数组第二个元素,1个字节

        5. sizeof( &arr ), &arr表示取出一整个数组的大小,是数组就是4/8个字节 

        6. sizeof( &arr + 1), &arr + 1表示跳过一整个数组取出的地址,是地址就是4/8个字节

        7. sizeof( &arr[ 0 ] + 1), &arr[ 0 ] +1表示数组第二个元素的地址,是地址就是4/8个字节

        答案如下:

        strlen

        1. strlen( arr ), 这里的arr为数组首元素地址,从数组首元素开始找‘ \0 ’,所以为6

        2. strlen( arr + 0), 同上,为6

        3. strlen( *arr ), 意为strlen( ‘ a ’ ),就是strlen( 97 ), 非法访问

        4. strlen( arr[ 1 ]), 同上,非法访问     

        5. strlen( &arr ), arr虽然是数组的地址,但也是从首元素开始找‘ \0 ’,所以为6

        6. strlen( &arr + 1), 跳过整个数组开始找,随机值

        7. strlen( &arr[ 0 ] + 1), 跳过数组首元素开始找‘ \0 ’,所以为6   

        答案如下:

        2.2.3 指针型

        sizeof

        1. sizeof( p ), 这里指针p指向的是字符串的首个字符的地址,所以sizeof( p )就是第一个字符的地址的大小,是地址就是4/8个字节

        2. sizeof( p + 1 ), 就是指向第二个字符的地址的大小,是地址就是4/8个字节

        3. sizeof( *p ), 就是‘ a ’的大小,为1个字节

        4. sizeof( p[ 0 ]), p[ 0 ]就是*( p + 0 ),和上一个一样,大小为1个字节  

        5. sizeof( &p ), &p就是取出p的地址,是二级指针,是地址就是4/8个字节

        6. sizeof( &p +1 ), &p + 1,和上一个类似,跳过指针p取下一个地址,是地址就是4/8个字节

        7. sizeof( &p[ 0 ] + 1), &p[ 0 ]是‘ a ’的地址,+1就是‘ b ’的地址,是地址就是4/8个字节

        答案如下:

        strlen

        1. strlen( p ) ,就是从第一个字符‘ a  ’开始找‘ \0 ’,所以为6

        2. strlen( p + 1 ), 跳过‘ a ’,从‘ b ’ 开始找‘ \0 ’ ,所以为5

        3. strlen( *p ), 非法访问

        4. strlen( p[ 0 ]), p[ 0 ]和*( p + 0 )一样,所以也是非法访问  

        5.strlen( &p ), 从p的地址开始找‘ \0 ’ ,为随机值

        6. strlen( &p + 1 ), 跳过p的地址开始找‘ \0 ’,为随机值

        7. strlen( &p[ 0 ] + 1),  &p[ 0 ]为‘ a ’的地址,所以+1就是‘ b ’的地址,所以为5

        答案如下:

        2.3 二维数组

        上强度咯~

        1. sizeof( a ), 这里数组名a单独存放在sizeof中,因此表示整个数组,所以他的大小为48个字节

        2. sizeof( a[ 0 ][ 0 ] ), 为数组中第一个元素的大小,就是4个字节

        3. sizeof( a[ 0 ] ), 是第一行的数组名,单独放在sizeof中,为数组第一行的元素大小,就是16个字节

        4. sizeof( a[ 0 ] + 1 ), a[ 0 ]没有单独放在sizeof中,所以表示a[ 0 ]数组中的首元素地址,也就是a[ 0 ][ 0 ]的地址,+1就是a[ 0 ][ 1 ]的地址,是地址就是4/8个字节

        5.sizeof( *( a[ 0 ] + 1)), 表示a[ 0 ][ 1 ]的大小,就是4个字节

        6.sizeof( a + 1), a没有单独存放在sizeof中,所以这里表示数组a的首元素地址,就是数组a[ 0 ]的地址,是地址就是4/8个字节

        7. sizeof( *( a+ 1)), 就是数组a[ 0 ]的大小,就是16个字节

        8.sizeof( &a[ 0 ] + 1), &a[ 0 ]表示取出数组a[ 0 ]的地址,+1就是a[ 1 ]的地址,是地址就是4/8个字节

        9. sizeof( *( &a[ 0 ] + 1)),   就是数组a[ 1 ]的大小,就是16个字节

        10. sizeof( *a ), a没有单独存放在sizeof中,所以表示首元素地址,就是a[ 0 ],所以是16个字节

        11. sizeof( a[ 3 ] ), a[ 3 ]等价于*( a + 3),越界访问了,但是大小依然是16个字节

        答案如下:

三、指针笔试题

#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 main()
{
	char* a[] = { "work","at","alibaba" };
	char** pa = a;
	pa++;
	printf("%s\n", *pa);
	return 0;
}
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;
}

        上面代码结果是什么?

        答案评论666我私信给你

        给我三连的都是帅哥美女~

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2190253.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

5G NR BWP 简介

文章目录 BWP介绍BWP 分类BWP相关总结 BWP介绍 5G NR 系统带宽比4G LTE 大了很多&#xff0c;4G LTE 最大支持带宽为20MHz&#xff0c; 而5G NR 的FR1 最大支持带宽为100MH在&#xff0c; FR2 最大支持带宽为 400MH在。带宽越大&#xff0c;意味了终端功耗越多。为了减少终端的…

哪款百元头戴式耳机性价比高?四款大火爆全网的机型盘点推荐!

在繁忙的生活节奏中&#xff0c;寻找一片属于自己的宁静空间&#xff0c;成为了许多人的内心渴望。头戴式降噪耳机&#xff0c;正是那把打开音乐世界的钥匙。它不仅能够隔绝外界的喧嚣&#xff0c;还能将您带入一个纯净无瑕的音乐世界。无论是沉浸在古典乐的悠扬旋律中&#xf…

数据服务-存储服务(NFS)

1.概述 存储: 用于存放用户上传的内容(数据),一般应用在网站集群中 如果不使用存储,用户上传的数据就直接存放在网站服务器上了,用户下次访问就可能找不到 如果使用存储,用户上传的内容存放在存储上面,用户访问就会访问存储. 位置: 网站后排. 2. 存储分类 分类说明硬件存储硬件…

【高等数学学习记录】函数的极限

一、知识点 &#xff08;一&#xff09;知识结构 #mermaid-svg-Dz0Ns0FflWSBWY50 {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-Dz0Ns0FflWSBWY50 .error-icon{fill:#552222;}#mermaid-svg-Dz0Ns0FflWSBWY50 .erro…

KiCad 综合笔记

开窗 选中顶层或者底层 Mask 层,然后进行覆铜: 四层板 KiCad Tutorial - How to make a 4 layer PCB https://bbs.elecfans.com/jishu_2365544_1_1.html 虽然在“电路板设置”中,可以选择铜层的类型,但如果选择了“电源层”,除了用于告诉“Free router”布线器在自动布…

vue3+vite@4+ts+elementplus创建项目详解

1、第一步创建项目cnpm init vite4 2、设置vue3.2局域网可访问配置&#xff1a; 找到项目路径下的package.json目录下找到script对象下面添加一下代码&#xff1a; "serve": "vite --host 0.0.0.0" 启动项目命令不在是dev而是&#xff1a;cnpm run serve 3…

Linux中的进程信号

目录 进程信号 kill/raise/abort 硬件异常产生信号 由软件条件产生信号 信号在内核中的表示示意图 pending: block: 信号集操作函数 sigprocmask 进程信号 信号量和信号不同 信号量的本质是计数器&#xff0c;计数器可以被多进程同时看到。可以对资源进行预定。 所有进…

OpenJudge | 置换选择排序

总时间限制: 1000ms 内存限制: 65536kB 描述 给定初始整数顺串&#xff0c;以及大小固定并且初始元素已知的二叉最小堆&#xff08;为完全二叉树或类似完全二叉树&#xff0c;且父元素键值总小于等于任何一个子结点的键值&#xff09;&#xff0c;要求利用堆实现置换选择排序&a…

程序员如何在 AI 时代保持核心竞争力

前言 随着 AIGC 大语言模型的不断涌现&#xff0c;AI 辅助编程工具的普及正在深刻改变程序员的工作方式。在这一趋势下&#xff0c;程序员面临着新的挑战与机遇&#xff0c;需要思考如何应对以保持并提升自身的核心竞争力。 目录 一、AI 对编程工作的影响 &#xff08;一&…

一、走进新语言

走进新语言 介绍环境配置JDK配置Kotlin配置 开发工具代码基本结构程序注释 介绍 Kotlin是一种现代但已经成熟的编程语言&#xff0c;旨在让开发人员更快乐。它简洁、安全、可与Java和其他语言互操作&#xff0c;并提供了许多在多个平台之间重用代码的方法。它由JetBrains公司于…

2.JUC

掌握 Java 并发编程&#xff0c;熟悉线程池、并发容器以及锁的机制&#xff0c;如 sychronized、ReentrantLock、AQS等。 2.0 并发基础 线程等待唤醒机制LockSupport (3种) 方式一&#xff1a;使用Object中的wait()方法让线程等待&#xff0c;使用Object中的notify()方法唤醒…

数据结构 ——— 单链表oj题:链表分割(带哨兵位单向不循环链表实现)

目录 题目要求 手搓简易单链表 代码实现 题目要求 现有一链表的头指针 ListNode* head &#xff0c;给一定值 x &#xff0c;编写一段代码将所有小于 x 的节点排在其余节点之前&#xff0c;且不能改变原来的数据顺序&#xff0c;返回重新排列后的链表的头节点 举例说明&a…

【包教包会】2D图片实现3D透视效果(支持3.x、支持原生、可合批)

将去年写的SpriteFlipper从2.x升级到3.x。 如果需要2.x版本或需要了解算法思路&#xff0c;请移步&#xff1a;https://blog.csdn.net/weixin_42714632/article/details/136745051 优化功能&#xff1a;可同时绕X轴和Y轴旋转&#xff0c;两者效果会叠加。 完美适配Web、原生…

typescript使用webpack打包编译问题

解决方案&#xff1a;在webpack.config.js中的mdule.exports中设置mode。 再次运行npm run start即可。

Python基本库的使用--urllib

开篇 本篇文章旨在总结urlib基本库的一些常用用法。 相关方法 urlopen 用户打开和读取URL。 import urllib.requestresponse urllib.request.urlopen(https://www.python.org) print(response.read().decode(utf-8))带data参数 import urllib.parse import urllib.requestda…

【计算复杂性理论】P可归约(归约,P-reducible)与P、NP、NP-Hard、NP-Complete问题

1 问题背景 如果想要了解P问题、NP问题、NP-Hard问题、NP-Complete问题之间的关系&#xff0c;那就需要从了解NP-complete问题和归约概念开始。上一篇文章中&#xff0c;我们介绍了计算复杂性理论的奠基之作《The Complexity of Theorem-Proving Procedures》&#xff0c;在这篇…

初识算法 · 滑动窗口(1)

目录 前言&#xff1a; 长度最小的子数组 题目解析 算法原理 算法编写 无重复长度的最小字符串 题目解析 算法原理 算法编写 前言&#xff1a; 本文开始&#xff0c;介绍的是滑动窗口算法类型的题目&#xff0c;滑动窗口本质上其实也是双指针&#xff0c;但是呢&#…

初识数据结构--时间复杂度 和 空间复杂度

数据结构前言 数据结构 数据结构是计算机存储、组织数据的方式(指不仅能存储数据&#xff0c;还能够管理数据-->增删改)。指相互之间存在一种或多种特定关系的数据元素的集合。没有单一的数据结构对所有用途都有用&#xff0c;所以我们要学习各种的数据结构&#xff0c;比…

[Python] 编程入门:理解变量类型

文章目录 [toc] 整数常见操作 浮点数字符串字符串中混用引号问题字符串长度计算字符串拼接 布尔类型动态类型特性类型转换结语 收录专栏&#xff1a;[Python] 在编程中&#xff0c;变量是用于存储数据的容器&#xff0c;而不同的变量类型则用来存储不同种类的数据。Python 与 C…

Springboot项目整合RabbitMQ+Redis实现可靠的阿里云短信异步收发功能(手把手实操详细教程)

文章目录 1、项目介绍1.1、项目描述1.2、项目结构 2、创建项目(idea)2.1、依赖引入2.2、 配置文件2.3、 数据库表2.4、 实体类2.5、 配置类2.6、 验证码服务类2.7、 短信发送服务类2.8、 消费者类2.9、发送服务类2.10、定时任务类2.11、启动类2.12、测试控制器 3、效果测试4、总…