Question: 链表的内存越界问题

#include <stdio.h> #include <stdlib.h> #include <string.h>  char *getfileall(char *filename) { 	//将外部文件中的代码输入程序 	FILE *fp; 	char *str; 	char text[1000]; 	int filesize; 	if ((fp = fopen(filename, "r")) == NULL)  	{ 		printf("打开文件%s错误\n", filename); 		return NULL; 	} 	else 	{ 		fseek(fp, 0, SEEK_END);  		filesize = ftell(fp); 		str = (char *)malloc(filesize); 		str[0] = 0;  		rewind(fp); 		while ((fgets(text, 1000, fp)) != NULL) 		{ 			strcat(str, text); 		} 		fclose(fp); 		return str; 	} }  typedef struct node { 	char valuename[20]; 	int type; 	int ivalue; 	double dvalue; 	struct node *link; };  struct node * creat(struct node *p, struct node *h, struct node *s,int t, struct node *name[21]) { 	if ((s = (struct node *)malloc(sizeof(struct node) + sizeof(*name))) == NULL) /*分配空间并检测*/ 	{ 		printf("不能分配内存空间!"); 		exit(0); 	} 	p->link = s; /*把s的地址赋给p所指向的结点的链域，这样就把p和s所指向的结点连接起来了*/ 	strcpy(s->valuename, name); 	s->type = t; 	s->ivalue = 0; 	s->dvalue = 0.0; 	printf("%d%s", t,s->valuename); 	s->link = NULL; 	p = s; }  int main()  {  	int i = 0, j = 0, k = 0, l = 0, m = 0, a = 0;//j为行数，k为各行长度，i、l、m用于循环，a用以记录变量名 	char *code, code1[1000][1000] = { '\0' }; 	char *filename[20] = { '\0' }; 	gets(filename); 	code = getfileall(filename);  	//将一维代码按分号分割成二维 	for (i = 0; i < strlen(code); i++) 	{ 		if (code[i] == '\n' || code[i] == '\r') 		{ 			code[i] = ' '; 		} 	} 	for (i = 0; i < strlen(code); i++) 	{ 		if (code[i] == ';') 		{ 			code1[j][k] = code[i]; 			j++; 			k = 0; 		} 		else 		{ 			code1[j][k] = code[i]; 			k++; 		} 	} 	free(code);  	//对定义部分进行检测，将变量名输入并初始化对应数组内的空间 	struct node *p, *h, *s; /* *h保存表头结点的指针，*p指向当前结点的前一个结点，*s指向当前结点*/ 	char *name[21] = { '\0' }; 	int t; 	if ((h = (struct node *)malloc(sizeof(struct node))) == NULL) /*分配空间并检测*/ 	{ 		printf("不能分配内存空间!"); 		exit(0); 	} 	h->valuename[0] = '\0'; /*把表头结点的数据域置空*/ 	h->link = NULL; /*把表头结点的链域置空*/ 	p = h; /*p指向表头结点*/ 	s = NULL;  	for (i = 0; i < j; i++) 	{ 		if (strstr(code1[i], "int ") != NULL) 		{ 			name[21] = ""; 			for (l = 4; l < strlen(code1[i]); l++)                                             //此处改用指针以排除句首空格干扰 strstr返回值为‘i’的地址 			{ 				if (code1[i][l] != ' ' && code1[i][l] != ',' && code1[i][l] != ';') 				{ 					name[a] = code1[i][l]; 					a++; 				} 				else if (code1[i][l] == ',' || code1[i][l] == ';') 				{ 					a = 0; 					t = 0; 					creat(p, h, s, t, name); 					name[21] = ""; 				} 			} 		}		 		else if (strstr(code1[i], "double ") != NULL) 		{ 			name[21] = ""; 			for (l = 7; l < strlen(code1[i]); l++) 			{ 				if (code1[i][l] != ' ' && code1[i][l] != ',' && code1[i][l] != ';') 				{ 					name[a] = code1[i][l]; 					a++; 				} 				else if (code1[i][l] == ',' || code1[i][l] == ';') 				{ 					a = 0; 					t = 1; 					creat(p, h, s, t, name); 					name[21] = ""; 				} 			} 		} 		else 		{  		} 	} 	system("pause"); 	return 0; } 我剪一块0.0

全部有几百行0.0而且没写完

你倒是把代码上全啊

我这里过了 可能后来被我改得面目全非了ˊ_>ˋ

编译都通不过啊  strcpy(s->valuename, name); 这里的name是struct node *name[21]


Question: 指针指向问题

*（tempCmp+j）并没有将tempCmp进行移位，该命令执行之后对tempCmp产生影响


Question: 请教一个关于命令行参数的问题。

2 If they are declared, the parameters to the main function shall obey the following constraints: — The value of argc shall be nonnegative. — argv[argc] shall be a null pointer. — If the value of argc is greater than zero, the array members argv[0] through argv[argc-1] inclusive shall contain pointers to strings, which are given implementation-defined values by the host environment prior to program startup. The intent is to supply to the program information determined prior to program startup from elsewhere in the hosted environment. If the host environment is not capable of supplying strings with letters in both uppercase and lowercase, the implementation shall ensure that the strings are received in lowercase. — If the value of argc is greater than zero, the string pointed to by argv[0] represents the program name; argv[0][0] shall be the null character if the program name is not available from the host environment. If the value of argc is greater than one, the strings pointed to by argv[1] through argv[argc-1] represent the program parameters. — The parameters argc and argv and the strings pointed to by the argv array shall be modifiable by the program, and retain their last-stored values between program startup and program termination.

argc这个参数的值最小为1，即命令行下不输入任何参数的情况，此时argv数组里边就一个值，那就是该命令所在的路径构成的字符串。你的，明白？

你如果没有命令行的参数的话确实是1，为程序exe文件路径

DOS年代运行程序都是输入命令行的，由常驻内存的command.com这个DOS下命令解释器（类似Linux下的sh、bash）解释执行 比如： edit  a1.txt dir  /a  /w edit是外部命令，就是一个具体的程序名字，由command.com调用执行 dir是command.com的内部命令，直接执行它自身的部分代码 命令后面的就是命令的参数 如edit  a1.txt，argc==2, argv[0]=="edit", argv[1]=="a1.txt" 你也可以在命令行cmd（Win-R组合键，输入cmd运行）下运行你的程序，后面输入参数

你输入的决定的，所以叫命令行，你实际运行看看就明白多了。


Question: 多线程中，线程结束，主程序也结束了。

有时不将“调用函数名字＋各参数值，进入函数后各参数值，中间变量值，退出函数前准备返回的值，返回函数到调用处后函数名字＋各参数值＋返回值”这些信息写日志到文件中是无论如何也发现不了问题在哪里的，包括捕获各种异常、写日志到屏幕、单步或设断点或生成core文件、……这些方法都不行！ 写日志到文件参考下面： //循环向a函数每次发送200个字节长度（这个是固定的）的buffer, //a函数中需要将循环传进来的buffer，组成240字节（也是固定的）的新buffer进行处理， //在处理的时候每次从新buffer中取两个字节打印 #ifdef WIN32     #pragma warning(disable:4996) #endif #include <stdio.h> #include <stdlib.h> #include <string.h> #ifdef WIN32     #include <windows.h>     #include <process.h>     #include <io.h>     #define  MYVOID             void     #define  vsnprintf          _vsnprintf #else     #include <unistd.h>     #include <sys/time.h>     #include <pthread.h>     #define  CRITICAL_SECTION   pthread_mutex_t     #define  MYVOID             void * #endif //Log{ #define MAXLOGSIZE 20000000 #define MAXLINSIZE 16000 #include <time.h> #include <sys/timeb.h> #include <stdarg.h> char logfilename1[]="MyLog1.log"; char logfilename2[]="MyLog2.log"; static char logstr[MAXLINSIZE+1]; char datestr[16]; char timestr[16]; char mss[4]; CRITICAL_SECTION cs_log; FILE *flog; #ifdef WIN32 void Lock(CRITICAL_SECTION *l) {     EnterCriticalSection(l); } void Unlock(CRITICAL_SECTION *l) {     LeaveCriticalSection(l); } void sleep_ms(int ms) {     Sleep(ms); } #else void Lock(CRITICAL_SECTION *l) {     pthread_mutex_lock(l); } void Unlock(CRITICAL_SECTION *l) {     pthread_mutex_unlock(l); } void sleep_ms(int ms) {     usleep(ms*1000); } #endif void LogV(const char *pszFmt,va_list argp) {     struct tm *now;     struct timeb tb;      if (NULL==pszFmt||0==pszFmt[0]) return;     vsnprintf(logstr,MAXLINSIZE,pszFmt,argp);     ftime(&tb);     now=localtime(&tb.time);     sprintf(datestr,"%04d-%02d-%02d",now->tm_year+1900,now->tm_mon+1,now->tm_mday);     sprintf(timestr,"%02d:%02d:%02d",now->tm_hour     ,now->tm_min  ,now->tm_sec );     sprintf(mss,"%03d",tb.millitm);     printf("%s %s.%s %s",datestr,timestr,mss,logstr);     flog=fopen(logfilename1,"a");     if (NULL!=flog) {         fprintf(flog,"%s %s.%s %s",datestr,timestr,mss,logstr);         if (ftell(flog)>MAXLOGSIZE) {             fclose(flog);             if (rename(logfilename1,logfilename2)) {                 remove(logfilename2);                 rename(logfilename1,logfilename2);             }         } else {             fclose(flog);         }     } } void Log(const char *pszFmt,...) {     va_list argp;      Lock(&cs_log);     va_start(argp,pszFmt);     LogV(pszFmt,argp);     va_end(argp);     Unlock(&cs_log); } //Log} #define ASIZE    200 #define BSIZE    240 #define CSIZE      2 char Abuf[ASIZE]; char Cbuf[CSIZE]; CRITICAL_SECTION cs_HEX ; CRITICAL_SECTION cs_BBB ; struct FIFO_BUFFER {     int  head;     int  tail;     int  size;     char data[BSIZE]; } BBB; int No_Loop=0; void HexDump(int cn,char *buf,int len) {     int i,j,k;     char binstr[80];      Lock(&cs_HEX);     for (i=0;i<len;i++) {         if (0==(i%16)) {             sprintf(binstr,"%03d %04x -",cn,i);             sprintf(binstr,"%s %02x",binstr,(unsigned char)buf[i]);         } else if (15==(i%16)) {             sprintf(binstr,"%s %02x",binstr,(unsigned char)buf[i]);             sprintf(binstr,"%s  ",binstr);             for (j=i-15;j<=i;j++) {                 sprintf(binstr,"%s%c",binstr,('!'<buf[j]&&buf[j]<='~')?buf[j]:'.');             }             Log("%s\n",binstr);         } else {             sprintf(binstr,"%s %02x",binstr,(unsigned char)buf[i]);         }     }     if (0!=(i%16)) {         k=16-(i%16);         for (j=0;j<k;j++) {             sprintf(binstr,"%s   ",binstr);         }         sprintf(binstr,"%s  ",binstr);         k=16-k;         for (j=i-k;j<i;j++) {             sprintf(binstr,"%s%c",binstr,('!'<buf[j]&&buf[j]<='~')?buf[j]:'.');         }         Log("%s\n",binstr);     }     Unlock(&cs_HEX); } int GetFromRBuf(int cn,CRITICAL_SECTION *cs,FIFO_BUFFER *fbuf,char *buf,int len) {     int lent,len1,len2;      lent=0;     Lock(cs);     if (fbuf->size>=len) {         lent=len;         if (fbuf->head+lent>BSIZE) {             len1=BSIZE-fbuf->head;             memcpy(buf     ,fbuf->data+fbuf->head,len1);             len2=lent-len1;             memcpy(buf+len1,fbuf->data           ,len2);             fbuf->head=len2;         } else {             memcpy(buf     ,fbuf->data+fbuf->head,lent);             fbuf->head+=lent;         }         fbuf->size-=lent;     }     Unlock(cs);     return lent; } MYVOID thdB(void *pcn) {     char        *recv_buf;     int          recv_nbytes;     int          cn;     int          wc;     int          pb;      cn=(int)pcn;     Log("%03d thdB              thread begin...\n",cn);     while (1) {         sleep_ms(10);         recv_buf=(char *)Cbuf;         recv_nbytes=CSIZE;         wc=0;         while (1) {             pb=GetFromRBuf(cn,&cs_BBB,&BBB,recv_buf,recv_nbytes);             if (pb) {                 Log("%03d recv %d bytes\n",cn,pb);                 HexDump(cn,recv_buf,pb);                 sleep_ms(1);             } else {                 sleep_ms(1000);             }             if (No_Loop) break;//             wc++;             if (wc>3600) Log("%03d %d==wc>3600!\n",cn,wc);         }         if (No_Loop) break;//     } #ifndef WIN32     pthread_exit(NULL); #endif } int PutToRBuf(int cn,CRITICAL_SECTION *cs,FIFO_BUFFER *fbuf,char *buf,int len) {     int lent,len1,len2;      Lock(cs);     lent=len;     if (fbuf->size+lent>BSIZE) {         lent=BSIZE-fbuf->size;     }     if (fbuf->tail+lent>BSIZE) {         len1=BSIZE-fbuf->tail;         memcpy(fbuf->data+fbuf->tail,buf     ,len1);         len2=lent-len1;         memcpy(fbuf->data           ,buf+len1,len2);         fbuf->tail=len2;     } else {         memcpy(fbuf->data+fbuf->tail,buf     ,lent);         fbuf->tail+=lent;     }     fbuf->size+=lent;     Unlock(cs);     return lent; } MYVOID thdA(void *pcn) {     char        *send_buf;     int          send_nbytes;     int          cn;     int          wc;     int           a;     int          pa;      cn=(int)pcn;     Log("%03d thdA              thread begin...\n",cn);     a=0;     while (1) {         sleep_ms(100);         memset(Abuf,a,ASIZE);         a=(a+1)%256;         if (16==a) {No_Loop=1;break;}//去掉这句可以让程序一直循环直到按Ctrl+C或Ctrl+Break或当前目录下存在文件No_Loop         send_buf=(char *)Abuf;         send_nbytes=ASIZE;         Log("%03d sending %d bytes\n",cn,send_nbytes);         HexDump(cn,send_buf,send_nbytes);         wc=0;         while (1) {             pa=PutToRBuf(cn,&cs_BBB,&BBB,send_buf,send_nbytes);             Log("%03d sent %d bytes\n",cn,pa);             HexDump(cn,send_buf,pa);             send_buf+=pa;             send_nbytes-=pa;             if (send_nbytes<=0) break;//             sleep_ms(1000);             if (No_Loop) break;//             wc++;             if (wc>3600) Log("%03d %d==wc>3600!\n",cn,wc);         }         if (No_Loop) break;//     } #ifndef WIN32     pthread_exit(NULL); #endif } int main() { #ifdef WIN32     InitializeCriticalSection(&cs_log);     InitializeCriticalSection(&cs_HEX );     InitializeCriticalSection(&cs_BBB ); #else     pthread_t threads[2];     int threadsN;     int rc;     pthread_mutex_init(&cs_log,NULL);     pthread_mutex_init(&cs_HEX,NULL);     pthread_mutex_init(&cs_BBB,NULL); #endif     Log("Start===========================================================\n");      BBB.head=0;     BBB.tail=0;     BBB.size=0;  #ifdef WIN32     _beginthread((void(__cdecl *)(void *))thdA,0,(void *)1);     _beginthread((void(__cdecl *)(void *))thdB,0,(void *)2); #else     threadsN=0;     rc=pthread_create(&(threads[threadsN++]),NULL,thdA,(void *)1);if (rc) Log("%d=pthread_create %d error!\n",rc,threadsN-1);     rc=pthread_create(&(threads[threadsN++]),NULL,thdB,(void *)2);if (rc) Log("%d=pthread_create %d error!\n",rc,threadsN-1); #endif      if (!access("No_Loop",0)) {         remove("No_Loop");         if (!access("No_Loop",0)) {             No_Loop=1;         }     }     while (1) {         sleep_ms(1000);         if (No_Loop) break;//         if (!access("No_Loop",0)) {             No_Loop=1;         }     }     sleep_ms(3000);     Log("End=============================================================\n"); #ifdef WIN32     DeleteCriticalSection(&cs_BBB );     DeleteCriticalSection(&cs_HEX );     DeleteCriticalSection(&cs_log); #else     pthread_mutex_destroy(&cs_BBB);     pthread_mutex_destroy(&cs_HEX);     pthread_mutex_destroy(&cs_log); #endif     return 0; }

你把代码调整好，这没办法看……

int	__register_by_line(unsigned char prio) { 	int	ret; 	pthread_t	tid; 	PREGISTER_THREAD_ARG	thread_arg; printf("__register_by_line\n"); 	if(prio >= MAX_LINE_NUM)  		return 1; 	if(pthread_mutex_trylock(®ister_mutext[prio]) == EBUSY){ 	//	printf("register is locked!\n"); 		return 0; 	} 	if((thread_arg = malloc(sizeof(REGISTER_THREAD_ARG))) == NULL ) { 		pthread_mutex_unlock(®ister_mutext[prio]); 		Err_Msg(CMAN_ERR_NO_MEM, 1, "Malloc memeroy!\n"); 		return 1; 	} 	thread_arg->prio = prio; 	if((ret = pthread_create(&tid,NULL,®ister_thread, (void *)thread_arg)) != 0){ 		pthread_mutex_unlock(®ister_mutext[prio]); 		if(ret == EAGAIN)  { 			Err_Msg(0xff, 1, "Not enough system resource to create " 					" a process for the new thread!\n"); 		} else  { 			Err_Msg(0xff, 1, "more than %d threads are active!\n", 				PTHREAD_THREADS_MAX); 		} 		return ret; 	} printf("__register_by_line1\n"); 	return 0; } 这个是创建线程程序 void	*register_thread(void *thread_arg) { 	REGISTER_THREAD_ARG	arg;  	memcpy((void *)&arg, thread_arg, sizeof(arg)); 	free(thread_arg); 	pthread_detach(pthread_self()); 	 	register_main(arg.prio); 	pthread_mutex_unlock(®ister_mutext[arg.prio]);   	printf("xufeihu\n"); 	return (void *)0; } register_main(arg.prio)是线程函数。 打印可以看到xufeihu，然后整个程序就退出了。主进程是一个死循环。

代码贴出来啊


Question: doxygen无法生成CHM文件问题！！！！

楼主我现在也遇到了这个问题，生成的chm里没有内容。error.txt里记录错误为：error: failed to run html help compiler on index.hhp 请问你怎么解决的呀？

楼主，请问你的问题解决了吗？

引用 4 楼 user-6 的回复:网页生成了没有？  这个设置的没问题，但还是不行，生成的CHM文件没有内容

在chm文件上点鼠标右键、属性、安全、信任。

重点检查一下这个地方的设置：  Expert标签的HTML页面下， HHC_LOCATION，要选择HHC编译器的位置，可以选择win7自带的，路径为： C:/Program Files/HTML Help Workshop/hhc.exe

网页生成了没有？

生成了chm，但是无内容啊

Searching for include files... Searching for example files... Searching for images... Searching for dot files... Searching for msc files... Searching for dia files... Searching for files to exclude Searching for files to process... Searching for files in directory D:/workspace/img_Ta21V40_Ryb_20150706/BHApp_140523 Reading and parsing tag files Parsing files Building group list... Building directory list... Building namespace list... Building file list... Building class list... Associating documentation with classes... Computing nesting relations for classes... Building example list... Searching for enumerations... Searching for documented typedefs... Searching for members imported via using declarations... Searching for included using directives... Searching for documented variables... Building interface member list... Building member list... Searching for friends... Searching for documented defines... Computing class inheritance relations... Computing class usage relations... Flushing cached template relations that have become invalid... Creating members for template instances... Computing class relations... Add enum values to enums... Searching for member function documentation... Building page list... Search for main page... Computing page relations... Determining the scope of groups... Sorting lists... Freeing entry tree Determining which enums are documented Computing member relations... Building full member lists recursively... Adding members to member groups. Computing member references... Inheriting documentation... Generating disk names... Adding source references... Adding xrefitems... Sorting member lists... Computing dependencies between directories... Generating citations page... Counting data structures... Resolving user defined references... Finding anchors and sections in the documentation... Transferring function references... Combining using relations... Adding members to index pages... Generating style sheet... Generating example documentation... Generating file sources... Generating file documentation... Generating page documentation... Generating group documentation... Generating class documentation... Generating namespace index... Generating graph info page... Generating directory documentation... Generating index page... Generating page index... Generating module index... Generating namespace index... Generating namespace member index... Generating annotated compound index... Generating alphabetical compound index... Generating hierarchical class index... Generating member index... Generating file index... Generating file member index... Generating example index... finalizing index lists... writing tag file... Running dot... Running html help compiler... lookup cache used 0/65536 hits=0 misses=0 finished... *** Doxygen has finished

谁帮我回答一下，      这个软件对C没要求吧


Question: char *a='"qwer";  和 char[] = "qwer";的区别

char *a='"qwer" 编译会有告警

char *a = "qwer"; // 将一个常量指针赋值给a a[0] = 'a';  // 非法。因为a指针指向的是常量“qwer”，不允许修改  char a[] = "qwer"; // 在栈上分配5个字节的空间，并初始化为“qwer" （以'\0'结束） a[0] = 'a'; // 可以。

char *a = "qwer"; char a1 = *(a++); 这样是不行的 ； 而 char a[] = "qwer"; char a1 = *(a++); 才可以   您的意思是这样吗

常量和变量的区别


哎，没有更好的办法了么？不过还是感谢二位的回复，谢谢啦，散分！

你应该先生成  UCS2 的字符， 再转换回 UTF8 。

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


Question: 请问，为什么我在调试的时候会自动打开stdio.h，莫名其妙，然而可以正常执行，结果输出正常

因为你调试的时候进入stdio.h包含函数了，你没发现你的程序有问题？ for (i=b;putchar(ch[i])!='\0';i++); printf(",%c",ch[0]); for循环多了分号


Question: 统计包含0x00元素的数组个数问题？？？

既然初始化列表是你自己写的，那么最简单的：  int main(void){     char buf[100] = {0x7E,0x08,0x00,0x09,0x67,0x33};     int num=6;     printf("num=%d\n",num);     return 0; }

#include <stdio.h> #include <stdlib.h> int main(void){     char buf[100] = {0x7E,0x08,0x00,0x09,0x67,0x33};     int num=0,i = 0;     for(i=0;i<100;i++){         if(buf[i] != 0x33) {             num=num+1;             continue;         }         else             break;     }     num++;     printf("num=%d\n",num);     return 0; }

char buf[100] = {0x7E,0x08,0x00,0x09,0x67,0x33}; 	int count = sizeof(buf) / sizeof(buf[0]); 	while(count > 0) 	{ 		if(buf[count - 1]) break; 		--count; 	} 	printf("count = %d\n", count); 	return 0;

对啊，问题就在这，我是想有没有什么办法，改变一下if的判断条件，得到num=6的结果

你不是有一句叫if(buf[i] != '\0')，当然判断到0就结束了

那如何得到我想要的num=6 的结果啊

如果希望统计已经初始化的数据个数，那么没有任何手段可以统计出来 因为不确定你的数据中有没有 0这个数据

五楼的朋友我的必须是这样的：char buf[100] = {0x7E,0x08,0x00,0x09,0x67,0x33}; 不能把0x00放到最后

因为我的程序是有上文的， char buf[100]是不能变的，不能写成这位仁兄的unsigned char buf[] = {0x7E,0x08,0x00,0x09,0x67,0x33};  这种情况下，如何得到num=6 的结果

你能确定后面的全是0 ？ 那么可以统计最后一个非0数据。

看你程序的意思字符'\0'为结束字符, 但是你的声明如下: char buf[100] = {0x7E,0x08,0x00,0x09,0x67,0x33}; 第3个0x00就等'\0', 所以结果为2, 你把0x00放在最后面就可以统计了, 但是数据中不能包含0x00 char buf[100] = {0x7E,0x08,0x11,0x09,0x67,0x33,0x00};

unsigned char buf[] = {0x7E,0x08,0x00,0x09,0x67,0x33}; int size = sizeof(buf);

引用 2 楼 vshuo7013 的回复:我定义的数组buf是100个字节，如何算出它只有六个字节  它确实有 100 个元素，并不是只有六个元素。  这里只显式初始化了6个元素，其余元素其实也被初始化了。也就是说，buf 现在有 100 个已经初始化了的元素。

我定义的数组buf是100个字节，如何算出它只有六个字节

什么叫“实际元素个数”？


Question: 高手看看如何避免重复输出呢？

改好了  #include <stdio.h> char result[20]; int N = 0; void solve(int c, int t, int l, int d) {     int i = 1; 	if(d == l) 	{ 		result[ (l - 1) * 2 ]  = '+'; 		result[ (l - 1) * 2 + 1]  = '0' + N - t;         if(result[ (l - 1) * 2 + 1] >= result[ (l - 1) * 2 - 1])         {             for(i = 1; i < 20 ; i++)             {                 printf("%c",result[i]);             }             printf("\n");         }  	} 	else 	{  	   for(i = c;i + t < N ;i++) 	   { 		 result[(l - 1) * 2] = '+'; 		 result[(l - 1) * 2 + 1] = '0' + i;          solve(i, t + i, l + 1,d); 	   }  	} } void reset() { 	int i = 0; 	for(; i < 20; i++) 	{ 		result[i] = '\0'; 	} } int main() {     int i = 0; 	N = 10; 	printf("input number\n"); 	scanf("%d", &N); 	printf("\n"); 	for(i = 2; i <= N; i++) 	{ 		reset(); 		solve(1,0,1,i); 	} 	return 0; }

引用 3 楼 paschen 的回复:实现该算法的是时候加上一个条件：后一个数不能小于前一个数 明白了

从大到小也可以，总之按照升序或者降序即可

你只要按顺序分割就可以了 如果分割后，后面的数据比前面的小，那就是重复的，直接剪裁掉， 保证所有分割从小到大排列即可。

1: 5        2: 4 1        3: 3 2        4: 3 1 1        5: 2 2 1        6: 2 1 1 1        7: 1 1 1 1 1

实现该算法的是时候加上一个条件：后一个数不能小于前一个数

仅供参考：#include <stdio.h> #include <stdlib.h> void print(int res[], int num) {     static int L=0;     L++;     printf("%8d:",L);     for (int i=0;i<num;++i) {         printf(" %d", res[i]);     }     printf("\n"); } void split(int n, int m) {// n表示总数，m表示最大因子     static int res[100];// 保存结果     static int num=-1;// 当前因子下标      if (n<m || n<0 || m<1) return;     num++;     if (0==n) {// 递归终止条件，为0不可再分，直接输出         print(res,num+1);         num--;         return;     } else {         if (n==m) {// 不拆，直接输出             res[num]=m;             print(res,num+1);             num--;         } else {             // 拆分出第一个             res[num]=m;             n=n-m;              if (m>n) m = n; // 最大因子不可能大于总数              for (int i=m;i>=1;--i) {// 循环，第二个因子可以继续拆分，而且按照最大因子不同可以拆分成多个                 split(n,i);             }             num--;         }     } } void Split(int n) {     if (n<=0) return;     if (100<n) {         printf("Up to 100\n");         return;     }     for (int i=n;i>=1;--i) {         split(n, i);     } } void main(int argc,char **argv) {          if (argc<=1) Split(5);     else if (argc>=3) split(atoi(argv[1]),atoi(argv[2]));     else              Split(atoi(argv[1])); }

引用 1 楼 user-4 的回复:如果认为 2+3和3+2是一种情况 那么1+1+3和1+3+1和3+1+1是不是也认为是一种情况？  是啊，感觉很难去重


Question: 帮忙指出下列程序程序代码中的错误或不足，请说明原因

B的构造函数中， 1、没有对分配的空间进行初始化，可以用memset()。 2、没有对参数字符串的长度进行判断，传入的参数长度有可能会超过256。可以先取得长度，再分配空间。 3、对分配的内存有没有成功也没有判断。

为了代码安全

您能给我说说原因嘛？我才入门不是太懂，谢谢您啦

strcpy(m_buf,info);   应改为  strncpy(m_buf,info,255);  m_buf[255]=0;

谢谢了.....

用#include<iostream>  另外没有指定名字空间，所以cout要改成std::cout


Question: 求助 如何读取内存的中英文混合字符串

上面打错  memcpy(name, name_addr,10); 改成 strcpy(name, name_addr)

memcpy(name, name_addr,10); 改成 memcpy(name, name_addr)

仅供参考： void HexDump(char *buf,int len,int addr) {     int i,j,k;     char binstr[80];      for (i=0;i<len;i++) {         if (0==(i%16)) {             sprintf(binstr,"%08x -",i+addr);             sprintf(binstr,"%s %02x",binstr,(unsigned char)buf[i]);         } else if (15==(i%16)) {             sprintf(binstr,"%s %02x",binstr,(unsigned char)buf[i]);             sprintf(binstr,"%s  ",binstr);             for (j=i-15;j<=i;j++) {                 sprintf(binstr,"%s%c",binstr,('!'<buf[j]&&buf[j]<='~')?buf[j]:'.');             }             printf("%s\n",binstr);         } else {             sprintf(binstr,"%s %02x",binstr,(unsigned char)buf[i]);         }     }     if (0!=(i%16)) {         k=16-(i%16);         for (j=0;j<k;j++) {             sprintf(binstr,"%s   ",binstr);         }         sprintf(binstr,"%s  ",binstr);         k=16-k;         for (j=i-k;j<i;j++) {             sprintf(binstr,"%s%c",binstr,('!'<buf[j]&&buf[j]<='~')?buf[j]:'.');         }         printf("%s\n",binstr);     } }


Question: 出现runtime error 了 是代码问题还是?

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

出错的话最好自己设置断点调试一下

点重试，然后点中断，通过调用堆栈及变量监视窗口等观察分析出错原因

运行没发现错误啊


Question: 在vs2015社区版写了一段代码，编译通过，运行出错，没查出原因，跟IDE有关吗？

引用 6 楼 keith_bb 的回复:引用 2 楼 paschen 的回复:出错时断下看出错在哪分析原因错误就是这两张截图，特别是插入那个输出连续输出两个，而且第二个还是乱码，不应该啊  点重试，再点中断，通过调用规格与变量监视等窗口观察分析原因，从提示上说应该是buffer = NULL了，但你断言他不应该等于NULL

怎么出错法？

引用 3 楼 user-3 的回复:编译通过并不能证明程序就没有问题，比如一些逻辑性的错误，如除数为0，这样编译器是检查不出来 的，但是你运行的时候 就会出错对，我就是检查不出来，郁闷

引用 1 楼 relaxisland 的回复:怎么出错法？

出错时断下看出错在哪分析原因


Question: c语言算矩阵乘法，有的值算出来是负数，是溢出了吗？

楼上都是明白人啊，数组定义有问题，改了

代码功能归根结底不是别人帮自己看或讲解或注释出来的；而是被自己静下心来花足够长的时间和精力亲自动手单步或设断点或对执行到某步获得的中间结果显示或写到日志文件中一步一步分析出来的。 提醒：再牛×的老师也无法代替学生自己领悟和上厕所！ 单步调试和设断点调试（VS IDE中编译连接通过以后，按F10或F11键单步执行，按Shift+F11退出当前函数；在某行按F9设断点后按F5执行停在该断点处。）是程序员必须掌握的技能之一。  “多一少一”问题占程序员常犯错误的10%以上！ 避免“多一少一”问题的方法之一是将比如<10甚至<5的数代入程序片断，搬手指头心算验证一下程序到底应该写为 x、x-1、x+1中的哪个？ <、<=、==、>、>=中的哪个？

检查是否数组访问越界了

自己顶起，等待回复

自己顶起，等待回复

初学者，别嘲笑我啊

仅供参考：#include <stdio.h> #include <stdlib.h> #include <malloc.h> int **newarr2d(int rows,int cols) {     int **p,i;      p=(int **)malloc(rows*sizeof(int *));     if (NULL==p) exit(1);     for (i=0;i<rows;i++) {         p[i]=(int *)malloc(cols*sizeof(int));         if (NULL==p[i]) exit(1);     }     return p; } void deletearr2d(int **p,int rows) {     int i;      for (i=0;i<rows;i++) {         free(p[i]);     }     free(p); } int main() {     int **arr2d,i,j,r,c;      r=4;     c=5;     //在堆中开辟一个4×5的二维int数组     arr2d=newarr2d(r,c);     for (i=0;i<r;i++) {         for (j=0;j<c;j++) {             arr2d[i][j]=i*c+j;         }     }     for (i=0;i<r;i++) {         for (j=0;j<c;j++) {             printf(" %2d",arr2d[i][j]);         }         printf("\n");     }     deletearr2d(arr2d,r);      r=6;     c=3;     //在堆中开辟一个6×3的二维int数组     arr2d=newarr2d(r,c);     for (i=0;i<r;i++) {         for (j=0;j<c;j++) {             arr2d[i][j]=i*c+j;         }     }     for (i=0;i<r;i++) {         for (j=0;j<c;j++) {             printf(" %2d",arr2d[i][j]);         }         printf("\n");     }     deletearr2d(arr2d,r);      return 0; } //  0  1  2  3  4 //  5  6  7  8  9 // 10 11 12 13 14 // 15 16 17 18 19 //  0  1  2 //  3  4  5 //  6  7  8 //  9 10 11 // 12 13 14 // 15 16 17 //

数组的定义大小与真实大小不一致，导致数组越界。对于数组越界的问题，建议参考这篇帖子：http://bbs.csdn.net/topics/310083831

1）数组不能动态修改占用内存大小，和元素个数 2）数组越界，


Question: 请问C语言中，整型指针数组怎么获得结构中整型变量的地址

n 是结构体名称，需要一个结构体变量

因为在我感觉上，结构体就是把一些数据攒到一段连续内存里。也就是楼主的struct n 里面的a、b、c是在一段连续内存里，也就是有了a，那么b、c也就知道了，楼主平白多了一个指针数组来存储a、b、c，是不是多余呢？ 因为 struct n *struct_p; 一个指针变量就可以了，你想要a，可以用(*struct_p).a, 想要b，可以用(*struct_p).b

你需要有一个结构体对象，因为你结构体中的变量是属于对象的，也就是说每个对象都有一份a、b、c，如果按你这么写，编译器怎么知道你要的是哪个对象的  但你可以写成这样；  struct n var; p[0] = &var.a


Question: 遇到一个无符号与有符号比较的怪异问题

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

if(c1>uc1) 这句把c1与uc1都转换成了int， c1转换后是个负数，而uc1是正数，所以条件不成立，执行else  小于int的类型比较大小时，若类型不一致，会转换成int比较

在某个范围内的无符号数和有符号数，相同二进制，表示不相同的数。 所以千万别直接比较 无符号数和有符号数 除非知道数的范围

整数类型在进行比较的时候，都至少会提升（隐式类型转化; integral promotion）为 int （如果 int 可以提升前类型的所有值）或 unsigned int （如果 int 不能表示提升前类型的所有值）。（详细规则略） 这一提升对每一个操作数单独进行的，不考虑另一侧的操作数。  前两个比较都是两侧均提升为 int 进行的，因为 int 可以表示 char, unsigned char, short, unsigned short 的所有值。  最后一个，一侧为 int ，另一侧为 unsigned int 。（两侧提升独立进行，没有关系。这里实际都没有类型的转换）  此时，一个称作 usual arithmetic conversions 的转换将进行，将一侧的类型转换为另一侧的类型：在一侧为 signed T ，另一侧为 unsigned T 时，那么 signed T 类型将转换为 unsigned T 类型。（其它规则略）  所以最后一个比较，最终两侧都转换为 unsigned int 进行。  =========== 总结：不要比较 signed 和 unsigned 类型。最好比较前将其转换为同为 signed 或 同为 unsigned 类型。


Question: 请教一个回调函数返回的结构体指针能够直接赋值吗

p2=p1,这种形式只是浅拷贝，即只把结构体的指针拷贝了，而里面的数据地址并没有被拷贝，memcpy可以进行深拷贝，数据地址也会被拷贝

另外结构体赋值，如果是C++类差不多作用的结构体，内部的指针指向的数据，并没有被复制过来，而是直接bitcopy的指针。

struct xxx x; struct xxx y,*p1=y; struct xxx *p2=& x; call(callBack, p1);//这样就可以了，值在y中 x=*p1;//如果需要转储，可以这样 除非C版本低 结构体可以直接赋值

C语言下的结构体可以直接memcpy，把另一个结构体内存数据复制过来

memcpy这个我知道可以使用，但我想知道为什么传递不过去

使用 memcpy struct S{ };  memcpy(&d, &s, sizeof(struct S));


Question: 我是新手，弱弱问一句作业问题能问吗。。

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

引用 9 楼 paschen 的回复:[quote=引用 5 楼 qq_32874397 的回复:] [quote=引用 1 楼 paschen 的回复:] isspace(*p) 此时p所指的位置还没被初始过  你*p++; 这句的效果等价于 p++，如果你是要表示p所指的字符+1应该写成 (*p) ++我这个应该怎么改。。感觉懵圈了[/quote]  p++放到isspace后面？ 我不知你是想要什么效果[/quote] 不用指针我改了一下。 void input(char *p, int n) { int i; for(i=0;i<n;i++) { p[i]=getchar(); if(isspace(p[i]))  //为什么无效  break; } p[i+1]='\0'; } 但是为什么我那个不行还是搞不清。*p=getchar();*p++;这两行我是想输第一个字母指针指到下一个字母，然后循环又输入指到的这个字母，你们说的优先级的问题，查了下是同优先级，自右向左，按理说这程序应该不对，但运行起来却可以实现，只是没有遇到空格就不输出的这个功能。

引用 8 楼 weixin_30460121 的回复:for(i=0;i<n;i++) { *p=getchar(); if(isspace(*p))       break; p++; }试了下不行，感觉字符串的不能不用指针去自增。

引用 5 楼 qq_32874397 的回复:[quote=引用 1 楼 paschen 的回复:] isspace(*p) 此时p所指的位置还没被初始过  你*p++; 这句的效果等价于 p++，如果你是要表示p所指的字符+1应该写成 (*p) ++我这个应该怎么改。。感觉懵圈了[/quote]  p++放到isspace后面？ 我不知你是想要什么效果

引用 14 楼 paschen 的回复: #include <stdio.h> #include <ctype.h>  void input(char *p, int n); int main(void) { 	char shuzu[80] = {0}; int n; 	printf("a num:\n"); 	scanf("%d", &n); 	getchar(); 	input(shuzu, n); 	puts(shuzu); 	return 0; } void input(char *p, int n) { 	int i; 	for (i = 0; i < n; i++) 	{ 		*p = getchar(); 		if (isspace(*p++)) 			break; 	} } 好的，多谢版主

引用 4 楼 xusongge 的回复:虽然我是菜鸟，但我从头到尾看了一下楼主的代码，很混乱，你是主函数读取要打印的字符串然后传递到函数？好像不是！因为你主函数和函数部分都有getchar（），而且主函数部分还用错了。如果我写*p++这句话，我一定会写成（*p)++或*(p++)，因为我记不住哪个优先级高，根据实际需求加括号。。 input函数用来输入，主函数用来输出啊，主函数那个getchar()是为了消除回车符，为什么我也不知道，我是看的书上说的。

引用 2 楼 xusongge 的回复:getchar不是这样用的吧？你不把getchar得到的字符赋给一个变量？？？赋给指针为什么不行啊

引用 1 楼 paschen 的回复:isspace(*p) 此时p所指的位置还没被初始过  你*p++; 这句的效果等价于 p++，如果你是要表示p所指的字符+1应该写成 (*p) ++我这个应该怎么改。。感觉懵圈了

应该换成gets(shuzu)

getchar不是这样用的吧？你不把getchar得到的字符赋给一个变量？？？


Question: c语言

代码就如楼上所给，其实思想倒是挺简单的，proc函数只需要执行两个for循环就ok了。

#include <stdio.h>  #define M 5 int a[M][M];  void proc(int arr[][M]); void print(int arr[][M]); int main() { 	 	int i,j; 	for(i=0;i<M;i++) 		for(j=0;j<M;j++) 			a[i][j]=i+2*j; 	print(a); 	proc(a); 	print(a); 	getchar(); 	return 0; } void proc(int arr[][M]) { 	int i,j; 	for(i=0;i<M;i++) 		for(j=i;j<M;j++) 			arr[i][j]=0; } void print(int arr[][M]) { 	int i,j; 	for(i=0;i<M;i++){ 		for(j=0;j<M;j++) 			printf("%d ",arr[i][j]); 		printf("\n"); 	} }


Question: c语言

void proc(char a[], char b[], int n) { 	int i; 	char *p; 	i = 0; 	p = a; 	while (*p != *(a + n)) 		b[i++] = *p++; 	++p; 	while (*p) 		b[i++] = *p++; 	b[i] = '\0'; }


Question: 一道oj的题

按照上面的要求写了一下 void sort(int a[],int n) {     for(int i=1;i<n;i++){         int x=a[i],j=i-1;         for(;j>=0&&a[j]>x;j--) a[j+1]=a[j];         a[j+1] =x;     } } int find(int a[],int n,int value) {     for(int i=0;i<n;i++) if(a[i]==value) return i;     return -1; } void display(int a[],int n) {     printf("%d",a[0]);     for(int i=1;i<n;i++) printf(" %d",a[i]);     printf(".\n"); } void reverse(int a[],int n) {     for(int i=0,j=n-1;i<j;i++,j--){         int t=a[i];         a[i] =a[j];         a[j] =t;     } } void remove(int a[],int n,int pos) {     for(int i=pos+1;i<n;i++) a[i-1]=a[i]; } int main() {     int n,a[15],b[15],x;     scanf("%d",&n);     while(n--){         for(int i=0;i<10;i++) scanf("%d",a+i);         scanf("%d",&x);         bool handle=false;         int arraylen=10;         int pos=find(a,arraylen,x);         if(x&1){             handle =pos!=-1;             if(handle){                 remove(a,arraylen--,pos);                 sort(a,arraylen);             }         }else{             handle =pos==-1;             if(handle){                 a[arraylen++] =x;                 sort(a,arraylen);                 reverse(a,arraylen);             }         }         if(!handle){             int odd=0,even=9;             for(int i=0;i<arraylen;i++){                 if(a[i]&1) b[odd++] =a[i];                 else b[even--] =a[i];             }             memcpy(a,b,arraylen*sizeof(*a));             sort(a,odd);             reverse(a,odd);             sort(a+odd,arraylen-odd);             reverse(a+odd,arraylen-odd);         }         display(a,arraylen);     }     return 0; }

引用 1 楼 user-2 的回复:写个程序哪这么复杂。貌似还是Java风格。不得不吐槽下，你的变量没注释，而且命名很随意，读起来很晦涩 。。。什么叫java风格


Question: 求exec函数使用方法

仅供参考：/* EXEC.C illustrates the different versions of exec including:  *      _execl          _execle          _execlp          _execlpe  *      _execv          _execve          _execvp          _execvpe  *  * Although EXEC.C can exec any program, you can verify how   * different versions handle arguments and environment by   * compiling and specifying the sample program ARGS.C. See   * SPAWN.C for examples of the similar spawn functions.  */  #include <stdio.h> #include <conio.h> #include <process.h>  char *my_env[] =                /* Environment for exec?e */ {    "THIS=environment will be",    "PASSED=to new process by",    "the EXEC=functions",    NULL };  void main() {    char *args[4], prog[80];    int ch;     printf( "Enter name of program to exec: " );    gets( prog );    printf( " 1. _execl  2. _execle  3. _execlp  4. _execlpe\n" );    printf( " 5. _execv  6. _execve  7. _execvp  8. _execvpe\n" );    printf( "Type a number from 1 to 8 (or 0 to quit): " );    ch = _getche();    if( (ch < '1') || (ch > '8') )        exit( 1 );    printf( "\n\n" );     /* Arguments for _execv? */    args[0] = prog;    args[1] = "exec??";    args[2] = "two";    args[3] = NULL;     switch( ch )    {    case '1':       _execl( prog, prog, "_execl", "two", NULL );       break;    case '2':       _execle( prog, prog, "_execle", "two", NULL, my_env );       break;    case '3':       _execlp( prog, prog, "_execlp", "two", NULL );       break;    case '4':       _execlpe( prog, prog, "_execlpe", "two", NULL, my_env );       break;    case '5':       _execv( prog, args );       break;    case '6':       _execve( prog, args, my_env );       break;    case '7':       _execvp( prog, args );       break;    case '8':       _execvpe( prog, args, my_env );       break;    default:       break;    }     /* This point is reached only if exec fails. */    printf( "\nProcess was not execed." );    exit( 0 ); }

man exec中的6个函数


Question: 问个关于char与函数的小问题

错误提示不是已经写了，第一个没有初始化就直接用了，而第二个你用用户的输入初始化后才用的，所以没问题

很明显，第一个程序中的子函数word的输入ch未定义，故而出错。而第二个程序ch=ch=getchar()这句你是要干嘛？多此一举。


Question: 关于指针数组的问题

我也是新手，我觉得char是个很特殊的类型，特别是使用指针时，char*我感觉其实不只是char类型的指针，他更像是一个字符串，是一体的，

因为有%s.......

printf("%s\n", p[i]); 你都用%s了当然是打印字符串了

这个就是对指针的理解不够透彻了。 第一个问题，只要明白char** p与char* p[]等效，问题就不难理解了 第二个问题，指针的指向都发生改变了，那么内容自然就不同了。举个例子，如果A路通往北京，B路通往上海，现在我把两条路改修为A通往上海，B通往北京，那么两条路指向发生了改变，目的地也就不同了

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


Question: 下面C程序的输出结果是什么呢？谢谢老师们

作为新手我表示没有tab的代码看不下去

找个编译器试一下就知道了。

你这个代码对？ class B不继承A？ 继承A的话，多态，结果： Class B: 25

引用 2 楼 lm_whales 的回复:vitural void pick(int a = 1)； 重载的函数，不要重载缺省参数不要修改缺省参数

不要迷信书、考题、老师、回帖； 要迷信CPU、编译器、调试器、运行结果。 并请结合“盲人摸太阳”和“驾船出海时一定只带一个指南针。”加以理解。 任何理论、权威、传说、真理、标准、解释、想象、知识……都比不上摆在眼前的事实！  有人说一套做一套，你相信他说的还是相信他做的？ 其实严格来说这个世界上古往今来所有人都是说一套做一套，不是吗？  不要写连自己也预测不了结果的代码！


Question: 求解答一点都不懂

等于3啊，三目运算符，打好基础啊

a?b:c是c语言中少数几个三值运算符中的一个，该语句是个逻辑语句，执行过程为：若a为真则返回b，否则返回c

老实说，这种题目如果不能够懂的话，考试是真没的考

#include <stdio.h>  int main() {     int a = 10, b = 2, c = 3, d;      d = (b>c) ? a : c;     printf("d=%d\n", d);      return 0; 编译后，程序运行结果如下： d=3  ========== expression1 ? expression2 : expression3 称为条件表达式。它首先计算expression1，如果其值不等于0（为真），则计算expression2的值，并以该值作为条件表达式的值；否则计算expression3的值，并以该值作为条件表达式的值。 ? : 的优先级高于 = 的优先级，所以会先计算出 (b>c) ? a : c的值，再赋值给d。由于b>c为假，故条件表达式的值为c的值，即3.


Question: 大神帮我把这段C代码转换成汇编语言。

引用 4 楼 seanking1987 的回复:等我把头折成90度再来看看  有打出来的代码啊。

引用 5 楼 u011702993 的回复:[quote=引用 4 楼 seanking1987 的回复:] 等我把头折成90度再来看看  有打出来的代码啊。[/quote]  上个可以正常编译的代码来

来人

等我把头折成90度再来看看

代码编辑好，选择合适的编译器，编译输出汇编语言代码即可 如果需要名字可读性，手动改变编译器生成的名字。 几乎每个编译器都有这个功能。  人工翻译 的话，必须自己做，不然不会了解为何翻译成这个样子。

把代码输入后，在调试过程中通过反汇编窗口查看转换成的汇编代码，或者把生成的EXE文件用IDA等工具生成反汇编代码


Question: DSP28335响应中断后，CPU将IER清除，为什么还能继续响应中断？

楼主后来问题解决了嘛，我也有这个疑问

技术上是可以重入的，即便高优先级的中断，也可以在ISR中设置EOI，允许响应中断。

同一个中断总不允许重入吧。

可以，有特殊全嵌套方式，允许在中断处理中响应同级或更高级中断。

据我所知，相同优先级的中断是不能重入的。


Question: c程序求助

哦~原来真的有100分。。。

帮忙改错 谢谢

引用 2 楼 zhao4zhong1 的回复:#include<stdio.h> #include<string.h> void xianshi(); void game_ks(); void game_xuanze(int); char biaozhun[100]; char shuru[100]; int main() {     xianshi();     int xuanze;     scanf("%d",&xuanze)     game_xuanze(xuanze);     gets(shuru)     game_ks();     return 0; } //给用户展示 的内容 void xianshi() {     printf("这是一个指法练习");     printf("请选择游戏类型\n");     printf("1:数字练习\n");     printf("2:字母练习\n");     printf("3:字符练习\n");     printf("4:超强混合练习（敢来挑战么？）\n");     printf("其他键 默认练习\n"); } //游戏开始-选择(仅限1234) void game_xuanze(int x) {     switch (x) {     case '2': strcpy(biaozhun,"abcdefgABCDEFG"); break;     case '3': strcpy(biaozhun,"$*(&#@#$%^*())&%#@@");break;     case '4': strcpy(biaozhun,"$*(&#@#$%^AFHGDXJsd1234565432hxjxj*())&%#@@");break;     default: strcpy(biaozhun,"078276870"); break;     } } // 游戏开始 void game_ks() {     if(strcmp(shuru,biaozhun)==0) {         printf("you are right!完全正确\n");     }     else {         int n,i,fase=0;         float baifenlv=0.0;         n=strlen(shuru);         int n_biaozhun=strlen(biaozhun);         for (i=0;i<n && i<n_biaozhun;i++) {             if(biaozhun[i]!=shuru[i])                 fase++;         }         printf("输入字符个数%d\n",n);         printf("错误个数%d\n",fase);         baifenlv=(float)(n_biaozhun-fase)/n_biaozhun;         printf("正确率是%f%%\n",baifenlv*100.0);     } } 赵四罕见地不讲人生大道理了。哦~原来有100分。。。

game_xuanze 函数返回类型声明为char，但返回的是char[100]  game_ks函数中n_biaozhun没定义  biaozhun名字拼错了


Question: 有关C语言连字符##使用

#与##在宏定义中的--宏展开 #include <stdio.h> #define f(a,b) a##b #define g(a)   #a #define h(a) g(a) int main() {         printf("%s\n", h(f(1,2)));   // 12         printf("%s\n", g(f(1,2))); // f(1,2)         return 0; } 宏展开时： 如果宏定义以#开头，不展开参数，直接替换。 故g(f(1,2))--->#f(1,2)--->"f(1,2)"； 如果宏定义不以#开头，展开参数，直接替换，由外层向里层，如果碰到的是#开头的宏，不继续往里层展开，往外层展开。 由外层向里层，如果碰到的是以非#开头的宏，继续往里层走，直至最里层，开始一层层往外层展开。 故h(f(1,2))--->h(12)--->g(12)---->#12----->"12"。 PS： ##在宏中定义，是字符连接符 如a##b##c 等同于 "abc" #在宏开头出现，是表示宏展开的方式不同 #a 等同于"a" #abc 等同于 "abc" 复杂的: #include <stdio.h> #define f(a,b) a##b #define g(a)   #a #define h(a) g(a) int main() {         char a = 'a';         cout<<g(a)<<endl; // a         cout<<g(g(a))<<endl; // a         printf("%s\n", h(f(1,2)));   // 12         printf("%s\n", g(f(1,2))); // f(1,2)         printf("%s\n", g(h(f(1,2)))); // h(f(1,2))         printf("%s\n", h(g(f(1,2)))); // "f(1,2)"         printf("%s\n", h(h(f(1,2)))); // "12"         system("pause");         return 0; } 预处理后的：（在编译选项中添加/EP /P后编译生成的.i文件。gcc加-E） int main() {         char a = 'a';         cout<<"a"<<endl;         cout<<"g(a)"<<endl;         printf("%s\n", "12");         printf("%s\n", "f(1,2)");         printf("%s\n", "h(f(1,2))");         printf("%s\n", "\"f(1,2)\"");         printf("%s\n", "\"12\"");         system("pause");         return 0; } --------------------------------------------------- 宏解析 1.       ##操作符 ##操作符它的作用是在替代表中将其前后的参数连接成为一个预处理符号，它不能出现于宏替代表的开端和末尾。 例： #define concat(s,t) s##t #define AAA ABC concat(A, AA) 将被替换成 ABC 2.       重新扫描和替换 在替换列表中的所有参数替换过之后，预处理器将对结果token序列重新扫描以便对其中的宏再次替换。 当正在替换的宏在其替换列表中发现自身时，就不再对其进行替换。在任何正在嵌套替换的宏的替换过程中遇到正被替换的宏就对其不再进行替换（防止递归）。 例： #define ROOT AAA CCC #define AAA ROOT ROOT 将被替换成 ROOT CCC

引用 1 楼 user-2 的回复:## 只能用于宏替换的串里。不能用在其它地方。  你这个，直接去掉 ## 加个空格，编译器会自动拼接相邻的字符串。 哈哈，脑袋晕了。多谢。


Question: 大一小白求大神指教一下~

你的闰年的判断为什么要写个反的。应该判断是闰年的情况。 然后，你的闰年时，应该是month[1]=29 ，数组从0开始 再着，你的m从2开始，那不是无法统计1月份的日期了。你算天数的算法根本就是错的。  下面的应该是对的，你参考下。  #include <stdio.h> void main() { 	int year,day,d,m,leap; 	int month[12]={31,28,31,30,31,30,31,31,30,31,30,31}; 	printf("Input the year and day:\n"); 	scanf("%d",&year); 	scanf("%d",&day); 	if ((year%4==0&&year%100!=0)||(year%400==0))  		leap=1;	//是闰年  	else 		leap=0;	//不是闰年  	 	if (leap==1) 		month[1]=29; 		 	m=1; 	for (int i=0;i<12;i++) 	{ 		if (day>month[i]) 		{ 			day=day-month[i]; 			m++; 		}  		else 		{ 			d=day; 			break;	 		}		 	} 	 	printf("The date is :%d年%d月%d日",year,m,d);  }

求各位大神帮帮我啊！


Question: 求大神解答 关于文件的输入输出问题

不知道你想问什么，是想问输入的数据怎么读出来吗。 我加了个dat_read函数，不知道是不是要问这个。   #include <stdio.h> #include <stdlib.h> #define size 4 struct student_type {     char name[10];     int num;     int age; }stud[size],std[size]; void save() {     FILE *fp;     int i;     if((fp=fopen("student.dat","wb"))==NULL)     {         printf("error1");         exit(0);     }     for(i=0;i<4;i++)         if(fwrite(&stud[i],sizeof(struct student_type),1,fp)!=1)         printf("error2");     fclose(fp); }  void dat_read() {     FILE *fp;     int i;     if((fp=fopen("student.dat","rb"))==NULL)     {         printf("error1");         exit(0);     }	          for(i=0;i<4;i++)         if(fread(&std[i],sizeof(struct student_type),1,fp)!=1)         printf("error2");         else         {         	printf("%s-%d-%d\n",std[i].name,std[i].num,std[i].age); 		}     fclose(fp);  }    int main() {     int i;     for(i=0;i<size;i++)     {         scanf("%s%d%d",stud[i].name,&stud[i].num,&stud[i].age);     }         save();                  printf("-----输入的数据是--------\n"); 		          dat_read();                  return 0; }


Question: 求大神介绍一个支持win764位的C语言软件，谢谢了

Visual C++ 2010 Express简体中文版http://pan.baidu.com/s/1bnwRVLt

《深入理解C指针》这本书不错，当当或者亚马逊都有。 《C语言点滴》 《C语言课程设计案例精编》 C语言程序开发范例宝典 C语言经典编程282例  c primer plus 或者谭浩强 C语言程序设计：现代方法：第2版(被誉为"近10年来最好的一部C语言著作") C和指针

code::blocks


Question: 求大神帮助~

graphics.h是什么鬼, 以前tc的东西吗? 要么就认真学API, 没时间就搞一份网上的代码来自己编译,也当学习了

楼主你好，如果是Windows的话，可以用GDI做，用到有限的一些API函数借口，上百度一搜或者到MSDN查一下怎么传参就好了。

之前在控制台下写过扫雷

这样的一个小模块，你再网上搜一下，有好多类似的资源。挑挑拣拣，改一改就出来了。。。

说的好像所谓的"line"不是API一样


Question: fscanf问题！

引用 5 楼 zhao4zhong1 的回复:为什么不使用ftell函数呢？  想了解下文件指针指向的问题！求赵4老师 科普下！文件指针不是对文件调用一次 文件指针才++的吗？

为什么不使用ftell函数呢？

建议楼主去了解一下 全缓冲 行缓冲 不带缓冲

引用 2 楼 visp 的回复://  为什么多了这条fscanf程序没出错，但是上面的gets输入就白输了（输入时无错误回车正常结束），打开文件发现完全没变化， 加这条fscanf是会出错的，因为有缓冲的原因，数据没有写到文件里。但是数据指针已经到了最后，但是最后的数据又没有在文件里，所以fscanf就读不到数据，所以程序就出错了。所以你看到的文件就没有变量。 你在fprintf(fp, "%s", max);后加一个fflush(fp);就可以体会到了。 fprintf(fp, "%s", max)执行后，并没有把max的内容写到文件里。比如max有三个字符，这时文件指针却指到了这3个字符的位置。但是fscanf却读不到。 //好好体会下缓冲，和文件指针的位置。fprintf(fp, "%s", max)之后，加下面两句中的一条，你的程序都是对的。 fflush(fp); rewind(fp);   #include <stdio.h> #include <stdlib.h> int main() { int i = 0; FILE *fp; char max[50] = { 0 }; if((fp = fopen("kiss.txt", "a+"))==NULL) { printf("打开错误\n"); } printf("Re Input: "); gets(max); fprintf(fp, "%s", max); //好好体会下缓冲，和文件指针的位置。下面两句有一条，程序都是对的。不刷新的话，就把指针指到文件开头 fflush(fp); //rewind(fp); fscanf(fp,"%s",max); puts(max);   puts("**********"); fclose(fp);                      return 0; }    文件指针移动不是要对数据进行一次处理的时候文件指针才会指向下一个字节码？ fprintf(fp, "%s", max); 运行一次也会让文件指针++？那到底我运行时是++呢？还是+整个strlen（max）的字节？

ftell Gets the current position of a file pointer.  long ftell( FILE *stream );  Function Required Header Optional Headers Compatibility  ftell <stdio.h> <errno.h> ANSI, Win 95, Win NT    For additional compatibility information, see Compatibility in the Introduction.  Libraries  LIBC.LIB Single thread static library, retail version  LIBCMT.LIB Multithread static library, retail version  MSVCRT.LIB Import library for MSVCRT.DLL, retail version    Return Value  ftell returns the current file position. The value returned by ftell may not reflect the physical byte offset for streams opened in text mode, because text mode causes carriage return–linefeed translation. Use ftell with fseek to return to file locations correctly. On error, ftell returns –1L and errno is set to one of two constants, defined in ERRNO.H. The EBADF constant means the stream argument is not a valid file-handle value or does not refer to an open file. EINVAL means an invalid stream argument was passed to the function. On devices incapable of seeking (such as terminals and printers), or when stream does not refer to an open file, the return value is undefined.  Parameter  stream  Target FILE structure  Remarks  The ftell function gets the current position of the file pointer (if any) associated with stream. The position is expressed as an offset relative to the beginning of the stream.  Note that when a file is opened for appending data, the current file position is determined by the last I/O operation, not by where the next write would occur. For example, if a file is opened for an append and the last operation was a read, the file position is the point where the next read operation would start, not where the next write would start. (When a file is opened for appending, the file position is moved to end of file before any write operation.) If no I/O operation has yet occurred on a file opened for appending, the file position is the beginning of the file.  In text mode, CTRL+Z is interpreted as an end-of-file character on input. In files opened for reading/writing, fopen and all related routines check for a CTRL+Z at the end of the file and remove it if possible. This is done because using ftell and fseek to move within a file that ends with a CTRL+Z may cause ftell to behave improperly near the end of the file.   Example  /* FTELL.C: This program opens a file named FTELL.C  * for reading and tries to read 100 characters. It  * then uses ftell to determine the position of the  * file pointer and displays this position.  */  #include <stdio.h>  FILE *stream;  void main( void ) {    long position;    char list[100];    if( (stream = fopen( "ftell.c", "rb" )) != NULL )    {       /* Move the pointer by reading data: */       fread( list, sizeof( char ), 100, stream );       /* Get position after read: */       position = ftell( stream );       printf( "Position after trying to read 100 bytes: %ld\n",               position );       fclose( stream );    } }   Output  Position after trying to read 100 bytes: 100   Stream I/O Routines  See Also   fgetpos, fseek, _lseek, _tell

不要把 fopen("...","...");fscanf,fprintf,fgets,fgetc,fclose //读时把\r\n替换成\n，写时把\n替换成\r\n;读到\x1a就设置EOF;读写的内容当字符看待 和 fopen("...","...b");fseek,ftell,fread,fwrite,fgetc,fclose //不作以上替换，遇到\x1a仍继续读;读写的内容当字节看待 弄混了

引用 7 楼 paschen 的回复:http://blog.csdn.net/liu1164316159/article/details/10300343  感谢版主！

在程序中给max一个初值试试~


Question: C语言中while结果显示问题

前面从100开始的也输出了 只不过屏幕上存不下那么多行内容 不信你输出到文件试试 或者把MAX改小点

程序是对的没有问题 只是你要输出的东西太多了 输出框装不下了 所以在没有显示完 你把while(--count>0)改成while(--count>50)你就明白了


Question: #ifdef WIN32 的问题

WIN32/_WIN32 可以用来判断是否 Windows 系统（对于跨平台程序）， 对于64位不需要更改，你可以试试。 _WIN64 用来判断编译环境是 x86 还是 x64。

代表32-bit platform，而不是32位系统

百度的相关解答链接:为什么要定义 #ifdef WIN32 和#endif


Question: 跪求源代码！！用c语言设计实现一个模拟的通信录管理系统（信息系统）

估计没人会帮你写！ 论坛交流学习用的 不是帮你写程序用的，如果你有不懂的，哪里写不出来，有很多大神帮忙（虽然我不是），而不是拿到个问题，什么都不想，直接扔论坛了，这样你一辈子也写不出程序来（本人的想法）不好意思！好像说重了

这样的一个小模块，你再网上搜一下，有好多类似的资源。挑挑拣拣，改一改就出来了。。。很简单。


Question: 函数的数组地址

思考一下，为什么不把整个互联网内容当作函数参数传来传去呢？

当调用一个函数时，参数只是堆栈上的一个空间。  而数组是没有变量的。数组名只是一个地址而已。 你的情况就是，当呼叫函数时， 在堆栈上创建了一个变量，这个变量的内容就是数组的地址。  数组，地址，指针，指针变量。

当函数的参数包含有数组时，将被默认为该数组类型的指针，MAIN中调用函数时，应该是对应类型的指针奥！

其实吧 数组都会退化成指针！ 你那f(a); 其实传给形参int a[] 就是指针int*a指向了主函数里面a数组的首地址！

C/C++中如果是数组作为函数参数，数组将退化为指向数组首元素的指针，完全等价于void f(int* a)

形式参数都是变量

void f(int a[]) 与 void f(int *a)近似等价.

它不是真正的数组，它只是一个指针。


Question: 这是一个求助帖。C语言关于选择排序法的问题，求指教。

两个交换按理说是等价的

这两个交换是没什么区别，自己再去看看提交的程序是不是哪里写错了。比如把 i 和 j 给敲错了

有没有人回复啊？


Question: 如果一次只能读一个16位寄存器，如果读浮点数？

函数ReadHoldingRegister是否能返回地址？或者通过其它方式取得。。。 你可以取得前16位的地址，然后再在地址上+1,就能得到后16位值，然后你再把两个值整理成一个值就行了


Question: 开源库代码的官网，如何保证文件的没有被篡改？

楼上的这么牛B， 伪造个 Linus Torvalds 的 Key 给大家看看， 上面只有 100+ 个人签过名 .  给这个KEY签上不可导出的签名的人应该至少有几万吧。  从值得信任的渠道获得 他的 GPG KEY、指纹， 比如给项目 mail list 上的几个人发邮件要 ，并细验证指纹。 信任几个值得信任的 KEY， 按 GPG 的规则， 被你信任的几个 KEY 签过名的 KEY 会被信任。 如果你认识 某个人并能确认他的 KEY， 你应该给他签上可导出的签名， 并上传到 key server， 这样可以帮助别人验证。  重要的 KEY 总是有很多重要的人的签名， 不重要的也不会有啥人无聊的去伪造。

木马面前，没有安全。

up up

《黑客帝国》完全解析_知识库_博客园 《黑客帝国》里的锡安是不是虚拟世界_知识库_博客园


Question: 华为oj的坐标移动问题

解决这种string parse类问题的万灵丹是有限状态自动机。 参考《编译原理》中的词法分析和有限状态自动机。

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

引用 1 楼 zhao4zhong1 的回复:仅供参考：#include <stdio.h> char s[]="123 ab 4"; char *p; int v,n,k; void main() {     p=s;     while (1) {         k=sscanf(p,"%d%n",&v,&n);         printf("k,v,n=%d,%d,%d\n",k,v,n);         if (1==k) {             p+=n;         } else if (0==k) {             printf("skip char[%c]\n",p[0]);             p++;         } else {//EOF==k             break;         }     }     printf("End.\n"); } //k,v,n=1,123,3 //k,v,n=0,123,3 //skip char[ ] //k,v,n=0,123,3 //skip char[a] //k,v,n=0,123,3 //skip char[b] //k,v,n=1,4,2 //k,v,n=-1,4,2 //End. 更改了之后，我觉得很好了，为什么还是错误 #include <stdio.h> int main(void) {     int x=0,y=0,temp=0,k,n;     char first,check;     char string[100];     char *str;     gets(string);     str=string;     while(1)     {             k=sscanf(str,"%c%d%c%n",&first,&temp,&check,&n);             //putchar(first);            putchar(check);             printf("%d\n",temp);             printf("%d\n",k);             if(-1==k)                 break;             if((first==';')||(0==temp))//             {                 str++;                 //puts(str);                 continue;             }             else if(';'!=check)             {                 if(*str=='\n')                     break;                 while((*str++)!=';')                 continue;             }     if((k==3)&&(';'==check))     {          switch (first)         {             case 'A':x=x-temp;break;             case 'S':y=y-temp;break;             case 'D':x=x+temp;break;             case 'W':y=y+temp;break;         }         str+=n;         temp=0;           //puts(str);     }     else     {          break;     }     }     printf("%d,%d",x,y);     return 0;  }

引用 2 楼 github_27756899 的回复:[quote=引用 楼主 iuedui 的回复:]  题目大概就是这样，以下是我的代码 #include<stdio.h> int main(void) {     int x=0,y=0,temp=0;     char first,last;     while((first=getchar())!='\n')     {             if(scanf("%d",&temp)==0)             {                 while((last=getchar())!=';');                 continue;             }             last=getchar();             if(last=='\n')                break;             if(last!=';')             {                 while((last=getchar())!=';');                 continue;             }         switch (first)         {               case 'A':x=x-temp;break;             case 'S':y=y-temp;break;             case 'D':x=x+temp;break;             case 'W':y=y+temp;break;         }     }     printf("%d,%d",x,y);     return 0; }  但是代码有一个bug，就是最后输入两个';'时会卡在scanf那里等待一个数据输入 请问如何解决这个问题？             if(first == ';')   //添加的部分 			continue;       //添加的部分             if(scanf("%d",&temp)==0)             {                 while((last=getchar())!=';');                 continue;             }[/quote]代码贴进去，提示时间超限

引用 5 楼 zhao4zhong1 的回复:代码功能归根结底不是别人帮自己看或讲解或注释出来的；而是被自己静下心来花足够长的时间和精力亲自动手单步或设断点或对执行到某步获得的中间结果显示或写到日志文件中一步一步分析出来的。 提醒：再牛×的老师也无法代替学生自己领悟和上厕所！ 单步调试和设断点调试（VS IDE中编译连接通过以后，按F10或F11键单步执行，按Shift+F11退出当前函数；在某行按F9设断点后按F5执行停在该断点处。）是程序员必须掌握的技能之一。代码其实没有问题，但是确实有一个bug，就是输入最后没有加入";"的时候会出现问题，而华为的那个测试平台的一个测试用例正好是最后不加分号，所以我多加了一段程序，就是不论输入如何，都通过程序在最后加入一个分号再处理，最后提交后显示答案正确，谢谢赵老师了！

引用 楼主 iuedui 的回复: 题目大概就是这样，以下是我的代码 #include<stdio.h> int main(void) {     int x=0,y=0,temp=0;     char first,last;     while((first=getchar())!='\n')     {             if(scanf("%d",&temp)==0)             {                 while((last=getchar())!=';');                 continue;             }             last=getchar();             if(last=='\n')                break;             if(last!=';')             {                 while((last=getchar())!=';');                 continue;             }         switch (first)         {               case 'A':x=x-temp;break;             case 'S':y=y-temp;break;             case 'D':x=x+temp;break;             case 'W':y=y+temp;break;         }     }     printf("%d,%d",x,y);     return 0; }  但是代码有一个bug，就是最后输入两个';'时会卡在scanf那里等待一个数据输入 请问如何解决这个问题？             if(first == ';')   //添加的部分 			continue;       //添加的部分             if(scanf("%d",&temp)==0)             {                 while((last=getchar())!=';');                 continue;             }


Question: 请问C语言的结构体像这样初始化可以吗?

struct total a; memset((char *)&a,0,sizeof(a));

要让结构体初始为0，可以用memset函数

如果全零的话，可以 memset 。

#include <stdio.h> struct total { char name[20]; int money; char ch; }; int main() {     struct total a={0};      printf("%d\n",a.money);     return 0; }

定义对象，为每个成员分别赋值。

引用 3 楼 Kenier 的回复:定义对象，为每个成员分别赋值。   在定义结构的时候，不能初始化吗？

引用 1 楼 fefe82 的回复:在 C 语言里，这是不可以的。 引用 1 楼 fefe82 的回复:在 C 语言里，这是不可以的。   那应该怎样初始化呢?

在 C 语言里，这是不可以的。


Question: 菜鸟求助，C语言字符指针必须初始化？后面程序只是把字符指针当临时变量，不初始化提示错误？我有一个简单的程序，但我发现好多问题

引用 7 楼 zhao4zhong1 的回复:*temp=NULL; *temp=...;/将...的值保存到NULL即0地址处，操作系统不让你保存数据到0地址处。  char a; char *temp=&a;//将temp的值初始化为变量a所在地址。 *temp=...;/将...的值保存到temp的值对应地址处，即a变量对应内存地址处。那我这样做为什么还不对呢？char *temp="abc"  其余地方不变，还是运行出错

引用 10 楼 zhao4zhong1 的回复:char *temp="abc" ;//在默认不能写只能读的常量内存区分配4个字节并填写为0x61 0x62 0x63 0x00，然后将0x61所在地址赋值给变量temp。 *temp=...;//将...的值保存到temp的值对应地址处，即企图将...保存到前面0x61开始的地址处，操作系统不让。大哥，你解释的太清楚了，菜鸟的福音

你这个程序没必要使用指针啊，如果要使用，你又没有初始化，没有指定的内存空间肯定就报错啦。  如果非要用，你这个程序 只要加上char *temp=(char*)malloc(sizeof(char));就行了  结束时记得free(temp)

出错不要紧，关键是要学会调试

引用 2 楼 zhao4zhong1 的回复:#define _CRT_SECURE_NO_WARNINGS #include<stdio.h> #include<stdlib.h> #include<string.h> int main(void) {     int len, i, j;     char *temp ;//temp这个变量里面可以保存一个内存地址，从这个地址开始的若干字节当作char来看待     char arr[1025] = { 0 };//arr这个变量的值是一个内存地址，从这个内存地址开始预留1025个字节用来保存最多1025个char     gets(arr);     len = strlen(arr);     for (i = 0;i < len;i++)         for (j = i + 1;j < len;j++)         {             if (arr[i] > arr[j]&&arr[j]!=' ')             {                 *temp = arr[i];//由于temp的值没有初始化，可能是一个随机值，给*temp赋值，导致给这个随机值对应的地址处赋值                 arr[i] = arr[j];                 arr[j] = *temp;             }         }     puts(arr);     system("pause");     return 0; }   #define _CRT_SECURE_NO_WARNINGS #include<stdio.h> #include<stdlib.h> #include<string.h> int main(void) {     int len, i, j;     char temp ;//temp这个变量里面可以保存一个字节当作char来看待     char arr[1025] = { 0 };//arr这个变量的值是一个内存地址，从这个内存地址开始预留1025个字节用来保存最多1025个char     gets(arr);     len = strlen(arr);     for (i = 0;i < len;i++)         for (j = i + 1;j < len;j++)         {             if (arr[i] > arr[j]&&arr[j]!=' ')             {                 temp = arr[i];                 arr[i] = arr[j];                 arr[j] = temp;             }         }     puts(arr);     system("pause");     return 0; } 出错的位置还是*temp=arr[i]这句

引用 2 楼 zhao4zhong1 的回复:#define _CRT_SECURE_NO_WARNINGS #include<stdio.h> #include<stdlib.h> #include<string.h> int main(void) {     int len, i, j;     char *temp ;//temp这个变量里面可以保存一个内存地址，从这个地址开始的若干字节当作char来看待     char arr[1025] = { 0 };//arr这个变量的值是一个内存地址，从这个内存地址开始预留1025个字节用来保存最多1025个char     gets(arr);     len = strlen(arr);     for (i = 0;i < len;i++)         for (j = i + 1;j < len;j++)         {             if (arr[i] > arr[j]&&arr[j]!=' ')             {                 *temp = arr[i];//由于temp的值没有初始化，可能是一个随机值，给*temp赋值，导致给这个随机值对应的地址处赋值                 arr[i] = arr[j];                 arr[j] = *temp;             }         }     puts(arr);     system("pause");     return 0; }   #define _CRT_SECURE_NO_WARNINGS #include<stdio.h> #include<stdlib.h> #include<string.h> int main(void) {     int len, i, j;     char temp ;//temp这个变量里面可以保存一个字节当作char来看待     char arr[1025] = { 0 };//arr这个变量的值是一个内存地址，从这个内存地址开始预留1025个字节用来保存最多1025个char     gets(arr);     len = strlen(arr);     for (i = 0;i < len;i++)         for (j = i + 1;j < len;j++)         {             if (arr[i] > arr[j]&&arr[j]!=' ')             {                 temp = arr[i];                 arr[i] = arr[j];                 arr[j] = temp;             }         }     puts(arr);     system("pause");     return 0; } 不是输入数字没问题，是输入字符串如果顺序本来就正确就没问题，顺序不对还是会出问题

引用 2 楼 zhao4zhong1 的回复:#define _CRT_SECURE_NO_WARNINGS #include<stdio.h> #include<stdlib.h> #include<string.h> int main(void) {     int len, i, j;     char *temp ;//temp这个变量里面可以保存一个内存地址，从这个地址开始的若干字节当作char来看待     char arr[1025] = { 0 };//arr这个变量的值是一个内存地址，从这个内存地址开始预留1025个字节用来保存最多1025个char     gets(arr);     len = strlen(arr);     for (i = 0;i < len;i++)         for (j = i + 1;j < len;j++)         {             if (arr[i] > arr[j]&&arr[j]!=' ')             {                 *temp = arr[i];//由于temp的值没有初始化，可能是一个随机值，给*temp赋值，导致给这个随机值对应的地址处赋值                 arr[i] = arr[j];                 arr[j] = *temp;             }         }     puts(arr);     system("pause");     return 0; }   #define _CRT_SECURE_NO_WARNINGS #include<stdio.h> #include<stdlib.h> #include<string.h> int main(void) {     int len, i, j;     char temp ;//temp这个变量里面可以保存一个字节当作char来看待     char arr[1025] = { 0 };//arr这个变量的值是一个内存地址，从这个内存地址开始预留1025个字节用来保存最多1025个char     gets(arr);     len = strlen(arr);     for (i = 0;i < len;i++)         for (j = i + 1;j < len;j++)         {             if (arr[i] > arr[j]&&arr[j]!=' ')             {                 temp = arr[i];                 arr[i] = arr[j];                 arr[j] = temp;             }         }     puts(arr);     system("  [quote=引用 2 楼 zhao4zhong1 的回复:] [code=c]#define _CRT_SECURE_NO_WARNINGS #include<stdio.h> #include<stdlib.h> #include<string.h> int main(void) {     int len, i, j;     char *temp ;//temp这个变量里面可以保存一个内存地址，从这个地址开始的若干字节当作char来看待     char arr[1025] = { 0 };//arr这个变量的值是一个内存地址，从这个内存地址开始预留1025个字节用来保存最多1025个char     gets(arr);     len = strlen(arr);     for (i = 0;i < len;i++)         for (j = i + 1;j < len;j++)         {             if (arr[i] > arr[j]&&arr[j]!=' ')             {                 *temp = arr[i];//由于temp的值没有初始化，可能是一个随机值，给*temp赋值，导致给这个随机值对应的地址处赋值                 arr[i] = arr[j];                 arr[j] = *temp;             }         }     puts(arr);     system("pause");     return 0; }   #define _CRT_SECURE_NO_WARNINGS #include<stdio.h> #include<stdlib.h> #include<string.h> int main(void) {     int len, i, j;     char temp ;//temp这个变量里面可以保存一个字节当作char来看待     char arr[1025] = { 0 };//arr这个变量的值是一个内存地址，从这个内存地址开始预留1025个字节用来保存最多1025个char     gets(arr);     len = strlen(arr);     for (i = 0;i < len;i++)         for (j = i + 1;j < len;j++)         {             if (arr[i] > arr[j]&&arr[j]!=' ')             {                 temp = arr[i];                 arr[i] = arr[j];                 arr[j] = temp;             }         }     puts(arr);     system("pause");     return 0; } 我知道为什么一定要初始化了，是我理解错了，我认为是*temp被赋予了一个随机值，而不是temp被赋予了随机值。那为什么改为char *temp=NULL后，输入纯数字没有问题，输入数字加字母又出问题了呢？？

改为char temp不管输入什么都能得到正确结果，这是为什么？char temp和char *temp不是一样么？？？？？


Question: libxml2库 c语言生成xml时 添加 cdata标签

引用 8 楼 zhao4zhong1 的回复:http://blog.csdn.net/pwlazy/article/details/17273153   #include <stdio.h> #include <unistd.h> #include <sys/types.h> #include <stdlib.h>   #include <stdio.h> #include <libxml/parser.h> #include <libxml/tree.h> //gcc -o xmltest -I/usr/local/include/libxml2 -L/usr/local/lib -lxml2 xmltest.c int main() { 	int ret = -1; 	char *out = "hello &world"; 	xmlNodePtr node = NULL; 	//定义文档和节点指针  xmlDocPtr doc = xmlNewDoc(BAD_CAST "hello world 1.0"); 	xmlDocPtr doc = xmlNewDoc(BAD_CAST "1.0"); 	 	//创建一个新的结点，名字叫root 	xmlNodePtr root_node = xmlNewNode(NULL,BAD_CAST "root"); 	//设置根节点 	xmlDocSetRootElement(doc,root_node); 	 	//在doc中创建一个新的结点，文本内容是out指向的字符串 	node = 	xmlNewDocNode(doc, NULL, (const xmlChar*)"newNode4", out); 	//为root_node添加子结点node 	xmlAddChild(root_node,node); 	 	//为root_node添加子结点node5,内容为out字符串，返回值为一个xmlNodePtr指针 	node=xmlNewChild(root_node, NULL, (xmlChar *) "node5",(xmlChar *)out);  	int nRel = xmlSaveFormatFile ("greatexml.xml", doc, 1);  	if (nRel != -1) 	{ 		printf("一个xml文档被创建，写入%d个字节\n", nRel); 	} 	xmlFreeDoc(doc);  	return 1;  } 老师我直接上代码了，您老看看我这代码该怎么改吧！编译出来后执行就报错！ error : unterminated entity reference           world error : unterminated entity reference           world

引用 4 楼 zhao4zhong1 的回复://+-------------------------------------------------------------------------  //  //  Method:     CSpecialCharHashTable::CSpecialCharHashTable  //  //  Synopsis:   Constructor  //  //--------------------------------------------------------------------------    CSpecialCharHashTable::CSpecialCharHashTable()  {      for (unsigned i=0; i<SPECIAL_CHAR_HASH_TABLE_SIZE; i++)          _aHashTable[i] = 0;        //      // Initialize the table with various Ascii string->Unicode mappings      //        //      // For lt and gt, use Unicode chars from private use area to avoid      // collision with '<' and '>' chars in Html tags. These will be      // mapped back to '<' and '>' by the scanner.      //      Add(L"lt",      PRIVATE_USE_MAPPING_FOR_LT);      Add(L"gt",      PRIVATE_USE_MAPPING_FOR_GT);        Add(L"amp",     0x26);      Add(L"quot",    0x22);      Add(L"nbsp",    0xa0);      Add(L"shy",     0xad);      Add(L"Agrave",  0xc0);      Add(L"agrave",  0xe0);      Add(L"Aacute",  0xc1);      Add(L"aacute",  0xe1);      Add(L"Acirc",   0xc2);      Add(L"acirc",   0xe2);      Add(L"Atilde",  0xc3);      Add(L"atilde",  0xe3);      Add(L"Auml",    0xc4);      Add(L"auml",    0xe4);      Add(L"Aring",   0xc5);      Add(L"aring",   0xe5);      Add(L"AElig",   0xc6);      Add(L"aelig",   0xe6);      Add(L"Ccedil",  0xc7);      Add(L"ccedil",  0xe7);      Add(L"Egrave",  0xc8);      Add(L"egrave",  0xe8);      Add(L"Eacute",  0xc9);      Add(L"eacute",  0xe9);      Add(L"Ecirc",   0xca);      Add(L"ecirc",   0xea);      Add(L"Euml",    0xcb);      Add(L"euml",    0xeb);      Add(L"Igrave",  0xcc);      Add(L"igrave",  0xec);      Add(L"Iacute",  0xcd);      Add(L"iacute",  0xed);      Add(L"Icirc",   0xce);      Add(L"icirc",   0xee);      Add(L"Iuml",    0xcf);      Add(L"iuml",    0xef);      Add(L"ETH",     0xd0);      Add(L"eth",     0xf0);      Add(L"Ntilde",  0xd1);      Add(L"ntilde",  0xf1);      Add(L"Ograve",  0xd2);      Add(L"ograve",  0xf2);      Add(L"Oacute",  0xd3);      Add(L"oacute",  0xf3);      Add(L"Ocirc",   0xd4);      Add(L"ocirc",   0xf4);      Add(L"Otilde",  0xd5);      Add(L"otilde",  0xf5);      Add(L"Ouml",    0xd6);      Add(L"ouml",    0xf6);      Add(L"Oslash",  0xd8);      Add(L"oslash",  0xf8);      Add(L"Ugrave",  0xd9);      Add(L"ugrave",  0xf9);      Add(L"Uacute",  0xda);      Add(L"uacute",  0xfa);      Add(L"Ucirc",   0xdb);      Add(L"ucirc",   0xfb);      Add(L"Uuml",    0xdc);      Add(L"uuml",    0xfc);      Add(L"Yacute",  0xdd);      Add(L"yacute",  0xfd);      Add(L"THORN",   0xde);      Add(L"thorn",   0xfe);      Add(L"szlig",   0xdf);      Add(L"yuml",    0xff);      Add(L"iexcl",   0xa1);      Add(L"cent",    0xa2);      Add(L"pound",   0xa3);      Add(L"curren",  0xa4);      Add(L"yen",     0xa5);      Add(L"brvbar",  0xa6);      Add(L"sect",    0xa7);      Add(L"die",     0xa8);      Add(L"copy",    0xa9);      Add(L"laquo",   0xab);      Add(L"reg",     0xae);      Add(L"macron",  0xaf);      Add(L"deg",     0xb0);      Add(L"plusmn",  0xb1);      Add(L"sup2",    0xb2);      Add(L"sup3",    0xb3);      Add(L"acute",   0xb4);      Add(L"micro",   0xb5);      Add(L"para",    0xb6);      Add(L"middot",  0xb7);      Add(L"cedil",   0xb8);      Add(L"supl",    0xb9);      Add(L"raquo",   0xbb);      Add(L"frac14",  0xbc);      Add(L"frac12",  0xbd);      Add(L"frac34",  0xbe);      Add(L"iquest",  0xbf);      Add(L"times",   0xd7);      Add(L"divide",  0xf7);  }     万能的赵老师能不能讲的详细点！

没人回答么！！！！大神去哪里了！？

引用 1 楼 user-3 的回复:&  & 你这什么意思能不能讲明白点谢谢！


Question: 线段树为什么就Memory Limit Exceeded

用数组会超时

为什么不直接用数组呢？


Question: 大神们求帮助

传说中的伸手党！ //回复可查看

什么都不做来求代码？


Question: C语言编译遇到window.h问题

偶遇到类似问题都是用 “每次用/*...*/注释掉不同部分再重新编译，直到定位到具体语法出错的位置。” 的方法解决的。

引用 3 楼 ytpvip 的回复:[quote=引用 1 楼 paschen 的回复:] 是windows.h，不是window.h，另试下改变windows.h这个头文件包含顺序，放到所有包含文件的最前或者最后试一下    可是我头文件就没有#include “Windows.h”[/quote]  #include <Windows.h>

还有winnt.h。我用13的，选中输入的词就可以转到定义，10的我不太熟悉。

你打开编译器查看 driverspecs.h里面具体宏定义，根据行号找就可以了。

c:\program files\microsoft sdks\windows\v7.0a\include\driverspecs.h(142): error C2008: “$”: 宏定义中的意外 1>c:\program files\microsoft sdks\windows\v7.0a\include\driverspecs.h(294): error C2008: “$”: 宏定义中的意外 1>c:\program files\microsoft sdks\windows\v7.0a\include\driverspecs.h(295): warning C4005: “__”: 宏重定义 1>          c:\program files\microsoft sdks\windows\v7.0a\include\driverspecs.h(142) : 参见“__”的前一个定义 1>c:\program files\microsoft sdks\windows\v7.0a\include\driverspecs.h(308): error C2008: “$”: 宏定义中的意外 1>c:\program files\microsoft sdks\windows\v7.0a\include\driverspecs.h(309): warning C4005: “__”: 宏重定义 1>          c:\program files\microsoft sdks\windows\v7.0a\include\driverspecs.h(295) : 参见“__”的前一个定义 1>c:\program files\microsoft sdks\windows\v7.0a\include\driverspecs.h(312): error C2008: “$”: 宏定义中的意外 1>c:\program files\microsoft sdks\windows\v7.0a\include\driverspecs.h(313): warning C4005: “__”: 宏重定义 1>          c:\program files\microsoft sdks\windows\v7.0a\include\driverspecs.h(309) : 参见“__”的前一个定义 1>c:\program files\microsoft sdks\windows\v7.0a\include\driverspecs.h(316): error C2008: “$”: 宏定义中的意外 1>c:\program files\microsoft sdks\windows\v7.0a\include\driverspecs.h(317): warning C4005: “__”: 宏重定义 1>          c:\program files\microsoft sdks\windows\v7.0a\include\driverspecs.h(313) : 参见“__”的前一个定义 1>c:\program files\microsoft sdks\windows\v7.0a\include\driverspecs.h(320): error C2008: “$”: 宏定义中的意外 1>c:\program files\microsoft sdks\windows\v7.0a\include\driverspecs.h(321): warning C4005: “__”: 宏重定义 1>          c:\program files\microsoft sdks\windows\v7.0a\include\driverspecs.h(317) : 参见“__”的前一个定义 1>c:\program files\microsoft sdks\windows\v7.0a\include\winnt.h(1202): error C2018: 未知字符“0x24” 1>c:\program files\microsoft sdks\windows\v7.0a\include\winnt.h(1202): error C2061: 语法错误: 标识符“drv_group” 1>c:\program files\microsoft sdks\windows\v7.0a\include\winnt.h(1202): error C2059: 语法错误:“;”     错误警告如上

引用 1 楼 paschen 的回复:是windows.h，不是window.h，另试下改变windows.h这个头文件包含顺序，放到所有包含文件的最前或者最后试一下    可是我头文件就没有#include “Windows.h”


Question: 如何用C连续的执行命令并且获得命令的输出？

引用 6 楼 zhao4zhong1 的回复:仅供参考：#pragma comment(lib,"user32") #include <stdio.h> #include <windows.h> int main() {     SECURITY_ATTRIBUTES sa          = {0};     STARTUPINFO         si          = {0};     PROCESS_INFORMATION pi          = {0};     HANDLE              hPipeOutputRead  = NULL;     HANDLE              hPipeOutputWrite = NULL;     HANDLE              hPipeInputRead   = NULL;     HANDLE              hPipeInputWrite  = NULL;     BOOL                bTest = 0;     DWORD               dwNumberOfBytesRead = 0;     DWORD               dwNumberOfBytesWrite = 0;     CHAR                szMsg[100];     CHAR                szBuffer[256];      sa.nLength = sizeof(sa);     sa.bInheritHandle = TRUE;     sa.lpSecurityDescriptor = NULL;      // Create pipe for standard output redirection.     CreatePipe(&hPipeOutputRead,  // read handle             &hPipeOutputWrite, // write handle             &sa,      // security attributes             0      // number of bytes reserved for pipe - 0 default             );      // Create pipe for standard input redirection.     CreatePipe(&hPipeInputRead,  // read handle             &hPipeInputWrite, // write handle             &sa,      // security attributes             0      // number of bytes reserved for pipe - 0 default             );      // Make child process use hPipeOutputWrite as standard out,     // and make sure it does not show on screen.     si.cb = sizeof(si);     si.dwFlags     = STARTF_USESHOWWINDOW | STARTF_USESTDHANDLES;     si.wShowWindow = SW_HIDE;     si.hStdInput   = hPipeInputRead;     si.hStdOutput  = hPipeOutputWrite;     si.hStdError   = hPipeOutputWrite;      CreateProcess (           NULL, "cmd.exe",           NULL, NULL,           TRUE, 0,           NULL, NULL,           &si, &pi);      // Now that handles have been inherited, close it to be safe.     // You don't want to read or write to them accidentally.     CloseHandle(hPipeOutputWrite);     CloseHandle(hPipeInputRead);      // Now test to capture DOS application output by reading     // hPipeOutputRead.  Could also write to DOS application     // standard input by writing to hPipeInputWrite.     sprintf(szMsg, "dir *.txt /b\nexit\n");     WriteFile(           hPipeInputWrite,      // handle of the write end of our pipe           &szMsg,               // address of buffer that send data           18,                   // number of bytes to write           &dwNumberOfBytesWrite,// address of number of bytes read           NULL                  // non-overlapped.           );      while(TRUE)     {        bTest=ReadFile(           hPipeOutputRead,      // handle of the read end of our pipe           &szBuffer,            // address of buffer that receives data           256,                  // number of bytes to read           &dwNumberOfBytesRead, // address of number of bytes read           NULL                  // non-overlapped.           );        if (!bTest){           sprintf(szMsg, "Error #%d reading pipe.",GetLastError());           MessageBox(NULL, szMsg, "WinPipe", MB_OK);           break;       }        // do something with data.       szBuffer[dwNumberOfBytesRead] = 0;  // null terminate       MessageBox(NULL, szBuffer, "WinPipe", MB_OK);     }      // Wait for CONSPAWN to finish.     WaitForSingleObject (pi.hProcess, INFINITE);      // Close all remaining handles     CloseHandle (pi.hProcess);     CloseHandle (hPipeOutputRead);     CloseHandle (hPipeInputWrite);      return 0; }  现在有一个基础的思路是在程序创建子进程而后子进程执行bash命令，等待输入。 而后将子进程的输入输出流重定向到父进程的相应文件描述符，以此来达到目的。

用system？ system("ls -l > test.txt");

bash是开源的。

动态库链接，每条命令作为一个接口。或者干脆弄个脚本语言调用系统接口函数

//用命令行方式检测 BOOL PingIPByCmd(CString& strIP) { 	 	DWORD dwStartTicks,dwEndTicks, dwParseTime_ms; 	 	dwStartTicks = GetTickCount(); 	//常量 	CString strCmd ; 	//CString strEnSearch = _T("请求超时");  	std::string strChSearch1 = "请求超时"; 	std::string strChSearch2 = "找不到主机"; 	strCmd.Format(_T("ping %s"), strIP);  	BOOL bret; 	SECURITY_ATTRIBUTES sa;  	sa.nLength = sizeof(SECURITY_ATTRIBUTES);  	sa.lpSecurityDescriptor = NULL;  	sa.bInheritHandle = TRUE;   	//创建管道 	HANDLE hReadPipe,hWritePipe;  	bret = CreatePipe(&hReadPipe, &hWritePipe, &sa, 0); 	if(!bret) 	{ 		return FALSE; 	}  	//控制命令行窗口信息 	STARTUPINFO si;  	//返回进程信息 	PROCESS_INFORMATION pi;   	si.cb = sizeof(STARTUPINFO);  	GetStartupInfo(&si);  	si.hStdError = hWritePipe;  	si.hStdOutput = hWritePipe;  	si.wShowWindow = SW_HIDE; //隐藏命令行窗口 	si.dwFlags = STARTF_USESHOWWINDOW | STARTF_USESTDHANDLES;  	//创建获取命令行进程 	bret = CreateProcess(NULL, strCmd.GetBuffer(), NULL, NULL, TRUE, 0, NULL, NULL, &si, &pi ); 	strCmd.ReleaseBuffer(); 	if (!bret)  	{  		CloseHandle(hWritePipe); 		return FALSE; 	}  	WaitForSingleObject (pi.hProcess, INFINITE);  	unsigned long count;  	char szBuffer[512]; //放置命令行输出缓冲区 	memset(szBuffer, 0x00, 512); 	bret = ReadFile(hReadPipe, szBuffer,511, &count, 0);  	//关闭所有的句柄 	CloseHandle(hWritePipe); 	CloseHandle(pi.hProcess);  	CloseHandle(pi.hThread);  	CloseHandle(hReadPipe);  	// 读取失败返回 	if(!bret) 	{		 		return FALSE; 	}  	// 分析获取MAC 	std::string strBuffer = szBuffer;	 	int  ipos1 =0, ipos2 =0; 	ipos1= strBuffer.find(strChSearch1,ipos1); 	ipos2 = strBuffer.find(strChSearch1,ipos2);   	dwEndTicks = GetTickCount();  	// 计算时长  	if (dwEndTicks < dwStartTicks)  	{  		dwParseTime_ms = (0xFFFFFFFF - dwStartTicks + dwEndTicks + 1);  	}  	else  	{  		dwParseTime_ms = (dwEndTicks - dwStartTicks)+1;  	}  	dwParseTime_ms= dwParseTime_ms/1000; 	wcout<<dwParseTime_ms<<endl;  	if (ipos1>0 && ipos2  >0 ) 	{ 		return FALSE; 	} 	return TRUE; } 不知道我的可以不

引用 1 楼 zhao4zhong1 的回复:bash是开源的。 查了一天的terminal,bash,shell有点晕。。。


char *str="ABCDEFG";     char *substr="CDE"; /*返回指针的函数*/  字符存储在常量区，不可以被修改

指针不要这样初始化，因为常量存放在程序的一块常量区域，用字符串初始化指针会让指针指向常量区域，一修改就会导致内存错误，改用数组

char *str="ABCDEFG";  改成  char str[100]="ABCDEFG";


Question: 新人求助，C语言用malloc出现读取位置冲突，一直找不到原因，求大神，我把代码贴出来，二楼说一下题目

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

这一中：pResult[i][0] = pResult[i - 1][0] + i;   在第一次循环的时候，i 是0 ，那么会访问到i-1项数组当然出错了

引用 2 楼 xusongge 的回复:55555555，我自己居然会犯这么傻 的问题，单步调试发现原因是i=0的原因 哈哈，这种问题谁也免不了的，可以养成写0==i的习惯，这样会直接报错，不用再单步找原因了

55555555，我自己居然会犯这么傻 的问题，单步调试发现原因是i=0的原因

题目是输入一个数字，比如5，输出结果是 1 3 6 10 15 2 5 9 14 4 8 13 7 12 11 是华为在线软件测试平台上的一个题目，叫蛇形矩阵，我用malloc做，不用固定数组大小的方法，求大神解决问题


Question: 怎么用二维数组计算这天是一年中的第几天呢

引用 2 楼 qq_33131973 的回复:[quote=引用 1楼赵4老师 的回复:]COleDateTime::GetDayOfYear int GetDayOfYear( ) const;  Return Value  The day of the year represented by the value of this COleDateTime object.  Remarks  Call this member function to get the day of the year represented by this date/time value.   The COleDateTime class handles dates from 1 January 100 – 31 December 9999.看不懂…[/quote] #include <afxdisp.h> #include <stdio.h> int main() {     COleDateTime t=COleDateTime::GetCurrentTime();     CString s=t.Format(_T("%Y-%m-%d"));     _tprintf(_T("%s %d\n"),s,t.GetDayOfYear());     return 0; } //2015-12-02 336 //

引用 6 楼 qq_33131973 的回复:[quote=引用 3楼chehw_1 的回复:] #include<stdio.h>  int main(int argc, char ** argv) { 	int y, m, d; 	static int n[2][12] = { 		//	 1	2	3	4	5	  6		7	8	 9	  10,  11, 12	 			{0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334}, // 平年 			{0, 31, 60, 91, 121, 152, 182, 213, 244, 275, 305, 335}  // 闰年 		}; 	int flag; 	 	while(1) 	{ 		printf("yyyy-mm-dd: ");	 		scanf("%d-%d-%d", &y, &m, &d); 		 		flag = (((y % 400) == 0) || ((y % 100) && ((y % 4) == 0)))?1:0; 		if(m > 12 || m <= 0) 		{ 			fprintf(stderr, "invalid month value.\n"); 			continue; 		}else if((d > (n[flag][m] - n[flag][m - 1])) || (d < 1)) 		{ 			fprintf(stderr, "invalid day value.\n"); 			continue; 		} 		 		 		break; 	} 	 	 	int n_day = n[flag][m - 1] + d; 	 	printf("n_day = %d\n", n_day); 	 	return 0; } 你这样更长了啊，别人说用二维数组代码会更短一点[/quote]  我额外增加了判断月和日的输入的数字是否有效性。  另外，使用二维数组，不是让代码更短，而是减少代码执行的步骤，用空间换取时间。（加法运算的次数减少了）

引用 4楼user-3 的回复:flag的判定看着蛋疼怎么办？楼主你少了判定输入是否有效的环节。一维数组也好用啊，增加一个判断if(flag&&b>2) {....... c+=1;}不用啊，flag那行把输出的值直接加进第二个月了

引用 3楼chehw_1 的回复: #include<stdio.h>  int main(int argc, char ** argv) { 	int y, m, d; 	static int n[2][12] = { 		//	 1	2	3	4	5	  6		7	8	 9	  10,  11, 12	 			{0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334}, // 平年 			{0, 31, 60, 91, 121, 152, 182, 213, 244, 275, 305, 335}  // 闰年 		}; 	int flag; 	 	while(1) 	{ 		printf("yyyy-mm-dd: ");	 		scanf("%d-%d-%d", &y, &m, &d); 		 		flag = (((y % 400) == 0) || ((y % 100) && ((y % 4) == 0)))?1:0; 		if(m > 12 || m <= 0) 		{ 			fprintf(stderr, "invalid month value.\n"); 			continue; 		}else if((d > (n[flag][m] - n[flag][m - 1])) || (d < 1)) 		{ 			fprintf(stderr, "invalid day value.\n"); 			continue; 		} 		 		 		break; 	} 	 	 	int n_day = n[flag][m - 1] + d; 	 	printf("n_day = %d\n", n_day); 	 	return 0; } 你这样更长了啊，别人说用二维数组代码会更短一点

引用 1楼赵4老师 的回复:COleDateTime::GetDayOfYear int GetDayOfYear( ) const;  Return Value  The day of the year represented by the value of this COleDateTime object.  Remarks  Call this member function to get the day of the year represented by this date/time value.   The COleDateTime class handles dates from 1 January 100 – 31 December 9999.看不懂…


Question: 新手自学C，9道C问题，麻烦大神

1．以下正确的程序段是（）。 A． char s[20];                               B． char *s; scanf("%s", &s);                             scanf("%s", s); C． char s[20];                               D． char s[20], *t=s; scanf("%s", &s[2]);                           scanf("%s", t[2]); 第一题后面有数字括号不知怎么发上去没了..我选的是D..答案是C..如果是C那不是和A一样..D的话t[2]不是相当于给地址了吗    引用 3 楼 paschen 的回复:第一题确实没答案，A和C是一样的，写成scanf("%c", &s); 就对了  另外楼主哪些地方看不懂需要解释

为什么我觉得1没有答案

引用 5 楼 ddyyuan 的回复:第2题是哪个printf不懂..为什么指针format可以在那打字符串 第3题完全不懂 第4题的A选项不是t可以覆盖上去s吗..难道是因为越界问题 第5题不懂.. 第6题是在倒数第三局q后面填的..那里要填c..那c跟D有何其区别..为什么我填D会错 第7、8、9题应该和第5题一样都是main的带参数。。不懂  第二题 等价于printf("%s, m=%d, n=%d\n", "m*=n", m,n);  你问题太多了，先看书啊，都很基础的，再不行你在电脑上调试，一步步看程序怎么运行。。

引用 4 楼 ddyyuan 的回复:1．以下正确的程序段是（）。 A． char s[20];                               B． char *s; scanf("%s", &s);                             scanf("%s", s); C． char s[20];                               D． char s[20], *t=s; scanf("%s", &s[2]);                           scanf("%s", t[2]); 第一题后面有数字括号不知怎么发上去没了..我选的是D..答案是C..如果是C那不是和A一样..D的话t[2]不是相当于给地址了吗    [quote=引用 3 楼 paschen 的回复:] 第一题确实没答案，A和C是一样的，写成scanf("%c", &s); 就对了  另外楼主哪些地方看不懂需要解释[/quote]  是选C   D的t[2]只是一个字符，而不是这个字符的地址，B的s没分配内存

如下题,答案我都知道,希望有详细易懂的解释  1．以下正确的程序段是（）。 A． char s;                               B． char *s; scanf("%s", &s);                             scanf("%s", s); C． char s;                               D． char s, *t=s; scanf("%s", &s);                           scanf("%s", t);  2．下面程序段的运行结果是（）。 #include "stdio.h" main() {     int m=10, n=20;     char *format="%s, m=%d, n=%d\n";     m*=n;     printf(format, "m*=n", m,n); } A． format, "m*=n", m, n                      B． format, "m*=n" C． m*=n, m=200, n=20                        D． 以上结果都不对  3．下面程序的功能是将八进制正整数字符串转换为十进制整数。请选择填空。 #include "stdio.h" #include "string.h"     main()     {         char *t, s;         int n;         t=s;         gets(t);         n=【1】;         while (【2】!= '\0') n=n*8+*t-'0';         printf("%d\n", n);     }     【1】A． 0           B． *t              C． *t-'0'             D． *t+'0'     【2】A． *t          B． *t++            C． *(++t)              D． t  4．以下正确的程序段是（）。 A． char s="12345", t="6543d21";    strcpy( s,t); B． char s, *t="12345";   strcat(s,t); C． char s=" ", *t="12345"; strcat(s, t); D． char *s="12345", *t="54321";  strcat (s,t);  5．不合法的main函数命令行参数表示形式是：（）。     A． main( int a, char *c)                  B． main(int argc, char *argv)     C． main( int arc, char **arv)               D． main( int argv, char*argc)  6．下面程序的功能是统计字串sub在母串s中出现的次数。请选择填空。 #include "stdio.h" #include "string.h"     main()b     {         char s, sub;//字符串函数         int n;         gets(s);         gets(sub);         printf("%d\n", count(s,sub));     }     int count( char *p, char *q)     {         int m, n, k, num=0;         for (m=0; p; m++)             for (【1】, k=0; q==p; k++, n++)  //b  c                 if(q=='\0')                 { num++;  break;}         return (num);     }     【1】A． n=m+1        B． n=m            C． n=0              D． n=1     【2】A． k             B． k++            C． k+1              D． ++k   #include "stdio.h" #include "string.h"     main(int argc, char *argv)     {            int m, length=0;         for (m=1;m<argc; m++)  length+=strlen(argv);         printf("%d\n", length);     }   7.  程序编译连接后生成的可执行文件是file.out，若执行时输入带参数的命令行是：     ./file.out 1234  567  89↙     则运行结果是（）     A． 22              B． 17               C． 12             D． 9   8.假定下列程序的可执行文件名为file.out，则在该程序所在的子目录下输入命令行：     ./file.out  girl  boy↙     后，程序的输出结果是（）。 #include "stdio.h"     main(int argc, char *argv)     {            int m;         if (argc<=0) return;         for (m=1; m<argc ; m++)             printf("%c", *argv);     }     A． girl  boy        B． gb             C． gir              D． girlboy   9．设有一个名为file的C源程序，且已知命令行为：file  girl  boy  student， 则可得到以下运行结果的C源程序为（）     girl     boy     student     A． main( int argc, char *argv)     {           while (--argc>1)             printf("%s%c", *argv, (argc>1)? '\n'：' ');     }     B． main( int a, char * b)     {          while (a-->1)             printf("%s\n", *++b);     }     C． main( int argc, char *argv)     {           while (++argc>0)             printf("%s%c", *++argv, (argc>1) ? ' ' ：'\n');     }     D． main(int argc, char *argv)     {          while (argc>1)             printf("%s", *++argv);      }


Question: 为啥我发不了帖吖吖吖

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

引用 3 楼 zhao4zhong1 的回复:不要迷信书、考题、老师、回帖； 要迷信CPU、编译器、调试器、运行结果。 并请结合“盲人摸太阳”和“驾船出海时一定只带一个指南针。”加以理解。 任何理论、权威、传说、真理、标准、解释、想象、知识……都比不上摆在眼前的事实！ 是的..所以我一直觉得答案跟我的不符合我都会去上机验证..如果确实是我错了..想不懂我就得上来请教了.

我估计没人会帮你看的，一，排班太乱，二，自己哪点不理解直接把那一点提出来，不要把一段代码贴上来求解释，特别是作业题目！


Question: 动态分配内存的指针释放的问题。不明白，能给解释下吗？

了解一下操作系统的进程管理吧。

主函数结束自动释放了，zu指向的地址就是申请的内存地址，所以也可以在主函数用完了zu就把zu释放掉

确实没有释放！ 可以在主函数最后释放 不过这不是一个好的方式，你可以考虑用类封装或者使用智能指针 通常应该是谁分配内存，谁就负责释放


Question: C语言文件与二进制

可以使用位移还有位运算来实现！  每次右移一个 然后 使用 位运算  得出1或者0   然后在右移一位  然后在算

仅供参考：//有一个二进制文件，要求每隔50bits，删除后面的12bits。 #include <stdio.h> #include <stdlib.h> #include <string.h> FILE *fi,*fo; char buf[31]; char obf[31]; int bn,n; void filter() {//对buf中前n个字节中的位，每隔50bits，忽略12bits，结果放在obf中,且将bn设置为obf中的字节数。     char bit[249];     char obt[249];     char b8[33];     char b88[33];     int i,j;     char *e;      for (i=0;i<n;i++) {         _itoa(buf[i],b8,2);         sprintf(b88,"%032s",b8);         sprintf(bit+i*8,"%s",b88+24);     }      j=0;     for (i=0;i<n*8;i++) {         if (i%62<50) {             obt[j]=bit[i];             j++;         }     }     if (j%8) {         bn=(j/8+1)*8;     } else {         bn=j;     }     for (i=j;i<bn;i++) obt[i]='0';     obt[bn]=0;     bn=bn/8;     for (i=0;i<bn;i++) {         strncpy(b8,obt+i*8,8);b8[8]=0;         obf[i]=(char)strtol(b8,&e,2);     } } int main() {     fi=fopen("in.bin","rb");     if (NULL==fi) {         printf("Can not open file in.bin!\n");         return 1;     }     fo=fopen("out.bin","wb");     if (NULL==fo) {         fclose(fi);         printf("Can not open file out.bin!\n");         return 2;     }     while (1) {         n=fread(buf,1,31,fi);         if (0==n) break;         filter();         fwrite(obf,1,bn,fo);     }     fclose(fo);     fclose(fi);     return 0; }

参考代码： #include <stdio.h> #include <stdlib.h>  int main(int argc, char *argv[]) {     FILE *fp;     unsigned char buf[1024];     unsigned char dst[sizeof buf * 8];     int readSize, index;      fp = fopen(argv[1], "rb"); // argv[1]存放文件名字     readSize = fread(buf, 1, 1024, fp);      for (int i = 0; i < readSize; ++i)     { 		for (int j = 0; j < 8; ++j)         {             index = i * 8 + j;             dst[index] = buf[i] >> (7 - j) & 1;             printf("B[%d]=%d\n", index, dst[index]);         }     }     return 0; }

引用 3 楼 ddyyuan 的回复:借个帖问个问题,为什么我发帖子总是说文章内容不能含有特殊字符。！！！  那要看你有没有输入什么啦~

思路：定义变量，赋初值0，写一个循环逐位判断，如果第i位是字符1，让一个临时变量为1，然后左移i位，然后让先前的那个变量与这个临时变量做 |= 运算

借个帖问个问题,为什么我发帖子总是说文章内容不能含有特殊字符。！！！

读文件就不说了，转化可用个笨方法方法，仅供参考  	char c = '0'; 	bool b0,b1,b2,b3,b4,b5,b6,b7; 	b0=c & 0x01; 	b1=c & 0x02; 	b2=c & 0x04; 	b3=c & 0x08; 	b4=c & 0x10; 	b5=c & 0x20; 	b6=c & 0x40; 	b7=c & 0x80;

顶一个~大神们，求教啊！


Question: gpg为什么比md5等摘要算法高明？

现在用 AES 的应该最多， 现在的CPU一般都带aes扩展指令，性能，加密强度都相当不错。

仅供参考：#pragma comment(lib, "crypt32.lib") #pragma comment(lib, "advapi32.lib") #define _WIN32_WINNT 0x0400 #include <stdio.h> #include <windows.h> #include <wincrypt.h> #define KEYLENGTH  0x00800000 void HandleError(char *s); //-------------------------------------------------------------------- //  These additional #define statements are required. #define ENCRYPT_ALGORITHM CALG_RC4 #define ENCRYPT_BLOCK_SIZE 8 //   Declare the function EncryptFile. The function definition //   follows main. BOOL EncryptFile(     PCHAR szSource,     PCHAR szDestination,     PCHAR szPassword); //-------------------------------------------------------------------- //   Begin main. void main(void) {     CHAR szSource[100];     CHAR szDestination[100];     CHAR szPassword[100];     printf("Encrypt a file. \n\n");     printf("Enter the name of the file to be encrypted: ");     scanf("%s",szSource);     printf("Enter the name of the output file: ");     scanf("%s",szDestination);     printf("Enter the password:");     scanf("%s",szPassword);     //--------------------------------------------------------------------     // Call EncryptFile to do the actual encryption.     if(EncryptFile(szSource, szDestination, szPassword)) {         printf("Encryption of the file %s was a success. \n", szSource);         printf("The encrypted data is in file %s.\n",szDestination);     } else {         HandleError("Error encrypting file!");     } } // End of main //-------------------------------------------------------------------- //   Code for the function EncryptFile called by main. static BOOL EncryptFile(     PCHAR szSource,     PCHAR szDestination,     PCHAR szPassword) //-------------------------------------------------------------------- //   Parameters passed are: //     szSource, the name of the input, a plaintext file. //     szDestination, the name of the output, an encrypted file to be //         created. //     szPassword, the password. {     //--------------------------------------------------------------------     //   Declare and initialize local variables.     FILE *hSource;     FILE *hDestination;     HCRYPTPROV hCryptProv;     HCRYPTKEY hKey;     HCRYPTHASH hHash;     PBYTE pbBuffer;     DWORD dwBlockLen;     DWORD dwBufferLen;     DWORD dwCount;     //--------------------------------------------------------------------     // Open source file.     if(hSource = fopen(szSource,"rb")) {         printf("The source plaintext file, %s, is open. \n", szSource);     } else {         HandleError("Error opening source plaintext file!");     }     //--------------------------------------------------------------------     // Open destination file.     if(hDestination = fopen(szDestination,"wb")) {         printf("Destination file %s is open. \n", szDestination);     } else {         HandleError("Error opening destination ciphertext file!");     }     //以下获得一个CSP句柄     if(CryptAcquireContext(                 &hCryptProv,                 NULL,               //NULL表示使用默认密钥容器，默认密钥容器名                 //为用户登陆名                 NULL,                 PROV_RSA_FULL,                 0)) {         printf("A cryptographic provider has been acquired. \n");     } else {         if(CryptAcquireContext(                     &hCryptProv,                     NULL,                     NULL,                     PROV_RSA_FULL,                     CRYPT_NEWKEYSET))//创建密钥容器         {             //创建密钥容器成功，并得到CSP句柄             printf("A new key container has been created.\n");         } else {             HandleError("Could not create a new key container.\n");         }     }     //--------------------------------------------------------------------     // 创建一个会话密钥（session key）     // 会话密钥也叫对称密钥，用于对称加密算法。     // （注: 一个Session是指从调用函数CryptAcquireContext到调用函数     //   CryptReleaseContext 期间的阶段。会话密钥只能存在于一个会话过程）     //--------------------------------------------------------------------     // Create a hash object.     if(CryptCreateHash(                 hCryptProv,                 CALG_MD5,                 0,                 0,                 &hHash)) {         printf("A hash object has been created. \n");     } else {         HandleError("Error during CryptCreateHash!\n");     }     //--------------------------------------------------------------------     // 用输入的密码产生一个散列     if(CryptHashData(                 hHash,                 (BYTE *)szPassword,                 strlen(szPassword),                 0)) {         printf("The password has been added to the hash. \n");     } else {         HandleError("Error during CryptHashData. \n");     }     //--------------------------------------------------------------------     // 通过散列生成会话密钥     if(CryptDeriveKey(                 hCryptProv,                 ENCRYPT_ALGORITHM,                 hHash,                 KEYLENGTH,                 &hKey)) {         printf("An encryption key is derived from the password hash. \n");     } else {         HandleError("Error during CryptDeriveKey!\n");     }     //--------------------------------------------------------------------     // Destroy the hash object.     CryptDestroyHash(hHash);     hHash = NULL;     //--------------------------------------------------------------------     //  The session key is now ready.     //--------------------------------------------------------------------     // 因为加密算法是按ENCRYPT_BLOCK_SIZE 大小的块加密的，所以被加密的     // 数据长度必须是ENCRYPT_BLOCK_SIZE 的整数倍。下面计算一次加密的     // 数据长度。     dwBlockLen = 1000 - 1000 % ENCRYPT_BLOCK_SIZE;     //--------------------------------------------------------------------     // Determine the block size. If a block cipher is used,     // it must have room for an extra block.     if(ENCRYPT_BLOCK_SIZE > 1)         dwBufferLen = dwBlockLen + ENCRYPT_BLOCK_SIZE;     else         dwBufferLen = dwBlockLen;     //--------------------------------------------------------------------     // Allocate memory.     if(pbBuffer = (BYTE *)malloc(dwBufferLen)) {         printf("Memory has been allocated for the buffer. \n");     } else {         HandleError("Out of memory. \n");     }     //--------------------------------------------------------------------     // In a do loop, encrypt the source file and write to the destination file.     do {         //--------------------------------------------------------------------         // Read up to dwBlockLen bytes from the source file.         dwCount = fread(pbBuffer, 1, dwBlockLen, hSource);         if(ferror(hSource)) {             HandleError("Error reading plaintext!\n");         }         //--------------------------------------------------------------------         // 加密数据         if(!CryptEncrypt(                     hKey,           //密钥                     0,              //如果数据同时进行散列和加密，这里传入一个                     //散列对象                     feof(hSource),  //如果是最后一个被加密的块，输入TRUE.如果不是输.                     //入FALSE这里通过判断是否到文件尾来决定是否为                     //最后一块。                     0,              //保留                     pbBuffer,       //输入被加密数据，输出加密后的数据                     &dwCount,       //输入被加密数据实际长度，输出加密后数据长度                     dwBufferLen))   //pbBuffer的大小。         {             HandleError("Error during CryptEncrypt. \n");         }         //--------------------------------------------------------------------         // Write data to the destination file.         fwrite(pbBuffer, 1, dwCount, hDestination);         if(ferror(hDestination)) {             HandleError("Error writing ciphertext.");         }     } while(!feof(hSource));     //--------------------------------------------------------------------     //  End the do loop when the last block of the source file has been     //  read, encrypted, and written to the destination file.     //--------------------------------------------------------------------     // Close files.     if(hSource)         fclose(hSource);     if(hDestination)         fclose(hDestination);     //--------------------------------------------------------------------     // Free memory.     if(pbBuffer)         free(pbBuffer);     //--------------------------------------------------------------------     // Destroy session key.     if(hKey)         CryptDestroyKey(hKey);     //--------------------------------------------------------------------     // Destroy hash object.     if(hHash)         CryptDestroyHash(hHash);     //--------------------------------------------------------------------     // Release provider handle.     if(hCryptProv)         CryptReleaseContext(hCryptProv, 0);     return(TRUE); } // End of Encryptfile //-------------------------------------------------------------------- //  This example uses the function HandleError, a simple error //  handling function, to print an error message to the standard error //  (stderr) file and exit the program. //  For most applications, replace this function with one //  that does more extensive error reporting. void HandleError(char *s) {     fprintf(stderr,"An error occurred in running the program. \n");     fprintf(stderr,"%s\n",s);     fprintf(stderr, "Error number %x.\n", GetLastError());     fprintf(stderr, "Program terminating. \n");     exit(1); } // End of HandleError

引用 5 楼 mLee79 的回复:公钥服务器上 libucurl 的公钥被很多人的签名过， 你说改就改， 当大家白痴啊。  好吧，上面的问题到此结束  下面请教一个文件加密的问题，  不少网络安全公司，开发一个程序对文件加密， 当用户想访问文件的时候，必须输入密码，然后解密，  我遇到个问题 （1）它们这类公司一般是采用什么对称算法加密？  比如aes,des等  还是用一些 特殊少见的加密算法来加密文件。

引用 1 楼 mLee79 的回复:gpg pgp 用私钥对 hash 签名， 怎么可能是 个简单 hash 能比的， 晕死。  pgp gpg 没有证书——》 无法验证公钥的真伪。  要说验证真伪， 其也是靠公钥的指纹靠验证！！！   靠指纹有啥用， 照样可以攻击公钥。  方法如下：   篡改libcurl官网的gpg文件，用自己的私钥签名（不是libcurl私钥） ， 然后，到公钥服务器里篡改libucurl的公钥。  （gpg文件里有 libcurl文件的签名     和公钥的指纹。）   没比md5好哪里去啊

只有MD5, 就属于公说公有理,婆说婆有理, 无法溯源, 如果用公钥证书, 发布者可以用自己私鉏证明身份,并确保不被篡改,

公钥加密，私钥解密。私钥不是公开的。 就像银行卡密码，你非要把它写在银行卡上的话，那这密码也就没什么用了。


Question: C语言vc6.0运行程序过程中提示***.EXE已停止工作

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

因为你字符串是在常量区，不能修改 如果要修改，就用字符数组在栈上分配   #include<stdio.h>       #define NUL '\0' /*'\0'不好打*/      char *match( char *str, char *substr);   int del_substr( char *str, char  *substr);     int main()   {   	char str[20]="ABCDEFG";     char *substr="CDE"; /*返回指针的函数*/      del_substr(str,substr);     puts(str); }    /*  **为了清楚，单独写一个子函数实现判断两个字符串匹配  */   char *match(char *str,char *substr)   {       while(*substr!=NUL) if(*str++!=*substr++)               return NUL; return str; }      /*  **删除子串函数  */   int del_substr(char *str,char *substr )   {   char *next;         /*      **保证被操作字符串不为空      **      */      while(*str!= NUL)     {           next=match(str,substr);           if(next!= NULL)             break;           str++;       }       /*      **到达源字符串文件尾的时候，说明没有子串      */       if(*str==NUL)           return 0;        /*      **被删除子串之后的字符复制操作      */       while(*str++=*next++);/*字符串拷贝*/     return 1;   }

*str指向的是内存中的ro区（只读）不能改变上面的东西的，不过你可以把str指向别的地方

C没有为字符串定义专门的变量类型，而是把它储存在char数组中。

str[]之所以可以是因为，程序在被编译时分配了内存区给str的，而且str不是常量类型，其内部值固然可以改变。 但是char *str="CDE"中的字符串被编译后是存放在静态常量区的，然后首地址返回给str，其内容是不可以改变的，只能读不能写。


Question: 编写一个返回数组的函数，帮忙看看哪出错了！

我没主函数，晕！

这样？  #include<stdio.h> #include<stdlib.h> #define STRLEN 10 int* qudu_shuzu(void) {     int *pzu=NULL; 	int count=0,shu=0,str_len=STRLEN; 	int *P=NULL;      pzu=(int*)malloc(10*sizeof(int)+1);     if(!pzu)     {         printf("fen pei nei cun shibai!\n");         exit(1);     }          printf("qing shu ru yi xi lie zheng shu(hui che jieshu):\n");     fflush(stdin);     while(scanf("%d",&shu))       {           ++count;           if(count==str_len)           {               str_len+=STRLEN;                              pzu=(int*)realloc(pzu,str_len*sizeof(int)+1);               if(!pzu)               {                   printf("dong tai fen pei shibai!");                   exit(1);               }           }           *(pzu+count)=shu;       }     *pzu=count;     *(pzu+count+1)='\0';      return pzu;  }


Question: 关于字符串的一个题目

引用 4楼LLW059 的回复:while（s[i-1]==‘’&&i-->0）； while循环先判断字符串结束标记前的字符是否为空格且i>0是否满足，都满足则i=i-1，接着循环判断前一个字符是否为空格等等；直到字符不为空格或者i = 0为止。接着将第一个空格改成字符串结束标记，即将尾部空格去掉。注意while没有循环体，结束循环才执行下一步s[i]=‘\0’；明了，谢谢

这样写：   void str1(char s[])  { 	int i = strlen(s); 	auto a = s[i]; 	while(s[--i] == ' '); 	s[i+1] = '\0'; }

i--是先判断i>0然后再减1，你调试一下就好了

while（）｛｝的含义是，当字符串数组S 的第i-1个字符为空格时，都在第i个字符位置插入终止符，直到i-1非空为止。


Question: for循环

因为先判断在i自增，到最后1=9的时候，做循环体，做完上来i++变成10了 然后在判断条件是否成立！

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

1,2,3,4,5,6,7,8,9 然后10不满足条件 <10 ，不会printf

判断循环条件十次，执行循环体九次

你的问题太模糊了，最好把代码附上。


Question: #define的问题

我用的是xilinx sdk，只是想知道 #define 后面加那么多东西是什么意思。

谢谢！ 略懂！

首先要了解#define定义 #define A B A 表示即将调用的，B 是对A 的执行。 A的形式 可以是 A， 也可以是A(x), 当然也可以是A（x，y）。 B的形式 可以是 B，也可以是一条赋值或运算语句，也可以是函数调用，甚至可以是一段语句（函数+运算+赋值+判断都可以）  然后再来你的问题。 分割一条结构复杂的语句，以便清晰理解。 XAxiDma_IntrEnable(InstancePtr, Mask, Direction)  就是A（x，y，z）的形式。剩下的一堆就是B 我们看B内，有\符号，表示换行，连接，没有其他意思。 XAxiDma_WriteReg（）是一个函数，再跟据，符号就知道他有4个参数（用abcd表示）。 那么你问题就是： #define A（x，y，z）    B（a, b, c, d） 现在能看懂吧。

VC编译选项加/EP /P（项目、属性、配置属性、C/C++、预处理器、预处理到文件：是，预处理取消显示行号：是），重新编译，查看宏展开后对应的.i文件。gcc加-E http://bbs.csdn.net/topics/391003898

VS下可以这样查看宏展开后的代码：http://blog.csdn.net/qyee16/article/details/9322281

与下面的大概等价:  #define  XAxiDma_IntrEnable(InstancePtr, Mask, Direction)  XAxiDma_WriteReg((InstancePtr)->RegBase + (XAXIDMA_RX_OFFSET * Direction), XAXIDMA_CR_OFFSET, (XAxiDma_ReadReg((InstancePtr)->RegBase + (XAXIDMA_RX_OFFSET * Direction), XAXIDMA_CR_OFFSET)) | (Mask & XAXIDMA_IRQ_ALL_MASK))