Posts Tagged ‘C’

July 6, 2010

  对qsort需要注意几点:

  • qsort中第一个参数是待排序数组的开始地址,既然是数组,各元素就是同类型、同大小的对象,且数组是“一维数组”(即地址是连续的);
  • qsort用以区分对象的依据是第二和第三个参数,分别表示对象个数和每个对象的大小(字节);
  • qsort并不知道每个对象的类型和结构,排序准则由用户在第四个参数(比较函数)中指出,qsort按该比较函数准则的“升序”对数组进行排序;
  • 标准C不支持运算符重载,各对象的交换(因为这是qsort)靠的是逐字节的拷贝(memcpy?)。

  在上面的两片代码中,待排序的对象一个是字符型指针,一个是char (*)[10]型数组。然后,就没有然后了。

Tags: ,,. 52 views
May 21, 2010

  在形如struct structName varName;的语句中,struct是必须的吗?这是一个显而易见的语法问题,但却容易被忽略,尤其容易被C+C++的同志们忽略。
  在标准C中,struct关键字是必须的:

1
2
3
4
5
6
7
8
9
10
struct structName {
    int n;
};
//~ typedef struct structName structName;
int
main()
{
    struct structName n;
    return 0;
}

若没有前置的struct关键字,上面的代码就不能通过编译。我的gcc会提示”structName” undeclared, parse error before ‘n’的错误。为了方便,通常会使用typedef struct structName structName;语句来为struct structName定义类型别名。
  但是,在C++中,一般情况下,struct/class关键字就不是必须的。但是,在有些情况下struct/class关键字又是必须的,因为这时的名字structName有歧义性。这是因为,C/C++语言允许用户自定义类型和函数同名。

Tags: ,. 38 views
November 28, 2009
1
2
3
4
5
6
7
8
9
10
11
12
13
void fun1(char * str) {}
void fun2(char ** str) {}
 
//~ int main(int argc, char ** argv)
int main(int argc, char * argv[])
{
	char str1[] = "Hello, Piggy!";
	char str2[][4] = "Hello, Piggy!";
	fun1(str1);
	fun2(str2);
	fun2(&str1);
	return 0;
}

  上面的snippet有错误吗?有几个?你能找出来并说出原因吗?4、5两行有区别吗?想一下,然后看gcc给出的错误信息,

Tags: . 7 views
November 14, 2009

  看Chris对内联的总结,说到内联函数在编译时会被放入”符号表”,想一探究竟,结果却发现另外一个问题,疑惑不解。

1
2
3
4
5
6
7
#include <stdio.h>
inline int add(int a, int b) { return a + b; }
int main()
{
	int n = add(1,2);
	return 0;
}
Tags: ,,. 7 views
November 3, 2009

  这里面猫腻儿还真不少。

  karmic到源里面没有以前到vim-full包了,取而代之到是vim包,但现在有很多问题,n”+yy和n”+p无法和系统”剪切板”里到内容关联了,不知道什么原因。

Update
  一切都释然了,只要意识到,>也需要进行类型提升。那么后面到-1啦-2啦之类的,都是很大很大的数了,循环根本就进不去,更别提死循环了。这样看来四、五两段程序就没有必要列出来了。其实,我是被它们的汇编代码给迷惑住了。

Tags: ,,. 8 views
August 22, 2009
  1. 减少pthread_cond_signal和sem_post的调用,只在有必要的时候调用;
  2. 尽量避免pthread_mutex进入竞争态。增大消息队列的大小,可以有效减少竞态条件的出现。

/*
* 此处循环判断的原因如下:假设2个线程在getq阻塞,然后两者都被激活,
* 而其中一个线程运行比较块,快速消耗了2个数据,
* 另一个线程醒来的时候已经没有新数据可以消耗了。
* 另一点,man pthread_cond_wait可以看到,
* 该函数可以被信号中断返回,此时返回EINTR。
* 为避免以上任何一点,都必须醒来后再次判断睡眠条件。
* 更正:pthread_cond_wait是信号安全的系统调用,不会被信号中断。
*/

Tags: ,,. 41 views

表明看来似乎合情合理,由于C++的多态特性,允许我们将一个子类地址赋给父类型的指针pb,释放对象时理所当然的对pb进行delete。但,在程序运行时,并没有输出M destructed…,即D::m的析构函数没有被调用,而m的析构函数是需要D::~D()来调用的,所以子类D的析构函数也没有被调用。这是很容易理解的,因为父类的析构函数不是virtual的。由此,我们得出结论,用来继承的父类的析构函数总应该是virtual的,除非你确定它绝对不会被用于多态。关于这一点,《Effective C++》里面已经讲到了。

除了上面的问题,我们还应该关心的是,尽管析构函数没有被调用,那M::i的空间被释放了吗?It’s a question!由于析构函数没有被调用,那么释放M::i的任务就完全落在了delete身上的了,那么delete做到了吗?It’s a very question!这又回到了上一篇日志中所描述的问题上了。我的观点是delete做到了它应该做的事情,它只负责释放当初new申请的空间,即对象本身,至于对象里面是否有动态申请的内存,那就不是delete而是对象析构函数自己的工作了。

Tags: ,,. 7 views
August 19, 2009

源码之前,了无秘密。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
//~ demo.cpp
#include <iostream>
#include <fstream>
#include <string>
#include <streambuf>
using namespace std;
//~ 测试代码 :)
int main()
{
	ifstream in("demo.cpp");
	char buffer[4096]="original content in this buffer";
	cout<<buffer<<endl;
	streambuf * ptrbuff = in.rdbuf(); //~ 将streambuf与文件句柄关联
	ptrbuf->pubsetbuf(bufer, 4096); //~ 设置缓冲区,即设置in的缓冲区
	cout<<buffer<<endl; //~ 此时bufer里面的内容还是original content in this buffer
	string str;
	in>>str; //~ 真正要输入时bufer才被填充为in的内容
	cout<<str<<endl;
	cout<<buffer<<endl;
	return 0;
}

另外,还有一个filebuf,用法相近。看了很多C++方面的书,从来没有那本书对I/O流做过详细的介绍。C里面有setbuf可以修改缓冲区,但我在fstream里面却没看到这么个setbuf,rdbuf倒是有一个,它返回streambuf类型的指针。搜索streambuf的用法,无果,MSDN里面看到streambuf有一个setbuf的成员,甚喜。编译器说,setbuf是私有的,再看MSDN,还有一个pubsetbuf,哟西!

Tags: ,. 77 views
August 16, 2009
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
template <class T>
class Queue
{
public:
	Queue(int size = 30);
	~Queue();
	void EnQueue(T value);
	T DeQueue();
	T GetFirst();
	bool IsEmpty();
	bool IsFull();
	void ClearQueue();
private:
	T *queue;
	int front;
	int rare;
	int MaxSize;
	int CurLen;
};
Tags: ,,. 2 views

一个堆栈类模板,和用到此模板的一个表达式计算器。
输入四则运算表达式(可含括号),输出计算结果,暂未提供盛放运算和浮点数功能。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
class Stack   
{   
public:   
	Stack(int stack_size = 30);   
	~Stack();   
	void Push(T value);   
	T Pop();   
	T Top();   
	bool IsEmpty();   
	bool IsFull();   
	void ClearStack();   
private:   
	int top;   
	T* stack;   
	int size;   
};
Tags: ,,. 38 views
Page 1 of 212