Question: getchar（）输入汉字

对电脑而言没有乱码，只有二进制字节；对人脑才有乱码。啊 GBK:0xB0 0xA1,Unicode-16 LE:0x4A 0x55,Unicode-16 BE:0x55 0x4A,UTF-8:0xE5 0x95 0x8A

getc, getwc, getchar, getwchar Read a character from a stream (getc, getwc), or get a character from stdin (getchar, getwchar).  int getc( FILE *stream );  wint_t getwc( FILE *stream );  int getchar( void );  wint_t getwchar( void );  Routine Required Header Compatibility  getc <stdio.h> ANSI, Win 95, Win NT  getwc <stdio.h> or <wchar.h> ANSI, Win 95, Win NT  getchar <stdio.h> ANSI, Win 95, Win NT  getwchar <stdio.h> or <wchar.h> ANSI, Win 95, Win NT    For additional compatibility information, see Compatibility in the Introduction.  Libraries  LIBC.LIB Single thread static library, retail version  LIBCMT.LIB Multithread static library, retail version  MSVCRT.LIB Import library for MSVCRT.DLL, retail version    Return Value  Each of these functions returns the character read. To indicate an read error or end-of-file condition, getc and getchar return EOF, and getwc and getwchar return WEOF. For getc and getchar, use ferror or feof to check for an error or for end of file.  Parameter  stream  Input stream  Remarks  Each of these routines reads a single character from a file at the current position and increments the associated file pointer (if defined) to point to the next character. In the case of getc and getwc, the file is associated with stream (see Choosing Between Functions and Macros). Routine-specific remarks follow.  Routine Remarks  getc Same as fgetc, but implemented as a function and as a macro.  getwc Wide-character version of getc. Reads a multibyte character or a wide character according to whether stream is opened in text mode or binary mode.   getchar Same as _fgetchar, but implemented as a function and as a macro.  getwchar Wide-character version of getchar. Reads a multibyte character or a wide character according to whether stream is opened in text mode or binary mode.    Generic-Text Routine Mappings  TCHAR.H Routine  _UNICODE & _MBCS Not Defined _MBCS Defined _UNICODE Defined  _gettc getc getc getwc  _gettchar getchar getchar getwchar    Example  /* GETC.C: This program uses getchar to read a single line  * of input from stdin, places this input in buffer, then  * terminates the string before printing it to the screen.  */  #include <stdio.h>  void main( void ) {    char buffer[81];    int i, ch;     printf( "Enter a line: " );     /* Read in single line from "stdin": */    for( i = 0; (i < 80) &&  ((ch = getchar()) != EOF)                          && (ch != '\n'); i++ )       buffer[i] = (char)ch;     /* Terminate string with null character: */    buffer[i] = '\0';    printf( "%s\n", buffer ); }   Output  Enter a line: This is a test This is a test   Stream I/O Routines  See Also   fgetc, _getch, putc, ungetc

还有汉字机内码是什么？谢谢各位

引用 2 楼 buyong 的回复:getline什么意思？

引用 1 楼 user-3 的回复: 汉字不是char吧可如果用getchar输入汉字也可以啊，占两个字节，这里怎么回事，求解答关于一些getchar输入汉字的知识

getline

汉字不是char吧


Question: 一道C语言题，复查了很长时间能通过编译，但就是不能实现想要的功能

引用 7 楼 ALNG 的回复:如果你的意思确实是连续6位但不能多于6位数字的话，我确实又想到了一个问题。你先自己想想。  如果输入的是 1234567223456abcdef789432  你期待你的程序给出什么结果？我估计是789432, 但你的程序实际会给出什么答案呢？223456  你的水平搞定这个问题绰绰有余，留给你自己吧。 感谢大家的热情回复！经历过这个小程序，越发的觉得自己的思维不够严密了。 作为一个新手，我觉得还是练习量不够，看来还得多多练习才行。 话说现在我觉得对于一个程序员来说最可怕的不是不会如何编出程序实现自己想要的功能，而是想不到会出现的所有情况。

1. p定义应该是char *类型的，int *类型的指针一般++滞后跳过四个字节，char *类型的是一个字节 2. 使用%s输出pw，pw最后最好加上\0，要不然也可能引起异常 3. 字符'0'和数字0对应的值是不一样的

参考《编译原理》中的词法分析和有限状态自动机。

神啊，还以为是6位连续的数字，还说这密码有够弱的 :)  char * get_password(char * str) {      char *p=NULL, ch;      while((ch=*str)!=0)      {          if(ch<'0' || ch>'9')          {              p=NULL;              continue;          }          if(str-p==5) //到了          {               *++str='\0'; // 加入字符串结束标志               return p;          }      }      return NULL; }    检查一下你的代码  #include <stdio.h> #define NUM 6 void main() {     int pw[NUM],str[100];     int *p;     int i,count0=0,j=0;//count0为数字计数器     scanf("%s",str);     p=str;     for(i=0;*(p+i)!='\0';i++)     {         if(count0==NUM)// 检查count0==NUM应该放在读到一个数字为并把count0计数器自加之后             if((*(p+i))>='0'&&(*(p+i)<='9'))  // 这里的意思是不是要连续6位，不能多也不能少？                 {                     count0=0;   //注意 *(p+i)等价于p[i], 后一种写法显得简洁些。                     j=0;             }//check             else                 break;         if((*(p+i)>='0')&&(*(p+i)<='9'))             {                 count0++;                 pw[j]=*(p+i);                 j++;         }         else             {                 count0=0;                 j=0;         }     }     if(count0==NUM)         printf("The password is:%s\n",pw); // 上面的提到过了，如果你准备这样操作pw串     else                                   // 有必要在其后加一个"\0"结束标志，先把         printf("ERROR!\n");                // 其定义为 char pw[NUM+1]; }   对了，楼上的mend已经给出的正确答案，问题出在str应该定义成char数组。  逻辑上还真没读出什么问题，如果你的意思确实是连续6位但不能多余6为的数字的话。  还有个你的p变量初始化后完全没有再对它赋过值，可以省略他，直接用str就行的，而且所有*(p+i)的表达都可以对应替换为str[i]，当然这些并不影响程序的行为，甚至也不影响效率。  修改后的程序  #include <stdio.h> #define NUM 6 void main() {     char pw[NUM+1],str[100];       int i,count0=0,j=0;//count0为数字计数器     scanf("%s",str);          pw[6]='\0';          for(i=0;str[i]!='\0';i++)     {         if(count0==NUM)             if((str[i])>='0'&&(str[i]<='9'))                 {                     count0=0;                     j=0;             }//check             else                 break;         if((str[i]>='0')&&(str[i]<='9'))         {                 pw[j++]=str[i];                 if(++count0==6)                 {                                      };         }         else             {                 count0=0;                 j=0;         }     }     if(count0==NUM)         printf("The password is:%s\n",pw);     else         printf("ERROR!\n"); }

逻辑有问题吧？  办法1: 记住前一个数字位的值（非数字位的话用-1), 记住当前读到的连续数字位的个数，到6就OK了。  void get_password(const char * str, char password[]) {      int count=0;      int v=-1, c;      password[0]='\0'; // 以防输入串中不存在密码      while((c=*str)!=0)      {          if(c>='0' && c<='9')          {              if(++v==c) //检查是否连续              {                   if(++count==6) //检查是否也读到了足够的连续位                   {                        // 如果是，保留并退出                        for(int i=5; i>=0; --i, --c)                          password[i]=c;                        return;                   }              }else //不连续，就从1开始              {                   v=c;                   count=1;              }          }else{              v=-1;              count=0; // 这句也可以comment掉          }      }       }   如果考虑到第一个数位不能大于'9'-5, 还可以利用这个只是进一步改进上面的程序，这是小修小补，完成功能后再锦上添花。  办法2，记住这一次连续数字开始的位置，如果输入串可以改写，这个办法会更快一些  char * get_password(char * str) {      char *p=NULL, ch;      while((ch=*str)!=0)      {          if(ch<'0' || ch>'9')          {              p=NULL;              continue;          }          if(!p || ch-*p!=str-p){ // 利用ch-*p与str-p是否相等来判断是否连续              p=str;              continue;          }          // 如果走到这里，前面是连续的，判断是否已经到了6个          if(str-p==5) //到了          {               *++str='\0'; // 加入字符串结束标志               return p;          }      }      return NULL; }

代码逻辑上过得去， 不过严格来讲， 是有不合理处的....str 数组用来保存的是 字串， 应该用 char型的； pw用于打印的话， 应该给个结束符；

#include <stdio.h> #define NUM 6 int main() {   char str[100],*p;   int i,j;//count0为数字计数器   scanf("%99s",str);   for(i = 0 ; str[i] ;i++)   {     for(p = str + i, j = 0; j < 6 &&  p[j]; ++j)         {       if(p[j] < '0' ||  p[j] >'9')       {         break;       }     }     if(j == NUM)     {       break;     }   }   if(j==NUM)     printf("The password is:%.6s\n",p);   else     printf("ERROR!\n");   return 0; }

int *p 改为 char *p


Question: HOOK WSASend

http://blog.csdn.net/rrrfff/article/details/18844699 解决方案

C:\windows_2000_source_code\win2k\private\net\sockets\winsock2\dll\winsock2\send.cpp     197: int WSAAPI     198: WSASend(     199:     SOCKET s,     200:     LPWSABUF lpBuffers,     201:     DWORD dwBufferCount,     202:     LPDWORD lpNumberOfBytesSent,     203:     DWORD dwFlags,     204:     LPWSAOVERLAPPED lpOverlapped,     205:     LPWSAOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine     206:     )     207: /*++     208: Routine Description:     209:      210:     Send data on a connected socket.     211:      212: Arguments:     213:      214:     s                   - A descriptor identifying a connected socket.     215:      216:     lpBuffers           - A  pointer  to  an  array of WSABUF structures.  Each     217:                           WSABUF  structure  contains a pointer to a buffer and     218:                           the length of the buffer.     219:      220:     dwBufferCount       - The  number  of  WSABUF  structures  in the lpBuffers     221:                           array.     222:      223:     lpNumberOfBytesSent - A pointer to the number of bytes sent by this call if     224:                           the I/O operation completes immediately.     225:      226:     dwFlags             - Specifies the way in which the call is made.     227:      228:     lpOverlapped        - A  pointer  to a WSAOVERLAPPED structure (ignored for     229:                           non-overlapped sockets).     230:      231:     lpCompletionRoutine - A  pointer  to the completion routine called when the     232:                           send   operation  has  been  completed  (ignored  for     233:                           non-overlapped sockets).     234:      235: Returns:     236:      237:     If  no  error  occurs  and  the  send  operation has completed immediately,     238:     WSASend() returns 0.  Otherwise, a value of SOCKET_ERROR is returned, and a     239:     specific  error  code  may  be retrieved by calling WSAGetLastError().  The     240:     error  code WSA_IO_PENDING indicates that the overlapped operation has been     241:     successfully  initiated  and  that  completion will be indicated at a later     242:     time.  Any other error code indicates that the overlapped operation was not     243:     successfully  initiated  and  no  completion indication will occur.  If the     244:     MSG_INTERRUPT  flag  is set, the meaning of the return value is changed.  A     245:     value  of  zero  indicates  success  and is interpreted as described above.     246:     Otherwise,  the  return  value  will directly contain the appropriate error     247:     code.  Note that this is applicable only to Win16 environments and only for     248:     protocols that have the XP1_INTERRUPT bit set in the WSAPROTOCOL_INFO     249:     struct.     250:      251: --*/     252: {     253:     PDSOCKET           Socket;     254:     INT                ErrorCode;     255:     LPWSATHREADID      ThreadId;     256:      257:     ErrorCode = TURBO_PROLOG_OVLP(&ThreadId);     258:     if (ErrorCode==ERROR_SUCCESS)     259:     {     260:         Socket = DSOCKET::GetCountedDSocketFromSocket(s);     261:         if(Socket != NULL){     262:             INT                ReturnValue;     263:             PDPROVIDER         Provider;     264:      265:             Provider = Socket->GetDProvider();     266:             ReturnValue = Provider->WSPSend(s,     267:                                             lpBuffers,     268:                                             dwBufferCount,     269:                                             lpNumberOfBytesSent,     270:                                             dwFlags,     271:                                             lpOverlapped,     272:                                             lpCompletionRoutine,     273:                                             ThreadId,     274:                                             &ErrorCode);     275:             Socket->DropDSocketReference();     276:             if (ReturnValue==ERROR_SUCCESS)     277:                 return ReturnValue;     278:             assert (ErrorCode!=NO_ERROR);     279:             if (ErrorCode==NO_ERROR)     280:                 ErrorCode = WSASYSCALLFAILURE;     281:         }     282:         else {     283:             ErrorCode = WSAENOTSOCK;     284:         }     285:     }     286:      287:     SetLastError(ErrorCode);     288:     return SOCKET_ERROR;     289: }

@VisualEleven

@斑竹 @CSDN


Question: 使用C语言计算sinx的值

楼主是问sinx的原理么? 1、在开发过程中，优先调用<math.h>中的sin函数； 2、在面试的过程中，优先考虑正弦函数的级数展开式，因为这样比较符合某些面试官的题意: sin x = x-x^3/3!+x^5/5!-...(-1)^(k-1)*x^(2k-1)/(2k-1)!+Rn(x)(-∞<x<∞) 　　Rn(x)为余项  #include<stdio.h> const int max=20; const double pi=3.14159; /**判断某一项的正负号  * */ double zhengfu(double k){ 	 	if((int)k%2==0){ 		return -1; 	}else{ 		return 1; 	} } /**计算pow(x,2k-1)  * */ double power(double x,double k){ 	double sum=1; 	double i; 	for(i=1;i<=2*k-1;i++){ 		sum*=x; 	} 	return sum; } /**计算n的阶乘  * */ double jiecheng(double n){ 	return n==0||n==1?1:n*jiecheng(n-1); } /**先把x转为弧度制，然后计算级数展开式  * */ void sin(double x){ 	x=x*pi/180; 	double sum=x, 	double one=0; 	double k=2; 	for(;k<=max;k++){ 		one=zhengfu(k)*power(x,k)/jiecheng(2*k-1); 		sum+=one; 	} 	printf("%7.3f\n",sum); } void main(){ 	double x; 	scanf("%lf",&x); 	sin(x); }

注意单位不是度而是弧度。 sin, sinh Calculate sines and hyperbolic sines.  double sin( double x );  double sinh( double x );  Routine Required Header Compatibility  sin <math.h> ANSI, Win 95, Win NT  sinh <math.h> ANSI, Win 95, Win NT    For additional compatibility information, see Compatibility in the Introduction.  Libraries  LIBC.LIB Single thread static library, retail version  LIBCMT.LIB Multithread static library, retail version  MSVCRT.LIB Import library for MSVCRT.DLL, retail version    Return Value  sin returns the sine of x. If x is greater than or equal to 263, or less than or equal to –263, a loss of significance in the result occurs, in which case the function generates a _TLOSS error and returns an indefinite (same as a quiet NaN).  sinh returns the hyperbolic sine of x. If the result is too large, sinh sets errno to ERANGE and returns ±HUGE_VAL. You can modify error handling with _matherr.  Parameter  x  Angle in radians  Example  /* SINCOS.C: This program displays the sine, hyperbolic  * sine, cosine, and hyperbolic cosine of pi / 2.  */  #include <math.h> #include <stdio.h>  void main( void ) {    double pi = 3.1415926535;    double x, y;     x = pi / 2;    y = sin( x );    printf( "sin( %f ) = %f\n", x, y );    y = sinh( x );    printf( "sinh( %f ) = %f\n",x, y );    y = cos( x );    printf( "cos( %f ) = %f\n", x, y );    y = cosh( x );    printf( "cosh( %f ) = %f\n",x, y ); }   Output  sin( 1.570796 ) = 1.000000 sinh( 1.570796 ) = 2.301299 cos( 1.570796 ) = 0.000000 cosh( 1.570796 ) = 2.509178   Floating-Point Support Routines  See Also   acos, asin, atan, cos, tan

学会使用gdb GDB常用命令 调用gdb编译需要在cc后面加 -g参数再加-o； [root@redhat home]#gdb 调试文件：启动gdb (gdb) l ：（字母l）从第一行开始列出源码 (gdb) break n :在第n行处设置断点 (gdb) break func：在函数func()的入口处设置断点 (gdb) info break： 查看断点信息 (gdb) r：运行程序 (gdb) n：单步执行 (gdb) c：继续运行 (gdb) p 变量 ：打印变量的值 (gdb) bt：查看函数堆栈 (gdb) finish：退出函数 (gdb) shell 命令行：执行shell命令行 (gdb) set args 参数:指定运行时的参数 (gdb) show args：查看设置好的参数 (gdb) show paths:查看程序运行路径；            set environment varname [=value] 设置环境变量。如：set env USER=hchen；             show environment [varname] 查看环境变量； (gdb) cd 相当于shell的cd; (gdb)pwd ：显示当前所在目录 (gdb)info program： 来查看程序的是否在运行，进程号，被暂停的原因。 (gdb)clear 行号n：清除第n行的断点 (gdb)delete 断点号n：删除第n个断点 (gdb)disable 断点号n：暂停第n个断点 (gdb)enable 断点号n：开启第n个断点 (gdb)step：单步调试如果有函数调用，则进入函数；与命令n不同，n是不进入调用的函数的 list ：简记为 l ，其作用就是列出程序的源代码，默认每次显示10行。 list 行号：将显示当前文件以“行号”为中心的前后10行代码，如：list 12 list 函数名：将显示“函数名”所在函数的源代码，如：list main list ：不带参数，将接着上一次 list 命令的，输出下边的内容。 注意 ：如果运行list 命令得到类似如下的打印，那是因为在编译程序时没有加入 -g 选项： (gdb) list 1       ../sysdeps/i386/elf/start.S: No such file or directory.         in ../sysdeps/i386/elf/start.S run：简记为 r ，其作用是运行程序，当遇到断点后，程序会在断点处停止运行，等待用户输入下一步的命令。 回车：重复上一条命令。 set args：设置运行程序时的命令行参数，如：set args 33 55 show args：显示命令行参数 continue：简讯为 c ，其作用是继续运行被断点中断的程序。 break：为程序设置断点。 break 行号：在当前文件的“行号”处设置断点，如：break  33 break 函数名：在用户定义的函数“函数名”处设置断点，如：break cb_button info breakpoints：显示当前程序的断点设置情况 disable breakpoints Num：关闭断点“Num”，使其无效，其中“Num”为 info breakpoints 中显示的对应值 enable breakpoints Num：打开断点“Num”，使其重新生效 step：简记为 s ，单步跟踪程序，当遇到函数调用时，则进入此函数体（一般只进入用户自定义函数）。 next：简记为 n，单步跟踪程序，当遇到函数调用时，也不进入此函数体；此命令同 step 的主要区别是，step 遇到用户自定义的函数，将步进到函数中去运行，而 next 则直接调用函数，不会进入到函数体内。 until：当你厌倦了在一个循环体内单步跟踪时，这个命令可以运行程序直到退出循环体。 finish： 运行程序，直到当前函数完成返回，并打印函数返回时的堆栈地址和返回值及参数值等信息。 stepi或nexti：单步跟踪一些机器指令。 print 表达式：简记为 p ，其中“表达式”可以是任何当前正在被测试程序的有效表达式，比如当前正在调试C语言的程序，那么“表达式”可以是任何C语言的有效表达式，包括数字，变量甚至是函数调用。 print a：将显示整数 a 的值 print ++a：将把 a 中的值加1,并显示出来 print name：将显示字符串 name 的值 print gdb_test(22)：将以整数22作为参数调用 gdb_test() 函数 print gdb_test(a)：将以变量 a 作为参数调用 gdb_test() 函数 bt：显示当前程序的函数调用堆栈。 display 表达式：在单步运行时将非常有用，使用display命令设置一个表达式后，它将在每次单步进行指令后，紧接着输出被设置的表达式及值。如： display a watch 表达式：设置一个监视点，一旦被监视的“表达式”的值改变，gdb将强行终止正在被调试的程序。如： watch a kill：将强行终止当前正在调试的程序 help 命令：help 命令将显示“命令”的常用帮助信息 call 函数(参数)：调用“函数”，并传递“参数”，如：call  gdb_test(55) layout：用于分割窗口，可以一边查看代码，一边测试： layout src：显示源代码窗口 layout asm：显示反汇编窗口 layout regs：显示源代码/反汇编和CPU寄存器窗口 layout split：显示源代码和反汇编窗口 Ctrl + L：刷新窗口 quit：简记为 q ，退出gdb 当然，gdb的功能远不止这些，包括多进程/多线程/信号/远程调试等功能在这里均没有提及，有需要的读者可以参考其它信息 本文来自CSDN博客，转载请标明出处：http://blog.csdn.net/pizi0475/archive/2011/03/08/6232749.aspx

这是我写的代码#include "stdio.h" float abc(float a,int b) {int i;   float c;   c=1.0;   for(i=1;i<=b;i++)     c=c*a;   return c; }   main() {   float sinx,x;   int n;   sinx=0;   printf("please input the number x:");   scanf("%f",&x);   for(n=1;n<=9;n++)     {  if(n%2!=0)       sinx=sinx+abc(x,(2*n-1))/(2*n-1);  else    sinx=sinx-abc(x,(2*n-1))/(2*n-1); } printf("sinx=%f\n",sinx); }  特别说明：在linux下用gcc编译后运行，发现出错了。

c标准库里面就有，一般都已经够用了。

#include <math.h>后可以使用sin库函数


Question: shell sed 参数问题

试试循环调用此脚本时让row从大到小变化。

bash下是没有问题的 sed -i -e "$row"H  -e "$row"G dialogue.smail sed -i -e "${row}"H  -e "${row}"G dialogue.smail 都OK  可能是你的shell支持有差异。

$row ?


Question: 循环分支问题？

p_arr1<=arr1+2是一个逻辑表达式，其值为1或者0（真或者假），然后再取反（！），作为if分支的条件，如果p_arr1确实小于等于arr1+2，则不会执行打印语句，反之则会打印

看到下划线的code我就感觉头晕。。。

if(!(p_arr1<=arr1+2)) 指针对比，先看内部括号，表示p_arr1指向的位置不超过arr1指向的位置2步(含2步)，再加个非，那就是p_arr1超过arr12步之外的位置了

p_arr1<=arr1+2 表示前面的循环arr1[]没有遍历完就找到了不一样的字符 !(p_arr1 <= arr1 + 2) 就是反过来， 说明arr1[]完整的匹配了

如果 p_arr1<=arr1+2, 那么三个元素都是匹配的。


Question: 请问判超时是原因

^_^，还真是我看错了。那这题也太弱了。连累我把用非波拿起方式产生的串的第n位（n<10^9)问题解决了，那可不是一个数量级的问题 :(

引用 6 楼 ALNG 的回复:上面说重复循环是误解，不存在这样的规律，原题这个地方应该存在录入错误。  我大体搞定了。楼主低估了斐波那契数列的增长速度，它是指数增长的，需要大整数计算。好在因为增长快，10^9蹦蹦跳跳很快就到了。我的程序，在我的机上求一个10^9方位左右的n要5秒左右。花点内存存些中间结果，1000ms应该不难做到。 认真看题目，"如果把数列的前两项写在一行，后面每个数字都是前两个数字的和..",5,8,13在莱不是21，而是1+3=4，不是标准斐波那契...

题目描述斐波那契数列，又称黄金分割数列，指的是这样一个数列：0、1、1、2、3、5、8、13、21、…… 在数学上，斐波纳契数列以如下被以递归的方法定义：F0=0，F1=1，Fn=F(n-1)+F(n-2)（n>=2，n∈N*）。鹏鹏最近重新温习了一下斐波那契数列，然后他想到了一个问题，如果把数列的前两项写在一行，后面每个数字都是前两个数字的和，那么数列的第n个数字是几呢？例如，当前两项为0和1的时候，数列可以写成下面形式： 011235813471123581347112358…… 最后那串数列里的1123581347是重复循环的，那么不管多大的项次都能简单快速算出，所以重点不是暴力求解，而是找出循环规律...

判超时就是因为超时了呗。  0<=a,b<10,0<n<10^9,  n最多可达999999999, 不找数论上的特别规律，n=999999999时1秒钟之内一题都未必做得出来，更不用说还有多组测试。  这是一道数学题，不太算编程题，设计到的编程或者算法上的技巧少之又少，大头在数学上。  如果能快速的判定对给定的a,b,第n位是该斐波那契数列的第i项的第j个数位，再根据通项公式求出这个第i项，找出它的第j位，这题就搞定了。

B无用啊，这个程序结果是超时，，，，2楼的是一般的斐波那契这个上10位后就要分成两个、   链接http://acm.sdut.edu.cn/sdutoj/problem.php?action=showproblem&problemid=2764

你也不看看b有多大，就直接这么干……这题算法显然不是这样的

#include<stdio.h>   int fib(int n) {   int f[n+1];   int i;     f[0] = 0;   f[1] = 1;     for (i = 2; i <= n; i++)   {       f[i] = f[i-1] + f[i-2];   }     return f[n]; }


Question: 函数返回值问题。

不客气，刚才又想了一下，我的第一个回答有些问题。 两个问题都是由于第2种解释引起的。

引用 10 楼 mmns 的回复:另外，如果你的源文件是.c而不是.cpp,那么编译器也不会没有返回值而报错，而是扔出一个warning.因为标准的C语言编器可以容忍这个错误，而标准c++编译器不能。真是太感谢你了。我建立源文件的时候，在文件名上加上了.c

你的某个编译选项容忍了这种错误，具体哪个选项我记不清了，好久没用vc6了。不要深究这个了。 不过你的问题非常好，真是个美妙的巧合。

引用 7 楼 mmns 的回复:[quote=引用 6 楼 zhudou_love 的回复:] [quote=引用 4 楼 mmns 的回复:] 问题出在这一句：printf("%d\n",max_zhu(a,b));  这行代码在调用printf之前，先调用了max_zhu(a,b)，max_zhu()会在栈中为z分配空间，然后那个地址会保存a和b中的最大值。 max_zhu(a,b)执行完以后，堆栈指针会移回原处，然后调用printf。 很凑巧，printf("%d\r\n", x);这个x在堆栈中的地址和max_zhu(a,b)函数中的变量z在堆栈中的位置正好重合。所以就把刚才max_zhu(a,b)执行过程中z的值输出来了。我把printf("%d\n",max_zhu(a,b));这句话改成 c = max_zhu(a,b); printf("%d\n",c); 为什么仍然能通过编译以及输出最大值呢？[/quote] 你用的应该是个特殊的编译器，一般的c编译器编译这段代码不能通过，对于某些特殊的编译器是可以的。 好吧，这个问题我就多说两句，对于以下的函数：  int max_zhu(int x , int y)  {    int z;    z = x>y?x:y;     return z;       /////注意这里，有返回值  } 一般编译器会把retuan z;这一句编译成 两句汇编 MOV EAX, z;  ///注意这是伪代码，就是说把栈中的内容移到寄存器EAX中。 RET          ///函数返回  而对于以下语句c = max_zhu(a, b); 编译器会处理为: CALL  max_zhu; ///伪代码，调用函数 MOV   c, eax;  ///伪代码，c指的是栈中的某个地址，实际的目标码应该适用堆栈指针寻址到c的地址  虽然你的函数没有返回值，即没把z的内容移到EAX中，但这里出现一个绝妙的巧合，很多编译器会用EAX来保留中间计算结果，你 max_zhu函数中的z = x>y?x:y; 恰好也适用eax保存x>y?x:y这个表达式计算的中间结果。 ok!你应该明白了，虽然你的max_zhu函数没有通过return z;的方式把返回值保存在eax中，但巧中之巧eax寄存器中放的正好是计算结果。 所以：在执行完 CALL  max_zhu; MOV   c, eax; 后，变量c中存的就是最大值了。 [/quote]你好，我还有个问题，我用的是VC++ 6.0编译器，群里有其他朋友用别机器上的VC6测试的时候为什么不能通过编译呢？

引用 6 楼 zhudou_love 的回复:[quote=引用 4 楼 mmns 的回复:] 问题出在这一句：printf("%d\n",max_zhu(a,b));  这行代码在调用printf之前，先调用了max_zhu(a,b)，max_zhu()会在栈中为z分配空间，然后那个地址会保存a和b中的最大值。 max_zhu(a,b)执行完以后，堆栈指针会移回原处，然后调用printf。 很凑巧，printf("%d\r\n", x);这个x在堆栈中的地址和max_zhu(a,b)函数中的变量z在堆栈中的位置正好重合。所以就把刚才max_zhu(a,b)执行过程中z的值输出来了。我把printf("%d\n",max_zhu(a,b));这句话改成 c = max_zhu(a,b); printf("%d\n",c); 为什么仍然能通过编译以及输出最大值呢？[/quote] 你用的应该是个特殊的编译器，一般的c编译器编译这段代码不能通过，对于某些特殊的编译器是可以的。 好吧，这个问题我就多说两句，对于以下的函数：  int max_zhu(int x , int y)  {    int z;    z = x>y?x:y;     return z;       /////注意这里，有返回值  } 一般编译器会把retuan z;这一句编译成 两句汇编 MOV EAX, z;  ///注意这是伪代码，就是说把栈中的内容移到寄存器EAX中。 RET          ///函数返回  而对于以下语句c = max_zhu(a, b); 编译器会处理为: CALL  max_zhu; ///伪代码，调用函数 MOV   c, eax;  ///伪代码，c指的是栈中的某个地址，实际的目标码应该适用堆栈指针寻址到c的地址  虽然你的函数没有返回值，即没把z的内容移到EAX中，但这里出现一个绝妙的巧合，很多编译器会用EAX来保留中间计算结果，你 max_zhu函数中的z = x>y?x:y; 恰好也适用eax保存x>y?x:y这个表达式计算的中间结果。 ok!你应该明白了，虽然你的max_zhu函数没有通过return z;的方式把返回值保存在eax中，但巧中之巧eax寄存器中放的正好是计算结果。 所以：在执行完 CALL  max_zhu; MOV   c, eax; 后，变量c中存的就是最大值了。

引用 4 楼 mmns 的回复:问题出在这一句：printf("%d\n",max_zhu(a,b));  这行代码在调用printf之前，先调用了max_zhu(a,b)，max_zhu()会在栈中为z分配空间，然后那个地址会保存a和b中的最大值。 max_zhu(a,b)执行完以后，堆栈指针会移回原处，然后调用printf。 很凑巧，printf("%d\r\n", x);这个x在堆栈中的地址和max_zhu(a,b)函数中的变量z在堆栈中的位置正好重合。所以就把刚才max_zhu(a,b)执行过程中z的值输出来了。我把printf("%d\n",max_zhu(a,b));这句话改成 c = max_zhu(a,b); printf("%d\n",c); 为什么仍然能通过编译以及输出最大值呢？

这都能编译过，main不return个int就要出错，调用的居然还能不return

引用 2 楼 missheaven2011 的回复:属于不安全操作吧怎么个意思？

属于不安全操作吧

这相当的不科学


Question: 如何 判断一个字符串指针的前二个字符是"f:"

#include <string.h>  int main() {       char *p="ffjjj";       if(!strncmp(p,"ff",2))                   printf("true");        else                    printf("false");       return 0; }

楼主要的应该是这样,经测试成功 int main() { int i=0,flag1=0,flag2=0; char arr[]="abffcdef:"; char *p=arr; for(i=0;i<9;i++) {  if(*(p+i)=='f') {   flag1=1; }  if(*(p+i)==':') {   flag2=1; } } if(flag1+flag2==2) {  printf("该字符串存在f:\n"); } else {  printf("没有\n"); } return 0; }

//判断一个字符串指针的前二个字符是否是"f:" if (0==strncmp(p,"f:",2)) //判断一个字符串指针所指向的字符中存在"f:"? (不一定是前二位) if (strstr(p,"f:"))  String Manipulation These routines operate on null-terminated single-byte character, wide-character, and multibyte-character strings. Use the buffer-manipulation routines, described in Buffer Manipulation, to work with character arrays that do not end with a null character.  String-Manipulation Routines  Routine Use  _mbscoll, _mbsicoll, _mbsncoll, _mbsnicoll Compare two multibyte-character strings using multibyte code page information (_mbsicoll and _mbsnicoll are case-insensitive)  _mbsdec, _strdec, _wcsdec Move string pointer back one character  _mbsinc, _strinc, _wcsinc Advance string pointer by one character  _mbslen Get number of multibyte characters in multibyte-character string; dependent upon OEM code page  _mbsnbcat Append, at most, first n bytes of one multibyte-character string to another  _mbsnbcmp Compare first n bytes of two multibyte-character strings  _mbsnbcnt Return number of multibyte-character bytes within supplied character count  _mbsnbcpy Copy n bytes of string  _mbsnbicmp Compare n bytes of two multibyte-character strings, ignoring case  _mbsnbset Set first n bytes of multibyte-character string to specified character  _mbsnccnt Return number of multibyte characters within supplied byte count  _mbsnextc, _strnextc, _wcsnextc Find next character in string  _mbsninc. _strninc, _wcsninc  Advance string pointer by n characters  _mbsspnp, _strspnp, _wcsspnp Return pointer to first character in given string that is not in another given string  _mbstrlen Get number of multibyte characters in multibyte-character string; locale-dependent  sprintf, _stprintf Write formatted data to a string  strcat, wcscat, _mbscat Append one string to another  strchr, wcschr, _mbschr Find first occurrence of specified character in string  strcmp, wcscmp, _mbscmp Compare two strings  strcoll, wcscoll, _stricoll, _wcsicoll, _strncoll, _wcsncoll, _strnicoll, _wcsnicoll Compare two strings using current locale code page information (_stricoll, _wcsicoll, _strnicoll, and _wcsnicoll are case-insensitive)  strcpy, wcscpy, _mbscpy Copy one string to another  strcspn, wcscspn, _mbscspn,  Find first occurrence of character from specified character set in string  _strdup, _wcsdup, _mbsdup Duplicate string  strerror Map error number to message string  _strerror Map user-defined error message to string  strftime, wcsftime Format date-and-time string  _stricmp, _wcsicmp, _mbsicmp Compare two strings without regard to case  strlen, wcslen, _mbslen, _mbstrlen Find length of string  _strlwr, _wcslwr, _mbslwr Convert string to lowercase  strncat, wcsncat, _mbsncat Append characters of string  strncmp, wcsncmp, _mbsncmp Compare characters of two strings  strncpy, wcsncpy, _mbsncpy Copy characters of one string to another  _strnicmp, _wcsnicmp, _mbsnicmp Compare characters of two strings without regard to case  _strnset, _wcsnset, _mbsnset Set first n characters of string to specified character  strpbrk, wcspbrk, _mbspbrk Find first occurrence of character from one string in another string  strrchr, wcsrchr,_mbsrchr Find last occurrence of given character in string  _strrev, _wcsrev,_mbsrev Reverse string  _strset, _wcsset, _mbsset Set all characters of string to specified character  strspn, wcsspn, _mbsspn Find first substring from one string in another string  strstr, wcsstr, _mbsstr Find first occurrence of specified string in another string  strtok, wcstok, _mbstok Find next token in string  _strupr, _wcsupr, _mbsupr Convert string to uppercase  strxfrm, wcsxfrm Transform string into collated form based on locale-specific information  vsprintf, _vstprint Write formatted output using a pointer to a list of arguments

if (p[0]=='f' && p[1]==':') {  }

if(14590==*(short*)p) 是 else 不是

引用 4 楼 huabinsir 的回复:如何 判断一个字符串指针所指向的字符中存在"f:"? (不一定是前二位)  strchr函数和strrchr函数！

p[0] == 'f' && p[1] == ':';

http://man.chinaunix.net/develop/c&c++/linux_c/default.htm 常用的一些Linux C函数

引用 5 楼 fjhyy 的回复:用linux C提供的函数即可：  strchr（查找字符串中第一个出现的指定字符） 相关函数 index，memchr，rinex，strbrk，strsep，strspn，strstr，strtok 表头文件 #include<string.h> 定义函数 char * strchr (const char *s,int c); 函数说明 strchr()用来找出参数s字符串中第一个出现的参数c地址，然后将该字符出现的地址返回。 返回值 如果找到指定的字符则返回该字符所在地址，否则返回0。 范例 #include<string.h> main() { char *s=0123456789012345678901234567890”; char *p; p=strchr(s,'5'); printf("%s\n",p); }  上面错了，是这个。。。  strstr（在一字符串中查找指定的字符串） 相关函数 index，memchr，rindex，strchr，strpbrk，strsep，strspn，strtok 表头文件 #include<string.h> 定义函数 char *strstr(const char *haystack,const char *needle); 函数说明 strstr()会从字符串haystack 中搜寻字符串needle，并将第一次出现的地址返回。 返回值 返回指定字符串第一次出现的地址，否则返回0。

如何 判断一个字符串指针所指向的字符中存在"f:"? (不一定是前二位)

先判断'f' 在判断 ':'

楼主要求的应该是指针所指的内存空间的前两个字节是"f:"，而不是要求指针本身吧？ 比如： char * p; // 要保证p已经指向了可用的内存空间，这里略去 if((*p == 'f') && (*(p + 1) == ':')) {     // 字符指针所指内存前两字节是f: }

char * a; ... if (0 == memcmp(a,"f:",2)) { //oh yeah }


Question: [求助贴] Main函数的疑问

一个是控制台 一个是GUI应用

引用 3 楼 buyong 的回复:[quote=引用 2 楼 zbplusplus 的回复:] WinMain是VC自定义的，标准的main被隐藏了 main本身只是编译器的规定，应用程序格式则是操作系统规定的。 应用程序总是包含一个入口点和相关的参数，以及环境变量。入口点仅仅表示程序代码总是从这个地址开始执行。 不同语言、编译器生成的可执行程序都遵循相同格式，但是有不同的表现形式。 只有main是最接近原始的（虽然如此也不是真正的最初的应用程序入口）。  误人子弟[/quote] Winmain绝对不是 VC定义的 =_=|| winmain是windows app的入点， main是win console. 两个木有包含关系

引用 2 楼 zbplusplus 的回复:WinMain是VC自定义的，标准的main被隐藏了 main本身只是编译器的规定，应用程序格式则是操作系统规定的。 应用程序总是包含一个入口点和相关的参数，以及环境变量。入口点仅仅表示程序代码总是从这个地址开始执行。 不同语言、编译器生成的可执行程序都遵循相同格式，但是有不同的表现形式。 只有main是最接近原始的（虽然如此也不是真正的最初的应用程序入口）。  误人子弟

1)Win32 Console Application —— main；Win32 Application —— WinMain 2)VS IDE中，在不明白的符号RunUserInterface上点鼠标右键，选转到定义。


Question: flex和bison想实现一个一元二次方程求根，语法分析报错求解

语法不能把次序和次数都限死了。  equation: expression '=' '0'  expression: term | term '+' expression | term '-' expression // 好久不用bison了，不知道语法是写成左递归还是右递归好，也可能要这样 // expression : expression '+' term | expression '-' term  term : INTEGER |        INTEGER EKS |        INTEGER EKSSQR

LZ计科的啊。


Question: 打印数组碰到一个问题

引用 3 楼 sinnay523 的回复:[quote=引用 1 楼 user-1 的回复:] 因为'\0'就是0   想明白了 脑子秀逗了[/quote]

引用 1 楼 user-1 的回复:因为'\0'就是0   想明白了 脑子秀逗了

引用 1 楼 user-1 的回复:因为'\0'就是0   那不是结束符的意思吗？ '\0' 和 0 的acsii码不一样呀


Question: 请大家看看我这几个函数中存在内存溢出、数组越界的情况吗

数组越界，野指针用gflags测测看。

引用 12 楼 ALNG 的回复:”而且你的插入步骤我觉得还要加一个prev->pnext = q;该函数最后一句*p=q是为什么，为什么要修改它呢？我觉得如果是插入第0个节点改变还行，那插入中间节点为什么也要，这句不懂 ===========================================  prev只是来记录指针值的，prev可能是NULL, 所以没有用prev->pnext=q. 真正完成prev->pnext=q这个逻辑的正是*p=q. 如果*p这个指针或者是head，或者是要插在其后的节点的pnext指针。功能上肯定没有问题的，测试过了，不会是碰巧。你的代码能通过测试，相信也没有问题，问题出在别处。但你的插入的实现真心效率稍差，你的插入可能遍历链表两遍，有些代价是不必要的。  其实我上面也有点玩花，没必要的让程序难解。后来想了以下，其实只要区分两种情况，一种是插在最前面，另外一种是插入现有的某个节点的后面，如果按这种思路来写插入操作就容易写也容易懂了。下面的随手敲的，主要是意思   void insert_node(node **list, int i, int value) {     node * a; // 要插在其后的节点的指针     node * n; // 新节点指针     if(i==0) // 插在最前面     {          n=(node*)malloc(sizeof(node));          n->data=value;          n->plast=NULL;  // 设置新插节点的前后节点指针值          n->pnext=list;          if(*list) // 设置其后续节点的plast             (*list)->plast=n;          *list=n;     }     a=*list;     while(--i>0 && a!=NULL)        a=a->next;     if(i!=0 || a==NULL) //越界        exit(1);     n=(node*)malloc(sizeof(node));     n->data=value;     n->plast=a;  // 设置新插节点的前后节点指针值     n->pnext=a->pnext;     if(a->pnext)       a->pnext->plast=n;     a->pnext=n;  //一共改四个指针(或三个，如果a是原链表的最后一节)      }   从这个naive实现的基础上，设法合并让malloc, 和设置指针们的操作只进行一次。  void insert_node(node **list, int i, int value) {     // 重复利用list为要修改的指向新节点的指针的指针      // 这行没必要了，用上面的list来完成  //node * a; // 要插在其后的节点的指针     node * n; // 新节点指针     node * plast; // 新节点的前驱结点指针应赋的值     if(i==0) // 插在最前面     {            // list的值已经是对的了，不需调整                   //n=(node*)malloc(sizeof(node));          //n->data=value;          plast=NULL;  // 设置新插节点的前后节点指针值          n->pnext=list;          // 下面三行合并到后面，不需要修改          //if(*list) // 设置其后续节点的plast           //   (*list)->plast=n;          //*list=n;     }else{         a=*list;         while(--i>0 && a!=NULL)            a=a->next;         if(i!=0 || a==NULL) //越界            exit(1);          要修改a->pnext, 所以让list为a->pnext的地址          list=&a->pnext;          plast=a;     }      // 好了，两种情况下的插入都可以共用下面的代码了     n=(node*)malloc(sizeof(node));     n->data=value;     n->plast=plast;  // 设置新插节点的前后节点指针值     n->pnext=plast?plast->next:NULL;     if(plast && plast->pnext)        plast->pnext->plast=n;     *list=n;  //一共改四个指针(或三个，如果a是原链表的最后一节) }   上面的    if(plast && plast->pnext)        plast->pnext->plast=n; 还显得有点笨拙，如果用个变量记住后续节点，就基本上是我原来的版本了。看别人完成的代码往往比较痛苦。 思路很新颖，很有想法。 这几天我也对比了几处代码，我的错误可能是我理解题有偏差，插入函数

引用 8 楼 ALNG 的回复:我上面在printnode里面有检测代码的，每次插入、删除后看看链表是否合法。  你可以把这个函数放到你的代码里面，然后    int main() {      struct strlnode* num;       insertnode(&num 0, 5);// 头部插入      printnode(num);      insertnode(&num 0, 6);//头部插入第二次      printnode(num);      insertnode(&num 2, 6); //尾部插入      printnode(num);      insertnode(&num 3, 8); //尾部插入第二次      printnode(num);      insertnode(&num 2, 0); //中间插入      printnode(num);                }   运行看看是什么环节出了问题。也用这个测试我的代码，插入和删除节点都试试，看看错的错在哪里，对的对在哪里，比较一下找出原因，就达到学习效果了。 你这个我试过，你的测试代码直接插入，并没有用create函数创建双链表，直接用此段代码会出错，因为num声明没有初始化为null，故检查不出空，报错了；后来我初始化为空后可以，在链表首尾中间查也没问题，大整数相加也没问题的

那就不是你的插入，删除，相加环节的错误。每次使用后有否释放动态分配的内存，有没有可能内存溢出？  网址给出来。

写代码一定要学会设计测试。需要点时间，慢慢的你就都会了。

引用 4 楼 zhao4zhong1 的回复:试试0+0=? 还真没试过这个，试试看

引用 2 楼 ALNG 的回复:吐血。以下代码仅供学习链表的插入删除。大整数的计算不带这么玩的，太低效了。你根本没有在任意位置插入一个数位的要求，为什么不用一个哪怕字符数组呢。这是另一个题目了，anyway:   #include <stdio.h> #include <stdlib.h>  struct strlnode {     int data;     struct strlnode *plast;     struct strlnode *pnext; };  // 不如传入strlnode* // int getnodenum(struct strlnode *p)  /*获取链表中节点个数*/ {     int nodenum = 0;     while(p != NULL)     {         nodenum++;         p = p->pnext;     }     return nodenum; }  void printnode(struct strlnode*p) { #ifdef _DEBUG 	if(p && p->plast!=NULL) 		printf("head node's plast not set to NULL\n"); #endif	 	while(p) 	{ 		printf("%d ", p->data); #ifdef _DEBUG 		if(p->pnext && p->pnext->plast!=p) 			printf("\nNode(data %d)'s next node's previous node not correctly set\n", p->data); #endif 		p=p->pnext; 	} 	putchar('\n'); }  /* 传入strlnode**的原因就是为了修改它，如果没有修改，结果必然是错的  */ void insertnode(struct strlnode **p, int i, int x) /* 在链表第i个位置插入数据等于x的节点 */ { 	struct strlnode *q, *prev=NULL;     if(i < 0)         exit(1);     while(i!=0)     {         --i;         if(*p==NULL)//越界             exit(-1);         prev=*p;         p=&(*p)->pnext;     }     q=(struct strlnode*)malloc(sizeof(*q));         q->data=x;     q->pnext=*p;     q->plast=prev;     if(*p)         (*p)->plast=q;     *p=q; }  void deletenode(struct strlnode **p, int i) /* 删除链表中第i个节点 */ { 	/* locate the node to delete. we can safely assume p is not NULL because of the way we use it */ 	struct strlnode* prev=NULL, *q; 	while(i!=0) 	{ 		--i; 		if(*p==NULL) 			exit(-1); // out of bound 		prev=*p; 		p=&(*p)->pnext; 	} 	if(*p==NULL) 		exit(-1); // out of bound 	q=*p; 	*p=q->pnext; 	if(q->pnext) 		q->pnext->plast=prev; 	free(q); }  void bignumberplus(struct strlnode **plus, struct strlnode **p, struct strlnode **q) /* 使用链表实现大整数相加 */ {      struct strlnode *p0,*q0,*plus0;      unsigned int add,flag=0;      p0 = *p;      q0 = *q;            while(p0->pnext != NULL)          p0 = p0->pnext;      while(q0->pnext != NULL)          q0 = q0->pnext;            while(q0 != NULL || p0 != NULL)      {          add=flag;          if(q0!=NULL)          {              add+=q0->data;          	 q0=q0->plast;          }          if(p0!=NULL)          {              add+=p0->data;              p0=p0->plast;          }         flag=0;         if(add>=10)         {             ++flag;             add-=10;         }         insertnode(plus,0,add);      }      if(flag)          insertnode(plus,0,1);  }   int main() { 	struct strlnode * head=NULL; 	struct strlnode * num2=NULL, *sum=NULL;  	insertnode(&head, 0, 3); 	insertnode(&head, 0, 4); 	insertnode(&head, 0, 5); 	insertnode(&head, 0, 7); 	insertnode(&head, 0, 8); 	insertnode(&head, 0, 1); 	printnode(head);  	insertnode(&num2, 0,1); 	insertnode(&num2, 0, 5); 	insertnode(&num2, 0, 2); 	insertnode(&num2, 0, 8); 	insertnode(&num2, 0, 7); 	insertnode(&num2, 0, 3); 	printnode(num2); 	 	bignumberplus(&sum, &head, &num2); 	printnode(sum); }  我这只是做题的，实际用这确实是有点浪费~~~ 链表插入函数，i你没有判断大于链表节点个数是因为你在while循环里面加了为空节点的判断的，但是我把链表节点数判断加进去了，在while里面循环液不可能溢出啊，因为我的i肯定取值范围是“0=<i<=链表节点数-1”而且你的插入步骤我觉得还要加一个prev->pnext = q;该函数最后一句*p=q是为什么，为什么要修改它呢？我觉得如果是插入第0个节点改变还行，那插入中间节点为什么也要，这句不懂 删除节点函数：我觉得也是把i的取值范围判断在我的节点范围内就行了，所以就不会有空或者内存溢出的情况，那我的难道也不行吗？ 赞一个你最后的一个大整数相加写得真好，代码函数变小了好多！！！ 对于我上面的问题，还希望你耐心解答，谢谢！

引用 3 楼 truelance 的回复:"VC能通过" 你只测了一两个用例吧 要学会写测试用例, 你这么多代码, 要做单元测试的话, 至少应该有30个用例. 测试用例？这个怎么弄?能否介绍下，我觉得这是个突破口

// 传入strlnode**, 就需要检查p为NULL指针的情形, 不如传入strlnode* // int getnodenum(struct strlnode *p)  /*获取链表中节点个数*/ {     int nodenum = 0; //    struct strlnode *q; //    if( p ) //    { //        q=*p 	    while(p != null) 	    { 	        nodenum++; 	        p = p->pnext; 	    } //    }     return nodenum; }  // 同样要检查p为NULL指针的情形， void insertnode(struct strlnode **p, int i, int x) /* 在链表第i个位置插入数据等于x的节点 */ {     struct strlnode *q=null,*q0=null;     q = *p;     if(i < 0 || i > (getnodenum(p) - 1))         exit(1);     else     {         q0 = (struct strlnode *)malloc(sizeof(struct strlnode));         q0->data = x;         if(0 == i)         {             q0->pnext = q;             q->plast = q0;             q0->plast = null;             *p = q0;         }else         {             while(i > 0)             {                 i--;                 q = q->pnext;             }             q->plast->pnext = q0;             q0->plast = q->plast;             q0->pnext = q;             q->plast = q0;         }     }     }  // 同样要检查 void deletenode(struct strlnode **p, int i) /* 删除链表中第i个节点 */ {     struct strlnode *q = *p;     if(i < 0 || i > getnodenum(p) - 1)         exit(1);     else     {                 while(i > 0)                 {             i--;             q = q ->pnext;         }         if(q->plast == null)        //del first         {             *p = q ->pnext;             free(q);             q = *p;             q ->plast = null;         }else if(q->pnext == null)        //del last         {                       q->plast->pnext = null;             free(q);         }else         {             q->plast->pnext = q->pnext;             q->pnext->plast = q->plast;             free(q);         }     } } void bignumberplus(struct strlnode **plus, struct strlnode **p, struct strlnode **q) /* 使用链表实现大整数相加 */ {      struct strlnode *p0,*q0,*plus0;      unsigned int add,flag=0;      p0 = *p;      q0 = *q;            while(p0->pnext != null)          p0 = p0->pnext;      while(q0->pnext != null)          q0 = q0->pnext;            while(q0 != null && p0 != null)      {         add = p0->data + q0->data + flag;         if(add >= 10)         {             flag = 1;             insertnode(plus,0,add%10);         }else         {             flag = 0;             insertnode(plus,0,add);         }         p0 = p0->plast;         q0 = q0->plast;      }      if(p0 != null || q0 != null)      {         if(p0 == null)             plus0 = q0;         else             plus0 = p0;         while(plus0 != null)         {             add = plus0->data + flag;             if(add >= 10)             {                 flag = 1;                 insertnode(plus,0,add%10);             }else             {                 flag = 0;                 insertnode(plus,0,add);             }             plus0 = plus0->plast;         }      }      if(flag == 1)         insertnode(plus,0,1);      add = getnodenum(plus);      deletenode(plus,add-1); }   如果作为练习链表的训练，这样做可以理解，否则这些操作都太昂贵，这样的大数是不能拿来用的。  哦，你真是拿这个去做题了，那肯定不行的


Question: 单向链表创建

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

head = head->next; return head; 直接舍弃了头结点head。 应该严谨一点， p=head; free(p);  p = NULL;

s只是一个指针，在head=s前，他是指向最后一个节点的，但是head=s后，它就不是了，这个时候free不会影响最后一个节点；你的理解没错，你说的node* p2=head->next;和return p2也可以的，目的只是把链表头的指针返回。 引用 7 楼 ysmz4 的回复:[quote=引用 6 楼 KenZhang1031 的回复:] 我只是解释了head=head->next在这里的意图，你说的没错，原来的head没用了的话就该释放掉，后面几行可以这样： s = head; head=head->next; free(s); return head; s是已经分配过空间的，free(s)会造成最后一个s节点被释放掉吧。  你的意思是不是拿一个没malloc的指针来指向head，然后删除？ 比如我创建个node* p2=head->next;             free(head);             //p2变成头结点             node* head=p2;//head又变回头节点了，不过我觉得返回p2就可以了，没人用head当全局变量吧 原来那个内存泄露的代码是程序员面试宝典上的哟~~

我只是解释了head=head->next在这里的意图，你说的没错，原来的head没用了的话就该释放掉，后面几行可以这样： s = head; head=head->next; free(s); return head; 引用 4 楼 lovehuan54 的回复:引用 2 楼 KenZhang1031 的回复:在这个程序中，head=head->next;表示通过scanf_s输入的第一个节点作为链表的head，因为head->next就指向scanf_s输入的第一个节点，这个节点作为head。但是第一个malloc的内存没人free啊。

node * creat(){     //创建链表     node *head= (node *)malloc(sizeof(node));  //创建了一个肯定存在的链表的头结点     node *p,*s;  //两个链表结点的临时指针     p=head;     //p指向链表头，结合下面代表可知p指向了链表的最后一个结点     int x,cycle=1;  //x用来取得录入的非零数值；cycle用来表示是否继续循环，据下面代码可知输入0时结束创建链表     while(cycle){  //cycle值非零时循环         printf("\ninput the data:");         scanf_s("%d",&x);  //用x取得输入值         if(0==x)             cycle=0; //x为0时退出循环         else{             s = (node *)malloc(sizeof(node)); //创建链表的一个新结点             s->data=x;  //给新结点赋值             p->next=s;  //将新结点放置在链表的末尾             p=p->next;  //p指向p的下一个结点，也即s，或者说链表的末尾         }     }     p->next=NULL;   //因为链表尾部结点之后没有下一个结点，显性赋值NULL，避免出现错误。     head=head->next;  //抛弃原有的头结点，显然没有释放（free）那个结点的内存！     return head; }

是啊，为什么把head指向下一个？ 会有内存泄露的。

好像是  最好free掉


Question: raw socket errno = 13

socket(PF_PACKET, SOCK_RAW, htons(ETH_P_IP))

引用 1 楼 user-2 的回复:root用户执行程序的？ su root之后也不行，发送不出去，刚才的无权限问题已经解决了是自己的IP越界了，但是IP写正确之后，程序显示发送成功，接收不到，wireshark抓包也没有，不知道为什么 if(setsockopt(g_sctpRawSock, IPPROTO_IP, IP_HDRINCL, (char*)&flag, sizeof(flag)) == ETERROR)//设置socket属性，使得ip头可以自己封装    {          return ETERROR;    } 测试IP_HDRINCL = 3的话发送不出去，IP_HDRINCL=2（TTL）的话是可以的，但是并不是自己定义的IP头，

root用户执行程序的？


Question: 清理上网痕迹

是一组批处理命令 attrib 更改权限 del 删除文件

在cmd窗口中输入 help 或 help 要取得帮助的命令 或 要取得帮助的命令 /?

貌似都是一些批处理命令 上网找一下批处理命令的解释 对应着应该能看懂吧 attrib命令 del命令等 手动删改文件的过程改用了批处理


Question: 有关一段代码的疑问（指针的）

引用 8 楼 w82076322 的回复:[quote=引用 6 楼 starytx 的回复:] [quote=引用 5 楼 w82076322 的回复:] [quote=引用 1 楼 starytx 的回复:] p保存着地址，*p就是去这个地址上的内容(值)，很正常啊，有什么疑问呢？ p=&n  这是把n的地址给了p，那么对p取内容的时候就是读取n的数值 *p=&n 我理解的是对p读内容的时候读出来的应该是n的地址才对[/quote]指针类型前边加个*,表示对指针的“解引用”操作，意即取出该指针指向的地址的值[/quote]那这时候p本身就存有n的数值了，n的数值变化还会影响p么？p还能操作n么？[/quote]p本身保存着n这个变量的地址值，n数值的变化不会影响p的值(p本身是一个地址值)，通过*p = xxx;也就相当于n = xxx;修改了n的值

引用 7 楼 truexf 的回复:int n = 2; int *p = &n; //初始化。对p进行定义并初始化为n的地址，相当于 int *p; p = &n;两条语句 *p = n; //赋值。修改p指向的地址的内容为n;  初始化、赋值，是不同的概念，虽然都是一个等号操作符。懂了！谢谢！

引用 6 楼 starytx 的回复:[quote=引用 5 楼 w82076322 的回复:] [quote=引用 1 楼 starytx 的回复:] p保存着地址，*p就是去这个地址上的内容(值)，很正常啊，有什么疑问呢？ p=&n  这是把n的地址给了p，那么对p取内容的时候就是读取n的数值 *p=&n 我理解的是对p读内容的时候读出来的应该是n的地址才对[/quote]指针类型前边加个*,表示对指针的“解引用”操作，意即取出该指针指向的地址的值[/quote]那这时候p本身就存有n的数值了，n的数值变化还会影响p么？p还能操作n么？

引用 5 楼 w82076322 的回复:[quote=引用 1 楼 starytx 的回复:] p保存着地址，*p就是去这个地址上的内容(值)，很正常啊，有什么疑问呢？ p=&n  这是把n的地址给了p，那么对p取内容的时候就是读取n的数值 *p=&n 我理解的是对p读内容的时候读出来的应该是n的地址才对[/quote]指针类型前边加个*,表示对指针的“解引用”操作，意即取出该指针指向的地址的值

引用 1 楼 starytx 的回复:p保存着地址，*p就是去这个地址上的内容(值)，很正常啊，有什么疑问呢？ p=&n  这是把n的地址给了p，那么对p取内容的时候就是读取n的数值 *p=&n 我理解的是对p读内容的时候读出来的应该是n的地址才对

int n = 2; int *p = &n; //此时p就是n的地址，而*表示取地址对应的内容，就是2

你可以这么理解。 int *p跟int i是一回事,那么 *p和i都一样是一个int类型。因为你打印i的打印数值，所以*p保存的也是数值！

你想打印地址，就不要加*了，*是取值操作。

p保存着地址，*p就是去这个地址上的内容(值)，很正常啊，有什么疑问呢？


Question: 在C语言的环境下分别用多进程和多线程求素数

#include <stdio.h> #include <stdlib.h> #include <string.h> #ifdef WIN32     #include <windows.h>     #include <io.h> #else     #include <unistd.h>     #include <sys/time.h>     #include <pthread.h>     #define  CRITICAL_SECTION   pthread_mutex_t     #define  _vsnprintf         vsnprintf #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); } #else void Lock(CRITICAL_SECTION *l) {     pthread_mutex_lock(l); } void Unlock(CRITICAL_SECTION *l) {     pthread_mutex_unlock(l); } #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} int main(int argc,char * argv[]) {     int i; #ifdef WIN32     InitializeCriticalSection(&cs_log); #else     pthread_mutex_init(&cs_log,NULL); #endif     for (i=0;i<10000;i++) {         Log("This is a Log %04d from FILE:%s LINE:%d\n",i, __FILE__, __LINE__);     } #ifdef WIN32     DeleteCriticalSection(&cs_log); #else     pthread_mutex_destroy(&cs_log); #endif     return 0; } //1-78行添加到你带main的.c或.cpp的那个文件的最前面 //81-85行添加到你的main函数开头 //89-93行添加到你的main函数结束前 //在要写LOG的地方仿照第87行的写法写LOG到文件MyLog1.log中

2楼说的很正确，就算写出来了，运行正常，结果也会非常接近，根本达不到你的目的。  进程线程效率问题体现在多任务通信的开销上，通信越频繁，效率差距越大。  而你的测试程序，是一个cpu消耗型任务，根本没牵扯到任务间通信，性能不会差太多。

貌似你这个没有什么意义啊，算素数这个和进程线程也没关系，进程只是浪费点内存。切换浪费点点时间，和你的运算素数的数量级比，可以忽略。

C语言这个环境太大啊。要求的线程库，进程间通信的机制都是操作系统相关的。你说的求素数是怎么个求法，从2开始一直往上尽可能多地找素数吗？这些都要搞清楚。  如果是从2开始尽可能多地找素数，你可以先写一个单进程单线程的，看看应该怎么在进程/线程间分配计算任务。

不知道楼主要 在 unix系统 还是 win系统的测试？

为什么要为难自己

Finding prime numbers - Kenneth Haugland Different schemas for finding prime numbers explained with code http://www.codeproject.com/Article.aspx?tag=198374988322054872&


Question: Opencv进行图像匹配的问题

opencv自带例子？

opencv对算法好的封装，最好学习相关的算法理论，匹配有好多种的，基于质心的 模板的 直方图的 轮廓等等，每个算法都有依据的。

先编译链接调试OpenCV自带的相关例子代码？


Question: 一事不明，关于main函数return 0

引用 12 楼 pathletboy 的回复:这其实是一个宏定义值，只是人家一般未使用宏定义，直接数字了，定义在stdlib.h中 /*  * These values may be used as exit status codes.  */ #define	EXIT_SUCCESS	0 #define	EXIT_FAILURE	1 标准写法应该是 return EXIT_SUCCESS; 当然这需要include上stdlib.h 您说的才是重点，解决了我的问题。thanks

人家喜欢返回0咋的了 人家有没有说不许你返回false 你完全可以返回任何你喜欢的数

自己编写的程序 main()是主函数， 实际上这个main是要被系统函数调用的，main函数 的返回值 是 这个系统函数 查看 你写的这个程序 的退出 状态的。 你可以看看return（）和 _exit（）的区别 ， 你对这个问题的理解。

。。。楼主你想太多了

0 标识 false  非0 true 函数返回值要匹配函数的原型的！ main函数是程序的入口函数，返回会给系统的，0表示正常吧

负数一般是false 其他是true

windows用0表示正常、成功，非0就表示相应的失败error

c语言没有布尔型这个概念，c语言的真和假用0和非0表示，0为假，非0为真。至于man函数返回0，是因为规定main函数为int型的，而int型的函数必须返回int型的数据，而返回0一般表示函数正常结束，返回其他值有其他含义。

成功运行了的程序只有一种可能----返回0 失败的程序则各有各的失败----返回各种非0

返回值类型是int，所以建议返回正确写return 0，而不是return true。 至于c语言中 1等于true，0等于false，你这个说法也是不正确的，true和false的值不是在任何地方都等于1和0的。   很多时候函数正常返回0，异常返回-1

返回的其实是一个int值，参考下面的文章就会很清楚了： http://blog.csdn.net/fangfei_119/article/details/2256656 http://blog.csdn.net/piaojun_pj/article/details/5986516  引用 楼主 u013457767 的回复:c语言中 1等于true，0等于false，那么main函数中为嘛要返回0而不是1呢？ 这种规定有问题吗  #include "stdafx.h" int main( int argc, char *argv[] )  { 	return ( int )true; }

return ( int )true;   这返回的是int类型啊,没bool啥事吧。

因为他是main 木有问题，不好理解的话，这就是规定

main的返回值不是bool，是int，一般int类型的返回值，返回0表示正常，其他值表示其他意义


Question: codeblocks单步调试求助

走到这一步时，这一句还没有执行，而程序进程是被挂起的。所以你的输入没有立即显示到程序上。  再往下走一步再输入就行了

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

就是影响啊，万一输入错误怎么办

不影响调试就OK了啊。  引用 楼主 u013545836 的回复:我写了一个简单的程序如下，用codeblocks进行单步调试，但走到while（（ch=getchar())!=EOF)这一步的时候，那个黑窗口一弹出就立马最小化，而且输入时完全没反应，点击下一步后再看黑窗口，上面就就显示了刚才输入的，这是怎么情况


Question: c main () ;获取函数值的问题？

引用 3 楼 xihu1364 的回复:char ntop[NI_MAXHOST];  是临时变量，过了生命域，就还给系统了  2种解决办法  1.将char*以函数的参数传进去  2.别用临时变量，去堆上申请，用完就释放 还有static

引用 1 楼 vipcxj 的回复: const char * ntop = get_socket_address(socket, remote, flags); //socket，remote，flags是什么我也不知道，这个问你~ sprintf(buf,"%s",ntop); ... //此时ntop已经不需要了 xfree(ntop);  我觉得LZ你应该去多看看书，把基础搞好再说，你就初学水平，竟然还搞网络变成~ 纸上得来终觉浅，绝知此事要躬行。 个人觉得

拷贝值  struct ntop {   char v[NI_MAXHOST] };  static struct ntop get_socket_address(...)

昨晚做了一晚自己搞定，多楼上几位朋友指点了，用main()调用函数就可以解决了。谢了


Question: 大家帮忙看下什么原因

引用 5 楼 huang369509940 的回复:[quote=引用 4 楼 u013537217 的回复:] [quote=引用 1 楼 huang369509940 的回复:] 中文乱码。。。编码方式的问题吧 用的是VC么？ 使用WIN-TC编写的 [/quote] 可能是这个平台不支持中文 换个吧 用VC++或devc++[/quote] 没用过TC 你看看这个管用不 http://zhidao.baidu.com/link?url=ruso4UeqLymakIqcpeiYK_wk2cDeHfI4t-xmaHjOGAvO7qtXF9Rtu9ZtT0bFAl6hUUXve0YDUv8I9t80uvX4Kq

引用 4 楼 u013537217 的回复:[quote=引用 1 楼 huang369509940 的回复:] 中文乱码。。。编码方式的问题吧 用的是VC么？ 使用WIN-TC编写的 [/quote] 可能是这个平台不支持中文 换个吧 用VC++或devc++

引用 1 楼 huang369509940 的回复:中文乱码。。。编码方式的问题吧 用的是VC么？ 使用WIN-TC编写的

使用WIN-TC编写的

没见过，不科学

中文乱码。。。编码方式的问题吧 用的是VC么？

wintc 工具里面 有一个 中文界面的 你找找

引用 楼主 u013537217 的回复: 运行结果后  不显示汉字   不知道为啥??????  你得先setlocale，然后用wprintf输出。字符串字面量得用前缀L。

winTC不支持中文，建议使用vc或者vs


Question: 新人，望各位大大指教代码。

单步调试 慢慢看就懂了

可以这样理解，当i=1的时候，进入第二层循环，j<=i则执行1次，输出1个*,然后出循环，输出一次换行（\n），再继续第一层循环i=2时，进入第二层循环，j<=i则输出2个*，然后出循环，输出一次换行（\n），依次类推，直到i=8的时候，进入第二层循环输出8个*,之后整个循环结束。于是打印成这个上下下大的图案 #include <stdio.h>  int main() {    int i,j;        for(i=1;i<=8;i++)//i可以控制*的行数      {          for(j=1;j<=i;j++)//j可以控制每行*的个数        {          printf("*");                      }             printf("\n");//i每循环一次输出一次换行，一共8行                 }          return 0; }

说是一物即不中！

引用 楼主 u011565490 的回复:#include <stdio.h>  int main() {    int i,j;        for(i=1;i<=8;i++)      {          for(j=1;j<=i;j++)        {          printf("*");                      }             printf("\n");                 }          return 0; }      * ** *** **** ***** ****** ******* ********   求详解，新人看不懂啊，喷子请点右（左）上角红叉  谢谢！  已经定义了整型变量i、j，下面执行第一个for语句： 首先执行的是i = 1，之后判断i是否小于等于8（即执行的是for中间的那个语句），因为i的确小于8，所以i<=8成立，于是开始执行for控制的语句，即第二个for语句； 第二个for语句，首先执行的是j = 1，之后判断j是否小于等于i，因为此时i = 1，j = 1，所以j<=i成立，于是开始执行下一个语句（即第二个for语句控制的那个printf语句），输出了一个*，之后j++，j就变成了2，而此时i的值仍是1，所以j<=i不成立，第二个for循环结束，继续执行下一个语句（因为下一个printf语句和第二个for语句都被第一个for语句所控制），即printf("\n")，进行了换行，然后返回执行第一个for语句的第三个，即i++，此时i = 2，再执行第一个for的第二个，即判断i是否小于等于8，是，于是执行第一个for控制的语句，即第二个for语句，还是先执行j = 1，然后判断j是否小于等于i，是则执行第二个for语句控制的语句，即printf（"*"），然后j++，j变成2，再判断j是否小于等于i，是，则再次执行printf（"*"），然后j++，j变成了3，判断j是否小于等于i，此时i仍是2，所以循环条件不在满足，第二个fou语句结束，继续执行下一个语句，即printf("\n")，进行了换行，再然后执行第一个for语句的第三个，即i++，此时i = 3，接着再执行第一个for的第二个，即判断i是否小于等于8.....如此反复循环执行直至执行完i++后i = 9，即i不再满足i<=8这个条件，循环就此结束最终输出了楼主下边输出的结果。

代码功能归根结底不是别人帮自己看或讲解或注释出来的；而是被自己静下心来花足够长的时间和精力亲自动手单步或设断点或对执行到某步获得的中间结果显示或写到日志文件中一步一步分析出来的。 提醒：再牛×的老师也无法代替学生自己领悟和上厕所！ 单步调试和设断点调试是程序员必须掌握的技能之一。

#include <stdio.h>  int main() {    int i,j;        for(i=1;i<=8;i++)//控制行数      {          for(j=1;j<=i;j++)//控制*号的个数        {          printf("*");//打印*                      }             printf("\n");//每循环一次换行                 }          return 0; }

这是一个双重的嵌套循环。外层i从1到8(1,2,3,4,5,6,7,8)正好8次，这是八行的来历  内层循环打印每行的*字符。  如果把内层循环写成 for(j=1; i<=8;++)...这样会打印出一个方方正正的8x8的矩阵。但它采用了变上界i。i这个变量每次进入for-j循环时的值比前一次大1，从1开始，这样第一行i=1，打印的*的个数也是1，第二行i=2，打印*的个数也是2，以此类推，到第八行打印出了8个*。  for循环的语法你应该知道吧，由分号分隔成3部分，第一部分通常称为初始化块，一般用于初始化循环计数器，在进入循环体前执行。第二部分为条件判断块，仅当该逻辑表达式(或其它可以隐式地转化为boolean值的表达式。第三部分是更新块，它会在循环体的后面执行，设计的目的用于更新计数器。以上各块都可以为空，为空时相应的；分隔符还是要保留。  以for(int i=0; i<2; ++i) {     循环体 }  1. 初始化    int i=0; 2. 条件检查 如果 i<2，进入循环体3， 否则跳出循环去到5 3. 循环体 4. 更新计数器 ++i，跳转到2; 5. 循环后的第一个语句  开始，执行1， i为0； 2. i==0 <2 成立，进入3 3. 第一次执行循环体 4. 更新计数器 ++i, i变成了1，跳转到2 2. i为1， 小于2成立，进入3 3. 第二次执行循环体 4. 更新计数器 ++i, i变成了2，跳转到步骤2 2. i为2，小于2不亨利，跳转到5，循环结束。  可以看到初始化块执行了1次，循环体和更新块各执行了2次，结束循环的时候i为2，但因为我们声明i的方式，这个变量在循环外不可见了。


Question: 请问高手，谁用c语言和go语言做过比较？

IT界可以没有go语言，但绝不能没有c语言！

引用 15 楼 ForestDB 的回复:[quote=引用 14 楼 king_2007 的回复:] [quote=引用 13 楼 ForestDB 的回复:] 中文和英语有区别吗？ 汇编和C有区别吗？ C和go有区别吗？你怎么不看我的引用就发言呢？[/quote] 那请看我7L的发言。 [/quote] 我看你还是完整的看完go再发言吧！

引用 14 楼 king_2007 的回复:[quote=引用 13 楼 ForestDB 的回复:] 中文和英语有区别吗？ 汇编和C有区别吗？ C和go有区别吗？你怎么不看我的引用就发言呢？[/quote] 那请看我7L的发言。

引用 13 楼 ForestDB 的回复:中文和英语有区别吗？ 汇编和C有区别吗？ C和go有区别吗？你怎么不看我的引用就发言呢？

中文和英语有区别吗？ 汇编和C有区别吗？ C和go有区别吗？

引用 10 楼 gavin_8724 的回复:两种应用于不同目标环境中的语言放在一起比较毫无意义！针对不用的应用环境具体分析吧！  什么是不同目标环境？？这两种语言有什么区别吗？

c 和 go 的共同点 Thompson

具体的比较，请问有谁做过？对比一下。

个人还没有真正完整去看go 但是觉着Google是在做互联网环境中的C 就像面向机器的C一样  即 CPU -> C 互联网 -> go

不同语言不同用途，就像有C\C++\Java。。。

系统底层开发？ ==> c /C++

引用 1 楼 ForestDB 的回复:简言之，目标不同，谈何比较？ 板凳已准备 准备看评论

那目标不一样，你对c语言和go语言有什么体会？？随便谈谈。

简言之，目标不同，谈何比较？


Question: c语言 malloc疑问

我考研的考试题就有一个这样的，明显有溢出，但是可以输出的

溢出了！不安全的，下次当你程序使用内存较多的时候就容易出问题了！

引用 24 楼 lyramilk 的回复:malloc是每次分配的内存是一个小块，并不是真给的参数，而是更大一些的整块。你malloc(1)还是malloc(4)都是一样的。我没记错的话这个粒度好像是32个字节，你malloc32个字节以内都是一样的。你的分配没有任何问题。  在application verifier中配置好内存检查之后，系统会在malloc分配之后的精确位置上映射一页不可写的内存强制安置一个边界帮助你检查泄露。误导别人了 malloc 分配的内存块 只有参数指定的那么大一块可以保证安全的使用 malloc 分配比参数多的部分 你怎么知道能用 实现可能是实现 用来存储调试信息 内存保护之类的 别胡乱去改

引用 24 楼 lyramilk 的回复:malloc是每次分配的内存是一个小块，并不是真给的参数，而是更大一些的整块。你malloc(1)还是malloc(4)都是一样的。我没记错的话这个粒度好像是32个字节，你malloc32个字节以内都是一样的。你的分配没有任何问题。  在application verifier中配置好内存检查之后，系统会在malloc分配之后的精确位置上映射一页不可写的内存强制安置一个边界帮助你检查泄露。 刚才试了一下，貌似应该是8个字节。 malloc(1) === malloc(8)

有溢出，推荐用strncpy，就像少用strcat，多用strncat，少用gets,多用fgets一样。

举个例子，两个人坐一张桌子，因为某种原因对方小妹妹给你分了三八线，严正声明：超过三八线的是小狗！ 可是你趁他不注意的时候超过线了。。。她不知道吧。但是万一你动作过大或者某种未知原因，不幸被她发现了，那就。。。越界了必然造成溢出，只不过你的溢出是造成简单的数据覆盖，还是直接适用了未分配的内存。不崩不代表就没溢出。  再举个例子: struct Test {   char szData[4];   char cType; }  Test t; t.szData[4] = 'e';//单看这个数组的定义和适用你能说没溢出吗？确实越界溢出了 但是，这里结构体两个成员后面还有一个，由于结构体内存连续，t.szData[4]实际上已经是cType这个变量了

已经溢出了  内存是“平坦”的，连续的，给了你两个字节的空间，但是这两个字节是和别的空间连在一起的。 请注意：strcpy是不会帮你做越界检查的，整个C都不会，那是你自己的责任。

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

溢出了，只是没有崩溃而已，楼上说得对！

已经溢出 运气好而已

肯定内存溢出了，这又是个蛋疼的问题，输出是有可能可以输出。如果name分配的内存(2个字节)后面刚好是编译器不允许你操作的内存，就会报段错误，如果允许你操作，你的操作就会覆盖你没有操作权限的内存，影响其它程序段的运行。

运气好没挂掉，正好申请的2个字节内存后面没有被其它程序占用。

能打印不等于没溢出，不能用偶然的正确去推导出必然的正确。 引用 楼主 biangren 的回复:比如下面一段代码: char *name=(char *)malloc(2*sizeof(char)); strcpy(name,"binjing"); printf("name=%s",name); 输出：name=binjing  有一点疑问 char *name=(char *)malloc(2*sizeof(char)); 这段执行的时候，分配了两个字节的内存空间，此时name为这段内存空间的首地址 strcpy(name,"binjing"); 这段执行的时候，把"binjing"复制给了这段内存空间，但是内存空间一开始只分配了2个字节，这样为什么不会导致”溢出“?

谁说不安全的操作就一定会马上死的？

未定义行为.

同意楼上说的，其实这个程序已经溢出了

运行的结果正确不能代表程序没有问题，这句话应该知道吧，你自己都知道内存溢出了，问题都知道了，解决它

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


Question: 文件读取------获取值

请判断fscanf函数的返回值！  推荐使用WinHex软件查看硬盘或文件或内存中的原始字节内容。  不要把 fopen("...","...");fscanf,fprintf,fclose //读时把\r\n替换成\n，写时把\n替换成\r\n;读到\x1a就设置EOF;读写的内容当字符看待 和 fopen("...","...b");fread,fwrite,fclose  //不作以上替换，遇到\x1a仍继续读;读写的内容当字节看待 弄混了  电脑内存或文件内容只是一个一维二进制字节数组及其对应的二进制地址； 人脑才将电脑内存或文件内容中的这个一维二进制字节数组及其对应的二进制地址的某些部分看成是整数、有符号数/无符号数、浮点数、复数、英文字母、阿拉伯数字、中文/韩文/法文……字符/字符串、汇编指令、函数、函数参数、堆、栈、数组、指针、数组指针、指针数组、数组的数组、指针的指针、二维数组、字符点阵、字符笔画的坐标、黑白二值图片、灰度图片、彩色图片、录音、视频、指纹信息、身份证信息……  printf里面的%和变量的一一对应关系 scanf里面的%和变量以及变量前加不加&的一一对应关系 是C代码中非常容易出错的地方，而且通常编译还不出错。 所以在编译源代码之前值得专门仔细检查一遍甚至多遍。

我想要fscanf函数，，但出了点问题。 char buf[128]; int value = 0; 在while(!feof(fp)) {       fscanf(fp, "%s", buf); 还是  fscanf(fp, "%d", &value); }

引用 15 楼 u012889234 的回复:[quote=引用 14 楼 derekrose 的回复:] [quote=引用 9 楼 u012889234 的回复:] [quote=引用 7 楼 derekrose 的回复:] 文件的内容怎么会有value 都是字符啊。。。 enum GLOBAL_VALUE {     nId,     value_num  }; enum GLOBAL_STRING {       strFile = value_num,       string_num }; /*文件的内容怎么会有value 都是字符啊。。。*/  什么意思。 文件就两个枚举。 enum GLOBAL_VALUE {     nId,     value_num  }; 这个枚举里全是值类型的全局变量名，value_num不就是总个数吗，枚举默认从0开始，这里就是1。 enum GLOBAL_STRING {       strFile = value_num,       string_num }; 这个枚举里全是串类型的全局变量名，string_num不就是串类型的总个数吗，从value_num开始（也就是1开始），这里string_num = 2。[/quote] 这种需求是谁要的。。。 [/quote]   全局变量管理器： 管理所有的全局变量。[/quote]  相当于一个parse工具了  你现在的难点在哪一步？

引用 14 楼 derekrose 的回复:[quote=引用 9 楼 u012889234 的回复:] [quote=引用 7 楼 derekrose 的回复:] 文件的内容怎么会有value 都是字符啊。。。 enum GLOBAL_VALUE {     nId,     value_num  }; enum GLOBAL_STRING {       strFile = value_num,       string_num }; /*文件的内容怎么会有value 都是字符啊。。。*/  什么意思。 文件就两个枚举。 enum GLOBAL_VALUE {     nId,     value_num  }; 这个枚举里全是值类型的全局变量名，value_num不就是总个数吗，枚举默认从0开始，这里就是1。 enum GLOBAL_STRING {       strFile = value_num,       string_num }; 这个枚举里全是串类型的全局变量名，string_num不就是串类型的总个数吗，从value_num开始（也就是1开始），这里string_num = 2。[/quote] 这种需求是谁要的。。。 [/quote]   全局变量管理器： 管理所有的全局变量。

引用 9 楼 u012889234 的回复:[quote=引用 7 楼 derekrose 的回复:] 文件的内容怎么会有value 都是字符啊。。。 enum GLOBAL_VALUE {     nId,     value_num  }; enum GLOBAL_STRING {       strFile = value_num,       string_num }; /*文件的内容怎么会有value 都是字符啊。。。*/  什么意思。 文件就两个枚举。 enum GLOBAL_VALUE {     nId,     value_num  }; 这个枚举里全是值类型的全局变量名，value_num不就是总个数吗，枚举默认从0开始，这里就是1。 enum GLOBAL_STRING {       strFile = value_num,       string_num }; 这个枚举里全是串类型的全局变量名，string_num不就是串类型的总个数吗，从value_num开始（也就是1开始），这里string_num = 2。[/quote] 这种需求是谁要的。。。

引用 12 楼 ganpengjin1 的回复:没有办法了，只能挨个字符读出，一行算一个变量名了。然后你的变量名所存的数据用map比较，key作为变量名，直接hash去查找你的数据了，只能这样了。  我弱弱的说一句，要是哪个员工这样设计存储方式，明年估计不用来上班了。 其实你说复杂了，这里只有名字，没有值，不用map，，也不用hash。 我只是要获取value_num 和 string_num的值。 肯定是两个整数  。比如这里 value_num = 1   string_num = 2.

引用 8 楼 ganpengjin1 的回复:你这个数据时怎么保存的，目前我只知道你的文件中保存的是两个枚举类型的数据结构。 这个文件里仅仅是全局变量名， 而怎么初始化这些全局变量 ，怎么使用，其他的一切这里都不考虑！

引用 8 楼 ganpengjin1 的回复:你这个数据时怎么保存的，目前我只知道你的文件中保存的是两个枚举类型的数据结构。 是的，就只有两个枚举，没有别的！

引用 7 楼 derekrose 的回复:文件的内容怎么会有value 都是字符啊。。。 enum GLOBAL_VALUE {     nId,     value_num  }; enum GLOBAL_STRING {       strFile = value_num,       string_num }; /*文件的内容怎么会有value 都是字符啊。。。*/  什么意思。 文件就两个枚举。 enum GLOBAL_VALUE {     nId,     value_num  }; 这个枚举里全是值类型的全局变量名，value_num不就是总个数吗，枚举默认从0开始，这里就是1。 enum GLOBAL_STRING {       strFile = value_num,       string_num }; 这个枚举里全是串类型的全局变量名，string_num不就是串类型的总个数吗，从value_num开始（也就是1开始），这里string_num = 2。

你这个数据时怎么保存的，目前我只知道你的文件中保存的是两个枚举类型的数据结构。

文件的内容怎么会有value 都是字符啊。。。

引用 5 楼 ganpengjin1 的回复:[quote=引用 4 楼 u012889234 的回复:] [quote=引用 3 楼 ganpengjin1 的回复:] [quote=引用 2 楼 u012889234 的回复:] [quote=引用 1 楼 ganpengjin1 的回复:] 直接read就好了 [/quote]  sorry，没看清楚前面的，是文件内容，这个就不好办了，比较麻烦，为何不把这个数据结构的数据单独放到一个文件中，然后read它们呢，[/quote] 这个文件里的内容是不定的，有用户自己决定。这是个全局变量管理器，具体多少个全局变量不是预先确定的。[/quote] 为什么不用数据库呢，数据库搞的话，一下就搞定了。[/quote] 数据库是另一种方式，都需要考虑到！

引用 4 楼 u012889234 的回复:[quote=引用 3 楼 ganpengjin1 的回复:] [quote=引用 2 楼 u012889234 的回复:] [quote=引用 1 楼 ganpengjin1 的回复:] 直接read就好了 [/quote]  sorry，没看清楚前面的，是文件内容，这个就不好办了，比较麻烦，为何不把这个数据结构的数据单独放到一个文件中，然后read它们呢，[/quote] 这个文件里的内容是不定的，有用户自己决定。这是个全局变量管理器，具体多少个全局变量不是预先确定的。[/quote] 为什么不用数据库呢，数据库搞的话，一下就搞定了。

引用 3 楼 ganpengjin1 的回复:[quote=引用 2 楼 u012889234 的回复:] [quote=引用 1 楼 ganpengjin1 的回复:] 直接read就好了 [/quote]  sorry，没看清楚前面的，是文件内容，这个就不好办了，比较麻烦，为何不把这个数据结构的数据单独放到一个文件中，然后read它们呢，[/quote] 这个文件里的内容是不定的，有用户自己决定。这是个全局变量管理器，具体多少个全局变量不是预先确定的。

引用 2 楼 u012889234 的回复:[quote=引用 1 楼 ganpengjin1 的回复:] 直接read就好了 [/quote]  sorry，没看清楚前面的，是文件内容，这个就不好办了，比较麻烦，为何不把这个数据结构的数据单独放到一个文件中，然后read它们呢，

引用 1 楼 ganpengjin1 的回复:直接read就好了

直接read就好了


Question: 帮忙写个C程序

引用 1 楼 ganpengjin1 的回复:程序意思明白，但是不知道有何用 没什么用，但是很想知道这样的程序怎么写。

写一个数组存1～9,定义一个变量(i)用来存你获取的次数,每获取一次,i++  然后用9-i来替换你取出的值。

程序意思明白，但是不知道有何用


Question: printf %lf %f修饰符问题

%lf据cpp这本书上说，在scanf里面是输入double，因为printf会把float转换成double,所以只有%f，没有%lf，想输入和输出long double,是%Lf

引用 楼主 u013529726 的回复:不是 %lf %f都可以打印 double么？  但是在我这里 #include<stdio.h> int main() {     double i=0.5;     printf("%f %lf",i,i);     return 0; }  这个程序的输出是  0.500000 0.000000  为什么第二个%lf 不输出正确的值？  查到的资料 c99标准 %lf等价于%f。。。 c99标准（编译器设置为 -std=c99 )楼主的代码在我的编辑器dev c++ 5.5.3上是正常输出的

%f对应double，而%Lf对应long double。且有%lf等效于%f。  依据如下 C语言标准中有如下的信息： l      It has no effect on a following a, A, e, E, f, F, g, or G        conversion specifier . 在linux下man 3 printf可以得到如下的信息： L      A following a, A, e, E, f, F, g, or G conversion corresponds  to        a long double argument.  (C99 allows %LF, but SUSv2 does not.)

不知道为什么，不选C90了，也是这个样子！

C90 不会改成 %hf--->flaot,%f -->double, %lf--> long double 了吧 code::block 12.11 输出如下选上 C90。  #include<stdio.h>  int main() {     float f=0.5;     double d =0.5 ;     long double ld=0.5;      printf("size of float,double,long double %d,%d,%d\n",sizeof(f),sizeof(d),sizeof(ld));     printf("f = %hf d = %f ld = %lf\n",f,d,ld); //选上 C90。 是这种格式；     //printf("f = %f d = %lf ld = %Lf\n",f,d,ld); 通常是这种格式；     return 0; } 结果： size of float,double,long double 4,8,12 f = 0.500000 d = 0.500000 ld = 0.500000

c99中应该是一样的，我在mingw gcc上执行的结果是一样的，不知道是否你编译器的问题。

貌似没有%lf  http://www.cplusplus.com/reference/cstdio/printf/

%f ---- double %Lf ----- long double

引用 楼主 u013529726 的回复:查到的资料 c99标准 %lf等价于%f。。。 c99标准（编译器设置为 -std=c99 )  什么资料?

引用 3 楼 user-8 的回复:不要在只试了一个编译器后就急着求助。 ...可是我问的是为什么啊~ 应该是可以的 c99中 %lf应该等价于%f啊~  如果在设置中删掉这句【-std=c99】 输出就是0.500000 0.500000

不要在只试了一个编译器后就急着求助。

引用 1 楼 user-8 的回复:楼主试过几个编译器？ 用的codeblocks gcc

楼主试过几个编译器？


Question: 有啥区别？

引用 3 楼 KenZhang1031 的回复:linklist相当于listnode *；比如 listnode * head和linklist head是一样的。   是不是意味着我可以将上面的修改为如下：  typedef struct lnode {    char name[20];    char addr[20;    struct lnode *nest; }listnode;//*linklist;  listnode  * head = NULL, *r = NULL; listnode  *p_creat,*p_save;

上述中的listnode与*linklist有哈区别的,分别具体指什么意思呢？ 简单的理解 listnode就是该结构体类型的变量 ，可以直接用；*linklist是该结构体类型的指针，必须指向有效地址空间才能正确使用 例如：linklist=&listnode .或者动态开辟一块内存，然后用该指针进行操作。

没错，可以，少打了一个括号外，char addr[20];其它没问题。 引用 6 楼 learner520 的回复:[quote=引用 3 楼 KenZhang1031 的回复:] linklist相当于listnode *；比如 listnode * head和linklist head是一样的。   是不是意味着我可以将上面的修改为如下：  typedef struct lnode {    char name[20];    char addr[20;    struct lnode *nest; }listnode;//*linklist;  listnode  * head = NULL, *r = NULL; listnode  *p_creat,*p_save;[/quote]

主要区别是 一条声明（定义）语句，可能会声明（定义）若干变量。 linklist 不需要每次都加个*号 ，定义的只能是指针。 listnode 可以定义节点或者，节点指针，定义指针每次都要加个*号，定义节点不需要。  listnode 定义指针，漏了* 就是错误，linklist没有这个问题。  其次，linklist 表示链表，意义明确。 listnode 只是链表一个节点的数据结构，同样意义明确。//就是说，名副其实  C中 struct lnode 是类型的完整名字，lnode 不是（只是类型名字的一部分）， 所以定义另一个名字listnode 替换 struct lnode ，表示节点的数据类型。  对于C++，这个listnode是多余的，lnode就可以了。  C的链表是非常简洁的，不过链表和节点的两个层次，纠缠到一起了  实际上应该这么定义  struct LinkList{ struct lnode *head; };  这样的链表，层次才清晰，不会和节点混淆。 不过，C追求简洁，高效，所以一般都不会这么干。

改成这样,也许你就懂了.  struct lnode {    char name[20];    char addr[20;    struct lnode *nest; }; typedef struct lnode listnode; typedef struct lnode *linklist;

listnode类型是lnode类型，linklist类型是lnode*类型

listnode代表的结构体struct Inode的类型名，而linklist代表的是struct Inode *的类型名。 关于结构体指针类型的重定义，这是规定的。 下面代码完全等价 listnode *p; 和linklist p; 上述代码都是定义了一个struct Inode类型的结构体指针p.


Question: 程序运行后 进程负载过高

linux下还可以用top命令吧。

线程内 死循环 不让出时间片会导致cpu占用过高，大量申请内存没有合理释放掉会导致占用内存过高

引用 4 楼 boyhailong 的回复:[quote=引用 3 楼 zhuobattle 的回复:] CPU过高，下个相关工具，比如ProcessExplorer，可以查看到每个线程的cpu及相应堆栈，就能定位问题出在哪里。 内存过高，有可能是内存泄漏，也有可能是对象管理不当，这个可以用windbg结合相关命令查看。 百度搜索下windbg 内存泄漏，它其实是可以找出运行一段时间后，相关内存分配（可以查看分配最多）的对应代码。 linux下呢？[/quote] linux下要使用oprofile，不过要内核打开支持。

用oprofile统计每个函数/每行代码的执行时间, 看是哪里的问题

引用 3 楼 zhuobattle 的回复:CPU过高，下个相关工具，比如ProcessExplorer，可以查看到每个线程的cpu及相应堆栈，就能定位问题出在哪里。 内存过高，有可能是内存泄漏，也有可能是对象管理不当，这个可以用windbg结合相关命令查看。 百度搜索下windbg 内存泄漏，它其实是可以找出运行一段时间后，相关内存分配（可以查看分配最多）的对应代码。 linux下呢？

内存使用过高  内存泄漏

cpu利用率过高  死循环


Question: 获得CPU风扇转速

楼主是怎么解决的这个问题

y pc has T-Balancer bigNG fan controller or http://www.alphacool.com/product_info.php/info/p999_Alphacool-Heatmaster-II.html?language=en ???

即将放假回家过年，感谢 luciferisnotsatan user-7 anti-child 等，各位好心人！ 年后继续这个问题，如果有好的思路我继续给分。 年前就到这里，我给大家散分！多少是个意思！祝大家新年快乐！

引用 17 楼 xinkexue 的回复:似乎就是调用API而已  请问能告诉我用具体的哪个API么？谢谢

引用 14 楼 luciferisnotsatan 的回复:[quote=引用 12 楼 coperator 的回复:] [quote=引用 9 楼 luciferisnotsatan 的回复:] DesiredSpeed      Data type: uint64     Access type: Read/write      Currently requested fan speed, defined in revolutions per minute, when a variable speed fan is supported (VariableSpeed is TRUE). The current speed is determined by a sensor (CIM_Tachometer) that is associated with the fan using the CIM_AssociatedSensor relationship. This property is inherited from CIM_Fan.  这句话里的两个连接看下有没有用  CIM_Tachometer CIM_AssociatedSensor 这两个类WMI都不实现，我应该怎么用啊？求指点[/quote] http://stackoverflow.com/questions/1310777/set-fan-speed-on-windows-in-c 这里有个通过com来获得的CIM_Fan，你可以试着用同样的方法来获得CIM_Tachometer   http://www.dmtf.org/standards/smbios   你可以在这里下到smbios协议[/quote]  http://stackoverflow.com/questions/1310777/set-fan-speed-on-windows-in-c 是set部分，我要的是get部分  http://www.dmtf.org/standards/smbios  这个非常好！我用细看了 感谢您，多次的帮助！

似乎就是调用API而已

WMI中有一个Win32_Fan T-Balancer bigNG fan controller or http://www.alphacool.com/product_info.php/info/p999_Alphacool-Heatmaster-II.html? can work bacos

引用 10 楼 KenZhang1031 的回复:这里有源代码 http://www.oschina.net/code/snippet_222150_14129  谢谢。但是不知道为什么？我用鲁大师读取到的是 1328转/分钟而 程序给出的是675，能告诉一下原因么？

引用 9 楼 luciferisnotsatan 的回复:DesiredSpeed      Data type: uint64     Access type: Read/write      Currently requested fan speed, defined in revolutions per minute, when a variable speed fan is supported (VariableSpeed is TRUE). The current speed is determined by a sensor (CIM_Tachometer) that is associated with the fan using the CIM_AssociatedSensor relationship. This property is inherited from CIM_Fan.  这句话里的两个连接看下有没有用  CIM_Tachometer CIM_AssociatedSensor 这两个类WMI都不实现，我应该怎么用啊？求指点

引用 8 楼 luciferisnotsatan 的回复:class Win32_Fan : CIM_Fan {   boolean  ActiveCooling;   uint16   Availability;   string   Caption;   uint32   ConfigManagerErrorCode;   boolean  ConfigManagerUserConfig;   string   CreationClassName;   string   Description;   uint64   DesiredSpeed;   string   DeviceID;   boolean  ErrorCleared;   string   ErrorDescription;   datetime InstallDate;   uint32   LastErrorCode;   string   Name;   string   PNPDeviceID;   uint16   PowerManagementCapabilities[];   boolean  PowerManagementSupported;   string   Status;   uint16   StatusInfo;   string   SystemCreationClassName;   string   SystemName;   boolean  VariableSpeed; };  DesiredSpeed      Data type: uint64     Access type: Read/write      Currently requested fan speed, defined in revolutions per minute, when a variable speed fan is supported (VariableSpeed is TRUE). The current speed is determined by a sensor (CIM_Tachometer) that is associated with the fan using the CIM_AssociatedSensor relationship. This property is inherited from CIM_Fan.      For more information about using uint64 values in scripts, see Scripting in WMI.  这个不是么？网上看了下，好像有些主板也不支持WMI获取fan的接口。 不行就只有试试SMBIOS了。如果是windows xp系统，应该还可以在用户态下映射物理内存文件。  “不行就只有试试SMBIOS了。如果是windows xp系统，应该还可以在用户态下映射物理内存文件。”您说的SMBIOS，是在debug中查到的么？在Win7下可以用“用户态下映射物理内存文件”么？

引用 12 楼 coperator 的回复:[quote=引用 9 楼 luciferisnotsatan 的回复:] DesiredSpeed      Data type: uint64     Access type: Read/write      Currently requested fan speed, defined in revolutions per minute, when a variable speed fan is supported (VariableSpeed is TRUE). The current speed is determined by a sensor (CIM_Tachometer) that is associated with the fan using the CIM_AssociatedSensor relationship. This property is inherited from CIM_Fan.  这句话里的两个连接看下有没有用  CIM_Tachometer CIM_AssociatedSensor 这两个类WMI都不实现，我应该怎么用啊？求指点[/quote] http://stackoverflow.com/questions/1310777/set-fan-speed-on-windows-in-c 这里有个通过com来获得的CIM_Fan，你可以试着用同样的方法来获得CIM_Tachometer   http://www.dmtf.org/standards/smbios   你可以在这里下到smbios协议

引用 4 楼 derekrose 的回复:http://www.codeproject.com/Articles/17973/How-To-Get-Hardware-Information-CPU-ID-MainBoard-I  谢谢！ 您给出的这个资料，我看了，但是没有找到风扇相关的信息啊！

引用 2 楼 user-7 的回复:http://msdn.microsoft.com/en-us/library/aa394146(VS.85).aspx http://msdn.microsoft.com/en-us/library/aa387269(v=vs.85).aspx http://stackoverflow.com/questions/485448/programmatically-access-cpu-fan-on-a-laptop-windows  谢谢！ 这个好像说WMI没有支持风扇转速的设置是吧？ 那有什么其他办法么？

引用 1 楼 luciferisnotsatan 的回复:SMBIOS里取到Cooling Device这个结构，应该就有风扇的信息。不过现在的windows（XP以后）已经不能在用户态下映射物理内存了。你还可以试试window提供的WMI，看看有没有风扇速度。  linux下，SMBIOS拿。或者看看dmidecode能不能直接拿到风扇转速。  谢谢！ 我是在Windows操作系统下，想要获得信息。 WMI中有一个Win32_Fan类，但是我得不到想要的信息。 不知道还有没有其他的类能获得风扇信息？


Question: 我写了一个求方差的C程序，但是在输完数据时，程序就出错退出，希望大家看一下哪里出错了！谢谢

引用 5 楼 yjx879735513 的回复:[quote=引用 4 楼 zhao4zhong1 的回复:] 崩溃的时候在弹出的对话框按相应按钮进入调试，按Alt+7键查看Call Stack里面从上到下列出的对应从里层到外层的函数调用历史。双击某一行可将光标定位到此次调用的源代码或汇编指令处。 我是直接用Mingw来编译的，这个也可以么？[/quote] 进程意外退出会在当前目录下产生‘core’文件或形如‘core.数字’的文件比如‘core.1234’ 使用命令 gdb 运行程序名 core或core.数字 进入gdb然后使用bt命令 可以查看进程意外退出前函数调用的堆栈，内容为从上到下列出对应从里层到外层的函数调用历史。 如果进程意外退出不产生core文件，参考“ulimit -c core文件最大块大小”命令

1.i一直没加，输入永远放在第一个数组，也就是i一直是0 2.所以导致j那个循环不会进去，直接发生除0异常，程序肯定crash了  可能隐患： 另外你这些除法要判断下是否可能发生除0的问题，比如 average = sum*1.0/(i-1);

引用 4 楼 zhao4zhong1 的回复:崩溃的时候在弹出的对话框按相应按钮进入调试，按Alt+7键查看Call Stack里面从上到下列出的对应从里层到外层的函数调用历史。双击某一行可将光标定位到此次调用的源代码或汇编指令处。 我是直接用Mingw来编译的，这个也可以么？

请问，出现这种情况是因为什么原因？

sum += number[i++];


Question: 最小公倍数

#include <stdio.h> int gcd(int v1,int v2) { 		while(v2) { 				int temp = v2; 				v2 = v1 % v2; 				v1 = temp; 		} 		return v1; } int main() {           int a,b,n;            n=gcd(a,b);           printf("%d\n",n); }

最大公倍数就是两数相乘再除以最大公约数，比如12、8，最大公约数是4，那么他们最小公倍数就是28*8/4=24。  最大公约数用碾转相除法，大的数除以小的数，如果能整除，则为小的那个数，如果不能，则以小的那个数为大数，余数为小的数，继续作此运算。  最好用循环，递归效率低些。   //a>b int GetGCD(int a, int b) {     int remainder = a % b;     while(remainder > 0)     {         a = b;         b = remainder;         remainder = a % b;     }      return b; }

#include<stdio.h>  int lcm(int,int);  int main(){           int a,b,l;      printf("Enter any two positive integers ");     scanf("%d%d",&a,&b);       if(a>b)          l = lcm(a,b);     else          l = lcm(b,a);         printf("LCM of two integers is %d",l);      return 0; }  int lcm(int a,int b){        int temp = a;      while(1){          if(temp % b == 0 && temp % a == 0)              break;          temp++;     }     return temp; }

比如x,y,z的最小公倍数，先求其中两个的最小公倍数，比如x,y最小公倍数得到是m,再求m,z的最小公倍数。n个数也是一样的道理。 引用 4 楼 u013337743 的回复:n个数怎么求

比如x,y,z的最小公倍数，先求其中两个的最小公倍数，比如x,y最小公倍数得到是m,再求m,z的最小公倍数。n个数也是一样的道理。 引用 3 楼 truelance 的回复:已知m,n 1. 用辗转相除法求最大公约数 2. 最小公倍数 = m*n/最大公约数

引用 4 楼 u013337743 的回复:n个数怎么求 比如求两个数的int foo(int x, int y) { .. } 那么如果你要求3个数就是 int foo3(int x, int y, int z) {     int t = foo(x, y);     return foo(t, z); } 如果求n个数(n >= 2) int foon(int x[], int n) {     int t = foo(x[0], x[1]);     for (int i = 2; i < n; i++)         t = foo(t, x[i]);     return t; }

n个数怎么求

选择一个数，从1到另一个数穷举倍数，找到第一个可以整除另一个数的值，返回。代码如下： int foo(int x, int y) {     for (int i = 1; i < y; i++)         if (x * i % y == 0) return x * i;     return x * y; }

已知m,n均为正整数，试用C语言写出求m与n的最小公倍数的算法，算法的步骤为(该算法的好处是只需用一次乘法)： （1） 计算m*n的积，送临时变量r。 （2） 若m等于n，则输出最小公倍数r/m，算法结束。 （3） 若m大于n，计算m-n，结果送m，否则，计算n-m，结果送n。(即max = max - min) （4） 转到（2）或者（3）。  在已知最大公约数的前提下，另一个方法：最小公倍数=m*n/最大公约数


Question: 大一新生求助！！

引用 4 楼 max_min_ 的回复:好好看看你手上的那本书呗，敲下例程！  嗯，好好看书，还要多加练习

好好看看你手上的那本书呗，敲下例程！

编程需要灵活的实践方法，多试试用不同的方法解决问题。

多上论坛混混，也会有很大帮助

学编程，多实践才是王道。多练习。多敲代码，切忌好高骛远。不要一开始就想着弄个图形界面的软件出来。先打磨语言功底。 基础的东西学完了，可以学习数据结构，慢慢的你的编码能力会再有提升。 有点数据结构和算法基础可以去做acm的题目。比如杭电OJ上的题目。

计算机组成原理→DOS命令→汇编语言→C语言（不包括C++）、代码书写规范→数据结构、编译原理、操作系统→计算机网络、数据库原理、正则表达式→其它语言（包括C++）、架构……  先下载Win-TC，然后参考C:\Win-TC\tcstudy.chm

引用 5 楼 SKATE11 的回复:对学习编程者的忠告： 眼过千遍不如手过一遍！ 书看千行不如手敲一行！ 手敲千行不如单步一行！ 单步源代码千行不如单步对应汇编一行！  VC调试时按Alt+8、Alt+7、Alt+6和Alt+5,打开汇编窗口、堆栈窗口、内存窗口和寄存器窗口看每句C对应的汇编、单步执行并观察相应堆栈、内存和 寄存器变化，这样过一遍不就啥都明白了吗。 对VC来说，所谓‘调试时’就是编译连接通过以后，按F10或F11键单步执行一步以后的时候，或者在某行按F9设了断点后按F5执行停在该断点处的时 候。看不懂哈。。。。。


Question: 如何去掉全角的空格？

void Trim(char *s) { for(; *s; s++) if(*s == -95) break; *s = 0; }  我把-95改为全角空格，还是一样~他居然把我所有的字符都KO了~~

-95应该是全角空格的内码。 如果不是，你可以直接写'　'

这个帖子我看过啦~-95是什么？？

#pragma comment(lib,"gdi32") #include <windows.h> #include <stdio.h>  int main() {     const DWORD uWidth = 18 + 17 * 256, uHeight = 18 + 17 * 128;      PBITMAPINFO pbmi = (PBITMAPINFO) LocalAlloc (LPTR, sizeof (BITMAPINFOHEADER) + sizeof (RGBQUAD) * 2);     pbmi->bmiHeader.biSize = sizeof (BITMAPINFOHEADER);     pbmi->bmiHeader.biWidth = uWidth;     pbmi->bmiHeader.biHeight = uHeight;     pbmi->bmiHeader.biPlanes = 1;     pbmi->bmiHeader.biBitCount = 1;     pbmi->bmiHeader.biSizeImage = ((uWidth + 31) & ~31) / 8 * uHeight;     pbmi->bmiColors[0].rgbBlue = 0;     pbmi->bmiColors[0].rgbGreen = 0;     pbmi->bmiColors[0].rgbRed = 0;     pbmi->bmiColors[1].rgbBlue = 255;     pbmi->bmiColors[1].rgbGreen = 255;     pbmi->bmiColors[1].rgbRed = 255;      HDC hDC = CreateCompatibleDC (0);     void * pvBits;     HBITMAP hBitmap = CreateDIBSection (hDC, pbmi, 0, &pvBits, NULL, 0);     SelectObject (hDC, hBitmap);     HFONT hFont = CreateFont (16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "宋体"); //  HFONT hFont = CreateFont (16, 0, 0, 0, 0, 0, 0, 0, SHIFTJIS_CHARSET, 0, 0, 0, 0, "宋体");     SelectObject (hDC, hFont);     BitBlt (hDC, 0, 0, uWidth, uHeight, NULL, 0, 0, WHITENESS);      char c[4];     int i, j;     for (i = 128; i < 256; i++) {         sprintf (c, "%02X", i);         TextOut (hDC, 1, (i - 127) * 17 + 1, c, 2);     }     for (j = 0; j < 256; j++) {         sprintf (c, "%02X", j);         TextOut (hDC, (j + 1)* 17 + 1, 1, c, 2);     }     for (i = 128; i < 256; i++) {         for (j = 0; j < 256; j++) {             c[0] = (char) i;             c[1] = (char) j;             TextOut (hDC, (j + 1) * 17 + 1, (i - 127) * 17 + 1, c, 2);         }     }     for (i = 0; i < 130; i++) {         MoveToEx (hDC, 0, i * 17, NULL);         LineTo (hDC, uWidth, i * 17);     }     for (j = 0; j < 258; j++) {         MoveToEx (hDC, j * 17, 0, NULL);         LineTo (hDC, j * 17, uHeight);     }      BITMAPFILEHEADER bmfh;     bmfh.bfType = *(PWORD) "BM";     bmfh.bfReserved1 = 0;     bmfh.bfReserved2 = 0;     bmfh.bfOffBits = sizeof (BITMAPFILEHEADER) + sizeof (BITMAPINFOHEADER) + sizeof (RGBQUAD) * 2;     bmfh.bfSize = bmfh.bfOffBits + pbmi->bmiHeader.biSizeImage;      HANDLE hFile = CreateFile ("goal.bmp", GENERIC_WRITE, 0, 0, CREATE_ALWAYS, 0, 0);     if (hFile != INVALID_HANDLE_VALUE) {         DWORD dwWritten;         WriteFile (hFile, &bmfh, sizeof (BITMAPFILEHEADER), &dwWritten, NULL);         WriteFile (hFile, pbmi, sizeof (BITMAPINFOHEADER) + sizeof (RGBQUAD) * 2, &dwWritten, NULL);         WriteFile (hFile, pvBits, pbmi->bmiHeader.biSizeImage, &dwWritten, NULL);          CloseHandle (hFile);     }      DeleteObject (hFont);     DeleteObject (hBitmap);     DeleteDC (hDC);     LocalFree (pbmi);      return 0; }  看一下上面代码生成的文件goal.bmp，里面显示为全角空格的GBK字符总共多少个！

先确定你用的是什么编码，不同编码，值不一定都一样。


Question: 分布式服务器学习

引用 5 楼 emailtome 的回复:分布式服务器编程（语言主要考虑C++,lua python  perl c js ...，平台考虑linux） 为毛排除C++，lua

眼见为实，耳听为虚。书的好坏在于是否适合自己，不是适合别人

引用 1 楼 derekrose 的回复: Distributed Systems: Concepts and Design, 5th Edition 这本书您读过没，我看到豆瓣上评价不好。。。。


Question: C语言传字符数组，求解

为什么不用参数传递整个互联网内容呢？ 矫枉必须过正！

数组退化成指针了。

为什么会退化成指针，C++ 也是这样的吗？

引用 4 楼 u013470052 的回复:数组名作为函数形参的时候会退化为指针！就是这个原因。 void test(char array[])跟void test(char * array)是完全等价的 而任何指针都是一个十六进制的无符号长整型数，所以任何指针的长度都是4.所以你求得肯定是4. 你可以把char 换成其他类型，比如说int 或者double试试，肯定都是4.

数组名作为函数形参的时候会退化为指针！就是这个原因。

数组在作为函数参数的时候，和指针的效果是一样的！所以最好把长度也得传进来作为参数的！

数组除了在初始化之外，不能整体操作，当然也不能整个复制到函数中 函数传递时，传递的是指向数组首元素的指针 顺便说一句，[]是指针的操作符，数组使用[]也是通过隐式转化为指针才能使用

谢谢大家

因为在test中，array看上去虽然是数组，其实就是指针


Question: 请教未来的学习指导

引用 1 楼 zhuobattle 的回复: 引用 4 楼 max_min_ 的回复: 引用 2 楼 xihu1364 的回复: 引用 6 楼 zhao4zhong1 的回复: 谢谢

作为学生  已经很厉害了

1 如果条件好的话，建议考研吧 2 c/c++的成熟期本来就是比java要长很多，c++是最复杂的语言了，没有之一的 3 静下心，沉住气，打算学了，就好好学！   后期可以看看Effective c++ , more effective c++ ,深入探讨c++对象模型这些，深入学习下   C++的一些机制。后面再看看重构，代码大全这些！

顶！！！

考研吧...

1.你情况适合考研，因为你出去工作可能竞争力不够 2.打好基础才是王道，做项目也是从基础开始的，做项目过程中要总结，不断提高 3.找家还算可以的公司实习下

下载研究eMule源代码。


Question: 关于变长数组 c中为何不能定义成全局变量？

引用 5 楼 zhao4zhong1 的回复:个人意见： malloc realloc free 这才叫变长数组。 那个是动态数组。具体看这里http://baike.baidu.com/link?url=bRob39mFcApY27G3sPW-cB43LQ8YSQSRjzs67i6TACCR4RIOIwXb3sBcgRGi7Kx9sPGL7wX0T4hQIZEju9g4k_

什么叫变长数组

const int maxn=10; int f[maxn];  这不是变长数组啊，在常量折叠的情况下，不就相当于  #define maxn 10 int f[maxn];

C99定义的这种变长数组的使用是有限制的，不能像在C++等语言中一样自由使用 变长数组有以下限制： 1、变长数组必须在程序块的范围内定义，不能在文件范围内定义变长数组； 2、变长数组不能用static或者extern修饰； 3、变长数组不能作为结构体或者联合的成员，只能以独立的数组形式存在； 4、变长数组的作用域为块的范围，对应地，变长数组的生存时间为当函数执行流退出变长数组所在块的时  你是放在文件块范围内定义了，放到函数内部定义就可以了。

请问C语言为什么叫C语言？

引用 5 楼 zhao4zhong1 的回复:个人意见： malloc realloc free 这才叫变长数组。 +1

因为const的语义在C和C++里不完全一样

第一个问题: c/c++中全局变量的存储空间是编译器分配的, 不是在运行期分配的, 大小必须在编译期能确定, 因此变长数组不能是全局变量. 2楼说的几种情况都同理.  第二个问题: const在c++里是常量, 在c里是只读变量. 因此这个定义在c++里是固定长度的全局数组变量, 是允许的; 在c里是变长数组, 是不允许的.

void test(n) {   int a[n]; } 他其实想说的是这类变长数组，提醒别用vs编译器去编译哦，

个人意见： malloc realloc free 这才叫变长数组。


Question: c 打开一个地址获取数据

能举个例子不

不行！fopen需要本地的文件！需要建立连接的，具体的参考socket吧！

各位能举个简单的例子吗

libcurl

windows平台可以看下Winhttp库，里面包含了get,post等等功能的函数

建立短连接，直接发送http请求获取就行。看下socket通信资料。

引用 1 楼 mujiok2003 的回复:使用http库  请问怎么用，我想打开一个地址，然后接收返回的数据。。。

使用http库

wininet libcurl

参考 MSDN98\SAMPLES\VC98\MFC\INTERNET\STOCKTICKER\STOCKQUOTES\*.* MSDN98\SAMPLES\VC98\MFC\INTERNET\TEAR\*.* ？

参考 MSDN98\SAMPLES\VC98\MFC\INTERNET\STOCKTICKER\STOCKQUOTES\*.* MSDN98\SAMPLES\VC98\MFC\INTERNET\TEAR\*.*？ ？

求举个简单的例子，我打开一个网址，接收返回的字符窜就好了


Question: 为什么这段代码一运行就.exe停止工作？？

很简单，因为char *s1="abc",*s2="123";这样写是不真确的写法 "abc"是常量字符串，保存在只读的内存块里。应该养成这样写的习惯： const char* s1="abc";  char s1[] = "abc"; //这样就OK，是用常量字符串"abc"初始化局部变量字符数组s1

因为char1和char2都指向了常量区，内存的内容应该不能变的吧？

和传的值得地址有关

#include <stdio.h> void swap(char *x,char *y) {     char *t;     t=x;x=y;y=t;    printf("%s,%s\n",s1,s2); }   int main(void) {     char *s1="abc",*s2="123";     swap(s1,s2);      }

http://bbs.csdn.net/topics/350206749 函数传递大总结。什么时候交换成功，什么时候交换不成功，lz参考下吧

引用 18 楼 zeuong 的回复:因为你S1和S2都是指向一个字符串常量，怎么可能调换他们头字母，改成数组就行了 谢谢，，我居然发现这试卷里面的Bug了！

引用 31 楼 u013529401 的回复:[quote=引用 16 楼 zeuong 的回复:] void swap(char* x, char* y) { 	char temp; 	temp = *x; 	*x = *y; 	*y = temp; }  int main() { 	char s1[20] = "abc"; 	char s2[20] = "123"; 	swap(s1,s2); 	printf("%s,%s\n",s1,s2); 	getchar(); 	return 1; }对的，但是为什么要改掉成char s1[20] = "abc"; 	char s2[20] = "123";[/quote]  这样就不会抛出异常了，具体参考10楼的解释。

引用 28 楼 u013529401 的回复:[quote=引用 27 楼 huoqingna2332 的回复:] [quote=引用 26 楼 YTerrenceLau 的回复:] 楼主的需求，16楼不就是答案么。  要1bc,a23 ， 16楼的就是[/quote]你的是对的，但是为什么要把指针改成形式改成数组形式啊？[/quote]  这个是为了告诉你，你开始的代码异常的错误，参考我10楼的解释。

引用 16 楼 zeuong 的回复:void swap(char* x, char* y) { 	char temp; 	temp = *x; 	*x = *y; 	*y = temp; }  int main() { 	char s1[20] = "abc"; 	char s2[20] = "123"; 	swap(s1,s2); 	printf("%s,%s\n",s1,s2); 	getchar(); 	return 1; }对的，但是为什么要改掉成char s1[20] = "abc"; 	char s2[20] = "123";

引用 27 楼 huoqingna2332 的回复:[quote=引用 26 楼 YTerrenceLau 的回复:] 楼主的需求，16楼不就是答案么。  要1bc,a23 ， 16楼的就是[/quote] 那么就要定义把字符串存在栈或上堆上，不要放在全局静态数据区。

引用 27 楼 huoqingna2332 的回复:[quote=引用 26 楼 YTerrenceLau 的回复:] 楼主的需求，16楼不就是答案么。  要1bc,a23 ， 16楼的就是[/quote]说错了，以为你是16L了

引用 27 楼 huoqingna2332 的回复:[quote=引用 26 楼 YTerrenceLau 的回复:] 楼主的需求，16楼不就是答案么。  要1bc,a23 ， 16楼的就是[/quote]你的是对的，但是为什么要把指针改成形式改成数组形式啊？

引用 26 楼 YTerrenceLau 的回复:楼主的需求，16楼不就是答案么。  要1bc,a23 ， 16楼的就是

楼主的需求，16楼不就是答案么。

引用 19 楼 huoqingna2332 的回复:void swap(char **x,char **y) { 	char *temp = NULL; 	temp=*x; 	*x=*y; 	*y=temp; }  main() { char str1[]="abc";  char str2[]="123";  char *p1=str1;  char *p2=str2;  printf("%s\n",p1);  printf("%s\n",p2); swap(&p1,&p2);  printf("%s\n",p1);  printf("%s\n",p2); }谢谢啊，可是怎么才能让他输出1bc,a23啊，这答案就是这个

引用 20 楼 user-7 的回复:这样 void swap(char *x,char *y) { 	char *t; 	t=x;x=y;y=t; }  void test2(void) { 	char *s1="abc",*s2="123"; 	swap(s1,s2); 	printf("%s,%s\n",s1,s2); }结果不是1bc,a23啊？

，还有交换字符这种需求，服了。匿了，貌似楼上有人给出答案了。

引用 12 楼 yfl819586803 的回复: #include<stdio.h> void swap(char **x,char **y) {     char *t;     t=*x;*x=*y;*y=t; }    main() {     char *s1="abc",*s2="123";     swap(&s1,&s2);     printf("%s,%s\n",s1,s2); } 这个虽然可以执行，但是与原题不符啊，这题输出结果答案是1bc,a23,而且他给的代码就是开始那段，是不是哪弄错了？ 谢谢各位回答~

vc6.0 测试通过，


Question: MSP430F247串口发送问题，求高手帮忙看一下，谢谢，实在是弄不出来了~

while (!(IFG2&UCA0TXIFG)); UCA0TXBUF = 0xab;  改成  while (!(IFG2&UCA0TXIFG)) UCA0TXBUF = 0xab;  试试。

我怀疑你的程序没有执行到while（1）一直发送的地方，那个循环是发送0xab的，是不是程序卡在哪里了？比如do...while循环那里。

参考http://blog.csdn.net/lyj636588/article/details/9626517  引用 楼主 u013447015 的回复:我的程序是这样的： #include  void delay_us(int n) { for(int i=0; i<n; i++) for(int j=0; j<8; j++); } void UartInit() {  UCA0CTL1 |= UCSWRST; P3SEL |= 0x30; // P3.4,5 = USART0 TXD/RXD UCA0CTL1 |= UCSSEL1; //8Mhz, 115200 UCA0CTL0 = 0; // UCA0CTL0 &= ~UC7BIT; //no parity, 8-bit data, uart mode UCA0BR0 = 69;  UCA0BR1 = 0;  UCA0MCTL |= UCBRS2;  UCA0CTL1 &= ~UCSWRST;  IE2 |= UCA0RXIE; // Enable USCI_A0 RX interrupt }  int main( void ) { volatile unsigned int i; // Stop watchdog timer to prevent time out reset WDTCTL = WDTPW + WDTHOLD; //clock set BCSCTL1 &= ~XT2OFF; // XT2on BCSCTL2 |= SELM1 + SELS + DCOR; do { IFG1 &= ~OFIFG; // Clear OSCFault flag delay_us(50); }while((IFG1 & OFIFG));  // BCSCTL3 |= XT2S1;  //uart init UartInit(); //spi init // SpiInit(); _BIS_SR(LPM0_bits + GIE); // Enter LPM0 w/ interrupt  while(1) { while (!(IFG2&UCA0TXIFG)); UCA0TXBUF = 0xab; } }  #pragma vector=USCIAB0RX_VECTOR __interrupt void USCI0RX_ISR(void) { while (!(IFG2&UCA0TXIFG)); // USCI_A0 TX buffer ready? UCA0TXBUF = UCA0RXBUF; // TX -> RXed character }  实在是弄不明白为什么每次启动单片机就发送了个0xE0然后就没了，但是我的while里面是一直发送的啊，而中断程序里的发送是正常的，也就是当pc给单片机发送的时候单片机将收到的字节发送回来是可以的，怎么调都是这样的，求大神指点一二，谢谢了~

发到 http://bbs.21ic.com/iclist-124-1.html 吧,那上面讨论这个的比较多。


Question: 全排列和子集

引用 4 楼 zhao4zhong1 的回复:仅供参考//qplw.cpp #include <stdio.h> #include <string.h> #include <stdlib.h> int v=0; int w=0; int m;//记录字符串长度 int n;//记录字符串中的字符种类数 char map[256];//记录是哪几种字符 int count[256];//记录每种字符有多少个 int stack[1000];//递归用的栈，并记录当前生成的排列 void Make_Map(char *str) {//统计字符串的相关信息     int s[256];     int i;     memset(s,0,sizeof(s));     memset(count,0,sizeof(count));     m=strlen(str);     if (w<1 || m<w) w=m;     while(*str) {         s[*str]++;         str++;     }     n=0;     for (i=0;i<256;i++)         if (s[i]) {             map[n]=i;             count[n]=s[i];             n++;         } } void Find(int depth) {//递归式回溯法生成全排列     if (depth==w) {         int i;         for (i=0;i<depth;i++) putchar(map[stack[i]]);         putchar('\n');     } else {         int i;         if (v && depth>0) {             for (i=0;i<depth;i++) putchar(map[stack[i]]);             putchar('\n');         }         for (i=0;i<n;i++)             if (count[i]) {                 stack[depth]=i;                 count[i]--;                 Find(depth+1);                 count[i]++;             }     } } void main(int argc,char**argv) {     if (argc<2) {         printf("%s 要产生全排列的字符串 [限定长度|-1]\n",argv[0]);         return;     }     if (argc>=3) w=atoi(argv[2]);     if (-1==w) v=1;     Make_Map(argv[1]);     Find(0); } //C:\test>qplw //qplw 要产生全排列的字符串 [限定长度|-1] // //C:\test>qplw 123 //123 //132 //213 //231 //312 //321 // //C:\test>qplw 123 2 //12 //13 //21 //23 //31 //32 // //C:\test>qplw 122333 3 //122 //123 //132 //133 //212 //213 //221 //223 //231 //232 //233 //312 //313 //321 //322 //323 //331 //332 //333 // //C:\test>qplw 123 -1 //1 //12 //123 //13 //132 //2 //21 //213 //23 //231 //3 //31 //312 //32 //321 //  C:\test>qplw 123456789 5 12345 12346 12347 12348 12349 12354 12356 12357 12358 12359 12364 12365 12367 12368 12369 12374 12375 12376 12378 12379 12384 12385 12386 12387 12389 12394 12395 12396 12397 12398 …… 98675 98712 98713 98714 98715 98716 98721 98723 98724 98725 98726 98731 98732 98734 98735 98736 98741 98742 98743 98745 98746 98751 98752 98753 98754 98756 98761 98762 98763 98764 98765 共15120行

引用 7 楼 u011547107 的回复:to 5楼 && ６楼，谢谢你们！嗯，是的，简单来说，就是 从1-9这 ９个数中找出５个数的所有组合，并且这五个数是互不相同的。  洗牌算法

指的是输出所有可能？

我不理解你的意思？9个数随机选择5个，如何不漏掉每种情况？是指要列出从9个数中选5个的所有组合吗？ 引用 3 楼 u011547107 的回复:@2楼，感谢你的回答！我想我应该是没有把意思说明白，要进行全排列的5个数是从1-9中随机选的。之前我自己已经写出来了全排列的程序，我的问题是如何从里面选择5个数，而且保证不会漏掉每种情况。

#include <stdio.h>  int n = 0;  void swap(int *a, int *b) {     int m;     m = *a;     *a = *b;     *b = m; } void perm(int list[], int k, int m) {     int i;     if(k > m)     {         for(i = 0; i <= m; i++)             printf("%d ", list[i]);         printf("\n");         n++;     }     else     {         for(i = k; i <= m; i++)         {             swap(&list[k], &list[i]);             perm(list, k + 1, m);             swap(&list[k], &list[i]);         }     } } int main() {     int list[] = {1, 2, 3, 4, 5};     setvbuf(stdout, NULL, _IONBF, 0);     perm(list, 0, 4);     printf("total:%d\n", n);     return 0; }

1. 从9个数中选5个，编写一个全部情况的获取程序。 2. 5个数全排列，找个算法。


奇怪， eLIBs_printf 在其它界面的输出信息是正确的.  个人认为：是不是嵌入式小系统 堆或栈方面分配内存有问题.

*nNandFileCount = pScanInfo->CurCnt;  eLIBs_printf("..%s..%d...pScanInfo->CurCnt=%d...path = %s;...path = %s;...path = %s;\n\n", __FILE__, __LINE__,  pScanInfo->CurCnt, pScanInfo->last_file_path1, pScanInfo->last_file_path2, pScanInfo->last_file_path3); //pScanInfo->last_file_path1, pScanInfo->last_file_path2, pScanInfo->last_file_path3 内容显示正常   上面的注释里，你声称程序到这里为止一直是正常的，那么后面如果出现不正常，妥妥是因为eLIBs_printf的问题，除非你上面的注释里是胡扯的。

引用 1 楼 user-1 的回复:有时是啥时候呢？ 难道是当且仅当CurCnt >= 3的时候？ 不正常又是怎么个不正常，正常又是怎么个正常呢？  有时能正确的显示出内容, 有时显示出来的是乱。 这是什么原因呢?

eLIBs_printf 是小系统的自带的函数.  第一次显示正常，后来大多数不正常(有时是正常的).

eLIBs_printf 还有这东西是不是有问题，因为照你的说法，乱之前最近的那一次正常，就发生在这个函数里，而这个函数和后面发生乱码的情况之间根本就没隔其他语句，那唯一可能出问题的地方就妥妥是它了，何况这东西明显不是系统函数，是你们自己写的，出错也很正常~

引用 2 楼 huabinsir 的回复:[quote=引用 1 楼 user-1 的回复:] 有时是啥时候呢？ 难道是当且仅当CurCnt >= 3的时候？ 不正常又是怎么个不正常，正常又是怎么个正常呢？  有时能正确的显示出内容, 有时显示出来的是乱。 这是什么原因呢?[/quote] 怎么个乱发，举个例子嘛，是部分乱，还是全部乱~


Question: 关于c语言我有话说

引用 21 楼 zhao4zhong1 的回复:[quote=引用 18 楼 u013545389 的回复:] 话说C的整型数组最大可以定义多少啊？   比如int a[10000],此时好像就不行了 在占用内存空间较大的局部数组声明的前面加static将其从堆栈数据段挪到全局数据段即可避开因局部数组大小超过默认堆栈大小1MB造成程序不能正常运行的问题。 [/quote]  多谢指教，，，const  好像也行吧

引用 18 楼 u013545389 的回复:话说C的整型数组最大可以定义多少啊？   比如int a[10000],此时好像就不行了 在占用内存空间较大的局部数组声明的前面加static将其从堆栈数据段挪到全局数据段即可避开因局部数组大小超过默认堆栈大小1MB造成程序不能正常运行的问题。

看看 Learn C The Hard Way http://c.learncodethehardway.org/book/

下载一个C语言的手机开源项目，然后读懂它。

曾经有本C语言的书，最后面带了五笔教程的。然后呢，C语言有没学会不清楚，五笔是学会了。吼吼。

引用 8 楼 wIloverYou123456789 的回复:看大家的回复貌似不太热烈， 我就在加 60 分，希望大家踊跃发言 给出中肯的意见和建议！  看来大家的回复 有的说 看 The C Programming Language  有的是让下载看 “入门圣经”  还有的说 Win-TC   我说一下现在的情况吧，目前做手机开发 android 你们懂得 应用方面做了一些时间了，现在想往framework层努力，但是 framework中jni有些东西是c的东西，所以鉴于此想补习c，希望大家能从一个白痴的人学习c 这个角度看就行了，这样给出的学习思路应该是适合我的！ 我觉得楼主不妨看看郝斌老师的C语言视频，它将的浅显易懂，而且也很好，你可以边看视频边照着他说的敲代码

手机，不是都在用安卓系统吗？不是Java开发吗？C的话，初学建议《C Primer Plus（第五版）中文版》，这本书带有练习题的，如果有基础，只是想复习一下，快速浏览一遍，做几道题就可以了。 引用 楼主 wIloverYou123456789 的回复:因为做手机开发现在想补习一下c语言，求大神知道学习路线！做好是务实的路线不要是纯理论，希望能一边看书一边又能写代码实践的

<<The C Programming Language>>

我只是新手学习来着

首先你需要下载android的源码和一台配套的手机 然后你需要在linux上编译过源码再烧到手机看看 如果没问题 之后你就可以选择一个自己喜欢的模块来研究framework层的代码 framework层貌似大部分是C++的代码 你需要懂得一些C++的技巧和设计模式 你还需要了解一些硬件的知识 这样你研究android的源码会事半功倍 再然后你就可以自己修改源码  编译 再烧机实践就可以了 具体的学习方法以及看什么书可以问搜索引擎

引用 7 楼 supermegaboy 的回复:[quote=引用 5 楼 zhao4zhong1 的回复:] 先下载Win-TC，然后参考C:\Win-TC\tcstudy.chm  唉，你看看六楼，都是你造的孽啊。[/quote] 哈！身后留下点“残渣余孽”总好过“雁过不留痕”吧。

我觉着，要是深入学c的话可以看下c primer plus 这本书个人感觉还是很好的

引用 8 楼 wIloverYou123456789 的回复:看大家的回复貌似不太热烈， 我就在加 60 分，希望大家踊跃发言 给出中肯的意见和建议！  看来大家的回复 有的说 看 The C Programming Language  有的是让下载看 “入门圣经”  还有的说 Win-TC   我说一下现在的情况吧，目前做手机开发 android 你们懂得 应用方面做了一些时间了，现在想往framework层努力，但是 framework中jni有些东西是c的东西，所以鉴于此想补习c，希望大家能从一个白痴的人学习c 这个角度看就行了，这样给出的学习思路应该是适合我的！ 作为有编程经验的人，你只需要了解C和Java的区别就可以了。

引用 5 楼 zhao4zhong1 的回复:先下载Win-TC，然后参考C:\Win-TC\tcstudy.chm  唉，你看看六楼，都是你造的孽啊。

VC调试时按Alt+8、Alt+7、Alt+6和Alt+5,打开汇编窗口、堆栈窗口、内存窗口和寄存器窗口看每句C对应的汇编、单步执行并观察相应堆栈、内存和 寄存器变化，这样过一遍不就啥都明白了吗。 对VC来说，所谓‘调试时’就是编译连接通过以后，按F10或F11键单步执行一步以后的时候，或者在某行按F9设了断点后按F5执行停在该断点处的时 候。  不要迷信书、考题、老师、回帖； 要迷信CPU、编译器、调试器、运行结果。 并请结合“盲人摸太阳”和“驾船出海时一定只带一个指南针。”加以理解。 任何理论、权威、传说、真理、标准、解释、想象、知识……都比不上摆在眼前的事实！

先下载Win-TC，然后参考C:\Win-TC\tcstudy.chm

http://download.csdn.net/detail/max_min_/6333711 上面的例程，都敲敲，入门应该没问题了

上机操作，操作再操作！相当务实！


Question: whlid 循环不起作用？

谢谢！  给出我最新的实现，提供后来者参考 int main(int argc , char *argv[]) {     pthread_t thr[10];     for(int i=0;i<10;i++)     {          pthread_create(&thr[i],NULL,threadhander,(void *)i);      }     for(int i=0;i<10;i++)     {          pthread_join(thr[i], NULL);/*等待进程t_b结束*/     }   	return 0; }  void *threadhander(void * fid) {     while(1)     {        // toserver((int )fid);         pthread_t t1;         t1=pthread_self();          printf("fid=%d,threadid=%u\r\n",(int)fid,(int)t1);         sleep(1);     }     return 0; }

引用 5 楼 xihu1364 的回复:main 中的 return 0 上一句 加一个 while（1）｛｝  或者加上 system("pause");

main 中的 return 0 上一句 加一个 while（1）｛｝

请问xihu1364，truelance 两大哥，如何改进呢？

主线程结束了, 所有的子线程都会被干掉.

main(int argc , char *argv[]) 父进程 结束了...   还有传参 是传的 局部变量pthread_create(&thr,NULL,threadhander,(void *)i);

void *threadhander(void * fid)   的return 0应该去删了吧;


Question: 为什么这个局部指针变量还可返回？

地址可以传出来，但是栈上变量被回收了，这块地址就可能被再利用，地址中的值也就不确定了

引用 5 楼 zmlovelx 的回复:说俗点吧： A上了次厕所， 过一会C进去了，这个时候可能A的那陀还在，也有可能已经被清洁工人清洁掉了。人才啊

引用 楼主 u011323280 的回复:#include<stdio.h> #include<stdlib.h> int* S(int *a) { 	int *p,b; 	p=&b; 	*p=5;  	return p; }  int main(void) { 	int p[1],*a=p; 	p[0]=3; 	a=S(a); 	printf("%d",*a);//输出5 	return 0;  }  p和b都是子函数里面定义的局部变量啊，但是函数还是可以输出5，这不是表明p可以复制给主函数里面的a嘛  大家说得已经很到位了，能得到你想要的结果，只能说是侥幸，如果结果不对，你也没办法。 这就是所谓的未定义行为。  不能保证结果的程序，你敢用吗？

引用 5 楼 zmlovelx 的回复:说俗点吧： A上了次厕所， 过一会C进去了，这个时候可能A的那陀还在，也有可能已经被清洁工人清洁掉了。  你能说的不这么恶心么？

虽然能正常运行也不能这样写，就跟你new了一块内存，存入数据但是当你delete后通常还是能访问的，但是这个时候的指针是悬垂的，他的值可以是随机的，因为他所指向的内存空间可以被其他程序重新使用，所以，其他程序如果更改了这个地址中的值的话就会出错。但是咱们的计算机任务量太小了，那块内存可能很长时间用不着所以才会出现 假正确的现象。

首先你应该理解返回值的内容，然后再理解这个指针所指向的内容。 不过我觉的实际使用的时候楼主应该不会这么写这么无稽的代码

五楼是语言大师啊。

引用 5 楼 zmlovelx 的回复:说俗点吧： A上了次厕所， 过一会C进去了，这个时候可能A的那陀还在，也有可能已经被清洁工人清洁掉了。 高手

说俗点吧： A上了次厕所， 过一会C进去了，这个时候可能A的那陀还在，也有可能已经被清洁工人清洁掉了。   真生动的例子。。牛逼。。。

可以 ! = 正确

其实你逐步调试一下，跟踪一下就知道问题是出在哪里了

引用 5 楼 zmlovelx 的回复:说俗点吧： A上了次厕所， 过一会C进去了，这个时候可能A的那陀还在，也有可能已经被清洁工人清洁掉了。+1

引用 楼主 u011323280 的回复:#include<stdio.h> #include<stdlib.h> int* S(int *a) { 	int *p,b; 	p=&b; 	*p=5;  	return p; }  int main(void) { 	int p[1],*a=p; 	p[0]=3; 	a=S(a); 	printf("%d",*a);//输出5 	return 0;  }  p和b都是子函数里面定义的局部变量啊，但是函数还是可以输出5，这不是表明p可以复制给主函数里面的a嘛 这么说吧，p中存放的地址是子函数的局部变量b的，在子函数调用完的时候这个地址就被释放了，释放的意思是告诉计算机可以使用这块内存了，这块内存程序不在占有，然后你再主函数中调用的时候这个地址的值并没有被修改，所以调用的时候可以输出子函数中b的值，但是这个地址的值还有可能会被别的因素修改。属于非法访问内存，是未定义的行为。

引用 5 楼 zmlovelx 的回复:说俗点吧： A上了次厕所， 过一会C进去了，这个时候可能A的那陀还在，也有可能已经被清洁工人清洁掉了。 这比喻亮了.

引用 5 楼 zmlovelx 的回复:说俗点吧： A上了次厕所， 过一会C进去了，这个时候可能A的那陀还在，也有可能已经被清洁工人清洁掉了。 生动啊

你是在质疑规则

系统没有必要把你用过的地址对应的内容特意去擦除（你这里用的是stack上的空间） 可能会在下个函数中使用时被覆写。


Question: 二叉树问题  望高手 解惑！！！

Segmentation fault is a specific kind of error caused by accessing memory that “does not belong to you.” It’s a helper mechanism that keeps you from corrupting the memory and introducing hard-to-debug memory bugs. Whenever you get a segfault you know you are doing something wrong with memory – accessing variable that has already been freed, writing to a read-only portion of the memory, etc. Segmentation fault is essentially the same in most languages that let you mess with the memory management, there is no principial difference between segfaults in C and C++.

tree inittree(tree t,int n) { //	static int num=0; if(n>=20){    puts("bianjiedaole");	 return; }  t = (struct node *)malloc(sizeof(struct node)); t->r=t->l=NULL; if(t!=NULL) { t->data = n; //	 printf("%d \n",t->data); //	 num++; inittree(t->l,2*n+1); puts("lllll"); inittree(t->r,2*n+2); puts("rrrrr"); } }  创建函数有问题啊。参数传的是指针的值，但是你又需要修改指针的值，所以你需要传指针的指针进去。


Question: 缓存代码问题

这种替换，比较偏门，一般只有某些库代码会这么做。  正常的程序编写中，多半不会使用这样的代码。

预编译的宏替换规则，不是这么做的。 你需要符号替换才行，需要用到 ##这个符号。 看看MFC的那些宏，是如何实现的，你就明白该怎么做了。 你这个替换，达不到你的目的。 单纯的宏替换，只是字符串的直接替换，不能做符号替换，除非使用 ##这个符号连接符。  也就是说： Cache(fib2) 被替换成 name_cache，而不是 fib2_cache CacheProc(fib2) 被替换成name_patch，而不是 fib2_patch  改成这样就可以了： #define PasteSym(x,y)     x##y #define  Cache(name)  PasteSym(name,_cache) #define  CacheProc(name)  PasteSym(name,_patch)  这样就会有如下替换效果： Cache(fib2) ---> fib2_cache CacheProc(fib2) ---> fib2_patch

麻烦哪位能回答下红字的问题啊。

name_path 在下面代码中没找到，所以他如何被替换呢？

引用 2 楼 robin622 的回复:name_path 在下面代码中没找到，所以他如何被替换呢？ 干么要找到呢?  替换就是

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

#define就是简单的替换而已


Question: dlopen函数是否检查so文件的合法性

看看用myhandle的地方吧

只是open，应该不会有问题  看看其他的地方吧 32bit AIX程序可以malloc的内存上限默认为256M

没人回啊！！


Question: ACM 病狗问题 有兴趣的朋友看下

引用 10 楼 lm_whales 的回复:[quote=引用 9 楼 FancyMouse 的回复:] [quote=引用 8 楼 lm_whales 的回复:]  不过，还是感觉，第一天就可以判断出，自己家的狗是否病狗。  因为如果看到所有的狗，那么只能看出 n-1 只是否病狗 ，自己的看不出来， 那么假设自己家的，不是病狗则可以看到 K 只病狗。 否则，假设自己家的是病狗，看到 K-1 只病狗。 那么自家的一定是病狗，因为只有自家的看不错来。  所以这里面应该还有条件，比如每次最多，只能看 n-k只狗。 你是不知道别人家看到了几只病狗的。所以你看到一个值，你不知道它是k-1还是k。[/quote] ++ 那就是还有一个条件，K是不知道的，只知道至少有一只病狗，只是第K天有人杀狗，大家都知道几只了 是这样么。 谢谢。 [/quote] k要是知道了这题还有啥出的价值？  >只是第K天有人杀狗，大家都知道几只了 这个不是条件。这个是你知道其他村民都足够聪明的时候他们能推导出的策略。

两个，不太容易看出来的，隐含条件  1）村民，不知道,有几条狗是病狗，只知道有病狗（1～n 只病狗） 2）村民，每天判断一轮。  其他隐含条件  3) n>= 病狗数 >=1 4) n>= k >=  1 如果给出村民户数的话，需要判断 K是否是合法的数据， 最好 n 也要判断一下，这样才能保证，程序的健壮性（鲁棒性）robustness  即使直接输出 也需要判断n,k 是否符合以下条件 a）n>= 1               至少有1户村民，养了一只狗  b) n >= K && K>= 1     杀狗的天数 = 病狗数量 = 被杀的狗的数量= K =1～n

谢谢 FancyMouse  终于理解了： K只病狗，是每个户村民不知道的，只是第K天有人杀狗，大家都知道是K只了 这样： 其中一条推论是， 每户村民，要么看到K 只病狗，要么看到K-1 只病狗  家有病狗和没有病狗的在K-1 轮的时候，都不会杀狗  因为看到K只病狗的，可以判断出要么K+1只病狗，要么K只病狗 如果是 K 只的话，自家的不是病狗，不用杀狗 如果是 K+1只，自家的是病狗，才会在第K+1天杀狗  而看到K-1 只的，看到K-1天，没有人杀狗，第K天，则会认定自家的狗是病狗 逻辑和看到K只的相同。 ================================  谢谢 FancyMouse

引用 9 楼 FancyMouse 的回复:[quote=引用 8 楼 lm_whales 的回复:]  不过，还是感觉，第一天就可以判断出，自己家的狗是否病狗。  因为如果看到所有的狗，那么只能看出 n-1 只是否病狗 ，自己的看不出来， 那么假设自己家的，不是病狗则可以看到 K 只病狗。 否则，假设自己家的是病狗，看到 K-1 只病狗。 那么自家的一定是病狗，因为只有自家的看不错来。  所以这里面应该还有条件，比如每次最多，只能看 n-k只狗。 你是不知道别人家看到了几只病狗的。所以你看到一个值，你不知道它是k-1还是k。[/quote] ++ 那就是还有一个条件，K是不知道的，只知道至少有一只病狗，只是第K天有人杀狗，大家都知道几只了 是这样么。 谢谢。

引用 13 楼 FancyMouse 的回复:[quote=引用 10 楼 lm_whales 的回复:]   [quote=引用 9 楼 FancyMouse 的回复:] [quote=引用 8 楼 lm_whales 的回复:]  不过，还是感觉，第一天就可以判断出，自己家的狗是否病狗。  因为如果看到所有的狗，那么只能看出 n-1 只是否病狗 ，自己的看不出来， 那么假设自己家的，不是病狗则可以看到 K 只病狗。 否则，假设自己家的是病狗，看到 K-1 只病狗。 那么自家的一定是病狗，因为只有自家的看不错来。  所以这里面应该还有条件，比如每次最多，只能看 n-k只狗。 你是不知道别人家看到了几只病狗的。所以你看到一个值，你不知道它是k-1还是k。[/quote] ++ 那就是还有一个条件，K是不知道的，只知道至少有一只病狗，只是第K天有人杀狗，大家都知道几只了 是这样么。 谢谢。 [/quote] k要是知道了这题还有啥出的价值？  >只是第K天有人杀狗，大家都知道几只了 这个不是条件。这个是你知道其他村民都足够聪明的时候他们能推导出的策略。[/quote] 知道了  嗯，因为，这个几乎是理所当然的原因，所以题目里，没有作为条件列出 但是推理的时候，要用到他，所以他也是隐含的条件。

引用 8 楼 lm_whales 的回复:不过，还是感觉，第一天就可以判断出，自己家的狗是否病狗。  因为如果看到所有的狗，那么只能看出 n-1 只是否病狗 ，自己的看不出来， 那么假设自己家的，不是病狗则可以看到 K 只病狗。 否则，假设自己家的是病狗，看到 K-1 只病狗。 那么自家的一定是病狗，因为只有自家的看不错来。  所以这里面应该还有条件，比如每次最多，只能看 n-k只狗。 你是不知道别人家看到了几只病狗的。所以你看到一个值，你不知道它是k-1还是k。

引用 3 楼 lm_whales 的回复:这是应该用prolog 语言，这样才能够让程序去推理。 用C++，直接实现一个，推理系统有点难度。 没有推理过程，这个程序也没有用处，虽然可能是正确的。 求个prolog代码。我看了半天也没想出来怎么用prolog写这玩意

看懂一点： 这里有个隐含条件，没有给出。 1）即村民全体，每天做一次判断，不多也不少。 其他逻辑是 2）每家村民一只狗 3）狗狗有两种状态，       3.1）病了，3.2）没病 4）村民对自己的狗，可以采取两种措施        4.1）杀，4.2）不杀， 5）村民一天只做一次判断，并杀掉自家的病狗。  6）村民在同一天杀狗的讯息，不会传到其他村民家中，只有第二天才会知道，         6.1） 上一轮没人杀狗，再次开始判断         6.2） 上一轮有人杀狗，结束判断。  7）村民杀自家的狗的前提是，判断出来自家的狗是病狗。      //伪代码：         //if(dog[peson] == illdog)killdog(dog[person]); 8）村民不能直接判断自家的狗，是否病狗 9）村民可以观察到，别家的村民的家的狗，是否病狗和别家的病狗个数，   从而判断出自家的狗，是病狗，和不确定是病狗的信息。 10）每户村民，可以观察到的病狗数目是        9.1）自己的狗没病结果,是病狗总数        9.2) 自己的狗是病结果,是病狗总数-1 11）村民判断出自家的狗，是病狗的条件是，病狗数比自己观察到的病狗数多1只 12）村民，可以根据上一轮，还没有杀狗的天数。    判断出病狗，是否比观察到的病狗数多一只，从而断定自己家的是病狗。    12.1） 看到所有病狗的村民，不需要在判断了，因为自己家的狗，不是病狗    12.2） 少看到一只病狗的村民，只能根据自己看到的狗数，和判断持续的轮数           判断自己家的狗是否病狗。       13）当有病狗的时候，病狗数>=1 就是#1楼的第一条.并且一定有病狗。 14) 所有村民，的逻辑都没有错误。（每户村民都是极其聪明的） 15）第K天家有病狗的村民(都同时),判断出自己家的狗是病狗，并杀掉.   16）杀狗的天数和病狗的数量相同。（结论1） 17）到杀狗那天结束为止，村里没有病狗了，因为病狗都杀了（结论2，此时判断过程结束） 18）病狗的数量 =K （结论3，最终结论）   这是我对这个题目的总结，可能有些结论是无用的

引用 5 楼 FancyMouse 的回复:[quote=引用 3 楼 lm_whales 的回复:] 这是应该用prolog 语言，这样才能够让程序去推理。 用C++，直接实现一个，推理系统有点难度。 没有推理过程，这个程序也没有用处，虽然可能是正确的。 求个prolog代码。我看了半天也没想出来怎么用prolog写这玩意[/quote] 很遗憾，prolog 看过，不会用，另外对那个分析，我也是没怎么看懂

这是一道逻辑题，通过逻辑推演可以证明，第几天响起枪声，就有几条病狗 代码本身的功能是输入k然后输出k，代码不能用来证明什么，只是你证明之后才能写出代码


Question: doxygen有关宏定义的问题

doxygen配置问题吧

引用 1 楼 user-2 的回复:仔细检查下各个宏定义，不知是你哪个头文件里写了相关宏定义  程序不是自己写的，是公司研发的几个人一起完成的，我现在需要把它做成html，对程序也不是特别了解。但是我试着使用doxygen的时候。做过这个样子的尝试，只打开其中的一个程序。 #if defined  (ABC) #include "aaa.h" #include "bbb.h" #include "ccc.h" #include "ddd.h" /** * 函数功能     : 初始化 * @param [in]  : 无 * @param [out] : 无 * @retval      : OK-成功 * @retval      : ERROR-失败 */ int abcd(void) {     return (abcde()); }     这个是程序的一部分。这样生成出来的html没有东西。但是我把开头的#if defined  (ABC)去掉之后，这样可以生成int abcd (void)的函数，并且可以链接到注释中的文字。     我就在想是不是配置的时候出了什么问题。。

仔细检查下各个宏定义，不知是你哪个头文件里写了相关宏定义


Question: c新手 请帮我看下这个评委打分的程序 哪错了，谢谢

同意上面所说，既然你要初始化三个变量，那为什么不直接用数字初始化呢

最后一个输入数据没加上，如1楼所说，把输入和累加顺序换过来，并且循环外记得sum先把第一个值加上，这样就行了

#include<stdio.h> void main() { float x,max,min,sum=0; int n,i=1; printf("input people number:"); scanf("%d",&n); printf("input score:"); scanf("%f",&x); max=x; min=x; sum = x; while(i<n) {  i++; scanf("%f",&x); sum+=x; if(max<x)max=x;   else if(x<min)min=x;   } sum=sum-max-min; printf("%f\n",sum); }

LZ 的思路有点儿乱，是不是让 max 和 min 必须有初值给闹的。 其实可以有点小技巧处理一下。如果分数的范围是 0~100的话，可以初始化 min = 101; max = -1; 这两个数值显然都是没用的，最终肯定会被正确的值给替换掉的。 对于次数确定的循环，建议无论如何都要使用 for 结构，写的人心里有数，不易错，看的人也容易理解。

逻辑上，应该先 scanf("%f", &x) ，再累加 sum += x。 LZ 把顺序搞反了。循环里最后少累加一次。