Question: 多个文件夹的makefile怎么写啊

引用 12 楼 imarshal 的回复:[quote=引用 11 楼 zilaishuichina 的回复:] 扩展名你自己取什么都好， 只要你开心就好，你也可以就叫默认的.out  哦，我还以为你是在用mingw编译真正的exe[/quote]  这个就是linux下的， 只不过是我这一个c++项目里的，我复制过来的， 你的如果是c项目的话，就把cpp换成c，g++换成gcc

引用 11 楼 zilaishuichina 的回复:扩展名你自己取什么都好， 只要你开心就好，你也可以就叫默认的.out  哦，我还以为你是在用mingw编译真正的exe

引用 10 楼 imarshal 的回复:[quote=引用 9 楼 zilaishuichina 的回复:] linux都是/，windows下面才是\\  什么意思，我看第一行是exe啊，linux下怎么叫这个[/quote]  扩展名你自己取什么都好， 只要你开心就好，你也可以就叫默认的.out

引用 9 楼 zilaishuichina 的回复:linux都是/，windows下面才是\\  什么意思，我看第一行是exe啊，linux下怎么叫这个

引用 8 楼 imarshal 的回复:[quote=引用 5 楼 zilaishuichina 的回复:]   OUT_PUT = XXX/OUT/XXX.exe  SRC_DIR_XXX1 = XXX/SRC/XXX1 SRC_DIR_XXX2 = XXX/SRC/XXX2  OBJ_DIR_XXX1 = XXX/OBJ/XXX1 OBJ_DIR_XXX2 = XXX/OBJ/XXX2  OBJS = $(patsubst $(SRC_DIR_XXX1)/%.cpp, $(OBJ_DIR_XXX1)/%.o, $(wildcard $(SRC_DIR_XXX1)/*.cpp)) \ 	$(patsubst $(SRC_DIR_XXX2)/%.cpp, $(OBJ_DIR_XXX2)/%.o, $(wildcard $(SRC_DIR_XXX2)/*.cpp))  INCLUDE_DIR = -IXXX/SRC/XXX1 -IXXX/SRC/XXX2  vpath %.h XXX/SRC/XXX1 vpath %.h XXX/SRC/XXX2  vpath %.cpp XXX/SRC/XXX1 vpath %.cpp XXX/SRC/XXX2  All: $(OBJ_DIR_XXX1) $(OBJ_DIR_XXX2) $(OBJS) 	g++ -o $(OUT_PUT) $(OBJS)  $(OBJ_DIR_XXX1) $(OBJ_DIR_XXX2): 	mkdir $@  $(patsubst $(SRC_DIR_XXX1)/%.cpp, $(OBJ_DIR_XXX1)/%.o, $(wildcard $(SRC_DIR_XXX1)/*.cpp)): $(OBJ_DIR_XXX1)/%.o: $(SRC_DIR_XXX1)/%.cpp 	g++ -c $< $(INCLUDE_DIR) -o $@  $(patsubst $(SRC_DIR_XXX2)/%.cpp, $(OBJ_DIR_XXX2)/%.o, $(wildcard $(SRC_DIR_XXX2)/*.cpp)): $(OBJ_DIR_XXX2)/%.o: $(SRC_DIR_XXX2)/%.cpp 	g++ -c $< $(INCLUDE_DIR) -o $@  clean: 	-rm -rf $(OUT_PUT) $(OBJ_DIR_XXX1) $(OBJ_DIR_XXX2)    多谢了，还有很多看不明白，不过这和linux下的规则有没有区别啊，怎么exe也是用的/，应该是\\啊[/quote]   linux都是/，windows下面才是\\

引用 5 楼 zilaishuichina 的回复:  OUT_PUT = XXX/OUT/XXX.exe  SRC_DIR_XXX1 = XXX/SRC/XXX1 SRC_DIR_XXX2 = XXX/SRC/XXX2  OBJ_DIR_XXX1 = XXX/OBJ/XXX1 OBJ_DIR_XXX2 = XXX/OBJ/XXX2  OBJS = $(patsubst $(SRC_DIR_XXX1)/%.cpp, $(OBJ_DIR_XXX1)/%.o, $(wildcard $(SRC_DIR_XXX1)/*.cpp)) \ 	$(patsubst $(SRC_DIR_XXX2)/%.cpp, $(OBJ_DIR_XXX2)/%.o, $(wildcard $(SRC_DIR_XXX2)/*.cpp))  INCLUDE_DIR = -IXXX/SRC/XXX1 -IXXX/SRC/XXX2  vpath %.h XXX/SRC/XXX1 vpath %.h XXX/SRC/XXX2  vpath %.cpp XXX/SRC/XXX1 vpath %.cpp XXX/SRC/XXX2  All: $(OBJ_DIR_XXX1) $(OBJ_DIR_XXX2) $(OBJS) 	g++ -o $(OUT_PUT) $(OBJS)  $(OBJ_DIR_XXX1) $(OBJ_DIR_XXX2): 	mkdir $@  $(patsubst $(SRC_DIR_XXX1)/%.cpp, $(OBJ_DIR_XXX1)/%.o, $(wildcard $(SRC_DIR_XXX1)/*.cpp)): $(OBJ_DIR_XXX1)/%.o: $(SRC_DIR_XXX1)/%.cpp 	g++ -c $< $(INCLUDE_DIR) -o $@  $(patsubst $(SRC_DIR_XXX2)/%.cpp, $(OBJ_DIR_XXX2)/%.o, $(wildcard $(SRC_DIR_XXX2)/*.cpp)): $(OBJ_DIR_XXX2)/%.o: $(SRC_DIR_XXX2)/%.cpp 	g++ -c $< $(INCLUDE_DIR) -o $@  clean: 	-rm -rf $(OUT_PUT) $(OBJ_DIR_XXX1) $(OBJ_DIR_XXX2)    多谢了，还有很多看不明白，不过这和linux下的规则有没有区别啊，怎么exe也是用的/，应该是\\啊

引用 6 楼 zhao4zhong1 的回复:一般都是一个项目一个makefile 比如： D:\MSDN98\SAMPLES\VC98\MFC\TUTORIAL>dir /b /s makefile D:\MSDN98\SAMPLES\VC98\MFC\TUTORIAL\AUTOCLIK\STEP1\MAKEFILE D:\MSDN98\SAMPLES\VC98\MFC\TUTORIAL\AUTOCLIK\STEP2\MAKEFILE D:\MSDN98\SAMPLES\VC98\MFC\TUTORIAL\AUTOCLIK\STEP3\MAKEFILE D:\MSDN98\SAMPLES\VC98\MFC\TUTORIAL\AUTODRIV\MAKEFILE D:\MSDN98\SAMPLES\VC98\MFC\TUTORIAL\CONTAIN\STEP1\MAKEFILE D:\MSDN98\SAMPLES\VC98\MFC\TUTORIAL\CONTAIN\STEP2\MAKEFILE D:\MSDN98\SAMPLES\VC98\MFC\TUTORIAL\ENROLL\STEP1\MAKEFILE D:\MSDN98\SAMPLES\VC98\MFC\TUTORIAL\ENROLL\STEP2\MAKEFILE D:\MSDN98\SAMPLES\VC98\MFC\TUTORIAL\ENROLL\STEP3\MAKEFILE D:\MSDN98\SAMPLES\VC98\MFC\TUTORIAL\ENROLL\STEP4\MAKEFILE D:\MSDN98\SAMPLES\VC98\MFC\TUTORIAL\SCRIBBLE\STEP1\MAKEFILE D:\MSDN98\SAMPLES\VC98\MFC\TUTORIAL\SCRIBBLE\STEP2\MAKEFILE D:\MSDN98\SAMPLES\VC98\MFC\TUTORIAL\SCRIBBLE\STEP3\MAKEFILE D:\MSDN98\SAMPLES\VC98\MFC\TUTORIAL\SCRIBBLE\STEP4\MAKEFILE D:\MSDN98\SAMPLES\VC98\MFC\TUTORIAL\SCRIBBLE\STEP5\MAKEFILE D:\MSDN98\SAMPLES\VC98\MFC\TUTORIAL\SCRIBBLE\STEP6\MAKEFILE D:\MSDN98\SAMPLES\VC98\MFC\TUTORIAL\SCRIBBLE\STEP7\MAKEFILE

一般都是一个项目一个makefile

引用 2 楼 imarshal 的回复:[quote=引用 1 楼 zilaishuichina 的回复:] All: 	cd XXX; make 	cd XXX; make 	cd XXX; make 	cd XXX; make  这样写感觉不太好啊，应该是只写一个makefile，就是不知道makefile中怎么处理cd的[/quote]     OUT_PUT = XXX/OUT/XXX.exe  SRC_DIR_XXX1 = XXX/SRC/XXX1 SRC_DIR_XXX2 = XXX/SRC/XXX2  OBJ_DIR_XXX1 = XXX/OBJ/XXX1 OBJ_DIR_XXX2 = XXX/OBJ/XXX2  OBJS = $(patsubst $(SRC_DIR_XXX1)/%.cpp, $(OBJ_DIR_XXX1)/%.o, $(wildcard $(SRC_DIR_XXX1)/*.cpp)) \ 	$(patsubst $(SRC_DIR_XXX2)/%.cpp, $(OBJ_DIR_XXX2)/%.o, $(wildcard $(SRC_DIR_XXX2)/*.cpp))  INCLUDE_DIR = -IXXX/SRC/XXX1 -IXXX/SRC/XXX2  vpath %.h XXX/SRC/XXX1 vpath %.h XXX/SRC/XXX2  vpath %.cpp XXX/SRC/XXX1 vpath %.cpp XXX/SRC/XXX2  All: $(OBJ_DIR_XXX1) $(OBJ_DIR_XXX2) $(OBJS) 	g++ -o $(OUT_PUT) $(OBJS)  $(OBJ_DIR_XXX1) $(OBJ_DIR_XXX2): 	mkdir $@  $(patsubst $(SRC_DIR_XXX1)/%.cpp, $(OBJ_DIR_XXX1)/%.o, $(wildcard $(SRC_DIR_XXX1)/*.cpp)): $(OBJ_DIR_XXX1)/%.o: $(SRC_DIR_XXX1)/%.cpp 	g++ -c $< $(INCLUDE_DIR) -o $@  $(patsubst $(SRC_DIR_XXX2)/%.cpp, $(OBJ_DIR_XXX2)/%.o, $(wildcard $(SRC_DIR_XXX2)/*.cpp)): $(OBJ_DIR_XXX2)/%.o: $(SRC_DIR_XXX2)/%.cpp 	g++ -c $< $(INCLUDE_DIR) -o $@  clean: 	-rm -rf $(OUT_PUT) $(OBJ_DIR_XXX1) $(OBJ_DIR_XXX2)

引用 3 楼 zhao4zhong1 的回复:搜“跟我一起写makefile”  没讲到，不可能一个文件夹一个makefile啊

搜“跟我一起写makefile”

引用 1 楼 zilaishuichina 的回复:All: 	cd XXX; make 	cd XXX; make 	cd XXX; make 	cd XXX; make  这样写感觉不太好啊，应该是只写一个makefile，就是不知道makefile中怎么处理cd的


Question: 北邮ACM题

gets(a);不丢弃换行符，所以会导致下一次读不是预期的数据

边界条件 输入输出格式 ……

嗯嗯，谢谢各位，这里貌似用gets总是会读入回车  引用 3 楼 cfjtaishan 的回复: #include <stdio.h> #include <string.h>  int main() {     char a[1008];     int m, i, j, count, min;      scanf("%d\n",&m);      while(m--) {         fgets(a, 1007, stdin);         a[strlen(a)-1] = 0;         min=9999999;         for(i=0;a[i]!='\0';i++){             count=0;             for(j=0;a[j]!='\0';j++){                 if(a[i]>a[j])                     count+=(a[i]-a[j])<(a[j]+26-a[i])?(a[i]-a[j]):(a[j]+26-a[i]);                 if(a[i]<a[j])                     count+=(a[j]-a[i])<(a[i]+26-a[j])?(a[j]-a[i]):(a[i]+26-a[j]);             }             if(min>count)                 min=count;         }         printf("%d\n",min);     }     return 0; }  用fgets替换gets是想把警告去掉；fgets和gets都会将换行符自动加到字符数组倒数第二个位置，最后一个字符是字符串结束标志。 所以，通过a[strlen(a)-1] = 0就是用字符串结束标记覆盖回车符。这样就把字符数组a中的回车符去掉了。 这里还是答案错误了

引用 2 楼 jianwen0529 的回复:gets(a); getchar(); //读取一个字符，把换行符读取掉  你试试这个 这种方法是行不通的，因为gets是将回车符加到了字符串数组中成为字符串的一部分，getchar是接收回车符，是改变不了gets将回车符加到字符串中的。 比如输入abbba,在字符串中的存放是： abbba\n\0

引用 7 楼 jianwen0529 的回复:[quote=引用 4 楼 cfjtaishan 的回复:] [quote=引用 2 楼 jianwen0529 的回复:] gets(a); getchar(); //读取一个字符，把换行符读取掉  你试试这个 这种方法是行不通的，因为gets是将回车符加到了字符串数组中成为字符串的一部分，getchar是接收回车符，是改变不了gets将回车符加到字符串中的。 比如输入abbba,在字符串中的存放是： abbba\n\0[/quote]  gets 跟 fgets 是不一样的，buffer中并不会保存换行符 http://www.cplusplus.com/reference/cstdio/gets/?kw=gets[/quote] sorry,是我记错了～

引用 4 楼 cfjtaishan 的回复:[quote=引用 2 楼 jianwen0529 的回复:] gets(a); getchar(); //读取一个字符，把换行符读取掉  你试试这个 这种方法是行不通的，因为gets是将回车符加到了字符串数组中成为字符串的一部分，getchar是接收回车符，是改变不了gets将回车符加到字符串中的。 比如输入abbba,在字符串中的存放是： abbba\n\0[/quote]  gets 跟 fgets 是不一样的，buffer中并不会保存换行符 http://www.cplusplus.com/reference/cstdio/gets/?kw=gets


Question: 为什么我用C语言无法实现输入，应该是一个很简单的问题，但是我不知道问题出在哪

改成scanf("%lf",&r);

6楼头像太萌！会萌死人的。

printf里面的%和变量的一一对应关系 scanf里面的%和变量以及变量前加不加&的一一对应关系 是C代码中非常容易出错的地方，而且通常编译还不出错。 所以在编译源代码之前值得专门仔细检查一遍甚至多遍。  在每个最后不带\n的printf后面加fflush(stdout); 在每个不想受接收缓冲区旧内容影响的scanf前面加rewind(stdin); 另外请检查scanf的返回值。 //请今后要用 int c; scanf("%c",&c); //时，都改为 char s[2]; int c; scanf("%1s",s); c=s[0];

%d 是 int %f 是 float %lf 是 double

引用 3 楼 u011498414 的回复:应该是scanf("%lf",&r); 因为这是DOUBLE型的数据。 果然解决了，非常感谢！ 但是10个用例只能通过7个，请问是怎么回事呀？

应该是scanf("%lf",&r); 因为这是DOUBLE型的数据。

引用 1 楼 sinat_35261315 的回复:scanf("%f",&r); 我试了，还是不行。。。输出依然是0。

scanf("%f",&r);


Question: C语言函数setenv为找到定义

引用 3 楼 小灸舞 的回复:setenv 头文件 #include<stdlib.h>  定义函数 int setenv(const char *name,const char * value,int overwrite);  函数说明 setenv()用来改变或增加环境变量的内容。参数name为环境变量名称字符串。  参数 value则为变量内容，参数overwrite用来决定是否要改变已存在的环境变量。如果overwrite不为0，而该环境变量原已有内容会被改为参数value所指的变量内容。如果overwrite为0，且该环境变量已有内容，则参数value会被忽略。  返回值 执行成功则返回0，有错误发生时返回-1。  举例： #include<stdlib.h> int main() { 　　char * p; 　　if((p=getenv(“USER”))) 　　　　printf(“USER =%sn”,p); 　　setenv(“USER”,"test",1); 　　printf(“USER=%sn”,getenv(“USEr”)); 　　unsetenv(“USER”); 　　printf(“USER=%sn”,getenv(“USER”)); } 执行： USER = root USER = test USER = (null) 说明：1、unsetenv函数就是清除环境变量的值(value)，这个很明显           2、如果overwrite 的值是0，并且环境变量name中的value是空(NULL)，也会将传进的参数值value赋给环境变量name。这一特性经常使用。  版主大大，这个setenv如果设置失败返回-1的原因有哪些呀？ 我在测试中调用一直返回0，但是在生产上突然出现返回-1的情况。但我又没有排查出来问题。希望请教一下

#include<stdlib.h>


Question: C++语言小白求助，关于零钱计算

引用 7 楼 qq_36483087 的回复:我输入 0.36的时候，结果不对呀。 第一轮n=35， 第二轮 n=10，第三轮n=0；  第一轮 n应该是36呀 这个是浮点数的存储导致的，浮点数是以二进制存储的，0.36实际上是以0.35999999的形式，所以浮点到整型的强制转换会导致个位数的改变  解决方法： int n=(int)(rmn*100); 改成 int n=round(rmn*100);  round()在math头文件中，前面顺便加上  #include<math.h>

#include <stdio.h> #include <stdlib.h> #include <string.h> float f; double d; void showf() {     char bs[65];     char b[65];     unsigned char *p;     char e[12];     char *t;     int ex;      printf("\nf=%.6f\n",f);     p=(unsigned char *)&f;     printf("hex=%02X %02X %02X %02X\n",p[3],p[2],p[1],p[0]);     ltoa(*(long *)&f,b,2);     sprintf(bs,"%032s",b);     printf("bin=%s\n",bs);     printf("bin=%.1s %.8s   %s\n",bs,bs+1,bs+9);     strncpy(e,bs+1,8);e[8]=0;     ex=strtol(e,&t,2);     printf("    %c %-4d-127 1.%s\n",(bs[0]=='0')?'+':'-',ex,bs+9);     ex-=127;     printf("    %c %-8d 1.%s\n",(bs[0]=='0')?'+':'-',ex,bs+9); } void showd() {     char bs[65];     char b[65];     unsigned char *p;     char e[12];     char *t;     int ex;      printf("\nd=%.15lf\n",d);     p=(unsigned char *)&d;     printf("hex=%02X %02X %02X %02X %02X %02X %02X %02X\n",p[7],p[6],p[5],p[4],p[3],p[2],p[1],p[0]);     _i64toa(*(__int64 *)&d,b,2);     sprintf(bs,"%064s",b);     printf("bin=%s\n",bs);     printf("bin=%.1s %.11s   %s\n",bs,bs+1,bs+12);     strncpy(e,bs+1,11);e[11]=0;     ex=strtol(e,&t,2);     printf("    %c %-6d-1023 1.%s\n",(bs[0]=='0')?'+':'-',ex,bs+12);     ex-=1023;     printf("    %c %-11d 1.%s\n",(bs[0]=='0')?'+':'-',ex,bs+12); } int main() {      for (f=0.0f;f<=2.2f;f+=0.2f) showf();     printf("------------\n");     f=2.0f;showf();     printf("-----------------------------------\n");     for (d=0.0 ;d<=2.2 ;d+=0.2 ) showd();     printf("------------\n");     d=2.0 ;showd();      return 0; } // //f=0.000000 //hex=00 00 00 00 //bin=00000000000000000000000000000000 //bin=0 00000000   00000000000000000000000 //  + 0   -127 1.00000000000000000000000 //  + -127     1.00000000000000000000000 // //f=0.200000 //hex=3E 4C CC CD //bin=00111110010011001100110011001101 //bin=0 01111100   10011001100110011001101 //  + 124 -127 1.10011001100110011001101 //  + -3       1.10011001100110011001101 // //f=0.400000 //hex=3E CC CC CD //bin=00111110110011001100110011001101 //bin=0 01111101   10011001100110011001101 //  + 125 -127 1.10011001100110011001101 //  + -2       1.10011001100110011001101 // //f=0.600000 //hex=3F 19 99 9A //bin=00111111000110011001100110011010 //bin=0 01111110   00110011001100110011010 //  + 126 -127 1.00110011001100110011010 //  + -1       1.00110011001100110011010 // //f=0.800000 //hex=3F 4C CC CD //bin=00111111010011001100110011001101 //bin=0 01111110   10011001100110011001101 //  + 126 -127 1.10011001100110011001101 //  + -1       1.10011001100110011001101 // //f=1.000000 //hex=3F 80 00 00 //bin=00111111100000000000000000000000 //bin=0 01111111   00000000000000000000000 //  + 127 -127 1.00000000000000000000000 //  + 0        1.00000000000000000000000 // //f=1.200000 //hex=3F 99 99 9A //bin=00111111100110011001100110011010 //bin=0 01111111   00110011001100110011010 //  + 127 -127 1.00110011001100110011010 //  + 0        1.00110011001100110011010 // //f=1.400000 //hex=3F B3 33 34 //bin=00111111101100110011001100110100 //bin=0 01111111   01100110011001100110100 //  + 127 -127 1.01100110011001100110100 //  + 0        1.01100110011001100110100 // //f=1.600000 //hex=3F CC CC CE //bin=00111111110011001100110011001110 //bin=0 01111111   10011001100110011001110 //  + 127 -127 1.10011001100110011001110 //  + 0        1.10011001100110011001110 // //f=1.800000 //hex=3F E6 66 68 //bin=00111111111001100110011001101000 //bin=0 01111111   11001100110011001101000 //  + 127 -127 1.11001100110011001101000 //  + 0        1.11001100110011001101000 // //f=2.000000 //hex=40 00 00 01 //bin=01000000000000000000000000000001 //bin=0 10000000   00000000000000000000001 //  + 128 -127 1.00000000000000000000001 //  + 1        1.00000000000000000000001 //------------ // //f=2.000000 //hex=40 00 00 00 //bin=01000000000000000000000000000000 //bin=0 10000000   00000000000000000000000 //  + 128 -127 1.00000000000000000000000 //  + 1        1.00000000000000000000000 //----------------------------------- // //d=0.000000000000000 //hex=00 00 00 00 00 00 00 00 //bin=0000000000000000000000000000000000000000000000000000000000000000 //bin=0 00000000000   0000000000000000000000000000000000000000000000000000 //  + 0     -1023 1.0000000000000000000000000000000000000000000000000000 //  + -1023       1.0000000000000000000000000000000000000000000000000000 // //d=0.200000000000000 //hex=3F C9 99 99 99 99 99 9A //bin=0011111111001001100110011001100110011001100110011001100110011010 //bin=0 01111111100   1001100110011001100110011001100110011001100110011010 //  + 1020  -1023 1.1001100110011001100110011001100110011001100110011010 //  + -3          1.1001100110011001100110011001100110011001100110011010 // //d=0.400000000000000 //hex=3F D9 99 99 99 99 99 9A //bin=0011111111011001100110011001100110011001100110011001100110011010 //bin=0 01111111101   1001100110011001100110011001100110011001100110011010 //  + 1021  -1023 1.1001100110011001100110011001100110011001100110011010 //  + -2          1.1001100110011001100110011001100110011001100110011010 // //d=0.600000000000000 //hex=3F E3 33 33 33 33 33 34 //bin=0011111111100011001100110011001100110011001100110011001100110100 //bin=0 01111111110   0011001100110011001100110011001100110011001100110100 //  + 1022  -1023 1.0011001100110011001100110011001100110011001100110100 //  + -1          1.0011001100110011001100110011001100110011001100110100 // //d=0.800000000000000 //hex=3F E9 99 99 99 99 99 9A //bin=0011111111101001100110011001100110011001100110011001100110011010 //bin=0 01111111110   1001100110011001100110011001100110011001100110011010 //  + 1022  -1023 1.1001100110011001100110011001100110011001100110011010 //  + -1          1.1001100110011001100110011001100110011001100110011010 // //d=1.000000000000000 //hex=3F F0 00 00 00 00 00 00 //bin=0011111111110000000000000000000000000000000000000000000000000000 //bin=0 01111111111   0000000000000000000000000000000000000000000000000000 //  + 1023  -1023 1.0000000000000000000000000000000000000000000000000000 //  + 0           1.0000000000000000000000000000000000000000000000000000 // //d=1.200000000000000 //hex=3F F3 33 33 33 33 33 33 //bin=0011111111110011001100110011001100110011001100110011001100110011 //bin=0 01111111111   0011001100110011001100110011001100110011001100110011 //  + 1023  -1023 1.0011001100110011001100110011001100110011001100110011 //  + 0           1.0011001100110011001100110011001100110011001100110011 // //d=1.400000000000000 //hex=3F F6 66 66 66 66 66 66 //bin=0011111111110110011001100110011001100110011001100110011001100110 //bin=0 01111111111   0110011001100110011001100110011001100110011001100110 //  + 1023  -1023 1.0110011001100110011001100110011001100110011001100110 //  + 0           1.0110011001100110011001100110011001100110011001100110 // //d=1.600000000000000 //hex=3F F9 99 99 99 99 99 99 //bin=0011111111111001100110011001100110011001100110011001100110011001 //bin=0 01111111111   1001100110011001100110011001100110011001100110011001 //  + 1023  -1023 1.1001100110011001100110011001100110011001100110011001 //  + 0           1.1001100110011001100110011001100110011001100110011001 // //d=1.800000000000000 //hex=3F FC CC CC CC CC CC CC //bin=0011111111111100110011001100110011001100110011001100110011001100 //bin=0 01111111111   1100110011001100110011001100110011001100110011001100 //  + 1023  -1023 1.1100110011001100110011001100110011001100110011001100 //  + 0           1.1100110011001100110011001100110011001100110011001100 // //d=2.000000000000000 //hex=3F FF FF FF FF FF FF FF //bin=0011111111111111111111111111111111111111111111111111111111111111 //bin=0 01111111111   1111111111111111111111111111111111111111111111111111 //  + 1023  -1023 1.1111111111111111111111111111111111111111111111111111 //  + 0           1.1111111111111111111111111111111111111111111111111111 // //d=2.200000000000000 //hex=40 01 99 99 99 99 99 99 //bin=0100000000000001100110011001100110011001100110011001100110011001 //bin=0 10000000000   0001100110011001100110011001100110011001100110011001 //  + 1024  -1023 1.0001100110011001100110011001100110011001100110011001 //  + 1           1.0001100110011001100110011001100110011001100110011001 //------------ // //d=2.000000000000000 //hex=40 00 00 00 00 00 00 00 //bin=0100000000000000000000000000000000000000000000000000000000000000 //bin=0 10000000000   0000000000000000000000000000000000000000000000000000 //  + 1024  -1023 1.0000000000000000000000000000000000000000000000000000 //  + 1           1.0000000000000000000000000000000000000000000000000000 //

浮点数格式 http://bbs.csdn.net/topics/390676437

引用 2 楼 u012021393 的回复:发错了，这个才是  void do_print(double rmn){      int i=0 ,ttd=0, td=0, fd=0,od=0,ftc=0,tfc=0,tc=0,fc=0,oc=0;     int n=(int)(rmn*100);     while(n>0){         cout << " before :ooooooo "<<rmn<<endl;          if(n>=2000){             n = n -2000;             ttd++;             //break;             }             else if(n<2000&&n>=1000){                 n = n -1000;                 td++;                // break;             }                 else if(n<1000&&n>=500){                     n = n -500;                     fd++;                     //break;                 }                     else if(n<500&&n>=100){                         n =n -100;                         od++;                        // break;                     }                         else if(n<100&&n>=50){                             n=n-50;                             ftc ++;                            // break;                         }                             else if(n<50&&n>=25){                                 n =n -25;                                 tfc ++;                                // break;                             }                                 else if(n<25&&n>=10){                                     n=n-10;                                     tc++;                                     //break;                                 }                                     else if(n<10&&n>=5){                                          n=n-5;                                         fc++;                                         cout << "74"<<n<<endl;                                        // break;                                     }                                         else if(n<5&&n>=1){                                                n=n-1;                                             oc++;                                             //break;                                         }                                         //else ;                            cout << " aaaaT:ooooooo "<<rmn<<endl;                         }      //cout << " T: "<<rmn<<endl;     cout << " Twenty US Dollar Bills: "<<ttd<<endl;     cout << " Ten US Dollar Bills: "<<td<<endl;     cout << " Five US Dollar Bills: "<<fd<<endl;     cout << " One US Dollar Bills: "<<od<<endl;     cout << " Fifty US Cents Coins: "<<ftc<<endl;     cout << " Twenty-Five US Cents Coins: "<<tfc<<endl;     cout << " Ten US Cents Coins: "<<tc<<endl;     cout << " Five US Cents Coins: "<<fc<<endl;     cout << " One US Cent Coins: "<<oc<<endl;  }  发错了，这个才是   我输入 0.36的时候，结果不对呀。 第一轮n=35， 第二轮 n=10，第三轮n=0；  第一轮 n应该是36呀

二进制小数不能精确表示 1/10  就像  十进制小数不能精确表示 1/3

大部分浮点数无法精确存储，只是存储一个近似值。 http://blog.chinaunix.net/uid-23204219-id-1761337.html

引用 2 楼 u012021393 的回复:发错了，这个才是  void do_print(double rmn){      int i=0 ,ttd=0, td=0, fd=0,od=0,ftc=0,tfc=0,tc=0,fc=0,oc=0;     int n=(int)(rmn*100);     while(n>0){         cout << " before :ooooooo "<<rmn<<endl;          if(n>=2000){             n = n -2000;             ttd++;             //break;             }             else if(n<2000&&n>=1000){                 n = n -1000;                 td++;                // break;             }                 else if(n<1000&&n>=500){                     n = n -500;                     fd++;                     //break;                 }                     else if(n<500&&n>=100){                         n =n -100;                         od++;                        // break;                     }                         else if(n<100&&n>=50){                             n=n-50;                             ftc ++;                            // break;                         }                             else if(n<50&&n>=25){                                 n =n -25;                                 tfc ++;                                // break;                             }                                 else if(n<25&&n>=10){                                     n=n-10;                                     tc++;                                     //break;                                 }                                     else if(n<10&&n>=5){                                          n=n-5;                                         fc++;                                         cout << "74"<<n<<endl;                                        // break;                                     }                                         else if(n<5&&n>=1){                                                n=n-1;                                             oc++;                                             //break;                                         }                                         //else ;                            cout << " aaaaT:ooooooo "<<rmn<<endl;                         }      //cout << " T: "<<rmn<<endl;     cout << " Twenty US Dollar Bills: "<<ttd<<endl;     cout << " Ten US Dollar Bills: "<<td<<endl;     cout << " Five US Dollar Bills: "<<fd<<endl;     cout << " One US Dollar Bills: "<<od<<endl;     cout << " Fifty US Cents Coins: "<<ftc<<endl;     cout << " Twenty-Five US Cents Coins: "<<tfc<<endl;     cout << " Ten US Cents Coins: "<<tc<<endl;     cout << " Five US Cents Coins: "<<fc<<endl;     cout << " One US Cent Coins: "<<oc<<endl;  }  发错了，这个才是  聪明啊 好哒，谢谢拉。 电脑中0.1不是完全的0.1好像都是个约值。 您能说说这个吗？

太复杂了，其实代码是这样的。至于浮点之类的，乘以100转换为整数就可以了。 int cc(int v, int *s, int count) { 	if (v == 0) return 1; 	if (v < 0 || count == 0) return 0; 	return cc(v, &s[1], count - 1) + cc(v - s[0], s, count); }  int test_cc() { /*把1元钱换成50分 20分 10分 5分 2分 1分的方法*/ 	int s[] = { 50, 20 , 10, 5, 2, 1 }; 	int v = 100; 	int count = 6; 	int sum = cc(v, s, count); 	printf("sum=%d\n", sum); }

最好别直接用浮点数，转换成int再用  #include <iostream>   using namespace std;   void do_print(double rmn);   int main() {       double value, buy, rmn, tmp;       cout << " Enter a value: ";     cin >> value;     cout << " Enter an amount of purchases made against this amount: ";     cin >> buy;     rmn = value - buy;     cout << " The remaining change is: " << rmn <<endl;     do_print(rmn);                   return 0; }   void do_print(double rmn){       int i=0 ,ttd=0, td=0, fd=0,od=0,ftc=0,tfc=0,tc=0,fc=0,oc=0;       while(rmn>0){         cout << " before :ooooooo "<<rmn<<endl;           if(rmn>=20){             rmn = rmn -20;             ttd++;             //break;             }             else if(rmn<20&&rmn>=10){                 rmn = rmn -10;                 td++;                // break;             }                 else if(rmn<10&&rmn>=5){                     rmn = rmn -5;                     fd++;                     //break;                 }                     else if(rmn<5&&rmn>=1){                         rmn =rmn -1;                         od++;                        // break;                     }                         else if(rmn<1&&rmn>=0.5){                             rmn=rmn-0.5;                             ftc ++;                            // break;                         }                             else if(rmn<0.5&&rmn>=0.25){                                 rmn =rmn -0.25;                                 tfc ++;                                // break;                             }                                 else if(rmn<0.25&&rmn>=0.1){                                     rmn=rmn-0.1;                                     tc++;                                     //break;                                 }                                     else if(rmn<0.1&&rmn>=0.05){                                           rmn=rmn-0.05;                                         fc++;                                         cout << "74"<<rmn<<endl;                                        // break;                                     }                                         else /*if(rmn<0.05&&rmn>=0.01)*/{                                                rmn=rmn-0.01;                                             oc++;                                             //break;                                         }                                         //else ;                                                       cout << " aaaaT:ooooooo "<<rmn<<endl;                         }       //cout << " T: "<<rmn<<endl;     cout << " Twenty US Dollar Bills: "<<ttd<<endl;     cout << " Ten US Dollar Bills: "<<td<<endl;     cout << " Five US Dollar Bills: "<<fd<<endl;     cout << " One US Dollar Bills: "<<od<<endl;     cout << " Fifty US Cents Coins: "<<ftc<<endl;     cout << " Twenty-Five US Cents Coins: "<<tfc<<endl;     cout << " Ten US Cents Coins: "<<tc<<endl;     cout << " Five US Cents Coins: "<<fc<<endl;     cout << " One US Cent Coins: "<<oc<<endl;   }


Question: 大神老师看过来！这个函数的功能是删除字符串中的字符，但是这个函数具体是怎样执行的？求详细叙述

引用 5 楼 include_xy 的回复:引用 2 楼 cfjtaishan 的回复:逻辑是：通过遍历str字符数组，用后面的字符覆盖前面查到的字符ch，你注意一下i和j的变化；单步调试的时候i=j=0这一步是直接跳过的，这个我很疑惑 直接跳过是什么意思？i=j=0这句是初始化呢

代码功能归根结底不是别人帮自己看或讲解或注释出来的；而是被自己静下心来花足够长的时间和精力亲自动手单步或设断点或对执行到某步获得的中间结果显示或写到日志文件中一步一步分析出来的。 提醒：再牛×的老师也无法代替学生自己领悟和上厕所！ 单步调试和设断点调试（VS IDE中编译连接通过以后，按F10或F11键单步执行，按Shift+F11退出当前函数；在某行按F9设断点后按F5执行停在该断点处。）是程序员必须掌握的技能之一。

void delete_string(char str[],char ch)   功能描述：去掉原字符串(str)中含有指定字符（ch），并返回 执行过程： void delete_string(char str[],char ch) { int i,j; for(i=j=0;str[i]!='\0';i++)/*循环依次指向str中的每个字符，直至结局，即str[i]='\0'*/ if(str[i]!=ch) str[j++]=str[i];/*当ch不等于str第i个字符时，当前字符不变（i 和j自加前是相等的）*/ str[j]='\0'; }

引用 2 楼 cfjtaishan 的回复:逻辑是：通过遍历str字符数组，用后面的字符覆盖前面查到的字符ch，你注意一下i和j的变化；在那之前我已经单步调试了，只是单步调试后也不是很明白，所以才会问的。你说的很有道理！谢谢！

向前递增，判断某个字符是否为需要删除的字符（i）     是：         跳过     不是：         则赋值给 j 位置，并且 j 向前一步 i 递增  所有字符循环完毕，在有效字符的下一个位置用 '\0' 截断


Question: 菜鸟求大解答一下

多谢了，要的就是这样的东西。

1.pNew->pNext=NULL;	//这一行你的理解是对的，将新结点的pNext指针指向空 2.pEnd->pNext=pNew; //这一行你的理解好像就不对了，并不是将pNew的值给了pEnd，而是将pEnd(指向最后一个结点)的pNext指向指向了新结点（实现了新节点的插入操作） 3.pEnd=pNew; //这行理解也不对，并不是pNew（空）给了pEnd，此时的pNew并不为空，它是刚刚malloc出来的啊 意思是：pEnd指向pNew（pEnd始终保持指向最后一个结点）

else语句，第一行pNew一开始指向空，第二行将pNew的值给了pEnd，第三行怎么又将pNew（空）给了pEnd呢？大神我是纯属自学，下学期才开课了。基础不好请见谅

因为开始时，链表为空，当iCount为1时，就是创建第一个节点时，即头节点。后面创建的节点直接放在头节点之后。

iCount为1的时候，也就是这是你第一个插入的结点： pNew->pNext=pHead;	/*使得指向为空*/ pEnd=pNew;	/*跟踪新加入的结点*/ pHead=pNew;	/*头指针指向首结点*/ 感觉注释讲的很清楚了啊？  else分支： pNew->pNext=NULL;	/*新结点的pNext指针为空*/ pEnd->pNext=pNew;	/*原来的最后一个结点的pNext指向新结点,也就连上了新的结点到链表上了*/ pEnd=pNew;	/*pEnd指向新结点（最后一个结点）*/

1： 如果链表没有节点 把新的节点赋值给头结点 否则 把新节点追加到尾节点的下一个节点  2： 链表结构简化为下面 Head-->1-->2-->3-->......-->NULL  一直找下去直到NULL为止


Question: 学习APUE书的时候，编译源代码提示找不到 -lbsd

可用命令ld --verbose | grep SEARCH列出搜索路径， 一般/lib, /usr/lib, /usr/local/lib这三个都有，另外就是自定义的

引用 2 楼 chenzhp 的回复:[quote=引用 1 楼 user-1 的回复:] 试试sudo apt-get install libbsd-dev  还是你厉害啊。谢谢，成功了。 顺便问一下，我install了这个以后，为什么我在usr/lib里面还是看不到libbsd相关的，但是编译就没问题了呢。[/quote] 那可能在其他目录 ，你可以用locate命令搜索一下

引用 1 楼 user-1 的回复:试试sudo apt-get install libbsd-dev  还是你厉害啊。谢谢，成功了。 顺便问一下，我install了这个以后，为什么我在usr/lib里面还是看不到libbsd相关的，但是编译就没问题了呢。

试试sudo apt-get install libbsd-dev


Question: 我把main函数和print函数放在不同的文件中，但有错误，错误我放在程序最后，急用，求大神

最好还是全部编译通过最好

你这只是一些警告，如果没有ERROR的话应该是能编译过去的。 http://wenku.baidu.com/link?url=KYYGCw9QfkY4ua_gZzu9QeCg3S3Y3wFf0Dbm-QfXMIOY_QmHmKF9Z6Fv7DWg3V7zYmhI4yLa6G8tFfYADQh_r3NnbQ88_HSyfNgXfU5QxcK

注意，将函数的声明放在main函数的前面，函数定义可以放在main函数之后。 也可以将函数声明放在一个头文件里，然后通过include到main函数所在的文件里。

main()函数的文件加上#include "XXX.h"  把main()函数文件的#include <stdio.h> 写到 .h 文件里去

在你实现         void scan(); 	void print(); 	void delet(); 	void stu_aver(); 	void total_aver(); 的c文件里面 #include<stdio.h>  void (*p)(); 修改为 typedef void (*p)();

只是把void( *p )( )改为typedef  void （*p）（）的话不对啊，有语法错误

感觉应该要添加自己编写库函数的头文件~


Question: CodeForces - 217A  为什么WA了

3 0 0 1 1 0 1


Question: remove（）函数的相关问题

引用 2 楼 cc_innocent 的回复:楼上的dalao我还是不懂，什么叫 删除的名称是文件的最后一个链接。 还有  打开的是文档吧 ，没有打开要删除的文件 。为什么还是要fclose才能删  进程占用了啊

引用 2 楼 cc_innocent 的回复:楼上的dalao我还是不懂，什么叫 删除的名称是文件的最后一个链接。 还有  打开的是文档吧 ，没有打开要删除的文件 。为什么还是要fclose才能删  Linux系统中,文件存在硬链接.一个文件实际的数据块可以对应多个文件名. 请看Linux link DESCRIPTION        link() creates a new link (also known as a hard link) to an existing file.         If newpath exists it will not be overwritten.         This new name may be used exactly as the old one for any operation; both names        refer to the same file (and so have the same permissions and ownership) and it        is impossible to tell which name was the "original".  link man document      chunli@Linux:~$ man 2 link LINK(2)                       Linux Programmer's Manual                       LINK(2)    NAME        link - make a new name for a file  SYNOPSIS        #include <unistd.h>         int link(const char *oldpath, const char *newpath);  DESCRIPTION        link() creates a new link (also known as a hard link) to an existing file.         If newpath exists it will not be overwritten.         This new name may be used exactly as the old one for any operation; both names        refer to the same file (and so have the same permissions and ownership) and it        is impossible to tell which name was the "original".  RETURN VALUE        On  success,  zero  is  returned.   On error, -1 is returned, and errno is set        appropriately.  ERRORS        EACCES Write access to the directory containing newpath is denied,  or  search               permission  is  denied for one of the directories in the path prefix of               oldpath or newpath.  (See also path_resolution(7).)         EDQUOT The user's quota of disk blocks on the filesystem has been exhausted.         EEXIST newpath already exists.         EFAULT oldpath or newpath points outside your accessible address space.         EIO    An I/O error occurred.         ELOOP  Too many symbolic links were encountered in resolving oldpath  or  new‐               path.         EMLINK The file referred to by oldpath already has the maximum number of links               to it.         ENAMETOOLONG               oldpath or newpath was too long.         ENOENT A directory component in oldpath or newpath does not exist or is a dan‐               gling symbolic link.         ENOMEM Insufficient kernel memory was available.         ENOSPC The device containing the file has no room for the new directory entry.         ENOTDIR               A  component used as a directory in oldpath or newpath is not, in fact,               a directory.         EPERM  oldpath is a directory.         EPERM  The filesystem containing oldpath and newpath does not support the cre‐               ation of hard links.         EPERM (since Linux 3.6)               The  caller does not have permission to create a hard link to this file               (see the description of /proc/sys/fs/protected_hardlink in proc(5)).         EROFS  The file is on a read-only filesystem.         EXDEV  oldpath and newpath are not on the  same  mounted  filesystem.   (Linux               permits  a filesystem to be mounted at multiple points, but link() does               not work across different mount points, even if the same filesystem  is               mounted on both.)  CONFORMING TO        SVr4, 4.3BSD, POSIX.1-2001 (but see NOTES).  NOTES        Hard  links, as created by link(), cannot span filesystems.  Use symlink(2) if        this is required.         POSIX.1-2001 says that link() should dereference oldpath if it is  a  symbolic        link.   However,  since kernel 2.0, Linux does not do so: if oldpath is a sym‐        bolic link, then newpath is created as a (hard) link to the same symbolic link        file  (i.e.,  newpath  becomes  a  symbolic link to the same file that oldpath        refers to).  Some other implementations behave in the same  manner  as  Linux.        POSIX.1-2008  changes  the  specification of link(), making it implementation-        dependent whether or not oldpath is dereferenced if it  is  a  symbolic  link.        For precise control over the treatment of symbolic links when creating a link,        see linkat(2).  BUGS        On NFS filesystems, the return code may be wrong in case the NFS  server  per‐        forms  the  link  creation and dies before it can say so.  Use stat(2) to find        out if the link got created.  SEE ALSO        ln(1),  linkat(2),  open(2),  rename(2),   stat(2),   symlink(2),   unlink(2),        path_resolution(7), symlink(7)  COLOPHON        This  page is part of release 3.54 of the Linux man-pages project.  A descrip‐        tion of the project, and information about reporting bugs,  can  be  found  at        http://www.kernel.org/doc/man-pages/.    Linux                                 2013-01-27                              LINK(2) chunli@Linux:~$

来自Linux man文档: 主要看这句话:        If  the removed name was the last link to a file and no processes have the file open, the file is deleted        and the space it was using is made available for reuse.  附上全部内容 chunli@Linux:~$ man 3 remove  REMOVE(3)                                   Linux Programmer's Manual                                  REMOVE(3)    NAME        remove - remove a file or directory  SYNOPSIS        #include <stdio.h>         int remove(const char *pathname);  DESCRIPTION        remove() deletes a name from the filesystem.  It calls unlink(2) for files, and rmdir(2) for directories.         If  the removed name was the last link to a file and no processes have the file open, the file is deleted        and the space it was using is made available for reuse.         If the name was the last link to a file, but any processes still have the file open, the file will remain        in existence until the last file descriptor referring to it is closed.         If the name referred to a symbolic link, the link is removed.         If  the  name  referred  to  a socket, FIFO, or device, the name is removed, but processes which have the        object open may continue to use it.  RETURN VALUE        On success, zero is returned.  On error, -1 is returned, and errno is set appropriately.  ERRORS        The errors that occur are those for unlink(2) and rmdir(2).  CONFORMING TO        C89, C99, 4.3BSD, POSIX.1-2001.  NOTES        Under libc4 and libc5, remove() was an alias for unlink(2) (and hence would not remove directories).  BUGS        Infelicities in the protocol underlying NFS can cause the unexpected disappearance  of  files  which  are        still being used.  SEE ALSO        rm(1), unlink(1), link(2), mknod(2), open(2), rename(2), rmdir(2), unlink(2), mkfifo(3), symlink(7)  COLOPHON        This  page  is  part  of  release 3.54 of the Linux man-pages project.  A description of the project, and        information about reporting bugs, can be found at http://www.kernel.org/doc/man-pages/.    GNU                                                2008-12-03                                          REMOVE(3) chunli@Linux:~$


Question: 北邮ACM字符串问题本机没问题，总是WA或者运行时错误

#include <stdio.h> int main(){ 	int m,n,i,j,count,min; 	char a[1008]; 	scanf("%d\n",&m); 	while(m--){ 		gets(a); 		min=9999999; 		for(i=0;a[i]!='\0';i++){ 			count=0; 			for(j=0;a[j]!='\0';j++){ 			   if(a[i]>a[j]) 				   count+=(a[i]-a[j])<(a[j]+26-a[i])?(a[i]-a[j]):(a[j]+26-a[i]);                  if(a[i]<a[j])                       count+=(a[j]-a[i])<(a[i]+26-a[j])?(a[j]-a[i]):(a[i]+26-a[j]); 			} 			if(min>count) 				min=count; 	} 		printf("%d\n",min); 	} 		return 0; 	} 那这样呢？

if(min>count||i==1)  这估计bac就能放倒了


Question: 转跳不到switch语句

定位这样的问题，可以看一下choice的值；如果进不了switch逻辑，很可能是choice的值不是在switch中。 如果choice不是所输入的值，那就向上查看，很可能是上面的输入后的数据进入到choice的内存空间里。

代码功能归根结底不是别人帮自己看或讲解或注释出来的；而是被自己静下心来花足够长的时间和精力亲自动手单步或设断点或对执行到某步获得的中间结果显示或写到日志文件中一步一步分析出来的。 提醒：再牛×的老师也无法代替学生自己领悟和上厕所！ 单步调试和设断点调试（VS IDE中编译连接通过以后，按F10或F11键单步执行，按Shift+F11退出当前函数；在某行按F9设断点后按F5执行停在该断点处。）是程序员必须掌握的技能之一。

楼上说的地方确实有问题，需要改正，而且在最后的时候需要做一次清除缓冲的处理 printf("请输入您的选择：\n"); fflush(stdin); scanf("%d",&choice); 就行了。

for(i=0;i<n;i++) 		scanf("%s%f",name[i],&score[i]);


Question: 求助一个数据结构c语言版的问题

仅供参考：#include <stdio.h> #include <stdlib.h> #include <time.h> unsigned long ulrand(void) {     return (      (((unsigned long)rand()<<24)&0xFF000000ul)     |(((unsigned long)rand()<<12)&0x00FFF000ul)     |(((unsigned long)rand()    )&0x00000FFFul)); } unsigned __int64 ullrand(void) {     return (      (((unsigned __int64)ulrand())<<32)     | ((unsigned __int64)ulrand())); } int i; unsigned long ul; unsigned __int64 ull; void main() {     srand(time(NULL));     for (i=0;i<10;i++) {         ul=ulrand();         printf("%010lu 0x%08x\n",ul,ul);     }     for (i=0;i<10;i++) {         ull=ullrand();         printf("%020I64u 0x%016I64x\n",ull,ull);     } } //3971076432 0xecb1d150 //2433428051 0x910b2a53 //1415415336 0x545d8628 //1312330759 0x4e389407 //1845758378 0x6e0409aa //0008069933 0x007b232d //4202720757 0xfa806df5 //2669855255 0x9f22c217 //0312068736 0x1299ca80 //2084555989 0x7c3fccd5 //03502077880857307931 0x3099e1472040ab1b //16884702393146816355 0xea52835e19b43763 //01877364819396611730 0x1a0dbd5b45f34e92 //07839440151924835771 0x6ccb4948756a05bb //09471412086917299176 0x8371371c820bfbe8 //04411255971577469925 0x3d37edef2f321be5 //13735846279546091130 0xbe9f876a65b7367a //04512980766520059820 0x3ea15418aa9927ac //15821377118299441610 0xdb90d2a9f1bb49ca //15512417228822200185 0xd7472d480398bf79


Question: 杭电OJ1002求大神帮测什么地方有问题

网上找下AC的代码吧。 1.看看你们的输入输出格式是不是一致 2.多测试一些样例

另外这个题目要求输出的数字和加号，等号之间都是有空格的。你的输出结果没有

看下测试的结果


Question: 求助：strcat函数问题

把整个代码已经输入输出贴上来


Question: 水仙数问题，测试数据与实际不符合。输入153本应该为水仙数，可是每位3次方后和为152！求指点！谢谢！

引用 3 楼 jianwen0529 的回复:[quote=引用 2 楼 jianwen0529 的回复:] for(i=0;i<count;i++)     sum=sum+pow(box[i],count); sum = (int)sum + f; // 0.000001 <  f < 0.999998  pow 没有计算整数的重载，估计是精度造成的  或者写一个求整数n次幂的函数  int pown(int x, int y) {     if (y <= 0) return 1;     else if (y == 1) return x;     return x * pown(x, y - 1); }[/quote] 虽然没有整型的pow，但是它的返回值给了一个整形数，它pow返回值会自动被截断为整型的数值。

/*    一个N位数，其各个数位上的数的n次方之和恰好等于原数    测试数据    153，370，371，407，1634，8208，9474；    */  #include <stdio.h> #include <math.h>  int main(void) {     int box[10];     int i = 0, t, num, count = 0, sum = 0;      printf("输入一个正整数：");     scanf("%d", &num);     t = num;     while(num)     {         count++;       //统计位数         box[i] = num % 10; //将num的每一位放入         num /= 10;         i++;     }     //看是几位数     printf("数字位数：%d\n",count);      //看数组里面装的元素     printf("数组存放：");     for(i = 0; i < count; i++)         printf("%d ", box[i]);     putchar('\n');      //看sum的值是否与num相等     for(i = 0; i < count; i++)         sum = sum + pow(box[i], count); //将num存入box[]中的每一位count次方     printf("sum=%d\n",sum);      if(sum == t)         printf("%d是水仙数\n",t);     else         printf("%d不是水仙数\n",t);      return 0; }  你的程序没有问题，请查看一下你的输入是否有问题。你是否将153输入成了152。 程序没问题，我通过了测试验证。153，370，371，407，1634，8208，9474这些通过验证结论都是水仙数。

引用 7 楼 jianwen0529 的回复:[quote=引用 5 楼 cfjtaishan 的回复:] [quote=引用 3 楼 jianwen0529 的回复:] [quote=引用 2 楼 jianwen0529 的回复:] for(i=0;i<count;i++)     sum=sum+pow(box[i],count); sum = (int)sum + f; // 0.000001 <  f < 0.999998  pow 没有计算整数的重载，估计是精度造成的  或者写一个求整数n次幂的函数  int pown(int x, int y) {     if (y <= 0) return 1;     else if (y == 1) return x;     return x * pown(x, y - 1); }[/quote] 虽然没有整型的pow，但是它的返回值给了一个整形数，它pow返回值会自动被截断为整型的数值。[/quote]  所以就是截断的问题，不能保证int转为浮点数的时候精度有差别，比如 1 为 0.999999999... 再转换回int 就成为 0了。 如果他的步骤没有问题，那我只能猜测这方面的原因 更好的是自己提供一个计算整形数的pow[/quote] 整型数据的运算用不到小数部分，并且根据浮点数在内存保存格式，如果整形数较大时，超过了浮点数整数表示的范围就有可能报错了。但纯本问题不会出现越界的。 对于大数据建议你的方案。

引用 5 楼 cfjtaishan 的回复:[quote=引用 3 楼 jianwen0529 的回复:] [quote=引用 2 楼 jianwen0529 的回复:] for(i=0;i<count;i++)     sum=sum+pow(box[i],count); sum = (int)sum + f; // 0.000001 <  f < 0.999998  pow 没有计算整数的重载，估计是精度造成的  或者写一个求整数n次幂的函数  int pown(int x, int y) {     if (y <= 0) return 1;     else if (y == 1) return x;     return x * pown(x, y - 1); }[/quote] 虽然没有整型的pow，但是它的返回值给了一个整形数，它pow返回值会自动被截断为整型的数值。[/quote]  所以就是截断的问题，不能保证int转为浮点数的时候精度有差别，比如 1 为 0.999999999... 再转换回int 就成为 0了。 如果他的步骤没有问题，那我只能猜测这方面的原因 更好的是自己提供一个计算整形数的pow

引用 2 楼 jianwen0529 的回复:for(i=0;i<count;i++)     sum=sum+pow(box[i],count); sum = (int)sum + f; // 0.000001 <  f < 0.999998  pow 没有计算整数的重载，估计是精度造成的  或者写一个求整数n次幂的函数  int pown(int x, int y) {     if (y <= 0) return 1;     else if (y == 1) return x;     return x * pown(x, y - 1); }


Question: 取余计算总是有误差

引用 7 楼 自信男孩的回复:0x75没有问题，正确值是0x75,取余数不是移位。如果想得到低八位的数，不能用取余的办法，可以考虑使用移位的方法（若要取高位）。 y = x & 0xFF; 我取了高八位，用的是y=x/0xff；经过你的提醒，我改成了y=(x>>8)&0xff;多谢

谢谢大家的热心帮助，我都试了一下，发现下面三种方法都是有效的，都可以得到正确的结果  y=x&0xff;  y=(uint8)x;  y=(uint8)(x%256);

0xff是255，你是要对256取余。 uint32 x =0x372; uint8 y = x; //一般强制转换就行了，自动截断，取低字节。 或者y = x & 0xFF;  //按位与

(X & 0x00FFU)

y= x & 0xff;

理解和讨论之前请先学会如何观察！  计算机组成原理→DOS命令→汇编语言→C语言（不包括C++）、代码书写规范→数据结构、编译原理、操作系统→计算机网络、数据库原理、正则表达式→其它语言（包括C++）、架构……  对学习编程者的忠告： 多用小脑和手，少用大脑、眼睛和嘴，会更快地学会编程！ 眼过千遍不如手过一遍！ 书看千行不如手敲一行！ 手敲千行不如单步一行！ 单步源代码千行不如单步Debug版对应汇编一行！ 单步Debug版对应汇编千行不如单步Release版对应汇编一行！ 不会单步Release版对应汇编？在你想单步Release版C/C++代码片断的前面临时加一句DebugBreak();重建所有，然后在IDE中运行。（一般人我不告诉他！）  VC调试时按Alt+8、Alt+7、Alt+6和Alt+5,打开汇编窗口、堆栈窗口、内存窗口和寄存器窗口看每句C对应的汇编、单步执行并观察相应堆栈、内存和寄存器变化，这样过一遍不就啥都明白了吗。 对VC来说，所谓‘调试时’就是编译连接通过以后，按F10或F11键单步执行一步以后的时候，或者在某行按F9设了断点后按F5执行停在该断点处的时候。

写成：y=(uint8)x%0xff; 得到的才是0x72  y=(uint8)(x%0xff); 得到的是0x75


Question: 静态平台类驱动

这是这么指定的用法，那我晓得了~谢谢

新语法，指定成员变量名的初始化。


Question: 求解，怎样用C写一个convertor将C++语法代码转化成C语法代码

引用 4 楼 douqihou7537 的回复:额，这是我们的一个作业，要我们写代码的。我没什么思路，所以上来寻解 全部支持的话工程很大，可以先从简单的开始，只支持部分C++语法。 比如你说的把class换成struct. 下一步class中的函数全部变成全局函数，可以用类名作为新的全局函数的前缀。 新的全局函数增加一个this指针参数，搜索函数实现中的变量，如果是类的成员数据，改成this->xxx

因为是作业，也有时间限制，所以不是说将所有的C++代码转换成C代码，满足一定要求即可

额，这是我们的一个作业，要我们写代码的。我没什么思路，所以上来寻解

1楼正确。C++最初就是先编译成C然后再编译的

楼主，这个工程很浩大啊！！！！

cfront


Question: 求大神相助

我排完序了却不知道怎样把学生和他的名词联系起来，就是怎么查询他的名次

名次的计算水很深。

求单门课程的平均成绩：遍历所有学生，然后累加，然后除以学生数 求每门课程的平均成绩并排序：排序可以用冒泡 求某一个人在班级的名次：排完序的学生，求一个人的名次想必就简单了吧？

void main() { 	 	int choice; 	while(1) 	{ 		system("color 7D"); 		/*主菜单*/ 		printf("\n\t\t*****学生成绩管理系统*****\n"); 		printf("\t\t*\t		1.录入成绩\t\t *\n");		 		printf("\t\t*\t		2.保存成绩\t\t *\n"); 		printf("\t\t*\t		3.修改成绩\t\t *\n"); 		printf("\t\t*\t		4.删除成绩\t\t *\n"); 		printf("\t\t*\t		5.学生查询平均成绩\t *\n"); 		printf("\t\t*\t		6.排序\t\t\t *\n"); 		printf("\t\t*\t		7.单门课程平均成绩\t *\n"); 		printf("\t\t*\t		8.学生名次查询\t\t *\n");		 		printf("\t\t*\t		0.退出\t\t\t *\n"); 		printf("\t\t**********●0●*********\n\n"); 		printf("请选择您要执行的操作(0-10):"); 		scanf("%d",&choice); 		getchar(); 		switch(choice) 		{ 		case 1: 			Student_Input(); 			break; 		case 2: 			Save();//Student_Display(); 			break; 		case 3: 			Student_Modify();//Student_Add(); 			break; 		case 4: 			Student_Delete();//Student_Insert();Student_Display();			 			break; 		case 5: 			Student_aver_Select(); 			break; 		case 6: 			Student_Sort(); 			 			break; 		case 7: 			//Student_Select(); 			break; 		case 8: 			Search(); 			break; 		case 0: 			printf("\n操作结束,再见！\n"); 			exit(0); 			break; 		default: 			printf("\n输入错误！请重新输入！\n"); 		} 	} }


Question: C调用python出错 undefined reference to `_imp__Py_Initialize'

引用 5 楼 赵4老师 的回复:不要做A语言代码修改为B语言代码的无用功。 也不要做用A语言代码直接调用B语言代码库这样复杂、这样容易出错的傻事。 只需让A、B语言代码的输入输出重定向到文本文件，或修改A、B语言代码让其通过文本文件输入输出。 即可很方便地让A、B两种语言之间协调工作。 比如： A将请求数据写到文件a.txt，写完后改名为aa.txt B发现aa.txt存在时，读取其内容，调用相应功能，将结果写到文件b.txt，写完后删除aa.txt，改名为bb.txt A发现bb.txt存在时，读取其内容，读完后删除bb.txt 以上A可以替换为任何一种开发语言或开发环境，B可以替换为任何一种与A不同的开发语言或开发环境。 除非A或B不支持判断文件是否存在、文件读写和文件更名。 但是谁又能举出不支持判断文件是否存在、文件读写和文件更名的开发语言或开发环境呢？ 可以将临时文件放在RamDisk上提高效率减少磨损磁盘。 数据的结构很复杂的话，文本文件的格式问题可参考json或xml  共享临时文本文件这种进程之间的通讯方法相比其它方法的优点有很多，下面仅列出我现在能想到的： ·进程之间松耦合 ·进程可在同一台机器上，也可跨机，跨操作系统，跨硬件平台，甚至跨国。 ·方便调试和监视，只需让第三方或人工查看该临时文本文件即可。 ·方便在线开关服务，只需删除或创建该临时文本文件即可。 ·方便实现分布式和负载均衡。 ·方便队列化提供服务，而且几乎不可能发生队列满的情况（除非硬盘空间满） ·……  “跨语言、跨机，跨操作系统，跨硬件平台，跨国，跨*.*的”苦海无边， 回头是“使用共享纯文本文件进行信息交流”的岸！ 再不济也是用socket啊，怎么会用文件这种影响io的操作。。。

引用 19 楼 赵4老师 的回复:不要迷信书、考题、老师、回帖； 要迷信CPU、编译器、调试器、运行结果。 并请结合“盲人摸太阳”和“驾船出海时一定只带一个指南针。”加以理解。 任何理论、权威、传说、真理、标准、解释、想象、知识……都比不上摆在眼前的事实！  理解和讨论之前请先学会如何观察！领教了，谢谢

引用 16 楼 赵4老师 的回复:[quote=引用 15 楼 青春不言败(WuChW) 的回复:] [quote=引用 5 楼 赵4老师 的回复:] 不要做A语言代码修改为B语言代码的无用功。 也不要做用A语言代码直接调用B语言代码库这样复杂、这样容易出错的傻事。 只需让A、B语言代码的输入输出重定向到文本文件，或修改A、B语言代码让其通过文本文件输入输出。 即可很方便地让A、B两种语言之间协调工作。 比如： A将请求数据写到文件a.txt，写完后改名为aa.txt B发现aa.txt存在时，读取其内容，调用相应功能，将结果写到文件b.txt，写完后删除aa.txt，改名为bb.txt A发现bb.txt存在时，读取其内容，读完后删除bb.txt 以上A可以替换为任何一种开发语言或开发环境，B可以替换为任何一种与A不同的开发语言或开发环境。 除非A或B不支持判断文件是否存在、文件读写和文件更名。 但是谁又能举出不支持判断文件是否存在、文件读写和文件更名的开发语言或开发环境呢？ 可以将临时文件放在RamDisk上提高效率减少磨损磁盘。 数据的结构很复杂的话，文本文件的格式问题可参考json或xml  共享临时文本文件这种进程之间的通讯方法相比其它方法的优点有很多，下面仅列出我现在能想到的： ·进程之间松耦合 ·进程可在同一台机器上，也可跨机，跨操作系统，跨硬件平台，甚至跨国。 ·方便调试和监视，只需让第三方或人工查看该临时文本文件即可。 ·方便在线开关服务，只需删除或创建该临时文本文件即可。 ·方便实现分布式和负载均衡。 ·方便队列化提供服务，而且几乎不可能发生队列满的情况（除非硬盘空间满） ·……  “跨语言、跨机，跨操作系统，跨硬件平台，跨国，跨*.*的”苦海无边， 回头是“使用共享纯文本文件进行信息交流”的岸！这样确实能够省去这些麻烦，但是会占用大量的CPU，必须得有一个程序一直循环检查是否存在这个文件，很浪费资源啊。[/quote] 那只是因为你不会使用ReadDirectoryChangesW，FindFirstChangeNotification 而已罢了。 [/quote] 这两个函数的底层是什么样的啊，看了一下介绍，两个都是windows上的函数。并且它介绍里是说监控，如果不是中断方式来通知文件变化的话，监控还是循环等待喽。linux上有没有类似的函数啊。我的一个想法是把被调用函数编译后作为外部程序，主调函数进行外部函数调用，被调用的函数将执行结果放在文件中，主调函数调用完毕以后，去查看产生的文件，这样就可以免去监控文件状态的消耗。

引用 15 楼 青春不言败(WuChW) 的回复:[quote=引用 5 楼 赵4老师 的回复:] 不要做A语言代码修改为B语言代码的无用功。 也不要做用A语言代码直接调用B语言代码库这样复杂、这样容易出错的傻事。 只需让A、B语言代码的输入输出重定向到文本文件，或修改A、B语言代码让其通过文本文件输入输出。 即可很方便地让A、B两种语言之间协调工作。 比如： A将请求数据写到文件a.txt，写完后改名为aa.txt B发现aa.txt存在时，读取其内容，调用相应功能，将结果写到文件b.txt，写完后删除aa.txt，改名为bb.txt A发现bb.txt存在时，读取其内容，读完后删除bb.txt 以上A可以替换为任何一种开发语言或开发环境，B可以替换为任何一种与A不同的开发语言或开发环境。 除非A或B不支持判断文件是否存在、文件读写和文件更名。 但是谁又能举出不支持判断文件是否存在、文件读写和文件更名的开发语言或开发环境呢？ 可以将临时文件放在RamDisk上提高效率减少磨损磁盘。 数据的结构很复杂的话，文本文件的格式问题可参考json或xml  共享临时文本文件这种进程之间的通讯方法相比其它方法的优点有很多，下面仅列出我现在能想到的： ·进程之间松耦合 ·进程可在同一台机器上，也可跨机，跨操作系统，跨硬件平台，甚至跨国。 ·方便调试和监视，只需让第三方或人工查看该临时文本文件即可。 ·方便在线开关服务，只需删除或创建该临时文本文件即可。 ·方便实现分布式和负载均衡。 ·方便队列化提供服务，而且几乎不可能发生队列满的情况（除非硬盘空间满） ·……  “跨语言、跨机，跨操作系统，跨硬件平台，跨国，跨*.*的”苦海无边， 回头是“使用共享纯文本文件进行信息交流”的岸！这样确实能够省去这些麻烦，但是会占用大量的CPU，必须得有一个程序一直循环检查是否存在这个文件，很浪费资源啊。[/quote] 那只是因为你不会使用ReadDirectoryChangesW，FindFirstChangeNotification 而已罢了。

你没有调查研究，怎么就武断“监控还是循环等待喽。linux上有没有类似的函数啊。”了呢？ 无知者无畏！  无profiler不要谈效率！！尤其在这个云计算、虚拟机、模拟器、CUDA、多核 、多级cache、指令流水线、多种存储介质、……满天飞的时代！

引用 5 楼 赵4老师 的回复:不要做A语言代码修改为B语言代码的无用功。 也不要做用A语言代码直接调用B语言代码库这样复杂、这样容易出错的傻事。 只需让A、B语言代码的输入输出重定向到文本文件，或修改A、B语言代码让其通过文本文件输入输出。 即可很方便地让A、B两种语言之间协调工作。 比如： A将请求数据写到文件a.txt，写完后改名为aa.txt B发现aa.txt存在时，读取其内容，调用相应功能，将结果写到文件b.txt，写完后删除aa.txt，改名为bb.txt A发现bb.txt存在时，读取其内容，读完后删除bb.txt 以上A可以替换为任何一种开发语言或开发环境，B可以替换为任何一种与A不同的开发语言或开发环境。 除非A或B不支持判断文件是否存在、文件读写和文件更名。 但是谁又能举出不支持判断文件是否存在、文件读写和文件更名的开发语言或开发环境呢？ 可以将临时文件放在RamDisk上提高效率减少磨损磁盘。 数据的结构很复杂的话，文本文件的格式问题可参考json或xml  共享临时文本文件这种进程之间的通讯方法相比其它方法的优点有很多，下面仅列出我现在能想到的： ·进程之间松耦合 ·进程可在同一台机器上，也可跨机，跨操作系统，跨硬件平台，甚至跨国。 ·方便调试和监视，只需让第三方或人工查看该临时文本文件即可。 ·方便在线开关服务，只需删除或创建该临时文本文件即可。 ·方便实现分布式和负载均衡。 ·方便队列化提供服务，而且几乎不可能发生队列满的情况（除非硬盘空间满） ·……  “跨语言、跨机，跨操作系统，跨硬件平台，跨国，跨*.*的”苦海无边， 回头是“使用共享纯文本文件进行信息交流”的岸！这样确实能够省去这些麻烦，但是会占用大量的CPU，必须得有一个程序一直循环检查是否存在这个文件，很浪费资源啊。

我也遇到了相同的问题，请问楼主是怎么解决的呀？

引用 10 楼 user-6 的回复:没有 mingw , gcc 和 .a 的 32/64 匹配吗什么意思

编译的时候，把对应的lib文件链接上

-lpython27  试试

引用 6 楼 user-6 的回复:找找你的 d soft python2 libs 下有扩展名是 .a 的吗 有的，libpython27.a

找找你的 d soft python2 libs 下有扩展名是 .a 的吗

引用 3 楼 user-6 的回复:windows 下用 gcc 要连接 libpython27.a好像不行啊，请问是哪里错了吗。路径没有问题的

windows 下用 gcc 要连接 libpython27.a

引用 1 楼 jianwen0529 的回复:编译的时候，把对应的lib文件链接上是这样吗？我不是太懂makefile这块。但是这样也不对

没有 mingw , gcc 和 .a 的 32/64 匹配吗

引用 8 楼 user-6 的回复:-lpython27  试试 原帖中使用的就是-lpython27 不行的


Question: 学生信息管理的文件修改函数，拜托拜托，在线等

将旧的文件删掉。 在fwrite前面加一句rewind(pf_modify);

引用 5 楼 赵4老师的回复:将旧的文件删掉。 在fwrite前面加一句rewind(pf_modify); 天呐老师真的是太太太太太厉害了，一句话就解决我4天都找不出的问题。

引用 3 楼 Potato_Lyy 的回复:[quote=引用 2 楼 jianwen0529 的回复:] 写前重新定位下读写位置？ fseek 试过了没有用。。。[/quote]  那更一了百了的方式：分开读写

引用 2 楼 jianwen0529 的回复:写前重新定位下读写位置？ fseek 试过了没有用。。。

写前重新定位下读写位置？ fseek

所谓修改删除文件a某位置的内容，其实是读打开文件a，再将‘a中修改删除位置之前的内容＋修改删除的内容＋a中修改删除位置之后的内容’保存到文件b，关闭文件a，删除文件a，将文件b改名为与之前文件a相同的名字，仅此而已。http://bbs.csdn.net/topics/391975224


Question: 求一个概率问题

如果G抽到红球的概率为80%，那么G抽到红球的概率是80%

引用 9 楼 fefe82 的回复:A和B抽同时中(红球或蓝球)的概率为80%  同时红和同时蓝都是 80% ，加一起就已经 160% ...  一红一篮的概率是负的？.... 确实是...

引用 8 楼 zilaishuichina 的回复:请先练习如何把题目描述清楚  你描述的是：A和B抽同时中(红球或蓝球)的概率为80%  即2种情况：  A和B同时中红球的概率为80%，在一次测试中B抽中蓝球，求A抽中红球的概率  A和B同时中蓝球的概率为80%，在一次测试中B抽中蓝球，求A抽中红球的概率  见下图  确实是...

引用 8 楼 zilaishuichina 的回复:请先练习如何把题目描述清楚  你描述的是：A和B抽同时中(红球或蓝球)的概率为80%  即2种情况：  A和B同时中红球的概率为80%，在一次测试中B抽中蓝球，求A抽中红球的概率  A和B同时中蓝球的概率为80%，在一次测试中B抽中蓝球，求A抽中红球的概率  见下图  很矛盾，如楼上所说的，是不是我的问题有问题...

《概率论与数理统计》

引用 1 楼 fefe82 的回复:如果G抽到红球的概率为80%，那么G抽到红球的概率是80% A和B抽同时中(红球或蓝球)的概率为80% A和C同上 A和D同上 A和E同上  在一次测试中 B抽中蓝球 C抽中蓝球 D抽中蓝球 E抽中红球 求A抽中红球的概率

引用 3 楼 zilaishuichina 的回复:仅从lz的描述  如果x，则y 是不能反推： 如果y，则x  如果G抽到红球的概率为80%，那么A、B、C、D抽到的红球概率也是80%。 是不能反推出 ：  如果A、B、C、D抽到的红球概率是x%， 则G抽到红球的概率为y%  因此，如果一次测试中A抽到红球、B抽到红球、C抽到蓝球、D抽到蓝球， 跟G有半毛钱关系啊 谢谢回答！可能我的问题没有描述清楚，我再尝试描述一次吧: A和B抽同时中(红球或蓝球)的概率为80% A和C同上 A和D同上 A和E同上  在一次测试中 B抽中蓝球 C抽中蓝球 D抽中蓝球 E抽中红球 求A抽中红球的概率

你自己都说了80%，那就80%呗


Question: C的线程池原理 进程池原理 多路io原理和优化

搜“毛德操 进程管理 线程调度”

一般如果涉及到线程处理较慢或者线程里要处理大量的io读写操作时，这时我们引入线程池的方式来统一管理线程，线程池说白了就是控制线程并发数量，防止程序阻塞，上学时肯定学过游泳池放水排水的问题，自己查查资料不难理解。  通俗的说就是很多线程同时处理较慢的数据时，往往容易造成系统自动分配时间分配的不好，这样，我们就通过线程池控制同时执行的线程数量，并控制顺序，让系统干不了的事我们自己来干  进程池类似于线程池，不同的是管理的进程而已。  多路io复用，说白了也是为了优化操作系统本身的不足。  总之就一句话，以上这些东西，没啥道道，主要是为了让程序更稳定，处理速度更快（不受系统缺陷的影响）


Question: 这个C++我编译出错 但是我不知道该怎么改 各位大神教教我

感觉你这代码哪里抄来的，WinSunProc函数第2第3个case名字不对

将错误拿去搜索

贴错误代码  感觉你这是因为字符编码的问题  如果是这样子，你在所有显示字符串前加L宏 比如 wndcls.lpszClassName=L"xiahezhuang Game";


Question: 分治求最大连续和。。。（当输入数据全是0 的时候 上下界的输出就不对了），求大神

数组下标最好从0开始

代码功能归根结底不是别人帮自己看或讲解或注释出来的；而是被自己静下心来花足够长的时间和精力亲自动手单步或设断点或对执行到某步获得的中间结果显示或写到日志文件中一步一步分析出来的。 提醒：再牛×的老师也无法代替学生自己领悟和上厕所！ 单步调试和设断点调试（VS IDE中编译连接通过以后，按F10或F11键单步执行，按Shift+F11退出当前函数；在某行按F9设断点后按F5执行停在该断点处。）是程序员必须掌握的技能之一。


Question: C语言基础，编译多重文件，文件包含问题

引用 6 楼 ipqtjmqj 的回复:[quote=引用 4 楼 qq_15623245 的回复:] [quote=引用 3 楼 ipqtjmqj 的回复:] 你没编译show.c当然找不到了。 编译命令改成  gcc -o main main.c show.c 感谢！这个真的可行！ 有没有方法不用gcc -o  main main.c  show.c, 直接使用gcc -o main main.c[/quote] 那要分几条指令了 gcc -c main.c gcc -c show.c gcc -o main main.o show.o  觉得太长的话，可以存到一个shell脚本里，或者写个Makefile[/quote] 感谢！我愚钝了，make用的多！却没自个写好好写过makefile，忘了基本的编译流程。。。

引用 4 楼 qq_15623245 的回复:[quote=引用 3 楼 ipqtjmqj 的回复:] 你没编译show.c当然找不到了。 编译命令改成  gcc -o main main.c show.c 感谢！这个真的可行！ 有没有方法不用gcc -o  main main.c  show.c, 直接使用gcc -o main main.c[/quote] 那要分几条指令了 gcc -c main.c gcc -c show.c gcc -o main main.o show.o  觉得太长的话，可以存到一个shell脚本里，或者写个Makefile

还有一个问题是 我在test.h 中定义了一个全局变量int info_count，在show.c 和main.c中使用有以下问题 /tmp/cce6Jr5W.o:(.bss+0x0): multiple definition of `info_count' /tmp/ccgVGa1h.o:(.bss+0x0): first defined here

引用 3 楼 ipqtjmqj 的回复:你没编译show.c当然找不到了。 编译命令改成  gcc -o main main.c show.c 感谢！这个真的可行！ 有没有方法不用gcc -o  main main.c  show.c, 直接使用gcc -o main main.c

意思是将.c 改成.cpp,gcc改成g++？ 结果还是一样，找不到show（）

不把show.c变进去，程序是找不到show函数的。 编译是第一步，链接是第二步； 第一步只是检查语法错误，生成.o文件，第二步链接，将.o文件合到可执行文件。 gcc -Wall main.c show.c其实是包含编译和链接两步的。

改成cpp试试，或者就直接包含.c文件


Question: 稳定状态为小幅度波动时的判断算法

简单一点阈值？

搜“低通滤波”？


Question: 大一难度的链表初级的链表反转

谢了，这个我看看，理解一下

链表反转是很多笔试面试常考之题，既然这么常见那就好好研究下。其实链表反转方法很多，主要有一下几种办法： 1、重建新链表，使用头插法将原链表元素放入，时空复杂度较大，同时如果加入“就地逆序不新建”等限制条件，该算法便不可用； 2、堆栈法：将原链表元素依序push如堆栈中，然后再pop入新链表中，时空复杂度依然过大，但是思路不错； 3、修正的头插法： 对方法1的头插法进行改进，不插入新建列表中，而是插入已置空的当然链表中，只修改各节点的next指向，时间复杂度只有O(n)。是较为完美的解决方案。 总结：其实还存在一些变形的算法，比如笔者刚开始开始自制了一种类似头插法的算法，不过需要增加一个零时指针保存当前指针在原链表中的next节点，时间复杂度同算法3是相同的，但是在参考了一些数据结构书后发现这三种算法相对思路更加清晰更“规范”些。尤其是算法三。  有了以上讨论，写出反转链表的算法就很容易了，以下是算法3的C语言实现：  #include <stdio.h> #include <stdlib.h>  #define LINK_LENGTH 15  typedef struct _Node {     int data;     struct _Node *next; }Node, *NodePtr;  void CreateLinklist(NodePtr pHead) {     NodePtr pPrev, pCurr;     int i = 0;     pPrev = pHead;     for(i = 0; i < LINK_LENGTH; i++)     {         pCurr = (NodePtr)malloc(sizeof(Node));         pCurr->data = i + 1;         pCurr->next = NULL;         pPrev->next = pCurr;         pPrev = pCurr;     } }  void ReverseLinklist(NodePtr pHead) {     NodePtr pCurr, pTmp;      pCurr = pHead->next;     pHead->next = NULL; // Empty the original linklist     while(pCurr != NULL)     {         pTmp = pCurr->next;         // Insert to head         pCurr->next = pHead->next;         pHead->next = pCurr;         pCurr = pTmp;     } }  void PrintLinklist(NodePtr pHead) {     NodePtr pCurr = pHead->next;      while(pCurr != NULL)     {         printf("%d ", pCurr->data);         pCurr = pCurr->next;     }     printf("\n"); }  int main() {     NodePtr pHead = NULL;     pHead = (NodePtr)malloc(sizeof(Node));     pHead->data = -1;   // Head always not in real linklist.     pHead->next = NULL;     CreateLinklist(pHead);      printf("Original Linklist: ");     PrintLinklist(pHead);      // Reverse     ReverseLinklist(pHead);     printf("Reversed Linklist: ");     PrintLinklist(pHead);      system("pause");     return 0; }

循环以下两个步骤： struct node *next;翻转，再把（头部节点的前一个节点） next 和 （尾部节点） next Address 是一个道理，调换（每个节点的前后值），再交换 （头部节点后值） 和（ 尾部节点的前值）

再供参考：//不带表头结点的单向链表 #include <stdio.h> #include <stdlib.h> #include <malloc.h> #include <time.h> #include <locale.h> struct NODE {     int          data;     struct NODE *next; } *head,*p,*q,*s,*p1,*p2,*q1,**ta; int i,k,n,t,m,v,N=10; int main() {     setlocale(LC_ALL,"chs");     srand(time(NULL));      head=NULL;      printf("创建%d个节点的单链表:",N);//创建N个节点的单链表     p=head;     for (i=0;i<N;i++) {         q=(struct NODE *)malloc(sizeof(struct NODE));         if (NULL==q) exit(1);         q->data=rand()%100;//填写0..99的随机值         q->next=NULL;         if (NULL==p) {             head=q;             p=head;         } else {             p->next=q;             p=q;         }     }      //输出整个单链表     s=head;     while (1) {         if (NULL==s) {             printf("\n");             break;         }         printf("%02d->",s->data);         s=s->next;     }      k=3;     v=5;     printf("将值为%d的结点插入到单链表的第%d个结点前:",v,k);//将值为v的结点插入到单链表的第k个结点前     n=0;     p=head;     while (1) {         if (NULL==p) {             break;         }         n++;         if (k==1) {             q=(struct NODE *)malloc(sizeof(struct NODE));             if (NULL==q) exit(1);             q->data=v;             q->next=head;             head=q;             break;         } else {             if (k-1==n) {                 q=(struct NODE *)malloc(sizeof(struct NODE));                 if (NULL==q) exit(1);                 q->data=v;                 q->next=p->next;                 p->next=q;                 break;             }         }         p=p->next;     }      //输出整个单链表     s=head;     while (1) {         if (NULL==s) {             printf("\n");             break;         }         printf("%02d->",s->data);         s=s->next;     }      k=5;     printf("删除第%d个节点:",k);//删除第k个节点     n=0;     p=head;     while (1) {         if (NULL==p) {             break;         }         n++;         if (k==1) {             q=head;             head=head->next;             free(q);             break;         } else {             if (k-1==n) {                 q=p->next;                 if (q) {                     p->next=q->next;                     free(q);                 }                 break;             }         }         p=p->next;     }      //输出整个单链表     s=head;     while (1) {         if (NULL==s) {             printf("\n");             break;         }         printf("%02d->",s->data);         s=s->next;     }      printf("从小到大排序:");//从小到大排序     for (p=head,p1=NULL;p!=NULL;p1=p,p=p->next) {         for (q=p->next,q1=p;q!=NULL;q1=q,q=q->next) {             if (p->data > q->data) {                  //交换data //              printf("swap %02d %02d\n",p->data,q->data); //              t=p->data;p->data=q->data;q->data=t;                  //或者                  //交换next //              printf("swap %02d %02d\n",p->data,q->data);                 if (p==head) {//p是头                     if (p->next==q) {//pq挨着                         head=q;                         p->next=q->next;                         q->next=p;                         q=p;                         p=head;                     } else {//pq不挨着                         head=q;                         p2=p->next;                         p->next=q->next;                         q->next=p2;                         q1->next=p;                         q=p;                         p=head;                     }                 } else {//p不是头                     if (p->next==q) {//pq挨着                         p1->next=q;                         p->next=q->next;                         q->next=p;                         q=p;                         p=p1->next;                     } else {//pq不挨着                         p1->next=q;                         p2=p->next;                         p->next=q->next;                         q->next=p2;                         q1->next=p;                         q=p;                         p=p1->next;                     }                 }                  //输出整个单链表 //              s=head; //              while (1) { //                  if (NULL==s) { //                      printf("\n"); //                      break; //                  } //                  printf("%02d->",s->data); //                  s=s->next; //              } //              getchar();             }         }     }      //输出整个单链表并计算链表长度n     n=0;     s=head;     while (1) {         if (NULL==s) {             printf("\n");             break;         }         printf("%02d->",s->data);         n++;         s=s->next;     }      printf("将整个链表逆序:");//将整个链表逆序     if (n>=2) {         p=head;         q=p->next;         p->next=NULL;         while (1) {             q1=q->next;             q->next=p;             p=q;             q=q1;             if (NULL==q) break;         }         head=p;     }      //输出整个单链表     s=head;     while (1) {         if (NULL==s) {             printf("\n");             break;         }         printf("%02d->",s->data);         s=s->next;     }      m=4;     n=6;     printf("将单链表中前%d个结点和后%d个结点进行互换:",m,n);//将单链表中前m个结点和后n个结点进行互换,m+n为链表总长     k=0;     p=head;     while (1) {         if (NULL==p) {             break;         }         k++;         if (m==k) {             q=p;         }         s=p;         p=p->next;     }     q1=head;     head=q->next;     s->next=q1;     q->next=NULL;      //输出整个单链表     s=head;     while (1) {         if (NULL==s) {             printf("\n");             break;         }         printf("%02d->",s->data);         s=s->next;     }      //释放所有节点     p=head;     while (1) {         if (NULL==p) {             break;         }         q=p->next;         free(p);         p=q;     }      return 0; } //创建10个节点的单链表:08->74->07->23->03->99->31->56->88->16-> //将值为5的结点插入到单链表的第3个结点前:08->74->05->07->23->03->99->31->56->88->16-> //删除第5个节点:08->74->05->07->03->99->31->56->88->16-> //从小到大排序:03->05->07->08->16->31->56->74->88->99-> //将整个链表逆序:99->88->74->56->31->16->08->07->05->03-> //将单链表中前4个结点和后6个结点进行互换:31->16->08->07->05->03->99->88->74->56-> //

仅供参考：//带表头结点的单向链表 #include <stdio.h> #include <stdlib.h> #include <malloc.h> #include <time.h> struct NODE {     int          data;     struct NODE *next; } H,*head,*p,*q,*q1,*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;     }      //将整个链表逆序     if (head->next!=NULL && head->next->next!=NULL) {         p=head->next;         q=p->next;         p->next=NULL;         while (1) {             q1=q->next;             q->next=p;             p=q;             q=q1;             if (NULL==q) break;         }         head->next=p;     }      //输出整个单链表     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; } //84->28->20->23->96->19->59->97->29->41-> //84->28->05->20->23->96->19->59->97->29->41-> //84->28->05->20->96->19->59->97->29->41-> //05->19->20->28->29->41->59->84->96->97-> //97->96->84->59->41->29->28->20->19->05-> //41->29->28->20->19->05->97->96->84->59-> //


Question: 枚举变量赋值问题

因为你加了__attribute__((packed))，导致sizeof(ptp_bool)是1。

引用 4 楼 laoqiuge 的回复:援引二楼，不错我用了memset(a,1,64*sizeof(ptp_bool));但是a只占用一个字节，我怎么会同时对四个字节赋值呢？  你的TRUE与FALSE类型是int，如果要char，要写成：enum xxx :  char  另参看：  http://en.cppreference.com/w/cpp/language/enum

printf里面的%和变量的一一对应关系 scanf里面的%和变量以及变量前加不加&的一一对应关系 是C代码中非常容易出错的地方，而且通常编译还不出错。 所以在编译源代码之前值得专门仔细检查一遍甚至多遍。

我知道了是我用输出类型%d的原因

引用 4 楼 laoqiuge 的回复:援引二楼，不错我用了memset(a,1,64*sizeof(ptp_bool));但是a只占用一个字节，我怎么会同时对四个字节赋值呢？  你得把 sizeof(ptp_bool) 打出来看看。  还有，你得去重新看看 memset 的文档。

引用 1 楼 jianwen0529 的回复:bool 当 0 表示false，非0值为 true 大多数编译器false转int为0，true 为 1（不一定，可以自行决定具体的表现）  C 没有 bool ,之后 _Bool （从哪个版本加上的记不得了，C11 已经有了），用来保存两个值，0 和 1 。  stdbool.h 里定义了 #define bool _Bool #define true 1 #define false 0

printf的时候用了%d，应该没有正确对应enum的输出类型

引用 楼主 laoqiuge 的回复:枚举变量在定义好之后，如果对这个变量赋值不是只能取已经定义好的值吗？比如说，我定义这样一个枚举变量 typedef enum {    FALSE = 0,    TRUE  = 1, }__attribute__((packed)) ptp_bool;  ptp_bool a[24]; 那么a[0-23]不是只可以取值0或者1吗？但是我给赋值2或者3之类的合法值也是可以赋上的，不知道什么原因？ 而且赋值为1的时候打印结果却不是1，qt下编译是16843009？ （ps:第二个问题值不对感觉很奇怪）  1. C 标准下 enum type 大小至少是一个 sizeof(char) 。在用非 enum constant 给 enum 变量赋值的时候，标准允许给 warning , 但是这不是一个强制要求。  2. 不知道你是怎么输出的。    比如：printf 输出的时候，%d 一类格式控制符需求的类型与给出的类型不一致的时候，是一个 UB (可能得到任何结果）。    printf 没有用于输出 enum 的格式控制符，所以必须手工转换。

16843009，即0x01010101，你是不是用什么函数给变量赋值了，比如memset(a, 1, sizeof(a));


Question: 刚自学的C语言 自己编了个程序,可是很多错误,求解释...

引用 2 楼 幻夢之葉的回复: #include<stdlib.h> #include<stdio.h> #include <string.h>  struct student_st {     int num;     char name[20];     int score1;     int score2;     int score3;     float average; };  void CopyStudent(student_st &dst, const student_st &src) {     dst = src;     strcpy(dst.name, src.name); }  void createstudent(struct student_st *stu) {     int i, j;     float average;     for (i = 0; i < 3; i++)     {         printf("enter student %d\n", i + 1);         printf("学号为:");         scanf("%d", &stu[i].num);         printf("姓名是:");         scanf("%s", stu[i].name);         printf("第1门成绩是:");         scanf("%d", &stu[i].score1);         printf("第2门成绩是:");         scanf("%d", &stu[i].score2);         printf("第3门成绩是:");         scanf("%d", &stu[i].score3);         printf("\n");         stu[i].average = (stu[i].score1 + stu[i].score2 + stu[i].score3) / 3.0f;     } }  void sortstudent(struct student_st *stu, int c)  {     int i, j, max;     struct student_st temp;     for (i = 0; i < c; i++)     {         max = i;         for (j = i + 1; j < c; j++)         {             if (stu[j].average > stu[max].average)                 max = j;         }         if (max != i)         {             CopyStudent(temp, stu[max]);             CopyStudent(stu[max], stu[i]);             CopyStudent(stu[i], temp);         }     } }  int main() {     int i;     struct student_st stu[3];     createstudent(stu);     sortstudent(stu, 3);     printf("id\tname\tscore1\tscore2\tscore3\taverage\n");     for (i = 0; i < 3; i++)     {         printf("%d %s %d %d %d %0.1f", stu[i].num, stu[i].name, stu[i].score1, stu[i].score2, stu[i].score3, stu[i].average);         printf("\n");     } }  膜拜  大神  回去好好看看

引用 3 楼 小灸舞的回复:1.形参名应该是stu，类型应该是struct student_st *stu 2.主函数里struct student_st stu;struct student_st stu[3];2个都叫stu? 3.createstudent函数里score1都写成了Score1 PS：自己根据编译器错误改改并不是很难 OK  谢谢 大神 唉 英语比较烂 看不怎么懂

主函数中的stu是个局部变量，仅在主函数中可用，其他函数中的stu是没有定义过的


Question: 麻烦大家帮我看看这个问题！

能否麻烦以上两位从运行时的初始化给我讲一下！

“变量赋值”和“变量初始化”不是一回事！ “变量赋值”发生在运行期，其写法遵循赋值语法规定。 “变量初始化”发生在编译期或运行期，其写法遵循初始化列表语法规定。

用{}只有定义的时候才可以那样写（定义的时候初始化） 之后只能用strcpy来赋值

你的name是一个字符数组，要用strcpy赋值

strcpy


Question: 关于VS2013下的Debug Assertion Failed

引用 7 楼 LOSWind 的回复:[quote=引用 1 楼 paschen 的回复:] int compare_num = compare(input_num, rand_num[4]);  改成：  int compare_num = compare(input_num, rand_num); 为什么要这样改，好像用数组做实参是可以的吧？[/quote]   rand_num[4] 只是数组的第5个元素，而且这个元素还越界了

请那些喜欢将数组作为函数参数传来传去或作为函数返回值的码农思考一下为什么不把整个互联网内容当作函数参数传来传去或作为函数返回值呢？

弹出的错误意思是，表达式c（char类型？）的值应位于[-1，255]之间

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

你这个judge函数写的不对，比如我输入5621 它直接就isalpha(judge_num)也就是isalpha(5621)就出现那个错误了 这个isalpha要一个个字符判断才行

引用 1 楼 paschen 的回复:int compare_num = compare(input_num, rand_num[4]);  改成：  int compare_num = compare(input_num, rand_num); 为什么要这样改，好像用数组做实参是可以的吧？

引用 2 楼 jianwen0529 的回复:不是告诉你那个文件第几行，是c 的问题么没有定义c啊，56行是i和j

引用 1 楼 paschen 的回复:int compare_num = compare(input_num, rand_num[4]);  改成：  int compare_num = compare(input_num, rand_num);试了，一样

不是告诉你那个文件第几行，是c 的问题么


Question: 着急！菜鸟有关链表的小问题

引用 1楼user-1 的回复:恕我直言，写的不是一点点的小问题，首先在函数部分，在结构体没有用别名的情况下声明结构体类型应该要加上struct，其次，下面的链表构建完全不是一个画风的，准确来说很难猜到您要表达的意思，首先，while后面的判断，在您申请的头节点，存储下一个节点地址的next应该就是NULL，其次，在循环中的节点构建此时已经不是头节点了，tail已经单独的成为了一个新的节点，和head没有任何关系了。 以上回答如有发现有问题的，麻烦指出来，相互学习！谢谢！谢谢了，我是初学者，听取了您的意见现在已经改好了。


Question: 求大神帮忙看一下，实在改不出来。

引用 1 楼 user-1 的回复:错误表现是什么？错的地方已经改正了，谢谢你的关注。

错误表现是什么？


Question: 关于 指针和数组的初始化问题

向http://bbs.csdn.net/topics/392077960的btz201601学习。

引用 17 楼 zhao4zhong1 的回复:[quote=引用 16 楼 songjiajia 的回复:] [quote=引用 14 楼 zhao4zhong1 的回复:] 计算机组成原理→DOS命令→汇编语言→C语言（不包括C++）、代码书写规范→数据结构、编译原理、操作系统→计算机网络、数据库原理、正则表达式→其它语言（包括C++）、架构…… 赵老师 13楼的问题帮回答下吧 有点不解！[/quote] 理解和讨论之前请先学会如何观察！  计算机组成原理→DOS命令→汇编语言→C语言（不包括C++）、代码书写规范→数据结构、编译原理、操作系统→计算机网络、数据库原理、正则表达式→其它语言（包括C++）、架构……  对学习编程者的忠告： 多用小脑和手，少用大脑、眼睛和嘴，会更快地学会编程！ 眼过千遍不如手过一遍！ 书看千行不如手敲一行！ 手敲千行不如单步一行！ 单步源代码千行不如单步Debug版对应汇编一行！ 单步Debug版对应汇编千行不如单步Release版对应汇编一行！ 不会单步Release版对应汇编？在你想单步Release版C/C++代码片断的前面临时加一句DebugBreak();重建所有，然后在IDE中运行。（一般人我不告诉他！）  VC调试时按Alt+8、Alt+7、Alt+6和Alt+5,打开汇编窗口、堆栈窗口、内存窗口和寄存器窗口看每句C对应的汇编、单步执行并观察相应堆栈、内存和寄存器变化，这样过一遍不就啥都明白了吗。 对VC来说，所谓‘调试时’就是编译连接通过以后，按F10或F11键单步执行一步以后的时候，或者在某行按F9设了断点后按F5执行停在该断点处的时候。 [/quote]  多谢您很透彻！ 我尝试之后还是不理解13楼的增加一行打印信息就可以了，这个打印信息起到什么作用呢

引用 16 楼 songjiajia 的回复:[quote=引用 14 楼 zhao4zhong1 的回复:] 计算机组成原理→DOS命令→汇编语言→C语言（不包括C++）、代码书写规范→数据结构、编译原理、操作系统→计算机网络、数据库原理、正则表达式→其它语言（包括C++）、架构…… 赵老师 13楼的问题帮回答下吧 有点不解！[/quote] 理解和讨论之前请先学会如何观察！  计算机组成原理→DOS命令→汇编语言→C语言（不包括C++）、代码书写规范→数据结构、编译原理、操作系统→计算机网络、数据库原理、正则表达式→其它语言（包括C++）、架构……  对学习编程者的忠告： 多用小脑和手，少用大脑、眼睛和嘴，会更快地学会编程！ 眼过千遍不如手过一遍！ 书看千行不如手敲一行！ 手敲千行不如单步一行！ 单步源代码千行不如单步Debug版对应汇编一行！ 单步Debug版对应汇编千行不如单步Release版对应汇编一行！ 不会单步Release版对应汇编？在你想单步Release版C/C++代码片断的前面临时加一句DebugBreak();重建所有，然后在IDE中运行。（一般人我不告诉他！）  VC调试时按Alt+8、Alt+7、Alt+6和Alt+5,打开汇编窗口、堆栈窗口、内存窗口和寄存器窗口看每句C对应的汇编、单步执行并观察相应堆栈、内存和寄存器变化，这样过一遍不就啥都明白了吗。 对VC来说，所谓‘调试时’就是编译连接通过以后，按F10或F11键单步执行一步以后的时候，或者在某行按F9设了断点后按F5执行停在该断点处的时候。

引用 14 楼 zhao4zhong1 的回复:计算机组成原理→DOS命令→汇编语言→C语言（不包括C++）、代码书写规范→数据结构、编译原理、操作系统→计算机网络、数据库原理、正则表达式→其它语言（包括C++）、架构…… 赵老师 13楼的问题帮回答下吧 有点不解！

好帖子，学习了，记号

引用 5 楼 scribbler 的回复:没改变程序逻辑，增加一行打印，结果不一样  char* reverseString1(char* s) {     int i= strlen(s)-1;     char restr[i+1];     int j=i;     if(i>1){                  do {             restr[i-j]=s[j];             j--;         } while(j>=0);         //printf("%s,%d\n",restr,(int)strlen(restr));         restr[i+1]='\0';     }    printf("len=%d\n",(int)strlen(restr));    return restr; } int main(int argc, const char * argv[]) {     // insert code here...     char str[100] = "123456";     printf("%s\n",reverseString(str));     return 0; } //6 //654321   为什么增加一行打印信息就可以保留下数据了啊？

引用 3 楼 jianwen0529 的回复:malloc 申请的空间一直有效，知道free掉 栈上的数据，一旦跨出作用域就会被回收，（2）中你的数组作用域在函数内，函数返回之后就咔嚓掉了  strlen 计算字符串长度是不包含 '\0' 结束符的 所以你要完整复制一个字符串，分配的空间至少 strlen(str) + 1;  谢谢！ “栈上的数据，一旦跨出作用域就会被回收” 这个回收的意思是之前的数据被清零了吗？

栈中的变量通常包括函数参数和函数里声明的临时变量。 栈中的基本变量退出其作用域时，没有谁执行一段代码去释放/销毁/析构它所占用的内存，仅仅是没人再去理会的留在当前栈顶上方的若干遗留下来可被后续压栈操作覆盖的无用数据而已。 而栈中的类变量退出其作用域时，会自动执行其析构函数，……

你在函数调用栈里定义的数组只在 函数内部有效 。该次函数调用之后这部分内存会被释放掉。你可以改成static char restr[i+1];储存成静态数组 然后在文件最上面写一个 extern static char restr[i+1];扩展他的作用域，这样就可以用了

char* reverseString(char* s) {     int i= strlen(s)-1;    char restr[i+1];     int j=i;     if(i>1){                   do {             restr[i-j]=s[j];             j--;         } while(j>=0);                   restr[i+1]='\0';     }     memcpy(s, restr, strlen(restr)+1);     return s; }  这样就可以了。原因是栈上和堆上的空间生命周期不一样。栈上的数组是随着函数的调用而创建，随着函数的退出而释放。释放之后的空间自然就没有意义了。

函数内部的数组如果没有使用malloc或者new或者外部分配空间的话，那么函数返回后，该内存的数据会释放，最后你获取的是个未知数据。通常你想最终通过函数返回地址得到数据，可以采用：1.外部分配空间，该空间作为函数传出参数。2.内部主动分配，malloc。3使用二重指针

引用 3 楼 jianwen0529 的回复:malloc 申请的空间一直有效，知道free掉 栈上的数据，一旦跨出作用域就会被回收，（2）中你的数组作用域在函数内，函数返回之后就咔嚓掉了  strlen 计算字符串长度是不包含 '\0' 结束符的 所以你要完整复制一个字符串，分配的空间至少 strlen(str) + 1;  谢谢！明白了！

函数结束后，局部变量就销毁了，restr如果是一个局部数组，返回后得到的指针将指向已经销毁的地址  但动态申请的内存只要不释放就会一直存在

使用一个生命周期结束的变量，是未定义行为

栈内存和堆内存的区别，栈内存在作用哉结束后自动释放掉了，堆内存申请后需要代码上用free释放。 第一个是用malloc申请的堆内存，第二个是栈内存数组。 另外永远要记得，要给字符串最后预留一个字节符保存终止符，你申请的内存少了一个字节。

编译器的c++标准不支持栈上动态数组


Question: CTurkeyAdapter到底是鸡还是鸭？

使用上错了，正确方法如下  CTurkeyAdapter *pAdapter=new CTurkeyAdapter(pTurkey); pAdapter-＞Quack(); pAdapter-＞Fly();  接口适配器主要用于统一接口 对于一些你不便修改的的情况下（比如得不到源码，公有接口在别人的模块被太多使用不便修改）  比如你CTurkeyAdapter 适配器就是在你不能随意更改CTurkey的接口函数下 而你又想修改公用接口函数的名称，就多加了一层包装 void Quack() {     m_pTurkey-＞Gobble(); }  说白了就是换个接口名称或者封装一组操作


Question: 在做C解析器的时候关于转义字符的转换问题

你是不是在看调试器 ....  你把它打出来看看 ...

参考Tiny C Compiler源代码。

转义字符就这几种类型： http://baike.baidu.com/link?url=gc3TOKUt9_W6keS3wZzWee2vfp_zGX6aZ8MDpuI1rEVufIjdU8qZI3tdegQp8uQ56CW5dBiNhX8no4FT5OpRNd_zm05jQ9NC3KWTCVHvqK9xiIc6fm4RATfdLtrvBGHE


Question: 关于受限制的双端队列问题

参考stl dqueue？

另外，你的代码是链表，不是队列。 队列一般采用顺序存储，不允许中间插入删除。

“只能在front端出队但能在rear端进行入队、出队” 你的意思是，"在front端只能出队但能在rear端进行入队、出队" ？  肯定还是用双向链表，你把front的push操作去掉就行了，其它一模一样。

那我用的结构还是双向链表结构？  typedef struct DQueuelist    //定义结构体结点 { 	int data;                //结构体数据域 	struct DQueuelist *prior; //结构体前向指针 	struct DQueuelist *next;  //结构体后向指针 }DQueuelist, *DQueueptr; typedef struct                //定义双端队列 { 	DQueueptr front;         //头指针，指向链队列头结点 	DQueueptr rear;          //尾指针，指向链队列最后一个结点 }LinkDQueue;

双端队列你不是都有了吗  class MyQueue { public: //你的三个操作 private: MyDeque m_deq; //双端队列 }  要求模板的话就实现为模板


Question: ODBC 多线程并行执行SQLExecute

多进程是可以的并行的。

感谢。 发现是odbc配置文件 odbcinst.ini的问题。 其中有一条属性是 Threading = 0/1/2/3，不附加该内容的话，默认被设置为3，在驱动层面是串行执行的。 添加Threading = 1 问题解决。

试试使用多进程。


Question: C语言 liunx 下libpcap 解析 HTTP 拼包问题跪求

1,创建一个buffer list,  这个buffer list的总体大小不超过4M， 2，抓包： 网络包都大于64byte; 如果小于64，当做坏包处理， 3，如果当前的list 是空，并且整个包长小于 140 （tcp + http head ... 知道出现content length）    		并且pkt_data+34 是“HTTP” , 或者进一步判断是 HTTP/1.1 200 OK 			如果是，说明这个包是http的response的开头。 			寻找当前的content length ,并求出content length的大小。 				如果没有找到content length，也没有找到 Transfer-Encoding ： 那这种包，我还没有见过。 				如果找到content length ，那判断pkt_data 的剩余长度 + 4 （\r\n\r\n），是不是 恰好是content length, 				如果是-恰好说明是： 这个包已经是一个完整的http 包了，没有分包，即没有出现 数据被分包的问题。 				如果不是-- 说明数据被分包了，请把下列属性当成一个 list 的一个节点。 					src_ip，dst_ip，src_port，dst_port，seq ,next_seq, ack, current_buffer,cur_buf_len. 					请把这个member ,增加到 list里面。 		 		如果当前的list 非空， 		那对比当前的 这些属性 是否和list的某个成员的属性一致: src_ip，dst_ip，src_port，dst_port，seq ,next_seq, ack 		注意ack ,seq的大小端问题： BigLittleSwap32。 		如果属性匹配那把这个buffer 增加到 旧的buffer后面，再次call : Check_http_content_is_end 		 		如果分包的话，一般情况下包的长度的序列如下：X,X,X,X,...Y ,并且X>Y, 		如果中间出现某些 包的PDU_Packet_length 和 X的包长不相等 --- 至少我没有见过， 那我就报错了。		 		如果不相等，去判断Check_http_content_is_end（）了。 		 		如果没有content-length ,na zhoad transfer-Encoding: 看是否是chunked. 		 		如果最后一个包的tcp的flag: 是0x18 (PSH,ACK)， 这更能说明是这是一个http 分包的最后一个包了。

HTTP不是有Content-Length吗？

#include <stdio.h> #include <pcap.h> #include <string.h>   /*ip*/ struct ip_address {     u_char byte1;     u_char byte2;     u_char byte3;     u_char byte4; };  struct ipadd { 	struct ip_address src_ip; 	struct ip_address dst_ip; };  /*udp和tcp的端口*/ struct ip_port {   u_int16_t src_port;	/*源端口*/   u_int16_t dst_port;	/*目的端口*/ };  struct tcp_header { 	u_int16_t src_port; 	u_int16_t dst_port; 	u_int32_t num1; 	u_int32_t num2; 	u_int8_t tcp_hlen_f; /*tcp首部长度和选项*/ 	u_int8_t tcp_hlen; 	u_int16_t windows; 	u_int16_t checksum; 	u_int16_t urgent_pointer; };  struct udp_header { 	u_int16_t src_port; 	u_int16_t dst_port; 	u_int16_t len; 	u_int16_t Checksum; };  /*ip数据头*/ struct ip_header   {   u_int8_t ip_hlen_v;  /*ip版本和首部长度*/   u_int8_t ip_tos;     u_int16_t ip_length;  /*ip总长度*/   u_int16_t ip_id;     u_int16_t  ip_off;     u_int8_t ip_ttl;     u_int8_t ip_protocol;     u_int16_t ip_checksum;     struct ipadd ip;	/*ip地址*/ };  u_int8_t get_tcpLen(u_int8_t tcp_hlen_f) { 	tcp_hlen_f >>= 4; 	tcp_hlen_f <<= 2; 	return tcp_hlen_f; }  u_int8_t get_ipLen(u_int8_t ip_hlen_v) { 	ip_hlen_v <<=4; 	ip_hlen_v >>= 2; 	return ip_hlen_v; }  /*获取对应http信息*/ void get_http(const u_char * packet_data, char * head_str, char *tail_str, u_int16_t datelen, u_int8_t p)/*head_str：需要查找的字段头，tail_str：结束。len：数据报文长度*/ { 	char * data = NULL; 	data = (char *)(packet_data + 14 + p); /*用户忽略数据帧、ip头和tcp头*/ 	char * d = NULL; 	d = strstr(data,head_str); 	datelen -= p; 	if (d != NULL) 	{ 		char * m = NULL; 		m = strstr(d,tail_str); 		int l = m - d; 		char buf[l+1]; 		buf[l]='\0'; 		strncpy(buf,d,l); 		printf("- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \n"); 		printf("%s\n",buf); 		 		char da[datelen + 1]; 		da[datelen]='\0'; 		strncpy(da,data,datelen); 		printf("pake len:%d-  - - %d\n",datelen,strlen(da)); 		printf("%s\n",da); 	} 	else 	{                 char da[datelen + 1];                 da[datelen]='\0';                 strncpy(da,data,datelen);                 printf("pake len:%d-  - - %d\n",datelen,strlen(da));                 printf("%s\n",da); 	 	}  }  void tcp_udp(char * typ, const u_char * pack_tcp_udp, struct ipadd ip, u_int16_t datelen, u_int8_t p) { 	struct ip_port * ip_port = (struct ip_port *)(pack_tcp_udp + 14 + p); 	u_int16_t src_port = ntohs(ip_port->src_port); 	u_int16_t dst_port = ntohs(ip_port->dst_port); 	/* 	printf("* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * \n"); 	printf("%s\t%d.%d.%d.%d : %d -> %d.%d.%d.%d : %d\n", 		typ, 		ip.src_ip.byte1, 		ip.src_ip.byte2, 		ip.src_ip.byte3, 		ip.src_ip.byte4, 		src_port, 		ip.dst_ip.byte1, 		ip.dst_ip.byte2, 		ip.dst_ip.byte3, 		ip.dst_ip.byte4, 		dst_port); 	*/ 	if (strcmp(typ, "Tcp") == 0) 	{ 		u_int8_t tcplen; 		struct tcp_header * tcp_header = (struct tcp_header*)(pack_tcp_udp + 14 + p); 		tcplen = get_tcpLen(tcp_header->tcp_hlen_f); 		//printf("%d\n",tcplen); 		if(src_port == 80 || dst_port == 80) 		{ 			//get_http(pack_tcp_udp, "GET ", "HTTP/1.1\r\n", datelen, p + tcplen); 			get_http(pack_tcp_udp, "POST ", "HTTP/1.1\r\n", datelen, p + tcplen); 		}  	}else 	{ 		 		 	} }  void packet_out(u_char * argument,const struct pcap_pkthdr * packet_header,                    const u_char * packet_content) { 	struct ip_header * ip_header; 	u_int8_t iplen; 	char *typ; 	 	ip_header = (struct ip_header*)(packet_content+14); 	iplen = get_ipLen(ip_header -> ip_hlen_v); 	 	switch(ip_header -> ip_protocol)   	{ 		case 6: 			typ = "Tcp"; 			break; 		case 17:   			typ = "Udp"; 			break;  		default: 			return;  	} 	 	tcp_udp(typ, packet_content, ip_header->ip, ntohs(ip_header->ip_length), iplen); 	 	//pcap_dump(argument,packet_header,packet_content);  }  void ReadPcap(char * fname) { 	pcap_t *fp; 	char ebuf[PCAP_ERRBUF_SIZE]; 	fp = pcap_open_offline(fname, ebuf);  	pcap_loop(fp, 0, packet_out, NULL); 	 }   int main(int argc, char **argv) /*-i 指定网口 -w 输出报文文件 port 指定端口 tcp 或 udp 过滤 -r 读包文件名*/ { 	pcap_t *handle;     char err[PCAP_ERRBUF_SIZE], *dev, *out; 	char pd[20] = "";      out = "output.pcap"; 	dev = pcap_lookupdev(err);  	int i;         for (i = 1; i < argc; i++  )         {         	if (strcmp(argv[i], "-i") == 0 )                 {                 	dev = argv[++i];                 }                 else if (strcmp(argv[i], "-w") == 0)                 {                         out = argv[++i];                 } 		else if(strcmp(argv[i], "udp") == 0 			|| strcmp(argv[i], "tcp") == 0) 		{ 			char pdtcp[20]; 			strcpy(pdtcp, argv[i]); 			strcat(pdtcp, " "); 			strcat(pdtcp, pd); 			strcpy(pd, pdtcp); 		} 		else if (strcmp(argv[i], "port") == 0 ) 		{ 			strcat(pd, argv[i]); 			strcat(pd, " "); 			strcat(pd, argv[++i]); 			strcat(pd, " "); 		} else if (strcmp(argv[i], "-r") == 0) 		{ 			ReadPcap(argv[++i]); 			return 0; 			 		} 		 	}          if(dev)     {             printf("dev:%s\n",dev); 	printf("output file: %s\n", out); 	printf("pd: %s\n", pd); 	printf("ing......\n");     }     else     {         printf("error :%s\n",err); 		return 0;     }      bpf_u_int32 mask;     bpf_u_int32 net; 	struct bpf_program filter;  	pcap_lookupnet(dev, &net, &mask, err);  	handle = pcap_open_live(dev, BUFSIZ, 1, 0, err);  	pcap_compile(handle, &filter, pd, 0, net); 	pcap_setfilter(handle, &filter);  	pcap_dumper_t* out_pcap; 	out_pcap  = pcap_dump_open(handle, out); 	 	while(1) 	{ 		pcap_loop(handle,30,packet_out,(u_char *)out_pcap);         pcap_dump_flush(out_pcap); 	} 	pcap_close(handle); 	pcap_dump_close(out_pcap); 	 	return 0; }


Question: 变量的存储类别

c语言的存储类别问题，请看博客http://blog.csdn.net/libing403/article/details/72934528

//char (*(*x[3])())[5];//x是什么类型的变量? // //分析C语言声明，关键是搞清楚这个变量是个什么东西（函数、指针、数组）， //是函数那么剩下的就是他的参数和返回值， //是指针那剩下部分是说明他指向什么， //是数组剩下的部分就是说明数组的成员是什么类型。 //解析C语言声明规则： //从左侧第一个标识符开始，按照优先级进行结合。*表示是..的指针，const表示只读的，volatile表示可变的，[]表示是数组，()表示是函数。 // //x和[3]结合说明是一个大小为3的数组，该数组的每个元素为一类指针，该类指针指向一类函数，该类函数无参数，返回一类指针，该类指针指向一个大小为5的char型数组 #include <stdio.h> #include <typeinfo.h> char num[5]; char (*x00())[5] {     return # } int main() {     char (*(*x[3])())[5];//是个数组，大小为3     char (*(*x0  )())[5];//数组的元素，是个函数指针     char (*( x00 )())[5];//函数原型，参数为空，返回值为指针     char (*  x000   )[5];//返回值      x0 = x00;     x[0] = x0;     x[1] = x0;     x[2] = x0;     printf("typeid(x).name() is %s\n",typeid(x).name());     return 0; } //typeid(x).name() is char (* (__cdecl**)(void))[5]  void HexDump(char *buf,int len,int addr) {     int i,j,k;     char binstr[80];      for (i=0;i<len;i++) {         if (0==(i%16)) {             sprintf(binstr,"%08x -",i+addr);             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]:'.');             }             printf("%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]:'.');         }         printf("%s\n",binstr);     } }

引用 3 楼 企鹅爱吃方便面的回复:感觉你是想问auto，static，extern，register的问题，你看看这个吧，http://blog.csdn.net/hjxhjh/article/details/8947397 感谢：)  文章很有用 已经收藏了

电脑内存或文件内容或传输内容只是一个一维二进制字节数组及其对应的二进制地址； 人脑才将电脑内存或文件内容或传输内容中的这个一维二进制字节数组及其对应的二进制地址的某些部分看成是整数、有符号数/无符号数、浮点数、复数、英文字母、阿拉伯数字、中文/韩文/法文……字符/字符串、汇编指令、函数、函数参数、堆、栈、数组、指针、数组指针、指针数组、数组的数组、指针的指针、二维数组、字符点阵、字符笔画的坐标、黑白二值图片、灰度图片、彩色图片、录音、视频、指纹信息、身份证信息……  推荐使用WinHex软件查看硬盘或文件或内存中的原始字节内容。  不要把 fopen("...","...");fscanf,fprintf,fgets,fgetc,fclose //读时把\r\n替换成\n，写时把\n替换成\r\n;读到\x1a就设置EOF;读写的内容当字符看待 和 fopen("...","...b");fseek,ftell,fread,fwrite,fgetc,fclose //不作以上替换，遇到\x1a仍继续读;读写的内容当字节看待 弄混了

引用 楼主 qq_37308044 的回复:定义变量时，如果指明变量的存储类型时，此时改变量的存储类别是什么  求解答 存储类别是指在内存中所占用的位置吗？

这个在百度和书上的没找到 = =


Question: 双向循环链表的一个题

遍历O（n）插入就好了，难点是什么


Question: 计算1+1/2!+1/3!+……+1/n! n为输入的整数

懂了，谢谢大家

f,c都没赋初值，c值每次循环做完没有更新

对于函数内部定义的变量（包括main（））得到的是一个不确定的值。所产生的后果就是结果未定义。因此你的代码中f的值是不确定的，拿一个不确定的值去与一个确定的数相加得到的数也是一个不确定的值。

引用 1 楼 user-4 的回复:f没有初值。 另外int<=float，不要这么用。 f没有初值会有什么影响么？

仅供参考：// 按下列数级计算e的近视值，使e有小数点后1000位有效数字。 // e=1+1/1!+1/2!+1/3!+......1/n! #include <iostream> #include <string> using namespace std; inline int compare(string str1,string str2) {//相等返回0，大于返回1，小于返回-1          if (str1.size()>str2.size()) return 1; //长度长的整数大于长度小的整数     else if (str1.size()<str2.size()) return -1;     else                              return str1.compare(str2); //若长度相等，则头到尾按位比较 } string SUB_INT(string str1,string str2); string ADD_INT(string str1,string str2) {//高精度加法     int sign=1; //sign 为符号位     string str;     if (str1[0]=='-') {         if (str2[0]=='-') {             sign=-1;             str=ADD_INT(str1.erase(0,1),str2.erase(0,1));         } else {             str=SUB_INT(str2,str1.erase(0,1));         }     } else {         if (str2[0]=='-') {             str=SUB_INT(str1,str2.erase(0,1));         } else { //把两个整数对齐，短整数前面加0补齐             string::size_type L1,L2;             int i;             L1=str1.size();             L2=str2.size();             if (L1<L2) {                 for (i=1;i<=L2-L1;i++) str1="0"+str1;             } else {                 for (i=1;i<=L1-L2;i++) str2="0"+str2;             }             int int1=0,int2=0; //int2 记录进位             for (i=str1.size()-1;i>=0;i--) {                 int1=(int(str1[i])-'0'+int(str2[i])-'0'+int2)%10;                 int2=(int(str1[i])-'0'+int(str2[i])-'0'+int2)/10;                 str=char(int1+'0')+str;             }             if (int2!=0) str=char(int2+'0')+str;         }     }     //运算后处理符号位     if ((sign==-1)&&(str[0]!='0')) str="-"+str;     return str; } string SUB_INT(string str1,string str2) {//高精度减法     int sign=1; //sign 为符号位     string str;     int i,j;     if (str2[0]=='-') {         str=ADD_INT(str1,str2.erase(0,1));     } else {         int res=compare(str1,str2);         if (res==0) return "0";         if (res<0) {             sign=-1;             string temp =str1;             str1=str2;             str2=temp;         }         string::size_type tempint;         tempint=str1.size()-str2.size();         for (i=str2.size()-1;i>=0;i--) {             if (str1[i+tempint]<str2[i]) {                 j=1;                 while (1) {//zhao4zhong1添加                     if (str1[i+tempint-j]=='0') {                         str1[i+tempint-j]='9';                         j++;                     } else {                         str1[i+tempint-j]=char(int(str1[i+tempint-j])-1);                         break;                     }                 }                 str=char(str1[i+tempint]-str2[i]+':')+str;             } else {                 str=char(str1[i+tempint]-str2[i]+'0')+str;             }         }         for (i=tempint-1;i>=0;i--) str=str1[i]+str;     }     //去除结果中多余的前导0     str.erase(0,str.find_first_not_of('0'));     if (str.empty()) str="0";     if ((sign==-1) && (str[0]!='0')) str ="-"+str;     return str; } string MUL_INT(string str1,string str2) {//高精度乘法     int sign=1; //sign 为符号位     string str;     if (str1[0]=='-') {         sign*=-1;         str1 =str1.erase(0,1);     }     if (str2[0]=='-') {         sign*=-1;         str2 =str2.erase(0,1);     }     int i,j;     string::size_type L1,L2;     L1=str1.size();     L2=str2.size();     for (i=L2-1;i>=0;i--) { //模拟手工乘法竖式         string tempstr;         int int1=0,int2=0,int3=int(str2[i])-'0';         if (int3!=0) {             for (j=1;j<=(int)(L2-1-i);j++) tempstr="0"+tempstr;             for (j=L1-1;j>=0;j--) {                 int1=(int3*(int(str1[j])-'0')+int2)%10;                 int2=(int3*(int(str1[j])-'0')+int2)/10;                 tempstr=char(int1+'0')+tempstr;             }             if (int2!=0) tempstr=char(int2+'0')+tempstr;         }         str=ADD_INT(str,tempstr);     }     //去除结果中的前导0     str.erase(0,str.find_first_not_of('0'));     if (str.empty()) str="0";     if ((sign==-1) && (str[0]!='0')) str="-"+str;     return str; } string DIVIDE_INT(string str1,string str2,int flag) {//高精度除法。flag==1时,返回商; flag==0时,返回余数     string quotient,residue; //定义商和余数     int sign1=1,sign2=1;     if (str2 == "0") {  //判断除数是否为0         quotient= "ERROR!";         residue = "ERROR!";         if (flag==1) return quotient;         else         return residue ;     }     if (str1=="0") { //判断被除数是否为0         quotient="0";         residue ="0";     }     if (str1[0]=='-') {         str1   = str1.erase(0,1);         sign1 *= -1;         sign2  = -1;     }     if (str2[0]=='-') {         str2   = str2.erase(0,1);         sign1 *= -1;     }     int res=compare(str1,str2);     if (res<0) {         quotient="0";         residue =str1;     } else if (res == 0) {         quotient="1";         residue ="0";     } else {         string::size_type L1,L2;         L1=str1.size();         L2=str2.size();         string tempstr;         tempstr.append(str1,0,L2-1);         for (int i=L2-1;i<L1;i++) { //模拟手工除法竖式             tempstr=tempstr+str1[i];             tempstr.erase(0,tempstr.find_first_not_of('0'));//zhao4zhong1添加             if (tempstr.empty()) tempstr="0";//zhao4zhong1添加             for (char ch='9';ch>='0';ch--) { //试商                 string str;                 str=str+ch;                 if (compare(MUL_INT(str2,str),tempstr)<=0) {                     quotient=quotient+ch;                     tempstr =SUB_INT(tempstr,MUL_INT(str2,str));                     break;                 }             }         }         residue=tempstr;     }     //去除结果中的前导0     quotient.erase(0,quotient.find_first_not_of('0'));     if (quotient.empty()) quotient="0";     if ((sign1==-1)&&(quotient[0]!='0')) quotient="-"+quotient;     if ((sign2==-1)&&(residue [0]!='0')) residue ="-"+residue ;     if (flag==1) return quotient;     else         return residue ; } string DIV_INT(string str1,string str2) {//高精度除法,返回商     return DIVIDE_INT(str1,str2,1); } string MOD_INT(string str1,string str2) {//高精度除法,返回余数     return DIVIDE_INT(str1,str2,0); } int main() {     string s1,s2,s3,s4;     int i;      s4="0";      s3="1";     for (i=0;i<1002;i++) s3+="0";      s1="1";     s2="1";      s4=ADD_INT(s4,DIV_INT(s3,s1));     s4=ADD_INT(s4,DIV_INT(s3,s1));      for (i=2;i<451;i++) {//因为450!是一个1001位数         s2=ADD_INT(s2,string("1"));         s1=MUL_INT(s1,s2);         s4=ADD_INT(s4,DIV_INT(s3,s1));     }      cout<<s4<<endl;      return(0); } //271828182845904523536028747135266249775724709369995957496696762772407663035354759457138217852516642742746639193200305992 //181741359662904357290033429526059563073813232862794349076323382988075319525101901157383418793070215408914993488416750924 //476146066808226480016847741185374234544243710753907774499206955170276183860626133138458300075204493382656029760673711320 //070932870912744374704723069697720931014169283681902551510865746377211125238978442505695369677078544996996794686445490598 //793163688923009879312773617821542499922957635148220826989519366803318252886939849646510582093923982948879332036250944311 //730123819706841614039701983767932068328237646480429531180232878250981945581530175671736133206981125099618188159304169035 //159888851934580727386673858942287922849989208680582574927961048419844436346324496848756023362482704197862320900216099023 //530436994184914631409343173814364054625315209618369088870701676839642437814059271456354906130310720851038375051011574770 //4171898610687396965521267154688957035035174

f没有初值。 另外int<=float，不要这么用。


Question: 请教一下为什么sendto的返回值一直是-1

引用 3 楼 jianwen0529 的回复:网上找个例子先运行下，端口开大点，先启动服务端然后再启动客户端  我的程序基本是照着视频照抄的，视频上运行成功了，可是我这个却不行，换了好几个端口号了都不行，用netstat -ano检查端口，也没有被占用。接收程序在 bind(st,(SOCKADDR *)&addr,sizeof(SOCKADDR)) 这里就返回-1，接收不到数据。代码跟视频比较很多次都不知道是什么问题，实在是没辙了。

网上找个例子先运行下，端口开大点，先启动服务端然后再启动客户端

引用 5 楼 jianwen0529 的回复:http://www.cnblogs.com/ayanmw/archive/2012/05/03/2480854.html  测试下这个！  感谢帮助，已经解决。我把SOCKET结构体赋值放在初始化前面了，所以socket函数没有调用成功

引用 1 楼 jianwen0529 的回复:你这个是客户端，但是你的服务程序呢  我是小白不太懂，服务程序是接收程序吗，接收程序我也写了，但是在bind绑定端口那里就挂了，错误代码也是10038

你这个是客户端，但是你的服务程序呢


Question: 请教前辈，在dev C++下建立一个c项目文件，出现recipe for target "Project1.exe" failed错误

原来是这一坨有错误来着

新建的项目自带一个main.c文件，我原来是把这个文件删了，用自己的文件里面的main函数发现不行，然后把自己文件main函数的内容复制到项目自带的main文件里面，发现可以编译运行了点yes就OK了

同问解决了吗

我想问楼主你解决了这个问题吗

关闭UAC、防火墙、杀毒软件 在任务管理器里面结束掉进程collect2.exe，如果有。


Question: 指针的类型和指针所指向的类型不同时，数据解析问题

double可以可能由于变量大于4字节后就是用指针类型去解释了  建议楼主单步跟踪到prinft函数里去找原因

printf 参数是按值传递的  如果你传递的参数类型是int，但格式是(%f)，prinft内部应该直接将一个int变量赋值给一个浮点变量，而不是按指针类型去解释

@赵4老师  float和double同为浮点数，只是精度不同，为何double可以，而float不行呢？

可能跟printf的实现有关

字节序 结构体成员对齐 编解码 ……

经过多方查找，已有正确解释： float类型的参数，在入栈时会进行类型转换，变成double类型，而%f解析的是双精度浮点数8字节，所以最后解析输出会出现错误。  另外：无符号char short在作为参数入栈时也会自动转换为无符号int            有符号char short在作为参数入栈时也会自动转换为有符号int  %c  %hd在解析时分别只解析1字节和2字节数据，但是指针位移是4字节

printf里面的%和变量的一一对应关系 scanf里面的%和变量以及变量前加不加&的一一对应关系 是C代码中非常容易出错的地方，而且通常编译还不出错。 所以在编译源代码之前值得专门仔细检查一遍甚至多遍。


Question: 求解决啊  急！谢谢

我试过   好像也不行  出现了新的错误

应该是fclose(fp)不是fclose(p)

额   你知道怎么解决吗

这段代码你是哪里抄来的吧


Question: 关于getchar函数的一个疑问

getchar就是读取缓冲区中的一个字符  scanf后，缓冲区中还会留下你最后的回车产生的换行符\n，第一个getcahr接收了他，否则换行符会仍留在缓冲区中  第二个则是等待用户输入一个字符再继续

楼上已经基本解释清楚了。 比如你输入3+回车符（此时输入缓冲区是:3\n） 你scanf %d只是读取掉了3，回车符还会遗留下来的，所以可以用getchar清掉这个回车符

第一个回车是用来终止scanf的，getchar是用来清楚这个回车用的，不然这个回车还残留在缓冲区中。第二个不一定要输入回车，随便输入个东西按回车就会继续。getchar是从缓冲区中读取第一个字符，这个字符是什么都行，如果缓冲区没有字符可以读取，就等待输入。


Question: 如何定义函数和向函数传递参数？参数类型为字符串二维数组，即二维数组中每个元素类型为字符串类型

数组退化成指针。

根据大家的建议，采用了如下方式，达到了同等的目的吧。 #include<cstring> #include<iostream> #include<stdio.h> #include<stdlib.h> #include<iomanip>  using namespace std;  void threeArr(char** arr,int m,int n){     int count = 0;     for(int i=0;i<m;i++){         for(int j=0;j<n;j++){             cout<<std::left<<std::setw(10)<<*(arr + n*i + j)<<" ";             ++count;         }         if(count%n == 0){             cout<<endl;         }     } };  int main(){     char *arrays[3][5] = {{"bcdaqw","thbcda","weccgh","uk3e","13br04"},                          {"gjh","df7h","5i6sf","yhjj5","xkh"},                          {"nml","lwfm","fbjyn","huxue","qibo"}};     threeArr((char**)arrays,3,5);     return 0; }

每个元素都是char*类型。又是数组当然用数组指针呀

你这个是一个二维的char*数组  你给的代码没有编译问题

void threeArr(int(&arr)[3][5]); //必须传 3X5 大小的数组 void threeArr(int **arr, int row, int col); void threeArr(int *arr[], int row, int col);


Question: 请教一个数据结构的问题，在不同.c文件中用不同的元素类型

引用 3 楼 jianwen0529 的回复:[quote=引用 2 楼 luo560 的回复:] [quote=引用 1 楼 jianwen0529 的回复:] typedef union{ uint16_t u16; unit32_t u32; float f; double d; }ElementType;  用联合体来替代ElementType，在你用不同场景的时候选择适当的union中的值即可 恩恩，的确解决我的问题了，但是假如有很多文件的话并且结构体成员比较多的话就比较麻烦了[/quote]  用C++[/quote] 用C++的话要用到哪块知识呢   我没学过C++

引用 2 楼 luo560 的回复:[quote=引用 1 楼 jianwen0529 的回复:] typedef union{ uint16_t u16; unit32_t u32; float f; double d; }ElementType;  用联合体来替代ElementType，在你用不同场景的时候选择适当的union中的值即可 恩恩，的确解决我的问题了，但是假如有很多文件的话并且结构体成员比较多的话就比较麻烦了[/quote]  用C++

引用 1 楼 jianwen0529 的回复:typedef union{ uint16_t u16; unit32_t u32; float f; double d; }ElementType;  用联合体来替代ElementType，在你用不同场景的时候选择适当的union中的值即可 恩恩，的确解决我的问题了，但是假如有很多文件的话并且结构体成员比较多的话就比较麻烦了

参考protobuf


Question: 512*512 的方阵如何分割

没看出来难度在哪里。。。 活着需求没有描述清楚？

仅供参考：//有两个每一项都是0或1组成的二维数组：A[50][50]和B[2][2] //找出在A里包含有多少与B相同的项，并标出坐标 #include <stdio.h> #include <stdlib.h> #include <time.h> int A[50][50]; int B[2][2]; int y,x; int j,i; int n; int main() {     srand(time(NULL));     for (y=0;y<50;y++) {         for (x=0;x<50;x++) {             A[y][x]=rand()%2;         }     }     for (y=0;y<2;y++) {         for (x=0;x<2;x++) {             B[y][x]=rand()%2;         }     }     n=0;     for (y=0;y<50-2+1;y++) {         for (x=0;x<50-2+1;x++) {             for (j=0;j<2;j++) {                 for (i=0;i<2;i++) {                     if (A[y+j][x+i]!=B[j][i]) goto NE;                 }             }             n++;             printf("n    y,x=%4d %2d,%2d\n",n,y,x);             NE:;         }     }     return 0; } //n    y,x=   1  0, 1 //n    y,x=   2  0, 3 //n    y,x=   3  0,17 //n    y,x=   4  1,12 //n    y,x=   5  1,20 //n    y,x=   6  1,33 //n    y,x=   7  2, 4 //n    y,x=   8  2,32 //n    y,x=   9  3,13 //n    y,x=  10  3,31 //n    y,x=  11  3,48 //n    y,x=  12  4, 0 //n    y,x=  13  5,14 //n    y,x=  14  5,32 //n    y,x=  15  5,36 //n    y,x=  16  5,47 //n    y,x=  17  6, 7 //n    y,x=  18  6,17 //n    y,x=  19  6,45 //n    y,x=  20  7, 1 //n    y,x=  21  7,31 //n    y,x=  22  8, 0 //n    y,x=  23  8,16 //n    y,x=  24  8,18 //n    y,x=  25  8,25 //n    y,x=  26  9, 9 //n    y,x=  27  9,27 //n    y,x=  28 10,12 //n    y,x=  29 10,26 //n    y,x=  30 12,12 //n    y,x=  31 12,20 //n    y,x=  32 13,36 //n    y,x=  33 13,45 //n    y,x=  34 13,48 //n    y,x=  35 14, 5 //n    y,x=  36 14, 7 //n    y,x=  37 14, 9 //n    y,x=  38 14,21 //n    y,x=  39 15, 4 //n    y,x=  40 15,20 //n    y,x=  41 16,10 //n    y,x=  42 16,23 //n    y,x=  43 16,45 //n    y,x=  44 17,16 //n    y,x=  45 17,22 //n    y,x=  46 17,40 //n    y,x=  47 18, 1 //n    y,x=  48 18, 5 //n    y,x=  49 18,26 //n    y,x=  50 18,43 //n    y,x=  51 19,40 //n    y,x=  52 19,46 //n    y,x=  53 20,31 //n    y,x=  54 20,38 //n    y,x=  55 21,27 //n    y,x=  56 21,41 //n    y,x=  57 21,48 //n    y,x=  58 22,10 //n    y,x=  59 22,15 //n    y,x=  60 22,20 //n    y,x=  61 22,24 //n    y,x=  62 23, 0 //n    y,x=  63 23, 3 //n    y,x=  64 23,40 //n    y,x=  65 24,11 //n    y,x=  66 24,14 //n    y,x=  67 24,29 //n    y,x=  68 24,34 //n    y,x=  69 24,43 //n    y,x=  70 25,16 //n    y,x=  71 25,19 //n    y,x=  72 25,25 //n    y,x=  73 26,18 //n    y,x=  74 26,23 //n    y,x=  75 27, 9 //n    y,x=  76 27,44 //n    y,x=  77 28, 7 //n    y,x=  78 28,22 //n    y,x=  79 28,24 //n    y,x=  80 28,33 //n    y,x=  81 28,48 //n    y,x=  82 29, 0 //n    y,x=  83 29,35 //n    y,x=  84 29,41 //n    y,x=  85 29,44 //n    y,x=  86 30, 7 //n    y,x=  87 30,23 //n    y,x=  88 31,35 //n    y,x=  89 31,41 //n    y,x=  90 31,45 //n    y,x=  91 33,21 //n    y,x=  92 33,27 //n    y,x=  93 34, 2 //n    y,x=  94 34,19 //n    y,x=  95 34,25 //n    y,x=  96 34,47 //n    y,x=  97 35,14 //n    y,x=  98 36, 6 //n    y,x=  99 36,13 //n    y,x= 100 36,25 //n    y,x= 101 36,31 //n    y,x= 102 36,41 //n    y,x= 103 36,47 //n    y,x= 104 37,11 //n    y,x= 105 37,16 //n    y,x= 106 37,24 //n    y,x= 107 37,30 //n    y,x= 108 38,18 //n    y,x= 109 38,20 //n    y,x= 110 38,28 //n    y,x= 111 38,38 //n    y,x= 112 39,32 //n    y,x= 113 39,43 //n    y,x= 114 39,45 //n    y,x= 115 39,48 //n    y,x= 116 40,35 //n    y,x= 117 40,38 //n    y,x= 118 41,33 //n    y,x= 119 42, 9 //n    y,x= 120 42,13 //n    y,x= 121 42,22 //n    y,x= 122 42,25 //n    y,x= 123 43,21 //n    y,x= 124 44,25 //n    y,x= 125 45,15 //n    y,x= 126 45,20 //n    y,x= 127 45,42 //n    y,x= 128 46, 4 //n    y,x= 129 47, 3 //n    y,x= 130 47,22 //n    y,x= 131 47,33 //n    y,x= 132 47,43 //n    y,x= 133 47,45 //n    y,x= 134 47,48 //n    y,x= 135 48, 0 //


Question: c语言用什么编译器好点啊

我用的是MinGW版，gcc……凑个字数

Visual C++ 2010 Express简体中文版http://pan.baidu.com/s/1bnwRVLt

WINDOWS下就用VS吧

VS系列都行，比较好用。

devc++


Question: 结构体的指针和首末地址的问题

se3buf* pt=se3bufs2; se3bufs2[10]取首地址就是“se3bufs2”或者pt,   (pt+i)=&se3bufs2[i] 末地址就是   &se3bufs2[9]或者(pt+9)  se3bufs1是结构体对象,只有一个首地址&se3bufs1,不是结构体数组,所以不存在未地址的说法,或者可以说未地址等于首地址,也是&se3bufs1

引用 4 楼 u010417757 的回复:[quote=引用 3 楼 reg_wan 的回复:] se3bufs1是结构体对象,只有一个首地址&se3bufs1,不是结构体数组,所以不存在未地址的说法,或者可以说未地址等于首地址,也是&se3bufs1  我说法错了，，我是想知道se3bufs1所占用的地址范围，第一位和最后一位的地址 首位的话就应该是&se3bufs1，末位的话应该是什么？？ （&se3bufs1+sizeof(se3bufs1)）,????[/quote]  寻址只到字节，不到位。 se3bufs1的地址就是&se3bufs1，占用大小是sizeof(se3bufs1)。

http://edu.csdn.net/course/detail/2344 C语言指针与汇编内存地址-一.代码要素

引用 3 楼 reg_wan 的回复:se3bufs1是结构体对象,只有一个首地址&se3bufs1,不是结构体数组,所以不存在未地址的说法,或者可以说未地址等于首地址,也是&se3bufs1  我说法错了，，我是想知道se3bufs1所占用的地址范围，第一位和最后一位的地址 首位的话就应该是&se3bufs1，末位的话应该是什么？？ （&se3bufs1+sizeof(se3bufs1)）,????

引用它的名称“se3bufs2”也是它的指针。 这种说法就不对。摒弃这种说法。数组是数组，指针是指针，只是数组在很多情况下为转化为指向其首元素的指针。 这样可能会好理解一些。


Question: UTC时间换算

参考这里的GetDateTime

使用localtime函数，他会考虑时区和闰年等情况

struct tm *localtime(    const time_t *timer  );


Question: C语言结构体赋值

赋值时没有 {} 这种方式，一个成员一个成员地进行赋值吧

最好定义成结构体数组。

“变量赋值”和“变量初始化”不是一回事！ “变量赋值”发生在运行期，其写法遵循赋值语法规定。 “变量初始化”发生在编译期或运行期，其写法遵循初始化列表语法规定。

Student arr1 = { 20, 88.8, "zhang" }; arr[0] = arr1;

检查标点符号中英文

只有在声明定义时才能用大括号初始化，赋值就不能这样用了，只能给成员一个个地赋值。