Question: mfc消息机制

引用 5 楼 user-3 的回复:简单的说，所有的代码都在某个线程里执行，如果你没开新线程，那么所有的代码实际上都是在一个线程（也叫主线程）里执行 包括你写的所有功能代码，包括不是你写的所有界面绘制代码 sleep(3000)的功能是“当前线程停止执行3秒钟”，这3秒钟内，这个线程什么都不能做，如果你的程序只有一个线程，那就是整个程序在3秒内停止运行  赵老师给出的方法是用循环的方式取代sleep，在循环的时间内处理消息列表的所有消息，也就是这个线程应该执行的所有功能，以此避免当你延时时，整个程序的所有功能都被延迟 这个方法只是权宜之计，根本的解决方法还是多线程   分析的挺好的

引用 1 楼 zhao4zhong1 的回复:将Sleep(3000);替换为 MSG msg; for (int i=0;i<30;i++) {         Sleep(100);         if (GetMessage(&msg,NULL,0,0)) {             TranslateMessage(&msg);             DispatchMessage(&msg);         } }   赵老师这是用于操作键盘、鼠标消息的吧！ 我这里相当于给某个  sockfd  注册个消息。有个回调会去负责有可读信息时recv。  我做了个实验。一个按钮对于的函数里创建socket，必须要这个函数返回后回调函数才会执行。 不管在函数内等待多久回调函数都不会执行，就算有信号过来。

有个edit控件。ID是IDC_MESSAGE 对于的变量名是 m_message;  怎么让它分层显示。。好像界面等到执行完了显示一次。。   CString str1, str2, str3, str3; m_message.SetWindowTextA("\r\nnihao."); Sleep(1000); m_message.GetWindowTextA(str1); str2.Format("%s", wo hen hao); str2 = str1 + str2; m_message.SetWindowTextA(str2); Sleep(1000); m_message.GetWindowTextA(str3); str4.Format("%s",na jiu hao); str4 = str3 + str4; m_message.SetWindowTextA(str4 );

引用 3 楼 u012889234 的回复:          CString str1, str2, str3, str3;       m_message.SetWindowTextA("\r\nnihao.");       Sleep(1000);        m_message.GetWindowTextA(str1);       str2.Format("\r\n%s"," wo hen hao");       str2 = str1 + str2;       m_message.SetWindowTextA(str2);       Sleep(1000);       m_message.GetWindowTextA(str3);       str4.Format("\r\n%s","na jiu hao");       str4 = str3 + str4;       m_message.SetWindowTextA(str4    就是先显示:        nihao 停顿一秒，再显示：     nihao    wohenhao 停顿一秒，再显示：    nihao    wohenhao    najiuhao  现在就只能看到最后的结果，中间的没有。。用Updatedate(FALSE)没有效果！！！ InvalidateRect The InvalidateRect function adds a rectangle to the specified window's update region. The update region represents the portion of the window's client area that must be redrawn.   BOOL InvalidateRect(   HWND hWnd,  // handle of window with changed update region   CONST RECT *lpRect,               // address of rectangle coordinates   BOOL bErase // erase-background flag );   Parameters hWnd  Handle to the window whose update region has changed. If this parameter is NULL, the system invalidates and redraws all windows, and sends theWM_ERASEBKGND and WM_NCPAINT messages to the window procedure before the function returns.  lpRect  Pointer to a RECT structure that contains the client coordinates of the rectangle to be added to the update region. If this parameter is NULL, the entire client area is added to the update region.  bErase  Specifies whether the background within the update region is to be erased when the update region is processed. If this parameter is TRUE, the background is erased when the BeginPaint function is called. If this parameter is FALSE, the background remains unchanged.  Return Values If the function succeeds, the return value is nonzero.  If the function fails, the return value is zero.   Windows NT: To get extended error information, callGetLastError.  Remarks The invalidated areas accumulate in the update region until the region is processed when the next WM_PAINT message occurs or until the region is validated by using the ValidateRect or ValidateRgn function.   The system sends a WM_PAINT message to a window whenever its update region is not empty and there are no other messages in the application queue for that window.   If the bErase parameter is TRUE for any part of the update region, the background is erased in the entire region, not just in the given part.   Windows CE: The hWnd parameter cannot be NULL.  QuickInfo   Windows NT: Requires version 3.1 or later.   Windows: Requires Windows 95 or later.   Windows CE: Requires version 1.0 or later.   Header: Declared in winuser.h.   Import Library: Use user32.lib.  See Also Painting and Drawing Overview, Painting and Drawing Functions, BeginPaint, InvalidateRgn, RECT, ValidateRect, ValidateRgn,WM_ERASEBKGND, WM_NCPAINT, WM_PAINT

引用 7 楼 zhao4zhong1 的回复:个人意见：不要轻易打开“多线程”这个‘潘多拉盒子’，尤其是使用mfc时。  否则必须： 《Windows核心编程》 Synchronization Functions The following functions are used in synchronization.   CancelWaitableTimer   CreateEvent   CreateMutex   CreateSemaphore   CreateWaitableTimer   DeleteCriticalSection   EnterCriticalSection   GetOverlappedResult   InitializeCriticalSection   InitializeCriticalSectionAndSpinCount   InterlockedCompareExchange   InterlockedDecrement   InterlockedExchange   InterlockedExchangeAdd   InterlockedIncrement   LeaveCriticalSection   MsgWaitForMultipleObjects   MsgWaitForMultipleObjectsEx   OpenEvent   OpenMutex   OpenSemaphore   OpenWaitableTimer   PulseEvent   QueueUserAPC   ReleaseMutex   ReleaseSemaphore   ResetEvent   SetCriticalSectionSpinCount   SetEvent   SetWaitableTimer   SignalObjectAndWait   TimerAPCProc   TryEnterCriticalSection   WaitForMultipleObjects   WaitForMultipleObjectsEx   WaitForSingleObject   WaitForSingleObjectEx  这太复杂了，我现在也只是临时需要才先学的，，，， 刚说的哪个方法我试了。没有问题。。  我的那个edit显式的怎么解决啊？？


Question: 如何跳出for循环

谢谢大家的解答，我前几天已经改出来了，这样直接就跳出当前循环了，我看到楼上同学已经解答了  for(int i){      for(int j){        }      if(){           for(){                 if(){                       j--;                      break;                 }           }        }

你在内层循环需要break的地方设置一下外层循环需要到达的条件不就完了 for(int i=0;i<nn;i++)     {     for(int j=0;j<p->gcNc[0].cellNc[i].NombreFrequences;j++)         {             int freq = rand() % m +1;             //exist || non satisfait Cii contrainte(CSC).  exemple rand() 7,encore rand() 7             if(a[freq] == 1)             {                 j--;                 continue;                                       }               //non exist && satisfait contrainte. exemple: rand() 7, apres rand() 8             if(a[freq] != 1)             {                 for(int k=0;k<p->gcNc[0].cellNc[i].NombreFrequences;k++)                 {                     if((p->gcNc[0].cellNc[i].frequences[k]-freq >= Cii || p->gcNc[0].cellNc[i].frequences[k]-freq <= -Cii ))                     {                         a[freq] = 1;                         p->gcNc[0].cellNc[i].frequences[j] = freq;                                    printf("%d ",p->gcNc[0].cellNc[i].frequences[j]);                       }else{                         printf("continue");                         i = nn;//你这里设置一下外循环到达条件不就完了                         break;                     }                 }             }                                         }

我是来学习的，谢谢分享！

这种情况下使用 goto 不用有什么负担，完全可以接受的。 当然，要想更好一点的话就把两个 for 循环放到一个函数里面，然后就可以使用 return 语句退出多层的循环了。  如果把 for 提出来成为函数发现参数太多，而且有很多是要返回出去的话，就该考虑把这些东西封装成一个类用对象来操作了。 C 语言虽然没有 C++ 的类，但是也可以借鉴其思想，使用结构体加配套函数的方法来.

goto语句容易陷入死循环，因此要慎用，可以用break来跳出当前循环

好多大神啊。。可以通过设置标签符来进行跳出语句的判断。。

出于便于理解的目的，你只需要记住在 C/C++中的 "{"和 "}" 本身也是特殊的执行语句。另外goto语句从严格来说也并不是“无条件”跳转，同样并不简单等同于一条汇编的jmp语句，比如除了jmp外它同样会依次执行被跳出块({})的“}”语句。 如果你理解了这些，那么你例子中的问题就很明显了， 最外层循环块的"}"并没有执行--即for(a;b;c)中的c部分被忽略了。所以要更正也很简单， 只要将label放到最外面那个“}”前面就可以了。

引用 21 楼 DuanKong86 的回复:6,7层判断什么的, 不要那么做, 太崩溃了. 可用用设计来避免, 避免不了的, 可以用 do{ if(a) break; if(b) break; }while(0); 这样来替换也可以用switch

引用 2 楼 galiniur0u 的回复:表示用goto的都太nb了，目前不敢用。提供个其它方法。可以设一个标志位，跳出一层循环后立马判断标志位是否需要跳出，需要跳出break；  int judge = 0; for() { for() { if(...) { judge = 1 continue; } } if(1 == judge) { break; } } 感觉还不如直接用goto快

for(int i=0;i<nn;i++)     { loop:    for(int j=0;j<p->gcNc[0].cellNc[i].NombreFrequences;j++)         {                              for(int k=0;k<p->gcNc[0].cellNc[i].NombreFrequences;k++)                 {                                             goto loop;  ///////////////////////////////////?????????????????????????????????                         printf("continue");                     }                 }             }                                         } 把结构突出出来，无关跳转的东西去掉了看 i,j,k三层循环，想从k循环跳出，跳到j循环前，此时i值不变，j循环从头开始。。。。这一定是个死循环 所以还要回到算法设计步骤去讨论 你是想 1.从k循环跳出，i不变，j++开始，继续执行？ 还是 2.从k循环跳出，i++，,j从头开始，继续执行？ 建议还是用"标志变量+continue"，continue在它所在的循环中会做一次i++,j++或k++操作 for(int i=0;i<nn;i++)     {      for(int j=0;j<p->gcNc[0].cellNc[i].NombreFrequences;j++)         {             int freq = rand() % m +1;             //exist || non satisfait Cii contrainte(CSC).  exemple rand() 7,encore rand() 7             if(a[freq] == 1)             {                 j--;                 continue;                                       }               //non exist && satisfait contrainte. exemple: rand() 7, apres rand() 8             if(a[freq] != 1)             {                 for(int k=0;k<p->gcNc[0].cellNc[i].NombreFrequences;k++)                 {   leapflag=0;  //跳出标志为假                     if((p->gcNc[0].cellNc[i].frequences[k]-freq >= Cii || p->gcNc[0].cellNc[i].frequences[k]-freq <= -Cii ))                     {......                     }else{                         leapflag=1; ////跳出标志为真                         goto next;  ///////////////////////////////////?????????????????????????????????                         printf("continue");                     }                  next: if(leapflag==1)                              continue; //j++开始----情况1                 }             }                             next: if(leapflag==1)                      continue; //i++开始----情况2            } goto可用，最好向外向后跳，不要向前跳

引用 12 楼 zhao4zhong1 的回复:[quote=引用 11 楼 my_live_123 的回复:] 你的格式缩进都进入6，7层的状态！重做吧，重新设计算法！缩进最好不要超过4层，否则，后果自负！ 试举一反例： #include <stdio.h> #include <conio.h> #include <windows.h> #include <wincon.h> FILE *f; char c; long offset; char patch[3]="\x1b\x6d";//\x00 default void main(int argc,char **argv)//".vs\0\x31\0\0\x1f\x00\x08"->".vs\0\x31\0\0\x1b\x6d\x00" {     if (argc!=2) {         printf("VxPatch filename.vx");         getch();GenerateConsoleCtrlEvent(CTRL_BREAK_EVENT,0);         return;     }     if (NULL==(f=fopen(argv[1],"r+b"))) {         printf("----------Can not find %s!",argv[1]);         getch();GenerateConsoleCtrlEvent(CTRL_BREAK_EVENT,0);         return;     }     while (1) {         c=fgetc(f);         if (feof(f)) break;//         if (c=='.') {             c=fgetc(f);             if (feof(f)) break;//             if (c=='v') {                 c=fgetc(f);                 if (feof(f)) break;//                 if (c=='s') {                     c=fgetc(f);                     if (feof(f)) break;//                     if (c=='\0') {                         c=fgetc(f);                         if (feof(f)) break;//                         if (c=='\x31') {                             c=fgetc(f);                             if (feof(f)) break;//                             if (c=='\0') {                                 c=fgetc(f);                                 if (feof(f)) break;//                                 if (c=='\0') {                                     c=fgetc(f);                                     if (feof(f)) break;//                                     if (c=='\x1f') {                                         c=fgetc(f);                                         if (feof(f)) break;//                                         if (c=='\x00') {                                             c=fgetc(f);                                             if (feof(f)) break;//                                             if (c=='\x08') {                                                 offset=ftell(f);                                                 offset=offset-3;                                                 fseek(f,offset,SEEK_SET);                                                 if (3!=fwrite(patch,1,3,f)) {                                                     fclose(f);                                                     printf("----------%s VxPached fwrite error!",argv[1]);                                                     getch();GenerateConsoleCtrlEvent(CTRL_BREAK_EVENT,0);                                                 } else {                                                     fclose(f);                                                     printf("OK.");                                                 }                                                 return;                                             } else break;//                                         } else break;//                                     } else if (c=='\x1b') {                                         fclose(f);                                         printf("%s is VxPatched. Please type vlc.err!",argv[1]);                                         getch();GenerateConsoleCtrlEvent(CTRL_BREAK_EVENT,0);                                         return;                                     } else break;//                                 }                             }                         }                     }                 }             }         }     }     fclose(f);     printf("----------%s is not a unVxPached .vx file!",argv[1]);     getch();GenerateConsoleCtrlEvent(CTRL_BREAK_EVENT,0); }  请牢记：源代码本身的书写是否结构化或面向对象或符合设计模式或敏捷…并不重要，重要的是你是否使用结构化或面向对象或符合设计模式或敏捷…的方法命名标识符、阅读、修改、检查、测试源代码。 [/quote] 恩，书写格式一定程度上反映出设计的优劣，当然不是绝对化。有些算法的深层次嵌套“很难”避免。 你的这个代码，条件判断如此之多，汇编出来的跳转指令也将会很多，它并不是高效的实现，也不是只能如此实现！这代码让不是自己写的人，维护起来似乎不那么简单！

引用 15 楼 henry3695 的回复: 加个分号 loop:;  [size=48px] NB[/size]

for (int i1 = 0; i1 < 10; i1++) // for1 	{ 		bool break1 = false; 		for (int i2 = 0; i2 < 10; i2++) // for2 		{ 			bool break2 = false; 			for (int i3 = 0; i3 < 10; i3++) // for3 			{ 				bool break3 = false; 				for (int i4 = 0; i4 < 10; i4++) // for4 				{ 					bool break4 = false; 					for (int i5 = 0; i5 < 10; i5++) // for5 					{ 						break4 = true; 						break; // break for5 					} 					if (break4) 					{ 						break3 = true; 						break; // break for4 					} 				} 				if (break3) 				{ 					break2 = true; 					break; // break for3 				} 			} 			if (break2) 			{ 				break1 = true; 				break; // break for2 			} 		} 		if (break1) 		{ 			break; // break for1 		} 	}

goto慎用，此处可用break

引用 19 楼 my3439955 的回复:我能想到的跳出多层循环的方法：  1、return法，直接返回，多少层循环也挡不住  2、goto法，直接跳到程序末尾  3、try-catch法，在需要跳出的地方throw指定异常，在多层循环的外部捕获，则跳出了循环  4、__try-__finlly法，用结构化异常处理包裹住多层循环，则内部可以用__leave关键字体面的跳出循环  其中第一种法不靠谱，第二种法涉及goto不规范，第三种法增加的异常处理的成本，第四种法仅限Windows平台。  不考虑平台限制的话，第四种法是最好的。我实际使用过。

引用 8 楼 fengheooo 的回复:[quote=引用 5 楼 zhao4zhong1 的回复:] for (int i=0;i<nn;i++) { LOOP2:     for (int j=0;j<p->gcNc[0].cellNc[i].NombreFrequences;j++) {         int freq = rand() % m +1;          //exist || non satisfait Cii contrainte(CSC).  exemple rand() 7,encore rand() 7         if (a[freq] == 1) {             j--;             continue;         }          //non exist && satisfait contrainte. exemple: rand() 7, apres rand() 8         if (a[freq] != 1) {             for (int k=0;k<p->gcNc[0].cellNc[i].NombreFrequences;k++) {                 int v=p->gcNc[0].cellNc[i].frequences[k]-freq;                 if ( v <= -Cii || Cii <= v) {                     a[freq] = 1;                     p->gcNc[0].cellNc[i].frequences[j] = freq;                     printf("%d ",p->gcNc[0].cellNc[i].frequences[j]);                 } else {                     i++;//需要加这句才能开始i的下次循环                     goto LOOP2;                 }             }         }     } }  for (A;B;C) D; //等价于 {  A;  while (1) {   if (!(B)) break;   D;   C;  } }  如果我还想执行完第二个for循环呢，刚这样试了下还有问题  for(int i){      Loop:      for(int j){          }      if(){           for(){                 if(){                       j--;                      goto Loop;                 }           }       }  [/quote]  Loop写错了，应该在外面

引用 5 楼 zhao4zhong1 的回复:for (int i=0;i<nn;i++) { LOOP2:     for (int j=0;j<p->gcNc[0].cellNc[i].NombreFrequences;j++) {         int freq = rand() % m +1;          //exist || non satisfait Cii contrainte(CSC).  exemple rand() 7,encore rand() 7         if (a[freq] == 1) {             j--;             continue;         }          //non exist && satisfait contrainte. exemple: rand() 7, apres rand() 8         if (a[freq] != 1) {             for (int k=0;k<p->gcNc[0].cellNc[i].NombreFrequences;k++) {                 int v=p->gcNc[0].cellNc[i].frequences[k]-freq;                 if ( v <= -Cii || Cii <= v) {                     a[freq] = 1;                     p->gcNc[0].cellNc[i].frequences[j] = freq;                     printf("%d ",p->gcNc[0].cellNc[i].frequences[j]);                 } else {                     i++;//需要加这句才能开始i的下次循环                     goto LOOP2;                 }             }         }     } }  for (A;B;C) D; //等价于 {  A;  while (1) {   if (!(B)) break;   D;   C;  } }  如果我还想执行完第二个for循环呢，刚这样试了下还有问题  for(int i){      for(int j){      Loop:       }      if(){           for(){                 if(){                       j--;                      goto Loop;                 }           }       }

你这代码写的。 你换一下loop: 位置看看。 放到第一层循环右大括号结尾处，一个continu，就继续执行第一层循环了


Question: 页式存储管理模拟器

《30天自制操作系统》

楼主是学生吗，你这个问题挺复杂的

引用 2 楼 u012150227 的回复:引用 1 楼 zhao4zhong1 的回复:《30天自制操作系统》什么意思？看这本书？来不及了 不知道这本书有没有随书光盘啥的。


Question: 学windows编程从汇编开始比较好吗?

如果你的学习方式是“学完一本书”“再学另一本”，那么你也太不会学习了。  如果你真的爱学习，感兴趣，会找各种书来看。多看书是没有坏处的，知识是网状的，不是线性的。  如果你要学Windows编程，没有必要特别学习汇编，因为Windows本身是C语言为主开发的，所以C语言是Windows和Windows API的第一语言。但是罗的书的确可以让你扩展视野，比如说提到的修改程序入口点，以及线程注入这样的高级话题。

用最适合的语言比较好, win32 api  就是 c/c++ 了, c++ 也只能用简单的封装库.

个人觉得先看<WINDOWS下32位汇编语言程序设计>要好点。。


Question: error LNK2019: 无法解析的外部符号， fatal error LNK1120: 1 个无法解析的外部命令

Traits是类吗？怎么定义的？


Question: 如何用c语言写一个程序 用文件名替换#include 命令

仅供参考//codegen.c // 输入一组字符串，比如 // aa ss ddd dd 33 dd // 然后自动生成一个函数 int A(const char*); // 实现A("aa")返回0  A("ss")返回1 依次类推 #include <stdio.h> int main(int argc,char **argv) {     int i;     if (argc<2) {         printf("%s p1 [p2 ...] [>result.c]\nGenerate code int A(const char *a); 0==A(\"p1\") 1==A(\"p2\") ...",argv[0]);         return 1;     }     //printf("#include <string.h>\n");     printf("int A(const char *a) {\n");     for (i=0;i<argc-1;i++) {         printf("    if (0==strcmp(a,\"%s\")) return %d;\n",argv[i+1],i);     }     printf("    return -1;\n");     printf("}\n");     return 0; } //C:\test\Debug>codegen.exe //codegen.exe p1 [p2 ...] [>result.c] //Generate code int A(const char *a); 0==A("p1") 1==A("p2") ... //C:\test\Debug>codegen.exe aa ss ddd dd 33 dd //int A(const char *a) { //    if (0==strcmp(a,"aa")) return 0; //    if (0==strcmp(a,"ss")) return 1; //    if (0==strcmp(a,"ddd")) return 2; //    if (0==strcmp(a,"dd")) return 3; //    if (0==strcmp(a,"33")) return 4; //    if (0==strcmp(a,"dd")) return 5; //    return -1; //} // //c:\test\Debug>codegen.exe aa ss ddd dd 33 dd >result.c // //c:\test\Debug>type result.c //int A(const char *a) { //    if (0==strcmp(a,"aa")) return 0; //    if (0==strcmp(a,"ss")) return 1; //    if (0==strcmp(a,"ddd")) return 2; //    if (0==strcmp(a,"dd")) return 3; //    if (0==strcmp(a,"33")) return 4; //    if (0==strcmp(a,"dd")) return 5; //    return -1; //} //

引用 楼主 u013476411 的回复:如何用c语言写一个程序 用文件名替换#include 命令 我只想到了宏。等待别的答案。

预编译？


Question: 页式存储管理模拟器

《30天自制操作系统》


Question: 结构体成员是结构体数组指针，如何初始化，如何赋值？

由于acc_data里面声明的是指向struct_B的指针，所以在赋值之前需要先分配内存才行。 另，struct可以使用typedef声明，代码会更简洁一些。 typedef struct  struct_A{ 	/**/ }; typedef struct  struct_B{ 	char name[11+1];   };  typedef struct acc_data { 	struct_A A_name;  	struct_B *B_name[1024];  };    for (int i = 0; i < 1024; i++) 	{ 		ss.B_name[i] = new struct_B; 		if(NULL != ss.B_name[i]) 			strcpy_s(ss.B_name[i]->name, "***"); 	}

for (int i = 0; i < 1024; i++) {     B_name[i] = new struct  struct_B;     if(NULL != B_name[i])         B_name[i]->name = XXX; }

全部初始化为NULL就可以

解决方案基本和楼上的一致！结贴！


Question: 新手，刚刚接触C，做了个指针冒泡排序，大神们帮我找找bug！谢谢了

多谢分享，我正想找一些这样的实例呢

参考 C:\Microsoft SDK\src\crt\qsort.c C:\Program Files\Microsoft Platform SDK for Windows Server 2003 R2\src\crt\qsort.c C:\Program Files\Microsoft Visual Studio\VC98\CRT\SRC\QSORT.C C:\Program Files\Microsoft Visual Studio 8\VC\crt\src\qsort.c C:\Program Files\Microsoft Visual Studio 9.0\VC\crt\src\qsort.c C:\Program Files\Microsoft Visual Studio 10.0\VC\crt\src\qsort.c

这是个快排算法，一般我们把sort分为两部分，代码如下： int once(int *x,int n,int m)//一次快排 { 	int a=*x; 	int i=n,j=m; 	while(i<j) 	{	while((a>=*(x+j))&&i<j) 			j--; 		if(i<j) 		{	*(x+i)=*(x+j); 			i++; 		} 		while((*(x+i)>a)&&i<j) 			i++; 		if(i<j) 		{ 			*(x+j)=*(x+i); 			j--; 		} 	} 	*(x+i)=a; 	return i; } void sort(int *x,int n,int m) { 	int i; 	if(n<m) 		{   i=once(x,n,m); 	             sort(x,n,i-1); 	           sort(x,i+1,m);                  } }

1、递归，没有退出条件      可以加上 if( n >= m ) return; 2、while(n<m) 你已经知道了 3、while((a>=*(x+j))&&i<j)     while((*(x+i)<a)&&i<j)       这是从大到小排序，还是从小到大排序

实在看不懂这个是冒泡排序。。。。。。。。

这是第几次看到有人把简单的代码写的这么复杂了。。。

引用 6 楼 u013470052 的回复:哪里冒泡了啊？冒泡都是两层循环的，你的只有一层，所以说肯定不是冒泡。哈哈 是快速排序

引用 5 楼 endeavourken 的回复:实在看不懂这个是冒泡排序。。。。。。。。哈哈 说错了 是快速排序！ 标题手误

引用 4 楼 u010882724 的回复:大神啊，真心没看懂sort函数什么意思，不过外部的while应该会一直循环吧（n<m）、、、恩 是这个地方写错了 ！ 应该是i<j

仅供参考//假设带表头结点的单向链表头指针为head，试编写一个算法将值为5的结点插入到连接表的第k个结点前，删除第k个节点，并对该链表进行排序。 #include <stdio.h> #include <stdlib.h> #include <malloc.h> #include <time.h> struct NODE {     int          data;     struct NODE *next; } H,*head,*p,*q,*s1,*s2,*s3,*s4,*s; int i,j,k,n,t,m; int main() {     srand(time(NULL));      //填写头节点数据     H.data=-1;     H.next=NULL;     head=&H;      //创建10个节点的单链表     p=head;     for (i=0;i<10;i++) {         q=(struct NODE *)malloc(sizeof(struct NODE));         if (NULL==q) return 1;         q->data=rand()%100;//填写0..99的随机值         q->next=NULL;         p->next=q;         p=q;     }      //输出整个单链表     s=head->next;     while (1) {         if (NULL==s) {             printf("\n");             break;         }         printf("%02d->",s->data);         s=s->next;     }      //将值为5的结点插入到单链表的第k个结点前     k=3;     n=0;     p=head;     while (1) {         if (NULL==p) {             break;         }         n++;         if (k==n) {             q=(struct NODE *)malloc(sizeof(struct NODE));             if (NULL==q) return 1;             q->data=5;             q->next=p->next;             p->next=q;             break;         }         p=p->next;     }      //输出整个单链表     s=head->next;     while (1) {         if (NULL==s) {             printf("\n");             break;         }         printf("%02d->",s->data);         s=s->next;     }      //删除第k个节点     k=5;     n=0;     p=head;     while (1) {         if (NULL==p) {             break;         }         n++;         if (k==n) {             q=p->next;             if (q) {                 p->next=q->next;                 free(q);             }             break;         }         p=p->next;     }      //输出整个单链表     s=head->next;     while (1) {         if (NULL==s) {             printf("\n");             break;         }         printf("%02d->",s->data);         s=s->next;     }      //从小到大排序     for (p=head;p!=NULL && p->next!=NULL;p=p->next) {         for (q=p->next;q!=NULL && q->next!=NULL;q=q->next) {             if (p->next->data > q->next->data) {                  //交换data //              printf("swap %02d %02d\n",p->next->data,q->next->data); //              t=p->next->data;p->next->data=q->next->data;q->next->data=t;                  //或者                  //交换next //              printf("swap %02d %02d\n",p->next->data,q->next->data);                 s1=p->next;                 s2=p->next->next;                 s3=q->next;                 s4=q->next->next;                  if (s2!=s3) {                      p->next=s3;                     s3->next=s2;                      q->next=s1;                     s1->next=s4;                 } else {                      p->next=s3;                     s3->next=s1;                            q=s3;                     s1->next=s4;                 }                  //输出整个单链表 //              s=head->next; //              while (1) { //                  if (NULL==s) { //                      printf("\n"); //                      break; //                  } //                  printf("%02d->",s->data); //                  s=s->next; //              } //              getchar();             }         }     }      //输出整个单链表     s=head->next;     while (1) {         if (NULL==s) {             printf("\n");             break;         }         printf("%02d->",s->data);         s=s->next;     }      //将单链表中前 m 个结点和后 n 个结点进行互换,m+n为链表总长10     m=4;     n=6;     k=0;     p=head;     while (1) {         if (NULL==p) {             break;         }         k++;         if (m+1==k) {             q=p;         }         s=p;         p=p->next;     }     s1=head->next;     head->next=q->next;     s->next=s1;     q->next=NULL;      //输出整个单链表     s=head->next;     while (1) {         if (NULL==s) {             printf("\n");             break;         }         printf("%02d->",s->data);         s=s->next;     }      //释放所有节点     p=head->next;     while (1) {         if (NULL==p) {             break;         }         q=p->next;         free(p);         p=q;     }      return 0; } //18->94->58->17->27->20->43->57->75->78-> //18->94->05->58->17->27->20->43->57->75->78-> //18->94->05->58->27->20->43->57->75->78-> //05->18->20->27->43->57->58->75->78->94-> //43->57->58->75->78->94->05->18->20->27-> //

都涉及到指针了 还简单么

哪里冒泡了啊？冒泡都是两层循环的，你的只有一层，所以说肯定不是冒泡。

引用 2 楼 user-9 的回复:我是大神 ，爱偶你呀最强王者，你说我算不算大神？先解决下问题我在评价评价

我是大神 ，爱偶你呀最强王者，你说我算不算大神？

没有大神吗


Question: C语言printf问题

// UTF-8 编码字符理论上可以最多到 6个字节长，但目前全世界的所 // 有文字和符号种类加起来也只要编到 4个字节长就够了。 // 　　UTF-8 是以 8位（即 1个字节）为单元对原始码进行编码（注意一 // 点：这里所讲的原始码都是指Unicode码），并规定：多字节码（2个字 // 节以上才称为多字节）以转换后第1个字节起头的连续“1”的数目（这 // 些连续“1”称为标记位），表示转换成几个字节：“110”连续两个 // “1”，表示转换结果为2个字节，“1110”表示3个字节，而“11110” // 则表示4个字节……跟随在标记位之后的“0”，其作用是分隔标记位和 // 字符码位。第2～第4个字节的起头两个位固定设置为“10”，也作为标 // 记，剩下的6个位才做为字符码位使用。 // 　　这样，2字节UTF-8码剩下11个字符码位，可用以转换0080～07FF的 // 原始字符码，3字节剩下16个字符码位，可用以转换0800～FFFF的原始字 // 符码，由此类推。编码方式的模板如下： // // 原始码（16进制）　UTF－8编码（二进制） // -------------------------------------------- // 0000 - 007F       0xxxxxxx // 0080 - 07FF       110xxxxx 10xxxxxx // 0800 - FFFF       1110xxxx 10xxxxxx 10xxxxxx // …… // -------------------------------------------- // // 　　模板中的“x”表示字符码。 // 　　Ascii码＜007F，编为1个 // 字节的UTF－8码。汉字的 Unicode编码范围为0800－FFFF，所以被编为 // 3个字节的UTF－8码。 // 　　例如“汉”字的Unicode编码是6C49，6C49在0800-FFFF之间，所以 // 要用3个字节的模板：1110wwww 10xxxxyy 10yyzzzz。  //    6    C    4    9 // 0110 1100 0100 1001 // wwww xxxx yyyy zzzz //     wwww   xxxxyy   yyzzzz // 1110wwww 10xxxxyy 10yyzzzz。 // 11100110 10110001 10001001 //    E   6    B   1    8   9 //“汉”字的UTF-8编码是E6 B1 89

引用 7 楼 zhao4zhong1 的回复:对电脑而言没有乱码，只有二进制字节；对人脑才有乱码。啊 GBK:0xB0 0xA1,Unicode-16 LE:0x4A 0x55,Unicode-16 BE:0x55 0x4A,UTF-8:0xE5 0x95 0x8A领教了

printf("%s") 是不管编码的，只是原样按字符串输出

到此已经理解，我觉得应该是这样的：我用gedit编辑的该程序，该软件默认UTF-8编码，所以以上的几个汉字也是UTF-8编码存入可执行文件。utf8是很聪明的一种表示方式。      1、对于单字节符号，字节第一位为0，后面7位表示字节编码。      2、对于n字节符号，第一字节的前n位都设为1，第n＋1位为0，其余位为编码位置。 所以当putchar读到汉字时，知道汉字以3个字节表示，并能正确读取对应汉字正确的编码，终端就可以以正确的方式解码汉字

引用 4 楼 BensonLaur 的回复:我是男生啊吧ab~#$  sizeof(a) = 30    strlen(a) = 17 我用codeblocks 运行结果是汉字占两个字节耶+1

putchar 也是没有问题的。

多字节编码方案


Question: 作为一个c菜鸟，我想说赵老师的回复

赵四老师，肇事的老师

曾经出现的真假赵老师的那两帖子不知道还在否。

引用 22 楼 wangyaninglm 的回复:赵老湿！！！！！！！！！！！！！！  想不到这里有冲田。。。

提醒：再牛×的老师也无法代替学生自己领悟和上厕所！

一般赵4哥（4哥或者四阿哥...，随便了，因为我办公室有个大神级别的赵老师了，所以只能换个称谓了）只是给你指个方向， 怎么走，能不能走到还得靠自己，有时候一个方向就足够了

引用 60 楼 u012006886 的回复:[quote=引用 52 楼 zhao4zhong1 的回复:] [quote=引用 49 楼 garbageam 的回复:] 我来告诉你,赵4能力很强,但他只是个精神领袖.换句话说,也只能在大方向上指点你,具体问题他不正面回答的 正面回答也行。男的email单聊并付费。女的开房单聊我付费！ [/quote]赵老师你这么收费，你家管钱的造吗[/quote]

引用 8 楼 whoho 的回复:说他热心我也认同，不过我相当不认同他的方式 即便是真知灼见，重复贴百遍也就是不论病症乱贴狗皮膏药了

慢慢深入，不要急于求成，重要的是领悟方法。常常你想要的知识就在不远处，赵老师只是督促你自己去找。

感觉赵老师非常强大，好像什么板块的问题都能回答，简直无法直视，而且很有时间回答问题，而且有了新问题能够在几分钟内看到，应该是csdn的工作人员，很多的工作人员用一个帐号，你怎么看

引用 52 楼 zhao4zhong1 的回复:[quote=引用 49 楼 garbageam 的回复:] 我来告诉你,赵4能力很强,但他只是个精神领袖.换句话说,也只能在大方向上指点你,具体问题他不正面回答的 正面回答也行。男的email单聊并付费。女的开房单聊我付费！ [/quote]赵老师你这么收费，你家管钱的造吗

新人居然啥都看不懂  连你们说的话都不懂   感觉一个一个都是油条子

引用 55 楼 kang2618 的回复:看着很蛋疼,大一刚来的时候是那几句话,这马上大三了,说来说去还是那些... 等阁下弥留之际，解决软件问题仍旧需要我说的那些。

呵呵，纸上谈兵

以不变应万变。。。

看着很蛋疼,大一刚来的时候是那几句话,这马上大三了,说来说去还是那些...

好多经典啊~~~

引用 49 楼 garbageam 的回复:我来告诉你,赵4能力很强,但他只是个精神领袖.换句话说,也只能在大方向上指点你,具体问题他不正面回答的 正面回答也行。男的email单聊并付费。女的开房单聊我付费！


Question: 请教关于struct

引用 3 楼 melos 的回复:楼主大概问的是这一句：typedef struct AInputEvent AInputEvent; 这是以前使用c语言时遗留的习惯。 因为在c中，要使用结构体，结构体前必须带struct，导致后续的使用书写时很不方便，因此进行一下typedef，于是可以看到第3行代码就能直接AInputEvent* 了，这就是它的作用。 当然在c++下这个问题已经不存在了，但习惯上一直这样写。。。。  记住了。

引用 3 楼 melos 的回复:楼主大概问的是这一句：typedef struct AInputEvent AInputEvent; 这是以前使用c语言时遗留的习惯。 因为在c中，要使用结构体，结构体前必须带struct，导致后续的使用书写时很不方便，因此进行一下typedef，于是可以看到第3行代码就能直接AInputEvent* 了，这就是它的作用。 当然在c++下这个问题已经不存在了，但习惯上一直这样写。。。。+1

空结构或者空类在代码中可以起到stub(桩)的作用。 在代码未成型之前，保证能编译通过的前提下，先写出一个代码架构来，这个时候空结构，空类还有空函数能起到占位的作用。

引用 3 楼 melos 的回复:楼主大概问的是这一句：typedef struct AInputEvent AInputEvent; 这是以前使用c语言时遗留的习惯。 因为在c中，要使用结构体，结构体前必须带struct，导致后续的使用书写时很不方便，因此进行一下typedef，于是可以看到第3行代码就能直接AInputEvent* 了，这就是它的作用。 当然在c++下这个问题已经不存在了，但习惯上一直这样写。。。。  其实问题的关键在第一句，那是一个空的struct。我记得我看过一个老外关于这个问题的解释，不过是好几年前了，现在记不得了。真遗憾。唯一记得的就是他说这是一个hack。绝对不是那么表面。

只是单纯的为了以后使用的时候书写方便，可以用AInputEvent 代替struct AInputEvent。没其他的意思。

3#正解、、

引用 楼主 julius1234567 的回复:struct AInputEvent;//这是一个空的stuct typedef struct AInputEvent AInputEvent; void f(AInputEvent* event),这么用有什么目的？或者好处？ 目的是定义一个看类型名就知道是做什么用的类型，增加错误检查提示。windows编程中，这样的东西很多。 比如： PSTR            //相当于char *，但char *不一定是字符串，而PSTR是专门是字符串 LPSTR         //32位的机器上和PSTR没有什么区别 LPCTSTR   //相当于const char*，  AInputEvent *，相当于，void*，但不能随意传void* ，这个时候会报类型不匹配，需要强制转换才会不报错。 这样就减少了编写代码时候的手误。

形参为结构体指针，就是说明在该函数中需要修改该结构体变量数据成员的值。 函数调用分两种形式，传值、传地址。这里就是传地址了。


Question: EEMD

matlab有工具箱，直接用就可以了，参数自己选择，你发错地方了

就是有没有关于EEMD的程序例题，看到的程序全是EEMD的源程序，没有具体分析的

完全摸不着头脑了

c语言编程实现分解你说得信号？

这问题太高端了,高端到问的不知是啥


Question: 对文件操作的一个小疑问！

果然如此，多谢楼上指正

EOF是文本文件的结束标志 可是我的file1.dat文件里并没有EOF啊？  computer and c  总共14个字符，文件只有14个字节？ 那EOF在哪里呢？ 程序是怎么找到EOF的呢？这个有点不明白，百科搜EOF也没有答案。。。 引用 1 楼 zhao4zhong1 的回复: 引用 4 楼 u010882724 的回复: 引用 5 楼 zjq9931 的回复:

推荐使用WinHex软件查看硬盘或文件或内存中的原始字节内容。

如果文件中存在一个字节是0xff，那么用下面的程序，iIn接收fgetc的返回值，和用cIn接收fgetc输出的结果是不同的。 用iIn接收，可以读取完整的文件，用cIn接收，只能读取到文件中的0xff处。  #include<stdio.h> int main() { 	FILE *pflIn; 	char cIn; 	int iIn; 	pflIn = fopen("f:\\b.txt", "rb"); 	if(pflIn == NULL) 	{ 		puts("sdfsdfds"); 		return 0; 	} 	cIn = fgetc(pflIn); 	while (cIn!=EOF) 	{ 		printf("%d\n", cIn); 		cIn = fgetc(pflIn); 	} 	printf("%d\n", EOF); 	return 0; }  引用 8 楼 u013491662 的回复:EOF是文本文件的结束标志 可是我的file1.dat文件里并没有EOF啊？  computer and c  总共14个字符，文件只有14个字节？ 那EOF在哪里呢？ 程序是怎么找到EOF的呢？这个有点不明白，百科搜EOF也没有答案。。。 [quote=引用 1 楼 zhao4zhong1 的回复:] 引用 4 楼 u010882724 的回复: 引用 5 楼 zjq9931 的回复:[/quote]  引用 8 楼 u013491662 的回复:EOF是文本文件的结束标志 可是我的file1.dat文件里并没有EOF啊？  computer and c  总共14个字符，文件只有14个字节？ 那EOF在哪里呢？ 程序是怎么找到EOF的呢？这个有点不明白，百科搜EOF也没有答案。。。 [quote=引用 1 楼 zhao4zhong1 的回复:] 引用 4 楼 u010882724 的回复: 引用 5 楼 zjq9931 的回复:[/quote]

while (!feof(in))     {         ch = fgetc(in);         fputc(ch, out);         putchar(ch);     }  当读出最后一个字节时，feof(in)   == 0, 接着又进入while    ch = fgetc(in);之后， feof(in)   != 0了， 之后便该跳出循环了。     for(;;)     {         ch = fgetc(in);         if(feof(in))         {            break;         }         fputc(ch, out);         putchar(ch);     }

注意如果用EOF判断，因为EOF是-1,而不是用feof()这个函数来判断，那么，接收fgetc函数返回值的必须是int型，不能是char型。因为文件中可能存在char型的-1，如果是文件中的-1字符（0xff）,用char型的接收，就后有问题了。int型的-1是0xffffffff 引用 8 楼 u013491662 的回复:EOF是文本文件的结束标志 可是我的file1.dat文件里并没有EOF啊？  computer and c  总共14个字符，文件只有14个字节？ 那EOF在哪里呢？ 程序是怎么找到EOF的呢？这个有点不明白，百科搜EOF也没有答案。。。 [quote=引用 1 楼 zhao4zhong1 的回复:] 引用 4 楼 u010882724 的回复: 引用 5 楼 zjq9931 的回复:[/quote]

引用 1 楼 zhao4zhong1 的回复:不要使用 while (条件) 更不要使用 while (组合条件) 要使用 while (1) {  if (条件1) break;  //...  if (条件2) continue;  //...  if (条件3) return;  //... } 因为前两种写法在语言表达意思的层面上有二义性，只有第三种才忠实反映了程序流的实际情况。 典型如： 下面两段的语义都是当文件未结束时读字符 while (!feof(f)) {  a=fgetc(f);  //...  b=fgetc(f);//可能此时已经feof了！  //... } 而这样写就没有问题： while (1) {  a=fgetc(f);  if (feof(f)) break;  //...  b=fgetc(f);  if (feof(f)) break;  //... } 类似的例子还可以举很多。

EOF是，文件读取函数的返回值。并没有在文件里面存着。是文件读取函数根据系统的文件结构来的。 引用 8 楼 u013491662 的回复:EOF是文本文件的结束标志 可是我的file1.dat文件里并没有EOF啊？  computer and c  总共14个字符，文件只有14个字节？ 那EOF在哪里呢？ 程序是怎么找到EOF的呢？这个有点不明白，百科搜EOF也没有答案。。。 [quote=引用 1 楼 zhao4zhong1 的回复:] 引用 4 楼 u010882724 的回复: 引用 5 楼 zjq9931 的回复:[/quote]

引用 17 楼 taiyang_1435586562 的回复:在对文件操作时，我也遇到过这样的问题，我是这样解决的： ch=fgetc(in); putchar(ch); fputc(ch,out); while(!feof(fp)) 	{	ch=fgetc(in);                 putchar(ch);                 fputc(ch,out); 	} 这段代码操作长度为0的文件时会出问题。

引用 9 楼 endeavourken 的回复:楼主确定file1.dat只有14个字符吗？ 我做一个file1.dat文件后，显示大小为15个字符，说明结尾有个EOF字符。 EOF字符的整数值为-1,所以在用char来显示时会是个奇怪的图形（ASCII码，不要忘记，规定的是0～127的对应字符，-1没有对应字符）

引用 2 楼 user-8 的回复:        听说feof()就是有这个问题，读到-1后不立即结束，还要多读一次.....那个符号就是 -1 吧，你调试下看看你while(!feof(in))里面是不是执行了15次 EOF是文本文件的结束标志 可是我的file1.dat文件里并没有EOF啊？  computer and c  总共14个字符，文件只有14个字节？ 哪EOF在哪里呢？ 程序是怎么找到EOF的呢？这个有点不明白，百科搜EOF也没有答案。。。

引用 楼主 u013491662 的回复:两个文件分别是 file1.dat file2.dat file1.dat里面的内容是 一共14个字符 file1.dat这个文件占14个字节 我的疑问是 为什么file2.dat占15个字节，内容里最后还有个字符，好像是空格，也好想是全角空格，又或者是别的！  读写文件的过程改成这样就可以了。  ch = fgetc(in); while (!feof(in))     {         fputc(ch, out);         putchar(ch);         ch = fgetc(in);//读取之后判断，是否文件结束，如果是结束，就不用写出了。     }

楼主可以去看一下百科的解释，里面详细说明了这个问题的原因、、、 http://baike.baidu.com/link?url=caxKNmCIhaGoPS-74dO4_GOIiTO74I_rDvSUdJv1luF0SjZCjNabyJqd0F2dBT1a

在没进行任何读操作之前是不可能feof的。


Question: 请大家帮忙看下我下面的程序错在哪里？

怎么结帖后全部显示0分？明明给了分的呀

float用f不是d，有警告

引用 8 楼 zxh707wk 的回复:[quote=引用 1 楼 zhao4zhong1 的回复:] int m,n; char c; while (1) {     printf("请输入两个整数，并用空格分隔开：");fflush(stdout);     rewind(stdin);     if (3==scanf("%d%d%c",&m,&n,&c)) {         if (c=='\n') {             printf("m/n=%d/%d=%g\n",m,n,(float)m/n);             break;         }     }     printf("错误！输入值中含有非整数！请重新输入！\n"); } 够屌[/quote] ++++++++++++++++++++++++++++++++

明明提示的输入两个整数，输入用的也是%d，变量也是整形的，非要输入小数。你是自己玩自己么？

输入“1 2xxx”试试。

引用 1 楼 zhao4zhong1 的回复:int m,n; char c; while (1) {     printf("请输入两个整数，并用空格分隔开：");fflush(stdout);     rewind(stdin);     if (3==scanf("%d%d%c",&m,&n,&c)) {         if (c=='\n') {             printf("m/n=%d/%d=%g\n",m,n,(float)m/n);             break;         }     }     printf("错误！输入值中含有非整数！请重新输入！\n"); } 够屌

break会退出到while外面。

好像不是break的原因，我找到其它原因了 如图，我把mn改成float型，然后把输出变量改成float型就解决了。

引用 1 楼 zhao4zhong1 的回复:int m,n; char c; while (1) {     printf("请输入两个整数，并用空格分隔开：");fflush(stdout);     rewind(stdin);     if (3==scanf("%d%d%c",&m,&n,&c)) {         if (c=='\n') {             printf("m/n=%d/%d=%g\n",m,n,(float)m/n);             break;         }     }     printf("错误！输入值中含有非整数！请重新输入！\n"); } break报错

printf里面的%和变量的一一对应关系 scanf里面的%和变量以及变量前加不加&的一一对应关系 是C代码中非常容易出错的地方，而且通常编译还不出错。 所以在编译源代码之前值得专门仔细检查一遍甚至多遍。

#include <stdio.h> void main() {	float m,n;  while(1) {	printf("请输入两个整数，并用空格分隔开：\n"); scanf("%f %f",&m,&n);                                                //如何判断输入的数是整数？                                               if (m==(int)m*10/10&&n==(int)n*10/10) {	printf("m/n=%.5f\n",(float)m/n); break; }  else printf("错误！输入值中含有非整数！请重新输入！\n"); } system("pause"); }  /* m 和 n是 float 形 scanf("%d %d",&m,&n);    中的 %d    改成 %f printf("m/n=%.5d\n",(float)m/n);  看你意思应该要输出float形的吧   把d  也改成 f  // m*10/10 可以把m小数部分变成0  例如 m = 6.9    m*10（69）/10 = 6  （整数除整数结果一定是整数） // 其实可以写成 if (m == (int)m && n == (int)n)    */

在每个最后不带\n的printf后面加fflush(stdout); 在每个不想受接收缓冲区旧内容影响的scanf前面加rewind(stdin); 另外请检查scanf的返回值。


Question: 学C两年多，请大家给点学习建议 ^_^

就是用c写的图形库嘛多了个去 ，Windows 自带的图形库，API就是C 写的，linux下有GTK,还有一些乱78遭的库。数据处理不就是用C调用数据库嘛，建议先学个sqlite 或 mysql玩玩.

嵌入式平台是C的天下

当然可以啦，只是要造很多轮子

啥叫“平台”？

给你一个平台你看看 图书信息管理平台，平台无处不在，在心里，在代码的世界里 图书信息管理平台

引用 4 楼 sinat_16612001 的回复:[quote=引用 1 楼 zhao4zhong1 的回复:] 啥叫“平台”？ 就是有界面窗口，可以数据和图形的显示处理的软件[/quote] MSDN98\SAMPLES\VC98\MFC\TUTORIAL\SCRIBBLE\STEP1～7\*.*

引用 5 楼 sinat_16612001 的回复:[quote=引用 2 楼 merlinfang 的回复:] 当然可以啦，只是要造很多轮子 “轮子”类似于什么？[/quote]  别人已经做好的东西！已经存在，已经有的工具，软件，平台，代码等等！

学好C语言， 再学点图形学，推荐玩Linux吧， 那是个很好玩的世界

引用 3 楼 Intel0011 的回复:嵌入式平台是C的天下 嵌入式平台?怎么学?

引用 2 楼 merlinfang 的回复:当然可以啦，只是要造很多轮子 “轮子”类似于什么？

引用 1 楼 zhao4zhong1 的回复:啥叫“平台”？ 就是有界面窗口，可以数据和图形的显示处理的软件


Question: 哥们,c如何全部删除指定元素?

引用 9 楼 super_admi 的回复:如果不是智商有硬伤，就是语文水平太差了。 我所看到的是人家问你是什么存储结构，而你却以为人家猜中了你的存储结构。 话说，即使你说了“猜对了”三个字，人家也还是没弄明白你到底用的什么方式来存储的吧？  [quote=引用 8 楼 king769147 的回复:] [quote=引用 3 楼 starytx 的回复:] 你想在什么结构上删除？链表？数组？... 版主, 四楼猜对了...[/quote][/quote]  我语文从读书到现在都是班里最差的... 你回答就回答,不回答拉倒.不要在这里语言攻击别人... 我都说我忘记说, 我承认我忘记交代在数组中. 你如果智商高点,可以有点推理能力的...我也不是有意说'猜'.

引用 10 楼 yangyunzhao 的回复:迫切需要提供语言表达能力，否则在项目组里面要吃亏的。  嗯嗯, 谢了,一直都注意着...继续努力...

迫切需要提供语言表达能力，否则在项目组里面要吃亏的。

引用 3 楼 starytx 的回复:你想在什么结构上删除？链表？数组？... 版主, 四楼猜对了...

引用 4 楼 henry3695 的回复:楼主是希望删除一个数组里面的元素吧，删除以后，希望把后面的元素移动到前面吧 对哈. 我没表达清楚,你懂...高人...

引用 1 楼 lovesmiles 的回复:完全不知道你在问什么，自言自语的。 对数组进行操作... 就是比如 {1,3,2,7,3},删除数组中所有值为3的元素. 但是不另外创建数组,也就是说在原有基础上进行操作.

如果不是智商有硬伤，就是语文水平太差了。 我所看到的是人家问你是什么存储结构，而你却以为人家猜中了你的存储结构。 话说，即使你说了“猜对了”三个字，人家也还是没弄明白你到底用的什么方式来存储的吧？  引用 8 楼 king769147 的回复:[quote=引用 3 楼 starytx 的回复:] 你想在什么结构上删除？链表？数组？... 版主, 四楼猜对了...[/quote]

#include <stdio.h> int del_node(char ary[],int nlen,char ch_del) {	 	int nPos = 0; 	int i = 0; 	for (;i<nlen;i++) 	{ 		if (ary[i]==ch_del) 		{ 			nPos=i; 			break; 		} 	}	 	for (i=nPos;(i+1)<nlen;i++) 	{ 		ary[i]=ary[i+1]; 	} 	return (nlen-1); }  int main(void) { 	char data[] = {0x1,0x2,0x3,0x4,0x5,0x6,0x7,0x8,0x9,0x10};  	int i =0; 	int nlen = del_node(data,sizeof(data),0x9); 	for (i=0;i<nlen;i++) 	{ 		printf("0x%x,",data[i]); 	} 	printf("\n******************************************************\n");   	nlen = del_node(data,nlen,0x3); 	for (i=0;i<nlen;i++) 	{ 		printf("0x%x,",data[i]); 	} 	printf("\n******************************************************\n");    	return 0; }

楼主是希望删除一个数组里面的元素吧，删除以后，希望把后面的元素移动到前面吧

完全不知道你在问什么，自言自语的。

你想在什么结构上删除？链表？数组？...

仅供参考#include <stdio.h> #include <string.h> #include <locale.h> char s[256]; char *p; int r,n,i; int main() {     setlocale(LC_ALL,"chs");     while (1) {         printf("请输入一行文字(空行结束),\"%%20\"将替换为\" \",\"你懂得\"将替换为\"XXXXXX\":\n");         fgets(s,256,stdin);         if ('\n'==s[0]) break;         p=s;         while (1) {             p=strstr(p,"%20");             if (p) {                 memmove(p+1,p+3,strlen(p)-3+1);                 p[0]=' ';             } else break;         }         p=s;         while (1) {             p=strstr(p,"你懂得");             if (p) {                 memmove(p+6,p+6,strlen(p)-6+1);                 for (i=0;i<6;i++) p[i]='X';             } else break;         }         printf("%s",s);     }     return 0; } //请输入一行文字(空行结束),"%20"将替换为" ","你懂得"将替换为"XXXXXX": //abcdefg%20helloworld%20something.pdf //abcdefg helloworld something.pdf //请输入一行文字(空行结束),"%20"将替换为" ","你懂得"将替换为"XXXXXX": //这是测试文字你懂得，在这个你懂的地方，就得做你懂得的事 //这是测试文字XXXXX，在这个你懂的地方，就得做XXXXX的事 //请输入一行文字(空行结束),"%20"将替换为" ","你懂得"将替换为"XXXXXX": //


Question: 求助，一个指针问题，详见主贴

引用 4 楼 zjq9931 的回复:[quote=引用 3 楼 cjwcommonuse 的回复:] 编译器错误刚解决，逻辑错误又出来了，哎~~~~ 逻辑错误，跟踪调试。 这种时候最长经验。如果不行我给跟踪一下。[/quote] 说实话，我是那种吃三堑 长一智的人，智商是硬伤

最后算是出来了 //消重函数 //数组名，数组元素个数，单个元素大小 //sample: //int iArray[] = {0, 1,2, 2, 3}; //unsigned count = sizeof(iArray)/sizeof(int); //int iRet = remove_repeat(iArray, &count, sizeof(int)); int remove_repeat(void *array, unsigned *pcount, unsigned ele_sz) { 	int count = *pcount; 	int valid_count = 0; 	if(array==NULL || count==0 || ele_sz==0) 		return -1;  	char *_array = (char*)array; 	char *buf = (char*)malloc(count*ele_sz);	//allocate 	memcpy(buf, _array, count*ele_sz);  	int bRepeat = 0; 	for(int i=0,j=0; i<count; ++i) 	{ 		bRepeat = 0; 		for(j=0; j<valid_count; ++j) 		{ 			//if(buf[i]==buf[j]) 			if(memcmp(buf+i*ele_sz, _array+j*ele_sz, ele_sz)==0)			 			{ 				bRepeat = 1; 				break; 			}		 		} 		if(!bRepeat) 		{ 			//array[i] = buf[i]; 			memcpy(_array+j*ele_sz, buf+i*ele_sz, ele_sz); 			++valid_count; 		} 	}  	*pcount = valid_count; 	free(buf);  	return 0; }

引用 3 楼 cjwcommonuse 的回复:编译器错误刚解决，逻辑错误又出来了，哎~~~~ 逻辑错误，跟踪调试。 这种时候最长经验。如果不行我给跟踪一下。

编译器错误刚解决，逻辑错误又出来了，哎~~~~

因为你用的void *buf,指针步进值不确定，你用buf+i*ele_sz才提示的，buf声明成你需要的指针类型

意思是，不知道指针是什么类型的指针，也就是指针指向的是字符型还是，整型，还是别的类型？ 字符型指针增1，地址移动1，长整型的指针增1，地址移动4，等等，这些区别。所以，一定要指定指针类型。 看你的程序中是，int型的，那就强制转换成int型的。


Question: 有没有大神会用C语言编写跟图像处理方面有关的函数？

可以用FreeImage，网上材料也比较多

网上对于ind2gray函数的比较多……你能不能给个链接一类的~？


Question: 数据存储的问题

首先要看你每组数据是不是同样的大小， 还是每组数据的大小是不一样的？  如果大小一样， 你可以在8M的Flash上预先分配好每组数据的空间，然后你就挨个往里填就可以了， 就像数组一样  如果大小不一样，那就只能链表了，并且由于你需要删除，可能删掉的节点空出来的空间，不足以放新元素，需要进行内存的合并，所以删除的过程中，可能还存在数据的移动。

如果数据大小固定，在8M空间建个索引怎样呢

以下内容仅供参考： 所谓修改删除文件a某位置的内容，其实是读打开文件a，再将‘a中修改删除位置之前的内容＋修改删除的内容＋a中修改删除位置之后的内容’保存到文件b，关闭文件a，删除文件a，将文件b改名为与之前文件a相同的名字，仅此而已。


Question: 碰到个有意思的编程题，跟大家分享下

经典的背包问题

动态问题，动态规划，真不懂~

就是0-1背包问题了，一般可以使用动态规划算法跟回溯法

有点小问题，如果主件都是0的话，那怎样确定那个附件是哪个主件的

可以看看贪心算法的介绍，提供个思路

这个是背包问题。这里给一个代码，LZ参考。 #include <stdio.h> #include <stdlib.h> #define N 60 int CountMaxValue( int index, int money, int f  ); struct InputBuf {     int price;     int weight;     int type; };  struct InputBuf inputBuf[N]; int m, n; int main() {     int i;     scanf( "%d%d", &n, &m );     //这里输入默认主物件如果有附件则附件一定紧挨着的主物件后面     for ( i=0; i<m; i++ ) scanf( "%d%d%d", &inputBuf[i].price, &inputBuf[i].weight, &inputBuf[i].type );     printf( "\n" );      printf( "%d ", CountMaxValue(0, n, 1) );      return 0; } /* **index为数物品下标，money剩余的钱， f为1时，附件可购买，为0时附件不可购买 */ int CountMaxValue( int index, int money, int f  ) {     int a = 0, b = 0;      if ( index >= m ) return 0;      if( inputBuf[index].type == 0 )     {          if ( money >= inputBuf[index].price )          {              a = CountMaxValue( index + 1, money - inputBuf[index].price, 1 ) + inputBuf[index].price * inputBuf[index].weight;              b = CountMaxValue( index + 1, money, 0 );              return a > b ? a:b;            }          else return CountMaxValue( index + 1, money, 0 );     }     else if ( (inputBuf[index].type != 0) && ( f == 1 ) )     {         if( money >= inputBuf[index].price ) a = CountMaxValue( index + 1, money - inputBuf[index].price, f ) + inputBuf[index].price * inputBuf[index].weight;         b = CountMaxValue( index + 1, money, f );         return a > b? a:b;     }     else     {         return CountMaxValue( index + 1, money, f );     }      return 0;  }

感觉上肯定是背包算法了，去google “背包9讲”

看着感觉很复杂，感觉很厉害


Question: 用C宏定义实现累加

宏定义的是常量，不是变量！

编译选项加/EP /P，重新编译，查看宏展开后对应的.i文件。gcc加-E

宏, 归根结底就是像你的   Find And Replace.  查找替换.  也就是编译器对代码进行编译前, 对所有代码做了一次"查找替换",   你觉得这个替换过程能有什么计算吗?

去看看 BOOST_PP

宏定义只是简单的字符串替换，你可别当成变量使用。每次加1，你觉得会保留嘛？

#define INDEX_CODE 0  #define TEMP INDEX_CODE #undef INDEX_CODE #define INDEX_CODE (TEMP + 1)  #undef TEMP #define TEMP INDEX_CODE #undef INDEX_CODE #define INDEX_CODE (TEMP + 1)  int a = INDEX_CODE;  TEMP 是用INDEX_CODE 定义的  后面接触了INDEX_CODE 就相当于TEMP没定义，然后又用 报错啦。    可以把TEMP改数字 验证我上面的说法。  至于其它的 表示不懂楼主想要什么。。。。。。


Question: 求教c语言实现工件表面检测需要的知识

嗯，你的这个问题，C语言只是工具，你更需要学习的是机器视觉方面的知识。 初期可以看看现成的视觉库，比如OpenCV这个开源视觉库，有C和C++的接口，大部分基础工作这个库已经做好了，你根据需要在进行开发。并且这个库还带了很多例子，估计和你的应用能考上，这样做起来就方便多了。 书籍就去下载一本《学习OpenCV中文版》

引用 楼主 qq_17338763 的回复:我做一个课题——用ccd采集数据，实现对工件表面检测，判断是否合格。我只学了一学期c语言，对这方面不懂，希望知道需要哪些知识，最好详细点，我好去查找资料。 ....感觉有点象这个笑话，我捡了一个鼠标，想配台电脑，请问还缺什么。。。


Question: 关于VS2012安全警告级别的问题

直接将某个警告设置为无效可以避免出现类似if(a=2)不提示的情况，好的，谢谢

#pragma warning(disable : xxxx)

后果是可能忽略掉了想看到的编译器警告，比如 if(a=2) 这种警告你都看不到


Question: 单精度浮点型运算问题？？？

引用 2 楼 user-2 的回复:循环变量张冠李戴了 for (j = 0; j < 3; j++) { 	zongfen += p->score[i]; 	zuigao += p->score[i]; }  显然应改为 for (j = 0; j < 3; j++) { 	zongfen += p->score[j]; 	zuigao += p->score[j]; }  ++++

刚试过 double型也是一样的结果！


Question: realloc函数调用时出现堆错误！

引用 1 楼 user-3 的回复:L->elem = (ElemType *)realloc(L->elem, (L->listsize + LISTINCREMENT) * sizeof(ElemType)); 用了malloc就要有free 但是我这个顺序表要一直保存着的，我后面还会对其进行其他的操作的，不能free掉吧

代码的意图看的一头雾水。 不过19行分配了4个字节的空间给(*L)->elem ， 50行给L->elem[L->length] 赋值，从第2个循环起就已经越界了，到后面第10个循环realloc的时候，判断这个指针不是有效的堆指针，然后崩溃了。

37行-47行，看了看，如果没理解错，是有问题的。你增加了LISTINCREMENT * sizeof(ElemType)空间，后面的 L->listsize怎么只加1呢。listsize应该是记录数组大小的，length应该是记录数组实际存在的元素个数的吧         if(L->length >= L->listsize)         {             L->elem = (ElemType *)realloc(L->elem, L->listsize  + LISTINCREMENT * sizeof(ElemType));                                     if(!L->elem)                 return;             else             {                 L->listsize += LISTINCREMENT ;             }         }

void CreateList(SqList *L)里，for第二次循环，数组L->elem[L->length]就越界了。初始化的时候，应该(*L)->elem = (ElemType *)malloc(sizeof(ElemType) *LIST_INIT_SIZE )，开辟一个10个整型大小的空间，才符合你的本意

还有个小问题，用rand()之前要先用srand()设种子


Question: 字符串和指针的一些疑问？

想到一个，，，C++的typeid().name() 、、、不过看不懂返回值

char (*)[20]与char **是不等价的，前者是指针数组，后者是二级指针。指针数组的意思就是指针指向了整个数组，这点体现在自加自减运算上最为明显，二级指针的意思是这个指针指向了另一个一级指针的地址。 你可以用代码试一下。 char a[2][20]; 	char (*p)[20]; 	p = a; 	char **q ; 	char *q1 = "a"; 	q = &q1; 	printf("%p\t%p\n",p,q); 	p++; 	q++; 	printf("%p\t%p\n",p,q); 看看结果就知道指针指向整个数组的意思了。 至于书的话就是c和指针，c陷阱与缺陷。

学好指针，C就差不多了

p    的类型是 char *[]  ar_p的类型是 char (*)[]  你代码中：     p指向常量区     ar_p指向堆栈

#include<stdio.h> int main(void) {         char *p[]={"i love","c language"};   //p的值等于"i love"的首地址，char *p[]  是指针数组 		//可以这样理解   		//char ary[]   和 char* pAary   可以等价， 		//所以  char *p[]  可以理解为 char ary[][]   		//同理   char (*ar_p)[20]    可以理解为  char ary[][20]         puts(p[0]);         puts(p[1]);         printf("%s\n",p[1]);         char ar[2][20]={"i love","c language"};         char (*ar_p)[20]=ar; 		         puts(ar_p[0]);//指向 ar[0][20]         puts(ar_p[1]);//指向 ar[1][20]  		printf("%c\n",*(ar_p[0]));         printf("%c\n",*(ar_p[1]));         printf("%s\n",ar_p[1]); 		//      char *p1="i love"; 		//      char (*p2)[]="c language";         return 0; }

引用 13 楼 u013163564 的回复:还有两本书可以去看，C与指针 C陷阱与缺陷+1

还有两本书可以去看，C与指针 C陷阱与缺陷

计算机组成原理→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指针，必须学习汇编以及C和汇编的对应关系。 从汇编的角度理解和学习C语言的指针，原本看似复杂的东西就会变得非常简单！ 指针即地址。“地址又是啥？”“只能从汇编语言和计算机组成原理的角度去解释了。” 但我又不得不承认：  有那么些人喜欢或者适合用“先具体再抽象”的方法学习和理解复杂事物；  而另一些人喜欢或者适合用“先抽象再具体”的方法学习和理解复杂事物。 而我本人属前者。  不要企图依赖输出指针相关表达式的值【比如printf("%p\n",...)】来理解指针的本质， 而要依赖调试时的反汇编窗口中的C/C++代码【比如void *p=...】及其对应汇编指令以及内存窗口中的内存地址和内存值来理解指针的本质。  这辈子不看内存地址和内存值；只画链表、指针示意图，画堆栈示意图，画各种示意图，甚至自己没画过而只看过书上的图……能从本质上理解指针、理解函数参数传递吗？本人深表怀疑！ 这辈子不种麦不收麦不将麦粒拿去磨面；只吃馒头、吃面条、吃面包、……甚至从没看过别人怎么蒸馒头，压面条，烤面包，……能从本质上理解面粉、理解面食吗？本人深表怀疑！！  提醒： “学习用汇编语言写程序” 和 “VC调试(TC或BC用TD调试)时按Alt+8、Alt+7、Alt+6和Alt+5,打开汇编窗口、堆栈窗口、内存窗口和寄存器窗口看每句C对应的汇编、单步执行并观察相应堆栈、内存和寄存器变化，这样过一遍不就啥都明白了吗。 （Linux或Unix下可以在用GDB调试时,看每句C对应的汇编并单步执行观察相应内存和寄存器变化。） 想要从本质上理解C指针，必须学习C和汇编的对应关系。” 不是一回事！  不要迷信书、考题、老师、回帖； 要迷信CPU、编译器、调试器、运行结果。 并请结合“盲人摸太阳”和“驾船出海时一定只带一个指南针。”加以理解。 任何理论、权威、传说、真理、标准、解释、想象、知识……都比不上摆在眼前的事实！  有人说一套做一套，你相信他说的还是相信他做的？ 其实严格来说这个世界上古往今来所有人都是说一套做一套，不是吗？  不要写连自己也预测不了结果的代码！  电脑内存或文件内容只是一个一维二进制字节数组及其对应的二进制地址； 人脑才将电脑内存或文件内容中的这个一维二进制字节数组及其对应的二进制地址的某些部分看成是整数、有符号数/无符号数、浮点数、复数、英文字母、阿拉伯数字、中文/韩文/法文……字符/字符串、汇编指令、函数、函数参数、堆、栈、数组、指针、数组指针、指针数组、数组的数组、指针的指针、二维数组、字符点阵、字符笔画的坐标、黑白二值图片、灰度图片、彩色图片、录音、视频、指纹信息、身份证信息……  十字链表交换任意两个节点C源代码（C指针应用终极挑战）http://download.csdn.net/detail/zhao4zhong1/5532495

1-p与ar_p是不是等价的? 答：不等价；p的类型char *数组；ar_p数据类型是char(*)[]数组指针！一个数组（多个元素），一个指针变量（单变量），当然不等  2-为什么两种打印结果完全相同？ p两个成员，每个成员指向一个字面字符串；二维ar，两行，每行20个字符，每行存储一个字符串。赋值给ar_p后，即*ap_p = ar; ar_p[0],ar_p[1]存储的两个行指针！（注意，我省略了第二维）输出的时候输出一行！因此，和输出p一致  3-那么char (*)[]是不是与char **等价？ 性质上不等价，操作上可等价。参考《c和指针》的数组与指针的相关内容。  4-请推荐一本准确详细的介绍指针的书：《c & pointer》

c风格的字符串就是使用一个字符指针+结束符'\0'来表示字符串的。只需知道首字符地址，就可以代表一个字符串，处理到时候系统自动从这个首地址开始一个一个读直到遇到结束符'\0'为止

引用 楼主 myclass242 的回复: /*  char *p="i love";成立,那么是不是可以使用字符串初始化char * 类型指针？ 如果是 char * 类型数组该如何初始化？这样可不可以？ char *p[]={"i love","c language"};  */  /*既然上述问题可以，那么我可不可以把{"i love","c language"}看成二维数组？那么 char ar[][20]={"i love","c language"}; char (*ar_p)[20]=ar; 是不是可以成立？*/  /*ar_p是指向20个char元素的指针变量，p是元素为char指针变量的数组*/ #include<stdio.h> int main(void) {         char *p[]={"i love","c language"};         puts(p[0]);         puts(p[1]);         printf("%s\n",p[1]);         char ar[2][20]={"i love","c language"};         char (*ar_p)[20]=ar;         puts(ar_p[0]);         puts(ar_p[1]);         printf("%s\n",ar_p[1]); //      char *p1="i love"; //      char (*p2)[]="c language";         return 0; }   这两种方法都可以，p与ar_p是不是等价的?如果不等价，我也觉得不能等价，不然我三观都毁了，为什么两种打印结果完全相同？ p的类型是不是 char **? ar_p的类型为char (*)[20]，如果等价，那么char (*)[]是不是与char **等价？  还有，指针好难，请推荐一本准确详细的介绍指针的书。我看的是《c primer plus(第五版)》，这本书就不要推荐了指针讲的太差了   首先就你提问题的方式，这样可不可以，我希望你先自己上机去编译去测试 完了再来问 要学会自己去验证，去琢磨，玩程序，这一点非常重要

char *p[]={"i love","c language"}; []的优先级高于*，所以p为数组，只不过数组元素的类型为字符串指针，即 char * 可以使用字符串初始化char * 类型指针，因为C语言中，字符串本质上代表的是一个地址，编译器会帮你自动转化  char ar[2][20]={"i love","c language"}; char (*ar_p)[20]=ar; 这个当然成立

请推荐一本准确详细的介绍指针的书 ------------------- 推荐哪本书，想象不出来。。。关键是用，看，想。练。学用结合，体会才能深刻。

p的类型是不是 char **? ------------------------------------ 不是。这个是指针数组。 char **是指针的指针。（两个，可以通用是因为，数组名，可以表示，数组的起始地址） 数组的地址是固定的。“容量”也是固定的。 指针指向的地址是可变的，“容量”也是可变的。 char *p[]={"i love","c language"};这个语句，说明，这个指针数组，初始化成含有两个指针的指针数组。  ar_p的类型为char (*)[20]，如果等价，那么char (*)[]是不是与char **等价？ ----------------------------------------- 上面已经说明。  做一个类比吧。可能不太恰当。 把内存当成一本书。 数组，相当于，书本的目录。表示某个内容在书本某一页-某一页，书本出版出来，这个是不能变了，虽然我们可以在指向的那一页做做批注笔记什么的（修改）。但我们不能改变目录的内容了。 指针，相当于书签，我们读到了哪里，就把书签插到那里（指针指向的地址改变），便于下次接着读。 书签非常多，我们想规范一下书签，于是又有了不同的整理方法，书签的书（指针数组），和书签的书签（指针的指针）。

C和指针，可以看看


Question: 在c语言中怎么实现计算两个时间的差值，精确到时分秒计算

仅供参考#include <afxdisp.h> #include <stdio.h> #include <stdlib.h> int main(int argc, TCHAR* argv[]) {     COleDateTime t;     COleDateTimeSpan ts;     CString s,fmt;     int nYear;     int nMonth;     int nDay;     int nHour;     int nMin;     int nSec;     int lDays;     int nHours;     int nMins;     int nSecs;     int i,N;     // initialize MFC and print and error on failure     if (!AfxWinInit(::GetModuleHandle(NULL), NULL, ::GetCommandLine(), 0)) {         printf("Fatal Error: MFC initialization failed\n");         return 1;     }     if (argc<13) {         printf("Usage:%s sYYYY sMM sDD shh smm sss pDD phh pmm pss n {SQL|YYYY|YY}\n",argv[0]);         return 2;     }     if (stricmp(argv[12],"SQL")==0) fmt="%Y-%m-%d %H:%M:%S";     else if (stricmp(argv[12],"YYYY")==0) fmt="%Y%m%d %H%M%S";     else if (stricmp(argv[12],"YY")==0) fmt="%y%m%d %H%M%S";     else {         printf("Usage:%s sYYYY sMM sDD shh smm sss pDD phh pmm pss n {SQL|YYYY|YY}\n",argv[0]);         return 3;     }     nYear =atoi(argv[ 1]);     nMonth=atoi(argv[ 2]);     nDay  =atoi(argv[ 3]);     nHour =atoi(argv[ 4]);     nMin  =atoi(argv[ 5]);     nSec  =atoi(argv[ 6]);     lDays =atoi(argv[ 7]);     nHours=atoi(argv[ 8]);     nMins =atoi(argv[ 9]);     nSecs =atoi(argv[10]);     N     =atoi(argv[11]);     if (N<=0) {         printf("Usage:%s sYYYY sMM sDD shh smm sss pDD phh pmm pss n {SQL|YYYY|YY}\n",argv[0]);         return 4;     }     t=COleDateTime( nYear, nMonth, nDay, nHour, nMin, nSec);     ts=COleDateTimeSpan( lDays, nHours, nMins, nSecs );     for (i=1;i<=N;i++) {         s=t.Format(fmt);         printf("%08d %s\n",i,s);         t=t+ts;     }     return 0; }

这个直接度娘吧。就搜“c语言 时间差”，答案一大堆

引用 5 楼 yuqing89320 的回复:struct tm tm_1 = 初始化; struct tm tm_2 = 初始化; printf( "%s", ctime( mktime( &tm_1 ) - mktime( &tm_2 ) ) );  改为 #include <stdio.h> #include <time.h>  int main( void ) {     struct tm tm_1 = {0};     struct tm tm_2 = {0};     struct tm tm_3 = {0};      tm_1.tm_sec = 1;  tm_1.tm_min = 1;     tm_1.tm_hour = 1; tm_1.tm_mday = 1;     tm_1.tm_mon = 0;  tm_1.tm_year = 2014 - 1900;          tm_2.tm_sec = 2;  tm_2.tm_min = 2;     tm_2.tm_hour = 2; tm_2.tm_mday = 2;     tm_2.tm_mon = 1;  tm_2.tm_year = 2015 - 1900;      tm_3.tm_sec = 0;  tm_3.tm_min = 0;     tm_3.tm_hour = 0; tm_3.tm_mday = 0;     tm_3.tm_mon = 0;  tm_3.tm_year = -1900;      time_t tim_1 = mktime( &tm_1 );     time_t tim_2 = mktime( &tm_2 );     time_t tim_3 = mktime( &tm_3 );     printf("time1: %s\n", ctime( &tim_1 ) );     printf("time2: %s\n", ctime( &tim_2 ) );     time_t tim = tim_2 - tim_1 + tim_3;     printf("time: %s\n", ctime( &tim ) );      return 0; }

difftime Finds the difference between two times.  double difftime( time_t timer1, time_t timer0 );  Routine Required Header Compatibility  difftime <time.h> ANSI, Win 95, Win NT    For additional compatibility information, see Compatibility in the Introduction.  Libraries  LIBC.LIB Single thread static library, retail version  LIBCMT.LIB Multithread static library, retail version  MSVCRT.LIB Import library for MSVCRT.DLL, retail version    Return Value  difftime returns the elapsed time in seconds, from timer0 to timer1. The value returned is a double-precision floating-point number.  Parameters  timer1  Ending time  timer0  Beginning time  Remarks  The difftime function computes the difference between the two supplied time values timer0 and timer1.  Example   /* DIFFTIME.C: This program calculates the amount of time  * needed to do a floating-point multiply 10 million times.  */  #include <stdio.h> #include <stdlib.h> #include <time.h>  void main( void ) {    time_t   start, finish;    long loop;    double   result, elapsed_time;     printf( "Multiplying 2 floating point numbers 10 million times...\n" );        time( &start );    for( loop = 0; loop < 10000000; loop++ )       result = 3.63 * 5.27;     time( &finish );     elapsed_time = difftime( finish, start );    printf( "\nProgram takes %6.0f seconds.\n", elapsed_time ); }   Output  Multiplying 2 floats 10 million times...  Program takes      2 seconds.   Floating-Point Support Routines |  Time Management Routines  See Also   time

去搜一下defftime,就是精确到秒的

linux下使用gettimeofday轻松搞定

没有，什么意思。。。。

听说过“闰秒”么？


Question: C语言矩阵行变换排序

推荐使用WinHex软件查看硬盘或文件或内存中的原始字节内容。  不要把 fopen("...","...");fscanf,fprintf,fgets,fgetc,fclose //读时把\r\n替换成\n，写时把\n替换成\r\n;读到\x1a就设置EOF;读写的内容当字符看待 和 fopen("...","...b");fseek,fread,fwrite,fgetc,fclose  //不作以上替换，遇到\x1a仍继续读;读写的内容当字节看待 弄混了


Question: 二叉树插入函数的一个细节

这和swap(int *a, int *b)里面要用指针是一个道理。 要想改变一个变量，就要用它的指针。现在你要改变指针，就得用指针的指针，指针自己其实也就是个变量。

嗯让我想想看

引用 1 楼 user-1 的回复:注意这里： *position = new_node; 根据前面的运行，这个相当于 node->left = new_node 或者 tree->root  = new_node 不用二重指针，做不到这个效果  那为什么不用一维指针做呢? position=new_node不就行了?

如果不用二重指针，比如这么写： BiTreeNode *position; position = tree->root; position = new_node;  // 这里只不过是把position指向了new_node，而 tree->root没有变化。 用了二级指针可以改变tree->root


Question: while ( scanf ("%d %d %d", &x, &y, &z ) != EOF ) 的相关问题

谢谢各位的解答，已经解决问题。。谢谢

Format Specification Fields: scanf and wscanf Functions A format specification has the following form:  % [width] [{h | l | I64 | L}]type  The format argument specifies the interpretation of the input and can contain one or more of the following:   White-space characters: blank (' '); tab ('\t'); or newline ('\n'). A white-space character causes scanf to read, but not store, all consecutive white-space characters in the input up to the next non–white-space character. One white-space character in the format matches any number (including 0) and combination of white-space characters in the input.   Non–white-space characters, except for the percent sign (%). A non–white-space character causes scanf to read, but not store, a matching non–white-space character. If the next character in stdin does not match, scanf terminates.   Format specifications, introduced by the percent sign (%). A format specification causes scanf to read and convert characters in the input into values of a specified type. The value is assigned to an argument in the argument list.  The format is read from left to right. Characters outside format specifications are expected to match the sequence of characters in stdin; the matching characters in stdin are scanned but not stored. If a character in stdin conflicts with the format specification, scanf terminates, and the character is left in stdin as if it had not been read.  When the first format specification is encountered, the value of the first input field is converted according to this specification and stored in the location that is specified by the first argument. The second format specification causes the second input field to be converted and stored in the second argument, and so on through the end of the format string.  An input field is defined as all characters up to the first white-space character (space, tab, or newline), or up to the first character that cannot be converted according to the format specification, or until the field width (if specified) is reached. If there are too many arguments for the given specifications, the extra arguments are evaluated but ignored. The results are unpredictable if there are not enough arguments for the format specification.  Each field of the format specification is a single character or a number signifying a particular format option. The type character, which appears after the last optional format field, determines whether the input field is interpreted as a character, a string, or a number.   The simplest format specification contains only the percent sign and a type character (for example, %s). If a percent sign (%) is followed by a character that has no meaning as a format-control character, that character and the following characters (up to the next percent sign) are treated as an ordinary sequence of characters, that is, a sequence of characters that must match the input. For example, to specify that a percent-sign character is to be input, use %%.  An asterisk (*) following the percent sign suppresses assignment of the next input field, which is interpreted as a field of the specified type. The field is scanned but not stored.

引用 3 楼 user-3 的回复:[quote=引用 1 楼 zjq9931 的回复:] 因为要输入3个数，所以要3个Ctrl+Z才可以。  #include <stdio.h>  int main() { 	int      x, y, z; 	int	    vnum = 0; 	 	while ( scanf("%d %d %d", &x, &y, &z)!=EOF )	//因为这个函数要输入3个数字，所以，要3个文件结束符，才能结束 	{ 		printf("x=%d, y=%d, z=%d", x, y, z); 	} 	//如果和结构体无关，建议用这种形式： 	while ( 1 )  	{ 		if(scanf("%d", &x)==EOF) 		{ 			break; 		} 		if(scanf("%d", &y)==EOF) 		{ 			break; 		} 		if(scanf("%d", &z)==EOF) 		{ 			break; 		} 		printf("x=%d, y=%d, z=%d", x, y, z); 	} 	puts("end"); 	return 0; }  别胡说  不是什么个数问题  [/quote] 啊，我试验过的啊，感觉确实是个数的问题。 我个人在这方面确实也有些疑惑，请指教。

引用 1 楼 zjq9931 的回复:因为要输入3个数，所以要3个Ctrl+Z才可以。  #include <stdio.h>  int main() { 	int      x, y, z; 	int	    vnum = 0; 	 	while ( scanf("%d %d %d", &x, &y, &z)!=EOF )	//因为这个函数要输入3个数字，所以，要3个文件结束符，才能结束 	{ 		printf("x=%d, y=%d, z=%d", x, y, z); 	} 	//如果和结构体无关，建议用这种形式： 	while ( 1 )  	{ 		if(scanf("%d", &x)==EOF) 		{ 			break; 		} 		if(scanf("%d", &y)==EOF) 		{ 			break; 		} 		if(scanf("%d", &z)==EOF) 		{ 			break; 		} 		printf("x=%d, y=%d, z=%d", x, y, z); 	} 	puts("end"); 	return 0; }  别胡说  不是什么个数问题

不要使用 while (条件) 更不要使用 while (组合条件) 要使用 while (1) {  if (条件1) break;  //...  if (条件2) continue;  //...  if (条件3) return;  //... } 因为前两种写法在语言表达意思的层面上有二义性，只有第三种才忠实反映了程序流的实际情况。 典型如： 下面两段的语义都是当文件未结束时读字符 while (!feof(f)) {  a=fgetc(f);  //...  b=fgetc(f);//可能此时已经feof了！  //... } 而这样写就没有问题： while (1) {  a=fgetc(f);  if (feof(f)) break;  //...  b=fgetc(f);  if (feof(f)) break;  //... } 类似的例子还可以举很多。

引用 4 楼 zjq9931 的回复:[quote=引用 3 楼 user-3 的回复:] [quote=引用 1 楼 zjq9931 的回复:] 因为要输入3个数，所以要3个Ctrl+Z才可以。  #include <stdio.h>  int main() { 	int      x, y, z; 	int	    vnum = 0; 	 	while ( scanf("%d %d %d", &x, &y, &z)!=EOF )	//因为这个函数要输入3个数字，所以，要3个文件结束符，才能结束 	{ 		printf("x=%d, y=%d, z=%d", x, y, z); 	} 	//如果和结构体无关，建议用这种形式： 	while ( 1 )  	{ 		if(scanf("%d", &x)==EOF) 		{ 			break; 		} 		if(scanf("%d", &y)==EOF) 		{ 			break; 		} 		if(scanf("%d", &z)==EOF) 		{ 			break; 		} 		printf("x=%d, y=%d, z=%d", x, y, z); 	} 	puts("end"); 	return 0; }  别胡说  不是什么个数问题  [/quote] 啊，我试验过的啊，感觉确实是个数的问题。 我个人在这方面确实也有些疑惑，请指教。[/quote]不同环境要求不一样  这里是ctrl+z 别的环境可能是ctrl+d 然后 ctrl+z 好像有一个特殊的要求 不能是 1 2 3 ctrl+z 回车 应该是 1 2 3 回车 ctrl+z 回车


Question: 关于队列的数组实现 有一行不太明白 谢谢老师

size是 当前 已经有 的 元素个数  capacity 可以理解为   size 能达到的最大值 ，就是Array数组的长度， 最多能放多少个 元素   rear 是 当前尾指针 的位置 ，就是当前Array数组中最后一个 有效元素 的 下标 ， if(++Value == Q->Capacity)这是一个前置++ 也就是预先算一下，下一个元素的下标应该放在哪个位置  如果 这个 下标达到了capacity ，也就是超过了数组 元素的最大个数，再从头开始放  之所以可以再从头开始放，因为你的代码没有贴全 ，这里猜测是跟front有关的，也就是这个Array是一个循环数组 比如下标为0的位置上的元素已经被删掉了，那么front就会指到1的位置上，这时0位置就空出来了 此时再插入一个元素，如果一直到capacity-1的位置 都已经放满了， 就放到0位置，这样循环使用。   比如说0-9个位置，容量Capacity为10，然后应该是Value=9，也就是rear =9，传给的value， ++value=10，  ++value == Q->Capacity，表示rear =9就是放满了 然后从头开始放  不会出现Value等于10的情况，因为这里始终是rear 传给的 Value， 当rear =9之后，调用Succ，返回时0，也就是rear等于9之后，就是rear等0，不会等于10

第一个问题看这里http://www.tuicool.com/articles/Iniu6r


Question: 计算链地址法的查找失败ASL

1*4吧   是不是少写了一个

引用 4 楼 user-2 的回复:这也许是你想要的  我也是这么算的。。和老师的课件就是不一样

这也许是你想要的

上面写的还要除以9，而且楼主不必拘泥于这个问题，这是转牛角尖，基本上不会考不成功的，问的都是成功的

引用 1 楼 user-2 的回复:查找成功asl为下 14,36,23,11,82,55共6个查找1次  1*6                          01,68两个查找2次   2*2                                        19查找3次   1*3 总共为1*6+2*2+1*3=13; 我想问的是查找失败的ASL，不是查找成功的ASL


Question: 逻辑错误，分析半小时也没看出来哪里错了，请高人指点！

引用 6 楼 u013491662 的回复:[quote=引用 3 楼 baichi4141 的回复:] 比起逻辑分析来，单步调试才是根本 感谢，一语惊醒梦中人 找到错误了 80-82行的  temp = *t; *t = *k; *k = temp;  改为  temp.num = t->num; t->num = k->num; k->num = temp.num; temp.score = t->score; t->score = k->score; k->score = temp.score;  就行了[/quote] 楼主，这两个有什么区别吗？求指教！！！

错误是因为替换的时候，替换节点的上一节点的next还指向原来的地址。举个例子 m->next = t; l->next = k; 经过以下置换之后。 temp = *t; *t = *k; *k = temp; m->next = t 和l->next = k没有变化。就导致链表混乱，从而出现错误。 楼主后来想到的替换方法是正确的 引用temp.num = t->num; t->num = k->num; k->num = temp.num; temp.score = t->score; t->score = k->score; k->score = temp.score;

仅供参考//假设带表头结点的单向链表头指针为head，试编写一个算法将值为5的结点插入到连接表的第k个结点前，删除第k个节点，并对该链表进行排序。 #include <stdio.h> #include <stdlib.h> #include <malloc.h> #include <time.h> struct NODE {     int          data;     struct NODE *next; } H,*head,*p,*q,*s1,*s2,*s3,*s4,*s; int i,j,k,n,t,m; int main() {     srand(time(NULL));      //填写头节点数据     H.data=-1;     H.next=NULL;     head=&H;      //创建10个节点的单链表     p=head;     for (i=0;i<10;i++) {         q=(struct NODE *)malloc(sizeof(struct NODE));         if (NULL==q) return 1;         q->data=rand()%100;//填写0..99的随机值         q->next=NULL;         p->next=q;         p=q;     }      //输出整个单链表     s=head->next;     while (1) {         if (NULL==s) {             printf("\n");             break;         }         printf("%02d->",s->data);         s=s->next;     }      //将值为5的结点插入到单链表的第k个结点前     k=3;     n=0;     p=head;     while (1) {         if (NULL==p) {             break;         }         n++;         if (k==n) {             q=(struct NODE *)malloc(sizeof(struct NODE));             if (NULL==q) return 1;             q->data=5;             q->next=p->next;             p->next=q;             break;         }         p=p->next;     }      //输出整个单链表     s=head->next;     while (1) {         if (NULL==s) {             printf("\n");             break;         }         printf("%02d->",s->data);         s=s->next;     }      //删除第k个节点     k=5;     n=0;     p=head;     while (1) {         if (NULL==p) {             break;         }         n++;         if (k==n) {             q=p->next;             if (q) {                 p->next=q->next;                 free(q);             }             break;         }         p=p->next;     }      //输出整个单链表     s=head->next;     while (1) {         if (NULL==s) {             printf("\n");             break;         }         printf("%02d->",s->data);         s=s->next;     }      //从小到大排序     for (p=head;p!=NULL && p->next!=NULL;p=p->next) {         for (q=p->next;q!=NULL && q->next!=NULL;q=q->next) {             if (p->next->data > q->next->data) {                  //交换data //              printf("swap %02d %02d\n",p->next->data,q->next->data); //              t=p->next->data;p->next->data=q->next->data;q->next->data=t;                  //或者                  //交换next //              printf("swap %02d %02d\n",p->next->data,q->next->data);                 s1=p->next;                 s2=p->next->next;                 s3=q->next;                 s4=q->next->next;                  if (s2!=s3) {                      p->next=s3;                     s3->next=s2;                      q->next=s1;                     s1->next=s4;                 } else {                      p->next=s3;                     s3->next=s1;                            q=s3;                     s1->next=s4;                 }                  //输出整个单链表 //              s=head->next; //              while (1) { //                  if (NULL==s) { //                      printf("\n"); //                      break; //                  } //                  printf("%02d->",s->data); //                  s=s->next; //              } //              getchar();             }         }     }      //输出整个单链表     s=head->next;     while (1) {         if (NULL==s) {             printf("\n");             break;         }         printf("%02d->",s->data);         s=s->next;     }      //将单链表中前 m 个结点和后 n 个结点进行互换,m+n为链表总长10     m=4;     n=6;     k=0;     p=head;     while (1) {         if (NULL==p) {             break;         }         k++;         if (m+1==k) {             q=p;         }         s=p;         p=p->next;     }     s1=head->next;     head->next=q->next;     s->next=s1;     q->next=NULL;      //输出整个单链表     s=head->next;     while (1) {         if (NULL==s) {             printf("\n");             break;         }         printf("%02d->",s->data);         s=s->next;     }      //释放所有节点     p=head->next;     while (1) {         if (NULL==p) {             break;         }         q=p->next;         free(p);         p=q;     }      return 0; } //18->94->58->17->27->20->43->57->75->78-> //18->94->05->58->17->27->20->43->57->75->78-> //18->94->05->58->27->20->43->57->75->78-> //05->18->20->27->43->57->58->75->78->94-> //43->57->58->75->78->94->05->18->20->27-> //

引用 3 楼 baichi4141 的回复:比起逻辑分析来，单步调试才是根本 感谢，一语惊醒梦中人 找到错误了 80-82行的  temp = *t; *t = *k; *k = temp;  改为  temp.num = t->num; t->num = k->num; k->num = temp.num; temp.score = t->score; t->score = k->score; k->score = temp.score;  就行了

引用 1 楼 user-5 的回复:指针没有初始化！！ 引用 2 楼 user-5 的回复:sort(）函数里有两处指针没有申请内存空间直接使用！而且在creat()函数中p2也没有申请空间！ 。。。creat函数里p2是用来做链表的。 sort函数里两处没有申请内存空间的指针是哪两个？

比起逻辑分析来，单步调试才是根本

指针没有初始化！！


Question: VS2010 中freopen 总是报错

引用 2 楼 islandlin0212 的回复:[quote=引用 1 楼 mujiok2003 的回复:] #include <stdio.h>   我没那么二拉，，不是这个问题[/quote] 使用C++编译 /TP,不要使用C编译 /TC  http://msdn.microsoft.com/en-us/library/032xwy55.aspx

*.c--> *.cpp

你建立的是C工程，不是C++工程 C不允许在变量声明之前有其他语句，C++中可以 将 freopen("data.out","w",stdout); freopen("data.in","r",stdin); 放在S=0;i=0;之后 即 S=0;i=0; freopen("data.out","w",stdout); freopen("data.in","r",stdin); scanf("%d",&x);  min =x ;max= x;//初值很重要

引用 1 楼 mujiok2003 的回复:#include <stdio.h>   我没那么二拉，，不是这个问题

#include <stdio.h>


Question: 在VS2013下，我的C语言火车问题的队列程序怎么运行不了？

代码功能归根结底不是别人帮自己看或讲解或注释出来的；而是被自己静下心来花足够长的时间和精力亲自动手单步或设断点或对执行到某步获得的中间结果显示或写到日志文件中一步一步分析出来的。 提醒：再牛×的老师也无法代替学生自己领悟和上厕所！ 单步调试和设断点调试（VS IDE中编译连接通过以后，按F10或F11键单步执行，按Shift+F11退出当前函数；在某行按F9设断点后按F5执行停在该断点处。）是程序员必须掌握的技能之一。

我测试不会报错，so，贴错误吧。

千万别用vs


Question: 请问这个是'指针'么?

楼主说的对 string存的是实际字符的地址 楼主的问题出在   *  这个运算符上 这个运算符叫指针运算符，也称间接访问运算符 *string 表示“string指向的对象”即string指针变量里的地址指向的字符型变量 *string != '\0' 这样就意味着 string指向的字符型变量与'\0'比较

我比较纳闷的是第一个while有什么用，if不就好了吗？？

strings是char ** string = *strings 所以string是char * 那*string就是char了。

我也看错了, string和 strings...

引用 2 楼 caozhy 的回复:strings相当于二维数组。 每个元素是一个字符数组（string） string是一个一维数组（value） value是单个字符。 完全出乎意料,入门c中,谢了...版主...

引用 1 楼 user-6 的回复:char	*string;	/* the string we're looking at */  string是char* *string是char 入门c中,天呀.完全不懂,得把指针和字符串看了先...谢了...


Question: 小白求教，带双引号的字符串和char[]有什么区别，还有怎么获得当前日期的格式化字符串

仅供参考#include <stdio.h> #include <string.h> #include <time.h> #include <sys/timeb.h>  struct tm st; time_t tt; char mon[4]; char mn[12][4]={"Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"}; int i; char timstr[27]; char tmpbuf[128]; struct _timeb tb; int tz; char c;  void main() {     strcpy(timstr,"08/Dec/2011:15:25:03 +0800");     sscanf(timstr,"%2d/%3s/%4d:%2d:%2d:%2d",&st.tm_mday,mon,&st.tm_year,&st.tm_hour,&st.tm_min,&st.tm_sec);     for (i=0;i<12;i++) if (0==stricmp(mn[i],mon)) {st.tm_mon=i; break;}     st.tm_year-=1900;     tt=mktime(&st);     if (-1!=tt) {         strftime(tmpbuf,128,"%Y-%m-%d %H:%M:%S\n",localtime(&tt));         printf(tmpbuf);//2011-12-08 15:25:03     } else {         printf("[%s] is Invalid time string!\n",timstr);     }      _ftime(&tb);     strftime(tmpbuf,128,"%m/%b/%Y:%H:%M:%S",localtime(&tb.time));     tz=-tb.timezone;     c=(tz>0)?'+':'-';     tz=(tz>0)?tz:-tz;     sprintf(tmpbuf,"%s %c%02d%02d\n",tmpbuf,c,tz/60,tz%60);     printf(tmpbuf);//12/Dec/2011:17:36:41 +0800 }

应该是strftime需要char *，Show_Str需要unsigned char *引起的

引用 1 楼 caozhy 的回复:char *修改为unsigned char * 哇，是C大！  我按照你说的方法改了一下 void display_page1(void) { 	time_t rawtime; 	struct tm * timeinfo; 	unsigned char strbuff[128]; 	 	rawtime = time(NULL); 	timeinfo = localtime(&rawtime);	 	strftime( strbuff, 128, "%Y年 %A月 %d日", timeinfo);	  	Show_Str(80,200,320,16,strbuff,16,0); }  编译的时候，报了另外一个错： ..\MONITOR\monitor_display.c(35): warning:  #167-D: argument of type "unsigned char *" is incompatible with parameter of type "char *restrict"  另外我把u8的定义也贴一下： typedef unsigned          char uint8_t; typedef uint8_t  u8;

char 修改为unsigned char

char *修改为unsigned char *


Question: 关于c语言中的宏的问题

#与##在宏定义中的--宏展开 #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

error C2065:'ab':undeclared identifier 这个不明摆着的嘛！

遇到宏问题时，可以加上 编译参数 /EP 查看宏展开后的结果  这里 printf ("%s\n", join(a, b));  等价于printf ("%s\n", ab); 而程序中并未定义变量ab，so error

printf ("%s\n",join(a,b));  等价于printf ("%s\n",ab); 这能不出错吗

因为没有叫“ab”的变量。 没事别瞎折腾宏。 你这样搞出来的代码，最后只能是维护上的噩梦，害人害己的。

或者lz是想这样 #include <stdio.h> #include <stdlib.h> #include <string.h>   #define show(var) printf (#var"is %d\n",var) #define print(var) printf ("%s\n",#var) #define join(a,b) "%s%s",a,b   int main () {     int number = 10;     char a[]="hsppy ";     char b[]="day!";      show(number);     print(C language);     printf (join(a,b));     return 0; }

引用 5 楼 u014360189 的回复:楼主，你的愿意是想输出"a##b"吧,而你宏定义里却只是a##b是个变量，我把你的代码在a##b处添加“”双引号，把它变作字符串，就可运行成功了#define join(a,b) "a##b"+1


Question: C语言数据结构

崩溃的时候在弹出的对话框按相应按钮进入调试，按Alt+7键查看Call Stack里面从上到下列出的对应从里层到外层的函数调用历史。双击某一行可将光标定位到此次调用的源代码或汇编指令处。   仅供参考//假设带表头结点的单向链表头指针为head，试编写一个算法将值为5的结点插入到连接表的第k个结点前，删除第k个节点，并对该链表进行排序。 #include <stdio.h> #include <stdlib.h> #include <malloc.h> #include <time.h> struct NODE {     int          data;     struct NODE *next; } H,*head,*p,*q,*s1,*s2,*s3,*s4,*s; int i,j,k,n,t,m; int main() {     srand(time(NULL));      //填写头节点数据     H.data=-1;     H.next=NULL;     head=&H;      //创建10个节点的单链表     p=head;     for (i=0;i<10;i++) {         q=(struct NODE *)malloc(sizeof(struct NODE));         if (NULL==q) return 1;         q->data=rand()%100;//填写0..99的随机值         q->next=NULL;         p->next=q;         p=q;     }      //输出整个单链表     s=head->next;     while (1) {         if (NULL==s) {             printf("\n");             break;         }         printf("%02d->",s->data);         s=s->next;     }      //将值为5的结点插入到单链表的第k个结点前     k=3;     n=0;     p=head;     while (1) {         if (NULL==p) {             break;         }         n++;         if (k==n) {             q=(struct NODE *)malloc(sizeof(struct NODE));             if (NULL==q) return 1;             q->data=5;             q->next=p->next;             p->next=q;             break;         }         p=p->next;     }      //输出整个单链表     s=head->next;     while (1) {         if (NULL==s) {             printf("\n");             break;         }         printf("%02d->",s->data);         s=s->next;     }      //删除第k个节点     k=5;     n=0;     p=head;     while (1) {         if (NULL==p) {             break;         }         n++;         if (k==n) {             q=p->next;             if (q) {                 p->next=q->next;                 free(q);             }             break;         }         p=p->next;     }      //输出整个单链表     s=head->next;     while (1) {         if (NULL==s) {             printf("\n");             break;         }         printf("%02d->",s->data);         s=s->next;     }      //从小到大排序     for (p=head;p!=NULL && p->next!=NULL;p=p->next) {         for (q=p->next;q!=NULL && q->next!=NULL;q=q->next) {             if (p->next->data > q->next->data) {                  //交换data //              printf("swap %02d %02d\n",p->next->data,q->next->data); //              t=p->next->data;p->next->data=q->next->data;q->next->data=t;                  //或者                  //交换next //              printf("swap %02d %02d\n",p->next->data,q->next->data);                 s1=p->next;                 s2=p->next->next;                 s3=q->next;                 s4=q->next->next;                  if (s2!=s3) {                      p->next=s3;                     s3->next=s2;                      q->next=s1;                     s1->next=s4;                 } else {                      p->next=s3;                     s3->next=s1;                            q=s3;                     s1->next=s4;                 }                  //输出整个单链表 //              s=head->next; //              while (1) { //                  if (NULL==s) { //                      printf("\n"); //                      break; //                  } //                  printf("%02d->",s->data); //                  s=s->next; //              } //              getchar();             }         }     }      //输出整个单链表     s=head->next;     while (1) {         if (NULL==s) {             printf("\n");             break;         }         printf("%02d->",s->data);         s=s->next;     }      //将单链表中前 m 个结点和后 n 个结点进行互换,m+n为链表总长10     m=4;     n=6;     k=0;     p=head;     while (1) {         if (NULL==p) {             break;         }         k++;         if (m+1==k) {             q=p;         }         s=p;         p=p->next;     }     s1=head->next;     head->next=q->next;     s->next=s1;     q->next=NULL;      //输出整个单链表     s=head->next;     while (1) {         if (NULL==s) {             printf("\n");             break;         }         printf("%02d->",s->data);         s=s->next;     }      //释放所有节点     p=head->next;     while (1) {         if (NULL==p) {             break;         }         q=p->next;         free(p);         p=q;     }      return 0; } //18->94->58->17->27->20->43->57->75->78-> //18->94->05->58->17->27->20->43->57->75->78-> //18->94->05->58->27->20->43->57->75->78-> //05->18->20->27->43->57->58->75->78->94-> //43->57->58->75->78->94->05->18->20->27-> //

伙计，这么长的代码也没个注释，谁能看懂啊!

楼主要把全部的错给贴出来才好看啊..............


Question: Uva10152——where goes wrong

因为你的测试数据和人家的测试数据不一样。


Question: 在VS2010环境下调试一个C程序，报错了，但是我看不懂，求教

int j=0; while(sum[j]==0) { j++; } 这句话啥意思啊？

谢谢，已经运行出来了。

出错原因是以下语句只申请了一个字节的内存来存放长整数： p1=(char *)malloc(sizeof(char)); p2=(char *)malloc(sizeof(char));  建议如下修改：  #define MAX_LENGTH 100 /*加 假定整数最长不超过99位*/ void main() {   char *p1,*p2,*sum,*sum_out;   p1=(char *)malloc(MAX_LENGTH*sizeof(char));//改 p1=(char *)malloc(sizeof(char));   p2=(char *)malloc(MAX_LENGTH*sizeof(char));//改 p2=(char *)malloc(sizeof(char));


Question: C语言malloc和strcpy基本问题

strcpy不会管目的地的容量，它只将源地址的以'\0'结尾的字符串复制到目的地，目的地太短的话会越界操作 建议使用有字符数限制的版本  char *strncpy( char *strDest, const char *strSource, size_t count );

printf的格式描述要和实参匹配。  打印地址用%p,不要用%d

引用 2 楼 u013025310 的回复:我的意思是c3指向的是3个字节的堆空间，为什么abcdefg超过3个字节能正常输出，这里strcpy的原理是什么？ 溢出,占用了后面的其它空间,可能引发崩溃,当然你程序小,没有不良反应

引用 2 楼 u013025310 的回复:我的意思是c3指向的是3个字节的堆空间，为什么abcdefg超过3个字节能正常输出，这里strcpy的原理是什么？ 已经越界， 行为未定义。 所谓“正常输出“是可能的结果之一。  strcpy的文档：http://www.cplusplus.com/reference/cstring/strcpy/

输出到"/0"空字符


Question: 中文的字符输出

// test.cpp : 定义控制台应用程序的入口点。 //  #include "stdafx.h" #include <iostream> #include <conio.h> #include <atlbase.h> using namespace std;    int _tmain(int argc, _TCHAR* argv[]) {          int k,l; 		USES_CONVERSION;  		wchar_t a[]= {0x5927,0x5bb6,0x597d,0x5927,0x5bb6,0x597d,0x0000}; 		printf("%s\n", W2A(a));          for(k=0;*(a+k)!='\0';k++)         { 			wchar_t p = a[k];                 printf("*(a+%d)=%s",k,W2A(&p)); 				//putchar(*(a+k));                 putchar('\n');         }  	return 0; }

楼主可以试试加一行 printf("%d\n", strlen(a)); 看看这个字符串的长度，应该是11。5个汉字对应了10个字节，再加上一个c 比如说，假定某个汉字的编码是0x1234，那么连续输出0x12和0x34就会显示这个汉字，但是输出0x12 \n 0x34就会显示两行乱码

每个汉字实际上是两个字节，如果各自单独打印就是两个乱码。但是两个乱码连起来就又是一个汉字了。


Question: 定义一个数组，先进先出。怎样做效率高一点

引用 9 楼 xia8710279 的回复:回复   [quote=引用 4 楼 zilaishuichina 的回复:] C的话 简单写一个， 用数组做的循环队列   const int capacity = 10;//队列最大元素个数 typedef struct Queue { 	int m_array[capacity]; 	int m_front;//首元素下标 	int m_rear;//尾元素下标 	int m_size;//当前元素个数 }Queue;  void InitQueue(Queue *pQueue) { 	pQueue->m_front = 0; 	pQueue->m_rear = 0; 	pQueue->m_size = 0; }  bool IsFull(Queue *pQueue) { 	return pQueue->m_size == capacity ? true : false; }  void Push(Queue *pQueue, int v) { 	pQueue->m_array[pQueue->m_rear] = v;  	pQueue->m_rear++; 	if (pQueue->m_rear == capacity) 	{ 		pQueue->m_rear = 0; 	}  	pQueue->m_size++; }  bool IsEmpty(Queue *pQueue) { 	return pQueue->m_size == 0 ? true : false; }  int Pop(Queue *pQueue) { 	int current = pQueue->m_front;  	pQueue->m_front++; 	if (pQueue->m_front == capacity) 	{ 		pQueue->m_front = 0; 	}  	pQueue->m_size--;  	return pQueue->m_array[current]; }    这个不错，再在进队列和出队列的时候调用bool IsFull(Queue *pQueue)，bool IsEmpty(Queue *pQueue)[/quote] 再加个数组内求平均怎么做啊

仅供参考：//循环向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; }

通常要（取模） “%队列长度”。 pQueue->m_front = 0; ？？？

我觉着用STL就行  个人写的还是不如STL

数组循环队列

引用 5 楼 my_live_123 的回复:数组循环队列 差不多

回复   引用 4 楼 zilaishuichina 的回复:C的话 简单写一个， 用数组做的循环队列   const int capacity = 10;//队列最大元素个数 typedef struct Queue { 	int m_array[capacity]; 	int m_front;//首元素下标 	int m_rear;//尾元素下标 	int m_size;//当前元素个数 }Queue;  void InitQueue(Queue *pQueue) { 	pQueue->m_front = 0; 	pQueue->m_rear = 0; 	pQueue->m_size = 0; }  bool IsFull(Queue *pQueue) { 	return pQueue->m_size == capacity ? true : false; }  void Push(Queue *pQueue, int v) { 	pQueue->m_array[pQueue->m_rear] = v;  	pQueue->m_rear++; 	if (pQueue->m_rear == capacity) 	{ 		pQueue->m_rear = 0; 	}  	pQueue->m_size++; }  bool IsEmpty(Queue *pQueue) { 	return pQueue->m_size == 0 ? true : false; }  int Pop(Queue *pQueue) { 	int current = pQueue->m_front;  	pQueue->m_front++; 	if (pQueue->m_front == capacity) 	{ 		pQueue->m_front = 0; 	}  	pQueue->m_size--;  	return pQueue->m_array[current]; }    这个不错，再在进队列和出队列的时候调用bool IsFull(Queue *pQueue)，bool IsEmpty(Queue *pQueue)

这个实用性不够强吧。只能保存字符呀

多谢指点

我觉得大致的思路也就是这样了，很简单，效率也不错，我想不到效率更高的办法，也许有高手可以。  几个细节要注意：  a=A_buff[HeadNum]; 这个a后来没用到呀。两个可能：或者a就没用，或者应该return a，这个细节楼主自己调试吧，我没时间细看了。  不知道你打算把NULL_DATA定义成什么，不管是0xFF还是0还是别的什么值，都无法和正常值区分开，所以我建议把这个函数改成 BOOL Out_Stack(unsigned char *ret_value);  先进先出的是队列queue，不是栈stack。c程序员的字典里没有“堆栈”这个词，只有“堆”和“栈”  uchar、unsigned char、uint8 太乱了，要一致才好。head对应tail，begin对应end


Question: 请教高手如何在windows窗口系统下（不是控制台模式）的学习c语言

查MSDN是Windows程序员必须掌握的技能之一。  英语也是一门计算机语言的说。

#pragma comment(lib,"user32") #pragma comment(lib,"gdi32") #include <windows.h> LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) {     PAINTSTRUCT ps;     HDC hdc;     HFONT hfont,ohfont;     RECT r;     COLORREF oc;      switch(message) {     case WM_CLOSE://按Alt+F4退出         PostQuitMessage(0);         break;     case WM_PAINT:         BeginPaint(hWnd, &ps);         hdc = ps.hdc; // the device context to draw in         GetClientRect(hWnd, &r); // Obtain the window's client rectangle         hfont = CreateFont(240, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "华文楷体");         ohfont=SelectObject(hdc,hfont);         oc=SetTextColor(hdc,0x00C080FF);         SetBkMode(hdc, TRANSPARENT);         TextOut(hdc,r.left+r.right/2-720, r.top+r.bottom/2-120,"最短画图程序",12);         SelectObject(hdc,ohfont);         SetTextColor(hdc,oc);         DeleteObject(hfont);         EndPaint(hWnd, &ps);         break;     default:         return DefWindowProc(hWnd, message, wParam, lParam);     }     return 0; } int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) {     MSG msg             = {0};     WNDCLASS wc         = {0};     HBRUSH hbrh;     hbrh=CreateSolidBrush(0x00000000);     wc.lpfnWndProc      = WndProc;     wc.hInstance        = hInstance;     wc.hbrBackground    = hbrh;     wc.lpszClassName    = "minwindowsapp";     wc.hCursor          = LoadCursor(NULL,IDC_ARROW);     if( FAILED(RegisterClass(&wc)) ) return 1;      if(FAILED(CreateWindow(wc.lpszClassName,                         "Minimal Windows Application",                         WS_POPUP|WS_VISIBLE,                         0,                         0,                         GetSystemMetrics(SM_CXSCREEN),                         GetSystemMetrics(SM_CYSCREEN),                         0,                         0,                         hInstance,                         NULL)))         return 2;      while( GetMessage( &msg, NULL, 0, 0 ) > 0 ) {         DispatchMessage( &msg );     }     DeleteObject(hbrh);     return 0; }

MSDN  原汁原味

给你一个例子吧，c++的，其实差不多的 C++写的win32简单密码保险箱

引用 楼主 king_2007 的回复:请问高手哪里有中文的windows api的文档？？最好是翻译不错的。另外学习用c语言开发窗口应用程序？一些句柄的类型如何获取呢？ http://wenku.baidu.com/link?url=edl0-qCA3C9yAEW2sFB_f8oYUD2s_HL6Te8DoVcG3rPEZpLYLQ70haQjDXaG5hhi9EguljLqDQis3HPq-sWtIh8S2YAR4kIdP6XNCGVOA-K 新编Windows_API_参考大全(真正完整版) 但最好用英文版 句柄的类型 可以在VS中 点击右键 －－－> Go to definition of  ****查看是如何定义的


Question: 栈的数组实现 有2行不明白

你先把 数据类型看清楚  应该就知道哪些东西需要分派内存

S应该是一个指向结构体的指针，要为它分配。 S结构的的Array成员也是指针，因此也需要分配空间。

第一次是为S结构体本身开辟空间 第二次是为S结构体的Array成员所指向ElementType结构体数组开辟空间


Question: 回文判断（用C语言）    求大神帮忙

如果是短的输入用一个字符串存储，用下标比较前后对应位置是否相等，如果长的话用vector来存储避免浪费内存。

bool  isPalindrome(char *str) { 	char *p1=str; 	char *p2=str; 	if(str==NULL)  return false; 	while(*(p2+1))  p2++; 	while(1) 	{ 		if(*p1!=*p2)  return false; 		if(p2<=p1) return true; 		p1++; 		p2--; 	} }

#include <stdio.h> #include <string.h> #define N 1000 #define TURE 1 #define FALSE 0 int is_palindrome(char *s) { 	char *h = s; 	char *t = s+strlen(s)-1; 	 	while(h < t) 	{ 		if(*h != *t) 				return FALSE; 		else 		{ 			h++; 			t--; 		} 	} 	return TURE; } int main() { 	char str[N]; 	int ret;  	printf("input\n"); 	scanf("%s",str); 	if(is_palindrome(str)) 	{ 		printf("input is palindrome\n"); 	} 	else 	{ 		printf("input is not palindrome\n"); 	} 	return 0;  }

#include<stdio.h> #include<string.h> char _str[1005]; int palindrome(char _str[],int _L,int _R) {  if(_L>=_R)return 1;  if(_str[_L]-_str[_R])   return 0;  return palindrome(_str,_L+1,_R-1); } int main(void ) {  while(gets(_str),strcmp(_str,"@"))//输入@结束   printf("%s\n",palindrome(_str,0,strlen(_str)-1)?"Yes":"No"); }