- 博客(34)
- 收藏
- 关注
原创 引用 | c++
引用不是新定义一个变量,而是给已存在变量取了一个别名,编译器不会为引用变量开辟内存空间,它和它引用的变量。注意:引用类型必须和引用实体是同种类型的(涉及中类型转换的知识)
2025-11-30 18:39:05
676
原创 const成员函数
本文探讨了C++中const成员函数的相关问题。const成员函数通过修饰this指针来限制对类成员的修改,防止权限扩大问题。当非const对象调用const成员函数时属于权限缩小,是允许的。文章指出,const在*左右位置作用不同:左侧限制指向内容,右侧限制指针本身。在成员函数定义时应遵循原则:能定义为const的尽量定义为const,这样const和非const对象都能调用;需要修改成员变量的函数则不能定义为const。同时,重载运算符时非const函数会优先匹配非const对象调用,不会产生歧义。
2025-11-30 17:58:12
270
原创 计算二叉树的深度 | C语言
摘要:计算二叉树深度时,应以左右子树中较深的子树高度加1为准,而非两子树高度之和。避免直接递归调用左右子树造成的重复计算,可采用记忆化优化或使用fmax函数比较子树高度。核心公式为:树深度 = max(左子树深度, 右子树深度) + 1。
2025-11-16 22:01:50
271
原创 设计循环队列 | C语言实现
本文实现了一个循环队列的数据结构。通过数组存储元素,使用front和rear指针分别标记队首和队尾,并额外开辟一个空间来区分队列满和空的情况。关键操作包括:创建队列时分配k+1空间;通过模运算处理指针循环移动;判断空队列(front==rear)和满队列((rear+1)%(k+1)==front);实现入队、出队、获取队首队尾元素等功能,均处理了边界情况。该方法保证了O(1)时间复杂度的基本操作,空间利用率高。
2025-11-12 22:55:09
452
原创 用两个队列实现栈 | C语言实现
以下是LeetCode原题:https://leetcode.cn/problems/implement-stack-using-queues/https://leetcode.cn/problems/implement-stack-using-queues/把有元素的那个队列除最后一个元素全部入队没有元素的队列,然后把剩下的那一个元素出队。将新元素尾插到有元素的那个队。下面是具体的实现代码
2025-11-07 23:35:32
273
原创 有效的括号详解 | C语言用动态数组实现栈解决
该题解通过栈数据结构验证括号字符串的有效性,满足顺序闭合、类型匹配和数量正确三个条件。使用动态数组实现栈结构,包括初始化、压栈、出栈等操作。解题时遍历字符串:左括号入栈,右括号则与栈顶元素匹配,若不匹配或栈空则返回false。最后检查栈是否为空确保括号数量匹配。提供了两种条件判断写法:直接比较和使用临时变量存储栈顶值。算法时间复杂度O(n),空间复杂度O(n)。
2025-11-06 23:37:10
411
原创 C语言解决轮转数组
本文介绍了轮转数组问题的三种解法:1.暴力法通过多次交换元素实现右旋,时间复杂度O(N²),空间O(1);2.额外数组法利用新数组存储并重新组合元素,时间O(N),空间O(N);3.最优的逆序法通过三次局部和全局逆序操作实现,时间O(N),空间O(1)。其中逆序法通过巧妙的分段翻转达到最优解。
2025-10-24 21:40:10
137
原创 C语言程序的环境和预处理
define 机制包括了一个规定,允许把参数替换到文本中,这种实现通常称为宏(macro)或定义宏(define macro)。定义宏时需要注意以下规则:其中的parament-list 是一个由逗号隔开的符号表,它们可能出现在stuff中。参数列表的左括号必须与name紧邻。如果两者之间有任何空白存在,参数列表就会被解释为stuff的一部分。#defined定义的宏需要注意,宏参数的替换是整个直接替换,如果传递的是表达式则需注意优先级的变化,所以宏在定义时的参数最好全部带括号。
2025-10-22 13:17:08
360
原创 用一个宏交换一个数二进制的奇偶位
所以在32bit位下,就是n&0xaaaaaaaa) >> 1和n&0x55555555) << 1,两者相加就是奇数和偶数互换后的a。实际上保留奇数位就是a与01010101按位与,01010101即是0x55,然后按位右移一位。同样的保留偶数位就是a与10101010按位与,10101010即是0xaa,然后按位左移一位。可以分别让奇数或偶数位的每一位与按位与1,这样可以保留对应的二进制位。如奇数位(从右往左数)是 0001,按位与1 是 0001,没有改变。
2025-10-22 00:30:13
180
原创 模拟实现atoi
这是一个C语言实现的字符串转整数函数MyAtoi。主要功能包括: 处理空指针和空字符串 跳过前导空白字符 识别正负号 转换数字字符并处理溢出 使用全局状态标记转换有效性 遇到非数字字符立即返回当前结果 函数模拟标准库atoi的行为,但增加了错误检查机制,能正确处理边界情况和非法输入。主函数通过fgets获取输入并调用该转换函数,根据状态输出结果或错误信息。
2025-10-21 23:25:45
84
原创 找出单身狗 | 使用异或找出一组数字都是成对出现的数组中的两个单独数字
摘要:本文介绍了一种使用异或运算找出数组中两个不成对数字的方法。首先将所有数字异或得到两个目标数字的异或值,然后通过找到该值中为1的二进制位来区分这两个数字。接着根据该位的值将数组分成两组分别异或,最终得到两个单独的数字。文中提供了完整的C语言实现代码,示例输出正确识别了数组中的5和6两个不成对数字。
2025-10-21 22:00:08
194
原创 C语言中Struct结构体的位段是什么?怎么使用?
位段的声明和结构是类似的,有两个不同:1. 位段的成员必须是int、unsigned int 或signed int。2. 位段的成员名后边有一个冒号和一个数字。位段后的数字是其占用的Bit位,总计47个bit位,1个字节32个比特位,所以需要开辟两个字节的空间。这是因为有些成员仅需要非常少的空间,这时候就可以使用位段节省空间。
2025-10-21 19:45:52
529
原创 C语言结构体的特殊情况(结构体自引用和匿名结构体)
1.结构体的自引用c语言引入结构体来描述复杂对象。结构是一些值的集合,这些值称为成员变量,结构的每个成员可以是不同类型的变量。数组: 一组相同类型的元素的集合结构体:是一组不一定相同元素的集合结构成员的类型:结构的成员可以是标量(变量)、数组、指针,甚至是其他结构体(嵌套结构体)。1.结构体的自引用结构体的成员甚至可以是自己,这种情况称为结构体自引用,但这存在问题。
2025-10-21 18:57:53
322
原创 用C语言复制一份文件
这段C语言代码实现了文件复制功能:首先以读取模式打开源文件data01.txt,然后以写入模式创建/打开目标文件data02.txt。通过while循环逐个字符读取源文件内容并写入目标文件,直到遇到文件结束符(EOF)为止。程序包含完善的错误处理机制,在文件操作完成后会正确关闭文件指针并置空。最终在源目录下生成与data01.txt内容完全相同的data02.txt文件。
2025-10-18 21:16:39
147
原创 C语言结构体的对齐
结构体对齐是为了提高内存访问效率,通过牺牲空间换取时间。计算机以固定字长(如32位机4字节)读取数据,未对齐的成员需要多次访问。对齐规则包括:首成员偏移0,其他成员按对齐数(成员大小与编译器默认值的较小值)的整数倍存放,总大小为最大对齐数的整数倍。通过offsetof宏可查看成员偏移量。示例显示不同成员排列会导致不同结构体大小(S1占12字节,S2占8字节),建议将小成员集中存放以减少空间浪费。这种机制虽增加内存占用,但显著提升了数据读取性能。
2025-09-04 23:14:34
193
原创 void*类型的指针如何使用?
如果用来接收int*类型的指针,只需要对(char*)str循环操作4次即可达到int*类型的效果,所以强制类型转换成(char*)是最有通用性的。有时候为了通用性,会将自定义函数的指针类型设置为void*以接收各种类型的指针。那么这种指针如何使用呢?如果想对这类指针解引用,需要先使用强制类型转换转换成需要类型的指针。那么void*类型的指针可以使用++或--操作符吗?
2025-09-02 23:20:30
128
原创 在编译器中&a是什么类型,为什么有时候取地址,编译器无法识别?
如果直接&(c+1)编译器是无法识别的,因为数组名实际上是一个指向首元素的指针,c自己的地址和首元素的地址是不同的,且编译器只开辟了一个char**的空间存放c。c+1实际上可以解释为两个操作,一是c自己的地址加1,二是c指向的位置+1。&(c+1)执行的就是第一种操作,&(c+1),取的是c+1自己的地址,但编译器没有给c+1自己的地址开辟空间,是越界访问,所以编译器报错。正确的做法是先解引用再取地址,&*(c+1)。在编译器中,对一个变量取地址,如&a,则&a在编译器中实际上是一个指向a的指针。
2025-09-02 01:35:47
141
原创 为什么一个二级指针可以维护一个存放二级指针的指针数组?
同理,存放一级指针的指针数组也可以直接用二级指针维护,即便指针数组的数组名相当于一个二级指针;存放二级指针的指针数组也可以直接用三级指针维护,即便这里的指针数组的数组名相当于一个三级指针。数组也是同理,因为数组名自己就是指向其首元素的地址,所以可以直接用一级指针维护。同样的,二维数组可以直接用二级指针维护。但如果不要求对pt的自己的地址进行维护,仅要求对pt指向的地址进行维护,则也可以用一级指针指向pt指向的地址。
2025-09-02 00:52:35
156
原创 C语言数组名在不同场景下的意义(指针数组练习题)
a是一个指针数组,里面存着3个指针,每个指针都是一个字符串的首元素。数组名a的值是首元素的地址,类型是int*[]。int*[]类型是一个数组,这个数组的类型是int*,所以可以使用二级指针pa维护。pa++,pa指向指针数组的第二个字符串,对pa解引用,相当于a[1],所以结果是打印at。
2025-09-02 00:33:18
897
原创 C语言中的数组名是什么?不同场景下它的步长是多少?
本文探讨了C语言中数组和指针的核心区别,重点分析了数组的值属性与类型属性。数组名具有双重属性:值属性是首元素地址(指针),类型属性则反映数组整体结构(如int[4])。通过sizeof运算验证了数组与指针在内存占用上的差异,数组占用的空间是各元素总和,而指针固定为4/8字节。文章详细解析了指针运算中的"步长"概念,指出步长由指向数据类型决定,并通过一维、二维数组案例展示了不同表达式(arr、&arr等)的步长差异。最后以二维数组为例,说明多维数组名的类型属性和地址运算规则,强调了
2025-08-30 22:37:45
760
原创 C语言 数组名在不同场景下的意义(二维数组)
a+1得到这个数组最后一个元素地址,类型是int[3][4],即得到这个数组最后一个元素地址的后一个的地址所存储的值,该值的类型是int[4],所以大小是16Byte。&a[0]取出第一行整个数组的地址,+1得到第二行的地址,类型是int(*)[4],对第二行的地址解引用,得到的类型是int[4],代表第一行整个数组,大小是16字节。a[0]这里表示第二行首元素的地址,a[0]+1,步长是一行的数组,+1即表示第二行数组的地址,是一个地址,类型是int*,大小是4或者8字节。
2025-08-30 17:18:41
418
原创 C语言 数组名在不同场景下的意义(字符串)
以下是输出结果: 因为是直接访问arr,所以这里arr代表整个数组,类型是char[7],所以大小是7Byte。arr先进行一次算数运算,arr代表首元素地址,+0后仍是首元素地址,类型是char*,是指针,大小是4或8Byte。这里arr是首元素的地址,*arr是首元素,类型是char,大小1Byte。arr[1],即是字符串的第二个元素,类型是char,所以大小是1Byte。&arr,是取出这个字符串的地址,类型是char(*)[7],&arr是一个数组指针,仍是一个指针,大小是4或8字节。&arr+
2025-08-30 14:40:34
364
原创 C语言 数组名在不同场景下的意义(一维数组和字符数组)
数组名在两种情况下代表整个数组,分别是sizeof(数组名)和&数组名时。以下是上述程序的输出结果:接下来我们来逐一解析。
2025-08-29 22:35:42
786
原创 C语言函数指针数组和回调函数的妙用
想要了解函数指针数组和回调函数的作用,需要先写一个不含两者的程序,以一个简单的计算器程序为例(包含加法、减法、乘法和除法四种运算)。
2025-08-24 22:46:45
194
原创 C语言指针数组和数组指针及其传参详解
整型指针:指向整型变量的指针,存放整型变量地址的指针变量。字符指针:指向字符变量的指针,存放字符变量地址的指针变量。数组指针:指向数组的指针,存放数组的地址的指针变量。int(*p)[10]可以用以下方法理解:*p说明p是指针,int [10]是数组的类型,所以p指向的是一个大小为10的数组,int(*p)[10]是数组指针变量。注意:[]的优先级是高于*的所以要用()保证*先和p和结合。
2025-08-24 00:00:42
440
原创 C语言中数据的存储(整型,字符型和浮点型)
摘要:文章详细讲解了C语言中整型和浮点型数据的存储方式。整型部分重点分析了char和unsigned char的存储原理,包括原码、反码、补码转换规则及取值范围(char为-128~127,unsigned char为0~255)。浮点型部分依据IEEE754标准,介绍了32位和64位浮点数的存储格式,包括符号位S、有效数字M和指数E的存储规则,特别说明了E的中间数处理机制(32位加127,64位加1023)以及不同情况下E的取值规则。文章通过具体示例演示了不同类型数据的存储转换过程。
2025-08-19 23:53:43
1036
原创 C语言如何一次性输入带空格的字符串?gets,fgets和scanf(“%[^\n]s“, str)三种方式
本文介绍了在VS2022中使用三种方法输入带空格的字符串:1) gets函数直接读取至换行符,但VS会警告;2) fgets函数更安全,可限制读取字符数;3) scanf配合正则表达式[^\n]实现相同功能。三种方法均能正确处理含空格的输入,其中fgets是推荐替代gets的方案。文章提供了每种方法的代码示例、输出结果及官方文档链接。
2025-08-19 19:49:31
1183
原创 C语言中的原码、反码和补码及数据的大小端存储模式
计算机中的整数有三种2进制表示方法,即原码、反码和补码。三种表示方法均有符号位和数值位两部分。正数的符号位用0表示,负数的符号位用1表示。如果直接将整数1换算成二进制位就是整数1的原码。00000000000000000000000000000001 --- 这就是1的原码。C语言中的整型是4Byte大小,所以有32个bit位,即32个二进制位。其中第一位就是符号位,其余的31位是数值位。将1的原码除符号位外全部按位取反可以得到1的反码。
2025-08-17 21:52:53
841
原创 VS中如何用键盘输入EOF?可以使用Ctrl+D或Ctrl+Z
摘要:本文介绍了C语言中EOF(文件结束符)的两种键盘模拟方式:Ctrl+D和Ctrl+Z。通过测试程序发现,在VS2022环境下需要输入两次Ctrl+Z加回车才能成功模拟EOF。文章特别指出,输入Ctrl+Z前需先按回车键,否则会被识别为普通字符存入数组。程序示例展示了如何用scanf循环接收字符直到EOF,并演示了正确的输入方法。
2023-07-18 23:26:29
2531
1
空空如也
空空如也
TA创建的收藏夹 TA关注的收藏夹
TA关注的人
RSS订阅