Question: 感觉没有错，怎么运行结果是一个很大的负整数?请教下大家

a[i-3] = a[i-2]; a[i-2] = a[i-1]; a[i-1] = a[i];   这是在干什么？

这个用递归是比较好实现的吧！

怎么看怎么觉得         a[i-3] = a[i-2];         a[i-2] = a[i-1];         a[i-1] = a[i]; 这三行是多余的


Question: 求从1到n中选择5个数，求其非递减序的排列个数

//http://bbs.csdn.net/topics/390667169 //1到1中选5个数：1 //11111 //共1种， //1到2中选5个数：12 2 2 2 2 //11111                   A //11112 //11122 //11222 //12222 //22222 //共6种， //1到3中选5个数：123 23 3 23 3 3 23 3 3 3 233333 //11111                                   A //11112 //11113 //11122 //11123 //11133 //11222 //11223 //11233 //11333 //12222 //12223 //12233 //12333 //13333 //22222 //22223 //22233 //22333 //23333 //33333 //共21种， //1到4中选5个数：1234 234 34 4 234 34 4 34 4 4 234 34 4 34 4 4 34 4 4 4  234 34 4 34 4 4 34 4 4 4 344444 //11111                                                                  A //11112 //11113 //11114 //11122 //11123 //11124 //11133 //11134 //11144 //11222 //11223 //11224 //11233 //11234 //11244 //11333 //11334 //11344 //11444 //12222 //12223 //12224 //12233 //12234 //12244 //12333 //12334 //12344 //12444 //13333 //13334 //13344 //13444 //14444 //22222 //22223 //22224 //22233 //22234 //22244 //22333 //22334 //22344 //22444 //23333 //23334 //23344 //23444 //24444 //33333 //33334 //33344 //33444 //34444 //44444 //共56种， //1到5中选5个数：12345 2345 345 45 5 2345 345 45 5 345 45 5 45 5 5 2345 345 45 5 345 45 5 45 5 5 345 45 5 45 5 5 45 5 5 5  2345 345 45 5 345 45 5 45 5 5 345 45 5 45 5 5 45 5 5 5 345 45 5 45 5 5 45 5 5 5 455555 //11111                                                                                A //11112 //11113 //11114 //11115 //11122 //11123 //11124 //11125 //11133 //11134 //11135 //11144 //11145 //11155 //11222 //11223 //11224 //11225 //11233 //11234 //11235 //11244 //11245 //11255 //11333 //11334 //11335 //11344 //11345 //11355 //11444 //11445 //11455 //11555 //12222 //12223 //12224 //12225 //12233 //12234 //12235 //12244 //12245 //12255 //12333 //12334 //12335 //12344 //12345 //12355 //12444 //12445 //12455 //12555 //13333 //13334 //13335 //13344 //13345 //13355 //13444 //13445 //13455 //13555 //14444 //14445 //14455 //14555 //15555 //22222 //22223 //22224 //22225 //22233 //22234 //22235 //22244 //22245 //22255 //22333 //22334 //22335 //22344 //22345 //22355 //22444 //22445 //22455 //22555 //23333 //23334 //23335 //23344 //23345 //23355 //23444 //23445 //23455 //23555 //24444 //24445 //24455 //24555 //25555 //33333 //33334 //33335 //33344 //33345 //33355 //33444 //33445 //33455 //33555 //34444 //34445 //34455 //34555 //35555 //44444 //44445 //44455 //44555 //45555 //55555 //共126种， //1到6中选5个数：123456 23456 3456 456 56 6 23456 3456 456 56 6 3456 456 56 6 456 56 6 56 6 6 23456 3456 456 56 6 3456 456 56 6 456 56 6 56 6 6 3456 456 56 6 456 56 6 56 6 6 456 56 6 56 6 6 56 6 6 6  23456 3456 456 56 6 3456 456 56 6 456 56 6 56 6 6 3456 456 56 6 456 56 6 56 6 6 456 56 6 56 6 6 56 6 6 6 3456 456 56 6 456 56 6 56 6 6 456 56 6 56 6 6 56 6 6 6 456 56 6 56 6 6 56 6 6 6 566666 //11111                                                                                A //11112 //11113 //11114 //11115 //11116 //11122 //11123 //11124 //11125 //11126 //11133 //11134 //11135 //11136 //11144 //11145 //11146 //11155 //11156 //11166 //11222 //11223 //11224 //11225 //11226 //11233 //11234 //11235 //11236 //11244 //11245 //11246 //11255 //11256 //11266 //11333 //11334 //11335 //11336 //11344 //11345 //11346 //11355 //11356 //11366 //11444 //11445 //11446 //11455 //11456 //11466 //11555 //11556 //11566 //11666 //12222 //12223 //12224 //12225 //12226 //12233 //12234 //12235 //12236 //12244 //12245 //12246 //12255 //12256 //12266 //12333 //12334 //12335 //12336 //12344 //12345 //12346 //12355 //12356 //12366 //12444 //12445 //12446 //12455 //12456 //12466 //12555 //12556 //12566 //12666 //13333 //13334 //13335 //13336 //13344 //13345 //13346 //13355 //13356 //13366 //13444 //13445 //13446 //13455 //13456 //13466 //13555 //13556 //13566 //13666 //14444 //14445 //14446 //14455 //14456 //14466 //14555 //14556 //14566 //14666 //15555 //15556 //15566 //15666 //16666 //22222 //22223 //22224 //22225 //22226 //22233 //22234 //22235 //22236 //22244 //22245 //22246 //22255 //22256 //22266 //22333 //22334 //22335 //22336 //22344 //22345 //22346 //22355 //22356 //22366 //22444 //22445 //22446 //22455 //22456 //22466 //22555 //22556 //22566 //22666 //23333 //23334 //23335 //23336 //23344 //23345 //23346 //23355 //23356 //23366 //23444 //23445 //23446 //23455 //23456 //23466 //23555 //23556 //23566 //23666 //24444 //24445 //24446 //24455 //24456 //24466 //24555 //24556 //24566 //24666 //25555 //25556 //25566 //25666 //26666 //33333 //33334 //33335 //33336 //33344 //33345 //33346 //33355 //33356 //33366 //33444 //33445 //33446 //33455 //33456 //33466 //33555 //33556 //33566 //33666 //34444 //34445 //34446 //34455 //34456 //34466 //34555 //34556 //34566 //34666 //35555 //35556 //35566 //35666 //36666 //44444 //44445 //44446 //44455 //44456 //44466 //44555 //44556 //44566 //44666 //45555 //45556 //45566 //45666 //46666 //55555 //55556 //55566 //55666 //56666 //66666 //共252种， //1到7中选5个数： //…… //从1到n中选5个数，求其非递减序可重复数字的排列的个数 #include <stdio.h> int data[8]; int count(int b) {     int k,r;     r=0;     for (k=0;k<b-2;k++) r+=data[k];     return r; } int sum1to(int m) {     return (1+m)*m/2; } int main() {     int n,t,i,j,d;      data[0]=6;     for (d=1;d<=7;d++) {         t=0;         for (i=d+2;i>=1;i--) {             for (j=i;j>=1;j--) {                 t=t+sum1to(j);             }         }         data[d]=t;     }     while (1) {         printf("Input n(1..9):");fflush(stdout);         rewind(stdin);         scanf("%d",&n);         if (1<=n && n<=9) break;     }     if (n==1) t=1;     else if (n==2) t=data[0];     else if (n>2) t=data[n-2]+count(n);     printf("%d\n",t);     return 0; } //Input n(1..9):1 //1 //Input n(1..9):2 //6 //Input n(1..9):3 //21 //Input n(1..9):4 //56 //Input n(1..9):5 //126 //Input n(1..9):6 //252 //Input n(1..9):7 //462 //Input n(1..9):8 //792 //Input n(1..9):9 //1287 //

n=4时咋办？！

个数就是从n中取5的组合数（C(n, 5)）。  引用 楼主 wxyztuv 的回复:求从1到n中选择5个数，求其非递减序的排列个数，例如，从1到10中，选择5个数，求其非递减序的排列个数，(数字不能重复，例如，123455,是不行的) 请问计算公式是什么，我用递归计算太慢了，当n很大时，例如p(100,5),所以，想知道有没有一个计算公式，可以很快计算出其个数，只需要计算出个数来就OK。

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

引用 10 楼 zhao4zhong1 的回复:1到1中选5个数: 11111 共1种， 1到2中选5个数： 11111 11112 11122 11222 12222 22222 共6种， 1到3中选5个数： 11111 11112 11113 11122 11123 11133 11222 11223 11233 11333 12222 12223 12233 12333 13333 22222 22223 22233 22333 23333 33333 共21种， 1到4中选5个数： ……   我知道这样，我想知道通用的计算公式是什么，例如我想求从1到100中选8个数，用程序遍历求个数太慢了。 问题：从1到n中选m个数，求其非递减序可重复数字的排列的个数

引用 8 楼 turingo 的回复:不需要减才对。  [quote=引用 7 楼 wxyztuv 的回复:] [quote=引用 6 楼 turingo 的回复:] n的5次方左右。  [quote=引用 5 楼 wxyztuv 的回复:] [quote=引用 1 楼 turingo 的回复:] 个数就是从n中取5的组合数（C(n, 5)）。  [quote=引用 楼主 wxyztuv 的回复:] 求从1到n中选择5个数，求其非递减序的排列个数，例如，从1到10中，选择5个数，求其非递减序的排列个数，(数字不能重复，例如，123455,是不行的) 请问计算公式是什么，我用递归计算太慢了，当n很大时，例如p(100,5),所以，想知道有没有一个计算公式，可以很快计算出其个数，只需要计算出个数来就OK。[/quote]  如果可以重复，怎么求，例如，可以是12222,123455等，要求个数，如何求？[/quote][/quote]  我一开始想的是用n^5 减去它的排列，即 n^5 - p(n,5),即 不排序不唯一 减去 不排序唯一，但是结果似乎是错的。[/quote][/quote]  是求可重复数字的非递减序排列，如果不减，那只是求了可重复的排列吧，例如n个中选5个，可重复递减序，12344   12222 是可以的，但是 14333   12354就不行了，因为它们中有数字递减了。如何求？

不需要减才对。  引用 7 楼 wxyztuv 的回复:[quote=引用 6 楼 turingo 的回复:] n的5次方左右。  [quote=引用 5 楼 wxyztuv 的回复:] [quote=引用 1 楼 turingo 的回复:] 个数就是从n中取5的组合数（C(n, 5)）。  [quote=引用 楼主 wxyztuv 的回复:] 求从1到n中选择5个数，求其非递减序的排列个数，例如，从1到10中，选择5个数，求其非递减序的排列个数，(数字不能重复，例如，123455,是不行的) 请问计算公式是什么，我用递归计算太慢了，当n很大时，例如p(100,5),所以，想知道有没有一个计算公式，可以很快计算出其个数，只需要计算出个数来就OK。[/quote]  如果可以重复，怎么求，例如，可以是12222,123455等，要求个数，如何求？[/quote][/quote]  我一开始想的是用n^5 减去它的排列，即 n^5 - p(n,5),即 不排序不唯一 减去 不排序唯一，但是结果似乎是错的。[/quote]

引用 6 楼 turingo 的回复:n的5次方左右。  [quote=引用 5 楼 wxyztuv 的回复:] [quote=引用 1 楼 turingo 的回复:] 个数就是从n中取5的组合数（C(n, 5)）。  [quote=引用 楼主 wxyztuv 的回复:] 求从1到n中选择5个数，求其非递减序的排列个数，例如，从1到10中，选择5个数，求其非递减序的排列个数，(数字不能重复，例如，123455,是不行的) 请问计算公式是什么，我用递归计算太慢了，当n很大时，例如p(100,5),所以，想知道有没有一个计算公式，可以很快计算出其个数，只需要计算出个数来就OK。[/quote]  如果可以重复，怎么求，例如，可以是12222,123455等，要求个数，如何求？[/quote][/quote]  我一开始想的是用n^5 减去它的排列，即 n^5 - p(n,5),即 不排序不唯一 减去 不排序唯一，但是结果似乎是错的。

n的5次方左右。  引用 5 楼 wxyztuv 的回复:[quote=引用 1 楼 turingo 的回复:] 个数就是从n中取5的组合数（C(n, 5)）。  [quote=引用 楼主 wxyztuv 的回复:] 求从1到n中选择5个数，求其非递减序的排列个数，例如，从1到10中，选择5个数，求其非递减序的排列个数，(数字不能重复，例如，123455,是不行的) 请问计算公式是什么，我用递归计算太慢了，当n很大时，例如p(100,5),所以，想知道有没有一个计算公式，可以很快计算出其个数，只需要计算出个数来就OK。[/quote]  如果可以重复，怎么求，例如，可以是12222,123455等，要求个数，如何求？[/quote]

引用 1 楼 turingo 的回复:个数就是从n中取5的组合数（C(n, 5)）。  [quote=引用 楼主 wxyztuv 的回复:] 求从1到n中选择5个数，求其非递减序的排列个数，例如，从1到10中，选择5个数，求其非递减序的排列个数，(数字不能重复，例如，123455,是不行的) 请问计算公式是什么，我用递归计算太慢了，当n很大时，例如p(100,5),所以，想知道有没有一个计算公式，可以很快计算出其个数，只需要计算出个数来就OK。[/quote]  如果可以重复，怎么求，例如，可以是12222,123455等，要求个数，如何求？

求从1到n中选择5个数 的数目是 n*(n-1)*(n-2)*(n-3)*(n-4) 这5个数的递减序只有一个 所以结果是 n*(n-1)*(n-2)*(n-3)*(n-4) - 1

123455 这个数哪里递减了？或者“非递减序”是如何定义的？


Question: 求大神指教一下  must return a value

函数需要返回一个HNODETYPE类型的值，或者你把原型改为void huffmantree(char *s2,char s3[])也可以。  引用 楼主 u013131780 的回复:HNODETYPE huffmantree(char *s2,char s3[]) {     HNODETYPE huffnode[MAXNODE];     HCODETYPE huffcode[MAXLEAF],cd;     int sum,i,j,n1,n2,x1,x2,p,k,c;     char s1[26]={'a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z'};     char s5[MAXLEAF];     int ww[26]={0},n=0;     strcpy( s5,s2);     sum=strlen(s2);     for(i=0;i<26;i++) /*统计所有字符出现的频度*/     for(j=0;j<sum;j++)     if(s2[j]==s1[i]) ww[i]++;     n=strlen(s3);     for (i=0;i<2*n-1;i++) 	{ 		huffnode[i].weight=0;         huffnode[i].parent=-1;         huffnode[i].lchild=-1;         huffnode[i].rchild=-1; 	}     for(i=0;i<n;i++) /*分配给各叶结点权值*/     for(j=0;j<26;j++)     if (s3[i]==s1[j]) huffnode[i].weight=ww[j];     for (i=0;i<n-1;i++) /*构造哈夫曼树*/ 	{ 		n1=n2=MAXVALUE;         x1=x2=0;         for(j=0;j<n+i;j++) 		{  			if (huffnode[j].parent==-1 && huffnode[j].weight<n1) 			{ 				n2=n1;                 x2=x1;                 n1=huffnode[j].weight;                 x1=j;  			}             else             if (huffnode[j].parent==-1 && huffnode[j].weight<n2) 			{ 				 n2=huffnode[j].weight; x2=j;} 		}         huffnode[x1].parent=n+i;         huffnode[x2].parent=n+i;         huffnode[n+i].weight=huffnode[x1].weight+huffnode[x2].weight;         huffnode[n+i].lchild=x1;         huffnode[n+i].rchild=x2; 	}     for(i=0;i<n;i++) /*求每个叶结点的哈夫曼编码*/ 	{   		cd.start=n-1;         c=i;         p=huffnode[c].parent;         while (p!=-1) 		{    			if (huffnode[p].lchild==c)             cd.bit[cd.start]=0;             else             cd.bit[cd.start]=1;             cd.start--;             c=p;             p=huffnode[c].parent; 		}         for (j=cd.start+1;j<n;j++)         huffcode[i].bit[j]=cd.bit[j];         huffcode[i].start=cd.start; 	}     printf(" 各叶结点对应哈夫曼编码 : ");/*输出每个叶结点的哈夫曼编码*/     for(i=0;i<n;i++) 	{   		for(j=huffcode[i].start+1;j<n;j++)         printf("%d",huffcode[i].bit[j]);         printf(" "); 	}     printf("\n 电文的全部哈夫曼编码 : ");/*输出电文的全部哈夫曼编码*/     for(k=0;k<sum;k++)     for(i=0;i<n;i++)     if(s2[k]==s3[i]) 	{   		for(j=huffcode[i].start+1;j<n;j++)         printf("%d",huffcode[i].bit[j]);         printf(" "); 	}     printf("\n"); }  ____ error C4716: 'huffmantree' : must return a value

你的函数没写返回值

//函数需要一个返回值 类型是HNODETYPE HNODETYPE huffmantree(char *s2,char s3[]) {   // do something      return (HNODETPE)RetVal; }


Question: Linux 下这段汇编 的几个疑问

4.看错, 应该是0x8048000

引用 6 楼 slutlifei 的回复:谢谢 zhao4zhong1 高人  gdb单步调试时，可以看到内存和寄存器的变化 你是怎么看到的？ 是使用其他工具的吗  再次 问题3 被高人解决   linux下 info reg可以看到寄存器的值,ni是单步执行 vc 下,有个窗口可以看寄存器

1.上一函数栈顶esp由ebp保存,eax一般用来存返回值或入参,不用保存 2.xor异或 3.调三号中断 4.不是,变长指令每个指令占内存数不一样,好像没有一个字节的指令?~~

int3 是进入调试的中断 在GDB中单步执行，看每步对内存和寄存器的影响。 layout src：显示源代码窗口 layout asm：显示反汇编窗口 layout regs：显示源代码/反汇编和CPU寄存器窗口 layout split：显示源代码和反汇编窗口

这是一段Linux下的汇编哈 我只是把ATT格式改成了INTEL

"我查阅到ebx,ecx,edx,esi和edi一般都是放参数的，那么这段代码只push保存其中3个" 在win下这些参数会从右至左push进栈，这里我没看到，Linux下我不是太熟，不过貌似不会吧eax这种寄存器作为参数吧？，这是什么函数调用的汇编？

非常感谢Ipcads 的热心回答 问题3,4还需等待高手解答  再加问一下问题1  你讲的eax,esp我明白了 我查阅到ebx,ecx,edx,esi和edi一般都是放参数的，那么这段代码只push保存其中3个， 后面ecx和edx为啥不保存，xor为啥也只有3个 不应该把这5个全赋0了再用？  eip好像是要指向正在运行指令的下一条，不是很清楚，但是不知为何这种情况下好像eip=0x8048002

1 eax属于“易失存储器”，由于最后要放函数返回值，pop eax 无意义；4个pop后，esp 自动恢复，无需保存。 2 没错 3 调用3号中断（虽然我不知道3号具体是干嘛的） 4 不清楚，我还一直觉得是 0x8048000 。待大侠解答。


Question: 简单的C语言问题，虚心求教

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

return((n<1||n>7) ? name[0] : name[n]);  n=1 时(n<1||n>7)为flase 返回的是name[n]即name[1]的内容，对应的字符串是Monday

static char *name[] 说明name是一个数组，数组的每个成员都是char *，即字符串指针 name[0]对应字符串 "Illegal day" 的首地址 name[1]对应字符串 "Monday" 的首地址

指针即地址。只是输出的时候你%s输出会从指针指向的地址输出那段连续的内存里面的字符

你的函数定义char* dayname()不就是说明返回一个指向char类型的指针吗？ 只是dayname[1]指向monday字符串的地址。

返回的是指向monday的指针，这个指针就表示这个字符串， 用%s输出的时候，一次输出一串

返回的就是指针，你理解的没错。字符串本身也可以理解成一个字符指针


Question: 新人求助（面试题）  局部变量地址问题

引用 12 楼 zmlovelx 的回复:藏在深闺中的妹纸，如果带不出来就想泡很难。 变量也一样。

返回了局部变量的地址，局部变量在函数结束时就消失了，因此对这个返回的地址进行操作是很危险的。 怎么改正：不要写这种无聊的代码。

局部变量不能作为返回值返回，你研究下变量的作用于和生存周期就明白了

引用 4 楼 max_min_ 的回复:1 传参代替 2 自己分配堆内存 3 static也可以 static刚看了这一章节，举个栗子： unsigned char * func(){  static unsigned char i = 0；         ++i;         return &i;  } 这就搞定了。

如果没有被擦初，有可能能访问，但是不安全...菜鸟...请勿拍砖...

这题是考static

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

局部变量离开块作用域{}生命期就结束了。

引用 17 楼 derekrose 的回复:使用智能指针 顶楼上 返回的函数指针封装进对象里，然后将释放写入析构函数。。然后对象的周期到了的时候，析构函数就会被调用，再然后那指针就被释放咯。。。好像智能指针就是这么搞的。

使用智能指针

这是作业题吧？

感觉有点像 函数的返回值是个指针   嗯。在函数调用结束后，局部变量所占的内存被释放，虽然地址还在，只是地址里的内容就不好说了。。

引用 10 楼 u012982053 的回复: 返回局部变量的地址值，但是这个地址指向的内容不能被操作，因为内存已经被释放 把最后句改为 因为内存已经不可预知咯。这样应该对了吧？

以前一直以为不能使用， 原来还是能用嘛。就说。某个地址值指向的内存应该是固定的，还是能访问的。就是。。不可预知。

藏在深闺中的妹纸，如果带不出来就想泡很难。 变量也一样。

囧 刚刚没事去测试了下。。。发现能访问返回的地址 是否是因为系统不会擦除此地址指向的内存，只有当此内存再次被使用时，会被新的内容覆盖。这函数写出来 编译器会发出警告的， 说返回一个局部变量的地址。此内存不应该被这样使用，因为系统很可能将他分配给其他变量使用，这是一个不可预知的值。。。

返回局部变量的地址值，但是这个地址指向的内容不能被操作，因为内存已经被释放

局部变量不能将数据返回，想办法把局部变量的地址改成其他地方的地址，比如堆上的（malloc)、数据段上的（static，或全局变量）。

又是作业题吧

引用 4 楼 max_min_ 的回复:1 传参代替 2 自己分配堆内存 3 static也可以++1


Question: 新手求教关于C语言程序运行，我们研究室的人都倒下了

请问楼主，这个可以用win系统运行吗？

小日本无奈的说了一句，不愧是中国人

引用 12 楼 turingo 的回复:抗日成功！  引用 11 楼 u013130285 的回复:搞定了，谢谢各位大哥

抗日成功！  引用 11 楼 u013130285 的回复:搞定了，谢谢各位大哥

搞定了，谢谢各位大哥

./mcxyz

运行的时候，需要这样写：  ./mcxyz example1  引用 8 楼 u013130285 的回复:在linux系统上运行了下，  输入   gcc mcxyz.c -lm -o mcxyz  出现了一个mcxyz的文件    然后输入  mcxyz example1  发生错误 bash: mcxyz: command没有找到（就是那句日语）  求解答 我们研究室都是学生物和光学的，他们日本人都不会，哪位大侠搞定他啊。以后好让我尽情鄙视日本人  上图  [quote=引用 7 楼 turingo 的回复:] 已经很详细了，用gcc就一条命令就可以了啊：  gcc mcxyz.c -lm -o mcxyz   你也可以用VC/Code::Blocks/DevC++等编译器编译，都是相当的简单。   [quote=引用 4 楼 u013130285 的回复:] 对不起不是很清楚怎么直接编译，能说得具体点吗，有个图什么最好了 拜托了，要不加我QQ？  [quote=引用 3 楼 turingo 的回复:] 直接编译就可以了：  gcc mcxyz.c -lm -o mcxyz   运行maketissue.m (MATLAB)生成所需的(myname_T.bin, myname_H.mci)文件。 然后执行如下命令即可：  mcxyz myname    [quote=引用 楼主 u013130285 的回复:] 新手求教关于C语言程序运行，我们研究室的人都倒下了  压缩包里有mcxyz.c myname_H.mci 和myname_T.bin 3个文件 执行mcxyz.c读取myname_H.mci 和myname_T.bin，然后生成myname_F.bin文件  试行后发生错误，感觉myname_H.mci 和myname_T.bin文件好像没被读取。各种泪奔  求大牛联系，qq4731117  程序是关于光传播解析的，从美国大学的网站上找来的 http://omlc.ogi.edu/software/mc/mcxyz/index.html[/quote][/quote][/quote][/quote]

在linux系统上运行了下，  输入   gcc mcxyz.c -lm -o mcxyz  出现了一个mcxyz的文件    然后输入  mcxyz example1  发生错误 bash: mcxyz: command没有找到（就是那句日语）  求解答   我们研究室都是学生物和光学的，他们日本人都不会，哪位大侠搞定他啊。以后好让我尽情鄙视日本人  上图  引用 7 楼 turingo 的回复:已经很详细了，用gcc就一条命令就可以了啊：  gcc mcxyz.c -lm -o mcxyz   你也可以用VC/Code::Blocks/DevC++等编译器编译，都是相当的简单。   [quote=引用 4 楼 u013130285 的回复:] 对不起不是很清楚怎么直接编译，能说得具体点吗，有个图什么最好了 拜托了，要不加我QQ？  [quote=引用 3 楼 turingo 的回复:] 直接编译就可以了：  gcc mcxyz.c -lm -o mcxyz   运行maketissue.m (MATLAB)生成所需的(myname_T.bin, myname_H.mci)文件。 然后执行如下命令即可：  mcxyz myname    [quote=引用 楼主 u013130285 的回复:] 新手求教关于C语言程序运行，我们研究室的人都倒下了  压缩包里有mcxyz.c myname_H.mci 和myname_T.bin 3个文件 执行mcxyz.c读取myname_H.mci 和myname_T.bin，然后生成myname_F.bin文件  试行后发生错误，感觉myname_H.mci 和myname_T.bin文件好像没被读取。各种泪奔  求大牛联系，qq4731117  程序是关于光传播解析的，从美国大学的网站上找来的 http://omlc.ogi.edu/software/mc/mcxyz/index.html[/quote][/quote][/quote]

已经很详细了，用gcc就一条命令就可以了啊：  gcc mcxyz.c -lm -o mcxyz   你也可以用VC/Code::Blocks/DevC++等编译器编译，都是相当的简单。   引用 4 楼 u013130285 的回复:对不起不是很清楚怎么直接编译，能说得具体点吗，有个图什么最好了 拜托了，要不加我QQ？  [quote=引用 3 楼 turingo 的回复:] 直接编译就可以了：  gcc mcxyz.c -lm -o mcxyz   运行maketissue.m (MATLAB)生成所需的(myname_T.bin, myname_H.mci)文件。 然后执行如下命令即可：  mcxyz myname    [quote=引用 楼主 u013130285 的回复:] 新手求教关于C语言程序运行，我们研究室的人都倒下了  压缩包里有mcxyz.c myname_H.mci 和myname_T.bin 3个文件 执行mcxyz.c读取myname_H.mci 和myname_T.bin，然后生成myname_F.bin文件  试行后发生错误，感觉myname_H.mci 和myname_T.bin文件好像没被读取。各种泪奔  求大牛联系，qq4731117  程序是关于光传播解析的，从美国大学的网站上找来的 http://omlc.ogi.edu/software/mc/mcxyz/index.html[/quote][/quote]

引用 楼主 u013130285 的回复:新手求教关于C语言程序运行，我们研究室的人都倒下了  压缩包里有mcxyz.c myname_H.mci 和myname_T.bin 3个文件 执行mcxyz.c读取myname_H.mci 和myname_T.bin，然后生成myname_F.bin文件  试行后发生错误，感觉myname_H.mci 和myname_T.bin文件好像没被读取。各种泪奔  求大牛联系，qq4731117  程序是关于光传播解析的，从美国大学的网站上找来的 http://omlc.ogi.edu/software/mc/mcxyz/index.html  擦，那个网站说的那么详细，还跑到这边来问，岂不是舍近求远嘛

自己顶下，在线等回复

对不起不是很清楚怎么直接编译，能说得具体点吗，有个图什么最好了 拜托了，要不加我QQ？  引用 3 楼 turingo 的回复:直接编译就可以了：  gcc mcxyz.c -lm -o mcxyz   运行maketissue.m (MATLAB)生成所需的(myname_T.bin, myname_H.mci)文件。 然后执行如下命令即可：  mcxyz myname    [quote=引用 楼主 u013130285 的回复:] 新手求教关于C语言程序运行，我们研究室的人都倒下了  压缩包里有mcxyz.c myname_H.mci 和myname_T.bin 3个文件 执行mcxyz.c读取myname_H.mci 和myname_T.bin，然后生成myname_F.bin文件  试行后发生错误，感觉myname_H.mci 和myname_T.bin文件好像没被读取。各种泪奔  求大牛联系，qq4731117  程序是关于光传播解析的，从美国大学的网站上找来的 http://omlc.ogi.edu/software/mc/mcxyz/index.html[/quote]

直接编译就可以了：  gcc mcxyz.c -lm -o mcxyz   运行maketissue.m (MATLAB)生成所需的(myname_T.bin, myname_H.mci)文件。 然后执行如下命令即可：  mcxyz myname  引用 楼主 u013130285 的回复:新手求教关于C语言程序运行，我们研究室的人都倒下了  压缩包里有mcxyz.c myname_H.mci 和myname_T.bin 3个文件 执行mcxyz.c读取myname_H.mci 和myname_T.bin，然后生成myname_F.bin文件  试行后发生错误，感觉myname_H.mci 和myname_T.bin文件好像没被读取。各种泪奔  求大牛联系，qq4731117  程序是关于光传播解析的，从美国大学的网站上找来的 http://omlc.ogi.edu/software/mc/mcxyz/index.html

新手中的新手啊，不会写Demo啊，星期一才开始学C语言的。。。。 大侠您能留个qq来救救我吗...

自己写个demo测试下呗！  检查下文件操作的api是否都成功调用了！ 把读出来的内容在 内存中尽量对应解析一部分打印出来瞧瞧！确认正确数据了再向新的文件中写


Question: 关于指针的+1操作的问题

引用 4 楼 max_min_ 的回复: //不管数组多长，这都是相差一个指针的长度的！ char *c[2] = {"1111111","22222222222"};  char *c1 = "1111111"; char *c2 = "22222222222"; 一针见血！我懂了版主~谢谢！

引用 2 楼 user-3 的回复:sizeof(char*)==4 这肯定是没问题的。

指针：32位机器上为4个字节

@ max_min_


Question: 关于对多维指针定义方法的疑问？？

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

差别可大了，数据类型就不同

引用 楼主 tyy_wjt 的回复:		 #if 0 char *str1[]={{'a','b','4'},{'c','d','x'}}; //错误，字符指针数组，只能用字符串初始化！ //      指针数组，和二维字符数组，不完全等价 //      {{'a','b','4'},{'c','d','x'}} //      只能匹配，嵌套结构，结构数组，嵌入一维数组的结构，和二维字符数组。 //      不能匹配，指针数组。            #endif  正确的格式如下 char *str1[]={"ab4","cdx"};  /***********************************************/ 	char (*str1)[3]; 	char str[2][3]={{'a','b','4'},{'c','d','x'}};//正确，数组，可以用常量组合初始化。                      //因为，{。。。。} 可以表示,struct 和数组                      //两种不同结构的数据，所以不可单独用来初始化指针数组。                      //二维字符数组，由于可以和常量组合匹配，所以没问题。                      //匹配以后，该常量组合，被认为是，二维字符数组常量。              	str1 = str; //正确，一维字符数组的指针，可以和二维字符数组匹配。  上面两种对str1的定义有什么不同吗？为啥第一种只是一个指向a的指针,第二个却是一个指针数组？？？ 上面两种对str1的定义有什么不同吗？ 第一种，定义指针的数组。 * 和 char 组合成一个类型，char* （字符指针）然后，和str1[]组合成字符指针数组 str1 指针变量类型的数据的数组。  第二种，定义数组的指针。 char 和[3] 组成 字符数组； char [3] 然后和（*str1）结合；  其中str1是变量 所以是和（*） 结合成数组的指针。 str1 是 char 类型数组的指针。 指针家括号后，类型和数组先结合，构成数组，在和指针结合，构成数组的指针。  char * str1 相当于(char*)[]str1; char *[]str1;  char (*str1)[3] 相当于 char [3] *str1;(char [3]) *str1;

第一个不可能编译的过，它表示一个存储char *的一维数组，而你初始化传入的值却是二维数组。  第二个，指针存储了一个char [3]数组的地址，char [2][3]是一个二维数组，每个元素是char [3]，数组名str是第一个元素的地址，也就是第一个char[3]的地址，所以可以存到str1指针里。

第一种方式是str1定义了一个指针数组，第二种方式是str1定义了一个数组指针； char *str1[]={"ab4","cdx"};应该是这样定义。char*指针指向的应该是字符串吧。

可以用字符串，初始化指针； 不可用 字符数组常量（没有这种常量，只有字符常量组合，字符串两种），初始化指针。


Question: scanf会改变数组长度？？？

引用 6 楼 lineage191 的回复:研究一种明知道错误的写法实在无意义， 还有楼主不要把自己的本性暴漏出来啊，写个数组都带色情的，数组名：Sex， 理解你的人知道是性别，不理解的还以为你性骚扰呢 char str[3] = "123"; 倒不算是错误  只是不能当C风格字符串使用罢了  和 char str[3] = {'1','2', '3'}; 是一样的

研究一种明知道错误的写法实在无意义， 还有楼主不要把自己的本性暴漏出来啊，写个数组都带色情的，数组名：Sex， 理解你的人知道是性别，不理解的还以为你性骚扰呢  引用 1 楼 lin5161678 的回复:char sex[3]="234"; 你的 sex 不能用str系列函数了  没 \0 引用 4 楼 missheaven2011 的回复:scanf("%6s",sex); 输入时不能大于2 因为字符串char sex[3]，申请的内存大小为3，除去结束符，只有两个字符可以保存 输入过大导致越界

strlen不能用来计算数组长度，它用于计算输入的指针到下一个'\0'有几个字符 c++对于类型检查比c严格得多，虽然不管在c还是在c++中，楼主的写法都是错误的

在c语言中数组的长度这个概念其实不存在

引用 1 楼 lin5161678 的回复:char sex[3]="234"; 你的 sex 不能用str系列函数了  没 \0可是我把sex[3]="23"; 也是一样的结果,数组长度改变了。。。。  还有是不是c++更严格？sex[3]="232"      用gcc可以编译,用g++会报错


Question: 为什么按y后又执行了一遍循环

引用 9 楼 qq921965140 的回复:[quote=引用 8 楼 oOo532200 的回复:] 使用getchar（）的问题，debug一下就知道了，你用的什么IDE，版本是多少。 把getchar（）改成_getch()，添加#include <conio.h>非标准C库。就欧克了 引用 8 楼 oOo532200 的回复:使用getchar（）的问题，debug一下就知道了，你用的什么IDE，版本是多少。 把getchar（）改成_getch()，添加#include <conio.h>非标准C库。就欧克了我水平很渣，你们说的太高深了[/quote] 这不是水平问题,方法其实很多种

引用 8 楼 oOo532200 的回复:使用getchar（）的问题，debug一下就知道了，你用的什么IDE，版本是多少。 把getchar（）改成_getch()，添加#include <conio.h>非标准C库。就欧克了 引用 8 楼 oOo532200 的回复:使用getchar（）的问题，debug一下就知道了，你用的什么IDE，版本是多少。 把getchar（）改成_getch()，添加#include <conio.h>非标准C库。就欧克了我水平很渣，你们说的太高深了

引用 2 楼 qq921965140 的回复:引用 1 楼 derekrose 的回复:自己debug我来问题，能好好回答吗  这就是认真的回答，不能每次都让人帮你debug，debug之后还不能解决问题再来问

引用 4 楼 tao346995926 的回复:这个程序有问题，scanf之后应该加个去除回车符十分谢谢提醒，我想起来啦！用这个scanf("%d%*c",&v);。吃掉回车。

引用 3 楼 user-4 的回复:scanf("%d",&v); 这句语句结束后还有一个 '\n'在输入缓冲区内 ch=getchar(); 第一次获取了 缓冲区内的 '\n'，即ch 值为 '\n' 不满足 if(ch=='y') 再次循环  可以将 scanf("%d",&v); 改为 scanf("%d",&v); getchar();十分谢谢提醒，我想起来啦！用这个scanf("%d%*c",&v);。吃掉回车。

这个程序有问题，scanf之后应该加个去除回车符

引用 1 楼 derekrose 的回复:自己debug我来问题，能好好回答吗

自己debug


Question: CTime，CSpantime ，CArray，CString替代类

名字打错了。。

worldly： 1，请问你有过类似的操作吗？ 2，就拿CTime类来说，是用不依赖于MFC类库的C++代码实现的吗？还是说该类的实现过程中也是用了其他的MFC类。 3，这个问题比较蠢。。。如何获得源码啊，我右键转到定义只能打开相应的头文件，找不到类的具体实现源码啊？  灰常感谢!!!!

最简单的办法是，去掉原来的include的文件， 将mfc的那几个类的源码拷贝到一个新建的头文件中，include入你自己的头文件，这样代码都不用改了

灰常感谢，我查了一些资料也是这么说的

CTime，CSpantime 直接用标准C的time_t应该问题不大 CArray -> std::vector CString -> std::string


Question: C里不能使用__m128i类型吗

不支持。。。。

看样子，像是intel编译器的关键字。

那个是特定编译器才支持的特性吧？你看看你用的编译器是不是支持那个关键字。


引用 楼主 fcpplo 的回复:刚开始学习C语言，用的是谭浩强的第四版 课后有个习题做了一下，但是用如下语言始终不对，代码如下 #include <stdio.h> int main() { 	int max(int x, int y,int z); 	int a, b, c, m; 	scanf("%d%d%d", &a, &b, &c); 	m = max(a, b, c); 	printf("max=%d", m); 	return 0; } int max(int x, int y, int z) { 	int n; 	if (x > y&&x > z) n = x; 	else  	if (y > x&&y > z) n = y; 	else n = z; 	return(n); } 输入2，3，4   输出是max=2 然后找来找去，把 scanf("%d%d%d", &a, &b, &c); 改成了 scanf("%d,%d,%d", &a, &b, &c); 然后答案正确了，这是为什么啊，难道这个必须加逗号？与后面的对应么  我看谭浩强老师的书上都是不带逗号的 敢不敢换本书?如果我去大学上课，第一件事就是让学生把和谭浩强相关的东西丢进厕所

输入为1,2,3  用scanf("%d,%d,%d",&a,&b,&c); 因为在测试的时候输入了逗号，如果不加逗号，就无法匹配你输入的值和变量。 或者换上%c scanf("%d%c%d%c%d",&a,&c1,&b,&c2,&c);

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

scanf和printf都属于格式化的I/O. scanf("%d;%d;%d", &a, &b, &c);//读取的时候用分号隔开，输入的时候就必须用分号隔开 格式化...格式化...

什么都不加应该是可以的，但具体要看题目的要求

最好的办法是什么都不加。 %d%d%d

2，3，4  ==>scanf("%d,%d,%d", &a, &b, &c); 2 3 4    ==>scanf("%d%d%d", &a, &b, &c);

这应该是取决于编译器的设计吧，如果要用原本的写法 scanf("%d%d%d", &a, &b, &c);，在输入的时候用空白隔开就好。

之间换成空格也行，什么都不加貌似一直都不行


Question: 急急急！有没有人用过mplayer

mplayer是没有图形界面的，后面得给出要播放的文件名。

搜该软件的安装教程吧。


Question: 求助家谱处理程序

不用树也可以。。。 我写的：http://blog.csdn.net/u014801032/article/details/25797033

非常简单的例子 看看 http://cse222.wikispaces.com/Binary+Tree,+Example+beginning+C+code

tree+search+parse text

参考《算法精解（C语言实现）》里面有关树的章节。

引用 1 楼 zhao4zhong1 的回复:树 我知道是用树，但是不知道怎么写啊。不会程序

树


Question: 迷途指针

delete指针后，只是告诉系统，你这个指针没有关系了，但是指针的内容还是指向那块内存的，所以平时操作delete p; p = NULL;   但是还是调用p的话，那块内存可能被其他程序调用，也可能被系统调用，也可能空置在那...那块内存已经不属于你，结果...  愚见

其实电脑开机后物理内存的每个字节都是可读写的，区别仅在于操作系统内存管理模块在你读写时是否能发现并是否采取相应动作而已。操作系统管理内存的粒度不是字节而是页，一页通常为4KB。  崩溃的时候在弹出的对话框按相应按钮进入调试，按Alt+7键查看Call Stack里面从上到下列出的对应从里层到外层的函数调用历史。双击某一行可将光标定位到此次调用的源代码或汇编指令处。

引用 2 楼 ysmz4 的回复:[quote=引用 1 楼 user-3 的回复:] 属于未定义的行为，深究无益 需要什么定义？给个例子吧[/quote]  http://cn.bing.com/search?q=undefined+behavior+c%2B%2B&go=&qs=AS&form=QBLH&pq=undefined+behavior+c%2B%2B&sc=0-12&sp=1&sk=

引用 1 楼 user-3 的回复:属于未定义的行为，深究无益 需要什么定义？给个例子吧

属于未定义的行为，深究无益


Question: 逻辑简单但是超长函数的优化

引用 11 楼 zhao4zhong1 的回复:透露一个看Release版对应汇编指令的绝招，一般人我不告诉他： 临时在要看对应汇编指令的地方加一句DebugBreak();或__asm int 3 然后在VS IDE里面运行，停在加的那句时，按Alt+8打开汇编窗口。

引用 9 楼 Liu_peiqi 的回复:[quote=引用 7 楼 zhao4zhong1 的回复:] 听鄙人的，不要做任何改动，Release版编译器会优化的不能再优化的。 不信可以看Release版对应的汇编指令，肯定是用跳转表的方法。正在编译，看看情况，先谢赵老师[/quote]好像是这个样子的，指令一会儿就跳出函数了。。。。。。。看来我是想多了。

引用 7 楼 zhao4zhong1 的回复:听鄙人的，不要做任何改动，Release版编译器会优化的不能再优化的。 不信可以看Release版对应的汇编指令，肯定是用跳转表的方法。正在编译，看看情况，先谢赵老师

对学习编程者的忠告： 眼过千遍不如手过一遍！ 书看千行不如手敲一行！ 手敲千行不如单步一行！ 单步源代码千行不如单步对应Debug版汇编一行！ 单步Debug版汇编千行不如单步对应Release版汇编一行！

这种结构明显应该用查表的方法，用数组和下标进行操作。  引用 楼主 Liu_peiqi 的回复:我遇到一个取值函数，逻辑特简单，全部函数内容就是一个switch case结构，每个case平均也3行代码，因为代码很长很长（平均3000行）我就简化如下：  int getModValue( int witchValue, int *value) {     switch(witchValue)     {     case MOD1ST:         *value=mod->MOD1STval;         break;     case MOD2ED:         *value=mod->MOD2EDval;         break;     //几千行这样的代码.....     default:         return ERROR;         break;     }     return NO_ERROR; } 函数很长，但是只有那么一点点功能，上层一般会调用300次左右。请问大神们，这种函数有优化的可能吗？现在程序对性能很敏感的。。。 。。。

引用 4 楼 Liu_peiqi 的回复:[quote=引用 2 楼 mujiok2003 的回复:] [quote=引用 1 楼 wangdahu888 的回复:] 做个table对应不行嘛  表驱动。[/quote]与取值对应的函数还有赋值函数 int setValue (int witchVal, int val) {     switch(witchVal)     {      case MOD1ST:         mod->MOD1STval = val;         mod->MOD1SThaveVal = TRUE;         break; //*****************************     }     renture NO_ERROR; } haveVal是结构体mod定义的位，unsigned MOD1SThaveVal:1; 这样的话怎么设计比较好？是把val和haveVal绑定一个结构体（这样的话，因为有字节对齐，要浪费不少内存），还是独立维护两个表（项目很多，万一没对准，就跪了。。。。。），还是请大神指点[/quote]  不连续的问题这么解决：   int modes[4] = {3,4, 9, 5}; //不重复 typedef int (*OP)(Mode*); OP ops[4] = {....}; //与modes对应 int index = std::find(modes,modes+4, your_mode) - modes;  your_value = ops[index](mod);

引用 2 楼 mujiok2003 的回复:[quote=引用 1 楼 wangdahu888 的回复:] 做个table对应不行嘛  表驱动。[/quote]与取值对应的函数还有赋值函数 int setValue (int witchVal, int val) {     switch(witchVal)     {      case MOD1ST:         mod->MOD1STval = val;         mod->MOD1SThaveVal = TRUE;         break; //*****************************     }     renture NO_ERROR; } haveVal是结构体mod定义的位，unsigned MOD1SThaveVal:1; 这样的话怎么设计比较好？是把val和haveVal绑定一个结构体（这样的话，因为有字节对齐，要浪费不少内存），还是独立维护两个表（项目很多，万一没对准，就跪了。。。。。），还是请大神指点

引用 楼主 Liu_peiqi 的回复:我遇到一个取值函数，逻辑特简单，全部函数内容就是一个switch case结构，每个case平均也3行代码，因为代码很长很长（平均3000行）我就简化如下：  int getModValue( int witchValue, int *value) {     switch(witchValue)     {     case MOD1ST:         *value=mod->MOD1STval;         break;     case MOD2ED:         *value=mod->MOD2EDval;         break;     //几千行这样的代码.....     default:         return ERROR;         break;     }     return NO_ERROR; } 函数很长，但是只有那么一点点功能，上层一般会调用300次左右。请问大神们，这种函数有优化的可能吗？现在程序对性能很敏感的。。。 。。。有时候因为种种原因，casee标签的序号会发生变化，有时候也不连续。。。。。

引用 1 楼 wangdahu888 的回复:做个table对应不行嘛  表驱动。

做个table对应不行嘛


Question: 关于C函数指针和可变参数函数问题

不懂，所以我瞎说 int test_func(int a,  void* b) 中间明确加上 __cdecl 试试

gdb


Question: 请教大神这个习题哪里不对

非常有用，谢谢。我明白了

那应该如何修改呢？谢谢

main() { char c1,c2; int i1, i2 printf("请输入你需要表示的整数值；\n"); scanf("%d, %d", &i1, &i2); c1 = i1; c2 = i2; printf(" 输出整数对应的字符: \n"); printf("%d对应的字符是：%c\n", c1, c1); printf("%d对应的字符是：%c\n", c2, c2);  }

字符char应该用%c格式，否则结果难料。  引用 楼主 kenny83915 的回复:我是按照书上的习题在Dev-C++上做的，源代码如下： #include<stdio.h> main() { 	char c1,c2; 	printf("请输入你需要表示的整数值；\n"); 	scanf("%d, %d", &c1, &c2); 	printf(" 输出整数对应的字符: \n"); 	printf("%d对应的字符是：%c\n", c1, c1); 	printf("%d对应的字符是：%c\n", c2, c2); 	 } 运行下来这个结果只能显示一个整数值的字符，另外一个显示为o，不清楚是怎么回事，还请大神帮我解答，谢谢


Question: C语言中的MACRO宏的用法

谢谢楼上的各位哦，我最后采取的 函数指针的方式 写了一个类似面向对象的 return value的函数

你准备一个数组装3个函数指针，指定0,1,2作为下标，然后去比较不就是了，运行期的问题怎么还整出个宏来。  typedef int (*compare_function)(struct test *l, struct test *r); compare_function funcs[3];

比较函数传递一个index 参数就可以了。  这样，很多库函数，就不能直接用了。 不过，C链表也没有库函数，可以排序；  所以直接写个用三参数比较的排序函数就行了，  比较用三参数比较，两个节点一个索引。  排序多传递一个，索引值参数，就行了。

你还不如这样：  struct test {   int data[3];   struct test* next; };

宏在这里不行的！在预编译器就已经替换了的！ 这里最好用联合体，动态的决定用那个！完全没有必要定义三个！

运行期要想修改编译期的变量值的话，请将编译和运行放在一个循环批处理中。

用宏肯定不行，因为宏是固定的，不会随着输入而变化，你可以增加一个： int sort(TEST* this, int field) 这样的函数，其中field就是排序所依据的域。  引用 楼主 soul376 的回复:本人在写一个struct的链表类型结构的排序程序，遇到了一下疑惑 我的struct结构如下：  struct test{ int a; int b; int c; struct test *next; }  typedef struct test Test  int main(void){     Test myStruct; }    此时我希望给用户一个选择，如果输入0就通过比较a成员来排序，如果输入1就通过比较b成员来排序，如果输入2就通过比较c成员来排序  目前我的方法是比较麻烦的写了三个不同的比较function，然后做成函数指针 每个函数分别三个不同的成员变量之差  小弟想问的是没有没方法能给根据条件来#define OBJECT 如果用户输入0 就#define OBJECT a 输入1 就 #define OBJECT b 输入2 就 #define OBJECT c   这样就只需要写一个比较function，return ( (myStruct->OBJECT) - (myStruct->OBJECT) ) 就好了

#define 是预编译  也就是说，程序运行的时候，已经确定了 所以不能用它


Question: 简单问题求各种解

#include <stdio.h>  int main(int argc, char* argv[]) { 	char str[4]; 	int i;  	for(i = 0; i < 6; i++) 	{ 		sprintf(str, "%03d", i + 1); 		printf("%s\n", str); 	}  	return 0; }  引用 楼主 wangjian617765 的回复:CString  str; str = "001"; for(int i=0; i<6; i++) {     ...... }  输出结果： 当i=0时　　　str="001"; 当i=1时　　　str="002"; 当i=2时　　　str="003"; 当i=3时　　　str="004"; 当i=4时　　　str="005"; 当i=5时　　　str="006"

sprintf(buf, "00%d", i+1);


Question: c语言如何用return返回一个数组，并输出，，程序如下

不太理解你说的返回数组是什么意思？我的理解是要么你的数组在main()函数里面定义好作为参数传入调用的子函数；要么在子函数里面使用动态内存分配返回这个内存的首地址。这个代码中的数组b[2]是一个局部变量，局部变量是被存于栈中，在调用这个子函数的时候分配内存，一旦调用完就会被擦除。所以你的输出有点问题。

b[3]在函数结束时就释放掉了内存了  你可以加一个参数 数组 用来接收要的结果 也可以全局数组来接收

b是个局部变量 不能这么干的

不能返回数组


Question: 想请教一个关于头文件中函数申明与编译时是怎样寻找函数定义的问题？

这是链接器的事情 将所有的obj lib 一起进行链接操作。

《Windows PE权威指南》

Windows下使用 dumpbin.exe /EXPORTS xxx.dll dumpbin.exe /EXPORTS xxx.lib 查看xxx.dll和xxx.lib文件中都导出了哪些函数。

dll 导出函数名的那些事 关键字：　VC++ 　DLL  导出函数　 经常使用VC6的Dependency查看DLL导出函数的名字，会发现有DLL导出函数的名字有时大不相同，导致不同的原因大多是和编译DLL时候指定DLL导出函数的界定符有关系。 VC++支持两种语言：即C/C++，这也是造成DLL导出函数差异的根源 我们用VS2008新建个DLL工程，工程名为"TestDLL" 把默认的源文件后缀 .CPP改为.C（C文件） 输入测试代码如下： 01 int _stdcall MyFunction(int iVariant) 02 { 03 return 0; 04 } 为了导出上面这个函数，我们有以下几个方法： 1. 使用传统的模块定义文件 (.def) 新建一个 后缀为.def的文本文件(这里建一个TestDll.Def)，文件内容为： LIBRARY TestDll EXPORTS MyFunction 在 Link 时指定输入依赖文件：/DEF:"TestDll.Def" 2. Visual C++ 提供的方便方法 在01行的int 前加入 __declspec(dllexport) 关键字 通过以上两种方法，我们就可以导出MyFunction函数。 我们用Dependency查看导出的函数： 第一种方法导出的函数为： MyFunction 第二种方法导出的函数为： _MyFunction@4 __stdcall会使导出函数名字前面加一个下划线，后面加一个@再加上参数的字节数，比如_MyFunction@4的参数（int iVariant）就是4个字节 __fastcall与 __stdcall类似，不过前面没有下划线，而是一个@，比如@MyFunction@4 __cdecl则是始函数名。 小结：如果要导出C文件中的函数，并且不让编译器改动函数名，用def文件导出函数。 下面我们来看一下C++文件 我们用VS2008新建个DLL工程，工程名为"TestDLL" 默认的源文件后缀为 .CPP （即C++文件）。 输入测试代码如下： 01 int _stdcall MyFunction(int iVariant) 02 { 03 return 0; 04 } 为了导出上面这个函数，我们有以下几个方法： 3. 使用传统的模块定义文件 (.def) 新建一个 后缀为.def的文本文件(这里建一个TestDll.Def)，文件内容为： LIBRARY TestDll EXPORTS MyFunction 在 Link 时指定输入依赖文件：/DEF:"TestDll.Def" 4. Visual C++ 提供的方便方法 在01行的int 前加入 __declspec(dllexport) 关键字 通过以上两种方法，我们就可以导出MyFunction函数。 我们用Dependency查看导出的函数： 第一种方法导出的函数为： MyFunction 第二种方法导出的函数为： ?MyFunction@@YGHH@Z 可以看到 第二种方法得到的 导出函数名 并不是我们想要的，如果在exe中用显示方法（LoadLibrary、GetProcAddress）调用 MyFunction 肯定会失败。 但是用引入库(*.LIB)的方式调用，则编译器自动处理转换函数名，所以总是没有问题。 解决这个问题的方法是： 用VC 提供的预处理指示符 "#pragma" 来指定链接选项。 如下： #pragma comment(linker, "/EXPORT:MyFunction=?MyFunction@@YGHH@Z") 这时，就会发现导出的函数名字表中已经有了我们想要的MyFunction。但我们发现原来的那个 ?MyFunction@@YGHH@Z 函数还在，这时就可以把 __declspec() 修饰去掉，只需要 pragma 指令即可。 而且还可以使如下形式： #pragma comment(linker, "/EXPORT:MyFunction=_MyFunction@4,PRIVATE") PRIVATE 的作用与其在 def 文件中的作用一样。更多的#pragram请查看MSDN。 小结：如果要导出C++文件中的函数，并且不让编译器改动函数名，用def文件导出函数。 同时可以用#pragma指令（C 中也可以用）。 总结： C++编译器在生成DLL时，会对导出的函数进行名字改编，并且不同的编译器使用的改编规则不一样，因此改编后的名字也是不同的（一般涉及到C++ 中的重载等）。 如果利用不同编译器分别生成DLL和访问DLL的exe程序，后者在访问该DLL的导出函数时就会出现问题。如上例中函数MyFunction在C++编译器改编后的名字是?MyFunction@@YGHH@Z。我们希望编译后的名字不发生改变，这里有几种方法。 第一种方法是通过一个称为模块定义文件DEF来解决。 LIBRARY TestDll EXPORTS MyFunction LIBRARY 用来指定动态链接库内部名称。该名称与生成的动态链接库名一定要匹配，这句代码不是必须的。 EXPORTS说明了DLL将要导出的函数，以及为这些导出函数指定的符号名。 第二种是定义导出函数时加上限定符：extern "C" 如：#define DLLEXPORT_API extern "C" _declspec(dllexport) 但extern "C"只解决了C和C++语方之间调用的问题(extern "C" 是告诉编译器，让它按C的方式编译)，它只能用于导出全局函数这种情况 而不能导出一个类的成员函数。 同时如果导出函数的调用约定发生改变，即使使用extern "C"，编译后的函数名还是会发生改变。例如上面我们加入_stdcall关键字说明调用约定（标准调用约定，也就是WINAPI调用约定）。 #define DLLEXPORT_API extern "C" _declspec(dllexport) 01 DLLEXPORT_API int _stdcall MyFunction(int iVariant) 02 { 03 return 0; 04 } 编译后函数名MyFunction改编成了_MyFunction@4 通过第一种方法模块定义文件的方式DLL编译后导出函数名不会发生改变。 DLL(动态库)导出函数名乱码含义 C++编译时函数名修饰约定规则：   __stdcall调用约定：   1、以"?"标识函数名的开始，后跟函数名；    2、函数名后面以"@@YG"标识参数表的开始，后跟参数表；    3、参数表以代号表示：   X--void   D--char   E--unsigned char   F--short   H--int   I--unsigned int   J--long   K--unsigned long   M--float   N--double   _N--bool   ....   PA--表示指针，后面的代号表明指针类型，如果相同类型的指针连续出现，以"0"代替，一个"0"代表一次重复；   4、参数表的第一项为该函数的返回值类型，其后依次为参数的数据类型,指针标识在其所指数据类型前；    5、参数表后以"@Z"标识整个名字的结束，如果该函数无参数，则以"Z"标识结束。   其格式为"?functionname@@YG*****@Z"或"?functionname@@YG*XZ"，例如                       int Test1(char *var1, unsigned long)-----"?Test1@@YGHPADK@Z"                      void Test2()-----"?Test2@@YGXXZ"    __cdecl调用约定：   规则同上面的_stdcall调用约定，只是参数表的开始标识由上面的"@@YG"变为"@@YA"。   __fastcall调用约定：   规则同上面的_stdcall调用约定，只是参数表的开始标识由上面的"@@YG"变为"@@YI"。   如果要用DEF文件输出一个"C++"类，则把要输出的数据和成员的修饰名都写入.def模块定义文件   所以...   通过def文件来导出C++类是很麻烦的,并且这个修饰名是不可避免的

引用 6 楼 zhao4zhong1 的回复:《程序员的自我修养——链接、装载与库》 这本书有在看呢，看到前面两章了，不过感觉时间太紧了，是把pdf放在手机里面蹲厕所的时候看的，

引用 1 楼 lile1234_show 的回复:编译的时候, .cpp以及 这个.cpp里 包含的所有.h里的代码，都会被扩展到.cpp文件里，然后被变异成一个.obj文件。(PE格式，并不一定能执行)  ....然后再链接.... 引用 2 楼 akirya 的回复:这是链接器的事情 将所有的obj lib 一起进行链接操作。 引用 4 楼 user-6 的回复:还有一个链接中间文件的过程的！(库文件) 引用 5 楼 turingo 的回复:绝大部分编译器默认都会直接链接libc（C标准库），printf也包含在其中。  [quote=引用 楼主 Enter_ 的回复:] 例如：printf函数是申明在《stdio.h》文件中的，但是我们在编写程序时，却只是包含了头文件《stdio.h》，里面没有它的定义，但是却可以正常的输出，这是为什么呢？是关于编译器的问题么？？程序是如何知道printf函数是在哪里定义的呢？一个文件一个文件的挨着查找么？还是直接查找包含头文件《stdio.h》的c文件呢？  它的定义是包含在类似如下一个文件中的： 文件名：printf.c  #include "stdio.h" int printf (const char *, ...) {....}[/quote]  引用 3 楼 sinservice 的回复:只需声明原型就可以了，寻找真正的函数实现（就是找到符号地址）是链接器的工作。  其实，楼主的想法是有些道理的，楼主觉得总要告诉编链接器printf函数实现的coff的位置吧？  没错，但这些编译器都会将printf的定义所在的lib库设定为默认链接，你不管它，它就默默给你加上去了。  如果你使用一些非默认的lib，就需要你手工告诉连接器了，比如，当你使用输入法的相关API，就要加入Imm32.lib，这需要你人工在linker选项里加入。  同理，你自己做的lib，也要你手工引入。  你也可以在代码里插入linker注释，  (不同编译器写法不尽相同) #pragma comment(lib, "abc.lib"）  这样其实是在预处理阶段做了一个记录，让最后的链接阶段做这个操作而已。  但我不建议你使用这种预处理注释，还是老老实实地在工程属性的linker选项里加入需要链接的lib。 嗯，谢谢哈！现在脑袋里面有个大体的逻辑了！！

《程序员的自我修养——链接、装载与库》

绝大部分编译器默认都会直接链接libc（C标准库），printf也包含在其中。  引用 楼主 Enter_ 的回复:例如：printf函数是申明在《stdio.h》文件中的，但是我们在编写程序时，却只是包含了头文件《stdio.h》，里面没有它的定义，但是却可以正常的输出，这是为什么呢？是关于编译器的问题么？？程序是如何知道printf函数是在哪里定义的呢？一个文件一个文件的挨着查找么？还是直接查找包含头文件《stdio.h》的c文件呢？  它的定义是包含在类似如下一个文件中的： 文件名：printf.c  #include "stdio.h" int printf (const char *, ...) {....}

还有一个链接中间文件的过程的！(库文件)


Question: 关于程序设计，大家给点建议

引用 2 楼 user-2 的回复:之前这么做肯定也是有它的原因的！ 单线程没什么不好 那有关于程序设计的书籍可以推荐的么

最好不要自己实现，因为难度真的很高。  直接参照 google webrtc 的源代码吧，直接用都行，直接用并不是很难。

之前这么做肯定也是有它的原因的！ 单线程没什么不好


Question: C中的bool运用求解（在VC6.0中）

引用 1 楼 wangdahu888 的回复:吐血了呀 宏不是这样写的 #define ture  1 #define false  0 除了这个，估计楼主手误： ture --> true

#define ture = 1;//不要= #define true 1;

#include <stdio.h> #define ture = 1 #define false = 0  int main() {  if(ture) printf("bool ok"); else printf("wrong");  return 0; } 宏定义里面是简单的替换 ture就是1 不需要使用等于号。

看看基本语法。预处理那部分吧。。。

引用 1 楼 wangdahu888 的回复:吐血了呀 宏不是这样写的 #define ture  1 #define false  0+1

这个东西叫布尔？   bool b=1;  是一个类型啊。~

楼主基础知识需加强啊

看看define的定义


Question: 十六进制转十进制看不懂啊?

沒錯! 回车也代表一个字符

是不是'\0'在回车之后，回车是不是也代表一个字符，如果是的话，那就可以执行后面的else if(flag)了

我觉得先看书了解基本语法比较好。。

你得先明白几个东西: 1. 16进制转换成10进制的原理, 即手动在纸上, 你要会算. 2. 明白字符串与内存数据的区别. 即ASCII码  你这个程序是把"字符串"表示的16进制数据, 转换成"字符串"表示的10进制  所以你需要做的就是先把字符串的"0-9"会转换成内存数据的0-9, 把字符串中的"a-f"转换成对应的内存数据10-15.  剩下的就是按原理换算了.

还是...您能将您的问题再描述得更清楚一点!?

看不懂各位的解答。。。

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

关于您的问题：  1.确实如果c = '\0'，那么就不会进到回圈里，不过，getchar()会等待使用者输入，使用者应该也没办法输入'\0'，所以不管输入什么还是会进回圈执行判断。  2.因为是getchar() 的关系，n=0 应该只是单纯想要表示一次只会针对一个字元做转换，不考虑两位数的转换吧。


Question: C语言结构中的一个问题

楼主呀,这有什么好问的,各编译器对标准的诠释可能不一样,就记住了就行了,知道就行了. 以后如果你学C#什么的,里面有不少的语法糖,也是记住写法就行了,问为什么真的没意思?

typedef struct node { Item item; struct node * next; }Node; struct Node *list;//首先这里应该是struct node *list //其次，他等价于Node *list,因为Node就是struct node这个结构体的别名

在C++中效果是一样的... 因为在C++中struct和class差不多，只是有一些区别而已 但是在C中，必须加上struct了...

引用 2 楼 KenZhang1031 的回复:我觉得你还要清楚两个问题： 1、这四种写法的区别 typedef struct   // 第一种 {    int a; }tName;  struct   // 第二种 {   int a; }tName;   typedef struct __name   // 第三种 {    int a; }tName;  struct __name      // 第四种 {    int a; }tName;  第一种是相当于先定义结构， struct {     int a; }; 然后用typedef 把结构设置成别名tName。第三种和这个是一样的，只是给结构起了个名字__name而已。  第二种是定义结构，为结构类型定义一个变量tName。第四种和这个是一样的，只是给结构起了名字__name而已。  2、typedef 定义的别名使用 用typedef定义的别名，可以直接定义类型。比如： typedef char* PCHAR; // 为char*定义别名PCHAR PCHAR p;  // 相当于定义了char * p 给结构定义别名也是一样的， typedef struct __name tName； // 定义别名tName tNmae ddd;  // 定义结构ddd，和struct __name ddd一样的 定义别名是为了少些struct这个单词。效果是一样的。   你说的这些我都明白。因此我才问，struct node * list  跟node * list是不是一样的效果。

以前的 C 语言里面是不可以的

我是不是应该去报个班，学一下？

就是因为是新手，而且是自学的。难啊。


Question: 数组指针的问题

我觉得应该是a[0]=v[0],a[1]=v[1]不是v[10];在二维数组v[2][10]也能分为v[0],v[1];

引用 1 楼 zhouda829829 的回复:#include <iostream.h> int main(){   int v[2][10]={{1,2,3,4,5,6,7,8,9,10},{11,12,13,14,15,16,17,18,19,20}};   int (*a)[10]=v;//数组指针   cout<<**a<<endl; //结果是1，没问题**a就是指向这个二维数组的第一个存储空间的值   cout<<**(a+1)<<endl; //结果是11，没问题   cout<<*(*a+1)<<endl; //*a就是a[0] 所以这句话就是*(a[0]+1)也就是数组中1的后一个也就是2   cout<<*(a[0]+1)<<endl;//同上   cout<<*(a[1])<<endl;//这个是*(*(a+1)) 结果是11   cout<<*(*(a+1))<<endl;//同上   return 0; } 结果是1，11，2，2，11，我有点明白了，本来想问问*a用v怎么表示，但是应该把a看做二维数组,a[0]=v[0],a[1]=v[10]

对指针进行加减操作，加的是指针所指向类型的字节数 **(a+1)  //由于a指向的是二维数组的第一行，所以加1加的是一整行，a+1就相当于a+1*sizeof(*a) *(*a+1)  //*a指向的是a[0][0]，是一个元素,所以加的是一个整数的字节，*a+1就相当于*a+1*sizeof(**a)


Question: 恕我眼拙：这个代码怎么都看不出哪里出错了

引用 1 楼 zhao4zhong1 的回复:代码功能归根结底不是别人帮自己看或讲解或注释出来的；而是被自己静下心来花足够长的时间和精力亲自动手单步或设断点或对执行到某步获得的中间结果显示或写到日志文件中一步一步分析出来的。 提醒：再牛×的老师也无法代替学生自己领悟和上厕所！ 单步调试和设断点调试是程序员必须掌握的技能之一。 谢谢赵哥提点！我已经指导，就是在第150行试读之后，文件指针已经向下移动一个struct的位置了，所以那个位置的struct就没有读到，在后面的读取之前加个rewind()就好了！


Question: 探讨：C语言编程中一个有关文件读写的问题

加个判断条件，是打开失败，再重新打开并创建(大多数都是这么处理)

由于思考时间太长，造成一起抄袭事件。

说一下我的想法。 可以先尝试用r+打开文件，如果成功，就继续后续操作；如果失败，说明文件不存在，那么再尝试用w+创建这个文件。这样就不用事先人为创建一个空文档了。

引用 楼主 mcmay 的回复:我在写代码时经常会遇到这样的情况，程序需要创建一个文件，然后从该文件中进行读写操作。但问题是，创建一个文件，要求用"w+"这个可用以创建文件的写参数（假设程序中不能用"a"参数，例如在文件的任意位置写入）。那么，每当程序再次运行时，就会抹除上次运行时的写入的内容。有一个解决办法，就是预先人为建立一个空文档，然后用"r+"做读写操作。不过觉得这个办法，不是很智能。请问有没有什么更好的办法？      谢谢您的参与！ 这办法就不错了。

先"r+"打开，失败（说明不存在）则用"w+"再打开。


Question: 程序如何产生 一个周期的 正弦 数据

那就赶快结贴吧  别人来了就分不了多少了

OK问题解决了


Question: 请教关于指针在多维数组中运算的问题

1. 指针+1, 地址增加的是sizeof(类型) 2. 你并没有指定数组大小，甚至没有分配内存，这个指针实际指向的是常量区。常量区内存如何分布是编译器决定的，在你这个例子里，编译器用了4字节对齐，所以在3个字节后增加了一个pad字节。

不好意思，这里写错了： printf("str2+1和str的指针是： %d %d\n",str2+1,str2);  //相差5字节，2686724 2686719

请教楼上，这个有怎么解释呢？ #include <stdio.h> int main(void) {  char *str1[]={{'a','b','4','z','m'},{'c','d','x','b','l'}};  char str2[5][5] = {{'a','b','4','z','m'},{'c','d','x','b','l'}};  char *str3[] = {"ab4121111","cdx121111"};   printf("str1指向的变量是 %c\n",*str1); //a  printf("str1+1指向的变量是 %c\n",*(str1+1)); //c  printf("str1+1和str的指针是： %d %d\n",str1+1,str1); // 2686748 2686744   printf("str2指向的变量是 %c\n",**str2); //a  printf("str2+1指向的变量是 %c\n",**(str2+1)); //c  printf("str2+1和str的指针是： %d %d\n",str2+1,str2); //2686738 2686735,相差3字节，str2指定大小，在栈上分配的连续内存   printf("str3指向的变量是 %c\n",**str3); //a  printf("str3+1指向的变量是 %c\n",**(str3+1)); //c  printf("str3+1和str的指针是： %d %d",str3+1,str3); //2686728 2686724   return 0; }

楼主，你这样声明是有问题的（我把'b'改成了'q'）： char *c[] = { { 'a', 'q', '4' }, { 'c', 'd', 'x' } };  怎么取到'q'这个值？

希望对你有帮助，楼主： http://bbs.csdn.net/topics/390667800

1:    #include <stdio.h> 2:    int main(void) 3:    { 00401000 55                   push        ebp 00401001 8B EC                mov         ebp,esp 00401003 83 EC 68             sub         esp,68h 00401006 53                   push        ebx 00401007 56                   push        esi 00401008 57                   push        edi 4:     char str2[5][5] = {{'a','b','4','z','m'},{'c','d','x','b','l'}}; 00401009 C6 45 E4 61          mov         byte ptr [ebp-1Ch],61h 0040100D C6 45 E5 62          mov         byte ptr [ebp-1Bh],62h 00401011 C6 45 E6 34          mov         byte ptr [ebp-1Ah],34h 00401015 C6 45 E7 7A          mov         byte ptr [ebp-19h],7Ah 00401019 C6 45 E8 6D          mov         byte ptr [ebp-18h],6Dh 0040101D C6 45 E9 63          mov         byte ptr [ebp-17h],63h 00401021 C6 45 EA 64          mov         byte ptr [ebp-16h],64h 00401025 C6 45 EB 78          mov         byte ptr [ebp-15h],78h 00401029 C6 45 EC 62          mov         byte ptr [ebp-14h],62h 0040102D C6 45 ED 6C          mov         byte ptr [ebp-13h],6Ch 00401031 33 C0                xor         eax,eax 00401033 89 45 EE             mov         dword ptr [ebp-12h],eax 00401036 89 45 F2             mov         dword ptr [ebp-0Eh],eax 00401039 89 45 F6             mov         dword ptr [ebp-0Ah],eax 0040103C 66 89 45 FA          mov         word ptr [ebp-6],ax 00401040 88 45 FC             mov         byte ptr [ebp-4],al 5:     char *str3[] = {"ab4121111","cdx121111"}; 00401043 C7 45 DC A0 20 40 00 mov         dword ptr [ebp-24h],offset string "ab4121111" (004020a0) 0040104A C7 45 E0 94 20 40 00 mov         dword ptr [ebp-20h],offset string "cdx121111" (00402094) 6:     void *p; 7: 8:     p=(void *)**str2; 00401051 0F BE 4D E4          movsx       ecx,byte ptr [ebp-1Ch] 00401055 89 4D D8             mov         dword ptr [ebp-28h],ecx 9:     p=(void *)**(str2+1); 00401058 0F BE 55 E9          movsx       edx,byte ptr [ebp-17h] 0040105C 89 55 D8             mov         dword ptr [ebp-28h],edx 10:    p=(void *)(str2+1); 0040105F 8D 45 E9             lea         eax,[ebp-17h] 00401062 89 45 D8             mov         dword ptr [ebp-28h],eax 11:    p=(void *)str2; 00401065 8D 4D E4             lea         ecx,[ebp-1Ch] 00401068 89 4D D8             mov         dword ptr [ebp-28h],ecx 12: 13:    p=(void *)**str3; 0040106B 8B 55 DC             mov         edx,dword ptr [ebp-24h] 0040106E 0F BE 02             movsx       eax,byte ptr [edx] 00401071 89 45 D8             mov         dword ptr [ebp-28h],eax 14:    p=(void *)**(str3+1); 00401074 8B 4D E0             mov         ecx,dword ptr [ebp-20h] 00401077 0F BE 11             movsx       edx,byte ptr [ecx] 0040107A 89 55 D8             mov         dword ptr [ebp-28h],edx 15:    p=(void *)(str3+1); 0040107D 8D 45 E0             lea         eax,[ebp-20h] 00401080 89 45 D8             mov         dword ptr [ebp-28h],eax 16:    p=(void *)str3; 00401083 8D 4D DC             lea         ecx,[ebp-24h] 00401086 89 4D D8             mov         dword ptr [ebp-28h],ecx 17: 18:    return 0; 00401089 33 C0                xor         eax,eax 19:   } 0040108B 5F                   pop         edi 0040108C 5E                   pop         esi 0040108D 5B                   pop         ebx 0040108E 8B E5                mov         esp,ebp 00401090 5D                   pop         ebp 00401091 C3                   ret  1:    #include <stdio.h> 2:    int main(void) 3:    { 00401000 55                   push        ebp 00401001 8B EC                mov         ebp,esp 00401003 83 EC 68             sub         esp,68h 00401006 53                   push        ebx 00401007 56                   push        esi 00401008 57                   push        edi 4:     char str2[5][5] = {{'a','b','4','z','m'},{'c','d','x','b','l'}}; 00401009 C6 45 E4 61          mov         byte ptr [ebp-1Ch],61h 0040100D C6 45 E5 62          mov         byte ptr [ebp-1Bh],62h 00401011 C6 45 E6 34          mov         byte ptr [ebp-1Ah],34h 00401015 C6 45 E7 7A          mov         byte ptr [ebp-19h],7Ah 00401019 C6 45 E8 6D          mov         byte ptr [ebp-18h],6Dh 0040101D C6 45 E9 63          mov         byte ptr [ebp-17h],63h 00401021 C6 45 EA 64          mov         byte ptr [ebp-16h],64h 00401025 C6 45 EB 78          mov         byte ptr [ebp-15h],78h 00401029 C6 45 EC 62          mov         byte ptr [ebp-14h],62h 0040102D C6 45 ED 6C          mov         byte ptr [ebp-13h],6Ch 00401031 33 C0                xor         eax,eax 00401033 89 45 EE             mov         dword ptr [ebp-12h],eax 00401036 89 45 F2             mov         dword ptr [ebp-0Eh],eax 00401039 89 45 F6             mov         dword ptr [ebp-0Ah],eax 0040103C 66 89 45 FA          mov         word ptr [ebp-6],ax 00401040 88 45 FC             mov         byte ptr [ebp-4],al 5:     char *str3[] = {"ab4121111","cdx121111"}; 00401043 C7 45 DC A0 20 40 00 mov         dword ptr [ebp-24h],offset string "ab4121111" (004020a0) 0040104A C7 45 E0 94 20 40 00 mov         dword ptr [ebp-20h],offset string "cdx121111" (00402094) 6:     void *p; 7: 8:     p=(void *)**str2; 00401051 0F BE 4D E4          movsx       ecx,byte ptr [ebp-1Ch] 00401055 89 4D D8             mov         dword ptr [ebp-28h],ecx 9:     p=(void *)**(str2+1); 00401058 0F BE 55 E9          movsx       edx,byte ptr [ebp-17h] 0040105C 89 55 D8             mov         dword ptr [ebp-28h],edx 10:    p=(void *)(str2+1); 0040105F 8D 45 E9             lea         eax,[ebp-17h] 00401062 89 45 D8             mov         dword ptr [ebp-28h],eax 11:    p=(void *)str2; 00401065 8D 4D E4             lea         ecx,[ebp-1Ch] 00401068 89 4D D8             mov         dword ptr [ebp-28h],ecx 12: 13:    p=(void *)**str3; 0040106B 8B 55 DC             mov         edx,dword ptr [ebp-24h] 0040106E 0F BE 02             movsx       eax,byte ptr [edx] 00401071 89 45 D8             mov         dword ptr [ebp-28h],eax 14:    p=(void *)**(str3+1); 00401074 8B 4D E0             mov         ecx,dword ptr [ebp-20h] 00401077 0F BE 11             movsx       edx,byte ptr [ecx] 0040107A 89 55 D8             mov         dword ptr [ebp-28h],edx 15:    p=(void *)(str3+1); 0040107D 8D 45 E0             lea         eax,[ebp-20h] 00401080 89 45 D8             mov         dword ptr [ebp-28h],eax 16:    p=(void *)str3; 00401083 8D 4D DC             lea         ecx,[ebp-24h] 00401086 89 4D D8             mov         dword ptr [ebp-28h],ecx 17: 18:    return 0; 00401089 33 C0                xor         eax,eax 19:   } 0040108B 5F                   pop         edi 0040108C 5E                   pop         esi 0040108D 5B                   pop         ebx 0040108E 8B E5                mov         esp,ebp 00401090 5D                   pop         ebp 00401091 C3                   ret

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

有对齐的因素！  引用 楼主 tyy_wjt 的回复:#include <stdio.h> int main(void) {   char *str1[]={{'a','b','4'},{'c','d','x'}};  printf("str1指向的变量是 %c\n",*str1);  printf("str1+1指向的变量是 %c\n",*(str1+1));  printf("str1+1和str的指针是： %d %d",str1+1,str1); }  /*  1.为啥str1+1指针值和str1相差的是4,从上面两个printf可以看出str1指向a,str1+1指向c,他们的指针应该相差3才对啊？？？？？？？  2.为啥数组的指针和变量的指针运算+1都是指向下个元素的地址,,,,如何直接对他们的地址值进行+1？？？？？，*/    运行结果： str1指向的变量是 a str1+1指向的变量是 c str1+1和str的指针是： -1095886336 -1095886340


Question: 急急急！c++求1000次内的不可约多项式，求教各路大神

生成多项式 最多 1000 Bits 的二进制数，实际是 n 位数 从1 开始 ~ n个 1结束，

1）生成多项式 （系数只能 为0或1），直接用二进制数表示。 2）多项式除法 求余数多项式总是不为0 的多项式。无论加减，都是位异或处理，乘法记不住了。 3）求重量，统计1的个数。

我竟然没看懂题,如果这是面试题的话,我得溜了,不浪费时间

引用 楼主 MIFAND 的回复:求在F2上的1000次以内的不可约多项式，假设x的系数（不为0）相加等于此多项式的重量，求每一个n对应的重量最小的不可约多项式。我写了一段，还有点没完成 #include<stdio.h> #include<math.h> #define N 1000  int n; void main() { int determine(int f[N],int sign); int gcd(int a[N],int b[N]); int mod(int x[N],int f[N]); int devide(int n,int n1[100]); int deg(int x[N]); 	int i,j,e=0; 	int f[10000]; 	for(n=2;n<=1000;n++) 	{ 		for(i=3;;i=i+2) 		{ 			for(j=)/*从f[]的n-1个位置中，取出i-2个放入1，其余为0,这等价于生成一个重量为i的n次多项式*/ 			{	 				determine(f,e);/*判断函数是否不可约 若不可约 则返回e=1*/ 				if(e) goto result; 				else continue; 			} 		} result: 	printf(%d"次多项式的重量为"%d:n,i); 	} } int devide(int n,int n1[100]) { 	int i,j; 	int e[]={0}; 		n1[0]=1; 	for (i=2,j=1;i<=n/2;) 	{ 		if(n%i==0)  		{ 			if(i!=n1[j-1])  			{ 				n1[j]=i; 				e[j]++; 				j++; 			} 			else e[j-1]++; 		}	 		else i++; 	} } int deg(int *x) { 	int i; 	for(i=1;;i++) 	{ 		if(x[i]!=0)域都出来了，想不到真有数学系出没。

你这个要做多项式除法，余数多项式不为0，即可。

看得懂，不会做！！！

专业数学，看不懂很正常。

你的问题是什么？ 不会是希望别人帮你写完吧

求在F2上的1000次以内的不可约多项式，假设x的系数（不为0）相加等于此多项式的重量，求每一个n对应的重量最小的不可约多项式。  看来我是out了，怎么看就是看不懂lz什么意思


Question: linux下的哲学家问题...

引用 2 楼 u013168863 的回复:这个循环貌似没有结束啊，ctrl+z。  抱歉..好几天都没上网了。  ctrl+c,ctrl+z都不行。抓狂了，就直接把终端关掉，重头再运行。  最后的解决办法： 再开一个终端，ps -a,再kill掉那五个哲学家子进程。  现在的问题是输出不对..不知道问题出在哪儿T T

引用 1 楼 turingo 的回复:CTRL+C一定会停止的。 抱歉..好几天都没上网了。 的确是不行的。无论是ctrl+c或者是ctrl+z都不行。  最后的解决方法： 打开另一个终端，ps -a 查看当前所有进程，接着kill掉在执行那五个子进程..  再一问：输出结果不是预期中的结果。问题出在哪儿了？互斥变量应该没用错。难道是printf函数或者是临界区没设置对?

这个循环貌似没有结束啊，ctrl+z。

CTRL+C一定会停止的。  引用 楼主 u011408943 的回复:问题： 1、怎么互斥变量没起作用？ 2、执行后，程序一直在跑，ctrl+c不起作用   代码：  #include<unistd.h> #include<sys/types.h> #include<stdio.h> #include<semaphore.h> #include<stdio.h>  #define NUM 5	//哲学家人数 #define LEFT (ph_num-1)%NUM      //左邻 #define RIGHT (ph_num+1)%NUM	//右邻  typedef enum{thinking,hungry,eating}STATE_TYPE;	//哲学家的状态：思考，饥饿，进食  sem_t ph[NUM];	//每个哲学家有个信号量，初值为0 sem_t mutex;	//信号量，保护临界区 STATE_TYPE state[NUM];	//定义整型数组  //测试操作 void test(int ph_num) {    if((state[ph_num]==hungry)&&(state[LEFT]!=eating)&&(state[RIGHT]!=eating))    {      state[ph_num]=eating;	//左右邻都不处于eating状态，则将state[ph_num]状态置eating      sem_post(&ph[ph_num]);	//V操作，将信号量-1     } } 	  //取叉操作 void get_forks(int ph_num) {    sem_wait(&mutex);	//P操作，信号量-1，保护临界区    state[ph_num]=hungry;	//将state[ph_num]状态置为hungry    printf("Philosopher %d is hungry.\n",ph_num+1);    test(ph_num);	//测试函数    sem_post(&mutex);	//V操作，信号量+1    sem_wait(&ph[ph_num]);	//第ph_num位哲学家信号量-1 }  //放叉操作 void put_forks(int ph_num) {    printf("Philosopher %d is full and put down chopsticks.\n",ph_num+1);    sem_wait(&mutex);	//P操作，信号量-1，保护临界区    state[ph_num]=thinking;	//将state[ph_num]状态置为hungry    printf("Philosopher %d is thinking\n",ph_num+1);    test(LEFT);	//检验左邻是否有waiting,若无，则继续；若有，则wake    test(RIGHT);	//检验右邻...    sem_post(&mutex);    }  //吃操作 void eat(int ph_num) {    printf("Philosopher %d is eating...\n",ph_num+1);    sleep(2); }   //哲学家操作 void  *philosopher(int ph_num) {    while(1)    {           printf("**********************************\n");           printf("Dining...\n"); 	  get_forks(ph_num);	//取叉 	  eat(ph_num);		//eating状态 	  put_forks(ph_num);	//进食完毕，放叉           	} }  //主函数	   void main() {    int i;    pid_t pid;    sem_init(&mutex,0,1);	//初始化信号量为1，且信号量在进程间共享    for(i=0;i<NUM;i++)    {         sem_init(&ph[i],0,0);	//初始化ph[i]的值为0，即哲学家都在thinking          printf("Philosopher %d is thinking.\n",i+1);    }    pid_t p0 = fork();     if( p0 == 0 )    {      philosopher(0);     return ; //若此处没有return 0 p1 进程也会执行 pid_t p2=fork()语句     }      pid_t p1 = fork();     if( p1 == 0 )    {      philosopher(1);     return ;      }    pid_t p2 = fork();    if( p2 == 0 )    {      philosopher(2);     return ;      }   pid_t p3 = fork();    if( p3 == 0 )    {      philosopher(3);     return ;      }   pid_t p4 = fork();    if( p4 == 0 )    {      philosopher(4);     return ;      }     }    linux中执行结果： Philosopher 1 is thinking. Philosopher 2 is thinking. Philosopher 3 is thinking. Philosopher 4 is thinking. Philosopher 5 is thinking. ********************************** Dining... Philosopher 1 is hungry. Philosopher 1 is eating... ********************************** Dining... Philosopher 2 is hungry. Philosopher 2 is eating... ********************************** Dining... Philosopher 3 is hungry. Philosopher 3 is eating... ********************************** Dining... Philosopher 4 is hungry. Philosopher 4 is eating... ********************************** Dining... Philosopher 5 is hungry. Philosopher 5 is eating... zncj@zncj-desktop:~$ Philosopher 1 is full and put down chopsticks. Philosopher 1 is thinking ********************************** Dining... Philosopher 1 is hungry. Philosopher 1 is eating... Philosopher 2 is full and put down chopsticks. Philosopher 2 is thinking ********************************** Philosopher 3 is full and put down chopsticks. Dining... Philosopher 3 is thinking Philosopher 2 is hungry.


Question: 分享一个红黑树的实现，请大家帮忙指出需要优化的地方

有具体的实现就自己对照一下吧


Question: 一个关于指针的问题，求助

free(tmp);为什么用free呢  不是malloc出来的 不用这么做

有借有还，不是借的，自然不用还。

引用 2 楼 Automation_dmu 的回复:    static char temp[20];      free(tmp);  静态存储区的tmp 干嘛用free去释放？+1

free的让人很迷茫，楼上说的是对的

2种都错 不用介意

malloc/free 匹配使用，当你malloc了 你才能free！ 没有malloc就不要去free了！第一个程序也是有问题的！ 不能free

循环没有结束么~~


Question: 一个socket通讯问题，多结构传输问题

啊。。。非常感谢各位的指导，我已经搞定了，把结构体对象接收改为char buf接收然后再用结构体强转 就好了

XML

重新写解析函数，解析时需要与发送时相对应的，可以自己规定发送与解析时的机制

我的意思是既然前人已经用realorrev这个对象来接收数据了，没有用buf，那么怎么从A结构体的对象realorrev中取出B结构体的值呢，是直接用 &realorrev地址偏移吗？还是该怎么写呢？

你的意思是可以这样写？ B.a = &realorrev + 偏移量？？？  还是怎么写？求赐教

引用 7 楼 yangw150 的回复:再弱弱的问一句，前人的代码是这样写的 int iRec = aSocket.ReceiveFrom(&realorrev, sizeof(REALOR_SHAKEHANDS),strIp,port);  收的时候用的不是buf是用的A类型的结构体，realorrev是结构体的对象，这样的话发的时候是A+B结构，但是收的时候用的是A结构体接收的，这似乎不对吧 只是一个地址而已！这样也可以，取B结构体信息的时候，偏移A结构体大小就好！ 实际开发的时候还是用buf比较靠谱，上面那种写法比较误导人

引用 4 楼 yangw150 的回复:非常感谢楼上的回复，这是发送的代码，怎么收呢？  你发送端是如何发的！你接收端就如何接收！ 中间怎么发，这就是接和收之间的协议了！@

引用 4 楼 yangw150 的回复:非常感谢楼上的回复，这是发送的代码，怎么收呢？//recv buf... A* pa = (A*)buf; // use pa ... B* pb = (B*)(buf+sizeof(A)); // use pb...我认为通讯最好是基于‘协议’的，而不要基于数据结构，这样才能做到机器无关

非常感谢楼上的回复，这是发送的代码，怎么收呢？

仅供参考char* buf = (char*)malloc(sizeof(A)+sizeof(B)); A* pa = (A*)buf; pa->a = 1; pa->b = 2; B* pb = (B*)(buf+sizeof(A)); strcpy(pb->a, "abc"); strcpy(pb->b, "bcd"); //send buf... free(buf);

关键问题是怎么解析？client端收消息是用的A的结构体收的，代码如下 int iRec = aSocket.ReceiveFrom(&realorrev, sizeof(REALOR_SHAKEHANDS),strIp,port);  REALOR_SHAKEHANDS就是A结构体，realorrev是A的对象，怎么解析后面那个B的结构体呢？

直接分配一块大空间阿！加上消息头，标注后面消息体的大小！ 然后把两个结构体拷贝进去，发过去！ 那边对应解析就好；


Question: c函数指针赋值的问题

grep

引用 2 楼 yuwujian 的回复:静态局部变量存储在内存的全局区域，可供全局使用。 百度了下静态局部变量随便找了个链接，你看看吧 http://www.blogjava.net/faintbear/archive/2010/01/06/308408.html多谢提供的帮助，我对静态局部变量更了解了，我再分析分析代码，问题好像不在此。

那一定是你没看到


Question: 【求位数和%3，负数就错了】

unsigned long  a,t,i; // unsigned


Question: windows平台下软件开发

引用 5 楼 yangw150 的回复:[quote=引用 1 楼 zhao4zhong1 的回复:] http://jpkc.wxit.edu.cn/vb/Wlkc/index/index.html  ==================================================================== VB都淘汰了哦，现在还有人用吗？是不是有点误人子弟啊[/quote] 用筷子吃饭啥时候淘汰呀？！

引用 1 楼 zhao4zhong1 的回复:http://jpkc.wxit.edu.cn/vb/Wlkc/index/index.html  ==================================================================== VB都淘汰了哦，现在还有人用吗？是不是有点误人子弟啊

用MFC啊，虽然现在用的少，但是真学完还是很不错的，因为什么东西都要自己来，如果时间紧张的话搞搞qt吧还是，上手比较快点，而且界面比较好看

你得自己去搜索一般的你想综合的测试功能一般都是通过哪些语言来实现的！ 然后自己再重点去抓这方面的知识！ 如果还有带界面的话，那就Qt好好搞搞！ 一步一步来吧！

软件工程相关的知识吧!好多,总之我觉得你的问题过于复杂啊,什么都相关. 可以找老师讨论讨论


Question: 这种错误是不是因为写指针的时候写错了，然后应用程序出错了？

我关机的时候有时候都会run time error呢

这个bug 连xp系统都会老是出现的了！

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

引用 3 楼 truelance 的回复:原因很多, 踩内存, 堆栈溢出, 都可以造成这种现象. 唉。。。不是说系统会有保护的吗，怪不得我做个编程作业360都能看成木马。。那菜鸟编程人员的电脑岂不是很多程序都容易悲剧

引用 2 楼 u012345348 的回复:[quote=引用 1 楼 derekrose 的回复:] 弱弱的问一句什么叫写指针 我用语不太规范，就是在写程序的时候用到指针的意思。。[/quote]  pointer无处不在，其实pointer就是地址    http://www.tutorialspoint.com/cprogramming/c_pointers.htm 介绍给你看看

引用 1 楼 derekrose 的回复:弱弱的问一句什么叫写指针 ++

原因很多, 踩内存, 堆栈溢出, 都可以造成这种现象.

引用 1 楼 derekrose 的回复:弱弱的问一句什么叫写指针 我用语不太规范，就是在写程序的时候用到指针的意思。。

弱弱的问一句什么叫写指针


Question: 大神，我用VC6.0学习C可以不！！！

这个不能吧，因为vc6.0没有出64位的，只有32位的，你可以尝试使用更高版本的vc，目前很多中型和大型的应用软件还没有出64位的，毕竟64位的系统还没有普及，只是为了适应现在越来越高的硬件配置要求，纯属经验，希望能帮到你。有时间多看看这方面的基础：http://net.itcast.cn/net/video.shtml

如果是新手的话，就不要用vc了！ 新手c-free吧！

............... 你学习C语言跟你用什么编译工具好像没什么关系, 放心用VC++吧

必须可以的~

工具而已... 语言才印巴

对你以后有影响的是你的脑子和变通能力，没听说一个软件能影响人生的

可以是可以，不过建议用高版本VS或gcc 编译正确代表没有语法错误，不能运行或者运行结果错误代表程序写错了


Question: 关于指针的小问题

float * g () g是一个函数， 它的返回值指向一个float类型的指针   float (*g)() g是一个指针，它指向一个返回值是float类型的函数

返回值没有写 第一个就是retunr p； 浮点数指针值的是这个指针指向的空间内容里面写的是浮点数。

float *g() 返回的是一个指针，指针类型指向float类型； float (*g)() 返回的是一个数值，数值的类型是float；

#include <iostream> using namespace std ; float *p(float *point) { 	 	float path = 2.5 ; 	point = &path ; 	return point ; } int main() { 	float* ios = NULL ; 	cout << *p(ios) ; 	return 0 ; } return float型变量指针 不然牺牲精度发生隐式转换 。。

引用 4 楼 u012804737 的回复:float * g() 返回的是不是一个指针，然后这个指针的值是指向一个float类型的常量？能不能这么理解？呵呵，不是这么理解，应该是就是这样的

引用 4 楼 u012804737 的回复:float * g() 返回的是不是一个指针，然后这个指针的值是指向一个float类型的常量？能不能这么理解？  float* g() {    float* pRet = NULL;    //....    float* pf = new float;    *pf  = 8.0;    pRet = pf;    return pRet; }

函数指针LZ知道吧？不知道的话去百度查查

这2个就区别大了 float * g ()  //函数名g 返回值float*  float (*g) () //函数指针g 返回值float

第一个好像明白了，返回的是一个指向浮点数的指针，也就是这个指针指向的值应该是浮点数对吧？那么怎么用return返回呢？


Question: 最近在大数排序，总是超时求解

冒泡和选择的算法复杂度都是n^2 了，进行海量数据排序时肯定是不能选用的，你可以用快排，如果是只需要输出前n 个最大的话，那么就可以用随机选择第n 大的算法了

qsort strcmp


Question: 我天天晚上8点到12点在线，求一个C语言的老师教我！！！！！

谢谢了，等我学完了这些，应该我就会知道我要学什么了，应该往哪个方向前进了！！！！！！！！！

qq:549835996 喜欢同类，对编程的热情

如果不懂， 往后看。 学习有时候纠结在一个地方不好的。 读书百遍， 其意自现。 我是最开始学MFC的。 那时候 啥都不懂， 连定义变量为啥要取名字， 不直接定义为x, y, z都不晓得。 然后我就逮着孙鑫的20集视频。。。一遍 两遍 三遍。。。。。。 学习切记急躁 更好的学习方法有很多， 在没有找到的时候还是沉默的学习吧。。。 关于效率问题 ， 其实现在回想， 当初的我学习的时候真的好蠢 啥都不会 连上网搜都不会 但这是我最珍贵的回忆之一  最珍贵的经验的 永远是失败

先看一下我的博文http://blog.csdn.net/turingo/article/details/8115042  引用 4 楼 u012777651 的回复:我的QQ邮箱245913495@qq.com，可以发给我，然后我自己会努力学习的

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

bc++3.1 帮助里面对每个函数都有一小段能拷贝出来运行看效果的例子程序。非常适合初学C语言。相比较而言VC带的帮助MSDN就没有。http://download.csdn.net/source/2805028 计算机组成原理→DOS命令→汇编语言→C语言（不包括C++）、代码书写规范→数据结构、编译原理、操作系统→计算机网络、数据库原理、正则表达式→其它语言（包括C++）、架构……  对学习编程者的忠告： 眼过千遍不如手过一遍！ 书看千行不如手敲一行！ 手敲千行不如单步一行！ 单步源代码千行不如单步对应汇编一行！  VC调试时按Alt+8、Alt+7、Alt+6和Alt+5,打开汇编窗口、堆栈窗口、内存窗口和寄存器窗口看每句C对应的汇编、单步执行并观察相应堆栈、内存和寄存器变化，这样过一遍不就啥都明白了吗。 对VC来说，所谓‘调试时’就是编译连接通过以后，按F10或F11键单步执行一步以后的时候，或者在某行按F9设了断点后按F5执行停在该断点处的时候。 （Turbo C或Borland C用Turbo Debugger调试,Linux或Unix下用GDB调试时,看每句C对应的汇编并单步执行观察相应内存和寄存器变化。）

我找了N多了，自己天天在家看，但我还是希望有个师傅，不然遇到不懂的，我找谁啊，上网查，给我的答案太多，让我不知道那个是对的！！！

初学者。。。最好找些视频教程 照着做  做两遍 ， 基本可以算是入门咯。C语言的基础教程。。。网上一大堆  你找些看吧 实在不行看C语言零基础的 只看书没用的 初学必须动手。

不要你多少时间，只要给我一些资料，和对我一些不懂的问题给我答案就好，（我自己会用各种方法自己尝试，实在不行在求救师傅的！！）

最好可以告诉我一些C语言的专业术语，我现在完全是们外汉，你给我的资料我会背下来，只求一位好一点的师傅，或者程序员！！！！！！！！！！！！！！ 师傅，看见了我，就别走了把，在不就的将来我一定会有出息的！！！！！！！！！！！

孺子可教也，可惜我们的时间不多啊，还是学生时代好！  引用 楼主 u012777651 的回复:本人热爱计算机编程，可以为了改BUG不睡觉，以前把VB学一点可以过2级了，现在打算好好学习C语言，让他为我一生的语言，不知道那位大神有空！！！！！稍微指导我下就好，不用你天天在线，只要我有什么不懂的就可以问你，我现在自己学习的感觉好累，完全找不到C语言的方向！！ 跪求！！！！！！！！！！！！！！！！！！！！！！！


Question: ortp大数据链传输问题

数据包过大，没有分包吗？

程序中设置了接收空间的大小的，并且能够保证值大于发送空间的值，如下： 发送端： int rtpSend(unsigned char *send_buffer, int frame_len) { 	int sended_bytes; 	 	sended_bytes = rtp_session_send_with_ts(rtp_session_mgr.rtp_session,  		(uint8_t *)send_buffer,  		frame_len, 		rtp_session_mgr.cur_timestamp);  	//printf("------Send msg len : %d %d\n",frame_len,sended_bytes); 	rtp_session_mgr.cur_timestamp += rtp_session_mgr.timestamp_inc;  	return sended_bytes; } 接收端的设置：  void rtpInit(RtpSessionMgr *rtp_session_mgr) { 	WSADATA wsaData; 	if ( WSAStartup(MAKEWORD(2,2), &wsaData) != 0) 	{ 		fprintf(stderr, "WAStartup failed!\n"); 		return ; 	}  	ortp_init(); 	ortp_scheduler_init();  	rtp_session_mgr->rtp_session = rtp_session_new(RTP_SESSION_RECVONLY);  	rtp_session_set_scheduling_mode(rtp_session_mgr->rtp_session, 1); 	rtp_session_set_blocking_mode(rtp_session_mgr->rtp_session, 1); 	//rtp_session_set_blocking_mode(rtp_session_mgr->rtp_session, 0); 	rtp_session_set_local_addr(rtp_session_mgr->rtp_session, recv_ip, recv_port);  	rtp_session_enable_adaptive_jitter_compensation(rtp_session_mgr->rtp_session, TRUE); 	rtp_session_set_jitter_compensation(rtp_session_mgr->rtp_session, 40);  	rtp_session_set_payload_type(rtp_session_mgr->rtp_session, 34); 	rtp_session_set_recv_buf_size(rtp_session_mgr->rtp_session, recv_bufsize);  	rtp_session_mgr->timestamp = timestamp_inc; } 似乎好像是当数据大于65535时，还是要自己分片？

在ortp中win_receive中还需要显示调用： rtp_session_set_recv_buf_size(rtp_session_mgr .rtp_session , recv_bufsize); 这里的recv_bufsize必须要比win_sender中 sended_bytes = rtp_session_send_with_ts (rtp_session_mgr .rtp_session ,                           ( uint8_t *) send_buffer,                            wrapLen,                           rtp_session_mgr.cur_timestamp ); 的wrapLen要大

能够用TCP自己下个发送方案，自己实现大数据分片和组片，由于传输的距离用无线，并且距离不远，不知是否可行？


Question: 关于读取硬件设备的问题

引用 1 楼 turingo 的回复:归根结底需要从MSDN中寻找答案，参考http://msdn.microsoft.com/en-us/library/windows/desktop/aa363908(v=vs.85).aspx ... 还有就是怎么获得\\\\.\\PHYSICALDRIVE0呢?好像只有一个获得卷的办法?

引用 1 楼 turingo 的回复:归根结底需要从MSDN中寻找答案，参考http://msdn.microsoft.com/en-us/library/windows/desktop/aa363908(v=vs.85).aspx ... 请问,设备是什么? 我在网上找不到

谢谢两位了......

http://technet.microsoft.com/en-us/sysinternals/bb896657 WinObj is a must-have tool if you are a system administrator concerned about security, a developer tracking down object-related problems, or just curious about the Object Manager namespace.  WinObj is a 32-bit Windows NT program that uses the native Windows NT API (provided by NTDLL.DLL) to access and display information on the NT Object Manager's name space. Winobj may seem similar to the Microsoft SDK's program of the same name, but the SDK version suffers from numerous significant bugs that prevent it from displaying accurate information (e.g. its handle and reference counting information are totally broken). In addition, our WinObj understands many more object types. Finally, Version 2.0 of our WinObj has user-interface enhancements, knows how to open device objects, and will let you view and change object security information using native NT security editors.

归根结底需要从MSDN中寻找答案，参考http://msdn.microsoft.com/en-us/library/windows/desktop/aa363908(v=vs.85).aspx  引用 楼主 qilinno 的回复:请问下，我刚刚看了用API直接读取磁盘的指定簇的问题，可是不太明白。 应该怎么获得像\\\\.\\PHYSICALDRIVE0的东西呢？ 毕竟我在用的时候只是拿来后直接使用的，万一我不想读第一块硬盘，想读第二块硬盘应该怎么办呢？ 所以，有没有什么办法能够直接获得计算机上有哪些硬盘以及他们的名字（就是像\\\\.\\PHYSICALDRIVE0的东西）这类的东西呢，就像获得磁盘上的卷一样 谢谢大神!


Question: 函数调用老是error C2065: 'getmax' : undeclared identifier怎么办

#include <stdio.h> #include <math.h>                                                  //预处理 /*  *  *	项目：任意输入一个4位自然数，调用函数输出该自然数的各位数字组成的最大数。  *	  *  */ void getmax(int nums2[]); int main() {	 int number,nums[4],numsmax; printf("请输入一个4位自然数"); scanf("%d",&number); nums[3]=number/1000; nums[2]=number/100%10; nums[1]=number/10%10; nums[0]=number%10; for (int i=0;i<4;i++) { printf("%d",nums[i]);  } getmax(nums); printf("%d",numsmax);  return 0; } void getmax(int nums2[4]) {	 int numsmax; for (int i=0;i<4;i++) { for (int j=1;j<4;j++) { if (nums2[i]>nums2[j]) { numsmax=nums2[i]; } } } }  引用 楼主 u013096814 的回复:#include <STDIO.H> #include <MATH.H>                                                  //预处理 /*  *  *	项目：任意输入一个4位自然数，调用函数输出该自然数的各位数字组成的最大数。  *	  *  */ main() {	 	int number,nums[4],numsmax; 	printf("请输入一个4位自然数"); 	scanf("%d",&number); 	nums[3]=number/1000; 	nums[2]=number/100%10; 	nums[1]=number/10%10; 	nums[0]=number%10; 	for (int i=0;i<4;i++) 	{ 		printf("%d",nums[i]); 	 	} 	getmax(nums); 	printf("%d",numsmax); 	  } void getmax(int nums2[4]) {	int nums2[]; 	int numsmax; 	for (int i=0;i<4;i++) 	{ 		for (int j=1;j<4;j++) 		{ 			if (nums2[i]>nums2[j]) 			{ 				numsmax=nums2[i]; 			} 		} 	} }   函数调用的时候老显示 error C2065: 'getmax' : undeclared identifier

申明原型先。

void getmax(int nums2[4])； //在main函数前面加上这句！

未申明先使用是大忌! 雖然這次你學會了,但更要學的是錯誤報告.   'getmax' : undeclared identifier  'getmax'中就是變量或函数名, undeclared identifier 意思就未申明  以後見到這種報告就很容易解決

参考1楼，简洁明了

引用 4 楼 user-8 的回复:getmax放在main的前面 或者在include之后定义getmaz函数原型谢了哈哈哈哈

引用 2 楼 mujiok2003 的回复:申明原型先。谢了哈哈哈，做出来了

引用 4 楼 user-8 的回复:getmax放在main的前面 或者在include之后定义getmaz函数原型+1


引用 3 楼 mujiok2003 的回复:#define _CRT_SECURE_NO_WARNINGS  #include <string.h> #define _CRT_SECURE_NO_WARNINGS  #include <string.h>  int main(void) { 	char pi[5]; 	strcpy(pi, "oo"); 	return 0; }

strcpy_s(p[1], 3, "oo");  //ps:char *p[5],你指针数组好像没有给每个指针分配空间的吧！


Question: 关于VC做键盘扫描仿真的问题，求教啊！！！谢谢

引用 2 楼 adeng1919 的回复:额，老家有模拟键盘的源码，VC++的，可惜最近不回老家……  [quote=引用 楼主 u013095810 的回复:] 需要把8048进行键盘扫描时的数据流向动态展示出来。 数据流向是什么概念？[/quote]   对键盘键的扫描的确定是8048进行的，以及确定了它会把数据送往哪里。 能不能大体说下思路。因为是仿真，要对扫描过程进行展示，所以程序可能不像简单的进行扫描那么简单。谢谢哈。

[quote=引用 1 楼 turingo 的回复:] 这个看起来应该用Adobe Flash来做会比较合适吧。  但是要求是要用VC。还是谢谢哈。

额，老家有模拟键盘的源码，VC++的，可惜最近不回老家……  引用 楼主 u013095810 的回复:需要把8048进行键盘扫描时的数据流向动态展示出来。 数据流向是什么概念？

这个看起来应该用Adobe Flash来做会比较合适吧。  引用 楼主 u013095810 的回复:大神们，我需要用VC做一个键盘扫描的仿真程序，需要把8048进行键盘扫描时的数据流向动态展示出来。该如何做啊，给点建议。！还有我想把PC标准键盘用控件画出来，需要按那个键就用鼠标去点，然后就动态显示键盘扫描的数据流向。这样能做到不，怎么做啊！谢谢朋友些。


Question: 大整数加法测试了没发现哪里错了但是提交到网上总是提示结果错误

引用 6 楼 wusuopuBUPT 的回复:#include <stdio.h> #include <stdlib.h> #include <string.h>  int main() { 	int a[200] = { 0 }, b[200] = { 0 }, sum[202] = { 0 }; 	char x[200], y[200]; 	fgets(x, sizeof(x), stdin); 	fgets(y, sizeof(y), stdin);  	int i = 0; 	int j = strlen(x); 	int k = strlen(y); 	for (i = 0; i < j; i++) //把字符数组转换成整形数组 		a[i] = x[i] - 48; 	for (i = 0; i < k; i++) 		b[i] = y[i] - 48; 	int n; 	if (j > k) 		n = j; 	else 		n = k; 	i = 1; 	while (n--) { 		int h = 0; 		int j1 = a[j - i], j2 = b[k - i]; 		if (j - i < 0) //如果两个数字位数不同j-i越界后将第一个加数置0 			j1 = 0; 		if (k - i < 0) 			j2 = 0; 		h = j1 + j2; 		sum[202 - i] += h; 		if (sum[202 - i] / 10 == 1) //进位 				{ 			sum[202 - i - 1]++; 			sum[202 - i] = sum[202 - i] % 10; 		} 		i++; 	} 	i = 0; 	while (sum[i] == 0) //抹0 	{ 		i++; 	} 	for (; i < 201; i++) //输出结果 		printf("%d", sum[i]); 	printf("\n"); 	return 0; }  还是不行啊，应该不是gets那里的错

引用 3 楼 xlz35429674 的回复:[quote=引用 2 楼 derekrose 的回复:] 这种东西没必要非要accept 很浪费生命 这是一个比赛的评分标准啊[/quote]  如果是比赛 上面的话当我没说 哈哈

引用 1 楼 wusuopuBUPT 的回复:gets_s()不是C99的标准，OJ平台的GCC不认识你的gets_s()函数.换成fgets()。  参考：https://forums.freebsd.org/viewtopic.php?&t=10428 http://stackoverflow.com/questions/15149168/undefined-reference-to-gets-s 改了也不行啊

引用 2 楼 derekrose 的回复:这种东西没必要非要accept 很浪费生命 这是一个比赛的评分标准啊

这种东西没必要非要accept 很浪费生命

仅供参考#include <stdio.h> #include <string.h> #define MAXLEN 1000 char a1[MAXLEN]; char a2[MAXLEN]; static int v1[MAXLEN]; static int v2[MAXLEN]; static int v3[MAXLEN]; int i,j,n,L,z; void main(void) {     scanf("%d",&n);     for (j=0;j<n;j++) {         scanf("%s%s",a1,a2);          L=strlen(a1);         for (i=0;i<L;i++) v1[i]=a1[L-1-i]-'0';          L=strlen(a2);         for (i=0;i<L;i++) v2[i]=a2[L-1-i]-'0';          for (i=0;i<MAXLEN;i++) v3[i]=v1[i]+v2[i];          for (i=0;i<MAXLEN;i++) {             if (v3[i]>=10) {                 v3[i+1]+=v3[i]/10;                 v3[i]=v3[i]%10;             }         }          printf("Case %d:\n", j+1);         printf("%s + %s = ", a1, a2);          z=0;         for (i=MAXLEN-1;i>=0;i--) {             if (z==0) {                 if (v3[i]!=0) {                     printf("%d",v3[i]);                     z=1;                 }             } else {                 printf("%d",v3[i]);             }         }         if (z==0) printf("0");          printf("\n");     } } //Sample Input //3 //0 0 //1 2 //112233445566778899 998877665544332211 // //Sample Output //Case 1: //0 + 0 = 0 //Case 2: //1 + 2 = 3 //Case 3: //112233445566778899 + 998877665544332211 = 1111111111111111110

我重新写了一个，楼主，仅供参考：  #include <stdio.h> #include <stdlib.h> #include <string.h>  int main() { 	int a[200] = {0}, b[200] = {0}, sum[202] = {0}; 	char x[200], y[200]; 	fgets(x, sizeof(x), stdin); 	fgets(y, sizeof(y), stdin);  	int len_i = strlen(x) - 1; //注意字符串结尾的'\0'不能算进来 	int len_j = strlen(y) - 1;  	int i, j; 	for(i = 0; i < len_i; i++) { 		a[len_i-1-i] = x[i] - 48; //reverse 	} 	for(j = 0; j < len_j; j++) { 		b[len_j-1-j] = y[j] - 48; 	}  	int n; 	n = len_i >= len_j ? len_i : len_j;  	i = 0; 	int temp_c = 0; 	for(; i < n; i++) { 		int temp_s = a[i] + b[i] + temp_c; 		sum[i] = temp_s % 10; 		temp_c = temp_s / 10; 		//printf("a=%d,b=%d,sum[i]=%d,temp_c=%d\n", a[i], b[i],sum[i],temp_c); 	} 	if(temp_c != 0) { 		sum[n] = temp_c; 		n++; 	} 	for (i = n-1; i >= 0; i--) { 		printf("%d", sum[i]); 	} 	putchar('\n');  	return 0; }


Question: 请教一下这个小问题（青年大赛求平均值）。

#include <stdio.h>  /* 青年歌手参加歌曲大奖赛，有10个评委打分，试编程求选手的平均得分（去掉一个最高分和一个最低分） */ int main(void){     float a[10]={0.0}, min, max, average, sum=0;     int i;       for (i = 0 ; i < 10 ; i++)         scanf("%f", &a[i]); //这里应该是%f不是%d       min = a[0];     for (i = 1 ; i < 10 ; i++)         if (a[i] < min)             min = a[i];       max = a[0];     for (i = 1 ; i < 10 ; i++)         if (a[i] > max)             max = a[i];       for (i = 0 ; i < 10 ; i++)         sum += a[i];     sum = sum - min - max;     average = sum / 8.0;     printf("Average : %f \n", average);       return 0; } 你的scanf()函数给的类型不对

for (i = 0 ; i < 10 ; i++)              if( scanf("%f", &a[i]) != 1 )      {          i--;      }


Question: AVI文件索引修复的问题

个人猜测，遍历文件，要不然怎么可能弄出索引来？

引用 楼主 zhehan54 的回复:现有损坏的AVI文件 文件头可以加上去 但是文件的索引不知道怎么加！ 有一个软件叫做DivFix的 可以修复索引，但是不知道它怎么做到的 ！！  有过经验的麻烦帮忙一下！！ 在另外一个帖子你也回复我了 谢谢！ 我看了下  不知道你说的这个跟AVI的索引有什么关系！！ 能详细的说说吗？ 谢谢了！！


Question: C语言入门刚遇到的小疑问。

引用 3 楼 wusuopuBUPT 的回复:楼上说的很清楚了。 补充一下： %3.0f的意思是：浮点型输出共占3位，其中小数点后占0位，不足3位的左边补上空格 %6.1f的意思是：浮点型输出共占6为，其中小数点后占1位，不足6位的左边补上空格   0 -17.8  20  -6.7  40   4.4  60  15.6  80  26.7 100  37.8 120  48.9 140  60.0 160  71.1 180  82.2 200  93.3 220 104.4 240 115.6 260 126.7 280 137.8 300 148.9  算上小数点，你的摄氏度的输出最长为5位（148.9），左边还会有一个空格，所以，不同tab(\t)也能有分隔的效果。  另外，%3.0f\t%6.1f是没有问题的。  谢谢了大哥 自己不够仔细

引用 2 楼 KenZhang1031 的回复:"%3.0f%\t6.1f\n"不会有问题 不好意思，打错了，是"%3.0f\t%6.1f\n"。  谢谢了大哥 可能是我眼神不对打错了 现在知道了

\t只是一个制表符，就跟你在键盘上打了Tab按键一样，只是隔开而已，对结果没有任何影响。 再者，第一个有个空格格开了，第二个你不打\t，用空格也行啊；第一个用\t也不会有问题，你说的第一个加了\t有错误，那是你加的地方不对啊。"%3.0f%\t6.1f\n"不会有问题。


Question: 考研题 待解决

引用 楼主 u013108570 的回复:一·（1）写出该算法的用途 输入：多行文本 输出：若干行文本及其行号 变量：buf用于保存若干行文本及其行号 1）X﹤—0，i﹤—1 2）从键盘读入一行文本，存入line 3)n﹤—求line中文本字符个数 4）if n=0  then 转向第13）步 5）if n>X  then  6)         清空buf 7)         X﹤—n 8)         将line中的文本及其行号i添加到buf 9) if n=x  then 10)        将line中的文本及其行号i添加到buf 11) i﹤—i+1 12)重复执行第2）到11）步 13）输出buf的所以内容 （2）请用C语言编制程序，实现该算法  二 当前路径下有文件file.txt里面的内容 “The best way to learn is to walk through and build some useful code”  #include <stdio.h> # define N 10 void main() {    FILE *fp;    char ch,str[N];    int k=0;     fp=fopen("file.txt","r");    while(k<N){    ch=fgetc(fp);    if(ch==EOF)  break;    if(ch!='')  str[K++]=ch+1;            }    str[k]='\0';    fclose(fp);    puts(str);  } 输出结果是： 三 #include <stdio.h> #include <stdio.h> void main() {   int i=0,*p;      p=(int*)malloc(sizeof(int)*4);   while(i<4)   scanf("%d",p + i++);   i=*p;   *p=*(P+2);   *(p+2)=i;   i=p[1];   p[1]=p[3];   p[3]=i;   for(i=0;i<4;i++)   printf("%d\t",p[i]); }    设输入为12 23 34 45，请写出程序的运行结果。 四、 #include <stdio.h> void main（） {    char ch,s[]="C Program";        ch=getcher();    printf("%d\n%s\n",fun(s,ch),s); } int fun(char *str,char ch) {    char *p;    int n=0;        for(p=str;*p!='\0';p++){     if(*p!=ch)  *str++=*p;     else        n++;       }    *str='\0';    return n;  } 若程序运行时输入一个字符：r,请写出程序运行的结果 若再次运行程序，并输入一个字符：m,请写出程序运行的结果  哦操,考研就考这种题? 尼玛要不是万恶的政治和英语 分分钟考进去啊

围观我也不太懂

引用 3 楼 u013108570 的回复:好心人帮帮忙吧 ，我是跨专业，实在不懂。运行处错误 把你的代码贴出来， 哪里不会问哪里。

第二题会因为数组越界报错。

第一题程序的作用是将多行文本中文本字符个数的行输出

一： #include <stdio.h> #include <string.h> #include <stdlib.h> int main() { 	size_t x = 0; 	size_t n ; 	int i = 1; 	char buf[4096]; 	char tmp[1024]; 	FILE* pf; 	 	if ((pf=fopen("../t/main.cpp", "r")) == NULL) 		return 1; 	while(fgets(tmp,1024,pf)!= NULL){ 		fputs(tmp,stdout); 		i++; 		n = strlen(tmp); 		if(n>x){ 			x = n; 			sprintf(buf , "%d: %s",i-1,tmp); 		}else if (n==x){ 			sprintf(buf, "%s%d: %s",buf, i-1 , tmp); 		}else{ 			continue; 		}	 	} 	fclose(pf); 	printf(buf); 	return 0; }剩下3题自己运行下不就知道了

都是要考研的人了，还在论坛找答案，如果直接给了你答案，让其他本科的人情何以堪。

都是要考研的人了，还在论坛找答案，如果直接给了你答案，让其他没文凭的人情何以堪。

好心人帮帮忙吧 ，我是跨专业，实在不懂。运行处错误

都是准备考研的牛人了！ 自己先动手写写，做做，想想，敲敲 然后把问题细化，一个一个的来！


Question: C语言中文件夹遍历的问题

这个麻烦大家帮忙看看！！ 挺捉急 的！！

引用 2 楼 zhao4zhong1 的回复:system("dir /b /a-d c:\\*.* >d:\\allfiles.txt"); //读文件d:\\allfiles.txt的内容即C:\\下所有文件的名字 system("dir /b /a-d /s c:\\*.* >d:\\allfilesinsub.txt"); //读文件d:\\allfilesinsub.txt的内容即C:\\下所有文件的名字包含子目录 system("dir /b /ad  c:\\*.* >d:\\alldirs.txt"); //读文件d:\\alldirs.txt的内容即C:\\下所有子目录的名字 请记住，能用shell命令获取文件、文件夹信息或者操作文件、文件夹最好用shell命令获取或者操作，而不要用各种API获取或者操作，因为当遇到非法文件夹名或非法文件名或非法文件长度、非法文件日期、压缩文件、链接文件、稀疏文件……等各种意料之外的情况时，API会处理的不全面或陷入死循环，而shell命令不会。  非常感谢你！！ 这个我马上试试！！！


Question: 困惑：指向结构体数组的指针不能做fwrite()/fread()的参数？

引用 4 楼 mcmay 的回复:[quote=引用 2 楼 max_min_ 的回复:] [quote=引用 1 楼 KenZhang1031 的回复:] fread和fwrite的函数原型第一个参数都是空指针，所以任何指针类型都可以当第一个参数，你的pp[index]和pt[index]都不是指针，而是INFO的结构，改成&pp[index]和&pt[index]试试。  不是空指针！ 第一个参数 是void型指针！也就是接受任意类型的指针而已！  fwrite( &pp[index], sizeof (INFO),1, fp); [/quote] 谢谢，max_min_版主，不过我向KenZhang1031请教的3楼的问题我也想同样向你请教。[/quote] pp[index]是取了里面的内容的不是指针！

引用 6 楼 max_min_ 的回复:[quote=引用 4 楼 mcmay 的回复:] [quote=引用 2 楼 max_min_ 的回复:] [quote=引用 1 楼 KenZhang1031 的回复:] fread和fwrite的函数原型第一个参数都是空指针，所以任何指针类型都可以当第一个参数，你的pp[index]和pt[index]都不是指针，而是INFO的结构，改成&pp[index]和&pt[index]试试。  不是空指针！ 第一个参数 是void型指针！也就是接受任意类型的指针而已！  fwrite( &pp[index], sizeof (INFO),1, fp); [/quote] 谢谢，max_min_版主，不过我向KenZhang1031请教的3楼的问题我也想同样向你请教。[/quote] pp[index]是取了里面的内容的不是指针！[/quote] 是的，后来想想，用普通数组的指针所引用的也的确是数组元素本身而非其指针。谢谢！

引用 5 楼 KenZhang1031 的回复:引用谢谢，我试了，还真行！但是 INFO * pp不是已经就等于&data[0]了吗？它本来就是指针的啊，怎么还要再用&pp[index]呢？而且函数processdata(INFO * pp, int n, FILE *fp)里面的参数INFO *pp也明显就是指针啊，怎么也还要采取&pt[index]的形式，fread()才认呢？请指教！ pp是指针，但是pp[index]不是。这样说吧，你定义了数组data[SIZE]，里面每个元素都是一个你定义的INFO结构，指针pp指向这个数组的首地址，因此pp[index]表示数组里的第index个元素，也就是表示的是数组里第index个的INFO结构数据，所以不是指针，加上&后取地址后才是。 确实如此，后来想通了，谢谢！

引用 2 楼 max_min_ 的回复:[quote=引用 1 楼 KenZhang1031 的回复:] fread和fwrite的函数原型第一个参数都是空指针，所以任何指针类型都可以当第一个参数，你的pp[index]和pt[index]都不是指针，而是INFO的结构，改成&pp[index]和&pt[index]试试。  不是空指针！ 第一个参数 是void型指针！也就是接受任意类型的指针而已！  fwrite( &pp[index], sizeof (INFO),1, fp); [/quote] 谢谢，max_min_版主，不过我向KenZhang1031请教的3楼的问题我也想同样向你请教。

引用 1 楼 KenZhang1031 的回复:fread和fwrite的函数原型第一个参数都是空指针，所以任何指针类型都可以当第一个参数，你的pp[index]和pt[index]都不是指针，而是INFO的结构，改成&pp[index]和&pt[index]试试。 谢谢，我试了，还真行！但是 INFO * pp不是已经就等于&data[0]了吗？它本来就是指针的啊，怎么还要再用&pp[index]呢？而且函数processdata(INFO * pp, int n, FILE *fp)里面的参数INFO *pp也明显就是指针啊，怎么也还要采取&pt[index]的形式，fread()才认呢？请指教！

引用 1 楼 KenZhang1031 的回复:fread和fwrite的函数原型第一个参数都是空指针，所以任何指针类型都可以当第一个参数，你的pp[index]和pt[index]都不是指针，而是INFO的结构，改成&pp[index]和&pt[index]试试。  不是空指针！ 第一个参数 是void型指针！也就是接受任意类型的指针而已！  fwrite( &pp[index], sizeof (INFO),1, fp);


Question: C语言 大整数运算，实现n!-m!,麻烦大神来看一下，

引用 9 楼 q745401990 的回复:看完了，我就郁闷了，大整数的运算都是使用int 数组来做的，100位的就开个int a[100] 然后两个数组进行相加减，中间考虑进位..........  [quote=引用 8 楼 M173475237 的回复:] 高精度的数据都是用字符串表示的。。。 int 怎么可能容下那么多位。[/quote]  int 数组。你想多了。。你怎么实现把大数的每一位分开放的数组里？  如果用求余。那。。。太复杂不说，还容易出错，。 如果用字符数组的话，每一位占数组的一个单元是很好实现的。。而且运算起来也不难： 0=‘0’-‘0’； 1=‘1’-‘0’......一位一位的计算，其实就是模拟手工运算

看完了，我就郁闷了，大整数的运算都是使用int 数组来做的，100位的就开个int a[100] 然后两个数组进行相加减，中间考虑进位..........  引用 8 楼 M173475237 的回复:高精度的数据都是用字符串表示的。。。 int 怎么可能容下那么多位。

高精度的数据都是用字符串表示的。。。 int 怎么可能容下那么多位。

我也想到了。64位也放不下。

如果允许的话可以试试GNU Multiple Precision Arithmetic Library http://gmplib.org 或者参考它的源代码

引用 1 楼 jianqiu000 的回复: int i,j,m,n; stp: printf("请输入m,n"); scanf("%d,%d",&m,&n); if(m<0||n<0||m>n){     go stp; } for(i=1;i<=m;i++){     m=m*i; } for(j=1;j<=n;j++){     n=n*j; } printf("n!-m!的结果是:%d",n-m); 应该没有啥问题，我没有测试过。其实结果就是(n-m)*m!,希望帮到你 ...都说了要用大数int范围明显不够，就算是64位100！大概也放不下 自己搜个大数的程序就可以了，剩余就简单了

我说错了。结果不是(n-m)*m!，失误，失误。

假设n较大，m较小，那么可以把m!提出来： n!-m! = ( n * (n-1) * ... * (m+1)  - 1 ) * m! 反之同理。 如果依然太大，你可以找个大整数的库。

仅供参考#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() {     char ch;     string s1,s2,res;      while (cin>>s1>>ch>>s2) {         switch (ch) {             case '+':res=ADD_INT(s1,s2);break;             case '-':res=SUB_INT(s1,s2);break;             case '*':res=MUL_INT(s1,s2);break;             case '/':res=DIV_INT(s1,s2);break;             case '%':res=MOD_INT(s1,s2);break;             default :                   break;         }         cout<<res<<endl;     }     return(0); }


Question: 怎么将C++改成C语言的

将类的私有数据成员定义为struct 将成员函数定义为公共的函数。函数对结构体成员进行操作

我有一个程序是C++的，但是老师不允许在程序中使用类  注意不使用class的c++ 代码 并不是c语言

引用 12 楼 cwt19902010 的回复:引用 10 楼 bijiaoben 的回复:改了函数声明和定义之后，调用的地方也要改吧？C++成员函数里面有this指针的。除非用全局变量。我以前把一段C++改成过C你好，能把代码发来我看看具体是怎么修改的么，谢谢了 那是我在第一个公司的时候的一个小工作了，只是一个小的C++解码库而已。一个是因为那是公司的代码，不方便发出来，另一个是我早跳槽了，没有备份，而且年代久远，记不太清了。如果你要是需要的话，可以把你的代码打包发给我，我看看怎么改。

简单啊.把类改成结构体,然后类中的函数=>结构体中的函数指针. 例如.  class CMyTest1 { private:     int m_nTest1; public:     CMyTest1()     {           this->m_nTest1 = 1;           printf("构造函数\n");      }     ~CMyTest()     {           printf("析构函数\n");     }      int OnTest(int nVal)      {            this->m_nTest1 = nVal;            return 1;       } };  /// 改成结构体如下.  typedef struct tag_MyTest {       int m_nTest1;       void (*MyTest)(struct tag_MyTest *pData);       void (*_MyTest)(struct tag_MyTest *pData);       int  (*OnTest)(struct tag_MyTest *pData, int nVal); }MYTEST;  void MY_MyTest1(MYTEST *pData)  {       if(!pData)          return;       pData->m_nTest1 = 1;        printf("构造函数\n");  } void MY__MyTest(MYTEST *pData) {     if(!pData)         return;     printf("析构函数\n");  } int MY_OnTest(MYTEST *pData, int nVal) {      if(!pData)          return 0;      pData->m_nTest1 = nVal;      return 1; }  int MYTEST_Init(MYTEST *pData) {      if(!pData)         return 0;      // 所有函数都要调用.      pData->MyTest = MY_MyTest1;      pData->_MyTest= MY__MyTest;      pData->OnTest = MY_OnTest; }  // 使用如: int main_struct()  //用结构体. {     MYTEST test;      MYTEST_Init(&test); // 每个都必须调用.     test.MyTest(&test); // 模拟构造函数.手动调用.          test.OnTest(&test, 1000); // 函数调用.      test._MyTest(&test); // 模拟析构函数,手动调用.       } int main_class()   // 用类. {       CMyTest1 test;            test.OnTest(1000); }

老师为什么这么要求？

这并不难，但是麻烦。 基本的思路是这样的：把类写成结构体；把方法写成函数，函数接受一个结构体的指针作为第一个参数。 要注意： 1：C++会自动完成一些操作，换成C之后要手工补上。 2：这种简单方法不能解决虚函数的问题。  假设如下简单代码：   class Foo { public:   Foo();   Foo(int value);    ~Foo();    void show();    int member; };  class Bar: Foo { public:     Bar();     ~Bar(); }  Foo::Foo(): member(0) {} Foo::Foo(int value): member(value) {} void Foo::show() { cout<<value<<endl; }     可以写个这样的C：  typedef struct {   int member; } Foo;  typedef struct {   Foo parent; } Bar;  Foo* Foo_new() {   return (Foo*) malloc(sizeof(Foo)); }  void Foo_construct(Foo* self) {   self->member = 0; }  void Foo_construct_with_value(Foo* self, int value) {   self->member = value; }  void Foo_show(Foo* self) {   printf("%d\n",self->member); }  void Foo_destruct(Foo* self) {}  void Foo_release(Foo* self) {   free(self); }  Bar* Bar_new() {   return (Bar*) malloc(sizeof(Bar)); }  void Bar_construct(Bar* self) {   Foo_construct(self->parent); }  void Bar_destruct(Bar* self) {   Foo_destruct(self->parent); }  void Bar_release(Bar* self) {   free(self); }    然后，假设你原来有这样的代码：  void main() {   Foo obj1;   Bar* obj2 = new Bar(); }  现在就得变成这样：  void main() {   Foo obj1;   Foo_construct(&obj1);   Bar* obj2 = Bar_new();   Bar_construct(obj2);    Foo_destruct(&obj1);   Bar_destruct(obj2);   Bar_release(obj2); }

不要做A语言代码修改为B语言代码的无用功。 也不要做用A语言代码直接调用B语言代码库这样复杂、这样容易出错的傻事。 只需让A、B语言代码的输入输出重定向到文本文件，或修改A、B语言代码让其通过文本文件输入输出。 即可很方便地让A、B两种语言之间协调工作。

引用 9 楼 worldy 的回复:将数据和函数分开成两部分 数据部分假设叫 struct A  所有原来的非静态函数都有更改 函数签名 原来：xxx aFun( parmlist)==>xxx aFun(A* pA,parmlist) 函数体内所有的原来类成员变量改为：pA->yyy 所有的原来成员函数改为: aFun(pA,....)  你们老师也真是脑袋有问题，如果你的类比较复杂，够你喝一壶的了唉，马上还有考试，说多了都是泪，谢谢啦……

引用 4 楼 max_min_ 的回复:把类除掉啊！用普通函数也是可以的啊！ 只是代码量会多一点而已！谢谢版主了

引用 3 楼 zhouda829829 的回复:贴出来看看 帮你想想怎么改 这么笼统怎么改已经附上代码，谢谢了……

#include "Car.h"  ////////////////////////////////////////////////////////////////////// // Construction/Destruction //////////////////////////////////////////////////////////////////////  //赛车宽、长：51 133  CCar::CCar() {  }  CCar::~CCar() {  }  /**  * @brief CCar::LoadImage 加载赛车图片 *  * Detailed description.通过参数加载赛车图片 * @param[in] img 传入的赛车图片(IplImage*)类型 */ void CCar::LoadImage(IplImage *img) { 	m_pImg = img; }   /**  * @brief CCar::CopyToBack 把赛车图片贴到背景图片上 *  * Detailed description.获取赛车图片，并把赛车图片贴到背景图片上 * @param[in] backImage 传入的背景图片 */ void CCar::CopyToBack(IplImage *backImage) { 	int i,j,b,g,r; 	int x = m_pos.x; 	int y = m_pos.y; 	for(i = 0 ; i < m_pImg->height; ++i) 	{ 		for(j = 0;j < m_pImg->width; ++j) 		{ 			/** @brief  通过使用宏CV_IMAGE_ELEM，获取三通道像素值*/             b = CV_IMAGE_ELEM(m_pImg,uchar,i,j * 3 + 0);             g = CV_IMAGE_ELEM(m_pImg,uchar,i,j * 3 + 1); 			r = CV_IMAGE_ELEM(m_pImg,uchar,i,j * 3 + 2); 			              if(!(b >= 250 && g >= 250 && r >= 250)) 			{  				CV_IMAGE_ELEM(backImage,uchar,i + y,(j + x) * 3 + 0) = b; 				 				CV_IMAGE_ELEM(backImage,uchar,i + y,(j + x) * 3 + 1) = g;  				 				CV_IMAGE_ELEM(backImage,uchar,i + y,(j + x) * 3 + 2) = r; 			} 		} 	} }  /**  * @brief CCar::InitPos 初始化赛车位置 *  * Detailed description.通过传入的CvPoint类型数据pos,初始化赛车位置 * @param[in] pos 赛车的位置坐标 */ void CCar::InitPos(CvPoint pos) { 	m_pos.x = pos.x; 	m_pos.y = pos.y; }  /**  * @brief CCar::RunLeftRight 控制让赛车左右偏移 *  * Detailed description.用键盘控制，让赛车左右偏移  同时把赛车限制在赛道中部； * @param[in] leftOrRight 参数为'a'、'A'赛车向左偏移，参数为'd'、'D'赛车向左偏移; */ void CCar::RunLeftRight(char leftOrRight) { 	switch (leftOrRight) 	{ 	case 'a': 	case 'A':if(m_pos.x >= 150)m_pos.x -= 15;break; 	case 'd': 	case 'D':if(m_pos.x <= 750)m_pos.x += 15;break; 	} }  /**  * @brief CCar::RunOnLine 赛车可沿直线方向移动 *  * Detailed description.用键盘控制，让赛车上下移动  同时把赛车限制在屏幕内; * @param[in] lineMove 参数为'w'、'W'赛车向上移动，参数为's'、'S'赛车向下移动。 */ void CCar::RunOnLine(char lineMove) { 	switch (lineMove) 	{ 	case 'w': 	case 'W':if(m_pos.y >= 1)m_pos.y -= 8;break;//速度有最大值if(m_speed <= -9)m_speed = -9; 	case 's': 	case 'S':if(m_pos.y <= 500)m_pos.y += 8;break;//速度最小为if(m_speed < 0)0; 	} }   /**  * @brief CCar::InitSpeed 初始化赛车速度 *  * Detailed description.初始化赛车速度 * @param[in] _speed 整形参数_speed 为初始化的赛车速度 */ void CCar::InitSpeed(int _speed) { 	m_speed = _speed; } /**  * @brief CCar::InitSize 初始化赛车大小 *  * Detailed description.初始化赛车大小 * @param[in] width 赛车的宽带 * @param[in] height 赛车的高度 */ void CCar::InitSize(int width, int height) { 	m_size.width = width; 	m_size.height = height; }   /**  * @brief CCar::InitScore 初始化分数 *  * Detailed description.初始化分数 * @param[in] score 整形参数score为初始化的分数 */ void CCar::InitScore(int score) { 	m_score = score; } 谢谢大家的回复，比如其中的一个文件是这样的，想问问大家怎么修改，谢谢了……

把class全部替换成struct

把类除掉啊！用普通函数也是可以的啊！ 只是代码量会多一点而已！

贴出来看看 帮你想想怎么改 这么笼统怎么改

你得能看懂c++代码

用結構就好啦,最大分別是結構不能有方法就是啦,


Question: C,五子棋，想实现电脑智能算法，高价悬赏!!!!!!

这个需要一个很大的库吧，存储五子棋高手的走步，模仿人的思维

这个是自己写的，在linux终端上运行的

lz你的UI是用什么画的

这个代码应该开源的吧？

好吧！！！！！！

这里几句话说不清。我以前用VC写过一个五子棋程序，带有禁手功能的，模仿黑石的界面，可以设置搜索深度，太久找不到源代码了。不过我当时是参考了一本书《PC游戏编程(人机博弈)》。你可以找这本书看看。

AI不好写  看牛人


Question: sscanf格式请教

多打了个&，不好意思。不过二位给了我C++的写法，收获不小。

cout << setprecision(10) << "dXCoordinate = " << dXCoordinate << endl; 这样显示效果更好

引用 1 楼 fyzhuhui 的回复:我这样写的： sscanf(buffer,"%lf%lf%lf",&dXCoordinate,&dYCoordinate,&dZCoordinate); 或者 sscanf(buffer,"     %lf         %lf        %lf",&dXCoordinate,&dYCoordinate,&dZCoordinate); 都是只能读出来第一个。  我试了，都能读出来：     char buffer[]="     0.148800001         0.200489998         0.155780002";     double dXCoordinate, dYCoordinate, dZCoordinate;      sscanf(buffer,"%lf%lf%lf",&dXCoordinate,&dYCoordinate,&dZCoordinate);      cout << "dXCoordinate = " << dXCoordinate << endl;     cout << "dYCoordinate = " << dYCoordinate << endl;     cout << "dZCoordinate = " << dZCoordinate << endl;  输出： dXCoordinate = 0.1488 dYCoordinate = 0.20049 dZCoordinate = 0.15578


Question: 编写一个函数，对输入的整数k输出它的全部素数因子。 例如：当k＝126时，素数因子为：2，3，3，7。 要求按如下格式输出：126 = 2 * 3 * 3 *

引用 7 楼 KenZhang1031 的回复:如果输入负数，结果要怎样显示才算正确？ 加个ABS应该没问题

#include<stdio.h> //预处理命令 #include<math.h>  //预处理命令 void foo(int n) { 	int i; 	for(i = 2; i < n ; i++) 	{ 		if(n % i == 0)  		{ 			printf("%d*", i); 			foo(n / i); 			return; 		} 	} 	printf("%d\n",n); } int main() { 	int t; 	printf("请任意输入一个整数："); 	scanf("%d",&t); 	printf("%d=",t); 	foo(t); }

引用 2 楼 KenZhang1031 的回复:#include "stdio.h" #include "math.h"  unsigned int GetPrimeFactor(unsigned int uiNum) { 	unsigned int i; 	unsigned int uiSqrt = (unsigned int)sqrt((float)uiNum);  	for(i = 2; i < uiSqrt; i++) 	{ 		if(uiNum % i == 0) 		{ 			return i; 		} 	}  	return uiNum; }   void main(void) { 	int iSrc = 126; 	unsigned int uiSrc = abs(iSrc); 	unsigned int uiPrime;  	printf("%d = ", iSrc); 	if(iSrc < 0) 	{ 		printf("-"); 	} 	while(uiSrc) 	{ 		uiPrime = GetPrimeFactor(uiSrc); 		uiSrc /= uiPrime; 		printf("%d", uiPrime); 		if(uiSrc != 1) 		{ 			printf(" * "); 		} 		else 		{ 			printf("\n"); 			break; 		} 	}  	getchar(); } 无论iSrc是正数还是负数都可以输出。你可以修改成使用例如scanf输入数据方式的。 我写了个很简单的

如果输入负数，结果要怎样显示才算正确？

个人认为，递归尽量不要用。用迭代好点。

引用 2 楼 KenZhang1031 的回复:#include "stdio.h" #include "math.h"  unsigned int GetPrimeFactor(unsigned int uiNum) { 	unsigned int i; 	unsigned int uiSqrt = (unsigned int)sqrt((float)uiNum);  	for(i = 2; i < uiSqrt; i++) 	{ 		if(uiNum % i == 0) 		{ 			return i; 		} 	}  	return uiNum; }   void main(void) { 	int iSrc = 126; 	unsigned int uiSrc = abs(iSrc); 	unsigned int uiPrime;  	printf("%d = ", iSrc); 	if(iSrc < 0) 	{ 		printf("-"); 	} 	while(uiSrc) 	{ 		uiPrime = GetPrimeFactor(uiSrc); 		uiSrc /= uiPrime; 		printf("%d", uiPrime); 		if(uiSrc != 1) 		{ 			printf(" * "); 		} 		else 		{ 			printf("\n"); 			break; 		} 	}  	getchar(); } 无论iSrc是正数还是负数都可以输出。你可以修改成使用例如scanf输入数据方式的。 这个不懂，百度上是说平方根？ unsigned int uiSqrt = (unsigned int)sqrt((float)uiNum);

求救。。。。


Question: c语言

//输入"",输出"" //输入"A",输出"A1" //输入"AA",输出"A2" //输入"AAABBBBCCCCCC",输出"A3B4C6" //输入"AAAAAAAAAAAAA",输出"A13" //输入字符串中不包含'0'..'9' #include <stdio.h> #include <string.h> char a[100]; char b[100]; char c[100]; char ch,ch1; int i,j,k,n; void pack(char *u) {     i=0;     j=0;     b[j]=0;     ch1=0;     n=0;     while (1) {         ch=u[i++];         if (0==ch) break;         if (ch1==0) {             ch1=ch;             n=1;             b[j++]=ch1;             continue;         }         if (ch1==ch) {             n++;         } else {             k=sprintf(b+j,"%d",n);             j+=k;             ch1=ch;             n=1;             b[j++]=ch1;         }     }     if (ch1) {         k=sprintf(b+j,"%d",n);         j+=k;     }     b[j]=0; } void unpack(char *p) {     c[0]=0;     while (1) {         k=sscanf(p,"%c%d%n",&ch,&n,&j);         if (k==2) {             p+=j;             for (i=0;i<n;i++) sprintf(c,"%s%c",c,ch);         } else break;     } } void main() {     strcpy(a,""             );pack(a);unpack(b);printf("[%s]=>[%s]=>[%s]\n",a,b,c);     strcpy(a,"A"            );pack(a);unpack(b);printf("[%s]=>[%s]=>[%s]\n",a,b,c);     strcpy(a,"AA"           );pack(a);unpack(b);printf("[%s]=>[%s]=>[%s]\n",a,b,c);     strcpy(a,"AAABBBBCCCCCC");pack(a);unpack(b);printf("[%s]=>[%s]=>[%s]\n",a,b,c);     strcpy(a,"AAAAAAAAAAAAA");pack(a);unpack(b);printf("[%s]=>[%s]=>[%s]\n",a,b,c); } //[]=>[]=>[] //[A]=>[A1]=>[A] //[AA]=>[A2]=>[AA] //[AAABBBBCCCCCC]=>[A3B4C6]=>[AAABBBBCCCCCC] //[AAAAAAAAAAAAA]=>[A13]=>[AAAAAAAAAAAAA]

#include<stdio.h> #include<string.h> void main(void){ 	char a[100] = {0}; 	char b[100] = {0}; 	int i,j=0,k,n,m=1; 	printf("enter the sentense\n"); 	gets(a); 	n=strlen(a); 	for(i=0;i<n;i++) 	{ 		if(a[i] == a[i+1]) 		{ 			m++;		 		} 		else 		{ 			k = m%10+48; 			b[j] = a[i]; 			b[j+1] = k; 			j+=2; 			m=1; 		} 	} 	printf("%s",b); } 你看看对不对？

我在计算的时候迷茫了。 #include<stdio.h> #include<string.h> void main() { 	char a[100]; 	int i,n,m=1; 	printf("enter the sentense\n"); 	gets(a); 	n=strlen(a);     for(i=0;i<n;i++) 	{ 		if(a[i]==a[i+1]) 		{ 			m++; 		} 		else 		{ 			m=1; 			if(a[i+1]==a[i+2]) 			{ 			     m++; 			} 		} 	} 	printf("%d %c",m,a[i]); }

没思路啊。帮个忙。

楼主，这种问题就不用挂上去了吧


Question: c语言为啥第二次调用函数,,会出现第一次的值，第一次调用会出现乱码，用c++6.0编写的

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

// main函数改成这样吧 //这个结果是和编译器有关系，printf函数不同的编译器参数入栈的顺序是不同的！ #include <stdio.h> int main() {     float average(float array[],int n,float a[2]);     float a[2];     float score1[]={98.5,97,91.5,60,55}, score2[]={67.5,89.5,99,69.5,77,89.5,76.5,54,60,99.5};     printf("The average of class A is %6.2f \n",average(score1,5,a));     printf("the largest is %6.2f the smallest is %6.2f\n",a[0],a[1]);     printf("The average of class B is %6.2f \n",average(score2,10,a));     printf("the largest is %6.2f the smallest is %6.2f\n",a[0],a[1]);     return 0; }

根据C语言标准6.5.2.2.10 The order of evaluation of the function designator, the actual arguments, and subexpressions within the actual arguments is unspecified, but there is a sequence point before the actual call.  average(), a[0], a[1]都是printf()的参数, 它们之间的计算顺序是不能假定的,也就是说你不能因为a[0], a[1]写在了后面就认为是在调用average()后的结果.

可能没说明白 就是第一次调用函数average()的时候 a[0],a[1] 里面没有值；他是先输出a[1],然后a[0]，在调用函数average()，乱码是因为你的数组没有初始化；同理第二次调用函数average()的时候，存的是前面的a[1]与a[0]，所以是第一次调用的值。

#include <stdio.h> int main(){ 	float average(float array[],int n,float a[2]); 	float a[2] = {0}; 	float score1[]={98.5,97,91.5,60,55}, score2[]={67.5,89.5,99,69.5,77,89.5,76.5,54,60,99.5}; 	float aver; 	aver = average(score1,5,a); 	printf("The average of class A is %6.2f the largest is %6.2f the smallest is %6.2f\n",aver,a[0],a[1]); 	aver = average(score2,10,a); 	printf("The average of class B is %6.2f the largest is %6.2f the smallest is %6.2f\n",aver,a[0],a[1]); 	return 0; }   float average(float array[],int n,float a[2]){ 	int i; 	float aver,sum=array[0]; 	a[0]=array[0]; 	a[1]=array[0]; 	for(i=1;i<n;i++) 	{ 		if(a[0]<array[i]) 			a[0]=array[i]; 		if(a[1]>array[i]) 			a[1]=array[i]; 		sum=sum+array[i]; 	} 	aver=sum/n; 	return (aver); } 首先定义的数组最好初始化，之所以出现你说的那种情况是由于函数printf()带来的，它是从后面就是a[2]向前进栈，所以之前没有执行你的函数average()故没有值；第二次输出的是第一次的值。代码个人觉得写的有点冗余，我也没改这样修改应该是对的！


Question: 内存驻留程序（TSR）问题

引用 1 楼 supermegaboy 的回复:不行，TSR是实模式时代的东西，而VS产生的代码是保护模式的。  你应该用tc写TSR  可以用vs环境编写类似tsr程序的么？

引用 3 楼 lpcads 的回复:[quote=引用 2 楼 u010165006 的回复:] TSR是DOS时代的东西吧，Windows是多任务。记得以前学微机原理的时候学汇编语言，想把一个动态显示时钟的程序改成TSR，结果没有成功，没有研究下去了。 你是不是使用 int 21h 显示字符串了，改用 int 10h 就可以了。[/quote] 也可能是，以前没有网络，有问题也不一定能找到帮助，现在DOS和BIOS中断向量这些我都忘光了。

使用 masm 编译，32位系统cmd下可以运行（相当于虚拟8086模式）。如果是64位系统，那只能安装虚拟机了（xp）。

引用 2 楼 u010165006 的回复:TSR是DOS时代的东西吧，Windows是多任务。记得以前学微机原理的时候学汇编语言，想把一个动态显示时钟的程序改成TSR，结果没有成功，没有研究下去了。 你是不是使用 int 21h 显示字符串了，改用 int 10h 就可以了。