Question: 送分了，好简单的问题，fread()

在某些情况下是等价的

MSDN上说得已经很清楚了： fread Reads data from a stream.  size_t fread( void *buffer, size_t size, size_t count, FILE *stream );  Function Required Header Compatibility  fread <stdio.h> ANSI, Win 95, Win NT    For additional compatibility information, see Compatibility in the Introduction.  Libraries  LIBC.LIB Single thread static library, retail version  LIBCMT.LIB Multithread static library, retail version  MSVCRT.LIB Import library for MSVCRT.DLL, retail version    Return Value  fread returns the number of full items actually read, which may be less than count if an error occurs or if the end of the file is encountered before reaching count. Use the feof or ferror function to distinguish a read error from an end-of-file condition. If size or count is 0, fread returns 0 and the buffer contents are unchanged.  Parameters  buffer  Storage location for data  size  Item size in bytes  count  Maximum number of items to be read  stream  Pointer to FILE structure  Remarks  The fread function reads up to count items of size bytes from the input stream and stores them in buffer. The file pointer associated with stream (if there is one) is increased by the number of bytes actually read. If the given stream is opened in text mode, carriage return–linefeed pairs are replaced with single linefeed characters. The replacement has no effect on the file pointer or the return value. The file-pointer position is indeterminate if an error occurs. The value of a partially read item cannot be determined.  Example  /* FREAD.C: This program opens a file named FREAD.OUT and  * writes 25 characters to the file. It then tries to open  * FREAD.OUT and read in 25 characters. If the attempt succeeds,  * the program displays the number of actual items read.  */  #include <stdio.h>  void main( void ) {    FILE *stream;    char list[30];    int  i, numread, numwritten;     /* Open file in text mode: */    if( (stream = fopen( "fread.out", "w+t" )) != NULL )    {       for ( i = 0; i < 25; i++ )          list[i] = (char)('z' - i);       /* Write 25 characters to stream */       numwritten = fwrite( list, sizeof( char ), 25, stream );       printf( "Wrote %d items\n", numwritten );       fclose( stream );     }    else       printf( "Problem opening the file\n" );     if( (stream = fopen( "fread.out", "r+t" )) != NULL )    {       /* Attempt to read in 25 characters */       numread = fread( list, sizeof( char ), 25, stream );       printf( "Number of items read = %d\n", numread );       printf( "Contents of buffer = %.25s\n", list );       fclose( stream );    }    else       printf( "File could not be opened\n" ); }   Output  Wrote 25 items Number of items read = 25 Contents of buffer = zyxwvutsrqponmlkjihgfedcb   Stream I/O Routines  See Also   fwrite, _read

虽然看起来差不多，但函数对size和count的处理方式是不一样的，这就涉及到效率问题。最好按照函数的本意去使用。

引用 1 楼 Saleayas 的回复:不一样的。 试试 如果只有 1023 个？？  如果大于1024字节的文件呢，比如 20480 ， 你觉得调用一次效果应该是一样吗？

按道理来说： 读1次最多1024字节 读1024次1字节 含义有区别？

不一样的。  试试 如果只有 1023 个？？

size 要读的每个数据项的字节数，单位是字节 count 要读count个数据项，每个数据项size个字节.


Question: 关于逆波兰表达式的处理


Question: C语言初学者求问

谢谢您，我现在想起来了这点，还是见得少，还的好好学

scanf遇到%d，先滤掉所有的空白，包括回车，等到第一个非空白字符才试图转换成整数


Question: 弱问, python是不是重载？（这个版本有很多c++, python大神）

1L回答的很好，就是自行判断参数个数而已。

Python不支持像C++一样的重载，但可以实现类似重载的功能，你可以搜一下。 这是range的源码源码 static PyObject * builtin_range(PyObject *self, PyObject *args) {     long ilow = 0, ihigh = 0, istep = 1;     long bign;     Py_ssize_t i, n;      PyObject *v;      if (PyTuple_Size(args) <= 1) {         if (!PyArg_ParseTuple(args,                         "l;range() requires 1-3 int arguments",                         &ihigh)) {             PyErr_Clear();             return handle_range_longs(self, args);         }     }     else {         if (!PyArg_ParseTuple(args,                         "ll|l;range() requires 1-3 int arguments",                         &ilow, &ihigh, &istep)) {             PyErr_Clear();             return handle_range_longs(self, args);         }     }     if (istep == 0) {         PyErr_SetString(PyExc_ValueError,                         "range() step argument must not be zero");         return NULL;     }     if (istep > 0)         bign = get_len_of_range(ilow, ihigh, istep);     else         bign = get_len_of_range(ihigh, ilow, -istep);     n = (Py_ssize_t)bign;     if (bign < 0 || (long)n != bign) {         PyErr_SetString(PyExc_OverflowError,                         "range() result has too many items");         return NULL;     }     v = PyList_New(n);     if (v == NULL)         return NULL;     for (i = 0; i < n; i++) {         PyObject *w = PyInt_FromLong(ilow);         if (w == NULL) {             Py_DECREF(v);             return NULL;         }         PyList_SET_ITEM(v, i, w);         ilow += istep;     }     return v; }   这是别人实现的range函数range  def my_range(start, stop = None, step = 1):  2     # 实现自己的 range  3     if stop == None:  4         start, stop = 0, start  5   6     result = []  7     if step > 0:  8         i = start  9         while i < stop: 10             result.append(i) 11             i += step 12     else: 13         i = start 14         while (i > stop): 15             result.append(i) 16             i += step 17     return result


Question: 求c语言大神解答

直接拿a跟b+0,b+1,b+..k 去比较不行吗

[size=24px]题目描述：Given two strings A and B, whose alphabet consist only ‘0’ and ‘1’. Your task is only to tell how many times does A appear as a substring of B? For example, the text string B is ‘1001110110’ while the pattern string A is ‘11’, you should output 3, because the pattern A appeared at the position 4, 5 and 8. It’s very simple, isn’t it?[/size] 输入：The first line consist only one integer C(C <= 10), indicates C cases follows. In each case, there are two lines, the first line gives the string A, length (A) <= 30, and the second line gives the string B, length (B) <= 100000000. And it is guaranteed that B is always longer than A. 输出：For each case, output a single line consist a single integer, tells how many times do B appears as a substring of A

楼主能不能把 前面的题目描述,输入,输出 截清楚.

截的图太模糊了，你可以把问题叙述一下


Question: 最大子序列求和问题

for(int i=iCenter;i>=iLeft;i--) //从中间向左扩展求子段的最大子序列和，必然包括子段的最右端数       {           iLeftBorderSum+=s[i];           if(iLeftBorderSum>iMaxLeftBorderSum)           {               iMaxLeftBorderSum = iLeftBorderSum; //包含左端数的最大子序列和  ？只是反序查找左区间能够达到的最大和。                                                                                //这个最大和是中间向左这一小段最大的                     }       }   下面那个循环，性质相同，这两段是相连的，也就是中间一段，跨越了左右两个区间。所以对它们求和，就是跨区间最大和 下面就是比较到底谁最大，取最大的那个 两个递归，和一个终止条件，（也包括递归过程的跨界这一段）。共同求出左，右两个区间最大和、  递归部分直接就认为是对的，不要问为什么，除非这个问题的结构不是这样的。

递归的思想是 1）基准情形：必须总有某些基准情形，此时不用递归，就能求解。（这样可以有个出口，避免无穷递归。） 2）不断推进：对于递归求解的情况，递归必须总能够朝着一个基准情形推进。（这保证，规模不是无限增加，以至于到不了出口） 3）设计法则：假设所有递归都能运行。（就是不要考虑细节。递归自己会处理的。） 4）合成效益法则：在求解同一个问题的同一实例的时候，切勿在不同的递归调用中，做重复性的工作。（避免重复以至于耗时太多） 这是数据结构的书籍中，一般都会提到的。 这几句，是在书中原话抄来的，不过不是英文原文 () 括号中注解的是我个人的理解。 书名 << Data Structures and Algorithm Analysis in C++>>  Third Edition  原作者是 Mark Allen Weiss  中文版 ： 《数据结构与算法分析C++描述》  第3版 张怀勇 等翻译 刘田 审校 人民邮电出版社

引用 2 楼 user-1 的回复:iMaxLeftSum = SubsequenceSum(s,iLeft,iCenter); //每次递归返回时，该值为该子段的最终左最大子序列和  ？ iMaxRightSum = SubsequenceSum(s,iCenter+1,iRight); //每次递归返回时，该值为该子段的右最大自序列和  ？ 这是递归部分， 不要问为什么， 要问这个结构合理不合理 可不可以这么做。 首先，这么做，确实是一个元素不漏，把区间划分成左右两部分了。 所以只要非递归部分实现没有问题，这个地方就没有问题。  递归问题，要考虑的是，有没有这种递归结构，能不能这么分开处理。所以递归调用只要初值设好了就基本可实现了？感觉这种抽象思维还是没形成


Question: 用C语言如何获取当前系统的当前毫秒数，每八位转换成十六进制，并做统计由高到底按顺序输出？？？？，重点是后边的转换！！！

引用 4 楼 vshuo7013 的回复:这是我写的程序： #include <stdio.h>     #include <sys/time.h>   //获取十进制毫秒数二进制位数函数 int num_bin(long time){ 	int num=0; 	while(time!=0)     {        	time/=2;        	num++;     } 	return num; } //获取系统当前时间毫秒数十六进制形式函数 void binhex(int num,long time,int *hex){ 	int j;  	for(j=0;j<num;j++){ 		hex[j] = time & 0XFF; 		time=time>>8;  	} } //获取当前时间毫秒数    long getCurrentTime()     {        	struct timeval tv;        	gettimeofday(&tv,NULL);         long time = tv.tv_sec * 1000 + tv.tv_usec / 1000; 	return time;     }              int main()     {   	long time = getCurrentTime(); 	int num = num_bin(time);     	printf("%ld\n",time); 	int NUM = (num/8 +1); 	printf("NUM=%d\n", NUM); 	int hex[NUM]; 	binhex(NUM,time,hex);  	int n;	 	for(n=0;n<NUM;n++){ 		printf("%02X ",hex[n]); 	} 	printf("\n");    	return 0;     }    其中的一个运行结果是： 1450193000132 NUM=6 C4 16 3D A6 51 01 我的意图就是得到这种答案：C4 16 3D A6 51 01 我觉得我的方法很麻烦！ 想请教下有没有更好的方法？？？ 作为一个C程序员，对  scanf,sscanf,fscanf  printf,sprintf,fprintf 这类函数的用法，还是要做到“拳不离手，曲不离口”的。  #include <stdio.h> int main() {     long long int ms=1450193000132LL;     printf("%016llX\n",ms);     for (int i=0;i<8;i++) {         printf("%02X ",((unsigned char *)&ms)[i]);     }     printf ("\n");     return 0; } //00000151A63D16C4 //C4 16 3D A6 51 01 00 00 //

14501700938 假设其二进制形式为111000010101010001000110101010101010101010 从左到右，有高到底，转换成每八位对应十六进制

引用 1 楼 user-3 的回复: 什么叫“每8位转成十六进制”？  char a[100]; sprintf(a,"%016llx",1450170093810LL);

什么叫“每8位转成十六进制”？  char a[100]; sprintf(a,"%llx",1450170093810);


Question: 备忘录法解背包问题，哪错了

引用 2 楼 u010107248 的回复:[quote=引用 1 楼 user-1 的回复:] MFKnapsack 中int i 是递减, 小于0 怎么办, 还有T[i][j]初始化行列都少1 if(i>=0&&j>=0)不是只有i>0时才执行么。 初始化我改了，还还不对啊 	for(i=0 ; i<=goods->numbers ; i++) 		for(j=0 ; j<=knapsack->MaxWeight ; j++) 			T[i][j] = -1 ; [/quote] value = MFKnapsack(i-1,j, knapsack, 如果i=0, 这个调用会返回什么

int MFKnapsack(int i, int j, struct Knapsack *knapsack, struct Goods *goods) {     int value;      if (i > 0 && j > 0)     {         if (T[i][j] < 0)         {             if (j < goods->weight[i])             {                 value = MFKnapsack(i - 1, j, knapsack, goods);             }             else             {                 value = Max(MFKnapsack(i - 1, j, knapsack, goods),                         goods->value[i] + MFKnapsack(i - 1, j - goods->weight[i], knapsack, goods));             }             T[i][j] = value;         }         return T[i][j];     }     return T[i][j] = 0; }

引用 4 楼 user-1 的回复:[quote=引用 2 楼 u010107248 的回复:] [quote=引用 1 楼 user-1 的回复:] MFKnapsack 中int i 是递减, 小于0 怎么办, 还有T[i][j]初始化行列都少1 if(i>=0&&j>=0)不是只有i>0时才执行么。 初始化我改了，还还不对啊 	for(i=0 ; i<=goods->numbers ; i++) 		for(j=0 ; j<=knapsack->MaxWeight ; j++) 			T[i][j] = -1 ; [/quote] value = MFKnapsack(i-1,j, knapsack, 如果i=0, 这个调用会返回什么[/quote] 原来是没设置递归出口 int  MFKnapsack( int i , int j , struct Knapsack *knapsack ,  struct Goods *goods )  { 	int value ;  	if(i==0) return 0 ;  	else  	{ 		if(T[i][j]<0) 		{ 			if( j<goods->weight[i] ) 				value = MFKnapsack(i-1,j, knapsack ,  goods ) ; 			else 				value =  Max(   MFKnapsack(i-1,j, knapsack , goods ) , 						   goods->value[i]+MFKnapsack( i-1 , j-goods->weight[i] , knapsack , goods )  ); 			T[i][j] = value ; 		} 		 		return T[i][j] ; 	} 	 }

引用 1 楼 user-1 的回复:MFKnapsack 中int i 是递减, 小于0 怎么办, 还有T[i][j]初始化行列都少1 if(i>=0&&j>=0)不是只有i>0时才执行么。 初始化我改了，还还不对啊 	for(i=0 ; i<=goods->numbers ; i++) 		for(j=0 ; j<=knapsack->MaxWeight ; j++) 			T[i][j] = -1 ;


Question: 有个问题,如何给一个没有窗体的程序用sendmessage发送消息?

两个windows进程间通信的问题，可以socket，也可以管道，等等。

PostThreadMessage给线程发消息  怎么接受，搜“控制台 消息循环”


Question: [预编译大牛请进]C 语言中如何解决头文件中互相嵌套问题!!!!!!头疼

引用 19 楼 rogone 的回复:#pragma once  这个没有用的

#pragma once

相互包含头文件，说明程序结构有问题，重新思考划分模块

引用 9 楼 Z_R_Z_798205 的回复:[quote=引用 7 楼 user-7 的回复:] 把公共的宏单独放在一个独立的头里面。 这个方法可行,但是由于项目的不断扩大,这个方法不是长久之策[/quote] 检讨一下设计吧。windows linux office都是巨无霸项目，你这才多少代码就有这种问题。

大家好,针对随着代码的不断扩大,头文件应用问题我是这么处理的. 按下面原则,优先级依次降低; 1. 原则上头文件不引用任何头文件. 2. 避免头文件引用成死循环. 2. 如果头文件有数据定义,满足数据定义成员的类型的头文件引用. 3. 如果宏定义引用其他头文件,此时引用相应的头文件 4. 如果出现因 inline 函数参数引用其他头文件,则引用头文件. 4. 如果因 inline 函数内部或数据定义时需要引用其他头文件或者 C 文件,则统一使用 extern.  通过上面几个原则,轻松搞定五十多个头文件的项目,debug 起来 error 和 warning 以及 note 轻松解决. 始终坚持的原则就是头文件高内聚低耦合.  调试 warning 和 note 的时候真的变容易太多了!!!!!!!

恭喜恭喜恭喜恭喜

引用 14 楼 jiqiang01234 的回复:相互包含头文件，说明程序结构有问题，重新思考划分模块  已经重构了头文件的架构,原则上高内聚低耦合,数据定义优先,inline 函数次之的原则,很有效的解决头文件混用问题.

引用 12 楼 zhao4zhong1 的回复:参考大项目的源码中是如何#define和#undef宏的。比如include\stdlib.h 已经找到替代方法了,采用高内聚低耦合,数据定义优先,inline 函数次之的原则. 已经解决问题,谢谢  引用 13 楼 akirya 的回复:[quote=引用 9 楼 Z_R_Z_798205 的回复:] [quote=引用 7 楼 user-7 的回复:] 把公共的宏单独放在一个独立的头里面。 这个方法可行,但是由于项目的不断扩大,这个方法不是长久之策[/quote] 检讨一下设计吧。windows linux office都是巨无霸项目，你这才多少代码就有这种问题。[/quote]  重新思考了头文件的设计,原则上高内聚低耦合,数据定义优先,inline 函数次之的原则,很有效的解决头文件混用问题. 初期的架构很重要,头文件五十个左右,c 文件三十个左右,通过这种头文件架构原则,重源头上避免了很多 warning 的产生.

引用 10 楼 paschen 的回复:不要想互包含， 不然试下把个每个函数、变量、宏单独用下面这个包含（而不是整个文件）  #ifndef XXX     #define XXX      #endif 这样有点不好,我在写 Linux 内核的一个模块,出现这个问题我参照内核头文件的引用, 初步看是可以互相引用,而且由于互相引用导致函数问题我是有方法解决的,但头文件中的 宏定义就很麻烦处理! 谢谢,能不能帮我想想更好的解决办法.

引用 7 楼 user-7 的回复:把公共的宏单独放在一个独立的头里面。 这个方法可行,但是由于项目的不断扩大,这个方法不是长久之策

引用 2 楼 zhao4zhong1 的回复:楼主自己解套，这个总比股票解套容易。  嵌套导致的函数引用问题,我有办法解决, 但嵌套导致的宏问题,我不知道怎么解决, 我贴了代码,帮我预处理分析一下.谢谢

引用 4 楼 paschen 的回复:自己更清关系，再不会参看一下标准库里各头文件怎么包含的 就算出现头文件嵌套导致函数相关问题,我都有解决的办法. 但如果嵌套时有宏引起的问题,我就不知道怎么解决.  随着项目的不断变大,头文件嵌套无法避免,手动控制头文件不嵌套,不现实.

把公共的宏单独放在一个独立的头里面。

我把我的问题用简单代码写出来了,大家帮我解决一下: 我定义了三个文件, 预编使用 gcc 3.c -E 编译使用 gcc 3.c -o a 由于项目在不断变大,嵌套问题该如何处理? // 1.h #ifndef _Q_H_ #define _Q_H_  #include "2.h"  void inline show(void) {     int a;      a += 2; } //void inline st(void); void inline add(void) {     int a;      a = PAGE_SIZE;     a += 3;     st(); }   #endif  // 2.h #ifndef _W_H_ #define _W_H_ #include "1.h"   #define PAGE_SIZE 3 void inline st(void) {     show(); }  #endif   // 3.c  #include "2.h"   int main() {     return 0; }

自己更清关系，再不会参看一下标准库里各头文件怎么包含的

我把我的问题用简单代码写出来了,大家帮我解决一下: 我定义了三个文件, 预编使用 gcc 3.h -E 编译使用 gcc 3.h -o a 由于项目在不断变大,嵌套问题该如何处理? // 1.h #ifndef _Q_H_ #define _Q_H_  #include "2.h"  void inline show(void) {     int a;      a += 2; } //void inline st(void); void inline add(void) {     int a;      a = PAGE_SIZE;     a += 3;     st(); }   #endif  // 2.h #ifndef _W_H_ #define _W_H_ #include "1.h"   #define PAGE_SIZE 3 void inline st(void) {     show(); }  #endif   // 3.c  #include "2.h"   int main() {     return 0; }

楼主自己解套，这个总比股票解套容易。

不要出现 a.h引用b.h b.h引用a.h


Question: unsigned char和char都赋值0xFF，再与常量0xFF进行==判断的疑问？

引用 5 楼 xiezz 的回复:[quote=引用 3 楼 paschen 的回复:] 对于这一句if(a == 0xFF)： 前者==两端类型不同，将转换类型后再判断，此时a被转换成了int的-1，所以不相等了 后者则相等可否这样理解，关键的原因是a == 0xFF中==两端类型不同，所以要转换类型。char要转换成int，变成了int的-1（内存中是存32个1），而0xFF常量是int的，因此就不相等了。[/quote]  是的~

引用 3 楼 paschen 的回复:对于这一句if(a == 0xFF)： 前者==两端类型不同，将转换类型后再判断，此时a被转换成了int的-1，所以不相等了 后者则相等可否这样理解，关键的原因是a == 0xFF中==两端类型不同，所以要转换类型。char要转换成int，变成了int的-1（内存中是存32个1），而0xFF常量是int的，因此就不相等了。

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

char  总共8字节，char a;     a = 0xFF;    a=1111 1111;其中第一个1为符号位。实际上a=-1；


Question: 数组查询求教

2楼的方法受教了。我本来直接想到的是用char来循环查找buf里的字符，进行判断。然后逐个记住v的位置。

#include <stdio.h> char *buf="v11111011v2222201212v21323123"; __int64 v[3]; int main() {     sscanf(buf,"v%I64dv%I64dv%I64d",&v[0],&v[1],&v[2]);     printf("%I64d %I64d %I64d",v[0],v[1],v[2]);//11111011 2222201212 21323123     return 0; }

字符串分割，或者strchr查找v找到后从指针位置后一字符开始复制到目的数组中


Question: 为什么用fwrite函数输出的文本文件打开为乱码？

void writeFile(int number) {     int i=0;     FILE *fp;     if((fp = fopen("studentscore.txt","w"))==NULL)     {         printf("打开studentscore.txt失败\n");         return;     }     rewind(fp); //    fwrite(Score,sizeof(StuS),number,fp);     for(i=0;i<number;i++);     {         fprintf(fp,"%d%s%d%d%d%d%.1f\n",Score[i].ID,Score[i].Name,Score[i].MathScore,Score[i].EngScore,Score[i].PhyScore,Score[i].TotalScore,Score[i].AverScore);     }     fclose(fp);     printf("文件写入成功\n");     return; }    引用 1 楼 zhangxiangDavaid 的回复:二进制写入，使用fwrite，所以打开乱码 文本文件写入，使用fprintf   我改成这样了为何输出了一串0，用printf在屏幕上输出都正常

read与write时都分二进制文件与文本文件

电脑内存或文件内容只是一个一维二进制字节数组及其对应的二进制地址； 人脑才将电脑内存或文件内容中的这个一维二进制字节数组及其对应的二进制地址的某些部分看成是整数、有符号数/无符号数、浮点数、复数、英文字母、阿拉伯数字、中文/韩文/法文……字符/字符串、汇编指令、函数、函数参数、堆、栈、数组、指针、数组指针、指针数组、数组的数组、指针的指针、二维数组、字符点阵、字符笔画的坐标、黑白二值图片、灰度图片、彩色图片、录音、视频、指纹信息、身份证信息……  推荐使用WinHex软件查看硬盘或文件或内存中的原始字节内容。  不要把 fopen("...","...");fscanf,fprintf,fgets,fgetc,fclose //读时把\r\n替换成\n，写时把\n替换成\r\n;读到\x1a就设置EOF;读写的内容当字符看待 和 fopen("...","...b");fseek,ftell,fread,fwrite,fgetc,fclose //不作以上替换，遇到\x1a仍继续读;读写的内容当字节看待 弄混了

二进制写入，使用fwrite，所以打开乱码 文本文件写入，使用fprintf


Question: 用C语言编程，如何将一个将一个IP地址字符串转换成十六进制数

请问char IP[7]={“”11001100“”}，这字符串怎么转换整数吗？

请问char IP[7]={"11001100"} 怎么转换int a=?

赵4老师多谢了!!!

作为一个C程序员，对  scanf,sscanf,fscanf  printf,sprintf,fprintf 这类函数的用法，还是要做到“拳不离手，曲不离口”的。 sscanf(IP,"%x.%x.%x.%x",&a,&b,&c,&d);


Question: c语言实现顺序栈进栈时的指针问题

引用 3 楼 xiangkuiming的回复:引用 1 楼 u011133403 的回复:楼主好，你上面的代码一看就是严奶奶数据结构那本书上的C语言伪代码。伪代码就是为了让我们更容易看懂。void Push(SqStack &S,SElemType e) 这段伪代码指参数是SqStack 的地址。  真正用的时候应该就是void Push(SqStack *S,SElemType e)，SqStack *S 代表参数是地址。   手工打字党，望采纳。恩  我大致明白了。后来我了解到&作引用是在c++中才可以对吗？如果用C++写的话就可以用void Push(SqStack &S,SElemType e)来实现了吧？然后具体实现也可以用*S.top而非必须用*S->top吧？ 非常sorry,没有去研究过C＋＋。

《数据结构（C语言描述）》


Question: 谁来讲一讲在什么情况下定义头文件(x.h)??? 想知道？

不想提供C代码给调用者，仅提供.h和.lib、.dll

我想说的是在C语言中，你这个是C++了，

简单的程序是不需要的，程序复杂的话是必须建立头文件的，目的是对一些类进行声明，尤其是需要建立自己的名称空间的时候


Question: 怎么才能HOOK到其他的进程

OpenProcess ReadProcessMemory WriteProcessMemory

提醒：再牛×的老师也无法代替学生自己领悟和上厕所！  仅供参考： /*     Application:    Code Injection in Explorer     Author:     @_RT     Compiled on:    Feb 2014     URL:http://www.codeproject.com/Tips/732044/Code-Injection-2      We will see the different steps involved to perform a code injection into an already running process.      Following are the quick steps through the process of injection.     1.Get the API addresses that you will be calling from the injected code.     2.Prepare shell code of your function that you want to get executed from the injected process.     3.Get the process ID of the running process that you wish to inject into by enumerating through the       list of processes or by finding the process's window (in case it's a GUI application) by class name or title.     4.Open the process using its Pid with All Access rights.     5.Allocate different memory spaces in the process that you are going to inject to with desired access       rights for holding different segments of your shell code.         Code part (executable instructions)         Data part (strings, function parameters, etc.)     6.Write the allocated memories with the respective values (code and data).     7.Call CreateRemoteThread API and pass to it the start of allocated memory address where you have       written your shell code from the process we are injecting. */  #include <windows.h> #pragma comment(lib,"user32.lib")  LPVOID addr; LPVOID addr2;  BOOL InjectExecutable(DWORD dwPid,LPVOID si,LPVOID pi,int sisize,int pisize) {     LPVOID hNewModule;     HANDLE hProcess;     CHAR S[]    = { "C:\\Windows\\notepad.exe" };     BYTE byt[]  = {0x6A, 0x00, 0x6A, 0x00, 0x6A, 0x00, 0x6A, 0x01, 0x6A, 0x00, 0x6A, 0x00, 0x6A, 0x00, 0x68};     BYTE byt2[] = {0xE8};     BYTE byt3[] = {0x68};      hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, dwPid);     if (hProcess == NULL)     {         return FALSE;     }      LPVOID staddr = VirtualAllocEx(hProcess, NULL, sizeof(S), MEM_COMMIT, PAGE_READWRITE);     WriteProcessMemory(hProcess, staddr, S, sizeof(S), NULL);     LPVOID fnaddr = VirtualAllocEx(hProcess, NULL, 4, MEM_COMMIT, PAGE_READWRITE);     WriteProcessMemory(hProcess, fnaddr, si, sisize, NULL);     LPVOID fnaddr2 = VirtualAllocEx(hProcess, NULL, 4, MEM_COMMIT, PAGE_READWRITE);     WriteProcessMemory(hProcess, fnaddr2, pi, pisize, NULL);      hNewModule = VirtualAllocEx(hProcess, NULL, 100, MEM_COMMIT, PAGE_EXECUTE_READWRITE);     if (hNewModule == NULL)     {         return FALSE;     }     LPTHREAD_START_ROUTINE strtaddr = (LPTHREAD_START_ROUTINE)hNewModule;      WriteProcessMemory(hProcess, hNewModule, byt3, sizeof(byt3), NULL);     hNewModule = (LPVOID)((int)hNewModule + sizeof(byt3));     WriteProcessMemory(hProcess, hNewModule, &fnaddr, sizeof(fnaddr), NULL);     hNewModule = (LPVOID)((int)hNewModule + sizeof(fnaddr));     WriteProcessMemory(hProcess, hNewModule, byt3, sizeof(byt3), NULL);     hNewModule = (LPVOID)((int)hNewModule + sizeof(byt3));     WriteProcessMemory(hProcess, hNewModule, &fnaddr2, sizeof(fnaddr2), NULL);     hNewModule = (LPVOID)((int)hNewModule + sizeof(fnaddr2));     WriteProcessMemory(hProcess, hNewModule, byt, sizeof(byt), NULL);     hNewModule = (LPVOID)((int)hNewModule + sizeof(byt));     WriteProcessMemory(hProcess, hNewModule, &staddr, sizeof(staddr), NULL);     hNewModule = (LPVOID)((int)hNewModule + sizeof(staddr));     WriteProcessMemory(hProcess, hNewModule, byt2, sizeof(byt2), NULL);     hNewModule = (LPVOID)((int)hNewModule + sizeof(byt2));     addr = (LPVOID)((int)addr - ((int)hNewModule + 4));     WriteProcessMemory(hProcess, hNewModule, &addr, sizeof(addr), NULL);     hNewModule = (LPVOID)((int)hNewModule + sizeof(addr));     WriteProcessMemory(hProcess, hNewModule, byt, 2, NULL);     hNewModule = (LPVOID)((int)hNewModule + 2);     WriteProcessMemory(hProcess, hNewModule, byt2, sizeof(byt2), NULL);     hNewModule = (LPVOID)((int)hNewModule + sizeof(byt2));     addr2 = (LPVOID)((int)addr2 - ((int)hNewModule + 4));     WriteProcessMemory(hProcess, hNewModule, &addr2, sizeof(addr2), NULL);      CreateRemoteThread(hProcess, 0, 0, strtaddr, NULL, 0, NULL);     return TRUE; }  void main() {     _STARTUPINFOA si;     PROCESS_INFORMATION pi;      ZeroMemory(&si, sizeof(si));     si.cb = sizeof(si);     ZeroMemory(&pi, sizeof(pi));      DWORD dwPid;     HMODULE ldlib = LoadLibraryA("Kernel32.dll");     addr = GetProcAddress(ldlib, "CreateProcessA");     addr2 = GetProcAddress(ldlib, "ExitThread");     GetWindowThreadProcessId(FindWindow(NULL, L"Start Menu"), &dwPid);      InjectExecutable(dwPid,&si,&pi,sizeof(si),sizeof(pi)); }

用一下detours好了

引用 6 楼 zhao4zhong1 的回复:Detours库是开源的，这个库的功能就是“读取对方进程内存地址，将指向MessageBoxA的地址转换成指向MyMessageBoxA的”。 你高兴了把它的部分代码拷贝到你的代码中调通就行。能不能把我上面的程序做成一个线程 注入到目标MessageBoxA里面呢

引用 3 楼 zhao4zhong1 的回复:https://www.baidu.com/s?wd=detours&rsv_spt=1&rsv_iqid=0xbb1f641200001eb4&issp=1&f=8&rsv_bp=0&rsv_idx=2&ie=utf-8&tn=baiduhome_pg&rsv_enter=1&rsv_n=2&rsv_sug3=1 赵老师，我们的要求是不用这种现成的库函数，而是读取对方进程内存地址，将指向MessageBoxA的地址转换成指向MyMessageBoxA的。

引用 1 楼 fly_dragon_fly 的回复:用一下detours好了具体操作可以说下吗


Question: 程序跑loadfile()后提示 steam!=null  求老师指点

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

scanf("%s", &file1); ==>  scanf("%s", file1);


Question: 求大神解决。问题：可以运行只有一个星星没有墙，小白本想编一个迷宫的，求大神抽空改一下小白的程序让它完整

main里面introduced前面的void去掉，打印迷宫函数里面打印#字符前面掉了printf

引用 2 楼 aaa461534727的回复:按您的要求加了printf与去掉viod，运行后可以玩了，但是在地图中按右键撞那个墙后就变黑屏了，按其他键有恢复，求解决 加个判断，撞了墙就结束游戏


Question: 原来C语言不支持体外循环

引用 3 楼 adlay 的回复:函数外面不是不能有循环，而是任何语句都不行，只能对全局变量做初始化。

函数外面不是不能有循环，而是任何语句都不行，只能对全局变量做初始化。

语句不能放在全局区，需要放到函数里

楼主是javascript转过来的？


Question: 调用含参函数不传参数？

引用 7 楼 paschen 的回复:[quote=引用 6 楼 u011412782 的回复:] [quote=引用 5 楼 paschen 的回复:] 那个只是声明，不是函数调用，而且通常应该把他放到该函数前面（虽然在里面也行） 嗯嗯，但是在内部申明函数有什么意义呢？？与外面有什么不同？[/quote]  在内部只有当前这个函数可以用，其他函数（在调用函数的上面的）则用不了[/quote]  所噶，那主要作用就还是控制函数作用范围咯？？  非常感谢！

引用 6 楼 u011412782 的回复:[quote=引用 5 楼 paschen 的回复:] 那个只是声明，不是函数调用，而且通常应该把他放到该函数前面（虽然在里面也行） 嗯嗯，但是在内部申明函数有什么意义呢？？与外面有什么不同？[/quote]  在内部只有当前这个函数可以用，其他函数（在调用函数的上面的）则用不了

引用 5 楼 paschen 的回复:那个只是声明，不是函数调用，而且通常应该把他放到该函数前面（虽然在里面也行） 嗯嗯，但是在内部申明函数有什么意义呢？？与外面有什么不同？

那个只是声明，不是函数调用，而且通常应该把他放到该函数前面（虽然在里面也行）

引用 3 楼 user-2 的回复:[quote=引用 2 楼 u011412782 的回复:] [quote=引用 1 楼 user-2 的回复:] 调用了有参数的函数，但是并没有传递参数 是指那一句? 不会是指上面的函数声明吧 是这里： void add(comp_int ,comp_int ,comp_int *); void sub(comp_int ,comp_int ,comp_int *); void mul(comp_int ,comp_int ,comp_int *); 这里是函数的申明？？？ C语言不允许这样的函数申明吧？  如果是函数申明的话，这样的申明的意义在哪儿呢？[/quote] 不声明 func_die就不能调用这些函数[/quote]  那为什么不在函数外面申明？？在内部申明有什么意义？

引用 1 楼 user-2 的回复:调用了有参数的函数，但是并没有传递参数 是指那一句? 不会是指上面的函数声明吧 是这里： void add(comp_int ,comp_int ,comp_int *); void sub(comp_int ,comp_int ,comp_int *); void mul(comp_int ,comp_int ,comp_int *); 这里是函数的申明？？？ C语言不允许这样的函数申明吧？  如果是函数申明的话，这样的申明的意义在哪儿呢？

引用 2 楼 u011412782 的回复:[quote=引用 1 楼 user-2 的回复:] 调用了有参数的函数，但是并没有传递参数 是指那一句? 不会是指上面的函数声明吧 是这里： void add(comp_int ,comp_int ,comp_int *); void sub(comp_int ,comp_int ,comp_int *); void mul(comp_int ,comp_int ,comp_int *); 这里是函数的申明？？？ C语言不允许这样的函数申明吧？  如果是函数申明的话，这样的申明的意义在哪儿呢？[/quote] 不声明 func_die就不能调用这些函数

调用了有参数的函数，但是并没有传递参数 是指那一句? 不会是指上面的函数声明吧


Question: 小白一枚 初次试水  碰到了一个oj上无法编译但编译器正常编译运行的问题 请各路大神帮忙看看

引用 4 楼 supersuperna 的回复:引用 2楼lm_whales 的回复:int a[n];估计问题在这里我是先输入的n后定义的an 应该不会有事情阿 而且我都运行成功了只是oj显示编译不对 int *a=new int[n]; 弄明白编译期、运行期相关概念。

[n] 去掉。

对不起哦，我不太明白应该加在哪里， 麻烦您能说的细一点吗 谢谢了哦

int a[n];///估计问题在这里  这是gcc 或者C99标准支持的 但是很多编译器支持的不是很好。 也就是说，你的oj系统，采用的一个或者多个编译器的几个，不支持这个写法 于是不能编译。 虽然，你用你自己的编译器（或者开发环境中的编译器），没有任何问题。 int *a=new int[n];///可以解决这个 ..... delete[] a; ///最后别忘记加上这个。

int  *a = malloc(n * sizeof(int));

引用 3楼Zllvincent 的回复:你的数组是在栈上分配的，不能是动态的，数组大小在编译时就确定了大小的，但是运行成功了编译器也没有问题 请问该怎么改改呢

你的数组是在栈上分配的，不能是动态的，数组大小在编译时就确定了大小的，

int a[n];估计问题在这里

C99 或 gcc 私货 C99 很多编译器支持的不好 因为C99出生太晚了 很少有专门做C编译器  大家一般都是C++编译器， 买一赠一C编译器，而且一般还附赠汇编器。 所以C99标准,各大编译器，支持的不是很好。 个人猜测是这个样子的， 具体原因，真的不知道为何支持这么差。


Question: 用C语言，如何将一个16位二进制字符串转换成十进制整数？？？？？

引用 1 楼 machongcong 的回复:int  m= 0; int n = strlen(AD); for(int i =0;i<n;i++) { if(AD[i]!=0) m+= AD[i]*pow(16,n-1-i); }  m为最终计算的10进制数  int  m= 0;     int n = strlen(AD);     for(int i =0;i<n;i++)     {     if(AD[i]!='0')     m+=pow(2,n-1-i);     }    上面的有点错误

初始整数a为0 ，定义临时变量 t 为1 从低位到高位循环这20个数 每次循环判断，如果是字符1，a &= t; 每次循环完，t <<= 1;

#include <stdio.h>  int main(int argc, char **argv) { 	char str[20] = "0000000000010010"; 	 	long value = 0; 	char * p = str;  	// skip leading zeros 	while(*p == '0') ++p; 	 	if(*p != '\0')  	{ 		value = 1; 		while(*(++p)) 		{		 			value <<= 1; 			if((*p) == '1') value++; 		} 	} 	 	printf("value = %ld\n", value);	 	return 0; }

从低位往高位算啊。。


Question: C语言请问你们会用函数的安全版本吗，比如scanf_s，strncmp,fopen_s之类的？

引用 17 楼 pcboyxhy 的回复:[quote=引用 13 楼 mLee79 的回复:] 进程线程， 网络， UI， FS 是操作系统的事， 关C啥事。  它们比C99更加不可移植[/quote]  比C99好多了， 做一个 POSIX 版本的， 一个 WIN32 版本的就解决了 90% 的问题， UI要么 GL/GLES 要么自己刷离屏表面， 跟系统相关的也就2,3个函数了， 反正我要么跑命令行，要么人肉贴 png， 省事，美工随便画画图也比我们做的界面好看多了。  遇到 RTOS 了， 定制下 代码也不会多。  而要用 C99 就基本得完全不甩 M$， 这也不太好，M$看起来也没有支持 C99 的计划， 我现在在 WIN32 下， 第三方库也全部用 mingw32 编译了， 比用 M$VC 去编译方便很多， 用用 C99 本来也没啥关系， 不过 C99 本来大部分特性也不是太有用， 有用的一般都有编译器扩展支持， 关系也不大。

一般自己写代码不会用，编译也没有问题。 但是在公司如果遇到特殊情况，报错了就用呗，视情况而定，随波逐流。

引用 13 楼 mLee79 的回复:进程线程， 网络， UI， FS 是操作系统的事， 关C啥事。  它们比C99更加不可移植

引用 15 楼 mewiteor 的回复:如果想用请按照C11标准的规定使用。具体见C标准参考。 举个例子（不一定对）  #   ifdef __STDC_LIB_EXT1__     retByScanf = scanf_s("%[a-zA-Z0-9_]",str,size);     printf("scanf_s return %zu.\n",retByScanf); #   else     {         char format[64];         sprintf(format,"%%%zu[a-zA-Z0-9_]",size-1);         retByScanf = scanf(format,str);         printf("scanf return %zu.\n",retByScanf);     } #   endif  char s[4096]={0}; scanf("%4095[^\n]",s);  这是最省事的做法，看起来浪费，由于各种情况都可适用，反而更经济(可以安全替代gets())。 如果是数据库，则需要关心的是类型匹配，这部分必须手工做函数，标准库就是儿戏不能直接使用的。

我一般来说， 库基本只用纯 C， 基本只用C89 特性， app/tools 啥的就随意了。 一般我写的库都在 win/linux/arm-linux/android/rtos ...  下都做测试。

其实完全不用M$的东西也无妨，server和嵌入式有linux和freebsd，手机是ios和android绝对垄断，这些领域都没M$的事。传统PC端软件，倒也不需要C99，性能至关重要的用C++就是了，性能不敏感的现在用C#和Java的也无妨，不必跟C99较劲。

如果想用请按照C11标准的规定使用。具体见C标准参考。 举个例子（不一定对）  // 先输入字符数组的容量，再输入一个字符串（只能包含字母、数字和下划线） #define __STDC_WANT_LIB_EXT1__ 1 #include <stdio.h> #include <malloc.h> #include <stdlib.h>  int main(void) {     size_t size,i,retByScanf;     char* str = NULL;      if (0==scanf("%zu",&size))     {         fputs("scanf return 0",stderr);         exit(EXIT_FAILURE);     }     while('\n'!=getchar());      str=(char*)calloc(size,sizeof(char));     if (NULL==str)     {         fputs("out of memory!",stderr);         exit(EXIT_FAILURE);     }  #   ifdef __STDC_LIB_EXT1__     retByScanf = scanf_s("%[a-zA-Z0-9_]",str,size);     printf("scanf_s return %zu.\n",retByScanf); #   else     {         char format[64];         sprintf(format,"%%%zu[a-zA-Z0-9_]",size-1);         retByScanf = scanf(format,str);         printf("scanf return %zu.\n",retByScanf);     } #   endif      if(retByScanf)         puts(str);     free(str);      return EXIT_SUCCESS; }

关键是fgets,scanf本身就有很安全的用法，自己不用而去用有可能无法移植的“安全”代码，不觉得这实际上是另一种隐性BUG吗

引用 8 楼 mLee79 的回复:glibc 支持么， 不支持谁鸟啊。  C 标准应该是对语言的影响最小的委员会了， C99 都几乎没有人鸟， 就不说 C11 了。 支持不支持是一回事，但这不是方言。

引用 4 楼 mLee79 的回复:不用 _s 这类方言。 已经是C11标准

#pragma warning(disable:4996) ...

进程线程， 网络， UI， FS 是操作系统的事， 关C啥事。

引用 10 楼 mLee79 的回复:一个基本语言特性还在 C89 的竟然用20多年后的标准说事了， 古怪。  可移植性和对程序员的信任是 C 的灵魂, 这些函数没有啥存在的价值。  假设C89以外的东西不用， 进程线程的概念没有了，网络没有了，图形界面没有了，>2G的文件没的处理了，自个儿跟自个儿玩？

引用 10 楼 mLee79 的回复:一个基本语言特性还在 C89 的竟然用20多年后的标准说事了， 古怪。  可移植性和对程序员的信任是 C 的灵魂, 这些函数没有啥存在的价值。 你不原意用就直说了嘛。 先扯不是标准，确定是标准后。就扯到glibc不支持，再接着又拿移植性说事。 只是一些函数而已，不牵涉到语言特性，爱用_s的函数就用，就算glibc不支持，找个实现贴到工程中也没不是什么难事。

会的，我在用VS2013时就要用安全版本，不然会报错，又懒的调解

不用 _s 这类方言。

会

没必要，在scanf("%s",s);时写成 scanf("%5s",s);//---假设s长度为6的话。 之所以出现函数使用的不安全完全是编程者自己偷懒图省事。


Question: C/C++随机数生成

c++11 #include<random>

srand需要且只需要执行一次

random_shuffle 这个算不算


Question: 大神们，帮菜鸟做个数独游戏呗？


Question: 【提问】关于static定义函数的使用问题

我明白了，谢谢

引用 4 楼 Sariel_zq 的回复:但是我测试时不是这样的，是不是我哪里使用有问题 主函数文件： // main.cpp : 定义控制台应用程序的入口点。 //  #include "stdafx.h" #include "A.h" #include "B.h"   int _tmain(int argc, _TCHAR* argv[]) { 	A(); 	B(); 	printf("main\r\n"); 	return 0; }  A.h文件 #include "stdafx.h"  static void fun() { 	printf("AAAAA\r\n"); }  void A() { 	fun(); } B.h文件 #include "stdafx.h"  static void fun() { 	printf("BBBBB\r\n"); }  void B() { 	fun(); }  编译结果 1>------ 已启动生成:  项目: main, 配置: Debug Win32 ------ 1>  main.cpp 1>i:\project\多文件staitc测试\main\main\b.h(4): error C2084: 函数“void fun(void)”已有主体 1>          i:\project\多文件staitc测试\main\main\a.h(3) : 参见“fun”的前一个定义 1>i:\project\多文件staitc测试\main\main\b.h(10): error C3861: “fun”:  找不到标识符 ========== 生成:  成功 0 个，失败 1 个，最新 0 个，跳过 0 个 ========== 是说这个函数重定义了，但我是声明为static了的啊，这里哪有问题吗？  说的文件是指源文件   当一个源程序由多个源文件组成时，根据函数能否被其它源文件中的函数调用，将函数分为内部函数和外部函数。 1 内部函数（又称静态函数） 如果在一个源文件中定义的函数，只能被本文件中的函数调用，而不能被同一程序其它文件中的函数调用，这种函数称为内部函数。 定义一个内部函数，只需在函数类型前再加一个“static”关键字即可： static  函数类型  函数名(函数参数表) 关键字“static”，译成中文就是“静态的”，所以内部函数又称静态函数。但此处“static”的含义不是指存储方式，而是指对函数的作用域仅局限于本文件。 使用内部函数的好处是：不同的人编写不同的函数时，不用担心自己定义的函数，是否会与其它文件中的函数同名，因为同名也没有关系。 2 外部函数 外部函数的定义：在定义函数时，如果没有加关键字“static”，或冠以关键字“extern”，表示此函数是外部函数，也就是我们最常用的函数形式。

变量也好，函数也好，你在不同文件中用static定义不会出现重复定义

可以通过函数指针，等手段，在别的文件里面使用 不能直接通过函数名调用 毕竟 static 本来就是局部的，只打算在这个文件里面使用 static 其实是对其他.c，.cpp 隐藏的私有函数  两个文件里面同名完全没有关系，因为这个名字，只在本文件使用  毕竟 外部函数才是模块的接口。 静态函数不是，他只是实现手段。  各个文件编译的时候，互相没有关联， 连接的时候，才会连接到一起。 所以只有外部函数，才会有命名冲突。  多人开发的话 只需要开发 外部函数，这些名字要统一命名，每个模块的开发者都知道有这个名字。 静态函数，就不必了，可以随意命名。不需要大家都知道。 毕竟只是为何实现，才定义的函数。

两个 fun 相互独立，互不干扰。  ============ 但是程序员有可能被两个同名函数搞糊涂。


Question: VS2015能不能不下断点查看内存

麻烦各位老师们看到了给说一下初学者应该怎样简单了解一下调试方法，以及windows平台下都有哪些常用的调试工具

判断是否越界访问，可以在数组的最后一个元素之后对应的地址处设置数据读写断点。如果该地址对应其它变量干扰判断，可将数组多声明一个元素，并设置数据读写断点在该多出元素对应的地址上。 #include <time.h> #include <stdlib.h> #include <windows.h> int main() {     int a,b[11];//本来是b[10]，为判断哪句越界，故意声明为b[11]      srand((unsigned int)time(NULL));//按两次F11，等黄色右箭头指向本行时，调试、新建断点、新建数据断点，地址：&b[10]，字节计数：4，确定。     while (1) {//按F5，会停在下面某句，此时a的值为10，b[10]已经被修改为对应0..4之一。         b[(a=rand()%11)]=0;         Sleep(100);         b[(a=rand()%11)]=1;         Sleep(100);         b[(a=rand()%11)]=2;         Sleep(100);         b[(a=rand()%11)]=3;         Sleep(100);         b[(a=rand()%11)]=4;         Sleep(100);     }     return 0; }

引用 1 楼 user-2 的回复:VS里不能不断下查看内存，如果要看你可以用一些工具查看内存，但没意义 为什么没有意义啊，理解不了这句话

VS里不能不断下查看内存，如果要看你可以用一些工具查看内存，但没意义


Question: C语言指针传递问题

调用后，x的值肯定变了，因为就指针特性而言，调用后x的地址指向的值为8，所以你的第一个输出是8,8，而第二个输出是在x的值改变后，所以输出为16,8

你需要参考下函数参数压栈的方式

引用 2 楼 yaojuntong77 的回复:楼主，这个问题是因为printf函数对参数的入栈调用规则造成的：  1、printf函数参数的入站顺序为从右至左，因而末尾的x入栈时的值为初始值4（你可以把x改成6试试，同样有这种现象） 2、然后入栈求和函数的地址，于是在代码运行期间，跳转到了求和函数，而求和的系统默认入栈顺序也是从右到左，所以能够顺利地传入存放x为初始值4时的main中变量x的地址； 3、求和函数中，对自身的指针x指向的内存单元地址（main中的变量x的内存单元），通过求和和重新赋值，获得了新值8，并通过返回求和函数的 x 的指针值，新值得以保存到main中的变量x的内存单元中； 4、printf继续执行，从栈中，读出了求和函数处理完成的结果数据（此时x值被改变后的真实数据），和在自己的参数栈中的前期入栈数据（修改前的x的值4）  所以你总会看到这样奇怪的输入； 因为不同的操作系统平台或者不同的编译环境，对参数入栈规则可能略有差异，这样交叉使用同一变量的方法，容易导致错误，还是建议楼主用注释掉的那部分代码来实现，比较安全。  操作系统对于带参数的函数，调用时会涉及两个基本动作： 1、将参数压入临时开辟的栈帧；入栈顺序为：有的系统从右到左，有的系统从左到右； 2、处理参数值；       在处理参数时，往往多数是从左到右，当需要某个局部数据时，会从第一步入栈时的内存区取需要的值进行计算；  在带参函数处理完成后就向其调用者返回处理结果；

序列点问题。 入栈顺序不是求值顺序，C语言没有规定函数参数的求值顺序，具体请看置顶贴


Question: c语言 文件中读取浮点数的问题

可以把这个结构，当作一个编程语言 按照解释器的思路做 也可以看作树结构， 用树的思路 来做  方法是读取关键字解释它的含义（后面的数据是什么） facet侧面 outer 外部 vertex 顶点  这明显是某种图形的结构

仅供参考：//NAME: essaie bla bla //DIMENSION: 8 //DATA //1  14  15 //2  11  10 //3  6   4 //4  7   13 //5  9   21 //6  19  3 //7  1   5 //8  8   8 //EOF // // 文本文件中可能还含有其他内容，但是需要用到的内容即以上  //比如data.txt: //NAME: essaie bla bla //其它内容 //DIMENSION: 8 //其它内容 //DATA //其它内容 //1  14  15 //其它内容 //2  11  10 //其它内容 //3  6   4 //其它内容 //4  7   13 //其它内容 //5  9   21 //其它内容 //6  19  3 //其它内容 //7  1   5 //其它内容 //8  8   8 //其它内容 //EOF  // 目标是要获取NAME后字串，DIMENSION后数值，以及DATA以下的数值 // 其中NAME就是随便个字句，DIMENSION是城市数量，DATA以下是城市编号，X坐标，Y坐标 // 所有的这些将赋值给一个事先定义好的结构 #include <stdio.h> #include <string.h> #define MAXCPL   80   //每行最大字符数 #define MAXCITY  100  //每组数据中DATA最多项数，DIMENSION的最大值 #define MAXNAMEL 32   //NAME最大长度 struct S {     char NAME[MAXNAMEL+1];     int  DIMENSION;     struct D {         int NO;         int X;         int Y;     } DATA[MAXCITY]; } s; FILE *f; int st,n,i; char ln[MAXCPL]; int main() {     f=fopen("data.txt","r");     if (NULL==f) {         printf("Can not open file data.txt!\n");         return 1;     }     st=0;     n=0;     while (1) {         if (NULL==fgets(ln,MAXCPL,f)) break;         if (st==0) {             if (1==sscanf(ln,"NAME: %32[^\n]",s.NAME)) st=1;         } else if (st==1) {             if (1==sscanf(ln,"DIMENSION: %d",&s.DIMENSION)) st=2;         } else if (st==2) {             if (0==strcmp(ln,"DATA\n")) st=3;         } else if (st==3) {             if (3==sscanf(ln,"%d%d%d",&s.DATA[n].NO,&s.DATA[n].X,&s.DATA[n].Y)) {                 n++;                 if (n>=MAXCITY || n>=s.DIMENSION) break;             }         }     }     fclose(f);     printf("s.NAME=[%s]\n",s.NAME);     printf("s.DIMENSION=%d\n",s.DIMENSION);     for (i=0;i<n;i++) {         printf("s.DATA[%d].NO,X,Y=%d,%d,%d\n",i,s.DATA[i].NO,s.DATA[i].X,s.DATA[i].Y);     }     return 0; } //s.NAME=[essaie bla bla] //s.DIMENSION=8 //s.DATA[0].NO,X,Y=1,14,15 //s.DATA[1].NO,X,Y=2,11,10 //s.DATA[2].NO,X,Y=3,6,4 //s.DATA[3].NO,X,Y=4,7,13 //s.DATA[4].NO,X,Y=5,9,21 //s.DATA[5].NO,X,Y=6,19,3 //s.DATA[6].NO,X,Y=7,1,5 //s.DATA[7].NO,X,Y=8,8,8


Question: 关于二维数组的子数组越界问题

两个知识点： 1.  数组在内存中是线性连续的 2. []下标运算符  感谢各位回答

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

a[i][j] 理解成  *(*(a+i)+j)

数组在内存是线性连续

别的语言，至少Fortran,VB，pascal 也是连续内存，但是是否可以这么用，有点记不得了

基于内存的连续性，C,C++ 都不认为有什么问题

引用 4 楼 zhao4zhong1 的回复:理解和讨论之前请先学会如何观察！  计算机组成原理→DOS命令→汇编语言→C语言（不包括C++）、代码书写规范→数据结构、编译原理、操作系统→计算机网络、数据库原理、正则表达式→其它语言（包括C++）、架构……  观察是肯定观察过了，来提问只是想证实一下，或者想得到一个专业或者正规的说法。 我的理解是以c[0] 为起始地址，然后指针往后移动8个存储单元

计算机会正常访问访问c[0][8]！应为编译器是这样理解数组的c[][]解释为**c!然后你自己看！以指针的角度去看会有问题吗!


Question: 关于字符数组的长度的基础问题

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

数组的大小（长度）和“以零结尾的”字符串的长度是两回事，两者完全不同。  以上数组的长度都是固定的。  部分初始化的时候，没有初始化值的数据会被初始化为零。由于数组的长度的不同，造成了有些有 '\0' ，有些没有。造成了他们有些是合法的“以零结尾的字符串”，有些不是。

就像int a[5] = {1,2,3}; 这句，a中后面两个元素将被初始化为0，是这么规定的，同理你的char  另char数组不可以这样初始化：char b[] = "ac0z3df"; 这样结尾也是带有0的

不知道你对长度的理解是什么，是数组的长度还是用strlen测出的数组长度

引用 7 楼 醉花阴柳的回复:不知道你对长度的理解是什么，是数组的长度还是用strlen测出的数组长度 不知道你对长度的理解是什么，是数组的长度还是用strlen测出的长度，多打了两字

当数组或结构使用 {} 赋值的时候，没有被明确赋值的元素或者字段被置为 0. 所以如果数组或者结构需要赋值 0. 直接使用 = { }; 就可以了。  '\0' 的。

引用 3 楼 qq_30632937 的回复:这个结果取决于计算机！我用安卓手机软件c4droid运行没有问题！用电脑测试(5)有问题！(5)的定义看上去没问题！引用时会出现问题！我用标准c编译器！他会访问越界！ 可能侥幸没问题，但是不能保证任何时间、任何环境中都没问题

c对数组检测能力很弱！

引用 1 楼 wang0635的回复:（1）数组中有7个元素，没有初始化到的用0补了 （5）数组中只有6个元素，全初始化了，却没有0 这个数组没有问题吗？


Question: linux C编译出错

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

已经解决了，眼瞎了。和你说的一样。不过十分谢谢……

引用 1 楼 user-2的回复:opnedir还是opendir？ 已经解决了，眼瞎了。和你说的一样。不过十分谢谢……

opnedir还是opendir？


Question: 数据结构的直接插入和简单选择排序 编译时候出现问题 求助！！！

void InsertSort(ElemType a[],int n) { int i,j; ElemType temp; for(i=0;i<n-1;i++) { temp=[a+1]; [a+1]是什么？ j=i; while(j>-1 && temp.key<a[j].key) { a[j+1]=a[j]; j--; } a[j+1]=temp; } }   main() { int n=11; int k; printf("请输入元素"); for(k=0,k<n,k++)   for格式不对 scanf("%d",&a[k]); printf("简单选择排序为："); SelectSort(a[],11);  a[]应该是a，数组a又在哪里定义的呢？ printf("直接插入排序为："); InsertSort(a[],11);  a[]应该是a }

改了之后变成这样   G:\sy14.cpp(37) : error C2059: syntax error : '[' G:\sy14.cpp(53) : error C2143: syntax error : missing ';' before ')' G:\sy14.cpp(53) : error C2143: syntax error : missing ';' before ')' G:\sy14.cpp(54) : error C2065: 'a' : undeclared identifier G:\sy14.cpp(54) : error C2109: subscript requires array or pointer type G:\sy14.cpp(54) : error C2102: '&' requires l-value G:\sy14.cpp(56) : error C2059: syntax error : ']' G:\sy14.cpp(58) : error C2059: syntax error : ']' G:\sy14.cpp(59) : warning C4508: 'main' : function should return a value; 'void' return type assumed 执行 cl.exe 时出错.   #include<stdio.h> #include<stdlib.h>  #define N 100 #define KeyType int   typedef struct { KeyType key; }ElemType;  void SelectSort(ElemType a[],int n) //待排序的n个元素放在数组a中 { int i,j,pos;//pos用来标识每一轮找到的最小关键字位置 ElemType temp; for (i=0;i<n-1;i++) { pos=1;//假定第i条记录为第i轮选择初始时的最小值 for(j=i+1;j<n;j++)//从第i+1条记录到n条记录间寻找关键字最小记录 if(a[j].key<a[pos].key) pos=j;//记住最小元素的下标值 if(pos!=i) { temp=a[i]; a[i]=a[pos]; a[pos]=temp; } } }  void InsertSort(ElemType a[],int n) { int i,j; ElemType temp; for(i=0;i<n-1;i++) { temp=[a+1]; j=i; while(j>-1 && temp.key<a[j].key) { a[j+1]=a[j]; j--; } a[j+1]=temp; } }  main() { int n=11; int k; printf("请输入元素"); for(k=0,k<n,k++) scanf("%d",&a[k]); printf("简单选择排序为："); SelectSort(a[],11); printf("直接插入排序为："); InsertSort(a[],11); }

提示说的很明白啊  typedef struct { KeyType key;  //这里的KeyType是种什么类型，编译器不知道（是否遗漏了包含你的头文件） }ElemType ;  这里要有分号

typedef struct { KeyType key; }ElemType ; 这里要有分号


Question: 这两个全局数组怎么失效了

孩子！以后别撸了！听我的！没错

访问越界！你定义的数组用第101个元素吗？

不错

局部变量和全局变量重名了~

#include <stdio.h> #include <stdlib.h>  #define  MaxNumber 100 #define  MaxWeight1 100 int M[100][100] ; int book[100] ;  struct Goods { 	int	weight[ MaxNumber ] ; 	int value[ MaxNumber]   ; 	int numbers            ;//物品数量 } ;   struct Knapsack { 	int MaxWeight ;  //背包承重量  } ;  int Max( int a, int b ) { 	if(a>b) return a ; 	else return b ; }   //自底向上动态规划 int MaxValue( struct Knapsack *knapsack ,  struct Goods *goods ) { 	int i , j ;  	for(j=0 ; j<=knapsack->MaxWeight ; j++ ) //第0行每列都为0 		M[0][j] = 0 ;     	for(i=1 ; i<=goods->numbers ; i++) 	{ 		M[i][0] = 0  ;	//逐行，从左向右依次填充表格 		for(j=1 ; j<= knapsack->MaxWeight ; j++) 		{ 			if( j< goods->weight[i] ) 				M[i][j] = M[i-1][j] ; 			else   				M[i][j] = Max( M[i-1][j] , goods->value[i]+M[i-1][ j-goods->weight[i] ] ) ;			 		}	 	} 	 	return M[goods->numbers][knapsack->MaxWeight] ; }  void recall(struct Knapsack *knapsack ,  struct Goods *goods ) { 	int i , j ;//回溯表格，标记最优子集中的物品,属于最优子集中的标记为1，否则标记为0 	j=knapsack->MaxWeight ; 	for(i=goods->numbers ; i>=0 ; i--)	 			if(M[i][j] == M[i-1][j] ) 			{ 				book[i]=0 ;//第i个物品放与不放不影响价值，则不需要放入 			} 			else 			{	 				book[i]=1 ;//第i个物品取出 				j = j-goods->weight[i] ; 			} 		  }  int main( ) { 	int i,j ; 	int MV ; 	struct Knapsack *knapsack ; 	struct Goods *goods ;  	knapsack=(struct Knapsack *)malloc(sizeof(struct Knapsack) ) ; 	goods = (struct Goods *)malloc( sizeof(struct Goods) ) ;  	printf("输入背包最大承重量\n"); 	scanf( "%d" , &knapsack->MaxWeight ) ;//输入背包最大承重量  	printf("输入物品数量\n"); 	scanf( "%d" , &goods->numbers ) ; //输入物品数量  	printf("输入物品重量\n"); 	for( i=1 ; i<=goods->numbers ; i++ )//输入物品重量 	{ 		scanf("%d",&goods->weight[i]) ; 	}  	printf("输入物品价值\n"); 	for( i=1 ; i<=goods->numbers ; i++ )//输入物品价值 	{ 		scanf("%d",&goods->value[i]) ; 	}  	MV=MaxValue( knapsack , goods ) ;  	printf("背包能容纳的最大价值%d\n" , MV ) ;	 	 	printf("输出表格\n"); 	for(i=0 ; i<=goods->numbers ; i++)//输出表格 	{	 		for(j=0 ; j<=knapsack->MaxWeight ; j++) 			printf("%d ", M[i][j]) ; 		printf("\n"); 	} 	 	//最优子集不止一种如何输出 	recall( knapsack , goods ) ; 	printf("输出最优子集物品编号\n") ;  	for(i=1;i<=goods->numbers;i++) 		if(book[i]==1) printf("%d ",i) ; 	printf("\n") ; }

找到M[][]的原因了，在函数内部定义了一次M[][]导致全局变量定义失效，book[]失效还在找原因

MaxValue函数中又有一个局部的数组M


Question: 不懂正则求个字符批量求和替换的表达式

分乃身外之物，生不带来，死不带去。 http://bbs.csdn.net/topics/391875032

结贴给分每个人多给了10分，你们自己含糊其辞我也只能看着给了～ @user-2  @zhao4zhong1  @user-2 @zhao4zhong1

引用 9 楼 user-2 的回复:我 无 所 谓 。 那我就选“我 有 所 谓 。”了。 没见《是真的吗？》栏目嘉宾都得选不一样的答案吗？

我 无 所 谓 。

得分分配m君45，赵老师30如何?两位没异议的话过会结贴了 @user-2  @zhao4zhong1  @user-2 @zhao4zhong1

引用 6 楼 user-2 的回复:[quote=引用 4 楼 u013550545 的回复:]...在当前页面,不需要建立js文件。，另改一下代码 以去掉括号：javascript:(function(){var z=document.getElementsByClassName('container')[2];for(var i=0;i<z.childElementCount;++i){z.children[i].lastChild.innerText=z.children[i].lastChild.innerText.replace(/\(\d+\s*\+\d+\)/g,function(s){return eval(s);});}})() 当然，也可以在当前页面，按F12，在Console中输入var z=document.getElementsByClassName('container')[2];for(var i=0;i<z.childElementCount;++i){z.children[i].lastChild.innerText=z.children[i].lastChild.innerText.replace(/\(\d+\s*\+\d+\)/g,function(s){return eval(s);});}然后你顶楼的代码就改好了，只是只能手动选中、复制。 原理就是javascript的String.replace(searchvalue,newvalue)方法，searchvalue是需要被替换的字符串或正则表达式，这里是/\(\d+\s*\+\d+\)/g，表示(一个以上的数字 0个以上空白+一个以上的数字)；newvalue替换文本或替换函数，这里用了javascript的eval把字符串当作表达式计算。[/quote]拜谢十分具体。

引用 4 楼 u013550545 的回复:...在当前页面,不需要建立js文件。，另改一下代码 以去掉括号：javascript:(function(){var z=document.getElementsByClassName('container')[2];for(var i=0;i<z.childElementCount;++i){z.children[i].lastChild.innerText=z.children[i].lastChild.innerText.replace(/\(\d+\s*\+\d+\)/g,function(s){return eval(s);});}})() 当然，也可以在当前页面，按F12，在Console中输入var z=document.getElementsByClassName('container')[2];for(var i=0;i<z.childElementCount;++i){z.children[i].lastChild.innerText=z.children[i].lastChild.innerText.replace(/\(\d+\s*\+\d+\)/g,function(s){return eval(s);});}然后你顶楼的代码就改好了，只是只能手动选中、复制。 原理就是javascript的String.replace(searchvalue,newvalue)方法，searchvalue是需要被替换的字符串或正则表达式，这里是/\(\d+\s*\+\d+\)/g，表示(一个以上的数字 0个以上空白+一个以上的数字)；newvalue替换文本或替换函数，这里用了javascript的eval把字符串当作表达式计算。

引用 3 楼 zhao4zhong1 的回复:case   1://(1  +0) case   9://(9  +0) case  17://(17 +0) case  25://(25 +0) case  33://(33 +0) case  41://(41 +0) case  49://(49 +0) case  57://(57 +0) case  65://(65 +0) case  73://(73 +0) case  81://(81 +0) case  89://(89 +0) case  97://(97 +0) case 105://(105+0) case 113://(113+0) case 121://(121+0) case 129://(129+0) case 137://(137+0) case 145://(145+0) case 153://(153+0) case 161://(161+0) case 169://(169+0) case 177://(177+0) case 185://(185+0) case 193://(193+0) case 201://(201+0) case 209://(209+0) case 217://(217+0) case 225://(225+0) case 233://(233+0) case 241://(241+0) case 249://(249+0) case   2://(1  +1) case  10://(9  +1) case  18://(17 +1) case  26://(25 +1) case  34://(33 +1) case  42://(41 +1) case  50://(49 +1) case  58://(57 +1) case  66://(65 +1) case  74://(73 +1) case  82://(81 +1) case  90://(89 +1) case  98://(97 +1) case 106://(105+1) case 114://(113+1) case 122://(121+1) case 130://(129+1) case 138://(137+1) case 146://(145+1) case 154://(153+1) case 162://(161+1) case 170://(169+1) case 178://(177+1) case 186://(185+1) case 194://(193+1) case 202://(201+1) case 210://(209+1) case 218://(217+1) case 226://(225+1) case 234://(233+1) case 242://(241+1) case 250://(249+1) case   3://(1  +2) case  11://(9  +2) case  19://(17 +2) case  27://(25 +2) case  35://(33 +2) case  43://(41 +2) case  51://(49 +2) case  59://(57 +2) case  67://(65 +2) case  75://(73 +2) case  83://(81 +2) case  91://(89 +2) case  99://(97 +2) case 107://(105+2) case 115://(113+2) case 123://(121+2) case 131://(129+2) case 139://(137+2) case 147://(145+2) case 155://(153+2) case 163://(161+2) case 171://(169+2) case 179://(177+2) case 187://(185+2) case 195://(193+2) case 203://(201+2) case 211://(209+2) case 219://(217+2) case 227://(225+2) case 235://(233+2) case 243://(241+2) case 251://(249+2) case   4://(1  +3) case  12://(9  +3) case  20://(17 +3) case  28://(25 +3) case  36://(33 +3) case  44://(41 +3) case  52://(49 +3) case  60://(57 +3) case  68://(65 +3) case  76://(73 +3) case  84://(81 +3) case  92://(89 +3) case 100://(97 +3) case 108://(105+3) case 116://(113+3) case 124://(121+3) case 132://(129+3) case 140://(137+3) case 148://(145+3) case 156://(153+3) case 164://(161+3) case 172://(169+3) case 180://(177+3) case 188://(185+3) case 196://(193+3) case 204://(201+3) case 212://(209+3) case 220://(217+3) case 228://(225+3) case 236://(233+3) case 244://(241+3) case 252://(249+3) case   5://(1  +4) case  13://(9  +4) case  21://(17 +4) case  29://(25 +4) case  37://(33 +4) case  45://(41 +4) case  53://(49 +4) case  61://(57 +4) case  69://(65 +4) case  77://(73 +4) case  85://(81 +4) case  93://(89 +4) case 101://(97 +4) case 109://(105+4) case 117://(113+4) case 125://(121+4) case 133://(129+4) case 141://(137+4) case 149://(145+4) case 157://(153+4) case 165://(161+4) case 173://(169+4) case 181://(177+4) case 189://(185+4) case 197://(193+4) case 205://(201+4) case 213://(209+4) case 221://(217+4) case 229://(225+4) case 237://(233+4) case 245://(241+4) case 253://(249+4) case   6://(1  +5) case  14://(9  +5) case  22://(17 +5) case  30://(25 +5) case  38://(33 +5) case  46://(41 +5) case  54://(49 +5) case  62://(57 +5) case  70://(65 +5) case  78://(73 +5) case  86://(81 +5) case  94://(89 +5) case 102://(97 +5) case 110://(105+5) case 118://(113+5) case 126://(121+5) case 134://(129+5) case 142://(137+5) case 150://(145+5) case 158://(153+5) case 166://(161+5) case 174://(169+5) case 182://(177+5) case 190://(185+5) case 198://(193+5) case 206://(201+5) case 214://(209+5) case 222://(217+5) case 230://(225+5) case 238://(233+5) case 246://(241+5) case 254://(249+5) case   7://(1  +6) case  15://(9  +6) case  23://(17 +6) case  31://(25 +6) case  39://(33 +6) case  47://(41 +6) case  55://(49 +6) case  63://(57 +6) case  71://(65 +6) case  79://(73 +6) case  87://(81 +6) case  95://(89 +6) case 103://(97 +6) case 111://(105+6) case 119://(113+6) case 127://(121+6) case 135://(129+6) case 143://(137+6) case 151://(145+6) case 159://(153+6) case 167://(161+6) case 175://(169+6) case 183://(177+6) case 191://(185+6) case 199://(193+6) case 207://(201+6) case 215://(209+6) case 223://(217+6) case 231://(225+6) case 239://(233+6) case 247://(241+6) case 255://(249+6) case   8://(1  +7) case  16://(9  +7) case  24://(17 +7) case  32://(25 +7) case  40://(33 +7) case  48://(41 +7) case  56://(49 +7) case  64://(57 +7) case  72://(65 +7) case  80://(73 +7) case  88://(81 +7) case  96://(89 +7) case 104://(97 +7) case 112://(105+7) case 120://(113+7) case 128://(121+7) case 136://(129+7) case 144://(137+7) case 152://(145+7) case 160://(153+7) case 168://(161+7) case 176://(169+7) case 184://(177+7) case 192://(185+7) case 200://(193+7) case 208://(201+7) case 216://(209+7) case 224://(217+7) case 232://(225+7) case 240://(233+7) case 248://(241+7) case 256://(249+7) 666666666666

user-212321君（认得你哟～）试了下结果，chrome浏览器貌似不支持你那样的，或者是mei掌握诀窍?直接用F12控制台了。raner没有js基础，结果是否可以支持以下格式呢?我试了下是失败了呢。不知道是不是我自身没设置好的原因。?⊙▽⊙

把括号内部的运算子替换成运算之后的值


Question: 读配置文件问题

num++;if (num>=100) {printf("SectionNumbers>=100!\n";return 1;}

大早上特意来为楼主改代码，改动如下，望采纳。 #include <stdio.h> #include <stdlib.h> #include <string.h>  int GetConfigSection(char *FileName){     FILE *fp;     //char *SectionName[100];     char SectionName[100][32];     char buffer[100];     int num=0;     memset(SectionName, 0, sizeof(SectionName));     if(NULL==(fp=fopen(FileName,"r"))){         perror("fopen"),exit(-1); } printf("文件打开成功\n");     while(!feof(fp)){ char *p1,*p2;         memset(buffer,0,sizeof(buffer));         if(NULL==fgets(buffer, 20, fp))             break;         if(*buffer == '['){ //printf("%s",buffer); num++; p1 = buffer+1; p2 = buffer+1; while(*p1 != ']') p1++; *p1 = '\0'; //SectionName[num-1] = p2; strcpy(SectionName[num-1],p2); printf("%s\n",SectionName[num-1]);         }     } printf("%s\n",SectionName[0]);         SectionName[0]原来是指向buffer+1的位置的 ，现在buffer+1处的字符串早就为空了。 printf("%s\n",SectionName[1]);           printf("%s\n",SectionName[2]);           printf("节名个数:num=%d\n",num); return num; } int main(void){     int num = GetConfigSection("./Config"); printf("%d\n",num); printf("\n");     return 0; }

因为你char *SectionName[100] 定义的是指针数组，在循环里的时候， SectionName［0］指向p1，所以能打印出来，而出了循环， SectionName［0］只是个指针。   说到底就是你找到的 SectionName 没有保存。  你可以用二维数组 char SectionName[100]［32］，这样就能行。

话说我好像有回答过楼主这个类似问题。


Question: 如何让这个程序在C++中运行

C与C++程序设计学习与实验系统 2013.3 自带TC和VC编译器，自带DOSBox 你这个是TC程序，就用TC编译器 如果要移植到Windows下，可以了解一下EasyX

Head.h 这个文件不存在，先找到这个文件吧

几个头文件都不在，这个程序好像很古老


Question: c语言Puzzle拼图游戏

一直是wronganwser不知道为什么


Question: c语言指针传递原来值到底变不变请教大神

printf()不是函数！ printf()的参数是从右向左计算的！

C语言只有传值调用 所有的实参都不会变 通过参数找到的其他内容有可能被改变

引用 4 楼 srx942173347 的回复:[quote=引用 1 楼 aini_dianlu 的回复:] 函数参数的压栈顺序导致的，就你后面这段打印在不同的编译器上有可能会导致结果不同 请问以后编程怎样避免这样的情况？[/quote] 很简单，在同一个函数的多个参数之间如果有互相计算关系，不要再直接在参数中嵌套调用。 最简单的避免方法就是，先计算函数的值然后再将此值传入函数就行，不要直接嵌套调用。 像你这种情况，如果项目很大，这个隐含的bug会坑死很多人！！！

x变量的地址是复制进函数的，所以返回值（复制后的地址）与原X地址肯定不同 x本身则是相同的，函数中修改的值会反应到X变量

引用 1 楼 aini_dianlu 的回复:函数参数的压栈顺序导致的，就你后面这段打印在不同的编译器上有可能会导致结果不同 请问以后编程怎样避免这样的情况？

刚才在手机上回答的，现在上电脑详细解释一下。 1，这个函数qiuhe2调用之后肯定是会导致传入的参数值发生变化的，这个是毫无疑问的，在这一点上就不用纠结了。 2，C语言中，调用函数时会系统会讲函数的参数压入栈，之后执行函数代码。那么问题来了，对于多个参数，先压入 哪一个参数呢？也就是说，函数的参数时从左到右压栈还是从右到左？这个具体的编译器以及平台会有不同的结果， 有的是从左到右，有的编译器是从右到左。 3，所以，你得问题情况就是如下： a，系统在调用printf时，如果参数从左到右压栈，那么*qiuhe(&x)会比x先执行计算，所以到计算x的时候，其实此时x的值已经 在计算qiuhe(&x)的时候被改变了，此时，x被打印出来就是改变之后的结果。 b，如果系统是从右到左压站，那么，x先别传入printf,之后qiuhe2才会被调用计算出结果并传入printf，此时，打印出的x的 值就是为被改变之前的值。此时就看起来好像是x的值“没变”，其实x的值已经变了，只不过，x先被值传递到printf的而已。

你在16行之后加一句： printf(",调用后x=%d\n",  x); 看结果思考一下

函数参数的压栈顺序导致的，就你后面这段打印在不同的编译器上有可能会导致结果不同


Question: 求解

不要迷信书、考题、老师、回帖； 要迷信CPU、编译器、调试器、运行结果。 并请结合“盲人摸太阳”和“驾船出海时一定只带一个指南针。”加以理解。 任何理论、权威、传说、真理、标准、解释、想象、知识……都比不上摆在眼前的事实！  代码功能归根结底不是别人帮自己看或讲解或注释出来的；而是被自己静下心来花足够长的时间和精力亲自动手单步或设断点或对执行到某步获得的中间结果显示或写到日志文件中一步一步分析出来的。 提醒：再牛×的老师也无法代替学生自己领悟和上厕所！ 单步调试和设断点调试（VS IDE中编译连接通过以后，按F10或F11键单步执行，按Shift+F11退出当前函数；在某行按F9设断点后按F5执行停在该断点处。）是程序员必须掌握的技能之一。

自己运行一下不就知道答案咯 然后再调试一遍，不就知道为啥了？

<script>alert("close me!")</script>

选A。 递归，n的值分别是0 1 2 3。  为了方便，第一个e（）为a，第二个e（）为b。  3是初始值，直到n变成0一直没有输出。 从0开始退出每层递归： 第一步 0的时候，if条件不满足，不输出； 第二步 1的时候输出0； 第三步 2的时候，输出1，b执行，但是条件不满足，没有输出； 第四步 3的时候，输出2，b执行，然后重复第一步和第二步，输出0； 结束。


Question: 请教c语言把malloc申请的内存块写入各种数据后存进文件，但是从文件中读出来时发现数据的位置有变动。即无法读取正确的数据

推荐使用WinHex软件查看硬盘或文件或内存中的原始字节内容。  不要把 fopen("...","...");fscanf,fprintf,fgets,fgetc,fclose //读时把\r\n替换成\n，写时把\n替换成\r\n;读到\x1a就设置EOF;读写的内容当字符看待 和 fopen("...","...b");fseek,ftell,fread,fwrite,fgetc,fclose //不作以上替换，遇到\x1a仍继续读;读写的内容当字节看待 弄混了

任何地址，都不要写入文件 读出来后很可能是无效的，即不是所希望的位置

1）结构体，有对齐问题，这个跟编译器有关 2）int,double 等非单字节数据，有字节序问题，这和CPU等平台相关。 如果你采用的，是同一个操作系统的同一个版本，同一个编译器的同一版本 编译参数也是相同设置。那应该没问题。  如果出现，和上面两种情况相关的问题，那就可能读取出错。 否则，可能是你自己的读写代码有问题。

用结构体，把结构体写到文件里面对取得时候遍历就好了，不会乱不影响使用


Question: c/c++标准有没有规定字符编码？

更多的处理方法是，你的源文件是啥编码的，你的字符串就是啥编码的。  编译器通常不给自己找麻烦做编码转换。  只有程序员才必须知道自己的东西是啥编码的，以便于信息的显示、传输或交换。  ===========  你那个数组，你有没有指定长度，编译器自然会自己计算长度开辟空间。  不过编译器通常不会去管你的编码是啥，程序源文件中，两个引号之间的二进制字节会是字符串的内容。  引用 5 楼 u012879787 的回复:[quote=引用 4 楼 user-2 的回复:] Windows 上 MBCS 字符串，和ANSI字符串 都采用 char数组实现， 这个已经使用很多年了，不可能给什么警告。 除非微软以后都不支持， 仅仅支持 ANSI编码（8bits ,256甚至仅仅128个字符） 和UNICODE编码（16Bits ,后来也不够用了，一部分采用32Bits编码）。 windows 采用 MBCS 编码，支持西方语言和多字节混合编码。 后来又有UNICODE编码，支持统一编码。 linux 采用 UTF8 编码，支持西方语言和多字节混合编码。是单字节和UNICODE编码的杂糅 UTF8 编码 也被网络传输采用 所以，编程语言，尤其是像，C,C++这种跨平台的编程语言，不太可能仅仅支持哪一种编码  不知道你是不是没有理解我的意思，还是我没有理解你的。  我是想说：  1. c/c++编译器对于 字符串的编码默认是由操作系统来决定（编译器没有规定），  windows 采用mbcs， 由于国内几乎都是中文系统，很少见纯英文操作系统。所以编码实际上是gbk，  gbk对中文是2个字节。所以那个数组没有溢出。  2.  linux下默认是utf-8,  gcc默认也采用utf-8， utf8对于中文字符可以采用2-3个，  所以造成了数组溢出！！！  中——E4B8AD  国——E59BBD   加上3个asicc码， 导出溢出！！！   以上是我要表达的观点。  ————————分割线—————————————————————— 下面说你提到的问题：   MBCS 字符串，和ANSI字符串   其中ansi就是mbcs， dbcs也是mbcs的一个子集。   警告的原因是溢出，和微软有没有搞这么多年，感觉没有关系。[/quote]

刚刚查了一下，中国的编码是0x4E2D;0x56FD; 按说，UTF8三字节编码汉字，跟两字节编码 不是同一 位置的数据，应该不会忽而两字节，忽而三字节吧 我觉得，遇到汉字统一三字节应该就可以了 毕竟字符串加结束符是编译系统做的。数组大点没问题。

如果你只是用到 127以内的字符。按照字符数数，没有问题 如果包含汉字，还希望能够兼容，数组只好开大一点了。 不考虑 个别32Bits 汉字， utf8  最多3各字节， MBCS 汉字最多占用2个字节。 unicode 16 汉字两个字节，不过字母也占用两个字节。 如果是网上传过来的文件，会自动转换代码的应该，因为网上用UTF8 正好是linux的格式 Windows估计会做转换 如果是优盘复制就不会转换了

引用 4 楼 user-2 的回复:Windows 上 MBCS 字符串，和ANSI字符串 都采用 char数组实现， 这个已经使用很多年了，不可能给什么警告。 除非微软以后都不支持， 仅仅支持 ANSI编码（8bits ,256甚至仅仅128个字符） 和UNICODE编码（16Bits ,后来也不够用了，一部分采用32Bits编码）。 windows 采用 MBCS 编码，支持西方语言和多字节混合编码。 后来又有UNICODE编码，支持统一编码。 linux 采用 UTF8 编码，支持西方语言和多字节混合编码。是单字节和UNICODE编码的杂糅 UTF8 编码 也被网络传输采用 所以，编程语言，尤其是像，C,C++这种跨平台的编程语言，不太可能仅仅支持哪一种编码  不知道你是不是没有理解我的意思，还是我没有理解你的。  我是想说：  1. c/c++编译器对于 字符串的编码默认是由操作系统来决定（编译器没有规定），  windows 采用mbcs， 由于国内几乎都是中文系统，很少见纯英文操作系统。所以编码实际上是gbk，  gbk对中文是2个字节。所以那个数组没有溢出。  2.  linux下默认是utf-8,  gcc默认也采用utf-8， utf8对于中文字符可以采用2-3个，  所以造成了数组溢出！！！  中——E4B8AD  国——E59BBD   加上3个asicc码， 导出溢出！！！   以上是我要表达的观点。  ————————分割线—————————————————————— 下面说你提到的问题：   MBCS 字符串，和ANSI字符串   其中ansi就是mbcs， dbcs也是mbcs的一个子集。   警告的原因是溢出，和微软有没有搞这么多年，感觉没有关系。

引用 1 楼 user-2 的回复:没有吧， 毕竟操作系统，才能决定该用什么编码 例如 UTF8 编码，Window 并不怎么爱用 不过，C11以及以后的标准， 规定了字符串常量 可以按照 某种编码给出。 u8"abcs" 是UTF8 编码，如此等等 引用 2 楼 fefe82 的回复:这些都是 implementation defined 。也就是，由编译器自行规定。  那这不会带来问题吗？  比如：  char str[7] = "he中国";  不同的编码方式，容易造成，溢出的。  gbk 2个字节一个中文， 如果操作系统用utf8来解释这句代码的话，恐怕？  做个试验：  linux 下编译，果然有警告  vc15 无警告， vc15应该说对警告，错误检测已经很严格了。


Question: 关于位类型

引用 5 楼 paschen 的回复:[quote=引用 4 楼 paschen 的回复:] *(unsigned long*)flag  ?  错了，*(unsigned char*)flag ??[/quote]  *(unsigned char*)&flag

引用 4 楼 paschen 的回复:*(unsigned long*)flag  ?  错了，*(unsigned char*)flag ??

*(unsigned long*)flag  ?

引用 2 楼 mewiteor 的回复:printf("%hhu\n",*(unsigned char*)flag); 少了个&，应该是 printf("%hhu\n",*(unsigned char*)&flag);

printf("%hhu\n",*(unsigned char*)flag);

union U {  FLAGS f; unsigned char u; };  U flag; printf("%d\n", flag.u);

引用 9 楼 ojc520520 的回复:[quote=引用 8 楼 mewiteor 的回复:] [quote=引用 7 楼 ojc520520 的回复:] [quote=引用 3 楼 mewiteor 的回复:] [quote=引用 2 楼 mewiteor 的回复:] printf("%hhu\n",*(unsigned char*)flag); 少了个&，应该是 printf("%hhu\n",*(unsigned char*)&flag);[/quote] hhu这个代表了什么？[/quote]printf, fprintf, sprintf, snprintf, printf_s, fprintf_s [/quote] 英文不好看不懂，好像没看到对hhu的描述[/quote]就是中间的那个表格。length modifier中有hh，Conversion specifier中有u

引用 8 楼 mewiteor 的回复:[quote=引用 7 楼 ojc520520 的回复:] [quote=引用 3 楼 mewiteor 的回复:] [quote=引用 2 楼 mewiteor 的回复:] printf("%hhu\n",*(unsigned char*)flag); 少了个&，应该是 printf("%hhu\n",*(unsigned char*)&flag);[/quote] hhu这个代表了什么？[/quote]printf, fprintf, sprintf, snprintf, printf_s, fprintf_s [/quote] 英文不好看不懂，好像没看到对hhu的描述

引用 7 楼 ojc520520 的回复:[quote=引用 3 楼 mewiteor 的回复:] [quote=引用 2 楼 mewiteor 的回复:] printf("%hhu\n",*(unsigned char*)flag); 少了个&，应该是 printf("%hhu\n",*(unsigned char*)&flag);[/quote] hhu这个代表了什么？[/quote]printf, fprintf, sprintf, snprintf, printf_s, fprintf_s

引用 3 楼 mewiteor 的回复:[quote=引用 2 楼 mewiteor 的回复:] printf("%hhu\n",*(unsigned char*)flag); 少了个&，应该是 printf("%hhu\n",*(unsigned char*)&flag);[/quote] hhu这个代表了什么？


Question: C语言读取文件的一个很奇怪的问题

引用 1 楼 user-1 的回复:fscanf(fp, "%d%d", &a, &b); fscanf(fp, "%d“, &CityInfo[a].TInfo[b].MoneyCost);  你一行的最后一个数据读取的时候要用到 a, b ，所以不要写到一起。  正解，谢谢了！奇怪在第一次读取第一行没问题，后面几次读取才出问题


Question: vs2013编译不过，运行不出来。求大神帮忙看看。

引用 1 楼 user-2的回复:strcpy_s的参数第一个是目的，第二个是目的大小，第三个是源 所以你参数顺序没搞对，你把大小放在最后了 其次把其他函数放到主函数前，或者在主函数前面加上声明 谢谢你啊

谢谢各位大神 ，问题已经解决了 嘿嘿

C++环境下编译，加头文件#include<stdlib.h>; gets_s(name[i], 9);改为gets_s(name[i] ; strcpy_s(temp2, name[i], 7); strcpy_s(name[i], name[min], 7); strcpy_s(name[min], temp2, 7); 上述三条改为 strcpy(temp2, name[i]); strcpy(name[i], name[min]); strcpy(name[min], temp2); 编译通过，运行正确

gets_s(name[i], 9);改为gets(name[i]);


Question: 求助：c语言神奇的问题，真的是日狗了，请各位大神解救

谢谢楼上。。。自己太逗比了

int locate(char *s,char a)//给出字符a在字符串s中的下标 {     int i;     while(*(s+i)!=a&&*(s+i)!='\0') ++i;     if(*(s+i)=='\0'){         printf("There is no 'a' in the string.\n");         return -1;     }     return i; } --- int i,没有对i初始化，改了之后试试呢


Question: 求数组中的不同元素个数

仅供参考：//文件1中的内容排序并去重,结果保存到文件2中 #include <stdio.h> #include <stdlib.h> #include <string.h> #define MAXCHARS 128      //能处理的最大行宽,包括行尾的\n和字符串尾的\0 int MAXLINES=10000,MAXLINES2; char *buf,*buf2; int c,n,hh,i,L; FILE *f; char ln[MAXCHARS]; int ignore_case=0; int icompare(const void *arg1,const void *arg2) {    return stricmp((char *)arg1,(char *)arg2); } int compare(const void *arg1,const void *arg2) {    return strcmp((char *)arg1,(char *)arg2); } int main(int argc,char **argv) {     if (argc<3) {         printf("Unique line. Designed by zhao4zhong1@163.com. 2012-08-20\n");         printf("Usage: %s src.txt uniqued.txt [-i]\n",argv[0]);         return 1;     }     if (argc>3) ignore_case=1;//若存在命令行参数3，忽略大小写     f=fopen(argv[1],"r");     if (NULL==f) {         printf("Can not find file %s!\n",argv[1]);         return 1;     }     buf=(char *)malloc(MAXLINES*MAXCHARS);     if (NULL==buf) {         fclose(f);         printf("Can not malloc(%d LINES*%d CHARS)!\n",MAXLINES,MAXCHARS);         return 2;     }     n=0;     hh=0;     i=0;     while (1) {         if (NULL==fgets(ln,MAXCHARS,f)) break;//         hh++;         L=strlen(ln)-1;         if ('\n'!=ln[L]) {//超长行忽略后面内容             printf("%s Line %d too long(>%d),spilth ignored.\n",argv[1],hh,MAXCHARS);             while (1) {                 c=fgetc(f);                 if ('\n'==c || EOF==c) break;//             }         }         while (1) {//去掉行尾的'\n'和空格             if ('\n'==ln[L] || ' '==ln[L]) {                 ln[L]=0;                 L--;                 if (L<0) break;//             } else break;//         }         if (L>=0) {             strcpy(buf+i,ln);i+=MAXCHARS;             n++;             if (n>=MAXLINES) {                 MAXLINES2=MAXLINES*2;                 if (MAXLINES2==1280000) MAXLINES2=2500000;                 buf2=(char *)realloc(buf,MAXLINES2*MAXCHARS);                 if (NULL==buf2) {                     printf("Can not malloc(%d LINES*%d CHARS)!\n",MAXLINES2,MAXCHARS);                     printf("WARNING: Lines >%d ignored.\n",MAXLINES);                     break;//                 }                 buf=buf2;                 MAXLINES=MAXLINES2;             }         }     }     fclose(f);     if (n>1) {         if (ignore_case) qsort(buf,n,MAXCHARS,icompare);         else qsort(buf,n,MAXCHARS,compare);     }     f=fopen(argv[2],"w");     if (NULL==f) {         free(buf);         printf("Can not create file %s!\n",argv[2]);         return 2;     }     fprintf(f,"%s\n",buf);     if (n>1) {         if (ignore_case) {             hh=0;             L=MAXCHARS;             for (i=1;i<n;i++) {                 if (stricmp((const char *)buf+hh,(const char *)buf+L)) {                     fprintf(f,"%s\n",buf+L);                 }                 hh=L;                 L+=MAXCHARS;             }         } else {             hh=0;             L=MAXCHARS;             for (i=1;i<n;i++) {                 if ( strcmp((const char *)buf+hh,(const char *)buf+L)) {                     fprintf(f,"%s\n",buf+L);                 }                 hh=L;                 L+=MAXCHARS;             }         }     }     fclose(f);     free(buf);     return 0; }

引用 9 楼 醉花阴柳的回复:依题意可以声明int a[6]，下标0-5就表示数字，数组元素初始化都为0(数组元素的值表示那个数字出现的次数)，然后我假设数字是用户输入的(范围限定在5以内)，用t来读取输入的数，读取一个后a[t]自增一。完了要输出时一个循环判断是否数组元素是否为0 原来是数组上限为5，我看成了数字大小上限5，如果数字有范围的话依然可以用这种简化的方法，否则就不行了，就稍微麻烦点

扫描每个元素知道不等， 计数加一 如果没结束，开启下一趟扫描

先用for循环  然后下面用if来判断  如果跟每一个不同 break   输出

就楼主的问题用简化的桶排序就可以

如果数据量大了可以排序了找，这样效率高

#include <stdio.h>   int main() {   int a[] = {1,4,5,26,5,2,3,1,5,4,8,5};   int count = sizeof(a) / sizeof(a[0]);   int n = 0;   for (int i = 0; i < count ; i++) {     for (int j = i + 1 ; j < count ; j++) {       if ( a[i] == a[j]) { //改 if ( p[i] == p[j]) {         n++;         break;//加       }     }     //移 printf("%d", count - n);               //应该移动吧,移了n不就重复减多了嘛   }   printf("%d\n", count - n);   return 0; }

噢 排序是要的 或者采用计数的方式

#include <stdio.h>  int main() {   int a[] = {1,4,5,26,5,2,3,1,5,4,8,5};   int count = sizeof(a) / sizeof(a[0]);   int n = 0;   for (int i = 0; i < count ; i++) {     for (int j = i + 1 ; j < count ; j++) {       if ( a[i] == a[j]) { //改 if ( p[i] == p[j]) {         n++;         break;//加       }     }     //移 printf("%d", count - n);   }   printf("%d\n", count - n);   return 0; }

简化的桶排序,不太了解..具体是怎样的 我写的: int a[] = {1,4,5,26,5,2,3,1,5,4,8,5};   int count = sizeof(a) / sizeof(a[0]);     int n = 0;     for (int i = 0; i < count ; i++) {         for (int j = i + 1 ; j < count ; j++) {             if ( p[i] == p[j]) {                 n ++;             }         }     printf("%d", count - n);


Question: 如何用C编程，遍历一个配置文件中的所有节名，并保存到一个字符指针数组中？？？？请高手们指教！！！

里面居然不能标注红色，重传一次。（令一个帖子不让我传了，只能放到楼主这个帖子了。）  #include <stdio.h> #include <stdlib.h> #include <string.h>  int GetConfigSection(char *FileName){     FILE *fp;     //char *SectionName[100];    char SectionName[100][32];     char buffer[100];     int num=0;     memset(SectionName, 0, sizeof(SectionName));     if(NULL==(fp=fopen(FileName,"r"))){         perror("fopen"),exit(-1); } printf("文件打开成功\n");     while(!feof(fp)){ char *p1,*p2;         memset(buffer,0,sizeof(buffer));         if(NULL==fgets(buffer, 20, fp))             break;         if(*buffer == '['){ //printf("%s",buffer); num++; p1 = buffer+1; p2 = buffer+1; while(*p1 != ']') p1++; *p1 = '\0'; //SectionName[num-1] = p2; strcpy(SectionName[num-1],p2);  printf("%s\n",SectionName[num-1]);         }     } printf("%s\n",SectionName[0]);         SectionName[0]原来是指向buffer+1的位置的 ，现在buffer+1处的字符串早就为空了。 printf("%s\n",SectionName[1]);           printf("%s\n",SectionName[2]);           printf("节名个数:num=%d\n",num); return num; } int main(void){     int num = GetConfigSection("./Config"); printf("%d\n",num); printf("\n");     return 0; }

我这是在linux下，另外能不能写出详细的代码啊，我是个新手啊！

用fgets(fp)一行行读取，第一个字符为‘[’为所需的，保存到定义的数组中。

WINDOWS自身带了读写 ini配置文件的API，不需要自己写 比如GetPrivateProfileString 等，用法网上都有讲


Question: windows窗体应用程序制作一个登陆程序

MessageBox  另建议楼主去C#版块问，那边牛人多。


Question: 有关c语言宏定义

之后如果用到，就把他替换成空，一般仅作一个标记 还有就是如果定义了这个宏可以通过#ifdef  #ifndef 判断是否定义过，根据判断结果编译不同的代码

定义为空，就没作用。  显然在没有定义 ENABLE_DTRACE 的时候，不需要这些语句。


Question: 怎样实现覆盖explorer.exe的打开动作？求C语言大牛帮帮忙，万分感谢。

在cmd窗口中输入以下命令： ftype /? assoc /?


Question: 多线程调度问题

哪个平台？linux？ 加了-lpthread链接选项了没？


Question: 初上OJ；算高精度阶乘和遇到超时，不知道程序还能怎么优化，大神求解

对哦要用数组

__int64 factorial(int num)  //用__int64减小溢出可能性 { 	__int64 value = 1; 	while(num>1) 		value*=num--; 	return value; }

你这好像不是高精度阶乘吧，高精度阶乘可以用数组实现

在计算factorial(int m)的时候，循环中从1开始乘开始已经把1到m-1的阶乘全部计算了一遍， 越小的数的阶乘被重复计算的次数越多，建议楼主建立一个存n个数的数组 long* arr =  (long*)malloc(n*sizeof(long)); arr[0] = 1; for(int i = 1; i <n; ++i) { arr[i] = arr[i-1]*(i+1); }  for(int i = 0; i < n; ++i) { S += arr[i]; }

#include"stdio.h" long main() {     long S=0;     long n,i;     long p=1;     scanf("%d",&n);     for(i=1;i<=n;i++)     {         p*=i;         S+=p;     }     printf("%ld",S); }

刚刚看到你发的觉得好简单可是运行了一下还是超时

#include"stdio.h" long main() { 	long S=0; 	long n,i; 	long c,p=1; 	scanf("%d",&n); 	for(i=1;i<=n;i++) 	{ 		p*=i; 		S+=p; 	} 	printf("%ld",S);  }


Question: 大神求解！初上OJ，最怕遇到答案对却wronganswer的题

楼主现在就改行还来得及。

很多问题，你试下你的版本字符串第一个是数字能统计到吗？isdigit没有包含头文件，ch大小应该是256   #include <stdio.h> #include<ctype.h> int main() { 	int i=0,c=0; 	char ch[256]; 	gets(ch); 	while(ch[i]!='\0') 	{ 		if(isdigit(ch[i])) 			c++; 		i++; 	} 	printf("%d",c); 	return 0; }

首先第一，按照题意，数组为ch[256]才对，应为要包含最后一个结束符‘\0’, 第二，i++，应给放在while循环的最后一句。不然一开始就没检测到ch[0]。 还有while（ch[i]  != '\0'）的意思是检测到最后的字符为‘\0’时结束循环。 ‘\0’是字符串的结束标志。你输入完字符串按确定后，系统会自动在字符串最后加一个'\0'. 所有while判定是以'\0'为结束的标志。

我觉得应该把＇\0＇换成＇\n＇

小白有话想问，就是那个while里面的意思是当ch[i]不等于空格的时候的在开始循环吧（不知道这么理解对不对），但是为什么不能去掉呢，假入我去掉了然后不打空格的话，运行也不对啊，而且我试了试用没有ctype.h的头文件只用stdio.h的也ac了啊请问大神为什么呢

头文件错了#include<iostream>

好像还是错的。

#include"stdio.h" int main() {     int i=0,c=0;     char ch[255];     gets(ch);     while(ch[i]!='\0')     {                if(isdigit(ch[i]))         c++;          i++;//放到这里     }     printf("%d",c); }


Question: 字符数组内容为0X04，0X03，0X00....，作输出后为04 03 00，而不是4 3 0这样的形式?

printf("%02X ",buf[i]);  这跟浮点型数想保留两位小数一样道理

用 "%02X"

printf("%X ",buf[i]) 修改为 printf("%02X ",buf[i]);


Question: 初学者关于数组的问题

告诉你一个最简单的办法。   一批数对吧， 不知道多少个对吧， 那么100个够不够？a[100] 不够？1000个够不够？a[1000] 还不够？100w个够不够？a[1000000] 总够了吧

搂主总得说明你的一堆整数程序是如何输入的阿?对吧,是文件呢,还是一个一个的键盘输入呢,这样才好设计整个程序的逻辑流程.

预先指定个数或结束符。

对于我们初学者来说还不知道动态内存是什么意思， 我大概只会判断一下录入了多少个数字之间的分隔符来判断输入了多少个数字

程序使用方法： 1、每输入一个整数，按一下回车。 2、最后，输入calc，并且按回车开始计算。  #include <stdio.h> #include <stdlib.h> #include <string.h>  typedef struct _Node {     int value;     _Node * next; }Node;  int main() {     //初始化     Node * pHead = new Node;     pHead->next = NULL;     Node * pTemp = NULL;     int max=0, min=0;          //录入数据     char buf[32];     while(true) {         scanf("%s", buf);         if (strcmp(buf, "calc") == 0)             break;         else         {             Node * pTemp = new Node;             pTemp->value = atoi(buf);             pTemp->next = pHead;             pHead = pTemp;         }     }      //计算数据     pTemp = pHead;     max = min = pTemp->value;     while (pTemp->next)     {         if (pTemp->value > max)             max = pTemp->value;         if (pTemp->value < min)             min = pTemp->value;         pTemp = pTemp->next;     }      //输出结果     printf("最大值为%d，最小值为%d\n",max,min);      //清理     while (pHead)     {         pTemp = pHead;         pHead = pHead->next;         delete pTemp;     }      //暂停     system("pause");     return 0; }

可以这么定义 struct unfixedArr { int len; int a[];//这里也可以设为1 个元素 };  unfixedArr *alloc_arr(int n) {      unfixedArr *p = malloc (sizeof(unfixedArr ) +sizeof(int)*n);      if(p)p->len =n;       return p;  }

用链表来实现

先让用户输入数组长度，然后动态分配一个：int* arr = (int*)malloc(n*sizeof(int));   //n为数组元素个数

先malloc申请，不够（判断）再通过relloc申请

一个未定义长度的数组，是编译不了的，数组的内存未指定

VLA或动态内存都可以

大概的意思是a[n]


Question: 关于linux内核链表写法问题

引用 5 楼 chj4129 的回复:1.这里就是一个量表的头，占用2个指针的内存，如果用struct    list_head *app_info_head的话，还需要为app_info_head去kmalloc内存，一般人不会这么写代码的。 2.如果是hash表的表头，就有可能使用指针。  非常感谢 想明白了  如果是指针  这里只不过是分配一个指针变量  没有任何的内存空间  就需要malloc内存然后挂载上去才行！ 所以用结构体方法！

老师  您直接告诉我 不就得了么

网上搜，有理由的。

引用 2 楼 Unixb 的回复:老师  您直接告诉我 不就得了么 问题是我也忘了。 http://www.cnblogs.com/Daniel-G/archive/2013/09/06/3305834.html http://www.cnblogs.com/Anker/archive/2013/12/15/3475643.html

container_of()的存在，让它成为可能 1. 每个需要链入的结构实例中都嵌入list_head实例 2. 通过嵌入list_head实例相互链接起来，而不关心具体的“箱子”结构体是什么，实现了任何类型都能链接起来的通用 3. 通过指定的结构类型，和链表指针，使用container_of()宏反推结构体的基址  打个比方：货运火车见过吧？这个list_head就像货运火车,不同的结构体实例就是火车上的货物，第一节是油罐，第二节是木材，第三节是坦克。container_of()通过链接指针和货物类型，就能获得它的实例基址。


Question: 求助C语言构建数据结构中的线性顺序表

引用 2 楼 roovyoung 的回复:[quote=引用 1 楼 user-2 的回复:] 别直接传结构体。  把所有的函数都修改为传递指针，例如：  Sqlist * InitList_Sq(Sqlist * p_list) {     p_list->elem = ... }  int main(int argc, char ** argv) {      Sqlist La;        InitList_Sq(&La);      ...  } 谢谢，做出来了，能告诉我原因吗？[/quote]  传入函数的参数按值传递只是一个副本，如果你要修改他，应该传递他的地址进函数

引用 1 楼 user-2 的回复:别直接传结构体。  把所有的函数都修改为传递指针，例如：  Sqlist * InitList_Sq(Sqlist * p_list) {     p_list->elem = ... }  int main(int argc, char ** argv) {      Sqlist La;        InitList_Sq(&La);      ...  } 谢谢，做出来了，能告诉我原因吗？


Question: 命令行参数错误！帮忙看看

项目、属性、配置属性、调试、命令参数：填写命令行参数。

去终端输入！ 直接用IDE编译肯定直接通过了！

window下点开开始->运行，输入cmd，定位到你的程序目录，输入程序名空格后输入命令行参数

我说的是main（）函数，它有两种一种是没有参数一种是有两个参数。两个参数就是上面的这种，但是运行不出来啊。

项目属性中可以添加命令行参数，实际运行时可以在命令行下自己加上命令行参数，如果不加的话argc就是1（为程序自身路径） 这方面也不用看书，去网上看下资料就行了，没什么难理解的

上面就会输出 shell.exe  arg1 arg2  arg3

不是，你理解错了。 比如你上面这个是名为shell.exe的执行文件， 你在cmd里面输入 ./shell.exe arg1 arg2 arg3 那么main的形参argv就会包含这四个字符串。


Question: 求c语言大牛指导下，怎么实现在U盘一插入USB时会运行U盘里面的应用程序

搜“AUTORUN.INF”


Question: 在C中如何接收DLL发送的消息

如果指的是SendMessage所发的消息，那么在对应窗口的回调程序中接收该消息。  假设该窗口句柄（hWnd）对应的回调函数为MyWndProc  LRESULT CALLBACK MyWndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) {       switch(uMsg)       {       ...       case MY_DEFINED_MESSAGE:             // do sth.              break;       }       return DefWindowProc(hWnd, uMsg, wParam, lParam); }


Question: 求助，c语言查找排序，快速排序出bug了

出错时点中断，通过调用堆栈、变量窗口等观察分析原因

不知道你是想以什么为依据排序，但是deal[i]=(int) mes[i][7];中没有第8列，你定义的是double mes[4000000][7]，最多到mes[i][6]。另外迭代算法也有问题，自创了几条数据后单步调试发现，Swap(&A[Center], &A[Right - 1]); /* 将基准Pivot藏到右边*/ 在Right=0时出现错误，因为没有&A[-1]，越界了。你可以减少数据调试下

引用 1 楼 zxhuser-3 的回复: 参考代码段: http://pan.baidu.com/s/17yIcQ 还是没明白啊，错误显示就在swap函数那行

参考代码段: http://pan.baidu.com/s/17yIcQ


Question: 一个结构体对齐的问题

引用 2 楼 zhao4zhong1 的回复:仅供参考：#include <stdio.h> #define field_offset(s,f) (int)(&(((struct s *)(0))->f)) struct AD  { int a; char b[13]; double c;}; #pragma pack(push) #pragma pack(1) struct A1  { int a; char b[13]; double c;}; #pragma pack(2) struct A2  { int a; char b[13]; double c;}; #pragma pack(4) struct A4  { int a; char b[13]; double c;}; #pragma pack(8) struct A8  { int a; char b[13]; double c;}; #pragma pack(16) struct A16 { int a; char b[13]; double c;}; #pragma pack(pop) int main() {     printf("AD.a %d\n",field_offset(AD,a));     printf("AD.b %d\n",field_offset(AD,b));     printf("AD.c %d\n",field_offset(AD,c));     printf("\n");     printf("A1.a %d\n",field_offset(A1,a));     printf("A1.b %d\n",field_offset(A1,b));     printf("A1.c %d\n",field_offset(A1,c));     printf("\n");     printf("A2.a %d\n",field_offset(A2,a));     printf("A2.b %d\n",field_offset(A2,b));     printf("A2.c %d\n",field_offset(A2,c));     printf("\n");     printf("A4.a %d\n",field_offset(A4,a));     printf("A4.b %d\n",field_offset(A4,b));     printf("A4.c %d\n",field_offset(A4,c));     printf("\n");     printf("A8.a %d\n",field_offset(A8,a));     printf("A8.b %d\n",field_offset(A8,b));     printf("A8.c %d\n",field_offset(A8,c));     printf("\n");     printf("A16.a %d\n",field_offset(A16,a));     printf("A16.b %d\n",field_offset(A16,b));     printf("A16.c %d\n",field_offset(A16,c));     printf("\n");     return 0; } //AD.a 0 //AD.b 4 //AD.c 24 // //A1.a 0 //A1.b 4 //A1.c 17 // //A2.a 0 //A2.b 4 //A2.c 18 // //A4.a 0 //A4.b 4 //A4.c 20 // //A8.a 0 //A8.b 4 //A8.c 24 // //A16.a 0 //A16.b 4 //A16.c 24 // //  感谢赵老师的，收益良多，但是并非所要答案，

可能是这样的  #pragma pack(push, 1) //.... typedef struct _IMAGE_RELOCATION {     union {         DWORD   VirtualAddress;         DWORD   RelocCount;             // Set to the real count when IMAGE_SCN_LNK_NRELOC_OVFL is set     };     DWORD   SymbolTableIndex;     WORD    Type; } IMAGE_RELOCATION; //....  #pragma pack(pop)  而你的没有设置1字节对齐


Question: 排序问题求解答！

用scanf输入数值,以空格分隔,以回车结束输入,然后用getchar检测是否输入完毕

用C++的STL的list实现很容易。  但是估计楼主这是要求用C的作业题，实现起来就繁琐一些


Question: VS2010合在一起写就不报错，如果分成几个2个头文件和2个c文件，就报错，为什么。。。

引用 10 楼 fefe82 的回复:你的”主函数“和”boc1-1.c"的内容是一样的？ 代码贴错了，问题已经自己解决了，谢谢大家。

你的”主函数“和”boc1-1.c"的内容是一样的？

在你彻底搞清 .h .c 对编译器的区别，以及 c 的编译链接流程之前，不要 #include  .c 。

引用 5 楼 CYTCHAN 的回复:[quote=引用 1 楼 zhao4zhong1 的回复:] .h文件前面加一句 #pragma once 再重建所有不行哎，还是报错。。[/quote] 这个代码作为第一行

引用 6 楼 Jammg 的回复:在Bo1-1.c 里面#include"Bo1-1.c"，想想也是醉了，确定不会死循环吗？还有include .c文件还真没试过，我还是太年轻了恩，现在把函数声明放到"Bo1-1.h"里面去了，不过还是报错

引用 1 楼 zhao4zhong1 的回复:.h文件前面加一句 #pragma once 再重建所有不行哎，还是报错。。

引用 2 楼 wang0635 的回复:惊现 #include"Bo1-1.c" ！ 这样不可以吗？

还是不行。。。

惊现 #include"Bo1-1.c" ！

.h文件前面加一句 #pragma once 再重建所有


Question: 关于推箱子的自动求解

引用 3 楼 heikefangxian23 的回复:赵老师简直神人啊

赵老师简直神人啊

引用 1 楼 zhao4zhong1 的回复:http://download.csdn.net/detail/zhao4zhong1/3230945谢谢！学习一下


Question: 求大神帮忙：字符串中删除与某字符相同的字符。。

仅供参考：#include <stdio.h> #include <string.h> char s[256]; char *p; int r,n,i; int main() {     while (1) {         printf("请输入一行文字(空行结束),\"%%20\"将替换为\" \",\"你懂得\"将替换为\"XXXXXX\":\n");         fgets(s,256,stdin);         if ('\n'==s[0]) break;         p=s;         while (1) {             p=strstr(p,"%20");             if (p) {                 memmove(p+1,p+3,strlen(p)-3+1);                 p[0]=' ';             } else break;         }         p=s;         while (1) {             p=strstr(p,"你懂得");             if (p) {                 memmove(p+6,p+6,strlen(p)-6+1);                 for (i=0;i<6;i++) p[i]='X';             } else break;         }         printf("%s",s);     }     return 0; } //请输入一行文字(空行结束),"%20"将替换为" ","你懂得"将替换为"XXXXXX": //abcdefg%20helloworld%20something.pdf //abcdefg helloworld something.pdf //请输入一行文字(空行结束),"%20"将替换为" ","你懂得"将替换为"XXXXXX": //这是测试文字你懂得，在这个你懂的地方，就得做你懂得的事 //这是测试文字XXXXX，在这个你懂的地方，就得做XXXXX的事 //请输入一行文字(空行结束),"%20"将替换为" ","你懂得"将替换为"XXXXXX": //

指针法 估计指的是 *a++ 数组法 估计是  a[i];

分别用字符数组和字符指针作函数参数两种方法编程实现如下功能：在字符串中删除与某字符相同的字符。 这个其实就是一种方法 作为参数会退化成字符指针 一个意思 void DelChar(char* psz, char delchar) { 	if (psz == NULL) 		return; 	char*pcur =psz; 	char* psearch =psz; 	while(*psearch != '\0') 	{ 		if (*psearch != delchar)	 		{ 			*pcur = *psearch; 			pcur++; 			psearch ++; 		}			 		else 		{ 			psearch ++;		 		}	 	} 	*pcur = '\0'; }

void del(char *p,char ch) {     char *l=p,*r=p;     while(*r){         if(*r!=ch) *l++=*r++;         else ++r;     }     *l ='\0'; }

把代码贴上来，说明白是什么问题


Question: 如何把一段字符串逐段的截取

CString 中find mid 等函数很好用 还有boost中有分割的函数   引用 1 楼 LLW059 的回复:可以使用strtok()函数，char *strtok(char s[], const char *delim);s为要分解的字符串，delim为分隔符字符串。 以逗号为分割符即可，具体用法可以搜一下。 这个也很好用 很多呢 分割字符串函数


Question: C语言中select函数 应用于网络存储中配合fread/fwrite是否存在阻塞问题

select可以先看下是否有数据到来，有再接收，不会阻塞


Question: C语言推箱子，求助！


Question: 关于C primer plus 程序清单7.2 cypher.c程序的困惑

两种写法不同！前者每次循环判断时都会getchar()接收一个字符，后者每次循环都是判断之前的那个ch，而不运行getchar了

按注释写while上面和里面的最下面ch就不需要再读入一个字符了，这样写简化了程序

结果不一样吗，我觉得一样啊


引用 1 楼 user-1 的回复:保存和读出来一样处理，不要做任何手脚 保存成8位也24位处理？

保存和读出来一样处理，不要做任何手脚

15Bits  1:5:5:5 16 Bits 5:6:5 24 Bits 8:8:8 32 Bits 8:8:8:8

另外，位图有正向反向两种位图，他们的主要标志是高的符号 高度为正， 正向，高度为负，反向

当然不是  所有位图的数据，都是32Bits对齐的 15，16，24，32 Bits 数据本身可以看作颜色表（或者叫调色板），所以就没有颜色表了 1，4，8 都是有的颜色表  你的问题是，应该保存为 32Bits对齐。


Question: 数组名作函数的实参，数组做函数的形参问题

数组是一个内存布局。 数组的首地址是一个指针。 而参数是一个变量，一个指针变量，这个变量的内容就是数组的首地址。

你说数组接收一个地址这个描述就是错的，传入的是个指针，可以操作他所指向的内存，并不是只能通过数组读写内存

形式参数都是变量，不管你怎么写

数组在内存中地址是连续的，数组名就是数组中第一个元素的地址，其他元素可以一次推算出来。

数组是数据的聚集，一个数组的第一个元素的地址，可以确定其他元素的地址 所以只要传递第一个元素地址，整个数组的元素都可以找到 由于参数传递时候，是值传递， 数组采用指针的值传递，所以数组的元素个数，不能通过数组名传递 函数需要添加一个参数，表示数组元素个数 这个函数这样写 float  average(int mark[]，int n)//多传入一个参数 n表示元素个数。 { float ave;   int sum=0,i;  for(i=0;i<n;i++)       sum=sum+mark[i];       ave=(float)sum/n;       return(ave); }  int main(){    int i;    int  score[30];    FILE *fp =fopen("score.txt","r");    if(NULL==fp){        printf("Cannot Open %s","score.txt");        exit(-1);    }      for( i=0;i<30;i++)          fscanf(" %d",a+i); //读取成绩     fclose(fp);     printf("Average =%f\n",  average(score,30));     return 0;  }  C++ 的还可以这么做  template <int N>float  average(int (&mark)[N])//传递数组引用，其实数组指针也可以，但是C没有模板，作用不大 { float ave;   int sum=0,i;  for(i=0;i<N;i++)       sum=sum+mark[i];       ave=(float)sum/N;       return(ave); }  int main(){    int i;    int  score[30];    FILE *fp =fopen("score.txt","r");    if(NULL==fp){        printf("Cannot Open %s","score.txt");        exit(-1);    }      for( i=0;i<30;i++)          fscanf(" %d",a+i); //读取成绩     fclose(fp);     printf("Average =%f\n",  average(score,30));     return 0;  }

mark 其实是一个指针。  score 被转换成了指向第一个元素的指针，这个指针传递给饿了 mark 。


Question: float 型数据比较

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

浮点数最好不要做比较，一般是做差再比较差值

浮点数是有精度问题的，不过你这个貌似也不会0.000047大于0.000050吧


Question: 0 error(s), 0 warning(s)   出现“exe”已停止工作

void Sort(long a[],float b[],int n)  {      int i,m;float j;long k;      for(i=0;i<n;m++,i++)  {   for(i=0;i<n-1-m;i++)       {if(a[i]>a[i+1])  {k=a[i];a[i]=a[i+1];a[i+1]=k;   j=b[i];b[i]=b[i+1];b[i+1]=j;}   }  } 局部变量没有初始化~~~ m的值不确定，访问后结果未知~~~

sort函数中，m没有初始化，会导致内存导致越界，程序出现段错误。

两个0是通知你程序的语法上没有编译错误，运行终止则是程序内在的逻辑有错！编译器是管不了逻辑的！好比：合法正规的驾照考试合格了，但是真正上路跑时，依然会出交通事故，这和驾校没有关系的！是车主自己操作有误

首先Sort函数不需要返回，你返回有个retrun 0删了 其实Sort中你的m没有初始化 目前只看了这么多，你先改了看，有问题再回复


Question: 一道作业题，我想破脑子还是没有头绪关于从txt文件读取字符然后在cmd输出

C++ iostream里面中有相关文件读取的类对象，读起来很方便

#include <stdio.h> #include <string.h> #include <stdlib.h> #include <assert.h>   #define MAX_PICTURES (100)  typedef struct picinfo { 	char key[100];  // 图片名称 	int lines;		// 图片的行数 	char * imageData;	// 图片数据的指针 	int cbImageData;	// 图片数据的字节数 }picinfo_t;  size_t read_file(const char * file_name, char ** pp_buffer) { 	FILE * fp; 	char * buffer = NULL; 	assert(NULL != pp_buffer); 	 	buffer = *pp_buffer; 	 	long int size; 	fp = fopen(file_name, "r"); 	if(NULL == fp) 	{ 		perror("fopen"); 		return 0; 	} 	 	fseek(fp, 0, SEEK_END); 	size = ftell(fp); 	fseek(fp, 0, SEEK_SET); 	 	if(size == -1) 	{ 		perror("ftell"); 		return 0; 	} 	 	if(size == 0) return 0; 	 	 	if(NULL == buffer) 	{ 		buffer = (char *)malloc(size + 1); 		assert(NULL != buffer); 	} 	 	 	if(1 != fread(buffer, size, 1, fp)) 	{ 		free(buffer); 		return 0; 	} 	buffer[size] = '\0'; 	if(NULL != pp_buffer && NULL == *pp_buffer) *pp_buffer = buffer; 	 	fclose(fp); 	return size; }  static char * skip_lines(char * iter, int nLines) { 	char * p = iter; 	 	while(nLines > 0) 	{ 		p = strchr(p, '\n'); 		if(NULL == p) return NULL; 		p++; 		nLines--; 	} 	return p; }  int main(int argc, char **argv) { 	int rc; 	const char * file_name = "pictures.txt"; 	char * buffer = NULL; 	char * p; 	size_t cbBuffer; 	 	picinfo_t pics[MAX_PICTURES] = {0}; 	int count = 0; 	int i; 	 	// 把文件全部读入一个缓冲区 	cbBuffer = read_file(file_name, &buffer); 	if(0 == cbBuffer) 	{ 		fprintf(stderr, "read file failed.\n"); 		exit(1); 	} 	 	// 解析从文件中读取的数据，并将相关信息（如名称、长度等）转存至自定义的picinfo_t数组 	p = buffer; 	while(p && (count < MAX_PICTURES)) 	{	 		if(*p == '/' && *(p + 1) == '/')  // 跳过注释行 		{ 			p = skip_lines(p, 1); 			continue; 		} 		if(*p == '\n') // 跳过空白行 		{ 			p = skip_lines(p, 1); 			continue; 		} 		 		// 读取缓冲区中读取图片名称和行数 		rc = sscanf(p, "%s %d", pics[count].key, &pics[count].lines);		 		if(rc != 2 || pics[count].lines <= 0)  		{ 			break; 		} 		 		// 移至下一行 		p = skip_lines(p, 1); 		pics[count].imageData = p;	// 保存图片数据的起始位置的指针 		 		// 移至图片数据末尾 		p = skip_lines(p, pics[count].lines); 		pics[count].cbImageData = p - pics[count].imageData; // 确定图片大小（字节数） 		 		++count; 		if(NULL == p) break; 	} 	 	printf("Pictures list:\n"); 	printf("===================================\n"); 	for(i = 0; i < count; i++) 	{ 		printf("%d: [%s], lines = %d\n", i, pics[i].key, pics[i].lines); 		 	} 	printf("===================================\n\n"); 	 	picinfo_t search = {0}; 	 	 	size_t cb; 	 	while(1) 	{ 		printf("Please input the picture name and preferred lines: \n" 			"example: gun 3\n" 			"(input 'quit 0' to exit)\n"); 		rc = scanf("%s %d]", search.key, &search.lines); 		if(rc == 0 || rc > 2) break; 		 		// 如果输入"quit 0" 则退出程序 		if(strncasecmp(search.key, "quit", 4) == 0) break; 		 		// 在pics数组中查找是否有与用户输入名称相匹配的项 		for(i = 0; i < count; i++) 		{ 			if(strncasecmp(pics[i].key, search.key, sizeof(pics[i].key)) == 0) 			{ 				break; 			} 		} 		 		if(i == count) // 没有 		{ 			printf("not found.\n"); 			continue; 		} 		 		// 默认输出的字节数为整个图片的字节数 		cb = pics[i].cbImageData; 		if(rc == 2) 		{ 			// 如果用户输入的行数为负值，则退出程序			 			if(search.lines < 0) break; 			 			// 如果行数为0或大于实际图片的行数，则调整输出行数为实际图片的行数 			if((search.lines == 0) || (search.lines > pics[i].lines)) search.lines = pics[i].lines; 			else if(search.lines < pics[i].lines) 			{ 				// 如果用户输入的行数小于实际行数，则计算此次输出所需的字节数 				p = pics[i].imageData; 				p = skip_lines(p, search.lines); 				cb = p - pics[i].imageData; 			} 		} 	 		// 输出指定字节数的图片数据到stdout 		fwrite(pics[i].imageData, cb, 1, stdout); 	} 	 	free(buffer); 	 	return 0; }

这个没规律寻吧  要是我就直接一整个输入输出

偷懒的办法是直接数~

整个读进来整个一起输出，不需要一行一行

我想用gets()函数来做，但是我不知道要怎么确定Snoopy 13这些标题的位置和要输出多少行！


Question: 比较字符串数组大小的问题

在string.h中strcmp只能比较字符串 就是a-z或者A-Z，有数字的字符串用Strcmp是不能比较出来的。

引用 1 楼 user-2的回复:if(strcmp(a[2],max)>0) 这句楼主实际应该想表示的是 if(strlen(a[2])>strlen(max))吧 你说的没错 一开始用的strcmp发现不对 改用strlen 结果没有改全

strcmp比较的是字符串，而不是字符串的长度


Question: 判断句 里 ‘=’和‘==’的区别

k=1，是赋值k为1，循环中恒为真。  k==1是判断这个表达式是真还是假

引用 1 楼 user-5 的回复:= 是赋值 == 是比较是否相等  对于你的例子，用=号循环时每次比较相当于是一个赋值，而该值是1，所以永远是true，一直循环 如果改成==，那么你k初始是-1，直接一开始就进不了循环，因为比较结果为假 好好补下基础啊！ 是这样的  = 是赋值          返回的是=号左边的那个值 == 是比较是否相等        返回的是比较后的BOOL值

= 是赋值 == 是比较是否相等

“=”是赋值运算； “==”是逻辑运算； 楼主for循环中条件k=1，条件始终成立，不会跳出循环的。


Question: 急求解假设以邻接矩阵作为图的存储结构，编写算法，判别在给定的有向图中是否存在一个简单的有向回路，若存在，则以顶点序列的方式输出该回路（找到一条即可）（注：图中不

for(int i=0;i<n;i++) if(G[u][i]&&i!=fa){         if(vis[i]<0) { cycle =u;return false;}这个呢         if(!dfs(i,u)) return false; 这个是什么意思     }     vis[u] =1; 1和-1代表什么意思，尽量给解释下具体的思想 快，我要结算帖子了

楼上的好像有问题啊，请再试试 #include<iostream.h> #include<stdlib.h> #include<stdio.h> #include<string.h> #include<conio.h> const int N=100; bool G[N][N]; int path[N], vis[N],n,cycle; bool dfs(int u,int fa) {     vis[u] =-1;     path[u] =fa;     for(int i=0;i<n;i++) if(G[u][i]&&i!=fa){         if(vis[i]<0) { cycle =u;return false;}         if(!dfs(i,u)) return false;     }     vis[u] =1;     return true; } void showpath(int u){     if(u<0) return;     showpath(path[u]);     cout<<' '<<u; } int main() { 	scanf("%d" ,  &n) ;     memset(G , 0 , sizeof(G)) ;     for(int i = 1;i <= n;i++) 	{ 		for(int j = 1;j <= n;j++) 		{ 			scanf("%d" , &G[i][j]) ; 		}     }          cycle =-1;         for( i=0;i<n;i++)  			if(!vis[i]&&!dfs(i,-1)) 				break;         if(cycle<0) 			cout<<"no cycle\n";         else 		{             cout<<"find cycle\n";             showpath(cycle);             cout<<endl;         }     return 0; } 这个程序咋回事，感觉还是有问题，结果不对

应该是明明这个存在环的

const int N=100; bool G[N][N]; int path[N], vis[N],n,cycle; bool dfs(int u,int fa) {     vis[u] =-1;     path[u] =fa;     for(int i=0;i<n;i++) if(G[u][i]&&i!=fa){         if(vis[i]<0) { cycle =u;return false;}         if(!dfs(i,u)) return false;     }     vis[u] =1;     return true; } void showpath(int u){     if(u<0) return;     showpath(path[u]);     cout<<' '<<u; } int main(){          while(cin>>n&&n){         memset(vis,0,sizeof vis);         for(int i=0;i<n;i++) for(int j=0;j<n;j++)             cin>>G[i][j];         cycle =-1;         for(int i=0;i<n;i++) if(!vis[i]&&!dfs(i,-1)) break;         if(cycle<0) cout<<"no cycle\n";         else{             cout<<"find cycle\n";             showpath(cycle);             cout<<endl;         }     }     return 0; }

哦，具体是怎么解释啊，算法思想是什么呢，能简单说下吗

你改了我的代码, 我的结点是从0开始的, 你在读G的时候变成了1开始

楼上的程序还是有问题吧，判断是否有环存在啊，怎么不行啊

这么猛楼上，我试试行不行啊

#include<cstdio> #include<cstring> #include<iostream> using namespace std ; const int maxn = 1010 ; int map[maxn][maxn] ; int vis[maxn] ; int n  ; bool dfs(int u , int &x){     if(vis[u]){         x = u ;         printf("%d\n" , u) ;         return true  ;     }     vis[u] = 1 ;     for(int i = 1;i <= n;i++){         if(map[u][i]){             if(dfs(i , x)){                 if(x && x != u){                     printf("%d\n" , u) ;                 }                 else if(x == u){                      printf("%d\n" , u) ;                      x = 0 ;                 }                 return true  ;             }         }     }     return false ; } int main() {     scanf("%d" ,  &n) ;     memset(map , 0 , sizeof(map)) ;     for(int i = 1;i <= n;i++){          for(int j = 1;j <= n;j++){              scanf("%d" , &map[i][j]) ;          }     }     memset(vis , 0 , sizeof(vis)) ;     bool flag = false ;     for(int i = 1;i <= n;i++){         int x = 0 ;         if(!vis[i]){              if(dfs(i,x)){                  flag = true ;                  break ;              }         }     }     if(!flag){         puts("NO") ;     } }

直接DFS搜一下不行吗

急求，大牛帮忙


Question: c语言程序设计

#include<stdio.h> #include<math.h>  double Monopoly_Game( double n); int main(void) { 	double x; 	x = Monopoly_Game(30); 	printf("%f", x); 	system("pause"); 	return 0; } double Monopoly_Game( double n) { 	if (n > 0) 		return pow(2, n)+Monopoly_Game(n-1); 	else 		return 0; }

一个月那个陌生人就成富翁了，而富翁就成穷人了

int total=0; int new=1; for(int i=0;i<30;i++){ total=total+new; new=new*2; }

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

递归的方法：    #include <stdio.h> #include <assert.h> #include <stdint.h>  #define FIRST_DAY_SUBSIDY (1) // 初始收入  uint64_t income(int day, uint64_t * p_sum) { 	uint64_t value; // 当天收入 	assert(NULL != p_sum);  	 	 	if(day < 1) return 0; 	if(day == 1) 	{ 		value = FIRST_DAY_SUBSIDY; 		*p_sum = value; 		return value; 	} 	 	value = income(day - 1, p_sum);	// 获取前一天的收入（包含前一天的总收入） 	value *= 2;						// 当天收入 = 前一天收入 * 2 	*p_sum += value;					// 总收入 = 当天收入 + 前一天的总收入 	 	return value; // 返回当天的收入 }  int main(int argc, char **argv) { 	uint64_t sum = 0; 	uint64_t value = 0; 	int day; 	 	for(day = 1; day <= 30; day++) 	{	 		value = income(day, &sum); 		printf("%d: value = %ld, sum = %ld\n", day, value, sum); 	} 	 	return 0; }

int total=0; int new=1; for(int i=0;i<30;i++){ new=new*2; total=total+new; } total就是给富翁的钱


Question: 如何给结构体指针的数组分配内存

引用 5 楼 my_live_123 的回复:[quote=引用 3 楼 paschen 的回复:] pash=(position *)malloc(10000*sizeof(pnode));才对  position的类型是pnode*，也就是说是一个指针，你用sizeof得到的是4（32位） 应该是一维吧，pash多了个*，因此强转类型也多了个 * [/quote]  估计楼主是想表示： position pash; pash=(position )malloc(10000*sizeof(pnode));

引用 3 楼 paschen 的回复:pash=(position *)malloc(10000*sizeof(pnode));才对  position的类型是pnode*，也就是说是一个指针，你用sizeof得到的是4（32位） 应该是一维吧，pash多了个*，因此强转类型也多了个 *

你可以做个试验： 打印一下sizeof(Pnode)和sizeof(position)就知道区别了

建议不用写类型, 让编译器自己去推导  10000*sizeof(*pash)

sizeof里面应该是Pnode, 你现在sizeof里面放的是指针，指针大小是4个字节，所以出错了


Question: 为什么用getche（）接受字符之后会在屏幕输出一个a啊？

仅供参考：//The _getch function reads a single character from the console without echoing. //Function can not be used to read CTRL+Break. //When reading a function key or an arrow key, //_getch must be called twice; the first call returns 0 or 0xE0, //and the second call returns the actual key code. #include <conio.h> #include <windows.h> void main() {     unsigned short k;      while (1) {         Sleep(100);         k=getch();         if (27==k) break;//按Esc键退出         if (0==k||0xe0==k) k|=getch()<<8;//非字符键         cprintf("%04x pressed.\r\n",k);     } }

#define VK_LEFT           0x25 #define VK_UP             0x26 #define VK_RIGHT          0x27 #define VK_DOWN           0x28


Question: C语言找出一个字符串中最左边的最长单词

我想问如果用strtok的话是怎么用？ #include <stdio.h> #include <string.h> int main(void){ 	char str[100],*p; 	char max[100]; 	int i,maxnum=0; 	gets(str); 	p=strtok(str," ."); 	if(p){ 		if(strlen(p)>maxnum) 		maxnum=strlen(p); 		max[100]=p; 		p=strtok(NULL," ."); 	} 	printf("%s\n",max[100]); 	return 0; } 我自己这么写好像有毛病，，哭哭。。。

哈哈哈哈weqweqwe

看到自己以前的代码，被自己蠢哭了，哈哈哈。谢谢各位

楼主错误略多啊！我也只是纯粹的帮楼主找错误。已作注释修改，望采纳！    还有个建议，可以去看下strtok（）这个库函数的用法，应该可以简单很多。  #include<stdio.h>> #include<string.h> #define N 80 void LongestWord( char* str,char* c) {     char*b;     char A[N+1];  // 这边有两个错误 1.要定义字符数组非字符指针数组 2.数组定义大     char*a;     int i,j;     b=str;     a=A;      for(j=0;j<strlen(str);j++)     {         if(*(b+j)==' '||*(b+j)=='\0')         {             j++;         }		         for(i=0;*(b+j)!=' '&&*(b+j)!='\0';i++,j++) //这边a的指针偏移不能用j，不然一直是第一个单词，跑不到下面的长度比较中         { 			*(a+i)=*(b+j);  		}         *(a+i)='\0';	//*a='\0',这样字符串的值都被你清空了，strlen(a)恒为0         if(strlen(c)<strlen(a))         {             strcpy(c,a);         }     } } int  main() {   char s[N+1],r[N+1];     gets(s); //********** LongestWord is called here ************     LongestWord(s,r); //**************************************************     printf("%s\n",r);     return 0; }

char *A[128]=>char A[128]

修改如楼上所言，这样效率应该很差吧，如果输入字符分布 39个字母+ 空格+39个字母，你这个方法会不会偏了很多呢？


Question: 关于头文件重复包含的问题

cpp文件不用包含，你加入工程就行（从截图你已经加入了）

你把cpp包括进来了，就会重定义啊，头文件只声明不定义的原因就是防止重定义，你要使用1208里面的函数只要弄个头文件定义一下，然后用cpp实现也能包括进来

是阿，怎么把CPP都包含进来了？这是不好的设计模式

头文件最开始加上 #param once 保证你的头文件只编译一遍

写错了是 #pragma once

#include "1208_01.cpp"   这就是在作死,  虽然语法上能通过.  一般来说include的只应该是.h文件.  再有.一般来说.   全局函数, 全局变量都不要在.h文件中实现.    .h文件中只应该存在声明.  你的问题解决办法:   去掉下面这句 #include "1208_01.cpp"  因为你的fun已经在下面声明了.  编译器会自动去找实现的地方来连接.

#ifndef TEST_H_ #define TEST_H_ ... ... ... #endif 并去掉头文件中包含的1208_1.cpp

再次感谢各位！

感谢各位，理解了。

楼主，你的代码问题出现在#define TEST这一行；  如果代码中多处出现这一行时，编译会出问题，可以把这行删除，然后在Test.h头文件中添加如下行：  LINE01:  #ifndef  __TEST_HEADER_FILE__ LINE02:  #define  __TEST_HEADER_FILE__  // 定义的其它功能性代码  LINE END: #endif  // #define  __TEST_HEADER_FILE__

CPP文件不需要包含

test.h包含1208_01.c后，#include “test.h”这句就会被替换为1208_01.c的内容

是不是在Test.h包含1208_01.cpp后编译，会存在两个fun()函数的定义。

楼主我用你的代码做了下实验 #ifndef  _test_ #define _test_ #include <stdio.h> #include <windows.h> #include "1208_01.c" #define TEST "调用其他文件的函数"   void fun(); #endif 问题有两点  1 #include "1208_01.c“ 相当于文本替换，编译1208.c因此这里printf("%s",TEST)与之后的#define TEST "调用其他文件的函数 出现了问题，对调二者位置， 2 已有fun主体的问题， 在你编译了1208.c之后，1208.obj文件中已经包含了fun函数代码，我用dumpbin看的，我于是在工程中删掉1208_01.c,再组建，不编译1208.c之后可以形成.exe文件，运行有打印，证明确实有fun


Question: 数据结构初学者，求大神指导 C语言

感谢各位大神指教~小的正努力学习中~

同理setqueue也是这个问题

问了好几个学长都不会，估计他们不想认真帮你  setstack你返回的是一个局部变量的指针，函数结束时对象就没了，当然有问题

你建立空栈就错了，楼上已经跟你提出来了，你应该好生理解下存储时期相关的内容

1.楼主你这码得凌乱了，很难看下去，  2,一般给结构分配空间不是用楼主这种stack s；这样分配的，理由楼上，一般用s=(stack*)malloc(sizeof(stack)  3.这样不是在栈（函数体内的变量所在空间），而是在堆中开辟一块地方用于存放你的结构，在堆中开辟的空间存在的时间由你的代码 掌控，或者程序结束，而栈中开辟的空间在你这个函数结束时就没用了，这个栈空间它可能被其他同属一线程的函数使用，


Question: c语言面试题

越界问题，要细腻的思维呀，很容易犯这些小错误的

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

放不下了，越界了

很明显越界了，楼主先把基础打好啊

c的大小是10个字节，memcpy把11个字节数据放到c里面，越界了

超出字符数组c的人容量限制！

后面加'\0'试试


Question: C语言中指针就可以访问地址直接操作了，为什么还要变量呢

明白了，写多就明白了，谢谢

不要捣乱，我支持你

引用 15 楼 tm1mc2 的回复:区分尸食屎柿 http://baike.baidu.com/link?url=FLzIDjlvN5Aalk-J9xd0l6ijfv9Ie49WHc7Cku2U29ssCxdVtY9ozksGvI4x6LqqhaE_al6qmhBB7E4CM_oeFa

区分尸食屎柿

有原子了，为什么还要区别食和屎呢？

有经纬度了，为什么还要地名呢？ 有DNA了，为什么还要种类和姓名呢？

呵呵，这个问题，挺好玩的哦，感觉指针还是挺危险的，用的不好，程序就崩了

哈哈，要不你试一试用01写代码？我相信你会很刺激的 变量是从汇编继承下来的

z=x+y 直接用指针 *（int*）(0x1000) =*(int *)(0x1004)+*(int *)(0x1008); 你看这么做好不? 或者  #define  z  (*(int *)0x1000) #defeine x  (*(int *)0x1004) #define   y  (*(int *)0x1008)  z =x+y

让你直接用0和1编程你干不干

代码贴出来大家看看

最早的程序是直接接线连接 表示01的 整个程序就是线的连接，不连为0，连为1 或者相反

1）可读性，编程语言最早用于解决数学计算 有了变量，表达式 和数学公式差别不大，看着很舒服 2）程序员直接操作内存地址，工作量大，并存在很多隐患。 也没啥可读性， 很难直接按照逻辑编程，安排地址就成为主要工作了

让你直接操作地址，准会闹得一团糟 不如，编译器安排，爽利，看着也比较舒服

直接用二进制机器码就可以写程序了，要高级语言干嘛

指针也是一种变量的一种啊 ...

因为它是高级语言，用变量更抽象，更符合人的思维


Question: 明明感觉很简单，可就是写不出来，求各位大侠看下（能用递归最好）

引用 9 楼 lm_whales 的回复:int invorder(int a[],int n){       int c =0;      if(n==1)return 0;       for(int i=0;i<n-1;i++)              c+= a[i]>a[n-1];        return c + invorder(a,n-1); } 修改一下

int invorder(int a[],int n){       int c =0;      if(n==1)return 0;       for(int i=0;i<n-1;i++)              c+= a[i]>a[n-1];        return t + invorder(a,n-1); }

引用 13 楼 yaojuntong77 的回复:还有一个想法，就是把排列中的所有元素组织成小根堆树，则问题可以转化为： 值超过树根或者子树根的节点总数； 在构造出树结构了以后，再调整成满二叉树，就可以直接用数学公式了  可以在构造出的小根堆的每个节点追加一个卫星数据，用于记录其在原排列中的顺序下标值 接着从树根开始递归遍历树，遇上下标值小于树根或者子树根的就累计加1，否则不累计加

我有个主意，楼主试试： 1、从序偶的要求来看，可以从找到排列中的最小值对应的下标 k[i] 开始，则在该下标前的所有下标均符合序偶构造要求，所以此时有 k[i] 个序偶，将其计入累积量 summary 中； 2、将步骤1找到的最小值从排列中删除，剩下来 n-1 容量的排列，这是步骤1的子问题； 3、判断 剩余的 n-1 容量是否递减到1，如果没有到1，返回 步骤1继续 执行，否则结束循环查找； 4、输出 summary 结果

楼上的算法，我很欣赏，这个是我没有想到的一种实现方式。不过效率还是比我的效率低，测试代码如下： #include <stdio.h> #include <time.h> #include <stdlib.h> #include <string.h>  int invorder(int a[],int n){     int c =0;     if(n==1)return 0;     for(int i=0;i<n-1;i++)         c+= a[i]>a[n-1];     return c + invorder(a,n-1); }  struct Node{     int data;     int nums_r;     Node *parent;     Node *lChild;     Node *rChild; };  class CGetNixuNum { public:     CGetNixuNum() {         nNiXuNum = 0;          NIL = new Node;         memset(NIL, 0, sizeof(Node));         NIL->lChild = NIL;         NIL->rChild = NIL;         NIL->parent = NIL;         root = NIL;      }      ~CGetNixuNum() {         DestroyTree(root);         delete NIL;     }      size_t GetNixuNum() {return nNiXuNum;}      void Insert(int data) {         Node *node = new Node;         memset(NIL, 0, sizeof(Node));          node->data = data;         node->parent = NIL;         node->lChild = node->rChild = NIL;          InsertNode(node);     }  private:     void InsertNode(Node *node) {         Node *p = root;         Node *pP = NIL;         while (p != NIL) {             pP = p;             if (p->data <= node->data) {                 ++(p->nums_r);                 p = p->rChild;             }             else {                 nNiXuNum +=  p->nums_r + 1;                 p = p->lChild;             }         }         node->parent = pP;         if (pP == NIL) root = node;         else {             if (pP->data > node->data) pP->lChild = node;             else pP->rChild = node;         }      }      void DestroyTree(Node *node) {         if (node == NIL) return;         DestroyTree(node->lChild);         DestroyTree(node->rChild);          delete node;     } private:     Node *NIL;     Node *root;      size_t nNiXuNum; };   int main() {     const int SIZE = 50000;     int *a = new int[SIZE];      for (int i=0; i<SIZE; ++i)  {         a[i] = rand() % SIZE;     }      clock_t t1, t2;     double dt;      int nixu;      t1 = clock();     nixu = invorder(a, SIZE);     t2 = clock();     dt = ((double)(t2 - t1))/ CLOCKS_PER_SEC;     printf("%lf sec\n", dt);     printf("ni xu num is: %d\n", nixu);      t1=clock();     CGetNixuNum tree;     for (int i=0; i<SIZE; ++i) {         tree.Insert(a[i]);     }     nixu = tree.GetNixuNum();     t2=clock();     dt = ((double)(t2 - t1))/ CLOCKS_PER_SEC;     printf("%lf sec\n", dt);     printf("ni xu num is: %d\n", nixu);      delete [] a;      return 0; }  测试结果如下： 4.480000 sec ni xu num is: 623351270 0.020000 sec ni xu num is: 623351270

目前 ，我能想到的最快的方法是使用二叉查找数的建立过程来提高算法的效率

#include <stdio.h> #include <string.h>  struct Node{     int data;     int nums_r;     Node *parent;     Node *lChild;     Node *rChild; };  class CGetNixuNum { public:     CGetNixuNum() {         nNiXuNum = 0;          NIL = new Node;         memset(NIL, 0, sizeof(Node));         NIL->lChild = NIL;         NIL->rChild = NIL;         NIL->parent = NIL;         root = NIL;      }      ~CGetNixuNum() {         DestroyTree(root);         delete NIL;     }      size_t GetNixuNum() {return nNiXuNum;}      void Insert(int data) {         Node *node = new Node;         memset(NIL, 0, sizeof(Node));          node->data = data;         node->parent = NIL;         node->lChild = node->rChild = NIL;          InsertNode(node);     }  private:     void InsertNode(Node *node) {         Node *p = root;         Node *pP = NIL;         while (p != NIL) {             pP = p;             if (p->data <= node->data) {                 ++(p->nums_r);                 p = p->rChild;             }             else {                 nNiXuNum +=  p->nums_r + 1;                 p = p->lChild;             }         }         node->parent = pP;         if (pP == NIL) root = node;         else {             if (pP->data > node->data) pP->lChild = node;             else pP->rChild = node;         }      }      void DestroyTree(Node *node) {         if (node == NIL) return;         DestroyTree(node->lChild);         DestroyTree(node->rChild);          delete node;     } private:     Node *NIL;     Node *root;      size_t nNiXuNum; };  int main() {     int a[10] = {0, 8, 9, 5, 7, 6, 2, 1, 3, 4};      CGetNixuNum tree;     for (int i=0; i<10; ++i) {         tree.Insert(a[i]);     }      printf("ni xu num is: %d\n", tree.GetNixuNum());      return 0; }

最直接的方法两层循环 int i, j; int a[SIZE]; for(i = 0; i < sizeof a; ++i)      for(j = i + 1; j < sizeof a; ++j)            if(a[i] > a[j])                //输出

拿分走人，谢谢楼主

直接用merge_sort的思想, a 是输入, t是临时buffer与a等长 int invert_count(int *a,int x,int y,int *t){     if(y-x<=1) return 0;     int m =x+(y-x)/2;     int lct=invert_count(a,x,m,t);     int rct=invert_count(a,m,y,t);     int ct =0,p=x,q=m,i=x;     while(q<y||p<m){         if(q>=y||(p<m&&a[p]<=a[q])) t[i++] =a[p++];         else{             t[i++]  =a[q++];             ct +=m-p;         }     }     for(i=x;i<y;i++) a[i]=t[i];     return ct+lct+rct; }

好像直接有公式都可以算个数的

逆序数量，冒泡排序并统计可以不？

人是怎么做的，就怎么写程序