C语言进阶第二篇【指针进阶】(下)

简介: C语言进阶第二篇【指针进阶】(下)

4.2 二维数组传参


15c0fb6d2f074b009a854b995eb04833.png


对于二维数组传参,我们还是要分为数组形式和指针形式接收:

1、数组形式接收:二维数组传参,我们以二维数组的形式接收完全没问题,需要注意的是:我们只能省略行,不能省略列!所以1,2都是可以的,3不行 。


2、指针形式接收:二维数组传参,传的是首元素的地址,也就是一维数组的地址,我们用一级指针来接收,肯定是不行的,所以4no;5是指针数组,根本就不是指针的形式,no;首元素的地址代表第一行的地址,我们用指向一维数组的指针来接收是刚好可以的,所以6,数组指针是ok的;传的是首元素的地址,也就是一维数组的地址,我们用二维数组接收也是不对的,我们要弄清楚我们传过去的是什么,在考虑用什么接收!所以对于二维数组传参,我们如果用指针的形式接收只能用数组指针的形式。


4.3 一级指针传参

e97c023046ca42dabcd483c2d4f87051.png


我们还是根据传过来本质是什么形式,我们就以什么样的形式 来接收!传过来的是一级指针,所以我们用一级指针来接收肯定是没问题的。


思考:反过来想,如果我们以一级指针的形式接收参数,那么传参的时候是传什么样的呢?


例如void print(char* p)来接收,我们传参?例如:char ch = 'w',我们传ch的地址&ch是可以的;char* p = &ch,这样传一级指针p也是可以的!


4.4 二级指针传参

49ed327163b6472089b4838fbc078ba3.png


二级指针传参,我们就用二级指针接收;我们要找到或者修改原来的数据,也要解应用两次。


思考:反过来想,如果我们以二级指针的形式接收参数,那么传参的时候是传什么样的呢?


例如:上面的例题,我们已知:void test(int** ptr)来接收,我们传参?


1、首先我们就传二级指针,二级指针接收,肯定是没问题的;


2、或者传一级指针的地址,二级指针接收;那么还有什么形式呢?


3、传一级指针的数组,如果我们写成指针数组的形式:int* arr[10],就传arr可以吗?前面是指针数组,里面存放的都是int*指针,arr又代表首元素的地址,最终本质也就是一级指针的地址,不也是可以的!


5. 习题补充篇


今天的指针学习就暂时到这里,最主要的就是要理解指针数组和数组指针的区别和用法!下面让我们补充一些课外题目,发散一下思维吧。


5.1 无符号数和有符号数比较大小

在做下面这道例题之前,我们要先知道两个知识点:


1.sizeof这个操作符,算出的结果返回的类型是无符号整型unsigned int


2.无符号数和有符号数比较大小,要先把有符号数转换成无符号数,在比较大小


cdfe9181ccf340c582513916222b95e5.png


a08525458a714734914231f53c281fec.png


按照我们一般的理解:i = -1,sizeof(i) = 4;最终结果应该是-1 < 4,打印出来<;但最终打印出来的结果确是>;很难让人接受。


解析:


1、这里我们先要理清局部变量和全局变量未初始化的区别:对于全局变量没有初始化,默认值为0;对于局部变量未初始化,默认是一个随机值!


2、sizeof(i)结果是4,此时的4实际上是无符号数;i--结果是-1,此时的-1是有符号数


3、无符号数和有符号数比较大小,要先把有符号数转换成无符号数,在比较大小。所以要先把有符号数-1转换成无符号数:

f161f40b264c4e3ba779f34fd3a7a240.png

所以最终打印出来的结果是:>


5.2 求Sn=a+aa+aaa+aaaa+aaaaa的前五项之和

其中a是一个数字,我们不妨就拿一组具体的数来分析:2+22+222+2222+22222


b39141600bb946b99f6170891a6e2f9f.png


有了规律,我们就写出一个通用的代码!在不考虑溢出的情况下:求任何一个数n的前m项都是可以的:

1f242abfd9324a26ac920aad3cae5fa2.png



5.3 求出0-100000之间的所有“水仙花数”并输出

"水仙花数"是指一个n位数,其各位数字的n(n是位数)次方之和刚好等于该数本身;我们之前接触的大都是三位数的水仙花数,例如:153 = ++;今天我们写一下0-100000之间的!


08990d25f181456c838737eb24190c07.png

be2387934c254d2b9766d6bfc17a1f01.png



5.4 指针练手


03345abc414346e580c60d87944ed41d.png

这道关于指针的题目其实很简单,我们只要把指针理解了就很容易得出答案:


d94669c0fc1341e3982994509baa8fa0.png

8bcc9e7899b343e78fa20be60b6c8ed2.png



5.5 打印菱形

例如:


2baa08995895461a916e90d48c319f44.png


我们首先要分两部分进行打印,上面一部分下面一部分:

2ae55493a717466f8dc0731d5e4b7488.png



我们根据图形很容易就能写出来,需要注意的是:假如要打印的大小n=4,我们上半部分打印4行,下半部分只需要打印3行就可以了!


5.6 喝汽水问题

1瓶汽水1元,2个空瓶可以换一瓶汽水,给20元,问最终可以换多少瓶汽水?这也是一道找规律题;我们还是画图进行分析:


e77552d45f634aca8f0c6c61c825c301.png


有了上面的逻辑分析,我们理清一下思路,就能写出代码了!

10f3dcab45954e80ad6fe50fe40489de.png



5.7  调整数组使奇数全部都位于偶数前面


比如:1 2 3 4 5 6 7 8 9 10打印出来的结果就是前面全是奇数,后面全是偶数;当然顺序不重要!思路:我们的思路就是左右两头开始;左边找偶数,右边找奇数,然后交换一下位置就可以


fa3f168f50754769ab4a3dd96a11eacd.png


两种特殊情况也要考虑到:

cac5feb5c8224360a0f935e114384065.png

具体代码:


d6c4864c34d24284baa92df5d7726d69.png9f8060cac79f4c5f8496aef697618a5a.png



5.8 发生截断的例题

221bae07c23d476297877bb728cbb5d3.png

9d6c5de1f3c94f9f9c87654c8c361ef2.png


这道题的结果是什么?初看感觉都是300;但是实际上却不是,我们还是先分析一下:


03f45585cfc34383886be4161cea5550.png


我们已经分析出来c的值是44,那么a+b的值为啥没有越界,发生截断呢?


原因是:a+b没有放到c里面,计算完结果会直接放到内存里,不会发生截断;


             而c=a+b,是把a+b的结果放到了char类型的c里,会发生截断,再放入内存


5.9 杨辉三角


1fff3a3e6c3045b6a6b8f81d629f2dc5.png

打印杨辉三角和打印菱形算是一类题目,我们不要上来就想着去打印,要先分析这个图形是怎么后构成的。比如杨辉三角:


1、无非就是第一列(j==0)和对角线(i==j) 全为1;


2、剩下的从第三行第二列开始(i=2,j=1)当前数是上一行两数的和;


分析清楚了,代码就很好写出来了


5878cf8c2a2f452b9e799a17a8088014.png



5.10 谁是killer(抽象问题转换成代码)

题目:判断谁是凶手,其中3个人说真话,一个人说假话:

A说:不是我

B说:是C

C说:是D

D说:C在胡说


我们就根据他们说的话作为判断条件;就假设他们每一个人说的话都正确:


如果A说真话,说明杀手不是A


如果B说真话,说明杀手是C


如果C说真话,说明杀手是D


如果D数真话,说明杀手不是D


最终我们在带入每个人说的话进行验证,看是否这个人说的话,与另外两个人说的也是对应的;换而言之,只与一个人的话起冲突;那么这个人说谁是小偷,谁就是小偷!


最终我们得到的是姓名是一个字符,所以定义为字符型

b17b51397d2045f39c9bb155a8a275ee.png



5.11 我是第几名(抽象问题转换成代码)

题目:5位运动员参加了10米台跳比赛,有人让他们预测比赛结果:每个人说的话只有一半真一半假

A选手说:B第二,我第三

B选手说:我第二,E第四

C选手说:我第一,D第二

D选手说:C最后,我第三

E选手说:我第四,A第一


最终我们得到的是名字是整型,所以定义为整型


我们不妨就嵌套5个for循环,根据他们说的话一半真一半假作为筛选条件;最后在根据其他限制条件再次筛选掉那些名词重复的:


f3c0e00f08cf4864a6ddee285985f2f4.png


最终得到我们想要的结果:

8bd716626a6e444e9ac2f4f814d5df36.png

总结:以上就是今天要学习的的内容,我们主要讲了字符指针、指针数组和数组指针的内容。这些也需要我们去重点掌握!指针的内容很多,也很重要,需要我们经常去练习才能掌握;下一篇我们将继续学习指针部分:函数指针、函数指针数组等精彩内容


结束语


今天的分享就到这里,想要提升编程思维的,快快去注册牛客网开始刷题吧!各种大厂面试真题在等你哦!


💬刷题神器,从基础到大厂面试题👉点击跳转刷题网站


184068dc41e94efbb14e555f972eaa17.png

相关文章
|
3月前
|
C语言
【c语言】指针就该这么学(1)
本文详细介绍了C语言中的指针概念及其基本操作。首先通过生活中的例子解释了指针的概念,即内存地址。接着,文章逐步讲解了指针变量的定义、取地址操作符`&`、解引用操作符`*`、指针变量的大小以及不同类型的指针变量的意义。此外,还介绍了`const`修饰符在指针中的应用,指针的运算(包括指针加减整数、指针相减和指针的大小比较),以及野指针的概念和如何规避野指针。最后,通过具体的代码示例帮助读者更好地理解和掌握指针的使用方法。
67 0
|
1月前
|
存储 NoSQL 编译器
【C语言】指针的神秘探险:从入门到精通的奇幻之旅 !
指针是一个变量,它存储另一个变量的内存地址。换句话说,指针“指向”存储在内存中的某个数据。
103 3
【C语言】指针的神秘探险:从入门到精通的奇幻之旅 !
|
1月前
|
存储 编译器 C语言
【C语言】指针大小知多少 ?一场探寻C语言深处的冒险 !
在C语言中,指针的大小(即指针变量占用的内存大小)是由计算机的体系结构(例如32位还是64位)和编译器决定的。
77 9
|
1月前
|
安全 程序员 C语言
【C语言】指针的爱恨纠葛:常量指针vs指向常量的指针
在C语言中,“常量指针”和“指向常量的指针”是两个重要的指针概念。它们在控制指针的行为和数据的可修改性方面发挥着关键作用。理解这两个概念有助于编写更安全、有效的代码。本文将深入探讨这两个概念,包括定义、语法、实际应用、复杂示例、最佳实践以及常见问题。
51 7
|
2月前
|
存储 C语言
C语言如何使用结构体和指针来操作动态分配的内存
在C语言中,通过定义结构体并使用指向该结构体的指针,可以对动态分配的内存进行操作。首先利用 `malloc` 或 `calloc` 分配内存,然后通过指针访问和修改结构体成员,最后用 `free` 释放内存,实现资源的有效管理。
215 13
|
2月前
|
存储 C语言 开发者
C 语言指针与内存管理
C语言中的指针与内存管理是编程的核心概念。指针用于存储变量的内存地址,实现数据的间接访问和操作;内存管理涉及动态分配(如malloc、free函数)和释放内存,确保程序高效运行并避免内存泄漏。掌握这两者对于编写高质量的C语言程序至关重要。
76 11
|
2月前
|
存储 程序员 编译器
C 语言数组与指针的深度剖析与应用
在C语言中,数组与指针是核心概念,二者既独立又紧密相连。数组是在连续内存中存储相同类型数据的结构,而指针则存储内存地址,二者结合可在数据处理、函数传参等方面发挥巨大作用。掌握它们的特性和关系,对于优化程序性能、灵活处理数据结构至关重要。
|
2月前
|
算法 C语言
C语言中的文件操作技巧,涵盖文件的打开与关闭、读取与写入、文件指针移动及注意事项
本文深入讲解了C语言中的文件操作技巧,涵盖文件的打开与关闭、读取与写入、文件指针移动及注意事项,通过实例演示了文件操作的基本流程,帮助读者掌握这一重要技能,提升程序开发能力。
179 3
|
2月前
|
存储 算法 程序员
C 语言指针详解 —— 内存操控的魔法棒
《C 语言指针详解》深入浅出地讲解了指针的概念、使用方法及其在内存操作中的重要作用,被誉为程序员手中的“内存操控魔法棒”。本书适合C语言初学者及希望深化理解指针机制的开发者阅读。
|
2月前
|
程序员 C语言
C语言中的指针既强大又具挑战性,它像一把钥匙,开启程序世界的隐秘之门
C语言中的指针既强大又具挑战性,它像一把钥匙,开启程序世界的隐秘之门。本文深入探讨了指针的基本概念、声明方式、动态内存分配、函数参数传递、指针运算及与数组和函数的关系,强调了正确使用指针的重要性,并鼓励读者通过实践掌握这一关键技能。
56 1