其实,我最初写的不是这样子滴,对比上面的程序,看看下面这个哪里会出问题?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
string multiply(const string &l, const string &r)
{
	size_t lenl = l.size();
	size_t lenr = r.size();
	string result(lenl+lenr, '\0');
	for(size_t i = 0; i < lenl; ++i)
		for(size_t j = 0; j < lenr; ++j)
		{
			result[i + j + 1] += ctoi(l[i]) * ctoi(r[j]);
		}
	for(size_t i = lenl + lenr-1 ; i > 0; --i)
	{
		result[i - 1] += (unsigned char)result[i] / 10;
		result[i] = (unsigned char)result[i] % 10 + '0';
	}
	if(result[0] == 0)
		result.erase(0, 1);
	else
		result[0] += '0';
 
	return result;
}
Tags: ,,.

看了Linux内核代码linux/string.h中的一些字符串操作函数,有几个写的真是漂亮!

char * strstr(const char*, const char*)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
/**
 * strstr - Find the first substring in a %NUL terminated string
 * @s1: The string to be searched
 * @s2: The string to search for
 */
char *strstr(const char *s1, const char *s2)
{
	int l1, l2;
 
	l2 = strlen(s2);
	if (!l2)
		return (char *)s1;
	l1 = strlen(s1);
	while (l1 >= l2) {
		l1--;
		if (!memcmp(s1, s2, l2))
			return (char *)s1;
		s1++;
	}
	return NULL;
}
Tags: ,.
题外话

C/C++中,为了读或写一个文件,我们需要首先需要调用open来打开相应的文件,完成对该文件的访问(read, write)后,再调用close将之关闭。那么为什么不再read和write内部完成打开和关闭文件的操作呢?这是因为打开一个文件时操作系统需要根据文件名,在文件系统中查找文件的位置、检验文件的属性(读、写、执行、追加等)进而验证本次操作是否有相应的权限,对于write调用,还需要为文件分配存储(磁盘)空间。所有这些操作都是非常费时的,于是操作系统打开文件时,就在内核中相应的文件打开表中添加该文件的文件指针(打开该文件的进程也会有自己的文件表),结束对文件的访问后,再从相应的文件表中删除文件指针表项。

Tags: ,.

一直没弄明白在控制台下如何实现实时更新、无闪烁的时间显示,今天偶然发现回车(CR)和换行(LF)是不同的,在C语言中分别用转义字符’\r’和’\n’表示。回车的语义应该是”光标”移动到当前行的行首,而换行是”光标”移动到下一行,并没有定义一定移动到行首。这样,这里要实现的控制台下实时更新、无闪烁的小时钟就可以用相关的时间函数和回车符来完成:

Tags: .

Linux 为每个进程提供了三个定时器:

  • ITIMER_REAL: 给一个指定的时间间隔,按照实际的时间来计数,发出SIGALRM信号;
  • ITIMER_VIRTUAL: 当进程执行的时候才计数,发出SIGVTALRM信号;
  • ITIMER_PROF: 当进程执行或者是系统为进程调度的时候计数,发出SIGPROF信号。这个和ITIMER_VIRTUAL联合,常用来计算系统内核时间和用户时间。
Tags: ,.

如果两个或多个进程永久等待某个事件而该事件只能由这些等待进程的某一个引起,那么死锁就会发生。死锁的发生需要满足四个必要条件:

  • 互斥:资源的互斥访问,没有互斥就不会产生死锁;
  • 占有并等待:某个进程占有了一定资源,并且因无法得到其他资源而等待;
  • 非抢占:某个进程所占有的资源,不允许被其他进程抢占;
  • 循环等待:对于进程序列{P0, p1, …… , Pi, Pi+1, ……, Pn},Pi在等待Pi+1所占有的资源,P0占有了Pn需要的资源;
Tags: .
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
#include<iostream>
 
using namespace std;
 
class demo
{
public:
	demo(){}
private:
	const int m_matrix[10][10];
};
 
int main()
{
	return 0;
}

error C2439: ‘demo::m_matrix’ : member could not be initialized
这可咋办啊?class里面,普通数组可以有,可const数组就真的不能有吗?

Tags: .

多线程程序的各线程通常会共享某些资源,比如代码、文件、数据等,这些被共享的资源通常会成为临界资源。各线程访问临界资源的代码区段称作临界区,临界区代码的执行应该是互斥的,否则可能造成错误的行为。解决临界区问题的算法必须满足三个条件:

  • 互斥:临界区的访问应该是互斥进行的;
  • 有空让进:若没有线程的其临界区执行,则应该允许一个或者多个线程请求(进入区)进入其临界区;
  • 有限等待:任何线程都不能霸占临界区,即持续访问临界区的时间或者次数应该有一个上限;

下面的这段代码简易地实现了两个线程互斥地访问临界资源(std::string Critical),可以证明,其满足上述三个条件。

Tags: .
1
2
3
4
5
6
7
#include <iostream>
using namespace std;
int main()
<%
    cout<<"hello,world"<<endl;
    return 0;
%>

哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈!

Tags: .
题目描述:

给你n个整数,用这n个拼成一个超长的整数,要令这个新的整数最小

输入:

多组测试数据,每组第一行为n(1<=n<=1000),接下来是n个正整数,使用空格或者换行分开;
每个数字的长度不会超过1000,不存在前导0;
当n为0时结束程序.

输出:

对于每组输入,输出拼成的新的整数的结果

Tags: ,.