Question: uva455周期串问题  求好心人看看哪里错了提交就是wa

Two consecutive input will separated by a blank line.   这种时候不要用gets这种对空行敏感的输入。谁知道这数据会出成什么样子。

跟踪调试是必会技能。

我想知道我这个哪里错了，运行跟你那个一样啊。

#include <stdio.h>   #include <string.h>      #define MAXN 80      int strcmplen(char a[], int s, int t, int len)   {       int i;          for(i=1; i<=len; i++) {           if(a[s] != a[t])               return a[s] - a[t];              s++;           t++;       }          return 0;   }      int main(void)   {       int n, len, i, j;       char s[MAXN+1];          scanf("%d", &n);       while(n--) {           scanf("%s", s);              len = strlen(s);              for(i=1; i<len; i++) {               if(len % i)                   continue;                  for(j=i; j<len; j+=i)                   if(strcmplen(s, 0, j, i) != 0)                       break;                  if(j == len)                   break;           }              printf("%d\n", i);           if(n)               printf("\n");       }          return 0;   }   http://blog.csdn.net/tigerisland45/article/details/52056047


Question: 求解一个输出问题？

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

写着写着，第三个的%写成&呢 个人建议编译的时候不要放过任何警告；争取将警告也一并去掉；

scanf_s("%d%d&d",&a,&b,&c); -> scanf_s("%d%d%d",&a,&b,&c);

%d%d&d

看编译器错误提示，就算不能直接指出错误，也能大概知道错在哪一行了。

输入函数用的不对 详情百度scanf_s的用法  以上改为scanf也可以

为什么输出不了三个数？


Question: 自己找不出问题，求解

#include<stdio.h>  struct Stu {     char a[10];     char name[10];     int grade1;     int grade2;     int grade3;     int sum; };  int get_max_idx(struct Stu *arr, int len);  int main() {     static struct Stu stu[100];     int i,N,max,maxi;     scanf("%d",&N);     for(i=0;i<N;i++){         scanf("%s %s %d %d %d", stu[i].a, stu[i].name,&stu[i].grade1,&stu[i].grade2,&stu[i].grade3);         stu[i].sum=stu[i].grade1+stu[i].grade2+stu[i].grade3;     } #if 1     maxi = get_max_idx(stu, N); #else     max=stu[0].sum;     for(i=1;i<N;i++){         if(max<stu[i].sum){             maxi=i;             max=stu[i].sum;         }     } #endif     printf("%s %s %d",stu[maxi].name,stu[maxi].a,stu[maxi].sum);     return 0; }  int get_max_idx(struct Stu *arr, int len) {     int i;     int max_i = 0;      for (i = 1; i < len; i++)         if (arr[i].sum > arr[max_i].sum)             max_i = i;      return max_i;  } 参考一下吧；获取总成绩最大的算法你的是没问题的，我自己写了一个函数，比你的少用一个max变量；  去掉scanf中的'\n'，另外，a，name前面的&也一并去掉；因为数组名本身就是地址；  scanf("%s %s %d %d %d", stu[i].a, stu[i].name,&stu[i].grade1,&stu[i].grade2,&stu[i].grade3);

scanf去掉‘\n’

scanf("%d\n",&N); --> scanf("%d",&N); scanf("%s %s %d %d %d\n",&stu[i].a,&stu[i].name,&stu[i].grade1,&stu[i].grade2,&stu[i].grade3); --> scanf("%s %s %d %d %d",stu[i].a,stu[i].name,&stu[i].grade1,&stu[i].grade2,&stu[i].grade3); //数组不需加&


Question: 《c程序设计语言第二版 》14页，1.5.4 单词统计，例子运行无结果输出，求指导

引用 6 楼 儿童节 的回复:[quote=引用 5 楼 浪荡 的回复:] [quote=引用 1 楼 棉猴 的回复:] 个人感觉你的程序在while()循环中没有跳出来，也就是getchar()没有获取到EOF。 EOF是End Of File的简写，在MSDN中提到“To indicate a read error or end-of-file condition, getchar``returns EOF."就是说，当getchar()发生读取错误或者文件末尾时，getchar()函数返回EOF，而在Windows中，要用Ctrl+Z来表示EOF。所以，在输入字符串按下回车键之后，还要Ctrl+Z输入EOF。   求助大神，为什么我输入abc123 运行的结果是1 6 7  [/quote]  你啥时候把宏给改了？    #define OUT 0 //  #define OUT 1  [/quote]  感谢！！..没发现

引用 1 楼 棉猴 的回复:个人感觉你的程序在while()循环中没有跳出来，也就是getchar()没有获取到EOF。 EOF是End Of File的简写，在MSDN中提到“To indicate a read error or end-of-file condition, getchar``returns EOF."就是说，当getchar()发生读取错误或者文件末尾时，getchar()函数返回EOF，而在Windows中，要用Ctrl+Z来表示EOF。所以，在输入字符串按下回车键之后，还要Ctrl+Z输入EOF。   求助大神，为什么我输入abc123 运行的结果是1 6 7

引用 5 楼 浪荡 的回复:[quote=引用 1 楼 棉猴 的回复:] 个人感觉你的程序在while()循环中没有跳出来，也就是getchar()没有获取到EOF。 EOF是End Of File的简写，在MSDN中提到“To indicate a read error or end-of-file condition, getchar``returns EOF."就是说，当getchar()发生读取错误或者文件末尾时，getchar()函数返回EOF，而在Windows中，要用Ctrl+Z来表示EOF。所以，在输入字符串按下回车键之后，还要Ctrl+Z输入EOF。   求助大神，为什么我输入abc123 运行的结果是1 6 7  [/quote]  你啥时候把宏给改了？    #define OUT 0 //  #define OUT 1

#include <stdio.h>   #define IN 1 #define OUT 0   int main () {     int c, nl, nw, nc, state;       state = OUT;     nl = nw = nc = 0;     while ((c = getchar()) != EOF){         ++nc;         if (c == '\n')             ++nl;         if (c == ' ' || c == '\n' || c == '\t')             state = OUT;         else if (state == OUT){             state = IN;             ++nw;         }       }       printf("%d %d %d\n",nl,nw,nc);       return 0; } 没有输入怎么会有输出，程序在等待你的输入。 最后还要输入ctrl+D（Linux）或ctrl+Z(Windows）

输入完成，输入 ctrl+Z


Question: c程序设计语言第二版 14页，1.5.4 单词统计，例子运行无结果输出

#include <stdio.h>   #define IN 1 #define OUT 0   int main () {     int c, nl, nw, nc, state;       state = OUT;     nl = nw = nc = 0;     while ((c = getchar()) != EOF){         ++nc;         if (c == '\n')             ++nl;         if (c == ' ' || c == '\n' || c == '\t')             state = OUT;         else if (state == OUT){             state = IN;             ++nw;         }       }       printf("%d %d %d\n",nl,nw,nc);       return 0; } 没有输入怎么会有输出，程序在等待你的输入(getchar())。 最后还要输入ctrl+D（Linux）或ctrl+Z(Windows）

无结果输出 你是输入有问题吧 输入结束符才能输出


Question: 新人求助，同样大小数组matlab能算C分配不出来

容量大小从小到大：栈≤全局数据≤堆≤文件≤硬盘≤磁盘阵列≤云存储 当程序需要使用比如2GB～1TB左右的存储时，最简单的办法恐怕得是用文件读写模拟内存读写了吧。windows参考_fseeki64函数，linux参考fseeko64函数。 FILE *fA;fA=fopen("A","rb+");_fseeki64(fA,10000000000i64*sizeof(int),SEEK_SET);fputc(fA,0);//int A[10000000000]; int B; _fseeki64(fA,9999999999i64*sizeof(int),SEEK_SET);fread(&B,1,sizeof(int),fA);//B=A[9999999999]; _fseeki64(fA,9999999999i64*sizeof(int),SEEK_SET);fwrite(&B,1,sizeof(int),fA);//A[9999999999]=B; fclose(fA);

个人认为没必要一次性把所有数据需要的都放在内存，如果确实有这样的需求，可以试一试静态的变量static或全局变量；

C里面分配内存是连续的，所以问题应该出在没有连续15G的内存上。所以不要一次性分配这么大，用链表串起一系列的小块内存比较好。


int main int mian

现在又出现了这些错误   这是咋回事呢

你的Main函数没有得到定义，就算再怎么是.h文件，前面也应该有定义

main函数在.h文件中？

555文件连个后缀名都没有不应该是.c文件? 这个文件也没有添加到项目中去..为什么不好好看一下教程?

你的Main函数定义好了后，它所在的555.c文件也要添加到项目里，才能编译

有啊

没有main函数? 程序不知道入口 不知道从哪里开始运行


Question: c程序设计语言第2版部分例子运行结果无输出

命令行解释器概述 命令行解释器是一个单独的软件程序，它可以在用户和操作系统之间提供直接的通讯。非图形命令行解释器用户界面提供运行基于字符的应用程序和实用程序的环境。通过使用类似于 MS-DOS 命令解释程序 Command.com 的单独字符，命令行解释器执行程序并在屏幕上显示其输出。Windows 服务器操作系统命令行解释器使用命令解释程序 Cmd.exe（该程序加载应用程序并指导应用程序之间的信息流动）将用户输入转换为操作系统可理解的形式。 可以使用命令行解释器创建和编辑可自动执行常规任务的批处理文件（也称作脚本）。例如，可以使用脚本自动管理用户帐户或夜间备份。还可以使用 Windows 脚本宿主 CScript 的命令行版本在命令行解释器中运行更高级的脚本。详细信息，请参阅运行 Windows 脚本宿主。通过使用批处理文件来执行操作，可比使用用户界面更有效率。批处理文件接受命令行上可用的所有命令。有关批处理文件和脚本的详细信息，请参阅使用批处理文件。 您可以自定义命令提示符窗口以易于查看并增强对程序运行方式的控制。有关自定义命令提示符窗口的详细信息，请参阅配置命令提示符。  使用命令语法 语法按命令及所带参数必须遵循的键入顺序出现。下面的 xcopy 命令示例显示了各种语法文本格式：  xcopy Source [Destination] [/w] [/p] [/c] [/v] [/q] [/f] [/l] [/g] [/d[:MM-DD-YYYY]] [/u] [/i] [/s [/e]] [/t] [/k] [/r] [/h] [{/a | /m}] [/n] [/o] [/x] [/exclude:File1[+[File2]][+[File3]] [{/y | /-y}] [/z]  下表说明如何解释不同的文本格式。  格式化图例 格式                                             含义 斜体                                             用户必须提供的信息 粗体                                             用户必须准确键入的要显示的元素 省略号(...)                                      在命令行中可多次重复的参数 中括号([])                                       可选项 大括号({})；选项用竖线(|)分隔。例如：{even|odd}  用户必须从选项集合中选择一个 Courier字体                                      代码或程序输出  使用多个命令和条件处理符号 使用条件处理符号可以在单个命令行或脚本中运行多个命令。通过条件处理符号运行多个命令时，条件处理符号右边的命令根据条件处理符号左边命令的执行结果来发挥作用。例如，只有在前一个命令失败的情况下才可能需要运行一个新命令。或者，只有在前一个命令成功时才可能需要运行一个新命令。 可以使用下表列出的特殊字符来传递多个命令。  字符       语法                            定义 & [...]    Command1 & Command2             用来分隔一个命令行中的多个命令。Cmd.exe 运行第一个命令，然后运行第二个命令。 && [...]   Command1 && Command2            只有在符号 && 前面的命令成功时，才运行该符号后面的命令。Cmd.exe 运行第一个命令，然后只有在第一个命令运行成功时才运行第二个命令。 || [...]   Command1 || Command2            只有在符号 || 前面的命令失败时，才运行符号 || 后面的命令。Cmd.exe 运行第一个命令，然后只有在第一个命令未能运行成功（接收到大于零的错误代码）时才运行第二个命令。 ( ) [...]  (Command1 & Command2)           用来分组或嵌套多个命令。 ;或者,     Command1 Parameter1;Parameter2  用来分隔命令参数。  注意 “与”符号 (&)、管道符号 (|) 以及括号 () 是特殊字符，将它们作为参数传递时，必须在其前面加上转义字符 (^) 或引号。 如果某个命令成功完成操作，该命令就返回零 (0) 退出代码或不返回任何退出代码。有关退出代码的详细信息，请参阅 Microsoft Windows 部署和资源工具包。  嵌套命令行解释器 通过在命令提示符下打开新的 Cmd.exe 实例，可以在 Cmd.exe 内嵌套命令行解释器。默认情况下，Cmd.exe 的每个实例继承其父 Cmd.exe 应用程序的环境。通过嵌套 Cmd.exe 的实例，可以更改局部环境，而不会影响 Cmd.exe 的父应用程序。这使您能够保留 Cmd.exe 的原始环境，并在终止嵌套的命令行解释器之后返回到原始环境。但是在嵌套的命令行解释器中所做的更改将不会被保存。 要嵌套命令行解释器，请在命令提示符下键入：  cmd  出现类似于下面内容的消息：  Microsoft (R) Windows Server 2003 Standard Edition (TM) (C) 版权所有 1985-2002 Microsoft Corp. 要关闭嵌套的命令行解释器，请键入 exit。  使用 setlocal 和 endlocal 命令，可以在 Cmd.exe 的实例中（或在脚本中）进一步将更改局部化。Setlocal 创建局部作用范围，而 endlocal 终止局部作用范围。在 setlocal 和 endlocal 作用范围内所做的更改将会被放弃，从而保持原始环境不变。这两个命令的嵌套最高可达到 32 级。有关 setlocal 和 endlocal 命令的详细信息，请参阅 Setlocal 和 Endlocal。  将环境变量与 Cmd.exe 一起使用 Cmd.exe 命令行解释器环境由确定命令行解释器和操作系统行为的变量进行定义。可以使用两种类型的环境变量（系统和局部）来定义命令行解释器环境或整个操作系统环境的行为。系统环境变量定义全局操作系统环境的行为。局部环境变量定义 Cmd.exe 当前实例环境的行为。 系统环境变量预置于操作系统之中，并可用于所有 Windows 服务器操作系统进程。只有具有管理凭据的用户才可以更改系统变量。这些变量最常用于登录脚本。 局部环境变量只有在创建变量时针对的目标用户登录到计算机时才有效。HKEY_CURRENT_USER 配置单元中设置的局部变量只对当前用户有效，但它们可定义全局操作系统环境的行为。  下表按优先顺序的降序描述变量的各种类型： 1.内置系统变量 2.在 HKEY_LOCAL_MACHINE 配置单元中找到的系统变量 3.在 HKEY_CURRENT_USER 配置单元中找到的局部变量 4.在 Autoexec.bat 文件中设置的所有环境变量和路径 5.在登录脚本（如果有的话）中设置的所有环境变量 6.在脚本或批处理文件中交互使用的变量  在命令行解释器中，Cmd.exe 的每个实例都继承其父应用程序的环境。因此，可以在不影响父应用程序环境的情况下更改新的 Cmd.exe 环境中的变量。 下表列出 Windows server operating system 的系统和本地环境变量。  变量                     类型       描述 %ALLUSERSPROFILE%        本地       返回“所有用户”配置文件的位置。 %APPDATA%                本地       返回默认情况下应用程序存储数据的位置。 %CD%                     本地       返回当前目录字符串。 %CMDCMDLINE%             本地       返回用来启动当前的Cmd.exe的准确命令行。 %CMDEXTVERSION%          系统       返回当前的“命令处理程序扩展”的版本号。 %COMPUTERNAME%           系统       返回计算机的名称。 %COMSPEC%                系统       返回命令行解释器可执行程序的准确路径。 %DATE%                   系统       返回当前日期。使用与date/t命令相同的格式。由Cmd.exe生成。有关date命令的详细信息，请参阅Date。 %ERRORLEVEL%             系统       返回上一条命令的错误代码。通常用非零值表示错误。 %HOMEDRIVE%              系统       返回连接到用户主目录的本地工作站驱动器号。基于主目录值而设置。用户主目录是在“本地用户和组”中指定的。 %HOMEPATH%               系统       返回用户主目录的完整路径。基于主目录值而设置。用户主目录是在“本地用户和组”中指定的。 %HOMESHARE%              系统       返回用户的共享主目录的网络路径。基于主目录值而设置。用户主目录是在“本地用户和组”中指定的。 %LOGONSERVER%            本地       返回验证当前登录会话的域控制器的名称。 %NUMBER_OF_PROCESSORS%   系统       指定安装在计算机上的处理器的数目。 %OS%                     系统       返回操作系统名称。Windows2000显示其操作系统为Windows_NT。 %PATH%                   系统       指定可执行文件的搜索路径。 %PATHEXT%                系统       返回操作系统认为可执行的文件扩展名的列表。 %PROCESSOR_ARCHITECTURE% 系统       返回处理器的芯片体系结构。值：x86或IA64（基于Itanium）。 %PROCESSOR_IDENTFIER%    系统       返回处理器说明。 %PROCESSOR_LEVEL%        系统       返回计算机上安装的处理器的型号。 %PROCESSOR_REVISION%     系统       返回处理器的版本号。 %PROMPT%                 本地       返回当前解释程序的命令提示符设置。由Cmd.exe生成。 %RANDOM%                 系统       返回0到32767之间的任意十进制数字。由Cmd.exe生成。 %SYSTEMDRIVE%            系统       返回包含Windowsserveroperatingsystem根目录（即系统根目录）的驱动器。 %SYSTEMROOT%             系统       返回Windowsserveroperatingsystem根目录的位置。 %TEMP%和%TMP%            系统和用户 返回对当前登录用户可用的应用程序所使用的默认临时目录。有些应用程序需要 TEMP，而其他应用程序则需要 TMP。 %TIME%                   系统       返回当前时间。使用与time/t命令相同的格式。由Cmd.exe生成。有关time命令的详细信息，请参阅Time。 %USERDOMAIN%             本地       返回包含用户帐户的域的名称。 %USERNAME%               本地       返回当前登录的用户的名称。 %USERPROFILE%            本地       返回当前用户的配置文件的位置。 %WINDIR%                 系统       返回操作系统目录的位置。  设置环境变量 使用 set 命令创建、更改、删除或显示环境变量。set 命令只更改当前解释器环境中的变量。  要查看变量，请在命令提示符下键入：  set VariableName  要添加变量，请在命令提示符下键入：  set variablename=Value  要删除变量，请在命令提示符下键入：  set VariableName=  可以将大多数字符用作变量值，其中包括空格。如果使用特殊字符 <、>、|、& 或 ^，则必须在它们前面加上转义字符 (^) 或引号。如果使用引号，则必须将引号作为值的组成部分，因为等号后面的任何内容都会被视为值。请考虑下列示例：  要创建变量值 new&name，请键入： set varname=new^&name  要创建变量值 "new&name"，请键入： set varname="new&name"  如果在命令提示符下键入 set varname=new&name，就会出现与下面内容类似的错误消息： “'name' 不是内部或外部文件，也不是可运行的程序或批处理文件。” 变量名不区分大小写。但是，set 显示的变量与您键入的完全相同。可以在变量名中结合使用大写字母和小写字母，这样可以使代码更具有可读性（例如，UserName）。  注意  单个环境变量的最大大小为 8192 字节。 所有环境变量的大小总和（包括变量名和等号）最大为 65,536 KB。 替换环境变量值 要在命令行或脚本中启用变量值替换，请将变量名包括在百分号之中（即，%VariableName%）。使用百分号可以确保 Cmd.exe 引用变量值，而不是进行文字比较。为变量名定义变量值之后，请将变量名包括在百分号之中。Cmd.exe 搜索该变量名的所有实例，并用定义的变量值进行替换。例如，如果创建包含不同值（例如，用户名）的脚本，并且想要用这些值为每个用户定义 USERNAME 环境变量，可以使用包括在百分号之中的 USERNAME 来编写代码。运行此脚本时，Cmd.exe 将用变量值替换 %USERNAME%，这样就消除了为每个用户手动执行此任务的必要。变量替换是不可递归的。Cmd.exe 检查变量一次。有关变量替换的详细信息，请参阅 For 和 Call。

使用命令重定向操作符可以使用重定向操作符将命令输入和输出数据流从默认位置重定 向到不同的位置。输入或输出数据流的位置即为句柄。  下表将列出可用的句柄。  句柄      句柄的数字代号 描述 STDIN     0              键盘输入 STDOUT    1              输出到命令提示符窗口 STDERR    2              错误输出到命令提示符窗口 UNDEFINED 3-9            这些句柄由应用程序单独定义，并且是各个工具特定的。  数字 0 到 9 代表前 10 个句柄。可以使用命令 Cmd.exe 运行程序并将该程序前 10 个 句柄中的任何一个重定向。要指定想使用的句柄，可在重定向操作符前面键入该句柄的 数字。如果未定义句柄，则默认的 < 重定向输入操作符是 0，而默认的 > 重定向输出 操作符是 1。键入 > 或 < 操作符之后，必须指定要读取或写入数据的位置。可以指定 文件名或另一个现有的句柄。  要指定重定向到现有句柄，请使用与 (&) 字符，后面接要重定向的句柄号 （例如 &句柄#）。例如，下面的命令可以将句柄 2（即 STDERR）重定向到 句柄 1（即 STDOUT）：  2>&1  下表列出了可用于将输入和输出数据流进行重定向的操作符。  重定向操作符 描述 > 将命令输出写入到文件或设备（例如打印机）中，而不是写在命令提示符窗口或句柄中。 < 从文件中而不是从键盘或句柄中读入命令输入。 >> 将命令输出添加到文件末尾而不删除文件中的信息。 >& 将一个句柄的输出写入到另一个句柄的输入中。 <& 从一个句柄读取输入并将其写入到另一个句柄输出中。 | 从一个命令中读取输出并将其写入另一个命令的输入中。也称作管道。  默认情况下，可以从键盘将命令输入（即 STDIN 句柄）发送到 Cmd.exe，然后由 Cmd.exe 将命令输出（即 STDOUT 句柄）发送到命令提示符窗口。  重定向输入 (<) 要将键盘输入重定向到文件或设备，请使用 < 操作符。例如，要从 File.txt 获取 sort 命令的输入，请键入：  sort<file.txt  File.txt 的内容将以字母顺序列表的方式显示在命令提示符窗口中。  < 操作符可以打开具有只读访问的指定文件名。所以，不能使用该操作符向文件中写入 信息。例如，如果以 <&2 启动程序，则所有试图读取句柄 0 的操作都将失败，因为句 柄 2 最初是以只写访问打开的。   注意  0 是 < 重定向输入操作符的默认句柄。 重定向输出 (>) 几乎所有的命令都将输出发送到命令提示符窗口。即使将输出发送到驱动器或打印机的 命令也会在命令提示符窗口显示消息和提示。  要将输出从命令提示符窗口重定向到文件或设备，请使用 > 操作符。可以在许多命令中 使用该操作符。例如，要将 dir 输出重定向到 Dirlist.txt，请键入：  dir>dirlist.txt  如果 Dirlist.txt 不存在，Cmd.exe 将创建该文件。如果 Dirlist.txt 存在，Cmd.exe 将使用 dir 命令的输出替换文件中的信息。  要运行 netsh routing dump 命令，然后将输出发送到 Route.cfg，请键入：  netsh routing dump>c:\route.cfg  > 操作符可以打开具有只写访问属性的指定文件。所以，不能使用该操作符读取文件。 例如，如果使用重定向 >&0 启动程序，则所有试图写入句柄 1 的操作都将失败，因为 句柄 0 最初是以只读访问打开的。   注意  1 是 > 重定向输出操作符的默认句柄。 复制句柄 重定向操作符 & 可以将输出或输入从一个指定句柄复制到另一个指定的句柄。例如， 要将 dir 输出发送到 File.txt 并将错误输出发送到 File.txt，请键入：  dir>c:\file.txt 2>&1  复制句柄时，可以复制该句柄原状态的所有特性。例如，如果一个句柄具有只写访问的 属性，则该句柄的所有副本都具有只写访问属性。不能将一个具有只读访问属性的句柄 复制到另一个具有只写访问属性的句柄。  使用 & 操作符重定向输入和副本 要将重定向输入操作符 (<) 与复制操作符 (&) 一起使用，指定的文件必须已经存在。 如果输入文件存在，Cmd.exe 将以只读方式打开该文件，然后将文件中包含的字符作为 输入发送到此命令（如同从键盘输入一样）。如果指定了句柄，Cmd.exe 将指定的句柄 复制到系统现有的句柄中。  例如，要以句柄 0 输入读取（即 STDIN）的方式打开 File.txt，请键入：  <file.txt  要打开 File.txt，并在内容排序后将输出发送到命令提示符窗口（即 STDOUT），请键入：  sort<file.txt  要查找 File.txt，然后将句柄 1（即 STDOUT）和句柄 2（即 STDERR）重定向到 Search.txt，请键入：  findfile file.txt>search.txt 2<&1  要以句柄 0 输入读取（即 STDIN）的方式复制用户定义句柄 3，请键入：  <&3  使用 & 操作符重定向输出和复制 如果将输出重定向到文件且指定了现有的文件名，Cmd.exe 将以只写方式打开文件并覆 盖该文件内容。如果指定了句柄，Cmd.exe 将文件复制到现有句柄中。  要将用户定义句柄 3 复制到句柄 1，请键入：  >&3  要将包括句柄 2（即 STDERR）的所有输出从 ipconfig 命令重定向到 句柄 1（即 STDOUT），然后将输出重定向到 Output.log，请键入：  ipconfig.exe>>output.log 2>&1  使用 >> 重定向操作符追加输出 要从命令中将输出添加到文件末尾而不丢失文件中已存在的任何信息，请使用两个连续 的大于号（即 >>）。例如，下面的命令可以将由 dir 命令生成的目录列表追加到 Dirlist.txt 文件：  dir>>dirlist.txt  要将 netstat 命令的输出追加到 Tcpinfo.txt 的末尾，请键入：  netstat>>tcpinfo.txt  使用管道操作符 (|) 管道操作符 (|) 可以提取一个命令的输出（默认情况下是 STDOUT），然后将其导入另 一个命令的输入中（默认情况下是 STDIN）。例如，下面的命令将对目录分类：  dir | sort  在本例中，将同时启动两个命令，但随后 sort 命令会暂停，直到它接收到 dir 命令 的输出为止。sort 命令使用 dir 命令的输出作为输入，然后将输出发送到 句柄 1（即 STDOUT）。  合并带重定向操作符的命令 可以通过合并带有其他命令和文件名的筛选器命令创建自定义命令。例如，可以使用以 下命令存储包含“LOG”字符串的文件名:  dir /b | find "LOG" > loglist.txt  dir 命令的输出通过 find 筛选器命令发送。包含字符串 "LOG" 的文件名作为文件名 列表（例如，NetshConfig.log、Logdat.svd 和 Mylog.bat）存储在文件 Loglist.txt 中。  要在相同命令中使用多个筛选器，请使用管道 (|) 分隔筛选器。例如，下面的命令将 搜索 C 盘上的每个目录以查找包含 "LOG" 字符串的文件名，并且在命令提示符窗口中 每次显示一屏：  dir c:\ /s /b | find "LOG" | more  利用管道 (|) 可以将 Cmd.exe 导向为通过 find 筛选器命令发送 dir 命令输出。 find 命令只选择包含字符串 "LOG" 的文件名。more 命令可以显示由 find 命令选择 的文件名（在命令提示符窗口中每次显示一屏）。有关筛选器命令的详细信息，请参阅 使用筛选器。

你需要输入EOF才会结束循环，进而输出，EOF在WINDOWS下可以CTRL+Z

#include <stdio.h>  #define IN 1 #define OUT 0  int main () {     int c, nl, nw, nc, state;      state = OUT;     nl = nw = nc = 0;     while ((c = getchar()) != EOF){         ++nc;         if (c == '\n')             ++nl;         if (c == ' ' || c == '\n' || c == '\t')             state = OUT;         else if (state == OUT){             state = IN;             ++nw;         }      }      printf("%d %d %d\n",nl,nw,nc);      return 0; } 没有输入怎么会有输出，程序在等待你的输入。 最后还要输入ctrl+D（Linux）或ctrl+Z(Windows）

如下运行：


Question: 两个乒乓球队进行比赛，各出三人。甲队为a,b,c三人，乙队为x,y,z三人。已抽签决定比赛名单。有人向队员打听比赛的名单。a说他不和x比，c说他不和x,z比，请

我还是不懂这个答案是什么意思，能解释下为啥要用三个循环吗

循环其实用的是字符所对应的ASCII码值。

引用 4 楼 qq_40790112 的回复:我还是不懂这个答案是什么意思，能解释下为啥要用三个循环吗 就好比 （a,b,c）(x,y,z)找符合上述要求的比赛规格。 肯定要依次判断呀： a和x比，和y比，和z比 同样b也可以与xyz比 c也可以与xyz比 理论上相当于次数3*3*3=27次。（三次循环的理由） 但是 同一个人只能和一个人比，从而程序中就加了 这样 if(i!=j)的判断，来避免一人多比。  道理就是这样，但是这个算法虽然能实现，但是效率低。

字符类型char or unsigned char是int类型的子集，当然可以使用。 不但字符可以，double/float也是可以的。

计算机中所用的都是ASCII码，而'X'的ASCII码是58H，而'Z'的ASCII码是5AH，是可以放在for循环的呀

计算机里是不存在什么字母的，所有char类型字符都是以ASCII码的形式存储在内存中 也就是说 'A'(65)＜'B'(66)


Question: 小白求解释

应该是输入法的问题

楼上几位大神已说

也许你的负号 输入的是中文负号 也就是全角的负号

代码应该是没有问题

没问题啊，我这编译出来运行结果也是对的

刚才测试了一下，如果逗号是中文，则就像你说的，sum是负数  如果是英文逗号，则正常  估计是你把逗号写成中文逗号了

VS2015+Windows10 64位测试正常  是否把英文逗号写成中文逗号了？

引用 3 楼 user-11 的回复:[quote=引用 2 楼 Intel0011的回复:]int a,b,sum=0; sum必须初始化为0 这里不需要初始化sum，看清楚咯[/quote] 是的，眼花了

问题说得不清楚，怎么不能正常运算。最好截个图。

#include<stdio.h> #include<stdlib.h>  int main() {     int a, b, sum; //,Cha,Ji,Shan;     printf("请输入两个整数用逗号隔开\n");     scanf("%d,%d",&a,&b);     sum = a+b;     printf("sun=%d\n",sum);     system("pause");     return 0; } 代码没问题； 不需要的变量建议注释掉，定义就会分配空间，即使你不用。

可正常运行，估计是你自身环境问题

#include<stdio.h> #include<stdlib.h> int main() { 	int a; 	int b; 	int sum = 0; 	printf("请输入两个整数用逗号隔开\n"); 	scanf("%d,%d",&a,&b); 	sum=a+b; 	printf("sun=%d\n",sum); 	system("pause"); 	return 0; }

引用 2 楼 Intel0011的回复:int a,b,sum=0; sum必须初始化为0 这里不需要初始化sum，看清楚咯

int a,b,sum=0; sum必须初始化为0

负责人的告诉你是没有问题的，应该是你的输入法问题或者编译器问题，我调试正常运行


Question: c/c++,密码有效期的函数

引用 27 楼 zhao4zhong1 的回复:[quote=引用 25 楼 DelphiGuy 的回复:] [quote=引用 24 楼 zhao4zhong1 的回复:] 使用北斗卫星校准时间！  你咋不让他买俩原子钟呢...  [/quote] 估计买原子钟花钱多多了。[/quote]  那肯定，最便宜的铷原子钟也要一万多，几百年误差一秒，当然二手拆机的也就几百到一两千，这种廉价原子钟精度还是不如北斗授时的，北斗授时精度可以达到误差0.3纳秒以内。

引用 24 楼 zhao4zhong1 的回复:使用北斗卫星校准时间！  你咋不让他买俩原子钟呢...

使用北斗卫星校准时间！

学习路过顶

引用 25 楼 DelphiGuy 的回复:[quote=引用 24 楼 zhao4zhong1 的回复:] 使用北斗卫星校准时间！  你咋不让他买俩原子钟呢...  [/quote] 估计买原子钟花钱多多了。

我是这样想的，客户端有公钥，服务器有私钥，客户端将时间加密，上送到服务器，服务器解密校验看看是不是允许通讯

网游可能涉及到防外挂机制了，确实比较复杂。

引用 20 楼 hzy_76 的回复:不改变长度和字节序？这个要求貌似不是很必要啊，只要在原程序收到之前，被你的程序先解密，原程序收到的依然是正确的数据就够了吧。如果这样的话，就可以考虑压缩和全文加密了。  如果非要这么严格，我给你提供一个思路，不见得好，帮你拓展一下思维：第一个字节转为十进制然后取个位数，按这个数再去取另一个序号的数据，比如02 AB 3F 90这样的头部，按第一个字节02去取第3个字节3F，这个数就用来做密钥的种子。加密时，对第一个字节、所选取的另一个字节（本例中是第3个）不加密。收到数据时也按此思路，保持这两个字节不解密。  这样做不复杂，结果的规律性也不强，你觉得呢？ 你的这个方法我也试过，奇怪的事，在普通聊天程序上没任何问题，因为没有被HOOK的程序本身就没有其它复杂的字节验证什么的， 但现在碰到的这个网游程序，他本身就有一些验证规则，他的程序是WSARecv接收数据的，不知道他程序怎么处理的，一但不是一个字节一个字节处理他就会强制断开这个socket，你说的先看前一个字节，再处理后一个字节就显然 不行了，只要不是单独处理单字节 就会被断开

引用 16 楼 hzy_76 的回复:关于时间同步问题，我没测试过如果都同步网络时间的话，能不能达到秒级的一致性。我们以前做过设备时间同步的，有一个时间同步协议，感兴趣的话可以去找来看看。基本的原理我可以在这里给你说说： 首先有一个很重要的假设，就是一来一回两次的数据包传输时间一样。机器A发包时打上时间戳，记为t1，机器B收到包时记录时间T2，回复包时打上另一个时间戳T2，机器A收到回复时记录时间t2。此时机器A可以得知其发包到收到回复的时间是t2 - t1，而机器B的业务处理时间是T2 - T1，则单程的传输时间为((t2 - t1) - (T2 - T1))/2，因为已知机器B的发包时间是T2，因此机器A就可以把自己的时间校正为T2 + ((t2 - t1) - (T2 - T1))/2，即跟机器B同步。 可以看出来这个算法的误差，一是传输时间是否绝对一样，二是设置本地时间所耗费的时间。但是我想这个精度应该已经能满足你的需要了。你可以把这几个时间戳加到数据通讯的报文里，不必单独做时间同步协议，抽取一定比例的数据包中的时间戳用来校正时间就可以了。 你说的这些我也早想过，但如果加个前提 ， 这个前提就是在不改变原数据的长度和字节序的情况下（首先这些程序是客户的，我们是在没有程序源码的情况下给这些客户的程序封包加解密，要求不允许改变原始数据长度和字节序），给这些要发送的数据加密，那只能单字节加密，单字节加解密的缺点是太容易看得懂了，比如客户程序有时候 会在短时间内连续发送数据"01 02 00 00 08 08 FF 00 00 AD 00 00"这样的数据,单字节加密，又不可以改这些数据的序列，如果用固定密钥加密，那么加密后的数据还是会变成连续的“xxxxxxxxx”什么的，所以我想到用时间seed做可变的密钥，这样数据就不会还是连续的"xxxxxxxx"，就会变成杂乱无章的字节序。而且老板不允许增加网络开销，其实倒不是怕有什么开销，主要是怕我们的程序hook客户的程序后另发数据包会给客户程序原本的通信验证带来难度，导致各种有可能不稳定的因素。 所以你看在不改变原数据的长度和字节序的还有不发送额外数据情况下怎么做单字节加解密，然后加密后的数据要看起来杂乱无章呢？

引用 15 楼 baidu_37097818 的回复:自相矛盾，照你的说法，所有时间都只能是同一个值了。1分0秒的密码必须和1分30的密码一样，1分30秒的密码又必须和2分0秒的密码一样，2分0秒的密码又必须和2分30秒的密码一样，2分30秒的密码又必须和3分0秒的密码一样，…… 嗯，你这个比喻很到位，确实是我疯了，想多了。哈哈。

不好意思，手误，其中一句要纠正一下： 机器B收到包时记录时间T1

感谢“老马何以识途”和“早打大打打核战争”你们两位，好像就你们俩位明白我的意思 我最后想了想，在不可能互相通信的情况下，就算时间严格一致也做不到 	for (int i = 0; i < 60; i++) 	{ 		getkey(xx分xx秒) = getkey(xx分xx秒 + i) 	} 帖子先留着看看有没有人讨论吧，明天再来看看

只要两台设备从同一时间服务器定时同步，保证双方时间误差小于一秒就可以。比如这个东西就是每分钟生成一个动态密码：

想了一下，还有另一个做法，更新密钥时也通过加密通讯告知对方，但还用旧密钥通讯，对端收到新的密钥后保存下来，这个过程必须保证可靠，即发送方要确认对端已经收到。确认后方可删除本地旧密钥。

引用 8 楼 micckkk 的回复:客户端的数据需要通过密钥加密，然后服务端通过 这个密钥解密数据，这个密钥就是以上我想问的有时效的密钥 以上通信是严格控制的，也无法多附加任何其实数据的传输，只能传输指定的数据。所以没法传输密钥。 唯一共同点就是日期和时间  那么你这个方案就有很大问题，因为首次生成密钥的时间无法同步，即使时间严格一致，也没办法保证知道对方更新密钥的具体秒数——这个数据若要传输必须通过加密通讯，而新的密钥对方却不知道！发现陷入了一个悖论没？ 解决办法呢，一是大家都从每分钟的开始更新密钥，二是更新时间通过不加密手段告知对方。  但是我还有另一个疑问，你能保证两台设备的时间严格一致吗？

两端平台一样的话可以用伪随机解决啊	time_t t=time(0); 	t=t-t%60; 	srand(t); 	int encode_key=rand();		//这里可以约定循环取几次  拿到key就随便搞了

取秒计数，比如用time()函数，再整除以60得到分计数，以分计数来生成密码就可以。


Question: 程序要求输出一维数组中的最小值和下标，运行后得不到正确结果。

请看代码，你写的有问题  #include <stdio.h> #include<time.h> #include<stdlib.h> int main() { 	int x[20], n; 	int min = 0; 	int min_sub = 0; 	srand(time(0));  	for (n = 0; n <= 19; n++) 		x[n] = rand() % 100; 	for (n = 0; n <= 19; n++) 		printf("%3d", x[n]); 	min = x[0]; 	for( n = 1; n <= 19; n++) 	{ 		if(x[n] <= min) 		{ 			min = x[n]; 			min_sub = n; 		} 	} 	printf("\n%d   ", min); 	printf("下标是%d", min_sub); 	return 0; }

for(n=0,flag=0;n<=19&&flag==1;n++) flag一开始为0，就不满足flag==1，所以直接退出循环

#include <stdio.h> #include <time.h> #include <stdlib.h>  int get_min_idx(int *arr, int len); int main() {     int  x[20], min;     int i;      srand(time(0));      for(i = 0; i <= 19; i++)         x[i] = rand()%100;     for(i = 0; i <= 19 ; i++)         printf("%3d", x[i]);      min = get_min_idx(x, 20);      printf("\n%d, idx = %d\n", x[min], min);  #if 0     for(n=0,flag=0;n<=19&&flag==1;n++)          for(i=0;i<=19;i++)         { if(x[n]<=x[i])             ;             else                 flag=1;         }   #endif }  int get_min_idx(int *arr, int len) {     int i;      int min = 0;     for (i = 1; i < len; i++)         if (arr[min] > arr[i])             min = i;      return min; } 参考一下吧

flag只在外层循环开始时初始化为0，而后内层循环中如果找到一个数比X[n]小，flag就被设置为1了，而外层循环的下一次执行并不会重新把他设为0，所以只有当第一个数是最小数时才正确。因此这块代码应该这么写：  for(n=0; n <= 19 && flag == 1; n ++) { 	flag = 0; 	for(i = 0; i <= 19; i ++) 	{ 		if(x[i] < x[n]) 		{ 			flag=1; 			break; 		} 	} }

设置断点进行单步调试


Question: 【C语言】求s=a+aa+aaa+aaaa+aa...a的值

2 楼  正解。  2 楼  正解。

int a, b,c;  	scanf_s("%d%d",&a,&c); 	for (b = 0; b < c; b++) 	{ 		a=(a * 10+a); 	}  	printf("%d", a);

//求和 int sum(int a, int n){     int sum = 0, i = 1;     //个位相加，十位相加，百位相加     while (n) {         sum += a*i*n;         i *= 10;         n--;     }      return sum; }

s=0, 放到循环里面

Format Specification Fields: scanf and wscanf Functions A format specification has the following form:  % [width] [{h | l | I64 | L}]type  The format argument specifies the interpretation of the input and can contain one or more of the following:   White-space characters: blank (' '); tab ('\t'); or newline ('\n'). A white-space character causes scanf to read, but not store, all consecutive white-space characters in the input up to the next non–white-space character. One white-space character in the format matches any number (including 0) and combination of white-space characters in the input.   Non–white-space characters, except for the percent sign (%). A non–white-space character causes scanf to read, but not store, a matching non–white-space character. If the next character in stdin does not match, scanf terminates.   Format specifications, introduced by the percent sign (%). A format specification causes scanf to read and convert characters in the input into values of a specified type. The value is assigned to an argument in the argument list.  The format is read from left to right. Characters outside format specifications are expected to match the sequence of characters in stdin; the matching characters in stdin are scanned but not stored. If a character in stdin conflicts with the format specification, scanf terminates, and the character is left in stdin as if it had not been read.  When the first format specification is encountered, the value of the first input field is converted according to this specification and stored in the location that is specified by the first argument. The second format specification causes the second input field to be converted and stored in the second argument, and so on through the end of the format string.  An input field is defined as all characters up to the first white-space character (space, tab, or newline), or up to the first character that cannot be converted according to the format specification, or until the field width (if specified) is reached. If there are too many arguments for the given specifications, the extra arguments are evaluated but ignored. The results are unpredictable if there are not enough arguments for the format specification.  Each field of the format specification is a single character or a number signifying a particular format option. The type character, which appears after the last optional format field, determines whether the input field is interpreted as a character, a string, or a number.   The simplest format specification contains only the percent sign and a type character (for example, %s). If a percent sign (%) is followed by a character that has no meaning as a format-control character, that character and the following characters (up to the next percent sign) are treated as an ordinary sequence of characters, that is, a sequence of characters that must match the input. For example, to specify that a percent-sign character is to be input, use %%.  An asterisk (*) following the percent sign suppresses assignment of the next input field, which is interpreted as a field of the specified type. The field is scanned but not stored.

空白字符会使scanf()函数在读操作中略去输入中的一个或多个空白字符，空白符可以是space,tab,newline等等，直到第一个非空白符出现为止

你的代码有问题 scanf 使用错误 两个%d之间不能有空格

#include <stdio.h> #include <math.h>   int main(void) { #if 1      int digit, num, s = 0, total = 0;     int i, k = 1;     scanf("%d%d", &digit, &num);      if (num >= 10)         return 0;      while (k <= num) {         for (i = 1; i < k; i++)             s += digit * pow(10, i);         s += digit;         printf("s = %d\n", s);         total += s;         s = 0;         k++;     }     printf("total = %d\n", total);  #else     int a,n,s,p,i,d;     scanf("%d %d",&a,&n);     s=0;     p=0;     for(i=1; i<=n; i=i+1)     {         for(d=1; d<=i; d=d+1)         {             s=s*10+a;         }         p=p+s;       }     printf("%d\n",p); #endif      return 0; }  参考一下吧

当i = 1时，内循环执行1次，s = 2，p = 2；当i = 2时，内循环执行2次，内循环第一次s = 2 * 10 + 2，s变为 22，内循环执行第二次s = 22 * 10 +2，s变为220。两次的和相加就是224. 如果在p = p + s后面写一句：s = 0，可以解决。

“多一少一”问题占程序员常犯错误的10%以上！ 避免“多一少一”问题的方法之一是将比如<10甚至<5的数代入程序片断，掰手指头心算验证一下程序到底应该写为 x、x-1、x+1中的哪个？ <、<=、==、>、>=中的哪个？

#include <stdio.h> #include <math.h> int main() { 	int a,n,sum,i;     sum=0; 	i=1; 	scanf("%d,%d",&a,&n); 	while(i<=n) 	{     sum=sum+a; 	a=a+a*(pow(10,i)); 	i++; 	} 		printf("%d\n",sum); 	return 0; }

在for(d=1;d<=i;d++)s中，i=1执行一次，i=2是会执行两次，总的就会执行三次，故输出结果为224.

多循环了一下*10  d的循环有问题 建议调试


Question: 关于宏的问题

学习了，谢谢各位。

&(x)为什么不直接写成 &x -->当x是个复杂的表达式时，两者是有差别的

建议用inline函数代替宏

因为宏定义展开就是等价替换，若x是一个表达式，就会有问题；  比如 #define MUL(x, y)  (x * y) MUL(6-2, 8+4)；    /*即: 6-2 * 8 + 4 */   MUL(6-2, 8+4)展开就变成(6-2 * 8 + 4) 若加上括号；就变成： (6-2) * (8+4) 这样就正常了 。

加（）是严谨。 不加（）是不好的。 比如说&a+b 与&（a+b） ，真实需要的是a+b 再取地址，而你用第一个的话就走岔了。

比如： #define Mul(x)    x*x  Mul(5+1)   //应该等于6*6=36  但 5+1*5+1

当x是一个复合表达式的时候呢？


Question: 【C语言】Strtod精度问题

引用 14 楼 zxzr1990 的回复:[quote=引用 13 楼 iloveyou418 的回复:] [quote=引用 9 楼 zxzr1990 的回复:] [quote=引用 8 楼 iloveyou418 的回复:] 用unsigned char数组来存储？这样就不会出现精度问题了.... 说的对，我就是用char来做保存的。 现在要用char保存的数据要把它变成double带入计算。。 char好像不能直接乘除吧。。[/quote] 我一般处理都是假装小数点不存在，先进行数据处理，最后再把小数点补上。。。[/quote]  还需要一个专门数小数点的函数？[/quote] char数组直接判断'.'，Cstring直接find。。。我都是如此偷懒

引用 13 楼 iloveyou418 的回复:[quote=引用 9 楼 zxzr1990 的回复:] [quote=引用 8 楼 iloveyou418 的回复:] 用unsigned char数组来存储？这样就不会出现精度问题了.... 说的对，我就是用char来做保存的。 现在要用char保存的数据要把它变成double带入计算。。 char好像不能直接乘除吧。。[/quote] 我一般处理都是假装小数点不存在，先进行数据处理，最后再把小数点补上。。。[/quote]  还需要一个专门数小数点的函数？

引用 9 楼 zxzr1990 的回复:[quote=引用 8 楼 iloveyou418 的回复:] 用unsigned char数组来存储？这样就不会出现精度问题了.... 说的对，我就是用char来做保存的。 现在要用char保存的数据要把它变成double带入计算。。 char好像不能直接乘除吧。。[/quote] double 的精度就是如此，16位有效数字

引用 8 楼 iloveyou418 的回复:用unsigned char数组来存储？这样就不会出现精度问题了.... 说的对，我就是用char来做保存的。 现在要用char保存的数据要把它变成double带入计算。。 char好像不能直接乘除吧。。

用unsigned char数组来存储？这样就不会出现精度问题了....

引用 1 楼 zhao4zhong1 的回复:浮点数格式 http://bbs.csdn.net/topics/390676437 受教。多谢！

引用 2 楼 hongwenjun 的回复:#include <stdio.h>      /* printf, NULL */ #include <stdlib.h>     /* strtod */  int main() {     char sz[] = "12345.6789";     char* pEnd;      double t1 = strtod(sz, &pEnd);     printf("%f", t1);     return 0; } /* output 12345.678900 */  好像没什么问题吧  默认的6位是没什么问题，目前要用精确到20位左右， 把你的%f变成%30.20f试一下，看看后面都是0吗。

引用 9 楼 zxzr1990 的回复:[quote=引用 8 楼 iloveyou418 的回复:] 用unsigned char数组来存储？这样就不会出现精度问题了.... 说的对，我就是用char来做保存的。 现在要用char保存的数据要把它变成double带入计算。。 char好像不能直接乘除吧。。[/quote] 我一般处理都是假装小数点不存在，先进行数据处理，最后再把小数点补上。。。

引用 7 楼 zxzr1990 的回复:[quote=引用 1 楼 zhao4zhong1 的回复:] 浮点数格式 http://bbs.csdn.net/topics/390676437 受教。多谢！[/quote]

个人觉得这个跟二进制表示浮点数的方法有关系。正如前面有朋友所说的“很多十进制的浮点数是无法用二进制精确表示的”。如果把代码改为  char* stopstring; double t1 = strtod("12345.0625", &stopstring); printf("%030.15f", t1);  此时的输出即为00000000000010.062500000000000 因为此时的小数部分0,0625是能够正好被二进制精确表示的。但是如果改为12345.6789，此时小数部分0.6789不能被二进制精确表示，所以就会出现小数部分不相同的情况。

很多十进制的浮点数是无法用二进制精确表示的

没有办法吧，这是浮点数的存储方式决定的。但是你可以从业务的实际出发来想办法，比如涉及金额的用分或厘做单位，以整数进行计算。

引用 2 楼 hongwenjun 的回复:#include <stdio.h>      /* printf, NULL */ #include <stdlib.h>     /* strtod */  int main() {     char sz[] = "12345.6789";     char* pEnd;      double t1 = strtod(sz, &pEnd);     printf("%f", t1);     return 0; } /* output 12345.678900 */  好像没什么问题吧 double类型的数据应该用%lf输出，使用%f输出会影响其精度


Question: 菜鸡求教~如何将两个大小不同的二维数组互换？

只有真正的闲才能孕育出真正的创意！

#include <stdio.h> #include <stdlib.h> #include <malloc.h> void swap(int *a, int *b); int main() { 	int line_1, row_1, line_2, row_2, i, j;  	printf("依次输入第一个int数组的行、列:"); 	scanf("%d %d", &line_1, &row_1); 	int **c = (int**)malloc(line_1 * sizeof(int*)); 	for (i = 0; i<line_1; i++) 		c[i] = (int*)malloc(row_1 * sizeof(int)); 	printf("输入第一个数组的数据.\n"); 	for (i = 0; i < line_1; i++) 		for (j = 0; j < row_1; j++) 			scanf("%d", &c[i][j]);  	printf("依次输入第二个int数组的行、列:"); 	scanf("%d %d", &line_2, &row_2); 	int **d = (int**)malloc(line_2 * sizeof(int*)); 	for (i = 0; i < line_2; i++) 		d[i] = (int*)malloc(row_2 * sizeof(int)); 	printf("输入第二个数组的数据.\n"); 	for (i = 0; i < line_2; i++) 		for (j = 0; j < row_2; j++) 			scanf("%d", &d[i][j]); 	       	swap(&c,&d); 			printf("%d ", c[i][j]); 			printf("%d ", d[i][j]); 	return 0; } void swap(int *a,int *b) {     } 我已经晕了，swap函数不知道要怎么弄了，函数里我也试过用realloc函数，可运行起来就是不对。。我也调试不出什么东西来，，我二维数组指针的传递还是理解的不好。。明天我还是再看看书吧

a是两行两列，b是3行3列，数组的长度是不一样的，可以把a中的数据放到b中，但是b中的数据放不到a中。除非他们是一样大的。

请使用std::vector<int> ，以及std::swap， 把生命浪费在这些麻烦且容易出错的东西上面，不值得

。。用两个字符指针就ok了 如下： int main()  {  	char **a, **b; 	for (int i = 0; i < 2; i++) { 		a = new (char*); 		for (int j = 0; j < 2; j++) { 			*a = new char; 		} 	} 	//b同样操作 	for (int i = 0; i < 3; i++) { 		b = new (char*); 		for (int j = 0; j < 3; j++) { 			*b = new char; 		} 	} 	//然后就可以把a,b当作数组操作了，注意别越界 	for (int i = 0; i < 2; i++) { 		for (int j = 0; j < 2; j++) { 			scanf("%c", &a[i][j]); 		} 	} 	for (int i = 0; i < 3; i++) { 		for (int j = 0; j < 3; j++) { 			scanf("%c", &b[i][j]); 		} 	} 	//输出 	printf("\n,array B:   "); 	for (int i = 0; i < 2; i++) { 		for (int j = 0; j < 2; j++) { 			printf("%c ", a[i][j]); 		} 		printf("\n"); 	} 	printf("\n,array B:   "); 	for (int i = 0; i < 3; i++) { 		for (int j = 0; j < 3; j++) { 			scanf("%c ", b[i][j]); 		} 		printf("\n"); 	} 	printf("\n"); 	//以下是swap操作 	char **c; 	c = b; 	b = a; 	a = c; 	//输出 	printf("\n,array B:   "); 	for (int i = 0; i < 3; i++) { 		for (int j = 0; j < 3; j++) { 			printf("%c ", a[i][j]); 		} 		printf("\n"); 	} 	printf("\n,array B:   ");  	for (int i = 0; i < 2; i++) { 		for (int j = 0; j < 2; j++) { 			scanf("%c ", b[i][j]); 		} 		printf("\n"); 	} 	printf("\n"); 	//完成 	return 0; }    。。我真是闲的。。

百度 动态数组 二维动态数组


Question: 服务端和客户端聊天

客户端建立套接字连接服务器以后 就可以send啊  都是调用函数 百度不少源码

如果是简单的一问一答形式，很容易，recv后再send 如果不是这样简单的形式，那么多线程。一个线程recv，一个线程send，多线程要处理线程同步的情况，比较复杂了。


Question: char下面的红线看不懂，提示信息是：类型说明符的组合无效

是unsigned而不是unsignde，拼写有错误；

unsigned拼错了


Question: mmap问题

log.txt 文件大小比sizeof(int)小？

映射/dev/zero会自动创建一个制定长度的映射区，但是对于普通文件是不可以。

#include <stdio.h> #include <stdlib.h> #include <fcntl.h> #include <unistd.h> #include <sys/mman.h>   int main(void) {     int zero = 100;     int fd = open("log.txt",O_RDWR|O_CREAT,0666);     write(fd, &zero, sizeof(int));     int *mmp = (int *)mmap( NULL,sizeof(int),PROT_READ |             PROT_WRITE,MAP_SHARED,fd,0 );     if (mmp == MAP_FAILED) {         fprintf(stderr, "map error!\n");         goto errno_r;     }      close(fd);     printf("%d\n", *mmp);     *mmp = 0;     printf("%d\n", *mmp);  errno_r:     munmap(mmp, sizeof(int));      return 0; } write(fd, &zero, sizeof(int));是需要的，因为若不加这句，fd的偏移不是sizeof(int)个字节； 若不加这句，可以打开/dev/zero文件，即：  #include <stdio.h> #include <stdlib.h> #include <fcntl.h> #include <unistd.h> #include <sys/mman.h>   int main(void) {     int zero = 100;     //int fd = open("log.txt",O_RDWR|O_CREAT,0666);     int fd = open("/dev/zero",O_RDWR|O_CREAT,0666);     //write(fd, &zero, sizeof(int));     int *mmp = (int *)mmap( NULL,sizeof(int),PROT_READ |             PROT_WRITE,MAP_SHARED,fd,0 );     if (mmp == MAP_FAILED) {         fprintf(stderr, "map error!\n");         goto errno_r;     }      close(fd);     printf("%d\n", *mmp);     *mmp = 10;     printf("%d\n", *mmp);  errno_r:     munmap(mmp, sizeof(int));      return 0; } 另外，建议加上对mmap返回值的判断


Question: 牛顿迭代法解高次方程和超越方程,新手求教

这个方程有无数个解，你可以画出图像看一下，牛顿迭代法依赖于初值，初值不同，收敛区间不同也就导致收敛得到的结果不同，上面1.114157和-9.317243是对的，应该是你带回去的时候弧度和角度没进行转换。

仅供参考：//用C语言编程，求出2^x=x^10这个方程的解。 #include <math.h> #include <stdio.h> double x,e; void main () {     x=-1.0;     e=0.001;     while (1) {         while (1) {             if (pow(2.0,x)<pow(x,10.0)) {                 x+=e;             } else {                 break;             }         }         e/=10.0;         if (e<1e-15) break;         while (1) {             if (pow(2.0,x)>pow(x,10.0)) {                 x-=e;             } else {                 break;             }         }         e/=10.0;         if (e<1e-15) break;     }     printf("%+.14g\n",x);      x=1.0;     e=0.001;     while (1) {         while (1) {             if (pow(2.0,x)>pow(x,10.0)) {                 x+=e;             } else {                 break;             }         }         e/=10.0;         if (e<1e-15) break;         while (1) {             if (pow(2.0,x)<pow(x,10.0)) {                 x-=e;             } else {                 break;             }         }         e/=10.0;         if (e<1e-15) break;     }     printf("%+.14g\n",x); }


Question: 求分析

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

输入最多十行加上去并没有什么作用,输出就是按行输出

他的输入要求最大可以输入100位的数,你这个long long int应该表示不了那么大的数

#include <stdio.h> #include <stdlib.h> #include <string.h> #include <math.h>  #define MAX_NUM     10  int main(void) {  #if 1     unsigned long long num, diff;     int cnt = 0, s_digit;      while (1 == scanf("%llu", &num) && num > 0) {         if (cnt++ > MAX_NUM)             break;         s_digit = num % 10;         diff = llabs(num / 10 - s_digit * 5);          if (diff % 17 == 0)             printf("1\n");         else             printf("0\n");      } #else     int i,length,num=0,n=0;      char s[102];      while(1)     {          gets(s);          if(s[0]=='0')              break;          length = strlen(s);          for(i=0;i<length;i++)          {              num += (s[i]-'0')*(int)pow(10,length-1-i); //注意pow返回值类型为double          }          num = num/10-num%10*5;          if(0 == num%17)              printf("1\n");          else              printf("0\n");          num = 0;      } #endif     return 0;  } 参考一下吧～


Question: 新人跪求大神解释fgets源码	*s  = str ->_Back[--str->_Nback]; 这是啥意思啊

引用 6 楼 hzy_76 的回复:凭以上代码猜测，_Back是文件的栈式缓冲区，栈顶是最前面的字符，_Nback是栈大小，至于_Rend，还没想明白，在遍历完文件时设置的，会是什么呢？#include <string.h> #include "xstdio.h"   char *(fgets)(char *buf, int n, FILE *str) //get a line from stream    {   	unsigned char *s;     	if(n <= 1)   		return (NULL);    	for(s = (unsigned char * )buf; 0 < --n && str -> _Nback; )   	{   		//deliver pushed bach chars    		*s  = str ->_Back[--str->_Nback];    		if(str->_Nback == 0)   			   			str->_Rend = str->_Rsave;    		   		if(*s++ == '\n')   		{               //terminate full line   			*s = '\0';    			return (buf);    		}   	}     while(0 < n)     {     	//ensure buffer has chars       	if(str->_Next < str ->_Rend)      		else if (_Frpre(str) < 0)     			return (NULL);      		else if(str -> _Mode & _MEOF)     			break;              {             	 //copy as many as possible               	unsigned char *s1 = memchr(str->_Next,              		'\n', str->_Rend - str ->_Next);              	size_t m = (s1 ? s1 + 1 : str->_Rend) - str->_Next;               	if ( n < m)             		s1 = NULL, m  = n;              	memcpy(s, str->_Next, m);              	s += m, n -= m;              	str -> _Next += m;              	if(s1)             	{             		//terminate full line             		*s = '\0';              		return (buf);              	}             }             }      if(s == (unsigned char * ) buf)      	return (NULL)      else       {   //termintate partial line      	*s = '\0';       	return (buf);      }    } /* 摘于《C标准库》一书，作者Plauger */

这个要看你具体的环境了，或者你能看到FILE结构体定义的话，发上来看看也许能猜到。

引用 2 楼 zhao4zhong1 的回复:http://edu.csdn.net/course/detail/2344 C语言指针与汇编内存地址-一.代码要素谢谢赵老师！

引用 1 楼 hzy_76 的回复:str的_Nback成员自减1，然后把它当作数组索引，取str的_Back数组成员，赋给s指针。能具体说说_Back，Nback，  _Rend 的意思吗，非常感谢


Question: 【求助】链表实现一元多项式的带余除法运算

代码功能归根结底不是别人帮自己看或讲解或注释出来的；而是被自己静下心来花足够长的时间和精力亲自动手单步或设断点或对执行到某步获得的中间结果显示或写到日志文件中一步一步分析出来的。 提醒：再牛×的老师也无法代替学生自己领悟和上厕所！ 单步调试和设断点调试（VS IDE中编译连接通过以后，按F10或F11键单步执行，按Shift+F11退出当前函数；在某行按F9设断点后按F5执行停在该断点处。）是程序员必须掌握的技能之一。  崩溃的时候在弹出的对话框按相应按钮进入调试，按Alt+7键查看Call Stack即“调用堆栈”里面从上到下列出的对应从里层到外层的函数调用历史。双击某一行可将光标定位到此次调用的源代码或汇编指令处，看不懂时双击下一行，直到能看懂为止。

建议给出完整的代码，尤其是调用的形式（即main中的调用关系）

跟踪调试是必会技能。


Question: switch中不能有输入语句吗？

好吧，谢谢你的回复。

你前面已经用scanf读入过c2了 然后你判断的时候又用getchar一遍？ 所以你想干什么


Question: C语言求二次函数的根

#include<stdio.h> #include<math.h> #include<String> #define EOX 0.000001        //代码中的数值都是浮点数，如果和int型的0比较大小就会发生错误，所以此处我自己定义了一个精度，(-EXO,EXO)区间代表0  double Equationsolving(double a, double b, double c)//定义一个求解子函数（接口） {      if ((a > -EOX) && (a < EOX))//如果a在（-EXO，EXO）区间内代表a=0，那就不是一个一元二次方程     {         printf("这不是一个一元二次方程\n");     }     else     {         double d  = b*b - 4 * a*c;                   double x1 = (-b + sqrt(d)) / 2 * a; //两个求解的公式         double x2 = (-b - sqrt(d)) / 2 * a;         if (d>=EOX)               //d大于零，方程有两个不同的解         {             printf("该方程有两个不同的解：x1 = %lf,  x2 = %lf\n", x1, x2);         }         else         {             if ((d > -EOX) && (d < EOX)) //d等于零，方程有两个相同的解             {                 printf("该方程有两个相同的解：x1 = x2 = %lf\n", x1);             }             else             {                 printf("该方程无解\n");  // d小于零，方程无解             }         }     }     return 0; }  int main() {     printf("请输入要求解的一元二次方程的三个系数a,b,c的值：");     double a = 0;     double b = 0;     double c = 0;     scanf_s("%lf%lf%lf", &a, &b, &c); //从键盘上输入a，b，c的值，这里的scanf_s语句是编译器自带的，通常情况下还是写scanf     Equationsolving(a, b, c); //调用子函数（接口）     system("pause");          //暂停功能     return 0; }

当F<0时直接输出没有解

如果是实数根，b平方减4ac有可能为负数，此时没有根，应中断。 如果需要虚数根，需要先查看sqrt函数能否对负数参数输出虚数。

#include <stdio.h> #include <math.h> int main() { 	double a,b,c,disc,x1,x2,realpart,imagpart;     scanf("%1f,%1f,%1f",&a,&b,&c); 	printf("the question\n"); 	if(fabs(a)<=1e-6) 		printf("is not the quadratic.\n"); 	else 	{ 		disc=b*b-4*a*c; 		if(fabs(disc)<=1e-6) 			printf("has two equal rooots:%8.4f\n",-b/(2*a)); 		else 			if(disc>1e-6) 		{ 				x1=(-b+sqrt(disc))/(2*a); 			    x2=(-b-sqrt(disc))/(2*a); 				printf("has two different roots:%8.4f and %8.4f\n",x1,x2); 		} 		else  		{ 			realpart=-b/(2*a); 			imagpart=sqrt(-disc)/(2*a); 			printf("has complex roots:\n"); 			printf("%8.4f+%8.4fi\n",realpart,imagpart); 			printf("%8.4f-%8.4fi\n",realpart,imagpart);  		}  	} 	return 0; }

把结果打出来啊，是不是-e什么的

c 语言能开负数的平方根吗？


Question: 跪求大神分析下代码哪里有错哈（题目是：一个整数，它加上100 后是一个完全平方数，再加上168 又是一个完全平方数，请问该数是多少？）

return 0 应该放到最外面，当所有的平方数都测试完成，没有符合的才是返回 false。 当有符合的就返回 true。

我明白了，judge函数else里面应该是continue

这样改没用啊，程序运行还是什么也没有


Question: 新人基础问题求教

上面那个是字符串结尾为  ‘\0'

字符串也是一种数组,但是它的最后一位是 \0  表示结束,c primer plus上有具体讲

char b[5]="abcd";//这是一个字符串，在内存的内容是：“abcd\0"共计5个字符组成； char a[5]={'a','b','c','d','e'};//这是一个char（字符）数组，每个数组就是一个char（字符），总共有5个char（字符）。 这是二个完成不同的概念，一个是字符串，一个是数组，不过这里却保存char（字符）内容O(∩_∩)O

字符串未尾有个'\0'，虽然他存在，但你看不见。

第一个是字符串，第二个是字符，字符串结尾有\0占据一位

char b[5]="abcd";//字符串结尾带‘\0’ char a[5]={'a','b','c','d','e'};//字符不带

怎么输出？ 第一个数组是有4个字符，第二个数组有5个字符，若用循环%c输出，那么都能输出5个字符，（第一个数组的a[4]是'\0'无法显现到终端） 但是，若以%s输出，那么第二个数组不是字符串，而是字符数组；所以以%s输出，第二个数组是会越界的。 因为%s是按照字符串的形式输出，那么第二个字符数组没有'\0'，所以输出时就一直找到'\0'才停止输出；

字符串 和 字符的区别

<button onclick="xzf();">xzf</button>   function xzf(){   alert(ok); }

源代码

分别sizeof  和 strlen 看看就明白了

char b[5]="abcd";  等价于  char b[5] = {'a','b','c','d','\0'}; C语言中的字符串是由'\0'结束，系统会在字符串后加一个'\0'作为结束符。

字符串"abcd"的话，数组中第五个元素存的是"\0"

求教啊，大佬们人呢


Question: 求解释！！！！

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

上面是常量的字符串赋值，默认都判定的。 下面是单个字符赋值，如果你赋值‘\0’，肯定不会报错。 所以上面是字符串赋值，下面是字符赋值，层级不一样，判定也不一样。

在VS中按F9添加断点，按F5进行调试。查看监视和内存就很清楚了。

怎么输出？ 第一个数组是有4个字符，第二个数组有5个字符，若用循环%c输出，那么都能输出5个字符，（第一个数组的a[4]是'\0'无法显现到终端） 但是，若以%s输出，那么第二个数组不是字符串，而是字符数组；所以以%s输出，第二个数组是会越界的。

字符串和字符数组      分别sizeof  和  strlen  看看

char b[5] = "abcd"; // 编译器转化为char b[5] = { 'a', 'b', 'c', 'd', '\0' }; b可以作为字符串使用，因为有结尾符'\0' char a[5] = { 'a', 'b', 'c', 'd', 'e' }; //因为没有'\0'，所以不能作为字符串使用

上面是以字符串形式保存的，字符串末尾会有'\0'，占一个字符

上面那一种，系统会自动在最后面加一个'\0'


Question: C语言求助，简单的球和

printf("sum = %d \n", &sum);   //error

//printf("sum = %d \n", &sum);  //scanf才需要对sum取地址       printf("sum = %d \n", sum);     }

打印的是sum的地址信息

1、printf内对sum取址 2、求和应该是每次sum+=i吧

printf("sum = %d \n", &sum);     // 这里你取 sum的地址，是错误的


Question: C语言新手求指导，接受批评，rand()函数还有二维数组，实在不知道要怎么改了，求指出问题，

#include<stdio.h> #include<stdlib.h> #include<time.h> int main() { 	int a[50][5]; 	int GPA, i, j, m, n = 0; 	srand(time(0)); 	for (i = 0; i <= 49; i++) { 		for (j = 0; j <= 4; j++) {  			m = rand() % 101;  			if (m >= 90) 				a[i][j] = 9; 			else if (m >= 80) 				a[i][j] = 8; 			else if (m >= 70) 				a[i][j] = 7; 			else if (m >= 60) 				a[i][j] = 6; 			else if (m >= 0) 				a[i][j] = 0; 		} 		n = a[i][0] * 3 + a[i][1] * 4 + a[i][2] * 2 + a[i][3] * 5 + a[i][4] * 1; //改这里 		GPA = n / 15; 		printf("%d\n", GPA); 	} 	return 0; }

我感觉你这方法可以形成随机数，是二维数组的下标出问题了。 定义的是int a[50][5]； n=a[i][1]*3+a[i][2]*4+a[i][3]*2+a[i][4]*5+a[i][5]*1; 这里不能出现a[i][5]的，这样会越界产生随机大数。 rand()应该不会产生负值，否则还要考虑m产生负值的情况，希望对你有帮助

看视频可以知道，如果种子数(1)，随机数是固定。 第一个种子可以用时间当种子数

/* srand example */ #include <stdio.h>      /* printf, NULL */ #include <stdlib.h>     /* srand, rand */ #include <time.h>       /* time */  int main () {   printf ("First number: %d\n", rand()%100);   srand (time(NULL));   printf ("Random number: %d\n", rand()%100);   srand (1);   printf ("Again the first number: %d\n", rand()%100);    return 0; }


Question: 帮我看一下这个一元多项式的乘法函数哪里错了，不需要给我多正确的代码，帮我检查一下mutpoly函数哪里错了就行其他基本没问题，谢谢你

仅供参考：//链表实现一元多项式的加法减法乘法 #include <stdio.h> #include <stdlib.h> typedef struct node {     float coef;   //系数     int expn;     //指数     struct node *next; } PolyNode;      //多项式节点 polynomial node typedef PolyNode* Polynomial; Polynomial createPolynomial() {  //创建多项式     PolyNode *p, *q, *head = (PolyNode *)malloc(sizeof(PolyNode));   //头节点     head->next = NULL;     float coef;     int expn;     printf("输入该多项式每一项的系数和指数，每项一行，输入0 0结束！\n");     while (scanf("%f %d", &coef, &expn) && coef) {   // 默认，按指数递减排列         if (head->next) {             p = head;             while (p->next && expn < p->next->expn)                 p = p->next;             if (p->next) {                 if (expn == p->next->expn) { //有相同指数的直接把系数加到原多项式                     p->next->coef += coef;                     if (p->next->coef > -0.000001 && p->next->coef < 0.000001) { //若是相加后系数为0，则舍弃该节点                         q = p->next;                         p->next = q->next;                         free(q);                     }                 } else {                     q = (PolyNode*)malloc(sizeof(PolyNode));                     q->coef = coef;                     q->expn = expn;                     q->next = p->next;                     p->next = q;                 }             } else {                 p->next = (PolyNode*)malloc(sizeof(PolyNode));                 p = p->next;                 p->coef = coef;                 p->expn = expn;                 p->next = NULL;             }         } else {             head->next = (PolyNode*)malloc(sizeof(PolyNode));             head->next->coef = coef;             head->next->expn = expn;             head->next->next = NULL;         }     }     return head; } Polynomial multiply(Polynomial poly, float coef, int expn) {  //多项式与指定单项式相乘，该单项式为 coefx^expn     PolyNode *p, *q, *Poly = (PolyNode*)malloc(sizeof(PolyNode));     p = Poly;     q = poly->next;     while (q) {         p->next = (PolyNode*)malloc(sizeof(PolyNode));         p = p->next;         p->coef = (q->coef*coef);         p->expn = (q->expn + expn);         q = q->next;     }     p->next = NULL;     return Poly; } void add(Polynomial poly1, Polynomial poly2) {  //把 poly2 加到 poly1 上     PolyNode *p, *q, *r;     r = poly1;     p = poly1->next;  //指向第一个节点     q = poly2->next;     poly2->next = NULL;     while (p && q) {         if (p->expn > q->expn) {             r->next = p;             p = p->next;             r = r->next;         } else if (p->expn < q->expn) {             r->next = q;             q = q->next;             r = r->next;         } else {             PolyNode *t;             p->coef += q->coef;             if (!(p->coef > -0.000001 && p->coef < 0.000001)) //系数不为0             {                 r->next = p;                 r = r->next;                 p = p->next;             } else {                 t = p;                 p = p->next;                 free(t);             }             t = q;             q = q->next;             free(t);         }     }     if (p)         r->next = p;     if (q)         r->next = q; } Polynomial polySubtract(Polynomial poly1, Polynomial poly2) {  //多项式减法 poly1-poly2形成一个新的多项式     //把poly2的系数取相反数，形成一个新的多项式     Polynomial poly = (PolyNode*)malloc(sizeof(PolyNode)); //构造头节点     PolyNode *p, *q;     p = poly;     q = poly2->next;     while (q) {         p->next = (PolyNode*)malloc(sizeof(PolyNode));         p = p->next;         p->coef = -(q->coef);  //系数取反         p->expn = q->expn;         q = q->next;     }     p->next = NULL;     add(poly, poly1);  //利用加法     return poly; } Polynomial polyAdd(Polynomial poly1, Polynomial poly2) { //多项式相加 poly1+poly2形成一个新的多项式     Polynomial poly = (PolyNode*)malloc(sizeof(PolyNode));  //和多项式的头节点     poly->next = NULL;     PolyNode *p, *q, *r;     r = poly;     p = poly1->next;     q = poly2->next;     while (p&&q) {         if (p->expn > q->expn) {             r->next = (PolyNode*)malloc(sizeof(PolyNode));             r = r->next;             r->coef = p->coef;             r->expn = p->expn;             p = p->next;         } else if (p->expn < q->expn) {             r->next = (PolyNode*)malloc(sizeof(PolyNode));             r = r->next;             r->coef = q->coef;             r->expn = q->expn;             q = q->next;         } else {             float m = p->coef + q->coef;             if (!(m > -0.000001 && m < 0.000001)) {                 r->next = (PolyNode*)malloc(sizeof(PolyNode));                 r = r->next;                 r->coef = m;                 r->expn = p->expn;             }             q = q->next;             p = p->next;         }     }     while (p) {         r->next = (PolyNode*)malloc(sizeof(PolyNode));         r = r->next;         r->coef = p->coef;         r->expn = p->expn;         p = p->next;     }     while (q) {         r->next = (PolyNode*)malloc(sizeof(PolyNode));         r = r->next;         r->coef = q->coef;         r->expn = q->expn;         q = q->next;     }     r->next = NULL;     return poly; } Polynomial polyMultiply(Polynomial poly1, Polynomial poly2) {  //多项式相乘     Polynomial poly = (PolyNode*)malloc(sizeof(PolyNode));  //创建多项式和的头节点     poly->next = NULL;     PolyNode *p;     p = poly2->next;     while (p) {         add(poly, multiply(poly1, p->coef, p->expn));         p = p->next;     }     return poly; } void printPoly(Polynomial poly) {  //打印多项式     if (poly && poly->next) {         PolyNode *p = poly->next;  //p指向第一个节点         while (p->next) {             printf("%gx^%d", p->coef, p->expn);             p = p->next;             if (p && (p->coef > 0))                 printf("+");         }         if (p->expn == 0)             printf("%g", p->coef);   //打印常数项         else             printf("%gx^%d", p->coef, p->expn);         printf("\n");     } } void freePoly(Polynomial poly) {  //释放内存     if (poly && poly->next) {         PolyNode *p, *q;         p = poly;         while (p) {             q = p->next;             free(p);             p = q;         }     }     poly = NULL; } int main() {     printf("用链表实现多项式的加减法\n");     Polynomial poly1, poly2, poly3;     printf("创建多项式一\n");     poly1 = createPolynomial();     printf("多项式一：\n");     printPoly(poly1);     printf("创建多项式二\n");     poly2 = createPolynomial();     printf("多项式二：\n");     printPoly(poly2);     printf("两多项式相加，和为：\n");     poly3 = polyAdd(poly1, poly2);     printPoly(poly3);     freePoly(poly3);     printf("两个多项式相乘，积为：\n");     poly3 = polyMultiply(poly1, poly2);     printPoly(poly3);     freePoly(poly3);     printf("两多项式相减，差为：\n");     poly3 = polySubtract(poly1, poly2);     printPoly(poly3);     freePoly(poly1);     freePoly(poly2);     freePoly(poly3);     system("pause");     return 0; }

出错了可以中断下来分析原因，经检查，你的Rear = Rear->Next;后，你的Rear得到的值是NULL，在接下来的循环中又执行Rear->Next = temp;，这里解引NULL指针导致出错


Question: C语言题目求助

#include <stdio.h> #include <stdlib.h> #include <math.h>  int is_prime(int num);  int main(void) {  #if 1     int m, n, cnt = 0, sum = 0;     int i;      scanf("%d%d", &m, &n);      if (m < n)         return 0;      for (i = 2; i < 200; i++)         if (is_prime(i)) {             printf("%d\n", i);             cnt++;             if (cnt > m)                 break;              if (cnt >= n)                  sum += i;         }     printf("sum = %d\n", sum); #else      int data[200],i,n,m,dataNumber=2,sum=0;     for(i=0;i<             200;i++)     {         if(dataNumber=2)         {             data[i]=dataNumber;             dataNumber++;         }         else         {             data[i]=dataNumber;             dataNumber=dataNumber+2;         }     }     scanf("%d%d",&n,&m);     for(n<=m;n++;)     {         sum=sum+data[n];     }     printf("%d\n",sum); #endif     return 0; }  /*check prime */ int is_prime(int num) {     int i;      int len = sqrt(num) + 1;     for (i = 2; i< len; i++)         if (num % i == 0)             break;      if (i >= len)         return 1;     else         return 0; } 参考一下吧

寻找素数的算法有问题： 1.楼主的方法除了2以外，寻找的都是奇数，奇数不一定是素数。 2.  if(dataNumber=2)这一句会导致寻找的200个素数全部为2。 后续计算问题： 1.  for(n<=m;n++;)会导致循环无法退出。 附上根据楼主的思路修改的程序，请查阅，有问题请指出 int main(void) {    int data[200],i,n,m,dataNumber=2,sum=0;     for(i=0;i<200;i++)     {         if(dataNumber==2)         {             data[i]=dataNumber;             dataNumber++;             printf("%d\n",data[i]);         }         else         {             int j=2;             for(j=2;j<dataNumber;j++)             {                 if(dataNumber%j==0)                 {                     dataNumber+=2;                 }             }             data[i]=dataNumber;             dataNumber=dataNumber+2;             printf("%d\n",data[i]);         }     }      scanf("%d%d",&n,&m);     for(;n<=m;n++)     {         sum=sum+data[n];     }     printf("%d\n",sum);     return 0; }  这个问题其实分两步： 1. 找出200个素数。 2. 计算第n与第m之间的素数和。  我的建议是： 1. 先寻找素数。从寻找5个素数开始，逐步增加，并打印信息，可以迅速定位问题。然后扩展到200个素数。 2. 进行计算和。 3. 考虑异常情况。  如有错误，请指出。

请看代码，不懂留言  #include <stdio.h> int judgePrime(int num); //这是用来判断是否是素数的 int main() { 	int n = 1, m = 9, sum = 0; 	for(int i = n; i <= m ; i++) 	{ 		if( judgePrime(i)) 		{ 			printf("%d\n",i); 			sum = sum + i; 		} 	} 	printf("所有的素数的和是%d\n",sum); } int judgePrime(int num) //判断素数的函数的实现 { 	int i = 2,j = num; 	for( i ; i < j ; i++) 	{ 		if( num % i == 0 ) 		{ 			return 0; 		} 	} 	return 1; }

算法有误，可以打印出来看看。

1.语法问题 if(dataNumber=2) ---> if(dataNumber==2) for(n<=m;n++;) --> for(;n<=m;n++) 2.另外你的素数产生算法是错误的


Question: 一个明显的错误

引用 6 楼 冷羽的回复:这时由于 long long a 是 8 个字节而你的第一个是 %d 表示一个32为整数，这样 a 的高位 0 就会被第二个 %d 所输出 0，第三个 %d 才会输出 sizeof(long long),而 最后一个 sizeof(b) 就没有被用到。  32 为系统中的压栈， int，char，long ， ULONG 等压入的时候，都占用 4 个字节，而如果压入 的是 int64 longlong 的时候，是占用的8 字节，所以，就会出现这种不对应的情况。 可以修改为 printf("%I64d,%d,%d\n",a,sizeof(long long),sizeof(b)); 告诉第一次参数 a 是64位的，这样就不会出错了。 get!      非常感谢

引用 6 楼 XiaoFang 的回复:这时由于 long long a 是 8 个字节而你的第一个是 %d 表示一个32为整数，这样 a 的高位 0 就会被第二个 %d 所输出 0，第三个 %d 才会输出 sizeof(long long),而 最后一个 sizeof(b) 就没有被用到。  32 为系统中的压栈， int，char，long ， ULONG 等压入的时候，都占用 4 个字节，而如果压入 的是 int64 longlong 的时候，是占用的8 字节，所以，就会出现这种不对应的情况。 可以修改为 printf("%I64d,%d,%d\n",a,sizeof(long long),sizeof(b)); 告诉第一次参数 a 是64位的，这样就不会出错了。 学习了。谢

引用 3 楼 shw014 的回复:printf("%d,%d\n",a,sizeof(long long)); [code=c][/printf("%lld,%d\n",a,sizeof(long long)); 输出0code]

int、long、long long在printf中的格式     http://blog.csdn.net/fz_ywj/article/details/8107582 printf("%d,%d\n",a,sizeof(long long));

我和楼主一样 win7，codeblocks      printf("%d,%d\n",a,sizeof(long long)); 输出0     printf("%d,%d\n",sizeof(long long),a); 输出8     printf("%d",sizeof(long long)); 输出8  给了一个警告warning: format '%d' expects argument of type 'int', but argument 2 has type 'long long int' [-Wformat=]|  好像是sizeof返回的size_tl类型的问题。 什么%zu、%u、%lu %llu， 反正都是不好使。 求大神指点。

在Linux下测试，结果是：1 8,1 不会出现你的那种结果； 另外，a的输出和sizeof的输出，应该分别是用%lld， %lu


Question: C语言函数怎样做才能做到引用传递

把要返回的数组成一个数组，例如在主函数里定义一个数组，在被调函数中将数组名作为形参。注，用指向数组的指针做形参也可以。

& 取地址不就好了 百度 引用传递 很多吧


Question: for循环语句有问题啊，该怎么弄

#include<stdio.h> int main() { char ch; char wrs; printf("请输入您要进行的功能（a/A加密，b/B解密）："); scanf("%c", &ch); if (ch =='a' || ch == 'A') { printf("输入要转换的字符：");  fflush(stdin); for (fflush(stdin);(wrs = getchar()) != '\n'; ){ 	wrs = wrs + 2; 	printf("%d", wrs);  } } else { printf("输入要转换的字符："); fflush(stdin); for (; wrs != '\n'; wrs = getchar()) wrs = wrs - 2; printf("%d", wrs); }  return 0; }


Question: loadrunner编写C语言有关指针的问题

可是*p的值是什么呢，初始化的时候没给呀

赋值给p了 p和 *p   p有值 *p自然也有了 毕竟指针


Question: 分别构造插入到表头、表中和表尾三种情况的测试用例进行测试。

单步你的程序可以发现，linklist p = head->next这句p被赋值NULL，之后while (p->info<x)反问NULL指针导致出错

错误场景一:   输入一组升序排列的整数： 请输入整数序列（空格分开，以0结束）: 0 List is:  请输入要插入的值：1 程序崩溃  原因，insert函数中，初始化p为head->next，此时p为NULL，通过空指针访问数据当然崩溃    好好调试！


Question: C/C++批量处理问题，菜鸟求助

引用 4 楼 zhuimengdeluntai 的回复:[quote=引用 2 楼 jack960330 的回复:] 使用文件搜索的方法搜索，遍历目录 涉及到哪些函数或者类呢？[/quote] 去查查windows API和c/c++库的方法 要学会自助学会查文档

system("dir /b /a-d c:\\*.* >d:\\allfiles.txt"); //读文件d:\\allfiles.txt的内容即C:\\下所有文件的名字 system("dir /b /a-d /s c:\\*.* >d:\\allfilesinsub.txt"); //读文件d:\\allfilesinsub.txt的内容即C:\\下所有文件的名字包含子目录 system("dir /b /ad  c:\\*.* >d:\\alldirs.txt"); //读文件d:\\alldirs.txt的内容即C:\\下所有子目录的名字 请记住，能用shell命令获取文件、文件夹信息或者操作文件、文件夹最好用shell命令获取或者操作，而不要用各种API获取或者操作，因为当遇到非法文件夹名或非法文件名或非法文件长度、非法文件日期、压缩文件、链接文件、稀疏文件……等各种意料之外的情况时，API会处理的不全面或陷入死循环，而shell命令不会。 如果嫌system黑窗口一闪，将system("...")替换为WinExec("cmd /c ...",SW_HIDE);

引用 8 楼 hzy_76 的回复:涉及的函数，要看你的环境了，Windows/Linux/VC？ windows环境。能不能给写个例子啊，比如D盘下面有个文件夹AAA，AAA下面有很多个子文件夹。每个子文件夹里面有相同名字的文件，111.txt  222.txt   333.txt。要依次访问每一个子文件夹里面的txt，并将处理的结果写成txt，放在该子文件夹下面。

我有写过VC的，要晚上才能给你翻翻代码，貌似楼上说的是对的。

找到一段VC代码，仅供参考：  void CHYXQuantTraderDlg::OnImpStrategyBtn() { 	TCHAR pszPath[MAX_PATH]; 	CString pathAndSuffix; 	CString fileName[MAX_IMP_FILE_NUM]; 	int fileNum = 0; 	BROWSEINFO bi; 	bi.hwndOwner = this->GetSafeHwnd(); 	bi.pidlRoot = NULL; 	bi.pszDisplayName = NULL; 	bi.lpszTitle = TEXT("请选择策略文件所在目录"); 	bi.ulFlags = BIF_RETURNONLYFSDIRS | BIF_STATUSTEXT; 	bi.lpfn = NULL; 	bi.lParam = 0; 	bi.iImage = 0;  	if (!CTPStatus.initFinished) 	{ 		AfxMessageBox(_T("系统未初始化完毕，请稍候")); 		return; 	}  	if (addingNewStrategy) 	{ 		AfxMessageBox(_T("有新策略未初始化完毕，请稍候")); 		return; 	}  	if (impStrategyDlg.IsWindowVisible()) 	{ 		DEBUG_LOG("导入窗口已打开"); 		return; 	}  	LPITEMIDLIST pidl = SHBrowseForFolder(&bi); 	if (pidl == NULL) 	{ 		return; 	}  	if (SHGetPathFromIDList(pidl, pszPath)) 	{ 		//AfxMessageBox(pszPath); 		CFileFind tempFind; 		//是否成功找到文件 		BOOL bFound;  		pathAndSuffix.Format(_T("%s\\*.sth"), pszPath);	//修改"*.*"可限定查找文件类型 		bFound = tempFind.FindFile(pathAndSuffix);   		//遍历文件，找够100个就中断 		while (bFound && fileNum < MAX_IMP_FILE_NUM) 		{ 			//第一次执行FindNextFile是选择第一个文件，以后执行为选择下一个文件 			bFound = tempFind.FindNextFile();  			//如果找到的是返回上层的目录 则结束本次查找 			if (tempFind.IsDots()) 				continue;  			if (tempFind.IsDirectory()) 			{ 				//找到的是文件夹，不处理 			} 			else 			{ 				//得到文件名，包括后缀名，存入数组 				fileName[fileNum] = tempFind.GetFileName(); 				fileNum ++; 			} 		}  		tempFind.Close();  		//打开导入管理窗口 		impStrategyDlg.SetFileList(pszPath, fileName, fileNum); 		impStrategyDlg.ShowWindow(SW_SHOW); 	}  	return; }

FindFirstFile,FindNextFile

可以使用cmd命令， system(...)中调用此命令

涉及的函数，要看你的环境了，Windows/Linux/VC？

引用 2 楼 jack960330 的回复:使用文件搜索的方法搜索，遍历目录 涉及到哪些函数或者类呢？

引用 1 楼 hzy_76 的回复:父文件夹要做成参数的形式，运行时输入； 子文件夹、文件，都用扫描的方式找出来，再一个个处理就好了。 请问，能不能说的再详细一些呢？比如会涉及到哪些函数或者类？

dir /S /A /B *.cpp  > list.txt

这时候我就建议用python了          个人网站www.qtdoc.cn

遍历文件目录，然后依次调用你的处理程序即可，遍历方法网上很多代码

使用文件搜索的方法搜索，遍历目录


改成scanf_s("%s", name, 40);  或者  scanf("%s", name);  scanf_s还需要一个参数用于确认缓冲区大小

作者：benpigchu 链接：https://www.zhihu.com/question/53311855/answer/134429152 来源：知乎 著作权归作者所有。商业转载请联系作者获得授权，非商业转载请注明出处。  scanf_s 和 scanf 几乎是一样的，但是 scanf_s 在字符串的读入上有不同，允许在参数中指定读入字符串的长度上限，以避免读入的内容长度超过已有的内存空间的长度。比如，如果我们这样写： char word[10]; scanf("%s",word); 然后运行的时候输入了一个这样的字符串：tooyoungtoosimplesometimesnaive 那么这么长的字符串就会全部填在 word 数组里，超过它的长度，这样会出偏差的。为了避免出现这样的偏差，scanf_s 允许你指定读入串的长度上限，于是我们改成下面这样： scanf_s("%s",word,(rsize_t)sizeof word); 这样输入过长时就会产生错误，执行你之前在 set_constraint_handler_s 中定义的错误处理函数（如果你没有定义的话，系统会给你准备一个，也许是直接忽略，也许是直接停止运行），你的程序就不会在这里搞出什么偏差。而且，如果你传入的参数有空指针的话，也会产生错误，执行你定义的错误处理函数。也就是说，使用 scanf_s 比使用 scanf 要更安全。不过，并不是所有的标准库都实现了 scanf_s，你可以通过检测 __STDC_LIB_EXT1__ 是否被 #define 了，检测标准库是否支持，然后在代码最前面加上下面这一行：#define __STDC_WANT_LIB_EXT1__ 1 来开启标准库对于 scanf_s 以及其他一些函数的更安全的版本（比如 strcpy_s memset_s 之类的）的支持。这是 C11 新增的内容。

scanf_s("%s", name, 40); scanf_s使用时缺少参数，详细的请查阅一下scanf_s的原型


Question: 关于八皇后问题

你确定不出错？？？

我确定的可以运行，自己也试过，完全没问题，反倒是更改后就是各种问题，运行不了。

可编译可运行； 但是i = 8，肯定越界，可能并未运行到i=8时刻，已经return了

传进来的数组有查看过吗?

若QueenArr是的实参是8个元素的数组，那么标红色的循环确实是越界访问；当i=8时就越界了


Question: 新手！！链桟问题请大神求解！！

引用 2 楼 cfjtaishan 的回复:#if 0 #include<stdio.h> #include<stdlib.h>  typedef struct car {     int id;     char color[20]; }CAR;  typedef struct node {     CAR data;     struct node *next; }NODE;  int main(void) {      NODE *top;     top = NULL;      //加入节点，入栈     NODE *p; //定义指针     p = (NODE *)malloc(sizeof(NODE)); //分配空间     p->data.id=12345; //赋值     p->next = NULL;      NODE *q;     q=(NODE *)malloc(sizeof(NODE));     q->data.id=23456;     q->next = NULL;      NODE *s;     s=(NODE *)malloc(sizeof(NODE));     s->data.id = 34567;     s->next = NULL;      p->next = top;     top = p;      q->next = top;     top = q;      s->next = top;     top = s;      //输出     NODE *t;     t = top;     while(t)     {         printf("%d\n",t->data.id);         t = t->next;     }      //删除     NODE *tmp;     tmp = top;     top = top->next;     if (tmp)         free(tmp); //释放内存      //输出     NODE *t1;     t1 = top;     printf("删除\n");     while(t1)     {         printf("%d\n",t1->data.id);         t1 = t1->next;     }  }  #else  //现要求对上面的代码改为在函数中实现  //下面的是我修改的，出现的语法错误，本人刚入门，请大神指点一二，万分感激  #include<stdio.h> #include<stdlib.h> #include <string.h>  typedef struct car {     int id;     char color[20]; }CAR;  typedef struct node {     CAR data;     struct node *next; }NODE;  void initLinkStack(NODE **top) {     *top = NULL; }  void insertLinkStack(NODE **top,CAR newCar) {     NODE *node;      node = (NODE *)malloc(sizeof(NODE));     if (!node)         exit(0);      node->data = newCar;     node->next = *top;     *top = node; }  void outPutLinkStack(NODE *top) {     NODE *t;      t = top;     while (t) {         printf("车牌：%d ,颜色：%s\n",t->data.id,t->data.color);         t = t->next;     } }  void deleteLinkStack(NODE **top) {     NODE *tmp;      if (!top)         return;     tmp = *top;     *top = (*top)->next;     free(tmp); //释放内存  }  int main() {     CAR C1 = {123456,"black"};     CAR C2 = {234567,"blue"};     CAR C3 = {345678,"red"};      NODE *top; //定义栈顶指针     initLinkStack(&top);      //增加元素     printf("依次增加桟元素:\n");     insertLinkStack(&top,C1);     insertLinkStack(&top,C2);     insertLinkStack(&top,C3);     //输出元素     outPutLinkStack(top);      //删除元素     printf("删除栈顶元素:\n");     deleteLinkStack(&top);     //输出元素     outPutLinkStack(top);  } #endif 修改你的代码之后，可以试一下；  NODE top; //定义栈顶指针 initLinkStack(&top); 注释和你的实际不相符，比如上面的两句代码，注释是定义栈顶指针，但是，却是定义了一个结构体变量，而非指针。  谢谢啦

引用 1 楼 user-2 的回复:并没有语法错误。 main函数需要返回int  我用无返回类型的呢，我直接用指针传值的

谢谢大家！！！

并没有语法错误。 main函数需要返回int


Question: 求分析

#include<stdio.h> #include<math.h> int main() {      double pi = 0,i=1,temp = 1;      //3.141591 #if 1     int count1 = 1;     while(fabs(temp)>=1e-6)     {         pi += temp;         i = i+2;         temp = pow(-1,count1++)*1.0/i;     } #else     //3.141595     int count2 = 1;     while(fabs(temp)>=1e-6)     {       temp = pow(-1,count2++)*1.0/i;       pi += temp;       i = i+2;     } #endif     pi = pi * 4;     printf("%.6f\n",pi);      return 0; }   区别不是这两句执行的前后吗？：       pi += temp;       i = i+2;

这前后应该没什么影响吧?但是两种方式算出来的答案就是不一样,第一种是标准答案,第二种就是错的


Question: 计算2的n次方，不能使用乘法运算和循环

pow函数的参数可以是double类型的

x的y次方: pow(x,y); pow(2,n);可以么？

int two_x(int x) { int num = 1; num = num << x; return num; }

引用 3 楼 FoolCarpe的回复:不能使用乘法运算和循环， 用递归？ 递归不也是循环…嵌套循环…

对代表指数部份的段位加n，就可以了啊。

引用 10 楼 zhao4zhong1 的回复:[quote=引用 9 楼 Intel0011 的回复:] [quote=引用 8 楼 zhao4zhong1 的回复:] 你咋不想万一 要计算2的-1.2+2.3i次方捏？！ 不用搬出复数吧，如果n足够大的话，再强的机器也无法得到结果[/quote] 矫枉必须过正！[/quote] 我的想法也是这样，万一遇到浮点型的要考虑，毕竟题目没有说n的整数。真的需要考虑c的库函数，单纯去编是做不到的

真的需要考虑c的库函数，单纯去编是做不到的

计算2的n方：pow(2.0,n)  2要写成2.0   头文件  #include<math>

应该说只需要 与非 ( ~（A&B）， 储存（ LDR/STR ）， 分支( if )   就够了 ...  没循环的话， 很多操作要展开， 会写的很长 ....  不过也可以 .....

只用位运算 ( &, |, ^, <<, >>) 完全可以实现所有的 运算， 就稍微麻烦点， 浮点数，  复数啥的也没啥问题,  以前应该贴过 ....

引用 7 楼 Intel0011 的回复:如果可以使用C库函数的话，直接 double pow (double base, double exponent); 这位仁兄正解。哈哈哈

感觉就是考位运算的

过犹不及...

找pow函数的源代码看看。 参考一下：http://blog.csdn.net/xiaoxiongli/article/details/2134626

引用 9 楼 Intel0011 的回复:[quote=引用 8 楼 zhao4zhong1 的回复:] 你咋不想万一 要计算2的-1.2+2.3i次方捏？！ 不用搬出复数吧，如果n足够大的话，再强的机器也无法得到结果[/quote] 矫枉必须过正！

引用 8 楼 zhao4zhong1 的回复:你咋不想万一 要计算2的-1.2+2.3i次方捏？！ 不用搬出复数吧，如果n足够大的话，再强的机器也无法得到结果

你咋不想万一 要计算2的-1.2+2.3i次方捏？！

次方最基本的定义是:n为正整数，


Question: 括号匹配问题

#include <stdio.h> #include <string.h>  char Stack[10002], c[10002];  int main() {     int len;     while(~scanf("%s", c))     {         int top = 0; 	len = strlen(c);         for(int i = 0; i < len; i++)         {             if(top == 0 && (c[i] == ')' || c[i] == ']' || c[i] == '}' || c[i] == '>'))                 break;              switch(c[i])             {                 case '(': case '[': case '{': case '<':                     Stack[++top] = c[i];                     break;                 case ')':                     if(top>0 && Stack[top] == '(')                         top--;                     break;                 case ']':                     if(top>0 && Stack[top] == '[')                         top--;                     break;                 case '}':                     if(top>0 && Stack[top] == '{')                         top--;                     break;                 case '>':                     if(top>0 && Stack[top] == '<')                         top--;                     break;             }         }          if(top)             printf("NO\n");         else             printf("YES\n");     }      return 0; } 改成这样，把strlen(c);放到循环外，因为每次判断都需要计算一下，没必要，用一个变量len计算一次即可； 另外，你的程序不健壮，因为只输入}或者]或者)也会输出YES，这是逻辑的缺陷，建议继续查一下；

引用 2 楼 user-3 的回复:for(int i = 0; i < strlen(c); i++) 光把这句改掉估计就能过了 赞同，在循环里使用strlen特别耗时。

#include <stdio.h> #include <string.h>  char Stack[10002], c[10002];  int main() {     while(~scanf("%s", c))     {         int top = 0;          for(int i = 0; i < strlen(c); i++)         {             if(top == 0 && (c[i] == ')' || c[i] == ']' || c[i] == '}' || c[i] == '>'))                 break;              switch(c[i])             {                 case '(': case '[': case '{': case '<':                     Stack[++top] = c[i];                     break;                 case ')':                     if(top>0 && Stack[top] == '(')                         top--;                     break;                 case ']':                     if(top>0 && Stack[top] == '[')                         top--;                     break;                 case '}':                     if(top>0 && Stack[top] == '{')                         top--;                     break;                 case '>':                     if(top>0 && Stack[top] == '<')                         top--;                     break;             }         }          if(top)             printf("NO\n");         else             printf("YES\n");     }      return 0; }


Question: 如图

/* scanf example */ #include <stdio.h>  int main () {   char str [80];   int i;    printf ("Enter your family name: ");   scanf ("%s",str);     printf ("Enter your age: ");   scanf ("%d",&i);   printf ("Mr. %s , %d years old.\n",str,i);   printf ("Enter a hexadecimal number: ");   scanf ("%x",&i);   printf ("You have entered %#x (%d).\n",i,i);      return 0; }

main函数标准的写法是返回int型，有些系统会以该返回值判断程序是否返回成功，比如Makefile；另外一般还带2个参数：int argc, char **argv，用来传入参数，即形如"test arg1 arg2 agr3"这样的命令行调用。

引用 5 楼 qq_27014717 的回复:[quote=引用 4 楼 Season__0_0 的回复:] 除了上面的问题，还有main函数没有类型，没有返回值，一开始学养成良好的习惯吧 #include <stdio.h> int main() { int a; scanf("%d",&a); printf("%d",a); return 0; }教材上主函数都是void型，为什么你写的是int型，这个有什么说法吗，我看codeblocks新建源文件时打开的主函数也是int型[/quote]  选本靠谱的教材吧

同意一楼说法，另外，楼主，这不是anyview的作业吗，哈哈哈哈

引用 4 楼 Season__0_0 的回复:除了上面的问题，还有main函数没有类型，没有返回值，一开始学养成良好的习惯吧 #include <stdio.h> int main() { int a; scanf("%d",&a); printf("%d",a); return 0; }教材上主函数都是void型，为什么你写的是int型，这个有什么说法吗，我看codeblocks新建源文件时打开的主函数也是int型

引用 1 楼 hzy_76 的回复:空格用来分割输入，所以带空格时，+被当作了输入，他不是一个合法数字，a就是随机的值；没空格时+3就是3了。 赞同！  scanf函数是格式化输入，若不按照该函数指定的函数输入，那么结果可能是未定义的。

因为你把正号赋予了变量a，当遇到空格，则输入结束。


Question: 怎样让codeblocks使用最新的gcc和gdb?

1. 首先要下载并安装mingw，下载的是一个zip压缩文件，解压你就进入解压文件下，有一个MinGW-5.1.6.exe，点开后按提示安装就好了（记住路径）。 2. codeblocks配置MinGW，settings-->compiler-->selected compiler（选择GNU GCC Compiler）-->Toolchain executables：   compiler's installation directory：选择你的安装路径   点Auto-detect   重复第2步，直到selected compiler和compiler's installation directory显示都正确。 3. windows下安装gdb可以参考这个链接：https://blog.csdn.net/codebattle/article/details/38868313。 4. 编译完了，找到gdb目录下的gdb.exe文件，复制到MinGW\bin目录下。 5. 在codeblocks下配置调试器，setting-->debugger-->default-->executable path选择你的gdb.exe文件。

引用 4 楼 xsklld 的回复:https://sourceforge.net/projects/mingw-w64/ 非常感谢

引用 6 楼 hongwenjun 的回复:CB集成的是 TDM-GCC   你可以下载单独的 TDM-GCC  64，自己配置一下 CB 2018版快要出了，可以再等等 非常感谢，cb真是款好软件

Git_Vim_Gcc安装和使用视频  http://vc.yiche.com/vplay/136129.html

引用 2 楼 paschen 的回复:软件是不会自动帮你去下载的，需要你自己下载需要的编译器，然后安装设置 您好，不知道那些从gcc、gdb官网下载的文件怎么编译成.exe，在网上也找不到相关的教程

软件是不会自动帮你去下载的，需要你自己下载需要的编译器，然后安装设置

去官网上下载，再根据官网上的说明文档安装。不过，官网的文档似乎都是英文的，如果看不懂可以找一下翻译软件。


Question: 请大家帮我看看这个问题

还有个问题，问什么新建源文件的时候主函数默认是int型（教材上都是void型），而且有输出hello world的语句？

引用 2 楼 wang0635 的回复:两个文件的时候，由于调用aver的文件中没有它的声明，编译器就自行假定它的返回值是int型的了。实际的返回值在赋值给av之前已经另行解释成int了（不是强制转换），因此与你预期的不一样没看懂为什么结果是10

哇，真的可以，多谢各位

对，函数应该在主函数那页声明一下，才能正常的调用。

没发现有啥问题，放在两个文件里编译有没有提示警告？ aver函数需要在main.c文件里声明一下的，不然应该会提示警告


Question: 集合问题

引用 4 楼 倦怠的回复:递归效率不高，可以用动态规划解决 看你程序定位，如果只是小程序，就没必要追求极高效率

递归效率不高，可以用动态规划解决

可以试试用递归，在输出各个组合的时候判断m是否等于组合元素相加

只有相加，但不是两两，有可能三三四四，就是从集合中挑1到n个数相加。比如说：集合｛12345｝,1+2+3和1+2+3+4+5，这些都是它的拓展域。现在给定一个数m，判断是否m在拓展的集合，比如n=3时｛1 2 3｝可拓展为｛123456｝ 当输入m为1到6时 输出yes,否则输出no

这个集合的拓扑就是通过原有集合元素两两相加得到吗？还是有其他要求？比如，相乘，相减，相除，取余等等


Question: 段错误哪位大神能够解释一下，这是为什么？

#pragma comment(linker,"/SECTION:.rdata,RW") //加这句可以让常量区可写，后果自负！

引用 8 楼 qq_36179095 的回复:[quote=引用 6 楼 自信男孩的回复:]p指向的是只读数据段的数据"world",所以只读数据段的数据不能被修改，修改了（strcpy)就会提示段错误； &p是在栈上的地址，因为char *p是在栈上申请的一个指针变量，该变量是存放"world"只读数据段的地址。所以&p看到的地址是栈上的地址。 第二张图片，那个地址是什么呢？[/quote] 这个地址应该是段错误出现的内存位置

引用 6 楼 自信男孩的回复:p指向的是只读数据段的数据"world",所以只读数据段的数据不能被修改，修改了（strcpy)就会提示段错误； &p是在栈上的地址，因为char *p是在栈上申请的一个指针变量，该变量是存放"world"只读数据段的地址。所以&p看到的地址是栈上的地址。 第二张图片，那个地址是什么呢？

引用 5 楼 学习是无止境的的回复:[quote=引用 4 楼 Intel0011的回复:]char *p = "world";改为char p[] = "world"; char *p = "world";这样定义后p指向常量区，不能修改 char p[] = "world";这样定义后p指向栈区，可以修改 你看看这个图片呢，，，，，，，，，[/quote] 第二张图片，那个地址是什么呢？

引用 4 楼 Intel0011的回复:char *p = "world";改为char p[] = "world"; char *p = "world";这样定义后p指向常量区，不能修改 char p[] = "world";这样定义后p指向栈区，可以修改 你看看这个图片呢，，，，，，，，，

引用 1 楼 user-4的回复:p指向的是常亮区，不能改变里面的值 常量区，打错字了。。。

反过来就可以拷贝了，你试试

p指向的是常亮区，不能改变里面的值


Question: c结构体这个怎么改，定义后，声明时老是报错

那个结构体我写在头文件里面，然后调用的时候，没能调用，改了后，我写在了源文件里面，然后就没有报错了。  提问一下，结构体不能写在头文件里面吗？？

错误有点多，没好意思发。。。。 下面是错误； >c:\users\administrator\documents\visual studio 2015\projects\mysecond\mysecond\hero.cpp(3): error C4430: 缺少类型说明符 - 假定为 int。注意: C++ 不支持默认 int 1>c:\users\administrator\documents\visual studio 2015\projects\mysecond\mysecond\hero.cpp(3): error C2146: 语法错误: 缺少“;”(在标识符“heros”的前面) 1>c:\users\administrator\documents\visual studio 2015\projects\mysecond\mysecond\hero.cpp(4): error C4430: 缺少类型说明符 - 假定为 int。注意: C++ 不支持默认 int 1>c:\users\administrator\documents\visual studio 2015\projects\mysecond\mysecond\hero.cpp(4): error C2146: 语法错误: 缺少“;”(在标识符“jobs”的前面) 1>c:\users\administrator\documents\visual studio 2015\projects\mysecond\mysecond\hero.cpp(4): error C2143: 语法错误: 缺少“;”(在“{”的前面) 1>c:\users\administrator\documents\visual studio 2015\projects\mysecond\mysecond\hero.cpp(4): error C2447: “{”: 缺少函数标题(是否是老式的形式表?) 1>c:\users\administrator\documents\visual studio 2015\projects\mysecond\mysecond\hero.cpp(31): error C2065: “heros”: 未声明的标识符 1>c:\users\administrator\documents\visual studio 2015\projects\mysecond\mysecond\hero.cpp(31): error C2228: “.id”的左边必须有类/结构/联合 1>c:\users\administrator\documents\visual studio 2015\projects\mysecond\mysecond\hero.cpp(33): error C2065: “heros”: 未声明的标识符 1>c:\users\administrator\documents\visual studio 2015\projects\mysecond\mysecond\hero.cpp(33): error C2228: “.name”的左边必须有类/结构/联合 1>c:\users\administrator\documents\visual studio 2015\projects\mysecond\mysecond\hero.cpp(35): error C2065: “heros”: 未声明的标识符 1>c:\users\administrator\documents\visual studio 2015\projects\mysecond\mysecond\hero.cpp(35): error C2228: “.sex”的左边必须有类/结构/联合 1>c:\users\administrator\documents\visual studio 2015\projects\mysecond\mysecond\hero.cpp(40): error C2065: “jobs”: 未声明的标识符 1>c:\users\administrator\documents\visual studio 2015\projects\mysecond\mysecond\hero.cpp(40): error C2228: “.name”的左边必须有类/结构/联合 1>c:\users\administrator\documents\visual studio 2015\projects\mysecond\mysecond\hero.cpp(44): error C2065: “heros”: 未声明的标识符 1>c:\users\administrator\documents\visual studio 2015\projects\mysecond\mysecond\hero.cpp(44): error C2228: “.job”的左边必须有类/结构/联合 1>c:\users\administrator\documents\visual studio 2015\projects\mysecond\mysecond\hero.cpp(44): error C2065: “jobs”: 未声明的标识符 1>c:\users\administrator\documents\visual studio 2015\projects\mysecond\mysecond\hero.cpp(45): error C2065: “heros”: 未声明的标识符 1>c:\users\administrator\documents\visual studio 2015\projects\mysecond\mysecond\hero.cpp(45): error C2228: “.name”的左边必须有类/结构/联合 1>c:\users\administrator\documents\visual studio 2015\projects\mysecond\mysecond\hero.cpp(45): error C2228: “.job”的左边必须有类/结构/联合 1>c:\users\administrator\documents\visual studio 2015\projects\mysecond\mysecond\hero.cpp(33): warning C4477: “scanf_s”: 格式字符串“%s”需要类型“char *”的参数，但可变参数 1 拥有了类型“int” 1>  c:\users\administrator\documents\visual studio 2015\projects\mysecond\mysecond\hero.cpp(33): note: 此参数由转换说明符使用 1>c:\users\administrator\documents\visual studio 2015\projects\mysecond\mysecond\hero.cpp(33): warning C4473: “scanf_s”: 没有为格式字符串传递足够的参数 1>  c:\users\administrator\documents\visual studio 2015\projects\mysecond\mysecond\hero.cpp(33): note: 占位符和其参数预计 2 可变参数，但提供的却是 1 参数 1>  c:\users\administrator\documents\visual studio 2015\projects\mysecond\mysecond\hero.cpp(33): note: 缺失的可变参数 2 为格式字符串“%s”所需 1>  c:\users\administrator\documents\visual studio 2015\projects\mysecond\mysecond\hero.cpp(33): note: 此参数用作缓冲区大小 1>c:\users\administrator\documents\visual studio 2015\projects\mysecond\mysecond\hero.cpp(35): warning C4477: “scanf_s”: 格式字符串“%c”需要类型“char *”的参数，但可变参数 1 拥有了类型“int” 1>  c:\users\administrator\documents\visual studio 2015\projects\mysecond\mysecond\hero.cpp(35): note: 此参数由转换说明符使用 1>c:\users\administrator\documents\visual studio 2015\projects\mysecond\mysecond\hero.cpp(35): warning C4473: “scanf_s”: 没有为格式字符串传递足够的参数 1>  c:\users\administrator\documents\visual studio 2015\projects\mysecond\mysecond\hero.cpp(35): note: 占位符和其参数预计 2 可变参数，但提供的却是 1 参数 1>  c:\users\administrator\documents\visual studio 2015\projects\mysecond\mysecond\hero.cpp(35): note: 缺失的可变参数 2 为格式字符串“%c”所需 1>  c:\users\administrator\documents\visual studio 2015\projects\mysecond\mysecond\hero.cpp(35): note: 此参数用作缓冲区大小 1>c:\users\administrator\documents\visual studio 2015\projects\mysecond\mysecond\hero.cpp(40): warning C4473: “printf”: 没有为格式字符串传递足够的参数 1>  c:\users\administrator\documents\visual studio 2015\projects\mysecond\mysecond\hero.cpp(40): note: 占位符和其参数预计 1 可变参数，但提供的却是 0 参数 1>  c:\users\administrator\documents\visual studio 2015\projects\mysecond\mysecond\hero.cpp(40): note: 缺失的可变参数 1 为格式字符串“%s”所需 1>c:\users\administrator\documents\visual studio 2015\projects\mysecond\mysecond\hero.cpp(43): warning C4477: “scanf_s”: 格式字符串“%d”需要类型“int *”的参数，但可变参数 1 拥有了类型“int” 1>c:\users\administrator\documents\visual studio 2015\projects\mysecond\mysecond\hero.cpp(45): warning C4473: “printf”: 没有为格式字符串传递足够的参数 1>  c:\users\administrator\documents\visual studio 2015\projects\mysecond\mysecond\hero.cpp(45): note: 占位符和其参数预计 2 可变参数，但提供的却是 0 参数 1>  c:\users\administrator\documents\visual studio 2015\projects\mysecond\mysecond\hero.cpp(45): note: 缺失的可变参数 1 为格式字符串“%s”所需

我有我的看法。 1、对于代码，我看到的问题是，给结构体赋值Hero.cpp中，没有new空间，应该new出char的空间和new出结构体的空间。 2、你说结构体声明的时候出错了，建议贴出来错误信息哈，更多热能够参与解答，这样有猜测的嫌疑。

什么意思，没看懂

char const *

Hero heros[5];   好像这一句有问题

看了各位的回复，去改了改，还是有些错误

建议你把结构体初始化写进 inputHero()里试试，而且你的sacnf_s缺少参数， jobChoice设置一个初始值，而且你的heros[i].job = jobs[jobChoice - 1];中的heros[i]后的是不是写错了？  我也是新手，只能帮你的到这了

个人一点看法，在c++中，虽然struct和class差别不大。 在struct中，尽量少用指针，最好用字符数组的形式。这样便于struct的直接赋值。 比如：struct job {     int id;     char name[24];//职业名称     char desc[24]; };用string虽然也可以直接赋值，但在某些场合也麻烦，比如要对struct序列化进行保存到文件或传输到网络的时候，用string也要进一步处理，不如char[]方便。 如果确实需要用指针或者string，还是用class更合理。 因为对struct，总有感觉是可以用memset(&struct, 0, sizeof(struct))这类操作，而不会有人对class这样用。

scanf_s("%s", heros[i].name); //换成 scanf_s("%s", heros[i].name, 50);          scanf_s("%c", &heros[i].sex); //换成 scanf_s("%c", &heros[i].sex, 1); scanf_s相比scanf更安全，安全在多一个参数，用于注明缓存的大小；

多学习下


Question: 新人求问

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

输入格式太过严格了吧，还有就是提示什么样的错误请明示。

将float改为double 双精度就可以

scanf("%.2f\n",&amount);中的\n会导致scanf挂起，原因是"%f\n"或"%f "使scanf函数跳过空白符，读取一个浮点数数，然后跳到下一个非空白符处才返回

scanf不支持按照精度输入，所以直接用%f格式输入，输出是可以格式化printf

[quote=引用 3 楼 hefashion0190 的回复:] float有效数字很短,当有小数位的时候丢失精度基本很常见..有的小数的二进制表示是很长很长的.................... 但是float变量的存储空间又是很小很小的........................ 所以就截断了很多,所以很容易近似................... 你要是输入一个100,它肯定没误差，因为小数位的二进制全是0(应该是0吧..). 所以,尽量让变量的内存空间大一点.........有效数字多一点........... 就可以多表示点小数位的二进制,就精确了很多..........可能截断那么一点都怎样,通过输出的.精度控制一下，就是你想要的了.  #include <stdio.h>  int main(int argc, char *argv[]) {     double num;     scanf("%lf",&num);     printf("\n%.2lf",num);//注意.控制四舍五入保留2位小数      getchar(); //吃回车     getchar(); //等待输入退出     return 0; }   摘自http://bbs.csdn.net/topics/340072804 7楼  main函数返回值为void，return (0) 没报错？  [/quo  没有任何报错，就是结果不对。应该是scanf 这个函数用错了。

引用 2 楼 cfjtaishan 的回复:#include <stdio.h>  void  main() {     float amount,sum;      printf("Enter an amount:");     scanf("%f",&amount);      sum = amount +0.05*amount;     printf("with tax added:$%.2f\n",sum);      return(0); } 对printf可以%.2f输出，对于输入不建议使用。  参考你的已经解决了，非常感谢，书上写的scanf函数是可以有%.2f的输出的，我还是慢慢学，谢谢！

[quote=引用 1 楼 hzy_76 的回复:] 结果差了多少？ 浮点数的计算结果可能跟你的预期不是精确一致的。如果你要很精确的结果，可以转成整数计算，比如以分为单位进行。[/quote   结果是个随机的数 吧，反正相差很多，参考楼下的，已经解决了，谢谢谢谢！


Question: pc端用c#调用蓝牙接收单片机数据

写程序调用蓝牙驱动?


Question: 新手请教一个socket问题

问题已经解决了：　原来recv还需要循环接收  引用 楼主 user-0 的回复:问题：客户端发送一次数据后，第二次服务端接收不了啦，只能接收一次是为什么      服务端代码： #include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <sys/types.h> #include <sys/socket.h> #include <arpa/inet.h> #include <netinet/in.h> #include <string.h>   int main() { 	int sfd, cfd; 	struct sockaddr_in server_addr; 	char buff[10];  	//创建套接字 	if( (sfd=socket(AF_INET, SOCK_STREAM, 0))<0 ){ 		perror("create socket error!"); 		exit(0); 	} 	 	memset(&server_addr, 0, sizeof(server_addr)); 	server_addr.sin_family = AF_INET; 	server_addr.sin_port = htons(8888); 	server_addr.sin_addr.s_addr = htonl(INADDR_ANY);		//通配符地址  	//防止服务器关闭后需要等待TIME_WAIT状态才能才继续使用address 	int on=1; 	if ( setsockopt(sfd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on))<0 ){ 		perror("set socket opt fail!\n"); 		exit(0); 	} 	//绑定套接字 	if( bind(sfd, (struct sockaddr *)&server_addr, sizeof(server_addr))==-1 ){ 		perror("bind has error!\n"); 		exit(0); 	} 	 	//监听套接字 	if( listen(sfd, 10)==-1 ) { 		perror("listen has error!\n"); 		exit(0); 	} 	 	//接收客户端 	while(1){ 		puts("waitting for client on 888"); 		if( (cfd = accept(sfd,  (struct sockaddr *)NULL, NULL)) > -1 ) { 			printf("new socket fd:%d\n", cfd); 		} 		 		int n; 		if( (n = recv(cfd, buff, strlen(buff), 0)) < 0 ) { 			puts("recv data fail\n"); 			exit(0); 		} 	    buff[n] = '\0';     	printf("recv msg from client: %s\n", buff); 		puts(buff); 		close(cfd); 	} 	 	//关闭close(); 	close(sfd); 	 	return 0; }  客户端代码： #include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <sys/types.h> #include <sys/socket.h> #include <arpa/inet.h> #include <netinet/in.h> #include <string.h>  int main() { 	int cfd; 	struct sockaddr_in server_addr; 	char buff[10]; 	 	//创建socket 	server_addr.sin_family = AF_INET; 	server_addr.sin_port = htons(8888); 	server_addr.sin_addr.s_addr = inet_addr("127.0.0.1"); 	 	cfd = socket(AF_INET, SOCK_STREAM, 0); 	if( cfd<0 ) { 		perror("create socket error\n!"); 		exit(0); 	} 	 	//连接 	if( connect(cfd, (struct sockaddr *)&server_addr, sizeof(server_addr)) ==-1 ){ 		perror("connect has error!\n"); 		exit(1); 	} 	printf("connect with destination host...\n");   	 	while(1){ 		memset(buff, 0, strlen(buff)); 		scanf("%s", buff); 		send(cfd, buff, strlen(buff), 0); 	} 	 	 	//关闭close(); 	close(cfd); }


Question: c语言 二维数组数组名问题

引用 13 楼 qq_33194620 的回复:[quote=引用 10 楼 chenqi123_ 的回复:] 除了优先级以外,下标引用和间接访问完全相同,对于C选项来说: (*(a+1)[1])等价于(a[1])[1],即a[1][1] 那为什么我运行出来，输出的不是a[1][1]的地址呢，好纠结。[/quote] 谢谢，也就是说这道题目却是存在问题对吧。

不好意思我那个看错了,C应该是括号括错了

引用 10 楼 chenqi123_ 的回复:除了优先级以外,下标引用和间接访问完全相同,对于C选项来说: (*(a+1)[1])等价于(a[1])[1],即a[1][1] 那为什么我运行出来，输出的不是a[1][1]的地址呢，好纠结。

不要迷信书、考题、老师、回帖； 要迷信CPU、编译器、调试器、运行结果。 并请结合“盲人摸太阳”和“驾船出海时一定只带一个指南针。”加以理解。 任何理论、权威、传说、真理、标准、解释、想象、知识……都比不上摆在眼前的事实！

http://edu.csdn.net/course/detail/2516 C语言指针与汇编内存地址-三.数组和二维数组

《C++二维数组》 http://blog.csdn.net/hou09tian/article/details/78421982 《C++数组地址偏移》 http://blog.csdn.net/hou09tian/article/details/75332577 《C++中的指针数组与数组指针》 http://blog.csdn.net/hou09tian/article/details/77426750 希望能帮到你

个人觉得应该选C和D。 A和B都可以表示a[1][1]，原因我觉得你分析的很到位。 假设 int a[3][4] = { 0,1,2,3,4,5,6,7,8,9,10,11}; a+1则指向{4,5,6,7}需要注意的是，此时a+1的类型仍然是3×4的多维数组，所以，此时的(a+1)[1]应该指向的是{8， 9， 10， 11}，如图所示  而方括号[]的优先级高于星号*，所以选项C，*(a+1)[1]的值应该是8。 对于选项D，*(a+5)的类型是数组的地址，而不是数组的一个具体元素值。

选项C的括号是不必要的，间接说明括号位置错了。应该是 (*(a + 1))[1] 正确答案是D，同时选项C括号位置应该改正

意思是这题答案不唯一？ 可这是研究生考题啊，怎么会出现这种错误

C和D都不能表示a[1][1]  D如楼主所说。 说 一下C，(*(a+1)[1])，首先a的类型相当于一个指向有4个整数的数组的指针，与 int (*b)[4]中的b指针类型是一样的，那 a+1就指向了下一行，也就是&a[1][0]，但a的类型不变，我们让 b=a+1，然后(a+1)[1]也就是b[1]，这又指向了下一行，也就是&a[2][0]，解引用之后就得到了a[2][0].

引用 2 楼 qq_33194620 的回复:那这题答案是什么 答案就是你说的AB呢  *(a+1)[1]就是相当于a[2][0]呢

那这题答案是什么

注意[]的优先级高于*所以(a+1)[1]为一体，即等价于*((a+1)[1])。  (a+1)[1]就相当于*((a+1)+1)，所以*(a+2)即a[2]为第三行的首地址； 然后在加上前面的*，所以取得的就是第三行的第一个元素的值；   可以参考一下如下的链接： http://bbs.csdn.net/topics/320177279


Question: 这段二叉树非递归先序遍历含义不是太懂

仅供参考：#include <iostream> #include <stack> #include <queue> #include <locale.h> using namespace std; typedef struct BiTNode {//二叉树结点     char data;                      //数据     struct BiTNode *lchild,*rchild; //左右孩子指针 } BiTNode,*BiTree; int CreateBiTree(BiTree &T) {//按先序序列创建二叉树     char data;     scanf("%c",&data);//按先序次序输入二叉树中结点的值（一个字符），‘#’表示空树     if (data == '#') {         T = NULL;     } else {         T = (BiTree)malloc(sizeof(BiTNode));         T->data = data;         //生成根结点         CreateBiTree(T->lchild);//构造左子树         CreateBiTree(T->rchild);//构造右子树     }     return 0; } void Visit(BiTree T) {//输出     if (T->data != '#') {         printf("%c ",T->data);     } } void PreOrder(BiTree T) {//先序遍历     if (T != NULL) {         Visit(T);               //访问根节点         PreOrder(T->lchild);    //访问左子结点         PreOrder(T->rchild);    //访问右子结点     } } void InOrder(BiTree T) {//中序遍历     if (T != NULL) {         InOrder(T->lchild);     //访问左子结点         Visit(T);               //访问根节点         InOrder(T->rchild);     //访问右子结点     } } void PostOrder(BiTree T) {//后序遍历     if (T != NULL) {         PostOrder(T->lchild);   //访问左子结点         PostOrder(T->rchild);   //访问右子结点         Visit(T);               //访问根节点     } } void PreOrder2(BiTree T) {//先序遍历(非递归) //访问T->data后，将T入栈，遍历左子树；遍历完左子树返回时，栈顶元素应为T，出栈，再先序遍历T的右子树。     stack<BiTree> stack;     BiTree p = T;//p是遍历指针     while (p || !stack.empty()) {   //栈不空或者p不空时循环         if (p != NULL) {             stack.push(p);          //存入栈中             printf("%c ",p->data);  //访问根节点             p = p->lchild;          //遍历左子树         } else {             p = stack.top();        //退栈             stack.pop();             p = p->rchild;          //访问右子树         }     } } void InOrder2(BiTree T) {//中序遍历(非递归) //T是要遍历树的根指针，中序遍历要求在遍历完左子树后，访问根，再遍历右子树。 //先将T入栈，遍历左子树；遍历完左子树返回时，栈顶元素应为T，出栈，访问T->data，再中序遍历T的右子树。     stack<BiTree> stack;     BiTree p = T;//p是遍历指针     while (p || !stack.empty()) {   //栈不空或者p不空时循环         if (p != NULL) {             stack.push(p);          //存入栈中             p = p->lchild;          //遍历左子树         } else {             p = stack.top();        //退栈，访问根节点             printf("%c ",p->data);             stack.pop();             p = p->rchild;          //访问右子树         }     } }  typedef struct BiTNodePost{     BiTree biTree;     char tag; } BiTNodePost,*BiTreePost; void PostOrder2(BiTree T) {//后序遍历(非递归)     stack<BiTreePost> stack;     BiTree p = T;//p是遍历指针     BiTreePost BT;     while (p != NULL || !stack.empty()) {//栈不空或者p不空时循环         while (p != NULL) {//遍历左子树             BT = (BiTreePost)malloc(sizeof(BiTNodePost));             BT->biTree = p;             BT->tag = 'L';//访问过左子树             stack.push(BT);             p = p->lchild;         }         while (!stack.empty() && (stack.top())->tag == 'R') {//左右子树访问完毕访问根节点             BT = stack.top();             stack.pop();//退栈             printf("%c ",BT->biTree->data);         }         if (!stack.empty()) {//遍历右子树             BT = stack.top();             BT->tag = 'R';//访问过右子树             p = BT->biTree;             p = p->rchild;         }     } }  void LevelOrder(BiTree T) {//层次遍历     if (T == NULL) return;     BiTree p = T;     queue<BiTree> queue;//队列     queue.push(p);//根节点入队     while (!queue.empty()) {    //队列不空循环         p = queue.front();      //对头元素出队         printf("%c ",p->data);  //访问p指向的结点         queue.pop();            //退出队列         if (p->lchild != NULL) {//左子树不空，将左子树入队             queue.push(p->lchild);         }         if (p->rchild != NULL) {//右子树不空，将右子树入队             queue.push(p->rchild);         }     } } int main() {     BiTree T;      setlocale(LC_ALL,"chs");     CreateBiTree(T);      printf("先序遍历        ：");PreOrder  (T);printf("\n");     printf("先序遍历(非递归)：");PreOrder2 (T);printf("\n");                                                printf("\n");     printf("中序遍历        ：");InOrder   (T);printf("\n");     printf("中序遍历(非递归)：");InOrder2  (T);printf("\n");                                                printf("\n");     printf("后序遍历        ：");PostOrder (T);printf("\n");     printf("后序遍历(非递归)：");PostOrder2(T);printf("\n");                                                printf("\n");     printf("层次遍历        ：");LevelOrder(T);printf("\n");      return 0; } //ABC##DE#G##F### //先序遍历        ：A B C D E G F //先序遍历(非递归)：A B C D E G F // //中序遍历        ：C B E G D F A //中序遍历(非递归)：C B E G D F A // //后序遍历        ：C G E F D B A //后序遍历(非递归)：C G E F D B A // //层次遍历        ：A B C D E F G //  ///       A ///      / ///     B ///    / \ ///   C   D ///      / \ ///     E   F ///      \ ///       G  代码功能归根结底不是别人帮自己看或讲解或注释出来的；而是被自己静下心来花足够长的时间和精力亲自动手单步或设断点或对执行到某步获得的中间结果显示或写到日志文件中一步一步分析出来的。 提醒：再牛×的老师也无法代替学生自己领悟和上厕所！ 单步调试和设断点调试（VS IDE中编译连接通过以后，按F10或F11键单步执行，按Shift+F11退出当前函数；在某行按F9设断点后按F5执行停在该断点处。）是程序员必须掌握的技能之一。  “给定一个小点的输入，完整单步跟踪(同时按Alt+7键查看Call Stack里面从上到下列出的对应从里层到外层的函数调用历史)一遍。”是理解递归函数工作原理的不二法门！ 递归函数关注以下几个因素 ·退出条件 ·参数有哪些 ·返回值是什么 ·局部变量有哪些 ·全局变量有哪些 ·何时输出 ·会不会导致堆栈溢出

求助求助求助

典型的用栈代替函数递归调用。先访问当前节点数据，然后右子树压栈，左子树压栈，若没有左子树和右子树，说明这个分支到底了，弹出上一级的节点。 对应的递归算是：   void f52(BiTree T,void(*visit)(TElemmType)) { isit(T->data); if(p->rchild!=NULL) f52(p->rchild, visit); if(p->lchild!=NULL) f52(p->lchild, visit); }


Question: 新手编斐波那契数列，程序有些问题

每次在循环里面都给a 和 b 赋值1，所以结果是2。应该把赋值语句放循环前面。

可以用数值储存计算好的值后，以后再调用

#include <stdio.h> int main() {    int f1=1,f2=1,f3;    int i;    printf("%12d\n%12d\n",f1,f2);    for(i=1;i<=38;i++)    //40个    { 	   f3=f1+f2; 	   printf("%12d\n",f3); 	   f1=f2; 	   f2=f3;    }    return 0; }

a, b放在循环里定义，其作用域是for循环体内。每次循环体执行一遍，就会释放，然后重新定义，并初始化为1，所以，a ,b的值在每次循环开始时都是固定的1

#include <stdio.h>  int main(void) {    int i, a, b, c, num;     printf("请输入第num位数:");    scanf("%d", &num);     a = b = 1;    for (i = 0;  i < num - 2; ++i)    {       c = a + b;       a = b;       b = c;    }     printf("%d\n", c);    return 0; }

#include <stdio.h>  int main() {     int i, a, b, c, num;     printf("请输入第num位数:");     scanf("%d",&num);     a = b = 1;     if(1==num)     {         printf("%d\n",a);     }     else if(2==num)     {         printf("%d\n%d\n",a,b);     }     else if(num >2)     {         printf("%d\n%d\n",a,b);         for(i=3;i<=num;i++)         {             c = a+b;             a = b;             b = c;             printf("%d\n",b);         }     }     else     {         printf("num error!\n");         return -1;     }     return 0; }

每次都初始化a b 为1 这结果绝对不会变


Question: 菜鸟提一个关于数组指针的问题，求大神解答

理解和讨论之前请先学会如何观察！ //char (*(*x[3])())[5];//x是什么类型的变量? // //分析C语言声明，关键是搞清楚这个变量是个什么东西（函数、指针、数组）， //是函数那么剩下的就是他的参数和返回值， //是指针那剩下部分是说明他指向什么， //是数组剩下的部分就是说明数组的成员是什么类型。 //解析C语言声明规则： //从左侧第一个标识符开始，按照优先级进行结合。*表示是..的指针，const表示只读的，volatile表示可变的，[]表示是数组，()表示是函数。 // //x和[3]结合说明是一个大小为3的数组，该数组的每个元素为一类指针，该类指针指向一类函数，该类函数无参数，返回一类指针，该类指针指向一个大小为5的char型数组 #include <stdio.h> #include <typeinfo.h> char num[5]; char (*x00())[5] {     return # } int main() {     char (*(*x[3])())[5];//是个数组，大小为3     char (*(*x0  )())[5];//数组的元素，是个函数指针     char (*( x00 )())[5];//函数原型，参数为空，返回值为指针     char (*  x000   )[5];//返回值      x0 = x00;     x[0] = x0;     x[1] = x0;     x[2] = x0;     printf("typeid(x).name() is %s\n",typeid(x).name());     return 0; } //typeid(x).name() is char (* (__cdecl**)(void))[5]

引用 4 楼 tecsai的回复:可以看做类型定义，其实也是强制转换。 好的谢谢大神，十分感谢

引用 2 楼 自信男孩的回复:int (*p)[2]是指向一个二维数组的指针，并且该二维数组是一个列数为2的（行数不固定）。这样的指针叫做数组指针，即指向数组的指针；和它比较混的就是指针数组 int *q[2];这是一个定义了2个指针元素的数组，即数组中的元素都是int *指针；int (*p)[2]指向的数组元素都是int类型的数值。  int []的写法是强制类型转换，因为{1, 2}的类型可以理解为一维数组，比如int arr[2] = {1, 2}; int (*p)[2]上面已经讲了是数组指针，指向二维数组，所以类型是不匹配的。 但是这种强制类型转换是否有效我是持怀疑态度的；  以下是int (*p)[2]的使用。 int (*p)[2]; int arr[5][2] = { {1, 2} }; p = arr; 好的谢谢大神，十分感谢

引用 1 楼 user-5的回复:int(*p)[2] = (int[]) { 1, 2 };应该写成int *p = (int[]) { 1, 2 }; 这是C99中的复合赋值，C89不支持 C89的写法是 int b[2] = { 1,2 }; int(*p1)[2] = &b; //不是int(*p1)[2] = b; 好的谢谢大神，十分感谢

可以看做类型定义，其实也是强制转换。

C99中，复合赋值中，可以指定对象类型的数组、结构或联合表达式。当使用复合赋值时，应在括弧内指定类型，后跟由花括号围起来的初始化列表；若类型为数组，则不能指定数组的大小。建成的对象是未命名的。 　　例： double *fp = (double[]) {1.1, 2.2, 3.3}; 　　该语句用于建立一个指向double的指针fp，且该指针指向这个3元素数组的第一个元素。 在文件域内建立的复合赋值只在程序的整个生存期内有效。在模块内建立的复合赋值是局部对象，在退出模块后不再存在。

C89或者C++都不支持这种用法

int b[2] = { 1,2 }; int(*p1)[2] = b; 这种写法是不对的，类型不匹配；  int b[2] = {1, 2}; int *p = b;


Question: 请问编写同一程序，用有参函数编写快还是无参函数编写快

当然是直接把函数展开更快啦，根本就没有函数调用的开销了。 不过你要清楚你到底想做什么，而不是纠结于这一点点的压栈的开销

参数的有无不是根据这个来决定了，参数的有无是接口设计决定的。可以根据自己需求设计来确定是否需要参数； 比如，求一个数组里的最大元素；若无参数定义求最大值的函数，那么该数组就要定义成全局的。这样做是没问题的，定义成全局的可能要考虑维护全局变量；若该数组长度较大（占用空间几K设置是几M），那么可以考虑定义成全局变量，若此时在栈上申请，就会得不偿失；若数组长度较小，可以考虑定义形参，通过参数传递到求最大值的自定义函数； 总之，参数是函数与外界交互的一个窗口，对于参数有无和定义多少要根据需求设计来定，需要权衡一些条件。

无profiler不要谈效率！！尤其在这个云计算、虚拟机、模拟器、CUDA、多核 、多级cache、指令流水线、多种存储介质、……满天飞的时代！

参数是调用函数和被调用函数，交互用的 有参的肯定要比无参多几个指令， 但是你不能为了节省这点性能，就不要参数。 就好比为了省钱就不吃饭了。

最根本的问题是“函数是干什么用的？” 如果能狗回答这个问题，其余一切自然会恍然大悟

函数不用参数就要用全局变量，不可取。 这点性能影响微不足道。 如果你原意的话，可以不用函数，每个调用函数的地方用完整代码替代，这比调用函数不用参数还快。

不用参数只能用全局变量，这不是一个好的选择。

参数个数不宜过多（控制在<= 5)，参数多了会影响函数调用效率；