Archive for the ‘C++’ Category.

整数取反,颠倒位置

题目很简单,完成函数reverse,要求实现把给定的一个整数取其相反数的功能,举两个例子如下: x = 123, return 321 x = -123, return -321
规则:

1.完成功能函数即可。

下面是我用C写的,用C++其实也一样。

int reverse(int x) {
    int result = 0;
    do {
        int temp = x % 10;
        result = result * 10 + temp;
    } while ((x /= 10) != 0);
	return result;
}
int main()
{
	int num = 0;
	scanf("%d", &num);
	printf("%d\n", reverse(num));
	return 0;
}

这个是C++的
Continue reading ‘整数取反,颠倒位置’ »

explicit防止隐式转换

c++允许隐式转换,没有加入explicit限定符的都看作是能够实现隐式转换的,但有些时候不期望这样做。

例如:

class CBook
{
public:
	CBook(std::string name) : m_name(name), m_width(0), m_height(10) {}
	int Compare(CBook& book);
	std::string m_name;
	int m_width;
	int m_height;
};

CBook book1("book1");
book1.m_width = 10;
book1.m_height = 20;
int result = book1.Compare("book2");

在这里调用Compare函数时,本来是需要CBook参数的,但由于CBook的构造函数参数是std::string,这里编译器自动使用”book2″临时构造一个CBook对象,同时将这个临时对象传给Compare函数,并在离开Compare函数时自动析构,这就是隐式转换的过程。
Continue reading ‘explicit防止隐式转换’ »

ACE链接错误解决办法

今天编写程序时,某个工程需要用到互斥锁,而ACE正好有这个函数,在成员变量中加入下面这句:

private:
    ACE_Recursive_Thread_Mutex m_listBuffLock;

编译链接的时候报以下错误:

1>Linking...
1>   Creating library ../lib/MediaConverterModule.lib and object ../lib/MediaConverterModule.exp
1>MediaConverter.obj : error LNK2001: unresolved external symbol "__declspec(dllimport) public: int __thiscall ACE_Recursive_Thread_Mutex::release(void)" (__imp_?release@ACE_Recursive_Thread_Mutex@@QAEHXZ)
1>MediaConverter.obj : error LNK2001: unresolved external symbol "__declspec(dllimport) public: int __thiscall ACE_Recursive_Thread_Mutex::acquire(void)" (__imp_?acquire@ACE_Recursive_Thread_Mutex@@QAEHXZ)
1>MediaConverter.obj : error LNK2001: unresolved external symbol "__declspec(dllimport) public: __thiscall ACE_Recursive_Thread_Mutex::~ACE_Recursive_Thread_Mutex(void)" (__imp_??1ACE_Recursive_Thread_Mutex@@QAE@XZ)
1>MediaConverter.obj : error LNK2001: unresolved external symbol "__declspec(dllimport) public: __thiscall ACE_Recursive_Thread_Mutex::ACE_Recursive_Thread_Mutex(wchar_t const *,struct ACE_mutexattr_t *)" (__imp_??0ACE_Recursive_Thread_Mutex@@QAE@PB_WPAUACE_mutexattr_t@@@Z)
1>../bin_release/MediaConverterModule.dll : fatal error LNK1120: 4 unresolved externals

Continue reading ‘ACE链接错误解决办法’ »

VS2005中C#程序调用C++动态库断点无效解决办法

近段时间将编译环境换成了VS2005,出现了一些其名其妙的问题,比如C#的程序调用C++的动态库,设置断点始终提示“当前不会命中断点,还没有为该该文档加载任何符号”


Continue reading ‘VS2005中C#程序调用C++动态库断点无效解决办法’ »

调用DLL弹出The value of ESP was not properly saved across a function call

像这种错误一般是由于C++回调函数声明引起的,在声明回调函数指针的时候,使用

typedef void (*RecvMessage)(const char* msgContent);

只要将声明加上一个回调定义就可以了__stdcall,如下

#ifdef WIN32
	typedef void (__stdcall *RecvMessage)(const char* msgContent);
#else
	typedef void (*RecvMessage)(const char* msgContent);
#endif

这样就可以解决了。

windows和linux使用printf输出64位长整数

变量定义 输出方式 gcc(mingw32) g++(mingw32) gcc(linux i386) g++(linux i386) MicrosoftVisual C++ 6.0
long long “%lld” 错误 错误 正确 正确 无法编译
long long “%I64d” 正确 正确 错误 错误 无法编译
__int64 “lld” 错误 错误 无法编译 无法编译 错误
__int64 “%I64d” 正确 正确 无法编译 无法编译 正确
long long cout 非C++ 正确 非C++ 正确 无法编译
__int64 cout 非C++ 正确 非C++ 无法编译 无法编译
long long printint64() 正确 正确 正确 正确 无法编译

关于printf函数输出64位数的问题,其实在window下和linux下是不一样的
linux下是

printf("%lld/n",a);
printf("%llu/n",a);

windows下是

printf("%I64d/n",a);
printf("%I64u/n",a);

printf与cout混用输出先后顺序的问题

在代码中若使用了printf与cout,若不注意则会出现输出顺序与预想的不一致的问题。如下代码:

int main()
{
	int i = 0;
	for (i = 0; i < 3; i++)
	{
		std::cout << "i= ";
		printf("%d\n", i);
	}
	return 0;
}

Continue reading ‘printf与cout混用输出先后顺序的问题’ »

多字节字符与宽字符的printf输出

有某些情况需要用到输出多字节字符,而直接使用

printf("%s", xxx);

的方式只能输出第一个字符,例如下面的内存块中保存的宽字符:

0x00294B38  43 00 3a 00 5c 00 57 00 69 00 6e 00 64 00 6f 00 77 00 73 00 5c 00 73 00 79  C.:.\.W.i.n.d.o.w.s.\.s.y
0x00294B51  00 73 00 74 00 65 00 6d 00 33 00 32 00 5c 00 74 00 61 00 73 00 6b 00 68 00  .s.t.e.m.3.2.\.t.a.s.k.h.
0x00294B6A  6f 00 73 00 74 00 2e 00 65 00 78 00 65 00 00 00 cd cd cd cd cd cd cd cd cd  o.s.t...e.x.e...?????????

如果直接使用

printf("%s", xxx);

输出,则会将0x43后面的0x00当作结束符,也就是只会认为只有C字符就结束了,输出的时候会发现,只输出了C后面的内容则没有输出,而且使用

strlen(xxx);

来计算长度也为1。

如果需要完成输出,则需要将printf中的小写s改为大写即可,即

printf("%S", xxx);

如何双击dsw文件快速打开多个VC++6.0工程

在Win7操作系统下,如果是以Administrator登陆,则VC6.0打开工程文件的时候,不能同时打开多个工程文件,后打开的工程会将前一个工程close掉,这样,VC6.0只能出现一个进程。在xp下,我们可以设置文件打开的默认方式中去掉DDE选项,这样可以使得VC6可以同时打开多个工程,但在win7下,却没有办法找到这个设置窗口。经过实践,可以用以下办法解决:

打开cmd:

1)输入assoc .dsp回车,确认后缀为.dsp的文件类型为dspfile;
2)输入assoc .dsw回车,确认后缀为.dsw的文件类型为dswfile;
3)打开vc6的快捷方式的属性,拷贝vc6的路径,注意连两边的双引号都一起拷贝,比如时候这个路径:
“C:\Program Files\Microsoft Visual Studio\Common\MSDev98\Bin\MSDEV.EXE”
4)在cmd窗口,输入ftype dspfile=”C:\Program Files\Microsoft Visual Studio\Common\MSDev98\Bin\MSDEV.EXE” %1
5)在cmd窗口,输入ftype dswfile=”C:\Program Files\Microsoft Visual Studio\Common\MSDev98\Bin\MSDEV.EXE” %1

设置结束,双击不同的工程文件,看是否可同时打开多个工程文件吧。

c++类的基类构造函数

在c++中子类构造时,会先调用基类的构造函数,可以利用此方法,将所有子类中共用的成员变量放入到基类的构造函数中进行初始化,如下代码

class B
{
public:
	B()
	{
		printf("class B construct\n");
	}
	B(int a)
	{
		printf("class B construct a%d\n", a);
	}
	virtual ~B(){}
	virtual int Add(int a, int b);
};

class C : public B
{
public:
	C()
	{
		printf("class C construct\n");
	}
	C(int a)
	{
		printf("class C construct a%d\n", a);
	}
	virtual ~C(){}
	virtual int Add(int a, int b);
};
int main()
{
	B* b = new B;
	B* c = new C(1);
	int result = b->Add(1,2);
	printf("result1:%d\n", result);
	result = c->Add(1,2);
	printf("result2:%d\n", result);
	return 0;
}

Continue reading ‘c++类的基类构造函数’ »