C++乱七八糟

内存释放了为什么还能使用
int* p=new int[10]; //你向房东租了间房子,房东给你一把钥匙p
p[0]=1234;          //你开始使用这间房子,扔了一堆你的东西
delete[] p;         //你向房东退房了
//p=NULL;           //你把钥匙还了,如果没有这句就是你没还钥匙
cout <<p[0];        //你明明退了房子,但没有还钥匙。然后还用这把钥匙开门进去。
                       //这时有三种结果:(1)房子还是老样子,你扔的东西都还在,就像你没退房一样
                       // (2) 房子已经被房东收拾过了,你的东西被扔掉了。
                      //  (3) 房子已经被租给其他人了,你被当做小偷暴打了一顿。
最后,请记住:退房记得还钥匙。 

 

 获取系统版本号

 OSVERSIONINFO osi;
    ZeroMemory(&osi,sizeof(OSVERSIONINFO));
    osi.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
    GetVersionEx(&osi);
    
    //判断系统是否是XP
    if (osi.dwMinorVersion >= 1 && osi.dwMajorVersion == 5)
    {
     

    }
    else
    {
     

    }

 

_T()

VC++里面定义字符串的时候,用_T来保证兼容性。VC++支持asciiunicode两种字符类型,用_T可以保证从ascii编码类型转换到unicode编码类型的时候,程序不需要修改。
_t("hello world")
在ansi的环境下,它是ansi的,如果在unicode下,那么它将自动解释为双字节字符串,既unicode编码。 
这样做的好处,不管是ansi环境,还是unicode环境,都适用。
那么在VC++中,字符串_T("ABC")和一个普通的字符串"ABC"有什么区别呢?

_T("ABC") 
如果定义了unicode,它将表示为L"ABC",每个字符为16位,宽字符串。 
如果没有定义unicode,它就是ascii的"ABC",每个字符为8位。
相当于 
#ifdef _UNICODE 
#define _T("ABC") L"ABC" 
#else 
#define _T("ABC") "ABC" 
#endif
_T("ABC")中的一个字符和汉字一样,占两个字节,而在"ABC"中,英文字符占一个字节,汉字占两个字节。
 在字符串前加一个L作用: 
   如  L"我的字符串"    表示将ANSI字符串转换成unicode的字符串,就是每个字符占用两个字节。
  strlen("asd")   =   3;   
  strlen(L"asd")   =   6;

 

static 类成员

        非 static 数据成员存在于类类型的每个对象中。不像普通的数据成员,static 数据成员独立于该类的任意对象而存在;
每个 static 数据成员是与类关联的对象,并不与该类的对象相关联。
       正如类可以定义共享的 static 数据成员一样,类也可以定义 static 成员函数。static 成员函数没有 this 形参,它可以直接访问所属类的 static 成
员,但不能直接使用非 static 成员。

static成员函数的定义:

 class Account {
     public:
         // interface functions here
         void applyint() { amount += amount * interestRate; }
         static double rate() { return interestRate; }
         static void rate(double); // sets a new rate
     private:
         std::string owner;
         double amount;
         static double interestRate;
         static double initRate();
     };

Account 类有两个名为 rate 的 static 成员函数,其中一个定义在类的内
部。当我们在类的外部定义 static 成员时,无须重复指定 static 保留字,该
保留字只出现在类定义体内部的声明处:
     void Account::rate(double newRate)
     {
         interestRate = newRate;
     }

因为 static 成员不是任何对象的组成部分,所以 static 成员函数不能被
声明为 const。毕竟,将成员函数声明为 const 就是承诺不会修改该函数所属
的对象。 最后, static 成员函数也不能被声明为虚函数。


 

二进制字符串转换为浮点型字符串

 float  f=0.0;
 unsigned char i,*p,fc[]={0x65,0x88,0x76,0x40},fd[33]={0};//float占4个字节
 p=(unsigned char *)&f;
 for (i=0;i<4;i++)
      p[i]=fc[i];
 for (i=0;i<4;i++)
      printf("%x\t",p[i]);
 printf("%f\n",f); 

sprintf((char *)fd,"%.2f",f);//保留到小数点后两位

 

INT类型最大最小值获取

计算机中采用二进制补码存储数据。正数源码、反码、补码不变,负数需要把除符号位以后的部分取反加1
int类型:
二进制原码最大为0111111111111111=215-1=32767
二进制原码最小为1111111111111111=-215-1=-32767

0和负00000000000000000=1000000000000000=0,补码表示中,前者的补码还是0000000000000000,后者经过非符号位取反加1后,同样变成了0000000000000000,也就是正0和负0在补码系统中的编码是一样的。
-1的16位二进制原码:1000000000000001,-1的16位二进制补码:1111111111111111。
因为任何一个原码都不可能在转成补码时变成1000000000000000所以,人为规定1000000000000000这个补码编码为-32768
已知补码求源码,只需将补码再求补码就得到源码:
已知补码:1111 1111 1100 0101
首先最高位为1所以为负数
反码为:1000 0000 0011 1010
原码为:1000 0000 0011 1011=-59

unsigned intGetUnsignedIntMax()

{
    
return   ~ 0 ;
}
 

signed int GetSignedIntMax()
{
    
return ((unsigned int)( ~ 0 )) >>   1) ;//(unsigned int)( ~ 0 ) 为:1111....1111 ;    >>1之后为:0111....1111
}

int int_min = ~(unsigned int(-1) >> 1);

http://blog.csdn.net/gzydulala/article/details/22332087

头文件 <limits.h> 、<float.h>

 

 

inet_addr实现原理

转:http://blog.csdn.net/brk1985/article/details/17032433

输入是点分的IP地址格式(如A.B.C.D)的字符串,从该字符串中提取出每一部分,转换为ULONG,假设得到4个ULONG型的A,B,C,D,
ulAddress(ULONG型)是转换后的结果,
ulAddress = D<<24 + C<<16 + B<<8 + A(网络字节序),即inet_addr(const char *)的返回结果
另外我们也可以得到把该IP转换为主机序的结果,转换方法一样
A<<24 + B<<16 + C<<8 + D 

 

NEW异常捕获

vc6.0不支持new异常抛出,new分配失败直接返回NULL;

构造函数中new异常捕获:

转:http://blog.csdn.net/hywbd/article/details/5338818 

 

 win32下C++线程同步机制

线程的同步可分用户模式的线程同步和内核对象的线程同步两大类。用户模式中线程的同步方法主要有原子访问和临界区等方法。其特点是同步速度特别快,适合于对线程运行速度有严格要求的场合。

内核对象的线程同步则主要由事件等待定时器信号量以及信号灯等内核对象构成。由于这种同步机制使用了内核对象,使用时必须将线程从用户模式切换到内核模式,而这种转换一般要耗费近千个CPU周期,因此同步速度较慢,但在适用性上却要远优于用户模式的线程同步方式。

在WIN32中,同步机制主要有以下几种:
  
(1)事件(Event);
  
(2)信号量(semaphore);
  
(3)互斥量(mutex);
  (4)临界区(Critical section)。

临界区

CRITICAL_SECTION cs;
InitializeCriticalSection( & cs);
// 线程1:
EnterCriticalSection( & cs);
int a = s.a;
int b = s.b;
LeaveCriticalSection( & cs);
// 线程2
EnterCriticalSection( & cs);
s.a ++ ;
s.b -- ;
LeaveCriticalSection( & cs);
// 最后:
DeleteCriticalSection( & cs);

详细介绍 转:http://blog.csdn.net/theplayerwuliang/article/details/6431722

事件
  事件(Event)是WIN32提供的最灵活的线程间同步方式,事件可以处于激发状态(signaled or true)或未激发状态(unsignal or false)。根据状态变迁方式的不同,事件可分为两类:
  (1)手动设置:这种对象只可能用程序手动设置,在需要该事件或者事件发生时,采用SetEvent及ResetEvent来进行设置。
  (2)自动恢复:一旦事件发生并被处理后,自动恢复到没有事件状态,不需要再次设置。
  使用"事件"机制应注意以下事项:
  (1)如果跨进程访问事件,必须对事件命名,在对事件命名的时候,要注意不要与系统命名空间中的其它全局命名对象冲突;
  (2)事件是否要自动恢复;
  (3)事件的初始状态设置。
  由于event对象属于内核对象,故进程B可以调用OpenEvent函数通过对象的名字获得进程A中event对象的句柄,然后将这个句柄用于ResetEvent、SetEvent和WaitForMultipleObjects等函数中。此法可以实现一个进程的线程控制另一进程中线程的运行,例如:
HANDLE hEvent=OpenEvent(EVENT_ALL_ACCESS,true,"MyEvent"); 
ResetEvent(hEvent);

信号量
  信号量是维护0到指定最大值之间的同步对象。信号量状态在其计数大于0时是有信号的,而其计数是0时是无信号的。信号量对象在控制上可以支持有限数量共享资源的访问。

  信号量的特点和用途可用下列几句话定义:
  (1)如果当前资源的数量大于0,则信号量有效;
  (2)如果当前资源数量是0,则信号量无效;
  (3)系统决不允许当前资源的数量为负值;
  (4)当前资源数量决不能大于最大资源数量。

  创建信号量
  HANDLE CreateSemaphore (
   PSECURITY_ATTRIBUTE psa,
   LONG lInitialCount, //开始时可供使用的资源数
   LONG lMaximumCount, //最大资源数
   PCTSTR pszName);
  释放信号量  
    通过调用ReleaseSemaphore函数,线程就能够对信标的当前资源数量进行递增,该函数原型为:
  BOOL WINAPI ReleaseSemaphore(
   HANDLE hSemaphore,
   LONG lReleaseCount, //信号量的当前资源数增加lReleaseCount
   LPLONG lpPreviousCount
   );  

 打开信号量  
  和其他核心对象一样,信号量也可以通过名字跨进程访问,打开信号量的API为:
  HANDLE OpenSemaphore (
   DWORD fdwAccess,
   BOOL bInherithandle,
   PCTSTR pszName
  );

互锁访问
  当必须以原子操作方式来修改单个值时,互锁访问函数是相当有用的。所谓原子访问,是指线程在访问资源时能够确保所有其他线程都不在同一时间内访问相同的资源。

LONG __cdecl InterlockedExchangeAdd(
   _Inout_  LONG volatile * Addend,
   _In_     LONG Value
);

 

常用函数

memcmp()函数

#include <string.h>或#include<memory.h>
int memcmp(const void *buf1, const void *buf2, unsigned int count);
比较内存区域buf1和buf2的前count个字节,该函数是按字节比较。
当buf1<buf2时,返回值<0
当buf1=buf2时,返回值=0
当buf1>buf2时,返回值>0
 
sscanf()函数

 从一个字符串中读进与指定格式相符的数据。
nt sscanf(const char *buffer,const char *format,[argument ]...);
sscanf会从buffer里读进数据,依照format的格式将数据写入到argument里。
成功则返回参数数目,失败则返回-1,

strtok()函数

char *strtok(char s[], const char *delim);
分解字符串为一组字符串。s为要分解的字符串,delim为分隔符字符串。首次调用时,s指向要分解的字符串,之后再次调用要把s设成NULL。
返回从s开头开始的一个个被分割的串。当查找不到delim中的字符时,返回NULL。所有delim中包含的字符都会被滤掉,并将被滤掉的地方设为一处分割的节点。

 

 sprintf()函数

字串格式化命令,主要功能是把格式化的数据写入某个字符串中。
int sprintf( char *buffer, const char *format, [ argument] … );
bufferchar型指针,指向将要写入的字符串的缓冲区。  format:格式化字符串。    [argument]...:可选参数,可以是任何类型的数据。
返回值:字符串长度(strlen

 

strstr()函数

strstr(*str1, *str2)实现从 字符串str1中查找是否有字符串str2,如果有,从str1中的str2位置起,返回str1中str2起始位置的 指针,如果没有,返回null。

 

 内存管理:

转:http://blog.csdn.net/HITXuQin/article/details/12573535

 

 

C++结构体成员初始化:

C++结构体类似于类,拥有构造函数,所以结构体成员赋初值直接在构造函数中进行; 

typedef struct SMySelf

{
    int iLength;

    BYTE byCount;   

    DWORD dwWide;   

    WORD     wLength;//word(unsigned short)

    bool         bIsTrue;

    long         lHeight;

    short        nLength;

    long         *lpLong;

    unsigned  int    uLength;

    unsigned  long  ulLength;

    char         cStr;

 
 SMySelf()
 {
    byCount = 0;

    dwWide= 0;

    wLength = 0;

    bIsTrue= false;

    lHeight = 0;

    nLength = 0;

    lpLong = null;

    uLength = 0;

    ulLength = 0;

 }
 
}SSMY_SELY;

 


标签:

VC6.0编译时警告:LINK : warning LNK4089: all references to "ole32.dll" discarded by /OPT:REF

解决方法:project->setting->link 选项卡 ,在Object/library  modules框中添加ws2_32.lib

 

 

 

 

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值