c++ 里面, "helloworld"类型是const char [11]   (或者 char const [11]), 自己用typeid试试就知道了(VS的智能感应鼠标指上去也行). c里面, 话说c的类型系统就是蛋疼, 也不用探究类型了, 反正又不能重载.

引用 11 楼 paschen 的回复:"helloworld"我觉得应该是算const char[11]  至于数组类型之间是不能赋值的，但初始化的时候允许这种做法（虽然我不知标准上是否是这样认为）  这个const的依据是从哪里来的？ 数组类型之间不能赋值该怎么解释？ struct t {char a [22];} ta, tb; /* ... ... */ ta = tb; 这算不算是数组类型之间的赋值。

字面串严格地说没有类型，只有字面上的形式的意义。在预处理阶段，它是一个预处理记号，预处理之后，它是一个记号（token），C实现用它初始化一个没有名字的静态数组。 如果字面串用做初始化器，那么，如果是初始化一个指针，则那个静态数组将自动转换为指向其首元素的指针；如果是初始化一个数组，则用那个静态数组的内容来初始化那个数组。 为了方便，在C标准文档里，将字面串看成是基本表达式。凡是可以出现数组类型表达式的地方，也可以使用字面串。所以，字面串通常可以看成是具有数组类型的表达式。

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

引用 楼主 u011877771 的回复:c99 page 71面第6段： The multibyte character sequence is then used to initialize an array of static storage duration and length just sufficient to contain the sequence. 我靠，标准说了这是合法的，那就是合法的了，那问题就很复杂了，要么标准出现了不一致了，要么"helloworld"的类型不是数组类型，那么回到根本问题上，sizeof计算"helloworld"是怎么计算的？它的类型到底是什么呢？  说明 string literal 可以初始化数组不在这里，见 4 楼第二段引用。  标准既然要把它单独拿出来说，一般来说就是不能通过其它条文来解释的。

"helloworld"; 是 const char [11];类型 char arr[] = "helloworld"; 是常量字符串初始化字符数组，不是常量字符数组初始化字符数组的。

引用 5 楼 akirya 的回复:我们都知道数组类型是可以转型为指针类型的，这句话是错误的，你查查标准有没退化这种说法么？  数组类型可以赋值给指针类型。 arr是数组类型，p是指针。完全不一样的东西。 额看错了。。。忽略这个吧

ISO/IEC 9899:1999 6.4.5 String literals 5 In translation phase 7, a byte or code of value zero is appended to each multibyte character sequence that results from a string literal or literals.65) The multibyte character sequence is then used to initialize an array of static storage duration and length just sufficient to contain the sequence. For character string literals, the array elements have type char, and are initialized with the individual bytes of the multibyte character sequence; for wide string literals, the array elements have type wchar_t, and are initialized with the sequence of wide characters corresponding to the multibyte character sequence, as defined by the mbstowcs function with an implementation-defined current locale. The value of a string literal containing a multibyte character or escape sequence not represented in the execution character set is implementation-defined.  6.7.8 Initialization 14 An array of character type may be initialized by a character string literal, optionally enclosed in braces. Successive characters of the character string literal (including the terminating null character if there is room or if the array is of unknown size) initialize the elements of the array.

第一句是个特殊语法 第二句就是一个语法糖

引用 1 楼 u011877771 的回复:其实我个人认为是数组类型，至于用字符串去初始化数组为什么合法这个的确是不需要去探究了，就像 char arr2[] = { 'h', 'e', 'l', 'l', 'o', '\0' }; 这句一样合法，但是又能怎么解释呢？只能说当个语法记得就可以了 至于 arr2 = arr; 这句为什么不合法，那标准说它不合法，那我只能认为这个c99语言的语法本身不支持罢了 打错了 arr2 = arr不合法是因为arr2不能为左值，数组名不能作左值 正确的例子： char arr3[] = arr;


Question: 大一程序猿，求解一个你们肯定会的程序设计

double sinx(double xdec) {     auto x=xdec/180*acos(-1.0);     auto ans=0.0, dx=x,x2=x*x;     int sign=1,deno=1;     while(dx>0.00001){         if(sign&1) ans+=dx;         else ans -=dx;         sign ^=1;         dx *=x2;         dx /=++deno;         dx /=++deno;     }     return ans; }

貌似上学的时候也见过,但是忘了怎么做了...只能默默帮顶.....


Question: 新手问舍位和上溢

浮点数转换为整数时候，上溢的时候 有的编译器，会置为最大（最小）可表示数字 有的编译器，会采用截取法  整型之间的转换，一般都是截取法 如果需要置为最大（最小）可表示数字，需要自行编码处理。，  另外，常量溢出，应该不同编译器，处理方式不同。 没看标准，不敢乱猜

比如你做加法后，结果用的原来的类型已经存储不下了，就发生上溢了，高位的数据就丢失了，同样减法就会发生下溢 比如一个字节如果表示无符号，范围是0-128，有符号是-128-127，同理其他

百度搜


Question: 新手请高手赐教简单的问题

GDB常用命令 调用gdb编译需要在cc后面加 -g参数再加-o； [root@redhat home]#gdb 调试文件：启动gdb (gdb) l ：（字母l）从第一行开始列出源码 (gdb) break n :在第n行处设置断点 (gdb) break func：在函数func()的入口处设置断点 (gdb) info break： 查看断点信息 (gdb) r：运行程序 (gdb) n：单步执行 (gdb) c：继续运行 (gdb) p 变量 ：打印变量的值 (gdb) bt：查看函数堆栈 (gdb) finish：退出函数 (gdb) shell 命令行：执行shell命令行 (gdb) set args 参数:指定运行时的参数 (gdb) show args：查看设置好的参数 (gdb) show paths:查看程序运行路径；            set environment varname [=value] 设置环境变量。如：set env USER=hchen；             show environment [varname] 查看环境变量； (gdb) cd 相当于shell的cd; (gdb)pwd ：显示当前所在目录 (gdb)info program： 来查看程序的是否在运行，进程号，被暂停的原因。 (gdb)clear 行号n：清除第n行的断点 (gdb)delete 断点号n：删除第n个断点 (gdb)disable 断点号n：暂停第n个断点 (gdb)enable 断点号n：开启第n个断点 (gdb)step：单步调试如果有函数调用，则进入函数；与命令n不同，n是不进入调用的函数的 list ：简记为 l ，其作用就是列出程序的源代码，默认每次显示10行。 list 行号：将显示当前文件以“行号”为中心的前后10行代码，如：list 12 list 函数名：将显示“函数名”所在函数的源代码，如：list main list ：不带参数，将接着上一次 list 命令的，输出下边的内容。 注意 ：如果运行list 命令得到类似如下的打印，那是因为在编译程序时没有加入 -g 选项： (gdb) list 1       ../sysdeps/i386/elf/start.S: No such file or directory.         in ../sysdeps/i386/elf/start.S run：简记为 r ，其作用是运行程序，当遇到断点后，程序会在断点处停止运行，等待用户输入下一步的命令。 回车：重复上一条命令。 set args：设置运行程序时的命令行参数，如：set args 33 55 show args：显示命令行参数 continue：简讯为 c ，其作用是继续运行被断点中断的程序。 break：为程序设置断点。 break 行号：在当前文件的“行号”处设置断点，如：break  33 break 函数名：在用户定义的函数“函数名”处设置断点，如：break cb_button info breakpoints：显示当前程序的断点设置情况 disable breakpoints Num：关闭断点“Num”，使其无效，其中“Num”为 info breakpoints 中显示的对应值 enable breakpoints Num：打开断点“Num”，使其重新生效 step：简记为 s ，单步跟踪程序，当遇到函数调用时，则进入此函数体（一般只进入用户自定义函数）。 next：简记为 n，单步跟踪程序，当遇到函数调用时，也不进入此函数体；此命令同 step 的主要区别是，step 遇到用户自定义的函数，将步进到函数中去运行，而 next 则直接调用函数，不会进入到函数体内。 until：当你厌倦了在一个循环体内单步跟踪时，这个命令可以运行程序直到退出循环体。 finish： 运行程序，直到当前函数完成返回，并打印函数返回时的堆栈地址和返回值及参数值等信息。 stepi或nexti：单步跟踪一些机器指令。 print 表达式：简记为 p ，其中“表达式”可以是任何当前正在被测试程序的有效表达式，比如当前正在调试C语言的程序，那么“表达式”可以是任何C语言的有效表达式，包括数字，变量甚至是函数调用。 print a：将显示整数 a 的值 print ++a：将把 a 中的值加1,并显示出来 print name：将显示字符串 name 的值 print gdb_test(22)：将以整数22作为参数调用 gdb_test() 函数 print gdb_test(a)：将以变量 a 作为参数调用 gdb_test() 函数 bt：显示当前程序的函数调用堆栈。 display 表达式：在单步运行时将非常有用，使用display命令设置一个表达式后，它将在每次单步进行指令后，紧接着输出被设置的表达式及值。如： display a watch 表达式：设置一个监视点，一旦被监视的“表达式”的值改变，gdb将强行终止正在被调试的程序。如： watch a kill：将强行终止当前正在调试的程序 help 命令：help 命令将显示“命令”的常用帮助信息 call 函数(参数)：调用“函数”，并传递“参数”，如：call  gdb_test(55) layout：用于分割窗口，可以一边查看代码，一边测试： layout src：显示源代码窗口 layout asm：显示反汇编窗口 layout regs：显示源代码/反汇编和CPU寄存器窗口 layout split：显示源代码和反汇编窗口 Ctrl + L：刷新窗口 quit：简记为 q ，退出gdb 当然，gdb的功能远不止这些，包括多进程/多线程/信号/远程调试等功能在这里均没有提及，有需要的读者可以参考其它信息 本文来自CSDN博客，转载请标明出处：http://blog.csdn.net/pizi0475/archive/2011/03/08/6232749.aspx


Question: 问题：error=/tmp/liboop.so: undefined symbol: OOPServer_Init!

希望有高人能指点

希望有高人能指点

希望有高人能指点


Question: 请教大神，如果a=5,为什么++a+a++=13？不应该是12吗？

引用 26 楼 Chen8013 的回复:象这样令人费解、并且会有歧义的代码，有多大的意义！！！  Kill time.

象这样令人费解、并且会有歧义的代码，有多大的意义！！！

我错了，通过程序验证应该是12

一句话，不要在一个完整的表达式之内对一个变量进行多次引用，即顺序点之间实现修改，其结果不能保证。不要写这种语句，也不要纠结这种语句。一个编译器一直理解，换个编译器说不定等于12

跟编译器有关。我觉得没什么可以纠结的。平时写代码也不会这么写。要不然你平时用vs2013 突然让你用vs2008 搞不好就会出错了。平时尽量用通用性强的语法更好

++a+a++=13 谁要敢在实际工程中写这种代码,我直接一砖头拍过去,还有必要讨论吗?

引用 14 楼 lm_whales 的回复:++ a  这个表达式取 a自增后的值，但是这个值未必立即取，如果a 继续变化，取变化后的值，也和自增后不矛盾  所以这个表达式 是这么计算的  ++ a ；前缀运算符++ //a=6 a++ ; 后缀运算符 ++；a++这是最后一个子表达式，取 a 的当前值 a=6, 此后 a=7 然后，计算 +这个运算  ++a + a++  ///++a这个子表达式 值为 a 的值7(自增后的值) 7+ 6 =13；  这个表达式 =11，12，13 都对，没什么不可理解的 这在C++11 以前，是顺序点问题。 在这以后，顺序点被废弃， 新的提法大家还没有熟悉， 但是本质上是一样的 c++14 n4296 1.9 Program execution 15 Except where noted, evaluations of operands of individual operators and of subexpressions of individual expressions are unsequenced. [ Note: In an expression that is evaluated more than once during the execution of a program, unsequenced and indeterminately sequenced evaluations of its subexpressions need not be performed consistently in different evaluations. — end note ] The value computations of the operands of an operator are sequenced before the value computation of the result of the operator. If a side effect on a scalar object is unsequenced relative to either another side effect on the same scalar object or a value computation using the value of the same scalar object, and they are not potentially concurrent (1.10), the behavior is undefined.

引用 15 楼 lm_whales 的回复:置顶帖，被弃，因为顺序点的概念被废弃， 新的和置顶帖有同样效果的帖子，还没人去写。  http://blog.csdn.net/fefe82/article/details/37833767  不足之处，还望指正。

“应该”和“实操”之间永远是有区别的。 谁见过现实世界中发生过1+1=2？

我要分   求积分

however，关注更有效的技能的好，比如反汇编。

为啥我算的是12呢

先执行++a，此时a=6，再执行a++，a++=7，但此时a仍然等于6，所以结果是6+7=13

引用 20 楼 fefe82 的回复:[quote=引用 15 楼 lm_whales 的回复:] 置顶帖，被弃，因为顺序点的概念被废弃， 新的和置顶帖有同样效果的帖子，还没人去写。  http://blog.csdn.net/fefe82/article/details/37833767  不足之处，还望指正。[/quote] 收藏到本ID的常用复制粘贴库中。

n=5; ++n使n变成了6, +(n++) 这里的(n++)在计算中为7,输出的结果是6.

莫非是时间这把杀猪刀？

引用 5 楼 lovesmiles 的回复:看置顶贴 看置顶贴 看置顶贴  不看置顶贴就来问++的问题，简直是新人找骂来的。 问题是不知哪只幕后黑手将此经典置顶贴给kill了！

看置顶贴 看置顶贴 看置顶贴  不看置顶贴就来问++的问题，简直是新人找骂来的。


Question: 用栈做的进制转换程序，为什么输出停不下来啊一直是4206655

如下修改2行：  Status StackEmpty(SqStack *S){//判断栈是否为空   return((*S).top==(*S).base);//改 return((*S).top==0); } Status Pop(SqStack *S,SElemType *e){   if((*S).top==(*S).base)return ERROR;   (*S).top--;   *e=*((*S).top); //改 e=(*S).top;   return OK; }


Question: 除零错误！！！错在那啊，找不到

while (z != 0) { y1 = z; x1 = y1; z = x1%y1; } 这里错误，x1=y1=z

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

if(a--0)括号里面应该是逻辑判断 a==0之类的


Question: 有关poj1002的问题，可以AC但编译器通过不了

源代码扩展名是.c还是.cpp区别还是蛮大的。

看得有点晕, AC了你说通不过编译, 强转后可以编译, 又得到CE, 到底有没有AC

那qsort(phone, n, 9,strcmp)中不是缺少第三个参数（每个元素的字节数，用于交换数据）吗？ 这个9不是还是数组的信息吗？

C语言标准库函数 qsort  第一个参数，是数组首地址， 第二个参数，是元素个数，这开头两个参数，是待排序数组信息。 第三个参数是，每个元素的字节数，用于交换数据。 第四个参数是，比较函数，用于比较大小。

奇怪了，昨天明明编译出错今天突然通过了。那么请问一下： qsort的二维数组排序不应该是这样的吗？ qsort(a,1000,sizeof(int)*2,comp); int comp(const void*a,const void*b) {     return((int*)a)[0]-((int*)b)[0]; } 为什么qsort(phone, n, 9,strcmp)也行？ 还有绿色部分是什么意思？


Question: 关于指针数组的一点疑惑

@fefe82 一语中的啊。 thanks

printf的%s不支持nullptr空指针吧

引用 2 楼 suseyaoyao 的回复:@user-3 我问的不是这个啊。。 我是指段错误。为什么会有段错误  访问空指针就会段错误啊

@user-3 我问的不是这个啊。。 我是指段错误。为什么会有段错误

pch[5]是空啊，数组初始化时，如果元素少于个数时，后面会被初始化为0 你pch[6]有六个元素， {"妹","妹","你","别","走"} 只有五个，所以最后一个初始为0，所以就显示(Null)了 就比如你写int a[5] = {1,2,3};   那么a中的值为 1 2 3 0 0


Question: C语言如何导入C++文件头

你包含的时候include的路径错了. 你可以这样写:include"/***/***/*.h"就是include进去绝对路径. 或者你的*.cpp文件在你的*.h文件同一个路径下就这样写:include"./*.h". --- 总的来说:你在你*.cpp文件路径下,可以打开*.h的路径就是include应该包含的路径. 再比如:你的*.h文件在include目录下,*.cpp文件在src目录下.同时include和src目录在同一个目录下,此时你应该这样写: ../include/*.h 既 ../ 找到上一级目录,然后进入include目录,然后定位到你的h文件. 说的比较绕口,希望你可以看明白. 你在一楼列出来的写法肯定是找不到的.

引用 5 楼 FreeMyself 的回复:你用的什么编译器，你用的什么平台，还有看样子不像标准C/C++。在Linux下使用makefile进行程序编译的，主要用C语言写的，最近需要使用一个C++的.so库

你用的什么编译器，你用的什么平台，还有看样子不像标准C/C++。

求教求教求教

求教求教求教


Question: 关于C连接ODBC数据库

//确保D:\MyDir\test.mdb是所需的access文件。 SQLCHAR s[256] = "DRIVER=Microsoft Access Driver(*.mdb);DBQ=D:\\MyDir\\test.mdb";


Question: C语言中函数形参和实参问题    向各位大神求助！

实参只有被调用的时候，才称为实参，其它时候都是形参。

实参是表达式，理论上未必有地址。 形参才是变量，不过形参是函数的调用者，准备的无名变量，准备好以后，开始调用被调函数。， 被调函数执行时，形参才成为了真正 的有名变量。 函数调用结束，形参名字又看不见了。

形参是对数据结构的重定义,实参是数据的一次真实写照!!!!!!!!!!

形参是啥？ 实参是啥？  理解他们的定义你就知道他们为什么可以不同名了，因为他们本来就是不同的东西。 实参传递入函数内部时，是被复制一遍赋值给形参的。

不要相信监视窗口这么不可靠的东西。

形参只是类型相同，实参传的是地址，修改的是地址所指的内容

写了几年, 都忘记啥叫形参, 啥叫实参了


Question: 要求从键盘输入的100个数中最大的质数是多少

#include<stdio.h>   int main() { 	int a[10]; 	int b[10]; 	int i, 		j, 		max; 	int h=0; 	int t=0;  	for(i=0;i<10;i++) 	{ 		scanf_s("%d",&a[i]); 	}  	for(i=0;i<10;i++) 	{ 		for(j=2;j<a[i];j++) 		{ 			if(a[i]%j==0)   //检验所有的数不能除，便是质数 			{ 				t++; 				break; 			} 		} 		if(0==t)   //是质数，保存到b 		{ 			b[h]=a[i]; 			h++; 		} 		else 		{ 			t=0;  //不是质数，t清零，进行下一次 		} 	} 	max=b[0]; 	for(;h>=0;h--) 	{ 		if(max<b[h])	 		{ 			max=b[h]; 		} 	} 	printf("%d\n",max); 	return 0; }

我没电脑，明天早上发给你，几点交？

你的else里面的语句不对，不一定能存10个


Question: 大牛快来帮我啊，写了一个程序，检测没问题，运行就直接挂掉了，怎么回事啊

static student s[1000]; static student ne[1000]; 在占用内存空间较大的局部数组声明的前面加static将其从堆栈数据段挪到全局数据段即可避开因局部数组大小超过默认堆栈大小1MB造成程序不能正常运行的问题。

引用 2 楼 user-2 的回复:测试数据是什么 Sample Input   4 5 25 10 10 12 13 15 CS004 3 5 1 3 CS003 5 2 4 1 3 5 CS002 2 1 2 CS001 3 2 3 5 1 2 40 10 30 CS001 1 2 2 3 20 10 10 10 CS000000000000000001 0 CS000000000000000002 2 1 2 0         Sample Output   3 CS003 60 CS001 37 CS004 37 0 1 CS000000000000000002 20

测试数据是什么

怎么没人来啊


Question: c语言自定义函数

int main()//这个就是自定义函数 {     printf("");//这个就是库函数 }

可以调用，直接调用就好。

引用 2 楼 WeSdFgVs 的回复:[quote=引用 1 楼 动力风暴的回复:]当然可以啊~~~~~ 库函数也是函数。 那怎么调用？合法嘛？[/quote]   void  a() {           strcpy(...);  //库函数 }  建议楼主先看书，这些很基础的东西，否则学起来会很痛苦的

引用 1 楼 动力风暴的回复:当然可以啊~~~~~ 库函数也是函数。 那怎么调用？合法嘛？

当然可以啊~~~~~ 库函数也是函数。


Question: c编程求助


Question: 学习日记二：多项式加法，乘法又出错


Question: SendMessage (hwndEdit, EM_LIMITTEXT, 32000, 0L)中的0L是什么意思？

C++ Integer Constants Integer constants are constant data elements that have no fractional parts or exponents. They always begin with a digit. You can specify integer constants in decimal, octal, or hexadecimal form. They can specify signed or unsigned types and long or short types.  Syntax  integer-constant :  decimal-constant integer-suffixopt octal-constant integer-suffixopt hexadecimal-constant integer-suffixopt 'c-char-sequence'  decimal-constant :  nonzero-digit decimal-constant digit  octal-constant :  0 octal-constant octal-digit  hexadecimal-constant :  0x hexadecimal-digit 0X hexadecimal-digit hexadecimal-constant hexadecimal-digit  nonzero-digit : one of  1 2 3 4 5 6 7 8 9  octal-digit : one of  0 1 2 3 4 5 6 7  hexadecimal-digit : one of  0 1 2 3 4 5 6 7 8 9 a b c d e f A B C D E F  integer-suffix :  unsigned-suffix long-suffixopt long-suffix unsigned-suffixopt  unsigned-suffix : one of  u U  long-suffix : one of  l L  64-bit integer-suffix :  i64  To specify integer constants using octal or hexadecimal notation, use a prefix that denotes the base. To specify an integer constant of a given integral type, use a suffix that denotes the type.  To specify a decimal constant, begin the specification with a nonzero digit. For example:  int i = 157;   // Decimal constant int j = 0198;  // Not a decimal number; erroneous octal constant int k = 0365;  // Leading zero specifies octal constant, not decimal  To specify an octal constant, begin the specification with 0, followed by a sequence of digits in the range 0 through 7. The digits 8 and 9 are errors in specifying an octal constant. For example:  int i = 0377;   // Octal constant int j = 0397;   // Error: 9 is not an octal digit  To specify a hexadecimal constant, begin the specification with 0x or 0X (the case of the “x” does not matter), followed by a sequence of digits in the range 0 through 9 and a (or A) through f (or F). Hexadecimal digits a (or A) through f (or F) represent values in the range 10 through 15. For example:  int i = 0x3fff;   // Hexadecimal constant int j = 0X3FFF;   // Equal to i  To specify an unsigned type, use either the u or U suffix. To specify a long type, use either the l or L suffix. For example:  unsigned uVal = 328u;             // Unsigned value long lVal = 0x7FFFFFL;            // Long value specified                                    //  as hex constant unsigned long ulVal = 0776745ul;  // Unsigned long value

这个参数没用到，随便传一个数

msdn中 搜下EM_LIMITTEXT SendMessage(    (HWND) hWnd,        // handle to destination window    EM_LIMITTEXT,       // message to send   (WPARAM) wParam,    // text length   (LPARAM) lParam     // not used; must be zero );

long 类型常量 0  long 后缀为,l, L，  float 后缀是 f int ,double 不需要后缀 long double 后缀也是L long long 后缀是 ll，LL unsigned long long 后缀是 ULL，ull,也有编译器 支持 llu,LLU， unsigned 后缀是 U,u


Question: 多线程双线链表实现贪食蛇蛇身不长


Question: 关于随机函数，求解释

因为 time 求得的时间粒度太大 你多次调用同一个函数，时间还没来得及变化。 结果是每次产生同一个序列 随机数发生器，是一种遍历一定范围整数 的算法 似乎应该叫，伪随机序列生成器。 我所说的同一程序，两次执行， 指的是 生成的可执行文件。 执行两次， 由于时间差太小，以至于看到的结果相同。 time 似乎是秒级的

引用 11 楼 MicroPDA 的回复:[quote=引用 9 楼 u012956540 的回复:] 函数执行结束，随机种子会被销毁。 相当于随机种子被重置了。 既然种子被重置，又是以时间做的种子，那么随机值不是更应该不同么？为啥会相同呢？[/quote]  time（）的时间默认是以秒为单位的。两次执行的时间间隔太短，随机种子会相同。 代码示例： #include <ctime> #include <cstdio> #include <windows.h> int main() { 	int length = 10; 	for(int i = 0; i < length; i++) 	{ 		__int64 out = time(NULL); 		printf("%ld\n", out); 		Sleep(500); //注释这一句对照运行下 	} 	return 0; }  有关time函数的说明，请见：http://www.cplusplus.com/reference/ctime/time/?kw=time

我用循环调用10W次h()函数测试，果然是时间太短的缘故！谢谢各路大神！

引用 7 楼 lm_whales 的回复:srand((signed)time(NULL))； 应该在所有调用随机数的表达式执行之前，执行。 一般写在 main 开头就可以了 当然，这不能避免，同一程序两次执行生成相同的随机数序列。就想知道两次执行，而且是不同时刻的两次执行为什么生成的随机数序列是相同的呢？

引用 10 楼 baidu_32513371 的回复:嗯，对的，这就是根据时间来决定的，时间太短，值一样  试了函数里面加语句增加运行时间，或者主函数调用函数次数增加到20000，值还是不变，应该不是时间短的问题耶

引用 9 楼 u012956540 的回复:函数执行结束，随机种子会被销毁。 相当于随机种子被重置了。 既然种子被重置，又是以时间做的种子，那么随机值不是更应该不同么？为啥会相同呢？

嗯，对的，这就是根据时间来决定的，时间太短，值一样

函数执行结束，随机种子会被销毁。 相当于随机种子被重置了。

引用 6 楼 ID870177103 的回复:[quote=引用 5 楼 github_27756899 的回复:] srand((signed)time(NULL)); srand()函数赋的值不一样;  你觉得运行这段程序要多久？[/quote] 很短时间(signed)time(NULL)的值一样。  楼主你可以考虑一下每次调用时改变srand()中的值。

引用 5 楼 github_27756899 的回复:srand((signed)time(NULL)); srand()函数赋的值不一样;  你觉得运行这段程序要多久？

引用 2 楼 ID870177103 的回复:因为你每次产生随机数的时候，都重新调用srand每次重新调用产生的随机数都会是一样的？

在一次运行的时候只调用一次 srand

因为你每次产生随机数的时候，都重新调用srand

srand一般实现比较简陋, 这是微软的实现: // Seeds the random number generator with the provided integer. extern "C" void __cdecl srand(unsigned int const seed) {     __acrt_getptd()->_rand_state = seed; }  // Returns a pseudorandom number in the range [0,32767]. extern "C" int __cdecl rand() {     __acrt_ptd* const ptd = __acrt_getptd();      ptd->_rand_state = ptd->_rand_state * 214013 + 2531011;     return (ptd->_rand_state >> 16) & RAND_MAX; }  可以看出srand基本就是一个赋值操作


Question: 正在用c语言写个简单实用的象棋程序

引用 2 楼 zhao4zhong1 的回复:将前面的#define全部注释掉再试试。 您的程序运行后是乱的，而且对于我个初学者来说太复杂了，根本看不懂。不过也谢啦

引用 1 楼 user-3 的回复:你调用qipan_init函数并没有初始化main中的qipan啊，初始化的只是该函数内部的qipan 谢谢啦，你修改的内容解决了我的问题，不过原因我要再想想。非常感谢

象棋程序，进来一看，貌似控制台界面

仅供参考：#include <windows.h> #include <stdio.h>  void ConPrint(char *CharBuffer, int len); void ConPrintAt(int x, int y, char *CharBuffer, int len); void gotoXY(int x, int y); void ClearConsole(void); void ClearConsoleToColors(int ForgC, int BackC); void SetColorAndBackground(int ForgC, int BackC); void SetColor(int ForgC); void HideTheCursor(void); void ShowTheCursor(void);  int main(int argc, char* argv[]) {    HideTheCursor();    ClearConsoleToColors(15, 1);    ClearConsole();    gotoXY(1, 1);    SetColor(14);    printf("This is a test...\n");    Sleep(5000);    ShowTheCursor();    SetColorAndBackground(15, 12);    ConPrint("This is also a test...\n", 23);    SetColorAndBackground(1, 7);    ConPrintAt(22, 15, "This is also a test...\n", 23);    gotoXY(0, 24);    SetColorAndBackground(7, 1);    return 0; }  //This will clear the console while setting the forground and //background colors. void ClearConsoleToColors(int ForgC, int BackC) {    WORD wColor = ((BackC & 0x0F) << 4) + (ForgC & 0x0F);    //Get the handle to the current output buffer...    HANDLE hStdOut = GetStdHandle(STD_OUTPUT_HANDLE);    //This is used to reset the carat/cursor to the top left.    COORD coord = {0, 0};    //A return value... indicating how many chars were written    //not used but we need to capture this since it will be    //written anyway (passing NULL causes an access violation).    DWORD count;     //This is a structure containing all of the console info    // it is used here to find the size of the console.    CONSOLE_SCREEN_BUFFER_INFO csbi;    //Here we will set the current color    SetConsoleTextAttribute(hStdOut, wColor);    if(GetConsoleScreenBufferInfo(hStdOut, &csbi))    {       //This fills the buffer with a given character (in this case 32=space).       FillConsoleOutputCharacter(hStdOut, (TCHAR) 32, csbi.dwSize.X * csbi.dwSize.Y, coord, &count);        FillConsoleOutputAttribute(hStdOut, csbi.wAttributes, csbi.dwSize.X * csbi.dwSize.Y, coord, &count);       //This will set our cursor position for the next print statement.       SetConsoleCursorPosition(hStdOut, coord);    } }  //This will clear the console. void ClearConsole() {    //Get the handle to the current output buffer...    HANDLE hStdOut = GetStdHandle(STD_OUTPUT_HANDLE);    //This is used to reset the carat/cursor to the top left.    COORD coord = {0, 0};    //A return value... indicating how many chars were written    //   not used but we need to capture this since it will be    //   written anyway (passing NULL causes an access violation).    DWORD count;    //This is a structure containing all of the console info    // it is used here to find the size of the console.    CONSOLE_SCREEN_BUFFER_INFO csbi;    //Here we will set the current color    if(GetConsoleScreenBufferInfo(hStdOut, &csbi))    {       //This fills the buffer with a given character (in this case 32=space).       FillConsoleOutputCharacter(hStdOut, (TCHAR) 32, csbi.dwSize.X * csbi.dwSize.Y, coord, &count);       FillConsoleOutputAttribute(hStdOut, csbi.wAttributes, csbi.dwSize.X * csbi.dwSize.Y, coord, &count);       //This will set our cursor position for the next print statement.       SetConsoleCursorPosition(hStdOut, coord);    } }  //This will set the position of the cursor void gotoXY(int x, int y) {    //Initialize the coordinates    COORD coord = {x, y};    //Set the position    SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), coord); }  //This will set the forground color for printing in a console window. void SetColor(int ForgC) {    WORD wColor;    //We will need this handle to get the current background attribute    HANDLE hStdOut = GetStdHandle(STD_OUTPUT_HANDLE);    CONSOLE_SCREEN_BUFFER_INFO csbi;     //We use csbi for the wAttributes word.    if(GetConsoleScreenBufferInfo(hStdOut, &csbi))    {       //Mask out all but the background attribute, and add in the forgournd color       wColor = (csbi.wAttributes & 0xF0) + (ForgC & 0x0F);       SetConsoleTextAttribute(hStdOut, wColor);    } }  //This will set the forground and background color for printing in a console window. void SetColorAndBackground(int ForgC, int BackC) {    WORD wColor = ((BackC & 0x0F) << 4) + (ForgC & 0x0F);;    SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), wColor); }  //Direct console output void ConPrint(char *CharBuffer, int len) {    DWORD count;    WriteConsole(GetStdHandle(STD_OUTPUT_HANDLE), CharBuffer, len, &count, NULL); }  //Direct Console output at a particular coordinate. void ConPrintAt(int x, int y, char *CharBuffer, int len) {    DWORD count;    COORD coord = {x, y};    HANDLE hStdOut = GetStdHandle(STD_OUTPUT_HANDLE);    SetConsoleCursorPosition(hStdOut, coord);    WriteConsole(hStdOut, CharBuffer, len, &count, NULL); }  //Hides the console cursor void HideTheCursor() {    CONSOLE_CURSOR_INFO cciCursor;    HANDLE hStdOut = GetStdHandle(STD_OUTPUT_HANDLE);     if(GetConsoleCursorInfo(hStdOut, &cciCursor))    {       cciCursor.bVisible = FALSE; 	  SetConsoleCursorInfo(hStdOut, &cciCursor);    } }  //Shows the console cursor void ShowTheCursor() {    CONSOLE_CURSOR_INFO cciCursor;    HANDLE hStdOut = GetStdHandle(STD_OUTPUT_HANDLE);     if(GetConsoleCursorInfo(hStdOut, &cciCursor))    {       cciCursor.bVisible = TRUE; 	  SetConsoleCursorInfo(hStdOut, &cciCursor);    } }

这样试下：   #include<stdio.h> #define 车 a #define 马 b #define 相 c #define 士 d #define 帅 e #define 炮 f #define 兵 g #define 車 A #define 馬 B #define 象 C #define 仕 D #define 将 E #define 泡 F #define 卒 G int i,j; char a,b,c,d,e,f,g,A,B,C,D,E,F,G; char qipan[10][9]={{'A','B','C','D','E','D','C','B','A'},{'+','+','+','+','+','+','+','+','+'},{'+','F','+','+','+','+','+','F','+'},{'G','+','G','+','G','+','G','+','G'},{'+','+','+','+','+','+','+','+','+'},{'+','+','+','+','+','+','+','+','+'},{'g','+','g','+','g','+','g','+','g'},{'+','f','+','+','+','+','+','f','+'},{'+','+','+','+','+','+','+','+','+'},{'a','b','c','d','e','d','c','b','a'}}; char** qipan_init() {  	for(i=0;i<10;i++) 	{ 		for(j=0;j<9;j++) 			printf("%4c",qipan[i][j]); 		printf("\n\n"); 	} 	return (char**)qipan; } void print(int M,int N,int X,int Y) { 	qipan[10][9]; 	qipan[X][Y]=qipan[M][N]; 	qipan[M][N]='+'; 	for(i=0;i<10;i++) 	{ 		for(j=0;j<9;j++) 			printf("%4c",qipan[i][j]); 		printf("\n\n"); 	} } int main() {  	qipan_init(); 	int m,n,x,y,flag; 	int step=0;  	for(;;) 	{ 		do 		{ 			printf("请红方走子："); 			scanf("%d%d%d%d",&m,&n,&x,&y); 			if((m<10)&&(m>=0)&&(n<9)&&(n>=0)&&(x<10)&&(x>=0)&&(y<9)&&(y>=0)) 			{ 				switch(qipan[m][n]) 				{ 				case'a':printf("红方走车");flag=1;break; 				case'b':printf("红方走马");flag=1;break; 				case'c':printf("红方走相");flag=1;break; 				case'd':printf("红方走士");flag=1;break; 				case'e':printf("红方走帅");flag=1;break; 				case'f':printf("红方走炮");flag=1;break; 				case'g':printf("红方走兵");flag=1;break; 				default:flag=0;printf("走错子啦！\n"); 				} 				if(flag==1) 				{ 					print(m,n,x,y); 					step++; 				} 			} 			else  				printf("走错啦，重新走\n"); 		} 		while (step%2==0); 		do{ 			printf("请黑方走子："); 			scanf("%d%d%d%d",&m,&n,&x,&y); 			if((m<10)&&(m>=0)&&(n<9)&&(n>=0)&&(x<10)&&(x>=0)&&(y<9)&&(y>=0)) 			{ 				switch(qipan[m][n]) 				{ 				case'A':printf("黑方走车");flag=1;break; 				case'B':printf("黑方走马");flag=1;break; 				case'C':printf("黑方走相");flag=1;break; 				case'D':printf("黑方走士");flag=1;break; 				case'E':printf("黑方走帅");flag=1;break; 				case'F':printf("黑方走炮");flag=1;break; 				case'G':printf("黑方走兵");flag=1;break; 				default:flag=0;printf("走错子啦！\n"); 				} 				if(flag==1) 				{ 					print(m,n,x,y); 					step++; 				} 			} 			else 				printf("走错啦!重新走\n"); 		} 		while(step%2==1); 	} }

将前面的#define全部注释掉再试试。


Question: 已经#define 一个参数，把他用在一个函数前面是什么意思

方便统一定义接口函数特性。

编译时将替换为空，通常这么做是为了让你清楚这个函数是个什么类型的，比如你这个可能是想说是MAC_INTERNAL的API函数，仅此而矣

这个替换之后就是一个空串啊

无意义，好看。


Question: c语言 想写个贪吃蛇，如何实现蛇身自己边长，求高人指点下。

早上试了一下，贪吃蛇可以用一个vector来存储蛇身，每次移动的时候，在vector头部插入新的蛇头，删除蛇尾，然后根据vector更新画面（只要更新新蛇头和旧蛇尾画面就可以了）

引用 1楼user-4 的回复:用链表写____stl也行百度了下链表 好像可以 研究下

方块的随机出现位置可以用两次rand()函数得到随机的行坐标和列坐标，rand()之前可以用srand()初始化。 楼主可以的

定时器到了准备移动，如果下一次的蛇头位置为墙壁（3）或者为蛇身（1），Game Over。

引用 5 楼 u010165006 的回复:[quote=引用 4 楼 u010165006 的回复:] 贪吃蛇的位置可以定义为二维数组里面的1，空的位置为0，方块的位置为2，吃掉方块以后尾巴添加一个1，方块的位置也改变为1（因为处于蛇身），每次刷新显示的时候根据贪吃蛇位置的数据来画。 每次刷新显示的时候多画一个蛇头，蛇尾用背景画没掉。 主要的是吃掉方块尾巴添加在哪个方向，一般添加的尾巴和原来尾巴的两个方块一条直线，或者尾巴添加在上一次移动蛇身前的尾巴位置。[/quote] 另外用5个变量来存储蛇头位置、蛇尾位置、上一次蛇尾位置、移动方向、下一次蛇头位置，蛇移动的时候如果蛇头位置等于随机的方块位置就吃掉方块，在上一次蛇尾位置添加蛇尾。其实这里还可以优化。

引用 4 楼 u010165006 的回复:贪吃蛇的位置可以定义为二维数组里面的1，空的位置为0，方块的位置为2，吃掉方块以后尾巴添加一个1，方块的位置也改变为1（因为处于蛇身），每次刷新显示的时候根据贪吃蛇位置的数据来画。 每次刷新显示的时候多画一个蛇头，蛇尾用背景画没掉。 主要的是吃掉方块尾巴添加在哪个方向，一般添加的尾巴和原来尾巴的两个方块一条直线，或者尾巴添加在上一次移动蛇身前的尾巴位置。

搜“贪吃蛇 C语言源代码”


Question: 将程序隐藏到后台运行[C语言]

你是要让你写的程序自己隐藏 还是 用你的程序隐藏别的程序  前者参看：http://www.cnblogs.com/syxchina/archive/2010/12/14/2197274.html 后者的话还有点麻烦需要发消息给那个程序

FindWindow ShowWindow

输出也要处理掉

写个批处理程序加载批处理即可，前提是不要有输入，有的话也要处理掉，不然看控制台还会暴露的

不创建控制台程序就行了


Question: 我是新人，初发帖希望有人能告诉我这段代码是什么意思

我希望能帮我理下思路，我就很感谢了

//这是G://inputdata.txt文件内容，我忘打了，抱歉  3 3 4 0 0 3 4 1 0 3 4 1 1

看起来是个数学计算题，求什么内容没看明白


Question: 自己写.h文件，在.c中调用时出错

引用 2 楼 fefe82 的回复:extern struct LNODE *linklist ,lnode;  你是不是想写  teypedef struct LNODE *linklist ,lnode; 我是想在lianbiao.h中声明结构体，然后在lianbiao.c中定义结构体变量。 我把.h中的改了，改成typedef struct LNODE{}*linklist； 然后想在linklist.c中定义一个结构体变量L，在main.c中直接就可以用了····

引用 1 楼 ipqtjmqj 的回复:linklist 是个变量，又不是类型。 一语惊醒，已解决，谢谢。

extern写在函数外面

linklist 是个变量，又不是类型。

引用 6 楼 ziyuxuan7177 的回复:把文件改了一下 lianbiao.h #ifndef _lianbiao_h #define _lianbiao_h  #include<stdio.h> #include<stdlib.h> typedef struct LNODE  { int data; struct LNODE *next; }*linlist，lnode; .......函数声明 #endif ------------------------------------------------------------------ lianbiao.c  linklist L; .............。h中声明的函数的定义   ---------------------------------------------------------------------- main.c #include"lianbiao.h" #include<stdio.h> int main()  { linklist L; `````` return 0; }  这次又出现了错误：main。c中“L"未声明；                                   lianbiao。c中 未知的类型名”linklist“ linklist你未定义，h文件中单词拼错了，注意细节


Question: 有关数组指针的问题

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

上面说错，是char aa[][3];  char bb[][3];

引用 3 楼 u014069062 的回复:“指向一个char[3]的指针”这个是什么意思呢？  数组也是一种类型，一个指针也可以指向他啊  如果你定义了char aa[3];  char bb[3]; 那么你的指针可以指向aa，也可以指向bb 虽然是指向的是首地址，但和二级指针不完全一样，区别同intr[]与int*

引用 4 楼 adan_shaw_VC 的回复:首先，你定义的字符串是没有结束 转义字符，所以会造成： abc...后面乱码 def...后面乱码 乱码   其次，char (*p)[3] = a; 一维字符指针只会指向单个字符。 char (*p)[3] = a; p[0] == a , p[1] == b , p[2] == 0 . 我测试了下，发现p[0]、p[1]并非是单个字符的值，而是指向的某个字符串……

[quote=引用 2 楼 paschen 的回复:] 指向一个char[3]的指针  这个可以理解为二维指针变量吗？

“指向一个char[3]的指针”这个是什么意思呢？

指向一个char[3]的指针  如果是char *p[3]  ，则是一个int*类型的数组，这个数组中有3个int*类型的元素

指向一维数组的指针

引用 4 楼 adan_shaw_VC 的回复:首先，你定义的字符串是没有结束 转义字符，所以会造成： abc...后面乱码 def...后面乱码 乱码   其次，char (*p)[3] = a; 一维字符指针只会指向单个字符。 char (*p)[3] = a; p[0] == a , p[1] == b , p[2] == 0 .楼主也没说是字符串  你想太多了 另外 你并不了解数组指针 还是先看书了解一下

引用 10 楼 lm_whales 的回复:char a[][3] = {'a','b','c','d','e','f'}; char (*p)[3] = a;///<==> char (*p)[3] = &a[0]; a[0] 是个三个字符的数组 p++;/// p== &a[1]; p--;/// 重新变成 p ==&a[0]; char (*p)[3]  ；///指向定长数组的指针, 指向的数组 ,有3个char 元素. p[0][0]///<==>a[0][0]; p[1][1]///<==>a[1][1]; 数组的指针，和非数组指针用法其实是相同的，只是写法比较奇怪 数组指针，指向的目标是数组。 指针数组，每个元素都是指针。  数组指针，只需要 初始化或者赋值一次。就可以像二维数组一样，使用两个下标。 指针数组，每个指针元素，都需要初始化或者赋值一次，才可以像二维数组一样，使用两个下标。 修改一下

char a[][3] = {'a','b','c','d','e','f'}; char (*p)[3] = a;///<==> char (*p)[3] = &a[0]; a[0] 是个三个字符的数组 p++;/// p== &a[1]; p--;///  p ==&a[1]; char (*p)[3]  ；///指向定长数组的指针, 指向的数组 ,有3个char 元素. p[0][0]///<==>a[0][0]; p[1][1]///<==>a[1][1]; 数组的指针，和非数组指针用法其实是相同的，只是写法比较奇怪 数组指针，指向的目标是数组。 指针数组，每个元素都是指针。  数组指针，只需要 初始化或者赋值一次。就可以像二维数组一样，使用两个下标。 指针数组，每个指针元素，都需要初始化或者赋值一次，才可以像二维数组一样，使用两个下标。

举例： int a[5][10]={1,2}; int (*p)[10]=a; cout<<p<<endl; cout<<p[0]<<endl; cout<<p[9]<<endl;  p是指向二维数组a的指针，请问p[0],p[9]分别是什么？ 解答： int(*p)[10]定义了一个指向二维数组的指针p，赋给它10个长度。然后把a数组的值赋给(*p)[10]，注意，这里是a数组是5行10列的，放入（*p）[10]是把a[0][0]，a[0][1]，a[0][2]，a[0][3]，a[0][4]，a[0][5]，a[0][6]，a[0][7]，a[0][8]，a[0][9]放入(*p)[0]中，同理，将a[1][0...9]放入(*p)[1]。最后（*p）[10]中的值只有五行被初始化为a数组的值了。 在本例中，p和p[0]是同一个意思，就是数组a的起始地址，等价于cout<<a<<endl，但是他们有区别，p指向的是整个数组的首地址，而p[0]则指向a的首行首地址（继续往下看...）。 p[9]则值内存为p数组分配的(*p)[9]的地址。如果你仔细验证程序的输出结果，你就会发现： #include<stdio.h> #include "iostream" using std::cout; using std::endl; using std::hex; void main() { int a[5][10]={1,2}; int (*p)[10]=a; cout<<p<<endl; cout<<p[0]<<endl; cout<<p[9]<<endl; } 输出结果为(不同机器结果不同)： 0012FEB8 0012FEB8 00130020 如果你验证它们这些地址存储的值，你会发现： #include<stdio.h> #include "iostream" using std::cout; using std::endl; using std::hex; void main() { int a[5][10]={1,2}; int (*p)[10]=a; cout<<*p<<endl; cout<<(*p)[0]<<endl; cout<<(*p)[9]<<endl; } 输出结果为： 0012FEB8 1 0 这是p和p[0]的区别就体现出来了。因为*p并不是取首元素的值，它这时才相当于p[0]。那如何通过p取得首元素的值呢，很显然，应该再加一个*操作符，如下： cout<<**p<<endl; 这时输出结果自然就会和(*p)[0]一样是1了。


Question: 想了解C语言程序内存怎么分配的，需要看哪些资料？

VMMap 是进程虚拟和物理内存分析实用工具。http://technet.microsoft.com/zh-cn/sysinternals/dd535533

参考Linux源代码中加载可执行文件相关片断。

直接看标准吧

看下这两篇博文就基本明白了  http://blog.csdn.net/gytanonymous/article/details/7060574 http://www.cnblogs.com/lancidie/archive/2011/08/05/2128318.html

看下这两个贴就大概了解了：   [url=http://www.cnblogs.com/lancidie/archive/2011/08/05/2128318.html][/url]

看汇编吧，不过前期没有必要了解这么深~

百度搜  "C 内存管理"

看操作系统原理。


Question: Scanf函数非法输入的处理

仅供参考：#include <stdio.h> int main() {     int a,b,n,v,r,k;     char buf[80];     char *p;      k=0;     r=EOF;     while (1) {         if (EOF==r) {             fgets(buf,80,stdin);             p=buf;         }         while (1) {             r=sscanf(p,"%d%n",&v,&n);             if (1==r) {k++;break;}             if (EOF==r) break;             p++;         }         if (EOF==r) continue;         p+=n;         if (1==k) a=v;         if (2==k) {             b=v;             break;         }     }     printf("%d,%d\n",a,b);     return 0; }

引用 5楼wang0635 的回复:代码哪里无效了？ 没问题啊你输入错误的格式，可以提示继续输入？输出结果贴上来看看？

代码哪里无效了？ 没问题啊

楼主的那个循环是个死循环，fflush的作用只是清空输入流，但是后面的读取一直可以是0。你可以做一个实验试一下。 另外，上面我那段代码还有个缺陷，输入1,3e时也会认为是正确结果。 考虑到fflush是微软自己引进的一个函数，它的机能不是很明确改进为（这种机制可以识别1,3e的错误）：   1 #include<stdio.h>   2 int main()   3 //计算过程中保证只有1,3形式输入才计算，1 3和1,e等   4 //认为是错误输入。直到正确输入才开始计算。   5 {   6 int i,j,a,b,c; /*计算a+b*/   7 int input;   8 char t;   9 for(i=0;;i++)  10 {  11 j=0;  12 input=scanf("%d,%d",&a,&b);  13 while((t=getchar())!='\n'&& t!=EOF) j++;  14 if(input==2 && j==0) break;  15 }  16 c=a+b;  17 printf("%d+%d=%d\n",a,b,c);  18 return 0;  19 } 这种形式scanf("%d,%d")的正确输入格式是var1,var2；如果需要var[空格]var形式，对应改为scanf("%d%d")即可。

楼主的意思是第二段代码输入非法数据的时候程序不提示重新输入?

1 #include<stdio.h>   2 int main()   3 {   4 int i,a,b,c; /*计算a+b*/   5 int input;   6 char t;   7 for(i=0;;i++)   8 {   9 input=scanf("%d,%d",&a,&b);  10 fflush(stdin);  11 if(input==2) break;  12 scanf("%c",&t);  13 }  14 c=a+b;  15 printf("%d+%d=%d",a,b,c);  16 return 0;  17 }  gcc编译通过，前提是输入方式是1,3，1 3认为是不合格的输入。

输入的数据，和格式符号个数相等，表示成功， 函数返回值 就是成功输入的个数 返回值不等于格式要求输入的数据个数以及 0，EOF等表示输入失败 返回正数 表示至少有一个输入成功， 返回值和要求输入的个数相同，表示输入成功 输入失败，包括不完全成功，最好清掉输入缓存


Question: gcc编译静态函数库的问题： 库调用出错

引用 5 楼 user-1 的回复:头文件不就是干这事的么, 不干这个要头文件干嘛. 函数声明写在头文件, 函数实现写在源文件.或者提供静态/动态库 感谢，给分～

引用 2 楼 user-1 的回复:因为t.c里面没有主动声明triarea函数， C语言对于没有声明的函数会假定返回int之类的. c++就相对好点, 直接报错. 你好，请问最后一个问题： 我从网上查到，nm可以查看库函数内包含的函数，但是貌似不能看函数原型。 请问如果从网上下载的库函数，如果不知道它内部包含的函数原型，该怎么用？ 另外，如果在生成库函数时，调用了某些头文件，那么头文件是不是也要提供？ 谢谢～～～

感谢大神！原来还会有这么一说。。。那岂不是说，在linux下，库在被调用的时候需要知道库里面包含的函数原型了？

没有人回答么？ 怎么没有人回答啊。


Question: 谁能帮我分析一下这个题目具体思路[C语言]

仅供参考：#include <iostream> #include <string> #include <regex> using namespace std; int main() {     string str("This expression could match from A and beyond. [ expression  express ]");     string rs = "exp\\w*";  // 正则字符串，exp开始的单词     cout << str << endl;      regex expression(rs); // 字符串传递给构造函数，建立正则表达式  // regex_match 判断一个正则表达式(参数 e)是否匹配整个字符序列 str. 它主要用于验证文本。 // 注意，这个正则表达式必须匹配被分析串的全部，否则函数返回 false. // 如果整个序列被成功匹配，regex_match 返回 True.     bool ret = regex_match(str, expression);     if (ret)         cout << "可以匹配整个文本" << endl;     else         cout << "不能匹配整个文本" << endl;  // regex_search 类似于 regex_match, 但它不要求整个字符序列完全匹配。 // 你可以用 regex_search 来查找输入中的一个子序列，该子序列匹配正则表达式 e.     ret = regex_search(str, expression);     if (ret)         cout << "能够搜索到 " << rs << endl;     else         cout << "不能搜索" << endl;  // regex_replace 在整个字符序列中查找正则表达式e的所有匹配。 // 这个算法每次成功匹配后，就根据参数fmt对匹配字符串进行格式化。 // 缺省情况下，不匹配的文本不会被修改，即文本会被输出但没有改变。      str = regex_replace(str, expression, string("表达式")); // VC2010或者TR1注意：这里第三个参数要用string()转换 // http://www.johndcook.com/cpp_regex.html // started with C++ TR1 regular expressions     cout << str << endl;     return 0; } //This expression could match from A and beyond. [ expression  express ] //不能匹配整个文本 //能够搜索到 exp\w* //This 表达式 could match from A and beyond. [ 表达式  表达式 ]

字符串：121DSFDSFBEG:U=12.34,I=0.03,T=28.5:ENDWERWFEFS 正则表达式：.*:U=([0-9.]*?),I=([0-9.]*?),T=([0-9.]*?): 检索结果：(1).12.34 (2).0.03 (3).28.5

用正则表达式吧


Question: 数据结构——停车场问题，不知道自己错在哪里，望高手解答

那个问题已经解决了，我的pop函数中忘记要返回e的值了。现在还有个新的问题，就是我想把它放在工程里，但是有个Stype的结构体变量定义，我在栈和队列里都用到了它，但是不知道在工程中应该把它写在哪里？ 以下十几个.h文件 第一个：stack.h       #include<stdio.h> #include<stdlib.h> #define initsize 2 typedef struct { 	int num; 	int time; }Stype; //用顺序栈实现停车场 typedef struct { 	Stype *base; 	Stype *top; 	int stacksize; }Sqstack;   void initstack(Sqstack &s);//初始化栈 void push(Sqstack &s,Stype e);//入栈 void pop(Sqstack &s,Stype e);//出栈 int length(Sqstack s);//栈的长度 int print(Sqstack s,Stype car);   第二个 queue.h typedef struct { 	int num; 	int time; }Stype; typedef struct Node { 	Stype data; 	struct Node *next; }Qnode,*Queue;//定义链队列结点类型 typedef struct { 	Queue front; 	Queue rear; }Linkqueue;//定义链队列类型  void initqueue(Linkqueue &q);//初始化队列 void enqueue(Linkqueue &q,Stype e);      //入队列 void dequeue(Linkqueue &q,Stype &e);      //出队列 void gethead(Linkqueue q,Stype &e);//取队头元素 int length(Linkqueue q);//求队列长度 int place(Linkqueue q,Stype c);//在队列中的位置  编译时出现的错误是：d:\数据结构实验\实验五\duilie3\queue.h(15) : error C2371: 'Stype' : redefinition; different basic types         d:\数据结构实验\实验五\duilie3\stack.h(8) : see declaration of 'Stype'

那如果我想要它们分开写的话，在工程里应该怎么写他们呢？

在queue.h和stack.h中Style定义重复了。

具体问题是什么？给个输入输出样例。


你那个是逆序的算法啊，你要对比的crc16用的什么顺序都不明确，只能瞎猜了。而且crc16还有一个ccitt版本，使用的多项式不同。下面是我从linux内核中提取出来的crc16算法： unsigned short const crc16_table[256] = { 	0x0000, 0xC0C1, 0xC181, 0x0140, 0xC301, 0x03C0, 0x0280, 0xC241, 	0xC601, 0x06C0, 0x0780, 0xC741, 0x0500, 0xC5C1, 0xC481, 0x0440, 	0xCC01, 0x0CC0, 0x0D80, 0xCD41, 0x0F00, 0xCFC1, 0xCE81, 0x0E40, 	0x0A00, 0xCAC1, 0xCB81, 0x0B40, 0xC901, 0x09C0, 0x0880, 0xC841, 	0xD801, 0x18C0, 0x1980, 0xD941, 0x1B00, 0xDBC1, 0xDA81, 0x1A40, 	0x1E00, 0xDEC1, 0xDF81, 0x1F40, 0xDD01, 0x1DC0, 0x1C80, 0xDC41, 	0x1400, 0xD4C1, 0xD581, 0x1540, 0xD701, 0x17C0, 0x1680, 0xD641, 	0xD201, 0x12C0, 0x1380, 0xD341, 0x1100, 0xD1C1, 0xD081, 0x1040, 	0xF001, 0x30C0, 0x3180, 0xF141, 0x3300, 0xF3C1, 0xF281, 0x3240, 	0x3600, 0xF6C1, 0xF781, 0x3740, 0xF501, 0x35C0, 0x3480, 0xF441, 	0x3C00, 0xFCC1, 0xFD81, 0x3D40, 0xFF01, 0x3FC0, 0x3E80, 0xFE41, 	0xFA01, 0x3AC0, 0x3B80, 0xFB41, 0x3900, 0xF9C1, 0xF881, 0x3840, 	0x2800, 0xE8C1, 0xE981, 0x2940, 0xEB01, 0x2BC0, 0x2A80, 0xEA41, 	0xEE01, 0x2EC0, 0x2F80, 0xEF41, 0x2D00, 0xEDC1, 0xEC81, 0x2C40, 	0xE401, 0x24C0, 0x2580, 0xE541, 0x2700, 0xE7C1, 0xE681, 0x2640, 	0x2200, 0xE2C1, 0xE381, 0x2340, 0xE101, 0x21C0, 0x2080, 0xE041, 	0xA001, 0x60C0, 0x6180, 0xA141, 0x6300, 0xA3C1, 0xA281, 0x6240, 	0x6600, 0xA6C1, 0xA781, 0x6740, 0xA501, 0x65C0, 0x6480, 0xA441, 	0x6C00, 0xACC1, 0xAD81, 0x6D40, 0xAF01, 0x6FC0, 0x6E80, 0xAE41, 	0xAA01, 0x6AC0, 0x6B80, 0xAB41, 0x6900, 0xA9C1, 0xA881, 0x6840, 	0x7800, 0xB8C1, 0xB981, 0x7940, 0xBB01, 0x7BC0, 0x7A80, 0xBA41, 	0xBE01, 0x7EC0, 0x7F80, 0xBF41, 0x7D00, 0xBDC1, 0xBC81, 0x7C40, 	0xB401, 0x74C0, 0x7580, 0xB541, 0x7700, 0xB7C1, 0xB681, 0x7640, 	0x7200, 0xB2C1, 0xB381, 0x7340, 0xB101, 0x71C0, 0x7080, 0xB041, 	0x5000, 0x90C1, 0x9181, 0x5140, 0x9301, 0x53C0, 0x5280, 0x9241, 	0x9601, 0x56C0, 0x5780, 0x9741, 0x5500, 0x95C1, 0x9481, 0x5440, 	0x9C01, 0x5CC0, 0x5D80, 0x9D41, 0x5F00, 0x9FC1, 0x9E81, 0x5E40, 	0x5A00, 0x9AC1, 0x9B81, 0x5B40, 0x9901, 0x59C0, 0x5880, 0x9841, 	0x8801, 0x48C0, 0x4980, 0x8941, 0x4B00, 0x8BC1, 0x8A81, 0x4A40, 	0x4E00, 0x8EC1, 0x8F81, 0x4F40, 0x8D01, 0x4DC0, 0x4C80, 0x8C41, 	0x4400, 0x84C1, 0x8581, 0x4540, 0x8701, 0x47C0, 0x4680, 0x8641, 	0x8201, 0x42C0, 0x4380, 0x8341, 0x4100, 0x81C1, 0x8081, 0x4040 }; static inline unsigned short crc16_byte(unsigned short crc, const unsigned char data) { 	return (crc >> 8) ^ crc16_table[(crc ^ data) & 0xff]; } unsigned short crc16(unsigned short crc, unsigned char const *buffer, unsigned int len) { 	while (len--) 		crc = crc16_byte(crc, *buffer++); 	return crc; }


Question: 字符处理

sscanf(buf, "%x", &v); 或v = strtol(buf, NULL, 16)

引用 2 楼 andylauxing 的回复:[quote=引用 1 楼 user-2 的回复:] 自己可以想想, 想到了话, 编程能力就能提高一节了.  字符我倒可以拆成2个一组的0F 04 03 EB 00 02,但就是不知道如何把字符0F变成0x0F,也就是字符0F转成16进制形式0x0F[/quote] '0' - '0' = 0, 'F' - 'A' + 10 = 15, 0 * 16 + 15 = 15 = 0x0F 当然还要考虑小写, 甚至无效字符的就稍微麻烦了.

引用 1 楼 user-2 的回复:自己可以想想, 想到了话, 编程能力就能提高一节了.  字符我倒可以拆成2个一组的0F 04 03 EB 00 02,但就是不知道如何把字符0F变成0x0F,也就是字符0F转成16进制形式0x0F

自己可以想想, 想到了话, 编程能力就能提高一节了.


Question: 用指针操作三维数组的问题

引用 1 楼 user-3 的回复:一眼看到两个j++ 惭愧惭愧了

第三个循环应该是想表示k++吧

引用 1 楼 user-3 的回复:一眼看到两个j++  哈哈 ，眼尖！ for (i = 0;i < 3;i++) for (j = 0;j < 5;j++) for (k = 0;k < 7;j++)

一眼看到两个j++


Question: char Hex问题

谢谢楼上 网友。

printf("%02X ",x[i]); 楼主去搜下printf


Question: C语言新手，望大神赐教 [Error] declaration of 'int k' shadow a parameter

引用 2 楼 user-2的回复:不能在函数体的最外层定义和函数参数同名的变量。  int f (int k) {     int k, ... }  你在这里直接定义了一个和函数参数同名的变量 k 您好，我还不是特别明白，如果定义了同名变量会如何呢，不可以定义同名变量的原理是什么呢？

谢谢 ！！！

因为你函数参数已经用了k了，然后你里面又定义了一个

第三行中，显示[Error] declaration of 'int k' shadows a parameter 这是为什么呢？


Question: do while循环体内scanf函数被跳过，循环结束

#include<stdio.h> int main() {     char c;     printf("\n\n***************do while 开始***************\n\n");     do     {         printf("这是一个do while循环！\n");           printf("继续执行请输入y或Y，否则请输入其它\n");           scanf("%c",&c);         getchar();       }     while(c == 'y'||c == 'Y');     return 0; } 加个getchar接收回车

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

参考printf的源代码比如：C:\Program Files\Microsoft Visual Studio 10.0\VC\crt\src\output.c

引用 18 楼 zhao4zhong1 的回复:[quote=引用 16 楼 gblhack 的回复:] [quote=引用 13 楼 zhao4zhong1 的回复:] 在每个最后不带\n的printf后面加fflush(stdout); 在每个不想受接收缓冲区旧内容影响的scanf前面加rewind(stdin); 另外请检查scanf的返回值。 //请今后要用 int c; scanf("%c",&c); //时，都改为 char s[2]; int c; scanf("%1s",s); c=s[0]; 请问赵老师： 在printf后面加fflush(stdout);可以起到什么作用，不加会产生什么后果[/quote] 不加可能被缓冲而不输出。[/quote] 这个不太理解，可以说的稍微具体点吗，或者这些属于哪方面的知识，我去了解一下。

仅供参考：#include <stdio.h> #include <string.h> char s[80]; int i; char c; int main() {     while (1) {         printf("Input a integer:");fflush(stdout);         rewind(stdin);         fgets(s,80,stdin);         if (strlen(s)>10) {             printf("Input too long(>9)!\n");             continue;         }         if (2==sscanf(s,"%d%c",&i,&c)) {             if ('\n'==c) {                 printf("%d is a integer.\n",i);                 break;             }         }         if ('\n'==s[strlen(s)-1]) s[strlen(s)-1]=0;         printf("\"%s\" is NOT a integer!\n",s);     }     return 0; }

引用 16 楼 gblhack 的回复:[quote=引用 13 楼 zhao4zhong1 的回复:] 在每个最后不带\n的printf后面加fflush(stdout); 在每个不想受接收缓冲区旧内容影响的scanf前面加rewind(stdin); 另外请检查scanf的返回值。 //请今后要用 int c; scanf("%c",&c); //时，都改为 char s[2]; int c; scanf("%1s",s); c=s[0]; 请问赵老师： 在printf后面加fflush(stdout);可以起到什么作用，不加会产生什么后果[/quote] 不加可能被缓冲而不输出。

引用 13 楼 zhao4zhong1 的回复:在每个最后不带\n的printf后面加fflush(stdout); 在每个不想受接收缓冲区旧内容影响的scanf前面加rewind(stdin); 另外请检查scanf的返回值。 //请今后要用 int c; scanf("%c",&c); //时，都改为 char s[2]; int c; scanf("%1s",s); c=s[0]; 请问赵老师： 在printf后面加fflush(stdout);可以起到什么作用，不加会产生什么后果

scanf(" %c",&c);

换行符的问题

line = gets() sscanf(line, fmt, args...)

while(c == 'y'||c == 'Y' || c=='\r' || c=='\n);

引用 9 楼 paschen 的回复:[quote=引用 5 楼 qq_26496361 的回复:] rewind（stdin）； fflush（stdin）； 这两个试过了，还是没有解决啊，这个问题是怎么产生的，怎么跟书上写的scanf（）函数的使用方法不一样呢？求大声在指点指点，小弟菜鸟，一头雾水 。  问题我上面不是说了，scanf把回车也接收了，所以你下一次循环得到的值是\n，然后就退出循环了 再不行你这样可好：用getchar把\n接收了  #include<stdio.h> int main() { 	char c; 	printf("\n\n***************do while 开始***************\n\n"); 	do 	{ 		printf("这是一个do while循环！\n");  		printf("继续执行请输入y或Y，否则请输入其它\n");  		scanf("%c",&c); 		getchar();  	} 	while(c == 'y'||c == 'Y'); 	return 0; }[/quote] 这个方法把问题解决了，多谢啊，以后会注意的。

引用 5 楼 qq_26496361 的回复:rewind（stdin）； fflush（stdin）； 这两个试过了，还是没有解决啊，这个问题是怎么产生的，怎么跟书上写的scanf（）函数的使用方法不一样呢？求大声在指点指点，小弟菜鸟，一头雾水 。  问题我上面不是说了，scanf把回车也接收了，所以你下一次循环得到的值是\n，然后就退出循环了 再不行你这样可好：用getchar把\n接收了  #include<stdio.h> int main() { 	char c; 	printf("\n\n***************do while 开始***************\n\n"); 	do 	{ 		printf("这是一个do while循环！\n");  		printf("继续执行请输入y或Y，否则请输入其它\n");  		scanf("%c",&c); 		getchar();  	} 	while(c == 'y'||c == 'Y'); 	return 0; }

不过似乎真的没必要

“ %c" 加上一个空格看行不？ 从前 fortran 格式语句， 要加上1x 用于吃掉走纸控制符

引用 2 楼 paschen 的回复:因为你输入'y'+回车后，他会接收了你的换行符，所以下一次循环取出的就是换行符 怎么会出现这种情况呢，平时写代码，输入字符，也没错啊，怎么和书上写的scanf函数使用方法不一样呢，头好晕。。

#include<stdio.h> int main() { 	char c; 	printf("\n\n***************do while 开始***************\n\n"); 	do 	{ 		printf("这是一个do while循环！\n");  		printf("继续执行请输入y或Y，否则请输入其它\n");  		scanf("%c",&c); 		fflush(stdin);   	} 	while(c == 'y'||c == 'Y'); 	return 0; }

在scanf("%c",&c);上面加上rewind(stdin);


Question: 关于逻辑运算符的简单问题

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

-5非零为真..

-5算真，非0均为真

否，0 =false ,else =true

非零都算真的，我是新手，以前也搞错过， 作为新手难免有这种情况，见多了，也就慢慢进步了

引用 2楼paschen 的回复:-5算真，非0均为真谢谢

引用 3楼github_27756899 的回复:-5非零为真..谢谢

引用 1楼lm_whales 的回复:否，0 =false ,else =true谢谢各位


Question: c语言希尔排序的问题！上交到校题库，冒泡排序未超时，希尔超时了。求大神指教

参看：http://blog.sina.com.cn/s/blog_673ccb5b0100ifyv.html  数据较多时希尔排序肯定比冒泡排序好很好，从复杂度也可以看出


Question: C语言低级问题   函数调用求助

参数类型错误。char 不是 char*


Question: 求帮忙！！！

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

scanf("%d",&a);

{scanf("%d",a);  我看到这里就没有看下去了  a 这边要 a的地址 --> &a  后面你继续调吧

那么明显的错误，地址

这是在你的程序的基础上修改得来的 #include <stdio.h> #define max 100 int main(void) { 	char c; 	int j=0,i=0; 	char a[max]; 	while((c=getchar())!='#'&&(i<max)) 	{ 		if(c=='.'||c=='!') 		{ 			if(c=='.') 				a[i++]='!'; 			if(c=='!') 			{ 				a[i++]='!'; 				a[i++]='!'; 			} 			j++; 		} 		else a[i++]=c; 	} 	a[i]='\0'; 	 		printf("%d\n%s\n",j,a); 	return 0;  }

a的类型是不是应该改为char类型，相应的scanf函数中%d改为%c。那样输入不是方便些，你难道想直接输入对应的ASCⅡ码？


Question: 字符串和字符数组的区别

谢谢大家，我明白了

字符串常量的值是不能修改的。

回楼主"china" 字符串常量是不能修改的   另外 引用 2 楼 user-4 的回复:C 语言中凡是双引号引起来的字符串直接赋值给指针或作为参数，编译器将其视为： const char *p ="china" ，这个通不过;char *p ='c'，这个就可以。 C语言的 "china" 没有const的  所以 char* p = "china" 没什么问题  倒是你后面是char *p ='c' 你是怎么想的 p是char* 'c'是int 可以????

char *p = "china" 中的字符串是分配在了常量区，然后让指针指向他，你修改他的值就出错了 而字符数组则是你在栈上分配的，所以可以修改

具体参看：http://blog.csdn.net/yahohi/article/details/7427724

char *p ; p= "china"


Question: sizeof一个函数,大小为什么是1

引用 10 楼 zhao4zhong1 的回复:http://bbs.chinaunix.net/thread-2021216-1-1.html 懂了, sizeof根据某类型对应的指针类型加1的表现, 决定该类型的大小, 函数指针加1结果比原来就多1, 所以sizeof函数结果为1.

我在VS下是提示错误的，sizeof不能是函数，干嘛要去求函数的长度呢，这就像函数是不能搞一个函数数组

引用 4 楼 ipqtjmqj 的回复:[quote=引用 2 楼 zhao4zhong1 的回复:] 参考gcc或g++中sizeof的实现。 sizeof是运算符不是函数,所以在头文件中应该找不到, gcc是开源的, 不过我不知道在哪找它的源码, 特别是要找到sizeof运算符的源码, 麻烦赵4老师给个链接.[/quote] 学会使用百度和grep

引用 6 楼 ipqtjmqj 的回复:[quote=引用 1 楼 user-3 的回复:] C standard N1570 6.5.3.4 The sizeof and _Alignof operators Constraints 1 The sizeof operator shall not be applied to an expression that has function type or an incomplete type, to the parenthesized name of such a type, or to an expression that designates a bit-field member. 你这有_Alignof应该是c11标准吧, 以前的标准是支持的, 编译也没报错, 请问以前的标准怎么说的.[/quote]  ISO/IEC 9899:1999 (E) ©ISO/IEC 6.5.3.4 The sizeof operator Constraints 1 The sizeof operator shall not be applied to an expression that has function type or an incomplete type, to the parenthesized name of such a type, or to an expression that designates a bit-field member.  C89 (ISO/IEC 9899:1990)我从来没有见过，非常抱歉。  但是从 http://en.cppreference.com/w/c/language/sizeof 的叙述来看，sizeof 的这一要求从 C89 以来没有发生变化。这个网站对在某版标准开始发生变化的内容都有特别的标注。

引用 3 楼 user-3 的回复: $ cat test.c #include <stdio.h> typedef int f(int, ...); int main() {     printf("%d,%d", sizeof(printf), sizeof(f));     return 0; } $ gcc --std=c11 --pedantic-errors test.c test.c: In function ‘main’: test.c:5:27: error: invalid application of ‘sizeof’ to a function type [-Wpointer-arith]      printf("%d,%d", sizeof(printf), sizeof(f));                            ^ test.c:5:44: error: invalid application of ‘sizeof’ to a function type [-Wpointer-arith]      printf("%d,%d", sizeof(printf), sizeof(f));                                             ^ test.c:5:5: warning: format ‘%d’ expects argument of type ‘int’, but argument 2 has type ‘long unsigned int’ [-Wformat=]      printf("%d,%d", sizeof(printf), sizeof(f));      ^ test.c:5:5: warning: format ‘%d’ expects argument of type ‘int’, but argument 3 has type ‘long unsigned int’ [-Wformat=] $ gcc --version gcc (Ubuntu 4.9.2-10ubuntu13) 4.9.2 Copyright (C) 2014 Free Software Foundation, Inc. This is free software; see the source for copying conditions.  There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  你这是c++11吧, 报错了, 用以前的标准不会报错.

引用 1 楼 user-3 的回复:C standard N1570 6.5.3.4 The sizeof and _Alignof operators Constraints 1 The sizeof operator shall not be applied to an expression that has function type or an incomplete type, to the parenthesized name of such a type, or to an expression that designates a bit-field member. 你这有_Alignof应该是c11标准吧, 以前的标准是支持的, 编译也没报错, 请问以前的标准怎么说的.

引用 2 楼 zhao4zhong1 的回复:参考gcc或g++中sizeof的实现。 sizeof是运算符不是函数,所以在头文件中应该找不到, gcc是开源的, 不过我不知道在哪找它的源码, 特别是要找到sizeof运算符的源码, 麻烦赵4老师给个链接.

参考gcc或g++中sizeof的实现。

引用 11 楼 ipqtjmqj 的回复:[quote=引用 10 楼 zhao4zhong1 的回复:] http://bbs.chinaunix.net/thread-2021216-1-1.html 懂了, sizeof根据某类型对应的指针类型加1的表现, 决定该类型的大小, 函数指针加1结果比原来就多1, 所以sizeof函数结果为1.[/quote]  gcc 对指针运算进行了扩展(GNU C)，允许对 函数指针 进行算数运算（比如 p + 1）。为了支持这种算数运算，才支持 sizeof(function) == 1 。  以下引用自：https://gcc.gnu.org/onlinedocs/gcc/Pointer-Arith.html  6 Extensions to the C Language Family 引用6.23 Arithmetic on void- and Function-Pointers  In GNU C, addition and subtraction operations are supported on pointers to void and on pointers to functions. This is done by treating the size of a void or of a function as 1.  A consequence of this is that sizeof is also allowed on void and on function types, and returns 1.  The option -Wpointer-arith requests a warning if these extensions are used.  对 函数指针 进行算数运算，sizeof(function) 在标准里原本都是不允许的。

引用 5 楼 ipqtjmqj 的回复:[quote=引用 3 楼 user-3 的回复:]  $ cat test.c #include <stdio.h> typedef int f(int, ...); int main() {     printf("%d,%d", sizeof(printf), sizeof(f));     return 0; } $ gcc --std=c11 --pedantic-errors test.c test.c: In function ‘main’: test.c:5:27: error: invalid application of ‘sizeof’ to a function type [-Wpointer-arith]      printf("%d,%d", sizeof(printf), sizeof(f));                            ^ test.c:5:44: error: invalid application of ‘sizeof’ to a function type [-Wpointer-arith]      printf("%d,%d", sizeof(printf), sizeof(f));                                             ^ test.c:5:5: warning: format ‘%d’ expects argument of type ‘int’, but argument 2 has type ‘long unsigned int’ [-Wformat=]      printf("%d,%d", sizeof(printf), sizeof(f));      ^ test.c:5:5: warning: format ‘%d’ expects argument of type ‘int’, but argument 3 has type ‘long unsigned int’ [-Wformat=] $ gcc --version gcc (Ubuntu 4.9.2-10ubuntu13) 4.9.2 Copyright (C) 2014 Free Software Foundation, Inc. This is free software; see the source for copying conditions.  There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  你这是c++11吧, 报错了, 用以前的标准不会报错.[/quote]   $ gcc --std=c89 --pedantic-errors test.c test.c: In function ‘main’: test.c:5:27: error: invalid application of ‘sizeof’ to a function type [-Wpointer-arith]      printf("%d,%d", sizeof(printf), sizeof(f));                            ^ test.c:5:44: error: invalid application of ‘sizeof’ to a function type [-Wpointer-arith]      printf("%d,%d", sizeof(printf), sizeof(f));                                             ^ test.c:5:5: warning: format ‘%d’ expects argument of type ‘int’, but argument 2 has type ‘long unsigned int’ [-Wformat=]      printf("%d,%d", sizeof(printf), sizeof(f));      ^ test.c:5:5: warning: format ‘%d’ expects argument of type ‘int’, but argument 3 has type ‘long unsigned int’ [-Wformat=]


Question: 关于字符串的问题

多谢各位的解答

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

不错，学习了

char *str1 ="Hello"; 让声明一个char*指针，指向常量区的常量字符数组，所以你不能去修改 而char[]则在在栈上分配的字符数组，可以修改  请参看：http://blog.csdn.net/yahohi/article/details/7427724

code1   :  使用的是字符指针，但你没有申请空间，仅指向常量区，而常量区不可写。

code1，使用的是字符指针，str1和str2指向数据段的某个位置，期内容时"Hello\0"和"China\0"，'\0'，表示字符串的结尾。 str1指向的位置，也就是5个字符的大小，而要将str2追加上，str1指向的内存没有足够的空间容纳str2，所以在strcat中报错。  code2，使用的是，字符数组，因为字符数组比较短，所以存放在程序运行时的堆栈中，堆栈由于对齐的关系，往往会分配多余空间，所以还能容纳str2的，故不会报错。


Question: 链表实现多项式相乘，两个多项式分别有M项和N项，求时间复杂度为O（M的平方乘以N）。

引用 5 楼 zhao4zhong1 的回复:我还真没本事解这个惑。  既然是已出版书籍中的练习题，多半在百度上可以搜到练习题的正宗答案的。Thank you all the same.

引用 3 楼 zhao4zhong1 的回复:引用 2 楼 leonardohq 的回复:[quote=引用 1 楼 zhao4zhong1 的回复:] http://blog.csdn.net/lanseshenhua/article/details/5451798这个解法的时间复杂度为O（M²N²），我想要的是O（M²N）的解法。 个人意见：平均每天使用次数少于10次，每次使用时间不超过一分钟的算法都不需要考虑什么劳什子复杂度。[/quote]您说的很对，我并不是要拘泥于时间复杂度，这是《数据结构与算法分析》一书中的一道练习题，要求给出O（M²N²），O（M²N），O（MN）三种时间复杂度的算法，我想不出O（M²N）的解法，所以特来请教以解惑。

引用 2 楼 leonardohq 的回复:引用 1 楼 zhao4zhong1 的回复:http://blog.csdn.net/lanseshenhua/article/details/5451798这个解法的时间复杂度为O（M²N²），我想要的是O（M²N）的解法。 个人意见：平均每天使用次数少于10次，每次使用时间不超过一分钟的算法都不需要考虑什么劳什子复杂度。


Question: C语言指针数组维度问题！

引用 8 楼 libinden71 的回复:[quote=引用 7 楼 paschen 的回复:] [quote=引用 6 楼 libinden71 的回复:] [quote=引用 5 楼 paschen 的回复:] 因为一级数组会退化成指针，所以总共是一个二级指针，函数参数中的数组均会退化为指针，所以你的int *gars[]在这里就和int** gars等价   我对数组的退化不是很了解，能解释下给我听吗？ 谢谢啊！[/quote]   退货后他就只是一个指针，指向数组首元素，退化前用sizeof运算符是可以得到数组的长度，退化成指针后得到的将是指针的长度（32位下为4）  具体可以参看《C++必知必会》条款6  这个我知道！我不懂的是 为什么是一个二级的指针！,int *gars[]  不是一个一级指针吗？ [/quote]  int[]退化成int* int*[]退化成int**

明白了 ！感谢大神！

引用 7 楼 paschen 的回复:[quote=引用 6 楼 libinden71 的回复:] [quote=引用 5 楼 paschen 的回复:] 因为一级数组会退化成指针，所以总共是一个二级指针，函数参数中的数组均会退化为指针，所以你的int *gars[]在这里就和int** gars等价   我对数组的退化不是很了解，能解释下给我听吗？ 谢谢啊！[/quote]   退货后他就只是一个指针，指向数组首元素，退化前用sizeof运算符是可以得到数组的长度，退化成指针后得到的将是指针的长度（32位下为4）  具体可以参看《C++必知必会》条款6  这个我知道！我不懂的是 为什么是一个二级的指针！,int *gars[]  不是一个一级指针吗？

引用 6 楼 libinden71 的回复:[quote=引用 5 楼 paschen 的回复:] 因为一级数组会退化成指针，所以总共是一个二级指针，函数参数中的数组均会退化为指针，所以你的int *gars[]在这里就和int** gars等价   我对数组的退化不是很了解，能解释下给我听吗？ 谢谢啊！[/quote]   退货后他就只是一个指针，指向数组首元素，退化前用sizeof运算符是可以得到数组的长度，退化成指针后得到的将是指针的长度（32位下为4）  具体可以参看《C++必知必会》条款6

引用 5 楼 paschen 的回复:因为一级数组会退化成指针，所以总共是一个二级指针，函数参数中的数组均会退化为指针，所以你的int *gars[]在这里就和int** gars等价   我对数组的退化不是很了解，能解释下给我听吗？ 谢谢啊！

任何传进函数的指针，数组（实参）参数，都是指针（形参），即变量的地址 其实它就是char **argv。

gars 是指针数组，不是二维数组 数组中每个元素都是指向 char 型的指针，或者说指向字符串的指针 在windows中，你的程序，如果可执行文件名字是 asd.exe 在命令窗口中输入 asd 12 + 34 gars[0] 指向 "asd.exe" gars[1] 指向 "12" gars[2] 指向 "+" gars[3] 指向 "34" 它们都是 char* 型的 指针都可以后加[ ]，如 p[1] 就是 *(p+1)，p[0] 就是 *p，gars[2][0]就是 *(gars[2])

应该是 int main(int argc, char * argv[])  吧？ 或者 int main(int argc, char ** argv)    int main(int argc, char *argv[]) {          printf("arg = %s, %s \n", argv[1], argv[2]);      return 0; } test@/samba/test$ ./a.out  Hello World  arg = Hello,World

大晚上 脑子太累 printf("程序错误，被除数不能为0！\n"); 这条写错了，别在意！


Question: C语言数组如何赋值给字符串

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

#include <stdio.h>  int main() { 	int str[5] = {1,2,3,4,5};       char str1[6]; 	int i = 0; 	for(i=0;i<5;i++) 	{ 		str1[i] = str[i] + '0'; 	} 	str1[i] = '\0';  	printf("%s\n",str1);  	return 0; }

int main(int argc, char *argv[]) {     char *str = "12345";     printf("str = %s \n", str); } str = 12345   int main(int argc, char *argv[]) {     char str[] = "12345";     printf("str = %s \n", str); } str = 12345

你的str1是一个字符，不是字符串，我可以理解为是单字节整数，你倒底是要一个整数，还是要一个字符串，请先表述清楚。


Question: C语言链表新建问题求助。

再供参考：//将c:\\tmp文件夹下的所有文件的内容全部放到用malloc分配的内存中 #include <stdio.h> #include <stdlib.h> #include <string.h> #include <io.h> struct FB {     char fn[256];     size_t fl;     char *b;     struct FB *next;     struct FB *prev; } *fh,*fb,*ft; char ln[256]; char fpn[256]; FILE *af; FILE *f; int L,n; int main() {     system("dir /b /a-d c:\\tmp\\*.* >c:\\allfn.txt");     af=fopen("c:\\allfn.txt","r");     if (NULL==af) {         printf("Can not open file c:\\allfn.txt!\n");         return 1;     }     fh=NULL;     fb=NULL;     n=0;     while (1) {         if (NULL==fgets(ln,256,af)) break;         L=strlen(ln);         if ('\n'==ln[L-1]) ln[L-1]=0;         printf("read %s\n",ln);         strcpy(fpn,"c:\\tmp\\");         strcat(fpn,ln);         ft=(struct FB *)malloc(sizeof(struct FB));         if (NULL==ft) {             printf("Can not malloc ft!\n");             fclose(af);             return 2;//之前的malloc在main退出后由操作系统自动free         }         printf("ft[%d]==%p\n",n,ft);         strcpy(ft->fn,fpn);         f=fopen(fpn,"rb");         if (NULL==f) {             printf("Can not open file %s!\n",fpn);             fclose(af);             return 3;//之前的malloc在main退出后由操作系统自动free         }         ft->fl=_filelength(fileno(f));         ft->b=malloc(ft->fl);         if (NULL==ft->b) {             printf("Can not malloc ft->b!\n");             fclose(f);             fclose(af);             return 4;//之前的malloc在main退出后由操作系统自动free         }         printf("ft[%d]->b==%p\n",n,ft->b);         if (ft->fl!=fread(ft->b,1,ft->fl,f)) {             printf("fread error!\n");             fclose(f);             fclose(af);             return 5;//之前的malloc在main退出后由操作系统自动free         }         fclose(f);         ft->next=NULL;          if (NULL==fh) {             ft->prev=NULL;             fh=ft;         } else {             fb->next=ft;             ft->prev=fb;         }         fb=ft;         n++;     }     fclose(af);     printf("-----list-----\n");     for (ft=fh;NULL!=ft;ft=ft->next) {         printf("%8d %s\n",ft->fl,ft->fn);         if (NULL!=ft) fb=ft;     }     printf("-----free-----\n");     n--;     if (NULL!=fh) {         for (ft=fb->prev;NULL!=ft;ft=ft->prev) {             if (NULL!=ft->next->b) {                 printf("ft[%d]->b==%p\n",n,ft->next->b);                 free(ft->next->b);             }             if (NULL!=ft->next) {                 printf("ft[%d]==%p\n",n,ft->next);                 free(ft->next);             }             n--;         }         if (NULL!=fh->b) {             printf("ft[0]->b==%p\n",fh->b);             free(fh->b);         }         printf("ft[0]==%p\n",fh);         free(fh);     }     return 0; } //C:\tmp\tmp\Debug>dir /a-d c:\tmp // 驱动器 C 中的卷是 C_HD5_1 // 卷的序列号是 1817-D526 // // c:\tmp 的目录 // //找不到文件 // //C:\tmp\tmp\Debug>tmp //找不到文件 //-----list----- //-----free----- // //C:\tmp\tmp\Debug>dir /a-d c:\tmp // 驱动器 C 中的卷是 C_HD5_1 // 卷的序列号是 1817-D526 // // c:\tmp 的目录 // //2011-06-30  18:04            44,840 my_c.rar //2011-06-30  17:18             1,036 err.frm //2011-06-30  14:32            14,243 出租.txt //2011-06-28  12:08            23,681 MSDN98书签.txt //             4 个文件         83,800 字节 //             0 个目录 17,041,870,848 可用字节 // //C:\tmp\tmp\Debug>tmp //read my_c.rar //ft[0]==00421800 //ft[0]->b==00520068 //read err.frm //ft[1]==00421670 //ft[1]->b==0052AFC0 //read 出租.txt //ft[2]==00421530 //ft[2]->b==00378F28 //read MSDN98书签.txt //ft[3]==004213F0 //ft[3]->b==0052B3F8 //-----list----- // 44840 c:\tmp\my_c.rar //  1036 c:\tmp\err.frm // 14243 c:\tmp\出租.txt // 23681 c:\tmp\MSDN98书签.txt //-----free----- //ft[3]->b==0052B3F8 //ft[3]==004213F0 //ft[2]->b==00378F28 //ft[2]==00421530 //ft[1]->b==0052AFC0 //ft[1]==00421670 //ft[0]->b==00520068 //ft[0]==00421800 // //C:\tmp\tmp\Debug>

仅供参考：//不带表头结点的单向链表 #include <stdio.h> #include <stdlib.h> #include <malloc.h> #include <time.h> #include <locale.h> struct NODE {     int          data;     struct NODE *next; } *head,*p,*q,*s,*p1,*p2,*q1,**ta; int i,k,n,t,m,v,N=10; int main() {     setlocale(LC_ALL,"chs");     srand(time(NULL));      head=NULL;      printf("创建%d个节点的单链表:",N);//创建N个节点的单链表     p=head;     for (i=0;i<N;i++) {         q=(struct NODE *)malloc(sizeof(struct NODE));         if (NULL==q) exit(1);         q->data=rand()%100;//填写0..99的随机值         q->next=NULL;         if (NULL==p) {             head=q;             p=head;         } else {             p->next=q;             p=q;         }     }      //输出整个单链表     s=head;     while (1) {         if (NULL==s) {             printf("\n");             break;         }         printf("%02d->",s->data);         s=s->next;     }      k=3;     v=5;     printf("将值为%d的结点插入到单链表的第%d个结点前:",v,k);//将值为v的结点插入到单链表的第k个结点前     n=0;     p=head;     while (1) {         if (NULL==p) {             break;         }         n++;         if (k==1) {             q=(struct NODE *)malloc(sizeof(struct NODE));             if (NULL==q) exit(1);             q->data=5;             q->next=head;             head=q;             break;         } else {             if (k-1==n) {                 q=(struct NODE *)malloc(sizeof(struct NODE));                 if (NULL==q) exit(1);                 q->data=5;                 q->next=p->next;                 p->next=q;                 break;             }         }         p=p->next;     }      //输出整个单链表     s=head;     while (1) {         if (NULL==s) {             printf("\n");             break;         }         printf("%02d->",s->data);         s=s->next;     }      k=5;     printf("删除第%d个节点:",k);//删除第k个节点     n=0;     p=head;     while (1) {         if (NULL==p) {             break;         }         n++;         if (k==1) {             q=head;             head=head->next;             free(q);             break;         } else {             if (k-1==n) {                 q=p->next;                 if (q) {                     p->next=q->next;                     free(q);                 }                 break;             }         }         p=p->next;     }      //输出整个单链表     s=head;     while (1) {         if (NULL==s) {             printf("\n");             break;         }         printf("%02d->",s->data);         s=s->next;     }      printf("从小到大排序:");//从小到大排序     for (p=head,p1=NULL;p!=NULL;p1=p,p=p->next) {         for (q=p->next,q1=p;q!=NULL;q1=q,q=q->next) {             if (p->data > q->data) {                  //交换data //              printf("swap %02d %02d\n",p->data,q->data); //              t=p->data;p->data=q->data;q->data=t;                  //或者                  //交换next //              printf("swap %02d %02d\n",p->data,q->data);                 if (p==head) {//p是头                     if (p->next==q) {//pq挨着                         head=q;                         p->next=q->next;                         q->next=p;                         q=p;                         p=head;                     } else {//pq不挨着                         head=q;                         p2=p->next;                         p->next=q->next;                         q->next=p2;                         q1->next=p;                         q=p;                         p=head;                     }                 } else {//p不是头                     if (p->next==q) {//pq挨着                         p1->next=q;                         p->next=q->next;                         q->next=p;                         q=p;                         p=p1->next;                     } else {//pq不挨着                         p1->next=q;                         p2=p->next;                         p->next=q->next;                         q->next=p2;                         q1->next=p;                         q=p;                         p=p1->next;                     }                 }                  //输出整个单链表 //              s=head; //              while (1) { //                  if (NULL==s) { //                      printf("\n"); //                      break; //                  } //                  printf("%02d->",s->data); //                  s=s->next; //              } //              getchar();             }         }     }      //输出整个单链表并计算链表长度n     n=0;     s=head;     while (1) {         if (NULL==s) {             printf("\n");             break;         }         printf("%02d->",s->data);         n++;         s=s->next;     }      printf("将整个链表逆序:");//将整个链表逆序     if (n>=2) {         p=head;         q=p->next;         p->next=NULL;         while (1) {             q1=q->next;             q->next=p;             p=q;             q=q1;             if (NULL==q) break;         }         head=p;     }      //输出整个单链表     s=head;     while (1) {         if (NULL==s) {             printf("\n");             break;         }         printf("%02d->",s->data);         s=s->next;     }      m=4;     n=6;     printf("将单链表中前%d个结点和后%d个结点进行互换:",m,n);//将单链表中前m个结点和后n个结点进行互换,m+n为链表总长     k=0;     p=head;     while (1) {         if (NULL==p) {             break;         }         k++;         if (m==k) {             q=p;         }         s=p;         p=p->next;     }     q1=head;     head=q->next;     s->next=q1;     q->next=NULL;      //输出整个单链表     s=head;     while (1) {         if (NULL==s) {             printf("\n");             break;         }         printf("%02d->",s->data);         s=s->next;     }      //释放所有节点     p=head;     while (1) {         if (NULL==p) {             break;         }         q=p->next;         free(p);         p=q;     }      return 0; } //创建10个节点的单链表:08->74->07->23->03->99->31->56->88->16-> //将值为5的结点插入到单链表的第3个结点前:08->74->05->07->23->03->99->31->56->88->16-> //删除第5个节点:08->74->05->07->03->99->31->56->88->16-> //从小到大排序:03->05->07->08->16->31->56->74->88->99-> //将整个链表逆序:99->88->74->56->31->16->08->07->05->03-> //将单链表中前4个结点和后6个结点进行互换:31->16->08->07->05->03->99->88->74->56-> //

楼上代码给的很全面啊，你没有贴具体代码，也不知道你问题出在哪里？ 总之，记得给结点开辟空间。

请牢记：源代码本身的书写是否结构化或面向对象或符合设计模式或敏捷…并不重要，重要的是你是否使用结构化或面向对象或符合设计模式或敏捷…的方法命名标识符、阅读、修改、检查、测试源代码。  意思是你程序结构看上去再合理，再简洁，也不一定比看上去一团乱麻的程序结构在运行或修改时更不易出错，更方便修改，出错了更容易找到哪里出错和具体出错的原因，更容易改正错误。  试对比 图书馆（对图书的分类够结构化了吧） 和 搜索引擎（可看作是扁平化任何结构数据，仅支持全文检索） 哪个处理信息更方便、更高效。  所以 与其费劲去重构代码让其看上去更简洁、更合理 不如费劲学习grep、sed、awk、……这类全文搜索和批处理编辑的工具。  结构越复杂，越难修改，越难除错。 有时（甚至大多数时候），看上去越合理、越简洁的代码，运行起来性能越差，出错时查找原因越难，找到出错原因后改正越费劲。  程序员要做的不是尽力避免错误，而是聚焦在快速发现并改正错误。真正以快速方式轻易解决错误，“快速的失败”远胜过“预防错误”。Fred George

单链表的实现是很简单的，随便都能搜到一堆代码，稍微用点心研究下都能搞定了。  先把单链表的核心功能实现，再写个文件字符串处理函数就行了。strtok 之后 InsertNode而已。  要注意代码风格写好一点，不然debug时会疯掉的。楼上贴的代码就是个反面例子。


Question: 内存泄露问题  怎么修改，求具体指导下


Question: ascii编码表是否在链接的时候也链接到执行程序中了？

引用 3 楼 fiveyes 的回复:操作系统中有字体库，每一个字母或汉字，即使像I这么简单的一个大写字母，它的字形也不是一个字节能够保存的。  因此ascii码表中保存的只是一个编号，操作系统首先要根据这个编号找到对应的字符，然后再从字体库中取出真正的字形，把它输出到显示器或其它设备。 所以说操作系统中有一个基础信息表，操作系统根据ASCII表找到相应的字符形状后，将其输出；

你在电脑上用的任何资源：图片、声音、字符等等在内存里都是二进制数据，至于他表示什么，要看你怎么去解释这些数据

不是。  把 0x41 显示为 'A' 是由 OS 或者 shell 等其他程序完成的。


Question: 字符串传给this对象指针，在怎么获取到？

引用 楼主 chinabhlt 的回复:#include <iostream> #include <cstdio> #include <cstdlib> using namespace std;  class Test { public:     Test(); 	Test(string val);     virtual ~Test();     operator string() const; 	string GetString(); }; Test::Test(){} Test::Test(string val){*this = val;} Test::~Test(){} string Test::GetString() { 	return static_cast<string>(*this); } Test::operator string() const { 	return (string)(*this); } int main(int argc, char *argv[]) { 	string haha = "haha";     Test t(haha); 	string tt = ""; 	tt = t.GetString(); 	cout << tt << endl;     return 0; }  这段程序总是报段错误，求正确的获取字符串方式？  忽略了一个细节： =运算符重载 正确的的写法： #include <iostream> #include <cstdio> #include <cstdlib> using namespace std;  class Test { public:     Test(); 	Test(string val);     virtual ~Test(); 	string GetString(); 	Test& operator=(string val); 	string m_val; }; Test::Test(){} Test::Test(string val){*this = val;} Test::~Test(){} Test& Test::operator=(string val) { 	m_val = val; } string Test::GetString() { 	return m_val; }  int main(int argc, char *argv[]) { 	string haha("haha");     Test t(haha);  	cout << t.GetString() << endl; 	     return 0; }

Test::Test(string val){*this = val;}  *this = val 需要先把 val 转换为 Test 类型，于是会递归调用 Test::Test(string) 。这是一个无穷递归。  你的 operator string 也是一个无穷递归。

先学走，再学跑，this指针还不适合你...  private:      string m_str;  Test::Test(string val){m_str = val;}  string Test::GetString() { return m_str; }  以上.  P.S 没有用引用，指针，主旨在于简单易懂，请不要纠结于这些细节


Question: 网卡如何保证多线程收发无误？

《WIndows核心编程》

引用 3 楼 sand6174 的回复:单线程的，没有多线程的！你可以这样理解，网卡收到数据后会产生一个中断，存在系统内核buf中，然后根据TCP/IP以太网头等，注入某个线程中。你看到并行是假的。  你说的是接收数据的情况。那么，发送数据的情况呢？A线程也要发送数据，B线程也要发送数据。两个线程同时向网卡写入数据。那么网卡如何保证两个线程的数据相互独立？ 假设没有相应的处理机制的话，A写入网卡部分数据，CPU被B抢了，B又写了部分数据，然后A又来了，然后B又来了。这样子，数据会不会错乱？

封包解包有标识，进程线程有标识。 到了进程线程这个层面就是操作系统的事了。你自己看操作系统方面的书。

网卡的处理永远是单线程的，你的程序是多线程的，所以网卡的数据是不会错乱的。而程序肯定是单个连接一个线程，不可能一个连接分出两个线程，除非你自找麻烦。根据连接，数据永远不会跑其他线程去。


Question: 磁盘的读写速度如何检测

看到了进程的枚举，还没看到关于磁盘速度检测相关的东西，多谢提供思路。

在MSDN里面搜“PDH”


Question: 这个运行结果总是不对，函数这块实在不会。求大神。

下断点，然后单步调试。调试是解决问题的一种好方式

printf("%f\n",s(x,n));

#include<stdio.h> #include<math.h> double s(double x, double n); int main() {   	int x,n; 	scanf("%d,%d",&x,&n); 	printf("%f",s(x,n)); 	return 0; }  double s(double x, double n) {    	int i;  float sum=0.0; 	for(i=1;i<=n;i++) 		sum = sum + pow(x,i); 	return sum; }  楼主，我简单改了下，输出正常了，pow函数的第二个入参要double型，另外打印输出不能是整形。

编译器不会警告吗, 还是说无视了.  1. 换个编译器 2. 查看警告信息


Question: C语言switch语句不执行

引用 7 楼 qq_32202481 的回复:[quote=引用 6 楼 qq_28409599 的回复:] 很典型的错误，do3里面的getchar把空格吸收了，换成scanf("  %c",&c);注意%c前面有一个空格,吸收你输入数字后打的回车，也就是\n  如何解决[/quote] int menu()  {      int  cn;     printf("请输入指令:");     scanf("%d",&cn);     getchar();   //把空格吸收了     return cn; }

引用 6 楼 qq_28409599 的回复:很典型的错误，do3里面的getchar把空格吸收了，换成scanf("  %c",&c);注意%c前面有一个空格,吸收你输入数字后打的回车，也就是\n  如何解决

do2函数里面,这句a%4==0&&a%100!=0||a%100==0应该是判断闰年, 最后应该是|| a % 400 == 0

因为你在前面menu()函数里面输入3的时候，在缓存里会留下一个回车符'\n'，到do3()的时候，c=getchar()读入的是回车符

兄弟 我的锅 是do3 不执行

#include<stdio.h> void do1() { 	int n,i,m; 	int a[10]={0}; 	printf("请输入要判断的数:"); 	scanf("%d",&n); 	m=n; 	for(i=0;;i++) 	{ 		a[i]=m%10; 		m/=10; 		if(m==0) 			break; 	} 	for(i=0;a[i]!=0;i++) 	{ 		m+=a[i]*a[i]*a[i]; 	} 	if(n==m) 		printf("%d是水仙花数\n",n); 	else 		printf("%d不是水仙花数\n",n); }  void do2() { 	int a,b,t,i=0; 	printf("请输入年份"); 	scanf("%d%d",&a,&b); 	if(a>b) 	{ 		t=a; 		a=b; 		b=t; 	} 	while(a<=b) 	{ 		if(a%4==0&&a%100!=0||a%100==0) 			i=i+1; 		a=a+1; 	} 	printf("%d",i); }  int do3()  { 	char c; 	printf("沉梦昂志");  	c=getchar(); 	{ 		if ((c>='a'&&c<='z')||(c>='A'&&c<='Z')) 		{ 			if ((c>='W'&&c<='Z')||(c>='w'&&c<='z'))c=c-22; 				else c=c+4; 		} 		printf("%c",c); 		c=getchar(); 	} 	printf("\n"); 	return 0; }  int menu()  {  	int  cn; 	printf("请输入指令:"); 	scanf("%d",&cn); 	return cn; }  int main()  {  	for(; ;) 	{  		switch(menu()) 		{  		case 1:  			do1(); break;  		case 2:  			do2(); break;  		case 3:  			do3();break; 		}  	}  }  楼主代码中do2()函数中scanf("%d%d",a,b);有语法错误，应该是scanf("%d%d",&a,&b);


Question: 学习日记一：环形队列

队列 http://blog.csdn.net/zhangxiangdavaid/article/details/29195859

将复杂数据结构的整个内容在处理它的每一步使用一小段代码按自己很容易理解的格式输出，非常有助于调试！或者可以说是“基础设施”：//不带表头结点的单向链表 #include <stdio.h> #include <stdlib.h> #include <malloc.h> #include <time.h> #include <locale.h> struct NODE {     int          data;     struct NODE *next; } *head,*p,*q,*s,*p1,*p2,*q1,**ta; int i,k,n,t,m,v,N=10; int main() {     setlocale(LC_ALL,"chs");     srand(time(NULL));      head=NULL;      printf("创建%d个节点的单链表:",N);//创建N个节点的单链表     p=head;     for (i=0;i<N;i++) {         q=(struct NODE *)malloc(sizeof(struct NODE));         if (NULL==q) exit(1);         q->data=rand()%100;//填写0..99的随机值         q->next=NULL;         if (NULL==p) {             head=q;             p=head;         } else {             p->next=q;             p=q;         }     }      //输出整个单链表     s=head;     while (1) {         if (NULL==s) {             printf("\n");             break;         }         printf("%02d->",s->data);         s=s->next;     }      k=3;     v=5;     printf("将值为%d的结点插入到单链表的第%d个结点前:",v,k);//将值为v的结点插入到单链表的第k个结点前     n=0;     p=head;     while (1) {         if (NULL==p) {             break;         }         n++;         if (k==1) {             q=(struct NODE *)malloc(sizeof(struct NODE));             if (NULL==q) exit(1);             q->data=5;             q->next=head;             head=q;             break;         } else {             if (k-1==n) {                 q=(struct NODE *)malloc(sizeof(struct NODE));                 if (NULL==q) exit(1);                 q->data=5;                 q->next=p->next;                 p->next=q;                 break;             }         }         p=p->next;     }      //输出整个单链表     s=head;     while (1) {         if (NULL==s) {             printf("\n");             break;         }         printf("%02d->",s->data);         s=s->next;     }      k=5;     printf("删除第%d个节点:",k);//删除第k个节点     n=0;     p=head;     while (1) {         if (NULL==p) {             break;         }         n++;         if (k==1) {             q=head;             head=head->next;             free(q);             break;         } else {             if (k-1==n) {                 q=p->next;                 if (q) {                     p->next=q->next;                     free(q);                 }                 break;             }         }         p=p->next;     }      //输出整个单链表     s=head;     while (1) {         if (NULL==s) {             printf("\n");             break;         }         printf("%02d->",s->data);         s=s->next;     }      printf("从小到大排序:");//从小到大排序     for (p=head,p1=NULL;p!=NULL;p1=p,p=p->next) {         for (q=p->next,q1=p;q!=NULL;q1=q,q=q->next) {             if (p->data > q->data) {                  //交换data //              printf("swap %02d %02d\n",p->data,q->data); //              t=p->data;p->data=q->data;q->data=t;                  //或者                  //交换next //              printf("swap %02d %02d\n",p->data,q->data);                 if (p==head) {//p是头                     if (p->next==q) {//pq挨着                         head=q;                         p->next=q->next;                         q->next=p;                         q=p;                         p=head;                     } else {//pq不挨着                         head=q;                         p2=p->next;                         p->next=q->next;                         q->next=p2;                         q1->next=p;                         q=p;                         p=head;                     }                 } else {//p不是头                     if (p->next==q) {//pq挨着                         p1->next=q;                         p->next=q->next;                         q->next=p;                         q=p;                         p=p1->next;                     } else {//pq不挨着                         p1->next=q;                         p2=p->next;                         p->next=q->next;                         q->next=p2;                         q1->next=p;                         q=p;                         p=p1->next;                     }                 }                  //输出整个单链表 //              s=head; //              while (1) { //                  if (NULL==s) { //                      printf("\n"); //                      break; //                  } //                  printf("%02d->",s->data); //                  s=s->next; //              } //              getchar();             }         }     }      //输出整个单链表并计算链表长度n     n=0;     s=head;     while (1) {         if (NULL==s) {             printf("\n");             break;         }         printf("%02d->",s->data);         n++;         s=s->next;     }      printf("将整个链表逆序:");//将整个链表逆序     if (n>=2) {         p=head;         q=p->next;         p->next=NULL;         while (1) {             q1=q->next;             q->next=p;             p=q;             q=q1;             if (NULL==q) break;         }         head=p;     }      //输出整个单链表     s=head;     while (1) {         if (NULL==s) {             printf("\n");             break;         }         printf("%02d->",s->data);         s=s->next;     }      m=4;     n=6;     printf("将单链表中前%d个结点和后%d个结点进行互换:",m,n);//将单链表中前m个结点和后n个结点进行互换,m+n为链表总长     k=0;     p=head;     while (1) {         if (NULL==p) {             break;         }         k++;         if (m==k) {             q=p;         }         s=p;         p=p->next;     }     q1=head;     head=q->next;     s->next=q1;     q->next=NULL;      //输出整个单链表     s=head;     while (1) {         if (NULL==s) {             printf("\n");             break;         }         printf("%02d->",s->data);         s=s->next;     }      //释放所有节点     p=head;     while (1) {         if (NULL==p) {             break;         }         q=p->next;         free(p);         p=q;     }      return 0; } //创建10个节点的单链表:08->74->07->23->03->99->31->56->88->16-> //将值为5的结点插入到单链表的第3个结点前:08->74->05->07->23->03->99->31->56->88->16-> //删除第5个节点:08->74->05->07->03->99->31->56->88->16-> //从小到大排序:03->05->07->08->16->31->56->74->88->99-> //将整个链表逆序:99->88->74->56->31->16->08->07->05->03-> //将单链表中前4个结点和后6个结点进行互换:31->16->08->07->05->03->99->88->74->56-> //

没有分了，跪求给点分啊


Question: "强符号"和"弱符号"是C语言标准的一部分吗,还是编译器的概念?

没有，那是链接器里面的概念


Question: 文件加密

st1[strlen(st1)]='\n'; 这句有问题吧, 字符串以0结尾,搞个回车做什么

引用 7 楼 fefe82 的回复:[quote=引用 6 楼 zzl_zZ 的回复:] [quote=引用 5 楼 fefe82 的回复:] [quote=引用 3 楼 zzl_zZ 的回复:] [quote=引用 1 楼 user-3 的回复:]  1）  FILE *f1=fopen("d://a.txt","w"); fputs(st1,f1); rewind(f1); 文件没关闭，也没 flush 文件大小不确定。只怕是 0 ，  2）while(feof(f1)){S;}  文件结束执行循环，而且是一直在循环， 要不执行循环体，要么死循环。 #include<stdio.h> #include<stdlib.h> #include<string.h> #define SIZE 1024 int main(void) {     FILE *f1=fopen("d://a.txt","w");     char st1[SIZE]={0};     while(gets(st1)!=NULL&&st1[0]!='\0')     {         if(strcmp(st1,"exit")==0)             break;         st1[strlen(st1)-1]='\n';         fputs(st1,f1);         memset(st1,0,sizeof(st1));      }     fclose(f1);          FILE *f2=fopen("d://a.txt","r");     rewind(f2);          while(!feof(f2))     {     	     }          fclose(f2);     return 0; } 我这样也不行，输入exit没反应了，可是把第二个while(!feof(f2))删了就好了， 这是什么原因啊。。。。[/quote]  第二个while(!feof(f2)) : 这不是个死循环嘛 ...[/quote]  怎么死循环了。。。。求解释啊[/quote]  你想一下什么时候循环会推出就好了。  =============  循环体里没有操作，你循环多少次 feof(f2) 的返回值都不会发生变化的。[/quote]  谢谢

引用 6 楼 zzl_zZ 的回复:[quote=引用 5 楼 fefe82 的回复:] [quote=引用 3 楼 zzl_zZ 的回复:] [quote=引用 1 楼 user-3 的回复:]  1）  FILE *f1=fopen("d://a.txt","w"); fputs(st1,f1); rewind(f1); 文件没关闭，也没 flush 文件大小不确定。只怕是 0 ，  2）while(feof(f1)){S;}  文件结束执行循环，而且是一直在循环， 要不执行循环体，要么死循环。 #include<stdio.h> #include<stdlib.h> #include<string.h> #define SIZE 1024 int main(void) {     FILE *f1=fopen("d://a.txt","w");     char st1[SIZE]={0};     while(gets(st1)!=NULL&&st1[0]!='\0')     {         if(strcmp(st1,"exit")==0)             break;         st1[strlen(st1)-1]='\n';         fputs(st1,f1);         memset(st1,0,sizeof(st1));      }     fclose(f1);          FILE *f2=fopen("d://a.txt","r");     rewind(f2);          while(!feof(f2))     {     	     }          fclose(f2);     return 0; } 我这样也不行，输入exit没反应了，可是把第二个while(!feof(f2))删了就好了， 这是什么原因啊。。。。[/quote]  第二个while(!feof(f2)) : 这不是个死循环嘛 ...[/quote]  怎么死循环了。。。。求解释啊[/quote]  你想一下什么时候循环会推出就好了。  =============  循环体里没有操作，你循环多少次 feof(f2) 的返回值都不会发生变化的。

引用 5 楼 fefe82 的回复:[quote=引用 3 楼 zzl_zZ 的回复:] [quote=引用 1 楼 user-3 的回复:]  1）  FILE *f1=fopen("d://a.txt","w"); fputs(st1,f1); rewind(f1); 文件没关闭，也没 flush 文件大小不确定。只怕是 0 ，  2）while(feof(f1)){S;}  文件结束执行循环，而且是一直在循环， 要不执行循环体，要么死循环。 #include<stdio.h> #include<stdlib.h> #include<string.h> #define SIZE 1024 int main(void) {     FILE *f1=fopen("d://a.txt","w");     char st1[SIZE]={0};     while(gets(st1)!=NULL&&st1[0]!='\0')     {         if(strcmp(st1,"exit")==0)             break;         st1[strlen(st1)-1]='\n';         fputs(st1,f1);         memset(st1,0,sizeof(st1));      }     fclose(f1);          FILE *f2=fopen("d://a.txt","r");     rewind(f2);          while(!feof(f2))     {     	     }          fclose(f2);     return 0; } 我这样也不行，输入exit没反应了，可是把第二个while(!feof(f2))删了就好了， 这是什么原因啊。。。。[/quote]  第二个while(!feof(f2)) : 这不是个死循环嘛 ...[/quote]  怎么死循环了。。。。求解释啊

引用 楼主 zzl_zZ 的回复:#include<stdio.h> #include<stdlib.h> #include<string.h> #define SIZE 1024 void code(char *s) {     while(*s)     {         (*s)++;         s++;     } } int main(void) {     FILE *f1=fopen("d://a.txt","w");     FILE *f2=fopen("c://b.txt","w");     char st1[SIZE];     char st2[SIZE];     while(1)     {         gets(st1);         if(strcmp(st1,"exit")==0)             break;         st1[strlen(st1)]='\n';         fputs(st1,f1);     }     rewind(f1);     while(feof(f1))     {         memset(st2,0,sizeof(st2));         fgets(st2,sizeof(st2),f1);         code(st2);         fputs(st2,f2);     }     fclose(f1);     fclose(f2);     return 0; }    为什么生成b.txt里面是空的啊。。。。 实在不知道怎么回事。。。。  读文件要用 "r" 方式打开。

引用 3 楼 zzl_zZ 的回复:[quote=引用 1 楼 user-3 的回复:]  1）  FILE *f1=fopen("d://a.txt","w"); fputs(st1,f1); rewind(f1); 文件没关闭，也没 flush 文件大小不确定。只怕是 0 ，  2）while(feof(f1)){S;}  文件结束执行循环，而且是一直在循环， 要不执行循环体，要么死循环。 #include<stdio.h> #include<stdlib.h> #include<string.h> #define SIZE 1024 int main(void) {     FILE *f1=fopen("d://a.txt","w");     char st1[SIZE]={0};     while(gets(st1)!=NULL&&st1[0]!='\0')     {         if(strcmp(st1,"exit")==0)             break;         st1[strlen(st1)-1]='\n';         fputs(st1,f1);         memset(st1,0,sizeof(st1));      }     fclose(f1);          FILE *f2=fopen("d://a.txt","r");     rewind(f2);          while(!feof(f2))     {     	     }          fclose(f2);     return 0; } 我这样也不行，输入exit没反应了，可是把第二个while(!feof(f2))删了就好了， 这是什么原因啊。。。。[/quote]  第二个while(!feof(f2)) : 这不是个死循环嘛 ...

引用 1 楼 user-3 的回复:1）  FILE *f1=fopen("d://a.txt","w"); fputs(st1,f1); rewind(f1); 文件没关闭，也没 flush 文件大小不确定。只怕是 0 ，  2）while(feof(f1)){S;}  文件结束执行循环，而且是一直在循环， 要不执行循环体，要么死循环。 #include<stdio.h> #include<stdlib.h> #include<string.h> #define SIZE 1024 int main(void) {     FILE *f1=fopen("d://a.txt","w");     char st1[SIZE]={0};     while(gets(st1)!=NULL&&st1[0]!='\0')     {         if(strcmp(st1,"exit")==0)             break;         st1[strlen(st1)-1]='\n';         fputs(st1,f1);         memset(st1,0,sizeof(st1));      }     fclose(f1);          FILE *f2=fopen("d://a.txt","r");     rewind(f2);          while(!feof(f2))     {     	     }          fclose(f2);     return 0; } 我这样也不行，输入exit没反应了，可是把第二个while(!feof(f2))删了就好了， 这是什么原因啊。。。。


Question: C语言定义结构体，里面有一个字符型指针数组 输出乱码

L->name[j]=strdup(name);

应该说字符指针指向的字符串是不是全局的，输出时指向的字符串必须还存在。

你在给name赋值的时候，需要用strcpy函数，且要保证name[i]有空间， L->name[j]=name;只是指向某个地方，那个地方函数推出就返回给系统了

bool ListInsert(StudentLi *L,int i,int id,int age,char name[],char sex) 参数char name[]是全局变量吗？


Question: 求大神指教，化简程序，在500MS内输出即可

学习学习，受教了！

进来学习

五人一列余2,个位怎么可以是1

使用网易邮箱的撤销功能，对方是看不到的被撤销的邮件的，不过只能够撤销1小时之内的哦

学习一下 HEHE

5楼的思路表达得相当清晰。正确性的证明，额。。。其实这个问题就是中国余数定理啦。 我的建议也是在按照5楼的迭代思路迭代基础上有几个改进。 1，先理解迭代思路：对于A和B互素（A和B不必都是素数），余数分别是a和b，分别搜索合适的非负整数m和n， 使Am mod B = 1，Bn mod A = 1（这里m和n是必然存在的，不证明了），则 r = (Amb + Bna) mod AB为所求，将A和B合并成AB，余数对应变成了r进入下一次迭代。 2，从具体问题上考虑，应当首先获取全部输入后对余数相同的素数分别直接合并成最小公倍数(因为两两互素，所以就是乘积啦)，理论上有利于减少迭代次数。 3，从前面第1点可以看到搜索m和n是最影响性能的步骤。那么问题来了，怎样更快搜索到m和n？这是我的那20%部分啦。 由1知m和n只与A和B有关，与余数无关，且由同余法则可得，小于B的m必存在，小于n的A必存在，因此 Am + Bn ＜AB + BA = 2AB；另一方面，事实上，令a=b=1，则r=1，即(Am + Bn) mod AB = 1。因此 满足Am + Bn = AB + 1的m和n必然存在。m和n只需要搜索其中一个另一个可直接计算不必再次搜索。 设A>B，则m的最差搜索次数小于n的最差搜索次数。 所以，为了搜索m或n的次数最优化，对素数进行大小排序可能是有必要的。迭代应当从最大的开始，理由。。你懂的。

另补充下，这类问题，在阶数不是比较高的情况下，弄明白整数规划后，用手工都能算出来的，先去看看《运筹学》中的整数规划吧

1. 这是运筹学中典型的整数规划问题（参见清华大学出版社的《运筹学》）； 2. 这类问题，不建议直接用计算机程序直接求解； 3. 建议利用运筹学中的整数规划对算法进行优化后，再用计算机程序实现，这样计算量会小很多很多； 4. 如果可能的话，再在第3步实现的基础上，增加并发计算的可能性，以提高性能。

中国剩余数定理解法#include <stdio.h> #include <assert.h> #include <string.h> #define DEBUG #ifdef DEBUG #include <time.h> #endif enum{LEN=32}; // a+=b void add(unsigned int*a,size_t *asz,const unsigned int*b,size_t bsz); // a*=b void mul(unsigned int*a,size_t *size,unsigned long long b); // a%=b void rem(unsigned int *a,size_t *asz,const unsigned int*b,size_t bsz); // ax+by=g -> return x unsigned long long exgcd(const unsigned int*a,size_t size,unsigned long long b); int main() {     unsigned long long mi[8],ai[8],result;     unsigned int Mi[8][LEN],M[LEN];     size_t i,j,Mi_size[8]={0},M_size=0; #ifdef DEBUG     clock_t tim; #endif     for(i=0;i<8;++i)         scanf("%llu",mi+i);     for(i=0;i<8;++i)         scanf("%llu",ai+i); #ifdef DEBUG     tim=clock(); #endif     for(i=0;i<8;++i)         mul(M,&M_size,mi[i]);     for(i=0;i<8;++i)         for(j=0;j<8;++j)             if(i!=j)                 mul(Mi[i],Mi_size+i,mi[j]);     for(i=0;i<8;++i)     {         unsigned long long x=exgcd(Mi[i],Mi_size[i],mi[i]);         mul(Mi[i],Mi_size+i,x);         mul(Mi[i],Mi_size+i,ai[i]);     }     for(i=1;i<8;++i)         add(Mi[0],Mi_size,Mi[i],Mi_size[i]);     rem(Mi[0],Mi_size,M,M_size);     assert(Mi_size[0]<=2);     switch(Mi_size[0])     {         case 0:result=0;break;         case 1:result=Mi[0][0];break;         case 2:result=*(unsigned long long*)Mi[0];break;     }     if(M_size<=2)     {         for(i=1;i<8;++i)             if(mi[0]<mi[i])                 mi[0]=mi[i];         if(result<mi[0])         {             unsigned long long MM=0;             switch(M_size)             {                 case 0:MM=0;break;                 case 1:MM=M[0];break;                 case 2:MM=*(unsigned long long*)M;break;             }             result+=MM;         }     }     printf("%llu\n",result); #ifdef DEBUG     printf("time:%gs\n",(double)(clock()-tim)/CLOCKS_PER_SEC); #endif     return 0; } void add(unsigned int*a,size_t *asz,const unsigned int*b,size_t bsz) {     unsigned int v[LEN]={0};     size_t vsz=0;     unsigned long long r=0;     while(vsz<*asz||vsz<bsz)     {         if(vsz<*asz)             r+=a[vsz];         if(vsz<bsz)             r+=b[vsz];         v[vsz++]=(unsigned int)r;         r>>=32;     }     if(r)         v[vsz++]=(unsigned int)r;     memcpy(a,v,sizeof v);     *asz=vsz;     assert(*asz<LEN); } void mul(unsigned int*a,size_t *size,unsigned long long b) {     unsigned long long r=0;     size_t i;     if(!*size)     {         *(unsigned long long*)a=b;         *size=b>>32?2:1;     }     else if(b>>32)     {         unsigned long long c=(unsigned int)b;         b>>=32;         for(i=0;i<*size;++i)         {             unsigned int t[3]={0};             *(unsigned long long*)t=a[i]*c+(r&-1U);             *(unsigned long long*)(t+1)+=a[i]*b+(r>>32);             a[i]=t[0];             r=*(unsigned long long*)(t+1);         }         if(r)         {             *(unsigned long long*)(a+*size)=r;             *size+=r>>32?2:1;         }     }     else     {         for(i=0;i<*size;++i)         {             r+=a[i]*b;             a[i]=(unsigned int)r;             r>>=32;         }         if(r)             a[(*size)++]=(unsigned int)r;     }     assert(*size<LEN); } void rem(unsigned int *a,size_t *asz,const unsigned int*b,size_t bsz) {     unsigned int r[LEN];     size_t rsz=0,l=*asz<<5,i;     while(l--)     {         if(!rsz)         {             if(a[l>>5]>>(l&31)&1)                 r[rsz++]=1;         }         else         {             i=rsz-1;             if(r[rsz-1]>>31)                 r[rsz++]=1;             while(i)             {                 r[i]=r[i]<<1|r[i-1]>>31;                 --i;             }             r[0]=(r[0]<<1)|((a[l>>5]>>(l&31))&1);         }         if(rsz>bsz)         {             for(i=bsz;i;--i)                *(unsigned long long*)(r+i-1)-=b[i-1];             while(rsz&&!r[rsz-1]) --rsz;         }         else if(rsz&&rsz==bsz)         {             for(i=rsz;i&&r[i-1]==b[i-1];--i);             if(!i||r[i-1]>b[i-1])             {                 r[rsz-1]-=b[bsz-1];                 for(i=rsz-1;i;--i)                     *(unsigned long long*)(r+i-1)-=b[i-1];                 while(rsz&&!r[rsz-1]) --rsz;             }         }     }     memcpy(a,r,sizeof r);     *asz=rsz;     assert(*asz<LEN); } unsigned long long exgcd(const unsigned int*a,size_t size,unsigned long long b) {     long long x[2]={0,1};     unsigned long long aa=b,bb=0,r;     if(1==size)         bb=a[0]%b;     else     {         unsigned int tmp[LEN];         size_t tsz=size;         memcpy(tmp,a,sizeof tmp);         rem(tmp,&tsz,(unsigned int*)&b,b>>32?2:1);         assert(tsz<=2);         switch(tsz)         {             case 0:bb=0;break;             case 1:bb=*tmp;break;             case 2:bb=*(unsigned long long*)tmp;break;         }     }     do     {         long long t=x[0];x[0]=x[1];x[1]=t-aa/bb*x[0];         r=aa%bb;aa=bb;bb=r;     }while(bb);     if(x[0]>=0)         return (unsigned long long)x[0];     else         return (unsigned long long)((long long)b+x[0]); } 附测试数据和结果 2 3 5 7 11 13 17 19 1 1 1 1 1 1 1 1 9699691 time:5.7e-05s  9223372036854775399 9223372036854775417 9223372036854775421 9223372036854775433 9223372036854775507 9223372036854775549 9223372036854775643 9223372036854775783 408 390 386 374 300 258 164 24 9223372036854775807 time:0.000285s 4294967111 4294967143 4294967161 4294967189 4294967197 4294967231 4294967279 4294967291 2147500667 2147495275 2147492692 2147489318 2147488498 2147485727 2147483783 2147483657 9223372036854775807 time:0.000137s  4294967111 4294967143 4294967161 4294967189 4294967197 4294967231 4294967279 4294967291 400879708 76365989 2309746472 1488927345 2481541213 2405183635 4065902492 1259857083 8690466096661279830 time:0.000127s

7+3m=7+5n,             3m=5n,  m肯定有5的因子， n肯定有3的因子。

网上搜了一下中国剩余数定理，数学原理告诉我们定域内解是唯一的。 至少有6种解法，其中至少三种符合楼主的要求。 我的这种是逐级求解法，计算时间还是长了，有不用循环，直奔答案的解法。

d2 := a1*a2; n := (d2*i + c2) mod a3; 为什么要用前面数的最小公倍数做基数，为什么一个基数倍域范围内只有只一个解，这里我用的是经验公式，数学原理也不清楚。

07年的明基笔记本跑不出毫秒级时差   StartTime:=GetTickCount;   a1:=2; a2:=3; a3:=5; a4:=7; a5:=11; a6:=13; a7:=17; a8:=19;   b1:=1; b2:=1; b3:=1; b4:=1;  b5:=1;  b6:=1; b7:=1;  b8:=1;   for i := 1 to a2 do   begin     n := (a1*i + b1) mod a2;     if n = b2 then     begin       c2 := a1*i + b1;       d2 := a1*a2;       break;     end;   end;   //i = 3  c2 = 7   for i := 1 to a3 do   begin     n := (d2*i + c2) mod a3;     if n = b3 then     begin       c3 := d2*i + c2;       d3 := d2*a3;       break;     end;   end;   //i = 4 c3 = 31   for i := 1 to a4 do   begin     n := (d3*i + c3) mod a4;     if n = b4 then     begin       c4 := d3*i + c3;       d4 := d3*a4;       break;     end;   end;   //i = 6 c4=211   for i := 1 to a5 do   begin     n := (d4*i + c4) mod a5;     if n = b5 then     begin       c5 := d4*i + c4;       d5 := d4*a5;       break;     end;   end;   //i = 10 c5=2311   for i := 1 to a6 do   begin     n := (d5*i + c5) mod a6;     if n = b6 then     begin       c6 := d5*i + c5;       d6 := d5*a6;       break;     end;   end;   //i = 12 c6=30031   for i := 1 to a7 do   begin     n := (d6*i + c6) mod a7;     if n = b7 then     begin       c7 := d6*i + c6;       d7 := d6*a7;       break;     end;   end;   //i = 16 c7=510511   for i := 1 to a8 do   begin     n := (d7*i + c7) mod a8;     if n = b8 then     begin       c8 := d7*i + c7;       d8 := d7*a8;       break;     end;   end;   //i = 18; c8=9699691   EndTime:=GetTickCount;

求最小值，共循环57次，算法分解，一目了然   a1:=3; a2:=5; a3:=7; a4:=13; a5:=17; a6:=19; a7:=23; a8:=29;   b1:=1; b2:=2; b3:=4; b4:=6;  b5:=2;  b6:=10; b7:=1;  b8:=11;   for i := 1 to a2 do   begin     n := (a1*i + b1) mod a2;     if n = b2 then     begin       c2 := a1*i + b1;       d2 := a1*a2;       break;     end;   end;   //i = 2  c2 = 7   for i := 1 to a3 do   begin     n := (d2*i + c2) mod a3;     if n = b3 then     begin       c3 := d2*i + c2;       d3 := d2*a3;       break;     end;   end;   //i = 4 c3 = 67   for i := 1 to a4 do   begin     n := (d3*i + c3) mod a4;     if n = b4 then     begin       c4 := d3*i + c3;       d4 := d3*a4;       break;     end;   end;   //i = 4 c4=487   for i := 1 to a5 do   begin     n := (d4*i + c4) mod a5;     if n = b5 then     begin       c5 := d4*i + c4;       d5 := d4*a5;       break;     end;   end;   //i = 5 c5=7312   for i := 1 to a6 do   begin     n := (d5*i + c5) mod a6;     if n = b6 then     begin       c6 := d5*i + c5;       d6 := d5*a6;       break;     end;   end;   //i = 18 c6=425002   for i := 1 to a7 do   begin     n := (d6*i + c6) mod a7;     if n = b7 then     begin       c7 := d6*i + c6;       d7 := d6*a7;       break;     end;   end;   //i = 2 c7=1306792   for i := 1 to a8 do   begin     n := (d7*i + c7) mod a8;     if n = b8 then     begin       c8 := d7*i + c7;       d8 := d7*a8;       break;     end;   end;   //i = 22; c8=224399662

for(k=mn/(a[i]-1),s=0,ab=0;ab<=mn;k++)范围太大 15X+7=7Y+4<15*7 过滤掉了绝大部分的不可能数据

我是逐位求，你得是直接来八个，这样逐个计算太浪费。


Question: 大神快来，strcpy函数是否会导致溢出？

这是什么鬼代码？b申请了空间，但不赋值，又问字节里面是什么内容？乱码都有可能阿。

感谢各位，我在linux里也试了一下，确实如 qldsrx说的结果。

可能会出现溢出，需要程序元自己确保，现在新版VS默认需要使用安全的strcpy_s，该函数需要输入目标字符数组大小，来确保不会溢出。

对了，你这个时候如果在return之前添加 free(b); 立刻程序崩溃，因为b这个对象释放时要查找b申请的大小，信息记录在其内存的前面，但被你改写了。

我用gnu C在linux下测试是这样的结果，这个其实是和内存分配是否连续有关，如果两次申请的内存是连续内存空间，那么20字节再加上后面申请内存的头部字节（预估是12字节），这样下面一个申请的20字节正好偏移了32字节，自然就是你看到的结果了。

溢出肯定会的。用strcpy时都会提示，这个函数不安全，建议用strcpy_s。 我在VS2013下，这段代码运行不起来。。就是因为这个函数。

引用 6 楼 yupeigu 的回复:我用visual c++ 6.0 运行程序后，发现数组b都没有值的 你要干什么啊, 你又没给b赋值

我用visual c++ 6.0 运行程序后，发现数组b都没有值的

T就是Technology的首字母，那后面的字母自然是e和c了

其实电脑开机后物理内存的每个字节都是可读写的，从来不会因为所谓的new、delete或malloc、free而被创建、销毁。区别仅在于操作系统内存管理模块在你读写时是否能发现并是否采取相应动作而已。操作系统管理内存的粒度不是字节而是页，一页通常为4KB。  推荐使用WinHex软件查看硬盘或文件或内存中的原始字节内容。

引用 2 楼 yupeigu 的回复:[quote=引用 1 楼 qldsrx 的回复:] 溢出是肯定会的啊，只要不写入到受保护的内存地址，一般程序不会崩溃，但是这样就很可能会把其他变量的值给替换掉了，导致程序运行不稳定。  哦哦哦，明白。  现在的问题是，这段程序已知：  b[11] = T 那么 b[12] = 什么 以及 b[13] = 什么 [/quote] 不一定是什么吧 b和a可能离很远, T不一定是a里面的T

引用 1 楼 qldsrx 的回复:溢出是肯定会的啊，只要不写入到受保护的内存地址，一般程序不会崩溃，但是这样就很可能会把其他变量的值给替换掉了，导致程序运行不稳定。  哦哦哦，明白。  现在的问题是，这段程序已知：  b[11] = T 那么 b[12] = 什么 以及 b[13] = 什么