Question: fread（）返回值不正确，什么原因？

!feof(fp)这根判断方法是否有问题？

不要使用 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;  //... } 类似的例子还可以举很多。  fread Reads data from a stream.  size_t fread( void *buffer, size_t size, size_t count, FILE *stream );  Function Required Header Compatibility  fread <stdio.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  fread returns the number of full items actually read, which may be less than count if an error occurs or if the end of the file is encountered before reaching count. Use the feof or ferror function to distinguish a read error from an end-of-file condition. If size or count is 0, fread returns 0 and the buffer contents are unchanged.  Parameters  buffer  Storage location for data  size  Item size in bytes  count  Maximum number of items to be read  stream  Pointer to FILE structure  Remarks  The fread function reads up to count items of size bytes from the input stream and stores them in buffer. The file pointer associated with stream (if there is one) is increased by the number of bytes actually read. If the given stream is opened in text mode, carriage return–linefeed pairs are replaced with single linefeed characters. The replacement has no effect on the file pointer or the return value. The file-pointer position is indeterminate if an error occurs. The value of a partially read item cannot be determined.  Example  /* FREAD.C: This program opens a file named FREAD.OUT and  * writes 25 characters to the file. It then tries to open  * FREAD.OUT and read in 25 characters. If the attempt succeeds,  * the program displays the number of actual items read.  */  #include <stdio.h>  void main( void ) {    FILE *stream;    char list[30];    int  i, numread, numwritten;     /* Open file in text mode: */    if( (stream = fopen( "fread.out", "w+t" )) != NULL )    {       for ( i = 0; i < 25; i++ )          list[i] = (char)('z' - i);       /* Write 25 characters to stream */       numwritten = fwrite( list, sizeof( char ), 25, stream );       printf( "Wrote %d items\n", numwritten );       fclose( stream );     }    else       printf( "Problem opening the file\n" );     if( (stream = fopen( "fread.out", "r+t" )) != NULL )    {       /* Attempt to read in 25 characters */       numread = fread( list, sizeof( char ), 25, stream );       printf( "Number of items read = %d\n", numread );       printf( "Contents of buffer = %.25s\n", list );       fclose( stream );    }    else       printf( "File could not be opened\n" ); }   Output  Wrote 25 items Number of items read = 25 Contents of buffer = zyxwvutsrqponmlkjihgfedcb   Stream I/O Routines  See Also   fwrite, _read

fopen中的路径，\要用\\，才行。

引用 3 楼 buyong 的回复:fopen(...,"rb");  rb

fopen(...,"rb");

你只复制了这么多啊


Question: 单片机中有关C语言 定义const常量的问题，请高手帮忙

谢谢大侠，就是这个问题困扰了我，按照你说的办法，解决了。谢谢你。

const uchar * const CD_ab1[ ]; const uchar * const * const WA_MAR[ ]; 单片机没用过，单从语法上讲，指针的值和指针的内容要分别const，一个const不能修饰两个不同的东西


Question: C中同名函数

引用 楼主 luo15979039240 的回复:code1 //test.c #include <stdio.h> #include <stdlib.h>  int main() {  char *buf = NULL;   buf = (char *)malloc(10);  if(NULL == buf)  {   printf("failed.\n");  }  else  {   printf("%p.\n", buf);   free(buf);  }   return 0; }  在linux下编译 gcc test.c -o test ./test 0x12345678//地址乱写的   code2  code1 //test.c #include <stdio.h> #include <stdlib.h>  void *malloc(unsigned long size) {  printf("what a xxoo day.\n");  return NULL; }  int main() {  char *buf = NULL;   buf = (char *)malloc(10);  if(NULL == buf)  {   printf("failed.\n");  }  else  {   printf("%p.\n", buf);   free(buf);  }   return 0; }  在linux下编译 gcc test.c -o test ./test what a xxoo day. failed  问题。像这样存在几个同函数， 1 编译为什么能通过 2 怎么知道系统使用哪个  我在windows下试了，编译不过去

code1中， test.o这个编译单元，找不到符号malloc的定义，所以会在链接时，查找其定义，于是找到了c库中的malloc。 code2中，test.o这个编译单元，找到了符号malloc的定义，所以不会在链接时再去查找其定义，于是使用了本地malloc。 可以用readelf 或者 objdump查看目标文件的符号表，相信会有收获。

代码里的函数优先于库中的函数


Question: fwprintf函数使用问题

mbstowcs Converts a sequence of multibyte characters to a corresponding sequence of wide characters.  size_t mbstowcs( wchar_t *wcstr, const char *mbstr, size_t count );  Routine Required Header Compatibility  mbstowcs <stdlib.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  If mbstowcs successfully converts the source string, it returns the number of converted multibyte characters. If the wcstr argument is NULL, the function returns the required size of the destination string. If mbstowcs encounters an invalid multibyte character, it returns –1. If the return value is count, the wide-character string is not null-terminated.  Parameters  wcstr  The address of a sequence of wide characters  mbstr  The address of a sequence of multibyte characters  count  The number of multibyte characters to convert  Remarks  The mbstowcs function converts count or fewer multibyte characters pointed to by mbstr to a string of corresponding wide characters that are determined by the current locale. It stores the resulting wide-character string at the address represented by wcstr. The result is similiar to a series of calls to mbtowc. If mbstowcs encounters the single-byte null character ('\0') either before or when count occurs, it converts the null character to a wide-character null character (L'\0') and stops. Thus the wide-character string at wcstr is null-terminated only if a null character is encountered during conversion. If the sequences pointed to by wcstr and mbstr overlap, the behavior is undefined.  If the wcstr argument is NULL, mbstowcs returns the required size of the destination string.   Example  /* MBSTOWCS.CPP illustrates the behavior of the mbstowcs function  */  #include <stdlib.h> #include <stdio.h>  void main( void ) {     int i;     char    *pmbnull  = NULL;     char    *pmbhello = (char *)malloc( MB_CUR_MAX );     wchar_t *pwchello = L"Hi";     wchar_t *pwc      = (wchar_t *)malloc( sizeof( wchar_t ));      printf( "Convert to multibyte string:\n" );     i = wcstombs( pmbhello, pwchello, MB_CUR_MAX );     printf( "\tCharacters converted: %u\n", i );     printf( "\tHex value of first" );     printf( " multibyte character: %#.4x\n\n", pmbhello );      printf( "Convert back to wide-character string:\n" );     i = mbstowcs( pwc, pmbhello, MB_CUR_MAX );     printf( "\tCharacters converted: %u\n", i );     printf( "\tHex value of first" );     printf( " wide character: %#.4x\n\n", pwc ); }   Output  Convert to multibyte string:    Characters converted: 1    Hex value of first multibyte character: 0x0e1a  Convert back to wide-character string:    Characters converted: 1    Hex value of first wide character: 0x0e1e   Data Conversion Routines |  Locale Routines |  Interpretation of Multibyte-Character Sequences  See Also   mblen, mbtowc, wcstombs, wctomb, MultiByteToWideChar

先搞清文件和字符串编码方式是否相同？


Question: C中 ReleaseByteArrayElements到底什么意思？起什么作用呢？

决定是否对plbFeaTest释放，为0的时候  plbFeaTest  会被内存释放，你做下实验啊，运行完这个函数 plbFeaTest在delete就会报double free的错了

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

google

有人帮忙吗？

引用 2 楼 zhao4zhong1 的回复:google google上不去，baidui 没有很好的解释。


Question: C语言数据结构基础方面的教材，值得一看。

我有此书，错误多成马了。。。

额，扫描版的？

我干过一本基本的数据结构预算法 不过还是忘记了

《数据结构（C语言描述）》 《算法精解（C语言描述）》

引用 3 楼 Claude_Ray 的回复:看起来还可以，我还是喜欢严奶奶的~~哎，调皮一下~网速实在不给力，没下载好，不能验货…不过这种经典书网上资源蛮多的，楼主推荐的不错，支持~个人建议，发链接不如做个详细的书目推荐，而且还是实体书看着舒服一些

楼主总共发过俩帖子，都是分享教材的，都是119G网的

看起来还可以，我还是喜欢严奶奶的~~

清华大学数据结构C语言第二版

好想可以下载支持一下楼主


Question: 请教关于c的printf函数问题

提醒： “学习用汇编语言写程序” 和 “VC调试(TC或BC用TD调试)时按Alt+8、Alt+7、Alt+6和Alt+5,打开汇编窗口、堆栈窗口、内存窗口和寄存器窗口看每句C对应的汇编、单步执行并观察相应堆栈、内存和寄存器变化，这样过一遍不就啥都明白了吗。 （Linux或Unix下可以在用GDB调试时,看每句C对应的汇编并单步执行观察相应内存和寄存器变化。） 想要从本质上理解C指针，必须学习C和汇编的对应关系。” 不是一回事！

printf的源代码在output.c中。 C:\60G\Microsoft SDK\src\crt\output.c C:\Program Files\Microsoft Platform SDK for Windows Server 2003 R2\src\crt\output.c C:\Program Files\Microsoft Visual Studio\VC98\CRT\SRC\OUTPUT.C C:\Program Files\Microsoft Visual Studio 8\VC\crt\src\output.c C:\Program Files\Microsoft Visual Studio 9.0\VC\crt\src\output.c C:\Program Files\Microsoft Visual Studio 10.0\VC\crt\src\output.c

printf的实现在msvcrt.lib中了

引用 楼主 dasdase 的回复:#include <stdio.h>     main()    {      printf("hello, world\n");    } ----------------------------------------------------分隔线 .const szHello db 'Hello, world!', 0 .code main        proc invoke    printf, offset szHello ret main endp end    main 我是初学者，用msvcrt.lib的printf和这C的PRINTF函数做对比的，程序如上，我想问，为什么汇编的Messagebox源码和C的基本一样，但printf函数的源码就完全不一样呢，难道说C的printf函数不是这个？？，很想知道答案，为什么源码不同？  不了解汇编


Question: 题虽小，不简单，遍历指定库阶乘输出。大家做做看 ^ _ ^

#include <iostream> using namespace std; int main() { 	char a[9]={'a','b','c','1','2','3','!','@','#'}; 	int stack[9]; 	int n,top; 	cin>>n; 	for(int len=1;len<=n;len++) 	{ 		top=0; 		do 		{ 			if(top<len) 				stack[top++]=0; 			else 				stack[top-1]++; 			while(stack[top-1]>=9) 				if(--top>0) stack[top-1]++; 			if(top==len) 			{ 				for(int i=0;i<len;i++) 					printf("%c",a[stack[i]]); 				printf(","); 			} 		}while(top>0); 		printf("\n"); 	} 	system("pause"); }

请简单考虑一下，下面的代码输出什么？ for (int i = 0; i < 100; i++)     printf("%02d\n", i); 是的，它输出10的2次方个数字，这些数字是10进制表示，输出的数字的宽度是2 有没有注意到这些带颜色的数字？它就是我的解决方法的关键。  LZ其实在输出固定宽度的9进制数，只不过不是用012345678来表示digit，而是用abc123!@#来表示digit。  # include <stdio.h> # include <string.h> # include <math.h>  void reverse(char * string) {     int l = strlen(string);     int i;     char tmp;     for (i = 0; i < l / 2; i++)     {         tmp = string[i];         string[i] = string[l - 1 - i];         string[l - 1 - i] = tmp;     } }  char * format_to_base(int n, int base, int width, char a[]) {     static char buffer[100] = "";     int i = 0;     int q, r;     memset(buffer, 0, 100);     do {         q = n / base;         r = n % base;         buffer[i++] = a[r];         n = q;     } while (q != 0);     while (i < width)         buffer[i++] = a[0];     reverse(buffer);     return buffer; }  void output_line(int n) {     char a[] = "abc123!@#";     int max = pow(9, n);     int width = n;     int i;     for (i = 0; i < max; i++)     {         printf("%s", format_to_base(i, 9, width, a));         if (i != max - 1)             putchar(',');     }     putchar('\n'); }  int main() {     int n;     int i;     printf("input n (0 < n < 9): ");     scanf("%d", &n);     for (i = 1; i <= n; i++)         output_line(i);      return 0; }

打算到周五结贴，还有新思路的朋友表吝啬呀，哈哈

引用 17 楼 zhao4zhong1 的回复:15楼似乎借鉴的不对啊。嗯，貌似有些偏

引用 19 楼 zxh707wk 的回复:该算法非递归输出 #include <stdio.h> #include <string.h> #include <malloc.h>  #define str "abc123!@#"  void putstr(int num[],int len) { 	int i; 	for(i=0;i<len;i++) 	{ 		printf("%c",str[num[i]]); 	} }  void fun(int n) { 	int i; 	int len=strlen(str); 	int* num=(int*)malloc(sizeof(int)*n); 	for(i=0;i<n;i++) 	{ 		num[i]=0; 	} 	for(;num[0]<len;) 	{ 		putstr(num,n); 		num[n-1]++; 		for(i=n-1;i>0;i--) 		{ 			if(num[i]>=len) 			{ 				num[i-1]++; 				num[i]=0; 			} 		} 		if(num[0]<len)printf(","); 	} }  int main() { 	int n; 	scanf("%d",&n); 	fun(n); 	return 0; }  http://www.codeproject.com/Articles/418776/How-to-replace-recursive-functions-using-stack-and

理解成一个M进制N位的全部表达。然后不断的++，再打印。

15楼似乎借鉴的不对啊。

赵老师出马，不仅是一个顶两

学到的东西越来越多

链接给出了将任何递归程序改写为非递归实现的方法和步骤。

引用 20 楼 zhao4zhong1 的回复:[quote=引用 19 楼 zxh707wk 的回复:] 该算法非递归输出 #include <stdio.h> #include <string.h> #include <malloc.h>  #define str "abc123!@#"  void putstr(int num[],int len) { 	int i; 	for(i=0;i<len;i++) 	{ 		printf("%c",str[num[i]]); 	} }  void fun(int n) { 	int i; 	int len=strlen(str); 	int* num=(int*)malloc(sizeof(int)*n); 	for(i=0;i<n;i++) 	{ 		num[i]=0; 	} 	for(;num[0]<len;) 	{ 		putstr(num,n); 		num[n-1]++; 		for(i=n-1;i>0;i--) 		{ 			if(num[i]>=len) 			{ 				num[i-1]++; 				num[i]=0; 			} 		} 		if(num[0]<len)printf(","); 	} }  int main() { 	int n; 	scanf("%d",&n); 	fun(n); 	return 0; }  http://www.codeproject.com/Articles/418776/How-to-replace-recursive-functions-using-stack-and [/quote] 链接页面的内容看不懂。。。

“给定一个小点的输入，完整单步跟踪(同时按Alt+7键查看Call Stack里面从上到下列出的对应从里层到外层的函数调用历史)一遍。”是理解递归函数工作原理的不二法门！ 递归函数关注以下几个因素 ·退出条件 ·参数有哪些 ·返回值是什么 ·局部变量有哪些 ·全局变量有哪些 ·何时输出 ·会不会导致堆栈溢出

难者不会，会者不难。 赵4出品，必属精品！  //给定一个数组a[9]={'a','b','c','1','2','3','!','@',"#"}， //要求程序启动后提示输入整数n(0<n<9),根据输入整数进行输出， //输出规则为：从一行一字符到n行n字符遍历数组中所有字符，比如： //n=1,则输出： //a,b,c,1,2,3,!,@,# //n=2.则如下输出： //a,b,c,1,2,3,!,@,# //aa,ab,ac,a1,a2,a3,a!,a@,a#,ba,bb,bc,b1,b2,b3,b!,b@,b#,ca,cb,cc,c1,c2,c3,c!,c@,c#,1a,1b,1c,11,12,13,1!,1@,1#,2a,2b,2c,21,22,23,2!,2@,2#,3a,3b,3c,31,32,33,3!,3@,3#,!a,!b,!c,!1,!2,!3,!!,!@,!#,@a,@b,@c,@1,@2,@3,@!,@@,@#,a,#b,#c,#1,#2,#3,#!,#@,## //…… #include <stdio.h> char a[9]={'a','b','c','1','2','3','!','@','#'}; char t[9]; void out(int m,int L) {     int i;     if (m==L) {         for (i=0;i<m;i++) printf("%c",t[i]);         for (i=0;i<m;i++) if ('#'!=t[i]) break;         if (i<m) printf(",");         return;     }     for (i=0;i<9;i++) {         t[L]=a[i];         out(m,L+1);     } } void out1_n(int n) {     int m;      for (m=1;m<=n;m++) {         out(m,0);         printf("\n");     } } int main() {     int n;      while (1) {         printf("Input n(0<n<9):");         fflush(stdout);         rewind(stdin);         if (1==scanf("%d",&n)) {             if (0<n && n<9) break;         }     }     out1_n(n);     return 0; } //Input n(0<n<9):1 //a,b,c,1,2,3,!,@,# // //Input n(0<n<9):2 //a,b,c,1,2,3,!,@,# //aa,ab,ac,a1,a2,a3,a!,a@,a#,ba,bb,bc,b1,b2,b3,b!,b@,b#,ca,cb,cc,c1,c2,c3,c!,c@,c#,1a,1b,1c,11,12,13,1!,1@,1#,2a,2b,2c,21,22,23,2!,2@,2#,3a,3b,3c,31,32,33,3!,3@,3#,!a,!b,!c,!1,!2,!3,!!,!@,!#,@a,@b,@c,@1,@2,@3,@!,@@,@#,#a,#b,#c,#1,#2,#3,#!,#@,## // //Input n(0<n<9):3 //a,b,c,1,2,3,!,@,# //aa,ab,ac,a1,a2,a3,a!,a@,a#,ba,bb,bc,b1,b2,b3,b!,b@,b#,ca,cb,cc,c1,c2,c3,c!,c@,c#,1a,1b,1c,11,12,13,1!,1@,1#,2a,2b,2c,21,22,23,2!,2@,2#,3a,3b,3c,31,32,33,3!,3@,3#,!a,!b,!c,!1,!2,!3,!!,!@,!#,@a,@b,@c,@1,@2,@3,@!,@@,@#,#a,#b,#c,#1,#2,#3,#!,#@,## //aaa,aab,aac,aa1,aa2,aa3,aa!,aa@,aa#,aba,abb,abc,ab1,ab2,ab3,ab!,ab@,ab#,aca,acb,acc,ac1,ac2,ac3,ac!,ac@,ac#,a1a,a1b,a1c,a11,a12,a13,a1!,a1@,a1#,a2a,a2b,a2c,a21,a22,a23,a2!,a2@,a2#,a3a,a3b,a3c,a31,a32,a33,a3!,a3@,a3#,a!a,a!b,a!c,a!1,a!2,a!3,a!!,a!@,a!#,a@a,a@b,a@c,a@1,a@2,a@3,a@!,a@@,a@#,a#a,a#b,a#c,a#1,a#2,a#3,a#!,a#@,a##,baa,bab,bac,ba1,ba2,ba3,ba!,ba@,ba#,bba,bbb,bbc,bb1,bb2,bb3,bb!,bb@,bb#,bca,bcb,bcc,bc1,bc2,bc3,bc!,bc@,bc#,b1a,b1b,b1c,b11,b12,b13,b1!,b1@,b1#,b2a,b2b,b2c,b21,b22,b23,b2!,b2@,b2#,b3a,b3b,b3c,b31,b32,b33,b3!,b3@,b3#,b!a,b!b,b!c,b!1,b!2,b!3,b!!,b!@,b!#,b@a,b@b,b@c,b@1,b@2,b@3,b@!,b@@,b@#,b#a,b#b,b#c,b#1,b#2,b#3,b#!,b#@,b##,caa,cab,cac,ca1,ca2,ca3,ca!,ca@,ca#,cba,cbb,cbc,cb1,cb2,cb3,cb!,cb@,cb#,cca,ccb,ccc,cc1,cc2,cc3,cc!,cc@,cc#,c1a,c1b,c1c,c11,c12,c13,c1!,c1@,c1#,c2a,c2b,c2c,c21,c22,c23,c2!,c2@,c2#,c3a,c3b,c3c,c31,c32,c33,c3!,c3@,c3#,c!a,c!b,c!c,c!1,c!2,c!3,c!!,c!@,c!#,c@a,c@b,c@c,c@1,c@2,c@3,c@!,c@@,c@#,c#a,c#b,c#c,c#1,c#2,c#3,c#!,c#@,c##,1aa,1ab,1ac,1a1,1a2,1a3,1a!,1a@,1a#,1ba,1bb,1bc,1b1,1b2,1b3,1b!,1b@,1b#,1ca,1cb,1cc,1c1,1c2,1c3,1c!,1c@,1c#,11a,11b,11c,111,112,113,11!,11@,11#,12a,12b,12c,121,122,123,12!,12@,12#,13a,13b,13c,131,132,133,13!,13@,13#,1!a,1!b,1!c,1!1,1!2,1!3,1!!,1!@,1!#,1@a,1@b,1@c,1@1,1@2,1@3,1@!,1@@,1@#,1#a,1#b,1#c,1#1,1#2,1#3,1#!,1#@,1##,2aa,2ab,2ac,2a1,2a2,2a3,2a!,2a@,2a#,2ba,2bb,2bc,2b1,2b2,2b3,2b!,2b@,2b#,2ca,2cb,2cc,2c1,2c2,2c3,2c!,2c@,2c#,21a,21b,21c,211,212,213,21!,21@,21#,22a,22b,22c,221,222,223,22!,22@,22#,23a,23b,23c,231,232,233,23!,23@,23#,2!a,2!b,2!c,2!1,2!2,2!3,2!!,2!@,2!#,2@a,2@b,2@c,2@1,2@2,2@3,2@!,2@@,2@#,2#a,2#b,2#c,2#1,2#2,2#3,2#!,2#@,2##,3aa,3ab,3ac,3a1,3a2,3a3,3a!,3a@,3a#,3ba,3bb,3bc,3b1,3b2,3b3,3b!,3b@,3b#,3ca,3cb,3cc,3c1,3c2,3c3,3c!,3c@,3c#,31a,31b,31c,311,312,313,31!,31@,31#,32a,32b,32c,321,322,323,32!,32@,32#,33a,33b,33c,331,332,333,33!,33@,33#,3!a,3!b,3!c,3!1,3!2,3!3,3!!,3!@,3!#,3@a,3@b,3@c,3@1,3@2,3@3,3@!,3@@,3@#,3#a,3#b,3#c,3#1,3#2,3#3,3#!,3#@,3##,!aa,!ab,!ac,!a1,!a2,!a3,!a!,!a@,!a#,!ba,!bb,!bc,!b1,!b2,!b3,!b!,!b@,!b#,!ca,!cb,!cc,!c1,!c2,!c3,!c!,!c@,!c#,!1a,!1b,!1c,!11,!12,!13,!1!,!1@,!1#,!2a,!2b,!2c,!21,!22,!23,!2!,!2@,!2#,!3a,!3b,!3c,!31,!32,!33,!3!,!3@,!3#,!!a,!!b,!!c,!!1,!!2,!!3,!!!,!!@,!!#,!@a,!@b,!@c,!@1,!@2,!@3,!@!,!@@,!@#,!#a,!#b,!#c,!#1,!#2,!#3,!#!,!#@,!##,@aa,@ab,@ac,@a1,@a2,@a3,@a!,@a@,@a#,@ba,@bb,@bc,@b1,@b2,@b3,@b!,@b@,@b#,@ca,@cb,@cc,@c1,@c2,@c3,@c!,@c@,@c#,@1a,@1b,@1c,@11,@12,@13,@1!,@1@,@1#,@2a,@2b,@2c,@21,@22,@23,@2!,@2@,@2#,@3a,@3b,@3c,@31,@32,@33,@3!,@3@,@3#,@!a,@!b,@!c,@!1,@!2,@!3,@!!,@!@,@!#,@@a,@@b,@@c,@@1,@@2,@@3,@@!,@@@,@@#,@#a,@#b,@#c,@#1,@#2,@#3,@#!,@#@,@##,#aa,#ab,#ac,#a1,#a2,#a3,#a!,#a@,#a#,#ba,#bb,#bc,#b1,#b2,#b3,#b!,#b@,#b#,#ca,#cb,#cc,#c1,#c2,#c3,#c!,#c@,#c#,#1a,#1b,#1c,#11,#12,#13,#1!,#1@,#1#,#2a,#2b,#2c,#21,#22,#23,#2!,#2@,#2#,#3a,#3b,#3c,#31,#32,#33,#3!,#3@,#3#,#!a,#!b,#!c,#!1,#!2,#!3,#!!,#!@,#!#,#@a,#@b,#@c,#@1,#@2,#@3,#@!,#@@,#@#,##a,##b,##c,##1,##2,##3,##!,##@,### //

嗯，借鉴赵老师处理逗号的思路，修改了下。 #include<iostream> #include<string> #include<fstream> using namespace std;  char a[9] = { 'a', 'b', 'c', '1', '2', '3', '!', '@', '#' }; char c[20];  void Circle(ostream& os, int times, int size){ 	if (times == 0){ 		for (int i = 0; i < size; ++i) 			os << c[i]; 		for (int i = 0; i < size; ++i){ 			if (c[i] != '#'){ 				os << ','; 				break; 			} 		} 		return; 	}  	for (int i = 0; i < 9; ++i){ 		c[size] = a[i]; 		Circle(os, times - 1, size + 1); 	} }  void Print(ostream& os, int times){ 	for (int i = 0; i < times; ++i){ 		Circle(os, i + 1, 0); 		os << endl; 	} }  int main(){ 	int times; 	cin >> times; 	/*ofstream out("Test.txt"); 	Print(out, times);*/ 	Print(cout, times); }

如下改成文件流形式可以以文件来检查输出： #include<iostream> #include<string> #include<fstream> using namespace std;  char a[9] = { 'a', 'b', 'c', '1', '2', '3', '!', '@', '#' }; char temp[20];  void Circle(ostream& os,int times, char* c,int size){ 	if (times == 0){ 		for (int i = 0; i < size;++i) 			os << c[i] ; 		os << ','; 		return; 	}  	for (int i = 0; i < 9; ++i){ 		c[size] = a[i]; 		Circle(os,times - 1, c, size + 1); 	} }  void Print(ostream& os,int times){ 	for (int i = 0; i < times; ++i){ 		Circle(os, i + 1, temp, 0); 		os << endl; 	} }  int main(){ 	int times; 	cin >> times; 	ofstream out("Test.txt"); 	Print(out,times); } 嗯，n=4的时候没问题！

犹豫数据不多，最笨的办法就是7楼的列举法，然后就是8楼的递归与循环了，坐等更牛的算法大神！

貌似输入4的时候，控制台前面一部分就被覆盖掉了。 #include<iostream> using namespace std;  char a[9] = { 'a', 'b', 'c', '1', '2', '3', '!', '@', '#' }; char temp[20];  void Circle(int times, char* c,int size){ 	if (times == 0){ 		for (int i = 0; i < size;++i) 			cout << c[i] ; 		cout << ','; 		return; 	}  	for (int i = 0; i < 9; ++i){ 		c[size] = a[i]; 		Circle(times - 1, c, size + 1); 	} }  void Print(int times){ 	for (int i = 0; i < times; ++i){ 		Circle(i + 1, temp, 0); 		cout << endl; 	} }  int main(){ 	int times; 	cin >> times; 	Print(times); }

引用 4 楼 polyard 的回复:[quote=引用 3 楼 Falleyes 的回复:] 最后一个逗号没有处理。#include<iostream> #include<string> using namespace std;  char a[9] = { 'a', 'b', 'c', '1', '2', '3', '!', '@', '#' };  void Print(int times,char c){ 	if (times == 1){ 		for (int i = 0; i < 9; ++i){ 			if (c) 				cout << c; 			cout << a[i] << ','; 		} 		return; 	}  	for (int i = 0; i < 9; ++i){ 		if (c) 			cout << c; 		Print(times - 1, a[i]); 	} }  int main(){ 	int times; 	cin >> times; 	Print(times,NULL); 	cout << endl; }     你题理解了一点，但就是关键的没看。你的程序是当times=2时，输出了相当于我题目中n=2输出中的下半部分，它还需要输出n=1的情况，也就是n=max时，输出要是max!的所有输出，而且是按照n=1,n=2...的顺序输出的。另外，你的程序当times=3时输出时错误的哦，加油，真没那么简单^_^[/quote]嗯，确实如此。按照n=1,n=2... 的顺序输出好改。times=3时出错了，看样子还要研究研究！


Question: 如何获取当前时间到第2天凌晨00：00：00剩余的秒数

楼主   同求啊 不知道你是怎么做的

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

谢谢楼上的，结贴了

引用 1 楼 stormlk1983 的回复:难度要把struct tm里面的时间设置成00：00：00，取得了当前的time_t后在加上86400？ 求大神看看有没有更好的方法，或者接口 差不多的思路， 24hour - (now - start of today) /* difftime example */ #include <stdio.h>      /* printf */ #include <time.h>       /* time_t, struct tm, difftime, time, mktime */  int main () {   time_t now = time(NULL);   struct tm today = *localtime(&now);   double seconds;    today.tm_hour = 0; today.tm_min = 0; today.tm_sec = 0;      seconds = 24*60*60-difftime(now,mktime(&today));    printf (" %.f seconds left today\n" seconds);    return 0; }


Question: 在镜像文件中，找到idx1这个字符串，怎么做？别说用字符串匹配函数。

C:\>findstr /? 在文件中寻找字符串。  FINDSTR [/B] [/E] [/L] [/R] [/S] [/I] [/X] [/V] [/N] [/M] [/O] [/F:file]         [/C:string] [/G:file] [/D:dir list] [/A:color attributes] [/OFF[LINE]]         strings [[drive:][path]filename[ ...]]    /B         在一行的开始配对模式。   /E         在一行的结尾配对模式。   /L         按字使用搜索字符串。   /R         将搜索字符串作为一般表达式使用。   /S         在当前目录和所有子目录中搜索匹配文件。   /I         指定搜索不分大小写。   /X         打印完全匹配的行。   /V         只打印不包含匹配的行。   /N         在匹配的每行前打印行数。   /M         如果文件含有匹配项，只打印其文件名。   /O         在每个匹配行前打印字符偏移量。   /P         忽略有不可打印字符的文件。   /OFF[LINE] 不跳过带有脱机属性集的文件。   /A:attr    指定有十六进位数字的颜色属性。请见 "color /?"   /F:file    从指定文件读文件列表 (/ 代表控制台)。   /C:string  使用指定字符串作为文字搜索字符串。   /G:file    从指定的文件获得搜索字符串。 (/ 代表控制台)。   /D:dir     查找以分号为分隔符的目录列表   strings    要查找的文字。   [drive:][path]filename              指定要查找的文件。  除非参数有 /C 前缀，请使用空格隔开搜索字符串。 例如: 'FINDSTR "hello there" x.y' 在文件 x.y 中寻找 "hello" 或 "there"。'FINDSTR /C:"hello there" x.y' 文件 x.y  寻找 "hello there"。  一般表达式的快速参考:   .        通配符: 任何字符   *        重复: 以前字符或类别出现零或零以上次数   ^        行位置: 行的开始   $        行位置: 行的终点   [class]  字符类别: 任何在字符集中的字符   [^class] 补字符类别: 任何不在字符集中的字符   [x-y]    范围: 在指定范围内的任何字符   \x       Escape: 元字符 x 的文字用法   \<xyz    字位置: 字的开始   xyz\>    字位置: 字的结束  有关 FINDSTR 常见表达法的详细情况，请见联机命令参考。


Question: 候车场信息输出的不对其他都能运行  大神帮忙改下  要答辩很急 ~~

答辩需要代码？毕设这么点代码是走命令行?


Question: C语言从一个字符串中提取指定的几个字符串并打印出来的问题

引用 2 楼 zhao4zhong1 的回复:作为一个C程序员，对  scanf,sscanf,fscanf  printf,sprintf,fprintf 这类函数的用法，还是要做到“拳不离手，曲不离口”的。  #include <stdio.h> char buf[1024] = "[{\"bucket_name\":\"andy-personal-cloud4\",\"status\":\"0\",\"cdatetime\":\"1402481705\",\"used_capacity\":\"0\",\"total_capacity\":\"0\",\"region\":\"beijing\"}" ",{\"bucket_name\":\"andy-personal-cloud3\",\"status\":\"0\",\"cdatetime\":\"1402479952\",\"used_capacity\":\"0\",\"total_capacity\":\"0\",\"region\":\"beijing\"}" ",{\"bucket_name\":\"andy-personal-cloud2\",\"status\":\"0\",\"cdatetime\":\"1402386155\",\"used_capacity\":\"119056\",\"total_capacity\":\"0\",\"region\":\"beijing\"}" ",{\"bucket_name\":\"andy-personal-cloud\",\"status\":\"0\",\"cdatetime\":\"1401209441\",\"used_capacity\":\"19491722\",\"total_capacity\":\"0\",\"region\":\"beijing\"}]..."; char s[40]; char *p; int n,r; int main() {     p=buf;     while (1) {         r=sscanf(p,"{\"bucket_name\":\"%39[^\"]\"%n",s,&n);         if (1==r) {             printf("[%s]\n",s);             p+=n;         } else if (0==r) p++;         else break;     }     return 0; } //[andy-personal-cloud4] //[andy-personal-cloud3] //[andy-personal-cloud2] //[andy-personal-cloud] //   +1

6楼代码不如2楼代码简洁。

#include <stdio.h> #include <string.h>  char str[1024]="[{\"bucket_name\":\"andy-personal-cloud4\",\"bucket_name\":\"andy-personal-cloud5\",\"bucket_name\":\"andy-personal-cloud6\"}]";  char dst[30]="";  char check[20]="\"bucket_name\":";  int main() { 	char *p=str; 	while((p = strstr(p,check)) != NULL){ 		puts(p); 		sscanf(p,"\"bucket_name\":\"%[^\"]", dst); 		p = p + strlen(check) + strlen(dst)+ 3; 		puts(dst); 	} }

引用 2 楼 zhao4zhong1 的回复:作为一个C程序员，对  scanf,sscanf,fscanf  printf,sprintf,fprintf 这类函数的用法，还是要做到“拳不离手，曲不离口”的。  #include <stdio.h> char buf[1024] = "[{\"bucket_name\":\"andy-personal-cloud4\",\"status\":\"0\",\"cdatetime\":\"1402481705\",\"used_capacity\":\"0\",\"total_capacity\":\"0\",\"region\":\"beijing\"}" ",{\"bucket_name\":\"andy-personal-cloud3\",\"status\":\"0\",\"cdatetime\":\"1402479952\",\"used_capacity\":\"0\",\"total_capacity\":\"0\",\"region\":\"beijing\"}" ",{\"bucket_name\":\"andy-personal-cloud2\",\"status\":\"0\",\"cdatetime\":\"1402386155\",\"used_capacity\":\"119056\",\"total_capacity\":\"0\",\"region\":\"beijing\"}" ",{\"bucket_name\":\"andy-personal-cloud\",\"status\":\"0\",\"cdatetime\":\"1401209441\",\"used_capacity\":\"19491722\",\"total_capacity\":\"0\",\"region\":\"beijing\"}]..."; char s[40]; char *p; int n,r; int main() {     p=buf;     while (1) {         r=sscanf(p,"{\"bucket_name\":\"%39[^\"]\"%n",s,&n);         if (1==r) {             printf("[%s]\n",s);             p+=n;         } else if (0==r) p++;         else break;     }     return 0; } //[andy-personal-cloud4] //[andy-personal-cloud3] //[andy-personal-cloud2] //[andy-personal-cloud] //  ++

引用 2 楼 zhao4zhong1 的回复:作为一个C程序员，对  scanf,sscanf,fscanf  printf,sprintf,fprintf 这类函数的用法，还是要做到“拳不离手，曲不离口”的。  #include <stdio.h> char buf[1024] = "[{\"bucket_name\":\"andy-personal-cloud4\",\"status\":\"0\",\"cdatetime\":\"1402481705\",\"used_capacity\":\"0\",\"total_capacity\":\"0\",\"region\":\"beijing\"}" ",{\"bucket_name\":\"andy-personal-cloud3\",\"status\":\"0\",\"cdatetime\":\"1402479952\",\"used_capacity\":\"0\",\"total_capacity\":\"0\",\"region\":\"beijing\"}" ",{\"bucket_name\":\"andy-personal-cloud2\",\"status\":\"0\",\"cdatetime\":\"1402386155\",\"used_capacity\":\"119056\",\"total_capacity\":\"0\",\"region\":\"beijing\"}" ",{\"bucket_name\":\"andy-personal-cloud\",\"status\":\"0\",\"cdatetime\":\"1401209441\",\"used_capacity\":\"19491722\",\"total_capacity\":\"0\",\"region\":\"beijing\"}]..."; char s[40]; char *p; int n,r; int main() {     p=buf;     while (1) {         r=sscanf(p,"{\"bucket_name\":\"%39[^\"]\"%n",s,&n);         if (1==r) {             printf("[%s]\n",s);             p+=n;         } else if (0==r) p++;         else break;     }     return 0; } //[andy-personal-cloud4] //[andy-personal-cloud3] //[andy-personal-cloud2] //[andy-personal-cloud] //  你太shuai了

放到std::string里面，然后find


Question: 问题请教,按照教材上的一段代码练习，要求是统计各个数字、空白符以及其他字符出现的次数，为什么数不出结果？

引用 1 楼 zhao4zhong1 的回复:输入完毕请按 Enter，Ctrl+Z，Enter 知道了，结束符用的是CTRL+C就可以了。~

正解。注意EOF的涵义。

输入完毕请按 Enter，Ctrl+Z，Enter


Question: 链表问题~~~求解答

引用 8 楼 oYinGui1 的回复: void add (stu student, note **plist ) {     note *pnew = (note *) malloc((size_t) sizeof(note));     pnew->students = student;     pnew->next = NULL;          if (*plist == NULL) {         *plist = pnew;     }     else {         note *tmp = *plist;         while (tmp->next != NULL) {             tmp = tmp->next;         }         tmp->next = pnew;     } }  成功了，谢谢

引用 7 楼 xuzhouweihao 的回复:下面链表的创建部分这个参考下吧。谢谢

下面链表的创建部分这个参考下吧。   /*   * 有一个数组a[1000]存放0--1000;要求每隔二个数删掉一个数，  * 到末尾时循环至开头继续进行，求最后一个被删掉的数的原始下标位置。  */  #include <stdio.h> #include <stdlib.h>  typedef struct shuzu{ 	int data; 	struct shuzu *next; }*Pshuzu;  void create_link(Pshuzu *node,int data) { 	if((*node) == NULL){ 		(*node) = malloc(sizeof(struct shuzu)); 		(*node)->data = data; 		(*node)->next = NULL; 	}else{ //(*node) != NULL 		create_link(&((*node)->next),data); 	}  	return; }  void deletn_link(Pshuzu *node,int n) { 	Pshuzu p = NULL; 	Pshuzu pnext =NULL; 	int i;  	if((*node) == NULL){ 		return; 	}  	pnext = (*node);  	while(1){ 		if((*node)->next == NULL){ 			break; 		} 		for(i=0; i<(n-1); i++){ 			pnext = pnext->next; 			if(pnext == NULL){ 				pnext = (*node); 			} 		}  		if(pnext->next != NULL){ 			free(pnext->next); 			pnext->next = pnext->next->next; 			pnext = pnext->next; 			if(pnext == NULL){ 				 pnext = (*node); 			} 		}else{ 			p = (*node)->next; 			free(*node); 			(*node) = p; 			pnext = (*node); 		} 	} }  void print_link(Pshuzu *node) { 	if((*node) == NULL){ 		printf("NULL\n"); 		return; 	}  	printf("%d->",(*node)->data); 	print_link(&((*node)->next)); 	return; }  void delet_link(Pshuzu *node) { 	if((*node) == NULL){ 	}else if((*node)->next == NULL){ 		free(*node); 		(*node) = NULL; 	}else{ 		delet_link(&((*node)->next)); 	}  	return; }  int main() { 	int i; 	Pshuzu root=NULL;  	for(i=1; i<=1000; i++){ 		create_link(&root,i); 	}  	print_link(&root);  	deletn_link(&root,2);  	print_link(&root);  	delet_link(&root);  }

引用 5 楼 u012805025 的回复:[quote=引用 2 楼 truelance 的回复:] 你要把函数定义成 void add (stu student, note **pplist ) 谢谢[/quote] up！

引用 2 楼 truelance 的回复:你要把函数定义成 void add (stu student, note **pplist ) 谢谢

引用 3 楼 oYinGui1 的回复: void add (stu student, note *plist ) {     note *pnew;     note *prev = plist;           pnew = (note *) malloc (sizeof(note));           pnew->students  = student;     pnew->next = NULL;     if (prev == NULL)            plist = pnew;              else            {             while ( prev->next !=NULL )                     prev = prev->next;                prev->next = pnew;     } }  看你的add形参列表就清楚了，你修改的只是plist这个形参，并没有修改传的实参。  改了一下，但不成功，能否帮忙改正，我对比一下，谢谢

传指针类型的变量可以达到修改指针指向的对象内容，但是这也避免不了传进去的指针是个副本的问题，你对它的修改，反映不到原指针上。C里要通过函数修改指针变量，就传个指针的指针。C++里传指针的引用。


Question: 关于快速排序算法

引用 6 楼 u012514171 的回复:楼主我粗略的看了一下楼主的传参，楼主传进去的参数貌似没有被改变，改变的只是形参的变量值（这个值是拷贝的实参的值），所以打印出来的应该是没有改变的x[]，但是却偏偏又什么都没有打印出来，应该是留在了QuickSort函数里面，设断点单步调试吧调试了一下，终于发现果然是卡在QuickSort里面（不愧是高手！），经过修改，现在已经可以了~

引用 2 楼 zhao4zhong1 的回复:为什么不参考下面随便哪个 C:\Microsoft SDK\src\crt\qsort.c C:\Program Files\Microsoft Platform SDK for Windows Server 2003 R2\src\crt\qsort.c C:\Program Files\Microsoft Visual Studio\VC98\CRT\SRC\QSORT.C C:\Program Files\Microsoft Visual Studio 8\VC\crt\src\qsort.c C:\Program Files\Microsoft Visual Studio 9.0\VC\crt\src\qsort.c C:\Program Files\Microsoft Visual Studio 10.0\VC\crt\src\qsort.c 呢？想根据自己的思路编一个

使用了测试代码并在linux mint上编译通过，经供参考 /*  * 快速排序  */  #include <stdio.h> #include <stdlib.h> #include <malloc.h> #include <time.h> #include <unistd.h> #include <math.h>  int* a; int n	=10; int len	=10; int num;  void putf();  void make_num() { 	int i; 	int j; 	srand((int)time(0)); 	for(i=0;i<n;i++) 	{ 		a[i]=abs(rand())%len+1; 		for(j=0;j<i;j++) 		{ 			if(a[i]==a[j]) 			{ 				i--; 				break; 			} 		} 	} }  void sort(int head,int end) { 	int i=head+1; 	int j=end-1; 	int t=a[head]; 	int temp; 	if(head>=end) 	{ 		return ; 	} 	for(;i<=j;) 	{ 		for(;a[i]<=t&&i<=end;num++,i++); 		for(;a[j]>t;num++,j--); 		if(a[i]>t&&a[j]<=t&&i<=j) 		{ 			temp=a[i];a[i]=a[j];a[j]=temp; 		} 		num++; 	} 	temp=a[head];a[head]=a[j];a[j]=temp; 	sort(head,j); 	sort(j+1,end); }  void putf() { 	int i; 	printf("%d:",num); 	for(i=0;i<n;i++) 	{ 		printf("%3d ",a[i]); 	} 	printf("\n"); }  int main() { 	int sum=0; 	int i=1; 	srand((int)time(0)); 	a=(int*)malloc(sizeof(int)*n); 	for(;;) 	{ 		num=0; 		make_num(); 		putf(); 		sort(0,n); 		sum=sum+num; 		printf("\r%d:%f",num,sum*1.0/i++); 		putf(); 		printf("\n"); 		sleep(1); 	} 	return 0; }

为什么上代码呢？图片那么好吗？

LZ，你自己有没有单步调用一下？

/*  ============================================================================  Name        : quick_sort.c  Author      : braveboyny  Version     :  Copyright   : Your copyright notice  Description : quick_sort in C, Ansi-style  ============================================================================  */  #include<stdio.h> int partition(int array[],int low,int high) { 	int i,j,key,temp; 	key=array[high];/*以key值作为参考将数组划分成大于key和小于key的2部分*/ 	i=low-1;  /*以i作为边界，小于key的放在i（包括i）左边，大于key的放在在i右边 			   *初始默认都大于key*/ 	for(j=low;j<high;j++){ 		if(array[j]<=key){ 			i=i+1;  /*若array[j]<=key,则将array[i+1]与array[i]交换， 			 	 	 *因为i是边界所以i+1代表的数绝B大于key,这样就将小于key的值放在了i左边*/ 			temp=array[i]; 			array[i]=array[j]; 			array[j]=temp; 			} 	} 	temp=array[i+1]; 	array[i+1]=array[high]; 	array[high]=temp;/*最后将大于key的array[i+1]于key也就是array[high]交换 	 	 	 	 	 	 	 	  * 这样分组就圆满完成了*/ 	return i+1; } void quick_sort(int array[],int low,int high) { 	int k; 	if(low<high){ 		k=partition(array,low,high); 		quick_sort(array,low,k-1); 		quick_sort(array,k+1,high); 	} } int main(int argc,char *argv[]) { 	int array[10]={8,2,3,6,5,9,4,1,0,7},i; 	quick_sort(array,0,9); 	for(i=0;i<10;i++) 		printf("%d ",array[i]); 	putchar('\n'); 	return 0; } //out:0 1 2 3 4 5 6 7 8 9

引用 3 楼 Koptop 的回复:http://blog.csdn.net/morewindows/article/details/6684558  这里面讲快排讲的简单易懂，楼主可以看一下，然后对比你自己写的看有什么差别。最好自己单步调试一下参考这个！

这里也有一篇快速排序的文章，供楼主参考。


Question: C语言从一个字符串中找出指定的几个字符串并打印出来的问题

const char* str = "	[{\"bucket_name\":\"bucket_name\",\"status\":\"0\",\"bucket_name\":\"1402481705\""; 	const char* key = "\"bucket_name\""; 	const char *p = str; 	size_t len = strlen(key); 	char value[256]; 	 	while( (p=strstr(p,key))!=NULL ) 	{ 		sscanf(p, "\"bucket_name\":\"%[^\"]",value); 		p+= (len+strlen(value)); 		puts(value); 	}

大体是这样： char  *pc; pc = strstr(buf, "bucket_name")+strlen("bucket_name");  你的代码根本就无法编译吧？双引号用的太乱。 注意：如果字符串中有，双引号，在代码中应当这样表示：\"


Question: 一个运行错误

fgets(StrLine,33,fp); 这些参数你确定传对了么

主函数是怎么调用的？

非常感谢！！！！！！！！

进程意外退出会在当前目录下产生‘core’文件或形如‘core.数字’的文件比如‘core.1234’ 使用命令 gdb 运行程序名 core或core.数字 进入gdb然后使用bt命令 可以查看进程意外退出前函数调用的堆栈，内容为从上到下列出对应从里层到外层的函数调用历史。 如果进程意外退出不产生core文件，参考“ulimit -c core文件最大块大小”命令

话说我运行了下代码。。没有出现段错误啊。。。  #include  <stdio.h>  int ReadSL(char* filename, int WhichLine, char* StrLine) { 	FILE* fp = NULL; 	int curindex = 0;  	if((fp = fopen(filename, "r")) == NULL) 	{ 		printf("Open file error\n"); 		return -1; 	}  	while(!feof(fp)) 	{ 		if(curindex == WhichLine) 		{ 			fgets(StrLine, 33, fp); 			fclose(fp); 			return 0; 		} 		curindex++; 		fgets(StrLine, 33, fp); 	}  	fclose(fp); 	return -1; }  int main(int argc, char *argv[]) { 	char buffer[100]; 	char file[] = "test.txt"; 	int ret = ReadSL(file, 2, buffer); 	printf("%s\n", buffer);  	return 0; }    test.txt里面有三行，每行一个词，能正常读出来东西啊，楼主是不是文件名或者参数的问题？Buffer(StrLine)够大吗？文件有没有那么多行？ 楼主可以测试下fgets的返回值


引用 11 楼 NineTyNine_LP 的回复:[quote=引用 9 楼 yangyunzhao 的回复:] [quote=引用 8 楼 NineTyNine_LP 的回复:] Linux下的大型C++项目使用的是什么IDE/工具呢？  我习惯vs2008里面编写代码，然后在linux里面自己写makefile编译。 如果是跨平台的代码，我一般都在windows下调试完成，然后再到linux下调试[/quote]  看来Linux下优秀的C++IDE真的很匮乏啊。[/quote] 关键是Linux下优秀的图形UI基本上都比不上Windows

引用 9 楼 yangyunzhao 的回复:[quote=引用 8 楼 NineTyNine_LP 的回复:] Linux下的大型C++项目使用的是什么IDE/工具呢？  我习惯vs2008里面编写代码，然后在linux里面自己写makefile编译。 如果是跨平台的代码，我一般都在windows下调试完成，然后再到linux下调试[/quote]  看来Linux下优秀的C++IDE真的很匮乏啊。

Linux下的大型C++项目使用的是什么IDE/工具呢？

引用 9 楼 yangyunzhao 的回复:[quote=引用 8 楼 NineTyNine_LP 的回复:] Linux下的大型C++项目使用的是什么IDE/工具呢？  我习惯vs2008里面编写代码，然后在linux里面自己写makefile编译。 如果是跨平台的代码，我一般都在windows下调试完成，然后再到linux下调试[/quote] 这个办法不错

引用 8 楼 NineTyNine_LP 的回复:Linux下的大型C++项目使用的是什么IDE/工具呢？  我习惯vs2008里面编写代码，然后在linux里面自己写makefile编译。 如果是跨平台的代码，我一般都在windows下调试完成，然后再到linux下调试

个人觉得,codeblocks跟VS差的不是一星半点

coblocks可能不适合编写大型代码

跟同一时代VS还是有差距的。

黑猫白猫，能抓老鼠的都是好猫。

VS 2010，是我最讨厌的一个VS版本。不但跑得慢，还奇丑无比，让我很不爽。  所以，我主要使用的VS版本有：6.0, 2005, 2008, 2012.  2002和2003我也很讨厌。  codeblocks也在用，但一般不会用于工作，而是用于学习，验证一些东西。

镰刀与联合收割机比较，优势和劣势？

引用 1 楼 akirya 的回复:个人觉得,codeblocks跟VS差的不是一星半点 废话，等于没说


Question: 求大神帮忙改下代码 运行不出来~~~停车场管理问题~~很急~~~

还是运行不出来~~~

#include  <stdio.h> #include  <malloc.h> #define N 3/*停车场最多的停车数*/ #define M 4/*候车场内最多的停车数*/ #define Price 2/*每单位停车费用*/ typedef struct { 	int CarNo[N];        //车牌号 	int CarTime[N];      //进场时间 	int top;            //栈指针 }SqStack;             //定义顺序栈类型 typedef struct { 	int CarNo[M];     //车牌号 	int front,rear;    //队首和队尾指针 }SqQueue;                //定义循环队类型 void InitStack(SqStack *&s) { 	s=(SqStack *)malloc(sizeof(SqStack)); 	s->top=-1; } bool StackEmpty(SqStack *s)//主要是这些bool函数出问题 { 	return(s->top==-1); } bool StackFull(SqStack *s) { 	return(s->top==N-1); } bool Push(SqStack* s) {int e1,e2; if(s->top==N-1) 	return false; s->top++; s->CarNo[s->top]=e1; s->CarTime[s->top]=e2; return true; } bool Pop(SqStack* s,int e1,int e2) { 	if(s->top==-1) 		return false; 	e1=s->CarNo[s->top]; 	e2=s->CarTime[s->top]; 	s->top--; 	return true; }  void DispStack(SqStack*s) { 	int i; 	for(i=s->top;i>=0;i--) 		printf("%d",s->CarNo[i]); 	printf("\n"); }//以下为循环队列的基本运算算法 void InitQueue(SqQueue *&q) { 	q=(SqQueue*)malloc(sizeof(SqQueue)); 	q->front=q->rear=0; } bool QueueEmpty(SqQueue *q) { 	return(q->front==q->rear); } bool QueueFull(SqQueue *q)  //判断队满 { 	return((q->rear+1)%M==q->front); } bool enQueue(SqQueue* q)//进队 {  	int e; 	if((q->rear+1)%M==q->front); 		return false; 	q->rear=(q->rear+1)%M; 	q->CarNo[q->rear]=e; 	return true; } bool deQueue(SqQueue*&q,int &e)    //出队 { 	if(q->front==q->rear)            //队出的情况 		return false; 	q->front=(q->front+1)%M; 	e=q->CarNo[q->front]; 	return true; } void DispQueue(SqQueue*q)         //输出队中元素 { 	int i; 	i=(q->front+1)%M; 	printf("%d",q->CarNo[i]); 	while((q->rear-i+M)%M>0) 	{ 		i=(i+1)%M; 		printf("%d",q->CarNo[i]); 	} 	printf("\n"); } void main() { 	int comm; 	int no,e1,time,e2; 	int i,j; 	//int St,St1; 	SqStack *St,*St1; 	SqQueue *Qu; 	InitStack(St); 	InitStack(St1); 	InitQueue(Qu); 	do 	{ 		printf("输入指令（1：到达2：离开3：停车场4：候车场0：退出"); 		scanf("%d",&comm); 		switch(comm) 		{ 		case 1:               //汽车到达 			printf("车号以及到达时间："); 			scanf("%d,%d",&no,&time); 			if(!StackFull(St))             //停车场不满 			{ 				SqStack st; 				st.CarNo[0] = no; 				st.CarTime[0] = time; 				Push(&st);  // 				Push(St); // 				Push(no); // 				Push(time); 				printf("***停车场位置：%d\n",St->top+1); 			} 			else              //停车场满 			{ 				if(!QueueFull(Qu))        //候车场不满 				{ 					enQueue(Qu); //					enQueue(no); 					printf("***候车场位置：%d\n",Qu->rear); 				} 				else 					printf("***候车场已满，请下次再来哦(*^__^*) 嘻嘻……\n"); 			} 			break; 		case 2:                //汽车离开 			printf("车号以及离开时间："); 			scanf("%d,%d",&no,&time); 			for(i=0;i<=St->top&&St->CarNo[i]!=no;i++) 				if(i>St->top) 					printf("没有找到此编号的汽车哦！\n"); 				else 				{ 					for(j=i;j<=St->top;j++) 					{ 						Pop(St,e1,e2); // 						Pop(e1); // 						Pop(e2); 						Push(St1); // 						Push(e1); // 						Push(e2); 					}               //倒车到临时栈St1中  					Pop(St,e1,e2); // 					Pop(e1); // 					Pop(e2);                     //该汽车离开 					printf("您一共要交：%d\n",no,(time-e2)*Price); 					while(!StackEmpty(St1))           //将临时栈St1重新回到St中 					{ 						Pop(St1,e1,e2); // 						Pop(e1); // 						Pop(e2); 						Push(St); // 						Push(e1); // 						Push(time); 					} 					if(!QueueEmpty(Qu)) 					{ 						deQueue(Qu,e1);  						St->CarNo[0] = e1; 						St->CarTime[0] = time; 						Push(St); 						 // 						Push(e1); // 						Push(time); 					} 				}    				break;  		case 3: 			if(!StackEmpty(St)) 			{ 				printf("停车场里有："); 				DispStack(St); 			} 			else 				printf("**停车场没有位子了哦！\n"); 			break; 		case 4: 			if(!QueueEmpty(Qu)) 			{ 				printf("候车场中的车辆："); 				DispQueue(Qu); 			} 			else 				printf("**候车场中无车辆\n"); 			break; 		case 0: 			if(!StackEmpty(St)) 			{ 				printf("停车场中的车辆："); 				DispStack(St); 			} 			if(!QueueEmpty(Qu)) 			{ 				printf("候车场中的车辆："); 				DispQueue(Qu); 			} 			break; 		default: 			printf("输入错误哦！\n"); 			break; 		}   	}while(comm!=0); }

该的都恶心了，什么玩意

至少你应该把出现的错误以及你做了哪些尝试告诉我们。要理解栈和队列并不是什么好难的事

楼主，这个代码是你随便找的，怕是没细看吧  第39行括号里怎么有分号 第30行代码压栈时里边的参数是SqStack *&s，怎么在main中传入的参数成int了  问题不少，还是从新找一个问题较少的慢慢改吧


Question: 求质数算法

引用 1 楼 user-3 的回复:i*i <= l 就相当于 i <= sqrt(l) 假定l的平方根是s，那么只要l不能被小于s的所有数整除，比s大的数也就没有必要再算了。  为什么比s大的数也就没有必要再算了？这是什么原理？怎么理解？

引用 3 楼 constmei 的回复:[quote=引用 1 楼 user-3 的回复:] i*i <= l 就相当于 i <= sqrt(l) 假定l的平方根是s，那么只要l不能被小于s的所有数整除，比s大的数也就没有必要再算了。  为什 么比s大的数也就没有必要再算了？这是什么原理？怎么理解？[/quote] 1. (l%j==0)除了表示j是l的一个整因子，还蕴含着l/j（记作k吧）也是l的一个整因子。即一次%j运算是可以判断出两个整因子的。 ----》l%k就是多余的了。  2.j与k的分布是以sqrt(l)为界左右分布的 以l=36为例 2是36的最小整因子，同时可以判断出18是36的最大整因子（真因子） 3是36的整因子，同时可以判断出12也是36的整因子 4是36的整因子，同时可以判断出9也是36的整因子 6是36的整因子，同时可以判断出6也是36的整因子！！！！

嗯，楼上回答够细心的  只是循环的次数减少了  至于原因，比如说a是一个数，设其平方根为x，如果从2到x（如果x不是整数，就下取整）都不能整除a，则再往上试比x更大的数，那这个比x更大的数所乘的数一定比x小，而比x小的数前边都已经试过，不能用才到后边这步，所以，用a的平方根即可判断a是不是素数

感谢大家的回复 终于明白了 特别感谢user-3的回复 没有用到一个数学名词 说的相当清楚 明白

假设x不是质数，x = a * b，x的平方根是s，那么a和b必然有一个大于s，另一个小于s，除非a和b相等都是s 还是以37为例，当我们发现它不能被23456整除，那么他也不可能被7到36的任何一个数整除。如果真有一个a在7到36之间可以整除的，那么对应的b必然小于7，而我们已经验证过小于7的都不能整除，所以b不可能存在，那么a也就不可能存在了。

更正一楼： 只要l不能被所有小于或等于s的所有数整除  其实楼主说的两个方法原理是一样的，只是循环范围不同而已。 比如，如果l=37，那么循环在i=7的时候结束，因为不需要再去除更大的数了


Question: C语言中有没有类似Python中的StringIO可以读写的。

引用 1 楼 truelance 的回复:c++中的string c里自带的字符串处理能力很弱, 都依赖自己实现 谢谢，其实这个实现起来一点都不难，主要是高级语言（python java）之类的用多了， 人就变懒了，申请一个malloc，然后移动指针写入数据就OK了。：）就不该问这样的问题。

c++中的string c里自带的字符串处理能力很弱, 都依赖自己实现


Question: xp和win7下共用的dll文件有哪些啊

引用 1 楼 user-2 的回复:写10个hello world 要求是系统自带的

写10个hello world

c:\windows\system32\oleaut32.dll c:\windows\system32\ole32.dll c:\windows\system32\comdlg32.dll c:\windows\system32\shlwapi.dll c:\windows\system32\shell32.dll c:\windows\system32\user32.dll c:\windows\system32\gdi32.dll c:\windows\system32\secur32.dll c:\windows\system32\advapi32.dll c:\windows\system32\ws2_32.dll c:\windows\system32\ntdll.dll c:\windows\system32\kernel32.dll

引用 3 楼 zhao4zhong1 的回复:http://www.dllzj.com 我当然知道这种dll网站  百度能找到 可是xp和win7都具有的并且一定在system32下存在的共同文件名的dll


Question: 文件操作 fputc()

引用 3 楼 wenbo228228 的回复:我觉得警告级别还是不要太高吧，不然出了问题都不知道 我觉得正好相反，警告级别低了才是“出了问题都不知道”。 警告级别高了，编译的时候可能有点麻烦，但这总比程序到了用户那里出错再拿回来到处找问题要好。 有的公司不但把编译器警告级别设到最高，还要求零警告甚至直接要求编译器把警告当作错误，这都是有原因的。

引用 5 楼 wenbo228228 的回复:用惯了搜狗不想换 而且在其他地方没有这种情况，只是在codeblocks里面这样，是不是我哪里设置不对？ coding的时候，关闭中文输入法。 只有有必要的时候（比如中文注释，中文输出）， 打开中文输入法（自己定义快捷键吧）。

引用 3 楼 wenbo228228 的回复:确实是优先级的问题 还有个问题，我有时候输入了中文，下一句该输入英文，但是忘了切换过来，比如此时已经输入中文状态下的printf，我想直接搞成英文状态的printf，所以直接按了shift键，但是屏幕上只显示了rintf,第一个p没有了，你们遇到过这种情况吗，怎么解决的？  我觉得警告级别还是不要太高吧，不然出了问题都不知道 果断换个输入法。

有些编译器会有警告的。编译的时候把警告级别设的高一点比较好。  我就记不住优先级，所以到处加括号，反正多加了括号也没坏处。 而且我不太敢这么写代码，宁可分两行 fp = fopen(...); if (fp ...)

注意运算符优先级    if((fp=fopen("E:\\c语言\\文件操作\\a.txt","w+"))==NULL)


Question: 关于头文件包含问题

这种问题我以前好象遇到过，有个可能是因为a.h找不到b.h的路径，导致b.h并没有真正加载到a.h中，当然就没有定义了。 楼主检查一下a.h中引用b.h时的路径设置， 另外在编译时仔细一点可以看到中间码时是否把b.h包含进来了

a.c 有没有包含a.h？ 这个确实不好 猜

目测是楼主的test结构体在定义的时候忘了加分号

编译选项加/EP /P，重新编译，查看宏展开后对应的.i文件。gcc加-E  理解和讨论之前请先学会如何观察！

结构体前面没有加struct

没有遇到过。名字写对了么

报错是指编译通不过还是提示有问题

引用 7 楼 cau_eric 的回复:[quote=引用 楼主 navyliu1986 的回复:] 我有四个文件，a.c    a.h      b.c    b.h， b.h里定义了一个结构体 test，a.h包含了b.h， 在a.c里面定义了一个函数 void hello(test  inA); 在a.h里声明了这个函数void hello(test  inA)，此时总是报错test结构体未定义，但在a.c中又没问题。  大家来出现过这种问题没？我是一个大项目里，处理这四个文件还有其他文件，我分析了下好像又没什么问题，请各位大牛指点可能问题出在哪里？谢谢啦！  楼主把代码发上来看看？[/quote] +1

引用 楼主 navyliu1986 的回复:我有四个文件，a.c    a.h      b.c    b.h， b.h里定义了一个结构体 test，a.h包含了b.h， 在a.c里面定义了一个函数 void hello(test  inA); 在a.h里声明了这个函数void hello(test  inA)，此时总是报错test结构体未定义，但在a.c中又没问题。  大家来出现过这种问题没？我是一个大项目里，处理这四个文件还有其他文件，我分析了下好像又没什么问题，请各位大牛指点可能问题出在哪里？谢谢啦！  楼主把代码发上来看看？

直接看一下代码比这里瞎猜要好得多

在a.h里，要确保先写了结构体定义，再写函数定义


Question: 数据结构哈弗曼树的编码，求指出编译器无法显示的错误！

typedef char **HuffmanCode; // 动态分配数组存储赫夫曼编码表  怎样理解”**“？这是双指针还是？在程序里有啥作用？

#include <stdio.h> #include <limits.h> #include <malloc.h> #include <string.h> #include <windows.h>  // 赫夫曼树和赫夫曼编码的存储表示  typedef struct { 	unsigned int weight; 	unsigned int parent,lchild,rchild; }HTNode,*HuffmanTree; // 动态分配数组存储赫夫曼树   typedef char **HuffmanCode; // 动态分配数组存储赫夫曼编码表   // 函数void select()调用 int min1(HuffmanTree t,int i) {  	int j,flag; 	unsigned int k=UINT_MAX; // 取k为不小于可能的值  	for(j = 1; j <= i; j++) 		if(t[j].weight < k && t[j].parent == 0) 			k = t[j].weight,flag = j; 	t[flag].parent=1; 	return flag; }  // s1为最小的两个值中序号小的那个 void select(HuffmanTree t,int i,int *s1,int *s2) {  	int j; 	*s1=min1(t,i); 	*s2=min1(t,i); 	if(*s1 > *s2) 	{ 		j=*s1; 		*s1=*s2; 		*s2=j; 	} }  // w存放n个字符的权值(均>0),构造赫夫曼树HT,并求出n个字符的赫夫曼编码HC void HuffmanCoding(HuffmanTree *HT,HuffmanCode *HC,int *w,int n)  {   	int m,i,s1,s2,start; 	unsigned c,f; 	HuffmanTree p; 	char *cd; 	 	if(n<=1) 		return; 	m=2*n-1;	//因为一颗有n个叶子结点的赫夫曼树共有2n-1个结点 	*HT=(HuffmanTree)malloc((m+1)*sizeof(HTNode)); // 0号单元未用  	for(p=*HT+1,i=1;i<=n;++i,++p,++w)	//初始化各结点的权值 	{ 		(*p).weight=*w; 		(*p).parent=0; 		(*p).lchild=0; 		(*p).rchild=0; 	} 	for(;i<=m;++i,++p)	//初始化双亲位置 		(*p).parent=0; 	for(i=n+1;i<=m;++i) // 建赫夫曼树  	{ 		// 在HT[1 ~ i-1]中选择parent为0且weight最小的两个结点,其序 		// 号分别为s1和s2  		select(*HT,i-1,&s1,&s2); 		(*HT)[s1].parent=(*HT)[s2].parent=i; 		(*HT)[i].lchild=s1; 		(*HT)[i].rchild=s2; 		(*HT)[i].weight=(*HT)[s1].weight+(*HT)[s2].weight; 	} 	// 从叶子到根逆向求每个字符的赫夫曼编码  	*HC=(HuffmanCode)malloc((n+1)*sizeof(char*)); 	// 分配n个字符编码的头指针向量([0]不用)  	cd=(char*)malloc(n*sizeof(char)); // 分配求编码的工作空间  	cd[n-1]='\0'; // 编码结束符  	for(i=1;i<=n;i++) 	{  		// 逐个字符求赫夫曼编码  		start=n-1; // 编码结束符位置  		for(c=i,f=(*HT)[i].parent; f!=0; c=f,f=(*HT)[f].parent) 			// 从叶子到根逆向求编码  			if((*HT)[f].lchild==c) 				cd[--start]='0'; 			else 				cd[--start]='1'; 		(*HC)[i]=(char*)malloc((n-start)*sizeof(char)); 		// 为第i个字符编码分配空间  		strcpy((*HC)[i],&cd[start]); // 从cd复制编码(串)到HC  	} 	free(cd); // 释放工作空间  }  int main() { 	HuffmanTree HT; 	HuffmanCode HC; 	int *w,n,i; 	 	printf("请输入权值的个数(>1)："); 	scanf("%d",&n); 	w=(int*)malloc(n*sizeof(int)); 	printf("请依次输入%d个权值(整型)：\n",n); 	for(i=0;i<=n-1;i++) 		scanf("%d",w+i); 	HuffmanCoding(&HT,&HC,w,n); 	for(i=1;i<=n;i++) 		puts(HC[i]); 		 	system("pause"); 	return 0; } 楼主你和这个对比一下吧


Question: C语言，，这样写是什么意思

c语言也可以面向对象。但楼主这段程序，有构造函数，有初始化列表，是纯c？

引用 25 楼 cdcxy2009 的回复:谁说C没有构造函数，一样有的，没什么问题。 但不明白楼主的问题是什么？  无语了，纯C有构造函数？ 构造函数是干嘛的？这个你都没搞清。

哪本C语言的书讲构造函数了？

引用 31 楼 zhuyf87 的回复:c语言也可以面向对象。但楼主这段程序，有构造函数，有初始化列表，是纯c？ C语言可以面向对象？

纯C中俩冒号咋能编译过去？？求举例。。。

语法糖越甜，编译调试查错越苦！ 把有限的生命浪费在品尝/品鉴无穷多种的语法糖中，我认为不值当。

struct能定义函数么？

引用 17 楼 M173475237 的回复:我想知道C语言里,,这个冒号是什么意思,,,,而且，也可以这样用参数初始化列表么？  如果是c++，Snake::Snake(const POINT &npt, Snake * nnext, Snake * nbefore): 这句中的最后一个冒号，表示后面跟的是初始化列表，C++中结构体也能像类一样定义构造函数，至于其他成员函数、是否能继承……我也不知道，没有尝试过，因为要是需要这些东西，直接定义成类就行了。

c不是面向对象的语言，这种语法，已经用到面向对象的概念了，所以我觉得不是纯C的语法。  楼主有没有在TC上编译过？

引用 13 楼 polyard 的回复:这是API编程，看看《VC++深入详解》你就知道了，这里一言难尽，好吧，其实我没看懂你想问什么，哈哈~ 引用 15 楼 majia2011 的回复:很正常的写法，咱的结构就这么写，有时还会多写几个执行函数进去，呵呵  我想知道C语言里,,这个冒号是什么意思,,,,而且，也可以这样用参数初始化列表么？

不是c，是c++

很正常的写法，咱的结构就这么写，有时还会多写几个执行函数进去，呵呵

C语言 +1

明显不是C嘛

这是C么？ 哪个版本的C？

我喜欢9楼的头像

谁说C没有构造函数，一样有的，没什么问题。 但不明白楼主的问题是什么？

我瞬间凌乱了！

估计先学C，然后C++，刚学C++的时候，都是这个样子的。 当然，有时候为了 效率-------像C那样编写程序，，，真的有效率吗？----- 和 方便----------C++，，使用C++的某些语法，比如构造函数，比如省略 struct ,比如引用-------， 这种C式的C++也是无可厚非的。


Question: linux下，c语言工程如何调用c++文件

有没有返回值，不管返回值是什么类型，都不影响extern "C"的用法

引用 2 楼 brookmill 的回复:编译：  gcc -c -o test.o test.c  g++ -c -o nad.o nad.cpp  g++ test.o nad.o /* nad.h */ #ifdef __cplusplus extern "C" { #endif  int nad(int a, int b);  #ifdef __cplusplus } #endif // nad.cpp extern "C" int nad(int a, int b) {         return a+b; } /* test.c */ #include <stdio.h> #include "nad.h"  int main(void) {         printf("%d\n", nad(1,2));         return 0; }  如果没有返回值，直接使用nad()是不是可以？

make报什么错？贴出来看看 用g++编译cpp文件应该没问题。检查一下你的makefile，cpp文件不是用gcc编译的吧？

引用 5 楼 brookmill 的回复:有没有返回值，不管返回值是什么类型，都不影响extern "C"的用法 非常感谢～写的很明白！ 我照这个方法编译了一下，gcc是可以通过的，但最后的make还是报错识别不了cpp文件中的new，delete等等关键字，是不是有这些东西的cpp是无法用在c文件里的？ 无奈最后还是改写成了c文件。。还好工程量不大 折腾了一大圈，学习啦～

这里的要点是让c++的编译器按照c的方式(而不是c++的方式)来编译nad函数。而c文件不需要做任何的特殊处理，就把nad当作普通的c函数调用即可。 所以extern "C"需加到cpp文件里面nad的定义，还有头文件里面nad的声明。当用gcc编译c文件的时候，虽然也包含了头文件，但是extern "C"被ifdef删掉了。

不能自己写需要的函数吗？


Question: 字符从文件中读取的问题

引用 1 楼 zjq9931 的回复:其实我想说，这种问题，只要会跟踪调试，解决起来很简单的。 我就是用单步调试找出来的

其实我想说，这种问题，只要会跟踪调试，解决起来很简单的。

推荐使用WinHex软件查看硬盘或文件或内存中的原始字节内容。  不要把 fopen("...","...");fscanf,fprintf,fgets,fgetc,fclose //读时把\r\n替换成\n，写时把\n替换成\r\n;读到\x1a就设置EOF;读写的内容当字符看待 和 fopen("...","...b");fseek,fread,fwrite,fgetc,fclose  //不作以上替换，遇到\x1a仍继续读;读写的内容当字节看待 弄混了  printf里面的%和变量的一一对应关系 scanf里面的%和变量以及变量前加不加&的一一对应关系 是C代码中非常容易出错的地方，而且通常编译还不出错。 所以在编译源代码之前值得专门仔细检查一遍甚至多遍。  在每个最后不带\n的printf后面加fflush(stdout); 在每个不想受接收缓冲区旧内容影响的scanf前面加rewind(stdin); 另外请检查scanf的返回值。


Question: 先有鸡还是先有蛋？？？

先有鸡！鸡蛋鸡蛋，鸡在前，未听过蛋鸡！

个人意见，仅供参考： 最早的生物都是不会繁殖后代的生物（也可以不叫其生物），先有一个生物会用DNA繁殖后代，后有一串这个生物死后留下的能繁殖其后代的一串DNA； 最早的鸡都是不会下蛋的鸡（也可以不叫其鸡），先有一只会下鸡蛋的鸡，后有一枚这只会下鸡蛋的鸡下的鸡蛋。

引用 29 楼 zhao4zhong1 的回复:[quote=引用 28 楼 wjfwd2010 的回复:] 世界先有男人还是先有女人？ 先生已经解释了这个问题。 鸡蛋已经解释了这个问题。 现有雌雄同体吧。[/quote] 哈哈我从脑筋急转弯的角度说的。

先有雌雄同体，后有雌雄异体。

引用 28 楼 wjfwd2010 的回复:世界先有男人还是先有女人？ 先生已经解释了这个问题。 鸡蛋已经解释了这个问题。 现有雌雄同体吧。

世界先有男人还是先有女人？ 先生已经解释了这个问题。 鸡蛋已经解释了这个问题。

开关---> 机器语言 电子管开关---> 机器语言 三极管开关-->机器语言  机器语言-------------------------->高级语言            机器语言----> 汇编------->      高级语言  (低级语言-》中级语言-》高级语言) 早期的机器指令很少，可能不需要汇编步骤，直接用机器语言编程，或者直接搞个高级语言（跟汇编指令相似的语言） 使用穿孔纸带控制运行

创建一种语言常用的方法是：  （1）先用这种语言写一个编译器，当然，此时没有编译器程序。然后人肉将这个编译器翻译成机器语言（不求优化），再用这个编译器编译它自己。 （2）先实现一个精简语法的小编译器，再不断扩充，所谓添油战术。 （3）用另外一种语言写编译器。  哲学命题，先有鸡还是先有蛋，理解这个问题的本质是，下蛋的鸡和孵出鸡的蛋是有微小不同的，虽然它们被视作同一个概念。直到量变引起质变，下蛋的“鸡”和我们理解的鸡已经不能算同一个事物了，那么那就是鸡的起源。

引用 16 楼 zhao4zhong1 的回复:人脑和人手。+1

拨弄开关 写的

当然是机器码了

扯淡贴，经常有人说编译器，是鸡蛋，这个那个的，呵呵呵

那么这样写帖子为贵嘛，不违规我重写一个这样的帖子

引用 18 楼 u013697891 的回复:[quote=引用 16 楼 zhao4zhong1 的回复:] 人脑和人手。 我想发个帖子，求助写个软件，这个软件要找个qq好，35*******九位的，昵称是123，像这样的帖子违规吗，我发表了一个帖子好像被删除了[/quote] http://www.csto.com/ 但刚试了打不开。

引用 16 楼 zhao4zhong1 的回复:人脑和人手。 我想发个帖子，求助写个软件，这个软件要找个qq好，35*******九位的，昵称是123，像这样的帖子违规吗，我发表了一个帖子好像被删除了

引用 16 楼 zhao4zhong1 的回复:人脑和人手。 确实，那个时候的电子管电路都是人用手和大脑做出来的。

人脑和人手。

机器语言指令

计算机只认识0和1，所以与计算机最接近最早的一种语言必然是用0和1写的，也就是机器码


Question: 求助：DHCP client 如何向server 要固定的IP地址？

看看DCHP发广播包的时候，带上要请求的地址看看。

不能直接在DHCP服务器设置保留ip吗？


Question: 链表 排序

codeblocks不一样，你就说命令是什么吧。我先设断点，再step into ,然后一直next line,这样可以在watch窗口看到变量的值，但是我总是感觉不对

编译连接通过以后，按F10或F11键单步执行，按Shift+F11返回当前函数，或者在某行按F9设了断点后按F5执行停在该断点处。

我的没中文名字 单步执行究竟怎么搞啊亲？按F5设置断点然后运行吗

引用 11 楼 peterzhangxl 的回复:length_list函数改变了phead的指向，为啥sort_list还能正常运行呢？ length_list之后phead不是指向链表末尾了么？ 那个phead是局部变量，和主函数的phead不一样，主函数的phead没有改变指向

引用 6 楼 wenbo228228 的回复:恩  问题在这里    但是没改之前依然可以排序，只是排完之后会提示程序出错 楼主你什么编译器啊？  我用C-Free，你的代码的结果——

引用 10 楼 wenbo228228 的回复:[quote=引用 7 楼 u013410838 的回复:] 最好的解决办法就是单步执行看看各个变量的值是否和预期的一致 怎么搞，我设置断点后编译和不设一样的，我用的是codeblocks[/quote]  工程要建在英文目录下..... 有中文的话，，它会找不到北滴~~~

引用 7 楼 u013410838 的回复:最好的解决办法就是单步执行看看各个变量的值是否和预期的一致 怎么搞，我设置断点后编译和不设一样的，我用的是codeblocks

我codeblocks，编译器是官网自带的mingw

最好的解决办法就是单步执行看看各个变量的值是否和预期的一致

恩  问题在这里    但是没改之前依然可以排序，只是排完之后会提示程序出错

网络不好

第58行int len = 0;

第58行int len = 0;

int length_list(PNODE phead)  {      int len;      while(phead->pnext!=NULL)      {          len++;                       // len没有初始化，返回的值是不是有问题啊 ？           phead=phead->pnext;     }      return len;  }

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


Question: 【新人求助】关于结构体格式化输入

引用 5 楼 hnwyllmm 的回复:楼主关注下4楼的解释，另外要保证输入不会溢出 不过我感觉这个初始化虽然能够避免很多问题，但是不是必须的 最后提醒一个常见错误，%d不能输出字符串，%s对应的参数不能是数字，要不然也会输出乱码之前也是把%d的地方输入了字符串，结果全成乱码了。不过在百度上看到在定义结构体时已经初始化了。。。

引用 4 楼 u011717322 的回复:因为你的数组没有初始化。 但是你在scanf输入时又没有输入到数组的最大值，所以其余的可能就是乱码了。 初始化数组看看。好像是我在“&bookS.bookName[20]”时初始化的是第20个的原因，而对之前的没初始化，之后去掉了[20]，输入就没有乱码。只是之前都有[20]时，只有“&bookS.bookName[20]”处输出的地方出现了乱码，之后的却没有。。。O(∩_∩)O谢谢

引用 1 楼 hnwyllmm 的回复:楼主想说什么问题呢？就是关于结构体输入的问题，因为看不出来代码哪错了

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

楼主想说什么问题呢？


Question: 调用系统DLL不稳定的问题

引用 11 楼 bigbaldy 的回复:有SharpPcap，所以根本不需要自己写 我前面都说用wireshark了。楼主偏要自己写啊。

引用 8 楼 qq554006164 的回复:只将（wpcap.dll和Packet.dll）两个DLL拷贝到system32目录，要报错：无法加载 DLL“wpcap”: 找不到指定的模块。  然后我就用regsvr32注册不了 应该还安装了对应的驱动。  看winpcap使用手册  或者在安装winpcap时使用 Process Monitor 实时监视文件系统、注册表、进程、线程和 DLL 活动。 http://www.microsoft.com/china/technet/sysinternals/utilities/processmonitor.mspx

有SharpPcap，所以根本不需要自己写

引用 9 楼 user-3 的回复:libpcap 能说清楚点儿吗

libpcap

引用 6 楼 zhao4zhong1 的回复:[quote=引用 5 楼 qq554006164 的回复:] [quote=引用 3 楼 zhao4zhong1 的回复:] [quote=引用 2 楼 qq554006164 的回复:] [quote=引用 1 楼 zhao4zhong1 的回复:] 权限或UAC或防火墙或杀毒软件惹的祸。 推荐使用抓包软件wireshark 我想自己写个抓包类，生成DLL给C#调用[/quote] 还不如你写个类，将winpcap库封装到里面，暴露（导出）必要的经你简化的接口（函数）。[/quote]  引用 3 楼 zhao4zhong1 的回复:[quote=引用 2 楼 qq554006164 的回复:] [quote=引用 1 楼 zhao4zhong1 的回复:] 权限或UAC或防火墙或杀毒软件惹的祸。 推荐使用抓包软件wireshark 我想自己写个抓包类，生成DLL给C#调用[/quote] 还不如你写个类，将winpcap库封装到里面，暴露（导出）必要的经你简化的接口（函数）。[/quote]  我用了winpcap的方式进行抓包，但这种方式需要winpcap.dll文件，很多电脑都没有，而且这个还需要区分32和64位电脑，感觉不是很好[/quote] 请注意，wireshark软件底层也是依赖winpcap.dll的。 你如果有足够的自信你自己写的这个软件能超越wireshark或你自己写个实现抓包的dll能超越winpcap也行。 反正我是没有。 [/quote] 那我还是用winpcap这种吧，那我还有一个问题需要请教您一下，麻烦你耐心解答一下。 我现在使用这种方式，必须要安装WinPcap_4_1_3.exe才能使用，如果只是将winpcap.dll和Packet.dll拷贝到system32目录下，是不能使用的。我现在就是不想用安装的方式，能不能直接拷贝相关DLL？

引用 5 楼 qq554006164 的回复:[quote=引用 3 楼 zhao4zhong1 的回复:] [quote=引用 2 楼 qq554006164 的回复:] [quote=引用 1 楼 zhao4zhong1 的回复:] 权限或UAC或防火墙或杀毒软件惹的祸。 推荐使用抓包软件wireshark 我想自己写个抓包类，生成DLL给C#调用[/quote] 还不如你写个类，将winpcap库封装到里面，暴露（导出）必要的经你简化的接口（函数）。[/quote]  引用 3 楼 zhao4zhong1 的回复:[quote=引用 2 楼 qq554006164 的回复:] [quote=引用 1 楼 zhao4zhong1 的回复:] 权限或UAC或防火墙或杀毒软件惹的祸。 推荐使用抓包软件wireshark 我想自己写个抓包类，生成DLL给C#调用[/quote] 还不如你写个类，将winpcap库封装到里面，暴露（导出）必要的经你简化的接口（函数）。[/quote]  我用了winpcap的方式进行抓包，但这种方式需要winpcap.dll文件，很多电脑都没有，而且这个还需要区分32和64位电脑，感觉不是很好[/quote] 请注意，wireshark软件底层也是依赖winpcap.dll的。 你如果有足够的自信你自己写的这个软件能超越wireshark或你自己写个实现抓包的dll能超越winpcap也行。 反正我是没有。

引用 3 楼 zhao4zhong1 的回复:[quote=引用 2 楼 qq554006164 的回复:] [quote=引用 1 楼 zhao4zhong1 的回复:] 权限或UAC或防火墙或杀毒软件惹的祸。 推荐使用抓包软件wireshark 我想自己写个抓包类，生成DLL给C#调用[/quote] 还不如你写个类，将winpcap库封装到里面，暴露（导出）必要的经你简化的接口（函数）。[/quote]  引用 3 楼 zhao4zhong1 的回复:[quote=引用 2 楼 qq554006164 的回复:] [quote=引用 1 楼 zhao4zhong1 的回复:] 权限或UAC或防火墙或杀毒软件惹的祸。 推荐使用抓包软件wireshark 我想自己写个抓包类，生成DLL给C#调用[/quote] 还不如你写个类，将winpcap库封装到里面，暴露（导出）必要的经你简化的接口（函数）。[/quote]  我用了winpcap的方式进行抓包，但这种方式需要winpcap.dll文件，很多电脑都没有，而且这个还需要区分32和64位电脑，感觉不是很好

引用 3 楼 zhao4zhong1 的回复:[quote=引用 2 楼 qq554006164 的回复:] [quote=引用 1 楼 zhao4zhong1 的回复:] 权限或UAC或防火墙或杀毒软件惹的祸。 推荐使用抓包软件wireshark 我想自己写个抓包类，生成DLL给C#调用[/quote] 还不如你写个类，将winpcap库封装到里面，暴露（导出）必要的经你简化的接口（函数）。[/quote]  谢谢指点，我尝试一下

引用 2 楼 qq554006164 的回复:[quote=引用 1 楼 zhao4zhong1 的回复:] 权限或UAC或防火墙或杀毒软件惹的祸。 推荐使用抓包软件wireshark 我想自己写个抓包类，生成DLL给C#调用[/quote] 还不如你写个类，将winpcap库封装到里面，暴露（导出）必要的经你简化的接口（函数）。

引用 1 楼 zhao4zhong1 的回复:权限或UAC或防火墙或杀毒软件惹的祸。 推荐使用抓包软件wireshark 我想自己写个抓包类，生成DLL给C#调用

权限或UAC或防火墙或杀毒软件惹的祸。 推荐使用抓包软件wireshark


Question: 二叉树的创建

引用 1 楼 zhao4zhong1 的回复:仅供参考#include <iostream> #include <stack> #include <queue> #include <locale.h> using namespace std; typedef struct BiTNode {//二叉树结点     char data;                      //数据     struct BiTNode *lchild,*rchild; //左右孩子指针 } BiTNode,*BiTree; int CreateBiTree(BiTree &T) {//按先序序列创建二叉树     char data;     scanf("%c",&data);//按先序次序输入二叉树中结点的值（一个字符），‘#’表示空树     if (data == '#') {         T = NULL;     } else {         T = (BiTree)malloc(sizeof(BiTNode));         T->data = data;         //生成根结点         CreateBiTree(T->lchild);//构造左子树         CreateBiTree(T->rchild);//构造右子树     }     return 0; } void Visit(BiTree T) {//输出     if (T->data != '#') {         printf("%c ",T->data);     } } void PreOrder(BiTree T) {//先序遍历     if (T != NULL) {         Visit(T);               //访问根节点         PreOrder(T->lchild);    //访问左子结点         PreOrder(T->rchild);    //访问右子结点     } } void InOrder(BiTree T) {//中序遍历     if (T != NULL) {         InOrder(T->lchild);     //访问左子结点         Visit(T);               //访问根节点         InOrder(T->rchild);     //访问右子结点     } } void PostOrder(BiTree T) {//后序遍历     if (T != NULL) {         PostOrder(T->lchild);   //访问左子结点         PostOrder(T->rchild);   //访问右子结点         Visit(T);               //访问根节点     } } void PreOrder2(BiTree T) {//先序遍历(非递归) //访问T->data后，将T入栈，遍历左子树；遍历完左子树返回时，栈顶元素应为T，出栈，再先序遍历T的右子树。     stack<BiTree> stack;     BiTree p = T;//p是遍历指针     while (p || !stack.empty()) {   //栈不空或者p不空时循环         if (p != NULL) {             stack.push(p);          //存入栈中             printf("%c ",p->data);  //访问根节点             p = p->lchild;          //遍历左子树         } else {             p = stack.top();        //退栈             stack.pop();             p = p->rchild;          //访问右子树         }     } } void InOrder2(BiTree T) {//中序遍历(非递归) //T是要遍历树的根指针，中序遍历要求在遍历完左子树后，访问根，再遍历右子树。 //先将T入栈，遍历左子树；遍历完左子树返回时，栈顶元素应为T，出栈，访问T->data，再中序遍历T的右子树。     stack<BiTree> stack;     BiTree p = T;//p是遍历指针     while (p || !stack.empty()) {   //栈不空或者p不空时循环         if (p != NULL) {             stack.push(p);          //存入栈中             p = p->lchild;          //遍历左子树         } else {             p = stack.top();        //退栈，访问根节点             printf("%c ",p->data);             stack.pop();             p = p->rchild;          //访问右子树         }     } }  typedef struct BiTNodePost{     BiTree biTree;     char tag; } BiTNodePost,*BiTreePost; void PostOrder2(BiTree T) {//后序遍历(非递归)     stack<BiTreePost> stack;     BiTree p = T;//p是遍历指针     BiTreePost BT;     while (p != NULL || !stack.empty()) {//栈不空或者p不空时循环         while (p != NULL) {//遍历左子树             BT = (BiTreePost)malloc(sizeof(BiTNodePost));             BT->biTree = p;             BT->tag = 'L';//访问过左子树             stack.push(BT);             p = p->lchild;         }         while (!stack.empty() && (stack.top())->tag == 'R') {//左右子树访问完毕访问根节点             BT = stack.top();             stack.pop();//退栈             BT->biTree;             printf("%c ",BT->biTree->data);         }         if (!stack.empty()) {//遍历右子树             BT = stack.top();             BT->tag = 'R';//访问过右子树             p = BT->biTree;             p = p->rchild;         }     } }  void LevelOrder(BiTree T) {//层次遍历     if (T == NULL) return;     BiTree p = T;     queue<BiTree> queue;//队列     queue.push(p);//根节点入队     while (!queue.empty()) {    //队列不空循环         p = queue.front();      //对头元素出队         printf("%c ",p->data);  //访问p指向的结点         queue.pop();            //退出队列         if (p->lchild != NULL) {//左子树不空，将左子树入队             queue.push(p->lchild);         }         if (p->rchild != NULL) {//右子树不空，将右子树入队             queue.push(p->rchild);         }     } } int main() {     BiTree T;      setlocale(LC_ALL,"chs");     CreateBiTree(T);      printf("先序遍历        ：");PreOrder  (T);printf("\n");     printf("先序遍历(非递归)：");PreOrder2 (T);printf("\n");                                                printf("\n");     printf("中序遍历        ：");InOrder   (T);printf("\n");     printf("中序遍历(非递归)：");InOrder2  (T);printf("\n");                                                printf("\n");     printf("后序遍历        ：");PostOrder (T);printf("\n");     printf("后序遍历(非递归)：");PostOrder2(T);printf("\n");                                                printf("\n");     printf("层次遍历        ：");LevelOrder(T);printf("\n");      return 0; } //ABC##DE#G##F### //先序遍历        ：A B C D E G F //先序遍历(非递归)：A B C D E G F // //中序遍历        ：C B E G D F A //中序遍历(非递归)：C B E G D F A // //后序遍历        ：C G E F D B A //后序遍历(非递归)：C G E F D B A // //层次遍历        ：A B C D E F G //  ///       A ///      / ///     B ///    / \ ///   C   D ///      / \ ///     E   F ///      \ ///       G 不错，认真看一下！

“给定一个小点的输入，完整单步跟踪(同时按Alt+7键查看Call Stack里面从上到下列出的对应从里层到外层的函数调用历史)一遍。”是理解递归函数工作原理的不二法门！ 递归函数关注以下几个因素 ·退出条件 ·参数有哪些 ·返回值是什么 ·局部变量有哪些 ·全局变量有哪些 ·何时输出 ·会不会导致堆栈溢出


Question: 霍夫曼压缩编码问题

引用 4 楼 liwenjin1992 的回复:将转化的编码写入硬盘文件中，例如源文件名为qq.doc,压缩后命名为qq.doc.zip 就当做普通的二进制文件写就好了，名字都是自己定的

仅供参考//有一个二进制文件，要求每隔50bits，删除后面的12bits。 #include <stdio.h> #include <stdlib.h> #include <string.h> FILE *fi,*fo; char buf[31]; char obf[31]; int bn,n; void filter() {//对buf中前n个字节中的位，每隔50bits，忽略12bits，结果放在obf中,且将bn设置为obf中的字节数。     char bit[249];     char obt[249];     char b8[33];     char b88[33];     int i,j;     char *e;      for (i=0;i<n;i++) {         _itoa(buf[i],b8,2);         sprintf(b88,"%032s",b8);         sprintf(bit+i*8,"%s",b88+24);     }      j=0;     for (i=0;i<n*8;i++) {         if (i%62<50) {             obt[j]=bit[i];             j++;         }     }     if (j%8) {         bn=(j/8+1)*8;     } else {         bn=j;     }     for (i=j;i<bn;i++) obt[i]='0';     obt[bn]=0;     bn=bn/8;     for (i=0;i<bn;i++) {         strncpy(b8,obt+i*8,8);b8[8]=0;         obf[i]=(char)strtol(b8,&e,2);     } } int main() {     fi=fopen("in.bin","rb");     if (NULL==fi) {         printf("Can not open file in.bin!\n");         return 1;     }     fo=fopen("out.bin","wb");     if (NULL==fo) {         fclose(fi);         printf("Can not open file out.bin!\n");         return 2;     }     while (1) {         n=fread(buf,1,31,fi);         if (0==n) break;         filter();         fwrite(obf,1,bn,fo);     }     fclose(fo);     fclose(fi);     return 0; }

楼主会把编码放到内存数组里面吗？

这里有一篇关于霍夫曼编码的文章，楼主可以参考


Question: linux shell  问题

引用 4 楼 shencallwudi 的回复:this time is:'date'  ./k2.sh: 24: ./k2.sh: [18: not found ./k2.sh: 27: ./k2.sh: [18: not found good evening! back from function evening... back from function greeting.. back from function greeting_again  引用 4 楼 shencallwudi 的回复:this time is:'date'  ./k2.sh: 24: ./k2.sh: [18: not found ./k2.sh: 27: ./k2.sh: [18: not found good evening! back from function evening... back from function greeting.. back from function greeting_again   我上面那句是可以的，刚才试过了，你复制过去试试吧。 hour=$(date +"%H") 看看哪里有不同。

引用 2 楼 shencallwudi 的回复:this time is:'date'  date: 额外的操作数 "%H" Try 'date --help' for more information. ./k2.sh: 24: [: Illegal number:  ./k2.sh: 27: [: Illegal number:  good evening! back from function evening... back from function greeting.. back from function greeting_again 還是不行啊！ 刚才还有个地方忘记说了  + 和 “%H” 也没有空格，你试试

greeting() {    hour= $ (date + %H )  // 这一句出现了错误， = 和$和（） 中间不该出现空格吧？！！ 改成这个样子就好了： hour=$(date +"%H")


Question: vs6.0 DSW文件中添加功能

问题已经解决，谢谢各位！

引用 9 楼 u013093541 的回复:可是我现在没有main入口函数，只是一个动态库，我改怎么向动态库中添加我的函数才能被正确调用呢？ 请通读MSDN中有关DLL编写、调试的相关章节。 mk:@MSITStore:C:\MSDN98\98VS\2052\winbase.chm::/devdoc/live/pdwbase/dll_77lf.htm Using Dynamic-Link Libraries Creating a simple dynamic-link library  Viewing the DLL exports  Using load-time dynamic linking  Using run-time dynamic linking  Using shared memory in a dynamic-link library  Using thread local storage in a dynamic-link library

引用 3 楼 zhao4zhong1 的回复:*.dsp(DeveloperStudio Project)：是VC++的工程配置文件,比如说你的工程包含哪个文件,你的编译选项是什么等等,编译的时候是按照.dsp的配置来的。 *.dsw(DeveloperStudio Workspace)：是工作区文件，用来配置工程文件的。它可以指向一个或多个.dsp文件。 *.clw：是 ClassWizard信息文件,实际上是INI文件的格式,有兴趣可以研究一下.有时候ClassWizard出问题,手工修改CLW文件可以解决.如果此文件不存在的话,每次用ClassWizard的时候绘提示你是否重建。 *.opt：工程关于开发环境的参数文件，如工具条位置等信息。 *.aps：(AppStudio File),资源辅助文件,二进制格式,一般不用去管他。 *.rc：资源文件。在应用程序中经常要使用一些位图、菜单之类的资源, VC中以rc为扩展名的文件称为资源文件, 其中包含了应用程序中用到的所有的windows资源, 要指出的一点是rc文件可以直接在VC集成环境中以可视化的方法进行编辑和修改。 *.plg：是编译信息文件,编译时的error和warning信息文件(实际上是一个html文件,一般用处不大)，在Tools->Options里面有个选项可以控制这个文件的生成。 *.hpj：(Help Project)是生成帮助文件的工程,用microsfot Help Compiler可以处理。 *.mdp：(Microsoft DevStudio Project)是旧版本的项目文件,如果要打开此文件的话,会提示你是否转换成新的DSP格式。 *.bsc：是用于浏览项目信息的,如果用Source Brower的话就必须有这个文件。如果不用这个功能的话,可以在Project Options里面去掉Generate Browse Info File,可以加快编译速度。 *.map：是执行文件的映像信息纪录文件,除非对系统底层非常熟悉,这个文件一般用不着。 *.pch：(Pre-Compiled File)是预编译文件,可以加快编译速度,但是文件非常大。 *.pdb：(Program Database)记录了程序有关的一些数据和调试信息,在调试的时候可能有用。 *.exp：只有在编译DLL的时候才会生成,记录了DLL文件中的一些信息。一般也没什么用。 *.ncb：无编译浏览文件(no compile browser)。当自动完成功能出问题时可以删除此文件，build后会自动生成。 *.c：源代码文件，按C语言用法编译处理。 *.cpp：源代码文件，按C++语法编译处理。 *.h是头文件，一般用作声明和全局定义。 *.sln:在开发环境中使用的解决方案文件。它将一个或多个项目的所有元素组织到单个的解决方案中。此文件存储在父项目目录中.解决方案文件，他是一个或多个.proj（项目文件）的集合。 *.vcproj 是vc的工程项目文件 .vcproj .sln 分别是VC2002以上工程文件和解决方案文件 .dsp .dsw 分别是VC6的工程文件和工程组文件 将VC7工程转换回VC6工程，换言之，就是将.sln/.vcproj这两个文件转换到.dsw/.dsp文件。 vc6打开dsp或dsw，vc2003,2005打开sln或vcproj VC6打开*.dsw文件,单击工具栏上的"!",然后你的文件夹里多了一个DEBUG文件夹里面有.EXE文件 在vc7里面打开vc6的工程时，它会提示你是否转换成vc7的格式，转换后就可以直接使用了。 转换后的工程，vc6就不认识了。 我使用vc.net 2003打开vc6的工程，提示要升级，我也选了yes to all ， 但是其实vc.net只是读取vc6的.dsw和.dsp中的信息并添加了.sln和.vcproj。 用vc.net打开过的vc6工程 dsw和dsp都没有改变。所以用vc.net打开过的vc6工程，虽然已经被“升级”其实 dsw和dsp并没有被改动，再打开时就不用dsw而用sln了。 这点做得很好，只是从vc6的工程文件中读信息，并不改，照样可以用vc6打开原来的dsw和dsp 引用 3 楼 zhao4zhong1 的回复:*.dsp(DeveloperStudio Project)：是VC++的工程配置文件,比如说你的工程包含哪个文件,你的编译选项是什么等等,编译的时候是按照.dsp的配置来的。 *.dsw(DeveloperStudio Workspace)：是工作区文件，用来配置工程文件的。它可以指向一个或多个.dsp文件。 *.clw：是 ClassWizard信息文件,实际上是INI文件的格式,有兴趣可以研究一下.有时候ClassWizard出问题,手工修改CLW文件可以解决.如果此文件不存在的话,每次用ClassWizard的时候绘提示你是否重建。 *.opt：工程关于开发环境的参数文件，如工具条位置等信息。 *.aps：(AppStudio File),资源辅助文件,二进制格式,一般不用去管他。 *.rc：资源文件。在应用程序中经常要使用一些位图、菜单之类的资源, VC中以rc为扩展名的文件称为资源文件, 其中包含了应用程序中用到的所有的windows资源, 要指出的一点是rc文件可以直接在VC集成环境中以可视化的方法进行编辑和修改。 *.plg：是编译信息文件,编译时的error和warning信息文件(实际上是一个html文件,一般用处不大)，在Tools->Options里面有个选项可以控制这个文件的生成。 *.hpj：(Help Project)是生成帮助文件的工程,用microsfot Help Compiler可以处理。 *.mdp：(Microsoft DevStudio Project)是旧版本的项目文件,如果要打开此文件的话,会提示你是否转换成新的DSP格式。 *.bsc：是用于浏览项目信息的,如果用Source Brower的话就必须有这个文件。如果不用这个功能的话,可以在Project Options里面去掉Generate Browse Info File,可以加快编译速度。 *.map：是执行文件的映像信息纪录文件,除非对系统底层非常熟悉,这个文件一般用不着。 *.pch：(Pre-Compiled File)是预编译文件,可以加快编译速度,但是文件非常大。 *.pdb：(Program Database)记录了程序有关的一些数据和调试信息,在调试的时候可能有用。 *.exp：只有在编译DLL的时候才会生成,记录了DLL文件中的一些信息。一般也没什么用。 *.ncb：无编译浏览文件(no compile browser)。当自动完成功能出问题时可以删除此文件，build后会自动生成。 *.c：源代码文件，按C语言用法编译处理。 *.cpp：源代码文件，按C++语法编译处理。 *.h是头文件，一般用作声明和全局定义。 *.sln:在开发环境中使用的解决方案文件。它将一个或多个项目的所有元素组织到单个的解决方案中。此文件存储在父项目目录中.解决方案文件，他是一个或多个.proj（项目文件）的集合。 *.vcproj 是vc的工程项目文件 .vcproj .sln 分别是VC2002以上工程文件和解决方案文件 .dsp .dsw 分别是VC6的工程文件和工程组文件 将VC7工程转换回VC6工程，换言之，就是将.sln/.vcproj这两个文件转换到.dsw/.dsp文件。 vc6打开dsp或dsw，vc2003,2005打开sln或vcproj VC6打开*.dsw文件,单击工具栏上的"!",然后你的文件夹里多了一个DEBUG文件夹里面有.EXE文件 在vc7里面打开vc6的工程时，它会提示你是否转换成vc7的格式，转换后就可以直接使用了。 转换后的工程，vc6就不认识了。 我使用vc.net 2003打开vc6的工程，提示要升级，我也选了yes to all ， 但是其实vc.net只是读取vc6的.dsw和.dsp中的信息并添加了.sln和.vcproj。 用vc.net打开过的vc6工程 dsw和dsp都没有改变。所以用vc.net打开过的vc6工程，虽然已经被“升级”其实 dsw和dsp并没有被改动，再打开时就不用dsw而用sln了。 这点做得很好，只是从vc6的工程文件中读信息，并不改，照样可以用vc6打开原来的dsw和dsp

如果是vc6的话，新建一个txt文件，改名成.c或者.cpp文件（注意，之前，设置不要隐藏文件扩展名），直接用vc6打开，main函数直接在里面写就可以了。

你想添加什么函数啊？

引用 3 楼 zhao4zhong1 的回复:*.dsp(DeveloperStudio Project)：是VC++的工程配置文件,比如说你的工程包含哪个文件,你的编译选项是什么等等,编译的时候是按照.dsp的配置来的。 *.dsw(DeveloperStudio Workspace)：是工作区文件，用来配置工程文件的。它可以指向一个或多个.dsp文件。 *.clw：是 ClassWizard信息文件,实际上是INI文件的格式,有兴趣可以研究一下.有时候ClassWizard出问题,手工修改CLW文件可以解决.如果此文件不存在的话,每次用ClassWizard的时候绘提示你是否重建。 *.opt：工程关于开发环境的参数文件，如工具条位置等信息。 *.aps：(AppStudio File),资源辅助文件,二进制格式,一般不用去管他。 *.rc：资源文件。在应用程序中经常要使用一些位图、菜单之类的资源, VC中以rc为扩展名的文件称为资源文件, 其中包含了应用程序中用到的所有的windows资源, 要指出的一点是rc文件可以直接在VC集成环境中以可视化的方法进行编辑和修改。 *.plg：是编译信息文件,编译时的error和warning信息文件(实际上是一个html文件,一般用处不大)，在Tools->Options里面有个选项可以控制这个文件的生成。 *.hpj：(Help Project)是生成帮助文件的工程,用microsfot Help Compiler可以处理。 *.mdp：(Microsoft DevStudio Project)是旧版本的项目文件,如果要打开此文件的话,会提示你是否转换成新的DSP格式。 *.bsc：是用于浏览项目信息的,如果用Source Brower的话就必须有这个文件。如果不用这个功能的话,可以在Project Options里面去掉Generate Browse Info File,可以加快编译速度。 *.map：是执行文件的映像信息纪录文件,除非对系统底层非常熟悉,这个文件一般用不着。 *.pch：(Pre-Compiled File)是预编译文件,可以加快编译速度,但是文件非常大。 *.pdb：(Program Database)记录了程序有关的一些数据和调试信息,在调试的时候可能有用。 *.exp：只有在编译DLL的时候才会生成,记录了DLL文件中的一些信息。一般也没什么用。 *.ncb：无编译浏览文件(no compile browser)。当自动完成功能出问题时可以删除此文件，build后会自动生成。 *.c：源代码文件，按C语言用法编译处理。 *.cpp：源代码文件，按C++语法编译处理。 *.h是头文件，一般用作声明和全局定义。 *.sln:在开发环境中使用的解决方案文件。它将一个或多个项目的所有元素组织到单个的解决方案中。此文件存储在父项目目录中.解决方案文件，他是一个或多个.proj（项目文件）的集合。 *.vcproj 是vc的工程项目文件 .vcproj .sln 分别是VC2002以上工程文件和解决方案文件 .dsp .dsw 分别是VC6的工程文件和工程组文件 将VC7工程转换回VC6工程，换言之，就是将.sln/.vcproj这两个文件转换到.dsw/.dsp文件。 vc6打开dsp或dsw，vc2003,2005打开sln或vcproj VC6打开*.dsw文件,单击工具栏上的"!",然后你的文件夹里多了一个DEBUG文件夹里面有.EXE文件 在vc7里面打开vc6的工程时，它会提示你是否转换成vc7的格式，转换后就可以直接使用了。 转换后的工程，vc6就不认识了。 我使用vc.net 2003打开vc6的工程，提示要升级，我也选了yes to all ， 但是其实vc.net只是读取vc6的.dsw和.dsp中的信息并添加了.sln和.vcproj。 用vc.net打开过的vc6工程 dsw和dsp都没有改变。所以用vc.net打开过的vc6工程，虽然已经被“升级”其实 dsw和dsp并没有被改动，再打开时就不用dsw而用sln了。 这点做得很好，只是从vc6的工程文件中读信息，并不改，照样可以用vc6打开原来的dsw和dsp学习

你要添加啥函数啊？

我打开了，但是不知道该在哪儿添加。。。

你先要用VC6打开dsw文件，然后再在里面添加函数


Question: “else”求助！

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

if、for、do、while后面都忌讳带多余的分号。

还有就是你的main函数最后应该添加返回值  int main(int argc, char** argv) {     ..........      return 0; }

#include <stdio.h> int main() {    int n1,n2;    printf("Input the first number:");    scanf("%d",&n1);    printf("Input the second number:");    scanf("%d",&n2);    if(n1>n2)    { 	   printf("min=%d",n2);    }    else     { 	   printf("min=%d",n1);    } } 改成这样就好了，就是"if(n1>n2);"这个地方多了个";"。

因为楼主if(n1>n2);这句后面不应该加分号    if (conditions) {  } else {  }

if(n1>n2); 这里多了个;


Question: sscanf() 函数的一个问题。

引用 4 楼 IT_dreamer1993 的回复:为什么不百度，很全的。。。 我这边暂时只想起来几个简单的例子 输入形式： char string[30]="(10,20)"; int  a=0,b=0; sscanf(string,"(%d,%d)",&a,&b); printf("a = %d,b = %d\n",a.b); 输出a和b结果就是 a=10,b=20 呵呵，的确是这样的，不过你这种用法对我来说没用，我是要用正则表达式来处理。

引用 2 楼 user-4 的回复: const char *strSource = "49, \"M1A1\", \"tank\", 1"; int nRet = sscanf(strSource, "%d, %*c%[^\"]s%*c, %*c%[^\"]s%*c, %d", ...); 改为(s是多余的) int nRet = sscanf(strSource, "%d, %*c%[^\"]%*c, %*c%[^\"]%*c, %d", ...);  OK，3Q，的确是这个S多余了。

赵老师内功深厚，支持。 引用 3 楼 zhao4zhong1 的回复:作为一个C程序员，对  scanf,sscanf,fscanf  printf,sprintf,fprintf 这类函数的用法，还是要做到“拳不离手，曲不离口”的。  #include <stdio.h> const char *strSource = "49, \"M1A1\", \"tank\", 1"; int i1,i4; char s2[40],s3[40]; int main() {     if (4==sscanf(strSource,"%d%*[^\"]\"%39[^\"]\"%*[^\"]\"%39[^\"]\",%d",&i1,s2,s3,&i4)) {         printf("i1,s2,s3,i4=%d,%s,%s,%d\n",i1,s2,s3,i4);     } else {         printf("Format error!\n");     }     return 0; } //i1,s2,s3,i4=49,M1A1,tank,1 //   Format Specification Fields: scanf and wscanf Functions A format specification has the following form:  % [width] [{h | l | I64 | L}]type  The format argument specifies the interpretation of the input and can contain one or more of the following:   White-space characters: blank (' '); tab ('\t'); or newline ('\n'). A white-space character causes scanf to read, but not store, all consecutive white-space characters in the input up to the next non–white-space character. One white-space character in the format matches any number (including 0) and combination of white-space characters in the input.   Non–white-space characters, except for the percent sign (%). A non–white-space character causes scanf to read, but not store, a matching non–white-space character. If the next character in stdin does not match, scanf terminates.   Format specifications, introduced by the percent sign (%). A format specification causes scanf to read and convert characters in the input into values of a specified type. The value is assigned to an argument in the argument list.  The format is read from left to right. Characters outside format specifications are expected to match the sequence of characters in stdin; the matching characters in stdin are scanned but not stored. If a character in stdin conflicts with the format specification, scanf terminates, and the character is left in stdin as if it had not been read.  When the first format specification is encountered, the value of the first input field is converted according to this specification and stored in the location that is specified by the first argument. The second format specification causes the second input field to be converted and stored in the second argument, and so on through the end of the format string.  An input field is defined as all characters up to the first white-space character (space, tab, or newline), or up to the first character that cannot be converted according to the format specification, or until the field width (if specified) is reached. If there are too many arguments for the given specifications, the extra arguments are evaluated but ignored. The results are unpredictable if there are not enough arguments for the format specification.  Each field of the format specification is a single character or a number signifying a particular format option. The type character, which appears after the last optional format field, determines whether the input field is interpreted as a character, a string, or a number.   The simplest format specification contains only the percent sign and a type character (for example, %s). If a percent sign (%) is followed by a character that has no meaning as a format-control character, that character and the following characters (up to the next percent sign) are treated as an ordinary sequence of characters, that is, a sequence of characters that must match the input. For example, to specify that a percent-sign character is to be input, use %%.  An asterisk (*) following the percent sign suppresses assignment of the next input field, which is interpreted as a field of the specified type. The field is scanned but not stored.  To read strings not delimited by space characters, a set of characters in brackets ([ ]) can be substituted for the s (string) type character. The corresponding input field is read up to the first character that does not appear in the bracketed character set. If the first character in the set is a caret (^), the effect is reversed: The input field is read up to the first character that does appear in the rest of the character set.  Note that %[a-z] and %[z-a] are interpreted as equivalent to %[abcde...z]. This is a common scanf function extension, but note that the ANSI standard does not require it.  To store a string without storing a terminating null character ('\0'), use the specification %nc where n is a decimal integer. In this case, the c type character indicates that the argument is a pointer to a character array. The next n characters are read from the input stream into the specified location, and no null character ('\0') is appended. If n is not specified, its default value is 1.  The scanf function scans each input field, character by character. It may stop reading a particular input field before it reaches a space character for a variety of reasons:   The specified width has been reached.   The next character cannot be converted as specified.   The next character conflicts with a character in the control string that it is supposed to match.    The next character fails to appear in a given character set.  For whatever reason, when the scanf function stops reading an input field, the next input field is considered to begin at the first unread character. The conflicting character, if there is one, is considered unread and is the first character of the next input field or the first character in subsequent read operations on stdin.

引用 楼主 su_787910081 的回复: const char *strSource = "49, \"M1A1\", \"tank\", 1"; int nRet = sscanf(strSource, "%d, %*c%[^\"]s%*c, %*c%[^\"]s%*c, %d", ...); // nRet = 2;   第二个字符串总是读不出来，有人知道原因么。 这个函数调用读取到"M1A1"字符串后就出错返回了，我想知道它为什么会出错返回，或者告诉我正确的方法也可以。3Q了。  用到了正则表达式？我看晕了。。。 最好是别用正则表达式了吧。。。这样逻辑上更简单。


Question: 关于获取文件长度的问题！

为什么不用 FILE *f; __int64 fl; …… f=fopen(…… …… fl=_filelengthi64(_fileno(f)); printf("%I64d\n",fl); …… fclose(f); 呢？

回车、换行等控制字符对getc族函数有影响，还是不应该用此族函数

当然有种可能，Unicode 文件：如果使用 Unicode 读法前面两个字节不会读到。但使用字节的读法，会读到 Unicode 文件标识符。

结果应该是一样，建议 LZ 上代码来分析原因

结果应该是一样的，可能是代码有问题。fseek和ftell应该是不太会错的，可能是用fgetc循环计数的时候多算或者少算了一个。用操作系统直接看文件的大小，再和你的运行结果对比一下就知道了。  1. 无代码无真相 2. “非常轻微的差别”到底是什么差别 3. windows还是linux还是什么系统

文件里面还会保存一些文件信息，所以用GetFileSize


Question: 请问一个字节对齐的问题？

计算机组成原理→DOS命令→汇编语言→C语言（不包括C++）、代码书写规范→数据结构、编译原理、操作系统→计算机网络、数据库原理、正则表达式→其它语言（包括C++）、架构…… 搜“地址总线” 对浮点数的处理是CPU内部的浮点处理单元负责而非CPU内部的通用运算器负责。

实际对32位系统，按8字节对齐只会浪费空间，这里vs系列做的不够好，gcc下32位系统默认按4字节对齐，这个才是最佳的选择

内存对齐，主要是考虑到CPU的存取速度。  主要是因为现代计算机都使用了Cache。因为CPU直接访问内存是比较慢的，所以将平时经常使用的内容存放到Cache里面。  Cache是通过一些Cache block来组织的，每一个Cache block一般包含16个字节，32个字节或64个字节等。 比如某个计算机一级Cache的Cache block长度是32个字节，那么每段Cache block总是会包含32个字节对齐的一段内存。  现在有一个double，8字节，如果它的地址不是8字节对齐的，而是被允许进行4字节对齐了，那么就有可能访问它的时候，需要使用两个Cache block，也就是说前4个字节在前一个Cache block上，后4个字节在后一个Cache block上。那么访问两次肯定比访问一次慢。同时这个时候，这个数据没有在Cache里面的机会会增加，因为你允许了这个double4字节对齐，而正好最后一个Cache block上空有4字节的空余，于是机器先把前4字节读到Cache了。但是如果这样的话，当cpu需要使用这个double计算的时候，发现这个double还差4个字节不在，还需要将数据从内存调入Cache，会非常慢，降低了计算的速度。 而如果double，你要求就是8字节对齐，那么要么它就是直接全部读到Cache ，要么就是比如Cache空余不足8字节，Cache满了，那么就一个字节也不会读进去， 等空出来8个字节才会读到Cache ，不会出现Cache 空了4个字节的时候读了一个数据的一半的情况。  摘录《Professional Assembly Language》：里面是这么说的 Memory access is one of the slowest functions the processor performs. When writing assembly language programs that require high performance, it is best to avoid memory access as much as possible. Whenever possible, it is best to keep variables in registers on the processor. Register access is highly optimized for the processor, and is the quickest way to handle data. When it is not possible to keep all of the application data in registers, you should try to optimize the memory access for the application. For processors that use data caching, accessing memory in a sequen- tial order in memory helps increase cache hits, as blocks of memory will be read into cache at one time. One other item to think about when using memory is how the processor handles memory reads and writes. Most processors (including those in the IA-32 family) are optimized to read and write memory locations in specific cache blocks, beginning at the start of the data section. On a Pentium 4 processor, the size of the cache block is 64 bits. If you define a data element that crosses a 64-bit block boundary, it will require two cache operations to retrieve or store the data element in memory. To solve this problem, Intel suggests following these rules when defining data: ❑ Align 16-bit data on a 16-byte boundary. ❑ Align 32-bit data so that its base address is a multiple of four. ❑ Align 64-bit data so that its base address is a multiple of eight. ❑ Avoid many small data transfers. Instead, use a single large data transfer. ❑ Avoid using larger data sizes (such as 80- and 128-bit floating-point values) in the stack. Aligning data within the data section can be tricky. The order in which data elements are defined can be crucial to the performance of your application. If you have a lot of similarly sized data elements, such as integer and floating-point values, place them together at the beginning of the data section. This ensures that they will maintain the proper alignment. If you have a lot of odd-sized data elements, such as strings and buffers, place those at the end of the data section so they won’t throw off the alignment of the other data elements. 大意是这么说的： 内存访问是处理器执行的功能里很慢的一个，所以要写出高性能的程序，就要尽量减少内存访问。 对于使用数据缓存的处理器，按顺序访问内存可以提高缓存命中率，因为每次有一整段的内存被读取到缓存里。 大多处理器（包括IA-32系列）被优化而对特定的缓存块进行内存读写。在奔四处理器上，缓存块大小是64位。如果你定义了一个跨过64位界限的数据，它会执行两次缓存操作来提取或存储此数据。 为解决这个问题，Intel建议在定义数据时遵守那几条规则，即把n字节的数据定义在n的倍数的内存地址上进行对齐。 所以，对于大量大小相似的数据元素（如整型、浮点型）最好把它们一起放到开头；而有些奇数大小的数据（如字符串、缓冲区），最好把它们放到后面。

1.首先在计算机的体系结构层次上，存储系统是多级的，在存储器和cpu的寄存器之间，有多个cache(高速缓存)。如果存储器的存储单位是“字-word-32bit-4byte"的话，存储器上一级的cache的存储单位会是n(=2^k，2的k次方，k>=2)个”字“（称为一个块-block）  2.当存储器中的数据是8byte时，按8的整数倍起始地址对齐的话，这个数据向上级cache传送是会保证在一个块中  3.当存储器中的数据是8byte时，按4的整数倍起始地址对齐的话，这个数据一定有可能分布在前一块的最后和后一块的最前。 即对这个8byte数据访问时，要传送两个块到cache中----效率如何？

引用 楼主 waitianlou 的回复:最近在看字节对齐的问题，有一个疑问就是为什么变量要放在和自身所占字节整数倍的起始位置上？ 如果说字节对齐是为了cpu的总线读取更有效率的话，那么对于一个8位的double型数据来说，为什么要是在8的整数倍地址上呢？在4的整数倍上有什么问题呢？ 比如说： 一个double值： 在0x0004地址上存放，那么就占了0x0004-0x000B 在0x0008地址上存放，那么就占了0x0008-0x000F 对于一个32位的cpu来说，两者有不同的么？  是CPU的一次读取字节的整数倍，不是变量自身所占字节的整数倍。

感觉大伙没有明白楼主想问的主要问题是啥。 楼主貌似只是想知道首地址为什么必须和8对齐，而不是和4对齐即可，衍生一下，为什么“首地址能够被其最宽基本类型成员的大小所整除”。 不知道我对楼主的的问题的理解是否正确，对于字节对齐的背景知识，这个网上能搜到很多~~~

引用 2 楼 91program 的回复:字节对齐，不同编译器会做出不同的处理，没有强制的要求。就是同一编译器，是否字节对齐一般都是可以设置的。  对齐是体系结构的事，编译器只是要求跟体系结构配合

引用 楼主 waitianlou 的回复:最近在看字节对齐的问题，有一个疑问就是为什么变量要放在和自身所占字节整数倍的起始位置上？ 如果说字节对齐是为了cpu的总线读取更有效率的话，那么对于一个8位的double型数据来说，为什么要是在8的整数倍地址上呢？在4的整数倍上有什么问题呢？ 比如说： 一个double值： 在0x0004地址上存放，那么就占了0x0004-0x000B 在0x0008地址上存放，那么就占了0x0008-0x000F 对于一个32位的cpu来说，两者有不同的么？  字节对齐这种事是给cpu方便的，像mips如果直接去访问 末尾非0 4 8 c的地址会有额外的开销，老一点的编译器甚至直接就不允许写出非对齐访问的汇编代码。

楼主可以看看这家伙的blog。  c/c++中内存对齐完全理解，看完不理解请砍我(http://www.cnblogs.com/xylc/p/3780907.html) 以及 http://blog.sina.com.cn/s/blog_67c294ca01012qbu.html


Question: Makefile 编译不过去

搜“跟我一起写makefile”

引用 5 楼 jmppok 的回复:一个工程里面不能包含两个main主要原因是makefile不正确

一个工程里面不能包含两个main

或者你可以这样写：  hello:hello.o           gcc -o  $@  $< hello.o:hello.c           gcc -c $<  world: world.o           gcc -o  $@  $< world.o:world.c           gcc -c $<

第一条规则就写错了，去掉world.o

引用 8 楼 Koptop 的回复:同时编译的文件只能有一个main函数哦  [quote=引用 7 楼 zhao4zhong1 的回复:] 搜“跟我一起写makefile”  这个确实有用，如果你要学Makefile的话[/quote] 谢谢捧场！

同时编译的文件只能有一个main函数哦  引用 7 楼 zhao4zhong1 的回复:搜“跟我一起写makefile”  这个确实有用，如果你要学Makefile的话

不是Makefile的问题，而是编译命令不会使用，更确切来说是对C语言的编译链接不熟悉。熟悉C语言的编译链接过程再去好好学Makefile的使用吧。这样才能事半功倍。

不能定义两个main程序的。编译器不知道该用哪个main作为目标程序了。


Question: 归并排序小问题

r是辅助数组，merge 完后要拷贝回去。 加两行代码就可以了。 如下 #include <stdio.h>  void merge (int *a, int *r, int s, int m, int n) {     int i = s, j = m+1, k = s;      while (i <= m && j <= n)     {         if (a[i] <= a[j])             r[k++] = a[i++];         else             r[k++] = a[j++];     }      if (i <= m)     {         while (i <= m)             r[k++] = a[i++];     }     else if (j <= n)     {         while (j <= n)             r[k++] = a[j++];     }     // copy back     for( i = s; i <=n; i++ )         a[i] = r[i]; }  void mergesort (int *a, int *r, int s, int n) {     int m;      if (s == n)         ;     else     {         m = (s + n) / 2;         mergesort(a, r, s, m);         mergesort(a, r, m+1, n);         printf("s=%d, m=%d, n=%d\n", s,m,n);         merge(a, r, s, m, n);         printf("==>\n");     } }


Question: read被阻塞了，莫名其妙，求帮忙

代码如下： void *socthread() { 		timeout.tv_sec = 3;         timeout.tv_usec = 0; 		while(1) 		{ 			printf("\nSpiMaster_V35: create socket");fflush(stdout); 			 			if ((listenfd = socket(AF_INET, SOCK_STREAM, 0)) == -1) 			{                           //调用socket创建用于监听客户端的socket 				printf("\nSpiMaster_V35: create socket failed");fflush(stdout); 				exit(1); 			}  			int opt = SO_REUSEADDR; 			setsockopt(listenfd, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt));  //设置socket属性  			 			int flags = fcntl(listenfd, F_GETFL, 0); 			fcntl(listenfd, F_SETFL, flags|O_NONBLOCK); 			 			bzero(&server, sizeof(server)); 			server.sin_family = AF_INET; 			server.sin_port = htons(20002); 			server.sin_addr.s_addr = htonl(INADDR_ANY);  			printf("\nSpiMaster_V35: bind");fflush(stdout); 			 			if (bind(listenfd, (struct sockaddr *)&server, sizeof(struct sockaddr)) == -1) 			{                           //调用bind绑定地址 				printf("\nSpiMaster_V35: Bind error.");fflush(stdout); 				exit(1); 			}  			printf("\nSpiMaster_V35: listen");fflush(stdout); 			 			if (listen(listenfd, BACKLOG) == -1) 			{                           //调用listen开始监听 				printf("\nSpiMaster_V35: listen() error\n");fflush(stdout); 				exit(1); 			}  			printf("\nSpiMaster_V35: listen end");fflush(stdout); 			 			//初始化select 			maxfd = listenfd; 			maxi = -1; 			for (i = 0; i < FD_SETSIZE; i++) 			{ 				client[i].fd = -1; 			} 			FD_ZERO(&allset);           //清空 			FD_SET(listenfd, &allset);  //将监听socket加入select检测的描述符集合 			//printf("\nspi_master: loop start");fflush(stdout); 			while (1) 			{ 				usleep(10000); 				//processMonWrite(MON_TCP_SERVER_FLAG, TcpSemId, PShmBuf); 				struct sockaddr_in addr; 				rset = allset; 				//printf("\nspi_master: begin select。。。。。。");fflush(stdout); 				nready = select(maxfd + 1, &rset, NULL, NULL, &timeout);    //调用select 				 				if (nready == -1) 				{ 					//select错误，退出程序  					printf("\nspi_master_V35: Select() error, exit(%d).", nready);fflush(stdout); 					break; 				} 				else if (nready == 0) 				{ 					//再次轮询 					//printf("\nspi_master: Select() NG, continue(%d).", nready);fflush(stdout); 					continue; 				} 				else 				{ 					//printf("\nspi_master: Select() OK", nready);fflush(stdout); 				}  				 				if (FD_ISSET(listenfd, &rset)) 				{                       //检测是否有新客户端请求 					printf("\nspi_master_V35: Accept a connection.\n");fflush(stdout); 					//调用accept，返回服务器与客户端连接的socket描述符 					sin_size = sizeof(struct sockaddr_in); 					if ((connectfd = 						 accept(listenfd, (struct sockaddr *)&addr, (socklen_t *) & sin_size)) == -1) 					{ 						printf("\nspi_master_V35: Accept() error\n");fflush(stdout); 						continue; 					}  					flagsclient = fcntl(connectfd, F_GETFL, 0);         			fcntl(connectfd, F_SETFL, flagsclient|O_NONBLOCK);  					//将新客户端的加入数组 					for (i = 0; i < FD_SETSIZE; i++) 					{  						if (client[i].fd < 0) 						{ 							char buffer[20]; 							client[i].fd = connectfd;   //保存客户端描述符 							clientfd = connectfd; 							memset(buffer, '0', sizeof(buffer)); 							sprintf(buffer, "Client[%.2d]", i); 							memcpy(client[i].name, buffer, strlen(buffer)); 							client[i].addr = addr; 							memset(buffer, '0', sizeof(buffer)); 							sprintf(buffer, "Only For Test!"); 							memcpy(client[i].data, buffer, strlen(buffer)); 							printf(" spi_master: Add a new connection. clientid=%d\n",connectfd); 							printf("\nSocket clientfd=%d.\n",clientfd);fflush(stdout); 							fflush(stdout); 							break; 						} 					} 					 					if (i == FD_SETSIZE) 						printf("\nSpiMaster_V35: Too many clients\n");fflush(stdout); 					FD_SET(connectfd, &allset); //将新socket连接放入select监听集合 					if (connectfd > maxfd) 						maxfd = connectfd;  //确认maxfd是最大描述符 					if (i > maxi)       //数组最大元素值 						maxi = i; 					if (--nready <= 0) 						continue;       //如果没有新客户端连接，继续循环 				} 				 				for (i = 0; i <= maxi; i++) 				{ 					//shi 600 S 					//processMonWrite(MON_TCP_SERVER_FLAG, TcpSemId, PShmBuf); 					 					if ((sockfd = client[i].fd) < 0)    //如果客户端描述符小于0，则没有客户端连接，检测下一个 						continue; 					if(client[i].fd != clientfd) 					    continue; 					// 有客户连接，检测是否有数据 					if (FD_ISSET(sockfd, &rset)) 					{ 						printf("\nTCPServer: Receive from connect fd[%d].\n", client[i].fd);fflush(stdout); 						memset(recvbuf, 0, MAX_DATA_SIZE); 						if ((n = read(sockfd, recvbuf, READ_BUF_SIZE)) == 0) 						{               //从客户端socket读数据，等于0表示网络中断 						    printf("\n fd close.fd=%d,errno=%d\n",sockfd,errno); 							close(sockfd);  //关闭socket连接 							FD_CLR(sockfd, &allset);    //从监听集合中删除此socket连接 							client[i].fd = -1;  //数组元素设初始值，表示没客户端连接 						} 						else 							readinfo(&client[i], recvbuf, n); //接收到客户数据，开始处理 						//if (--nready <= 0) 						//    break;      //如果没有新客户端有数据，跳出for循环回到while循环 					} 				} 				 			} 			close(listenfd); 	    } }

各位，我把clientfd设置成非阻塞的，然后运行1天左右，还是会阻塞，同时客户端write也失败了并且错误码是11

引用 1 楼 hnwyllmm 的回复:clientfd，楼主你的这个套接字没有设置非阻塞模式啊 select仅在可读或timeout时返回，如果不是timeout, 此时去read不应该阻塞（socket可以使block的）。 会不会是被其他线程读取了？

楼上正解。不过干嘛要用非阻塞呢，没数据时就在那等着呗

引用 5 楼 ufotree 的回复:谢谢各位回复， accept获得的fd在linux下默认是阻塞的吗？ 是

引用 2 楼 ufotree 的回复:clientfd是客户端连过来的fd，这个怎么设置非阻塞？ 跟设置listenfd的方法一样的，调用一下就好了

你的select使用有点问题吧，或者全部代码帖来可分析，select 在读取数据是不会阻塞的，但需要while循环设置socket到fd_set

你发现阻塞了就说明是的  亲，像这种问题，自己试一下就出来了，我觉得比问出答案更好

谢谢各位回复， accept获得的fd在linux下默认是阻塞的吗？

引用 2 楼 ufotree 的回复:clientfd是客户端连过来的fd，这个怎么设置非阻塞？   不是select listensocket么，当有FD_ACCEPT 的时候就accpet 不就得到客户端socket了？ 然后就  cntl(clientfd, F_SETFL, flags|O_NONBLOCK);

楼主你只是把listenfd设置为非阻塞，但对于真正用来接收数据的套接字clientfd却没有设置成非阻塞。

clientfd是客户端连过来的fd，这个怎么设置非阻塞？

clientfd，楼主你的这个套接字没有设置非阻塞模式啊


Question: windows下的c/c++连接oracle

顶啊，不要沉啊、。。

oci可以的

用C/C++调用ADO来连接和操作ORACLE，绝对是个坑。  引用 5 楼 focuslight 的回复:用ADO连接, 要不调用第三方库

用ADO连接, 要不调用第三方库

调用OCCI。

参考demo\*.*： Program Name                              Features Illustrated cdemo81.c                                 Using basic SQL processing with release 8 and later functionality. cdemo82.c                                 Performing basic processing of user-defined objects. cdemocor.c                                Using complex object retrieval (COR) to improve performance. cdemodr1.c,cdemodr2.c,cdemodr3.c          Using INSERT/UPDATE/DELETE statements with RETURNING clause used with basic datatypes, LOBs and REFs. cdemodsa.c                                Describing information about a table. cdemodsc.c                                Describing information about an object type. cdemofo.c                                 Registering and operating application failover callbacks. cdemolb.c                                 Create and insert LOB data and then read, write, copy, append and trim the data. cdemolb2.c                                Writing and reading of CLOB/BLOB columns with stream mode and callback functions. cdemolbs.c                                Writing and reading to LOBs with the LOB buffering system. cdemobj.c                                 Pinning and navigation of REF object. cdemorid.c                                Using INSERT, UPDATE, DELETE statements and fetches to get multiple rowids in one round-trip. cdemoses.c                                Using session switching and migration. cdemothr.c                                Using the OCIThread package. cdemosyev.c                               Registering predefined subscriptions and specifying a callback function to be invoked for client notifications (for more information about Advanced Queuing, see Oracle Streams Advanced Queuing User’s Guide and Reference). ociaqdemo00.c,ociaqdemo01.c,ociaqdemo02.c Advanced queuing. cdemodp.c,cdemodp_lip.c                   Loading data with the direct path load functions. cdemdpco.c                                Loading a column object with the direct path load functions. cdemdpno.c                                Loading a nested column object with the direct path load functions. cdemdpin.c                                Loading derived type (inheritance) - direct path. cdemdpit.c                                Loading an object table with inheritance - direct path. cdemdpro.c                                Loading a reference with the direct path load functions. cdemdpss.c                                Loading SQL strings with the direct path load functions. cdemoucb.c,cdemoucbl.c                    Using static and dynamic user callbacks. cdemoupk.c,cdemoup1.c,cdemoup2.c          Using dynamic user callbacks with multiple packages. cdemodt.c                                 Datetime and interval example. cdemosc.c                                 Scrollable cursor. cdemol2l.c                                Accesses LOBs using the LONG API. cdemoin1.c                                Inheritance demo which modifies an inherited type in a table and displays a record from the table. cdemoin2.c                                Inheritance demo to do attribute substitutability. cdemoin3.c                                Inheritance demo that describes an object, inherited types, object tables, and a sub-table. cdemoanydata1.c                           Anydata demo. Inserts and selects rows to and from anydata table. cdemoanydata2.c                           Anydata demo. Creates a type piecewise using OCITypeBeginCreate() and then describes the new type created. cdemosp.c                                 Session pooling. cdemocp.c                                 Connection pooling. cdemocpproxy.c                            Connection pooling with proxy functionality. cdemostc.c                                Statement caching. cdemouni.c                                Program for OCI UTF16 API. nchdemo1.c                                Shows nchar implicit conversion feature and codepoint feature.

怎么没人啊。。。