Question: c语言 两个程序对同一个文件读写

_sopen, _wsopen Open a file for sharing.  int _sopen( const char *filename, int oflag, int shflag [, int pmode ] );  int _wsopen( const wchar_t *filename, int oflag, int shflag [, int pmode ] );  Routine Required Header Optional Headers Compatibility  _sopen <io.h> <fcntl.h>, <sys/types.h>, <sys/stat.h>, <share.h> Win 95, Win NT  _wsopen <io.h> or <wchar.h> <fcntl.h>, <sys/types.h>, <sys/stat.h>, <share.h> 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  Each of these functions returns a file handle for the opened file. A return value of –1 indicates an error, in which case errno is set to one of the following values:  EACCES  Given path is a directory, or file is read-only, but an open-for-writing operation was attempted.  EEXIST  _O_CREAT and _O_EXCL flags were specified, but filename already exists.  EINVAL  Invalid oflag or shflag argument.  EMFILE  No more file handles available.  ENOENT  File or path not found.  Parameters  filename  Filename  oflag  Type of operations allowed  shflag  Type of sharing allowed  pmode  Permission setting  Remarks  The _sopen function opens the file specified by filename and prepares the file for shared reading or writing, as defined by oflag and shflag. _wsopen is a wide-character version of _sopen; the filename argument to _wsopen is a wide-character string. _wsopen and _sopen behave identically otherwise.  Generic-Text Routine Mappings  TCHAR.H Routine  _UNICODE & _MBCS Not Defined _MBCS Defined _UNICODE Defined  _tsopen _sopen _sopen _wsopen    The integer expression oflag is formed by combining one or more of the following manifest constants, defined in the file FCNTL.H. When two or more constants form the argument oflag, they are combined with the bitwise-OR operator ( | ).  _O_APPEND  Repositions file pointer to end of file before every write operation.  _O_BINARY  Opens file in binary (untranslated) mode. (See fopen for a description of binary mode.)  _O_CREAT  Creates and opens new file for writing. Has no effect if file specified by filename exists. The pmode argument is required when _O_CREAT is specified.  _O_CREAT | _O_SHORT_LIVED  Create file as temporary and if possible do not flush to disk. The pmode argument is required when _O_CREAT is specified.  _O_CREAT | _O_TEMPORARY  Create file as temporary; file is deleted when last file handle is closed. The pmode argument is required when _O_CREAT is specified.   _O_CREAT | _O_EXCL  Returns error value if file specified by filename exists. Applies only when used with _O_CREAT.  _O_NOINHERIT  Prevents creation of a shared file handle.  _O_RANDOM  Specifies primarily random access from disk.  _O_RDONLY  Opens file for reading only; cannot be specified with _O_RDWR or _O_WRONLY.  _O_RDWR  Opens file for both reading and writing; cannot be specified with _O_RDONLY or _O_WRONLY.  _O_SEQUENTIAL  Specifies primarily sequential access from disk  _O_TEXT  Opens file in text (translated) mode. (For more information, see Text and Binary Mode File I/O and fopen.)  _O_TRUNC  Opens file and truncates it to zero length; the file must have write permission. You cannot specify this flag with _O_RDONLY. _O_TRUNC used with _O_CREAT opens an existing file or creates a new file.  Warning   The _O_TRUNC flag destroys the contents of the specified file.  _O_WRONLY  Opens file for writing only; cannot be specified with _O_RDONLY or _O_RDWR.  To specify the file access mode, you must specify either _O_RDONLY, _O_RDWR, or _O_WRONLY. There is no default value for the access mode.  The argument shflag is a constant expression consisting of one of the following manifest constants, defined in SHARE.H.  _SH_DENYRW  Denies read and write access to file  _SH_DENYWR  Denies write access to file  _SH_DENYRD  Denies read access to file  _SH_DENYNO  Permits read and write access  The pmode argument is required only when you specify _O_CREAT. If the file does not exist, pmode specifies the file’s permission settings, which are set when the new file is closed the first time. Otherwise pmode is ignored. pmode is an integer expression that contains one or both of the manifest constants _S_IWRITE and _S_IREAD, defined in SYS\STAT.H. When both constants are given, they are combined with the bitwise-OR operator. The meaning of pmode is as follows:  _S_IWRITE  Writing permitted  _S_IREAD  Reading permitted  _S_IREAD | _S_IWRITE  Reading and writing permitted  If write permission is not given, the file is read-only. Under Windows NT and Windows 95, all files are readable; it is not possible to give write-only permission. Thus the modes _S_IWRITE and _S_IREAD | _S_IWRITE are equivalent.  _sopen applies the current file-permission mask to pmode before setting the permissions (see _umask).  Example  /* LOCKING.C: This program opens a file with sharing. It locks  * some bytes before reading them, then unlocks them. Note that the  * program works correctly only if the file exists.  */  #include <io.h> #include <sys/types.h> #include <sys/stat.h> #include <sys/locking.h> #include <share.h> #include <fcntl.h> #include <stdio.h> #include <stdlib.h>  void main( void ) {    int  fh, numread;    char buffer[40];     /* Quit if can't open file or system doesn't      * support sharing.      */    fh = _sopen( "locking.c", _O_RDWR, _SH_DENYNO,                   _S_IREAD | _S_IWRITE );    if( fh == -1 )       exit( 1 );     /* Lock some bytes and read them. Then unlock. */    if( _locking( fh, LK_NBLCK, 30L ) != -1 )    {       printf( "No one can change these bytes while I'm reading them\n" );       numread = _read( fh, buffer, 30 );       printf( "%d bytes read: %.30s\n", numread, buffer );       lseek( fh, 0L, SEEK_SET );      _locking( fh, LK_UNLCK, 30L );       printf( "Now I'm done. Do what you will with them\n" );    }    else       perror( "Locking failed\n" );     _close( fh ); }   Output  No one can change these bytes while I'm reading them 30 bytes read: /* LOCKING.C: This program ope Now I'm done. Do what you will with them   Low-level I/O Routines  See Also   _close, _creat, fopen, _fsopen, _open           _locking Locks or unlocks bytes of a file.  int _locking( int handle, int mode, long nbytes );  Routine Required Header Optional Headers Compatibility  _locking <io.h> and <sys/locking.h> <errno.h> 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  _locking returns 0 if successful. A return value of –1 indicates failure, in which case errno is set to one of the following values:  EACCES  Locking violation (file already locked or unlocked).  EBADF  Invalid file handle.  EDEADLOCK  Locking violation. Returned when the _LK_LOCK or _LK_RLCK flag is specified and the file cannot be locked after 10 attempts.  EINVAL  An invalid argument was given to _locking.  Parameters  handle  File handle  mode  Locking action to perform  nbytes  Number of bytes to lock  Remarks  The _locking function locks or unlocks nbytes bytes of the file specified by handle. Locking bytes in a file prevents access to those bytes by other processes. All locking or unlocking begins at the current position of the file pointer and proceeds for the next nbytes bytes. It is possible to lock bytes past end of file.  mode must be one of the following manifest constants, which are defined in LOCKING.H:  _LK_LOCK  Locks the specified bytes. If the bytes cannot be locked, the program immediately tries again after 1 second. If, after 10 attempts, the bytes cannot be locked, the constant returns an error.  _LK_NBLCK  Locks the specified bytes. If the bytes cannot be locked, the constant returns an error.  _LK_NBRLCK  Same as _LK_NBLCK.  _LK_RLCK  Same as _LK_LOCK.  _LK_UNLCK  Unlocks the specified bytes, which must have been previously locked.  Multiple regions of a file that do not overlap can be locked. A region being unlocked must have been previously locked. _locking does not merge adjacent regions; if two locked regions are adjacent, each region must be unlocked separately. Regions should be locked only briefly and should be unlocked before closing a file or exiting the program.  Example  /* LOCKING.C: This program opens a file with sharing. It locks  * some bytes before reading them, then unlocks them. Note that the  * program works correctly only if the file exists.  */  #include <io.h> #include <sys/types.h> #include <sys/stat.h> #include <sys/locking.h> #include <share.h> #include <fcntl.h> #include <stdio.h> #include <stdlib.h>  void main( void ) {    int  fh, numread;    char buffer[40];     /* Quit if can't open file or system doesn't      * support sharing.      */    fh = _sopen( "locking.c", _O_RDWR, _SH_DENYNO,                   _S_IREAD | _S_IWRITE );    if( fh == -1 )       exit( 1 );     /* Lock some bytes and read them. Then unlock. */    if( _locking( fh, LK_NBLCK, 30L ) != -1 )    {       printf( "No one can change these bytes while I'm reading them\n" );       numread = _read( fh, buffer, 30 );       printf( "%d bytes read: %.30s\n", numread, buffer );       lseek( fh, 0L, SEEK_SET );      _locking( fh, LK_UNLCK, 30L );       printf( "Now I'm done. Do what you will with them\n" );    }    else       perror( "Locking failed\n" );     _close( fh ); }   Output  No one can change these bytes while I'm reading them 30 bytes read: /* LOCKING.C: This program ope Now I'm done. Do what you will with them   File Handling Routines  See Also   _creat, _open

引用 5 楼 rtkgy 的回复:[quote=引用 3 楼 q3733353520 的回复:] 你这个是多线程，还是真正2个程序？ 真正的两个程序  不是多线程 [/quote]  那就是进程间通讯咯

引用 4 楼 cfjtaishan 的回复:[quote=引用 2 楼 rtkgy 的回复:] [quote=引用 1 楼 cfjtaishan 的回复:] 程序1写入的时候写的内容还在内存里，不在文件里，所以程序2读不到内容； 当文件关闭或程序退出时，内存的数据才会刷到（磁盘或flash）文件里，还有可以通过每次强制刷到文件里。  如果是两个程序需要通讯，建议走进程间通信，当然这个需要运用进程间通信的知识，需要注意一个同步。 1.程序写入完会执行fflush 写入进去的 2.这样的情况需要进程通信吗，做到俩个互不干扰就行[/quote] 你的程序都是写吗?[/quote]  程序2 是先读一下在写 先fopen（r+）把里面内容读出来 内容会处理一下  然后fclose 在fopen(w+)清空一下 在把处理的内容写回去 就是这么个流程  也需要程序2执行的时候 程序1 不在执行

引用 3 楼 q3733353520 的回复:你这个是多线程，还是真正2个程序？ 真正的两个程序  不是多线程

引用 2 楼 rtkgy 的回复:[quote=引用 1 楼 cfjtaishan 的回复:] 程序1写入的时候写的内容还在内存里，不在文件里，所以程序2读不到内容； 当文件关闭或程序退出时，内存的数据才会刷到（磁盘或flash）文件里，还有可以通过每次强制刷到文件里。  如果是两个程序需要通讯，建议走进程间通信，当然这个需要运用进程间通信的知识，需要注意一个同步。 1.程序写入完会执行fflush 写入进去的 2.这样的情况需要进程通信吗，做到俩个互不干扰就行[/quote] 你的程序都是写吗?

你这个是多线程，还是真正2个程序？

引用 1 楼 cfjtaishan 的回复:程序1写入的时候写的内容还在内存里，不在文件里，所以程序2读不到内容； 当文件关闭或程序退出时，内存的数据才会刷到（磁盘或flash）文件里，还有可以通过每次强制刷到文件里。  如果是两个程序需要通讯，建议走进程间通信，当然这个需要运用进程间通信的知识，需要注意一个同步。 1.程序写入完会执行fflush 写入进去的 2.这样的情况需要进程通信吗，做到俩个互不干扰就行

引用 7 楼 q3733353520 的回复:[quote=引用 5 楼 rtkgy 的回复:] [quote=引用 3 楼 q3733353520 的回复:] 你这个是多线程，还是真正2个程序？ 真正的两个程序  不是多线程 [/quote]  那就是进程间通讯咯[/quote]  看错了   两个不同的程序调用的同一个so库 去对这一个文件写入........


Question: 网络编程终端连接

Window下的cmd窗口中输入以下命令启动100个记事本： for /L %a in (1,1,100) do start notepad.exe

引用 2 楼 zfh19921230 的回复:脚本怎么执行啊,可以说得明白点不大神 在脚本里用一个循环，比如你的客户端程序是a.out, 那么每次循环都执行一个./a.out 建议先看一下脚本；perl或者Linux的bash也可以（如果是LInux下开发)。

脚本怎么执行啊,可以说得明白点不大神

首先先写一个终端程序（client)，然后用脚本执行该程序呗。


Question: b-树传参问题

因为我原以为SearchBtree中修改p时本来就需要修改传进来的*t

引用 2 楼 zhao4zhong1 的回复:略改，不一定对，还需进一步调试： #include<stdio.h> #include<stdlib.h>  #define MAXM 10 typedef int KeyType; typedef struct node//B-树节点类型定义 { 	int	keynum; 	KeyType	key[MAXM];//key[1....keynum]存放关键字，key[0]不用 	struct node	*parent; 	struct node	*ptr[MAXM];//孩子节点指针数组ptr[0...keynum] }BTNode;  typedef struct//B-树的查找结果类型 { 	BTNode *pt;//指向找到的节点 	int	i;//1..m在节点中中的关键字序号 	int	tag;//1:查找成功 0:查找失败 }Result;    int m;   //m阶B-树 int Max; //m阶B-树每个节点的至多关键字个数，max=m-1; int Min;//m阶B-树非叶子节点的至少关键字个数，min=(m-1)/2  int Search(BTNode *p, KeyType k) { 	//在p->key[1.keynum]中查找i,使得p->key[i]<=k<p->key[i+1] 	int	i =	0; 	for	(i = 0;	i <	p->keynum&&p->key[i	+ 1] <=	k; i++); 	return i; }  Result SearchBTree(BTNode **t, KeyType k) { 	BTNode *p =	*t; 	BTNode *q =	NULL; 	int	found =	0,i	= 0; 	Result r; 	while (p !=	NULL&&found	== 0) 	{ 		i =	Search(p, k);//在p->key[1..keynum]中查找i,使得p->key[i]<=k<p->key[i+1] 		if (i>0	&& p->key[i] ==	k) 		{ 			found =	1; 		} 		else 		{ 			q =	p; 			p =	p->ptr[i];             *t=p; 		} 	} 	r.i	= i; 	if (found == 1)//查找成功 	{ 		r.pt = p; 		r.tag =	1; 	} 	else		 //查找失败，返回k的插入位置信息 	{ 		r.pt = q; 		r.tag =	0; 	} 	return r; }  void Insert(BTNode **q, int i, KeyType x, BTNode *ap) { 	int	j; 	for	(j = (*q)->keynum; j > i; j--) 	{ 		(*q)->key[j	+ 1] = (*q)->key[j]; 		(*q)->ptr[j	+ 1] = (*q)->ptr[j]; 	} 	(*q)->key[i	+ 1] = x; 	(*q)->ptr[i	+ 1] = ap;  	if (ap != NULL) 	{ 		ap->parent = *q; 	} 	(*q)->keynum++; }  void Split(BTNode **q, BTNode **ap) { 	//将节点q分裂成两个节点，前一半保留，后一半移入新生节点qp 	int	i, s = (m +	1) / 2; 	(*ap) =	(BTNode	*)malloc(sizeof(BTNode)); 	(*ap)->ptr[0] =	(*q)->ptr[s]; 	for	(i = s + 1;	i <= m;	i++) 	{ 		(*ap)->key[i - s] =	(*q)->key[i]; 		(*ap)->ptr[i - s] =	(*q)->ptr[i]; 		if ((*ap)->ptr[i - s] != NULL) 		{ 			(*ap)->ptr[i - s]->parent =	*ap; 		} 	} 	(*ap)->keynum =	(*q)->keynum - s; 	(*ap)->parent =	(*q)->parent; 	for	(i = 0;	i <	(*q)->keynum - s; i++) 	{ 		if ((*ap)->ptr[i] != NULL) 		{ 			(*ap)->ptr[i]->parent =	*ap; 		} 	} 	(*q)->keynum = s - 1; } BTNode NewRoot(BTNode **t,BTNode *p,KeyType x,BTNode *ap) { 	(*t) = (BTNode *)malloc(sizeof(BTNode)); 	(*t)->keynum = 1; 	(*t)->ptr[0] = p; 	(*t)->ptr[1] = ap; 	(*t)->key[1] = x; 	if (p != NULL) 	{ 		p->parent =	*t;//是*t 	} 	if (ap != NULL) 	{ 		ap->parent = *t; 	} 	(*t)->parent = NULL; }  void InsertBTree(BTNode **t,KeyType k,BTNode *q,int i) { 	BTNode *ap; 	int	finished, needNewRoot, s; 	KeyType	x; 	if (q == NULL) 	{ 		NewRoot(t,	NULL, k, NULL);//tshi空树，生成只含关键字k的根节点*t 	} 	else 	{ 		x =	k; 		ap = NULL; 		finished = needNewRoot = 0; 		while (needNewRoot == 0	&& finished	== 0) 		{ 			Insert(&q, i, x, ap); 			if (q->keynum <= Max) 			{ 				finished = 1; 			} 			else 			{ 				////分裂结点*q,将q->key[s+1..m],q->ptr[s..m]和q->recptr[s+1..m]移入新结点*ap 				s =	(m + 1)	- 2; 				Split(&q, &ap); 				x =	q->key[s]; 				if (q->parent) 				{ 					q =	q->parent; 					i =	Search(q, x); 				} 				else needNewRoot = 1; 			} 		} 		if (needNewRoot	== 1) 		{ 			NewRoot(t,	q, x, ap); 		} 	} }  void DispBTree(BTNode *t) { 	int	i; 	if (t != NULL) 	{ 		printf("["); 		for	(i = 1;	i <	t->keynum; i++) 		{ 			printf("%d", t->key[i]); 		} 		printf("%d", t->key[i]); 		printf("]"); 		if (t->keynum>0) 		{ 			if (t->ptr[0] != 0) 			{ 				printf("("); 			} 			for	(i = 0;	i <	t->keynum; i++) 			{ 				DispBTree(t->ptr[i]); 				if (t->ptr[i + 1] != NULL) printf(","); 			} 			DispBTree(t->ptr[t->keynum]); 			if (t->ptr[0] != 0)	printf(")"); 		} 	} }  int main() { 	BTNode *t =	NULL; 	Result s; 	int	j, n = 10; 	KeyType	a[]	= {	4, 9, 0, 1,	8, 6, 3, 5,	2, 7 }; 	KeyType	k; 	m =	3; 	Max	= m	- 1; 	Min	= (m - 1) /	2; 	printf("创建一颗%d阶的B-树:\n", m); 	for	(j = 0;	j <	n; j++) 	{ 		s =	SearchBTree(&t,	a[j]); 		if (s.tag == 0) 		{ 			InsertBTree(&t,a[j],s.pt,s.i); 		} 		printf("第%d步，插入%d", j + 1, a[j]); 		DispBTree(t); 		printf("\n"); 	} 	system("pause"); 	return 0;  } 谢谢赵四老师 把你给的代码里SearchBtree里的 加的那句*t=p删掉就正确了

代码太长了，懒得看啊。。。你直接说说你的需求不行么。


Question: 关于strcpy()的一个疑问

第一个name指向位置在堆里；第二个name指向位置在栈里(栈指针本身未初始化为0，编译器自动给初值为0xCCCCCCCC)。

说明编译器没检查出来呗，运行的话会修改掉不该修改的内存，破坏性可想而知

没有问题不等于总是没有问题；这是一个潜在的bug，对于潜在的bug还不如明显的bug好，因为明显的bug好定位，潜在的bug不好定位。 对野指针拷贝数据，是一个潜在的bug;

你确定你第二种是对的？？

你多试几次试试

碰巧了。 正确的程序，一定能得正确的结果。 错误的程序，什么都有可能。


Question: C读取txt列的数据

如果你读懂了Linux下的sed对应源代码的话，你就会变成该领域的大神了。

仅供参考：//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: %31[^\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

不好意思，上面说错了，应该用fprintf(fp, "%f%f%f%f%f",&a[0],&a[1],&a[2],&a[3],&a[4]);

直接读取到数组里，然后输出的时候交换一下位置就可以了，读取直接用scanf("%f%f%f%f%f",&a[0],&a[1],&a[2],&a[3],&a[4])


Question: strcpy()崩溃

引用 8 楼 u014453898 的回复:那为什么int main() { 	char *name; 	strcpy(name,"jimy"); 	return 0; } 又不会发生错误呢 不崩溃不代表下次不崩溃，也不代表在其他环境下不崩溃，也不代表正确

我不知道malloc是怎么用的，只是猜猜。代码可能 不可行。意思就是分配一个适当的存储字符数组的空间。让后让name指向它。

你的结构体里只放了一个char指针和一个int变量，所以字符串没地方放，应该这样      test *p = (test*)malloc(sizeof(test));     p->name = (char*)malloc(64*sizeof(char));//64是你放的最多的字符数     strcpy(p->name,"jim");

#include <stdio.h>  #include <string.h> #define STRSIZE = 10; typedef struct T { 	char *name; 	int num; }test;  int main() { 	test *p = (test*)malloc(sizeof(test));         p->name = (char *)malloc(STRSIZE); 	strcpy(p->name,"jim"); 	printf("%s\n",p->name); 	return 0;  }

结构体分配的空间不包含结构体里面的成员吗？？

name没有malloc空间。

请问那应该如何改呢

给结构分配了内存，但没给name分配空间。


Question: 【求教】怎么用ping判断网络通不通

仅供参考：#include <windows.h> #include <stdio.h> #include <string.h> char YN(int k) {     FILE *f;     char fn[40];     char ln[80];     char yn;     int n;      yn='N';     sprintf(fn,"d:\\ping%d.txt",k);     f=fopen(fn,"r");     if (NULL!=f) {         n=0;         while (1) {             if (NULL==fgets(ln,80,f)) break;//             if (strstr(ln,"ms ")) {                 yn='Y';                 break;//             }             n++;             if (n>=4) break;//         }         fclose(f);     }     return yn; } void main(int argc,char **argv) {     char cmdstr[256];     int i;     int IP[3];     char c;      if (argc<2) {     USAGE:         printf("Usage example:\n    %s 192.168.60.\nto test 192.168.60.1-254\n",argv[0]);         return;     }     if (4==sscanf(argv[1],"%d.%d.%d%c",&IP[0],&IP[1],&IP[2],&c)) {         if (0<=IP[0] && IP[0]<=255          && 0<=IP[1] && IP[1]<=255          && 0<=IP[2] && IP[2]<=255          && '.'==c) {             for (i=1;i<255;i++) {                 sprintf(cmdstr,"cmd /c ping %s%d -n 1 -w 1000 >d:\\ping%d.txt",argv[1],i,i);                 WinExec(cmdstr,SW_HIDE);             }             Sleep(3000);             for (i=1;i<255;i++) {                 printf("%c %s%d\n",YN(i),argv[1],i);             }             Sleep(3000);             WinExec("cmd /c del /q d:\\ping*.txt",SW_HIDE);         } else goto USAGE;     } else goto USAGE; }

在Linux下直接ping 加IP地址就可以了。需要编程吗？如果编程建议使用libpcap库，自己封装ping协议包；然后通过库函数通过网卡发出去。 另外，有些网管或服务器是禁ping的，所以ping也不能完全作为网络通的有理证据。

稍微修改了下  #include <stdio.h> #include <string.h>  #include <unistd.h> #include <sys/types.h> #include <sys/socket.h> #include <netdb.h>   static struct addrinfo *get_host_addrinfo(const char *host, int port) { 	struct addrinfo hints, *pAI; 	char service[16];  	memset(&hints, 0, sizeof(hints)); 	hints.ai_family = AF_UNSPEC;	// don't care ipv4 or ipv6 	hints.ai_socktype = SOCK_STREAM; 	hints.ai_protocol = IPPROTO_TCP;  	sprintf(service, "%d", port); 	if (getaddrinfo(host, service, &hints, &pAI)) 		pAI = NULL;  	return pAI; }  static int connect_to_addr(struct addrinfo *pAI, int *pSock) { 	struct addrinfo *p;  	for (p = pAI; p != NULL; p = p->ai_next) 	{ 		*pSock = socket(p->ai_family, p->ai_socktype, p->ai_protocol); 		if (*pSock != -1) 		{ 			if (connect(*pSock, p->ai_addr, p->ai_addrlen)) 				close(*pSock); 			else 				break; 		} 	}  	return p == NULL; }  static int connect_to_host(const char *host, int port) { 	struct addrinfo *pAI; 	int sock = -1;  	if ((pAI = get_host_addrinfo(host, port))) 	{ 		if (connect_to_addr(pAI, &sock)) 			sock = -1; 		freeaddrinfo(pAI); 	} 	 	return sock; }  static int check_connection(const char *host) { 	if (!host) 		host = "www.baidu.com";  	int sock = connect_to_host(host, 80); 	if (sock != -1) 		close(sock);  	return sock != -1; }   int main() { 	int status = check_connection(NULL); 	if (status) 		printf("connected\n"); 	else 		printf("not connected\n"); }

仅供参考，以下代码只是尝试连接到www.baidu.com，并没有真的ping  #include <stdio.h> #include <string.h>  #include <unistd.h> #include <sys/types.h> #include <sys/socket.h> #include <netdb.h>   static struct addrinfo *get_host_addrinfo(const char *host, int port) { 	struct addrinfo hints, *pAI; 	char service[16]; 	int rv;  	memset(&hints, 0, sizeof(hints)); 	hints.ai_family = AF_UNSPEC;	// don't care ipv4 or ipv6 	hints.ai_socktype = SOCK_STREAM; 	hints.ai_protocol = IPPROTO_TCP;  	sprintf(service, "%d", port); 	if ((rv = getaddrinfo(host, service, &hints, &pAI))) 		pAI = NULL;  	return pAI; }  static int connect_to_addr(struct addrinfo *pAI, int *pSock) { 	struct addrinfo *p;  	for (p = pAI; p != NULL; p = p->ai_next) 	{ 		*pSock = socket(p->ai_family, p->ai_socktype, p->ai_protocol); 		if (*pSock != -1) 		{ 			if (connect(*pSock, p->ai_addr, p->ai_addrlen)) 				close(*pSock); 			else 				break; 		} 	}  	return p == NULL; }  static int connect_to_host(const char *host, int port) { 	struct addrinfo *pAI; 	int sock = -1;  	if ((pAI = get_host_addrinfo(host, port))) 		if (connect_to_addr(pAI, &sock)) 			sock = -1;  	freeaddrinfo(pAI); 	return sock; }  static int check_connection(const char *host) { 	if (!host) 		host = "www.baidu.com";  	int sock = connect_to_host(host, 80); 	if (sock != -1) 		close(sock);  	return sock != -1; }    int main() { 	int status = check_connection(NULL); 	if (status) 		printf("connected\n"); 	else 		printf("not connected\n"); }

引用 5 楼 vnvlyp 的回复:看你什么平台，Windows的话可以使用InternetCheckConnection if(InternetCheckConnection(L"http://www.baidu.com", FLAG_ICC_FORCE_CONNECTION, 0)) {     // 网络正常 }  或者你自己弄个socket，然后尝试连接一个服务器。  好像是linux的，因为我师父让我找的是linux socket ping

int CO_GetNetCardInfo(char *pNetCard, char *pBuf){          int ret = 0;          if((pNetCard == NULL) || (pBuf == NULL)){         return -1;     }     S_NetCardInfo* pCardInfo = (S_NetCardInfo*) pBuf;                  if(get_ipaddr(pNetCard, pCardInfo->ipAddr)){         ret++;             }      if(get_netmask(pNetCard, pCardInfo->maskAddr)){         ret++;     }      if(get_mac(pNetCard, pCardInfo->macAddr)){         ret++;     }      if(get_broadcast(pNetCard,pCardInfo->boardCast)){         ret++;     }      dbgPrintf(LLEV_DBG, "pCardInfo->ipAddr= %s\n",pCardInfo->ipAddr);     dbgPrintf(LLEV_DBG, "pCardInfo->maskAddr= %s\n",pCardInfo->maskAddr);     dbgPrintf(LLEV_DBG, "pCardInfo->macAddr= %s\n",pCardInfo->macAddr);     dbgPrintf(LLEV_DBG, "pCardInfo->boardCast= %s\n",pCardInfo->boardCast);          return (ret == 0 ? 0 : -1); }    代码如上

引用 1 楼 cyfcsd 的回复:如果是windows就进入dos，如果是linux就直接在命令行中 输入ping xxx.xxx.xxx.xxx回车就可以了，xxx的地方就是你要连接的ip地址，如果判断是否连接到互联网，可以ping www.baidu.com 好吧是我没说清，我意思是在代码中ping一下之后判断通不通，通的话显示Ip地址什么的，不通再返回别的地方。我现在具体的情况您可以看一下3楼

手头问题现在的情况是断网的情况下ifconfig还会显示ip地址等，在开发的APP中也会显示ip，通过重启网卡会超时，想请教一下ping的方法


Question: 大神，特殊符号怎么过滤？

引用 5 楼 sdhexu 的回复:有穷自动状态机啊。。。多简单。 正则表达式也行啊。。也不难。

有穷自动状态机啊。。。多简单。

字符串是读文件读出来的，现在想的是用替换的方法，如何替换？转义怎么加进去？

建议sprintf之前，先把name中的其他字符串去掉；然后在sprintf； 如果特殊字符比较有规律的，建议使用sscanf，如果是不规律的，就不好弄了。只能从文件上下工夫。

name="'张三"； 这个字符串怎么会有“'呢？

sql执行肯定报错，打错字了


Question: printf函数问题

加 flush。 不加的话，是否显示没保障，显示也正常，不显示也正常。

xCode是Object-c的编程软件吧； printf需要加上'\n'才能输出，因为标准输出是行缓冲；在标准的C里面还没有遇到你这种情况，还是使用NSLog吧

在每个最后不带\n的printf后面加fflush(stdout); 在每个不想受接收缓冲区旧内容影响的scanf前面加rewind(stdin); 另外请检查scanf的返回值。 //请今后要用 char c; scanf("%c",&c); //时，都改为 char s[2]; char c; scanf("%1s",s); c=s[0];


Question: 大学党求教一个C语言处理数据的问题

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

仅供参考：//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: %31[^\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

fgetc，读到关键字符，然后开始放入一个定义好的缓存里。直到读到结束符，停止读取

一个一个的字符地读，判断一下是不是开始时的字符，是就开始读，直到发现结束时的字符。


Question: C语言初学者提问：请问从哪里能了解所有C语言的函数

外事不决问谷歌，房事不决问百度

还没装linux系统，用的是Mac，谢大神

Linux下可以通过man看库函数或系统函数的说明。比如想看strncpy，可以直接在终端bash输入man strncpy，就可以了。

Windows: MSDN98  MSDN98_1.ISO http://pan.baidu.com/s/1dDF41ix,  MSDN98_2.ISO http://pan.baidu.com/s/1bnGo0Vl Run-Time Routines by Category This chapter lists and describes Microsoft run-time library routines by category. For reference convenience, some routines are listed in more than one category. Multibyte-character routines and wide-character routines are grouped with single-byte – character counterparts, where they exist.  The main categories of Microsoft run-time library routines are:  Argument access Floating-point support  Buffer manipulation Input and output  Byte classification Internationalization  Character classification Memory allocation  Data conversion Process and environment control  Debug Searching and sorting  Directory control String manipulation  Error handling System calls  Exception handling Time management  File handling       Linux:man命令或网站http://www.cplusplus.com/reference/clibrary/

我就是在学完了基础以后不知道干啥，了解清楚然后用一用，谢大神回答

引用 1 楼 jack960330 的回复:这个没有书可以百分百了解，除非你查阅c语音标准函数列表，网上有。。。还有一些参考书会有，书店有卖  但这也是了解个大概，最好的办法是自己把这些函数用上


Question: 大二c语言小白求助，关于用链表实现插入

函数声明建议在main函数外～

1： typedef struct {     elemtype data;     /*struct*/ node *next; }node;  2: 改为 initiate(&p) create(&p, a)


Question: 学完C基础，不知怎样做了，求指点迷津

对学习编程者的忠告： 多用小脑和手，少用大脑、眼睛和嘴，会更快地学会编程！ 眼过千遍不如手过一遍！ 书看千行不如手敲一行！ 手敲千行不如单步一行！ 单步源代码千行不如单步Debug版对应汇编一行！ 单步Debug版对应汇编千行不如单步Release版对应汇编一行！ 不会单步Release版对应汇编？在你想单步Release版C/C++代码片断的前面临时加一句DebugBreak();重建所有，然后在IDE中运行。（一般人我不告诉他！）  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对应的汇编并单步执行观察相应内存和寄存器变化。）

还有淘宝上有很多学习视频

我觉得你拿别人的例子来敲，学习。

赵老师还是讲的比较详细的，但是一般人耐不住寂寞。 因为学到的东西不知道有什么用，开始迷惘了。  程序分支很多，但是很重要的： C 和数据结构，这两个必须过关！ 赵老师所说语言编程规范，没办法，如果你是深受《谭浩强的C》毒害，必须重修编程规范。 个人觉得  英文很关键！！！  快速上手玩东西： c - 单片机，淘宝有的买，也就200/300就有套件玩了。 linux c - 树莓派  淘宝有的买，300大洋左右可以玩了。  不买树莓派，你就装个虚拟机吧。 c++    c++builder,上手非常快的一个UI框架 C#   .net  这个也是拖控件一流。 java-Android，成本不高，一部普通国产手机就可以玩。 c++-MFC  苦逼的UI框架，封装的烂的透底，不知道为什么现在还没挂掉。  有钱的话，报个培训班，若有一线编程经验的老师，可以开阔你的眼界。 建议认真把大学所有基础课学好，出来工作回报一定是丰厚的！ 现在社会很浮躁，你若不浮躁，沉下心来学东西，一般前（钱）途无限美好！

学完C语言基础，还只能是入门C语言；基础还需要加强复习和学习； 个人建议： 1.复习之前学习时记得笔记，总结学习到的知识，并将书本上的练习进行重做或者看一下之前写的是否可以再优化一下，复杂一下；这个优化包括，代码可读性，代码健壮性，容错性，代码性能方面等等，都建议分析一下，温故而知新；还有一个重点，是之前的练习不会做，做的不好的，现在可以继续做一做，都保质保量的做好它。 2. 走出课本，去看一些C语言的其他书籍，并加强自己的动手能力：不停练习和“抄袭”，编译运行，然后总结归纳； 3. 做一些稍微复杂的程序，锻炼自己的编程能力； 4. 继续深入学习C语言，前面都是基础，不论是在编译，调试方面都总结了一些基本能力；接下来继续深入学习新的知识，比如文件操作，链表，二叉树，系统函数（socket编程，文件操作，进程，线程等等）等等；这些的学习会比较复杂，但是没有前面的基础，这些学起来会很吃力。所以基础一定要打牢； 5. 不停的写和调试，不断的总结经验； 6. 大学里可能还开其他的科目，比如数据结构，操作系统，编译原理等等，建议你不要放弃，因为这些和编程是息息相关的； C语言没有近5年的编写过程，不能完全的理解C语言和自如运用C语言； 所以，如果你想一直从事C语言开发，将来想靠它找工作和实现自己的价值，你要做的还很多；如果不感兴趣，或者感觉乏味，建议你早点脱离苦海，转行做其他的（非编程）；  不建议： 1. C语言还没怎么学好，就去忙着学起他，等你毕业了，你什么都是只知道皮毛，什么都不能胜任。我不是说C语言有多好，建议你专一一种语言（不一定是C）；然后其他了解皮毛；  2. 不建议你选择自己不喜欢的东西，然后硬着头皮去做，这样对自己对未来都没好处。

如果涉及网络编程，可能还需要学一些网络基础知识。 也可以自己找一家软件公司去实习，即使不要工资，也能学到很多实际的东西。

汇编  数据结构  操作系统原理   算法  这些都是基础的不能再基础的了。

学c++吧，基本学什么这两个都是基础。

引用 8 楼 u010165006 的回复:巩固C，或者先学C++。  把饼做厚，或者先把饼摊大一点。

巩固C，或者先学C++。

参考书： 《深入理解C指针》 《C语言点滴》 《C陷阱与缺陷》 《C专家编程》 《C语言课程设计案例精编》 C语言程序开发范例宝典 C语言经典编程282例

计算机组成原理→DOS命令→汇编语言→C语言（不包括C++）、代码书写规范→数据结构、编译原理、操作系统→计算机网络、数据库原理、正则表达式→其它语言（包括C++）、架构……


Question: 哈夫曼树 某段代码不太理解

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


Question: 这个c语言程序在gcc编译器下可以正常编译运行，但为什么在vs 2015中只能编译，它的运行结果确是错的呢

你分配的大小是12个元素，下标有效范围是0~11，for (int i = 1; i <= 12; i++) 当i为12时已经越界，未定义行为

按照13 分配内存，计算出结果是10

代码手打实测  int* a =（int *） calloc(12, sizeof(int));  bool* visit = （bool*）calloc(12, sizeof(bool)); 这里需要类型转换  #include <stdbool.h> 头文件未知 windows库文件种没有  主函数增加getchar() 函数，使控制台窗口停留  并没有输出结果，我也很诧异  真心不理解，你那一坨&&条件是什么，反正没有输出任何数据

越界后的行为是未定义的，你这次正常运行，可能下次就会挂。。。。。。和编译器无关

有越界访问 0~12应该分配13个单元

其实电脑开机后物理内存的每个字节都是可读写的，从来不会因为所谓的new、delete或malloc、free而被创建、销毁。区别仅在于操作系统内存管理模块在你读写时是否能发现并是否采取相应动作而已。操作系统管理内存的粒度不是字节而是页，一页通常为4KB。  判断是否越界访问，可以在数组的最后一个元素之后对应的地址处设置数据读写断点。如果该地址对应其它变量干扰判断，可将数组多声明一个元素，并设置数据读写断点在该多出元素对应的地址上。 #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; }


Question: 大神看下c语言递归问题

引用 13 楼 qq_36639412 的回复:引用 12 楼 cfjtaishan 的回复:[quote=引用 10 楼 qq_36639412 的回复:] [quote=引用 8 楼 cfjtaishan 的回复:] [quote=引用 6 楼 qq_36639412 的回复:] [quote=引用 3 楼 cfjtaishan 的回复:] 注意递归是不停的申请函数栈空间，根据先进后出的栈原理，它的输出自然是逆序的。关键是两个if是怎么判断的？条件都是一样的，第一个是不成立就不调用自己，那么第二if也是一样的判断条件呢，是不是可以这样理解，如果输入#了就不调用，返回上一次调用的输入判断满不满足条件？ 如果输入的不是#,函数会继续进入新的函数栈，然后重新开始执行，等待输入，然后判断输入的字符是否为#,如果遇到了#，那么该函数栈继续向后执行，输出最后一个输入的字符，最后一个是#，所以不输出。从最后一个函数栈上退出，返回倒数第二次输入的函数栈，执行余下的语句：   if(i!='#')       printf("%c\n",i);   system("pause"); 倒数第二次输入的不是#，所以把倒数第二次输入的字符输出，然后进入倒数第三次的函数栈，执行：   if(i!='#')       printf("%c\n",i);       system("pause"); 这样输出倒数第三次输入的字符。依次类推，这就是递归嘛[/quote] 嗯，那为什么#还是会输出呢？[/quote] 你确定输出了#? 我试了一下你的程序怎么没有输出#.[/quote] 你看下这段代码怎么会输出， #include<iostream> #include<cstdlib> using namespace std; void Z(int n) {            cin>>n;      if(n!=5)      Z(0);      if(n!=5);     cout<<n<<endl;   system("pause");         } int main() {     Z(0);      return 0;     }  [/quote] 这是第二个问题了，我们一直在讨论你的第一个问题，第二个程序很明显和第一个程序差距很大呢，判断条件都已经变了，怎么可能输入和输出都一样呢？

引用 21 楼 qq_36639412 的回复:引用 20 楼 qq_36639412 的回复:[quote=引用 19 楼 cfjtaishan 的回复:] [quote=引用 18 楼 qq_36639412 的回复:] [quote=引用 17 楼 cfjtaishan 的回复:] [quote=引用 13 楼 qq_36639412 的回复:] [quote=引用 12 楼 cfjtaishan 的回复:] [quote=引用 10 楼 qq_36639412 的回复:] [quote=引用 8 楼 cfjtaishan 的回复:] [quote=引用 6 楼 qq_36639412 的回复:] [quote=引用 3 楼 cfjtaishan 的回复:] 注意递归是不停的申请函数栈空间，根据先进后出的栈原理，它的输出自然是逆序的。关键是两个if是怎么判断的？条件都是一样的，第一个是不成立就不调用自己，那么第二if也是一样的判断条件呢，是不是可以这样理解，如果输入#了就不调用，返回上一次调用的输入判断满不满足条件？ 如果输入的不是#,函数会继续进入新的函数栈，然后重新开始执行，等待输入，然后判断输入的字符是否为#,如果遇到了#，那么该函数栈继续向后执行，输出最后一个输入的字符，最后一个是#，所以不输出。从最后一个函数栈上退出，返回倒数第二次输入的函数栈，执行余下的语句：   if(i!='#')       printf("%c\n",i);   system("pause"); 倒数第二次输入的不是#，所以把倒数第二次输入的字符输出，然后进入倒数第三次的函数栈，执行：   if(i!='#')       printf("%c\n",i);       system("pause"); 这样输出倒数第三次输入的字符。依次类推，这就是递归嘛[/quote] 嗯，那为什么#还是会输出呢？[/quote] 你确定输出了#? 我试了一下你的程序怎么没有输出#.[/quote] 你看下这段代码怎么会输出， #include<iostream> #include<cstdlib> using namespace std; void Z(int n) {            cin>>n;      if(n!=5)      Z(0);      if(n!=5);     cout<<n<<endl;   system("pause");         } int main() {     Z(0);      return 0;     }  [/quote] 这是第二个问题了，我们一直在讨论你的第一个问题，第二个程序很明显和第一个程序差距很大呢，判断条件都已经变了，怎么可能输入和输出都一样呢？[/quote]  引用 17 楼 cfjtaishan 的回复:引用 13 楼 qq_36639412 的回复:[quote=引用 12 楼 cfjtaishan 的回复:] [quote=引用 10 楼 qq_36639412 的回复:] [quote=引用 8 楼 cfjtaishan 的回复:] [quote=引用 6 楼 qq_36639412 的回复:] [quote=引用 3 楼 cfjtaishan 的回复:] 注意递归是不停的申请函数栈空间，根据先进后出的栈原理，它的输出自然是逆序的。关键是两个if是怎么判断的？条件都是一样的，第一个是不成立就不调用自己，那么第二if也是一样的判断条件呢，是不是可以这样理解，如果输入#了就不调用，返回上一次调用的输入判断满不满足条件？ 如果输入的不是#,函数会继续进入新的函数栈，然后重新开始执行，等待输入，然后判断输入的字符是否为#,如果遇到了#，那么该函数栈继续向后执行，输出最后一个输入的字符，最后一个是#，所以不输出。从最后一个函数栈上退出，返回倒数第二次输入的函数栈，执行余下的语句：   if(i!='#')       printf("%c\n",i);   system("pause"); 倒数第二次输入的不是#，所以把倒数第二次输入的字符输出，然后进入倒数第三次的函数栈，执行：   if(i!='#')       printf("%c\n",i);       system("pause"); 这样输出倒数第三次输入的字符。依次类推，这就是递归嘛[/quote] 嗯，那为什么#还是会输出呢？[/quote] 你确定输出了#? 我试了一下你的程序怎么没有输出#.[/quote] 你看下这段代码怎么会输出， #include<iostream> #include<cstdlib> using namespace std; void Z(int n) {            cin>>n;      if(n!=5)      Z(0);      if(n!=5);     cout<<n<<endl;   system("pause");         } int main() {     Z(0);      return 0;     }  [/quote] 这是第二个问题了，我们一直在讨论你的第一个问题，第二个程序很明显和第一个程序差距很大呢，判断条件都已经变了，怎么可能输入和输出都一样呢？[/quote] 是一样的啊，只是判断的是个整数，第一个程序是字符，那第二个怎么会输出不满足的条件值呢[/quote] 嗯，条件不一样，你输入#是可以输出#的，因为#不是5；你的判断条件是只要输入的不是5，都会将输入的内容倒序输出。[/quote] 嗯，但是输入12345，输出54321，这正确么？5不是条件嘛[/quote] 哦，知道问题了，if那里执行了空语句[/quote]

引用 20 楼 qq_36639412 的回复:引用 19 楼 cfjtaishan 的回复:[quote=引用 18 楼 qq_36639412 的回复:] [quote=引用 17 楼 cfjtaishan 的回复:] [quote=引用 13 楼 qq_36639412 的回复:] [quote=引用 12 楼 cfjtaishan 的回复:] [quote=引用 10 楼 qq_36639412 的回复:] [quote=引用 8 楼 cfjtaishan 的回复:] [quote=引用 6 楼 qq_36639412 的回复:] [quote=引用 3 楼 cfjtaishan 的回复:] 注意递归是不停的申请函数栈空间，根据先进后出的栈原理，它的输出自然是逆序的。关键是两个if是怎么判断的？条件都是一样的，第一个是不成立就不调用自己，那么第二if也是一样的判断条件呢，是不是可以这样理解，如果输入#了就不调用，返回上一次调用的输入判断满不满足条件？ 如果输入的不是#,函数会继续进入新的函数栈，然后重新开始执行，等待输入，然后判断输入的字符是否为#,如果遇到了#，那么该函数栈继续向后执行，输出最后一个输入的字符，最后一个是#，所以不输出。从最后一个函数栈上退出，返回倒数第二次输入的函数栈，执行余下的语句：   if(i!='#')       printf("%c\n",i);   system("pause"); 倒数第二次输入的不是#，所以把倒数第二次输入的字符输出，然后进入倒数第三次的函数栈，执行：   if(i!='#')       printf("%c\n",i);       system("pause"); 这样输出倒数第三次输入的字符。依次类推，这就是递归嘛[/quote] 嗯，那为什么#还是会输出呢？[/quote] 你确定输出了#? 我试了一下你的程序怎么没有输出#.[/quote] 你看下这段代码怎么会输出， #include<iostream> #include<cstdlib> using namespace std; void Z(int n) {            cin>>n;      if(n!=5)      Z(0);      if(n!=5);     cout<<n<<endl;   system("pause");         } int main() {     Z(0);      return 0;     }  [/quote] 这是第二个问题了，我们一直在讨论你的第一个问题，第二个程序很明显和第一个程序差距很大呢，判断条件都已经变了，怎么可能输入和输出都一样呢？[/quote]  引用 17 楼 cfjtaishan 的回复:引用 13 楼 qq_36639412 的回复:[quote=引用 12 楼 cfjtaishan 的回复:] [quote=引用 10 楼 qq_36639412 的回复:] [quote=引用 8 楼 cfjtaishan 的回复:] [quote=引用 6 楼 qq_36639412 的回复:] [quote=引用 3 楼 cfjtaishan 的回复:] 注意递归是不停的申请函数栈空间，根据先进后出的栈原理，它的输出自然是逆序的。关键是两个if是怎么判断的？条件都是一样的，第一个是不成立就不调用自己，那么第二if也是一样的判断条件呢，是不是可以这样理解，如果输入#了就不调用，返回上一次调用的输入判断满不满足条件？ 如果输入的不是#,函数会继续进入新的函数栈，然后重新开始执行，等待输入，然后判断输入的字符是否为#,如果遇到了#，那么该函数栈继续向后执行，输出最后一个输入的字符，最后一个是#，所以不输出。从最后一个函数栈上退出，返回倒数第二次输入的函数栈，执行余下的语句：   if(i!='#')       printf("%c\n",i);   system("pause"); 倒数第二次输入的不是#，所以把倒数第二次输入的字符输出，然后进入倒数第三次的函数栈，执行：   if(i!='#')       printf("%c\n",i);       system("pause"); 这样输出倒数第三次输入的字符。依次类推，这就是递归嘛[/quote] 嗯，那为什么#还是会输出呢？[/quote] 你确定输出了#? 我试了一下你的程序怎么没有输出#.[/quote] 你看下这段代码怎么会输出， #include<iostream> #include<cstdlib> using namespace std; void Z(int n) {            cin>>n;      if(n!=5)      Z(0);      if(n!=5);     cout<<n<<endl;   system("pause");         } int main() {     Z(0);      return 0;     }  [/quote] 这是第二个问题了，我们一直在讨论你的第一个问题，第二个程序很明显和第一个程序差距很大呢，判断条件都已经变了，怎么可能输入和输出都一样呢？[/quote] 是一样的啊，只是判断的是个整数，第一个程序是字符，那第二个怎么会输出不满足的条件值呢[/quote] 嗯，条件不一样，你输入#是可以输出#的，因为#不是5；你的判断条件是只要输入的不是5，都会将输入的内容倒序输出。[/quote] 嗯，但是输入12345，输出54321，这正确么？5不是条件嘛[/quote] 哦，知道问题了，if那里执行了空语句

引用 19 楼 cfjtaishan 的回复:引用 18 楼 qq_36639412 的回复:[quote=引用 17 楼 cfjtaishan 的回复:] [quote=引用 13 楼 qq_36639412 的回复:] [quote=引用 12 楼 cfjtaishan 的回复:] [quote=引用 10 楼 qq_36639412 的回复:] [quote=引用 8 楼 cfjtaishan 的回复:] [quote=引用 6 楼 qq_36639412 的回复:] [quote=引用 3 楼 cfjtaishan 的回复:] 注意递归是不停的申请函数栈空间，根据先进后出的栈原理，它的输出自然是逆序的。关键是两个if是怎么判断的？条件都是一样的，第一个是不成立就不调用自己，那么第二if也是一样的判断条件呢，是不是可以这样理解，如果输入#了就不调用，返回上一次调用的输入判断满不满足条件？ 如果输入的不是#,函数会继续进入新的函数栈，然后重新开始执行，等待输入，然后判断输入的字符是否为#,如果遇到了#，那么该函数栈继续向后执行，输出最后一个输入的字符，最后一个是#，所以不输出。从最后一个函数栈上退出，返回倒数第二次输入的函数栈，执行余下的语句：   if(i!='#')       printf("%c\n",i);   system("pause"); 倒数第二次输入的不是#，所以把倒数第二次输入的字符输出，然后进入倒数第三次的函数栈，执行：   if(i!='#')       printf("%c\n",i);       system("pause"); 这样输出倒数第三次输入的字符。依次类推，这就是递归嘛[/quote] 嗯，那为什么#还是会输出呢？[/quote] 你确定输出了#? 我试了一下你的程序怎么没有输出#.[/quote] 你看下这段代码怎么会输出， #include<iostream> #include<cstdlib> using namespace std; void Z(int n) {            cin>>n;      if(n!=5)      Z(0);      if(n!=5);     cout<<n<<endl;   system("pause");         } int main() {     Z(0);      return 0;     }  [/quote] 这是第二个问题了，我们一直在讨论你的第一个问题，第二个程序很明显和第一个程序差距很大呢，判断条件都已经变了，怎么可能输入和输出都一样呢？[/quote]  引用 17 楼 cfjtaishan 的回复:引用 13 楼 qq_36639412 的回复:[quote=引用 12 楼 cfjtaishan 的回复:] [quote=引用 10 楼 qq_36639412 的回复:] [quote=引用 8 楼 cfjtaishan 的回复:] [quote=引用 6 楼 qq_36639412 的回复:] [quote=引用 3 楼 cfjtaishan 的回复:] 注意递归是不停的申请函数栈空间，根据先进后出的栈原理，它的输出自然是逆序的。关键是两个if是怎么判断的？条件都是一样的，第一个是不成立就不调用自己，那么第二if也是一样的判断条件呢，是不是可以这样理解，如果输入#了就不调用，返回上一次调用的输入判断满不满足条件？ 如果输入的不是#,函数会继续进入新的函数栈，然后重新开始执行，等待输入，然后判断输入的字符是否为#,如果遇到了#，那么该函数栈继续向后执行，输出最后一个输入的字符，最后一个是#，所以不输出。从最后一个函数栈上退出，返回倒数第二次输入的函数栈，执行余下的语句：   if(i!='#')       printf("%c\n",i);   system("pause"); 倒数第二次输入的不是#，所以把倒数第二次输入的字符输出，然后进入倒数第三次的函数栈，执行：   if(i!='#')       printf("%c\n",i);       system("pause"); 这样输出倒数第三次输入的字符。依次类推，这就是递归嘛[/quote] 嗯，那为什么#还是会输出呢？[/quote] 你确定输出了#? 我试了一下你的程序怎么没有输出#.[/quote] 你看下这段代码怎么会输出， #include<iostream> #include<cstdlib> using namespace std; void Z(int n) {            cin>>n;      if(n!=5)      Z(0);      if(n!=5);     cout<<n<<endl;   system("pause");         } int main() {     Z(0);      return 0;     }  [/quote] 这是第二个问题了，我们一直在讨论你的第一个问题，第二个程序很明显和第一个程序差距很大呢，判断条件都已经变了，怎么可能输入和输出都一样呢？[/quote] 是一样的啊，只是判断的是个整数，第一个程序是字符，那第二个怎么会输出不满足的条件值呢[/quote] 嗯，条件不一样，你输入#是可以输出#的，因为#不是5；你的判断条件是只要输入的不是5，都会将输入的内容倒序输出。[/quote] 嗯，但是输入12345，输出54321，这正确么？5不是条件嘛

引用 18 楼 qq_36639412 的回复:引用 17 楼 cfjtaishan 的回复:[quote=引用 13 楼 qq_36639412 的回复:] [quote=引用 12 楼 cfjtaishan 的回复:] [quote=引用 10 楼 qq_36639412 的回复:] [quote=引用 8 楼 cfjtaishan 的回复:] [quote=引用 6 楼 qq_36639412 的回复:] [quote=引用 3 楼 cfjtaishan 的回复:] 注意递归是不停的申请函数栈空间，根据先进后出的栈原理，它的输出自然是逆序的。关键是两个if是怎么判断的？条件都是一样的，第一个是不成立就不调用自己，那么第二if也是一样的判断条件呢，是不是可以这样理解，如果输入#了就不调用，返回上一次调用的输入判断满不满足条件？ 如果输入的不是#,函数会继续进入新的函数栈，然后重新开始执行，等待输入，然后判断输入的字符是否为#,如果遇到了#，那么该函数栈继续向后执行，输出最后一个输入的字符，最后一个是#，所以不输出。从最后一个函数栈上退出，返回倒数第二次输入的函数栈，执行余下的语句：   if(i!='#')       printf("%c\n",i);   system("pause"); 倒数第二次输入的不是#，所以把倒数第二次输入的字符输出，然后进入倒数第三次的函数栈，执行：   if(i!='#')       printf("%c\n",i);       system("pause"); 这样输出倒数第三次输入的字符。依次类推，这就是递归嘛[/quote] 嗯，那为什么#还是会输出呢？[/quote] 你确定输出了#? 我试了一下你的程序怎么没有输出#.[/quote] 你看下这段代码怎么会输出， #include<iostream> #include<cstdlib> using namespace std; void Z(int n) {            cin>>n;      if(n!=5)      Z(0);      if(n!=5);     cout<<n<<endl;   system("pause");         } int main() {     Z(0);      return 0;     }  [/quote] 这是第二个问题了，我们一直在讨论你的第一个问题，第二个程序很明显和第一个程序差距很大呢，判断条件都已经变了，怎么可能输入和输出都一样呢？[/quote]  引用 17 楼 cfjtaishan 的回复:引用 13 楼 qq_36639412 的回复:[quote=引用 12 楼 cfjtaishan 的回复:] [quote=引用 10 楼 qq_36639412 的回复:] [quote=引用 8 楼 cfjtaishan 的回复:] [quote=引用 6 楼 qq_36639412 的回复:] [quote=引用 3 楼 cfjtaishan 的回复:] 注意递归是不停的申请函数栈空间，根据先进后出的栈原理，它的输出自然是逆序的。关键是两个if是怎么判断的？条件都是一样的，第一个是不成立就不调用自己，那么第二if也是一样的判断条件呢，是不是可以这样理解，如果输入#了就不调用，返回上一次调用的输入判断满不满足条件？ 如果输入的不是#,函数会继续进入新的函数栈，然后重新开始执行，等待输入，然后判断输入的字符是否为#,如果遇到了#，那么该函数栈继续向后执行，输出最后一个输入的字符，最后一个是#，所以不输出。从最后一个函数栈上退出，返回倒数第二次输入的函数栈，执行余下的语句：   if(i!='#')       printf("%c\n",i);   system("pause"); 倒数第二次输入的不是#，所以把倒数第二次输入的字符输出，然后进入倒数第三次的函数栈，执行：   if(i!='#')       printf("%c\n",i);       system("pause"); 这样输出倒数第三次输入的字符。依次类推，这就是递归嘛[/quote] 嗯，那为什么#还是会输出呢？[/quote] 你确定输出了#? 我试了一下你的程序怎么没有输出#.[/quote] 你看下这段代码怎么会输出， #include<iostream> #include<cstdlib> using namespace std; void Z(int n) {            cin>>n;      if(n!=5)      Z(0);      if(n!=5);     cout<<n<<endl;   system("pause");         } int main() {     Z(0);      return 0;     }  [/quote] 这是第二个问题了，我们一直在讨论你的第一个问题，第二个程序很明显和第一个程序差距很大呢，判断条件都已经变了，怎么可能输入和输出都一样呢？[/quote] 是一样的啊，只是判断的是个整数，第一个程序是字符，那第二个怎么会输出不满足的条件值呢[/quote] 嗯，条件不一样，你输入#是可以输出#的，因为#不是5；你的判断条件是只要输入的不是5，都会将输入的内容倒序输出。

引用 17 楼 cfjtaishan 的回复:引用 13 楼 qq_36639412 的回复:[quote=引用 12 楼 cfjtaishan 的回复:] [quote=引用 10 楼 qq_36639412 的回复:] [quote=引用 8 楼 cfjtaishan 的回复:] [quote=引用 6 楼 qq_36639412 的回复:] [quote=引用 3 楼 cfjtaishan 的回复:] 注意递归是不停的申请函数栈空间，根据先进后出的栈原理，它的输出自然是逆序的。关键是两个if是怎么判断的？条件都是一样的，第一个是不成立就不调用自己，那么第二if也是一样的判断条件呢，是不是可以这样理解，如果输入#了就不调用，返回上一次调用的输入判断满不满足条件？ 如果输入的不是#,函数会继续进入新的函数栈，然后重新开始执行，等待输入，然后判断输入的字符是否为#,如果遇到了#，那么该函数栈继续向后执行，输出最后一个输入的字符，最后一个是#，所以不输出。从最后一个函数栈上退出，返回倒数第二次输入的函数栈，执行余下的语句：   if(i!='#')       printf("%c\n",i);   system("pause"); 倒数第二次输入的不是#，所以把倒数第二次输入的字符输出，然后进入倒数第三次的函数栈，执行：   if(i!='#')       printf("%c\n",i);       system("pause"); 这样输出倒数第三次输入的字符。依次类推，这就是递归嘛[/quote] 嗯，那为什么#还是会输出呢？[/quote] 你确定输出了#? 我试了一下你的程序怎么没有输出#.[/quote] 你看下这段代码怎么会输出， #include<iostream> #include<cstdlib> using namespace std; void Z(int n) {            cin>>n;      if(n!=5)      Z(0);      if(n!=5);     cout<<n<<endl;   system("pause");         } int main() {     Z(0);      return 0;     }  [/quote] 这是第二个问题了，我们一直在讨论你的第一个问题，第二个程序很明显和第一个程序差距很大呢，判断条件都已经变了，怎么可能输入和输出都一样呢？[/quote]  引用 17 楼 cfjtaishan 的回复:引用 13 楼 qq_36639412 的回复:[quote=引用 12 楼 cfjtaishan 的回复:] [quote=引用 10 楼 qq_36639412 的回复:] [quote=引用 8 楼 cfjtaishan 的回复:] [quote=引用 6 楼 qq_36639412 的回复:] [quote=引用 3 楼 cfjtaishan 的回复:] 注意递归是不停的申请函数栈空间，根据先进后出的栈原理，它的输出自然是逆序的。关键是两个if是怎么判断的？条件都是一样的，第一个是不成立就不调用自己，那么第二if也是一样的判断条件呢，是不是可以这样理解，如果输入#了就不调用，返回上一次调用的输入判断满不满足条件？ 如果输入的不是#,函数会继续进入新的函数栈，然后重新开始执行，等待输入，然后判断输入的字符是否为#,如果遇到了#，那么该函数栈继续向后执行，输出最后一个输入的字符，最后一个是#，所以不输出。从最后一个函数栈上退出，返回倒数第二次输入的函数栈，执行余下的语句：   if(i!='#')       printf("%c\n",i);   system("pause"); 倒数第二次输入的不是#，所以把倒数第二次输入的字符输出，然后进入倒数第三次的函数栈，执行：   if(i!='#')       printf("%c\n",i);       system("pause"); 这样输出倒数第三次输入的字符。依次类推，这就是递归嘛[/quote] 嗯，那为什么#还是会输出呢？[/quote] 你确定输出了#? 我试了一下你的程序怎么没有输出#.[/quote] 你看下这段代码怎么会输出， #include<iostream> #include<cstdlib> using namespace std; void Z(int n) {            cin>>n;      if(n!=5)      Z(0);      if(n!=5);     cout<<n<<endl;   system("pause");         } int main() {     Z(0);      return 0;     }  [/quote] 这是第二个问题了，我们一直在讨论你的第一个问题，第二个程序很明显和第一个程序差距很大呢，判断条件都已经变了，怎么可能输入和输出都一样呢？[/quote] 是一样的啊，只是判断的是个整数，第一个程序是字符，那第二个怎么会输出不满足的条件值呢

因为item函数中，递归调用是在printf前面，所以会一直递归到最里层，才开始输出，所以是逆序的

引用 3 楼 cfjtaishan 的回复:注意递归是不停的申请函数栈空间，根据先进后出的栈原理，它的输出自然是逆序的。关键是两个if是怎么判断的？条件都是一样的，第一个是不成立就不调用自己，那么第二if也是一样的判断条件呢，是不是可以这样理解，如果输入#了就不调用，返回上一次调用的输入判断满不满足条件？

引用 2 楼 u012807807 的回复:你的输出是在递归调用之后才有的，所以如果不输入#就一直递归下去，每一层都在递归的那个函数停下来进入更深层，直到出现了#不再调用，程序能够退出，这时候才从里到外层层执行你的那个输出函数，自然就是逆序输出了。 引用 2 楼 u012807807 的回复:你的输出是在递归调用之后才有的，所以如果不输入#就一直递归下去，每一层都在递归的那个函数停下来进入更深层，直到出现了#不再调用，程序能够退出，这时候才从里到外层层执行你的那个输出函数，自然就是逆序输出了。 第二个if(!='#')怎么理解，是不等于#了就返回上一层的函数输入？

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

注意递归是不停的申请函数栈空间，根据先进后出的栈原理，它的输出自然是逆序的。

引用 15 楼 qq_36639412 的回复:[quote=引用 3 楼 cfjtaishan 的回复:] 注意递归是不停的申请函数栈空间，根据先进后出的栈原理，它的输出自然是逆序的。 会输出不满足条件的值 #include<iostream> #include<cstdlib> using namespace std; void Z(int n) {            cin>>n;      if(n!=5)      Z(0);      if(n!=5);     cout<<n<<endl;   system("pause");         } int main() {     Z(0);      return 0;     } [/quote] 你最初的程序不会输出#，这个程序应该会进入死循环，最后栈溢出然后挂掉吧，你只要输入的不是5，则会一直不停调用在Z（0）,再也退不出来了

引用 3 楼 cfjtaishan 的回复:注意递归是不停的申请函数栈空间，根据先进后出的栈原理，它的输出自然是逆序的。 会输出不满足条件的值 #include<iostream> #include<cstdlib> using namespace std; void Z(int n) {            cin>>n;      if(n!=5)      Z(0);      if(n!=5);     cout<<n<<endl;   system("pause");         } int main() {     Z(0);      return 0;     }

引用 2 楼 u012807807 的回复:你的输出是在递归调用之后才有的，所以如果不输入#就一直递归下去，每一层都在递归的那个函数停下来进入更深层，直到出现了#不再调用，程序能够退出，这时候才从里到外层层执行你的那个输出函数，自然就是逆序输出了。 怎么不满足条件的也会输出 #include<iostream> #include<cstdlib> using namespace std; void Z(int n) {            cin>>n;      if(n!=5)      Z(0);      if(n!=5);     cout<<n<<endl;   system("pause");         } int main() {     Z(0);      return 0;     }

引用 12 楼 cfjtaishan 的回复:引用 10 楼 qq_36639412 的回复:[quote=引用 8 楼 cfjtaishan 的回复:] [quote=引用 6 楼 qq_36639412 的回复:] [quote=引用 3 楼 cfjtaishan 的回复:] 注意递归是不停的申请函数栈空间，根据先进后出的栈原理，它的输出自然是逆序的。关键是两个if是怎么判断的？条件都是一样的，第一个是不成立就不调用自己，那么第二if也是一样的判断条件呢，是不是可以这样理解，如果输入#了就不调用，返回上一次调用的输入判断满不满足条件？ 如果输入的不是#,函数会继续进入新的函数栈，然后重新开始执行，等待输入，然后判断输入的字符是否为#,如果遇到了#，那么该函数栈继续向后执行，输出最后一个输入的字符，最后一个是#，所以不输出。从最后一个函数栈上退出，返回倒数第二次输入的函数栈，执行余下的语句：   if(i!='#')       printf("%c\n",i);   system("pause"); 倒数第二次输入的不是#，所以把倒数第二次输入的字符输出，然后进入倒数第三次的函数栈，执行：   if(i!='#')       printf("%c\n",i);       system("pause"); 这样输出倒数第三次输入的字符。依次类推，这就是递归嘛[/quote] 嗯，那为什么#还是会输出呢？[/quote] 你确定输出了#? 我试了一下你的程序怎么没有输出#.[/quote] 你看下这段代码怎么会输出， #include<iostream> #include<cstdlib> using namespace std; void Z(int n) {            cin>>n;      if(n!=5)      Z(0);      if(n!=5);     cout<<n<<endl;   system("pause");         } int main() {     Z(0);      return 0;     }

引用 10 楼 qq_36639412 的回复:引用 8 楼 cfjtaishan 的回复:[quote=引用 6 楼 qq_36639412 的回复:] [quote=引用 3 楼 cfjtaishan 的回复:] 注意递归是不停的申请函数栈空间，根据先进后出的栈原理，它的输出自然是逆序的。关键是两个if是怎么判断的？条件都是一样的，第一个是不成立就不调用自己，那么第二if也是一样的判断条件呢，是不是可以这样理解，如果输入#了就不调用，返回上一次调用的输入判断满不满足条件？ 如果输入的不是#,函数会继续进入新的函数栈，然后重新开始执行，等待输入，然后判断输入的字符是否为#,如果遇到了#，那么该函数栈继续向后执行，输出最后一个输入的字符，最后一个是#，所以不输出。从最后一个函数栈上退出，返回倒数第二次输入的函数栈，执行余下的语句：   if(i!='#')       printf("%c\n",i);   system("pause"); 倒数第二次输入的不是#，所以把倒数第二次输入的字符输出，然后进入倒数第三次的函数栈，执行：   if(i!='#')       printf("%c\n",i);       system("pause"); 这样输出倒数第三次输入的字符。依次类推，这就是递归嘛[/quote] 嗯，那为什么#还是会输出呢？[/quote] 你确定输出了#? 我试了一下你的程序怎么没有输出#.

引用 9 楼 u012807807 的回复:[quote=引用 5 楼 qq_36639412 的回复:] [quote=引用 2 楼 u012807807 的回复:] 你的输出是在递归调用之后才有的，所以如果不输入#就一直递归下去，每一层都在递归的那个函数停下来进入更深层，直到出现了#不再调用，程序能够退出，这时候才从里到外层层执行你的那个输出函数，自然就是逆序输出了。 第二个if(!='#')怎么理解，是不等于#了就返回上一层的函数输入？ [/quote] 六楼已经说的很清楚了应该，你的第二个判断都是暂时不执行的，因为已经进入了更深层次的函数，只有等函数返回了 才接着进行第二个if判断，这时的i都还存在栈里面，倒着一个个吐出来[/quote] 那怎么#还是会输出

引用 8 楼 cfjtaishan 的回复:引用 6 楼 qq_36639412 的回复:[quote=引用 3 楼 cfjtaishan 的回复:] 注意递归是不停的申请函数栈空间，根据先进后出的栈原理，它的输出自然是逆序的。关键是两个if是怎么判断的？条件都是一样的，第一个是不成立就不调用自己，那么第二if也是一样的判断条件呢，是不是可以这样理解，如果输入#了就不调用，返回上一次调用的输入判断满不满足条件？ 如果输入的不是#,函数会继续进入新的函数栈，然后重新开始执行，等待输入，然后判断输入的字符是否为#,如果遇到了#，那么该函数栈继续向后执行，输出最后一个输入的字符，最后一个是#，所以不输出。从最后一个函数栈上退出，返回倒数第二次输入的函数栈，执行余下的语句：   if(i!='#')       printf("%c\n",i);   system("pause"); 倒数第二次输入的不是#，所以把倒数第二次输入的字符输出，然后进入倒数第三次的函数栈，执行：   if(i!='#')       printf("%c\n",i);       system("pause"); 这样输出倒数第三次输入的字符。依次类推，这就是递归嘛[/quote] 嗯，那为什么#还是会输出呢？

引用 5 楼 qq_36639412 的回复:[quote=引用 2 楼 u012807807 的回复:] 你的输出是在递归调用之后才有的，所以如果不输入#就一直递归下去，每一层都在递归的那个函数停下来进入更深层，直到出现了#不再调用，程序能够退出，这时候才从里到外层层执行你的那个输出函数，自然就是逆序输出了。 第二个if(!='#')怎么理解，是不等于#了就返回上一层的函数输入？ [/quote] 六楼已经说的很清楚了应该，你的第二个判断都是暂时不执行的，因为已经进入了更深层次的函数，只有等函数返回了 才接着进行第二个if判断，这时的i都还存在栈里面，倒着一个个吐出来


Question: 十六进制数转整数

然后你还需要注意大小端的问题

C是值传递  x是函数的局部变量 你给x 赋值 毫无意义

本来想用指针来写以为简单些，看来想法是错误的。

不能这么转换  要用位运算

#include <stdio.h> typedef unsigned char u8; //8个十六进制数存在一个数组里 unsigned char Arry[8]= {0x00,0x00,0x00,0x03,0x0F,0x93,0x2E,0xBE}; //转换成一个unsigned long long型的整数中，a= 0x000000030F932EBE unsigned long long a; void HEXtoLongLongBE(unsigned char *byteArry,unsigned long long *x) {     u8 i;     unsigned char* p = (unsigned char*)x;      for ( i =0; i < 8; i++ ) {         *p = *byteArry;         byteArry++;         p++;     } } void HEXtoLongLongLE(unsigned char *byteArry,unsigned long long *x) {     u8 i;     unsigned char* p = (unsigned char*)x;      byteArry+=7;     for ( i =0; i < 8; i++ ) {         *p = *byteArry;         byteArry--;         p++;     } } int main() {     HEXtoLongLongBE(Arry,&a);     printf("0x%016llx\n",a);     HEXtoLongLongLE(Arry,&a);     printf("0x%016llx\n",a);     return 0; } //0xbe2e930f03000000 //0x000000030f932ebe //

unsigned long long x = *(unsigned long long *)Arry; 不过这样映射和存储格式相关，从你说的转换结果看如果是大端格式的机器可以直接这样，如果是小端格式的机器，例如x86/x64，可以： unsigned long long x =    (unsigned long long)Arry[0] << 56 |  (unsigned long long)Arry[1] << 48 |   (unsigned long long)Arry[2] << 40 |  (unsigned long long)Arry[3] << 32 |   (unsigned long long)Arry[4] << 24 |  (unsigned long long)Arry[5] << 16 |   (unsigned long long)Arry[6] << 8 |  Arry[7];

可以用union  union CONVERT{ 	ULONGLONG a; 	BYTE Arry[8]; };  	CONVERT x; 	x.Arry[7] = 0x00; 	x.Arry[6] = 0x00; 	x.Arry[5] = 0x00; 	x.Arry[4] = 0x03; 	x.Arry[3] = 0x0f; 	x.Arry[2] = 0x93; 	x.Arry[1] = 0x2e; 	x.Arry[0] = 0xbe; 	ULONGLONG a = x.a;


Question: poj 1002 wrong answer  大家看看有什么问题，没找到

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

int num[100000]; 看到这个定义，我就害怕； 你要做什么？必须定义这么大的数组呢？ 没怎么看明白楼主程序的需求或者要求什么，建议详细一些～

开始时把变量定义好，在后边的程序中不能定义变量。 void quicksort(int [],int ,int ); int n;  scanf("%d",&n);  int i,j; for(i=0;i<n;i++)    { scanf("%s",s); int c=0; 这里面：int i,j;和int c=0;以及其他的变量定义放到scanf("%d",&n);之前。


Question: C语言读取txt任意一个数

可以先把每行读入一个字符串，然后用sscanf 读取每行里的各个实数

思想是这样的，以‘\n'换行作为判断一行的条件 ，逐个查找匹配，读第三行第二个数。 就是读取第二个换行'\n' ， 然后找第一个空格和第二个空格之间的字符 ，空格是’ ‘  例如 if（ch == ’\n' ）

每一行数据个数都是确定的吗？

使用fscanf读取，一次读一行。无法指定读取某个数据，只能将前几个先读出来，然后在读取你想要的数据。 建议使用fscanf读取，一次读取一行，然后匹配到自己想要的数据。

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


Question: 求助!链表的选择排序中当最小值对应的结点是最后一个时候该怎么处理？？

谢谢啦，我已经解决啦，虽然你说的这种方法可行，但我们老师是想要不改变数据的方式做的。我之前的代码写的有点BUG，链了后面的没链前面所以找不到一些节点

除了修改节点的地址之外，还可以只修改节点的数据，而不改变链表的指向顺序。即链表框架不变，节点间的位置不变，而是交换节点里的data。


Question: typedef数组

请那些喜欢将数组作为函数参数传来传去或作为函数返回值的码农思考一下为什么不把整个互联网内容当作函数参数传来传去或作为函数返回值呢？

引用 5 楼 fefe82 的回复:[quote=引用 楼主 yuxi1989 的回复:] 我需要用typedef一个数组，然后作为函数形参，那函数传进去的仍然是数组指针吧？不会做深拷贝吧？那如果想达到类似效果，是不是只能typedef struct了，struct里面一堆int。谢谢！  typedef int a[100]; int func(a)   数组不能成为函数的参数，任何方式都不行。  但是数组的指针可以。  数组的指针与指向数组首元素的指针是两回事。数组可能自动转换为指向其首元素的指针（临时变量）。如果要得到数组的指针需要用 & 。  你可以用 struct ，但是如果元素比较多的话不推荐。效率问题。[/quote] 主要是想类似c++里面class，class我只要定义好构造、析构、复制、operator=，深拷贝基本上就没有这种问题了。C还没有任何思路该怎么做。

引用 楼主 yuxi1989 的回复:我需要用typedef一个数组，然后作为函数形参，那函数传进去的仍然是数组指针吧？不会做深拷贝吧？那如果想达到类似效果，是不是只能typedef struct了，struct里面一堆int。谢谢！  typedef int a[100]; int func(a)   数组不能成为函数的参数，任何方式都不行。  但是数组的指针可以。  数组的指针与指向数组首元素的指针是两回事。数组可能自动转换为指向其首元素的指针（临时变量）。如果要得到数组的指针需要用 & 。  你可以用 struct ，但是如果元素比较多的话不推荐。效率问题。

首先你这个想法有点多此一举，因为你可以直接把数组当作参数传递进去，但是如果传递数组，要哦注意算好数组的长度连同数据一起传进去， 比如:  void  MyFunction(int  nA[16])//函数定义  int  nArry[16] = {0};   //数组定义  MyFunction(nArry[16])//调用   至于你这个问题也是一样的，你要是要用typedef，那么你的函数参数变量类型也要是你typedef出来的类型，实际上传的就是一种东西啊；但是你这样有一个问题，传进去以后数组长度可能不对

引用 2 楼 yuxi1989 的回复:[quote=引用 1 楼 jianwen0529 的回复:] 类似效果是什么效果？  typedef struct传的是值吧 就是函数func传进去的不是数组转成的指针，而是数组的内容。[/quote] 确实不能 数组你需要一个副本，就定义一个临时数组，然后循环拷贝每一个值即可 如果你数组元素不多，这个性能的开销是很微小的

引用 1 楼 jianwen0529 的回复:类似效果是什么效果？  typedef struct传的是值吧 就是函数func传进去的不是数组转成的指针，而是数组的内容。

类似效果是什么效果？  typedef struct传的是值吧

1、数组作为参数会退化为指针  2、可以传递指向数组的指针  3、下面语句中，c的类型实际为int*  typedef int a[100]; int func(a c) { }  4、下面传入的是指向数组的指针：  int func(int (*c)[100])

我感觉这个typedef定义数组太硬，即数组的长度已经固定了。参数传递数组，其实编译器就是认为是指针。 数组长度不确定，可以考虑在堆上动态申请； 数组参数是指针，那么就没必要typedef数组了。

引用 8 楼 fefe82 的回复:[quote=引用 7 楼 Janxionwang 的回复:] [quote=引用 5 楼 fefe82 的回复:] [quote=引用 楼主 yuxi1989 的回复:] 我需要用typedef一个数组，然后作为函数形参，那函数传进去的仍然是数组指针吧？不会做深拷贝吧？那如果想达到类似效果，是不是只能typedef struct了，struct里面一堆int。谢谢！  typedef int a[100]; int func(a)   数组不能成为函数的参数，任何方式都不行。  但是数组的指针可以。  数组的指针与指向数组首元素的指针是两回事。数组可能自动转换为指向其首元素的指针（临时变量）。如果要得到数组的指针需要用 & 。  你可以用 struct ，但是如果元素比较多的话不推荐。效率问题。[/quote]  谁说的数组不能做参数的？[/quote]  函数参数里，任何数组形式的东西，实际都是指针（指向元素类型的指针）。  #4 楼的例子里，函数的参数也是一个指针（int *）。[/quote]  虽然这两个等价： void function( int* );  void function( int[SIZE] );   但是那也是说编译器把数组参数识别为指针，这不能说成是函数参数不支持数组吧，你把一个数组当作参数来写来传递，这是可以的啊，所以你只能说他们等价，不能说不支持数组，你觉得呢？

引用 7 楼 Janxionwang 的回复:[quote=引用 5 楼 fefe82 的回复:] [quote=引用 楼主 yuxi1989 的回复:] 我需要用typedef一个数组，然后作为函数形参，那函数传进去的仍然是数组指针吧？不会做深拷贝吧？那如果想达到类似效果，是不是只能typedef struct了，struct里面一堆int。谢谢！  typedef int a[100]; int func(a)   数组不能成为函数的参数，任何方式都不行。  但是数组的指针可以。  数组的指针与指向数组首元素的指针是两回事。数组可能自动转换为指向其首元素的指针（临时变量）。如果要得到数组的指针需要用 & 。  你可以用 struct ，但是如果元素比较多的话不推荐。效率问题。[/quote]  谁说的数组不能做参数的？[/quote]  函数参数里，任何数组形式的东西，实际都是指针（指向元素类型的指针）。  #4 楼的例子里，函数的参数也是一个指针（int *）。

引用 5 楼 fefe82 的回复:[quote=引用 楼主 yuxi1989 的回复:] 我需要用typedef一个数组，然后作为函数形参，那函数传进去的仍然是数组指针吧？不会做深拷贝吧？那如果想达到类似效果，是不是只能typedef struct了，struct里面一堆int。谢谢！  typedef int a[100]; int func(a)   数组不能成为函数的参数，任何方式都不行。  但是数组的指针可以。  数组的指针与指向数组首元素的指针是两回事。数组可能自动转换为指向其首元素的指针（临时变量）。如果要得到数组的指针需要用 & 。  你可以用 struct ，但是如果元素比较多的话不推荐。效率问题。[/quote]  谁说的数组不能做参数的？


Question: 求教此问题如何解决？根据书上的步骤做的就是有很多错误

引用 2 楼 幻夢之葉的回复:1： 你用到的ElemType，那你就需要include 定义它的头文件  2： 不要include .c 和 cpp文件，虽然不一定有错，但是它们属于编译单元和实现的代码，你include算个什么含义 按书上步骤做的，初学什么都不懂

附上完整截图


Question: 关于c语言值传递的问题

一般传值就是靠函数返回return    或者 传指针 这样就不用return

或者指针和引用做参数，这样修改的就是实参，也不需要return

第二次c是局部变量c＝7，而不是全局的c＝6

理解和讨论之前请先学会如何观察！  计算机组成原理→DOS命令→汇编语言→C语言（不包括C++）、代码书写规范→数据结构、编译原理、操作系统→计算机网络、数据库原理、正则表达式→其它语言（包括C++）、架构……  对学习编程者的忠告： 多用小脑和手，少用大脑、眼睛和嘴，会更快地学会编程！ 眼过千遍不如手过一遍！ 书看千行不如手敲一行！ 手敲千行不如单步一行！ 单步源代码千行不如单步Debug版对应汇编一行！ 单步Debug版对应汇编千行不如单步Release版对应汇编一行！ 不会单步Release版对应汇编？在你想单步Release版C/C++代码片断的前面临时加一句DebugBreak();重建所有，然后在IDE中运行。（一般人我不告诉他！）  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对应的汇编并单步执行观察相应内存和寄存器变化。）  想要从本质上理解C指针，必须学习汇编以及C和汇编的对应关系。 从汇编的角度理解和学习C语言的指针，原本看似复杂的东西就会变得非常简单！ 指针即地址。“地址又是啥？”“只能从汇编语言和计算机组成原理的角度去解释了。” 但我又不得不承认：  有那么些人喜欢或者适合用“先具体再抽象”的方法学习和理解复杂事物；  而另一些人喜欢或者适合用“先抽象再具体”的方法学习和理解复杂事物。 而我本人属前者。  不要企图依赖输出指针相关表达式...的值【比如printf("%p\n",...);或者cout<<...】来理解指针的本质， 而要依赖调试时的反汇编窗口中的C/C++代码【比如void *p=(void *)(...);】及其对应汇编指令以及内存窗口中的内存地址和内存值来理解指针的本质。  这辈子不看内存地址和内存值；只画链表、指针示意图，画堆栈示意图，画各种示意图，甚至自己没画过而只看过书上的图……能从本质上理解指针、理解函数参数传递吗？本人深表怀疑！ 这辈子不种麦不收麦不将麦粒拿去磨面；只吃馒头、吃面条、吃面包、……甚至从没看过别人怎么蒸馒头，压面条，烤面包，……能从本质上理解面粉、理解面食吗？本人深表怀疑！！  提醒： “学习用汇编语言写程序” 和 “VC调试(TC或BC用TD调试)时按Alt+8、Alt+7、Alt+6和Alt+5,打开汇编窗口、堆栈窗口、内存窗口和寄存器窗口看每句C对应的汇编、单步执行并观察相应堆栈、内存和寄存器变化，这样过一遍不就啥都明白了吗。 （Linux或Unix下可以在用GDB调试时,看每句C对应的汇编并单步执行观察相应内存和寄存器变化。） 想要从本质上理解C指针，必须学习C和汇编的对应关系。” 不是一回事！  不要迷信书、考题、老师、回帖； 要迷信CPU、编译器、调试器、运行结果。 并请结合“盲人摸太阳”和“驾船出海时一定只带一个指南针。”加以理解。 任何理论、权威、传说、真理、标准、解释、想象、知识……都比不上摆在眼前的事实！  有人说一套做一套，你相信他说的还是相信他做的？ 其实严格来说这个世界上古往今来所有人都是说一套做一套，不是吗？  不要写连自己也预测不了结果的代码！  电脑内存或文件内容或传输内容只是一个一维二进制字节数组及其对应的二进制地址； 人脑才将电脑内存或文件内容或传输内容中的这个一维二进制字节数组及其对应的二进制地址的某些部分看成是整数、有符号数/无符号数、浮点数、复数、英文字母、阿拉伯数字、中文/韩文/法文……字符/字符串、汇编指令、函数、函数参数、堆、栈、数组、指针、数组指针、指针数组、数组的数组、指针的指针、二维数组、字符点阵、字符笔画的坐标、黑白二值图片、灰度图片、彩色图片、录音、视频、指纹信息、身份证信息……  十字链表交换任意两个节点C源代码（C指针应用终极挑战）http://download.csdn.net/detail/zhao4zhong1/5532495

传值相当于传递的是值得一个副本，一个拷贝

值传递是单向的，可以理解成不论是指针变量还是普通变量，都是将实参变量在内存里的值传给形参；这个需要明白一个问题，形参和实参是相互独立的，形参在被调用函数栈上申请；实参是在调用函数栈上申请；它们之间的传递是值传递； 参数根据参数的功能，可以分为传入参数可传出参数（都是值传递），传出参数除了传进来一个值，还能将被调用函数的一个结果传到调用函数里，因为通过传指针，可以直接修改调用嗯函数栈上的内存空间； #include <stdio.h>  int fun(int);  int main() {     int d = 4;     printf("fun(d) - (1): %d\n", fun(d));     printf("fun(d) - (1): %d\n", fun(d));     printf("fun(d) - (1): %d\n", fun(d));      return 0; }  int fun(int x) {     int d = 4;     int y = 1;     static int z = 3;      y++;     z++;     d++;      return x = x + y + z; } 问题： 1,函数声明，建议放在main函数之外；这种放在函数内的函数声明建议改掉该习惯； 2. printf参数个数不对； 传入传出参数例子： #include <stdio.h>  int fun(int *);  int main() {     int d = 4, result;      result = fun(&d);     printf("fun(&d) : %d, d = %d\n", result, d);      return 0; }  int fun(int *x) {     int d = 4;     int y = 1;     static int z = 3;      y++;     z++;     d++;      return *x = *x + y + z; }

第一个问题，首先给你一个建议，全局变量和函数内部变量，不要出现同类型且同名称的； 你的问题在于：一个函数的内部变量是不能直接被另一个函数使用的（除非被传递到另一个函数），函数只调用全局变量，传进来的参数变量和内部定义的变量；你这里自己定义一堆abc，导致一个变量名对应多个变量，两个函数里可能都有一个叫a的变量，可以他们实际毫无关系...  第二个问题可以用指针：   main() { 	int iCount = 0; 	int fun(int, &iCount); 	//......... }  int fun(int x, int *pCount) { 	int d=4; 	int y=1; 	static int z=3; 	 	y++; 	z++; 	d++; 	 	*pCount = x+y+z;  	return 0; }

你这个代码问题稍微有点多啊，不报重定义我也是服了你的编译器；

函数里面定义的变量跟外部或者主调函数都没有关联，所以它们只是在它们所在的函数有效  函数定义的变量会隐藏同名的全局变量，所以它们也没有任何关联 在函数中要使用全局变量需要  int a = 10; void fun(int a) { a += 10; //局部变量 ::a += 10; // ::限定符，使用全局变量 }   除了return之外，还可以使用引用或者指针参数作为返回 int fun(int a, int &b, int *c) //修改b会影响实参，修改 *c 也会影响实参所指向内存的值

和return没关系，不论参数还是返回值，值传递相当于是复制过去的  如果是参数，函数中修改这个参数不会影响函数外的实参，因为函数中的只是一个复制品

我自己才不会定义那么多abcd呢，题长这样，我也很无奈呀


Question: C语言栈运用

operator是c++的关键字，所以你不能定义这样名字的变量，你改下名称即可

下面这条语句后面少了分号  int operand2=0 //后操作数  其次operator变量名换个名字，和关键字有重复

扩展名 cpp 应该会按 c++ 编译。  扩展名 c 默认会按 C 编译。

#include<stdio.h>   #define MAXSIZE 10  typedef struct {     //char data[MAXSIZE];     int data[MAXSIZE];     int top; }SeqStack;  void Init_SeqStack(SeqStack *s) {     s->top=0; }  /*入栈操作*/ int Push_SeqStack(SeqStack *s, int x) {     if(s->top==MAXSIZE)         return 0;     s->data[s->top]=x;     s->top++;      return 1; }  int Pop_SeqStack(SeqStack *s, int *x) {     if(s->top == 0) {         return 0;//栈空不能出栈     } else {         s->top--;         *x = s->data[s->top];         return 1;     }  } int Empty_SeqStack(SeqStack *s) {     if(s->top == 0)         return 1;     else         return 0; }  int is_operator(int operator) {     switch (operator) {         case '+':         case '-':         case '*':         case '/':             return 1;//是运算符返回1             break;          default:             return 0;//不是运算符返回0     } }  int priority(int o) {     switch(o)     {         case '+':         case '-':             return 1;//加减运算符的优先级为1         case '*':         case '/':             return 2;//乘除运算符的优先级为2         default:             return 0;     } }  int two_result(int operator, int operator1, int operator2) {     switch(operator)     {         case '+':             return(operator2+operator1);         case '-':             return(operator2-operator1);         case '*':             return(operator2*operator1);         case '/':             return(operator2/operator1);     }      return 0; }  int main(void) {     SeqStack operand, operator, *s_operand, *s_operator;     char expression[50];//声明表达式字符数组     int position = 0;//表达式中元素位置     int op = 0;//运算符     int operand1=0;//前操作数     int operand2=0;//后操作数     int evaluate=0;//运算结果      s_operand = &operand;     s_operator = &operator;      Init_SeqStack(s_operand);     Init_SeqStack(s_operator);     gets(expression);      while(expression[position] != '\0' && expression[position] != '\n');     {         if(is_operator(expression[position]))         {             if(!Empty_SeqStack(s_operator))             {                 while(!Empty_SeqStack(s_operator) && priority(expression[position]) <= priority(s_operator->data[s_operator->top-1]))                 {                     Pop_SeqStack(s_operand, &operand1);                     Pop_SeqStack(s_operand,&operand2);                     Pop_SeqStack(s_operator,&op);                     Push_SeqStack(s_operand,two_result(op,operand1,operand2));                 }             }             Push_SeqStack(s_operator,expression[position]);         }         else             Push_SeqStack(s_operand,expression[position]-48);         position++;     }     while(!Empty_SeqStack(s_operator))     {         Pop_SeqStack(s_operator,&op);         Pop_SeqStack(s_operand,&operand1);         Pop_SeqStack(s_operand,&operand2);         Push_SeqStack(s_operand,two_result(op,operand1,operand2));     }     Pop_SeqStack(s_operand,&evaluate);     printf("%d",evaluate);     return 0; } 把源文件的后缀名改一下，改成.c试试； 另外，程序里有太多Pop-SeqStack或Push-SeqStack等等；这些函数的定义的名字都是以_下划线连接的，不是-连接的。 另外，类型不匹配，入栈，出栈的参数定义时使用char类型，调用时，传递的是int类型。这些都需要注意下。 程序没有运行，逻辑问题没有检查；


Question: 这个lingo模型运行出错，怎么修改，

建议换个板块，这个版本是C语言的～


Question: 请教一下关于binary bomb的问题

这是一个非常初级的代码，就是把输入的串参数和临时构造的一个串"Wow! Brazilbis big."（不包括引号）比较，不一致则执行explode_bomb代码，估计是显示你没成功破解之类的。

0x08048cfd <+21>:	call   0x8048870 <malloc@plt>  就是调用glibc里的malloc接口申请内存

IDAPro6.6_part1 IDAPro6.6_part2   可以直接看汇编的C语言代码

VC调试时按Alt+8、Alt+7、Alt+6和Alt+5,打开汇编窗口、堆栈窗口、内存窗口和寄存器窗口看每句C对应的汇编、单步执行并观察相应堆栈、内存和寄存器变化，这样过一遍不就啥都明白了吗。


Question: C语言用指针数组对字符串集合进行快速排序

引用 2 楼 bcai_yuan 的回复:编译器就是visual C++6.0，alloc是分配存储单元，返回一个指向n个连续字符存储单元的指针。 #include<stdio.h>  #define ALLOCSIZE 10000  static char allocbuf[ALLOCSIZE]; static char *allocp = allocbuf;  /*返回指向n个字符的指针*/ char *alloc(int n) { 	if((allocbuf + ALLOCSIZE) - allocp >= n){  //有足够的空闲空间 		allocp += n; 		return allocp - n;    //分配前的指针p 	}else                    //空闲空间不够 		return 0; }  qsort应该没问题吧，这个是快速排序 哦，我没有这个编译器，另外，你的qsort和Linux下的qsort参数还是有区别的

你的编译器是那个？alloc没用过，在Linux没有该函数，windows下也没怎么见过这个函数；qsort的参数也有问题，没见过这么调用的。


Question: 请问十进制数怎么转换成十六进制数？

引用 1 楼 cfjtaishan 的回复:#include <stdio.h> #include <string.h>  int main(void) {     double FloatNumber= 13800100500;     unsigned long long num = FloatNumber;     unsigned char disp[8];     int i;       printf("%lf\n", FloatNumber);     printf("%llu\n", num);      memcpy(disp, &num, 8);     for (i = 8; i >= 0; i--)         printf("%02X ", disp[i]);     putchar(10);      return 0; } 在内存中，不论是十进制还是16进制，甚至是8进制等等，都是二进制的形式存储的，即以010101这种方式存储的。之所以有10进制或者16进制，而是输出到终端的形式不同而已； 在内存中，浮点数和无符号整数存储的方式不同，因为浮点数有小数。所以，可以先把浮点数的整数部分给一个变量（这个变量需要能够存放这个浮点数的整数部分），然后在memcpy至一个8字节缓存里，最后以16进制形式输出。  解答得非常清楚，多谢！


Question: windows下如何用C语言写有界面的程序

装个黑苹果，美滋滋。。

字数被限制了，晕~~ 不需要头文件，也不需要其他什么库~~~ 字数被限制了，LZ留邮箱吧，或者发我邮件yhchen@gc.omron.com，我把附件发给你。 我也是新手刚学不久，不足之处请见谅

引用 1 楼 u010165006 的回复:虚拟机装Mac。。与时俱进+1

看看，c怎么写界面，

仅供参考：#pragma comment(lib,"user32") #pragma comment(lib,"gdi32") #include <windows.h> LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) {     PAINTSTRUCT ps;     HDC hdc;     HFONT hfont,ohfont;     RECT r;     COLORREF oc;      switch(message) {     case WM_CLOSE://按Alt+F4退出         PostQuitMessage(0);         break;     case WM_PAINT:         BeginPaint(hWnd, &ps);         hdc = ps.hdc; // the device context to draw in         GetClientRect(hWnd, &r); // Obtain the window's client rectangle         hfont = CreateFont(200, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "宋体");         ohfont=(HFONT)SelectObject(hdc,hfont);         oc=SetTextColor(hdc,0x00C080FF);         SetBkMode(hdc, TRANSPARENT);         TextOut(hdc,r.left+r.right/2-600, r.top+r.bottom/2-100,"最短画图程序",12);         SelectObject(hdc,ohfont);         SetTextColor(hdc,oc);         DeleteObject(hfont);         EndPaint(hWnd, &ps);         break;     default:         return DefWindowProc(hWnd, message, wParam, lParam);     }     return 0; } int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) {     MSG msg             = {0};     WNDCLASS wc         = {0};     HBRUSH hbrh;     hbrh=CreateSolidBrush(0x00000000);     wc.lpfnWndProc      = WndProc;     wc.hInstance        = hInstance;     wc.hbrBackground    = hbrh;     wc.lpszClassName    = "minwindowsapp";     wc.hCursor          = LoadCursor(NULL,IDC_ARROW);     if (0==RegisterClass(&wc)) return 1;      if (NULL==CreateWindow(wc.lpszClassName,                         "Minimal Windows Application",                         WS_POPUP|WS_VISIBLE,                         0,                         0,                         GetSystemMetrics(SM_CXSCREEN),                         GetSystemMetrics(SM_CYSCREEN),                         0,                         0,                         hInstance,                         NULL))         return 2;      while( GetMessage( &msg, NULL, 0, 0 ) > 0 ) {         DispatchMessage( &msg );     }     DeleteObject(hbrh);     return 0; }

虚拟机装Mac。。与时俱进


Question: 输出的i和j分别是多少？为什么会这样？

不过，没有输出，你的输入计划放在哪？是这吗？ #define _CRT_SECURE_NO_WARNINGS 1  #include <stdio.h>  static int j = 0; void fun1() {     static int i = 0;     i++;     printf("i = %d\n", i); }  void fun2() {     int j = 0;     j++;     printf("j = %d\n", j); } int main() {     int k = 0;     for(k = 0; k<10; k++)     {         fun1();         fun2();     }     return 0; } 这个题目主要是要学到两点：静态变量和局部变量的作用域和生命周期； 静态变量的作用域是：（又分为全局静态变量和局部静态变量），全局静态变量是从定义处开始，后面的函数都是可见和使用的。局部静态变量是在函数了定义的静态变量。它的作用域是该函数内；但是不论是全局或者局部的静态变量，生命周期都是整个程序； 局部变量的作用域只是函数体内，生命周期会随着函数的调用而创建，随着函数的结束而结束； 另，当局部变量和全局变量同名时，局部变量屏蔽全局变量。

不过，没有输出，你的输入计划放在哪？是这吗？   引用 1 楼 hxl199109 的回复:目测你这个 程序编译不过。有static i=0这种定义变量的方式吗?可能我书读的少 可以编译通过，编译器默认会把这两个静态变量定义成int


Question: 用链式队列 做二叉树的层次遍历为啥不成功啊  麻烦大神们~~

int Out_LQueue(LQueue *q,BiTNode *bt) {     QNode *p;     if(!(Empty_LQueue(q)))     {         printf("队列空");         return 0;     }     else     {         p = q->front->next;         q->front->next = p->next;         *bt = p->data2;         printf("%c ", p->data2.data);         //free(p);   /*这个地方不能释放，因为你还需要它*/         if(q->rear->next == NULL)             q->rear = q->front;     }      return 1; } 你的数据结构看着是，多个二叉树链到一个队列里。队列里每个节点都是一个二叉树的根。不知道这个是否从你的需求出发定义的数据结构。


不等；根据ASCII码， 可以看到它们的值：空格死40，'\0'是0；

空格字符 指键盘上长长的那个键产生的字符，16进制0x20, 十进制32。而空字符是在字符串结尾系统自动加上的‘\0’，以让系统识别出一个字符串的结尾。如字符串“china”实际上在系统内是以“china\0”储存的

不等于，但是这里涉及到scanf的用法，输入的字符串不能包含空格，否则，会输入结束，但是你用gets()时，带空格不会输入结束。C语言的书上面有说明。


Question: （有一部分错了）用单链表实现一个学生信息管理系统，     学生信息为如下表格，系统功能要求对学生信息进行录入，显示，插入一个新学生信息，删除一个学生，并实现

#include <stdio.h> #include <stdlib.h> #include <string.h>  typedef struct Student {     char no[10];     char name[20];     int age;     char leaveSch; }elemtype;   typedef struct node {     elemtype      data;     /*数据域*/     struct node *next;     /*指针域*/ }linklist;   linklist *InitList(linklist *L)     /*建立一个带头结点的单链表*/ {     L = (linklist*)malloc(sizeof(linklist));     L->next = NULL;     return(L); }  /*通过输入n个数据，创建一个单链表*/ linklist *CreateList(int n) {     int i;     char no[10];     char name[20];     int  age;     char leaveSch;      /*设数据元素的类型为int*/     linklist  *L = NULL, *r, *p;     L = InitList(L);     /*构建头结点空间*/     r = L;     for(i=1;i<=n;i++)/*循环构建n个结点*/     {         printf("\n 请输入学生信息,以回车键间隔:");         scanf("%s",no);         scanf("%s",name);         scanf("%d",&age);         //fflush(stdin);         getchar();         scanf("%c", &leaveSch);         p = (linklist *)malloc(sizeof(linklist));         strcpy(p->data.no, no);         strcpy(p->data.name, name);         p->data.age = age;         p->data.leaveSch = leaveSch;         p->next = NULL;         r->next = p;         r = r->next;         /*指针r始终指向链表中末数据元素所在位置*/     }      return(L); }   void output(linklist  *L)     /*输出链表的值*/ {     linklist *p;     p = L->next; /*p为第一个结点的指针*/      printf("\noutput element：\n");     for( ; p; p = p->next) {         printf("%s  ", p->data.no);         printf("%s  ", p->data.name);         printf("%d  ", p->data.age);         printf("%c\n", p->data.leaveSch);     } }   int InsItem (linklist *L, int i) {     int j;     char no[10];     char name[20];     int  age;     char leaveSch;     linklist *p,  *t;     p = L;     j=1;     printf("请输入你想要插入的学生信息:\n");     scanf("%s",no);     scanf("%s",name);     scanf("%d",&age);     //fflush(stdin);     getchar();     scanf("%c",&leaveSch);     t=(linklist*)malloc(sizeof(linklist)); /*生成新结点t*/     strcpy(t->data.no,no);     strcpy(t->data.name,name);     t->data.age=age;     t->data.leaveSch=leaveSch;     if(L->next == NULL)     {         if(i==0)         {             L->next = t;             t->next = NULL;             return(1);         }         else             return 0;     }     while((p->next!=NULL) && (j<i)) /*查找第i个结点*/     {         p = p->next;         j++;     }     if ((p->next==NULL)  && (j<i))         /*在表中不存在插入位置i ，找不到，则插入操作失败*/     {         printf("The node %d is not exist\n", i);         return(0);     }     else         /*若找到第i个结点，则在第i个结点前插入新结点*/     {         t->next = p->next;         p->next = t;         return 1;     } }    int DelItem ( linklist *L, int i) {/*删除给定序号的结点*/     int j;     linklist *p, *q;     p=L;     j=1;     if( L->next==0)         /*L为空表，无结点可删除*/     {         printf("The linklist is empty.\n");         return(0);     }     while((p->next!=0) && (j<i)) /*查找第i个结点*/     {         p=p->next;         j++;     }     if(p->next == NULL)         /*若没有第i个结点，则删除操作失败*/     {         printf("he node %d is not exist\n", i);         return(0);     }     else         /*若找到第i个结点，则删除并释放第i个结点*/     {         q = p->next;         p->next = p->next->next;         free(q);         return(1);     } }   int loclItem(linklist *L, char *item) {     linklist *p;     int i;     p = L->next;     i = 1;      while (p) {         if (strcmp(p->data.no, item)==0) {             return i;         }         p = p->next;         i++;     }     return 0; }   int main() {     linklist  *L;     int i;     char item[10];     L=CreateList(3);     output(L);     printf("\n请输入你想要插入学生的位置\n");     scanf("%d", &i);     InsItem(L,i);     output(L);     printf("\n请输入你想删除的学生的位置\n");     scanf("%d", &i);     DelItem(L,i);     output(L);     printf("\n请输入你要查找的学生的No\n");     scanf("%s", item);     i = loclItem(L, item);     printf("你要查找的学生在第%d位", i);     return 0; } 调用localItem前，输入scanf("%s", item);去掉前面的&,并且将上面描述“要查找的学生的位置”改成“学生的No"，如果是位置，那么是一个整型，输入的时候就是scanf("%d", &no);

strcpy要求的是字符串，未必以\0结尾，但你下面的p->data.no不是  p=( linklist *)malloc(sizeof(linklist)); strcpy(p->data.no,no);   scanf("%s", &item);  最好改成：  scanf("%s", item);

#include<stdio.h>   typedef struct Student {   char no[10];   char name[20];    int age;   char leaveSch; }elemtype;   typedef struct node {     elemtype      data;     /*数据域*/     struct node *next;     /*指针域*/ }linklist;   linklist *InitList(linklist *L)       /*建立一个带头结点的单链表*/ {     L=(linklist*)malloc(sizeof(linklist));     L->next=NULL;     return(L); }   linklist *CreateList(int n) /*通过输入n个数据，创建一个单链表*/  {     int x,i;     char no[10];     char name[20];     int  age;     char leaveSch; /*设数据元素的类型为int*/     linklist  *L, *r, *p;     L=InitList(L); /*构建头结点空间*/     r=L;     for(i=1;i<=n;i++) /*循环构建n个结点*/     {         printf("\n 请输入学生信息,以回车键间隔:");         scanf("%s",no);         scanf("%s",name);         scanf("%d",&age);         fflush(stdin);         scanf("%c",&leaveSch);         p=( linklist *)malloc(sizeof(linklist));         strcpy(p->data.no,no);         strcpy(p->data.name,name);         p->data.age=age;         p->data.leaveSch=leaveSch;         p->next=NULL;         r->next=p;         r=r->next; /*指针r始终指向链表中末数据元素所在位置*/     }     return(L); }   void output(linklist  *L) /*输出链表的值*/ {     int i;     linklist *p;     p=L->next; /*p为第一个结点的指针*/     printf("\noutput element：\n");     for( ;p!=NULL;p=p->next)     {         printf("%s  ",p->data.no);         printf("%s  ",p->data.name);         printf("%d  ",p->data.age);         printf("%c  \n",p->data.leaveSch);     } }   int InsItem (linklist *L, int i) {     int j;     char no[10];     char name[20];     int  age;     char leaveSch;     linklist *p,  *t;     p=L;     j=1;     printf("请输入你想要插入的学生信息:\n");     scanf("%s",no);     scanf("%s",name);     scanf("%d",&age);     fflush(stdin);     scanf("%c",&leaveSch);     t=(linklist*)malloc(sizeof(linklist)); /*生成新结点t*/     strcpy(t->data.no,no);     strcpy(t->data.name,name);     t->data.age=age;     t->data.leaveSch=leaveSch;     if(L->next == NULL)     {         if(i==0)         {             L->next = t;             t->next = NULL;             return(1);         }         else return 0;     }     while((p->next!=NULL) && (j<i)) /*查找第i个结点*/     {         p=p->next;         j++;     }     if ((p->next==NULL)  && (j<i))   /*在表中不存在插入位置i ，找不到，则插入操作失败*/     {         printf("The node %d is not exist\n", i);         return(0);     }     else  /*若找到第i个结点，则在第i个结点前插入新结点*/     {         t->next=p->next;         p->next= t;         return(1);     } }     int DelItem ( linklist *L, int i) {/*删除给定序号的结点*/     int j;     linklist *p, *q;     p=L;     j=1;     if( L->next==0)  /*L为空表，无结点可删除*/     {         printf("The linklist is empty.\n");         return(0);     }     while((p->next!=0) && (j<i)) /*查找第i个结点*/     {         p=p->next;         j++;     }     if(p->next==NULL) /*若没有第i个结点，则删除操作失败*/     {         printf("he node %d is not exist\n", i);         return(0);     }     else  /*若找到第i个结点，则删除并释放第i个结点*/     {         q=p->next;         p->next = p->next->next;         free(q);         return(1);     }  }   int loclItem(linklist *L, char *item) {     linklist *p;     int i;     p=L->next;     i=1;     while(p!=NULL)     {         if (strcmp(p->data.no,item)==0)         {            return i;         }         p=p->next;         i++;     }     return 0; }   int main() {     linklist  *L;     int i;     char item[10];     L=CreateList(3);     output(L);     printf("\n请输入你想要插入学生的位置\n");     scanf("%d", &i);     InsItem(L,i);     output(L);     printf("\n请输入你想删除的学生的位置\n");     scanf("%d", &i);     DelItem(L,i);     output(L);     printf("\n请输入你要查找的学生的位置\n");     scanf("%s", &item);     i=loclItem(L, item);     printf("你要查找的学生在第%d位", i);     return 0; }


Question: 求，，，这个主函数怎么写，其实主要是初始化后我不会往里面给结点变量data赋值，

最后，注意一下代码风格，函数名，变量名的命名规则要统一，不要一会这个命名规格，一会另一个命名规则，建议加强代码可读性的努力。

#include<stdio.h> //#include<malloc.h> #include <stdlib.h>  typedef struct Node{     int data;     struct Node *pre;     struct Node *next; }Node, *NodeList;   #define false (-1) #define true (0)  NodeList CreateList(NodeList L, int length) {     int i, data;     NodeList newnum, tail;     tail = L;      for(i = 0; i < length; i++) {         printf("请输入的结点的数值：");         scanf("%d", &data);          newnum = (NodeList)malloc(sizeof(Node));         if (!newnum) {             fprintf(stderr, "malloc error!\n");             exit(-1);         }         newnum->data = data;          newnum->next = tail->next;         tail->next = newnum;         tail = newnum;     }      return L; }  void InitList(NodeList *L) {     *L = (NodeList)malloc(sizeof(Node));     if(!(*L)) {         fprintf(stderr, "malloc error!\n");         exit(-1);     }      (*L)->next = (*L)->pre = *(L); }  void DestoryList(NodeList *L) {     NodeList q, p;      q = (*L)->next;     while(q != *L) {         p = q->next;         free(q);         q = p;     }     free(*L);     *L = NULL;  } int ClearList(NodeList L) {     NodeList q, p=L->next;     while(q!=NULL)     {         p=q->next;         free(q);         q=p;     }     L->next=L->pre=L; } int JudgeNULL(NodeList L) {     if(L->pre==L&&L->next==L)         return true;     else         return false; } int GetElem(NodeList L,int i,int *e) {     int j=1;     NodeList p=L->next;     while(p!=L&&j<i)     {         p=p->next;         j++;     }     *e=p->data;     if(p==L&&j>i)     {         return false;     }     // return *e;(指针类型不用返回) } int GetLength(NodeList L) {     int length=0;     NodeList p=L->next;     while(p!=L)     {         length++;         p=p->next;     }     return length; } int LocateElem(NodeList L,int e,int (*compare)(int ,int)) {     int j=1;     NodeList p=L->next;     while(p!=L)     {         if(compare(p->data,e))         {             return j;         }         p=p->next;         j++;     } } /*int PreElem(NodeList L,int i)   {   NodeList p;   int j=0;   p=L->next->next;   while(p!=L&&j<i-1)   {   p=p->next;   }   return p->pre->pre->data;   }*/ NodeList GetElemdirection(NodeList L,int i) {     NodeList p;     int j=1;     p=L;//因为最后要返回的是一个p的位置指针,所以也可以是L，故此时不必再对L进行判断     for(j=1;j<=i;j++)     {         p=p->next;     }     return p; } int InsertElem(NodeList L,int i, int data) {     if(i<1||i>GetLength(L))         return false;     NodeList p,newnum;     p=GetElemdirection(L,i-1);     newnum=(NodeList)malloc(sizeof(Node));     newnum->data=data;     newnum->pre=p;     newnum->next=p->next;     p->pre->next=newnum;     p->next=newnum; } int DeleteElem(NodeList L,int i) {     if(i<1||i>GetLength(L))         return false;     NodeList p,prenum;     p=GetElemdirection(L,i);     p=p->next=p->pre;     free(p); } int GetPre(NodeList L,int i) {     if(i<2||i>GetLength(L)+1)         return false;     NodeList p=GetElemdirection(L,i);     if(i==GetLength(L)+2)     {         NodeList s=GetElemdirection(L,i+1);         return s->data;     }     else         return p->pre->data; } int Getnext(NodeList L,int i) {     if(i<1||i>=GetLength(L)+1)         return false;     NodeList p=GetElemdirection(L,i);     return p->next->data; }  void PutHead(NodeList L,int data) {     NodeList p = L;     NodeList newnum;     newnum=(NodeList)malloc(sizeof(Node));     newnum->data=data;     L->next=newnum; }  void output (NodeList phead) {     NodeList p = phead->next;      printf("Show the data list: \n");     while (p != phead) {         printf("%d\t", p->data);         p = p->next;     }     putchar(10); }  int main(void) {     int len;     NodeList phead;      InitList(&phead);     printf("Please input the length of double link:");     scanf("%d", &len);     phead = CreateList(phead, len);     output(phead);      return 0; } 问题还是比较多的，改了初始化双向循环链表头，创建双向链表并赋值； 其他函数没有改，建议你尝试动手改一改；基本的语法错误，要先解决；有返回值，就要加返回值，如果没有必要返回值，那就把函数定义成void类型； 建议在这个基础上继续改，然后有问题继续问吧/


Question: c#连接Access数据库查询功能，具体如下

C#

我这里有个现成在用的，但是要30万字，无法给你 你有邮箱吗？ 请联系我yhchen@gc.omron.com

问题没描述清楚，button1和textbox1对应哪个控件？


Question: C语言逻辑运算符的短路,优先级和结合性谁更优先?

&&：左为错，不进行右边的语句； ||：左为对，不进行右边的语句。

没在编辑器上面运行过程序， 但是按你的说法，解释如下：||逻辑运算符当左为1时，不对右边的进行判断。 &&：当左边为1，才对右边进行判断。


Question: while(!feof(fp))死循环

不要使用 while (条件) 更不要使用 while (组合条件) 要使用 while (1) {  if (条件1) break;  //...  if (条件2) continue;  //...  if (条件3) return;  //... } 因为前两种写法在语言表达意思的层面上有二义性，只有第三种才忠实反映了程序流的实际情况。 典型如： 下面两段的语义都是当文件未结束时读字符 while (!feof(f)) {  a=fgetc(f);  //...  b=fgetc(f);//可能此时已经feof了！  //... } 而这样写就没有问题： while (1) {  a=fgetc(f);  if (feof(f)) break;  //...  b=fgetc(f);  if (feof(f)) break;  //... } 类似的例子还可以举很多。

学习了。。。。。。。。。。

引用 1 楼 user-4 的回复:每次循环都fseek到同一个位置了吧   谢谢，这里的确写错了，改成fseek(fp1, 8, SEEK_CUR)就可以跳出 不过fseek(fp1, 8, SEEK_CUR)；这一句放在for循环之后就又死循环了 兄弟知道是什么原因吗？  int main() { 	FILE *fp1 = NULL; 	FILE *fp2 = NULL;     char buf[40];     int i = 0;  fp1 = fopen(F_PATH1,"rb"); fp2 = fopen(F_PATH2,"wb");  if(NULL == fp1 || NULL == fp2) { 	return -1; } 	while(!feof(fp1)) 	{ 		//	fseek(fp1, 8, SEEK_CUR); 			for(i=0; i<1638; i++) 			{ 				fread(buf, sizeof(buf), 1, fp1); 				fwrite(buf, sizeof(buf), 1, fp2);	 			} 			fseek(fp1, 8, SEEK_CUR);  	} fclose(fp1); fclose(fp2);  return 0; }

去掉for循环，当feof返回非0时，退出，文件也也复制完了。

fread(buf, 40, 1, fp1) 改为fread(buf, sizeof(buf), 1, fp1）

i小于1638是干啥的

每次循环都fseek到同一个位置了吧


Question: 关于C Primer Plus 上泛型的疑问

引用 4 楼 kinolukaslana 的回复:[quote=引用 2 楼 user-2 的回复:] vc只有在文件名.c的时候才用c编译。cpp就用c++编译。你这_Generic是c11的东西，不是c++的东西。 而且vc是不是支持c11我还不确定。毕竟vc全称叫vc++。换个gcc啥的学c(11)吧 C++不是完美兼容C的吗？[/quote]  C++并不是所有C的内容都有的，甚至有些都完全不同  如C99中的变长数组，C++也是不支持的

引用 2 楼 user-2 的回复:vc只有在文件名.c的时候才用c编译。cpp就用c++编译。你这_Generic是c11的东西，不是c++的东西。 而且vc是不是支持c11我还不确定。毕竟vc全称叫vc++。换个gcc啥的学c(11)吧 C++不是完美兼容C的吗？

引用 2 楼 user-2 的回复:vc只有在文件名.c的时候才用c编译。cpp就用c++编译。你这_Generic是c11的东西，不是c++的东西。 而且vc是不是支持c11我还不确定。毕竟vc全称叫vc++。换个gcc啥的学c(11)吧 我在VS测试的时候是以.cpp为后缀的（应为要借用引用）

顺带把整段代码贴上吧！ //  generic.c  -- defining generic macros  #include <stdio.h> #include <math.h> #define RAD_TO_DEG (180/(4 * atanl(1)))  // generic square root function #define SQRT(X) _Generic((X),\     long double: sqrtl, \     default: sqrt, \     float: sqrtf)(X)  // generic sine function, angle in degrees #define SIN(X) _Generic((X),\ long double: sinl((X)/RAD_TO_DEG),\ default:     sin((X)/RAD_TO_DEG),\ float:       sinf((X)/RAD_TO_DEG)\ )  int main(void) {     float x = 45.0f;     double xx = 45.0;     long double xxx =45.0L;          long double y = SQRT(x);     long double yy= SQRT(xx);     long double yyy = SQRT(xxx);     printf("%.17Lf\n", y);   // matches float     printf("%.17Lf\n", yy);  // matches default     printf("%.17Lf\n", yyy); // matches long double     int i = 45;     yy = SQRT(i);            // matches default     printf("%.17Lf\n", yy);     yyy= SIN(xxx);           // matches long double     printf("%.17Lf\n", yyy);          return 0; }

引用 7 楼 paschen 的回复:VS对C99都不全支持那么请问有办法更换VS的默认编译器吗？没有的话我去用code blocks 应为我尝试了一些C99和C11在msys2上是完全没有问题的

VS对C99都不全支持

引用 5 楼 paschen 的回复:[quote=引用 4 楼 kinolukaslana 的回复:] [quote=引用 2 楼 user-2 的回复:] vc只有在文件名.c的时候才用c编译。cpp就用c++编译。你这_Generic是c11的东西，不是c++的东西。 而且vc是不是支持c11我还不确定。毕竟vc全称叫vc++。换个gcc啥的学c(11)吧 C++不是完美兼容C的吗？[/quote]  C++并不是所有C的内容都有的，甚至有些都完全不同  如C99中的变长数组，C++也是不支持的[/quote]  这个我知道，我在C4DROID上面测试过的，那么有没有更换VS默认编译器的方法呢？


Question: undefined reference to 'WinMain'

这个不是一个完整的程序，自定义函数htoi没有被调用；在一个程序里，需要有一个main函数，这个函数是整个程序的入口，即main是执行入口～

没有入口函数，main（控制台程序）或者winmain（windows程序）


Question: 这种嵌套循环要怎么看,可以最快的解读出来程序的内容

好的格式，已经每层循环是要干什么的，起始和终结条件，就很容易解读了  #include<stdio.h> int main(void) { 	char lets[27] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"; 	char letter;  	printf("please Enter a letter (for example: E ):\n"); 	scanf("%c",&letter);  	int out_i, in_i_black, in_i_up, in_i_down; 	for (out_i = 0; lets[out_i] <= letter; out_i++) { 		for (in_i_black = 0; in_i_black < (letter - lets[out_i]); in_i_black++) { 			putchar(' '); 		} 		for (in_i_up = 0; in_i_up < out_i; in_i_up++) { 			putchar(lets[in_i_up]); 		} 		for (in_i_down = out_i; in_i_down >= 0; in_i_down--) { 			putchar(lets[in_i_down]); 		} 		putchar('\n'); 	}  	getchar(); 	getchar(); 	return 0; }

最好的办法：不要抱着头空想，单步跟踪程序运行，观察每一步程序执行流程及变量变化情况


Question: ubuntu下fwrite存数据，再fread读取时出现乱码

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

读是getline，写是fwrite，getline是对ASCII字符（文本字符）的读，而fwrite是二进制的写，格式不一样。很有可能会出现乱码； fread和fwrite是成对出现的，建议成对使用，怎么写的就怎么读，相反一样。


Question: 二叉树小白 求教导啊！！来大神 已经看了好久了

引用 3楼user-1 的回复:void NRPreOrder(BiTree bt) { 	Seqstack *S; 	BiTree t=bt; 	S=Init_Seqstack(); 	if(!t) 		printf("the tree is empty"); 	else 	{ 		while(t||!Empty_Seqstack(S)) 		{ 			while(t) 			{ 				printf("%c \n",t->data); 				Push_Seqstack(S,*t);  				t=t->lchild; 			} 			BiTNode temp = {0}; 			Pop_Seqstack(S,&temp); 			t=temp.rchild; 		} 	} }   Pop_Seqstack是对第二个参数进行读写的，对指针读写之前先考虑指针指向的空间是不是你分配的是否可用。麻烦。不太理解。。

BiTree *bt;  InsertL(bt); 这里面就会运行错误吧。bt是一个指针，没有指向可操作的内存区域。 修改成下面的方式： BiTree bt = NULL;  InsertL(&bt);

调试了一下 出栈那里非法内存访问


Question: 关于c排序的优化...求大神解答

想了一下根本不需要建数组c，只需要一个int c记录你取了多少次就行，

引用 4 楼 qq_36752486 的回复:[quote=引用 3 楼 xg436的回复:]第一 拿你举的例子 1  5 7 9                                 2 4 6 8 10                                 第一位自然是1.2比较，但第二位只需要比较1.2里面被挑剩下的那个（2）和挑走的的列的下一个（5）， 第二  你排序的时候采用的是不断插入，这样当然很耗时间 比如你第一次插入就要把后面的9999个数字全部移动一遍 正确的方法是取得第一个数字 插入c[0]，取得第二个插入c[1]， 但是数据变化很多，很难将正确的顺序顺利赋值[/quote] 不太明白你说的数据变化是什么 你的代码我也没仔细看  但是你有后移操作应该是后移后插入 这个很费时间 我的意思是比如你比较a[L1]和b[L2],取小数存进c[0]，然后看你取得是a还是b，把相应L加一，然后重复比较，存值，加一， 注意一下超过R没有 重复k次 取c[k-1] 完了

总之你百度一下归并排序的原理，特别是合并那个步骤，搞清楚以后你自然知道这题怎么做了。  学而不思则罔，思而不学则殆。这句送你最合适。

引用 楼主 qq_36752486 的回复:我也想过将两列数字从头比较，但是这样情况很多。不好写代码。 例如  1  5 7 9          2 4 6 8 10         可以比较1,2确认第一位，确认第二位时将2和4,5比较... 引用 4 楼 qq_36752486 的回复:但是数据变化很多，很难将正确的顺序顺利赋值  也是醉了。。 确认第二位时比4干嘛？4是2后面的元素，因此4肯定是大于2的，所以你只需要比较2和5就好了。 总之你每次比较两列数字各列的第一个就行了，然后把小的那个拿走，这就是思路。

引用 3 楼 xg436的回复:第一 拿你举的例子 1  5 7 9                                 2 4 6 8 10                                 第一位自然是1.2比较，但第二位只需要比较1.2里面被挑剩下的那个（2）和挑走的的列的下一个（5）， 第二  你排序的时候采用的是不断插入，这样当然很耗时间 比如你第一次插入就要把后面的9999个数字全部移动一遍 正确的方法是取得第一个数字 插入c[0]，取得第二个插入c[1]， 但是数据变化很多，很难将正确的顺序顺利赋值

这难道不就是归并排序的合并过程原理？ 都给你排好序了你再去排一次不超时就怪了。。


Question: 关于结构体不声明不定义的情况

struct no_define *p  这不就是定义了一个匿名的结构体的指针了吗

这是一个没有元素的结构体，定义指针是可以，因为指针变量的长度是固定的，都是4个字节（32位系统）；但是定义结构体变量就不行了，因为内存不知道应该给它分配多大空间。


Question: 为什么会出这种问题？

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

#include <stdio.h> #include <stdlib.h> #include <string.h>  struct StuGrade {     char name[32];     int score; };   int main(void) {     FILE* fp1;     FILE* fp2;     FILE* fp3;      struct StuGrade stu1[100];     struct StuGrade stu2[100];     int index1 = 0, index2 = 0;     int i, j;      fp1 = fopen("ab1.txt", "r");     fp2 = fopen("ab2.txt", "r");     fp3 = fopen("db3.txt", "w");      while(!feof(fp1))     {         fscanf(fp1, "%s %d\n", stu1[index1].name, &stu1[index1].score);         index1++;     }     fclose(fp1);      while(!feof(fp2))     {         fscanf(fp2,"%s %d\n",stu2[index2].name, &stu2[index2].score);         index2++;     }     fclose(fp2);       for(i=0;i<index1;i++)     {         for(j=0;j<index2;j++)         {             if(strcmp(stu1[i].name, stu2[j].name) == 0)             {                 fprintf(fp3,"%s %d %d %f\n",                         stu1[i].name,                         stu1[i].score,                         stu2[j].score,                         (stu1[i].score+stu2[j].score)*0.5);             }         }     }     fclose(fp3);     return 0; } 2个问题： 1. 给野指针赋值，name是一个野指针，建议动态申请或者直接定义成一个字符数组； 2. 读文件时，score需要前面加&，因为是往该地址里写数据。

struct StuGrade {     char* name;     int score; }; 你的结构体只定义指针，都没有所指，自然没有办法读入，除非你在读之前先初始化，或者简单点 声明改成 struct StuGrade {     char  name[10];     int score; }; ---------------------------------------------------------------- fscanf(fp1,"%s %d\n",stu1[index1].name,stu1[index1].score); 此外你的fscanf参数也不对啊,后面两个参数应该是地址，所以应该写成 fscanf(fp1,"%s %d\n",stu1[index1].name,&stu1[index1].score); 第一个没改是因为本身就已经是字符串指针了


Question: 觉得自己编的没错呀

谢谢爸爸们，第一次问问题这么快回帖，爱你们哦，

i没有初始化，并且每次循环没有i++

1.i未赋初值，系统会给一个不确定的值。因此会造成后续一系列问题。 2.while(while(str[i]!='\n'){......}，因为前述原因，该循环体中，i值是系统随机给的值，str[i]取的是哪个，鬼晓得？这是是无法实现你设想的目的的。由于i的值是随机的，就意味着你的程序很有可能永远都无法跳出该循环体结束运行。

#include <stdio.h> main() {     char str[50];     int i = 0;     int a = 0, n = 0, e = 0;      gets(str);     while(str[i] != '\0'){         if((str[i]>='A'&&str[i]<='Z') || (str[i]>='a'&&str[i]<='z'))             a++;         else if(str[i]>='0'&&str[i]<='9')             n++;         else             e++;         i++;     }     printf("%d,%d,%d", a, n, e); } 问题： 1, 变量i没有初始化，默认是一个随机值很容易导致数组str越界，导致段错误； 2. i没有在循环++,循环不能继续进行，也不能计算后面的字符； 3. gets不会将回车符加到缓存str里，所以，判断'\n'是不能让循环退出的，故需要改成'\0' 建议：不要使用gets，因为它不知道缓存大小，容易导致越界；建议使用fgets

因为你分配空间分配小了，char str[50],如果输入的是1000个字符呢？

fgets函数不是跟文件一起用吗?用的少，不会用，仅限于见过。

为什么你要定义一个一维数组的char类型来统计


Question: 求助！从文件中读取链表总是在头和尾出现两个乱码的信息怎么回事？

“多一少一”问题占程序员常犯错误的10%以上！ 避免“多一少一”问题的方法之一是将比如<10甚至<5的数代入程序片断，掰手指头心算验证一下程序到底应该写为 x、x-1、x+1中的哪个？ <、<=、==、>、>=中的哪个？  不要使用 while (条件) 更不要使用 while (组合条件) 要使用 while (1) {  if (条件1) break;  //...  if (条件2) continue;  //...  if (条件3) return;  //... } 因为前两种写法在语言表达意思的层面上有二义性，只有第三种才忠实反映了程序流的实际情况。 典型如： 下面两段的语义都是当文件未结束时读字符 while (!feof(f)) {  a=fgetc(f);  //...  b=fgetc(f);//可能此时已经feof了！  //... } 而这样写就没有问题： while (1) {  a=fgetc(f);  if (feof(f)) break;  //...  b=fgetc(f);  if (feof(f)) break;  //... } 类似的例子还可以举很多。

读取的时候，你的头节点是一个哨兵，并没有将文件里的数据赋值给哨兵。所以，你在输出时，头节点的数据是随机值。写入的时候也将头节点写入文件，头节点的数据是随机值，所以文件里的数据就是随机值。

来人啊啊，。。。。。。

没人吗....

第一次发帖好紧张~


Question: 如何做出栈的合法性，有大神解答吗

用一个辅助栈，按照数据进栈的顺序模拟数据压入，和出栈数据进行比较  bool IsPopOrder(vector<int> pushV,vector<int> popV) {         stack<int> temp;         vector<int>::const_iterator itPush = pushV.begin();         vector<int>::const_iterator itPop = popV.begin();          for(;itPop!=popV.end();++itPop){             if(!temp.empty() && temp.top()==*itPop){                 temp.pop();                 continue;             }             for(;itPush != pushV.end(); ++itPush){                 if(*itPush == *itPop){                     break;                 }                 else{                     temp.push(*itPush);                 }             }             if(itPush == pushV.end())                 return false;             ++itPush;         }         return true;     }


Question: 急，如何实现c和java的des互相加解密

这怎么解决的 也遇到这问题了

楼主，最后是怎么解决的。。 我朋友跟你差不多的问题，，

问题是我用java加密的，c无法解密

自己找到问题所在了，不是代码问题

那你前面写的那个有什么问题？

确实，aes比这强，但这是别人要求的

我说一句废话  现在还用DES怕是不太好吧。。

/* 16 Iterations */         for(iter=1;iter< 17;iter++){         for(i=0;i< 32;i++)         {         buffer[i]=bufout[32+i];         } /* Calculation of F(R, K) */ /* Permute - E */         worka[0]=buffer[31];         worka[1]=buffer[0];         worka[2]=buffer[1];         worka[3]=buffer[2];         worka[4]=buffer[3];         worka[5]=buffer[4];         worka[6]=buffer[3];         worka[7]=buffer[4];         worka[8]=buffer[5];         worka[9]=buffer[6];         worka[10]=buffer[7];         worka[11]=buffer[8];         worka[12]=buffer[7];         worka[13]=buffer[8];         worka[14]=buffer[9];         worka[15]=buffer[10];         worka[16]=buffer[11];         worka[17]=buffer[12];         worka[18]=buffer[11];         worka[19]=buffer[12];         worka[20]=buffer[13];         worka[21]=buffer[14];         worka[22]=buffer[15];         worka[23]=buffer[16];         worka[24]=buffer[15];         worka[25]=buffer[16];         worka[26]=buffer[17];         worka[27]=buffer[18];         worka[28]=buffer[19];         worka[29]=buffer[20];         worka[30]=buffer[19];         worka[31]=buffer[20];         worka[32]=buffer[21];         worka[33]=buffer[22];         worka[34]=buffer[23];         worka[35]=buffer[24];         worka[36]=buffer[23];         worka[37]=buffer[24];         worka[38]=buffer[25];         worka[39]=buffer[26];         worka[40]=buffer[27];         worka[41]=buffer[28];         worka[42]=buffer[27];         worka[43]=buffer[28];         worka[44]=buffer[29];         worka[45]=buffer[30];         worka[46]=buffer[31];         worka[47]=buffer[0]; /* KS Function Begin */         if(flg){         nbrofshift=shift[iter-1];         for(i=0;i< (int)nbrofshift;i++){         temp1=kwork[0];         temp2=kwork[28];         for(j=0;j< 27;j++){         kwork[j]=kwork[j+1];         kwork[j+28]=kwork[j+29];         }         kwork[27]=temp1;         kwork[55]=temp2;         }         }else if(iter>1){         nbrofshift=shift[17-iter];         for(i=0;i< (int)nbrofshift;i++){         temp1=kwork[27];         temp2=kwork[55];         for(j=27;j>0;j--){         kwork[j]=kwork[j-1];         kwork[j+28]=kwork[j+27];         }         kwork[0]=temp1;         kwork[28]=temp2;         }         } /* Permute kwork - PC2 */         kn[0]=kwork[13];         kn[1]=kwork[16];         kn[2]=kwork[10];         kn[3]=kwork[23];         kn[4]=kwork[0];         kn[5]=kwork[4];         kn[6]=kwork[2];         kn[7]=kwork[27];         kn[8]=kwork[14];         kn[9]=kwork[5];         kn[10]=kwork[20];         kn[11]=kwork[9];         kn[12]=kwork[22];         kn[13]=kwork[18];         kn[14]=kwork[11];         kn[15]=kwork[3];         kn[16]=kwork[25];         kn[17]=kwork[7];         kn[18]=kwork[15];         kn[19]=kwork[6];         kn[20]=kwork[26];         kn[21]=kwork[19];         kn[22]=kwork[12];         kn[23]=kwork[1];         kn[24]=kwork[40];         kn[25]=kwork[51];         kn[26]=kwork[30];         kn[27]=kwork[36];         kn[28]=kwork[46];         kn[29]=kwork[54];         kn[30]=kwork[29];         kn[31]=kwork[39];         kn[32]=kwork[50];         kn[33]=kwork[44];         kn[34]=kwork[32];         kn[35]=kwork[47];         kn[36]=kwork[43];         kn[37]=kwork[48];         kn[38]=kwork[38];         kn[39]=kwork[55];         kn[40]=kwork[33];         kn[41]=kwork[52];         kn[42]=kwork[45];         kn[43]=kwork[41];         kn[44]=kwork[49];         kn[45]=kwork[35];         kn[46]=kwork[28];         kn[47]=kwork[31]; /* KS Function End */ /* worka XOR kn */         for(i=0;i< 48;i++)         worka[i]=worka[i]^kn[i]; /* 8 s-functions */         valindex=s1[2*worka[0]+worka[5]]         [2*(2*(2*worka[1]+worka[2])+         worka[3])+worka[4]];         valindex=valindex*4;         kn[0]=binary[0+valindex];         kn[1]=binary[1+valindex];         kn[2]=binary[2+valindex];         kn[3]=binary[3+valindex];         valindex=s2[2*worka[6]+worka[11]]         [2*(2*(2*worka[7]+worka[8])+         worka[9])+worka[10]];         valindex=valindex*4;         kn[4]=binary[0+valindex];         kn[5]=binary[1+valindex];         kn[6]=binary[2+valindex];         kn[7]=binary[3+valindex];         valindex=s3[2*worka[12]+worka[17]]         [2*(2*(2*worka[13]+worka[14])+         worka[15])+worka[16]];         valindex=valindex*4;         kn[8]=binary[0+valindex];         kn[9]=binary[1+valindex];         kn[10]=binary[2+valindex];         kn[11]=binary[3+valindex];         valindex=s4[2*worka[18]+worka[23]]         [2*(2*(2*worka[19]+worka[20])+         worka[21])+worka[22]];         valindex=valindex*4;         kn[12]=binary[0+valindex];         kn[13]=binary[1+valindex];         kn[14]=binary[2+valindex];         kn[15]=binary[3+valindex];         valindex=s5[2*worka[24]+worka[29]]         [2*(2*(2*worka[25]+worka[26])+         worka[27])+worka[28]];         valindex=valindex*4;         kn[16]=binary[0+valindex];         kn[17]=binary[1+valindex];         kn[18]=binary[2+valindex];         kn[19]=binary[3+valindex];         valindex=s6[2*worka[30]+worka[35]]         [2*(2*(2*worka[31]+worka[32])+         worka[33])+worka[34]];         valindex=valindex*4;         kn[20]=binary[0+valindex];         kn[21]=binary[1+valindex];         kn[22]=binary[2+valindex];         kn[23]=binary[3+valindex];         valindex=s7[2*worka[36]+worka[41]]         [2*(2*(2*worka[37]+worka[38])+         worka[39])+worka[40]];         valindex=valindex*4;         kn[24]=binary[0+valindex];         kn[25]=binary[1+valindex];         kn[26]=binary[2+valindex];         kn[27]=binary[3+valindex];         valindex=s8[2*worka[42]+worka[47]]         [2*(2*(2*worka[43]+worka[44])+         worka[45])+worka[46]];         valindex=valindex*4;         kn[28]=binary[0+valindex];         kn[29]=binary[1+valindex];         kn[30]=binary[2+valindex];         kn[31]=binary[3+valindex]; /* Permute - P */         worka[0]=kn[15];         worka[1]=kn[6];         worka[2]=kn[19];         worka[3]=kn[20];         worka[4]=kn[28];         worka[5]=kn[11];         worka[6]=kn[27];         worka[7]=kn[16];         worka[8]=kn[0];         worka[9]=kn[14];         worka[10]=kn[22];         worka[11]=kn[25];         worka[12]=kn[4];         worka[13]=kn[17];         worka[14]=kn[30];         worka[15]=kn[9];         worka[16]=kn[1];         worka[17]=kn[7];         worka[18]=kn[23];         worka[19]=kn[13];         worka[20]=kn[31];         worka[21]=kn[26];         worka[22]=kn[2];         worka[23]=kn[8];         worka[24]=kn[18];         worka[25]=kn[12];         worka[26]=kn[29];         worka[27]=kn[5];         worka[28]=kn[21];         worka[29]=kn[10];         worka[30]=kn[3];         worka[31]=kn[24]; /* bufout XOR worka */         for(i=0;i< 32;i++){         bufout[i+32]=bufout[i]^worka[i];         bufout[i]=buffer[i];         }         } /* End of Iter */ /* Prepare Output */         for(i=0;i< 32;i++){         j=bufout[i];         bufout[i]=bufout[32+i];         bufout[32+i]=j;         } /* Inverse Initial Permutation */         buffer[0]=bufout[39];         buffer[1]=bufout[7];         buffer[2]=bufout[47];         buffer[3]=bufout[15];         buffer[4]=bufout[55];         buffer[5]=bufout[23];         buffer[6]=bufout[63];         buffer[7]=bufout[31];         buffer[8]=bufout[38];         buffer[9]=bufout[6];         buffer[10]=bufout[46];         buffer[11]=bufout[14];         buffer[12]=bufout[54];         buffer[13]=bufout[22];         buffer[14]=bufout[62];         buffer[15]=bufout[30];         buffer[16]=bufout[37];         buffer[17]=bufout[5];         buffer[18]=bufout[45];         buffer[19]=bufout[13];         buffer[20]=bufout[53];         buffer[21]=bufout[21];         buffer[22]=bufout[61];         buffer[23]=bufout[29];         buffer[24]=bufout[36];         buffer[25]=bufout[4];         buffer[26]=bufout[44];         buffer[27]=bufout[12];         buffer[28]=bufout[52];         buffer[29]=bufout[20];         buffer[30]=bufout[60];         buffer[31]=bufout[28];         buffer[32]=bufout[35];         buffer[33]=bufout[3];         buffer[34]=bufout[43];         buffer[35]=bufout[11];         buffer[36]=bufout[51];         buffer[37]=bufout[19];         buffer[38]=bufout[59];         buffer[39]=bufout[27];         buffer[40]=bufout[34];         buffer[41]=bufout[2];         buffer[42]=bufout[42];         buffer[43]=bufout[10];         buffer[44]=bufout[50];         buffer[45]=bufout[18];         buffer[46]=bufout[58];         buffer[47]=bufout[26];         buffer[48]=bufout[33];         buffer[49]=bufout[1];         buffer[50]=bufout[41];         buffer[51]=bufout[9];         buffer[52]=bufout[49];         buffer[53]=bufout[17];         buffer[54]=bufout[57];         buffer[55]=bufout[25];         buffer[56]=bufout[32];         buffer[57]=bufout[0];         buffer[58]=bufout[40];         buffer[59]=bufout[8];         buffer[60]=bufout[48];         buffer[61]=bufout[16];         buffer[62]=bufout[56];         buffer[63]=bufout[24];         j=0;         for(i=0;i< 8;i++){         *(dest+i)=0x00;         for(k=0;k< 7;k++)         *(dest+i)=((*(dest+i))+buffer[j+k])*2;         *(dest+i)=*(dest+i)+buffer[j+7];         j+=8;         }         return 0;         }