Question: PAT乙级1080题，测试点3超时，怀疑是给结构体内部数据赋值太费时了

呵呵，看你不知道所以才告诉你的 引用 4 楼 Mr_relativity 的回复:[quote=引用 2 楼 自信男孩的回复:]耗时是时间复杂度大了，影响时间复杂度的主要还是循环次数 这种定义式的回答，我也知道说，但没解答我的问题啊[/quote]

引用 2 楼 自信男孩的回复:耗时是时间复杂度大了，影响时间复杂度的主要还是循环次数 这种定义式的回答，我也知道说，但没解答我的问题啊

引用 1 楼 636f6c696e的回复:单纯的赋值根本不耗多少时间，该优化的是循环 这种定义式的回答，我也知道说，但没解答我的问题啊

不要疑神疑鬼的啦，PAT要求算法的复杂度在N*logN，你这N*N的算法一定超时的。 乙级PAT搞来搞去就是些排序之类的简单算法。  这道题用C语言写，思路如下： 1：首先将学号和在线编程成绩读入到student数组中，期中、期末成绩置-1。 2：按照学号，用快速排序（qsort）对数组进行排序。 3：读入学号、期中成绩，用二分法（bsearch）查找学号，找到则修改对应的期中成绩。 4：读入学号、期末成绩，用二分法（bsearch）查找学号，找到则修改对应的期末成绩；并按规则计算出总成绩； 5：按总成绩、学号，进行快速排序。 6：输出：在线编程成绩>=200并且总成绩>=60 的记录。

耗时是时间复杂度大了，影响时间复杂度的主要还是循环次数

单纯的赋值根本不耗多少时间，该优化的是循环

引用 6 楼 Italink的回复:你贴张图片，让神仙给你找错？代码贴出来，附上题目链接，别人才可以帮你调试，做修改啊 代码怎么贴出来呢，直接粘贴，格式会乱啊

引用 楼主 Mr_relativity的回复:问题描述： 我是一个编程小白，在做PAT乙级1080题目时，自己的程序提交，发现测试点3超时，网上搜索多说是因为循环对比确定学生导致了超时，要用map的方法锁定学生，显然那样做是OK的。 但我发现把我程序中所有循环里的赋值语句删除或者把原本赋值给结构体的语句改为赋值给数组，再提交，就不会超时了（虽然答案还是错误的），这是为什么呢？    为此我一直怀疑赋值给结构体数组很耗时，但就是一个赋值操作，不应该这么耗时啊，求大佬解答！！！！（图片附上题目和代码）  第一张图片是题目，第二张是头文件，第三、四张是第1次的代码截图，第五、六张是第2次代码截图 *****第二次我本来想先在循环里把值赋给三个数组（改成赋给数组之后就不超时了，只是答案错误）。但计算结束后再赋回给结构体数组的操作（就是引用住的那部分赋值语句）居然又导致了超时，种种迹象让我老觉得是赋值给结构体数组导致的超时 题目地址：https://pintia.cn/problem-sets/994805260223102976/problems/994805261493977088

引用 6 楼 Italink的回复:你贴张图片，让神仙给你找错？代码贴出来，附上题目链接，别人才可以帮你调试，做修改啊 哦，我的错；新手，不知道规矩，哈哈(๑>؂<๑）


Question: pi求法

#include <stdio.h> long a=10000; long b; long c=2800; long d; long e; long f[2801]; long g; int main() {     for(;b-c;) f[b++]=a/5; //  while (1) { //      if (0==b-c) break; //      f[b]=a/5; //      b++; //  }      //f[0 - 2800] = 10000/5     for(;d=0,g=c*2;c-=14,printf("%.4d",e+d/a),e=d%a)           for(b=c;d+=f[b]*a,f[b]=d%--g,d/=g--,--b;d*=b); //  while (1) { //      d=0; //      g=c*2; //      if (0==g) break; //      b=c; //      while (1) { //          d+=f[b]*a; //          f[b]=d%--g; //          d/=g--; //          --b; //          if (0==b) break; //          d*=b; //      } //      c-=14; //      printf("%.4d",e+d/a); //      e=d%a; //  }  	return 0; }

#include<math.h> 可以去掉的，因为程序里并没有使用数学函数

所以你的问题是什么？秀一段乱命名别人根本看不懂的代码么？


Question: 成绩统计系统，写入的信息读取不出来

读文件有问题，你应该能看到编译器给你的警告； 改成如下： fscanf(fp,"%10s,%10s,%8.2f,%8.2f" ,student[i].num, student[i].name,&student[i].c, &student[i].math);

再次运行程序时总会把我上次写入的信息给清掉


Question: 字符串数组的初始化

引用 3 楼 636f6c696e的回复:错误代码导致的未定义行为 只能说明编译器中a、b、c是连续内存 所以打印c的时候，由于没有找到截止符'\0'，因此也打印了b的内容 b的长度比较长，一般都会有截止符 可是我把b和a删去了也会出现两次abc？？

引用 1 楼 轻箬笠的回复:习惯用第一种。 至于为什么有两个abc，应该说c[]没有字符串截止符 那b为什么就有截止符呢

习惯用第一种。 至于为什么有两个abc，应该说c[]没有字符串截止符

谢谢老哥，你一说我更懂了。不过我已经结贴了

谢谢老哥，你一说我更懂了。不过我已经结贴了

懂了，谢谢老哥。不过我刚刚已经结贴

这个和编译器对局部变量的布局有关，不同的编译器对局部变量有不同的方案 你换一个编译器可能就有不同的结果，因为你的代码中对c变量的写法属于C语言标准中未定义的行为 你可以用printf("%u\n", sizeof(c));看看，结果是3，这说明没有结束符，所以c严格来说不是一个有效的字符串 强行显示会越界直到遇到结束符为止，你的情况刚好越界显示了

引用 2 楼 Martin Morning 的回复:[quote=引用 1 楼 轻箬笠的回复:]习惯用第一种。 至于为什么有两个abc，应该说c[]没有字符串截止符 那b为什么就有截止符呢[/quote] 好像b这种初始化方式，后面没有值的，就都是初始化为0的吧


Question: 在被调用的函数中定义数组，长度为变量。

vs不支持这个特性 人家定位就是C++ 要测试C语言的一些新特性 换IDE  顺便书里面写错了  变成数组没有分main函数和非main函数 都一样

引用 5 楼 自信男孩 的回复:C++支持可变长数组，C语言还是不支持的。不过，如果想用可变数组也是没问题， 使用malloc/free就可以了。比如你在func中这样使用： int iArray = (int *)malloc(sizeof(int) * n); 用完记着释放错了 C++根本不存在变长数组  变长数组是C语言特性

引用 2 楼 user-4 的回复:[quote=引用 1 楼 weixin_45358177 的回复:] 导致我每次只能用很大的数组下标来开一个很大的空间，才能让我较自由地输入。 你这是什么书，在非托管语言中数组分配在译时必须为确定的空间,要不你就动态分配内存，自己管理，用完释放。[/quote]不是必须

最新的C语言标准好像可以，换个新的编译器吧

引用 11 楼 自信男孩 的回复:[quote=引用 7 楼 lin5161678 的回复:] [quote=引用 5 楼 自信男孩 的回复:] C++支持可变长数组，C语言还是不支持的。不过，如果想用可变数组也是没问题， 使用malloc/free就可以了。比如你在func中这样使用： int iArray = (int *)malloc(sizeof(int) * n); 用完记着释放错了 C++根本不存在变长数组  变长数组是C语言特性[/quote]  https://www.jianshu.com/p/cdc4c3ffc031  供参考～[/quote] 你的链接很清楚的写了是C99呀 这是C语言标准  C++标准里面没有变长数组这种东西的  C++编译变长数组Error

引用 7 楼 lin5161678 的回复:[quote=引用 5 楼 自信男孩 的回复:] C++支持可变长数组，C语言还是不支持的。不过，如果想用可变数组也是没问题， 使用malloc/free就可以了。比如你在func中这样使用： int iArray = (int *)malloc(sizeof(int) * n); 用完记着释放错了 C++根本不存在变长数组  变长数组是C语言特性[/quote]  https://www.jianshu.com/p/cdc4c3ffc031  供参考～

Thank  you！

引用 4 楼 636f6c696e的回复:最新的C语言标准好像可以，换个新的编译器吧 前辈，弱弱地问一句编译器怎么换？

引用 2 楼 user-4的回复:[quote=引用 1 楼 weixin_45358177 的回复:] 导致我每次只能用很大的数组下标来开一个很大的空间，才能让我较自由地输入。 你这是什么书，在非托管语言中数组分配在译时必须为确定的空间,要不你就动态分配内存，自己管理，用完释放。[/quote] 谭浩强的C程序设计第四版。

引用 1 楼 weixin_45358177 的回复:导致我每次只能用很大的数组下标来开一个很大的空间，才能让我较自由地输入。 你这是什么书，在非托管语言中数组分配在译时必须为确定的空间,要不你就动态分配内存，自己管理，用完释放。

导致我每次只能用很大的数组下标来开一个很大的空间，才能让我较自由地输入。


Question: 求助

“微差事”这样的？据说微差事比较坑

引用 5 楼 仙人板板！的回复:个人接c++开发，性价比最高，毕业课设都可以联系我 我只是额大一学生哈哈哈

个人接c++开发，性价比最高，毕业课设都可以联系我

打工。。。家教。。。

引用 1 楼 user-3的回复:这个可以有，不过商业的一般都是整个项目的，这种也可以找某宝个人，看看有没有专业查错或技术攻关的。 那对于大一的学生有没有啥子适合的赚钱的么


Question: 关于gets函数，此题为什么只运行一次？

引用 6 楼 自信男孩的回复:[quote=引用 4 楼 weixin_45358177 的回复:] [quote=引用 2 楼 自信男孩的回复:]在for循环之后加一条语句getchar(); 只执行一次的原因是scanf输入后会把换行符留在输入缓存里，所以遇到gets时直接返回了。 还有一个问题是：为什么在输入三个成绩时 前两个scanf之后不用吸收，而都可以继续输入下一个scanf？@636f6c696e@自信男孩[/quote] 因为前两个输入的是浮点型，%f，回车不会和它匹配。另外，gets可以细查一下实现原理，它是遇到换行符就返回的。[/quote] 那和%s匹配吧？但是这种情况不用getchar没问题。

那么请问怎么同时引用呢？

没有@功能吧，只有引用，你可以引用两个人的回复 引用 7 楼 weixin_45358177 的回复:OK，这下更清楚了。谢谢啦！另外能告一下怎么@吗？

OK，这下更清楚了。谢谢啦！另外能告一下怎么@吗？

引用 4 楼 weixin_45358177 的回复:[quote=引用 2 楼 自信男孩的回复:]在for循环之后加一条语句getchar(); 只执行一次的原因是scanf输入后会把换行符留在输入缓存里，所以遇到gets时直接返回了。 还有一个问题是：为什么在输入三个成绩时 前两个scanf之后不用吸收，而都可以继续输入下一个scanf？@636f6c696e@自信男孩[/quote] 因为前两个输入的是浮点型，%f，回车不会和它匹配。另外，gets可以细查一下实现原理，它是遇到换行符就返回的。

引用 1 楼 636f6c696e的回复:用getchar();吸收下第一次输入的回车字符 怎么@呢？每次只能回复一个人吗？而且还得引用改楼的回答。

引用 2 楼 自信男孩的回复:在for循环之后加一条语句getchar(); 只执行一次的原因是scanf输入后会把换行符留在输入缓存里，所以遇到gets时直接返回了。 还有一个问题是：为什么在输入三个成绩时 前两个scanf之后不用吸收，而都可以继续输入下一个scanf？@636f6c696e@自信男孩

嗯，确实可以解决谢谢大家！

用getchar();吸收下第一次输入的回车字符


Question: C语言课程设计时排序出现错误

void sort(struct tele *s) {     struct tele a;     int i,j;     for(i=0;i<cur-1;i++)         for(j=0;j<cur-i-1;j++)             if(strcmp(s[j].name, s[j+1].name) > 0)             {                 a=s[j];                 s[j]=s[j+1];                 s[j+1]=a;             }     printf("Done!\n");     press();     return ; } 供参考～  字符串比较应该用字符串函数来处理，而不是直接比较值，那就成了比较地址值了。


Question: 这个C#的函数调用为什么要加n.（新手刚学不太明摆）

FindMax是NumberManipulator的成员函数


Question: C语言；为什么这个while可以连续输入好几组数字

引用 5 楼 自信男孩的回复:while循环条件是从缓存里得到一个int类型数据，根据scanf是格式化输入，每次输入是以空格分开的，再根据标准输入是行缓冲，即 输入回车才能将输入缓存里的数据刷到内存。因此执行完123的输入之后再次等待输入，正好此时后面还有456，就继续执行了。 好的，谢谢指点，---------

引用 2 楼 轻箬笠 的回复:因为没有刷新输入缓冲区。下次scanf的时候，继续从输入缓冲区读入数据. while(scanf("%lu",&num)==1)                                //数字用u     { fflush(stdin);//加了这句就跟楼主想的一样了       for (div=2,isprime=1;(div*div)<=num;div++) //快速找出合适的数字       {           if(num%div==0)//余数为0 则说明可以除尽，           {               if((div*div)!=num)   //如果不等于则打印                   printf("%lu 可被整除 %lu 和 %lu.\n",num,div,num/div);               else                      printf("%lu的除数和被除数都是%lu.\n",num,div);               isprime=0;           }       }       if(isprime)           printf("%lu 是一个素数.\n",num);       printf("请输入另一个整数进行分析;");       printf("输入字母会结束.\n");     } 谢谢指点，新入门c prime plus才看了200页，清除缓冲后续应该会学到！

scanf输入数字,你用回车换行分隔也行,用空格 tab之类的也行

好像乱码了，点击原码可以查看


Question: 新手尝试中：二维字符数组按行操作的问题。

引用 4 楼 636f6c696e的回复:初始化可以等号，后续的赋值请用strcpy 嗯，谢谢。我意识到这个问题后看论坛都这么多回复了。。

初始化可以等号，后续的赋值请用strcpy

strncpy,strcpy

char 数组不可以用=号赋值

直接字符串就可以 不需要那个{}


Question: 怎样在被调用的函数里生成一个四位的随机数，然后让电脑去猜，就是在“你的工作在这个函数”那里

设置下随机数种子，如楼上所说 引用 1 楼 636f6c696e 的回复:int num = 0; while (num < 1000) // 保证num是一个四位数 {     num = rand() % 10000;  }

引用 2 楼 PETER.QUEST 的回复:把这个代码放进去了，但是无论怎样猜出来的都是2645，求解  #include<ctime> int num = 0; srand((int)time(0)); while (num < 1000) // 保证num是一个四位数 {     num = rand() % 10000;  }

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

把这个代码放进去了，但是无论怎样猜出来的都是2645，求解


Question: Win10 Vmware 虚拟网络适配器导致发不出广播包的问题

引用 5 楼 赵4老师 的回复:Win10网络更安全，网络防火墙更严格。我猜。 防火墙没开。

Win10网络更安全，网络防火墙更严格。我猜。

引用 3 楼 早打大打打核战争 的回复:使用桥接模式，虚拟机相当于局域网内部的一台真机，理论上不会有任何问题，要么是设置的问题，或者可以升级VMWare高版本试试 已验证。不行。Win7是没有任何问题的。Win10我这里都有问题。

引用 1 楼 早打大打打核战争 的回复:虚拟机设置中的网络适配器->网络连接模式，选桥接模式，不要用NAT模式  emmm我就是桥接模式。

虚拟机设置中的网络适配器->网络连接模式，选桥接模式，不要用NAT模式


Question: Linux下进行的des加密后base64编码为什么放到网上的在线解码器上就解不出来了

void HexDump(char *buf,int len,int addr) {     int i,j,k;     char binstr[80];      for (i=0;i<len;i++) {         if (0==(i%16)) {             sprintf(binstr,"%08x -",i+addr);             sprintf(binstr,"%s %02x",binstr,(unsigned char)buf[i]);         } else if (15==(i%16)) {             sprintf(binstr,"%s %02x",binstr,(unsigned char)buf[i]);             sprintf(binstr,"%s  ",binstr);             for (j=i-15;j<=i;j++) {                 sprintf(binstr,"%s%c",binstr,('!'<buf[j]&&buf[j]<='~')?buf[j]:'.');             }             printf("%s\n",binstr);         } else {             sprintf(binstr,"%s %02x",binstr,(unsigned char)buf[i]);         }     }     if (0!=(i%16)) {         k=16-(i%16);         for (j=0;j<k;j++) {             sprintf(binstr,"%s   ",binstr);         }         sprintf(binstr,"%s  ",binstr);         k=16-k;         for (j=i-k;j<i;j++) {             sprintf(binstr,"%s%c",binstr,('!'<buf[j]&&buf[j]<='~')?buf[j]:'.');         }         printf("%s\n",binstr);     } }

先澄清一个概念： 加密的对象不是字符串，是长度固定的一段二进制字节。

引用 1 楼 赵4老师 的回复:先澄清一个概念： 加密的对象不是字符串，是长度固定的一段二进制字节。 老师，使用openssl -des 命令加密后以base64编码结果输出和这种程式代码实现是有区别的吗？ 指令得到的结果是能够被在线解码解析出来

先澄清一个概念： 加密的对象不是字符串，是长度固定的一段二进制字节。


Question: NAND FLASH数据能破解吗？

引用 1 楼 user-1 的回复：https://blog.csdn.net/qq_30866297/article/details/52104197看不是很懂，有人写好破解的软件么？


Question: 求助大神，到底哪里出错了？？

楼主要用switch的话，可以先将字符串转成哈希值

C语言的switch是只针对int类型而言的，其他类型不支持的。

引用 1 楼 main(进击的菜鸟)的回复:1、输入字符串要用name[20];用&只能是字符。 2、c/c++ 语言 case后面 只允许是 整型 常量 表达式,不能跟字符串。 多谢大神指点


Question: VS2017 编写C语言代码，计算结果出错是什么造成的

1l|I│┃▏▕〡︱︳

哎呀果然是这个问题，没看清楚，太感谢了，谢谢🙏

%lf 不是%1f   这个问题没搞懂为啥那么多人会把l写成1的


Question: C语言中三角函数调用失败

很看不上这种过于高估自己语文水平的提问。

楼主解决问题了嘛，我好像也遇到类似的问题了。求教

我觉着楼主还是把代码和结果贴出来看看比较好

atan, atan2 Calculates the arctangent of x (atan) or the arctangent of y/x (atan2).  double atan( double x );  double atan2( double y, double x );  Routine Required Header Compatibility  atan <math.h> ANSI, Win 95, Win NT  atan2 <math.h> ANSI, 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  atan returns the arctangent of x. atan2 returns the arctangent of y/x. If x is 0, atan returns 0. If both parameters of atan2 are 0, the function returns 0. You can modify error handling by using the _matherr routine. atan returns a value in the range –π/2 to π/2 radians; atan2 returns a value in the range –π to π radians, using the signs of both parameters to determine the quadrant of the return value.   Parameters  x, y  Any numbers  Remarks  The atan function calculates the arctangent of x. atan2 calculates the arctangent of y/x. atan2 is well defined for every point other than the origin, even if x equals 0 and y does not equal 0.  Example  /* ATAN.C: This program calculates   * the arctangent of 1 and -1.  */  #include <math.h> #include <stdio.h> #include <errno.h>  void main( void )  {    double x1, x2, y;     printf( "Enter a real number: " );    scanf( "%lf", &x1 );    y = atan( x1 );    printf( "Arctangent of %f: %f\n", x1, y );    printf( "Enter a second real number: " );    scanf( "%lf", &x2 );    y = atan2( x1, x2 );    printf( "Arctangent of %f / %f: %f\n", x1, x2, y );  }   Output  Enter a real number: -862.42 Arctangent of -862.420000: -1.569637 Enter a second real number: 78.5149 Arctangent of -862.420000 / 78.514900: -1.480006   Floating-Point Support Routines  See Also   acos, asin, cos, _matherr, sin, tan

角度需要转换为弧度

加调试手段啊，调用atan的输入输出都打印出来不就能确定是atan的问题还是其他的问题了么？ 引用 3 楼 Kelvin_001 的回复:通过比对出错时程序区代码正常未被改写。另外程序结构有些复杂，感觉是调用环节出了问题，但是又不知道该怎么排查

单位没问题的，是弧度的。关键是前面两次调用atan函数返回值是正确的。执行两次以后就不按照输入来了，即使是同样的输入。

引用 楼主 Kelvin_001 的回复:最近在TI DSP 6701平台上写了个大地坐标系高度角计算的函数，其中用到了三角函数atan，发现前面几次调用时程序执行正常，但是执行两轮后，后续调用时，返回结果均不符合预期。经过初步排查出错时程序正常，栈未溢出。尚不知问题出在哪，恳请各位大拿指点！ 谢谢邀请，这种结果不符合预期，仅凭上面说的这些很难推断出问题所在 首先得排除掉标准函数出错的可能 那就从给的参数入手了，对这个平台不太了解，帮不上你什么

标准库还是有这种问题我是不信的 建议加打印贴出调试结果


Question: 带有头结点的双链表的实现和相关操作

哥哥，能帮我注释一下么，有的看不懂…

引用 1 楼 李文强liwq的回复:双向链表属于基本数据结构，网上资料太多了。下面是我写的，仅供参考。   #include <stdio.h> #include <stdlib.h>  typedef struct T_Node { 	int iValue; 	struct T_Node *pLeftNode; 	struct T_Node *pRightNode; }TNode;  static TNode *g_ptHeadNode = NULL;  TNode *func_create(int iValue) { 	TNode *ptNode = (TNode*)malloc(sizeof(TNode)); 	if(NULL == ptNode) 	{ 		return NULL; 	} 	 	ptNode->pLeftNode = NULL; 	ptNode->pRightNode = NULL;	 	ptNode->iValue = iValue; 	 	return ptNode; }  int func_isEmptyCheck() { 	if(NULL == g_ptHeadNode) 	{ 		return -1; 	} 	 	return 0; }  /*插入尾部*/ void func_tailInsert() { 	int iValue = 0; 	int iRet = func_isEmptyCheck(); 	if(-1 == iRet) 	{ 		printf("请输入头结点的数值:"); 		scanf("%d",&iValue);		 		g_ptHeadNode = func_create(iValue); 		 		return; 	} 	 	printf("请输入要添加的尾节点的数值:"); 	scanf("%d",&iValue); 	TNode *ptNode = func_create(iValue); 	 	TNode *ptTailNode = g_ptHeadNode; 	 	while(ptTailNode->pRightNode) 	{ 		ptTailNode = ptTailNode->pRightNode; 	} 	 	ptTailNode->pRightNode = ptNode; 	 	ptNode->pLeftNode = ptTailNode; 	ptNode->pRightNode = NULL; 	 	return; }  /*插入头部*/ void func_headInsert() { 	int iValue = 0; 	int iRet = func_isEmptyCheck(); 	if(-1 == iRet) 	{ 		printf("请输入头结点的数值:"); 		scanf("%d",&iValue);		 		g_ptHeadNode = func_create(iValue); 		 		return; 	} 	 	printf("请输入要添加的头节点的数值:"); 	scanf("%d",&iValue); 	TNode *ptNode = func_create(iValue); 	 	TNode *ptRightNode = g_ptHeadNode->pRightNode; 	 	g_ptHeadNode->pLeftNode = ptNode;	 	ptNode->pRightNode = g_ptHeadNode; 	 	g_ptHeadNode = ptNode; 	 	return; }  /*删除尾部*/ void func_tailDelete() { 	int iValue = 0; 	int iRet = func_isEmptyCheck(); 	if(-1 == iRet) 	{ 		printf("双向链表是空的\n"); 		return; 	}	 	 	TNode *ptTailNode = g_ptHeadNode; 	 	while(ptTailNode->pRightNode) 	{ 		ptTailNode = ptTailNode->pRightNode; 	} 		 	ptTailNode->pLeftNode->pRightNode = NULL;	 	 	printf("你要删除的尾节点为%d\n",ptTailNode->iValue); 	 	free(ptTailNode); 	ptTailNode = NULL; 	 	return; }  /*删除头部*/ void func_headDelete() { 	int iValue = 0; 	int iRet = func_isEmptyCheck(); 	if(-1 == iRet) 	{ 		printf("双向链表是空的\n"); 		return; 	} 	 	TNode *ptNextNode = g_ptHeadNode->pRightNode; 	 	ptNextNode->pLeftNode = NULL; 		 	printf("你要删除的头结点为%d\n",g_ptHeadNode->iValue); 	 	free(g_ptHeadNode); 	g_ptHeadNode = NULL; 	 	g_ptHeadNode = ptNextNode; 	 	return; }  /*显示打印*/ void func_showAll() { 	int iValue = 0; 	int iRet = func_isEmptyCheck(); 	if(-1 == iRet) 	{ 		printf("双向链表是空的\n"); 		return; 	}	 	 	TNode *ptNode = g_ptHeadNode; 	 	while(ptNode) 	{ 		printf("%d<=>",ptNode->iValue); 		ptNode = ptNode->pRightNode; 		if(ptNode == g_ptHeadNode) 		{ 			break; 		} 	} 	printf("\n"); 	 	return; }  /*删除*/ void func_allDelete() { 	int iValue = 0; 	int iRet = func_isEmptyCheck(); 	if(-1 == iRet) 	{ 		printf("双向链表是空的\n"); 		return; 	}	 	 	TNode *ptNode = g_ptHeadNode; 	TNode *ptRightNode = NULL; 	 	while(ptNode) 	{ 		ptRightNode = ptNode->pRightNode; 		free(ptNode); 		ptNode=NULL; 		 		ptNode = ptRightNode; 	} 	 	g_ptHeadNode = NULL; 	 	return; }  int main() { 	int iFlag = 0;  	while(1) 	{ 		printf("操作选项:\n\t1:尾部增加;\t2:头部增加;\n\t3:尾部删除;\t4:头部删除;\n\t5:输出全部;\t6:全部删除;\n\t0:退出\n"); 		printf("请输入你的选择:"); 		scanf("%d",&iFlag); 		switch(iFlag) 		{ 			case 0: 				break; 				 			case 1: 				func_tailInsert(); 				break; 				 			case 2: 				func_headInsert(); 				break; 				 			case 3: 				func_tailDelete(); 				break; 					 			case 4: 				func_headDelete(); 				break; 					 			case 5: 				func_showAll(); 				break; 					 			case 6: 				func_allDelete(); 				break; 					 			default:				 				break; 		} 		 		if(0 == iFlag) 		{ 			break; 		} 		if(5 != iFlag) 		{ 			func_showAll(); 		} 	} 	 	func_allDelete(); 	 	return 0; }  谢谢，我一会仔细看一看…


Question: sizeof 使用求解

我也觉得没啥意义，应该是编译器规定，sizeof 函数的值就为1，函数指针值就和指针的大小一样

要详细就直接翻标准文档不就好了么  sizeof的内容也不多

sizeof 不能用函数名做操作数  结果没意义 不用讨论

引用 3 楼 636f6c696e 的回复:应该是编译器规定，sizeof 函数的值就为1没有这样的规定


Question: 结构体对问题

这两个结构体都是1字节对齐，因为结构体成员的类型最大是char类型。

平常不用，基本在c语言的开源库里见过几次。详情可看下 https://www.cnblogs.com/LonelyEnvoy/p/6065252.html

1) 如果相邻位域字段的类型相同，且其位宽之和小于类型的sizeof大小，则后面的字段将紧邻前一个字段存储，直到不能容纳为止； 2) 如果相邻位域字段的类型相同，但其位宽之和大于类型的sizeof大小，则后面的字段将从新的存储单元开始，其偏移量为其类型大小的整数倍； 3) 如果相邻的位域字段的类型不同，则各编译器的具体实现有差异，VC6采取不压缩方式（不同位域字段存放在不同的位域类型字节中），Dev-C++和GCC都采取压缩方式；  所以st3大小是3，st4是1


Question: dev 运行失败，求大神解答

引用 5 楼 user-1的回复:[quote=引用 4 楼 数码空间 的回复:] [quote=引用 3 楼 user-1的回复:]你先在右上角 改成32bit debug版本看看 还是没有用，exe文件还是无法打开[/quote] 是一闪而过还是提示无法运行啊  你可以在你的代码最后加上一条输入指令比如getchar()或者system("pause"),让它暂停再关闭[/quote] 我搜索到其他的软件有这样的问题，有解决方法，但就我这个还没找到

引用 5 楼 user-1的回复:[quote=引用 4 楼 数码空间 的回复:] [quote=引用 3 楼 user-1的回复:]你先在右上角 改成32bit debug版本看看 还是没有用，exe文件还是无法打开[/quote] 是一闪而过还是提示无法运行啊  你可以在你的代码最后加上一条输入指令比如getchar()或者system("pause"),让它暂停再关闭[/quote] error 216：该版本的1%与你运行的windows版本不兼容....

引用 5 楼 user-1的回复:[quote=引用 4 楼 数码空间 的回复:] [quote=引用 3 楼 user-1的回复:]你先在右上角 改成32bit debug版本看看 还是没有用，exe文件还是无法打开[/quote] 是一闪而过还是提示无法运行啊  你可以在你的代码最后加上一条输入指令比如getchar()或者system("pause"),让它暂停再关闭[/quote] 没有用，这次是提示：不支持的16位应用程序 由于与64位的windows版本不兼容，此程序或功能....无法启动或运行。请联系软件供应商询问是否有与64位windows兼容的版本

引用 4 楼 数码空间 的回复:[quote=引用 3 楼 user-1的回复:]你先在右上角 改成32bit debug版本看看 还是没有用，exe文件还是无法打开[/quote] 是一闪而过还是提示无法运行啊  你可以在你的代码最后加上一条输入指令比如getchar()或者system("pause"),让它暂停再关闭

引用 3 楼 user-1的回复:你先在右上角 改成32bit debug版本看看 还是没有用，exe文件还是无法打开

你先在右上角 改成32bit debug版本看看

引用 1 楼 user-1的回复:你首先在文件夹里找一下 看这个exe生成了没有 如果没有的话,先要编译,才能运行 有，生成了exe文件，但是双击打不开，以前都可以得，现在不知道怎么回事了


Question: 新手求教 c语言一个奇怪的问题

ceil是不是应该有传入参数，在Linux下不会编译成功

可能的原因 1.编译器缺省会引入math.h 头文件 2.编译器对于未声明的函数，认为返回值是int ,  参数可以任意多个。  也就是说，这和编译器有关。

如果引用math库，则编译器知道ceil的原型，可以正确返回 如果不引用math库，则编译器默认为ceil返回int，与原型中的double是不一样的，这是为了兼容C89标准前的程序


Question: 求大神解答这个题里A和B文件信息怎么合并的

引用 2 楼 main(进击的菜鸟)的回复:第二页读B文件的循环语句：for(i=0;(ch=fgetc(fp))!=EOF;i++) 似乎有误，应该将i=0去掉或者自己定义一个变量才对。先将A读到数组，继续读到B，最后写到C文件，达到合并的效果。自己可以百度那些函数。 是有误的，改为i=ni就可以把A和B合在一起，谢谢大佬！

引用 1 楼 user-2的回复:把 A B两个文件中的字符一个个读入到数组c中，再通过冒泡法排序，然后写入文件C中。  不过我觉得第二页读B文件的循环语句：for(i=0;(ch=fgetc(fp))!=EOF;i++) 似乎有误，应该将i=0去掉或者改为i=ni才对。 对的，是有误，之前没发现，谢谢大佬


Question: C野指针简单理解

引用 2 楼 自信男孩 的回复：ok，明白了，谢谢指教

在编程中，都会对指针变量进行if判断，一旦发现了是NULL都会立即报错或者返回。因此NULL指针危险性不会很大。 这个前提是不一定的。 其他没啥问题

危险性大不大，纯粹看人品。

free不是释放了里面的内容，而是把堆上的空间（申请的）由使用状态变成未使用状态，即其他的进程或程序可以继续使用这部分内存区域 只是对内存状态做了修改，并没有对内存里的内容作修改。

答对了


Question: C语言构建栈push操作有问题

引用 3 楼 user-1 的回复:浅拷贝，它拷贝的是对象的地址，它与原对象共享一个对象。    stack->data[++stack->top] = item； 仅copy了地址，没有复制真正的内容，所以说是浅copy。  如你所说：这样写的目的是将二维数组的每一行的指针都指向输入的item这个数组。 这个思路是正确的，但是你需要为其用malloc动态分配一个数组，以保证其所指向的内容是不同的。   Push(stack, realcommand);，保存的是realcommand的地址，指向的是同一个内存地址~~  所以当realcommand的值改变时，就出现了这样的情况 C：\Users\hp\micro> C：\Users\hp\soft\soft>  而 Push(stack, "Users");    Push(stack, "hp");， "Users"、"hp"这两个无名数组的内存地址是不一样的，所以显示正常。  简单的讲吧，如果你压栈函数想用： stack->data[++stack->top] = item；通常情况下，item应当是用malloc动态分配的。  惭愧 ，手误了，没检查，free(stack); 应改为free_stack(stack);   哇 彻底清楚了！！真的非常感谢！ 这积分我留着有何用，全都给你！！再次感谢！

太感谢楼上的大佬了！代码不仅功能实现了，而且代码行文也简洁了许多，学到了很多！万分感谢！ 还有两个小问题，能不能再麻烦大佬给稍微讲解一下：  1. 不是很懂为什么Push函数中 stack->data[++stack->top] = item; 这样的写法是浅拷贝呢？我之前的理解是data是一个二维数组，stack->data[++stack->top] = item;这样写的目的是将二维数组的每一行的指针都指向输入的item这个数组；如果说这样是浅拷贝的话，那么为什么在输入命令行之前，先push了一个users，再push了一个hp，后面不管输入 cd 啥，输出的路径中 users和hp都是没有错的呢？这一点我有点想不明白。  2. 还有就时看到您写了一个叫free_stack的函数，这个函数是不是在您的代码中最终没有使用？还是说在这边您有一个笔误，应该在代码最后return 0之前调用这个函数呢？  引用 1 楼 user-1 的回复:看你的入栈函数，浅copy啊~~~并没有将真正的内容压到栈里去。  按你的思路，改了一下代码.  #include <stdio.h> #include <stdlib.h> #include <string.h>  #define ElementType char //存储数据元素的类型 #define MAXSIZE 1000 //存储数据元素的最大个数  //堆栈的顺序存储结构通常由一个一维数组和一个记录栈顶元素位置的变量组成 typedef struct { 	ElementType** data; 	int top; }Stack;  //初始化栈 Stack* InitStack() { 	Stack* stack; 	stack = (Stack*)malloc(sizeof(Stack)); 	stack->data = (ElementType * *)malloc(sizeof(ElementType*) * 1000); 	if (!stack) { 		printf("空间不足\n"); 		return NULL; 	} 	stack->top = -1; 	return stack; }  void PrintStack(Stack* stack) { 	printf("当前栈中的元素:\n"); 	int i; 	for (i = stack->top; i >= 0; i--) { 		printf("%s\n", stack->data[i]); 	} }  int IsFull(Stack* stack) { 	if (stack->top == MAXSIZE - 1) { 		printf("堆栈已满\n"); 		return 1; 	} 	return 0; }  int IsEmpty(Stack* stack) { 	if (stack->top == -1) { 	//	printf("堆栈空\n"); 		return 1; 	} 	return 0; }  //入栈 void Push(Stack* stack, const ElementType* item) { 	if (IsFull(stack)) { 		return; 	} 	++stack->top; 	stack->data[stack->top] = (char*)malloc(sizeof(char) * strlen(item) + 1); 	strcpy(stack->data[stack->top], item); 	//stack->data[++stack->top] = item; }  //出栈  栈的空间是动态分配的，所以要修改出栈函数 //原先出栈函数，需要静态的。 int Pop(Stack* stack) { //, ElementType* item 	if (IsEmpty(stack)) { 		return 0; 	} 	//strcpy(item, stack->data[stack->top]);   	free(stack->data[stack->top]); 	stack->top--; 	return 1; }  //打印路径 void print_path(Stack* stk) { 	printf("C:"); 	if (IsEmpty(stk)) 		printf("\\"); 	else 		for (int i = 0; i <= stk->top; i++) 			printf("\\%s", stk->data[i]); 	printf(">\n"); }  //释放空间 void free_stack(Stack* stk) { 	if (!IsEmpty(stk)) { 		for (int i = stk->top; i == -1; i--) 			Pop(stk); 	} 	free(stk->data); 	free(stk); }   int main() { 	Stack* stack; 	stack = InitStack(); 	Push(stack, "Users"); 	Push(stack, "hp");  	int num = 0; 	scanf("%d", &num); 	getchar(); 	char command[15] = { '\0' };  	while ((num > 0) && (scanf("%[^\n]", command) != EOF)) { 		getchar(); 		if (command[3] == '.') { 			Pop(stack); 			print_path(stack); 		} 		else { 			Push(stack, command + 3); 			print_path(stack); 		} 		num--; 	} 	free(stack); 	return 0; }


Question: 单片机

应该是编译器的问题吧，我运行你的程序没有一点问题

从你贴出来的程序是没有错的。 但是根据你的错误提示，你的工程里面是不是有2个.c的源文件。你自己检查一下。 如果只有一个main.c并且这个main.c就是你贴出来的内容，应该是不会有错的。  如果可以你把你工程里所包含的文件贴出来，这样应该可以找到问题。

程序没问题的


Question: 单线链表报错，是我的指针用得有问题吗？

#include<stdio.h> #include<stdlib.h> #include<string.h>  struct stud_node {     int num;     char name[20];     int score;     struct stud_node* next; };  struct stud_node* Create_Stu_Doc(); struct stud_node* InsertDoc(struct stud_node* head, struct stud_node* stud); struct stud_node* DeleteDoc(struct stud_node* head, int num); void Print_Stu_Doc(struct stud_node* head);  int main(void) {     struct stud_node* head = NULL, * p;     int choice, num, score;     char name[20];     int size = sizeof(struct stud_node);      do {         printf("1:Creat 2:Insert 3:Delete 4:Print 0:Exit\n");         scanf_s("%d", &choice);         switch (choice) {             case 1:                 head = Create_Stu_Doc();                 break;             case 2:                 printf("Input num,name and score:\n");                 scanf_s("%d%s%d", &num, name, 20, &score);                 p = (struct stud_node*)malloc(size);                 p->num = num;                 p->score = score;                 strcpy_s(p->name, 20, name);                 head = InsertDoc(head, p);                 break;             case 3:                 printf("Input num:\n");                 scanf_s("%d", &num);                 head = DeleteDoc(head, num);                 break;             case 4:                 Print_Stu_Doc(head);                 break;         }      } while (choice != 0);      return 0; }  /*新建链表*/ struct stud_node* Create_Stu_Doc() {     struct stud_node* head, * p;     int num, score;     char name[20];     //int size = sizeof(struct stud_node*);    //此处申请的空间大小有问题     int size = sizeof(struct stud_node);      head = NULL;     printf("Input num,name and score:\n");     scanf_s("%d%s%d", &num, name, 20, &score);     while (num != 0) {         p = (struct stud_node*)malloc(size);         p->num = num;         p->score = score;         strcpy_s(p->name, 20, name);         head = InsertDoc(head, p);         scanf_s("%d%s%d", &num, name, 20, &score);     }     return head; }  struct stud_node* InsertDoc(struct stud_node* head, struct stud_node* stud) {     struct stud_node* ptr, * ptr1 = NULL, * ptr2;     ptr2 = head;     ptr = stud;     if (head == NULL) {         head = ptr;         head->next = NULL;         return head;     }     //if ((ptr2->next != NULL) && (ptr->num > ptr2->num)) {     while (ptr2  && (ptr->num > ptr2->num)) {         ptr1 = ptr2;         ptr2 = ptr2->next;     }     if (!ptr2) {         ptr1->next = ptr;         ptr->next = NULL;     } else {         if (head == ptr2) {             ptr->next = head;             head = ptr;             return head;         }         ptr1->next = ptr;         ptr->next = ptr2;     }     /*     if (ptr->num <= ptr2->num) {         if (head == ptr2) {             ptr->next = head;             head = ptr;             return head;         }         ptr1->next = ptr;         ptr->next = ptr2;     } else {         ptr2->next = ptr;         ptr->next = NULL;     }     */      return head; }  /*删除成绩小于60分的学生*/ struct stud_node* DeleteDoc(struct stud_node* head, int num) {     struct stud_node* ptr1, * ptr2;     while (head != NULL && head->num == num)     {         ptr2 = head;         head = head->next;         free(ptr2);     }     if (head == NULL)         return NULL;      ptr1 = head;     ptr2 = head->next;     while (ptr2 != NULL)     {         if (ptr2->num == num) {             ptr1->next = ptr2->next;             free(ptr2);         }         else {             ptr1 = ptr2;             ptr2 = ptr2->next;         }     }     return head; }  void Print_Stu_Doc(struct stud_node* head) {     struct stud_node* ptr;     if (head == NULL) {         printf("\nNo Records\n");         return;     }     printf("\nThe Studens' Records Are:\n");     printf("Num\t Name\t Score\n");     //for (ptr = head; ptr->next != NULL; ptr = ptr->next) {     for (ptr = head; ptr != NULL; ptr = ptr->next) {         printf("%d\t%s\t%d\n", ptr->num, ptr->name, ptr->score);     }  }   供参考～

int size = sizeof(struct stud_node* ); 敲错了，这个size在32位机器上永远是4，因为是地址

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

手抖打错了几行代码吧~~   31 行	scanf_s("%d%s%d", &num, name, 20 , &score);   加上20  59行  int size = sizeof(struct stud_node* ); 把*去掉。


Question: 怎么有32呢

引用 1 楼 lin5161678 的回复:你把main里面的变量名换掉 不要用 abc  然后你告诉我为什么func里面的c 应该是 2? 厉害了，我的哥

默认值只看传递顺序，又不是看变量名，函数里的变量名对外是不可见的

Console.Write(Fun(c,b)); ==>fun(2,5,6) ==》return 2+5*6


Question: double的精度问题

引用 2 楼 轻箬笠 的回复:double和floatdouble存在精度问题。强制转为int，舍弃小数点后部分。 应该是100 × d之后的结果舍弃小数部分，而不是d县舍弃小数部分再乘以100.这个需要明确的。

存储格式参考：https://blog.csdn.net/qq_15437667/article/details/50901543 说白了你输入的数字在计算机的二进制都是无法准确表达的数字 如果是0.5 0.75这样的小数部分，二进制能够准确表达成.1和.11。但是0.99这样的小数部分，无论是float还是double都无法准确表达，都会有误差。 所以你的例子中，*100产生精度损失后，出现了误差

你的问题要去深入float和double的存储格式才能知道了

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

引用 5 楼 Martin Morning 的回复:[quote=引用 4 楼 轻箬笠的回复:][quote=引用 3 楼 Martin Morning 的回复:] [quote=引用 2 楼 轻箬笠的回复:]double和floatdouble存在精度问题。强制转为int，舍弃小数点后部分。 可是为什么99和199要减1，299就不用了[/quote] 这个跟IEEE754的标准有关系。[/quote] 意思是不同环境下运行结果不同吗[/quote] 楼主可以用http://www.binaryconvert.com/result_float.html?decimal=050046057057这个地址下面的转换器试试看。 对于单精度数float 0.99=9.900000095367431640625E-1 1.99=1.9900000095367431640625E0 2.99=2.9900000095367431640625E0 -0.99=-9.900000095367431640625E-1 对于双精度数double 0.99=9.89999999999999991118215802999E-1 1.99=1.989999999999999991118215803E0 2.99=2.99000000000000021316282072803E0 3.99=3.99000000000000021316282072803E0 跟楼主的打印结果相符合

引用 4 楼 轻箬笠的回复:[quote=引用 3 楼 Martin Morning 的回复:] [quote=引用 2 楼 轻箬笠的回复:]double和floatdouble存在精度问题。强制转为int，舍弃小数点后部分。 可是为什么99和199要减1，299就不用了[/quote] 这个跟IEEE754的标准有关系。[/quote] 意思是不同环境下运行结果不同吗

引用 3 楼 Martin Morning 的回复:[quote=引用 2 楼 轻箬笠的回复:]double和floatdouble存在精度问题。强制转为int，舍弃小数点后部分。 可是为什么99和199要减1，299就不用了[/quote] 这个跟IEEE754的标准有关系。

引用 2 楼 轻箬笠的回复:double和floatdouble存在精度问题。强制转为int，舍弃小数点后部分。 可是为什么99和199要减1，299就不用了

建议多多看看基础课程


Question: 间接访问为什么用**表示？

弱爆了，感觉要仔细想想

引用 9 楼 过程中的美好 的回复:[quote=引用 8 楼 gouyanfen的回复:][quote=引用 7 楼 过程中的美好 的回复:] 各位大神能不能简单直白点呢 因为例子要把定义和赋值放到一句 你可以这样看*(*p2)=&p1; *可以理解为指向后面表达式值的空间 *p2为定义为指针变量变为他分配一个地址，返回这个地址，这个并不是设计**而是*号的嵌套使用 比如这个例子，你也可以这样定义     int v2=1;     int *p1=&v2;     int *p2=0;     p2=(int*)&p1;     printf("%X,%X,%d,%d",p2,p1,*(int*)*p2,*p1);   [/quote] FFA6421C, FFA64220,1,1[/quote] 这样和你说的意思就是其实*一个同样可以表达** **是一种简化的写法，你理解了指针，十个*都是一个道理 int *******point;也不是很难理解的

引用 8 楼 gouyanfen的回复:[quote=引用 7 楼 过程中的美好 的回复:] 各位大神能不能简单直白点呢 因为例子要把定义和赋值放到一句 你可以这样看*(*p2)=&p1; *可以理解为指向后面表达式值的空间 *p2为定义为指针变量变为他分配一个地址，返回这个地址，这个并不是设计**而是*号的嵌套使用 比如这个例子，你也可以这样定义     int v2=1;     int *p1=&v2;     int *p2=0;     p2=(int*)&p1;     printf("%X,%X,%d,%d",p2,p1,*(int*)*p2,*p1);   [/quote] FFA6421C, FFA64220,1,1

定义成哪样都不会算错，关键是使用上面，用**更方便 你要用二级指针访问int，怎么更方便？

引用 14 楼 WindyValley的回复:[quote=引用 10 楼 过程中的美好的回复:]其实我的理解是*只是代表这个申明的被声明对象是地址变量，*只是一个标示，并没有实际作用。打破这个观点，我就能理解了，谢谢 然后11楼gouyanfen想表达的意思，按我的想说的就是： 在实际使用指针的时候（也就是定义指针的那条语句之外的地方），*不再是说明符，而是叫做提领运算符，它的作用是根据操作数中存储的地址来读取内存然后返回到程序（作为运算符有返回值不奇怪吧），你定义指针的时候给的数据类型决定了它在读取内存时读多少个字节。比如bool型的指针在读取内存的时候就只读一个字节，因为bool变量就只占一个字节。但因为int型变量的字节数与指针变量的字节数是相同的，所以即使我进行了这样的操作： int var=0; int *p1=&var; int *p2=(int*)p1; cout<<*p2<<endl; 仍然可以输出p1的地址，因为按int的字节数读取内存的时候并没有丢失哪怕一个字节的数据（从数据存储的角度来讲，指针跟int型整数是等效的）。但这种把一级指针当二级指针用的操作，也就只有在int上有效，换了其他类型的数据，读取的字节数改变，就不行了。 （第三行使用强制类型转换，因为编译器认为一级指针的地址应该赋给二级指针，直接赋给p2会给出警告或编译错误）[/quote] 谢谢，我更理解了。。。

引用 10 楼 过程中的美好的回复:其实我的理解是*只是代表这个申明的被声明对象是地址变量，*只是一个标示，并没有实际作用。打破这个观点，我就能理解了，谢谢 然后11楼gouyanfen想表达的意思，按我的想说的就是： 在实际使用指针的时候（也就是定义指针的那条语句之外的地方），*不再是说明符，而是叫做提领运算符，它的作用是根据操作数中存储的地址来读取内存然后返回到程序（作为运算符有返回值不奇怪吧），你定义指针的时候给的数据类型决定了它在读取内存时读多少个字节。比如bool型的指针在读取内存的时候就只读一个字节，因为bool变量就只占一个字节。但因为int型变量的字节数与指针变量的字节数是相同的，所以即使我进行了这样的操作： int var=0; int *p1=&var; int *p2=(int*)p1; cout<<*p2<<endl; 仍然可以输出p1的地址，因为按int的字节数读取内存的时候并没有丢失哪怕一个字节的数据（从数据存储的角度来讲，指针跟int型整数是等效的）。但这种把一级指针当二级指针用的操作，也就只有在int上有效，换了其他类型的数据，读取的字节数改变，就不行了。 （第三行使用强制类型转换，因为编译器认为一级指针的地址应该赋给二级指针，直接赋给p2会给出警告或编译错误）

引用 10 楼 过程中的美好的回复:其实我的理解是*只是代表这个申明的被声明对象是地址变量，*只是一个标示，并没有实际作用。打破这个观点，我就能理解了，谢谢 *在定义指针变量的时候的确是说明符，用来说明定义的是指向某一类型变量的指针，而不是常规变量，这个类型就是*p前面的类型。 **ptr_2前面的**是说明这是一个二级指针，也就是说这个指针ptr_2所指向的变量本身就是一个一级指针（也就是指向非指针变量的指针），虽然编译器是“int  **ptr_2”这样去解析的（因为指针说明符*和引用说明符&都是要在定义变量的时候跟在变量名前面），但其实你可以这样去理解“int*     *ptr_2” 前面他们说的二维数组的说法是错的（虽然二级指针可以通过分配空间成为二维数组）

二维动态数组  int **p; p = new int*[num];  for(int i=0; i <num; ++i)  p[i] = new int[num2]; //  for(int m=0;m <num;m++)  delete[] p[m];  delete[] p;

引用 7 楼 过程中的美好 的回复:各位大神能不能简单直白点呢 因为例子要把定义和赋值放到一句 你可以这样看*(*p2)=&p1; *可以理解为指向后面表达式值的空间 *p2为定义为指针变量变为他分配一个地址，返回这个地址，这个并不是设计**而是*号的嵌套使用 比如这个例子，你也可以这样定义     int v2=1;     int *p1=&v2;     int *p2=0;     p2=(int*)&p1;     printf("%X,%X,%d,%d",p2,p1,*(int*)*p2,*p1);

各位大神能不能简单直白点呢🌝

呃，好吧~~我也不懂啊。  可能因为*point_1没有灵魂而不直接使用，**point_1有灵魂，就拿来使用了吧。。。

为什么要用“**”表示，而不直接用“*”，指针变量也是有地址的，请仔细看问题

1：用于表示二维数组。 2：作为函数参数传递 ，类似于c++的传引用& ~~  请楼下继续补充

引用 1 楼 user-7的回复:因为point_1要保存的是point_2的指针，而point_2本身就是指针； 因此使用**类型就很明显了：就是指向指针的指针。  举个实际例子：var代表你家的房子，301代表你家房号，如果你把房号的标签存在一个405号邮箱里，如果找到房间内容呢？  这里point_1 值为405， point_2为301，var为房间。 显然，你不懂我意思啊


Question: 求助，一段代码放在非主函数里会报错，但放在main里可以正常运行。。怎么回事

你要把l n m 的指针的地址传进去才行的啊，你传了个值，mian中的l n m 又不会改变的。  修改：  void LinkList_Organize(LinkList head, LinkList *l, LinkList *n, LinkList *m) { 	Node* q, * r, * s, * t, * p = head->next; 	*l = InitiateLinkList(); 	*n = InitiateLinkList(); 	*m = InitiateLinkList(); 	q = *l, r = *n, s = *m;  mian中修改： 	LinkList_Organize(head_a, &l, &n, &m);


Question: 【求助-链接属性】

类型声明而已，不会链接。

谈链接属性是不是针对变量而言的，而a不是变量呢，它其实已经变成了类型，是char的别名。

typedef char a; 不就等于 #define a char;

在哪里有讲过？快想起来告诉我


Question: c语言统计汉字

已经解决啦蟹蟹蟹蟹谢谢谢谢


Question: c语言代码错误不知道怎么改，求助各位大佬进来看看

函数调用与函数声明是有区别的，建议查一下这两者的区别。

你这语法哪里学得。。。 函数调用为啥要加返回值类型？ 函数调用的用法就是func()，你写的都是void func()

有些是编译器的问题，或许你可以把函数放在主函数前面

函数的定义在主函数（main）前面，定义时带上类型。 拿的CASE里面写的是调用函数，但是你这几个调用函数里面为啥在定义函数？ 我觉你是想调用而不是定义，调用函数没有数据类型。 函数的定义不能嵌套在函数中。

你这代码不全，只能说你是重新定义了一个不同的类型

我的函数名没有问题吧😂


Question: 不能换行

在你的IDE或编辑器的设置中找找 比如VS中的菜单上的工具->选项->文本编辑器->C/C++->自动换行 取消

引用 1 楼 user-1的回复:修改编辑器设置中的行的长度设定 以前都是设定为每行80个字符 其实现在没必要了 怎么修改呀？我是刚入门的，还请大神赐教

修改编辑器设置中的行的长度设定 以前都是设定为每行80个字符 其实现在没必要了


Question: 关于codeblocks生成exe文件无法运行，求解

你的codeblocks下载的版本可能跟你的windows不兼容，下一个64位的codeblocks试试？


Question: 西北角法表上作业法c/c++/java实现

或者是只有西北角法的一段代码也行，求求求大佬

只找到有关matlab和lingo的，没有c/java

有没有大佬啊？跪求


Question: PAT卖个萌

引用 1 楼 user-1 的回复:你是跟PAT杠上了啊~~~ 建议增强你的代码可读性，这样你自己调试起来方便，人家看起来也方便。 需要修改的地方在下面的代码中已标明。   #include <stdio.h> #include <stdlib.h>  int main() { 	int i = 0, j = 1, a[3]; 	char c; 	char s[3][11][5];//因为一个表情符合包括多个字符，所以要用字符串 	for (; i < 3; i++) 	{ 		j = 1; 		while ((c = getchar()) != '\n') 		{ 			if (c == '[') 			{ 				scanf("%[^]]", s[i][j++]); 			} 		} 		a[i] = --j; 	} 	int n, b[5];  	scanf("%d", &n); 	for (i = 0; i < n; i++) 	{ 		for (j = 0; j < 5; j++) 			scanf("%d", &b[j]);  		if (b[0] > a[0] || b[1] > a[1] || b[2] > a[2] || b[3] > a[1] || b[4] > a[0]) //这里考虑的是超出上界 			printf("Are you kidding me? @\\/@\n"); //<===== ‘ \ ’是转义符，所以需要加一个 		else if (b[0] < 1 || b[1] < 1 || b[2] < 1 || b[3] < 1 || b[4] < 1) //<=====所以还需要考虑超出下界的情况。 			printf("Are you kidding me? @\\/@\n"); 		else 			printf("%s(%s%s%s)%s\n", s[0][b[0]], s[1][b[1]], s[2][b[2]], s[1][b[3]], s[0][b[4]]); 	} } 十分感谢。因为是自学想考研，所以想增强代码能力多做点题，不过每次遇到这种输入特别多的题出现错误我都有点束手无策的感觉。其实你这样一解决我发现问题也不是很难，下次我自己多想想后再来发帖问吧。再次感谢老哥


Question: 素数相关

我也MARK一个。  #include<stdio.h> #include<stdbool.h> #include<stdlib.h> #include<time.h>  #define N 50  long long QuickPow(long long a,long long n,long long MOD){     long long ret=1,tmp=a%MOD;     while(n){         if(n&1) ret=ret*tmp%MOD;         tmp=tmp*tmp%MOD;         n>>=1;     }     return ret; }  bool Miller_Rabin(long long x, long long a) // a^(x-1) = 1 (mod x) {     long long tmx = x - 1;     long long s2 = tmx & -tmx;     long long res = QuickPow(a, tmx/s2, x);     if(res == 1 || res == tmx)         return 1;     while(s2>1)     {         res=(res*res)%x;         if(res == 1)             return 0;         if(res == tmx)             return 1;         s2>>=1;     }     return 0; }  bool IsPrime(long long x, int k) {     if(x == 2 || x == 3) return 1;     if(x < 2 || x%2 == 0 || x%3 == 0) return 0;     while(k--)         if(!Miller_Rabin(x, rand()%(x-2)+2))             return 0;     return 1; }  int main(){     long long m,n;     long long i;     long long sum=0;     int count=0;     int k;     srand(time(NULL));     scanf("%lld %lld", &m,&n);     if (m==1){         m=2;     }     for(i=m;i<=n;i++){         if(IsPrime(i, N)){             count++;             sum+=i;         }     }      printf("%d %lld",count,sum);     return 0; }


Question: c语言

-9在二维数组的第一行第一列，所以 i1 = 1; j1 = 1;

这个程序实质是查找一个二维数组中数字的位置。 在二维数组中a[1][1]=-9 所以i1是1，j1也是1，计算一下结果就是7


Question: 新手请多关照：有关printf的两个问题。

引用 4 楼 super_admi的回复:你真是太死板了。这些概念以及概念所包含的规则，只是出于某种需求人为规定的，如果你口里的物理学家和化学家因“有效数字”的概念而出现错误，那他们为什么还强行要使用这个概念？直接“保留X位小数”不是更好？ [quote=引用 2 楼 weixin_45358177 的回复:] [quote=引用 1 楼 Python_angew的回复:]有效数字为小数点后第一个不为零的数字开始计算的 啊，真是如此。谢谢你。但是 这对于物理学家和化学家其实是不对的。[/quote][/quote] 谢谢回复。不过你可能不知道有效数字除了保留小数（有时候根本轮不上小数位）外的重要意义。单说一个数的话可能不知道它是干什么的，而在实验中，由于测量不同物理量仪器可能精度不匹配，比如滴定管和普通托盘天平，比如分度值不同的电压表和电流表，不同有效位数的数据运算的结果保留几位有效数字，这时涉及多个数据，才能体现有效数字的重要意义。另外，如此不加声明的用一个已经要明确定义的科学名词是不合适的。而这至少在敝校（我觉得在其他很多地方也一样），只是高中这么一个初级阶段，都是被认为是概念混淆的。

你真是太死板了。这些概念以及概念所包含的规则，只是出于某种需求人为规定的，如果你口里的物理学家和化学家因“有效数字”的概念而出现错误，那他们为什么还强行要使用这个概念？直接“保留X位小数”不是更好？ 引用 2 楼 weixin_45358177 的回复:[quote=引用 1 楼 Python_angew的回复:]有效数字为小数点后第一个不为零的数字开始计算的 啊，真是如此。谢谢你。但是 这对于物理学家和化学家其实是不对的。[/quote]

关于这样的问题， 最好直接找到C99的官方叙述。

引用 1 楼 Python_angew的回复:有效数字为小数点后第一个不为零的数字开始计算的 啊，真是如此。谢谢你。但是 这对于物理学家和化学家其实是不对的。

有效数字为小数点后第一个不为零的数字开始计算的


Question: C语言开发能做数码相机?

数码相机类开发属于影像编解码类产品。 肯定是需要你具备影像处理， 编解码等知识储备， 甚至有可能要求你有运用DSP或者ASIC等相关技术。 这些都需要用C语言作为基础。 不是C语言能做什么， 而是作为基本使用的工具.

1.外设驱动； 2.内置算法。


Question: 模拟计算器，求大佬带

明天就要交了，慌的一批

不会写矩阵运算

实现二维数组功能就是说这个是要用矩阵乘法吗？


Question: 我这个关于职工管理系统文件编译好像有问题，求解答，我运行代码连接好像有问题

希望对你有帮助：https://blog.csdn.net/it_xiangqiang/category_10581430.html 希望对你有帮助：https://blog.csdn.net/it_xiangqiang/category_10768339.html

？什么东西提到了我？

那肯定了，除非你特别厉害

引用 10 楼 main(进击的菜鸟)的回复:[quote=引用 9 楼 九华山小和尚 的回复:] [quote=引用 8 楼 main(进击的菜鸟)的回复:]最好功能逐个实现，从最基础的开始，其他的先注释掉，这种项目不要急于写一大堆 这个项目我感觉不是很大，那样慢慢写太浪费时间了[/quote] 但是一旦出错就就像你这样子[/quote] 以后写大的程序都是一个一个功能慢慢实现吗

引用 9 楼 九华山小和尚 的回复:[quote=引用 8 楼 main(进击的菜鸟)的回复:]最好功能逐个实现，从最基础的开始，其他的先注释掉，这种项目不要急于写一大堆 这个项目我感觉不是很大，那样慢慢写太浪费时间了[/quote] 但是一旦出错就就像你这样子

引用 8 楼 main(进击的菜鸟)的回复:最好功能逐个实现，从最基础的开始，其他的先注释掉，这种项目不要急于写一大堆 这个项目我感觉不是很大，那样慢慢写太浪费时间了

最好功能逐个实现，从最基础的开始，其他的先注释掉，这种项目不要急于写一大堆

引用 3 楼 636f6c696e的回复:编译问题90%百度就能解决了，就算论坛上问也贴下编译错误内容啊 好的，等下我来贴一下

编译问题90%百度就能解决了，就算论坛上问也贴下编译错误内容啊

引用 6 楼 慕思暗的回复:包教包会不急不急   不急 what?你说什么，没看懂

引用 1 楼 自信男孩 的回复:这么长的代码，建议通过注释部分功能，然后再逐步放开部分功能，一次来查找问题出在哪个功能函数里，这样也比较容易解决问题我明天试试，没什么经验，我不知道是不是文件那里用错了


Question: 萌新问下if嵌套结构的问题

不合格哈哈  v哈哈v

已经知道了，等号应该是d==0，判别要两个等号，没注意

求大佬们帮忙


Question: C语言迷宫问题

回溯，简单点可以用深度优先，广度优先。相对稍微复杂点点的用A*，都很简单的

这不就是一个典型的回溯算法？


Question: 还是关于return的问题。

引用 4 楼 weixin_45358177的回复:[quote=引用 3 楼 user-2的回复:]return 返回数据而已，你可以接收，也可以不接受，你定义的是int,但是你没有返回int,你自己看编译的输出结果里面是不是有警告 是有警告。但是我还是没有理解为什么有的时候没有return结果就不对；还有M，N是全局变量的时候 ，没写return就没有影响？[/quote] 你定义函数时给了函数是什么类型的就要return返回什么类型的数据，return也可以用于结束此段代码执行

你换一个编译器你的代码会报错，编译不过。你自己定义的函数类型都有一个int要返回，但是你没有返回，这个是你自己写错了

引用 3 楼 user-2的回复:return 返回数据而已，你可以接收，也可以不接受，你定义的是int,但是你没有返回int,你自己看编译的输出结果里面是不是有警告 是有警告。但是我还是没有理解为什么有的时候没有return结果就不对；还有M，N是全局变量的时候 ，没写return就没有影响？

引用 1 楼 user-2的回复:你的m,n是全局变量 那么return的作用到底是什么呢？是储存一个结果的作用吗？

你的m,n是全局变量


Question: 关于Return的问题。

引用 13 楼 weixin_45358177的回复:[quote=引用 12 楼 ggglivw的回复:]add (int Long,int Width) 没有return 嗯，我知道自己没打return，我是在去掉return的条件下看它有什么作用。说概念的话我知道它是返回，也知道它可以接受也可以不接受，但对于不打return出来的奇怪结果我想知道系统是怎么运行的。 还有return 在运行过程中对最后的结果有什么作用。[/quote] iResult=add(m_Long,m_Width);这句话就不成立，add没有返回值，你还定义变量来接受它，岂不是矛盾。

代码贴出来.

引用 21 楼 636f6c696e的回复:原来以为这样的程序编译不过的，但在gcc上试了下居然还真能编过，所以顺带分析了下 (gdb) disassemble  add Dump of assembler code for function add:    0x0000000000400674 <+0>:     push   %rbp    0x0000000000400675 <+1>:     mov    %rsp,%rbp    0x0000000000400678 <+4>:     sub    $0x20,%rsp    0x000000000040067c <+8>:     mov    %edi,-0x14(%rbp)    0x000000000040067f <+11>:    mov    %esi,-0x18(%rbp)    0x0000000000400682 <+14>:    mov    -0x14(%rbp),%eax    0x0000000000400685 <+17>:    mov    %eax,%edx    0x0000000000400687 <+19>:    imul   -0x18(%rbp),%edx    0x000000000040068b <+23>:    mov    %edx,%eax    0x000000000040068d <+25>:    shl    $0x2,%eax    0x0000000000400690 <+28>:    add    %edx,%eax    0x0000000000400692 <+30>:    add    %eax,%eax    0x0000000000400694 <+32>:    mov    %eax,-0x4(%rbp)    0x0000000000400697 <+35>:    mov    -0x4(%rbp),%esi    0x000000000040069a <+38>:    mov    $0x4007e5,%edi    0x000000000040069f <+43>:    mov    $0x0,%eax    0x00000000004006a4 <+48>:    callq  0x4004e0 <printf@plt>    0x00000000004006a9 <+53>:    leaveq     0x00000000004006aa <+54>:    retq   简单解释下，函数的返回值都是保存在寄存器eax上的，我们可以看到add函数在return之前， 先将寄存器eax赋值为0：mov    $0x0,%eax 然后再调用printf函数：callq  0x4004e0 <printf@plt> 之后就返回了：leaveq 、retq 因此返回值实质上就是printf的返回值。  可能很多人不知道prinf这个函数是有返回值的，返回值代表实际输出字符的长度。 printf("长方体的体积为：%d\n"， iResult); 中“长方体的体积为：”都是中文字符，每个2个字节，一共是16字节。 %d是体积，如果输入是1 2，体积是20，那么就是2个字节，再加上\n 1个字节，加起来就是19字节，所以输出是19. 如果你输入的是1 10，那么体积是100，输出则会是20。  不过说了那么多，这些东西对初学者并无实际的意义。正确的做法是显示指定返回值，知道这点就够了。 [quote=引用 13 楼 weixin_45358177 的回复:] [quote=引用 12 楼 ggglivw的回复:]add (int Long,int Width) 没有return 嗯，我知道自己没打return，我是在去掉return的条件下看它有什么作用。说概念的话我知道它是返回，也知道它可以接受也可以不接受，但对于不打return出来的奇怪结果我想知道系统是怎么运行的。 还有return 在运行过程中对最后的结果有什么作用。[/quote][/quote] 因为我们 高中物理化学学的有效数字 是从左边第一个不为零的数字开始算。所以我们是区分有效数字几位和小数点后几位（从小数点后第一位开始算，不同于 有效数字的概念）这两个概念的。但我最近感觉 有关资料上认为这两个概念是等价的。

引用 21 楼 636f6c696e的回复:原来以为这样的程序编译不过的，但在gcc上试了下居然还真能编过，所以顺带分析了下 (gdb) disassemble  add Dump of assembler code for function add:    0x0000000000400674 <+0>:     push   %rbp    0x0000000000400675 <+1>:     mov    %rsp,%rbp    0x0000000000400678 <+4>:     sub    $0x20,%rsp    0x000000000040067c <+8>:     mov    %edi,-0x14(%rbp)    0x000000000040067f <+11>:    mov    %esi,-0x18(%rbp)    0x0000000000400682 <+14>:    mov    -0x14(%rbp),%eax    0x0000000000400685 <+17>:    mov    %eax,%edx    0x0000000000400687 <+19>:    imul   -0x18(%rbp),%edx    0x000000000040068b <+23>:    mov    %edx,%eax    0x000000000040068d <+25>:    shl    $0x2,%eax    0x0000000000400690 <+28>:    add    %edx,%eax    0x0000000000400692 <+30>:    add    %eax,%eax    0x0000000000400694 <+32>:    mov    %eax,-0x4(%rbp)    0x0000000000400697 <+35>:    mov    -0x4(%rbp),%esi    0x000000000040069a <+38>:    mov    $0x4007e5,%edi    0x000000000040069f <+43>:    mov    $0x0,%eax    0x00000000004006a4 <+48>:    callq  0x4004e0 <printf@plt>    0x00000000004006a9 <+53>:    leaveq     0x00000000004006aa <+54>:    retq   简单解释下，函数的返回值都是保存在寄存器eax上的，我们可以看到add函数在return之前， 先将寄存器eax赋值为0：mov    $0x0,%eax 然后再调用printf函数：callq  0x4004e0 <printf@plt> 之后就返回了：leaveq 、retq 因此返回值实质上就是printf的返回值。  可能很多人不知道prinf这个函数是有返回值的，返回值代表实际输出字符的长度。 printf("长方体的体积为：%d\n"， iResult); 中“长方体的体积为：”都是中文字符，每个2个字节，一共是16字节。 %d是体积，如果输入是1 2，体积是20，那么就是2个字节，再加上\n 1个字节，加起来就是19字节，所以输出是19. 如果你输入的是1 10，那么体积是100，输出则会是20。  不过说了那么多，这些东西对初学者并无实际的意义。正确的做法是显示指定返回值，知道这点就够了。 [quote=引用 13 楼 weixin_45358177 的回复:] [quote=引用 12 楼 ggglivw的回复:]add (int Long,int Width) 没有return 嗯，我知道自己没打return，我是在去掉return的条件下看它有什么作用。说概念的话我知道它是返回，也知道它可以接受也可以不接受，但对于不打return出来的奇怪结果我想知道系统是怎么运行的。 还有return 在运行过程中对最后的结果有什么作用。[/quote][/quote] 分数用完了，好像不能发帖提问了。所以这里问一下吧：一般说的float和double有效数字6位和15位是指小数点后的6位和15位吧？

引用 21 楼 636f6c696e的回复:原来以为这样的程序编译不过的，但在gcc上试了下居然还真能编过，所以顺带分析了下 (gdb) disassemble  add Dump of assembler code for function add:    0x0000000000400674 <+0>:     push   %rbp    0x0000000000400675 <+1>:     mov    %rsp,%rbp    0x0000000000400678 <+4>:     sub    $0x20,%rsp    0x000000000040067c <+8>:     mov    %edi,-0x14(%rbp)    0x000000000040067f <+11>:    mov    %esi,-0x18(%rbp)    0x0000000000400682 <+14>:    mov    -0x14(%rbp),%eax    0x0000000000400685 <+17>:    mov    %eax,%edx    0x0000000000400687 <+19>:    imul   -0x18(%rbp),%edx    0x000000000040068b <+23>:    mov    %edx,%eax    0x000000000040068d <+25>:    shl    $0x2,%eax    0x0000000000400690 <+28>:    add    %edx,%eax    0x0000000000400692 <+30>:    add    %eax,%eax    0x0000000000400694 <+32>:    mov    %eax,-0x4(%rbp)    0x0000000000400697 <+35>:    mov    -0x4(%rbp),%esi    0x000000000040069a <+38>:    mov    $0x4007e5,%edi    0x000000000040069f <+43>:    mov    $0x0,%eax    0x00000000004006a4 <+48>:    callq  0x4004e0 <printf@plt>    0x00000000004006a9 <+53>:    leaveq     0x00000000004006aa <+54>:    retq   简单解释下，函数的返回值都是保存在寄存器eax上的，我们可以看到add函数在return之前， 先将寄存器eax赋值为0：mov    $0x0,%eax 然后再调用printf函数：callq  0x4004e0 <printf@plt> 之后就返回了：leaveq 、retq 因此返回值实质上就是printf的返回值。  可能很多人不知道prinf这个函数是有返回值的，返回值代表实际输出字符的长度。 printf("长方体的体积为：%d\n"， iResult); 中“长方体的体积为：”都是中文字符，每个2个字节，一共是16字节。 %d是体积，如果输入是1 2，体积是20，那么就是2个字节，再加上\n 1个字节，加起来就是19字节，所以输出是19. 如果你输入的是1 10，那么体积是100，输出则会是20。  不过说了那么多，这些东西对初学者并无实际的意义。正确的做法是显示指定返回值，知道这点就够了。 [quote=引用 13 楼 weixin_45358177 的回复:] [quote=引用 12 楼 ggglivw的回复:]add (int Long,int Width) 没有return 嗯，我知道自己没打return，我是在去掉return的条件下看它有什么作用。说概念的话我知道它是返回，也知道它可以接受也可以不接受，但对于不打return出来的奇怪结果我想知道系统是怎么运行的。 还有return 在运行过程中对最后的结果有什么作用。[/quote][/quote] 谢谢你的分析和解释，现在知道结果异常的原因了。

原来以为这样的程序编译不过的，但在gcc上试了下居然还真能编过，所以顺带分析了下 (gdb) disassemble  add Dump of assembler code for function add:    0x0000000000400674 <+0>:     push   %rbp    0x0000000000400675 <+1>:     mov    %rsp,%rbp    0x0000000000400678 <+4>:     sub    $0x20,%rsp    0x000000000040067c <+8>:     mov    %edi,-0x14(%rbp)    0x000000000040067f <+11>:    mov    %esi,-0x18(%rbp)    0x0000000000400682 <+14>:    mov    -0x14(%rbp),%eax    0x0000000000400685 <+17>:    mov    %eax,%edx    0x0000000000400687 <+19>:    imul   -0x18(%rbp),%edx    0x000000000040068b <+23>:    mov    %edx,%eax    0x000000000040068d <+25>:    shl    $0x2,%eax    0x0000000000400690 <+28>:    add    %edx,%eax    0x0000000000400692 <+30>:    add    %eax,%eax    0x0000000000400694 <+32>:    mov    %eax,-0x4(%rbp)    0x0000000000400697 <+35>:    mov    -0x4(%rbp),%esi    0x000000000040069a <+38>:    mov    $0x4007e5,%edi    0x000000000040069f <+43>:    mov    $0x0,%eax    0x00000000004006a4 <+48>:    callq  0x4004e0 <printf@plt>    0x00000000004006a9 <+53>:    leaveq     0x00000000004006aa <+54>:    retq   简单解释下，函数的返回值都是保存在寄存器eax上的，我们可以看到add函数在return之前， 先将寄存器eax赋值为0：mov    $0x0,%eax 然后再调用printf函数：callq  0x4004e0 <printf@plt> 之后就返回了：leaveq 、retq 因此返回值实质上就是printf的返回值。  可能很多人不知道prinf这个函数是有返回值的，返回值代表实际输出字符的长度。 printf("长方体的体积为：%d\n"， iResult); 中“长方体的体积为：”都是中文字符，每个2个字节，一共是16字节。 %d是体积，如果输入是1 2，体积是20，那么就是2个字节，再加上\n 1个字节，加起来就是19字节，所以输出是19. 如果你输入的是1 10，那么体积是100，输出则会是20。  不过说了那么多，这些东西对初学者并无实际的意义。正确的做法是显示指定返回值，知道这点就够了。 引用 13 楼 weixin_45358177 的回复:[quote=引用 12 楼 ggglivw的回复:]add (int Long,int Width) 没有return 嗯，我知道自己没打return，我是在去掉return的条件下看它有什么作用。说概念的话我知道它是返回，也知道它可以接受也可以不接受，但对于不打return出来的奇怪结果我想知道系统是怎么运行的。 还有return 在运行过程中对最后的结果有什么作用。[/quote]

现在编程越来越傻瓜式了，居然这么写也是符合语法规则的

引用 19 楼 WNs_ACE的回复:补充一下，每个函数结束的时候，不管有没有return，都会调用ret指令（有时候会使用jmp或者其他跳转指令和push指令配合使用达到ret指令的效果，具体可能需要看具体的编译器来定，没有办法一概而论） 谢谢！实在没有别的感激的话了。

你这个程序可能只能在高版本的vs上面编译了，低版本的vs都可以编译不了，而你要理解一个东西，return在汇编其实就是ret，而ret指令的作用就是出栈和把栈顶地址交给EIP寄存器，然后把EAX寄存器的东西作为函数返回值赋值给iResult变量，其实你上面的程序不管你写不写return，最后都会把EXA寄存器的东西交给iResult变量，至于EAX寄存器到底放什么的数据，就要看编译器编译出来的汇编逻辑来决定了，所以你看到的“少1的普遍规律”可能只是运气和编译器版本导致的，想要了解语法的底层，你最好还是去看汇编指令才容易明白。

语法规定的，你应该返回，你不返回编译器通过后会产生啥后果你只有去看编译器的实现了。这种在古老的编译器上是无法通过编译的

引用 12 楼 ggglivw的回复:add (int Long,int Width) 没有return 嗯，我知道自己没打return，我是在去掉return的条件下看它有什么作用。说概念的话我知道它是返回，也知道它可以接受也可以不接受，但对于不打return出来的奇怪结果我想知道系统是怎么运行的。 还有return 在运行过程中对最后的结果有什么作用。

add (int Long,int Width) 没有return

引用 6 楼 ggglivw 的回复:你准备让我手敲你代码给你分析？我无偿给你回答问题还要自己手敲，你觉得谁会这么干. 谢谢啦，不是贴的，教室没网，到老师办公室敲得。 这个add（）没有return。 #include<stdio.h> #include<stdlib.h> #define Height 10  int add(int Long,int Width); int main() { int m_Long; int m_Width; int iResult; printf(“请输入长方体的长：”）； scanf("%d",&m_Long); printf("请输入长方体的宽："); scanf("%d",&m_Width); iResult=add(m_Long,m_Width); printf("长方体的体积为：%d\n",iResult); system("pause"); } add (int Long,int Width) { int iResult=Long*Width*Height; printf("长方体的体积为：%d"iResult); }

引用 9 楼 轻箬笠的回复:[quote=引用 8 楼 weixin_45358177 的回复:] [quote=引用 6 楼 ggglivw的回复:]你准备让我手敲你代码给你分析？我无偿给你回答问题还要自己手敲，你觉得谁会这么干. 前辈，“代码贴出来”的意思是敲到这个论坛里吗？对不起，新人不太了解了 。我觉得自己已经拍下来了呀。[/quote] 程序不跑一下，有些问题查不出来。那怎么跑呢？你是拍下了，回答问题的人是对着照片再写一遍代码，还是有软件可以让回答问题的人自动识别照片里面的代码？[/quote] 谢谢你，        明白了。

引用 8 楼 weixin_45358177 的回复:[quote=引用 6 楼 ggglivw的回复:]你准备让我手敲你代码给你分析？我无偿给你回答问题还要自己手敲，你觉得谁会这么干. 前辈，“代码贴出来”的意思是敲到这个论坛里吗？对不起，新人不太了解了 。我觉得自己已经拍下来了呀。[/quote] 程序不跑一下，有些问题查不出来。那怎么跑呢？你是拍下了，回答问题的人是对着照片再写一遍代码，还是有软件可以让回答问题的人自动识别照片里面的代码？

引用 6 楼 ggglivw的回复:你准备让我手敲你代码给你分析？我无偿给你回答问题还要自己手敲，你觉得谁会这么干. 前辈，“代码贴出来”的意思是敲到这个论坛里吗？对不起，新人不太了解了 。我觉得自己已经拍下来了呀。

自己看3楼的回答，他已经说清楚原因了，编译器版本的设置不同，某些错误会给你报警告，本来你应该是编译不过的，结果弄了一个警告出来。

引用 2 楼 ggglivw的回复:代码贴出来. 前辈，照片上的不算代码吗？


Question: 为什么是一次都不执行？

这个程序应该是输出无数个-1

对于判断是否相等的逻辑表达式， 在coding的时候， 建议尽量将常量或者表达式的返回放在左侧， 这样一旦漏写了一个等号， 编译器会告诉你这个错误。 如以下可写成： int main() { int k=0;    while(0 == k) { k=k-1; printf ("%d",k); } return 0;

恩，搞错了赋值0就直接跳出了

错了哦，while(k=0) 一次都不会执行哦 引用 2 楼 冢中枯骨 的回复:这个程序应该是输出无数个-1

while(k=0) -> 1. 判断k=0表达式的结果 2.k=0表达式的结果为k的值 3. k的值被赋值为0 4. 0表示假 5. 一次都不执行循环

一个＝是赋值操作，两个＝才是相等

我建议你可以看看程序编译后的汇编和OD调试一下程序，你就应该会明白了，要看while编译成汇编的时候变成什么的跳转指令，根据不同的跳转指令和标志寄存器来决定是否进入while的循环，而k=0本身是不修改标志寄存器的，如果像你上面写的程序的话，标志寄存器应该都是默认为0，跳转指令根据标志寄存器的值就会自动跳过while结构体循环了。

我想你是想要k == 0作为while语句的条件吧


Question: C语言：关于%c,只能打印一个，为什么加了while，就可以打印出来全部，

其实只要你后面输入的ch≠'g'你就会一直处于while循环中，当然可以多次读取并打印你每次输入的ch值了

在每个最后不带\n的printf后面加fflush(stdout); 在每个不想受接收缓冲区旧内容影响的scanf前面加rewind(stdin); 另外请检查scanf的返回值。 //请今后要用 char c; scanf("%c",&c); //时，都改为 char s[2]; char c; scanf("%1s",s); c=s[0]; //自动跳过一个或多个空格或Tab字符或回车换行，读取下一个字符。

引用 3 楼 轻箬笠 的回复:我错了 挨个打印是因为你的输入流没读完，所以每次scanf("%c",&ch);都能读到一个字符。  引用 6 楼 轻箬笠 的回复:可以看下这篇文章https://blog.csdn.net/xlost_sl/article/details/46432377 开始在缓冲区读取字符，当它读完第一个字符后释放了那个字符所占的内存看过了，大概意思是内存缓冲区的值会一直在，用字符就会去掉一个，下面的第二个字符就变成第一个了，直到！=  这个值有效g就结束。

引用 6 楼 轻箬笠的回复:可以看下这篇文章https://blog.csdn.net/xlost_sl/article/details/46432377 开始在缓冲区读取字符，当它读完第一个字符后释放了那个字符所占的内存 好的，我会看的，谢谢

引用 7 楼 ggglivw的回复:char ch;     scanf("%c",&ch); 只能读取一个char 你这个和我的想法不挨着

char ch;     scanf("%c",&ch); 只能读取一个char

引用 3 楼 轻箬笠 的回复:我错了 挨个打印是因为你的输入流没读完，所以每次scanf("%c",&ch);都能读到一个字符。既然可以读到，为什么可以顺着读下去，而不是只读第一个？我现在是初入门，之前学的是%c,只能读一个，也就是一个字符串的第一个字符。

引用 2 楼 轻箬笠 的回复:int main(void) {     char ch;     scanf("%c",&ch);     while (ch++!='g')     {        printf("%c",ch);     }     return 0;  } 挨个打印，你得让ch++目前不加也可以打印直到碰倒限制的g

主要不明白ch !='g'这一块的运行结果对字符是怎么就能挨个打印了？


Question: 情况是这样的，我写了个控制台程序，用Shell_NotifyIcon给程序加了个托盘区图标，现在想实现右键托盘图标弹出菜单，应该怎么做呢

上面是自己想在控制台下写一个隐藏的窗口来获取消息，从而激活托盘图标能够响应右键可以弹出图标，这里我把创建这个隐藏的子窗口写在另一个线程里，在控制台主线程过程中运行，可是没有效果，是哪里不对吗（这里创建的是控制台程序，所以用了GetModuleHandle获取当前实例句柄），另外nif是前面定义好的NIF托盘结构体。跪求解答  或者不用这样，只要能有在控制台下可以右键我创建好的托盘图标弹出菜单的方法也可以。成功解决问题可以追加分数

HMENU hMenu; HWND hWnd1; LRESULT CALLBACK    WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) { 	switch (message)      {    	case WM_NOTIFYICON: 		{ 			switch(lParam) 	        case WM_RBUTTONDOWN: 			{ 				POINT pt; 				GetCursorPos(&pt); 				hMenu= CreatePopupMenu(); 				AppendMenu(hMenu,MF_STRING,IDM_GOBACK,L"回到主菜单"); 				AppendMenu(hMenu, MF_SEPARATOR, 0, NULL); 	         AppendMenu(hMenu,MF_STRING,IDM_HELP,L"帮助"); 			 AppendMenu(hMenu, MF_SEPARATOR, 0, NULL); 	         AppendMenu(hMenu,MF_STRING,IDM_EXIT,L"退出游戏"); 			 AppendMenu(hMenu,MF_SEPARATOR,0,NULL); 			 TrackPopupMenu(hMenu, TPM_RIGHTBUTTON,  pt.x, pt.y, NULL, hwnd, NULL); 			}break; 		} 		break;      case WM_DESTROY:          PostQuitMessage(0);          break;      default:          return DefWindowProc(hwnd, message, wParam, lParam);      }      return 0; } unsigned int _stdcall THREAD(void *lpParam) { 	nif.cbSize=sizeof(nif); 	nif.hWnd=hWnd; 	nif.uID=600; 	nif.uFlags=NIF_ICON|NIF_MESSAGE|NIF_TIP; 	nif.szTip[0]=L'提'; 	nif.szTip[1]=L'示'; 	nif.hIcon=(HICON)LoadImage(NULL, _T("resource\\1.ICO"), IMAGE_ICON, 32, 32, LR_LOADFROMFILE);  	nif.dwState=NIS_SHAREDICON; 	nif.uCallbackMessage= WM_NOTIFYICON; 	Shell_NotifyIcon(NIM_ADD,&nif); 	HINSTANCE hInstance = ::GetModuleHandle(NULL); 	WNDCLASSEXW wcex;     wcex.cbSize = sizeof(WNDCLASSEX);  wcex.style   = CS_HREDRAW | CS_VREDRAW;  wcex.lpfnWndProc = WndProc;  wcex.cbClsExtra  = 0;  wcex.cbWndExtra  = 0;  wcex.hInstance  = hInstance;  wcex.hIcon   = NULL;  wcex.hCursor  = LoadCursor(NULL, IDC_ARROW);  wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);  wcex.lpszMenuName = NULL;//MAKEINTRESOURCE(IDC_XEYE);  wcex.lpszClassName = L"EW";  wcex.hIconSm  = NULL;  RegisterClassEx(&wcex);      hWnd1=CreateWindowEx(WS_EX_NOACTIVATE, // 该参数保证该窗口永不被激活    L"EW", L"title",    WS_POPUP,    0, 0, 10, 10,    NULL, NULL, 0, NULL) ; 	  MSG msg;    // 主消息循环:        while (GetMessage(&msg, nullptr, 0, 0))       {           TranslateMessage(&msg);           DispatchMessage(&msg);       }        return msg.wParam;    }


Question: 麻烦帮忙解答一下图片上的题，谢谢

是要好好看看书了，谢谢你的解答:)

学了一学期都搞不定，该好好看书了  #include <stdio.h>  float sum = 0, max = 0 ; int cnt = 0, failCnt = 0 ; void Score(float score) { 	sum += score ; 	cnt += 1 ; }  void MaxScore(float score) { 	if(max < score) 		max = score ; }  void GetFailCnt(float score) { 	if(score < 60) 		failCnt += 1 ; }  int main()  { 	float score = 0 ; 	while(1) 	{ 		scanf("%f", &score) ; 		if(score < 0)	//输入负数停止 			break ;  		Score(score) ; 		MaxScore(score) ; 		GetFailCnt(score) ; 	} 	 	printf("总分：%f\n平均分：%f\n最高分：%f\n不及格人数：%d\n",  		sum, sum/cnt, max, failCnt) ;  	return 0;  }


Question: 新手求助，为什么运行到登录函数 输入用户名程序就会死掉

这个问题你自己看下堆栈，编译器其实已经告诉你答案了，超大概率是2楼说的，空指针问题。C系列的语言，指针操作前一定判断NULL，越界。

检查你的D盘是否有你要读取的这个文件：information.txt


Question: 系统开发

下面代码是百度的。 #include"stdio.h" #include"stdlib.h" #include"string.h" #define N 3 typedef struct z1 { char no[11]; char name[15]; int score[N]; float sum; float average; int order; struct z1 *next; }STUDENT; STUDENT *init(); STUDENT *create(); STUDENT *del(STUDENT *h); void print(STUDENT *h); void search1(STUDENT *h); void search2(STUDENT *h); STUDENT *insert(STUDENT *h); void sort(STUDENT *h); void save(STUDENT *h); void tongji(STUDENT *h); int menu_select(); STUDENT *load(); void inputs(char *prompt,char *s,int count); STUDENT *load(); main() { int i; STUDENT *head; head=init(); for(;;) { switch(menu_select()) { case 0:head=init();break; case 1:head=create();break; case 2:head=insert(head);break; case 3:save(head);break; case 4:print(head);break; case 5:search1(head);break; case 6:head=del(head);break; case 7:sort(head);break; case 8:tongji(head);break; case 9:search2(head);break; case 10:exit(0); } } } int menu_select() { char *menu[]={"************菜单************", "0. 初始化链表", "1. 输入学生成绩", "2. 插入学生成绩", "3. 保存学生记录", "4. 显示学生记录", "5. 按学号查找学生信息", "6. 删除指定学号的学生信息", "7. 按某一门课对学生成绩排序", "8. 统计某门课程的学生成绩", "9. 按姓名查找学生信息", "10. 退出系统"}; char s[3]; int c,i; for(i=0;i<=11;i++) printf(" %s\n",menu[i]); do { printf("\n请选择0~10中的某一个选项\n"); scanf("%s",s); c=atoi(s); }while(c<0||c>10); return c; } STUDENT *init() { return NULL; } STUDENT *create() { int i;int s; STUDENT *h=NULL,*info; for(;;) { info=(STUDENT *)malloc(sizeof(STUDENT)); if(!info) { printf("\n内存不足"); return NULL; } inputs("输入学号:",info->no,11); if(info->no[0]=='@')break; inputs("输入姓名:",info->name,15); printf("开始输入%d门课的成绩\n",N); s=0; for(i=0;i<N;i++) { do{ printf("第%d门分数:",i+1); scanf("%d",&info->score[i]); if(info->score[i]>100||info->score[i]<0) printf("输入成绩错误，请重新输入:\n"); }while(info->score[i]>100||info->score[i]<0); s=s+info->score[i]; } info->sum=s; info->average=(float)s/N; info->order=0; info->next=h; h=info; } return h; } void inputs(char *prompt,char *s,int count) { char p[255]; do { printf(prompt); scanf("%s",p); if(strlen(p)>count) printf("\n太长了!\n"); }while(strlen(p)>count); strcpy(s,p); } void print(STUDENT *h) { int i=0; STUDENT *p; p=h; printf("\n\n\n***********************学生***********************\n"); printf("|序号|学号 | 姓名 | 语文 | 英语 |数学 | 总分 |平均分 |名次 |\n"); printf("|---|-------|--------|----|----|----|------|------|---|\n"); while(p!=NULL) { i++; printf("|%3d |%-10s|%-8s|%4d|%4d|%4d|%4.2f|%4.2f|%3d|\n",i,p->no,p->name,p->score[0],p->score[1],p->score[2],p->sum,p->average,p->order); p=p->next; } printf("***********************end***********************\n"); } STUDENT *del(STUDENT *h) { STUDENT *p,*q; char s[11]; printf("请输入要删除的学生的学号\n"); scanf("%s",s); q=p=h; while(strcmp(p->no,s)&&p!=NULL) { q=p; p=p->next; } if(p==NULL) printf("\n链表中没有学号为%s的学生\n",s); else { printf("\n\n\n***********************找到了***********************\n"); printf("|学号 | 姓名 | 语文 | 英语 | 数学 | 总分 | 平均分 | 名次 |\n"); printf("|----------|----------|----|----|----|------|------|---|\n"); printf("|%-10s|%-8s|%4d|%4d|%4d|%4.2f|%4.2f|%3d|\n",p->no,p->name,p->score[0],p->score[1],p->score[2],p->sum,p->average,p->order); printf("***********************end***********************\n"); printf("请按任意键删除\n"); getchar(); if(p==h) h=p->next; else q->next=p->next; free(p); printf("\n已经删除学号为%s的学生\n",s); printf("不要忘了保存数据\n"); } return h; } void search1(STUDENT *h) { STUDENT *p; char s[11]; printf("请输入你要查找的同学的学号\n"); scanf("%s",s); p=h; while(strcmp(p->no,s)&&p!=NULL) p=p->next; if(p==NULL) printf("'n没有学号为%s的学生\n",s); else { printf("\n\n\n***********************找到了***********************\n"); printf("|学号 | 姓名 | 语文 | 英语 | 数学 | 总分 | 平均分 | 名次 |\n"); printf("|----------|-----------|----|----|----|------|------|---|\n"); printf("|%-10s|%-8s|%4d|%4d|%4d|%4.2f|%4.2f|%3d|\n",p->no,p->name,p->score[0],p->score[1],p->score[2],p->sum,p->average,p->order); printf("***********************end***********************\n"); } } void search2(STUDENT *h) { STUDENT *p; char s[11]; printf("请输入你要查找的同学的姓名\n"); scanf("%s",s); p=h; while(strcmp(p->name,s)&&p!=NULL) p=p->next; if(p==NULL) printf("\n没有姓名为%s的学生\n",s); else { printf("\n\n\n***********************找到了***********************\n"); printf("|学号 | 姓名 | 语文 | 英语 | 数学 | 总分 | 平均分 | 名次 |\n"); printf("|----------|-----------|----|----|----|------|------|---|\n"); printf("|%-10s|%-8s|%4d|%4d|%4d|%4.2f|%4.2f|%3d|\n",p->no,p->name,p->score[0],p->score[1],p->score[2],p->sum,p->average,p->order); printf("***********************end***********************\n"); } } STUDENT *insert(STUDENT *h) { STUDENT *p,*q,*info; char s[11]; int s1,i; printf("请输入插入点的学生学号\n"); scanf("%s",s); printf("\n请输入新的学生信息\n"); info=(STUDENT *)malloc(sizeof(STUDENT)); if(!info) { printf("\n内存不足!"); return NULL; } inputs("输入学号:",info->no,11); inputs("输入姓名:",info->name,15); printf("请输入%d门课的分数\n",N); s1=0; for(i=0;i<N;i++) { do{ printf("分数%d",i+1); scanf("%d",&info->score[i]); if(info->score[i]>100||info->score[i]<0) printf("输入数据有误，请重新输入\n"); }while(info->score[i]>100||info->score[i]<0); s1=s1+info->score[i]; } info->sum=s1; info->average=(float)s1/N; info->order=0; info->next=NULL; p=h; q=h; while(strcmp(p->no,s)&&p!=NULL) {q=p;p=p->next;} if(p==NULL) if(p==h) h=info; else q->next=info; else if(p==h) { info->next=p; h=info; } else { info->next=p; q->next=info; } printf("\n已经插入了%s这个学生\n",info->name); printf("----不要忘了存盘啊--\n"); return(h); } void save(STUDENT *h) { FILE *fp; STUDENT *p; char outfile[10]; printf("请输入保存文件的文件名，例如 c:\\f1\\te.txt:\n"); scanf("%s",outfile); if((fp=fopen(outfile,"wb"))==NULL) { printf("不能打开文件\n"); exit(1); } printf("\n正在保存......\n"); p=h; while(p!=NULL) { fwrite(p,sizeof(STUDENT),1,fp); p=p->next; } fclose(fp); printf("------保存成功!!!------\n"); } void sort(STUDENT *h) { int i=0,j; STUDENT *p,*q,*t,*h1; printf("请输入要按哪门课程的编号来排序:(0.语文 1.数学 2.英语)\n"); scanf("%d",&j); h1=h->next; h->next=NULL; while(h1!=NULL) { t=h1; h1=h1->next; p=h; q=h; while(t->score[j]<p->score[j]&&p!=NULL) { q=p; p=p->next; } if(p==q) { t->next=p; h=t; } else { t->next=p; q->next=t; } } p=h; while(p!=NULL) { i++; p->order=i; p=p->next; } print(h); printf("排序成功!!!\n"); } void tongji(STUDENT *h) { STUDENT *p; int a,b,i; printf("请输入课程编号\n"); scanf("%d",&i); printf("请输入分数段:\n"); scanf("%d,%d",&a,&b); p=h; while(p!=NULL) { printf("\n\n\n***********************找到了***********************\n"); if(p->score[i]>=a&&p->score[i]<=b) { printf("|学号 | 姓名 | 语文 | 英语 | 数学 | 总分 | 平均分 | 名次 |\n"); printf("|--------|---------|----|----|----|------|------|---|\n"); printf("|%-10s|%-8s|%4d|%4d|%4d|%4.2f|%4.2f|%3d|\n",p->no,p->name,p->score[0],p->score[1],p->score[2],p->sum,p->average,p->order); } p=p->next; } printf("***********************end***********************\n"); }


Question: PAT德才论 BUG

引用 15 楼 user-1 的回复:[quote=引用 7 楼 Martin Morning 的回复:] [quote=引用 12 楼 user-1 的回复:] [quote=引用 11 楼 Martin Morning 的回复:] [quote=引用 10 楼 user-1 的回复:] 你德判断条件不严谨，换成下面德代码。    if(s2[j].s!=s2[t].s ) {  //总分不相等时，按总分判断 	if(s2[j].s>s2[t].s) 		t=j; } else {				// 总分相等 	if(s2[j].s1!=s2[t].s1) {  //但德 分数不同，根据 德 判断 		if(s2[j].s1>s2[t].s1) 			t=j; 	} else {  //总分、德 也相同，根据学号判断 		if(s2[j].N<s2[t].N) 			t=j; 	} } 你的代码和我的意思是一样呀，我换了你的也是错的[/quote]  是一样的，这让我很困惑啊。感叹找人家程序中的BUG总是那么的困难。。。。  早上脑子比较清晰，再看了一遍，找出问题。  STU s[10001];  <=====BUG，少了一位！！！溢出了~~  就那么简单，问题解决了~~~费了我不少时间~~~  存储第三类考生，条件判断： if(s[i].s1<80&&s[i].s1>=60&&s[i].s2<80&&s[i].s2>=60&&s[i].s1>s[i].s2) 改为： if( s[i].s1<80&&s[i].s1>=60 &&  s[i].s2>=60  &&  s[i].s1>=s[i].s2 )比较妥当。     [/quote]能加个Q或者V吗，可以相互讨论，论坛讨论太麻烦了[/quote]  你呀~~~那么粗心~~~我都给你验证过了的。 if(s[i].s1<80&&s[i].s1>=60&&s[i].s2<80&&s[i].s2>=60&&s[i].s1>s[i].s2)     80换为h，60换为l，每条都去换。 还是给你贴上改过的代码吧~~~记住，要细心点~~不要太暴躁~~    #include <stdio.h> #include <stdlib.h>  /* run this program using the console pauser or add your own getch, system("pause") or input loop */ typedef struct student { 	long int N;//准考证号 	int s1;//德 	int s2;//才 	int s;//总分 } STU;  void sort(STU s2[],int l,int r) { 	int i,j; 	for(i=l; i<=r; i++) { 		int t=i;  		for(j=i+1; j<=r; j++) {  			if(s2[j].s>s2[t].s  || s2[j].s==s2[t].s && s2[j].s1>s2[t].s1 || s2[j].s==s2[t].s&&s2[j].s1==s2[t].s1&&s2[j].N<s2[t].N  ) { 	//修改点1 				t=j; 			}  		} 		if(t!=i) { 			STU T=s2[i]; 			s2[i]=s2[t];  			s2[t]=T; 		} 	} }    int main(int argc, char *argv[]) { 	int n,l,h; 	scanf("%d%d%d",&n,&l,&h); 	int i,j; 	STU s[100001];//<===修改点2 	for(i=0; i<n; i++) { //输入学号德才总分   		scanf("%ld",&s[i].N); 		scanf("%d%d",&s[i].s1,&s[i].s2); 		s[i].s=	s[i].s1+s[i].s2; 	} 	int k=0; 	STU s2[100001]; 	for(i=0; i<n; i++) { //存储第一类考生 		if(s[i].s1>=h &&s[i].s2>=h)	//修改点3 			s2[k++]=s[i]; 	} 	int d1=k-1;//记录最后一个第一类考生的下标 	for(i=0; i<n; i++) { //存储第二类考生 		if(s[i].s1>=h&&s[i].s2<h&&s[i].s2>=l)	//修改点4 			s2[k++]=s[i]; 	} 	int d2=k-1;//记录最后一个第二类考生的下标 	for(i=0; i<n; i++) { //存储第三类考生 		if(s[i].s1<h&&s[i].s1>=l&&s[i].s2>=l&&s[i].s1>=s[i].s2)	//修改点5 			s2[k++]=s[i]; 	} 	int d3=k-1;//记录最后一个第三类考生的下标 	for(i=0; i<n; i++) { //第四类考生 		if(s[i].s1<h&&s[i].s1>=l&&s[i].s2>=l&&s[i].s1<s[i].s2)//修改点6 			s2[k++]=s[i]; 	} 	int d4=k-1;////记录最后一个第四类考生的下标 	printf("%d\n",k);  	sort(s2,0,d1); 	sort(s2,d1+1,d2); 	sort(s2,d2+1,d3); 	sort(s2,d3+1,d4);  	for(i=0; i<k; i++) { 		printf("%ld %d %d\n",s2[i].N,s2[i].s1,s2[i].s2); 	} } [/quote]解决了，  引用 15 楼 user-1 的回复:[quote=引用 7 楼 Martin Morning 的回复:] [quote=引用 12 楼 user-1 的回复:] [quote=引用 11 楼 Martin Morning 的回复:] [quote=引用 10 楼 user-1 的回复:] 你德判断条件不严谨，换成下面德代码。    if(s2[j].s!=s2[t].s ) {  //总分不相等时，按总分判断 	if(s2[j].s>s2[t].s) 		t=j; } else {				// 总分相等 	if(s2[j].s1!=s2[t].s1) {  //但德 分数不同，根据 德 判断 		if(s2[j].s1>s2[t].s1) 			t=j; 	} else {  //总分、德 也相同，根据学号判断 		if(s2[j].N<s2[t].N) 			t=j; 	} } 你的代码和我的意思是一样呀，我换了你的也是错的[/quote]  是一样的，这让我很困惑啊。感叹找人家程序中的BUG总是那么的困难。。。。  早上脑子比较清晰，再看了一遍，找出问题。  STU s[10001];  <=====BUG，少了一位！！！溢出了~~  就那么简单，问题解决了~~~费了我不少时间~~~  存储第三类考生，条件判断： if(s[i].s1<80&&s[i].s1>=60&&s[i].s2<80&&s[i].s2>=60&&s[i].s1>s[i].s2) 改为： if( s[i].s1<80&&s[i].s1>=60 &&  s[i].s2>=60  &&  s[i].s1>=s[i].s2 )比较妥当。     [/quote]能加个Q或者V吗，可以相互讨论，论坛讨论太麻烦了[/quote]  你呀~~~那么粗心~~~我都给你验证过了的。 if(s[i].s1<80&&s[i].s1>=60&&s[i].s2<80&&s[i].s2>=60&&s[i].s1>s[i].s2)     80换为h，60换为l，每条都去换。 还是给你贴上改过的代码吧~~~记住，要细心点~~不要太暴躁~~    #include <stdio.h> #include <stdlib.h>  /* run this program using the console pauser or add your own getch, system("pause") or input loop */ typedef struct student { 	long int N;//准考证号 	int s1;//德 	int s2;//才 	int s;//总分 } STU;  void sort(STU s2[],int l,int r) { 	int i,j; 	for(i=l; i<=r; i++) { 		int t=i;  		for(j=i+1; j<=r; j++) {  			if(s2[j].s>s2[t].s  || s2[j].s==s2[t].s && s2[j].s1>s2[t].s1 || s2[j].s==s2[t].s&&s2[j].s1==s2[t].s1&&s2[j].N<s2[t].N  ) { 	//修改点1 				t=j; 			}  		} 		if(t!=i) { 			STU T=s2[i]; 			s2[i]=s2[t];  			s2[t]=T; 		} 	} }    int main(int argc, char *argv[]) { 	int n,l,h; 	scanf("%d%d%d",&n,&l,&h); 	int i,j; 	STU s[100001];//<===修改点2 	for(i=0; i<n; i++) { //输入学号德才总分   		scanf("%ld",&s[i].N); 		scanf("%d%d",&s[i].s1,&s[i].s2); 		s[i].s=	s[i].s1+s[i].s2; 	} 	int k=0; 	STU s2[100001]; 	for(i=0; i<n; i++) { //存储第一类考生 		if(s[i].s1>=h &&s[i].s2>=h)	//修改点3 			s2[k++]=s[i]; 	} 	int d1=k-1;//记录最后一个第一类考生的下标 	for(i=0; i<n; i++) { //存储第二类考生 		if(s[i].s1>=h&&s[i].s2<h&&s[i].s2>=l)	//修改点4 			s2[k++]=s[i]; 	} 	int d2=k-1;//记录最后一个第二类考生的下标 	for(i=0; i<n; i++) { //存储第三类考生 		if(s[i].s1<h&&s[i].s1>=l&&s[i].s2>=l&&s[i].s1>=s[i].s2)	//修改点5 			s2[k++]=s[i]; 	} 	int d3=k-1;//记录最后一个第三类考生的下标 	for(i=0; i<n; i++) { //第四类考生 		if(s[i].s1<h&&s[i].s1>=l&&s[i].s2>=l&&s[i].s1<s[i].s2)//修改点6 			s2[k++]=s[i]; 	} 	int d4=k-1;////记录最后一个第四类考生的下标 	printf("%d\n",k);  	sort(s2,0,d1); 	sort(s2,d1+1,d2); 	sort(s2,d2+1,d3); 	sort(s2,d3+1,d4);  	for(i=0; i<k; i++) { 		printf("%ld %d %d\n",s2[i].N,s2[i].s1,s2[i].s2); 	} } [/quote]  引用 15 楼 user-1 的回复:[quote=引用 7 楼 Martin Morning 的回复:] [quote=引用 12 楼 user-1 的回复:] [quote=引用 11 楼 Martin Morning 的回复:] [quote=引用 10 楼 user-1 的回复:] 你德判断条件不严谨，换成下面德代码。    if(s2[j].s!=s2[t].s ) {  //总分不相等时，按总分判断 	if(s2[j].s>s2[t].s) 		t=j; } else {				// 总分相等 	if(s2[j].s1!=s2[t].s1) {  //但德 分数不同，根据 德 判断 		if(s2[j].s1>s2[t].s1) 			t=j; 	} else {  //总分、德 也相同，根据学号判断 		if(s2[j].N<s2[t].N) 			t=j; 	} } 你的代码和我的意思是一样呀，我换了你的也是错的[/quote]  是一样的，这让我很困惑啊。感叹找人家程序中的BUG总是那么的困难。。。。  早上脑子比较清晰，再看了一遍，找出问题。  STU s[10001];  <=====BUG，少了一位！！！溢出了~~  就那么简单，问题解决了~~~费了我不少时间~~~  存储第三类考生，条件判断： if(s[i].s1<80&&s[i].s1>=60&&s[i].s2<80&&s[i].s2>=60&&s[i].s1>s[i].s2) 改为： if( s[i].s1<80&&s[i].s1>=60 &&  s[i].s2>=60  &&  s[i].s1>=s[i].s2 )比较妥当。     [/quote]能加个Q或者V吗，可以相互讨论，论坛讨论太麻烦了[/quote]  你呀~~~那么粗心~~~我都给你验证过了的。 if(s[i].s1<80&&s[i].s1>=60&&s[i].s2<80&&s[i].s2>=60&&s[i].s1>s[i].s2)     80换为h，60换为l，每条都去换。 还是给你贴上改过的代码吧~~~记住，要细心点~~不要太暴躁~~    #include <stdio.h> #include <stdlib.h>  /* run this program using the console pauser or add your own getch, system("pause") or input loop */ typedef struct student { 	long int N;//准考证号 	int s1;//德 	int s2;//才 	int s;//总分 } STU;  void sort(STU s2[],int l,int r) { 	int i,j; 	for(i=l; i<=r; i++) { 		int t=i;  		for(j=i+1; j<=r; j++) {  			if(s2[j].s>s2[t].s  || s2[j].s==s2[t].s && s2[j].s1>s2[t].s1 || s2[j].s==s2[t].s&&s2[j].s1==s2[t].s1&&s2[j].N<s2[t].N  ) { 	//修改点1 				t=j; 			}  		} 		if(t!=i) { 			STU T=s2[i]; 			s2[i]=s2[t];  			s2[t]=T; 		} 	} }    int main(int argc, char *argv[]) { 	int n,l,h; 	scanf("%d%d%d",&n,&l,&h); 	int i,j; 	STU s[100001];//<===修改点2 	for(i=0; i<n; i++) { //输入学号德才总分   		scanf("%ld",&s[i].N); 		scanf("%d%d",&s[i].s1,&s[i].s2); 		s[i].s=	s[i].s1+s[i].s2; 	} 	int k=0; 	STU s2[100001]; 	for(i=0; i<n; i++) { //存储第一类考生 		if(s[i].s1>=h &&s[i].s2>=h)	//修改点3 			s2[k++]=s[i]; 	} 	int d1=k-1;//记录最后一个第一类考生的下标 	for(i=0; i<n; i++) { //存储第二类考生 		if(s[i].s1>=h&&s[i].s2<h&&s[i].s2>=l)	//修改点4 			s2[k++]=s[i]; 	} 	int d2=k-1;//记录最后一个第二类考生的下标 	for(i=0; i<n; i++) { //存储第三类考生 		if(s[i].s1<h&&s[i].s1>=l&&s[i].s2>=l&&s[i].s1>=s[i].s2)	//修改点5 			s2[k++]=s[i]; 	} 	int d3=k-1;//记录最后一个第三类考生的下标 	for(i=0; i<n; i++) { //第四类考生 		if(s[i].s1<h&&s[i].s1>=l&&s[i].s2>=l&&s[i].s1<s[i].s2)//修改点6 			s2[k++]=s[i]; 	} 	int d4=k-1;////记录最后一个第四类考生的下标 	printf("%d\n",k);  	sort(s2,0,d1); 	sort(s2,d1+1,d2); 	sort(s2,d2+1,d3); 	sort(s2,d3+1,d4);  	for(i=0; i<k; i++) { 		printf("%ld %d %d\n",s2[i].N,s2[i].s1,s2[i].s2); 	} } [/quote]通过了，谢谢老哥的帮忙，下次我一定自己注意。

引用 7 楼 Martin Morning 的回复:[quote=引用 12 楼 user-1 的回复:] [quote=引用 11 楼 Martin Morning 的回复:] [quote=引用 10 楼 user-1 的回复:] 你德判断条件不严谨，换成下面德代码。    if(s2[j].s!=s2[t].s ) {  //总分不相等时，按总分判断 	if(s2[j].s>s2[t].s) 		t=j; } else {				// 总分相等 	if(s2[j].s1!=s2[t].s1) {  //但德 分数不同，根据 德 判断 		if(s2[j].s1>s2[t].s1) 			t=j; 	} else {  //总分、德 也相同，根据学号判断 		if(s2[j].N<s2[t].N) 			t=j; 	} } 你的代码和我的意思是一样呀，我换了你的也是错的[/quote]  是一样的，这让我很困惑啊。感叹找人家程序中的BUG总是那么的困难。。。。  早上脑子比较清晰，再看了一遍，找出问题。  STU s[10001];  <=====BUG，少了一位！！！溢出了~~  就那么简单，问题解决了~~~费了我不少时间~~~  存储第三类考生，条件判断： if(s[i].s1<80&&s[i].s1>=60&&s[i].s2<80&&s[i].s2>=60&&s[i].s1>s[i].s2) 改为： if( s[i].s1<80&&s[i].s1>=60 &&  s[i].s2>=60  &&  s[i].s1>=s[i].s2 )比较妥当。     [/quote]能加个Q或者V吗，可以相互讨论，论坛讨论太麻烦了[/quote]  你呀~~~那么粗心~~~我都给你验证过了的。 if(s[i].s1<80&&s[i].s1>=60&&s[i].s2<80&&s[i].s2>=60&&s[i].s1>s[i].s2)     80换为h，60换为l，每条都去换。 还是给你贴上改过的代码吧~~~记住，要细心点~~不要太暴躁~~    #include <stdio.h> #include <stdlib.h>  /* run this program using the console pauser or add your own getch, system("pause") or input loop */ typedef struct student { 	long int N;//准考证号 	int s1;//德 	int s2;//才 	int s;//总分 } STU;  void sort(STU s2[],int l,int r) { 	int i,j; 	for(i=l; i<=r; i++) { 		int t=i;  		for(j=i+1; j<=r; j++) {  			if(s2[j].s>s2[t].s  || s2[j].s==s2[t].s && s2[j].s1>s2[t].s1 || s2[j].s==s2[t].s&&s2[j].s1==s2[t].s1&&s2[j].N<s2[t].N  ) { 	//修改点1 				t=j; 			}  		} 		if(t!=i) { 			STU T=s2[i]; 			s2[i]=s2[t];  			s2[t]=T; 		} 	} }    int main(int argc, char *argv[]) { 	int n,l,h; 	scanf("%d%d%d",&n,&l,&h); 	int i,j; 	STU s[100001];//<===修改点2 	for(i=0; i<n; i++) { //输入学号德才总分   		scanf("%ld",&s[i].N); 		scanf("%d%d",&s[i].s1,&s[i].s2); 		s[i].s=	s[i].s1+s[i].s2; 	} 	int k=0; 	STU s2[100001]; 	for(i=0; i<n; i++) { //存储第一类考生 		if(s[i].s1>=h &&s[i].s2>=h)	//修改点3 			s2[k++]=s[i]; 	} 	int d1=k-1;//记录最后一个第一类考生的下标 	for(i=0; i<n; i++) { //存储第二类考生 		if(s[i].s1>=h&&s[i].s2<h&&s[i].s2>=l)	//修改点4 			s2[k++]=s[i]; 	} 	int d2=k-1;//记录最后一个第二类考生的下标 	for(i=0; i<n; i++) { //存储第三类考生 		if(s[i].s1<h&&s[i].s1>=l&&s[i].s2>=l&&s[i].s1>=s[i].s2)	//修改点5 			s2[k++]=s[i]; 	} 	int d3=k-1;//记录最后一个第三类考生的下标 	for(i=0; i<n; i++) { //第四类考生 		if(s[i].s1<h&&s[i].s1>=l&&s[i].s2>=l&&s[i].s1<s[i].s2)//修改点6 			s2[k++]=s[i]; 	} 	int d4=k-1;////记录最后一个第四类考生的下标 	printf("%d\n",k);  	sort(s2,0,d1); 	sort(s2,d1+1,d2); 	sort(s2,d2+1,d3); 	sort(s2,d3+1,d4);  	for(i=0; i<k; i++) { 		printf("%ld %d %d\n",s2[i].N,s2[i].s1,s2[i].s2); 	} }

引用 12 楼 user-1 的回复:[quote=引用 11 楼 Martin Morning 的回复:] [quote=引用 10 楼 user-1 的回复:] 你德判断条件不严谨，换成下面德代码。    if(s2[j].s!=s2[t].s ) {  //总分不相等时，按总分判断 	if(s2[j].s>s2[t].s) 		t=j; } else {				// 总分相等 	if(s2[j].s1!=s2[t].s1) {  //但德 分数不同，根据 德 判断 		if(s2[j].s1>s2[t].s1) 			t=j; 	} else {  //总分、德 也相同，根据学号判断 		if(s2[j].N<s2[t].N) 			t=j; 	} } 你的代码和我的意思是一样呀，我换了你的也是错的[/quote]  是一样的，这让我很困惑啊。感叹找人家程序中的BUG总是那么的困难。。。。  早上脑子比较清晰，再看了一遍，找出问题。  STU s[10001];  <=====BUG，少了一位！！！溢出了~~  就那么简单，问题解决了~~~费了我不少时间~~~  存储第三类考生，条件判断： if(s[i].s1<80&&s[i].s1>=60&&s[i].s2<80&&s[i].s2>=60&&s[i].s1>s[i].s2) 改为： if( s[i].s1<80&&s[i].s1>=60 &&  s[i].s2>=60  &&  s[i].s1>=s[i].s2 )比较妥当。     [/quote]能加个Q或者V吗，可以相互讨论，论坛讨论太麻烦了

引用 12 楼 user-1 的回复:[quote=引用 11 楼 Martin Morning 的回复:] [quote=引用 10 楼 user-1 的回复:] 你德判断条件不严谨，换成下面德代码。    if(s2[j].s!=s2[t].s ) {  //总分不相等时，按总分判断 	if(s2[j].s>s2[t].s) 		t=j; } else {				// 总分相等 	if(s2[j].s1!=s2[t].s1) {  //但德 分数不同，根据 德 判断 		if(s2[j].s1>s2[t].s1) 			t=j; 	} else {  //总分、德 也相同，根据学号判断 		if(s2[j].N<s2[t].N) 			t=j; 	} } 你的代码和我的意思是一样呀，我换了你的也是错的[/quote]  是一样的，这让我很困惑啊。感叹找人家程序中的BUG总是那么的困难。。。。  早上脑子比较清晰，再看了一遍，找出问题。  STU s[10001];  <=====BUG，少了一位！！！溢出了~~  就那么简单，问题解决了~~~费了我不少时间~~~  存储第三类考生，条件判断： if(s[i].s1<80&&s[i].s1>=60&&s[i].s2<80&&s[i].s2>=60&&s[i].s1>s[i].s2) 改为： if( s[i].s1<80&&s[i].s1>=60 &&  s[i].s2>=60  &&  s[i].s1>=s[i].s2 )比较妥当。     [/quote]老铁，费心了。不过很遗憾，并不是这里出的问题，因为我改了之后还是报错

引用 11 楼 Martin Morning 的回复:[quote=引用 10 楼 user-1 的回复:] 你德判断条件不严谨，换成下面德代码。    if(s2[j].s!=s2[t].s ) {  //总分不相等时，按总分判断 	if(s2[j].s>s2[t].s) 		t=j; } else {				// 总分相等 	if(s2[j].s1!=s2[t].s1) {  //但德 分数不同，根据 德 判断 		if(s2[j].s1>s2[t].s1) 			t=j; 	} else {  //总分、德 也相同，根据学号判断 		if(s2[j].N<s2[t].N) 			t=j; 	} } 你的代码和我的意思是一样呀，我换了你的也是错的[/quote]  是一样的，这让我很困惑啊。感叹找人家程序中的BUG总是那么的困难。。。。  早上脑子比较清晰，再看了一遍，找出问题。  STU s[10001];  <=====BUG，少了一位！！！溢出了~~  就那么简单，问题解决了~~~费了我不少时间~~~  存储第三类考生，条件判断： if(s[i].s1<80&&s[i].s1>=60&&s[i].s2<80&&s[i].s2>=60&&s[i].s1>s[i].s2) 改为： if( s[i].s1<80&&s[i].s1>=60 &&  s[i].s2>=60  &&  s[i].s1>=s[i].s2 )比较妥当。

引用 10 楼 user-1 的回复:你德判断条件不严谨，换成下面德代码。    if(s2[j].s!=s2[t].s ) {  //总分不相等时，按总分判断 	if(s2[j].s>s2[t].s) 		t=j; } else {				// 总分相等 	if(s2[j].s1!=s2[t].s1) {  //但德 分数不同，根据 德 判断 		if(s2[j].s1>s2[t].s1) 			t=j; 	} else {  //总分、德 也相同，根据学号判断 		if(s2[j].N<s2[t].N) 			t=j; 	} } 你的代码和我的意思是一样呀，我换了你的也是错的

引用 8 楼 user-1 的回复:[quote=引用 7 楼 Martin Morning 的回复:] [quote=引用 6 楼 user-1的回复:]if(s2[j].s>s2[t].s  || s2[j].s==s2[t].s && s2[j].s1>s2[t].s1  ) 你仅考虑了1:按总分，2：总分相同按德，没有考虑3：总分、德相同，需要按照学号升序排列。  这个测试数据有陷阱的，所以你用测试数据能输出正确结果。但是如果你把： 10000011 85 80 10000003 85 80 这两行位置换一下看看，输出就不对了。  PTA的老师很狡猾的…… 你说的对，但是很奇怪，我没加学号的条件运行出来的结果也是对的，你不信可以把给的样例输进去试试。样例学号11在03之前，但是运行出来11变到03之后了。然后我又单独把这2个学号拿出来试，发现学号又不能排序了，你知道这是为什么吗[/quote]  道理很简单，你用的是选择排序法，它的排序结果是不稳定的。当a==b时，b有可能出现在a的前面，这个在《数据结构》上有介绍的。如果你用稳定的排序算法，如冒泡、插入等排序法，估计你很快就发现漏了一个判断条件。[/quote]恍然大悟。可是为啥我把学号的条件加上去，	if(s2[j].s>s2[t].s  || s2[j].s==s2[t].s && s2[j].s1>s2[t].s1||s2[j].s==s2[t].s&&s2[j].s1==s2[t].s1&&s2[j].N<s2[t].N  )，提交上去那个测试点还是错误的呢

引用 7 楼 Martin Morning 的回复:[quote=引用 6 楼 user-1的回复:]if(s2[j].s>s2[t].s  || s2[j].s==s2[t].s && s2[j].s1>s2[t].s1  ) 你仅考虑了1:按总分，2：总分相同按德，没有考虑3：总分、德相同，需要按照学号升序排列。  这个测试数据有陷阱的，所以你用测试数据能输出正确结果。但是如果你把： 10000011 85 80 10000003 85 80 这两行位置换一下看看，输出就不对了。  PTA的老师很狡猾的…… 你说的对，但是很奇怪，我没加学号的条件运行出来的结果也是对的，你不信可以把给的样例输进去试试。样例学号11在03之前，但是运行出来11变到03之后了。然后我又单独把这2个学号拿出来试，发现学号又不能排序了，你知道这是为什么吗[/quote]  道理很简单，你用的是选择排序法，它的排序结果是不稳定的。当a==b时，b有可能出现在a的前面，这个在《数据结构》上有介绍的。如果你用稳定的排序算法，如冒泡、插入等排序法，估计你很快就发现漏了一个判断条件。

引用 6 楼 user-1的回复:if(s2[j].s>s2[t].s  || s2[j].s==s2[t].s && s2[j].s1>s2[t].s1  ) 你仅考虑了1:按总分，2：总分相同按德，没有考虑3：总分、德相同，需要按照学号升序排列。  这个测试数据有陷阱的，所以你用测试数据能输出正确结果。但是如果你把： 10000011 85 80 10000003 85 80 这两行位置换一下看看，输出就不对了。  PTA的老师很狡猾的…… 你说的对，但是很奇怪，我没加学号的条件运行出来的结果也是对的，你不信可以把给的样例输进去试试。样例学号11在03之前，但是运行出来11变到03之后了。然后我又单独把这2个学号拿出来试，发现学号又不能排序了，你知道这是为什么吗

引用 3 楼 user-1的回复:你把 #include<stdlib.h>去掉，PTA的stdlib 库中带有qsort排序算法的，冲突了~~。 这个不影响吧，头文件多了又不会影响编译和运行。我用qsort做出来了一个答案，可是我最初写的这个答案我还是没找到错误

引用 1 楼 user-1的回复:1：你排序的判断条件不够严谨，导致出现一个测试点答案错误。2：这道题需要用N(logN）的排序算法才不会超时。3：你的快速排序算法是错误的。 大佬能看看条件哪里不够严谨吗？快排是我根据天勤书上的代码写的，照说不应该错的，我用普通整型数组也试过确实有效。

贴上代码，供你参考。    #include <stdio.h> #include<stdlib.h>  #define TRUE 1 #define FALSE 0 #define BOOL int  typedef struct _student { 	int id;//准考证号 	int de;//德 	int cai;//才 	int level; //等级  } student;  //排序比较函数 ，s1>s2 返回TRUE 其它返回FALSE   BOOL cmp(student * s1, student *s2 ) { 	int sum1,sum2; 	//计算总分  	sum1=s1->de+s1->cai; 	sum2=s2->de+s2->cai;  	if (s1->level != s2->level)  //1：比较等级  		return s1->level > s2->level;  	if (sum1 < sum2) {           //2：等级相同，比较总分  		return FALSE; 	} else if (sum1 > sum2) {  		return TRUE; 	} else {                      //3：总分相同，比较德  		if (s1->de < s2->de) { 			return FALSE; 		} else if (s1->de > s2->de) { 			return TRUE; 		} else {                  //4：德也相同，比较id  			if (s1->id < s2->id) { 				return TRUE; 			} else { 				return FALSE; 			} 		} 	} }  //快速排序  void qsort(student stu[], int low,int high) {  	int i,j; 	student temp;  	if(low<high) { 		i=low,j=high,temp=stu[i];  		while(i<j) { 			while(i<j&&!cmp(&stu[j],&temp)) 				j--; 			if(i<j) { 				stu[i]=stu[j]; 				i++; 			}  			while(i<j&&cmp(&stu[i],&temp)) 				++i; 			if(i<j) { 				stu[j]=stu[i]; 				j--; 			} 		} 		stu[i]=temp;  		qsort(stu,low,i-1); 		qsort(stu,i+1,high); 	} 	return; }  int main() { 	int n, l, h; 	int i, j; 	student stu[100000]; 	int count = 0; //符合最低标准人数   	scanf("%d%d%d", &n, &l, &h); 	for (i = 0; i < n; i++) { //输入学号德才总分 		scanf("%ld", &stu[i].id); 		scanf("%d%d", &stu[i].de, &stu[i].cai); 	}  //按标准进行分类，并统计符合标准的人数。  	for (i = 0; i < n; i++) { 		if (stu[i].de >= h && stu[i].cai >= h) j=5; 		else if (stu[i].de >= h && stu[i].cai >= l) j = 4; 		else if (stu[i].de >= l && stu[i].cai >= l && stu[i].de >= stu[i].cai) j = 3; 		else if (stu[i].de >= l && stu[i].cai >= l) j = 2; 		else j=1; 		stu[i].level = j; 		if (j > 1) count++; 	}  	qsort(stu,0,n-1); //快速排序   	printf("%d\n", count ); 	for (i = 0; i < count; i++) { 		printf("%ld %d %d\n", stu[i].id, stu[i].de, stu[i].cai); 	} 	return 0; }


Question: 新手请多指教：有关Return的问题

引用 2 楼 user-2的回复:你这add实现函数没有类型可以编译过？？ 不写类型是默认int。

函数的返回值一般由寄存器eax返回，你在调试器中可以看看eax的变化

你这add实现函数没有类型可以编译过？？

我赋值长是1，宽是2，最后结果是2。


Question: 运行出来结果对了为什么提交到PAT上去一个测试点过不了

引用 4 楼 coo135 的回复:智商有限，这道题目实在是看不懂啊…… 能弄明白在讲什么的真是神仙啊！！！  百度到有位神仙他明白，解释如下：  解决问题的关键是第二个和第三个要求。  （1）第二个要求说明了a的长度和c的长度是相等的，所以我们可以列出一个等式：lena = lenc；  （2）第三个要求则说明，在第二个条件成立的条件下，将aPATc中的A字符换成b串，变为aPbTc。如果该字符串正确，那么aPbATac字符串也正确。仔细观察不难发现，P和A字符中间多加了一个A字符，而字符串末尾c串后面则加了一个a串。也就是说，c串后面加的a串的个数与P字符和T字符中间加入的A字符的个数相等。  假设b含有lenb个A字符，那么新加入的A字符的个数就是（lenb-1）个(因为为了保证字符串正确，b中最起码要有一个A字符)。所以c串后面的a串个数也就是（lenb-1）个。所以可以列出一个式子： lenc = lenc+（lenb-1）*lena 。  由第二个要求得出的式子 lena = lenc 带入得： lenc = lena + （lenb-1）*lena 。  化简上式即为 ： lenc = lena * lenb。   原来如此~~~~拜一下~~~这样写代码就简单了  #include <stdio.h> #include <string.h> // 解题关键  (len_a)P(len_b)T(len_c)  // 例：AAPATAA,  len_a=2，len_b=1，len_c=2 // 判断条件：len_c = len_a * len_b，并且len_b>=1。  //judge，符合要求，返回1，否则返回0 int judge(char str[]) { 	int len_a, len_b, len_c;// 'A' 的个数 	char* p, * t;  	//字符串中有非'P'、'A'、'T'字符，不符合要求 	for (char* s = str; *s != '\0'; s++) { 		if (*s != 'P' && *s != 'A' && *s != 'T') 			return 0; 	} 	// 找出'P'，'T' 在字符串中的位置 	p = strchr(str, 'P'); 	t = strchr(str, 'T'); 	//未找到字符'P','T' 或者'T'在'P'之前，说明不符合要求 	if (p == NULL || t == NULL || p > t) return 0; 	//求a,b,c 长度 	len_a = p - str; 	len_b = t - p - 1; 	len_c = strlen(t + 1); 	//根据条件，进行判断 	if (len_b >= 1 && len_c == len_a * len_b) 		return 1; 	else 		return 0; } int main() { 	int n; 	char str[10][101]; 	scanf("%d", &n); 	for (int i = 0; i < n; i++) { 		scanf("%s", str[i]); 		if (judge(str[i]) == 1) 			printf("YES\n"); 		else 			printf("NO\n"); 	} 	return 0; }  我知道是啥意思，我的代码思路和你的一样，而且我运行出来的结果都是对的。只是提交进PAT测试点全错了。我刚又在牛客网上去提交了一遍发现全过了，这不是我第一次碰到这种情况了。我觉得PAT的判题系统可能有BUG

引用 12 楼 coo135的回复:1.字符串中必须仅有 P、 A、 T这三种字符，不可以包含其它字符；  题目中的条件1规定了。  你做PAT，建议做甲级或以上的，乙级基本不需要算法，对学习帮助不大。 比较推荐做：数据结构与算法题目集，这些程序相对较为复杂，对编程帮助比较大。   好的，谢谢你的建议，我明天改刷算法题集，甲级英文题目理解起来有点浪费时间，暂时先不做了

引用 10 楼 coo135 的回复:相信这次说到点子上了……  错误如下图所标，有2处。 1：flag在循环中没有被重置，这个错误是比较明显的，所以我就认为逻辑有问题，没有细看你的程序。抱歉。 if (flag == 1 && cntp == 1 && cntt == 1 && cnta != 0) 当flag置为2时，不管对错，都将一直输出NO； 测试用例1：输出8个NO。 8 PT PAT PAAT AAPATAA AAPAATAAAA xPATx Whatever APAAATAA  2：计数器没有重置，这是刚刚调试时发现的问题。  解决：在 for (i = 0; i < n; ++i)后增加重置语句： flag = 1; cntp = cnta = cntt = 0;   修改后PAT结果： 我怎么就没想到呢。感谢老哥的指导，这道题是我很久以前发的贴了，现在才找到BUG，结果还是这种低级错误。然后我还想问一点就是如果按照题目这种说法，为什么PT输出是NO，题目里隐含了 “字符串里必须有A”和“PT之间必须有A的哪一种条件吗？

引用 1 楼 user-2的回复:估计是调试打印影响了，你删掉试试 printf("%d",p1-s[i]); 这个是我后面加上去的，忘删了。加上去之前就错了

这个是我后面加上去的，忘删了。加上去之前就错了

估计是调试打印影响了，你删掉试试 printf("%d",p1-s[i]);


Question: 新手请多关照：有关变量声明的问题

引用 6 楼 ggglivw的回复:你们老师是体育老师寒假看了几天书就来教你们的？ 确实有点儿失望，高考完抱着很大的好奇心找了个学校学C语言，好多问题却只能自己解决。我觉得老师自己就不重视概念，只重操作。而我的学习经历告诉我只有弄清概念才知道每一步到底该干什么，为什么这样做，才能算“有思想的芦苇”，而不是低级的机器人。有些东西我通过高中数学知识的迁移都理解得比老师容易。所以谢谢前辈的帮助了。

注意局部变量的作用域是函数内，除了函数就没有意义和无效的。

你们老师是体育老师寒假看了几天书就来教你们的？

。。。。。。。。。。。。。这个都怪老师么 引用 4 楼 weixin_45358177 的回复:[quote=引用 2 楼 曹佑之的回复:]全局变量、局部变量的作用域不同。。。。。。 main里面认识MN,但是add函数中不认识。。。。 谢谢啦，我买本教程自己看吧，老师没有讲这些内容。[/quote]

引用 2 楼 曹佑之的回复:全局变量、局部变量的作用域不同。。。。。。 main里面认识MN,但是add函数中不认识。。。。 谢谢啦，我买本教程自己看吧，老师没有讲这些内容。

引用 1 楼 ggglivw的回复:没毛病，确实没有声明，注意变量的生命周期，这个是基础中的基础，再看下书. 唉，老师讲的确实不到位啊，这个基础问题确实没讲到。

没毛病，确实没有声明，注意变量的生命周期，这个是基础中的基础，再看下书.


Question: 初学者请多关照：&&两侧不是命题时？

&&的结果只有2个，true和false, 左右的条件非0即true

引用 1 楼 ggglivw的回复:a&&b的意思是a和b都非0即可 那么 就是说逻辑运算符，比如&&两侧可以是命题，判断真假，返回0或1；也可以是 数值 通过判断是否为0来返回0和1。对吗？

引用 5 楼 weixin_45358177 的回复:[quote=引用 1 楼 ggglivw的回复:]a&&b的意思是a和b都非0即可 谢谢帮助，那么负数也是1吗？[/quote]负数当然不是 1

引用 4 楼 weixin_45358177 的回复:[quote=引用 3 楼 曹佑之的回复:]非0为真，也就是两个数不是0的情况就是真。 谢谢你，那就是说负数也是1吗？[/quote]  计算规则是判断两个数：0或者非0     所以不论正负

&& 判断的不是什么命题不命题的  &&检查2个表达式求值结果 是不是0 (或者0.0 或者NULL等)

引用 2 楼 ggglivw的回复:这个问题你自己用编译器尝试下，很容易就试出来的，常规点的0，1，-1，0xffffffff, 0x8fffffff 还有一个问题，除了0，1外其他值是怎么出来的？

引用 1 楼 ggglivw的回复:a&&b的意思是a和b都非0即可 谢谢帮助，那么负数也是1吗？

引用 3 楼 曹佑之的回复:非0为真，也就是两个数不是0的情况就是真。 谢谢你，那就是说负数也是1吗？

非0为真，也就是两个数不是0的情况就是真。

a&&b的意思是a和b都非0即可


Question: 遇到snprintf() 疑惑！

提醒：snprintf是开源的。

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

你在其他地方使用都正常，就某个位置，那就贴你的数据内容瞧瞧，估计是内容导致。 你也可尝试讲数组中间插入结束符号，然后你又取超过一个结束符号。 例如： aa[]={0x1,0x2,'\0',0x3,0x4} ,然后取len=5，看看0x03 估计是取不到的。

引用 3 楼 github.com/andarm 的回复:我尝试使用qt5.10 没有你说的len+0 才是需要输出。    char buf[20]={0};     snprintf(buf,4,"%s","12345"); // 需求是输出123.    len+1      qDebug()<<"show debug:"<<buf<<endl;  ------------------------------------------ 调试实际输出： 123   ； 所以你的问题应该和你的数据内容有关，是否数据中有结束符‘\0’  这个函数我在其他地方使用，都是正常的，实际输入字符长度+1；但唯独在这个函数中，出现异常，我想不明白是怎么回事。

snprintf()会自动在末尾加'\0'，若长度不+1，则将原字符串最后一字符舍去了。为了保证原字符串不变，需长度+1； 而我这里，+1之后，最后一个字符并不是0，而是非可显示字符（ASCCC值为171的。）

_snprintf, _snwprintf Write formatted data to a string.  int _snprintf( char *buffer, size_t count, const char *format [, argument] ... );  int _snwprintf( wchar_t *buffer, size_t count, const wchar_t *format [, argument] ... );  Routine Required Header Compatibility  _snprintf <stdio.h> Win 95, Win NT  _snwprintf <stdio.h> or <wchar.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  _snprintf returns the number of bytes stored in buffer, not counting the terminating null character. If the number of bytes required to store the data exceeds count, then count bytes of data are stored in buffer and a negative value is returned. _snwprintf returns the number of wide characters stored in buffer, not counting the terminating null wide character. If the storage required to store the data exceeds count wide characters, then count wide characters are stored in buffer and a negative value is returned.  Parameters  buffer  Storage location for output  count  Maximum number of characters to store  format  Format-control string  argument  Optional arguments  Remarks  The _snprintf function formats and stores count or fewer characters and values (including a terminating null character that is always appended unless count is zero or the formatted string length is greater than or equal to count characters) in buffer. Each argument (if any) is converted and output according to the corresponding format specification in format. The format consists of ordinary characters and has the same form and function as the format argument for printf. If copying occurs between strings that overlap, the behavior is undefined.  _snwprintf is a wide-character version of _snprintf; the pointer arguments to _snwprintf are wide-character strings. Detection of encoding errors in _snwprintf may differ from that in _snprintf. _snwprintf, like swprintf, writes output to a string rather than to a destination of type FILE.  Generic-Text Routine Mappings  TCHAR.H Routine  _UNICODE & _MBCS Not Defined _MBCS Defined _UNICODE Defined  _sntprintf _snprintf _snprintf _snwprintf    Example  /* SPRINTF.C: This program uses sprintf to format various  * data and place them in the string named buffer.  */  #include <stdio.h>  void main( void ) {    char  buffer[200], s[] = "computer", c = 'l';    int   i = 35, j;    float fp = 1.7320534f;     /* Format and print various data: */    j  = sprintf( buffer,     "\tString:    %s\n", s );    j += sprintf( buffer + j, "\tCharacter: %c\n", c );    j += sprintf( buffer + j, "\tInteger:   %d\n", i );    j += sprintf( buffer + j, "\tReal:      %f\n", fp );     printf( "Output:\n%s\ncharacter count = %d\n", buffer, j ); }   Output  Output:    String:    computer    Character: l    Integer:   35    Real:      1.732053  character count = 71   Stream I/O Routines  See Also   sprintf, fprintf, printf, scanf, sscanf, vprintf Functions


Question: 请教下各位大神，为什么我请求返回的报文base64用在线的解码器解不了，用程序也解不了

引用 18 楼 user-2 的回复:DES是对称加密算法，哪来什么公私钥，只有非对称加密算法才有公私钥 [quote=引用 16 楼 Chi King Chang 的回复:] [quote=引用 12 楼 stherix 的回复:] [quote=引用 11 楼 Chi King Chang 的回复:] 这是他边提供的C#解码编码  和他的php代码根本对不上 php用的3des加密 c#代码用的des解密 秘钥处理方式也不一样[/quote] 採用 DES 簽名，加密因子為指定（參考後面的文件）XML 報文，DES 加密後需再用 Base64 進行編碼。（由公司為您提供公私碼， 其中私碼用於您返回報文時的簽名，公碼用於驗證公司發送 的查詢的結果。）  这里意思是des解密的时候的Key值应该用他提供给我的公码是吧？[/quote][/quote] 询问过后他说加密解密都是使用53MP236N这个Key值，而且上面返回的base64码他们也说解码不成功，说是我这边发送的request有问题，有没有可能是因为两边开发平台不一致导致的？加之我把程序加密后的base64代码放去在线解码的工具上，好像都解不出来。

引用 18 楼 user-2 的回复:DES是对称加密算法，哪来什么公私钥，只有非对称加密算法才有公私钥  他这里的公私码和通常意义上的不一样 指的是发出去的和发回去的用的不是同一个秘钥

引用 18 楼 user-2 的回复:DES是对称加密算法，哪来什么公私钥，只有非对称加密算法才有公私钥 [quote=引用 16 楼 Chi King Chang 的回复:] [quote=引用 12 楼 stherix 的回复:] [quote=引用 11 楼 Chi King Chang 的回复:] 这是他边提供的C#解码编码  和他的php代码根本对不上 php用的3des加密 c#代码用的des解密 秘钥处理方式也不一样[/quote] 採用 DES 簽名，加密因子為指定（參考後面的文件）XML 報文，DES 加密後需再用 Base64 進行編碼。（由公司為您提供公私碼， 其中私碼用於您返回報文時的簽名，公碼用於驗證公司發送 的查詢的結果。）  这里意思是des解密的时候的Key值应该用他提供给我的公码是吧？[/quote][/quote] 是的，只有非对称算法才要公私码，小白学到了.

DES是对称加密算法，哪来什么公私钥，只有非对称加密算法才有公私钥 引用 16 楼 Chi King Chang 的回复:[quote=引用 12 楼 stherix 的回复:] [quote=引用 11 楼 Chi King Chang 的回复:] 这是他边提供的C#解码编码  和他的php代码根本对不上 php用的3des加密 c#代码用的des解密 秘钥处理方式也不一样[/quote] 採用 DES 簽名，加密因子為指定（參考後面的文件）XML 報文，DES 加密後需再用 Base64 進行編碼。（由公司為您提供公私碼， 其中私碼用於您返回報文時的簽名，公碼用於驗證公司發送 的查詢的結果。）  这里意思是des解密的时候的Key值应该用他提供给我的公码是吧？[/quote]

引用 16 楼 Chi King Chang 的回复:[quote=引用 12 楼 stherix 的回复:] [quote=引用 11 楼 Chi King Chang 的回复:] 这是他边提供的C#解码编码  和他的php代码根本对不上 php用的3des加密 c#代码用的des解密 秘钥处理方式也不一样[/quote] 採用 DES 簽名，加密因子為指定（參考後面的文件）XML 報文，DES 加密後需再用 Base64 進行編碼。（由公司為您提供公私碼， 其中私碼用於您返回報文時的簽名，公碼用於驗證公司發送 的查詢的結果。）  这里意思是des解密的时候的Key值应该用他提供给我的公码是吧？[/quote]  看他的说法,应该是把

引用 12 楼 stherix 的回复:[quote=引用 11 楼 Chi King Chang 的回复:] 这是他边提供的C#解码编码  和他的php代码根本对不上 php用的3des加密 c#代码用的des解密 秘钥处理方式也不一样[/quote] 採用 DES 簽名，加密因子為指定（參考後面的文件）XML 報文，DES 加密後需再用 Base64 進行編碼。（由公司為您提供公私碼， 其中私碼用於您返回報文時的簽名，公碼用於驗證公司發送 的查詢的結果。）  这里意思是des解密的时候的Key值应该用他提供给我的公码是吧？

引用 12 楼 stherix 的回复:[quote=引用 11 楼 Chi King Chang 的回复:] 这是他边提供的C#解码编码  和他的php代码根本对不上 php用的3des加密 c#代码用的des解密 秘钥处理方式也不一样[/quote]而且有点疑问的是，为什么他用的是ebc模式也需要初始化向量

引用 12 楼 stherix 的回复:[quote=引用 11 楼 Chi King Chang 的回复:] 这是他边提供的C#解码编码  和他的php代码根本对不上 php用的3des加密 c#代码用的des解密 秘钥处理方式也不一样[/quote]已经询问了，看看后续吧

引用 11 楼 Chi King Chang 的回复:这是他边提供的C#解码编码  和他的php代码根本对不上 php用的3des加密 c#代码用的des解密 秘钥处理方式也不一样

这是他边提供的C#解码编码  #region DESEncrypt DES加密  /// <summary>  /// 进行DES加密。  /// </summary>  /// <param name="pToEncrypt">要加密的字符串。</param>  /// <param name="sKey">密钥，且必须为8位。</param>  /// <returns>以Base64格式返回的加密字符串。</returns>  public static string DESEncrypt(string pToEncrypt, string sKey)  {  using (DESCryptoServiceProvider des = new DESCryptoServiceProvider())  {  byte[] inputByteArray = Encoding.UTF8.GetBytes(pToEncrypt);  des.Key = ASCIIEncoding.ASCII.GetBytes(sKey);  des.IV = ASCIIEncoding.ASCII.GetBytes(sKey);  System.IO.MemoryStream ms = new System.IO.MemoryStream();  using (CryptoStream cs = new CryptoStream(ms,  des.CreateEncryptor(), CryptoStreamMode.Write))  {  cs.Write(inputByteArray, 0, inputByteArray.Length);  cs.FlushFinalBlock();  cs.Close();  }  string str = Convert.ToBase64String(ms.ToArray());  ms.Close();  return str;  }  }  #endregion  #region DESDecrypt DES解密  /// <summary>  /// 进行DES解密。  /// </summary>  /// <param name="pToDecrypt">要解密的以Base64</param>  /// <param name="sKey">密钥，且必须为8位。</param> /// <returns>已解密的字符串。</returns>  public static string DESDecrypt(string pToDecrypt, string sKey)  {  byte[] inputByteArray = Convert.FromBase64String(pToDecrypt);  using (DESCryptoServiceProvider des = new DESCryptoServiceProvider())  {  des.Key = ASCIIEncoding.ASCII.GetBytes(sKey);  des.IV = ASCIIEncoding.ASCII.GetBytes(sKey);  System.IO.MemoryStream ms = new System.IO.MemoryStream();  using (CryptoStream cs = new CryptoStream(ms,  des.CreateDecryptor(), CryptoStreamMode.Write))  {  cs.Write(inputByteArray, 0, inputByteArray.Length);  cs.FlushFinalBlock();  cs.Close();  }  string str = Encoding.UTF8.GetString(ms.ToArray());  ms.Close();  return str;  }  }  #endregion

引用 9 楼 stherix 的回复:用它的php解密出来也是乱码 应该不是文本 根据他的协议文档来说就是解出来是xml，我这边已经给他报文叫他那边解析一下了。

用它的php解密出来也是乱码 应该不是文本

引用 3 楼 user-2 的回复:你用的不是DES-ECB模式么，和base64不是一种吧 DES-EBC模式在使用选项-a的时候不是能使用base64解码吗？  这是我网上看到的原话：-a和-A选项：对文件进行BASE64编解码操作

引用 6 楼 stherix 的回复:[quote=引用 5 楼 Chi King Chang 的回复:] [quote=引用 1 楼 stherix 的回复:] 你确认加密方法 passphrase 都是对的吗 文件也是完整的吗 这是我HTTPRequest 对方返回的报文，解密方法的话用了openssl下面的des-ecb指令解码，但是返回输出bad magic[/quote]  你问了对方是-des-ecb加密的吗,passphrase也是53MP236N?[/quote]  我问了对方 对方说对返回的报文是先进行base64解码再用des解密 下面是对方提供的php解密加密代码 //$input - stuff to decrypt //$key - the secret key to use function do_mencrypt($input, $key) { $input = str_replace(""n", "", $input); $input = str_replace(""t", "", $input); $input = str_replace(""r", "", $input); $key = substr(md5($key), 0, 24); $td = mcrypt_module_open('tripledes', '', 'ecb', ''); $iv = mcrypt_create_iv(mcrypt_enc_get_iv_size($td), MCRYPT_RAND); mcrypt_generic_init($td, $key, $iv); $encrypted_data = mcrypt_generic($td, $input); mcrypt_generic_deinit($td); mcrypt_module_close($td); return trim(chop(base64_encode($encrypted_data))); } //$input - stuff to decrypt //$key - the secret key to use function do_mdecrypt($input, $key) { $input = str_replace(""n", "", $input); $input = str_replace(""t", "", $input); $input = str_replace(""r", "", $input); $input = trim(chop(base64_decode($input))); $td = mcrypt_module_open('tripledes', '', 'ecb', ''); $key = substr(md5($key), 0, 24); $iv = mcrypt_create_iv(mcrypt_enc_get_iv_size($td), MCRYPT_RAND); mcrypt_generic_init($td, $key, $iv); $decrypted_data = mdecrypt_generic($td, $input); mcrypt_generic_deinit($td); mcrypt_module_close($td); return trim(chop($decrypted_data)); }

引用 5 楼 Chi King Chang 的回复:[quote=引用 1 楼 stherix 的回复:] 你确认加密方法 passphrase 都是对的吗 文件也是完整的吗 这是我HTTPRequest 对方返回的报文，解密方法的话用了openssl下面的des-ecb指令解码，但是返回输出bad magic[/quote]  你问了对方是-des-ecb加密的吗,passphrase也是53MP236N?

引用 1 楼 stherix 的回复:你确认加密方法 passphrase 都是对的吗 文件也是完整的吗 这是我HTTPRequest 对方返回的报文，解密方法的话用了openssl下面的des-ecb指令解码，但是返回输出bad magic

你用的不是DES-ECB模式么，和base64不是一种吧

你确认加密方法 passphrase 都是对的吗 文件也是完整的吗

用了linux自带的命令也不行 openssl enc -d -a -k 53MP236N -des-ecb -in return_decode.txt -out  return_encode.txt


Question: C语言函数模块的定义参数列表功能说明以及函数间的调用关系程序的详细结构

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


Question: PTA C语言666问题

能先说一下什么问题吗？另外，题目的需求是什么，但从代码去理解吗？如果但从代码去理解，代码是不是应该先没问题，所以 很矛盾。

int main() {     int n,sn=0,i,k=1;     scanf("%d",&n);     for(i=1;i<=n;i++)     {         sn=sn+k*6;         k=pow(10,i);     }     printf("%d\n",sn);     return 0;      }


Question: C语言这是一个计算时间的程序，把秒数转换为分钟和秒数

引用 1 楼 轻箬笠 的回复:while(sec > 0);//这个分号多余了好的谢谢，是我的认真度还不够，这么简单的问题也没发现，憋了好久。非常感谢第一时间回答我的问题。

while(sec > 0);//这个分号多余了

這個問題常常發生在打字太快

都是从菜鸟过来的。


Question: C语言考试

希望对你有帮助：https://blog.csdn.net/it_xiangqiang/category_10581430.html 希望对你有帮助：https://blog.csdn.net/it_xiangqiang/category_10768339.html

引用 2 楼 636f6c696e的回复:恭喜挂科，虽然楼主考完试是不会来看的 这么久了我还是来看了，没挂科，七十几

引用 1 楼 ggglivw的回复:还有30分钟考试完毕 没挂科欧，七十几，嘻嘻😄

😂😂😂😂😂这个没挂科，七十几分

恭喜挂科，虽然楼主考完试是不会来看的

还有30分钟考试完毕

看了一下，好像过了考试时间哦，那就不用写了，哈哈。。。。。 暑假愉快。。。


Question: Memery  c 代码实现(本人小白，希望大家提出问题)

引用 2 楼 user-2的回复:char  *src_t=(char  *)src; 这行需要加const。  memerycpy改成memorycpy。  还有同一块内存不同部位copy的时候有重叠的情况会有bug。 谢谢你 亲，可以指点一下怎么去规避这种bug呢，关于这点我没有想到过

逻辑理解上应该是对的， 但是由于coding不太规范， 可能会让你的这段source code编译失败。 不信， 可以将这段代码放到IDE里编译试试看.

char  *src_t=(char  *)src;


Question: 编写一个程序

引用 1 楼 user-1的回复:我希望公式没有敲错。  #include <stdio.h> #include <math.h>  #define NCNT 10000  double P = 206235.0; double E = 0.082; double L = 3.0; double A = 6378137.0;  double CalH(double mu) {     return E*cos(mu); }  double CalM(double mu) {     return A*(1-pow(E,2))/sqrt(pow(1-pow(E,2)*sin(mu),3)); }  double CalS(double mu) {     double s = 0, x = 0;     for(int i = 1; i < NCNT + 1; i ++)     {         x = (x + mu/NCNT);         s = s + CalM(x)*(mu/NCNT);     }     return s; }  double CalN(double mu) {     return A/sqrt(1-pow(E,2)*pow(sin(mu),2)); }  double getX(double mu) {     return CalS(mu) + pow(L,2)*CalN(mu)*sin(mu)*cos(mu)/(2*pow(P,2)) + pow(L,4)*CalN(mu)*sin(mu)*cos(mu)*(5-pow(tan(mu),2)+9*pow(CalH(mu),2)+4*pow(CalH(mu),4)); }  double getY(double mu) {     return L*CalN(mu)*cos(mu)/P +            pow(L,3)*CalN(mu)*pow(cos(mu),3)*(1-pow(tan(mu),2)+pow(CalH(mu),2))/(6*pow(P,3)) +            pow(L,5)*CalN(mu)*pow(cos(mu),5)*(5-180*pow(tan(mu),2)+pow(tan(mu),4)); }  int main() {     double x, y, mu;     mu = 46.0;     x = getX(mu);     y = getY(mu);     printf("X = %f,  Y = %f\r\n", x, y);     return 0; } 太感谢了，，，感谢相助。


Question: C++函数sprintf在安卓与PC下的区别

引用 9 楼 早打大打打核战争 的回复:用math.h的nearbyint：   fesetround(FE_TONEAREST);   printf("%.0lf\n", nearbyint(0.5));   printf("%.0lf\n", nearbyint(1.5)); 谢谢啦

引用 2 楼 赵4老师的回复:浮点数格式 http://bbs.csdn.net/topics/390676437 谢谢。不过我怀疑是不同系统之间的差异

对的。使用sprintf的%.0f，是四舍五入的。 只是同样的代码下，安卓与pc下的结果一直都不一样，安卓的这个结果还是固定的，试了五六台安卓设备，都是这样子。 精度应该是上下浮动，那应该会有概率的得到不同结果。 另外上面代码中，我换成使用round来获取四舍五入的值，则必定是进一的。 所以有点搞不懂这个的原理

引用 6 楼 早打大打打核战争的回复:这是编译器使用的round方法造成的，而且看起来fesetround无效，库函数printf、sprintf之类的使用固定的舍入方法，严格来说，安卓上的输出是对的，因为IEEE754定义了5种舍入方法，默认是roundTiesToEven，所以0.5转换到整数是0，1.5则是2 请问下，pc上面，没有采用这种标准是吗？

引用 6 楼 早打大打打核战争的回复:这是编译器使用的round方法造成的，而且看起来fesetround无效，库函数printf、sprintf之类的使用固定的舍入方法，严格来说，安卓上的输出是对的，因为IEEE754定义了5种舍入方法，默认是roundTiesToEven，所以0.5转换到整数是0，1.5则是2 果然是这个标准，好头晕。 还是谢谢啦

比如 double d1=1; double d0=0.5; d1 += d0; 不同的环境下,d1有可能是1.500000001也可能是1.49999999995 而sprintf的时候会四舍五入

double和float的数都存在精度问题的。


Question: 二级指针求助

str为一级指针数组，p为二级指针 第四行是二级指针p指向一级指针str 第五行是二级指针p降级一次变为一级指针，p指向的是str【0】的值，显示hello（提示：这里的星号表示降级和上面定义char的星号表示指针。数组不打中括号，默认首地址str【0】） 第六行是二级指针p的指向向下偏移一次再降级，指向的就是一级指针str[1]，打印出的就是the

数组里面存的应该是 【char *】【char *】【char *】 p是指向数组元素的指针。 p+1所指向的位置的移动长度就是sizeof(char *)，也就是说指向下一个数组元素。

p=str[0]的地址，*p=str[0]地址的内存信息=“hello” p+1=str[1]的地址，*(p+1)=str[1]地址的内存信息=“the” 依次类推


Question: 使用C语言读取特定编码的文件内容

这不扯呢吗？谁告诉你c语言默认是用utf8编码读取文件了，这明明跟文件和系统编码有关。 如果文件存的是gbk编码，文件内容是“中”，你觉得读出来的字节是两字节还是三字节？

参考 https://github.com/sunxfancy/ExIconv


Question: 我用fread写入一个链表进文件，但是读出来就出错了

p->next = head->next;         head->next = p; 感觉是这里错了吧，p是新申请的，那么应该把前一个结构体的成员赋值为p而不是把p的成员赋值为前一个成员的地址


Question: 这个要用c语言什么数据结构实现

每个单词用char[]存储，用一个链表存char[]的头指针，读取新单词的时候遍历查重


Question: 请大佬解答关于文件的写入问题

首先不要这么贴代码，搞得我还要重新给你排版，编辑框这里有个专门插入代码的功能。 我这里运行没有问题，重开后能够输出上一次录入的信息，你换DEV吧，我用DEV试的

引用 1 楼 六道佩恩的回复:贴代码，另希望及时结贴 已贴，见三楼，请大佬赐教

#include<stdio.h> #include<stdlib.h> #include<string.h> #include<conio.h> void save(); void luru(); void search(); void search_by_time(); void search_by_name(); void print(); void shanchu(); void setstate(); /*定义线性表的顺序存储类型*/ typedef struct { 	char number[10];/*班车车号*/ 	char model[20]; /*班车型号*/     int  seating;   /*座位数*/     char name[20];  /*司机姓名*/     char time[20];  /*发车时间*/ 	int  state;     /*班车状态*/ }mbus; /*声明校车数组及校车数量*/ typedef struct { 	mbus bus[1000]; 	int count; }mstop; mstop stop;/*定义类型为struct mstop的结构变量stop*/  int main() { 	int i; 	char c; 	char s[2]; 	FILE *fp;  /*定义1文件型指针变量，指针名叫fp*//*fp指向file类型结构体的指针*/ 	if((fp=fopen("stop.txt","rb"))==NULL)/*以写的方式打开stop*/ 		stop.count=0; 	else 	{ 		fread(&stop.count,sizeof(int),1,fp);/*读入一个结构体字符块到stop.count*/ 		fread(stop.bus,sizeof(stop.bus[1]),stop.count+1,fp);/*将stop.count+1读入到stop.bus*/ 		fclose(fp);/*关闭文件*/ 	}     printf("\n\n\n\t\t\t欢迎使用班车管理系统！\n");/*班车信息管理系统欢迎界面*/ 	printf("操作说明：\n");     printf("1.数据输入完成后按Enter键确认\n");     printf("2.班车信息状态栏中，1表示未发车，0表示已发车\n"); 	printf("3.对于录入的班车信息的状态，系统默认为1\n"); 	printf("4.如果为教师专用车，请在时间后加'*'\n"); 	printf("5.班车型号均为两字\n"); 	printf("6.请严格按照要求操作：\n"); 	printf("\n\n\t\t\t请按任意键继续");     getch(); 	while(c!='0') 	{ 		printf("\n\n\n\n\n");   		printf("\t\t 班车管理系统\n");  /*班车管理系统菜单选项*/ 		for(i=0;i<45;i++) 			printf("*"); 		printf("\n");         printf("\t\t0.退出\n");         printf("\t\t1.录入班车信息\n"); 		printf("\t\t2.班车信息查询\n"); 		printf("\t\t3.班车信息输出\n"); 		printf("\t\t4.删除班车信息\n"); 		printf("\t\t5.班车状态转换\n"); 		for(i=0;i<45;i++) 			printf("*"); 		printf("\n\n"); 		printf("请输入你的选择："); /*班车信息管理系统各个选项及其后继步骤*/ 		scanf("%1s",s); 	    c=s[0];         switch(c) 		{ 	    	case'1':luru();break; 		    case'2':search();break; 	     	case'3':print();break; 			case'4':shanchu();break; 	    	case'5':setstate();break; 			default:break; 		} 	} 	printf("\n\n\n\n\n\n\n\n\n\t\t\t\t谢谢使用!\n"); 	getch(); } void save()    {    FILE *fp;/*定义1文件型指针变量，指针名叫fp*//*fp指向file类型结构体的指针*/    fp=fopen("stop.txt","wb");/*以写的方式打开stop*/    fwrite(&stop.count,sizeof(int),1,fp);/*写入一个结构体字符块到stop.count*/    fwrite(stop.bus,sizeof(stop.bus[1]),stop.count+1,fp);/*将stop.count+1写入到stop.bus*/    fclose(fp);/*关闭文件*/ } void luru()    /*班车信息录入*/ { 	int a=1; 	while(a!=0) 	{ 		stop.count++; 		printf("录入班车信息\n"); 		printf("请输入班车车号："); 		scanf("%s",stop.bus[stop.count].number);         printf("请输入班车型号：");         scanf("%s",stop.bus[stop.count].model); 		printf("请输入座位数："); 		scanf("%d",&stop.bus[stop.count].seating); 		printf("请输入司机姓名："); 		scanf("%s",stop.bus[stop.count].name);         printf("请输入发车时间：");         scanf("%s",stop.bus[stop.count].time); 		stop.bus[stop.count].state=1; 		printf("退出请按0，继续请按1："); 		scanf("%d",&a); 	} 	save(); } void search()      /*查询班车信息*/ { 	int a; 	printf("-----------------班车信息查询---------------\n"); 	printf("\t\t1.司机姓名查询\n"); 	printf("\t\t2.发车时间查询\n"); 	printf("请选择查询方式："); 	scanf("%d",&a); 	switch(a) 	{ 		case 1:search_by_name();break;         case 2:search_by_time();break; 		default:break; 	} } void search_by_time()  /*按发车时间来查询班车信息*/ { 	int i,n=1; 	char a[20]; 	printf("请输入你要查找的班车发车时间："); 	scanf("%s",a); 	getchar();     printf("班车车号    \t班车型号      座位数   司机姓名     \t发车时间  \t班车状态\n"); 	for(i=1;i<=stop.count;i++) 	  if(strcmp(a,stop.bus[i].time)==0) 	  { 		 printf("%s\t%s\t\t%d\t%s\t\t%s\t\t%d\n",stop.bus[i].number,stop.bus[i].model,stop.bus[i].seating,stop.bus[i].name,stop.bus[i].time,stop.bus[i].state);/*显示车号，型号，座位数，司机姓名，发车时间，班车状态*/ 		 n=0; 	  } 	   if(n==1) 			printf("对不起，没有相应信息"); 		getch(); } void search_by_name()   /*按司机姓名来查询班车信息*/ { 	char a[20]; 	int n=1,i; 	printf("请输入你要查找班车的司机姓名："); 	scanf("%s",a); 	getchar();     printf("班车车号    \t班车型号      座位数   司机姓名     \t发车时间  \t班车状态\n"); 	for(i=1;i<=stop.count;i++)      if(strcmp(a,stop.bus[i].name)==0) 	 {         printf("%s\t%s\t\t%d\t%s\t\t%s\t\t%d\n",stop.bus[i].number,stop.bus[i].model,stop.bus[i].seating,stop.bus[i].name,stop.bus[i].time,stop.bus[i].state);/*显示车号，型号，座位数，司机姓名，发车时间，班车状态*/ 		n=0; 	 }        if(n==1)/*如果没有数据,显示对不起.....*/ 			printf("对不起，没有相应信息"); 		  getch(); } void print() { 	int i;     printf("班车车号    \t班车型号      座位数   司机姓名     \t发车时间  \t班车状态\n");     for(i=1;i<=stop.count;i++)         printf("%s\t%s\t\t%d\t%s\t\t%s\t\t%d\n",stop.bus[i].number,stop.bus[i].model,stop.bus[i].seating,stop.bus[i].name,stop.bus[i].time,stop.bus[i].state);/*显示车号，型号，座位数，司机姓名，发车时间，班车状态*/ 	  getch(); } void shanchu()   /*班车信息的删除*/ { 	int i,j,ch,n=0; 	char a[20],b[20]; 	printf("请输入要删除的班车的车号和发车时间\n"); 	printf("\t车号："); 	scanf("%s",a); 	getchar(); 	printf("\t发车时间："); 	scanf("%s",b); 	getchar();     for(i=1;i<=stop.count;i++) 		if((strcmp(a,stop.bus[i].number)==0)&&(strcmp(b,stop.bus[i].time)==0)) 		{ 			n=i;             printf("班车车号    \t班车型号      座位数   司机姓名     \t发车时间  \t班车状态\n");             printf("%s\t%s\t\t%d\t%s\t\t%s\t\t%d\n",stop.bus[i].number,stop.bus[i].model,stop.bus[i].seating,stop.bus[i].name,stop.bus[i].time,stop.bus[i].state);/*显示车号，型号，座位数，司机姓名，发车时间，班车状态*/ 			printf("是否删除信息？     1(是),0(否)"); 			scanf("%d",&ch); 			if(ch==1) 			{ 				for(j=i+1;j<=stop.count;j++) 					stop.bus[j-1]=stop.bus[j]; 				stop.count--; 			} 			else  				break; 		} 		save(); 		if(n==0) 		{ 			printf("班车信息输入有误"); 			getch(); 		} } void setstate()     /*班车状态转换*/  { 	 int i,a,n=1; 	 char ch[20]; 	 printf("请输入班车车号："); 	 scanf("%s",ch); 	 getchar(); 	 for(i=1;i<=stop.count+1;i++) 		 if((strcmp(ch,stop.bus[i].number))==0) 		 {              printf("班车车号    \t班车型号      座位数   司机姓名     \t发车时间  \t班车状态\n");          	printf("%s\t%s\t\t%d\t%s\t\t%s\t\t%d\n",stop.bus[i].number,stop.bus[i].model,stop.bus[i].seating,stop.bus[i].name,stop.bus[i].time,stop.bus[i].state);/*显示车号，型号，座位数，司机姓名，发车时间，班车状态*/ 			n=0;break; 		 } 		 if(n==0) 		 { 			 printf("状态转换（是（1），否（0）："); 			 scanf("%d",&a); 			 if(a==1) 			 { 				 if(stop.bus[i].state==1) 					 stop.bus[i].state=0; 				 else if(stop.bus[i].state==0) 					 stop.bus[i].state=1; 			 } 			 else if(a==0) 				 return; 			 else 				 return; 		 } 		 else 			 return;  }

盲猜你写入和读出的方式不同，比如你以字符串方式写入，却以整型读出

贴代码，另希望及时结贴


Question: 串口不存在

打开电脑的 device Manager，然后看看 Ports下面有没有COM2。  我估计现在的电脑90%都没有COM2了。

看下管理里面端口有没有com2


Question: 哪里错了，该怎么改呀，

另外，重复定义x，y --> 第4，5行前面int去掉； 先读入a，b，再计算x，y --> 调整下scanf语句和计算x，y语句顺序； scanf语句双引号里面最好不要加逗号，不然你读入的时候也要输入逗号 --> 把双引号里面逗号去掉，读入的时候以空格或者回车作为间隔

楼主写过hello world吗？为啥include语句后面还有分号啊？

建议 1) 去掉include后面的分号； 2) 去掉x = a + b; y = a - b；前面的int； 3) 完成上面的第2步后，把x = a + b; y = a -b;放到scanf语句之后；否则得不到你想要的结果；

还有第一行，#include <stdio.h>后面不要加分号

楼上说的对。 要么：int a,b,x,y;修改为int a,b; 要么：后面的int x = a+b修改为x=a+b; 即前面的int去掉。  还有要计算x,y的数值，应该在scanf后进行x=a+b;等运算。

x,y重复定义了 将int a,b,x,y;改为int a,b; 即可。

引用 7 楼 文言言 的回复:先输入a，b。再对x，y赋值  我也有这个疑问，，ab复制之前不能用这两个变量去初始化别的变量吧。。

先输入a，b。再对x，y赋值


Question: 数据结构c语言严版中的二叉树遍历中*visit

Visit是一个函数指针，他代表着一种处理当前结点data的方式 先序遍历的话，就是先visit(T->data),，然后再遍历左孩子和右孩子。 书上不是有个最简单的visit函数嘛，他直接打印了当前结点T的data。你就吧那个参数TElemType e看成 T->data就行了。 就是看你想怎么输出二叉树结点的数据就怎么写这个visit。 我自己理解书上的 status OK ERROR OVERFLOW  #define OK 0 #define ERROR -1 #define OVERFLOW -2  typedef int Status;


Question: 求大佬解一下这一题谢谢!

是连续return 0，否则return -1  int func_checkNum(int iNumber) { 	int iTemp = 0; 	 	if(iNumber < 10) 	{ 		return -1; 	} 	 	int iValue = iNumber%2; 	 	iTemp = iNumber/10; 	 	if(iValue == iTemp%2) 	{ 		return 0; 	} 	 	return func_checkNum(iNumber/10); }

别做伸手党，自己动手做做

循环提取连续两个位的数字判断和是否为偶就可以啦


Question: function' : incompatible types - from 'int [100]' to 'const char *'

先弄明白a是做什么的，为什么定义成int类型缺当成字符数组用

int a[100]={0}; int 数组为什么赋值成一个字符串？

编译器问题，如果不想换编译器，可以改成a[100]={}试试。 还有，命名风格弄好点，变量尽量有实际的意义，除非for里面的迭代临时变量，变量尽量初始化，避免雷。

i没有初始化，strlen要求的是char*，你传递的是int*

错的是 strlen(a) 不是定义初始化 a

将a[100]={'\0'}单独拿出来 写 char a[100]={0}; 即可解决 '\0'的值就是0，和写0是一样的