- 博客(67)
- 收藏
- 关注
原创 输入一个链表的头结点,从尾到头反过来打印每个结点的值——5
一般这样的题,链表肯定不会是一个双向链表还带个循环什么的,也就是只给一个单链表的头结点,然后从尾到头输出每个结点的值; 如果从前往后去找最后一个结点,那找到了输出然后就没办法往返回往头部访问了,因为只是个单链表;因此可以想到,用递归来实现:#include using namespace std;template //将链表的结点定义为模板类,实现代码的复用性struc
2017-10-20 20:40:58 404
原创 将一个字符串中的空格替换为指定的内容——4
实现一个函数,将一个字符串中的所有空格替换为"%20",例如输入字符串"How beautiful you are!",输出结果应为"How%20beautiful%20you%20are!"。 首先,如果另开辟一块空间并且足够将全部空格都替换成"%20",然后一个单词一个单词的拷贝过去,当遇到空格时就放进去"%20",这种低效率的方法肯定是可行的,但很显然不仅效率不高还浪费存储空间,因此,
2017-10-20 20:40:55 509
原创 在一个每一行从左到右递增每一列从上到下递增的二维数组中查找一个整数是否存在——3
给定一个二维数组,数组的特点是:每一行从左到右数据大小依次递增,每一列数据从上到下依次递增,要求判断一个整数是否在这个二维数组中;设计二维数组如下:650) this.width=650;" src="http://s1.51cto.com/wyfs02/M02/7F/73/wKioL1cfMmLxgqRwAAAY1Yn6gfs969.png" title="arr[5][5].png" alt=
2017-10-20 20:40:52 597
原创 自我实现一个简洁版的String类——1
在C++中有C没有的string字符串类型,string类型的数据其实是一个指向字符串首地址的指针变量,因此在string类的默认成员函数拷贝构造和赋值运算符的重载就会涉及到深浅拷贝的问题,一不小心要么就是内存泄露要么就是多次释放同一块空间导致程序崩溃,下面就来模拟实现一个简洁版的String类: 既然是指向一个字符串的指针,因此类的成员变量就需要有一个char*类型的指针;#include
2017-10-20 20:40:49 355
原创 读写锁————用互斥量和条件变量模拟
一. 读写锁 在多线程环境下为了防止对临界资源访问的冲突我们往往会在线程函数中加入互斥锁来完成线程间的互斥;但是,在有些情况下,互斥锁mutex并不是那么高效,比如当要对一块缓冲区进行读写操作的时候,因为读的需要比写入修改的需要要多,读取数据并不会修改缓冲区的数据个数或者内容,如果要使用互斥锁就会耗费额外的时间,每一次读取都要争夺锁资源挂起等待,因此就可以使用另外一种锁机制————读写锁。
2017-10-20 20:40:45 760
原创 信号量————生产者与消费者模型(环形缓冲区)
一. 信号量 在进程间通信中有一种通信机制是信号量,它往往标识着一个临界资源的有无来控制不同的进程是否能访问到这个临界资源,它创建出来一般是一个信号量集的形式。 这里要提到的信号量,也是一个计数器,用来标识资源的个数,我们知道完成线程之间的互斥可以使用互斥锁,其实mutex也可以认为是一个计数器标识资源的可用数量,只是它的值非0即1,加锁时表示要使用资源,将mutex减1,释放锁表示有
2017-10-20 20:40:43 1405
原创 线程的同步与互斥(生产者与消费者模型)
一个进程中可以有多个线程,这些线程共享进程的资源,但当多个线程访问同一个资源时,在并不能保证操作是原子的情况下,就会产生冲突而使数据最终的结果不准确,像上次我们提到的将一个数进行加1操作需要三步:将数据从内存中取出;将数据加1;再将数据放回内存中,当多个线程并发执行这一操作时,有可能一个线程刚将数据从内存中取出就被临时切换出去了,这时别的线程进行加1操作,而当被切出去的线程重新回来继续执行加1操作
2017-10-20 20:40:40 969
原创 线程的同步与互斥(死锁的产生和避免)
可以知道,一条语句对一个变量进行+1操作,转成汇编指令共有三条:将这个变量从内存中取出;将其值加1;再将加后的结果放回内存;当一个进程中的两个线程同时进行这个操作时,本来期望的是将变量进行两次加1,但中途有可能当一个线程刚从内存中将变量取出就被切换暂停了,此时线程会保存硬件上下文,第二个线程将变量加1之后前面切出去的线程回来继续执行,这时保存的还是变量原来的值,再将变量加1,会发现变量的最终结果并
2017-10-20 20:40:37 440
原创 线程的控制与分离
一. 线程 可以知道,进程是作为系统中资源分配的一个基本实体,而线程就是在进程中作为资源调度的一个基本运行单位。 一个进程当中可以有多个线程,这些线程共享调用它们的进程中的资源,比如进程的uid和gid;比如文件描述符表和当前工作目录;比如每种信号的处理方式等; 但是每个线程也有属于自己私有的一份数据,比如每个线程都有自己的ID号;有自己的上下文,包括各种寄存器的值、程序计数器和
2017-10-20 20:40:34 219
原创 进程间通信(IPC)之————共享内存
一. 共享内存 在系统中,两个不同的进程都会维护自己的一块地址空间,这个地址空间一般是虚拟地址,会通过mmu和页表映射到对应的物理内存中,因为不同的进程会有不同的内存空间,因此两个进程之间是无法看见彼此的数据的,而共享内存就是使两个进程看到同一块地址空间,以此来实现不同进程间的数据交互。 值得提出的是,共享内存是进程间通信方式中最高效的一种,因为是直接通过访问内存来交换数据的,省去了消
2017-10-20 20:40:31 405
原创 进程间通信(IPC)之————信号量
一. 信号量 在谈论信号量之前,先要提到临界资源和临界区的概念,临界资源是指多个进程访问但一个时间段内只允许一个进程独占的资源,而临界区是指多个进程访问临界资源的这一段公共的代码。 信号量的本质是一种数据操作锁,也可以说就是一个计数器,它本身并不能提供对进程间的通信,而是通过控制某一资源来完成进程间的互斥和同步,比如当一个进程请求某一用信号量来表示的临界资源时,先要进行检查该资源的信号
2017-10-20 20:40:28 386
原创 进程间通信(IPC)之————消息队列
一.消息队列 前面提到的进程间通信的一种最基本的方式就是管道,而现在来谈一下另一种进程间的通信方式——消息队列。消息队列是从一个进程向另一个进程发送数据块的方式,每个数据块都有其类型,接收者接收的数据块也可以有不同的类型,这样我们就可以通过发送消息的方式来避免命名管道的同步和阻塞问题。 消息队列不同于管道的是,管道是基于字节流的,而消息队列是基于消息的,而且消息队列的读取方式不一定是
2017-10-20 20:40:26 230
原创 进程间通信(IPC)之————管道
在Linux操作系统中,每个进程都有属于自己的运行空间,空间内存放有数据和执行代码,那么不同的进程相互之间是如何进行数据和信息的交换呢?Linux中提供了一种用于进程间通信(IPC-Inter Process Communication)最基本的机制——管道。 在Linux系统中一切皆文件,管道是一种特殊的文件,它是在内核中开辟了一块缓冲区,该缓冲区大小往往是固定的,Ubuntu中为6553
2017-10-20 20:40:23 256
原创 inode及硬链接和软链接
*inode* 当我们需要打开一个文件的时候,往往是输入打开文件的命令加上文件名,这时操作系统就会去硬盘上查找对应的文件,这里应该知道,Unix/Linux系统内部并不使用文件名来查找相应的文件,而是通过一个叫“文件索引节点”的inode来进行查找,而这个inode用来存放文件的元信息,比如文件的创建者、文件的size和文件的时间信息等等,而每一个文件也相应的对应一个inode。*inode
2017-10-20 20:40:20 293
原创 Linux平台下变量在栈帧中的存储
局部变量的存储位置是在栈中,栈在内存中的特点是自上而下生长,也就是由高地址到低地址,当变量作为函数参数传递时为传值方式,函数形参作为接收方会开辟一块临时空间来拷贝实参的值,如下代码:650) this.width=650;" src="http://s5.51cto.com/wyfs02/M01/7E/64/wKioL1b-ILyCJeKlAABJJbHIj1E243.png" title="QQ
2017-10-20 20:40:17 331
原创 数据结构——广义表
实现广义表的内部基本函数,创建,拷贝,清除,计算表深度及结点个数等函数。代码如下:#pragma once;#include //表结点类型enum NodeType{ HEAD, VALUE, SUB,};//表各结点的成员struct GeneralizedNode{ NodeType _type; //结点类型 GeneralizedNode* _next;
2017-10-20 20:40:14 491
原创 稀疏矩阵的压缩存储及快速转置
当一个矩阵为稀疏矩阵时,有效数据的个数比无效数据要少得多,因此若将一个矩阵全部存储会浪费空间,可以只将有效数据存储起来,无效数据作为标记代码如下:#include #include using namespace std;//可用一个三元组来存储有效数据的信息templatestruct Triple{ size_t _row; size_t _col; T _value;};//系数矩阵类 te
2017-10-20 20:40:12 474
原创 自我实现内存管理
在我们使用内存的时候,偶尔会由于疏忽而忘记释放掉已用完的内存,从而引起内存泄露,因此可以写一个内存管理的程序,用来检查那些内存泄露,在什么位置,从而能使程序更高效。代码如下:#pragma once //头文件#include using namespace std;#include #include #include struct BlockInfo{ void* _p
2017-10-20 20:40:09 260
原创 别拿浅拷贝不当拷贝
我们知道C++中类里的成员函数中构造函数和拷贝构造都是值拷贝,所以地址也是值拷贝,也就是多个对象用到了同样的一块地址,例如:#include using namespace std;class String{public: String(char* str) :_str(new char[strlen(str)+1]) { strcpy(_str,str);
2017-10-20 20:40:06 200
原创 实现一个日期计算器
#include using namespace std;class Date{public: Date(int year = 1900,int month = 1,int day = 1) { //判断输入是否正确 if((year12)||(dayGetMonthDay(year,month))) { cout 0) { while(_day>GetMonthDay(_year,
2017-10-20 20:40:03 489
原创 使用mian函数的命令行参数
使用main函数的参数,实现一个整数计算器,程序可以接受三个参数,第一个参数“-a”选项执行加法,“-s”选项执行减法,“-m”选项执行乘法,“-d”选项执行除法,后面两个参数为操作数。#include #include #include enum JUDGE { RIGHT, ERROR};int judge = RIGHT; //设定了一个全局
2017-10-20 20:40:00 573
原创 实现将一个字符串转化成对应的整形数字
输入一个字符串比如“+1234”,将其转换成对应的数字1234输出,若是“-1234”,则输出-1234:#include enum Charec{TRUE,FALSE};int check = FALSE;int my_atoi(const char *str){ int num = 0; if((str != NULL)&&(*str != '\0')) { int minus = 0;
2017-10-20 20:39:57 2222
原创 模拟实现在一个字符串中查找一个字符串
在标准库中有一个函数strstr()用于在一个字符串中查找一个规定的字符串,这个函数可以模拟实现一下,代码如下:#include #include char *my_strstr(const char str[],const char strstr[]){ int i = 0,j = 0,k = 0; assert(str != NULL); assert(strstr != NULL); for
2017-10-20 20:39:54 295
原创 求一个数二进制位中有多少个 1 的不同解法
*返回一个数的二进制表达中1的个数。*#includeint main(){ unsigned int i; scanf("%d",&i); printf("%d的二进制表达中有 %d 个1",i,count_one_bits(i)); return 0;}int count_one_bits(unsigned int m){ int n,count; //
2017-10-20 20:39:52 531
原创 打印杨辉三角
*打印杨辉三角* 1 1 1 1 2 1 1 3 3 1 1 4 6 4 1 ...... 特点是每个数等于肩上两个数的和#includeint main(){ int i = 0,
2017-10-20 20:39:49 427
原创 折半查找 && 在标准输出上打印行号
*折半查找*#includeint half_search(int arr[],int first,int last,int n){ int mid = 0; while(first arr[mid]) //若大于中间数,在后一半查找 { first = mid + 1; } else ret
2017-10-20 20:39:46 210
原创 volatile 和 const 的用法
1.volatile类型修饰符,可以让变量被不同的线程访问和修改,也可以防止变量被编译器优化,而const用来限定一个变量不允许被改变,但下面的程序运行结果为20。#includeint main(){ volatile const int num = 10; int *p = (int *) & num; *p = 20; printf("%d\n",num); r
2017-10-20 20:39:43 329
空空如也
空空如也
TA创建的收藏夹 TA关注的收藏夹
TA关注的人