
C温故补缺
文章平均质量分 62
C温故补缺
chocolate7777777
这个作者很懒,什么都没留下…
展开
-
C温故补缺(十八):网络编程
在网络层中,IP协议传输的消息类型是IP数据报,它是无连接的,且不可靠的。在发送数据时,TCP协议会按照顺序将数据分成多个数据包进行传输,每个数据包都带有一个序列号,接收方会根据序列号来确定数据包的顺序,并向发送方发送确认号,表示已经接收到了序列号对应的数据包。参数epfd是epoll实例的文件描述符,参数events是一个epoll_event结构体数组,用于存储事件,参数maxevents指定了最多可以返回的事件个数,参数timeout指定了超时时间,如果为-1,则表示一直阻塞,直到有事件发生。转载 2023-06-06 17:47:45 · 113 阅读 · 0 评论 -
C温故补缺(十七):动态链接(ELF,PIC,GOT,PLT)
在数据段中,编译器创建为了GOT表,GOT表包括多个表项,每个表项里存储一个地址,GOT[0]~GOT[3]是内置的表项,从GOT[4]开始,每个函数一个表项,例如GOT[4]是第一个函数引用的表项,GOT[5]为第二个函数引用的表项,编译器生成可执行文件时,GOT[4]中存储的地址总是指向了PLT[2]表项的第二条指令,GOT[5]中存储的地址总是指向了PLT[3]表项的第二条指令,因此类推。0x4005c0为PLT[2]表项的地址,这个地址是个相对地址,与内存无关的,生成可执行文件时,就已经确定了。转载 2023-06-06 17:43:25 · 191 阅读 · 0 评论 -
C温故补缺(十六):未定义行为
在计算机程序设计中,未定义行为是指执行某种计算机代码所产生的结果,这种代码在当前程序状态下的行为在其所使用的语言标准中没有规定.以C语言为例,未定义行为指C语言标准未作规定的行为,同时,标准也未要求编译器判断未定义行为,所有的未定义行为由编译器自行处理.所以,未定义行为在不同的编译器中可能会产生不同的结果,有可能编译成功,得到了结果,但在其他系统甚至另外一个日期都有可能失败.在编程过程中尽量避免未定义行为.如:++i++z,x=f()+g(),int *p;*p=3;等。转载 2023-06-06 17:40:37 · 202 阅读 · 0 评论 -
C温故补缺(十五):栈帧
栈帧:也叫过程活动记录,是编译器用来实现过程/函数调用的一种数据结构,每次函数的调用,都会在调用栈(call stack)上维护一个独立的栈帧(stack frame)再来看ret,ret是将之前存的RIP给出栈,经过sub分配空间然后再add释放空间,pop rbp后,rsp刚好在旧的rip处。当发生函数调用时,也就是call时,callq 指令会自动将rip压入栈,并将rip指向被调用的函数,如。将当前栈帧切换到新栈帧(将esp值装入ebp,跟新栈底),此时ebp指向栈顶,转载 2023-06-06 17:39:45 · 151 阅读 · 0 评论 -
C温故补缺(十四):内存管理
这样是错误的,会报异常:assignment to 'int' from 'int *' makes integer from pointer without a cast,即从“int *”赋值到“int”会使指针中的整数没有强制转换,因为a是一个int型指针,*a得到的应该是一个int型,&x则是一个int *,这个操作相当于把一个int *赋值给一个int。如果给指针赋值&a,并不会自动对齐后续的空间,p++得到的是&a++,实际上,p++后指针指向本身。如果不赋值的化,就会被编译器优化掉。转载 2023-06-06 17:36:15 · 124 阅读 · 0 评论 -
C温故补缺(十三):可变参数
va_arg()有两个参数,第一个是va_list变量,第二个是取出来的参数的类型。va_arg()有类似指针的操作,每次读取一个参数,然后下移读下一个。头文件提供了实现可变参数功能的函数和宏。va_start(vl,num)接收num个参数。转载 2023-06-06 16:58:24 · 82 阅读 · 0 评论 -
C温故补缺(十二):预编译器与头文件
defined用于判断宏是否定义,并返回真/假,一般和if连用,但ifdef和ifndef也能实现这样的效果。如果不小心引用了两次头文件,编译器就会处理两次,预编译文件中就会有两边头文件代码,可能会导致异常。建议把所有的常量、宏、系统全局变量和函数原型写在头文件中,在需要的时候随时引用这些头文件。error用来提示预编译的错误,当程序执行的#error时,输出信息,停止编译后续代码。预编译器就是之前学的预编译指令的执行者。这些预编译的宏都是可以直接输出的。括起来的表示系统环境中的头文件。转载 2023-06-06 16:38:56 · 158 阅读 · 0 评论 -
C温故补缺(十一):文件读写
二进制存储,直接存二进制位的信息,是直接把本质存储了.可以保证数据完整,无误差,像float型的如1/3,不论保留多少位小数都是有误差的,而用二进制存储可以避免.同时二进制存储,也可以存像数组,结构体或其他自己定义的数据结构。如果这个函数在读取最后一个字符之前就遇到一个换行符 '\n' 或文件的末尾 EOF,则只会返回读取到的字符,包括换行符。表达式表示,第三个参数count是要读写的元素的个数,最后一个参数是FILE对象地址。也是把字符串写入fp指向的输出流,但是可以格式化参数,输出变量或表达式的值。转载 2023-06-06 16:13:41 · 70 阅读 · 0 评论 -
C温故补缺(十):输入输出
格式:int getchar(void), 能够从标准输入中读字符,一次只能读取一个字符,返回这个字符的ASCII。格式int putchar(int) ,putchar可以输出一个ASCII码的字符形式,并返回这个ASCII码。gets()是需要参数的,所以要实现定义字符串str,然后把输入的字符串存在str,再用puts输出。gets的返回值char *就是输入的str,puts输出成功返回0,失败返回EOF。int scanf() 返回的是是输入的参数的个数。gets()和puts()转载 2023-06-06 16:04:38 · 67 阅读 · 0 评论 -
C温故补缺(九):字节对齐与排序
这样就可以把几个不同的对象用一个字节的二进制位域来表示。因为C语言有默认的对齐方式,段内按4字节对齐,所以虽然Data只用了两位,仍要申请4字节的内存。一般说,一个位域只能在一个字节中,一个字节可以有多个位域,有时为了对齐,会填充空位域。如bs的第一个字节只存放a这一个位域,剩下的3位放不下b,c,所以用空位域对齐。:是定义在结构体中的指定了变量宽度的变量 (变量宽度的单位是bit/位)int型占4个字节,但指定两位的位域后,输出的却是4个字节?如果按默认对齐方式,不足四字节的按四字节算,那么,转载 2023-06-06 15:58:42 · 68 阅读 · 0 评论 -
C温故补缺(八):结构体与共用体
因为union作为变量时共用相同的内存地址,且同一时间内只能作为一种类型的变量,所以可以根据这个特点设计程序,来查看机器的内存字节排序是大端还是小端。只是结构上和结构体相似,但共用体更接近于一个变量,这个变量的类型可以是多种的.但是它不能同时有多个类型。用Data定义的变量可以是int,long或char []型的,它的内存空间按最大的变量算。是一个可以存储多个不同类型的变量的结构,类似于面对对象中的类(只有成员变量的类).结构变量,定义在结构的末尾,最后一个分号之前,可以指定一个或多个结构变量。转载 2023-06-06 15:34:22 · 48 阅读 · 0 评论 -
C温故补缺(七):函数指针与回调函数
在功能上,回调函数和普通调用函数没差,回调函数存在的意义就在于其作为参数可变.在项目开发过程中,函数库和主程序一般时分开的,当库函数中的函数不能满足需求时,如果不想改库函数源码,就可以重新写新的库函数,调用时只需传入新的回调函数即可.其实回调函数是一种破坏系统结构的设计思路,只是迫不得已的修改,一旦文件中出现多回调函数,那么说明之前的函数库设计不合理,需要重新构建函数库。指向一个确定的函数后,就可以通过指针调用函数,在实际执行中还是max函数栈,并不是funp函数栈。转载 2023-06-06 15:29:27 · 57 阅读 · 0 评论 -
C温故补缺(六):C反汇编常用的AT&Tx86语法
表示长度,根据操作的是1字节,2字节,4字节,8字节,分别对应后缀b,w,l,q,即byte(1字节),word(1个字),long word(双字),quad word(四字)指令寄存器RIP包含下一条将要被执行的指令的逻辑地址,通常情况下,每取出一条指令后,RIP会自动指向下一条指令,但遇到call和ret时,RIP会被修改。RFLAGS和8086的FLAGS寄存器类似,也是用来存不同标记和状态的,但它是64位的,远比8086长,但常用的也就是那几个。ScaleFactor的取值可以是1,2,4,8。转载 2023-06-06 15:25:14 · 196 阅读 · 0 评论 -
C温故补缺(五):main函数的参数
main()函数的参数,用于在外部执行时传入参数,类似windows的bat脚本或linux的sh脚本.在bat脚本中传入参数,用%接收.sh脚本的参数用$接收.:参数的数量,不用指定,会自动很具参数个数生成,实际的argc=参数个数+1,因为第一个参数是运行的程序本身,这个类似linux的bash语言。:字符串数组,也就是接收的参数,argv[0]是程序本身,argv[1]是第一个参数,类型为字符数组。:执行程序所用的环境参数,也类似linux的bash语言的系统参数。转载 2023-06-06 15:20:47 · 65 阅读 · 0 评论 -
C温故补缺(四):GDB
查看寄存器用:info register rip/rsp...,或info registers所有寄存器。在调试前,需要先编译.c程序,且要加上-g使输出文件变得可调式。u:显示的内存字节长度,用b/h/w/g表示1/2/4/8字节。n是查看内存个数,即该内存后多少字节,也可以是负数,表示前面。查看内存:examine,简写成x,x /设置参数和显示参数,相当于main()的参数。x/d/o/t:16,10,8,2进制显示。来查看函数栈帧的反汇编代码。c/s:字符,字符串。转载 2023-06-06 14:56:30 · 78 阅读 · 0 评论 -
C温故补缺(三):存储类声明符(auto,register,extern,static)
③。转载 2023-06-06 14:48:45 · 51 阅读 · 0 评论 -
C温故补缺(二):volatile
volatile也是一个类型修饰符,被其修饰的变量意味着可以被某些编译器未知的因素修改,如操作系统,硬件,线程等.cmp 用0和pass比较,只有相等时ZF=1,其他只要pass非零,ZF=0。所以,pass=0,则cmp 0,pass的结果ZF=1,jne不跳转。添加volatile,不再放在存储器了,而是在寄存器中,每次都test。当遇到volatile修饰的变量时,编译器对访问该变量的代码就。当pass=1时,编译器就会优化次代码,将循环条件置为。:两个数按位与运算,只有所有位结果都是0,ZF=1。转载 2023-06-06 14:43:47 · 82 阅读 · 0 评论 -
C温故补缺(一):数据类型和基本类型占位
数据的类型只是一个标签,人为规定他们存什么样的数据,但实际int long是一样的内存空间:都是4个字节,32位.char则是1个字节,8位,这8位可以存8个二进制位,至于它是什么值,是由编译器处理的.对于cpu来说,都是相同的二进制位.而float和double则存在IP指令指针寄存器,并用LC标志其类型和内存对齐系数,也就是说,浮点数需要额外的指令来操作,并最终在Xmm寄存器运算。:指针(*),数组([]),结构体(struct),共用体(union),函数(fun()):就是算术类型,包括。转载 2023-06-06 14:41:50 · 80 阅读 · 0 评论