Question: 为什么对话框显示后，程序不能动弹了

非常感谢ant2012的帮助.我又可以继续前进了. 需要总结下: 之前我一直在搜DialogBox()函数相关的东西看,一直没能找到真正的问题所在. 为什么我没法精准定位到是这个问题呢,而且根本想不到是这个问题. 如果WS_POPUP style   和  WS_CHILD style 放在某个函数里边做参数,我可能会去尝试修改, 放在资源属性里,真是不容易发现,况且对这些属性本身也不太了解.  谢谢ant2012 . 也谢谢link0007 . 分数怎么你呢.

对话框上没X吗？ 在  case   WM_COMMAND :              switch (LOWORD (wParam))              {                 case   IDOK :                 //case   IDCANCEL :                         EndDialog (hDlg, 0) ;                         return TRUE ;              }              break ; case IDOK那插一个断点试试，看看有没有执行到这一步

搜索 模态对话框 与 非模态对话框 区别

IDD_AboutBox这是你自己定义的，我改成大写了，也没用； 另外，IDD_ABOUTBOX 对话框的资源视图，在资源属性里把"system menu"打上钩，就有边框了。 但是，做了上面的改动，对话框仍然不能关闭，OK按钮没反应，程序死掉了，动弹不得。

IDD_AboutBox这是你自己定义的？系统定义的都是大写， 看看是不是这个资源，另外，找到IDD_AboutBox对话框的资源视图，看看在设计的时候你是不是把它的边框去掉了

我有这个ENDDLG函数的: BOOL CALLBACK AboutDlgProc(HWND hDlg, UINT message,WPARAM wParam, LPARAM lParam) {    switch (message)    {       case   WM_INITDIALOG : 		     MessageBox(NULL,"WM_INITDIALOG 执行到了",MB_OK,NULL);              return TRUE ;       case   WM_COMMAND :              switch (LOWORD (wParam))              {                 case   IDOK :                 //case   IDCANCEL :                         EndDialog (hDlg, 0) ;                         return TRUE ;              }              break ;    }    return FALSE ; }  问题是, 对话框没有完整显示,中间区域显示了,但是旁边的边框没有显示,所以没法关闭对话框.

DialogBoxParam创建的是一个模态对话框，当模态对话框处于活跃状态时，父窗口会被阻塞，如果你不关闭它，父窗口是无法操作的，可以调用EndDialog去关闭它 BOOL EndDialog(   HWND hDlg,    // handle to dialog box   int nResult   // value to return ); 第一个参数为创建模态对话框的句柄，第二个参数为DialogBoxParam的返回值

我可以告诉你是哪个点错误，就是下面这个函数：  DialogBoxParam(hInstance, MAKEINTRESOURCE(IDD_AboutBox), hwnd, (DLGPROC)AboutDlgProc,NULL) ;  但是我不知道问题在哪。

插断点，自己调试一下，太长了，找错太费劲了

主线程等待对话框返回，于是就挂起了

把对话框style属性由child改成popup,，就ok了 WS_CHILD Creates a child window. A window with this style cannot have a menu bar. This style cannot be used with the WS_POPUP style.

谢谢,已经发给你了.

我也实在是无能为力了，楼主如果方便的话，把整个程序打包发给我，我有时间调试一下看看，1533846097@qq.com

case   WM_INITDIALOG :                                MessageBox(NULL,"WM_INITDIALOG 执行到了","提示",MB_OK);                                // return TRUE ; 	        return FALSE ;  改成  return FALSE ;  也一样.  对话框资源属性设置看不出有什么问题.  真是奇怪呀, 跟说明书上的例程对比,没发现什么差异,就是搞不正确,这个问题困扰我1~2两个月了.

case   WM_INITDIALOG :      MessageBox(NULL,"WM_INITDIALOG 执行到了","提示",MB_OK);              return TRUE ; 改成return FALSE;试试  楼主再看看对话框资源属性设置有没有问题

是的.  但是,我把MessageBox(NULL,"WM_INITDIALOG 执行到了","提示",MB_OK);  这句去掉, 也会死掉.

MessageBox(NULL,"WM_INITDIALOG 执行到了","提示",MB_OK); 这个提示框弹出来了？ 然后点ok就死了？

我觉得问题出在创建对话框上,  DialogBox(hInstance, (LPCTSTR)IDD_ABOUTBOX, hwnd,  (DLGPROC)AboutDlgProc) ;  但是这个函数也没有问题呀,

问题不在MessageBox函数上,因为这个函数是可以点OK 按钮的. 而且,改过了之后,问题仍在. 之前我说的,对话框界面不显示,只显示边框,这个也验证过了,有时有这个现象,有时没有,多数情况是可以显示界面的. 所以,程序死掉跟MessageBox函数没关系.

下面是改过的代码 :  #include <windows.h> #include "resource.h"     LRESULT  CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM) ; BOOL CALLBACK AboutDlgProc(HWND, UINT, WPARAM, LPARAM) ;           int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance,PSTR szCmdLine, int iCmdShow) //int main() {     /* 	HINSTANCE hInstance,hPrevInstance;         int iCmdShow;     	LPTSTR szCmdLine;          hInstance=GetModuleHandle(NULL);  //获取程序本身的实例句柄         iCmdShow=SW_SHOWNORMAL;//定义窗口显示模式         szCmdLine=GetCommandLine();//获取命令行字符串         hPrevInstance=NULL; //这个是历史遗留问题，一般程序用不到这个参数     */       static TCHAR szAppName[] = TEXT ("MENUDEMO") ;//TEXT ("About1") ;      MSG    msg ;      HWND   hwnd ; 	 HMENU  hmenu; //菜单创建方式二；       WNDCLASS  wndclass ;      wndclass.style= CS_HREDRAW | CS_VREDRAW ;      wndclass.lpfnWndProc= WndProc ;      wndclass.cbClsExtra= 0 ;      wndclass.cbWndExtra= 0 ;      wndclass.hInstance= hInstance ;      wndclass.hIcon= LoadIcon (hInstance, szAppName) ;      wndclass.hCursor= LoadCursor (NULL, IDC_ARROW) ;      //wndclass.hbrBackground= (HBRUSH) GetStockObject (WHITE_BRUSH) ; 	 wndclass.hbrBackground = (HBRUSH)GetSysColorBrush(COLOR_BTNFACE);      //wndclass.lpszMenuName= "IDR_MENU1"; //szAppName ; 	 //wndclass.lpszMenuName=MAKEINTRESOURCE(IDR_MENU1);  //菜单创建方式一；   	 wndclass.lpszMenuName=NULL;   //菜单创建方式二、三；      wndclass.lpszClassName= szAppName ;                   if (!RegisterClass (&wndclass))      {         MessageBox (NULL, TEXT ("This program requires Windows NT!"),         szAppName, MB_ICONERROR) ;         return 0 ;      }          	 //hmenu=LoadMenu(hInstance,MAKEINTRESOURCE(IDR_MENU1));  //菜单创建方式二； 	       hwnd = CreateWindow (szAppName, TEXT ("About Box Demo Program"),                           WS_OVERLAPPEDWINDOW,  						  CW_USEDEFAULT,  						  CW_USEDEFAULT,                           CW_USEDEFAULT,  						  CW_USEDEFAULT,                           NULL,  						  NULL, 						  //hmenu,  //菜单创建方式二； 						  hInstance, NULL) ;  	 hmenu=LoadMenu(hInstance,MAKEINTRESOURCE(IDR_MENU1));   //菜单创建方式三；      SetMenu(hwnd,hmenu);   //菜单创建方式三；        ShowWindow (hwnd, iCmdShow) ;       UpdateWindow (hwnd) ;       while (GetMessage (&msg, NULL, 0, 0))       {         TranslateMessage (&msg) ;         DispatchMessage (&msg) ;       }        	 return msg.wParam ; }        BOOL openDlg(HWND hwnd, TCHAR* fullPath, TCHAR* fileName)  {     static OPENFILENAME ofn;     static TCHAR szFilter[] = TEXT("Text Files(*.txt)\0*.txt\0All Files(*.*)\0*.*\0\0");     // 确定结构的大小      ofn.lStructSize = sizeof(OPENFILENAME);     // 指定它的父窗口      ofn.hwndOwner = hwnd;     // 一般为NULL，表示我们使用的是通用对话框      // ，当然我们也可以自定义对话框，此时hInstance指示      // 资源的handle。      ofn.hInstance = NULL;     // 指示打开或者保存文件时的过滤器，比如说：      // static TCHAR szFilter[] = TEXT("Text Files(*.txt)\0*.txt\0") \      //    TEXT("All Files(*.*)\0*.*\0\0");      // 结构是这样的:描述\0过滤\0, 最后一项必须是两个\0,      // 详情请参考MSDN。      ofn.lpstrFilter = szFilter;     // 一般为NULL      ofn.lpstrCustomFilter = NULL;     // 一般为0      ofn.nMaxCustFilter = 0;     // 指示默认过滤器为第几项      ofn.nFilterIndex = 0;     // 用于保存文件的完整路径及文件名      ofn.lpstrFile = fullPath;     // 指示上面结构的大小      ofn.nMaxFile = MAX_PATH;     // 用于保存文件名，不包括路径      ofn.lpstrFileTitle = fileName;     // 指示上面结构的大小      ofn.nMaxFileTitle = MAX_PATH;     // 指示打开对话框的第一路径，      // 我发现为NULL时，初始化路径总是      // “我的文档”。      ofn.lpstrInitialDir = NULL;     // 指示对话框的caption, 我们一般为NULL，      // 让系统指示， 当然也可以自己设置。      ofn.lpstrTitle = NULL;     // 这个东西在打开保存等有点不同，下面是为了打开而设置的      // 我们以后会看到保存时此项的设置。      ofn.Flags = OFN_HIDEREADONLY;     // 为0就可以了      ofn.nFileOffset = 0;     // 为0就可以了      ofn.nFileExtension = 0;     // 如果你保存的时候忘记加.txt时，      // 它会自动给你加上。      ofn.lpstrDefExt = TEXT("txt");     // 为0就可以了      ofn.lCustData = 0;     // 为NULL就可以了      ofn.lpfnHook = NULL;     // 如果想定制对话框， 下面的就不能为NULL了      // 但是我们一般为NULL。      ofn.lpTemplateName = NULL;      return GetOpenFileName(&ofn); 	//GetSaveFileName(&ofn);  //保存文件的函数； }   BOOL openReadFile(HWND hwnd, TCHAR* fullPath)  { 	     HANDLE hFile;     //PBYTE pBuffer;     int iFileLength;     DWORD dwByteRead;  	hFile = CreateFile(fullPath, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL);      if(hFile==INVALID_HANDLE_VALUE) 	{ 		MessageBox(NULL,"文件打开失败！","提示",MB_OK); 		CloseHandle(hFile); 		return FALSE; 	} 	else 	{        iFileLength = GetFileSize(hFile, NULL);        char *pBuffer = (char *)malloc(iFileLength + 2); 	   pBuffer[iFileLength] = pBuffer[iFileLength + 1] = '\0'; 	   //memset(pBuffer,'\0', iFileLength+1);        ReadFile(hFile, (void *)pBuffer, iFileLength, &dwByteRead, NULL);        CloseHandle(hFile);	           SetWindowText(hwnd, pBuffer);        free(pBuffer);        return TRUE; 	} 	 	 }        LRESULT CALLBACK WndProc (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) {    static HINSTANCE hInstance ;    //HANDLE hFile;     static HWND hEdit;     static TCHAR fullPath[MAX_PATH], fileName[MAX_PATH];    //TCHAR* pText;    static HWND hwndEdit;    //HWND hdlgbox;     switch (message)    {       case   WM_CREATE :              hInstance = ((LPCREATESTRUCT) lParam)->hInstance;             /* 			 hEdit = CreateWindowEx(WS_EX_CLIENTEDGE, TEXT("EDIT"), TEXT(""),  			                        WS_CHILDWINDOW|ES_MULTILINE|WS_VSCROLL,  									10, 10, 300, 200, 			                        hwnd, NULL, NULL, NULL); 		     ShowWindow(hEdit, SW_SHOW);      			 */ 			  			 hwndEdit = CreateWindow(TEXT("edit"),NULL,                                      WS_CHILD | WS_VISIBLE | ES_LEFT| WS_HSCROLL | WS_VSCROLL | ES_MULTILINE | ES_AUTOVSCROLL,                                      10, 10, 300, 300,                                      hwnd,                                      (HMENU)1,                                      (HINSTANCE)GetWindowLong(hwnd, GWL_HINSTANCE),                                      NULL);                return 0 ;        case   WM_COMMAND :              switch (LOWORD (wParam))              { 				 case IDM_FILE_NEW: 					 Beep(1000,500); 					 /* 					 hFile=CreateFile("D:\\资料\\计算机\\程序练习\\TEST\\3\\1.text", 						               GENERIC_READ | GENERIC_WRITE , FILE_SHARE_READ | FILE_SHARE_WRITE , 						               NULL, 						               CREATE_NEW, 						               FILE_FLAG_OVERLAPPED , 						               NULL); 					if(hFile==INVALID_HANDLE_VALUE) 					 { 						 MessageBox(NULL,"文件创建失败！","提示",MB_OK); 						 CloseHandle(hFile);  					 } 					else 					{ 					    ShellExecute(NULL,"open","notepad.exe",fullPath,NULL,SW_SHOWNORMAL); 					} 					*/ 					 ShellExecute(NULL,"open","notepad.exe",NULL,NULL,SW_SHOWNORMAL); 					return 0 ;  				 case IDM_FILE_Open: 					 /* 					  hFile=CreateFile("D:\\资料\\计算机\\程序练习\\TEST\\3\\1.text", 						                GENERIC_READ | GENERIC_WRITE , FILE_SHARE_READ | FILE_SHARE_WRITE , 						                NULL, 						                OPEN_EXISTING, 						                FILE_FLAG_OVERLAPPED, 						                NULL); 					 if(hFile==INVALID_HANDLE_VALUE) 					 { 						 MessageBox(NULL,"文件打开失败！","提示",MB_OK); 						 CloseHandle(hFile);  					 } 					 */ 					  					 if(!openDlg(hwnd, fullPath, fileName))  					 {                          MessageBox(NULL, TEXT("can not open file."),TEXT("Error"), MB_ICONERROR);                          fullPath[0] = '\0';                          fileName[0] = '\0';                          return 0; 					 } 					  					 /*                      if(!openReadFile(hwndEdit, fullPath))  					 {                          MessageBox(NULL, TEXT("error read file."),TEXT("Error"), MB_ICONERROR);                          fullPath[0] = '\0';                          fileName[0] = '\0';                          return 0; 					 } 					 */ 					 ShellExecute(NULL,"open","notepad.exe",fullPath,NULL,SW_SHOWNORMAL); 					 //PathStripPath(fullPath);  //得到文件名					   					 					 return 0 ;  				                case IDM_APP_ABOUT :   //IDD_AboutBox:   				  MessageBox(NULL,"DialogBox()执行到了","提示",MB_OK);                    //DialogBox (hInstance, TEXT ("IDD_AboutBox"), hwnd, (DLGPROC)AboutDlgProc) ;  				  DialogBox(hInstance, (LPCTSTR)IDD_ABOUTBOX, hwnd,  (DLGPROC)AboutDlgProc) ; 				   //DialogBox (hInstance, MAKEINTRESOURCE(IDD_AboutBox), hwnd, (DLGPROC)AboutDlgProc) ;  				   //hdlgbox=CreateDialog(hInstance, MAKEINTRESOURCE(IDD_AboutBox), hwnd, AboutDlgProc); 				   //ShowWindow(hdlgbox, SW_SHOW ); 				   //InvalidateRect (hwnd, NULL, TRUE) ;  				   //DialogBoxParam(hInstance, MAKEINTRESOURCE(IDD_ABOUTBOX), hwnd, (DLGPROC)AboutDlgProc,NULL) ;  				   //MessageBox(NULL,"DialogBox()执行到了","提示",MB_OK);                    break ; 				                 }              return 0 ;  	  /* 	  case WM_PAINT:           hdc = BeginPaint (hwnd, &ps) ;                      GetClientRect (hwnd, &rect) ;                      DrawText (hdc, TEXT ("Hello, Windows XP!"), -1, &rect,                     DT_SINGLELINE | DT_CENTER | DT_VCENTER) ;                      EndPaint (hwnd, &ps) ;        return 0 ; 	   */        case   WM_DESTROY :              PostQuitMessage (0) ; 			 //MessageBox(NULL,"PostQuitMessage (0)执行到了","提示",MB_OK);              return 0 ;    }    return DefWindowProc (hwnd, message, wParam, lParam) ; }   BOOL CALLBACK AboutDlgProc(HWND hDlg, UINT message,WPARAM wParam, LPARAM lParam) {    switch (message)    {       case   WM_INITDIALOG : 		     MessageBox(NULL,"WM_INITDIALOG 执行到了","提示",MB_OK);              return TRUE ;       case   WM_COMMAND :              switch (LOWORD (wParam))              {                 case   IDOK :                 case   IDCANCEL : 					    MessageBox(NULL,"IDOK/IDCANCEL执行到了","提示",MB_OK);                         EndDialog (hDlg, 0) ;                         return TRUE ;              }              break ;    }    return FALSE ; }


Question: 大家来看看 谭浩强 的代码有没有问题

看了这么久，我想问谁是谭浩强？

引用 24 楼 cjqpker 的回复:谭浩强的C带领多少人进入C程序的世界，......  我敢肯定，我的C语言课本不是谭浩强的， 我是这两年才听说这个人的

403 Forbidden

引用 32 楼 bear234 的回复:while (/* …… */)         if (/* …… */) break;         else continue; 你的意思是不是这个while语句等效于     while (/* …… */)         if (/* …… */) break; ok   看来确实是书错了   [/quote] 你认识 if else 却不认识 do while ...... 我和鼠侠的例子 其实是没什么区别的

引用 31 楼 bear234 的回复:1) 二元运算符 和 一元运算符    是在“算术运算符”的概念里的。换句话说，如果说某个运算符是一元还是二元，那么它一定是算数运算符，而不是关系运算符，也不是赋值运算符。 2）先声明了就能使用了？声明了，只是编译器认识了而已，并不一定就能使用。这里是在谈使用，不是在区分声明和定义的区别。至于你的例子，只能说你在玩文字游戏了，“先定义”中的“先”，是告诉你你在使用时，要保证其已经被定义过。而不是代码行上的先后顺序。 3）while语句和do while语句都分不清，你在逗我吗？  至于变长数组   我回复了  确实是书写错了  你弄错了 一元二元三元 说的只是 这个运算符 和 多少个操作数结合 比如说 一元运算符  -  他只会和1个操作数结合 -a  全部意思仅此而已 请不要随意加什么算术运算符这样的限制  再举一个例子整个C语言中唯一一个 三元运算符 ?: 三元的意思也仅仅是说 整个运算符有三个操作数  而且 这个运算符 也不是你所谓的算术运算符 对吧  再贴一张图   你看这张图里面 标记二元运算符的还有  > 大于 < 小于 >= 大于等于 <= 小于等于 并不是你所说的 只有"算术运算符" 才有一元二元的

实践是检验真理的唯一标准

引用 20 楼 lin5161678 的回复:[quote=引用 15 楼 bear234 的回复:] 有不能和赋值运算符组合成复合运算符的二元运算符？ && 运算符是不是二元运算符  || 运算符是不是二元运算符  += 运算符是不是二元运算符 (不错 这个说法已经造成递归 错得离谱) 引用 15 楼 bear234 的回复:先定义，后使用 ----- 定义是对声明的实现或者实例化。连接器(linker)需要它（定义）来引用内存实体。所以定义只能有一次。 所以这句话有什么问题？ 这句话的问题是 正确的说法应该是 先声明再使用 void foo() { 	extern int x; 	printf("%d", x);//这里已经可以使用 x 但是x并没有定义  } int x = 99;//x直到这里才定义  别告诉我 你不清楚声明和定义的区别 引用 15 楼 bear234 的回复:C的实数常量都是双精度型”，接着在后面提到“添加f来强制指定类型" SomeType d = 1.23; //1.23是双精度   如果要用float  请写成1.23f    我是这么理解这句话的，有错？ 你怎么理解这句话和这句话对不对毫无关系  这句话说 实型常量都是双精度  但是 存在一个这样的实型常量1.23f 并不是不是double 而是float 那么这句话毫无疑问是错的  引用 15 楼 bear234 的回复:循环体如果包含一个以上的语句，应该用花括号括起来，以复合语句形式出现。如果不加花括号，则while语句的范围只到while后面第一个分号处。 请问这句话哪里有错 	while(1) 		do 			x = 99;//第一个分号到了 问题是 这个循环体是在第二个分号才结束   		while(0);   如此漏洞百出的描述 你都看不出哪里错  只能说明 谭C误导得挺成功的 引用 15 楼 bear234 的回复:int a[n]: C99 允许变长数组  之前的标准不允许   这里有什么问题？ 有什么问题我已经在前面说明过了 但是你好像选择性失明 现在我加大加粗标红 请看清楚 不要再问出别人早就回答过的问题  问题就是 谭C第四版号称支持C99 问题就是谭C第四版讲解的是就是C99   排版错了 重新发一次 上一楼作废 抱歉[/quote]   好吧  我并没有什么主观意思  谭浩强的书我没看过    我只是想知道为什么大家总说他错误很多.....

引用 22 楼 sholber 的回复:[quote=引用 15 楼 bear234 的回复:] [quote=引用 10 楼 lin5161678 的回复:] [quote=引用 9 楼 bear234 的回复:] [quote=引用 7 楼 love1code 的回复:] 这个问题讨论无意义。 时代不同，而且谭书错误多是公认的。  求你给我说出两个这本书里的错误来[/quote] 引用* “凡是二元运算符都可以与赋值符组合成复合赋值符”。 错的 引用* “先定义，后使用”。 错的 引用* “C的实数常量都是双精度型”，接着在后面提到“添加f来强制指定类型”。 谭C自己打脸了 引用* “while语句的范围只到while后的第一个分号处”。 错的 引用* “int a[n];是不合法的”。 int a[n]在C99是合法的 而谭C第四版号称里面的内容是介绍C99   还要么?[/quote]   循环体如果包含一个以上的语句，应该用花括号括起来，以复合语句形式出现。如果不加花括号，则while语句的范围只到while后面第一个分号处。 请问这句话哪里有错  [/quote] 最近不常来CSDN，既然今天赶上了，也来说两句，单说这个while语句。 我没看过谭书，不知道你这段话是自己穿靴戴帽加上的，还是谭果真是这么写的。但无论如何，都是错的。请看： while (/* …… */)         if (/* …… */) break;         else continue; 你的意思是不是这个while语句等效于     while (/* …… */)         if (/* …… */) break;[/quote]   ok   看来确实是书错了

引用 18 楼 lin5161678 的回复:[quote=引用 15 楼 bear234 的回复:] 有不能和赋值运算符组合成复合运算符的二元运算符？ && 运算符是不是二元运算符  || 运算符是不是二元运算符  += 运算符是不是二元运算符 (不错 这个说法已经造成递归 错得离谱) 引用 15 楼 bear234 的回复:先定义，后使用 ----- 定义是对声明的实现或者实例化。连接器(linker)需要它（定义）来引用内存实体。所以定义只能有一次。 所以这句话有什么问题？ 这句话的问题是 正确的说法应该是 先声明再使用 void foo() { 	extern int x; 	printf("%d", x);//这里已经可以使用 x 但是x并没有定义  } int x = 99;//x直到这里才定义  别告诉我 你不清楚声明和定义的区别 引用 15 楼 bear234 的回复:C的实数常量都是双精度型”，接着在后面提到“添加f来强制指定类型" SomeType d = 1.23; //1.23是双精度   如果要用float  请写成1.23f    我是这么理解这句话的，有错？ [/code] 你怎么理解这句话和这句话对不对毫无关系  这句话说 实型常量都是双精度  但是 存在一个这样的实型常量1.23f 并不是不是double 而是float 那么这句话毫无疑问是错的  [quote=引用 15 楼 bear234 的回复:] 循环体如果包含一个以上的语句，应该用花括号括起来，以复合语句形式出现。如果不加花括号，则while语句的范围只到while后面第一个分号处。 请问这句话哪里有错 	while(1) 		do 			x = 99;//第一个分号到了 问题是 这个循环体是在第二个分号才结束   		while(0);   如此漏洞百出的描述 你都看不出哪里错  只能说明 谭C误导得挺成功的 引用 15 楼 bear234 的回复:int a[n]: C99 允许变长数组  之前的标准不允许   这里有什么问题？ 有什么问题我已经在前面说明过了 但是你好像选择性失明 现在我加大加粗标红 请看清楚 不要再问出别人早就回答过的问题 显得自己笨 问题就是 谭C第四版号称支持C99 问题就是谭C第四版讲解的是就是C99 [/quote]   1) 二元运算符 和 一元运算符    是在“算术运算符”的概念里的。换句话说，如果说某个运算符是一元还是二元，那么它一定是算数运算符，而不是关系运算符，也不是赋值运算符。 2）先声明了就能使用了？声明了，只是编译器认识了而已，并不一定就能使用。这里是在谈使用，不是在区分声明和定义的区别。至于你的例子，只能说你在玩文字游戏了，“先定义”中的“先”，是告诉你你在使用时，要保证其已经被定义过。而不是代码行上的先后顺序。 3）while语句和do while语句都分不清，你在逗我吗？  至于变长数组   我回复了  确实是书写错了

&&= 和  ||= 曾经也是可以的，现在的编译器 和 标准没看过，不清楚可以不

引用 2 楼 K8001 的回复:[quote=引用 1 楼 fly_dragon_fly 的回复:] 有兴趣讨论可以贴下代码, 图片就不想看了  上面有谭的文字,这样对代码的作者有一点证明力  我不贴代码是想大家用自己对C的理解去审视这段代码,而不是复制下来一运行说是对是错. [/quote]代码不长,看了一下, 老谭的代码应该在TC下用的,可能当时没什么问题(记不清了), 其实差一个const, 反正我记得第一次使用const是在c++而不是c, 版本b应该是const char *a="", 这样就很清楚,a内容不可改变, 对const的内容改变, 标准应该是未定义吧

引用 24 楼 cjqpker 的回复:谭浩强的C带领多少人进入C程序的世界，其对我国程序的贡献不是几个“错误”或者几句贬损的话就能抹消的。 5、“int a[n]”，至于这个问题，至少我用VS2010编译，仍然不支持该特性；不过gcc已经支持了。但广大初学者，应该多数使用VS系列来学习C语言吧（不排除少数人使用gcc）。对于这样一个很多编译器不支持的特性，标注为“非法”从教学的意义上，并无大碍，当然我承认谭老师可能在此处出了错。不过，至今为止，我读过的代码中，从来没见过使用这个特性的，即使有人问我，我也会告诉他，不！要！用！，不！准！用！。虽然从编译或标准的角度上可以让C实现这样或者那样的目前不支持的功能，但对一个C程序员来说，定义一个运行时确定长度地数组，会带来很多不可预测的问题。如果非要用，你去malloc，不差这几行代码。  什么是不可预测的问题，使用VLA为什么会带来不可预测的问题？说来我听听。

引用 24 楼 cjqpker 的回复:谭浩强的C带领多少人进入C程序的世界，其对我国程序的贡献不是几个“错误”或者几句贬损的话就能抹消的。 看了@lin5161678 指出的对@bear234 朋友评论的反驳，实在看不下去，以下稍作见解。 1、&&和|| 属于逻辑运算符，本来就不是用来计算，而是用来控制，因其恰好在C中可以产生1或0的结果，而在此讨论“与赋值运算符结合”的问题，本身就有问题。可见这位朋友对“运算”的理解。 2、“先定义，后使用”，这句话在编译器层面上，我认同@bear234 朋友的意见，声明给别人使用，定义以供链接；至于先定义后使用从代码角度上来说，由于未知这句话所出的上下文，暂不做猜测。至于“//这里已经可以使用 x 但是x并没有定义 ”这句话，根本不成立，在使用之前必定要定义，只不过不一定要在此处定义，引此例简直…… 3、“C的实数常量都是双精度型”，竟然说出了“存在一个这样的实型常量1.23f” 这样的话，1.23f只不过告诉编译器，用float来理解这个变量。如果按照lin5161678的说法，那（1.23+5.67f）岂不是也是一个“实型常量”？ 4、“while语句的范围只到while后面第一个分号处”，这里的“第一个分号”表达的是“第一个语句”的意思；另外，不管加不加大括号，do while都已经是一个复合语句，lin5161678 脱离语言，从文字上挑毛病，实在不该。这里我在给你举一个例子：  while(1)     printf(";;;;;;;");  //哇，好多分号！  5、“int a[n]”，至于这个问题，至少我用VS2010编译，仍然不支持该特性；不过gcc已经支持了。但广大初学者，应该多数使用VS系列来学习C语言吧（不排除少数人使用gcc）。对于这样一个很多编译器不支持的特性，标注为“非法”从教学的意义上，并无大碍，当然我承认谭老师可能在此处出了错。不过，至今为止，我读过的代码中，从来没见过使用这个特性的，即使有人问我，我也会告诉他，不！要！用！，不！准！用！。虽然从编译或标准的角度上可以让C实现这样或者那样的目前不支持的功能，但对一个C程序员来说，定义一个运行时确定长度地数组，会带来很多不可预测的问题。如果非要用，你去malloc，不差这几行代码。  233 看得出来，你应该是学谭浩强的书掌握了C。 顺便说一下，翻遍C标准，也不见“运算”的定义，那你认为什么是运算呢？运算仅仅是加减乘除左移右移？不敢苟同。

引用 24 楼 cjqpker 的回复:至于“//这里已经可以使用 x 但是x并没有定义 ”这句话，根本不成立，在使用之前必定要定义，只不过不一定要在此处定义，引此例简直…… 这里你好像分不清 编译期 和 运行期  按照你的说法 哪怕 int x = 99; 写在这个位置 也是先定义  那么我另外再举一个例子好了  #include <stdbool.h>  int main() { 	printf("%d\n", x); 	return 0; } int x = 99;  x "先定义"了 但是这段代码无法通过编译   我说清楚了吗  假如 谭C的说法是正确的 那么第一段代码中的变量x 是有先定义 那么第二段代码中的变量x 一样是有先定义 但是 第一段代码是正常的 第二段代码却是错误的 于是 谭C的说法是错误的

以上发个代码，证明朕来过了。嘎嘎~~

# include <stdio.h>  struct t {char c; float f;} f (struct t t) {     printf ("%c,%f", t.c, t.f);     return t; }  int main (void) {     f ((struct t) {'x', 0.01}); }

引用 24 楼 cjqpker 的回复:谭浩强的C带领多少人进入C程序的世界，其对我国程序的贡献不是几个“错误”或者几句贬损的话就能抹消的。 看了@lin5161678 指出的对@bear234 朋友评论的反驳，实在看不下去，以下稍作见解。 1、&&和|| 属于逻辑运算符，本来就不是用来计算，而是用来控制，因其恰好在C中可以产生1或0的结果，而在此讨论“与赋值运算符结合”的问题，本身就有问题。可见这位朋友对“运算”的理解。 2、“先定义，后使用”，这句话在编译器层面上，我认同@bear234 朋友的意见，声明给别人使用，定义以供链接；至于先定义后使用从代码角度上来说，由于未知这句话所出的上下文，暂不做猜测。至于“//这里已经可以使用 x 但是x并没有定义 ”这句话，根本不成立，在使用之前必定要定义，只不过不一定要在此处定义，引此例简直…… 3、“C的实数常量都是双精度型”，竟然说出了“存在一个这样的实型常量1.23f” 这样的话，1.23f只不过告诉编译器，用float来理解这个变量。如果按照lin5161678的说法，那（1.23+5.67f）岂不是也是一个“实型常量”？ 4、“while语句的范围只到while后面第一个分号处”，这里的“第一个分号”表达的是“第一个语句”的意思；另外，不管加不加大括号，do while都已经是一个复合语句，lin5161678 脱离语言，从文字上挑毛病，实在不该。这里我在给你举一个例子：  while(1)     printf(";;;;;;;");  //哇，好多分号！  5、“int a[n]”，至于这个问题，至少我用VS2010编译，仍然不支持该特性；不过gcc已经支持了。但广大初学者，应该多数使用VS系列来学习C语言吧（不排除少数人使用gcc）。对于这样一个很多编译器不支持的特性，标注为“非法”从教学的意义上，并无大碍，当然我承认谭老师可能在此处出了错。不过，至今为止，我读过的代码中，从来没见过使用这个特性的，即使有人问我，我也会告诉他，不！要！用！，不！准！用！。虽然从编译或标准的角度上可以让C实现这样或者那样的目前不支持的功能，但对一个C程序员来说，定义一个运行时确定长度地数组，会带来很多不可预测的问题。如果非要用，你去malloc，不差这几行代码。 他做了什么贡献和他的书是不是写错了 毫无关系  我没有一个字是在评价关于谭浩强做出了什么贡献  请看清楚 我只描述 谭C的书中出现的错误之处 请问 是不是因为他有贡献 所以我们不可以说他写错了? 你对运算的理解太过于片面 为了照顾你的理解  我这样说吧 += 这个运算符就是你所谓的用来计算的 += 这个运算符是二元运算符  但是 并不能和 =符号组合成为 +== ? 所以谭C这个断言是错误的   你好像连什么是实数常量都不懂  按照C语言标准文档的描述  12.3f 这个完全符合实数常量的语法定义  请不要信口开河 对于不了解的东西 不要不懂装懂  既然是第一个语句的意思 为什么不老老实实的说清楚是第一个语句 为什么要使用 "第一个分号" 这种漏洞百出的说法 既然使用了漏洞百出的说法 被我看出漏洞 怪我咯? do while 并不是复合语句 复合语句说的是 {} 我发现你对C的理解极其片面 有许多都是基于自己的想象  这很不好 请多看一些靠谱的书 和 文档 比如 C99标准文档(你喜欢看C89标准文档也行)  最后的关于 VLA的问题 是的 请大声的说  请! 不! 要! 使! 用! 不! 准! 使! 用! 这种有用的建议请千万不要吝啬 请多多的告诉新手  但是 不好用的特性不能说成是错误的语法 书既然是在介绍C99  那么就应该按照C99的说法说清楚  这个做法是合乎语法的 但是由于原因123 建议不要使用 我说清楚了吗  我说的是 你的合理建议并不能为谭C的错误洗地 谭C说VLA是错的 这句话是的的确确是错的 毋庸置疑

引用 15 楼 bear234 的回复:[quote=引用 10 楼 lin5161678 的回复:] [quote=引用 9 楼 bear234 的回复:] [quote=引用 7 楼 love1code 的回复:] 这个问题讨论无意义。 时代不同，而且谭书错误多是公认的。  求你给我说出两个这本书里的错误来[/quote] 引用* “凡是二元运算符都可以与赋值符组合成复合赋值符”。 错的 引用* “先定义，后使用”。 错的 引用* “C的实数常量都是双精度型”，接着在后面提到“添加f来强制指定类型”。 谭C自己打脸了 引用* “while语句的范围只到while后的第一个分号处”。 错的 引用* “int a[n];是不合法的”。 int a[n]在C99是合法的 而谭C第四版号称里面的内容是介绍C99   还要么?[/quote]   C的实数常量都是双精度型”，接着在后面提到“添加f来强制指定类型" SomeType d = 1.23; //1.23是双精度   如果要用float  请写成1.23f    我是这么理解这句话的，有错？ [/quote]  我们不用“实数常量”这个术语，但如果你要用，我们不反对，但我们有一个问题：C中的实数包括整数类型和实浮点类型，难不成整型常量也是双精度型 ？

引用 15 楼 bear234 的回复:[quote=引用 10 楼 lin5161678 的回复:] [quote=引用 9 楼 bear234 的回复:] [quote=引用 7 楼 love1code 的回复:] 这个问题讨论无意义。 时代不同，而且谭书错误多是公认的。  求你给我说出两个这本书里的错误来[/quote] 引用* “凡是二元运算符都可以与赋值符组合成复合赋值符”。 错的 引用* “先定义，后使用”。 错的 引用* “C的实数常量都是双精度型”，接着在后面提到“添加f来强制指定类型”。 谭C自己打脸了 引用* “while语句的范围只到while后的第一个分号处”。 错的 引用* “int a[n];是不合法的”。 int a[n]在C99是合法的 而谭C第四版号称里面的内容是介绍C99   还要么?[/quote]   循环体如果包含一个以上的语句，应该用花括号括起来，以复合语句形式出现。如果不加花括号，则while语句的范围只到while后面第一个分号处。 请问这句话哪里有错  [/quote] 最近不常来CSDN，既然今天赶上了，也来说两句，单说这个while语句。 我没看过谭书，不知道你这段话是自己穿靴戴帽加上的，还是谭果真是这么写的。但无论如何，都是错的。请看： while (/* …… */)         if (/* …… */) break;         else continue; 你的意思是不是这个while语句等效于     while (/* …… */)         if (/* …… */) break;


Question: #DEFINE与typedef

typedef是直接定义类型，而#define只是直接替换你所定义的字符串内容，没有类型可言。所以用到#define的时候一定要注意它所在位置被替换成目标字符串后，是否存在判断优先级的问题。

引用 9 楼 sholber 的回复:typedef int * A; const A a; 初看起来，标识符a的类型const int *，因为以上第二行似乎等效于 const int * a; 事实上，这是错的。你应当这样来解读：a的类型是const A，而A是一个指针类型的别名。所以，a的类型是const指针，即 int * const a;+1

VC编译选项加/EP /P，重新编译，查看宏展开后对应的.i文件。gcc加-E http://bbs.csdn.net/topics/391003898

const a p;// int * const p;  const b p;// int const *p;

引用 5 楼 ant2012 的回复:const int  （*p）;和（const int*） p;是一个意思啊 typedef 和 #define 区别在于：前者是自定义类型，后者是简单替换。 typedef int* a; #define b int*  const a p; const b p;  这两句效果是等价的  但如果是 const a p1, p2;    // 相当于 const int *p1, *p2; contst b p1, p2;   // 相当于 const int *p1, p2; 就不一样了 前者p1, p2都是指向整型常量的指针，即值不能更改 后者p1是指向整型常量的指针， p2是int整型  不对吧。兄弟。 看代码。 # include<stdio.h> typedef int* a; # define b int* int main (void) { 	 	int x = 1; 	const a p1=&x;    //         const  作用于 p1  	const b p2=&x;   //宏展开后：const int* p2=&x,const 作用于*p2  	 	(*p1)--; 	(*p2)--;    //error 	 	 	return 0; }

先看一个问题: const int p=1;      它等价于:int cosnt p=1  //其实后者才是最符合逻辑的，const 修饰p而不是int，但是人们习惯前者这样写。 int a = 1; cosnt int * p =&a;  //你认为const修饰哪个呢？用下面的代码做实验： # include <stdio.h> int main (void) { 	 	int a = 1; 	const int *p=&a; 	 	(*p)--;  //测试点1，如果这句有问题，说明cosnt修饰 *p  	 	p=NULL;  //测试点2，如果这句有问退，说明cosnt修饰 p  	 	return 0; }  问题： 大家写的时候都喜欢cosnt打头，到底cosnt修饰谁？ 有一个规律已经可以看出来了：cosnt 跳过一个最简单的类型符号，修饰后面的部分。 什么意思呢？ const int p=1;      cosnt 跳过int    于是写成  : int cosnt p=1  ，结论：cosnt 修饰p const int *p=&a;  cosnt 跳过int  (int 比int*简单，所以跳过int而不是int*)  于是写成  ：int cosnt*p=&a，结论：cosnt 修饰*p 类推。 现在再引入typedef  和 # define 。 这个是老话题了。typedef 是给一个已经存在的类型取别名，而define 仅仅是代码字面上的替换（编译第一阶段预处理是进行） typedef int* a    //a就是int*型的别名,一旦形成，它是固定的，不可分拆，就是说a就是一个简单类型 再来看：  const a p     cosnt跳过类型a    写成------>a const p ,很明了 而define呢？自己先宏替换，再按那个思路，就好了。

#define的作用是直接替换，C++中有type这种用法吗？我只知道type用在模板类中

typedef int        *PTR_T; typedef const int  *PTR_CONST_T; typedef const PTR_T CONST_PTR_T;  #define PTR_D       int * #define PTR_CONST_D const int * #define CONST_PTR_D int * const  // 等价 const PTR_T p;      // <==> const int *p; const PTR_D p;      // <==> const int *p;  // 等价(同上) PTR_CONST_T p;      // <==> const int *p; PTR_CONST_D p;      // <==> const int *p;  // 等价 CONST_PTR_T p;      // <==> int *const p; CONST_PTR_D p;      // <==> int *const p;  // 不等价 const PTR_T p1, p2; // <==> const int *p1, *p2;                     //      const int *p1; <==> const int (*p1); <==> int const (*p1);                     //      const int *p2; <==> const int (*p2); <==> int const (*p2); const PTR_D p1, p2; // <==> const int *p1, p2;                     //      const int *p1; <==> const int (*p1); <==> int const (*p1);                     //      const int p2; // 不等价(同上) PTR_CONST_T p1, p2; // <==> const int *p1, *p2;                     //      const int *p1; <==> const int (*p1); <==> int const (*p1);                     //      const int *p2; <==> const int (*p2); <==> int const (*p2); PTR_CONST_D p1, p2; // <==> const int *p1, p2;                     //      const int *p1; <==> const int (*p1); <==> int const (*p1);                     //      const int p2; // 不等价 CONST_PTR_T p1, p2; // <==> int *const p1, *const p2;                     //      int *const p1; <==> int (*const p1);                     //      int *const p2; <==> int (*const p2); CONST_PTR_D p1, p2; // <==> int *const p1, p2;                     //      int *const p1; <==> int (*const p1);                     //      int p2;

没写完，const b p;// 是否可以理解为 const int  （*p）;


Question: 大神，关于枚举的问题

a是对象，能取里面的任何值。关键是你要给他赋值啊

没有初始化的话，编译都出错，int a=sun ,a的值就是0;

没有初始化，不确定。 可以随后赋值，如： a = mon;


Question: 小白求教学，关于图的深度优先遍历问题

深度、广度遍历都是有编程框架可循的。 你代码除了问题，那就要自己调试了

没有试过单步调试吗？打印输出一下，看看哪里有问题。 大篇幅的代码贴上来后应该有一些自己的分析


Question: 字符串指针赋值出错

代码本身没问题，问题可能在于你的 a不是合法的，由于不知楼主是怎么调用这函数的，所以说不清原因

还有传参数不能传在静态常量区的数据，例如： char *p = "nihao";//这个是在静态常量区 char p[6] = "nihao";//这样子就不会出错了

void q2swap(char *a, char *b) {     if(a[0]=='9') printf("==9\n");     //读没有问题     a[0]='8';             //写就出问题了,运行报错,系统甚至崩溃     为什么?                     char *t;      ×t=×a;×a=×b;×b=×t;           //不改变任何东西, 为什么? }  这样试一试呢

引用 7 楼 ant2012 的回复:楼主确定为a开辟内存了？  我猜测、估计是没有，值声明了！

得看传给形参的值的类型

引用 15 楼 K8001 的回复:[quote=引用 14 楼 cfjtaishan 的回复:] 函数：q2swap的第一个参数可能是只读的，你可以把你传递给q2swap函数的实参拿出来~主要看实参是不是只读的。  void q2() { 	char *p1="9Compiling..."; 	char *p2="6Linking..."; 	char *p3="20 errors(s), 0 warning(s)...";  	q2swap(p1,p2);  	printf("Q2.String from small to big:\n%s\n%s\n%s\n",p1,p2,p3); } [/quote] 真是只读的，那不是字符串常量嘛，只可以读，不可以写的，即不可以修改~解决办法是申请空间，不论是栈上的，还是堆上的都可以，把字符串拷贝到新申请的空间里

先来看这句话：“读没有问题，写就报错了”。 原因：字符串本身在静态区，而不是栈里。静态区一般是不允许改写的。 如： int *p="ABC";        p[0]='1'     //error  ,静态区数据可读不可写。 避免以上问题，把字符串定义在栈里就OK了。     char s[]="ABC";  第二个问题。/ 说明你还没理解指针有什么用，c语言函数的值传参本质。 记住：C语言实参传递给形参都是按值传递的。 # include <stdio.h> void q2swap(char *a, char *b); int main (void) { 	 	char s1[]="123"; 	char s2[]="ABC"; 	 	q2swap(s1,s2); //调用  	 	 	return 0; }    void q2swap(char *a, char *b) {     if(a[0]=='9') printf("==9\n");     //读没有问题     a[0]='8';             //写就出问题了,运行报错,系统甚至崩溃     为什么?                     char *t;      t=a;a=b;b=t;           //不改变任何东西, 为什么? } 我么看分析内存上发生了什么事（这个很重要）  也就是说，你在函数内操作的指针和原来的字符串的指针是不同的对象。只不过他们的值相等而已。

当函数的参数为指针时，如果不能保证指针的指向有效，则所有的一切都没有意义。

你只是改变存放变量的地址，但是指向的内容没变啦

a指向的内存区域是只读的。

引用 14 楼 cfjtaishan 的回复:函数：q2swap的第一个参数可能是只读的，你可以把你传递给q2swap函数的实参拿出来~主要看实参是不是只读的。  void q2() { 	char *p1="9Compiling..."; 	char *p2="6Linking..."; 	char *p3="20 errors(s), 0 warning(s)...";  	q2swap(p1,p2);  	printf("Q2.String from small to big:\n%s\n%s\n%s\n",p1,p2,p3); }

并不是指针本身，而是指针指向的内容是否可以修改  引用 5 楼 K8001 的回复:[quote=引用 1 楼 FightForProgrammer 的回复:] a指向的内存区域是只读的。  谭浩强书上有如下的代码:  void copy_string(char *from ,char *to ) {    for(;*from!='\0';from++,to++)                    *to = * from;     *to='\0'; }   这么看是可以赋值的啊[/quote]

引用 11 楼 zhao4zhong1 的回复:[quote=引用 3 楼 sholber 的回复:] [quote=引用 2 楼 zhao4zhong1 的回复:] #pragma comment(linker,"/SECTION:.rdata,RW") //加这句可以让常量区可写，后果自负！   不是C语言内的东西，拿出来宣扬只能被认为是诲盗诲淫。[/quote] link不是c语言写的？[/quote]  有可能不是。

引用 3 楼 sholber 的回复:[quote=引用 2 楼 zhao4zhong1 的回复:] #pragma comment(linker,"/SECTION:.rdata,RW") //加这句可以让常量区可写，后果自负！   不是C语言内的东西，拿出来宣扬只能被认为是诲盗诲淫。[/quote] link不是c语言写的？

仅供参考：#include <stdio.h> #define SWAP(a,b) do ((&(a))!=(&(b)))?((a)^=(b)^=(a)^=(b)):((a)=(a)); while (0) char   *p1="1" ,*p2="2" ; char    c1=1   , c2=2   ; short   s1=1   , s2=2   ; int     i1=1   , i2=2   ; __int64 I1=1i64, I2=2i64; float   f1=1.0f, f2=2.0f; double  d1=1.0 , d2=2.0 ; void main() {     SWAP((int)p1,(int)p2);                printf("char *     %5s,   %5s\n",p1,p2);     SWAP(c1,c2);                          printf("char       %5d,   %5d\n",c1,c2);     SWAP(s1,s2);                          printf("short      %5d,   %5d\n",s1,s2);     SWAP(i1,i2);                          printf("int        %5d,   %5d\n",i1,i2);     SWAP(I1,I2);                          printf("__int64 %5I64d,%5I64d\n",I1,I2);     SWAP(*(int     *)&f1,*(int     *)&f2);printf("float      %5g,   %5g\n",f1,f2);     SWAP(*(__int64 *)&d1,*(__int64 *)&d2);printf("double    %5lg,  %5lg\n",d1,d2);      SWAP(c1,c1);     printf("%d\n",c1); } //char *         2,       1 //char           2,       1 //short          2,       1 //int            2,       1 //__int64     2,    1 //float          2,       1 //double        2,      1 //2

引用 8 楼 wang0635 的回复:传给形参a的实参应该是数组名 而不是一个指针，简单地把一个字符串首地址赋值给他（就像谭浩强那样）

传给形参a的实参应该是数组名

楼主确定为a开辟内存了？


Question: 关于字符变量定义问题，求解！

原因是，char被当作一种整型对待，只是长度只有 一个字节 四个字节 ，32Bits 系统中，可以表示 一个 整型int 类型的数据。 这些编译器，允许单引号内的多个字符，当作整型int 常量用。 估计主要原因还是，多字节字符，unicode字符的出现，字符不再仅仅用一个字节了。 这样，只允许一个字节的话，多于一个字节的字符，可能就不能一下子表示出来了。

带毛笔，呵呵

早期的编译器，不支持非转义字符多字符 char 常量 后来的某些 编译器支持了，标准就不清楚了

printf("%d\n", sizeof('a')); //结果是4    C里面字符常量按4个字节存储  char a = 'abcd'; //这样赋值没问题 char a = 'abcde'; //超过4个 编译器就报错了

谢谢各楼的解答，继续努力！

引用 6 楼 zhao4zhong1 的回复:编译器的自定义行为和不可预知行为多如牛毛。  同学：“老师让明天去学校时带钢笔。” 小明：“带毛笔！” A.小明打算带毛笔去学校 B.小明不打算带任何笔去学校 C.小明没钢笔 D.小明有毛笔  可见，人脑这个编译器的自定义行为和不可预知行为也多如牛毛！

编译器对未知行为的不确定

这个是未定义问题，标准并未作出强制的要求。 一般编译器系统会给出警告或错误提示。  下面是两种常见的处理方式： 1.cl (windows常用C前端),忽略前面的所有字符,运算结果为最后一个字符 ex: char a = "asdf";     //a的值为'f'  2.ccl (gcc处理C的前端)取第一个有效字符 ex: char a = "asdf";     //a的值为'a'  上述并不是所有编译器处理的绝对情况，请以实验为主 希望能帮助到你

定义的是一个字节，你abcd有四个字节，会发生截取；

为什么呢？我用的VC编写的，没有出现警告与错误啊

只是警告： D:\Project\CTest\main.cpp:5: warning: multi-character character constant [-Wmultichar]      char a='abcd';             ^


Question: 求解ashmem-dev.c:21:1: error: expected ';', ',' or ')' before '{' token

没看出来那里有错, 可能那个头文件有问题

在哪出的问题，21行？

偶遇到类似问题都是用 “每次用/*...*/注释掉不同部分再重新编译，直到定位到具体语法出错的位置。” 的方法解决的。

引用 1 楼 ant2012 的回复:会不会是中文的逗号  什么意思 ？代码是同步于官方的，不是我写的，但是编译时就报错

会不会是中文的逗号


Question: 热烈庆祝本人受关注人数即将突破8000大关！散分！！＋设置终端图标和字体大小C源代码

接分接分接分接分……

久闻赵老师大名

赵老师，你好啊，我很崇拜你的，希望多多跟你学习。

恭喜，学习的榜样

来晚了一步啊

人总得时不时找点理由庆祝一下哈。今天吃巴甫洛夫……

嗯，关注人数还差46人达8000人，赵老师，在努把力。哈哈  嗯，我在想，当赵老师你的关注人数达8000人时，我把自己对你的关注取消了，这个关注人数不有下落掉8000人了吗？哈哈

希望还没来晚

恭喜恭喜

那些都是我小号，你不信，看我换一个号，发同样的内容

支持分享。

恭喜楼主，躺下接分

恭喜楼主，接分！

又来接分咯

赵老师，给你增加点人气。赞一个 赞一个 赞一个

没有看到分呀

接分接分

菜鸟来接分了

同楼上。。。。


Question: 50分， 3个版本的makefile ，百思不得骑姐

不要迷信书、考题、老师、回帖； 要迷信CPU、编译器、调试器、运行结果。 并请结合“盲人摸太阳”和“驾船出海时一定只带一个指南针。”加以理解。 任何理论、权威、传说、真理、标准、解释、想象、知识……都比不上摆在眼前的事实！  有人说一套做一套，你相信他说的还是相信他做的？ 其实严格来说这个世界上古往今来所有人都是说一套做一套，不是吗？

搜“跟我一起写makefile”

up 起来，等高手解答

ERR := $(error found an error!)      all:main1 main2         @echo $${array[0]} main1: main1.c     @gcc main1.c -o main1 main2: main2.o     @gcc main2.o -o main2 main2.o: main2.c     @gcc -c main2.c   .PHONY:clean err  err:;$(ERR) clean:     @rm -f main2.o                                 第2行报错，然后makefile停止。  我之所以这么写，是参考以下文章：  http://blog.chinaunix.net/uid-23929712-id-2650467.html 示例2： ERR = $(error found an error!)   .PHONY: err err: ; $(ERR)   这个例子，在make读取Makefile时不会出现致命错误。只有目标“err”被作为一个目标被执行时才会出现。  红色的是文章里提到的内容。  于是我仿写了，结果依然报错。

不是Tab的问题。  在目标内部， 内置函数不需要顶头写，有多少空格，或者tab都无所谓。    刚才又尝试了几次，发现这3个版本的执行结果的原因：  目标内部，error和warning的优先级别高，所以先执行，所以根本不会去管echo!!!   另外一个问题：  在target里的注释问题！！！！！  命令的必须用@#进行注释！！  命令与命令之间没有必要用; 隔开，网上说隔开的，都是扯犊子。  还有，对于内置函数的注释用#，需要顶到行首进行注释。

提醒：makefile里面的tab字符必须是真正的tab字符，不能用几个空格代替。

引用 4 楼 zhao4zhong1 的回复:搜“跟我一起写makefile”  解决不了，  我看过哪些文章。


Question: 关于GetModuleHandle函数用法的疑问？还请大牛解惑！

#ifndef __JEMALLOC___INCLUDED__ #define __JEMALLOC___INCLUDED__   #include <windows.h>  typedef void*    (__cdecl *_LPMALLOC)		(unsigned int size); typedef void*    (__cdecl *_LPCALLOC)		(unsigned int number, unsigned int size); typedef int      (__cdecl *_LPPOSIX_MEMALIGN)( void **ptr, unsigned int alignment, unsigned int size); typedef void*    (__cdecl *_LPALIGNED_ALLOC)(unsigned int alignment, unsigned int size); typedef void*    (__cdecl *_LPREALLOC)		(void *ptr, unsigned int size); typedef void     (__cdecl *_LPFREE)			(void *ptr); typedef int      (__cdecl *_LPSTRDUP)		(char *Source); typedef int      (__cdecl *_LPWCSDUP)		(wchar_t * Source); typedef int      (__cdecl *_LPSTRNDUP)		(char *Source, int); typedef unsigned int    (__cdecl *_LPMALLOC_USABLE_SIZE)(const void *ptr); typedef void*    (__cdecl *_LPFREX)			(void); typedef void*    (__cdecl *_LPMEMALIGN)		(unsigned int boundary, unsigned int size); typedef void*    (__cdecl *_LPVALLOC)		(unsigned int size);  typedef struct { 	_LPMALLOC	malloc; 	_LPCALLOC	calloc; 	_LPPOSIX_MEMALIGN posix_memalign; 	_LPALIGNED_ALLOC	align_alloc; 	_LPREALLOC	realloc; 	_LPFREE		free; 	_LPSTRDUP	strdup; 	_LPWCSDUP	wcsdup; 	_LPSTRNDUP	strndup; 	_LPMALLOC_USABLE_SIZE malloc_usable_size; 	_LPFREX		frex; 	_LPMEMALIGN	memalign; 	_LPVALLOC	valloc; } MOZILLA_JEMALLOC, *LPMOZILLA_JEMALLOC;  HINSTANCE hJeMod;  VOID LoadJemallocLibrary (const char* version_name, LPMOZILLA_JEMALLOC lpmz) { 	BOOL mask = 0; 	{ 		hJeMod = LoadLibraryA(version_name);   		if(!hJeMod) MessageBoxA(nullptr, "LoadJemalloc Failed", "ERROR", MB_OK), exit(-1);	 		 		{ 			lpmz->malloc				= (_LPMALLOC) 				GetProcAddress(hJeMod, "malloc"); 			lpmz->calloc				= (_LPCALLOC) 				GetProcAddress(hJeMod, "calloc"); 			lpmz->posix_memalign		= (_LPPOSIX_MEMALIGN) 		GetProcAddress(hJeMod, "posix_memalign"); 			lpmz->align_alloc			= (_LPALIGNED_ALLOC) 		GetProcAddress(hJeMod, "align_alloc"); 			lpmz->realloc				= (_LPREALLOC) 				GetProcAddress(hJeMod, "realloc"); 			lpmz->free					= (_LPFREE) 				GetProcAddress(hJeMod, "free"); 			lpmz->strdup				= (_LPSTRDUP) 				GetProcAddress(hJeMod, "strdup"); 			lpmz->wcsdup				= (_LPWCSDUP) 				GetProcAddress(hJeMod, "wcsdup"); 			lpmz->strndup				= (_LPSTRNDUP) 				GetProcAddress(hJeMod, "strndup"); 			lpmz->malloc_usable_size	= (_LPMALLOC_USABLE_SIZE) 	GetProcAddress(hJeMod, "malloc_usable_size"); 			lpmz->frex					= (_LPFREX) 				GetProcAddress(hJeMod, "frex"); 			lpmz->memalign				= (_LPMEMALIGN)				GetProcAddress(hJeMod, "memalign"); 			lpmz->valloc				= (_LPVALLOC) 				GetProcAddress(hJeMod, "valloc"); 		} 	} }  BOOL FreeJemallocLibrary () { 	return FreeLibrary(hJeMod); } #endif   这是我写的读取火狐jemalloc dll的代码(不想用lib。。) 希望对lz有所帮助

Map到内存 也可以 Windows exe和 dll 加载方式都只这么做的， 注意加载参数选择， 内存映像方式

如果DLL没有加载到内存，怎么会有句柄？如果不想显示加载，那就使用与DLL相关的lib进行隐式加载就是。

不好意思，目前我只知道LoadLibrary，为何不用它呢，挺方便的

引用 1 楼 ant2012 的回复:MSDN The handles returned by GetModuleHandle and LoadLibrary can be used in the same functions — for example, GetProcAddress, FreeLibrary, orLoadResource. The difference between the two functions involves the reference count. LoadLibrary maps the module into the address space of the calling process, if necessary, and increments the module's reference count, if it is already mapped. GetModuleHandle, however, returns the handle to a mapped module without incrementing its reference count.   也就是说如果动态链接库已经加载到地址空间中，就可直接用GetModuleHandle ，否则得通过LoadLibrary 将库映射到进程的地址空间中请问除了LoadLibrary 还有其他的办法吗？


Question: 么么，新人求助，已知5个人的学号，身高，体重，要求输入学号，输出学号，身高，体重。

如果是别人，那直接一个结构体存数据但愿，用map组织数据，map自带查找功能。 你想用链表，也可以，自己实现一个链表，设计一个结构体，然后遍历链表查找，自己实现起来，还是很有意思的。

我想用这个题参考，我自己想的题，想看看别人怎么做，哥哥们，给力点 啊。。

恩 用结构体，指针，数组。。。

你直接问代码啊？


Question: 请问如何用C写一个暴力破解SSH的程序

你看看我的代码，我不会shell，所以都是瞎写的，不知道错在哪，你看这种方法能实现吗 #include<stdio.h> #include<memory.h> int main(int argc,char**argv){ 	FILE* fp=NULL; 	fp=fopen("passwd.txt","r"); 	char buff[20]; 	int i; 	for(i=0;;i++){ 		memset(buff,0,sizeof(buff));  		if(fp==NULL) 			break;  		fgets(buff,20,fp); 		printf("%s",buff); 		char shell[200]; 		sprintf(shell,"/home/hht/workspeace/work1/ssh.sh %s %s",argv[1],buff); 		system(shell); 			} }  下面是shell  #!/usr/bin/expect -f set passwd $2 #密码 set host $1 #目标主机地址 set name root #用户名  spawn ssh $host -l $name expect "root@$host’s password:" send "$passwd\r"  send"uname\n" expect"LINUX" send_user"success"  expect"Permission denied,please try again." send_user"wrongnumber"

网上使用字典暴力破解的源代码自己搜搜看。

暴力破解好费时间的

我也在想如何做，一直没有头绪

是停费时间的，但是我需要做这样一个程序，毕竟从头做起嘛

就是类似medusa那种功能，但是不用那么专业，只是来试验用


Question: 自己写了一个字符串连接函数，请问哪里错了

问题：内存越界。  在你写的函数strcpy()里面， while(*pa!='\0') {      pa++; }  这里没问题。 问题是：后面的 while((*pa++=*pb)!='\0); 因为退出第一个循环后，你的pa指针就指向了字符串的结尾的'\0'，然后，第二个循环你还在让pa++,显然访问了不属于你这个字符串的内存，所以错误罗。 你难道不理解为什么 书上说strcpy()在使用时要确保第一个字符串参数要有足够的空间 ？理解一下。

1. 主函数都有问题，a,b指向的是字符串常量，其指向的数据是只读的，不能更改的 2. while(*pa != '\0'){         pa++;     }     后par指向的值为‘\0’再往后++就越界了

char a[80] = "love"; char b[80] = "you";

char * a = "love";  char * b = "you"; //Text Segment | Read-Only

while((*pa++ = *pb++) != '\0'); //pa | over bounds | SIGSEGV

不是连接函数有问题，是用法有问题，这个用法来调用标准的链接函数也会出问题的。

上面是对pa++

while((*pa++ = *pb++) != '\0');  你已经在上面将pb++了，这时候pb已经在字符串的尾部，再对他进行操作，肯定就遇到‘\0’了啊，所以拷贝错误


Question: 能有位大神帮忙看一下小程序吗？很短的，可惜渣渣怎么都看不懂！感谢

就是定义了一个结构体而已

typedf 是重命名 将结构体命名为T_POST_EVENT_TYPE


Question: 关于getchar和scanf的问题求助。。。

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

程序运行第一遍的时候是没问题的，scanf读的是2 3 但之后有没有问题，得看你怎么输入了，getchar()能够读取任意字符，包括空格、回车，scanf只能读取规定格式的数据


Question: 在用msp430f5529和ADXL345实现计步器  程序在一个地方停止了  弄了好几天  求大神指点！

移动至“硬件/嵌入式”板块


Question: JNI中有关C语言指针的疑问

引用 2 楼 ligenmt 的回复:[quote=引用 1 楼 user-1 的回复:] JNIEnv本身就是指针  哦！那您的意思是env其实是指针的指针了？[/quote] jni.h中  struct JNINativeInterface_; struct JNIEnv_; #ifdef __cplusplus typedef JNIEnv_ JNIEnv; #else typedef const struct JNINativeInterface_ *JNIEnv; #endif

引用 1 楼 user-1 的回复:JNIEnv本身就是指针  哦！那您的意思是env其实是指针的指针了？

JNIEnv本身就是指针

引用 3 楼 user-1 的回复:[quote=引用 2 楼 ligenmt 的回复:] [quote=引用 1 楼 user-1 的回复:] JNIEnv本身就是指针  哦！那您的意思是env其实是指针的指针了？[/quote] jni.h中  struct JNINativeInterface_; struct JNIEnv_; #ifdef __cplusplus typedef JNIEnv_ JNIEnv; #else typedef const struct JNINativeInterface_ *JNIEnv; #endif[/quote]  谢谢！


Question: 求大神帮解一道C语言

7楼正解。除了一些比较常用的循环以外，基本不用++

除了出题，其他情况用不到这种写法

函数参数的求值顺序是没做定义的，所以楼主的那一次编译最后参数先编译，利用了i = 8 的初始值，而后面的都是些随机情况。 LZ请注意，C语言中只有4个运算符规定了求值顺序 （1） 逻辑与 “&&”  （2)逻辑或“ ||” （3）条件运算符 “？：”（4）逗号运算符“ ，”。 除此之外的都没做定义，需要我们适当使用括号或者分开来写。

又是这种专牛角尖的题。 1.学生被考试害得不轻啊，你要是在面试的时候写这种代码，对不起，走人。 2.教学害得。IT更新多块，什么年代，还在写void main().   --->  int main (void)  解答一下： 这个主要是函数调用时，参数压栈顺序的问题。 函数的值是从右边往左压栈的。所以，副作用从printf(""          ) 的最右边开始。     printf("   xxxxx",++i    ,    i++,     --i     ,     i++     ,--i,       -i++      ,i--)                           (7)           (6)      (5)         (4)       (3)        (2)     (1) 先计算(1) 再(2) .。。。。。。 i++  ++i 这类问题的就看书吧。

几乎没什么人会这么写,这么写的结果很依赖与编译器,你用DEV的话结果又会不一样. 这就是C/C++ . 很大程度上依赖于编译器厂商. 你要做的就是熟悉一个,了解这种差异 这有关于你的问题的详解.....也就是楼上说的顶置贴.......http://bbs.csdn.net/topics/370153775

这种问题去看置顶帖 就算看不懂，只要知道不要这么写就可以了

楼上正解，调用函数的时候，参数从左向右压栈

在计算时，遇到x++会记录此时的x的值作为最后的输出结果。遇到x和++x的时候则不会将此时的计算结果作为最终的输出，只会修改x的值，在最终输出的时候都输出x的值。 对于i++的结果，是有ebp寻址函数栈空间来记录中间结果的，在最后给printf压栈的时候，再从栈中把中间结果取出来；而对于++i的结果，则直接压寄存器变量，寄存器经过了所有的自增操作。  在不同的编译器下结果不同

只看到窗帘，没看到人，好黑。

难道置顶帖放着都不看么？

这个包含参数传递和++等运算符，而且与编译器相关，所以，楼主不要纠结这种问题的答案


Question: 问一个关于返回值的问题

感谢各位的回答 问题已解决 就此结帖。

调用函数，被调用函数，实参，形参你应该都清楚吧，这个就不解释其定义了； 看下你代码： #include <stdio.h> int main() {     int latitude = 32 ;     go_south_east(latitude);     printf("当前位置: [%i]\n",latitude);     return 0; } int go_south_east(int lat) {     lat = lat - 1;         return lat; } 你这里在主函数中调用函数int go_south_east（）并将latitude作为实参传递给形参lat，属于值传递，在这个值传递的过程中，发生了以下事情：形参lat是一个局部变量，存储在栈中，接收的值为实参latitude的值，那么请你思考一下两个变量latitude和lat存储在内存中的地址是否相同？说白了是不是指向同一内存空间？ 答案是：不是；不信你打印他们地址看一看，明白了这个就好理解其他的，另个存储在不同内存空间中的两个变量，你改变其中一个变量的值对另外一个有影响吗？肯定没有啊； 再来说说你返回lat，麻烦问一下，你返回lat作为被调用函数的返回值，可主函数中有接受返回值的变量吗？你都没有变量接受那么这个值肯定丢掉了啊；    你可以改成这样看看 latitude= go_south_east(latitude);

楼主你调用函数的时候，使用的参数传递方式是值传递，所以实参是不会受形参的修改而改变的。 另外，你在被调用的函数中是用返回值来表示结果的，所以如果你想得到结果应该用楼上的方式，把返回值保存下来再用。

把返回值接收下，就行，如 latitude = go_south_east(latitude);

1楼的是c++代码，不是c 楼主再仔细看看c语言参数传递那一部分吧

@user-5 我不是很明白 能详细说一下么

int go_south_east(int& lat)


Question: Linux下C语言数组用sscanf问题？？

过早的优化是万恶之源。  但填表式排版还是要用的。 http://bbs.csdn.net/topics/380157851    //get操作          if(strcmp(rectype,"id210")==0) printf("%d\n",a_1  );     else if(strcmp(rectype,"id220")==0) printf("%d\n",a_2  );     else if(strcmp(rectype,"id230")==0) printf("%d\n",a_3  );     ......     else if(strcmp(rectype,"id999")==0) printf("%d\n",a_300);     //set操作          if(strcmp(rectval,"id210")==0) a_1  =recval;     else if(strcmp(rectval,"id220")==0) a_2  =recval;     else if(strcmp(rectval,"id230")==0) a_3  =recval;     ......     else if(strcmp(rectval,"id999")==0) a_300=recval;

引用 4 楼 zhao4zhong1 的回复:其实电脑开机后物理内存的每个字节都是可读写的，从来不会因为所谓的new、delete或malloc、free而被创建、销毁。区别仅在于操作系统内存管理模块在你读写时是否能发现并是否采取相应动作而已。操作系统管理内存的粒度不是字节而是页，一页通常为4KB。  程序有两个文件，一个a程序一个b声明变量的外部文件，a通过include引用b; html通过ajax请求到a程序，通过接收到的参数来判断引用b文件中哪一个变量。 sscanf("%[^=]=%s",rectype,recval); 如果是get操作只需要recval，如果是set就需要rectype，recval两个局部变量。 现在我用的if判断，如果几百条的话是不是太麻烦了该怎么优化？？ 麻烦了，多谢。。。。 代码如下： b.h  	int a_1; 	int a_2; 	int a_3; 	int a_4; 	...... 	int a_300;           a.c     //get操作 	if(strcmp(rectype,"id210")==0){ 		printf("%d\n",a_1); 	}else if(strcmp(rectype,"id220")==0){ 		printf("%d\n",a_2); 	}else if(strcmp(rectype,"id230")==0){ 		printf("%d\n",a_3); 	} 	...... 	else if(strcmp(rectype,"id999")==0){ 		printf("%d\n",a_300); 	}      //set操作 	if(strcmp(rectval,"id210")==0){ 		a_1=recval; 	}else if(strcmp(rectval,"id220")==0){ 		a_2=recval; 	}else if(strcmp(rectval,"id230")==0){ 		a_3=recval; 	} 	...... 	else if(strcmp(rectval,"id999")==0){ 		a_300=recval; 	}

引用 3 楼 user-2 的回复:[quote=引用 2 楼 GZQ0821 的回复:] 第一位数组data[0]就可以，后面data[1],data[2]。。。就不行了，怎么解决？？ 来 看我口型 跟着我读 因为很重要所以读三次 能输出是运气好  能输出是运气好  能输出是运气好   data[0] 只是 "运气好"  你的错误是野指针 怎么纠正野指针 自己百度[/quote] 谢谢，改为字符数组就可以了！另外，还有一个问题： 程序有两个文件，一个a程序一个b声明变量的外部文件，a通过include引用b; html通过ajax请求到a程序，通过接收到的参数来判断引用b文件中哪一个变量。 sscanf("%[^=]=%s",rectype,recval); 如果是get操作只需要recval，如果是set就需要rectype，recval两个局部变量。 现在我用的if判断，如果几百条的话是不是太麻烦了该怎么优化？？ 麻烦了，多谢。。。。 代码如下： b.h  	int a_1; 	int a_2; 	int a_3; 	int a_4; 	...... 	int a_300;              //get操作 	if(strcmp(rectype,"id210")==0){ 		printf("%d\n",a_1); 	}else if(strcmp(rectype,"id220")==0){ 		printf("%d\n",a_2); 	}else if(strcmp(rectype,"id230")==0){ 		printf("%d\n",a_3); 	} 	...... 	else if(strcmp(rectype,"id999")==0){ 		printf("%d\n",a_300); 	}      //set操作 	if(strcmp(rectval,"id210")==0){ 		a_1=recval; 	}else if(strcmp(rectval,"id220")==0){ 		a_2=recval; 	}else if(strcmp(rectval,"id230")==0){ 		a_3=recval; 	} 	...... 	else if(strcmp(rectval,"id999")==0){ 		a_300=recval; 	}

引用 2 楼 GZQ0821 的回复:第一位数组data[0]就可以，后面data[1],data[2]。。。就不行了，怎么解决？？ 来 看我口型 跟着我读 因为很重要所以读三次 能输出是运气好  能输出是运气好  能输出是运气好   data[0] 只是 "运气好"  你的错误是野指针 怎么纠正野指针 自己百度

引用 1 楼 user-2 的回复:char *rectype,*recval; 这两个是野指针  能输出是运气好 不能输出是常见现象  有时候还会崩溃 第一位数组data[0]就可以，后面data[1],data[2]。。。就不行了，怎么解决？？


Question: 无聊 各位来秀秀码风如何 ?

拖延症患者来结贴了

引用 15 楼 bear234 的回复:楼主，你的风格我不敢恭维啊  为什么函数定义时的大括号要缩进去？为什么不和class那样class和大括号对其呢？你不觉得你的缩进很丑么.....  如果你用vs的话，我建议你ctrl+A，然后ctrl+K+F 看看vs默认的风格   vs在这些方面做得还是很好的额 ... 本人菜鸟 ... 你说的很对 。。抛砖引玉~ 谢谢你的建议 ... 本人最头疼的就是代码风格和变量命名的问题 ...

引用 16 楼 u013550545 的回复:[quote=引用 15 楼 bear234 的回复:] 楼主，你的风格我不敢恭维啊  为什么函数定义时的大括号要缩进去？为什么不和class那样class和大括号对其呢？你不觉得你的缩进很丑么.....  如果你用vs的话，我建议你ctrl+A，然后ctrl+K+F 看看vs默认的风格   vs在这些方面做得还是很好的额 ... 本人菜鸟 ... 你说的很对 。。抛砖引玉~ 谢谢你的建议 ... 本人最头疼的就是代码风格和变量命名的问题 ... [/quote]  基本上，vs的快速格式化的快捷键是先选中你需要格式化的代码，然后ctrl+K + F  这个风格算是微软的风格吧，用vs做c c++ c# 基本都是这个风格 你可以可以去看看eclipse的，快捷键是ctrl+i 还有一个不错的东西：netbeans   这个编译环境的风格是可以自己设定的   不过即使它允许自己设定，你也不可能把代码风格设定成你1楼那个样子的.......  做这些编译器的人都是牛人，我建议你最好在上面那些里面选一个自己喜欢的就好了～～～  变量命名的话，除了全部大写表示常量比如PI、首字母小写表示变量ipOfServer、首字母大写表示函数ShowAllMembers外，还有一些程序员里的潜规则  你可以专门去了解下   其实这些潜规则都很有用   可以避免很多2b的问题  另外，如果你是新手的话，我建议你研究一下你常用的编译环境的快捷键   记住最常用的几个  可以大幅提高编译效率 我用的是vs，基本上我在写代码的时候很少用到鼠标，你别觉得鼠标很方便，其实鼠标会降低编写代码时的效率  最好能熟练快捷键，用键盘操作 这样会很快

再来一段，顶起顶起：void GetDefFileNameByMIME(PCSTR pszMimeType, PSTR pszFileName) {     HKEY hKey = NULL;     DWORD dwSize = 0;     char szSubKey[1024] = { 0 };     char szDefExt[256] = { 0 };      struct {         PCSTR pszMimeType;         PCSTR pszDefExt;     } mapMimeExt[] = {         { "image/bmp",  ".bmp" },         { "image/gif",  ".gif" },         { "image/jpeg", ".jpg" },         { "image/png",  ".png" },         { "image/tiff", ".tiff" },     };      lstrcpyA(pszFileName, "cover");      wsprintfA(szSubKey, "MIME\\Database\\Content Type\\%s", pszMimeType);     if (RegOpenKeyExA(HKEY_CLASSES_ROOT, szSubKey, 0, KEY_QUERY_VALUE, &hKey) == ERROR_SUCCESS) {         RegQueryValueExA(hKey, "Extension", NULL, NULL, (BYTE *)szDefExt, &dwSize);         RegCloseKey(hKey);     }     if (szDefExt[0] == 0 || dwSize == 0) {         for (size_t i = 0; i < ARRAYSIZE(mapMimeExt); i++) {             if (lstrcmpi(mapMimeExt[i].pszMimeType, pszMimeType) == 0) {                 lstrcpy(szDefExt, mapMimeExt[i].pszDefExt);             }         }     }     PathAddExtension(pszFileName, szDefExt); }

引用 10 楼 jiqiang01234 的回复: #ifndef _BD_TRANSMISSION_DEF_H_ #define _BD_TRANSMISSION_DEF_H_ #include "BD_PlatformConfigDef.h"   #ifndef Bool #define Bool    int #endif   #ifndef True #define True    1 #endif  #ifndef False #define False   0 #endif   typedef struct tagBDHandle* BDHandle;  enum {      BD_REQUEST_IC_CHECK,     BD_RETURN_IC_CHECK, /*     BD_REQUEST_SYSTEM_CHECK,     BD_RETURN_SYSTEM_CHECK, */     BD_REQUEST_DATETIME,     BD_RETURN_DATETIME,      BD_REQUEST_POWER_CHECK,     BD_RETURN_POWER_CHECK,      BD_REQUEST_COMMUNICATION,     BD_RETURN_COMMUNICATION,      BD_REQUEST_POSITION,     BD_RETURN_POSITION,      BD_REQUEST_BAUDRATE,      BD_RETURN_FEEKBACK,       BD_RETURN_MESSAGE,      //单播或通播长消息的发送状态     BD_RECV_MESSAGE,        //接收到长消息      BD_NMEA_GPRMC,     BD_NMEA_GPGSA,      BD_NMEA_BDRMC,     BD_NMEA_BDGSA,      BD_NMEA_GNRMC,     BD_NMEA_GNGSA,      BD_NMEA_GPGSV,     BD_NMEA_BDGSV,  };  enum {     FEEDBACK_CODE_SUCCESS,                    //成功     FEEDBACK_CODE_FAILURE,                    //失败     FEEDBACK_CODE_SIGNAL_UNLOCK,              //信号未锁定     FEEDBACK_CODE_LOW_BATTERY,                //电量不足     FEEDBACK_CODE_UNAVAILABLE_EMISSION_FREQUENCY,        //发射频度未到     FEEDBACK_CODE_CRYPTO_ERROR,               //加密解密错误     FEEDBACK_CODE_CRC_ERROR,                  //CRC错误     FEEDBACK_CODE_UNKNOWN,                    //未知的反馈信息  };  enum {     MESSAGE_CODE_SUCCESS,     MESSAGE_CODE_FAILURE, };  enum BD_Protocol {     BD_PROTOCOL_V1,  //北斗一代协议     BD_PROTOCOL_V2,  //北斗二代协议     BD_PROTOCOL_V3,  //东方红协议 };  enum BD_Baudrate {     BD_BAUDRATE_1200     = 1200,     BD_BAUDRATE_2400     = 2400,     BD_BAUDRATE_4800     = 4800,     BD_BAUDRATE_9600     = 9600,     BD_BAUDRATE_19200    = 19200,     BD_BAUDRATE_38400    = 38400,     BD_BAUDRATE_57600    = 57600,     BD_BAUDRATE_115200   = 115200 };  enum BD_DataBits {     BD_DATABITS_5   = 5,     BD_DATABITS_6   = 6,     BD_DATABITS_7   = 7,     BD_DATABITS_8   = 8 };  enum BD_StopBits {     BD_STOPBITS_1,     BD_STOPBITS_1_5,     BD_STOPBITS_2 };  enum BD_Parity {     BD_PARITY_NONE,     BD_PARITY_ODD,     BD_PARITY_EVEN };  enum BD_PriorityLevel {     PRIORITY_LEVEL_0,   //最高优先级     PRIORITY_LEVEL_1,     PRIORITY_LEVEL_2,   //只能使用比level2更低的优先级，高的优先级内部使用      //以下为调用端可以使用的优先级     PRIORITY_LEVEL_3,     PRIORITY_LEVEL_4,     PRIORITY_LEVEL_5,     PRIORITY_LEVEL_6,   //最低优先级      PRIORITY_LEVEL_COUNT };  #pragma pack(1)    struct BD_CommParam {     enum BD_Protocol protocol;     enum BD_Baudrate baudrate;     enum BD_Parity parity;     enum BD_DataBits databits;     enum BD_StopBits stopbits; };  struct BD_Time {     uint8_t hour;     uint8_t minute;     uint8_t second;     uint16_t millisec; };  struct BD_Date {     uint8_t year;   //0=2000,1=2001,2=2002,...     uint8_t month;     uint8_t day; };  struct BD_GPSPosition {     uint32_t value; //单位:度，扩大了10000倍     char location;  //'N''S''W''E' };  //Recommended Minimum sentence C struct BD_RMC {     struct BD_Date date;     struct BD_Time utc;     char status;    //'A'=active or 'V'=Void.     struct BD_GPSPosition latitude;     struct BD_GPSPosition longitude;     uint16_t speed;   //对地航速,单位:节,Speed over the ground，扩大了10倍     uint16_t angle;   //真航迹角,单位:度,Track angle True,扩大了10倍 };  #define BD_SATELLITE_PRN_COUNT    12 struct BD_GSA {     char fixMode;       //定位模式,=='A'自动,=='M'手动     uint8_t fixType;    //定位类型,==0未定位,==2是2D定位,==3为3D定位     uint8_t prn[BD_SATELLITE_PRN_COUNT];  //定位卫星的prn(伪随机噪声码)     uint8_t count;                         //prn数组中有效数据的个数 };  #define BD_SENTENCE_SATELLITE_COUNT     4 struct BD_GSV {     uint8_t viewNum;    //可视卫星的数量     struct     {         uint8_t prn;         uint16_t elevation;     //仰角,单位:度         uint16_t azimuth;       //方位角,单位:度         uint8_t snr;            //信噪比(Signal to Noise Ratio)     }info[BD_SENTENCE_SATELLITE_COUNT];     uint8_t count; };  struct BD_RequestDateTime {     uint16_t frequency;       //输出频度，单位:秒,==0单次,>0周期输出 };  struct BD_ReturnDateTime {     struct BD_Date date;     struct BD_Time time; };  struct BD_RequestICCheck {     uint32_t addr;      //返回指定设备地址的ic信息,如果是本机设备则为0     uint8_t frame;      //帧号 };  struct BD_ReturnICCheck {     uint32_t addr;              //查询的设备地址     uint8_t frame;              //帧号     uint32_t broadcastAddr;     //通播地址     uint8_t feature;            //用户特征值     uint16_t frequency;         //服务频度,单位:秒     uint8_t level;              //通信等级1~4     uint8_t encrypt;            //是否加密，!=0加密，==0不加密     uint16_t userCount;         //下属用户数 };  #define BD_LocalICInfo BD_ReturnICCheck  #define BD_BEAMPOWER_COUNT      6 struct BD_RequestPowerCheck {     uint8_t frequency;  //输出频度，单位:秒,==0单次,>0周期输出 };  #define BD_MAX_BEAMPOWER_VALUE     4 struct BD_ReturnPowerCheck {     uint8_t power[BD_BEAMPOWER_COUNT]; //波束功率 };  struct BD_ReturnFeekback {     uint16_t code;        //返回的信息码     uint32_t description; //若是FEEDBACK_CODE_UNAVAILABLE_EMISSION_FREQUENCY，表示需要等待的时间，单位:秒;若是BD_FEEDBACK_UNKNOWN，表示返回的原始值 };  #define BD_MAX_REQUEST_CONTENT_SIZE     78 struct BD_RequestCommunication {     uint32_t toAddr;     uint8_t content[BD_MAX_REQUEST_CONTENT_SIZE];     uint16_t size;     uint8_t format; };   #define BD_MAX_RETURN_CONTENT_SIZE      210 struct BD_ReturnCommunication {     uint32_t fromAddr;     uint8_t content[BD_MAX_RETURN_CONTENT_SIZE];     uint16_t size;     uint8_t format;     //内容的编码格式,==0为内码(以双字节为单位的二进制),==1为普通二进制,==2为混发二进制(0xA4开头)     struct BD_Time t;   //发信时间 };   struct BD_Position {     uint8_t degree;     uint8_t minute;     uint32_t second;    //扩大1000倍后的秒     char location;      //'N''S''W''E' };  struct BD_RequestPosition {     uint16_t frequency;     //入站频度,单位:秒,==0单次,>0周期输出 };  struct BD_ReturnPosition {     struct BD_Time t;       //定位时间     struct BD_Position latitude;     struct BD_Position longitude;     uint8_t accuracy;       //精度,==0为20米,==1为100米     int32_t elevation;    //高程(可以为负数)，单位:米 };  struct BD_RequestBaudrate {     uint16_t baudrate; };  //不要超过8k,因包序号表示的范围限制 #define BD_MAX_MESSAGE_CONTENT_SIZE       2048 //对单播地址发送长消息的请求 struct BD_RequestUnicastMessage {     uint32_t toAddr;     uint8_t priority;    //发送优先级     uint8_t content[BD_MAX_MESSAGE_CONTENT_SIZE];     uint32_t size; };   //不能超过255 #define BD_MAX_BROADCAST_ADDRESS_COUNT     100 //通播发送长消息的请求 struct BD_RequestBroadcastMessage {     uint32_t toAddrs[BD_MAX_BROADCAST_ADDRESS_COUNT];     uint8_t addrCount;     uint8_t priority;      uint8_t content[BD_MAX_MESSAGE_CONTENT_SIZE];     uint32_t size; };  struct BD_ReturnMessage {     uint32_t id;        //发送时返回的id     uint32_t toAddr;    //发往的目的地址,如果是通播发送,每向一个地址发送成功便产生一次本消息     uint8_t code;       //返回码 };  struct BD_RecvMessage {     uint32_t fromAddr;     uint8_t content[BD_MAX_MESSAGE_CONTENT_SIZE];     uint32_t size; };  #pragma pack()  #endif // _BD_TRANSMISSION_DEF_H_    一个感觉，瘦高个，代码很高挑。膜拜！

void LSVM::SMOTrainModelExample(     IN const LSVMMatrix& sampleMatrix,      IN const LSVMMatrix& classVector,      IN float C,     IN float toler,      OUT float& b,      OUT LSVMMatrix& alphaVector) {     unsigned int sampleNum = sampleMatrix.RowLen; // 样本数量     unsigned int featureNum = sampleMatrix.ColumnLen; // 样本的特征数量  	float B = 0.0f; // 分割超平面的截距      // 将alpha向量初始化为0向量(列向量)     alphaVector.Reset(sampleNum, 1);     for (unsigned int i = 0; i < alphaVector.RowLen; i++)     {         alphaVector[i][0] = 0.0f;     }      int iter = 0;     while (iter < 40)     {         bool alphaChanged = false;         // 循环扫描每一个alpha, 对可优化的alpha进行优化         for (unsigned int i = 0; i < sampleNum; i++)         { 			// 根据现有alpha计算出第i个样本的间隔, 计算出的值不符合KKT条件表明需要优化  			// 计算权重 			// w = sum for i = 1 to m (alpha(i) * y(i) * x(i))             LSVMMatrix W = LSVMMatrix::DOTMUL(alphaVector, classVector).T() * sampleMatrix;// 计算出的权重为行向量  			// 根据权重计算间隔 			// margin = y(i) * (W * X(i) + b) 			LSVMMatrix Xi = sampleMatrix.GetRow(i); // 行向量             LSVMMatrix XiT = Xi.T(); // 列向量 			LSVMMatrix WXi = W * XiT;             float Ei = WXi[0][0] + B - classVector[i][0]; // 样本i标签的误差 			float marginXi = classVector[i][0] * (WXi[0][0] + B); // 样本i的间隔              			// KKT条件:: 			//alpha如果小于C, 那么margin应该大于等于1, 如不符合那么违反KKT条件, 则需要优化 			//alpha如果大于0, 那么margin应该小于等于1, 如不符合那么违反KKT条件, 则需要优化 			if (((alphaVector[i][0] < C) && (marginXi < 1 - toler)) || 				((alphaVector[i][0] > 0) && (marginXi > 1 + toler))) 			{                 // 随机选择另一个alpha j                 int j = this->SelectRand(i, sampleNum-1);                 LSVMMatrix Xj = sampleMatrix.GetRow(j); // 行向量                 LSVMMatrix XjT = Xj.T(); // 列向量                 LSVMMatrix WXj = W * XjT;                 float Ej = WXj[0][0] + B - classVector[j][0]; // 样本j标签的误差                 float marginXj = classVector[j][0] * (WXj[0][0] + B); // 样本j的间隔                                 float LAj = 0.0f; // alpha j 的下届                 float HAj = 0.0f; // alpha j 的上届                 // 计算alpha j 的上下界                 if (classVector[i][0] != classVector[j][0])                 {                     LAj = LMAX(0, alphaVector[j][0] - alphaVector[i][0]);                     HAj = LMIN(C, C + alphaVector[j][0] - alphaVector[i][0]);                 }                 if (classVector[i][0] == classVector[j][0])                 {                     LAj = LMAX(0, alphaVector[j][0] - alphaVector[i][0] - C);                     HAj = LMIN(C, alphaVector[j][0] - alphaVector[i][0]);                 }                                  if (LAj == HAj)                 {                     continue;                 }                                 // 计算eta = 2 * Xi * Xj - Xi * Xi - Xj * Xj                 LSVMMatrix XiXj = Xi * XjT;                 LSVMMatrix XiXi = Xi * XiT;                 LSVMMatrix XjXj = Xj * XjT;                  float eta = 2 * XiXj[0][0] - XiXi[0][0] - XjXj[0][0];                 if (eta == 0.0f)                 {                     continue;                 }                                  // 计算新的alpha j                  float AjOld = alphaVector[j][0];                 alphaVector[j][0] -= classVector[j][0] * (Ei - Ej) / eta;                 // 裁剪alpha j                 alphaVector[j][0] = this->ClipAlpha(alphaVector[j][0], LAj, HAj);                  // 如果alpha j 改变量太小, 则退出                 if (abs(alphaVector[j][0] - AjOld) < 0.00001)                 {                     continue;                 }                  // 计算新的alpha i                 float AiOld = alphaVector[i][0];                 alphaVector[i][0] += classVector[i][0] * classVector[j][0] * (AjOld - alphaVector[j][0]);                  // 计算截距B的值                 float B1 = B - Ei - classVector[i][0] * (alphaVector[i][0] - AiOld) * XiXi[0][0] -                      classVector[j][0] * (alphaVector[j][0] - AjOld) * XiXj[0][0];                 float B2 = B - Ej - classVector[i][0] * (alphaVector[i][0] - AiOld) * XiXj[0][0] -                     classVector[j][0] * (alphaVector[j][0] - AjOld) * XjXj[0][0];                  if (alphaVector[i][0] > 0 && alphaVector[i][0] < C)                 {                     B = B1;                 }                 else if (alphaVector[j][0] > 0 && alphaVector[j][0] < C)                 {                     B = B1;                 }                 else                 {                     B = (B1 + B2)/2;                 }                                alphaChanged = true;               			}         }              if (alphaChanged)             iter = 0;         else             iter++;     }      b = B; }

使用默认的VC风格的路过。

#include "common_include.h" #include "custom_util.h" #include "BD_Transmission.h" #include "BD_MessageCodecV1.h" #include "BD_MessageCodecV2.h" #include "BD_MessageCodecV3.h" #include "BD_IOServiceThread.h" #include "BD_CoreTransmission.h" #include "ASIO_SerialPort.h" #include "ASIO_Buffer.h"  struct BDHandleImpl {     std::unique_ptr<BD_IOServiceThread> iothread;     std::unique_ptr<BD_MessageCodecBase> codec;     std::unique_ptr<BD_CoreTransmission> core;     std::unique_ptr<ASIO_SerialPort> sp;      BD_MessageCallback cb;     void* user;      std::condition_variable cv;     std::mutex mtx;     struct BD_ReturnICCheck ic;     bool initComplete; };  static const int CHECK_IC_COUNT = 3;  static void STD_CALL BD_MessageHandler(int msg, const void* content, size_t size, void* user); static BD_MessageCodecBase* BD_CreateMessageCodec(int protocol, BD_MessageCallback cb, void* user); static void BD_IOWrite(const void* content, size_t size, void* user); static void BD_SerialPortHandler(ASIO_Buffer* buffer, void* user);  static custom_util::RandInt g_rand(1, UINT32_MAX);//生成随机数,保证不同北斗实例产生的消息id不相同 BD_API BDHandle BD_CreateDevice(const char* devName, const struct BD_CommParam* param, BD_MessageCallback cb, void* user) {     struct BDHandleImpl* impl = NULL;     try     {         impl = new struct BDHandleImpl();          impl->cb = cb;         impl->user = user;         impl->codec.reset(BD_CreateMessageCodec(param->protocol, &BD_MessageHandler, impl));          //启动线程后，马上等待         impl->iothread.reset(new BD_IOServiceThread(impl->cv));         {             std::unique_lock<std::mutex> lock(impl->mtx);             std::cv_status s = impl->cv.wait_for(lock, std::chrono::milliseconds(500));     //防止线程先启动而导致无限等待，故用超时控制             assert(s == std::cv_status::no_timeout);         }          impl->core.reset(new BD_CoreTransmission(impl->iothread->GetService(), g_rand, &BD_IOWrite, &BD_MessageHandler, impl));         impl->sp.reset(new ASIO_SerialPort(impl->iothread->GetService(),                                         std::bind(&BD_SerialPortHandler, std::placeholders::_1, impl)));         impl->initComplete = false;           if(!impl->sp->Open(devName, param->baudrate, param->databits, param->stopbits, param->parity))             throw false;          //多次检测，保证不会由于意外而不能正常读取         for(int i = 0; i < CHECK_IC_COUNT; i++)         {             struct BD_RequestICCheck r = {0};             DataBlock blk = impl->codec->Encode(BD_REQUEST_IC_CHECK, 0, &r, sizeof(struct BD_RequestICCheck));             impl->sp->Write(blk.data(), blk.size());              std::unique_lock<std::mutex> lock(impl->mtx);             std::cv_status s = impl->cv.wait_for(lock, std::chrono::milliseconds(200));//同步获取ic信息             if(s == std::cv_status::no_timeout)             {                 impl->initComplete = true;                 impl->core->SetLocalIC(&impl->ic);                 break;             }         }          if(!impl->initComplete)             throw false;     }     catch(...)     {         if(impl != NULL)         {             delete impl;             impl = NULL; //保证有正确的返回值         }      }      return reinterpret_cast<BDHandle>(impl); }  BD_API void BD_DestroyDevice(BDHandle handle) {     struct BDHandleImpl* impl = reinterpret_cast<struct BDHandleImpl*>(handle);     delete impl; } BD_API void BD_GetLocalICInfo(BDHandle handle, struct BD_LocalICInfo* info) {     struct BDHandleImpl* impl = reinterpret_cast<struct BDHandleImpl*>(handle);     assert(impl != NULL);     memcpy(info, &impl->ic, sizeof(struct BD_LocalICInfo)); }  BD_API void STD_CALL BD_WriteMessage(BDHandle handle, int msg, const void* content, size_t size) {     struct BDHandleImpl* impl = reinterpret_cast<BDHandleImpl*>(handle);     assert(impl->sp->IsOpen());      DataBlock blk = impl->codec->Encode(msg, impl->ic.addr, content, size);      //因io线程与调用线程不同，需要同步保护     std::unique_lock<std::mutex> lock(impl->mtx);     impl->sp->Write(blk.data(), blk.size()); }  BD_API uint32_t STD_CALL BD_UnicastMessage(BDHandle handle, const struct BD_RequestUnicastMessage* r) { #ifdef BD_SUPPORT_LONG_MESSAGE     //to do:是否允许给自己发送长消息？     struct BDHandleImpl* impl = reinterpret_cast<BDHandleImpl*>(handle);     assert(impl->sp->IsOpen());     return impl->core->Append(r); #else     assert(0);     return 0; #endif  } ///////////////////////////////////////////////////////////////////// static BD_MessageCodecBase* BD_CreateMessageCodec(int protocol, BD_MessageCallback cb, void* user) {     if(protocol == BD_PROTOCOL_V1)     {         return new BD_MessageCodecV1(cb, user);     }     else if(protocol == BD_PROTOCOL_V2)     {         return new BD_MessageCodecV2(cb, user);     }     else if(protocol == BD_PROTOCOL_V3)     {         return new BD_MessageCodecV3(cb, user);     }     else     {         assert(0);         return NULL;     } }  static void BD_IOWrite(const void* content, size_t size, void* user) {     struct BDHandleImpl* impl = static_cast<struct BDHandleImpl*>(user);      DataBlock blk = impl->codec->Encode(BD_REQUEST_COMMUNICATION, impl->ic.addr, content, size);      std::unique_lock<std::mutex> lock(impl->mtx);     impl->sp->Write(blk.data(), blk.size()); }  static void BD_SerialPortHandler(ASIO_Buffer* buffer, void* user) {     struct BDHandleImpl* impl = static_cast<struct BDHandleImpl*>(user);     //将从串口接收的数据发送至编解码模块     impl->codec->Post(buffer->GetData(), buffer->GetSize());      buffer->RemoveAll(); }  static void BD_MessageHandler(int msg, const void* content, size_t size, void* user) {     struct BDHandleImpl* impl = static_cast<struct BDHandleImpl*>(user);      if(!impl->initComplete)     {         if(msg == BD_RETURN_IC_CHECK)         {             const struct BD_ReturnICCheck* r = static_cast<const struct BD_ReturnICCheck*>(content);             assert(size == sizeof(struct BD_ReturnICCheck));             if(r->frame == 0) //只有第0帧的数据才包含本机的有效信息             {                 memcpy(&impl->ic, content, size);                  impl->cv.notify_one();             }         }     }     else     { #ifdef BD_SUPPORT_LONG_MESSAGE         //若不是本系统的长消息,则直接回调调用端         if(!impl->core->DoHandle(msg, content, size)) #endif         {             (*impl->cb)(msg, content, size, impl->user);         }      }  }

引用 5 楼 super_admi 的回复:使用默认的VC风格的路过。 +1, 别外需要说明如下: 1:    开心开心， 所以代码尽量开扩 2:    { 从不右置 3:    少注释， 一个思路完 与 难解的地方才注释一下 4:    变量说明紧跟变量， 而不是函数前 5:    变量名称显示其意义， 绝不满篇都是数学家式的m, n 6:    虽然比较时常量在前较好， 但还是习惯跟着思路常量在后  //    从进程名称判定是否需要隐藏 // BOOL IsHideProcName( 		LPCSTR procName = NULL,		//	为0则采用当前进程名称 		ULONG procName_Len = 15		//	因为从当前进程获得名称时， 最大长度为16， 而实际比较长度为15 		);	  BOOL FnManipulatoinCheck::IsHideProcName( 	LPCSTR procName,		 	ULONG procName_Len	 	) { 	if (!procName) 	{ 		procName = GetCurrentProcessName(); 	} 	if (!procName || !procName_Len || procName_Len >= _countof(m_HideProcs[0].name)) 		return NULL;  	for (ULONG n = 0; n < M_HIDEPROCS_Count; n++) 	{ 		if (!m_HideProcs[n].setled) 			continue; 		if (strncmp(m_HideProcs[n].name, procName, procName_Len) == 0) 			return TRUE; 	} 	return FALSE; }

// 个人风格：  // 变量随用随声明。如做不到则声明时必定初始化： BOOL fRet = FALSE; DWORD dwSize = 0; RECT rc = { 0 }; TCHAR szPath[MAX_PATH] = { 0 };  // 即使一行代码，大括号也必写，左大括号放行尾。以前也是独占一行， 由于屏幕太小，因此改变风格。 // 比较时常量写在右边，句柄、指针与 NULL 比较，数值与数值比较，BOOL 直接当作 bool 表达式。 HMODULE hinstDLL = LoadLibrary(TEXT("kernel32.dll")); if (hinstDLL != NULL) {     FreeLibrary(hinstDLL); } else {     printf("LoadLibrary: %d\n", GetLastError()); }  // 极其讨厌句柄指针当 bool 用的 if (hinstDLL) if (!hinstDLL)  // 极其讨厌 LONG 等当 bool 用的 // 虽然 ERROR_SUCCESS/NO_ERROR == 0 且代表成功 LONG lRet = RegOpenKeyEx(...); if (!lRet) // 个人习惯 if (lRet == ERROR_SUCCESS)  // 极其讨厌 HRESULT 等当 bool 用的 // 虽然 S_OK == 0 且代表成功 HRESULT hr = CoInitialize(NULL); if (!hr) // 个人习惯 if (hr == S_OK)  // case 不缩进，default 必写。 switch (uMsg) { case WM_COMMAND:     break; case WM_NOTIFY:     break; default:     break; }  // BOOL 结果当 bool 用 BOOL fResult = GetWindowRect(hwnd, &rc); if (fResult) {     // ... }  // 极其讨厌和 TRUE、FALSE 比较的 if (fResult == TRUE) if (fResult == FALSE) // 个人习惯 if (fResult) if (!fResult)  // 极其讨厌 C++ 程序员 NULL 当 0 用的，0 当 NULL 用的 // 虽然 C++ 定义 NULL 为 0 也不代表你可以随便滥用 MessageBox(0, TEXT("Hello C++!"), TEXT("Tip"), NULL); // 即便 MB_OK == 0 写一个 0 上去看着依然不舒服 MessageBox(NULL, TEXT("Hello C++!"), TEXT("Tip"), MB_OK);

bool Pattern::contain(const Pattern &rhs) const { 	// check bound intersect 	double left0,top0,right0,bottom0; 	double left1,top1,right1,bottom1; 	bound(left0,top0,right0,bottom0); 	rhs.bound(left1,top1,right1,bottom1); 	if(max(left0,left1) > min(right0,right1) 	 ||max(top0,top1) > min(bottom0,bottom1)) 		return false;  	// check line intersect 	vector<bezier_info> lhsInfo,rhsInfo; 	getPatternSegments(lines,lineUseIndex,lhsInfo); 	getPatternSegments(rhs.lines,rhs.lineUseIndex,rhsInfo);  	if(hasIntersect(lhsInfo,rhsInfo)) 		return false; 	 	return all_of(rhs.points.begin(),rhs.points.end(),[&](const decltype(*rhs.points.begin()) rpt )->bool{ 		INTERSECT_CONT cont; 		distcall_t d={nullptr,PAT_LINE_MINDIS,0}; 		return horzScan(rpt,cont,d); 	}); }

引用 3 楼 u013550545 的回复:[quote=引用 2 楼 user-10 的回复:] 个人的疯狂注释, 目的不是为了解释代码, 而是美化代码     // Buffer of MainWindow, align for 4(x86)     alignas(sizeof(void*)) size_t buffer[sizeof(MainWindow) / sizeof(size_t) + 1];     // 初始化 OLE (OLE会调用CoInitializeEx初始化COM)     if (SUCCEEDED(::OleInitialize(nullptr))) {         // 初始化 窗口管理器          if (SUCCEEDED(UIManager.Initialize(&config))) {             // 作战控制连线!             UIManager << DL_Hint << L"Battle Control Online!" << LongUI::endl;             // 创建主窗口             UIManager.CreateUIWindow<MainWindow>(test_xml, nullptr, buffer);             // 运行本程序             UIManager.Run();             // 作战控制终止!             UIManager << DL_Hint << L"Battle Control Terminated!" << LongUI::endl;         }         // 反初始化 窗口管理器         UIManager.UnInitialize();         // 反初始化 COM 与 OLE         ::OleUninitialize();      }     return EXIT_SUCCESS;代码的感觉很紧凑 ... 行代码也都不长 ... 前置括号写法嘛  ... 本noob试过一段时间 if {} 第一句依据紧贴的括号看起来太紧凑了 空一行感觉 有有太空了 注释跟语句交叉起来 看起来确实舒服的多 ...  话说我不喜欢在注释里面写中文 一方面是编码问题 还有的就是感觉中文写在里面有点调档次 (后面一句可以无视 ... - -!) ... 使用的库有 ATL的风格[/quote]  编码问题我现在全部使用UTF-8, 使用中文注释的原因恰恰是因为太好看了，英文注释的话， 乍一看，还以为是被临时注释掉的代码，看到中文注释，就100%保证是真正注释

引用 2 楼 user-10 的回复:个人的疯狂注释, 目的不是为了解释代码, 而是美化代码     // Buffer of MainWindow, align for 4(x86)     alignas(sizeof(void*)) size_t buffer[sizeof(MainWindow) / sizeof(size_t) + 1];     // 初始化 OLE (OLE会调用CoInitializeEx初始化COM)     if (SUCCEEDED(::OleInitialize(nullptr))) {         // 初始化 窗口管理器          if (SUCCEEDED(UIManager.Initialize(&config))) {             // 作战控制连线!             UIManager << DL_Hint << L"Battle Control Online!" << LongUI::endl;             // 创建主窗口             UIManager.CreateUIWindow<MainWindow>(test_xml, nullptr, buffer);             // 运行本程序             UIManager.Run();             // 作战控制终止!             UIManager << DL_Hint << L"Battle Control Terminated!" << LongUI::endl;         }         // 反初始化 窗口管理器         UIManager.UnInitialize();         // 反初始化 COM 与 OLE         ::OleUninitialize();      }     return EXIT_SUCCESS;代码的感觉很紧凑 ... 行代码也都不长 ... 前置括号写法嘛  ... 本noob试过一段时间 if {} 第一句依据紧贴的括号看起来太紧凑了 空一行感觉 有有太空了 注释跟语句交叉起来 看起来确实舒服的多 ...  话说我不喜欢在注释里面写中文 一方面是编码问题 还有的就是感觉中文写在里面有点调档次 (后面一句可以无视 ... - -!) ... 使用的库有 ATL的风格

#ifndef ___JOYPAD___INCLUDED__ #define ___JOYPAD___INCLUDED__  #include "iDinput8.hpp"  __declspec(align(16)) UINT32	Win_KEYS[8]; __declspec(align(16)) UINT32	AlignWinInputInfo[4]; // [0] : Locked [1]: counter [2]:InputBuffer [3]:for align just ~~  EXTERN_C OUTPUT NAKED VOID CDECL SetWinPadKeyMapper (PVOID pWinPadArray) { 	__asm { 		mov		eax, 		[esp+4] 		lea		ecx,		[Win_KEYS]  		lddqu	xmm0,		[eax] 		lddqu	xmm1,		[eax+16]  		movdqa	[ecx],		xmm0 		movdqa	[ecx+16],	xmm1  		ret 	} }  EXTERN_C OUTPUT	NAKED UCHAR CDECL GetKeyWinStatus() { 	__asm { 		movd	mm7,	esp 		movd	mm0,	ebp  		push 	ebx 		push 	esi  		lea 	ebp, 	[esp-20]	//	Stack offset correction 		push 	edi  		sub		esp,	276 		and 	ebp, 	-16			//	align 	16 	 	address  		mov 	esi, 	lpdikey		//	load 	com 	pointer 		sub 	ebp, 	256  		push	ebp 		push 	256  		mov 	edi, 	[esi]		// 		push 	esi  		call 	[edi+24h] 			// 									//  		cmp 	eax, 8007001Eh  	// Lost Input Device ? 		jne 	key_test 			// N:immed deal Key Message ..  		push 	esi 		call 	[edi+1Ch]  		test 	eax, eax 		jz		aget_dev_info  		__emit	0xFF 		__emit	0xAA  aget_dev_info: 		push 	esi 		call 	[edi+24h] 			//	Get Func Address from VfTable 									//	and call IDirectInputDevice8::GetDeviceState 		align 	16 key_test: 		lea 	esi,	[Win_KEYS] 		lea		ebp,	[ebp]  		mov		edx,	[esi] 		mov		ebx,	[esi+4] 		mov		edi,	[esi+8] 		mov		esp,	[esi+12]  		mov 	al, 	[ebp+edx] 		mov 	cl, 	[ebp+ebx] 		mov 	ah, 	[ebp+edi] 		mov 	ch, 	[ebp+esp]  		bswap 	eax 		bswap 	ecx  		mov		edx,	[esi+16] 		mov		ebx,	[esi+20] 		mov		edi,	[esi+24] 		mov		esp,	[esi+28]  		mov 	al, 	[ebp+edx] 		mov 	cl, 	[ebp+ebx] 		mov 	ah, 	[ebp+edi] 		mov 	ch, 	[ebp+esp]  		movd 		mm6, 	eax 		movd 		mm5, 	ecx  		movd		esp,	mm7 		punpckldq	mm5, 	mm6		//  		movd		ebp,	mm0 		pmovmskb 	eax, 	mm5 	// 	eax <- now  write mask delay  		mov		edi,	[esp-12] 		mov		esi,	[esp-8] 		mov		ebx,	[esp-4] 		ret 	} }


Question: 怎么把txt中的数据存入数组中

把原文件文件粘一部分出来，不要用图片，我需要复制数据

仅供参考：//NAME: essaie bla bla //DIMENSION: 8 //DATA //1  14  15 //2  11  10 //3  6   4 //4  7   13 //5  9   21 //6  19  3 //7  1   5 //8  8   8 //EOF // // 文本文件中可能还含有其他内容，但是需要用到的内容即以上  //比如data.txt: //NAME: essaie bla bla //其它内容 //DIMENSION: 8 //其它内容 //DATA //其它内容 //1  14  15 //其它内容 //2  11  10 //其它内容 //3  6   4 //其它内容 //4  7   13 //其它内容 //5  9   21 //其它内容 //6  19  3 //其它内容 //7  1   5 //其它内容 //8  8   8 //其它内容 //EOF  // 目标是要获取NAME后字串，DIMENSION后数值，以及DATA以下的数值 // 其中NAME就是随便个字句，DIMENSION是城市数量，DATA以下是城市编号，X坐标，Y坐标 // 所有的这些将赋值给一个事先定义好的结构 #include <stdio.h> #include <string.h> #define MAXCPL   80   //每行最大字符数 #define MAXCITY  100  //每组数据中DATA最多项数，DIMENSION的最大值 #define MAXNAMEL 32   //NAME最大长度 struct S {     char NAME[MAXNAMEL+1];     int  DIMENSION;     struct D {         int NO;         int X;         int Y;     } DATA[MAXCITY]; } s; FILE *f; int st,n,i; char ln[MAXCPL]; int main() {     f=fopen("data.txt","r");     if (NULL==f) {         printf("Can not open file data.txt!\n");         return 1;     }     st=0;     n=0;     while (1) {         if (NULL==fgets(ln,MAXCPL,f)) break;         if (st==0) {             if (1==sscanf(ln,"NAME: %32[^\n]",s.NAME)) st=1;         } else if (st==1) {             if (1==sscanf(ln,"DIMENSION: %d",&s.DIMENSION)) st=2;         } else if (st==2) {             if (0==strcmp(ln,"DATA\n")) st=3;         } else if (st==3) {             if (3==sscanf(ln,"%d%d%d",&s.DATA[n].NO,&s.DATA[n].X,&s.DATA[n].Y)) {                 n++;                 if (n>=MAXCITY || n>=s.DIMENSION) break;             }         }     }     fclose(f);     printf("s.NAME=[%s]\n",s.NAME);     printf("s.DIMENSION=%d\n",s.DIMENSION);     for (i=0;i<n;i++) {         printf("s.DATA[%d].NO,X,Y=%d,%d,%d\n",i,s.DATA[i].NO,s.DATA[i].X,s.DATA[i].Y);     }     return 0; } //s.NAME=[essaie bla bla] //s.DIMENSION=8 //s.DATA[0].NO,X,Y=1,14,15 //s.DATA[1].NO,X,Y=2,11,10 //s.DATA[2].NO,X,Y=3,6,4 //s.DATA[3].NO,X,Y=4,7,13 //s.DATA[4].NO,X,Y=5,9,21 //s.DATA[5].NO,X,Y=6,19,3 //s.DATA[6].NO,X,Y=7,1,5 //s.DATA[7].NO,X,Y=8,8,8


Question: c语言问题求助

明白了，谢谢大神

malloc为指针开辟动态堆内存空间 ，并用free进行释放。malloc开辟的空间不会由系统自动释放，所以需要用户自己用free去释放它，否则会造成内存泄露，不过当程序运行结束后，系统也会将这些内存回收

char *strcpy( char *strDestination, const char *strSource ); strcpy第一个参数是一个指针，其内存必需在调用strcpy之前开辟，否则会出现指针越界访问

你说的是strcpy吗？ 将后面参数的字符串数据复制到前面字符串中，以‘\0’结尾 malloc是开辟内存，并返回内存的首地址，不是复制内存。相当于我建一栋房子，告诉你地址，你就能通过我给你的地址找到访问它。sno[i]相当于一个地址函，记录内存的地址

再请问下什么情况要用malloc开空间呢，如果不malloc直接stcrpy，就会崩溃

引用 13 楼 ant2012 的回复:按照我贴的代码改，运行一下看看有没有问题  或者将pl->sno[i] = (char*)malloc(sizeof(char) * 10);改成 pl->sno[i] = (char*)malloc(sizeof(char) * pl->max);就能发挥m参数的作用了 好的，这个函数就是复制内存过去的吧？ 感谢大神帮助

大概了解了问题，可是这样怎么改呀

解决办法：  a->name[100]=(int )malloc(sizeof(int)*m); a->sno[10]=(char *)malloc(sizeof(char)*m); if(a->name&&a->sno) { a->max=m; a->n=0; printf("success to create\n"); return a; } else  { free(a); printf("free!"); }  改成 a->max=m; a->n=0; printf("success to create\n"); return a; 其它代码无意义，不可能到达  void insert(plist pl,int i,int x,char sno[10])中 pl->sno[i]=sno; 改为 pl->sno[i] = (char*)malloc(sizeof(char) * 10); strcpy(pl->sno[i], sno);  不过这样以来，create函数的参数m就没胡意义，如果要想其发生作用，可以在create对所有sno数组元素开辟内存空间，然后在insert函数中，只需strcpy复制插入的数据即可，而无需当场开辟内存空间

void insert(plist pl,int i,int x,char sno[10]) sno参数承接的是实参的地址，并没有发生数据的拷贝，即为x变量的地址，pl->sno[i]=sno;实际上是将x变量的地址给了sno。所以当再次插入值时，x变量的值被修改，从而sno[i]值也会修改

malloc returns a void pointer to the allocated space, or NULL if there is insufficient memory available. To return a pointer to a type other than void, use a type cast on the return value. The storage space pointed to by the return value is guaranteed to be suitably aligned for storage of any type of object. If size is 0, malloc allocates a zero-length item in the heap and returns a valid pointer to that item. Always check the return from malloc, even if the amount of memory requested is small.  说得通俗点，malloc是为指针开辟空间用的，因为指针在定义的时候，系统不会为其开辟内存空间。所以所有指针的大小都是机器字长的大小 （32位机的指针大小为4个字节）。指针变量存放的是其它变量的地址，malloc为指针开辟一个堆内存，此时指针的值为开辟内存的首地址。  void *malloc( size_t size );  malloc返回的是一个void指针，在使用malloc为各种类型的指针变量开辟空间时需要对其返回值进行强制转换 如：int *pi = (int*)malloc(sizeof(int) * n);     char *pc = (char*)malloc(sizeof(char) * n);  由于楼主定义的name是表态数组，不是指针，系统已经在定义时为其开辟了栈地址空间，不需要用malloc为其开辟堆空间

引用 7 楼 ant2012 的回复:[quote=引用 6 楼 taoxin78 的回复:] 我把对于结构体malloc的那两条指令直接注释掉，他依然能跑，没有任何区别  楼主好像没看懂我在3楼发的内容[/quote]  的确没太懂，malloc那部分是按照书上打的，书上没有写明是什么类型，写的是datatype，是泛泛的一种类型的意思我觉得，学生自学，不太清楚这部分内容，同样的写法不同的结果让我很诧异，小白求说的更简单一点

引用 6 楼 taoxin78 的回复:我把对于结构体malloc的那两条指令直接注释掉，他依然能跑，没有任何区别  楼主好像没看懂我在3楼发的内容

我把对于结构体malloc的那两条指令直接注释掉，他依然能跑，没有任何区别

可能是字符串内存地址共用的问题，楼主可以把改好后的代码贴出来，方便我们去查错

我是那个顺序表的提问者，可能之前的开辟空间有问题，但是我改了改并没有用 同是一个结构体下的int[]和char *[]，做出的反应不同，例如我输入 sno为aa name为4，他插入，查询打印的是aa 4，此时我再插入，比如插入在之前参数之后，bb 5，他查询打印的是 bb 4，bb 5，如果插入之前，就是bb 5，bb4，也就是说，数字int插入的是正确的，而输入的字符串，不正确，但是写法都是一样的啊

楼主，你是不是前面出问题了 a->name[100]=(int )malloc(sizeof(int)*m); 开辟m个整形的int型的连续内存给name数组中下标值为100的元素。 1. 下标值100已经越界，name是一个静态数组，其长度为100，下标值范围为0~99。 2. name是一个静态数组，其元素也是普通int型变量，当实例化一个结构体对象时，即楼主plist a=(plist)malloc(sizeof(struct list));操作系统已经为其开辟了栈空间，无需在通过malloc给其某个元素开辟动态堆空间。 3. 此时name[100]（可能已经是sno中的元素）存放的是由malloc开辟的m个连续内存的首地址  a->sno[10]=(char *)malloc(sizeof(char)*m); sno是一个指针数组，即sno是一个静态数组，只不过其元素是一个字符型指针 以上这句代码的意思是为sno第11个元素（即下标值为10）开辟一个一个由m个char型组成的内存空间，sno[10]存放的是开辟空间的首地址。然而sno中其它元素由于没有指向有效的内存地址，都处于野指针状态  总之，楼主好像对数组和指针的概念不是很清楚

额，我的意思是，在红字部分的操作，如果是int[]型的进行循环传递就没问题，但是如果是字符串char *[]就会将后面的数据覆盖前面的，而不是一一替换，实在不理解操作一样结果不同是因为什么

凑凑热闹，代码如下，详细过程参见 http://blog.csdn.net/a_flying_bird/article/details/47132415  /* see: http://bbs.csdn.net/topics/391091587 */  #include <stdio.h> #include <stdlib.h> #include <string.h> #include <assert.h>  struct node {     int max_count;     int current_count;     int id[100];     char *name[100]; };  typedef struct node *pnode;  //创建一个空的顺序表，最大值为m。n为0 pnode create(int max_count) {     pnode node = (pnode)malloc(sizeof(struct node));     if (NULL == node) {         printf("failed to create!");         return NULL;     }          node->max_count = max_count;     node->current_count = 0;     printf("success to create\n");          return node; }  //查询一个表是否为空表 int is_empty(pnode pnode) {     if (pnode->current_count == 0) {         //printf("empty\n");         return 1;     }      //printf("not empty\n");     return 0; }  //插入一个信息到顺序表,插入到第index个元素之前 void insert(pnode pnode, int index, int id, char name[10]) {     if (index < 0 || index > pnode->current_count) index = pnode->current_count;          for(int q = pnode->current_count - 1; q >= index; q--) {         pnode->id[q + 1] = pnode->id[q];         pnode->name[q + 1] = pnode->name[q];     }          pnode->current_count++;     pnode->id[index] = id;     //pnode->name[index] = strdup(name); #MinGW's error     pnode->name[index] = (char*)malloc(sizeof(char) * sizeof(strlen(name) + 1));     if (NULL == pnode->name[index]) {         printf("malloc failed.\n");     } else {         strcpy(pnode->name[index], name);     }          //return pnode; }  int visit(pnode pnode) {     int i;          if (is_empty(pnode)) return 0;          for (i = 0; i < pnode->current_count; i++) {         printf("%d:[%d, %s] ", i, pnode->id[i], pnode->name[i]);     }          printf("\n"); }  void delete(pnode pnode) {     int i;     for (i = 0; i < pnode->current_count; i++) {         free(pnode->name[i]);         pnode->name[i] = NULL;     }          pnode->current_count = 0; }  static void test1() {        pnode pnode;     char buffer[1024]; // Assume the input string will not exceed 1024.     char name[1024];     int loc = -1;     int id = -1;     int max_count = 10;     int current_count = 0;     pnode = create(max_count);          if (NULL == pnode) return;          while(1) {         printf("Please enter: [name, id, index]. Enter directly to exit.\n");                  int index = 0;         for (; (buffer[index] = getchar()) != '\n' && index < 1024; index++) {             //printf("index=%d, buffer[%d]=0x%02x\n", index, index, buffer[index]);         }                  //printf("index=%d\n", index);                  if (index == 0) {             break;         }                  //printf("User's input: %s\n", buffer);                  if (3 != sscanf(buffer, "%s %d %d", &name, &id, &loc)) {             printf("Error input. The input should be, e.g., \"John 35 0\"\n");             continue;         }                  insert(pnode, loc, id, name);                  visit(pnode);                  current_count++;         if (current_count == max_count) {             printf("Now is the max count! Stop automatically!\n");             break;         }     }          delete(pnode); }  int main() {     test1();          return 0; }


Question: leetcode plus one in c

引用 18 楼 chengye_xin 的回复:话说楼主你这道题目PASS了么，遇到你一样的问题了，刚刚AC。  函数形参里面的那个int * returnSize 应该是你返回的int数组的长度。 A了，觉得很多题目用c写的难度远远大于题本身的难度

引用 14 楼 fly_dragon_fly 的回复:[quote=引用 13 楼 zhao4zhong1 的回复:] 其实最好的策略应该是在digits中将各位数字倒着存放。这样就可以避免有进位时还得逐位拷贝了。  No program run faster than no program!《观止-微软创建NT和未来的夺命狂奔》拷那么多注释何必了, 看看题要求吧 Note: The returned array must be malloced, assume caller calls free(),如果digits是栈地址,怎么realloc[/quote] 你见过哪段代码将栈地址在参数中用指针传递？ malloced的意思就是调用malloc函数？！ 千句解释不如一句举例。

我说“千句解释不如一句举例。”的意思不是让你给我举“将栈地址在参数中用指针传递”的例子。 是说我注释中将函数功能解释和举例的很到位，如果不举例，只有解释是会被不同的人理解成不同具体实现的。  你竟然可以象下面这样理解： The returned array must be malloced, but the parameter digits can be global variable's address or local variable's address or alloca memory's address ?! 那你就只能后果自负了。

引用 15 楼 zhao4zhong1 的回复:[quote=引用 14 楼 fly_dragon_fly 的回复:] [quote=引用 13 楼 zhao4zhong1 的回复:] 其实最好的策略应该是在digits中将各位数字倒着存放。这样就可以避免有进位时还得逐位拷贝了。  No program run faster than no program!《观止-微软创建NT和未来的夺命狂奔》拷那么多注释何必了, 看看题要求吧 Note: The returned array must be malloced, assume caller calls free(),如果digits是栈地址,怎么realloc[/quote] 你见过哪段代码将栈地址在参数中用指针传递？ malloced的意思就是调用malloc函数？！ 千句解释不如一句举例。[/quote]栈地址还要举例, 那就再举一下 int a[]={1,2,3}, la; plus(a,3,&la); 觉得栈地址不好,那就定义成全局.

引用 13 楼 zhao4zhong1 的回复:其实最好的策略应该是在digits中将各位数字倒着存放。这样就可以避免有进位时还得逐位拷贝了。  No program run faster than no program!《观止-微软创建NT和未来的夺命狂奔》拷那么多注释何必了, 看看题要求吧 Note: The returned array must be malloced, assume caller calls free(),如果digits是栈地址,怎么realloc

引用 10 楼 fly_dragon_fly 的回复:[quote=引用 7 楼 u012042752 的回复:] [quote=引用 4 楼 fly_dragon_fly 的回复:] 模拟加1是吧, 本地能够通过就奇怪了, returnSize不对,这个是用来返回长度, 你用来放数字了.我想本地能够通过的就是这样 int a[]={1,2,3},la=3; plus(a,la,&la), 改成la=1234;plus(a,3,&la) 或者试试int a[]={9,9,9},就是需要进位的时候然而本地0，9，｛9，9，9｝都通过了[/quote]可能测试代码有问题, 999是不可能通过测试的,不过既然已经结贴就不评论了,赵四的break是错的,那本来就不应该叫count,是carry,下面重写一下 // if (count==1) *returnSize=digitsSize+count; int *rd =malloc(*returnSize*sizeof(*rd)); if(count) rd[0] =1; memcpy(rd+count,digits,digitsSize*sizeof(*rd)); return rd;[/quote] 返回新malloc的rd了，原来digits不free？内存泄露了！ 新malloc，你还得memcpy，不嫌费劲吗？ 这里应该用realloc realloc Reallocate memory blocks.  void *realloc( void *memblock, size_t size );  Routine Required Header Compatibility  realloc <stdlib.h> and <malloc.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  realloc returns a void pointer to the reallocated (and possibly moved) memory block. The return value is NULL if the size is zero and the buffer argument is not NULL, or if there is not enough available memory to expand the block to the given size. In the first case, the original block is freed. In the second, the original block is unchanged. The return value points to a storage space that is guaranteed to be suitably aligned for storage of any type of object. To get a pointer to a type other than void, use a type cast on the return value.  Parameters  memblock  Pointer to previously allocated memory block  size  New size in bytes  Remarks  The realloc function changes the size of an allocated memory block. The memblock argument points to the beginning of the memory block. If memblock is NULL, realloc behaves the same way as malloc and allocates a new block of size bytes. If memblock is not NULL, it should be a pointer returned by a previous call to calloc, malloc, or realloc.  The size argument gives the new size of the block, in bytes. The contents of the block are unchanged up to the shorter of the new and old sizes, although the new block can be in a different location. Because the new block can be in a new memory location, the pointer returned by realloc is not guaranteed to be the pointer passed through the memblock argument.  realloc calls malloc in order to use the C++ _set_new_mode function to set the new handler mode. The new handler mode indicates whether, on failure, malloc is to call the new handler routine as set by _set_new_handler. By default, malloc does not call the new handler routine on failure to allocate memory. You can override this default behavior so that, when realloc fails to allocate memory, malloc calls the new handler routine in the same way that the new operator does when it fails for the same reason. To override the default, call   _set_new_mode(1)  early in your program, or link with NEWMODE.OBJ.  When the application is linked with a debug version of the C run-time libraries, realloc resolves to _realloc_dbg. For more information about how the heap is managed during the debugging process, see Using C Run-Time Library Debugging Support.  Example  /* REALLOC.C: This program allocates a block of memory for  * buffer and then uses _msize to display the size of that  * block. Next, it uses realloc to expand the amount of  * memory used by buffer and then calls _msize again to  * display the new amount of memory allocated to buffer.  */  #include <stdio.h> #include <malloc.h> #include <stdlib.h>  void main( void ) {    long *buffer;    size_t size;     if( (buffer = (long *)malloc( 1000 * sizeof( long ) )) == NULL )       exit( 1 );     size = _msize( buffer );    printf( "Size of block after malloc of 1000 longs: %u\n", size );     /* Reallocate and show new size: */    if( (buffer = realloc( buffer, size + (1000 * sizeof( long )) ))          ==  NULL )       exit( 1 );    size = _msize( buffer );    printf( "Size of block after realloc of 1000 more longs: %u\n",              size );     free( buffer );    exit( 0 ); }   Output  Size of block after malloc of 1000 longs: 4000 Size of block after realloc of 1000 more longs: 8000   Memory Allocation Routines  See Also   calloc, free, malloc

引用 10 楼 fly_dragon_fly 的回复:[quote=引用 7 楼 u012042752 的回复:] [quote=引用 4 楼 fly_dragon_fly 的回复:] 模拟加1是吧, 本地能够通过就奇怪了, returnSize不对,这个是用来返回长度, 你用来放数字了.我想本地能够通过的就是这样 int a[]={1,2,3},la=3; plus(a,la,&la), 改成la=1234;plus(a,3,&la) 或者试试int a[]={9,9,9},就是需要进位的时候然而本地0，9，｛9，9，9｝都通过了[/quote]可能测试代码有问题, 999是不可能通过测试的,不过既然已经结贴就不评论了,赵四的break是错的,那本来就不应该叫count,是carry,下面重写一下 // if (count==1) *returnSize=digitsSize+count; int *rd =malloc(*returnSize*sizeof(*rd)); if(count) rd[0] =1; memcpy(rd+count,digits,digitsSize*sizeof(*rd)); return rd;[/quote] 谢谢，昨天自己改了改通过了

引用 7 楼 u012042752 的回复:[quote=引用 4 楼 fly_dragon_fly 的回复:] 模拟加1是吧, 本地能够通过就奇怪了, returnSize不对,这个是用来返回长度, 你用来放数字了.我想本地能够通过的就是这样 int a[]={1,2,3},la=3; plus(a,la,&la), 改成la=1234;plus(a,3,&la) 或者试试int a[]={9,9,9},就是需要进位的时候然而本地0，9，｛9，9，9｝都通过了[/quote]可能测试代码有问题, 999是不可能通过测试的,不过既然已经结贴就不评论了,赵四的break是错的,那本来就不应该叫count,是carry,下面重写一下 // if (count==1) *returnSize=digitsSize+count; int *rd =malloc(*returnSize*sizeof(*rd)); if(count) rd[0] =1; memcpy(rd+count,digits,digitsSize*sizeof(*rd)); return rd;

引用 5 楼 zhao4zhong1 的回复:楼主找找差距吧： /**  * array digits[0..digitsSize-1] store a long decimal digits  * function plusOne plus 1 to it.  * whether carried or not, resize or not resize digits, return new size to *returnSize  # For example:  *     if digits[2]={9,8} plusOne return digits[2]={9,9} and *returnSize=2  *     if digits[2]={9,9} plusOne return digits[3]={1,0,0} and *returnSize=3  * Note: The returned array must be malloced, assume caller calls free().  */ int* plusOne(int* digits, int digitsSize, int* returnSize) {     int i;     int count=1;     int *digits1;      assert(digits);     assert(digitsSize>0);     assert(returnSize);     for (i=digitsSize-1;i>=0;i--) {         int a = digits[i] + count;         digits[i] = a % 10;         count = a / 10;         if (0==count) break;     }     if (count==1) {         digitsSize++;         digits1 =(int*)realloc(digits,sizeof(int)*digitsSize);         assert(digits1);         for (i=digitsSize-2; i>=0; i--) digits1[i+1]=digits1[i];         digits1[0]=1;         *returnSize=digitSize;         return digits1;     } else {         *returnSize=digitSize;         return digits;     } } 谢谢，正在努力缩小差距：）

引用 6 楼 mewiteor 的回复:Return an array of size *returnSize. *returnSize是用来记录返回数组的大小的,大概测试程序将*returnSize初始化为0了,这样Output会永远为空. 应该是: count==1时,*returnSize=digitsSize+1; count==0时,*returnSize=digitsSize; 不要改变returnSize,只能改变*returnSize. 另外定义一个int型指针用于返回.好像明白一点了，3ks～

引用 4 楼 fly_dragon_fly 的回复:模拟加1是吧, 本地能够通过就奇怪了, returnSize不对,这个是用来返回长度, 你用来放数字了.我想本地能够通过的就是这样 int a[]={1,2,3},la=3; plus(a,la,&la), 改成la=1234;plus(a,3,&la) 或者试试int a[]={9,9,9},就是需要进位的时候然而本地0，9，｛9，9，9｝都通过了

不明白要干吗

input [0] 在执行到if(count == 1)时，digits[0] = 1没错，可是此时count = 0，程序直接跳到else中 此时returnSize未初始化，我估计leetcode是通过returnSize的值来取返回值

不明白要完成什么功能。


Question: int x=s.top();if(x

s是优先队列, 在stl中就是堆了, 通常是建立大顶堆, 这里用的greater, 就是小顶堆, s.top指的就是当前最小的元素

VS IDE中，在不明白的符号上点鼠标右键，选转到定义。

来人来人来人吧

求解求解求解～


Question: 关于cpu的流水线，为何写寄存器在时钟周期的前半段，而读寄存器在后半段

因为必须先存入上一个指令的值，然后才可以读从寄存器文件中读取下一个指令的值

那就不能上条指令写完后再开始本条指令读吗？


Question: QT中开辟二维数组出错

还有malloc次数多了，记录信息就多，会产生内存碎片。

动态分配，可以动态调整容量啊。

引用 8 楼 love1code 的回复:你这开辟的其实都是一维数组。只不过先开辟的是一个指针数组，在给数组里的指针分配新的内存。 释放起来很麻烦。 真正的动态分配2维数组。我一般这样写 int main (void) { 	int i,j; 	float(*t)[5]=(float(*)[5])malloc(sizeof(float)*5*3); 	//5代表列数，3是行数  	for(i=0;i<3;++i) 	 for(j=0;j<5;++j) 	   t[i][j]=1.0; 	 	 	//这样free一下就OK了  	free(t); 	return 0; } 不是方法问题，而是开辟的容量大小

为何不用QVector?

QT最好不要使用malloc/free,控制不好生命周期的话，bug都不知道在哪里，还是用new/delete。  原谅我没看代码打个酱油

可不可以告诉我哪里错了以及为什么会错

引用 2 楼 zhao4zhong1 的回复:小心驶得万年船！ float **count; float **t;     count=(float **)malloc(sizeof(float *)*72628L);     if (count) {         long int i;         for (i=0;i<72628L;i++) {             count[i]=(float *)malloc(sizeof(float)*73251L);             if (NULL==count[i]) {                 while (1) {                     i--;                     free(count[i]);                     if (i==0) break;                 }                 break;             }         }         if (i<72628L) {             free(count);             count=NULL;         }     }     if (count) {         t=(float **)malloc(sizeof(float *)*72628L);         if (t) {             long int i;             for (i=0;i<72628L;i++) {                 t[i]=(float *)malloc(sizeof(float)*73251L);                 if (NULL==t[i]) {                     while (1) {                         i--;                         free(t[i]);                         if (i==0) break;                     }                     break;                 }             }             if (i<72628L) {                 free(t);                 t=NULL;             }         }         if (t) {             //use count and t             //...             //...              //free t             for (long int i=0;i<72628L;i++) free(t[i];             free(t);             t=NULL;              //free count             for (long int i=0;i<72628L;i++) free(count[i];             free(count);             count=NULL;         } else {             printf("Can not malloc t!\n");             //free count             for (long int i=0;i<72628L;i++) free(count[i];             free(count);             count=NULL;         }     } else {         printf("Can not malloc count!\n");     }   赵老师终于出手了

float **count; float **t;   count=(float **)malloc(sizeof(float *)*72628);//根据两个vector大小创建count数组   for(int i=0;i<72628;i++)         count[i]=(float *)malloc(sizeof(float)*73251);    t=(float **)malloc(sizeof(float *)*144616);//创建t变量数组         ////出错位置    for(int i=0;i<72628;i++)         t[i]=(float *)malloc(sizeof(float)*144616);       这个更大为什么反而可以，求解


Question: makefile 的内嵌函数的$(strip

搜“跟我一起写makefile”

iles := $(strips($files))    :=  $(strip $(files))


Question: vfork创建子进程，子进程退出后释放内存空间

昨天才知道了真正的原因，当case0结束后使用的是break，最后没有执行任何语句，则最后退出时默认使用return来退出，而return相当于一个函数的退出，一个函数的退出会释放局部变量，也就是栈内存中的变量，所以会产生这样的结果，而如果在最后使用exit退出则不会释放栈内存，大概就这样，关于进程的退出，可以看我的博客 blog.csdn.net/zhuxinquan61/article/details/47143313

楼主做些尝试了解vfork是可以的，但是vfork只应该调用exec族函数和_exit, 而且不能修改任何变量(接收vfork返回值的变量除外)，否则结果是不确定的。 NAME      vfork - create new process; share virtual memory    SYNOPSIS        #include <unistd.h>      pid_t vfork(void);   DESCRIPTION      The vfork() function has the same effect as fork(), except that the behaviour is undefined if the process created by vfork() either modifies any data other than a variable of type pid_t used to store the return value from vfork(), or returns from the function in which vfork() was called, or calls any other function before successfully calling _exit() or one of the exec family of functions.

百度百科的解释：  子进程在vfork()返回后直接运行在父进程的栈空间，并使用父进程的内存和数据。这意味着子进程可能破坏父进程的数据结构或栈，造成失败。 为了避免这些问题，需要确保一旦调用vfork()，子进程就不从当前的栈框架中返回，并且如果子进程改变了父进程的数据结构就不能调用exit函数。子进程还必须避免改变全局数据结构或全局变量中的任何信息，因为这些改变都有可能使父进程不能继续。

最后我又做了尝试，因为子进程是在break;之后退出的，算作是非正常退出，在其后添加exit(0)之后就不会出现这种随机数了，也就是说，虽然子进程同样会改变父进程使用的变量的值，但是随机数的出现并非是内存释放，而是异常退出导致子进程的数据不正常，也就顺带导致了父进程内存区域的值的改变


Question: C语言main函数char数组的问题

输入一个字符串，都是把地址传给printf啊，不过，也可以遍历输出。如 char arr[] = "asdfsd"; printf("%s\n", arr); arr就是数组的首地址。 当采用%s输出字符串时，函数printf通过字符串的首地址和’\0‘来确定其范围

基本功不扎实

理解和讨论之前请先学会如何观察！  计算机组成原理→DOS命令→汇编语言→C语言（不包括C++）、代码书写规范→数据结构、编译原理、操作系统→计算机网络、数据库原理、正则表达式→其它语言（包括C++）、架构……  对学习编程者的忠告： 多用小脑和手，少用大脑、眼睛和嘴，会更快地学会编程！ 眼过千遍不如手过一遍！ 书看千行不如手敲一行！ 手敲千行不如单步一行！ 单步源代码千行不如单步Debug版对应汇编一行！ 单步Debug版对应汇编千行不如单步Release版对应汇编一行！  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",...);或者cout<<...】来理解指针的本质， 而要依赖调试时的反汇编窗口中的C/C++代码【比如void *p=(void *)(...);】及其对应汇编指令以及内存窗口中的内存地址和内存值来理解指针的本质。  这辈子不看内存地址和内存值；只画链表、指针示意图，画堆栈示意图，画各种示意图，甚至自己没画过而只看过书上的图……能从本质上理解指针、理解函数参数传递吗？本人深表怀疑！ 这辈子不种麦不收麦不将麦粒拿去磨面；只吃馒头、吃面条、吃面包、……甚至从没看过别人怎么蒸馒头，压面条，烤面包，……能从本质上理解面粉、理解面食吗？本人深表怀疑！！  提醒： “学习用汇编语言写程序” 和 “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

这种叫格式化输出。C规定，如果是%s就要把输出对象当作字符串。我们知道，字符串实际上是带串尾符的字符数组，所以字符串的指针实际上就是这个数组的首地址。输出时，就顺次把字符全部输出了。

%s对应字符串,字符串的值就是其首地址.


Question: 【C语言】关于typedef 对结构变量的用法

typedef   就是把一种类型定义 成另外一个名字而已 struct LNode{ Elemtype date; struct LNode* next; } 就是一个结构体定义 类似于  { typedef   int INT，*PINT； 等价于 typedef   int INT； typedef   int *PINT；  然后理解INT  i；   就是  int i； PINT  p      ；  就是int　＊ｐ；就行了 }

typedef 结构体 自定义名 然后那个自定义名就等同那个结构体

LNode还是LNode，LinkList是LNode*的别名。 以下声明等效：LinkList a;  LNode* a;


Question: C语言结构体数组遍历

struct Name {     const int Base_Class1;     const int  Sub_Class1;     const int  Interface1;     const char  *Meaning1; } mean[17]={     {0x00,0x00,0x00,"All currently implemented devices"},     {0x00,0x01,0x00,"VGA-compatible device"},     {0x01,0x01,0x80,"IDE controller"},     {0x01,0x80,0x00,"Other mass storage controller"},     {0x02,0x00,0x00,"Ethernet controller"},     {0x02,0x80,0x00,"Other network controller"},     {0x03,0x00,0x00,"VGA-compatible controller"},     {0x03,0x80,0x00,"Other display controller"},     {0x06,0x00,0x00,"Host bridge"},     {0x06,0x01,0x00,"ISA bridge"},     {0x06,0x04,0x00,"PCI-to-PCI bridge"},     {0x06,0x04,0x01,"Subtractive Decode PCI-to-PCI bridge"},     {0x06,0x07,0x00,"CardBus bridge"},     {0x0c,0x00,0x10,"IEEE 1394 OpenHCI"},     {0x0c,0x03,0x00,"USB Universal Host Controller"},     {0x0c,0x03,0x20,"Intel USB2 Enhanced Host Controller"},     {0x0c,0x05,0x00,"SMBus"}, }; int i; for (i=0;i<17;i++)     if (Base_Class == mean[i].Base_Class1      &&  Sub_Class == mean[i]. Sub_Class1      &&  Interface == mean[i]. Interface1) break; if (i<17) puts(mean[i].Meaning1); else printf("%s\t","Unknow Device");

for(i=0;i<17;i++) {     if(Base_Class == mean[i].Base_Class1 && Sub_Class == mean[i].Sub_Class1 && Interface == mean[i].Interface1)     {         puts(mean[i].Meaning1);         break;     } } if(i == 17)     printf("%s\t","Unknow Device");

这不对吧？不知道你理解我程序想做什么么？

BOOL bl =flase; for() { if(true) { bl = true; break; } }  if(!bl) {printf(); }


Question: 如何将数字字符串转为16进制字符串？

没有最好，只有更好！ //如何将数字字符串转为16进制字符串？ //字符串：char str[20]=“1234567890123456”; //将中间的“789012”转换为16进制的“0C0A14”； //最后str="1234560C0A143456" #include <stdio.h> int main() {     char str[20]="1234567890123456";     int v;     char c;      sscanf(str+6,"%6d",&v);     c=str[12];     sprintf(str+6,"%06X",v);     str[12]=c;     printf("[%s]\n",str);      return 0; } //[1234560C0A143456] //

非常感谢，写的太好了。

转换：      char src[] = "789012";     int srclen = strlen(src);      int a = atoi(src);      char format[256];     sprintf(format, "%%0%dX", srclen);      char dest[256];     sprintf(dest, format, a);


Question: 一个宏的笔试题帮我看看！

引用 2 楼 fly_dragon_fly 的回复:直接展开 ++Z ++Y*X/2 ++X+3*X/2 ++a%4+3*a%4/2 展开后存在求值顺序问题, 不对答案作评价 引用 9 楼 lin5161678 的回复:题目是错的 结果没有意义  看置顶帖 ++

引用 7 楼 zhangxiangDavaid 的回复:[quote=引用 5 楼 w2276190 的回复:] ++a%4+3*a%4/2 宏 直接替换，然后看优先级 * / % +  ++  所以+后面是（3*10）%（4/2）=0 然后算 a%4=10%4=2 ++2=3. 新手共同进步，这个主要考的是优先级的，你可以再看看优先级的资料，记住就行了。 ++优先级高于*[/quote] 谢谢提醒。

引用 6 楼 baidu_30054729 的回复:++a%4+3*a%4/2 第一步++a = 11； a = 11； 第二步:++a%4 = 3； //第一部分值为3 第三步：3*11%4/2 = 0;  //计算就出来了 3+0=3 优先级很多，主要看他是几元运算符，++只有一个操作数，优先级就高。 感谢！

引用 7 楼 zhangxiangDavaid 的回复:[quote=引用 5 楼 w2276190 的回复:] ++a%4+3*a%4/2 宏 直接替换，然后看优先级 * / % +  ++  所以+后面是（3*10）%（4/2）=0 然后算 a%4=10%4=2 ++2=3. 新手共同进步，这个主要考的是优先级的，你可以再看看优先级的资料，记住就行了。 ++优先级高于*[/quote]你的这种算法不理解，* / %是同级的

看了置顶帖这个问题就没有意义了 不过，如果是做题的话，把计算优先级搞清楚就好 如果是自己写代码，你确定类似这种代码提交上去不罚款？

题目是错的 结果没有意义  看置顶帖

%的优先级与乘除是一样的呀

引用 5 楼 w2276190 的回复:++a%4+3*a%4/2 宏 直接替换，然后看优先级 * / % +  ++  所以+后面是（3*10）%（4/2）=0 然后算 a%4=10%4=2 ++2=3. 新手共同进步，这个主要考的是优先级的，你可以再看看优先级的资料，记住就行了。 ++优先级高于*

引用 2 楼 fly_dragon_fly 的回复:直接展开 ++Z ++Y*X/2 ++X+3*X/2 ++a%4+3*a%4/2 展开后存在求值顺序问题, 不对答案作评价 算下来答案怎么都应该是4,啊，你算了多少？

楼上正解！！！！

全部展开 printf ("%d", ++a％4+3*a%4/2);


Question: 哪位大牛帮忙看下这个

那这应该是我的机子问题了，可是问题出在哪啊。。

本机测试, 无任何问题 另外: 1:  char result[1024 * 40] = "";  没错, 将第一个字节置0;          不过, 将 40K 的大小作局部变量放在栈中真的合适么, 不怕溢出? 2:  	   char buffer[1024] ;  if (fgets(buffer, 1280, pipe)) //   怎么超过分配在大小了

引用 1 楼 user-4 的回复:see_ip 中 char result[1024 * 40] = "";  改成 char result[1024 * 40] = {0}; ""; 指向一个常量地址， 常量地址不能被赋值， 调用execmd报错 不要误导别人好不好，看清楚什么才叫常量指针	char* cbuf = "123456"; 	char vbuf[] = "123456";

多谢两位。。我去试试

崩溃的时候在弹出的对话框按相应按钮进入调试，按Alt+7键查看Call Stack即“调用堆栈”里面从上到下列出的对应从里层到外层的函数调用历史。双击某一行可将光标定位到此次调用的源代码或汇编指令处，看不懂时双击下一行，直到能看懂为止。


Question: gcc抽风了， gcc搜索库目录的路劲是哪一个？

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