Question: 哪位老师讲解的算法比较好，求推荐。有视频的。

数据结构的视频我强烈推荐郝斌的。。

国外的麻省理工的算法导论，国内的就是严蔚敏的视频。国外的比较经典但不一定适合国情，可以先看看国内的。大话数据结构一书基本是严蔚敏版教材的详解版，可以做参考教材！

引用 6 楼 fetag 的回复:其实我觉得我讲的很不错...真心话~~ 额，有视频嘛？话说，自学真的好难

mit的，还有knuth的art貌似也非常经典。

其实我觉得我讲的很不错...真心话~~

引用 1 楼 user-11 的回复:- -！ 推荐《麻省理工学院公开课:算法导论》，结合《算法导论》一书不错，， 不过我还是推荐你去看严蔚敏的视频---《数据结构》~~~  关键是学得好

1、如果仅仅是入门，知道基本的栈、队列、链表等数据结构，清华严蔚敏版的差不多了。  2、如果需要进一步提高，了解各种排序算法的优劣及深入原理，学会使用动态规划和贪心算法，以及一些高级数据结构，比如图、红黑树、堆、二叉平衡树等的实现及机制。那么，首推《算法导论》，目前中文版只有第二版的，第三版的英文版也已经有了。相关视频，在网易公开课中有，麻省的，该书的作者主讲。  此外，对于《算法导论》这本书，不要作为教科书来看，除非你要参加ACM这种大赛做集训，一般情况下，你只需要重点学习吃透其中的2、6、7、10、11、15、16、22章就够了，这几章你吃透，基本可以秒杀90%以上的程序猿面试题了（包括MS, GOOGLE的）。

引用 1 楼 user-11 的回复:- -！ 推荐《麻省理工学院公开课:算法导论》，结合《算法导论》一书不错，， 不过我还是推荐你去看严蔚敏的视频---《数据结构》~~~ 1.麻省理工学院公开课:算法导论(在线)：http://edu.51cto.com/lesson/id-2236.html 语言是英文的，不过字幕已经被翻译为中文。 2.数据结构经典疑难问题视频讲解（在线）：http://edu.51cto.com/course/course_id-158.html 这个主要是描述问题，然后如何用程序实现，没有巧妙的算法，但是解决问题的方法还可以。 3.清华大学《数据结构与算法》课程（严蔚敏）（在线）：http://edu.51cto.com/lesson/id-4133.html 4.郝斌数据结构：下载地址参见：http://www.52pojie.cn/thread-130075-1-1.html 书籍使用的是严蔚敏的。

引用 1 楼 user-11 的回复:- -！ 推荐《麻省理工学院公开课:算法导论》，结合《算法导论》一书不错，， 不过我还是推荐你去看严蔚敏的视频---《数据结构》~~~  ++


Question: typedef struct有:号是什么总思？

位域，编译器是看做两个结构体的！

给你个范例参考，使用位段获取整数不同的位   #include <stdio.h>  union decompose{ 	int integer; 	struct{ 		unsigned int w0 : 16; 		unsigned int w1 : 16; 	}w16;  	struct{ 		unsigned int bt0 : 8; 		unsigned int bt1 : 8; 		unsigned int bt2 : 8; 		unsigned int bt3 : 8; 	}bt8;  	struct{ 		unsigned int hex0 : 4; 		unsigned int hex1 : 4; 		unsigned int hex2 : 4; 		unsigned int hex3 : 4; 		unsigned int hex4 : 4; 		unsigned int hex5 : 4; 		unsigned int hex6 : 4; 		unsigned int hex7 : 4; 	}hex4;  	struct{ 		unsigned int b0 : 1; 		unsigned int b1 : 1; 		unsigned int b2 : 1; 		unsigned int b3 : 1; 		unsigned int b4 : 1; 		unsigned int b5 : 1; 		unsigned int b6 : 1; 		unsigned int b7 : 1; 		unsigned int b8 : 1; 		unsigned int b9 : 1; 		unsigned int b10 : 1; 		unsigned int b11 : 1; 		unsigned int b12 : 1; 		unsigned int b13 : 1; 		unsigned int b14 : 1; 		unsigned int b15 : 1; 		unsigned int b16 : 1; 		unsigned int b17 : 1; 		unsigned int b18 : 1; 		unsigned int b19 : 1; 		unsigned int b20 : 1; 		unsigned int b21 : 1; 		unsigned int b22 : 1; 		unsigned int b23 : 1; 		unsigned int b24 : 1; 		unsigned int b25 : 1; 		unsigned int b26 : 1; 		unsigned int b27 : 1; 		unsigned int b28 : 1; 		unsigned int b29 : 1; 		unsigned int b30 : 1; 		unsigned int b31 : 1; 	}b32; }; /* 此宏定义不能用于循环，即n不能是变量，只能是数字  * 因此比较适用与零散获取位状态或者字节状态  */ #define GETWORD(x, n) (((union decompose){.integer = x}).w16.w##n)  #define GETBYTE(x, n) (((union decompose){.integer = x}).bt8.bt##n)  #define GETHEX(x, n) (((union decompose){.integer = x}).hex4.hex##n)  #define GETBIT(x, n) (((union decompose){.integer = x}).b32.b##n)   void test_getx() { 	int tmp = 0x0f0f0f0f; 	int i; 	printf("%X\n", GETBYTE(tmp, 0)); 	printf("%X\n", GETBYTE(tmp, 1)); 	printf("%X\n", GETBYTE(tmp, 2)); 	printf("%X\n", GETBYTE(tmp, 3));  	printf("%X", GETHEX(tmp, 0)); 	printf("%X", GETHEX(tmp, 1)); 	printf("%X", GETHEX(tmp, 2)); 	printf("%X", GETHEX(tmp, 3)); 	printf("%X", GETHEX(tmp, 4)); 	printf("%X", GETHEX(tmp, 5)); 	printf("%X", GETHEX(tmp, 6)); 	printf("%X\n", GETHEX(tmp, 7));  	printf("%d", GETBIT(tmp, 0)); 	printf("%d", GETBIT(tmp, 1)); 	printf("%d", GETBIT(tmp, 2)); 	printf("%d", GETBIT(tmp, 3)); 	printf("%d", GETBIT(tmp, 4)); 	printf("%d", GETBIT(tmp, 5)); 	printf("%d", GETBIT(tmp, 6)); 	printf("%d", GETBIT(tmp, 7)); 	printf("%d", GETBIT(tmp, 8)); 	printf("%d", GETBIT(tmp, 9)); }  int main() { 	test_getx();	 	return 0; }

为了节省存储空间，并使处理简便，Ｃ语言又提供了一种数据结构，称为“位域”或“位段”。所谓“位域”是把一个字节中的二进位划分为几个不同的区域，并说明每个区域的位数。每个域有一个域名，允许在程序中按域名进行操作。 这样就可以把几个不同的对象用一个字节的二进制位域来表示。

google 位域

这个位域，楼主先百度下，然后再编程看看。。。理论+实践

位域。 使用时应该注意字节对齐问题：http://kofsky.iteye.com/blog/211686

位域，节约内存，更好的cache。

位域 很精细，我就在设计的通信协议里面用过~~~

参考http://blog.sina.com.cn/s/blog_3d8529400100istl.html  引用 楼主 aree 的回复:typedef struct {    unsigned COMPLETED      : 1;    unsigned A             : 1;    unsigned st_1          : 27; } TEST_O, *PTEST_O;  typedef struct {    unsigned COMPLETED      : 1;    unsigned st_2          : 28; } TEST_O, *PTEST_O;  请教一下，这个结构的的 : 号表示什么意思？与普通结构体定义不太一样，有:号的。 另外，上面这2个结构体是一样的吗？

那上面这2个结构体是不样的吗？ 不能替换吧。

位域 表示 这个变量占多少个位（一个字节8个位）

位域

说明定义的变量只占用该类型的1位，两个结构体的大小一样。


Question: C语言 循环使用fwrite

fwrite 有返回值啊你可以累加这个返回值来得到已经写的数据量，此外，你可以借助 fseek定位到文件的位置进行读写

引用 7 楼 haoba74257 的回复:关键是 怎么循环写呢？？？ 不会用啊  这个fwrite函数 如果想循环使用的话 假如每次写入1M字节的话，下次写的时候是不是从1M处开始写呢？？？怎么定位呢???  要写的总大小已经知道了，每次定量写多少，写多少次循环，你自己决定就好了！ 是的，当你写了1M之后，只要文件没有关闭或者没有手动移动文件描述符fw的话，会在1M字节后面开始写的， 这个不需要我们定位的，fw文件描述符会搞定的

10*1024*1024 ,10M读写，没有问题吧？？？ 不能一次读写，每次读1024 总可以吧 每次写成功指针，递增1024，就行了。 10×1024次完成。

fwrite()+fseek() 读多少就偏移多少

可以将数据分成几份，然后循环读取，放到指定的缓存里。这个不是特别难实现，不过需要注意读取（实际读取）的字节数，和存放缓存的指定位置。

static char dataread[10*1024*1024]=""; 在占用内存空间较大的局部数组声明的前面加static将其从堆栈数据段挪到全局数据段即可避开因局部数组大小超过默认堆栈大小1MB造成程序不能正常运行的问题。

不是很明白意思   一次读10M 确实有点多了，就读 4K 吧   int main() {    int time;    int i;    time = 10*1024*1024/4096;     for (i = 0; i < time; i++) {        read(); /* read data */        write(); /* write to file */    } }

推荐使用WinHex软件查看硬盘或文件或内存中的原始字节内容。  不要把 fopen("...","...");fscanf,fprintf,fclose //读时把\r\n替换成\n，写时把\n替换成\r\n;读到\x1a就设置EOF;读写的内容当字符看待 和 fopen("...","...b");fread,fwrite,fclose  //不作以上替换，遇到\x1a仍继续读;读写的内容当字节看待 弄混了


Question: 指标内容重新设的问题

引用 2 楼 shanwu1985 的回复:我百度了一下，它说是在文字常量区… 能不能请前辈介绍一本书，让我能学更完整一些 :)      [quote=引用 1 楼 user-1 的回复:]  char *ptr="hello";静态区的，可读不可以改的！  用char ptr[10] = "hello";[/quote] 字符串常量应该是存储在静态存储区， 你说的文字常量区貌似比较少听到，应该也是静态存储区的吧！

这边有也有解说，给有同样问题的其它人参考下

我百度了一下，它说是在文字常量区… 能不能请前辈介绍一本书，让我能学更完整一些 :)      引用 1 楼 user-1 的回复:char *ptr="hello";静态区的，可读不可以改的！  用char ptr[10] = "hello";


Question: C#中大数据的存储怎么办？

算法参考小学二、三年级加法和乘法竖式。

仅供参考： #include <iostream> #include <string> #include <algorithm> using namespace std; int COMPARE(string number1, string number2) {     int i,j;      int length1 = number1.size();     int length2 = number2.size();      if(number1.size() == 0) number1 = "0";     if(number2.size() == 0) number2 = "0";      j = 0;     for(i = 0; i < length1; ++i) {         if(number1[i] == '0') ++j;         else break;     }     number1 = number1.substr(j);      j = 0;     for(i = 0; i < length2; ++i) {         if(number2[i] == '0') ++j;         else break;     }     number2 = number2.substr(j);      length1 = number1.size();     length2 = number2.size();      if(length1 > length2) {         return 1;     } else if(length1 == length2) {         if(number1.compare(number2) > 0) {             return 1;         } else if(number1.compare(number2) == 0) {             return 0;         } else {             return -1;         }     } else {         return -1;     }      return 0; } string PLUS(string number1,string number2) {     int i;     int length1 = number1.size();     int length2 = number2.size();      string result="";      reverse(number1.begin(), number1.end());     reverse(number2.begin(), number2.end());      for(i = 0; i < length1 && i < length2; i++) {         char c = (char)(number1[i] + number2[i] - 48);         result = result + c;     }      while(i < length1) {         result = result + number1[i];         ++i;     }      while(i < length2) {         result = result + number2[i];         ++i;     }      int carry = 0;     for(i = 0; i < (int)result.size(); ++i) {         int value = result[i] - 48 + carry;         result[i] = (char)(value % 10 + 48);         carry = value / 10;     }      if(carry !=0 ) {         result = result + (char)(carry + 48);     }      for(i = result.size() - 1; i >= 0; i--) {         if(result[i] != '0') break;     }      result = result.substr(0, i + 1);      reverse(result.begin(), result.end());     if(result.length() == 0) result = "0";     return result; } string MINUS(string number1,string number2) {     int i;     string result = "";      int length1 = number1.size();     int length2 = number2.size();      if(COMPARE(number2,number1) > 0) {         return "-" + MINUS(number2, number1);     }      reverse(number1.begin(),number1.end());     reverse(number2.begin(),number2.end());      for(i = 0; i < length1 && i < length2; i++) {         char c = number1[i] - number2[i] + 48;         result = result + c;     }      if(i < length1) {         for(; i < length1; i++) {             result = result + number1[i];         }     }      int carry = 0;     for(i = 0; i < (int)result.length(); i++) {         int value = result[i] - 48 + carry;         if(value < 0) {             value = value + 10;             carry = -1;         } else carry = 0;         result[i]=(char)(value + 48);     }      for(i = result.size() - 1; i >= 0; i--) {         if(result[i] != '0')break;     }      result = result.substr(0, i+1);      reverse(result.begin(), result.end());     if(result.length()==0) result = "0";     return result; } string MULTIPLY(string number1, string number2) {     int i, j;     int *iresult;     int length1 = number1.size();     int length2 = number2.size();     string result = "";      reverse(number1.begin(), number1.end());     reverse(number2.begin(), number2.end());      iresult = (int*)malloc(sizeof(int) * (length1 + length2 + 1));     memset(iresult, 0, sizeof(int) * (length1 + length2 + 1));      for(i = 0; i < length1; i++) {         for(j = 0; j < length2; j++) {             iresult[i+j] += ((number1[i] - 48) * (number2[j] - 48));         }     }      int carry = 0;     for(i = 0; i < length1 + length2; i++) {         int value = iresult[i] + carry;         iresult[i] = value % 10;         carry = value / 10;     }      for(i = length1 + length2 - 1; i >= 0; i--) {         if(iresult[i] != 0)break;     }      for(; i >= 0; i--) {         result = result + (char)(iresult[i]+48);     }      free(iresult);      if(result == "") result = "0";     return result; } string factorial(string n) {     string temp = "1";     string i;     for(i = "1"; COMPARE(i, n) <= 0; i = PLUS(i, "1")) {         temp = MULTIPLY(temp, i);     }     return temp; } int main(void) {     cout << factorial("100") << endl;     return 0; }


Question: 请教大神，interrupt affinity怎么用？

引用 12 楼 zhao4zhong1 的回复:请亲自动手打开procmon.chm查看。  啊，好的，谢谢！

请亲自动手打开procmon.chm查看。

引用 3 楼 zhao4zhong1 的回复:那建议用软件 procmon filemon regmon 监视你那个小工具在运行时都干了些啥。  请问用procmon要怎么看到某应用程序都做了什么操作呢？刚刚下到该程序，但还不会用……

引用 8 楼 user-2 的回复:为什么要改这个？ 改乱了 会很麻烦的 请问这个改后复原不行么？

引用 8 楼 user-2 的回复:为什么要改这个？ 改乱了 会很麻烦的  需要屏蔽某些核的中断来完成实时性较高的处理。 我也发现改过后再恢复QQ和另一个软件就不能用了…………

为什么要改这个？ 改乱了 会很麻烦的

引用 6 楼 user-2 的回复:这个工具修改的是注册表 http://msdn.microsoft.com/zh-cn/subscriptions/ff547969.aspx  从MSND弄明白 有关的注册表项 然后用注册表WIN32 API自己去修改。  好的，谢谢~~~！

API 文件 注册表

引用 3 楼 zhao4zhong1 的回复:那建议用软件 procmon filemon regmon 监视你那个小工具在运行时都干了些啥。  这个能监视到什么？？

引用 1 楼 zhao4zhong1 的回复:SetProcessAffinityMask SetThreadAffinityMask ？ 呃，不是这个


Question: 百度面试题

我能够弱弱的问一下： 能够for循环使用stl的count函数实现吗？

//有一个很大的整型数组int a[n],里面的每一个数字可能有奇数个，也可能有偶数个，要求找出其中有奇数个的数字。 #include<stdio.h> #include <stdlib.h> #define SIZE 2000 static int data[SIZE]; struct st_num{ 	int num; 	int count; 	bool zero; }arry[SIZE];  static void build_data(){ 		printf("%s","数据样本："); 		printf("\n"); 	for(int a=0;a<SIZE;a++){ 		data[a]=rand()%200;		 		printf("%d%c",data[a],','); 	} }  int main(){ 	build_data(); 	int oflag=0; 	for(int a=0;a<SIZE;a++){ 		int flag=0; 		for(int b=0;b<SIZE;b++){             if(arry[b].zero&&data[a]==0||(data[a]!=0&&data[a]==arry[b].num)){				 				arry[b].count++; 			}else{ 				flag++; 			}		 			if(flag==SIZE){ 				arry[oflag].num=data[a]; 				arry[oflag].count=1; 				if(data[a]==0){ 					arry[oflag].num=0; 					arry[oflag].zero=true; 				} 				oflag++; 			} 		} 	} 	printf("\n"); 	printf("%s","分析结果："); 	printf("\n");  	for(int a=0;a<SIZE;a++){ 		if(arry[a].count%2==1){ 			printf("%d%s%d",arry[a].num,"出现的次数是：",arry[a].count); 			printf("\n"); 		} 	} 	return 0;

建立一个单向顺序链表，然后遍历数组，某个数字在链表里没有出现过就按大小顺序插入，已经有了则删除，遍历结束，这个链表里留下的节点的数据域里就是出现过奇数次的数啦

#include<stdio.h> #include <stdlib.h>  #define SIZE 100 static int data[SIZE]; struct st_num{ 	int num; 	int count; 	bool zero; }arry[SIZE]; static void build_data(){ 		printf("%s","数据样本："); 		printf("\n"); 	for(int a=0;a<SIZE;a++){ 		data[a]=rand()%10;		 		printf("%d%c",data[a],','); 	} }  int main(){ 	//有一个很大的整型数组int a[n],里面的每一个数字可能有奇数个，也可能有偶数个，要求找出其中有奇数个的数字。 	build_data(); 	int oflag=0; 	for(int a=0;a<SIZE;a++){ 		int flag=0; 		for(int b=0;b<SIZE;b++){             if(data[a]==0&&arry[b].zero||(data[a]!=0&&data[a]==arry[b].num)){				 				arry[b].count++; 			}else{ 				flag++; 			}		 			if(flag==SIZE){ 				arry[oflag].num=data[a]; 				arry[oflag].count=1; 				if(data[a]==0){ 					arry[oflag].num=0; 					arry[oflag].zero=true; 				} 				oflag++; 			} 		} 	} 	printf("\n"); 	printf("%s","分析结果："); 	printf("\n");  	for(int a=0;a<SIZE;a++){ 		if(arry[a].count%2==1){ 			printf("%d%s%d",arry[a].num,"出现的次数是：",arry[a].count); 			printf("\n"); 		} 	} 	return 0; }

如果是int，用32位的数组，记录每个数字在该位为1的个数，最后选出位置值为奇数的位置，将其余位置置0，十进制后就是要的数字。 不过前提是这个数组里只有一个数字是出现奇数次，其他数字都是出现偶数次

用循环遍历的方法就OK了啊，a【i】%2！=0的时候就输出，就是所有的奇数了

哈哈 可以用字典树实现，内存需求没多少，且看我的代码http://bbs.csdn.net/topics/390602795

引用 13 楼 qq120848369 的回复:全异或啊，老题目啊。记得只有一个奇数的时候可以用这个方法，貌似楼主的意思是奇数个的数也有多个，那异或之后貌似也不好处理啊。

引用 13 楼 qq120848369 的回复:全异或啊，老题目啊。 具有奇数个数的数字只有一个，全异或就可以得到。

全异或啊，老题目啊。

引用 11 楼 aa122333 的回复:不过需要512M内存 照你的作法估计大家都不要用百度搜索了....

无语了，不能编辑，总的修改为以下：  （1）因为int的个数为为2^32，我们可以考虑直接用连续内存的一位来记录对应的一个数出现是偶次数还是奇次数 （2）总共需要的内存是2^32/8 字节 = 2^29 字节 = 2^19 k = 2^9 m = 512 m （3）如果一个数出现一次（奇数次），把该位置1，出现第二次（偶次数），把该位置0 （4）最后再把置上1的位对应的整数输出即可  不过需要512M内存

火线刘明

我汉语太差了，看不懂中文了都。

int型最大为2^31 - 1，粗心了

最后一句修改：需要256M内存

（1）因为是int型，所以最大为2^31，我们可以考虑直接用连续内存的一位来记录对应的一个数出现是偶次数还是奇次数 （2）总共需要的内存是2^31/8 字节 = 2^28 字节 = 2^18 k = 2^8 m = 256 m （3）如果一个数出现一次（奇数次），把该位置1，出现第二次（偶次数），把该位置0 （4）最后再把置上1的位对应的整数输出即可  不过需要255M内存

很高端的样子  引用 4 楼 zhao4zhong1 的回复:仅供参考//随机产生100000000个取值范围为[0～2的32次方减1]的数据， //然后让用户输入一个数据，判断用户输入的数据是不是包含在前面随机产生的数据中。 //要求：当用户输入完成后，必须在1毫秒(千分之一秒)之内完成判断。 #include <stdio.h> #include <stdlib.h> #include <time.h> #include <malloc.h> long int i; unsigned long ul; unsigned long *d; unsigned long ulrand(void) {     return (      (((unsigned long)rand()<<24)&0xFF000000ul)     |(((unsigned long)rand()<<12)&0x00FFF000ul)     |(((unsigned long)rand()    )&0x00000FFFul)); } void main() {     d=(unsigned long *)calloc(1<<(32-5),sizeof(unsigned long));     if (NULL==d) {         printf("Can not calloc(%d,%d)!\n",1<<(32-5),sizeof(unsigned long));         return;     }     srand(time(NULL));     for (i=0;i<100000000;i++) {         while (1) {             ul=ulrand();             if (0==(d[ul>>5]&(1lu<<(ul%32)))) {                 d[ul>>5]|=1<<(ul%32);                 break;             }         }         if (0==i%1000000) printf("%09d,%10lu\n",i,ul);     }     while (1) {         printf("\nInput a number:");         fflush(stdout);         rewind(stdin);         if (1==scanf("%lu",&ul)) break;     }     if (d[ul>>5]&(1<<(ul%32))) printf("Include.\n"    );     else                       printf("Not include.\n");     free(d); } //000000000,2135468533 //001000000,2465805973 //002000000,3844079964 //003000000,1883232874 //004000000,1204697784 //005000000,4050838287 //006000000,3802081245 //007000000,1586042671 //008000000,3119931368 //009000000, 251096899 //010000000,3491239701 //011000000,3365323844 //012000000,2191846708 //013000000,1879478195 //014000000,1112631457 //015000000,1927301519 //016000000,1717332861 //017000000,2922278240 //018000000, 694854106 //019000000, 273255526 //020000000, 398518467 //021000000,3270756812 //022000000,1500289424 //023000000,1502241936 //024000000,1770380660 //025000000,3668842116 //026000000,3255869879 //027000000,1299184024 //028000000,1072990028 //029000000, 242094712 //030000000,3789344297 //031000000,2599365925 //032000000, 962754138 //033000000,2055075654 //034000000,4083452879 //035000000, 489250842 //036000000, 611455230 //037000000, 277350616 //038000000,1597410795 //039000000,3224173662 //040000000,2291446877 //041000000,2546280575 //042000000,2509145642 //043000000,2371773252 //044000000, 635555963 //045000000,2674538666 //046000000,4253690312 //047000000,2675755514 //048000000,1269320296 //049000000,3172516920 //050000000,1430265210 //051000000, 196156173 //052000000,2470825669 //053000000,2536750977 //054000000,1182829949 //055000000,3202826434 //056000000,2263336265 //057000000, 313302924 //058000000,3630264578 //059000000,1154892716 //060000000,2985304230 //061000000,1252204837 //062000000,1292076720 //063000000, 242249250 //064000000,3999999961 //065000000, 431166416 //066000000,1366947236 //067000000,1414387330 //068000000,2143784481 //069000000,3242175409 //070000000,4158065163 //071000000,1425449573 //072000000,2493600232 //073000000,1316783455 //074000000,3723170478 //075000000,3064111466 //076000000, 408557403 //077000000,3722586955 //078000000,3801652651 //079000000,3788160154 //080000000,3329440047 //081000000,1408976868 //082000000, 471838899 //083000000,2145198260 //084000000,3781081738 //085000000,3439027738 //086000000,1150808750 //087000000,2782578638 //088000000,  85604584 //089000000,2704078162 //090000000, 584840269 //091000000,3854577719 //092000000,2823653537 //093000000, 797877025 //094000000,2248017755 //095000000,1787038685 //096000000,2816548567 //097000000, 489107494 //098000000, 911680090 //099000000,3677777147 // //Input a number:3677777147 //Include.


Question: 一个奇怪的socket 端口冲突问题

自己顶一个。。。

在SO_REUSEPORT尚未普及的情况下, 内核中的每个port只应属于一个process，但是有两个特例：  1，bind后fork的。 2，listen后accept的。  楼主问题1：既然随机端口被占用着，你bind肯定是失败的，除非有REUSERPORT选项。 楼主问题2：你是说系统会给你分配到一个已经bind的端口？不太可能。

多谢版主出马，SO_REUSEPORT目前并不支持； 问题依旧： 1、随机端口被占用，比如说51365，那么在51365上的监听就起不来么？(这个是我碰到的问题的根源) 那这么说所有的监听端口是不是都要在随机端口的范围下面才合适？ netstat -an |grep 44445 tcp        0      0 172.18.64.64:51365      172.17.236.122:44445    ESTABLISHED   44445是我主机的一个监听，实验主机用的客户端程序连接到44445，产生随机端口51365 然后悲剧发生了：实验主机上的服务端程序绑定51365失败了。。。 socket ok! setsockopt ok! bind()sockfd[3]fail, errno[98], errmsg[Address already in use] 主要是这个怎么解释？？？  2、我在实验主机的客户端connect之前SO_REUSEADDR，问题就解决了，相当于clt和svr都设置了SO_REUSEADDR才可以。。。 当然，作为服务端程序，第一次碰到跟别人的随机端口冲突，也不能指望别人调用之前SO_REUSEADDR，更不能寄希望系统不会分配到跟我们监听端口一样的随机端口； 这个该怎么解释？？  这个问题最终是可以解决的，就是listen在随机端口范围以下的端口就ok了； 但是1和2是为什么？？？？

再说一下实验过程吧： SUSE Linux ： 1、客户端socket  connect 172.17.233.122：44445 2、连接成功 tcp  0  0 172.18.64.64:54050  172.17.236.122:44445    ESTABLISHED  3、服务端socket  setsockopt(SO_REUSEADDR) bind(172.18.64.64:54050)  listen accept 4、启动服务端，bind失败，errno98   1、客户端socket  setsockopt(SO_REUSEADDR) connect 172.17.233.122：44445 2、连接成功 tcp  0  0 172.18.64.64:54052  172.17.236.122:44445    ESTABLISHED  3、服务端socket  setsockopt(SO_REUSEADDR) bind(172.18.64.64:54052)  listen accept 4、启动服务端，bind成功  IBM AIX: 上述两种情况都bind成功，只要svr设置了setsockopt(SO_REUSEADDR)； 上述两种情况都bind失败，只要svr没有设置setsockopt(SO_REUSEADDR)；

版主说要用REUSERPORT选项来实现，但是我的这个例子中用SO_REUSEADDR已经可以解决这个冲突问题了，但是苦于在UNP上SO_REUSEADDR的四条用法中找不到对应的解释： SO_REUSEADDR可以用在以下四种情况下：      (摘自《Unix网络编程》卷一，即UNPv1)      1、当有一个有相同本地地址和端口的socket1处于TIME_WAIT状态时，而你启 动的程序的socket2要占用该地址和端口，你的程序就要用到该选项。      2、SO_REUSEADDR允许同一port上启动同一服务器的多个实例(多个进程)。但 每个实例绑定的IP地址是不能相同的。在有多块网卡或用IP Alias技术的机器可 以测试这种情况。      3、SO_REUSEADDR允许单个进程绑定相同的端口到多个socket上，但每个soc ket绑定的ip地址不同。这和2很相似，区别请看UNPv1。      4、SO_REUSEADDR允许完全相同的地址和端口的重复绑定。但这只用于UDP的 多播，不用于TCP。  我所纠结的问题在这儿： 1、既然存在这种跟随机端口冲突的问题，那我的监听端口该设定为多少才能保证不会跟随机端口冲突，就是svr监听端口的取值范围问题 2、从上述实验中只有clt和svr都设置了SO_REUSEADDR，绑定在该端口上的bind操作才会成功，只要一个没有设置就errno98，如何解释，必须要clt也设置SO_REUSEADDR； 3、实际上我在AIX上也做过实验，AIX只需要svr设置了SO_REUSEADDR就可以bind在一个已经分配了的随机端口上，还是想知道如何解释这个实现机制。

引用 1 楼 user-1 的回复:SO_REUSERPORT是可以多进程bind同一个Port的，但只有linux3.x内核才刚刚支持这个选项，之前此选项是不起作用的。  SO_REUSERADDR是复用TIME_WAIT的，没问题。  多提一句吧，windows的socket早就支持SO_REUSERPORT这个功能了，很多木马会扫除比如QQ正在使用的通讯端口，然后也bind到这个端口上，从而避免杀软发现自己。  你只要知道TCP是4元组，那么肯定知道在本地bind 无数次同一个Port是毫无问题的，只是linux内核一直把SO_REUSERPORT这个选项别扭着没实现。


Question: 如果给出节点的顺序打乱，用孩子兄弟法如何建立树？

似乎应该这么做： if(j==0)         Array[parentid].FirstChild=&Array[childid];             else               Array[lastid].NextSibling=&Array[childid];  不过数组存储树，一般都是用索引，而不用指针。 一般指针用于链式存储。 另外你这个树，好奇怪，居然没有数据。  任何数据结构，只在数据存储方式，和一些基本算法上有用。  我们使用数据结构，是为了用这种结构存储数据，和使用这种算法，而不是为数据结构，而开个数据结构。  数据是核心，数据结构和相应的算法，是为了数据服务的。  你这个树的数据是什么。难道不用存储数据？？？？？  还是你只关系，数据结构，不关心数据？？？

引用 5 楼 lm_whales 的回复:你这说的太简单，信息太少。 首先，你这是那种数据结构，其他节点如何除了（没给出孩子节点的节点）  马马虎虎，可以看出，这似乎是一棵树。  你可以先创建一片森林，然后查找，每棵树的根节点在主树的位置，插入主树对应的节点上。即可。  也可一先创建主树。 然后再插入节点数据。   具体看你的树本身，是个什么树。 擦，怎么缩进没有了，再弄一遍 typedef struct Tree *PtrToTree; struct Tree {   PtrToTree FirstChild;   PtrToTree NextSibling; }; PtrToTree *Array;  int main(void) {   int i,j;   int childid,parentid,lastid;   int childnum;   scanf("%d %d",&n,&m);   while(n)   {     Array=(PtrToTree *)malloc(sizeof(PtrToTree)*(n+1));     maxlevel=0;     for(i=0;i<m;i++)   {       scanf("%d %d",&parentid,&childnum);       if(!childnum)         Array[parentid]->FirstChild=NULL;       else      {          for(j=0;j<childnum;j++)          {             scanf("%d",&childid);             if(j==0)                Array[parentid]->FirstChild=Array[childid];             else                Array[lastid]->NextSibling=Array[childid];             lastid=childid;           }        Array[childid]->NextSibling=NULL;     }   }   } return 0; }

引用 5 楼 lm_whales 的回复:你这说的太简单，信息太少。 首先，你这是那种数据结构，其他节点如何除了（没给出孩子节点的节点）  马马虎虎，可以看出，这似乎是一棵树。  你可以先创建一片森林，然后查找，每棵树的根节点在主树的位置，插入主树对应的节点上。即可。  也可一先创建主树。 然后再插入节点数据。   具体看你的树本身，是个什么树。 唔，我才刚学树，树林是什么还不知道。。 我刚刚写了这个程序，定义一个指向结构的指针数组 typedef struct Tree *PtrToTree; struct Tree { 	PtrToTree FirstChild; 	PtrToTree NextSibling; }; PtrToTree *Array;  int main(void) { 	int i,j; 	int childid,parentid,lastid; 	int childnum; 	scanf("%d %d",&n,&m); 	while(n) 	{ 		Array=(PtrToTree *)malloc(sizeof(PtrToTree)*(n+1)); 		maxlevel=0; 		for(i=0;i<m;i++) 		{ 			scanf("%d %d",&parentid,&childnum); 			if(!childnum) 				Array[parentid]->FirstChild=NULL; 			else 			{ 				for(j=0;j<childnum;j++) 				{ 					scanf("%d",&childid); 					if(j==0) 						Array[parentid]->FirstChild=Array[childid]; 					else 						Array[lastid]->NextSibling=Array[childid]; 					lastid=childid; 				} 				Array[childid]->NextSibling=NULL; 			} 		}  调试的时候在“Array[parentid]->FirstChild=Array[childid];”这里出现了问题，难道这不可以吗？

难道木有人知道吗

来人啊，求帮助

数据结构问题在CSDN上好像很少受关注啊 顶一下


Question: 函数的宏替换问题，出现了未定义错误

楼主要搞莫子啊  #define 会替换   楼主是想要定义函数指针类型吧

引用 8 楼 modyaj 的回复: //楼主既然知道宏是简单文字替换 那么楼主认为下面这代码是做什么呢？ fun_cb = do { \     printf("fuck!\n"); \ } while(0)   嗯，对，我前面的 fun_cb = fun1；和上面这个一样，当然编译不过了，所以，要想一边用宏来替换函数，一边又能通过编译，因此还要如大神.xiaohuh421所说的‘宏能最终指向一个函数名.’谢谢你们的指导，受益匪浅啊，谢谢你们 user-4 xiaohuh421 modyaj

引用 5 楼 yangyi_33855 的回复:[quote=引用 3 楼 xiaohuh421 的回复:] 楼主看来完全没有理解宏函数的意思哟. 宏就是做代码替换工作的.  楼主想实现什么功能呢?  函数指针, 仿函数都是很好用的东西呀. 谢谢您的回答。仔细想想自己为什么提这个问题，也是，我都还没弄清楚  宏是否能代替函数定义 来通过编译(表达的好乱)，就来问了。我想了解的场景是这样的：假设 在编译某段程序中，出现了，“****”undeclared的错误，然后，我是否能通过 宏替换掉这个“****”, 来使得编译通过，而至于“****”这段代码，处理过什么数据，返回了什么值，我暂时不关心它，只是说先通过编译。[/quote]  这要看函数是怎么调用的, 如果说是函数指针的赋值, 那么告诉你, 宏是办不到的. SS_FP_APPMNG_CB fun_cb; fun_cb = func1; //这里不能用宏函数代替, 只能用实际的函数名.或者宏能最终指向一个函数名. 但如果是只调用函数.  func1(xxx,xxx); 这里就以用函数宏代替掉.  你只要理解到, 宏, 只是作代码替换.  比如还是你定义的宏: int main() {     int ret=0, ret_len=0;     func1(ret,ret_len); }  编译时替换成: int main() {     int ret=0, ret_len=0;     do{          printf("fuck!\n");     }while(0) }

引用 4 楼 user-4 的回复:[quote=引用 2 楼 yangyi_33855 的回复:] 谢谢您的回答，对于某个，我只知道是另外一个.c文件里面的，函数名为‘func1’, 形参类型、返回值类型，都不知道，也不关心，这样的话，我要调用‘func1’，还要在这里重新定义一遍么?确实，main()后面写个 void func1(void *ret, uint32_t ret_len) { 	printf("fuck!\n"); 	return; }能编译通过，但是要打桩，做桩函数的话，该怎么定义宏呢？就不能通过函数宏来替换了吗? 1 如果你要使用其他文件中的函数，就要在本文件使用该函数之前声明该函数 2 函数的名称和参数类型和返回值类型共同确定一个函数，差一个都不行 3 宏是简单的文本替换，只要你知道替换具体是怎么执行的，想怎么替换就怎么替换，但如果你只是因为“函数宏中有函数两个字”就认为“它可以用来替换两个函数”，那很抱歉我无能为力[/quote] 谢谢您的回答，我先去了解 宏替换具体是怎么执行的吧，

引用 3 楼 xiaohuh421 的回复:楼主看来完全没有理解宏函数的意思哟. 宏就是做代码替换工作的.  楼主想实现什么功能呢?  函数指针, 仿函数都是很好用的东西呀. 谢谢您的回答。仔细想想自己为什么提这个问题，也是，我都还没弄清楚  宏是否能代替函数定义 来通过编译(表达的好乱)，就来问了。我想了解的场景是这样的：假设 在编译某段程序中，出现了，“****”undeclared的错误，然后，我是否能通过 宏替换掉这个“****”, 来使得编译通过，而至于“****”这段代码，处理过什么数据，返回了什么值，我暂时不关心它，只是说先通过编译。

引用 2 楼 yangyi_33855 的回复:谢谢您的回答，对于某个，我只知道是另外一个.c文件里面的，函数名为‘func1’, 形参类型、返回值类型，都不知道，也不关心，这样的话，我要调用‘func1’，还要在这里重新定义一遍么?确实，main()后面写个 void func1(void *ret, uint32_t ret_len) { 	printf("fuck!\n"); 	return; }能编译通过，但是要打桩，做桩函数的话，该怎么定义宏呢？就不能通过函数宏来替换了吗? 1 如果你要使用其他文件中的函数，就要在本文件使用该函数之前声明该函数 2 函数的名称和参数类型和返回值类型共同确定一个函数，差一个都不行 3 宏是简单的文本替换，只要你知道替换具体是怎么执行的，想怎么替换就怎么替换，但如果你只是因为“函数宏中有函数两个字”就认为“它可以用来替换两个函数”，那很抱歉我无能为力

引用 1 楼 user-4 的回复:typedef void (*SS_FP_APPMNG_CB)(void *, uint32_t); 这一句声明了一个新的函数指针类型SS_FP_APPMNG_CB SS_FP_APPMNG_CB fun_cb; 这一句定义了一个函数指针fun_cb fun_cb = func1; 函数指针指向了一个不认识的东西  为什么呢，看看func1是什么 #define func1(ret, ret_len) do { \     printf("fuck!\n"); \ } while(0) 嗯，func1是一个宏，宏和函数是完全不同的两码事，结束 谢谢您的回答，对于某个，我只知道是另外一个.c文件里面的，函数名为‘func1’, 形参类型、返回值类型，都不知道，也不关心，这样的话，我要调用‘func1’，还要在这里重新定义一遍么?确实，main()后面写个 void func1(void *ret, uint32_t ret_len) { 	printf("fuck!\n"); 	return; }能编译通过，但是要打桩，做桩函数的话，该怎么定义宏呢？就不能通过函数宏来替换了吗?


Question: 我一直很想问一个问题，关于想编写游戏的话有什么书推荐

我找到一个开源的曹操传的项目，希望对和我一样有同样兴趣的朋友有用 http://code.google.com/p/caocaozhuan/source/checkout

引用 5 楼 zhao4zhong1 的回复:搜开源策略游戏 谢谢，举一反三，我搜索开源战棋游戏看看嘿嘿

引用 4 楼 uniquecapo 的回复:http://blog.csdn.net/zhmxy555/article/category/1104646/3 【 Visual C++】游戏开发笔记，希望对你有帮助。  谢谢

《Visual C++ 游戏开发经典案例详解》 搜网络教程“学OpenGL编3D游戏”。

搜开源策略游戏

引用 2 楼 N_sev7 的回复:个人觉得： 还是先研究算法吧，比如3D场景显示的时候你用什么算法能高效的显示出来 至于那些画面什么的3D场景的模型，看OpenGL3D编程呗  不要3D我就想自己能编一个像曹操传一样的战棋游戏这行了这是2D吧 主要是觉得看C++方面的书我一个人又没有经验也不会项目，可能还是需要例子来引导更好 一步步上手也更容易，有目标一些 只看你所说的还是不能写出游戏来


Question: 有关约瑟夫环的我自己写的一个程序 调试了N遍都不对 求大神帮个忙看下 感激不尽

//假设有n个人团团围做，从第1个人开始数数，数到第m个人时候，第m个人出列， //然后继续从1开始数数，数到第m个人退出 #include <stdio.h> #include <conio.h> int i,k,t; int n,m; static char f[1001];//0该座位未出圈,1该座位已出圈 void main() {     while (1) {         printf("Input n m(1000>=n>=m>=1):");         fflush(stdout);         rewind(stdin);         if (2==scanf("%d%d",&n,&m)) {             if (1000>=n && n>=m && m>=1) break;         }     }     t=0;//已出圈总人数     i=1;//座位编号     k=1;//当前要数的数     while (1) {         if (0==f[i]) {             if (m==k) {                 t++;                 f[i]=1;                 printf("%3d ",i);                 if (0==t%10) printf("\n");                 if (t>=n) break;             }             k++;if (k>m) k=1;         }         i++;if (i>n) i=1;     }     cprintf("Press any key ...");     getch(); }

LZ程序如下加一行即可:    for(i=0;i<number;i++)   {     pb=NULL;//加  这样就不会把2组数据链成一个环了.


Question: WlanHostedNetworkStartUsing调用成功，但承载网络却未启动，为什么？

找到了问题所在，代码第30行的WlanCloseHandle(WlanHandle, NULL);要去掉，关闭了句柄wifi也会关闭，还有程序退出之后wifi也会自动关闭

WlanHostedNetworkForceStart()可以启动，但前提是需要管理员权限运行


Question: 'NULL':未定义的标识符

引用 20 楼 my_live_123 的回复:完全可以自己定义一个  #define NULL (void*)(0)  #ifndef NULL #ifdef __cplusplus #define NULL    0 #else  /* __cplusplus */ #define NULL    ((void *)0) #endif  /* __cplusplus */ #endif  /* NULL */

缺少头文件#include<stdlib.h>

完全可以自己定义一个  #define NULL (void*)(0)

加 #include<cstdio>或<stdio.h>  亲测可行

#define NULL 0 不太放心的话就使用 nullptr

引用 5 楼 hai200501019 的回复:if(curr==NUll||curr->rightChild==NULL)return NULL; 楼主注意拼写啊  curr==NULL  而不是curr==NUll   ，看好了 还有 if(curr==NULL||curr->leftChild=NULL)  return NULL; 应该是 curr->leftChild == NULL +++

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

using namespace std  NULL在std里

实在不行  自己定义呀

自己定义吧#define    NULL (void*)0

这么简单的问题，未定义定义一个就好了呀 在你程序文件前面，头文件后面加上几行： #ifndef NULL #define NULL ((void *)0) #endif

curr==NUll||curr->rightChild==NULL 好像这句错了吧，注意拼写NULL

实在不行，直接#define NULL 0，效果是一样的，如果还有错就是其他问题了。 你的实现文件是分开写的？确定每个文件都加了stdio.h吗？再仔细看一下。

引用 6 楼 yangyi_33855 的回复:头文件包含错了吧，是#include <stdio.h>什么的 “”表示在当前文件夹啊 这个是没问题的，""会先查找当前文件夹再查找库，<>是直接搜索库，如果反过来用<>查找当前文件夹就错了，不过如果当前文件夹有很多文件的话也不建议用""来代替<>

cstddef cstdio cstring ctime

运行时就出错？？？  编译连接都没问题吗

这是所有的代码，可是运行时就出错

#include "stdafx.h" #include  "stdlib.h" #include  "stdio.h" #include  "stddef.h" //#include "windows.h" typedef  char DataType; //#define NULL (Node *)0 #include  "bitreenode.h"  int _tmain(int argc, _TCHAR* argv[]) { 	BiTreeNode *root,*p;  	Initiate(&root); 	p=InsertLeftNode(root,'A'); 	p=InsertLeftNode(p,'B'); 	p=InsertLeftNode(p,'D'); 	p=InsertLeftNode(p,'G'); 	p=InsertRightNode(root->leftChild,'C'); 	InsertLeftNode(p,'E'); 	InsertRightNode(p,'F'); 	return 0; }


Question: 怎么用C语言编写以下代码

强烈鄙视6楼，人家小孩子刚开始学编程，得锻炼自学能力，你给人家实现了就显得你很了得？？ 授之以鱼不如授之以渔，懂？？

不一定对，仅供参考： int Encode(     const char * pcSendText,     char * pcPacketBuff) {     int i,j;     char c;      i=0;     j=0;     pcPacketBuff[i]='S';     i++;     while (1) {         c=pcSendText[j];         j++;         if (0==c) break;         switch (c) {         case 'S':             pcPacketBuff[i]='C';             i++;             pcPacketBuff[i]='A';             i++;         break;         case 'E':             pcPacketBuff[i]='C';             i++;             pcPacketBuff[i]='B';             i++;         break;         case 'C':             pcPacketBuff[i]='C';             i++;             pcPacketBuff[i]='C';             i++;         break;         default:             pcPacketBuff[i]=c;             i++;         break;         }     }     pcPacketBuff[i]='E'; }   int Decode(     const char * pcPacket,     char * pcRecvText) {     int i,j;     char c1,c2;      i=0;     j=0;     while (1) {         c1=pcPacket[j];         if (0==c1) break;         c2=pcPacket[j+1];                if ('S'==c1) {             j++;         } else if ('C'==c1 && 'C'==c2) {             pcRecvText[i]='C';i++;             j+=2;         } else if ('C'==c1 && 'A'==c2) {             pcRecvText[i]='S';i++;             j+=2;         } else if ('C'==c1 && 'B'==c2) {             pcRecvText[i]='E';i++;             j+=2;         } else if ('E'==c1) {             break;         } else {             pcRecvText[i]=c1;i++;             j++;         }     } }

谢谢提供，我改修下就行了

主要是我不懂怎么实现转义和解析，求帮忙

感觉这两个接口是有问题的，但是也可以写

引用 2 楼 u012279204 的回复:但是都看不懂，没办法下手啊 那就看懂了再下手

但是都看不懂，没办法下手啊

作业题，自己好好做！有不懂的，或者代码有问题再来问问


Question: 关于malloc

引用 1 楼 spirit008 的回复:http://blogimg.chinaunix.net/blog/upfile2/080101160701.pdf 善用搜索引擎 thanks.

引用 2 楼 jerry_dqh 的回复:我估计是函数重载了吧，原生的malloc只有一个参数。这个某个网络编程特别重载的malloc函数点C后缀 那么 应该不是重载 C没重载  也许是 宏 吧

引用 楼主 cogbee 的回复:在in.c文件里面有这么一句： oia=(struct in_ifaddr *)malloc(sizeof *oia,M_IFADDR,M_WAITOK) 这个应该是分配空间吧。malloc后面3个参数是什么情况？请教大虾，谢谢！ 我估计是函数重载了吧，原生的malloc只有一个参数。这个某个网络编程特别重载的malloc函数


Question: 关于顺序表嵌套结构体 的问题

谢谢各位大大的帮忙 问题已经解决了 非常感谢大家的帮助

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

结构体的Stu指针在用下表去访问的时候，在此之前没有申请内存。

仅供参考//将c:\\tmp文件夹下的所有文件的内容全部放到用malloc分配的内存中 #include <stdio.h> #include <stdlib.h> #include <string.h> #include <io.h> struct FB {     char fn[256];     size_t fl;     char *b;     struct FB *next;     struct FB *prev; } *fh,*fb,*ft; char ln[256]; char fpn[256]; FILE *af; FILE *f; int L,n; int main() {     system("dir /b /a-d c:\\tmp\\*.* >c:\\allfn.txt");     af=fopen("c:\\allfn.txt","r");     if (NULL==af) {         printf("Can not open file c:\\allfn.txt!\n");         return 1;     }     fh=NULL;     fb=NULL;     n=0;     while (1) {         if (NULL==fgets(ln,256,af)) break;         L=strlen(ln);         if ('\n'==ln[L-1]) ln[L-1]=0;         printf("read %s\n",ln);         strcpy(fpn,"c:\\tmp\\");         strcat(fpn,ln);         ft=(struct FB *)malloc(sizeof(struct FB));         if (NULL==ft) {             printf("Can not malloc ft!\n");             fclose(af);             return 2;//之前的malloc在main退出后由操作系统自动free         }         printf("ft[%d]==%p\n",n,ft);         strcpy(ft->fn,fpn);         f=fopen(fpn,"rb");         if (NULL==f) {             printf("Can not open file %s!\n",fpn);             fclose(af);             return 3;//之前的malloc在main退出后由操作系统自动free         }         ft->fl=_filelength(fileno(f));         ft->b=malloc(ft->fl);         if (NULL==ft->b) {             printf("Can not malloc ft->b!\n");             fclose(f);             fclose(af);             return 4;//之前的malloc在main退出后由操作系统自动free         }         printf("ft[%d]->b==%p\n",n,ft->b);         if (ft->fl!=fread(ft->b,1,ft->fl,f)) {             printf("fread error!\n");             fclose(f);             fclose(af);             return 5;//之前的malloc在main退出后由操作系统自动free         }         fclose(f);         ft->next=NULL;          if (NULL==fh) {             ft->prev=NULL;             fh=ft;         } else {             fb->next=ft;             ft->prev=fb;         }         fb=ft;         n++;     }     fclose(af);     printf("-----list-----\n");     for (ft=fh;NULL!=ft;ft=ft->next) {         printf("%8d %s\n",ft->fl,ft->fn);         if (NULL!=ft) fb=ft;     }     printf("-----free-----\n");     n--;     if (NULL!=fh) {         for (ft=fb->prev;NULL!=ft;ft=ft->prev) {             if (NULL!=ft->next->b) {                 printf("ft[%d]->b==%p\n",n,ft->next->b);                 free(ft->next->b);             }             if (NULL!=ft->next) {                 printf("ft[%d]==%p\n",n,ft->next);                 free(ft->next);             }             n--;         }         if (NULL!=fh->b) {             printf("ft[0]->b==%p\n",fh->b);             free(fh->b);         }         printf("ft[0]==%p\n",fh);         free(fh);     }     return 0; } //C:\tmp\tmp\Debug>dir /a-d c:\tmp // 驱动器 C 中的卷是 C_HD5_1 // 卷的序列号是 1817-D526 // // c:\tmp 的目录 // //找不到文件 // //C:\tmp\tmp\Debug>tmp //找不到文件 //-----list----- //-----free----- // //C:\tmp\tmp\Debug>dir /a-d c:\tmp // 驱动器 C 中的卷是 C_HD5_1 // 卷的序列号是 1817-D526 // // c:\tmp 的目录 // //2011-06-30  18:04            44,840 my_c.rar //2011-06-30  17:18             1,036 err.frm //2011-06-30  14:32            14,243 出租.txt //2011-06-28  12:08            23,681 MSDN98书签.txt //             4 个文件         83,800 字节 //             0 个目录 17,041,870,848 可用字节 // //C:\tmp\tmp\Debug>tmp //read my_c.rar //ft[0]==00421800 //ft[0]->b==00520068 //read err.frm //ft[1]==00421670 //ft[1]->b==0052AFC0 //read 出租.txt //ft[2]==00421530 //ft[2]->b==00378F28 //read MSDN98书签.txt //ft[3]==004213F0 //ft[3]->b==0052B3F8 //-----list----- // 44840 c:\tmp\my_c.rar //  1036 c:\tmp\err.frm // 14243 c:\tmp\出租.txt // 23681 c:\tmp\MSDN98书签.txt //-----free----- //ft[3]->b==0052B3F8 //ft[3]==004213F0 //ft[2]->b==00378F28 //ft[2]==00421530 //ft[1]->b==0052AFC0 //ft[1]==00421670 //ft[0]->b==00520068 //ft[0]==00421800 // //C:\tmp\tmp\Debug>

引用 3 楼 Spiech 的回复:引用 2 楼 AnYidan 的回复:贴出错误信息就是在输入数据后就崩溃了 那就先仔细检查接收数据的代码

typedef struct{ Student* Stu; int length; }Seqlist;//定义Seq这个新的数据类型 Seqlist结构体成员Stu是一个指针类型， 这里的Stu没有分配内存空间的，所以给他取地址赋值出错的！  void creat(Seqlist &L) { int a; printf("请输入要创建的元素的个数:\t"); scanf("%d",&a); //这里加上给他动态的分配内存空间 L.Stu = (Student *)malloc(sizeof(Student) * a);  for(int i=0;i<a;i++) { printf("请输入第%d个学生学号:\t",i+1); //对于字符串，就不用取地址了,数组名就是首地址 scanf("%s",L.Stu[i].no); printf("请输入第%d个学生姓名:\t",i+1); scanf("%s",L.Stu[i].name); printf("请输入第%d个学生成绩:\t",i+1); scanf("%d",&L.Stu[i].price); L.length++; } }

引用 2 楼 AnYidan 的回复:贴出错误信息就是在输入数据后就崩溃了

贴出错误信息

typedef struct{ Student* Stu; int length; }Seqlist;//定义Seq这个新的数据类型 你这里Stu用指针的话 你在主函数中是怎么分配内存的啊？  直接用数组好了啊 干嘛用指针


Question: 关于select机制和套接字的问题

1楼上说得对，断掉后服务器是非堵塞且会收到一个长度为0的包，所以要处理接收为0的状态。 而且客户端断开是不会发sigpipe信号，只有服务器没有处理0长的包，继续发送数据给断了socket才有可能受到sigpipe信号。

select监听一个断裂的套接字时，通信断开，则客户端不会有数据过来，select却成了非阻塞状态，认为有数据，但是会读不出来。  if(FD_ISSET(lSockFd,&read_set) {      count = recv(lSockFd,buf,LEN,0);     if((count == 0)||(count == -1))     {        /* 这两种情况都可认为是链路关闭*/     } } 在select 时候，可以进行对端的连接检测，链路关闭则是断开。。。这样就可以进行判断，可以删除！


&& 前为假 后面就不执行  && 前为真 后面执行

不习惯这个写法，嘿嘿

逻辑运算你都不懂了?


Question: 如何用时间控制程序的运行

你好   谢谢你的解答  对我很有帮助  我还想问一下   怎么使用逻辑时间控制  而不使用机械时间？就是整个程序的时间计算使用逻辑时间

#pragma comment(lib,"user32") #include <stdio.h> #include <time.h> #include <sys/timeb.h> #include <windows.h> char datestr[16]; char timestr[16]; char mss[4]; void log(char *s) {     struct tm *now;     struct timeb tb;      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,s); } VOID CALLBACK myTimerProc1(   HWND hwnd, // handle of window for timer messages   UINT uMsg, // WM_TIMER message   UINT idEvent, // timer identifier   DWORD dwTime // current system time ) {  log("In myTimerProc1\n"); } VOID CALLBACK myTimerProc2(   HWND hwnd, // handle of window for timer messages   UINT uMsg, // WM_TIMER message   UINT idEvent, // timer identifier   DWORD dwTime // current system time ) {  log("In myTimerProc2\n"); } int main() {     int i;     MSG msg;      SetTimer(NULL,0,1000,myTimerProc1);     SetTimer(NULL,0,2000,myTimerProc2);     for (i=0;i<20;i++) {         Sleep(500);         log("In main\n");         if (GetMessage(&msg,NULL,0,0)) {             TranslateMessage(&msg);             DispatchMessage(&msg);         }      }     return 0; } //2012-07-26 17:29:06.375 In main //2012-07-26 17:29:06.875 In myTimerProc1 //2012-07-26 17:29:07.375 In main //2012-07-26 17:29:07.875 In myTimerProc2 //2012-07-26 17:29:08.375 In main //2012-07-26 17:29:08.375 In myTimerProc1 //2012-07-26 17:29:08.875 In main //2012-07-26 17:29:08.875 In myTimerProc1 //2012-07-26 17:29:09.375 In main //2012-07-26 17:29:09.890 In myTimerProc2 //2012-07-26 17:29:10.390 In main //2012-07-26 17:29:10.390 In myTimerProc1 //2012-07-26 17:29:10.890 In main //2012-07-26 17:29:10.890 In myTimerProc1 //2012-07-26 17:29:11.390 In main //2012-07-26 17:29:11.890 In myTimerProc2 //2012-07-26 17:29:12.390 In main //2012-07-26 17:29:12.390 In myTimerProc1 //2012-07-26 17:29:12.890 In main //2012-07-26 17:29:12.890 In myTimerProc1 //2012-07-26 17:29:13.390 In main //2012-07-26 17:29:13.890 In myTimerProc2 //2012-07-26 17:29:14.390 In main //2012-07-26 17:29:14.390 In myTimerProc1 //2012-07-26 17:29:14.890 In main //2012-07-26 17:29:14.890 In myTimerProc1 //2012-07-26 17:29:15.390 In main //2012-07-26 17:29:15.890 In myTimerProc2 //2012-07-26 17:29:16.390 In main //2012-07-26 17:29:16.390 In myTimerProc1 //2012-07-26 17:29:16.890 In main //2012-07-26 17:29:16.890 In myTimerProc1 //2012-07-26 17:29:17.390 In main //2012-07-26 17:29:17.890 In myTimerProc2 //2012-07-26 17:29:18.390 In main //2012-07-26 17:29:18.390 In myTimerProc1 //2012-07-26 17:29:18.890 In main //2012-07-26 17:29:18.890 In myTimerProc1 //2012-07-26 17:29:19.390 In main //2012-07-26 17:29:19.890 In myTimerProc2

定时器

开线程，循环 + sleep

signal函数吧

面向对象语言用定时器咯，过程的话用循环+sleep咯


Question: 汉字和分隔符在一起，如何解析

//iconv_linux下字符集编码转换轻松实现 (1) iconv_t iconv_open(const char *tocode, const char *fromcode); //此函数说明将要进行哪两种编码的转换,tocode是目标编码,fromcode是原编码,该函数返回一个转换句柄,供以下两个函数使用。 (2) size_t iconv(iconv_t cd,char **inbuf,size_t *inbytesleft,char **outbuf,size_t *outbytesleft); //此函数从inbuf中读取字符,转换后输出到outbuf中,inbytesleft用以记录还未转换的字符数,outbytesleft用以记录输出缓冲的剩余空间。 (3) int iconv_close(iconv_t cd); //此函数用于关闭转换句柄,释放资源。  //例子1: 用C语言实现的转换示例程序  /* f.c : 代码转换示例C程序 */ #include <iconv.h> #define OUTLEN 255 main() { char *in_utf8 = "姝ｅ?ㄥ??瑁?"; char *in_gb2312 = "正在安装"; char out[OUTLEN];  /*unicode码转为gb2312码*/ rc = u2g(in_utf8,strlen(in_utf8),out,OUTLEN); printf("unicode-->gb2312 out=%sn",out); //gb2312码转为unicode码  rc = g2u(in_gb2312,strlen(in_gb2312),out,OUTLEN); printf("gb2312-->unicode out=%sn",out); } /*代码转换:从一种编码转为另一种编码*/ int code_convert(char *from_charset,char *to_charset,char *inbuf,int inlen,char *outbuf,int outlen) { iconv_t cd; int rc; char **pin = &inbuf; char **pout = &outbuf;  cd = iconv_open(to_charset,from_charset); if (cd==0) return -1; memset(outbuf,0,outlen); if (iconv(cd,pin,&inlen,pout,&outlen)==-1) return -1; iconv_close(cd); return 0; } /*UNICODE码转为GB2312码*/ int u2g(char *inbuf,int inlen,char *outbuf,int outlen) { return code_convert("utf-8","gb2312",inbuf,inlen,outbuf,outlen); } /*GB2312码转为UNICODE码*/ int g2u(char *inbuf,size_t inlen,char *outbuf,size_t outlen) { return code_convert("gb2312","utf-8",inbuf,inlen,outbuf,outlen); }  //例子2: 用C++语言实现的转换示例程序  /* f.cpp : 代码转换示例C++程序 */ #include <iconv.h> #include <iostream>  #define OUTLEN 255  using namespace std;  // 代码转换操作类  class CodeConverter {  private: iconv_t cd; public:  // 构造 CodeConverter(const char *from_charset,const char *to_charset) { cd = iconv_open(to_charset,from_charset); }   // 析构 ~CodeConverter() { iconv_close(cd); }   // 转换输出 int convert(char *inbuf,int inlen,char *outbuf,int outlen) { char **pin = &inbuf; char **pout = &outbuf;  memset(outbuf,0,outlen); return iconv(cd,pin,(size_t *)&inlen,pout,(size_t *)&outlen); } };  int main(int argc, char **argv) { char *in_utf8 = "姝ｅ?ㄥ??瑁?"; char *in_gb2312 = "正在安装"; char out[OUTLEN];  // utf-8-->gb2312 CodeConverter cc = CodeConverter("utf-8","gb2312"); cc.convert(in_utf8,strlen(in_utf8),out,OUTLEN); cout << "utf-8-->gb2312 in=" << in_utf8 << ",out=" << out << endl;  // gb2312-->utf-8 CodeConverter cc2 = CodeConverter("gb2312","utf-8"); cc2.convert(in_gb2312,strlen(in_gb2312),out,OUTLEN); cout << "gb2312-->utf-8 in=" << in_gb2312 << ",out=" << out << endl; }    二、利用iconv命令进行编码转换  iconv命令用于转换指定文件的编码,默认输出到标准输出设备,亦可指定输出文件。  用法： iconv [选项...] [文件...]  有如下选项可用:  输入/输出格式规范： -f, --from-code=名称 原始文本编码 -t, --to-code=名称 输出编码  信息： -l, --list 列举所有已知的字符集  输出控制： -c 从输出中忽略无效的字符 -o, --output=FILE 输出文件 -s, --silent 关闭警告 --verbose 打印进度信息  -?, --help 给出该系统求助列表 --usage 给出简要的用法信息 -V, --version 打印程序版本号  例子: iconv -f utf-8 -t gb2312 aaa.txt >bbb.txt 这个命令读取aaa.txt文件，从utf-8编码转换为gb2312编码,其输出定向到bbb.txt文件。  小结: Linux为我们提供了强大的编码转换工具,给我们带来了方便。

引用 12 楼 lpcads 的回复:如果含有128及以上的字符，先转为unicode，再解析，这是我的想法。。。 有没有linux下用c转换GB18030到unicode 进行处理 ，最后又把unicode转为GB18030的实例呢

如果含有128及以上的字符，先转为unicode，再解析，这是我的想法。。。

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

不知道有多少前人掉在TCP Socket send(人多)send(病少)send(财富) recv(人多病)recv(少财富) 陷阱里面啊！ http://topic.csdn.net/u/20120210/09/51109ed0-07b9-41f2-b487-a51597f2ca01.html

字符集编码的自动识别jchardet：能查到不少Java的开源代码。 C的很少，你看看这个 http://lxr.mozilla.org/mozilla/source/intl/chardet/

引用 5 楼 davidyu720 的回复:[quote=引用 4 楼 angel518 的回复:] [quote=引用 2 楼 baichi4141 的回复:] 如果是ASCII编码，从前向后，每一个大于0x80的字节和后面的字节共同构成一个非英文字符 如果是UNICODE编码，每两个字节构成一个字符 如果是UTF-8等不定长编码，去查每种语言对应的数值范围 是linux环境，在.bash_profile里有一行LANG=zh_CN.GB18030，这是否表明是用的字符集就是GB18030 这种情况下怎么解析[/quote] LANG表明你的shell工作环境的字符集，比如输出显示的字符集。  但是这个字符集与你需要处理的文本文件的字符集不见得一样。程序可以设置一个参数，表明文件的字符集。如果你的文件来源确定，那么字符集也可以确定，那参数就用不上了。  还有一种比较高级的做法，是自动读取文件的一部分内容，推测其字符集。[/quote] 有代码吗，学习下

引用 4 楼 angel518 的回复:[quote=引用 2 楼 baichi4141 的回复:] 如果是ASCII编码，从前向后，每一个大于0x80的字节和后面的字节共同构成一个非英文字符 如果是UNICODE编码，每两个字节构成一个字符 如果是UTF-8等不定长编码，去查每种语言对应的数值范围 是linux环境，在.bash_profile里有一行LANG=zh_CN.GB18030，这是否表明是用的字符集就是GB18030 这种情况下怎么解析[/quote] LANG表明你的shell工作环境的字符集，比如输出显示的字符集。  但是这个字符集与你需要处理的文本文件的字符集不见得一样。程序可以设置一个参数，表明文件的字符集。如果你的文件来源确定，那么字符集也可以确定，那参数就用不上了。  还有一种比较高级的做法，是自动读取文件的一部分内容，推测其字符集。

引用 2 楼 baichi4141 的回复:如果是ASCII编码，从前向后，每一个大于0x80的字节和后面的字节共同构成一个非英文字符 如果是UNICODE编码，每两个字节构成一个字符 如果是UTF-8等不定长编码，去查每种语言对应的数值范围 是linux环境，在.bash_profile里有一行LANG=zh_CN.GB18030，这是否表明是用的字符集就是GB18030 这种情况下怎么解析

汉字乱码，一半是和 编号为128以后的图形字符混淆了，127以内的一般不会。

可以学一下C的转义字符的处理方式 1）printf 格式串 % 代表格式， %% 代表% 本身。 %%--->% 2）字符串反斜杠，\转义序列，\\反斜杠本身。 \\---->\ UNICODE 可以这么处理： 007C ===>| 007C7CXX===> 7CXX 7CXX 表示7C开头的任意汉字。  其实 UNICODE 本身是16 BITS ，可以直接识别。 只怕MBCS才是需要另外识别的。 不过MBCS 汉字每个字节高位为1，不会和7C混淆的。 不知哪里会有问题。

所以处理多字节编码时一定要小心

解析前就应该知道文本的编码格式。


Question: linux下面的信号的问题？？？

引用 2 楼 user-3 的回复:man 7 signal 里面有解释   Real-time Signals        Linux  supports real-time signals as originally defined in the POSIX.1b        real-time extensions (and now included in  POSIX.1-2001).   Linux  sup-        ports  32  real-time signals, numbered from 32 (SIGRTMIN) to 63 (SIGRT-        MAX).  (Programs should always refer to real-time signals  using  nota-        tion  SIGRTMIN+n,  since  the  range of real-time signal numbers varies        across Unices.)         Unlike standard signals, real-time signals have no predefined meanings:        the entire set of real-time signals can be used for application-defined        purposes.  (Note, however, that the  LinuxThreads  implementation  uses        the first three real-time signals.)  ++

你列出来的都是不可靠信号，后面的都是可靠信号，也是后来扩充的！ 那里都是有介绍的！ 答案楼上。

这些信号中34以前的  在网上都能找到确切的意思  但是34以后的就找不到了 请问谁有34以后的每一个信号的  功能的解释  能否告诉我  谢谢各位！！！


Question: 关于vector new delete的问题

#include <iostream> #include <vector> using namespace std;  typedef struct //定义结构体AA {     int a; } AA;  int main() {     vector<AA> tempa(2); //定义AA类型的向量      vector<AA>  *p1=new vector<AA>(4);//定义AA类型的指针     vector<AA>  *p2=new vector<AA>(4);//定义AA类型的指针      p1=&tempa;      cout<<p1->size()<<endl;     cout<<(*p1).size()<<endl;      cout<<p2->size()<<endl;     cout<<(*p2).size()<<endl;      cout<<tempa.size()<<endl;     delete p1;     delete p2;     cout<<"press key to coutinue...";     cin.sync();     cin.get();     return 0; }   可以看出p的类型了吧。我初学者，如果说的不对的地方请包涵。

struct AA{ int x,y; };  int main() {     //1)     vector <AA> *p=new vector <AA>(4);     delete p;     //2)     vector <AA> *pa=new vector <AA>[4];     for(int i=0;i<4;i++)(pa+i)->resize(4);      delete []pa;         //3)     vector <AA> a;       //4)     vector<AA> v(4);     return 0; }  这些都不会出错 你的 new,和delete []不匹配，所以出错。

delete P;


Question: 判断ip地址属不属于某个区间

先把 所有的 小段  都补成    三位数， 然后 转化成 字符串，或者数字都可以

妈的,老子得了精神病

直接字符串比较可以吧

转成整数比大小就可以了

引用 楼主 nadleeh123 的回复:RT，ip就是大端格式的  私有ip  ，从协议栈里面搞下来的，大家有没神马好思路没  效果很简单,实现这种逻辑效果   192.168.1.1 <= 192.168.10.11 <= 192.168.22.255   PS;递归别来 转成word32型，比如0xc0000002,就是192.0.0.2

引用 1 楼 nice_cxf 的回复:转成整数比大小就可以了  ++ 本质上就是一个int

转成DWORD比较

引用 1 楼 nice_cxf 的回复:转成整数比大小就可以了  这个是最好的选择！

引用 1 楼 nice_cxf 的回复:转成整数比大小就可以了 英雄所见略同。

引用 2 楼 max_min_ 的回复:直接字符串比较可以吧 好象不行。


Question: dev c++新建工程为什么老是不成功？

搜“跟我一起写makefile”

别叫 main.cpp 改名就可以了。


Question: 求教hash值和数组下标对应的问题

#include <stdio.h> int d[12]={26,31,353,387,91,28,337,12,140,496,1,111}; int i; int main() {     for (i=0;i<12;i++) {         printf("%3d %lld\n",d[i],(((unsigned long long int)d[i] * 2654435769ull) & 0xFFFFFFFFull) >> 28);     }     return 0; }

上班闲逛，在网上看到关于hash算法的东西，如下： 对于32位整数值，hash算法为：index = value * 2654435769 >> 28; 有如下value值和数组位置对应关系： 本地传图片半天都没传上去，我就手写吧，大家将就着看： 数组位置     value值（链表） 0            1          26 2          31 353 387  3          91 4          28 337 5 6          12 7           8          140 496 9          1   111 10 11 12 13 14 15  我想问的是通过那个公式算出的值，怎么就和数组小标对应起来了呢，是怎么对应上的呢？？？

你那不还是有个链表吗，那个是防止冲突用的。 数据在链表中。

引用 8 楼 najiutan 的回复:[quote=引用 5 楼 zhao4zhong1 的回复:] 无视本ID的代码，你会浪费一大截生命。 哥，你不告诉我，我死都整不出来，万谢[/quote] 过了啊。

引用 5 楼 zhao4zhong1 的回复:无视本ID的代码，你会浪费一大截生命。 哥，你不告诉我，我死都整不出来，万谢

结贴！！！呵呵

引用 3 楼 zhao4zhong1 的回复:#include <stdio.h> int d[12]={26,31,353,387,91,28,337,12,140,496,1,111}; int i; int main() {     for (i=0;i<12;i++) {         printf("%3d %I64d\n",d[i],(((unsigned __int64)d[i] * 2654435769ui64) & 0xFFFFFFFFui64) >> 28);     }     return 0; } // 26 1 // 31 2 //353 2 //387 2 // 91 3 // 28 4 //337 4 // 12 6 //140 8 //496 8 //  1 9 //111 9 //  谢谢，我之前没写程序来算就直接在win下面提供的计算器算的，算出的结果居然对不上，干才用程序一算还真的是这些值。

无视本ID的代码，你会浪费一大截生命。

引用 2 楼 user-2 的回复:假设这个数组，可以放下97个元素，  那么我们只放 30个 int a[97]; int hash(int val){...return ...;}; a[hash(n)]= n; 这样，数值和表就建立了联系；  哈希算法可以确保哈希值在数组容量之内。 如果是空表，直接赋值就行。 否则要检查，是否有冲突，有冲突要处理哈希值的冲突。 我知道是这个意思，但是通过上面的算法得到的值不是数组的下标值，我就奇怪了，不知道是通过什么方式对应的


Question: 编译报错，函数返回类型？

引用 1 楼 user-4 的回复:要么进行函数的原型声明,要么把函数的实现放到函数的调用之前. 的确是函数声明的问题，不声明，gcc就默认返回int...

49行改为single = (long)a[i] * myExponentiation(x, i);

你返回的 return -1;  这是不是long型啊。。。  return -1L;

return (long)-1; return -1L; 都可以； -1 不是long 类型； 你的类型检查太严格，所以 这个return -1；不能通过；   引用 楼主 cc_mugiwala 的回复: long myExponentiation(int x, int i) {         if (i == 0) {                 return (long)1;         } else if (i == 1) {                 return (long)x;         } else if (i > 1) {                 if (i%2 == 0) {                         return myExponentiation(x*x, i/2);                 } else {                         return myExponentiation(x*x, i/2) * x;                 }         } else if (i < 0) {                return -1;//  -1 是整型 int，不是 long      } }

要么进行函数的原型声明,要么把函数的实现放到函数的调用之前.


Question: 想问一下GCC编译器下的程序需要注意什么？？

你的冒泡写的有问题，head3也参与了排序，链表头变成了最小的一项，简单来说排好序后是这样的，： 头->1->2->3  你的变成了 1->2->3->头 （这个主要看头的指数的大小，因为你未指定，所以可能正，可能负，从你的截图看是正的，一般不同机器，不同编译器，未分配数都不一样的，所以你的VS和gcc结果就有差异了） 然后你执行合并的时候少了1项，多了一项head3。 你这样改： int i, j; 	NODE *p = head3; 	int count = 0; 	while (p->next != NULL) 	{ 		count++; 		p = p->next; 	} 	for (i = 0; i < count - 1; i++) /* 冒泡法排序 */ 	{ 		q = head3; 		p = head3->next; 		for (j = 0; j < count - i - 1; j++) 		{ 			if (p->exp > p->next->exp) 			{ 				q->next=p->next; 				p->next=p->next->next; 				q->next->next=p; 			} 			q = q->next; 			p = q->next; 		} 	} 	/*-----------------------------*/ 	p3 = head3 ->next; 	pre = head3; 	while (p3->next != NULL) 	{ 		if (p3->exp == p3->next->exp) 		{ 			p3->coef += p3->next->coef; 			temp = p3->next; 			p3->next = temp->next; 			free(temp); 			if (p3->coef == 0) 			{ 				temp = p3; 				pre->next=p3->next; 				free(temp); 			} 		} 		else 		{ 			pre = pre->next; 			p3 = pre->next; 		} 	} } 后面的没什么问题，就是有点乱，我简单改了下。 还有就是一点，一个函数尽量不要写太长，明确一个函数的职责，一个函数是排序就排序，是合并就合并，最后在按顺序调用这些函数，这样以后容易阅读，写太长了反而不知道这个函数的目的是什么了。

就是结果有误,编译正确.

结果有误 给的什么提示？