Question: C程序设计语言这本书的第五章的第10题，谁帮我看下哪里有问题呢？

命令行想输入*需要用^*代替。  命令行解释器概述 命令行解释器是一个单独的软件程序，它可以在用户和操作系统之间提供直接的通讯。非图形命令行解释器用户界面提供运行基于字符的应用程序和实用程序的环境。通过使用类似于 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。

就是乘法不能用，只能用X替代*号后才能用乘法。我想不明白

//不知道你说的是什么问题，程序是可以运行的

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


Question: 问个模块封装的问题

你给num2提供赋值函数，不给num1提供赋值函数，也是可以的。 但是有的人倾向于既然给num2提供了赋值函数，就给所有num提供赋值函数，这样看起来更整齐规范。  void Test_set_num1(Test_t *test, int value); void Test_set_num2(Test_t *test, int value); void Test_set_num3(Test_t *test, int value); void Test_set_num4(Test_t *test, int value);  这样把这个模块拿给别人用时，别人一看头文件就一目了然，清晰易懂。 其实这些很大程度上都是编码风格问题，不必过于纠结。 现在很多库都没有给出此类赋值函数，哪怕是限制对num1的赋值只允许在1-5之间，也仅仅是通过注释或文档来告知程序员。

模块化就是希望其他模块在与之交互的时候减少耦合，提供这个接口给你用就是希望你不需要管这个接口的实现细节，你只管调用，即使以后改了实现细节（包括修改struct Test_t)你也可以不用修改你的代码，如果说不提供那么首先 你每个人在修改全局变量的时候你可能使用gTest.num1=value;这样的代码，这就要求 你的代码里面必须知道 Test_t的完整定义。而且一旦Test_t的细节被修改比如num1改成了num_m那么所有gTest.num1=value;的代码都需要被修改 而且这些代码都需要重新编译

搞一个头文件，既让模块用，也让使用这个模块的源文件用。 /*********public.h goes here***************/ typedef struct __Test {     int num1;     int num2;     int num3;     int num4;     char str[10]; } Test_t;   extern Test_t  gTest;

引用 4 楼 CharlesSimonyi 的回复:如果只是简单的直接赋值test->num1 = value;那么不需要，除非你要对它的赋值操作进行一些限制、干预等才需要这么用。 比如Test_t.num1的值只能在1-5之间，则限制对它的赋值：  bool Test_set_num1(Test_t *test, int value) { 	if (value < 1 || value > 5) 		return false; 	test->num1 = value; 	return true; }  又比如Test_t.num1表示毫秒，但是设置的时候用的单位是秒，则对它的赋值进行一些干预：  bool Test_set_num1(Test_t *test, int value) { 	test->num1 = value * 1000; }   当然也许是编程风格问题，整个项目中一些地方用到了这种赋值函数，则进行统一，对所有的结构体成员都提供赋值函数，这样更好看，规范。  比如 num1很简单，只是++或者-- 但num2有点限制  那么给num2写个接口访问，num1直接++或者--？

引用 3 楼 zhao4zhong1 的回复:请牢记：源代码本身的书写是否结构化或面向对象或符合设计模式或敏捷…并不重要，重要的是你是否使用结构化或面向对象或符合设计模式或敏捷…的方法命名标识符、阅读、修改、检查、测试源代码。  To set a breakpoint when a variable changes value   From the Edit menu, click Breakpoints. Click the Data tab of the Breakpoints dialog box. In the Expression text box, type the name of the variable. Click OK to set the breakpoint. 引用 3 楼 zhao4zhong1 的回复:请牢记：源代码本身的书写是否结构化或面向对象或符合设计模式或敏捷…并不重要，重要的是你是否使用结构化或面向对象或符合设计模式或敏捷…的方法命名标识符、阅读、修改、检查、测试源代码。  To set a breakpoint when a variable changes value   From the Edit menu, click Breakpoints. Click the Data tab of the Breakpoints dialog box. In the Expression text box, type the name of the variable. Click OK to set the breakpoint. 你能像楼下的哪位一样吗？太抽象了

用一个接口去访问是要好一些，比如以后你要修改的话，直接修改这个接口就行了 如果你直接使用gTest = value之类的，以后修改就麻烦了

引用 5 楼 wangjun403 的回复:[quote=引用 3 楼 zhao4zhong1 的回复:] 请牢记：源代码本身的书写是否结构化或面向对象或符合设计模式或敏捷…并不重要，重要的是你是否使用结构化或面向对象或符合设计模式或敏捷…的方法命名标识符、阅读、修改、检查、测试源代码。  To set a breakpoint when a variable changes value   From the Edit menu, click Breakpoints. Click the Data tab of the Breakpoints dialog box. In the Expression text box, type the name of the variable. Click OK to set the breakpoint. 引用 3 楼 zhao4zhong1 的回复:请牢记：源代码本身的书写是否结构化或面向对象或符合设计模式或敏捷…并不重要，重要的是你是否使用结构化或面向对象或符合设计模式或敏捷…的方法命名标识符、阅读、修改、检查、测试源代码。  To set a breakpoint when a variable changes value   From the Edit menu, click Breakpoints. Click the Data tab of the Breakpoints dialog box. In the Expression text box, type the name of the variable. Click OK to set the breakpoint. 你能像楼下的哪位一样吗？太抽象了[/quote] 我的意思是没必要弄什么劳什子接口函数。 过早的优化是万恶之源。 真到了不知道在哪里全局变量被修改的那一天，还有数据改变断点帮助你。


Question: 问个预处理的问题

不结帖的同学不是好经理。

#include<stdio.h> #include<stdlib.h>  #define PRINT_VAR(fmt, var) printf(#var " = "#fmt, var)  int main(int argc, char *argv[]) {     int aa = 5;     int bb = 6;     int cc = 7;      PRINT_VAR("%d", aa);      return 0; }

#define NAME(x) #x

VC编译选项加/EP /P，重新编译，查看宏展开后对应的.i文件。gcc加-E

"%s\n","NAME(aa)"     后面也加引号？

#include<stdio.h> #include<stdlib.h> #define NAME(x) #x  int main(){ int aa = 5; int bb = 6; int cc = 7; printf("%s\n",NAME(aa));//这里的预处理中的aa我想改成"aa"字符串类型  如何修改呢？？？ } 你想这样？


Question: 空间、指针的释放

引用 6 楼 wuhailin1987 的回复:#include <stdio.h> #include <stdlib.h> int main() { 	int len = 5; 	char *array = (char *)malloc( len*sizeof( char ) ); 	int i; 	for (i = 0; i < len; i++) 	{ 	/*something to do with array*/ 		printf("%d\t", array[i]); // 用数组来做 	} 	printf("\n"); 	free(array); 	return 0; } 对不住啊，刚才引用失误了... 数组确实有效

引用 7 楼 dbzhang800 的回复:[quote=引用 5 楼 zcppacers 的回复:] 谢谢！ free的机制是认的申请地址的首位么？还是说必须是指定的某个变量+初始位置？因为我又试了下用一个中间的指针变量  char *tmp = array; ....../*中间还是对array进行操作*/ free(tmp); tmp=NULL;  这样就不行  你怎么判断的不行？[/quote] 因为报错...

引用 6 楼 wuhailin1987 的回复:#include <stdio.h> #include <stdlib.h> int main() { 	int len = 5; 	char *array = (char *)malloc( len*sizeof( char ) ); 	int i; 	for (i = 0; i < len; i++) 	{ 	/*something to do with array*/ 		printf("%d\t", array[i]); // 用数组来做 	} 	printf("\n"); 	free(array); 	return 0; } 因为报错...

free(array-len);

很多内存是这么管理的 [alloc struct][block alloc for use ] 在分配的内存块前面，设置一个数据结构， 记录已经分配的内存相关的数据 free(p) 的时候在p前面，找到这个 结构，把这块内存回收， 记录为未分配的内存，以便以后可以重新分配 当然，也可以利用数组，链表记录已经分配的内存位置 总之，已经分配的内存的地址，是有个数据结构记录的 free 可以凭借当初分配的那个地址值， 查到分配时候的记录，然后回收这块内存，以便重新利用  如果 p 这个值丢失了，你就无法主动释放了。 如果这个值改变了，free一个改变的值， 查找就会发生错误，free函数 出错， 甚至造成内存分配记录出错， 以后的再分配内存就会出错。

引用 4 楼 sholber 的回复:一般来说是没有办法的。但就你这个程序本身而言，还是有办法的： int len = 5; char * array = (char *) malloc ( len * sizeof (char ) ); int i; for (i = 0; i < 5; i ++) {     array ++;     /*something to do with array*/     printf ("%d\t", array); } printf ("\n"); printf ("%d\n", array); free (array - len);     //或者free (array-i); array = NULL; 谢谢！ free的机制是认的申请地址的首位么？还是说必须是指定的某个变量+初始位置？因为我又试了下用一个中间的指针变量  char *tmp = array; ....../*中间还是对array进行操作*/ free(tmp); tmp=NULL;  这样就不行

引用 5 楼 zcppacers 的回复:谢谢！ free的机制是认的申请地址的首位么？还是说必须是指定的某个变量+初始位置？因为我又试了下用一个中间的指针变量  char *tmp = array; ....../*中间还是对array进行操作*/ free(tmp); tmp=NULL;  这样就不行  你怎么判断的不行？

引用 2 楼 TJF331311545 的回复:array ++;     在把他减回去？  输出可以用下标法

array ++;     在把他减回去？

除非你能把指针还原，否则保存原始地址是跑不了的


Question: 关于指针指向的问题

补充一下，实参只是传递一份拷贝给函数，你对一份拷贝的数据操作，函数调作完了就释放掉了，实参的值没有改变，所以达不到你的目的

函数是值传递，虽然你函数的参数是指针，但是你只修改了函数的参数（也就是你传递的指针），这样是没有效果的，就像你传递两个整型值进去操作一样。

仅供参考#include <stdio.h> #define SWAP(a,b) do ((&(a))!=(&(b)))?((a)^=(b)^=(a)^=(b)):((a)=(a)); while (0) char   *p1="1" ,*p2="2" ; char    c1=1   , c2=2   ; short   s1=1   , s2=2   ; int     i1=1   , i2=2   ; __int64 I1=1i64, I2=2i64; float   f1=1.0f, f2=2.0f; double  d1=1.0 , d2=2.0 ; void main() {     SWAP((int)p1,(int)p2);                printf("char *     %5s,   %5s\n",p1,p2);     SWAP(c1,c2);                          printf("char       %5d,   %5d\n",c1,c2);     SWAP(s1,s2);                          printf("short      %5d,   %5d\n",s1,s2);     SWAP(i1,i2);                          printf("int        %5d,   %5d\n",i1,i2);     SWAP(I1,I2);                          printf("__int64 %5I64d,%5I64d\n",I1,I2);     SWAP(*(int     *)&f1,*(int     *)&f2);printf("float      %5g,   %5g\n",f1,f2);     SWAP(*(__int64 *)&d1,*(__int64 *)&d2);printf("double    %5lg,  %5lg\n",d1,d2);      SWAP(c1,c1);     printf("%d\n",c1); } //char *         2,       1 //char           2,       1 //short          2,       1 //int            2,       1 //__int64     2,    1 //float          2,       1 //double        2,      1 //2

应为  void swap(int *p1,int *p2) {     int temp;     temp = *p1;     *p1 = *p2;     *p2 = temp; }  上面的 p1, p2 是 a, b 的地址。在 swap 函数里面要获取到 a, b 的值用 *p1 和 *p2。 平时的指针作为参数实质上还是参数复制的形式，只是复制的是变量的地址，我们在函数里面可以通过 * 操作符获取对应的变量。

你在函数里面交换的是指针，而不是指针的内容，也就是没有交换数值 试试  { int t; t=*p1; *p1=*p2; *p2=t; }

因为你只是置换了两个参数里面的地址，而没有置换两个传进的两个指针里面的地址

函数写错了，应该这样 void swap(int *p1,int *p2) { int temp; temp=*p1; *p1=*p2; *p2=temp; }


Question: 把jpg文件读到内存后，用二进制读进去的，放到一个char*  内存里， 然后怎么把这个 char* 内存 赋值给一个 HBITMAP

引用 17 楼 cutmelon 的回复:赵老师您真有闲，哈，用VC6的我10年前就这么写过，不过支持的图片格式少了点，我给您翻出来瞅瞅 void DrawPicOld(CDC *pDC,char *buf,int len) { 	//内存数据转换成流 	HGLOBAL hMem=GlobalAlloc(GMEM_FIXED,len); 	BYTE* pMem=(BYTE*)GlobalLock(hMem); 	memcpy(pMem,buf,len); 	IStream* pStreamm; 	HRESULT hr=CreateStreamOnHGlobal(pMem,FALSE,&pStreamm);  	//生成ole图片对象 	IPicture *pPic; 	hr=OleLoadPicture(pStreamm,0,FALSE,IID_IPicture,(void**)&pPic);  	//画图前需要计算像素大小 	long hmWidth,hmHeight; 	pPic->get_Width(&hmWidth); 	pPic->get_Height(&hmHeight); 	CSize sz(hmWidth,hmHeight); 	pDC->HIMETRICtoDP(&sz);  	//画到DC 	pPic->Render(*pDC,0,0,sz.cx,sz.cy,0,hmHeight,hmWidth,-hmHeight,NULL);  	//清理 	pPic->Release(); 	pStreamm->Release(); 	GlobalFree(hMem); } 又学了一招。足见我VC/MFC/ATL是门外汉啊！

引用 9 楼 czy_163_com 的回复:这样做是可以的，但是我已经从数据库中取到内存了， 再存回磁盘，然后再从磁盘读上来，有点绕弯了。 那是因为你之前 将.jpg文件从磁盘读出来，再存到数据库中，有点绕弯了。

多谢各位老师了，看来应该可以了，我需要的就是这个。怎么给分都不清楚呢，我是个新手。

引用 14 楼 cutmelon 的回复:[quote=引用 12 楼 zhao4zhong1 的回复:] [quote=引用 11 楼 cutmelon 的回复:] 这个问题不是很复杂啊，楼主我给你段代码吧，如果你是在windows下开发直接就能用 void DrawPic(CDC *pDC,char *buf,int len) { 	//内存数据转换成流 	HGLOBAL hMem=GlobalAlloc(GMEM_FIXED,len); 	BYTE* pMem=(BYTE*)GlobalLock(hMem); 	memcpy(pMem,buf,len); 	IStream* pStream; 	HRESULT hr=CreateStreamOnHGlobal(pMem,FALSE,&pStream);  	//画图 	CImage img; 	img.Load(pStream); 	img.Draw(pDC->GetSafeHdc(),CPoint(0,0));  	//清理 	img.Destroy(); 	pStream->Release(); 	GlobalFree(hMem); } 如果你非要Bitmap的话，参照3楼的说法改改就行了 学习了。 是不是少了句GlobalUnlock(hMem);?[/quote] 这里用的固定块，GMEM_FIXED，没必要unlock[/quote] 哦。受教。

亲测可用，可惜VC6不支持CImage： #pragma comment(lib,"user32") #pragma comment(lib,"gdi32") #include <stdlib.h> #include <stdio.h> #include <io.h> #include <conio.h> #include <windows.h> #include <atlimage.h> #include <objidl.h> void DrawPic(HDC hdc,char *buf,int len) {     HGLOBAL hMem=GlobalAlloc(GMEM_FIXED,len);     BYTE* pMem=(BYTE*)GlobalLock(hMem);     memcpy(pMem,buf,len);     IStream* pStream;     HRESULT hr=CreateStreamOnHGlobal(pMem,FALSE,&pStream);      CImage img;     img.Load(pStream);     img.Draw(hdc,CPoint(0,0));      img.Destroy();     pStream->Release();     GlobalUnlock(hMem);     GlobalFree(hMem); } //HWND WINAPI GetConsoleWindow(); void HideTheCursor() {     CONSOLE_CURSOR_INFO cciCursor;     HANDLE hStdOut = GetStdHandle(STD_OUTPUT_HANDLE);     if (GetConsoleCursorInfo(hStdOut, &cciCursor)) {         cciCursor.bVisible = FALSE;         SetConsoleCursorInfo(hStdOut, &cciCursor);     } } void ShowTheCursor() {     CONSOLE_CURSOR_INFO cciCursor;     HANDLE hStdOut = GetStdHandle(STD_OUTPUT_HANDLE);     if (GetConsoleCursorInfo(hStdOut, &cciCursor)) {         cciCursor.bVisible = TRUE;         SetConsoleCursorInfo(hStdOut, &cciCursor);     } } int main() {     HWND  hwnd;     HDC   hdc;     HFONT hfont;     HBITMAP hbm;     HDC hdcBits;     BITMAP bm;      system("color F0");     system("cls");     HideTheCursor();     hwnd  = GetConsoleWindow();     hdc   = GetDC(hwnd);     hfont = CreateFont(48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "华文楷体");     SelectObject(hdc,hfont);     TextOut(hdc,10,10,"这是泡泡",8);     DeleteObject(hfont);     hbm=(HBITMAP)LoadImage(0,"C:\\Windows\\Soap Bubbles.bmp",IMAGE_BITMAP,0,0,LR_DEFAULTSIZE|LR_LOADFROMFILE);     if (hbm) {         hdcBits = CreateCompatibleDC(hdc);         GetObject (hbm, sizeof(BITMAP), &bm);         SelectObject(hdcBits,hbm);         BitBlt(hdc,200,10,bm.bmWidth, bm.bmHeight,hdcBits,0,0,SRCCOPY);         DeleteDC(hdcBits);         DeleteObject(hbm);     }     getch();     FILE *f;     f=fopen("c:\\new\\tmp.jpg","rb");     if (f) {         int fl=filelength(fileno(f));         char *buf=(char *)malloc(fl);         if (buf) {             fread(buf,fl,1,f);         }         fclose(f);         if (buf) {             DrawPic(hdc,buf,fl);             free(buf);         }     }     ReleaseDC(hwnd,hdc);     getch();     system("color 07");     system("cls");     ShowTheCursor();     return 0; }

引用 12 楼 zhao4zhong1 的回复:[quote=引用 11 楼 cutmelon 的回复:] 这个问题不是很复杂啊，楼主我给你段代码吧，如果你是在windows下开发直接就能用 void DrawPic(CDC *pDC,char *buf,int len) { 	//内存数据转换成流 	HGLOBAL hMem=GlobalAlloc(GMEM_FIXED,len); 	BYTE* pMem=(BYTE*)GlobalLock(hMem); 	memcpy(pMem,buf,len); 	IStream* pStream; 	HRESULT hr=CreateStreamOnHGlobal(pMem,FALSE,&pStream);  	//画图 	CImage img; 	img.Load(pStream); 	img.Draw(pDC->GetSafeHdc(),CPoint(0,0));  	//清理 	img.Destroy(); 	pStream->Release(); 	GlobalFree(hMem); } 如果你非要Bitmap的话，参照3楼的说法改改就行了 学习了。 是不是少了句GlobalUnlock(hMem);?[/quote] 这里用的固定块，GMEM_FIXED，没必要unlock

你没解码，读进去也不能显示为图像。  你必须用 libjpeg解码，然后得到位图信息，将此位图信息转换为os图形层认识的内存位图格式就可以显示了。

引用 11 楼 cutmelon 的回复:这个问题不是很复杂啊，楼主我给你段代码吧，如果你是在windows下开发直接就能用 void DrawPic(CDC *pDC,char *buf,int len) { 	//内存数据转换成流 	HGLOBAL hMem=GlobalAlloc(GMEM_FIXED,len); 	BYTE* pMem=(BYTE*)GlobalLock(hMem); 	memcpy(pMem,buf,len); 	IStream* pStream; 	HRESULT hr=CreateStreamOnHGlobal(pMem,FALSE,&pStream);  	//画图 	CImage img; 	img.Load(pStream); 	img.Draw(pDC->GetSafeHdc(),CPoint(0,0));  	//清理 	img.Destroy(); 	pStream->Release(); 	GlobalFree(hMem); } 如果你非要Bitmap的话，参照3楼的说法改改就行了 学习了。 是不是少了句GlobalUnlock(hMem);?

引用 7 楼 zhao4zhong1 的回复:[quote=引用 6 楼 czy_163_com 的回复:] 多谢各位， 我试一下。 我的jpg文件已经通过二进制保存在数据库里了。现在从数据库读出后放在char*内存里，想把这个图形通过打印机打印出来 你为什么不 从数据库读出后保存到临时.jpg文件里，再把这个.jpg文件通过打印机打印出来 呢？ [/quote] 如果你嫌这样磨损硬盘的话，将临时文件放在RAM Disk上。

引用 6 楼 czy_163_com 的回复:多谢各位， 我试一下。 我的jpg文件已经通过二进制保存在数据库里了。现在从数据库读出后放在char*内存里，想把这个图形通过打印机打印出来 你为什么不 从数据库读出后保存到临时.jpg文件里，再把这个.jpg文件通过打印机打印出来 呢？

导进资源文件，用CBitmap操作不好吗，太费劲

MFC里面有个CImage类 #include <atlimage.h> CImage img; img.Load(L"d:\\1.jpg"); HBITMAP hBitmap = img.Detach();  就可以了。 从char*中读取也可以，不过麻烦点，需要用CreateStreamOnHGlobal创建一个IStream， 然后用IStream::Read()把char*读进去，然后传递给CImage::Load()进行读取

费那事干嘛？ 直接用GDI+的Image对象加载.jpg文件。

那么直接读取为CBitmap行不行 http://blog.csdn.net/huangxy10/article/details/7089093

CreateDIBSection得到HBITMAP，得到pbits，拷贝一下就行了


Question: onvif协议开发

它只是个协议，看看然后动手做做实验就能明白的


Question: 我刚下了个VC6.0  无论怎么写程序都是一个错误，求帮忙。。。

开始，运行，regedit，删除注册表左侧的项目：      HKEY_CURRENT_USER\Software\Microsoft\DevStudio\6.0  再重新运行VC6.0，应该没问题了。  或者使用我空间的链接里的补丁文件也可以。 参考资料：www.uushare.com/user/jsj08/file/1797836

你把杀毒软件关了 再重新装下vc就好了

我不推荐安装visual c++6.0。推荐安装visual studio2008英文版。我是卸载了visual c++6.0

我相信计算机语言教师。编译器，只要是microsoft英文版本，就永远是源代码输入错误，编译器不会出错误。请注意：spawning cl.exe，这一段语言，是说visual c++6.0，安装错误。我告诉你一个visual c++6.0 iso下载地址，也是我使用的版本。不要使用网络流传的汉化版本；绿色版本。地址：http://yunpan.cn/cKLvH8YV2aJz8  提取码 a7dc 。注意：必须使用虚拟光驱安装。虚拟光驱，你就自己搜索吧。我是默认安装在C盘。在windows7操作系统安装visual c++6.0，需要注意一个问题，就是把Tools里面的OLE/COM Object Viewer去掉。【我送你一个参考办法，你必须看，自定义安装选项的办法：点击tools选项、点击change option...（更改选项的意思）、接下去，把OLE/COM Object Viewer选项，勾掉、接下去，点击ok。就这个OLE/COM Object Viewer选项不要，其它的选项，都要勾选。你要用我说的办法，勾选剩余的所有选项。再送你一个参考办法，必须看。地址：http://blog.sina.com.cn/s/blog_a4c12c9201014djg.html】

3楼正解 楼主应该是下载 “绿色版” 的 VC++ 6.0 导致路径配置不正确问题。

引用 11 楼 zhao4zhong1 的回复:FileTool.exe 替换打开和添加到项目中 Visual C++ 的新功能 http://support.microsoft.com/kb/241396/zh-cn 喜感的头像

第一、你要确定，你是在用控制台程序，建立工作组。同时建议你安装英文版本。第二、一个你没有看到的字符错误，会导致编译失败。第三、不管使用什么编译软件。都是需要先编译源代码，再运行程序。可能是你没有编译源代码，就运行，导致的错误。第四、我测试了你写出的源代码。编译成功。输出“he”。请继续努力。第五、操作过程是：点击viusal c++6.0、点击file【文件】、点击new【新建】、点击win32 console Application【win32控制台项目】、在project name输入框，输入文件名。这个自己定，比喻：输入1。【我经常使用的是数字】、点击ok、选择An empty project【一个空项目】、点击Finish【完成】、点击ok。接下去，可以点击工作组组下边的FileWiew、点击file、点击new、点击c++ source file【c++源文件】、点击add to project【添加到项目】输入框、在file输入框，输入1、接下去，可以输入源代码。要记得先编译『【在编译器，第三排菜单栏，右侧，看到小手掌了么，向左看，第五个图标build【生成。调试。】；第六个图标compile【编译】，这二个图标，点击哪个都是可以。接下去，点击第三个图标【感叹号图标execute program。运行程序】。

文件、新建、工程、Win32 Console Application、工程：test，确定，A “Hello, World" application.，完成。

估计是建错项目了，

如果楼主只为学习C，那换一个IDE吧——C/C++开发者必不可少的15款编译器+IDE 如果非要用VC6，我的资源里有完整绿色版，可以试试

你的电脑是WIN7吗?还是XP?  如果是WIN7及以上，真心不推荐还装VC6.0了。装个最新版的VS2013，你可以使用免费版的，或者是...

你是用控制台模式创建的工程吗？

来学习的。。。用了那么久的vc，没见过这个错。

实际上这个问题很多情况下是由于路径设置的问题引起的，  “CL.exe”是VC使用真正的编译器（编译程序），其路径在“VC根目录\VC98\Bin”下面，  你可以到相应的路径下找到这个应用程序。   因此问题可以按照以下方法解决：打开vc界面 点击VC“TOOLS（工具）”—>“Option（选择）”  —>“Directories（目录）”重新设置“Excutable Fils、Include Files、  Library Files、Source Files”的路径。很多情况可能就一个盘符的不同  （例如你的VC装在C，但是这些路径全部在D），改过来就OK了。   如果你是按照初始路径安装vc6.0的，路径应为：  executatble files:  C:\Program Files\Microsoft Visual Studio\Common\MSDev98\Bin  C:\Program Files\Microsoft Visual Studio\VC98\BIN  C:\Program Files\Microsoft Visual Studio\Common\TOOLS  C:\Program Files\Microsoft Visual Studio\Common\TOOLS\WINNT   include files:  C:\Program Files\Microsoft Visual Studio\VC98\INCLUDE  C:\Program Files\Microsoft Visual Studio\VC98\MFC\INCLUDE  C:\Program Files\Microsoft Visual Studio\VC98\ATL\INCLUDE   library files:  C:\Program Files\Microsoft Visual Studio\VC98\LIB  C:\Program Files\Microsoft Visual Studio\VC98\MFC\LIB   source files:  C:\Program Files\Microsoft Visual Studio\VC98\MFC\SRC  C:\Program Files\Microsoft Visual Studio\VC98\MFC\INCLUDE  C:\Program Files\Microsoft Visual Studio\VC98\ATL\INCLUDE  C:\Program Files\Microsoft Visual Studio\VC98\CRT\SRC   如果你装在其他盘里，则仿照其路径变通就行。  关键是microsoft visual studio\ 后面的东西要相同。

把错误信息复制去搜索，你会找到答案的


Question: 输入一个数，将这个数分解成几个数相加的形式输出

#include <stdio.h>  int main() {     int iNum = 0;     int nFive = 0, nRest = 0;     int i = 0;     while (true)     {         printf("Enter a number(0 to exit):\n");         scanf("%d", &iNum);         if (0 == iNum)         {             break;         }          printf("%d=", iNum);          nFive = (iNum - 1) / 5;         for (i = 0; i < nFive; i++)         {             printf("%d+", 5);         }         nRest = iNum - nFive * 5;         printf("%d+%d\n", nRest - 1, 1);     } }

仅供参考： //求从Begin到End的正整数中挑出任意个数使其总和为Sum的所有方案 #include <stdio.h> int Begin,End,Sum; int j; int o[1000]; long n; void combsum(int b,int e,int s,int d) {     int i;      if (e>s) e=s;     for (i=e;i>=b;i--) {         if ((i+b)*(i-b+1)/2<s) break;         o[d]=i;         if (s-i<=0) {             n++;             printf("%8ld:",n);             for (j=0;j<=d;j++) printf("%d ",o[j]);             printf("\n");         } else {             if (d+1<1000) combsum(b,i-1,s-i,d+1);             else {                 printf("Error:Too deep.\n");                 return;             }         }     } } int main() {     printf("Input Begin,End,Sum:");fflush(stdout);     scanf("%d,%d,%d",&Begin,&End,&Sum);     n=0L;     combsum(Begin,End,Sum,0);     printf("Total:%ld\n",n);     return 0; }


Question: 究竟错在哪里！！！！

爆什么错 是WA 还是PE

修改下。  #include <stdio.h> #include <math.h> double get_c_length(float x1,float y1,float x2,float y2) {   float tmp1,tmp2;   tmp1=abs(x2-x1);   tmp2=abs(y2-y1);     if(tmp1==0 && tmp2==0 ){   	return 0;   }else  if(tmp1==0){ 	return tmp2;      }else if(tmp2==0){ 	return tmp1;    }else{  	return sqrt(tmp1*tmp1+tmp2*tmp2);   } }  int main(){     double x1, y1, x2, y2, ans;     while(scanf("%lf %lf %lf %lf", &x1, &y1, &x2, &y2)!=EOF)    {                  printf("%.2lf\n",get_c_length(x1,y1,x2,y2));    }    return 0; }

要对用户输入的各种情况考虑，就好比盖房子，不能只关注门，还得关注房子的墙，屋顶，等等。

我调整了下，你运行看看  #include <stdio.h> #include <math.h> double get_c_length(float x1,float y1,float x2,float y2) {   float tmp1,tmp2;   tmp1=abs(x2-x1);   tmp2=abs(y2-y1);     if(tmp1==tmp2){   	return 0;   }else  if(tmp1==0){ 	return tmp2;      }else if(tmp2==0){ 	return tmp1;    }else{  	return sqrt(tmp1*tmp1+tmp2*tmp2);   } }  int main(){      double x1, y1, x2, y2, ans;    while(scanf("%lf %lf %lf %lf", &x1, &y1, &x2, &y2)!=EOF)    {                  printf("%.2lf\n",get_c_length(x1,y1,x2,y2));    }    return 0; }

按格式用x1,y1，这样就不容易搞错了  #include <stdio.h> #include <math.h> int main() {     double x1, y1, x2, y2, ans;       while(scanf("%lf %lf %lf %lf", &x1, &y1, &x2, &y2)!=EOF)     {         ans = sqrt((x1 - x2)*(x1 - x2)+(y1 - y2)*(y1 -y2));         printf("%.2lf\n",ans);     }     return 0; }

错误时啥？咋不描述错误呢！

应该是(a-c)*(a-c)+(b-d)*(b-d)开根号


Question: 小问题，新手求教

多个分号，表示该while循环不执行或者说执行的是空语句， 当n已经变成3后，3<=2不成立，则会再次执行一下n++，所以。。。

多个分号他就是一个独立的语句了。 加分号相当于  while(n++<=2) {  } printf("%d\n",n);   不加分号相当于  while(n++<=2) { printf("%d\n",n); }


Question: 如何修改#define 定义的常量中的参数

上面的“以数组为例 ”注释 实际上不是这个程序的

#include <stdio.h>  #define name(i) (#i)  void printwithoutret(char *v_name,int v_value) { 	printf("%s=%d\n",v_name,v_value); }  char* printwithret(int * v_back) { 	int d = 4;  	*v_back = d;  	return name(d);//你可以把这个地址strcpy到一个堆上  	               //意义不大 } int main(void) { 	//我以数组为例 	int a=1,b=2,c=3;     char *p; 	int e; 	int *x= &e; //第一种 直接打印 变量名=变量值     printf("%s=%d\n",name(a),a); //第二种 使用字符指针保存变量名 打印 	p = name(b); 	printf("%s=%d\n",p,b); //第三种 将这个字符指针传递到子函数里面打印 	p = name(c); 	printwithoutret(p,c); //第四种 接收子程序传来的变量名 然后打印 	p = printwithret(x); 	printf("%s=%d\n",printwithret(x),*x); 	return 0; }

#与##在宏定义中的--宏展开 #include <stdio.h> #define f(a,b) a##b #define g(a)   #a #define h(a) g(a) int main() {         printf("%s\n", h(f(1,2)));   // 12         printf("%s\n", g(f(1,2))); // f(1,2)         return 0; } 宏展开时： 如果宏定义以#开头，不展开参数，直接替换。 故g(f(1,2))--->#f(1,2)--->"f(1,2)"； 如果宏定义不以#开头，展开参数，直接替换，由外层向里层，如果碰到的是#开头的宏，不继续往里层展开，往外层展开。 由外层向里层，如果碰到的是以非#开头的宏，继续往里层走，直至最里层，开始一层层往外层展开。 故h(f(1,2))--->h(12)--->g(12)---->#12----->"12"。 PS： ##在宏中定义，是字符连接符 如a##b##c 等同于 "abc" #在宏开头出现，是表示宏展开的方式不同 #a 等同于"a" #abc 等同于 "abc" 复杂的: #include <stdio.h> #define f(a,b) a##b #define g(a)   #a #define h(a) g(a) int main() {         char a = 'a';         cout<<g(a)<<endl; // a         cout<<g(g(a))<<endl; // a         printf("%s\n", h(f(1,2)));   // 12         printf("%s\n", g(f(1,2))); // f(1,2)         printf("%s\n", g(h(f(1,2)))); // h(f(1,2))         printf("%s\n", h(g(f(1,2)))); // "f(1,2)"         printf("%s\n", h(h(f(1,2)))); // "12"         system("pause");         return 0; } 预处理后的：（在编译选项中添加/EP /P后编译生成的.i文件。gcc加-E） int main() {         char a = 'a';         cout<<"a"<<endl;         cout<<"g(a)"<<endl;         printf("%s\n", "12");         printf("%s\n", "f(1,2)");         printf("%s\n", "h(f(1,2))");         printf("%s\n", "\"f(1,2)\"");         printf("%s\n", "\"12\"");         system("pause");         return 0; } --------------------------------------------------- 宏解析 1.       ##操作符 ##操作符它的作用是在替代表中将其前后的参数连接成为一个预处理符号，它不能出现于宏替代表的开端和末尾。 例： #define concat(s,t) s##t #define AAA ABC concat(A, AA) 将被替换成 ABC 2.       重新扫描和替换 在替换列表中的所有参数替换过之后，预处理器将对结果token序列重新扫描以便对其中的宏再次替换。 当正在替换的宏在其替换列表中发现自身时，就不再对其进行替换。在任何正在嵌套替换的宏的替换过程中遇到正被替换的宏就对其不再进行替换（防止递归）。 例： #define ROOT AAA CCC #define AAA ROOT ROOT 将被替换成 ROOT CCC

#define varname(x)  #x    能解释一下这句么  #x代表？？？？

一旦写成函数，则函数实参的变量名，就不能得到了 唯一的办法是写成宏 可以为 函数定义一个宏 ，用宏来调用函数，这样就可以传递 变量名了

#define varname(x)  #x  #define print_int(a)  printf("%s =%d",varname(a),(a))  print_int(a); print_int(b); print_int(c);

说得糊里八涂的。你的意思就是传入字符串呗： void f (const char *); /* …… */ f ("name"); f ("gender"); f ("age"); 语文太差了，现代的大学生们！

脑子是个好东西，希望你也有

即使你觉得自己有，也不一定真有。自负是共性。

楼主想问的是使用 const 定义常量？


Question: libcurl发送post方式的json串出现“Unsupported Media Type”

我现在也在是项目需要：c  http client端 目前也是用curl 实现POST  json到服务器端，也需要这个完成源码，谢谢我的QQ邮箱是 455738018@qq.com   我的问题卡在拼这个jsom数据的时候，是写死的一个json串  ，不够灵活，以后不方便扩展，想知道你是怎么实现的？ 方便的话，希望你把源码也发我一份参考下 谢谢！

您好，请问完整代码能否发我看看，我是新手，这方面完全不懂，现在做项目又需要，谢了啊！379014829@qq.com

引用 6 楼 jk110333 的回复:[quote=引用 4 楼 wanguser-3 的回复:] 1、HTTP头部不是这么加的，应该是这样：  headers = curl_slist_append(headers, "Accept: application/json"); headers = curl_slist_append(headers, "Content-Type: application/json"); headers = curl_slist_append(headers, "charset: utf-8"); headers = curl_slist_append(headers, tmp);  2、遇到这种问题你先抓包看一下你发出去的是什么样的包，用HttpAnalyzer就可以。 多些哥们  测试成功！！！！ 哈哈   学习下你的HttpAnalyzer[/quote]

引用 4 楼 wanguser-3 的回复:1、HTTP头部不是这么加的，应该是这样：  headers = curl_slist_append(headers, "Accept: application/json"); headers = curl_slist_append(headers, "Content-Type: application/json"); headers = curl_slist_append(headers, "charset: utf-8"); headers = curl_slist_append(headers, tmp);  2、遇到这种问题你先抓包看一下你发出去的是什么样的包，用HttpAnalyzer就可以。 多些哥们  测试成功！！！！ 哈哈   学习下你的HttpAnalyzer

引用 4 楼 wanguser-3 的回复:1、HTTP头部不是这么加的，应该是这样：  headers = curl_slist_append(headers, "Accept: application/json"); headers = curl_slist_append(headers, "Content-Type: application/json"); headers = curl_slist_append(headers, "charset: utf-8"); headers = curl_slist_append(headers, tmp);  2、遇到这种问题你先抓包看一下你发出去的是什么样的包，用HttpAnalyzer就可以。  马上测试你的方法   多些哥们回复！

代码我都发上来了！ 大家看看    有没有遇见这些问题的！

ciao  还没有人帮忙！

有兄弟帮忙下吗？


Question: 函数的设计

int recvdata(char *a) {     char *p=a;     while(*p)     {         if(*p=='\r'&&*(p+1)=='\n')  return p-a;         p++;     }     return 0; }

是这样吗   int recvdata(char *a) {     char ch,*p=a;     while((ch=getchar())!=EOF){         if(ch=='\r' || ch=='\n') break;         *p++ =ch;     }     *p ='\0';     return p-a; }

int receiveData(unsigned char * a) {      unsigned char * p = a;      while ((* (a ++)) != '\n' && (* (a ++) = getData ()) != '\r') ;      * (a -= 2) = 0;      return a - p; }

你程序写的就是这个啊。你要做啥？？你可以调试


Question: C语言中关于对数e的输入问题

引用 3 楼 sholber 的回复:找虱老湿的代码为什么总是看起来这么别扭哇…… 因为是剽窃yu_hua的啊。

scanf("%lf", &x); 需要输入浮点数, 在第一个例子中，楼主需要输入e的值，2.718282，而不是exp(1)

找虱老湿的代码为什么总是看起来这么别扭哇……

谢谢，受教了

仅供参考： /*--------------------------------------- 函数型计算器(VC++6.0,Win32 Console)程序由 yu_hua 于2007-07-27设计完成 功能： 目前提供了10多个常用数学函数:     ⑴正弦sin     ⑵余弦cos     ⑶正切tan     ⑷开平方sqrt     ⑸反正弦arcsin     ⑹反余弦arccos     ⑺反正切arctan     ⑻常用对数lg     ⑼自然对数ln     ⑽ｅ指数exp     ⑾乘幂函数∧ 用法： 如果要求2的32次幂，可以打入2^32<回车> 如果要求30度角的正切可键入tan(Pi/6)<回车> 注意不能打入：tan(30)<Enter> 如果要求1.23弧度的正弦，有几种方法都有效： sin(1.23)<Enter> sin 1.23 <Enter> sin1.23  <Enter> 如果验证正余弦的平方和公式,可打入sin(1.23)^2+cos(1.23)^2 <Enter>或sin1.23^2+cos1.23^2 <Enter> 此外两函数表达式连在一起,自动理解为相乘如：sin1.23cos0.77+cos1.23sin0.77就等价于sin(1.23)*cos(0.77)+cos(1.23)*sin(0.77) 当然你还可以依据三角变换，再用sin(1.23+0.77)也即sin2验证一下。 本计算器充分考虑了运算符的优先级因此诸如：2+3*4^2 实际上相当于：2+(3*(4*4)) 另外函数名前面如果是数字,那么自动认为二者相乘. 同理，如果某数的右侧是左括号，则自动认为该数与括弧项之间隐含一乘号。 如：3sin1.2^2+5cos2.1^2 相当于3*sin2(1.2)+5*cos2(2.1) 又如：4(3-2(sqrt5-1)+ln2)+lg5 相当于4*(3-2*(√5 -1)+loge(2))+log10(5) 此外，本计算器提供了圆周率 Pi键入字母时不区分大小写,以方便使用。 ----------------------------------------*/ #include <iostream> #include <iomanip> #include <cstdlib> #include <cstring> #include <cctype> #include <cmath> #include <stdio.h> #include <string.h> #include <windows.h> using namespace std; const char Tab=0x9; const int  DIGIT=1; const int MAXLEN=16384; char s[MAXLEN],*endss; int pcs=15; double fun(double x,char op[],int *iop) {     while (op[*iop-1]<32) //本行使得函数嵌套调用时不必加括号,如 arc sin(sin(1.234)) 只需键入arc sin sin 1.234<Enter>         switch (op[*iop-1]) {         case  7: x=sin(x);  (*iop)--;break;         case  8: x=cos(x);  (*iop)--;break;         case  9: x=tan(x);  (*iop)--;break;         case 10: x=sqrt(x); (*iop)--;break;         case 11: x=asin(x); (*iop)--;break;         case 12: x=acos(x); (*iop)--;break;         case 13: x=atan(x); (*iop)--;break;         case 14: x=log10(x);(*iop)--;break;         case 15: x=log(x);  (*iop)--;break;         case 16: x=exp(x);  (*iop)--;break;         }     return x; } double calc(char *expr,char **addr) {     static int deep; //递归深度     static char *fname[]={ "sin","cos","tan","sqrt","arcsin","arccos","arctan","lg","ln","exp",NULL};     double ST[10]={0.0}; //数字栈     char op[10]={'+'}; //运算符栈     char c,*rexp,*pp,*pf;     int ist=1,iop=1,last,i;      if (!deep) {         pp=pf=expr;         do {             c = *pp++;             if (c!=' '&& c!=Tab)                 *pf++ = c;         } while (c!='\0');     }     pp=expr;     if ((c=*pp)=='-'||c=='+') {         op[0] = c;         pp++;     }     last = !DIGIT;     while ((c=*pp)!='\0') {         if (c=='(') {//左圆括弧             deep++;             ST[ist++]=calc(++pp,addr);             deep--;             ST[ist-1]=fun(ST[ist-1],op,&iop);             pp = *addr;             last = DIGIT;             if (*pp == '('||isalpha(*pp) && strnicmp(pp,"Pi",2)) {//目的是：当右圆括弧的右恻为左圆括弧或函数名字时，默认其为乘法                 op[iop++]='*';                 last = !DIGIT;                 c = op[--iop];                 goto operate ;             }         }         else if (c==')') {//右圆括弧             pp++;             break;         } else if (isalpha(c)) {             if (!strnicmp(pp,"Pi",2)) {                 if (last==DIGIT) {                     cout<< "π左侧遇）" <<endl;exit(1);                 }                 ST[ist++]=3.14159265358979323846264338328;                 ST[ist-1]=fun(ST[ist-1],op,&iop);                 pp += 2;                 last = DIGIT;                 if (!strnicmp(pp,"Pi",2)) {                     cout<< "两个π相连" <<endl;exit(2);                 }                 if (*pp=='(') {                     cout<< "π右侧遇（" <<endl;exit(3);                 }             } else {                 for (i=0; (pf=fname[i])!=NULL; i++)                     if (!strnicmp(pp,pf,strlen(pf))) break;                 if (pf!=NULL) {                     op[iop++] = 07+i;                     pp += strlen(pf);                 } else {                     cout<< "陌生函数名" <<endl;exit(4);                 }             }         } else if (c=='+'||c=='-'||c=='*'||c=='/'||c=='^') {             char cc;             if (last != DIGIT) {                 cout<< "运算符粘连" <<endl;exit(5);             }             pp++;             if (c=='+'||c=='-') {                 do {                     cc = op[--iop];                     --ist;                     switch (cc) {                     case '+':  ST[ist-1] += ST[ist];break;                     case '-':  ST[ist-1] -= ST[ist];break;                     case '*':  ST[ist-1] *= ST[ist];break;                     case '/':  ST[ist-1] /= ST[ist];break;                     case '^':  ST[ist-1] = pow(ST[ist-1],ST[ist]);break;                     }                 } while (iop);                 op[iop++] = c;             } else if (c=='*'||c=='/') { operate:        cc = op[iop-1];                 if (cc=='+'||cc=='-') {                     op[iop++] = c;                 } else {                     --ist;                     op[iop-1] = c;                     switch (cc) {                     case '*':  ST[ist-1] *= ST[ist];break;                     case '/':  ST[ist-1] /= ST[ist];break;                     case '^':  ST[ist-1] = pow(ST[ist-1],ST[ist]);break;                     }                 }             } else {                 cc = op[iop-1];                 if (cc=='^') {                     cout<< "乘幂符连用" <<endl;exit(6);                 }                 op[iop++] = c;             }             last = !DIGIT;         } else {             if (last == DIGIT) {                 cout<< "两数字粘连" <<endl;exit(7);             }             ST[ist++]=strtod(pp,&rexp);             ST[ist-1]=fun(ST[ist-1],op,&iop);             if (pp == rexp) {                 cout<< "非法字符" <<endl;exit(8);             }             pp = rexp;             last = DIGIT;             if (*pp == '('||isalpha(*pp)) {                 op[iop++]='*';                 last = !DIGIT;                 c = op[--iop];                 goto operate ;             }         }     }     *addr=pp;     if (iop>=ist) {         cout<< "表达式有误" <<endl;exit(9);     }     while (iop) {         --ist;         switch (op[--iop]) {         case '+':  ST[ist-1] += ST[ist];break;         case '-':  ST[ist-1] -= ST[ist];break;         case '*':  ST[ist-1] *= ST[ist];break;         case '/':  ST[ist-1] /= ST[ist];break;         case '^':  ST[ist-1] = pow(ST[ist-1],ST[ist]);break;         }     }     return ST[0]; } int main(int argc,char **argv) {     int a;      if (argc<2) {         if (GetConsoleOutputCP()!=936) system("chcp 936>NUL");//中文代码页         cout << "计算函数表达式的值。"<<endl<<"支持(),+,-,*,/,^,Pi,sin,cos,tan,sqrt,arcsin,arccos,arctan,lg,ln,exp"<<endl;         while (1) {             cout << "请输入表达式：";             gets(s);             if (s[0]==0) break;//             cout << s <<"=";             cout << setprecision(15) << calc(s,&endss) << endl;         }     } else if (argc==2 && 0==strcmp(argv[1],"/?")) {         if (GetConsoleOutputCP()!=936) system("chcp 936>NUL");//中文代码页         cout << "计算由≥1个命令行参数给出的函数表达式的值。最后一个参数是.0～.15表示将计算结果保留小数0～15位"<<endl<<"支持(),+,-,*,/,^^,Pi,sin,cos,tan,sqrt,arcsin,arccos,arctan,lg,ln,exp"<<endl;     } else {         strncpy(s,argv[1],MAXLEN-1);s[MAXLEN-1]=0;         if (argc>2) {             for (a=2;a<argc-1;a++) strncat(s,argv[a],MAXLEN-1);//将空格间隔的各参数连接到s             if (1==sscanf(argv[a],".%d",&pcs) && 0<=pcs && pcs<=15) {//最后一个参数是.0～.15表示将计算结果保留小数0～15位                 printf("%.*lf\n",pcs,calc(s,&endss));             } else {                 strncat(s,argv[a],MAXLEN-1);                 printf("%.15lg\n",calc(s,&endss));             }         } else {             printf("%.15lg\n",calc(s,&endss));         }     }     return 0; }


Question: 【求助】如何修改char*指向的常量字符串

引用 1 楼 user-1 的回复:关键是常量字符串不放在栈，放在不可修改的内存页上。所以你还是别修改了 谢谢

关键是常量字符串不放在栈，放在不可修改的内存页上。所以你还是别修改了


Question: 关于指针，写入位置时发生冲突

char *str = "ABCDEFG"; 等价 const char *str = "ABCDEFG";

引用 3 楼 FightForProgrammer 的回复:进一步解释就是，你原来声明的字符串是在内存中的某个区域（貌似叫常量区），那里的东东是不容许改动的，因此你str有了改动的行为时候*s = *(s+i);就会报错，而substr没有对它进行过改动行为，只有比较操作，因此没有崩掉  意思是用指针定义字符串，指针所指向的字符串为const类型?不能修改？

引用 4 楼 gn6199 的回复:[quote=引用 3 楼 FightForProgrammer 的回复:] 进一步解释就是，你原来声明的字符串是在内存中的某个区域（貌似叫常量区），那里的东东是不容许改动的，因此你str有了改动的行为时候*s = *(s+i);就会报错，而substr没有对它进行过改动行为，只有比较操作，因此没有崩掉  意思是用指针定义字符串，指针所指向的字符串为const类型?不能修改？[/quote]  不是的。这个const没关系，内存分为好几个区域，有些区域是不能修改，只能读取的。比如常量区。你以后慢慢多学习就知道了

原因在于你的定义，改成  char str[] = "ABCDEFG";//char* str = "ABCDEFG";   因为你声明的str只是一个地址。而不是分配了空间的数组。所以你的*s会出问题。  不过你这个代码实现不了你的目的哦（删除子窜）。自己再改改吧

void main() {     char *str = "ABCDEFG";     char *substr = "CDE";     int i;     i = del_substr(str, substr);     printf("%d\n", i);     printf("%s\n", str);   } to void main() {     char str[] = "ABCDEFG";     char substr[] = "CDE";     int i;     i = del_substr(str, substr);     printf("%d\n", i);     printf("%s\n", str);   }


Question: 操作系统题目

引用 4 楼 cumtwyc 的回复:从上往下看每ns完成一条指令的工作量，从左到右看，每个指令周期完成一条指令。《现代操作系统》书上的答案是10亿。 十亿怎么得来的，就按照楼主解释的，一个指令再细分，也没有十亿...

引用 1 楼 hnwyllmm 的回复: 希望楼主可以看懂这个图 然后就很容易计算了 1s = 1000000000ns 从图上看，前面4ns和后面4ns除外，中间都是平均1ns一个指令，就是999999992条指令 最后再加上前面一条和后面一条，正好是999999994条指令+1,这个有点像我小学做的一道过桥问题

引用 1 楼 hnwyllmm 的回复: 你说的是对的，但是我不理解的是一条指令不是可以分为几个周期吗，比如取指、译码、执行。假设每个周期都是1/3ns，当流水线被填满后，不是每1/3ns就有一条指令完成吗？


Question: 求解素数算法问题

程序没问题啊

Finding prime numbers - Kenneth Haugland Different schemas for finding prime numbers explained with code http://www.codeproject.com/Articles/429694/Finding-prime-numbers

程序没有问题

#include<stdio.h> #include <math.h> void main() { 	int i,k,tag; 	for(i=3;i<=1000;i+=2 ) 	{ tag=0; 	for(k=2;k<=sqrt(float(i));k++) 		if(i%k==0) 			tag=1; 	if(tag==0) 		printf("%d ",i); 	} }  没有问题，但不跟踪看看，到底是没有计算到还是输出的问题

我跑了另一个很简单的程序 #include<stdio.h> main() { int i; for(i=1;i<1000;i++) printf("%d ",i)  这个就可以显示600之前的啊，说明电脑没问题吧.......

楼主电脑有问题哈哈

程序没有问题。

#include<iostream> #include<iomanip> #include<cmath> using namespace std;  class primer { 	public: 	inline static bool isprimer(int n) 		{ 			bool state = true; 			int  tmp = (int)sqrt((double) n); 				for(int i = 2; i < tmp+1 ;++i) 					if(n % i == 0) 					{ 						state = false; 						break; 					} 			return state; 		} };  int main() { 	for(int i = 3; i < 1000; ++i) 		if(primer::isprimer(i)) 			cout << setw(5) << i;  	return 0; }

在printf里面加\n试试


Question: C语言无法连续输入

while (num % test == 0)//有bug，除数为0就出错了

test第二次的时候变成了0 你可以设个断点看。

求解答……TAT

引用 1 楼 jacksonfan 的回复:while (num % test == 0)//有bug，除数为0就出错了 按照我的走test不会变成0吧好像 如果是的话为什么输入一个然后EOF答案又完全正确呢


Question: WindowAPI编程 中 如何取消BS_CHECKBOX 的勾选

LRESULT r = SendMessage(hBtn2,BM_GETCHECK,0,0);              if(r==BST_CHECKED)//被选中              {                  MessageBox(NULL,L"CheckBox is CHECKED!",L"Hi!",MB_OK);              }

if (SendMessage(chbHwnd1, BM_GETCHECK, 0, 0))


Question: 带上“_T（）”以后，两行字符串不能并成一个字符串怎么办？

奇怪

printf("%ls ",p);

原因找到了，结贴。

引用 2 楼 screen12 的回复:[quote=引用 1 楼 user-3 的回复:] wchar_t const* p = L"　　最终用户软件许可协议\n"        L"　　XX五笔为免费、无捆绑、无插件、无广告的五笔输入法软件。您一旦复制、安装、使用本软件产品，"; 好象不行，还是只能显示第一行。[/quote]  那时你显示函数的问题。

引用 1 楼 user-3 的回复:wchar_t const* p = L"　　最终用户软件许可协议\n"        L"　　XX五笔为免费、无捆绑、无插件、无广告的五笔输入法软件。您一旦复制、安装、使用本软件产品，"; 好象不行，还是只能显示第一行。


Question: 敢不敢来个知道的，来了敢不敢顺带做个好事告诉我下答案。


Question: 敢不敢来个知道的，来了敢不敢顺带做个好事告诉我下答案。

MoonDeviceA 用devicetree看下有没问题

来见识下！！

敢

来了！！！！！！！！！


Question: 敢不敢来个知道的，来了敢不敢顺带做个好事告诉我下答案。

引用 3 楼 u012421456 的回复:不会帮顶了 楼主问个问题至于这样吗？连发好几个传送门帖子  要不楼主去别处问问，比如http://bbs3.driverdevelop.com/ 谢谢

引用 1 楼 user-2 的回复:会不会发链接啊 http://bbs.csdn.net/topics/390973172?page=1#post-398805891  给你也没用啊，连续几个帖子 没人给答案。


Question: 我到底哪里错了

引用 1 楼 user-1 的回复:A指ANSI，而ANSI并不是一个字符集，而是代表当前系统的默认字符集，在简体中文Windows下就是GBK，繁体中文则是BIG5，以此类推。  A指ANSI，而ANSI并不是一个字符集，  请问其和mdbc啥关系？


感谢各位回答，我再消化一下

输入函数计算的字节数，数据本身的字节数没有直接关系。

输入函数和数据本身的字节数没关系， %n 和 函数返回值，一个表示成功输入的字节数，一个表示成功输入的数据个数 -2.35 共有 5个字节 - 2 . 3 5 所以 %4f 只输入 -2.3 四个字符  -2.35 15 25 ready2go 共有20各字节，每个字节都是有效的输入数据， 虽然 *号跳过了一部分字符，但是这个被跳过的字符，也是成功输入的字符  第一次全部输入数据，都是有效字符，所以成功输入20个字符 第二次只有最后一个o 不是有效数据，该数据保留在缓冲区，没有被输入数据中 所以只有19个字符输入成功了

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

非常感谢你的回答，这个是C语言我学“基本输入和输出”这个章节里面的内容，fp1对应的转换说明符是%4f，所以我才有以为是不是结果是4个字符，不明白为什么多出来5个0.

那在猜测一下  value_count = scanf_s(format, &fp1, &i , &j, word1, sizeof(word1), word2, sizeof(word2), &byte_count); byte_count 为接收到的输入的格式化字符的字节数  Enter as input: -2.35 15 25 ready2go\ byte_count  为20  Enter as input: -2.35 15 25 ready332go\ byte_count  为22  value_count 同C语言 匹配的格式化个数  所以程序本身没有问题 问题是对scanf_s的参数说明 没理解   第二个scanf_s()函数 byte_count 的值为什么是19，我计算结果是18：4字节的float+4字节的int+4字节的int+5字节的ready+1字节的g=18，请教19是怎么来的？还有为什么这里的fp1=-2.300000，读入4字符不应该是-2.3吗？ 为什么是19  同上 为什么是fp1=-2.300000  这个和编辑器 默认保留的小数位 有关吧  这个也可以通过格式化强制保留多少位

我回答错了 我怎么感觉我不认识这个scanf_s 这是C++里面的东西 怎么那么多参数 不是getchar()的问题 我想错了

引用 1 楼 u011779875 的回复:请教各位为什么第一个scanf_s()函数 byte_count 的值是20？我计算值应该是19：4字节的float变量+4字节int变量+4字节int变量+5字节ready字符+2字节go字符。（数字2被忽略，其余的已被读入的字符数被%n存储到 byte_count）  目测 你把 最后的\n读进去了     getchar();     value_count = scanf_s(format, &fp1, &i , &j, word1, sizeof(word1), word2, sizeof(word2), &byte_count);     getchar(); 看看是不是19 请教“最后的\n读进去了”是什么意思呢？“Enter as input: -2.35 15 25 ready2go\n”这里面的\n应该没有被读入，单纯的换行应该，我把\n去掉再次编译测试了一下，结果不变呢。


Question: 谁能帮我看一下这段代码到底哪有问题，输出结果本应是倒序打印字符串

#include <stdio.h> #include <string.h> #include <assert.h>  void revp (const char * c) {     assert (c != NULL);     int n = strlen (c);     while (n --) printf ("%c", c [n]); }

#include<iostream> #include<algorithm> #include<string> using namespace std; class mystring { 	private: 		string str; 	public: 		mystring(string s):str(s){} 		void myreverse(); 		void print_string(); }; void mystring::myreverse() { 	reverse(str.begin(),str.end()); } void mystring::print_string() { 	cout << str << endl; }  int main() { 	string a; 	cin >> a; 	mystring obj(a); 	obj.myreverse(); 	obj.print_string(); 	return 0; }

// reversing list #include <iostream> #include <list>  int main () {   std::list<int> mylist;    for (int i=1; i<10; ++i) mylist.push_back(i);    mylist.reverse();    std::cout << "mylist contains:";   for (std::list<int>::iterator it=mylist.begin(); it!=mylist.end(); ++it)     std::cout << ' ' << *it;    std::cout << '\n';    return 0; }

for(;(*ch) != '\0';)         printf("%c",*ch); 这个循环要么死循环，要么一次都不会执行

引用 1 楼 zgxyz2010 的回复:"asdasdasd"是在常量内存区分配的，你却在*ch2 = *cp试图修改该内存，要崩溃，修改为char  ch[] = "asdasdasd";至于其他问题，楼主再慢慢调试额好吧，谢谢，这个的确不知道

/**  * @file    strrev.c  * @brief     */  #include <stdio.h> #include <string.h>  char * strrev(char *s) {     char  c;     char *b, *e;      for (e = s; *e != '\0'; e++)         ;     for (b = s, e--; b < e; b++, e--) {          c = *b;         *b = *e;         *e =  c;     }     return s; }  int main(void) {     char s[] = "0123456789ABCDEF";      printf("[%s]\n", strrev(s));     printf("[%s]\n", strrev(s));      s[15] = '\0';     printf("[%s]\n", strrev(s));     printf("[%s]\n", strrev(s));      s[14] = '\0';     printf("[%s]\n", strrev(s));     printf("[%s]\n", strrev(s));      s[10] = '\0';     printf("[%s]\n", strrev(s));     printf("[%s]\n", strrev(s));      s[9] = '\0';     printf("[%s]\n", strrev(s));     printf("[%s]\n", strrev(s));      s[1] = '\0';     printf("[%s]\n", strrev(s));     printf("[%s]\n", strrev(s));      s[0] = '\0';     printf("[%s]\n", strrev(s));     printf("[%s]\n", strrev(s));      return 0; }  /* output: [FEDCBA9876543210] [0123456789ABCDEF] [EDCBA9876543210] [0123456789ABCDE] [DCBA9876543210] [0123456789ABCD] [9876543210] [0123456789] [876543210] [012345678] [0] [0] [] [] */

#include<stdio.h> #include<string.h> int main(void) {      char   ch[] = "asdasdasd";      char * ch2;      char * cp;      int a,b;      char temp;       a = 1;      cp = ch;      ch2 = ch;      while(*(++cp) != '\0')         a++;      cp--;       for(b = 0;b <(a/2);b++)      {         temp = *ch2;         *ch2 = *cp;         *cp = temp;         ch2++;         cp--;      }      for(ch2 = ch; (*ch2) != '\0'; ch2++)         printf("%c",*ch2);              return 0;   }

#include <stdio.h> #include <string.h>   int main() { 	char tmp; 	char ch[] = "abcdefg"; 	int len = sizeof(ch)/sizeof(char); 	int i = 0, j = len - 2;//长度包括最后的'\0',所以最后的字符下标为len-2 	while (i < j) 	{ 		if (ch[i] != ch[j]) 		{ 			tmp = ch[i]; 			ch[i] = ch[j]; 			ch[j] = tmp;			 		} 		++i; 		--j; 	} 	printf("%s\n", ch); 	return 0; }


Question: 求指导大数阶乘，自己写了一个但是值到30就不准确了

#include <stdio.h> #include <stdlib.h>  /* run this program using the console pauser or add your own getch, system("pause") or input loop */  int main()  { 	long a[3000] = {0}; 	int n,i,m,j; 	int k= 1; 	a[0] = 1; 	printf("请输入n："); 	scanf("%d",&n); 	for(i = 1,j = 0;i <= n;i++) 	{ 		for(m = 0;m <= j;m++) 		{ 			a[m] = a[m]*i; 		} 		for(m = 0;m <= j;m++) 		{ 			if(a[m] > 10) 			{ 				a[m+1] = a[m+1] + a[m]/10; 				a[m] = a[m]%10; 			} 		} 		if(a[j] > 0) 			j++; 		 	} 	for(i = j-1;0 <= i;i--){ 		printf("%ld",a[i]); 	} 	printf("\n总共%d位",j); 	return 0; }

大神们，，，小弟受教了，，，，

进位处理有问题，while(a[j] > 0) j++; 遇到10不是分成0和1了，要么记一下位数，或者直接找一下换成 for(j=3000;!a[j-1];j--);

向楼主推荐： 我以前看过这个帖子：http://bbs.csdn.net/topics/390962326 这个帖子中5楼有赵4老师的解答，楼主可参考其思路……

看懂我意思。你比如乘之前数是1，那么j=1。假设乘以后是101，那么a[j]（a[1]）还是0，但是这时候a[2]是1，所以你实际j应该要弄成3，但是按照你的逻辑j还是1，那就丢了最高位的数字了。

但是我的第二for循环已经把每个数都保持在10以内了哈。。。

while(a[j] > 0) j++;  位数不是这么算的。你假设一个1一下子蹦到101，按你这办法你会以为还是1。


Question: 错误信息

多谢前辈指点，编译无错，可以运行。

#include <stdio.h>  //方式一函数要声明 才能找到定义 void printstar(); void print_message();  //方式二为遇到定义 即为定义且声明 /* void printstar()//函数void类型最好不要省略 { printf("********************\n");  return;//不管函数返回值是什么类型 写return是件只对不错的事情。 } void print_message()//函数void类型最好不要省略 { printf("How do you do!"); //不管函数返回值是什么类型 写return是件只对不错的事情。 }  */ int main() {     printstar();         //call function      print_message();     printstar();      return 0;//返回 C语言默认返回int int不写也返回int } void printstar()//函数void类型最好不要省略 {     printf("********************\n");      return;//不管函数返回值是什么类型 写return是件只对不错的事情。 } void print_message()//函数void类型最好不要省略 {     printf("How do you do!");     //不管函数返回值是什么类型 写return是件只对不错的事情。 }


Question: 求C开发工具.

不知道你要如何才叫爽啊！！！要IDE猜测你想写的代码？

引用 5 楼 luciferisnotsatan 的回复:VC+VS还不觉得满意的话，那就用emacs，然后自己写各种插件加上去。 打错了，是VC+VA

VC+VS还不觉得满意的话，那就用emacs，然后自己写各种插件加上去。

安装vs2010之后，安装Visual Assist X， 爽到不行。。

试试QT creator吧

VC就够用了额，编辑工具不是问题，问题是遇到问题怎么解决问题。

code blocks ?


Question: 执行时，该内存不能为"read"，求指点！

午夜散分！多谢各位大虾的热情支持了！

下面是VC debug下，常见的几个内存问题 　　0xcdcdcdcd - Created but not initialized  　　0xdddddddd - Deleted  　　0xfeeefeee - Freed memory set by NT's heap manager  　　0xcccccccc - Uninitialized locals in VC6 when you compile w/ /GZ  　　0xabababab - Memory following a block allocated by LocalAlloc()

哪个指针（局部变量的）没有初始化，自己找找。

引用 17 楼 a1193561652 的回复:其实我想说我真的不知道C的实现标准什么的。 另，我看了我刚才的解释觉得写的有点误导楼主， wc={xxx}；是将wc的第一个成员赋值为xxx，后面的成员没有给出要付的值，就默认赋值为0了。 所以wc={2}；不是将每一个成员都赋值为2，是只将第一个成员赋值为2，后面的都是0. 没关系。能给我解释这么多已经远远超过我的预期了！谢谢了，帅哥！

引用 18 楼 call_from_dream 的回复:[quote=引用 16 楼 sholber 的回复:] [quote=引用 15 楼 a1193561652 的回复:] [quote=引用 13 楼 sholber 的回复:] [quote=引用 12 楼 a1193561652 的回复:] [quote=引用 10 楼 sholber 的回复:] [quote=引用 9 楼 a1193561652 的回复:] [quote=引用 5 楼 call_from_dream 的回复:] [quote=引用 3 楼 a1193561652 的回复:] 定义窗口类的时候差一个窗口菜单的定义，wc又是局部变量所以初始值不确定，加一个wc.lpszMenuName=NULL;套用星爷电影里的一句台词：我对你的佩服犹如滔滔江水，连绵不绝…… 加一个wc.lpszMenuName=NULL;立马就OK了。 有人刚跟我说，把wc初始化：WNDCLASS wc = {0};这样也OK。wc作为WNDCLASS类的一个对象，里面有很多成员，这么初始化，我感觉很怪。不过，那么做也OK。能告诉我怎么回事吗？//我现在刚学MFC,技术很菜[/quote] 就是上面说的wc是局部变量，初始值不确定，如果你不给它赋值谁知道它里面是什么奇奇怪怪的东西，于是就报错了(理论上人品爆表是可以不报错的)。WNDCLASS wc = {0}是申请变量时就就把他初始化（相当于int i=0;类似的），这样wc里面的所有成员都赋值为0了。[/quote]  struct T {char a, b, c, d, e;} t = {0}; 这样，结构的所有成员都是0了？ 你的依据呢，小朋友？[/quote] int main() { 	struct T 	{ 		int a,b,c; 	} t1={0},t2; 	cout<<t1.a<<t1.b<<t1.c<<endl; 	cout<<t2.a<<t2.b<<t2.c<<endl; 	return 0; } [/quote]  这就是你的依据？我很惊讶。你知道吗，C的实现有符合标准的，也有不符合标准的，还有没跟上标准的。[/quote]好吧确实不知道，这个写法是我不知道在哪看的，不过一直在用而且很好用的样子。[/quote]  哈哈哈，你应该坚持自己的观点，不要被我恶意地左右自己的想法。如果觉得自己正确，要找资料为自己辩护。 其次你是对的。 N1570－－－ Committee Draft — April 12, 2011 ISO/IEC 9899:201x 6.7.9 Initialization If an object that has automatic storage duration is not initialized explicitly, its value is indeterminate. If an object that has static or thread storage duration is not initialized explicitly, then: — if it has pointer type, it is initialized to a null pointer; — if it has arithmetic type, it is initialized to (positive or unsigned) zero; — if it is an aggregate, every member is initialized (recursively) according to these rules, and any padding is initialized to zero bits; — if it is a union, the first named member is initialized (recursively) according to these rules, and any padding is initialized to zero bits;  If there are fewer initializers in a brace-enclosed list than there are elements or members of an aggregate, or fewer characters in a string literal used to initialize an array of known size than there are elements in the array, the remainder of the aggregate shall be initialized implicitly the same as objects that have static storage duration.[/quote] 弱弱的问一句：大虾，你这资料在哪找的？[/quote]  C99标准的pdf，网上多得很； C11标准的PDF，n1570 但C11没有正式官方文本的PDF

引用 16 楼 sholber 的回复:[quote=引用 15 楼 a1193561652 的回复:] [quote=引用 13 楼 sholber 的回复:] [quote=引用 12 楼 a1193561652 的回复:] [quote=引用 10 楼 sholber 的回复:] [quote=引用 9 楼 a1193561652 的回复:] [quote=引用 5 楼 call_from_dream 的回复:] [quote=引用 3 楼 a1193561652 的回复:] 定义窗口类的时候差一个窗口菜单的定义，wc又是局部变量所以初始值不确定，加一个wc.lpszMenuName=NULL;套用星爷电影里的一句台词：我对你的佩服犹如滔滔江水，连绵不绝…… 加一个wc.lpszMenuName=NULL;立马就OK了。 有人刚跟我说，把wc初始化：WNDCLASS wc = {0};这样也OK。wc作为WNDCLASS类的一个对象，里面有很多成员，这么初始化，我感觉很怪。不过，那么做也OK。能告诉我怎么回事吗？//我现在刚学MFC,技术很菜[/quote] 就是上面说的wc是局部变量，初始值不确定，如果你不给它赋值谁知道它里面是什么奇奇怪怪的东西，于是就报错了(理论上人品爆表是可以不报错的)。WNDCLASS wc = {0}是申请变量时就就把他初始化（相当于int i=0;类似的），这样wc里面的所有成员都赋值为0了。[/quote]  struct T {char a, b, c, d, e;} t = {0}; 这样，结构的所有成员都是0了？ 你的依据呢，小朋友？[/quote] int main() { 	struct T 	{ 		int a,b,c; 	} t1={0},t2; 	cout<<t1.a<<t1.b<<t1.c<<endl; 	cout<<t2.a<<t2.b<<t2.c<<endl; 	return 0; } [/quote]  这就是你的依据？我很惊讶。你知道吗，C的实现有符合标准的，也有不符合标准的，还有没跟上标准的。[/quote]好吧确实不知道，这个写法是我不知道在哪看的，不过一直在用而且很好用的样子。[/quote]  哈哈哈，你应该坚持自己的观点，不要被我恶意地左右自己的想法。如果觉得自己正确，要找资料为自己辩护。 其次你是对的。 N1570－－－ Committee Draft — April 12, 2011 ISO/IEC 9899:201x 6.7.9 Initialization If an object that has automatic storage duration is not initialized explicitly, its value is indeterminate. If an object that has static or thread storage duration is not initialized explicitly, then: — if it has pointer type, it is initialized to a null pointer; — if it has arithmetic type, it is initialized to (positive or unsigned) zero; — if it is an aggregate, every member is initialized (recursively) according to these rules, and any padding is initialized to zero bits; — if it is a union, the first named member is initialized (recursively) according to these rules, and any padding is initialized to zero bits;  If there are fewer initializers in a brace-enclosed list than there are elements or members of an aggregate, or fewer characters in a string literal used to initialize an array of known size than there are elements in the array, the remainder of the aggregate shall be initialized implicitly the same as objects that have static storage duration.[/quote] 弱弱的问一句：大虾，你这资料在哪找的？

引用 15 楼 a1193561652 的回复:[quote=引用 13 楼 sholber 的回复:] [quote=引用 12 楼 a1193561652 的回复:] [quote=引用 10 楼 sholber 的回复:] [quote=引用 9 楼 a1193561652 的回复:] [quote=引用 5 楼 call_from_dream 的回复:] [quote=引用 3 楼 a1193561652 的回复:] 定义窗口类的时候差一个窗口菜单的定义，wc又是局部变量所以初始值不确定，加一个wc.lpszMenuName=NULL;套用星爷电影里的一句台词：我对你的佩服犹如滔滔江水，连绵不绝…… 加一个wc.lpszMenuName=NULL;立马就OK了。 有人刚跟我说，把wc初始化：WNDCLASS wc = {0};这样也OK。wc作为WNDCLASS类的一个对象，里面有很多成员，这么初始化，我感觉很怪。不过，那么做也OK。能告诉我怎么回事吗？//我现在刚学MFC,技术很菜[/quote] 就是上面说的wc是局部变量，初始值不确定，如果你不给它赋值谁知道它里面是什么奇奇怪怪的东西，于是就报错了(理论上人品爆表是可以不报错的)。WNDCLASS wc = {0}是申请变量时就就把他初始化（相当于int i=0;类似的），这样wc里面的所有成员都赋值为0了。[/quote]  struct T {char a, b, c, d, e;} t = {0}; 这样，结构的所有成员都是0了？ 你的依据呢，小朋友？[/quote] int main() { 	struct T 	{ 		int a,b,c; 	} t1={0},t2; 	cout<<t1.a<<t1.b<<t1.c<<endl; 	cout<<t2.a<<t2.b<<t2.c<<endl; 	return 0; } [/quote]  这就是你的依据？我很惊讶。你知道吗，C的实现有符合标准的，也有不符合标准的，还有没跟上标准的。[/quote]好吧确实不知道，这个写法是我不知道在哪看的，不过一直在用而且很好用的样子。[/quote]  哈哈哈，你应该坚持自己的观点，不要被我恶意地左右自己的想法。如果觉得自己正确，要找资料为自己辩护。 其次你是对的。 N1570－－－ Committee Draft — April 12, 2011 ISO/IEC 9899:201x 6.7.9 Initialization If an object that has automatic storage duration is not initialized explicitly, its value is indeterminate. If an object that has static or thread storage duration is not initialized explicitly, then: — if it has pointer type, it is initialized to a null pointer; — if it has arithmetic type, it is initialized to (positive or unsigned) zero; — if it is an aggregate, every member is initialized (recursively) according to these rules, and any padding is initialized to zero bits; — if it is a union, the first named member is initialized (recursively) according to these rules, and any padding is initialized to zero bits;  If there are fewer initializers in a brace-enclosed list than there are elements or members of an aggregate, or fewer characters in a string literal used to initialize an array of known size than there are elements in the array, the remainder of the aggregate shall be initialized implicitly the same as objects that have static storage duration.

引用 13 楼 sholber 的回复:[quote=引用 12 楼 a1193561652 的回复:] [quote=引用 10 楼 sholber 的回复:] [quote=引用 9 楼 a1193561652 的回复:] [quote=引用 5 楼 call_from_dream 的回复:] [quote=引用 3 楼 a1193561652 的回复:] 定义窗口类的时候差一个窗口菜单的定义，wc又是局部变量所以初始值不确定，加一个wc.lpszMenuName=NULL;套用星爷电影里的一句台词：我对你的佩服犹如滔滔江水，连绵不绝…… 加一个wc.lpszMenuName=NULL;立马就OK了。 有人刚跟我说，把wc初始化：WNDCLASS wc = {0};这样也OK。wc作为WNDCLASS类的一个对象，里面有很多成员，这么初始化，我感觉很怪。不过，那么做也OK。能告诉我怎么回事吗？//我现在刚学MFC,技术很菜[/quote] 就是上面说的wc是局部变量，初始值不确定，如果你不给它赋值谁知道它里面是什么奇奇怪怪的东西，于是就报错了(理论上人品爆表是可以不报错的)。WNDCLASS wc = {0}是申请变量时就就把他初始化（相当于int i=0;类似的），这样wc里面的所有成员都赋值为0了。[/quote]  struct T {char a, b, c, d, e;} t = {0}; 这样，结构的所有成员都是0了？ 你的依据呢，小朋友？[/quote] int main() { 	struct T 	{ 		int a,b,c; 	} t1={0},t2; 	cout<<t1.a<<t1.b<<t1.c<<endl; 	cout<<t2.a<<t2.b<<t2.c<<endl; 	return 0; } [/quote]  这就是你的依据？我很惊讶。你知道吗，C的实现有符合标准的，也有不符合标准的，还有没跟上标准的。[/quote]好吧确实不知道，这个写法是我不知道在哪看的，不过一直在用而且很好用的样子。

引用 4 楼 u011779875 的回复:问题解决分析思路 找本Win32手册 查找出错的位置的函数RegisterClass 描述函数功能：该函数注册在随后调用CreateWindow函数和CreateWindowEx函数中使用的窗口类。 返回值：如果函数成功，返回值是唯一标识已注册的类的一个原子；如果函数失败，返回值为0。若想获得更多错误信息，请调用GetLastError函数 之后你需要灵感 RegisterClassEx 这个函数 发现不会崩溃，也许这就是为什么出现扩展的一部分原因。 之后你调用GetLastError(); 发现返回值是87 之后你会百度ERROR_INVALID_PARAMETER,可能某个参数不合法 之后你会找个合法的参数进行对比      WNDCLASS wndcls;     wndcls.cbClsExtra=0;     wndcls.cbWndExtra=0;     wndcls.hbrBackground=(HBRUSH)GetStockObject(BLACK_BRUSH);     wndcls.hCursor=LoadCursor(NULL,IDC_CROSS);     wndcls.hIcon=LoadIcon(NULL,IDI_ERROR);     wndcls.hInstance=hInstance;     wndcls.lpfnWndProc=NULL;     wndcls.lpszClassName="Weixin2003";     wndcls.lpszMenuName=NULL;     wndcls.style=CS_HREDRAW | CS_VREDRAW;*/ 很容易得出 wc.lpszMenuName=NULL; 没有设置 导致的 之后你会去了解为什么会这样 不设置就报错了呢 之后 之后 之后 。。。。。。 弱弱的问一句：你是怎么通过Win32手册就查到了出错的位置的函数RegisterClass？

引用 12 楼 a1193561652 的回复:[quote=引用 10 楼 sholber 的回复:] [quote=引用 9 楼 a1193561652 的回复:] [quote=引用 5 楼 call_from_dream 的回复:] [quote=引用 3 楼 a1193561652 的回复:] 定义窗口类的时候差一个窗口菜单的定义，wc又是局部变量所以初始值不确定，加一个wc.lpszMenuName=NULL;套用星爷电影里的一句台词：我对你的佩服犹如滔滔江水，连绵不绝…… 加一个wc.lpszMenuName=NULL;立马就OK了。 有人刚跟我说，把wc初始化：WNDCLASS wc = {0};这样也OK。wc作为WNDCLASS类的一个对象，里面有很多成员，这么初始化，我感觉很怪。不过，那么做也OK。能告诉我怎么回事吗？//我现在刚学MFC,技术很菜[/quote] 就是上面说的wc是局部变量，初始值不确定，如果你不给它赋值谁知道它里面是什么奇奇怪怪的东西，于是就报错了(理论上人品爆表是可以不报错的)。WNDCLASS wc = {0}是申请变量时就就把他初始化（相当于int i=0;类似的），这样wc里面的所有成员都赋值为0了。[/quote]  struct T {char a, b, c, d, e;} t = {0}; 这样，结构的所有成员都是0了？ 你的依据呢，小朋友？[/quote] int main() { 	struct T 	{ 		int a,b,c; 	} t1={0},t2; 	cout<<t1.a<<t1.b<<t1.c<<endl; 	cout<<t2.a<<t2.b<<t2.c<<endl; 	return 0; } [/quote]  这就是你的依据？我很惊讶。你知道吗，C的实现有符合标准的，也有不符合标准的，还有没跟上标准的。

引用 10 楼 sholber 的回复:[quote=引用 9 楼 a1193561652 的回复:] [quote=引用 5 楼 call_from_dream 的回复:] [quote=引用 3 楼 a1193561652 的回复:] 定义窗口类的时候差一个窗口菜单的定义，wc又是局部变量所以初始值不确定，加一个wc.lpszMenuName=NULL;套用星爷电影里的一句台词：我对你的佩服犹如滔滔江水，连绵不绝…… 加一个wc.lpszMenuName=NULL;立马就OK了。 有人刚跟我说，把wc初始化：WNDCLASS wc = {0};这样也OK。wc作为WNDCLASS类的一个对象，里面有很多成员，这么初始化，我感觉很怪。不过，那么做也OK。能告诉我怎么回事吗？//我现在刚学MFC,技术很菜[/quote] 就是上面说的wc是局部变量，初始值不确定，如果你不给它赋值谁知道它里面是什么奇奇怪怪的东西，于是就报错了(理论上人品爆表是可以不报错的)。WNDCLASS wc = {0}是申请变量时就就把他初始化（相当于int i=0;类似的），这样wc里面的所有成员都赋值为0了。[/quote]  struct T {char a, b, c, d, e;} t = {0}; 这样，结构的所有成员都是0了？ 你的依据呢，小朋友？[/quote] int main() { 	struct T 	{ 		int a,b,c; 	} t1={0},t2; 	cout<<t1.a<<t1.b<<t1.c<<endl; 	cout<<t2.a<<t2.b<<t2.c<<endl; 	return 0; }

引用 10 楼 sholber 的回复:[quote=引用 9 楼 a1193561652 的回复:] [quote=引用 5 楼 call_from_dream 的回复:] [quote=引用 3 楼 a1193561652 的回复:] 定义窗口类的时候差一个窗口菜单的定义，wc又是局部变量所以初始值不确定，加一个wc.lpszMenuName=NULL;套用星爷电影里的一句台词：我对你的佩服犹如滔滔江水，连绵不绝…… 加一个wc.lpszMenuName=NULL;立马就OK了。 有人刚跟我说，把wc初始化：WNDCLASS wc = {0};这样也OK。wc作为WNDCLASS类的一个对象，里面有很多成员，这么初始化，我感觉很怪。不过，那么做也OK。能告诉我怎么回事吗？//我现在刚学MFC,技术很菜[/quote] 就是上面说的wc是局部变量，初始值不确定，如果你不给它赋值谁知道它里面是什么奇奇怪怪的东西，于是就报错了(理论上人品爆表是可以不报错的)。WNDCLASS wc = {0}是申请变量时就就把他初始化（相当于int i=0;类似的），这样wc里面的所有成员都赋值为0了。[/quote]  struct T {char a, b, c, d, e;} t = {0}; 这样，结构的所有成员都是0了？ 你的依据呢，小朋友？[/quote] 我查了MSDN,发现WNDCLASS 是个结构体。我原先还以为它是个类呢！如果是类，里面还有函数，估计这么初始化就不行了吧？

引用 9 楼 a1193561652 的回复:[quote=引用 5 楼 call_from_dream 的回复:] [quote=引用 3 楼 a1193561652 的回复:] 定义窗口类的时候差一个窗口菜单的定义，wc又是局部变量所以初始值不确定，加一个wc.lpszMenuName=NULL;套用星爷电影里的一句台词：我对你的佩服犹如滔滔江水，连绵不绝…… 加一个wc.lpszMenuName=NULL;立马就OK了。 有人刚跟我说，把wc初始化：WNDCLASS wc = {0};这样也OK。wc作为WNDCLASS类的一个对象，里面有很多成员，这么初始化，我感觉很怪。不过，那么做也OK。能告诉我怎么回事吗？//我现在刚学MFC,技术很菜[/quote] 就是上面说的wc是局部变量，初始值不确定，如果你不给它赋值谁知道它里面是什么奇奇怪怪的东西，于是就报错了(理论上人品爆表是可以不报错的)。WNDCLASS wc = {0}是申请变量时就就把他初始化（相当于int i=0;类似的），这样wc里面的所有成员都赋值为0了。[/quote]  struct T {char a, b, c, d, e;} t = {0}; 这样，结构的所有成员都是0了？ 你的依据呢，小朋友？

引用 5 楼 call_from_dream 的回复:[quote=引用 3 楼 a1193561652 的回复:] 定义窗口类的时候差一个窗口菜单的定义，wc又是局部变量所以初始值不确定，加一个wc.lpszMenuName=NULL;套用星爷电影里的一句台词：我对你的佩服犹如滔滔江水，连绵不绝…… 加一个wc.lpszMenuName=NULL;立马就OK了。 有人刚跟我说，把wc初始化：WNDCLASS wc = {0};这样也OK。wc作为WNDCLASS类的一个对象，里面有很多成员，这么初始化，我感觉很怪。不过，那么做也OK。能告诉我怎么回事吗？//我现在刚学MFC,技术很菜[/quote] 就是上面说的wc是局部变量，初始值不确定，如果你不给它赋值谁知道它里面是什么奇奇怪怪的东西，于是就报错了(理论上人品爆表是可以不报错的)。WNDCLASS wc = {0}是申请变量时就就把他初始化（相当于int i=0;类似的），这样wc里面的所有成员都赋值为0了。

如果人你不想设置菜单名的话， 有两种解决办法 1，像楼上说的，置为null 2,在结构体初始化的时候 memset(&wc,0,sizeof(wc));  楼主你试试看  总之，结构体使用前最好初始化一下，习惯

wc.lpszClassName = "MyWndClass"; 在这一行下面加上一句 wc.lpszMenuName = "mymenu";  然后就可以运行了  原因是你没有初始化menu，而这在win窗口初始化看来是必须的

WNDCLASS wc = {0};  是用于初始化结构体的,   按顺序初始化, 如果个数不足时会全部填写0.  所以 ={0}, 实际就相当于 memset(&wc, 0, sizeof(wc)); 了.

引用 3 楼 a1193561652 的回复:定义窗口类的时候差一个窗口菜单的定义，wc又是局部变量所以初始值不确定，加一个wc.lpszMenuName=NULL;套用星爷电影里的一句台词：我对你的佩服犹如滔滔江水，连绵不绝…… 加一个wc.lpszMenuName=NULL;立马就OK了。 有人刚跟我说，把wc初始化：WNDCLASS wc = {0};这样也OK。wc作为WNDCLASS类的一个对象，里面有很多成员，这么初始化，我感觉很怪。不过，那么做也OK。能告诉我怎么回事吗？//我现在刚学MFC,技术很菜


Question: 怎样给链表结构体中的字符串数组直接赋值

a.name 表示字符数组的首地址，是个常量所以不能a.name="hello" 你可以使用strcpy(a.name,"hello") 也可以使用sprintf实现

strncpy 是 C语言的库函数之一，来自 C语言标准库， 定义于 string.h，char *strncpy(char *dest, char *src, int n)， 把src所指由以'\0'结束的字符串的前n个字节复制到dest所指的数组中，并返回指向dest的指针。

C/C++的数组不能直接赋值，只能拷贝，可以用memcpy，char[]也可以用strcpy/strncpy（最好用strncpy，更安全）： void * memcpy ( void * destination, const void * source, size_t num ); char * strncpy ( char * destination, const char * source, size_t num ); char * strcpy ( char * destination, const char * source );

我记得结构体赋值一般只能赋值一次（就是最开始的时候），程序在运行的时候是用不上的，比如楼上说的strnpy()和 memcpy()都可以用的上

数组怎么赋值就怎么赋值，没什么区别。

嗯，谢谢，太久没弄C语言了，都忘记可以怎么处理了。。。。。。。

引用 1 楼 pengzhixi 的回复:字符数组就用 strncpy +

字符数组就用 strncpy

没有这样的方法。 你的企图是 a.name = "hello"; 但是，name是数组类型，串字面值"hello"也是数组类型。 数组是不可修改的左值。


Question: 初学者的c代码，哪位好心人帮忙给看一下

后面要是指向的地址

可以看书解决的可以看看书先

scanf("%d\n",a[i]); 改成 scanf("%d",a+i);

scanf("%d",&n); 	for(i=0;i<n;i++) 		scanf("%d",&a[i]);


Question: UVa Problem 10189 Minesweeper （扫雷）

求指点


Question: c primer plus 第六章练习7

引用 1 楼 u010982299 的回复:敲回车时，实际上输入了两个字符\r\n  感谢你的回答。

引用 2 楼 jacksonfan 的回复:      while (1 == t || 0 == t) 	{ 		printf("wrong input, please enter again:\n"); 		flushall();//清除scanf缓冲区 		t = scanf("%f %f", &a, &b); 	}   感谢你的回答。

敲回车时，实际上输入了两个字符\r\n


Question: 高手进（最简单的递归（汉诺塔））

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

楼上正解，把递归如此抽象的东西都画出来了，

人呢？求救啊

高手快来帮帮我啊！！！

百度呀 有很多的

怎么没人啊？

根据你的定义来理解就可以了             有    n个盘子  从a      通过b     到 c void hannuota (int n,     char a,   char b,   char c) 1 先要把上面n-1 移动b  ， 所以为 han(n-1,a,c,b) 2.然后把最后一个移动c, 3. 最后把n-1盘从b移动c              han(n-1,b,a,c)

刚才图片发错了。  我画圈的不是应该和上一行一样吗，只不过n-1了，为什么压栈是acb，第二次压栈的时候就是abc了？搞不懂。。求解释啊

PPT也可以，谢谢谢


Question: 如何用C语言实现域名的多叉树？

段错误，那么肯定是你指针运用出错了。调试肯定能解决的。good luck


Question: 求 VC C++ MD5加密算法及计算实例

#include "global.h" #include "md5.h"  /* Constants for MD5Transform routine. */ #define S11 7 #define S12 12 #define S13 17 #define S14 22 #define S21 5 #define S22 9 #define S23 14 #define S24 20 #define S31 4 #define S32 11 #define S33 16 #define S34 23 #define S41 6 #define S42 10 #define S43 15 #define S44 21  static void MD5Transform PROTO_LIST ((UINT4 [4], unsigned char [64])); static void Encode PROTO_LIST   ((unsigned char *, UINT4 *, unsigned int)); static void Decode PROTO_LIST   ((UINT4 *, unsigned char *, unsigned int)); static void MD5_memcpy PROTO_LIST ((POINTER, POINTER, unsigned int)); static void MD5_memset PROTO_LIST ((POINTER, int, unsigned int));  static unsigned char PADDING[64] = {   0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };  /* F, G, H and I are basic MD5 functions. */ #define F(x, y, z) (((x) & (y)) | ((~x) & (z))) #define G(x, y, z) (((x) & (z)) | ((y) & (~z))) #define H(x, y, z) ((x) ^ (y) ^ (z)) #define I(x, y, z) ((y) ^ ((x) | (~z)))  /* ROTATE_LEFT rotates x left n bits. */ #define ROTATE_LEFT(x, n) (((x) << (n)) | ((x) >> (32-(n))))  /* FF, GG, HH, and II transformations for rounds 1, 2, 3, and 4. Rotation is separate from addition to prevent recomputation. */ #define FF(a, b, c, d, x, s, ac) { \ (a) += F ((b), (c), (d)) + (x) + (UINT4)(ac); \ (a) = ROTATE_LEFT ((a), (s)); \ (a) += (b); \   } #define GG(a, b, c, d, x, s, ac) { \ (a) += G ((b), (c), (d)) + (x) + (UINT4)(ac); \ (a) = ROTATE_LEFT ((a), (s)); \ (a) += (b); \   } #define HH(a, b, c, d, x, s, ac) { \ (a) += H ((b), (c), (d)) + (x) + (UINT4)(ac); \ (a) = ROTATE_LEFT ((a), (s)); \ (a) += (b); \   } #define II(a, b, c, d, x, s, ac) { \ (a) += I ((b), (c), (d)) + (x) + (UINT4)(ac); \ (a) = ROTATE_LEFT ((a), (s)); \ (a) += (b); \   }  /* MD5 initialization. Begins an MD5 operation, writing a new context. */ void MD5Init (context) MD5_CTX *context;                                        /* context */ {   context->count[0] = context->count[1] = 0;   /* Load magic initialization constants. */   context->state[0] = 0x67452301;   context->state[1] = 0xefcdab89;   context->state[2] = 0x98badcfe;   context->state[3] = 0x10325476; }  /* MD5 block update operation. Continues an MD5 message-digest   operation, processing another message block, and updating the   context. */ void MD5Update (context, input, inputLen) MD5_CTX *context;                                        /* context */ unsigned char *input;                                /* input block */ unsigned int inputLen;                    /* length of input block */ {   unsigned int i, index, partLen;    /* Compute number of bytes mod 64 */   index = (unsigned int)((context->count[0] >> 3) & 0x3F);    /* Update number of bits */   if ((context->count[0] += ((UINT4)inputLen << 3))   < ((UINT4)inputLen << 3)) context->count[1]++;   context->count[1] += ((UINT4)inputLen >> 29);    partLen = 64 - index;    /* Transform as many times as possible. */   if (inputLen >= partLen) { MD5_memcpy   ((POINTER)&context->buffer[index], (POINTER)input, partLen); MD5Transform (context->state, context->buffer);  for (i = partLen; i + 63 < inputLen; i += 64)   MD5Transform (context->state, &input[i]);  index = 0;   }   else i = 0;    /* Buffer remaining input */   MD5_memcpy ((POINTER)&context->buffer[index], (POINTER)&input[i],   inputLen-i); }  /* MD5 finalization. Ends an MD5 message-digest operation, writing the   the message digest and zeroizing the context. */ void MD5Final (digest, context) unsigned char digest[16];                        /* message digest */ MD5_CTX *context;                                      /* context */ {   unsigned char bits[8];   unsigned int index, padLen;    /* Save number of bits */   Encode (bits, context->count, 8);    /* Pad out to 56 mod 64. */   index = (unsigned int)((context->count[0] >> 3) & 0x3f);   padLen = (index < 56) ? (56 - index) : (120 - index);   MD5Update (context, PADDING, padLen);    /* Append length (before padding) */   MD5Update (context, bits, 8);   /* Store state in digest */   Encode (digest, context->state, 16);    /* Zeroize sensitive information. */   MD5_memset ((POINTER)context, 0, sizeof (*context)); }  /* MD5 basic transformation. Transforms state based on block. */ static void MD5Transform (state, block) UINT4 state[4]; unsigned char block[64]; {   UINT4 a = state[0], b = state[1], c = state[2], d = state[3], x[16];    Decode (x, block, 64);    /* Round 1 */   FF (a, b, c, d, x[ 0], S11, 0xd76aa478); /* 1 */   FF (d, a, b, c, x[ 1], S12, 0xe8c7b756); /* 2 */   FF (c, d, a, b, x[ 2], S13, 0x242070db); /* 3 */   FF (b, c, d, a, x[ 3], S14, 0xc1bdceee); /* 4 */   FF (a, b, c, d, x[ 4], S11, 0xf57c0faf); /* 5 */   FF (d, a, b, c, x[ 5], S12, 0x4787c62a); /* 6 */   FF (c, d, a, b, x[ 6], S13, 0xa8304613); /* 7 */   FF (b, c, d, a, x[ 7], S14, 0xfd469501); /* 8 */   FF (a, b, c, d, x[ 8], S11, 0x698098d8); /* 9 */   FF (d, a, b, c, x[ 9], S12, 0x8b44f7af); /* 10 */   FF (c, d, a, b, x[10], S13, 0xffff5bb1); /* 11 */   FF (b, c, d, a, x[11], S14, 0x895cd7be); /* 12 */   FF (a, b, c, d, x[12], S11, 0x6b901122); /* 13 */   FF (d, a, b, c, x[13], S12, 0xfd987193); /* 14 */   FF (c, d, a, b, x[14], S13, 0xa679438e); /* 15 */   FF (b, c, d, a, x[15], S14, 0x49b40821); /* 16 */  /* Round 2 */   GG (a, b, c, d, x[ 1], S21, 0xf61e2562); /* 17 */   GG (d, a, b, c, x[ 6], S22, 0xc040b340); /* 18 */   GG (c, d, a, b, x[11], S23, 0x265e5a51); /* 19 */   GG (b, c, d, a, x[ 0], S24, 0xe9b6c7aa); /* 20 */   GG (a, b, c, d, x[ 5], S21, 0xd62f105d); /* 21 */   GG (d, a, b, c, x[10], S22,  0x2441453); /* 22 */   GG (c, d, a, b, x[15], S23, 0xd8a1e681); /* 23 */   GG (b, c, d, a, x[ 4], S24, 0xe7d3fbc8); /* 24 */   GG (a, b, c, d, x[ 9], S21, 0x21e1cde6); /* 25 */   GG (d, a, b, c, x[14], S22, 0xc33707d6); /* 26 */   GG (c, d, a, b, x[ 3], S23, 0xf4d50d87); /* 27 */   GG (b, c, d, a, x[ 8], S24, 0x455a14ed); /* 28 */   GG (a, b, c, d, x[13], S21, 0xa9e3e905); /* 29 */   GG (d, a, b, c, x[ 2], S22, 0xfcefa3f8); /* 30 */   GG (c, d, a, b, x[ 7], S23, 0x676f02d9); /* 31 */   GG (b, c, d, a, x[12], S24, 0x8d2a4c8a); /* 32 */    /* Round 3 */   HH (a, b, c, d, x[ 5], S31, 0xfffa3942); /* 33 */   HH (d, a, b, c, x[ 8], S32, 0x8771f681); /* 34 */   HH (c, d, a, b, x[11], S33, 0x6d9d6122); /* 35 */   HH (b, c, d, a, x[14], S34, 0xfde5380c); /* 36 */   HH (a, b, c, d, x[ 1], S31, 0xa4beea44); /* 37 */   HH (d, a, b, c, x[ 4], S32, 0x4bdecfa9); /* 38 */   HH (c, d, a, b, x[ 7], S33, 0xf6bb4b60); /* 39 */   HH (b, c, d, a, x[10], S34, 0xbebfbc70); /* 40 */   HH (a, b, c, d, x[13], S31, 0x289b7ec6); /* 41 */   HH (d, a, b, c, x[ 0], S32, 0xeaa127fa); /* 42 */   HH (c, d, a, b, x[ 3], S33, 0xd4ef3085); /* 43 */   HH (b, c, d, a, x[ 6], S34,  0x4881d05); /* 44 */   HH (a, b, c, d, x[ 9], S31, 0xd9d4d039); /* 45 */   HH (d, a, b, c, x[12], S32, 0xe6db99e5); /* 46 */   HH (c, d, a, b, x[15], S33, 0x1fa27cf8); /* 47 */   HH (b, c, d, a, x[ 2], S34, 0xc4ac5665); /* 48 */    /* Round 4 */   II (a, b, c, d, x[ 0], S41, 0xf4292244); /* 49 */   II (d, a, b, c, x[ 7], S42, 0x432aff97); /* 50 */   II (c, d, a, b, x[14], S43, 0xab9423a7); /* 51 */   II (b, c, d, a, x[ 5], S44, 0xfc93a039); /* 52 */   II (a, b, c, d, x[12], S41, 0x655b59c3); /* 53 */   II (d, a, b, c, x[ 3], S42, 0x8f0ccc92); /* 54 */   II (c, d, a, b, x[10], S43, 0xffeff47d); /* 55 */   II (b, c, d, a, x[ 1], S44, 0x85845dd1); /* 56 */   II (a, b, c, d, x[ 8], S41, 0x6fa87e4f); /* 57 */   II (d, a, b, c, x[15], S42, 0xfe2ce6e0); /* 58 */   II (c, d, a, b, x[ 6], S43, 0xa3014314); /* 59 */   II (b, c, d, a, x[13], S44, 0x4e0811a1); /* 60 */   II (a, b, c, d, x[ 4], S41, 0xf7537e82); /* 61 */   II (d, a, b, c, x[11], S42, 0xbd3af235); /* 62 */   II (c, d, a, b, x[ 2], S43, 0x2ad7d2bb); /* 63 */   II (b, c, d, a, x[ 9], S44, 0xeb86d391); /* 64 */    state[0] += a;   state[1] += b;   state[2] += c;   state[3] += d;    /* Zeroize sensitive information. */   MD5_memset ((POINTER)x, 0, sizeof (x)); }  /* Encodes input (UINT4) into output (unsigned char). Assumes len is   a multiple of 4. */ static void Encode (output, input, len) unsigned char *output; UINT4 *input; unsigned int len; {   unsigned int i, j;    for (i = 0, j = 0; j < len; i++, j += 4) { output[j] = (unsigned char)(input[i] & 0xff); output[j+1] = (unsigned char)((input[i] >> 8) & 0xff); output[j+2] = (unsigned char)((input[i] >> 16) & 0xff); output[j+3] = (unsigned char)((input[i] >> 24) & 0xff);   } }  /* Decodes input (unsigned char) into output (UINT4). Assumes len is   a multiple of 4. */ static void Decode (output, input, len) UINT4 *output; unsigned char *input; unsigned int len; {   unsigned int i, j;    for (i = 0, j = 0; j < len; i++, j += 4) output[i] = ((UINT4)input[j]) | (((UINT4)input[j+1]) << 8) |   (((UINT4)input[j+2]) << 16) | (((UINT4)input[j+3]) << 24); }  /* Note: Replace "for loop" with standard memcpy if possible. */  static void MD5_memcpy (output, input, len) POINTER output; POINTER input; unsigned int len; {   unsigned int i;    for (i = 0; i < len; i++) output[i] = input[i]; }  /* Note: Replace "for loop" with standard memset if possible. */ static void MD5_memset (output, value, len) POINTER output; int value; unsigned int len; {   unsigned int i;    for (i = 0; i < len; i++) ((char *)output)[i] = (char)value; }


Question: win 8.1下面不支持的C语言系统函数

要么就是你库没有用对，要么就是编译器的问题，不可能不支持系统函数的。 还有系统函数跟C语言没有必然联系，mac下和windows下的系统函数是不一样的， 但是C语言里的函数是一样的，懂吗？

操作系统与C语言本身没有内在关系

楼主你方向错了, 不是系统函数(C库)的问题 编译是小问题, 如果不能用, 编译器厂商会负责处理的 关键 你应该找WIN8下不支持的API,像WIN7下有而win8没有的

#pragma warning(disable:4996)

C语言系统函数，是什么玩意儿？

引用 4 楼 bohecha0104 的回复:[quote=引用 3 楼 sholber 的回复:] [quote=引用 2 楼 bohecha0104 的回复:] 就是我把系统冲win vista升级到win8.1 了， 由于以前有一个C语言写的程序。需要调查这些C的函数能不能再win8.1 上面用而已。  想找出那些函数由于win8.1的升级而不能用了。。。。  取决于你的编译器，而不是win8.1 如果你用的是标准库函数，那么，所有依从于标准的C的实现，都能编译你的程序，但问题是，你所用的编译器能运行在win8.1上吗？[/quote]  编译器是在win8上  是一个公司的应用软件，操作系统升级后，可能会导致应用软件的部分功能不能使用，或者不能编译。 我们要找出这种风险和客户汇报。 你能帮到我们吗？ 谢谢了。[/quote] 这复杂了。有些程序本身就是不可移植的，比如为windows写的程序。但你目前应该不会被它困扰，因为，那个应用软件以前也是在WINDOWS上编译和运行，现在依然是。所以，不能编译的可能性较小。 现在，最大的问题是换个了操作系统，这涉及到编译后的软件同新操作系统的兼容问题。现在俺还不清楚兼容性的问题都涉及到哪些方面。

引用 3 楼 sholber 的回复:[quote=引用 2 楼 bohecha0104 的回复:] 就是我把系统冲win vista升级到win8.1 了， 由于以前有一个C语言写的程序。需要调查这些C的函数能不能再win8.1 上面用而已。  想找出那些函数由于win8.1的升级而不能用了。。。。  取决于你的编译器，而不是win8.1 如果你用的是标准库函数，那么，所有依从于标准的C的实现，都能编译你的程序，但问题是，你所用的编译器能运行在win8.1上吗？[/quote]  编译器是在win8上  是一个公司的应用软件，操作系统升级后，可能会导致应用软件的部分功能不能使用，或者不能编译。 我们要找出这种风险和客户汇报。 你能帮到我们吗？ 谢谢了。

引用 2 楼 bohecha0104 的回复:就是我把系统冲win vista升级到win8.1 了， 由于以前有一个C语言写的程序。需要调查这些C的函数能不能再win8.1 上面用而已。  想找出那些函数由于win8.1的升级而不能用了。。。。  取决于你的编译器，而不是win8.1 如果你用的是标准库函数，那么，所有依从于标准的C的实现，都能编译你的程序，但问题是，你所用的编译器能运行在win8.1上吗？

不知所云....


Question: 如何设置同步信号量保证进程按指定顺序运行

这个演示是线程，不是进程？


Question: 指针的问题，大家看看啊！

谢谢各位指点！

引用 8 楼 ruying1389279 的回复:*p2 = *p1 是把p1所指向的对象赋予p2所指向的对象，是这样吗？ 是的。 不过措辞不严谨。 是把p1所指向的对象的值赋予p2所指向的对象。

*p2 = *p1 是把p1所指向的对象赋予p2所指向的对象，是这样吗？

引用 6 楼 ruying1389279 的回复:[quote=引用 5 楼 sholber 的回复:] int * p1, * p2;//定义两个指针p1,p2 严格地说，这是声明。char * p1 = 0才是定义。  p1 = &i; //指针p1取变量i的地址,即p1 = 5; p2 = &j; //指针p2取变量j的地址,即p2 = 10; 这是胡说。p1永远不可能去取变量i的地址，那是一元&运算符的功能。运算符&的结果类型是指针，只是因为=运算符的右操作数是指针，同左操作数的类型相同，所以才允许赋值。  *p1 = 10; //给指针p1赋值为10 既p1 = 10; i = 10; 胡说。每个指针都属于完整类型，是一个独立的对象。所以，p1是一个独立的对象，它所指向的是另一个对象，也就是i。一元*运算符对指针解引用，指示对象i。最终，这条语句的意思是给指针pi所指向的对象赋值。  *p2 = *p1;//把指针p1的地址赋予指针p2 即p2=p1=i=10 狗屁不通。请参考上一条的解释。是将指针p2所指向的对象的值赋给指针p1所指向的对象。   p1 = p2;//把指针p2的地址赋予p1;这里最后指向的还是p1的地址，因为上一句已经将p1的地址赋予了p2，所以这时候p1和p2的地址都是p1的地址 傻瓜，看黄书看多了，离开个“地址”这个名词，就不能解释程序的意义了？因为指针也是对象，所以，是将指针p2的值赋给p1。这样，两个指针具有相同的值，并因此指向同一个对象。  *p1 = 20;//把20赋予了指针p1 胡说，参考上面的解释。  printf("i = %d\nj = %d\n",*p1,*p2);//p1 p2的值都为20 傻！p1和p2都是指针，*p1和*p2的结果指示指针所指向的对象。 谢谢指点 那*p1 = 10;的意思就是 把10赋予指针p1所指向的对象变量i，也就是改变i的值 还有*p2 = *p1 是把p2所指向的对象赋予p1所指向的对象。 不是把p1所指向的对象赋予p2所指向的对象吗？，写程序验证了下 int main(void) { 	int i = 10,j = 100; 	int *p1 = &i,*p2 = &j; 	*p2 = *p1; 	printf("%d\n",*p2); 	system("pause"); 	return 0;  } 打印的p2值是p1所指向的值 [/quote]  第一条你说得对， 第二条，你说反了。

引用 5 楼 sholber 的回复:int * p1, * p2;//定义两个指针p1,p2 严格地说，这是声明。char * p1 = 0才是定义。  p1 = &i; //指针p1取变量i的地址,即p1 = 5; p2 = &j; //指针p2取变量j的地址,即p2 = 10; 这是胡说。p1永远不可能去取变量i的地址，那是一元&运算符的功能。运算符&的结果类型是指针，只是因为=运算符的右操作数是指针，同左操作数的类型相同，所以才允许赋值。  *p1 = 10; //给指针p1赋值为10 既p1 = 10; i = 10; 胡说。每个指针都属于完整类型，是一个独立的对象。所以，p1是一个独立的对象，它所指向的是另一个对象，也就是i。一元*运算符对指针解引用，指示对象i。最终，这条语句的意思是给指针pi所指向的对象赋值。  *p2 = *p1;//把指针p1的地址赋予指针p2 即p2=p1=i=10 狗屁不通。请参考上一条的解释。是将指针p2所指向的对象的值赋给指针p1所指向的对象。   p1 = p2;//把指针p2的地址赋予p1;这里最后指向的还是p1的地址，因为上一句已经将p1的地址赋予了p2，所以这时候p1和p2的地址都是p1的地址 傻瓜，看黄书看多了，离开个“地址”这个名词，就不能解释程序的意义了？因为指针也是对象，所以，是将指针p2的值赋给p1。这样，两个指针具有相同的值，并因此指向同一个对象。  *p1 = 20;//把20赋予了指针p1 胡说，参考上面的解释。  printf("i = %d\nj = %d\n",*p1,*p2);//p1 p2的值都为20 傻！p1和p2都是指针，*p1和*p2的结果指示指针所指向的对象。 谢谢指点 那*p1 = 10;的意思就是 把10赋予指针p1所指向的对象变量i，也就是改变i的值 还有*p2 = *p1 是把p2所指向的对象赋予p1所指向的对象。 不是把p1所指向的对象赋予p2所指向的对象吗？，写程序验证了下 int main(void) { 	int i = 10,j = 100; 	int *p1 = &i,*p2 = &j; 	*p2 = *p1; 	printf("%d\n",*p2); 	system("pause"); 	return 0;  } 打印的p2值是p1所指向的值

擦，上面的乱了，再发一次  Memory addr  MEM             +----+ 0xef000010  |0x00|             +----+ 0xef000011  |0x19| p2 = 0xef000019 (4 byte)             +----+ 0xef000012  |0x00|             +----+ 0xef000013  |0x00|             +----+ 0xef000014  |0xef|             +----+ 0xef000015  |0x1d| p1 = 0xef00001d (4 byte)             +----+ 0xef000016  |0x00|             +----+ 0xef000017  |0x00|             +----+ 0xef000018  |0xef|             +----+ 0xef000019  |0x02| j = 0x00000002 (4 byte)             +----+ 0xef00001a  |0x00|             +----+ 0xef00001b  |0x00|             +----+ 0xef00001c  |0x00|             +----+ 0xef00001d  |0x01| i = 0x00000001 (4 byte)             +----+ 0xef00001e  |0x00|             +----+ 0xef00001f  |0x00|             +----+ 0xef000020  |0x00|             +----+

int i = 1, j = 2, *p1 = &i, *p2 = &j; // 定义4个变量 下面模拟执行到上面一行的内存布局，你要是能看懂那就没问题了  <Memory addr><MEM> 		        +----+ 0xef000010  |0x00| 		        +----+ 0xef000011  |0x19| p2 = 0xef000019 (4 byte) 		        +----+ 0xef000012  |0x00| 		        +----+ 0xef000013  |0x00| 		        +----+ 0xef000014  |0xef| 		        +----+ 0xef000015  |0x1d| p1 = 0xef00001d (4 byte) 		        +----+ 0xef000016  |0x00| 		        +----+ 0xef000017  |0x00| 		        +----+ 0xef000018  |0xef| 		        +----+ 0xef000019  |0x02| j = 0x00000002 (4 byte) 		        +----+ 0xef00001a  |0x00| 		        +----+ 0xef00001b  |0x00| 		        +----+ 0xef00001c  |0x00| 		        +----+ 0xef00001d  |0x01| i = 0x00000001 (4 byte) 		        +----+ 0xef00001e  |0x00| 		        +----+ 0xef00001f  |0x00| 		        +----+ 0xef000020  |0x00| 		        +----+

1.*p=10；表示将p所指向内容赋值为10，而p是不变的，即所指向地址不变，但这个地址中的内容改变。 3.显然不是 4.p表示一个地址，*p表示这个地址中的内容，都可以输出，只是看你想要看的是地址还是地址中的内容。

3.p1 = p2 是不是等同于 *p1 = *p2 不等同于  p1 p2分别保存的是地址   *p1 与*p2的作用是 按照指针的类型 去所在地址 进行取值  如int *p1  假设p1变量保存的值是 0x80808080 那么*p1就是去这个地址 取4个字节 做为一个int型的数。（32位系统） char *p1则是取到第一个/0才结束。所以p1 = p2 就相当于p1 看世界的方式改变(它要看什么) 它们的赋值 并不能直接改变世界的存在。指针就是看世界的方式. 当然 最后看世界的目的是方便的引用到这个世界并可以改变这个世界。 4.printf()函数打印指针，只能%d%d,*p1,*p2打印吗？为什么%d%d,p1,p2这样打印不行呢？ int i = 5, j = 10;（真实世界）  p1 = &i; p2 = &j;（看世界）  一个是真实的世界  一个是我拿什么看世界 肯定不一样啊。


Question: 线程的顺序调换出错怎么解决

引用 9 楼 user-1 的回复:当然，上面的step根据你的需要，你可以在任意地方增长，比如，完成第一步任务后，你才增长到2，顺序增长 好哒！谢谢大神=3=

如果你不想用event和waitforsingleobject 你也可以用一个简单的while循环试试 用while循环来考查一个变量，只有这个变量到达你的要求，你才执行  初始的时候 int step = 0;  在线程1中 while(step < 1){   sleep(10); }  线程2 while(step < 2){   sleep(10); }  以此类推

最简单的办法是这样  线程在开始执行的时候，先进入一个waitsingleobject, 如果这个信号检测完成，才进入执行  所以，可以设置两个event, 一个给线程1用，一个给线程2用  流程 1，主线程运行 2，主线程启动两个线程 3，两个线程各自在等自己的event 4，主线程把event1设置 5，线程1检查event1成功，开始执行业务，同时把event2设置 6，线程2执行检查event2成功，开始执行业务

引用 5 楼 qq_25344511 的回复:是的……加个=就好了……  顺便问问这里面怎么设置同步量保证两线程按指定顺序运行= =  = =

其实，这只是你一个小小的粗心的错误  if (n = 1)  你把这=改成 ==吧 if(n==1)

不能成功是不能运行？不能启动？还是打印不出？或者是打印得不对？

你说的不能成功是什么意思？

急！在线等！！


Question: 字符串数组 分配内存问题，求大神指导个好的方法

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

仅供参考//循环向a函数每次发送200个字节长度（这个是固定的）的buffer, //a函数中需要将循环传进来的buffer，组成240字节（也是固定的）的新buffer进行处理， //在处理的时候每次从新buffer中取两个字节打印 #ifdef WIN32     #pragma warning(disable:4996) #endif #include <stdio.h> #include <stdlib.h> #include <string.h> #ifdef WIN32     #include <windows.h>     #include <process.h>     #include <io.h>     #define  MYVOID             void     #define  vsnprintf          _vsnprintf #else     #include <unistd.h>     #include <sys/time.h>     #include <pthread.h>     #define  CRITICAL_SECTION   pthread_mutex_t     #define  MYVOID             void * #endif //Log{ #define MAXLOGSIZE 20000000 #define MAXLINSIZE 16000 #include <time.h> #include <sys/timeb.h> #include <stdarg.h> char logfilename1[]="MyLog1.log"; char logfilename2[]="MyLog2.log"; static char logstr[MAXLINSIZE+1]; char datestr[16]; char timestr[16]; char mss[4]; CRITICAL_SECTION cs_log; FILE *flog; #ifdef WIN32 void Lock(CRITICAL_SECTION *l) {     EnterCriticalSection(l); } void Unlock(CRITICAL_SECTION *l) {     LeaveCriticalSection(l); } void sleep_ms(int ms) {     Sleep(ms); } #else void Lock(CRITICAL_SECTION *l) {     pthread_mutex_lock(l); } void Unlock(CRITICAL_SECTION *l) {     pthread_mutex_unlock(l); } void sleep_ms(int ms) {     usleep(ms*1000); } #endif void LogV(const char *pszFmt,va_list argp) {     struct tm *now;     struct timeb tb;      if (NULL==pszFmt||0==pszFmt[0]) return;     vsnprintf(logstr,MAXLINSIZE,pszFmt,argp);     ftime(&tb);     now=localtime(&tb.time);     sprintf(datestr,"%04d-%02d-%02d",now->tm_year+1900,now->tm_mon+1,now->tm_mday);     sprintf(timestr,"%02d:%02d:%02d",now->tm_hour     ,now->tm_min  ,now->tm_sec );     sprintf(mss,"%03d",tb.millitm);     printf("%s %s.%s %s",datestr,timestr,mss,logstr);     flog=fopen(logfilename1,"a");     if (NULL!=flog) {         fprintf(flog,"%s %s.%s %s",datestr,timestr,mss,logstr);         if (ftell(flog)>MAXLOGSIZE) {             fclose(flog);             if (rename(logfilename1,logfilename2)) {                 remove(logfilename2);                 rename(logfilename1,logfilename2);             }         } else {             fclose(flog);         }     } } void Log(const char *pszFmt,...) {     va_list argp;      Lock(&cs_log);     va_start(argp,pszFmt);     LogV(pszFmt,argp);     va_end(argp);     Unlock(&cs_log); } //Log} #define ASIZE    200 #define BSIZE    240 #define CSIZE      2 char Abuf[ASIZE]; char Cbuf[CSIZE]; CRITICAL_SECTION cs_HEX ; CRITICAL_SECTION cs_BBB ; struct FIFO_BUFFER {     int  head;     int  tail;     int  size;     char data[BSIZE]; } BBB; int No_Loop=0; void HexDump(int cn,char *buf,int len) {     int i,j,k;     char binstr[80];      Lock(&cs_HEX);     for (i=0;i<len;i++) {         if (0==(i%16)) {             sprintf(binstr,"%03d %04x -",cn,i);             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]:'.');             }             Log("%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]:'.');         }         Log("%s\n",binstr);     }     Unlock(&cs_HEX); } int GetFromRBuf(int cn,CRITICAL_SECTION *cs,FIFO_BUFFER *fbuf,char *buf,int len) {     int lent,len1,len2;      lent=0;     Lock(cs);     if (fbuf->size>=len) {         lent=len;         if (fbuf->head+lent>BSIZE) {             len1=BSIZE-fbuf->head;             memcpy(buf     ,fbuf->data+fbuf->head,len1);             len2=lent-len1;             memcpy(buf+len1,fbuf->data           ,len2);             fbuf->head=len2;         } else {             memcpy(buf     ,fbuf->data+fbuf->head,lent);             fbuf->head+=lent;         }         fbuf->size-=lent;     }     Unlock(cs);     return lent; } MYVOID thdB(void *pcn) {     char        *recv_buf;     int          recv_nbytes;     int          cn;     int          wc;     int          pb;      cn=(int)pcn;     Log("%03d thdB              thread begin...\n",cn);     while (1) {         sleep_ms(10);         recv_buf=(char *)Cbuf;         recv_nbytes=CSIZE;         wc=0;         while (1) {             pb=GetFromRBuf(cn,&cs_BBB,&BBB,recv_buf,recv_nbytes);             if (pb) {                 Log("%03d recv %d bytes\n",cn,pb);                 HexDump(cn,recv_buf,pb);                 sleep_ms(1);             } else {                 sleep_ms(1000);             }             if (No_Loop) break;//             wc++;             if (wc>3600) Log("%03d %d==wc>3600!\n",cn,wc);         }         if (No_Loop) break;//     } #ifndef WIN32     pthread_exit(NULL); #endif } int PutToRBuf(int cn,CRITICAL_SECTION *cs,FIFO_BUFFER *fbuf,char *buf,int len) {     int lent,len1,len2;      Lock(cs);     lent=len;     if (fbuf->size+lent>BSIZE) {         lent=BSIZE-fbuf->size;     }     if (fbuf->tail+lent>BSIZE) {         len1=BSIZE-fbuf->tail;         memcpy(fbuf->data+fbuf->tail,buf     ,len1);         len2=lent-len1;         memcpy(fbuf->data           ,buf+len1,len2);         fbuf->tail=len2;     } else {         memcpy(fbuf->data+fbuf->tail,buf     ,lent);         fbuf->tail+=lent;     }     fbuf->size+=lent;     Unlock(cs);     return lent; } MYVOID thdA(void *pcn) {     char        *send_buf;     int          send_nbytes;     int          cn;     int          wc;     int           a;     int          pa;      cn=(int)pcn;     Log("%03d thdA              thread begin...\n",cn);     a=0;     while (1) {         sleep_ms(100);         memset(Abuf,a,ASIZE);         a=(a+1)%256;         if (16==a) {No_Loop=1;break;}//去掉这句可以让程序一直循环直到按Ctrl+C或Ctrl+Break或当前目录下存在文件No_Loop         send_buf=(char *)Abuf;         send_nbytes=ASIZE;         Log("%03d sending %d bytes\n",cn,send_nbytes);         HexDump(cn,send_buf,send_nbytes);         wc=0;         while (1) {             pa=PutToRBuf(cn,&cs_BBB,&BBB,send_buf,send_nbytes);             Log("%03d sent %d bytes\n",cn,pa);             HexDump(cn,send_buf,pa);             send_buf+=pa;             send_nbytes-=pa;             if (send_nbytes<=0) break;//             sleep_ms(1000);             if (No_Loop) break;//             wc++;             if (wc>3600) Log("%03d %d==wc>3600!\n",cn,wc);         }         if (No_Loop) break;//     } #ifndef WIN32     pthread_exit(NULL); #endif } int main() { #ifdef WIN32     InitializeCriticalSection(&cs_log);     InitializeCriticalSection(&cs_HEX );     InitializeCriticalSection(&cs_BBB ); #else     pthread_t threads[2];     int threadsN;     int rc;     pthread_mutex_init(&cs_log,NULL);     pthread_mutex_init(&cs_HEX,NULL);     pthread_mutex_init(&cs_BBB,NULL); #endif     Log("Start===========================================================\n");      BBB.head=0;     BBB.tail=0;     BBB.size=0;  #ifdef WIN32     _beginthread((void(__cdecl *)(void *))thdA,0,(void *)1);     _beginthread((void(__cdecl *)(void *))thdB,0,(void *)2); #else     threadsN=0;     rc=pthread_create(&(threads[threadsN++]),NULL,thdA,(void *)1);if (rc) Log("%d=pthread_create %d error!\n",rc,threadsN-1);     rc=pthread_create(&(threads[threadsN++]),NULL,thdB,(void *)2);if (rc) Log("%d=pthread_create %d error!\n",rc,threadsN-1); #endif      if (!access("No_Loop",0)) {         remove("No_Loop");         if (!access("No_Loop",0)) {             No_Loop=1;         }     }     while (1) {         sleep_ms(1000);         if (No_Loop) break;//         if (!access("No_Loop",0)) {             No_Loop=1;         }     }     sleep_ms(3000);     Log("End=============================================================\n"); #ifdef WIN32     DeleteCriticalSection(&cs_BBB );     DeleteCriticalSection(&cs_HEX );     DeleteCriticalSection(&cs_log); #else     pthread_mutex_destroy(&cs_BBB);     pthread_mutex_destroy(&cs_HEX);     pthread_mutex_destroy(&cs_log); #endif     return 0; }

如果每条信息是无限制长度的，干脆放到文件里。 一般来说，你也只需要若干 2048 字节而已 假设需要 n*2048 那就 开个 2*（n*2048）  即可 或者 n或者n+1个2048的循环缓冲即可， 不过这种情况下，就不会有完整的数据了，只能是分段的了。

引用 6 楼 mymtom 的回复:折中的办法呀, 初始化一个size，如果信息长度len大于size, 就重新分配大的内存。 #define MSG_SIZE 2048 size_t size; char * msg; 初始化的时候 size = MSG_SIZE; msg = malloc(size);  收到的数据长度为len;  if (len > size) {     char *ptr;     ptr = realloc(msg, size);     if (ptr != NULL) {         msg = ptr;         size = len;     }        }  这里的msg是局部变量还是成员变量呢？ 假如是局部变量，那就会出现我不想看到的，每次调用接口都会频繁申请和释放内存。 我估计版主意思应该是成员变量。 但成员变量好像也好难行得通， 从拿到服务器的数据拼成完整的信息之后， 到转换成客户端真正可以使用的数据之间，  有好几个function要对msg进行处理， 几个function里面都会把msg赋值给局部变量 如： msg2[SIZE]; memset(msg2, 0, SIZE) memcpy(msg2, msg1, SIZE) 至于msg2的用途嘛， 每个方法里面都不一样，例如， 其中一个方法处负责处理数据粘包问题，用msg2去保存拆分粘包后的数据。  所以。。要是用成员变量，那得有多少个成员变量去保存这些局部变量呢......

引用 5 楼 sholber 的回复:你先说服务器发过来的每条不超过2048，如超过则分开发送； 接着又说如果服务器发来的超过2048； 你到底几个意思。 如果你接受的信息是完整的，直接使用原始的串指针就可以； 否则，直接创建一个大的缓冲区是必须的，为了效率。 想让火车跑得快，还不想提前建铁路，想临时建铁路。 这是什么想法。  莫怒， 我就是不太懂嘛....所以才来问....  不过可能我描述不清晰你有点误解， 服务器每次发过来的是不会超过2048，但如果信息本身是超过2048的话，服务器会多次发送，客户端接收后会合并成一条完整的信息【就是说这条完整信息会超过2048】，然后我的问题主要是针对客户端如何处理这条超过2048的完整信息。  正如上面4楼所说，然后我的回答

引用 4 楼 user-8 的回复:网络通信, 拆包, 组包那是肯定的.  接收数据 , 组装成完整数据包, 加入队列, 然后其它模块处理这些完整包.  比如一个包长是1024;  如果你一次接收到的数据小于1024, 那么就需要再接收一次, 达到1024成一个完整数据包,   当一次接收的大于1024, 则需要拆出其中的1024做为一个完整包, 剩余数据, 等再次接收达到1024再组成完整包.  如果是一定长数据包, 处理方式相同.  每接收一次数据 就判断是否有完整包, 有就处理, 没有就继续接收.   对，现在服务器就是这样，和你说的一样 例如现在服务器发了4次包【前3次肯定是1024拉，第四次随便一个值就是了】，然后我把4次合成一个完整的数据包，我处理到这里了。   但客户端之后的处理中，有几个function里面都需要用一个临时变量缓存复制这个msg 如： msg2[SIZE]; memset(msg2, 0, SIZE) memcpy(msg2, msg1, SIZE)  至于msg2的用途嘛， 每个方法里面都不一样，例如， 其中一个方法处负责处理数据粘包问题，用msg2去保存拆分粘包后的数据。 就是纠结这些临时变量如何分配内存好。

如2L说的，那就开一个大点的ring buffer，2048*4这样的(消息处理要快)

一般都是创建环形缓冲区

你的方法一和方法二都不太好  你应该大概可以确定服务器发送过来的信息长度一般是多少吧？ 严格来说，如果要编写特别有效率的代码而你又不知道上面这个问题的答案的话.......就需要通过大量测试用统计的方法计算出一般情况下信息的长度    然后把msg定义为这么长的一个数组-----我建议你用new来定义这个数组  这样可以和下面统一 然后，你再定义一个数字，这个数字就是：当上面的那个数组不够用的时候，重新new一个新的数组出来用   这个数组应该多长？你也需要用统计的方法计算下  这么一来，你就做到了如下几点： 通常只new一次 个别时候需要再new一次 ---- 这一次可以确保所有的数据都绝对可以放得下  等你用完了记得delete   另外还要注意一点就是，万一出现了特殊情况或者新的需求，服务器发送来了更长的东西的时候，连两个new都放不下了..... 为了保证代码的健壮性，必须加个if判断，如果服务器发送信息的长度大于了这两个数组长度之和  则报错   这样一来  就可以及时更新代码了  我的这个策略是一个非常常见的策略，广泛应用于数据结构中，c++的vector也用了这样的策略


Question: 有关雷达接收机的软件模拟(c语言)，在做的过程中遇到的几个问题！

在Excel里面另存为.csv（半角逗号间隔列，回车换行间隔行的纯文本）文件。 在C中读该文件。

既然是搞硬件的，那就找个搞软件的合作吧。

这个你完全不懂c的话一两句话说不清啊  c语言如何读写文件自有它相关的函数，比如fopen等等   具体你最好自己查查或者问问身边的人  至于你提出的问题，不难 写个struct 里面有俩成员，一个是union-----里面有相差和编码，还有一个是频率 然后你定义一个这个结构体类型的数组  用来存放你所有的struct  具体查找的时候，只要便利该数组即可    如果上面我说的你听不懂的话.........你最好找个人直接给你做  网上说不清楚


Question: 超级终端

引用 4 楼 A812DLG1 的回复:鼠侠前辈：按你说的做了，还是不报错，难道要重做系统吗？如图  看来你安装的这个dll与你当前的windows不兼容。下载一个兼容的。

鼠侠前辈：按你说的做了，还是不报错，难道要重做系统吗？如图

俺都说了，点“开始” ->“运行”，输入regsvr32 hypertrm.dll  快点结帖给分！

你把那个dll文件和exe放在同一个目录再运行试试

你需要动动fingers： regsvr32 hypertrm.dll


Question: 菜鸟总是每天都有问题，今天我再问一个，关于特定宏的

输出日志推荐本ID原创MyLog： #include <stdio.h> #include <stdlib.h> #include <string.h> #ifdef WIN32     #include <windows.h>     #include <io.h> #else     #include <unistd.h>     #include <sys/time.h>     #include <pthread.h>     #define  CRITICAL_SECTION   pthread_mutex_t     #define  _vsnprintf         vsnprintf #endif //Log{ #define MAXLOGSIZE 20000000 #define MAXLINSIZE 16000 #include <time.h> #include <sys/timeb.h> #include <stdarg.h> char logfilename1[]="MyLog1.log"; char logfilename2[]="MyLog2.log"; static char logstr[MAXLINSIZE+1]; char datestr[16]; char timestr[16]; char mss[4]; CRITICAL_SECTION cs_log; FILE *flog; #ifdef WIN32 void Lock(CRITICAL_SECTION *l) {     EnterCriticalSection(l); } void Unlock(CRITICAL_SECTION *l) {     LeaveCriticalSection(l); } #else void Lock(CRITICAL_SECTION *l) {     pthread_mutex_lock(l); } void Unlock(CRITICAL_SECTION *l) {     pthread_mutex_unlock(l); } #endif void LogV(const char *pszFmt,va_list argp) {     struct tm *now;     struct timeb tb;      if (NULL==pszFmt||0==pszFmt[0]) return;     _vsnprintf(logstr,MAXLINSIZE,pszFmt,argp);     ftime(&tb);     now=localtime(&tb.time);     sprintf(datestr,"%04d-%02d-%02d",now->tm_year+1900,now->tm_mon+1,now->tm_mday);     sprintf(timestr,"%02d:%02d:%02d",now->tm_hour     ,now->tm_min  ,now->tm_sec );     sprintf(mss,"%03d",tb.millitm);     printf("%s %s.%s %s",datestr,timestr,mss,logstr);     flog=fopen(logfilename1,"a");     if (NULL!=flog) {         fprintf(flog,"%s %s.%s %s",datestr,timestr,mss,logstr);         if (ftell(flog)>MAXLOGSIZE) {             fclose(flog);             if (rename(logfilename1,logfilename2)) {                 remove(logfilename2);                 rename(logfilename1,logfilename2);             }         } else {             fclose(flog);         }     } } void Log(const char *pszFmt,...) {     va_list argp;      Lock(&cs_log);     va_start(argp,pszFmt);     LogV(pszFmt,argp);     va_end(argp);     Unlock(&cs_log); } //Log} int main(int argc,char * argv[]) {     int i; #ifdef WIN32     InitializeCriticalSection(&cs_log); #else     pthread_mutex_init(&cs_log,NULL); #endif     for (i=0;i<10000;i++) {         Log("This is a Log %04d from FILE:%s LINE:%d\n",i, __FILE__, __LINE__);     } #ifdef WIN32     DeleteCriticalSection(&cs_log); #else     pthread_mutex_destroy(&cs_log); #endif     return 0; } //1-78行添加到你带main的.c或.cpp的那个文件的最前面 //81-85行添加到你的main函数开头 //89-93行添加到你的main函数结束前 //在要写LOG的地方仿照第87行的写法写LOG到文件MyLog1.log中

查MSDN是Windows程序员必须掌握的技能之一。 Predefined Macros The compiler recognizes six predefined ANSI C macros (see Table 1.1), and the Microsoft C++ implementation provides several more (see Table 1.2). These macros take no arguments and cannot be redefined. Their value (except for __LINE__ and __FILE__) must be constant throughout compilation. Some of the predefined macros listed below are defined with multiple values. Their values can be set by selecting the corresponding menu option in the Visual C++ development environment, or by using a command-line switch. See the tables below for more information.  Table 1.1   ANSI Predefined Macros  Macro Description  __DATE__ The compilation date of the current source file. The date is a string literal of the form Mmm dd yyyy. The month name Mmm is the same as for dates generated by the library function asctime declared in TIME.H.   __FILE__ The name of the current source file. __FILE__ expands to a string surrounded by double quotation marks.   __LINE__ The line number in the current source file. The line number is a decimal integer constant. It can be altered with a #line directive.   __STDC__ Indicates full conformance with the ANSI C standard. Defined as the integer constant 1 only if the /Za compiler option is given and you are not compiling C++ code; otherwise is undefined.   __TIME__ The most recent compilation time of the current source file. The time is a string literal of the form hh:mm:ss.   __TIMESTAMP__ The date and time of the last modification of the current source file, expressed as a string literal in the form Ddd Mmm Date hh:mm:ss yyyy, where Ddd is the abbreviated day of the week and Date is an integer from 1 to 31.       Table 1.2   Microsoft-Specific Predefined Macros   Macro Description  _CHAR_UNSIGNED Default char type is unsigned. Defined when /J is specified.   __cplusplus Defined for C++ programs only.  _CPPRTTI Defined for code compiled with /GR (Enable Run-Time Type Information).  _CPPUNWIND Defined for code compiled with /GX (Enable Exception Handling).  _DLL Defined when /MD or /MDd (Multithread DLL) is specified.  _M_ALPHA Defined for DEC ALPHA platforms. It is defined as 1 by the ALPHA compiler, and it is not defined if another compiler is used.  _M_IX86 Defined for x86 processors. See Table 1.3 for more details.  _M_MPPC Defined for Power Macintosh platforms. Default is 601 (/QP601). See Table 1.4 for more details.  _M_MRX000 Defined for MIPS platforms. Default is 4000 (/QMR4000). See Table 1.5 for more details.  _M_PPC Defined for PowerPC platforms. Default is 604 (/QP604). See Table 1.6 for more details.  _MFC_VER Defines the MFC version. Defined as 0x0421 for Microsoft Foundation Class Library 4.21. Always defined.  _MSC_EXTENSIONS This macro is defined when compiling with the /Ze compiler option (the default).  Its value, when defined, is 1.  _MSC_VER Defines the compiler version. Defined as 1200 for Microsoft Visual C++ 6.0. Always defined.  _MT Defined when /MD or /MDd (Multithreaded DLL) or /MT or /MTd (Multithreaded) is specified.   _WIN32 Defined for applications for Win32®. Always defined.     As shown in following tables, the compiler generates a value for the preprocessor identifiers that reflect the processor option specified.  Table 1.3   Values for _M_IX86  Option in Developer Studio Command-Line Option Resulting Value  Blend /GB _M_IX86 = 500 (Default. Future compilers will emit a different value to reflect the dominant processor.)  Pentium /G5 _M_IX86 = 500  Pentium Pro /G6 _M_IX86 = 600  80386 /G3 _M_IX86 = 300  80486 /G4 _M_IX86 = 400       Table 1.4   Values for _M_MPPC  Option in development environment Command-Line Option Resulting Value  PowerPC 601 /QP601 _M_MPPC = 601 (Default)  PowerPC 603 /QP603 _M_MPPC = 603  PowerPC 604 /QP604 _M_MPPC = 604  PowerPC 620 /QP620 _M_MPPC = 620       Table 1.5   Values for _M_MRX000  Option in Developer Studio Command-Line Option Resulting Value  R4000 /QMR4000 _M_MRX000 = 4000 (Default)  R4100 /QMR4100 _M_MRX000 = 4100  R4200 /QMR4200 _M_MRX000 = 4200  R4400 /QMR4400 _M_MRX000 = 4400  R4600 /QMR4600 _M_MRX000 = 4600  R10000 /QMR10000 _M_MRX000 = 10000       Table 1.6   Values for _M_PPC  Option in Developer Studio Command-Line Option Resulting Value  PowerPC 601 /QP601 _M_PPC = 601  PowerPC 603 /QP603 _M_PPC = 603  PowerPC 604 /QP604 _M_PPC = 604 (Default)  PowerPC 620 /QP620 _M_PPC = 620


Question: 如何输出头文件里定义的结构体名称和大小

结构体都是你自己定义的 名称你自己应该清楚啊， 大小的话可以用sizeof

结构体的大小可以通过sizeof获得，但是名字，你是要做解析头文件的功能吗？

没看明白，举个例子。 要想使用头文件定义的结构体，需要#include 头文件，要想计算大小使用sizeof就可以啊

struct TestStruct { 	int a; 	char b; };

#include <iostream> using  std::cout; int main() { 	const type_info& info = typeid(TestStruct); 	cout << "结构名称为:" << info.name() << "结构大小为" << sizeof(TestStruct); 	return 0; }

struct x  {       int a;      int b;  }xx;  如果按上面的写法来作例子。   x和xx都是结构体的名字。  结构体的大小呢，你可以写sizeof(x);                                                  sizeof(xx);  这个结构体的大小是8个字节。


Question: 用memset()不能有效初始化结构体？

引用 1 楼 u010982299 的回复:你取的是指针大小，而不是结构体大小，改成这样就可以了 memset(cmdstruct,0x0,sizeof(*cmdstruct));  ok，you are right!!  thanks.


Question: 在程序中如何对 char *p[4]赋值？

引用 6 楼 leehh 的回复:[quote=引用 4 楼 lzl_2008 的回复:] char *p[4] ; p[0]= "abc"; p[1]="123"; p[2]="def"; p[3]="456";  我用的是：strncpy(p[i],str,num); //把有效的字段放到数组内。 编译没问题，但无法正常运行的。 [/quote] 搞清楚这两种赋值的区别~~

char *p[4]只是一个指针数组，没有存放数据的空间，把字符串的地址放在里面可以，要想修改数据是不可以的，因为字符串是常量

给数组中每个元素都new你所需要的空间

引用 7 楼 leehh 的回复:[quote=引用 6 楼 leehh 的回复:] [quote=引用 4 楼 lzl_2008 的回复:] char *p[4] ; p[0]= "abc"; p[1]="123"; p[2]="def"; p[3]="456";  我用的是：strncpy(p[i],str,num); //把有效的字段放到数组内。 编译没问题，但无法正常运行的。 [/quote]  但如果我把p[i]直接定义成一位数组，如char p[10]，运行正常。[/quote]  小朋友，傻了吧？ 指针是一个完整类型的对象，但它未必指向一个对象。为了使它指向一个对象，你可以选择的方法之一是malloc p [0] = malloc (num + 1); strncpy (p[i], str, num);

引用 6 楼 leehh 的回复:[quote=引用 4 楼 lzl_2008 的回复:] char *p[4] ; p[0]= "abc"; p[1]="123"; p[2]="def"; p[3]="456";  我用的是：strncpy(p[i],str,num); //把有效的字段放到数组内。 编译没问题，但无法正常运行的。 [/quote]  但如果我把p[i]直接定义成一位数组，如char p[10]，运行正常。

引用 4 楼 lzl_2008 的回复:char *p[4] ; p[0]= "abc"; p[1]="123"; p[2]="def"; p[3]="456";  我用的是：strncpy(p[i],str,num); //把有效的字段放到数组内。 编译没问题，但无法正常运行的。

引用 1 楼 u011308575 的回复:直接对*p[0]赋值，其实是对字符串的第一个字符赋值，你可以直接p[0]='abc'这样赋值，就可以将字符串指针赋给数组元素了！ 不行的，编译是没有问题，但无法正常运行的，我试过。

引用 2 楼 lzl_2008 的回复:char *p[4] = { "abc","123","def","456"};  这个是定义时初始化，我知道是可以的，程序内也有这样的定义。 我要实现的是程序内可以随时改变的，因为abc，123这些值不是固定的，你每次输入什么就给它赋值什么。相当于字符串处理，把有效的字符串放在*p[4]内。


Question: 最基本的Objective C例题

引用 1 楼 u010982299 的回复:Objective C怎么在C语言论坛问？ 因为有个 C 吧

Objective C怎么在C语言论坛问？