Question: 任意长度数组的全组合

这是不重复全排列，不是组合，组合是顺序无关的。

#include <stdio.h> #include <stdlib.h>  void   Comb(char array[], int n);  int main(void) {     char   array[10] = {'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J'};      Comb(array, 3);     return 0; /*************************************** 输出结果： A B C AB AC BC ABC ***************************************/ }   /* 全组合 */ /* 打印任意长度数组的全组合 */ /* 二进制转化法，模拟手动按顺序枚举所有组合 */ void Comb(char array[], int n) {     int    i, j, m, flag, cnt;     int*   buf;      buf = (int*) calloc(n, sizeof(int));      for (m = 1; m <= n; m++) {         /* 初始化 */         for (i = 0; i < n; i++)             buf[i] = i < m ? 1 : 0;          while (1) {             /* 输出一个组合 */             for (i = 0; i < n; i++)                 if (buf[i]) printf("%c", array[i]);             printf("\n");              /* 检查是否已经列出所有的组合，如果后m位都为1，说明已列出所有组合 */             flag = 1;             for (i = n - m; i < n; i++) {                 if (buf[i] == 0) {                     flag = 0;                     break;                 }             }             if (flag) break;              /* 将右边第1个“10”组合变成“01” */             for (i = n - 1; i > 0; i--) {                 if (buf[i] == 0 && buf[i - 1] == 1) {                     buf[i] = 1;                     buf[i - 1] = 0;                     break;                 }             }              /* 如果最后一位为1，则将右端所有连续的1移动到第i位之后，其它位设为0 */             if (buf[n - 1]) {                 for (j = n - 1, cnt = 0; j > i; j--) {                     if (buf[j] == 0)                         break;                     cnt++;                 }                 for (j = i + 1; j < n; j++) {                     if (j < i + 1 + cnt)                         buf[j] = 1;                     else                         buf[j] = 0;                 }             }         }     } }

引用 6 楼 vilnies 的回复:补上代码void   print(char array[], int print_len , char * last) { 	for( int i = 0 ; i < (print_len - 1 ) ; i++) 		printf("%c" , array[i]); 	printf("%c\n", *last); }  void   Comb(char array[], int n) {	 	for( int i = 0 ; i < n ; i++ ) 	{		  		for( int last =  i ; last < n ; last ++) 		{ 			print(array , i + 1 ,&array[last] ); 		} 	} } int main(void) { 	char   array[] = {'A', 'B', 'C', 'D', 'E'}; 	Comb(array, 5); 	return 0; }  可能我给的示例误导了你的算法，我想要的是全组合，你的运行结果长度为2以上时，全是以A开头的 我想要的是，AB AC AD AE BC BD BE CD CE DE ABC ABD...  不过我改了一下最初的方法，达到了要求，下面上代码

分析变化因素有2: 1.打印长度.规律是递增,初始值为1,最大值为n.优先度最高 2.打印串最后一个char.规律也是递增,且初始值为原数组中该位置的值,最大值为原数组的最后一个.  另外,其余的位置的值和原数组顺序一致.  所以两重循环就可以了.

循环2^n次，写个getnext函数判断下个值是多少，比如E下一个是AB等等

此贴应该对LZ颇有参考价值。 http://bbs.csdn.net/topics/390631458

用递归可以了

思路有4，供参考： 1. 将每个单独结果存起来，然后排序，再输出：耗费空间大，只能使用小批量组合；    （小变种：仍然是将结果存起来，不过是组合所有结果，将每个结果按字母规律存      储在存储空间的适合偏移位置，相信更难控制） 2. 每个结果存起来，然后使用可以定位光标位置的输出（如conio）； 3. 调整枚举算法，让其输出按特定规律。


Question: 数据结构中的线性表程序

个人觉得 除了主函数有些长， 其他都很好了 注释写多了也不是什么好事

main函数主要调用其他函数，然后把函数之间的结构写好，看着会比较舒服啊。

1. 除了声明的地方一句注释都没有？这貌似不太好。个人觉得关键、复杂的语句注释一下比较好。还有在什么的时候不仅仅只解释这个函数干嘛的。我一般用下面这种方式，仅供参考： /****************************************** * 函数名称：  * 入口参数：  * 返 回 值：  * 全局变量：  * 调用函数： * 功能描述：  * 备    注： *******************************************/  2. 变量最好不要都是些i,p,e,l之类的，最好让别人一看就知道你这个变量是干嘛的。

main函数体不要搞这么长了！ 丢一个接口出来实现就好了！

整体不错，主函数需要减负！  个人习惯是把main函数放到所有函数的最后

引用 4 楼 N_sev7 的回复:个人觉得 除了主函数有些长， 其他都很好了 注释写多了也不是什么好事 我的建议是无用的注释多了不是好事，但是对于楼主现在的注释情况是太少了，每个函数最好都添加一些注释，在函数里关键点，不易理解的地方都可以添加一些注释。 写代码的人，多能体会以下看代码的人，这样的代码才比较人性化@


Question: 求助！！！有符号二进制转化成十进制

//将1-6字节不定长有符号二进制byte数组转为十进制数 #include <stdio.h> #include <stdlib.h> #include <time.h> unsigned char b[6]; int t,n,i,s; __int64 d; int main() {     srand(time(NULL));      for (t=0;t<20;t++) {         n=1+rand()%6;         d=0i64;         for (i=0;i<n;i++) {             b[i]=rand()%256;             if (i==0) {                 if (b[i]>127) s=1;                 else          s=0;             }             d=d*256i64+(__int64)b[i];             printf("%02X ",b[i]);         }         if (s) d=d-(1i64<<(n*8));         printf("=> %I64d\n",d);     }     return 0; } //A9 EC 7A 3C 63 96 => -94641848556650 //10 01 B3 => 1049011 //42 06 => 16902 //33 85 EF 7D => 864415613 //26 66 => 9830 //B3 8E B8 F7 31 0E => -84049406775026 //D1 FE => -11778 //C7 67 93 => -3709037 //DC => -36 //DB 94 28 22 46 14 => -40045601733100 //C0 => -64 //D2 0D 14 08 85 B3 => -50521364200013 //06 23 => 1571 //3C 5C A5 81 => 1012704641 //F8 0A E0 2D => -133504979 //9E => -98 //F1 C8 7C => -931716 //8F => -113 //52 51 C3 => 5394883 //64 9C 9B => 6593691 //

引用 6 楼 my_live_123 的回复:分清大小端，取多少字节，你告知，从高位到低位循环遍历每一位，每次循环把上次的结果左移一位，即乘2.循环结束即搞定了！ 费那事儿！

不定长那么哪个是符号位呢？

int BinToDec( BYTE * p, int nCount ) {     int n = 0;     for( int i = 0; i < nCount; ++ i )     {          n = ( n * 2 ) + p[ i ];     }     return n; }

大数运算用GMP库，参考http://blog.csdn.net/turingo/article/details/8249799  引用 楼主 u012815293 的回复:用C语言实现，将1-6字节不定长有符号二进制byte数组转为十进制数


Question: C语言快速的排序函数看不懂了

快排的原理先看看吧，光看代码有多大用啊

问题2：swap(int v[],int i,int j)这句意思是不是将数组v和整型i,j交换位置？如果是为什么要写这样一句啊？如果不是那是什么意思呢？ 答：这条语句的意思是将数组v的第i个和第j个变量交换位置。如果你连这句话都看不懂，那我建议你不要研究什么算法了，先把基础知识掌握好。

快排，简单写就一递归而已。

先把你传进来的函数每个参数的意思理解清楚吧， 网上再看看快排序的理论知识，自己画画！

你应该先看懂快排是什么意思，然后再来看代码的部分。我觉得你连快排的原理还没搞懂。

引用 2 楼 caozhy 的回复:这根本就不是一个合法的程序，连括号都不匹配。一个错误的程序不值得讨论。 程序没错误，就是不完整

引用 3 楼 junlinfushi 的回复:话说，你理解一下快速排序算法，自己都可以写出来了。快速排序不难的 这是我在网上找的，不是我写的

话说，你理解一下快速排序算法，自己都可以写出来了。快速排序不难的

这根本就不是一个合法的程序，连括号都不匹配。一个错误的程序不值得讨论。

话说我也看不懂


Question: 一个基于SDK32和程序, 想实现以下这样的功能, 请给一个思路.

是手机开发吗?  没有开发过手机程序,  不过我猜想, 肯定有什么方法能拦截掉这个事件, 然后自己作处理, 不过, 这可能是启动器响应的多.

MFC更好一点吧 也可以在里面使用SDK


Question: 求〔C＋＋〕表达式分析的问题，输入“C＋＋表达式”，输出“语法树”...

还是用LALR吧, 你上面列的几个操作符在 LALR 下都没有二义性.. 你只要不像cpp样把你的脚本也搞个无比无聊的GP的话基本上用 LALR 压力不大 . 随便找个现成的LALR parser 吧, bison 啥的 .. 或者像我一样写个预处理器, 直接在 C 代码里写 EBNF/RegExp 然后自动生成对应的 PDA/DFA .. 我无聊的写了一个支持UNICODE的DFA的生成器 ...  我打算在无聊的时候写一个可以运行在RTOS上的, 多线程的, 可选GC的, 可JIT运行也可以直接生成对应的C语言目标代码的一个脚本.. 脚本的解析器准备用脚本自己自举.. 运行环境用C写..

C,C++ 函数调用也是表达式，除非简化一下（不考虑函数），否则比较困难。 但是不考虑函数，构造函数，要不要考虑呢？ 至于同时可以看作，单目运算符和双目运算符的运算符； 如果缺少操作数 就是单目运算。 如果不缺少就是双目运算符，把他们当作两个运算符处理就是了。 如果单目运算符，有两个不同含义也当作两个运算符处理就是了。  如果处理 new  注意 placement new 和 一般的new 的不同。      new 和 new [] 的不同。      p = new A;     new (p) A;//placement new     p = new A[10];     new (p) A[10];//placement new       我不是大牛，只是提供点意见。可以吗？

引用 18 楼 sinservice 的回复:用龙书前100页，写一个YACC程序。  如果觉得难，我可以给你我写的参考代码。  我写的这个YACC，对一个复杂到6000个状态的文法集，用40秒（在我原来破机器上）。  这位仁兄，请将你写的YACC和使用说明发到我邮箱好么？观摩学习..... sdhexu@hotmail.com

引用 2 楼 sdhexu 的回复:对于大牛的疑惑............     论坛里真的有大牛么？我所看到的大牛，只是分多一些而已....对于简单的问题，大家都抢着去回答，都以大牛的姿态去指点人家.....对于复杂的问题，都视而不见.........    有木有！！！！！ 我的确会选择性回答，但并不是视而不见，只是不想误人子弟而已，因为我本身就不是大牛...论坛的话，主要还是讨论问题，没有说谁一定是对的。除了个别人会以大牛姿态来指点别人，坚持说自己一定是对的，一定要别人相信自己的方法，但这类人毕竟是少数。  你这个问题，用LR(1)、LALR应该都可以，但如果你的输入很复杂的话，还是会有问题的。我对编译原理不熟就不多说了。和楼上说的一样，建议参考下龙书的YACC。

使用 Flex & Bison，可以解决你这些问题。。easy

参考Tiny C相关源代码。

参考gcc相关源代码。

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

我说明一下：     我研究编译器理论N年了，但我一直否弃使用LALR，我写的YACC生成的表是 标准 LR（1）的。

引用 15 楼 taodm 的回复:void f() #ifdef X ; #else {return;} #endif 这你准备怎么整？ 如果你想做一个完完全全的C++代码分析器，我的建议是放弃，没戏。 我就是要搞一个完完全全的C＋＋代码解释器。用于我的游戏引擎，作为脚本系统。  void f() 是一个语句。 #ifdef x 是预编译指令。这些都容易解析的。  我词法分析器已经搞定，语法分析就差表达式了。语义分析就是进行一些错误检查，然后就是目标代码了。我相信，能够实现的。

先好好考虑一下，晚些时候再回复你

引用 12 楼 uuuououlcz 的回复:class::static和namespace::fun的::，?:三目运算符，,逗号运算符，各种 operation= 运算符，还是比较复杂的  嗯嗯。是的。  所以递归下降啊，很麻烦。

引用 9 楼 sdhexu 的回复:[quote=引用 7 楼 uuuououlcz 的回复:] lz的表达式可包含sizeof()、new、delete还有各种cast？  是的，不过new 和 delete，我会把他们当作一个“语句”来处理。[/quote] 确切的说，delete做为语句来处理，new 还是一个表达式。new是一个单目运算符。不过它很容易识别，不像 +、－、*、&，既可以单目，也可以双目。

如果还要具备检测语法错误的功能的话，貌似就有点难了

引用 7 楼 uuuououlcz 的回复:lz的表达式可包含sizeof()、new、delete还有各种cast？  是的，不过new 和 delete，我会把他们当作一个“语句”来处理。

引用 6 楼 taodm 的回复:你想太多了。  好吧。即便是我用递归下降分析，那么怎么区别一个运算符是单目的，还是双目的啊。请指点。谢谢啊。

lz的表达式可包含sizeof()、new、delete还有各种cast？


Question: 一个关于pipe的小问题

谢谢各位的热心回帖

引用 楼主 wanren13 的回复:如果在一个程序里pipe分别让子进程和父进程写读，父进程需要使用wait()函数吗？  例如：  int fd[2]; pipe[fd];  pid_t pid = fork();  if(pid == 0){ close(fd[0]); write(fd[1], "Hello", 5); }  else if(pid > 0){ wait(NULL); //这里需要用wait吗？ char buf[BUFSIZ]; close(fd[1]); read(fd[0], buf, BUFSIZ); }   个人感觉，如果用了read，进程就会被阻挡，直到子进程的write结束，所以不用wait子进程。 但是我不是很确定，不知道这里有没有其他的例外？  请版里的大侠指点一二，小弟不胜感激。 可以放心的，可以不加wait(NULL); read会阻塞直到写完的。

int main(void) {     pid_t   pid;     int     status;      if ((pid = fork()) < 0)         err_sys("fork error");     else if (pid == 0)              /* child */         exit(7);      if (wait(&status) != pid)       /* wait for child */         err_sys("wait error");     pr_exit(status);                /* and print its status */      if ((pid = fork()) < 0)         err_sys("fork error");     else if (pid == 0)              /* child */         abort();                    /* generates SIGABRT */      if (wait(&status) != pid)       /* wait for child */         err_sys("wait error");     pr_exit(status);                /* and print its status */      if ((pid = fork()) < 0)         err_sys("fork error");     else if (pid == 0)              /* child */         status /= 0;                /* divide by 0 generates SIGFPE */      if (wait(&status) != pid)       /* wait for child */         err_sys("wait error");     pr_exit(status);                /* and print its status */      exit(0); }

read函数默认是会阻塞，因此只要有内容写入我觉得可以读到内容的，wait的作用是阻塞等待某个子进程退出后做清理工作的，LZ不用调wait来让子进程退出后再让read函数读管道中的内容。 另外pipe是个函数，调用的时候用pipe(fd);

嗯，需要的，不过不是在那个位置，而是在read之后的。

引用 5 楼 cfjtaishan 的回复:[quote=引用 2 楼 wanren13 的回复:] [quote=引用 1 楼 cfjtaishan 的回复:] 管道是单向的，若父进程向管道里写，子进程从管道里读，那么若父进程不写在进程就会阻塞着去读。即，如果管道里有数据那么就会告诉子进程去都，反之依然。  你好，谢谢你的回答。  在我提供的例子里，会不会父进程先进行，子进程还没有机会做任何事情，父进程就先结束了？[/quote] 父进程先执行或者子进程先执行都是可能的，若父进程先执行，但是子进程没有执行完，父进程是不会退出的，因为wait();没有执行。[/quote]  看来是我的问题不够清楚。。。  我就是想问在我提供的例子里，wait（）是必须的吗？

引用 3 楼 user-5 的回复:没有例外哈，read循环读到0为止，再进入wait回收一下资源就可以了。  所以说不需要加wait是吗？

引用 2 楼 wanren13 的回复:[quote=引用 1 楼 cfjtaishan 的回复:] 管道是单向的，若父进程向管道里写，子进程从管道里读，那么若父进程不写在进程就会阻塞着去读。即，如果管道里有数据那么就会告诉子进程去都，反之依然。  你好，谢谢你的回答。  在我提供的例子里，会不会父进程先进行，子进程还没有机会做任何事情，父进程就先结束了？[/quote] 父进程先执行或者子进程先执行都是可能的，若父进程先执行，但是子进程没有执行完，父进程是不会退出的，因为wait();没有执行。

没有例外哈，read循环读到0为止，再进入wait回收一下资源就可以了。

引用 1 楼 cfjtaishan 的回复:管道是单向的，若父进程向管道里写，子进程从管道里读，那么若父进程不写在进程就会阻塞着去读。即，如果管道里有数据那么就会告诉子进程去都，反之依然。  你好，谢谢你的回答。  在我提供的例子里，会不会父进程先进行，子进程还没有机会做任何事情，父进程就先结束了？


Question: 关于const的实验

引用 3 楼 max_min_ 的回复:http://blog.csdn.net/yby4769250/article/details/7359278 看看 NB

常量折叠现象而已！很正常，没什么大惊小怪的

编译通不过。改成 const int * b = &a可通过。


Question: C语言 新人求助指针问题！

引用 8 楼 u012620726 的回复:[quote=引用 6 楼 u012388912 的回复:] [quote=引用 2 楼 max_min_ 的回复:] 1 定义的常量指针数组，内容不可改，只可读！所以会引起内存会出错 2 里面的判断if条件不是并列关系，而是if elseif关系 ，不然换了以后，又会换回来的！  已经修改代码中的bug 看看  #include <stdlib.h> #include<stdio.h> int main() {     char *t;      int i;     char p[3][10]={"AbcDEfG","hIJKlmN","ZyxWVu"};     for(i=0;i<3;i++)     {            puts(p[i]);         for(t = p[i];*t !='\0'; t++)         {                if(*t >= 'A' && *t<= 'Z')             {                    *t=(*t) +32;             }                else if(*t>= 'a' && *t<='z')             {                    *t=(*t) - 32;              }            }            puts(p[i]);     }        return 0; }     题目说是指针数组定义3个字符串,, 请问下 如果原先只定义了char *p[3]; 接下来让用户输入字符串，该怎么让指针指向字符串呢? 如果scanf("%s",&p[0]); 直接这样不行啊。。[/quote]在定义个字符串，然后strcpy可以不？[/quote] 应该不怎么好吧……

char p[3][20]={"AbcDEfG","hIJKlmN","ZyxWVu"}； char *p[3]={"AbcDEfG","hIJKlmN","ZyxWVu"}; 好好理解下这两种定义的区别  变量的存储区域： 常量区 静态区 栈区 堆区 懂得各种变量的存储区域及各个区域的不同就自己会解决了

引用 2 楼 max_min_ 的回复:1 定义的常量指针数组，内容不可改，只可读！所以会引起内存会出错 2 里面的判断if条件不是并列关系，而是if elseif关系 ，不然换了以后，又会换回来的！  已经修改代码中的bug 看看  #include <stdlib.h> #include<stdio.h> int main() {     char *t;      int i;     char p[3][10]={"AbcDEfG","hIJKlmN","ZyxWVu"};     for(i=0;i<3;i++)     {            puts(p[i]);         for(t = p[i];*t !='\0'; t++)         {                if(*t >= 'A' && *t<= 'Z')             {                    *t=(*t) +32;             }                else if(*t>= 'a' && *t<='z')             {                    *t=(*t) - 32;              }            }            puts(p[i]);     }        return 0; }     嗯

引用 6 楼 u012388912 的回复:[quote=引用 2 楼 max_min_ 的回复:] 1 定义的常量指针数组，内容不可改，只可读！所以会引起内存会出错 2 里面的判断if条件不是并列关系，而是if elseif关系 ，不然换了以后，又会换回来的！  已经修改代码中的bug 看看  #include <stdlib.h> #include<stdio.h> int main() {     char *t;      int i;     char p[3][10]={"AbcDEfG","hIJKlmN","ZyxWVu"};     for(i=0;i<3;i++)     {            puts(p[i]);         for(t = p[i];*t !='\0'; t++)         {                if(*t >= 'A' && *t<= 'Z')             {                    *t=(*t) +32;             }                else if(*t>= 'a' && *t<='z')             {                    *t=(*t) - 32;              }            }            puts(p[i]);     }        return 0; }     题目说是指针数组定义3个字符串,, 请问下 如果原先只定义了char *p[3]; 接下来让用户输入字符串，该怎么让指针指向字符串呢? 如果scanf("%s",&p[0]); 直接这样不行啊。。[/quote]在定义个字符串，然后strcpy可以不？

引用 6 楼 u012388912 的回复:[quote=引用 2 楼 max_min_ 的回复:] 1 定义的常量指针数组，内容不可改，只可读！所以会引起内存会出错 2 里面的判断if条件不是并列关系，而是if elseif关系 ，不然换了以后，又会换回来的！  已经修改代码中的bug 看看  #include <stdlib.h> #include<stdio.h> int main() {     char *t;      int i;     char p[3][10]={"AbcDEfG","hIJKlmN","ZyxWVu"};     for(i=0;i<3;i++)     {            puts(p[i]);         for(t = p[i];*t !='\0'; t++)         {                if(*t >= 'A' && *t<= 'Z')             {                    *t=(*t) +32;             }                else if(*t>= 'a' && *t<='z')             {                    *t=(*t) - 32;              }            }            puts(p[i]);     }        return 0; }     题目说是指针数组定义3个字符串,, 请问下 如果原先只定义了char *p[3]; 接下来让用户输入字符串，该怎么让指针指向字符串呢? 如果scanf("%s",&p[0]); 直接这样不行啊。。[/quote] 不是，没有给每指针分配内存空间  for(int i =0 ; i < 3; i++) {     p[i] = (char *)malloc(sizeof(char) * 36); //每个指针分配36个空间     scanf("%s", p[i]); //不需要取地址，它本身就是首地址！

引用 2 楼 max_min_ 的回复:1 定义的常量指针数组，内容不可改，只可读！所以会引起内存会出错 2 里面的判断if条件不是并列关系，而是if elseif关系 ，不然换了以后，又会换回来的！  已经修改代码中的bug 看看  #include <stdlib.h> #include<stdio.h> int main() {     char *t;      int i;     char p[3][10]={"AbcDEfG","hIJKlmN","ZyxWVu"};     for(i=0;i<3;i++)     {            puts(p[i]);         for(t = p[i];*t !='\0'; t++)         {                if(*t >= 'A' && *t<= 'Z')             {                    *t=(*t) +32;             }                else if(*t>= 'a' && *t<='z')             {                    *t=(*t) - 32;              }            }            puts(p[i]);     }        return 0; }     题目说是指针数组定义3个字符串,, 请问下 如果原先只定义了char *p[3]; 接下来让用户输入字符串，该怎么让指针指向字符串呢? 如果scanf("%s",&p[0]); 直接这样不行啊。。

字符串常量存放在只读数据段，所以不可以修改的。

改为char p[3][20]={"AbcDEfG","hIJKlmN","ZyxWVu"};即可； char *p[3]={"AbcDEfG","hIJKlmN","ZyxWVu"};会成为常量指针，其内容不允许被修改。  引用 楼主 u012388912 的回复://题目:用指针数组方式定义3个字符串,然后遍历个字符串,把里面的小写字母改 大写,大写字母改小写。  //编译环境:C-Free 5.0 #include<stdio.h> int main() { 	char *t;  	int i; 	char *p[3]={"AbcDEfG","hIJKlmN","ZyxWVu"}; 	for(i=0;i<3;i++) 	{ 	   for(t=p[i];*t!='\0';t++) 	   { 	     if(*t>='A'&&*t<='Z') 	     *t=*t+32; 	     if(*t>='a'&&*t<='z') 	     *t=*t-32; 	   } 	   puts(p[0]); 	   puts(p[1]); 	   puts(p[2]);     }  }	    一点运行就停止工作了。。找了很久不知道哪错了， 请教各位高手！谢谢！


Question: C语言程序问题

char *p;  	char s1[] = "The summer soldier, the sunshine patriot";   	p = strtok(s1, " "); 	printf(p); 	do{ 		p = strtok(NULL, ", "); //('\0', ", "); 		if (p) printf("|%s\n", p); 	}while(p);

引用 4 楼 zhao4zhong1 的回复:fgets(linestr,MAXLEN,stdin); ... #include <stdio.h> char s[]="123 ab 4"; char *p; int v,n,k; void main() {     p=s;     while (1) {         k=sscanf(p,"%d%n",&v,&n);         printf("k,v,n=%d,%d,%d\n",k,v,n);         if (1==k) {             p+=n;         } else if (0==k) {             printf("skip char[%c]\n",p[0]);             p++;         } else {//EOF==k             break;         }     }     printf("End.\n"); } //k,v,n=1,123,3 //k,v,n=0,123,3 //skip char[ ] //k,v,n=0,123,3 //skip char[a] //k,v,n=0,123,3 //skip char[b] //k,v,n=1,4,2 //k,v,n=-1,4,2 //End.

引用 7 楼 max_min_ 的回复:google下 strtok函数！字符串操作 ++ 或者使用strsep函数，可以边解析边和已经解析出来的单词比较；  typedef strcut _tagWORD {     char *word;   //单词内容     int  cnt;     //单词出现的次数 }WORD_OBJ, *WORD_HANDLE; WORD_OBJ   word[64];  可以简单定义成这样的一个数据结构，仅供参考。

google下 strtok函数！字符串操作

非常感谢各位大神！

引用 2 楼 u012811542 的回复:状态机是什么？==那个比较高级了，状态机是编译原理的概念，如果学会的话很有好处。给你个简单的例子：#include <stdio.h>  int main() { 	char c[100]; 	int i=0,nword=0,flag; 	char *p=c; 	gets(c); 	flag = p[0]==' '?0:1;//是否在单词中 	for(;*p!=0;p++){ 		if(flag && *p==' '){//位于单词中，且遇到空格 			nword++; 			flag=0; 		} 		else if(!flag && *p != ' ')//不在单词中，遇到非空格 			flag=1; 	} 	printf("%d\n",nword); 	return 0; }

可以参考编译原理中get token的概念。  引用 2 楼 u012811542 的回复:状态机是什么？==

状态机是什么？==

用状态机，一个字符一个字符的遍历。  引用 楼主 u012811542 的回复:各位大神，紧急求助啊！ 输入一行字符，统计其中单词的个数。各单词之间用空格分隔，空格数可以是多个。才学C,不会啊。求指点TAT!


Question: main函数里创建分离线程

试试在main最后调用pthread_exit(NULL);觉得lz的逻辑很奇特，既然在意main退出与否，又为何要创建分离线程...

引用 3 楼 mymtom 的回复:创建分离线程之后调用在main里pause就行了啊 这个怎么调？什么是pause?

貌似设置了分离线程的属性后就不能够再join了吧  一般采用如下这样的方式：  void *cli_thread_func(void *arg) { //主业务 finish=true;//结束标为true; } int main(int argc, char **argv) {     bool finish=false;//增加变量判断线程函数是否结束     pthread_t cli_thread;       ret = pthread_create(&cli_thread, NULL, cli_thread_func, NULL);       while(!finish)//等待线程函数结束     {        sleep(1);     } }

int main(int argc, char **argv) {     pthread_t cli_thread;      ret = pthread_create(&cli_thread, NULL, cli_thread_func, NULL);     if (ret != 0)       {            printf("create cli_thread_func failed\n");         exit(1);     }    //1   while(1)       sleep(5); //2      pthread_join(cli_thread, NULL); // 等待指定线程结束  }

创建分离线程之后调用在main里pause就行了啊

在主线程退出之前等待子线程退出。。。  waitpid

main函数最后面加死循环。  引用 楼主 baoyuan24 的回复:int main(int argc, char **argv) {     pthread_t cli_thread;       ret = pthread_create(&cli_thread, NULL, cli_thread_func, NULL); 	if (ret != 0)        {	         printf("create cli_thread_func failed\n"); 		exit(1); 	}  } main函数里创建分离线程，如何避免线程函数cli_thread_func没有执行就退出？


Question: 简单4向路径搜索问题，求算法实现，第二贴100分！！

upupup

引用 4 楼 lunat 的回复:你这个不是什么路径搜索问题，不是靠移动棋子能完成的。看你例子应该是计算四联通区域子集的问题。  一针见血~~  引用 5 楼 lin5161678 的回复:俄罗斯方块 直接把方块编码写进去就好了嘛  这个所有都罗列确实可以做到，但是在这个搜索函数外边我还有一层递归，所以想找一个搜索效率高一点的实现。  引用 6 楼 lunat 的回复:最简单的方法，列出所有可能子集（假设所有点可通行且无边界），逐个匹配即可。 事先计算出来，然后哈希配对，相比5楼说的更具体，但和5楼的思想是一致的。

最简单的方法，列出所有可能子集（假设所有点可通行且无边界），逐个匹配即可。

俄罗斯方块 直接把方块编码写进去就好了嘛

引用 2 楼 user-3 的回复:[quote=引用 1 楼 BreathOfDeath 的回复:] 沙发：第一帖链接 http://bbs.csdn.net/topics/390639059/close#  第一贴不是有答案了么？[/quote]  第一帖的答案不满足需求

引用 1 楼 BreathOfDeath 的回复:沙发：第一帖链接 http://bbs.csdn.net/topics/390639059/close#  第一贴不是有答案了么？


Question: (NTDLL.DLL): 0xC0000005: Access Violation.

VC各版本依赖的运行时库不一样。 msvcrt.dll msvcrt20.dll msvcrt40.dll msvcr70.dll msvcr71.dll msvcr90.dll msvcr100.dll msvcr110.dll

First-chance exception in **.exe (NTDLL.DLL): 0xC0000005: Access Violation. 这个的原因应该是句柄没有关闭，一直在消耗，最后造成了内存不足的假象，导致申请资源失败   HEAP: Free Heap block *** modified at *** after it was freed. 这个的原因是因为多个线程同时Delete导致，虽然Delete的不是同一个地址。配置下编译环境可避免该错误。C/C++标签中Code generation->use run-time library选择debug multithreaded或multithreaded 但是在配置环境之后，新的问题来了：改了multithreaded不会出现这个堆错误，但是在调试/运行的时候内存一直泄露，打开任务管理器看着内存就一直增加。singlethread不会的时候内存似乎不会泄露，但是在调试态的时候会出现堆错误？？？

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

问题解决了，还有一个遗留问题：VC配置的各个选项有什么差别（C/C++标签中Code generation->use run-time library）？

更改不同的配置测试后，其中有一个不会出堆错误，生成的可执行程序执行时也不会内存泄露，但是在调试态的时候会泄露。为什么会这样子？是否正常？  VC配置的各个选项有什么差别（C/C++标签中Code generation->use run-time library）？ 调试和直接执行两种方式有什么区别？

引用 5 楼 zhao4zhong1 的回复:检查是否资源泄漏的办法之一： 在任务管理器 进程 查看 选择列 里面选择：内存使用、虚拟内存大小、句柄数、线程数、USER对象、GDI对象 让你的程序(进程)不退出,循环执行主流程很多遍，越多越好，比如1000000次甚至无限循环，记录以上各数值，再隔至少一小时，越长越好，比如一个月，再记录以上各数值。如果以上两组数值的差较大或随时间流逝不断增加，则铁定有对应资源的资源泄漏！ 句柄数一直增加，基本每秒钟增加10个，这个应该是出现在创建线程的时候，函数执行完，线程就结束了，句柄也没管了。应该怎么来关闭这些句柄呢？之前都是做嵌入式的，没涉及到这个，还望多多指点。  First-chance exception in **.exe (NTDLL.DLL): 0xC0000005: Access Violation. 这个报错出现在申请内存的时候，调试态跑一段时间就经常申请不成功了？？？为什么在运行的时候又可以呢？  HEAP: Free Heap block *** modified at *** after it was freed。 今天跑出现过一次这个问题。暂时还没查原因

引用 2 楼 xiaowai0219 的回复:[quote=引用 1 楼 user-2 的回复:] 是不是内存消耗太多引起的！跑起来后，看看内存使用情况！ 有台电脑从编译器进入运行态，跑了两天，刚跑过去一看发现占了1G多的内存。跟这个申请的内存差不多了，难道都没有释放？？？[/quote] 错了！ 也是在调试状态下。只不过另一机器装的是VS2008，运行两天后是开发环境占用内存1G多。比正常状态下多出的内存，跟申请的差不多。  上面提到的报错的情况使在VC6.0下面； 在VS2008下面调试不会报错，它就慢慢的跑着，可能到最后把内存都得耗光了。

引用 1 楼 user-2 的回复:是不是内存消耗太多引起的！跑起来后，看看内存使用情况！ 有台电脑从编译器进入运行态，跑了两天，刚跑过去一看发现占了1G多的内存。跟这个申请的内存差不多了，难道都没有释放？？？

崩溃的时候在弹出的对话框按相应按钮进入调试，按Alt+7键查看Call Stack里面从上到下列出的对应从里层到外层的函数调用历史。双击某一行可将光标定位到此次调用的源代码或汇编指令处。  VMMap 是进程虚拟和物理内存分析实用工具。http://technet.microsoft.com/zh-cn/sysinternals/dd535533

是不是内存消耗太多引起的！跑起来后，看看内存使用情况！


Question: 一个简单路径问题，求算法实现

还是递归读着舒服一些，楼上的代码我没具体测试，有点对不住了。 主要是由于我没有说明白需求，在测试的时候漏了几种情况，再开一贴，欢迎各位大大莅临指导~~   以我目前的需求，肯定会漏掉 漏了这么一种情况：  1 1 1 1 0  1 1 1 0 0  1 1 0 0 0  1 0 0 0 0  0 0 0 0 0

引用 4 楼 BreathOfDeath 的回复:不能走斜线。。  那你第一个例子是怎么走出来的？

不可以走已经经过的位置，需求说的不是很明白。 。

不能走斜线。。

能否走斜线？

有没说明白的地方，例如，棋子从a点走到b点再从b点走到a点，如此4步形成的路径可以吗？

沙发，上面的起始点为： 00000000 00111100 00011100 00010000

引用 12 楼 BreathOfDeath 的回复:[quote=引用 7 楼 uuuououlcz 的回复:] [quote=引用 5 楼 BreathOfDeath 的回复:] 不可以走已经经过的位置，需求说的不是很明白。 。  那就是经典回溯了呀，不用递归的话就用stack模拟递归就好了嘛，对于n比较小的时候（就像你这个n = 4的时候），n重for循环也可以[/quote]   递归来一个[/quote]  貌似不用得到全部路径，只要求多少条路径，那上面的就可以剩下path的复制环节了，allPath也可以不要了，给backtrace传个int& count就行了

嗯，没测试，算是个参考吧  #include <cstring> #include <vector> #include <utility> using namespace std; #define MAX 20  /*   coordinate   0------------>X   |   |   |   |   |   Y */  const int stepKind = 4;                                 //how many kinds of steps const int step[][2] = {{-1,0}, {1,0}, {0,-1}, {0,1}};   //all kinds of steps, step[i][0] is dy while step[i][1] is dx  int row, col;                           //row and column of the board int board[MAX][MAX];                    //state of each position, whether can be passed by bool vis[MAX][MAX];                     //whether the position has been passed by in a path  /**************************************************   whether the position is legal **************************************************/ inline bool outOfBorder(int y, int x) {     return y < 0 || y >= row || x < 0 || x >= col; } /**************************************************   sy is the y coordinate of the start   sx is the x coordinate of the start   stepLeft is the number of steps to move   allPath will contain all possible path, in which pair.first is y while pair.second is x **************************************************/ void backtrace(int sy, int sx, int stepLeft, vector<pair<int,int> >& path, vector<vector<pair<int,int> > >& allPath) {     if(stepLeft <= 0){         allPath.push_back(path);         return;     }      --stepLeft;      int y, x, i;     for(i = 0; i < stepKind; ++i){         y = sy + step[i][0];         x = sx + step[i][1];         if(!outOfBorder(y, x) && !vis[y][x] && board[y][x] == 1){//can move to this position             path.push_back(make_pair(y, x));            //move one step             vis[y][x] = true;                           //mark new position visited             backtrace(y, x, stepLeft, path, allPath);   //search following steps             path.pop_back();                            //cancel move             vis[y][x] = false;                          //cancel mark         }     } } /**************************************************   sy is the start's y coordinate   sx is the start's x coordinate   steps is the number of steps to move   allPath will hold all possible paths   return the number of paths ***************************************************/ int getAllPath(int sy, int sx, int steps, vector<vector<pair<int,int> > >& allPath) {     //initialize     memset(vis, false, sizeof(vis));     allPath.clear();      vector<pair<int,int> > path;     path.push_back(make_pair(sy, sx));     vis[sy][sx] = true;      //search path     backtrace(sy, sx, steps, path, allPath);     return allPath.size(); }

好强大的代码，多谢啦。

//可以把mapping函数修改一下，添加一个步数参数： void mapping(const bool * map,  	int map_width, int map_height,   	int x0, int y0,          size_t steps, 	std::vector<std::vector<std::pair<int, int> > > & routes) {     //...     assert(steps > 0);     //...      //for (size_t i = 0; i < 3; i++)     for (size_t i = 0; i < steps - 1; i++)     //... }  //main函数中调用部分可做相应修改

#include <cstdio> #include <assert.h>  #include <vector> #include <algorithm>  /**  * 计算4步路径所有可能  * @param map 			二值地图，true表示通行，false表示障碍，原点在左上角   * @param map_width 	地图宽度  * @param map_height 	地图高度  * @param x0 			初始位置横坐标  * @param y0 			初始位置纵坐标  * @param routes 		返回所有可能的路径   */  void mapping(const bool * map,  	int map_width, int map_height,   	int x0, int y0,  	std::vector<std::vector<std::pair<int, int> > > & routes) { 	assert(map != NULL); //map不可为空  	assert(map_width > 0 && map_height > 0); //长宽不可为空  	assert(x0 >= 0 && x0 < map_width); //初始点横坐标不可越界  	assert(y0 >= 0 && y0 < map_height); //初始点纵坐标不可越界  	 	assert(map[y0 * map_width + x0]); //初始点应属于可通行点 	 	//上、左、下、右四个方向偏移 	int x_4[] = { 0, -1, 0, 1 }, y_4[] = { -1, 0, 1, 0 };  	int x, y; 	 	typedef std::vector<std::pair<int, int> > route_type; 	typedef std::vector<route_type> 		  route_list; 	 	routes.clear(); 	 	//初始只含有一个长为1的路径 （仅含起始点）  	routes.push_back(route_type(1, std::make_pair(x0, y0)));  	//经过3次遍历扩展，每次扩展根据上一次结果寻找下一步路径  	for (size_t i = 0; i < 3; i++) 	{         size_t k = routes.size();  		// 遍历上一次寻路结果  		for (size_t m = 0; m < k; m++) 		{ 			// 4个方向寻找可行的路径  			for (int j = 0; j < 4; j++) 			{ 				// 取最后一个点为起始点进行偏移  				x = routes[m][i].first + x_4[j]; 				y = routes[m][i].second + y_4[j]; 				 				// 判定移动到的点有效  				if (x >= 0 && y >= 0 && x < map_width && y < map_height &&  					map[y * map_width + x]) 				{ 					// 判定未曾走过	 					if (std::find(routes[m].begin(), routes[m].end(),  							std::make_pair(x, y)) == routes[m].end()) 					{  						// 依据上次寻路结果加上本次可通行点形成一个新的路径  						route_type route(routes[m]); 						route.push_back(std::make_pair(x, y)); 						 						// 添加到寻路结果中  						routes.push_back(route); 					} 				}				 			} 		} 		 		// 删除上次寻路结果  		routes.erase(routes.begin(), routes.begin() + k); 	}  }  int main(int argc, char * argv[]) { 	bool map[25] = {true, true, true, true, false,                     true, true, true, false, false,                     true, true, false, false, false,                     true, false, false, false, false,                     false, false, false, false, false                    };    	printf("------- map --------\n"); 	for (size_t m = 0; m < 5; ++m) 	{ 		for (size_t n = 0; n < 5; ++n) 		{ 			printf("%d ", map[m * 5 + n]); 		} 		printf("\n"); 	}	 		     std::vector<std::vector<std::pair<int, int> > > vec;     mapping(map, 5, 5, 0, 0, vec);  	printf("------- routes -------\n");     for (size_t i = 0; i < vec.size(); ++i) 	{ 		int map_tmp[25] = {0}; 		 		for (size_t m = 0; m < 25; ++m) 		{ 			map_tmp[m] = map[m] ? 1 : 0; 		}	 		 		printf("route:%d\n", i); 		for (size_t j = 0; j < vec[i].size(); ++j) 		{ 			map_tmp[vec[i][j].second * 5 + vec[i][j].first] = 2;	 		} 		 		for (size_t m = 0; m < 5; ++m) 		{ 			for (size_t n = 0; n < 5; ++n) 			{ 				printf("%c ",  					map_tmp[m * 5 + n] == 0 ? '0' :  					map_tmp[m * 5 + n] == 1 ? '1' : '*'); 			} 			printf("\n"); 		} 	}  	return 0; }    运行结果： ------- map -------- 1 1 1 1 0  1 1 1 0 0  1 1 0 0 0  1 0 0 0 0  0 0 0 0 0  ------- routes ------- route:0 * 1 1 1 0  * 1 1 0 0  * 1 0 0 0  * 0 0 0 0  0 0 0 0 0  route:1 * 1 1 1 0  * 1 1 0 0  * * 0 0 0  1 0 0 0 0  0 0 0 0 0  route:2 * * 1 1 0  * * 1 0 0  1 1 0 0 0  1 0 0 0 0  0 0 0 0 0  route:3 * 1 1 1 0  * * 1 0 0  1 * 0 0 0  1 0 0 0 0  0 0 0 0 0  route:4 * 1 1 1 0  * * * 0 0  1 1 0 0 0  1 0 0 0 0  0 0 0 0 0  route:5 * * 1 1 0  * * 1 0 0  1 1 0 0 0  1 0 0 0 0  0 0 0 0 0  route:6 * * 1 1 0  1 * 1 0 0  1 * 0 0 0  1 0 0 0 0  0 0 0 0 0  route:7 * * 1 1 0  1 * * 0 0  1 1 0 0 0  1 0 0 0 0  0 0 0 0 0  route:8 * * * 1 0  1 1 * 0 0  1 1 0 0 0  1 0 0 0 0  0 0 0 0 0  route:9 * * * * 0  1 1 1 0 0  1 1 0 0 0  1 0 0 0 0  0 0 0 0 0

引用 7 楼 uuuououlcz 的回复:[quote=引用 5 楼 BreathOfDeath 的回复:] 不可以走已经经过的位置，需求说的不是很明白。 。  那就是经典回溯了呀，不用递归的话就用stack模拟递归就好了嘛，对于n比较小的时候（就像你这个n = 4的时候），n重for循环也可以[/quote]   递归来一个

bool map[25] = {true, true, true, true, false,                     true, true, true, false, false,                     true, true, false, false, false,                     true, false, false, false, false,                     false, false, false, false, false                    };      std::vector<std::vector<std::pair<int, int> > > vec;     mapping(map, 5, 5, 0, 0, vec);   结果不是预期的

难道BFS不可以吗？ 没仔细看需求

修正了一点问题：   #include <iostream> #include <vector>   /**  * 计算4步路径所有可能  * @param map 			二值地图，true表示通行，false表示障碍，原点在左上角   * @param map_width 	地图宽度  * @param map_height 	地图高度  * @param x0 			初始位置横坐标  * @param y0 			初始位置纵坐标  * @param routes 		返回所有可能的路径   */  void mapping(const bool * map,  	int map_width, int map_height,   	int x0, int y0,  	std::vector<std::vector<std::pair<int, int> > > & routes) { 	assert(map != NULL); //map不可为空  	assert(map_width > 0 && map_height > 0); //长宽不可为空  	assert(x0 >= 0 && x0 < map_width); //初始点横坐标不可越界  	assert(y0 >= 0 && y0 < map_height); //初始点纵坐标不可越界  	 	assert(map[x0 * map_width + y0]); //初始点应属于可通行点 	 	//上、左、下、右四个方向偏移 	int x_4[] = { 0, -1, 0, 1 }, y_4[] = { -1, 0, 1, 0 };  	int x, y; 	 	typedef std::vector<std::pair<int, int> > route_type; 	typedef std::vector<route_type> 		  route_list; 	 	routes.clear(); 	 	//初始只含有一个长为1的路径 （仅含起始点）  	routes.push_back(route_type(1, std::make_pair(x0, y0)));  	//经过3次遍历扩展，每次扩展根据上一次结果寻找下一步路径  	for (size_t i = 0, k = routes.size(); i < 3; i++) 	{ 		// 遍历上一次寻路结果  		for (size_t m = 0; m < k; m++) 		{ 			// 4个方向寻找可行的路径  			for (int j = 0; j < 4; j++) 			{ 				// 取最后一个点为起始点进行偏移  				x = routes[m][i].first + x_4[j]; 				y = routes[m][i].second + y_4[j]; 				 				// 判定移动到的点有效  				if (x >= 0 && y >= 0 && x < map_width && y < map_height &&  					map[x * map_width + y]) 				{ 					// 判定未曾走过	 					if (std::find(routes[m].begin(), routes[m].end(),  							std::make_pair(x, y)) == routes[m].end()) 					{  						// 依据上次寻路结果加上本次可通行点形成一个新的路径  						route_type route(routes[m]); 						route.push_back(std::make_pair(x, y)); 						 						// 添加到寻路结果中  						routes.push_back(route); 					} 				}				 			} 		} 		 		// 删除上次寻路结果  		routes.erase(routes.begin(), routes.begin() + k); 	}  }

没有数据测试，你试下。  #include <iostream> #include <vector>   /**  * 计算4步路径所有可能  * @param map 			二值地图，true表示通行，false表示障碍，原点在左上角   * @param map_width 	地图宽度  * @param map_height 	地图高度  * @param x0 			初始位置横坐标  * @param y0 			初始位置纵坐标  * @param routes 		返回所有可能的路径   */  void mapping(const bool * map,  	int map_width, int map_height,   	int x0, int y0,  	std::vector<std::vector<std::pair<int, int> > > & routes) { 	assert(map != NULL); //map不可为空  	assert(map_width > 0 && map_height > 0); //长宽不可为空  	assert(x0 >= 0 && x0 < map_width); //初始点横坐标不可越界  	assert(y0 >= 0 && y0 < map_height); //初始点纵坐标不可越界  	 	assert(map[x0 * map_width + y0]); //初始点应属于可通行点 	 	//上、左、下、右四个方向偏移 	int x_4[] = { 0, -1, 0, 1 }, y_4[] = { -1, 0, 1, 0 };  	int x, y; 	 	typedef std::vector<std::pair<int, int> > route_type; 	typedef std::vector<route_type> 		  route_list; 	 	routes.clear(); 	 	//初始只含有一个长为1的路径 （仅含起始点）  	routes.push_back(route_type(1, std::make_pair(x0, y0)));  	//经过3次遍历扩展，每次扩展根据上一次结果寻找下一步路径  	for (size_t i = 0, k = routes.size(); i < 3; i++) 	{ 		// 遍历上一次寻路结果  		for (size_t m = 0; m < k; m++) 		{ 			// 取最后一个点为起始点  			x = routes[m][i].first, y = routes[m][i].second; 			 			// 4个方向寻找可行的路径  			for (int j = 0; j < 4; j++) 			{ 				x += x_4[j]; 				y += y_4[j]; 				 				// 判定移动到的点有效  				if (x >= 0 && y >= 0 && x < map_width && y < map_height &&  					map[x * map_width + y]) 				{ 					// 判定未曾走过	 					if (std::find(routes[m].begin(), routes[m].end(),  							std::make_pair(x, y)) == routes[m].end()) 					{  						// 依据上次寻路结果加上本次可通行点形成一个新的路径  						route_type route(routes[m]); 						route.push_back(std::make_pair(x, y)); 						 						// 添加到寻路结果中  						routes.push_back(route); 					} 				}				 			} 		} 		 		// 删除上次寻路结果  		routes.erase(routes.begin(), routes.begin() + k); 	}  }

引用 5 楼 BreathOfDeath 的回复:不可以走已经经过的位置，需求说的不是很明白。 。  那就是经典回溯了呀，不用递归的话就用stack模拟递归就好了嘛，对于n比较小的时候（就像你这个n = 4的时候），n重for循环也可以


Question: 《c程序设计语言》里的一个翻译问题

引用 6 楼 Adol1111 的回复:引用 5 楼 u012345348 的回复:依然无解，只能自顶了。。。看下这里http://www.cnblogs.com/zj27sWizardTower/archive/2011/05/03/2035400.html 3q~因为刚学c，几乎没用过枚举变量，这段话几乎弄晕我了。

Enumerations provide a convenient way to associate constant values with names, an alternative to #define with the advantage that the values can be generated for you. Although variables of enum types may be declared, compilers need not check that what you store in such a variable is a valid value for the enumeration. Nevertheless, enumeration variables offer the chance of checking and so are often better than #defines. In addition, a debugger may be able to print values of enumeration variables in their symbolic form.  枚举类型提供一种便利的方式，将常量与名称联系起来。它能起到与#define相同的功能，但它还有一个优势，即能够为你自动产生数值。尽管enum类型的变量可以声明，但编译器并不需要检查你在这个变量中所存储的数值是否为一个合的法枚举类型数值。但枚举类型的变量却提供了机会，让用户可以检查变量中存储数值的合法性，因此它们通常优于#define。此外，一个debug程序能够以符号的形式打印出枚举类型变量的值。  也就是说，虽然编译器不做检查，但如果你想检查的话还是可以做到的，例如用循环加printf()。

枚举提供一条可选的，相比于用#define定义一些值的，更优越的， 使用名字组织常量的方便的途径。 尽管可以声明枚举类型的变量，编译器并不需要检查，那个变量是（否）一个合法的枚举值。 然而，枚举变量提供了一个检测的机会，于是经常比#defines 要好。 顺便说一下，一个调试器，也许能够打印，他们符号表中的，枚举的变量的值（名字和整数值）。 PS： 简单翻译一下，不知合不合原文！

引用 2 楼 cfjtaishan 的回复:使用google翻译试试~~~ +1

英语也是程序员的技能之一

不过这句话的理解的确有分歧，上下文也没有指名是checking什么，可以看下我刚刚发的那个网址中楼下的评论。当然C++的类型检查什么的比C要好多了。

依然无解，只能自顶了。。。

is there anyone out there,who knows the exact answer? 或者说有人精通枚举变量么么？

编译器不需要检查用枚举类型声明的变量的值是否有效，但是枚举变量提供检查的机会。我的理解是检不检查就跟编译器有关了，你编译器实现检查功能就检查，不实现也可以

使用google翻译试试~~~


Question: 为什么我的这个书里的例子提示有错

程序没错的。。

嵌套要像3楼学嘛

建议你的if嵌套不要这么写

我运行的是装在u盘里的绿色版vc！有的时候是不是会有报错的情况！

我解决了！不好意思

#include <studio.h>  int main(void)  {  char letter=0;  printf("enter an uppercase letter:");  scanf("%c",&letter);  if (letter >='A' && letter <='Z') //改成这样  {    letter=letter-'A'+'a';    printf ("you entered an uppercase %c\n",letter);  }  else  {    printf("try using the shirt key,bud i want a capital letter.\n"); }  return 0; }

if (letter >='A')    if (letter <='Z') 应该是if(letter>='A' && letter<='Z')

运行不起来，vc总是提示有一行有错


Question: 谁来帮我看看这个学生成绩管理系统

这是在读 保存的数据信息的时候 发生的错误么 ？还是？

我初学者 ，怎么没有后文了，求解

static void li(const stulink head) { 	stulink mv_link = head; 	while(mv_link!=NULL) 	{ 		printf("%d %s %0.2lf %0.2lf %0.2lf\n",mv_link->studata.id,mv_link->studata.name,mv_link->studata.chin, 			mv_link->studata.math,mv_link->studata.eng); 		mv_link = mv_link->next; 		if(mv_link->next == NULL) 			break; 	} }

用的那个编译器？


Question: 崩溃中

这几天在看书，没来回复帖子，看来论坛的朋友都很热情啊。

还要善于总结才行呢，一些东西可能开始不是很理解，不过随着自己知识面的提高，有些问题会迎刃而解的。 另外，还是要加强练习。

引用 6 楼 zhao4zhong1 的回复:计算机组成原理→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对应的汇编并单步执行观察相应内存和寄存器变化。）  想要从本质上理解C指针，必须学习汇编以及C和汇编的对应关系。 从汇编的角度理解和学习C语言的指针，原本看似复杂的东西就会变得非常简单！ 指针即地址。“地址又是啥？”“只能从汇编语言和计算机组成原理的角度去解释了。” 但我又不得不承认：  有那么些人喜欢或者适合用“先具体再抽象”的方法学习和理解复杂事物；  而另一些人喜欢或者适合用“先抽象再具体”的方法学习和理解复杂事物。 而我本人属前者。  这辈子不看内存地址和内存值；只画链表、指针示意图，画堆栈示意图，画各种示意图，甚至自己没画过而只看过书上的图……能从本质上理解指针、理解函数参数传递吗？本人深表怀疑！ 这辈子不种麦不收麦不将麦粒拿去磨面；只吃馒头、吃面条、吃面包、……甚至从没看过别人怎么蒸馒头，压面条，烤面包，……能从本质上理解面粉、理解面食吗？本人深表怀疑！！  提醒： “学习用汇编语言写程序” 和 “VC调试(TC或BC用TD调试)时按Alt+8、Alt+7、Alt+6和Alt+5,打开汇编窗口、堆栈窗口、内存窗口和寄存器窗口看每句C对应的汇编、单步执行并观察相应堆栈、内存和寄存器变化，这样过一遍不就啥都明白了吗。 （Linux或Unix下可以在用GDB调试时,看每句C对应的汇编并单步执行观察相应内存和寄存器变化。） 想要从本质上理解C指针，必须学习C和汇编的对应关系。” 不是一回事！  不要迷信书、考题、老师、回帖； 要迷信CPU、编译器、调试器、运行结果。 并请结合“盲人摸太阳”和“驾船出海时一定只带一个指南针。”加以理解。 任何理论、权威、传说、真理、标准、解释、想象、知识……都比不上摆在眼前的事实！  有人说一套做一套，你相信他说的还是相信他做的？ 其实严格来说这个世界上古往今来所有人都是说一套做一套，不是吗？  不要写连自己也预测不了结果的代码！  电脑内存或文件内容只是一个一维二进制字节数组及其对应的二进制地址； 人脑才将电脑内存或文件内容中的这个一维二进制字节数组及其对应的二进制地址的某些部分看成是整数、有符号数/无符号数、浮点数、复数、英文字母、阿拉伯数字、中文/韩文/法文……字符/字符串、汇编指令、函数、函数参数、堆、栈、数组、指针、数组指针、指针数组、数组的数组、指针的指针、二维数组、字符点阵、字符笔画的坐标、黑白二值图片、灰度图片、彩色图片、录音、视频、指纹信息、身份证信息……  十字链表交换任意两个节点C源代码（C指针应用终极挑战）http://download.csdn.net/detail/zhao4zhong1/5532495

这个东西还是要多看多写。

《C专家编程》里指针讲得很详细，推荐你看一下。

引用 楼主 u012804737 的回复:自学了C语言。看了谭浩强的，看了c primer plus,现在正在努力的看c 和指针。感觉有点没思路，没方向。很多问题还是解决不了。感觉水平很低，不能拔高啊...但是我不放弃，第一次来这个论坛，求关照。另外提个意见，验证码能不能弄的大一点，对我这种视力不好的老年人来说，伤不起啊。 我楼上 就是这个版块的大牛， 各种问题都能解决 人称“赵老师”也

除了怒刷代码，没有别的办法

学完汇编之后，感觉什么也不能做，就是 move 来 move 去，后来看了别人的程序，才知道 move 是程序的基础之一

引用 楼主 u012804737 的回复:自学了C语言。看了谭浩强的，看了c primer plus,现在正在努力的看c 和指针。感觉有点没思路，没方向。很多问题还是解决不了。感觉水平很低，不能拔高啊...但是我不放弃，第一次来这个论坛，求关照。另外提个意见，验证码能不能弄的大一点，对我这种视力不好的老年人来说，伤不起啊。  处于初始阶段就企图解决“很多问题”是不现实的，看完C和指针就找本数据结构方面的书，把里面的东西都实现一遍。

http://bbs.csdn.net/topics/390638386 看看，多多看点书，敲点代码！积极点，年轻人！

老年人……还在学C噢，敬佩一个，姜是老的辣啊！！  卖油翁的一句话：唯熟尔！ 一下子到了陌生地方，都是没思路，没方向，但时间长了自然就熟悉了。


Question: 求大家帮忙做一下这道程序设计题

//楼上是枪手 //鉴定完毕

//-------------------------------------------------- // //	功能：从键盘为一维整型数组输入10个整数，调用fun 函 //	数找出其中最小的数，并在main函数中输出。。 // //------------------------------------------------*/  #include "stdio.h" 	void wwjt();  int fun(int x[],int n) {   	/**********Program**********/   	int nMin = x[0];  	for (int i = 1;i < n; i++) 	{ 		if (nMin > x[i]) 			nMin = x[i]; 	}  	return nMin; 	/**********  End  **********/   } void main(){ 	int a[10],i,min; 	for(i=0;i<10;i++) 		scanf("%d",&a[i]); 	for(i=0;i<10;i++) 		printf("%3d",a[i]); 	printf("\n"); 	min=fun(a,10); 	printf("%d\n",min);   	wwjt(); }     void wwjt() { 	FILE *IN,*OUT; 	int in[4],out; 	IN=fopen("in.dat","r"); 	if(IN==NULL)    printf("Read FILE Error"); 	OUT=fopen("out.dat","w"); 	if(OUT==NULL)   printf("Write FILE Error");  	for(int j=0;j<5;j++) 	{  		for(int i=0;i<4;i++) 		{    			fscanf(IN,"%d",&in[i]); 		}    		out=fun(in,4); 		fprintf(OUT,"%d\n",out); 	} 	fclose(IN); 	fclose(OUT); }

/*------------------------------------------------ // 【程序设计】 // -------------------------------------------------- //  //功能：用函数求N个[10,60]上的整数中能被5整除的最大 //       的数，如存在则返回这个最大值，如果不存在则 //       返回0。 // //------------------------------------------------*/  #define N 30  #include "stdlib.h"  #include <stdio.h>  void  wwjt();    int find(int arr[],int n)  {     int m=0;    /**********Program**********/    m = arr[0];    for (int i = 1;i < N;i++)    { 	   if (0 == arr[i]%5) 	   { 		   if (m < arr[i]) 			   m = arr[i]; 	   }    }        /**********  End  **********/    return(m);  }   int main()  {    int a[N],i,k;    for(i=0;i<N;i++)      a[i]=rand()%(51)+10;    for(i=0;i<N;i++)    {      printf("%5d",a[i]);      if((i+1)%5==0) printf("\n");    }    k=find(a,N);    if(k==0)       printf("NO FOUND\n");    else      printf("the max is:%d\n",k);    wwjt();     return 0;  }   void wwjt()  {    FILE *IN,*OUT;    int n;    int i[5];    int o;    IN=fopen("in.dat","r");    if(IN==NULL)    {      printf("Read FILE Error");    }    OUT=fopen("out.dat","w");    if(OUT==NULL)    {      printf("Write FILE Error");    }    for(n=0;n<5;n++)    {          fscanf(IN,"%d",&i[n]);    }    o=find(i,5);    fprintf(OUT,"%d\n",o);    fclose(IN);    fclose(OUT);  }

引用 4 楼 IWSo920 的回复:[quote=引用 3 楼 xihu1364 的回复:] //楼上是枪手 //鉴定完毕   "枪手"? 什么意思？[/quote] 就是帮人打手枪

引用 3 楼 xihu1364 的回复://楼上是枪手 //鉴定完毕   "枪手"? 什么意思？


Question: 程序改错题

第一题 a==NULL 改成 a=NULL  ,  if ( r == p ) 改成if(*r==*p)  ,if ( *r ='\0' ) a = s;改成if ( *r =='\0' ) a = s;  第二题   case 12:             len=31;             /**********FOUND**********/             break  //这里加分号;      switch(yy)改成 switch(mm)   default //加冒号：            printf("input error!\n");            break;


Question: 使用的fat32文件系统创建的文件不能读取

推荐使用WinHex软件查看硬盘或文件或内存中的原始字节内容。  试对比利用实际可用的FAT32系统创建的文件和自己创建文件的FAT表和目录表的字节差异。

类似的东东我做过，也遇到的同样的错误，后来证实还是簇号的错误。


Question: 请教个问题！

引用 13 楼 u012207185 的回复:赵老师，你研究过linux内核吗？ 没

引用 9 楼 zhao4zhong1 的回复:对学习编程者的忠告： 眼过千遍不如手过一遍！ 书看千行不如手敲一行！ 手敲千行不如单步一行！ 单步源代码千行不如单步对应汇编一行！  单步类的实例“构造”或“复制”或“作为函数参数”或“作为函数返回值返回”或“参加各种运算”或“退出作用域”的语句对应的汇编代码几步后，就会来到该类的“构造函数”或“复制构造函数”或“运算符重载”或“析构函数”对应的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对应的汇编并单步执行观察相应内存和寄存器变化。） 赵老师，你研究过linux内核吗？

引用 11 楼 junlinfushi 的回复:[quote=引用 10 楼 u012207185 的回复:] [quote=引用 8 楼 zhao4zhong1 的回复:] 计算机组成原理→DOS命令→汇编语言→C语言（不包括C++）、代码书写规范→数据结构、编译原理、操作系统→计算机网络、数据库原理、正则表达式→其它语言（包括C++）、架构…… 离散数学要不要学？[/quote]离散没用到还是别自学吧。[/quote] 本科必修的一门课哦。怎么用不到呢？

引用 10 楼 u012207185 的回复:[quote=引用 8 楼 zhao4zhong1 的回复:] 计算机组成原理→DOS命令→汇编语言→C语言（不包括C++）、代码书写规范→数据结构、编译原理、操作系统→计算机网络、数据库原理、正则表达式→其它语言（包括C++）、架构…… 离散数学要不要学？[/quote]离散没用到还是别自学吧。

参加计算机竞赛吧！ 这样就有很多机会，敲代码了。

引用 8 楼 zhao4zhong1 的回复:计算机组成原理→DOS命令→汇编语言→C语言（不包括C++）、代码书写规范→数据结构、编译原理、操作系统→计算机网络、数据库原理、正则表达式→其它语言（包括C++）、架构…… 离散数学要不要学？

The C program language

《The C program language》->《c专家编程》、《c陷进和缺陷》->《Unix环境高级编程》

建议看下 C和指针

http://bbs.csdn.net/topics/390638386  楼主看看这个

看看 c和指针和The C program language，上面的例程都敲敲，写写代码，  有了一定的基础之后再看c专家编程，c陷进和缺陷！

《The C program language》应该不用学了吧！


Question: 请教个问题！

引用 7 楼 u012207185 的回复:[quote=引用 4 楼 max_min_ 的回复:] 1 执行的时候 后面跟 文件1 和文件2 2 两个文件都必须存在，且当前有权限进行读操作 3 两个文件路径必须在当前可执行目录下 当前可执行目录下指的是什么？哪个目录？[/quote]就是你当前目录下，比如C:\Users\Administrator>"……"这句 > 左边的就是你所在的目录了。dos应该会用的吧，盘符切换的话用d:就可以了，用cd XXX（文件夹路径）切换目录。

Directory Control These routines access, modify, and obtain information about the directory structure.  Directory-Control Routines  Routine Use  _chdir, _wchdir Change current working directory  _chdrive Change current drive  _getcwd, _wgetcwd Get current working directory for default drive  _getdcwd, _wgetdcwd Get current working directory for specified drive  _getdrive Get current (default) drive  _mkdir, _wmkdir Make new directory  _rmdir, _wrmdir Remove directory  _searchenv, _wsearchenv Search for given file on specified paths

引用 1 楼 u012207185 的回复:运行结果如下：   运行不成功

引用 4 楼 max_min_ 的回复:1 执行的时候 后面跟 文件1 和文件2 2 两个文件都必须存在，且当前有权限进行读操作 3 两个文件路径必须在当前可执行目录下 当前可执行目录下指的是什么？哪个目录？

引用 2 楼 user-6 的回复:你贴的图写的清清楚楚！ Usage: C:\xxx\xx.exe file1 file2 意思就是说，只需要2个命令行参数！而你给了三个！！  你不加任何参数的时候，argc为1，加一个的时候argc为2，第一个argv不需要你输入，可以自动获取，就是你的可执行文件。 谢谢你啊，执行成功了！

引用 4 楼 max_min_ 的回复:1 执行的时候 后面跟 文件1 和文件2 2 两个文件都必须存在，且当前有权限进行读操作 3 两个文件路径必须在当前可执行目录下 我那两个文件在我的文档里，和执行文件不在一个目录下。 我现在把他们剪切到和执行文件一个目录下，运行不了了，Could not open file！

应该是和你的执行文件在同一路径下吧~~~

运行结果如下：


Question: 关于feof()函数的一个问题

引用 1 楼 N_sev7 的回复:因为feof只是返回系统的一个statment的值，它是要fgetc fgets fread等等系统调用修改的。 fseek(fp, 0, SEEK_END)后文件指针指向size,如果此时feof(fp)的话，是不会返回非0的，原因就是根本没有系统调用改变了那个statment的值。所以还是返回0，这样如果不做判断直接fgetc的话，就会获得一个-1,当然也因为这个-1系统改变了statment的值，所以 先 fseek(fp, 0, SEEK_END 然后 fgetc（） 之后再 调用feof的时候就会返回非0  在百度上这样说： “ “C”语言的“feof()”函数和数据库中“eof()”函数的运作是完全不同的。数据库中“eof()”函数读取当前指针的位置，“C”语言的“feof()”函数返回的是最后一次“读操作的内容”。多年来把“位置和内容”相混，从而造成了对这一概念的似是而非。  那么，位置和内容到底有何不同呢？举个简单的例子，比如有人说“你走到火车的最后一节车箱”这就是位置。而如果说“请你一直向后走，摸到铁轨结束”这就是内容。也就是说用内容来判断会“多走一节”。这就是完全依赖于“while(!feof(FP)){...}”进行文件复制时，目标文档总会比源文档“多出一些”的原因。  ” 应该就是你说，指针先到位置，然后用fgetc()读取到这个位置的内容，才有这个statment的值，我这样理解对吧？

引用 1 楼 N_sev7 的回复:因为feof只是返回系统的一个statment的值，它是要fgetc fgets fread等等系统调用修改的。 fseek(fp, 0, SEEK_END)后文件指针指向size,如果此时feof(fp)的话，是不会返回非0的，原因就是根本没有系统调用改变了那个statment的值。所以还是返回0，这样如果不做判断直接fgetc的话，就会获得一个-1,当然也因为这个-1系统改变了statment的值，所以 先 fseek(fp, 0, SEEK_END 然后 fgetc（） 之后再 调用feof的时候就会返回非0  学习了

int fgetc(FILE *stream) fgetc returns the next character of stream as an unsigned char (converted to an int), or EOF if end of file or error occurs. 次函数的运行导致文件指针结构体中的元素变化，此变化由下面的函数检测   int feof(FILE *stream) feof returns non-zero if the end of file indicator for stream is set.

你先查一下feof和fgetc这两个函数：  fgetc: Returns the character currently pointed by the internal file position indicator of the specified stream. The internal file position indicator is then advanced to the next character.  If the stream is at the end-of-file when called, the function returns EOF and sets the end-of-file indicator for the stream (feof). feof: Check end-of-file indicator Checks whether the end-of-File indicator associated with stream is set, returning a value different from zero if it is.  This indicator is generally set by a previous operation on the stream that attempted to read at or past the end-of-file.

这应该是feof函数的问题， http://baike.baidu.com/view/656648.htm


Question: Linux下编写线性链表出现段错误，求解～～

说错了，因该是指针本身是一个普通的变量（即指针本身是一个值传递），*p才表示你指针所指的变量（这个变量传递的是地址），而你的malloc操作是针对指针本身，和传进来的 变量的地址 是无关的，你可以用二维指针做参数（把指针的地址也传进来）来验证下。

参考前面。。想通过参数返回指针，至少二级。。建议用函数返回值返回指针。。基础啊。。。。。。

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

参考一楼，创建链表的时候，返回值不太对

malloc之后，之前的指针地址就无效了，就是说操作的不是一块空间，所以即使是指针也是没用的，必须返回该指针。C++可以用引用，引用是变量的别名，和该变量一直绑定在一起，所以没关系。 参考1楼的代码就可以了。

#include<stdio.h> #include<malloc.h>  typedef struct LNode {         int data;         struct LNode *next; }LNode, *LinkList;          LinkList *CreateList_L(){         LinkList L = NULL;         L = (LinkList)malloc(sizeof(LNode));         L->data = 0;         L->next = NULL;         return L; }//CreateList_L  void ListInsert_L(LinkList L, int i, int e){         LinkList p = L;         LinkList s;         int j = 1;         while(p && j<i){                 p = p->next;                 ++j;         }         if( !p || j>i ){                 printf("error!\n");                 return;         }         s = (LinkList )malloc(sizeof(LNode));         s->data = e;         s->next = p->next;         p->next = s;         L->data = L->data + 1;         return; }//ListInsert_L          int main(){         LinkList La = CreateList_L();         ListInsert_L(La, 1, 10);         printf("%d\n", La->next->data);         return 0; }  粗略修改了下！


Question: 指针问题，急求！！

谢谢！会多加学习的。

我可以理解成修改简单的插入删除和修改链表吗？画个图你就知道了。。。

仅供参考//假设带表头结点的单向链表头指针为head，试编写一个算法将值为5的结点插入到连接表的第k个结点前，删除第k个节点，并对该链表进行排序。 #include <stdio.h> #include <stdlib.h> #include <malloc.h> #include <time.h> struct NODE {     int          data;     struct NODE *next; } H,*head,*p,*q,*s1,*s2,*s3,*s4,*s; int i,j,k,n,t,m; int main() {     srand(time(NULL));      //填写头节点数据     H.data=-1;     H.next=NULL;     head=&H;      //创建10个节点的单链表     p=head;     for (i=0;i<10;i++) {         q=(struct NODE *)malloc(sizeof(struct NODE));         if (NULL==q) return 1;         q->data=rand()%100;//填写0..99的随机值         q->next=NULL;         p->next=q;         p=q;     }      //输出整个单链表     s=head->next;     while (1) {         if (NULL==s) {             printf("\n");             break;         }         printf("%02d->",s->data);         s=s->next;     }      //将值为5的结点插入到单链表的第k个结点前     k=3;     n=0;     p=head;     while (1) {         if (NULL==p) {             break;         }         n++;         if (k==n) {             q=(struct NODE *)malloc(sizeof(struct NODE));             if (NULL==q) return 1;             q->data=5;             q->next=p->next;             p->next=q;             break;         }         p=p->next;     }      //输出整个单链表     s=head->next;     while (1) {         if (NULL==s) {             printf("\n");             break;         }         printf("%02d->",s->data);         s=s->next;     }      //删除第k个节点     k=5;     n=0;     p=head;     while (1) {         if (NULL==p) {             break;         }         n++;         if (k==n) {             q=p->next;             if (q) {                 p->next=q->next;                 free(q);             }             break;         }         p=p->next;     }      //输出整个单链表     s=head->next;     while (1) {         if (NULL==s) {             printf("\n");             break;         }         printf("%02d->",s->data);         s=s->next;     }      //从小到大排序     for (p=head;p!=NULL && p->next!=NULL;p=p->next) {         for (q=p->next;q!=NULL && q->next!=NULL;q=q->next) {             if (p->next->data > q->next->data) {                  //交换data //              printf("swap %02d %02d\n",p->next->data,q->next->data); //              t=p->next->data;p->next->data=q->next->data;q->next->data=t;                  //或者                  //交换next //              printf("swap %02d %02d\n",p->next->data,q->next->data);                 s1=p->next;                 s2=p->next->next;                 s3=q->next;                 s4=q->next->next;                  if (s2!=s3) {                      p->next=s3;                     s3->next=s2;                      q->next=s1;                     s1->next=s4;                 } else {                      p->next=s3;                     s3->next=s1;                            q=s3;                     s1->next=s4;                 }                  //输出整个单链表 //              s=head->next; //              while (1) { //                  if (NULL==s) { //                      printf("\n"); //                      break; //                  } //                  printf("%02d->",s->data); //                  s=s->next; //              } //              getchar();             }         }     }      //输出整个单链表     s=head->next;     while (1) {         if (NULL==s) {             printf("\n");             break;         }         printf("%02d->",s->data);         s=s->next;     }      //将单链表中前 m 个结点和后 n 个结点进行互换,m+n为链表总长10     m=4;     n=6;     k=0;     p=head;     while (1) {         if (NULL==p) {             break;         }         k++;         if (m+1==k) {             q=p;         }         s=p;         p=p->next;     }     s1=head->next;     head->next=q->next;     s->next=s1;     q->next=NULL;      //输出整个单链表     s=head->next;     while (1) {         if (NULL==s) {             printf("\n");             break;         }         printf("%02d->",s->data);         s=s->next;     }      //释放所有节点     p=head->next;     while (1) {         if (NULL==p) {             break;         }         q=p->next;         free(p);         p=q;     }      return 0; } //18->94->58->17->27->20->43->57->75->78-> //18->94->05->58->17->27->20->43->57->75->78-> //18->94->05->58->27->20->43->57->75->78-> //05->18->20->27->43->57->58->75->78->94-> //43->57->58->75->78->94->05->18->20->27-> //  计算机组成原理→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对应的汇编并单步执行观察相应内存和寄存器变化。）  想要从本质上理解C指针，必须学习汇编以及C和汇编的对应关系。 从汇编的角度理解和学习C语言的指针，原本看似复杂的东西就会变得非常简单！ 指针即地址。“地址又是啥？”“只能从汇编语言和计算机组成原理的角度去解释了。” 但我又不得不承认：  有那么些人喜欢或者适合用“先具体再抽象”的方法学习和理解复杂事物；  而另一些人喜欢或者适合用“先抽象再具体”的方法学习和理解复杂事物。 而我本人属前者。  这辈子不看内存地址和内存值；只画链表、指针示意图，画堆栈示意图，画各种示意图，甚至自己没画过而只看过书上的图……能从本质上理解指针、理解函数参数传递吗？本人深表怀疑！ 这辈子不种麦不收麦不将麦粒拿去磨面；只吃馒头、吃面条、吃面包、……甚至从没看过别人怎么蒸馒头，压面条，烤面包，……能从本质上理解面粉、理解面食吗？本人深表怀疑！！  提醒： “学习用汇编语言写程序” 和 “VC调试(TC或BC用TD调试)时按Alt+8、Alt+7、Alt+6和Alt+5,打开汇编窗口、堆栈窗口、内存窗口和寄存器窗口看每句C对应的汇编、单步执行并观察相应堆栈、内存和寄存器变化，这样过一遍不就啥都明白了吗。 （Linux或Unix下可以在用GDB调试时,看每句C对应的汇编并单步执行观察相应内存和寄存器变化。） 想要从本质上理解C指针，必须学习C和汇编的对应关系。” 不是一回事！  不要迷信书、考题、老师、回帖； 要迷信CPU、编译器、调试器、运行结果。 并请结合“盲人摸太阳”和“驾船出海时一定只带一个指南针。”加以理解。 任何理论、权威、传说、真理、标准、解释、想象、知识……都比不上摆在眼前的事实！  有人说一套做一套，你相信他说的还是相信他做的？ 其实严格来说这个世界上古往今来所有人都是说一套做一套，不是吗？  不要写连自己也预测不了结果的代码！  电脑内存或文件内容只是一个一维二进制字节数组及其对应的二进制地址； 人脑才将电脑内存或文件内容中的这个一维二进制字节数组及其对应的二进制地址的某些部分看成是整数、有符号数/无符号数、浮点数、复数、英文字母、阿拉伯数字、中文/韩文/法文……字符/字符串、汇编指令、函数、函数参数、堆、栈、数组、指针、数组指针、指针数组、数组的数组、指针的指针、二维数组、字符点阵、字符笔画的坐标、黑白二值图片、灰度图片、彩色图片、录音、视频、指纹信息、身份证信息……  十字链表交换任意两个节点C源代码（C指针应用终极挑战）http://download.csdn.net/detail/zhao4zhong1/5532495

引用 1 楼 user-3 的回复:void changedata(linklist *L)  {      linklist *pt1, *pt2;      char str_num[20];      if(L->next==NULL)      {          printf("无需修改，该表为空表\n");      }      else      {         printf("请输入您要修改的编号信息:");         scanf("%s",str_num);         pt1=L->next;   //      pt2=(linklist*)malloc(sizeof(linklist));         while(pt1 != NULL)         {             if(strcmp(pt1->num,str_num)==0)             {                 printf("\n输入添加货物的信息：");                 printf("\n请输入货物编号：");                 fscanf(STDIN, "%s", pt1->num);                 printf("\n请输入货物名称：");                 fscanf(STDIN, "%s", pt1->name);                 printf("\n请输入货物进货价：");                 fscanf(STDIN, "%f", &pt1->purchase);                 printf("\n请输入货物销售价：");                 fscanf(STDIN, "%f", &pt1->sales);                 printf("\n请输入货物生产日期：");                 fscanf(STDIN, "%s", pt1->MFG);                 printf("\n请输入货物和保质期：");                 fscanf(STDIN, "%s", pt1->EXP);                 printf("\n请输入货物库存量；");                 fscanf(STDIN, "%d", &pt1->VMI);                 printf("\n请输入货物销售数量；");                 fscanf(STDIN, "%d", &pt1->SV);             }             pt1=pt1->next;	           }       }  }   写错了 改成stdin 这是标准输入，在stdio头文件中。

STDIN 是在那个头文件下的呢？


Question: 文盲求大神指点程序错误，使之得出正确结果。

引用 6 楼 l371231365 的回复:[quote=引用 4 楼 max_min_ 的回复:] [quote=引用 3 楼 l371231365 的回复:]  #include<iostream>    //预编译命令 using namespace std; int main()         //主函数 {     float ApplePrice=3.5;            //对象1(苹果价格)     float BananaPrice=4.2;            //对象2(香蕉价格)     float AppleWeight=0.0;           //对象3(苹果重量)     float BananaWeight=0.0;               //对象4(香蕉重量)     float Total=0.0;              //对象5(总钱数)     cout<<"请输入苹果的重量"<<endl;       //提示信息     cin>>AppleWeight;                 //从键盘输入苹果的重量     cout<<"请输入香蕉的重量"<<endl;     cin>>BananaWeight;     Total=ApplePrice*AppleWeight+BananaPrice*BananaWeight;   //计算应付款     cout<<"应付款"<<endl;     system("pause");     return 0; }    //除了这里，其他没有问题，测试了下 cout<<"应付款"<< Total << endl; [/quote]  意思是就是把 cout<<"应付款"<<endl;  改成 cout<<"应付款"<< Total << endl; 然后就没有其他错误了吗？[/quote] 嗯！我这边没错误了，你如果有错误，把错误贴出来

引用 4 楼 max_min_ 的回复:[quote=引用 3 楼 l371231365 的回复:]  #include<iostream>    //预编译命令 using namespace std; int main()         //主函数 {     float ApplePrice=3.5;            //对象1(苹果价格)     float BananaPrice=4.2;            //对象2(香蕉价格)     float AppleWeight=0.0;           //对象3(苹果重量)     float BananaWeight=0.0;               //对象4(香蕉重量)     float Total=0.0;              //对象5(总钱数)     cout<<"请输入苹果的重量"<<endl;       //提示信息     cin>>AppleWeight;                 //从键盘输入苹果的重量     cout<<"请输入香蕉的重量"<<endl;     cin>>BananaWeight;     Total=ApplePrice*AppleWeight+BananaPrice*BananaWeight;   //计算应付款     cout<<"应付款"<<endl;     system("pause");     return 0; }    //除了这里，其他没有问题，测试了下 cout<<"应付款"<< Total << endl; [/quote]  意思是就是把 cout<<"应付款"<<endl;  改成 cout<<"应付款"<< Total << endl; 然后就没有其他错误了吗？

#include<iostream>    //预编译命令 using namespace std; int main()         //主函数 {     float ApplePrice=3.5;            //对象1(苹果价格)     float BananaPrice=4.2;            //对象2(香蕉价格)     float AppleWeight=0.0;           //对象3(苹果重量)     float BananaWeight=0.0;               //对象4(香蕉重量)     float Total=0.0;              //对象5(总钱数)     cout<<"请输入苹果的重量"<<endl;       //提示信息     cin>>AppleWeight;                 //从键盘输入苹果的重量     cout<<"请输入香蕉的重量"<<endl;     cin>>BananaWeight;     Total=ApplePrice*AppleWeight+BananaPrice*BananaWeight;   //计算应付款     cout<<"应付款"<<Total<<endl;     system("pause");     return 0; }   手误，前面少写了Total,求纠错

引用 3 楼 l371231365 的回复: #include<iostream>    //预编译命令 using namespace std; int main()         //主函数 {     float ApplePrice=3.5;            //对象1(苹果价格)     float BananaPrice=4.2;            //对象2(香蕉价格)     float AppleWeight=0.0;           //对象3(苹果重量)     float BananaWeight=0.0;               //对象4(香蕉重量)     float Total=0.0;              //对象5(总钱数)     cout<<"请输入苹果的重量"<<endl;       //提示信息     cin>>AppleWeight;                 //从键盘输入苹果的重量     cout<<"请输入香蕉的重量"<<endl;     cin>>BananaWeight;     Total=ApplePrice*AppleWeight+BananaPrice*BananaWeight;   //计算应付款     cout<<"应付款"<<endl;     system("pause");     return 0; }    //除了这里，其他没有问题，测试了下 cout<<"应付款"<< Total << endl;

C++不懂啊 C++的main不带参数可以不写void么？

1 贴代码 别截屏 2 你认为错在哪里 你认为哪错了 3 大神谁没事闲的琢磨人的内心啊


Question: 大神来支招！~TC下的代码在VS2012中怎么执行？

自己去做吧。 估计也就写个动态库什么的。 虽然没有一一对应的，还是有大概对应的东西的。

1楼的回答没有明白我的意思，或许是我没有表达清楚我的意思吧！ 2楼的回答有点明白我的意思！其实我就是想问，既然VS2012不支持TC下的这些函数，是否有其它函数可以替代之，从而可以在VS2012下输出同样的结果！

觉得没必要去深究那些函数，以后会学到更好的工具用来替代，当然写出来了也是挺有意思的（以前就是直接载TurboC编译器来写的）

VS2012不支持你用的conio；如果需要类似的功能可以使用ncurses，Windows上也有： Ncurses for Windows

安装DOS 6.22虚拟机，在上面安装Turbo C2.0进行编译运行。  引用 楼主 yerssa 的回复:#include <stdio.h> #include <conio.h> void main() { int i; char * s[] = {"BLACK","BLUE","GREEN","CYAN","RED","MAGENTA","BROWN","LIGHTGRAY"}; textmode(C80); textbackground(0); clrscr(); for (i = 1 ; i < 8 ; i ++) { window(10 + i * 5 , 30 + i * 5 , 15 + i); textbackground(i); clrscr(); textcolor(7 + i); if (i % 2 == 0) { highvideo(); } else lowvideo(); cputs(s[i]); } getch(); } 这段在TC下编写的代码，想在VS2012中运行看下效果，但很多函数都不支持，怎么办呢？


Question: 【代码求助】RSA加解密————使用libTomCrypt库

解密和加密去看雪论坛发，CSDN这方面牛人比较少


Question: 指点迷津！加了头文件，为什么还提示未定义？

conio.h是DOS下的。  引用 楼主 yerssa 的回复:#include <stdio.h> #include <conio.h> int main(void) { textmode(BW80); cprintf("BW80"); getch(); textmode(C80); cprintf("C80"); getch(); textmode(BW40); cprintf("BW40"); getch(); textmode(C40); cprintf("C40"); getch(); textmode(MONO); cprintf("MONO"); getch(); return 0; } [/code]VS2012 ,不是加头文件了嘛，怎么还显示textmode（）函数未定义？

conio.h不是c语言标准函数库，不同编译环境下它的内容是不同的 楼主这段代码大概是在TC下编写的吧，在VS下没有textmode这个函数


Question: 请问：如何定义返回值为多维数组（例如二维）的地址函数？

char (*)retptr(char (*ptr)[MAX], int n)[MAX]｛  return ptr;  ｝ 这么处理，没问题。 #define MAX 1000  typedef char (*char_arr_ptr)[MAX]; char_arr_ptr retptr(char (*ptr)[MAX],int n){ return ptr; }

记得好像要这么写！ char (*)retptr(char (*ptr)[MAX], int n)[MAX];

引用 3 楼 mcmay 的回复:[quote=引用 1 楼 user-6 的回复:] ok的吧 warning而已，你run的时候有什么bug？ 也没有什么bug之类的，但需要有个正式的格式吧？如果是返回多维（超过两维）那不是需要多几个星号？[/quote]  不转型你的编译器只是给的warning？我的咋报error了呢，而且static_cast<char**>也不行，都必须是reinterpret_cast<char**>  #define MAX 20 char** retptr(char (*ptr)[MAX], int n) {     return ptr; }  In function 'char** retptr(char (*)[20], int)':| error: cannot convert 'char (*)[20]' to 'char**' in return|

仅供参考//在堆中开辟一个3×4×5的3维int数组 #include <stdio.h> #include <malloc.h> int ***p; int i,j,k; void main() {     p=(int ***)malloc(3*sizeof(int **));     if (NULL==p) return;     for (i=0;i<3;i++) {         p[i]=(int **)malloc(4*sizeof(int *));         if (NULL==p[i]) return;         for (j=0;j<4;j++) {             p[i][j]=(int *)malloc(5*sizeof(int));             if (NULL==p[i][j]) return;         }     }     for (i=0;i<3;i++) {         for (j=0;j<4;j++) {             for (k=0;k<5;k++) {                 p[i][j][k]=i*20+j*5+k;             }         }     }     for (i=0;i<3;i++) {         for (j=0;j<4;j++) {             for (k=0;k<5;k++) {                 printf(" %2d",p[i][j][k]);             }             printf("\n");         }         printf("---------------\n");     }     for (i=0;i<3;i++) {         for (j=0;j<4;j++) {             free(p[i][j]);         }         free(p[i]);     }     free(p); } //  0  1  2  3  4 //  5  6  7  8  9 // 10 11 12 13 14 // 15 16 17 18 19 //--------------- // 20 21 22 23 24 // 25 26 27 28 29 // 30 31 32 33 34 // 35 36 37 38 39 //--------------- // 40 41 42 43 44 // 45 46 47 48 49 // 50 51 52 53 54 // 55 56 57 58 59 //---------------

你这样写 char **retptr(char **ptr, int n) 就可以了。

引用 2 楼 Ronux 的回复:没问题，不想看到warning，可以加上强制类型转换 如何加类型转换？

引用 1 楼 user-6 的回复:ok的吧 warning而已，你run的时候有什么bug？ 也没有什么bug之类的，但需要有个正式的格式吧？如果是返回多维（超过两维）那不是需要多几个星号？

没问题，不想看到warning，可以加上强制类型转换

ok的吧 warning而已，你run的时候有什么bug？


Question: 素数的Miller_Rabbin测试 问题！！！（希望都能看看~）

引用 3 楼 xw514124205 的回复:[quote=引用 1 楼 FancyMouse 的回复:] >在a不等于1的时候，则d*2^r-1 = 0 没有人告诉你有这回事。指数函数不就是这样的吗，而且a的值一定大于2嘛，那指数只能为0了帮帮忙[/quote] 说明你不懂模算术。连你贴的第一句话的费马小定理都还没懂。你仔细读读你贴的这段文字第一行是啥。

引用 1 楼 FancyMouse 的回复:>在a不等于1的时候，则d*2^r-1 = 0 没有人告诉你有这回事。指数函数不就是这样的吗，而且a的值一定大于2嘛，那指数只能为0了帮帮忙

数论玩不起呀

引用 4 楼 FancyMouse 的回复:[quote=引用 3 楼 xw514124205 的回复:] [quote=引用 1 楼 FancyMouse 的回复:] >在a不等于1的时候，则d*2^r-1 = 0 没有人告诉你有这回事。指数函数不就是这样的吗，而且a的值一定大于2嘛，那指数只能为0了帮帮忙[/quote] 说明你不懂模算术。连你贴的第一句话的费马小定理都还没懂。你仔细读读你贴的这段文字第一行是啥。[/quote] Miller和Rabin两个人的工作让Fermat素性测试迈出了革命性的一步，建立了Miller-Rabin素性测试算法。新的测试基于下面的定理：如果p是素数，x是小于p的正整数，且x2 mod p = 1，那么要么x=1，要么x=p-1。这是显然的，因为x2 mod p = 1相当于p能整除x2-1，也即p能整除(x+1)(x-1)。由于p是素数，那么只可能是x-1能被p整除(此时x=1)或x+1能被p整除(此时x=p-1)。 红色部分改成那么要么x=1 mod p，要么x=p-1 mod p 我就能好理解多了~

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

>在a不等于1的时候，则d*2^r-1 = 0 没有人告诉你有这回事。


Question: 【双十一到了，准备买书了么？】推荐几本c/c++入手的书籍

c pp怎么没有

现在新手应该买什么书？？？

谢谢楼主的分享！！！

程序员要看这么多书

C++ primer真是永恒的经典……

我也去买来看看

真心不错啊，赞一个

灰常好的，谢谢楼主

遇见本贴必赞

新手求教啊 顶个

大家能否推荐几本入门级的DEV C++的书啊

都是经典，希望能都好好阅读以下

这些书真心不错，顶一个

本打算想学C++,但一看到要看这么多书，顿时力不从心啊

mark一下，有时间看看，虽然离c++越来越远

哈哈~~看经典书籍

引用 36 楼 u012271055 的回复:都是杀死脑细胞的书！！！

mark, LZ thanks

引用 7 楼 caozhy 的回复:今年快过完了，这本书是我看到的今年最佳（其实这书去年就出了）   非技术书。看过哎~~


Question: 运行时可以动态增大进程栈空间吗？

我也知道栈溢出，但是我觉得也可能那是在没有分配栈空间的情况下而使用了未定义的内存空间，或覆盖了进程其它数据，但如果分配了合法的内存空间（不会与进程或系统其它数据冲突）作为栈空间，是不是就不会栈溢出呢？

我认为不可以，否则栈溢出就不会是问题。

谢谢大家，基本理解了！！！

引用 15 楼 chenhui1990421 的回复:[quote=引用 13 楼 jerry_dqh 的回复:] [quote=引用 10 楼 chenhui1990421 的回复:] 栈在物理内存中是连续的吗？ 对于一些程序，都是讲线性空间。[/quote] 所谓的线性空间可以理解成虚拟内存吗？[/quote] 不可以，对于32位系统，你的进程启动后，OS会给你的进程分配4G的线性空间，与其他的进程是独立开来的。当你的程序用到线性地址中的某块，操作系统才会将真实的物理内存映射到线性空间，所以当在程序了使用连续的地址，实际上用的是线性地址。操作系统可能将不连续的物理内存映射到进程中连续的线性地址中。对于程序来说感应不到真实的物理的地址是否连续了。

引用 13 楼 jerry_dqh 的回复:[quote=引用 10 楼 chenhui1990421 的回复:] 栈在物理内存中是连续的吗？ 对于一些程序，都是讲线性空间。[/quote] 所谓的线性空间可以理解成虚拟内存吗？

《windows核心编程》上说物理内存始终都以页面为单位来调拨，这是不是意味着所有的长度大于4kb的程序模块都可能不是连续的？

引用 10 楼 chenhui1990421 的回复:栈在物理内存中是连续的吗？ 对于一些程序，都是讲线性空间。

另外API会从用户态进入内核态，一定会使用内核堆栈，和用户堆栈两个堆栈，自然也不会物理一定连续了。 一般都不会物理连续的

引用 10 楼 chenhui1990421 的回复:栈在物理内存中是连续的吗？ 未必，你看到我上面的代码了吗， main 函数有两个不同的堆栈 这个一定不会是必然连续的了。 即使一个堆栈，通常都是使用虚拟内存，的物理上一般不连续。  多线程程序，每个程序有多个堆栈； 这些堆栈虚拟地址，也不是连续的； 物理地址上，自然一般不连续。

栈在物理内存中是连续的吗？

引用 7 楼 supermegaboy 的回复:通常需要很大栈空间的行为属于设计错误。 ++

上面的堆栈设置有点错误。 这个是测试过的没问题的。  int const NewSize =1024*1024 *8 /sizeof(int);//8M int run(){      int a[NewSize/2]={0}; 	for(int i=0;i<NewSize/2;i++)a[i] = i; 	printf("address of a = %p,address of a[NewSize/2-1]=%p,  %d\n",a,&a[NewSize/2-1],a[NewSize/2-1]);     return a[NewSize/2-1] ; }  int main(int argc, char* argv[]) {  	static int esp_sav = 0; 	static int ebp_sav = 0; 	static int *stack = new int[NewSize]; 	static int *top   = stack + NewSize -1; 	int a[200]={0};	 	printf("address of a = %p,address of a[100]=%p,  %d\n",a,&a[100],a[100]); 	printf("stack = %p,top =%p \n",stack,top);      	__asm{ 		mov esp_sav,esp 		mov ebp_sav,ebp 		mov esp,top 		mov ebp,esp	 	}  	{ 		printf("%d\n",run()); 		printf("%p\n",esp_sav); 	} 	 	__asm{ 		mov esp,esp_sav 		mov ebp,ebp_sav 	}     delete []stack;  	printf("Hello World!\n"); 	return 0; }

通常需要很大栈空间的行为属于设计错误。

有操作系统支持栈的自动增长的。 平坦模式的os可能有点困难；段模式的os应该比较容易实现。

动态增大栈？没听过，一般都是在事先设置好的。一般没必要用那么大的栈吧，除非递归什么的。不过递归也不建议调大栈空间吧。 动态分配（堆）要说极限的话，逻辑上的问题一般，都是有操作系统来处理的，不一定有多少空间就一定会分配，比如有内存碎片什么的导致空间浪费，硬件上的话，主要还是硬件本身能提供多少的问题吧。

举例：  #include <iostream>  using namespace std;  int a[4][4]={0,1,2,3,}; int firstElem(int a[][4]){  return a[0][0]; } int run(){ cout << firstElem(a)<<",Hello world!" << endl;}; int main() {     static int esp_sav =0;     static int ebp_sav =0;     static char * stack =new char [1024*1024*8];//设置为8M     __asm {         mov esp_sav,esp          mov ebp_sav,ebp                  mov esp ,stack         mov ebp ,esp      }           {            run();     }      __asm {         mov esp,esp_esp          mov ebp,ebp_sav       }     delete []stack ;     return 0; } PS： 这种情况下，异常不好处理。 一般都不会这个干的。

Windows 堆栈空间是属于线程的； Win32 不做任何处理的话，分配默认大小空间(1M 或者2M)； 但是提交很少的内存，随着堆栈空间的增长，逐渐提交，直到用完或者溢出。  如果手动控制的话，可以重新设置新的堆栈的指针，那么堆栈大小就是用户分配的大小。 在函数返回时要恢复堆栈指针，没有恢复之前，不能产生未处理异常。  不过几乎没有代码。手动设置堆栈指针。 这样堆栈的大小是固定的，不过提交的页面是可以动态增加的。  堆栈默认大小，可以在编译时设置，也有预编译指令可以设置，设置的大小也是固定的。


Question: #define CMPAPIENTRY CMPEXPORT CMPRESULT CMPCALL

引用一个个展开就好。  引用 1 楼 yunlongluo 的回复: C/C++ code  #define CMPAPIENTRY CMPEXPORT CMPRESULT CMPCALL  不好意思。 不好意思，还是不太明白，能举个例子解释下吗？

不好意思，还是不太明白，能举个例子解释下吗？

一个个展开就好。  引用 1 楼 yunlongluo 的回复:#define CMPAPIENTRY CMPEXPORT CMPRESULT CMPCALL 不好意思。


Question: 莱鸟求助：c语言写的复数四则运算！！——输入第二个时就不行了，为什么啊~~

[quote=引用 5 楼 zh19921107 的回复:谢谢 	float a,b,c,d; 	Complex   *c1,*c2,*Sum,*Sub,*Mul;  	//指针要先申请空间啊 	c1=(Complex*)malloc(sizeof(Complex)); 	c2=(Complex*)malloc(sizeof(Complex)); 	Sum=(Complex*)malloc(sizeof(Complex)); 	Sub=(Complex*)malloc(sizeof(Complex)); 	Mul=(Complex*)malloc(sizeof(Complex));[/quote]

谢谢各位，已经改好了

Complex   *c1,*c2,*Sum,*Sub,*Mul; //这些都是指针类型哦，没有给谈们分配内存的，所以错了  scanf()//为格式化函数，怎么的格式都要对应起来，

你的输入有问题，输入提示说用空格隔开。scanf("%f %f",&a,&b);这句当中也是用空格隔开 但是你输入的时候却是用，隔开当然会错误了。 你改成scanf("%f%f",&a,&b);去掉当中的空格就可以任意格式了

感谢指点，我再看一看

呵呵，这是逻辑错误啊，你再捋一遍吧，不行就跟着一步一步的调试一下！


Question: 为什么说常量没有地址？

引用 19 楼 drlsdrls 的回复:学过单片机的人一般都不会问这种问题 同意

学习了 。。。。

电脑内存或文件内容只是一个一维二进制字节数组及其对应的二进制地址； 人脑才将电脑内存或文件内容中的这个一维二进制字节数组及其对应的二进制地址的某些部分看成是整数、有符号数/无符号数、浮点数、复数、英文字母、阿拉伯数字、中文/韩文/法文……字符/字符串、汇编指令、函数、函数参数、堆、栈、数组、指针、数组指针、指针数组、数组的数组、指针的指针、二维数组、字符点阵、字符笔画的坐标、黑白二值图片、灰度图片、彩色图片、录音、视频、指纹信息、身份证信息……

引用 5 楼 Adol1111 的回复:楼上的说法都是有问题的，C/C++只有文字常量区，保存的是"hello world"这类字符串。对于1、2、3、'a'这类的数，它们是存放在寄存器上的，没有所谓的内存地址。  C/C++只可以用指针取字符串常量的地址，该类被认为是左值，而其他的字面值常量（literal constant），则被认为是右值，不允许取地址。至于const常量，只能说是一个const修饰的只读变量，和字面值常量不同。

有种东西叫立即数。

有个印象，说是什么被分配在寄存器上面。好像就是常量吧

常量被分配在寄存器上面，是这样不？

引用 30 楼 hangang7403 的回复:常量分几种情况：1、用#define定义的宏，此时其实它是立即数，在编译的时候，会直接写入程序不会占空间 2、用定义一个变量存储了一个常数（其实这时候是一个变量了，要占RAM空间的）； 3、定义在ROM中，如“__ROM"来声明，这时候就占ROM,而不是RAM，我们所说的内存指RAM，所以不占内存。 +1

不要纠结各种常量了，这个世界上唯一不变的就是变化。用API WriteProcessMemory还能修改正运行的其它进程的内存里面的所谓常量呢！

常量存储在全局数据区，是有地址的。

都是有地址的，自己看内存空间吧，好像可以在VC++6.0里调试时看！

要说明这个问题，必须了解cpu的寻址模式，也就是获得数据的方式，一般有寄存器寻址、内存寻址、立即数寻址、变址寻址等方式 常量是会被编译成立即寻址的方式，所谓立即寻址就是常量值作为cpu执行指令的一部分，它不需要另外的寄存器或者内存的支持

引用 22 楼 zhao4zhong1 的回复:因为说这句话的人不懂汇编。 http://bbs.csdn.net/topics/390627329 仔细看了下，屌炸了。 佩服了。

什么是常量？ 什么是rvalue？

涨知识了

引用 6 楼 mr_chenping 的回复:我只说两点： 1、字符串常量是有地址的 p="fuck". 2、数据常量如5、6等，不需要地址存放，它作用是来初始化或者赋值， 左值就成了它的地址，如 int fuck=5.我们使用时是使用fuck，而不是使用5.非要用这个单词吗？为何这样教坏小朋友，可以用gan、cao、cha等简单的单词呀

常量可以有地址，也可以没有。 因此，取常量的地址，可能是错误的。 尤其是，C++整型常量。 最好不要取常量的地址。


Question: 求助大神，这个程序为什么错了？

这道题目目的是什么你都不说··

for(p=a;p<a+10;p++) if(*p>*(p+1)) //当p指向最后一个数组元素时, p+1越界 { t=*p; *p=*(p+1); *(p+1)=t; }  另外排序遍历时可以减少一次循环. 整个升序排序改动如下   for(i=1;i<10;i++){ 			for(p=a;p<a+10-i;p++){ 				if(*p>*(p+1)) 				{ 					t=*p; 					*p=*(p+1); 					*(p+1)=t; 				} 			} 		}


Question: majority算法的执行过程到底是怎么样的啊？？？

女神来这里问问题了。。。

核心思想就是:如果某个数在数组中占多数,那么同时去除一个和该数不同的数,该数仍然在数组中占多数。 巜编程之美＞＞中有寻找发帖水王的例子正是该算法的一个例子。

lz为什么不先搜索一下呢，相信下面的链接可以帮到你： http://hi.baidu.com/gfang/item/5706373b65a88ec7392ffa94


Question: 函数递归的问题

改成尾递归。 少用全局变量或static

引用 9 楼 lm_whales 的回复:静态变量，定义在递归函数内部时，无法多次初始化。 当其它函数，调用递归函数两次以上时，就会出问题。 初始化放在其他地方呢？

另外这个函数，写的有问题 float res ;  res 没有初始化,a >= b  的时候，返回值不确定。 这应该不是，这个函数所需要的吧。   写成这样是否能达到你的目的？  float fun(int a,float b) {     float res = 0;     float sqrt();     if (a < b)         res = sqrt(1 + (a + 1)* fun(a + 1,b));     else         return res; }

其实可以写个函数，调用那个递归函数，外部不使用递归函数。

引用 10 楼 wanglui1990 的回复:[quote=引用 9 楼 lm_whales 的回复:] 静态变量，定义在递归函数内部时，无法多次初始化。 当其它函数，调用递归函数两次以上时，就会出问题。 初始化放在其他地方呢？[/quote] 全局变量，或者文件静态变量之类的，是可以的。  需要在，每次外部调用递归函数之前，重新把这个变量初始化（赋值） 这样一来，还不如传递参数简单。

if (a < b)         res = sqrt(1 + (a + 1)* fun(a + 1)); //人品不差，不过改return较妥...     else         return res; //这个值貌似未初始化，也拼人品是么...

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

静态肯定可以，但你应该没a++之类的语句吧，使a增长吧。而且没看出来哪里递归了。

引用 6 楼 max_min_ 的回复:[quote=引用 5 楼 manjucaka 的回复:] [quote=引用 1 楼 user-9 的回复:] 将a设置为static变量就可以了 int a = 1;改为 static int a = 1静态变量不行[/quote]  可以的吧！ 静态变量！  传参数也行， 全局变量也行！[/quote] 试过了，不行，全局也是不行

引用 5 楼 manjucaka 的回复:[quote=引用 1 楼 user-9 的回复:] 将a设置为static变量就可以了 int a = 1;改为 static int a = 1静态变量不行[/quote]  可以的吧！ 静态变量！  传参数也行， 全局变量也行！

引用 1 楼 user-9 的回复:将a设置为static变量就可以了 int a = 1;改为 static int a = 1静态变量不行

引用 2 楼 baichi4141 的回复:把a和b一起传给函数 可以了

引用 2 楼 baichi4141 的回复:把a和b一起传给函数++

把a和b一起传给函数


Question: 用弦截法求f(x) = 1- cos(x)ch(x)的解。 解的范围是[2 ， 5]。

引用 27 楼 worldy 的回复:[quote=引用 20 楼 u010119353 的回复:] [quote=引用 19 楼 worldy 的回复:] http://blog.csdn.net/worldy/article/details/15341449 运行有错[/quote]  有什么错，将你转换之后的代码发出来我看看[/quote] 我用VC++6.0编的。就是用你的代码，然后就报错了

引用 20 楼 u010119353 的回复:[quote=引用 19 楼 worldy 的回复:] http://blog.csdn.net/worldy/article/details/15341449 运行有错[/quote]  有什么错，将你转换之后的代码发出来我看看

每次求完x[i]的值，要保证f[i]与f[i-1]的值为异号，如为同号，要把x[i-2]的值赋给x[i-1], 在17行加上一条语句试试。 if(f[i]>0&&f[i-1]>0||f[i]<0&&f[x-1]<0) { x[i-1]=x[i-2]; f[i-1]=f[i-2]; }

那你看看函数是否由若干个极值点 只需要其中的一段计算即可。 如果需要都求出来。 分段计算，即可。

#include <stdio.h> #include <math.h>  #include <math.h>  #define N 100000 //最多迭代次数,防止发散  int main() { 	int i; 	double x,x1 = 2.0,x2= 5.0; 	double f,f1,f2;  	f1 = 1 - (cos(x1)*cosh(x1)); 	f2 = 1 - (cos(x2)*cosh(x2));  	for(i=0;i<N;i++) 	{ 	     x = x1 - f1 * (x1 - x2 ) / (f1 - f2); 	     f = 1 - cos(x) * cosh(x);  	     if(fabs(f)<0.001) 		 break; 	    // 这个 要这么处理              if(f* f1<0 ){ x1 =x; f1 = f;}              else {x2 =x;f2=f;}        }        printf("%lf\n", x); 	 	return 0; }

你在代码的头上加上： #ifndef BOOL #define BOOL  unsigned int #endif  然后在我给的函数里有个宏，把它注释掉，就是下面几句 #ifdef _DEBUG 			DEBUG_TRACE("替代次数:",n); #endif

不会吧，你连'BOOL类型都没有定义，你用的什么编译器？

引用 21 楼 worldy 的回复:[quote=引用 20 楼 u010119353 的回复:] [quote=引用 19 楼 worldy 的回复:] http://blog.csdn.net/worldy/article/details/15341449 运行有错[/quote]  不会吧？什么错？[/quote]  BOOL SolveEquation(double xa,double xb,double(*Fun)(double),double& Val,double mErr)都是这句话的 error C2146: syntax error : missing ';' before identifier 'SolveEquation' error C2501: 'BOOL' : missing storage-class or type specifiers fatal error C1004: unexpected end of file found

引用 20 楼 u010119353 的回复:[quote=引用 19 楼 worldy 的回复:] http://blog.csdn.net/worldy/article/details/15341449 运行有错[/quote]  不会吧？什么错？

引用 19 楼 worldy 的回复:http://blog.csdn.net/worldy/article/details/15341449 运行有错

引用 13 楼 worldy 的回复:4.730041? 对的，怎么算的？

仅供参考//用C语言编程，求出sin(x)=(5/6)*x这个方程在区间(0,π/2)的近似解。 #include <math.h> #include <stdio.h> double x,e; void main () {     x=0.001;     e=0.001;     while (1) {         while (1) {             if (sin(x)>5.0/6.0*x) {                 x+=e;             } else {                 break;             }         }         e/=10.0;         if (e<1e-15) break;         while (1) {             if (sin(x)<5.0/6.0*x) {                 x-=e;             } else {                 break;             }         }         e/=10.0;         if (e<1e-15) break;     }     printf("%.14g\n",x); } //1.026738291371

改成这么做试试：  #include <stdio.h> #include <math.h>  #include <math.h>  #define N 100000 //最多迭代次数,防止发散  int main() { 	int i; 	double x,x1 = 2.0,x2= 5.0; 	double f,f1,f2;  	f1 = 1 - (cos(x1)*cosh(x1)); 	f2 = 1 - (cos(x2)*cosh(x2));  	for(i=0;i<N;i++) 	{ 	     x = x1 - f1 * (x1 - x2 ) / (f1 - f2); 	     f = 1 - cos(x) * cosh(x);  	     if(fabs(f-f1)<0.001) 		 break; 	     double mod =(x1+x2)/2;              if(mid >x){ x1 =x; f1 = f;}              else {x2 =x;f2=f;        }        printf("%lf\n", x); 	 	return 0; }

对于 f(x) = 1- cos(x)ch(x)  f(x) = 0  在 2～5 之间，可能有3个解。 你把这个区间，分割成 2~PI,PI~3/2PI,3/2PI~5 试一试。

f(x) = 1- cos(x)ch(x)  f(x) = 0  在函数 cos(x)的每个周期内大约有两个解。 所以弦截法的选点，可能是有问题的。  弦截法在函数凹凸性，相同的区域，效果最好。

引用 10 楼 lm_whales 的回复:[quote=引用 9 楼 u010119353 的回复:] [quote=引用 6 楼 lm_whales 的回复:] 1）i<100,不能保证精度是0.001   2）if(f[i]<0.001 && f[i]>-0.001)            break; 这个判断也是不对的 应该是 abs(f[i]-f[i-1])<0.001 才对。 精度问题还不是大问题，关键是求出来的解不对，差的很大。 不用数组的话迭代有点不方便吧[/quote]   if(f[i]<0.001 && f[i]>-0.001)            break; 不完全是精度问题，这是迭代结束的条件。 只要两次得到的结果之差 ，小于0.001 就满足要求了。 否则，可能会差别很大，或者精度太高，做了许多无用功。  这里只有三个数据 xi ,xi-1,xi-2  // fi,fi-1,fi-2;  //  直接定义成 x,x1,x2            f,f1,f2 你改成这样试试：  #include <stdio.h> #include <math.h>  #include <math.h>  #define N 100000 //最多迭代次数,防止发散  int main() { 	int i; 	double x,x1 = 2.0,x2= 5.0; 	double f,f1,f2;  	f1 = 1 - (cos(x1)*cosh(x1)); 	f2 = 1 - (cos(x2)*cosh(x2));  	for(i=0;i<N;i++) 	{ 		x = x1 - f1 * (x1 - x2 ) / (f1 - f2); 		f = 1 - cos(x) * cosh(x);  		if(fabs(f-f1)<0.001) 			break; 		x2 = x1; 		x1 = x; 		f2 = f1; 		f1 = f; 	} 	printf("%lf\n", x); 	//printf("i=%d,x1= %lf,x2= %lf,f1 = %lf,f2 = %lf\n",i, x1,x2,f1,f2);  	return 0; }  [/quote] 结果还是不对啊

引用 9 楼 u010119353 的回复:[quote=引用 6 楼 lm_whales 的回复:] 1）i<100,不能保证精度是0.001   2）if(f[i]<0.001 && f[i]>-0.001)            break; 这个判断也是不对的 应该是 abs(f[i]-f[i-1])<0.001 才对。 精度问题还不是大问题，关键是求出来的解不对，差的很大。 不用数组的话迭代有点不方便吧[/quote]   if(f[i]<0.001 && f[i]>-0.001)            break; 不完全是精度问题，这是迭代结束的条件。 只要两次得到的结果之差 ，小于0.001 就满足要求了。 否则，可能会差别很大，或者精度太高，做了许多无用功。  这里只有三个数据 xi ,xi-1,xi-2  // fi,fi-1,fi-2;  //  直接定义成 x,x1,x2            f,f1,f2 你改成这样试试：  #include <stdio.h> #include <math.h>  #include <math.h>  #define N 100000 //最多迭代次数,防止发散  int main() { 	int i; 	double x,x1 = 2.0,x2= 5.0; 	double f,f1,f2;  	f1 = 1 - (cos(x1)*cosh(x1)); 	f2 = 1 - (cos(x2)*cosh(x2));  	for(i=0;i<N;i++) 	{ 		x = x1 - f1 * (x1 - x2 ) / (f1 - f2); 		f = 1 - cos(x) * cosh(x);  		if(fabs(f-f1)<0.001) 			break; 		x2 = x1; 		x1 = x; 		f2 = f1; 		f1 = f; 	} 	printf("%lf\n", x); 	//printf("i=%d,x1= %lf,x2= %lf,f1 = %lf,f2 = %lf\n",i, x1,x2,f1,f2);  	return 0; }

引用 6 楼 lm_whales 的回复:1）i<100,不能保证精度是0.001   2）if(f[i]<0.001 && f[i]>-0.001)            break; 这个判断也是不对的 应该是 abs(f[i]-f[i-1])<0.001 才对。 精度问题还不是大问题，关键是求出来的解不对，差的很大。 不用数组的话迭代有点不方便吧


Question: c语言两个指针可以传递地址吗

学习了，谢谢大家，每人十分

a+0 是一个地址，也就是一个常量，不能被修改的。

这个和数组不可以做左值的意思差不多。数组名只是一个标识，或者这儿认为其就是一个地址值。既然，地址值是常量，怎么可以做左值呢。

a+0 = a+3; a+3 = b; 这样做不行的！数组名不能作左值，数组名是常量指针的！ 加一个指针来作中间变量吧！

引用 2 楼 gigglesun 的回复:a+0不是变量名，是一个具体的值了，常值不能被赋值  更进一步：数组名不是变量，不能做 左值

不知道你想干什么 首先：  if (*(a+0) < *(a+3)) { b = a+0;  // 这个赋值是可以的 a+0 = a+3;// a+0是常量不能被修改，就是a=a+3;也不行，a是数组首地址，是const的，不能修改 a+3 = b;  // 错, 同上 }  如果你想交换3和54，可以用  int n = *a; a[0] = a[3]; a[3] = n;

a+0不是变量名，是一个具体的值了，常值不能被赋值

a+0 = a+3; a+3 = b; 这两句是有问题的，=左边的a+0和a+3都是右值是不可能赋值的，你想交换内容的话，应该是 b=a[0];//或者b=*(a+0) a[0]=a[3]; a[3]=b;swap的方法还有很多，自己多试试。不过注意下数组地址是不能修改的，不要用a=b之类的语句。


Question: 关于C语言的一道题

上面少些个大括号，不好意思  char* decode(char* dest, const char* src) {     char c, *p = dest;     for(; c = *src; ++src, ++p){         if(c == ' ') *p = 'j';         else if(c > 'z' || c < 'a') *p = c;         else if(c - 'a' <= 9) *p = c - 'a' + '0';         else if(c - 'a' <= 18) *p = c - 10;         else{              switch(c){                  case 't': *p = '@'; break;                  case 'u': *p = '#'; break;                  case 'v': *p = '$'; break;                  case 'w': *p = '%'; break;                  case 'x': *p = '&'; break;                  case 'y': *p = '!'; break;                  case 'z': *p = '*'; break;             }         }     }     *p = '\0';     return dest; }

lz刚学C吗，字节要多练哦，下面的代码仅供参考  char* decode(char* dest, const char* src) {     char c, *p = dest;     for(; c = *src; ++src, ++p){         if(c == ' ') *p = 'j';         else if(c > 'z' || c < 'a') *p = c;         else if(c - 'a' <= 9) *p = c - 'a' + '0';         else if(c - 'a' <= 18) *p = c - 10;         else switch(c){                  case 't': *p = '@'; break;                  case 'u': *p = '#'; break;                  case 'v': *p = '$'; break;                  case 'w': *p = '%'; break;                  case 'x': *p = '&'; break;                  case 'y': *p = '!'; break;                  case 'z': *p = '*'; break;              }         }     }     *p = '\0';     return dest; }

说说我的思路，建立一个电文和译文一一对应的线性表，由于a,b,c,...，z是顺序的可以用数组结构，查表复杂度为O（1）。对已给定序列依次取出其中元素，如果遇到空格则转换为j，如果不是空格则查表取得对应转换的字符，知道电文末尾


Question: 自己总结的列指针和行指针，大家看有什么错误没

引用 12 楼 u011488256 的回复:[quote=引用 11 楼 lm_whales 的回复:] 动态分配的内存，由于数据本身没有名字，只能通过指针进行操作； 所以需要格外注意，别把这个指针弄丢了。 丢了以后，就会造成内存泄露； 程序可分配内存不断减少，终有内存耗尽之时。  这里也只是提示一下，而已。 指针操作，对于于非动态分配的，还好一点。 动态分配的内存，就要仔细处理了，稍一疏忽，就可能出错。  指针，是C的难点，也是重点，据说没有学会指针，就不算学会了C  C++ ，多态（运行时多态），只能通过，类的继承，虚函数，配合指针和引用实现。 不过引用限制太多，实际上几乎都是用的指针。  想问一下关于内存泄露，如果我这个程序关闭，那原来泄露的内存windows还会使用么[/quote]  内存泄露，在windows 98 以前，问题很严重，以后的操作系统，就不是很严重了。 主要是，进程隔离的比较好，系统在进程结束后，回收全部资源。  这样，内存泄露主要影响，就表现在你的程序的稳定性，和健壮性了的。 对外部（其他程序），几乎没有影响。  对于长期运行的程序，绝对不能有内存泄露。 内存泄露造成 1）内存碎片化严重。分配出去的某些内存，不能回收了（就像大块的东西，从中间烂了个洞）。 2）可用内存不断减少。没有回收内存，所以不能再次利用。 3）直到内存耗尽，不能继续分配内存，程序崩溃。

指针总有说不完的话题！

引用 11 楼 lm_whales 的回复:动态分配的内存，由于数据本身没有名字，只能通过指针进行操作； 所以需要格外注意，别把这个指针弄丢了。 丢了以后，就会造成内存泄露； 程序可分配内存不断减少，终有内存耗尽之时。  这里也只是提示一下，而已。 指针操作，对于于非动态分配的，还好一点。 动态分配的内存，就要仔细处理了，稍一疏忽，就可能出错。  指针，是C的难点，也是重点，据说没有学会指针，就不算学会了C  C++ ，多态（运行时多态），只能通过，类的继承，虚函数，配合指针和引用实现。 不过引用限制太多，实际上几乎都是用的指针。  想问一下关于内存泄露，如果我这个程序关闭，那原来泄露的内存windows还会使用么

计算机组成原理→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对应的汇编并单步执行观察相应内存和寄存器变化。）  想要从本质上理解C指针，必须学习汇编以及C和汇编的对应关系。 从汇编的角度理解和学习C语言的指针，原本看似复杂的东西就会变得非常简单！ 指针即地址。“地址又是啥？”“只能从汇编语言和计算机组成原理的角度去解释了。” 但我又不得不承认：  有那么些人喜欢或者适合用“先具体再抽象”的方法学习和理解复杂事物；  而另一些人喜欢或者适合用“先抽象再具体”的方法学习和理解复杂事物。 而我本人属前者。  这辈子不看内存地址和内存值；只画链表、指针示意图，画堆栈示意图，画各种示意图，甚至自己没画过而只看过书上的图……能从本质上理解指针、理解函数参数传递吗？本人深表怀疑！ 这辈子不种麦不收麦不将麦粒拿去磨面；只吃馒头、吃面条、吃面包、……甚至从没看过别人怎么蒸馒头，压面条，烤面包，……能从本质上理解面粉、理解面食吗？本人深表怀疑！！  提醒： “学习用汇编语言写程序” 和 “VC调试(TC或BC用TD调试)时按Alt+8、Alt+7、Alt+6和Alt+5,打开汇编窗口、堆栈窗口、内存窗口和寄存器窗口看每句C对应的汇编、单步执行并观察相应堆栈、内存和寄存器变化，这样过一遍不就啥都明白了吗。 （Linux或Unix下可以在用GDB调试时,看每句C对应的汇编并单步执行观察相应内存和寄存器变化。） 想要从本质上理解C指针，必须学习C和汇编的对应关系。” 不是一回事！  不要迷信书、考题、老师、回帖； 要迷信CPU、编译器、调试器、运行结果。 并请结合“盲人摸太阳”和“驾船出海时一定只带一个指南针。”加以理解。 任何理论、权威、传说、真理、标准、解释、想象、知识……都比不上摆在眼前的事实！  有人说一套做一套，你相信他说的还是相信他做的？ 其实严格来说这个世界上古往今来所有人都是说一套做一套，不是吗？  不要写连自己也预测不了结果的代码！  电脑内存或文件内容只是一个一维二进制字节数组及其对应的二进制地址； 人脑才将电脑内存或文件内容中的这个一维二进制字节数组及其对应的二进制地址的某些部分看成是整数、有符号数/无符号数、浮点数、复数、英文字母、阿拉伯数字、中文/韩文/法文……字符/字符串、汇编指令、函数、函数参数、堆、栈、数组、指针、数组指针、指针数组、数组的数组、指针的指针、二维数组、字符点阵、字符笔画的坐标、黑白二值图片、灰度图片、彩色图片、录音、视频、指纹信息、身份证信息……  十字链表交换任意两个节点C源代码（C指针应用终极挑战）http://download.csdn.net/detail/zhao4zhong1/5532495

引用 7 楼 lm_whales 的回复:void ceshi2() { 	int i;    int **t;    int *p;    int  *a[3];    t=a;    //使一个指针的指针指向一个指针数组  for (i=0;i<3;i++) { a[i]=(int*)malloc(sizeof(int)*6); } //给a[i]数组里面的指针指向一个长度为6的int 内存空间  p=t[2]; //这个时候的p相当于等于a[2]; 他指向的是一个长度为6的int 空间  p=t[0]+1; //p等于a[1]; printf("p = %p,t = %p,*t =%p ,a=%p,a[0]=%p,a[2]=%p\n",p,t,*t,a,a[0],a[2]); p=(*t)++; //这个又是什么意思呢？ a【1】里面的地址内容自己+1然后给p？ //不是，他表示p指向了a[0]里面的第2个int空间。 //PS: 这是找死,*t 是动态分配的，改掉以后，无法释放内存。 printf("p = %p,t = %p,*t =%p ,a=%p,a[0]=%p,a[2]=%p\n",p,t,*t,a,a[0],a[2]); //	所以这里相当于行指针和列指针。 //之前总是在这里把他弄混 // 还有**一定要一级一级的赋值 p = (*t)--; printf("p = %p,t = %p,*t =%p ,a=%p,a[0]=%p,a[2]=%p\n",p,t,*t,a,a[0],a[2]); for(i=0;i<3;i++)      free(a[i]); }   只是写个范例··罢了··

行指针和列指针? 伪命题！

int a[4][4]; int *p; p=a;//让指针P 指向一个二维数组 看到这里就错了。

引用 5 楼 user-6 的回复:[quote=引用 4 楼 u011488256 的回复:] [quote=引用 2 楼 user-6 的回复:] 楼主，你申明一个指针*p，如果指向一维数组，他就是只能*p一次，指向二位数组他能**p运算，即同指向指针的指针，如果指向三维数组，他能***p运算，即同指向一个指针，这个指针是指向指针的指针。  2L 是想说 我ceshi2函数 里面的 int *p么 [/quote]我是说的一般情况，我要表达的意思是你只定义一个指针*p,你把他指向2维数组的时候，他就成了指向指针的指针了，即可以**p运算了.[/quote] 那你说的意思 还是1L的意思吧？ 我那个地方已经改过来了

引用 4 楼 u011488256 的回复:[quote=引用 2 楼 user-6 的回复:] 楼主，你申明一个指针*p，如果指向一维数组，他就是只能*p一次，指向二位数组他能**p运算，即同指向指针的指针，如果指向三维数组，他能***p运算，即同指向一个指针，这个指针是指向指针的指针。  2L 是想说 我ceshi2函数 里面的 int *p么 [/quote]我是说的一般情况，我要表达的意思是你只定义一个指针*p,你把他指向2维数组的时候，他就成了指向指针的指针了，即可以**p运算了.

引用 2 楼 user-6 的回复:楼主，你申明一个指针*p，如果指向一维数组，他就是只能*p一次，指向二位数组他能**p运算，即同指向指针的指针，如果指向三维数组，他能***p运算，即同指向一个指针，这个指针是指向指针的指针。  2L 是想说 我ceshi2函数 里面的 int *p么

引用 1 楼 lm_whales 的回复:p = a; p和a 类型不兼容（不同），不一定可以编译通过。 p 类型为 int *;  a 类型为 int a[4][4] 参数传递，可以和以下两种都兼容，因为这两种形式可以看作一种。 ==> int a[][4]; ==>int (*)[4];  直接赋值，参与算术运算，或者指针解引用，可以看作 ==>int (*)[4];  不好意思  你说的地方  定义int *p  应该 改成 int （*p）【4】  谢谢


Question: c语言文件问题

先分清楚2进制模式和文本模式的差别...

写文件错误 屯是0xcdcd，明显是在VS的调试模式下把未赋值的栈内存写进去了

你的文件不支持，---- 实际是操作系统，或者编辑器不支持---双字节字符，直接.txt 格式查看。

代码太少，你应该看看你文件操作部分（打开、读取、关闭），是不是都是正确的。我想应该是你读取文件了，但是操作之前应该判断读出来的是否是你想要的，毕竟字段之间还有空格或者tab键。这写内容也是会读出的。但是显示的时候课可能就是乱码了。


Question: char二维数组初始化问题。

引用 14 楼 zhao4zhong1 的回复:上帖后面少逗号，纠正如下： char *list[5][6]={     "TW"  ,"NULL","NULL","TW"  ,"NULL","NULL",     "NULL","+TW" ,"NULL","NULL","NULL","NULL",     "FR"  ,"NULL","NULL","FR"  ,"NULL","NULL",     "NULL","NULL","*FR" ,"NULL","NULL","NULL",     "ID"  ,"NULL","NULL","(E)" ,"NULL","NULL", }; //或 char list[5][6][5]={     "TW"  ,"NULL","NULL","TW"  ,"NULL","NULL",     "NULL","+TW" ,"NULL","NULL","NULL","NULL",     "FR"  ,"NULL","NULL","FR"  ,"NULL","NULL",     "NULL","NULL","*FR" ,"NULL","NULL","NULL",     "ID"  ,"NULL","NULL","(E)" ,"NULL","NULL", };  正解！

你这个是一个char类型的字符二维数组，一共有30个元素，每个元素为char类型，而不是char指针类型，然而你的初始化当中都是用"TEST"这样的表达式，这是一个字符串的指针char*类型，和char类型是不同的，如果你想存储这30个字符串的话，可以声明成：char* ch[30]，声明30个指向char类型的指针，每个指针用来存储字符串的首地址。

引用 4 楼 user-16 的回复:error C2078: 初始值设定项太多 char[5][6]是5*6个字符不是5*6个字符串+1

"NULL"是一个字符串，所以二维数组的元素要嘛char *,要嘛 char[5]  参看14L

首先，肯定是超了。 其次，赵老师的答案是对的。

数组名不能为list，你改一个别的试一试

char list[5][6] 表示的是30个char类型，你初始化的“tw”之类的是字符串啊。肯定出错啊。 正确的方法是，如果你要写30个，就写30个字符。或者5个长度小于6的字符串。 比如： char list[5][6]={'1','2','3','4',。。。。。,'30'}; or char list[5][6] = {"123456","345","456","34","ddg"};

明显数组越界了么！

char *list[5][6]={     "TW"  ,"NULL","NULL","TW"  ,"NULL","NULL"     "NULL","+TW" ,"NULL","NULL","NULL","NULL"     "FR"  ,"NULL","NULL","FR"  ,"NULL","NULL"     "NULL","NULL","*FR" ,"NULL","NULL","NULL"     "ID"  ,"NULL","NULL","(E)" ,"NULL","NULL" }; //或 char list[5][6][5]={     "TW"  ,"NULL","NULL","TW"  ,"NULL","NULL"     "NULL","+TW" ,"NULL","NULL","NULL","NULL"     "FR"  ,"NULL","NULL","FR"  ,"NULL","NULL"     "NULL","NULL","*FR" ,"NULL","NULL","NULL"     "ID"  ,"NULL","NULL","(E)" ,"NULL","NULL" };

数组越界了；      可以定义成 char* List[5][6] = {...};形式，   这样就可以保证定义的是一个字符串指针的二维数组。

你那根本就不是5*6＝30个字符呀……。当然会错

（1） char list[][6] ={"TW","NULL","NULL", "TW","NULL","NULL",            	 "NULL","+TW","NULL","NULL","NULL","NULL",	                  "FR","NULL","NULL","FR","NULL","NULL",	                  "NULL","NULL","*FR","NULL","NULL","NULL",                  "ID","NULL","NULL","(E)","NULL","NULL"  }; 等价于 char list[30][6] = {"TW","NULL","NULL", "TW","NULL","NULL",            	 "NULL","+TW","NULL","NULL","NULL","NULL",	                  "FR","NULL","NULL","FR","NULL","NULL",	                  "NULL","NULL","*FR","NULL","NULL","NULL",                  "ID","NULL","NULL","(E)","NULL","NULL"  }; (2) const char* list[5][6] = { {"TW","NULL","NULL", "TW","NULL","NULL"} {"NULL","+TW","NULL","NULL","NULL","NULL"}	 {"FR","NULL","NULL","FR","NULL","NULL"}	 {"NULL","NULL","*FR","NULL","NULL","NULL"} {"ID","NULL","NULL","(E)","NULL","NULL"} };

原来是char啊！ 楼主改成''吧

你完全理解错了,char [5][6]是分配5个长度最多为6的字符串，而不是5*6个字符串.... C++的话用string就好了(不是C)。 string list[5][6]={"TW","NULL","NULL", "TW","NULL","NULL",            	 "NULL","+TW","NULL","NULL","NULL","NULL",	  "FR","NULL","NULL","FR","NULL","NULL",	                  "NULL","NULL","*FR","NULL","NULL","NULL",                  "ID","NULL","NULL","(E)","NULL","NULL"  };C的话，直接分配char list[30][]或者list[5][6][]，或者自己定义struct什么的，自己组建一个字符串类型

{ {"TW","NULL","NULL", "TW","NULL","NULL"} {"NULL","+TW","NULL","NULL","NULL","NULL"}	 {"FR","NULL","NULL","FR","NULL","NULL"}	 {"NULL","NULL","*FR","NULL","NULL","NULL"} {"ID","NULL","NULL","(E)","NULL","NULL"} }; 试试

引用 1 楼 derekrose 的回复:compile error？[Error] C:\Users\Administrator\Desktop\实验二\SemanticalAnalysis.cpp:36: error: too many initializers for `char[5][6]'


Question: 一道C语言练习题，不知道错在哪里！！！

你要是用OJ的话，把程序里面开始的打印信息去掉！！  引用 13 楼 CLD1994 的回复:[quote=引用 12 楼 lunat 的回复:] 死了一堆脑细胞！自己测一下！   #include <stdio.h>  int main() { 	unsigned int m = 0, n = 0, i, k = 1, k1 = 1, x, y, v; 	unsigned int values[10] = {0}; 	 	printf("Please input n:"); 	scanf("%u", &n);	 	 	v = n / 10; 	 	//k 第m位单位 	//k1 第m-1位单位  	while(1) 	{ 		x = n % k; 		  // 余下所有值  		y = (n / k) % 10; // 第m位数  		 		for (i = 0; i < 10; i++) 		{ 			values[i] += y * m * k1; 		}   		for (i = 1; i < y; i++) 		{ 			values[i] += k;	 		} 		 		if (y > 0) 		{ 			values[y] += x + 1;			 		} 		 		values[0] -= k1 - 1;  		if (k > v) 		{ 			break; 		} 		 		k *= 10; 		 		if (m++ > 0) 		{ 			k1 *= 10; 		}	 	}      for(i = 0; i < 10; i++)      {      	printf("%u\n", values[i]);     }       return 0; }  程序是对的，但是提交上去还是显示运行错误65%。哎。。算了，改天去问问老师~[/quote]

引用 12 楼 lunat 的回复:死了一堆脑细胞！自己测一下！   #include <stdio.h>  int main() { 	unsigned int m = 0, n = 0, i, k = 1, k1 = 1, x, y, v; 	unsigned int values[10] = {0}; 	 	printf("Please input n:"); 	scanf("%u", &n);	 	 	v = n / 10; 	 	//k 第m位单位 	//k1 第m-1位单位  	while(1) 	{ 		x = n % k; 		  // 余下所有值  		y = (n / k) % 10; // 第m位数  		 		for (i = 0; i < 10; i++) 		{ 			values[i] += y * m * k1; 		}   		for (i = 1; i < y; i++) 		{ 			values[i] += k;	 		} 		 		if (y > 0) 		{ 			values[y] += x + 1;			 		} 		 		values[0] -= k1 - 1;  		if (k > v) 		{ 			break; 		} 		 		k *= 10; 		 		if (m++ > 0) 		{ 			k1 *= 10; 		}	 	}      for(i = 0; i < 10; i++)      {      	printf("%u\n", values[i]);     }       return 0; }  程序是对的，但是提交上去还是显示运行错误65%。哎。。算了，改天去问问老师~

scanf("%u", &d)

代码没有问题，我用楼主的代码在VC6.0中能够正确运行！ #include <stdio.h> int main()  {     int i,t,n;     int count[10] = {0};     scanf("%d",&n);     for(i = 1; i <= n; i++)      {         t = i;         while(t)         {             count[t%10]++;             t/=10;         }     }     for(i = 0; i < 10; i++)  		printf("数字%d用到的次数：%d\n",i, count[i]); 	return 1; }

好像是算法比较烂···计算时间超时了。。。谁能教教我怎么写简单？

还真看不出来。觉得没有问题耶！试着用楼上说的 int main（） 加个返回值试试！

都应该用unsigned int，并且如果n输入超过范围要舍弃。  引用 楼主 CLD1994 的回复:一本书的页码从自然数1 开始顺序编码直到自然数n。书的页码按照通常的习惯编排，  每个页码都不含多余的前导数字0。例如，第6 页用数字6 表示，而不是06 或006 等。数  字计数问题要求对给定书的总页码n，计算出书的全部页码中分别用到多少次数字0，1，  2，…，9。 输入 给出表示书的总页码的整数n（1≤n≤2^31-1）   输出 输出10行，在第k行输出页码中用到数字k-1 的次数，k=1，2，…，10。   我的代码如下。求解错在哪里。判定平台说运行错误。。。 #include <stdio.h> main()  {     int i,t,n;     int count[10] = {0};     scanf("%d",&n);     for(i = 1; i <= n; i++)      {         t = i;         while(t)         {             count[t%10]++;             t/=10;         }     }     for(i = 0; i < 10; i++)      printf("%d\n", count[i]); }

暂时没看出错误来，能不能把错误贴出来。如果一定要说有错的话就是风格问题。你的main函数写的不合规定。要改成这种int main()  { 	return 0; }C/C++标准只允许int返回型的main，void虽然不算错但不是标准，但你的光秃秃的main肯定算错（VC6等老编译器不算）

引用 5 楼 CLD1994 的回复:我加了unsigned int。加了int main() return 0; 但是还是错误····   还有个可能性，你输入的n太大了，计算时间比较长，耐心等待就好了。当然也可能会因为太大溢出了。 最好贴下错误。

2^31-1 =2147483647 也可能是有溢出。 这是个10位数， 下面  是（0～9）总个数统计： 1 位数 10个   2位数  90*2个  3位数  900*3个 4位数  9000*4个   。。。。。 9 位数 有 900000000*9个 1000000000 ～2000000000-1 和  9 位数 个数相同  这就有18 * 900000000 个数字了   这样平均 每个数字的个数为 1.8*900000000 =16.2 *100000000  所以，非常有可能会溢出。    而楼主的时间复杂度是  ∑log i （i=1~n)   大概是 = O(N log N) ~ O(N （log N)^2)  而这个 问题的时间复杂度,大约只需要O(10*（logN）^2)==> O (log*N) < O(N) ; c=10  不妨，先计算一下, 统计 1000000000 ～2000000000 的每个数字的个数，时间复杂度是多少。 1000000000 ～2000000000 大约就是 N log(N) 了

估计时间复杂度，比较高超时了。

LZ 我这里运行也没有错误哦


Question: 以每行一个单词的形式打印其输出，用数组时输出的每行的一个字符都是取址符？？

a!it should be s[0]=c!! 又犯二了

c=s[0] ???  s[0] == ?????????

自己帮顶一下~ 弱菜新手好纠结~~


Question: c语言 文件

桌面上？你的源文件放在那里？

太感谢了！！

if((fp=fopen("file1.txt","w"))==NULL) { printf("meichaodao\n"); fprintf(stderr, "%d : %s\n", __LINE__, strerror(errno)); getch(); exit(1); } 不好意思，有问题，现在改过来了。

printf("meichaodao\n"); 这条语句是否打印，如果打印了那是没建立文件。你也可以加上一句  if((fp=fopen("file1.txt","w"))==NULL) { printf("meichaodao\n"); fprintf(stderr, "%d : %s\n", strerror(errno)); getch(); exit(1); }   如果没打印那句话，那么查看一下你的文件保存路径。


Question: 如何灵活快捷的存储多媒体缓存

P2P是将文件分块存储的，元信息(meta)无非就是一个文件有多少块，每块多大，每块的sha1/md5。

日哦，搞终端的，虽然经常接触流，但也只会用，不会编啊，坐等big cow

自顶 就关注。。。

自顶 就关注。。。


Question: 程序的效率问题

引用 3 楼 cfjtaishan 的回复:效率上考虑，需要从时间和空间两方面考虑的吧。 但从时间上考虑，第二种循环的次数较第一种循环次数少哦。所以，第二种效率稍微高一些。 确实是这样的，但是有没有更高的方法呢？

引用 1 楼 user-2 的回复:都不高，判断是否是质数，只要从2到 根号n就可以，第二个虽然是i不会超过根号n，但是循环每次都做乘法，没有必要 int mMax=sqrt(n); for(i=2;i<=mMax;i++)   if(n % i==0) return false; return true; 额，这个我也知道，只是不想调用math头文件了

引用 4 楼 siaswj 的回复:[quote=引用 3 楼 cfjtaishan 的回复:] 效率上考虑，需要从时间和空间两方面考虑的吧。 但从时间上考虑，第二种循环的次数较第一种循环次数少哦。所以，第二种效率稍微高一些。 确实是这样的，但是有没有更高的方法呢？[/quote] 你的第二种方法和调用数学库函数sqrt很相似，或者说就是一个思路。


Question: 麻烦各位前辈进来帮我找下错误-关于建立一个矩阵出错

已经解决了。不用再看了


Question: 麻烦各位前辈进来帮我找下错误-关于建立一个矩阵

额  我以为你要求矩阵中最大的数，看错了，不好意思

引用 4 楼 N_sev7 的回复:[quote=引用 2 楼 sbtxt 的回复:] 谢谢大哥，你是我的恩人。才开始学C语言，很多地方不还不懂。太感谢你了。 以后像这样的判断是否相等的表达式，最好写成  NULL == p[i]    ////这样即使你不注意少写一个"="号，编译器也能帮你检查出来错误 [/quote] 嗯 谢谢你的指导。

引用 3 楼 N_sev7 的回复:[quote=引用 2 楼 sbtxt 的回复:] 谢谢大哥，你是我的恩人。才开始学C语言，很多地方不还不懂。太感谢你了。 貌似你的打印的最大值的行列结果是错误的...[/quote] 是错的吗？我重新试了下，没错啊。

引用 2 楼 sbtxt 的回复:谢谢大哥，你是我的恩人。才开始学C语言，很多地方不还不懂。太感谢你了。 以后像这样的判断是否相等的表达式，最好写成  NULL == p[i]    ////这样即使你不注意少写一个"="号，编译器也能帮你检查出来错误

引用 2 楼 sbtxt 的回复:谢谢大哥，你是我的恩人。才开始学C语言，很多地方不还不懂。太感谢你了。 貌似你的打印的最大值的行列结果是错误的...

谢谢大哥，你是我的恩人。才开始学C语言，很多地方不还不懂。太感谢你了。

if(p[i]=NULL)  //////p[i] = NULL 确定不是  p[i] == NULL { printf("No enough memory!\n"); freeMemory(p,row); return; }


Question: c语言结构体和指针的问题

太感谢了！！

没有分配内存，非法访问， 看看 已经帮你修改过来了  #include<stdio.h> #include<stdlib.h>  struct inf { 	int num;	 	char name[12]; };  int main() { 	FILE *fp; 	struct inf *p = (struct inf *)malloc(sizeof(struct inf)); 	scanf("%d",&p->num); 	scanf(" %s",p->name); 	fp=fopen("test.txt","wb");  	if (fp == NULL)   	{   	    printf("open the file failed!\n"); 	    return 0;	      } 	fwrite(p,sizeof(struct inf),1,fp);// 检查下返回值  	 	printf("%d \n",p->num); 	printf("%s\n",p->name); 	fclose(fp); 	return 0; }

struct inf *p; 你这个指针指向谁呢？你没有实际定义