Question: 写了段c 求大神给给指导

仅供参考#include<stdio.h> #include<malloc.h> #include<string.h> #define STACK_INIT_SIZE 10 #define STACK_GROW_SIZE 5 #define ELEMTYPE char #define OK 1 #define ERROR 0 typedef struct { /*建立一个栈的首结点*/     ELEMTYPE * base;     ELEMTYPE * top;     int stacksize; } SpStack; int InitStack(SpStack *s) { /*建立空的栈并返回首地址*/     s->base=((ELEMTYPE*)malloc(STACK_INIT_SIZE*sizeof(ELEMTYPE)));     if (!s->base) return ERROR;     s->top=s->base;     s->stacksize=STACK_INIT_SIZE;     return OK; } int StackEmpty(SpStack *s) { /*判断栈是否为空*/     if (s->top==s->base) return OK;     else                 return ERROR; } int Push(SpStack *s,ELEMTYPE e) { /*往栈顶插入元素即进栈*/     if (s->top-s->base>=s->stacksize) { /*判断是否栈满*/         s->base=((ELEMTYPE*)realloc(s->base,(s->stacksize+STACK_GROW_SIZE)*sizeof(ELEMTYPE)));         if (!s->base) return ERROR;         s->stacksize+=STACK_GROW_SIZE;         s->top=s->base+s->stacksize;     }     *s->top++=e;     return OK; } int Pop(SpStack *s,ELEMTYPE *e) { /*让栈顶元素依次输出即出栈*/     if (StackEmpty(s)) return ERROR;     *e=*(--s->top);     return OK; } int Comp(ELEMTYPE a,ELEMTYPE b) {     if ((a=='('&&b!=')')       ||(a=='['&&b!=']')       ||(a=='{'&&b!='}')) {         return ERROR;     } else return OK; } int Count(SpStack *s) {     ELEMTYPE e[STACK_INIT_SIZE*2];     ELEMTYPE e1;     int i;      InitStack(s);     fgets(e,STACK_INIT_SIZE*2,stdin);     if ('\n'==e[strlen(e)-1]) e[strlen(e)-1]=0;     printf("%s\n",e);     for (i=0;e[i]!='\0';i++) {         switch (e[i]) {         case '(':         case '[':         case '{':             Push(s,e[i]);             break;         case ')':         case ']':         case '}':             if (StackEmpty(s)) {                 printf("%*s↖右括号多余\n",i+1,"");                 return(ERROR);             } else Pop(s,&e1);             if (!Comp(e1,e[i])) {                 printf("%*s↖左右匹配出错\n",i+1,"");                 return(ERROR);             }         }     }     if (!StackEmpty(s)) {         printf("%*s↖左括号多余\n",i,"");         return(ERROR);     } else {         printf("匹配正确\n");         return(OK);     } } void main() {     SpStack s;     Count(&s);     free(s.base); }  //现在有一段文本。。 // 我需要把文本中/*....*/（注释中的内容）提取出来，存在一个字符串变量中 // 其中注释中有空格，数字，字母，换行等 // 并且有多段注释，多段注释并不相连 // 请问该如何编写 //注意：以下代码不支持/* */嵌套比如/*A/*B*/C*/ #include <stdio.h> #define MAXL 40 char s0[]="/**/"; char s1[]="/*A*/"; char s2[]="A/*B*/"; char s3[]="A/*B*/C"; char s4[]="A/*B 1a\n*/C"; char s5[]="A/*B*//*C*/"; char s6[]="A/*B*/C/*D*/"; char s7[]="A/*B*/C/*D*/E"; char s8[]="/*A/*B*/C*/"; char s9[]="A/*B*//*C"; char t[MAXL]; int st,i,j,k,L; char c; void test(char *s) {     st=0;     i=0;     j=0;     while (1) {         c=s[i];         if (0==c) {t[j]=0;break;}         switch (st) {         case 0:// 初始状态             if ('/'==c) st=1;         break;         case 1:// '/'之后             if ('*'==c) {k=j;st=2;}             else st=0;         break;         case 2:// "/*"之后             if ('*'==c && '/'==s[i+1]) {i++;st=0;}             else {                 t[j]=c;                 j++;                 if (j>=MAXL-1) {t[j]=0;goto END;}             }         break;         }         i++;     }     if (2==st) t[k]=0; END:     printf("s[%s],t[%s]\n",s,t); } int main() {     test(s0);     test(s1);     test(s2);     test(s3);     test(s4);     test(s5);     test(s6);     test(s7);     test(s8);     test(s9);     return 0; } // s[/**/],t[] // s[/*A*/],t[A] // s[A/*B*/],t[B] // s[A/*B*/C],t[B] // s[A/*B 1a // */C],t[B 1a // ] // s[A/*B*//*C*/],t[BC] // s[A/*B*/C/*D*/],t[BD] // s[A/*B*/C/*D*/E],t[BD] // s[/*A/*B*/C*/],t[A/*B] // s[A/*B*//*C],t[B]


Question: Vs编译.c文件   .C文件调用ffmpeg

引用 6 楼 ZhaDeNianQu 的回复:[quote=引用 5 楼 qiminixi 的回复:] [quote=引用 4 楼 ZhaDeNianQu 的回复:] [quote=引用 2 楼 qiminixi 的回复:] VC6.0是C98的C语言编译器 我用的是vs2008，难道是还需要改什么配置环境吗？[/quote] 2008也是C98，不支持C99。 你看看ffmpeg的头文件是不是C99的，如果是这个问题的话，就用C++编译器吧（换成cpp文件），好像2012以上的VS才支持c99[/quote]  如何看ffmpeg头文件是c99还是c98呢？我用的是ffmpeg的2.4版本。。[/quote]  感谢了，我自己解决了。。。但并不是你的这个问题

引用 5 楼 qiminixi 的回复:[quote=引用 4 楼 ZhaDeNianQu 的回复:] [quote=引用 2 楼 qiminixi 的回复:] VC6.0是C98的C语言编译器 我用的是vs2008，难道是还需要改什么配置环境吗？[/quote] 2008也是C98，不支持C99。 你看看ffmpeg的头文件是不是C99的，如果是这个问题的话，就用C++编译器吧（换成cpp文件），好像2012以上的VS才支持c99[/quote]  如何看ffmpeg头文件是c99还是c98呢？我用的是ffmpeg的2.4版本。。

引用 4 楼 ZhaDeNianQu 的回复:[quote=引用 2 楼 qiminixi 的回复:] VC6.0是C98的C语言编译器 我用的是vs2008，难道是还需要改什么配置环境吗？[/quote] 2008也是C98，不支持C99。 你看看ffmpeg的头文件是不是C99的，如果是这个问题的话，就用C++编译器吧（换成cpp文件），好像2012以上的VS才支持c99

引用 2 楼 qiminixi 的回复:VC6.0是C98的C语言编译器 我用的是vs2008，难道是还需要改什么配置环境吗？

用qt的路过。。。

主要是这个警告问题，我调用库里面的API，为什么会提示这个api未定义。。。。。。求解


Question: 文件流中的EOF标准键盘输入中的EOF

引用 2 楼 zhao4zhong1 的回复:参考fgetc对应的源代码、 C:\Program Files\Microsoft Visual Studio\VC98\CRT\SRC\FGETC.C C:\Program Files\Microsoft Visual Studio 10.0\VC\crt\src\fgetc.c

参考fgetc对应的源代码、

那回车本身怎么输入呢


Question: linux c程序调用open函数为什么两个或三个参数都可以？

#include <stdio.h> #include <stdarg.h>   #define COUNT_PARMS2(_1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _, ...) _ #define COUNT_PARMS(...)\     COUNT_PARMS2(__VA_ARGS__, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1)  没有其他什么细节，所有东西都在这两个宏定义里面了。  首先，注意看 COUNT_PARMS2 这个宏，它是直接返回括号内第11个参数 其次，再看COUNT_PARMS这个宏： 如果它有1个参数，即__VA_ARGS__代表1个参数，那么COUNT_PARMS2的第11参数此时是1. 如果它有2个参数，即__VA_ARGS__代表2个参数，那么COUNT_PARMS2的第11参数此时是2. 如果它有3个参数，即__VA_ARGS__代表3个参数，那么COUNT_PARMS2的第11参数此时是3.    ... 如果它有10个参数，即__VA_ARGS__代表10个参数，那么COUNT_PARMS2的第11参数此时是10.

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

C语言不支持重载，但是支持可变参数。

引用 9 楼 u010527305 的回复:[quote=引用 8 楼 mujiok2003 的回复:] [quote=引用 6 楼 u010527305 的回复:] #include <stdio.h> #include <stdarg.h>  #define COUNT_PARMS2(_1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _, ...) _ #define COUNT_PARMS(...)\ 	COUNT_PARMS2(__VA_ARGS__, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1) 	 static void print_strings2(int count, ...) { 	int i; 	va_list v; 	va_start(v, count); 	 	for (i = 0; i < count; i++) 	{ 		/* Grab next parameter + print it */ 		const char *s = va_arg(v, const char *); 		printf("%s\n", s); 	} 	 	va_end(v); }  #define print_strings(...)\ 	print_strings2(COUNT_PARMS(__VA_ARGS__), __VA_ARGS__)  #define display(fmt, args...) printf(fmt, args) #define show(fmt, ...) printf(fmt, ##__VA_ARGS__) #define debug(...) printf(__VA_ARGS__)  int main(void) { 	print_strings("m y", "n y"); 	//print_strings(""); 	//int n = 7; 	//char ch = 'a'; 	//debug("n = %d, ch = %c\n", n, ch); 	//display("n = %d\nch = %c\n", n, ch); 	//show("n = %d\nch = %c\n", n, ch); 	return 0 } 在问一下，那个COUNT_PARMS(...)怎么得到的参数个数？具体细节不清楚啊 Cpp（C预处理程序）知道细节。[/quote] 您知道细节么？麻烦讲解下， #define COUNT_PARMS2(_1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _, ...) _ #define COUNT_PARMS(...)\ 	COUNT_PARMS2(__VA_ARGS__, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1) COUNT_PARMS这个宏的实现细节，它怎么就得到参数的个数了呢？[/quote] cpp会解析你的源码文件呀。

引用 8 楼 mujiok2003 的回复:[quote=引用 6 楼 u010527305 的回复:] #include <stdio.h> #include <stdarg.h>  #define COUNT_PARMS2(_1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _, ...) _ #define COUNT_PARMS(...)\ 	COUNT_PARMS2(__VA_ARGS__, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1) 	 static void print_strings2(int count, ...) { 	int i; 	va_list v; 	va_start(v, count); 	 	for (i = 0; i < count; i++) 	{ 		/* Grab next parameter + print it */ 		const char *s = va_arg(v, const char *); 		printf("%s\n", s); 	} 	 	va_end(v); }  #define print_strings(...)\ 	print_strings2(COUNT_PARMS(__VA_ARGS__), __VA_ARGS__)  #define display(fmt, args...) printf(fmt, args) #define show(fmt, ...) printf(fmt, ##__VA_ARGS__) #define debug(...) printf(__VA_ARGS__)  int main(void) { 	print_strings("m y", "n y"); 	//print_strings(""); 	//int n = 7; 	//char ch = 'a'; 	//debug("n = %d, ch = %c\n", n, ch); 	//display("n = %d\nch = %c\n", n, ch); 	//show("n = %d\nch = %c\n", n, ch); 	return 0 } 在问一下，那个COUNT_PARMS(...)怎么得到的参数个数？具体细节不清楚啊 Cpp（C预处理程序）知道细节。[/quote] 您知道细节么？麻烦讲解下， #define COUNT_PARMS2(_1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _, ...) _ #define COUNT_PARMS(...)\ 	COUNT_PARMS2(__VA_ARGS__, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1) COUNT_PARMS这个宏的实现细节，它怎么就得到参数的个数了呢？

引用 6 楼 u010527305 的回复:#include <stdio.h> #include <stdarg.h>  #define COUNT_PARMS2(_1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _, ...) _ #define COUNT_PARMS(...)\ 	COUNT_PARMS2(__VA_ARGS__, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1) 	 static void print_strings2(int count, ...) { 	int i; 	va_list v; 	va_start(v, count); 	 	for (i = 0; i < count; i++) 	{ 		/* Grab next parameter + print it */ 		const char *s = va_arg(v, const char *); 		printf("%s\n", s); 	} 	 	va_end(v); }  #define print_strings(...)\ 	print_strings2(COUNT_PARMS(__VA_ARGS__), __VA_ARGS__)  #define display(fmt, args...) printf(fmt, args) #define show(fmt, ...) printf(fmt, ##__VA_ARGS__) #define debug(...) printf(__VA_ARGS__)  int main(void) { 	print_strings("m y", "n y"); 	//print_strings(""); 	//int n = 7; 	//char ch = 'a'; 	//debug("n = %d, ch = %c\n", n, ch); 	//display("n = %d\nch = %c\n", n, ch); 	//show("n = %d\nch = %c\n", n, ch); 	return 0 } 在问一下，那个COUNT_PARMS(...)怎么得到的参数个数？具体细节不清楚啊 Cpp（C预处理程序）知道细节。

#include <sys/stat.h>  #include <fcntl.h>  int open(const char *path, int oflag, ... );   可变参数

是我幼稚了，很明显的事情没看出来。 谢谢大家，结贴

引用 2 楼 mao236244378 的回复:变参函数.. 厉害，变参函数，解决了俺的问题。

引用 1 楼 dbzhang800 的回复:http://locklessinc.com/articles/overloading/ 高手啊，给的链接太有用了。

应该是一个宏判断他的参数是2个还是3个 然后调用

变参函数..


Question: c安全编码标准中整数加法溢出的判断方法分析（补码）

《The Intel 64 and IA-32 Architectures Software Developer's Manual》

if (     (         (si1^si2)         |         (             (                 (                     si1^(                         ~(si1^si2)                         &                         (                             1 << (sizeof(int)*CHAR_BIT-1)                         )                     )                 )                 +si2             )             ^si2         )     )     >= 0 )  //有符号整形a和b,如何判断a+b是否溢出 #pragma warning(disable:4035) #include <stdio.h> int ifo_add(int a,int b) {     __asm {         mov eax,a         add eax,b         jo  overflowed         xor eax,eax         jmp no_overflowed overflowed:         mov eax,1 no_overflowed:     } } int main() {     int a,b;      a=          1;b= 2;printf("%11d+(%2d) %d\n",a,b,ifo_add(a,b));     a=         -1;b=-2;printf("%11d+(%2d) %d\n",a,b,ifo_add(a,b));     a= 2147483647;b= 1;printf("%11d+(%2d) %d\n",a,b,ifo_add(a,b));     a=-2147483647;b=-1;printf("%11d+(%2d) %d\n",a,b,ifo_add(a,b));     a=-2147483647;b=-2;printf("%11d+(%2d) %d\n",a,b,ifo_add(a,b)); } //          1+( 2) 0 //         -1+(-2) 0 // 2147483647+( 1) 1 //-2147483647+(-1) 0 //-2147483647+(-2) 1

学习了，分析的挺好 要是好好排下版，观众应该会更多的，这么一大段看着太累了

寂寞的顶一下！

嗯啊，这些东西（可移植，安全）确实牺牲不少效率，得细细斟酌考量……

引用 9 楼 zytsonny 的回复:冤枉呀，这不是我的方法，我在书里看到的，它没给解释，我看它可移植性好一些，就试着分析了一下…… 不过感谢大神的提点了！  关于可移植性： 说“跨平台一定比不跨平台好”就和说“双性恋一定比异性恋好”一样！   ←这句话不是我原创，但我很赞同。

楼主你知道你的方法编译生成的汇编指令条数是我的方法编译生成的汇编指令条数的多少倍吗？  计算机组成原理→DOS命令→汇编语言→C语言（不包括C++）、代码书写规范→数据结构、编译原理、操作系统→计算机网络、数据库原理、正则表达式→其它语言（包括C++）、架构……  对学习编程者的忠告： 多用小脑和手，少用大脑、眼睛和嘴，会更快地学会编程！ 眼过千遍不如手过一遍！ 书看千行不如手敲一行！ 手敲千行不如单步一行！ 单步源代码千行不如单步Debug版对应汇编一行！ 单步Debug版对应汇编千行不如单步Release版对应汇编一行！  VC调试时按Alt+8、Alt+7、Alt+6和Alt+5,打开汇编窗口、堆栈窗口、内存窗口和寄存器窗口看每句C对应的汇编、单步执行并观察相应堆栈、内存和寄存器变化，这样过一遍不就啥都明白了吗。 对VC来说，所谓‘调试时’就是编译连接通过以后，按F10或F11键单步执行一步以后的时候，或者在某行按F9设了断点后按F5执行停在该断点处的时候。 （Turbo C或Borland C用Turbo Debugger调试,Linux或Unix下用GDB调试时,看每句C对应的汇编并单步执行观察相应内存和寄存器变化。）

尺有所短，寸有所长。

3楼提到的方法也不错哦，不过原理不太一样，你这个还是计算了两数相加，然后判断了标志位寄存器…… 我提到的那个方法，其实在溢出的情况下是没有让两数真正相加的…… 不过感谢3楼提到的方法，学习了

引用 2 楼 user-2 的回复:学习了，分析的挺好 要是好好排下版，观众应该会更多的，这么一大段看着太累了  是的，这么一大段确实看着费劲……


Question: 为什么我还没输入折扣哪项，他就有一堆数字在

他就有一堆数字在 楼主说的他是谁啊  是说输出的未初始化的变量吧， 一开始你不赋予变量值 那里边就是个垃圾数字所以，如你所见 scanf不要这么用——http://blog.csdn.net/u012421456/article/details/18501309

变量的初始化

这就是强调变量要初始化的重要性。


Question: 宏函数里能包含条件编译吗？

只能拆成两段了。

嗯，如果实在不行的话，只能拆成2段吧

改成下面这样倒是可以编译过。  #if (FGVI == ON)   #define EXCHAN(a,b)    \   {                                     \      a = b;                         \   }  #endif  不过实际的程序里，宏函数里还有其他的代码，如下： #define EXCHAN(a,b)    \   {                                     \   #if (FGVI == ON)           \       if(a == b)                    \       {                                 \             error();               \       }                               \   #endif                            \       a->item1 = 1;              \       a->item2 = 2;             \   }

改成这样试试  #if (FGVI == ON)  #define EXCHAN(a,b)    \  {                                     \     a = b;                         \  } #endif

好像是不行啊


Question: C语言 tcp 异常断开的检测代码？

是只能做心跳处理，服务端定时给客户发包，判断是否在线

在服务端检测，只能是在连接里面做自定义的心跳处理了，你用别的办法，可能客户端没有公网地址，根本通不了

引用 6 楼 hc_net 的回复:只要做一个主动式的检测就可以了，客户端不需要，我说的是类似于ping 只要知道，客户是否在线，不管是断电了还是网线断开状态 在所有待检测的主机上运行一个服务，定期给机群管理这报告自己状态。

你是要检测某个主机是否可达还是检测某个TCP 连接是否断开？

为什么还要做一个ping呢？你就在连接里面自己做个心跳包处理不就行了？

有函数可以实现吗，反正测试过用ping 是可以，但是特殊情况下是禁 ping的

这个不行的，上面的函数是采用TCP的心跳机制进行检测的，如果需要检测指定IP的连接状态，可以自己通过心跳机制实现

不行！心跳是tcp实现操作的，没办法控制到某个ip

如果建立了端对端的tcp链接，当然可以判断是否断开 如果需要判断某些设备是否存活，试试组播


Question: 多线程编程新手求助

这个……如果你要修改的话，要用同步的方式来做，可以在线程每次循环开始的地方，同步取一下更新后的变量 建议你还是查一下线程、同步或者信号量方面的资料吧

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

引用 7 楼 xionggch 的回复:你既然把时间变量声明全局的，可以用一个线程处理时间，修改和退出可以在主程序中处理，修改时间只要在主程序中直接改变时间变量就可以了 哥们你的这方法和我最近改进的几乎差不多，我用一个while循环，里面循环的内容是先对时间变量进行赋值，然后启动走表的线程，这样可以看似做到在走表，同时终端又在等待你的输入可以随时修改时间，问题是这个循环到下一个循环的等待用户输入时间的时候，走表线程就不走了.，貌似是阻塞式的IO输入，必须等你输入了才能继续，这里是个大问题，我考虑下用信号处理好了。

引用 3 楼 xpdavis 的回复:pthread join是等待线程结束退出，楼主整个思路都不对了。你把思路理出来再说，代码看得很累  其实我最初的想法就是能够做到一个表可以在走表的时候随时暂停修改了时间之后继续走......我就想到了是不是可以用多线程来完成这个，我就想着主线程在走表，然后挂2个线程在后台，一个等待用户比如说按个E键就退出，按个C键就是修改时间，这么想是对的吗？求指出一条正确的思路，我之前还想过用信号什么的，哎，学校里面都是学java偏向应用编程的东西，基本没有和底层挂钩的，我自学APUE感觉不是很容易，关键是学了底层编程没有练手的地方，想个东西思路想不清。

用两个线程实现。。。 一个走表，一个操作。。。

引用 1 楼 xpdavis 的回复:看得很累，感觉楼主对线程的理解好像不对我也是刚刚自学了一点C底层编程，我就自己给自己想了一个题，如果只是单线程走，那么时间就一直走下去，我就想写多个线程出来，在时间走的同时还是随时更改时间。

看得很累，感觉楼主对线程的理解好像不对


Question: 大家帮忙看看这个链表 选择排序算法 哪里错了

引用 5 楼 u013337743 的回复:[quote=引用 2 楼 zhao4zhong1 的回复:] 仅供参考//带表头结点的单向链表 #include <stdio.h> #include <stdlib.h> #include <malloc.h> #include <time.h> struct NODE {     int          data;     struct NODE *next; } H,*head,*p,*q,*s1,*s2,*s3,*s4,*s; int i,j,k,n,t,m; int main() {     srand(time(NULL));      //填写头节点数据     H.data=-1;     H.next=NULL;     head=&H;      //创建10个节点的单链表     p=head;     for (i=0;i<10;i++) {         q=(struct NODE *)malloc(sizeof(struct NODE));         if (NULL==q) return 1;         q->data=rand()%100;//填写0..99的随机值         q->next=NULL;         p->next=q;         p=q;     }      //输出整个单链表     s=head->next;     while (1) {         if (NULL==s) {             printf("\n");             break;         }         printf("%02d->",s->data);         s=s->next;     }      //将值为5的结点插入到单链表的第k个结点前     k=3;     n=0;     p=head;     while (1) {         if (NULL==p) {             break;         }         n++;         if (k==n) {             q=(struct NODE *)malloc(sizeof(struct NODE));             if (NULL==q) return 1;             q->data=5;             q->next=p->next;             p->next=q;             break;         }         p=p->next;     }      //输出整个单链表     s=head->next;     while (1) {         if (NULL==s) {             printf("\n");             break;         }         printf("%02d->",s->data);         s=s->next;     }      //删除第k个节点     k=5;     n=0;     p=head;     while (1) {         if (NULL==p) {             break;         }         n++;         if (k==n) {             q=p->next;             if (q) {                 p->next=q->next;                 free(q);             }             break;         }         p=p->next;     }      //输出整个单链表     s=head->next;     while (1) {         if (NULL==s) {             printf("\n");             break;         }         printf("%02d->",s->data);         s=s->next;     }      //从小到大排序     for (p=head;p!=NULL && p->next!=NULL;p=p->next) {         for (q=p->next;q!=NULL && q->next!=NULL;q=q->next) {             if (p->next->data > q->next->data) {                  //交换data //              printf("swap %02d %02d\n",p->next->data,q->next->data); //              t=p->next->data;p->next->data=q->next->data;q->next->data=t;                  //或者                  //交换next //              printf("swap %02d %02d\n",p->next->data,q->next->data);                 s1=p->next;                 s2=p->next->next;                 s3=q->next;                 s4=q->next->next;                  if (s2!=s3) {                      p->next=s3;                     s3->next=s2;                      q->next=s1;                     s1->next=s4;                 } else {                      p->next=s3;                     s3->next=s1;                            q=s3;                     s1->next=s4;                 }                  //输出整个单链表 //              s=head->next; //              while (1) { //                  if (NULL==s) { //                      printf("\n"); //                      break; //                  } //                  printf("%02d->",s->data); //                  s=s->next; //              } //              getchar();             }         }     }      //输出整个单链表     s=head->next;     while (1) {         if (NULL==s) {             printf("\n");             break;         }         printf("%02d->",s->data);         s=s->next;     }      //将单链表中前 m 个结点和后 n 个结点进行互换,m+n为链表总长10     m=4;     n=6;     k=0;     p=head;     while (1) {         if (NULL==p) {             break;         }         k++;         if (m+1==k) {             q=p;         }         s=p;         p=p->next;     }     s1=head->next;     head->next=q->next;     s->next=s1;     q->next=NULL;      //输出整个单链表     s=head->next;     while (1) {         if (NULL==s) {             printf("\n");             break;         }         printf("%02d->",s->data);         s=s->next;     }      //释放所有节点     p=head->next;     while (1) {         if (NULL==p) {             break;         }         q=p->next;         free(p);         p=q;     }      return 0; } //18->94->58->17->27->20->43->57->75->78-> //18->94->05->58->17->27->20->43->57->75->78-> //18->94->05->58->27->20->43->57->75->78-> //05->18->20->27->43->57->58->75->78->94-> //43->57->58->75->78->94->05->18->20->27-> // ，，，麻烦老师能指出我的算法错误吗，我自己找了半天了。谢谢了[/quote]谢谢老师，我仔细看了看你的算法，发现了我的错误，那就是移动元素时同时改变了i，j等计数器指针的指向导致报错。你的算法是对的，一定要注意保持计数器指针的不变。

引用 6 楼 u013337743 的回复:[quote=引用 5 楼 u013337743 的回复:] [quote=引用 2 楼 zhao4zhong1 的回复:] 仅供参考//带表头结点的单向链表 #include <stdio.h> #include <stdlib.h> #include <malloc.h> #include <time.h> struct NODE {     int          data;     struct NODE *next; } H,*head,*p,*q,*s1,*s2,*s3,*s4,*s; int i,j,k,n,t,m; int main() {     srand(time(NULL));      //填写头节点数据     H.data=-1;     H.next=NULL;     head=&H;      //创建10个节点的单链表     p=head;     for (i=0;i<10;i++) {         q=(struct NODE *)malloc(sizeof(struct NODE));         if (NULL==q) return 1;         q->data=rand()%100;//填写0..99的随机值         q->next=NULL;         p->next=q;         p=q;     }      //输出整个单链表     s=head->next;     while (1) {         if (NULL==s) {             printf("\n");             break;         }         printf("%02d->",s->data);         s=s->next;     }      //将值为5的结点插入到单链表的第k个结点前     k=3;     n=0;     p=head;     while (1) {         if (NULL==p) {             break;         }         n++;         if (k==n) {             q=(struct NODE *)malloc(sizeof(struct NODE));             if (NULL==q) return 1;             q->data=5;             q->next=p->next;             p->next=q;             break;         }         p=p->next;     }      //输出整个单链表     s=head->next;     while (1) {         if (NULL==s) {             printf("\n");             break;         }         printf("%02d->",s->data);         s=s->next;     }      //删除第k个节点     k=5;     n=0;     p=head;     while (1) {         if (NULL==p) {             break;         }         n++;         if (k==n) {             q=p->next;             if (q) {                 p->next=q->next;                 free(q);             }             break;         }         p=p->next;     }      //输出整个单链表     s=head->next;     while (1) {         if (NULL==s) {             printf("\n");             break;         }         printf("%02d->",s->data);         s=s->next;     }      //从小到大排序     for (p=head;p!=NULL && p->next!=NULL;p=p->next) {         for (q=p->next;q!=NULL && q->next!=NULL;q=q->next) {             if (p->next->data > q->next->data) {                  //交换data //              printf("swap %02d %02d\n",p->next->data,q->next->data); //              t=p->next->data;p->next->data=q->next->data;q->next->data=t;                  //或者                  //交换next //              printf("swap %02d %02d\n",p->next->data,q->next->data);                 s1=p->next;                 s2=p->next->next;                 s3=q->next;                 s4=q->next->next;                  if (s2!=s3) {                      p->next=s3;                     s3->next=s2;                      q->next=s1;                     s1->next=s4;                 } else {                      p->next=s3;                     s3->next=s1;                            q=s3;                     s1->next=s4;                 }                  //输出整个单链表 //              s=head->next; //              while (1) { //                  if (NULL==s) { //                      printf("\n"); //                      break; //                  } //                  printf("%02d->",s->data); //                  s=s->next; //              } //              getchar();             }         }     }      //输出整个单链表     s=head->next;     while (1) {         if (NULL==s) {             printf("\n");             break;         }         printf("%02d->",s->data);         s=s->next;     }      //将单链表中前 m 个结点和后 n 个结点进行互换,m+n为链表总长10     m=4;     n=6;     k=0;     p=head;     while (1) {         if (NULL==p) {             break;         }         k++;         if (m+1==k) {             q=p;         }         s=p;         p=p->next;     }     s1=head->next;     head->next=q->next;     s->next=s1;     q->next=NULL;      //输出整个单链表     s=head->next;     while (1) {         if (NULL==s) {             printf("\n");             break;         }         printf("%02d->",s->data);         s=s->next;     }      //释放所有节点     p=head->next;     while (1) {         if (NULL==p) {             break;         }         q=p->next;         free(p);         p=q;     }      return 0; } //18->94->58->17->27->20->43->57->75->78-> //18->94->05->58->17->27->20->43->57->75->78-> //18->94->05->58->27->20->43->57->75->78-> //05->18->20->27->43->57->58->75->78->94-> //43->57->58->75->78->94->05->18->20->27-> // ，，，麻烦老师能指出我的算法错误吗，我自己找了半天了。谢谢了[/quote]谢谢老师，我仔细看了看你的算法，发现了我的错误，那就是移动元素时同时改变了i，j等计数器指针的指向导致报错。你的算法是对的，一定要注意保持计数器指针的不变。[/quote] 这就是榜样的力量！

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

引用 1 楼 r_Jimy 的回复:楼主要注意你用的都是指针，不管链表怎么移动，你未曾改变指针的值，按楼主算法，以下队列节点丢失，而且l未判空导致 对空地址求值出错 0 9 6 8 2 5  相邻:0 6 9 8 2 5  相邻:0 8 9 2 5麻烦讲清楚点好吗，前面没看懂。后面因为已对j判空，而l始终指向j前面一个节点，所以不用对l判空。

如果只交换数据，不交换节点，排序可简化为  void order(BP head) {     BP i;     BP j;     DATET dtmp = 0;      for (i=head->next;i!=NULL;i=i->next)     {         for (j=i->next;j!=NULL;j=j->next)         {             if(i->date>j->date)             {                 dtmp = j->date;                 j->date = i->date;                 i->date = dtmp;             }         }     } }


Question: libxml2解析空标记节点问题

我觉得你是把Text节点当作<>节点了，你判断一下类型看看。

Up                             Up


Question: 链表保存多项式问题

引用 8 楼 jiuchang 的回复:你把修改后的代码和编译错误发出来看看 我真觉得你的这种方法不可靠，因为我定义的poly的数据类型的前身就是linklist，这个数据类型是*linklist，所以poly后面不可能会是指针类型的数据。至于你说的直接传送结构体类型数据，改程序没有直接传送数据，而是传送的结构体类型数据的地址，只是引函数符号不过，所以我蒋隐函数符号去掉了。。 如果定义的是poly *p,那么之后所有的poly数据类型都要定义成指针型数据，编译结果如下：

你把修改后的代码和编译错误发出来看看

引用 6 楼 jiuchang 的回复:过不了是什么意思？编译不过，还是执行结果错误？ 编译不过。

过不了是什么意思？编译不过，还是执行结果错误？

大一学的太狗血了，感觉越来越没心思来看代码了。。。

引用 10 楼 jiuchang 的回复:需要对*p加括号，优先级问题 (*p)->data.coef = 0; 结果如下：  感觉还是初始化的问题...我换了一种方法，就是用return返回表头，这种方法是可行的。

需要对*p加括号，优先级问题 (*p)->data.coef = 0;

引用 2 楼 jiuchang 的回复:下面这个是有问题的 int initiate(poly p) { p=(poly)malloc(sizeof(lnode)); p->data.coef=0; p->data.expn=-1; p->next=NULL; return 0; }//初始化多项式  调用时 poly p; initiate(p); p是一个结构，initiate中申请的内在是无效的，p->next也没有被赋值为NULL.  我估计你的原意是 poly *p;  另外传参时需要传递指针类型的参数，如 initiate(poly *p); creation(poly *p); print(poly *p); 直接传结构会引起很多预料之外的问题 刚才试了一下，这样造成的结果是程序过不了....

引用 3 楼 gkl23 的回复:int initiate(poly p) int creation(poly p) 改成： int initiate(poly &p) int creation(poly &p) 即可 你这个加上引函数符号我试过，编译器过不了。


Question: 谁能帮我看看这程序？

引用 1 楼 zhao4zhong1 的回复:代码功能归根结底不是别人帮自己看或讲解或注释出来的；而是被自己静下心来花足够长的时间和精力亲自动手单步或设断点或对执行到某步获得的中间结果显示或写到日志文件中一步一步分析出来的。 提醒：再牛×的老师也无法代替学生自己领悟和上厕所！ 单步调试和设断点调试（VS IDE中编译连接通过以后，按F10或F11键单步执行，按Shift+F11退出当前函数；在某行按F9设断点后按F5执行停在该断点处。）是程序员必须掌握的技能之一。  老师根据你的方法，让我了解了程序的执行情况，使我对程序有进一步的理解。 但是程序中，我还有一点不够明白，希望老师能够继续帮我解答！！！！！  while(p!=(a+k))///这句语句是什么意思？    {     p=strrchr(a,' ');     printf("%s ",p+1);      *(p)='\0';//这里p指针为什么要加括号？和*P不一样吗？ 为什么给P赋\0，是对字符数组的结束？   }

引用 1 楼 zhao4zhong1 的回复:代码功能归根结底不是别人帮自己看或讲解或注释出来的；而是被自己静下心来花足够长的时间和精力亲自动手单步或设断点或对执行到某步获得的中间结果显示或写到日志文件中一步一步分析出来的。 提醒：再牛×的老师也无法代替学生自己领悟和上厕所！ 单步调试和设断点调试（VS IDE中编译连接通过以后，按F10或F11键单步执行，按Shift+F11退出当前函数；在某行按F9设断点后按F5执行停在该断点处。）是程序员必须掌握的技能之一。 谢谢老师！ 我是一名c语言的初学者，可能是我对编译器使用不够了解，学习方式比较落后。 之前我都不知道有这一功能，谢谢老师让我知道了一个重要技能。

引用 4 楼 misskissC 的回复:[quote=引用 3 楼 fzx6393 的回复:] [quote=引用 1 楼 zhao4zhong1 的回复:] 代码功能归根结底不是别人帮自己看或讲解或注释出来的；而是被自己静下心来花足够长的时间和精力亲自动手单步或设断点或对执行到某步获得的中间结果显示或写到日志文件中一步一步分析出来的。 提醒：再牛×的老师也无法代替学生自己领悟和上厕所！ 单步调试和设断点调试（VS IDE中编译连接通过以后，按F10或F11键单步执行，按Shift+F11退出当前函数；在某行按F9设断点后按F5执行停在该断点处。）是程序员必须掌握的技能之一。  老师根据你的方法，让我了解了程序的执行情况，使我对程序有进一步的理解。 但是程序中，我还有一点不够明白，希望老师能够继续帮我解答！！！！！  while(p!=(a+k))///这句语句是什么意思？    {     p=strrchr(a,' ');     printf("%s ",p+1);      *(p)='\0';//这里p指针为什么要加括号？和*P不一样吗？ 为什么给P赋\0，是对字符数组的结束？   }[/quote] while(p!=(a+k))表示如果p和a+k的值不等就进入循环体。p和a+k是两个地址值。 *p与*(p)结果一样。'\0'是C中一个字符串结束的标志。判断一个字符串是否结束就是用的这个标志：'\0'。[/quote] 谢谢 misskissC  zhao4zhong1 的帮助！

引用 3 楼 fzx6393 的回复:[quote=引用 1 楼 zhao4zhong1 的回复:] 代码功能归根结底不是别人帮自己看或讲解或注释出来的；而是被自己静下心来花足够长的时间和精力亲自动手单步或设断点或对执行到某步获得的中间结果显示或写到日志文件中一步一步分析出来的。 提醒：再牛×的老师也无法代替学生自己领悟和上厕所！ 单步调试和设断点调试（VS IDE中编译连接通过以后，按F10或F11键单步执行，按Shift+F11退出当前函数；在某行按F9设断点后按F5执行停在该断点处。）是程序员必须掌握的技能之一。  老师根据你的方法，让我了解了程序的执行情况，使我对程序有进一步的理解。 但是程序中，我还有一点不够明白，希望老师能够继续帮我解答！！！！！  while(p!=(a+k))///这句语句是什么意思？    {     p=strrchr(a,' ');     printf("%s ",p+1);      *(p)='\0';//这里p指针为什么要加括号？和*P不一样吗？ 为什么给P赋\0，是对字符数组的结束？   }[/quote] while(p!=(a+k))表示如果p和a+k的值不等就进入循环体。p和a+k是两个地址值。 *p与*(p)结果一样。'\0'是C中一个字符串结束的标志。判断一个字符串是否结束就是用的这个标志：'\0'。


Question: 请教如何通过SOCKET方式获取一个ZIP文件

那需要特意安装个WIN下的wget命令包吧？ 有简单的方式，如果通过SOCKET的方式去下一个FTP上的TXT文件那样简单的办法吗？只需要简单的编写一些代码.

引用 5 楼 sunrier 的回复:WIN下有简单的方式实现吗？ 调用Windows下类似wget功能的命令行工具。

WIN下有简单的方式实现吗？

从url下载文件，那不得http libcurl很方便啊。 linux下wget也很方便。

不是，不使用库。

使用curl库？

因为下载下来的ZIP文件数据不是标准的，HTTP下发的最后还有一堆不需要的数据。恩，可以了，主要注意的是这样做ZIP文件必须要以二进制形式的。

引用 9 楼 sunrier 的回复:恩，关键是下ZIP的时候获取结束标志怎么判断，ZIP文件里面有特殊字符的。 为什么要判断结束符，将接收到的内容（除了http头之外）以二进制形式(wb)写入文件即可。我刚试过了，完全可行。

恩，关键是下ZIP的时候获取结束标志怎么判断，ZIP文件里面有特殊字符的。

通过http下载zip文件和txt文件是一样的。下面是一个简单的win下http请求的示例，稍作修改便可使用。  #include <WinSock2.h> #include <stdio.h>  #pragma comment(lib,"ws2_32.lib")  int main() { 	//构造socket 	WSADATA data; 	SOCKET sock; 	if (WSAStartup(MAKEWORD(2, 2), &data) != 0) return -1; 	sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); 	if (sock == INVALID_SOCKET) 	{ 		printf("invalid socket !"); 		return -1; 	} 	 	//连接服务器 	SOCKADDR_IN addr; 	addr.sin_family = AF_INET; 	addr.sin_port = htons(80); 	addr.sin_addr.S_un.S_addr = inet_addr("127.0.0.1"); 	if (connect(sock, (SOCKADDR *)&addr, sizeof(addr)) == SOCKET_ERROR) 	{ 		printf("connect error !"); 		closesocket(sock); 		return -1; 	}  	//发送HTTP请求 	char buf[1024]; 	int count = sprintf(buf, "GET /main.c HTTP/1.1\r\nhost:%s\r\n\r\n", "127.0.0.1"); 	send(sock, buf, count, 0);  	//接收回复并打印 	count = recv(sock, buf, 1024, 0); 	if (count > 0) 	{ 		buf[count] = 0; 		printf(buf); 	}  	closesocket(sock); 	WSACleanup(); 	return 0; }


Question: 单链表的基本操作

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

非常感谢，能讲讲原因吗？

do {     //system("cls");     menu();     printf("  请选择功能 :    \n");     scanf("%d", &n);     fflush(stdin); //加此行,用以清除回车   如果不清除回车，在“输入要删除的元素”时实际得到是原先遗留的回车。


Question: 新手简单c题目求解答！

引用 6 楼 zhao4zhong1 的回复:仅供参考//输入一个小于200的字符串，将该字符串以“_”分割成小于20的字串。请输出原串和子串。 //请注意以下测试用例： //·输入空串 //·输入长度为9的字符串 //·输入长度为19的字符串 //·输入长度为20的字符串 //·输入长度为38的字符串 //·输入长度为205的字符串 //·理论上还应该考虑输入串中包含_如何处理的逻辑（这个在我的代码中没有体现） #include <stdio.h> #include <string.h> char s[201]; char d[11][21]; int i,L,n; void main() {     fgets(s,201,stdin);     L=strlen(s);     if ('\n'==s[L-1]) {s[L-1]=0;L--;}     for (i=0;i<L;i++) {         d[i/19][i%19]=s[i];         if (i!=L-1 && 18==(i%19)) {             d[i/19][19]='_';             d[i/19][20]=0;         }     }     d[i/19][i%19]=0;     if (i>0 && 0==(i%19)) {         n=i/19;     } else {         n=i/19+1;     }     printf("s=\"%s\"\n",s);     for (i=0;i<n;i++) {         printf("d[%2d]=\"%s\"\n",i,d[i]);     } } 程序好像有点超出我的理解能力了，不过谢谢了，留下来研究研究

引用 2 楼 u012421456 的回复:说实话，并不太明白你说的题意  [quote=引用 楼主 WJ_Local 的回复:] 把较长的输入行“折”成短一些的两行或多行，折行位置在输出行的第n列之前的最后一个空格符之后。 要保证程序能够智能地处理输入行很长以及在指定的列前没有空格或制表符的情况。[/quote] 题目要求： 输入“i am a student welcome to c world" 打印"i am a \nstudent  \nwelcome \nto c world\n" 程序实际运行： 输入"i am a stuent" 打印" a stuent"

引用 2 楼 u012421456 的回复:说实话，并不太明白你说的题意  [quote=引用 楼主 WJ_Local 的回复:] 把较长的输入行“折”成短一些的两行或多行，折行位置在输出行的第n列之前的最后一个空格符之后。 要保证程序能够智能地处理输入行很长以及在指定的列前没有空格或制表符的情况。[/quote]就是我输入"i am a student"程序就打印 "i am a   student"

引用 1 楼 u012421456 的回复:16行到29行的while循环，如果c不为\t、\n且else if(++pos>=N)不成立，你看会怎样不成立的话就在循环一次

说实话，并不太明白你说的题意  引用 楼主 WJ_Local 的回复:把较长的输入行“折”成短一些的两行或多行，折行位置在输出行的第n列之前的最后一个空格符之后。 要保证程序能够智能地处理输入行很长以及在指定的列前没有空格或制表符的情况。


Question: C语言中的一个问题

U代表无符号整型

C Integer Constants An “integer constant” is a decimal (base 10), octal (base 8), or hexadecimal (base 16) number that represents an integral value. Use integer constants to represent integer values that cannot be changed.  Syntax  integer-constant :  decimal-constant integer-suffix opt octal-constant integer-suffix opt hexadecimal-constant integer-suffix opt  decimal-constant :  nonzero-digit decimal-constant digit  octal-constant :  0 octal-constant octal-digit  hexadecimal-constant :  0x hexadecimal-digit 0X hexadecimal-digit hexadecimal-constant hexadecimal-digit  nonzero-digit : one of  1 2 3 4 5 6 7 8 9  octal-digit : one of  0 1 2 3 4 5 6 7  hexadecimal-digit : one of  0 1 2 3 4 5 6 7 8 9 a b c d e f A B C D E F  integer-suffix :  unsigned-suffix long-suffix opt long-suffix unsigned-suffix opt   unsigned-suffix : one of  u U  long-suffix : one of  l L  64-bit integer-suffix :  i64  Integer constants are positive unless they are preceded by a minus sign (–). The minus sign is interpreted as the unary arithmetic negation operator. (See Unary Arithmetic Operators in Chapter 4 for information about this operator.)  If an integer constant begins with the letters 0x or 0X, it is hexadecimal. If it begins with the digit 0, it is octal. Otherwise, it is assumed to be decimal.   The following lines are equivalent:  0x1C   /* = Hexadecimal representation for decimal 28 */ 034    /* = Octal representation for decimal 28 */  No white-space characters can separate the digits of an integer constant. These examples show valid decimal, octal, and hexadecimal constants.   /* Decimal Constants */ 10 132 32179  /* Octal Constants */ 012 0204 076663  /* Hexadecimal Constants */ 0xa or 0xA 0x84 0x7dB3 or 0X7DB3

C语言中的浮点数有正负之分。

U表示该常数用无符号整型方式存储，相当于unsigned int; L表示该常数用长整型方式存储，相当于long F表示该常数用浮点方式存储，相当于float

引用 楼主 palm_m 的回复:C语言中 出现"2U" 是什么意思呢？ 类似的用法还有那些，2U是不是无符号整形呢？ 如果我这么写，该如何理解 int interger=2U;  另外问一下，C语言中的浮点数有没有正负之分呢？

printf("%2u",2); 输出  2 printf("%u",2); 输出 2 前者占2隔，后者占一隔，更详细的你百度pritf吧


Question: 程序运行正确，但是自己笔下算就不正确，求解答

哦哦，受教了，谢谢

你怎么能够只算一次呢？  你要一直算到下面这个不成立才能够退出，否则一直在里面除下去。 while(m!=0)  你说的算到n=20时，m就是10了。while(m!=0)这个继续成立，所以又进入里面了。


Question: proc 编译报错Syntax error at line 45, column 40, file /usr/include/string.h:

不会吧，proc 不认识size_t ?

顶——--------

高人指点啊----


Question: C语言

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

一语见地啊，谢了哈，

为什么不编个程序试一试呢#include<stdio.h> int main() { printf("",10); return 0; }

乍看起来c++的cin、cout在输入、输出上比c的scanf、printf简单，不用格式控制符！ 但是不用格式控制符，输入输出恰好是你期望的格式的时候好说；等到输入输出不是你期望的格式的时候，你就会觉得还是用格式控制符更方便、更靠谱。 摒弃cin、cout！ 使用scanf、printf。  printf里面的%和变量的一一对应关系 scanf里面的%和变量以及变量前加不加&的一一对应关系 是C代码中非常容易出错的地方，而且通常编译还不出错。 所以在编译源代码之前值得专门仔细检查一遍甚至多遍。

谢谢大家对我的帮助哈

%d作为占位符，用变量的实际值来在该位置显示 如果省略了，那变量该在什么位置显示呢

当然不能省略了，你要实现这样的输出，就得按别人的要求来。除非你自己搞一个新东西。

可以用宏替换， 或者自己写编译器。

不用时自然省得，要用时省了如何用得？

当然不能省略


Question: 不理解主机字节序转换为网络字节序的代码

你的代码假设主机是小端字节序

单步调试这句代码

就是说字节顺序有规定。

只有小端机器才需要使用该转换，交换高低字节。 网络字节顺序采用大端排序方式，也就是低字节存高地址，高字节存低地址 如果你的机子是大端的，就无需转换了


Question: 新手求助：C Primer Plus书中高级数据一章中抽象数据类型（ADT）的问题

为啥回复不了呢...请问楼上的童鞋，我看的是C Primer Plus中文版第五版的，书上确实是按照我上面那种写法来的。我还一直想不懂呢，你的书上没有我说的问题么？ListIsEmpty(&movies)中的实参也是二级指针是吧？

不知道是否是看错了，我看原文里写的是/* display          */      if (ListIsEmpty(&movies))          printf("No data entered. ");      else      {          printf ("Here is the movie list:\n");          Traverse(&movies, showmovies);      }      printf("You entered %d movies.\n", ListItemCount(&movies));    照你所写，肯定会报一个warning类型不匹配。

你的问题问得很好，照书本的代码输入计算机编译一下看看能不能编译通过就知道了。


Question: 新手求助C语言free()问题

我不是大神诶，我理解的free就是系统把指针指向的那一块内存拿回去。 举个例子，我malloc了一块内存a给p，此时p指向a，就相当于宣布了a是p的，系统你不能再分配给别人了。之后你free它，p仍然指向a，但是它已经没有所有权了，系统想把a给谁就给谁。 这里就有个问题，free了p，p没有置NULL，还是指向a，但是系统已经把a作为b的一部分给了q，好乱啊，这是再引用p，系统也凌乱了，于是就出现野指针的问题了。

free一块内存，有点像从硬盘上删除一个文件。操作系统只是把那块空间标记为可用，但不会主动修改其中的内容。这个文件被删除之后，还有可能恢复，取决于操作系统有没有在那块空间写入其他的文件。

free(current); current = current->next; // 这么写是不对的。current虽然还指向原来的位置，但是内容有可能被覆盖。 这段代码可以这么改：         current =head; while (current != NULL) { tmp = current;                 free(current); current = tmp->next; }

1current是一个指针变量，你不显式改变，它的值是不会变的，永远指向某块内存。 2free是释放某块内存给系统，就是告诉系统，这块内存还给你，但系统不一定马上就用它。 3如果系统用了释放的内存，那这块内存的值就会改变，像你的例子中，free之后，current指向的内存块就还给系统了，会被系统使用，如果这时有其它线程申请内存，有可能就会申请到current指向的内存，也可能会更改它的成员next，使next的值不再是之前的值。这样current->next就不知道是什么东西了。

free 可以看做是向os申请 自己放弃了这个内存的使用。  因此，free之后，不对current进行赋值， current是继续指向 原来那个内存。  只有这个内存没有被分配给其它进程，他可能继续保留着原来的数据。  话说，你修改后的版本没有内存释放哦

free的意思是，这块内存我用完了，还给你。系统不会马上动手改动其中的内容，但是有可能把它分配给别人用。 current仍然指向原来的内存单元，因为你没有改变它的值。但是，如果那块内存分配给别人用了，他就可能被覆盖。如果没有分配给别人用，内容就不变。


Question: 如何自己控制线程退出？

经过思考可能是线程创建时写时复制的问题，我再研究研究

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

read(sd,buf,102400); 试试把每次读取的长度改小

这里断点不是调试时的断点，而是断点续传

主线程使用pthread_join等待了， 我考虑了read/do_write阻塞的问题，但是这个操作仅仅是一段数据包的拷贝，当下次复制数据时就应该对flag进行测试了。问题在于它会继续下载，并且下载完后，没有数据丢失

read/do_write阻塞住了，长时间没有机会检查if(thread_now->flag == 1)  可以试试boost::asio等可以中断的lib.

是多线程调试的问题吧？问题关键点不在退出，在断点没断到。

主进程是不是没有等待子线程退出？


Question: 我的TURBO C为什么SCANF不暂停？

因为楼主从来不会判断scanf函数的返回值！

scanf的格式字符串里出现什么字符，你输入的时候就得输入什么字符，才能匹配。你用了逗号，就必须输入逗号。 如果想输入时按回车，把逗号去掉或者换成空格。

问题解决了，其实不用回车，用逗号分隔数字就行了

我根本就没有输入464啊，这个数字式怎么回事？每次按回车这个界面都消失了，根本无法输入下一个数字

还有为什么每次都出现一个464？每次只能输入一个数字，和464比较，我汗啊，这是怎么回事？


Question: 如何在shell同一位置处输出数据？

使用NCURSES库。

works g++ 4.7 in ubuntu #include <iostream> #include <iomanip> #include <unistd.h>  int main() {   std::cerr << "in progress:00%" << std::setfill('0');   for (int i = 0; i < 100; i++) {     std::cerr << "\b\b\b" << std::setw(2) << i << "%";     sleep(1);   }   std::cerr << std::endl;   return 0; }

printf("progress: %3d%%", 0);   for (i = 1; i <= 100; i++) {     fflush(stdout);     sleep(1);     printf("\b\b\b\b%3d%%", i);   }

for (i = 0; i < 100; i++) {     printf("\rprogress: %d%%", i);     fflush(stdout);     sleep(1);   }

用 VT100 的控制字符, 比如 "\\033[2J" 是清屏,  "\\33[nD" 是光标左移 n 位,  "\\033[K"是清除光标位置到行尾的字符, "\\33[y;xH" 是设置光标位置..


Question: CVI如何设置程序图标？

Build->Target Settings

National Instruments CVI应该支持这样的API接口才对，但在网上没查找到对应的接口。了解的盆友麻烦帮忙告我一声。

使用exeScope软件修改exe文件的图标。

windows平台可以用api设置图标吧。

呵呵，感谢赵4老师指点。不过我想知道的是CVI编译环境中是如何设置程序图标的，了解的盆友麻烦帮忙告我一声。


Question: 关于结构体定义在main函数里头的问题，短短的程序而已

引用 14 楼 wang0635 的回复:哪个老师教的？ 自学的~

引用 13 楼 zhao4zhong1 的回复:[quote=引用 11 楼 nsxzclx 的回复:] [quote=引用 10 楼 zhao4zhong1 的回复:] #include<stdio.h> #define FORMAT  "%d\n%s\n%f\n%f\n%f\n" struct student {     int num;     char name[20];     float score[3]; }; void print(struct student *p) {     printf(FORMAT,p->num,p->name,p->score[0],p->score[1],p->score[2]); } void main() {     struct student stu={302,"Longxin",90,91,92};     print(&stu);     system("pause"); }   是的 放在main函数前边就可以了 是怎么回事呢？[/quote] 是的，把鼻子放在嘴上面就正常了 是怎么回事呢？  Summary of Declarations declaration :  declaration-specifiers attribute-seq opt init-declarator-list opt ;                         /* attribute-seq is Microsoft Specific */  declaration-specifiers :  storage-class-specifier declaration-specifiers opt type-specifier declaration-specifiers opt type-qualifier declaration-specifiers opt  attribute-seq :            /* attribute-seq is Microsoft Specific */  attribute attribute-seq opt  attribute : one of      /* Microsoft Specific */  __asm __fastcall  __based __inline  __cdecl __stdcall    init-declarator-list :  init-declarator init-declarator-list , init-declarator  init-declarator :  declarator declarator = initializer /* For scalar initialization */  storage-class-specifier :  auto register static extern typedef __declspec ( extended-decl-modifier-seq ) /* Microsoft Specific */  type-specifier :  void char short int __int8       /* Microsoft Specific */ __int16      /* Microsoft Specific */ __int32      /* Microsoft Specific */ __int64      /* Microsoft Specific */ long float double signed unsigned struct-or-union-specifier enum-specifier typedef-name  type-qualifier :  const volatile  declarator :  pointer opt direct-declarator  direct-declarator :  identifier ( declarator ) direct-declarator [ constant-expression opt] direct-declarator ( parameter-type-list )   /* New-style declarator */ direct-declarator ( identifier-list opt )      /* Obsolete-style declarator */  pointer :  * type-qualifier-list opt * type-qualifier-list opt pointer  parameter-type-list :                           /* The parameter list */  parameter-list parameter-list , ...  parameter-list :  parameter-declaration parameter-list , parameter-declaration  type-qualifier-list :  type-qualifier type-qualifier-list type-qualifier  enum-specifier :  enum identifier opt { enumerator-list } enum identifier  enumerator-list :  enumerator enumerator-list , enumerator  enumerator :  enumeration-constant enumeration-constant = constant-expression  enumeration-constant :  identifier  struct-or-union-specifier :  struct-or-union identifier opt { struct-declaration-list } struct-or-union identifier  struct-or-union :  struct union  struct-declaration-list :  struct-declaration struct-declaration-list struct-declaration  struct-declaration :  specifier-qualifier-list struct-declarator-list ;  specifier-qualifier-list :  type-specifier specifier-qualifier-list opt type-qualifier specifier-qualifier-list opt  struct-declarator-list :  struct-declarator struct-declarator-list , struct-declarator  struct-declarator :  declarator type-specifier declarator opt : constant-expression  parameter-declaration :  declaration-specifiers declarator                /* Named declarator */ declaration-specifiers abstract-declarator opt /* Anonymous declarator */  identifier-list :      /* For old-style declarator */  identifier identifier-list , identifier  abstract-declarator :         /* Used with anonymous declarators */  pointer pointer opt direct-abstract-declarator  direct-abstract-declarator :  ( abstract-declarator ) direct-abstract-declarator opt [ constant-expression opt ] direct-abstract-declarator opt ( parameter-type-list opt )  initializer :  assignment-expression { initializer-list }   /* For aggregate initialization */  { initializer-list , }  initializer-list :  initializer initializer-list , initializer  type-name :  specifier-qualifier-list abstract-declarator opt  typedef-name :  identifier  extended-decl-modifier-seq :/*   Microsoft Specific */  extended-decl-modifier opt extended-decl-modifier-seq extended-decl-modifier  extended-decl-modifier :   /* Microsoft Specific */  thread naked dllimport dllexport [/quote] 这个……谢谢你的幽默

哪个老师教的？

引用 11 楼 nsxzclx 的回复:[quote=引用 10 楼 zhao4zhong1 的回复:] #include<stdio.h> #define FORMAT  "%d\n%s\n%f\n%f\n%f\n" struct student {     int num;     char name[20];     float score[3]; }; void print(struct student *p) {     printf(FORMAT,p->num,p->name,p->score[0],p->score[1],p->score[2]); } void main() {     struct student stu={302,"Longxin",90,91,92};     print(&stu);     system("pause"); }   是的 放在main函数前边就可以了 是怎么回事呢？[/quote] 是的，把鼻子放在嘴上面就正常了 是怎么回事呢？  Summary of Declarations declaration :  declaration-specifiers attribute-seq opt init-declarator-list opt ;                         /* attribute-seq is Microsoft Specific */  declaration-specifiers :  storage-class-specifier declaration-specifiers opt type-specifier declaration-specifiers opt type-qualifier declaration-specifiers opt  attribute-seq :            /* attribute-seq is Microsoft Specific */  attribute attribute-seq opt  attribute : one of      /* Microsoft Specific */  __asm __fastcall  __based __inline  __cdecl __stdcall    init-declarator-list :  init-declarator init-declarator-list , init-declarator  init-declarator :  declarator declarator = initializer /* For scalar initialization */  storage-class-specifier :  auto register static extern typedef __declspec ( extended-decl-modifier-seq ) /* Microsoft Specific */  type-specifier :  void char short int __int8       /* Microsoft Specific */ __int16      /* Microsoft Specific */ __int32      /* Microsoft Specific */ __int64      /* Microsoft Specific */ long float double signed unsigned struct-or-union-specifier enum-specifier typedef-name  type-qualifier :  const volatile  declarator :  pointer opt direct-declarator  direct-declarator :  identifier ( declarator ) direct-declarator [ constant-expression opt] direct-declarator ( parameter-type-list )   /* New-style declarator */ direct-declarator ( identifier-list opt )      /* Obsolete-style declarator */  pointer :  * type-qualifier-list opt * type-qualifier-list opt pointer  parameter-type-list :                           /* The parameter list */  parameter-list parameter-list , ...  parameter-list :  parameter-declaration parameter-list , parameter-declaration  type-qualifier-list :  type-qualifier type-qualifier-list type-qualifier  enum-specifier :  enum identifier opt { enumerator-list } enum identifier  enumerator-list :  enumerator enumerator-list , enumerator  enumerator :  enumeration-constant enumeration-constant = constant-expression  enumeration-constant :  identifier  struct-or-union-specifier :  struct-or-union identifier opt { struct-declaration-list } struct-or-union identifier  struct-or-union :  struct union  struct-declaration-list :  struct-declaration struct-declaration-list struct-declaration  struct-declaration :  specifier-qualifier-list struct-declarator-list ;  specifier-qualifier-list :  type-specifier specifier-qualifier-list opt type-qualifier specifier-qualifier-list opt  struct-declarator-list :  struct-declarator struct-declarator-list , struct-declarator  struct-declarator :  declarator type-specifier declarator opt : constant-expression  parameter-declaration :  declaration-specifiers declarator                /* Named declarator */ declaration-specifiers abstract-declarator opt /* Anonymous declarator */  identifier-list :      /* For old-style declarator */  identifier identifier-list , identifier  abstract-declarator :         /* Used with anonymous declarators */  pointer pointer opt direct-abstract-declarator  direct-abstract-declarator :  ( abstract-declarator ) direct-abstract-declarator opt [ constant-expression opt ] direct-abstract-declarator opt ( parameter-type-list opt )  initializer :  assignment-expression { initializer-list }   /* For aggregate initialization */  { initializer-list , }  initializer-list :  initializer initializer-list , initializer  type-name :  specifier-qualifier-list abstract-declarator opt  typedef-name :  identifier  extended-decl-modifier-seq :/*   Microsoft Specific */  extended-decl-modifier opt extended-decl-modifier-seq extended-decl-modifier  extended-decl-modifier :   /* Microsoft Specific */  thread naked dllimport dllexport

引用 10 楼 zhao4zhong1 的回复:#include<stdio.h> #define FORMAT  "%d\n%s\n%f\n%f\n%f\n" struct student {     int num;     char name[20];     float score[3]; }; void print(struct student *p) {     printf(FORMAT,p->num,p->name,p->score[0],p->score[1],p->score[2]); } void main() {     struct student stu={302,"Longxin",90,91,92};     print(&stu);     system("pause"); }  看到就直接+1

引用 10 楼 zhao4zhong1 的回复:#include<stdio.h> #define FORMAT  "%d\n%s\n%f\n%f\n%f\n" struct student {     int num;     char name[20];     float score[3]; }; void print(struct student *p) {     printf(FORMAT,p->num,p->name,p->score[0],p->score[1],p->score[2]); } void main() {     struct student stu={302,"Longxin",90,91,92};     print(&stu);     system("pause"); }   是的 放在main函数前边就可以了 是怎么回事呢？

引用 1 楼 plottowan_1977 的回复:void print(struct student *p); 函数声明在struct student声明之前就已经使用了该结构，把这句话放到结构声明后面去 void main() {         struct student     {         int num;         char name[20];         float score[3];     };     void print(struct student *p);      struct student stu={302,"Longxin",90,91,92};     print(&stu);     system("pause"); } 把他放到结构声明后面，void print(struct student *p);又有问题了。

引用 6 楼 derekrose 的回复:有什么问题是很重要的 什么意思？

引用 5 楼 plottowan_1977 的回复:[quote=引用 4 楼 nsxzclx 的回复:] 会不会是因为在后面print的函数定义中也用到这个结构体，如果定义在main函数中，就不能被他用到了？  应该是的，放最外面吧[/quote]  一般都是放在外面的是吗？感觉放在里边好多问题啊

有什么问题是很重要的

引用 4 楼 nsxzclx 的回复:会不会是因为在后面print的函数定义中也用到这个结构体，如果定义在main函数中，就不能被他用到了？  应该是的，放最外面吧

#include<stdio.h> #define FORMAT  "%d\n%s\n%f\n%f\n%f\n"  void main() {	  	struct student 	{ 		int num; 		char name[20]; 		float score[3]; 	}; 	struct student stu={302,"Longxin",90,91,92}; 	void print(struct student *p);  	print(&stu); 	system("pause"); }  void print(struct student *p) { 	printf(FORMAT,p->num,p->name,p->score[0],p->score[1],p->score[2]); }


Question: 商人过河策略问题，我自己写的出了什么问题

楼主和我采用的是穷举法，找出所有可能的组合，如果其中含有成功的组合，找到这个组合的生成路径就是最终的解法

好的，大概思路就是这样，第一次发帖不懂格式，但是还是有大神回复提醒我真的好开森 感谢大神抽空看看你有什么毛病  我的水平真的很低，以为期末考试以后一辈子都和西语言没有关系了，可曾想作死的选了数学建模，现在正在和数模作业作艰苦卓绝的斗争，这回作业关系到数模公选课会不会挂科，(感觉要挂了，好想死)虽然坛子里大神都有了自己的思路了，但是还是（不自量力不得好死地）想要自己写写。

#include<stdio.h> typedef struct state /*定义两岸的状态，x是商人，y是仆人*/ { 	int x,y; }state;  state s1,s2,p[40],q[40];/*S1表示此岸状态，S2表示彼岸状态，p,q放过程的此岸状态s1*/ int k1=0,k2=0,total=0;/*k1,k2是p，q的下标计数，total是方案的计数*/   int judgestate(state e)/*判断状态是不是会杀人越货，不是的话返回1*/ { 	if(e.x==0) 		return 1; 	if(e.x>0&&e.x>=e.y) 			return 1;   	return 0; } int check1(state e)/*判断状态是不是和p过程某一步重复，不重复就返回1 */ { 	int i; 	for(i=0;i<=k1;i++) 	{ 		if(e.x==p[i].x&&e.y==p[i].y) 			return 0; 		else  			return 1; 	} } int check2(state e)/*判断状态是不是和q过程某一步重复，重复返回0*/ { { 	int i; 	for(i=0;i<=k2;i++) 	{ 		if(e.x==q[i].x&&e.y==q[i].y) 			return 0; 		else  			return 1; 	} } void prt()/*输出*/ { 	int i; 	total++; 	printf("the %dth method is:\n",total); 	for(i=0;i<k1;i++) 	{ 		printf("(%d,%d)\n",p[i].x,p[i].y); 		printf("|\n"); 		printf("(%d,%d)\n",q[i].x,q[i].y); 	} 	printf("\n"); }  void boat(state s1,state s2) { 	int i,j,m,n;/*(i,j)表示乘船过去的（商人，仆人），(m,n)表示乘船回来的（商人，仆人）*/ 	for(i=0;i<=s1.x;i++)  		for(j=0;j<=s1.y;j++)/*乘船过去的人数应当少于当前此岸人数*/ 	 			if(i+j>0&&i+j<=2)/*小船只能坐两人*/ 			{ 				s1.x-=i; 				s1.y-=j; 				s2.x+=i; 				s2.y+=j; 				 				if(!judgestate(s1)||!judgestate(s2)||!check2(s1))/*判断这次改变是否会导致杀人越货 																 以及和之前的过程有重复，如果不满足 																条件就取消这次乘船，进入下一次循环*/ 				{ 					s1.x+=i; 					s1.y+=j; 					s2.x-=i; 					s2.y-=j; 					 					continue; 				} 				q[k2++]=s1;/*符合条件，就存储过程到数组*/ 	 				if(s2.x==3&&s2.y==3)/*判断是否全部安全运过去了，完成了就输出*/ 					prt();  				else/*没有完成还要往回运*/ 				{  					for(m=0;m<=s2.x;m++) 					  						for(n=0;n<=s2.y;n++)/*往回运的过程和运出去的差不多*/ 					  							if(i+j>0&&i+j<=2) 							{ 								s1.x+=m; 								s1.y+=n; 								s2.x-=m; 								s2.y-=n; 							 								if(!judgestate(s1)||!judgestate(s2)||!check1(s1)) 								{ 									s1.x-=m; 									s1.y-=n; 									s2.x+=m; 									s2.y+=n; 									continue; 								} 								p[++k1]=s2; 								boat(s1,s2);/*递归*/ 								 								s1.x-=m; 								s1.y-=n; 								s2.x+=m; 								s2.y+=n; 								--k1;/*递归回来了之后，恢复，继续循环下去*/ 							} 				} 		 				s1.x+=i; 				s1.y+=j; 				s2.x-=i; 				s2.y-=j; 				--k2; 			} } void main() { 		s1.x=3; 		s1.y=3; 		s2.x=0; 		s2.y=0; 		p[0]=s1;/*输入初始量*/ 		boat(s1,s2); } /*这思路很小白简单吧，可是没有结果，TAT,大神求求帮忙>3<*/

要不然看起来真不方便

这个真的是你写的吗？那你用代码格式重发一下代码，像这样—— #include<stdio.h> #include<stdlib.h> #include<conio.h> typedef struct state { 	int x,y; }state;  state s1,s2,p[40],q[40]; int k1=0,k2=0,total=0;   int judgestate(state e) { 	if(e.x==0) 	return 1; 	if(e.x>0&&e.x>=e.y) 	return 1; 	  	return 0; }另外给你的上面的变量标识一下，那些变量都代表什么

是这样的思路吗？ 设商人为A B C 所带仆人分别为a b c渡河过程： 1 商人A带着随从a渡河 2 A将船划回来 3 b c两名随从接着划船渡河 4 c将船划回来 5 A B两名商人划船渡河 6 B b主仆二人划船回来 7 B C两名商人划船渡河 8 仆人a划船回来 9 仆人a b划船渡河 10 商人C划船回来 11 商人C带随从c划船渡河

补充下： 1.状态是否复复应包括岸两边的状态与船的状态，不可只判断一边 2.生成的树的所有结点都记录下来供重复性判断，这样条理更清析

问题一：你写的两个check函数中的for循环原本是想检查是否有重复步骤的，结果在else那也返回，导致只会判断一次  int check1(state e)/*判断状态是不是和p过程某一步重复，不重复就返回1 */ {     int i;     for(i=0;i<=k1;i++)     {         if(e.x==p[i].x&&e.y==p[i].y)             return 0;         else              return 1;     } }  问题二：楼主对p和q的状态判断有问题，导致死循环 当出现左岸商人为3，奴隶为0，右岸商人为0，奴隶为3，此时船在右岸，这种情况下楼主的思路 会出现死循环，情况如下： 商3奴0    ---商0奴3船 商3奴1船---商0奴2 商3奴0    ---商0奴3船 。。。。 改进思路是构建一棵树，树顶是初始状态商3奴3船---商0奴0 接下来根据不同走法生成不同的结点，当生成商0奴0---商3奴3船这样的结点时，表示成功，此时沿着该点到根 的路径就是解决方案，共2个方案

按你的思路修改的，楼主的问题下一楼指出：   #include<stdio.h> #include<stdlib.h> #include<conio.h>  #define M_STATE_OK  0 #define M_STATE_ERR 1  #define M_MAX_CHILD_NUM 100 #define M_MAX_TREE_NODES  1000 #define M_MAX_SOLUTION_NODES 1000  typedef enum { 	T_DEFAULT = 0, 	T_S1TOS2, 	T_S2TOS1, }TRANS_T;  typedef struct { 	int master,slave,tmaster,tslave; 	TRANS_T tran;  }STATE_S;  typedef struct BOAT_TREE_S { 	STATE_S node; 	int     chileNum; 	struct BOAT_TREE_S* child[M_MAX_CHILD_NUM]; 	struct BOAT_TREE_S* parent; }BOAT_TREE_T;  BOAT_TREE_T treeNodes[M_MAX_TREE_NODES] = {0};  STATE_S solution[M_MAX_SOLUTION_NODES]={0};  int solutionNum=0,solutionIndex=0,treeNodesIndex = 0;  int check_err(STATE_S* s) { 	int i=0; 	 	if (NULL == s) 	{ 		printf("impossible err\n"); 		return M_STATE_ERR; 	} 	 	if ((s->master>0&&s->master<s->slave)||(s->tmaster>0&&s->tmaster<s->tslave)) 		return M_STATE_ERR; 	 	for (i=0;i<treeNodesIndex;i++) 	{ 		if (memcmp(&treeNodes[i].node,s,sizeof(STATE_S))==0) 		{ 			return M_STATE_ERR;		 		} 	} 	return M_STATE_OK; }  void tran_boat(BOAT_TREE_T* tree) { 	int i =0; 	int j =0; 	STATE_S tmp = {0}; 	BOAT_TREE_T* searchp = tree; 	 	if (NULL == tree) 	{ 		printf("error null point!\n"); 		return; 	} 	 	if (T_S1TOS2==tree->node.tran) 	{ 		for(i=0;i<=tree->node.master;i++) 			for(j=0;j<=tree->node.slave;j++) 			{ 				if (i+j>0&&i+j<=2) 				{ 					if (treeNodesIndex>M_MAX_TREE_NODES) 					{ 						printf("err:M_MAX_TREE_NODES\n"); 						exit(1); 					} 					 					memcpy(&treeNodes[treeNodesIndex].node,&tree->node,sizeof(STATE_S)); 				 					treeNodes[treeNodesIndex].node.master-=i; 					treeNodes[treeNodesIndex].node.slave-=j; 					treeNodes[treeNodesIndex].node.tmaster+=i; 					treeNodes[treeNodesIndex].node.tslave+=j; 					treeNodes[treeNodesIndex].node.tran = T_S2TOS1; 					 					if (treeNodes[treeNodesIndex].node.master==0&&treeNodes[treeNodesIndex].node.slave==0) 					{ 						solutionNum++; 						memcpy(&solution[solutionIndex],&treeNodes[treeNodesIndex].node,sizeof(STATE_S)); 						solutionIndex++; 						 						while (searchp!=NULL) 						{ 							memcpy(&solution[solutionIndex],&searchp->node,sizeof(STATE_S)); 							solutionIndex++; 							 							if (solutionIndex>M_MAX_SOLUTION_NODES)	 							{ 								printf("err:max solution\n"); 								exit(1); 							} 							searchp = searchp->parent; 						} 					} 					else if (check_err(&treeNodes[treeNodesIndex].node)!=M_STATE_ERR) 					{ 						if (tree->chileNum>=M_MAX_CHILD_NUM) 						{ 							printf("err:max child num!\n"); 							exit(1); 						} 						//memcpy(&treeNodes[treeNodesIndex].node,&tmp,sizeof(STATE_S)); 						treeNodes[treeNodesIndex].parent = tree; 						treeNodes[treeNodesIndex].chileNum = 0; 						tree->child[tree->chileNum] = &treeNodes[treeNodesIndex]; 						tree->chileNum++; 						treeNodesIndex++; 						tran_boat(&treeNodes[treeNodesIndex-1]); 					} 				} 			} 	} 	else if(T_S2TOS1==tree->node.tran) 	{ 		for(i=0;i<=tree->node.tmaster;i++) 			for(j=0;j<=tree->node.tslave;j++) 			{ 				if (i+j>0&&i+j<=2) 				{ 					if (treeNodesIndex>M_MAX_TREE_NODES) 					{ 						printf("err:M_MAX_TREE_NODES\n"); 						exit(1); 					} 					 					memcpy(&treeNodes[treeNodesIndex].node,&tree->node,sizeof(STATE_S)); 				 					treeNodes[treeNodesIndex].node.tmaster-=i; 					treeNodes[treeNodesIndex].node.tslave-=j; 					treeNodes[treeNodesIndex].node.master+=i; 					treeNodes[treeNodesIndex].node.slave+=j; 					treeNodes[treeNodesIndex].node.tran = T_S1TOS2; 					 					if (check_err(&treeNodes[treeNodesIndex].node)!=M_STATE_ERR) 					{ 						if (tree->chileNum>=M_MAX_CHILD_NUM) 						{ 							printf("err:max child num!\n"); 							exit(1); 						} 						//memcpy(&treeNodes[treeNodesIndex].node,&tmp,sizeof(STATE_S)); 						treeNodes[treeNodesIndex].parent = tree; 						treeNodes[treeNodesIndex].chileNum = 0; 						tree->child[tree->chileNum] = &treeNodes[treeNodesIndex]; 						tree->chileNum++; 						treeNodesIndex++; 						tran_boat(&treeNodes[treeNodesIndex-1]); 					} 				} 			} 	} 	else 	{ 		printf("error!\n"); 		exit(1); 	} }  void printsolution(void) { 	int master,slave,tmaster,tslave; 	TRANS_T tran;  	 	int i = 0; 	printf("total soution num:%d\n",solutionNum); 	 	for (i=solutionIndex-1;i>=0;i--) 	{ 		if (T_S1TOS2==solution[i].tran) 		{ 			printf("s1->s2:s1(%d,%d),s2(%d,%d)\n",solution[i].master,solution[i].slave,solution[i].tmaster,solution[i].tslave); 		} 		else if (T_S2TOS1==solution[i].tran) 		{ 			printf("s2->s1:s1(%d,%d),s2(%d,%d)\n",solution[i].master,solution[i].slave,solution[i].tmaster,solution[i].tslave); 		} 	} }  void main() { 	treeNodes[0].node.master = 3; 	treeNodes[0].node.slave = 3; 	treeNodes[0].node.tmaster = 0; 	treeNodes[0].node.tslave = 0; 	treeNodes[0].node.tran = T_S1TOS2; 	treeNodes[0].chileNum = 0; 	treeNodes[0].parent = NULL; 	 	treeNodesIndex++; 	 	tran_boat(&treeNodes[0]); 	printsolution(); }


Question: C语言 size_t到底是个什么东东？

unsigned int

无符号整型。

这是在不同的机器里面的的头文件定义的相应宏定义，实际上是unsigned int。

有一说法，数组下标应为size_t类型，具体size_t占几个字节与具体环境有关

大部分情况下是unsigned int

According to the 1999 ISO C standard (C99), size_t is an unsigned integer type of at least 16 bit (see sections 7.17 and 7.18.3).

<cstddef> <cstdio> <cstdlib> <cstring> <ctime> <cwchar> size_t Unsigned integral type Alias of one of the fundamental unsigned integer types.  It is a type able to represent the size of any object in bytes: size_t is the type returned by the sizeof operator and is widely used in the standard library to represent sizes and counts.

简单理解为 unsigned int就可以了


Question: 关于watcom c 的一篇文章————转帖

比如目录下有test.c文件，在命令行用wcl test命令，在源程序没有错误的情况下就可以编译出test.exe文件了

我电脑上的autoexec.bat批处理文件是这样的： PATH \WATCOM\BINW;%PATH%; SET INCLUDE=\WATCOM\H; SET WATCOM=\WATCOM SET EDPATH=\WATCOM\EDDAT SET WIPFC=\WATCOM\WIPFC 运行这个批处理文件以后就可以用wcl命令编译文件了


Question: 调用iomarkirppending的一个问题

你跟踪下Irp->PendingReturned是在哪置位的，想来iocompleterequest这个函数定然不全如函数名那般为IRP处理 全部后事，如果有置位还需要其它操作


Question: 关于静态变量的问题

静态变量的作用域在函数内，生命期和全局变量相同。

问题已解决 有两种方法 第一种方法是将face.c中原本为局部静态变量的ID改为具有内部链接的全局变量 然后再face.c中写一个自定义函数 FaceIDReset（） {         ID=0； } 然后再在Facelist.c的for循环前面调用该函数即可完成清零  方法二 在facelist.c中，声明ID为全局变量 在for循环前面加一句ID=0； 然后在face.c中使用extern声明ID变量 使得FaceNeW中的f->faceno=ID++能够进行

这是静态变量的定义方式决定你过得  可以定义为 static int id； id=0； 便不会在累加

问题已经解决了

如果有这么简单的话   我就不会发帖子了

清不了的   试过了   没用

一次for循环后把ID清零不就行了吗


Question: 链表问题

恩  正解  谢谢

bool Make_LNode(LNode **q) {     (*q)=(LNode *)malloc(sizeof(LNode));     if(!(*q))     {         printf("分配内存失败\n");         exit(-1);     } //    *q->next=NULL;           return true; }

bool append_LinkList(LinkList q,int x) {     LNode * pa;     Make_LNode(pa);     // 这里的Make_LNode函数参数有问题，pa是临时变量，在里面申请的内存与pa无关，返回后，pa并不是指向一个有效的内存       //    printf("---1\n");           LinkList p=q;     while(p->next != NULL)     {         p=p->next;     }     p->next=pa;     pa->data=x;     pa->next=NULL; //    p=pa;            print_LinkList(q);           return true;       }


Question: ip数据包校验和的问题

顶顶，lol  wow   dota2


Question: VS2010 fopen函数打开不了目标文件

_chdir, _wchdir Change the current working directory.  int _chdir( const char *dirname );  int _wchdir( const wchar_t *dirname );  Routine Required Header Optional Headers Compatibility  _chdir <direct.h> <errno.h> Win 95, Win NT  _wchdir <direct.h> or <wchar.h> <errno.h> Win NT    For additional compatibility information, see Compatibility in the Introduction.  Libraries  LIBC.LIB Single thread static library, retail version  LIBCMT.LIB Multithread static library, retail version  MSVCRT.LIB Import library for MSVCRT.DLL, retail version    Return Value  Each of these functions returns a value of 0 if successful. A return value of –1 indicates that the specified path could not be found, in which case errno is set to ENOENT.  Parameter  dirname  Path of new working directory  Remarks  The _chdir function changes the current working directory to the directory specified by dirname. The dirname parameter must refer to an existing directory. This function can change the current working directory on any drive and if a new drive letter is specified in dirname, the default drive letter will be changed as well. For example, if A is the default drive letter and \BIN is the current working directory, the following call changes the current working directory for drive C and establishes C as the new default drive:  _chdir("c:\\temp");  When you use the optional backslash character (\) in paths, you must place two backslashes (\\) in a C string literal to represent a single backslash (\).  _wchdir is a wide-character version of _chdir; the dirname argument to _wchdir is a wide-character string. _wchdir and _chdir behave identically otherwise.  Generic-Text Routine Mapping:  TCHAR.H Routine  _UNICODE & _MBCS Not Defined _MBCS Defined _UNICODE Defined  _tchdir _chdir _chdir _wchdir    Example  /* CHGDIR.C: This program uses the _chdir function to verify  * that a given directory exists.  */  #include <direct.h> #include <stdio.h> #include <stdlib.h>  void main( int argc, char *argv[] ) {    if( _chdir( argv[1] )   )       printf( "Unable to locate the directory: %s\n", argv[1] );    else       system( "dir *.wri"); }   Output   Volume in drive C is CDRIVE  Volume Serial Number is 0E17-1702   Directory of C:\write  04/21/95  01:06p                 3,200 ERRATA.WRI 04/21/95  01:06p                 2,816 README.WRI                2 File(s)          6,016 bytes                              71,432,116 bytes free   Directory Control Routines  See Also   _mkdir, _rmdir, system

你这两个程序是在同一个目录下么？ 前面把dat文件写在某个目录下，后面在另一个目录下找肯定找不到

是文件打开模式出问题了。文件不存在时，一些模式是无法打开文件的。搜索fopen参数自己看一下各个模式的意义。

打印出lasterror信息

文件打开模式错误，rb指的是读取二进制文件，改成ab或者wb就可以


Question: 国庆放假回来啦~给我解道题呗各路c语言的大神。谢啦

刚刚问老师了，恍然大悟啊！！主要的问题是我用的是动态，可是前面在定义的时候用的却是静态的！

好多天没回来看帖子~谢谢各路大神

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

@addsspu我看懂了你的代码，我是说楼主，他好像是直接敲上去了，所以我说编译能通过么在函数中的参数大多用的是指针传递和按值传递。c++中引用多用于类中的参数传递。

http://wenku.baidu.com/link?url=dyPDHGxm_yJB9ocLWUrczQ25j-6kWFJgNwvOvjwYEIqb8EeE0tldyoRL_veyIQJO6Wy5c4i39F71cEVsu3WKHCLc0QC-kdBg2oXCVqWc5g7 看不懂

你这唯一一个scanf函数 的格式说明 那个参数呢？

新的错误，我去百度。看一看瞧一瞧嘿

引用 8 楼 u013115035 的回复:[quote=引用 6 楼 mujiok2003 的回复:] scanf("%d", l.element+i) 是scanf("%d", &l.elem[i]);  吧？[/quote] 这俩是一样的。

scanf("%d", &l.elem[i]) 你太屌了

引用 6 楼 mujiok2003 的回复:scanf("%d", l.element+i) 是scanf("%d", &l.elem[i]);  吧？

原来是格式错了

scanf("%d", l.element+i)

我找不到我哪里把 “i” 从 int 变成char型的

我这个是照书里敲进去的。。。scanf是说“i”的呀

引用 15 楼 zp_00000 的回复:在写函数的时候这样写int Delete_SqList(SqList &list, int i)编译会通过？   呵呵，C语言不能用引用&，但没说不能用取地址&啊

引用 15 楼 zp_00000 的回复:在写函数的时候这样写int Delete_SqList(SqList &list, int i)编译会通过？  Status DeleteList_Sq(SqList *L,int i,SLElemType *e);//这是函数     SqList L;    SLElemType e;   DeleteList_Sq(&L，&e)//这是调用

main.c 调用一下DestroyList_Sq(&L);

//SqList.h #ifndef SQLIST_H_ #define SQLIST_H_  #ifndef constant #define constant  #define TRUE 1 #define FALSE 0 #define OK 1 #define ERROR 0 #define INFEASIBLE -1 #define OVERFLOW -2  #include <stdlib.h> typedef int Status;  #endif /* constant */  #define LIST_INIT_SIZE 20 //线性表初始大小 #define LISTINCREMENT  5  typedef int SLElemType;  typedef struct{ 	SLElemType *elem; 	int length; 	int listsize; } SqList;  Status InitList_Sq(SqList *L); Status CreateList_Sq(SqList *L,SLElemType elem[],int n); Status DestroyList_Sq(SqList *L); Status ClearList_Sq(SqList *L); int EmptyList_Sq(SqList *L); int LengthList_Sq(SqList *L); Status GetElem_Sq(SqList *L,int i,SLElemType *e); int LocateElem_Sq(SqList *L,SLElemType e); Status InsertList_Sq(SqList *L,int i,SLElemType e); Status DeleteList_Sq(SqList *L,int i,SLElemType *e);  #endif /* SQLIST_H_ */  //SqList.c #include "SqList.h"  int mutex=0;//是否需要用free函数释放内存标志 Status InitList_Sq(SqList *L){ 	if(mutex!=0) { 	free(L->elem); 	L->elem=NULL;} 	L->elem=(SLElemType *)malloc(LIST_INIT_SIZE*sizeof(SLElemType)); 	if(!L->elem) exit(OVERFLOW); 	mutex=1; 	L->length=0; 	L->listsize=LIST_INIT_SIZE; 	return OK; }  Status CreateList_Sq(SqList *L,SLElemType elem[],int n){ 	int i; 	if(mutex!=0) { 	free(L->elem); 	L->elem=NULL;} 	L->elem=(SLElemType *)malloc((n/LIST_INIT_SIZE+1)*LIST_INIT_SIZE*sizeof(SLElemType)); 	if(!L->elem) exit(OVERFLOW); 	mutex=1; 	for(i=0;i<n;i++){ 		L->elem[i]=elem[i]; 	} 	L->length=n; 	L->listsize=LIST_INIT_SIZE*(n/LIST_INIT_SIZE+1); 	return OK; }  Status DestroyList_Sq(SqList *L){ 	free(L->elem); 	L->elem=NULL; 	mutex=0; 	return OK; }  Status ClearList_Sq(SqList *L){ 	L->length=0; 	return OK; }  int EmptyList_Sq(SqList *L){ 	return L->length==0; }  int LengthList_Sq(SqList *L){ 	return L->length; }  Status GetElem_Sq(SqList *L,int i,SLElemType *e){ 	if(i<1 || i>L->length+1) return ERROR; 	*e=L->elem[i-1]; 	return OK; }  int LocateElem_Sq(SqList *L,SLElemType e){ 	int i=0; 	while(i<L->length && L->elem[i]!=e) i++; 	if (i>=L->length) 		return 0; 	else 		return i+1; }  Status InsertList_Sq(SqList *L,int i,SLElemType e){ 	SLElemType *p,*q; 	if(i<1 || i>L->length+1) return ERROR; 	if(L->length>=L->listsize){ 		SLElemType *newbase=(SLElemType *)realloc(L->elem,(L->listsize+LISTINCREMENT)*sizeof(SLElemType)); 		if(!newbase) exit(OVERFLOW); 		L->elem=newbase; 		L->listsize=L->listsize+LISTINCREMENT;    } 	q=&L->elem[i-1]; 	for(p=& L->elem[L->length-1];p>=q;--p) *(p+1)=*p; 	*q=e; 	++L->length; 	return OK; } Status DeleteList_Sq(SqList *L,int i,SLElemType *e){ 	SLElemType *p,*q; 	if(i<1 || i>L->length+1) return ERROR; 	p=&L->elem[i-1]; 	*e=*p; 	q=L->elem+L->length-1; 	for(++p;p<=q;++p) *(p-1)=*p; 	--L->length; 	return OK; }  //main.c #include <stdio.h> #include "SqList.h"  int main(){ 	SqList L; 	int i,temp; 	InitList_Sq(&L); 	for(i=0;i<10;i++){ 		scanf("%d",&temp); 		InsertList_Sq(&L,(i+1),temp); 	} 	for(i=0;i<10;i++){ 		GetElem_Sq(&L,(i+1),&temp); 		printf("%d\t",temp); 	} 	printf("\n"); 	return 0;  }  仅供参考，欢迎交流，

scanf还能这么用


Question: 求助，知道这个函数的，可以帮忙解答一下吗


Question: 求指点：C 四叉树深度判断

啥叫最多返回1？


Question: 求助链表显示 的问题

s = s->next;  如果传进来的参数s是NULL就会出问题。 对于用头节点保存数据的链表，如果没有数据，那么头节点就是NULL。 对于头节点不保存数据的链表，应该是在创建任何链表的时候(即使没有数据)都有一个非NULL的头节点。

这要看链表是怎么创建的。 我见过有些人的链表头节点不放数据，从第二个节点才开始保存数据。我没这么做过，我感觉大多数的链表都不是这样的。

主要看所创建的链表的头结点，如果头结点没有存放数据，就是说链表是从第二个人结点开始存放数据时，打印就需要先让s = s->next;


Question: 请问下回调函数的原理是什么？

这是什么情况......

引用 10 楼 stupid_boy2007 的回复:老子7年前学Ｃ语言函数指针时，就理解回调了，你他吗这么多年是吃屎去了吗？ 操你大爷的，还给我取ID, king_2007,你是不是吃屎大王？  虽然骂人不对,但是问题说的对的,一般人学了函数指针就明白回调了

参考Microsoft SDK\src\crt\qsort.c

引用 11 楼 stupid_boy2007 的回复:还在csdn装鸟，老子的思考的问题和你不是一个层次的，傻鸟你懂吗？你有神经病，我不跟你计较。

说原理，回调函数跟goto是一样的原理 就是地址的跳转

这个。。。。。。又有私人恩怨

你他吗个傻屌，回调都不知道，还装Ｂ干过多年程序。不丢你祖宗的脸吗？ 还给我私信说， “傻逼，还在我的帖子里卖弄的代码，老子当程序员的时候，你还在玩泥巴呢！” 这不是丢你祖宗的脸吗？

引用 5 楼 lambda2007 的回复:#include <iostream> #include <vector>  using namespace std;  float fun_type1(float a, int b) {     return a + b; }   float fun_type2(float a, int b) {     return a + b * 100.0f; }  typedef  float (*FUN_TYPE)(float a, int b);  float use_fun_type(FUN_TYPE fun_type) {     float sum = 1.25f * fun_type(1.2f, 10);     return sum; }  int main() {     cout << use_fun_type(fun_type1) << endl;     cout << use_fun_type(fun_type2) << endl;     return 0; }  即把函数当参数来用。能不能用c语言，不是c++!哥们你弄懂了语言没有？？

引用 4 楼 king_2007 的回复:引用 1 楼 fsy351 的回复:简单的讲，回调就是以函数为参数实现动态调用方式。比如A，B两个函数，main函数执行过程中调用A，A的参数包括一个B类型的函数！能不能用代码实例来解释你的这句话？？ 这个网上很多的！！5楼正解！！

请问下，有没有代码例子给解释下，我就理解的更好了！另外想问下int winapi winmain()函数中的winapi是什么？？？它起什么作用？

调用一个函数，编译器会把函回调函数数名转换成函数的入口地址。这可以看成函数地址常量。如果把这个函数地址保存到参数中，再调用，就是回调函数


Question: 快速排序，写了一个快排的算法，但是发现根本就没作用啊~~求救

引用 4 楼 u012421456 的回复:在Qsort函数中数组a传过来的可以说是一个指针，占四个字节 问题多多啊！ 建议先参考一下别人的吧——http://blog.sina.com.cn/s/blog_6d3488c30100ogdt.html 3Q多多学习~

引用 2 楼 Bokutake 的回复:有些书里说C可以按值(by value)和按地址(by address)传递数组，其实是不对的，不管形参声明成数组还是指针，在函数内部，编译器始终把它当作一个指向数组第一个元素的指针。 所以如果想用 sizeof()来获取数组的长度，所得结果只能是指针的长度。 你只能用额外的参数传递数组的大小。 非常感谢~找到问题了~见笑了……

引用 3 楼 tal_he 的回复:sizeof(a)/sizeof(a[0])-1;   这个表达式的值 你自己想想等于多少 谢谢~找到问题了~  非常感谢~~自己很水~让大家见笑了~~


Question: 关于数组溢出的问题

谢谢   赵4老师

判断是否越界访问，可以在数组的最后一个元素之后对应的地址处设置数据读写断点。如果该地址对应其它变量干扰判断，可将数组多声明一个元素，并设置数据读写断点在该多出元素对应的地址上。 #include <time.h> #include <stdlib.h> #include <windows.h> int main() {     int a,b[11];//本来是b[10]，为判断哪句越界，故意声明为b[11]      srand((unsigned int)time(NULL));//按两次F11，等黄色右箭头指向本行时，调试、新建断点、新建数据断点，地址：&b[10]，字节计数：4，确定。     while (1) {//按F5，会停在下面某句，此时a的值为10，b[10]已经被修改为对应0..4之一。         b[(a=rand()%11)]=0;         Sleep(100);         b[(a=rand()%11)]=1;         Sleep(100);         b[(a=rand()%11)]=2;         Sleep(100);         b[(a=rand()%11)]=3;         Sleep(100);         b[(a=rand()%11)]=4;         Sleep(100);     }     return 0; }

完整代码四五千行吧

你能把代码写在代码框里面吗，注释太多了也不好啊

问题已解决 有两种方法 第一种方法是将face.c中原本为局部静态变量的ID改为具有内部链接的全局变量 然后再face.c中写一个自定义函数 FaceIDReset（） {         ID=0； } 然后再在Facelist.c的for循环前面调用该函数即可完成清零  方法二 在facelist.c中，声明ID为全局变量 在for循环前面加一句ID=0； 然后在face.c中使用extern声明ID变量 使得FaceNeW中的f->faceno=ID++能够进行

请贴完整代码

已经发现了数组溢出是因为ID是一个局部静态变量，第一次循环之后，ID的值任然保留，而f->faceno=ID++；所以f->faceno是从上一次的ID的值开始的，所以后面导致数组溢出。 所以我想问 有没有办法能够使得ID这样一个局部静态变量在第二次循环的时候清零， 再或者不把ID定义为局部静态变量。 for循环在facelist.c这个文件夹中，而f->faceno=ID++在face.c这样一个文件夹中 我的设想是在for循环前面对ID清零，因为ID是跨文件使用，所以他需要定义为全局变量，在两个.c文件中都能使用

那没折了，你单步吧，可以在for那写个if (faoceno == 455)，在这个if后下断点，看是怎么溢出的 可能链表没创建好

大神在哪里？

很奇怪  为什么第二次循环会在第一次循环的基础上继续 有大神知道吗？

没那么复杂   前面的可以不看 就是能不能让我第二次循环不接着第一次来 就可以了 上学期学了C语言，垃圾老师60个学时连数组都没讲完，

不明觉厉 = =

这个该怎么从0开始


Question: c语言 编写下面的方程组  如何实现呢？？

如果用fmod（）在判断语句中控制也     double gg; 	int ggg; 	gg=2*10*pi/wh; 	if(fmod(t,gg)==0) 	ggg=1; 	else 	ggg=0; 	return (ggg); 也会出现循环次数越多   输出越不精确

如果循环次数越大  强制转换后  最后在整数倍的时候输出的也是0

强制转换的话  会出现精度不够精确

这个貌似不难啊

[quote=引用 2 楼 u012412689 的回复:] #include<stdio.h> int main() { 	int g; 	float t,p,r; 	int x=t/(2*p/r)/10-(int)t/(2*p/r)/10; 	if (x=0) 		g=1; 	else g=0; 	return 0; }  楼上的方法不对，不管怎么样，因为浮点到整型的强制转换总是会丢掉小数部分。 此外计算机的浮点数无法精确表示十进制整数，所以那个除法有可能会产生0.0000....1之类的尾巴。正确的方式应该是x也用浮点类型，并且将其绝对值和一个极小数（float是1e-5，double是1e-9）进行比较。

#include<stdio.h> int main() { 	int g; 	float t,p,r; 	int x=t/(2*p/r)/10-(int)t/(2*p/r)/10; 	if (x=0) 		g=1; 	else g=0; 	return 0; }  将本来的数减去强制转换为int的数，如果为0则为整数

if else


Question: 想要一直等待输入一个值又想要同时执行其他代码怎么做？windows下的C语言编程

while(1) { if(scanf(...)!=0) f1(); f1(); } 消息循环 switch(message) { case x: do something; case y: do something; default do something }

玩得转的。自己控制消息循环就行了。  引用 1 楼 u013797412 的回复:你该去学 窗口 和 多线程了 亲 黑屏程序 已然玩不转了......

用多线程。。。

引用 1 楼 u013797412 的回复:你该去学 窗口 和 多线程了 亲 黑屏程序 已然玩不转了...... 可是老师让我们用控制台写。。。

你该去学 窗口 和 多线程了 亲 黑屏程序 已然玩不转了......


Question: 关于malloc的问题

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

引用 9 楼 zhaozhaohelu 的回复:[quote=引用 8 楼 r_Jimy 的回复:] [quote=引用 7 楼 zhaozhaohelu 的回复:] 我弱弱地问一下，int * pArr = (int *)malloc(sizeof(int) * length); 这不能写成int * pArr = (int *)malloc(sizeof(length)); 么？直观地反映你申请了多少内存。。。菜鸟回答！见谅。 不能，sizeof(length)是固定大小为4，起不到申请动态数组的作用 另外，动态申请内存要增加if (NULL == pArr)的申请失败判断[/quote]其实既然知道了长度，那么可以不写sizeof的吧。malloc的参数就添length[/quote]但在某些编译器里int所占的字节数不同

用sizeof的话，如果以后需要移植的时候，就不需要修改代码了。另外，写死的话，也应该是length*4

引用 8 楼 r_Jimy 的回复:[quote=引用 7 楼 zhaozhaohelu 的回复:] 我弱弱地问一下，int * pArr = (int *)malloc(sizeof(int) * length); 这不能写成int * pArr = (int *)malloc(sizeof(length)); 么？直观地反映你申请了多少内存。。。菜鸟回答！见谅。 不能，sizeof(length)是固定大小为4，起不到申请动态数组的作用 另外，动态申请内存要增加if (NULL == pArr)的申请失败判断[/quote]其实既然知道了长度，那么可以不写sizeof的吧。malloc的参数就添length

引用 7 楼 zhaozhaohelu 的回复:我弱弱地问一下，int * pArr = (int *)malloc(sizeof(int) * length); 这不能写成int * pArr = (int *)malloc(sizeof(length)); 么？直观地反映你申请了多少内存。。。菜鸟回答！见谅。 不能，sizeof(length)是固定大小为4，起不到申请动态数组的作用 另外，动态申请内存要增加if (NULL == pArr)的申请失败判断

我找到答案了 length那里少了个&

scanf("%d",&length);

作用域那个，的确建议你修改。之所以没问题是因为在VC 6.0的一个不标准的地方，即使即使变量声明在for语句里，其作用域却是外面一层的。

呵呵  有的时候自己怎么看自己写的代码都对， 可就是有错误还找不到，最好就是先放下，休息一会，再看，很有可能找到问题~~~而且一般是些小问题，例如：输入错误，少了符号，或者多了符号，甚至大小写错误~~~~

有两个错误 1.你的变量i的作用于只在第一个for循环中，第二个for循环中的i时没有定义的。最好把i在main里面for外面定义； 2.scanf函数里面length前面少了&。 暂时只发现这两个，应该没有其他问题了

除了以上的问题之外，好像你的i的作用域有点问题，


Question: 求大神帮忙看看哪里错了，为什么错了

沒有錯誤阿........

引用 5 楼 liu15073458538 的回复:请问这个在什么软件上编译的@r_Jimy dev c++

楼主以后注意代码缩进，以下供楼主参考：  #include<stdio.h> #include<string.h>  char str[1000];  int main() { 	int num=0; 	int i = 0;//兼容C99前的标准，不在for内定义变量  	int j = 0; 	int  index = 0;//用index代替strlen提高效率  			 	scanf("%d",&num); 	fflush(stdin); 	 	for(i=0;i<num;i++) 	{ 		char s[101]={0};//局部变量应初始化  		int  size = sizeof(s); 		         //gets(s);         if (NULL == fgets((char*)s,size,stdin))         {         	printf("can't read!\r\n");         	continue;         }                  printf("we get:%s\n",s);                  s[100]='\0';//防止溢出                   for(j=0;j<strlen(s)&&index<sizeof(str)-1;j++)//防止str溢出  		{ 			if(s[j]>='A'&&s[j]<='Z') 			{ 				s[j]+=32; 				str[index]=s[j]; 				index++; 			} 			else if(s[j]>='a'&&s[j]<='z') 			{ 				s[j]-=32; 				str[index]=s[j]; 				index++; 			} 		} 	 	str[index]='#'; 	 	index++; 	} 	 	for(i=0;i<index;i++) 	{ 		if(str[i]!='#'&&str[i]>='A'&&str[i]<='z') 		{ 			printf("%c",str[i]); 		} 		else if(str[i]=='#')         {             printf("\n");         } 	} 	 	return 0; }

楼主觉得前三楼的问题不值得回复？我也有此疑问，不知楼主回不回

prog.c:12:1: error: ‘for’ loop initial declarations are only allowed in C99 mode  for(int i=0;i<num;i++) 你是说这种错误吗，是编译器版本的问题，是不要在for()里面定义局部变量就是了

有啥错误？？

可以正常运行。问这种题最好把错误提示贴出来

你是想说什么错了？输出正常啊！大写转换小写，或者小写转换大写都OK哦。


Question: 我是第一次编程啊，求助

楼主看书了吗？ 楼主需要认真看书

对的对的'，应该将大括号放到最后啊，不把return放到最后它会一直停不下来就出错了

return应该放在main函数里面。

认真点

楼上几位正解 可以参照二楼作法

include<stdio.h> int main() { int x,y,z,result; printf("please input 3 integers: "); scanf("%d %d %d",&x,&y,&z); result=x*y*z; printf("The result is ",result); return 0; }

二楼正解。。。。

大小写敏感啊

把 return 0; 放到反大括号}里面

#include<stdio.h> int main() { int x,y,z,result; printf("please input 3 integers: ");     scanf("%d,%d,%d",&x,&y,&z);     result=x*y*z; printf("The result is %d\n",result); return 0; }

return应该放在main函数里面。return如果放在大括号外面的话，你的主函数就没有返回值了。而且还要是return 0； 或者你可以把 int  main改成void main 然后把return去掉