C/C++
talentluke
这个作者很懒,什么都没留下…
展开
-
C/C++中产生随机数(rand,srand用法)
计算机的随机数都是由伪随机数,即是由小M多项式序列生成的,其中产生每个小序列都有一个初始值,即随机种子。(注意: 小M多项式序列的周期是65535,即每次利用一个随机种子生成的随机数的周期是65535,当你取得65535个随机数后它们又重复出现了。) 我们知道rand()函数可以用来产生随机数,但是这不是真正意义上的随机数,是一个伪随机数,是根据一个数(我们可以称它为种子)为基准以某个递推公式推算出来的一系列数,当这系列数很大的时候,就符合正态公布,从而相当于产生了随机数,但这不是真正的随机数,当计算原创 2010-12-02 10:09:00 · 872 阅读 · 1 评论 -
浅谈内存泄漏
<br />对于一个c/c++程序员来说,内存泄漏是一个常见的也是令人头疼的问题。已经有许多技术被研究出来以应对这个问题,比如Smart Pointer,Garbage Collection等。Smart Pointer技术比较成熟,STL中已经包含支持Smart Pointer的class,但是它的使用似乎并不广泛,而且它也不能解决所有的问题;Garbage Collection技术在Java中已经比较成熟,但是在c/c++领域的发展并不顺畅,虽然很早就有人思考在C++中也加入GC的支持。现实世界就是这样原创 2011-01-01 01:35:00 · 707 阅读 · 0 评论 -
如何检测内存泄漏——重载new和delete
作者 ariesram 电子邮件地址 [email protected], 或 [email protected] 本文及本人所有文章均收集在bambi.may10.ca/~ariesram/articles/中。 本文授权给www.linuxaid.com.cn。 正文: 我曾经参与过一个比较大的项目,在这个项目里面,我们没有一个完全确定的设计文档,所以程序的实现常常变动。虽然我们有一个比较灵活的框架,但是从程序的角度来讲,它使我们的程序非常的混乱。直到发原创 2011-01-02 01:16:00 · 754 阅读 · 0 评论 -
copy函数
<br /> vector<int> v1, v2;<br /> v1.push_back(1);<br /> v1.push_back(2);<br /> v1.push_back(3);<br /> v2.push_back(4);<br /> v2.push_back(5);<br /> v2.push_back(3);<br /> set<int> s;<br /> //copy(v1.begin(), v1.end原创 2011-01-04 23:09:00 · 1405 阅读 · 0 评论 -
如何重载new和delete函数
在嵌入式系统中使用C++的一个常见问题是内存分配,即对new 和 delete 操作符的失控。 具有讽刺意味的是,问题的根源却是C++对内存的管理非常的容易而且安全。具体地说,当一个对象被消除时,它的析构函数能够安全的释放所分配的内存。 这当然是个好事情,但是这种使用的简单性使得程序员们过度使用new 和 delete,而不注意在嵌入式C++环境中的因果关系。并且,在嵌入式系统中,由于内存的限制,频繁的动态分配不定大小的内存会引起很大的问题以及堆破碎的风险。 作为忠告,保守的使用内存分配原创 2011-01-05 10:36:00 · 4122 阅读 · 0 评论 -
位运算符
1. 按位与运算 按位与运算符"&"是双目运算符。其功能是参与运算的两数各对应的二进位相与。只有对应的两个二进位均为1时,结果位才为1 ,否则为0。参与运算的数以补码方式出现。 例如:9&5可写算式如下: 00001001 (9的二进制补码)&00000101 (5的二进制补码) 00000001 (1的二进制补码)可见9&5=1。 按位与运算通常用来对某些位清0或保留某些位。例如把a 的高八位清 0 , 保留低八位, 可作 a&255 运算 ( 255 的二进制数为000000001111原创 2011-01-11 01:52:00 · 945 阅读 · 0 评论 -
“初始化”: 截断常量值
(1)short i = 0x8000;//有警告:“初始化”: 截断常量值”(2)int j = i;//无警告因为(1)0x8000是数字,数字默认是int型的,int的表示范围比short大,所以从int隐式转换为short会警告截断。如果改成显示转换short i = (short)0x8000;则不会警告。因为(2)中i为short型,从小范围的short隐式转换为大范围的int,不会截断,即使没有显示转换也不会有警告,而是用最高位补足不足的位,即正数补0原创 2011-01-12 01:11:00 · 18444 阅读 · 3 评论 -
参数入栈顺序和计算顺序
int main(){ int i = 1; printf("%d/n%d/n%d/n", i, i++, ++i); return 0;}在vs2008下输出3 2 3。部分汇编代码如下:int i = 1;00418AAE mov dword ptr [i],1 //i=1 printf("%d/n%d/n%d/n", i, i++, ++i);00418AB5 mov eax,dword ptr [i]原创 2011-01-12 23:35:00 · 704 阅读 · 0 评论 -
C++问题集
<br />1:C和C++有什么区别: <br /> C++支持面向对象的编程,同时兼容C语言的面向过程编程 <br /><br /> 2:VB和C++有什么区别: <br /> VB是一门基于对象语言,有对象和类的概念,但是对于继承、多态实现的不好 <br /><br /> 3:VC和C++有什么区别: <br /> VC可以看成是C++加上MFC基础类库的组合 <br /><br /> 4:声明一个引用是需要注意什么,函数返回引用时需要注意什么: <br /> 1 必须在原创 2011-01-13 00:24:00 · 554 阅读 · 0 评论 -
C++中的异常(exception)
C++实践1.简介<br /> 异常是由语言提供的运行时刻错误处理的一种方式。提到错误处理,即使不提到异常,你大概也已经有了丰富的经验,但是为了可以清楚的看到异常的好处,我们还是不妨来回顾一下常用的以及不常用的错误处理方式。1.1 常用的错误处理方式<br />返回值。我们常用函数的返回值来标志成功或者失败,甚至是失败的原因。但是这种做法最大的问题是如果调用者不主动检查返回值也是可以被编译器接受的,你也奈何不了他:) 这在C++中还导致另外一个问题,就是重载函数不能只有不同的返回值,而有相原创 2011-01-16 22:47:00 · 863 阅读 · 0 评论 -
如何把字符3转换成数字3?
#include "stdio.h"main(){ char c='3'; int i = c - 48;//或者用以下方法 //int i = c - '0';// int i = c ^ '0'; //int i = c & 15; printf("%d/n", i); }原创 2010-11-25 00:17:00 · 2917 阅读 · 0 评论 -
复制文件
使用C++标准程序库的输入输出流(I/O Stream)复制文件,存在许多的方法, <br /><br />方法一:逐个字符复制 <br />#include < fstream > <br /><br />std::ifstream input( "in ",ios::binary); <br />std::ofstream output( "out ",ios::binary); <br />char ch; <br /><br />while (input.get(ch原创 2011-05-12 08:05:00 · 575 阅读 · 0 评论 -
动态链接库导出C++类
首先使用Wizard创建一个Win32 Dynamic-Link Library工程,然后定义一个简单的C++类CInDLL.由于该类会被工程之外的文件所引用,所以需要对这个类进行引出。因为只有引出后所生成的DLL中才带有供足够的信息以在连接和运行时被正确引入到进程空间中。有两种方法可以引出类,使用__declspec(dllexport)定义和使用定义文件。 下面先讲使用__declspec(dllexport)的方法:将类定义改为:class __declspec(dllexport) CInDLL原创 2011-05-22 17:32:00 · 3743 阅读 · 0 评论 -
指针的引用
int main(){ int a = 2; int b = 3;//int& const c = b;//会忽略const,因为引用初始化后就不可以改变的,此处c就是b的别名,不会是其他的别名int const & c = b; //c = 8;//不可以 b = 8;//却可以 int *p = &a; /*int * const &p1 = p;p1 = &b;//不可以*p1 = 6;//可以*/ //int const *&p1 = p;//不可以/*int const * const &原创 2011-04-22 10:25:00 · 437 阅读 · 0 评论 -
循环条件
namespace LinkListTest{ template class Node { public: Node(const T& data, Node* next) : _data(data), _next(next) {} T GetData() const { return _data; } Node* GetNext() const { return _next; } void SetNext(Node* next) { _next = next; } pri原创 2011-04-21 23:20:00 · 782 阅读 · 0 评论 -
执行地址的函数
#include using namespace std;void print(){cout }string get(int i, int j){cout string result = "get i j";return result;}int main(){ typedef void(*voidFuncPtr原创 2012-04-20 16:04:41 · 569 阅读 · 0 评论 -
union和struct类型的大小计算
对齐就是要满足存储变量的起始地址与对齐大小余数为0。对于union,分两步:先算union对齐大小,对齐的大小是取决于union成员中字节对齐最大的那个;再算union实际分配的空间,而分配给union的实际大小不仅要满足是对齐大小的整数倍,同时要满足实际大小不能小于最大成员的大小。如:Union U1{Char a[9];Intb;};成员a是char数组,对原创 2010-12-31 00:36:00 · 8889 阅读 · 6 评论 -
数据类型隐式转换
今天犯了一个粗心的错误:int a = 1, b = 2;double c = 2.4;double d ,e;d = a/b *c;e = (double)a/b * c;cout cout原创 2010-12-29 01:07:00 · 756 阅读 · 0 评论 -
C程序优化方法
<br />对程序进行优化,通常是指优化程序代码或程序执行速度。优化代码和优化速度实际上是一个予盾的统一,一般是优化了代码的尺寸,就会带来执行时间的增加,如果优化了程序的执行速度,通常会带来代码增加的副作用,很难鱼与熊掌兼得,只能在设计时掌握一个平衡点。<br />一、程序结构的优化<br />1、程序的书写结构<br />虽然书写格式并不会影响生成的代码质量,但是在实际编写程序时还是应该尊循一定的书写规则,一个书写清晰、明了的程序,有利于以后的维护。在书写程序时,原创 2010-12-29 01:01:00 · 3288 阅读 · 1 评论 -
左值右值
什么情况下返回指针?什么情况下返回引用?指针和引用的效果一样么?这里不仅涉及到引用的实现,也涉及到左值与右值的概念。因为返回值性质的不同决定了引用与指针必定不是相同的。相信你读过我写的这篇文章之后,会有一个比较清醒的认识。 左值(lvalue)和右值(rvalue)最先来源于C语言。最先在C语言中表示位于赋值运算符两侧的两个值,左边的就叫左值,右边的就叫右值。比如:int ii = 5; //ii是左值,5是右值int jj = ii; //jj是左值,ii是右值上面表明,左值肯定可以原创 2010-12-28 00:25:00 · 4377 阅读 · 5 评论 -
把int转换为char把int转换为char
char *ultoa(unsigned long value,char *string,int radix) 将无符号整型数value转换成字符串并返回该字符串,radix为转换时所用基数 char *ltoa(long value,char *string,int radix) 将长整型数value转换成字符串并返回该字符串,radix为转换时所用基数 char *itoa(int value,char *s原创 2010-12-02 17:10:00 · 115943 阅读 · 0 评论 -
超越private
#define private publicclass Test{public: Test(int i, double d, char c) { Init(i, d, c); } void Init(int i, double d, char c) { _i = i; _d = d; _c = c; }private: int _i; double _d; char _c;};int main(){原创 2010-10-18 23:44:00 · 407 阅读 · 0 评论 -
利用指针访问局部静态变量
<br />char* p = 0;<br /> <br />void fun()<br />{<br /> static char ch = 'a';<br /> p = &ch;<br /> cout << "atatic ch====" << ch << endl;<br />}<br /> <br />#line 2 "my.cpp"<br />#define MY_FILE __FILE__<br />int main()<br />{<br /> //change原创 2010-10-18 23:51:00 · 2337 阅读 · 0 评论 -
strcpy()、memcpy()、memmove()、memset()的实现
strcpy(), 字符串拷贝.char *strcpy(char *strDest, const char *strSrc){ assert((strDest!=NULL) && (strSrc !=NULL)); char *address = strDest; while( (*strDest++ = * strSrc++) != '/0') NULL ; return address ; }memcpy,原创 2010-12-08 19:36:00 · 349 阅读 · 0 评论 -
数组与指针的区别
在C语言中对于下面的两种情况,是否相同呢?char a[] = "abcdefg";---------------1char *p = "abcdefg";-----------------2在谈到这些区别时,应该先谈一下计算机中对变量是如何存储的。从编译原理中我们知道,对于所有的变量他都会影射到一个符号表中。为了简化,这里给出一种最简单的便于理解的符号表:a0xffaap0xffcc表1 一个简单的符号表示例以上表格中a代表一个变量,0xffaa则为变量a的内容的存储地址;p代表另一个变量,0xffcc为原创 2010-10-18 17:14:00 · 400 阅读 · 0 评论 -
几个宏
<br />#line 10 //设置行号<br />#line 2 "my.cpp"//设置行号和当前文件名<br /><br />int main()<br />{<br /> cout << __LINE__ << endl;//输出当前代码行号,英文状态下前后两个_<br /> cout << __FILE__ << endl;//输出当前文件路径,英文状态下前后两个_<br /> cout << __DATE__ << endl;//输出当前时间,英文状态下前后两个_<br原创 2010-10-18 23:55:00 · 521 阅读 · 0 评论 -
#pragma的作用
<br />#pragma的作用 <br />在所有的预处理指令中,#Pragma指令可能是最复杂的了,它的作用是设定编译器的状态或者是指示编译器完成一些特定的动作。#<br />pragma 指令对每个编译器给出了一个方法,在保持与C和C++语言完全兼容的情况下,给出主机或操作系统专有的特征。依据定义,编<br />译指示是机器或操作系统专有的, 且对于每个编译器都是不同的。 <br />其格式一般为: #Pragma Para <br />其中Para 为参数,下面来看一些常用的参数。 <br />(1原创 2010-10-19 00:18:00 · 1443 阅读 · 0 评论 -
在C语言使用位运算实现循环移位
<br /> <br />循环移位区别于一般移位的是移位时没有数位的丢失。循环左移时,用从左边移出的位填充字的右端,而循环右移时,用从右边移出的位填充字的左侧。这种情况在系统程序中时有使用,在一些控制程序中用得也不少。<br /> 设有数据说明:<br /> a=01111011,循环左移2位 正确结果: 11101101<br /> 过程:<br /> b=a>>(8-2) 用来得到正常左移丢失的位和循环移位后其正确位置 b=00000001;<br /> a=a<<2;左移 a=1110110原创 2010-12-11 17:38:00 · 1344 阅读 · 0 评论 -
int (**p)[2]的疑惑
int (**p)[2]首先p是指针类型,不是数组。p指向的数据类型,即*p的类型为int (*)[2]。 那么要申请含有n个int(*)[2]元素的数组,并用p指向这个数组的地址,方法如下int (**p)[2] = new (int (* [n])[2]); //不是int (**p)[2] = new (int(*)[2])[n]; //也不是int (**p)[2] = new ((int(*)[2])[n]); 因为是new一个数组,为了理解,可以添加一个数组名称,数组名称必须放在最里面的括号内原创 2010-10-23 15:58:00 · 2036 阅读 · 0 评论 -
原码、反码、补码、float、ASCII码
char ch=277在内存中的二进制形式因为数据在计算机中都是以二进制表示的,编译系统对于不同类型的变量分配不同大小的存贮空间,制定不同的取值范围。比如整型在计算机中的存储用2个字节16位的存储空间,其中的最高位代表符号位的,符号位为0表示的是正数,符号位为1表示为负数,整型数据在内存中以二进制的补码存放。 以10和-10说明正数在内存中的存放形式: 十进制 10 -10 二进制原码 0000000000001010 10000原创 2010-10-24 01:25:00 · 4975 阅读 · 0 评论 -
复杂指针读法
C代码 int a; // 一个整形 int * a; // 一个指针, 批向一个整形 (整形指针) int * a(); // 一个函数, 反回一个整形指针 int * a[10]; // 一个数组, 里面存放着整形指针 int (*a)(); // 一个指针, 指向一个函数, 该函数返回整形 int (*a)[]; // 一个指针, 指向一个数组, 数组里放着整形 int a; // 一个整形int * a;原创 2010-10-23 15:20:00 · 2328 阅读 · 0 评论 -
继承 和static
<br />继承和多态<br />1。友元是不可以被继承的:基类的友元不可以访问派生类的成员;同样,一个友元的派生类也不可以访问定义友元的类。<br />2。除static成员外,每个派生类都保存了基类的一个副本,包括派生类不能访问的 private成员;static在整个继承层中只有一个,其访问属性跟其他成员一样。<br />3。虚函数在本质上是语义上的完备性表现:作为基类的成员却可以能被派生类重新定义;当然也正因为如此才有了多态。<br />4。派生类的声明不允许有继承列表。<br />5。继承是非自反原创 2010-12-14 14:38:00 · 3447 阅读 · 0 评论 -
cerr, cout , clog
<br />三个都是ostream类定义的输出流对象,<br /><br />cout是在终端显示器输出,cout流在内存中对应开辟了一个缓冲区,用来存放流中的数据,当向cout流插入一个endl,不论缓冲区是否漫了,都立即输出流中所有数据,然后插入一个换行符.<br /><br />cerr流对象是标准错误流,指定为和显示器关联,和cout作用差不多,有点不同就是cout<br />通常是传到显示器输出,但可以被重定向输出到文件,而cerr流中的信息只能在显示器输出.<br /><br />原创 2010-12-14 14:39:00 · 1574 阅读 · 1 评论 -
类中定义常量
A: 如何在类中定义常量? Q: 如果你想得到一个可用于常量表达式中的常量,例如数组大小的定义,那么你有两种选择: class X { static const int c1 = 7; enum { c2 = 19 }; char v1[c1]; char v2[c2]; // ... }; 一眼望去,c1的定义似乎更加直截了当,但别忘了只有static的整原创 2010-12-16 21:49:00 · 9623 阅读 · 0 评论 -
函数调用规范
函数调用规范 当高级语言函数被编译成机器码时,有一个问题就必须解决:因为CPU没有办法知道一个函数调用需要多少个、什么样的参数。即计算机不知道怎么给这个函数传递参数,传递参数的工作必须由函数调用者和函数本身来协调。为此,计算机提供了一种被称为栈的数据结构来支持参数传递。 函数调用时,调用者依次把参数压栈,然后调用函数,函数被调用以后,在堆栈中取得数据,并进行计算。函数计算结束以后,或者调用者、或者函数本身修改堆栈,使堆栈恢复原装。在参数传递中,有两个很重要的问题必须得到明确说明: 1) 当参数个数原创 2010-10-27 00:14:00 · 621 阅读 · 0 评论 -
vector的size_type
<br />for( vector <int>::size_type j=vec.size()-1; j>=0; --j ) <br />会出现死循环,一直在刷屏。<br />for( int j=vec.size()-1; j>=0; --j ) <br />却是正确的。<br />size_type是unsigned int型的,你这么弄,当j==0之后,j--,那么j理应为-1,但是unsigned属性,让它变为一个正数了,所以会无限循环!!!<br /> <br /> <br />原创 2010-11-04 21:46:00 · 4445 阅读 · 1 评论 -
线程死锁
你在主线程用了WaitForSingleObject,导致了消息循环的阻塞,界面假死。然后在线程中调用了SetDlgItemText,而SetDlgItemText实际上调用的是SendMessage,而SendMessage要等待主线程处理完毕发送的消息才返回继续执行,而你主线程的消息循环已经阻塞,无法处理消息,导致整个过程“我等你,你等我”,无穷下去在界面线程不能使用Sleep和W转载 2013-03-14 15:12:44 · 1082 阅读 · 0 评论