- 博客(791)
- 资源 (7)
- 收藏
- 关注
原创 C语言的内存分配:malloc和free
在ANSI C中,我们应该坚持使用强制类型转换,因为这样可以提高代码的可读性,否则,我们就不容易记住这个指针所指向的实际类型,这样的阅读性就大打折扣。malloc函数会找到合适的空闲内存块,这样的内存是匿名的,即malloc分配了内存后,不会为其赋名,返回动态分配内存块的首字节地址,我们可以将这个地址赋给一个指针变量,使用这个指针访问这块内存。和malloc函数一样, 在ANSI C之前,calloc函数也返回指向char的指针,在ANSI C之后,返回指向void的指针。静态内存的数量在编译时固定的。
2025-02-22 18:53:09
301
原创 C语言中的作用域、链接、存储期
外部链接的静态变量具有文件作用域、外部链接和静态存储期,这样的变量有时被称为外部存储类别,属于该类别的变量称为外部变量,定义时,只需要将变量放在所有函数的外面即可。属于自动存储类别的变量都具有自动存储期,块作用域且无连接,声明在块中或函数头的任何变量都属于自动存储类别。寄存器变量是存储在CPU中的,因其存储在CPU中,所以无法获取寄存器变量的地址。auto是存储类型说明符,这个说明在C和C++的用法是相同的,如果写的程序包含C和C++代码,则要避免使用这个说明符。具有文件作用域的变量自动具有静态存储期。
2025-02-19 22:34:33
692
原创 C语言的递归与尾递归
递归的优点为某些编程问题提供了很简单的解决方案,缺点是一些递归算法会快速消耗计算机的内存资源。有时递归算法不是很好阅读和维护。尾递归是最简单的递归形式,它的特点就是将递归调用放在函数的末尾,即正好在return语句之前。C语言允许函数调用自己,这种调用过程就叫递归。
2025-02-16 20:32:56
163
原创 C语言中的文件概念
另一种方式是存储文件的大小的信息,Unix使用这种方法处理所有的文件。操作系统的差异导致它有不同的底层I/O实现,这里的差异是多方面的,如系统存储文件的方式的不同,在有的系统上把文件的内容储存在一处,而文件的相关信息存储在另一处;在处理文件方面,不同的系统也可能表现出差异,如有的系统使用单个换行符标记行末尾,有的系统可能使用回车符和换行符的组合来表示行末尾。这样,不同的操作系统可以有不同的底层I/O实现,用户通过使用C标准的文件处理模型和标准I/O函数,就可以获得统一的使用界面。
2025-02-16 12:49:22
324
原创 C语言中的对象、左值、右值、序列点、副作用的概念
序列点是程序的执行点,在C语言中,语句中的分号标记一个序列点,在该点上,所有副作用都在进入下一步之前发生,即在一个语句中的赋值运算、递增运算、递减运算对运算对象的修改必须在程序执行下一条语句之前完成。sizeof以字节为单位返回对象的大小,它的返回类型是size_t这是一个无符号整型数,用size_t时,编译器会根据不同系统来替换具体的整型类型。因此,对象指的是实际的数据存储,而左值是用于标识或定位存储位置的标签。副作用也是一个C语言的术语,它是指对数据对象或文件的修改。num是可修改左值,5是右值。
2025-02-15 23:32:59
340
原创 C语言函数的实参与形参与缓冲区的概念
在C语言中,实际参数是传递给函数的特定值。形式参数是函数中用于储存值的变量。缓冲区刷新是指把缓冲区中的数据送到屏幕或文件的行为。
2025-02-15 23:15:53
115
原创 C语言中的常量与只读变量,#define与const的区别
代码在编译时就需要确定好数组的长度,所以只能用#define定义的宏常量,const的作用是限制变量为只读,它的值只有在运行时才能够确定,因此用const的变量来指定数组长度会报错。这条定义宏的语句,是不是很熟悉,这条预处理指令会在编译器编译前把源文件中使用到这个宏的地方都先展开。表明C处理器需要在编译器接手工作之前先处理这条指令。因为它们的值都不能够改变,都是它们的意义却是不同的。
2025-02-15 23:08:28
358
原创 C语言编译机制
o目标文件只包含编译源文件后的机器语言代码,不包含标准库函数的代码(库文件中有许多函数的目标代码),它不能直接运行,因为它缺失启动代码,启动代码充当程序与操作系统之间的接口。C的精神告诉你,它相信你(程序员)能够控制好,能够组织好,它不会在语言层面设置障碍去阻止你做任何事,它时刻保持语言的精练、简单,高效。编译器把源文件(扩展名为.c的文件)编译出中间代码(中间代码有很多种形式,如.s编译代码、.o目标代码),链接器再将其与其他代码连接在一起生成可执行文件。所以你负有责任去管理你的程序过程。
2025-02-15 17:37:22
217
原创 计算机中数据的表示
对于计算机中的二进制的解析完全取决于具体的机器指令,也就是说对于最高位是不是符号位,要不要取负权重等问题,要依赖于具体的机器指令,和二进数本身关系不大,如对于内存中的二进制数1111 1011,有的指令读取后,会将其视为有符号数,而有的指令读取后则会将其视为无符号数。+0, -0在系统中的表示法是一样的,而原码和反码都做不到。原码没有办法表示+0和-0,它只能表示+0,反码就更加不行了,最反后就是另一个值了。根据前求负数的补码的过程,我们可知结果的最高位总是1,这就是我们常说的符号位。
2025-02-08 10:20:44
989
原创 汇编指令和机器码的区别
(本例子是在apple m1架构平台上进行的,编译出来的汇编代码和机器码与在x86架构下编译出来的会有所不同。不同架构的平台的对应的汇编代码与机器码也是不相同的)(本例子是在apple m1架构平台上进行的,编译出来的汇编代码和机器码与在x86架构下编译出来的会有所不同。不同架构的平台的对应的汇编代码与机器码也是不相同的)如汇编的ret指令对应的机器指令在我运行的平台上就是d65f03c0.编译出对应的汇编源文件*.s。将可执行文件反编译出来。
2025-02-08 09:00:51
276
原创 电路基本原理
当其中一个输入为高电平,另一个输入为低电平时,上面输出1,下面的输出就是0,结果就是二进制的01.当输入都为高电平,即1时,上面的输出就是0,下面的输出就是1,结果就是二进制的10.输入都是高电平,才会输出高电平,否则没有输出。只要其中一个输入是高电平,就会输出高电平。输入高电平,则输出低电平。输入低电平,则输出高电平。输出电平与输入电平相反。
2025-02-07 23:14:18
299
原创 CPU的基本结构
部件之间的通信是由各种各样的总线来完成。以内存为例,地址总线传输要访问的内存地址,数据总线传输读写的数据。在实际中,有的总线地址和数据是分离的,有的是同一根分时复用。北桥芯片也集成了内存控制器,用来控制与内存的通信。目前,最新的主板上,就没有北桥芯片了,因为北桥的功能已经被集成到CPU中去了。FSB总线:前端总线(Front Side Bus)是CPU和北桥传递的所有数据用的,FSB总线的频率直接影响到CPU访问内存的速度。PCI总线:这是一种高性能局部总线,CPU和外设之间的高速通道。
2025-02-07 22:58:19
343
原创 Vim跳转文件及文件行结束符EOL
在Windows上,行尾就不只使用 LF 这一个字符了,在 LF 前面会多一个 CR,编码值为 13(U+000D)。文本文件里存放的是用行结束符(EOL,即 End of Line)隔开的文本行,二进制文件里则没有这样的明确分隔符。使用 Vim 编辑的文本文件,最后一个字符通常是 LF(除非使用 Mac 行尾风格,则结尾是 CR)。在 Unix 或类Unix上,这个 EOL 在存盘时使用的字符是 LF,编码值是 10(U+000A)。可以在分割的窗口打开跳转的文件,不过在我的实验不是次次都成功。
2025-02-06 14:14:53
508
原创 Vim 多窗口编辑及文件对比
在光标所在的窗口,输入分割窗口命令就会对那个窗口进行分割。设置窗口高度,默认为纵向占满,利于专心编辑某个文件。只保留当前窗口,关闭其他所有窗口。只保留当前窗口,关闭其他所有窗口。默认使用水平分割的方式。把当前窗口横向一分为二。把当前窗口纵向一分为二。
2025-02-05 19:01:26
546
原创 Vim的基础命令
将光标所在行开始的【数字】行,直接删除掉,直接输入新的内容进行内容替换,其余没有删除掉的不受影响,如果没有带【数字】,就是一行。将光标所在处开始的【数字】个字符,直接删除,直接输入内容进行替换,其余没有删除掉的不受影响,如果没有带【数字】,就是一个字符。删除光标所在行开始的【数字】行,不带数字就是一行,并开始输入新内容。删除光标所在行开始的【数字】行,不带数字就是一行,并开始输入新内容。光标所在行开始【数字】行字符,不加数字,就是当前行。光标所在行开始【数字】行字符,不加数字,就是当前行。
2025-02-04 21:17:21
1096
原创 C 标准库提供的进程控制
上面程序调用函数 atexit 为程序注册了一个回调函数,注册回调函数成功后,atexit函数会返回0。这个函数会在程序显式调用 exit 函数时,或从 main 函数内正常退出时被触发。在对应的回调函数 exitHandler 中,调用用 getenv 函数,获取并打印了当前宿主机上环境变量 PATH 的值。
2025-02-03 10:56:05
247
原创 C语言中的信号量
硬件中断直接由硬件触发,如磁盘完成了某次由用户程序指定的 IO 操作后,就会通过硬件中断的方式来通知 CPU 这一消息,并让 CPU 进行后续的处理。此时,如果应用程序并未设置自定义的信号处理程序,则操作系统将会执行默认信号处理程序中的逻辑,一般是直接终止当前程序的运行。在信号处理的过程中, CPU 从用户程序到信号处理程序的执行流程转移。当上述程序访问了非法内存,操作系统便会将信号 SIGSEGV 发送给当前进程,并之前通过 signal 函数注册的信号处理信息,调用用户自定义或默认的信号处理函数。
2025-02-03 09:54:30
365
原创 C语言中的线程本地变量
因此线程在对 counter 变量进行累加时,便不会受到其他线程的影响。线程本地变量还有一个用途:用来存储线程独有的一些信息,如错误信息。这处线程本地变量可不是简单的函数中的本地变量。线程除了可以共享存在于进程内的全局变量外,还可以有属于自己的线程本地变量。线程本地变量的值只能够在某个具体线程的生存期内可用。除了以关键字来定义线程本地变量的方式之外,标准库还提供了一系列的函数来实现同样的目的。这样,当线程退出时,便可以确保相应的线程本地资源(比如堆内存)能够以正确的方式被清理。
2025-02-02 23:11:58
348
原创 在C语言中使用条件变量实现线程同步
在多线程应用中,当某个线程的执行依赖于另一个线程对数据的处理时,这个线程可能没有被阻塞,只是不断地检查某个条件是否成立了(这个条件就是另一个线程对数据处理的结果的指示器),这是一种“忙等待”的方式实现线程间的同步。这样一来,某个线程可以在完成了某件事情后,通知并唤醒等待线程,让其继续工作,完成接下来的任务。在上述程序中,在 main 线程中,调用了与条件变量相关的函数 cnd_wait。在我们的例子中,只有 main 函数对应的一个线程,所以此时,互斥量将被重新上锁,main 线程将继续执行接下来的指令。
2025-02-02 22:13:02
399
原创 实现C语言的原子操作
我们一般都是在多线程环境中,才会需要原子操作的支持。因为当多个线程中对共享资源进行原子操作时,编译器和 CPU 将能够保证这些操作的正确执行。当该线程将整个原子操作全部执行完毕后,其他线程才可以继续执行同样的操作。与使用互斥量相比,原子操作可以更加清晰和方便地抽象并行代码,而不需要频繁进行加锁与释放锁的操作。从性能角度来看,原子操作的执行通常直接依赖于 CPU 提供的相应的原子机器指令。而使用互斥量则需要让线程阻塞,还要频繁进行上下文切换,比较之下,原子操作的性能一般会更好。
2025-02-02 20:50:52
510
原创 在C语言多线程环境中使用互斥量
互斥量就像是一把锁,在一个线程在访问某个共享资源前,需要对互斥量进行加锁操作,其他线程想要对互斥量加锁就会被阻塞,直到当前线程释放该锁。当锁被释放后,被阻塞的线程都开始继续执行,并再次重复前面的步骤,开始争夺可以对互斥量进行加锁的操作。如果有十个银行账号通过不同的十条线程同时向同一个账号转账时,如果没有很好的机制保证十个账号依次存入,那么这些转账可能出问题。我们可以通过互斥量来解决。互斥量这种方式,可以保证每次只有一个线程在操作共享资源。C标准库提供了这个互斥量,只需要引入threads.头文件。
2025-02-02 13:20:32
182
原创 机器学习中的欠拟合
有时,我们为了避免过度训练模型导致过度拟合,会提前停止模型训练,但是这个提前有时太早了,反而在这个情况下导致了欠拟合的问题。这里也引出另一种情况也会导致欠拟合,那就是训练不足,解决之道就是增加训练时间,这个又要考虑如何避免训练时间太长造成过度拟合的问题。特征太少的话,在现实世界中,可能会对应很多可能的输出,这样的模型就像在胡说八道,实际上,是我们自己想得太简单了,增加相关的特征输入,就可以收窄这扇——更容易定位到我们期望的结果上。欠拟合和过度拟合一样,不能够在数据中建立主导趋势,导致模型训练错误、性能低。
2024-12-31 11:53:55
374
原创 什么是过度拟合和欠拟合?
不过要注意,想法虽好,但是如果停止太早导致模型训练不足,造成欠拟合,停止太晚,导致模型学习了太多噪音数据,造成过度拟合,所以这种方法,我们就要在欠拟合和过度拟合之间做出权衡,以期在找到一个处于两者之间的最佳的权衡点,这个点就是使用这种方式解决拟合问题要找的。特征选择:在构建一个模型时,会有很多特征供我们选择,用来预测特定的结果,很多时候这些特征有很多都是彼此重复的,识别并选择出最重要的那么特征,排除无关的,冗余的特征是很重要的。过度拟合的模型对新的(没有见过的)数据的分类或预测的准确性是很差的。
2024-12-30 21:51:50
1035
原创 机器学习、深度学习、神经网络之间的关系
如果一个神经元的输出高于指定的阈值,那么这个神经元就会被激活,并将数据发送到网络的下一层,否则这个神经元就不会发送任何数据到网络的下一层。深度学习的深度指的就是一个神经网络的层数。深度机器学习可以用被标记了的数据集通知它的算法,也可以用未标记的数据集通知它的算法。深度学习可以自动决定特征集, 这一点排除了必要的人为干预,使其能够应用到更加庞大数据量的数据集上,从这一点上来说,深度学习就是大规模的机器学习。它们都是是人工智能的子领域。更确切地说,神经网络是机器学习的子领域,深度学习是神经网络的子领域。
2024-12-28 21:58:29
576
原创 什么是机器学习
模型优化过程也是必须的,在这个模型能够拿来用之前,必须完成这个过程,这个过程利用训练数据集中的数据点,通过不断读取数据点,评估预测值与实际值的差距,不断调整权重,将函数的输入和输出值,尽可能符合训练集中的映射关系,这就是所谓的拟合。要一个模型百分百预测正确,其实是很困难的,随着训练数据集越大,拟合过程就越久,因为要不断的评估与优化,每一次权重的调整都可能会影响前面的数据点。旨在使机器或计算机像人一样学习,通过让其接触更多的数据,以期其能够自动执行任务,提高其性能和准确性。
2024-12-28 11:42:53
376
原创 bash脚本管道piping
选用ls命令列表出文件名列表,然后把文件名列表传给sort命令做排序,排序结果再传输给后面的head命令,取出前3个文件名。管道用|表示,用于将前面的结果传输到后面的命令去处理,如。
2024-12-27 20:52:33
290
原创 bash脚本函数
调用的方式:函数名,不用加括号。,函数中对参数的引用也是通过$1~${255}实现。函数的局部变量,需要用关键字local修饰。
2024-12-27 19:54:42
196
原创 bash shell的条件语句
中括号包住的条件与括号之间必须要有空格。if关键字与中括号之间也必须要有空格。为什么会这样, 因为命令与参数之间必须要用空格分开。所以如果没有空格了,解析器就会找到一个错误或不存在的命令,因为它会把在每一行遇到的第一个空格前面有字符串的字符串当作是命令,之后的当作是参数。所以如果if和[]没有空格,执行脚本时就会报错,把。为什么不可以用<,>等来表达上面这些关系,因为这些符号在类Unix系统中有特殊用途。温馨提示:赋值语句的等号左右不能有空格,否则会报错。
2024-12-27 12:47:34
428
原创 在脚本中执行基本脚本命令或系统命令
值得注意的是,单引号会使方式一失效,双引号则可以使方式一生效。- 方式一 :$(命令), 命令可以是系统或自定义的脚本。- 方式二:`命令`,命令可以是系统或自定义的脚本。
2024-12-27 11:35:53
120
Android-ttf.zip
2020-07-02
java-json.jar.zip
2020-06-27
sqlitestudio-3.2.1.tar.xz
2020-04-17
mongodb-org-server_4.2.5_amd64.deb
2020-03-28
jdk1.6-bin.zip
2019-10-23
空空如也
TA创建的收藏夹 TA关注的收藏夹
TA关注的人