??xml version="1.0" encoding="utf-8" standalone="yes"?>亚洲国产精品成人AV无码久久综合影院,性做久久久久久久久老女人,97精品伊人久久久大香线蕉http://www.shnenglu.com/glxhyt/zh-cnWed, 07 May 2025 17:24:38 GMTWed, 07 May 2025 17:24:38 GMT60【{】C/C++开源项目中?00个Bugs | WHO1753http://www.shnenglu.com/glxhyt/archive/2013/05/19/200409.html郭龙郭龙Sun, 19 May 2013 13:10:00 GMThttp://www.shnenglu.com/glxhyt/archive/2013/05/19/200409.htmlhttp://www.shnenglu.com/glxhyt/comments/200409.htmlhttp://www.shnenglu.com/glxhyt/archive/2013/05/19/200409.html#Feedback1http://www.shnenglu.com/glxhyt/comments/commentRss/200409.htmlhttp://www.shnenglu.com/glxhyt/services/trackbacks/200409.htmlhttp://www.who1753.com/100-bugs-in-c-cpp-opensource-projects/

俄罗?a >OOO Program Verification Systems公司用自q静态源码分析品PVS-Studio对一些知名的C/C++开源项目,诸如Apache Http Server?a >Chromium?a >Clang?a >CMake?a >MySQL{的源码q行了分析,扑և?a >100个典型的Bugs。个得这份列表对C/C++ E序员有一定参考意义。与其说事后用静态工具分析,倒不如在~码时就提高自知自觉Q避免这份列表上的错误发生在你的代码中,因此q里部分摘录一些BugsQBug~号q里不连l,为的是对应原文的~号Qƈ做简要说明。原文将q䆾Bug列表分ؓ了几c,q里也将沿用q个思\?/p>

一、数l和字符串处理错?/strong>

数组和字W串处理错误是C/C++E序中最多的一cȝL型。这也可以看作是我们为拥有高效地底层内存操作能力而付出的代h?/p>

[#1] Wolfenstein 3D目 -"只有部分对象被clear?

1
2
3
4
5
6
7
8
void CG_RegisterItemVisuals( int itemNum )
{
       
      itemInfo_t *itemInfo;
      
      memset( itemInfo, 0, sizeof( &itemInfo ) ); 
      
}

q里的Bug出现在memset那一行。代码的真实意图是clear iteminfoq块内存Q但调用memsetӞW三个参C入的却是sizeof(&iteminfo)Q要知道 sizeof(&itemInfo) != sizeof(itemInfo_t)Q前者只是一个指针的大小|了。正的写法是:

memset(itemInfo, 0, sizeof(itemInfo_t)); 或memset(itemInfo, 0, sizeof(*itemInfo));

[#2] Wolfenstein 3D目 -"只有部分Matrix被clear?

ID_INLINE mat3_t::mat3_t( float src[ 3 ][ 3 ] ) {
memcpy( mat, src, sizeof( src ) );
}

q里的Bug出现在memcpy一行。程序的原意是将clear src[3][3]q个二维数组。但q里有个坑:那就是作为函数Ş式参数的数组名已l退化ؓ指针了,对其sizeof只能得到一个指针的长度Q因此这里的 memcpy只是copy了一个指针的长度Q没有copy全。这里的代码是C++代码Q原文中l出了正的ҎҎ – 传referenceQ?/p>

ID_INLINE mat3_t::mat3_t( float (&src)[3][3] )
{
memcpy( mat, src, sizeof( src ) );
}

[#4] ReactOS目 – "错误地计一个字W串的长?

static const PCHAR Nv11Board = "NV11 (GeForce2) Board";
static const PCHAR Nv11Chip = "Chip Rev B2";
static const PCHAR Nv11Vendor = "NVidia Corporation";

BOOLEAN
IsVesaBiosOk(…)
{

if (!(strncmp(Vendor, Nv11Vendor, sizeof(Nv11Vendor))) &&
!(strncmp(Product, Nv11Board, sizeof(Nv11Board))) &&
!(strncmp(Revision, Nv11Chip, sizeof(Nv11Chip))) &&
(OemRevision == 0×311))

}

Bug处在IsVesaBiosOK中那一串strncmp调用中,代码一个指针的size传入strncmp作ؓW三个参敎ͼD strncmp实际只是比较?span style="color: red">字符串的? or 8个字?/span>Q而不是字W串的全部内宏V?/p>

[#6] CPU Identifying Tool目 – 数组界

#define FINDBUFFLEN 64  // Max buffer find/replace size

int WINAPI Sticky (…)
{

static char findWhat[FINDBUFFLEN] = {'\0'};

findWhat[FINDBUFFLEN] = '\0';

}

bug出在"findWhat[FINDBUFFLEN] = ‘\0′;”q一行。数l的最大长度ؓFINDBUFFLENQ但下标的最大值应该是FINDBUFFLEN-1Q而不是FINDBUFFLEN。因此这 行代码显然应该改?span style="color: red">findWhat[FINDBUFFLEN-1] = '\0';

[#7] Wolfenstein 3D目 – 数组界

typedef struct bot_state_s
{

char teamleader[32]; //netname of the team leader

}  bot_state_t;

void BotTeamAI( bot_state_t *bs ) {

bs->teamleader[sizeof( bs->teamleader )] = '\0';

}

"sizeof( bs->teamleader )]"q行的结果值已l超Z数组的最大边界,正确的代码是Q?/p>

bs->teamleader[
sizeof(bs->teamleader) / sizeof(bs->teamleader[0]) – 1
] = '\0';

[#8] Miranda IM目 – 只Copy了部分字W串

struct _textrangew
{
CHARRANGE chrg;
LPWSTR lpstrText;
} TEXTRANGEW;

const wchar_t* Utils::extractURLFromRichEdit(…)
{

::CopyMemory(tr.lpstrText, L"mailto:", 7);

}

q里的bug在于L"mailto:"是宽字符Ԍ宽字W串中的每个字符??个字节(依Compiler使用?/span>字符?/span>~码而定Q,因此q里?copy 7个字节显然是不够的,应该? * sizeof(wchar_t)?/p>

[#9] CMake目 – 循环內的数组界

static const struct {
DWORD   winerr;
int     doserr;
} doserrors[] =
{

};

static void
la_dosmaperr(unsigned long e)
{

for (i = 0; i < sizeof(doserrors); i++)
{
if (doserrors[i].winerr == e)
{
errno = doserrors[i].doserr;
return;
}
}

}

作者原本意图la_dosmaperr中for循环的次数等于数l的元素个数Q但sizeof(doserrors)q回的却是数l占用的字节个数Q这q远大于数组元素个数Q因此造成数组界。正的写法Q?/p>

for (i = 0; i < sizeof(doserrors) / sizeof(*doserrors); i++)

[#10] CPU Identifying Tool目 – 打印到自w的字符?/p>

char * OSDetection ()
{

sprintf(szOperatingSystem,
"%sversion %d.%d %s (Build %d)",
szOperatingSystem,
osvi.dwMajorVersion,
osvi.dwMinorVersion,
osvi.szCSDVersion,
osvi.dwBuildNumber & 0xFFFF);

sprintf (szOperatingSystem, "%s%s(Build %d)",
szOperatingSystem, osvi.szCSDVersion,
osvi.dwBuildNumber & 0xFFFF);

}

通过sprintfQ?span style="color: red">szOperatingSystem字符串将自己打印到自己里面,q是十分危险?/span>Q将D无法预知的错误结果,可能会导致栈溢出{严重问题?/p>

[#12] Notepad++目 – 数组局部clear

#define CONT_MAP_MAX 50
int _iContMap[CONT_MAP_MAX];

DockingManager::DockingManager()
{

memset(_iContMap, -1, CONT_MAP_MAX);

}

代码的原本试囑ְ数组_iContMap清零Q但memset的第三个参数CONT_MAP_MAXq不能代表数l的真正大小Q?span style="color: red">而只是数l的元素个数而已Q显然其忘记乘以sizeof(int)了?/span>

二、未定义行ؓ

在C/C++的语a规范中,我们常常能看?#8220;xx is undefined”。规范中q没有明表明这c错误是什么样子的Q只是说取决于Compiler的实玎ͼ也许Compiler会给出正的l果Q但q么使用却是不可UL的?/p>

[#1] Chromium目 – 指针的误?/p>

void AccessibleContainsAccessible(…)
{

auto_ptr<VARIANT> child_array(new VARIANT[child_count]);

}

q里的问题在于用new[]分配的内存,在智能指针释放时却用了deleteQ这会D未定义行为?/span>看看autoptr的destructorq道了Q?/p>

~auto_ptr() {
delete _Myptr;
}

我们可以找一些更合适的cLfixq个问题Q比如boost::scopedarray?/p>

[#2] IPP Sample目 – l典未定义行?/p>

template<typename T, Ipp32s size> void HadamardFwdFast(…)
{
Ipp32s *pTemp;

for(j=0;j<4;j++) {
a[0] = pTemp[0*4] + pTemp[1*4];
a[1] = pTemp[0*4] – pTemp[1*4];
a[2] = pTemp[2*4] + pTemp[3*4];
a[3] = pTemp[2*4] – pTemp[3*4];
pTemp = pTemp++;

}

}

很多Z眼就看到?pTemp = pTemp++"q行Q?/span>对于q个代码~译器会产生两种l果截然不同的翻译:

pTemp = pTemp + 1;
pTemp = pTemp;

?/p>

TMP = pTemp;
pTemp = pTemp + 1;
pTemp = TMP;

到底是哪U呢Q依赖于~译器的实现Q甚x优化U别的设定?/p>

三、与q算优先U相关的错误

[#1] MySQL工程 – !?amp;的运优先

int ha_innobase::create(…)
{

if (srv_file_per_table
&& !mysqld_embedded
&& (!create_info->options & HA_LEX_CREATE_TMP_TABLE)) {

}

q段代码原意是想试create_info->options变量中几个bit位的值是否set了,?(create_info->options & HA_LEX_CREATE_TMP_TABLE)Q但׃!的运优先高于&Q实际逻辑变成?!create_info->options) & HA_LEX_CREATE_TMP_TABLE了。如果想要这D代码如期工作,׃要吝啬小括号了?/p>

[#2] Emule工程 – *?+的运优先

STDMETHODIMP
CCustomAutoComplete::Next(…, ULONG *pceltFetched)
{

if (pceltFetched != NULL)
*pceltFetched++;

}

昄作者原意是惛_pceltFetched所指向的long型变量进?+操作Q但׃*?+的运优先没有搞对Q导致实际上执行?(pceltFetched++)的操作,而不?*pceltFetched)++操作?/p>

[#3] Chromium目 – &?=的运优先

#define FILE_ATTRIBUTE_DIRECTORY 0×00000010

bool GetPlatformFileInfo(PlatformFile file, PlatformFileInfo* info) {

info->is_directory =
file_info.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY != 0;

}

q个E序员的意图是通过试file_info.dwFileAttributes的几个bit位的值来判定是否是目录,逻辑上应该是(file_info.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) != 0Q但׃!=优先U高?amp;Q原代码中无括号Q结果逻辑变成了file_info.dwFileAttributes & (FILE_ATTRIBUTE_DIRECTORY != 0)Q导致is_directory永q求gؓtrue?/p>

[#4] BCmenu目 – if和else弄؜

void BCMenu::InsertSpaces(void)
{
if(IsLunaMenuStyle())
if(!xp_space_accelerators) return;
else
if(!original_space_accelerators) return;

}

q又是C语言的一?#8220;大坑”Q无奈这个BCMenu目的程序员掉坑里了。虽然从代码~进上来看,elseg是与最外层的if配对使用Q但实际q段代码的效果是Q?/p>

if(IsLunaMenuStyle())
{
if(!xp_space_accelerators) {
return;
} else {
if(!original_space_accelerators) return;
}
}

q显然不是程序员原意Q看来括号必要时q是不能省略的。修改后的代码如下:

if(IsLunaMenuStyle()) {
if(!xp_space_accelerators) return;
} else {
if(!original_space_accelerators) return;
}

四、格式化输出错误

[#1] ReactOS目 – 错误地输出WCHAR字符

static void REGPROC_unescape_string(WCHAR* str)
{

default:
fprintf(stderr,
"Warning! Unrecognized escape sequence: \\%c'\n",
str[str_idx]);

}

%c是用来格式化输出非宽字符的,q里用来输出WCHAR昄会得到错误的l果Q?span style="color: red">fix solution是将%c换位%C?/span>

[#2] Intel AMT SDK目 – ~少%s 【VS2010Q运行可能会崩溃?/span>

void addAttribute(…)
{

int index = _snprintf(temp, 1023,
"%02x%02x:%02x%02x:%02x%02x:%02x%02x:"
"%02x%02x:02x%02x:%02x%02x:%02x%02x",
value[0],value[1],value[2],value[3],value[4],
value[5],value[6],value[7],value[8],
value[9],value[10],value[11],value[12],
value[13],value[14],value[15]);

}

 

不解释了Q自己慢慢数和对照吧?/p>

[#3] Intel AMT SDK目 – 未用的参数

bool GetUserValues(…)
{

printf("Error: illegal value. Aborting.\n", tmp);
return false;
}

?span style="color: red">然tmp是多余的?/span>

五、书写错?/strong>

[#1] Miranda IM目 – 在if中赋?/p>

void CIcqProto::handleUserOffline(BYTE *buf, WORD wLen)
{

else if (wTLVType = 0×29 && wTLVLen == sizeof(DWORD))

}

“wTLVType = 0×29”昄是笔误,应该?#8220;wTLVType == 0×29”才对?/p>

[#3] Clang目 – 对象名书写错?/p>

static Value *SimplifyICmpInst(…) {

case Instruction::Shl: {
bool NUW =
LBO->hasNoUnsignedWrap() && LBO->hasNoUnsignedWrap();
bool NSW =
LBO->hasNoSignedWrap() && RBO->hasNoSignedWrap();

}

从最后一行先后用了LBO和RBO来看Q前面只用了LBO的那行很可能是有问题的,正确的应该是Q?/span>

bool NUW =
LBO->hasNoUnsignedWrap() && RBO->hasNoUnsignedWrap();

[#6] G3D Content Pak目 – 一Ҏh错了地方

bool Matrix4::operator==(const Matrix4& other) const {
if (memcmp(this, &other, sizeof(Matrix4) == 0)) {
return true;
}

}

׃括号N了地方,Dmemcmp最后的参数变成了sizeof(Matrix4) == 0Q这行代码的正确写法应该是:

if (memcmp(this, &other, sizeof(Matrix4)) == 0) {

[#8] Apache Http Server目 – 多余的sizeof

PSECURITY_ATTRIBUTES GetNullACL(void)
{
PSECURITY_ATTRIBUTES sa;
sa  = (PSECURITY_ATTRIBUTES)
LocalAlloc(LPTR, sizeof(SECURITY_ATTRIBUTES));
sa->nLength = sizeof(sizeof(SECURITY_ATTRIBUTES));

}

最后一行显然是W误Q?span style="color: red">sizeof(sizeof(SECURITY_ATTRIBUTES))应该写ؓsizeof(SECURITY_ATTRIBUTES)才对?/span>

[#10] Notepad++目 – 在本来应该用&的地方用了&&

TCHAR GetASCII(WPARAM wParam, LPARAM lParam)
{

result=ToAscii(wParam,
(lParam >> 16) && 0xff, keys,&dwReturnedValue,0);

}

(lParam >> 16) && 0xff没有什么意义,求值结果Ltrue。这里的代码应该?lParam >> 16) & 0xff?/span>

[#12] Fennec Media Project目 – 额外的分?/p>

int settings_default(void)
{

for(i=0; i<16; i++);
for(j=0; j<32; j++)
{
settings.conversion.equalizer_bands.boost[i][j] = 0.0;
settings.conversion.equalizer_bands.preamp[i]   = 0.0;
}
}

q又是一个实际逻辑与代码羃q不W的例子。作者的原意是这LQ?/p>

for(i=0; i<16; i++)
{
for(j=0; j<32; j++)
{
settings.conversion.equalizer_bands.boost[i][j] = 0.0;
settings.conversion.equalizer_bands.preamp[i]   = 0.0;
}
}

但实际执行代码逻辑却是Q?/p>

for(i=0; i<16; i++)
{
;
}

for(j=0; j<32; j++)
{
settings.conversion.equalizer_bands.boost[i][j] = 0.0;
settings.conversion.equalizer_bands.preamp[i]   = 0.0;
}

q一切都是那?D的?/p>

六、对基本函数和类的误?/strong>

[#2] TortoiseSVN目 – remove函数的误?/p>

STDMETHODIMP CShellExt::Initialize(….)
{

ignoredprops = UTF8ToWide(st.c_str());
// remove all escape chars ('\\')
std::remove(ignoredprops.begin(), ignoredprops.end(), '\\');
break;

}

作者意囑ֈ除所?\\'Q但他用错了函数Qremove函数只是交换元素的位|?/span>Q将要删除的元素交换到尾部trashQƈ且返回指向trash首地址的iterator。正的做法应该?span style="color: red">"v.erase(remove(v.begin(), v.end(), 2), v.end())"?/span>

[#5] Pixie目 – 在@环中使用alloca函数

inline  void  triangulatePolygon(…) {

for (i=1;i<nloops;i++) {

do {

do {

CTriVertex  *snVertex =
(CTriVertex *)alloca(2*sizeof(CTriVertex));

} while(dVertex != loops[0]);

} while(sVertex != loops[i]);

}

}

alloca函数在栈上分配内存,因此在@环中使用alloca可能会很快导致栈溢出?/span>

七、无意义的代?/strong>

[#1] IPP Samples目 – 不完整的条g

void lNormalizeVector_32f_P3IM(Ipp32f *vec[3],
Ipp32s* mask, Ipp32s len)
{
Ipp32s  i;
Ipp32f  norm;

for(i=0; i<len; i++) {
if(mask<0) continue;
norm = 1.0f/sqrt(vec[0][i]*vec[0][i]+
vec[1][i]*vec[1][i]+vec[2][i]*vec[2][i]);
vec[0][i] *= norm; vec[1][i] *= norm; vec[2][i] *= norm;
}
}

mask是Ipp32scd指针Q这?span style="color: red">if (mask< 0)q句代码昄没啥意义Q正的代码应该是:

if (mask[i] < 0) continue;

[#2] QT目 – 重复的检?/p>

Q3TextCustomItem* Q3TextDocument::parseTable(…)
{

while (end < length
&& !hasPrefix(doc, length, end, QLatin1String("</td"))
&& !hasPrefix(doc, length, end, QLatin1String("<td"))
&& !hasPrefix(doc, length, end, QLatin1String("</th"))
&& !hasPrefix(doc, length, end, QLatin1String("<th"))
&& !hasPrefix(doc, length, end, QLatin1String("<td"))
&& !hasPrefix(doc, length, end, QLatin1String("</tr"))
&& !hasPrefix(doc, length, end, QLatin1String("<tr"))
&& !hasPrefix(doc, length, end, QLatin1String("</table"))) {


}

q里?<td"做了两次check?/p>

八、LTrue或False的条?/strong>

[#1] Shareaza目 – charcd的D?/span>

void CRemote::Output(LPCTSTR pszName)
{


CHAR* pBytes = new CHAR[ nBytes ];
hFile.Read( pBytes, nBytes );

if ( nBytes > 3 && pBytes[0] == 0xEF &&
pBytes[1] == 0xBB && pBytes[2] == 0xBF )
{
pBytes += 3;
nBytes -= 3;
bBOM = true;
}

}

表达?pBytes[0] == 0xEF"LFalse。charcd的D围是-128~127 < 0xEFQ因此这个表辑ּLFalseQ导致整个if conditionL为FalseQ与预期逻辑不符?/p>

[#3] VirtualDub目 – 无符L型L>=0

typedef unsigned short wint_t;

void lexungetc(wint_t c) {
if (c < 0)
return;
g_backstack.push_back(c);
}

c是unsigned shortcdQ永q不会小?,也就是说if (c < 0)永远为False?/p>

[#8] MySQL目 – 条g错误

enum enum_mysql_timestamp_type
str_to_datetime(…)
{

else if (str[0] != ‘a’ || str[0] != 'A')
continue; /* Not AM/PM */

}

if (str[0] != ‘a’ || str[0] != 'A')q个条g永远为真。也许这块本意是想用&&?/span>

九、代码漏z?/strong>

D漏洞的代码错误实际上也都是笔误、不正确的条件以及不正确的数l操作等。但q里q是惛_一些特定错误划归ؓ一c,因ؓ入R者可以利用这些错误来d你的代码Q获取其利益?/p>

[#1] Ultimate TCP/IP目 – I字W串的错误检?/p>

char *CUT_CramMd5::GetClientResponse(LPCSTR ServerChallenge)
{

if (m_szPassword != NULL)
{

if (m_szPassword != '\0')
{

}

W二个if condition check意图查m_szPassword是否为空字符Ԍ但却错误的将指针?\0'q行比较Q正的代码应该是这LQ?/p>

if (*m_szPassword != '\0')

[#2] Chromium目 – NULL指针的处?/p>

bool ChromeFrameNPAPI::Invoke(…)
{
ChromeFrameNPAPI* plugin_instance =
ChromeFrameInstanceFromNPObject(header);
if (!plugin_instance &&
(plugin_instance->automation_client_.get()))
return false;

}

一旦plugin_instance为NULLQ?plugin_instance为TrueQ代码对&&后面的子条g求|引用plugin_instance导致程序崩溃。正的做法应该是:

if (plugin_instance &&
(plugin_instance->automation_client_.get()))
return false;

[#5] Apache httpd Server目 – 不完整的~冲区clear

#define MEMSET_BZERO(p,l)       memset((p), 0, (l))

void apr__SHA256_Final(…, SHA256_CTX* context) {

MEMSET_BZERO(context, sizeof(context));

}

q个错误前面提到q,sizeof(context)只是指针的大,之改ؓsizeof(*context)OK了?/p>

[#7] PNG Library目 – 意外的指针clear

png_size_t
png_check_keyword(png_structp png_ptr, png_charp key,
png_charpp new_key)
{

if (key_len > 79)
{
png_warning(png_ptr, "keyword length must be 1 – 79 characters");
new_key[79] = '\0';
key_len = 79;
}

}

new_key的类型ؓpng_charppQ顾名思义Q这是一个char**cdQ但代码中new_key[79] = ‘\0′q句昄是要l某个char赋|但new_key[n]得到的应该是一个地址Q给一个地址赋gؓ’\0′昄是有误的。正的写法应该?*new_key)[79] = '\0'?/span>

[#10] Miranda IM目 – 保护没生?/p>

void Append( PCXSTR pszSrc, int nLength )
{

UINT nOldLength = GetLength();
if (nOldLength < 0)
{
// protects from underflow
nOldLength = 0;
}

}

nOldLength椒UINTcdQ?span style="color: red">其值永q不会小?,因此if (nOldLength < 0)q行成了摆设?/span>

[#12] Ultimate TCP/IP目 – 不正的循环l束条g

void CUT_StrMethods::RemoveSpaces(LPSTR szString) {

size_t loop, len = strlen(szString);
// Remove the trailing spaces
for(loop = (len-1); loop >= 0; loop–) {
if(szString[loop] != ' ')
break;
}

}

?span style="color: red">环中的结束条件loop >= 0永qؓTrueQ因为loop变量的类型是size_t是unsignedcdQ永q不会小??/span>

十、拷贝粘?/strong>

和笔误不同,E序员们决不因该低估拯_脓问题Q这c问题发生了太多。程序员们花费了大量旉在这些问题的debug上?/p>

[#1] Fennec Media Project目 – 处理数组元素时出?/p>

void* tag_write_setframe(char *tmem,
const char *tid, const string dstr)
{

if(lset)
{
fhead[11] = '\0';
fhead[12] = '\0';
fhead[13] = '\0';
fhead[13] = '\0';
}

}

 

咋看一下,fhead[13]做了两次赋|g没啥问题。但仔细想一下,最后那行程序员的原意极可能是想写fhead[14] = '\0'。问题就在这里了?/p>

[#2] MySQL目 – 处理数组元素时出?/p>

static int rr_cmp(uchar *a,uchar *b)
{
if (a[0] != b[0])
return (int) a[0] – (int) b[0];
if (a[1] != b[1])
return (int) a[1] – (int) b[1];
if (a[2] != b[2])
return (int) a[2] – (int) b[2];
if (a[3] != b[3])
return (int) a[3] – (int) b[3];
if (a[4] != b[4])
return (int) a[4] – (int) b[4];
if (a[5] != b[5])
return (int) a[1] – (int) b[5];
if (a[6] != b[6])
return (int) a[6] – (int) b[6];
return (int) a[7] – (int) b[7];
}

 

~写q类代码Ӟ我猜l大多数Z选择Copy-PasteQ然后再逐行修改Q问题就发生在修改过E中Q上面的代码中当处理a[5] != b[5]时就忘记修改一个下标了Qreturn (int) a[1] – (int) b[5];昄q里的正代码应该是return (int) a[5] – (int) b[5]?/p>

[#3] TortoiseSVN目 文g名不正确

BOOL GetImageHlpVersion(DWORD &dwMS, DWORD &dwLS)
{
return(GetInMemoryFileVersion(("DBGHELP.DLL"),
dwMS,
dwLS)) ;
}

BOOL GetDbgHelpVersion(DWORD &dwMS, DWORD &dwLS)
{
return(GetInMemoryFileVersion(("DBGHELP.DLL"),
dwMS,
dwLS)) ;
}

GetImageHlpVersion和GetDbgHelpVersion都用了"DBGHELP.DLL"文gQ显然GetImageHlpVersion写错文g名了。应该用"IMAGEHLP.DLL"对了?/span>

[#4] Clang目 – {同的函C

MapTy PerPtrTopDown;
MapTy PerPtrBottomUp;

void clearBottomUpPointers() {
PerPtrTopDown.clear();
}

void clearTopDownPointers() {
PerPtrTopDown.clear();
}

我们看到虽然两个函数名不同,但是函数体的内容是相同的Q显然又是copy-paste惹的。做如下修改卛_Q?/p>

void clearBottomUpPointers() {
PerPtrBottomUp.clear();
}

 

十一、Null指针的校验迟?/strong>

q里?#8220;q了”的含义是先用指针,然后再校验指针是否ؓNULL?/p>

[#1] Quake-III-Arena目 – 校验q了

void Item_Paint(itemDef_t *item) {
vec4_t red;
menuDef_t *parent = (menuDef_t*)item->parent;
red[0] = red[3] = 1;
red[1] = red[2] = 0;
if (item == NULL) {
return;
}

}

 

?span style="color: red">校验item是否为NULL前已l用过item了,一旦item真的为NULLQ那E序必然崩溃?/span>

十二、其他杂?/strong>

[#1] Image Processing 目 – 八进制数

inline
void elxLuminocity(const PixelRGBus& iPixel,
LuminanceCell< PixelRGBus >& oCell)
{
oCell._luminance = uint16(0.2220f*iPixel._red +
0.7067f*iPixel._blue + 0.0713f*iPixel._green);
oCell._pixel = iPixel;
}

inline
void elxLuminocity(const PixelRGBi& iPixel,
LuminanceCell< PixelRGBi >& oCell)
{
oCell._luminance = 2220*iPixel._red +
7067*iPixel._blue + 0713*iPixel._green;
oCell._pixel = iPixel;
}

W二个函敎ͼE序员原意是使用713q个十进制整敎ͼ?713 != 713Q在C中,0713是八q制的表C法QCompiler会认是个八进制数?/p>

[#2] IPP Sample工程 – 一个变量用于两个loop?/p>

JERRCODE CJPEGDecoder::DecodeScanBaselineNI(void)
{

for(c = 0; c < m_scan_ncomps; c++)
{
block = m_block_buffer + (DCTSIZE2*m_nblock*(j+(i*m_numxMCU)));

// skip any relevant components
for(c = 0; c < m_ccomp[m_curr_comp_no].m_comp_no; c++)
{
block += (DCTSIZE2*m_ccomp

[/c]

.m_nblocks);
}

}

变量c用在了两个loop中,q会D只有部分数据被处理,或外部@环中止?/p>

[#3] Notepad++目 – 怪异的条件表辑ּ

int Notepad_plus::getHtmlXmlEncoding(….) const
{

if (langT != L_XML && langT != L_HTML && langT == L_PHP)
return -1;

}

代码中的那行if条g{h?span style="color: red"> if (langT == L_PHP)Q显然似乎不是作者原意,猜测正确的代码应该是q样的:

int Notepad_plus::getHtmlXmlEncoding(….) const
{

if (langT != L_XML && langT != L_HTML && langT != L_PHP)
return -1;

}



郭龙 2013-05-19 21:10 发表评论
]]>
【{】字W串查找法ȝhttp://www.shnenglu.com/glxhyt/archive/2013/05/19/200403.html郭龙郭龙Sun, 19 May 2013 08:58:00 GMThttp://www.shnenglu.com/glxhyt/archive/2013/05/19/200403.htmlhttp://www.shnenglu.com/glxhyt/comments/200403.htmlhttp://www.shnenglu.com/glxhyt/archive/2013/05/19/200403.html#Feedback0http://www.shnenglu.com/glxhyt/comments/commentRss/200403.htmlhttp://www.shnenglu.com/glxhyt/services/trackbacks/200403.html
【{?a >http://hi.baidu.com/w01fer/item/170353ec82f547225b2d6402

字符串匹配:

---willamette

在匹配串中寻找模式串是否出现Q注意和最长公共子序列相区?LCS: Longest Common Substring)

最单的Brute Force法Q?/p>

首先匹配串和模式串左对齐,然后从左向右一个一个进行比较,如果不成功则模式串向右移动一个单位?/p>

速度最慢?/p>

那么Q怎么改进呢?

我们注意到Brute Force法是每ơ移动一个单位,一个一个单位移动显然太慢,是不是可以找C些办法,让每ơ能够让模式串多Ud一些位|呢Q?/p>

当然是可以的?/p>

我们也注意到QBrute Force是很不intelligent的,每次匚w不成功的时候,前面匚w成功的信息都被当作废物丢弃了Q当Ӟ如现在的变废ؓ宝一P我们也同样可以将前面匚w成功的信息利用v来,极大地减计机的处理时_节省成本。^_^

首先介绍的就是KMP法?/p>

原始论文QKnuth D.E., Morris J.H., and Pratt V.R., Fast pattern matching in strings, SIAM Journal on Computing, 6(2), 323-350, 1977.

q个法实在是太有名了,大学上的法评除了最W的Brute Force法Q然后就介绍了KMP法。也难怪,呵呵。谁让Knuth D.E.q么world famous呢,不仅拿了囄奖,而且q写Z计算机界的Bible <The Art of Computer Programming>(业内人士一般简UTAOCP).E稍提一下,有个叫H.A.Simon的家伙,不仅拿了Turing AwardQ顺手拿了个Nobel Economics AwardQ做了AI的爸爸,q是Chicago Univ的Politics PhDQ可谓全才?/p>

KMP的思想是这LQ?/p>

利用不匹配字W的前面那一D字W的最长前后缀来尽可能地蟩q最大的距离

比如

模式串ababacq个时候我们发现在c处不匚wQ然后我们看c前面那串字符串的最大相{前后缀Q然后再来移?/p>

下面的两个都是模式串Q没有写出来匚w?/p>

原始位置ababac

Ud之后 ababac

因ؓ后缀是已l匹配了的,而前~和后~是相{的Q所以直接把前缀Ud到原来后~处,再从原来的c处,也就是现在的W二个b处进行比较。这是KMP?/p>

当然Q有市场有竞争Q字W串匚wq么大一个市场,不可能让BF和KMP全部占了Q于是又出现了几个强劲的Ҏ?/p>

W一个登场的是Horspool法?/p>

论文QHorspool R.N., 1980, Practical fast searching in strings, Software - Practice & Experience, 10(6):501-506

Horspool法的思想很简单的。不q有个创C处就是模式串是从叛_左进行比较的。很好很强大Qؓ后来的算法媄响很大?/p>

匚wԌabcbcsdxzcxx

模式Ԍcbcac

q个时候我们从叛_左进行对暗号Qc-cQ恩对上了,W二个b-aQ不对啊Q我们应该怎么办?Np么放弃么。于是,模式串从不匹配的那个字符开始从叛_左寻扑֌配串中不匚w的字Wb的位|,l果发现居然有,赶快对上赶快对上Q别耽误了?/p>

匚wԌabcbcsdxzcxx

模式Ԍ cbcac

然后l箋从最双的字W从叛_左进行比较。这时候,我们发现了,d-c不匹配啊Q而且模式IK面没有噢Q没办法Q只好移动一个模式串长度的单位了?/p>

匚wԌabcbcsdxzcxx

模式Ԍ cbcac

W二个上来的是Boyer-Moore法?/p>

是一个很复杂的算法,当然Q虽然理Z旉复杂度和KMP差不多,但是实际上却比KMP快数倍,可见实践是检验真理的唯一标准?/p>

原始论文QR.S.Boyer, J.S.Moore, A fast string searching algorithm , Communications of the ACM,20(10):762-772 ,1977

分ؓ两步预处理,W一个是bad-character heuristicsQ也是当出现错误匹配的时候,UMQ基本上是做的Horspool那一套?/p>

W二个就是good-suffix heuristicsQ当出现错误匚w的时候,我还要从不匹配点向左看啊Q以前匹配的那段子字W串是不是在模式串本w中q有重复的啊Q有重复的话Q那么我q接把重复的那D和匚w串中已经匚w的那一D对齐就是了。再比较

匚wԌabaccbabbazz

模式Ԍcbadcba

我们看到已经匚w好了cbaQ但是c-d不匹配,q个时候我们发现既可以采用bad-character heuristicsQ也可以使用good-suffix heuristics(模式Ԍcbadcba)Q在q种情况下,邪不压正。毅然投奔good。移动得?/p>

匚wԌabaccbabbazz

模式Ԍ cbadcba

可是Q我们有时候也发现Q已l匹配好的那一部分其实q没有再有重复了的啊。这个时候,我们发现已经匚w好的那串字符串有一部分在开头重新出CQ那么,赶快Q对齐吧?/p>

匚wԌabacccbbbazz

模式Ԍcbadccb

然后得到

匚wԌabacccbbbazz

模式Ԍ cbadccb

当两UGood-Suffix出现的时候,取移动距L大的那个?/p>

最后一个是Sunday法Q实际上比Boyer-Mooreq快Q呵c长江后推前浪?/p>

原始论文QDaniel M. Sunday, A very fast substring search algorithm, Communications of the ACM, v.33 n.8, p.132-142, Aug. 1990

看原始论文的题目QD.M. Sunday貌似是故意想气气Boyer-Moore两位大牛似的。呵c不q实际上的确Sunday法的确比BM法要快Q而且更简单?/p>

Sunday的算法思想和Horspool有些怼Q但是。当出现不匹配的时候,却不是去扑֌配串中不匚w的字W在模式串的位置Q而是直接找最双寚w的右一位的那个字符在模式串的位|?/p>

比如Q?/p>

匚wԌabcbczdxzc

模式Ԍzbcac

恩,q里我们看到b-a没有对上Q我们就看匹配串中的z在模式串的位|,然后Q嘿ѝ?/p>

匚wԌabcbczdxzc

模式Ԍ zbcac

如果模式串中的没有那个字W怎么办呢Q很单,跌d?/p>

匚wԌabcbcedxzcs

模式Ԍzbcac

e不在模式串中出现

那么我们?/p>

匚wԌabcbcedxzcs

模式Ԍ zbcac

 

实际上,现在q有很多很多字符串匹配算法,q里只是单介l了一下最怋用的五种法Q更多算法可以参考一?a >http://www.inf.fh-flensburg.de/lang/algorithmen/algo.htmQ?q这个是h|站Q有的网|有英文版的哦?/p>



郭龙 2013-05-19 16:58 发表评论
]]>
自己工作中犯的几个小问题http://www.shnenglu.com/glxhyt/archive/2012/05/15/175035.html郭龙郭龙Tue, 15 May 2012 15:27:00 GMThttp://www.shnenglu.com/glxhyt/archive/2012/05/15/175035.htmlhttp://www.shnenglu.com/glxhyt/comments/175035.htmlhttp://www.shnenglu.com/glxhyt/archive/2012/05/15/175035.html#Feedback3http://www.shnenglu.com/glxhyt/comments/commentRss/175035.htmlhttp://www.shnenglu.com/glxhyt/services/trackbacks/175035.html1Q指针问?
错误代码Q?br />//A.cpp
T gTemp;
void GetA(T *p)
{
   p = &gTemp;
}

//B.cpp
T iInfo;
GetA(&iInfo);
或?br />T *piInfo;
GetA(piInfo);

正确的是
//A.cpp
T gTemp;
T* GetA()
{
  return &gTemp;
}

//B.cpp
T *piInfo = GetA();

解决ҎQ?br /><<你必ȝ道的495个C语言问题>>
5.4 我有个函?它应该接受ƈ初始化一个指?void f(int *ip) { static int dummy = 5; ip = &dummy;} 但是当我如下调用? int *ip; f(ip); 调用者的指针却没有Q何变化?你确定函数初始化的是你希望它初始化的东西吗?误住在 C ? 参数是通过g递的。被调函C仅修改了传入的指针副本。你需要传入指针的地址 (函数变成接受指针的指?, 或者让函数q回指针?


同理下面也是错误?br />void Swap(T* rht, T* lht)
{
T *pTemp = rht;
rht = lht;
lht = pTemp;
}

2: 计算法旉问题

start = beginTime();
for (int i = 0; i < 100; ++ i)
   for (int j = 0; j < 1000; ++ j)
{
      //转化函数Q?/span>
      A......
      //法
      B.......
}

End = beginTime();

错误地方QA....p2毫秒

   l果试出现很大问题Q?br />   A....p两毫U?br />   100*1000*2 = 200s = 3.3分钟

 修改ҎQ?br /> 
   //转化函数Q?/span>
   A......
   攑֜外面q行转化
   

   start = beginTime();
   for (int j = 0; j < 1000; ++ j)
   {
      //转化函数Q?/span>
     A......
   }

   for (int i = 0; i < 100; ++ i)
      for (int j = 0; j < 1000; ++ j)
   {
      //法
      B.......
   }

  End = beginTime();

3: Hash 法

4Qfor(u_short i = 100; i >= 0; --i)
   修改Q?br />     for (u_short i = 100; i > 0; --i)
     for(int i = 100; i >= 0; --i)

5Q读写文Ӟ 发送消息,最好定义一个头,那样
   Ҏ知道d的是什么,d的是否错?br /> // 消息?br /> struct TMSG_HEADER
 {
  char    cMsgID;   // 消息标识

  TMSG_HEADER(char MsgID = INVALID_MSG)
   : cMsgID(MsgID)
  {
  }
 };


 // h传送的文g?br /> // 客户端传l服务器端的是全路径名称
 // 服务器传回给客户端的是文件名
 struct TMSG_FILENAME : public TMSG_HEADER
 {
  char szFileName[256];  // 保存文g名的字符数组

  TMSG_FILENAME()
   : TMSG_HEADER(MSG_FILENAME)
  {
  }
 };

 // 传送文仉?br /> struct TMSG_FILELENGTH : public TMSG_HEADER
 {
  long lLength;

  TMSG_FILELENGTH(long length)
   : TMSG_HEADER(MSG_FILELENGTH), lLength(length)
  {

  }
 };


累了Q以后再写吧Q?#8598;(^ω^)↗


郭龙 2012-05-15 23:27 发表评论
]]>
无题http://www.shnenglu.com/glxhyt/archive/2012/02/06/165058.html郭龙郭龙Mon, 06 Feb 2012 15:09:00 GMThttp://www.shnenglu.com/glxhyt/archive/2012/02/06/165058.htmlhttp://www.shnenglu.com/glxhyt/comments/165058.htmlhttp://www.shnenglu.com/glxhyt/archive/2012/02/06/165058.html#Feedback0http://www.shnenglu.com/glxhyt/comments/commentRss/165058.htmlhttp://www.shnenglu.com/glxhyt/services/trackbacks/165058.html2012 目标

1.
学一U脚本语a python
学习一下数据结? l习~程之美

2.
学习|络通信
看书自学

3.
研读CppUnit自动化测?br />学习交叉~译环境


复习d学习的Linux知识 C/C++知识
复习工作中ȝ点点滴滴



郭龙 2012-02-06 23:09 发表评论
]]>
链表l习(1)--FindMax Sumhttp://www.shnenglu.com/glxhyt/archive/2011/11/27/161042.html郭龙郭龙Sun, 27 Nov 2011 13:05:00 GMThttp://www.shnenglu.com/glxhyt/archive/2011/11/27/161042.htmlhttp://www.shnenglu.com/glxhyt/comments/161042.htmlhttp://www.shnenglu.com/glxhyt/archive/2011/11/27/161042.html#Feedback0http://www.shnenglu.com/glxhyt/comments/commentRss/161042.htmlhttp://www.shnenglu.com/glxhyt/services/trackbacks/161042.html  1#include <iostream>  2using namespace std; &...  阅读全文

郭龙 2011-11-27 21:05 发表评论
]]>
链表http://www.shnenglu.com/glxhyt/archive/2011/11/27/161031.html郭龙郭龙Sun, 27 Nov 2011 08:02:00 GMThttp://www.shnenglu.com/glxhyt/archive/2011/11/27/161031.htmlhttp://www.shnenglu.com/glxhyt/comments/161031.htmlhttp://www.shnenglu.com/glxhyt/archive/2011/11/27/161031.html#Feedback0http://www.shnenglu.com/glxhyt/comments/commentRss/161031.htmlhttp://www.shnenglu.com/glxhyt/services/trackbacks/161031.html阅读全文

郭龙 2011-11-27 16:02 发表评论
]]>
[转]gdb调试正在q行的进E?/title><link>http://www.shnenglu.com/glxhyt/archive/2011/11/27/161017.html</link><dc:creator>郭龙</dc:creator><author>郭龙</author><pubDate>Sat, 26 Nov 2011 16:22:00 GMT</pubDate><guid>http://www.shnenglu.com/glxhyt/archive/2011/11/27/161017.html</guid><wfw:comment>http://www.shnenglu.com/glxhyt/comments/161017.html</wfw:comment><comments>http://www.shnenglu.com/glxhyt/archive/2011/11/27/161017.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.shnenglu.com/glxhyt/comments/commentRss/161017.html</wfw:commentRss><trackback:ping>http://www.shnenglu.com/glxhyt/services/trackbacks/161017.html</trackback:ping><description><![CDATA[<div id="9lnv99v" class="tit">[转自] <a >http://hi.baidu.com/brady_home/blog/item/6b92aa8ffdfee2e6f01f369b.html</a><br /><br />gdb调试正在q行的进E?/div> <div id="dxld797" class="date">2009q?4?8?星期?下午 08:21</div> <table style="width: 100%; table-layout: fixed"> <tbody> <tr> <td> <div class="pz9zjv9" id="blog_text" class="cnt">有时会遇CU很Ҏ的调试需求,对当前正在运行的其它q程q行调试Q正是我今天遇到的情形)。这U情冉|可能发生在那些无法直接在调试器中q行的进En上,例如有的q程 只能在系l启动时q行。另外如果需要对q程产生的子q程q行调试的话Q也只能采用q种方式。GDB可以Ҏ在执行的E序q行调度Q它允许开发h员中断程?q查看其状态,之后q能让这个程序正常地l箋执行?<br /><br />GDB提供了两U方式来调试正在q行的进E:一U是在GDB命o行上指定q程的PIDQ另一U是在GDB中?#8220;attach”命o。例如,开发h员可以先启动debugmeE序Q让其开始等待用L输入。示例如下: <br /><br /><ccid_nobr> <table border="1" cellspacing="0" bordercolorlight="black" bordercolordark="#ffffff" cellpadding="2" width="400" align="center"> <tbody> <tr> <td style="font-size: 9pt" class="code" bgcolor="#e6e6e6"><pre><ccid_code>#./debugme<br /> Enter a string to count words:</ccid_code></pre></td></tr></tbody></table></ccid_nobr><br /><br />接下d另一个虚拟控制台中用下面的命令查q程对应的进E号Q?<br /><br /><ccid_nobr> <table border="1" cellspacing="0" bordercolorlight="black" bordercolordark="#ffffff" cellpadding="2" width="400" align="center"> <tbody> <tr> <td style="font-size: 9pt" class="code" bgcolor="#e6e6e6"><pre><ccid_code># ps -ax | grep debugme<br /> 555 pts/1 S 0:00 ./debugme</ccid_code></pre></td></tr></tbody></table></ccid_nobr><br /><br />得到q程的PID后,可以用GDB对其q行调试了: <br /><br /><ccid_nobr> <table border="1" cellspacing="0" bordercolorlight="black" bordercolordark="#ffffff" cellpadding="2" width="400" align="center"> <tbody> <tr> <td style="font-size: 9pt" class="code" bgcolor="#e6e6e6"><pre><ccid_code># gdb debugme 555<br /> GNU gdb Red Hat Linux (5.3post-0.20021129.18rh)<br /> Attaching to program: /home/xiaowp/debugme, process 555<br /> Reading symbols from /lib/libc.so.6...done.<br /> ……</ccid_code></pre></td></tr></tbody></table></ccid_nobr><br /><br />在上面的输出信息中,以Attaching to program开始的行表明GDB已经成功地附加在PID?55的进E上了。另外一U连接到其它q程的方法是先用file命o加蝲调试时所需的符可Q然后再通过“attaché”命oq行q接Q?<br /><br /><ccid_nobr> <table border="1" cellspacing="0" bordercolorlight="black" bordercolordark="#ffffff" cellpadding="2" width="400" align="center"> <tbody> <tr> <td style="font-size: 9pt" class="code" bgcolor="#e6e6e6"><pre><ccid_code>(gdb) file /home/xiaowp/debugme<br /> Reading symbols from /home/xiaowp/debugme...done.<br /> (gdb) attach 555<br /> ……</ccid_code></pre></td></tr></tbody></table></ccid_nobr><br /><br />如果想知道程序现在运行到了哪里,同样可以使用“backtrace”命o。当然也可以使用“step”命o对程序进行单步调试?<br /><br />在完成调试之后,不要忘记用detach命o断开q接Q让被调试的q程可以l箋正常q行?/div></td></tr></tbody></table><img src ="http://www.shnenglu.com/glxhyt/aggbug/161017.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.shnenglu.com/glxhyt/" target="_blank">郭龙</a> 2011-11-27 00:22 <a href="http://www.shnenglu.com/glxhyt/archive/2011/11/27/161017.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>[转]二维指针和二U指?/title><link>http://www.shnenglu.com/glxhyt/archive/2011/11/26/161015.html</link><dc:creator>郭龙</dc:creator><author>郭龙</author><pubDate>Sat, 26 Nov 2011 15:41:00 GMT</pubDate><guid>http://www.shnenglu.com/glxhyt/archive/2011/11/26/161015.html</guid><wfw:comment>http://www.shnenglu.com/glxhyt/comments/161015.html</wfw:comment><comments>http://www.shnenglu.com/glxhyt/archive/2011/11/26/161015.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.shnenglu.com/glxhyt/comments/commentRss/161015.html</wfw:commentRss><trackback:ping>http://www.shnenglu.com/glxhyt/services/trackbacks/161015.html</trackback:ping><description><![CDATA[[转自]<a >http://www.wutianqi.com/?p=1822</a><br /><br /> <h1 class="entry-title"><a rel="bookmark"><font color="#313428">二维数组和二U指针的传递问?/font></a></h1> <div id="7fjtb99" class="entry-info"> <div id="vlhd9pl" class="entry-author"><strong>By </strong> <address class="author vcard"><a class="url fn n" title="Tanky Woo" ><strong><font color="#666666">Tanky Woo</font></strong></a></address></div>– <abbr class="published" title="2010-12-21T15:37:36+00:00">2010q?2?1?/abbr><span id="jzdxtfb" class="entry-cat"><strong>Posted in: </strong><a ><font color="#666666">C/C++~程</font></a></span></div> <div id="zx99blh" class="entry-content clearfix"> <p>再次看这文章,感觉说的好多都是废话Q在文章最前面补充一句话Q?br />“<strong><code><font style="background-color: #eaeaea" size="2">[]的优先高于*</font></code></strong>”Q大家可以带着q句话看下面的~~~<br />========================<br />再一ơ的见证了自q基础不牢靠。。。幸好发现得早,看见|上_华ؓ的一个面试题p了q个斚w的?/p> <p>借那道华为的面试题引出问题,题目Q?/p> <p><strong>char **p, a[16][8]; 问:p=a是否会导致程序在以后出现问题Qؓ什么?</strong></p> <p>可能有一部分朋友会回{正,q里他们认ؓQa[]是一U指针,a[][]是二指针。那q个到底对不对呢Q?br /><span id="more-1822"></span><br />OKQ用事实说话Q?/p> <div style="padding-bottom: 0px" class="wp_syntax"> <table> <tbody> <tr> <td class="line_numbers"><pre>1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 </pre></td> <td class="code"><pre style="font-family: monospace" class="cpp"><span style="color: #666666">// Author: Tanky Woo</span> <span style="color: #666666">// Blog: www.WuTianQi.com</span> <span style="color: #666666">// Note: 验证二维数组与二U指针的传递问?/span> <span style="color: #339900">#include <iostream> </span> <span style="color: #0000ff">using</span> <span style="color: #0000ff">namespace</span> std<span style="color: #008080">;</span> <span style="color: #0000ff">void</span> Test<span style="color: #008000">(</span><span style="color: #0000ff">char</span> <span style="color: #000040">**</span>p<span style="color: #008000">)</span> <span style="color: #008000">{</span> <span style="color: #0000dd">cout</span> <span style="color: #000080"><<</span> p<span style="color: #008000">[</span><span style="color: #0000dd">0</span><span style="color: #008000">]</span><span style="color: #008000">[</span><span style="color: #0000dd">0</span><span style="color: #008000">]</span> <span style="color: #000080"><<</span> endl<span style="color: #008080">;</span> <span style="color: #008000">}</span> <span style="color: #0000ff">int</span> main<span style="color: #008000">(</span><span style="color: #008000">)</span> <span style="color: #008000">{</span> <span style="color: #0000ff">char</span> a<span style="color: #008000">[</span><span style="color: #0000dd">2</span><span style="color: #008000">]</span><span style="color: #008000">[</span><span style="color: #0000dd">3</span><span style="color: #008000">]</span><span style="color: #008080">;</span> Test<span style="color: #008000">(</span>a<span style="color: #008000">)</span><span style="color: #008080">;</span> <span style="color: #0000ff">return</span> <span style="color: #0000dd">0</span><span style="color: #008080">;</span> <span style="color: #008000">}</span></pre></td></tr></tbody></table></div> <p>l果报错Q?/p> <div style="padding-bottom: 15px" class="wp_syntax"> <table> <tbody> <tr> <td class="line_numbers"><pre>1 2 </pre></td> <td class="code"><pre style="font-family: monospace" class="cpp"><span style="color: #666666">// error C2664: “Test”: 不能参?1 ?#8220;char [2][3]”转换?#8220;char **”</span> <span style="color: #666666">// 与指向的cd无关Q{换要?reinterpret_cast、C 样式转换或函数样式{?/span></pre></td></tr></tbody></table></div> <p>于是乎,我看了下《C专家~程》里10.5?#8212;<a target="_blank"><font color="#313428">使用指针向函C递一个多l数l?/font></a>Q?/p> <p><strong>Ҏ一Q?/strong></p> <p>函数?</p> <div style="padding-bottom: 0px" class="wp_syntax"> <table> <tbody> <tr> <td class="line_numbers"><pre>1 </pre></td> <td class="code"><pre style="font-family: monospace" class="cpp"><span style="color: #0000ff">void</span> fun1<span style="color: #008000">(</span><span style="color: #0000ff">int</span> arr<span style="color: #008000">[</span><span style="color: #0000dd">2</span><span style="color: #008000">]</span><span style="color: #008000">[</span><span style="color: #0000dd">3</span><span style="color: #008000">]</span><span style="color: #008000">)</span><span style="color: #008080">;</span></pre></td></tr></tbody></table></div> <p>q种ҎD只能处理2?列的int型数l?/p> <p><strong>Ҏ二:</strong></p> <p>可以省略W一l的长度?/p> <p>函数是:</p> <div style="padding-bottom: 0px" class="wp_syntax"> <table> <tbody> <tr> <td class="line_numbers"><pre>1 </pre></td> <td class="code"><pre style="font-family: monospace" class="cpp"><span style="color: #0000ff">void</span> fun2<span style="color: #008000">(</span><span style="color: #0000ff">int</span> arr<span style="color: #008000">[</span><span style="color: #008000">]</span><span style="color: #008000">[</span><span style="color: #0000dd">3</span><span style="color: #008000">]</span><span style="color: #008000">)</span><span style="color: #008080">;</span></pre></td></tr></tbody></table></div> <p>q种Ҏ的限制略微宽松了一些,但是q是只能处理每行?个整数长度的数组?/p> <p>函数也可以写?</p> <div style="padding-bottom: 0px" class="wp_syntax"> <table> <tbody> <tr> <td class="line_numbers"><pre>1 </pre></td> <td class="code"><pre style="font-family: monospace" class="cpp"><span style="color: #0000ff">void</span> fun2_2<span style="color: #008000">(</span><span style="color: #0000ff">int</span> <span style="color: #008000">(</span><span style="color: #000040">*</span>arrr<span style="color: #008000">)</span><span style="color: #008000">[</span><span style="color: #0000dd">3</span><span style="color: #008000">]</span><span style="color: #008000">)</span><span style="color: #008080">;</span></pre></td></tr></tbody></table></div> <p><strong>Ҏ三:</strong></p> <p>创徏一个一l数l,数组中的元素是指向其他东西的指针。也可以说是二指针?/p> <p>函数?</p> <div style="padding-bottom: 0px" class="wp_syntax"> <table> <tbody> <tr> <td class="line_numbers"><pre>1 </pre></td> <td class="code"><pre style="font-family: monospace" class="cpp"><span style="color: #0000ff">int</span> fun3<span style="color: #008000">(</span><span style="color: #0000ff">int</span> <span style="color: #000040">**</span>arr<span style="color: #008000">)</span><span style="color: #008080">;</span></pre></td></tr></tbody></table></div> <p>注意Q只有把二维数组改ؓ一个指向向量的指针数组的前提下才可以这么做Q?/p> <p>比如Q?/p> <div style="padding-bottom: 0px" class="wp_syntax"> <table> <tbody> <tr> <td class="line_numbers"><pre>1 2 3 4 5 6 7 8 9 10 11 12 13 14 </pre></td> <td class="code"><pre style="font-family: monospace" class="cpp"><span style="color: #339900">#include <iostream> </span> <span style="color: #0000ff">using</span> <span style="color: #0000ff">namespace</span> std<span style="color: #008080">;</span> <span style="color: #0000ff">void</span> test<span style="color: #008000">(</span><span style="color: #0000ff">char</span> <span style="color: #000040">**</span>ptr<span style="color: #008000">)</span> <span style="color: #008000">{</span> <span style="color: #0000dd">cout</span> <span style="color: #000080"><<</span> <span style="color: #000040">*</span>ptr <span style="color: #000080"><<</span> endl<span style="color: #008080">;</span> <span style="color: #008000">}</span> <span style="color: #0000ff">int</span> main<span style="color: #008000">(</span><span style="color: #008000">)</span> <span style="color: #008000">{</span> <span style="color: #0000ff">char</span> <span style="color: #000040">*</span>p<span style="color: #008000">[</span><span style="color: #0000dd">3</span><span style="color: #008000">]</span> <span style="color: #000080">=</span> <span style="color: #008000">{</span><span style="color: #ff0000">"abc"</span>, <span style="color: #ff0000">"def"</span>, <span style="color: #ff0000">"ghi"</span><span style="color: #008000">}</span><span style="color: #008080">;</span> test<span style="color: #008000">(</span>p<span style="color: #008000">)</span><span style="color: #008080">;</span> <span style="color: #0000ff">return</span> <span style="color: #0000dd">0</span><span style="color: #008080">;</span> <span style="color: #008000">}</span></pre></td></tr></tbody></table></div> <p>在《C专家~程?0.3节的启发里讲的很透彻Q(以下q段文字及对比一定要认真分析Q)</p> <p><span style="color: #ff8000">数组和指针参数是如何被编译器修改的?</span></p> <p><span style="color: #ff8000">“<strong>数组名被改写成一个指针参?#8221;规则q不是递归定义的。数l的数组会被改写?#8220;数组的指?#8221;Q而不?#8220;指针的指?/strong>”Q?/span></p> <p><span style="color: #ff8000">实参 所匚w的Ş?/span></p> <p><span style="color: #ff8000">数组的数l?char c[8][10]; char (*)[10]; 数组指针</span></p> <p><span style="color: #ff8000">指针数组 char *c[10]; char **c; 指针的指?/span></p> <p><span style="color: #ff8000">数组指针(行指? char (*c)[10]; char (*c)[10]; 不改?/span></p> <p><span style="color: #ff8000">指针的指?char **c; char **c; 不改?/span></p> <p>我在CSDN上专门ؓq个问题提问q:</p> <p><a title="http://topic.csdn.net/u/20101221/12/da817bda-4e88-44df-bdf8-40e8f44aacb8.html?2076366575" ><font color="#313428">http://topic.csdn.net/u/20101221/12/da817bda-4e88-44df-bdf8-40e8f44aacb8.html?2076366575</font></a></p> <p>最后我ȝ下讨论结果:</p> <p>只要实参的类型与形参的类型一_或可转换Q就行?/p> <p>Z么这么说呢?</p> <p>piaojun_pj朋友l了一D代码,分析得很l力Q?/p> <div style="padding-bottom: 15px" class="wp_syntax"> <table> <tbody> <tr> <td class="line_numbers"><pre>1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 </pre></td> <td class="code"><pre style="font-family: monospace" class="cpp"><span style="color: #666666">// VectorTest.cpp : 定义控制台应用程序的入口炏V?</span> <span style="color: #666666">// </span> <span style="color: #339900">#include "stdafx.h" </span> <span style="color: #339900">#include <iostream> </span> <span style="color: #0000ff">using</span> <span style="color: #0000ff">namespace</span> std<span style="color: #008080">;</span> <span style="color: #0000ff">int</span> _tmain<span style="color: #008000">(</span><span style="color: #0000ff">int</span> argc, _TCHAR<span style="color: #000040">*</span> argv<span style="color: #008000">[</span><span style="color: #008000">]</span><span style="color: #008000">)</span> <span style="color: #008000">{</span> <span style="color: #0000ff">int</span> arr1<span style="color: #008000">[</span><span style="color: #0000dd">3</span><span style="color: #008000">]</span><span style="color: #008080">;</span> <span style="color: #0000ff">int</span> arr2<span style="color: #008000">[</span><span style="color: #0000dd">3</span><span style="color: #008000">]</span><span style="color: #008080">;</span> <span style="color: #0000ff">int</span> arr3<span style="color: #008000">[</span><span style="color: #0000dd">3</span><span style="color: #008000">]</span><span style="color: #008080">;</span> <span style="color: #0000ff">int</span> <span style="color: #000040">*</span> ptr<span style="color: #008080">;</span> <span style="color: #666666">// ptr1是一个指?int [3] 的指针,即ptr的类型和&arr1的类型是一LQ注意:arr1指向的内存区域定?</span> <span style="color: #0000ff">int</span> ptr1<span style="color: #008000">[</span><span style="color: #0000dd">3</span><span style="color: #008000">]</span><span style="color: #008000">[</span><span style="color: #0000dd">3</span><span style="color: #008000">]</span><span style="color: #000080">=</span><span style="color: #008000">{</span><span style="color: #008000">{</span><span style="color: #0000dd">1</span>,<span style="color: #0000dd">2</span>,<span style="color: #0000dd">3</span><span style="color: #008000">}</span>,<span style="color: #008000">{</span><span style="color: #0000dd">1</span>,<span style="color: #0000dd">2</span>,<span style="color: #0000dd">3</span><span style="color: #008000">}</span>,<span style="color: #008000">{</span><span style="color: #0000dd">1</span>,<span style="color: #0000dd">2</span>,<span style="color: #0000dd">3</span><span style="color: #008000">}</span><span style="color: #008000">}</span><span style="color: #008080">;</span> <span style="color: #666666">// ptr2是一个指?int * 的指针,即ptr2的类型和&ptr是一LQ注意:ptr指向的内存区域不定长 </span> <span style="color: #0000ff">int</span> <span style="color: #000040">*</span> ptr2<span style="color: #008000">[</span><span style="color: #0000dd">3</span><span style="color: #008000">]</span><span style="color: #000080">=</span><span style="color: #008000">{</span>arr1,arr2,arr3<span style="color: #008000">}</span><span style="color: #008080">;</span> <span style="color: #666666">// ptr3是一个指?int [3] 的指针,即ptr3的类型和&arr1的类型是一LQ注意:arr1指向的内存区域定?</span> <span style="color: #0000ff">int</span><span style="color: #008000">(</span><span style="color: #000040">*</span> ptr3<span style="color: #008000">)</span><span style="color: #008000">[</span><span style="color: #0000dd">3</span><span style="color: #008000">]</span><span style="color: #000080">=</span><span style="color: #000040">&</span>arr1<span style="color: #008080">;</span> ptr3<span style="color: #000080">=</span>ptr1<span style="color: #008080">;</span> <span style="color: #666666">// 没错Q他们的cd相同 </span> <span style="color: #666666">// ptr3=ptr2;//error 无法?#8220;int *[3]”转换?#8220;int (*)[3] </span> <span style="color: #666666">// ptr4是一个指?int * 的指针,即ptr4的类型和&ptr是一LQ注意:ptr指向的内存区域不定长 </span> <span style="color: #0000ff">int</span> <span style="color: #000040">**</span> ptr4<span style="color: #008080">;</span> <span style="color: #666666">//ptr4=&arr1; //error 无法?#8220;int (*)[3]”转换?#8220;int ** </span> ptr4<span style="color: #000080">=</span>ptr2<span style="color: #008080">;</span> <span style="color: #666666">// 没错Q他们的cd相同 </span> <span style="color: #666666">//ptr4=ptr3; // error 无法?#8220;int (*)[3]”转换?#8220;int ** </span> <span style="color: #0000ff">return</span> <span style="color: #0000dd">0</span><span style="color: #008080">;</span> <span style="color: #008000">}</span></pre></td></tr></tbody></table></div></div><img src ="http://www.shnenglu.com/glxhyt/aggbug/161015.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.shnenglu.com/glxhyt/" target="_blank">郭龙</a> 2011-11-26 23:41 <a href="http://www.shnenglu.com/glxhyt/archive/2011/11/26/161015.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>[转]二维数组和二U指?http://www.shnenglu.com/glxhyt/archive/2011/11/21/160668.html郭龙郭龙Mon, 21 Nov 2011 15:55:00 GMThttp://www.shnenglu.com/glxhyt/archive/2011/11/21/160668.htmlhttp://www.shnenglu.com/glxhyt/comments/160668.htmlhttp://www.shnenglu.com/glxhyt/archive/2011/11/21/160668.html#Feedback0http://www.shnenglu.com/glxhyt/comments/commentRss/160668.htmlhttp://www.shnenglu.com/glxhyt/services/trackbacks/160668.html阅读全文

郭龙 2011-11-21 23:55 发表评论
]]>
记录一下最q学习经?/title><link>http://www.shnenglu.com/glxhyt/archive/2010/10/31/131931.html</link><dc:creator>郭龙</dc:creator><author>郭龙</author><pubDate>Sun, 31 Oct 2010 14:48:00 GMT</pubDate><guid>http://www.shnenglu.com/glxhyt/archive/2010/10/31/131931.html</guid><wfw:comment>http://www.shnenglu.com/glxhyt/comments/131931.html</wfw:comment><comments>http://www.shnenglu.com/glxhyt/archive/2010/10/31/131931.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.shnenglu.com/glxhyt/comments/commentRss/131931.html</wfw:commentRss><trackback:ping>http://www.shnenglu.com/glxhyt/services/trackbacks/131931.html</trackback:ping><description><![CDATA[      ׃自己以前是学数学的,许多计算机知识都不懂Q所以学许多东西<br>时候感觉的很篏.......于是记录一下最q学习经历,一致勉p己,l箋努力Ql奋?   <br><br>     C++E序设计看到了异常,感觉真是受益匪浅Q许多东西讲的很深,于是反复看,<br>q结合effect c++Q看了两遍,q是有许多东西不懂)<br> <br>     Linux_c~程一战式学习据说是将Linux最好的书之一Q看了文Ӟq程Q线E,信号<br>     感觉讲的却是很好Q许多知识反复看了两遍,才看?...<br><br>     看到了一D|候又CUNIX环境高~程Q看了几十页Q正在l?.....<br><br>      在这其中又把林锐的c/c++ 高质量编E看了两遍,觉得指针Q内存那?br> 讲的太好了,\(^o^)/~<br>   <br>      没事随手看看C语言E序设计CҎQ和~程之美Q很不错了C<br>  语言书,和算法书?br> <br>   <img src ="http://www.shnenglu.com/glxhyt/aggbug/131931.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.shnenglu.com/glxhyt/" target="_blank">郭龙</a> 2010-10-31 22:48 <a href="http://www.shnenglu.com/glxhyt/archive/2010/10/31/131931.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss> <footer> <div class="friendship-link"> <p>лǵվܻԴȤ</p> <a href="http://www.shnenglu.com/" title="精品视频久久久久">精品视频久久久久</a> <div class="friend-links"> </div> </div> </footer> <a href="http://www.fm935.cn" target="_blank">ƷƷھþø</a>| <a href="http://www.jingzhuikang.cn" target="_blank">2022Ʒþþþ</a>| <a href="http://www.thelv.cn" target="_blank">þۺƵվ</a>| <a href="http://www.17714.com.cn" target="_blank">˳վþ99ȹ </a>| <a href="http://www.kxvd.cn" target="_blank">Ʒþþþav</a>| <a href="http://www.yiloupan.cn" target="_blank">þĻȫ</a>| <a href="http://www.mx3g.cn" target="_blank">þˬˬƬAV </a>| <a href="http://www.vanblog.cn" target="_blank">һɫþ88ۺպƷ</a>| <a href="http://www.akeyu.cn" target="_blank">ɫۺϾþþþר </a>| <a href="http://www.baaag.cn" target="_blank">þþƷަvDz</a>| <a href="http://www.loveclap.cn" target="_blank">ݺɫþۺ</a>| <a href="http://www.knjmj.cn" target="_blank">þǿdŮվ</a>| <a href="http://www.jkh7.cn" target="_blank">ձþþþĻ</a>| <a href="http://www.osgh.cn" target="_blank">ŷþۺϾɫۺ</a>| <a href="http://www.90xueyuan.cn" target="_blank">ƷŮþþm</a>| <a href="http://www.ahlgw.cn" target="_blank">Ʒþþþþþù˽ </a>| <a href="http://www.orzdream.cn" target="_blank">Ʒþۺ</a>| <a href="http://www.1985328.cn" target="_blank">ŷ˾þþƷ</a>| <a href="http://www.asook.cn" target="_blank">ĻhdþþƷ</a>| <a href="http://www.nbbook.com.cn" target="_blank">һõþۺϺݺAV</a>| <a href="http://www.shawcai.cn" target="_blank">ɫۺϾþþƷĻҳ </a>| <a href="http://www.8812345.com.cn" target="_blank">þAvԴվ</a>| <a href="http://www.pd2n.cn" target="_blank">Ʒxxxxˮ޹Ʒþһ </a>| <a href="http://www.nyvgcd.cn" target="_blank">þ޹˾Ʒɫ</a>| <a href="http://www.skjzy.cn" target="_blank">˳þõӰվ</a>| <a href="http://www.smsunion.cn" target="_blank">99þþƷһѿ </a>| <a href="http://www.uzxin.cn" target="_blank">Ʒ99þþþþè</a>| <a href="http://www.sijishi.cn" target="_blank">avھƷþþþӰԺ</a>| <a href="http://www.jia-hua.cn" target="_blank">ھƷžžþþƷ</a>| <a href="http://www.buchaqian.org.cn" target="_blank">պŮ18վþþƷ</a>| <a href="http://www.zodao.cn" target="_blank">ƷȾþþø</a>| <a href="http://www.shuntai.net.cn" target="_blank">ھƷ˾þþþ</a>| <a href="http://www.baobaonin.cn" target="_blank">þþƷëƬѹۿ</a>| <a href="http://www.hywsgc.cn" target="_blank">þùƷHDAV </a>| <a href="http://www.ode.net.cn" target="_blank">þþþ޾Ʒվ </a>| <a href="http://www.baotourcw.cn" target="_blank">þѵľƷV</a>| <a href="http://www.sun-q.cn" target="_blank">þþƷ2020</a>| <a href="http://www.qq577.cn" target="_blank">޾ƷҾþþþþ</a>| <a href="http://www.mofeigzs.cn" target="_blank">þþùҺ</a>| <a href="http://www.rolanskin.cn" target="_blank">ۺ˾þۺ</a>| <a href="http://www.bltt.net.cn" target="_blank">޹ƷƬþ</a>| <script> (function(){ var bp = document.createElement('script'); var curProtocol = window.location.protocol.split(':')[0]; if (curProtocol === 'https') { bp.src = 'https://zz.bdstatic.com/linksubmit/push.js'; } else { bp.src = 'http://push.zhanzhang.baidu.com/push.js'; } var s = document.getElementsByTagName("script")[0]; s.parentNode.insertBefore(bp, s); })(); </script> </body>