Question: 有木有大神帮帮忙调一下这个程序呀，好急的呀

我也是这个实验

你现在还有这个实验吗

再供参考： 递归转非递归指南：http://www.codeproject.com/Articles/418776/How-to-replace-recursive-functions-using-stack-and

不要依赖调试器输出复杂数据结构！而要将复杂数据结构的整个内容在处理它的每一步使用一小段代码按自己很容易理解的格式输出，非常有助于调试！或者可以说是“基础设施” 参考下面：//不带表头结点的单向链表 #include <stdio.h> #include <stdlib.h> #include <malloc.h> #include <time.h> #include <locale.h> struct NODE {     int          data;     struct NODE *next; } *head,*p,*q,*s,*p1,*p2,*q1,**ta; int i,k,n,t,m,v,N=10; int main() {     setlocale(LC_ALL,"chs");     srand(time(NULL));      head=NULL;      printf("创建%d个节点的单链表:",N);//创建N个节点的单链表     p=head;     for (i=0;i<N;i++) {         q=(struct NODE *)malloc(sizeof(struct NODE));         if (NULL==q) exit(1);         q->data=rand()%100;//填写0..99的随机值         q->next=NULL;         if (NULL==p) {             head=q;             p=head;         } else {             p->next=q;             p=q;         }     }      //输出整个单链表     s=head;     while (1) {         if (NULL==s) {             printf("\n");             break;         }         printf("%02d->",s->data);         s=s->next;     }      k=3;     v=5;     printf("将值为%d的结点插入到单链表的第%d个结点前:",v,k);//将值为v的结点插入到单链表的第k个结点前     n=0;     p=head;     while (1) {         if (NULL==p) {             break;         }         n++;         if (k==1) {             q=(struct NODE *)malloc(sizeof(struct NODE));             if (NULL==q) exit(1);             q->data=v;             q->next=head;             head=q;             break;         } else {             if (k-1==n) {                 q=(struct NODE *)malloc(sizeof(struct NODE));                 if (NULL==q) exit(1);                 q->data=v;                 q->next=p->next;                 p->next=q;                 break;             }         }         p=p->next;     }      //输出整个单链表     s=head;     while (1) {         if (NULL==s) {             printf("\n");             break;         }         printf("%02d->",s->data);         s=s->next;     }      k=5;     printf("删除第%d个节点:",k);//删除第k个节点     n=0;     p=head;     while (1) {         if (NULL==p) {             break;         }         n++;         if (k==1) {             q=head;             head=head->next;             free(q);             break;         } else {             if (k-1==n) {                 q=p->next;                 if (q) {                     p->next=q->next;                     free(q);                 }                 break;             }         }         p=p->next;     }      //输出整个单链表     s=head;     while (1) {         if (NULL==s) {             printf("\n");             break;         }         printf("%02d->",s->data);         s=s->next;     }      printf("从小到大排序:");//从小到大排序     for (p=head,p1=NULL;p!=NULL;p1=p,p=p->next) {         for (q=p->next,q1=p;q!=NULL;q1=q,q=q->next) {             if (p->data > q->data) {                  //交换data //              printf("swap %02d %02d\n",p->data,q->data); //              t=p->data;p->data=q->data;q->data=t;                  //或者                  //交换next //              printf("swap %02d %02d\n",p->data,q->data);                 if (p==head) {//p是头                     if (p->next==q) {//pq挨着                         head=q;                         p->next=q->next;                         q->next=p;                         q=p;                         p=head;                     } else {//pq不挨着                         head=q;                         p2=p->next;                         p->next=q->next;                         q->next=p2;                         q1->next=p;                         q=p;                         p=head;                     }                 } else {//p不是头                     if (p->next==q) {//pq挨着                         p1->next=q;                         p->next=q->next;                         q->next=p;                         q=p;                         p=p1->next;                     } else {//pq不挨着                         p1->next=q;                         p2=p->next;                         p->next=q->next;                         q->next=p2;                         q1->next=p;                         q=p;                         p=p1->next;                     }                 }                  //输出整个单链表 //              s=head; //              while (1) { //                  if (NULL==s) { //                      printf("\n"); //                      break; //                  } //                  printf("%02d->",s->data); //                  s=s->next; //              } //              getchar();             }         }     }      //输出整个单链表并计算链表长度n     n=0;     s=head;     while (1) {         if (NULL==s) {             printf("\n");             break;         }         printf("%02d->",s->data);         n++;         s=s->next;     }      printf("将整个链表逆序:");//将整个链表逆序     if (n>=2) {         p=head;         q=p->next;         p->next=NULL;         while (1) {             q1=q->next;             q->next=p;             p=q;             q=q1;             if (NULL==q) break;         }         head=p;     }      //输出整个单链表     s=head;     while (1) {         if (NULL==s) {             printf("\n");             break;         }         printf("%02d->",s->data);         s=s->next;     }      m=4;     n=6;     printf("将单链表中前%d个结点和后%d个结点进行互换:",m,n);//将单链表中前m个结点和后n个结点进行互换,m+n为链表总长     k=0;     p=head;     while (1) {         if (NULL==p) {             break;         }         k++;         if (m==k) {             q=p;         }         s=p;         p=p->next;     }     q1=head;     head=q->next;     s->next=q1;     q->next=NULL;      //输出整个单链表     s=head;     while (1) {         if (NULL==s) {             printf("\n");             break;         }         printf("%02d->",s->data);         s=s->next;     }      //释放所有节点     p=head;     while (1) {         if (NULL==p) {             break;         }         q=p->next;         free(p);         p=q;     }      return 0; } //创建10个节点的单链表:08->74->07->23->03->99->31->56->88->16-> //将值为5的结点插入到单链表的第3个结点前:08->74->05->07->23->03->99->31->56->88->16-> //删除第5个节点:08->74->05->07->03->99->31->56->88->16-> //从小到大排序:03->05->07->08->16->31->56->74->88->99-> //将整个链表逆序:99->88->74->56->31->16->08->07->05->03-> //将单链表中前4个结点和后6个结点进行互换:31->16->08->07->05->03->99->88->74->56-> //

出错时点中断，通过调用堆栈、变量窗口等观察分析原因  学会调试才是楼主需要的

而且程序没有崩溃，经验不足所以就不知道应该怎么做了

现在我调试知道问题在哪了,就是创建图和存储图的子函数应该引用结构体指针，对结构体进行操作，而不是复制它的值，但是我不知道应该怎么引用它的指针，就是怎么改？

崩溃的时候在弹出的对话框按相应按钮进入调试，按Alt+7键查看Call Stack即“调用堆栈”里面从上到下列出的对应从里层到外层的函数调用历史。双击某一行可将光标定位到此次调用的源代码或汇编指令处，看不懂时双击下一行，直到能看懂为止。  代码功能归根结底不是别人帮自己看或讲解或注释出来的；而是被自己静下心来花足够长的时间和精力亲自动手单步或设断点或对执行到某步获得的中间结果显示或写到日志文件中一步一步分析出来的。 提醒：再牛×的老师也无法代替学生自己领悟和上厕所！ 单步调试和设断点调试（VS IDE中编译连接通过以后，按F10或F11键单步执行，按Shift+F11退出当前函数；在某行按F9设断点后按F5执行停在该断点处。）是程序员必须掌握的技能之一。

题目在这： 先任意创建一个图 图的DFS,BFS的递归和非递归算法的实现 最小生成树（两种算法）的实现，求连通分量的实现 选择用邻接矩阵、邻接表等结构存储实现

这是主函数，题目在图片那 int main() { 	//MGraph_L G; 	//ALGraph gra; 	int s,j; 	char y='y';     printf("||¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤菜单¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤||\n");     printf("||-------------------------【0、创建一个无向图------------------------------||\n");     printf("||-------------------------【1、显示该图的邻接矩阵--------------------------||\n");     printf("||-------------------------【2、显示该图的邻接表----------------------------||\n"); 	printf("||-------------------------【3、广度优先遍历--------------------------------||\n");     printf("||-------------------------【4、深度优先遍历--------------------------------||\n"); 	printf("||-------------------------【5、连通分量------------------------------------||\n");     printf("||-------------------------【6、最小生成树MiniSpanTree_PRIM算法-------------||\n");     printf("||-------------------------【7、最小生成树MiniSpanTree_KRUSCAL算法----------||\n"); 	printf("||¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤||\n"); 	//printf("\t\t\t在求最小生成树前请先求连通分量!\n"); 	while(y=='y') 	{ 		printf("\t请选择菜单：\n"); 		printf("\t");         scanf("%d",&s); 		if(s==0) 		{ 			++o; 			if(o==2) 			{ 				n=0; 				l=0; 				o=0; 			} 		} 		switch(s) 		{ 		case 0:printf("\t创建一个无向图：\n"); 			creatMGraph_L(G);//用邻接矩阵的方式创建 			creatadj(gra,G);//但是为了输出方便使用邻接表的方式存储             break; 		case 1:printf("\t邻接矩阵显示如下：\n"); 			ljjzprint(G);             break;         case 2:             printf("\t邻接表显示如下：\n");             adjprint(gra,G);             break;         case 3:             printf("\t广度优先遍历：");             BFSTraverse(gra);             printf("\n");             break;         case 4: 			printf("\t深度优先遍历：");             DFStra(gra);             printf("\n");             break; 		case 5:printf("\t连通分量:\n"); 			DFSTraverse_fen(gra);             break;         case 6: 			if(n==0)  {printf("\t无权图没有最小生成树"); break;} 			else  				if(l>1) {printf("\t若该图为非强连通图(含有多个连通分量)时，最小生成树不存在\n"); break;} 			else 			{ 				int i,g[maxv][maxv]; 				for(i=0;i!=G.vexnum;++i) 					for(j=0;j!=G.vexnum;++j) 						g[i+1][j+1]=G.arcs[i][j].adj; 					printf("\t普利姆算法:\n"); 					MiniSpanTree_PRIM(g,G.vexnum); 					break; 			}         case 7:if(n==0){printf("\t无权图没有最小生成树");break;} 			else if(l>1){printf("\t该图为非强连通图(含有多个连通分量)，最小生成树不存在\n");break;} 			else 			{ 				printf("\t克鲁斯卡尔算法:\n");                 MiniSpanTREE_KRUSCAL(G,gra);                 break; 			}          		} 		printf("\n\t是否继续？y or n:\n"); 		printf("\t"); 		fflush(stdin);//刷新缓冲区，防止影响下次输入         scanf("%c",&y);         if(y=='n')         break; 	} 	return 0; }


Question: 用指针方法求 输出1~1000的完数  求改代码

#include <stdio.h> #include <stdlib.h> /*输出1~1000的完数(1不是完数 */  int getFactors(int n,int *arr,int *l);//*l表示因子的个数 void outPut(int n,int *arr,int l);  int main(int argc, char *argv[]) {     int     arr[1000], l, i;     for (i = 1; i < 1000; i++)     {         l = 0;  //这里！！！！！！！！         if (i == getFactors(i, arr, &l))         {             outPut(i, arr, l);  //这里！！！！！！！！         }     }      return 0; } int getFactors(int n, int *arr, int *l) {     int     *p, sum = 0, i, max = n / 2;     p = arr;     for (i = 1; i <= max; i++)     {         if (n % i == 0)         {             *p = i;//将因子储存起来             p++;//指向下一个元素             sum += i;             *l = *l + 1;         }     }     return sum; } void outPut(int n, int *arr, int l) {     printf("%d=", n);     int     i;     for (i = 0; i < l - 1; i++)     {         printf("%d+", arr[i]);     }     printf("%d\n", arr[i]); }


Question: c语言中用dll注射工具注射动态链接库时

仅供参考：dll 导出函数名的那些事 关键字：　VC++ 　DLL  导出函数　 经常使用VC6的Dependency查看DLL导出函数的名字，会发现有DLL导出函数的名字有时大不相同，导致不同的原因大多是和编译DLL时候指定DLL导出函数的界定符有关系。 VC++支持两种语言：即C/C++，这也是造成DLL导出函数差异的根源 我们用VS2008新建个DLL工程，工程名为"TestDLL" 把默认的源文件后缀 .CPP改为.C（C文件） 输入测试代码如下： 01 int _stdcall MyFunction(int iVariant) 02 { 03 return 0; 04 } 为了导出上面这个函数，我们有以下几个方法： 1. 使用传统的模块定义文件 (.def) 新建一个 后缀为.def的文本文件(这里建一个TestDll.Def)，文件内容为： LIBRARY TestDll EXPORTS MyFunction 在 Link 时指定输入依赖文件：/DEF:"TestDll.Def" 2. Visual C++ 提供的方便方法 在01行的int 前加入 __declspec(dllexport) 关键字 通过以上两种方法，我们就可以导出MyFunction函数。 我们用Dependency查看导出的函数： 第一种方法导出的函数为： MyFunction 第二种方法导出的函数为： _MyFunction@4 __stdcall会使导出函数名字前面加一个下划线，后面加一个@再加上参数的字节数，比如_MyFunction@4的参数（int iVariant）就是4个字节 __fastcall与 __stdcall类似，不过前面没有下划线，而是一个@，比如@MyFunction@4 __cdecl则是始函数名。 小结：如果要导出C文件中的函数，并且不让编译器改动函数名，用def文件导出函数。 下面我们来看一下C++文件 我们用VS2008新建个DLL工程，工程名为"TestDLL" 默认的源文件后缀为 .CPP （即C++文件）。 输入测试代码如下： 01 int _stdcall MyFunction(int iVariant) 02 { 03 return 0; 04 } 为了导出上面这个函数，我们有以下几个方法： 3. 使用传统的模块定义文件 (.def) 新建一个 后缀为.def的文本文件(这里建一个TestDll.Def)，文件内容为： LIBRARY TestDll EXPORTS MyFunction 在 Link 时指定输入依赖文件：/DEF:"TestDll.Def" 4. Visual C++ 提供的方便方法 在01行的int 前加入 __declspec(dllexport) 关键字 通过以上两种方法，我们就可以导出MyFunction函数。 我们用Dependency查看导出的函数： 第一种方法导出的函数为： MyFunction 第二种方法导出的函数为： ?MyFunction@@YGHH@Z 可以看到 第二种方法得到的 导出函数名 并不是我们想要的，如果在exe中用显示方法（LoadLibrary、GetProcAddress）调用 MyFunction 肯定会失败。 但是用引入库(*.LIB)的方式调用，则编译器自动处理转换函数名，所以总是没有问题。 解决这个问题的方法是： 用VC 提供的预处理指示符 "#pragma" 来指定链接选项。 如下： #pragma comment(linker, "/EXPORT:MyFunction=?MyFunction@@YGHH@Z") 这时，就会发现导出的函数名字表中已经有了我们想要的MyFunction。但我们发现原来的那个 ?MyFunction@@YGHH@Z 函数还在，这时就可以把 __declspec() 修饰去掉，只需要 pragma 指令即可。 而且还可以使如下形式： #pragma comment(linker, "/EXPORT:MyFunction=_MyFunction@4,PRIVATE") PRIVATE 的作用与其在 def 文件中的作用一样。更多的#pragram请查看MSDN。 小结：如果要导出C++文件中的函数，并且不让编译器改动函数名，用def文件导出函数。 同时可以用#pragma指令（C 中也可以用）。 总结： C++编译器在生成DLL时，会对导出的函数进行名字改编，并且不同的编译器使用的改编规则不一样，因此改编后的名字也是不同的（一般涉及到C++ 中的重载等）。 如果利用不同编译器分别生成DLL和访问DLL的exe程序，后者在访问该DLL的导出函数时就会出现问题。如上例中函数MyFunction在C++编译器改编后的名字是?MyFunction@@YGHH@Z。我们希望编译后的名字不发生改变，这里有几种方法。 第一种方法是通过一个称为模块定义文件DEF来解决。 LIBRARY TestDll EXPORTS MyFunction LIBRARY 用来指定动态链接库内部名称。该名称与生成的动态链接库名一定要匹配，这句代码不是必须的。 EXPORTS说明了DLL将要导出的函数，以及为这些导出函数指定的符号名。 第二种是定义导出函数时加上限定符：extern "C" 如：#define DLLEXPORT_API extern "C" _declspec(dllexport) 但extern "C"只解决了C和C++语方之间调用的问题(extern "C" 是告诉编译器，让它按C的方式编译)，它只能用于导出全局函数这种情况 而不能导出一个类的成员函数。 同时如果导出函数的调用约定发生改变，即使使用extern "C"，编译后的函数名还是会发生改变。例如上面我们加入_stdcall关键字说明调用约定（标准调用约定，也就是WINAPI调用约定）。 #define DLLEXPORT_API extern "C" _declspec(dllexport) 01 DLLEXPORT_API int _stdcall MyFunction(int iVariant) 02 { 03 return 0; 04 } 编译后函数名MyFunction改编成了_MyFunction@4 通过第一种方法模块定义文件的方式DLL编译后导出函数名不会发生改变。 DLL(动态库)导出函数名乱码含义 C++编译时函数名修饰约定规则：   __stdcall调用约定：   1、以"?"标识函数名的开始，后跟函数名；    2、函数名后面以"@@YG"标识参数表的开始，后跟参数表；    3、参数表以代号表示：   X--void   D--char   E--unsigned char   F--short   H--int   I--unsigned int   J--long   K--unsigned long   M--float   N--double   _N--bool   ....   PA--表示指针，后面的代号表明指针类型，如果相同类型的指针连续出现，以"0"代替，一个"0"代表一次重复；   4、参数表的第一项为该函数的返回值类型，其后依次为参数的数据类型,指针标识在其所指数据类型前；    5、参数表后以"@Z"标识整个名字的结束，如果该函数无参数，则以"Z"标识结束。   其格式为"?functionname@@YG*****@Z"或"?functionname@@YG*XZ"，例如                       int Test1(char *var1, unsigned long)-----"?Test1@@YGHPADK@Z"                      void Test2()-----"?Test2@@YGXXZ"    __cdecl调用约定：   规则同上面的_stdcall调用约定，只是参数表的开始标识由上面的"@@YG"变为"@@YA"。   __fastcall调用约定：   规则同上面的_stdcall调用约定，只是参数表的开始标识由上面的"@@YG"变为"@@YI"。   如果要用DEF文件输出一个"C++"类，则把要输出的数据和成员的修饰名都写入.def模块定义文件   所以...   通过def文件来导出C++类是很麻烦的,并且这个修饰名是不可避免的


Question: 如何通过 fopen返回的FILE句柄 找到文件名

#pragma comment(lib,"psapi") #include <windows.h> #include <stdio.h> #include <tchar.h> #include <string.h> #include <psapi.h> #include <io.h> #define BUFSIZE 512 BOOL GetFileNameFromHandle(HANDLE hFile) {     TCHAR pszFilename[MAX_PATH+1];     HANDLE hFileMap;      BOOL bSuccess = FALSE;     DWORD dwFileSizeHi = 0;     DWORD dwFileSizeLo = GetFileSize(hFile, &dwFileSizeHi);     if( dwFileSizeLo == 0 && dwFileSizeHi == 0 ) {         _tprintf(TEXT("Cannot map a file with a length of zero.\n"));         return FALSE;     }     hFileMap = CreateFileMapping(hFile,NULL,PAGE_READONLY,0,1,NULL);     if (hFileMap) {         // Create a file mapping to get the file name.         void* pMem = MapViewOfFile(hFileMap, FILE_MAP_READ, 0, 0, 1);         if (pMem) {             if (GetMappedFileNameA (GetCurrentProcess(),pMem,pszFilename,MAX_PATH)) {                 // Translate path with device name to drive letters.                 TCHAR szTemp[BUFSIZE];                 szTemp[0] = '\0';                 if (GetLogicalDriveStrings(BUFSIZE-1, szTemp)) {                     TCHAR szName[MAX_PATH];                     TCHAR szDrive[3] = TEXT(" :");                     BOOL bFound = FALSE;                     TCHAR* p = szTemp;                     do {                         // Copy the drive letter to the template string                         *szDrive = *p;                         // Look up each device name                         if (QueryDosDevice(szDrive, szName, MAX_PATH)) {                             size_t uNameLen = _tcslen(szName);                             if (uNameLen < MAX_PATH) {                                 bFound = _tcsnicmp(pszFilename, szName, uNameLen) == 0                                       && *(pszFilename + uNameLen) == _T('\\');                                 if (bFound) {                                     // Reconstruct pszFilename using szTempFile                                     // Replace device path with DOS path                                     TCHAR szTempFile[MAX_PATH];                                     sprintf(szTempFile,                                             TEXT("%s%s"),                                             szDrive,                                             pszFilename+uNameLen);                                     strcpy(pszFilename, szTempFile);                                 }                             }                         }                         // Go to the next NULL character.                         while (*p++);                     } while (!bFound && *p); // end of string                 }             }             bSuccess = TRUE;             UnmapViewOfFile(pMem);         }         CloseHandle(hFileMap);     }     _tprintf(TEXT("File name is %s\n"), pszFilename);     return(bSuccess); } int _tmain(int argc, TCHAR *argv[]) {     FILE *f;     HANDLE hFile;      if( argc != 2 ) {         _tprintf(TEXT("This sample takes a file name as a parameter.\n"));         return 0;     }     f=fopen(argv[1],"r");     if (NULL==f) return 0;      hFile=(HANDLE)_get_osfhandle(fileno(f));     //  hFile = CreateFile(argv[1], GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL);      if (hFile == INVALID_HANDLE_VALUE) {         _tprintf(TEXT("CreateFile failed with %d\n"), GetLastError());         return 0;     }     GetFileNameFromHandle( hFile );     fclose(f);     return 0; } //C:\test>test c:\windows\system32\kernel32.dll //File name is C:\WINDOWS\system32\kernel32.dll //

你不知道文件名，怎么open的？


Question: 把控制台上输出的内容转存到mysql数据库中

不用那么麻烦吧。。。。。老师，我觉得可以直接将屏幕上输出的内容存入mysql数据库里面，您觉得这样有什么不妥吗？

mysql 官方提供的C API，http://dev.mysql.com/doc/refman/5.5/en/c-api.html 建表，执行简单的SQL Insert语句，调用API也就OK了

使用命令重定向操作符可以使用重定向操作符将命令输入和输出数据流从默认位置重定 向到不同的位置。输入或输出数据流的位置即为句柄。  下表将列出可用的句柄。  句柄      句柄的数字代号 描述 STDIN     0              键盘输入 STDOUT    1              输出到命令提示符窗口 STDERR    2              错误输出到命令提示符窗口 UNDEFINED 3-9            这些句柄由应用程序单独定义，并且是各个工具特定的。  数字 0 到 9 代表前 10 个句柄。可以使用命令 Cmd.exe 运行程序并将该程序前 10 个 句柄中的任何一个重定向。要指定想使用的句柄，可在重定向操作符前面键入该句柄的 数字。如果未定义句柄，则默认的 < 重定向输入操作符是 0，而默认的 > 重定向输出 操作符是 1。键入 > 或 < 操作符之后，必须指定要读取或写入数据的位置。可以指定 文件名或另一个现有的句柄。  要指定重定向到现有句柄，请使用与 (&) 字符，后面接要重定向的句柄号 （例如 &句柄#）。例如，下面的命令可以将句柄 2（即 STDERR）重定向到 句柄 1（即 STDOUT）：  2>&1  下表列出了可用于将输入和输出数据流进行重定向的操作符。  重定向操作符 描述 > 将命令输出写入到文件或设备（例如打印机）中，而不是写在命令提示符窗口或句柄中。 < 从文件中而不是从键盘或句柄中读入命令输入。 >> 将命令输出添加到文件末尾而不删除文件中的信息。 >& 将一个句柄的输出写入到另一个句柄的输入中。 <& 从一个句柄读取输入并将其写入到另一个句柄输出中。 | 从一个命令中读取输出并将其写入另一个命令的输入中。也称作管道。  默认情况下，可以从键盘将命令输入（即 STDIN 句柄）发送到 Cmd.exe，然后由 Cmd.exe 将命令输出（即 STDOUT 句柄）发送到命令提示符窗口。  重定向输入 (<) 要将键盘输入重定向到文件或设备，请使用 < 操作符。例如，要从 File.txt 获取 sort 命令的输入，请键入：  sort<file.txt  File.txt 的内容将以字母顺序列表的方式显示在命令提示符窗口中。  < 操作符可以打开具有只读访问的指定文件名。所以，不能使用该操作符向文件中写入 信息。例如，如果以 <&2 启动程序，则所有试图读取句柄 0 的操作都将失败，因为句 柄 2 最初是以只写访问打开的。   注意  0 是 < 重定向输入操作符的默认句柄。 重定向输出 (>) 几乎所有的命令都将输出发送到命令提示符窗口。即使将输出发送到驱动器或打印机的 命令也会在命令提示符窗口显示消息和提示。  要将输出从命令提示符窗口重定向到文件或设备，请使用 > 操作符。可以在许多命令中 使用该操作符。例如，要将 dir 输出重定向到 Dirlist.txt，请键入：  dir>dirlist.txt  如果 Dirlist.txt 不存在，Cmd.exe 将创建该文件。如果 Dirlist.txt 存在，Cmd.exe 将使用 dir 命令的输出替换文件中的信息。  要运行 netsh routing dump 命令，然后将输出发送到 Route.cfg，请键入：  netsh routing dump>c:\route.cfg  > 操作符可以打开具有只写访问属性的指定文件。所以，不能使用该操作符读取文件。 例如，如果使用重定向 >&0 启动程序，则所有试图写入句柄 1 的操作都将失败，因为 句柄 0 最初是以只读访问打开的。   注意  1 是 > 重定向输出操作符的默认句柄。 复制句柄 重定向操作符 & 可以将输出或输入从一个指定句柄复制到另一个指定的句柄。例如， 要将 dir 输出发送到 File.txt 并将错误输出发送到 File.txt，请键入：  dir>c:\file.txt 2>&1  复制句柄时，可以复制该句柄原状态的所有特性。例如，如果一个句柄具有只写访问的 属性，则该句柄的所有副本都具有只写访问属性。不能将一个具有只读访问属性的句柄 复制到另一个具有只写访问属性的句柄。  使用 & 操作符重定向输入和副本 要将重定向输入操作符 (<) 与复制操作符 (&) 一起使用，指定的文件必须已经存在。 如果输入文件存在，Cmd.exe 将以只读方式打开该文件，然后将文件中包含的字符作为 输入发送到此命令（如同从键盘输入一样）。如果指定了句柄，Cmd.exe 将指定的句柄 复制到系统现有的句柄中。  例如，要以句柄 0 输入读取（即 STDIN）的方式打开 File.txt，请键入：  <file.txt  要打开 File.txt，并在内容排序后将输出发送到命令提示符窗口（即 STDOUT），请键入：  sort<file.txt  要查找 File.txt，然后将句柄 1（即 STDOUT）和句柄 2（即 STDERR）重定向到 Search.txt，请键入：  findfile file.txt>search.txt 2<&1  要以句柄 0 输入读取（即 STDIN）的方式复制用户定义句柄 3，请键入：  <&3  使用 & 操作符重定向输出和复制 如果将输出重定向到文件且指定了现有的文件名，Cmd.exe 将以只写方式打开文件并覆 盖该文件内容。如果指定了句柄，Cmd.exe 将文件复制到现有句柄中。  要将用户定义句柄 3 复制到句柄 1，请键入：  >&3  要将包括句柄 2（即 STDERR）的所有输出从 ipconfig 命令重定向到 句柄 1（即 STDOUT），然后将输出重定向到 Output.log，请键入：  ipconfig.exe>>output.log 2>&1  使用 >> 重定向操作符追加输出 要从命令中将输出添加到文件末尾而不丢失文件中已存在的任何信息，请使用两个连续 的大于号（即 >>）。例如，下面的命令可以将由 dir 命令生成的目录列表追加到 Dirlist.txt 文件：  dir>>dirlist.txt  要将 netstat 命令的输出追加到 Tcpinfo.txt 的末尾，请键入：  netstat>>tcpinfo.txt  使用管道操作符 (|) 管道操作符 (|) 可以提取一个命令的输出（默认情况下是 STDOUT），然后将其导入另 一个命令的输入中（默认情况下是 STDIN）。例如，下面的命令将对目录分类：  dir | sort  在本例中，将同时启动两个命令，但随后 sort 命令会暂停，直到它接收到 dir 命令 的输出为止。sort 命令使用 dir 命令的输出作为输入，然后将输出发送到 句柄 1（即 STDOUT）。  合并带重定向操作符的命令 可以通过合并带有其他命令和文件名的筛选器命令创建自定义命令。例如，可以使用以 下命令存储包含“LOG”字符串的文件名:  dir /b | find "LOG" > loglist.txt  dir 命令的输出通过 find 筛选器命令发送。包含字符串 "LOG" 的文件名作为文件名 列表（例如，NetshConfig.log、Logdat.svd 和 Mylog.bat）存储在文件 Loglist.txt 中。  要在相同命令中使用多个筛选器，请使用管道 (|) 分隔筛选器。例如，下面的命令将 搜索 C 盘上的每个目录以查找包含 "LOG" 字符串的文件名，并且在命令提示符窗口中 每次显示一屏：  dir c:\ /s /b | find "LOG" | more  利用管道 (|) 可以将 Cmd.exe 导向为通过 find 筛选器命令发送 dir 命令输出。 find 命令只选择包含字符串 "LOG" 的文件名。more 命令可以显示由 find 命令选择 的文件名（在命令提示符窗口中每次显示一屏）。有关筛选器命令的详细信息，请参阅 使用筛选器。

再供参考：#pragma comment(lib,"user32") #include <stdio.h> #include <string.h> #include <windows.h> int main() {     SECURITY_ATTRIBUTES sa          = {0};     STARTUPINFO         si          = {0};     PROCESS_INFORMATION pi          = {0};     HANDLE              hPipeOutputRead  = NULL;     HANDLE              hPipeOutputWrite = NULL;     HANDLE              hPipeInputRead   = NULL;     HANDLE              hPipeInputWrite  = NULL;     BOOL                bTest = 0;     DWORD               dwNumberOfBytesRead = 0;     DWORD               dwNumberOfBytesWrite = 0;     CHAR                szMsg[100];     CHAR                szBuffer[256];      sa.nLength = sizeof(sa);     sa.bInheritHandle = TRUE;     sa.lpSecurityDescriptor = NULL;      // Create pipe for standard output redirection.     CreatePipe(&hPipeOutputRead,  // read handle             &hPipeOutputWrite, // write handle             &sa,      // security attributes             0      // number of bytes reserved for pipe - 0 default             );      // Create pipe for standard input redirection.     CreatePipe(&hPipeInputRead,  // read handle             &hPipeInputWrite, // write handle             &sa,      // security attributes             0      // number of bytes reserved for pipe - 0 default             );      // Make child process use hPipeOutputWrite as standard out,     // and make sure it does not show on screen.     si.cb = sizeof(si);     si.dwFlags     = STARTF_USESHOWWINDOW | STARTF_USESTDHANDLES;     si.wShowWindow = SW_HIDE;     si.hStdInput   = hPipeInputRead;     si.hStdOutput  = hPipeOutputWrite;     si.hStdError   = hPipeOutputWrite;      CreateProcess (           NULL, "cmd.exe",           NULL, NULL,           TRUE, 0,           NULL, NULL,           &si, &pi);      // Now that handles have been inherited, close it to be safe.     // You don't want to read or write to them accidentally.     CloseHandle(hPipeOutputWrite);     CloseHandle(hPipeInputRead);      // Now test to capture DOS application output by reading     // hPipeOutputRead.  Could also write to DOS application     // standard input by writing to hPipeInputWrite.     sprintf(szMsg, "ver\n");     WriteFile(           hPipeInputWrite,      // handle of the write end of our pipe           &szMsg,               // address of buffer that send data           strlen(szMsg),        // number of bytes to write           &dwNumberOfBytesWrite,// address of number of bytes read           NULL                  // non-overlapped.           );      while(TRUE)     {        bTest=ReadFile(           hPipeOutputRead,      // handle of the read end of our pipe           &szBuffer,            // address of buffer that receives data           256,                  // number of bytes to read           &dwNumberOfBytesRead, // address of number of bytes read           NULL                  // non-overlapped.           );        if (!bTest){           sprintf(szMsg, "Error #%d reading pipe.",GetLastError());           printf("%s",szMsg);           break;       }        // do something with data.       szBuffer[dwNumberOfBytesRead] = 0;  // null terminate       printf("%s",szBuffer);       if ('>'==szBuffer[dwNumberOfBytesRead-1]) break;     }      sprintf(szMsg, "chcp\nexit\n");     WriteFile(           hPipeInputWrite,      // handle of the write end of our pipe           &szMsg,               // address of buffer that send data           strlen(szMsg),        // number of bytes to write           &dwNumberOfBytesWrite,// address of number of bytes read           NULL                  // non-overlapped.           );      while(TRUE)     {        bTest=ReadFile(           hPipeOutputRead,      // handle of the read end of our pipe           &szBuffer,            // address of buffer that receives data           256,                  // number of bytes to read           &dwNumberOfBytesRead, // address of number of bytes read           NULL                  // non-overlapped.           );        if (!bTest){           sprintf(szMsg, "Error #%d reading pipe.",GetLastError());           printf("%s",szMsg);           break;       }        // do something with data.       szBuffer[dwNumberOfBytesRead] = 0;  // null terminate       printf("%s",szBuffer);     }      // Wait for CONSPAWN to finish.     WaitForSingleObject (pi.hProcess, INFINITE);      // Close all remaining handles     CloseHandle (pi.hProcess);     CloseHandle (hPipeOutputRead);     CloseHandle (hPipeInputWrite);      return 0; } //C:\test>test //Microsoft Windows [版本 5.2.3790] //(C) 版权所有 1985-2003 Microsoft Corp. // //C:\test>ver // //Microsoft Windows [版本 5.2.3790] // //C:\test>chcp //活动的代码页: 936 // //C:\test>exit //Error #109 reading pipe. //C:\test>

以下内容仅供参考： system("dir /b /a-d c:\\*.* >d:\\allfiles.txt"); //读文件d:\\allfiles.txt的内容即C:\\下所有文件的名字 system("dir /b /a-d /s c:\\*.* >d:\\allfilesinsub.txt"); //读文件d:\\allfilesinsub.txt的内容即C:\\下所有文件的名字包含子目录 system("dir /b /ad  c:\\*.* >d:\\alldirs.txt"); //读文件d:\\alldirs.txt的内容即C:\\下所有子目录的名字 请记住，能用shell命令获取文件、文件夹信息或者操作文件、文件夹最好用shell命令获取或者操作，而不要用各种API获取或者操作，因为当遇到非法文件夹名或非法文件名或非法文件长度、非法文件日期、压缩文件、链接文件、稀疏文件……等各种意料之外的情况时，API会处理的不全面或陷入死循环，而shell命令不会。 如果嫌system黑窗口一闪，将system("...")替换为WinExec("cmd /c ...",SW_HIDE);


Question: 为何压栈不成功？

因为你在函数里操作的都只是main函数里的s的一个拷贝，需要传指针或者引用才行  #include"stdio.h" struct Stack { 	int sdata[100]; 	int slen; }s; //初始化栈 void initeStack(Stack *S) { 	S->slen=0; }  //删除栈顶元素 bool pop(Stack *S) { 	if(S->slen > 0) 	{ 		S->slen--; 		return 1; 	} 	else 	{ 		return 0; 	} } //元素压入栈中 bool push(Stack *S,int x) { 	if( S->slen<99)//栈不可满 	{ 		S->slen++; 		S->sdata[S->slen-1]= x ; 		return 1; 	} 	else 		return 0; } void emptyStack(Stack *S) { 	for(int i=0;i<S->slen;i++) 		pop(S); } int main() { 	Stack s; 	initeStack(&s); 	push(&s,1); 	printf("len of stack s=%d",s.slen); }

我知道怎么做了，但是为什么要这样呢？ 头文件stack.h struct Stack {     int sdata[100];     int slen; }; //初始化栈 void initeStack(Stack *S) { 	S->slen=0; } //删除栈顶元素 bool pop(Stack *S) {   if(S->slen > 0)   {     S->slen--;     return 1;   }   else   {     return 0;   } } //元素压入栈中 bool push(Stack *S,int x) {   if( S->slen<99)//栈不可满   {       S->slen++;       S->sdata[S->slen-1]= x ;       return 1;   }   else     return 0; } void emptyStack(Stack *S) {   for(int i=0;i<S->slen;i++)       pop(S); } 主函数： #include"stdio.h" #include"stack.h" int main() { Stack s; initeStack(&s); push(&s,1); push(&s,2); printf("len of stack s=%d",s.slen); }


Question: 求助大神

可以参考一下 C:\Program Files\OpenCV\modules\core\src\matrix.cpp 的内容。


Question: C/C++ 工程问题求助

一般段错误可以从buf溢出，内存分配处着手

放到开发板中运行会直接段错误，那可否先直接运行下呢，就是在linux或window内测试下代码呢，如ok，可以再找其他问题，

Windows： 崩溃的时候在弹出的对话框按相应按钮进入调试，按Alt+7键查看Call Stack即“调用堆栈”里面从上到下列出的对应从里层到外层的函数调用历史。双击某一行可将光标定位到此次调用的源代码或汇编指令处，看不懂时双击下一行，直到能看懂为止。  Linux： 进程意外退出会在当前目录下产生‘core’文件或形如‘core.数字’的文件比如‘core.1234’ 使用命令 gdb 运行程序名 core或core.数字 进入gdb然后使用bt命令 可以查看进程意外退出前函数调用的堆栈，内容为从上到下列出对应从里层到外层的函数调用历史。 如果进程意外退出不产生core文件，参考“ulimit -c core文件最大块大小”命令

struct  trans *info_st;  只是定义了一个指向结构体的指针 想必楼主应该是没有分配过空间吧，而直接使用了info_st->

给自己顶一下


Question: 字符串问题

引用 楼主 qq_34450551 的回复:char*buf[10]="10+10"; char c=*buf; If(c!="+")这不能正确判断，把+换成空格却可以 请问是什么地方出来问题 类型不匹配嘛，c 是char类型，*buf是char*类型;

感觉7、8楼回复得比较权威。推荐。

感觉5楼回复的较透彻，推荐

字符要用单引号  c!=‘+’

应该这样：  char buf[10]="10+10"; char *c=buf; if(*c++!=’+‘)

刚学应该自己多练习

不知道你到底想做什么，但从你语法上看，你的c语言没及格

引用 1 楼 user-9的回复:首先 char*buf[10] 表示10个cha*指针.  其次，char与char*怎么判断.... 完整代码我没有贴出来，这是我试着做状态机，上面的代码编译没有错误。char c 每次得到一个buf，可以判断c得到的是不是空格，却不能判断是不是其他符合

就这一点点代码，全是问题，你需要重修C语言

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

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


Question: 链表问题

#include <stdio.h> #include <stdlib.h>  struct node       //结点数据类型 { 	char data; 	struct node *next;  };  void traverse(struct node* head); void destroy(struct node* head); struct node* headinsert();//该函数按照头插法，创建4个结点的动态链表，并返回第1个结点的地址  int main() { 	struct node *head=NULL;  	head=headinsert();   //用头插法创建链表  	//遍历链表 	traverse(head);  	//释放资源，销毁链表中所有结点 	destroy(head);  } void traverse(struct node* head) { 	struct node *p; 	p= head; 	while(p) 	{ 		printf("%c ", p->data); 		p = p->next; 	}  }  void destroy(struct node* head) { 	struct node *p; 	while(head) 	{ 		p = head; 		head = head ->next; 		free(p); 	} } struct node* headinsert() { 	struct node *p, *head = NULL; 	int n=0; 	char buffer[64] = {0}; 	scanf("%s", buffer); 	while(buffer[n] != '\0') 	{ 		p = (struct node *) malloc (sizeof(struct node));	 		p->data = buffer[n]; 		p->next = head; 		head = p; 		n++; 	} 	return head; }


Question: 关于sizeof(struct)的一点疑问

注意 系统对齐设置（缺省设置，或者#pragma pack  设置）， 可能会强制较长类型，从非对齐位置开始存放

较短数据类型，跟较长类型放在一起对齐的时候 较短类型会拼接到一起，然后跟较长类型继续拼接 而每种类型的起始位置，都是按照该类型对齐量计算的。

内存对其，默认以pragma pack 中的参数8对齐了。可以使用#pragma pack(4)修改对齐字节。

由于存储变量时地址对齐的要求，编译器在编译程序时会遵循两条原则： 一、结构体变量中成员的偏移量必须是成员大小的整数倍（0被认为是任何数的整数倍）  二、结构体大小必须是所有成员大小的整数倍。

引用 3 楼 yuelengdihai 的回复:8+4+1+1=14,(这个结构体大小必须为8的整数倍，补齐后为16) 没看清题目

8+4+1+1=14,(这个结构体大小必须为8的整数倍，补齐后为16)

引用 楼主 a105112859 的回复:先贴代码 1. struct st1 { 	double df; //8 	int i;           //4 	char c1;    //1 	char c2;    //1 };  -------》 最大的是double类型，自身长度是8，所以是8*2 = 16 2. struct st2 { 	double df; 	char c1; 	int i; 	char c2; };  -------》double占用了8字节，c1和i共用了8个字节，c2用了8字节，所以是24 通过输出，可以看出st1大小为16，st2大小为24,有人知道这是为什么吗？环境是是VS2010 结论：变量定义的位置的不同时有可能影响结构体的大小

字节对齐，本质是以空间换时间。 以GCC为例，字节对齐规则是： 1.结构体内成员按自身长度自对齐。 所谓自对齐，指的是该成员的起始位置的内存地址必须是它自身长度的整数倍。如int只能以0,4,8这类的地址开始 2.结构体的总大小为结构体的有效对齐值的整数倍 结构体的有效对齐值的确定： 1）当未明确指定时，以结构体中最长的成员的长度为其有效值 2）当用#pragma pack(n)指定时，以n和结构体中最长的成员的长度中较小者为其值。 3）当用__attribute__ ((__packed__))指定长度时，强制按照此值为结构体的有效对齐值

不要迷信书、考题、老师、回帖； 要迷信CPU、编译器、调试器、运行结果。 并请结合“盲人摸太阳”和“驾船出海时一定只带一个指南针。”加以理解。 任何理论、权威、传说、真理、标准、解释、想象、知识……都比不上摆在眼前的事实！  有人说一套做一套，你相信他说的还是相信他做的？ 其实严格来说这个世界上古往今来所有人都是说一套做一套，不是吗？  不要写连自己也预测不了结果的代码！   仅供参考： #include <stdio.h> #define field_offset(s,f) (int)(&(((struct s *)(0))->f)) struct AD  { int a; char b[13]; double c;}; #pragma pack(push) #pragma pack(1) struct A1  { int a; char b[13]; double c;}; #pragma pack(2) struct A2  { int a; char b[13]; double c;}; #pragma pack(4) struct A4  { int a; char b[13]; double c;}; #pragma pack(8) struct A8  { int a; char b[13]; double c;}; #pragma pack(16) struct A16 { int a; char b[13]; double c;}; #pragma pack(pop) int main() {     printf("AD.a %d\n",field_offset(AD,a));     printf("AD.b %d\n",field_offset(AD,b));     printf("AD.c %d\n",field_offset(AD,c));     printf("AD sizeof %d\n", sizeof(AD));     printf("\n");     printf("A1.a %d\n",field_offset(A1,a));     printf("A1.b %d\n",field_offset(A1,b));     printf("A1.c %d\n",field_offset(A1,c));     printf("A1 sizeof %d\n", sizeof(A1));     printf("\n");     printf("A2.a %d\n",field_offset(A2,a));     printf("A2.b %d\n",field_offset(A2,b));     printf("A2.c %d\n",field_offset(A2,c));     printf("A2 sizeof %d\n", sizeof(A2));     printf("\n");     printf("A4.a %d\n",field_offset(A4,a));     printf("A4.b %d\n",field_offset(A4,b));     printf("A4.c %d\n",field_offset(A4,c));     printf("A4 sizeof %d\n", sizeof(A4));     printf("\n");     printf("A8.a %d\n",field_offset(A8,a));     printf("A8.b %d\n",field_offset(A8,b));     printf("A8.c %d\n",field_offset(A8,c));     printf("A8 sizeof %d\n", sizeof(A8));     printf("\n");     printf("A16.a %d\n",field_offset(A16,a));     printf("A16.b %d\n",field_offset(A16,b));     printf("A16.c %d\n",field_offset(A16,c));     printf("A16 sizeof %d\n", sizeof(A16));     printf("\n");     return 0; } //AD.a 0 //AD.b 4 //AD.c 24 //AD sizeof 32 // //A1.a 0 //A1.b 4 //A1.c 17 //A1 sizeof 25 // //A2.a 0 //A2.b 4 //A2.c 18 //A2 sizeof 26 // //A4.a 0 //A4.b 4 //A4.c 20 //A4 sizeof 28 // //A8.a 0 //A8.b 4 //A8.c 24 //A8 sizeof 32 // //A16.a 0 //A16.b 4 //A16.c 24 //A16 sizeof 32 // //

要对齐啊，因为int占4个字节，所以推测出地址总线4的字节，假设从地址2开始分配，不对齐，int占据的就是2-5的地址。由于读取是只能是0-3,4-7，4个4个读。可以想到，这样访问这个int需要读两次：先读地址0-3的数据，并抛弃地址0,1上的数据，再读4-7上的数据，抛弃掉地址6,7上的数据，然后组合。如果直接将int存放在3-7的位置上，那直接一次就可以搞定了。 首先VS中默认对齐设置为8 在第一个结构体中，第一个为double，因此min(8,8)等于8,按8字节对齐，占8个字节，                                    第二个为int，min(4,8)=4,而前一个double类型刚好占满了8个，所以紧挨着doube排，占4个字节                                    第三个为char，min(1,8)=1,前面Int再一次占满4个字节，因此它也紧挨着排列，占1                                     第三四个为char，min(1,8)=1,前面char再一次占满1个字节，因此它同样紧挨着排列，占1                                     最后，整个结构体必须长度必须为结构体内最长类型的整数倍，现在只用了8+4+1+1,=14，还不够， 因此，最后还需补两个空 在第二个结构体中，第一个为double，因此min(8,8)等于8,按8字节对齐，占8个字节，                                    第二个为char，min(1,8)=1,而前一个double类型刚好占满了8个，所以紧挨着doube排，占1个字节                                    第三个为int，min(4,8)=4,而前面char仅仅占了1个字节，为了以最少此时访问到，在int之前需要空3个字节，而自己占4个字节                                     第三四个为char，min(1,8)=1,前面int已经占满4个字节，因此它紧挨着排列，占1                                     最后，整个结构体必须长度必须为结构体内最长类型的整数倍，现在只用了8+1+3（空）+4+1,=17，还不够， 因此，最后还需补7个空。 以上本人浅显理解，应该比专业术语好懂。对齐的根本原则就是：使变量能以最少的读取次数访问，

搜索“内存对齐”，还有int可不一定是4字节的，建议用int32_t表示32位有符号整型

仅供参考：#include <stdio.h> #define field_offset(s,f) (int)(&(((struct s *)(0))->f)) struct AD  { int a; char b[13]; double c;}; #pragma pack(push) #pragma pack(1) struct A1  { int a; char b[13]; double c;}; #pragma pack(2) struct A2  { int a; char b[13]; double c;}; #pragma pack(4) struct A4  { int a; char b[13]; double c;}; #pragma pack(8) struct A8  { int a; char b[13]; double c;}; #pragma pack(16) struct A16 { int a; char b[13]; double c;}; #pragma pack(pop) int main() {     printf("AD.a %d\n",field_offset(AD,a));     printf("AD.b %d\n",field_offset(AD,b));     printf("AD.c %d\n",field_offset(AD,c));     printf("\n");     printf("A1.a %d\n",field_offset(A1,a));     printf("A1.b %d\n",field_offset(A1,b));     printf("A1.c %d\n",field_offset(A1,c));     printf("\n");     printf("A2.a %d\n",field_offset(A2,a));     printf("A2.b %d\n",field_offset(A2,b));     printf("A2.c %d\n",field_offset(A2,c));     printf("\n");     printf("A4.a %d\n",field_offset(A4,a));     printf("A4.b %d\n",field_offset(A4,b));     printf("A4.c %d\n",field_offset(A4,c));     printf("\n");     printf("A8.a %d\n",field_offset(A8,a));     printf("A8.b %d\n",field_offset(A8,b));     printf("A8.c %d\n",field_offset(A8,c));     printf("\n");     printf("A16.a %d\n",field_offset(A16,a));     printf("A16.b %d\n",field_offset(A16,b));     printf("A16.c %d\n",field_offset(A16,c));     printf("\n");     return 0; } //AD.a 0 //AD.b 4 //AD.c 24 // //A1.a 0 //A1.b 4 //A1.c 17 // //A2.a 0 //A2.b 4 //A2.c 18 // //A4.a 0 //A4.b 4 //A4.c 20 // //A8.a 0 //A8.b 4 //A8.c 24 // //A16.a 0 //A16.b 4 //A16.c 24 // //


Question: 数组大小

仅供参考：#include <stdio.h> #include <stdlib.h> #include <malloc.h> int **newarr2d(int rows,int cols) {     int **p,i;      p=(int **)malloc(rows*sizeof(int *));     if (NULL==p) exit(1);     for (i=0;i<rows;i++) {         p[i]=(int *)malloc(cols*sizeof(int));         if (NULL==p[i]) exit(1);     }     return p; } void deletearr2d(int **p,int rows) {     int i;      for (i=0;i<rows;i++) {         free(p[i]);     }     free(p); } int main() {     int **arr2d,i,j,r,c;      r=4;     c=5;     //在堆中开辟一个4×5的二维int数组     arr2d=newarr2d(r,c);     for (i=0;i<r;i++) {         for (j=0;j<c;j++) {             arr2d[i][j]=i*c+j;         }     }     for (i=0;i<r;i++) {         for (j=0;j<c;j++) {             printf(" %2d",arr2d[i][j]);         }         printf("\n");     }     deletearr2d(arr2d,r);      r=6;     c=3;     //在堆中开辟一个6×3的二维int数组     arr2d=newarr2d(r,c);     for (i=0;i<r;i++) {         for (j=0;j<c;j++) {             arr2d[i][j]=i*c+j;         }     }     for (i=0;i<r;i++) {         for (j=0;j<c;j++) {             printf(" %2d",arr2d[i][j]);         }         printf("\n");     }     deletearr2d(arr2d,r);      return 0; } //  0  1  2  3  4 //  5  6  7  8  9 // 10 11 12 13 14 // 15 16 17 18 19 //  0  1  2 //  3  4  5 //  6  7  8 //  9 10 11 // 12 13 14 // 15 16 17 //

不能，需要在编译时确定大小，如要可变需要动态分配

1、如果楼主不是用于什么特别的程序，仅仅只是用来实验或者做个小作业，可以先定义一个比较大的二维数组，然后输入x、y定义能够使用的数组边界。 2、楼主可以malloc(new)一个一维数组，将一维数组当做二维数组使用（对于计算机来说一维数组和二维数组没什么区别，只是人看着有区别而已） 3、按照楼上方法定义二维数组。

GCC什么的是支持变长数组的，如果是VS什么的是不行的，变长数组坑不少楼主用的时候小心 用new定义一个5x5的二维数组：  int m=5,n=5; int **p=new int*[m]; for(int i=0;i<m;i++) {     p[i]=new int[n];  }

变长数组（variable length array type）是C99才引入到C语言中的，C11不要求实现必须支持。 你需要一个支持变长数组的编译器，比如GCC和CLANG。


Question: 求两个矩阵相乘 不知为啥不对

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


Question: 我用vs2013使用窗体c++能做出打印模板成功打印

引用 2 楼 zhao4zhong1 的回复:用vs2013使用c++不能做出什么呢？  怎么做

引用 1 楼 user-2 的回复:能。 怎么操作，有案例参考吗？

参考MSDN中Office开发相关章节？

用vs2013使用c++不能做出什么呢？

能。


Question: openssl中如何提取算法源码

看源码费劲那就调试，埋日志。


Question: c指针存储单元

my_name和me指针属于局部变量，在32位系统中，该局部变量占4个字节；这两个指针在栈上分配的，my_name = me;只是将me指向的地址值赋值给了my_name；这样my_name的内存空间（4个字节）存放的是新的字符串的地址；

是啊，存在静态常量区  谁说指针一定要动态分配内存，指向常量区、指向栈上的变量一样可以啊

指针my_name和me都没有分配存储单元的，只是一个指针变量，例如，int a;一样，只不过他是指向了常量区的2个字符串常量的地址罢了，调用他就可以访问那2个字符串，但不能修改其内容的，因为不能修改常量的。要是malloc一个空间给一个指针的话，那此指针内的数据可以修改的了，我技术不行，理解不当之处，望高手指正，学习中！

my_name和me，因为定义的是一个普通指针，并没有定义空间来存放"Tony"，所以编译器得帮我们找地方来放"Tony"，显然，把这里的"Tony"当成常量并把它放到程序的常量区是编译器最合适的选择。所以尽管my_name的类型不是const char*，并且my_name[0] = 'x';也能编译通过，但是执行my_name[0] = 'x';就会发生运行时异常，因为这个语句试图去修改程序常量区中的东西。  记得哪本书中曾经说过char* my_name= "Tony";这种写法原来在c++标准中是不允许的，但是因为这种写法在c中实在是太多了，为了兼容c，不允许也得允许。虽然允许，但是建议的写法应该是const char* my_name= "Tony";这样如果后面写my_name[0] = 'x'的话编译器就不会让它编译通过，也就避免了上面说的运行时异常。  PS：在C++03中，char* my_name= "Tony"是合法的，但在C++11中是非法的，C++11必须这样写：const char* my_name= "Tony"


Question: 求教一道链表的问题

不是声明后，就指向下一个 而是定义了一个指针， 用于指向下一个节点（储存下各节点的地址） 这个指针，之所以能指向下一个节点，是因为， 链表相关的程序的代码， 保证这个这个指针，永远指向下各节点。  靠的是链表的数据结构，依赖的函数的代码实现，来保证这一点的

引用 6 楼 qq423399099 的回复:因为你采用的是尾插法，每次malloc出来的p节点都是最后一个待插入的节点，所以它的next指针要置为空 q->next表示的是q所指向的节点的next指针让它指向新malloc的节点，实现新节点的插入 q=p;表示将q节点指向新malloc出来的节点（q要指向最后一个节点，这样下次才能使用q->next=p;实现链表连接）讲的太详细了！我理解了，拜谢！

引用 3 楼 qq423399099 的回复:当然不是直接指向下一个结点。。 你得自己赋值啊，比如第一个结点p1,第二个节点p2 p1->next=p2这样赋值过才使得第一个节点的next指针指向第二个节点嗯嗯。。我看树上的输入代码大概是   for(i=1;i<=n;i++) {         scanf("%d", &a);         p = (struct node *)malloc(sizeof(struct node));//申请一个动态空间         p->data = a;         p->next = NULL;         if (head == NULL)              head = p;             else              q->next = p;             q = p；      } 请问这段代码里 q->next=p; q=p; 为什么要将q的后继指针指向p结点，q也要指向p结点呢？谢谢

引用 4 楼 jinyingmo94 的回复:[quote=引用 3 楼 qq423399099 的回复:] 当然不是直接指向下一个结点。。 你得自己赋值啊，比如第一个结点p1,第二个节点p2 p1->next=p2这样赋值过才使得第一个节点的next指针指向第二个节点嗯嗯。。我看树上的输入代码大概是   for(i=1;i<=n;i++) {         scanf("%d", &a);         p = (struct node *)malloc(sizeof(struct node));//申请一个动态空间         p->data = a;         p->next = NULL;         if (head == NULL)              head = p;             else              q->next = p;             q = p；      } 请问这段代码里 q->next=p; q=p; 为什么要将q的后继指针指向p结点，q也要指向p结点呢？谢谢 [/quote]还有为什么临时指针的后继指针指向空？谢谢

引用 1 楼 ArthurJava 的回复:大神。。我是想问为什么这样声明之后会指向下一个结点？


Question: 6174问题好像陷入了死循环，请帮我看一下

引用 楼主 computerfeiwu 的回复:例如，从1234出发，依次可以得到4321-1234=3087、8730-378=8352、8532-2358=6174，又回到了它自己！  不明白楼主的意思，又回到它自己是什么意思？

#include <stdio.h> #include <stdlib.h>  int comp(const void*a,const void*b) {     return *((int*)b) - *((int*)a); }  int CaoZuo( int n, int *times ) {     int a[4], i;     int temp = n, max, min;     for ( i=0; i<4; i++ )     {         a[i] = temp % 10;         temp /= 10;     }     qsort(a, 4, sizeof(int), comp);     max=a[0]*1000+a[1]*100+a[2]*10+a[3];     min=a[3]*1000+a[2]*100+a[1]*10+a[0];      if ( max - min != n )     {         (*times)++;         return CaoZuo( max - min, times );     }     return n; }  int main() { int n = 1283; int times = 0; int dest = CaoZuo(1234, ×); printf("n = %d dest=%d times=%d\n", n, dest, times);  return 0; }

paixuda里面j范围不对。


Question: C调用Python一个运行时间长的函数，如何实时获取中间结果

引用 5 楼 CharlesSimonyi 的回复:python代码中的download函数又是如何显示进度的？ 你的整个下载过程都写到一个函数里了，要调用完毕这个函数才获得结果，而且函数调用完毕的时候整个文件都下载完毕了。 先不说C如何调用的问题，你先解决这样的一个问题： 假如你的这个download函数拿给别人用，别人用python来调用你的download函数，如何实时获取进度并print()输出到屏幕上？ （注意，你写好代码拿给别人用，别人只能调用你写的代码，不能修改你的代码，就像标准库中的那些东西一样，你一般都只是调用，不会去修改它的代码） 所以这其实是个接口设计问题。 一个函数的调用需要很长时间才能完成，如何让调用者获取执行过程的进度，此类问题有多种解决方案： 1.拆分download函数，分步骤实现文件的下载，比如可以拆分成几个函数 打开连接（） 获取文件大小() 读一部分（size） 关闭连接（） 这样别人调用的时候，可以在一个循环中反复调用   读一部分（）并通过参数指定要读多少，这样调用者可以很好的知道进度。 Winhttp/Wininet等HTTP库在下载文件的时候都采用此办法 2.回调 download应提供一个参数以接收调用者提供的函数指针（或函数对象），download在下载过程中，每下载%5就调用一下这个回调函数通知调用者，这样调用者可以在回调函数中显示进度。 urllib使用的就是这种方式。 3.其它方法，如使用windows消息、事件来通知调用者，具有平台依赖性，用得较少   谢大神，一语惊醒梦中人啊。你的第一个方案非常不错。 第二个方案本来今天想研究一下的，想想太复杂的，就不干了 第三个是不适应的，有平台依赖性。  3Q Very Much！

显示进度这种事情不要放在download函数里，你的接口要设计成，当别人调用你的download函数的时候，别人能获取到进度

引用 2 楼 CharlesSimonyi 的回复:你的python代码是如何反馈进度的？ 是用print("10%")之类的方法输出的进度吗？ 还是用其他方式。 C代码是如何调用python的， 是通过Python/C API调用 还是把一个py文件当做可执行文件直接用ShellExecute之类的API去执行   def download(ftp_ip, ftp_port, ftp_user, ftp_pwd, remote_file, local_file): 	conn_result = _get_remote_file_size(ftp_ip, ftp_port, ftp_user, ftp_pwd, remote_file) 	ftps = conn_result[2] 	# start to download 	local_file_size = 0L 	try: 		download_result = False 		download_size = 0L 		ftps.voidcmd("TYPE I") 		download_connection = ftps.transfercmd('RETR ' + remote_file, local_file_size) 		percent = 0 		count = 0 		_progress(CLI_PROCESS_MAX_PRINT_LEN, percent) 		 		# 打开本地文件，准备从远端获取并下载 		with open(local_file, "ab") as local_save_file: 			while True: 				rcv_buffer = download_connection.recv(1024*1024*1024) 				write_len = local_save_file.write(rcv_buffer) 				。。。 				download_size += len(rcv_buffer) 				percent = int(float(download_size) / remote_file_size * 100) 				count = (count + 1) % 40 #(延迟打印规则) 				if 0 == count: 					# 打印进度条，后续删除_progress(CLI_PROCESS_MAX_PRINT_LEN, percent) 				if 100 == percent: 					# 打印进度条，后续删除 _progress(CLI_PROCESS_MAX_PRINT_LEN, percent) 	except Exception, e: 		# print "download fail with [%s]" % e 		download_result = UPG_FTP_DOWNLOAD_FAIL  	# 清理环境 	。。。 	return download_result    这个事是Python的下载组件，有部分是抽出来的方法，没有把代码贴出来。

引用 2 楼 CharlesSimonyi 的回复:你的python代码是如何反馈进度的？ 是用print("10%")之类的方法输出的进度吗？ 还是用其他方式。 C代码是如何调用python的， 是通过Python/C API调用 还是把一个py文件当做可执行文件直接用ShellExecute之类的API去执行  int pgPycFtpsFileDownload( const IN  UPGRADE_FTP_INFO * pFtpInfo,                            const IN char * pcRemotePath,                            const IN char * pcLocalPath,                            const IN int ulMaxFileSize) {     int  ulRet       = 0;     PyObject * pModule    = NULL;     PyObject * pDict      = NULL;     PyObject * pFunction  = NULL;     PyObject * pArgus     = NULL;     PyObject * pResult    = NULL;           do     {          Py_Initialize();          (VOS_VOID)PyRun_SimpleString("import sys"); 		         if(NULL == pModule)         {             //xxxxxx记录错误             break;         }          pDict      = PyModule_GetDict(pModule);         pFunction  = PyDict_GetItemString(pDict, "download");                  if(NULL == pFunction)         {             //xxxxxx记录错误             break;         }          pArgus = Py_BuildValue( "(s, i, s, s, s, s, l)",                             pFtpInfo->ucFtpIp,    pFtpInfo->ulFtpPort,                             pFtpInfo->ucFtpUsr,   pFtpInfo->ucFtpPwd,                             pcRemotePath,           pcLocalPath,    ulMaxFileSize);          pResult = PyEval_CallObject(pFunction, pArgus);                   /*获取download下载结果*/         (void)PyArg_Parse(pResult,"i"，ulRet);     }     while(0);         Py_Finalize()          //xxxxxx记录日志     return ulRet; }      使用的是Python 的C API方法

仅供参考：#pragma comment(lib,"user32") #include <stdio.h> #include <string.h> #include <windows.h> int main() {     SECURITY_ATTRIBUTES sa          = {0};     STARTUPINFO         si          = {0};     PROCESS_INFORMATION pi          = {0};     HANDLE              hPipeOutputRead  = NULL;     HANDLE              hPipeOutputWrite = NULL;     HANDLE              hPipeInputRead   = NULL;     HANDLE              hPipeInputWrite  = NULL;     BOOL                bTest = 0;     DWORD               dwNumberOfBytesRead = 0;     DWORD               dwNumberOfBytesWrite = 0;     CHAR                szMsg[100];     CHAR                szBuffer[256];      sa.nLength = sizeof(sa);     sa.bInheritHandle = TRUE;     sa.lpSecurityDescriptor = NULL;      // Create pipe for standard output redirection.     CreatePipe(&hPipeOutputRead,  // read handle             &hPipeOutputWrite, // write handle             &sa,      // security attributes             0      // number of bytes reserved for pipe - 0 default             );      // Create pipe for standard input redirection.     CreatePipe(&hPipeInputRead,  // read handle             &hPipeInputWrite, // write handle             &sa,      // security attributes             0      // number of bytes reserved for pipe - 0 default             );      // Make child process use hPipeOutputWrite as standard out,     // and make sure it does not show on screen.     si.cb = sizeof(si);     si.dwFlags     = STARTF_USESHOWWINDOW | STARTF_USESTDHANDLES;     si.wShowWindow = SW_HIDE;     si.hStdInput   = hPipeInputRead;     si.hStdOutput  = hPipeOutputWrite;     si.hStdError   = hPipeOutputWrite;      CreateProcess (           NULL, "cmd.exe",           NULL, NULL,           TRUE, 0,           NULL, NULL,           &si, &pi);      // Now that handles have been inherited, close it to be safe.     // You don't want to read or write to them accidentally.     CloseHandle(hPipeOutputWrite);     CloseHandle(hPipeInputRead);      // Now test to capture DOS application output by reading     // hPipeOutputRead.  Could also write to DOS application     // standard input by writing to hPipeInputWrite.     sprintf(szMsg, "ver\n");     WriteFile(           hPipeInputWrite,      // handle of the write end of our pipe           &szMsg,               // address of buffer that send data           strlen(szMsg),        // number of bytes to write           &dwNumberOfBytesWrite,// address of number of bytes read           NULL                  // non-overlapped.           );      while(TRUE)     {        bTest=ReadFile(           hPipeOutputRead,      // handle of the read end of our pipe           &szBuffer,            // address of buffer that receives data           256,                  // number of bytes to read           &dwNumberOfBytesRead, // address of number of bytes read           NULL                  // non-overlapped.           );        if (!bTest){           sprintf(szMsg, "Error #%d reading pipe.",GetLastError());           printf("%s",szMsg);           break;       }        // do something with data.       szBuffer[dwNumberOfBytesRead] = 0;  // null terminate       printf("%s",szBuffer);       if ('>'==szBuffer[dwNumberOfBytesRead-1]) break;     }      sprintf(szMsg, "chcp\nexit\n");     WriteFile(           hPipeInputWrite,      // handle of the write end of our pipe           &szMsg,               // address of buffer that send data           strlen(szMsg),        // number of bytes to write           &dwNumberOfBytesWrite,// address of number of bytes read           NULL                  // non-overlapped.           );      while(TRUE)     {        bTest=ReadFile(           hPipeOutputRead,      // handle of the read end of our pipe           &szBuffer,            // address of buffer that receives data           256,                  // number of bytes to read           &dwNumberOfBytesRead, // address of number of bytes read           NULL                  // non-overlapped.           );        if (!bTest){           sprintf(szMsg, "Error #%d reading pipe.",GetLastError());           printf("%s",szMsg);           break;       }        // do something with data.       szBuffer[dwNumberOfBytesRead] = 0;  // null terminate       printf("%s",szBuffer);     }      // Wait for CONSPAWN to finish.     WaitForSingleObject (pi.hProcess, INFINITE);      // Close all remaining handles     CloseHandle (pi.hProcess);     CloseHandle (hPipeOutputRead);     CloseHandle (hPipeInputWrite);      return 0; } //C:\test>test //Microsoft Windows [版本 5.2.3790] //(C) 版权所有 1985-2003 Microsoft Corp. // //C:\test>ver // //Microsoft Windows [版本 5.2.3790] // //C:\test>chcp //活动的代码页: 936 // //C:\test>exit //Error #109 reading pipe. //C:\test>


Question: 这是一个词法分析，怎么识别小数点和负数

十进制数的 分析： 正负号跟小数点，以及指数标志的分析 大概分这么几个步骤： 1）分析正负号 过滤空格，找到 + 或者 - ，找整数部分 没找到，判断是否数字，是数字，符号为 +，找整数部分 不是数字判断是否空格 是空格接着过滤空格 否则出错处理  2）找整数部分 一直找数字，直到不是，整数部分结束 此后一般不再滤除空格了，需要的话，在每步前面加上 3）找小数点  判断当前字符是否小数点，是 找小数，不是结束，这个数是整数 4）找小数尾数 一直找数字，直到不是，位数部分结束 5）找指数标志 E,e,有些系统例如fortran 还包括 D，d 判断当前字符是不是 指数标志，是找指数部分 6）指数部分 一般不在滤除空格 6.1）指数的符号 找+，-号，有找到了，没有，符号为 + ,直接找整数部分 6.2）指数的整数部分 找数字，直到非数字。  可能还有第7步，数据类型后缀 有些系统可能是前缀 C,C++ 十六进制数，既有有前缀和也有后缀 现在浮点常量，也可有十六进制表示 大约就这些吧

请问我要识别小数或者实数应该怎么改这个代码啊

词法分析(1)---词法分析的有关概念以及转换图(内含浮点数格式解析c源代码) http://www.cppblog.com/woaidongmao/archive/2009/09/25/97245.html

参考Tiny C Compiler源代码？

做的再好点是判断完'-'后面的是否是数字 再判断它之前的是否也是数字就能确定是减号还是负号

你在case'-':这里还需要继续看proc[p+1]是否是数字，如果是数字 那么syn=11,否则 syn=14如果是数字 那么你这里需要一直遍历到不是数字为止。


Question: 关于cJSON编译报错的问题

引用 3 楼 ighack 的回复:#include包含的顺序错误了 要先包函stdlib.h stdio.h 牛批！

4L是正解！

不知道楼主问题解决没有，可否分享一下？

你在.h里添加string头文件

#include包含的顺序错误了 要先包函stdlib.h stdio.h

引用 1 楼 user-5 的回复:size_t未定义。  #ifdef  __linux__ typedef unsigned int size_t #endif 如果我在cJSON.h添加这些 会提示在stddef.h里已经定义过了   gcc 版本 4.4.7 20120313 (Red Hat 4.4.7-16) (GCC)


Question: 结构体强制转化，大小端模式问题

buf的地址相对于结构类型TEST来说，不是正确对齐的。 未对齐的访问会产生未定义的行为，什么情况都有可能发生，程序没有崩溃已经很幸运了。 正确的做法是这样的： WORD buf[1024] = {0}; 或者 _Alignas (TEST) BYTE buf[1024] = {0};    //仅C11支持。

跟大小端无关啊，可能是数据对齐的问题 给test最后增加一个char成员再试试。

#include <stdio.h> #include <string.h> FILE *f; char buffer[4096]; int r,a; void HexDump(char *buf,int len,int addr) {     int i,j,k;     char binstr[80];      for (i=0;i<len;i++) {         if (0==(i%16)) {             sprintf(binstr,"%08x -",i+addr);             sprintf(binstr,"%s %02x",binstr,(unsigned char)buf[i]);         } else if (15==(i%16)) {             sprintf(binstr,"%s %02x",binstr,(unsigned char)buf[i]);             sprintf(binstr,"%s  ",binstr);             for (j=i-15;j<=i;j++) {                 sprintf(binstr,"%s%c",binstr,('!'<buf[j]&&buf[j]<='~')?buf[j]:'.');             }             printf("%s\n",binstr);         } else {             sprintf(binstr,"%s %02x",binstr,(unsigned char)buf[i]);         }     }     if (0!=(i%16)) {         k=16-(i%16);         for (j=0;j<k;j++) {             sprintf(binstr,"%s   ",binstr);         }         sprintf(binstr,"%s  ",binstr);         k=16-k;         for (j=i-k;j<i;j++) {             sprintf(binstr,"%s%c",binstr,('!'<buf[j]&&buf[j]<='~')?buf[j]:'.');         }         printf("%s\n",binstr);     } } int main(int argc,char **argv) {     if (argc<2) {         fprintf(stderr,"Usage: %s filename.ext\n",argv[0]);         return 2;     }     f=fopen(argv[1],"rb");     if (NULL==f) {         fprintf(stderr,"Can not open file [%s]!\n",argv[1]);         return 1;     }     a=0;     while (1) {         r=fread(buffer,1,4096,f);         HexDump(buffer,r,a);         a+=r;         if (r<4096) break;     }     fclose(f);     return 0; }

1   #include <stdio.h>                                                                                1 #include <string.h>   2        3        4 typedef char BYTE;   5 typedef short WORD;   6        7 typedef struct tag_TEST   8 {      9     |   WORD            nIndex;  10     BYTE        baud;  11     BYTE        protocol;    12     BYTE        port;  13     char        password[32];  14     BYTE        pwdLen;  15     BYTE        rateNum;  16 }TEST;  17 int main(void)  18 {     19     TEST tmp;  20     BYTE buf[1024] = {0};  21     memset(&tmp, 0x00, sizeof(TEST));  22     tmp.nIndex = 0x0001;  23     memcpy(buf, (BYTE*)&tmp, sizeof(TEST));  24       25     printf("buf_index=%04x, tmp_index=%04x\r\n",((TEST*)buf)->nIndex, tmp.nIndex);  26     return 0;  27 }  我测试的结果是一样的，没有出现LZ说的差异，我使用的是小端系统；LZ使用的是大端系统；

如果我在定义个TEST B,把buf里面的拷贝出来，在打印B.nIndex，结果就是正常的0x0001了   TEST B; memcpy(&B, buf, sizeof(TEST));

求指教求指教求指教求指教求指教


Question: acm c语言

引用 楼主 jianjiu7 的回复:求平均成绩 Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) Total Submission(s): 37344 Accepted Submission(s): 8899  Problem Description 假设一个班有n(n<=50)个学生，每人考m(m<=5)门课，求每个学生的平均成绩和每门课的平均成绩，并输出各科成绩均大于等于平均成绩的学生数量。  Input 输入数据有多个测试实例，每个测试实例的第一行包括两个整数n和m，分别表示学生数和课程数。然后是n行数据，每行包括m个整数（即：考试分数）。  Output 对于每个测试实例，输出3行数据，第一行包含n个数据，表示n个学生的平均成绩，结果保留两位小数；第二行包含m个数据，表示m门课的平均成绩，结果保留两位小数；第三行是一个整数，表示该班级中各科成绩均大于等于平均成绩的学生数量。 每个测试实例后面跟一个空行。  Sample Input 2 2 5 10 10 20  Sample Output 7.50 15.00 7.50 15.00 1    #include<stdio.h>  int main() { 	int n,m,i,j,cout,p; 	while(~scanf("%d %d",&n,&m)){ 		cout=0; 		int s[51][5]={0}; 		float a[6]={0}; 		float b[51]={0}; 		for(i=0;i<n;i++) 			for(j=0;j<m;j++){ 			scanf("%d",*(s+i)+j); 			b[i]+=s[i][j]; 			} 		 		for(j=0;j<m;j++)	 			for(i=0;i<n;i++) 				a[j]+=s[i][j]; 				 		for(i=0;i<n;i++){ 			p=1; 			for(j=0;j<m;j++) 				if(s[i][j]<a[j]/n){ 					p=0; 					break; 			} 			if(p) 			cout++; 		} 			 		for(i=0;i<n-1;i++) 			printf("%.2f ",b[i]/n); 		printf("%.2f\n",b[i]/n); 	 		for(j=0;j<m-1;j++) 			printf("%.2f ",a[j]/n); 		printf("%.2f\n",a[j]/n); 		printf("%d\n\n",cout); 	}  	return 0; } 为什么一直不对，到底哪里错了，求大神指教倒数第二个for循环里的除以n改成m也不对。。。。

引用 2 楼 mxway 的回复:while(~scanf("%d %d",&n,&m)) 改为 while(scanf("%d %d",&n,&m)!=EOF)有可能,float只有7位，但成绩累加后  引用 4 楼 mxway 的回复:[quote=引用 3 楼 jianjiu7 的回复:] [quote=引用 2 楼 mxway 的回复:] while(~scanf("%d %d",&n,&m)) 改为 while(scanf("%d %d",&n,&m)!=EOF)不是这个的原因，~的意思和！=EOF是一样的，刷题一般都用~代替，简单[/quote] 把程序中所有的float改成double，有可能是float的精度不够。[/quote]有道理，我刚算了，成绩累加后能达到千位，加上两个小数有可能会导致精度不够，不错不错

引用 5 楼 user-2 的回复:Time Limit: 2000/1000 MSMS是毫秒吧？是啊，

Time Limit: 2000/1000 MSMS是毫秒吧？

引用 3 楼 jianjiu7 的回复:[quote=引用 2 楼 mxway 的回复:] while(~scanf("%d %d",&n,&m)) 改为 while(scanf("%d %d",&n,&m)!=EOF)不是这个的原因，~的意思和！=EOF是一样的，刷题一般都用~代替，简单[/quote] 把程序中所有的float改成double，有可能是float的精度不够。

引用 2 楼 mxway 的回复:while(~scanf("%d %d",&n,&m)) 改为 while(scanf("%d %d",&n,&m)!=EOF)不是这个的原因，~的意思和！=EOF是一样的，刷题一般都用~代替，简单


Question: 关于变量类型问题

是否可以考虑一下C++的模板类或者泛型啊？

优先考虑这样设计合不合理，有没有别的方案，别人看不看得懂，毕竟不是像python这种动态语言想怎么赋值就怎么赋值

引用 14 楼 sensal 的回复:[quote=引用 12 楼 SXJIAKE 的回复:] 你这个写法无敌了：if(B=0) typedef dataType int; else if(B=1) typedef dataType float; 怎么说？[/quote]typedef 是编译时指令……

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

引用 12 楼 SXJIAKE 的回复:你这个写法无敌了：if(B=0) typedef dataType int; else if(B=1) typedef dataType float; 怎么说？

引用 12 楼 SXJIAKE 的回复:你这个写法无敌了：if(B=0) typedef dataType int; else if(B=1) typedef dataType float; 使用类似的代码生成技术。

引用 8 楼 yangyunzhao 的回复:void*不可以吗？ 由于可能的类型包括数组，void* 表示不了数组的长度，所以void*可能不能使用。

引用 9 楼 sholber 的回复:这种问题，笼统地说哪种方法好，是不正确的。得看你想做什么，准备怎么干， 才能确定一种最好的方法。 嗯，我是想确定一下有没有已经成熟的处理这种情况的技术、模板之类的，总比我自己关门造车要好一点。

void*不可以吗？

引用 4 楼 zhao4zhong1 的回复:参考各种Variant的实现。 谢谢

引用 2 楼 sensal 的回复:谢谢你的回答、解惑，这类问题就只能通过使用union来解决吗（包括variant类型）？有没有其他的解决方案，比如说我上面描述第二个思路，当然我知道它行不通，但我还是想知道有没有其他的思路！ 谢谢

引用 3 楼 jiqiang01234 的回复:如果可取的类型确定，可以用boost::variant<>，如果类型不固定，可以用boost::any 谢谢

类型都不同，使用的时候不判断，可能么？ 参考Variant类型，内部是一个类型标志加union结构，但使用时还是要判断类型标志，这不可避免。

参考各种Variant的实现。


Question: 无法运行请问错误在哪 c语言  谢谢

改成：return 0; （你写成冒号了，需要英文下的分号）

给分啊~~~都帮你解决问题 别人~~~

VS2015： #include<string.h> #include<stdio.h> int main(void) { 	char name[10], firstname[10]; 	int a, b; 	printf("input your name:\n"); 	scanf_s("%s", &name,10); 	printf("input your firstname:\n"); 	scanf_s("%s", &firstname,10); 	a = strlen(name); 	b = strlen(firstname); 	printf("%s %s.\n,%d %d.\n", name, firstname, a, b); 	printf("%s %s.\n,%d %d.\n", name, firstname, a, b); 	return 0; }  按照你的改了下 。 俺是小白 刚学个把月。 错了见谅哈。

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

return 0: 后面应该是分号

好伤心，笔误。学艺不精啊


Question: 一个问题？？？？

数组作为参数传递的时候，不能直接传的 一般传递是  数组名 和数组大小 分开写

请那些喜欢将数组作为函数参数传来传去的码农思考一下为什么不把整个互联网内容当作函数参数传来传去呢？

VS中不支持C99的变长数组VLA

求告之，求告知，求告知！！！


Question: 关于矩阵的问题,请大神帮忙指点一下

仅供参考，仅供参考。

引用 1 楼 zhao4zhong1 的回复:仅供参考：//有一个6x6的矿区，分布有4处铁矿和4处煤矿，中心2x2已预先分配给4家公司经营。 //要求给出所有可能，将整个矿区划分为形状相同，内部连通，且恰好包含铁矿煤矿各一处的4块 //给这4家公司。 // 012345  012345  012345 //0...... 0.....M 0CCAAAA //1...... 1....I. 1CCABAA //2..AB.. 2...M.. 2CAABBB //3..CD.. 3..MMI. 3CCCDDB //4...... 4..I... 4DDCDBB //5...... 5....I. 5DDDDBB #include <stdio.h> #include <time.h> #include <stdlib.h> #include <string.h> char W[6][6]; char M[6][6]; int Y[9],X[9]; char S[1000][37]; char s[37]; int N=0; void divide(int y,int x,int L) {     int m,y1,x1;     int b,y2,x2;      Y[L]=y;X[L]=x;     W[  y][  x]='A';     W[  x][5-y]='B';     W[5-x][  y]='C';     W[5-y][5-x]='D';     if (L>=8) {         for (y1=0;y1<6;y1++) {             for (x1=0;x1<6;x1++) {                 s[y1*6+x1]=W[y1][x1];             }         }         s[36]=0;         for (m=0;m<N;m++) if (0==strcmp(s,S[m])) break;         if (m>=N) {             strcpy(S[N],s);             N++; //          printf("N%d:\n",N); //          for (m=0;m<6;m++) printf("%.6s\n",s+m*6); //          printf("\n"); //          getchar();             if (N>=1000) {                 printf("N>=1000!\n");                 exit(1);             }         }         W[  y][  x]='.';         W[  x][5-y]='.';         W[5-x][  y]='.';         W[5-y][5-x]='.';         return;     }     for (b=L;b>=0;b--) {         y2=Y[b];x2=X[b];         if ((y2>0 && W[y2-1][x2  ]=='.')          || (x2>0 && W[y2  ][x2-1]=='.')          || (y2<5 && W[y2+1][x2  ]=='.')          || (x2<5 && W[y2  ][x2+1]=='.')) {             for (m=0;m<4;m++) {                 switch (m) {                 case 0://上                     y1=y2-1;x1=x2;                     if (y1<0) continue;                 break;                 case 2://左                     y1=y2;x1=x2-1;                     if (x1<0) continue;                 break;                 case 1://下                     y1=y2+1;x1=x2;                     if (y1>5) continue;                 break;                 case 3://右                     y1=y2;x1=x2+1;                     if (x1>5) continue;                 break;                 }                 if (W[  y1][  x1]=='.'                  && W[  x1][5-y1]=='.'                  && W[5-x1][  y1]=='.'                  && W[5-y1][5-x1]=='.') {                     divide(y1,x1,L+1);                     W[  y1][  x1]='.';                     W[  x1][5-y1]='.';                     W[5-x1][  y1]='.';                     W[5-y1][5-x1]='.';                 }             }         }     } } int main() {     int i,n,a,b,t;     int d[36];     int y,x;     int Ic[4],Mc[4];      srand(time(NULL));     n=36;     for (i=0;i<n;i++) d[i]=i;/* 填写0～n-1 */     for (i=n;i>0;i--) {/* 打乱0～n-1 */         a=i-1;b=rand()%i;         if (a!=b) {t=d[a];d[a]=d[b];d[b]=t;}     }     for (y=0;y<6;y++) for (x=0;x<6;x++) {         W[y][x]='.';M[y][x]='.';     }     for (i=0;i<4;i++) M[d[i]/6][d[i]%6]='I';//铁     for (i=4;i<8;i++) M[d[i]/6][d[i]%6]='M';//煤     for (y=0;y<6;y++) {         for (x=0;x<6;x++) {             printf("%c",M[y][x]);         }         printf("\n");     }     printf("\n");     divide(2,2,0);     n=0;     for (i=0;i<N;i++) {         for (t=0;t<4;t++) {Ic[t]=0;Mc[t]=0;}         for (y=0;y<6;y++) {             for (x=0;x<6;x++) {                 if (M[y][x]=='I') Ic[S[i][y*6+x]-'A']++;                 if (M[y][x]=='M') Mc[S[i][y*6+x]-'A']++;             }         }         if (Ic[0]==1 && Ic[1]==1 && Ic[2]==1 && Ic[3]==1          && Mc[0]==1 && Mc[1]==1 && Mc[2]==1 && Mc[3]==1) {             n++;             printf("%d:\n",n);             for (t=0;t<6;t++) printf("%.6s\n",S[i]+t*6);             printf("\n");         }     }     if (n==0) printf("Impossible.\n");     return 0; } //..M... //I.M..I //...... //...M.M //...I.. //....I. // //1: //CCCAAA //CAAABA //CCABBA //DCCDBB //DCDDDB //DDDBBB // //2: //CCCAAA //CCAAAA //CCABBA //DCCDBB //DDDDBB //DDDBBB // //   不是很明白,我现在做的每个 # 的位置固定, 现在变换没有做好. 能给点提示吗? 比如  ### ## 怎样变换成 #0#0# 0#0#0  或者 ### 00##


Question: 敲了一段C代码，感觉逻辑上理解的通，调试后出现了很多错误提示，自己也没办法解决，请各位朋友帮忙忙

楼上的都告诉你具体原因了 简单来说就是你把数组数量计算错了，数组从0开始，长度为5的数组，0 1 2 3 4 没有5 另外就是，这个玩意在ubuntu12上面用gcc编译，不会报错，可以运行 这种错误如果出现在大程序里，问题隐蔽，不会必出，找bug要找半天

#include<stdio.h> #include<malloc.h> #include<string.h> void main() { char *src="hello,world";//创建一字符指针变量，并进行初始化，src指向字符串首地址 char *dest=NULL;//创建一字符指针变量，指向空指针      int len;  len=strlen(src)+1;//字符串所含字符数+1，即12 dest=(char*)malloc(len);//堆中申请len个字节的内存,并将首地放入dest指针变量中 char *d=dest;//创建一字符指针变量d，指向所申请内存的首地址 char *s=&src[len-2];//创建一字符指针变量s，将"hello,world"中最后一个字符的地址存入s while(len>=0)//将"hello,world"字符串中的字符倒序放入所申请的内存空间内 {   *d=*s;     d++;//该语句在循环中被执行13次     s--; len--;//12,11,...,2,1,0 } *d='\0';//补上字符串结束标志'\0'←企图往dest+12地址处写字节0，越界! printf("%s\n",dest); free(dest);//释放所申请的内存 }  “多一少一”问题占程序员常犯错误的10%以上！ 避免“多一少一”问题的方法之一是将比如<10甚至<5的数代入程序片断，搬手指头心算验证一下程序到底应该写为 x、x-1、x+1中的哪个？ <、<=、==、>、>=中的哪个？

引用 13 楼 DTCPzhuxh 的回复:应该和编译器有关系，楼主程序语法没有什么问题。 我在linux编译器上编译是可以通过的,但是在AIX上可以编译通过，但是在执行*d=*s时，报段错误。 希望能帮助到楼主！我下次在linux系统上调试一下，我还是*d=*s还是就出错了，VC++不认

引用 12 楼 zhao4zhong1 的回复:要么编译或链接未通过 要么断点设在了没有实际汇编指令对应的C/C++语句处 要么断点设在了编译优化后没有实际汇编指令对应的C/C++语句处 要么……虽然后面两条不是很懂，不过还是谢谢回答

引用 8 楼 zhao4zhong1 的回复:偶遇到类似问题都是用 “每次用/*...*/注释掉不同部分再重新编译，直到定位到具体语法出错的位置。” 的方法解决的。是个不错的办法！~  我想请问下，我程序设了断点都没法调试，大概是哪个环节出错了呢

引用 6 楼 licusliu 的回复:vs编译可以运行   无错误 我一运行就出现上面我贴出的错误提示怎么回事哦

引用 7 楼 cfjtaishan 的回复:[quote=引用 4 楼 lkcool7 的回复:] 首先，谢谢楼上两位朋友的回答，根据你们回答的内容我修改了程序但是在提示窗口还是出现了错误，提示如下： 1>d:\用户目录\documents\visual studio 2005\projects\test70\main.c(9) : warning C4267: '=' : conversion from 'size_t' to 'int', possible loss of data 1>d:\用户目录\documents\visual studio 2005\projects\test70\main.c(13) : error C2143: syntax error : missing ';' before 'type' 1>d:\用户目录\documents\visual studio 2005\projects\test70\main.c(14) : error C2143: syntax error : missing ';' before 'type' 1>d:\用户目录\documents\visual studio 2005\projects\test70\main.c(17) : error C2065: 'd' : undeclared identifier 1>d:\用户目录\documents\visual studio 2005\projects\test70\main.c(17) : error C2100: illegal indirection 1>d:\用户目录\documents\visual studio 2005\projects\test70\main.c(17) : error C2065: 's' : undeclared identifier 1>d:\用户目录\documents\visual studio 2005\projects\test70\main.c(17) : error C2100: illegal indirection 1>d:\用户目录\documents\visual studio 2005\projects\test70\main.c(22) : error C2100: illegal indirection 1>生成日志保存在“file://d:\用户目录\Documents\Visual Studio 2005\Projects\test70\Debug\BuildLog.htm” 1>draft1 - 7 个错误，1 个警告 目前怀疑是你的编译环境的问题吧；另外，编写代码时注意中英文字符；我是在Linux编译你这部分代码的；代码是没问题的，只有可能是编译环境的问题了；[/quote]   我最后想到的可能就是这个原因，在VC++中老是有问题，解决不了。

引用 4 楼 lkcool7 的回复:首先，谢谢楼上两位朋友的回答，根据你们回答的内容我修改了程序但是在提示窗口还是出现了错误，提示如下： 1>d:\用户目录\documents\visual studio 2005\projects\test70\main.c(9) : warning C4267: '=' : conversion from 'size_t' to 'int', possible loss of data 1>d:\用户目录\documents\visual studio 2005\projects\test70\main.c(13) : error C2143: syntax error : missing ';' before 'type' 1>d:\用户目录\documents\visual studio 2005\projects\test70\main.c(14) : error C2143: syntax error : missing ';' before 'type' 1>d:\用户目录\documents\visual studio 2005\projects\test70\main.c(17) : error C2065: 'd' : undeclared identifier 1>d:\用户目录\documents\visual studio 2005\projects\test70\main.c(17) : error C2100: illegal indirection 1>d:\用户目录\documents\visual studio 2005\projects\test70\main.c(17) : error C2065: 's' : undeclared identifier 1>d:\用户目录\documents\visual studio 2005\projects\test70\main.c(17) : error C2100: illegal indirection 1>d:\用户目录\documents\visual studio 2005\projects\test70\main.c(22) : error C2100: illegal indirection 1>生成日志保存在“file://d:\用户目录\Documents\Visual Studio 2005\Projects\test70\Debug\BuildLog.htm” 1>draft1 - 7 个错误，1 个警告 目前怀疑是你的编译环境的问题吧；另外，编写代码时注意中英文字符；我是在Linux编译你这部分代码的；代码是没问题的，只有可能是编译环境的问题了；

vs编译可以运行   无错误

1   #include<stdio.h>                                                                                1 #include<malloc.h>     2 #include<string.h>     3          4 int main(void)     5 {    >>  6     char *src="hello,world";     7     char *dest=NULL;     8     int len;     9     len=strlen(src)+1;    10     dest=(char*)malloc(len);    11     if (NULL == dest)    12     |   return -1;    13     char *d=dest;    14     char *s=&src[len-2];    15         16     while(len > 1) {    17     |   putchar(len+'a');   //用于查看拷贝了多少个字符    18     |   *d=*s;    19     |   d++;    20     |   s--;    21     |   len--;    22     }    23     putchar(10);    24     *d='\0';    25     printf("%s\n",dest);    26     free(dest);    27         28     return 0;    29 }      ~

所以问题还是没有得到解决，我是用的VC++平台，难道在这环境下没法运行此程序？？

论坛里怎么回复帖子哦？

while(len>=0)应该改成while(len-1>0) 楼主多循环了两次，越界了，破坏了堆空间，所以free的时候报出异常了


Question: win10系统中用Dev C++和Codeblocks的debug功能在输入数据时没显示

引用 3 楼 zhao4zhong1 的回复:fflush(stdin);//Linux下好象不支持。  学习了。我是win系统。

fflush(stdin);//Linux下好象不支持。

引用 1 楼 zhao4zhong1 的回复:在每个最后不带\n的printf后面加fflush(stdout); 在每个不想受接收缓冲区旧内容影响的scanf前面加rewind(stdin); 另外请检查scanf的返回值。 //请今后要用 int c; scanf("%c",&c); //时，都改为 char s[2]; int c; scanf("%1s",s); c=s[0]; 是这个原因吗？请问rewind(stdin)和fflush(stdin)是同样的效果吗？


Question: 超长整数赋值问题

4357186184021382204544表示的是int类型  4357186184021382204544.0是double  4357186184021382204544.0f 是float  所以写成；double p = 4357186184021382204544.0;

用string形式或者是数组做。 然后自己写+-*/的算法。


Question: 怎么开辟动态二位数组

malloc

“多一少一”问题占程序员常犯错误的10%以上！ 避免“多一少一”问题的方法之一是将比如<10甚至<5的数代入程序片断，搬手指头心算验证一下程序到底应该写为 x、x-1、x+1中的哪个？ <、<=、==、>、>=中的哪个？

根据赵四老师的回复改的，但是不对啊。。啊。。 #include <stdio.h> #include <stdlib.h> #include <malloc.h> int **newarr2d(int rows,int cols) {     int **p,i;       p=(int **)malloc(rows*sizeof(int *));     if (NULL==p) exit(1);     for (i=0;i<rows;i++) {         p[i]=(int *)malloc(cols*sizeof(int));         if (NULL==p[i]) exit(1);     }     return p; } void deletearr2d(int **p,int rows) {     int i;       for (i=0;i<rows;i++) {         free(p[i]);     }     free(p); } void  main() {     int **arr2d,i,j,r,c,**arr3d,m,n,o,p;        scanf("%d",&m);    scanf("%d",&n);       //在堆中开辟一个4×5的二维int数组     arr2d=newarr2d(m,n);     for (i=0;i<m;i++) {         for (j=0;j<n;j++) {            scanf("%d", arr2d[i][j]);         }     }        scanf("%d",&r);     scanf("%d",&c);      //在堆中开辟一个6×3的二维int数组     arr3d=newarr2d(r,c);     for (i=0;i<r;i++) {         for (j=0;j<c;j++) {             scanf("%d",arr3d[i][j]);         }     }   	scanf("%d",&o); 	scanf("%d",&p); 	for(i=o-1;i<r&&i<m;i++){ 		for(j=p-1;j<c&&j<n;j++){ 			arr2d[i][j]=arr3d[i][j]; 		} 	} 	for(i=0;i<m;i++) 	{ 		for(j=0;j<n;j++) 		{ 			printf("%d" ,arr2d[i][j]); 		} 		printf("\n"); 	}  	deletearr2d(arr2d,r);     deletearr2d(arr3d,r);       }

仅供参考：#include <stdio.h> #include <stdlib.h> #include <malloc.h> int **newarr2d(int rows,int cols) {     int **p,i;      p=(int **)malloc(rows*sizeof(int *));     if (NULL==p) exit(1);     for (i=0;i<rows;i++) {         p[i]=(int *)malloc(cols*sizeof(int));         if (NULL==p[i]) exit(1);     }     return p; } void deletearr2d(int **p,int rows) {     int i;      for (i=0;i<rows;i++) {         free(p[i]);     }     free(p); } int main() {     int **arr2d,i,j,r,c;      r=4;     c=5;     //在堆中开辟一个4×5的二维int数组     arr2d=newarr2d(r,c);     for (i=0;i<r;i++) {         for (j=0;j<c;j++) {             arr2d[i][j]=i*c+j;         }     }     for (i=0;i<r;i++) {         for (j=0;j<c;j++) {             printf(" %2d",arr2d[i][j]);         }         printf("\n");     }     deletearr2d(arr2d,r);      r=6;     c=3;     //在堆中开辟一个6×3的二维int数组     arr2d=newarr2d(r,c);     for (i=0;i<r;i++) {         for (j=0;j<c;j++) {             arr2d[i][j]=i*c+j;         }     }     for (i=0;i<r;i++) {         for (j=0;j<c;j++) {             printf(" %2d",arr2d[i][j]);         }         printf("\n");     }     deletearr2d(arr2d,r);      return 0; } //  0  1  2  3  4 //  5  6  7  8  9 // 10 11 12 13 14 // 15 16 17 18 19 //  0  1  2 //  3  4  5 //  6  7  8 //  9 10 11 // 12 13 14 // 15 16 17 //


Question: "高半专用代用区"是啥意思?

处处留心皆学问

找到了： ]高位替代就是指这个范围的码位是两个WORD的UTF-16编码的第一个WORD。低位替代就是指这个范围的码位是两个WORD的UTF-16编码的第二个WORD。那么，高位专用替代是什么意思？我们来解答这个问题，顺便看看怎么由UTF-16编码推导Unicode编码。 如果一个字符的UTF-16编码的第一个WORD在0xDB80到0xDBFF之间，那么它的Unicode编码在什么范围内？我们知道第二个WORD的取值范围是0xDC00-0xDFFF，所以这个字符的UTF-16编码范围应该是0xDB80 0xDC00到0xDBFF 0xDFFF。我们将这个范围写成二进制： 110100 - 11 按照编码的相反步骤，取出高低WORD的后10位，并拼在一起，得到 0 1111 1111 1111 1111 即0xe0000-0xfffff，按照编码的相反步骤再加上0x10000，得到0xf0000-0x10ffff。这就是UTF-16编码的第一个WORD在0xdb80到0xdbff之间的Unicode编码范围，即平面15和平面16。因为Unicode标准将平面15和平面16都作为专用区，所以0xDB80到0xDBFF之间的保留码位被称作高位专用替代。 摘自：http://baike.baidu.com/link?url=Zhxw66zLVTWHi8WmoHOL4LQSqWCsAfoUbOrvPLRytVGls-j0sRfoSwl6Pq7B6mY3wdGilzKp9d77p0BuV1xgWa

楼上解释了“高半代用區”和“低半代用區”，这个不用解释，我已经知道并且在使用了。 我问的是“高半专用代用區”

仅供参考：#pragma comment(lib,"user32") #pragma comment(lib,"gdi32") #include <conio.h> #include <stdio.h> #include <stdlib.h> #include <windows.h> extern "C" HWND WINAPI GetConsoleWindow(); void HideTheCursor() {     CONSOLE_CURSOR_INFO cciCursor;     HANDLE hStdOut = GetStdHandle(STD_OUTPUT_HANDLE);      if(GetConsoleCursorInfo(hStdOut, &cciCursor)) {         cciCursor.bVisible = FALSE;         SetConsoleCursorInfo(hStdOut, &cciCursor);     } } void ShowTheCursor() {     CONSOLE_CURSOR_INFO cciCursor;     HANDLE hStdOut = GetStdHandle(STD_OUTPUT_HANDLE);      if(GetConsoleCursorInfo(hStdOut, &cciCursor)) {         cciCursor.bVisible = TRUE;         SetConsoleCursorInfo(hStdOut, &cciCursor);     } } int main() {     HWND  hwnd;     HDC   hdc;     HFONT hfont;     wchar_t wc[2];      system("color F0");     system("cls");     HideTheCursor();     hwnd  = GetConsoleWindow();     hdc   = GetDC(hwnd);     hfont = CreateFont(48,0,0,0,0,0,0,0,GB2312_CHARSET ,0,0,0,0,"宋体-方正超大字符集");     SelectObject(hdc,hfont);     wc[0]=0xD854u;     wc[1]=0xDC00u;     TextOutW(hdc,10,10,wc,2);     DeleteObject(hfont);     ReleaseDC(hwnd,hdc);     getch();     system("color 07");     system("cls");     ShowTheCursor();     return 0; } #if 0 代理项或代理项对是一对共同表示单个字符的 16 位 Unicode 编码值。需要记住的关键一点是： 代理项对实际上是 32 位单个字符，不能再假定一个 16 位 Unicode 编码值正好映射到一个字符。  使用代理项对 代理项对的第一个值是高代理项，包含介于 U+D800 到 U+DBFF 范围内的 16 位代码值。 该对的第二个值是低代理项，包含介于 U+DC00 到 U+DFFF 范围内的值。通过使用代理项对， 16 位 Unicode 编码系统可以对已由 Unicode 标准定义的一百多万个其他字符 (220) 进行寻址。  在传递给 XmlTextWriter 方法的任何字符串中都可以使用代理项字符。不过，代理项字符在编写的 XML 中应该有效。例如，万维网联合会 (W3C) 建议不允许在元素或属性的名称中使用代理项字符。 如果字符串包含无效的代理项对，则引发异常。  另外，可以使用 WriteSurrogateCharEntity 写出与代理项对相对应的字符实体。字符实体以十六 进制格式写出，并用以下公式生成：  (highChar -0xD800) * 0x400 + (lowChar -0xDC00) + 0x10000  如果字符串包含无效的代理项对，则引发异常。下面的示例显示将代理项对作为输入的 WriteSurrogateCharEntity 方法。  C#复制  // The following line writes 𐀀. WriteSurrogateCharEntity ('\uDC00', '\uD800'); 下面的示例生成一个代理项对文件，将其加载到 XmlReader 中，并用新的文件名保存文件。 然后，原始文件和新文件被加载回应用程序的 XML 文档对象模型 (DOM) 结构中以进行比较。  C#复制  char lowChar, highChar; char [] charArray = new char[10]; FileStream targetFile = new FileStream("SurrogatePair.xml",       FileMode.Create, FileAccess.ReadWrite, FileShare.ReadWrite);  lowChar = Convert.ToChar(0xDC00); highChar = Convert.ToChar(0xD800); XmlTextWriter tw = new XmlTextWriter(targetFile, null); tw.Formatting = Formatting.Indented; tw.WriteStartElement("root"); tw.WriteStartAttribute("test", null); tw.WriteSurrogateCharEntity(lowChar, highChar); lowChar = Convert.ToChar(0xDC01); highChar = Convert.ToChar(0xD801); tw.WriteSurrogateCharEntity(lowChar, highChar); lowChar = Convert.ToChar(0xDFFF); highChar = Convert.ToChar(0xDBFF); tw.WriteSurrogateCharEntity(lowChar, highChar);  // Add 10 random surrogate pairs. // As Unicode, the high bytes are in lower // memory; for example, word 6A21 as 21 6A. // The high or low is in the logical sense. Random random = new Random(); for (int i = 0; i < 10; ++i) {       lowChar = Convert.ToChar(random.Next(0xDC00, 0xE000));       highChar = Convert.ToChar(random.Next(0xD800, 0xDC00));       charArray[i] = highChar;       charArray[++i] = lowChar; } tw.WriteChars(charArray, 0, charArray.Length);  for (int i = 0; i < 10; ++i) {       lowChar = Convert.ToChar(random.Next(0xDC00, 0xE000));       highChar = Convert.ToChar(random.Next(0xD800, 0xDC00));       tw.WriteSurrogateCharEntity(lowChar, highChar); }  tw.WriteEndAttribute(); tw.WriteEndElement(); tw.Flush(); tw.Close();  XmlTextReader r = new XmlTextReader("SurrogatePair.xml");  r.Read(); r.MoveToFirstAttribute(); targetFile = new FileStream("SurrogatePairFromReader.xml",        FileMode.Create, FileAccess.ReadWrite, FileShare.ReadWrite);  tw = new XmlTextWriter(targetFile, null); tw.Formatting = Formatting.Indented; tw.WriteStartElement("root"); tw.WriteStartAttribute("test", null); tw.WriteString(r.Value); tw.WriteEndAttribute(); tw.WriteEndElement(); tw.Flush(); tw.Close();  // Load both result files into the DOM and compare. XmlDocument doc1 = new XmlDocument(); XmlDocument doc2 = new XmlDocument(); doc1.Load("SurrogatePair.xml"); doc2.Load("SurrogatePairFromReader.xml"); if (doc1.InnerXml != doc2.InnerXml) {       Console.WriteLine("Surrogate Pair test case failed"); } 在使用 WriteChars 方法（一次写出一个缓冲区的数据）写出时，输入中的代理项对可能 会在一个缓冲区内被意外拆分。由于代理项值是定义完善的，如果 WriteChars 遇到来自 较低范围或者较高范围的 Unicode 值，它将该值标识为代理项对的一半。当遇到  WriteChars 将导致从拆分代理项对的缓冲区写入的情况时，将引发异常。使用   IsHighSurrogate 方法检查缓冲区是否以高代理项字符结束。如果缓冲区中的最后一个   字符不是高代理项，可以将该缓冲区传递给 WriteChars 方法。  请参见 概念 使用 XmlTextWriter 创建格式正确的 XML XmlTextWriter 的 XML 输出格式设置 XmlTextWriter 的命名空间功能  #endif


Question: 简单的关于初始化的问题 求大神

printf("%lf",x);看看  -1.#IND00 对应符号位 1 , 阶码全1 , 尾数非0 .  无穷应该是 INF ..   This page will answer the following questions.  My program just printed out 1.#IND or 1.#INF (on Windows) or nan or inf (on Linux). What happened? How can I tell if a number is really a number and not a NaN or an infinity? How can I find out more details at runtime about kinds of NaNs and infinities? Do you have any sample code to show how this works? Where can I learn more? These questions have to do with floating point exceptions. If you get some strange non-numeric output where you're expecting a number, you've either exceeded the finite limits of floating point arithmetic or you've asked for some result that is undefined. To keep things simple, I'll stick to working with the double floating point type. Similar remarks hold for float types.  Debugging 1.#IND, 1.#INF, nan, and inf  If your operation would generate a larger positive number than could be stored in a double, the operation will return 1.#INF on Windows or inf on Linux. Similarly your code will return -1.#INF or -inf if the result would be a negative number too large to store in a double. Dividing a positive number by zero produces a positive infinity and dividing a negative number by zero produces a negative infinity. Example code at the end of this page will demonstrate some operations that produce infinities.  Some operations don't make mathematical sense, such as taking the square root of a negative number. (Yes, this operation makes sense in the context of complex numbers, but a double represents a real number and so there is no double to represent the result.) The same is true for logarithms of negative numbers. Both sqrt(-1.0) and log(-1.0) would return a NaN, the generic term for a "number" that is "not a number". Windows displays a NaN as -1.#IND ("IND" for "indeterminate") while Linux displays nan. Other operations that would return a NaN include 0/0, 0*∞, and ∞/∞. See the sample code below for examples.  In short, if you get 1.#INF or inf, look for overflow or division by zero. If you get 1.#IND or nan, look for illegal operations. Maybe you simply have a bug. If it's more subtle and you have something that is difficult to compute, see Avoiding Overflow, Underflow, and Loss of Precision. That article gives tricks for computing results that have intermediate steps overflow if computed directly.

float x = 0.0;

常量也有类型！ C++ Floating-Point Constants Floating-point constants specify values that must have a fractional part. These values contain decimal points (.) and can contain exponents.  Syntax  floating-constant :  fractional-constant exponent-partopt floating-suffixopt digit-sequence exponent-part floating-suffixopt  fractional-constant :  digit-sequenceopt . digit-sequence digit-sequence .  exponent-part :  e signopt digit-sequence E signopt digit-sequence  sign : one of  + –  digit-sequence :  digit digit-sequence digit  floating-suffix :one of  f l F L  Floating-point constants have a “mantissa,” which specifies the value of the number, an “exponent,” which specifies the magnitude of the number, and an optional suffix that specifies the constant’s type. The mantissa is specified as a sequence of digits followed by a period, followed by an optional sequence of digits representing the fractional part of the number. For example:  18.46 38.  The exponent, if present, specifies the magnitude of the number as a power of 10, as shown in the following example:  18.46e0      // 18.46 18.46e1      // 184.6  If an exponent is present, the trailing decimal point is unnecessary in whole numbers such as 18E0.  Floating-point constants default to type double. By using the suffixes f or l (or F or L — the suffix is not case sensitive), the constant can be specified as float or long double, respectively.  Although long double and double have the same representation, they are not the same type. For example, you can have overloaded functions like  void func( double );  and   void func( long double );

而且换成int就不会出现这种问题，很奇怪，能有人帮忙分析一下原因吗？


Question: 求大神帮我分析一下这段程序

matlab难道不能单步调试或添加输出语句输出变量值吗？

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


Question: 求大神救急！！signal函数编译的问题！！

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

编译报错 error: ‘SIG_ING’ undeclared (first use in this function) SIG_ING未声明 找找除了这里有SIG_ING其他地方还有没有.  能否看看 signal()函数

确定不是SIG_IGN。。。signal is ignored

error: ‘SIG_ING’ undeclared重装一个系统了

SIG_IGN   .....

沃日你哥哟！！！！！！！！！！！！！！！！！！！！ 我他么真是条狗！！！！！！！！ 艹！！！！！！！！！！！！！！！！IGN！！！！！！！！！！！！！！！！！！！！！！！


Question: 散分＋快来报名“C语言指针与汇编内存地址”公开课

抱歉，抱歉 其实VS2015,对C99的支持几乎是完备的,对C++11/14/17也是支持，只不过支持C17的部分内容。 至于C语言的版本演进是：1989年，ANSI发布了第一个完整的C语言标准——ANSI X3.159—1989，简称“C89”，不过人们也习惯称其为“ANSI C”。C89在1990年被国际标准组织ISO(International Organization for Standardization)一字不改地采纳，ISO官方给予的名称为：ISO/IEC 9899，所以ISO/IEC9899: 1990也通常被简称为“C90”。1999年，在做了一些必要的修正和完善后，ISO发布了新的C语言标准，命名为ISO/IEC 9899：1999，简称“C99”。[2]  在2011年12月8日，ISO又正式发布了新的标准，称为ISO/IEC9899: 2011，简称为“C11”。 C88是什么东东，也许是C语言的1.0版本吧，不知，请高人指点 这样说来，基于DOS操作系统16位的windows 1.0~3.0版的漏洞一定也不少O(∩_∩)O

关于c88-c89的就让他过去吧，目前C标准是C12&C14正在使用，最新试用版是C17了，在VS2017中用到部分C17内容O(∩_∩)O。

到底先有的蛋呢还是先有的机

把所有的回复都看完了 还是没有看到那个小程序关于c88-c89的解说

各位大神，能不能看看这个问题。 http://bbs.csdn.net/topics/391950873

欢迎来评价： http://edu.csdn.net/course/comment/2344

引用 132 楼 zhao4zhong1 的回复:听说本ID的公开课的回放视频迟迟不上线的原因是 CSDN课程的视频编辑被 将本ID的猥琐大叔形象PS成呆萌萝莉形象 的需求绞尽脑汁了。    刚看了一遍录像。 里面既没萝莉，也没大叔！

老师，特地来接分了

新传送门在此： http://bbs.csdn.net/topics/391951993

我就是来听课的。

引用 124 楼 CCDDzclxy 的回复:[quote=引用 50 楼 zhao4zhong1 的回复:] [quote=引用 46 楼 CCDDzclxy 的回复:] 赵4老师   这个直播结束后，会有录像放出来吗？ 应该会有。但不排除： 技术故障导致录像失败 无证程序员导致录像丢失 猥琐赵4老师导致录像很难看 内容太敏感导致全球黑客联盟黑掉 含违规内容导致广电总局封杀 …… [/quote] 错过直播了... 赵4老师  该放录像了啊，等着呢~~~[/quote] 我也等着呢……

犀利,太让人不懂.

完整看完，觉得【均陵鼠侠 】有点需要人关心。。。。。。。

前排强势围观

引用 125 楼 zhao4zhong1 的回复:讲课比想象的累啊！ 你双手的老茧不是这样出来的吗？

讲课比想象的累啊！

引用 50 楼 zhao4zhong1 的回复:[quote=引用 46 楼 CCDDzclxy 的回复:] 赵4老师   这个直播结束后，会有录像放出来吗？ 应该会有。但不排除： 技术故障导致录像失败 无证程序员导致录像丢失 猥琐赵4老师导致录像很难看 内容太敏感导致全球黑客联盟黑掉 含违规内容导致广电总局封杀 …… [/quote] 错过直播了... 赵4老师  该放录像了啊，等着呢~~~

支持楼主，干的漂亮！！

直播课有录像吗，错过了，真想看看


Question: vc6.0的c语言程序高分求解！！！其中的错误怎么改，求解！！！！！各位大神帮帮忙！！！急！！！明明定义了说我们有定义，帮帮忙了谢谢

printf里面的%和变量的一一对应关系 scanf里面的%和变量以及变量前加不加&的一一对应关系 是C代码中非常容易出错的地方，而且通常编译还不出错。 所以在编译源代码之前值得专门仔细检查一遍甚至多遍。  在每个最后不带\n的printf后面加fflush(stdout); 在每个不想受接收缓冲区旧内容影响的scanf前面加rewind(stdin); 另外请检查scanf的返回值。 //请今后要用 int c; scanf("%c",&c); //时，都改为 char s[2]; int c; scanf("%1s",s); c=s[0];

不是吧，竟然有，可能是我同学吧

你确定你和这个不是同一个人？ http://bbs.csdn.net/topics/391942027


Question: 又是 乱码的问题  大神教我

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

乱码是因为你存的时候一行只有41个字符，加上最后的换行符(如果是windows下那么一共就是43个字符) 而你fread的时候直接就是读取sizeof(contacts)那么长的长度自然乱码了 我没有修改你存文件的地方，只是在SearchinFile函数里改了,有三处： 1.memset(&con, 0, sizeof(CONTACTS)); //需要memset一下，因为你fread的时候是没有\0补进来的 2.fseek(fp,(k-1)*43,SEEK_SET);  //4+12+19+6+2=43(最后的+2是换行符，windows下是\r\n) 3.fread(&con.CONTACTSName,4, 1,fp); //每个成员都分别fread  #include <stdio.h> #include <stdlib.h> #include <string.h> #define N 30 typedef struct contacts {       	char CONTACTSPhone[30]; 	char CONTACTSName[10]; 	char CONTACTSAdress[10]; 	char CONTACTSPost[30]; } CONTACTS; void   access        (CONTACTS con[],int n); void   writetoFile   (CONTACTS con[],int i); int  ReadfromFile(CONTACTS con[]); void   printfcontacts(CONTACTS con[],int n); void SearchinFile(char fileName[] ,long k); int main() {        	CONTACTS con[N] ; 	int    x    ,      i       ,    n  ,j   ,m  ; 	long   k    ; 	printf("    1      存取     \n"); 	printf("    2      显示     \n"); 	printf("    3      删除记录     \n"); 	printf("    4      查询记录     \n"); 	printf("    0      退出程序      \n"); 	for(i=0;i<100;i++) 	{ 		printf("输入你需要的功能对应的数字\n"); 		scanf ("%d",&x); 		if    (x==1) 		{       printf("存入几个联系人？\n"); 		scanf ("%d",&n); 		access(con,n); 		writetoFile(con,n); 		}  		if(x==2) 		{ 			m=ReadfromFile(con); 			printfcontacts(con,m);  		} 		if(x==4) 		{ 			printf("需要查找第几个联系人？"); 			scanf("%ld",&k); 			SearchinFile("contacts.txt",k);   		} 		if(x==0) 		{ 			printf("谢谢使用"); 			break;} 		printf("\n");}   } void   access (CONTACTS con[],int n) {         	int i; 	for(i=0;i<n;i++) 	{     		printf("输入第%d个联系人姓名\n",i+1); 	scanf("%s",con[i].CONTACTSName);  	printf("输入第%d个联系人电话号码\n",i+1); 	scanf("%s",con[i].CONTACTSPhone);  	printf("输入第%d个联系人邮编\n",i+1); 	scanf("%s",con[i].CONTACTSPost);  	printf("输入第%d个联系人地址\n",i+1); 	scanf("%s",con[i].CONTACTSAdress); 	} } void writetoFile(CONTACTS con[],int n) {    	int i; 	FILE *fp; 	if((fp=fopen("contacts.txt","w"))==NULL) 	{ 		printf("打开文件失败!\n"); 		exit (0); 	}    	for(i=0;i<n;i++) 	{       		fprintf (fp, "%4s",  con[i].CONTACTSName); 	fprintf (fp, " %11s",con[i].CONTACTSPhone); 	fprintf (fp, "%19s",con[i].CONTACTSPost); 	fprintf (fp, "%6s\n", con[i].CONTACTSAdress); 	} 	fclose(fp); } int  ReadfromFile(CONTACTS con[]) { 	FILE *fp; 	int i ; 	if((fp=fopen("contacts.txt","r"))==NULL) 	{ 		printf("failure to open the file"); 		exit(0); 	} 	for(i=0;!feof(fp);i++) 	{ 		fscanf(fp, "%4s", con[i].CONTACTSName); 		fscanf(fp, " %11s", con[i].CONTACTSPhone); 		fscanf(fp, "%19s", con[i].CONTACTSPost); 		fscanf(fp, "%6s", con[i].CONTACTSAdress); 	} 	fclose(fp); 	return i-1; } void printfcontacts(CONTACTS con[],int n) { 	int i; 	for(i=0;i<n;i++) 	{    		printf ("%4s", con[i].CONTACTSName); 	printf (" %11s",con[i].CONTACTSPhone); 	printf ("%19s",con[i].CONTACTSPost); 	printf ("%6s\n", con[i].CONTACTSAdress);  	} } void SearchinFile(char fileName[] ,long k) {        	int i ; 	FILE *fp; 	CONTACTS con; 	memset(&con, 0, sizeof(CONTACTS)); 	if((fp=fopen(fileName,"r"))==NULL) 	{ 		printf("打开文件失败!\n"); 		exit (0); 	} 	//fseek(fp,(k-1)*sizeof(CONTACTS),SEEK_SET); 	//fread(&con,sizeof(CONTACTS), 1,fp); 	fseek(fp,(k-1)*43,SEEK_SET); 	fread(&con.CONTACTSName,4, 1,fp); 	printf ("%4s", con.CONTACTSName); 	fread(&con.CONTACTSPhone,12, 1,fp); 	printf (" %11s",con.CONTACTSPhone); 	fread(&con.CONTACTSPost,19, 1,fp); 	printf ("%19s",con.CONTACTSPost); 	fread(&con.CONTACTSAdress,6, 1,fp); 	printf ("%6s\n", con.CONTACTSAdress); 	fclose(fp); }

其实不是乱码问题，而是你的程序设计的文件，你使用结构体来存储信息，但是写入的时候又不是写入的结构体。


Question: 停车场管理系统运行出错，求大神

你写这么多代码   很多人根本没空看  懂吗？？

崩溃的时候在弹出的对话框按相应按钮进入调试，按Alt+7键查看Call Stack即“调用堆栈”里面从上到下列出的对应从里层到外层的函数调用历史。双击某一行可将光标定位到此次调用的源代码或汇编指令处，看不懂时双击下一行，直到能看懂为止。  代码功能归根结底不是别人帮自己看或讲解或注释出来的；而是被自己静下心来花足够长的时间和精力亲自动手单步或设断点或对执行到某步获得的中间结果显示或写到日志文件中一步一步分析出来的。 提醒：再牛×的老师也无法代替学生自己领悟和上厕所！ 单步调试和设断点调试（VS IDE中编译连接通过以后，按F10或F11键单步执行，按Shift+F11退出当前函数；在某行按F9设断点后按F5执行停在该断点处。）是程序员必须掌握的技能之一。  printf里面的%和变量的一一对应关系 scanf里面的%和变量以及变量前加不加&的一一对应关系 是C代码中非常容易出错的地方，而且通常编译还不出错。 所以在编译源代码之前值得专门仔细检查一遍甚至多遍。  在每个最后不带\n的printf后面加fflush(stdout); 在每个不想受接收缓冲区旧内容影响的scanf前面加rewind(stdin); 另外请检查scanf的返回值。 //请今后要用 int c; scanf("%c",&c); //时，都改为 char s[2]; int c; scanf("%1s",s); c=s[0];

输入的size太小了。

谢谢老师指导 但是我查看了call stack 和watches 栈初始化有问题 不知道怎么办


Question: 一道有意思的C语言数组问题

1：按string读取，按空格进行分割到vector,排序vector时写排序函数按长度排序，从排序好的vector的最后的那个串开始往前找与其相等长度的连续iterator，即为输出 2：做一个英文字符表，每读一个字符就设置相应字符表+1，最后扫描最大值

字母计数就可以了，位图法，不多说。 单词的话，主要是去重复得遍历。 我们假定单词长度可以规定最长为50，反正我没见过超过50的长度。 长度1 单词1->单词2->单词3->....->NULL 长度2 单词4->单词5>单词6->....->NULL ..... 长度50 单词n->单词n+1->单词n+2->....->NULL

引用 3 楼 user-4 的回复:英文字母，这个么，计数就可以了  楼主的意思是要看你怎么写吧，一看就是个新手遇到复杂一点的问题就短路了

英文字母，这个么，计数就可以了

引用 1 楼 user-4 的回复:用二叉树吧， 两个key 一个是 单词 一个是计数 每找到一个单词，插入二叉树 如果还需要知道每个单词的位置，为每个单词建立一个位置列表  新手驾驭不了，大神能否写出来让我学习一下？