Question: 关于malloc()的一个问题。

引用 6 楼 hyp41226 的回复:[quote=引用 5 楼 pokerLee 的回复:] 可以正常运行么？ 完整的程序是可以运行的，确实是在C中加不加类型指派都可以。[/quote]如果直接引用（void）类型可以么~~

引用 5 楼 pokerLee 的回复:可以正常运行么？ 完整的程序是可以运行的，确实是在C中加不加类型指派都可以。

可以正常运行么？

引用 3 楼 hyp41226 的回复:malloc返回的是void类型指针    这个我知道。 我的问题是malloc前面的类型指派是必须要加上去的吗？  比如说 int * p; ...... 1.    p = (int *)malloc(30 * sizeof(int)); 2.    p = malloc(30 * sizeof(int)); 这两种方法都对？也就是说类型指派不是必须的？ 因为起初C中没有void*类型，malloc返回的是char*类型，所以要求必须强制转换 但是自void*加入以后，可以不转换，也可以转换 不过有两点 1.C中可以不转换，可以编译通过 2.C++中必须强制转换，否则不能通过编译

void*型，转成什么都可以

malloc返回的是void类型指针  使用的时候最好强制转换一下   这什么东东啊  CSS？


Question: 回文的两种写法

如果回文，应该是对称的 for(int i=0;i<=strlen(ch);i++) 应该只需要扫描一半的长度吧？

不太清楚啊，我用的递归一般般#include <iostream> using namespace std;  bool IsPalindrome(string s){ 	if(s.length() <= 1) 		return true; 	return s[0] == s[s.length()-1] && IsPalindrome(s.substr(1,s.length()-2)); } int main(){ 	string s="aaabbbaaa"; 	bool a = IsPalindrome(s); 	cout<<a<<endl; 	return 0; }


Question: 关于stdin的重定向

仅供参考#include <stdio.h> #include <string.h> FILE *f; int c; void main(int argc,char **argv) {     if (argc==3) {         if (stricmp(argv[1],"-a")) goto USAGE;         f=fopen(argv[2],"a");         if (NULL==f) goto FNULL;         goto FOK;     } else if (argc==2) {         if (0==strcmp(argv[1],"/?")) {         USAGE:             fprintf(stderr,"Usage: program | tee [-a] file\n");             return;         }         f=fopen(argv[1],"w");         if (NULL==f) goto FNULL;     FOK:         while (1) {             c=getchar();             if (EOF==c) break;             if (EOF==fputc(c,f)) {                 putchar(c);                 break;             } else {                 if (EOF==putchar(c)) break;             }         }         fclose(f);     } else {     FNULL:         while (1) {             c=getchar();             if (EOF==c) break;             if (EOF==putchar(c)) break;         }     } }

tail -f


Question: 求解！！！！！！！

为什么i<=n-i+1 ??????

#include<stdio.h> int main()  {  	int n,i,k; 	scanf("%d",&k); 	while(k--) 	{ 		int l,a[1000],b,j,z,m=-1; 		scanf("%d %d",&l,&n); 		for(i=1;i<=n;i++) 			scanf("%d",&a[i]); 		 		for(i=1;i<=n-i+1;i++) 		{	 			b=0; 			for(j=i;j<i+l;j++) 			b=b+a[j]; 			if(b>m) 			{ 				m=b; 				z=i; 			} 		} 		if(m>=0) 		printf("%d\n",z); 		else 		printf("0\n"); 	} 		return 0;  }


Question: linux 下c 函数rename为什么 没法用啊。

int rename(const char *oldpath, const char *newpath); 试试全路径  EACCES Write permission is denied for the directory containing  oldpath               or  newpath,  or,  search  permission  is  denied for one of the               directories in the path prefix of oldpath or newpath, or oldpath               is  a  directory  and does not allow write permission (needed to               update the ..  entry).  (See also path_resolution(2).)

include\errno.h ... /* Error Codes */  #define EPERM           1 #define ENOENT          2 #define ESRCH           3 #define EINTR           4 #define EIO             5 #define ENXIO           6 #define E2BIG           7 #define ENOEXEC         8 #define EBADF           9 #define ECHILD          10 #define EAGAIN          11 #define ENOMEM          12 #define EACCES          13 #define EFAULT          14 #define EBUSY           16 #define EEXIST          17 #define EXDEV           18 #define ENODEV          19 #define ENOTDIR         20 #define EISDIR          21 #define ENFILE          23 #define EMFILE          24 #define ENOTTY          25 #define EFBIG           27 #define ENOSPC          28 #define ESPIPE          29 #define EROFS           30 #define EMLINK          31 #define EPIPE           32 #define EDOM            33 #define EDEADLK         36 #define ENAMETOOLONG    38 #define ENOLCK          39 #define ENOSYS          40 #define ENOTEMPTY       41 ...

引用 7 楼 zhao4zhong1 的回复:RENAME Section: POSIX Programmer's Manual (P) Updated: 2003  --------------------------------------------------------------------------------    NAME rename - rename a file    SYNOPSIS #include <stdio.h>    int rename(const char *old, const char *new);      DESCRIPTION The rename() function shall change the name of a file. The old argument points to the pathname of the file to be renamed. The new argument points to the new pathname of the file.   If either the old or new argument names a symbolic link, rename() shall operate on the symbolic link itself, and shall not resolve the last component of the argument. If the old argument and the new argument resolve to the same existing file, rename() shall return successfully and perform no other action.   If the old argument points to the pathname of a file that is not a directory, the new argument shall not point to the pathname of a directory. If the link named by the new argument exists, it shall be removed and old renamed to new. In this case, a link named new shall remain visible to other processes throughout the renaming operation and refer either to the file referred to by new or old before the operation began. Write access permission is required for both the directory containing old and the directory containing new.   If the old argument points to the pathname of a directory, the new argument shall not point to the pathname of a file that is not a directory. If the directory named by the new argument exists, it shall be removed and old renamed to new. In this case, a link named new shall exist throughout the renaming operation and shall refer either to the directory referred to by new or old before the operation began. If new names an existing directory, it shall be required to be an empty directory.   If the old argument points to a pathname of a symbolic link, the symbolic link shall be renamed. If the new argument points to a pathname of a symbolic link, the symbolic link shall be removed.   The new pathname shall not contain a path prefix that names old. Write access permission is required for the directory containing old and the directory containing new. If the old argument points to the pathname of a directory, write access permission may be required for the directory named by old, and, if it exists, the directory named by new.   If the link named by the new argument exists and the file's link count becomes 0 when it is removed and no process has the file open, the space occupied by the file shall be freed and the file shall no longer be accessible. If one or more processes have the file open when the last link is removed, the link shall be removed before rename() returns, but the removal of the file contents shall be postponed until all references to the file are closed.   Upon successful completion, rename() shall mark for update the st_ctime and st_mtime fields of the parent directory of each file.   If the rename() function fails for any reason other than [EIO], any file named by new shall be unaffected.     RETURN VALUE Upon successful completion, rename() shall return 0; otherwise, -1 shall be returned, errno shall be set to indicate the error, and neither the file named by old nor the file named by new shall be changed or created.     ERRORS The rename() function shall fail if:   EACCES  A component of either path prefix denies search permission; or one of the directories containing old or new denies write permissions; or, write permission is required and is denied for a directory pointed to by the old or new arguments.  EBUSY  The directory named by old or new is currently in use by the system or another process, and the implementation considers this an error.  EEXIST or ENOTEMPTY  The link named by new is a directory that is not an empty directory.   EINVAL  The new directory pathname contains a path prefix that names the old directory.  EIO  A physical I/O error has occurred.  EISDIR  The new argument points to a directory and the old argument points to a file that is not a directory.  ELOOP  A loop exists in symbolic links encountered during resolution of the path argument.  EMLINK  The file named by old is a directory, and the link count of the parent directory of new would exceed {LINK_MAX}.  ENAMETOOLONG  The length of the old or new argument exceeds {PATH_MAX} or a pathname component is longer than {NAME_MAX}.   ENOENT  The link named by old does not name an existing file, or either old or new points to an empty string.  ENOSPC  The directory that would contain new cannot be extended.  ENOTDIR  A component of either path prefix is not a directory; or the old argument names a directory and new argument names a non-directory file.  EPERM or EACCES  The S_ISVTX flag is set on the directory containing the file referred to by old and the caller is not the file owner, nor is the caller the directory owner, nor does the caller have appropriate privileges; or new refers to an existing file, the S_ISVTX flag is set on the directory containing this file, and the caller is not the file owner, nor is the caller the directory owner, nor does the caller have appropriate privileges.   EROFS  The requested operation requires writing in a directory on a read-only file system.  EXDEV  The links named by new and old are on different file systems and the implementation does not support links between file systems.   The rename() function may fail if:   EBUSY  The file named by the old or new arguments is a named STREAM.  ELOOP  More than {SYMLOOP_MAX} symbolic links were encountered during resolution of the path argument.  ENAMETOOLONG  As a result of encountering a symbolic link in resolution of the path argument, the length of the substituted pathname string exceeded {PATH_MAX}.   ETXTBSY  The file to be renamed is a pure procedure (shared text) file that is being executed.   The following sections are informative.     EXAMPLES    Renaming a File The following example shows how to rename a file named /home/cnd/mod1 to /home/cnd/mod2.     #include <stdio.h>   int status; ... status = rename("/home/cnd/mod1", "/home/cnd/mod2");      APPLICATION USAGE Some implementations mark for update the st_ctime field of renamed files and some do not. Applications which make use of the st_ctime field may behave differently with respect to renamed files unless they are designed to allow for either behavior.     RATIONALE This rename() function is equivalent for regular files to that defined by the ISO C standard. Its inclusion here expands that definition to include actions on directories and specifies behavior when the new parameter names a file that already exists. That specification requires that the action of the function be atomic.   One of the reasons for introducing this function was to have a means of renaming directories while permitting implementations to prohibit the use of link() and unlink() with directories, thus constraining links to directories to those made by mkdir().   The specification that if old and new refer to the same file is intended to guarantee that:     rename("x", "x");   does not remove the file.   Renaming dot or dot-dot is prohibited in order to prevent cyclical file system paths.   See also the descriptions of [ENOTEMPTY] and [ENAMETOOLONG] in rmdir() and [EBUSY] in unlink() . For a discussion of [EXDEV], see link() .     FUTURE DIRECTIONS None.     SEE ALSO link() , rmdir() , symlink() , unlink() , the Base Definitions volume of IEEE Std 1003.1-2001, <stdio.h>     COPYRIGHT Portions of this text are reprinted and reproduced in electronic form from IEEE Std 1003.1, 2003 Edition, Standard for Information Technology -- Portable Operating System Interface (POSIX), The Open Group Base Specifications Issue 6, Copyright (C) 2001-2003 by the Institute of Electrical and Electronics Engineers, Inc and The Open Group. In the event of any discrepancy between this version and the original IEEE and The Open Group Standard, the original IEEE and The Open Group Standard is the referee document. The original Standard can be obtained online at http://www.opengroup.org/unix/online.html .  --------------------------------------------------------------------------------   我的错误号 今天 打印了看到 是13

引用 2 楼 derekrose 的回复:http://www.yolinux.com/TUTORIALS/GDB-Commands.html不理解。怎么做嘛

引用 3 楼 turingo 的回复:设置断点，调试看看rename有没有执行。  [quote=引用 楼主 heshan0511 的回复:] typedef struct online { char name[20]; int fd; } ONL；   文件online存结构体数组。现有name，然后删除文件中相同name的结构体 为什么都对，到最后一步rename好像没执行，最后文件中只有online1   void offline(char *name) { FILE *fp,*fp2;  ONL *OnlInfo;  fp=fopen("online", "r");  fp2=fopen("online1","w"); if(fp==NULL) { printf("on one online!"); }  else { OnlInfo=(ONL *)malloc(sizeof(ONL));  while(!feof(fp)) { memset(OnlInfo,0,sizeof(ONL)); if((fread(OnlInfo,sizeof(ONL),1,fp)!=0)&&(strcmp(OnlInfo->name,name)!=0)) { fwrite(OnlInfo,sizeof(ONL),1,fp2); } } if(OnlInfo!=NULL) { free(OnlInfo); OnlInfo=NULL; } fclose(fp2); fclose(fp); }   remove("online");  rename("online1","online"); };[/quote]   我用了printf ，表示这一句是 执行了的

引用 1 楼 user-5 的回复:你remove掉online然后又对online1对其重命名成online,最后不是正好符合你结果么，不是没有运行remove是你没看到。。。   我说的是rename 重命名

设置断点，调试看看rename有没有执行。  引用 楼主 heshan0511 的回复:typedef struct online { char name[20]; int fd; } ONL；   文件online存结构体数组。现有name，然后删除文件中相同name的结构体 为什么都对，到最后一步rename好像没执行，最后文件中只有online1   void offline(char *name) { FILE *fp,*fp2;  ONL *OnlInfo;  fp=fopen("online", "r");  fp2=fopen("online1","w"); if(fp==NULL) { printf("on one online!"); }  else { OnlInfo=(ONL *)malloc(sizeof(ONL));  while(!feof(fp)) { memset(OnlInfo,0,sizeof(ONL)); if((fread(OnlInfo,sizeof(ONL),1,fp)!=0)&&(strcmp(OnlInfo->name,name)!=0)) { fwrite(OnlInfo,sizeof(ONL),1,fp2); } } if(OnlInfo!=NULL) { free(OnlInfo); OnlInfo=NULL; } fclose(fp2); fclose(fp); }   remove("online");  rename("online1","online"); };


Question: 关于内存对齐的问题，各位达人帮解答一下

typedef struct { double daa;	  //8 int xx;	          //8         char aaa[13];	// 8 + 8 }Str_A; sizeof(Str_A) = 8 + 8 + 8 + 8 = 32   typedef struct {	 int xx;	                   //4         char aaa[13];	   //4 + 4 + 4 + 4         double daa;        //4 + 4 }Str_B; sizeof(Str_B)  = 4 + 4 + 4 + 4 + 4 + 4 + 4 = 28 这个跟编译器有关。

#include <stdio.h> #define field_offset(s,f) (int)(&(((struct s *)(0))->f)) struct AD  { int a; char b[13]; double c;}; #pragma pack(push) #pragma pack(1) struct A1  { int a; char b[13]; double c;}; #pragma pack(2) struct A2  { int a; char b[13]; double c;}; #pragma pack(4) struct A4  { int a; char b[13]; double c;}; #pragma pack(8) struct A8  { int a; char b[13]; double c;}; #pragma pack(16) struct A16 { int a; char b[13]; double c;}; #pragma pack(pop) int main() {     printf("AD.a %d\n",field_offset(AD,a));     printf("AD.b %d\n",field_offset(AD,b));     printf("AD.c %d\n",field_offset(AD,c));     printf("\n");     printf("A1.a %d\n",field_offset(A1,a));     printf("A1.b %d\n",field_offset(A1,b));     printf("A1.c %d\n",field_offset(A1,c));     printf("\n");     printf("A2.a %d\n",field_offset(A2,a));     printf("A2.b %d\n",field_offset(A2,b));     printf("A2.c %d\n",field_offset(A2,c));     printf("\n");     printf("A4.a %d\n",field_offset(A4,a));     printf("A4.b %d\n",field_offset(A4,b));     printf("A4.c %d\n",field_offset(A4,c));     printf("\n");     printf("A8.a %d\n",field_offset(A8,a));     printf("A8.b %d\n",field_offset(A8,b));     printf("A8.c %d\n",field_offset(A8,c));     printf("\n");     printf("A16.a %d\n",field_offset(A16,a));     printf("A16.b %d\n",field_offset(A16,b));     printf("A16.c %d\n",field_offset(A16,c));     printf("\n");     return 0; } //AD.a 0 //AD.b 4 //AD.c 24 // //A1.a 0 //A1.b 4 //A1.c 17 // //A2.a 0 //A2.b 4 //A2.c 18 // //A4.a 0 //A4.b 4 //A4.c 20 // //A8.a 0 //A8.b 4 //A8.c 24 // //A16.a 0 //A16.b 4 //A16.c 24 // //

#pragma pack(push,4) typedef struct {     double daa;	     int xx;	     char aaa[13];	 }Str_A;  typedef struct {	     int xx;	     char aaa[13];	     double daa; }Str_B; #pragma pack(pop)这样出来都是28吧 #pragma pack(push,2) typedef struct {     double daa;	     int xx;	     char aaa[13];	 }Str_A;  typedef struct {	     int xx;	     char aaa[13];	     double daa; }Str_B; #pragma pack(pop)这样出来都是26吧，没有你说的一个是32一个是28的情况

32位系统下gcc是28，vs是32，32位系统下gcc默认对齐是4字节，vs默认8字节

不同的系统下 跟你结构体保存的起始地址有关吧

引用 3 楼 user-8 的回复:什么编译器啊， 难道32位编译的时候，设置成4个字节以上的时候，还是4个字节啊。  如果16字节设置有效的话应该是 32吧 typedef struct {	          int xx;       假设从0开始	         char aaa[13];	这个从4开始         double daa;     这个必须从8的倍数开始， 那大于（4+13）的只有 24了 }Str_B; 因此总大小 是32  VS实际确认也是32   确实是这样，不好意思，我理解错误了，谢谢。

引用 楼主 sduzhk 的回复:设置16字节对齐,32位编译。 以下两个结构体sizeof(Str_A)为32是正确的, 但是为何sizeof(Str_B) 为28  typedef struct { 	double daa;	 	int xx;	         char aaa[13];	 }Str_A;  typedef struct {	 	int xx;	         char aaa[13];	         double daa; }Str_B;我这运行出来sizeof(Str_B)是32，不是28

typedef struct { int xx;    //4字节         char aaa[13];//16字节         double daa;// 8字节不是16字节的原因: }Str_B;   数据成员对齐规则：结构(struct)(或联合(union))的数据成员，第一个数据成员放在offset为0的地方，以后每个数据成员的对齐按照 #pragma pack指定的数值和这个数据成员自身长度中，比较小的那个进行。

第二个4+16+8不是正好是28么


Question: 图片加密解密的设计与实现

#include <stdio.h> #include <string.h> #include <conio.h> FILE *fi,*fo; int i; int main(int argc,char **argv) {     if (argc<3) {         printf("Usage:%s src des\n",argv[0]);         return 1;     }     if (0==stricmp(argv[1],argv[2])) {         printf("Src and des is same!\n");         return 2;     }     fo=fopen(argv[2],"wb");     if (NULL==fo) {         printf("Can not create file %s\n",argv[2]);         return 3;     }     fi=fopen(argv[1],"rb");     if (NULL==fi) {         fclose(fo);         printf("Can not find file %s\n",argv[1]);         return 4;     }     i=0;     fseek(fi,-1L,SEEK_END);     while (1) {         fputc(fgetc(fi)^0x5A,fo);         i++;         if (i%1000000==0) cprintf("\r%dKB",i/1000);         if (fseek(fi,-2,SEEK_CUR)) break;     }     fclose(fi);     fclose(fo);     cprintf("\r%dKB OK.\r\n",i/1000);     return 0; }

百度一下异或加密

引用 4 楼 u013189263 的回复:[quote=引用 2 楼 user-4 的回复:] 看你要什么程度的加密算法了吧！简单的就顺便加点东西进去就好了(当然自己得记得加了啥，后面还是需要自己解密的)！ 简单一点的，算法的选择您能给我一些什么建议吗？[/quote] 异或就是xor

比如你的异或因子是0x5a： 1、你的图片数据每个字节和0x5a异或之后就相当于加密了； 2、解密的时候把数据与0x5a异或就可以还原之前的数据，相当于解密了。  引用 3 楼 u013189263 的回复:引用 1 楼 turingo 的回复:最简单快速的方法是异或。  [quote=引用 楼主 u013189263 的回复:] 大一小白一枚，求关于图片加密解密的设计与实现的代码，最好能告诉我使用的是什么算法，谢谢了 能说得具体一点吗？[/quote]

引用 2 楼 user-4 的回复:看你要什么程度的加密算法了吧！简单的就顺便加点东西进去就好了(当然自己得记得加了啥，后面还是需要自己解密的)！ 简单一点的，算法的选择您能给我一些什么建议吗？

引用 1 楼 turingo 的回复:最简单快速的方法是异或。  引用 楼主 u013189263 的回复:大一小白一枚，求关于图片加密解密的设计与实现的代码，最好能告诉我使用的是什么算法，谢谢了 能说得具体一点吗？


Question: C语言调用system指令的问题

#include <stdio.h> #include <stdlib.h> void getUsrName(char **p){ #ifdef WIN32     *p=getenv("USERNAME"); #else     *p=getenv("USER"); #endif } int main(void){     char *p;     getUsrName(&p)     printf("[%s]\n",p);     return 0; }

引用 5 楼 terhack 的回复:要不全用system，要不全用函数实现 英雄所见略同

饿，我还是先结贴好了，bus error的问题单独开个帖子来问，再次谢谢楼上的各位哦

引用 7 楼 slovelinux 的回复:[code=c] char *p;  　　　　if((p = getenv(“USER”)))              printf(“Welcome,%s\n”,p); [/code]  谢谢楼上的各位高手，我打算采用 getenv了（处理方法见下代码） 小弟还有一个问题请教一下，  void getUsrName(char **p){ #ifdef WIN32     userName=getenv("USERNAME"); #else     (*userName)=getenv("USER"); #endif }  int main(void){     char *p;     getUsrName(&p) }   请问这种写法会有问题吗？ 我是C语言环境 (因为原来在写程序的时候，提前声明了一个char * a 变量，然后在后续程序执行的时候，对这个变量a进行了scanf("%s", a) 结果会提示BUS ERROR，很担心这次会遇到同样的问题)

system也是很强大啊

要不全用system，要不全用函数实现

要刷新缓冲区才可以 printf("Welcome,"); setbuf(stdout, NULL); system("whoami");

#include <stdlib.h> int main() {     system("@echo Welcome, %USERNAME%&@echo %USERNAME%@Function^>");     return 0; } //Welcome, Administrator //Administrator@Function> //  命令行解释器概述命令行解释器是一个单独的软件程序，它可以在用户和操作系统之间提供直接的通讯。非图形命令行解释器用户界面提供运行基于字符的应用程序和实用程序的环境。通过使用类似于 MS-DOS 命令解释程序 Command.com 的单独字符，命令行解释器执行程序并在屏幕上显示其输出。Windows 服务器操作系统命令行解释器使用命令解释程序 Cmd.exe（该程序加载应用程序并指导应用程序之间的信息流动）将用户输入转换为操作系统可理解的形式。  可以使用命令行解释器创建和编辑可自动执行常规任务的批处理文件（也称作脚本）。例如，可以使用脚本自动管理用户帐户或夜间备份。还可以使用 Windows 脚本宿主 CScript 的命令行版本在命令行解释器中运行更高级的脚本。详细信息，请参阅运行 Windows 脚本宿主。通过使用批处理文件来执行操作，可比使用用户界面更有效率。批处理文件接受命令行上可用的所有命令。有关批处理文件和脚本的详细信息，请参阅使用批处理文件。  您可以自定义命令提示符窗口以易于查看并增强对程序运行方式的控制。有关自定义命令提示符窗口的详细信息，请参阅配置命令提示符。  使用命令语法 语法按命令及所带参数必须遵循的键入顺序出现。下面的 xcopy 命令示例显示了各种语法文本格式：  xcopy Source [Destination] [/w] [/p] [/c] [/v] [/q] [/f] [/l] [/g] [/d[:MM-DD-YYYY]] [/u] [/i] [/s [/e]] [/t] [/k] [/r] [/h] [{/a | /m}] [/n] [/o] [/x] [/exclude:File1[+[File2]][+[File3]] [{/y | /-y}] [/z]  下表说明如何解释不同的文本格式。  格式化图例 格式 含义  斜体 用户必须提供的信息  粗体 用户必须准确键入的要显示的元素  省略号 (...) 在命令行中可多次重复的参数  中括号 ([]) 可选项  大括号 ({})；选项用竖线 (|) 分隔。例如：{even|odd} 用户必须从选项集合中选择一个   Courier 字体 代码或程序输出    使用多个命令和条件处理符号 使用条件处理符号可以在单个命令行或脚本中运行多个命令。通过条件处理符号运行多个命令时，条件处理符号右边的命令根据条件处理符号左边命令的执行结果来发挥作用。例如，只有在前一个命令失败的情况下才可能需要运行一个新命令。或者，只有在前一个命令成功时才可能需要运行一个新命令。  可以使用下表列出的特殊字符来传递多个命令。  字符 语法 定义  & [...] Command1 & Command2 用来分隔一个命令行中的多个命令。Cmd.exe 运行第一个命令，然后运行第二个命令。  && [...] Command1 && Command2 只有在符号 && 前面的命令成功时，才运行该符号后面的命令。Cmd.exe 运行第一个命令，然后只有在第一个命令运行成功时才运行第二个命令。  || [...] Command1 || Command2 只有在符号 || 前面的命令失败时，才运行符号 || 后面的命令。Cmd.exe 运行第一个命令，然后只有在第一个命令未能运行成功（接收到大于零的错误代码）时才运行第二个命令。  ( ) [...] (Command1 & Command2)  用来分组或嵌套多个命令。  ; 或者 ， Command1 Parameter1;Parameter2 用来分隔命令参数。    注意  “与”符号 (&)、管道符号 (|) 以及括号 () 是特殊字符，将它们作为参数传递时，必须在其前面加上转义字符 (^) 或引号。  如果某个命令成功完成操作，该命令就返回零 (0) 退出代码或不返回任何退出代码。有关退出代码的详细信息，请参阅 Microsoft Windows 部署和资源工具包。  嵌套命令行解释器 通过在命令提示符下打开新的 Cmd.exe 实例，可以在 Cmd.exe 内嵌套命令行解释器。默认情况下，Cmd.exe 的每个实例继承其父 Cmd.exe 应用程序的环境。通过嵌套 Cmd.exe 的实例，可以更改局部环境，而不会影响 Cmd.exe 的父应用程序。这使您能够保留 Cmd.exe 的原始环境，并在终止嵌套的命令行解释器之后返回到原始环境。但是在嵌套的命令行解释器中所做的更改将不会被保存。  要嵌套命令行解释器，请在命令提示符下键入：   cmd  出现类似于下面内容的消息：  Microsoft (R) Windows Server 2003 Standard Edition (TM) (C) 版权所有 1985-2002 Microsoft Corp.  要关闭嵌套的命令行解释器，请键入 exit。  使用 setlocal 和 endlocal 命令，可以在 Cmd.exe 的实例中（或在脚本中）进一步将更改局部化。Setlocal 创建局部作用范围，而 endlocal 终止局部作用范围。在 setlocal 和 endlocal 作用范围内所做的更改将会被放弃，从而保持原始环境不变。这两个命令的嵌套最高可达到 32 级。有关 setlocal 和 endlocal 命令的详细信息，请参阅 Setlocal 和 Endlocal。  将环境变量与 Cmd.exe 一起使用 Cmd.exe 命令行解释器环境由确定命令行解释器和操作系统行为的变量进行定义。可以使用两种类型的环境变量（系统和局部）来定义命令行解释器环境或整个操作系统环境的行为。系统环境变量定义全局操作系统环境的行为。局部环境变量定义 Cmd.exe 当前实例环境的行为。  系统环境变量预置于操作系统之中，并可用于所有 Windows 服务器操作系统进程。只有具有管理凭据的用户才可以更改系统变量。这些变量最常用于登录脚本。  局部环境变量只有在创建变量时针对的目标用户登录到计算机时才有效。HKEY_CURRENT_USER 配置单元中设置的局部变量只对当前用户有效，但它们可定义全局操作系统环境的行为。  下表按优先顺序的降序描述变量的各种类型：  内置系统变量  在 HKEY_LOCAL_MACHINE 配置单元中找到的系统变量  在 HKEY_CURRENT_USER 配置单元中找到的局部变量  在 Autoexec.bat 文件中设置的所有环境变量和路径  在登录脚本（如果有的话）中设置的所有环境变量  在脚本或批处理文件中交互使用的变量  在命令行解释器中，Cmd.exe 的每个实例都继承其父应用程序的环境。因此，可以在不影响父应用程序环境的情况下更改新的 Cmd.exe 环境中的变量。  下表列出 Windows server operating system 的系统和本地环境变量。  变量 类型 描述  %ALLUSERSPROFILE% 本地 返回“所有用户”配置文件的位置。  %APPDATA% 本地 返回默认情况下应用程序存储数据的位置。  %CD% 本地 返回当前目录字符串。  %CMDCMDLINE% 本地 返回用来启动当前的 Cmd.exe 的准确命令行。  %CMDEXTVERSION% 系统 返回当前的“命令处理程序扩展”的版本号。  %COMPUTERNAME%  系统 返回计算机的名称。  %COMSPEC%  系统 返回命令行解释器可执行程序的准确路径。  %DATE%  系统 返回当前日期。使用与 date /t 命令相同的格式。由 Cmd.exe 生成。有关 date 命令的详细信息，请参阅 Date。  %ERRORLEVEL%  系统 返回上一条命令的错误代码。通常用非零值表示错误。  %HOMEDRIVE%  系统 返回连接到用户主目录的本地工作站驱动器号。基于主目录值而设置。用户主目录是在“本地用户和组”中指定的。  %HOMEPATH%  系统 返回用户主目录的完整路径。基于主目录值而设置。用户主目录是在“本地用户和组”中指定的。  %HOMESHARE%  系统 返回用户的共享主目录的网络路径。基于主目录值而设置。用户主目录是在“本地用户和组”中指定的。  %LOGONSERVER%  本地 返回验证当前登录会话的域控制器的名称。  %NUMBER_OF_PROCESSORS%  系统 指定安装在计算机上的处理器的数目。  %OS%  系统 返回操作系统名称。Windows 2000 显示其操作系统为 Windows_NT。  %PATH% 系统 指定可执行文件的搜索路径。  %PATHEXT% 系统 返回操作系统认为可执行的文件扩展名的列表。  %PROCESSOR_ARCHITECTURE%  系统 返回处理器的芯片体系结构。值：x86 或 IA64（基于 Itanium）。  %PROCESSOR_IDENTFIER% 系统 返回处理器说明。  %PROCESSOR_LEVEL%  系统 返回计算机上安装的处理器的型号。  %PROCESSOR_REVISION% 系统 返回处理器的版本号。  %PROMPT% 本地 返回当前解释程序的命令提示符设置。由 Cmd.exe 生成。  %RANDOM% 系统 返回 0 到 32767 之间的任意十进制数字。由 Cmd.exe 生成。  %SYSTEMDRIVE% 系统 返回包含 Windows server operating system 根目录（即系统根目录）的驱动器。  %SYSTEMROOT%  系统 返回 Windows server operating system 根目录的位置。  %TEMP% 和 %TMP% 系统和用户 返回对当前登录用户可用的应用程序所使用的默认临时目录。有些应用程序需要 TEMP，而其他应用程序则需要 TMP。  %TIME% 系统 返回当前时间。使用与 time /t 命令相同的格式。由 Cmd.exe 生成。有关 time 命令的详细信息，请参阅 Time。  %USERDOMAIN% 本地 返回包含用户帐户的域的名称。  %USERNAME% 本地 返回当前登录的用户的名称。  %USERPROFILE% 本地 返回当前用户的配置文件的位置。  %WINDIR% 系统 返回操作系统目录的位置。   设置环境变量 使用 set 命令创建、更改、删除或显示环境变量。set 命令只更改当前解释器环境中的变量。  要查看变量，请在命令提示符下键入：  set VariableName  要添加变量，请在命令提示符下键入：  set variablename=Value  要删除变量，请在命令提示符下键入：  set VariableName=  可以将大多数字符用作变量值，其中包括空格。如果使用特殊字符 <、>、|、& 或 ^，则必须在它们前面加上转义字符 (^) 或引号。如果使用引号，则必须将引号作为值的组成部分，因为等号后面的任何内容都会被视为值。请考虑下列示例：  要创建变量值 new&name，请键入：  set varname=new^&name  要创建变量值 "new&name"，请键入：  set varname="new&name"  如果在命令提示符下键入 set varname=new&name，就会出现与下面内容类似的错误消息：  “'name' 不是内部或外部文件，也不是可运行的程序或批处理文件。” 变量名不区分大小写。但是，set 显示的变量与您键入的完全相同。可以在变量名中结合使用大写字母和小写字母，这样可以使代码更具有可读性（例如，UserName）。   注意  单个环境变量的最大大小为 8192 字节。  所有环境变量的大小总和（包括变量名和等号）最大为 65,536 KB。  替换环境变量值 要在命令行或脚本中启用变量值替换，请将变量名包括在百分号之中（即，%VariableName%）。使用百分号可以确保 Cmd.exe 引用变量值，而不是进行文字比较。为变量名定义变量值之后，请将变量名包括在百分号之中。Cmd.exe 搜索该变量名的所有实例，并用定义的变量值进行替换。例如，如果创建包含不同值（例如，用户名）的脚本，并且想要用这些值为每个用户定义 USERNAME 环境变量，可以使用包括在百分号之中的 USERNAME 来编写代码。运行此脚本时，Cmd.exe 将用变量值替换 %USERNAME%，这样就消除了为每个用户手动执行此任务的必要。变量替换是不可递归的。Cmd.exe 检查变量一次。有关变量替换的详细信息，请参阅 For 和 Call。

用system的话，由于输出缓冲的缘故，你无法预期printf和whoami的打印顺序，直接用getenv获取用户名吧。  引用 楼主 soul376 的回复:小弟最近在写一个command line界面，想要得到以下效果(我的运行环境是Mac/Unix)  "Welcome, 用户名  用户名@Function>"  我是这样处理的：   printf("Welcome,") system("whoami"); ... system("echo -n `whoami`"); printf("@Function>");    结果运行结果不如预期， 首先，第一个 system("whoami");指令一定会在printf("Welcome,")之前被先执行， 得到不想要的效果： "用户名" "Welcome,"  其次，第二个 system("echo -n `whoami`"); 问题更大，也得到了不想要的效果： “-n 用户名” “@Function>”   请问各位大大们，有没有办法能把`whoami`这个指令最后打印出来的string赋值给以个变量啊， 然后我在后期的时候再将这个变量放入printf中正常打印？  或者说还有木有其他的解决方案呢？  PS： whoami 这个指令貌似unix 和 windows 下都有， 但是echo没有 (因为执行了whoami会自动换行，我纯粹是为了不要那个换行符，才被迫使用的echo。。。。) 有木有更好的解决方案呢？  THANKS INDEED

你用getenv直接获取用户名，不是更好？


Question: C语言求幂运算非得那么反人类么？

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

引用 65 楼 zhao4zhong1 的回复:算符优先级那是词法分析和表达式树所能解决的问题。 //将A^B        替换为pow(A,B) //将A^(bbb)    替换为pow(A,bbb) //将(aaa)^B    替换为pow(aaa,B) //将(aaa)^(bbb)替换为pow(aaa,bbb) //将(A^B)^(a^b)替换为pow(pow(A,B),pow(a,b)) //将(a^(A^B))^b替换为pow(pow(a,pow(A,B)),b) //将a^((A^B)^b)替换为pow(a,pow(pow(A,B),b)) //依此类推  哈，终于有人回复了。  问题是转化后要能用，就必须要考虑算符优先级和语法树这些。  perl版本： [code=perl]#!/usr/bin/perl my $levelN = qr/ (?> [^()]+ | \( [^\(|\)]* (??{ $levelN }) [^\(|\)]* \) )* /x; while (<STDIN>) {   (/\^/) while     s/(\w*\.*\w+|[pow]*\($levelN\))\s*\^\s*([pow]*\($levelN\)|\w+\.*\w*)/pow($1,$2)/;   print "$_"; }

引用 63 楼 felonwan 的回复:zhao大神的程序能比较好的处理“^”嵌套。只有些小毛病，比如这个： (10.000+(200.0*c)^(10.0+c))^B ==> pow(pow(10.000+200.0*c,10.0+c),B)  我的perl脚本相比之下差多了：没考虑嵌套的问题，虽然也能做一点嵌套，仅限于四种不同类型之间的嵌套，同种类型的嵌套会出错。 算符优先级那是词法分析和表达式树所能解决的问题。 //将A^B        替换为pow(A,B) //将A^(bbb)    替换为pow(A,bbb) //将(aaa)^B    替换为pow(aaa,B) //将(aaa)^(bbb)替换为pow(aaa,bbb) //将(A^B)^(a^b)替换为pow(pow(A,B),pow(a,b)) //将(a^(A^B))^b替换为pow(pow(a,pow(A,B)),b) //将a^((A^B)^b)替换为pow(a,pow(pow(A,B),b)) //依此类推 #pragma warning(disable:4018) #include <stdio.h> #include <string.h> char s[100]; char t[100]; int topow(char *p,int n) {//对p开始，长度n的内容进行替换     int i,j,k,m;     //形如"xxxxx"且xxxxx中不含^且不以(开头,原样返回     if (p[0]!='(') {         for (i=0;i<n;i++) if (p[i]=='^') break;         if (i>=n) {             strcpy(t,s);             if (p==s && n==strlen(s)) return 1;             else return 0;         }     } else if (p[n-1]==')') {//形如"(xxxxx)"且xxxxx中不含^,替换为"xxxxx",返回         for (i=1;i<n-1;i++) if (p[i]=='^') break;         if (i>=n-1) {             sprintf(t,"%.*s%.*s%s",p-s,s,n-2,p+1,p+n);             if (p==s && n==strlen(s)) return 1;             else return 0;         } else {//形如"(xxx^yyy)"且xxx和yyy中都不含^和(，替换为"pow[xxx,yyy]",返回             k=0;             for (i=1;i<n-1;i++) {                 if (p[i]=='^') {                     k++;                     if (k==1) j=i;                 }             }             if (k==1) {                 for (i=1;i<j;i++) if (p[i]=='(') break;                 if (i>=j) {                     for (i=j+1;i<n-1;i++) if (p[i]=='(') break;                     if (i>=n-1) {                         sprintf(t,"%.*spow[%.*s,%.*s]%s",p-s,s,j-1,p+1,n-j-2,p+j+1,p+n);                         if (p==s && n==strlen(s)) return 1;                         else return 0;                     }                 }             }         }     }     //形如"xxx^yyy"且xxx和yyy中都不含^和(，替换为"pow[xxx,yyy]",返回     k=0;     for (i=0;i<n;i++) {         if (p[i]=='^') {             k++;             if (k==1) j=i;         }     }     if (k==1) {         for (i=0;i<j;i++) if (p[i]=='(') break;         if (i>=j) {             for (i=j+1;i<n;i++) if (p[i]=='(') break;             if (i>=n) {                 sprintf(t,"%.*spow[%.*s,%.*s]%s",p-s,s,j,p,n-j-1,p+j+1,p+n);                 if (p==s && n==strlen(s)) return 1;                 else return 0;             }         }     }     //形如"wwwww"且wwwww中含≥2个^,按()层次从内到外逐层递归调用topow直到topow返回1     while (1) {         m=0;         k=0;         for (i=0;i<n;i++) {             if (p[i]=='(') {                 k++;                 if (k>m) m=k;             }             if (p[i]==')') {                 k--;             }         }         if (m==0) break;// //没有(),返回         k=0;         for (i=0;i<n;i++) {             if (p[i]=='(') {                 k++;                 if (k==m) j=i;             }             if (p[i]==')') {                 if (k==m) {                     k=i;                     break;//                 }                 k--;             }         }         topow(p+j,k-j+1);         strcpy(s,t);         if (1==topow(s,strlen(s))) break;//     }     return 1; } void chg() {//将[替换为(,]替换为)     int i,L;     char c;      L=strlen(t);     for (i=0;i<L;i++) {         c=t[i];         if (c=='[') c='(';         if (c==']') c=')';         s[i]=c;     } } int main() {     strcpy(s,"A^B");        printf("%s ==> ",s);topow(s,strlen(s));chg();printf("%s\n",s);     strcpy(s,"A^(bbb)");    printf("%s ==> ",s);topow(s,strlen(s));chg();printf("%s\n",s);     strcpy(s,"(aaa)^B");    printf("%s ==> ",s);topow(s,strlen(s));chg();printf("%s\n",s);     strcpy(s,"(aaa)^(bbb)");printf("%s ==> ",s);topow(s,strlen(s));chg();printf("%s\n",s);     strcpy(s,"(A^B)^(a^b)");printf("%s ==> ",s);topow(s,strlen(s));chg();printf("%s\n",s);     strcpy(s,"(a^(A^B))^b");printf("%s ==> ",s);topow(s,strlen(s));chg();printf("%s\n",s);     strcpy(s,"a^((A^B)^b)");printf("%s ==> ",s);topow(s,strlen(s));chg();printf("%s\n",s);     strcpy(s,"(10.000+(200.0*c)^(10.0+c))^B");printf("%s ==> ",s);topow(s,strlen(s));chg();printf("%s\n",s);     strcpy(s,"(10.000+((200.0*c)^(10.0+c)))^B");printf("%s ==> ",s);topow(s,strlen(s));chg();printf("%s\n",s);     return 0; } //A^B ==> pow(A,B) //A^(bbb) ==> pow(A,bbb) //(aaa)^B ==> pow(aaa,B) //(aaa)^(bbb) ==> pow(aaa,bbb) //(A^B)^(a^b) ==> pow(pow(A,B),pow(a,b)) //(a^(A^B))^b ==> pow(pow(a,pow(A,B)),b) //a^((A^B)^b) ==> pow(a,pow(pow(A,B),b)) //(10.000+(200.0*c)^(10.0+c))^B ==> pow(pow(10.000+200.0*c,10.0+c),B) //(10.000+((200.0*c)^(10.0+c)))^B ==> pow(10.000+pow(200.0*c,10.0+c),B) //

好了，下面这个基本完美，期待大家的检验。 小缺点：括号不能去掉；代码里面4种不同类型的代码顺序不能变（不熟悉正则表达式，凑合用，高手可能能简化吧）。   #!/usr/bin/perl  # dynamic regexp my $levelN; $levelN = qr/ (?> [^()]+ | \( (??{ $levelN }) \) )* /x;  while(<STDIN>){ my $line=$_; my $line1=$line; while(1){ 	$line1=~ s/(\($levelN\))\s*\^\s*(\($levelN\))/pow($1,$2)/g; #(a+b)^(c+d) 	if("$line1" eq "$line"){last;} 	$line=$line1; } while(1){ 	$line1=~ s/(\w*\.*\w*)\s*\^\s*(\($levelN\))/pow($1,$2)/g; #a^(b+c) 	if("$line1" eq "$line"){last;} 	$line=$line1; } while(1){ 	$line1=~ s/(\($levelN\))\s*\^\s*(\w*\.*\w*)/pow($1,$2)/g; #(a+b)^c 	if("$line1" eq "$line"){last;} 	$line=$line1; } while(1){ 	$line1=~ s/(\w*\.*\w*)\s*\^\s*(\w*\.*\w)/pow($1,$2)/g; #a^b 	if("$line1" eq "$line"){last;} 	$line=$line1; } print "$line1" }

感谢上面的大神。 我自己写了个perl版本，第一次写perl，哈哈：  #!/usr/bin/perl  # copy file use File::Copy; use strict; my $file_new="@ARGV[0]c"; copy("@ARGV[0]",$file_new);  # dynamic regexp my $levelN; $levelN = qr/ (?> [^()]+ | \( (??{ $levelN }) \) )* /x;  # replacement open FH,$file_new; while(<FH>){ 	for my $line ($_) { 		$line=~ s/(\($levelN\))\s*\^\s*(\($levelN\))/pow($1,$2)/g; #(a+b)^(c+d) 		$line=~ s/(\w*\.*\w*)\s*\^\s*(\($levelN\))/pow($1,$2)/g; #a^(b+c) 		$line=~ s/(\($levelN\))\s*\^\s*(\w*\.*\w*)/pow($1,$2)/g; #(a+b)^c 		$line=~ s/(\w*\.*\w*)\s*\^\s*([^\(]\w*\.*\w)/pow($1,$2)/g; #a^b 		print $line; 	} } close FH;

这么空闲啊，过来给我做义工吧，可以做很多好玩的东西。  引用 58 楼 felonwan 的回复:[quote=引用 55 楼 xiyuyan 的回复:] 同时需要说明，C是低层语言，这么设计也是合理的。 C语言本身支持的基本都是比较简单的原始操作。 而幂属于复杂数学运算。  请教下： 按位异或“^”如果设计之初就用“$”，应该不会造成什么其它问题吧？[/quote]  引用 59 楼 zhao4zhong1 的回复:技痒难忍，挠挠！//将A^B        替换为pow(A,B) //将A^(bbb)    替换为pow(A,bbb) //将(aaa)^B    替换为pow(aaa,B) //将(aaa)^(bbb)替换为pow(aaa,bbb) //将(A^B)^(a^b)替换为pow(pow(A,B),pow(a,b)) //将(a^(A^B))^b替换为pow(pow(a,pow(A,B)),b) //将a^((A^B)^b)替换为pow(a,pow(pow(A,B),b)) //依此类推 #pragma warning(disable:4018) #include <stdio.h> #include <string.h> char s[100]; char t[100]; int topow(char *p,int n) {//对p开始，长度n的内容进行替换     int i,j,k,m;     //形如"xxxxx"且xxxxx中不含^且不以(开头,原样返回     if (p[0]!='(') {         for (i=0;i<n;i++) if (p[i]=='^') break;         if (i>=n) {             strcpy(t,s);             if (p==s && n==strlen(s)) return 1;             else return 0;         }     } else if (p[n-1]==')') {//形如"(xxxxx)"且xxxxx中不含^,替换为"xxxxx",返回         for (i=1;i<n-1;i++) if (p[i]=='^') break;         if (i>=n-1) {             sprintf(t,"%.*s%.*s%s",p-s,s,n-2,p+1,p+n);             if (p==s && n==strlen(s)) return 1;             else return 0;         } else {//形如"(xxx^yyy)"且xxx和yyy中都不含^和(，替换为"pow[xxx,yyy]",返回             k=0;             for (i=1;i<n-1;i++) {                 if (p[i]=='^') {                     k++;                     if (k==1) j=i;                 }             }             if (k==1) {                 for (i=1;i<j;i++) if (p[i]=='(') break;                 if (i>=j) {                     for (i=j+1;i<n-1;i++) if (p[i]=='(') break;                     if (i>=n-1) {                         sprintf(t,"%.*spow[%.*s,%.*s]%s",p-s,s,j-1,p+1,n-j-2,p+j+1,p+n);                         if (p==s && n==strlen(s)) return 1;                         else return 0;                     }                 }             }         }     }     //形如"xxx^yyy"且xxx和yyy中都不含^和(，替换为"pow[xxx,yyy]",返回     k=0;     for (i=0;i<n;i++) {         if (p[i]=='^') {             k++;             if (k==1) j=i;         }     }     if (k==1) {         for (i=0;i<j;i++) if (p[i]=='(') break;         if (i>=j) {             for (i=j+1;i<n;i++) if (p[i]=='(') break;             if (i>=n) {                 sprintf(t,"%.*spow[%.*s,%.*s]%s",p-s,s,j,p,n-j-1,p+j+1,p+n);                 if (p==s && n==strlen(s)) return 1;                 else return 0;             }         }     }     //形如"wwwww"且wwwww中含≥2个^,按()层次从内到外逐层递归调用topow直到topow返回1     while (1) {         m=0;         k=0;         for (i=0;i<n;i++) {             if (p[i]=='(') {                 k++;                 if (k>m) m=k;             }             if (p[i]==')') {                 k--;             }         }         if (m==0) break;// //没有(),返回         k=0;         for (i=0;i<n;i++) {             if (p[i]=='(') {                 k++;                 if (k==m) j=i;             }             if (p[i]==')') {                 if (k==m) {                     k=i;                     break;//                 }                 k--;             }         }         topow(p+j,k-j+1);         strcpy(s,t);         if (1==topow(s,strlen(s))) break;//     }     return 1; } void chg() {//将[替换为(,]替换为)     int i,L;     char c;      L=strlen(t);     for (i=0;i<L;i++) {         c=t[i];         if (c=='[') c='(';         if (c==']') c=')';         s[i]=c;     } } int main() {     strcpy(s,"A^B");        printf("%s ==> ",s);topow(s,strlen(s));chg();printf("%s\n",s);     strcpy(s,"A^(bbb)");    printf("%s ==> ",s);topow(s,strlen(s));chg();printf("%s\n",s);     strcpy(s,"(aaa)^B");    printf("%s ==> ",s);topow(s,strlen(s));chg();printf("%s\n",s);     strcpy(s,"(aaa)^(bbb)");printf("%s ==> ",s);topow(s,strlen(s));chg();printf("%s\n",s);     strcpy(s,"(A^B)^(a^b)");printf("%s ==> ",s);topow(s,strlen(s));chg();printf("%s\n",s);     strcpy(s,"(a^(A^B))^b");printf("%s ==> ",s);topow(s,strlen(s));chg();printf("%s\n",s);     strcpy(s,"a^((A^B)^b)");printf("%s ==> ",s);topow(s,strlen(s));chg();printf("%s\n",s);     return 0; } //A^B ==> pow(A,B) //A^(bbb) ==> pow(A,bbb) //(aaa)^B ==> pow(aaa,B) //(aaa)^(bbb) ==> pow(aaa,bbb) //(A^B)^(a^b) ==> pow(pow(A,B),pow(a,b)) //(a^(A^B))^b ==> pow(pow(a,pow(A,B)),b) //a^((A^B)^b) ==> pow(a,pow(pow(A,B),b)) //

引用 57 楼 felonwan 的回复:[quote=引用 55 楼 xiyuyan 的回复:] 唉，这用争论吗？ 改不小菜一碟。 出100元辛苦费我给你改个。  同时需要说明，C是低层语言，这么设计也是合理的。 C语言本身支持的基本都是比较简单的原始操作。 而幂属于复杂数学运算。  但是，但是，世上无难事，就怕你能力不够又囊中羞涩！  最后，推荐尝试下： 习语言， 最完美的 C语言， 可以随意改变。  哈哈，您是说预处理上面改是吧，自己也能改，只是觉得光为改这个玩意花那么多时间和精力得不偿失，谢谢了。  比如说，自己简单写了几个sed： echo "d+ ((a*c)+b)^(a-b)*e" | sed 's/\([\* + - \/]\)\((.*)\)\^\((.*)\)\([ \* + - \/]\)/\1pow(\2,\3)\4/g' echo "10.011^20" | sed 's/\([a-z A-Z 0-9]\{1,\}\)\.\([a-z A-Z 0-9]\{1,\}\)\^\([a-z A-Z 0-9]\{1,\}\)/pow(\1.\2,\3)/g'[/quote]  看你的代码真心累，不清楚有几个人喜欢读你这个代码，反正我是不会看的。 我说好改是因为我有自己的编译器：习语言。 可以随意修改语法和实现。 修改语法定义及实现很容易。  当然在现有处理器，前置一个预处理动作，也是可以的。 总体不推荐，不能兼容的改变不如不改变，  中文符号库大的很，很多漂亮符号，干嘛非要吊死在几个英文符号上呢？

引用 44 楼 felonwan 的回复:[quote=引用 43 楼 zhao4zhong1 的回复:] 完全可以自己写一小段C语言程序，将命令行指定的C/C++源代码文件中的 A^B自动替换为pow(A,B) A^(…)自动替换为pow(A,…) (...)^B自动替换为pow(...,B) (...)^(…)自动替换为pow(...,…)   其实linux下直接用sed处理一下也可以吧。[/quote] 你原来不笨啊！

引用 55 楼 xiyuyan 的回复:同时需要说明，C是低层语言，这么设计也是合理的。 C语言本身支持的基本都是比较简单的原始操作。 而幂属于复杂数学运算。  请教下： 按位异或“^”如果设计之初就用“$”，应该不会造成什么其它问题吧？

引用 55 楼 xiyuyan 的回复:唉，这用争论吗？ 改不小菜一碟。 出100元辛苦费我给你改个。  同时需要说明，C是低层语言，这么设计也是合理的。 C语言本身支持的基本都是比较简单的原始操作。 而幂属于复杂数学运算。  但是，但是，世上无难事，就怕你能力不够又囊中羞涩！  最后，推荐尝试下： 习语言， 最完美的 C语言， 可以随意改变。  哈哈，您是说预处理上面改是吧，自己也能改，只是觉得光为改这个玩意花那么多时间和精力得不偿失，谢谢了。  比如说，自己简单写了几个sed： echo "d+ ((a*c)+b)^(a-b)*e" | sed 's/\([\* + - \/]\)\((.*)\)\^\((.*)\)\([ \* + - \/]\)/\1pow(\2,\3)\4/g' echo "10.011^20" | sed 's/\([a-z A-Z 0-9]\{1,\}\)\.\([a-z A-Z 0-9]\{1,\}\)\^\([a-z A-Z 0-9]\{1,\}\)/pow(\1.\2,\3)/g'

引用 53 楼 zhao4zhong1 的回复:不要做A语言代码修改为B语言代码的无用功。 也不要做用A语言代码直接调用B语言代码库这样复杂、这样容易出错的傻事。 只需让A、B语言代码的输入输出重定向到文本文件，或修改A、B语言代码让其通过文本文件输入输出。 即可很方便地让A、B两种语言之间协调工作。   赵老师，你邮箱发邮件了，但是没回复。我qq：9301462    c++ 源码修改

引用 53 楼 zhao4zhong1 的回复:不要做A语言代码修改为B语言代码的无用功。 也不要做用A语言代码直接调用B语言代码库这样复杂、这样容易出错的傻事。 只需让A、B语言代码的输入输出重定向到文本文件，或修改A、B语言代码让其通过文本文件输入输出。 即可很方便地让A、B两种语言之间协调工作。  确实。 搞过C中用matlab库画图，麻烦。 还是直接输出数据再用matlab画省事。

引用 51 楼 zhao4zhong1 的回复:[quote=引用 50 楼 felonwan 的回复:] [quote=引用 49 楼 zhao4zhong1 的回复:] 调侃容易写代码难。 Talk is cheap,show me the codes.——Linus Torvalds  用户调侃一下，提点建议还是可以的吧，改不改还是赵大师这样的大神说了算嘛。[/quote] gcc和g++源代码摆在那里，没人能够阻止你将它们分支为mygcc和myg++，将^重新定义为指数操作。[/quote]  之前还真有这样的想法，搞个为数值计算优化的C编译器，pow函数是一个小方面，我所知道的Fortran的动态数组和矩阵操作也可以引进来嘛。不过转念一想，这样的话，用C还有什么好处么？直接用Fortran不就完了。

引用 50 楼 felonwan 的回复:[quote=引用 49 楼 zhao4zhong1 的回复:] 调侃容易写代码难。 Talk is cheap,show me the codes.——Linus Torvalds  用户调侃一下，提点建议还是可以的吧，改不改还是赵大师这样的大神说了算嘛。[/quote] gcc和g++源代码摆在那里，没人能够阻止你将它们分支为mygcc和myg++，将^重新定义为指数操作。

引用 49 楼 zhao4zhong1 的回复:调侃容易写代码难。 Talk is cheap,show me the codes.——Linus Torvalds  用户调侃一下，提点建议还是可以的吧，改不改还是赵大师这样的大神说了算嘛。

引用 48 楼 felonwan 的回复:[quote=引用 47 楼 zhao4zhong1 的回复:] 写个完成将命令行指定的C/C++源代码文件中的 A^B自动替换为pow(A,B) A^(…)自动替换为pow(A,…) (...)^B自动替换为pow(...,B) (...)^(…)自动替换为pow(...,…)  功能的sed命令，贴到此帖，留给后人，估计会让你名垂青史！  这样伟大的功绩还是留给zhao大师吧，偶等小辈无此实力，只能“调侃”一下pow(x,n)函数反人类。 [/quote] 调侃容易写代码难。 Talk is cheap,show me the codes.——Linus Torvalds


Question: c指针问题

自己写代码搞不清楚算符优先级请多加括号。 看别人代码搞不清楚算符优先级能调试的话请单步调试对应汇编。 看别人代码搞不清楚算符优先级不能调试的话想办法照写一小段孤立的可调试的代码然后单步调试对应汇编。 看别人代码搞不清楚算符优先级不能调试的话且没有办法照写一小段孤立的可调试的代码然后单步调试对应汇编的话只能参考算符优先级表猜了（提醒：并不能100%猜对）。 //C++ Operators //  Operators specify an evaluation to be performed on one of the following: //    One operand (unary operator) //    Two operands (binary operator) //    Three operands (ternary operator) //  The C++ language includes all C operators and adds several new operators. //  Table 1.1 lists the operators available in Microsoft C++. //  Operators follow a strict precedence which defines the evaluation order of //expressions containing these operators.  Operators associate with either the //expression on their left or the expression on their right;    this is called //“associativity.” Operators in the same group have equal precedence and are //evaluated left to right in an expression unless explicitly forced by a pair of //parentheses, ( ). //  Table 1.1 shows the precedence and associativity of C++ operators //  (from highest to lowest precedence). // //Table 1.1   C++ Operator Precedence and Associativity // The highest precedence level is at the top of the table. //+------------------+-----------------------------------------+---------------+ //| Operator         | Name or Meaning                         | Associativity | //+------------------+-----------------------------------------+---------------+ //| ::               | Scope resolution                        | None          | //| ::               | Global                                  | None          | //| [ ]              | Array subscript                         | Left to right | //| ( )              | Function call                           | Left to right | //| ( )              | Conversion                              | None          | //| .                | Member selection (object)               | Left to right | //| ->               | Member selection (pointer)              | Left to right | //| ++               | Postfix increment                       | None          | //| --               | Postfix decrement                       | None          | //| new              | Allocate object                         | None          | //| delete           | Deallocate object                       | None          | //| delete[ ]        | Deallocate object                       | None          | //| ++               | Prefix increment                        | None          | //| --               | Prefix decrement                        | None          | //| *                | Dereference                             | None          | //| &                | Address-of                              | None          | //| +                | Unary plus                              | None          | //| -                | Arithmetic negation (unary)             | None          | //| !                | Logical NOT                             | None          | //| ~                | Bitwise complement                      | None          | //| sizeof           | Size of object                          | None          | //| sizeof ( )       | Size of type                            | None          | //| typeid( )        | type name                               | None          | //| (type)           | Type cast (conversion)                  | Right to left | //| const_cast       | Type cast (conversion)                  | None          | //| dynamic_cast     | Type cast (conversion)                  | None          | //| reinterpret_cast | Type cast (conversion)                  | None          | //| static_cast      | Type cast (conversion)                  | None          | //| .*               | Apply pointer to class member (objects) | Left to right | //| ->*              | Dereference pointer to class member     | Left to right | //| *                | Multiplication                          | Left to right | //| /                | Division                                | Left to right | //| %                | Remainder (modulus)                     | Left to right | //| +                | Addition                                | Left to right | //| -                | Subtraction                             | Left to right | //| <<               | Left shift                              | Left to right | //| >>               | Right shift                             | Left to right | //| <                | Less than                               | Left to right | //| >                | Greater than                            | Left to right | //| <=               | Less than or equal to                   | Left to right | //| >=               | Greater than or equal to                | Left to right | //| ==               | Equality                                | Left to right | //| !=               | Inequality                              | Left to right | //| &                | Bitwise AND                             | Left to right | //| ^                | Bitwise exclusive OR                    | Left to right | //| |                | Bitwise OR                              | Left to right | //| &&               | Logical AND                             | Left to right | //| ||               | Logical OR                              | Left to right | //| e1?e2:e3         | Conditional                             | Right to left | //| =                | Assignment                              | Right to left | //| *=               | Multiplication assignment               | Right to left | //| /=               | Division assignment                     | Right to left | //| %=               | Modulus assignment                      | Right to left | //| +=               | Addition assignment                     | Right to left | //| -=               | Subtraction assignment                  | Right to left | //| <<=              | Left-shift assignment                   | Right to left | //| >>=              | Right-shift assignment                  | Right to left | //| &=               | Bitwise AND assignment                  | Right to left | //| |=               | Bitwise inclusive OR assignment         | Right to left | //| ^=               | Bitwise exclusive OR assignment         | Right to left | //| ,                | Comma                                   | Left to right | //+------------------+-----------------------------------------+---------------+

指针数组：     整数指针（指向整数的指针）的数组：       int *a[2];         // 分解动作：            a [2]  =====> a 是个一维数组，元素共2个            *a[2]  =====> 再与*结合，说明，元素类型是指针         int *a[2] =====> 再连接上“前置类型”，说明指针指向整数。  指针数组：       指向整数数组的指针：         int (*a) [2];          // 分解动作：              *a  =====> 说明a是一个一级指针             （*a）[2] ====> 说明指针指向一个数组，数组元素共2个          int （*a)[2] ====> 结合前置类型，指出此数组元素的类型是int

指针数组和数组指针应该分别怎么定义啊？ 引用 4 楼 sinservice 的回复:加括号是为了改变默认结合关系，  *a []  a [] 先结合， 然后跟*结合。 就是说， *a[] =等价于= * (a[]) ，  但不等价于  (*a) [] ，在最后一种情况里，强制指定 *a 先结合，表示 a 是一个指针，指向 sometype的一维数组。  int * 不能结合，就是说， 你不能写 (int *) a[] ， 这样写显然就不是变量定义，而是强制类型转换了，C没有这种写法。  int * 为什么不能结合呢？   因为C的一个类型表示是两部分组成，一部分是前置类型，一个是对id的声明。  举例： 一个C变量声明语句为 int **i, (* f)();  我们如果标出冗余的括号就是：  int (**i), ((*f)());   并等价于 int **i; int (*f)();   前置类型，只能是typename，不能包括* [] ()等等。  当然有的编译器存在简单写法，如VC:  (int (*)()) a  将a强制转换为 “指向 返回整数的函数 的指针”，在这里，其实是省略了写一个id，依然不能将这个类型视作前置类型。

还要注意一点，就是const和volatile的结合问题。  const int 等价于 int const const int 等价于 int const *  前置类型可以向前结合N个const描述符，遇到 * id ( [ 就结束。

没有任何区别。

请看C语言基础


Question: 【新手提问..........A/D转换代码问题.......就是数字进制的问题....求轻拍】

直接乘除法处理； 如果觉得不够准确，作舍入处理一下即可。

signed short DACode,ADCode; unsigned char Dlsb,Dmsb; DACode=ADCode>>2; Dlsb=((unsigned char *)&DACode)[0]; Dmsb=((unsigned char *)&DACode)[1]; 试试看。


Question: 谁有基于OGRE图形引擎的雨雪天气模拟系统的设计与实现 ？

参考http://wap.cnki.net/lunwen-1012473867.html  引用 楼主 alexvanhy 的回复:要完成一个基于OGRE图形引擎的雨雪天气模拟系统的设计与实现的课程设计，需要能实现的源代码，如果有文档说明更好，但是无从下手，想问下大家有没有好的介绍？有的话麻烦请发到邮箱250764889@qq.com！！感激不尽！给分100分！！！


自己结构体初始化的时候为什么不试试memcpy呢？ 引用 33 楼 chengkun183 的回复:结贴了：：：  IplImage *getGray(const IplImage *img) { /****************************************************** IplImage *gray=(IplImage *)malloc(sizeof(IplImage *)); IplImage *gray32=gray; gray32=(IplImage *)img; 1.sizeof()使用错误，应该改为sizeof(IplImage ) 	感谢2/4楼的“starytx,拾瓦星哥”指出该错误;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> 	感谢7楼的“adeng1919,懒懒的吉他手”给出提醒.>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> 2.指针指向错误，首先指到分配的内存空间，然后又将指针指向const IplImage *img，并在后面的操作试图修改指针内容     感谢6/9/17/20/21/23/24的“xihu1364,版主大哥”指出错误，并提出解决方案以及告诫。>>> 	感谢10楼的“starytx,拾瓦星哥”描述。>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> 	感谢30楼的“jianwen0529，jianwen0529”指出该错误。>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> 	感谢31楼的“terhack，terhack”的提醒。>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> *******************************************************/ //直接修改为：：： IplImage *gray32=(IplImage *)malloc(sizeof(IplImage));  int i=0,j=0; int c=0; /****************************************************** int width=gray32->width; int heigh=gray32->height; int step=gray32->widthStep; int nchan=gray32->nChannels; float *data=(float*)gray32->imageData; 3.未对结构体成员指针分配内存空间 	感谢25/26/28楼的“bijiaoben，大奶兔白糖”指出该错误，以及提供解决方案。 *******************************************************/ //修改为：：： int width=img->width; int heigh=img->height; int step=img->widthStep; int nchan=img->nChannels; float *data=(float*)gray32->imageData; data=(float *)malloc(sizeof(float)*width*heigh); char * dat=img->imageData;  for (i=0;i<heigh;i++) { 	for (j=0;j<width;j++) 	{ 		if(nchan==3) 			data[i*step+j]=(dat[i*step+j*nchan]+dat[i*step+j*nchan+1]+dat[i*step+j*nchan+2])/765.0; 		else 		{ 			data[i*step+j]=(dat[i*step+j])/255.0f; 		//	printf("i=%d,j=%d,c=%d\n",i,j,c++); 		} 	} } //free(gray) //不再次使用 return gray32; } //这样修改可以保证这段代码可以运行，数据是不完整的， //因此IplImage数据结构内的很多成员参数都需要初始化， //不然得出的结果后面的程序是不能使用的， //只针对这段代码的本身的错误进行修改。 //另外感谢全楼成员的指导和帮助  /***************************警戒线*******以示自己对整个结构，指针的不了解**********************************/ //另外我也修改了一份把IplImage数据结构内的重要成员初始化的代码，后面的程序可以使用 IplImage *getGray(const IplImage *img) { 	IplImage *gray32=0; 	gray32=(IplImage *)malloc(sizeof(*gray32)); 	memset( gray32, 0, sizeof( *gray32 )); 	gray32->nSize=sizeof( *gray32 ); 	gray32->height=img->height; 	gray32->width=img->width; 	gray32->align=4; 	gray32->nChannels = 1; 	gray32->widthStep = 3200; 	gray32->imageSize=gray32->widthStep*gray32->height; 	gray32->origin=0; 	 	int i=0,j=0; 	int height = img->height; 	int width  = img->width; 	int step   = img->widthStep/sizeof(float); 	int nchan  = img->nChannels; 	float * data=(float*)malloc(sizeof(float)*width*height); 	gray32->imageData =(char*) data; 	char * dat = img->imageData;	   	for (i=0;i<height;i++) 		{ 			for (j=0;j<width;j++) 			{ 				if(nchan==3) 					data[i*step+j]=(float)(dat[i*step+j*nchan]+dat[i*step+j*nchan+1]+dat[i*step+j*nchan+2])/765.0f; 				else 					data[i*step+j]=(float)(dat[i*step+j])/255.0f;  			} 			 		}         return gray32; } /*************************************************************************************/

肯定指针指向错误地方了

gray32=(IplImage *)img; //这句屏蔽掉看看

引用 22 楼 chengkun183 的回复:[quote=引用 18 楼 xihu1364 的回复:] 发现提问题的...都是这么被动，根本不动脑子... IplImage *getGray(const IplImage *img) { 	IplImage *gray32=(IplImage *)malloc(sizeof(IplImage));  	memcpy(gray32,img,sizeof(IplImage));     int i=0,j=0;     int	c=0; 	int width=gray32->width; 	int heigh=gray32->height; 	int step=gray32->widthStep; 	int nchan=gray32->nChannels; 	float *data=(float*)gray32->imageData; 	float *data2=(float*)img->imageData; 	 	for (i=0;i<heigh;i++) 	{ 		for (j=0;j<width;j++) 		{ 			if(nchan==3) 				data[i*step+j]=(data2[i*step+j*nchan]+data2[i*step+j*nchan+1]+data2[i*step+j*nchan+2])/765.0; 			else 			{ 				data[i*step+j]=(data2[i*step+j])/255.0f; 				printf("i=%d,j=%d,c=%d\n",i,j,c++); 			} 		} 	} 	return gray32; } 修改成这样，错误依旧。[/quote] 你不要老是盯着错误，你得看怎么错了，去找问题，不是可以调试吗？  还有，一些基础知识你得在问题中去积累经验吧，这个才是重点吧.上面我就说了出问题的地方，自己去研究下。感觉你就是把代码贴上，问题提出来，就靠人家帮你弄好....

引用 18 楼 xihu1364 的回复:发现提问题的...都是这么被动，根本不动脑子... IplImage *getGray(const IplImage *img) { 	IplImage *gray32=(IplImage *)malloc(sizeof(IplImage));  	memcpy(gray32,img,sizeof(IplImage));     int i=0,j=0;     int	c=0; 	int width=gray32->width; 	int heigh=gray32->height; 	int step=gray32->widthStep; 	int nchan=gray32->nChannels; 	float *data=(float*)gray32->imageData; 	float *data2=(float*)img->imageData; 	 	for (i=0;i<heigh;i++) 	{ 		for (j=0;j<width;j++) 		{ 			if(nchan==3) 				data[i*step+j]=(data2[i*step+j*nchan]+data2[i*step+j*nchan+1]+data2[i*step+j*nchan+2])/765.0; 			else 			{ 				data[i*step+j]=(data2[i*step+j])/255.0f; 				printf("i=%d,j=%d,c=%d\n",i,j,c++); 			} 		} 	} 	return gray32; } 修改成这样，错误依旧。

还有 int imageSize;  //这应该是下面指针内容的大小    char *imageData;  //你上面贴的代码很有问题....

引用 19 楼 chengkun183 的回复:[quote=引用 15 楼 xihu1364 的回复:] 你把结构体IplImage定义贴出来？ 结构体typedef struct _IplImage { 	int nSize;                     	int ID;                          	int nChannels;            	int alphaChannel;  	int depth;  	char colorModel[4];  	char channelSeq[4];  	int dataOrder;  	int origin;  	int align;  	int width;  	int height; 	struct _IplROI *roi; 	struct _IplImage *maskROI;  	void *imageId;  	struct _IplTileInfo *tileInfo;  	int imageSize;  	char *imageData;  	int widthStep;  	int BorderMode[4];  	int BorderConst[4];  	char *imageDataOrigin;  }IplImage;[/quote] imageData这个是变长啊.... 楼主，出问题的地方，我估计是越界了.  首先，分少了，哈哈！ 其次，你分配内存的时候，应该以nSize（应该用这个结构体的大小）去分配内存。用sizeof（IplImage）前提是，该结构体是定长.

引用 15 楼 xihu1364 的回复:你把结构体IplImage定义贴出来？ 结构体typedef struct _IplImage { 	int nSize;                     	int ID;                          	int nChannels;            	int alphaChannel;  	int depth;  	char colorModel[4];  	char channelSeq[4];  	int dataOrder;  	int origin;  	int align;  	int width;  	int height; 	struct _IplROI *roi; 	struct _IplImage *maskROI;  	void *imageId;  	struct _IplTileInfo *tileInfo;  	int imageSize;  	char *imageData;  	int widthStep;  	int BorderMode[4];  	int BorderConst[4];  	char *imageDataOrigin;  }IplImage;

发现提问题的...都是这么被动，根本不动脑子...

引用 16 楼 chengkun183 的回复:[quote=引用 10 楼 starytx 的回复:] 确实是指针指向分配的空间了，但是后来却又指向形参的指向了，指针误用 如何能指向分配空间，又能使用形参呢？[/quote] IplImage *gray=(IplImage *)malloc(sizeof(IplImage));   memcpy(gray,img,sizeof(IplImage)); 这句话不就是吗？

引用 10 楼 starytx 的回复:确实是指针指向分配的空间了，但是后来却又指向形参的指向了，指针误用 如何能指向分配空间，又能使用形参呢？

你把结构体IplImage定义贴出来？

引用 6 楼 xihu1364 的回复:IplImage *gray=(IplImage *)malloc(sizeof(IplImage *));     IplImage *gray32=gray;     gray32=(IplImage *)img; 这里，你malloc有啥用？  修改1方案： IplImage *gray=(IplImage *)malloc(sizeof(IplImage));  memcpy(gray,img,sizeof(IplImage)); //还有你return一个IplImage *指针，那么你就别free了，free了你return有啥用？  第二个： 就用new，看IplImage类，有重载=运算符不，直接=过来....  我这样来： 	IplImage *gray=(IplImage *)malloc(sizeof(IplImage));  	memcpy(gray,img,sizeof(IplImage)); 	IplImage *gray32=gray; ：：： //free(gray);//注释掉 错误依然

引用 6 楼 xihu1364 的回复:IplImage *gray=(IplImage *)malloc(sizeof(IplImage *));     IplImage *gray32=gray;     gray32=(IplImage *)img; 这里，你malloc有啥用？  修改1方案： IplImage *gray=(IplImage *)malloc(sizeof(IplImage));  memcpy(gray,img,sizeof(IplImage)); //还有你return一个IplImage *指针，那么你就别free了，free了你return有啥用？  第二个： 就用new，看IplImage类，有重载=运算符不，直接=过来.... 木有无视，正在测试……

...回复内容，被LZ无视....

引用 7 楼 adeng1919 的回复:IplImage *gray=(IplImage *)malloc(sizeof(IplImage *)); 内存没被分配到足够大  改为：IplImage *gray=(IplImage *)malloc(sizeof(IplImage*)*img->width*img->height); 错误依然是不能read,

确实是指针指向分配的空间了，但是后来却又指向形参的指向了，指针误用

试图修改静态数据img->imageData;  float *data=(float*)gray32->imageData; 因为是指针，所以data指向的一直都是img->imageData的内存块 本来是静态的数据，你data[]试图修改之，所以不能报错！

不知道你理解到你出错的地方没有？  出错原因就是你申请的内存根本就没用，而是用的const IplImage *img，这个是const，你就修改，肯定出错


Question: mplayer播放在线视频时有没有办法得到下载速度与缓冲比率？

大神们帮帮忙

自己每隔比如1秒记录已下载字节数和已播放字节数现算？


Question: C语言编写的简单计算器无法实现请帮忙检查一下

谢谢 我犯的都是低级错误 自己还没找出来

#include"stdio.h" int M(int a,int b);//先声明，或者将子函数写在前面 int S(int a,int b);//先声明，或者将子函数写在前面 int C(int a,int b);//先声明，或者将子函数写在前面 float D(int a,int b);//先声明，或者将子函数写在前面，除法用float。 int main() { int m,n; scanf("%d,%d",&m,&n);/scanf（）函数不要乱写/n;而且转行是\n printf("%d %d\n",m,n); printf("%d %d %d %f\n",M(m,n),S(m,n),C(m,n),D(m,n)); } int M(int a,int b) {  int A; A=a-b; return A; } int S(int a,int b) { int B; B=a+b; return B; } int C(int a,int b) { int C; C=a*b; return C; } float  D(int a, int b) { float D; D= (float)a/b; return D; }


Question: 浮点数陷阱

用10进制小数不能精确表示某些三进制小数0.1(3)=0.33333333333……(10) 同理，用二进制小数也不能精确表示某些10进制小数。 #include <stdio.h> #include <math.h> int main() {     double i;     for (i=0.0;fabs(i-10.0)>0.01;i+=0.1)         printf("%.1lf\n",i);     return 0; }

你在调试窗口里看看不就知道了，真想把赵老师那段话搬过来

浮点数的比较是用<和>进行比较的，不能用等于号和不等于

运行结果就是无限循环，无限输出。原因是浮点数不能这么用，浮点数都是以二进制放入内存，这样不可控；还是用整数比较好。


Question: 显示错误说bool为不明确类型~~个人怀疑编译器的问题~~求指教~~

bool是C++才有的吧

就是编译器的问题，换成int不行么，。

自己define一个呗

C本来就没有bool。

#include <stdbool.h>

c本来就没有bool和true false  可以定义：  typedef char bool;  #define true 1 #define false 0  c其实也没有inline,  #define inline _inline

扩展名.c改成.cpp，如果还不行扔掉这个**编译器。

换个环境试下呗！可能当前环境不支持bool类型的！ 或者bool类型换成int类型试下


Question: sqlite3 二进制数据

sqlite> .out tmp1.binary_dump sqlite> select img_data from user_info where user_id=25;

select img_data from user_info where user_id=25;这是sql语句。

引用 3 楼 user-1 的回复:sqlite> .out tmp1.binary_dump sqlite> select hex(img_data) from user_info where user_id=25;  Thank You！！！


Question: 浮点数的一点问题，求大神指教

have a try 	printf("%d %d %d %f\n",a,ft1,ft2);

浮点数有误差很正常。  引用 8 楼 wql13110518269 的回复:[quote=引用 3 楼 turingo 的回复:] printf格式不匹配时结果难料，int用%d，float用%f  [quote=引用 楼主 u010309436 的回复:] void main() { 	int a = 10; 	float ft1=12.253; 	float ft2=23.45;// 	printf("%d %d %f\n",a,ft1,ft2); }  输出结果为 将printf换成这样后 输出结果为： 菜鸟求大神指教···[/quote]  可是为什么后面的输出会是23.45001[/quote]

引用 3 楼 turingo 的回复:printf格式不匹配时结果难料，int用%d，float用%f  [quote=引用 楼主 u010309436 的回复:] void main() { 	int a = 10; 	float ft1=12.253; 	float ft2=23.45;// 	printf("%d %d %f\n",a,ft1,ft2); }  输出结果为 将printf换成这样后 输出结果为： 菜鸟求大神指教···[/quote]  可是为什么后面的输出会是23.45001

本人菜鸟  一本书上看到过这个问题... 第一个%d没有问题 第二个%d是打印四个字节 而ft1是八个字节  多出来的四个字节放到后面的 %f去了   所以 乱了  应该是这样的

printf("%按熊猫的格式输出",CSDN论坛的u010309436); 合理的输出应该是……？

printf格式不匹配时结果难料，int用%d，float用%f  引用 楼主 u010309436 的回复:void main() { 	int a = 10; 	float ft1=12.253; 	float ft2=23.45;// 	printf("%d %d %f\n",a,ft1,ft2); }  输出结果为 将printf换成这样后 输出结果为： 菜鸟求大神指教···

计算机组成原理→DOS命令→汇编语言→C语言（不包括C++）、代码书写规范→数据结构、编译原理、操作系统→计算机网络、数据库原理、正则表达式→其它语言（包括C++）、架构……  对学习编程者的忠告： 眼过千遍不如手过一遍！ 书看千行不如手敲一行！ 手敲千行不如单步一行！ 单步源代码千行不如单步对应汇编一行！  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++ Floating-Point Constants Floating-point constants specify values that must have a fractional part. These values contain decimal points (.) and can contain exponents.  Syntax  floating-constant :  fractional-constant exponent-partopt floating-suffixopt digit-sequence exponent-part floating-suffixopt  fractional-constant :  digit-sequenceopt . digit-sequence digit-sequence .  exponent-part :  e signopt digit-sequence E signopt digit-sequence  sign : one of  + –  digit-sequence :  digit digit-sequence digit  floating-suffix :one of  f l F L  Floating-point constants have a “mantissa,” which specifies the value of the number, an “exponent,” which specifies the magnitude of the number, and an optional suffix that specifies the constant’s type. The mantissa is specified as a sequence of digits followed by a period, followed by an optional sequence of digits representing the fractional part of the number. For example:  18.46 38.  The exponent, if present, specifies the magnitude of the number as a power of 10, as shown in the following example:  18.46e0      // 18.46 18.46e1      // 184.6  If an exponent is present, the trailing decimal point is unnecessary in whole numbers such as 18E0.  Floating-point constants default to type double. By using the suffixes f or l (or F or L — the suffix is not case sensitive), the constant can be specified as float or long double, respectively.  Although long double and double have the same representation, they are not the same type. For example, you can have overloaded functions like  void func( double );  and   void func( long double );

整型、浮点，存储格式不同。

不管是浮点数还是整形，他都是以二进制的形式放入内存中，只是你用printf输出的时候它按照你的格式也就是%d,%f输出，所以你这样输出结果是不好预测的。


Question: 提问！

这里对应的指针步长是4 不是1

代码中p用printf("%d",p)显示与a[0]的地址值的差是4，但是你写为p-a[0]其实他的值是1，所以每4个跳一次。你可以检验如下int b=p-a[0]；然后打印b看吧。p的地址是1310544，p+1地址应该是1310548.


Question: 递归函数 返回值的 问题。 求解释。

你不使用返回值，你的返回值就是多余的，当然就没用了。 PS: 你递归中，没有任何递归终止条件和返回值有关系。

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

说明没有执行那两个return语句啊，只是执行了return 0 单步调试跟踪看看


Question: malloc 问题 求解

计算机组成原理→DOS命令→汇编语言→C语言（不包括C++）、代码书写规范→数据结构、编译原理、操作系统→计算机网络、数据库原理、正则表达式→其它语言（包括C++）、架构……  对学习编程者的忠告： 眼过千遍不如手过一遍！ 书看千行不如手敲一行！ 手敲千行不如单步一行！ 单步源代码千行不如单步对应汇编一行！  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",...)】来理解指针的本质， 而要依赖调试时的反汇编窗口中的C/C++代码【比如void *p=...】及其对应汇编指令以及内存窗口中的内存地址和内存值来理解指针的本质。  这辈子不看内存地址和内存值；只画链表、指针示意图，画堆栈示意图，画各种示意图，甚至自己没画过而只看过书上的图……能从本质上理解指针、理解函数参数传递吗？本人深表怀疑！ 这辈子不种麦不收麦不将麦粒拿去磨面；只吃馒头、吃面条、吃面包、……甚至从没看过别人怎么蒸馒头，压面条，烤面包，……能从本质上理解面粉、理解面食吗？本人深表怀疑！！  提醒： “学习用汇编语言写程序” 和 “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

引用 2 楼 xihu1364 的回复:这样的题目，不是面试经常考的？ void fun_malloc2(char *str)调用的时候传进的参数是一个temp temp分配了但是实参还是没有分配...  用void fun_malloc2(char **str)  或者void fun_malloc2(char*& str)   谢谢，，，解决了，，，，但是搞不懂原理

引用 5 楼 xyf12344 的回复:[quote=引用 3 楼 max_min_ 的回复:] 地址，也只是一个传值的动作而已！  char *str = NULL; fun_malloc2(&str); void fun_malloc2( char **str);  谢谢，，，，解决了，，，大神就是大神，，，， 不过我想问一下，能解释一下原因么？ 小弟拜上[/quote] 直接传fun_malloc2(str);//这是地址str的地址也是拷贝地址值操作的 在fun_malloc2函数体中，分配了内存，并把地址赋值给str,但是这个时候操作的只是拷贝的那一份而已！而不是其实际本体！

引用 3 楼 max_min_ 的回复:地址，也只是一个传值的动作而已！  char *str = NULL; fun_malloc2(&str); void fun_malloc2( char **str);  谢谢，，，，解决了，，，大神就是大神，，，， 不过我想问一下，能解释一下原因么？ 小弟拜上

额。。。学生一枚，，，还没招工作。。。 ，改了，还是不行啊

学会提问很重要 请列出不同之处


Question: 求戳=-=解救一道题。。。

由于题干没看太懂。只能给你改道这里了 。 只是给你 做个参考。 #include<stdio.h>  float Ave; int num; struct student { 		int number; 		char name[10]; 		float score1,score2,score3; 		float ave; }; struct student student[2],temp;   void input(int i) { 		puts("输入number："); 		scanf("%d",&student[i].number); 		getchar(); 		puts("输入name："); 		scanf("%s",student[i].name); 		getchar(); 		puts("输入sanmenchengji："); 		scanf("%f %f %f",&student[i].score1,&student[i].score2,&student[i].score3); 		getchar(); }   void averages() { 		int i; 		float sum=0.00,Ave; 		for(i=0;i<2;i++) 		{ 				student[i].ave=(student[i].score1+student[i].score2+student[i].score3)/3;   				sum+=student[i].ave;} 				Ave=sum*3/2;  }   void max() { 		float max; 		int i; 		max=student[0].ave;  		for(i=0;i<2;i++) 		{ 				if(max<student[i].ave) 				{ 		//				max=student[i].ave; 		//				temp=student[i]; } 					num = i; 				} 		}  } int main() { 		int i; 		for(i=0;i<2;i++) 				input(i); 		averages(); 		max(); 		printf("%f",Ave); 	//	printf("%d\n%s\n%.2f\n%.2f\n%.2f\n%.2f\n",temp.number,temp.name,temp.score1,temp.score2,temp.score3,temp.ave); 		printf("%d\n%s\n%.2f\n%.2f\n%.2f\n%.2f\n",student[num].number,student[num].name,student[num].score1,student[num].score2,student[num].score3,student[num].ave); }

我用puts也错了

原因是你输入名字的时候 不要空格建议你去看一下scanf()函数的定义；在一个你的平均值好像是一个子函数的一个变量；这个变量会在你掉用完这个子函数后自动擦除，你的平均值输出也是错误的。


Question: 输出到一个磁盘文件“test”中保存

#include <stdio.h> int main() {     FILE *fp;     int i=0;     char string[100];      if ((fp=fopen("text.txt","w"))==NULL) {         puts("Error on opening output file text");         return 1;     }     fgets(string,100,stdin);     while (string[i]!='!' && string[i]!='\n' string[i]!=0) {         if (string[i]>='a'&&string[i]<='z') string[i]=string[i]-32;         fputc(string[i],fp);         i++;     }     fclose(fp);     fp=fopen("test.txt","r");     fgets(string,100,fp)     fclose(fp);     printf("%s",string);     return 0; }

然后我自己写的那段不能解决我的题目要求。。 哪里出现问题呢。。。

if((fp=fopen("text.txt","w"))==NULL)//以w打开一个文件，没有的话会新建一个，不用自己建立


Question: 关于des加密，没法解密问题。

才发现自己结贴率75%。


Question: 数组变序列数字问题

要是只是要求显示不能把printf()函数里的格式控制符紧挨着写么~~

这个办法就是将其变为a[0]*10^9+a[1]*10*^8+...+a[9];但是希望注意你变化的这个值能被你所定义的那个数的类型所容纳。

123 == 1*100 + 2*10 + 3*1 以此类推。。


Question: c语言中头文件如何实现展开呢？

引用 6 楼 buyong 的回复:加name space 能具体教一下怎么玩么？ 一坨头文件搞晕了。。。。

加name space

嗯。。是的。。。主要是以前的code定型不能动。。  新加的部分又与之前的code有重复， 所以想把重复的部分拉出来

功能如果相同，则直接include，不要重新定义 功能如果不同，则不要使用相同的名称进行定义

你的意思是这两个类型完全一样？但是分布在两个file里？这不太奇怪了吗

引用 1 楼 zhao4zhong1 的回复:typedef新定义可以覆盖旧定义。 可是我旧的定义也还是要保留的  而且结构体比较多，要一个一个处理吗？  有没有可能这样的，两个重合的结构体放到aaa.h里， 然后A.h写成 #include aaa.h 。。。  后面再加自己专属的呢？

typedef新定义可以覆盖旧定义。


Question: 编程范式中遇到的问题！求救！困扰我很久了。。。

引用 5 楼 terhack 的回复:跟大小端有关 恩，我打印了另外2个字节 发现显示是16608就和我想的一样了~~~~

跟大小端有关

引用 3 楼 houzhenghui123 的回复:#include<stdio.h> void main() { float f= 7.0; int len = sizeof(f); unsigned char pchar = (unsigned char*)(&f); for(int i = 0; i< len ; i++){    pringf("%u\t", *(pchar +i)); } } 再对照你学的计算机组成知识，对比下就明白了。  #include<stdio.h> void main() { float f= 7.0; int len = sizeof(f); unsigned char* pchar = (unsigned char*)(&f); for(int i = 0; i< len ; i++){    pringf("%u\t", *(pchar +i)); } }

截断了吧，改下用字节长度一样的整形...  printf("%#x\n", *(unsigned int *)&f);

坚决消灭零回复.


Question: 这是我编的时钟程序，为什么指针有时会闪烁，我知道应该用双缓冲，但要怎么写啊，请各位大神说一下。。。

仅供参考：#include <graphics.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <dos.h> #include <conio.h> #include <time.h> #include <math.h> time_t t; char timestr1[30];//DDD MMM dd hh:mm:ss YYYY char timestr2[30];//DDD MMM dd hh:mm:ss YYYY char hhmmss[9]; int graphdriver,graphmode,page; int i,xo,yo,r0,r1,r2,r3,r4,r5,r6,r7; int x1,y1,x2,y2; int hh,mm,ss; double c,s; int xasp,yasp; void main() {     xo=60;yo=60;     r0=5; //轴     r1=20;//时针     r2=36;//分针     r3=45;//秒针     r4=50;//时刻度     r5=53;//分刻度     r6=55;//刻度外     r7=59;//表盘     graphdriver=VGA;     graphmode=VGAMED;     initgraph(&graphdriver,&graphmode,"D:\\BC\\BGI");     getaspectratio(&xasp, &yasp);     page=0;     timestr2[0]=0;     while (1) {         if (kbhit()) break;         time(&t);         strcpy(timestr1,ctime(&t));         if (strcmp(timestr1,timestr2)) {             strcpy(timestr2,timestr1);             hh=atoi(timestr2+11);             mm=atoi(timestr2+14);             ss=atoi(timestr2+17);             setvisualpage(page);             setactivepage(1-page);             cleardevice();             sprintf(hhmmss,"%02d:%02d:%02d",hh,mm,ss);             outtextxy(28,0,hhmmss);             pieslice(xo,yo,0,360,r0);             circle(xo,yo,r7);             for (i=0;i<60;i++) {                 c=cos(i*6*3.14159265/180);                 s=sin(i*6*3.14159265/180)*xasp/yasp;                 if (0==(i%5)) {                     x1=xo+r4*c;                     y1=yo+r4*s;                 } else {                     x1=xo+r5*c;                     y1=yo+r5*s;                 } 				x2=xo+r6*c; 				y2=yo+r6*s; 				line(x1,y1,x2,y2); 				if (((hh%12)*5+mm/12+45)%60==i) { 					x2=xo+r1*c; 					y2=yo+r1*s; 					setlinestyle(0,-1,3); 					line(xo,yo,x2,y2); 					setlinestyle(0,-1,1); 				} 				if ((mm+45)%60==i) { 					x2=xo+r2*c; 					y2=yo+r2*s; 					setlinestyle(0,-1,3); 					line(xo,yo,x2,y2); 					setlinestyle(0,-1,1); 				} 				if ((ss+45)%60==i) { 					x2=xo+r3*c; 					y2=yo+r3*s; 					line(xo,yo,x2,y2); 				} 			} 			page=1-page; 		}         delay(100);     }     getch();     closegraph(); }

画图程序闪烁不一定是绘制速度的问题，所以双缓冲不一定能解决闪烁问题，很多闪烁问题可能是由于不断地背景切换造成的，可以从这方面找原因和解决方法

"我知道应该用双缓冲，但要怎么写啊" 你这个还真是矛盾呀, 又知道, 又不知道?  双缓冲也就把要绘制的东西先绘制到内存中, 再一次绘制到屏幕上.


Question: 求知：C语言程序能处理非txt格式的文件吗？

仅供参考#pragma comment(lib,"gdi32") #include <windows.h> #include <stdio.h>  int main() {     const DWORD uWidth = 18 + 17 * 256, uHeight = 18 + 17 * 128;      PBITMAPINFO pbmi = (PBITMAPINFO) LocalAlloc (LPTR, sizeof (BITMAPINFOHEADER) + sizeof (RGBQUAD) * 2);     pbmi->bmiHeader.biSize = sizeof (BITMAPINFOHEADER);     pbmi->bmiHeader.biWidth = uWidth;     pbmi->bmiHeader.biHeight = uHeight;     pbmi->bmiHeader.biPlanes = 1;     pbmi->bmiHeader.biBitCount = 1;     pbmi->bmiHeader.biSizeImage = ((uWidth + 31) & ~31) / 8 * uHeight;     pbmi->bmiColors[0].rgbBlue = 0;     pbmi->bmiColors[0].rgbGreen = 0;     pbmi->bmiColors[0].rgbRed = 0;     pbmi->bmiColors[1].rgbBlue = 255;     pbmi->bmiColors[1].rgbGreen = 255;     pbmi->bmiColors[1].rgbRed = 255;      HDC hDC = CreateCompatibleDC (0);     void * pvBits;     HBITMAP hBitmap = CreateDIBSection (hDC, pbmi, 0, &pvBits, NULL, 0);     SelectObject (hDC, hBitmap);     HFONT hFont = CreateFont (16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "宋体"); //  HFONT hFont = CreateFont (16, 0, 0, 0, 0, 0, 0, 0, SHIFTJIS_CHARSET, 0, 0, 0, 0, "宋体");     SelectObject (hDC, hFont);     BitBlt (hDC, 0, 0, uWidth, uHeight, NULL, 0, 0, WHITENESS);      char c[4];     int i, j;     for (i = 128; i < 256; i++) {         sprintf (c, "%02X", i);         TextOut (hDC, 1, (i - 127) * 17 + 1, c, 2);     }     for (j = 0; j < 256; j++) {         sprintf (c, "%02X", j);         TextOut (hDC, (j + 1)* 17 + 1, 1, c, 2);     }     for (i = 128; i < 256; i++) {         for (j = 0; j < 256; j++) {             c[0] = (char) i;             c[1] = (char) j;             TextOut (hDC, (j + 1) * 17 + 1, (i - 127) * 17 + 1, c, 2);         }     }     for (i = 0; i < 130; i++) {         MoveToEx (hDC, 0, i * 17, NULL);         LineTo (hDC, uWidth, i * 17);     }     for (j = 0; j < 258; j++) {         MoveToEx (hDC, j * 17, 0, NULL);         LineTo (hDC, j * 17, uHeight);     }      BITMAPFILEHEADER bmfh;     bmfh.bfType = *(PWORD) "BM";     bmfh.bfReserved1 = 0;     bmfh.bfReserved2 = 0;     bmfh.bfOffBits = sizeof (BITMAPFILEHEADER) + sizeof (BITMAPINFOHEADER) + sizeof (RGBQUAD) * 2;     bmfh.bfSize = bmfh.bfOffBits + pbmi->bmiHeader.biSizeImage;      HANDLE hFile = CreateFile ("goal.bmp", GENERIC_WRITE, 0, 0, CREATE_ALWAYS, 0, 0);     if (hFile != INVALID_HANDLE_VALUE) {         DWORD dwWritten;         WriteFile (hFile, &bmfh, sizeof (BITMAPFILEHEADER), &dwWritten, NULL);         WriteFile (hFile, pbmi, sizeof (BITMAPINFOHEADER) + sizeof (RGBQUAD) * 2, &dwWritten, NULL);         WriteFile (hFile, pvBits, pbmi->bmiHeader.biSizeImage, &dwWritten, NULL);          CloseHandle (hFile);     }      DeleteObject (hFont);     DeleteObject (hBitmap);     DeleteDC (hDC);     LocalFree (pbmi);      return 0; }

引用 楼主 mcmay 的回复:各位达人，请问C语言做的程序除了处理txt文件之外，还能处理其他常见文件格式吗？例如，doc, xls, pdf, bmp,jpg等等。我看到的所有C语言处理文件的例子中，几乎全是处理txt格式，而且还是ANSI字符集的。虽然也有二进制读写的，但却没有谈如何处理特殊格式的文档，只是说特殊格式的文档中那些格式或特征性的东西也都是由二进制数据控制的，至于这些格式和特征如何在C语言的程序中进行读或写却没有涉及。      我想C语言应该有办法处理这些特殊格式的文档，否则如果只是跟txt打交道，那它的有用性在这方面还是要打折扣的。C语言诞生于Unix系统，该系统上的文档最初也都是ANSI字符集之内的，但现在的操作系统应该能够处理不同格式的文件，C语言在这方面应该也会有所更新吧。 所有的文件保存到硬盘都是2进制，从理论上说，C语言是无所不能的，你想打开什么文件，就要知道这个文件的协议即可，按照这种文件的协议去解析里面的内容。

哦？！原来我一直是横着走的？

引用 9 楼 zhao4zhong1 的回复:电脑内存或文件内容只是一个一维二进制字节数组及其对应的二进制地址； 人脑才将电脑内存或文件内容中的这个一维二进制字节数组及其对应的二进制地址的某些部分看成是整数、有符号数/无符号数、浮点数、复数、英文字母、阿拉伯数字、中文/韩文/法文……字符/字符串、汇编指令、函数、函数参数、堆、栈、数组、指针、数组指针、指针数组、数组的数组、指针的指针、二维数组、字符点阵、字符笔画的坐标、黑白二值图片、灰度图片、彩色图片、录音、视频、指纹信息、身份证信息…… 我发现这个可以在C/C++版可以横行天下。

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

摘抄   A file, in the computer world, is a self contained piece of information available to the operating system and any number of individual programs. Information inside the file could consist of essentially anything but whatever the file contains is likely related somehow. A computer file can be thought of much like a traditional file that one would find in an office's file cabinet.  Whatever program uses an individual file is responsible for understanding its contents. Similar types of files are said to be of a common "format." In most cases, the easiest way to determine a file's format is to look at the file's extension.  Each individual file in Windows will also have a file attribute which sets a condition to the specific file.  Files in any operating system are stored on hard drives, optical drives, and other storage devices. The specific way a file is stored and organized is referred to as a file system.  Examples: "For years I had a text file that I stored important telephones and addresses in. A few years ago, when I first started using Microsoft Excel, I moved the information that text file to a new Excel file I created. In this new file format, I can sort names and display the information in new ways."

引用 楼主 mcmay 的回复:C语言诞生于Unix系统，该系统上的文档最初也都是ANSI字符集之内的，但现在的操作系统应该能够处理不同格式的文件，C语言在这方面应该也会有所更新吧。  C语言指指提供基本读写操作，用C语言编写的程序/库可以完成更复杂的IO。

就算你只用标准库，也应当知道fread、fwrite是读写字节的啊。

所有格式文件的读和写都没有任何区别，之所以c语言大多数例子都是处理txt文件，那是因为它没有内部格式可以集中关心要学的东西，否则直接拿个tiff格式的图片写例程——新手同学们光是看格式定义就要头晕三天

引用 3 楼 czarten 的回复:举个例子你说doc，doc无非是word自己定义的格式而已，而word跟你自己写的应用程序没有本质的不同，你也可以自己做一个字处理软件，定义一种自己的格式，显然C语言不可能为每种格式的文件都提供标准库函数来操作它，它只需要提供基本的字节操作就行了，而你需要知道doc的数据格式是如何组织的，文件里每个字节代表什么，然后就可以用基本的字节操作来完成你想要的功能了 当然，也可以找第三方的函数库，但总之这不是C语言管的事  另外我觉得你有些误解，你可能觉得文件的后缀名是一个很重要的东西，其实后缀名只是提示操作系统，哪个程序能打开我而已，一个文件仅仅是一堆字节，跟它后缀名叫什么没关系，这堆字节代表什么意义，取决于谁来解读它，你用图片软件打开它，这堆字节就按照图片格式解析，你用word打开它，这堆字节就按照doc格式解析（这么说不太严格但意思差不多）+1

其实所有的文件都是二进制文件，因为文本文件比较方便，用途很多，所以把它单独抽出来。doc/xls/pdf/bmp/jpg格式的解析，完全取决于你对其文件格式的理解，在C语言中，都可以通过fopen/fclose/fread/fwrite/fgetc/fputc/fseek这些API来实现。  引用 楼主 mcmay 的回复:各位达人，请问C语言做的程序除了处理txt文件之外，还能处理其他常见文件格式吗？例如，doc, xls, pdf, bmp,jpg等等。我看到的所有C语言处理文件的例子中，几乎全是处理txt格式，而且还是ANSI字符集的。虽然也有二进制读写的，但却没有谈如何处理特殊格式的文档，只是说特殊格式的文档中那些格式或特征性的东西也都是由二进制数据控制的，至于这些格式和特征如何在C语言的程序中进行读或写却没有涉及。      我想C语言应该有办法处理这些特殊格式的文档，否则如果只是跟txt打交道，那它的有用性在这方面还是要打折扣的。C语言诞生于Unix系统，该系统上的文档最初也都是ANSI字符集之内的，但现在的操作系统应该能够处理不同格式的文件，C语言在这方面应该也会有所更新吧。

txt格式是什么格式？

所有文件都是二进制啊 至于要操作具体的类型，比如说bmp，你需要知道bmp的数据格式，比如开头多少字节是文件头，接下来每个像素信息占几位，每几位代表什么意思，这些都是可以查到的，而C语言只需要提供底层的字节操作就行了，具体的文件类型操作不是C语言的事情是程序员的事情 那些文件格式无非也都是应用程序自己定义的而已

能，LZ想想，Word使用什么语言写的？

如果你想要处理unicode字符的话C是完全可以的，只是函数稍微变以下，比如fwprintf函数等等。基本输入输出函数都有宽位字符的版本。你可以查看下stdio.h里面的函数声明，带w的基本都是宽位字符版本的。windows也为此专门提供了转码的api。 对于文件的处理，其实都是一样的，问题在于如何解析文件的内容。比如你认为C无法读取doc文件只是因为你无法正确的解析读取出来的文件而已。 C读取doc、xls文件可能不一定可以。C++倒是可以，但是需要导入几个类，所以C估计是不行的。至于其他的一些文件比如bmp,jpg等也是如此，一般会有对应的库来解决这样的问题，C++肯定都可以，C行不行就需要google之后才能断定


Question: 哪本c语言书比较好一点~~

比较推荐：《The C prime plus(第五版)》，其他书也不错。不过，这本书比较基础的。

计算机组成原理→DOS命令→汇编语言→C语言（不包括C++）、代码书写规范→数据结构、编译原理、操作系统→计算机网络、数据库原理、正则表达式→其它语言（包括C++）、架构……  对学习编程者的忠告： 眼过千遍不如手过一遍！ 书看千行不如手敲一行！ 手敲千行不如单步一行！ 单步源代码千行不如单步对应汇编一行！  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 primer plus 这本真的不错

c  primer

Kenneth和A.Reek的《c和指针》

第一本好点。

C primer plus


Question: 这个应该怎么改？有点转不过来弯。

因为当输出第一个文件的第一行后，ch1为\n，所以else语句块儿中的while条件一直为假。

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


Question: 文思海辉第一届在线编程大赛：单词博弈。我的这么经典居然说错了

这个题我没做，只简单看了下。 我觉得你的问题应该有两个：1、你要求甲乙两人都只删除最大单增序列以外的字符；2、最大单增序列可能不只一种组合。还有一点，最终一方获胜时，得到的字符串未必是最大单增序列。 比如字符串 baad，最大单增序列 ad、bd。如果甲删掉a或b，则必然乙胜利；而如果删掉d，则甲赢，最终的序列是b或a。

那如果最大有序增长的子序列有2个，并且长度相同，你怎么办

哎，同样郁闷中，测试用例失败。。。

引用 7 楼 u012902350 的回复:思路：自己去掉一个字母后直接获胜，否则去掉一个字母，让对方在回合内无法获胜。直到找到一个递增子序列，求长度=（单词长度-子字符串），长度为奇数，甲胜，长度为偶数，乙胜。不知思路对不对？ 对的，我的思路错了。

引用 5 楼 YouNeverCanTell 的回复:测试失败是什么意思？思路应该是对的，自己验证了几个也没有问题。提示测试用例失败，可能有没有想到的，求大家解决我的疑惑？？

测试失败是什么意思？思路应该是对的，自己验证了几个也没有问题。

引用 3 楼 derekrose 的回复:那一定是题目审核方面你不达标。怎么个审核法啊？求指点啊？我不想死了还不知道为什么！

那一定是题目审核方面你不达标。

引用 1 楼 yfqvip 的回复:对于这种刚发的帖子，我总是毫不犹豫的顶了。如果火了就是个前排，可以混个脸熟，说不定谁好心就给粉了…稳赚不赔；如果沉了就感觉是我弄沉的，很有成就感，还能捞经验。哥哥，你积分那么多，肯定是高手给我这个新手点指点啊，不要磨灭了我的研究激情


Question: 请大神帮忙。。。这是学校的期末课程设计，我是新手，实在不知道怎么改，。

跟着编译器的错误提示，一点一点修改你的语法错误先。编程人永远都跳不过这一步的。

编译器都跟你说的明明白白

函数声明没有，全是基本语法错误。   那个报错点那个错误。自己动手。搞编程的   没有人能跳过调试和找bug。

为何感觉好高端，我们大1就考试一些简单的题


Question: C语言文件操作中的问题，关于fread和fwrite

引用 楼主 sz0hj 的回复:我想把链表保存进文件，之后从这个文件读出每个节点，用这些新建立一个链表，应该怎么办呢？ 谢谢~~~  一个简单的方法是，只保存节点地址（节点指针）以外的数据。 每次读文件中的数据，并用这些数据创建链表。 必要的时候，可以保存数据个数。  指针保存到文件中，丝毫作用也不起。

本来说帮你调调吧  结果 我也郁闷了；为什么 能正确写入  却不能读出来 ，谁能帮我看看阿  ！  #include<stdio.h> #include<stdlib.h> #define LEN sizeof(struct student) struct student {    		int NO; 		char name[30]; 		float achievement[6]; 		float aver; 		float sum; 		struct student* next; }; struct student *input(int a,int b) { 		int i=0,r; 		struct student *p1,*p2,*head; //		head=(struct student*)malloc(LEN); 		while(i<a) 		{ 				p1=(struct student*)malloc(LEN); 				p1->next=NULL; 				i=i+1; 				p1->sum=0; 				printf("请输入学号：姓名：\n"); 				scanf("%d %s",&p1->NO,p1->name); 				for(r=0;r<b;r++) 				{    						printf("请输入第%d门成绩：\n",r+1); 						scanf("%f",&p1->achievement[r]); 						p1->sum=p1->sum+p1->achievement[r]; 				} 				p1->aver=p1->sum/b; 				if(1==i){ 						head = p1; 						head->next = NULL; 				}else{ 						p1->next = head; 						head = p1; 				}  		} 		return head; } void save(int a,struct student*head) { 		printf("请输入文件名：例[D:\\string.dat]\n"); 		char m[30]; 		scanf("%s",m); 		struct student*p1,*p2; 		int    r=1; 		p1=p2=(struct student*)malloc(LEN); 		FILE*fp; 		fp=fopen(m,"w"); //		fwrite(head,LEN,1,fp);                                  //这里是写入文件。 		fwrite(&head->NO,4,1,fp);                                  //这里是写入文件。 		fwrite(head->name,1,5,fp);                                  //这里是写入文件。 		while(r<a) 		{ 				r=r+1; 				p2->next=p1; 				p2=p1; 				p1=(struct student*)malloc(LEN); 				fwrite(p1,LEN,1,fp); 		} 		close(fp); } struct student* output(int a)                                                {    		struct student*head; 		struct student*p1,*p2; 		head=p1=p2=(struct student*)malloc(LEN); 		FILE *fp1;    		char m[30]; 		int NO,n; 		char buf[5]={}; 		printf("输入 文件名 m\n"); 		scanf("%s",m); 		printf("m = %s\n",m); 		if((fp1=fopen(m,"r"))==NULL)                		{    				printf("can not be open!\n"); 				exit(0); 		} 		int    r=0; 		printf("a= %d\n",a); 		while(r<a) 		{ 				r=r+1; 				n = fread(&NO,4,1,fp1);   				printf("n1 = %d\n",n);   				printf("%d\n",NO);       				n = fread(buf,1,5,fp1);   				printf("n2  = %d\n",n);    				printf("%s\n",buf);      				printf("why  ???\n");       //将读出的结构体里面的数据输 出到屏幕，可是结果不对，乱码的。 		} 		fclose(fp1); 		return(head); } void main() { 		struct student *head,*p; 		head=NULL; 		int a,b; 		printf("输入 学生数 和 课程数\n"); 		scanf("%d %d",&a,&b); 		head=input(a,b); 		save(a,head); 		for(p=head;p!=NULL;p=p->next){ 				printf("%d %s\n",p->NO,p->name); 		}  		output(a); }

你的程序我跑了，结果显示正常的，只是打开文件看的时候显示的是乱码，因为写入的时候以二进制形式写入，所以单独看是乱码的，

单独检验fwrite函数，只有写char[] 类型才成功，其他的都失败了，不知道为啥，，，

"w"，“r"改成"wb","rb"

void save(int a,struct student*head)函数里没有对打开的文件关闭哦。

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

引用 楼主 sz0hj 的回复:#include<stdio.h> #include<stdlib.h> #define LEN sizeof(struct student) struct student {	 	long int NO; 	char name[30]; 	float achievement[6]; 	float aver; 	float sum; 	struct student*next; }; struct student*input(int a,int b) { 	int i=0,r; 	struct student*p1,*p2,*head; 	head=p1=p2=(struct student*)malloc(LEN); 	while(i<a) 	{ 		i=i+1; 		p1->sum=0; 		printf("请输入学号：姓名：\n"); 		scanf("%d%s",&p1->NO,&p1->name); 		for(r=0;r<b;r++) 		{	 			printf("请输入第%d门成绩：\n",r+1); 			scanf("%f",&p1->achievement[r]); 			p1->sum=p1->sum+p1->achievement[r]; 		} 		p1->aver=p1->sum/b; 		if(i==1) 		{ 			head=p1; 		} 		p2=p1; 		p1=(struct student*)malloc(LEN); 		p2->next=p1; 	} 	p2->next=NULL; 	return head; } void save(int a,struct student*head) { 	printf("请输入文件名：例[D:\\string.dat]\n"); 	char m[30]; 	scanf("%s",m); 	struct student*p1,*p2; 	int	r=1; 	p1=p2=(struct student*)malloc(LEN); 	FILE*fp; 	fp=fopen(m,"w"); 	fwrite(head,LEN,1,fp);                                  //这里是写入文件。 	while(r<a) 	{ 		r=r+1; 		p2->next=p1; 		p2=p1; 		p1=(struct student*)malloc(LEN); 		fwrite(p1,LEN,1,fp); 	} 	p2->next=NULL; } struct student*input(int a)												 {	 	struct student*head; 	struct student*p1,*p2; 	head=p1=p2=(struct student*)malloc(LEN); 	FILE*f1;	 	char m[30]; 	scanf("%s",m); 	if((f1=fopen(m,"r"))==NULL)				 	{	 		printf("can not be open!\n"); 		exit(0); 	} 	int	r=0; 	while(r<a) 	{ 		r=r+1; 		fread(p1,LEN,1,f1);                                          //这里从文件里面读出。 		printf("%d\t%s\n\n",p1->NO,p1->name);       //将读出的结构体里面的数据输 出到屏幕，可是结果不对，乱码的。 	} 	return(head); 	fclose(f1); } void main() { 	struct student*head; 	head=NULL; 	int a,b; 	scanf("%d%d",&a,&b); 	head=input(a,b); 	save(a,head); 	input(a); } 为什么输出的时候就是乱码的呢？ 哪里有问题？ 我想把链表保存进文件，之后从这个文件读出每个节点，用这些新建立一个链表，应该怎么办呢？ 谢谢~~~ 说个无关紧要的，为什么链表里没有first节点。。。。。。

你的程序有以下几个问题  1）链表保存，不必保存指针。因为文件中保存指针，读取的时候，也用不到。  2）链表读出，要重新为链表的节点分配内存，即重建链表。  3）b要小于6 这个，不然就会出错，    所以：       要断言，并且要保护 4）分配的内存要释放。  5）保存数据，不需要分配内存。 6）保存的数据，不在链表中，没有保存链表中的数据。     7）输入是有内存泄露，     p2->next=NULL;    应该是 p1->next=NULL;  以上是错误  8）学生信息，没有必要和节点定义成一个结构体。    单独定义学生信息；    节点内有一个学生信息的成员，就可以了。 这个是，处理方式不太好。

错误的地方有点多，结果不正确是正常的，lz可以先确定下input函数有没有问题

19 error(s), 17 warning(s)

大神们你们人呢？？  要死掉了，为什么啊。。。


Question: 《怎样用c++编程骑士飞行棋,偶是菜鸟级》

大一就学习专业课了。  直接就课程设计。


Question: 自动化编程的都来看看

有时去执行一个错误的决定总比优柔寡断或者没有决定要好得多。

多了解一下吧，这个方向也不见得不好！如果能够提高C语言的能力，还是可以考虑。当然，你可以再试试其他的面试！

引用 7 楼 xiaolanghh 的回复:恩 面试我的那位师兄就是介绍说是写测试程序，不出意外应该是做芯片测试的吧。请问这个技术性强吗?还有做这个好找工作吗？ 怎么说呢.技术不强. 挺好找工作吧,一大堆的硬件电子公司都与这相关. 具体我也不是很清楚. 反正上面我提到的公司待遇都很好,都是很牛的.

引用 6 楼 Binzo 的回复:NI就是做芯片的公司啊，当然它也开发出了Labview，现在被TI收购了。  这类的公司很多（TI，Analog，Maxin，motor，Freescale，仙童）吧。一般去都是做销售或芯片测试。恩 面试我的那位师兄就是介绍说是写测试程序，不出意外应该是做芯片测试的吧。请问这个技术性强吗?还有做这个好找工作吗？

引用 3 楼 xiaolanghh 的回复:[quote=引用 1 楼 sinservice 的回复:] 是相对简单的工作，当然我这个说法是对C语言程序员而言的。在某些人看来，可能巨难。  比如，操纵和收集标准化的高级设备的数据，需要用到SECS协议，这可能需要你写一点代码来调一下标准SECS库。  没什么。这个行业的发展前景好吗？因为我看这方面的公司招人挺少的！我现在有点犹豫，怕以后如果公司出问题了，不太好找相关的工作[/quote]   你只要不断学习，还怕未来找不到工作。  现在北京，一个小孩，培训30课时的C++，要是好好学，都可以拿到8000.你怕什么？

发展前景的问题超出了程序员的范畴

引用 1 楼 sinservice 的回复:是相对简单的工作，当然我这个说法是对C语言程序员而言的。在某些人看来，可能巨难。  比如，操纵和收集标准化的高级设备的数据，需要用到SECS协议，这可能需要你写一点代码来调一下标准SECS库。  没什么。这个行业的发展前景好吗？因为我看这方面的公司招人挺少的！我现在有点犹豫，怕以后如果公司出问题了，不太好找相关的工作

引用 楼主 xiaolanghh 的回复:最近在找工作，面试了一家小型公司，基本通过了面试。但具体不太清楚做什么的，貌似说是做自动化编程，就是用c编程测试测量一些产品的质量，好像跟嵌入式有点关系，说国外发展好的有NI公司，在网上查阅了一些资料，个人对这个行业还是不太了解，好像做这方面开发的公司挺少的，想请问下，这个行业现在怎么样，以及未来发展前景好吗？希望大家都说说自己的看法，当然有做这个行业的师兄介绍下最好了，小弟不胜感激这个行业的发展前景好吗？因为我看这方面的公司招人挺少的！我现在有点犹豫，怕以后如果公司出问题了，不太好找相关的工作


Question: 新手求指教，此题如何处理？

引用 14 楼 u013151320 的回复:[quote=引用 13 楼 bijiaoben 的回复:] [quote=引用 10 楼 bijiaoben 的回复:] 单纯位数多不一定数字就大，比如前面输入了很多很多个0 引用 12 楼 u013151320 的回复:[quote=引用 11 楼 bijiaoben 的回复:] [quote=引用 9 楼 u013151320 的回复:] 提交到学校的题库里。。。被判定答案错误。。。怎么办？ 楼主你提交的代码是什么样的啊？[/quote]就用的楼上那段代码啊，那段代码确实能够判断，但是提交上去还是错误的呢[/quote] 代码要有自己写的，需要自己思考的，不能直接copy了别人的去用，至少你要先把别人的东西看懂，看看适不适合自己的使用。[/quote]看懂了啊。。。但是事实证明还是不对，不知道哪里出了错[/quote] 给你举个例子：字符串a“001”，字符串b“11”，那么用你提交的代码来处理的话，a大呢还是b大？ 你要先根据题目分析一下需求。首先你要检查输入的字符串中有没有‘0’~‘9’之外的非结束符字符，如果有的话，那么你的程序要提示输入错误。然后你要把2个字符串第一个有效数字之前的‘0’都过滤掉。再然后，才是按照这个代码中的方法进行比较。 我给你的提示你根本没看，你光看代码了

引用 13 楼 bijiaoben 的回复:[quote=引用 10 楼 bijiaoben 的回复:] 单纯位数多不一定数字就大，比如前面输入了很多很多个0 引用 12 楼 u013151320 的回复:[quote=引用 11 楼 bijiaoben 的回复:] [quote=引用 9 楼 u013151320 的回复:] 提交到学校的题库里。。。被判定答案错误。。。怎么办？ 楼主你提交的代码是什么样的啊？[/quote]就用的楼上那段代码啊，那段代码确实能够判断，但是提交上去还是错误的呢[/quote] 代码要有自己写的，需要自己思考的，不能直接copy了别人的去用，至少你要先把别人的东西看懂，看看适不适合自己的使用。[/quote]看懂了啊。。。但是事实证明还是不对，不知道哪里出了错

引用 10 楼 bijiaoben 的回复:单纯位数多不一定数字就大，比如前面输入了很多很多个0 引用 12 楼 u013151320 的回复:[quote=引用 11 楼 bijiaoben 的回复:] [quote=引用 9 楼 u013151320 的回复:] 提交到学校的题库里。。。被判定答案错误。。。怎么办？ 楼主你提交的代码是什么样的啊？[/quote]就用的楼上那段代码啊，那段代码确实能够判断，但是提交上去还是错误的呢[/quote] 代码要有自己写的，需要自己思考的，不能直接copy了别人的去用，至少你要先把别人的东西看懂，看看适不适合自己的使用。

引用 11 楼 bijiaoben 的回复:[quote=引用 9 楼 u013151320 的回复:] 提交到学校的题库里。。。被判定答案错误。。。怎么办？ 楼主你提交的代码是什么样的啊？[/quote]就用的楼上那段代码啊，那段代码确实能够判断，但是提交上去还是错误的呢

引用 9 楼 u013151320 的回复:提交到学校的题库里。。。被判定答案错误。。。怎么办？ 楼主你提交的代码是什么样的啊？

单纯位数多不一定数字就大，比如前面输入了很多很多个0

提交到学校的题库里。。。被判定答案错误。。。怎么办？

引用 6 楼 u013151320 的回复:编出程序来看看，用字符数组然后比较位数，如果位数相同再从开头那位进行比较就有点复杂了啊。。。  复杂吗？顶多十来行吧

引用 4 楼 M173475237 的回复:既然输入的是大数，。要保证数组的每个元素只储存一位的话，就要用字符数组了。不过10^1000。。嗯真够大的。 用动态分配吧。。输入多少位，就给分配多少。 10^1000也就char[1000]嘛，用不着动态

#include<stdio.h> #include<string.h> int main(){     char a[1024],b[1024];     scanf("%s%s",a,b);     if(strlen(a)>strlen(b)) printf("a>b\n");     else if(strlen(a)<strlen(b)) printf("a<b\n");     else{         int i=0;          while(a[i]==b[i]&&a[i]!='\0') i++;          if(a[i]>b[i])              printf("a>b\n");         else if(a[i]>b[i])              printf("a<b\n");         else               printf("a==b\n");     }     return 0; }   随便写写，不排除有错 如果可以用strcmp就更简单了

先比较位数，如果位数相同再从高到底逐位比较

引用 2 楼 user-5 的回复:[quote=引用 1 楼 truelance 的回复:] 先比较位数，如果位数相同再从高到底逐位比较 用std::string存储a,b[/quote] 还要判断是不是数，就是首位不能为0，所有位都要是数字

引用 1 楼 truelance 的回复:先比较位数，如果位数相同再从高到底逐位比较 用std::string存储a,b


Question: 链表啊！！为什么带数据测试的时候你时而抽风时而不抽风呢！！！

仅供参考//假设带表头结点的单向链表头指针为head，试编写一个算法将值为5的结点插入到连接表的第k个结点前，删除第k个节点，并对该链表进行排序。 #include <stdio.h> #include <stdlib.h> #include <malloc.h> #include <time.h> struct NODE {     int          data;     struct NODE *next; } H,*head,*p,*q,*s1,*s2,*s3,*s4,*s; int i,j,k,n,t,m; int main() {     srand(time(NULL));      //填写头节点数据     H.data=-1;     H.next=NULL;     head=&H;      //创建10个节点的单链表     p=head;     for (i=0;i<10;i++) {         q=(struct NODE *)malloc(sizeof(struct NODE));         if (NULL==q) return 1;         q->data=rand()%100;//填写0..99的随机值         q->next=NULL;         p->next=q;         p=q;     }      //输出整个单链表     s=head->next;     while (1) {         if (NULL==s) {             printf("\n");             break;         }         printf("%02d->",s->data);         s=s->next;     }      //将值为5的结点插入到单链表的第k个结点前     k=3;     n=0;     p=head;     while (1) {         if (NULL==p) {             break;         }         n++;         if (k==n) {             q=(struct NODE *)malloc(sizeof(struct NODE));             if (NULL==q) return 1;             q->data=5;             q->next=p->next;             p->next=q;             break;         }         p=p->next;     }      //输出整个单链表     s=head->next;     while (1) {         if (NULL==s) {             printf("\n");             break;         }         printf("%02d->",s->data);         s=s->next;     }      //删除第k个节点     k=5;     n=0;     p=head;     while (1) {         if (NULL==p) {             break;         }         n++;         if (k==n) {             q=p->next;             if (q) {                 p->next=q->next;                 free(q);             }             break;         }         p=p->next;     }      //输出整个单链表     s=head->next;     while (1) {         if (NULL==s) {             printf("\n");             break;         }         printf("%02d->",s->data);         s=s->next;     }      //从小到大排序     for (p=head;p!=NULL && p->next!=NULL;p=p->next) {         for (q=p->next;q!=NULL && q->next!=NULL;q=q->next) {             if (p->next->data > q->next->data) {                  //交换data //              printf("swap %02d %02d\n",p->next->data,q->next->data); //              t=p->next->data;p->next->data=q->next->data;q->next->data=t;                  //或者                  //交换next //              printf("swap %02d %02d\n",p->next->data,q->next->data);                 s1=p->next;                 s2=p->next->next;                 s3=q->next;                 s4=q->next->next;                  if (s2!=s3) {                      p->next=s3;                     s3->next=s2;                      q->next=s1;                     s1->next=s4;                 } else {                      p->next=s3;                     s3->next=s1;                            q=s3;                     s1->next=s4;                 }                  //输出整个单链表 //              s=head->next; //              while (1) { //                  if (NULL==s) { //                      printf("\n"); //                      break; //                  } //                  printf("%02d->",s->data); //                  s=s->next; //              } //              getchar();             }         }     }      //输出整个单链表     s=head->next;     while (1) {         if (NULL==s) {             printf("\n");             break;         }         printf("%02d->",s->data);         s=s->next;     }      //将单链表中前 m 个结点和后 n 个结点进行互换,m+n为链表总长10     m=4;     n=6;     k=0;     p=head;     while (1) {         if (NULL==p) {             break;         }         k++;         if (m+1==k) {             q=p;         }         s=p;         p=p->next;     }     s1=head->next;     head->next=q->next;     s->next=s1;     q->next=NULL;      //输出整个单链表     s=head->next;     while (1) {         if (NULL==s) {             printf("\n");             break;         }         printf("%02d->",s->data);         s=s->next;     }      //释放所有节点     p=head->next;     while (1) {         if (NULL==p) {             break;         }         q=p->next;         free(p);         p=q;     }      return 0; } //18->94->58->17->27->20->43->57->75->78-> //18->94->05->58->17->27->20->43->57->75->78-> //18->94->05->58->27->20->43->57->75->78-> //05->18->20->27->43->57->58->75->78->94-> //43->57->58->75->78->94->05->18->20->27-> //

你的create可以直接调用insert函数啊。

引用 4 楼 zhouda829829 的回复:逻辑混乱，我觉得你的creat()函数需要重新写。 那个我大体是按照教材上的来的。。。就是当时犯二了，以为函数返回至不能是传递过来的形参，你有什么好的修改意见么？跪求啊啊

引用 6 楼 angel_su 的回复:到处malloc，scanf容易出错，统一在insert里面做吧，main里单纯只是调用接口函数... 我的几个函数布局是按照教材上来的，高等教育出版社，c语言程序设计， 但是如果只在insert里有malloc的话 create就不好写了呀。。。

逻辑混乱，我觉得你的creat()函数需要重新写。

p你就分配了一个struct怎么能插多次

还有，望大神们来看看弱菜的编程风格或者这个程序本身哪里需要改进？？本弱菜定当感激涕零

刚才弱菜在不断的试验下，把main里面的 p的动态分配内存挪到了 do while 循环里面，case2 那句话那里，程序就变正常了，但是本弱菜觉得放在定义里省时省力而且没差啊，定义了一片内存空间以后，以后的p都在这块空间里写来写去不就好了？？！！ohno！！弱菜开窍了，那片空间是用来放一个学生的，不能省的。。。我去，弱菜就是弱菜。。。那这楼楼主自己来歪楼了，大家谈谈对链表，指针的认识吧，以及怎么不像lz一样犯二！！！


Question: C语言查找字符串中某字符第几次出现的位置

//给定字符串：this is java for you,java is good for programming! //打印最后一次出现字符串"for"的位置。 #include <stdio.h> #include <string.h> char s[]="this is java for you,java is good for programming!"; char f[]="for"; char *p,*q; int main() {     p=strstr(s,f);     if (NULL==p) {         printf("Can not find '%s' in '%s'!\n",f,s);     } else {         q=p+strlen(f);         while (1) {             p=strstr(q,f);             if (NULL==p) break;             q=p+strlen(f);         }         printf("The last location from 0 of '%s' in '%s' is %d.\n",f,s,q-s-strlen(f));     }     return 0; } //The last location from 0 of 'for' in 'this is java for you,java is good for programming!' is 34. //

问题已经解决了，不过还是很感谢你，而且您的这种方法对我也有启发。

对要查找的字符串反序，然后将标准的从前向后搜索子串的算法（比如KMP）改为从后向前，搜索反序后的那个字符串，即可。

参考http://see.xidian.edu.cn/cpp/html/174.html  引用 楼主 u013155036 的回复:给定字符串：this is java for you,java is good for programming! 打印最后一次出现字符串"for"的位置。 求完整代码

有个函数叫strstr


Question: 动态规划问题。

引用 2 楼 M173475237 的回复:[quote=引用 1 楼 sinservice 的回复:] 不懂。  我接触的动态规划，是指编译器代码生成技术的树匹配技术和动态规划，不理解主贴的意思。 嗯。我说的是算法中很重要的一种。。 也就是常说的DP。 那个方程也叫状态转移方程[/quote] 《算法导论》

引用 1 楼 sinservice 的回复:不懂。  我接触的动态规划，是指编译器代码生成技术的树匹配技术和动态规划，不理解主贴的意思。 嗯。我说的是算法中很重要的一种。。 也就是常说的DP。 那个方程也叫状态转移方程


Question: hist[*src++]++ 的执行顺序问题

引用 楼主 ysmz4 的回复:hist[*src++]++，之中好像没有顺序点。那么两个++哪个先执行？还是说都有可能？（如果都有可能，那么这个问题显得没意义） 本来是期待hist[*src]++；src++；但是懒得调了

第一个++ 操作数 src  第二个++ 操作数是hist[*src] 不是同一个对象 所以 谁先谁后 无所谓  也不会无意义

这么纠结。要么就写个程序调试看看，要么就不这么写。

自己去看置顶帖。 so没有意义的问题。

都有可能,因为没有冲突，所以也不属于未定义。 hist[*src++]++ 的值，为 hist[*src] ;两个++ 都不影响这个。


Question: 【具体数学】VS【算法导论】2选1如何选择？

前者是对问题建模的方法，后者是对已建模问题解决的方法。 相对来说，对初学者后者更实用，掌握以后能立刻感觉水平提高一个层次。 前者需要已经较高端的系统工程师/架构师才会用得上，对一般程序员有学了没用的感觉。  btw: 算法在 "其他技术论坛"->"高性能开发"

多啃几遍算法导论！ 如果不懂，再回头认真看下数据结构！

两本书的定位都不一样，有什么好比较的，基本如2楼所说。  《具体数学》可以算是kunth对自己的TAOCP的一个简单入门了，你如果打算学习TAOCP的话还是看看比较好。《算法导论》对一般程序员会更有用一些。