:: 首页 :: 新随笔 :: 联系 :: 聚合  :: 管理


C++操作符的优先级

操作符及其结合性

功能

用法

L
L
L
::
::
::
全局作用域
类作用域
名字空间作用域
::name
class::name
namespace::name
L
L
L
L
L
.
->
[]
()
()
成员选择
成员选择
下标
函数调用
类型构造
object.member
pointer->member
variable[expr]
name(expr_list)
type(expr_list)
R
R
R
R
R
++
--
typeid
typeid
显示强制类型转换
后自增操作
后自减操作
类型ID
运行时类型ID
类型转换
lvalue++
lvalue--
typeid(type)
typeid(expr)
cast_name<type>(expr)
R
R
R
R
R
R
R
R
R
R
R
R
R
R
sizeof
sizeof
++
--
~
!
-
+
*
&
()
new
delete
delete[]
对象的大小
类型的大小
前自增操作
前自减操作
位求反
逻辑非
一元负号
一元正号
解引用
取地址
类型转换
创建对象
释放对象
释放数组
sizeof expr
sizeof(type)
++lvalue
--lvalue
~expr
!expr
-expr
+expr
*expr
&expr
(type)expr
new type
delete expr
delete []expr
L
L
->*
.*
指向成员操作的指针
指向成员操作的指针
ptr->*ptr_to_member
obj.*ptr_to_member
L
L
L
*
/
%
乘法
除法
求模(求余)
expr * expr
expr / expr
expr % expr
L
L
+
-
加法
减法
expr + expr
expr - expr
L
L
<<
>>
位左移
位右移
expr << expr
expr >> expr
L
L
L
L
<
<=
>
>=
小于
小于或等于
大于
大于或等于
expr < expr
expr <= expr
expr > expr
expr >= expr
L
R
==
!=
相等
不等
Expr == expr
Expr != expr
R & 位与 Expr & expr
R ^ 位异或 Expr ^ expr
R | 位或 Expr | expr
R && 逻辑与 Expr && expr
R || 逻辑或 Expr || expr
R ?: 条件操作 Expr ? expr : expr
R
R
R
R
R
=
*=,/=,%=
+=,-=
<<=,>>=
&=,|=,^=
赋值操作
符合赋值操作

Lvalue= expr
Lvalue+= expr
……

R throw 抛出异常 Throw expr
L , 逗号 Expr, expr
记忆方法:
--摘自《C语言程序设计实用问答》     -吕凤翥     吕     涛著   
    问题:如何记住运算符的15种优先级和结合性?   
    解答:C语言中运算符种类比较繁多,优先级有15种,结合性有两种。   
    如何记忆两种结合性和15种优先级?下面讲述一种记忆方法。   
    结合性有两种,一种是自左至右,另一种是自右至左,大部分运算符的结合性是自左至右,只有单目运算符、三目运算符的赋值运算符的结合性自右至左。   
    优先级有15种。记忆方法如下:   
    记住一个最高的:构造类型的元素或成员以及小括号。   
    记住一个最低的:逗号运算符。   
    剩余的是一、二、三、赋值。   
    意思是单目、双目、三目和赋值运算符。   
    在诸多运算符中,又分为:   
    算术、关系、逻辑。   
    两种位操作运算符中,移位运算符在算术运算符后边,逻辑位运算符在逻辑运算符的前面。再细分如下:   
    算术运算符分     *,/,%高于+,-。   
    关系运算符中,》,》=,《,〈=高于==,!=。   
    逻辑运算符中,除了逻辑求反(!)是单目外,逻辑与(&&)高于逻辑或(||)。   
    逻辑位运算符中,除了逻辑按位求反(~)外,按位与(&)高于按位半加(^),高于按位或(|)。   
    这样就将15种优先级都记住了,再将记忆方法总结如下:   
    去掉一个最高的,去掉一个最低的,剩下的是一、二、三、赋值。双目运算符中,顺序为算术、关系和逻辑,移位和逻辑位插入其中。 

posted @ 2011-08-06 22:18 托雷宽 阅读(221) | 评论 (0)编辑 收藏

如果你的工作长期与某个领域相关,比如说长期做直接体绘制(DVR)方面的开发,那么你可能经常使用自己的传递函数类,如果每一个工程你都把传递函数类的.h和.cpp文

件添加进去会比较麻烦,其实,我们可以像使用opengl的库那样来用你自己的类,做法就是把你写好的类封装成dll,具体做法如下: 

第一步:制作dll

     利用VC6新建工程时选择win32 dynamic-Link Library(空的工程),然后添加头文件和cpp文件。假设你要封装的类的名成是TransferFunction,添加头文件

TransferFunction.h和TransferFunction.cpp到工程中。并将TransferFunction.h修改成: 

class __declspec(dllexport) TransferFunction
{
      ...

}

从而说明以后从dll要被导出的类是哪一个。这样编译完就会产生TransferFunction.dll和TransferFunction.lib两个文件。

第二步:如何使用这个dll

      当已经生成dll后,有两种方法可以在其它程序中调用dll中的类和成员函数:

方法一:

      1)把TransferFunction.dll和TransferFunction.lib复制到调用程序的执行路径下,注意不是debug路径下。

      2)在project->setting->link里添加TransferFunction.lib(或者用#pragma comment(lib, "TransferFunction.lib") )

      3)把TransferFunction.h中的__declspec(dllexport)改成__declspec(dllimport)

然后复制到调用程序的执行路径下。

      4)最后在主程序中就可以通过包含TransferFunction.h来使用TransferFunction类和它的成员函数。 
方法二(推荐):
       在方法一中,你每次建立一个工程都需要把 TransferFunction.dll,TransferFunction.lib,TransferFunction.h三个文件拷贝到工程里面 去,事实上这只发挥了dll对类的代码保护的功能,并没有多大的减轻编程人员的工作量,下面的方法可以减少编程人员的工作量,具体步骤:
1:将TransferFunction.dll扔到windows/system32下
2:将.TransferFunctionlib扔到VC的lib目录里
3:将方法一中的TransferFunction.h扔到VC的include目录里
4:同方法一的最后一步。
         以后你就可以像使用Opengl的glut、glui等库一样使用你自己封装的一个经常复用的类了。

posted @ 2011-08-06 22:17 托雷宽 阅读(1394) | 评论 (0)编辑 收藏

vs2010打开某个工程 ,转换成功之后,在工程目录看见一个sdf文件和一个ipch文件夹,都超大(起码几十M),我一个四百多k 的工程,结果用vs打开过后变成了两百多兆。

这个详细点的解释

大家也许发现了,visual studio 2010 中新建一个项目会同时建立一个ipch目录与sdf文件,即使你删掉它,再次打开工程时还是会重新建立。动辄30、50M的容量让我们心里很不爽。其实这 是2010的一个新功能,与智能提示,错误提示,代码恢复、团队本地仓库等等息息相关的东西。如果大家觉得很不爽可以关掉它。Tools —— Options —— Text Editor —— C/C++ —— Advanced ——Disable Database 设置为True,默认为false。这样,你关闭visual后删掉工程目录下的ipch与sdf就不会再产生了

但是这样的办法会产生另外的一些问题,可能会导致其他的一些功能不能使用。

另外一种解决方法是:

Tools->Options->Text Editor->C/C++->Advanced,在 Fallback Location 的属性组中,将"Always Use Fallback Location"设置为 true,将"Do Not Warn If Fallback Location Used" 设置为 true ,然后删除解决方案目录下的 sdf 文件和 ipch 目录,再次打开解决方案,发现这些烦人的东西已经不见了。

那么那些文件放置到那里了呢?看 "Fallback Location" 属性说明:这是存储浏览信息数据库和 IntelliSense 文件的第二个位置,如果不指定则放置到临时目录中;到临时目录一看,里面有一个 VC++ 的目录,都在那个目录里面呢。

可以在 "Fallback Location" 属性中,设置一个固定的路径来存储这些文件,比如D:\VS2010Temp,这样也比较好管理这些庞大的臃肿的文件,可以定期清理掉它们,释放出硬盘空间!

posted @ 2011-07-06 10:01 托雷宽 阅读(3717) | 评论 (0)编辑 收藏

1.1使用系统提供的OnTimerSet函数
Timer(m_hWnd,1,1000,NULL); //一个1秒触发一次的定时器
在MFC程序中SetTimer被封装在CWnd类中,调用就不用指定窗口句柄了

于是SetTimer函数的原型变为:

UINT SetTimer(UINT nIDEvent,UINT nElapse,void(CALLBACK EXPORT *lpfnTimer)(HWND,UINT ,YINT ,DWORD))

当使用SetTimer函数的时候,就会生成一个计时器。函数中nIDEvent指的是计 时器的标识,也就是名字。nElapse指的是时间间隔,也就是每隔多长时间触发一次事件。第三个参数是一个回调函数,在这个函数里,放入你想要做的事情 的代码,你可以将它设定为NULL,也就是使用系统默认的回调函数,系统默认认的是onTime函数。这个函数怎么生成的呢?你需要在需要计时器的类的生 成onTime函数:在ClassWizard里,选择需要计时器的类,添加WM_TIME消息映射,就自动生成onTime函数了。然后在函数里添加代 码,让代码实现功能。每隔一段时间就会自动执行一次。

例:

SetTimer(1,1000,NULL);

1:计时器的名称;

1000:时间间隔,单位是毫秒;

NULL:使用onTime函数。

当不需要计时器的时候调用KillTimer(nIDEvent);

例如:KillTimer(1);

1.2 调用回调函数

此方法首先写一个如下格式的回调函数

void CALLBACK TimerProc(HWND hWnd,UINT nMsg,UINT nTimerid,DWORD dwTime);
然后再用SetTimer(1,100,TimerProc)函数来建一个定时器,第三个参数就是回调函数地址。

二. 或许你会问,如果我要加入两个或者两个以上的 timer怎么办?

继续用SetTimer函数吧,上次的timer的ID是1,这次可以是2,3,4。。。。

SetTimer(2,1000,NULL);

SetTimer(3,500,NULL);

嗯,WINDOWS会协调他们的。当然onTimer函数体也要发生变化,要在函数体内添加每一个timer的处理代码:

onTimer(nIDEvent)

{

switch(nIDEvent)

{

case 1:........;

break;

case 2:.......;

break;

case 3:......;

break;

}

}

posted @ 2011-07-06 09:49 托雷宽 阅读(1194) | 评论 (0)编辑 收藏

1:图形绘制可使用easyX提供的graphics.h头文件

posted @ 2011-07-05 04:19 托雷宽 阅读(160) | 评论 (0)编辑 收藏

1.BOOL C***Dlg::OnInitDialog()

{

    //禁止关闭对话框
 CMenu* pMenu = this->GetSystemMenu(FALSE);
 pMenu->ModifyMenu(SC_CLOSE,MF_BYCOMMAND | MF_GRAYED );
    //禁止在任务管理器中关闭进程
 SetTimer(1,m_nTimer,NULL);//设置1号定时器,循环调用stopKillProcess()函数,禁止任务管理器中关闭进程

}

 

2.void CClientTracerDlg::stopKillProcess()//禁止任务管理器中关闭进程
{
 HWND hwnd;
 int  iItem=0;
 LVITEM lvitem, *plvitem;
 char ItemBuf[512],*pItem;
 DWORD PID;
 HANDLE hProcess;
 
 // 查找任务管理器ListView窗口句柄
 hwnd=::FindWindow("#32770",_T("Windows 任务管理器"));
 hwnd=::FindWindowEx(hwnd,0,"#32770",0);
 hwnd=::FindWindowEx(hwnd,0,"SysListView32",0);
 
 // Windows任务管理器尚未启动则返回
 if (!hwnd) 
  return;
 else
 {
  // 没有指定目标进程则返回
  iItem=::SendMessage(hwnd,LVM_GETNEXTITEM,-1,LVNI_SELECTED);
  if (iItem==-1) 
   return;
  else
  {
   // 获取进程句柄操作失败则返回
   GetWindowThreadProcessId(hwnd, &PID);
   hProcess=OpenProcess(PROCESS_ALL_ACCESS,false,PID);
   if (!hProcess)
    return;   
   else
   {
    plvitem=(LVITEM*)VirtualAllocEx(hProcess, NULL, sizeof(LVITEM), MEM_COMMIT, PAGE_READWRITE);
    pItem=(char*)VirtualAllocEx(hProcess, NULL, 512, MEM_COMMIT, PAGE_READWRITE);
    
    // 无法分配内存则返回
    if ((!plvitem)||(!pItem))
     return;    
    else
    {
     lvitem.cchTextMax=512;
     lvitem.iSubItem=0;  //ProcessName
     lvitem.pszText=pItem;
     WriteProcessMemory(hProcess, plvitem, &lvitem, sizeof(LVITEM), NULL);
     ::SendMessage(hwnd, LVM_GETITEMTEXT, (WPARAM)iItem, (LPARAM)plvitem);
     ReadProcessMemory(hProcess, pItem, ItemBuf, 512, NULL);
     
     // 比较字符串,匹配进程映像名
     CString str = (CString)ItemBuf;
     if(str.CompareNoCase(_T("ClientTracer.exe")) == 0)
     {
      HWND hWnd=::FindWindow(NULL,_T("Windows 任务管理器"));
      ::SendMessage(hWnd,WM_DESTROY,0,0);
      Sleep(100);
      ::MessageBox(NULL,_T("禁止关闭系统关键进程!"),_T("提示"),MB_ICONERROR | MB_OK);
     }
    }
   }
  }
 }
 
 //释放内存
 CloseHandle(hwnd);
 CloseHandle(hProcess);
 VirtualFreeEx(hProcess, plvitem, 0, MEM_RELEASE);
 VirtualFreeEx(hProcess, pItem, 0, MEM_RELEASE);
}

3.定时器设置调用stopKillProcess(),也可以多线程调用stopKillProcess()

void C***Dlg::OnTimer(UINT nIDEvent)
{
 // TODO: Add your message handler code here and/or call default
 if(nIDEvent == 1)
 {
  stopKillProcess();
 }
 CDialog::OnTimer(nIDEvent);
}

posted @ 2011-07-04 22:19 托雷宽 阅读(1472) | 评论 (1)编辑 收藏

使用CreateProcess函数时,有一组参照代码如下
PROCESS_INFORMATION pi;
    STARTUPINFO si={sizeof(si)};
    DWORD dwExitCode;
    BOOL fsuccess=CreateProcess(_T("C:\\Users\\Administrator\\Desktop\\explorer\\Debug\\explorer.exe"),NULL,NULL,NULL,FALSE,0,NULL,NULL,&si,&pi);
    if (fsuccess)
    {
        CloseHandle(pi.hThread);
        CloseHandle(pi.hProcess);
     }
si参数必须制定,在创建进程时需要是使用这个结构体的成员  
   

posted @ 2011-07-04 09:08 托雷宽 阅读(226) | 评论 (0)编辑 收藏

::SendMessage( HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam );
参数1:目的窗口的句柄
参数2:系定义消息类型
参数3:消息参数
参数4:消息参数
在接受该消息的窗口函数中添加消息处理函数即可

posted @ 2011-07-03 19:23 托雷宽 阅读(245) | 评论 (0)编辑 收藏

#include <iostream>
#include <fstream>
#include <afx.h>
using namespace std;

int main()
{
    char path_buffer[_MAX_PATH];
    char drive[_MAX_DRIVE];
    char dir[_MAX_DIR];
    char fname[_MAX_FNAME];
    char ext[_MAX_EXT];
    GetModuleFileName(NULL,path_buffer,MAX_PATH);//得到当前路径
    _splitpath( path_buffer, drive, dir, fname, ext );//拆分当前路径
    cout<<path_buffer<<endl;
    CString cStr,temp;
    temp.Format("%s",drive);
    cStr+=temp;
    temp.Empty();
    temp.Format("%s",dir);
    cStr+=temp;
    temp.Empty();
    temp.Format("%s","\\aa.jpg");//将路径拼接成想要的文件路径
    cStr.Delete(cStr.GetLength()-1,1);//去掉不包含文件名的路径的最后一个\,否则编译器会误会有转义字符
    cStr+=temp;
    temp.Empty();
    cStr.Replace("\\","\\\\");
    cStr.TrimRight();
    //cout<<cStr<<endl;
    const char* filename =cStr.GetBuffer(sizeof(cStr));//将路径赋值给一个const char* 的常量
    //cout<<filename<<endl;
    ifstream ifile(filename,iostream::binary);//使用
    ofstream ofile("D:\\aa.jpg",iostream::binary);
    try
    {
        if (ifile==NULL)
        {
            throw -1;
        }
        ofile<<(ifile.rdbuf());
    }
    catch (int e)
    {
        cout<<"error"<<endl;
    }
    ifile.close();
    ofile.close();
    system("pause");
     return 0;
}

posted @ 2011-07-01 09:55 托雷宽 阅读(4312) | 评论 (0)编辑 收藏

CString的GetBuffer:它的作用是返回一个可写的缓冲指针。
example:
CString s(_T("File.ext"));   LPTSTR p = s.GetBuffer();
CString的ReleaseBuffer:
不给它传递参数,它使用默认值 0,意思是:"给我这个字符串的指针,我保证不加长它"。
当调用 ReleaseBuffer 时,字符串的实际长度会被重新计算,然后存入 CString 对象中。

posted @ 2011-06-30 23:53 托雷宽 阅读(195) | 评论 (0)编辑 收藏

仅列出标题
共3页: 1 2 3