Question: 运算符问题

弱弱的问一下各位  你们用的什么软件编写代码  新手  专业需要学习  但是个人也比较喜爱

不要写这种代码，容易把人搞迷糊

C语言怪异代码大赛历届作品大全 1984～1996，1998，2000，2001，2004～2006，2011，2012http://download.csdn.net/detail/zhao4zhong1/5538847

应该是贪心法，在很多书上都是这么说的，

1.运算符的优先级问题 2.编译器的处理方式 3.最好带括号，这样的代码简单易懂，容易理解

//C++ Operators //  Operators specify an evaluation to be performed on one of the following: //    One operand (unary operator) //    Two operands (binary operator) //    Three operands (ternary operator) //  The C++ language includes all C operators and adds several new operators. //  Table 1.1 lists the operators available in Microsoft C++. //  Operators follow a strict precedence which defines the evaluation order of //expressions containing these operators.  Operators associate with either the //expression on their left or the expression on their right;    this is called //“associativity.” Operators in the same group have equal precedence and are //evaluated left to right in an expression unless explicitly forced by a pair of //parentheses, ( ). //  Table 1.1 shows the precedence and associativity of C++ operators //  (from highest to lowest precedence). // //Table 1.1   C++ Operator Precedence and Associativity // The highest precedence level is at the top of the table. //+------------------+-----------------------------------------+---------------+ //| Operator         | Name or Meaning                         | Associativity | //+------------------+-----------------------------------------+---------------+ //| ::               | Scope resolution                        | None          | //| ::               | Global                                  | None          | //| [ ]              | Array subscript                         | Left to right | //| ( )              | Function call                           | Left to right | //| ( )              | Conversion                              | None          | //| .                | Member selection (object)               | Left to right | //| ->               | Member selection (pointer)              | Left to right | //| ++               | Postfix increment                       | None          | //| --               | Postfix decrement                       | None          | //| new              | Allocate object                         | None          | //| delete           | Deallocate object                       | None          | //| delete[ ]        | Deallocate object                       | None          | //| ++               | Prefix increment                        | None          | //| --               | Prefix decrement                        | None          | //| *                | Dereference                             | None          | //| &                | Address-of                              | None          | //| +                | Unary plus                              | None          | //| -                | Arithmetic negation (unary)             | None          | //| !                | Logical NOT                             | None          | //| ~                | Bitwise complement                      | None          | //| sizeof           | Size of object                          | None          | //| sizeof ( )       | Size of type                            | None          | //| typeid( )        | type name                               | None          | //| (type)           | Type cast (conversion)                  | Right to left | //| const_cast       | Type cast (conversion)                  | None          | //| dynamic_cast     | Type cast (conversion)                  | None          | //| reinterpret_cast | Type cast (conversion)                  | None          | //| static_cast      | Type cast (conversion)                  | None          | //| .*               | Apply pointer to class member (objects) | Left to right | //| ->*              | Dereference pointer to class member     | Left to right | //| *                | Multiplication                          | Left to right | //| /                | Division                                | Left to right | //| %                | Remainder (modulus)                     | Left to right | //| +                | Addition                                | Left to right | //| -                | Subtraction                             | Left to right | //| <<               | Left shift                              | Left to right | //| >>               | Right shift                             | Left to right | //| <                | Less than                               | Left to right | //| >                | Greater than                            | Left to right | //| <=               | Less than or equal to                   | Left to right | //| >=               | Greater than or equal to                | Left to right | //| ==               | Equality                                | Left to right | //| !=               | Inequality                              | Left to right | //| &                | Bitwise AND                             | Left to right | //| ^                | Bitwise exclusive OR                    | Left to right | //| |                | Bitwise OR                              | Left to right | //| &&               | Logical AND                             | Left to right | //| ||               | Logical OR                              | Left to right | //| e1?e2:e3         | Conditional                             | Right to left | //| =                | Assignment                              | Right to left | //| *=               | Multiplication assignment               | Right to left | //| /=               | Division assignment                     | Right to left | //| %=               | Modulus assignment                      | Right to left | //| +=               | Addition assignment                     | Right to left | //| -=               | Subtraction assignment                  | Right to left | //| <<=              | Left-shift assignment                   | Right to left | //| >>=              | Right-shift assignment                  | Right to left | //| &=               | Bitwise AND assignment                  | Right to left | //| |=               | Bitwise inclusive OR assignment         | Right to left | //| ^=               | Bitwise exclusive OR assignment         | Right to left | //| ,                | Comma                                   | Left to right | //+------------------+-----------------------------------------+---------------+

这是运算符优先级的问题，在运算时会在操作数向左或者向右移动形成一个完整的运算定义符，应该是先++然后+，这是基本问题，楼主的基本功不扎实

这里讨论的不是一个一般 tokenizer 应该怎么做，而是在正确解释 C 语言程序时的 token 切分的结果是如何得到了。  在这一点上，C 语言并没有留出得到多个可能结果的余地。对一个程序，它的 token 切分是唯一的。无论的 token 切分具体实现成什么样子，+++++ (假设上一个token正好在第一个+前面结束)必须被切分成 ++ ++ + ，而不是其它。

我每次看到有人写这种代码就很来气，写这种代码的人想说明你自己对运算符的优先级掌握的很好？加个括号有这么麻烦？

我们读写文件或字符流都是从前往后读的，但是在一些人际应答界面，不排除其采用由后向前进行cat cut，这样话，操作符分割顺序就会颠倒了。这么说源自于我参与的一个项目，其中有一个内存分割的类似token的函数，采用的就是从后向前分割的，问起理由居然是省空间！在原有的字符串空间直接改成字符串列表并实现堆栈式后进先出存放，虽然很奇葩，但不失为一种精妙的处理方法。 但是商用的或非商用的的是基于文件的分割，在这点上，就目前来说能见到的都是由前向后分割的。这也是总被处理成++ ++ +形式的原因。

如果想验证编译器的具体实现的话，现在 g++ 和 clang 的代码都是开源的，去读就可以了。  引用 29 楼 fefe82 的回复:标准明确要求了要从前向后分割。  你可以从后向前分割（或者随意怎么分割），但是必须得到与从前向后分割相同的结果。否则你的编译器的实现就是错误的。  ===== 当然，也有时候有些编译器把故意不符合标准的处理方式当作 feature 的。不过通常情况下会用详细说明，并且有选项可以关掉。  [quote=引用 28 楼 FreeFice 的回复:] [quote=引用 27 楼 fefe82 的回复:] c++draft n4296  2.4 Preprocessing tokens  3. .................... (3.3) — Otherwise, the next preprocessing token is the longest sequence of characters that could constitute a preprocessing token, even if that would cause further lexical analysis to fail.  5 [ Example: The program fragment x+++++y is parsed as x ++ ++ + y, which, if x and y have integral types, violates a constraint on increment operators, even though the parse x ++ + ++ y might yield a correct expression. — end example ] 看来又有一个上了“标准”描述当的，这句话的有可能，源自于西方式语言严谨习惯，因为没法验证！其出台的前提在于token分割机制不确定性，因为不排除个别程序员读写代码是从尾向头读写分割的(谁叫人家有个性呢)！但是，很遗憾，商用的非商用编译器在处理程序代码时，采用的都是从头到尾式的顺序分割，也就是说虽然不排除可能，但实际上却没有。尤其是++ + ++分割牵涉到乱序分割问题，不仅仅是算法复杂度的增加，而且也是对程序稳定性的挑战。有必要为了一个不确定的技术可能而牺牲整个程序可靠便捷？更何况出现这一情况本就是建议禁止的？[/quote][/quote]

标准明确要求了要从前向后分割。  你可以从后向前分割（或者随意怎么分割），但是必须得到与从前向后分割相同的结果。否则你的编译器的实现就是错误的。  ===== 当然，也有时候有些编译器把故意不符合标准的处理方式当作 feature 的。不过通常情况下会用详细说明，并且有选项可以关掉。  引用 28 楼 FreeFice 的回复:[quote=引用 27 楼 fefe82 的回复:] c++draft n4296  2.4 Preprocessing tokens  3. .................... (3.3) — Otherwise, the next preprocessing token is the longest sequence of characters that could constitute a preprocessing token, even if that would cause further lexical analysis to fail.  5 [ Example: The program fragment x+++++y is parsed as x ++ ++ + y, which, if x and y have integral types, violates a constraint on increment operators, even though the parse x ++ + ++ y might yield a correct expression. — end example ] 看来又有一个上了“标准”描述当的，这句话的有可能，源自于西方式语言严谨习惯，因为没法验证！其出台的前提在于token分割机制不确定性，因为不排除个别程序员读写代码是从尾向头读写分割的(谁叫人家有个性呢)！但是，很遗憾，商用的非商用编译器在处理程序代码时，采用的都是从头到尾式的顺序分割，也就是说虽然不排除可能，但实际上却没有。尤其是++ + ++分割牵涉到乱序分割问题，不仅仅是算法复杂度的增加，而且也是对程序稳定性的挑战。有必要为了一个不确定的技术可能而牺牲整个程序可靠便捷？更何况出现这一情况本就是建议禁止的？[/quote]

分割 toke 和分割表达式是两个完全独立的过程。  分割 token 时，输入是字符，输出是 token 。  分割表达式时，输入是 token ，输出的表达式。 /// 这一句描述其实不慎准确。  至于关于分割 token 标准是如何规定，上面已经给出了。 /// 不过省略了些 ....  引用 31 楼 FreeFice 的回复:标准明确要求了要从前向后分割。 恰恰相反，标准在这一类实现上没有强制性，这牵涉到表达式是先序还是中序或后序分割问题，当是单一操作符时，是不会产生二义性问题的，但在多个操作符堆叠时，这种差异就体现出来了。好在我们通常所用的token都是先序分割的，因此就不会出现这类问题。 但要是中序或后序分割，那就有可能会成为++ + ++或+ ++ ++等其它结果(这要看操作符压栈语句怎么写)。

引用 18 楼 I_Surrender 的回复:[quote=引用 6 楼 fefe82的回复:]在将输入的字符切分为 token 的时候，每一个 token 都会尽可能用掉尽可能多的字符。  +++ 被切分的时候，会被分为 ++ +，而不是 + ++ 。第一个被切出来的 token 是 ++ 而不是 + ，因为 ++ 有两个字符，比 + （只有一个字符）多。  同样 +++++++++ 会被切分为 ++ ++ ++ ++ + 。  =========== 这跟优先级没多大关系 ... 好多人都说是优先级问题。你说的这个原因有办法验证没有？[/quote]  没有，请查标准。

引用 27 楼 fefe82 的回复:c++draft n4296  2.4 Preprocessing tokens  3. .................... (3.3) — Otherwise, the next preprocessing token is the longest sequence of characters that could constitute a preprocessing token, even if that would cause further lexical analysis to fail.  5 [ Example: The program fragment x+++++y is parsed as x ++ ++ + y, which, if x and y have integral types, violates a constraint on increment operators, even though the parse x ++ + ++ y might yield a correct expression. — end example ] 看来又有一个上了“标准”描述当的，这句话的有可能，源自于西方式语言严谨习惯，因为没法验证！其出台的前提在于token分割机制不确定性，因为不排除个别程序员读写代码是从尾向头读写分割的(谁叫人家有个性呢)！但是，很遗憾，商用的非商用编译器在处理程序代码时，采用的都是从头到尾式的顺序分割，也就是说虽然不排除可能，但实际上却没有。尤其是++ + ++分割牵涉到乱序分割问题，不仅仅是算法复杂度的增加，而且也是对程序稳定性的挑战。有必要为了一个不确定的技术可能而牺牲整个程序可靠便捷？更何况出现这一情况本就是建议禁止的？

引用 24 楼 庄鱼的回复:[quote=引用 18 楼 I_Surrender 的回复:] [quote=引用 6 楼 fefe82的回复:]在将输入的字符切分为 token 的时候，每一个 token 都会尽可能用掉尽可能多的字符。  +++ 被切分的时候，会被分为 ++ +，而不是 + ++ 。第一个被切出来的 token 是 ++ 而不是 + ，因为 ++ 有两个字符，比 + （只有一个字符）多。  同样 +++++++++ 会被切分为 ++ ++ ++ ++ + 。  =========== 这跟优先级没多大关系 ... 好多人都说是优先级问题。你说的这个原因有办法验证没有？[/quote] 你自己写个编译器就知道了。token分割总是就前不就后的，所以，其分割总是就目前所能解释的最大连接词(或符号)，自然就出现++ +的情况了。[/quote] 引用 18 楼 I_Surrender 的回复:[quote=引用 6 楼 fefe82的回复:]在将输入的字符切分为 token 的时候，每一个 token 都会尽可能用掉尽可能多的字符。  +++ 被切分的时候，会被分为 ++ +，而不是 + ++ 。第一个被切出来的 token 是 ++ 而不是 + ，因为 ++ 有两个字符，比 + （只有一个字符）多。  同样 +++++++++ 会被切分为 ++ ++ ++ ++ + 。  =========== 这跟优先级没多大关系 ... 好多人都说是优先级问题。你说的这个原因有办法验证没有？[/quote] 你自己写个编译器就知道了。token分割总是就前不就后的，所以，其分割总是就目前所能解释的最大连接词(或符号)，自然就出现++ +的情况了。[/quote] 嗯，明白了，我试试，非常感谢！

学习了！不过这样写好像真的会被打哎

很明显楼主在这里讨论的是个技术细节问题，而不是编程习惯问题，楼主纠结的不是怎么样可以得出结果，而是为什么能够出现这样的结果。这里不是运算优先级的问题，建议说优先级问题的人去看看编译原理。 非常认同#6 #7的说法，根据编译器的语义解析的贪心算法，会把+++解析成++   +，所以自然就变成了(a++)+b，只是编译器自动识别的。


Question: 怎样获得dll文件的导入表

nt文件头的index为1的DataDirectory放着导入表的rva，静态扫描涉及到rva到实际文件偏移的转换【扫描节表判断目标Rva落点，然后用相对节表Rva加上PointerToRawData的偏移就是寻址到真正的导入表】，动态则直接一个Rva就完事了，寻址到的结构地址会连着n个IMAGE_IMPORT_DESCRIPTOR【有多少个dll被导入就有多少个这种结构，后面加一个内容全是0的IMAGE_IMPORT_DESCRIPTOR结构（有点字符串的味道）】，在每个IID结构中能够找到dll的函数名和一堆名为IMAGE_THUNK_DATA的数组【也是以0结构结尾】可以用来找导入的函数名称【序号导出就没有函数名】。 iat的查找直接找nt文件头的index为12的DataDirectory

WinExec("cmd /c dumpbin /IMPORTS your.dll >d:\\yourdllimports.txt",SW_HIDE); //然后读文件d:\yourdllimports.txt的内容。 C:\Program Files\Microsoft Visual Studio 版本号\VC\bin\dumpbin.exe

用depends看有哪些函数，然后动态加载dll吧

谢谢楼上 不过PE跟COFF不是一种文件格式吧 我们是在做PE的输入表

另外 程序员的自我修养 这本书也有不错的说明，

楼主在网上查查coff文件格式，对你的问题有帮助的


Question: float变量0在内存中如何表示（0/1代码是多少）？

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

+0，-0 为特殊编码 ，+0 每一位都是0，-0 除了符号位是1，其余都是0 float a =0.0; printf("0x%08x",*(int *)&a);

0 有两个， +0  -0  阶码，尾数为0， 符号位0,1都可以， 很多情况下， 非规格化数/下溢数 也被视为 0， 就是阶码为0， 尾数非0 这种。

表示方法看：http://www.cnblogs.com/dolphin0520/archive/2011/10/02/2198280.html  浮点数0在内存中也全是0，但1就得计算一下才知道了

当然也还是0


Question: 字符串中每个字符间插入一个空格 运行的时候是错误的 大神看一下吧

位置很固定, 不知道为什么要两重循环,只要一重应该就够了 void add(char a[]) {     int n;     n=strlen(a);     if(!n) return;     for(int src=n-1,dst=2*src;src;src--){         a[dst--] =a[src];         a[dst--] =' ';     }     a[2*n-1]='\0'; }

自后向前把一个字符变成两个字符，第一个字符不动 例如 123 3 ---> 3 23---> 2 3 1 不动 123--->1 2 3 注意字符串结束符号要加上

int main() {     char a[200];     gets(a);     add(a); 	getchar();  } void add(char a[]) {     	int i ,j ,n;     n = strlen(a);     for(i = n-1; i > 0; i--) 	{ 		a[i + i] =  a[i]; 		a[i + i - 1] =  ' '; 	} 	a[n * 2 ] = '\0';      printf("%s",a); }  修改了下 不是很好

引用 5 楼 qq_31897979 的回复:i 改过了   还是不行    1楼说的那个问题确实存在  怎么改呢？？引用  我没具体看你怎么实现的，如果你是要表示i += 2的话也不会一真循环下去，因为n每次只加1，i每次是加2

i 改过了   还是不行    1楼说的那个问题确实存在  怎么改呢？？引用

引用 3 楼 qq_31897979 的回复:那应该怎样让n停止到2n？？？？？  你n没问题，有问题的是i

那应该怎样让n停止到2n？？？？？

for(i=1;i<n;i+2) 这句是要表示for(i=1;i<n;i+=2)吗，不然 i+2 并不会改变i的值， i 每次循环都是1

n不停在加, 这样何时是个头了,i<n成死循环了, 关键a才20


Question: 运行时候出错。。无法解析的外部符号。。不知道哪里错了，能不能帮我看看

如果函数在main函数之后定义，应该事先声明一下，你把TimeDiff声明在main之前试试

注意字母大小写  int TimeDiff(struct Time t1, struct Time t2) {  int second1, second2;//秒 int t;


Question: 用不了break的怎么终止无限循环

开辟单独的线程

引用 2 楼 user-2 的回复:[quote=引用 1 楼 Dulee_ 的回复:] 比如我要它输入回车就结束， 那应该怎么写呢？  	char ch; 	ch = getchar();       //然后判断ch的值 [/quote] 那这样的话就不会运行下去了啊... 时间就不能动态显示了

引用 1 楼 Dulee_ 的回复:比如我要它输入回车就结束， 那应该怎么写呢？  	char ch; 	ch = getchar();       //然后判断ch的值

比如我要它输入回车就结束， 那应该怎么写呢？

int main() { 	int a(void); 	clock_t newtime; 	while(1) 	{  		system("CLS"); 		a(); 		newtime=1000+clock(); 		while(newtime>clock()) 			; 		if(_kbhit()) 		{ 			char ch; 			ch = getchar(); 			if(ch == '\n') 				break; 		} 	} 	return 0; } int a() { 	char ch[100]; 	time_t t; 	struct tm *t1; 	t=time(NULL); 	t1=localtime(&t); 	strftime(ch,100,"%Y年%m月%d日 %H:%M:%S",t1); 	printf("现在是%s\n",ch); 	return 0; }   需要包含头文件#include <conio.h>


Question: 求解不等式!!!

http://www.doc88.com/p-4925163405966.html参考此论文，看看有没有变换可能 如果没有就蛮力实现即可

思路： 外循环m = 1.0、2.0、3.0.... 内循环计算不等式左边并比较 第一个找到的即为解

引用 4 楼 user-3 的回复:简单处理一下  (M+1)*sqrt(M) <sum(sqrt(M+i),0,M)^2<(m+1)*(sqrt(2M))  M^3<M(M+1)^2 <s ^2 <2*M*(M+1)^2<2M^3  如果 M^3 >= n^2 则 一定有 s>n 如果 M^3 <= n^2/2 则一定不会有 s> n 所以最小的M 在 (n^2 / 2)^(1/3) ~ (n^2)^(1/3)之间 在区间 [floor ((n^2 /2)^1/3) , ceil((n^2)^(1/3))]穷举M即可  校正一下

简单处理一下  (M+1)*sqrt(M) <sum(sqrt(M+i),0,M)<(m+1)*(sqrt(2M))  M^3<M(M+1)^2 <s ^2 <2*M*(M+1)^2<2M^3  如果 M^3 >= n^2 则 一定有 s>n 如果 M^3 <= n^2/2 则一定不会有 s> n 所以最小的M 在 (n^2 / 2)^(1/3) ~ (n^2)^(1/3)之间 在区间 [floor ((n^2 /2)^1/3) , ceil((n^2)^(1/3))]穷举M即可

先定个范围，再穷举 不然只好从1 开始枚举


Question: ccs2下载时提示这样，求大神

求大神们，真心希望能帮我这个忙！！！


Question: 给大家推荐一本经典数据结构图书，个人感觉非常不错

呵呵，只是推荐而已，可以相互交流

引用 2 楼 crcr 的回复:谢谢，互相交流学习啊，C语言板块熟悉数据结构，对这个比较感兴趣， 楼上是技术牛人吧  没有了，牛人就不逛论坛了

楼主在为自己代言

相互交流学习

另推荐楼主《STL源码剖析》


Question: (void (*)(Uint32))svgendq_calc 该语句意义

先强转成Uint，即无符号整形，然后再转成指针void *; void * 和Unit一般大小相等，可以相互转换而不丢失数据

typedef void (*Fn)(Uint32); Fn svgendq_calc; 这回看懂了没？

引用 2 楼 xiaohuagezai 的回复:svgen_dq1.calc(&svgen_dq1);怎么理解 svgen_dq1为结构体变量 结构体指针


Question: 求助大神  关于for循环 第一次循环和以后循环不同

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

scanf函数里面，把\n去掉

点击结帖按钮，然后分配分值， 必须分完，完成即可！

怎么结贴给分啊 我不会用 第一次用  点了不管用

scanf("%d", &...)


Question: vs2015中已经安装easyx 但是调用graphics中函数的时候仍然出错

只能用于C++啊，Ｃ就不行了

bioskey(0)用 		if(_kbhit())	//如果有键盘按下 		{ 			key=_getch();             if( key==0 || key==0xE0 )  // 非字符键                 key = _getch()<<8 | key; 		} 改写，delay改成Sleep()，要包含<windows.h>, getch()要包含<conio.h> randomize是Borland的，VC要用srand()， 其它未定义标识符或没有匹配的函数，是因为函数名一样，但是EasyX实现的时候函数参数已经变了，可以参考下载的EasyX里面的 EasyX_Help.chm 文档，里面有完整的函数文档。

int gd = DETECT, gm; initgraph(&gd, &gm, "c:\\tc"); 这2行注释掉，改成initgraph(640,480);

软件兼容编辑 与Borland BGI 绘图库的兼容情况 如果您需要移植原 Turbo C 的绘图程序，需要注意以下几个方面： 1. 颜色。EasyX 库支持了真彩色，这点与 TC 差别很大。 2.getimage / putimage，这组函数较 BGI 做了很多扩充。 3. 设置线性、填充类型的函数，和 BGI 的略有区别。 4.位操作，BGI 的功能很局限，EasyX 库实现了所有的位操作。 5. 常量命名，EasyX 库多采用和 Windows 贴近的命名。 6.其他扩充函数，例如鼠标、批操作等。  有些东西，还是有区别的，还是先看看头文件里有什么吧

编译不成功啊

bioskey 不是graphics.h 中的函数吧， 这是 bios函数 （内部调用 Bios功能调用)   编译结果是什么，你这怎么都是提示啊？


Question: 为什么c语言里，自定义函数在主函数之前，就不用在主函数里声明即可调用？

定义在前面的话编译器已经认识了这个函数，定义在后面的时候，编译到main函数还不知这个函数，如果未声明，就会出错

其实是因为 定义也是声明。 声明不是定义。  定义在前，表示已经声明了， 多声明一次，不过是重复声明而已， 如果没问题，就会被忽略

编译器在编译过程中可以在Main之前得到函数的声明/定义，就可以在Main中直接使用了。

函数可以调用只需要签过名就可以了。 比如说库函数都在头文件里面签名了。  而函数的定义，包含了定义函数体和签名两个。

因为编译器已经获取到它的信息了，所见即所得！你见过一个人，那么谈起他时就不要特别说明一下了；如果你没见过，那么需要一个细致的描述，你才能认知他！就是这么个理

这个牵涉到函数的作用域问题，楼主还是好好看看基础知识吧

我觉得你可以楼主可以多看看《程序员的自我修养》好多东西就都懂了

人物：A  B  场景1： A发短信给B：家里有饮料，不用买了。 B回来没带饮料 B回来发现家里有好多饮料，苹果味，橘子味等等  场景2： A发短信给B：家里有饮料，苹果味，橘子味...都有 B回来没带饮料  场景3： B回来买了好多饮料 B回家发现家里已经有A之前买的好多饮料，苹果味，橘子味...都有

编译器从前往后按顺序读取源程序并试图理解 看过了函数定义，已经知道调用函数时的所有细节 就用不着另外的声明了

大概可以这样理解和全局变量一样,在函数外声明.


Question: 字符串排序的一段代码

#include <stdio.h> #include <string.h> void sort(char *str[],int n) { 	char *temp; int i,j; 	for(i=0;i<n-1;i++) 	{ 		for(j=i+1;j<n;j++) 			if(strcmp(str[i],str[j])>0) 			{ 				temp=str[i]; 				str[i]=str[j]; 				str[j]=temp; 			} 	} } void main() { 	int i,n=4; 	char *string[4]={"AASCAL","PASCAL","BASIC","C"}; 	sort(string,n); 	for(i=0;i<n;i++) 		printf("%s\n",string[i]); }

这个程序用的是选择排序思想，楼上说得对 k = 1 if (k != 1) 把1改成i

void sort(char *str[],int n) 函数的 k = 1; if (k != 1) 两行中 1 应该是 i 不知道是你打错了，还是书上印错了


Question: 关于防止头文件重复包含的执行原理的疑问

#ifndef XXX      #define XXX ... #endif 子类一般会用#include"XXX"包含基类头文件，在多继承情况下，为了防止头文件被重复包含，菱形继承里面都要用到XXX一般用的是文件全名或者是能把这个文件区分开来的标识。 如： #ifndef PERSON_H #define PERSON_H class Person { ... }; #endif

你这里定义成空，通常也定义成空，当然你第二句写成#define XXX YYY 也是可以的 另外XXX通常取一个长一点的名字，避免与其他重复

#define A #define B 10  其中 A 表示 A 被定义了。但是被定义为空。 B 表示 B 被定义了，而且被定义为 10.  A 一般用在 #ifdef 中，或者用在宏函数中。

什么都没有 .....


Question: 通过指针引用数组 C语言 STM32串口发送程序 函数调用

bug： 指针访问少一字节，而且越界了  *(pucStr++)  中间的括号保证了，上来就偏移到第2个元素，而且会访问数组越界，就是最后一次循环！所以越界时段错误时就程序不行，每发生段错误，那么程序可能就跑起来了，这将是随即的

你重启什么软件，就成功了。两个函数应该是没区别的。

泥煤啊~~~~~~把有关的软件都关了，从新启动就好啦。为什么这样子。。。。。

有没有帮忙的呀~~~~~~~

顶一下


Question: c++指针问题，求大神教教

最大值，最小值，平均值函数中for循环的条件全部都错了，这条件永远不可能满足，返回值不是数组下标8，数组是从0开始的，你冒泡法也错了，没有判断就直接交换了。

乍看一下你的代码，不是很理解你要怎么做，你主要犯了两个错误 1.数组越界：a[8]b[8] 2, for (p = b; p < p + 7; p++)每个函数你都调用了类似这样的东东

你这一会 7 一会 8 的，先想好你的数组里到底有几个元素。


Question: C语言 单向链表 清除操作问题

感谢大家的回复，虽然这个问题当时还是没有解决，不过现在我有了新的构建链表的方法，也就不深究之前的错误了

if ((curr = (Node *)malloc(sizeof(Node))) == NULL)

仅供参考：//带表头结点的单向链表 #include <stdio.h> #include <stdlib.h> #include <malloc.h> #include <time.h> struct NODE {     int          data;     struct NODE *next; } H,*head,*p,*q,*q1,*s1,*s2,*s3,*s4,*s; int i,j,k,n,t,m; int main() {     srand(time(NULL));      //填写头节点数据     H.data=-1;     H.next=NULL;     head=&H;      //创建10个节点的单链表     p=head;     for (i=0;i<10;i++) {         q=(struct NODE *)malloc(sizeof(struct NODE));         if (NULL==q) return 1;         q->data=rand()%100;//填写0..99的随机值         q->next=NULL;         p->next=q;         p=q;     }      //输出整个单链表     s=head->next;     while (1) {         if (NULL==s) {             printf("\n");             break;         }         printf("%02d->",s->data);         s=s->next;     }      //将值为5的结点插入到单链表的第k个结点前     k=3;     n=0;     p=head;     while (1) {         if (NULL==p) {             break;         }         n++;         if (k==n) {             q=(struct NODE *)malloc(sizeof(struct NODE));             if (NULL==q) return 1;             q->data=5;             q->next=p->next;             p->next=q;             break;         }         p=p->next;     }      //输出整个单链表     s=head->next;     while (1) {         if (NULL==s) {             printf("\n");             break;         }         printf("%02d->",s->data);         s=s->next;     }      //删除第k个节点     k=5;     n=0;     p=head;     while (1) {         if (NULL==p) {             break;         }         n++;         if (k==n) {             q=p->next;             if (q) {                 p->next=q->next;                 free(q);             }             break;         }         p=p->next;     }      //输出整个单链表     s=head->next;     while (1) {         if (NULL==s) {             printf("\n");             break;         }         printf("%02d->",s->data);         s=s->next;     }      //从小到大排序     for (p=head;p!=NULL && p->next!=NULL;p=p->next) {         for (q=p->next;q!=NULL && q->next!=NULL;q=q->next) {             if (p->next->data > q->next->data) {                  //交换data //              printf("swap %02d %02d\n",p->next->data,q->next->data); //              t=p->next->data;p->next->data=q->next->data;q->next->data=t;                  //或者                  //交换next //              printf("swap %02d %02d\n",p->next->data,q->next->data);                 s1=p->next;                 s2=p->next->next;                 s3=q->next;                 s4=q->next->next;                  if (s2!=s3) {                      p->next=s3;                     s3->next=s2;                      q->next=s1;                     s1->next=s4;                 } else {                      p->next=s3;                     s3->next=s1;                            q=s3;                     s1->next=s4;                 }                  //输出整个单链表 //              s=head->next; //              while (1) { //                  if (NULL==s) { //                      printf("\n"); //                      break; //                  } //                  printf("%02d->",s->data); //                  s=s->next; //              } //              getchar();             }         }     }      //输出整个单链表     s=head->next;     while (1) {         if (NULL==s) {             printf("\n");             break;         }         printf("%02d->",s->data);         s=s->next;     }      //将整个链表逆序     if (head->next!=NULL && head->next->next!=NULL) {         p=head->next;         q=p->next;         p->next=NULL;         while (1) {             q1=q->next;             q->next=p;             p=q;             q=q1;             if (NULL==q) break;         }         head->next=p;     }      //输出整个单链表     s=head->next;     while (1) {         if (NULL==s) {             printf("\n");             break;         }         printf("%02d->",s->data);         s=s->next;     }      //将单链表中前 m 个结点和后 n 个结点进行互换,m+n为链表总长10     m=4;     n=6;     k=0;     p=head;     while (1) {         if (NULL==p) {             break;         }         k++;         if (m+1==k) {             q=p;         }         s=p;         p=p->next;     }     s1=head->next;     head->next=q->next;     s->next=s1;     q->next=NULL;      //输出整个单链表     s=head->next;     while (1) {         if (NULL==s) {             printf("\n");             break;         }         printf("%02d->",s->data);         s=s->next;     }      //释放所有节点     p=head->next;     while (1) {         if (NULL==p) {             break;         }         q=p->next;         free(p);         p=q;     }      return 0; } //84->28->20->23->96->19->59->97->29->41-> //84->28->05->20->23->96->19->59->97->29->41-> //84->28->05->20->96->19->59->97->29->41-> //05->19->20->28->29->41->59->84->96->97-> //97->96->84->59->41->29->28->20->19->05-> //41->29->28->20->19->05->97->96->84->59-> //

你这个判断函数执行的情况是不是一个函数一个函数试的，我看你那个clear函数编译过不了啊，c语言要在函数前面声明变量，然后才是其他执行语句  Node *head = *plist;     Node *temp; 将这两句位置换下，编译看看

这是我从头添加节点的代码，除了调用free的函数外其他的打印、逆序、查找、判断大小和是否为空的操作都是正常的。  bool AddItem(List * plist) { 	Node *head = *plist; 	Node *curr; 	int num; 	printf("Please enter an integer: "); 	while (scanf("%d", &num) == 1) 	{ 		if ((curr = (Node *)malloc(sizeof(List))) == NULL) 		{ 			fprintf(stderr, "Could not allocate memory."); 			return false; 		} 		curr->item.n = num; 		if (head == NULL) 			curr->next = NULL; 		else 			curr->next = head; 		head = curr; 		printf("Enter next integer: "); 	} 	*plist = head; 	return true; }

create节点的时候没有调用malloc?

估计是next指针一直没有赋空的原因吧

另外再补充一下：删除某个节点时，调用free也会出现同样的问题。


额 看了下pthread_cacel的描述，cancel之后可以join，但是你对thread_result使用有问题，你应该是 if(thread_result == PTHREAD_CANCELED)          printf("Thread is cancel");  这么使用thread_result而不是打印。

cancel之后就不要再join线程了。

你如果硬要试试 函数 ret = pthread_cancel(id); 的话, 可以在前面再create一个线程, 线程中等待输入, 当输入特定字符时, 就执行ret = pthread_cancel(id);     而main中就直接  pthread_join(...)

到49行时, pthread_join(id,&thread_result); 里的id已经失效了, 当然会段错误了,   pthread_join 是用在线程未退出前调用,然后会阻塞在那的

printf("Thread jointed it returned:%ld", (long)thread_result);  // 把%s 改成 %ld


Question: 数组下标是表达式或常量，运行速度有影响吗？

这样的话，编译器确实没法优化， 不过DCTSIZE_7 = DCTSIZE * 7这种优化， 编译器开足马力的话，是可以自己做到的

引用 6 楼 lm_whales 的回复:[quote=引用 5 楼 u010451062 的回复:] [quote=引用 2 楼 lm_whales 的回复:] [quote=引用 1 楼 user-4 的回复:] 第一种编译时就会计算出0和56了，所以这两种编译出来的代码完全一样++ 这里没有优化，这两种代码本质上是相同的  一种区别是 DCTSIZE*0=0，DCTSIZE*7=56 编译器需要计算一下。 0，56做下标，编译器扫描到0，56 就知道这是0，56了 另外一种区别，是修改 0，56 是比较困难的特别是代码很长，有很多这样的代码。[/quote] 谢谢大家的回复。“修改 0，56 是比较困难”是什么意思？是说如果数组下标里的表达式比较复杂的情况吗？这样会有区别吗？[/quote]修改 0，56 是比较困难 是这是数字，或称魔数，直接写在代码中，如果因为某种原因，需要修改为 0，128 那就必须查找 0，56 一个一个修改 而 DCTSIZE 是个 字母表示的数据， 只需要修改定义那一处  就可以了， [/quote] 哦，这样我就明白了，还有一种情况是：DCTSIZE不是用#define定义，而是直接用变量申明的，如 int DCTSIZE；cin>>DCTSIZE; 这样的话，是不是编译器就没有办法优化了？由于用到了for循环，如果在循环外先在计算出 int DCTSIZE_7 = DCTSIZE * 7；这样是否会快一些呢?

引用 5 楼 u010451062 的回复:[quote=引用 2 楼 lm_whales 的回复:] [quote=引用 1 楼 user-4 的回复:] 第一种编译时就会计算出0和56了，所以这两种编译出来的代码完全一样++ 这里没有优化，这两种代码本质上是相同的  一种区别是 DCTSIZE*0=0，DCTSIZE*7=56 编译器需要计算一下。 0，56做下标，编译器扫描到0，56 就知道这是0，56了 另外一种区别，是修改 0，56 是比较困难的特别是代码很长，有很多这样的代码。[/quote] 谢谢大家的回复。“修改 0，56 是比较困难”是什么意思？是说如果数组下标里的表达式比较复杂的情况吗？这样会有区别吗？[/quote]修改 0，56 是比较困难 是这是数字，或称魔数，直接写在代码中，如果因为某种原因，需要修改为 0，128 那就必须查找 0，56 一个一个修改 而 DCTSIZE 是个 字母表示的数据， 只需要修改定义那一处  就可以了，

引用 2 楼 lm_whales 的回复:[quote=引用 1 楼 user-4 的回复:] 第一种编译时就会计算出0和56了，所以这两种编译出来的代码完全一样++ 这里没有优化，这两种代码本质上是相同的  一种区别是 DCTSIZE*0=0，DCTSIZE*7=56 编译器需要计算一下。 0，56做下标，编译器扫描到0，56 就知道这是0，56了 另外一种区别，是修改 0，56 是比较困难的特别是代码很长，有很多这样的代码。[/quote] 谢谢大家的回复。“修改 0，56 是比较困难”是什么意思？是说如果数组下标里的表达式比较复杂的情况吗？这样会有区别吗？

应该是没有影响的 ~

交给编译器了。两种代码编译器出来的运行程序是一样一样的

第一种编译时就会计算出0和56了，所以这两种编译出来的代码完全一样

引用 1 楼 user-4 的回复:第一种编译时就会计算出0和56了，所以这两种编译出来的代码完全一样++ 这里没有优化，这两种代码本质上是相同的  一种区别是 DCTSIZE*0=0，DCTSIZE*7=56 编译器需要计算一下。 0，56做下标，编译器扫描到0，56 就知道这是0，56了 另外一种区别，是修改 0，56 是比较困难的特别是代码很长，有很多这样的代码。


Question: 数组

全部相减取绝对值，结果存个新的数组，排个序，取最小的那个就够了

#include <stdio.h> #include <stdlib.h> #include <string.h>  #define INPUT_CHARATER 10  int find_max(int *diffret) {         int loop=0;         int min_number=128;         int min_pos=0;          for(loop=0;loop<INPUT_CHARATER;loop++)         {                 if(min_number>diffret[loop])                 {                         min_number=diffret[loop];                         min_pos=loop;                 }         }          return min_pos; }  int find_diff(char *testbuf) {         int diffnum;         int retnum=0;         char diffmark='D';         int diffret[INPUT_CHARATER+1]={0};          for(diffnum=0;diffnum<INPUT_CHARATER;diffnum++)         {                 diffret[diffnum]=abs(testbuf[diffnum] - diffmark);         }          return find_max(diffret); }  int main(void) {         char testbuf[128]={0};         int ret=0;          printf("please input the %d charaters:\n",INPUT_CHARATER);         fgets(testbuf,sizeof(testbuf)-1,stdin);          if(strlen(testbuf)<INPUT_CHARATER)         {                 printf("input charaters number error:%d\n",strlen(testbuf));                 return 1;         }          printf("the input buf is %s",testbuf);         ret=find_diff(testbuf);         printf("the nearly charater position is %d,value is %c\n",ret+1,testbuf[ret]);          return 0; } 结果： please input the 10 charaters: ABSDWQRQRQFQR the input buf is ABSDWQRQRQFQR the nearly charater position is 4,value is D  如果输入有空格或TAB，需要做额外处理

相减取绝对值，然后比较


Question: 数据结构，二叉树问题。帮我看看！

引用 18 楼 crcr 的回复: 在vc6调试没有问题，只是先序遍历少了一句话遍历右子树  createbitree 函数中的参数t是一个指针，你要对他赋值，就应该传入指针的指针 否则你在函数中修改的只是t的一个副本，而不是你主函数里的t  这个函数有返回值了，所以就可以是一级指针了，如果没有返回值，需要二级指针 谢谢！给‘t’赋值是不是就是楼上那种？

引用 20 楼 qq_26153041 的回复:1.楼主你的代码让人不忍直视，排版不合理  2.t = createbitree(t);按照你的想法，创建这个你要的结构，在函数内部创建了之后有两种办法在main（）函数中得到所创建的结构体指针，一种用t=createbitree()，t接受指针，第二种用createbitree(&t)这样的形式，第一种不多说，第二种的话，函数声明createbitree(bitree* s) 内部用*s=(bitnode*)malloc(sizeof(bitnode));这样你的main函数中就可以得到你在createbitree中构造的结构指针 小白一枚！请谅解！我在试试！不懂了，再请教你们！

引用 15 楼 paschen 的回复:[quote=引用 14 楼 TmacT 的回复:] [quote=引用 13 楼 paschen 的回复:] [quote=引用 11 楼 TmacT 的回复:] [quote=引用 10 楼 paschen 的回复:] [quote=引用 7 楼 TmacT 的回复:] [quote=引用 6 楼 paschen 的回复:] 就好比你一个交换函数如果写成：void swap(int a, int b)的话，并不能达到真正的交换，交换的只是一个副本，你这里同理  还是不明白！你可想而知我的知识有多差劲 吧[/quote]  主函数中bitree t = new bitnode;[/quote] 还是不行！[/quote]  你不是定义过bitnode了！ 那你写成 bitnode b; bitree t = &b;[/quote] 可以，但是出现了和9楼一样的提示！！是不是编译器的问题？[/quote]  你代码没具体看，不知你输入要怎么输入，可以自己点中断然后分析原因[/quote] 恩 好的！谢谢了！等会结贴给你们分！

引用 14 楼 TmacT 的回复:[quote=引用 13 楼 paschen 的回复:] [quote=引用 11 楼 TmacT 的回复:] [quote=引用 10 楼 paschen 的回复:] [quote=引用 7 楼 TmacT 的回复:] [quote=引用 6 楼 paschen 的回复:] 就好比你一个交换函数如果写成：void swap(int a, int b)的话，并不能达到真正的交换，交换的只是一个副本，你这里同理  还是不明白！你可想而知我的知识有多差劲 吧[/quote]  主函数中bitree t = new bitnode;[/quote] 还是不行！[/quote]  你不是定义过bitnode了！ 那你写成 bitnode b; bitree t = &b;[/quote] 可以，但是出现了和9楼一样的提示！！是不是编译器的问题？[/quote]  你代码没具体看，不知你输入要怎么输入，可以自己点中断然后分析原因

引用 13 楼 paschen 的回复:[quote=引用 11 楼 TmacT 的回复:] [quote=引用 10 楼 paschen 的回复:] [quote=引用 7 楼 TmacT 的回复:] [quote=引用 6 楼 paschen 的回复:] 就好比你一个交换函数如果写成：void swap(int a, int b)的话，并不能达到真正的交换，交换的只是一个副本，你这里同理  还是不明白！你可想而知我的知识有多差劲 吧[/quote]  主函数中bitree t = new bitnode;[/quote] 还是不行！[/quote]  你不是定义过bitnode了！ 那你写成 bitnode b; bitree t = &b;[/quote] 可以，但是出现了和9楼一样的提示！！是不是编译器的问题？

引用 11 楼 TmacT 的回复:[quote=引用 10 楼 paschen 的回复:] [quote=引用 7 楼 TmacT 的回复:] [quote=引用 6 楼 paschen 的回复:] 就好比你一个交换函数如果写成：void swap(int a, int b)的话，并不能达到真正的交换，交换的只是一个副本，你这里同理  还是不明白！你可想而知我的知识有多差劲 吧[/quote]  主函数中bitree t = new bitnode;[/quote] 还是不行！[/quote]  你不是定义过bitnode了！ 那你写成 bitnode b; bitree t = &b;

引用 8 楼 linzertling 的回复:[quote=引用 5 楼 TmacT 的回复:] [quote=引用 4 楼 linzertling 的回复:] [quote=引用 2 楼 TmacT 的回复:] 是的！但是不知道从哪开始给 t 赋值！  在main函数里边bitree t处赋值。你的creatbitree函数完全没必要输入t啊[/quote]  我在bitree t;下面赋值t=‘%d';吧creatbitree=t;删掉了！能运行了，但是在先序遍历哪里出错！是不是我的赋值有问题！还是我上面个的代码有问题！[/quote]  你在先序遍历程序里边的递归函数有问题，递归函数输入的是指针，而你输入的是t->lchild,这是一个数，并非指针，试试改成指针*（t->lchild），另外，你说运行到这里出错了，错误提示是什么？[/quote] 出现那个错误是不是和编译器有关？

引用 10 楼 paschen 的回复:[quote=引用 7 楼 TmacT 的回复:] [quote=引用 6 楼 paschen 的回复:] 就好比你一个交换函数如果写成：void swap(int a, int b)的话，并不能达到真正的交换，交换的只是一个副本，你这里同理  还是不明白！你可想而知我的知识有多差劲 吧[/quote]  主函数中bitree t = new bitnode;[/quote] 还是不行！

引用 7 楼 TmacT 的回复:[quote=引用 6 楼 paschen 的回复:] 就好比你一个交换函数如果写成：void swap(int a, int b)的话，并不能达到真正的交换，交换的只是一个副本，你这里同理  还是不明白！你可想而知我的知识有多差劲 吧[/quote]  主函数中bitree t = new bitnode;

引用 8 楼 linzertling 的回复:[quote=引用 5 楼 TmacT 的回复:] [quote=引用 4 楼 linzertling 的回复:] [quote=引用 2 楼 TmacT 的回复:] 是的！但是不知道从哪开始给 t 赋值！  在main函数里边bitree t处赋值。你的creatbitree函数完全没必要输入t啊[/quote]  我在bitree t;下面赋值t=‘%d';吧creatbitree=t;删掉了！能运行了，但是在先序遍历哪里出错！是不是我的赋值有问题！还是我上面个的代码有问题！[/quote]  你在先序遍历程序里边的递归函数有问题，递归函数输入的是指针，而你输入的是t->lchild,这是一个数，并非指针，试试改成指针*（t->lchild），另外，你说运行到这里出错了，错误提示是什么？ [/quote] 图片是错误提示！改了之后还是不行！还是同样提示！

引用 5 楼 TmacT 的回复:[quote=引用 4 楼 linzertling 的回复:] [quote=引用 2 楼 TmacT 的回复:] 是的！但是不知道从哪开始给 t 赋值！  在main函数里边bitree t处赋值。你的creatbitree函数完全没必要输入t啊[/quote]  我在bitree t;下面赋值t=‘%d';吧creatbitree=t;删掉了！能运行了，但是在先序遍历哪里出错！是不是我的赋值有问题！还是我上面个的代码有问题！[/quote]  你在先序遍历程序里边的递归函数有问题，递归函数输入的是指针，而你输入的是t->lchild,这是一个数，并非指针，试试改成指针*（t->lchild），另外，你说运行到这里出错了，错误提示是什么？

引用 6 楼 paschen 的回复:就好比你一个交换函数如果写成：void swap(int a, int b)的话，并不能达到真正的交换，交换的只是一个副本，你这里同理  还是不明白！你可想而知我的知识有多差劲 吧

引用 4 楼 linzertling 的回复:[quote=引用 2 楼 TmacT 的回复:] 是的！但是不知道从哪开始给 t 赋值！  在main函数里边bitree t处赋值。你的creatbitree函数完全没必要输入t啊[/quote]  我在bitree t;下面赋值t=‘%d';吧creatbitree=t;删掉了！能运行了，但是在先序遍历哪里出错！是不是我的赋值有问题！还是我上面个的代码有问题！

引用 2 楼 TmacT 的回复:是的！但是不知道从哪开始给 t 赋值！  在main函数里边bitree t处赋值。你的creatbitree函数完全没必要输入t啊

是的！但是不知道从哪开始给 t 赋值！

不是提示你了吗，t没有初始化


Question: 二维数组中，输入5个人的3项科目成绩，如何计算并输出每一行每一列的平均分？

我的a[5][5]时表示5个学生，第一列是学号，最后一列是拿来装平均分的。所以才多了2列。 虽然C++我还不是很懂，但是根据你的我还是做出来了。谢谢。

本来只想给你写一个输出的，不过你代码看的我好蛋疼…… 帮你全部重写了一遍——用C++的方法，但你应该把cin和cout改成对应的就可以。 主要是看for的写法  // i是行数， j是列数。我这里是C++的格式，你自己改成printf吧，我不会用printf //另外说一句，你的a[5][5]我看的很蛋疼，5人3科你就a[5][3]啊，[3]是一个人的三科成绩，然后[5]是5个人 #include<iostream> using namespace std;  int main() { 	double total; //total用来计算总分的，除以列数就是该行的平均分，除行数就是该列的平均分 	int i, j; //先初始化行和列 	double a[5][3]; 	//以下是输入成绩的部分 	for (i = 0;i<5;i++) //注意，5个人，就小于5。下面的3科，就小于3，不是小于4，因为是0~4和0~2 	{ 		cout << "现在轮到输入第" << i + 1 << "个人的成绩了" << endl;	//换人的时候，提示 		for (j = 0;j < 3;j++) 		{ 			cout << "***输入他的第" << j + 1 << "科成绩："; 			cin >> a[i][j]; 		} 		cout << endl;	//换人的时候，换一行，看起来更清晰 	}   	//以下是计算平均分的部分，这是计算每个人的 	cout << "以下开始计算每个人的平均分：" << endl; 	for (i = 0;i < 5;i++) 	{ 		total = 0;	//每次换行的时候，总分清0，避免数据干扰 		for (j = 0;j < 3;j++) 		{ 			total = total + a[i][j];	//初始为0，每次都加当前的分数 		} 		cout << "第" << i + 1 << "个人的 " << j << " 科平均分是" << total / j << endl << endl; 	}  	//以下是计算每一科的 	for (j = 0;j < 3;j++) 	{ 		total = 0;	//每次换行的时候，总分清0，避免数据干扰 		for (i = 0;i < 5;i++) 		{ 			total = total + a[i][j];	//初始为0，每次都加当前的分数 		} 		cout << "第" << j+1 << "科的 " << i << " 个人平均分是" << total / i << endl << endl; 	}  	system("Pause"); 	return 0;  }


Question: 求大神帮忙 简单的电影院售票系统

先把基础打好！


Question: 文件操作问题

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


Question: 类型转换的问题

如果直接转换为char，编译器会出警告（长度不一样，指针一般是4字节或8字节，会损失精度）。  不过，这个示例先转换为int也有问题，在x64系统下，编译器也会警告。  应该先转换为long，这样在不同系统架构下就可以通用了： （char)(long)p

哈哈哈 客气客气~

引用 2 楼 hotxlf1 的回复:从你给出的程序中可以知道先前压入栈中的数据类型实际上是(void*)(int)exp[i]，是把char型通过int类型的过度  强制转换成void*，所以实际上是把exp[i]当作void*类型的形参压入栈了，因此  while( priority(exp[i]) <= priority((char)(int)LinkStack_Top(stack)) )中获取栈顶元素时就要反其道而行之，将栈顶的exp[i]  元素回归到char型。这里选用int型作为过渡转换的类型的原因可能是因为指针类型void*和int型所占内存相同，而int和char是可以进  行隐式转换的，因此即使这里你把（char）去除也不会影响程序的正常运行的~~~  这位老师回答的真好


Question: 求大神找错，单链表的建立及排序

引用 6 楼 adusuccessfully 的回复:[quote=引用 5 楼 Node_L 的回复:] [quote=引用 4 楼 paschen 的回复:] 你主函数中的La是个指针，都没分配空间，你就在函数中写： L->data=-1; L->next=cur; 当然有问题！ 嗯嗯，谢谢，还有就是 排序exit（0）那里错了[/quote]  请教楼主排序exit（0）错在哪里了呢？能附上修改后的吗？学习下~~[/quote]  /*在以单链表表示的正整数的有序集合上，实现集合的并、交和差运算。 基本要求：     （1）用单链表存储集合中的数据；     （2）对单链表中的数据进行排序。 */ #include<stdio.h> #include<stdlib.h> #include<time.h>  typedef struct LNode{ 	int data; 	struct LNode *next; }LNode,*LinkList;  void CreateLinkList(LinkList &L,int n){//尾插法建立单向链表,头结点不用  	LinkList cur,pNew; 	int i; 		 	srand(time(0)); 	 	L=cur=NULL;  	for(i=0;i<=n;i++){ 		pNew=(LinkList)malloc(sizeof(LNode)); 		pNew->data=rand()%90+10;				//产生出随机数作为集合内元素 		 		if(i==0){ 			L=cur=pNew; 			L->data=-1; 		} 		else{ 			cur->next=pNew; 			cur=pNew; 		} 	} 	cur->next=NULL;  }  int QuickSort(LinkList &L,LinkList tail){   //单链表递归快速排序 	LinkList mid,p,q,m; 	int key; 	 	if (L->next==tail || L->next->next==tail) 		return -1;  	mid=L->next; 	p=L; 	q=mid; 	key=mid->data; 	m=mid->next; 	 	while (m!=tail){ 		if (m->data<key) 			p=p->next=m; 		else 			q=q->next=m; 		m=m->next; 	}  	p->next = mid; 	q->next = tail;  	QuickSort(L,mid); 	QuickSort(mid,tail);  	return 0; }  void Print(LinkList L){//  输出集合 	LinkList p;  	p=L->next;; 	while(p){ 		printf("%d\t",p->data); 		p=p->next; 	} 	printf("\n"); }  void AddList(LinkList La,LinkList Lb){    //求并集并输出 	LinkList Lc; 	LinkList cur,la,lb,ln;  	Lc=cur=(LinkList)malloc(sizeof(LNode)); 	la=La->next; 	lb=Lb->next;  	while(la && lb){ 		if(la->data<lb->data){ 			ln=(LinkList)malloc(sizeof(LNode)); 			ln->data=la->data; 			cur->next=ln; 			cur=ln; 			la=la->next; 		} 		else if(la->data==lb->data){ 			ln=(LinkList)malloc(sizeof(LNode)); 			ln->data=la->data; 			cur->next=ln; 			cur=ln; 			la=la->next; 			lb=lb->next; 		} 		else{ 			ln=(LinkList)malloc(sizeof(LNode)); 			ln->data=lb->data; 			cur->next=ln; 			cur=ln; 			lb=lb->next; 		} 	} 	while(la){ 		ln=(LinkList)malloc(sizeof(LNode)); 		ln->data=la->data; 		cur->next=ln; 		cur=ln; 		la=la->next; 	} 	while(lb){ 		ln=(LinkList)malloc(sizeof(LNode)); 		ln->data=lb->data; 		cur->next=ln; 		cur=ln; 		lb=lb->next; 	} 	cur->next=NULL; 	 	Print(Lc); }  void JiaoList(LinkList La,LinkList Lb){ 	LinkList Lc,la,lb,ln,cur;  	Lc=cur=(LinkList)malloc(sizeof(LNode)); 	la=La->next; 	lb=Lb->next; 	while(la && lb){ 		if(la->data<lb->data) 			la=la->next; 		else if(la->data==lb->data){ 			ln=(LinkList)malloc(sizeof(LNode)); 			ln->data=la->data; 			cur->next=ln; 			cur=ln; 			la=la->next; 			lb=lb->next; 		} 		else 			lb=lb->next; 	} 		cur->next=NULL; 		Print(Lc); }  void ChaList(LinkList La,LinkList Lb){ 	LinkList Lc,la,lb,cur,ln;  	Lc=cur=(LinkList)malloc(sizeof(LNode)); 	la=La->next; 	lb=Lb->next; 	 	while(la && lb){ 		if(la->data<lb->data){ 			ln=(LinkList)malloc(sizeof(LNode)); 			ln->data=la->data; 			cur->next=ln; 			cur=ln; 			la=la->next; 		} 		else if(la->data==lb->data){ 			la=la->next; 			lb=lb->next; 		} 		else 			lb=lb->next; 	} 	while(la){ 		ln=(LinkList)malloc(sizeof(LNode)); 		ln->data=la->data; 		cur->next=ln; 		cur=ln; 		la=la->next; 	} 	cur->next=NULL; 	Print(Lc); }  int main(){ 	LinkList La,Lb; 	int na,nb;  	printf("请输入第一个集合的元素数目\n"); 	scanf("%d",&na); 	CreateLinkList(La,na);  	printf("请输入第二个集合的元素数目\n"); 	scanf("%d",&nb); 	CreateLinkList(Lb,nb);  	QuickSort(La,NULL); 	QuickSort(Lb,NULL); 	Print(La); 	Print(Lb);  	printf("并集为：\n"); 	AddList(La,Lb);  	printf("交集为：\n"); 	JiaoList(La,Lb);  	printf("差集为：\n"); 	ChaList(La,Lb);  	return 0; }

引用 5 楼 Node_L 的回复:[quote=引用 4 楼 paschen 的回复:] 你主函数中的La是个指针，都没分配空间，你就在函数中写： L->data=-1; L->next=cur; 当然有问题！ 嗯嗯，谢谢，还有就是 排序exit（0）那里错了[/quote]  请教楼主排序exit（0）错在哪里了呢？能附上修改后的吗？学习下~~

仅供参考：//带表头结点的单向链表 #include <stdio.h> #include <stdlib.h> #include <malloc.h> #include <time.h> struct NODE {     int          data;     struct NODE *next; } H,*head,*p,*q,*q1,*s1,*s2,*s3,*s4,*s; int i,j,k,n,t,m; int main() {     srand(time(NULL));      //填写头节点数据     H.data=-1;     H.next=NULL;     head=&H;      //创建10个节点的单链表     p=head;     for (i=0;i<10;i++) {         q=(struct NODE *)malloc(sizeof(struct NODE));         if (NULL==q) return 1;         q->data=rand()%100;//填写0..99的随机值         q->next=NULL;         p->next=q;         p=q;     }      //输出整个单链表     s=head->next;     while (1) {         if (NULL==s) {             printf("\n");             break;         }         printf("%02d->",s->data);         s=s->next;     }      //将值为5的结点插入到单链表的第k个结点前     k=3;     n=0;     p=head;     while (1) {         if (NULL==p) {             break;         }         n++;         if (k==n) {             q=(struct NODE *)malloc(sizeof(struct NODE));             if (NULL==q) return 1;             q->data=5;             q->next=p->next;             p->next=q;             break;         }         p=p->next;     }      //输出整个单链表     s=head->next;     while (1) {         if (NULL==s) {             printf("\n");             break;         }         printf("%02d->",s->data);         s=s->next;     }      //删除第k个节点     k=5;     n=0;     p=head;     while (1) {         if (NULL==p) {             break;         }         n++;         if (k==n) {             q=p->next;             if (q) {                 p->next=q->next;                 free(q);             }             break;         }         p=p->next;     }      //输出整个单链表     s=head->next;     while (1) {         if (NULL==s) {             printf("\n");             break;         }         printf("%02d->",s->data);         s=s->next;     }      //从小到大排序     for (p=head;p!=NULL && p->next!=NULL;p=p->next) {         for (q=p->next;q!=NULL && q->next!=NULL;q=q->next) {             if (p->next->data > q->next->data) {                  //交换data //              printf("swap %02d %02d\n",p->next->data,q->next->data); //              t=p->next->data;p->next->data=q->next->data;q->next->data=t;                  //或者                  //交换next //              printf("swap %02d %02d\n",p->next->data,q->next->data);                 s1=p->next;                 s2=p->next->next;                 s3=q->next;                 s4=q->next->next;                  if (s2!=s3) {                      p->next=s3;                     s3->next=s2;                      q->next=s1;                     s1->next=s4;                 } else {                      p->next=s3;                     s3->next=s1;                            q=s3;                     s1->next=s4;                 }                  //输出整个单链表 //              s=head->next; //              while (1) { //                  if (NULL==s) { //                      printf("\n"); //                      break; //                  } //                  printf("%02d->",s->data); //                  s=s->next; //              } //              getchar();             }         }     }      //输出整个单链表     s=head->next;     while (1) {         if (NULL==s) {             printf("\n");             break;         }         printf("%02d->",s->data);         s=s->next;     }      //将整个链表逆序     if (head->next!=NULL && head->next->next!=NULL) {         p=head->next;         q=p->next;         p->next=NULL;         while (1) {             q1=q->next;             q->next=p;             p=q;             q=q1;             if (NULL==q) break;         }         head->next=p;     }      //输出整个单链表     s=head->next;     while (1) {         if (NULL==s) {             printf("\n");             break;         }         printf("%02d->",s->data);         s=s->next;     }      //将单链表中前 m 个结点和后 n 个结点进行互换,m+n为链表总长10     m=4;     n=6;     k=0;     p=head;     while (1) {         if (NULL==p) {             break;         }         k++;         if (m+1==k) {             q=p;         }         s=p;         p=p->next;     }     s1=head->next;     head->next=q->next;     s->next=s1;     q->next=NULL;      //输出整个单链表     s=head->next;     while (1) {         if (NULL==s) {             printf("\n");             break;         }         printf("%02d->",s->data);         s=s->next;     }      //释放所有节点     p=head->next;     while (1) {         if (NULL==p) {             break;         }         q=p->next;         free(p);         p=q;     }      return 0; } //84->28->20->23->96->19->59->97->29->41-> //84->28->05->20->23->96->19->59->97->29->41-> //84->28->05->20->96->19->59->97->29->41-> //05->19->20->28->29->41->59->84->96->97-> //97->96->84->59->41->29->28->20->19->05-> //41->29->28->20->19->05->97->96->84->59-> //

看起来 CreateLinkList就有问题 1) L没有分配内存, 加上L= (LinkList)malloc(sizeof(*L)); 2) 分配的cur没用,后面即使cur=new,但跟L这链没关系 调试一下代码就知道了

又要沉了吗………………

引用 4 楼 paschen 的回复:你主函数中的La是个指针，都没分配空间，你就在函数中写： L->data=-1; L->next=cur; 当然有问题！ 嗯嗯，谢谢，还有就是 排序exit（0）那里错了


Question: 求大神帮忙寻找c++、opencv处理视频的内存泄漏问题，实在实在找不出了

引用 1 楼 user-1的回复:    int main(int argc, char * argv[]) {     CvCapture* pCapture = cvCreateCameraCapture(0);     IplImage * pFrame;     IplImage *psrc;     IplImage *src = cvCreateImage(cvSize(700,700), IPL_DEPTH_8U,3);     IplImage *gsrc = cvCreateImage(cvGetSize(src), IPL_DEPTH_8U,1);           IplImage *dsw ;     IplImage *dst;     CvMemStorage *storage;     CvSeq *first_contour;           while(1)     {         psrc=cvQueryFrame(pCapture );                    cvResize(psrc,src,1);         cvCvtColor(src,gsrc,CV_BGR2GRAY);           dsw = cvCreateImage(cvGetSize(src), 8, 1);           dst = cvCreateImage(cvGetSize(src), 8, 3);           storage = cvCreateMemStorage(0);           first_contour = NULL;             //turn the src image to a binary image           //cvThreshold(src, dsw, 125, 255, CV_THRESH_BINARY_INV);           cvThreshold(gsrc, dsw, 100, 255, CV_THRESH_BINARY);             cvFindContours(dsw, storage, &first_contour, sizeof(CvContour), CV_RETR_LIST, CV_CHAIN_APPROX_SIMPLE);           cvZero(dst);           int cnt = 0;           for(; first_contour != 0; first_contour = first_contour->h_next)           {               cnt++;               CvScalar color = CV_RGB(rand()&255, rand()&255, rand()&255);               cvDrawContours(dst, first_contour, color, color, 0, 2, CV_FILLED, cvPoint(0, 0));               CvRect rect = cvBoundingRect(first_contour,0);             cvRectangle(dst, cvPoint(rect.x, rect.y), cvPoint(rect.x + rect.width, rect.y + rect.height),CV_RGB(255, 0, 0), 1, 8, 0);         }             printf("the num of contours : %d\n", cnt);             cvNamedWindow( "Source", 1 );           cvShowImage( "Source", src );             cvNamedWindow( "dsw", 1 );           cvShowImage( "dsw", dsw );             cvNamedWindow( "Components", 1 );           cvShowImage( "Components", dst );     		cvReleaseMemStorage(&storage); 		 		cvReleaseImage(&dsw);  // 应移至此处 		cvReleaseImage(&dst); // 应移至此处           char c=cvWaitKey(10);         if(c==27)             break;        }       cvDestroyWindow("Source");     cvDestroyWindow("dsw");     cvDestroyWindow("Components");       //~ cvReleaseImage(&pFrame); //cvReleaseCapture会释放，千万别自己处理     cvReleaseImage(&gsrc);     cvReleaseImage(&src);            //cvReleaseMemStorage(&storage);     cvReleaseCapture(&pCapture);       return 0;   }    大神，真的是无比感谢


Question: 帮忙看一下这两个位移操作实现了什么功能

SetBitsVal(uchar *ch, sint l, sint h, uchar val)：把*ch的从l到h位设置为val的值 比如SetBitsVal(&c, 2, 4, 0x02)，则c变成了 XXX010XX，X表示原值不变

逐步运行看是要实现什么


Question: 请大神解答把输入的字符串 前后颠倒位置的程序

引用 10 楼 qq_18888869的回复:[quote=引用 6 楼 u011133403 的回复:] 主要有两处问题，已注释。代码如下，望采纳，  #include<stdio.h> #include<string.h>  char *reverse(char*str);  int main() { 	char *str; 	char reservestr[256]; 	str = reservestr; 	printf("reverse string\n"); 	gets(str);  //str 你并没有分配内存，屏幕输入的字符串无处安放 	str=reverse(str); 	printf("reversed string\n"); 	puts(str);  	return 0; }  char*reverse(char*str) { 	int n; 	char temp,*pf,*pt;  	n=strlen(str); //这边应该使用strlen()获得字符串长度 	//n=sizeof(str)-1; 	for(pf=str,pt=&str[n-1];pf<pt;pf++,pt--) 	{ 		temp=*pf; 		*pf=*pt; 		*pt=temp; 	} 	return str; }   char reservestr[256]; 	str = reservestr;这个是用来分派地址的吗 谢谢你 [/quote] 其实就是使用栈预先申请好存放你输入字符串的内存，当然也可以用malloc() 为指针str申请动态内存。

引用 6 楼 u011133403 的回复:主要有两处问题，已注释。代码如下，望采纳，  #include<stdio.h> #include<string.h>  char *reverse(char*str);  int main() { 	char *str; 	char reservestr[256]; 	str = reservestr; 	printf("reverse string\n"); 	gets(str);  //str 你并没有分配内存，屏幕输入的字符串无处安放 	str=reverse(str); 	printf("reversed string\n"); 	puts(str);  	return 0; }  char*reverse(char*str) { 	int n; 	char temp,*pf,*pt;  	n=strlen(str); //这边应该使用strlen()获得字符串长度 	//n=sizeof(str)-1; 	for(pf=str,pt=&str[n-1];pf<pt;pf++,pt--) 	{ 		temp=*pf; 		*pf=*pt; 		*pt=temp; 	} 	return str; }   char reservestr[256]; 	str = reservestr;这个是用来分派地址的吗 谢谢你

#include<stdio.h> #include<string.h>   void zhuan(char *p);   int main(void) {     char str[80];     puts("a sting:");     gets(str);     zhuan(str);     puts(str);     return 0; } void zhuan(char *p) { 	int i,j,n;char temp; 	char *a=p; 	n=strlen(p)-1; 	for(i=n,j=0;i>=n/2&&j<=n/2;i--,j++) 	{ 		temp=*(p+i); 		*(p+i)=*(p+j); 		*(p+j)=temp; 	} }

#include <stdio.h> #include <stdlib.h>  char *reverse(char *str);   int main() {     char str[256] = { 0 };     printf("reverse string\n");     gets(str);     reverse(str);     printf("reversed string\n");     puts(str);       return 0; }   char *reverse(char *str) {     int i = 0;     int l = strlen(str);     int n = l >> 1; // l / 2     while (i < n) {         int t = i++;         int s = l - i;         char c = str[t];         str[t] = str[s];         str[s] = c;     }     return str; }引用 5 楼 paschen 的回复:qq_18888869  这个QQ号好啊然而这并不是QQ号，或许只是CSDN给QQ登录的用户分配的一个默认id。你没发现所有QQ登录的用户都是“qq_8个数字”结尾吗？为什么都是8位的？明显不是QQ号。

还是把这句蹩脚的str=reverse(str);也换了吧 reverse(str );

qq_18888869  这个QQ号好啊

#include<stdio.h> #include<string.h>  char *reverse(char*str ,int n);  int main() {     char *str; 	int n;     printf("reverse string\n"); 	str=new char[100];     gets(str); 	n=strlen(str);     str=reverse(str,n);     printf("reversed string");     puts(str); 	     return 0; }   char*reverse(char*str, int n) {      char temp,*pf,*pt;       //n=strlen(str);     /*n=sizeof(str)-1;     for(pf=str,pt=&str[n-1];pf<pt;pf++,pt--)     {         temp=*pf;         *pf=*pt;         *pt=temp;     }     return str;*/  	for(pf=str,pt=&str[n-1];pf<pt;pf++,pt--)     {         temp=*pf;         *pf=*pt;         *pt=temp;     }     return str;  } 可以了

int main() {     char  str[100];

上代码！  #include<iostream> #include<string> void swap(char &a, char&b) { 	char c; 	c = a; 	a = b; 	b = c;	 } int main() { 	std::string s1 = "abcdefg"; 	for(int i = 0, j = s1.size() - 1; i < s1.size() / 2; i++ , j--) 	{ 		swap(s1[i],s1[j]); 	}  	std::cout<<s1<< std::endl; 	system("pause"); 	return 0; }

str只是个指针，没有分配内存啊！


Question: 有记忆功能的动态规划看不懂啊。。

仅供参考：//http://www.cnblogs.com/chinazhangjie/archive/2010/11/16/1878400.html //多边形游戏 //描述 //    一个多边形，开始有n个顶点。每个顶点被赋予一个正整数值，每条边被赋予一个运算符“+”或“*”。所有边依次用整数从1到n编号。 //    现在来玩一个游戏，该游戏共有n步： //    第1步，选择一条边，将其删除 //    随后n-1步，每一步都按以下方式操作： //    （1）选择一条边E以及由E连接着的2个顶点v1和v2； //    （2）用一个新的顶点取代边E以及由E连接着的2个顶点v1和v2，将顶点v1和v2的整数值通过边E上的运算得到的结果值赋给新顶点。 //    最后，所有边都被删除，只剩一个顶点，游戏结束。游戏得分就是所剩顶点上的整数值。那么这个整数值最大为多少？ //输入 //    第一行为多边形的顶点数n（n ≤ 20），其后有n行，每行为一个整数和一个字符， //    整数为顶点上的正整数值，字符为该顶点到下一个顶点间连边上的运算符“+”或“*” //    （最后一个字符为最后一个顶点到第一个顶点间连边上的运算符）。 //输出 //    输出仅一个整数，即游戏所计算出的最大值。 //样例输入 //4 //4 * //5 + //5 + //3 + //样例输出 //70 // //分析： //最优子结构性质 //按照顺时针顺序，多边形和顶点的顺序可以写成： //  op[1], v[1], op[2], v[2], …, op[n], v[n] //在所给多边形中，从顶点i(1 <= i <= n)开始，长度为j(链中有j个顶点)的顺时针链p(i，j) 可表示为 //v[i], op[i+1], v[i+1],…, op[i+j-1], v[i+j-1] // //如果这条链在op[i + s]处进行最后一次合并运算(1 <= s <= j-1)，则可在op[i+s]处将链分割为2个子链： // //从i开始长度为s的链：  p(i，s) //从i + s开始，长度为j - s的链：p(i + s，j-s)。 //设: //m1是对子链p(i，s)的任意一种合并方式得到的值，而a和b分别是在所有可能的合并中得到的最小值和最大值。 // //m2是p(i+s，j-s)的任意一种合并方式得到的值，而c和d分别是在所有可能的合并中得到的最小值和最大值。 // //依此定义有a <= m1 <= b，c <= m2 <= d // //(1)当op[i+s] = ‘+’时，显然有a + c <= m <= b + d // //(2)当op[i+s] = ’*’时，有 // //min {ac，ad，bc，bd} <= m <= max {ac，ad，bc，bd} //换句话说，主链的最大值和最小值可由子链的最大值和最小值得到。 #include <windows.h> #include <stdio.h> #include <string.h> #include <conio.h> #include <locale.h> int n; char o[21];//op int  d[21];//vertex data int maxv; struct SEGINFO {//阶段信息     int maxv;     int minv; } sg[21][21],si; int X,Y; void getXY() {     CONSOLE_SCREEN_BUFFER_INFO csbi;     GetConsoleScreenBufferInfo(GetStdHandle(STD_OUTPUT_HANDLE),&csbi);     X=csbi.dwCursorPosition.X;     Y=csbi.dwCursorPosition.Y; } void gotoXY(int x, int y) {     COORD coord = {x, y};     SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), coord); } 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); } void ClearCon() {     HANDLE hStdOut = GetStdHandle(STD_OUTPUT_HANDLE);     COORD coord = {0, 0};     DWORD count;     CONSOLE_SCREEN_BUFFER_INFO csbi;     if (GetConsoleScreenBufferInfo(hStdOut, &csbi)) {         FillConsoleOutputCharacter(hStdOut, (TCHAR) 32, csbi.dwSize.X * csbi.dwSize.Y, coord, &count);         FillConsoleOutputAttribute(hStdOut, csbi.wAttributes, csbi.dwSize.X * csbi.dwSize.Y, coord, &count);         SetConsoleCursorPosition(hStdOut, coord);     } } void show(char *p) {     int y,x;     static char ss[128];      for (y=1;y<n;y++) {         sprintf(ss,"%c",o[y]);         ConPrintAt(0,y,ss,1);         for (x=1;x<n;x++) {             sprintf(ss,"%2d ",sg[y][x].maxv);             ConPrintAt(x*3,y,ss,3);         }     }     sprintf(ss,"%-128s",p);     ConPrintAt(1,n,ss,128);     gotoXY(0,n); } void pmt(char *p) {     static char ss[128];      sprintf(ss,"%-128s",p);     ConPrintAt(1,n,ss,128);     gotoXY(0,n); } void getmaxmin(int i, int s, int j) {// 从i开始，长度为j，s为切分位置     int minL;     int maxL;     int minR;     int maxR;     int r;     int mm[4];     int vmin;     int vmax;     static char p[128];      minL=sg[i][s].minv;     maxL=sg[i][s].maxv;         sprintf(p,"总长j:%d 上开始i:%d,长度  s:%d,maxL:%d",j,i,s  ,maxL);pmt(p);getXY();gotoXY(s    *3,i);getch();gotoXY(X,Y);       r=(i+s-1)%(n-1)+1;     minR=sg[r][j - s].minv;     maxR=sg[r][j - s].maxv;     sprintf(p,"总长j:%d 下开始r:%d,长度j-s:%d,maxR:%d",j,r,j-s,maxR);pmt(p);getXY();gotoXY((j-s)*3,r);getch();gotoXY(X,Y);      if (o[r] == '+') {// 处理加法         si.minv=minL + minR;         si.maxv=maxL + maxR;    sprintf(p,"上下合并maxv:%d=maxL:%d + maxR:%d",si.maxv,maxL,maxR);pmt(p);getch();     } else {// 处理乘法         mm[0]=minL * minR;         mm[1]=minL * maxR;         mm[2]=maxL * minR;         mm[3]=maxL * maxR;         vmin=mm[0];         vmax=mm[0];         for (i=1;i<4;i++) {             if (mm[i]<vmin) vmin=mm[i];             if (mm[i]>vmax) vmax=mm[i];         }         si.minv=vmin;         si.maxv=vmax;           sprintf(p,"上下合并maxv:%d=maxL:%d * maxR:%d",si.maxv,maxL,maxR);pmt(p);getch();     } } void pg() {     int i,j,s;     static char p[128];      ClearCon();     for (i=1;i<n;i++) {         sg[i][1].maxv=d[i];         sg[i][1].minv=d[i];     }     show("init");getch();     for (j=2;j<n;j++) {//长度         for (i=1;i<n;i++) {//起点             for (s=1;s<j;s++) {//子切分位置                 getmaxmin(i,s,j);                 if (sg[i][j].minv > si.minv) sg[i][j].minv=si.minv;                  sprintf(p,"sg[开始i:%d][长度j:%d].maxv:%d < maxv=%d ?",i,j,sg[i][j].maxv,si.maxv);pmt(p);                 getXY();gotoXY(j*3,i);getch();gotoXY(X,Y);                 if (sg[i][j].maxv < si.maxv) {                     sg[i][j].maxv=si.maxv;                     show("");                     sprintf(p,"Yes, sg[开始i:%d][长度j:%d].maxv:%d <-- maxv=%d",i,j,sg[i][j].maxv,si.maxv);pmt(p);                     getXY();gotoXY(j*3,i);getch();gotoXY(X,Y);                 } else {                     sprintf(p,"sg[开始i:%d][长度j:%d].maxv:%d < maxv=%d ? No",i,j,sg[i][j].maxv,si.maxv);pmt(p);                     getch();                 }             }         }     }     sprintf(p,"规划完毕，下一步计算总maxv...");pmt(p);getch();     maxv=sg[1][n-1].maxv;     sprintf(p,"总maxv=sg[1][n-1].maxv:%d",maxv);pmt(p);     getXY();gotoXY((n-1)*3,1);getch();gotoXY(X,Y);     for (i=2;i<n;i++) {         sprintf(p,"总maxv:%d < sg[开始i:%d][长度n-1:%d].maxv:%d ?",maxv,i,n-1,sg[i][n-1].maxv);pmt(p);         getXY();gotoXY((n-1)*3,i);getch();gotoXY(X,Y);         if (maxv < sg[i][n-1].maxv) {             maxv=sg[i][n-1].maxv;             sprintf(p,"Yes,总maxv:%d <-- sg[开始i:%d][长度n-1:%d].maxv:%d",maxv,i,n-1,sg[i][n-1].maxv);pmt(p);             getXY();gotoXY((n-1)*3,i);getch();gotoXY(X,Y);         } else {             sprintf(p,"总maxv:%d < sg[开始i:%d][长度n-1:%d].maxv:%d ? No",maxv,i,n-1,sg[i][n-1].maxv);pmt(p);             getch();         }     }     sprintf(p,"计算出总maxv:%d",maxv);pmt(p);getch();     gotoXY(0,n+1); }  int main() {     int i;     char b[2];      setlocale(LC_ALL,"chs");     scanf("%d",&n);     for (i=1;i<=n;i++) {         scanf("%d%1s",&d[i],b);o[(i%n)+1]=b[0];     }     n++;     pg();//PolyGame     printf("%d\n",maxv);     return 0; } //4 //1 + //2 + //4 + //8 +

1) 自顶向下通常指的递归, 自底向上指的递推 2) 不知道V(1,2)是什么意思, 看伪码是除0行0列外都是计算出来的

类似自底向上动态规划算法法使用的表格.。。这句话该怎么理解


Question: 建立二叉树，怎么实现多组数据输入？

你应该至少要把问题描述一下

有人来帮解决吗？


Question: C语言,函数没有返回类型,形参没有类型,居然能编译通过?

老古董的写法了，不用多关心，知道就好了，已经不使用或很少使用了，编译器依然支持，保证向后的兼容

你孤陋寡闻了，现在还有很多开源代码的函数参数表是用你说的那种方式声明。

这段代码 没二十年也差不多了把

K&R  的标准写法， 有啥好奇怪的。  谁说只能用 a b 的， 想叫啥名字都可以。

难道又是从谭浩强的书中看到的？

叫老版本C函数的声明方法

形参声明列表在参数表后面，函数的最外层语句组大括号前面。

古董类型，最早的C就是这样的 无返回值类型缺省为 int

好像C是可以这样写的

C 很古老的函数声明语法，但现在依然被标准支持。

请大家帮帮忙


Question: C的fopen打开文件也可以用做数组？

总算搞明白了，跪谢！

引用 3 楼 libinden71 的回复:[quote=引用 2 楼 libinden71 的回复:] [quote=引用 1 楼 user-1 的回复:] name是要打开的文件名 那不加路径的话name这个文件在哪里？[/quote] 还有个问题fopen（“name”，“a+”）name+双引号和不+双引号的区别是什么？[/quote]  双引号是打开叫name的文件，不然是打开name这个变量里存的字符串为文件名的文件

引用 2 楼 libinden71 的回复:[quote=引用 1 楼 user-1 的回复:] name是要打开的文件名 那不加路径的话name这个文件在哪里？[/quote] 还有个问题fopen（“name”，“a+”）name+双引号和不+双引号的区别是什么？

引用 1 楼 user-1 的回复:name是要打开的文件名 那不加路径的话name这个文件在哪里？

name是要打开的文件名


Question: 关于二叉树的建立与输出，求教！

status biTreeCreate(biTreeNode *t){     char elemValue;     fflush(stdin);     scanf("%c",&elemValue);     if(elemValue=='#')         t=NULL;        if(t==NULL)         return FALSE;     else{             t=(biTreeNode*)malloc(sizeof(biTreeNode));             t->data=elemValue;             biTreeCreate(t->LChild);             biTreeCreate(t->RChild);         }            return TRUE; } 但是这里输入有个疑问，就是为什么当输入为字符时，他是连续输入完毕才接收，而不是输入一个字符回车一下，按道理是这样的，我想这个应该是缓冲区当回车时直接系统才接收

谢谢了，我结合了大家的回复，理解了为什么要用二级指针。 出现的问题不是因为递归，而是因为指针的问题。

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

#include <stdio.h> #include <malloc.h> #include <math.h> #include <stdlib.h> typedef char elemType; typedef enum{     FALSE=0,TRUE }status;  typedef struct binaryTreeNode{     elemType data;     struct binaryTreeNode *LChild;     struct binaryTreeNode *RChild; }biTreeNode;  //将树考虑成一个满二叉树，按照先序方式遍历树进入输入，空位用#填充  status biTreeCreate(biTreeNode **t){     char elemValue;     //fflush(stdin);     scanf("%c",&elemValue);     if(elemValue=='#')         *t=NULL;        if(*t==NULL)         return FALSE;     else{ 		*t=(biTreeNode*)malloc(sizeof(biTreeNode)); 		(*t)->data=elemValue; 		biTreeCreate(&((*t)->LChild)); 		biTreeCreate(&((*t)->RChild)); 	}            return TRUE; }  status biTreePreorderPrint(biTreeNode *t){     if(t==NULL)         return FALSE;     else{         printf("%c",t->data);         biTreePreorderPrint(t->LChild);         biTreePreorderPrint(t->RChild);     }     return TRUE; } void main(){     biTreeNode *t;     biTreeCreate(&t);     biTreePreorderPrint(t); } 已解决，看看指针方面的书籍，建议看看零基础学数据结构第二版， 多调试程序，

看看一级指针，二级指针，  为什么要用指针

你在biTreeCreate函数中对t分配了空间，可是此处的t并不是你主函数中的t，只是一个副本！


Question: C语言求图上每个点的偏心度，偏心度最小的是图的终点，求这个中心点

int d[MAXV][MAXV];// 两点最短路径 void floyd(){     for(int k=0;k<V;k++){         for(int i=0;i<V;i++)             for(int j=0;j<V;j++)                 d[i][j] =min(d[i][j],d[i][k]+d[k][j]);     } }

能做给我看看嘛

用Floyd行吗


Question: C语言如何将0,1,0,1类型的二进制流,写入二进制文件

size_t fwrite ( const void * ptr, size_t size, size_t count, FILE * stream );  Write block of data to stream Writes an array of count elements, each one with a size of size bytes, from the block of memory pointed by ptr to the current position in the stream.  The position indicator of the stream is advanced by the total number of bytes written.  Internally, the function interprets the block pointed by ptr as if it was an array of (size*count) elements of type unsigned char, and writes them sequentially to stream as if fputc was called for each byte.  Parameters  ptr     Pointer to the array of elements to be written, converted to a const void*. size     Size in bytes of each element to be written.     size_t is an unsigned integral type. count     Number of elements, each one with a size of size bytes.     size_t is an unsigned integral type. stream     Pointer to a FILE object that specifies an output stream.

写二进制用 fwrite 。


Question: 如何用C语言或者C++手动写一个远程监视另一台电脑屏幕的程序啊？

借个坑，请教个问题： 一个单链表，将链表从最后一个结点 依次间隔插入到从第一个结点之后，比如1->n->2->n-1.......，该怎么操作比较好

GetDesktopWindow  后创建一个相同大小的 离屏表面， 隔段时间往自己的表面上 bitblt 就是了， 要达到比较好的性能， 你应该用比较好的办法对图片做编码， 简单点的办法就对 两桢之间的数据做 差分， 对差分的数据做 gz , 把gz 的数据在网络上发送。  写了个简单的 demo 把桌面存成 png ， 大概就这个样子：  #include <windows.h> #include <stdio.h> #include <png.h>  #pragma comment (lib, "libpng-3.lib")  typedef struct { 	BITMAPINFOHEADER    bmiHeader; 	DWORD				R_mask, G_mask, B_mask; } BI_BITFIELDS_BITMAPINFO;  static void user_write_data(png_structp png_ptr, png_bytep data, png_size_t length) { 	fwrite(data, 1, length, (FILE*)png_get_io_ptr(png_ptr)); }  static void user_flush_data(png_structp png_ptr) {	 }  void save_png(const char* path, DWORD* pixels, int width, int height) { 	FILE *fp ; 	 	int  x , y;     png_structp png_ptr  = NULL;     png_infop   info_ptr = NULL; 	png_uint_32 bytes_per_row;     png_byte  **row_pointers = NULL; 	int pix_per_line = width; 	 	fp = fopen( path , "wb" ); 	if(NULL == fp) 		return;  	png_ptr  = png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL); 	if( NULL != png_ptr ) 		info_ptr = png_create_info_struct(png_ptr); 	 	if( NULL == info_ptr ) 	{ 		if( NULL != png_ptr ) 			png_destroy_write_struct(&png_ptr, NULL); 		fclose( fp ); 		return; 	} 	 	if (setjmp(png_jmpbuf(png_ptr))) { 		png_destroy_write_struct(&png_ptr, &info_ptr); 		fclose(fp); 		return;     } 	 	png_set_IHDR(png_ptr, 		info_ptr, 		width  , 		height , 		8, 		PNG_COLOR_TYPE_RGB, 		PNG_INTERLACE_NONE, 		PNG_COMPRESSION_TYPE_DEFAULT, 		PNG_FILTER_TYPE_DEFAULT); 	 	bytes_per_row = width * 3; 	row_pointers = (png_byte  **)png_malloc( png_ptr , height * sizeof(png_byte *) ); 	for( y = 0; y < height; ++y ) 	{ 		BYTE *row = (BYTE*)png_malloc(png_ptr, sizeof(BYTE) * bytes_per_row); 		row_pointers[y] = (png_byte *)row; 		for( x = 0; x < width; ++x ) 		{ 			DWORD	 pix = pixels[ y * pix_per_line + x ]; 			*row++ = (BYTE)(pix >> 16); 			*row++ = (BYTE)(pix >> 8); 			*row++ = (BYTE)(pix); 		} 	} 	 	png_set_write_fn(png_ptr,(png_voidp)fp,user_write_data,user_flush_data);     png_set_rows(png_ptr, info_ptr, row_pointers);     png_write_png(png_ptr, info_ptr, PNG_TRANSFORM_IDENTITY, NULL); 	     for (y = 0; y < height; y++) { 		png_free(png_ptr, row_pointers[y]);     }     png_free(png_ptr, row_pointers); 	     png_destroy_write_struct(&png_ptr, &info_ptr);     fclose(fp);     }  int main() { 	int i; 	HDC   hDCOffScreen = NULL; 	HBITMAP hBmpOffScr = NULL, hOldBmp = NULL; 	DWORD* pixels = NULL; 	DWORD width, height; 	char  path[300];  	BI_BITFIELDS_BITMAPINFO	bmi; 	BITMAPINFOHEADER *lpInfoh; 	RECT rct; 	HWND hWnd = GetDesktopWindow(); 	HDC  hDC  = GetDC(hWnd);  	GetClientRect(hWnd, &rct); 	width = rct.right - rct.left; 	height = rct.bottom - rct.top; 	lpInfoh = &bmi.bmiHeader;	 	lpInfoh->biSize = sizeof(BITMAPINFOHEADER); 	lpInfoh->biWidth = width; 	lpInfoh->biHeight = height * -1; 	lpInfoh->biPlanes = 1; 	lpInfoh->biBitCount = 8 * 4;		/*  */ 	lpInfoh->biCompression = BI_BITFIELDS;	 	lpInfoh->biSizeImage = 0; 	lpInfoh->biXPelsPerMeter = 0; 	lpInfoh->biYPelsPerMeter = 0; 	lpInfoh->biClrUsed = 0; 	lpInfoh->biClrImportant = 0;	 	bmi.R_mask = 0xFF0000;  	bmi.G_mask = 0x00FF00; 	bmi.B_mask = 0x0000FF;  	hBmpOffScr = CreateDIBSection(hDC, (BITMAPINFO*)&bmi, DIB_RGB_COLORS, (VOID**)&pixels, NULL, 0); 	hDCOffScreen = CreateCompatibleDC(hDC); 	hOldBmp = (HBITMAP)SelectObject(hDCOffScreen, hBmpOffScr);  	for(i = 0; i < 10; ++i) 	{ 		DWORD dtTick = GetTickCount(), dtTick2; 		BitBlt(hDCOffScreen, 0, 0, width, height, hDC, 0, 0, SRCCOPY); 		dtTick2 = GetTickCount(); 		sprintf(path, "screen%d.png", i); 		save_png(path, pixels, width, height); 		printf("Time used : %d %d\n", dtTick2 - dtTick, GetTickCount() - dtTick); 		Sleep(1000); 	}  	/* Release XXXX */  return 0; }

找一个开源远程监视项目参考之。

你先打好基础，会用网络编程收发数据就行，目标主机不断把桌面图片发送过来

人工顶一下，来人啊


Question: c语言 成绩管理系统问题

你好歹也加下格式在发嘛，这个看着也太累了

void nrank(int n, int grade[N], long num[N])  最外层少了个} 加上就好了！

#include <stdio.h> #include <stdlib.h> #pragma warning (disable :4996) #define N 30  void menu(); void input(int *p, long num[N]); void sum(int n, int grade[N]); void grank(int n, int grade[N], long num[N]); void nrank(int n, int grade[N], long num[N]); main() { 	long num[N]; 	int n, grade[N], a; 	menu();  	scanf("%d", &a); 	while (a != 0) 	{  		if (a == 1) 		{  			input(&n, num, grade); 			system("cls");  			menu(); 		}  		if (a == 2) 		{ 			sum(n, grade); 			system("cls"); 			menu(); 		}  		if (a == 3) 		{ 			grank(n, grade, num); 			system("cls");  			menu(); 		} 		if (a == 4) 		{ 			nrank(n, grade, num); 			system("cls"); 			menu(); 		}  		scanf("%d", &a);  	}  } void menu() { 	printf("1.输入记录\n");  	printf("2.计算总分和平均分\n");  	printf("3.按成绩由高到低排出名次表\n");  	printf("4.按学号由小到大排出成绩表\n");  	printf("按序号选择功能\n"); } void menu1() { 	printf("0.返回主菜单"); }  void input(int *p, long num[N], int grade[N]) { 	int i, amd; 	printf("输入人数"); 	scanf("%d", p);  	for (i = 0; i<*p; i++) 	{ 		printf("输入学号"); 		scanf("%ld", &num[i]); 		printf("输入成绩"); 		scanf("%d", &grade[i]); 	} 	menu1(); 	scanf("%d", &amd); }  void sum(int n, int grade[N]) { 	int j, k = 0, amd; 	for (j = 0; j<n; j++) 	{ 		k = k + grade[j]; 	} 	printf("总成绩：%d\n平均分：%d\n", k, k / n); 	menu1(); 	scanf("%d", &amd); } void grank(int n, int grade[N], long num[N]) { 	int x, y, h, g, q, amd; 	for (x = 0; x<n - 1; x++) 	{ 		for (y = 0; y<n - x; y++) 		{ 			if (grade[y]<grade[y + 1]) 			{ 				h = grade[y]; 				grade[y] = grade[y + 1]; 				grade[y + 1] = h; 				q = num[y]; 				num[y] = num[y + 1]; 				num[y + 1] = q;  			} 		}  	} 	for (g = 0; g<n; g++) 	{ 		printf("%ld\t%d\n", num[g], grade[g]); 	} 	menu1(); 	scanf("%d", &amd); }  void nrank(int n, int grade[N], long num[N]) { 	int w, e, u, o, s, amd; 	for (w = 0; w < n - 1; w++) 	{ 		for (e = 0; e < n - w; e++) 		{ 			if (num[e] > num[e + 1]) 			{ 				o = num[e]; 				num[e] = num[e + 1]; 				num[e + 1] = o; 				s = grade[e]; 				grade[e] = grade[e + 1]; 				grade[e + 1] = s; 			} 		} 	} 	for (u = 0; u < n; u++) 	{ 		printf("%ld\t%d\n", num[u], grade[u]); 	} 	menu1(); 	scanf("%d", &amd); }          //少了这个}了，最后一行 。代码运行没错误！

为何木有人

贴吧求助，度娘直接给我删了


Question: 数组中，输出成绩人数最后显示叠加。我要的结果是不叠加。请大神帮忙

一楼说的对，每个单独计数，不能用一个count.

哥们，你想统计各成绩段的人数，不分别设count1，count2等等之类的吗

2.0修订版。
#include <stdio.h>
int main(void){
        int a[20]; //a数组有20个元素

int i,e,f,g;
printf("请输入20个学生的成绩（0<=a[i<=100）：\n");
e=0;
f=0;
g=0;
for(i=0;i<20;i++){
scanf("%d",&a[i]);
}
    for(i=0;i<20;i++){
     if (a[i]>=80 && a[i]<=100) printf("%4d",a[i]);
     if (a[i]>=80 && a[i]<=100) e++;
    }
    printf("优秀人数：%d\n",e);
    for(i=0;i<20;i++){
     if (a[i]>=60 && a[i]<80) printf("%4d",a[i]);
     if (a[i]>=60 && a[i]<80) f++;
    }
    printf("及格人数：%d\n",f);
    for(i=0;i<20;i++){
     if (a[i]>=0 && a[i]<60) printf("%4d",a[i]);
     if (a[i]>=0 && a[i]<60) g++;
    }
    printf("不及格人数：%d\n",g);
}

按照楼主的原代码改了一些，实现了Dev c++下优秀、及格和不及格的都不叠加，楼主可以试试： #include <stdio.h> int main(void){         int a[20]; //a数组有20个元素   int i,e,f,g;  printf("请输入20个学生的成绩（0<=a[i<=100）：\n"); e=0; f=0; g=0; for(i=0;i<20;i++){ scanf("%d",&a[i]); }     for(i=0;i<20;i++){     	if (a[i]>=80 && a[i]<=100) printf("%4d",a[i]);     	if (a[i]>=80 && a[i]<=100) e++;     }      printf("优秀人数：%d\n",e);     for(i=0;i<20;i++){     	if (a[i]>=60 && a[i]<=80) printf("%4d",a[i]);     	if (a[i]>=60 && a[i]<=80) f++;     }      printf("及格人数：%d\n",f);     for(i=0;i<20;i++){     	if (a[i]>=0 && a[i]<=60) printf("%4d",a[i]);     	if (a[i]>=0 && a[i]<=60) g++;     }      printf("不及格人数：%d\n",g); }


Question: lParam获取的鼠标位LOWORD,HIWORD有问题，有的时候点了没有显示

f 之后一直是 FALSE

引用 3 楼 qq_30519181 的回复:[quote=引用 1 楼 paschen 的回复:] 获得的是屏幕坐标，要转换成客户区坐标在操作！额。。。我修改了一下            point.x=LOWORD(lParam);    point.y=HIWORD(lParam);            ScreenToClient(hwnd,&point);    px=(point.x-115)/30+1;    py=(point.y-115)/30+1;可是改了之后更加不对了[/quote]   case WM_LBUTTONDOWN: 		px=(LOWORD(lParam)-115)/30+1; 		py=(HIWORD(lParam)-115)/30+1; 		if(px<=15&&py<=15&&f&&qizi[px][py]==0) 		{ 			qizi[px][py]=1; 			f=!f; 			InvalidateRect(hwnd,NULL,FALSE); 		} 		else 			MessageBeep(0);   		return 0;   我知道你什么原因了，之前代码没细看，你代码中if(px<=15&&py<=15&&f&&qizi[px][py]==0) 这句第二次一直是是FALSE，导致即使点击了左键，也不会运行qizi[px][py]=1;这一句

LRESULT CALLBACK WndProc(HWND hwnd,UINT message,WPARAM wParam,LPARAM lParam) {     static BOOL f=TRUE;     int x,px,py,y,i,j;     static int qizi[15][15];     RECT rect;     switch(message) {     case WM_CREATE:         for(i=0;i<15;i++)             for(j=0;j<15;j++)                 qizi[i][j]=0;         return 0;      case WM_LBUTTONDOWN:         px=(LOWORD(lParam)-115)/30+1;         py=(HIWORD(lParam)-115)/30+1;         if(px<=15&&py<=15&&f&&qizi[px][py]==0) {             qizi[px][py]=1;             f=!f;             InvalidateRect(hwnd,NULL,FALSE);         } else             MessageBeep(0);         return 0;      case WM_RBUTTONDOWN:         px=(LOWORD(lParam)-115)/30+1;         py=(HIWORD(lParam)-115)/30+1;         if(px<=15&&py<=15&&!f&&qizi[px][py]==0) {             qizi[px][py]=2;             f=!f;             InvalidateRect(hwnd,NULL,FALSE);         } else             MessageBeep(0);         return 0;      case WM_PAINT:         HDC hdc;         PAINTSTRUCT ps;         hdc=BeginPaint(hwnd,&ps);         HBRUSH hobrush,hbrush1,hbrush2;         hbrush1=CreateSolidBrush(RGB(0,0,0));         hbrush2=CreateSolidBrush(RGB(255,255,255));         for(x=0;x<15;x++) {             MoveToEx(hdc,100+30*x,100,NULL);             LineTo(hdc,100+30*x,520);             MoveToEx(hdc,100,100+30*x,NULL);             LineTo(hdc,520,100+30*x);         }         hobrush=SelectObject(hdc,hbrush1);         for(x=0;x<15;x++)             for(y=0;y<15;y++) {                 if(qizi[x][y]==1) {                     SelectObject(hdc,hbrush1);                     Ellipse(hdc,(100+30*x)-sr,(100+30*y)-sr,(100+30*x)+sr,(100+30*y)+sr);                 } else if(qizi[x][y]==2) {                     SelectObject(hdc,hbrush2);                     Ellipse(hdc,(100+30*x)-sr,(100+30*y)-sr,(100+30*x)+sr,(100+30*y)+sr);                 }             }         SelectObject(hdc,hobrush);         DeleteObject(hbrush2);         DeleteObject(hbrush1);         EndPaint(hwnd,&ps);         return 0;     case WM_DESTROY:         PostQuitMessage(0);         return 0;      }     return DefWindowProc(hwnd,message,wParam,lParam); }

DeleteObject The DeleteObject function deletes a logical pen, brush, font, bitmap, region, or palette, freeing all system resources associated with the object. After the object is deleted, the specified handle is no longer valid.   BOOL DeleteObject(   HGDIOBJ hObject   // handle to graphic object );   Parameters hObject  Handle to a logical pen, brush, font, bitmap, region, or palette.  Return Values If the function succeeds, the return value is nonzero.  If the specified handle is not valid or is currently selected into a device context, the return value is zero.   Windows NT: To get extended error information, callGetLastError.  Remarks Do not delete a drawing object (pen or brush) while it is still selected into a device context.  When a pattern brush is deleted, the bitmap associated with the brush is not deleted. The bitmap must be deleted independently.   Windows CE: The DeleteObject function returns false if the object is currently selected into a device context.  QuickInfo   Windows NT: Requires version 3.1 or later.   Windows: Requires Windows 95 or later.   Windows CE: Requires version 1.0 or later.   Header: Declared in wingdi.h.   Import Library: Use gdi32.lib.  See Also Device Contexts Overview, Device Context Functions, SelectObject

引用 1 楼 paschen 的回复:获得的是屏幕坐标，要转换成客户区坐标在操作！额。。。我修改了一下            point.x=LOWORD(lParam);    point.y=HIWORD(lParam);            ScreenToClient(hwnd,&point);    px=(point.x-115)/30+1;    py=(point.y-115)/30+1;可是改了之后更加不对了

获得的是屏幕坐标，要转换成客户区坐标在操作！


Question: 求一道编程作业题程序，不用数组和指针

分别求 AB , AC,  BC, ABC的最小公倍数 这四个值分别为 LAB, LAC, LBC, LABC  第一炮同时放：3* D - D* min(A, B) / LAB - D * min(B, C) / LBC - D * min(AC) / LAC + D * min(A, B, C) / LABC  第一炮不同时放：3* D - D* min(A, B) / LAB - D * min(B, C) / LBC - D * min(AC) / LAC + D * min(A, B, C) / LABC - 2  貌似都和楼主的要求不符，别人是要不用指针和数组，不过这个似乎有点难啊。

//甲、乙、丙三人同时放鞭炮，甲每隔A秒放一个，乙每隔B秒放一个，丙每隔C秒放一个，他们各自放D个。对任意给定的A、B、C和D，求能听到多少声鞭响。 #include <stdio.h> #include <stdlib.h> #include <malloc.h> int main() {     int A,B,C,D;     int maxABC,i,n;     char *p;     scanf("%d%d%d%d",&A,&B,&C,&D);     maxABC=A;     if (maxABC<B) maxABC=B;     if (maxABC<C) maxABC=C;     p=(char *)calloc(maxABC*D,sizeof(char));     for (i=0;i<D;i++) {         p[A*i]=1;         p[B*i]=1;         p[C*i]=1;     }     n=0;     for (i=0;i<maxABC*D;i++) if (p[i]) n++;     free(p);     printf("%d\n",n);     return 0; } //2 3 7 10 //23 //

分别求 AB , AC,  BC, ABC的最小公倍数 这四个值分别为 LAB, LAC, LBC, LABC  听到的次数就是  3* D - D* min(A, B) / LAB - D * min(B, C) / LBC - D * min(AC) / LAC + D * min(A, B, C) / LABC

弄错了，是每隔ABC秒放一个 共放D个 这样 每个时间间隔是1秒 D个最多放 D*max(A,B,C) 秒 各人 分别放 A*D秒，B*D秒，C*D秒 假设第一响在同一时间 那么甲 每隔A秒，乙每隔B秒，丙每隔C 会响一声鞭炮 如果三者或者两者同时在放，只能听到一声响。 如果A=B=C 那么只能听到 D 声响 如果 A,B,C 互不相等，并且互质并且D*A， 不等于 K*B,K*C,D*B亦然，D*C亦然，  那么可以听到 3D - 2 声响 如果有公因子，那么就会少一点 所以最少D 最多3D-2  至于编程设置三个变量表示每个人点放的鞭炮个数，设置一个数表示时间 每当A,B,C 秒各放一个鞭炮，听到 每秒有人放炮则听到一声响，无人则没听到最后统计一下听到几声响即可

简单点，按照一秒100 个瞬间算，每个瞬间可以放一个鞭炮 ---噢有点快 假设 ABCD都是100 的因子 那么 时间间隔为 1/100 秒 于是变成 甲乙丙丁，四人 各在 100 个时间间隔的任意一个时间间隔开始放鞭炮 不妨设 成顺序 的，甲 早于或等于 乙 早于或等于 丙 早于或等于 丁 然后每隔 100/A,100/B,100/C,100/D时间段 放一个鞭炮 每个鞭炮点房的时间点（1/100 秒）可以听到一声响

最少 一秒 D声 最多一秒 A+B+C+D声

有点象容斥原理, 最简单就是直接枚举, 一个循环搞定

这题就毛病，鞭炮几响的？100头还是一万头的，我都想削出题的

a=b=c 完了不就简单了


Question: 出现error C2065: 'setfont' : undeclared identifier报错该如何解决呢？

引用 1楼____________-------- 的回复:去查setfont的声明 作用范围就是不知道他的申明，我在百度上没查到

引用 2楼lm_whales 的回复:TC没有楷体，setfont 不是这个样子的吧？这是用VC6.0编译的结果。

TC没有楷体，setfont 不是这个样子的吧？

去查setfont的声明 作用范围


Question: 菜鸟求助，k1=1,k2=1,k3=1,if(k1&&k2&&k3==1)为什么程序总是直接跳过这个if判断？

//C++ Operators //  Operators specify an evaluation to be performed on one of the following: //    One operand (unary operator) //    Two operands (binary operator) //    Three operands (ternary operator) //  The C++ language includes all C operators and adds several new operators. //  Table 1.1 lists the operators available in Microsoft C++. //  Operators follow a strict precedence which defines the evaluation order of //expressions containing these operators.  Operators associate with either the //expression on their left or the expression on their right;    this is called //“associativity.” Operators in the same group have equal precedence and are //evaluated left to right in an expression unless explicitly forced by a pair of //parentheses, ( ). //  Table 1.1 shows the precedence and associativity of C++ operators //  (from highest to lowest precedence). // //Table 1.1   C++ Operator Precedence and Associativity // The highest precedence level is at the top of the table. //+------------------+-----------------------------------------+---------------+ //| Operator         | Name or Meaning                         | Associativity | //+------------------+-----------------------------------------+---------------+ //| ::               | Scope resolution                        | None          | //| ::               | Global                                  | None          | //| [ ]              | Array subscript                         | Left to right | //| ( )              | Function call                           | Left to right | //| ( )              | Conversion                              | None          | //| .                | Member selection (object)               | Left to right | //| ->               | Member selection (pointer)              | Left to right | //| ++               | Postfix increment                       | None          | //| --               | Postfix decrement                       | None          | //| new              | Allocate object                         | None          | //| delete           | Deallocate object                       | None          | //| delete[ ]        | Deallocate object                       | None          | //| ++               | Prefix increment                        | None          | //| --               | Prefix decrement                        | None          | //| *                | Dereference                             | None          | //| &                | Address-of                              | None          | //| +                | Unary plus                              | None          | //| -                | Arithmetic negation (unary)             | None          | //| !                | Logical NOT                             | None          | //| ~                | Bitwise complement                      | None          | //| sizeof           | Size of object                          | None          | //| sizeof ( )       | Size of type                            | None          | //| typeid( )        | type name                               | None          | //| (type)           | Type cast (conversion)                  | Right to left | //| const_cast       | Type cast (conversion)                  | None          | //| dynamic_cast     | Type cast (conversion)                  | None          | //| reinterpret_cast | Type cast (conversion)                  | None          | //| static_cast      | Type cast (conversion)                  | None          | //| .*               | Apply pointer to class member (objects) | Left to right | //| ->*              | Dereference pointer to class member     | Left to right | //| *                | Multiplication                          | Left to right | //| /                | Division                                | Left to right | //| %                | Remainder (modulus)                     | Left to right | //| +                | Addition                                | Left to right | //| -                | Subtraction                             | Left to right | //| <<               | Left shift                              | Left to right | //| >>               | Right shift                             | Left to right | //| <                | Less than                               | Left to right | //| >                | Greater than                            | Left to right | //| <=               | Less than or equal to                   | Left to right | //| >=               | Greater than or equal to                | Left to right | //| ==               | Equality                                | Left to right | //| !=               | Inequality                              | Left to right | //| &                | Bitwise AND                             | Left to right | //| ^                | Bitwise exclusive OR                    | Left to right | //| |                | Bitwise OR                              | Left to right | //| &&               | Logical AND                             | Left to right | //| ||               | Logical OR                              | Left to right | //| e1?e2:e3         | Conditional                             | Right to left | //| =                | Assignment                              | Right to left | //| *=               | Multiplication assignment               | Right to left | //| /=               | Division assignment                     | Right to left | //| %=               | Modulus assignment                      | Right to left | //| +=               | Addition assignment                     | Right to left | //| -=               | Subtraction assignment                  | Right to left | //| <<=              | Left-shift assignment                   | Right to left | //| >>=              | Right-shift assignment                  | Right to left | //| &=               | Bitwise AND assignment                  | Right to left | //| |=               | Bitwise inclusive OR assignment         | Right to left | //| ^=               | Bitwise exclusive OR assignment         | Right to left | //| ,                | Comma                                   | Left to right | //+------------------+-----------------------------------------+---------------+

引用 4 楼 paschen 的回复:==优先级高于&&  楼上正解

==优先级高于&&

k1&&k2&&k3==0 会被当作k1&&k2&&(k3==0) 解释

我题目写错了，是K1=0,K2=1,K3=1,程序直接跳过这句if((k1&&k2&&k3)==0)


Question: C语言输出对齐问题

#include <stdio.h> char *s[]={"12","123","12345","324","11234","2345"}; int i; int main() {     for (i=0;i<3;i++) printf("%-6s",s[i]);printf("\n");     for (i=3;i<6;i++) printf("%-6s",s[i]);printf("\n");     return 0; } //12    123   12345 //324   11234 2345 //

引用 3 楼 paschen 的回复:可以限定宽度 能不能给个代码?

引用 2 楼 Jammg 的回复:对于整数%5d 或者%-5d 如果是字符川怎么对齐?

每个输出后用转义字符\t

可以限定宽度

对于整数%5d 或者%-5d

输出就是下面这样的。 12    123       12345 324  11234  2345


Question: 函数调用问题 求高手帮忙看看 实在是不会改了

函数没声明就直接调用？把子函数放main函数后边，先声明后调用

VS 不支持 variable length array。 换个编译器吧。

数组类型必须编译时确定大小 int Max[n]; 这里n是一个变量，所以不行 如果一定只能是变量，可以考虑使用动态分配内存


Question: 【链表】链表输入输出函数都写好了，但是为什么我用主函数输出总是程序崩溃

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

这种问题可以用单步调试来找

2楼正解   自己学会用gdb跟代码

p2=p1=(struct student*)malloc(LEN);     scanf("num=%ld,score%.5f",&p1->num,&p1->score);  你却没有给 p1->next = null;  没有初始化指向的地方是未知的，当然会崩

出错地方点中断，分析什么原因导致的，不知你这程序要输入什么


Question: 函数编写问题，求大神指教一下哪里整错了

int IsPrimerNumber(int m) {     int i,k;       if((m==0)||(m==1))     {         return FALSE;     }     else         if(m!=0 && m!=1)         {             k=(int)sqrt(m);             for(i=2;i<=k;i++)             {                 if(m%i==0)                 {                     return FALSE;                 }             }             return TRUE;         } // ==>  这里没有返回值 }  分支有点乱，不要这样写。尽量简单

引用 6 楼 qq_33271984 的回复:额，谢谢了，我的算法有问题，但是改了之后还是有那个警告啊，我觉得每种情况都有返回值啊  你这样for循环只会执行一次，根本没基本执行第二次，循环内就返回了

#include<stdio.h> #include<math.h> #define TRUE 1 #define FALSE 0 int IsPrimerNumber(int m) { 	int i,k;  	if((m==0)||(m==1)) 	{ 		return FALSE; 	} 	else 		if(m!=0 && m!=1) 		{ 			k=(int)sqrt(m); 			for(i=2;i<=k;i++) 			{ 				if(m%i==0) 				{ 					return FALSE; 				} 			} 			return TRUE; 		} } void TestPrime(int iNum) { 	int i; 	for(i=0;i<=iNum;i++) 		if(IsPrimerNumber(i)==TRUE) 			printf("\n%d is a prime.",i); 		else 			printf("\n%d is not a prime.",i); } void main() { 	IsPrimerNumber(4); 	int iNum; 	scanf("%d",&iNum); 	TestPrime(iNum); }

#include<stdio.h> #include<math.h> #define TRUE 1 #define FALSE 0 int IsPrimerNumber(int m) { 	int i,k;  	if((m==0)||(m==1)) 	{ 		return FALSE; 	} 	else 		if(m!=0 && m!=1) 		{ 			k=(int)sqrt(m); 			for(i=2;i<k;i++) 			{ 				if(m%i!=0) 				{ 					return TRUE; 				} 				else 				{ 					return FALSE; 				} 			} 		} } void TestPrime(int iNum) { 	int i; 	for(i=0;i<=iNum;i++) 		if(IsPrimerNumber(i)==TRUE) 			printf("\n%d is a prime.",i); 		else 			printf("\n%d is not a prime.",i); } void main() { 	int iNum; 	scanf("%d",&iNum); 	TestPrime(iNum); } c(29) : warning C4715: 'IsPrimerNumber' : not all control paths return a value 这样还是有错啊

IsPrimerNumber不是所有路径有返回值

函数IsPrimerNumber只定义了m>1的时候的程序，当m=0,1的时候函数无法得知返回值，故而出错，你可以在 if语句外边加个return 0,这样就ok了

m == 0 时你看你的函数返回了个啥？


Question: 希望老师们能帮帮我梳理一下这个题的思路！谢谢

约瑟夫环，数组实现，超出取余

约瑟夫问题 http://blog.csdn.net/zhangxiangdavaid/article/details/25109205

这里已有答案：http://bbs.csdn.net/topics/391863637?page=1


Question: 求教

引用 1楼user-1 的回复: #include <windows.h> #include <stdio.h> #include <stdlib.h> #include <conio.h> #include <math.h> #include <time.h>  typedef struct _time { 	int seconds; 	int minutes; 	int hours; }TIME, *LPTime;  LPTime InitTime(LPTime time); void UpdateTime(LPTime time); void ShowTime(LPTime time); void delay(int i);  int main() { 	LPTime systemtime = 0;  	systemtime = InitTime(systemtime);  	for (;;) { 		UpdateTime(systemtime); 		ShowTime(systemtime); 		Sleep(100); 	} 	return 0; }  LPTime InitTime(LPTime time) { 	time = (LPTime)malloc(sizeof(TIME));  	if (!time) 	{ 		printf("Error!!!\n"); 		exit(0); 	}  	time->hours = 0; 	time->minutes = 0; 	time->seconds = 0; 	return time;  } void UpdateTime(LPTime time) { 	time->seconds++; 	if (time->seconds == 60) 	{ 		time->seconds = 0; 		time->minutes++; 	} 	if (time->minutes == 60) 	{ 		time->minutes = 0; 		time->hours++; 	} 	if (time->hours == 24) 	{ 		time->hours = 0; 	} }  void ShowTime(LPTime time) { 	printf("%02d:", time->hours); 	printf("%02d:", time->minutes); 	printf("%02d\r", time->seconds); } 我谢谢你，今天才看到。。我马上试试


Question: 两个关联页面的动态数据抓取

public string flightSearch(string oneway,string orgcity,string dstcity,string flightdate)         {             string Url = "https://www.urumqi-air.com/flight/searchflight!getFlights.action";             //string Referer = "https://www.urumqi-air.com/flight/searchflight.action?tripType="+oneway+"&orgCity1="+orgcity+"&dstCity1="+dstcity+"&flightdate1="+flightdate+"&flightdate2=";             string PostData = "<flight><tripType>"+oneway+"</tripType><orgCity1>"+orgcity+"</orgCity1><dstCity1>"+dstcity+"</dstCity1><flightdate1>"+flightdate+"</flightdate1><index>1</index></flight>";             string flights = post(Url, PostData);             return flights;         }   public string post(string url, string str)         {             HttpWebRequest req = (HttpWebRequest)HttpWebRequest.Create(url);             req.Method = "POST";             req.Host = "www.urumqi-air.com";             req.UserAgent = "Mozilla/5.0 (Windows NT 6.1; rv:41.0) Gecko/20100101 Firefox/41.0";             req.Accept = "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8";             //req.Referer = refer;             byte[] buf = Encoding.UTF8.GetBytes(str);             req.ContentLength = buf.Length;             using (Stream s = req.GetRequestStream())             {                 s.Write(buf, 0, buf.Length);             }             HttpWebResponse resp = (HttpWebResponse)req.GetResponse();             using (Stream s = resp.GetResponseStream())             {                 using (StreamReader sr = new StreamReader(s))                 {                     return sr.ReadToEnd();                 }             }         }

比如：http://www.urumqi-air.com/ 打开后选择搜索数据   点击搜索   跳转到另一个页面    获得跳转后的页码的数据  才学习这个  不怎么懂  希望具体的思路和操作问题给我解析一下    小弟感激不尽


Question: 关于C语言函数返回指向局部字符数组问题

这是一种不确定行为，你输出的值和函数中的一样只能说明他该值还未被其他值覆盖，如果你调用其他函数等，之前指针所指的内存可能就被其他数据覆盖了，所以不要返回局部变量的指针

错误的程序可以得到任何结果。包括你期望看到的和不期望看到的结果。


Question: Unicode UTF-8 gb2312 字符集

// UTF-8 编码字符理论上可以最多到 6个字节长，但目前全世界的所 // 有文字和符号种类加起来也只要编到 4个字节长就够了。 // 　　UTF-8 是以 8位（即 1个字节）为单元对原始码进行编码（注意一 // 点：这里所讲的原始码都是指Unicode码），并规定：多字节码（2个字 // 节以上才称为多字节）以转换后第1个字节起头的连续“1”的数目（这 // 些连续“1”称为标记位），表示转换成几个字节：“110”连续两个 // “1”，表示转换结果为2个字节，“1110”表示3个字节，而“11110” // 则表示4个字节……跟随在标记位之后的“0”，其作用是分隔标记位和 // 字符码位。第2～第4个字节的起头两个位固定设置为“10”，也作为标 // 记，剩下的6个位才做为字符码位使用。 // 　　这样，2字节UTF-8码剩下11个字符码位，可用以转换0080～07FF的 // 原始字符码，3字节剩下16个字符码位，可用以转换0800～FFFF的原始字 // 符码，由此类推。编码方式的模板如下： // // 原始码（16进制）　UTF－8编码（二进制） // -------------------------------------------- // 0000 - 007F       0xxxxxxx // 0080 - 07FF       110xxxxx 10xxxxxx // 0800 - FFFF       1110xxxx 10xxxxxx 10xxxxxx // …… // -------------------------------------------- // // 　　模板中的“x”表示字符码。 // 　　Ascii码＜007F，编为1个 // 字节的UTF－8码。汉字的 Unicode编码范围为0800－FFFF，所以被编为 // 3个字节的UTF－8码。 // 　　例如“汉”字的Unicode编码是6C49，6C49在0800-FFFF之间，所以 // 要用3个字节的模板：1110wwww 10xxxxyy 10yyzzzz。  //    6    C    4    9 // 0110 1100 0100 1001 // wwww xxxx yyyy zzzz //     wwww   xxxxyy   yyzzzz // 1110wwww 10xxxxyy 10yyzzzz。 // 11100110 10110001 10001001 //    E   6    B   1    8   9 //“汉”字的UTF-8编码是E6 B1 89

utf8 中文是 3 个字节。  unicode 现在应该是可以到 0x1FFFFF 吧。utf16 用 2 个或 4 个字节(surrogate pairs) ，utf32 全是 4 个字节。  unicode 本身不是一种编码。


Question: 如何用C语言实现读取某txt文档并在有数字的地方自动换行的功能?

你总需要找到一个可以用来确认你要换行的判断方法 比如你可以把全部字符串读入，然后遍历查找数字,且数字之后为'.' 的，满足条件的插入\r\n 当然也可以直接用一些支持正则表达式的文本工具直接替换

引用 3 楼 my_live_123 的回复:方案： 1.打开文本文件，创建新的临时文件并打开 2.逐个字符复制，当遇到数字时，向临时文件添加一个换行符 3.重复2直到所有文本处理完成！ 4.修改临时文件名，此文件就是你需要的文件，保留原文件不动！  思路不对。第二步遇到数字就添加换行符不对，因为文本中的数字，不一定全都是序号，也有可能有的数字是文本内容之一。比如抓住这5个要点去做事中的5.

正则表达式速查 正则表达式举例 正则表达式学习 (4页A4纸)http://download.csdn.net/detail/zhao4zhong1/1808549

引用 7 楼 zhao4zhong1 的回复:凡是？。！后面跟1～1000后面跟半角.的，在？。！后面加回车换行。 //凡是？。！后面跟1～1000后面跟半角.的，在？。！后面加回车换行。 //in.txt: //1.测试。2.测试2？3.测试3！4.测试 //四。5.测试。6.测试6？7.测试3！8.测试 //运行该程序将输出重定向到比如out.txt即可将输出保存到文件out.txt中 #include <iostream> #include <fstream> #include <string> #include <regex> using namespace std; int main() {     wifstream wifs("in.txt");     wifs.imbue(locale("chs"));     wstring wstr(L""),wln;     while (wifs) {         getline(wifs,wln);         wstr+=wln;     }     wifs.close();     wcout.imbue(locale("chs"));     wcout << wstr << endl;      wstring rs = L"([？。！])(\\d{1,3}\\.)";     wregex expression(rs);     wstr = regex_replace(wstr, expression, wstring(L"$1\r\n$2"));     wcout << wstr << endl;      return 0; } //1.测试。2.测试2？3.测试3！4.测试四。5.测试。6.测试6？7.测试3！8.测试 //1.测试。 //2.测试2？ //3.测试3！ //4.测试四。 //5.测试。 //6.测试6？ //7.测试3！ //8.测试 //

凡是？。！后面跟1～1000后面跟半角.的，在？。！后面加回车换行。

引用 4 楼 czrzyy 的回复:[quote=引用 3 楼 my_live_123 的回复:] 方案： 1.打开文本文件，创建新的临时文件并打开 2.逐个字符复制，当遇到数字时，向临时文件添加一个换行符 3.重复2直到所有文本处理完成！ 4.修改临时文件名，此文件就是你需要的文件，保留原文件不动！  思路不对。第二步遇到数字就添加换行符不对，因为文本中的数字，不一定全都是序号，也有可能有的数字是文本内容之一。比如抓住这5个要点去做事中的5.[/quote]  思路是对的，只是条件不同而已！比对条件增强一下就是了，比如需要严格判定“5.“

假如你只是要处理文件,可以用notepad++  学一下正则表达式. 编程的话,以下代码,只是  后面没标点,原txt在行尾处有看不见的换行符没处理. #include <stdio.h>  int fw(char *filename) { 	FILE *fp; 	char ch; 	long n; 	n = 0; 	if((fp = fopen( filename , "r+")) == NULL) 		return -1; 	fseek(fp,3L,SEEK_SET); 	while((ch = fgetc(fp)) != EOF) 	{ 		if(ch < 48 || ch > 57) 			continue; 		else 		{ 			for(n = 1 ; (ch = fgetc(fp)) > 47 && ch < 58 ;n++); 			if(ch != 46) 				continue; 			else 				{ 					fseek(fp,-1 * (n + 3L),SEEK_CUR); 					fputc('\n',fp); 					fseek(fp,n + 5L,SEEK_CUR); 				} 		} 	} 	return fclose(fp); } int main (void) { 	char filename[10] = {'\0'}; 	printf("please input the filename:"); 	gets(filename); 	fw(filename) == 0 ? printf("\n操作成功!\n") : printf("\n操作失败!\n" ); 	return 0; } 仅供参考.


Question: 一个printf都能改变计算的值，搞不懂。。。

我在linux上测试，并没有楼主这样的问题。

很高深啊，vc的汇编是什么意思啊

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

输出只是从存储区读取数据怎么能影响数据的值呢？ 是向整形强转时导致的！不是printf影响的！

浮点误差  引用 3 楼 qq_32874397 的回复:我在奇怪为什么不是9.0000....

引用 9 楼 fefe82 的回复:[quote=引用 8 楼 paschen 的回复:] [quote=引用 7 楼 fefe82 的回复:] 贴编译结果的汇编吧 ...  VC6上确实有这个问题 VS上用的是xmm寄存器，而VC6不是  [/quote]  没有 printf 的话，估计没有 fst 和 fld 这两步。结果就不同了。[/quote]    如果有printf，c=(int)b; 这一句是从内存里取回b的值，没有prinf则直接用寄存器中的，应该是这里导致的

引用 8 楼 paschen 的回复:[quote=引用 7 楼 fefe82 的回复:] 贴编译结果的汇编吧 ...  VC6上确实有这个问题 VS上用的是xmm寄存器，而VC6不是  [/quote]  没有 printf 的话，估计没有 fst 和 fld 这两步。结果就不同了。

引用 7 楼 fefe82 的回复:贴编译结果的汇编吧 ...  VC6上确实有这个问题 VS上用的是xmm寄存器，而VC6不是

贴编译结果的汇编吧 ...

引用 1 楼 user-8的回复:亲，这不是printf改变的，是(int)改变的。类型转换发生信息丢失，是很常见的问题。 可是，上下的代码都一样，一个有printf一个没有，导致结果不同


Question: 怎么同时显示测试函数时间的结果

2楼正解，a已经排好序了，再用插入排序只需要一个O(n)的时间了，所以用时很短没法计时

这个意思？ printf("The time was:%5.2f ---- %5.2 ---- %5.2\n", (double)(end1 - start1) / CLK_TCK,  (double)(end2 - start2) / CLK_TCK,  (double)(end3 - start3) / CLK_TCK);

a已经排好序了, 再排就没用了, 拷贝两份出来, 分别排序

这样，你的变量不重复定义吗？


Question: 关于const修饰和指针

代码里倒是不会出现意想不到的结果，毕竟只是在改变第一个元素的值。书中说的“非法”估计更多的是指“语义”上非法，即“既然定义了一个const数组，后面的代码就应该由程序员保证不会去修改。” 注意：如果把代码改为int *p=i+10;*p=20;这可就是完全的“不可知”行为了，因为已经访问了越界的地址。

引用 1 楼 user-5的回复:这里的非法，意思是什么都可能发生。  你可能得到1，可能得到100，可能程序崩掉，可能 ........... 。。。。。是这个意思？

引用 5 楼 一根烂笔头的回复:这段程序使用GCC编译时候就已经告知你了  warning: initialization discards ‘const’ qualifier from pointer target type [-Wdiscarded-qualifiers]      int *p=i;   编译你的程序，反汇编得到main代码如下，个人PC是Fedora 22, Linux4.2内核，64位80686机器，GCC版本version 5.1.1 20150618 (Red Hat 5.1.1-4) (GCC)  123 0000000000400536 <main>: 124   400536:   55                      push   %rbp 125   400537:   48 89 e5                mov    %rsp,%rbp 126   40053a:   48 83 ec 20             sub    $0x20,%rsp 127   40053e:   c7 45 e0 01 00 00 00    movl   $0x1,-0x20(%rbp) 128   400545:   c7 45 e4 02 00 00 00    movl   $0x2,-0x1c(%rbp) 129   40054c:   c7 45 e8 03 00 00 00    movl   $0x3,-0x18(%rbp) 130   400553:   c7 45 ec 04 00 00 00    movl   $0x4,-0x14(%rbp) 131   40055a:   c7 45 f0 05 00 00 00    movl   $0x5,-0x10(%rbp) 132   400561:   48 8d 45 e0             lea    -0x20(%rbp),%rax 133   400565:   48 89 45 f8             mov    %rax,-0x8(%rbp) 134   400569:   48 8b 45 f8             mov    -0x8(%rbp),%rax 135   40056d:   c7 00 64 00 00 00       movl   $0x64,(%rax) 136   400573:   8b 45 e0                mov    -0x20(%rbp),%eax 137   400576:   89 c6                   mov    %eax,%esi 138   400578:   bf 20 06 40 00          mov    $0x400620,%edi 139   40057d:   b8 00 00 00 00          mov    $0x0,%eax 140   400582:   e8 89 fe ff ff          callq  400410 <printf@plt> 141   400587:   b8 00 00 00 00          mov    $0x0,%eax 142   40058c:   c9                      leaveq 143   40058d:   c3                      retq 144   40058e:   66 90                   xchg   %ax,%ax   注意这几句  124   400536:   55                      push   %rbp 125   400537:   48 89 e5                mov    %rsp,%rbp 126   40053a:   48 83 ec 20             sub    $0x20,%rsp 127   40053e:   c7 45 e0 01 00 00 00    movl   $0x1,-0x20(%rbp) 128   400545:   c7 45 e4 02 00 00 00    movl   $0x2,-0x1c(%rbp) 129   40054c:   c7 45 e8 03 00 00 00    movl   $0x3,-0x18(%rbp) 130   400553:   c7 45 ec 04 00 00 00    movl   $0x4,-0x14(%rbp) 131   40055a:   c7 45 f0 05 00 00 00    movl   $0x5,-0x10(%rbp)  这就是数组的初始化了!显然GCC并没有因为const原因而把它放到只读数据区，但是不排除其他编译器会这么做。以此为前提，那么接下来你修改它当然也是没有问题的！毕竟栈上数据可读写！ 谢谢你的热心解答!!!

引用 4 楼 chehw_1的回复:在C中，用const修饰的并不代表是真的常量，用#define 的才是。  用const修饰只是告诉编译器：该变量是readonly的，你不打算修改，让编译器帮你检查一下，防止你无意中犯了错误。  const修饰的指针既可以指向真的常量，也可以指向非常量。  指向真常量的例子： const char * s = "Hello World";   s[0] = 'h'; //会导致程序崩溃； 由于“Hello World"字符串是放在.data section，是个真的常量，此时常量指针指向的数据是有内存保护的，不能修改的，如果试图修改就会让程序崩溃。  指向语义上的常量的例子： const int a[5] = {0}; a[0] = 1; // 此时编译器会报错，告诉你不能修改  const int a[5] = {0}; int * p = a; p[0] = 1; // 没有问题，  因为int a[5]是在栈上分配内存，这块内存并没有受保护，可以修改。在前面加上const修饰，并不能把它放到.data段，只是告诉编译器，它应该为只读。    #include <stdio.h>  void modify(const char * str) { 	char * p = (char *)str; 	*p = 'h'; 	return; }  int main(int argc, char ** argv) { 	const char * s1 = "Hello World"; 	const char s2[] = "Hello World";  	const char * p = s2; 	modify(p); // 可以，因为s2指向的内存是在栈上分配的 	printf("%s\n", p);  	p = s1; 	modify(p); // 程序会崩溃（Segmentation fault），因为s1指向的是.data段的常量  	printf("%s\n", p); // 不会执行，因为程序已经崩溃了  	return 0; }   谢谢你的热心解答!!!

VS上int *p=i;这句不能通过编译：“初始化”: 无法从“const int *”转换为“int *”


Question: 愚蠢的我又来了，关于指针的一道作业题~~

引用 8 楼 wang0635 的回复:引用 7 楼 qq_32874397 的回复:引用 6 楼 wang0635 的回复:引用 5 楼 qq_32874397 的回复:引用 4 楼 wang0635 的回复:[quote=引用 3 楼 qq_32874397 的回复:] [quote=引用 1 楼 wang0635 的回复:] 第一次写的，为什么没有交换指针所指的内容呢？第二次写的交换了就没有问题了嘛也是设一个中间变量然后再交换就行了吗对呀，你试试。不过，交换一半就行了，记住不要交换多了多谢你，顺便想请教个问题，为什么不用中间变量就不行呢，然后我第一个程序输入abcdefg的话结果是abcdcba，为什么只有后半段倒序，前半段不改变呢。使用中间变量，第一个被修改的变量的值才能暂时保存到中间变量中，下一步再把它存入第二个变量；如果不用中间变量，直接将第二个变量的值存入第一个变量，它们变成一样的了，第一个变量原来的值就找不到了void reverse(char *p)  { 	int i,j; 	char p_2; 	for(i=0;*(p+i)!='\0';i++)continue; 	i--;                        //统计出字符串元素的个数 	for(j=0;i>j;i--,j++) 	{p_2=*(p+i);//依次将该字符串最后的地址指向第一位地址，倒数第二个地址指向第二个。。。。     *(p+i)=*(p++);     *p++=p_2; 	}      }这样改还是不知道哪错了。。[/quote]最后的for循环中，p都变化了，i、j也变化，p+i就跑得快了。把两个p++改成(p+j)[/quote]感谢耐心的解答，恍然大悟，但又突然觉得自己好蠢。。

闪开，都瞎说 #include <stdio.h>  void reverse(char *p); int main(void) { 	char str[80]={0};//规范化，定义数组得初始化 	puts("a sting:"); 	gets(str); 	reverse(str); 	puts(str); 	return 0; } void reverse(char *p)  { 	int i; 	char *p_1=p; 	for(i=0;*(p+i)!='\0';i++)continue; 	i--;                        //统计出字符串元素的个数 	int j=i/2; 	for(;i>j;i--) 	{ 		*(p+i)+=*(p_1); 		*p_1=*(p+i)-*p_1; 		*(p+i)=*(p+i)-*p_1; 		p_1++; 	} }

引用 7 楼 qq_32874397 的回复:引用 6 楼 wang0635 的回复:引用 5 楼 qq_32874397 的回复:引用 4 楼 wang0635 的回复:引用 3 楼 qq_32874397 的回复:[quote=引用 1 楼 wang0635 的回复:] 第一次写的，为什么没有交换指针所指的内容呢？第二次写的交换了就没有问题了嘛也是设一个中间变量然后再交换就行了吗对呀，你试试。不过，交换一半就行了，记住不要交换多了多谢你，顺便想请教个问题，为什么不用中间变量就不行呢，然后我第一个程序输入abcdefg的话结果是abcdcba，为什么只有后半段倒序，前半段不改变呢。使用中间变量，第一个被修改的变量的值才能暂时保存到中间变量中，下一步再把它存入第二个变量；如果不用中间变量，直接将第二个变量的值存入第一个变量，它们变成一样的了，第一个变量原来的值就找不到了void reverse(char *p)  { 	int i,j; 	char p_2; 	for(i=0;*(p+i)!='\0';i++)continue; 	i--;                        //统计出字符串元素的个数 	for(j=0;i>j;i--,j++) 	{p_2=*(p+i);//依次将该字符串最后的地址指向第一位地址，倒数第二个地址指向第二个。。。。     *(p+i)=*(p++);     *p++=p_2; 	}      }这样改还是不知道哪错了。。[/quote]最后的for循环中，p都变化了，i、j也变化，p+i就跑得快了。把两个p++改成(p+j)

引用 6 楼 wang0635 的回复:引用 5 楼 qq_32874397 的回复:引用 4 楼 wang0635 的回复:引用 3 楼 qq_32874397 的回复:引用 1 楼 wang0635 的回复:第一次写的，为什么没有交换指针所指的内容呢？第二次写的交换了就没有问题了嘛也是设一个中间变量然后再交换就行了吗对呀，你试试。不过，交换一半就行了，记住不要交换多了多谢你，顺便想请教个问题，为什么不用中间变量就不行呢，然后我第一个程序输入abcdefg的话结果是abcdcba，为什么只有后半段倒序，前半段不改变呢。使用中间变量，第一个被修改的变量的值才能暂时保存到中间变量中，下一步再把它存入第二个变量；如果不用中间变量，直接将第二个变量的值存入第一个变量，它们变成一样的了，第一个变量原来的值就找不到了void reverse(char *p)  { 	int i,j; 	char p_2; 	for(i=0;*(p+i)!='\0';i++)continue; 	i--;                        //统计出字符串元素的个数 	for(j=0;i>j;i--,j++) 	{p_2=*(p+i);//依次将该字符串最后的地址指向第一位地址，倒数第二个地址指向第二个。。。。     *(p+i)=*(p++);     *p++=p_2; 	}      }这样改还是不知道哪错了。。

void reverse(char* p) {     assert(p != NULL);     int n = strlen(p);     int from = 0;     int to = n - 1;     for(; from < to; from++, to--)     {         char tmp = p[from];         p[from] = p[to];         p[to] = tmp;     } }

第一次写的，为什么没有交换指针所指的内容呢？第二次写的交换了就没有问题了嘛


Question: 保留后六位

对每个阶乘 求余数相加

只求最后一位那么只需要算个位数相乘，只求最后两位只需要算最后两位数相乘，同理，只求最后六位那么只需要算最后六位相乘。这个题应该是计算大数据阶乘最后六位的，要么你先用数组直接把阶乘算出来再取后六位，要么就按上面的思路做

用取余的方法：s %= 100000;    #include<stdio.h> int main() { 	int n, s = 0, t, j, i; 	printf("请输入n\n"); 	scanf("%d", &n); 	for (i = 1; i <= n; i++) 	{ 		t = 1; 		for (j = 1; j <= i; j++) 		{ 			t = t*j; 		} 		s = s + t; 	} 	s %= 100000; 	printf("%d\n", s); 	return 0; }


Question: C program language上的1-13题

你说一下原题吧，都不知道原题要干啥

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

什么问题呢？自己探究没有呢？

练习题目……

C program language上的1-13的例子还是练习题目啊


Question: 写个字符串反序输出的函数,结果无法puts

如果只是要一个反序输出的结果，那么不必改变原串中的字符，这样处理：

如楼上所言，sta要减一不能把空字符算进去

void brck(char *ch)//字符串反序输出 { 	int i;     int sta = 0;     int number;     char temp[1];       while (ch[sta] != '\0')         sta++;     sta--;//不要把结束符算进去       number = sta / 2;     for (i = 0;i<=number; i++,sta--)     {         temp[0] = ch[sta];         ch[sta] = ch[i];         ch[i] = temp[0];       } 	puts(ch); }

字符串头尾交换了2遍啊…… 就好比“360度转弯”这样…… 改为for (int i = 0; i <= number / 2; i++, sta--)


Question: 多个c程序编译生成so文件，在cygwin环境下

引用 2 楼 user-1 的回复:函数声明写去头文件里，其他C文件里包含头文件谢谢你

函数声明写去头文件里，其他C文件里包含头文件

自己顶，顶起顶起