??xml version="1.0" encoding="utf-8" standalone="yes"?>久久婷婷国产剧情内射白浆,日韩AV无码久久一区二区,国内精品伊人久久久久妇 http://www.shnenglu.com/cc/半亩方塘 天光云媄 zh-cn Wed, 07 May 2025 01:01:50 GMT Wed, 07 May 2025 01:01:50 GMT 60 在windows环境中配|go语言开发环?/title> http://www.shnenglu.com/cc/archive/2013/02/07/197762.html北风之神007 北风之神007 Thu, 07 Feb 2013 02:13:00 GMT http://www.shnenglu.com/cc/archive/2013/02/07/197762.html http://www.shnenglu.com/cc/comments/197762.html http://www.shnenglu.com/cc/archive/2013/02/07/197762.html#Feedback 1 http://www.shnenglu.com/cc/comments/commentRss/197762.html http://www.shnenglu.com/cc/services/trackbacks/197762.html 参?/span>http://www.cnblogs.com/MikeZhang/archive/2012/02/10/nppRunGo.html
最q?/span>google ?/span>go 语言行E度来大了,学着别h写的内容自己?/span>windows 下搭Z一个简单的开发环境,记录在这里,如果需要参考的可以借鉴?/span>
一?span style="font-weight: normal; font-size: 7pt; line-height: normal; font-family: 'Times New Roman';"> 下蝲~译?/span>
下蝲 go语言的开发工具可以到 http://code.google.com/p/gomingw/downloads/list M载,q里列出了当前最新的版本?/span>
我选择下蝲 http://gomingw.googlecode.com/files/gowin386_release.r60.3.zip
下蝲完毕之后Q就是一个压~包Q我们把它解压羃Q最l解压羃后的目录?/span>go 命名?/span>
二?span style="font-weight: normal; font-size: 7pt; line-height: normal; font-family: 'Times New Roman';"> 配置环境变量
~译工具下蝲之后解压~,是一个目录,后期我们需要在命o行或者工具中调用~译E序Q所以需要把~译工具的\径以及相兛_性配|进pȝ环境变量?/span>
需要设定的环境变量如下Q?/span>
1. set goroot = go ~译E序ȝ录全路径
2. set goarch = 386
3. set path = %goroot% /bin
4. set goos = windows
其中 go 目录全\径是我们前面解压~后的以 go 命名的目录,我们q里假设?/span>c:\go
1 、在 xp 环境下:
在桌?strong>我的电脑 右键Q查看属性,弹出pȝ属性对话框Q如下:
新徏环境变量Q?/span>
?/span>vista ?/span>win 环境下:
在桌?strong>计算?/span>右键Q查看属性,打开pȝ信息H口Q再点击“高pȝ讄”Q弹出系l属性对话框Q对话框?/span>XP cMQ具体设|参?/span>XP pȝ讄部分?/span>
三?span style="font-weight: normal; font-size: 7pt; line-height: normal; font-family: 'Times New Roman';"> 配置开发工?/span>
开发工P我这里推荐两张,一U是 Notepad++ Q一U是集成开发环?/span>LiteIDE ?/span>
1Q?/span>Notepad++
Notepad++ 的主ؓ http://notepad-plus-plus.org/ Q大家可以上去自׃最新的版本?/span>
E序的安装与普通程序没有区别,安装完毕之后可以打开 notepad++ ?/span>
默认情况下, notepad 是不?/span>go 语言的代码解释器的,也不带便L译功能。所以我们需要下载安?/span>go 语言的代码解释器Qƈq行适当配置?/span>
操作步骤如下Q?/span>
Q?/span>1 Q下载语a解析模板
go 语言解析模板Q?/span>http://notepad-plus.sourceforge.net/commun/userDefinedLang/go.zip
下蝲之后Q解压羃Q里面有“ go.xml ”Q?#8220; userDefineLang_Go.xml ”Q?#8220; README ”三个文gQ我们重点关注前面两个文件?/span>
Q?/span>2 Q将文g userDefineLang_Go.xml 内容 copy ?/span>Application Data ?/span>Notepad++ 目录?/span>userDefineLang.xml 中,如果没有该文Ӟ则直?/span>userDefineLang_Go.xml 文g名改?/span>userDefineLang.xml 复制q去?/span> XP: C:\Documents and Settings\[username] \Application Data\Notepad++ Vista/Win7 : C:\Users\[username] \AppData\Roaming\Notepad++
拯q去之后Q打开 userDefineLang.xml 文gQ把文g前面与最后的“ <!-- <NotepadPlus> --> ”?#8220; <!-- </NotepadPlus> --> ”分别Ҏ“ <NotepadPlus> ”?#8220; </NotepadPlus> ” , 改完保存之后
Q?/span>3 Q将 go.xml 文g copy ?/span>notepad++ 安装目录下的 plugins\APIs 目录Q例如: D:\Program Files\Notepad++\plugins\APIs Q;
Q?/span>4 Q重?/span>notepad++ E序Q在语言菜单下可以看?/span>go ?/span>
Q?/span>5 Q设定快L译命令?/span>
打开 Notepad++ E序之后Q运?/span>F5 命o
在弹出的对话框中输入以下内容Q?#8220; cmd /k 8g.exe -o tmp.8 "$(FULL_CURRENT_PATH)" & 8l.exe -o tmp.exe tmp.8 & del tmp.8 & tmp.exe & PAUSE & del tmp.exe & EXIT ”?/span> 保存?/span>"Run Go" Qƈ讄 Ctrl+F6 为快捷键?/span>
Q?/span>6 Q测试编?/span>
我们使用 notepad++ 新徏一?/span>hello.go 文gQ在其中输入以下代码?/span>
package main import "fmt" func main() { fmt.Println("Hello World Q?/span>") }
再按“ Ctrl+F6 ”快捷键?/span>
弹出H口昄 Q证明环境配|完毕?/span>
我们也可以在 dos 命oH口中执行编译运行命令?/span>
~译Q?/span>8g -o hello.8 hello.go 链接Q?/span>8l -o hello.exe hello.8 q行Q?/span>hello.exe
2Q?/span>LiteIDE
LiteIDE ?/span>go 语言开发一个集成环境,可以?/span>
http://code.google.com/p/golangide/downloads/list L看最新版本?/span>
我们q里下蝲 LiteIDE12.2_windows版本 ?/span>
q个工具的配|在下蝲处有文档说明Q这里就不详l介l了?/span>
希望写的内容对大家有帮助?/span>
]]> QtE序Release模式~译 http://www.shnenglu.com/cc/archive/2012/11/12/195075.html北风之神007 北风之神007 Mon, 12 Nov 2012 06:01:00 GMT http://www.shnenglu.com/cc/archive/2012/11/12/195075.html http://www.shnenglu.com/cc/comments/195075.html http://www.shnenglu.com/cc/archive/2012/11/12/195075.html#Feedback 0 http://www.shnenglu.com/cc/comments/commentRss/195075.html http://www.shnenglu.com/cc/services/trackbacks/195075.html 在Linux下用Qt开发了一些界面的E序Q编译出来结果比较大Q有的都上百兆,查了之后才知道编译出来的E序不是release模式的,我们需要在pro文g中增加编译指令,用release模式~译Q效率方面没有做试Q不q程序体U只是之前的十分之一Q正怺很多?br /> 其实我们要做的不多,只要在pro文g中增加以下的选项卛_Q这样就可以release模式~译了?br />CONFIG+= release
]]> 使用jpeglib库实现bmp转jpg (? http://www.shnenglu.com/cc/archive/2012/02/22/166217.html北风之神007 北风之神007 Wed, 22 Feb 2012 03:04:00 GMT http://www.shnenglu.com/cc/archive/2012/02/22/166217.html http://www.shnenglu.com/cc/comments/166217.html http://www.shnenglu.com/cc/archive/2012/02/22/166217.html#Feedback 0 http://www.shnenglu.com/cc/comments/commentRss/166217.html http://www.shnenglu.com/cc/services/trackbacks/166217.html 一?/span>vc ~译jpeglib?/h1> 1 、下载源代码 下蝲地址Q?/span>http://www.ijg.org/。注意:一定要下蝲 win32 版本
2 、编译源代码 . A、解压源代码Q修Ҏ代码?/span>jconfig.vc?/span>jconfig.hQ?/span>
B、添加环境变?/span>PATHQ?/span>C:/Program Files/Microsoft Visual Studio/VC98/Bin Q?/span>
C、修?/span>makefile.vcQ将 Pull in standard variable definitions下面的一行换为: !include <C:/Program Files/Microsoft Visual Studio/VC98/Include/win32.mak> Q?/span>
D、进入命令提C环境下Q输入: vcvars32 回RQ这是一个用来设|?/span>VC路径环境的批处理Q?/span>
E、编译生成库文g 命oQ?/span>nmake /f makefile.vc nodebug=1Q?/span>
q样?/span>OK?/span>
3 ?/span>jpeglib ?/span>VC 下?/span> 对于库的使用只需要有相应?/span>.lib文g和头文g可以了?/span>Vc中要d libjpeg.lib库的q接
这几个文g拯C的项目中Q?/span>libjpeg.libQ?/span>jconfig.hQ?/span>jmorecfg.hQ?/span>jpeglib.hQ在你需要进行压~的文g中加?/span>
extern "C" {
#include "jpeglib.h"
#include "jmorecfg.h"
#include "jconfig.h"
}
参考:
http://blog.csdn.net/xingyu19871124/archive/2009/06/30/4310800.aspx
知识: bmp文g的前 54个字节是_后面才是像素倹{?/span>
二、用jpeg 库压~?/span> 在源代码的文件夹下面有一?/span>example.c的文件和 libjpeg.txtQ很有参考h倹{?/span>
1 、基本思\ 首先调用截屏E序Q将屏幕的位图信息存攑֜一?/span>buffer里面Q然后调?/span>jpg压羃函数Q在当前的目录下生成一?/span>ok.jpg的文件?/span>
2 、出现的问题Q?/h2> A、运行是L报错Q?/span>
我参考源代码的例子,也用 JSAMPLE * image_buffer;来指向位囄像素的首地址Q编译可以通过但是q行时就会报错,后来我用 BYTE *image_buffer;来定义就可以正常q行了?/span>
B、生成的 jpg囑փqQ?/span>
׃ window的位囄像素格式是: BGRAQ?/span>4个字节, jpeglib库用的?/span>RGBQ?/span>3个字节的格式Q所以需要将源像素去掉其透明字节Q同时改?/span>RGB的顺序。代码如下:
//RGB序调整
for (int i=0, int j=0; j < 1440*900*4; i+=3, j+=4)
{
*(image_buffer+i)=*(image_buffer+j+2);
*(image_buffer+i+1)=*(image_buffer+j+1);
*(image_buffer+i+2)=*(image_buffer+j);
}
C、生成的 jpg文g囑փ是倒的Q?/span>
原因没有扑ֈQ后来修改了压羃函数的代码,生成了正的 jpg文g
while (cinfo.next_scanline < cinfo.image_height) {
//q里我做q修改,׃ jpg文g的图像是倒的Q所以改了一下读的顺?/span>
//q是原代码: row_pointer[0] = & bits[cinfo.next_scanline * row_stride];
row_pointer[0] = & bits[(cinfo.image_height - cinfo.next_scanline - 1) * row_stride];
(void) jpeg_write_scanlines(&cinfo, row_pointer, 1);
}
3 、测试结果: 我编写了试代码Q连l截屏ƈ生成 jpg文g 100ơ,大约p 7U左叻I也就是说 1U可以截?/span>13ơ左叟뀂同时生成的 jpg文g?/span>100?/span>K的样子?/span>
三、代码:
#include "stdafx.h" #include <atlbase.h> #include <afxwin.h> #include <WINDOWSX.H> #define JPEG_QUALITY 50 // 它的大小军_jpg的质量好?/span> extern "C" { #include "jpeglib.h" #include "jmorecfg.h" #include "jconfig.h" } int savejpeg(char *filename, unsigned char *bits, int width, int height, int depth);void CapScreen(char filename[]); BYTE *image_buffer; // 指向位图buffer的全局指针Qwindow下像素格? BGRA(4个字? int main(int argc, char * argv[]) { image_buffer = (BYTE *)malloc(1440 * 900 * 4); for (int i = 0; i < 100; i++){ CapScreen("ok.bmp"); // RGB序调整 for (int i=0, int j=0; j < 1440*900*4; i+=3, j+=4) { *(image_buffer+i)=*(image_buffer+j+2); *(image_buffer+i+1)=*(image_buffer+j+1); *(image_buffer+i+2)=*(image_buffer+j); } savejpeg("ok.jpg", image_buffer, 1440, 900, 3); } delete [] image_buffer; return 0; } /* =================================================================================== function: jpeg压羃 input: 1:生成的文件名,2:bmp的指?3:位图宽度,4:位图高度,5:颜色深度 return: int description: bmp的像素格式ؓ(RGB) =================================================================================== */ int savejpeg(char *filename, unsigned char *bits, int width, int height, int depth) { struct jpeg_compress_struct cinfo; struct jpeg_error_mgr jerr; FILE * outfile; /* target file */ JSAMPROW row_pointer[1]; /* pointer to JSAMPLE row[s] */ int row_stride; /* physical row width in image buffer */ cinfo.err = jpeg_std_error(&jerr); jpeg_create_compress(&cinfo); if ((outfile = fopen(filename, "wb")) == NULL) { fprintf(stderr, "can't open %s/n", filename); return -1; } jpeg_stdio_dest(&cinfo, outfile); cinfo.image_width = width; /* image width and height, in pixels */ cinfo.image_height = height; cinfo.input_components = 3; /* # of color components per pixel */ cinfo.in_color_space = JCS_RGB; /* colorspace of input image */ jpeg_set_defaults(&cinfo); jpeg_set_quality(&cinfo, JPEG_QUALITY, TRUE /* limit to baseline-JPEG values */ ); jpeg_start_compress(&cinfo, TRUE); row_stride = width * depth; /* JSAMPLEs per row in image_buffer */ while (cinfo.next_scanline < cinfo.image_height) { // q里我做q修改,׃jpg文g的图像是倒的Q所以改了一下读的顺?br /> // q是原代码:row_pointer[0] = & bits[cinfo.next_scanline * row_stride]; row_pointer[0] = & bits[(cinfo.image_height - cinfo.next_scanline - 1) * row_stride]; (void ) jpeg_write_scanlines(&cinfo, row_pointer, 1); } jpeg_finish_compress(&cinfo); fclose(outfile); jpeg_destroy_compress(&cinfo); return 0; } void CapScreen(char filename[]) { CDC *pDC; pDC = CDC::FromHandle(GetDC(GetDesktopWindow())); if (pDC == NULL) return ; int BitPerPixel = pDC->GetDeviceCaps(BITSPIXEL); int Width = pDC->GetDeviceCaps(HORZRES); int Height = pDC->GetDeviceCaps(VERTRES); CDC memDC; if (memDC.CreateCompatibleDC(pDC) == 0) return ; CBitmap memBitmap, *oldmemBitmap; if (memBitmap.CreateCompatibleBitmap(pDC, Width, Height) == NULL) return ; oldmemBitmap = memDC.SelectObject(&memBitmap); if (oldmemBitmap == NULL) return ; if (memDC.BitBlt(0, 0, Width, Height, pDC, 0, 0, SRCCOPY) == 0) return ; BITMAP bmp; memBitmap.GetBitmap(&bmp); // fp = fopen(filename, "w+b"); BITMAPINFOHEADER bih = {0}; bih.biBitCount = bmp.bmBitsPixel; bih.biCompression = BI_RGB; bih.biHeight = bmp.bmHeight; bih.biPlanes = 1; bih.biSize = sizeof (BITMAPINFOHEADER); bih.biSizeImage = bmp.bmWidthBytes * bmp.bmHeight; bih.biWidth = bmp.bmWidth; BITMAPFILEHEADER bfh = {0}; bfh.bfOffBits = sizeof (BITMAPFILEHEADER) + sizeof (BITMAPINFOHEADER); bfh.bfSize = bfh.bfOffBits + bmp.bmWidthBytes * bmp.bmHeight; bfh.bfType = (WORD)0x4d42; // fwrite(&bfh, 1, sizeof(BITMAPFILEHEADER), fp); // fwrite(&bih, 1, sizeof(BITMAPINFOHEADER), fp); image_buffer = new BYTE[bmp.bmWidthBytes * bmp.bmHeight]; GetDIBits(memDC.m_hDC, (HBITMAP) memBitmap.m_hObject, 0, Height, image_buffer, (LPBITMAPINFO) &bih, DIB_RGB_COLORS); memDC.SelectObject(oldmemBitmap); // fwrite(p, 1, 1280 * 800 * 4, fp); // fclose(fp); }
]]>VC6.0下的GDI+配置(? http://www.shnenglu.com/cc/archive/2012/02/21/166167.html北风之神007 北风之神007 Tue, 21 Feb 2012 12:23:00 GMT http://www.shnenglu.com/cc/archive/2012/02/21/166167.html http://www.shnenglu.com/cc/comments/166167.html http://www.shnenglu.com/cc/archive/2012/02/21/166167.html#Feedback 0 http://www.shnenglu.com/cc/comments/commentRss/166167.html http://www.shnenglu.com/cc/services/trackbacks/166167.html GDI Plus 描述Q?/strong>
GDIPlus是微软出的一个C++面向对象库,它ؓwindows的图形设备接口提供了更好的访问。与标准的windows GDI相比Q二l绘囑֒囄使用得到很大改进。用GDIPlus你可以绘制定制的对象Q打开各种囄q以各种格式存储它们Q用多U字体和文本l制轨迹 和各U调色板功能?/span>
GDI Plus兼容性:
GDIPlus最初是为MS Visual Studio 7开发的Q但是因个品的发布推迟了,所以微软就为Visual Studio 6发行了这个库的版本。如果你使用Visual Studio 6Q可以从q里下蝲MFC GDI Plus库文件?/span>http://www.codersource.net/samples/mfcgdiplus.zip
aQVisual Studio 7或者更新版本用这个类库,只需要在你的工程里面包含<gdiplus.h>
bQ早期版本的MSVS要用这个类库,需要将下蝲的zip文g解压C个文件夹Q设其\径ؓyour_pathQ然后将目录your_path\ gdiplus\includes加入到开发环境的包含路径中(Tools->Options->Directories-> Include filesQ,然后在你的工E中你必d含文?lt;gdiplus>Q但是在那之前你必须定义define ULONG_PTRQ这是GDIPlus中的一个定义,在老版本的VS中没有定义过Q。也是_在StdAfx.h中你需要添加如下代码:
#define ULONG_PTR ULONG include <gdiplus.h>
然后目录your_path\gdiplus\lib包含C的工E(Tools->Options->Directories->Library filesQ,以它们可以链接C的程序?/span>
【efivol补充Q还必须在StdAfx.h?include <gdiplus.h>之后加入q两句,不然有错?/span>
using namespace Gdiplus; #pragma comment(lib, "gdiplus.lib")
补充完毕?/span>在编译完你的工程之后Q将your_path\gdiplus\gdiplus.dll拯到生成的执行文g所在的文g夹(\Debug或者\ReleaseQ?/span>
使用GDI PluscdQ?/strong>
要用GDI PluscdQ你必须首先初始化类库。初始化是一个调用两个参数的函数Q这两个参数是必d整个GDIPlus会话中都存在的变量。在使用完GDIPlus之后Q必调用一个函数来关闭会话?/span>
如果你用MFCQ一个好的方法是在你的CWinAppz的类中(比如CYourProjectAppQ添加变量:
privateQ?/span>GdiplusStartupInput m_gdiplusStartupInput; ULONG_PTR m_pGdiToken;
然后在app的InitInstance函数中的开始添加一行代码:
GdiplusStartup(&m_pGdiToken,&m_gdiplusStartupInput,NULL); //gdi+ init
然后重蝲ExitInstance函数Q如果没有的话)Q在其中d一行代码:
GdiplusShutdown(m_pGdiToken); //gdi+ end session
q些操作之后你就可以在你的程序中使用cd的功能了?/span>
可以使用了么Q不可以。我们新Z个单文档的工E,按上面的步骤做完Q然后在ViewcȝOnDrawQ)函数里添加如下代码:
Graphics graphics(pDC->m_hDC); Pen pen(Color(255, 0, 255)); graphics.DrawLine(&pen, 0, 0, 200, 100);
~译Q出错。就q样q是被很多h转蝲Q可恶吧?/span>
错误提示为: f:\includes\gdiplusenums.h(29) : error C2146: syntax error : missing ';' before identifier 'GraphicsState' f:\includes\gdiplusenums.h(29) : fatal error C1004: unexpected end of file found
q个错误在网上百度一下有很多Q问的h多,回答的h也多Q但是几乎没有人答寏V解x法是
?include <gdiplus.h>之前加上#include <afxdtctl.h>
好了Q一条线d来了。ؓ什么啊Q这׃知道了,据说q个文g的作用是为IE4公共控g提供MFC支持?/span>
x花明之后Q才发现q里有篇文章 Hints to get GDI+ running Q是一个h写的?/span>
里面_要防止编译错误和问题Q需要在#include <gdiplus.h>之前加上#include <afxwin.h>?lt;afxext.h>?lt;afxdisp.h>?lt;afxdtctl.h>?/span>
]]> Linux下QTE序字体讑֮错误造成E序中文q http://www.shnenglu.com/cc/archive/2010/09/25/127673.html北风之神007 北风之神007 Sat, 25 Sep 2010 14:37:00 GMT http://www.shnenglu.com/cc/archive/2010/09/25/127673.html http://www.shnenglu.com/cc/comments/127673.html http://www.shnenglu.com/cc/archive/2010/09/25/127673.html#Feedback 0 http://www.shnenglu.com/cc/comments/commentRss/127673.html http://www.shnenglu.com/cc/services/trackbacks/127673.html 最q在Linux环境下写QT的程序,在我的测试机器上面QTE序Q在启动的时候设定了字符集ؓGBKQ中文都是显C正常的Q没有Q何问题,然后同学在他的虚拟机上面也写了QTE序Q可以怎么弄中文都是ؕ码,什么GBKQUTF-8{等的编码都讑֮了,可是依然qQ分析这U情况应该不是程序的问题Q很可能是QT字体的问题,于是在命令行输入qtconfig Q其他了qt配置E序Q在其中讑֮了其他的字体Q发现程序的中文p正常昄了?br> 因此Q有时候程序没有问题了Q但是QT的字体设定错误也会造成中文q现象Q我们可以不通过qtconfigE序改变默认qtE序的字体,q可以在E序中强制设定程序本w所用的默认字体Q这样也是可以的Q这里只介绍q样的思\Q代码就不脓了,希望大家见的时候有个参考?/span> ]]> C 代码优化Q{Q?/title> http://www.shnenglu.com/cc/archive/2010/05/24/116216.html北风之神007 北风之神007 Mon, 24 May 2010 06:04:00 GMT http://www.shnenglu.com/cc/archive/2010/05/24/116216.html http://www.shnenglu.com/cc/comments/116216.html http://www.shnenglu.com/cc/archive/2010/05/24/116216.html#Feedback 0 http://www.shnenglu.com/cc/comments/commentRss/116216.html http://www.shnenglu.com/cc/services/trackbacks/116216.html 谈到优化Q很多h都会直接惛_汇编。难道优化只能在汇编层次吗?当然不是QC++层次一样可以作代码优化Q其中有些常常是意想不到的。在C++层次q行优化Q比在汇~层ơ优化具有更好的UL性,应该是优化中的首选做法?nbsp; 1.定点型变量和表达式是 float ?nbsp; Z让编译器产生更好的代?比如说?DNow! 或SSE指o的代?Q必ȝ定Q点型变量和表辑ּ?float 型的。要特别注意的是Q以 "QF"Q??"Qf"Q?为后~Q比如:3.14fQ的点帔R才是 float 型,否则默认?double 型。ؓ了避?float 型参数自动{化ؓ doubleQ请在函数声明时使用 float?nbsp; 2.使用32位的数据cd ~译器有很多U,但它们都包含的典型的32位类型是QintQsignedQsigned intQunsignedQunsigned intQlongQsigned longQlong intQsigned long intQunsigned longQunsigned long int。尽量?2位的数据cdQ因为它们比16位的数据甚至8位的数据更有效率?nbsp; 3.明智使用有符h型变?nbsp; 在很多情况下Q你需要考虑整型变量是有W号q是无符L型的。比如,保存一个h的体重数据时不可能出现负敎ͼ所以不需要用有W号cd。但是,如果是要保存温度数据Q就必须使用到有W号的变量?nbsp; 在许多地方,考虑是否使用有符L变量是必要的。在一些情况下Q有W号的运比较快Q但在一些情况下却相反?nbsp; 比如Q整型到点转化Ӟ使用大于16位的有符h型比较快。因为x86构架中提供了从有W号整型转化到Q点型的指令,但没有提供从无符h型{化到点的指令。看看编译器产生的汇~代码: 不好的代码: ~译? ~译?nbsp; double xQ?nbsp; mov [foo + 4], 0 unsigned int iQ?nbsp; mov eax, i x = iQ?nbsp; mov [foo], eax flid qword ptr [foo] fstp qword ptr [x] 上面的代码比较慢。不仅因为指令数目比较多Q而且׃指o不能配对造成的FLID指o被gq执行。最好用以下代码代替Q?nbsp; 推荐的代码: ~译?nbsp; ~译?nbsp; double xQ?nbsp; fild dword ptr int iQ?nbsp; fstp qword ptr [x] x = iQ?nbsp; 在整数运中计算商和余数Ӟ使用无符L型比较快。以下这D典型的代码是编译器产生?2位整型数除以4的代码: 不好的代?nbsp; ~译? ~译?nbsp; int iQ?nbsp; mov eax, i i = i / 4Q? cdq and edx, 3 add eax, edx sar eax, 2 mov i, eax 推荐的代?br>~译? ~译?nbsp; unsigned int iQ? shr i, 2 i = i / 4Q?nbsp; ȝQ?br> 无符L型用于:除法和余?循环计数,数组下标 有符L型用于:整型到Q点的转化 4.while VS. for 在编E中Q我们常帔R要用到无限@环,常用的两U方法是while (1) ?for (Q;)。这两种Ҏ效果完全一P但那一U更好呢Q然我们看看它们~译后的代码Q?nbsp; ~译? ~译?nbsp; while (1)Q? mov eax,1 test eax,eax je foo+23h jmp foo+18h ~译? ~译?nbsp; for (Q;)Q? jmp foo+23h 一目了Ӟfor (Q;)指o,不占用寄存器Q而且没有判断跌{Q比while (1)好?nbsp; 5.使用数组型代替指针型 使用指针会ɾ~译器很难优化它。因为缺乏有效的指针代码优化的方法,~译器L假设指针可以讉K内存的Q意地方,包括分配l其他变量的储存I间。所以ؓ了编译器产生优化得更好的代码Q要避免在不必要的地方用指针。一个典型的例子是访问存攑֜数组中的数据。C++ 允许使用操作W?[] 或指针来讉K数组Q用数l型代码会让优化器减生不安全代码的可能性。比如,x[0] 和x[2] 不可能是同一个内存地址Q但 *p ?*q 可能。强烈徏议用数l型Q因样可能会有意料之外的性能提升?nbsp; 不好的代?br>typedef struct { float x,y,z,wQ?br>} VERTEXQ?br>typedef struct{ float m[4][4]Q?br>} MATRIXQ?br>void XForm(float* res, const float* v, const float* m, int nNumVerts) { float dpQ?br> int iQ?br> const VERTEX* vv = (VERTEX *)vQ?br> for (i = 0Q?i <Q?nNumVertsQ?i++) { dp = vv->Qx * *m ++Q?br> dp += vv->Qy * *m ++Q?br> dp += vv->Qz * *m ++Q?br> dp += vv->Qw * *m ++Q?br> *res ++ = dpQ // 写入转换了的 x dp = vv->Qx * *m ++Q?br> dp += vv->Qy * *m ++Q?br> dp += vv->Qz * *m ++Q?br> dp += vv->Qw * *m ++Q?br> *res ++ = dpQ // 写入转换了的 y dp = vv->Qx * *m ++Q?br> dp += vv->Qy * *m ++Q?br> dp += vv->Qz * *m ++Q?br> dp += vv->Qw * *m ++Q?br> *res ++ = dpQ // 写入转换了的 z dp = vv->Qx * *m ++Q?br> dp += vv->Qy * *m ++Q?br> dp += vv->Qz * *m ++Q?br> dp += vv->Qw * *m ++Q?br> *res ++ = dpQ // 写入转换了的 w vv ++Q // 下一个矢?br> m -= 16Q?br> } } 推荐的代?nbsp; typedef struct { float x,y,z,wQ?br>} VERTEXQ?br>typedef struct { float m[4][4]Q?br>} MATRIXQ?br>void XForm (float* res, const float* v, const float* m, int nNumVerts) { int iQ?br> const VERTEX* vv = (VERTEX*)vQ?br> const MATRIX* mm = (MATRIX*)mQ?br> VERTEX* rr = (VERTEX*)resQ?br> for (i = 0Q?i <Q?nNumVertsQ?i++) { rr->Qx = vv->Qx * mm->Qm[0][0] + vv->Qy * mm->Qm[0][1] + vv->Qz * mm->Qm[0][2] + vv->Qw * mm->Qm[0][3]Q?br> rr->Qy = vv->Qx * mm->Qm[1][0] + vv->Qy * mm->Qm[1][1] + vv->Qz * mm->Qm[1][2] + vv->Qw * mm->Qm[1][3]Q?br> rr->Qz = vv->Qx * mm->Qm[2][0] + vv->Qy * mm->Qm[2][1] + vv->Qz * mm->Qm[2][2] + vv->Qw * mm->Qm[2][3]Q?br> rr->Qw = vv->Qx * mm->Qm[3][0] + vv->Qy * mm->Qm[3][1] + vv->Qz * mm->Qm[3][2] + vv->Qw * mm->Qm[3][3]Q?br> } } 注意: 源代码的转化是与~译器的代码发生器相l合的。从源代码层ơ很难控制生的机器码。依靠编译器和特D的源代码,有可能指针型代码~译成的机器码比同等条g下的数组型代码运行速度更快。明智的做法是在源代码{化后查性能是否真正提高了,再选择使用指针型还是数l型?nbsp; 6.充分分解的循环 要充分利用CPU的指令缓存,p充分分解的循环。特别是当@环体本n很小的时候,分解循环可以提高性能。BTW:很多~译器ƈ不能自动分解循环?nbsp; 不好的代?推荐的代?nbsp; // 3D转化Q把矢量 V ?4x4 矩阵 M 怹 for (i = 0Q?i <Q?4Q?i ++) { r = 0Q?br> for (j = 0Q?j <Q?4Q?j ++) { r += M[j]*V[j]Q?br> } } r[0] = M[0][0]*V[0] + M[1][0]*V[1] + M[2][0]*V[2] + M[3][0]*V[3]Q?br>r[1] = M[0][1]*V[0] + M[1][1]*V[1] + M[2][1]*V[2] + M[3][1]*V[3]Q?br>r[2] = M[0][2]*V[0] + M[1][2]*V[1] + M[2][2]*V[2] + M[3][2]*V[3]Q?br>r[3] = M[0][3]*V[0] + M[1][3]*V[1] + M[2][3]*V[2] + M[3][3]*v[3]Q?nbsp; 7.避免没有必要的读写依?nbsp; 当数据保存到内存时存在读写依赖,x据必d正确写入后才能再ơ读取。虽然AMD Athlon{CPU有加速读写依赖gq的gQ允许在要保存的数据被写入内存前d出来Q但是,如果避免了读写依赖ƈ把数据保存在内部寄存器中Q速度会更快。在一D很长的又互怾赖的代码链中Q避免读写依赖显得尤光要。如果读写依赖发生在操作数组Ӟ许多~译器不能自动优化代码以避免d依赖。所以推荐程序员手动L除读写依赖,举例来说Q引q一个可以保存在寄存器中的时变量。这样可以有很大的性能提升。下面一D代码是一个例子: 不好的代?br>float x[VECLEN], y[VECLEN], z[VECLEN]Q?br>...... for (unsigned int k = 1Q?k <Q?VECLENQ?k ++) { x[k] = x[k-1] + y[k]Q?br>} for (k = 1Q?k <Q?VECLENQ?k++) { x[k] = z[k] * (y[k] - x[k-1])Q?br>} 推荐的代?nbsp; float x[VECLEN], y[VECLEN], z[VECLEN]Q?br>...... float t(x[0])Q?br>for (unsigned int k = 1Q?k <Q?VECLENQ?k ++) { t = t + y[k]Q?br> x[k] = tQ?br>} t = x[0]Q?br>for (k = 1Q?k <Q?VECLENQ?k ++) { t = z[k] * (y[k] - t)Q?br> x[k] = tQ?br>} 8.Switch 的用?nbsp; Switch 可能转化成多U不同算法的代码。其中最常见的是跌{表和比较?树。推荐对case的g照发生的可能性进行排序,把最有可能的攑֜W一个,当switch用比较链的方式{化时Q这样可以提高性能。此外,在case中推荐用小的连l的整数Q因为在q种情况下,所有的~译器都可以把switch 转化成蟩转表?nbsp; 不好的代?br>int days_in_month, short_months, normal_months, long_monthsQ?br>...... switch (days_in_month) { case 28: case 29: short_months ++Q?br> breakQ?br> case 30: normal_months ++Q?br> breakQ?br> case 31: long_months ++Q?br> breakQ?br> default: cout <Q?lt;Q?"Qmonth has fewer than 28 or more than 31 days"Q?<Q?lt;Q?endlQ?br> breakQ?br>} 推荐的代?nbsp; int days_in_month, short_months, normal_months, long_monthsQ?br>...... switch (days_in_month) { case 31: long_months ++Q?br> breakQ?br> case 30: normal_months ++Q?br> breakQ?br> case 28: case 29: short_months ++Q?nbsp; breakQ?br> default: cout <Q?lt;Q?"Qmonth has fewer than 28 or more than 31 days"Q?<Q?lt;Q?endlQ?br> breakQ?br>} 9.所有函数都应该有原型定?nbsp; 一般来_所有函数都应该有原型定义。原型定义可以传辄~译器更多的可能用于优化的信息?nbsp; 可能用常?const)。C++ 标准规定Q如果一个const声明的对象的地址不被获取Q允许编译器不对它分配储存空间。这样可以代码更有效率Q而且可以生成更好的代码?nbsp; 10.提升循环的性能 要提升@环的性能Q减多余的帔R计算非常有用Q比如,不随循环变化的计)?nbsp; 不好的代?在for()中包含不变的if()) 推荐的代?nbsp; for( i ... ) { if( CONSTANT0 ) { DoWork0( i )Q?// 假设q里不改变CONSTANT0的?br> } else { DoWork1( i )Q?// 假设q里不改变CONSTANT0的?br> } } if( CONSTANT0 ) { for( i ... ) { DoWork0( i )Q?br> } } else { for( i ... ) { DoWork1( i )Q?br> } } 如果已经知道if()的|q样可以避免重复计算。虽然不好的代码中的分支可以单地预测Q但是由于推荐的代码在进入@环前分支已经定Q就可以减少对分支预的依赖? 把本地函数声明ؓ静态的(static) 如果一个函数在实现它的文g外未被用的话,把它声明为静态的(static)以强制用内部连接。否则,默认的情况下会把函数定义为外部连接。这样可能会影响某些~译器的优化——比如,自动内联?nbsp; 11.考虑动态内存分?nbsp; 动态内存分配(C++中的"Qnew"Q)可能L为长的基本类型(四字寚wQ返回一个已l对齐的指针。但是如果不能保证对齐,使用以下代码来实现四字对齐。这D代码假设指针可以映到 long 型?nbsp; 例子 double* p = (double*)new BYTE[sizeof(double) * number_of_doubles+7L]Q?br> double* np = (double*)((long(p) + 7L) &Q?–8L)Q?nbsp; 现在Q你可以使用 np 代替 p 来访问数据。注意:释放储存I间时仍然应该用delete p?nbsp; 12.使用昑ּ的ƈ行代?nbsp; 可能把长的有依赖的代码铑ֈ解成几个可以在流水线执行单元中ƈ行执行的没有依赖的代码链。因为QҎ作有很长的潜伏期Q所以不它被映成 x87 ?3DNow! 指oQ这都很重要。很多高U语aQ包括C++Qƈ不对产生的Q点表辑ּ重新排序Q因为那是一个相当复杂的q程。需要注意的是,重排序的代码和原来的代码在代C一致ƈ不等价于计算l果一_因ؓ点操作~Z_度。在一些情况下Q这些优化可能导致意料之外的l果。幸q的是,在大部分情况下,最后结果可能只有最不重要的位(x低位Q是错误的?nbsp; 不好的代?br>double a[100], sumQ?br>int iQ?br>sum = 0.0fQ?br>for (i=0Q?i<Q?00Q?i++) sum += aQ?nbsp; 推荐的代?nbsp; double a[100], sum1, sum2, sum3, sum4, sumQ?br>int iQ?br>sum1 = sum2 = sum3 = sum4 = 0.0Q?br>for (i = 0Q?i <Q?100Q?i += 4) { sum1 += aQ?br> sum2 += a[i+1]Q?br> sum3 += a[i+2]Q?br> sum4 += a[i+3]Q?br>} sum = (sum4+sum3)+(sum1+sum2)Q?nbsp; 要注意的是:使用4 路分解是因ؓq样使用?阶段水UQ点加法,点加法的每一个阶D占用一个时钟周期,保证了最大的资源利用率?nbsp; 13.提出公共子表辑ּ 在某些情况下QC++~译器不能从点表达式中提出公共的子表达式,因ؓq意味着相当于对表达式重新排序。需要特别指出的是,~译器在提取公共子表辑ּ前不能按照代数的{h关系重新安排表达式。这ӞE序员要手动地提出公q子表辑ּQ在VC.net里有一?#8220;全局优化”选项可以完成此工作,但效果就不得而知了)?nbsp; 推荐的代?nbsp; float a, b, c, d, e, fQ?br>... e = b * c / dQ?br>f = b / d * aQ?br>float a, b, c, d, e, fQ?br>... const float t(b / d)Q?br>e = c * tQ?br>f = a * tQ?nbsp; 推荐的代?nbsp; float a, b, c, e, fQ?br>... e = a / cQ?br>f = b / cQ?br>float a, b, c, e, fQ?br>... const float t(1.0f / c)Q?br>e = a * tQ?br>f = b * tQ?nbsp; 14.l构体成员的布局 很多~译器有“使结构体字,双字或四字对?#8221;的选项。但是,q是需要改善结构体成员的对齐,有些~译器可能分配给l构体成员空间的序与他们声明的不同。但是,有些~译器ƈ不提供这些功能,或者效果不好。所以,要在付出最代L情况下实现最好的l构体和l构体成员对齐,采取q些ҎQ?nbsp; A按类型长度排?nbsp; 把结构体的成员按照它们的cd长度排序Q声明成员时把长的类型放在短的前面?nbsp; 把结构体填充成最长类型长度的整倍数 把结构体填充成最长类型长度的整倍数。照q样Q如果结构体的第一个成员对齐了Q所有整个结构体自然也就寚w了。下面的例子演示了如何对l构体成员进行重新排序: 不好的代码,普通顺?推荐的代码,新的序q手动填充了几个字节 struct { char a[5]Q?br> long kQ?br> double xQ?br>} bazQ?br>struct { double xQ?br> long kQ?br> char a[5]Q?br>char pad[7]Q?br>} bazQ?/p>
q个规则同样适用于类的成员的布局?nbsp; B按数据类型的长度排序本地变量 当编译器分配l本地变量空间时Q它们的序和它们在源代码中声明的顺序一P和上一条规则一P应该把长的变量放在短的变量前面。如果第一个变量对齐了Q其它变量就会连l的存放Q而且不用填充字节自然׃寚w。有些编译器在分配变量时不会自动改变变量序Q有些编译器不能产生4字节寚w的栈Q所?字节可能不对齐。下面这个例子演CZ本地变量声明的重新排序: 不好的代码,普通顺?推荐的代码,改进的顺?nbsp; short ga, gu, giQ?br>long foo, barQ?br>double x, y, z[3]Q?br>char a, bQ?br>float bazQ?br>double z[3]Q?br>double x, yQ?br>long foo, barQ?br>float bazQ?br>short ga, gu, giQ?nbsp; 14.避免不必要的整数除法 整数除法是整数运中最慢的Q所以应该尽可能避免。一U可能减整数除法的地方是连除,q里除法可以׃法代ѝ这个替换的副作用是有可能在乘U时会溢出,所以只能在一定范围的除法中用?nbsp; 不好的代?推荐的代?nbsp; int i, j, k, mQ?br>m = i / j / kQ?br>int i, j, k, mQ?br>m = i / (j * k)Q?nbsp; 15.把频J用的指针型参数拷贝到本地变量 避免在函C频繁使用指针型参数指向的倹{因为编译器不知道指针之间是否存在冲H,所以指针型参数往往不能被编译器优化。这h数据不能被存攑֜寄存器中Q而且明显地占用了内存带宽。注意,很多~译器有“假设不冲H?#8221;优化开养I在VC里必L动添加编译器命o?Oa?OwQ,q允许编译器假设两个不同的指针L有不同的内容Q这样就不用把指针型参数保存到本地变量。否则,请在函数一开始把指针指向的数据保存到本地变量。如果需要的话,在函数结束前拯回去? 不好的代?nbsp; // 假设 q != r void isqrt(unsigned long a, unsigned long* q, unsigned long* r) { *q = aQ?br> if (a >Q?0) { while (*q >Q?(*r = a / *q)) { *q = (*q + *r) >Q?gt;Q?1Q?br> } } *r = a - *q * *qQ?br>} 推荐的代?br>// 假设 q != r void isqrt(unsigned long a, unsigned long* q, unsigned long* r) { unsigned long qq, rrQ?br> qq = aQ?br> if (a >Q?0) { while (qq >Q?(rr = a / qq)) { qq = (qq + rr) >Q?gt;Q?1Q?br> } } rr = a - qq * qqQ?br> *q = qqQ?br> *r = rrQ?br>} 16.赋g初始?br>先看看以下代码: class CInt { int m_iQ?nbsp; public: CInt(int a = 0):m_i(a) { cout <Q?lt;Q?"QCInt"Q?<Q?lt;Q?endlQ?} ~CInt() { cout <Q?lt;Q?"Q~CInt"Q?<Q?lt;Q?endlQ?} CInt operator + (const CInt&Q?a) { return CInt(m_i + a.GetInt())Q?} void SetInt(const int i) { m_i = iQ?} int GetInt() const { return m_iQ?} }Q?br> 不好的代?nbsp; void main() { CInt a, b, cQ?br> a.SetInt(1)Q?br> b.SetInt(2)Q?br> c = a + bQ?br>} 推荐的代?br>void main() { CInt a(1), b(2)Q?br> CInt c(a + b)Q?br>} q两D代码所作的事都一P但那一个更好呢Q看看输出结果就会发玎ͼ不好的代码输Z四个"QCInt"Q和四个"Q~CInt"Q,而推荐的代码只输Z个。也是_W二个例子比W一个例子少生成一ơ时对象。Why? h意,W一个中的c用的是先声明再赋值的ҎQ第二个用的是初始化的方法,它们有本质的区别。第一个例子的"Qc = a + b"Q先生成一个时对象用来保存a + b的|再把该时对象用位拷贝的Ҏlc赋|然后临时对象被销毁。这个时对象就是那个多出来的对象。第二个例子直接用拷贝构造函数的Ҏ对c初始化,不生时对象。所以,量在需要用一个对象时才声明,q用初始化的Ҏ赋初倹{?nbsp; 17.量使用成员初始化列?nbsp; 在初始化cȝ成员Ӟ量使用成员初始化列表而不是传l的赋值方式?nbsp; 不好的代?nbsp; class CMyClass { string strNameQ?nbsp; public: CMyClass(const string&Q?str)Q?br>}Q?nbsp; CMyClass::CMyClass(const string&Q?str) { strName = strQ?br>} 推荐的代?br>class CMyClass { string strNameQ?br> int iQ?br>public: CMyClass(const string&Q?str)Q?br>}Q?nbsp; CMyClass::CMyClass(const string&Qstr) :strName(str) {
} 不好的例子用的是赋值的方式。这PstrName会先被徏立(调用了string的默认构造函敎ͼQ再由参数str赋倹{而推荐的例子用的是成员初始化列表QstrName直接构造ؓstrQ少调用一ơ默认构造函敎ͼq少了一些安全隐患。zhuan
]]> C 高效~程忠告Q{Q?/title> http://www.shnenglu.com/cc/archive/2010/05/24/116212.html北风之神007 北风之神007 Mon, 24 May 2010 05:09:00 GMT http://www.shnenglu.com/cc/archive/2010/05/24/116212.html http://www.shnenglu.com/cc/comments/116212.html http://www.shnenglu.com/cc/archive/2010/05/24/116212.html#Feedback 1 http://www.shnenglu.com/cc/comments/commentRss/116212.html http://www.shnenglu.com/cc/services/trackbacks/116212.html 一?include “filename.h”?include <filename.h>的区?/span> #include “filename.h”是指~译器将从当前工作目录上开始查找此文g #include <filename.h>是指~译器将从标准库目录中开始查找此文g二、头文g的作?/span> 加强安全?br>通过头文件可能方便地调用库功能,而不必关心其实现方式三? , &修饰W的位置 int *i,j; // better for read i = new int(0); j = 0; int *&y = i; // pointer's reference 对于*?amp;修饰W,Z避免误解Q最好将修饰W紧靠变量名四、if语句 不要布变量与MD行比较,那会很容易出错的?br>整Ş变量必须要有cd相同的D行比?br>点变量最好少比相{,可以通过求差与较的数比?br>指针变量要和NULLq行比较Q不要和布尔型和整Ş比较五、const?define的比?/span> const有数据类型,#define没有数据cd 个别~译器中const可以q行调试Q?define不可以进行调?br>在类中定义常量有两种方式 1?在类在声明常量,但不赋|在构造函数初始化表中q行赋|Q常量和引用cd的成员变量必通过初始化列表来初始化赋| 2?用枚举代替const帔R?br>六、C++函数中值的传递方?/span> 有三U方式:g?Pass by value)、指针传?Pass by pointer)、引用传?Pass by reference) void fun(char c) //pass by value void fun(char *str) //pass by pointer void fun(char &str) //pass by reference 如果输入参数是以g递的话,最好用引用传递代替,因ؓ引用传递省M临时对象的构造和析构 函数的返回类型不能省略,q没有也要加个void七、函C中的指针或引用常量不能被q回 Char *func(void) { char str[]=”Hello Word”; //q个是不能被q回的,因ؓstr是个指定变量Q不是一般的|函数l束后会被注销?br> return str; }
函数体内的指针变量ƈ不会随着函数的消亡而自动释?br>八、一个内存拷贝函数的实现?/span> void *memcpy(void *pvTo,const void *pvFrom,size_t size) { assert((pvTo!=NULL)&&(pvFrom!=NULL)); byte *pbTo=(byte*)pvTo; //防止地址被改?br> byte *pbFrom=(byte*)pvFrom; while (size-- >0) pbTo++ = pbForm++; return pvTo; }
九、内存的分配方式 分配方式有三U,误住,说不定那天去面试的时候就会有人问你这问题 1?静态存储区Q是在程序编译时已l分配好的,在整个运行期间都存在Q如全局变量、常量。(E序~译后运行时包含code和data两部分,其中data即ؓ静态存储区分配Q程序一开始运行便分配整个data的东东) 2?栈上分配Q函数内的局部变量就是从q分配的Q但分配的内存容易有限?br>3?堆上分配Q也U动态分配,如我们用new,malloc分配内存Q用delete,free来释攄内存?br>十、内存分配的注意事项 用new或malloc分配内存Ӟ必须要对此指针赋初倹{?br>用delete 或free释放内存后,必须要将指针指向NULL 不能修改指向帔R的指针数?br>十一、内容复制与比较 //数组…… char a[]=”Hello Word!”; char b[10]; strcpy(b,a); if (strcmp(a,b)==0) {}
//指针…… char a[]=”Hello Word!”; char *p; p=new char[strlen(a)+1]; strcpy(p,a); if (strcmp(p,a)==0) {}
十二、sizeof的问?/span> C一点,C++无法知道指针所指对象的大小Q指针的大小永远?字节char a[]=”Hello World!” char *p=a; count<<sizeof(a)<<end; //12字节 count<<sizeof(p)<<endl; //4字节
而且Q在函数中,数组参数退化ؓ指针Q所以下面的内容永远输出?void fun(char a[1000]) { count<<sizeof(a)<<endl; //输出4而不?000 }
十三、关于指?/span> 1?指针创徏时必被初始?br>2?指针在free 或delete后必ȝ为NULL 3?指针的长度都?字节 4、释攑ֆ存时Q如果是数组指针Q必要释放掉所有的内存Q如char *p=new char[100]; strcpy(p,”Hello World”); delete []p; //注意前面的EQ号 p=NULL;
5、数l指针的内容不能过数组指针的最大容易?br>?char *p=new char[5]; strcpy(p,”Hello World”); //报错 目标Ҏ不够?br>delete []p; //注意前面的EQ号 p=NULL;
十四、关于malloc/free 和new /delete malloc/free 是C/C+的内存分配符Qnew /delete是C++的内存分配符?br>注意Qmalloc/free是库函数Qnew/delete是运符 malloc/free不能执行构造函C析构函数Q而new/delete可以 new/delete不能在C上运行,所以malloc/free不能被淘?br>两者都必须要成对?br>C++中可以用_set_new_hander函数来定义内存分配异常的处理十五、E++的特?/span> Q?+新增加有重蝲(overload)Q内联(inlineQ,ConstQVirtual四种机制 重蝲和内联:卛_用于全局函数Q也可用于类的成员函敎ͼ Const和VirtualQ只可用于类的成员函敎ͼ 重蝲Q在同一cMQ函数名相同的函数。由不同的参数决定调用那个函数。函数可要不可要Virtual关键字。和全局函数同名的函C叫重载。如果在cM调用同名的全局函数Q必ȝ全局引用W号::引用?br>覆盖是指zcd数覆盖基cd敎ͼ函数名相同;参数相同Q基cd数必LVirtual关键字;不同的范?zcd基类)?br>隐藏是指zcd蔽了基类的同名函数相?br>1?函数名相同,但参C同,此时不论基类有无Virtual关键字,基类函数被隐藏?br>2?函数名相同,参数也相同,但基cLVirtual关键?有就是覆?Q基cd数将被隐藏?br>内联Qinline关键字必M定义体放在一P而不是单单放在声明中?br>ConstQconst是constant的羃写,“恒定不变”的意思。被const修饰的东襉K受到强制保护Q可以预防意外的变动Q能提高E序的健壮性?br>1?参数做输入用的指针型参数Q加上const可防止被意外改动?br>2?按值引用的用户cd做输入参数时Q最好将按g递的改ؓ引用传递,q加上const关键字,目的是ؓ了提高效率。数据类型ؓ内部cd的就没必要做qg事情Q如Q?br>void Func(A a) 改ؓvoid Func(const A &a)?br>而void func(int a)没必要Ҏvoid func(const int &a); 3?l返回gؓ指针cd的函数加上constQ会使函数返回g能被修改Q赋l的变量也只能是const型变量。如Q函数const char*GetString(void); char *str=GetString()会出错。而const char *str=GetString()是正确的?br>4?Const成员函数是指此函C内只能调用Const成员变量Q提高程序的键壮性。如声明函数 int GetCount(void) const;此函C内就只能调用Const成员变量?br>VirtualQ虚函数Q派生类可以覆盖掉的函数Q纯虚函敎ͼ只是个空函数Q没有函数实CQ?br>十六、extern“C”有什么作用? Extern “C”是由Q+Q提供的一个连接交换指定符P用于告诉Q+Q这D代码是Q函数。这是因为C++~译后库中函数名会变得很长,与C生成的不一_造成Q+Q不能直接调用C函数Q加上extren “c”后,C++p直接调用C函数了?br>Extern “C”主要使用正规DLL函数的引用和导出 ?在C++包含C函数或C头文件时使用。用时在前面加上extern “c” 关键字即可?br>十七、构造函C析构函数 zcȝ构造函数应在初始化表里调用基类的构造函敎ͼ zcd基类的析构函数应加Virtual关键字?br>不要看构造函数和析构函数Q其实编hq是不容易?div class="code">#include <iostream.h> class Base { public: virtual ~Base() { cout<< "~Base" << endl ; } }; class Derived : public Base { public: virtual ~Derived() { cout<< "~Derived" << endl ; } }; void main(void) { Base * pB = new Derived; // upcast delete pB; }输出l果为: ~Derived ~Base 如果析构函数不ؓ虚,那么输出l果?br>~Base十八?IFNDEF/#DEFINE/#ENDIF有什么作?/span> 仿止该头文g被重复引?nbsp; ]]> UNIX下编译SQLite3.3.6 http://www.shnenglu.com/cc/archive/2009/09/18/96655.html北风之神007 北风之神007 Fri, 18 Sep 2009 09:41:00 GMT http://www.shnenglu.com/cc/archive/2009/09/18/96655.html http://www.shnenglu.com/cc/comments/96655.html http://www.shnenglu.com/cc/archive/2009/09/18/96655.html#Feedback 1 http://www.shnenglu.com/cc/comments/commentRss/96655.html http://www.shnenglu.com/cc/services/trackbacks/96655.html 虽然现在最新的版本已经C不少Q不q这个功能也可以了,刚好需要在HPUXQAIX以及Solaris都用它QRedhat下面自带Q所以在UNIX下面要编译了一下,q里把Makefile文g做了一些调_~译通过了?br> 解压~之后不需要再执行 Configure命o了,直接make可以了Q最后会在当前目录下?strong style="COLOR: #3366ff">.libs中生成相关的库,q接E序的时候加上这些库可以了?br> SQLite3.3.6 下蝲 Q?strong style="COLOR: #ff0000">AIX 5.2 XLC++V7试通过Q?br> SQLite3.3.6 下蝲 Q?strong style="COLOR: #ff0000">HPUX 11.23 aCC试通过Q?/span> ]]> *.bff文g的安?/title> http://www.shnenglu.com/cc/archive/2009/09/17/96509.html北风之神007 北风之神007 Thu, 17 Sep 2009 03:51:00 GMT http://www.shnenglu.com/cc/archive/2009/09/17/96509.html http://www.shnenglu.com/cc/comments/96509.html http://www.shnenglu.com/cc/archive/2009/09/17/96509.html#Feedback 0 http://www.shnenglu.com/cc/comments/commentRss/96509.html http://www.shnenglu.com/cc/services/trackbacks/96509.html 今天装了一台AIX5.2的环境,q要装编译器Q不q手里只有XLC++.V7版本的,以前在AIX5.2?.3的系l上都装q很多遍了,直接使用simt工具Q选好E序路径可以了Q基本上以ؓ不会有什么问题,但是今天在装的过E中却遇C一些意想不到的问题?br> pȝ装好之后Q先打了补丁Q然后开始装~译器,但是在装的过E中Q提Cxlmass.lib 4.3.0.0找不刎ͼ安装E序目录下面只有xlmass.lib 4.1.0.0的版本,由此造成后面几个关键包也安装不成功,最l导致安装失败。我不停的在光盘里面扑֕找,希望能找?.3.0.0版本的,可是q是没有扑ֈQ问题好像进入了死胡同了?br> 安装q程实际需要的是下面的版本
怎么搞呢Q有事情问baiduQgoogleQ查了半天,l于扑ֈ了IBM的XLC++的网?br>http://www-01.ibm.com/support/docview.wss?rs=0&uid=swg24019560 Q是XLC++V7在AIX5.2上面的运行库Q里面就有xlmass相关的包Q而且?.4.0.0版本的,比要求的要高了,不知道行不行Q不了Q下来再说。tar.Z文gQ先用uncompress解压~,然后再tar xvf可以了Q出来一?.bff文gQ还真没有用q这个东西,l箋baiduQ原来在smit工具里面打开可以了?br>用户模式下,smit installp->安装软gQ选择bff文g所在的路径卛_Q然后就是安装了Q安装过E中提示有错误,但是我要的这几个包好像提交成功了Q所以也不管了,装过之后再正常安装XLC++Q装完运行xlc命oQ大功告成阿?/span> ]]> 重装pȝ后ORACLE的恢复的几种Ҏ(转蝲) http://www.shnenglu.com/cc/archive/2009/08/19/93812.html北风之神007 北风之神007 Wed, 19 Aug 2009 04:48:00 GMT http://www.shnenglu.com/cc/archive/2009/08/19/93812.html http://www.shnenglu.com/cc/comments/93812.html http://www.shnenglu.com/cc/archive/2009/08/19/93812.html#Feedback 0 http://www.shnenglu.com/cc/comments/commentRss/93812.html http://www.shnenglu.com/cc/services/trackbacks/93812.html 我的电脑H然挂了Q不得不重装pȝQ不q我的ORACLE装在了D盘,所有的文g都还在,我相信一定能够恢复,直到搞定工作Q我才开始整我的数据库,׃两天旉Q终于恢复了Q庆一下,同时ȝ一下,希望有遇到同样问题的朋友能够快速搞定此c问? W一U: 首先Q备份数据库(X:\oracle\oradata)下的数据文gQ重新命名即?否则装数据库的时候会提示sid已存?。重新安装数据库Q当然数据库的名字就是你要恢复的名字。安装完成后Q打开控制面板Q停止oracle的服务。把(X:\oracle\oradata)下新生成的文件改名,把原先目录下的文件恢复名字。再重新启动oracle服务和监听。用sys/as dba 登陆数据库,可能会提C权限不够(ora-01031Q修改(X:\oracle\ora92\network\admin )文g夹下的sqlnet.ora文gQ添加SQLNET.AUTHENTICATION_SERVICES= (NTS)Q增加权限。登陆进dQ打开table提示不能打开。打开common,执行命oalert database openQ这时再htableQ发现原先的表可以打开了。恢复成功了。再用原先数据库的普通用戯入。发C切正常。至此,大功告成? W二U:1、首先,原来的ORACLE文gҎ名,原来的\径是D:/oracle。我暂时ҎD:/oracle_old。找来ORACLEQ我用的是ORACLE 9IQ安装光盘,ORACLE安装在原来安装的目录下,q样恢复h更加方便Q主要是注册表的内容不用修改?2、安装完了之后,pȝ中又有一个可以用的ORACLE了。这个时候要做的是原来的文g和数据恢复过来。第一步,先关闭ORACLE的所有已l启动的目Q在“服务”里面逐一关闭。然后,安装目录改名。我现在用的是D:/oracle。改成D:/oracle_new。再D:/oracle_oldҎD:/oracle?q样理论上说从物理层面恢复了ORACLE了。但是我们发玎ͼ现在q不能启动ORACLE的监听程序和服务E序。我们还要从逻辑上解冟? 3、在dos环境下执行一个删除命令:oradim -delete -sid mmQ其中mm为创建oracle时候创建的实例 执行q个命o后重新启动机器,重启后就可以建立和原来实例名相同的实例。当然你懒,不重新启动也可以Q但是你的实例名׃能和原来的一样了? 4、在dos环境下执行命?oradim -new -sid mm -startmode a -pfile "D:\oracle\admin\mm\pfile\initmm.ora "创徏一个新的实例,其中 “mm“为新数据库的名称? 5、启动服务,先打开数据库,然后可以用以前的用户名和密码登陆q去?要补充的是,一般的ORACLE数据库的监听E序都是用电脑的名称来识别地址的,而不?27.0.0.1或者localhost。所以,如果我们安装pȝ的时候用的是不同的电脑名Uͼ比如我原来用的是wm_mm。重新安装后用的是wenming_mmQ,那么我们q有一个工作要做,是修改文g listener.ora。将里面的相关的东西改过来就可以了? 需要耐心、细心,可能在一步里有一个细的差别׃Z古怪的错误提示Q有旉要根据错误提C采取策略,M原理是,先装一个一模一LORACLEQ安装目录、数据库名称都一Pq样保证注册表里不用更改Q再覆盖物理文gQ最后重新实例化Q打开数据库就可以q去了? 注:恢复必须要有以下文g a、初始化参数文gINIT.ORA b、所有数据文?.dbf c、所有重做日志文Ӟ联机日志、归档日志)redo d、所有控制文?crtl e、internal密码文g ]]>Solaris环境下编译头文g的注意事?/title> http://www.shnenglu.com/cc/archive/2009/07/29/91597.html北风之神007 北风之神007 Wed, 29 Jul 2009 07:45:00 GMT http://www.shnenglu.com/cc/archive/2009/07/29/91597.html http://www.shnenglu.com/cc/comments/91597.html http://www.shnenglu.com/cc/archive/2009/07/29/91597.html#Feedback 0 http://www.shnenglu.com/cc/comments/commentRss/91597.html http://www.shnenglu.com/cc/services/trackbacks/91597.html 最q在Solaris上编译程序的时候,发现它的~译器有个奇怪的习惯Q就是头文g的最后一行要加上一行回车行Q不知道是什么回事,否则׃产生警告Q在Solaris上装的就是sun公司自己的sunstudio开发工P在HPUX跟AIX上都没有q个问题Q应该是~译器的事情吧?br>下面截个囄大家看看Q?br>
]]> 单介lUNIX下编写定时器E序 http://www.shnenglu.com/cc/archive/2009/06/02/86548.html北风之神007 北风之神007 Tue, 02 Jun 2009 07:46:00 GMT http://www.shnenglu.com/cc/archive/2009/06/02/86548.html http://www.shnenglu.com/cc/comments/86548.html http://www.shnenglu.com/cc/archive/2009/06/02/86548.html#Feedback 1 http://www.shnenglu.com/cc/comments/commentRss/86548.html http://www.shnenglu.com/cc/services/trackbacks/86548.html 刚好写程序的时候要使用定时器,是定时的做一些操作,|上查了一下,自己也学着写了写,|上倒是说的好多U,我在q里׃做过多介l了Q就说我用的q个Q?span lang=EN-US style="FONT-SIZE: 10.5pt; COLOR: black; FONT-FAMILY: ˎ̥; mso-fareast-font-family: 宋体; mso-bidi-font-family: 宋体; mso-ansi-language: EN-US; mso-fareast-language: ZH-CN; mso-bidi-language: AR-SA">setitimer 函数?br>函数原型 int setitimer(int which, const struct itimerval *value, struct itimerval *ovalue); 参数说明 参数which 参数 which是定时器cd
取?/span>
含义
信号发?/span>
ITIMER_REAL
定时真实旉Q与 alarm cd相同?/span>
SIGALRM
ITIMER_VIRT
定时q程在用h下的实际执行时间?/span>
SIGVTALRM
ITIMER_PROF
定时q程在用h和核心态下 的实际执行时间?/span>
SIGPROF
q三U定时器定时完成时给q程发送的信号各不相同Q其中ITIMER_REALcd时器发送SIGALRM信号QITIMER_VIRTcd时器发送SIGVTALRM信号Q?span lang=EN-US style="BORDER-RIGHT: windowtext 1pt; PADDING-RIGHT: 0cm; BORDER-TOP: windowtext 1pt; PADDING-LEFT: 0cm; FONT-SIZE: 12pt; PADDING-BOTTOM: 0cm; BORDER-LEFT: windowtext 1pt; COLOR: black; PADDING-TOP: 0cm; BORDER-BOTTOM: windowtext 1pt; FONT-FAMILY: Arial; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt; mso-border-alt: none windowtext 0cm">ITIMER_PROF cd时器发送SIGPROF信号?/span>
参数 value l构itimerval描述了定时器的组成?br>
1 struct itimerval 2 { 3 struct timeval it_interval; /* 下次定时取?nbsp; */ 4 struct timeval it_value; /* 本次定时讄?nbsp; */ 5 } 6
l构timeval描述的是_到微U的l构?br>
1 struct timeval 2 { 3 long tv_sec; /* U(1000000微秒Q?nbsp; */ 4 long tv_usec; /* 微妙 */ 5 } 6
itimervall构中的it_value是代表首ơ定时的旉Q而it_interval代表下一ơ定时的旉Q执行完W一ơ之后,it_interval中的旉会赋值给it_valueQ周而复始。如果it_valueD讄?Q则定时器停止定Ӟ如果it_valueg?但it_intervalgؓ0Q则定时器在一ơ定时后l止?br> setitimer执行成功q回0Q否则返?1参数ovalue 该参数可以用空值NULLQ如果不为空的话Q返回的是上一个时ȝ定时器状态?br> 下面写的一个简单的例子E序?br>
1 #include < stdio.h > 2 #include < stdlib.h > 3 #include < unistd.h > 4 #include < signal.h > 5 #include < time.h > 6 #include < sys / time.h > 7 8 int n = 0 ; 9 void doAction( int sig) // 你要做的事情 10 { 11 printf( " 让一切痛苦随风而去 %d\n " ,n ++ ); 12 signal(SIGALRM,doAction); 13 } 14 void setMyTimer( int val) 15 { 16 struct itimerval value; 17 value.it_value.tv_sec = val; 18 value.it_value.tv_usec = 0 ; 19 value.it_interval.tv_sec = val; // valU?/span>20 value.it_interval.tv_usec = 0 ; 21 signal(SIGALRM, doAction); 22 setitimer(ITIMER_REAL, & value,NULL); 23 while ( 1 ); 24 } 25 26 int main( int argc, char ** argv ) 27 { 28 if (argc < 2 ) 29 { 30 printf( " h输入参数:\n " ); // W二个参数是定时器的旉的,单位是秒 31 return - 1 ; 32 } 33 int val = atoi(argv[ 1 ]); 34 printf( " %d\n " ,val); 35 setMyTimer(val); 36 return 0 ; 37 }
代码׃解释了,是启动的时候获得第二个参数Q用作定时器的时_然后打印?#8220;让一切痛苦随风去 0”Q如此@环?br>在AIX5.2下,使用XLC++V7.0~译通过?br> q行效果如下 ]]> LUNIX命oҎ?/title> http://www.shnenglu.com/cc/archive/2009/04/18/80396.html北风之神007 北风之神007 Sat, 18 Apr 2009 13:43:00 GMT http://www.shnenglu.com/cc/archive/2009/04/18/80396.html http://www.shnenglu.com/cc/comments/80396.html http://www.shnenglu.com/cc/archive/2009/04/18/80396.html#Feedback 0 http://www.shnenglu.com/cc/comments/commentRss/80396.html http://www.shnenglu.com/cc/services/trackbacks/80396.html LUNIX命oҎ表下?/u>
]]>XMananger不能dAIX的问题分?/title> http://www.shnenglu.com/cc/archive/2009/04/13/79538.html北风之神007 北风之神007 Mon, 13 Apr 2009 13:33:00 GMT http://www.shnenglu.com/cc/archive/2009/04/13/79538.html http://www.shnenglu.com/cc/comments/79538.html http://www.shnenglu.com/cc/archive/2009/04/13/79538.html#Feedback 0 http://www.shnenglu.com/cc/comments/commentRss/79538.html http://www.shnenglu.com/cc/services/trackbacks/79538.html W一U:盘?br> 我们在写E序的时候,l常会出C些程序死掉的问题Q在Windowspȝ中,E序L死掉了Q重启一下就行了Q但是在UNIX环境下,默认情况下程序死掉了都会产生一个core文gQcore文g中是E序的内存映部分,该文件的主要作用是用来帮我们查找问题的故障原因,调试用的?nbsp; 具体的调试需要用dbx工具Q这里不作介l。在q种情况下,可以讑֮pȝ只生成一个core文gQ后来生成的core文g会覆盖前面的Q这里就需要修?cshrc文g中的参数Q这里用的是cshellQ?nbsp; 打开.cshrc文g之后Q我们找到如下几行,如果没有的话Q自己可以手工填入?br> #setenv CORE_NAMING true setenv CORE_COMPRESS true setenv CORE_PATH true 前面加一?span style="COLOR: #0000ff">#号代表是注释掉,所以这一行就不v作用了,生成的core文g都叫coreQ而不再带有日期标讎ͼ所以默认就会只生成一个core文g了,但是q种情况下以前的core文g会被覆盖Q所以调试以前的E序׃方便了,可能也不知道以前有哪些程序死掉了?br> W二U:hosts文g~少内容 一般来_/etc/hosts文g中会有本C机的IP信息Q就少Q也应该?span style="COLOR: #0000ff"> 127.0.0.1 localhostq样的条目信息,如果没有的话Q远E登录上来的时候,可能会进入登录界面,但是输入用户名密码登录之后,界面׃停止Q或者问题对话框Q点ȝ定之后就退出系l了Q这U情况下要检查hosts文g是否有对应的 IP 与主机名信息Q如果没有,需要手工加入?br> W三U:CDE桌面q程未启?br> 在系l运行过E中QCDE桌面q程可能L会宕掉,或者由于其他原因没有启动,所以需要telnet上主机,然后手工启动?br>启动命o如下Q?br> # /etc/rc.dt ]]> AIX中的inittab 文gQ{Q?/title> http://www.shnenglu.com/cc/archive/2008/09/08/61305.html北风之神007 北风之神007 Mon, 08 Sep 2008 06:32:00 GMT http://www.shnenglu.com/cc/archive/2008/09/08/61305.html http://www.shnenglu.com/cc/comments/61305.html http://www.shnenglu.com/cc/archive/2008/09/08/61305.html#Feedback 0 http://www.shnenglu.com/cc/comments/commentRss/61305.html http://www.shnenglu.com/cc/services/trackbacks/61305.html
/etc/inittab 文g控制着初始化过E?/font>
/etc/inittab 文g?init 命o提供脚本作ؓ一个普通进E调度程序。构?init 命oq程调度zd的主要(多数Q进E是 /etc/getty U进E(line processQ,发vQ启动)专用U进E。被 init 命o特别调度的其他进Eؓ后台q程QDaemonQ和shell?/font>
/etc/inittab 文g?位置相关Qposition-dependent Q的条目l成Q格式如下:
Identifier:RunLevel:Action:Command
每一个条目都被一个换行字W分隔。一个换行字W前面一个反斜杠 (\) 表示一个条目的延箋?etc/inittab 文g中的条目数目没有限制Q而不是指条目的最大长度)。条目的最大长度是 1024 个字W?/font>
条目字段有:Identifier Q?标识唯一对象的一?1-4 位字W的字段?br>RunLevel Q?该条目运行的U别?br>q行U别有下列属性: - q行U别有效地符合系l进E的配置?br> - ?init 命o启动的每一个进E都被分配一个或多个该进E可存在于之的运行别?br> - q行U别?0-9 的数字来表示。例如,如果pȝq行于?1Q只有在q行U别字段?1 的那些条目被启动?br> - h init 命o改变q行U别Ӟ条目中运行别字D与目标q行U别不匹配的所有进E都会收C条警告信?(SIGTERM)Q在q程被删除符PEkill signal (SIGKILL)Q强行终止前Q有20U的宽限期?br> - q行U别字段可ؓ一个进E定义多个运行别,可以0-9的Q意组合。如果没有指定运行别,q程假定在所有的q行U别有效?br> - q有其他四个g出现在运行别字D,即他们q不是真正的q行U别Qa, b, c ?h。在q行U别字段有这些字W的条目仅仅在telinit 命oh时才q行Q与当前的系l运行别无养I。他们不同于init命o的运行别,init命o永远不能q入a, b, c, h q行U别。ƈ且,所有这些进E的q行h都不改变当前的运行别。此外,init 命o改变U别Ӟ由a, b, c 命o启动的进Eƈ不断开QkilledQ。只有当 /etc/inittab 文g中他们的行在action字段标记?offQ他们的行从 /etc/inittab 文g中完全删除,或者init 命oq入单用h式,q些q程才会被中断(killedQ?br>Action : 告知 init 命o如何处理?process 字段指定的进E。init 命o可识别的 actions 如下Q?br> respawn Q?如果q程不存在,则启动进E。却不等待进E终止(l箋扫描 /etc/inittab 文gQ。如q程LQ则重启该进E。如q程存在Ql扫?/etc/inittab 文g?br> wait Q??init 命oq入匚w某条目的q行U别Ӟ启动该进Eƈ{待该进E的l止。当init命o处于同样的运行别时Q所有对 /etc/inittab 文g随后的读取都会导?init 命o忽略该条目?br> once Q??init 命oq入匚w某条目的q行U别Ӟ启动该进E,q且不等待终止。当q程LӞ也不重启该进E。当pȝq入一个新的运行别时Q该q程仍然从之前运行别的变化q行Q程序也不重启?br> boot Q?只在pȝ引导q程中运行的条目Q这些进E是pȝ启动q程中,init 命o?/etc/inittab 文g中读取的。启动该q程Q不{待q程l止Qƈ且进E死掉时Q也不重启进E。有意义的指gơؓQ运行别应为默认,或者必Mpȝ引导?init 命o的运行别匹配。此 action 对于pȝg重启后的初始化功能非常有用?br> bootwait Q?pȝ引导后,init 命o从单用户到多用户状态,W一ơ运行的条目。启动该q程Qƈ{其l止Q进E死Ӟ不重启该q程。如?initdefault?2 Q则pȝ引导后直接运行该q程?br> powerfail Q?只有?init 命o收到一个电源故障信?SIGPWR)的时候,才执行与此条目相关的q程?br> powerwait Q?只有?init 命o收到一个电源故障信?SIGPWR)的时候,才执行与此条目相关的q程。ƈ{该q程l止Q才l箋处理 /etc/inittab 文g?br> off Q?如果与该条目相关的进E当前正在运行,发送一个警告信?SIGTERM)Q然后等?20 U才?kill 信号QSIGKILLQ终止该q程。如果进E不在运行,忽略该条目?br> ondemand Q?功能上与 respawn 相同Q不q,?action 应用 a, b, ?c |而不用运行别?br> initdefault Q?init 命o只在 最初调用时才扫描与?action 相关的条目。如果存在,init 命o使用该条目来军_初始q入的运行别。一般情况下Q用run-level 字段中指定的最高运行别来作ؓ初始状态。如果运行别字DؓI,则认?123456789Q因此,init 命oq入q行U别 9 。另外,如果 init 命o?/etc/inittab 文g中找不到initdefault 条目Q则在引导时向用戯求一个初始的q行U别?br> sysinit Q?此类型的条目在登录前 init 命o正要讉K控制C前被执行。该条目只被用来初始化设备,init 命o可能会针对这些设备询问运行别。这些条目被执行Qƈ{待完成后才l箋?/font>
Command Q?可执行的壻IshellQ命令。整?command 字段?exec 为前~Qƈ传给一?forked sh成ؓ sh -c exec 命o。Q何合法的 sh 命o语法都可出现在该字段。ƈ可用 # 插入注释?/font>
getty 命o覆写 /etc/inittab 文g中出现在它之前所有命令的输出。要在引导日志中记录q些命o的输出,可输送这些输出到 alog -tboot 命o?/font>
?init 命o正在处理 inittab 条目Ӟstdin, stdout, ?stderr q些文g描述W(file descriptorsQ可能是不可用的。所有写?stdout ?stderr 的条目不起作用,除非把输出重定向C个文件或者到 /dev/console?/font>
下列命o是唯一支持?/etc/inittab 文g中修改记录的ҎQ?br>mkitabQ?把记录添加到 /etc/inittab 文g?br>lsitabQ?列出 /etc/inittab 文g中的记录?br>chitabQ?修改 /etc/inittab 文g中的记录?br>rmitabQ??/etc/inittab 文g中删除记录?/font>
例如Q想?/etc/inittab 文g中添加一条记录,以运行?Qrun level 2Q运?find 命oq之一旦完成就再次启动?br>1. q行 ps 命oQ只昄包含 find 的进E: # ps -ef | grep find root 19750 13964 0 10:47:23 pts/0 0:00 grep find # 2. 使用 mkitab 命oQ在 /etc/inittab 文g中添加一个名?xcmd 的记录: # mkitab "xcmd:2:respawn:find / -type f > /dev/null 2>&1" 3. 使用 lsitab 命o昄新记录: # lsitab xcmd xcmd:2:respawn:find / -type f > /dev/null 2>&1 # 4. 查看q程Q?br># ps -ef | grep find root 25462 1 6 10:56:58 - 0:00 find / -type f root 28002 13964 0 10:57:00 pts/0 0:00 grep find # 5. 取消 find 命oq程Q?br># kill 25462 6. 查看q程Q?br># ps -ef | grep find root 23538 13964 0 10:58:24 pts/0 0:00 grep find root 28966 1 4 10:58:21 - 0:00 find / -type f #
本例中,׃ action 字段被配|?respawnQ故而每一ơ该命o一完成Q一个新q程׃启动?/font>
该进E将l箋再生 Qre-spawningQ,除非修改 action 字段Q例如: 1. 把记?xcmd ?action 字段?respawn 修改?onceQ?br># chitab "xcmd:2:once:find / -type f > /dev/null 2>&1" 2. 查看q程Q?br># ps -ef | grep find root 20378 13964 0 11:07:20 pts/0 0:00 grep find root 28970 1 4 11:05:46 - 0:03 find / -type f 3. 取消 find 命oq程Q?br># kill 28970 4. 查看q程Q?br># ps -ef | grep find root 28972 13964 0 11:07:33 pts/0 0:00 grep find #
要从 /etc/inittab 文g中删除该记录Q可使用 rmitab 命o。例如: # rmitab xcmd # lsitab xcmd #
/etc/inittab 条目的次?/font>
/etc/inittab 文g中的基本q程条目ơ序安装如下Q?br>1. initdefault 2. sysinit 3. Powerfailure Detection (powerfail) 4. Multiuser check (rc) 5. /etc/firstboot (fbcheck) 6. System Resource Controller (srcmstr) 7. Start TCP/IP daemons (rctcpip) 8. Start NFS daemons (rcnfs) 9. cron 10.pb cleanup (piobe) 11.getty for the console (cons)
pȝ资源控制?(SRC)必须?/etc/inittab 文g的开头附q就被启动,因ؓ启动其他的进E需要SRCq程QDaemonQ?br>׃NFS需要TCP/IPq程QDaemonQ才能正常运行,所以TCP/IPq程必须在NFSq程之前被启动?br>/etc/inittab 文g中的条目按相互依赖性排序,是_如果一个进E(process2Q需要另外一个进E(process1Q存在才能正常运行,那么?/etc/inittab文g中,process1的条目应该在process2的条目之前?/font>
]]> crontab命o详解Q{帖) http://www.shnenglu.com/cc/archive/2008/09/08/61304.html北风之神007 北风之神007 Mon, 08 Sep 2008 06:18:00 GMT http://www.shnenglu.com/cc/archive/2008/09/08/61304.html http://www.shnenglu.com/cc/comments/61304.html http://www.shnenglu.com/cc/archive/2008/09/08/61304.html#Feedback 0 http://www.shnenglu.com/cc/comments/commentRss/61304.html http://www.shnenglu.com/cc/services/trackbacks/61304.html crontab命o有三UŞ式的命o行结构: crontab [-u user] [file] crontab [-u user] [-e|-l|-r] crontab -l -u [-e|-l|-r] W一个命令行中,file是命令文件的名字。如果在命o行中指定了这个文Ӟ那么执行crontab命oQ则这个文件拷贝到crontabs目录下;如果在命令行中没有制定这个文Ӟcrontab命o接受标准输入(键盘Q上键入的命令,q将他们也存攑֜crontab目录下? 命o行中-r选项的作用是?usr/spool/cron/crontabs目录下删除用户定义的文gcrontabQ? 命o行中-l选项的作用是昄用户crontab文g的内宏V? 使用命ocrontab -u user -e命o~辑用户user的cron(c)作业。用户通过~辑文g来增加或修改M作业h? 执行命ocrontab -u user -r卛_删除当前用户的所有的cron作业? 作业与它们预定的旉储存在文?usr/spool/cron/crontabs/username里。username使用户名Q在相应的文件中存放着该用h要运行的命o。命令执行的l果Q无论是标准输出q是错误输出Q都以邮g形式发给用户。文仉的每一个请求必d含以spaces和tabs分割的六个域。前五个字段可以取整数|指定何时开始工作,W六个域是字W串Q称为命令字D,其中包括了crontab调度执行的命令? W一道第五个字段的整数取D围及意义是: 0?9 表示? 1?3 表示时 1?1 表示? 1?2 表示月䆾 0? 表示星期Q其?表示星期日) /usr/lib/cron/cron.allow表示谁能使用crontab命o。如果它是一个空文g表明没有一个用戯安排作业。如果这个文件不存在Q而有另外一个文?usr/lib/cron/cron.deny,则只有不包括在这个文件中的用h可以使用crontab命o。如果它是一个空文g表明M用户都可安排作业。两个文件同时存在时cron.allow优先Q如果都不存在,只有用户可以安排作业?br> ]]>QT Designer中安装QWT插g http://www.shnenglu.com/cc/archive/2008/09/05/60987.html北风之神007 北风之神007 Fri, 05 Sep 2008 04:54:00 GMT http://www.shnenglu.com/cc/archive/2008/09/05/60987.html http://www.shnenglu.com/cc/comments/60987.html http://www.shnenglu.com/cc/archive/2008/09/05/60987.html#Feedback 0 http://www.shnenglu.com/cc/comments/commentRss/60987.html http://www.shnenglu.com/cc/services/trackbacks/60987.html QWT是一套非怸错的开发库Q它能结合QT开发,做出非常好的曲线Q刻度,表盘{效果来?br> qwt的下载以及动态链接库的编译等q里׃做介l了。在源码目录下可以找到designer目录Q其中有插g的源码,~译完之后就会生成qwtplugin.dll和qwtplugin.libQ把他们拯?font face=Arial>$(QTDIR)\plugins\designer目录下,重新启动QT DesignerQ就会看到ToolBox面板中多ZQwtc,如下图所C。以上在QT3.3.4下测试通过Q?a style="COLOR: red" href="http://www.shnenglu.com/Files/cc/qwtplugin.rar">qwtplugin.dll和qwtplugin.lib下蝲
]]> C实现转动的短?/title> http://www.shnenglu.com/cc/archive/2008/08/29/60340.html北风之神007 北风之神007 Fri, 29 Aug 2008 03:18:00 GMT http://www.shnenglu.com/cc/archive/2008/08/29/60340.html http://www.shnenglu.com/cc/comments/60340.html http://www.shnenglu.com/cc/archive/2008/08/29/60340.html#Feedback 0 http://www.shnenglu.com/cc/comments/commentRss/60340.html http://www.shnenglu.com/cc/services/trackbacks/60340.html 在UNIX环境下的文字界面工作Ӟ如过E序在运行等待,可能׃看到转动的短,表示E序正在执行中,今天刚好看到资料Q上面说了一下,我就按照意思写了一个,不知道别的是怎么实现的,反正下面的代码看D工作了,不过正式使用可能q需要改q吧?br>
#include < stdio.h > int main() { int i = 0 ; char c; while ( 1 ) { i ++ ; if (i % 4 == 0 ) c = ' - ' ; else if (i % 4 == 1 ) c = ' \\ ' ; else if (i % 4 == 2 ) c = ' | ' ; else if (i % 4 == 3 ) c = ' / ' ; printf( " %c\b " ,c); sleep( 300 ); } system(" pause " ); return 0 ; }
以上代码在DEV-CPP 4.9.9.2中测试通过 ]]> C语言获取目录中文件名 http://www.shnenglu.com/cc/archive/2008/08/28/60292.html北风之神007 北风之神007 Thu, 28 Aug 2008 10:10:00 GMT http://www.shnenglu.com/cc/archive/2008/08/28/60292.html http://www.shnenglu.com/cc/comments/60292.html http://www.shnenglu.com/cc/archive/2008/08/28/60292.html#Feedback 2 http://www.shnenglu.com/cc/comments/commentRss/60292.html http://www.shnenglu.com/cc/services/trackbacks/60292.html #include < stdio.h > #include < dirent.h > #include < string .h > typedef struct FileList { char filename[ 64 ]; struct FileList * next; } FILENODE; FILENODE * getFiles( char * dir /**/ /* 文目?/span>*/ ) { DIR * directory_pointer; struct dirent * entry; directory_pointer = opendir(dir); struct FileList start; struct FileList * filesNode; start.next = NULL; filesNode =& start; while ((entry = readdir(directory_pointer)) != NULL) { filesNode -> next = ( struct FileList * )malloc( sizeof ( struct FileList)); filesNode = filesNode -> next; strcpy(filesNode -> filename,entry -> d_name); filesNode -> next = NULL; } closedir(directory_pointer); filesNode = start.next; return filesNode; } int main() { struct FileList * filesNode; char dir[ 100 ] = " D:\\down " ; filesNode = getFiles(dir); if (filesNode == NULL) { printf( " 没有成功 " ); return 0 ; } while (filesNode) { printf( " %s\n " ,filesNode -> filename); filesNode = filesNode -> next; } system( " pause " ); return 0 ; } ]]>Broadcom NetXtrem II|卡Linux安装指南Q{载) http://www.shnenglu.com/cc/archive/2008/05/29/51494.html北风之神007 北风之神007 Thu, 29 May 2008 09:01:00 GMT http://www.shnenglu.com/cc/archive/2008/05/29/51494.html http://www.shnenglu.com/cc/comments/51494.html http://www.shnenglu.com/cc/archive/2008/05/29/51494.html#Feedback 0 http://www.shnenglu.com/cc/comments/commentRss/51494.html http://www.shnenglu.com/cc/services/trackbacks/51494.html
Broadcom NetXtrem II|卡Linux安装指南
适用机型:
所有BladeCenter HS21; 所有BladeCenter LS21; 所有BladeCenter LS41; 所有System x3550; 所有System x3650; 所有System x3655; 所有System x3755
Broadcom NetXtreme II GbE|卡驱动有两U格式:source RPM 和tar格式。文件名分别为bnx2-<version>.src.rpm ?bnx2-<version>.tar.gz 下蝲地址Qhttp://www-1.ibm.com/support/docview.wss?uid=psg1MIGR-64538 Source RPM 驱动包的安装步骤 ============================= 1. 安装source RPM包: rpm -ivh bnx2-<version>.src.rpm 2. q入/usr/src路径q编?/font>cd /usr/src/{redhat,OpenLinux,turbo,packages,rpm ..} rpm -bb SPECS/bnx2.spec 或?/font>rpmbuild -bb SPECS/bnx2.spec (针对RPM version 4.x.x) 注意Q不同内核的linux版本Q其rpm路径不同 3. 安装刚刚~译好的?/font>rpm -ivh RPMS/i386/bnx2-<version>.i386.rpm 驱动被安装到如下路径 对于2.4.x kernels: /lib/modules/<kernel_version>/kernel/drivers/net/bnx2.o 对于2.6.0 kernels: /lib/modules/<kernel_version>/kernel/drivers/net/bnx2.ko 4. 加蝲驱动: insmod bnx2.o ?/font>insmod bnx2.ko (?2.6.x kernels) ?/font>modprobe bnx2 5. 配置|卡地址、网关等{?/font>TAR驱动包的安装步骤 ============================= 1. 创徏一个目录ƈ文件解?/font>tar xvzf bnx2-<version>.tar.gz 2. ~译驱动bnx2.o (或bnx2.ko)Q生成可加蝲的模?/font>cd src make 3. 通过加蝲模块对其q行试 insmod bnx2.o ?/font>insmod bnx2.ko (?.6.x kernels) ?/font>insmod bnx2 4. 安装驱动 make install 驱动被安装的位置与RPM方式安装的位|一?/font>5. 配置|卡地址、网关等{?/font>
]]>
þԾƷ |
ݺݾþۺһ77777 |
þùAV䡪ٶ |
ۺþһƷ |
97þþþ |
þҹۺϾþ |
ھƷþþþӰԺձ
|
þþþþƵ |
Ļɫ͵͵þ |
ٸþþþþ4 |
һþƵ |
þ |
þþùҺ |
þþþùƷ |
ھƷþþӰԺ |
þAV |
þþƷƵ |
þþƷ |
þþþþþùѿ |
þþþþAv뾫Ʒר |
Ʒ۲ӰԺþ
|
þܳ |
㽶þþƷ |
ƷۺϾþþþþ97 |
þѴƬ |
ϼþùƷӰԺ |
þˬˬƬAV |
þҹ1000ϼ |
պþþþĻ
|
þ99ֻоƷ |
ƷþþþþĻ |
þ99Ʒ |
Ʒþþþþø |
Ʒ18þþ⺾ |
ҹƷþþþþëƬ |
þþƷ2020 |
Ļþ2017 |
㽶þþƷۺ |
þþþþþòҰ¸߳
|
þþþAV |
ݺݾƷþþĻ
|