Question: 一道算法题

KISS － Keep It Simple, Stupid.

没找出规律来。。。

我找到一个规律，但是对最后两行数据不适用，很费解。 坐等坐等大神解惑

不明白这种变化 有什么规律  不明觉厉

引用 20 楼 zhao4zhong1 的回复:不用递归，用循环即可： #include <stdio.h> int i,a,b,c,d,e,f; int main() {     i=0;     for (a=0  ;a<28;a++) {     for (b=a+1;b<29;b++) {     for (c=b+1;c<30;c++) {     for (d=c+1;d<31;d++) {     for (e=d+1;e<32;e++) {     for (f=e+1;f<33;f++) {         printf("arrA[%2d,%2d,%2d,%2d,%2d,%2d]=arrB[%i]\n",a,b,c,d,e,f,i);         i++;     }     }     }     }     }     }     return 0; } //arrA[ 0, 1, 2, 3, 4, 5]=arrB[0] //arrA[ 0, 1, 2, 3, 4, 6]=arrB[1] //…… //arrA[ 0, 1, 2, 3, 4,32]=arrB[27] //arrA[ 0, 1, 2, 3, 5, 6]=arrB[28] //arrA[ 0, 1, 2, 3, 5, 7]=arrB[29] //…… //arrA[ 0, 1, 2, 3, 5,32]=arrB[54] //arrA[ 0, 1, 2, 3, 6, 7]=arrB[55] //…… //arrA[ 0, 1, 2, 4, 5, 6]=arrB[406] //…… //arrA[ 0, 1, 2, 6, 7, 8]=arrB[1135] //…… //arrA[ 0, 1, 2, 7, 8, 9]=arrB[1460] //…… //arrA[ 0, 1, 3, 4, 5, 6]=arrB[4060] //…… //arrA[ 0, 1, 3, 7, 9,10]=arrB[5138] //…… //arrA[ 0, 1, 3,16,28,29]=arrB[7144] //…… //arrA[ 6,11,15,25,28,29]=arrB[854564] //…… //arrA[27,28,29,30,31,32]=arrB[1107567] 还是这个好，现在不方便写代码，只能借用老赵的代码了

引用 23 楼 zhao4zhong1 的回复:纠正18楼，应该是6个。 是的看错了，是6-组合

引用 18 楼 zhao4zhong1 的回复:求0..32中任取5个不重复的数且从小到大排列的所有解 这个就是N个数据的 r-组合  就是 0～32 这33个数据的 5-组合 搜到一篇博客   博客标题  如何求一个r组合的编号  http://blog.csdn.net/qq675927952/article/details/6539270 组合数学里r组合 是r-组合

纠正18楼，应该是6个。

引用 20 楼 zhao4zhong1 的回复:不用递归，用循环即可： #include <stdio.h> int i,a,b,c,d,e,f; int main() {     i=0;     for (a=0  ;a<28;a++) {     for (b=a+1;b<29;b++) {     for (c=b+1;c<30;c++) {     for (d=c+1;d<31;d++) {     for (e=d+1;e<32;e++) {     for (f=e+1;f<33;f++) {         printf("arrA[%2d,%2d,%2d,%2d,%2d,%2d]=arrB[%i]\n",a,b,c,d,e,f,i);         i++;     }     }     }     }     }     }     return 0; } //arrA[ 0, 1, 2, 3, 4, 5]=arrB[0] //arrA[ 0, 1, 2, 3, 4, 6]=arrB[1] //…… //arrA[ 0, 1, 2, 3, 4,32]=arrB[27] //arrA[ 0, 1, 2, 3, 5, 6]=arrB[28] //arrA[ 0, 1, 2, 3, 5, 7]=arrB[29] //…… //arrA[ 0, 1, 2, 3, 5,32]=arrB[54] //arrA[ 0, 1, 2, 3, 6, 7]=arrB[55] //…… //arrA[ 0, 1, 2, 4, 5, 6]=arrB[406] //…… //arrA[ 0, 1, 2, 6, 7, 8]=arrB[1135] //…… //arrA[ 0, 1, 2, 7, 8, 9]=arrB[1460] //…… //arrA[ 0, 1, 3, 4, 5, 6]=arrB[4060] //…… //arrA[ 0, 1, 3, 7, 9,10]=arrB[5138] //…… //arrA[ 0, 1, 3,16,28,29]=arrB[7144] //…… //arrA[ 6,11,15,25,28,29]=arrB[854564] //…… //arrA[27,28,29,30,31,32]=arrB[1107567]  代码已看懂，这代码大赞 上面取5个不重复的数的所有解 、及序数 这些名词还有些费解，我再自己琢磨琢磨：） 还有一个疑惑，a-f明明是6个数字，怎么取的是5个不重复的数字呢？

引用 15 楼 zheshiwodehao 的回复:[quote=引用 4 楼 lm_whales 的回复:] 看看是否 r-组合------按照大小顺序排列。 前面是组合，后面是序号，r = 5 如果是，求出全组合和序数的关系，就可以了 否则的话，这个规律就不好总结了。。 不过看着很像r-组合 冒昧问句“什么是r-组合”？[/quote] 赵老师都给出算法了，这个就不要太就关注了 简单说一下吧： r-组合就是 N个数里面取出 r个数的(全部)组合 和排列不同，组合是不考虑顺序的，就是说 0，1，2，3，4 和 4，1，3，2，0 是同一个组合，但是是两个排列。 r-组合 例如r=5 , 0，1，2，3，4 就是一个5组合。 0，1，2，3，4 //最小5个数 0，1，2，3，5 0，1，2，3，6 .。。。。。。。。  5，6，7，8，9  //最大5个数 这一系列 数据，是 0～9 个数的全部 5 组合。 这些算法导论，组合数学上都有介绍

引用 14 楼 zheshiwodehao 的回复:你的思路是对的，好像你忽略了一个条件 “ a<b<c<d<e<f”  我把代码改了下，逆向验证过来 arrA[ 0, 1, 4, 5, 6, 7] = arrB[7144]  应该是 arrA[ 0, 1, 4, 5, 6, 7] = arrB[7714]                                                           arrA[ 0, 1, 3, 4, 5, 7] = arrB[5138]  应该是 arrA[ 0, 1, 3, 4, 5, 7] = arrB[4061]

求0..32中任取5个不重复的数且从小到大排列的所有解

题目可以转化为求0..32中任取5个数且从小到大排列的所有解，将这个解也按从左到右，从小到大排列，排完后，求其序数和排列的对应关系的计算方法。  可以用递归的思路解决。  “给定一个小点的输入，完整单步跟踪(同时按Alt+7键查看Call Stack里面从上到下列出的对应从里层到外层的函数调用历史)一遍。”是理解递归函数工作原理的不二法门！ 递归函数关注以下几个因素 ·退出条件 ·参数有哪些 ·返回值是什么 ·局部变量有哪些 ·全局变量有哪些 ·何时输出 ·会不会导致堆栈溢出

引用 14 楼 zheshiwodehao 的回复:[quote=引用 12 楼 user-5 的回复:] [quote=引用 10 楼 zheshiwodehao 的回复:] [quote=引用 8 楼 user-5 的回复:] 不好意思，前面错了，搞错的跳出循环的时机  arrB[854564]=arrA[4,14,15,17,21,28]         int index = n;         string strTemp = "arrB[" + index + "]=";          int intA = 0;         int intB = 1;         int intC = 2;         int intD = 3;         int intE = 4;         int intF = 5;          int intTemp = 0;         while (intA < 33)         {             while (intB < 33)             {                 while (intC < 33)                 {                     while (intD < 33)                     {                         while (intE < 33)                         {                             while (intF < 33)                             {                                 intF++;                                 intTemp++;                                 if (intTemp == index)                                 {                                     break;                                 }                             }                             if (intTemp == index)                             {                                 break;                             }                             intE++;                             intF = intE;                             //intTemp++;                         }                         if (intTemp == index)                         {                             break;                         }                         intD++;                         intE = intD;                         //intTemp++;                     }                     if (intTemp == index)                     {                         break;                     }                     intC++;                     intD = intC;                     //intTemp++;                 }                 if (intTemp == index)                 {                     break;                 }                 intB++;                 intC = intB;                 //intTemp++;             }             if (intTemp == index)             {                 break;             }             intA++;             intB = intA;             //intTemp++;         }          strTemp += "arrA[" + intA + "," + intB + "," + intC + "," + intD + "," + intE + "," + intF + "]";         lb.Text = strTemp; 我也写了一个类似的程序，不知你这个验证了上面的数据吗？我的程序最后两组数据验证是错误的。[/quote]  没有，刚才赶紧验证了下，发现自己太想当然了~MS是错误的~再想想先~[/quote] 你的思路是对的，好像你忽略了一个条件 “ a<b<c<d<e<f”[/quote]  嗯，修改过代码后和楼主一样了，也是最后两个验证有问题，其他都是正确的          int index =n;         int intA = 0;         int intB = 1;         int intC = 2;         int intD = 3;         int intE = 4;         int intF = 5;          string strTemp = "arrB[" + index + "]=";          for (int i = 1; i < index + 1; i++)         {             intF++;             while ((intB > 32) || (intC > 32) || (intD > 32) || (intE > 32) || (intF > 32))             {                 if (intF > 32)                 {                     intE++;                     if (intE > 32)                     {                         intD++;                         if (intD > 32)                         {                             intC++;                             if (intC > 32)                             {                                 intB++;                                 if (intB > 32)                                 {                                     intA++;                                     intB = intA + 1;                                 }                                 intC = intB + 1;                             }                             intD = intC + 1;                         }                         intE = intD + 1;                     }                     intF = intE + 1;                 }             }         }          strTemp += "arrA[" + intA + "," + intB + "," + intC + "," + intD + "," + intE + "," + intF + "]";         lb.Text = strTemp;  验证结果：   arrB[0]=arrA[ 0, 1, 2, 3, 4, 5]   arrB[1]=arrA[ 0, 1, 2, 3, 4, 6]   arrB[27]=arrA[ 0, 1, 2, 3, 4,32]  arrB[28]=arrA[ 0, 1, 2, 3, 5, 6]  arrB[29]=arrA[ 0, 1, 2, 3, 5, 7]  arrB[54]=arrA[ 0, 1, 2, 3, 5,32]  arrB[55]=arrA[ 0, 1, 2, 3, 6, 7]  arrB[406]=arrA[ 0, 1, 2, 4, 5, 6]  arrB[1135]=arrA[ 0, 1, 2, 6, 7, 8]  arrB[1460]=arrA[ 0, 1, 2, 7, 8, 9]   arrB[4060]=arrA[ 0, 1, 3, 4, 5, 6]  arrB[5138]=arrA[0,1,3,7,9,10] arrB[7144]=arrA[0,1,3,16,28,29]   规律应该是这个规律，最大的可能还是题错了，不一定是楼主写错了，可能题目本身就错了~

引用 4 楼 lm_whales 的回复:看看是否 r-组合------按照大小顺序排列。 前面是组合，后面是序号，r = 5 如果是，求出全组合和序数的关系，就可以了 否则的话，这个规律就不好总结了。。 不过看着很像r-组合 冒昧问句“什么是r-组合”？

引用 12 楼 user-5 的回复:[quote=引用 10 楼 zheshiwodehao 的回复:] [quote=引用 8 楼 user-5 的回复:] 不好意思，前面错了，搞错的跳出循环的时机  arrB[854564]=arrA[4,14,15,17,21,28]         int index = n;         string strTemp = "arrB[" + index + "]=";          int intA = 0;         int intB = 1;         int intC = 2;         int intD = 3;         int intE = 4;         int intF = 5;          int intTemp = 0;         while (intA < 33)         {             while (intB < 33)             {                 while (intC < 33)                 {                     while (intD < 33)                     {                         while (intE < 33)                         {                             while (intF < 33)                             {                                 intF++;                                 intTemp++;                                 if (intTemp == index)                                 {                                     break;                                 }                             }                             if (intTemp == index)                             {                                 break;                             }                             intE++;                             intF = intE;                             //intTemp++;                         }                         if (intTemp == index)                         {                             break;                         }                         intD++;                         intE = intD;                         //intTemp++;                     }                     if (intTemp == index)                     {                         break;                     }                     intC++;                     intD = intC;                     //intTemp++;                 }                 if (intTemp == index)                 {                     break;                 }                 intB++;                 intC = intB;                 //intTemp++;             }             if (intTemp == index)             {                 break;             }             intA++;             intB = intA;             //intTemp++;         }          strTemp += "arrA[" + intA + "," + intB + "," + intC + "," + intD + "," + intE + "," + intF + "]";         lb.Text = strTemp; 我也写了一个类似的程序，不知你这个验证了上面的数据吗？我的程序最后两组数据验证是错误的。[/quote]  没有，刚才赶紧验证了下，发现自己太想当然了~MS是错误的~再想想先~[/quote] 你的思路是对的，好像你忽略了一个条件 “ a<b<c<d<e<f”

引用 11 楼 zhao4zhong1 的回复:推导不出来，严重怀疑楼主题抄错了。 题没有错的亲，我验证了除了最后两组数据外的所有数据；我在怀疑最后两组数据是错的，或者是我规律直接找错了，所以想请大家帮忙验证下

引用 10 楼 zheshiwodehao 的回复:[quote=引用 8 楼 user-5 的回复:] 不好意思，前面错了，搞错的跳出循环的时机  arrB[854564]=arrA[4,14,15,17,21,28]         int index = n;         string strTemp = "arrB[" + index + "]=";          int intA = 0;         int intB = 1;         int intC = 2;         int intD = 3;         int intE = 4;         int intF = 5;          int intTemp = 0;         while (intA < 33)         {             while (intB < 33)             {                 while (intC < 33)                 {                     while (intD < 33)                     {                         while (intE < 33)                         {                             while (intF < 33)                             {                                 intF++;                                 intTemp++;                                 if (intTemp == index)                                 {                                     break;                                 }                             }                             if (intTemp == index)                             {                                 break;                             }                             intE++;                             intF = intE;                             //intTemp++;                         }                         if (intTemp == index)                         {                             break;                         }                         intD++;                         intE = intD;                         //intTemp++;                     }                     if (intTemp == index)                     {                         break;                     }                     intC++;                     intD = intC;                     //intTemp++;                 }                 if (intTemp == index)                 {                     break;                 }                 intB++;                 intC = intB;                 //intTemp++;             }             if (intTemp == index)             {                 break;             }             intA++;             intB = intA;             //intTemp++;         }          strTemp += "arrA[" + intA + "," + intB + "," + intC + "," + intD + "," + intE + "," + intF + "]";         lb.Text = strTemp; 我也写了一个类似的程序，不知你这个验证了上面的数据吗？我的程序最后两组数据验证是错误的。[/quote]  没有，刚才赶紧验证了下，发现自己太想当然了~MS是错误的~再想想先~

推导不出来，严重怀疑楼主题抄错了。


Question: 求取数组的长度和最小值不能同时进行

我还是不太明白，能帮我指点一下吗？谢谢！

文件居然用绝对引用的。。。


Question: Vs2012中C/C++　MySQL MediumBlob数据的写入

对于这种刚发的帖子，我总是毫不犹豫的顶了。如果火了就是个前排，可以混个脸熟，说不定谁好心就给粉了…稳赚不赔；如果沉了就感觉是我弄沉的，很有成就感，还能捞经验。


Question: 关于memcpy和函数参数的一个小问题

赵老师仿佛从不解决问题,他是精神领袖

楼上的抱歉,结贴的时候没看到你

赵老师怎么没来？坐等赵老师解答。

get_parcel函数应该是没错的，不过这种写法调用pqueue_extract时，需要调用者free内存，违背了谁分配谁释放的原则，有点蹩脚但称不上错误。而你写的代码则是错误的，把a的值copy到NULL处是不正确的，应该这么写：      int a = 3;     int *q = (int*)malloc(sizeof(int)); // 必须分配空间     fun(&a,q);     free(q);

memcpy  意思是内存复制. memcpy(parcel, data, sizeof(Parcel));   即是把  接收到data中的数据使用内存复制的方式复制到parcel中, 复制的字节数是sizeof(Parcel)

void fun(int *a,int *q) {     memcpy(q,a,sizeof(int));  //q传入的NULL,即没有分配任何内存空间, 你却想向里写东西, 当然程序就崩溃了.     return; } main() {     int a=3;     int *q=NULL;     fun(&a,q);  //q为NULL,      printf("%d\n",*q); }  而别人的程序却没有你这样的问题.


Question: 程序编译无错，调用函数后出现程序停止运行情况

话说，这样的变量，在打字的时候，大小写来回切换，不累吗？  引用 4 楼 yangyangsnr 的回复:int Add_Stu_Infomation int Init_Stu_Infomation 这两个函数实际上传递的都是形参，函数里所做的操作都是对形参所做的，而不会返回给实参。 请参考函数调用中的传值和传地址。 所以Stu_Infomation_S实际上使用时并没有分配空间。

引用 12 楼 sfd1234 的回复:语法正确，逻辑错误！仔细查找吧！可以单步就单步吧！  单步出来发现没进入调用的函数 但是还是找不到原因！

语法正确，逻辑错误！仔细查找吧！可以单步就单步吧！

引用 6 楼 u012148985 的回复:[quote=引用 4 楼 yangyangsnr 的回复:] int Add_Stu_Infomation int Init_Stu_Infomation 这两个函数实际上传递的都是形参，函数里所做的操作都是对形参所做的，而不会返回给实参。 请参考函数调用中的传值和传地址。 所以Stu_Infomation_S实际上使用时并没有分配空间。  有道理！我是不是要把实参作为返回值返回？[/quote] 可以，把那两个函数改成 Stu_Infomation *Add_Stu_Infomation Stu_Infomation *Init_Stu_Infomation 然后把参数返回就行了。 而且，你那个Add_Stu_Infomation里  Stu_Infomation_P->Stu_Name[Name_Maxsize]=Add_Stu_Name[Name_Maxsize]; 你这种赋值是错误的吧 对于C风格的字符串，可以使用 strcpy（Stu_Infomation_P->Stu_Name，Add_Stu_Name）; 来赋值。

明显的是语法正确,逻辑或数据不正确造成的BUG后程序退出.解决这种问题的王道是 断点调试.

引用 7 楼 zhuyf87 的回复:[quote=引用 6 楼 u012148985 的回复:] [quote=引用 4 楼 yangyangsnr 的回复:] int Add_Stu_Infomation int Init_Stu_Infomation 这两个函数实际上传递的都是形参，函数里所做的操作都是对形参所做的，而不会返回给实参。 请参考函数调用中的传值和传地址。 所以Stu_Infomation_S实际上使用时并没有分配空间。  有道理！我是不是要把实参作为返回值返回？[/quote]  参数可以用**[/quote]  没太听懂，我的意思是我的实参和形参名是一样的。 比如我在main函数中定义了 Stu_Infomation *Stu_Infomation_S int Add_Stu_ID;   char Add_Stu_Name[Name_Maxsize];  被调用函数为 int Add_Stu_Infomation(Stu_Infomation *Stu_Infomation_S,int Add_Stu_ID,char Add_Stu_Name[Name_Maxsize]) {   Stu_Infomation *Stu_Infomation_P;   Stu_Infomation_P=(Stu_Infomation*)malloc(sizeof(Stu_Infomation));   Stu_Infomation_P->Stu_ID=Add_Stu_ID;   Stu_Infomation_P->Stu_Name[Name_Maxsize]=Add_Stu_Name[Name_Maxsize];   Stu_Infomation_P->next=NULL;   Stu_Infomation_S->next=Stu_Infomation_P;   Stu_Infomation_S=Stu_Infomation_P;   /*if (sizeof(Stu_Infomation_S))       return 1; //Add Success   else       return 0; //Add Fail*/ }

引用 6 楼 u012148985 的回复:[quote=引用 4 楼 yangyangsnr 的回复:] int Add_Stu_Infomation int Init_Stu_Infomation 这两个函数实际上传递的都是形参，函数里所做的操作都是对形参所做的，而不会返回给实参。 请参考函数调用中的传值和传地址。 所以Stu_Infomation_S实际上使用时并没有分配空间。  有道理！我是不是要把实参作为返回值返回？[/quote]  参数可以用**

引用 4 楼 yangyangsnr 的回复:int Add_Stu_Infomation int Init_Stu_Infomation 这两个函数实际上传递的都是形参，函数里所做的操作都是对形参所做的，而不会返回给实参。 请参考函数调用中的传值和传地址。 所以Stu_Infomation_S实际上使用时并没有分配空间。  有道理！我是不是要把实参作为返回值返回？

引用 17 楼 u012148985 的回复:我仔细检查问题好像出在数组传参这里： 函数定义 Stu_Infomation * Add_Stu_Infomation(Stu_Infomation *Stu_Infomation_S,int Add_Stu_ID,char Add_Stu_Name[Name_Maxsize]) {   Stu_Infomation *Stu_Infomation_P;   Stu_Infomation_P=(Stu_Infomation*)malloc(sizeof(Stu_Infomation));   Stu_Infomation_P->Stu_ID=Add_Stu_ID;   Stu_Infomation_P->Stu_Name[Name_Maxsize]=Add_Stu_Name[Name_Maxsize];   Stu_Infomation_P->next=NULL;   return Stu_Infomation_P; 以下为调用语句： printf("Please Input StudentID\n"); 				  scanf("%d",&Add_Stu_ID); 				  printf("Please Input StudentName\n"); 				  scanf("%s",Add_Stu_Name); 				  Stu_Infomation_S->next=Add_Stu_Infomation(Stu_Infomation_S,Add_Stu_ID,Add_Stu_Name[Name_Maxsize]); 				  Stu_Infomation_S=Stu_Infomation_S->next; 				  if(Stu_Infomation_S->Stu_ID==Add_Stu_ID) 				  { 				    printf("Add Success!\n StudentID:%d  StudentName%s\n",Stu_Infomation_S->Stu_ID,Stu_Infomation_S->Stu_Name); 					ch=getch(); 				  } 				  else 				  { 				    printf("Add Fail!Press Any Key To Continue!\n"); 					ch=getch(); 				  }  不知道是不是这样传数组出现的问题  Stu_Infomation_P->Stu_Name[Name_Maxsize]=Add_Stu_Name[Name_Maxsize];  不能这样赋值吧。 用strcpy（）；

引用 14 楼 super_admi 的回复:话说，这样的变量，在打字的时候，大小写来回切换，不累吗？  [quote=引用 4 楼 yangyangsnr 的回复:] int Add_Stu_Infomation int Init_Stu_Infomation 这两个函数实际上传递的都是形参，函数里所做的操作都是对形参所做的，而不会返回给实参。 请参考函数调用中的传值和传地址。 所以Stu_Infomation_S实际上使用时并没有分配空间。[/quote]  只要一次定义好以后都是直接复制粘贴。。个人习惯

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

难道说大神都喜欢用好复杂好复杂的变量名字、、、  - -

看不懂。。。

引用 1 楼 zxhuser-8 的回复:果然，没有模版就直接回复还是不行啊 ??找到问题吗

果然，没有模版就直接回复还是不行啊


Question: 输入字符，如果是字母则报告并返回字母在字母表中序号的程序

谢谢2L,找了半天都发现这个问题。

lz把==和=搞混了 #include <stdio.h>  int if_char();  void main() {     int i;      printf("please enter something,if there is a letter,\n");     printf("i'll report it and its position in the alphabet.\n");     printf("enter a '&' to end this programme.\n");     while((i=if_char())!=0)                          //如果是&则结束     {         if(i>0)                            //如果是字母则显示其在字母表中的位置             printf(" and it's %d in the alphabet.\n",i);     }     printf("Bye!\n");     system("pause"); }   int if_char() {     int ch;     ch=getchar();            //获取字符     if(ch=='&')              // 如果是结束符号&则返回0         return 0;     else if((ch>=65&&ch<=90)||(ch>=97&&ch<=122))   //如果是字母则进入字母大小写判别     {         if(ch>=65&&ch<=90)        //如果是小写则返回字母ASCII码减64，（a返回1）         {             printf("%c is a letter",ch);             return ch-64;         }         else                 //如果是大写则返回字母ASCII码减96，（A返回1）         {             printf("%c is a letter",ch);             return ch-96;         }     }     else                                             //非字母返回-1         return -1; }


Question: 来拿分吧，

没有用'\0结尾’，所以n的值是随机的

因为字符数组没有用'\0'结尾，strlen是通过'\0'来判断字符串长度的，所以n的值会是一个不可预测的值


Question: 读c与指针，不明白这句话，强者帮忙

就是说从一个字符编码换到另一个字符编码不会出错

对于我们常用的编码            ' 0' 是字符0     ASCII码是 48   按你据说的是，value 的值应该是 字符(char)的1 （ASCII  为 49)或 0 (ASCII 为 48)，想转成数字1或0 (int)    value=value-48   这样就可以转换了， 当然用 value=value-'0'也是一样，编程器会自动把   '0' 转成 48  所以两种写法生成的汇编是一样的。   更为重要的是，不管你才用的是何种字符集，使用字符常量所产生的总是正确的值  这句话的理解是。假如某些机用的编码(也就是字符集)不再是我们常用语的编码    那 '0'　就不一定是　48了 如果你再用value=value-48　　结果就不对了 但如果你用value=value-'0'         结果还是对的，得回对应的数字

value=value–'0'; 因为此处的0是按当前的字符0的ASCII码来计算， 进而可读性和移植性更强些


Question: void*的作用

引用 2 楼 Cnwanglin 的回复:转换为void * 明显是错误的是的

编译不会通过

写法1就是个错的，参数类型已经对了，然后来这么一下，其实类型就错了。

void及void*用法

VC下编译不通过， 没有意义的转换

你自己转成void *之后,编译器又自动转换为了 char *,纯粹是多此一举,除了使用程序效率降低和吓唬菜鸟,再没有其它作用

写了两年代码了，第一次看到void*这个样子

引用 3 楼 zhdsheng 的回复:1 应该编译不过去吧 printf是不作类型检查的，也就是非类型安全的。所以C++中，用cout呢

这样写可能是想让我们这些菜鸟们看到这程序有种”竟然不懂这是什么意思，但看起来好像很厉害的样子“的感想。  (void*) 是多余的，printf 程序里面有强制转换机制， 它是根据%s    强制转换成 unsigned char * 类型,所以你在FileName前加个什么都无所谓了，都是多余,比如printf("This is the book name %s\n", (float *)FileName);  到函数里面照样被转成unsigned char * 处理。

这么改的目的是啥？如果输出名字，完全没意义啊。

1 应该编译不过去吧

转换为void * 明显是错误的

不但没这必要 而且是错的 %s要求参数就是char* 这么改 只能说 自作聪明


Question: 怎么才可以学好C语言，我只有初中毕业

专心弄一本书，读透多敲代码

关键还是兴趣吧，可以先自己看书，弄一本C语言的书，系统的看一边

加油吧，，，

有点盖空间花园的味道，建议楼主思考下为什么要学？有没有时间补各种数学知识，又怎么补，这些问题搞不清楚，那就没必要了

引用 7 楼 u013697891 的回复:[quote=引用 6 楼 king769147 的回复:] [quote=引用 3 楼 lovesmiles 的回复:] 又是一个玩页游的洗剪吹吗？ +1 学编程要学很多课程，不是单单学编程语言的。 离散数学，编译原理，操作系统原理，程序设计。。。多的去咯。。。[/quote] 可以简单说一下离散数学内容和有哪些应用吗[/quote]  离散数学是计算机课程基础课程,什么内容你搜一下就知道了. 这么说吧,其实我做编程那么久,一开始是单纯学编程语言的.但是如果不会算法和离散数学. 就觉得来来回回就只会 'if...while'之类的东西而已. 作用可能不是很明显而已,但是算法就很明显了...祝大家学习进步.

引用 13 楼 zhao4zhong1 的回复:初中毕业还是接着上高中或自学高中课程去吧。  希望楼主不要犯类似 “早知道吃完第七个包子就饱了，我为什么还要吃前六个包子呢？！” 这种低级错误。 这句话在理、、

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

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

看到赵老师的回复，我等菜鸟只好受教了，本来打算说说我的体会的，看来强者太多。楼主应该有所获！

初中毕业的人一般只有小学毕业水平

是来看赵老师的。受益匪浅。

我来看看而已，，自学最好观看视频，敲代码很重要。。

引用 6 楼 king769147 的回复:[quote=引用 3 楼 lovesmiles 的回复:] 又是一个玩页游的洗剪吹吗？ +1 学编程要学很多课程，不是单单学编程语言的。 离散数学，编译原理，操作系统原理，程序设计。。。多的去咯。。。[/quote] 可以简单说一下离散数学内容和有哪些应用吗

先自学高中数学和高等数学后，然后再看离散数学和概率论

引用 3 楼 lovesmiles 的回复:又是一个玩页游的洗剪吹吗？ +1 学编程要学很多课程，不是单单学编程语言的。 离散数学，编译原理，操作系统原理，程序设计。。。多的去咯。。。

小号啊。 我是来看赵老师的。 呵呵，页游洗剪吹。

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

又是一个玩页游的洗剪吹吗？


Question: 菜鸟问题，来拿分吧

某些面试管为了显示他牛逼,老出一些这样的题目让面试都来解答,纯属变态.写这种代码的人就该开除

这。。。我不会啊。。。。。。

你们把该说的都说了，我就不说啥了

引用 6 楼 xdayong 的回复:写这种代码的人，开除算了。类似于这样的代码，我一般都分开来写，别人看起来也舒服考试总喜欢考这个，不过现在已经考完高考啦

好好想想，你懂的，呵呵

不会

写这种代码的人，开除算了。类似于这样的代码，我一般都分开来写，别人看起来也舒服

看置顶贴，这样的问题被问了无数遍

不同的机器、不同的编译器就可能得出不同的结果，看置顶帖——http://bbs.csdn.net/topics/370153775

我能告诉solaris下cc 编译 结果：8 8 8 9 reahat下gcc编译 结果：8 8 7 8 这种问题，明显在c/c++置顶的帖子就是答案~~~


Question: windows下IO多路复用select怎么监听标准输入？？？

很久之前也遇到过这个问题，发现好像并没有特别好的解决方案。后来好像是用多线程封装select的方式实现的

我也 遇到了，看看这个https://blog.csdn.net/dengyejing/article/details/678444

引用 1 楼 adlay 的回复:windows 下一样可以用 select 来判断. Windows 以前还自带了一套完整的 POSIX 子系统的 能不能给个详解

windows下可以使用层叠IO


Question: 在结构体中定义另一个结构体类型变量可以吗

引用 11 楼 zhao4zhong1 的回复:http://edu.csdn.net/course/detail/2344 C语言指针与汇编内存地址-一.代码要素 http://edu.csdn.net/course/detail/2455 C语言指针与汇编内存地址-二.函数 http://edu.csdn.net/course/detail/2516 C语言指针与汇编内存地址-三.数组和二维数组 http://edu.csdn.net/course/detail/2517 C语言指针与汇编内存地址-四.三维数组 get

引用 6 楼 zhao4zhong1 的回复:#define Name_Maxsize 10 typedef struct List_2 {   char Class_Name[Name_Maxsize];   char Class_Term;   char Class_Score;   struct List_2 *next; } Stu_Score;  typedef struct Tree_1 {   int Room_ID;   struct Tree_1 *lchild,*rchild; } Stu_Room;  typedef struct List_1 {   int Stu_ID;   char Stu_Name[Name_Maxsize];   struct List_2 *Stu_Score_List_P;   struct Tree_1 *Stu_Room_Tree_P;   struct List_1 *next; } Stu_Information; int main() {     Stu_Information si;      si.Stu_ID=0;     return 0; }  赵老师，这个是不是就可以认为Stu_Information指向了List_2 和Tree_1，就是通过那两个指针连起来的，在对创建Stu——information的时候只给该对象申请空间就好，跟指针指向的list_2和？Tree_1是没有关系的？

感觉一个是全局的，一个是局部的（在结构体内定义的结构体，不能被外部调用定义新参数）

引用 5 楼 baichi4141 的回复:[quote=引用 4 楼 u012148985 的回复:] typedef struct List_Stu_Infomation {   int Stu_ID;   char Stu_Name[Name_Maxsize];   struct List_Stu_Infomation *next; }Stu_Infomation; 可以编译  typedef struct List_Stu_Infomation//Ñ§ÉúÐÅÏ¢±í½á¹¹ {   int Stu_ID;   char Stu_Name[Name_Maxsize];   Stu_Infomation *next; }Stu_Infomation; 编译报错 可见楼主没弄清楚这里的typedef是干什么的 typedef struct A { int x; } B; 这段代码实际上是两个功能的组合 第一个功能：strcut A { int x; }定义一个名为struct A的结构体 第二个功能：typedef struct A B;声明struct A的另一个名称B 所以，楼主的代码中，直到B;这一行为止，typedef这条语句都尚未完成，此时编译器根本就不知道有一个叫B的东西 所以楼主在struct A这个结构体里面，只能使用struct A来指代本类型  容易混淆的是，在C++中，struct A直接定义一个名为A的结构体，不需要typedef [/quote]+1

引用 5 楼 baichi4141 的回复:[quote=引用 4 楼 u012148985 的回复:] typedef struct List_Stu_Infomation {   int Stu_ID;   char Stu_Name[Name_Maxsize];   struct List_Stu_Infomation *next; }Stu_Infomation; 可以编译  typedef struct List_Stu_Infomation//Ñ§ÉúÐÅÏ¢±í½á¹¹ {   int Stu_ID;   char Stu_Name[Name_Maxsize];   Stu_Infomation *next; }Stu_Infomation; 编译报错 可见楼主没弄清楚这里的typedef是干什么的 typedef struct A { int x; } B; 这段代码实际上是两个功能的组合 第一个功能：strcut A { int x; }定义一个名为struct A的结构体 第二个功能：typedef struct A B;声明struct A的另一个名称B 所以，楼主的代码中，直到B;这一行为止，typedef这条语句都尚未完成，此时编译器根本就不知道有一个叫B的东西 所以楼主在struct A这个结构体里面，只能使用struct A来指代本类型  容易混淆的是，在C++中，struct A直接定义一个名为A的结构体，不需要typedef [/quote]  是这个问题！谢谢

引用 4 楼 u012148985 的回复:typedef struct List_Stu_Infomation {   int Stu_ID;   char Stu_Name[Name_Maxsize];   struct List_Stu_Infomation *next; }Stu_Infomation; 可以编译  typedef struct List_Stu_Infomation//Ñ§ÉúÐÅÏ¢±í½á¹¹ {   int Stu_ID;   char Stu_Name[Name_Maxsize];   Stu_Infomation *next; }Stu_Infomation; 编译报错 可见楼主没弄清楚这里的typedef是干什么的 typedef struct A { int x; } B; 这段代码实际上是两个功能的组合 第一个功能：strcut A { int x; }定义一个名为struct A的结构体 第二个功能：typedef struct A B;声明struct A的另一个名称B 所以，楼主的代码中，直到B;这一行为止，typedef这条语句都尚未完成，此时编译器根本就不知道有一个叫B的东西 所以楼主在struct A这个结构体里面，只能使用struct A来指代本类型  容易混淆的是，在C++中，struct A直接定义一个名为A的结构体，不需要typedef

引用 3 楼 zhao4zhong1 的回复:在结构体中定义另一个结构体类型变量 和 在结构体中定义指向另一个结构体类型的指针变量 不是一回事。 尽管两者都可以。 typedef struct List_Stu_Infomation {   int Stu_ID;   char Stu_Name[Name_Maxsize];   struct List_Stu_Infomation *next; }Stu_Infomation; 可以编译  typedef struct List_Stu_Infomation//Ñ§ÉúÐÅÏ¢±í½á¹¹ {   int Stu_ID;   char Stu_Name[Name_Maxsize];   Stu_Infomation *next; }Stu_Infomation; 编译报错

可以的,这样定义  另外一个结构体就变成了成员了

没问题啊~~


Question: 关于C中 i++ 与 ++i的问题

受教了 http://bbs.csdn.net/topics/370153775

引用 7 楼 zhao4zhong1 的回复:http://bbs.csdn.net/topics/370153775 二楼  引用printf("i,i++,i++ = %d,%d,%d\n",i,i++,i++); 代码是错的 结果没意义  基于结果得到的结论也没意义  怎么错的 看置顶帖 二楼

引用 3 楼 user-3 的回复:int i = 10; 0041139E  mov         dword ptr [i],0Ah   	printf("i = %d\n",i); 004113A5  mov         esi,esp   004113A7  mov         eax,dword ptr [i]   004113AA  push        eax   004113AB  push        offset string "i = %d\n" (415764h)   004113B0  call        dword ptr [__imp__printf (4182B0h)]   004113B6  add         esp,8   004113B9  cmp         esi,esp   004113BB  call        @ILT+305(__RTC_CheckEsp) (411136h)   	printf("i++ = %d\n",i++); 004113C0  mov         eax,dword ptr [i]   004113C3  mov         dword ptr [ebp-0D0h],eax   004113C9  mov         ecx,dword ptr [i]   004113CC  add         ecx,1   004113CF  mov         dword ptr [i],ecx   004113D2  mov         esi,esp   004113D4  mov         edx,dword ptr [ebp-0D0h]   004113DA  push        edx   004113DB  push        offset string "i++ = %d\n" (415758h)   004113E0  call        dword ptr [__imp__printf (4182B0h)]   004113E6  add         esp,8   004113E9  cmp         esi,esp   004113EB  call        @ILT+305(__RTC_CheckEsp) (411136h)   	printf("i++ = %d\n",i++); 004113F0  mov         eax,dword ptr [i]   004113F3  mov         dword ptr [ebp-0D0h],eax   004113F9  mov         ecx,dword ptr [i]   004113FC  add         ecx,1   004113FF  mov         dword ptr [i],ecx   00411402  mov         esi,esp   00411404  mov         edx,dword ptr [ebp-0D0h]   0041140A  push        edx   0041140B  push        offset string "i++ = %d\n" (415758h)   00411410  call        dword ptr [__imp__printf (4182B0h)]   00411416  add         esp,8   00411419  cmp         esi,esp   0041141B  call        @ILT+305(__RTC_CheckEsp) (411136h)    	i=100; 00411420  mov         dword ptr [i],64h   	printf("i,i++,i++ = %d,%d,%d\n",i,i++,i++); 00411427  mov         eax,dword ptr [i]   0041142A  mov         dword ptr [ebp-0D0h],eax   00411430  mov         ecx,dword ptr [i]   00411433  add         ecx,1   00411436  mov         dword ptr [i],ecx   00411439  mov         edx,dword ptr [i]   0041143C  mov         dword ptr [ebp-0D4h],edx   00411442  mov         eax,dword ptr [i]   00411445  add         eax,1   00411448  mov         dword ptr [i],eax   0041144B  mov         esi,esp   0041144D  mov         ecx,dword ptr [ebp-0D0h]   00411453  push        ecx   00411454  mov         edx,dword ptr [ebp-0D4h]   0041145A  push        edx   0041145B  mov         eax,dword ptr [i]   0041145E  push        eax   0041145F  push        offset string "i,i++,i++ = %d,%d,%d\n" (41573Ch)   00411464  call        dword ptr [__imp__printf (4182B0h)]   0041146A  add         esp,10h   0041146D  cmp         esi,esp   0041146F  call        @ILT+305(__RTC_CheckEsp) (411136h) 有毛病

引用 4 楼 lin5161678 的回复:[quote=引用 2 楼 xxxxing 的回复:]  不运行 就说 是错了  能说什么 不要以为 能运行就是对的好不好  让你去看置顶帖你看来没有  [/quote] 正在看

引用 2 楼 xxxxing 的回复:不运行 就说 是错了  能说什么 不要以为 能运行就是对的好不好  让你去看置顶帖你看来没有

引用 1 楼 lin5161678 的回复:printf("i,i++,i++ = %d,%d,%d\n",i,i++,i++); 代码是错的 结果没意义  基于结果得到的结论也没意义  怎么错的 看置顶帖  不运行 就说 是错了  能说什么


Question: 字符串超有趣问题！

c语言规定。。。

真的 char Array[] = "A"   "B"    "C";  只在最后的 C上会加结束符 '\0' 不止数组和函数参数可以这样，所有可以写字符串的都可以这样， sizeof("Wu"     "Dong");   结果为7   ,反汇编看一下它就是连成WuDong这个字符串放.. “Wu"为毛不自动加结束标志   求楼下解答

#include <stdio.h> int main() {     printf("%d" "%d" "%d" "%d" "\n", 1, 2, 3, 4);//为什么这样也行？     return 0; }  C标准中会自动把中间的双引号去掉，这个语句跟printf("%d %d %d %d \n", 1, 2, 3, 4); 这句效果是一样的。

哎，乌龟的屁股--------龟腚。

参考MSDN：http://msdn.microsoft.com/zh-cn/library/wc7014hz.aspx int printf(    const char *format [,    argument]...  ); 参数  format      格式控件。 argument      可选参数。 实例：    char     ch = 'h',              *string = "computer";    wchar_t  wch = L'w',              *wstring = L"Unicode";    int      count = -9234;    double   fp = 251.7366;     // Display integers    printf( "Integer formats:\n"            "   Decimal: %d  Justified: %.6d  "            "Unsigned: %u\n",            count, count, count, count );

C++ String Literals A string literal consists of zero or more characters from the source character set surrounded by double quotation marks ("). A string literal represents a sequence of characters that, taken together, form a null-terminated string.  Syntax  string-literal :  "s-char-sequenceopt" L"s-char-sequenceopt"  s-char-sequence :  s-char s-char-sequence s-char  s-char :  any member of the source character set except the double quotation mark ("), backslash (\), or newline character escape-sequence  C++ strings have these types:   Array of char[n], where n is the length of the string (in characters) plus 1 for the terminating '\0' that marks the end of the string   Array of wchar_t, for wide-character strings  The result of modifying a string constant is undefined. For example:  char *szStr = "1234"; szStr[2] = 'A';      // Results undefined  Microsoft Specific   In some cases, identical string literals can be “pooled” to save space in the executable file. In string-literal pooling, the compiler causes all references to a particular string literal to point to the same location in memory, instead of having each reference point to a separate instance of the string literal. The/Gf compiler option enables string pooling.  END Microsoft Specific  When specifying string literals, adjacent strings are concatenated. Therefore, this declaration:  char szStr[] = "12" "34";  is identical to this declaration:  char szStr[] = "1234";  This concatenation of adjacent strings makes it easy to specify long strings across multiple lines:  cout << "Four score and seven years "         "ago, our forefathers brought forth "         "upon this continent a new nation.";  In the preceding example, the entire string Four score and seven years ago, our forefathers brought forth upon this continent a new nation. is spliced together. This string can also be specified using line splicing as follows:  cout << "Four score and seven years \ ago, our forefathers brought forth \ upon this continent a new nation.";  After all adjacent strings in the constant have been concatenated, the NULL character, '\0', is appended to provide an end-of-string marker for C string-handling functions.  When the first string contains an escape character, string concatenation can yield surprising results. Consider the following two declarations:  char szStr1[] = "\01" "23"; char szStr2[] = "\0123";  Although it is natural to assume that szStr1 and szStr2 contain the same values, the values they actually contain are shown in Figure 1.1.  Figure 1.1   Escapes and String Concatenation    Microsoft Specific   The maximum length of a string literal is approximately 2,048 bytes. This limit applies to strings of type char[] and wchar_t[]. If a string literal consists of parts enclosed in double quotation marks, the preprocessor concatenates the parts into a single string, and for each line concatenated, it adds an extra byte to the total number of bytes.   For example, suppose a string consists of 40 lines with 50 characters per line (2,000 characters), and one line with 7 characters, and each line is surrounded by double quotation marks. This adds up to 2,007 bytes plus one byte for the terminating null character, for a total of 2,008 bytes. On concatenation, an extra character is added to the total number of bytes for each of the first 40 lines. This makes a total of 2,048 bytes. (The extra characters are not actually written to the string.) Note, however, that if line continuations (\) are used instead of double quotation marks, the preprocessor does not add an extra character for each line.  END Microsoft Specific  Determine the size of string objects by counting the number of characters and adding 1 for the terminating '\0' or 2 for type wchar_t.  Because the double quotation mark (") encloses strings, use the escape sequence (\") to represent enclosed double quotation marks. The single quotation mark (') can be represented without an escape sequence. The backslash character (\) is a line-continuation character when placed at the end of a line. If you want a backslash character to appear within a string, you must type two backslashes (\\). (SeePhases of Translation in the Preprocessor Reference for more information about line continuation.)  To specify a string of type wide-character (wchar_t[]), precede the opening double quotation mark with the character L. For example:  wchar_t wszStr[] = L"1a1g";  All normal escape codes listed in Character Constants are valid in string constants. For example:  cout << "First line\nSecond line"; cout << "Error! Take corrective action\a";  Because the escape code terminates at the first character that is not a hexadecimal digit, specification of string constants with embedded hexadecimal escape codes can cause unexpected results. The following example is intended to create a string literal containing ASCII 5, followed by the characters five:  \x05five"  The actual result is a hexadecimal 5F, which is the ASCII code for an underscore, followed by the characters ive. The following example produces the desired results:   "\005five"     // Use octal constant. "\x05" "five"  // Use string splicing.

标准规定  预处理阶段 把代码中任一多个空白字符分割的字符串字面量处理为一个字符串


Question: 求解 为何函数外与函数内运行结果不一样

假设你第一次选Y/N时选了N，那么程序不会执行整个while（c=='Y')循环，在这个while循环后第一句处时：p1==p2, n==0; 然后到p=head语句时 p1==p2 && p1==head, 后一个循环可以正常显示内容，程序继续执行free(p1)，然后p1 == p2 && p1 == head && head->已释放内存, 程序退出时返回head.... 也就是说main程序中的p是一个指向已释放内存的指针，你还指望它能正确显示无效内存中的数值吗？


Question: 考试报名系统    求帮助！！1

排名参考代码 按学校 班级 成绩三个关键字排降序 http://pan.baidu.com/s/1ntuNH0X

附加一些成绩评判的函数，如低于60分，高于90分，总分排名

注册 登录 删除用户 更改资料 成绩查询 成绩输入等


Question: 简单但重要，求帮忙！~针对样本大时就运行不了了啊

大文件读取时你可以采用分块的形式进行读取  以你的个例需求点来说，需要读取每一行的数据，你可以尝试这样做  每次读取32K字节大小的内容，如果读取的32K中不包含换行符‘\n’，那么这32K的内容都在一行，处理这32K的内容； 如果这32K内容中有换行符，那么以换行符为分界点，进行处理，直到在这32K内容里面找不到换行符  对文件进行分块处理，可以提高处理的效率   仅供参考

有两句多余了。。。 #include <stdio.h> #include <stdlib.h> #include <string.h>  int main( ) { 	char ch; 	char str_temp[1000]; 	int i; 	FILE* fp_in; 	FILE* fp_out; 	fp_in=fopen("1.txt","r"); 	if(fp_in==NULL) 	{ 		printf("files can not open!\n"); 		exit(1); 	} 	fp_out=fopen("2.txt","w"); 	if(fp_out==NULL) 	{ 		printf("files can not save!\n"); 		exit(2); 	} 	for(;;) 	{ 		for(i=0;i<46;i++) 		{ 			fgetc(fp_in); 		} 		fscanf(fp_in,"%s",str_temp); 		while((ch=fgetc(fp_in))!='\n'); 		if(ch==EOF)break; 		puts(str_temp); 		fprintf(fp_out,"%s\n",str_temp); 	} 	fclose(fp_in); 	fclose(fp_out); 	return 0; }

这样？ #include <stdio.h> #include <stdlib.h> #include <string.h>  int main( ) { 	char ch; 	char str_temp[1000]; 	int i; 	FILE* fp_in; 	FILE* fp_out; 	fp_in=fopen("1.txt","r"); 	if(fp_in==NULL) 	{ 		printf("files can not open!\n"); 		exit(1); 	} 	fp_out=fopen("2.txt","w"); 	if(fp_out==NULL) 	{ 		printf("files can not save!\n"); 		exit(2); 	} 	for(;;) 	{ 		ch=fgetc(fp_in); 		if(ch==EOF)break; 		for(i=0;i<45;i++) 		{ 			fgetc(fp_in); 		} 		fscanf(fp_in,"%s",str_temp); 		while((ch=fgetc(fp_in))!='\n'); 		if(ch==EOF)break; 		puts(str_temp); 		fprintf(fp_out,"%s\n",str_temp); 	} 	fclose(fp_in); 	fclose(fp_out); 	return 0; }  输出 夜明珠110kV白明线明57开关保护装置通讯故障 五峰GPS对时装置报警 郭家岗2#直流充电柜直流系统故障 郭家岗预告警信号 郭家岗2#直流充电柜直流系统故障 郭家岗预告警信号 麂子河220kV雁麂二回麂226开关PSL602U录波扰动数据在记录 麂子河220kV雁麂二回麂226开关PSL602U录波扰动数据在记录 麂子河220kV麂桑线麂221开关PSL602U录波扰动数据在记录 麂子河220kV麂桑线麂221开关PSL602U录波扰动数据在记录 五峰GPS对时装置报警

看了一半代码，好像你程序只要写超过6000字节就出错了吧（非法内存访问）？ 因为写2.txt 只有 fprintf(fp2,"%s\n",b); 一句，而且是在读取整个1.txt后。 哦哦哦, 在循环中j可能早就超过6000了， 但是你仍然*(b+j)=*(a+i);  *(b+j)='\0' ....  请将fprintf()移到while (fgets(a,sizeof(a),fp1))循环中并重置j=0;这样应该就可以解决问题了。


Question: 定义了一个指向结构类型的指针，然后在给结构体内的成员赋值时编译出错，求大家帮忙看看，谢谢~~

引用 3 楼 baichi4141 的回复:从缩进来看，大概楼主以为赋值语句不用放在函数中也可以执行吧 真的是这个原因，谢谢帮助

VS IDE中，在符号PIDREG_DEFAULTS上点鼠标右键，选转到定义。

引用 5 楼 Cnwanglin 的回复:[quote=引用 3 楼 baichi4141 的回复:] 从缩进来看，大概楼主以为赋值语句不用放在函数中也可以执行吧  不会吧...超强的纠错能力![/quote] 神人！ 不过错误提示好像是定义指针变量那一句就出错了，不是赋值才出错的

引用 3 楼 baichi4141 的回复:从缩进来看，大概楼主以为赋值语句不用放在函数中也可以执行吧 碉堡了

引用 3 楼 baichi4141 的回复:从缩进来看，大概楼主以为赋值语句不用放在函数中也可以执行吧  不会吧...超强的纠错能力!

从缩进来看，大概楼主以为赋值语句不用放在函数中也可以执行吧

#include <iostream> using namespace std;  typedef struct { 	int index; }Pos;  typedef Pos* pos;  void main() { 	Pos p; 	pos p2=&p; 	p2->index = 2; } 可以正常执行啊，是不是其他地方有影响？

貌似没问题  截什么图，粘帖啊，不能复制去编译

引用 10 楼 user-7123456789 的回复:好像dsp ccs的界面是的

好像dsp ccs的界面


Question: 关于C语言函数可重入的问题

谢谢大大的解答，看来还是学的太浅了。

你的信号处理函数中有调用 localtime_r 的地方吗？ 有的话会锁死就很自然了

引用 7 楼 pang68599 的回复:@zhao4zhong1 And @mymtom   两位大大，我想的是为什么像我那样写会产生死锁，这个死锁是如何产生的？  自己写个程序模拟就可以啦！  *-  * Copyright (C), 2014, mymtom  *  * vi:set ts=4 sw=4:  */ #ifndef lint static const char rcsid[] = "$Id$"; #endif /* not lint */  /**  * @file    foo.c  * @brief     */  #include <stdio.h> #include <signal.h>  #include <pthread.h> #include <sched.h>  struct tm * my_localtime(const time_t *timep) {     struct tm *res;      sigset_t set, oset;      sigemptyset(&set);     sigaddset(&set, SIGINT);      sigprocmask(SIG_SETMASK, &set, &oset);     res = localtime(timep);     sigprocmask(SIG_SETMASK, &oset, NULL);      return res; }  #if defined(_REENTRANT_LOCALTIME) #define localtime   my_localtime #endif  static void sig_int(int sig) {     time_t tks;     struct tm tms;      printf("sig=%d\n", sig);     tks = time(NULL);     tms = *localtime(&tks); }  void *worker(void *arg) {     int i;     time_t tks;     struct tm tms;      for (i = 0; i < 10000; ++i) {         printf("i=%d\n", i);         tks = time(NULL);         tms = *localtime(&tks);         sched_yield();     }      return NULL; }  int main(int argc, char *argv[]) {     int i;     pthread_t tid;      sigset(SIGINT, &sig_int);      pthread_create(&tid, NULL, &worker, NULL);      sched_yield();     for (i = 0; i < 10000; ++i) {         pthread_kill(tid, SIGINT);         sched_yield();     }     pthread_join(tid, NULL);      return 0; }  因为localtime和会调用一个处理时区的函数__tz_convert，这个函数会使用锁l进行同步 如果加锁后解锁前收到信号，执行信号处理函数的时候再次加锁，就会死锁，这个程序我编译后，运行不到5次就出现死锁了。 下面是用调试器看到的信息，注意标红的部分，死锁出现在信号处理函数的地方！ $ ./foo sig=2 i=0 sig=2 i=1 sig=2 i=2 sig=2 i=3 sig=2 i=4 sig=2 i=5 sig=2 i=6 sig=2 i=7 sig=2 i=8 sig=2 i=9 sig=2 i=10 sig=2 i=11 sig=2 i=12 sig=2 i=13 sig=2 i=14 sig=2 i=15 sig=2 i=16 sig=2 i=17 sig=2 i=18 sig=2 i=19 sig=2 i=20 sig=2 i=21 sig=2 i=22 i=23 i=24 i=25 i=26 i=27 i=28 i=29 i=30 i=31 i=32 i=33 i=34 i=35 i=36 i=37 i=38 i=39 i=40 i=41 i=42 i=43 i=44 i=45 i=46 i=47 i=48 i=49 i=50 i=51 i=52 i=53 i=54 i=55 i=56 i=57 i=58 i=59 i=60 i=61 i=62 i=63 i=64 i=65 i=66 i=67 i=68 i=69 i=70 i=71 i=72 i=73 i=74 i=75 i=76 i=77 i=78 i=79 i=80 i=81 i=82 i=83 i=84 i=85 i=86 i=87 i=88 i=89 i=90 i=91 i=92 i=93 i=94 i=95 i=96 i=97 i=98 i=99 i=100 i=101 i=102 i=103 i=104 i=105 i=106 i=107 i=108 i=109 i=110 i=111 i=112 i=113 i=114 i=115 i=116 i=117 i=118 i=119 i=120 i=121 i=122 i=123 i=124 i=125 i=126 i=127 i=128 i=129 i=130 i=131 i=132 i=133 i=134 i=135 i=136 i=137 i=138 i=139 i=140 i=141 i=142 i=143 i=144 i=145 i=146 i=147 i=148 i=149 i=150 i=151 i=152 i=153 i=154 i=155 i=156 i=157 i=158 i=159 i=160 i=161 i=162 i=163 i=164 i=165 i=166 i=167 i=168 i=169 i=170 i=171 i=172 i=173 i=174 i=175 i=176 i=177 i=178 i=179 i=180 i=181 i=182 i=183 i=184 i=185 i=186 i=187 i=188 i=189 i=190 i=191 i=192 i=193 i=194 i=195 i=196 i=197 i=198 i=199 i=200 i=201 i=202 i=203 i=204 i=205 i=206 i=207 i=208 i=209 i=210 i=211 i=212 i=213 i=214 i=215 i=216 i=217 i=218 i=219 i=220 i=221 i=222 i=223 i=224 i=225 i=226 i=227 i=228 i=229 i=230 sig=2 ^Z [1]+  Stopped                 ./foo $ bg [1]+ ./foo & $ ps   PID TTY          TIME CMD 26461 pts/6    00:00:00 bash 26603 pts/6    00:00:00 foo 26612 pts/6    00:00:00 ps $ gdb GNU gdb (GDB) Red Hat Enterprise Linux (7.2-48.el6) Copyright (C) 2010 Free Software Foundation, Inc. License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html> This is free software: you are free to change and redistribute it. There is NO WARRANTY, to the extent permitted by law.  Type "show copying" and "show warranty" for details. This GDB was configured as "x86_64-redhat-linux-gnu". For bug reporting instructions, please see: <http://www.gnu.org/software/gdb/bugs/>. (gdb) attach 26603 Attaching to process 26603 Reading symbols from /home/feel/devel/mymtom/src/foo/foo...done. Reading symbols from /lib64/libpthread.so.0...(no debugging symbols found)...done. [Thread debugging using libthread_db enabled] [New Thread 0x7f32205a9700 (LWP 26604)] Loaded symbols for /lib64/libpthread.so.0 Reading symbols from /lib64/libc.so.6...(no debugging symbols found)...done. Loaded symbols for /lib64/libc.so.6 Reading symbols from /lib64/ld-linux-x86-64.so.2...(no debugging symbols found)...done. Loaded symbols for /lib64/ld-linux-x86-64.so.2 0x000000308040803d in pthread_join () from /lib64/libpthread.so.0 Missing separate debuginfos, use: debuginfo-install glibc-2.12-1.25.el6.x86_64 (gdb) bt #0  0x000000308040803d in pthread_join () from /lib64/libpthread.so.0 #1  0x0000000000400a31 in main (argc=1, argv=0x7fffafe93fc8) at foo.c:83 (gdb) info thread   2 Thread 0x7f32205a9700 (LWP 26604)  0x000000307f8f619e in __lll_lock_wait_private () from /lib64/libc.so.6 * 1 Thread 0x7f32205ab700 (LWP 26603)  0x000000308040803d in pthread_join () from /lib64/libpthread.so.0 (gdb) thread 2 [Switching to thread 2 (Thread 0x7f32205a9700 (LWP 26604))]#0  0x000000307f8f619e in __lll_lock_wait_private ()    from /lib64/libc.so.6 (gdb) bt #0  0x000000307f8f619e in __lll_lock_wait_private () from /lib64/libc.so.6 #1  0x000000307f89cc9d in _L_lock_2163 () from /lib64/libc.so.6 #2  0x000000307f89ca57 in __tz_convert () from /lib64/libc.so.6 #3  0x00000000004008e2 in sig_int (sig=2) at foo.c:49 #4  <signal handler called> #5  0x000000307f89a7be in __offtime () from /lib64/libc.so.6 #6  0x000000307f89d1bf in __tzfile_compute () from /lib64/libc.so.6 #7  0x000000307f89cb17 in __tz_convert () from /lib64/libc.so.6 #8  0x0000000000400961 in worker (arg=0x0) at foo.c:61 #9  0x00000030804077e1 in start_thread () from /lib64/libpthread.so.0 #10 0x000000307f8e68ed in clone () from /lib64/libc.so.6 (gdb)

引用 1 楼 pang68599 的回复:如何实现才能让  static somelock;  int localtime_r(...)  {      lock(somelock);           ...do something...       unlock(somelock);  }   是可重入的 试试看，不保证行： #define MAXRL 100 static somelock[MAXRL]; int localtime_r(...) {     static int L=0;     assert(L<MAXRL);     lock(somelock[L++]);       ...do something...     unlock(somelock[--L]); }

《Windows核心编程》 Synchronization Functions The following functions are used in synchronization.    CancelWaitableTimer   CreateEvent   CreateMutex   CreateSemaphore   CreateWaitableTimer   DeleteCriticalSection   EnterCriticalSection   GetOverlappedResult   InitializeCriticalSection   InitializeCriticalSectionAndSpinCount   InterlockedCompareExchange   InterlockedDecrement   InterlockedExchange   InterlockedExchangeAdd   InterlockedIncrement   LeaveCriticalSection   MsgWaitForMultipleObjects   MsgWaitForMultipleObjectsEx   OpenEvent   OpenMutex   OpenSemaphore   OpenWaitableTimer   PulseEvent   QueueUserAPC   ReleaseMutex   ReleaseSemaphore   ResetEvent   SetCriticalSectionSpinCount   SetEvent   SetWaitableTimer   SignalObjectAndWait   TimerAPCProc   TryEnterCriticalSection   WaitForMultipleObjects   WaitForMultipleObjectsEx   WaitForSingleObject   WaitForSingleObjectEx

引用 4 楼 mymtom 的回复:这个函数式不可重入的，在信号处理函数里不能使用这个函数的。 如果一定要使用，可以考虑在函数中屏蔽信号，这个方法是否周全，还请大家多多指教！  #include <stdio.h> #include <stdlib.h>  #include <unistd.h>  #include <pthread.h> #include <sched.h>  int increment_counter(void) {     static int counter = 0;     static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;      int result;      /* 设置信号掩码 */     sigset_t set, oset;     sigemptyset(&set);     sigaddset(&set, SIGINT);     pthread_sigmask(SIG_SETMASK, &set, &oset);      pthread_mutex_lock(&mutex);     result = ++counter;     sleep(1);     pthread_mutex_unlock(&mutex);      /* 恢复信号掩码 */     pthread_sigmask(SIG_SETMASK, &oset, NULL);      return result; }  void sig_int(int sig) {     printf("%d:sig_intr\n", increment_counter()); }  int main(int argc, char *argv[]) {     int i, n;     pthread_t tid[10];      sigset(SIGINT, &sig_int);      printf("%d\n", increment_counter());     printf("%d\n", increment_counter());     printf("%d\n", increment_counter());     printf("%d\n", increment_counter());     printf("%d\n", increment_counter());      return 0; }   版主的意思是在我处理localtime_r的把此进程的信号给（会触发localtime_r）屏蔽掉么？

引用 3 楼 zhao4zhong1 的回复:[quote=引用 1 楼 pang68599 的回复:] 如何实现才能让  static somelock;  int localtime_r(...)  {      lock(somelock);           ...do something...       unlock(somelock);  }   是可重入的 试试看，不保证行： #define MAXRL 100 static somelock[MAXRL]; int localtime_r(...) {     static int L=0;     assert(L<MAXRL);     lock(somelock[L++]);       ...do something...     unlock(somelock[--L]); } [/quote]  如果这么使用 ...do something...就不是互斥的了， ...do something...是不是会被调用多次。


Question: 说说目前C语言的用途

毕竟是基础语言，我想大家都是从c语言开始的吧

搞游戏，openGL什么的。。。。

引用 5 楼 zhao4zhong1 的回复:[quote=引用 4 楼 zxh707wk 的回复:] 只要不谈界面，啥都行 Quake3的界面是C写的吧。[/quote]正在玩linux版的，感觉好流畅。。。

主要应用在嵌入式领域

引用 4 楼 zxh707wk 的回复:只要不谈界面，啥都行 Quake3的界面是C写的吧。

只要不谈界面，啥都行

Flash是C++开发的吧。

只要不是与网页和Flash界面相关的， C语言都可以开发之。 复杂界面不占优势；后台和底层的实现，C语言大有可为。。

C语言是很通用的语言， Linux， Window， 都可以有相应的运行环境， 嵌入式开发更是厉害；

引用 14 楼 zhangleiyigeren 的回复:[quote=引用 12 楼 zhao4zhong1 的回复:] 顺便打个广告，挣点资源分：  Excel最新版竟然也不支持显示超过32767行数据对应的折线图！ 无奈自己编程实现全屏分行显示大于32767行数据对应的折线图功能。 最多7列数据（支持鼠标左键点击折线图时在底部提示行显示对应第几行和对应数值，点击提示行轮换在最上面显示某组折线并以粗体字显示其对应数值） http://download.csdn.net/detail/zhao4zhong1/7610833  为什么 不整个可以32行或者16行，再甚8行的也好啊，，，前段时间刚用上过[/quote] 不是传说中的最多赚100积分而且就算是0资源分也能得到1分吗。

引用 10 楼 zhao4zhong1 的回复:这个旧模板先凑合用： 计算机组成原理→DOS命令→汇编语言→C语言（不包括C++）、代码书写规范→数据结构、编译原理、操作系统→计算机网络、数据库原理、正则表达式→其它语言（包括C++）、架构……

引用 9 楼 u013470052 的回复:引用 8 楼 assembly 的回复:这么经典的问题，赵老师没有模板吗？就是  应该搞个模板

引用 14 楼 zhangleiyigeren 的回复:[quote=引用 12 楼 zhao4zhong1 的回复:] 顺便打个广告，挣点资源分：  Excel最新版竟然也不支持显示超过32767行数据对应的折线图！ 无奈自己编程实现全屏分行显示大于32767行数据对应的折线图功能。 最多7列数据（支持鼠标左键点击折线图时在底部提示行显示对应第几行和对应数值，点击提示行轮换在最上面显示某组折线并以粗体字显示其对应数值） http://download.csdn.net/detail/zhao4zhong1/7610833 为什么 不整个可以32行或者16行，再甚8行的也好啊，，，前段时间刚用上过 反正是源代码，根据自己需要随便你怎么改。

12楼就是目前C语言的用途之一。

引用 12 楼 zhao4zhong1 的回复:顺便打个广告，挣点资源分：  Excel最新版竟然也不支持显示超过32767行数据对应的折线图！ 无奈自己编程实现全屏分行显示大于32767行数据对应的折线图功能。 最多7列数据（支持鼠标左键点击折线图时在底部提示行显示对应第几行和对应数值，点击提示行轮换在最上面显示某组折线并以粗体字显示其对应数值） http://download.csdn.net/detail/zhao4zhong1/7610833  为什么 不整个可以32行或者16行，再甚8行的也好啊，，，前段时间刚用上过


Question: 优先队列 之 包裹分拣 的两个细节问题

这两个指针指向的内容是都是存放在栈空间的，当执行完对应的函数后这个指针指向的内容就被释放了，为了将内容保存下来，才创建一个堆空间，要找到调用这些函数是什么时候，传递参数的时候，这个指针所指向的内容是在堆还是栈  以上纯属猜测，如有雷同，纯属扯淡~

楼上的大哥,都凌晨2点半了你怎么还不睡觉?

因为get_parcel传入的第2个参数是Parcel*而不是Parcel**, 也就是说需要获取的数据需要充填到调用者分配的内存中而不是PQueue中本来使用的内存。另外pqueue_extract明显返回了一个指针，指向PQueue中原本Parcel使用的内部内存，因为是内部使用的内存，所有需要复制内容到调用者所分配的内存内然后释放这块内部内存。 而put_parcel不使用用户传递的Parcel*作为PQueue内部内存是因为用户传递的可能是一个局部变量（即在栈上），可能一会就失效了。程序必须保证Parcel使用的内存处于堆上，所以需要自己malloc一块然后复制数据  至于get_parcel第二个参数不使用Parcel**是为了保证作为库函数有相似的行为，比如插入和取出时用户分配的内存都必须由用户释放，插入和取出时都可以使用局部变量。 同时可以防止函数处于dll中而调用者处于exe中并且两者使用不同的内存管理器时dll中分配的内存在exe中无法释放。


Question: C

跨地区传输（非局域网),你要知道你另一台机的公网ip和端口.........种种层层的路由器交换机的关联.......你没办法搞定的..除非你用一台公网的机子接收这两台电脑发来的信息，你就知道他们各自的路径了，之后就可以用这些路径互传.. 有本事买到一个公网IP,你就可以跨了.

百度 DNAT SNAT

可以建个讨论群

能不能加个QQ好友啊，有问题可以请教你们啊，qq：345917505，希望各位大哥今后多多指教啊。我还有很多都不懂啊。

不知道有多少前人掉在TCP Socket send(人多)send(病少)send(财富) recv(人多病)recv(少财富) 陷阱里面啊！ http://bbs.csdn.net/topics/380167545

十分感谢啊.虽然,无以回报

需要在 路由器配置一个 内外网ip端口映射表， 才能跨局域网连接  google 一下 NAT


Question: C语言关于局域网的问题

引用 楼主 chenxu1223537114 的回复:做了一个C/S程序，在局域网中，服务器处于监听状态，客户端怎么寻找服务器所在的IP地址？就好像CS里一个玩家创建了一个房间，其他的玩家可以刷新看到"服务器"创建的房间，这是怎么做到的？ 发个广播不就ok了

for(ip = startip; ip <= endip; ip++) {     for(port = startport; port <= endport; port++)     {         connect(ip, port)         recv(对方返回信息)         if(对方返回信息表明对方是CS房间)             显示房间信息         else //对方的返回信息无法识别，或者超时没有返回信息             对方不是CS房间，关闭该链接     } }


Question: 求好心人帮忙下一个codeproject的代码

不好意思，之后研究代码去了，然后各种事情，上个月后来我找了个github上面的，codeproject好像还是上不去，不过无所谓了，谢谢大家。

为什么我点了下载之后接没反应了。。。

对于这种刚发的帖子，我总是毫不犹豫的顶了。如果火了就是个前排，可以混个脸熟，说不定谁好心就给粉了…稳赚不赔；如果沉了就感觉是我弄沉的，很有成就感，还能捞经验。

哥帮你下了，http://download.csdn.net/detail/lovesmiles/7620941 哈哈，给点资源分吧。

再注册个啊，这个网站的很多资源都不错

下了，怎么给你？


Question: 请问printf的返回值格式?

引用 1 楼 user-6 的回复:printf返回输出的字符个数，比如 printf("abcde"); 返回5 自己写几行代码就可以验证  我看到有实例,可以返回值,所以查看VS的源码,发现不一样.所以上来问. 测试我肯定先测了...

引用 10 楼 zxh707wk 的回复:引用 5 楼 mymtom 的回复:坑爹的货多了，比如老谭的 void main()+1  有买老谭的书,不过比较经典的 <Pointers On C>, 等还没搞好...不懂有没有机会看老谭的...

参考 C:\Microsoft SDK\src\crt\printf.c C:\Program Files\Microsoft Platform SDK for Windows Server 2003 R2\src\crt\printf.c C:\Program Files\Microsoft Visual Studio\VC98\CRT\SRC\PRINTF.C C:\Program Files\Microsoft Visual Studio 8\VC\crt\src\printf.c C:\Program Files\Microsoft Visual Studio 9.0\VC\crt\src\printf.c C:\Program Files\Microsoft Visual Studio 10.0\VC\crt\src\printf.c

引用 3 楼 Automation_dmu 的回复:不知道你这个“速查”是个啥， C11中： 7.21.6.3 The printf function Synopsis 1 #include <stdio.h> int printf(const char * restrict format, ...); Description 2 The printf function is equivalent to fprintf with the argument stdout interposed before the arguments to printf. Returns 3 The printf function returns the number of characters transmitted, or a negative value if an output or encoding error occurred.  是"Knocker 2004.7.7 版本 0.5' 网上搜的,  我主要是想方便找函数用的, 而且如果是 chm格式的更好. 那懂是这样. 误导人.

引用 5 楼 mymtom 的回复:坑爹的货多了，比如老谭的 void main() void main() 貌似没有错, 应该涉及到C++了,在C++可以这样用. 因为在VS,貌似只能支持C++,没有纯脆针对C的...所以这个还好.

引用 2 楼 user-6 的回复:不过楼主也不用纠结，printf的返回值很少用到。 这个我不是担心, ,会误导人而已.

坑爹的货多了，比如老谭的 void main()

printf函数会返回一个整型数值，这个值是输出字符串的字符数，不过这个很少会用到

不过楼主也不用纠结，printf的返回值很少用到。


Question: VC 6.0 atof("123.567")

引用 楼主 li905663280 的回复:printf("%f\n",atof("123.567")); 结果为什么那么长，不知道出错在那， 因为小数并不精确。 即使手动赋值也是一样的。


Question: 使用C语言实现bcd码转十六进制数。

uchar bcd_hex(uchar bcd)			//bcdÂë×ª»»³É16½øÖÆÊý { 	uchar temp = bcd & 0x0f; 	bcd = bcd >> 4; 	bcd %= 0xf;  	return bcd *10 + temp; }

#include <stdio.h> #include <stdlib.h> #include <string.h> #include <locale.h> int main() {     int i,v;     char bs[33];     char b[33];     char hs[9];     char h[9];     char s[4];     char *e;  // 十进制整数转二进制串；     i=1024;     ltoa(i,b,2);     sprintf(bs,"%032s",b);     printf("i=%d,bs=%s\n",i,bs); // 十进制整数转十六进制串；     i=1024;     ltoa(i,h,16);     sprintf(hs,"%08s",h);     printf("i=%d,hs=%s\n",i,hs); // 十六进制字符串转成十进制数     strcpy(hs,"00000400");     sscanf(hs,"%x",&i);     printf("hs=%s,i=%d\n",hs,i); // 二进制字符串转化为十六进制字符串；     strcpy(bs,"00000000000000000000010000000000");     i=strtol(bs,&e,2);     ltoa(i,h,16);     sprintf(hs,"%08s",h);     printf("bs=%s,hs=%s\n",bs,hs); // 二进制字符串转化为十进制数；     strcpy(bs,"00000000000000000000010000000000");     i=strtol(bs,&e,2);     printf("bs=%s,i=%d\n",bs,i); // 十六进制字符串转成二进制串     strcpy(hs,"00000400");     sscanf(hs,"%x",&i);     ltoa(i,b,2);     sprintf(bs,"%032s",b);     printf("hs=%s,bs=%s\n",hs,bs); // ASC\GBK字符串转十六进制串     strcpy(s,"a汉");     i=0;     while (1) {         if (0==s[i]) break;         sprintf(hs+i*2,"%02X",(unsigned char)s[i]);         i++;     }     setlocale(LC_ALL,"chs");     printf("s=%s,hs=%s\n",s,hs); // 十六进制字符串转成汉字（GBK）及字符(ASC)     strcpy(hs,"61BABA");     i=0;     while (1) {         if (1!=sscanf(hs+i*2,"%2x",&v)) break;         s[i]=(char)v;         i++;     }     s[i]=0;     printf("hs=%s,s=%s\n",hs,s);      return 0;  } //i=1024,bs=00000000000000000000010000000000 //i=1024,hs=00000400 //hs=00000400,i=1024 //bs=00000000000000000000010000000000,hs=00000400 //bs=00000000000000000000010000000000,i=1024 //hs=00000400,bs=00000000000000000000010000000000 //s=a汉,hs=61BABA //hs=61BABA,s=a汉

仅供参考#include <stdio.h> #include <stdlib.h> #include <conio.h> unsigned int iv,i; unsigned char BCD[5];//定长10位BCD码 unsigned char sv[11]; void main() {     iv=123456789;//最大10位无符号正整数     //INT2BCD     sprintf(sv,"%010u",iv);     for (i=0;i<10;i+=2) {         BCD[i/2]=(sv[i]<<4)|(sv[i+1]&0x0F);     }     printf("BCD=%02x%02x%02x%02x%02x\n",BCD[0],BCD[1],BCD[2],BCD[3],BCD[4]);     //BCD2INT     for (i=0;i<10;i+=2) {         sv[i]='0'|(BCD[i/2]>>4);         sv[i+1]='0'|(BCD[i/2]&0x0F);     }     sscanf(sv,"%010u",&iv);     printf("iv=%010u\n",iv);     getch(); }

char *strBCD = "000100100111"; 	int num = 0; 	for (int i = 4; i <= strlen(strBCD); i = i + 4)//长度不足4的部分将被舍去 	{ 		num = num * 10 + 			(strBCD[i - 4] - '0') * 8 +  			(strBCD[i - 3] - '0') * 4 +  			(strBCD[i - 2] - '0') * 2 +  			(strBCD[i - 1] - '0'); 	}

引用 1 楼 zjq9931 的回复:问题比较简单。 0101是内存中的二进制码，并不是字符型的“0101”吧？ 第一步：把BCD码输出成10进制字符串，0101，输出成“5”，printf就可以做到。 然后用sscanf函数，可以将字符串型的“5”,转换成16进制的。 sprintf


Question: create window

多谢  另外我这个程序里面不能识别DestoryWindow函数，不知道他的头文件是什么，不是Window.h吗？

简单说，vs2010怎么让生成窗口在编译时自动显示,运行调试时自动打开观察变量的窗口，运行结束后这些窗口全部自动隐藏

再问个问题，vs2010怎么设置调试习惯，我看别人调试的时候自动跳出了好几个窗口，有一个是看各变量的值，有一个是看内存，那窗口是一个二维的内存序列，没访问的显示2个问号，访问过的内存显示当前的值，很帅有木有？还有其他窗口我忘了，不知道怎么设置这个东东？

你说得对 第一次写窗口程序，得罪之处还望见谅

case WM_PAINT: 后面少了一个break,直接跳到WM_CLOSE了。 大哥，能不能自己调试一下？什么问题都不调试就上来问了？

#include <Windows.h> #include <stdio.h>   LRESULT CALLBACK WinSunProc( 	HWND hwnd,      // handle to window 	UINT uMsg,      // message identifier 	WPARAM wParam,  // first message parameter 	LPARAM lParam   // second message parameter 	);  int WINAPI WinMain( 	HINSTANCE hInstance,  // handle to current instance 	HINSTANCE hPrevInstance,  // handle to previous instance 	LPSTR lpCmdLine,      // pointer to command line 	int nCmdShow          // show state of window 	) {	 	//创建一个窗口类 	WNDCLASS wndcls; 	 	 	//额外参数 	wndcls.cbClsExtra=0; 	wndcls.cbWndExtra=0; 	//背景色 	wndcls.hbrBackground=(HBRUSH)GetStockObject(BLACK_BRUSH); 	//光标 	wndcls.hCursor=LoadCursor(NULL,IDC_ARROW); 	//图标 	wndcls.hIcon=LoadIcon(NULL,IDI_SHIELD); 	//应用程序实例号 	wndcls.hInstance=hInstance; 	//窗口过程函数 	wndcls.lpfnWndProc=WinSunProc; 	//类名 	//#include <tchar.h>	更多信息： http://bbs.csdn.net/topics/390631479?page=1 	wndcls.lpszClassName="weixin"; 	//菜单名 	wndcls.lpszMenuName=NULL; 	//风格 	wndcls.style=CS_HREDRAW|CS_VREDRAW;//水平重画 或上 垂直重画  	//注册 	RegisterClass(&wndcls);  	//创建窗口 	/*参考信息： 	CreateWindow 	该函数创建一个重叠式窗口、弹出式窗口或子窗口。它指定窗口类 	，窗口标题，窗口风格，以及窗口的初始位置及大小（可选的）。 	函数也指该窗口的父窗口或所属窗口（如果存在的话），及窗口的 	菜单。若要使用除CreateWindow函数支持的风格外的扩展风格，则 	使用CreateWindowEx函数代替CreateWindow函数。*/ 	HWND hwnd; 	hwnd=CreateWindow("weixin","北京维新科学技术中心",WS_OVERLAPPEDWINDOW,500, 		500,1000,600,NULL,NULL,hInstance,NULL);  	//显示窗口 	ShowWindow(hwnd,SW_NORMAL);  	//更新窗口 	UpdateWindow(hwnd);  	//消息循环 	MSG msg; 	while(GetMessage(&msg,NULL,0,0)) 	{ 		TranslateMessage(&msg); 		DispatchMessage(&msg); 	}  	return 0; }  LRESULT CALLBACK WinSunProc( 	HWND hwnd,      // handle to window 	UINT uMsg,      // message identifier 	WPARAM wParam,  // first message parameter 	LPARAM lParam   // second message parameter 	) { 	switch(uMsg) 	{ 	case WM_CHAR: 		char szChar[20]; 		sprintf_s(szChar,20,"Char is %d",wParam); 		MessageBox(hwnd,szChar,"weixin",0); 		break; 	case WM_LBUTTONDOWN: 		MessageBox(hwnd,"mouse is clicked!","weixin",0); 		HDC hdc; 		hdc=GetDC(hwnd); 		TextOut(hdc,50,120,"Mouse clicked！",strlen("Mouse clicked！")); 		ReleaseDC(hwnd,hdc); 		break; 	case WM_PAINT: 		HDC hdc1; 		PAINTSTRUCT ps; 		hdc1=BeginPaint(hwnd,&ps); 		TextOut(hdc1,50,50,"维新培训",strlen("维新培训")); 		EndPaint(hwnd,&ps); 	case WM_CLOSE: 		if(IDYES==MessageBox(hwnd,"真的要退出吗？","weixin",MB_YESNO)) 		{ 			DestroyWindow(hwnd); 		} 		break; 	case WM_DESTROY: 		PostQuitMessage(0); 	default: 		return DefWindowProc(hwnd,uMsg,wParam,lParam); 	} 	return 0; } 这是改好能够运行的代码，运行时出现了一个问题，在重绘窗口的时候提示退出，这是什么原因啊？

额知道了，我是在控制台里面写的这个窗口程序

额我打错了，改好之后还有问题： MSVCRT.lib(crtexe.obj) : error LNK2001: 无法解析的外部符号 _main 1>D:\Program Files\Microsoft Visual Studio\MyProjects\WinMain\Release\WinMain.exe : fatal error LNK1120: 1 个无法解析的外部命令  下面是代码，我实在找不到问题在哪里： #include <Windows.h> #include <stdio.h>   LRESULT CALLBACK WinSunProc( 	HWND hwnd,      // handle to window 	UINT uMsg,      // message identifier 	WPARAM wParam,  // first message parameter 	LPARAM lParam   // second message parameter 	);  int WINAPI WinMain( 	HINSTANCE hInstance,  // handle to current instance 	HINSTANCE hPrevInstance,  // handle to previous instance 	LPSTR lpCmdLine,      // pointer to command line 	int nCmdShow          // show state of window 	) {	 	//创建一个窗口类 	WNDCLASS wndcls; 	 	 	//额外参数 	wndcls.cbClsExtra=0; 	wndcls.cbWndExtra=0; 	//背景色 	wndcls.hbrBackground=(HBRUSH)GetStockObject(BLACK_BRUSH); 	//光标 	wndcls.hCursor=LoadCursor(NULL,IDC_ARROW); 	//图标 	wndcls.hIcon=LoadIcon(NULL,IDI_SHIELD); 	//应用程序实例号 	wndcls.hInstance=hInstance; 	//窗口过程函数 	wndcls.lpfnWndProc=WinSunProc; 	//类名 	//#include <tchar.h>	更多信息： http://bbs.csdn.net/topics/390631479?page=1 	wndcls.lpszClassName="weixin"; 	//菜单名 	wndcls.lpszMenuName=NULL; 	//风格 	wndcls.style=CS_HREDRAW|CS_VREDRAW;//水平重画 或上 垂直重画  	//注册 	RegisterClass(&wndcls);  	//创建窗口 	/*参考信息： 	CreateWindow 	该函数创建一个重叠式窗口、弹出式窗口或子窗口。它指定窗口类 	，窗口标题，窗口风格，以及窗口的初始位置及大小（可选的）。 	函数也指该窗口的父窗口或所属窗口（如果存在的话），及窗口的 	菜单。若要使用除CreateWindow函数支持的风格外的扩展风格，则 	使用CreateWindowEx函数代替CreateWindow函数。*/ 	HWND hwnd; 	hwnd=CreateWindow("weixin","北京维新科学技术中心",WS_OVERLAPPEDWINDOW,500, 		500,1000,600,NULL,NULL,hInstance,NULL);  	//显示窗口 	ShowWindow(hwnd,SW_NORMAL);  	//更新窗口 	UpdateWindow(hwnd);  	//消息循环 	MSG msg; 	while(GetMessage(&msg,NULL,0,0)) 	{ 		TranslateMessage(&msg); 		DispatchMessage(&msg); 	}  	return 0; }  LRESULT CALLBACK WinSunProc( 	HWND hwnd,      // handle to window 	UINT uMsg,      // message identifier 	WPARAM wParam,  // first message parameter 	LPARAM lParam   // second message parameter 	) { 	switch(uMsg) 	{ 	case WM_CHAR: 		char szChar[20]; 		sprintf_s(szChar,20,"Char is %d",wParam); 		MessageBox(hwnd,szChar,"weixin",0); 		break; 	case WM_LBUTTONDOWN: 		MessageBox(hwnd,"mouse is clicked!","weixin",0); 		HDC hdc; 		hdc=GetDC(hwnd); 		TextOut(hdc,50,120,"Mouse clicked！",strlen("Mouse clicked！")); 		ReleaseDC(hwnd,hdc); 		break; 	case WM_PAINT: 		PAINTSTRUCT ps; 		hdc=BeginPaint(hwnd,&ps);//这里用的是上一个case中的hdc 		TextOut(hdc,50,50,"维新培训",strlen("维新培训")); 		EndPaint(hwnd,&ps); 	case WM_CLOSE: 		if(IDYES==MessageBox(hwnd,"真的要退出吗？","weixin",MB_YESNO)) 		{ 			DestroyWindow(hwnd); 		} 		break; 	case WM_DESTROY: 		PostQuitMessage(0); 	default: 		return DefWindowProc(hwnd,uMsg,wParam,lParam); 	} 	return 0; }

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

引用 4 楼 wenbo228228 的回复:能说说为什么吗 unicode和多字节字符的区别啊。 unicode编码大致的说是每个字符占两个字节，英文字符也是，中文字符也是。每个字符相当于unsigned shor类型。 而多字节字符，英文只占一个字节，正文占两个字节，还是char类型。 所以类型不匹配

能说说为什么吗

引用 2 楼 wenbo228228 的回复:没用   我这个程序每个需要用字符串的地方都有这个错误提示：const char * 类型 的实参与 LPCWSTR 类型的形参不兼容，是不是我创建项目的时候设置错了，我创建项目的时候什么都没设置，是个空项目，所有的都是默认的呢 工程里面设置了使用的字符集是unicode造成的，按道理二楼的办法可以解决。不过每个字符串都要改。 也可以在工程里面设置成不使用unicode，VS2010的设置方法是：project->property...->configuration..->General->Character Set Use Multi-Byte Character Set 其他版本的VS也差不多。

"..." 修改成 _T("...")


Question: 求解

自古二楼出正解。

这样的话是不是只能自己查错了？

char a[6]="bacao"; char b[] ="bbd"; strncat(a,b,3)     这里 a,b 是以地址传给它的，它不会检查你a具体有多少个元素的，所以不会报错,在strncat函数里面接连时应该是以地址++方式连接，也不检测数组大小，编译器一般是连续分配内存  所以b紧接在a后面,   内存内容为   bacao'\0'bbd'\0'  strncat(a,b,3); 会自动把a 字符串的 结束标志'\0'去接，   接上bbd  所以内存内容为  bacaobbd'\0'  printf("%s",a);   是以是a[0]地址开始一直到检测到'\0'才作为结束标志的，所以输出bacaobbd

c编译器不会对数组越界进行检查

呵呵，如果你再printf("%s",b); 就会发现b也变了（如果是release版的话），变成空字符串了。 因为a和b都是栈上的变量，a占用8字节栈空间，后面紧接着是b占用的4字节空间，所有当你strncat后b[0]就成了'\0‘了

其实电脑开机后物理内存的每个字节都是可读写的，区别仅在于操作系统内存管理模块在你读写时是否能发现并是否采取相应动作而已。操作系统管理内存的粒度不是字节而是页，一页通常为4KB。

楼上已经解答。

数组越界并不是一定会报出错误，所以这种错误是隐藏最深，最让人头疼和蛋疼的


Question: 文件指针的设置问题

fs = fopen("E:\\data task\\rfv3\\write.txt","w"); 用wb试一下，默认是文本格式写入，会对换行符做转换 有些会把"\r\n"转换一下

fs = fopen("E:\\data task\\rfv3\\write.txt","w"); 这一句 换成“wb”这样试试。 fs = fopen("E:\\data task\\rfv3\\write.txt","wb");


Question: strcpy和strncpy

楼主分享，我就接分。

strncpy, wcsncpy, _mbsncpy Copy characters of one string to another.  char *strncpy( char *strDest, const char *strSource, size_t count );  wchar_t *wcsncpy( wchar_t *strDest, const wchar_t *strSource, size_t count );  unsigned char *_mbsncpy( unsigned char *strDest, const unsigned char *strSource, size_t count );  Routine Required Header Compatibility  strncpy <string.h> ANSI, Win 95, Win NT  wcsncpy <string.h> or <wchar.h> ANSI, Win 95, Win NT  _mbsncpy <mbstring.h> Win 95, Win NT    For additional compatibility information, see Compatibility in the Introduction.  Libraries  LIBC.LIB Single thread static library, retail version  LIBCMT.LIB Multithread static library, retail version  MSVCRT.LIB Import library for MSVCRT.DLL, retail version    Return Value  Each of these functions returns strDest. No return value is reserved to indicate an error.  Parameters  strDest  Destination string  strSource  Source string  count  Number of characters to be copied  Remarks  The strncpy function copies the initial count characters of strSource to strDest and returns strDest. If count is less than or equal to the length of strSource, a null character is not appended automatically to the copied string. If count is greater than the length of strSource, the destination string is padded with null characters up to length count. The behavior of strncpy is undefined if the source and destination strings overlap.  wcsncpy and _mbsncpy are wide-character and multibyte-character versions of strncpy. The arguments and return value of wcsncpy and _mbsncpy vary accordingly. These three functions behave identically otherwise.  Generic-Text Routine Mappings  TCHAR.H Routine  _UNICODE & _MBCS Not Defined _MBCS Defined _UNICODE Defined  _tcsncpy strncpy _mbsnbcpy  wcsncpy     Example  /* STRNCPY.C */  #include <string.h> #include <stdio.h>  void main( void ) {    char string[100] = "Cats are nice usually";    printf ( "Before: %s\n", string );    strncpy( string, "Dogs", 4 );    strncpy( string + 9, "mean", 4 );    printf ( "After:  %s\n", string ); }   Output  Before: Cats are nice usually After:  Dogs are mean usually   String Manipulation Routines  See Also   _mbsnbcpy, strcat, strcmp, strcpy, strncat, strncmp, _strnicmp, strrchr, _strset, strspn


Question: sizeof的问题

引用 5 楼 cyd54454 的回复:[quote=引用 2 楼 zjq9931 的回复:] [quote=引用 楼主 cyd54454 的回复:] 用同一版本的编译器gcc,对下面的结构体求sizeof，32位机下得到12,64位机下得到16,这是为什么啊！难道gcc还分平台，来决定是否字节对齐么？ struct A {          int a;          double b; } 32位机器（编译器），默认是4字节对齐。就是4的倍数。 64位机器（编译器），默认是8字节对齐。就是8的倍数。  用这个方法改变对齐设置就可以了。 · 使用伪指令#pragma pack (n)，C编译器将按照n个字节对齐。 · 使用伪指令#pragma pack ()，取消自定义字节对齐方式。[/quote] 我看一些题目考一个sizeof（结构体）大小的，都是按结构体内最大的内置类型大小，来进行对齐的。哎，都不知道这些问题该怎么回答了....[/quote] 我验证了一下确实是这样。我同样也学到了。

引用 6 楼 cyd54454 的回复:[quote=引用 4 楼 zhao4zhong1 的回复:] #include <stdio.h> #define field_offset(s,f) (int)(&(((struct s *)(0))->f)) struct AD  { int a; char b[13]; double c;}; #pragma pack(push) #pragma pack(1) struct A1  { int a; char b[13]; double c;}; #pragma pack(2) struct A2  { int a; char b[13]; double c;}; #pragma pack(4) struct A4  { int a; char b[13]; double c;}; #pragma pack(8) struct A8  { int a; char b[13]; double c;}; #pragma pack(16) struct A16 { int a; char b[13]; double c;}; #pragma pack(pop) int main() {     printf("AD.a %d\n",field_offset(AD,a));     printf("AD.b %d\n",field_offset(AD,b));     printf("AD.c %d\n",field_offset(AD,c));     printf("\n");     printf("A1.a %d\n",field_offset(A1,a));     printf("A1.b %d\n",field_offset(A1,b));     printf("A1.c %d\n",field_offset(A1,c));     printf("\n");     printf("A2.a %d\n",field_offset(A2,a));     printf("A2.b %d\n",field_offset(A2,b));     printf("A2.c %d\n",field_offset(A2,c));     printf("\n");     printf("A4.a %d\n",field_offset(A4,a));     printf("A4.b %d\n",field_offset(A4,b));     printf("A4.c %d\n",field_offset(A4,c));     printf("\n");     printf("A8.a %d\n",field_offset(A8,a));     printf("A8.b %d\n",field_offset(A8,b));     printf("A8.c %d\n",field_offset(A8,c));     printf("\n");     printf("A16.a %d\n",field_offset(A16,a));     printf("A16.b %d\n",field_offset(A16,b));     printf("A16.c %d\n",field_offset(A16,c));     printf("\n");     return 0; } //AD.a 0 //AD.b 4 //AD.c 24 // //A1.a 0 //A1.b 4 //A1.c 17 // //A2.a 0 //A2.b 4 //A2.c 18 // //A4.a 0 //A4.b 4 //A4.c 20 // //A8.a 0 //A8.b 4 //A8.c 24 // //A16.a 0 //A16.b 4 //A16.c 24 // //  赵老师果然给力，不过为什么最后按16字节对齐，没有变化呢[/quote] 百度了一下知道，原来n大于等于所需要的字节时，就按默认方式字节对齐了

引用 4 楼 zhao4zhong1 的回复:#include <stdio.h> #define field_offset(s,f) (int)(&(((struct s *)(0))->f)) struct AD  { int a; char b[13]; double c;}; #pragma pack(push) #pragma pack(1) struct A1  { int a; char b[13]; double c;}; #pragma pack(2) struct A2  { int a; char b[13]; double c;}; #pragma pack(4) struct A4  { int a; char b[13]; double c;}; #pragma pack(8) struct A8  { int a; char b[13]; double c;}; #pragma pack(16) struct A16 { int a; char b[13]; double c;}; #pragma pack(pop) int main() {     printf("AD.a %d\n",field_offset(AD,a));     printf("AD.b %d\n",field_offset(AD,b));     printf("AD.c %d\n",field_offset(AD,c));     printf("\n");     printf("A1.a %d\n",field_offset(A1,a));     printf("A1.b %d\n",field_offset(A1,b));     printf("A1.c %d\n",field_offset(A1,c));     printf("\n");     printf("A2.a %d\n",field_offset(A2,a));     printf("A2.b %d\n",field_offset(A2,b));     printf("A2.c %d\n",field_offset(A2,c));     printf("\n");     printf("A4.a %d\n",field_offset(A4,a));     printf("A4.b %d\n",field_offset(A4,b));     printf("A4.c %d\n",field_offset(A4,c));     printf("\n");     printf("A8.a %d\n",field_offset(A8,a));     printf("A8.b %d\n",field_offset(A8,b));     printf("A8.c %d\n",field_offset(A8,c));     printf("\n");     printf("A16.a %d\n",field_offset(A16,a));     printf("A16.b %d\n",field_offset(A16,b));     printf("A16.c %d\n",field_offset(A16,c));     printf("\n");     return 0; } //AD.a 0 //AD.b 4 //AD.c 24 // //A1.a 0 //A1.b 4 //A1.c 17 // //A2.a 0 //A2.b 4 //A2.c 18 // //A4.a 0 //A4.b 4 //A4.c 20 // //A8.a 0 //A8.b 4 //A8.c 24 // //A16.a 0 //A16.b 4 //A16.c 24 // //  赵老师果然给力，不过为什么最后按16字节对齐，没有变化呢

引用 2 楼 zjq9931 的回复:[quote=引用 楼主 cyd54454 的回复:] 用同一版本的编译器gcc,对下面的结构体求sizeof，32位机下得到12,64位机下得到16,这是为什么啊！难道gcc还分平台，来决定是否字节对齐么？ struct A {          int a;          double b; } 32位机器（编译器），默认是4字节对齐。就是4的倍数。 64位机器（编译器），默认是8字节对齐。就是8的倍数。  用这个方法改变对齐设置就可以了。 · 使用伪指令#pragma pack (n)，C编译器将按照n个字节对齐。 · 使用伪指令#pragma pack ()，取消自定义字节对齐方式。[/quote] 我看一些题目考一个sizeof（结构体）大小的，都是按结构体内最大的内置类型大小，来进行对齐的。哎，都不知道这些问题该怎么回答了....

没有为什么  本来就没要求结构体一定的多大  对结构体大小的要求只是 足以容纳全部成员   编译器想安排多大都没问题 没限制

引用 楼主 cyd54454 的回复:用同一版本的编译器gcc,对下面的结构体求sizeof，32位机下得到12,64位机下得到16,这是为什么啊！难道gcc还分平台，来决定是否字节对齐么？ struct A {          int a;          double b; } 32位机器（编译器），默认是4字节对齐。就是4的倍数。 64位机器（编译器），默认是8字节对齐。就是8的倍数。  用这个方法改变对齐设置就可以了。 · 使用伪指令#pragma pack (n)，C编译器将按照n个字节对齐。 · 使用伪指令#pragma pack ()，取消自定义字节对齐方式。

是的。 · 使用伪指令#pragma pack (n)，C编译器将按照n个字节对齐。 · 使用伪指令#pragma pack ()，取消自定义字节对齐方式。


Question: 静态的局部变量：当函数执行完毕的时候，静态的局部变量的值在下次执行时，被保留了下来，为什么？

计算机组成原理→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++就是这样规定和设计的。

因为存储在静态存储区，所以只能初始化一次，而以后再函数调用的过程中其值都维持不变。

静态局部变量是存储在内存中的静态存储区的 随程序执行开始分配内存，直到程序结束进行释放。  对于静态局部变量，在程序开始是分配内存并且初始化。在以后调用函数的时候不再进行重新分配内存。  static int y=1;  对于这条语句，程序只执行一次，在以后使用此函数的过程中不再重新分配变量，相当于这条语句不执行了。


Question: 问个 unsigned int菜鸟问题.

c编译器没有检测这个的功能。。。

引用 14 楼 zxh707wk 的回复:请百度 原码 反码 补码  弄懂负数在计算机内的存储形式 come on. 我知道 负数的最高位为1.知道 反码补码. 现在我的奇怪的是 编译器的问题, 像 C#和java对应的编译器确实是就防止的呀.

引用 13 楼 mengwuxiy 的回复:ＬＺ可以看一下二进制编码的原理，其实计算机存的时候只是负数的最高位为１罢了 come on. 我知道 负数的最高位为1. 现在我的奇怪的是 编译器的问题, 像 C#和java对应的编译器确实是就防止的呀.

引用 14 楼 zxh707wk 的回复:请百度 原码 反码 补码  弄懂负数在计算机内的存储形式 计算机组成原理

其实C++ 存储数据的时候是没有正负的概念。  0xff 可以理解为 255，也可以理解为 -1  看变量是 char 还是 BYTE.

引用 7 楼 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对应的汇编并单步执行观察相应内存和寄存器变化。）  电脑内存或文件内容只是一个一维二进制字节数组及其对应的二进制地址； 人脑才将电脑内存或文件内容中的这个一维二进制字节数组及其对应的二进制地址的某些部分看成是整数、有符号数/无符号数、浮点数、复数、英文字母、阿拉伯数字、中文/韩文/法文……字符/字符串、汇编指令、函数、函数参数、堆、栈、数组、指针、数组指针、指针数组、数组的数组、指针的指针、二维数组、字符点阵、字符笔画的坐标、黑白二值图片、灰度图片、彩色图片、录音、视频、指纹信息、身份证信息……  不要迷信书、考题、老师、回帖； 要迷信CPU、编译器、调试器、运行结果。 并请结合“盲人摸太阳”和“驾船出海时一定只带一个指南针。”加以理解。 任何理论、权威、传说、真理、标准、解释、想象、知识……都比不上摆在眼前的事实！  有人说一套做一套，你相信他说的还是相信他做的？ 其实严格来说这个世界上古往今来所有人都是说一套做一套，不是吗？  不要写连自己也预测不了结果的代码！

引用 17 楼 king769147 的回复:[quote=引用 14 楼 zxh707wk 的回复:] 请百度 原码 反码 补码  弄懂负数在计算机内的存储形式 come on. 我知道 负数的最高位为1.知道 反码补码. 现在我的奇怪的是 编译器的问题, 像 C#和java对应的编译器确实是就防止的呀. [/quote]  那是编译器友好呗，编译器报什么样的warning和错误还不是人写的。

编译器赋值时只管数值的二进制，哪管正负数

请百度 原码 反码 补码  弄懂负数在计算机内的存储形式

ＬＺ可以看一下二进制编码的原理，其实计算机存的时候只是负数的最高位为１罢了

引用 9 楼 king769147 的回复:[quote=引用 2 楼 T5500 的回复:] 对无符号类型赋值一个超出它表示范围的值时，结果是初始值对无符号类型表示数值总数取模后的余数。 比如，int类型为32位时，unsigned int所能表示的数值范围是0 - 4294967295，共4294967296个可能的数值：  #include <iostream>  int main() { 	unsigned int ui; 	ui = -1; 	std::cout << ui << std::endl; //输出4294967295，即：4294967296 % 1 	 	ui = 4294967296; 	std::cout << ui << std::endl; //输出0，即：4294967296 % 4294967296 	return 0; }   我有这么个印象,至少C#和java这些对应的编译器不能是这样的...所以我觉得是和编译器有关,不是和机器有关的.[/quote]  别的语言就不清楚了，反正C++就是这样。我用g++编译的，正数超范围会报一个warning，赋负数时连warning都不会提示

引用 2 楼 T5500 的回复:  	std::cout << ui << std::endl; //输出4294967295，即：4294967296 % 1   4294967296 % 1 结果是 0

引用 4 楼 k91191 的回复:人类发明的傻逼电脑只知道0和1，正负数是相对于十进制而言的。“unsigned int 能赋值为 负数”这句的意思是一个             unsigned int类型的变量可以存储一个负数。为啥无字符数可以存一个负数，怎么存储的。请自行搜索有符号数和             无符号之间的转换。我有这么个印象,至少C#和java这些对应的编译器不能是这样的...所以我觉得是和编译器有关,不是和机器有关的.

引用 2 楼 T5500 的回复:对无符号类型赋值一个超出它表示范围的值时，结果是初始值对无符号类型表示数值总数取模后的余数。 比如，int类型为32位时，unsigned int所能表示的数值范围是0 - 4294967295，共4294967296个可能的数值：  #include <iostream>  int main() { 	unsigned int ui; 	ui = -1; 	std::cout << ui << std::endl; //输出4294967295，即：4294967296 % 1 	 	ui = 4294967296; 	std::cout << ui << std::endl; //输出0，即：4294967296 % 4294967296 	return 0; }   我有这么个印象,至少C#和java这些对应的编译器不能是这样的...所以我觉得是和编译器有关,不是和机器有关的.

引用 1 楼 Intel0011 的回复:编译器赋值时只管数值的二进制，哪管正负数 我有这么个印象,至少C#和java这些对应的编译器不能是这样的...所以我觉得是和编译器有关,不是和机器有关的.

如果无法理解的话，用电脑上的计算器，调整为“程序员”模式，就知道-1和255的含义了

可以的，只是会变成别的数了，你想一下有符号数最高位其实是符号位，0正1负，但是unsigned int的值编译器都会认为是正值，所以最好为的符号位也被认为是数值位了，所以，如果是负数的话将会得到一个较大的正数，因为最高位为1

unsigned int 能赋值为 负数 计算机的负数表示，只不过是设最高位为1罢了，


Question: C要运行很长时间，怎样能占用内存和CPU小些

可以把进程的优先级调低一点，就少占 CPU 了

好像多线程不行

应设计为每隔比如1小时保存当前状态到磁盘文件中，万一因为各种原因中断运行了，可以通过读取最后保存到磁盘的状态信息让工作继续从那个点继续运行。

引用 3 楼 yangyunzhao 的回复:[quote=引用 1 楼 Intel0011 的回复:] 1. 分配的内存使用完后立即释放 2. 适当使用Sleep函数以减少本程序对CPU的占用  第1种方法不好，应该是启动时申请内存，运行过程中不动态分配内存。占用内存不可怕，可怕的是你不确定你会占用多大内存。 具体还是要贴代码[/quote]  1.用事先申请的内存，在其中做逻辑操作。 2.改进算法 3.用release版本

引用 1 楼 Intel0011 的回复:1. 分配的内存使用完后立即释放 2. 适当使用Sleep函数以减少本程序对CPU的占用  第1种方法不好，应该是启动时申请内存，运行过程中不动态分配内存。占用内存不可怕，可怕的是你不确定你会占用多大内存。 具体还是要贴代码

少占内存的话就是注意动态申请的要及时释放。 少占cpu的话可以放进单独线程执行，以免独占cpu

可以用多线程

把所有的变量在执行循环前都定义好，包括栈和堆上。

1、不要死循环 2、每循环一次，不急的话 可以适当的sleep下 3、用内存管理，合理的分配/释放内存，可以保留一些内存，避免每次都是分配->释放 4、etc.


Question: c添加sql类，提示错误。

怎么感觉像是c#


Question: 一个有点难度的问题：文件缓冲区和标准输入输出的缓冲区的疑问

引用 3 楼 user-3 的回复:[quote=引用 2 楼 BiologyPianoProgram 的回复:] [quote=引用 1 楼 user-3 的回复:] 有什么问题么？ 那是肯定的~~~因为标准输入输出stdin  stdout是文件指针  fopen也会返回文件指针：这里面通常会包含指向缓存的指针。。。。  反正只要是标准i/o文件指针，就会有缓存~~~ 如果真是这样，倒也没啥问题。 我就是感觉书上在讲述流、缓冲区、文件时，说的高度抽象，使人望而却步，难以理解，所以想用一些具体的示例来把问题简单化。  发此贴的另一个目的就是指望有高人出现，能够针对流、缓冲区、文件操作给出一些通俗易懂的定义、概念和内部机制的解释（虽然目前我自己已经基本全都研究通了，但是无法用通俗易懂的语言组织起来，只能从侧面通过示例来解释一些概念）[/quote] 额~~那你还是看下《unix高级环境编程》吧，具体第几章我也忘了~~~[/quote]  这个暂时没空研究，之前看过机制的，还没到代码这个级别。 关于缓冲区的机制我自己是能够很透彻的理解了 我只是想总结下，写个博文，发出来，让以后不理解的同志都能看到，然后都能够迅速理解。本来就是一挺简单的事，偏偏被书上 说的很深奥很抽象

引用 4 楼 zhao4zhong1 的回复:为什么不按Alt+8，F11键单步进fopen函数参考其源代码呢？  老赵，我这不c搁置很久了，最近感觉越来越需要，所以才狠下心抽时间研究的 linux之前一直看的是机制方面的介绍，具体源码没看

为什么不按Alt+8，F11键单步进fopen函数参考其源代码呢？

引用 2 楼 BiologyPianoProgram 的回复:[quote=引用 1 楼 user-3 的回复:] 有什么问题么？ 那是肯定的~~~因为标准输入输出stdin  stdout是文件指针  fopen也会返回文件指针：这里面通常会包含指向缓存的指针。。。。  反正只要是标准i/o文件指针，就会有缓存~~~ 如果真是这样，倒也没啥问题。 我就是感觉书上在讲述流、缓冲区、文件时，说的高度抽象，使人望而却步，难以理解，所以想用一些具体的示例来把问题简单化。  发此贴的另一个目的就是指望有高人出现，能够针对流、缓冲区、文件操作给出一些通俗易懂的定义、概念和内部机制的解释（虽然目前我自己已经基本全都研究通了，但是无法用通俗易懂的语言组织起来，只能从侧面通过示例来解释一些概念）[/quote] 额~~那你还是看下《unix高级环境编程》吧，具体第几章我也忘了~~~

引用 1 楼 user-3 的回复:有什么问题么？ 那是肯定的~~~因为标准输入输出stdin  stdout是文件指针  fopen也会返回文件指针：这里面通常会包含指向缓存的指针。。。。  反正只要是标准i/o文件指针，就会有缓存~~~ 如果真是这样，倒也没啥问题。 我就是感觉书上在讲述流、缓冲区、文件时，说的高度抽象，使人望而却步，难以理解，所以想用一些具体的示例来把问题简单化。  发此贴的另一个目的就是指望有高人出现，能够针对流、缓冲区、文件操作给出一些通俗易懂的定义、概念和内部机制的解释（虽然目前我自己已经基本全都研究通了，但是无法用通俗易懂的语言组织起来，只能从侧面通过示例来解释一些概念）

引用 10 楼 BiologyPianoProgram 的回复:[quote=引用 8 楼 zhao4zhong1 的回复:] 参考C:\Program Files\Microsoft Visual Studio\VC98\CRT\SRC\OPEN.C  原理我都研究透啦，我主要是要让大牛给出一些通俗易懂的定义、概念或解释。[/quote] 源代码＞解释＞定义＞原理＞概念

引用 8 楼 zhao4zhong1 的回复:参考C:\Program Files\Microsoft Visual Studio\VC98\CRT\SRC\OPEN.C  原理我都研究透啦，我主要是要让大牛给出一些通俗易懂的定义、概念或解释。

引用 7 楼 ypzhong 的回复:再理解深入一点就是操纵系统接口的事了，打开文件fopen内部会调用具体的操纵系统API，windows应该是CreateFile，linux是open函数。windows返回的是句柄，linux返回的是一个整数值，就是区别其它文件的标识。进程进入mian函数之前已经打开了标准输入，输出，错误输出的文件。 原理我都研究透啦，我主要是要让大牛给出一些通俗易懂的定义、概念或解释。


Question: c指针

前者相当于 一重指针。后者相当于二重指针。因此接引要注意。我写过一段关于这里的文字。。。还没上传。明天吧。。

引用 楼主 u014251961 的回复: 1.不明白为什么array.和&array是一样的.难道是因为array本身就是地址.所以一样吗? 2.为什么ptr++的值跟ptr的值一样.但是*(ptr)跟*(Ptr++)却不一样. 3.还有后面的(*ptr)+1.跟*ptr++之间的也不明白..  #include "stdio.h" int main() {   	int array[10]={214,4654,6,76,5}; 	int (*ptr)[10]; 	ptr = &array;  	int* ptr1 = (int*)(ptr+1);  	printf("ptr:0x%p,ptr1:0x%p,offset:%d\n",ptr,ptr1,(int)ptr1-(int)ptr); 	//ptr:0x0012FF20,ptr1:0x0012FF48,offset:40     return 0; }  //ptr+1  以后，指向的地址相对于ptr来说，偏移了40个字节，说明ptr是指向了一个10个元素的整形数组 //关键的问题搞明白后，接下来的那些分析应该没问题了

引用 楼主 u014251961 的回复: 1.不明白为什么array.和&array是一样的.难道是因为array本身就是地址.所以一样吗? 2.为什么ptr++的值跟ptr的值一样.但是*(ptr)跟*(Ptr++)却不一样. 3.还有后面的(*ptr)+1.跟*ptr++之间的也不明白..  楼主的学习精神我很欣赏，但是尽量不要把代码截图，把代码copy上来，方便大伙帮你解决问题 看内存地址这样写比较舒服     prinf("0x%p\n",ptr); 测试问题的时候尽量一句一句测试,把别的printf先注释了 这样看问题会更加清楚 否则就会自己把自己给搞糊涂了  编程序尽量把复杂的问题简单化

array.和&array都是数组的首地址。（*ptr）[10]=ptr[][10]所以*(ptr)跟*(Ptr++)的值是两个不同的地址。     希望对你有用。

引用 12 楼 zhao4zhong1 的回复:理解和讨论之前请先学会如何观察！ 那个++的问题确实是我没有仔细观察.可是有的不理解呀.

引用 9 楼 cao_julians 的回复:大学的校园也有地址， XXXX路XXXX号，其实这是一个楼的地址、也是一个校园的地址。 array其实是&array[0]，即首元素array[0]的地址；而&array是整个数组的地址。地址值是一样的，但地址指向的对象是不一样的，一个是数组元素，另一个是整个数组。 继续： array+1是&array[1]，是下一元素的地址 而&array+1是&array[11]，是下一数组（不存在）的地址 恩.谢谢你.还有一点.ptr.跟*ptr为什么会一样?我的理解是ptr应该是这个指针本身的地址.*ptr是ptr指针占内存的一个值也就是&array..应该不一样才对丫..

引用 14 楼 u013171165 的回复:引用 12 楼 zhao4zhong1 的回复:理解和讨论之前请先学会如何观察！请教下，为啥子您这么有时间，天天待论坛，感觉不是一个人，做事却又是一种风格。。。不懂。很感谢您这样真正负责的前辈，不遗余力的指导小白正确的道路啊！ 时间就象乳沟，挤挤总还是有的。(.)(.)

看错了 不用了   ptr是指针，*ptr是指针的值 ,也是所占内存地方的值 好糊涂

谁用gcc输出下，帮帮忙 ，也看看哈

理解和讨论之前请先学会如何观察！

1:    int array[10]={214,4654,6,76,5}; 2:    int (*ptr)[10]; 3:    void *pv; 4:    int main() { 00401010   push        ebp 00401011   mov         ebp,esp 00401013   sub         esp,40h 00401016   push        ebx 00401017   push        esi 00401018   push        edi 5:        ptr=&array; 00401019   mov         dword ptr [ptr (00414554)],offset array (00414410) 6:        pv=(void *)( array); 00401023   mov         dword ptr [pv (00414558)],offset array (00414410) 7:        pv=(void *)(&array); 0040102D   mov         dword ptr [pv (00414558)],offset array (00414410) 8:        pv=(void *)(   ptr   ); 00401037   mov         eax,[ptr (00414554)] 0040103C   mov         [pv (00414558)],eax 9:        pv=(void *)(  *ptr   ); 00401041   mov         ecx,dword ptr [ptr (00414554)] 00401047   mov         dword ptr [pv (00414558)],ecx 10:       pv=(void *)( **ptr   ); 0040104D   mov         edx,dword ptr [ptr (00414554)] 00401053   mov         eax,dword ptr [edx] 00401055   mov         [pv (00414558)],eax 11:       pv=(void *)(   ptr++ ); 0040105A   mov         ecx,dword ptr [ptr (00414554)] 00401060   mov         dword ptr [pv (00414558)],ecx 00401066   mov         edx,dword ptr [ptr (00414554)] 0040106C   add         edx,28h 0040106F   mov         dword ptr [ptr (00414554)],edx 12:       pv=(void *)( *(ptr++)); 00401075   mov         eax,[ptr (00414554)] 0040107A   mov         [pv (00414558)],eax 0040107F   mov         ecx,dword ptr [ptr (00414554)] 00401085   add         ecx,28h 00401088   mov         dword ptr [ptr (00414554)],ecx 13:       pv=(void *)(  *ptr++ ); 0040108E   mov         edx,dword ptr [ptr (00414554)] 00401094   mov         dword ptr [pv (00414558)],edx 0040109A   mov         eax,[ptr (00414554)] 0040109F   add         eax,28h 004010A2   mov         [ptr (00414554)],eax 14:       pv=(void *)( (*ptr)+1); 004010A7   mov         ecx,dword ptr [ptr (00414554)] 004010AD   add         ecx,4 004010B0   mov         dword ptr [pv (00414558)],ecx 15:       pv=(void *)(** ptr++ ); 004010B6   mov         edx,dword ptr [ptr (00414554)] 004010BC   mov         eax,dword ptr [edx] 004010BE   mov         [pv (00414558)],eax 004010C3   mov         ecx,dword ptr [ptr (00414554)] 004010C9   add         ecx,28h 004010CC   mov         dword ptr [ptr (00414554)],ecx 16:       pv=(void *)(**(ptr++)); 004010D2   mov         edx,dword ptr [ptr (00414554)] 004010D8   mov         eax,dword ptr [edx] 004010DA   mov         [pv (00414558)],eax 004010DF   mov         ecx,dword ptr [ptr (00414554)] 004010E5   add         ecx,28h 004010E8   mov         dword ptr [ptr (00414554)],ecx 17:       return 0; 004010EE   xor         eax,eax 18:   } 004010F0   pop         edi 004010F1   pop         esi 004010F2   pop         ebx 004010F3   mov         esp,ebp 004010F5   pop         ebp 004010F6   ret  1:    int array[10]={214,4654,6,76,5}; 2:    int (*ptr)[10]; 3:    void *pv; 4:    int main() { 00401010   push        ebp 00401011   mov         ebp,esp 00401013   sub         esp,40h 00401016   push        ebx 00401017   push        esi 00401018   push        edi 5:        ptr=&array; 00401019   mov         dword ptr [ptr (00414554)],offset array (00414410) 6:        pv=(void *)( array); 00401023   mov         dword ptr [pv (00414558)],offset array (00414410) 7:        pv=(void *)(&array); 0040102D   mov         dword ptr [pv (00414558)],offset array (00414410) 8:        pv=(void *)(   ptr   ); 00401037   mov         eax,[ptr (00414554)] 0040103C   mov         [pv (00414558)],eax 9:        pv=(void *)(  *ptr   ); 00401041   mov         ecx,dword ptr [ptr (00414554)] 00401047   mov         dword ptr [pv (00414558)],ecx 10:       pv=(void *)( **ptr   ); 0040104D   mov         edx,dword ptr [ptr (00414554)] 00401053   mov         eax,dword ptr [edx] 00401055   mov         [pv (00414558)],eax 11:       pv=(void *)(   ptr++ ); 0040105A   mov         ecx,dword ptr [ptr (00414554)] 00401060   mov         dword ptr [pv (00414558)],ecx 00401066   mov         edx,dword ptr [ptr (00414554)] 0040106C   add         edx,28h 0040106F   mov         dword ptr [ptr (00414554)],edx 12:       pv=(void *)( *(ptr++)); 00401075   mov         eax,[ptr (00414554)] 0040107A   mov         [pv (00414558)],eax 0040107F   mov         ecx,dword ptr [ptr (00414554)] 00401085   add         ecx,28h 00401088   mov         dword ptr [ptr (00414554)],ecx 13:       pv=(void *)(  *ptr++ ); 0040108E   mov         edx,dword ptr [ptr (00414554)] 00401094   mov         dword ptr [pv (00414558)],edx 0040109A   mov         eax,[ptr (00414554)] 0040109F   add         eax,28h 004010A2   mov         [ptr (00414554)],eax 14:       pv=(void *)( (*ptr)+1); 004010A7   mov         ecx,dword ptr [ptr (00414554)] 004010AD   add         ecx,4 004010B0   mov         dword ptr [pv (00414558)],ecx 15:       pv=(void *)(** ptr++ ); 004010B6   mov         edx,dword ptr [ptr (00414554)] 004010BC   mov         eax,dword ptr [edx] 004010BE   mov         [pv (00414558)],eax 004010C3   mov         ecx,dword ptr [ptr (00414554)] 004010C9   add         ecx,28h 004010CC   mov         dword ptr [ptr (00414554)],ecx 16:       pv=(void *)(**(ptr++)); 004010D2   mov         edx,dword ptr [ptr (00414554)] 004010D8   mov         eax,dword ptr [edx] 004010DA   mov         [pv (00414558)],eax 004010DF   mov         ecx,dword ptr [ptr (00414554)] 004010E5   add         ecx,28h 004010E8   mov         dword ptr [ptr (00414554)],ecx 17:       return 0; 004010EE   xor         eax,eax 18:   } 004010F0   pop         edi 004010F1   pop         esi 004010F2   pop         ebx 004010F3   mov         esp,ebp 004010F5   pop         ebp 004010F6   ret

引用 6 楼 u013470052 的回复:[quote=引用 2 楼 modyaj 的回复:] 1.嗯 2.运算符优先级问题已经前置、后置++ 的问题 ptr++的值跟ptr的值一样---不用多解释 *(ptr)跟*(Ptr++)却不一样----先运算括号里，取值运算之前后面一个指针移动了 所以不同 3.有必要这里好好看看，ptr是一个指向具有10int类型的数组， 看你的倒数第三第四行代码 第三行 先取ptr  然后指针++ 此时指针移动偏移量=10*4 （也就是10个int） 看第四行 把它=+1  等价于+4(一个int)  所以第三行和第四行之间就相差 11个int  也就是44 你觉得*(ptr)和*(ptr++)的值不一样是因为先算括号里的？[/quote] 嗯，我是这么理解的！

计算机组成原理→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

指针是C的精华，也是最难的，共同学习。

引用 2 楼 modyaj 的回复:1.嗯 2.运算符优先级问题已经前置、后置++ 的问题 ptr++的值跟ptr的值一样---不用多解释 *(ptr)跟*(Ptr++)却不一样----先运算括号里，取值运算之前后面一个指针移动了 所以不同 3.有必要这里好好看看，ptr是一个指向具有10int类型的数组， 看你的倒数第三第四行代码 第三行 先取ptr  然后指针++ 此时指针移动偏移量=10*4 （也就是10个int） 看第四行 把它=+1  等价于+4(一个int)  所以第三行和第四行之间就相差 11个int  也就是44 你觉得*(ptr)和*(ptr++)的值不一样是因为先算括号里的？

为什么ptr++的值跟ptr的值一样 对啊，是一样的，后++是后效性的  .但是*(ptr)跟*(Ptr++)却不一样 对啊，因为你前面执行过一个ptr++了，所以指针+1，字节上前进了40

为什么array.和&array是一样的，这是一个历史问题。  当年c语言规定，int array[100]，array本身就是地址。但是后来总有人对array取地址，即可&array，语言上也兼容了这种情况，因此array和&array是一样的

指针问题多想  多研究 有必要的时候画草图辅助一下


Question: C语言菜鸟：为啥360会把我编的程序当成病毒，阻止运行？求大神指点

引用 3 楼 zhao4zhong1 的回复:因为360是流氓软件。 那应该用神马安全软件？

不过楼主的代码也被360报毒挺奇怪的，代码中没调用什么函数。

从来不用360  呵呵

360就是做流氓软件出生的,  还记得当年的3721吗 对于现在普通家用电脑, 应该果断卸载360, 你会发现机不卡了, 运行流畅了, 开机更快了.

因为你的程序没有被360记录下来

我不用360很多年。

程序人用360，小朋友你把我惊呆了

很多exe文件360也都会当成木马

因为360是流氓软件，你又沒有交保護費

写程序时先关闭360 这是常识

360正事干不了还净添乱 趁你不注意改点设置 结果vpn挂了。。。找了很久才想到360干的！ 果断卸载流氓软件

引用 6 楼 super_admi 的回复:楼上说的给360钱是一个办法，其实还有另一个办法，就是把你的软件写成一个病毒，360就不会阻止运行了。  求写病毒教程

请把钱打到这个卡上：10010001001001001 建行卡，开户名：360 谢谢！ 请打10000. 打过后保证不阻止。

引用 3 楼 zhao4zhong1 的回复:因为360是流氓软件。 原来是这样。

因为你没有给360塞钱，所以你没有进入它的白名单

有一次电脑管家也把我写的一个小程序当病毒删了。。。 就是计算1到100的和。。。

远离国产软件，不仅仅是杀毒软件！你见过正则工具都要联网么？我就见过！

因为360是流氓软件。

我觉得不是没塞钱的问题，因为编译成功后直接打开exe文件运行而不是点击IDE里的运行或调试按钮就不会被杀毒软件拦截。 应该是IDE里的调试器或者其他什么的在对正在运行的程序做监控或者调用什么的，导致杀毒软件误以为是恶意程序。 比如说要在IDE里debug,断言，断点这些。


Question: 关于C的一个小问题

非常感谢各位！ 知道错误在哪了。！　我自己以后会注意！　　太感谢了

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

以整型格式输出单精度型数据，是要被截断的，这个你可以在C的数据类型中查阅。

遇到此类问题，最好的办法是就在计算完成一步后，立即打印出各变量值，这样便于核对，初学时不要求快。  我调试了一下，改成如下语句便可打印出正确结果了。  printf ("%f", d);  //检查d值是否正确

#include "stdio.h"  void main() { int a,b,c,d; scanf("%d%d%d",&a,&b,&c); d=b*b-4*a*c; printf("%d",d); if(b>0) { 	printf("有两个根"); } else if(b=0) { 	printf("有一个根"); } getch();  }实测为1 ，要不 都用％ｆ或％ｄ

楼上正解

printf ("%f", d);  //检查d值是否正确


Question: 关于a++和++a的问题

引用 3 楼 ricardoAlex 的回复:[quote=引用 1 楼 user-1 的回复:] 去看置顶帖  这代码是错的  涉及未定义行为  结果没有意义  分析结果是在搞笑 请问是这一条吗？[/quote] 对的

引用 1 楼 user-1 的回复:去看置顶帖  这代码是错的  涉及未定义行为  结果没有意义  分析结果是在搞笑 请问是这一条吗？

另外 扯什么从右到左的 都是在误人子弟  楼下的自重

去看置顶帖  这代码是错的  涉及未定义行为  结果没有意义  分析结果是在搞笑


Question: 定义一个元素为指针的数组类型 typedef  char* (MESG_TYPE)[3] ;

没什么问题 typedef  char* (MESG_TYPE)[3]; // 可以直接写成 typedef  char* MESG_TYPE[3];  MESG_TYPE *grMesgQue = 0; MESG_TYPE grBufMesgQue2 =   {    "from task4:to eat4\n",    "from task4:to walk4\n",    "from task4:to sleep4\n" };  void func(void) {    grMesgQue = &grBufMesgQue2;    if (grMesgQue != 0)    {       debugs("%s\n", (*grMesgQue)[0]);       debugs("%s\n", (*grMesgQue)[1]);       debugs("%s\n", (*grMesgQue)[2]);       grMesgQue = 0;    } }

typedef  char (*MESG_TYPE)[3] ;

忘了说 编译环境是MDK ， arm三星的嵌入式芯片。


Question: 这个程序为什么不能显示统计制表符、换行符、空格个数？

引用 8 楼 asdasewqs 的回复:[quote=引用 7 楼 zhao4zhong1 的回复:] 按Enter、Ctrl+Z、Enter退出。 感谢！还2个问题，EOF(end of file)是不是字符串的结束符\0？ 2是这个程序： 输入复制到输出，将相连的多个空格用一个空格代替 #include <stdio.h> int main(void) {int c; int inspace; inspace=0; while((c=getchar())!=EOF) {if (c==' '){ if (inspace==0){ inspace==1; putchar(c); }} if (c!=' '){ inspace=0; putchar(c);}} return 0; } 输入复制到输出是实现了，但是我连敲3个空格回车后还是3空格，怎么实现3空格变一个空格？？谢谢了。 [/quote] 参考《编译原理》中的词法分析和有限状态自动机。

引用 7 楼 zhao4zhong1 的回复:按Enter、Ctrl+Z、Enter退出。 感谢！还2个问题，EOF(end of file)是不是字符串的结束符\0？ 2是这个程序： 输入复制到输出，将相连的多个空格用一个空格代替 #include <stdio.h> int main(void) {int c; int inspace; inspace=0; while((c=getchar())!=EOF) {if (c==' '){ if (inspace==0){ inspace==1; putchar(c); }} if (c!=' '){ inspace=0; putchar(c);}} return 0; } 输入复制到输出是实现了，但是我连敲3个空格回车后还是3空格，怎么实现3空格变一个空格？？谢谢了。

按Enter、Ctrl+Z、Enter退出。

呆B,EOF是那个字符????????????? 死循环知道不???????????  #include <stdio.h> int main(void) { int tabs,newlines,blanks; int c;                                  /*自己比较一下*/ int lastchar=0; blanks=0; tabs=0; newlines=0; while(1)                  /*自己比较一下*/ {c=getchar(); if(c==' ') ++blanks; if(c=='\t') ++tabs; if(c=='\n') ++newlines; if(c=='q'){                     /*自己比较一下,遇到q退出*/ if (lastchar!='\n'){ ++newlines;} break;}                    /*自己比较一下*/ lastchar=c; } printf("%d%d%d\n",blanks,tabs,newlines); return 0; }

引用 3 楼 asdasewqs 的回复:[quote=引用 1 楼 zhao4zhong1 的回复:] 仅供参考//The _getch function reads a single character from the console without echoing. //Function can not be used to read CTRL+Break. //When reading a function key or an arrow key, //_getch must be called twice; the first call returns 0 or 0xE0, //and the second call returns the actual key code. #include <conio.h> #include <windows.h> void main() {     unsigned short k;      while (1) {         Sleep(100);         k=getch();         if (27==k) break;//按Esc键退出         if (0==k||0xe0==k) k|=getch()<<8;//非字符键         cprintf("%04x pressed.\r\n",k);     } }  我写的程序问题出在哪呢？？[/quote] 代码功能归根结底不是别人帮自己看或讲解或注释出来的；而是被自己静下心来花足够长的时间和精力亲自动手单步或设断点或对执行到某步获得的中间结果显示或写到日志文件中一步一步分析出来的。 提醒：再牛×的老师也无法代替学生自己领悟和上厕所！ 单步调试和设断点调试（VS IDE中编译连接通过以后，按F10或F11键单步执行，按Shift+F11退出当前函数；在某行按F9设断点后按F5执行停在该断点处。）是程序员必须掌握的技能之一。

引用 2 楼 u010486937 的回复:tab键不是让你输入‘\t’的，而是计算机把tab转换成'\t'的，简单修改的一下 我是用vc++6.0，改成你写的还是不能显示次数。

引用 1 楼 zhao4zhong1 的回复:仅供参考//The _getch function reads a single character from the console without echoing. //Function can not be used to read CTRL+Break. //When reading a function key or an arrow key, //_getch must be called twice; the first call returns 0 or 0xE0, //and the second call returns the actual key code. #include <conio.h> #include <windows.h> void main() {     unsigned short k;      while (1) {         Sleep(100);         k=getch();         if (27==k) break;//按Esc键退出         if (0==k||0xe0==k) k|=getch()<<8;//非字符键         cprintf("%04x pressed.\r\n",k);     } }  我写的程序问题出在哪呢？？