Question: 用 vc 写了个对话框程序，但是运行没反应

楼主debug调试跟一下呗

spy是什么东东

学会使用Spy++

贴上代码 #include "stdafx.h" #include <windows.h> #include <windowsx.h> #include <mmsystem.h> #include <commdlg.h> #include "resource.h" #include "MainDlg.h" TCHAR precmd[MAX_PATH+10]="";  /* Template designed by RuPeng.com. Please visit http://www.rupeng.com for more information 如鹏网（http://www.rupeng.com）大学生计算机学习社区，提供大量免费视频学习教程，提供个性化一对一学习指导 */ BOOL WINAPI Main_Proc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) {     switch(uMsg)     {         HANDLE_MSG(hWnd, WM_INITDIALOG, Main_OnInitDialog);         HANDLE_MSG(hWnd, WM_COMMAND, Main_OnCommand);         HANDLE_MSG(hWnd,WM_CLOSE, Main_OnClose);     }      return FALSE; }  BOOL Main_OnInitDialog(HWND hwnd, HWND hwndFocus, LPARAM lParam) {     TCHAR strInitTime1[10]="00:00";     TCHAR strInitTime2[10]="00:00";     SetDlgItemText(hwnd,IDC_EDIT2,strInitTime1);     SetDlgItemText(hwnd,IDC_EDIT3,strInitTime2);     return TRUE; }  void Main_OnCommand(HWND hwnd, int id, HWND hwndCtl, UINT codeNotify) {     //TCHAR precmd[MAX_PATH+10]="";     //在同一个函数中，precmd不能在case之间传递     //跟c语言不同     switch(id)     {         case IDC_OK:         {             OPENFILENAME ofn;             char szFile[MAX_PATH];             ZeroMemory(&ofn,sizeof(ofn));             ofn.lStructSize = sizeof(ofn);             ofn.lpstrFile = szFile;             ofn.lpstrFile[0] = TEXT('\0');             ofn.nMaxFile = sizeof(szFile);             ofn.lpstrFilter = TEXT("ALL\0*.*\0Text\0*.TXT\0");             ofn.nFilterIndex = 1;             ofn.lpstrFileTitle = NULL;             ofn.nMaxFileTitle = 0;             ofn.lpstrInitialDir = NULL;             ofn.hwndOwner = hwnd;//自学能力、探索能力、猜测能力             ofn.Flags = OFN_EXPLORER |OFN_PATHMUSTEXIST | OFN_FILEMUSTEXIST;             if (GetOpenFileName(&ofn))             {                 HWND hwndList=GetDlgItem(hwnd,IDC_LIST1);                 ListBox_InsertString(hwndList,-1,szFile);                              }          }         break;         case IDC_LIST1:             {                 switch (codeNotify)                 {                 case LBN_DBLCLK:                     {                         mciSendString(precmd,"",0,NULL);                         HWND hwndList=GetDlgItem(hwnd,IDC_LIST1);                         int a=ListBox_GetCurSel(hwndList);                         TCHAR str[MAX_PATH];                         ListBox_GetText(hwndList,a,str);                         TCHAR shortpath[MAX_PATH];                         GetShortPathName(str,shortpath,sizeof(shortpath));                         SetDlgItemText(hwnd,IDC_EDIT1,str);                         TCHAR playcmd[MAX_PATH+10];                         wsprintf(playcmd,"play %s",shortpath);                         mciSendString(playcmd,"",0,NULL);                                                  TCHAR statuscmd[MAX_PATH+20];                         TCHAR buf[256];                         wsprintf(statuscmd,"status %s length",shortpath);                         mciSendString(statuscmd,buf,256,NULL);                         int minute,second,iAllLength;                         TCHAR strAllTime[256];                         iAllLength=strtol(buf,NULL,0);                         minute=iAllLength/60000;                         second=(iAllLength/1000)%60;                         wsprintf(strAllTime,"%02d:%02d",minute,second);                                                  SetDlgItemText(hwnd,IDC_EDIT3,strAllTime);                                              wsprintf(precmd,"stop %s",shortpath);                     }                 break;                 }             }         break;         case IDC_BUTTON1:             {                 mciSendString(precmd,"",0,NULL);                 HWND hwndList=GetDlgItem(hwnd,IDC_LIST1);                 int a=ListBox_GetCurSel(hwndList);                 TCHAR str[MAX_PATH];                 ListBox_GetText(hwndList,a,str);                 TCHAR shortpath[MAX_PATH];                 GetShortPathName(str,shortpath,sizeof(shortpath));                 SetDlgItemText(hwnd,IDC_EDIT1,str);                 TCHAR cmd[MAX_PATH+10];                 wsprintf(cmd,"play %s",shortpath);                 mciSendString(cmd,"",0,NULL);                 wsprintf(precmd,"stop %s",shortpath);             }         break;         case IDC_BUTTON2:             {                 HWND hwndList=GetDlgItem(hwnd,IDC_LIST1);                 int a=ListBox_GetCurSel(hwndList);                 TCHAR str[MAX_PATH];                 ListBox_GetText(hwndList,a,str);                 TCHAR shortpath[MAX_PATH];                 GetShortPathName(str,shortpath,sizeof(shortpath));                 SetDlgItemText(hwnd,IDC_EDIT1,str);                 TCHAR cmd[MAX_PATH+10];                 wsprintf(cmd,"pause %s",shortpath);                 mciSendString(cmd,"",0,NULL);             }         break;         case IDC_BUTTON3:             {                 HWND hwndList=GetDlgItem(hwnd,IDC_LIST1);                 int a=ListBox_GetCurSel(hwndList);                 TCHAR str[MAX_PATH];                 ListBox_GetText(hwndList,a,str);                 TCHAR shortpath[MAX_PATH];                 GetShortPathName(str,shortpath,sizeof(shortpath));                 SetDlgItemText(hwnd,IDC_EDIT1,str);                 TCHAR cmd[MAX_PATH+10];                 wsprintf(cmd,"resume %s",shortpath);                 mciSendString(cmd,"",0,NULL);             }         break;         case IDC_BUTTON4:             {                 HWND hwndList=GetDlgItem(hwnd,IDC_LIST1);                 int a=ListBox_GetCurSel(hwndList);                 TCHAR str[MAX_PATH];                 ListBox_GetText(hwndList,a,str);                 TCHAR shortpath[MAX_PATH];                 GetShortPathName(str,shortpath,sizeof(shortpath));                 SetDlgItemText(hwnd,IDC_EDIT1,str);                 TCHAR cmd[MAX_PATH+10];                 wsprintf(cmd,"stop %s",shortpath);                 mciSendString(cmd,"",0,NULL);             }         break;         default:         break;     } }  void Main_OnClose(HWND hwnd) {     EndDialog(hwnd, 0); }


Question: 前辈们，给点建议c语言学习的方向

学习C/C++如果非计算机基础，学习起来需要付出很多，因为有很多东西理解起来需要项目经验的支撑，不是光看书就可以理解。而且你说的那几本书不全部看懂，至少要翻一遍了解基本的原理。  学完了C/C++再学其它的技术语言，会容易很多。 如果真想走这条路，就linux+c/c++ 到时候闲着有空就学习下其它语言，写几个小界面忽悠下外行。

非计算机专业自学还是建议学JAVA。

关于自己是否适合编程的很简单的测试： 在报纸或杂志上随便找一段约1000字的文章，在Word中输入一遍。输完后再参考下面答案：  A里面有10处以上文字或标点错误 B里面没有文字或标点错误并敢为此跟人打赌 C里面没有文字或标点错误并且字体和排版完全与原稿一致 D打印在半透明的纸上和原稿重叠在一起检查一模一样，且自我感觉很有成就感  A不适合编程（理由：打字准确度偏低、粗心大意） B初级程序员（理由：打字准确度很高、认真细致、自信、理解全角半角概念） C高级程序员（理由：在B的基础上理解字体和排版也是电脑打印的重要因素、但相比D还不够偏执、精益求精、结果可验证） D软件项目经理（理由：能针对项目给出令人信服的细致到极点的需求说明和典型测试用例。用户几乎挑不出毛病。专业！）  如果想从A变成B的话，到我的资源http://download.csdn.net/detail/zhao4zhong1/4084259里面下载“适合程序员的键盘练习”

引用 6 楼 u011272720 的回复:[quote=引用 4 楼 zhao4zhong1 的回复:] 计算机组成原理→DOS命令→汇编语言→C语言（不包括C++）、代码书写规范→数据结构、编译原理、操作系统→计算机网络、数据库原理、正则表达式→其它语言（包括C++）、架构…… 一开始从这么底层的位置学起，作为一个初学者，如何孤独地、毫无价值输出地撑过这么长的时间？[/quote] 不是一个层次的，不能向他看齐。

感觉现在传统意义上的c/c++ 还是做C/S服务器端的程序员多一些 其实程序员主要都是自学，科班教的真没多少，而且找工作主要还是看你的经验和能力，说白了就是你能不能干活

引用 11 楼 zhuyuehen 的回复:同为初学者，表示直接看案例入门快一点，看书太慢 共勉

引用 9 楼 u012421456 的回复:这样的问题，好像许多人都问过了http://www.cnblogs.com/poiu-elab/archive/2012/05/08/2490809.html http://zhidao.baidu.com/link?url=anUJ0ffAwmAq-_odKw5WIX739XuNutRcoIZKTdu2uCn_2xiLlZfUfTDL_aaXfmIIh8sdFVOdDY1xtuwfrfOiv_

引用 8 楼 caozhy 的回复:不知道非职业程序员学C/C++有什么意义。甚至现在大部分程序员都不再使用这两种语言了。说难听点，你靠自学C语言找个码农的工作尚且凑合，找个程序员的工作，是不现实的。  学学PHP、Ruby或者Javascript，自己可以做点小网页小游戏。学学Basic还可以用它来代替人工处理一些事务，或者增强你用Office的效率。学学C#，你可以适应多种开发用途，用它创业很不错。学学Python，又可以当脚本，又可以做点科学运算。如果你想挑战下思维，Lisp/Scheme可以玩玩。如果你仅仅想找一份工作，学Java或者Objective-C的收获也比C/C++大得多。 这样我是不是永远没钱途了~还是坚持一下吧，了解多点总不是坏事。

买本书自学啊

同为初学者，表示直接看案例入门快一点，看书太慢

真正学起来，计算机专业和非计算机专业无界限。没有天生的某专业，路都是自己闯出来的。关键是兴趣、恒心、方法以及实践。

非计算机专业  ，java和.net搞起啊，尤其是.net，上手快

什么？你想在实战中学习？那你去学单片机或者ARM啊都用C写的,还能写出点东西，有成就感。，当我瞎说啊。

选一本的好的教材， 多动手，多折腾。

引用 4 楼 zhao4zhong1 的回复:计算机组成原理→DOS命令→汇编语言→C语言（不包括C++）、代码书写规范→数据结构、编译原理、操作系统→计算机网络、数据库原理、正则表达式→其它语言（包括C++）、架构…… 一开始从这么底层的位置学起，作为一个初学者，如何孤独地、毫无价值输出地撑过这么长的时间？

买本c++ primer, 多做练习。 先会爬了，再走路。后面再仔细体会数据结构也不迟。有了兴趣才好钻研


Question: 一个数组的语法问题

char *能这样初始化吗？

活人永远不会被尿憋死！ char *recv_Send1="\xAA\x0E\x12\x01""CAIWEI-1.7\0\x55"; char  recv_Send2[]={(char)0xAA, 0x0E, 0x12, 0x01 , 'C', 'A', 'I', 'W', 'E', 'I', '-', '1', '.', '7', '\0', 0x55}; int main() {     return 0; }

因为第一个指针没有指向一个具体的内存空间，肯定不能初始化

第一个只是一个指针，你没有给他分配实际的内存，现在实际只占了4个字节(未分配内存前）。 第二个是一个数组，是一个临时变量，已经在栈空间里给这个变量分配了大小。

字符串的基本单元是字符而不是其它的，应该这样写： char *recv_Send=“\xAA\x0E\x12\x01CAIWEI-1.7\0\x55" 另外'\0'是字符串的结束符，最好不要出现在0x55的前面  引用 楼主 caiwei_cs 的回复:char *recv_Send={0xAA, 0x0E, 0x12, 0x01 , 'C', 'A', 'I', 'W', 'E', 'I', '-', '1', '.', '7', '\0', 0x55}; char recv_Send[]={0xAA, 0x0E, 0x12, 0x01 , 'C', 'A', 'I', 'W', 'E', 'I', '-', '1', '.', '7', '\0', 0x55};  为什么第一个错误，第二个可以？  第一个错误提示为： warning C4047: “初始化”:“char *”与“int”的间接级别不同 （vc2010） {}must have 1 element to initialise scalar（ads）

32位系统中指针长度 至少要用32位来表示 ，同时int被扩展为2个字长，char的一个字节 太短了。

char *recv_Send={0xAA, 0x0E, 0x12, 0x01 , 'C', 'A', 'I', 'W', 'E', 'I', '-', '1', '.', '7', '\0', 0x55};   char*     "0xAA, 0x0E, 0x12, 0x01 , 'C', 'A', 'I', 'W', 'E', 'I', '-', '1', '.', '7', '\0', 0x55"  字符串


Question: 转义字符的问题 请解答 谢谢

C++ Character Constants Character constants are one or more members of the “source character set,” the character set in which a program is written, surrounded by single quotation marks ('). They are used to represent characters in the “execution character set,” the character set on the machine where the program executes.  Microsoft Specific   For Microsoft C++, the source and execution character sets are both ASCII.  END Microsoft Specific  There are three kinds of character constants:   Normal character constants   Multicharacter constants   Wide-character constants  Note   Use wide-character constants in place of multicharacter constants to ensure portability.  Character constants are specified as one or more characters enclosed in single quotation marks. For example:  char ch = 'x';          // Specify normal character constant. int mbch = 'ab';        // Specify system-dependent                         //  multicharacter constant. wchar_t wcch = L'ab';   // Specify wide-character constant.  Note that mbch is of type int. If it were declared as type char, the second byte would not be retained. A multicharacter constant has four meaningful characters; specifying more than four generates an error message.  Syntax  character-constant :  'c-char-sequence' L'c-char-sequence'  c-char-sequence :  c-char c-char-sequence c-char  c-char :  any member of the source character set except the single quotation mark ('), backslash (\), or newline character escape-sequence  escape-sequence :  simple-escape-sequence octal-escape-sequence hexadecimal-escape-sequence  simple-escape-sequence : one of  \' \" \? \\ \a \b \f \n \r \t \v  octal-escape-sequence :  \octal-digit \octal-digit octal-digit \octal-digit octal-digit octal-digit  hexadecimal-escape-sequence :  \xhexadecimal-digit hexadecimal-escape-sequence hexadecimal-digit  Microsoft C++ supports normal, multicharacter, and wide-character constants. Use wide-character constants to specify members of the extended execution character set (for example, to support an international application). Normal character constants have type char, multicharacter constants have type int, and wide-character constants have type wchar_t. (The type wchar_t is defined in the standard include files STDDEF.H, STDLIB.H, and STRING.H. The wide-character functions, however, are prototyped only in STDLIB.H.)  The only difference in specification between normal and wide-character constants is that wide-character constants are preceded by the letter L. For example:  char schar = 'x';               // Normal character constant wchar_t wchar = L'\x81\x19';    // Wide-character constant  Table 1.2 shows reserved or nongraphic characters that are system dependent or not allowed within character constants. These characters should be represented with escape sequences.  Table 1.2   C++ Reserved or Nongraphic Characters  Character ASCII  Representation ASCII  Value Escape Sequence  Newline NL (LF) 10 or 0x0a \n  Horizontal tab HT 9 \t  Vertical tab VT 11 or 0x0b \v  Backspace BS 8 \b  Carriage return CR 13 or 0x0d \r  Formfeed FF 12 or 0x0c \f  Alert BEL 7 \a  Backslash \ 92 or 0x5c \\  Question mark ? 63 or 0x3f \?  Single quotation mark ' 39 or 0x27 \'  Double quotation mark " 34 or 0x22 \"  Octal number ooo — \ooo  Hexadecimal number hhh — \xhhh  Null character NUL 0 \0    If the character following the backslash does not specify a legal escape sequence, the result is implementation defined. In Microsoft C++, the character following the backslash is taken literally, as though the escape were not present, and a level 1 warning (“unrecognized character escape sequence”) is issued.  Octal escape sequences, specified in the form \ooo, consist of a backslash and one, two, or three octal characters. Hexadecimal escape sequences, specified in the form \xhhh, consist of the characters \x followed by a sequence of hexadecimal digits. Unlike octal escape constants, there is no limit on the number of hexadecimal digits in an escape sequence.  Octal escape sequences are terminated by the first character that is not an octal digit, or when three characters are seen. For example:  wchar_t och = L'\076a';  // Sequence terminates at a char    ch = '\233';     // Sequence terminates after 3 characters  Similarly, hexadecimal escape sequences terminate at the first character that is not a hexadecimal digit. Because hexadecimal digits include the letters a through f (and A through F), make sure the escape sequence terminates at the intended digit.  Because the single quotation mark (') encloses character constants, use the escape sequence \' to represent enclosed single quotation marks. The double quotation mark (") can be represented without an escape sequence. The backslash character (\) is a line-continuation character when placed at the end of a line. If you want a backslash character to appear within a character constant, you must type two backslashes in a row (\\). (SeePhases of Translation in the Preprocessor Reference for more information about line continuation.)

引用 11 楼 pozimxb 的回复:[quote=引用 10 楼 zjq9931 的回复:] [quote=引用 9 楼 pozimxb 的回复:] [quote=引用 8 楼 zjq9931 的回复:] [quote=引用 7 楼 pozimxb 的回复:] [quote=引用 6 楼 zjq9931 的回复:] [quote=引用 5 楼 zjq9931 的回复:] [quote=引用 4 楼 pozimxb 的回复:] [quote=引用 3 楼 zjq9931 的回复:] 因为“\r”是回车键，回到这一行的开始，但并不换行。  但是我修改成这样printf(" as d\t fg\rh); 结果是has d        fg      这时fg是在第十行 光标在第二行a  然后输出\t   asd就都会没了吗？  反正我输出的结果就是空的 不知道为什么[/quote] 结果是对的啊，相当于输出" as d\t fg"，然后会到这一行的开始，再输出h。[/quote] 这里的回车，指的是，回到一行的开始，\r代表回车，意思是，会到当前行的开始，并不换行。 \n代表，换行（相当于，另起一行）[/quote]  哦 谢谢 耐心回答我  我主要是想知道这个\t 为什么把as d 给覆盖没了  你上面说是\r的作用 可是先去掉后面的\tj  这样输出printf(" as d\t fg\rh); 结果是as d还在  这就是不是\r的作用啊    如果\t是输出tab 那应该第一行是h 然后as d往后挪8格才对..   还是说\t就是往后覆盖8个空格的内容呢[/quote] \r指的是，光标回到行的开始，光表回到行的开始的过程中不会删除字符，只有回到开始后再输出才会替换（不是插入和编辑器中的不一样）字符。  #include<stdio.h>  int main() { 	printf("123456789\r000");//这个的输出结果 	printf("\t123456789\r000");//这个的输出结果 	return 0; }   [/quote]  我知道\r是回到行首不删除字符的  我一直问的是\t 啊 为什么printf(" as d\t fg\rh\tj\n");后面多了\tj  最后的输出结果就是h       jfg 而printf(" as d\t fg\rh); 结果是has d        fg  asd是怎么没的[/quote] 结果都很正常啊。。。没有什么奇怪的，不知道你觉得哪里奇怪？ 如果你觉得奇怪，可以把\r换成\n，这样就可以，上下两行对比，然后把第二行的换到，第一行去，就好了。[/quote]  我没说\r奇怪的啊  是\t   把asd都覆盖消失了.. 然后在f前面加了一个j 我理解\t的意思是输出tab 就是8个空格  那结果应该是asd往后挪8位  而不是消失了...    在\tj 执行前的结果是has d        fg      而\tj执行后就是h       jfg   我不是觉得那\r有问题  是\tj  去输出一个j  为啥把前面的asd弄没了.... 是说\t就是 覆盖后面8位变成空格吗 [/quote] 是的\r移动到行首，然后再输出的字符会替换掉原来的字符。

引用 10 楼 zjq9931 的回复:[quote=引用 9 楼 pozimxb 的回复:] [quote=引用 8 楼 zjq9931 的回复:] [quote=引用 7 楼 pozimxb 的回复:] [quote=引用 6 楼 zjq9931 的回复:] [quote=引用 5 楼 zjq9931 的回复:] [quote=引用 4 楼 pozimxb 的回复:] [quote=引用 3 楼 zjq9931 的回复:] 因为“\r”是回车键，回到这一行的开始，但并不换行。  但是我修改成这样printf(" as d\t fg\rh); 结果是has d        fg      这时fg是在第十行 光标在第二行a  然后输出\t   asd就都会没了吗？  反正我输出的结果就是空的 不知道为什么[/quote] 结果是对的啊，相当于输出" as d\t fg"，然后会到这一行的开始，再输出h。[/quote] 这里的回车，指的是，回到一行的开始，\r代表回车，意思是，会到当前行的开始，并不换行。 \n代表，换行（相当于，另起一行）[/quote]  哦 谢谢 耐心回答我  我主要是想知道这个\t 为什么把as d 给覆盖没了  你上面说是\r的作用 可是先去掉后面的\tj  这样输出printf(" as d\t fg\rh); 结果是as d还在  这就是不是\r的作用啊    如果\t是输出tab 那应该第一行是h 然后as d往后挪8格才对..   还是说\t就是往后覆盖8个空格的内容呢[/quote] \r指的是，光标回到行的开始，光表回到行的开始的过程中不会删除字符，只有回到开始后再输出才会替换（不是插入和编辑器中的不一样）字符。  #include<stdio.h>  int main() { 	printf("123456789\r000");//这个的输出结果 	printf("\t123456789\r000");//这个的输出结果 	return 0; }   [/quote]  我知道\r是回到行首不删除字符的  我一直问的是\t 啊 为什么printf(" as d\t fg\rh\tj\n");后面多了\tj  最后的输出结果就是h       jfg 而printf(" as d\t fg\rh); 结果是has d        fg  asd是怎么没的[/quote] 结果都很正常啊。。。没有什么奇怪的，不知道你觉得哪里奇怪？ 如果你觉得奇怪，可以把\r换成\n，这样就可以，上下两行对比，然后把第二行的换到，第一行去，就好了。[/quote]  我没说\r奇怪的啊  是\t   把asd都覆盖消失了.. 然后在f前面加了一个j 我理解\t的意思是输出tab 就是8个空格  那结果应该是asd往后挪8位  而不是消失了...    在\tj 执行前的结果是has d        fg      而\tj执行后就是h       jfg   我不是觉得那\r有问题  是\tj  去输出一个j  为啥把前面的asd弄没了.... 是说\t就是 覆盖后面8位变成空格吗

引用 9 楼 pozimxb 的回复:[quote=引用 8 楼 zjq9931 的回复:] [quote=引用 7 楼 pozimxb 的回复:] [quote=引用 6 楼 zjq9931 的回复:] [quote=引用 5 楼 zjq9931 的回复:] [quote=引用 4 楼 pozimxb 的回复:] [quote=引用 3 楼 zjq9931 的回复:] 因为“\r”是回车键，回到这一行的开始，但并不换行。  但是我修改成这样printf(" as d\t fg\rh); 结果是has d        fg      这时fg是在第十行 光标在第二行a  然后输出\t   asd就都会没了吗？  反正我输出的结果就是空的 不知道为什么[/quote] 结果是对的啊，相当于输出" as d\t fg"，然后会到这一行的开始，再输出h。[/quote] 这里的回车，指的是，回到一行的开始，\r代表回车，意思是，会到当前行的开始，并不换行。 \n代表，换行（相当于，另起一行）[/quote]  哦 谢谢 耐心回答我  我主要是想知道这个\t 为什么把as d 给覆盖没了  你上面说是\r的作用 可是先去掉后面的\tj  这样输出printf(" as d\t fg\rh); 结果是as d还在  这就是不是\r的作用啊    如果\t是输出tab 那应该第一行是h 然后as d往后挪8格才对..   还是说\t就是往后覆盖8个空格的内容呢[/quote] \r指的是，光标回到行的开始，光表回到行的开始的过程中不会删除字符，只有回到开始后再输出才会替换（不是插入和编辑器中的不一样）字符。  #include<stdio.h>  int main() { 	printf("123456789\r000");//这个的输出结果 	printf("\t123456789\r000");//这个的输出结果 	return 0; }   [/quote]  我知道\r是回到行首不删除字符的  我一直问的是\t 啊 为什么printf(" as d\t fg\rh\tj\n");后面多了\tj  最后的输出结果就是h       jfg 而printf(" as d\t fg\rh); 结果是has d        fg  asd是怎么没的[/quote] 结果都很正常啊。。。没有什么奇怪的，不知道你觉得哪里奇怪？ 如果你觉得奇怪，可以把\r换成\n，这样就可以，上下两行对比，然后把第二行的换到，第一行去，就好了。

引用 8 楼 zjq9931 的回复:[quote=引用 7 楼 pozimxb 的回复:] [quote=引用 6 楼 zjq9931 的回复:] [quote=引用 5 楼 zjq9931 的回复:] [quote=引用 4 楼 pozimxb 的回复:] [quote=引用 3 楼 zjq9931 的回复:] 因为“\r”是回车键，回到这一行的开始，但并不换行。  但是我修改成这样printf(" as d\t fg\rh); 结果是has d        fg      这时fg是在第十行 光标在第二行a  然后输出\t   asd就都会没了吗？  反正我输出的结果就是空的 不知道为什么[/quote] 结果是对的啊，相当于输出" as d\t fg"，然后会到这一行的开始，再输出h。[/quote] 这里的回车，指的是，回到一行的开始，\r代表回车，意思是，会到当前行的开始，并不换行。 \n代表，换行（相当于，另起一行）[/quote]  哦 谢谢 耐心回答我  我主要是想知道这个\t 为什么把as d 给覆盖没了  你上面说是\r的作用 可是先去掉后面的\tj  这样输出printf(" as d\t fg\rh); 结果是as d还在  这就是不是\r的作用啊    如果\t是输出tab 那应该第一行是h 然后as d往后挪8格才对..   还是说\t就是往后覆盖8个空格的内容呢[/quote] \r指的是，光标回到行的开始，光表回到行的开始的过程中不会删除字符，只有回到开始后再输出才会替换（不是插入和编辑器中的不一样）字符。  #include<stdio.h>  int main() { 	printf("123456789\r000");//这个的输出结果 	printf("\t123456789\r000");//这个的输出结果 	return 0; }   [/quote]  我知道\r是回到行首不删除字符的  我一直问的是\t 啊 为什么printf(" as d\t fg\rh\tj\n");后面多了\tj  最后的输出结果就是h       jfg 而printf(" as d\t fg\rh); 结果是has d        fg  asd是怎么没的

引用 7 楼 pozimxb 的回复:[quote=引用 6 楼 zjq9931 的回复:] [quote=引用 5 楼 zjq9931 的回复:] [quote=引用 4 楼 pozimxb 的回复:] [quote=引用 3 楼 zjq9931 的回复:] 因为“\r”是回车键，回到这一行的开始，但并不换行。  但是我修改成这样printf(" as d\t fg\rh); 结果是has d        fg      这时fg是在第十行 光标在第二行a  然后输出\t   asd就都会没了吗？  反正我输出的结果就是空的 不知道为什么[/quote] 结果是对的啊，相当于输出" as d\t fg"，然后会到这一行的开始，再输出h。[/quote] 这里的回车，指的是，回到一行的开始，\r代表回车，意思是，会到当前行的开始，并不换行。 \n代表，换行（相当于，另起一行）[/quote]  哦 谢谢 耐心回答我  我主要是想知道这个\t 为什么把as d 给覆盖没了  你上面说是\r的作用 可是先去掉后面的\tj  这样输出printf(" as d\t fg\rh); 结果是as d还在  这就是不是\r的作用啊    如果\t是输出tab 那应该第一行是h 然后as d往后挪8格才对..   还是说\t就是往后覆盖8个空格的内容呢[/quote] \r指的是，光标回到行的开始，光表回到行的开始的过程中不会删除字符，只有回到开始后再输出才会替换（不是插入和编辑器中的不一样）字符。  #include<stdio.h>  int main() { 	printf("123456789\r000");//这个的输出结果 	printf("\t123456789\r000");//这个的输出结果 	return 0; }

引用 6 楼 zjq9931 的回复:[quote=引用 5 楼 zjq9931 的回复:] [quote=引用 4 楼 pozimxb 的回复:] [quote=引用 3 楼 zjq9931 的回复:] 因为“\r”是回车键，回到这一行的开始，但并不换行。  但是我修改成这样printf(" as d\t fg\rh); 结果是has d        fg      这时fg是在第十行 光标在第二行a  然后输出\t   asd就都会没了吗？  反正我输出的结果就是空的 不知道为什么[/quote] 结果是对的啊，相当于输出" as d\t fg"，然后会到这一行的开始，再输出h。[/quote] 这里的回车，指的是，回到一行的开始，\r代表回车，意思是，会到当前行的开始，并不换行。 \n代表，换行（相当于，另起一行）[/quote]  哦 谢谢 耐心回答我  我主要是想知道这个\t 为什么把as d 给覆盖没了  你上面说是\r的作用 可是先去掉后面的\tj  这样输出printf(" as d\t fg\rh); 结果是as d还在  这就是不是\r的作用啊    如果\t是输出tab 那应该第一行是h 然后as d往后挪8格才对..   还是说\t就是往后覆盖8个空格的内容呢

引用 5 楼 zjq9931 的回复:[quote=引用 4 楼 pozimxb 的回复:] [quote=引用 3 楼 zjq9931 的回复:] 因为“\r”是回车键，回到这一行的开始，但并不换行。  但是我修改成这样printf(" as d\t fg\rh); 结果是has d        fg      这时fg是在第十行 光标在第二行a  然后输出\t   asd就都会没了吗？  反正我输出的结果就是空的 不知道为什么[/quote] 结果是对的啊，相当于输出" as d\t fg"，然后会到这一行的开始，再输出h。[/quote] 这里的回车，指的是，回到一行的开始，\r代表回车，意思是，会到当前行的开始，并不换行。 \n代表，换行（相当于，另起一行）

引用 4 楼 pozimxb 的回复:[quote=引用 3 楼 zjq9931 的回复:] 因为“\r”是回车键，回到这一行的开始，但并不换行。  但是我修改成这样printf(" as d\t fg\rh); 结果是has d        fg      这时fg是在第十行 光标在第二行a  然后输出\t   asd就都会没了吗？  反正我输出的结果就是空的 不知道为什么[/quote] 结果是对的啊，相当于输出" as d\t fg"，然后会到这一行的开始，再输出h。

引用 3 楼 zjq9931 的回复:因为“\r”是回车键，回到这一行的开始，但并不换行。  但是我修改成这样printf(" as d\t fg\rh); 结果是has d        fg      这时fg是在第十行 光标在第二行a  然后输出\t   asd就都会没了吗？  反正我输出的结果就是空的 不知道为什么

因为“\r”是回车键，回到这一行的开始，但并不换行。

引用 1 楼 user-3 的回复:先输出： as d\t fg 可是马上遇到 \r，这个是回车不换行 h\tj，将覆盖掉上面的输出，考虑 \t 占 8 个字符位置 如果考虑将它们分两行输出，就是下面这样：  然而，它们输出到一行，就成了： h       jfg 不过，其中的两个 \t 所占的字符数不一样，有点蹊跷  谢谢哦    那两个\t所占的字符数不一样  第一个\t后有个空格fg  第二个\t直接跟着j


Question: 我把一个 EXE 工程改成lib属性，竟然编译通过了，求lib库也可以有main函数吗？main函数能导出吗？如果想导出main函数该怎么办？能改名吗？

其实EXE程序，也可以当库用。我个人的感觉是，EXE和DLL什么的，主要差别就是加载点不太一样。

main函数入口的名称是可以改的。


Question: 实现两个字节的十六进制数高低位互换再换算成整型数输出

大端机器和小端机器，以及数据内存布局  --------------------------- |  x1  |  x2  |  x3  |  x4  | --------------------------- int tmp占4个字节（32位），在内存中的地址也是依次增长。开始的时候x1到x4都是0，memcpy后x1存放的是0x05, x2存放的是ox01， 现在tmp在小端机器上的十六进制是0x00000105，但是在大端机器是0x05010000。所以在大端机器上的字节这种方法是行不通的。

未必能，考虑字节序。

多谢了，学习了！


Question: 输入字符串 ，输入数字n，从n开始返回后面的字符。代码求指错。

引用 5 楼 xuzhouweihao 的回复:1.change函数定义的地方，s怎么没有类型啊 2.malloc申请的内存，在函数中没有发现释放的地方 3.因为循环执行了p++操作，所以你在change函数返回的地方，返回的地址不是初始的p的地址。   这个应该是你比较疑惑的地方吧。  楼主最好使用void change(char *in, char*out, int n)类似的定义，这样就可以在调用该函数的前后进行内存的申请和释放。赞！

其实电脑开机后物理内存的每个字节都是可读写的，区别仅在于操作系统内存管理模块在你读写时是否能发现并是否采取相应动作而已。操作系统管理内存的粒度不是字节而是页，一页通常为4KB。

引用 14 楼 u013756406 的回复:另外有个新问题。。。求解！！！！！ 就是我取内存空间的时候 p字符串的大小需不需要包括‘\0’的，这个有没有关系？ 虽然我运行了一下，加不加都能正常运行的。。。  需要

我也不知道哎

#include <stdio.h> #include <string.h> char *change(char *s,int n) {     return s+n; } int main() {     int m;     char a[100];      fgets(a,100,stdin);     if (a[strlen(a)-1]=='\n') a[strlen(a)-1]=0;     while (1) {         printf("Input m(0..%d):",strlen(a)-1);         fflush(stdout);         rewind(stdin);         if (1==scanf("%d",&m)) {             if (0<=m && m<=strlen(a)-1) {                 printf("%s",change(a,m));                 return 0;             }         }     } }

引用 7 楼 starytx 的回复:这个函数直接来个 return (s + n); 就可以了吧

还有就是这个语句	*(p+i)=*(s+n-1+i);  这是字符串赋值的语句。这个是正确的                                        但是这	*p++=*(s+n-1+i);和	*p++=*(s+n-1)++;为什么错了呢？逻辑是对的，语法错误吗？

char *change(char*s,int n)

感谢楼上的回答，，原来我的*s没有定义！！！！！！！！ 另外有个新问题。。。求解！！！！！ 就是我取内存空间的时候 p字符串的大小需不需要包括‘\0’的，这个有没有关系？ 虽然我运行了一下，加不加都能正常运行的。。。

#include <stdio.h> #include<string.h> void change(char *s, int n, char *t) {     int i, len;     len = strlen(s);     if(n>0 && n<=len)     {         for(i=0; i<=len-n+1; i++) 			*t++ = *(s + n - 1 + i); 		*t = '\0';     }	     return; }  int main() {	     int m;     char a[100], b[100];     gets(a);     scanf("%d", &m); 	change(a, m, b);     printf("%s\n", b); 	return 0;	 }

这个函数直接来个 return (s + n); 就可以了吧

char *change(*s,int n) *s是啥玩意 基础知识不过关

free的话在你用完返回的字符串地址后释放

#include <stdio.h> #include<string.h> char *change(char *s,int n) {     int i,len;     char *p;     len=strlen(s);     if(n>0&&n<=len-1)     {         p=(char *)malloc((len-n+1)*sizeof(char));         strcpy(p,&s[n]);//有函数不用你为啥要那样写呢，         return p;     } else {   return s;//错了啥也不做 }               return p; } void main() {           int m;     char a[100]={0},b[100]={0};//这个地方不知道会不会自动初始化为零我习惯了一半都会自己初始化为零     gets(a);//这个地方不多说了//正儿八经程序你要敢gets老板不弄死你，这玩意不检查长度     scanf("%d",&m);     printf("%s",change(a,m));       }

引用 楼主 u013756406 的回复:#include <stdio.h> #include<string.h> char *change(*s,int n) //<<<<<<<<<<<<<<<------ char *s { }  } 类型。 另外，什么时候free？

编译错误。我的想法是，调用函数change 把原来的地址放进去，然后函数返回新的字符串地址p


Question: Unicode既是字符集又是一种字符编码？

电脑内存或文件内容只是一个一维二进制字节数组及其对应的二进制地址； 人脑才将电脑内存或文件内容中的这个一维二进制字节数组及其对应的二进制地址的某些部分看成是整数、有符号数/无符号数、浮点数、复数、英文字母、阿拉伯数字、中文/韩文/法文……字符/字符串、汇编指令、函数、函数参数、堆、栈、数组、指针、数组指针、指针数组、数组的数组、指针的指针、二维数组、字符点阵、字符笔画的坐标、黑白二值图片、灰度图片、彩色图片、录音、视频、指纹信息、身份证信息……  推荐使用WinHex软件查看硬盘或文件或内存中的原始字节内容。

先 http://www.microsoft.com/visualstudio/chs/downloads#d-2010-express 点开Visual C++ 2010 Express下面的语言选‘简体中文’，再点立即安装  再参考 C:\Program Files\Microsoft Visual Studio 10.0\VC\crt\src\cvt\*.*

想搞清楚这些,下载一个notepad++,把一段文字用notepad++保存成txt文件,它有转换成不同编码的选项,可以随便改几种看一看.然后用二进制文本查看器,或者用C++代码,把保存的txt文件读出来,一个字节一个字节的看一看.还有,用word,打几个字,用alt+x的功能查到它的Unicode编码.结合起来,你就知道了.

引用 1 楼 supermegaboy 的回复:严格来讲，unicode是字符编码，但unicode的发行版本又包含了字符集，所以嘛，呵呵，如果从宽泛一点的看法出发，把unicode称为既包含字符编码也包含字符集也未尝不可。  ucs是ISO搞的一套，后来从unicode2.0开始与unicode一致了。  那些gb开头的东西虽然也规定了字符编码，但应该主要属于字符集。 学习了，我以为他就是一种占2字节的编码而已


Question: 咨询一个VS2013的编译错误

将错误信息中出现的标识符放在google里面搜一下，看其在哪个.lib中，然后在本地硬盘上搜索该.lib,如果没有，在网上搜索相关库或模块下载安装，然后将其所在目录填写到“附加依赖库所在目录”中，将其名字添加到“附加依赖库”中，重新连接。 VC6： 工程、设置、C/C++、分类：Preprocessor、附加包含路径：填写附加头文件所在目录 逗号间隔多项 工程、设置、Link、分类：Input、附加库路径：填写附加依赖库所在目录 分号间隔多项 工程、设置、Link、分类：Input、对象/库模块：填写附加依赖库的名字.lib 空格间隔多项 VS20xx： 项目、属性、C/C++、附加包含目录：填写附加头文件所在目录 分号间隔多项 项目、属性、链接器、常规、附加库目录：填写附加依赖库所在目录 分号间隔多项 项目、属性、链接器、输入、附加依赖项：填写附加依赖库的名字.lib 空格或分号间隔多项

是不是该库所在的目录不在搜索路径内？

引用 1 楼 akirya 的回复:缺少libGLESv2.lib 这library 已经添加到VS的VC++的lib内，并且在VC 项目中进行引用了！！不知道是不是其他地方没有引用他！！

是路径不对吧

引用 6 楼 benson_nupt 的回复:[quote=引用 4 楼 user-5 的回复:] [quote=引用 2 楼 benson_nupt 的回复:] [quote=引用 1 楼 akirya 的回复:] 缺少libGLESv2.lib 这library 已经添加到VS的VC++的lib内，并且在VC 项目中进行引用了！！不知道是不是其他地方没有引用他！！[/quote] 缺少libGLESv2.lib[/quote] 已经有了~~[/quote] 缺少libGLESv2.lib------------对于编译器来说。

引用 4 楼 user-5 的回复:[quote=引用 2 楼 benson_nupt 的回复:] [quote=引用 1 楼 akirya 的回复:] 缺少libGLESv2.lib 这library 已经添加到VS的VC++的lib内，并且在VC 项目中进行引用了！！不知道是不是其他地方没有引用他！！[/quote] 缺少libGLESv2.lib[/quote] 已经有了~~

引用 3 楼 xiaoqiao_82 的回复:是不是该库所在的目录不在搜索路径内？ 在哪里设置搜索路径？

引用 2 楼 benson_nupt 的回复:[quote=引用 1 楼 akirya 的回复:] 缺少libGLESv2.lib 这library 已经添加到VS的VC++的lib内，并且在VC 项目中进行引用了！！不知道是不是其他地方没有引用他！！[/quote] 缺少libGLESv2.lib


Question: 插入排序中memcpy()疑惑

谢谢，我懂了

memcpy(key, &a[j * esize], esize) esize是每个元素的大小，这是不固定的，有可能它是一个结构体 而a是char*，所以要取得下一个元素的地址就需要j*esize

memcpy以char为单位，指针参数是void *的，需要转换成具体的字节地址


Question: C语言int128 +-*如何实现

#include <iostream> #include <string> using namespace std; inline int compare(string str1,string str2) {//相等返回0，大于返回1，小于返回-1          if (str1.size()>str2.size()) return 1; //长度长的整数大于长度小的整数     else if (str1.size()<str2.size()) return -1;     else                              return str1.compare(str2); //若长度相等，则头到尾按位比较 } string SUB_INT(string str1,string str2); string ADD_INT(string str1,string str2) {//高精度加法     int sign=1; //sign 为符号位     string str;     if (str1[0]=='-') {         if (str2[0]=='-') {             sign=-1;             str=ADD_INT(str1.erase(0,1),str2.erase(0,1));         } else {             str=SUB_INT(str2,str1.erase(0,1));         }     } else {         if (str2[0]=='-') {             str=SUB_INT(str1,str2.erase(0,1));         } else { //把两个整数对齐，短整数前面加0补齐             string::size_type L1,L2;             int i;             L1=str1.size();             L2=str2.size();             if (L1<L2) {                 for (i=1;i<=L2-L1;i++) str1="0"+str1;             } else {                 for (i=1;i<=L1-L2;i++) str2="0"+str2;             }             int int1=0,int2=0; //int2 记录进位             for (i=str1.size()-1;i>=0;i--) {                 int1=(int(str1[i])-'0'+int(str2[i])-'0'+int2)%10;                 int2=(int(str1[i])-'0'+int(str2[i])-'0'+int2)/10;                 str=char(int1+'0')+str;             }             if (int2!=0) str=char(int2+'0')+str;         }     }     //运算后处理符号位     if ((sign==-1)&&(str[0]!='0')) str="-"+str;     return str; } string SUB_INT(string str1,string str2) {//高精度减法     int sign=1; //sign 为符号位     string str;     int i,j;     if (str2[0]=='-') {         str=ADD_INT(str1,str2.erase(0,1));     } else {         int res=compare(str1,str2);         if (res==0) return "0";         if (res<0) {             sign=-1;             string temp =str1;             str1=str2;             str2=temp;         }         string::size_type tempint;         tempint=str1.size()-str2.size();         for (i=str2.size()-1;i>=0;i--) {             if (str1[i+tempint]<str2[i]) {                 j=1;                 while (1) {//zhao4zhong1添加                     if (str1[i+tempint-j]=='0') {                         str1[i+tempint-j]='9';                         j++;                     } else {                         str1[i+tempint-j]=char(int(str1[i+tempint-j])-1);                         break;                     }                 }                 str=char(str1[i+tempint]-str2[i]+':')+str;             } else {                 str=char(str1[i+tempint]-str2[i]+'0')+str;             }         }         for (i=tempint-1;i>=0;i--) str=str1[i]+str;     }     //去除结果中多余的前导0     str.erase(0,str.find_first_not_of('0'));     if (str.empty()) str="0";     if ((sign==-1) && (str[0]!='0')) str ="-"+str;     return str; } string MUL_INT(string str1,string str2) {//高精度乘法     int sign=1; //sign 为符号位     string str;     if (str1[0]=='-') {         sign*=-1;         str1 =str1.erase(0,1);     }     if (str2[0]=='-') {         sign*=-1;         str2 =str2.erase(0,1);     }     int i,j;     string::size_type L1,L2;     L1=str1.size();     L2=str2.size();     for (i=L2-1;i>=0;i--) { //模拟手工乘法竖式         string tempstr;         int int1=0,int2=0,int3=int(str2[i])-'0';         if (int3!=0) {             for (j=1;j<=(int)(L2-1-i);j++) tempstr="0"+tempstr;             for (j=L1-1;j>=0;j--) {                 int1=(int3*(int(str1[j])-'0')+int2)%10;                 int2=(int3*(int(str1[j])-'0')+int2)/10;                 tempstr=char(int1+'0')+tempstr;             }             if (int2!=0) tempstr=char(int2+'0')+tempstr;         }         str=ADD_INT(str,tempstr);     }     //去除结果中的前导0     str.erase(0,str.find_first_not_of('0'));     if (str.empty()) str="0";     if ((sign==-1) && (str[0]!='0')) str="-"+str;     return str; } string DIVIDE_INT(string str1,string str2,int flag) {//高精度除法。flag==1时,返回商; flag==0时,返回余数     string quotient,residue; //定义商和余数     int sign1=1,sign2=1;     if (str2 == "0") {  //判断除数是否为0         quotient= "ERROR!";         residue = "ERROR!";         if (flag==1) return quotient;         else         return residue ;     }     if (str1=="0") { //判断被除数是否为0         quotient="0";         residue ="0";     }     if (str1[0]=='-') {         str1   = str1.erase(0,1);         sign1 *= -1;         sign2  = -1;     }     if (str2[0]=='-') {         str2   = str2.erase(0,1);         sign1 *= -1;     }     int res=compare(str1,str2);     if (res<0) {         quotient="0";         residue =str1;     } else if (res == 0) {         quotient="1";         residue ="0";     } else {         string::size_type L1,L2;         L1=str1.size();         L2=str2.size();         string tempstr;         tempstr.append(str1,0,L2-1);         for (int i=L2-1;i<L1;i++) { //模拟手工除法竖式             tempstr=tempstr+str1[i];             tempstr.erase(0,tempstr.find_first_not_of('0'));//zhao4zhong1添加             if (tempstr.empty()) tempstr="0";//zhao4zhong1添加             for (char ch='9';ch>='0';ch--) { //试商                 string str;                 str=str+ch;                 if (compare(MUL_INT(str2,str),tempstr)<=0) {                     quotient=quotient+ch;                     tempstr =SUB_INT(tempstr,MUL_INT(str2,str));                     break;                 }             }         }         residue=tempstr;     }     //去除结果中的前导0     quotient.erase(0,quotient.find_first_not_of('0'));     if (quotient.empty()) quotient="0";     if ((sign1==-1)&&(quotient[0]!='0')) quotient="-"+quotient;     if ((sign2==-1)&&(residue [0]!='0')) residue ="-"+residue ;     if (flag==1) return quotient;     else         return residue ; } string DIV_INT(string str1,string str2) {//高精度除法,返回商     return DIVIDE_INT(str1,str2,1); } string MOD_INT(string str1,string str2) {//高精度除法,返回余数     return DIVIDE_INT(str1,str2,0); } int main() {     char ch;     string s1,s2,res;      while (cin>>s1>>ch>>s2) {         switch (ch) {             case '+':res=ADD_INT(s1,s2);break;             case '-':res=SUB_INT(s1,s2);break;             case '*':res=MUL_INT(s1,s2);break;             case '/':res=DIV_INT(s1,s2);break;             case '%':res=MOD_INT(s1,s2);break;             default :                   break;         }         cout<<res<<endl;     }     return(0); }

可以用字符数组实现，将大整数转成字符串存储，例如a[0]代表个位a[1],十位这样理论上可以扩展任意长度，大质数相乘什么的都可以用这种方法

int 128位大整数

int128？什么意思？


Question: 网上找到的一个圆形波程序，请各位帮我看看分析，谢谢！

引用 1 楼 user-1 的回复:Navier–Stokes方程 Ripple效应 为什么时间要这样写？

Navier–Stokes方程 Ripple效应


Question: 这个程序咋就输不出来结果，可以正常输入，难道是什么输入方式错了？

判断一棵树是否是完全二叉树


Question: 求教有关字符串输入的问题

一、你输入的字符串最大为“right”,因此a的大小最小为6，有一个'\0'要存 二、scanf("%s",a)；是从第一个非空字符开始，到下一个空字符结束 三、EOF是文件结束的标志，其值为-1，而scanf的返回值表示你输入参数的个数，(在你的程序中只有输入字符串就为1)， crtl+z连续两次只是windows下的模拟EOF,

貌似这个不是程序的问题  貌似就是这样 没想到解决方法  不过可以用  cin>>a  替换  只需要一次就ok

你直接点击空格键试试看

你几点点击空格试试看

你只是你是这样，Windows好像都是这样


Question: 【求助】error: array type has incomplete element tpe

引用 3 楼 zhao4zhong1 的回复:偶遇到类似问题都是用 “每次用/*...*/注释掉不同部分再重新编译，直到定位到具体语法出错的位置。” 的方法解决的。  根据它的error提示，我在我的RFID.h的文件里面找到那一行，如下： extern struct TAG TagGroup[TAG_NUM]; 这是对于TagGroup结构体的声明，其中TAG_NUM已经在之前宏定义过了。 在VC环境下可以，但是在or里面就不行了，我不知道是不是它不支持结构体的缘故？

自己给自己顶一下。

引用 4 楼 QQ2543514322 的回复:[quote=引用 3 楼 zhao4zhong1 的回复:] 偶遇到类似问题都是用 “每次用/*...*/注释掉不同部分再重新编译，直到定位到具体语法出错的位置。” 的方法解决的。  根据它的error提示，我在我的RFID.h的文件里面找到那一行，如下： extern struct TAG TagGroup[TAG_NUM]; 这是对于TagGroup结构体的声明，其中TAG_NUM已经在之前宏定义过了。 在VC环境下可以，但是在or里面就不行了，我不知道是不是它不支持结构体的缘故？[/quote] 有时候编译出错提示的位置和实际语法出错的位置差几十个文件和几万行源代码不止。 此时你只有用 “每次用/*...*/注释掉不同部分再重新编译，直到定位到具体语法出错的位置。” 的方法手动定位到真正出错的位置。

它提示错误的地方我定义了一个结构体变量。是不是在这个环境里面不支持结构体？求解答。


Question: 为啥输出是这样子的啊

你像这样输入不会报错吗？？？ 显然你第二个输入已经越界了、、、  字符数组，想要当字符串来用，一定要记得结束时一定加‘\0‘,因此长度要比你输入的长度大1 %s输出时直到遇到'\0'才会结束、、、、

你设置个断点，单步运行就可以看出原因了。 F9设置断点，F5调试，F10,单步运行


Question: C——请问我写的这两种算法哪种更高效，以及各自的优点。求老师解答

引用 42 楼 user-4 的回复:long  num[256]={0}; unsigned char    ch;  while(1) {      ch=读文件1      if(文件结束)  break;      num[ch]++; } while(1) {      ch=读文件2      if(文件结束)  break;      num[ch]++; } for(ch=0;ch<256;ch++) {       for(int i=0;i<num[ch];i++)       {             write(FILE3, &ch, 1);      } }这样就对了嘛，你两个ch++。。。幸好我还知道点

引用 楼主 u014711608 的回复:题目：在磁盘文件FILE1和FILE2中，各存放着一行字母，现要求把两个文件中的信息合并（按字母顺序排序），输出到一个新文件FILE3中去。 我写了两种算法，请问我写的这两种算法哪种更高效，以及各自的优点。 第一种：#define _CRT_SECURE_NO_WARNINGS #define _CRT_NONSTDC_NO_DEPRECATE //题目：在磁盘文件FILE1和FILE2中，各存放着一行字母，现要求把两个文件中的信息合并（按字母顺序排序），输出到一个新文件FILE3中去。 #include<io.h> #include<stdio.h> #include<fcntl.h> #include<malloc.h> struct Stack { 	char character; 	Stack *next; }; void main() { 	//注意：已知 FILE1 中的字符已经顺序存储在 FILE3 中，这是前提，就当已经在此函数里处理过了。请忽略。 	int FILE2, FILE3; 	char CharacterA, CharacterB; 	int Position = NULL; 	FILE3 = open("FILE3", O_RDWR | O_TEXT); 	FILE2 = open("FILE2", O_RDONLY | O_TEXT); 	//取出FILE2中的字符一个一个与FILE3中的字符比较； 	while (read(FILE2, &CharacterA, 1) > 0) 	{ 		//取出FILE3中的字符； 		while (read(FILE3, &CharacterB, 1) > 0) 		{  			if (CharacterA < CharacterB) 			{ 				//如果FILE2中的字符小于FILE3中的字符 				lseek(FILE3, Position, SEEK_SET);//还原FILE3的位置到Position 				Stack *StackA = NULL, *StackB = NULL; 				char CharacterC; 				//取出FILE3中Position之后的字符，存储在栈中； 				while (read(FILE3, &CharacterC, 1) > 0) 				{ 					StackA = (Stack *)malloc(sizeof(Stack)); 					StackA->character = CharacterC; 					StackA->next = StackB; 					StackB = StackA; 				} 				lseek(FILE3, Position, SEEK_SET);//还原FILE3的位置到Position 				write(FILE3, &CharacterA, 1); 				//把栈中的字符，存入FILE3中 				while (StackA != NULL) 				{ 					write(FILE3, &StackA->character, 1); 					StackB = StackA; 					StackA = StackA->next; 					free(StackB); 				} 				lseek(FILE3, 0, SEEK_SET);//还原FILE3的位置到 0 				break;//退出循环 			} 			if (eof(FILE3) != 0)//如果 FILE3 读到了末尾，还没有把 FILE2 中取出的字符写入，则强制写入到FILE3 			{ 				write(FILE3, &CharacterA, 1); 				break;//退出循环 			} 			Position = tell(FILE3);//取出FILE3位置到Position 		} 	} 	close(FILE2); 	close(FILE3); } 第二种： #include<malloc.h> struct Stack { 	char character; 	Stack *next; }; void main() { 	Stack *StackA = NULL, *StackB = NULL; 	char Character; 	//从FILE1中取得字符，存储在栈中； 	int FILE1; 	FILE1 = open("FILE1", O_RDONLY | O_TEXT); 	while (read(FILE1, &Character, 1) > 0) 	{ 		StackA = (Stack *)malloc(sizeof(Stack)); 		StackA->character = Character; 		StackA->next = StackB; 		StackB = StackA; 	} 	close(FILE1); 	//从FILE2中取得字符，存储在栈中； 	int FILE2; 	FILE2 = open("FILE2", O_RDONLY | O_TEXT); 	while (read(FILE2, &Character, 1) > 0) 	{ 		StackA = (Stack *)malloc(sizeof(Stack)); 		StackA->character = Character; 		StackA->next = StackB; 		StackB = StackA; 	} 	close(FILE2); 	//对栈中的字符进行排序； 	Stack *Stack_Head = StackA; 	for (; StackA != NULL; StackA = StackA->next) 	{ 		for (StackB = StackA->next; StackB != NULL; StackB = StackB->next) 		{ 			if (StackA->character > StackB->character) 			{ 				Character = StackA->character; 				StackA->character = StackB->character; 				StackB->character = Character; 			} 		} 	} 	//把排完序的字符写入FILE3文件中； 	int FILE3; 	FILE3 = open("FILE3", O_WRONLY | O_TRUNC); 	while (Stack_Head != NULL) 	{ 		write(FILE3, &Stack_Head->character, 1); 		StackA = Stack_Head; 		Stack_Head = Stack_Head->next; 		free(StackA); 	} 	close(FILE3); }  先想想磁盘是如何工作的，cpu是如何与磁盘通信的，再来考虑这个问题

无profiler不要谈效率！！ 尤其在这个云计算、虚拟机、模拟器、CUDA、多核 、多级cache、指令流水线、多种存储介质、……满天飞的时代！

另外，LZ还需要补一补文件系统的概念。 首先LZ每次读一个字节，实际上VFS（Virtual File System）已经把文件的其他一个页，或者块缓存在内存中，供下次取得，当然这个是文件系统的优化，所以每次你读一个字节，当你需要读的数据不再缓存中，再去读实际的磁盘。所以何不一次性读多一些Block呢？  凡是具备： (1)有效性 (2)确定性 (3)有穷性 这样要素的都可称为算法。  可LZ得两个算法效率过低，主要来源不再插入排序算法，而是在于文件IO，90%时间花在这上面了。

1. 按照字节读难免造成太多的时间花在磁盘IO上，建议成块的的读取数据。 2. 因为题目所说按照字母顺序排序，是否说明只有可能存在 ascii 表内的内容呢？采用鸽巢排序（计数排序）算法，分配256个unsigned long long(64 bit)进行排序，随后成块输出到另外一个文件即可。 3. 时间复杂度应该是 O(N+M) ， 空间复杂度也只是一个常数。其中N是F1的字节个数，M是F2的字节个数。  LZ的两个算法忽略文件IO的延迟，单纯的之看待算法，LZ采用的是插入排序，且LZ假设前提两个文件都是排序好了的。最坏的情况是F1 中左右的数字都比F2中的答，算法复杂度是 O(N*M)。并没有实质上的差别。思想一样，都属于插入排序，只是一个全部加载到内存，一个慢慢读一个处理一个。  LZ可以把你的两个算法时间复杂度优化到O(M+N) ,采用Merge（归并），自行补学。  LZ可以思考一个问题：假设F1,F2 是20GB的文件呢（实际内存给你2G运行空间）？无序的呢？又该如何提高效率/重新设计你的算法。

引用 40 楼 user-4 的回复:我说的方法就这几句话 我从来不把问题复杂化而是简单化 你没看懂不是我没写明白 是你自己的心态在做怪 for(ch=0;ch<255;ch++) {       for(int i=0;i<num[ch];ch++)       {             向文件三写ch值      } }我来还原你的这部分算法 for(ch=0;ch<255;ch++) {       for(int i=0;i<num[ch];ch++)       {             write(FILE3, &ch, sizeof(char));      } }是这样吧

引用 38 楼 user-4 的回复:[quote=引用 37 楼 u014711608 的回复:] [quote=引用 36 楼 user-4 的回复:] 一个单字节还有这么多道道,正鸡巴蛋疼 long  num[255]={0};  unsigned char    ch  寻环从文件1读取数据到ch num[ch]++ 寻环从文件1读取数据到ch num[ch]++  for(ch=0;ch<255;ch++) {       for(int i=0;i<num[ch];ch++)       {             向文件三写ch值      } }如果num[ch] = 2; 很可惜，你弄丢了一个ch。[/quote]  你就颠狂吧,就是如果,假设,你试过吗? 没看懂乱鸡巴说 如果没弄丢呢? 自己抽自己两嘴巴[/quote]如果你说我没看懂，那你就应该把你的思想写明白点。

引用 37 楼 u014711608 的回复:[quote=引用 36 楼 user-4 的回复:] 一个单字节还有这么多道道,正鸡巴蛋疼 long  num[255]={0};  unsigned char    ch  寻环从文件1读取数据到ch num[ch]++ 寻环从文件1读取数据到ch num[ch]++  for(ch=0;ch<255;ch++) {       for(int i=0;i<num[ch];ch++)       {             向文件三写ch值      } }如果num[ch] = 2; 很可惜，你弄丢了一个ch。[/quote]  你就颠狂吧,就是如果,假设,你试过吗? 没看懂乱鸡巴说 如果没弄丢呢? 自己抽自己两嘴巴

引用 32 楼 zhao4zhong1 的回复:我真身其实就是那个传说中卖矛盾的小贩啊！哈哈。。老师谦虚了。我个人觉得 好的代码不是因为一个人知道的知识量的多，而是一个人去想怎么能最简单解决这个问题。也就是说一个圣人的知识再多也比不上一个白痴的一个想法。

推荐楼主学习使用profiler  VC6：   Run the Profiler from the Development Environment Home |  Overview |  Details  Feature Only in Professional and Enterprise Editions   Profiling is supported only in Visual C++ Professional and Enterprise Editions. For more information, see Visual C++ Editions.  The development environment will profile the active project’s target. To profile more than one project, you should use custom batch files; see Profiling Multiple .DLL and .EXE Files for more information.  See Select Code to Profile for information on how to specify which code shall be profiled.  To run the profiler from the development environment  On the Build menu, choose Profile to display the Profile dialog box, as shown in the figure below.  In the Profile Type box, click one of the following option buttons:  Function Timing   Function Coverage   Line Coverage   Merge   Use Custom and the Custom Settings text box to run a batch file that contains profiler commands. See Run the Profiler from the Command Line for information on why you might want to batch and execute your own profiler commands. See Running a Custom Batch File for more information on specifying a batch file from the development environment.   Advanced settings is where you can specify PREP Phase I options.  Click OK.  Profile Dialog Box    Note   If you haven’t built your current project with profiling enabled, an error message lets you know that you need to rebuild your project. See Enable Profiling for more information.

我真身其实就是那个传说中卖矛盾的小贩啊！

引用 30 楼 u014711608 的回复:[quote=引用 29 楼 zhao4zhong1 的回复:] [quote=引用 21 楼 zhao4zhong1 的回复:] 提醒：无profiler不谈效率。  使用电脑计时有时误差会很大，因为待测程序段的运行会影响电脑时钟。 将待测程序段循环足够多次，手动掐秒表计时可能更准确。  不要迷信书、考题、老师、回帖； 要迷信CPU、编译器、调试器、运行结果。 并请结合“盲人摸太阳”和“驾船出海时一定只带一个指南针。”加以理解。 任何理论、权威、传说、真理、标准、解释、想象、知识……都比不上摆在眼前的事实！  有人说一套做一套，你相信他说的还是相信他做的？ 其实严格来说这个世界上古往今来所有人都是说一套做一套，不是吗？  不要写连自己也预测不了结果的代码！ 讨论算法的效率、优劣、……之前， 请先验证其正确性！ 再实测其针对几组典型输入/输出数据的运行时间！ 最后才是在实测数据的基础上，讨论该算法的效率、优劣、…… 否则我认为都是空谈！  比如这个： C++ String Toolkit (StrTk) Tokenizer http://www.codeproject.com/Articles/23198/C-String-Toolkit-StrTk-Tokenizer[/quote]我运行了，正常。实测，正常。剩下....老师。。是你说不要迷信你的[/quote]对于特殊的情况。。。。老师我还是学生呢。不可能现在就去对一个简单的算法去思考它的特殊情况的

引用 29 楼 zhao4zhong1 的回复:[quote=引用 21 楼 zhao4zhong1 的回复:] 提醒：无profiler不谈效率。  使用电脑计时有时误差会很大，因为待测程序段的运行会影响电脑时钟。 将待测程序段循环足够多次，手动掐秒表计时可能更准确。  不要迷信书、考题、老师、回帖； 要迷信CPU、编译器、调试器、运行结果。 并请结合“盲人摸太阳”和“驾船出海时一定只带一个指南针。”加以理解。 任何理论、权威、传说、真理、标准、解释、想象、知识……都比不上摆在眼前的事实！  有人说一套做一套，你相信他说的还是相信他做的？ 其实严格来说这个世界上古往今来所有人都是说一套做一套，不是吗？  不要写连自己也预测不了结果的代码！ 讨论算法的效率、优劣、……之前， 请先验证其正确性！ 再实测其针对几组典型输入/输出数据的运行时间！ 最后才是在实测数据的基础上，讨论该算法的效率、优劣、…… 否则我认为都是空谈！  比如这个： C++ String Toolkit (StrTk) Tokenizer http://www.codeproject.com/Articles/23198/C-String-Toolkit-StrTk-Tokenizer[/quote]我运行了，正常。实测，正常。剩下....老师。。是你说不要迷信你的

引用 21 楼 zhao4zhong1 的回复:提醒：无profiler不谈效率。  使用电脑计时有时误差会很大，因为待测程序段的运行会影响电脑时钟。 将待测程序段循环足够多次，手动掐秒表计时可能更准确。  不要迷信书、考题、老师、回帖； 要迷信CPU、编译器、调试器、运行结果。 并请结合“盲人摸太阳”和“驾船出海时一定只带一个指南针。”加以理解。 任何理论、权威、传说、真理、标准、解释、想象、知识……都比不上摆在眼前的事实！  有人说一套做一套，你相信他说的还是相信他做的？ 其实严格来说这个世界上古往今来所有人都是说一套做一套，不是吗？  不要写连自己也预测不了结果的代码！ 讨论算法的效率、优劣、……之前， 请先验证其正确性！ 再实测其针对几组典型输入/输出数据的运行时间！ 最后才是在实测数据的基础上，讨论该算法的效率、优劣、…… 否则我认为都是空谈！  比如这个： C++ String Toolkit (StrTk) Tokenizer http://www.codeproject.com/Articles/23198/C-String-Toolkit-StrTk-Tokenizer

个人意见： 任何算法，如果它不能针对特殊情况定义出具体的、确定的特殊处理步骤和方法，都不能称其为一个完整、可实现的算法；甚至不能称其为一个算法。

引用 24 楼 grf9527 的回复:读就是读，排序就是排序。 写就是写。这样比较快。那就是说第二种算法快一点？还是重新用鸽巢排序法快一点？就拿数据很多的情况算

引用 25 楼 zhao4zhong1 的回复:[quote=引用 22 楼 u014711608 的回复:] [quote=引用 20 楼 zhao4zhong1 的回复:] 这个世界上从来就没有存在过，未来也不会存在在任何情况下都不造成数据丢失的算法！ 除时间和空间可能是无限的以外，其它任何具体事物都是有限的。 任何问题首先是一个哲学（世界观）问题。 哲学（世界观）不同/不正确，即道不同/不正确。 道不同不相为谋。 我们的观念不同，虽然有时候数据的丢失时不可逆转的，包括溢出，传输等等情况。但是能不造成数据丢失的情况下，我觉得就不要让数据丢失。即使我们的思想不同，你的观念也改变不了我，我也不想影响你的观念。但是还是谢谢你，因为你有我没有的东西—经验。[/quote] 针对一个数据处理问题，请先定义清楚要加工的数据规格（格式、规模、限制、……），然后再讨论其上将要应用的算法。不然的话，我会认为和空谈没有什么区别。  在磁盘文件FILE1和FILE2中（最大多大？KB、MB、GB、TB、PB、EB、……），各存放着一行字母（最长多长？KB、MB、GB、TB、PB、EB、……），现要求把两个文件中的信息合并（按字母顺序排序），输出到一个新文件FILE3中去（磁盘剩余空间够不够放？）。 你写了两种算法，请问你写的这两种算法在上面（）列出的各种情况下都能正常工作吗？ [/quote]对特殊情况，所程序员才写出报错机制。或者在数据储存的时候特殊处理，数据库的中心思想就是方便取出。这样才挽救数据丢失的情况。难道几代的程序员的努力都是白费了么。。。。。老师，我会仔细理解你跟我说的每一句话的。

引用 22 楼 u014711608 的回复:[quote=引用 20 楼 zhao4zhong1 的回复:] 这个世界上从来就没有存在过，未来也不会存在在任何情况下都不造成数据丢失的算法！ 除时间和空间可能是无限的以外，其它任何具体事物都是有限的。 任何问题首先是一个哲学（世界观）问题。 哲学（世界观）不同/不正确，即道不同/不正确。 道不同不相为谋。 我们的观念不同，虽然有时候数据的丢失时不可逆转的，包括溢出，传输等等情况。但是能不造成数据丢失的情况下，我觉得就不要让数据丢失。即使我们的思想不同，你的观念也改变不了我，我也不想影响你的观念。但是还是谢谢你，因为你有我没有的东西—经验。[/quote] 针对一个数据处理问题，请先定义清楚要加工的数据规格（格式、规模、限制、……），然后再讨论其上将要应用的算法。不然的话，我会认为和空谈没有什么区别。  在磁盘文件FILE1和FILE2中（最大多大？KB、MB、GB、TB、PB、EB、……），各存放着一行字母（最长多长？KB、MB、GB、TB、PB、EB、……），现要求把两个文件中的信息合并（按字母顺序排序），输出到一个新文件FILE3中去（磁盘剩余空间够不够放？）。 你写了两种算法，请问你写的这两种算法在上面（）列出的各种情况下都能正常工作吗？


Question: [swu]c51  流水灯

#include<reg52.h> void delay(int i); int j; main(void) { 	while(1) 	{ 		P1=0xef; 		delay(200); 		P1=0xbf; 		delay(200); 	} }  void delay(int i) { 	for(i;i>0;i--) 		for(j=100;j>0;j--); } 用一个while（1）来表示大循环，再写一个delay延时函数就可以啦


Question: 求一个最优的查找算法

查找算法最低时间复杂度就是O(logn)，再快就只能牺牲存储空间了

在有序的数组查找的话用二分法

二分查找基于一个事实，就是这一次没有找到没有关系，可以把下一次的查找范围缩小一半----即一次查找可以淘汰一半。  用类似的思想，能否淘汰的更多一点？----数学上有一个与0.5（一半）功能类似的常数（0.618....),用好了一次查找可以淘汰一半多（0.618比0.5大），用不好一次查找只能淘汰一小半（（1-0.618）=0.382<0.5） 这个0.618就是大大有名的“黄金分割数”

建立hash表

hash在数据较少时可能比折半慢。

如果这组数有范围的话，那么就将这组数放到数组中，对数的查找是O(1)   远远高于二分查找  如果没范围或者范围太大，hash 查找也是O(1)


unsigned short int RGB888toRGB565(unsigned long int pixel) {     int r = (pixel >> 16) & 0xFF;     int g = (pixel >> 8) & 0xFF;     int b = pixel & 0xFF;      unsigned short B = (b >> 3)                 & 0x001F;     unsigned short G = ((g >> 2) << 5)      & 0x07E0;     unsigned short R = ((red >> 3) << 11) & 0xF800;      return (unsigned short int) (R | G | B); }


Question: 队列算法封装好以后，如果改变定义的DataType类型

把队列算法的数据类型换成缓冲区,标上长度. 编解码工作交给使用的程序.


Question: 怎么用宏定义连接字符串（类似strcat）的功能

#与##在宏定义中的--宏展开 #include <stdio.h> #define f(a,b) a##b #define g(a)   #a #define h(a) g(a) int main() {         printf("%s\n", h(f(1,2)));   // 12         printf("%s\n", g(f(1,2))); // f(1,2)         return 0; } 宏展开时： 如果宏定义以#开头，不展开参数，直接替换。 故g(f(1,2))--->#f(1,2)--->"f(1,2)"； 如果宏定义不以#开头，展开参数，直接替换，由外层向里层，如果碰到的是#开头的宏，不继续往里层展开，往外层展开。 由外层向里层，如果碰到的是以非#开头的宏，继续往里层走，直至最里层，开始一层层往外层展开。 故h(f(1,2))--->h(12)--->g(12)---->#12----->"12"。 PS： ##在宏中定义，是字符连接符 如a##b##c 等同于 "abc" #在宏开头出现，是表示宏展开的方式不同 #a 等同于"a" #abc 等同于 "abc" 复杂的: #include <stdio.h> #define f(a,b) a##b #define g(a)   #a #define h(a) g(a) int main() {         char a = 'a';         cout<<g(a)<<endl; // a         cout<<g(g(a))<<endl; // a         printf("%s\n", h(f(1,2)));   // 12         printf("%s\n", g(f(1,2))); // f(1,2)         printf("%s\n", g(h(f(1,2)))); // h(f(1,2))         printf("%s\n", h(g(f(1,2)))); // "f(1,2)"         printf("%s\n", h(h(f(1,2)))); // "12"         system("pause");         return 0; } 预处理后的：（在编译选项中添加/EP /P后编译生成的.i文件。gcc加-E） int main() {         char a = 'a';         cout<<"a"<<endl;         cout<<"g(a)"<<endl;         printf("%s\n", "12");         printf("%s\n", "f(1,2)");         printf("%s\n", "h(f(1,2))");         printf("%s\n", "\"f(1,2)\"");         printf("%s\n", "\"12\"");         system("pause");         return 0; } --------------------------------------------------- 宏解析 1.       ##操作符 ##操作符它的作用是在替代表中将其前后的参数连接成为一个预处理符号，它不能出现于宏替代表的开端和末尾。 例： #define concat(s,t) s##t #define AAA ABC concat(A, AA) 将被替换成 ABC 2.       重新扫描和替换 在替换列表中的所有参数替换过之后，预处理器将对结果token序列重新扫描以便对其中的宏再次替换。 当正在替换的宏在其替换列表中发现自身时，就不再对其进行替换。在任何正在嵌套替换的宏的替换过程中遇到正被替换的宏就对其不再进行替换（防止递归）。 例： #define ROOT AAA CCC #define AAA ROOT ROOT 将被替换成 ROOT CCC

C++ String Literals A string literal consists of zero or more characters from the source character set surrounded by double quotation marks ("). A string literal represents a sequence of characters that, taken together, form a null-terminated string.  Syntax  string-literal :  "s-char-sequenceopt" L"s-char-sequenceopt"  s-char-sequence :  s-char s-char-sequence s-char  s-char :  any member of the source character set except the double quotation mark ("), backslash (\), or newline character escape-sequence  C++ strings have these types:   Array of char[n], where n is the length of the string (in characters) plus 1 for the terminating '\0' that marks the end of the string   Array of wchar_t, for wide-character strings  The result of modifying a string constant is undefined. For example:  char *szStr = "1234"; szStr[2] = 'A';      // Results undefined  Microsoft Specific   In some cases, identical string literals can be “pooled” to save space in the executable file. In string-literal pooling, the compiler causes all references to a particular string literal to point to the same location in memory, instead of having each reference point to a separate instance of the string literal. The/Gf compiler option enables string pooling.  END Microsoft Specific  When specifying string literals, adjacent strings are concatenated. Therefore, this declaration:  char szStr[] = "12" "34";  is identical to this declaration:  char szStr[] = "1234";  This concatenation of adjacent strings makes it easy to specify long strings across multiple lines:  cout << "Four score and seven years "         "ago, our forefathers brought forth "         "upon this continent a new nation.";  In the preceding example, the entire string Four score and seven years ago, our forefathers brought forth upon this continent a new nation. is spliced together. This string can also be specified using line splicing as follows:  cout << "Four score and seven years \ ago, our forefathers brought forth \ upon this continent a new nation.";  After all adjacent strings in the constant have been concatenated, the NULL character, '\0', is appended to provide an end-of-string marker for C string-handling functions.  When the first string contains an escape character, string concatenation can yield surprising results. Consider the following two declarations:  char szStr1[] = "\01" "23"; char szStr2[] = "\0123";  Although it is natural to assume that szStr1 and szStr2 contain the same values, the values they actually contain are shown in Figure 1.1.  Figure 1.1   Escapes and String Concatenation    Microsoft Specific   The maximum length of a string literal is approximately 2,048 bytes. This limit applies to strings of type char[] and wchar_t[]. If a string literal consists of parts enclosed in double quotation marks, the preprocessor concatenates the parts into a single string, and for each line concatenated, it adds an extra byte to the total number of bytes.   For example, suppose a string consists of 40 lines with 50 characters per line (2,000 characters), and one line with 7 characters, and each line is surrounded by double quotation marks. This adds up to 2,007 bytes plus one byte for the terminating null character, for a total of 2,008 bytes. On concatenation, an extra character is added to the total number of bytes for each of the first 40 lines. This makes a total of 2,048 bytes. (The extra characters are not actually written to the string.) Note, however, that if line continuations (\) are used instead of double quotation marks, the preprocessor does not add an extra character for each line.  END Microsoft Specific  Determine the size of string objects by counting the number of characters and adding 1 for the terminating '\0' or 2 for type wchar_t.  Because the double quotation mark (") encloses strings, use the escape sequence (\") to represent enclosed double quotation marks. The single quotation mark (') can be represented without an escape sequence. The backslash character (\) is a line-continuation character when placed at the end of a line. If you want a backslash character to appear within a string, you must type two backslashes (\\). (SeePhases of Translation in the Preprocessor Reference for more information about line continuation.)  To specify a string of type wide-character (wchar_t[]), precede the opening double quotation mark with the character L. For example:  wchar_t wszStr[] = L"1a1g";  All normal escape codes listed in Character Constants are valid in string constants. For example:  cout << "First line\nSecond line"; cout << "Error! Take corrective action\a";  Because the escape code terminates at the first character that is not a hexadecimal digit, specification of string constants with embedded hexadecimal escape codes can cause unexpected results. The following example is intended to create a string literal containing ASCII 5, followed by the characters five:  \x05five"  The actual result is a hexadecimal 5F, which is the ASCII code for an underscore, followed by the characters ive. The following example produces the desired results:   "\005five"     // Use octal constant. "\x05" "five"  // Use string splicing.

知识点： 1. #x可以将x字符串化； 2. 几个字符串放宏定义里面，会自动合并为一个字符串。      比如#define teststr "hello ""world", 使用printf时可以输出"hello world"

图片怎么不显示了？ 给出代码吧： #include <stdio.h>  #define cat(x,y) #x" "#y  int main() { 	printf("%s\n", cat(hello, world)); 	return 0; }

见图片，如果要增加空格，可以修改 #define cat(x,y) #x" "#y

自寻烦恼:-)

简单问题复杂化?这个貌似不是宏的最主要的用途.

引用 3 楼 taodm 的回复:字符串直接写一起就行了，哪需要宏这么复杂的东西。 "Hello" "world" 赞同。

#define	cat(x, y) x " " y  printf("%s\n", cat("Hello", "world"));

引用define 只会原样输出的  如果只要输出"hello world"  可以define的时候适当的调整引号空格

引用 5 楼 YinQingwei1986 的回复:#define CAT(x,y)    #(x##y) #是为#后首个参数加"" ##是连接前后 你试下 就这个


Question: Linux-关于ImageMagick添加水印

筷子，碗，饭都给你了，还要教你怎么吃饭吗？


Question: 问下一个打印内存的问题

引用 楼主 l360220954 的回复://这个是要在下面使用的那个数据类型的定义 typedef unsigned int UINT8; 然后我定义了一个这么大的缓冲区，该缓冲区总共可以接收1024个数据，每个数据的大小可达8个字节 UINT8 buf[1024][8]; 想问下该怎么打印出某一个缓冲区的数据有16进制表示呢？ 比方说，我现在想打印出buf[0]这个数据缓冲区，该怎么去写这个printf语句呢？  这个win32下是可以打印得出来，在linux下要用%llu

void HexDump(char *buf,int len,int addr) {     int i,j,k;     char binstr[80];      for (i=0;i<len;i++) {         if (0==(i%16)) {             sprintf(binstr,"%08x -",i+addr);             sprintf(binstr,"%s %02x",binstr,(unsigned char)buf[i]);         } else if (15==(i%16)) {             sprintf(binstr,"%s %02x",binstr,(unsigned char)buf[i]);             sprintf(binstr,"%s  ",binstr);             for (j=i-15;j<=i;j++) {                 sprintf(binstr,"%s%c",binstr,('!'<buf[j]&&buf[j]<='~')?buf[j]:'.');             }             printf("%s\n",binstr);         } else {             sprintf(binstr,"%s %02x",binstr,(unsigned char)buf[i]);         }     }     if (0!=(i%16)) {         k=16-(i%16);         for (j=0;j<k;j++) {             sprintf(binstr,"%s   ",binstr);         }         sprintf(binstr,"%s  ",binstr);         k=16-k;         for (j=i-k;j<i;j++) {             sprintf(binstr,"%s%c",binstr,('!'<buf[j]&&buf[j]<='~')?buf[j]:'.');         }         printf("%s\n",binstr);     } }

因为定义成 UINT8 buf[1024][8]; 所以 每个数据的大小可达8个字节。;这个无法解决。 除非额外存储 每个数组几个UINT8。 即再定义一个数组,表示数据长度  int len [1024];  再不然，增加一个数据表示结束数据 定义成 UINT8 buf[1024][ 8 + 1]; 也可以定义为结构数组 struct Data{  int len; UINT8 data[8]; }; struct Data buf[1024];

typedef unsigned char UINT8; UINT8 buf[1024][8];  for(int i =0; i < 1024; i++) { 	unsigned __int64 hexData = *(unsigned __int64*)buf[i]; 	printf("0x%.16I64X\n",hexData); }

把buf的数据解析出来！


Question: 多线程问题

学习了，谢谢

少的话，没问题么，那你看看大概多少的情况下，会失败呢，你检查你每次创建线程都成功了没

学习之。。。顺便+10分

仅供参考//循环向a函数每次发送200个字节长度（这个是固定的）的buffer, //a函数中需要将循环传进来的buffer，组成240字节（也是固定的）的新buffer进行处理， //在处理的时候每次从新buffer中取两个字节打印 #ifdef WIN32     #pragma warning(disable:4996) #endif #include <stdio.h> #include <stdlib.h> #include <string.h> #ifdef WIN32     #include <windows.h>     #include <process.h>     #include <io.h>     #define  MYVOID             void     #define  vsnprintf          _vsnprintf #else     #include <unistd.h>     #include <sys/time.h>     #include <pthread.h>     #define  CRITICAL_SECTION   pthread_mutex_t     #define  MYVOID             void * #endif //Log{ #define MAXLOGSIZE 20000000 #define MAXLINSIZE 16000 #include <time.h> #include <sys/timeb.h> #include <stdarg.h> char logfilename1[]="MyLog1.log"; char logfilename2[]="MyLog2.log"; static char logstr[MAXLINSIZE+1]; char datestr[16]; char timestr[16]; char mss[4]; CRITICAL_SECTION cs_log; FILE *flog; #ifdef WIN32 void Lock(CRITICAL_SECTION *l) {     EnterCriticalSection(l); } void Unlock(CRITICAL_SECTION *l) {     LeaveCriticalSection(l); } void sleep_ms(int ms) {     Sleep(ms); } #else void Lock(CRITICAL_SECTION *l) {     pthread_mutex_lock(l); } void Unlock(CRITICAL_SECTION *l) {     pthread_mutex_unlock(l); } void sleep_ms(int ms) {     usleep(ms*1000); } #endif void LogV(const char *pszFmt,va_list argp) {     struct tm *now;     struct timeb tb;      if (NULL==pszFmt||0==pszFmt[0]) return;     vsnprintf(logstr,MAXLINSIZE,pszFmt,argp);     ftime(&tb);     now=localtime(&tb.time);     sprintf(datestr,"%04d-%02d-%02d",now->tm_year+1900,now->tm_mon+1,now->tm_mday);     sprintf(timestr,"%02d:%02d:%02d",now->tm_hour     ,now->tm_min  ,now->tm_sec );     sprintf(mss,"%03d",tb.millitm);     printf("%s %s.%s %s",datestr,timestr,mss,logstr);     flog=fopen(logfilename1,"a");     if (NULL!=flog) {         fprintf(flog,"%s %s.%s %s",datestr,timestr,mss,logstr);         if (ftell(flog)>MAXLOGSIZE) {             fclose(flog);             if (rename(logfilename1,logfilename2)) {                 remove(logfilename2);                 rename(logfilename1,logfilename2);             }         } else {             fclose(flog);         }     } } void Log(const char *pszFmt,...) {     va_list argp;      Lock(&cs_log);     va_start(argp,pszFmt);     LogV(pszFmt,argp);     va_end(argp);     Unlock(&cs_log); } //Log} #define ASIZE    200 #define BSIZE    240 #define CSIZE      2 char Abuf[ASIZE]; char Cbuf[CSIZE]; CRITICAL_SECTION cs_HEX ; CRITICAL_SECTION cs_BBB ; struct FIFO_BUFFER {     int  head;     int  tail;     int  size;     char data[BSIZE]; } BBB; int No_Loop=0; void HexDump(int cn,char *buf,int len) {     int i,j,k;     char binstr[80];      Lock(&cs_HEX);     for (i=0;i<len;i++) {         if (0==(i%16)) {             sprintf(binstr,"%03d %04x -",cn,i);             sprintf(binstr,"%s %02x",binstr,(unsigned char)buf[i]);         } else if (15==(i%16)) {             sprintf(binstr,"%s %02x",binstr,(unsigned char)buf[i]);             sprintf(binstr,"%s  ",binstr);             for (j=i-15;j<=i;j++) {                 sprintf(binstr,"%s%c",binstr,('!'<buf[j]&&buf[j]<='~')?buf[j]:'.');             }             Log("%s\n",binstr);         } else {             sprintf(binstr,"%s %02x",binstr,(unsigned char)buf[i]);         }     }     if (0!=(i%16)) {         k=16-(i%16);         for (j=0;j<k;j++) {             sprintf(binstr,"%s   ",binstr);         }         sprintf(binstr,"%s  ",binstr);         k=16-k;         for (j=i-k;j<i;j++) {             sprintf(binstr,"%s%c",binstr,('!'<buf[j]&&buf[j]<='~')?buf[j]:'.');         }         Log("%s\n",binstr);     }     Unlock(&cs_HEX); } int GetFromRBuf(int cn,CRITICAL_SECTION *cs,FIFO_BUFFER *fbuf,char *buf,int len) {     int lent,len1,len2;      lent=0;     Lock(cs);     if (fbuf->size>=len) {         lent=len;         if (fbuf->head+lent>BSIZE) {             len1=BSIZE-fbuf->head;             memcpy(buf     ,fbuf->data+fbuf->head,len1);             len2=lent-len1;             memcpy(buf+len1,fbuf->data           ,len2);             fbuf->head=len2;         } else {             memcpy(buf     ,fbuf->data+fbuf->head,lent);             fbuf->head+=lent;         }         fbuf->size-=lent;     }     Unlock(cs);     return lent; } MYVOID thdB(void *pcn) {     char        *recv_buf;     int          recv_nbytes;     int          cn;     int          wc;     int          pb;      cn=(int)pcn;     Log("%03d thdB              thread begin...\n",cn);     while (1) {         sleep_ms(10);         recv_buf=(char *)Cbuf;         recv_nbytes=CSIZE;         wc=0;         while (1) {             pb=GetFromRBuf(cn,&cs_BBB,&BBB,recv_buf,recv_nbytes);             if (pb) {                 Log("%03d recv %d bytes\n",cn,pb);                 HexDump(cn,recv_buf,pb);                 sleep_ms(1);             } else {                 sleep_ms(1000);             }             if (No_Loop) break;//             wc++;             if (wc>3600) Log("%03d %d==wc>3600!\n",cn,wc);         }         if (No_Loop) break;//     } #ifndef WIN32     pthread_exit(NULL); #endif } int PutToRBuf(int cn,CRITICAL_SECTION *cs,FIFO_BUFFER *fbuf,char *buf,int len) {     int lent,len1,len2;      Lock(cs);     lent=len;     if (fbuf->size+lent>BSIZE) {         lent=BSIZE-fbuf->size;     }     if (fbuf->tail+lent>BSIZE) {         len1=BSIZE-fbuf->tail;         memcpy(fbuf->data+fbuf->tail,buf     ,len1);         len2=lent-len1;         memcpy(fbuf->data           ,buf+len1,len2);         fbuf->tail=len2;     } else {         memcpy(fbuf->data+fbuf->tail,buf     ,lent);         fbuf->tail+=lent;     }     fbuf->size+=lent;     Unlock(cs);     return lent; } MYVOID thdA(void *pcn) {     char        *send_buf;     int          send_nbytes;     int          cn;     int          wc;     int           a;     int          pa;      cn=(int)pcn;     Log("%03d thdA              thread begin...\n",cn);     a=0;     while (1) {         sleep_ms(100);         memset(Abuf,a,ASIZE);         a=(a+1)%256;         if (16==a) {No_Loop=1;break;}//去掉这句可以让程序一直循环直到按Ctrl+C或Ctrl+Break或当前目录下存在文件No_Loop         send_buf=(char *)Abuf;         send_nbytes=ASIZE;         Log("%03d sending %d bytes\n",cn,send_nbytes);         HexDump(cn,send_buf,send_nbytes);         wc=0;         while (1) {             pa=PutToRBuf(cn,&cs_BBB,&BBB,send_buf,send_nbytes);             Log("%03d sent %d bytes\n",cn,pa);             HexDump(cn,send_buf,pa);             send_buf+=pa;             send_nbytes-=pa;             if (send_nbytes<=0) break;//             sleep_ms(1000);             if (No_Loop) break;//             wc++;             if (wc>3600) Log("%03d %d==wc>3600!\n",cn,wc);         }         if (No_Loop) break;//     } #ifndef WIN32     pthread_exit(NULL); #endif } int main() { #ifdef WIN32     InitializeCriticalSection(&cs_log);     InitializeCriticalSection(&cs_HEX );     InitializeCriticalSection(&cs_BBB ); #else     pthread_t threads[2];     int threadsN;     int rc;     pthread_mutex_init(&cs_log,NULL);     pthread_mutex_init(&cs_HEX,NULL);     pthread_mutex_init(&cs_BBB,NULL); #endif     Log("Start===========================================================\n");      BBB.head=0;     BBB.tail=0;     BBB.size=0;  #ifdef WIN32     _beginthread((void(__cdecl *)(void *))thdA,0,(void *)1);     _beginthread((void(__cdecl *)(void *))thdB,0,(void *)2); #else     threadsN=0;     rc=pthread_create(&(threads[threadsN++]),NULL,thdA,(void *)1);if (rc) Log("%d=pthread_create %d error!\n",rc,threadsN-1);     rc=pthread_create(&(threads[threadsN++]),NULL,thdB,(void *)2);if (rc) Log("%d=pthread_create %d error!\n",rc,threadsN-1); #endif      if (!access("No_Loop",0)) {         remove("No_Loop");         if (!access("No_Loop",0)) {             No_Loop=1;         }     }     while (1) {         sleep_ms(1000);         if (No_Loop) break;//         if (!access("No_Loop",0)) {             No_Loop=1;         }     }     sleep_ms(3000);     Log("End=============================================================\n"); #ifdef WIN32     DeleteCriticalSection(&cs_BBB );     DeleteCriticalSection(&cs_HEX );     DeleteCriticalSection(&cs_log); #else     pthread_mutex_destroy(&cs_BBB);     pthread_mutex_destroy(&cs_HEX);     pthread_mutex_destroy(&cs_log); #endif     return 0; }

学习下，帮顶

线程局部存贮, TLS, 建议将download_pic也贴出来

引用 4 楼 gigglesun 的回复:貌似是因为while中fp没有自增操作 fgets改成getline看看线程循环了。！而且传过去的参数都是正常的。但是不知道为什么只能下载一部分图片

貌似是因为while中fp没有自增操作 fgets改成getline看看

引用 2 楼 gigglesun 的回复:这个和多线程什么关系while(!feof(fp)) 	{ 		fgets(sparam[j].a,500,fp); 		p[j]=&sparam[j]; 		handle[i]= CreateThread(NULL, 0, download_pic, p[j], 0, NULL); 		j++;i++; 	} 	WaitForMultipleObjects(i,handle,TRUE,INFINITE); 为什么我用wait做阻塞，图片要是多的话只能下载一部分函数就结束了，为什么不是等待这些线程都结束了，才执行wait后面的语句。参数传递都没有出现错误！。

这个和多线程什么关系


Question: 关于 自学 C 语言的问题。自学书籍 C Primer Plus

南阳理工在线acm练习场： http://acm.nyist.net/JudgeOnline/problemset.php你能A掉多少题，就看你造化了。

艺多不压身！ 有时去执行一个错误的决定总比优柔寡断或者没有决定要好得多。 手上的茧子磨的越厚，编程的水平才可能越高。  计算机组成原理→DOS命令→汇编语言→C语言（不包括C++）、代码书写规范→数据结构、编译原理、操作系统→计算机网络、数据库原理、正则表达式→其它语言（包括C++）、架构……  对学习编程者的忠告： 眼过千遍不如手过一遍！ 书看千行不如手敲一行！ 手敲千行不如单步一行！ 单步源代码千行不如单步对应汇编一行！  VC调试时按Alt+8、Alt+7、Alt+6和Alt+5,打开汇编窗口、堆栈窗口、内存窗口和寄存器窗口看每句C对应的汇编、单步执行并观察相应堆栈、内存和寄存器变化，这样过一遍不就啥都明白了吗。 对VC来说，所谓‘调试时’就是编译连接通过以后，按F10或F11键单步执行一步以后的时候，或者在某行按F9设了断点后按F5执行停在该断点处的时候。 （Turbo C或Borland C用Turbo Debugger调试,Linux或Unix下用GDB调试时,看每句C对应的汇编并单步执行观察相应内存和寄存器变化。）

当当网搜索 C语言程序开发范例宝典(第2版) C语言经典编程282例 《C语言点滴》 《C语言课程设计案例精编》

你可以快速把书看完。然后刷C语言经典100题

语言对程序员来说应该不是问题，简单说语言是工具，到底是拿来做UI，做服务，做逻辑，都需要特定领域的知识，而不是语言自身，。

学C语言, 个人推荐The C Programming Language首先要熟悉基本的语法,   然后做一些数据结构相关的练习题， 这个面试也会用到. 最后就是读一些自己感兴趣软件的源代码， 增加一些功能.....

都弄懂了更好，基础牢一点后面学得更轻松。有的问题并不一定是马上学就能弄懂的，可能你看到后面的某个地方的时候会有恍然大悟的感觉。这书可以多看几遍，每一遍都应该是有收获的。至于练习题可以找找那些acm的题练练(ZOJ这些可以百度看看).


Question: 关于动态内存的分配与释放

引用 49 楼 zhao4zhong1 的回复:[quote=引用 48 楼 arthuryangsh 的回复:] [quote=引用 35 楼 wenbo228228 的回复:] 听说OpenGL写的很混，不如3Dmax,有木有写3D游戏的同志，你们用什么写的 3Dmax是用来建模的吧？ 3D编程其实只有OpenGL和Direct3D两种选择。[/quote] Android和iOS上3D编程用啥呢？[/quote] OpenGL及其兄弟们

第一个free释放了，你怎么知道第二个free执行了？段错误是什么？麻烦解释下

引用 49 楼 zhao4zhong1 的回复:[quote=引用 48 楼 arthuryangsh 的回复:] [quote=引用 35 楼 wenbo228228 的回复:] 听说OpenGL写的很混，不如3Dmax,有木有写3D游戏的同志，你们用什么写的 3Dmax是用来建模的吧？ 3D编程其实只有OpenGL和Direct3D两种选择。[/quote] Android和iOS上3D编程用啥呢？[/quote] 仍然是OpenGL

引用 47 楼 wenbo228228 的回复:[quote=引用 37 楼 nadleeh123 的回复:] [quote=引用 楼主 wenbo228228 的回复:] #include <stdio.h> #include <malloc.h> void f(int ** q) {     *q=(int *)malloc(sizeof(int));     **q=5;     free(q); } int main() {     int * p;     f(&p);     printf("%d\n",*p); 	return 0; }   在f（）函数中已经把p变量给释放了，为什么程序还是正确的？  为什么你认为内存被释放了然后内存就不能访问了[/quote]  被释放了还能访问吗？我觉得不可以吧[/quote] 如果释放后就不能访问: char *p = malloc（100）； free(p); free(p); 第二个free就不能够重复释放了，而不是段错误

引用 48 楼 arthuryangsh 的回复:[quote=引用 35 楼 wenbo228228 的回复:] 听说OpenGL写的很混，不如3Dmax,有木有写3D游戏的同志，你们用什么写的 3Dmax是用来建模的吧？ 3D编程其实只有OpenGL和Direct3D两种选择。[/quote] Android和iOS上3D编程用啥呢？

引用 50 楼 nadleeh123 的回复:[quote=引用 47 楼 wenbo228228 的回复:] [quote=引用 37 楼 nadleeh123 的回复:] [quote=引用 楼主 wenbo228228 的回复:] #include <stdio.h> #include <malloc.h> void f(int ** q) {     *q=(int *)malloc(sizeof(int));     **q=5;     free(q); } int main() {     int * p;     f(&p);     printf("%d\n",*p); 	return 0; }   在f（）函数中已经把p变量给释放了，为什么程序还是正确的？  为什么你认为内存被释放了然后内存就不能访问了[/quote]  被释放了还能访问吗？我觉得不可以吧[/quote] 如果释放后就不能访问: char *p = malloc（100）； free(p); free(p); 第二个free就不能够重复释放了，而不是段错误[/quote]  第一个释放后，你怎么知道第二个释放语句是否执行成功了？

引用 51 楼 arthuryangsh 的回复:[quote=引用 49 楼 zhao4zhong1 的回复:] [quote=引用 48 楼 arthuryangsh 的回复:] [quote=引用 35 楼 wenbo228228 的回复:] 听说OpenGL写的很混，不如3Dmax,有木有写3D游戏的同志，你们用什么写的 3Dmax是用来建模的吧？ 3D编程其实只有OpenGL和Direct3D两种选择。[/quote] Android和iOS上3D编程用啥呢？[/quote] 仍然是OpenGL[/quote] 哦。 那Direct3D不能用了吧。

引用 35 楼 wenbo228228 的回复:听说OpenGL写的很混，不如3Dmax,有木有写3D游戏的同志，你们用什么写的 3Dmax是用来建模的吧？ 3D编程其实只有OpenGL和Direct3D两种选择。

引用 37 楼 nadleeh123 的回复:[quote=引用 楼主 wenbo228228 的回复:] #include <stdio.h> #include <malloc.h> void f(int ** q) {     *q=(int *)malloc(sizeof(int));     **q=5;     free(q); } int main() {     int * p;     f(&p);     printf("%d\n",*p); 	return 0; }   在f（）函数中已经把p变量给释放了，为什么程序还是正确的？  为什么你认为内存被释放了然后内存就不能访问了[/quote]  被释放了还能访问吗？我觉得不可以吧

引用 41 楼 user-8 的回复:[quote=引用 40 楼 nadleeh123 的回复:] [quote=引用 39 楼 user-8 的回复:] [quote=引用 37 楼 nadleeh123 的回复:] [quote=引用 楼主 wenbo228228 的回复:] #include <stdio.h> #include <malloc.h> void f(int ** q) {     *q=(int *)malloc(sizeof(int));     **q=5;     free(q); } int main() {     int * p;     f(&p);     printf("%d\n",*p); 	return 0; }   在f（）函数中已经把p变量给释放了，为什么程序还是正确的？  为什么你认为内存被释放了然后内存就不能访问了[/quote] 这个确实不一定，因为释放后，它的映射的物理内存不一定解除映射，只是将这块内存块置为free（可被再次使用），这块内存里面的数据可能还在；[/quote] system up，内存管理单元完成初始化后，所有的内存就在os的监管下，不知道你从哪里学到了的物理内存会在使用后解除映射这种观点。[/quote] 在linux C下，分配堆内存机制就是这样，如果程序一次申请的堆内存过多，使用完后，是不是要解除一部分的物理内存映射，留下几页的物理内存映射？[/quote] 看来你对内存映射理解有点偏差，你所说是堆内存分配只是在分页表里面建立相应数据结构，用完free后删除数据结构，表明相关页处于空闲状态  引用 41 楼 user-8 的回复:[quote=引用 40 楼 nadleeh123 的回复:] [quote=引用 39 楼 user-8 的回复:] [quote=引用 37 楼 nadleeh123 的回复:] [quote=引用 楼主 wenbo228228 的回复:] #include <stdio.h> #include <malloc.h> void f(int ** q) {     *q=(int *)malloc(sizeof(int));     **q=5;     free(q); } int main() {     int * p;     f(&p);     printf("%d\n",*p); 	return 0; }   在f（）函数中已经把p变量给释放了，为什么程序还是正确的？  为什么你认为内存被释放了然后内存就不能访问了[/quote] 这个确实不一定，因为释放后，它的映射的物理内存不一定解除映射，只是将这块内存块置为free（可被再次使用），这块内存里面的数据可能还在；[/quote] system up，内存管理单元完成初始化后，所有的内存就在os的监管下，不知道你从哪里学到了的物理内存会在使用后解除映射这种观点。[/quote] 在linux C下，分配堆内存机制就是这样，如果程序一次申请的堆内存过多，使用完后，是不是要解除一部分的物理内存映射，留下几页的物理内存映射？[/quote]  你所说的这个过程并不是物理地址到虚拟地址的转化，只是维护mmu的页表数据结构罢了，如果free之后就解除了内存映射，那么 char *p = malloc（100）； free（p）； *p = xxx; 这种情况根本就不会出现野指针，第3行就不会被执行，因为会直接段错误。 MMU是个很复杂的玩意儿，以至于powerpc 的某版架构还专门设计了一个硬件机构来加速虚拟地址到物理地址的转化，os启动后物理地址到虚拟地址的映射不会像malloc-free那样频繁去变动，因为维护起来很麻烦，也耗时。

The free() function deallocates the space pointed to by ptr, freeing it up for future use. ptr must have been used in a previous call to malloc(), calloc(), or realloc(). free（）函数只能释放由以上几个函数分配的内存，以上几个函数分配的内存在堆中，而你程序中的变量p不在堆而在栈中，所以free()不能释放p。

使用free(q);意图释放指针p的内存，但指针p不是通过malloc在堆中申请的动态内存，而是和普通的类型 如 int i一样存放在栈里，当调用free时，是无法在堆中查询到，也就无从释放  而且在C++中，就算内存被释放了，也就是变成野指针了，有时也是可以使用的，不过出现的结果是不可预知的，如果此时没有对被释放的内存进行过写操作，使用的结果也可能是正确的。即这个内存地址你已经不使用了，但别人不知道还跑来用，但里面的内容没有发生改变，此时别人也能当正常的使用一下。

引用 39 楼 user-8 的回复:[quote=引用 37 楼 nadleeh123 的回复:] [quote=引用 楼主 wenbo228228 的回复:] #include <stdio.h> #include <malloc.h> void f(int ** q) {     *q=(int *)malloc(sizeof(int));     **q=5;     free(q); } int main() {     int * p;     f(&p);     printf("%d\n",*p); 	return 0; }   在f（）函数中已经把p变量给释放了，为什么程序还是正确的？  为什么你认为内存被释放了然后内存就不能访问了[/quote] 这个确实不一定，因为释放后，它的映射的物理内存不一定解除映射，只是将这块内存块置为free（可被再次使用），这块内存里面的数据可能还在；[/quote]  system up，内存管理单元完成初始化后，所有的内存就在os的监管下，不知道你从哪里学到了的物理内存会在使用后解除映射这种观点。

引用 楼主 wenbo228228 的回复:#include <stdio.h> #include <malloc.h> void f(int ** q) {     *q=(int *)malloc(sizeof(int));     **q=5;     free(q); } int main() {     int * p;     f(&p);     printf("%d\n",*p); 	return 0; }   在f（）函数中已经把p变量给释放了，为什么程序还是正确的？  （1）free错误，应该free(*p)； （2）free（p），p根本没有分配空间，里面只有一个地址

在Linux 中  程序运行  第一次申请 栈内存  会映射33页   内存   也就是 4096*33 个字节 ， malloc底层实现了一个链表 管理着 这些映射的内存  当33页使用满了   会再次映射1页 或者多页 （N*4096  >= 你申请的内存） free只是标示一下这块空间不使用了，如果这块内存正处于 解除映射的物理空间内    再次访问此地址 会出现 段错误     如果这块映射空间没有被解除映射 ，数据也就存在，所以可以访问得到   ，建议不要这样使用

引用 40 楼 nadleeh123 的回复:[quote=引用 39 楼 user-8 的回复:] [quote=引用 37 楼 nadleeh123 的回复:] [quote=引用 楼主 wenbo228228 的回复:] #include <stdio.h> #include <malloc.h> void f(int ** q) {     *q=(int *)malloc(sizeof(int));     **q=5;     free(q); } int main() {     int * p;     f(&p);     printf("%d\n",*p); 	return 0; }   在f（）函数中已经把p变量给释放了，为什么程序还是正确的？  为什么你认为内存被释放了然后内存就不能访问了[/quote] 这个确实不一定，因为释放后，它的映射的物理内存不一定解除映射，只是将这块内存块置为free（可被再次使用），这块内存里面的数据可能还在；[/quote] system up，内存管理单元完成初始化后，所有的内存就在os的监管下，不知道你从哪里学到了的物理内存会在使用后解除映射这种观点。[/quote] 在linux C下，分配堆内存机制就是这样，如果程序一次申请的堆内存过多，使用完后，是不是要解除一部分的物理内存映射，留下几页的物理内存映射？

引用 28 楼 wenbo228228 的回复:问个题外话，我想写个fps（第一人称射击游戏），类似cf,当然不可能像cf那么复杂，只是简单的有一张地图，可以连接玩家在里面游戏，需要学习那些知识，我现在只会c语言基础 搜网络教程“学OpenGL编3D游戏”。

引用 37 楼 nadleeh123 的回复:[quote=引用 楼主 wenbo228228 的回复:] #include <stdio.h> #include <malloc.h> void f(int ** q) {     *q=(int *)malloc(sizeof(int));     **q=5;     free(q); } int main() {     int * p;     f(&p);     printf("%d\n",*p); 	return 0; }   在f（）函数中已经把p变量给释放了，为什么程序还是正确的？  为什么你认为内存被释放了然后内存就不能访问了[/quote] 这个确实不一定，因为释放后，它的映射的物理内存不一定解除映射，只是将这块内存块置为free（可被再次使用），这块内存里面的数据可能还在；

引用 34 楼 wenbo228228 的回复:[quote=引用 32 楼 user-8 的回复:] int i=5;   //这个i是在栈中的，（32位系统下，它占用四个字节），这个i在栈中也是有地址的，这个地址值也是也是四个字节； int * p=&i;  //定义一个int指针变量，这个指针变量也是占用4个字节（32位系统下），这四个字节里面存的是i变量的地址（四个字节），计算机内部变量的地址是指变量的低位字节的地址值，可以这么说，i的低位第一字节的地址和p指针变量里面存放的地址值是一样的；  也就是说，p这个指针变量,它4个字节的空间总共32个01代码，比如说00000000 01100000 00001111 11011101，存放的是i这个整形变量第一个字节在内存中的地址编号，我说的对吗?[/quote] 当你nt *p=&i时，在编译时，p指针变量里面被填充成i变量的地址； 你把变量i的四个字节看成一个整体，i的地址就是它第一个字节的地址； 就是这样的，如果想深入了解这方面，看看汇编知识。。

引用 楼主 wenbo228228 的回复:#include <stdio.h> #include <malloc.h> void f(int ** q) {     *q=(int *)malloc(sizeof(int));     **q=5;     free(q); } int main() {     int * p;     f(&p);     printf("%d\n",*p); 	return 0; }   在f（）函数中已经把p变量给释放了，为什么程序还是正确的？  为什么你认为内存被释放了然后内存就不能访问了


Question: 结构体指针

你难道不知到地址也可以用整形输出吗

问题是，你定义的结构体 struct student  {  int num;  int score;  struct student* next;  }; 在main函数中，也就是说，你的oi中的(struct student)类型并没有声明，出现类型不匹配的情况，将struct的定义放在全局就没问题了，/*main.cpp*/ #include<stdio.h>  struct student { 	int num; 	int score;		 	struct student* next; };  void oi(struct student *z);  int main() { 	struct student *k, *k1, p; 	k = &p; 	k1 = k; 	printf("%d %d ",k,k1); 	oi(&p); 	return 0;  }  void oi(struct student *z) { 	struct student *q; 	q = z; 	printf("%d",q); }

void oi(struct student *z); #include<stdio.h> int main() { struct student { int num; int score; struct student* next; }; struct student * k,*k1,p; k=&p;//p只是声明了，没有定义，也就是说没有为p分配内存，取地址无意义 k1=k;//此处k没有初始化，不能赋值 printf("%d %d ",k,k1); oi(&p); return 0;	 } void oi(struct student *z) { struct student *q; q=z; printf("%d",q);  }

k=&p;  没初始化

printf("%d %d ",k,k1); 把指针变量的值以整型输出？谁教你的？


Question: C语言正弦值输出结果的问题

sin和cos函数传入的参数是弧度不是角度

我看看是否如此

程序运行是正确的。 楼主没有搞清楚这个函数的使用方法，sin和cos函数传入的参数是弧度不是角度，你如果想得到sin(30°)的结果，先转换下吧


引用 9 楼 line_us 的回复:看看错在哪，怎么弄。还望大神指点解题思路~

引用 11 楼 zhao4zhong1 的回复:printf里面的%和变量的一一对应关系 scanf里面的%和变量以及变量前加不加&的一一对应关系 是C代码中非常容易出错的地方，而且通常编译还不出错。 所以在编译源代码之前值得专门仔细检查一遍甚至多遍。  在每个最后不带\n的printf后面加fflush(stdout); 在每个不想受接收缓冲区旧内容影响的scanf前面加rewind(stdin); 另外请检查scanf的返回值。说得很细致，只是这样的内容对一个菜鸟来说根本不能实践啊

引用 5 楼 q5390498 的回复:楼主， printf("please input the number of zushu"); 这一类的提示在oj是不会出现的，要严格按照题目要求来，至于算法，我也同求好的，受教了~

引用 1 楼 user-6 的回复:= =哥哥。。请多刷几道题。。。我正在刷题中。。。所以才有问题啊~~~

看看错在哪，怎么弄。

引用 3 楼 anshiny 的回复:以下代码供参考：  #include<stdio.h> #include<math.h> #define SIZE            1001 #define TIME_PER_TRACK  400 #define TIME_PER_SECTOR 1 #define TIME_PER_READ   10 int main() { 	struct _point { 		int track; 		int sector; 	} point[SIZE];          int group, number, i, j; 	int sumTrack, sumSector, sumRead, sum;     scanf("%d", &group);//组数     for(i=0; i<group; i++)     { 		sumTrack = 0, sumSector = 0, sumRead = 0;         scanf("%d", &number); 		point[0].track = 0; 		point[0].sector = 0;         for(j=1; j<=number; j++)         {             scanf("%d%d", &point[j].track, &point[j].sector);         }         for(j=1; j<=number; j++)         {             sumTrack += (point[j].track - point[j - 1].track) * 2 * TIME_PER_TRACK;             if(abs(point[j].sector - point[j - 1].sector) < 180){ 				sumSector += abs(point[j].sector - point[j - 1].sector) * TIME_PER_SECTOR; 			} else{ 				sumSector += (360 - abs(point[j].sector - point[j - 1].sector)) * TIME_PER_SECTOR; 			} 			sumRead += 10;         } 		         if(abs(point[number].sector - point[0].sector) < 180){ 			sumSector += abs(point[number].sector - point[0].sector) * TIME_PER_SECTOR; 		} else{ 			sumSector += (360 - abs(point[number].sector - point[0].sector)) * TIME_PER_SECTOR; 		} 		sum = sumTrack + sumSector + sumRead; 		printf("%d\n", sum);     } 	 	printf("%d", sum); 	return 0; }  楼上的过了？我测试了你的好多数据，跟我的都一样，感觉我们的代码都差不多，能看看吗？ #include<iostream> #include<fstream> #include<cmath> using namespace std; typedef struct s { 	int x,y; }ss; int  sub(int i,int j) { 	int t; 	if(i<j) 	{ 		t=i; 		i=j; 		j=t; 	} 	if((i-j)>180) 		return (360-i)+j; 	return i-j; } int f(int i) { 	if(i>180) 		return 360-i; 	return i; } int main() { //	ifstream cin("aa.txt"); 	int T; 	cin>>T; 	while(T--) 	{ 		int n; 		cin>>n; 		int i; 		ss x[1000+10]; 		x[0].x=0; 		x[0].y=0; 		x[n+1].x=0; 		x[n+1].y=0; 		long long  sum1=0,sum2=0; 		for(i=1;i<=n;i++) 		{ 			cin>>x[i].x>>x[i].y; 			sum1+=400*(x[i].x-x[i-1].x)+sub(x[i].y,x[i-1].y); 			sum1+=10; 		} 		sum1+=400*(x[n].x)+f(x[n].y); 			cout<<sum1<<endl; 	} }

scanf("%d%d",gd[j],sq[j]); 这可能是最致命的错误。

= =哥哥。。请多刷几道题。。。


Question: C语言 有关指针的问题，希望大神们给讲解一下

引用 4 楼 oYinGui1 的回复:[quote=引用 3 楼 slmw1234 的回复:] [quote=引用 2 楼 oYinGui1 的回复:]  *p1++     //等价于 *p1, p1++，但是并不是说单目*的优先级比++高 *++p1     //等价于 ++p1, *p1，同上，前缀后缀的++--优先级都是比单目*高的 (*p1)++   //这个就是解引用了再对指针指向的值自增  优先级查表就行。懒得查就自己加括号，不要写得自己都不知道是什么意思就行了  	printf("*p1++ = %d, *++p2 = %d, (*p3)++ = %d\n", *p1++, *++p2, (*p3)++); //*p1++在本行的打印结果是*p1指针指向地址的值，然后在下一行打印的时候打印出指向下一个地址里面的值。那是不是就是说在打印*p1++的同时，系统做了两个动作，第一个是因为++运算符的优先级大于*，所以p1的地址增量运算。第二个动作才是打印*p1指针指向的值到屏幕上。（*p3）也是同样做了两个动作。 	printf("*p1 = %d, *p2 = %d, *p3 = %d\n", *p1, *p2, *p3);//这里由于在上一行代码里*p1 和 *p3已经做了处理，所有打印发生了变化  [/quote] 差不多是这个意思。关于这种表达，可以翻看一下C++ primer，里面说的很详细。[/quote]   谢谢你的提示，我就是在看c primer plus 这本书自学的。

引用 3 楼 slmw1234 的回复:[quote=引用 2 楼 oYinGui1 的回复:]  *p1++     //等价于 *p1, p1++，但是并不是说单目*的优先级比++高 *++p1     //等价于 ++p1, *p1，同上，前缀后缀的++--优先级都是比单目*高的 (*p1)++   //这个就是解引用了再对指针指向的值自增  优先级查表就行。懒得查就自己加括号，不要写得自己都不知道是什么意思就行了  	printf("*p1++ = %d, *++p2 = %d, (*p3)++ = %d\n", *p1++, *++p2, (*p3)++); //*p1++在本行的打印结果是*p1指针指向地址的值，然后在下一行打印的时候打印出指向下一个地址里面的值。那是不是就是说在打印*p1++的同时，系统做了两个动作，第一个是因为++运算符的优先级大于*，所以p1的地址增量运算。第二个动作才是打印*p1指针指向的值到屏幕上。（*p3）也是同样做了两个动作。 	printf("*p1 = %d, *p2 = %d, *p3 = %d\n", *p1, *p2, *p3);//这里由于在上一行代码里*p1 和 *p3已经做了处理，所有打印发生了变化  [/quote] 差不多是这个意思。关于这种表达，可以翻看一下C++ primer，里面说的很详细。

引用 2 楼 oYinGui1 的回复: *p1++     //等价于 *p1, p1++，但是并不是说单目*的优先级比++高 *++p1     //等价于 ++p1, *p1，同上，前缀后缀的++--优先级都是比单目*高的 (*p1)++   //这个就是解引用了再对指针指向的值自增  优先级查表就行。懒得查就自己加括号，不要写得自己都不知道是什么意思就行了  	printf("*p1++ = %d, *++p2 = %d, (*p3)++ = %d\n", *p1++, *++p2, (*p3)++); //*p1++在本行的打印结果是*p1指针指向地址的值，然后在下一行打印的时候打印出指向下一个地址里面的值。那是不是就是说在打印*p1++的同时，系统做了两个动作，第一个是因为++运算符的优先级大于*，所以p1的地址增量运算。第二个动作才是打印*p1指针指向的值到屏幕上。（*p3）也是同样做了两个动作。 	printf("*p1 = %d, *p2 = %d, *p3 = %d\n", *p1, *p2, *p3);//这里由于在上一行代码里*p1 和 *p3已经做了处理，所有打印发生了变化

*p1++ 你看看运算符的优先级，如果*的优先级比右边++大，那*p++就是取p指向的变量再对变量++。 如果*的优先级小于右边的++，那么先对指针p1进行++操作，再去p1指向的变量  （*p3）++  取p3指向的变量再对变量++。  你要弄清楚的是： 1.*和++的优先级问题。 2.指针的++操作代表什么？ 3.左++和右++的区别 4.数组名和指针的异同


Question: 循环内if判断过后直接销毁这段语句..

楼主好想法，不过这种机制，我没听说过。

引用 10 楼 Blizzard_whx 的回复:[quote=引用 9 楼 u013115296 的回复:] [quote=引用 3 楼 starytx 的回复:] 我真的没明白你在说什么void main() {       for(int op = 0 ; op < 5 ; op++)     {          if(op == 3)           cout << "DS" ;       MessageBox(NULL,TEXT("test"),TEXT("test"),0) ;    } } 这个if只是当 op == 3 才会成立..但是 op只有一次为3 但是每次他都会判断if..按理说..op等于3之后的if操作一点意义都没有....所以感觉有点累赘啦~[/quote] 首先，这句判断消耗不是很大，楼主大没必要把精力花在如何优化它上 其实，实在要做也不是没有办法，那就是  for(int op = 0;op < 5,;i++) {     if(op == 3)     {         //code         break;     } } for(int op = 0;op < 5,;i++) {      //code }     但是楼主觉得有这样的必要吗？[/quote] 写错了，第二个for循环从op=4开始

引用 9 楼 u013115296 的回复:[quote=引用 3 楼 starytx 的回复:] 我真的没明白你在说什么void main() {       for(int op = 0 ; op < 5 ; op++)     {          if(op == 3)           cout << "DS" ;       MessageBox(NULL,TEXT("test"),TEXT("test"),0) ;    } } 这个if只是当 op == 3 才会成立..但是 op只有一次为3 但是每次他都会判断if..按理说..op等于3之后的if操作一点意义都没有....所以感觉有点累赘啦~[/quote] 首先，这句判断消耗不是很大，楼主大没必要把精力花在如何优化它上 其实，实在要做也不是没有办法，那就是  for(int op = 0;op < 5,;i++) {     if(op == 3)     {         //code         break;     } } for(int op = 0;op < 5,;i++) {      //code }     但是楼主觉得有这样的必要吗？

引用 12 楼 u011192174 的回复:楼主好想法，不过这种机制，我没听说过。忘了..结贴了。。好蠢..

引用 3 楼 starytx 的回复:我真的没明白你在说什么void main() {       for(int op = 0 ; op < 5 ; op++)     {          if(op == 3)           cout << "DS" ;       MessageBox(NULL,TEXT("test"),TEXT("test"),0) ;    } } 这个if只是当 op == 3 才会成立..但是 op只有一次为3 但是每次他都会判断if..按理说..op等于3之后的if操作一点意义都没有....所以感觉有点累赘啦~

引用 1 楼 baichi4141 的回复:1 没有这种机制 楼主想要的大概是一个能够自我编程的人工智能，如果真的有这种东西，它一定能够计算出当它出现后，人类已经一点用都没有了，然后把人类销毁掉  2 你的大括号是给编译器看的，运行看的是代码的意义而不是代码的格式，在某些情形下连大括号本身都会被编译器优化掉 如果想在结束循环之前做什么，在循环体的最后一行写下就行，如果不想明确的写出来，可以使用析构函数等机制好吧..我想多了..

引用 6 楼 zilaishuichina 的回复:lz为什么想把代码销毁了   是担心每次都要做if判断浪费时间 还是什么意思？只是觉得没必要的废操作看着膈应..

lz为什么想把代码销毁了   是担心每次都要做if判断浪费时间 还是什么意思？

程序就是代码，计算机只会按照你的代码执行，真不知道你是想控制代码还是控制程序运行流程，有点乱

楼主说的是美军侦查机的自毁么？

我真的没明白你在说什么

1 一些嵌入式环境估计运行时改变代码段也是可以的 2  你是想运行到所有大括号都输出信息？不知道可不可以用宏定义


Question: IOS平台，用C语言开发些什么？

Objective-C是C的超集，合法的C代码即OC的代码，故LZ的命题就有逻辑问题。

不明觉厉，一同共勉！

不知道为什么有了 C++ 还要衍生出这种东西...

这个平台开发一次，那个平台再开发一次。 累死你！

在多个平台开发，讲究是：跨平台，效率。

Objective-C与其它的语言的对接会在以后的时间里，只会给你带来麻烦！

user-5：   笑话一件！   难道你用cocos2D-x引擎开发游戏，你用C语言了？

给你建议是： iOS平台上最好的做法是使用Objective-C编程。  用什么语言来编程，对程序员来说，不成问题。


Question: 数组问题，新手

可以把写代码的人迁出去枪毙一百遍，完全不知道写的什么，各种错误

(unsigned char*) & a[0] 得到数组地址 相当于 a

你这语句写的。各种问题啊。没返回值，参数类型也错误 那有 *char 的，都是char * #include <stdio.h> char a[10]; char dibm(char *a) { 	return	a[0]-1;  } void main() { 	char a[10]="bcdefe";  	printf("%c\n",dibm(&a[0])); }  a[0]-1; 就是a[0] 所指的值，减1， 这里应 是取数组的首地址，为参进入函数 ，

a[0]就是数组的首地址，将数组首地址传递给函数指针参数，a[0]-1就是a[0]的值减一

dibm(*char a)  {   a[0]-1;    }   1.没有写返回值类型，语法错误 2.参数类型没有写对，字符型指针，应该是 char * ，而不是 * char，C或者C++里面似乎没有这种写法 3.若函数没有返回值，那么这个函数相当于什么也没有做。 4.调用dibm时的实参，相当于是拷贝了一个指针进去。


Question: error LNK2019 ,这是缺少什么lib?

引用 17 楼 zhao4zhong1 的回复:[quote=引用 16 楼 ggxxkkll 的回复:] [quote=引用 14 楼 zhao4zhong1 的回复:] 将错误信息中出现的标识符放在google里面搜一下，看其在哪个.lib中，然后在本地硬盘上搜索该.lib,如果没有，在网上搜索相关库或模块下载安装，然后将其所在目录填写到“附加依赖库所在目录”中，将其名字添加到“附加依赖库”中，重新连接。 VC6： 工程、设置、C/C++、分类：Preprocessor、附加包含路径：填写附加头文件所在目录 逗号间隔多项 工程、设置、Link、分类：Input、附加库路径：填写附加依赖库所在目录 分号间隔多项 工程、设置、Link、分类：Input、对象/库模块：填写附加依赖库的名字.lib 空格间隔多项 VS20xx： 项目、属性、C/C++、附加包含目录：填写附加头文件所在目录 分号间隔多项 项目、属性、链接器、常规、附加库目录：填写附加依赖库所在目录 分号间隔多项 项目、属性、链接器、输入、附加依赖项：填写附加依赖库的名字.lib 空格或分号间隔多项   大哥，您好！ 又出现了新的错误：  1>     正在创建库 E:\Driverprogram\imgport\Debug\imgport.dll 和对象 E:\Driverprogram\imgport\Debug\imgport.exp 1>LINK : fatal error LNK1104: 无法打开文件“E:\Driverprogram\imgport\Debug\imgport.dll” 1>  网上搜了一大堆，都没有解决。 这个问题，该如何解决？ 谢谢大哥！[/quote] 关闭防火墙和杀毒软件，重建所有。 试试看。[/quote]  都已经关闭了，还是提示相同的错误啊？？？

确认文件夹E:\Driverprogram\imgport\Debug\存在。 重建所有

引用 13 楼 ggxxkkll 的回复:[quote=引用 12 楼 lming_08 的回复:] dll库都出不来，这个很有可能是没有引用其他的库，找找到底是什么库  怎么找啊？ 就是因为找不到，才发帖求助啊！！！[/quote] 你把里面引用的一些函数在百度上艘一下不久出来了，我搜了下，应该是libjpeg.lib

引用 12 楼 lming_08 的回复:dll库都出不来，这个很有可能是没有引用其他的库，找找到底是什么库  怎么找啊？ 就是因为找不到，才发帖求助啊！！！

dll库都出不来，这个很有可能是没有引用其他的库，找找到底是什么库

引用 10 楼 zcdabing 的回复:[quote=引用 6 楼 ggxxkkll 的回复:] [quote=引用 4 楼 zcdabing 的回复:] dll加到工程目录了没  我现在只是编译 DLL，都编译通不过，  还没有开始弄控制应用程序[/quote]  你加lib不就是想使用DLL，DLL要加入你创建DLL的目录或者放在别的地方也行，需要加入环境变量[/quote]  DLL要加入你创建DLL的目录或者放在别的地方也行 怎么加，在哪里加啊？  加入环境变量 是右键 我的电脑-》高级-》环境变量，是在这里设置吗？   非常感谢！

引用 16 楼 ggxxkkll 的回复:[quote=引用 14 楼 zhao4zhong1 的回复:] 将错误信息中出现的标识符放在google里面搜一下，看其在哪个.lib中，然后在本地硬盘上搜索该.lib,如果没有，在网上搜索相关库或模块下载安装，然后将其所在目录填写到“附加依赖库所在目录”中，将其名字添加到“附加依赖库”中，重新连接。 VC6： 工程、设置、C/C++、分类：Preprocessor、附加包含路径：填写附加头文件所在目录 逗号间隔多项 工程、设置、Link、分类：Input、附加库路径：填写附加依赖库所在目录 分号间隔多项 工程、设置、Link、分类：Input、对象/库模块：填写附加依赖库的名字.lib 空格间隔多项 VS20xx： 项目、属性、C/C++、附加包含目录：填写附加头文件所在目录 分号间隔多项 项目、属性、链接器、常规、附加库目录：填写附加依赖库所在目录 分号间隔多项 项目、属性、链接器、输入、附加依赖项：填写附加依赖库的名字.lib 空格或分号间隔多项   大哥，您好！ 又出现了新的错误：  1>     正在创建库 E:\Driverprogram\imgport\Debug\imgport.dll 和对象 E:\Driverprogram\imgport\Debug\imgport.exp 1>LINK : fatal error LNK1104: 无法打开文件“E:\Driverprogram\imgport\Debug\imgport.dll” 1>  网上搜了一大堆，都没有解决。 这个问题，该如何解决？ 谢谢大哥！[/quote] 关闭防火墙和杀毒软件，重建所有。 试试看。

引用 14 楼 zhao4zhong1 的回复:将错误信息中出现的标识符放在google里面搜一下，看其在哪个.lib中，然后在本地硬盘上搜索该.lib,如果没有，在网上搜索相关库或模块下载安装，然后将其所在目录填写到“附加依赖库所在目录”中，将其名字添加到“附加依赖库”中，重新连接。 VC6： 工程、设置、C/C++、分类：Preprocessor、附加包含路径：填写附加头文件所在目录 逗号间隔多项 工程、设置、Link、分类：Input、附加库路径：填写附加依赖库所在目录 分号间隔多项 工程、设置、Link、分类：Input、对象/库模块：填写附加依赖库的名字.lib 空格间隔多项 VS20xx： 项目、属性、C/C++、附加包含目录：填写附加头文件所在目录 分号间隔多项 项目、属性、链接器、常规、附加库目录：填写附加依赖库所在目录 分号间隔多项 项目、属性、链接器、输入、附加依赖项：填写附加依赖库的名字.lib 空格或分号间隔多项   大哥，您好！ 又出现了新的错误：  1>     正在创建库 E:\Driverprogram\imgport\Debug\imgport.dll 和对象 E:\Driverprogram\imgport\Debug\imgport.exp 1>LINK : fatal error LNK1104: 无法打开文件“E:\Driverprogram\imgport\Debug\imgport.dll” 1>  网上搜了一大堆，都没有解决。 这个问题，该如何解决？ 谢谢大哥！

extern "C"

我把所有的库： msvcmrt.lib;msvcmrtd.lib;msvcprt.lib;msvcprtd.lib;msvcurt.lib;msvcurtd.lib;msvcrt.lib;msvcrtd.lib;oldnames.lib;pgobootrun.lib;pgort.lib;ptrustm.lib;ptrustmd.lib;ptrustu.lib;ptrustud.lib;RunTmChk.lib;vcomp.lib;vcompd.lib  都加进去了，然后编译又出现了如下error： 1>msvcurt.lib(ti_inst.obj) : fatal error LNK1313: 检测到 pure 模块；无法与 ijw/native 模块链接  采用网上的方法： 工程属性=》配置属性=》常规=》公共语言运行库支持，选 clr而不是cle/pure  还是报错相同的提示错误。

引用 6 楼 ggxxkkll 的回复:[quote=引用 4 楼 zcdabing 的回复:] dll加到工程目录了没  我现在只是编译 DLL，都编译通不过，  还没有开始弄控制应用程序[/quote]  你加lib不就是想使用DLL，DLL要加入你创建DLL的目录或者放在别的地方也行，需要加入环境变量

搜索 libpng 、libjpeg 等等。 如果你连的项目使用了那些第三方的库，都不知道。还是仔细弄清楚再说。 否则调试起来就是云山雾罩。

引用 7 楼 user-5 的回复:你的程序使用了第三方的库，把这些库添加进去。 看函数名字，好像是有jpeg 的一些库。 看上去不像是缺省的库。  jpeg的库可以去哪里下载啊？  谢谢！

引用 4 楼 zcdabing 的回复:dll加到工程目录了没  我现在只是编译 DLL，都编译通不过，  还没有开始弄控制应用程序

引用 4 楼 zcdabing 的回复:dll加到工程目录了没  什么 DLL，怎么加？

dll加到工程目录了没

引用 2 楼 SKATE11 的回复:extern "C"  谢谢你的回复。 请问：  fatal error LNK1313: 检测到 pure 模块；无法与 ijw/native 模块链接  如何解决？


Question: 数据结构栈Pop函数指针的问题

引用 8 楼 u013163178 的回复:typedef struct { SElemType *base; /* 栈底room */ SElemType *top; /* 栈顶room */ int stacksize; /* 栈的当前容量 */ }SqStack;请问你把数据保存在什么地方了。 你如果想从参数里面带回数据，那么参数就要是引用类型的 书上就是这样写的，而且我觉得没错，这是顺序栈，只需要两个指针就可以访问栈中的内容，关于数据的保存请看initstack函数，是在内存中分配了一块连续的空间，栈顶指针指向栈顶，栈底指针指向栈底，因为内存的分配是连续的只通过指针的加减就可以来访问

typedef struct { SElemType *base; /* 栈底room */ SElemType *top; /* 栈顶room */ int stacksize; /* 栈的当前容量 */ }SqStack;  这个就是节点啊？怎么和其他节点关联呢？没看懂这种栈

供参考：  Status GetTop(SqStack S, SElemType *e) { 	if(S.top == S.base) return ERROR; 	*e = *(S.top - 1);/*因为top指针指向栈顶元素的上一个位置，所以此处需要-1*/ 	return OK; }  Status Pop(SqStack *S, SElemType *e) { 	if(S->top == S->base) return ERROR; 	*e = *(S->top - 1); 	S->top--; 	return OK; }  int main(){ 	SqStack S; 	int i = 0, j = 0; 	char ch; 	char *m = &ch; 	char t[100], len; 	printf("please print some chars:"); 	InitStack(&S); 	scanf("%s", t); 	len = strlen(t); 	printf("%s", &t[0]); 	for(i; i<len; i++) 		Push(&S, t[i]);	 	Pop(&S, m); 	printf("%c\n", *m); 	return 0; }

引用 2 楼 oYinGui1 的回复:将指针作为形参传入函数时，传的其实是一个副本，你修改副本对原值没影响的(类似交换两值那种)。在C里你要修改指针，就传指针的指针。C++里就传指针的引用。 不行啊，我还是不会写Pop，不过我后来想了想，把指针改为用数组，结果就出来了。虽说指针和数组差不多，但还是感觉指针好难，得多看看书

引用 3 楼 liuhengxiao 的回复:这个就是节点啊？怎么和其他节点关联呢？没看懂这种栈 这个是顺序栈，地址是分配在一起的，通过栈顶指针的自动，也就是加减来访问栈中的值

引用 2 楼 oYinGui1 的回复:将指针作为形参传入函数时，传的其实是一个副本，你修改副本对原值没影响的(类似交换两值那种)。在C里你要修改指针，就传指针的指针。C++里就传指针的引用。好像有点明白了，我再去试试，谢谢了。

在线等回复，搞了好久还没搞出来。。。，我学过一点C++，不过大学老师教的那种，太基础了。。我指针是在C++里面学的，应该差不多吧


Question: warning C4305: "初始化": 从"double"到"const float"截断

问题已经解决了，第一个for循环嵌套的内层for循环的自增变量不应该是year++   应是month++

double占的字节数float多 由double到float的时候，丢失了部分内容，损失精度而已。  4.3 改为4.3f


Question: 请问下为什么指针PS的不是地址，而是字符串

额。。地址以字符串的形式显示给你看啊。显示的字符串不就是地址

引用 3 楼 FancyMouse 的回复:ostream<<char*有特殊重载（当成C风格字符串输出）。你想要输出char*实际的值就需要转成其他指针比如void*再输出。 ps输出vvvvvvvvv(9个v)，而*ps输出一个v怎么理解啊。ps不是应该是指向char型的指针吗？打印ps不就是打印ps所指向的地址吗？打印 *ps应该是打印ps所指向的地址的内容。为什么一个输出是9个V一个输出是一个V。

指的是地址，打印的时候转换成地址格式输出就可以了

引用 4 楼 liqiming100 的回复:[quote=引用 3 楼 FancyMouse 的回复:] ostream<<char*有特殊重载（当成C风格字符串输出）。你想要输出char*实际的值就需要转成其他指针比如void*再输出。 ps输出vvvvvvvvv(9个v)，而*ps输出一个v怎么理解啊。ps不是应该是指向char型的指针吗？打印ps不就是打印ps所指向的地址吗？打印 *ps应该是打印ps所指向的地址的内容。为什么一个输出是9个V一个输出是一个V。[/quote]  ps是字符串”vvvvvvvvv“的地址，同时也是首元素地址，*ps是也就是这个字符串的第一个字符，*ps也就等同于ps[0]  转换为数组你可能更容易明白一点，char *ps=”vvvvvv“，等同于 char ps[]=”vvvvvvv“


Question: TC编程动画设计

也许lz就差一个编程的

LZ会什么？

找到位移和时间的关系(计算公式) 假如每隔100ms显示一次,总共显示10000次 long t=0.0; for(int i=0;i<10000;i++) {      t+=0.1;      计算位置;      在结果位置画图      sleep(100);      清洗,比如可以用背景色画个块覆盖 }

1.知道当前的状态（位置，速度，加速度等） 2.由相关的物理公式（运动规律）推算下一个dt(delta t----三角形t)时的状态，画出来，停顿片刻擦去。。。。重复到某个特定状态（调整运动规律），。。。不断地重复

复习《初中物理》自由落体运动

你打算出多少钱

这么有意思的程序，怎么能直接伸手！？ 不自己折腾折腾没意思！


Question: 关于vc打开exe文件的问题

谢谢各位了，虽然还没有解决，但是我已经学到不少东西！

#include <stdio.h> #include <stdlib.h>  int main() {     double total_price = 0.0;     int type = 0;     int quantity = 0;     const double type1_price = 3.50;     const double type2_price = 5.50;     printf("输入版本(1 或 2):");     scanf("%d", &type);     printf("输入大小:");     scanf("%d", &quantity);     total_price = 	quantity * (type1_price + 		    (type - 1) * (type2_price - type1_price));     printf("The price for %d of type %d is $%.2f\n", quantity, type, 	   total_price);     getchar();     system("pause");     return 0; }

在运行里面输入 cmd，运行，再把你那个ｅｘｅ托到那个黑框里面，按回车

我也是用vc6.0的，但是如果把printf("pause")改成system("pause")会显示错误。

你用什么编译器的？我用VC++6.0编译没问题，但是用VS编译就闪退，用断点单步调试VS也没问题那，你那个加个头文件#include "windows.h" 你再把那个printf("pause")改成system("pause")

我知道拖到控制台啊！我就是想要不拖控制台也能用啊！毕竟拖去控制台还是有点麻烦啊

拖到控制台下运行

还是不行啊

return 0;放到最后

#include<stdio.h>//一个物品有两个版本，分别输入版本和大小得出价格 int main(void) { 	double total_price = 0.0; 	int type = 0; 	int quantity =0; 	const double type1_price = 3.50; 	const double type2_price = 5.50; 	printf("输入版本(1 或 2):"); 	scanf("%d",&type); 	printf("输入大小:"); 	scanf("%d",&quantity); 	total_price = quantity*(type1_price + (type - 1)*(type2_price - type1_price)); 	printf("The price for %d of type %d is $%.2f\n",quantity,type,total_price); 	return 0;     printf("pause"); 	getchar(); } 代码没问题

上代码

还是不行啊!

加在最后吗？那是一个计算的程序，最后的答案没有出来就退出了。我之前编写的程序也一样

system("pause");


Question: 谁帮忙找下opendir的源码实现

引用 1 楼 user-1 的回复:下载linux kernel看一下。里面没找到，，下载的3.1的

下载linux kernel看一下。


Question: 指针问题

还是我的 free问题造成的，free后造成没有指向，还有就是对multlines和count复制有个bug，要交换下，谢谢大家！

引用 7 楼 boxmanstan 的回复:[quote=引用 5 楼 u012514171 的回复:]    const char *line = words;还能这样写？  为毛不可以？[/quote]可以的，刚才没细看你的代码，才知道words是传的参数。sorry！

代码有错 变更下代码：   char** getwordsCount(const char *words, int *count){ 	if(words == NULL){ 		return NULL; 	} 	const char *line = words; 	*count = 0; 	char *temp = NULL;     char **multlines = NULL; 	while(1){ 		while(*line && isspace(*line))line++; 		if(temp == NULL){ 			temp = (char*)malloc(sizeof(char) * 100); 		} 		if(*line){ 			int done = 0; 			int tempcount = 0; 			while(!done){ 				switch(*line){ 				case ' ': 				case '\r': 				case '\t': 				case '\n': 				case '\v': 				case '\f': 				case '\0': 					done = 1; 					break; 				default: 					temp[tempcount] = *line; 					tempcount++; 					break; 				} 				if(*line){ 					line++; 				} 			} 			temp[tempcount] = '\0'; 			multlines = (char**)realloc(multlines, sizeof(char*) * ((*count) + 1)); 			(*count) = (*count) + 1; 			multlines[(*count)] = temp; 			free(temp); 			temp = NULL; 		}else{ 			break; 		} 	} 	return multlines; }

引用 5 楼 u012514171 的回复:   const char *line = words;还能这样写？  为毛不可以？

谢谢boxman我没仔细测试  line++写在哪里是会出现死循环：我修改了下，这里就不贴出来了

const char *line = words;还能这样写？

我觉得这么套死循环太危险，一个地方处理不好就完蛋。比如你这个，单独传个字母就死循环了

我觉得这里没有语法错误

引用 1 楼 user-3 的回复:字符串赋值不能用 = 赋值，要用strcpy，= 号只是将指针的值赋给了变量。  guys, oh,no

字符串赋值不能用 = 赋值，要用strcpy，= 号只是将指针的值赋给了变量。


Question: 如何查看位域成员的地址

引用 10 楼 zhao4zhong1 的回复:仅供参考#include <stdio.h> #pragma pack(push,1) union U {     unsigned char byte;     struct BF {         unsigned int b0:1;//a         unsigned int b1:1;//b         unsigned int b2:1;//c     } bf; } u; #pragma pack(pop) unsigned char bt; int a,b,c; int main() {     for (bt=0;bt<8;bt++) {         u.byte=(unsigned char)bt;         a=u.bf.b0;         b=u.bf.b1;         c=u.bf.b2;         printf("byte 0x%02x -- c:%d b:%d a:%d\n",bt,c,b,a);     }     for (c=0;c<2;c++)     for (b=0;b<2;b++)     for (a=0;a<2;a++) {         u.bf.b0=a;         u.bf.b1=b;         u.bf.b2=c;         bt=u.byte;         printf("c:%d b:%d a:%d -- byte 0x%02x\n",c,b,a,bt);     }     return 0; } //byte 0x00 -- c:0 b:0 a:0 //byte 0x01 -- c:0 b:0 a:1 //byte 0x02 -- c:0 b:1 a:0 //byte 0x03 -- c:0 b:1 a:1 //byte 0x04 -- c:1 b:0 a:0 //byte 0x05 -- c:1 b:0 a:1 //byte 0x06 -- c:1 b:1 a:0 //byte 0x07 -- c:1 b:1 a:1 //c:0 b:0 a:0 -- byte 0x00 //c:0 b:0 a:1 -- byte 0x01 //c:0 b:1 a:0 -- byte 0x02 //c:0 b:1 a:1 -- byte 0x03 //c:1 b:0 a:0 -- byte 0x04 //c:1 b:0 a:1 -- byte 0x05 //c:1 b:1 a:0 -- byte 0x06 //c:1 b:1 a:1 -- byte 0x07   #include <stdio.h> #include <stdlib.h> #include <string.h> int main() {     float f;     double d;     char bs[65];     char b[65];     char s[80];     unsigned char *p;     char e[12];     char *t;     int ex;      while (1) {         printf("Input a float point number:");fflush(stdout);         rewind(stdin);         fgets(s,80,stdin);         if (1==sscanf(s,"%f",&f) && 1==sscanf(s,"%lf",&d)) break;     }     printf("f=%g\n",f);     p=(unsigned char *)&f;     printf("hex=%02X %02X %02X %02X\n",p[3],p[2],p[1],p[0]);     ltoa(*(long *)&f,b,2);     sprintf(bs,"%032s",b);     printf("bin=%s\n",bs);     printf("bin=%.1s %.8s   %s\n",bs,bs+1,bs+9);     strncpy(e,bs+1,8);e[8]=0;     ex=strtol(e,&t,2);     printf("    %c %-4d-127 1.%s\n",(bs[0]=='0')?'+':'-',ex,bs+9);     ex-=127;     printf("    %c %-8d 1.%s\n",(bs[0]=='0')?'+':'-',ex,bs+9);      printf("\nd=%lg\n",d);     p=(unsigned char *)&d;     printf("hex=%02X %02X %02X %02X %02X %02X %02X %02X\n",p[7],p[6],p[5],p[4],p[3],p[2],p[1],p[0]);     _i64toa(*(__int64 *)&d,b,2);     sprintf(bs,"%064s",b);     printf("bin=%s\n",bs);     printf("bin=%.1s %.11s   %s\n",bs,bs+1,bs+12);     strncpy(e,bs+1,11);e[11]=0;     ex=strtol(e,&t,2);     printf("    %c %-6d-1023 1.%s\n",(bs[0]=='0')?'+':'-',ex,bs+12);     ex-=1023;     printf("    %c %-11d 1.%s\n",(bs[0]=='0')?'+':'-',ex,bs+12);      return 0; } //Input a float point number:0.125 //f=0.125 //hex=3E 00 00 00 //bin=00111110000000000000000000000000 //bin=0 01111100   00000000000000000000000 //    + 124 -127 1.00000000000000000000000 //    + -3       1.00000000000000000000000 // //d=0.125 //hex=3F C0 00 00 00 00 00 00 //bin=0011111111000000000000000000000000000000000000000000000000000000 //bin=0 01111111100   0000000000000000000000000000000000000000000000000000 //    + 1020  -1023 1.0000000000000000000000000000000000000000000000000000 //    + -3          1.0000000000000000000000000000000000000000000000000000 //  多谢 多谢 例子很好

引用 9 楼 yang382197207 的回复:[quote=引用 6 楼 richyhuang 的回复:] bit field是一种压缩的数据类型,其元素不一定以8为倍数的,所以只能看到整个结构的地址,而不能指定某一个元素的地址 可事实上有时候会想看一下，位域的排列，对齐，数据是都压缩存储，这个可以通过什么来查看？内存吗[/quote] 用watch试试吧,

#include <stdio.h> #include <stdlib.h> #include <string.h> #include <locale.h> int main() {     int i,v;     char bs[33];     char b[33];     char hs[9];     char h[9];     char s[4];     char *e;  // 十进制整数转二进制串；     i=1024;     ltoa(i,b,2);     sprintf(bs,"%032s",b);     printf("i=%d,bs=%s\n",i,bs); // 十进制整数转十六进制串；     i=1024;     ltoa(i,h,16);     sprintf(hs,"%08s",h);     printf("i=%d,hs=%s\n",i,hs); // 十六进制字符串转成十进制数     strcpy(hs,"00000400");     sscanf(hs,"%x",&i);     printf("hs=%s,i=%d\n",hs,i); // 二进制字符串转化为十六进制字符串；     strcpy(bs,"00000000000000000000010000000000");     i=strtol(bs,&e,2);     ltoa(i,h,16);     sprintf(hs,"%08s",h);     printf("bs=%s,hs=%s\n",bs,hs); // 二进制字符串转化为十进制数；     strcpy(bs,"00000000000000000000010000000000");     i=strtol(bs,&e,2);     printf("bs=%s,i=%d\n",bs,i); // 十六进制字符串转成二进制串     strcpy(hs,"00000400");     sscanf(hs,"%x",&i);     ltoa(i,b,2);     sprintf(bs,"%032s",b);     printf("hs=%s,bs=%s\n",hs,bs); // ASC\GBK字符串转十六进制串     strcpy(s,"a汉");     i=0;     while (1) {         if (0==s[i]) break;         sprintf(hs+i*2,"%02X",(unsigned char)s[i]);         i++;     }     setlocale(LC_ALL,"chs");     printf("s=%s,hs=%s\n",s,hs); // 十六进制字符串转成汉字（GBK）及字符(ASC)     strcpy(hs,"61BABA");     i=0;     while (1) {         if (1!=sscanf(hs+i*2,"%2x",&v)) break;         s[i]=(char)v;         i++;     }     s[i]=0;     printf("hs=%s,s=%s\n",hs,s);      return 0;  } //i=1024,bs=00000000000000000000010000000000 //i=1024,hs=00000400 //hs=00000400,i=1024 //bs=00000000000000000000010000000000,hs=00000400 //bs=00000000000000000000010000000000,i=1024 //hs=00000400,bs=00000000000000000000010000000000 //s=a汉,hs=61BABA //hs=61BABA,s=a汉

引用 6 楼 richyhuang 的回复:bit field是一种压缩的数据类型,其元素不一定以8为倍数的,所以只能看到整个结构的地址,而不能指定某一个元素的地址 可事实上有时候会想看一下，位域的排列，对齐，数据是都压缩存储，这个可以通过什么来查看？内存吗

引用 4 楼 lm_whales 的回复:位域无地址，但是可以看到位域变量占了哪些位； 方法是其他位为0，某位域变量全1 然后逐个字节，或者逐位输出。 这个方法不错，有用

位域不能取地址的&

把他当成char 数组解释每个位即可

引用 1 楼 user-5 的回复: struct data  {        unsigned int  num1;        unsigned int num2 ; 	   char ch1;        unsigned int  num3;        unsigned int num4;  };  data a; unsigned int *p_nNum1=&a.num1; printf("%d ",p_nNum1,);   你写的这个都不是bit field。bit field不能取地址

引用 1 楼 user-5 的回复: struct data  {        unsigned int  num1;        unsigned int num2 ; 	   char ch1;        unsigned int  num3;        unsigned int num4;  };  data a; unsigned int *p_nNum1=&a.num1; printf("%d ",p_nNum1,);    这个是偏移量 参考下  [code=c][/ #include "stdafx.h" #include<stdio.h>  struct data  {        unsigned int  num1;        unsigned int num2 ; 	   char ch1;        unsigned int  num3;        unsigned int num4;  };  int main(int argc, char* argv[]) { 	data a; 	unsigned int data::*p_nNum1=&data::num1; 	unsigned int data::*p_nNum2=&data::num2; 	unsigned int data::*p_nNum3=&data::num3; 	unsigned int data::*p_nNum4=&data::num4; 	char data::*p_cCh1=&data::ch1;   	printf("%d %d %d %d %d",p_nNum1,p_nNum2,p_nNum3,p_nNum4,p_cCh1);   	return 0; }code]


有缘人快帮我看看啊

为什么编译报错，运行没问题呢，逐行调试就提议以上的信息

我是用的是vs2010提示： 为“f:\dd\vctools\crt_bld\self_x86\crt\prebuild\eh\throw.cpp”查找源。Checksum: MD5 {71 72 36 66 b4 3b 91 95 84 76 e7 9d d9 88 65 52} 文件“f:\dd\vctools\crt_bld\self_x86\crt\prebuild\eh\throw.cpp”不存在。 正在脚本文档中查找“f:\dd\vctools\crt_bld\self_x86\crt\prebuild\eh\throw.cpp”... 正在项目中查找“f:\dd\vctools\crt_bld\self_x86\crt\prebuild\eh\throw.cpp”。 在项目中未找到该文件。 正在目录“d:\Program Files (x86)\Microsoft Visual Studio 10.0\VC\crt\src\”中查看... 正在目录“d:\Program Files (x86)\Microsoft Visual Studio 10.0\VC\atlmfc\src\mfc\”中查看... 正在目录“d:\Program Files (x86)\Microsoft Visual Studio 10.0\VC\atlmfc\src\atl\”中查看... 正在目录“d:\Program Files (x86)\Microsoft Visual Studio 10.0\VC\atlmfc\include\”中查看... 正在目录“d:\Program Files (x86)\Microsoft Visual Studio 10.0\VC\atlmfc\src\mfc”中查看... 正在目录“d:\Program Files (x86)\Microsoft Visual Studio 10.0\VC\atlmfc\src\mfcm”中查看... 正在目录“d:\Program Files (x86)\Microsoft Visual Studio 10.0\VC\atlmfc\src\atl”中查看... 正在目录“d:\Program Files (x86)\Microsoft Visual Studio 10.0\VC\crt\src”中查看... 正在目录“”中查看... 正在目录“d:\Program Files (x86)\Microsoft Visual Studio 10.0\VC\include”中查看... 正在目录“d:\Program Files (x86)\Microsoft Visual Studio 10.0\VC\atlmfc\include”中查看... 正在目录“C:\Program Files (x86)\Microsoft SDKs\Windows\v7.0A\include”中查看... 正在目录“C:\Program Files (x86)\Microsoft SDKs\Windows\v7.0A\\include”中查看... 正在目录“”中查看... 活动解决方案的调试源文件设置指明调试器不会要求用户查找文件: f:\dd\vctools\crt_bld\self_x86\crt\prebuild\eh\throw.cpp。 调试器未能找到源文件“f:\dd\vctools\crt_bld\self_x86\crt\prebuild\eh\throw.cpp”。

vc6.0 没问题

断点要打在exit（-1）之前，不然程序退出就看不到了。

为什么没有问愿意帮我解答啊


base = (void *)brk(0); 这句是否可以改为 base = (void *)sbrk(0); 再实现一个sbrk函数？