Question: 结构体中联合体初始化的问题

楼主，我现在也在做AUTOSAR的DEM这块，能否留个联系方式交流一下，多谢！

引用 5 楼 vnvlyp 的回复:[quote=引用 4 楼 mianzhouhu 的回复:] 这个方法在某些编译器上是可行的，而且代码简单易读，问题在于这种初始化方式并不兼容所有编译器，看我将这种代码注释就明白了。 不支持c99的编译器怕是也应该更新一下了吧。。[/quote]  汽车行业的，芯片配套的编译器，没办法的

引用 10 楼 zhao4zhong1 的回复:仅供参考：#include <stdio.h> #include <stdlib.h> char buf[17]; union U {   unsigned short int aa;   struct {     unsigned int bb:7;//(bit 0-6)     unsigned int cc:6;//(bit 7-12)     unsigned int dd:3;//(bit 13-15)   }; } u; void main() {                 //bbbbbbbbbbbbbbbb                 //iiiiiiiiiiiiiiii                 //tttttttttttttttt                 //111111                 //5432109876543210                 //::::::::::::::::     u.aa=0xE07F;//1110000001111111     printf("bb==%d,cc==%d,dd==%d\n",u.bb,u.cc,u.dd);     u.bb=0x41;     u.cc=0x21;//dddccccccbbbbbbb     u.dd=5;   //1011000011000001     printf("aa==0x%04X==%016s(2)\n",u.aa,itoa(u.aa,buf,2)); } //bb==127,cc==0,dd==7 //aa==0xB0C1==1011000011000001(2)   这个是联合体中嵌套结构体，跟结构体中嵌套联合体还是有点区别

引用 6 楼 cfjtaishan 的回复: 24 #include <stdio.h>           23                              22                              21 #define MAX_LEN     32    20                              19 struct node {                18     int type;                17     union bb {               16     |   const int *a;        15     |   const char *b;       14     |   const float *c;      13     }cc;                     12 };                           11                              10 int main(void)                9 {             8     int array[MAX_LEN];       7     char src[MAX_LEN];        6                           >>  5     union bb type;            4     type.a = array;           3               2     struct node tmp[2] = {     1     |   {1,  {type.a}},   25      |   {2,  {type.a}}                                                                                1     };        2               3     return 0;     4 }  类似这种定义方式，是否可以。  这种方法看起来有个问题，联合体的作用域不是在结构体中么？（虽然编译时确实可以通过）  另外，这个方法跟还是不适用此问题，因为实际中需要使用的是‘ type.b’,仍然会报类型不匹配

如果你这联合体只有指针的话，应该可以添加一个void *类型吧，然后就应该可以接受所有指针类型了  typedef struct {     Dem_PreDebounceNameType                        PreDebounceName;                // (1)     union {     void *ptr;     const Dem_PreDebounceMonitorInternalType    *PreDebounceMonitorInternal;    // (0..1)     const Dem_PreDebounceCounterBasedType        *PreDebounceCounterBased;        // (0..1)     const Dem_PreDebounceFrequencyBasedType        *PreDebounceFrequencyBased;        // (0..1)     const Dem_PreDebounceTimeBasedType            *PreDebounceTimeBased;            // (0..1)     } PreDebounceAlgorithm; } Dem_PreDebounceAlgorithmClassType;

引用 4 楼 mianzhouhu 的回复:这个方法在某些编译器上是可行的，而且代码简单易读，问题在于这种初始化方式并不兼容所有编译器，看我将这种代码注释就明白了。 不支持c99的编译器怕是也应该更新一下了吧。。

引用 2 楼 cfjtaishan 的回复:typedef struct {     Dem_PreDebounceNameType                        PreDebounceName;                // (1)     union {     const Dem_PreDebounceMonitorInternalType    *PreDebounceMonitorInternal;    // (0..1)     const Dem_PreDebounceCounterBasedType        *PreDebounceCounterBased;        // (0..1)     const Dem_PreDebounceFrequencyBasedType        *PreDebounceFrequencyBased;        // (0..1)     const Dem_PreDebounceTimeBasedType            *PreDebounceTimeBased;            // (0..1)     } PreDebounceAlgorithm; } Dem_PreDebounceAlgorithmClassType;  const Dem_PreDebounceCounterBasedType PreDebounceCounterBased[DEM_MAX_NUMBER_EVENT] = {     /* For event 'MCU_E_CLOCK_FAILURE' */     {         /*.JumpUp */TRUE,         /*.JumpDown */FALSE,         /*.CountInStepSize */1,         /*.CountOutStepSize */1     }      /* For event 'CANTRCV_E_NO_TRCV_CONTROL' */     ,{         /*.JumpUp */TRUE,         /*.JumpDown */FALSE,         /*.CountInStepSize */1,         /*.CountOutStepSize */1     } };  const Dem_PreDebounceAlgorithmClassType PreDebounceAlgorithmClass[DEM_MAX_NUMBER_EVENT] = {     /* For event 'MCU_E_CLOCK_FAILURE' */     {         /*.PreDebounceName */         DEM_PRE_DEBOUNCE_COUNTER_BASED,         /*.PreDebounceAlgorithm */         {             .PreDebounceCounterBased = &PreDebounceCounterBased[MCU_E_CLOCK_FAILURE - 1]         }     }      /* For event 'CANTRCV_E_NO_TRCV_CONTROL' */     ,{         /*.PreDebounceName */         DEM_PRE_DEBOUNCE_COUNTER_BASED,         /*.PreDebounceAlgorithm */         {             .PreDebounceCounterBased = &PreDebounceCounterBased[MCU_E_CLOCK_FAILURE - 1]         }     } }; 试一下这种初始化方式～  这个方法在某些编译器上是可行的，而且代码简单易读，问题在于这种初始化方式并不兼容所有编译器，看我将这种代码注释就明白了。

引用 1 楼 jianwen0529 的回复:成员换个位置？  强制转换？  干脆用一个void*替代联合体？  目前有的这个方法，将占用内存最大的成员放在第一个位置，然后强制转换成第一个成员类型，编译可以通过，但是这个方法太牵强，总觉得C语言不该这么low吧，目前也还没验证强制转换后对运行结果有没有影响。  void* 替代联合体？怎么知道联合体大小呢？估计行不通

成员换个位置？  强制转换？  干脆用一个void*替代联合体？


Question: 指针问题求解

书看千行不如手敲一行！ 不要迷信书、考题、老师、回帖； 要迷信CPU、编译器、调试器、运行结果。

声明时，*指针，&引用 使用时，*取内容，&取地址  《牛肉干》 C语言上机课，某女同学偷偷吃起牛肉干。 有一粒牛肉干掉到了键盘上，卡在7和8键之间。 女同学就在键盘上抠啊、抠啊、抠啊…… 程序里一行代码变成这个样子： int *pa=&*&*&*&*&*&*&*&*&*&*&*&*&*&*&*&*&*&*&*&*&*&*&*&a; 后来的结局是 ————程序顺利通过编译，运行结果正确！

& 取地址操作符 * 指针：表示对指针进行解引用操作，也就是获得指针指向的对象。 *p=24,表示将p指向的对象的值修改成了24（之前a=12） ptr=&p;表示让ptr指向了p（指针的指针） *ptr=&b;   // *ptr就是p，也就是让p指向了b **ptr=34;   // 相当于把b改成了34

引用 1楼user-4 的回复:书上的意思说用指针p给a赋值为24，不是说它等于24 后面的书上说的都比较清楚了，就是指针跟二级指针的基本使用方法 书不错，道理讲的比较明白，多做题，增加一些感性认识就可以了原来是这样，谢谢


Question: vc6安装问题

VC6可以用虚拟机去跑，建议换成VS: http://blog.csdn.net/cometnet/article/details/19551125

FileTool.exe 替换打开和添加到项目中 Visual C++ 的新功能 http://support.microsoft.com/kb/241396/zh-cn

安装虚拟机装个Xp系统，然后装vc 6.0 就行了

VC6太老了，建议用VS吧，如果仍要用，在虚拟机里安装吧

因为vc6.0太老了，win10已经不支持了，你还是用新一点的vs13，vs15什么的吧


Question: Visual C++6.0编译调试通过不能运行是哪里出了问题？

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

此外，printf("result:\n",compt(a));  改成；  printf("result:%d\n",compt(a));

return tmp+compt(a--);  改成：  return tmp+compt(--a);  否则每次递归a的值都是一样的

你可以把求阶乘和求和分别写成函数。 #include <stdio.h> int Jiecheng(int n)   {       int tmp;       if(n==1)        return tmp=1;       else        return tmp=n*Jiecheng(n-1);    }  int  jia(int n) {     int i;     int s=0;     for(i=1;i<=n;i++)         s=s+Jiecheng(i);     return s; }   main (){   int i,j;   printf("请输入一个整数x\n");   scanf("%d",&i);   j=jia(i);   if(j>0)    printf("x个阶乘的和为：%d",j);   else   printf("error");    } 这是我写的，互相学习下


Question: Visual C++6.0编译调试通过不能运行是哪里出了问题？

又是++  --  这种东西惹的货 建议, 这种语句单独放一行执行,  并且不要做为函数参数.   这样就不会有问题了.  除非, 你能非常清楚的区分++, --放到什么位置, 有什么样的结果.

#include<stdio.h> int compt(int a); void main() { int a; scanf("%d",&a); printf("result:%d\n",compt(a)); } int compt(int a) { if(a==1) return 1; int i=1; int tmp=1; for(;i<=a;i++) { tmp*=i; } return tmp+compt(a-1); }

把a--改成--a试试，你一直以相同的参数调用这个函数，肯定会堆栈溢出的


Question: 新手一枚 qsort 无法结束输出 应该还有很多错 求助

如果按照字母顺序排序，建议使用： return strcasecmp((char *)a, (char *)b);;不区分大写。

字符串比较建议使用库函数，qsort不能执行完，是因为参数有问题。以下是可以执行的代码。 #include<stdio.h> #include<stdlib.h> int cmp(const void*a,const void*b) {     return strcmp((char *)a, (char *)b); }  void sort(char (*pstr)[21], int count) {     qsort(pstr, count, sizeof(pstr[0]), cmp); }  int main() {     int i;     int p[26];     char s[27];     int count,j;     char str[128];     char a[100][21]; #if 0     while(scanf("%s\n",s)!=EOF)     {         for(i=0;i<26;i++)             p[s[i]-'A']=i;     } #endif     fgets(str, 128, stdin);     str[strlen(str)-1] = 0;     count=0;i=0;     while(1)     {         j=0;         while(str[i]!=' ' && str[i])    /* '\0' is equal 0 */             a[count][j++]=str[i++];         a[count][j] = 0;         count++;         if(!str[i])             break;         else             i++;     }     //qsort(a, count, sizeof(a[0]), cmp);     sort(a, count);     for(i = 0; i < count-1; i++)     {         printf("%s ",a[i]);     }     printf("%s\n",a[i]);     return 0; }

Description   给定一组以一个空格分隔的只含大小写字母的字符串。与普通字典序不同，按照给定的字母顺序对这组字符串排序。设两个字符串的字母不会完全相同。如：Hat、hat、HAt等不会同时出现。 例如：字母顺序为QWERTYUIOPASDFGHJKLZXCVBNM时，一组字符串 hat cat bat book bookworm Dallas Austin Houston fire firefox fumble的排序结果为：Austin Dallas fumble fire firefox Houston hat cat book bookworm bat。  Input   每组数据由2行组成，第1行为字母顺序（26个大写字母），第2行是需要排序的一组字符串（只含大小写字母，长度不大于20）。 数据不多于100组。需要排序的一组字符串中包含的字符串个数至少1个，至多100个。  Output   对于每一组数据，输出排序后的字符串。字符串之间输出一个空格，最后一个字符串后面没有空格，而是输出一个换行符。  Sample Input   QWERTYUIOPASDFGHJKLZXCVBNM hat cat bat book bookworm Dallas Austin Houston fire firefox fumble QWERTYUIOPASDFGHJKLZXCVBNM How are you QAZWSXEDCRFVTGBYHNUJMIKOLP How are you ABCDEFGHIJKLMNOPQRSTUVWXYZ How are you  Sample Output   Austin Dallas fumble fire firefox Houston hat cat book bookworm bat you are How are you How are How you


Question: 新人求指导——scanf函数输入参数的问题

#include <stdio.h> #include <math.h>  int main() {     double x0=6, x1=1.5, a=1;     printf("Please input a =\n");     printf("%f is %f\n", a, x1);     scanf("%lf", &a);     x0 = a/2.0;     printf("%f is %f\n", a, x0);      return 0; } %f换成%lf 因为a是double类型，使用lf才能正确赋值给a； float占4个字节，double占8个字节。由于表示的精度不同，float和double在内存存放形式也不一样。

用scanf输入的时候，double类型只能用%lf，输出可以用%f


Question: 纯虚数的幂，新手求助

当溢出时，应该返回 return num_size - 1; 这个地方改一下。

#include <stdio.h> #include <stdlib.h> #include <string.h>  #define MAX_NUM_LEN 2048  int cal_val(unsigned char *num_list, int num_size, int base, int num) {     int i = 0, j;     int len = 1, tmp, carry_bit;      num_list[1] = 1;      while (i < num) {         carry_bit = 0;         for (j = 1; j <= len; j++) {             tmp = num_list[j] * base + carry_bit;             num_list[j] = tmp % 10;             carry_bit = tmp / 10;             if (j >= len && carry_bit != 0)                 len++;             if (num_size-1 < len) {/* overflow */                 printf("Overflow!\n");                 return num_size;             }         }         i++;     }      return len; }   int main(void) {     unsigned char num_list[MAX_NUM_LEN];     int num_len, i;     int base, power;      memset(num_list, 0, sizeof(num_list));     printf("Please input two numbers: ");     scanf("%d%d", &base, &power);      if (base < 0 && power % 2)         num_list[0] = 1; /* negative number */     else         num_list[0] = 0;     base = abs(base);      num_len = cal_val(num_list, MAX_NUM_LEN, base, power);     printf("len = %d\n", num_len);     if (num_list[0])         putchar('-');     for (i = num_len; i >= 1; i--)         printf("%d", num_list[i]);     printf("\n");     return 0; }

可以参考n的阶乘代码： #include<stdio.h> int main() {     static int a[100000000]; //设置一个超大数组来存储乘积结果。     int n;//要求的n的阶乘     int jw;//用来表示进位     int i, j;//控制循环     int len = 1;//初始化数组长度为1     int temp;//过程变量     printf("请输入n：");     scanf("%d", &n);     a[1] = 1;     for (i = 2; i <= n; i++)//遍历。从1到n     {         jw = 0;         for (j = 1; j <= len; j++)//从数组的低位开始乘         {             temp = a[j] * i + jw;//变量存储结果             a[j] = temp % 10;//将变量最后一位放入数组。             jw = temp / 10;//表示除了最后一位需要进位的数             if (j >= len && jw != 0)                 len++;  //数组长度加一          }       }          printf("n! =");          for (i = len; i >= 1; i--)//逆序输出数组就是结果         printf("%d", a[i]);     printf("\n");     return 0; }


Question: vc6  调试时提示access violation

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

在调试下运行程序，出错可以通过调用堆栈定位到相关代码，以便分析原因

把你的输入和输出顺便贴一下

这个是求两个字符串 最大的相同子串


Question: RFID考试问题！！！明天补考了！！求大神！！！！

在读IC卡号的卡号时，需要提供密匙吗？经过哪些过程就可以读出卡号。 IC卡需要秘钥，目前市面上最流行的Mifare1卡。 可以去看下潘春伟的博客，讲的挺详细的。 http://blog.sina.com.cn/s/articlelist_2664458157_0_1.html

创业公司不管是女的还是男的去，都会让你酸爽的，会让你觉得生无可恋。 上了规模的公司，男的女的感觉区别不是太大。

我也不知道女性适不适合编程，反正我公司女性程序员有差不多7个

懒得动手的人和拖延症患者不适合编程。 跟性别无关。

block_read(  INT8U block_read( INT8U KeyBlockAddr ,INT8U *Money )		   // 参数“1”和“Money”指要读的是块 1 和将信息存放在 Money 中。 { 	INT8U CardReadBuf[16],i; 	INT8U CardKeyABuf[6]={0xff,0xff,0xff,0xff,0xff,0xff};		//   白卡默认密码是 6 个 0xff。     /*	if( KeyBlockAddr % 4 == 3 )	//  这里锁定密码块 	{ 		psUartDataRevSend->UartErrCode = ERROR_BLOCK_ADDR; 		memset( &psUartDataRevSend->UartDataBuf[1], 0x00, 16 ); 		bWarn = 1; 		return FALSE;	 	}   */  	if( PcdRequest( PICC_REQIDL, Card_type ) != MI_OK )//寻天线区内未进入休眠状态的卡，返回卡片类型 2字节	 	{ 		if( PcdRequest( PICC_REQIDL, Card_type ) != MI_OK )//寻天线区内未进入休眠状态的卡，返回卡片类型 2字节	 		{ 			return FALSE; 		}	 	}  	if( PcdAnticoll( Card_SN ) != MI_OK ) //防冲撞，返回卡的序列号 4字节  	{ 		bWarn = 1; 		return FALSE;	 	}  	if( PcdSelect( Card_SN ) != MI_OK )//选卡 	{  		bWarn = 1; 		return FALSE; 	}   	if( PcdAuthState( PICC_AUTHENT1A, KeyBlockAddr, CardKeyABuf, Card_SN ) != MI_OK )// 验证密码 	{ 		bWarn = 1; 		return FALSE;	 	}  	if( PcdRead( KeyBlockAddr, CardReadBuf ) != MI_OK )// 读卡	 读块 1 数据。16 字节数据存放在 CardReadBuf[16]中。 	{ 		bWarn = 1; 		return FALSE; 	}     	send_bytes(CardReadBuf,16);	 //串口发送数据  	for(i=0;i<3;i++)			//将有用的前 3 个字节数据取出来放在 Money[3]里面。  	Money[i]=CardReadBuf[i];  //用于写操作  	bPass = 1; 			 	return TRUE; }			   block_write( INT8U block_write(  INT8U KeyBlockAddr,INT16U Money_1,INT8U Money_2 )	             //参数“1”、“Money_1”和“Money_2”指要写的是块 1 和内容是金额             //的整数（Money_1）和小数（Money_2）。 { 	INT8U CardWriteBuf[16]; 	INT8U CardKeyABuf[6]={0xff,0xff,0xff,0xff,0xff,0xff}; 	CardWriteBuf[0]=  Money_1 /256;								 	//	将数据转换成16进制放在缓冲区CardWriteBuf[16]的前3字节里面内，                    //准备用来写进卡。 	CardWriteBuf[1]=  Money_1 %256; 	CardWriteBuf[2]=  Money_2 ; //<9的数 	if( KeyBlockAddr % 4 == 3 )	 //	 这里锁定密码块,不让修改	不让修改各个扇区的 03 块（密码块）。 	{ 		bWarn = 1; 		return FALSE;	 	} 	 	if( PcdRequest( PICC_REQIDL,Card_type ) != MI_OK )//寻天线区内未进入休眠状态的卡，返回卡片类型 2字节	 	{ 		if( PcdRequest( PICC_REQIDL,Card_type ) != MI_OK )//寻天线区内未进入休眠状态的卡，返回卡片类型 2字节	 		{ 			return FALSE; 		}	 	}  	if( PcdAnticoll( Card_SN ) != MI_OK ) //防冲撞，返回卡的序列号 4字节  	{ 		bWarn = 1; 		return FALSE;	 	}  	if( PcdSelect( Card_SN ) != MI_OK )//选卡 	{  		bWarn = 1; 		return FALSE; 	}   	if( PcdAuthState( PICC_AUTHENT1A, KeyBlockAddr, CardKeyABuf, Card_SN ) != MI_OK )// 验证密码 	{ 		bWarn = 1; 		return FALSE;	 	}  	if( PcdWrite( KeyBlockAddr, CardWriteBuf ) != MI_OK )//写卡	 将 CardWriteBuf[16]写进 IC 卡，实际只用到前 3 字节。 	{ 		bWarn = 1; 		return FALSE; 	} 	bPass = 1; 	 	return TRUE;    一个一个按键打的  辣么多！！

功能选择函数 void ctrl_process( void ) {		      INT8U           back_count=0,//退格记录          key_value=16, 		 Money_2=0,          Money_select=1, 	//整数 		 Money_BUF[7]={'0','0','0','0','0','.','0'}, //5位整数+1个小数	  定义显示缓存    		 Money[3], 		 statesbuf;     INT16U Money_1=0;    	    if(states!=statesbuf)  //状态改变，清屏	   当状态改变，也就是功能改变时，清屏 	  { 	    display_clear_line(2); 	    display_clear_line(3); 	    statesbuf=states; 	  }      switch(states) 	{        case 0:	       //余额显示		   状态“0”，进入余额显示状态。  		  	  display(1,0,1); 			  if( block_read(1,Money)) /*	执行 block_read(1,Money)函数， 			                                这里我们稍后会详细说明一下这个函数， 			                                现在先知道这个函数的功能，那就是读取第 1 块数据， 			                             	将前3 个字节存放在 Money[3]数组中，我们将前 2 个字节划分为电子钱包金额的整数， 		                            		后 1 字节作为小数。所以最大的金额为：65535.9 元。*/	    			  { 			    Money_1=Money[0]*256+Money[1];		  //按前面说的把 3 字节数据分离，得到余额的整数和小数部分。  				Money_2=Money[2];  				Money_BUF[0]=Money_1/10000+'0';		 //将余额数据分解，并用于 LCD 显示。这样余额就被显示到 LCD 上面 	            Money_BUF[1]=Money_1%10000/1000+'0'; 	            Money_BUF[2]=Money_1%1000/100+'0'; 	       		Money_BUF[3]=Money_1%100/10+'0'; 				Money_BUF[4]=Money_1%10+'0'; 				Money_BUF[5]='.'; 				Money_BUF[6]=Money_2+'0';      	     			display2(3,0,Money_BUF,7);	  				display2(3,4,"元",2); 				display(2,0,5);	 //成功 			  } 			 		//	else 	 display(2,0,6);   //失败 			 			  break;          case 1:							   //状态“1”，进入消费程序。  		       display(1,0,2);    //消费 			   display2(3,0,Money_BUF,7);	  	           display2(3,4,"元",2);                	while(1) 				{ 				  key_value=key_scan();  				  if(key_value==12)   //上一功能 				   {  				     states--; 	                 return; 					}  				  if(key_value==13)	  //下一功能 				  { 				   states++; 				   return; 				  }	 				   				  if(key_value==15)	  //确认键		 确认键被按下，通常是完成数据的输入后再按确认键，此时 IC 卡应提前放到模块上。  				  {			 				 				   if(block_read(1,Money))	  //我们先读出 IC 卡的余额，block_read(1,Money)。 				   { 				   if((Money_1 > (Money[0]*256+Money[1]))||((Money_1 == (Money[0]*256+Money[1])) && Money_2 > Money[2])) 				   /*   余额小于消费额  这里分了 3 种情况： 				      1.IC 卡余额小于消费额，则显示扣费失败  				      2.IC 卡余额整数大于消费额，小数小于消费额，则需要借位。 					  3. IC 卡 余额整数和小数部分均大于消费额，直接做减法。  */ 				     { 					   display(2,0,6); 					   					 } 				   else  				   { 				     if(Money_2 > Money[2])//需要借位 					   { 					      Money_1= (Money[0]*256+Money[1] )-Money_1-1; 						  Money_2=Money[2]+10 -Money_2 ; 					   } 				   	 else  					   { 					      Money_1=(Money[0]*256+Money[1] )-Money_1; 						  Money_2=Money[2]-Money_2;	   					   } 					 block_write(1,Money_1,Money_2 );//写卡		执行写卡操作，将原来余额减去消费额后的新余额写进 IC 卡块 1 里 						 //显示余额						    					Money_BUF[0]=Money_1/10000+'0';		   //在 LCD 上面显示新的余额。                   	Money_BUF[1]=Money_1%10000/1000+'0';  	                Money_BUF[2]=Money_1%1000/100+'0';                     Money_BUF[3]=Money_1%100/10+'0';                     Money_BUF[4]=Money_1%10+'0';                     Money_BUF[5]='.';                     Money_BUF[6]=Money_2+'0';                          display2(3,0,Money_BUF,7);  					   display(2,0,5); 		  				   } 				   	Delay_ms(3000); 					return; 				  }	 				  } 				   if(key_value==10)  //Money小数		小数点按键被按下，下一个数据输入的是小数。  				    { 					  Money_select=0; 					  back_count=0; 	//不影响退格使用 					}  				   if(key_value==11)	  //退格			 退格，这里增加了处理小数点的功能，请大家自行分析。  				    {   				 					   if( Money_select  ) 					   { 					     Money_1=Money_1/10; 					   } 					   else	 if(Money_select==0 && back_count==0) 					   { 					     Money_2=0;        	       			 back_count=1; 			           } 					   else if(Money_select==0 && back_count==1) 					   { 					   	 Money_1=Money_1/10; 						 Money_select=1; 						 back_count=0; 					   }			 				   					   	 				    	Money_BUF[0]=Money_1/10000+'0';                      	Money_BUF[1]=Money_1%10000/1000+'0';     	                Money_BUF[2]=Money_1%1000/100+'0';  	                    Money_BUF[3]=Money_1%100/10+'0';  	                    Money_BUF[4]=Money_1%10+'0'; 	                    Money_BUF[5]='.'; 	                    Money_BUF[6]=Money_2+'0';      	                         display2(3,0,Money_BUF,7);	  	                    display2(3,4,"元",2);	 					 } 				   				   if(key_value>=0 && key_value <=9)//有按键输入 ，包括小数点	  检测到按键是 0~9 的时候判定为有数字输入。  				  {	 			    				     								 					if(Money_select)		//整数				  判断是整数输入还是小数输入，进行相应操作。 					     Money_1=Money_1*10+key_value;  					else  					{  Money_2=key_value; 					   back_count=0;	//不影响退格使用 					}  						Money_BUF[0]=Money_1/10000+'0';				  //把刚刚输入的金额实时显示出来。                       	Money_BUF[1]=Money_1%10000/1000+'0';     	                Money_BUF[2]=Money_1%1000/100+'0';  	                    Money_BUF[3]=Money_1%100/10+'0';  	                    Money_BUF[4]=Money_1%10+'0'; 	                    Money_BUF[5]='.'; 	                    Money_BUF[6]=Money_2+'0';      	                         display2(3,0,Money_BUF,7);	  	                    display2(3,4,"元",2);	 				  }			   				} 		       break ; 		   		 case 2:		 		       display(1,0,3);      //充值	  状态“2”，充值功能。 			   display2(3,0,Money_BUF,7);	  	           display2(3,4,"元",2); 	           	while(1) 				{ 				  key_value=key_scan();  				  if(key_value==12)   //上一功能 				   {  				     states--; 	                 return; 					} 				   				  if(key_value==15)	  //确认键 				  {			 				 				   if(block_read(1,Money))				   	//		 先读出 IC 卡余额。 				   { 				   	                  if((Money[2]+Money_2)>9)                /*进位	这里分了 2 种情况： 	        1.IC 卡余额小数部分和充值金额小数部分的和大于 9，则相加后做进位处理。 	        2.IC 卡 IC 卡余额小数部分和充值金额小数部分的和<=9，则直接做加法出来。 	   */ 					 { 					  Money_1=(Money[0]*256+Money[1] )+Money_1+1; 				      Money_2=Money[2]+Money_2-10;	   					 } 					  else 					  { 					  Money_1=(Money[0]*256+Money[1] )+Money_1; 				      Money_2=Money[2]+Money_2;	   					 }  					 block_write(1,Money_1,Money_2 );//写卡	 						 //显示余额 					Money_BUF[0]=Money_1/10000+'0';		                   	Money_BUF[1]=Money_1%10000/1000+'0';  	                Money_BUF[2]=Money_1%1000/100+'0';                     Money_BUF[3]=Money_1%100/10+'0';                     Money_BUF[4]=Money_1%10+'0';                     Money_BUF[5]='.';                     Money_BUF[6]=Money_2+'0';                          display2(3,0,Money_BUF,7);  					   display(2,0,5); 		  				   } 				   	Delay_ms(3000); 					return; 			 				  } 				   if(key_value==10)  //Money小数 				    { 					  Money_select=0; 					  back_count=0; 	//不影响退格使用 					}  				   if(key_value==11)	  //退格 				    {   				 					   if( Money_select  ) 					   { 					     Money_1=Money_1/10; 					   } 					   else	 if(Money_select==0 && back_count==0) 					   { 					     Money_2=0;        	       			 back_count=1; 			           } 					   else if(Money_select==0 && back_count==1) 					   { 					   	 Money_1=Money_1/10; 						 Money_select=1; 						 back_count=0; 					   }			 				   					   	 				    	Money_BUF[0]=Money_1/10000+'0';                      	Money_BUF[1]=Money_1%10000/1000+'0';     	                Money_BUF[2]=Money_1%1000/100+'0';  	                    Money_BUF[3]=Money_1%100/10+'0';  	                    Money_BUF[4]=Money_1%10+'0'; 	                    Money_BUF[5]='.'; 	                    Money_BUF[6]=Money_2+'0';      	                         display2(3,0,Money_BUF,7);	  	                    display2(3,4,"元",2);	 					 }//退格 				   				   if(key_value>=0 && key_value <=9)//有按键输入 ，包括小数点 				  {	 			    				     								 					if(Money_select)		//整数 					     Money_1=Money_1*10+key_value;  					else  					{  Money_2=key_value; 					   back_count=0;	//不影响退格使用 					}  						Money_BUF[0]=Money_1/10000+'0';                      	Money_BUF[1]=Money_1%10000/1000+'0';     	                Money_BUF[2]=Money_1%1000/100+'0';  	                    Money_BUF[3]=Money_1%100/10+'0';  	                    Money_BUF[4]=Money_1%10+'0'; 	                    Money_BUF[5]='.'; 	                    Money_BUF[6]=Money_2+'0';      	                         display2(3,0,Money_BUF,7);	  	                    display2(3,4,"元",2);	 				  }			   				} 		       break ;   		default : break;  	 }	  		  	if( bPass )		 //处理成功 	{ 		bPass = 0; 		pass();	 	 	}  	if( bWarn )	     //处理失败 	{ 		bWarn = 0; 		warn(); 	}  } 	       因为文字超字数了 所以放到这里来了


再好的仿真也不如三流的真硬件。我觉得。

赵老师  您能告诉我这是什么问题吗   因为刚学很多东西不知道 所以 能帮忙解决吗

第一次用proteus和8086仿真以及用emu8086软件，所以能帮帮忙吗  指导一下

学会使用示波器或逻辑分析仪。

8086还在用？


Question: 100以内的哥德巴赫猜想，有个问题

通过验证，两个都是从4开始输出的；但是数量不一样/2，182个，不/2是349个

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

Finding prime numbers - Kenneth Haugland  Different schemas for finding prime numbers explained with code http://www.codeproject.com/Articles/429694/Finding-prime-numbers


Question: CentOs Linux7中C语言代码疑问

引用 3 楼 u011471566 的回复:[quote=引用 1 楼 jianwen0529 的回复:] %Lf //用大写L %lf //小写是指double类型  可是为什么最后那行又变了？好奇怪，刚刚改了下，第一行没问题了，第四个printf（）函数输出就变了[/quote]  谢谢啦，我搞懂了，也是用%Lf才行。书上写错了估计。

引用 1 楼 jianwen0529 的回复:%Lf //用大写L %lf //小写是指double类型  可是为什么最后那行又变了？好奇怪，刚刚改了下，第一行没问题了，第四个printf（）函数输出就变了

%Lf //用大写L %lf //小写是指double类型


Question: 一个c语言循环小问题

在scanf("%c",&x);后面加fflush(stdin);清楚后面多余的字符。

这个问题关系到有缓存输出与无缓存输出的区别。无缓存输出是输入字符之后马上就输出一个字符，而有缓冲输出是输入字符串之后字符串被储存在一个缓存区中，按下回车键之后，缓存区的字符串流才被输出到屏幕上。在你的程序中，你输入了小写的 'a'，按下了回车（等于输入了一个 '\n')，在第一次循环中，scanf读取了字符串流中的 'a'，可是还有一个 '\n' 还在字符串流中，这就被下一次循环读取了。'\n' 肯定不在 'A' 和 'Z' 之间，所以 '\n' 就被原样输出了。 这是我个人理解，具体的你可以参考《C Primer》这本书，里面讲的很详细。 希望对你有帮助。

scanf("%c", &x)；是从键盘缓冲区里拿，但是上次输入的‘\n’还在缓冲区里，所以你的第二次输入就是拿到的回车符

使用能接收回车符的字符前，比如scanf %c,getchar这种，一定要注意输入缓冲区是否有遗留的字符（比如回车符）

用个getchar去接收就好了。

空格，回车也会被当做字符。

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

没有回收垃圾（回车字符），第一次输入a，然后缓存区会有a和\n两个字符，让后scanf取走了a，留下了\n,下一次scanf会直接取走\n

引用 3 楼 jianwen0529 的回复:第二种方法不要用，我试了下我连运行都有问题  用第一种 或者刷新下缓冲 scanf("%c", &x); fflush(stdin); 这个倒是可以，我只是不明白为什么看起来逻辑没什么大问题的小程序会出现这种问题，估计原理还挺复杂，多谢回复

引用 1 楼 jianwen0529 的回复:scanf("%c",&x);//这个是我想的解决方法scanf("%c%*c",&x); getchar();  或者 scanf("%c\n",&x); 感谢回复，加getchar();和我的方法道理差不多，都是多收集一个字符，可是为什么要这样呢？加\n以后运行效果图，解决不了问题


Question: C语言经典问题之指针问题返回字符串中字符的个数

引用 1 楼 qq423399099 的回复:没有看你的str_c的逻辑。 main函数有2个问题： 1.a指针需要分配空间才行，char *a = (char *)malloc(sizeof(char) * 64); 2.你调用str_c引用的第二个参数c,在函数里也没用到，那你传进去干嘛的？c是字符c解决了，就是因为main函数里面的*a没有分配空间，导致出错，这和数组有着不同的地方，谢谢啦

if(*(s+i)=='c') 改为 if(*(s+i)== c) //跟变量c比较，而不是字符 ‘c'

没有看你的str_c的逻辑。 main函数有2个问题： 1.a指针需要分配空间才行，char *a = (char *)malloc(sizeof(char) * 64); 2.你调用str_c的第二个参数c,在函数里也没用到，那你传进去干嘛的？

除了需要对野指针a申请有效的内存空间之外，c的值也是随机的，随意还需要给c赋值一个有效的值。

为什么定义指针之后需要用那个给他分配空间。不是定义之后就已经分配了吗。 我是新手。希望大家能解答一下。谢谢


Question: 初学C，请教一个小问题

m/j得到的数依旧是整形，需要转换成double型。 不论是强制转化还是隐形转换。

#include <stdio.h> int main() {     int j=1,n,m=1;     double i=0;      printf("Please input an number:");     scanf("%d",&n);     while(j <= n)     {         i = i + m *1.0/j;         j = j + 1;         m=-m;     }     printf("总和为:%f\n", i);      return(0); } 类型需要转换一下～

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

数据类型不同导致的问题 要保证没问题，需要显式的进行类型转换 否则两个整数进行四则运算，结果还是整数，而非浮点数

i=i+(double)m/j; //对m进行强制转换为double类型  否则两个整形数相除的会取整操作，比如你程序得出来是0.xxx，但是只取整数部分0

i=i+m/j;   当j > m时 m / j == 0;


Question: 初学C，想请教一下有关结构体的问题。

第一个问题：函数声明，建议在函数体外，最好在文件的前端，头文件以下的地方。 第二个问题：分数和平均分建议使用float类型，因为对于你的数据float的精度和取值范围足够你的使用，double是高精度的，其实也用不了那么大的精度，反而占用更多的内存空间。 第三个问题：输入一次，第二次就直接退出了。原因是输入缓存里有垃圾数据，而getchar()又得到了这些垃圾数据，所以进入default了，这些垃圾数据就是上次输入残留下来的，比如回车符等其他数据。建议使用int类型的1，2，3，4来区分每个功能。 第四个问题：出现乱码一般就是没有找到字符串结束符，在你的程序里也有可能是字符串赋值越界导致。 以下是修改后的程序： 第五个问题：p+i与p++都是做偏移，一个是通过offset便宜量来完成，但本身值不变，p++也是偏移，但其偏移是修改自己的地址值完成的。还有有区别的，区别之处就是对p本身有没有修改。 #include<stdio.h>  #define LEN 20 #define NUM 3 #define CSIZE 4   struct name{     char lname[LEN];     char fname[LEN]; }; struct student{     struct name fun;     float grade[NUM];     float aver; };  void get_score(struct student *p); void calculate_average(struct student *p); void print_each(struct student *p);  void get_score(struct student *p) {     int i, j = 0;     for (i = 0; i < CSIZE;i++)     {         printf("input the %d score of %s %s\n", i + 1, p->fun.fname, p->fun.lname);         for (j = 0; j < NUM; j++)             scanf("%f", &p->grade[j]);         p++;     } } void calculate_average(struct student *p) {     int i, j;     float total = 0;      for (i = 0; i < CSIZE; i++)     {         for (j = 0; j < NUM; j++)         {             total += p->grade[j];         }         p->aver = total/NUM;         total = 0.0; /* note， 每个人的total不一样。 */         p++;     } } void print_each(struct student *p) {     int i, j;      for (i = 0; i < CSIZE; i++)     {         printf("%s %s\t", p->fun.fname, p->fun.lname);         for (j = 0; j < NUM; j++)             printf("%.2f\t", p->grade[j]);         printf("%.2f\n", p->aver);         p++;     } } int main(void) {     int ch;     struct student stu[CSIZE] = {         { "kaihang", "chen" },         { "kaichuan", "chen" },         { "kaixiang", "chen" },         { "youpu", "chen" }     };     while (1)     {         printf("Please input your choice:\n(1: add grade, 2: cal aver, 3: show info, 4: exit): ");         scanf("%d", &ch);          switch (ch)         {             case 1:                 get_score(stu); break;             case 2:                 calculate_average(stu); break;             case 3:                 print_each(stu); break;             default:                 puts("Bye!"); return 0;         }     }     return 0; }

void get_score(struct student *p) {     int i, j = 0;     for (i = 0; i < CSIZE; i++)     {         printf("input the %d score of %s %s\n", i + 1, p->fun.fname, p->fun.lname);         for (j = 0; j < NUM; j++)             scanf("%lf", &p->grade[j]); //scanf 输入double数据必须使用lf，不能用f替代         p++;     } }  int main() {     void get_score(struct student *p);     void calculate_average(struct student *p);     void print_each(struct student *p);     struct student *p;     struct student stu[CSIZE] = {         { "kaihang", "chen" },         { "kaichuan", "chen" },         { "kaixiang", "chen" },         { "youpu", "chen" }     };     while (1)     {         char ch = getchar();         if (ch == '\n')             continue;          switch (ch)         {         case 'd':get_score(stu); break;         case 'e':calculate_average(stu); break;         case 'f':print_each(stu); break;         default:puts("Bye!"); return 0;         }     }     return 0; }  指出两个不妥的地方

p++会改变原来p指针的指向，而(p+i)->是不会的  Debug模式下C程序，发现栈区开辟的存储空间都是使用0CCCCCCCCh来填充4字节单位的，也就是说，栈区开辟的存取局部变量的空间的每一个字节都被0xCC填充了。（为什么用0xCC，这个是int 3h的机器码，下断点用的）两个0xCC合起来输出时恰好对应中文“烫”字。动态分配的空间开辟的堆，VC的Debug用0xCD填充堆的空间，两个0xCD和在一起就是屯了。  单步调试和设断点调试（VS IDE中编译连接通过以后，按F10或F11键单步执行，按Shift+F11退出当前函数；在某行按F9设断点后按F5执行停在该断点处。）是程序员必须掌握的技能之一。

参考 http://blog.csdn.net/yes_i_am/article/details/52003511


Question: 字符回显的基础问题

越界了吧，你ch定义的大小是20，你用strlen求出的是23，而且你还没有结束符

#include<stdio.h> #include<string.h>  int main() {     char ch[20];     int i, len;      printf("enter a row:");     for(i = 0; (ch[i]=getchar()) !='\n'; i++)         ;     ch[i] = 0; /* add '\0' */     printf("reshow:");     len = strlen(ch);     printf("%d\n", len);     for(i = 1; i <= len; i++) {         printf("%c", ch[len-i]);     }     printf("\n");     return 0; }  一般遇到输出字符串时出现乱码，基本上都是没有加上字符串结束标记；建议下次遇到类似问题先检查字符串结束标识是否存在。

Debug模式下C程序，发现栈区开辟的存储空间都是使用0CCCCCCCCh来填充4字节单位的，也就是说，栈区开辟的存取局部变量的空间的每一个字节都被0xCC填充了。（为什么用0xCC，这个是int 3h的机器码，下断点用的）两个0xCC合起来输出时恰好对应中文“烫”字。动态分配的空间开辟的堆，VC的Debug用0xCD填充堆的空间，两个0xCD和在一起就是屯了。

你的输入为什么要这样呢，既然是想输入字符串，就直接scanf("%s",ch);不就行了

windows里常见的内存填充数据含义  * 0xABABABAB : Used by Microsoft's HeapAlloc() to mark "no man's land" guard bytes after allocated heap memory 漱 * 0xABADCAFE : A startup to this value to initialize all free memory to catch errant pointers 涵?  * 0xBAADF00D : Used by Microsoft's LocalAlloc(LMEM_FIXED) to mark uninitialised allocated heap memory 很?  * 0xBADCAB1E : Error Code returned to the Microsoft eVC debugger when connection is severed to the debugger 撅饰 * 0xBEEFCACE : Used by Microsoft .NET as a magic number in resource files 烫烫 * 0xCCCCCCCC : Used by Microsoft's C++ debugging runtime library to mark uninitialised stack memory 屯屯 * 0xCDCDCDCD : Used by Microsoft's C++ debugging runtime library to mark uninitialised heap memory 葺葺 * 0xDDDDDDDD : Used by Microsoft's free() or delete to mark freed heap memory 蕲蕲 * 0xDEADDEAD : A Microsoft Windows STOP Error code used when the user manually initiates the crash  * 0xFDFDFDFD : Used by Microsoft's C++ debugging heap to mark "no man's land" guard bytes before and after allocated heap memory  * 0xFEEEFEEE : Used by Microsoft's HeapFree() to mark freed heap memory

字符串要以\0结尾  for(i=0;(ch[i]=getchar())!='\n';i++) 		;  这句后面加上：  ch[i] = '\0';

for(i=0;(ch[i]=getchar())!='\n';i++) ; ch[i] = '\0'; 设置字符串结束标志

字符数组末尾没有 ‘\0’ 结束符，这样 strlen 求出来的值自然就不对，而且还把回车符算进去了


Question: c语言中传参传指针，为什么打印函数中指针的地址和main函数的地址不一样？

配了一把一样的钥匙而已，都可以开某个门，但两个钥匙本身是不同的东西（或者说材质，硬件上不是同一个东西）

指针指向内容一致，指针本身地址肯定不同！

参数传递，其实就是值传递；即把指针变量里的数据传递给子函数栈上的指针变量，这样，main函数里的指针指向哪个内存地址，那么子函数里的指针变量也就指向的那个内存地址。 具体问题还需要具体分析，最好能把你的代码贴出来，让大家给你分析一下。

实参和形参并不是同一个指针，他们只是指向的内存区域一样而已

http://edu.csdn.net/course/detail/2344 C语言指针与汇编内存地址-一.代码要素 http://edu.csdn.net/course/detail/2455 C语言指针与汇编内存地址-二.函数 http://edu.csdn.net/course/detail/2516 C语言指针与汇编内存地址-三.数组和二维数组 http://edu.csdn.net/course/detail/2517 C语言指针与汇编内存地址-四.三维数组

指针本身是复制过去的，只是他们指向的对象是一样的  你打印 &a[0] 你会发现是一样的了

因为你函数参数是按值传递的，也就是参数是复制的，函数中的指针只是main中指针的复制品，他们的地址当然不同  除非你按引用传递参数，也就是说参数类型为指针的引用

打印的对象是对的么？ #include <stdio.h>   void fun( int a[] ) {          printf( "%-20s0x%X\n", "Parameter address:", a );            // additional code here... }   void main( int argc, char *argv[] ) {          int a[] = { 9, 5, 2, 7 };                   printf( "%-20s0x%X\n", "Source address:", a );            fun( a );                   getchar(); }

从逻辑上来说，传地址肯定一致，你不会把指针的地址传过去了吧？ 指针的值和指针本身的地址不是一个概念

where is the code?


Question: 求提示，怎么让脉冲逐步调高呢？

逐步减少delay的时长？


Question: 初学C，一个小小的结构体问题望解答

非溢出，而是fun函数处理之后的数据没有拿到。 拿到fun处理后的数据有两种方式，一种就是通过返回值，另一种就是通过传入传出参数，即传结构体的地址过去。

关注一下，我也是主学C的

楼上说得都对

传结构体的地址过去就可以了  改2处  ：  void fun( struct gas *name )  //... fun( &name1 );

引用 1 楼 user-6 的回复:没有保存返回值 fun(name1); 改成name1 = fun(name1); 我明白了，谢谢。

#include <stdio.h>   struct gas {          float distance;          float gals;          float mpg; };   void fun( struct gas *name ) {          name->mpg = name->distance + name->gals; }   void main( int argc, char *argv[] ) {          struct gas name1;            scanf( "%f", &name1.distance );          scanf( "%f", &name1.gals );            fflush( stdin );            fun( &name1 );            printf( "%.2f %.2f %.2f%", name1.distance, name1.gals, name1.mpg );                   getchar(); }

你在fun函数中操作的形参name和main函数里的实参name并不是同一个 解决方法： 1.传入指针 2.楼上所说的接收fun的返回值


Question: 请大神帮我看看文件数据读写中出现的问题

fopen, _wfopen Open a file.  FILE *fopen( const char *filename, const char *mode );  FILE *_wfopen( const wchar_t *filename, const wchar_t *mode );  Function Required Header Compatibility  fopen <stdio.h> ANSI, Win 95, Win NT  _wfopen <stdio.h> or <wchar.h> Win NT    For additional compatibility information, see Compatibility in the Introduction.  Libraries  LIBC.LIB Single thread static library, retail version  LIBCMT.LIB Multithread static library, retail version  MSVCRT.LIB Import library for MSVCRT.DLL, retail version    The c, n, and t mode options are Microsoft extensions for fopen and _fdopen and should not be used where ANSI portability is desired.  Return Value  Each of these functions returns a pointer to the open file. A null pointer value indicates an error.   Parameters  filename  Filename  mode  Type of access permitted  Remarks  The fopen function opens the file specified by filename. _wfopen is a wide-character version of fopen; the arguments to _wfopen are wide-character strings. _wfopen and fopen behave identically otherwise.  Generic-Text Routine Mappings  TCHAR.H Routine  _UNICODE & _MBCS Not Defined _MBCS Defined _UNICODE Defined  _tfopen fopen fopen _wfopen    The character string mode specifies the type of access requested for the file, as follows:  "r"  Opens for reading. If the file does not exist or cannot be found, the fopen call fails.  "w"  Opens an empty file for writing. If the given file exists, its contents are destroyed.  "a"  Opens for writing at the end of the file (appending) without removing the EOF marker before writing new data to the file; creates the file first if it doesn’t exist.  "r+"  Opens for both reading and writing. (The file must exist.)  "w+"  Opens an empty file for both reading and writing. If the given file exists, its contents are destroyed.  "a+"  Opens for reading and appending; the appending operation includes the removal of the EOF marker before new data is written to the file and the EOF marker is restored after writing is complete; creates the file first if it doesn’t exist.  When a file is opened with the "a" or "a+" access type, all write operations occur at the end of the file. The file pointer can be repositioned using fseek or rewind, but is always moved back to the end of the file before any write operation is carried out. Thus, existing data cannot be overwritten.  The "a" mode does not remove the EOF marker before appending to the file. After appending has occurred, the MS-DOS TYPE command only shows data up to the original EOF marker and not any data appended to the file. The "a+" mode does remove the EOF marker before appending to the file. After appending, the MS-DOS TYPE command shows all data in the file. The "a+" mode is required for appending to a stream file that is terminated with the CTRL+Z EOF marker.  When the "r+", "w+", or "a+" access type is specified, both reading and writing are allowed (the file is said to be open for “update”). However, when you switch between reading and writing, there must be an intervening fflush, fsetpos, fseek, or rewind operation. The current position can be specified for the fsetpos or fseek operation, if desired.  In addition to the above values, the following characters can be included in mode to specify the translation mode for newline characters:  t  Open in text (translated) mode. In this mode, CTRL+Z is interpreted as an end-of-file character on input. In files opened for reading/writing with "a+", fopen checks for a CTRL+Z at the end of the file and removes it, if possible. This is done because using fseek and ftell to move within a file that ends with a CTRL+Z, may cause fseek to behave improperly near the end of the file.   Also, in text mode, carriage return–linefeed combinations are translated into single linefeeds on input, and linefeed characters are translated to carriage return–linefeed combinations on output. When a Unicode stream-I/O function operates in text mode (the default), the source or destination stream is assumed to be a sequence of multibyte characters. Therefore, the Unicode stream-input functions convert multibyte characters to wide characters (as if by a call to the mbtowc function). For the same reason, the Unicode stream-output functions convert wide characters to multibyte characters (as if by a call to the wctomb function).  b  Open in binary (untranslated) mode; translations involving carriage-return and linefeed characters are suppressed.   If t or b is not given in mode, the default translation mode is defined by the global variable _fmode. If t or b is prefixed to the argument, the function fails and returns NULL.   For more information about using text and binary modes in Unicode and multibyte stream-I/O, see Text and Binary Mode File I/O and Unicode Stream I/O in Text and Binary Modes.  c  Enable the commit flag for the associated filename so that the contents of the file buffer are written directly to disk if either fflush or _flushall is called.  n  Reset the commit flag for the associated filename to “no-commit.” This is the default. It also overrides the global commit flag if you link your program with COMMODE.OBJ. The global commit flag default is “no-commit” unless you explicitly link your program with COMMODE.OBJ.  Valid characters for the mode string used in fopen and _fdopen correspond to oflag arguments used in _open and _sopen, as follows.  Characters in mode String Equivalent oflag Value for _open/_sopen   a _O_WRONLY | _O_APPEND (usually _O_WRONLY | _O_CREAT | _O_APPEND)  a+ _O_RDWR | _O_APPEND (usually _O_RDWR | _O_APPEND | _O_CREAT )  r _O_RDONLY  r+ _O_RDWR  w _O_WRONLY (usually _O_WRONLY | _O_CREAT | _O_TRUNC)  w+ _O_RDWR (usually _O_RDWR | _O_CREAT | _O_TRUNC)  b _O_BINARY  t _O_TEXT  c None  n None    Example  /* FOPEN.C: This program opens files named "data"  * and "data2".It  uses fclose to close "data" and  * _fcloseall to close all remaining files.  */  #include <stdio.h>  FILE *stream, *stream2;  void main( void ) {    int numclosed;     /* Open for read (will fail if file "data" does not exist) */    if( (stream  = fopen( "data", "r" )) == NULL )       printf( "The file 'data' was not opened\n" );    else       printf( "The file 'data' was opened\n" );     /* Open for write */    if( (stream2 = fopen( "data2", "w+" )) == NULL )       printf( "The file 'data2' was not opened\n" );    else       printf( "The file 'data2' was opened\n" );     /* Close stream */    if( fclose( stream ) )       printf( "The file 'data' was not closed\n" );     /* All other files are closed: */    numclosed = _fcloseall( );    printf( "Number of files closed by _fcloseall: %u\n", numclosed ); }   Output  The file 'data' was opened The file 'data2' was opened Number of files closed by _fcloseall: 1   Stream I/O Routines  See Also   fclose, _fdopen, ferror, _fileno, freopen, _open, _setmode

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

你好，我怀疑是结构体对齐问题，但是用了#pragma pack还是不行！

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


Question: 关于GCC 优化选项的问题

gcc --help gcc -v --help

-fdata-sections         place data items into their own section

-R                      fold data section into text section

man gcc 里有所有选项的解释。

引用 2 楼 zhao4zhong1 的回复:加const？并不行

引用 2 楼 zhao4zhong1 的回复:加const？ 加const 一般不都是在.data段吗，我先试试

加const？

或者说，优化选项-O2到底做了哪些优化，网上基本没有说明，只是弄了一堆选项 -fthread-jumps            -falign-functions  -falign-jumps            -falign-loops  -falign-labels            -fcaller-saves            -fcrossjumping            -fcse-follow-jumps  -fcse-skip-blocks            -fdelete-null-pointer-checks            -fdevirtualize -fdevirtualize-speculatively            -fexpensive-optimizations            -fgcse  -fgcse-lm             -fhoist-adjacent-loads            -finline-small-functions            -findirect-inlining            -fipa-cp            -fipa-cp-alignment            -fipa-sra            -fipa-icf            -fisolate-erroneous-paths-dereference            -flra-remat            -foptimize-sibling-calls            -foptimize-strlen            -fpartial-inlining            -fpeephole2            -freorder-blocks-algorithm=stc            -freorder-blocks-and-partition -freorder-functions            -frerun-cse-after-loop             -fsched-interblock  -fsched-spec            -fschedule-insns  -fschedule-insns2            -fstrict-aliasing -fstrict-overflow            -ftree-builtin-call-dce            -ftree-switch-conversion -ftree-tail-merge            -ftree-pre            -ftree-vrp            -fipa-ra


Question: C语言指针之删除字符串中的数字

#include <stdio.h> #include <ctype.h>  void del_digit(char *str) {   int i, j;   while (*str) {     while (isdigit(*str)) {       for(i = 0, j = 1;*(str + i) = *(str + j), *(str + j) != 0; i++, j++);       *(str + j) = '\0';     }     *str++;   } }  int main(void) {   char str[] = "d32a2b";   del_digit(str);   printf("%s\n", str);   return 0; }

引用 4 楼 Mikeoperfect 的回复:[quote=引用 3 楼 qq_36409192 的回复:] #include <stdio.h> #include <stdlib.h> int main () { 	int i,j; 	char *str=(char *)malloc(60*sizeof(char)); 	scanf("%s",str); 	for(i=0;str[i];i++) 	{ 		if(str[i]<'9'&&str[i]>'0') 		{ 			for(j=i+1;str[j];j++) 				str[j-1]=str[j]; 			str[j-1]='\0'; 			i--; 		} 	} 	printf("%s\n",str); 	free(str); 	return 0; }数组当然好做了，重点就是指针不好弄[/quote] 数组退化不就是指针了，str[i]退化为指针就是*(str+i)。

引用 5楼我是你的主体 的回复:[quote=引用 1 楼 paschen 的回复:] *(str+i)='\0';  改成：  *(str+j)='\0';可否解释一二呢，确实起到了作用[/quote]删除数字之后的结尾在j  而i是删除前的长度

引用 2 楼 zhao4zhong1 的回复:仅供参考：#include <stdio.h> #include <string.h> char s[256]; char *p; int r,n,i; int main() {     while (1) {         printf("请输入一行文字(空行结束),\"%%20\"将替换为\" \",\"你懂得\"将替换为\"XXXXXX\":\n");         fgets(s,256,stdin);         if ('\n'==s[0]) break;         p=s;         while (1) {             p=strstr(p,"%20");             if (p) {                 memmove(p+1,p+3,strlen(p)-3+1);                 p[0]=' ';             } else break;         }         p=s;         while (1) {             p=strstr(p,"你懂得");             if (p) {                 memmove(p+6,p+6,strlen(p)-6+1);                 for (i=0;i<6;i++) p[i]='X';             } else break;         }         printf("%s",s);     }     return 0; } //请输入一行文字(空行结束),"%20"将替换为" ","你懂得"将替换为"XXXXXX": //abcdefg%20helloworld%20something.pdf //abcdefg helloworld something.pdf //请输入一行文字(空行结束),"%20"将替换为" ","你懂得"将替换为"XXXXXX": //这是测试文字你懂得，在这个你懂的地方，就得做你懂得的事 //这是测试文字XXXXX，在这个你懂的地方，就得做XXXXX的事 //请输入一行文字(空行结束),"%20"将替换为" ","你懂得"将替换为"XXXXXX": //   果然是仅供参考，这里面都不知道出现了多少不知名的函数了。。。。

引用 1 楼 paschen 的回复:*(str+i)='\0';  改成：  *(str+j)='\0';可否解释一二呢，确实起到了作用

引用 3 楼 qq_36409192 的回复:#include <stdio.h> #include <stdlib.h> int main () { 	int i,j; 	char *str=(char *)malloc(60*sizeof(char)); 	scanf("%s",str); 	for(i=0;str[i];i++) 	{ 		if(str[i]<'9'&&str[i]>'0') 		{ 			for(j=i+1;str[j];j++) 				str[j-1]=str[j]; 			str[j-1]='\0'; 			i--; 		} 	} 	printf("%s\n",str); 	free(str); 	return 0; }数组当然好做了，重点就是指针不好弄

*(str+i)='\0';  改成：  *(str+j)='\0';


Question: 汉诺塔递归算法中的回归是如何体现的

引用 3 楼 qq_25980231 的回复:[quote=引用 2 楼 qq_36409192 的回复:] 回归的过程，其实就是结束每一层递归的过程。  就是这一点不明白，在程序中是如何体现结束每一层递归的？ 由n到n-1,....最后到1，到1 的时候不直接出去了吗，如何结束每一层递归的，感觉只有递推啊[/quote] 递归，其实就是在每一层的语句中，套用该函数，直到找到出口位置。楼主所说的回归，其实就是，找到这个出口以后，由于这个函数是在上一层函数中套用的，那么你找到这个出口以后就相当于你上个函数的递归函数执行结束了，自然而然就得回到前一个函数，依次下去，最终也就结束函数的进行。  理解的过程，需要自己在写代码的过程中去体会，我说的你可能也听的不是很明白。如果楼主还不能理解，那么我只能建议楼主去多写写代码，看看别人写的递归，自己多思考下这个过程了。

单步类的实例“构造”或“复制”或“作为函数参数”或“作为函数返回值返回”或“参加各种运算”或“退出作用域”的语句对应的汇编代码几步后，就会来到该类的“构造函数”或“复制构造函数”或“运算符重载”或“析构函数”对应的C/C++源代码处。  VC调试时按Alt+8、Alt+7、Alt+6和Alt+5,打开汇编窗口、堆栈窗口、内存窗口和寄存器窗口看每句C对应的汇编、单步执行并观察相应堆栈、内存和寄存器变化，这样过一遍不就啥都明白了吗。 对VC来说，所谓‘调试时’就是编译连接通过以后，按F10或F11键单步执行一步以后的时候，或者在某行按F9设了断点后按F5执行停在该断点处的时候。

引用 2 楼 qq_36409192 的回复:回归的过程，其实就是结束每一层递归的过程。  就是这一点不明白，在程序中是如何体现结束每一层递归的？ 由n到n-1,....最后到1，到1 的时候不直接出去了吗，如何结束每一层递归的，感觉只有递推啊

回归的过程，其实就是结束每一层递归的过程。

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


Question: 求助，关于c语言中float和double型变量赋值相同的问题

就是double的尾数是52位吧 前边是0说明减去的float的尾数位数。

引用 8 楼 赵4老师的回复:看不懂，结合MSDN或百度中搜相关不懂的函数说明，并单步执行看或加printf();getchar();语句输出每一步中间结果使劲看。 好，谢谢老师，我去看一下

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

先自己把 1.2 转写为二进制小数看看

引用 2 楼 DelphiGuy 的回复:23、52位是指二进制，十进制精度哪有那么高。 对啊，所以我的困惑就是： 23和52都是二进制情况下的精度，10进制下float 6~7位，double 15~16位，但为什么在我实验过程中（上图），会出现直到52位仍然有数字的情况，而且到60位时，又恰好出现了8个0，这是巧合还是错误

引用 1 楼 user-6 的回复:这个和浮点数的精度有关    float：   1bit（符号位） 8bits（指数位） 23bits（尾数位）   double：   1bit（符号位） 11bits（指数位） 52bits（尾数位）     float：2^23 = 8388608，一共七位，这意味着最多能有7位有效数字，但绝对能保证的为6位，也即float的精度为6~7位有效数字；   double：2^52 = 4503599627370496，一共16位，同理，double的精度为15~16位。 但是就拿double来说，既然它的精度只有15~16位，那么为什么会出现上面最多可以在52位上有数字的情况呢？

23、52位是指二进制，十进制精度哪有那么高。


Question: 大家好  在做oj上的一个题目的时候遇到麻烦了 大家帮忙分析一下

引用 6 楼 zhao4zhong1 的回复:Accept多谢啊，经验不足，没见过这个缩写。

Accept

引用 2 楼 qq423399099 的回复:网上找下AC的代码吧。 1.看看你们的输入输出格式是不是一致 2.多测试一些样例你好  你说的ac的代码是什么意思？是acm吗？

引用 1 楼 cfjtaishan 的回复:出现多次打印17，检查一下你的输入是否有非数字的。除了将scanf的返回值与EOF比较，另外还需要判断输入是否合法； 以下是使用递归函数完成的： #include<stdio.h> #include<stdlib.h>  int count_time(int *array, int len, int num);  static int comp(const void*a,const void*b) {     return *(int*)b-*(int*)a; } static int total_tm = 0;  int main() {     int i = 0, ret;     int *array;     int number_of_man;      int sum_tm = 0;     printf("Please input the number of men(CTR+D to exit):\n");     ret = scanf("%d", &number_of_man);     while (ret != EOF && ret == 1) {         array = (int *)malloc(number_of_man * sizeof(int));         if (!array) {             fprintf(stderr, "malloc error!\n");             return -1;         }         for(i = 0; i < number_of_man; i++)             scanf("%d", array + i);          qsort(array, number_of_man, sizeof(int), comp);         sum_tm = count_time(array, number_of_man, number_of_man);         free(array);         printf("total time is %d\n", sum_tm);         total_tm = 0;         printf("Please input the number of men(CTR+D to exit): \n");         ret = scanf("%d", &number_of_man);     }       return 0; }  /* len: the number of man */ int count_time(int *array, int len, int num) {     if(num == 1) {         total_tm += array[0];     } else if(num == 2) {         total_tm += array[0];     } else if(num == 3) {         total_tm += (array[0] + array[1] + array[2]);     } else {         if((2*array[1]) >= (array[0]+array[num-2])) {             total_tm += (array[0] + array[1] + 2 * array[num-1]);             array[0] = 0;             array[1] = 0;             num -= 2;             qsort(array, len, sizeof(int), comp);             total_tm = count_time(array, len,  num);         } else if((2*array[1])<(array[0]+array[num-2]))         {             total_tm += (2 * array[num-2] + array[num-1] + array[0]);              array[0] = 0;             array[1] = 0;             num -= 2;             qsort(array, len, sizeof(int),comp);             total_tm = count_time(array, len, num);         }     }     return total_tm; }    你好 非常感谢你可以帮忙检查并且回复一段自己的代码，我马上就仔细研究一下你说的问题，非常感谢！

引用 楼主 NDFour 的回复:我在做学校的oj上的一个C语言编程题目 题目如下     这是代码提交后的错误界面，，也没看懂什么意思     下面是我自己写的代码，有点乱，，，看起来有点辛苦，实在不好意思  话说我的代码就是按照上面题目下面的提示写出来的，本地测试出来的结果是正确的，但是不知道提交后测试哪些数据时出了问题 ，所以麻烦大家帮忙看一下，代码我疏忽了哪里，还请提示一下。 万分感谢！！   注：array数组用于存放用户 输入的每个人过桥所用的时间  #include<stdio.h> #include<stdlib.h> //用来给时间数组排序 int comp(const void*a,const void*b) {     //输出的数组是按从大到小排列的     return *(int*)b-*(int*)a; }  int main() {     int i=0;     int *array;      int number_of_man;     while(scanf("%d",&number_of_man)!=EOF)     {         int n_of_man=number_of_man;         array=(int*)malloc(n_of_man*sizeof(int));          for(i=0; i<n_of_man; i++)         {             scanf("%d",(array+i));         }         qsort(array,n_of_man,sizeof(int),comp);          int sum_of_time=0;  loop:         //1个人的时候         if(n_of_man==1)             sum_of_time+=array[0];         //两个人的时候         else if(n_of_man==2)             sum_of_time+=array[0];         //3个人的时候         else if(n_of_man==3)             sum_of_time+=(array[0]+array[1]+array[2]);  //大于或等于4个人的时候         else         {             //模式1             if((2*array[1])>=(array[0]+array[n_of_man-2]))             {                 sum_of_time+=(array[0]+array[1]+(2*array[n_of_man-1]));                 array[0]=0;                 array[1]=0;                 n_of_man-=2;                 qsort(array,number_of_man,sizeof(int),comp);                 goto loop;             }  //模式2             else if((2*array[1])<(array[0]+array[n_of_man-2]))             {                 //大于等于4个人的时候                 sum_of_time+=((2*array[n_of_man-2])+array[n_of_man-1]+array[0]);                  array[0]=0;                 array[1]=0;                 n_of_man-=2;                 qsort(array,number_of_man,sizeof(int),comp);                 goto loop;             }         } //初始化数组         int i=0;         for(i=0; i<number_of_man; i++)             array[i]=0;         printf("%d\n",sum_of_time);         n_of_man=0;         number_of_man=0;     }      return 0; }你好 非常感谢你可以帮忙检查并且回复一段自己的代码，我马上就仔细研究一下你说的问题，非常感谢！


Question: 用c语言画棋盘

引用 1 楼 c_vs_noob的回复:我是根据这个写的  大佬，那个构成棋盘的线条是怎么从键盘上打出来的哦

别人的有continue的，你不加continue，就需要把全部的if都改成else if ，或者switch break结构

楼主如果想用C玩玩图形、小游戏编程，可以了解一下EasyX，EasyX是Windows平台最简单的绘图函数库（名副其实），兼容BC和TC的绘图函数，在VC下用EasyX来编程跟在TC下编程绘图差不多是完全一样的。EasyX既可以绘图，也支持图像显示和处理。  下载一个EasyX包，里面有完整的函数手册EasyX_Help.chm，有示例。EasyX官网有很多网友上传的实例，包括游戏。  仅供参考： 用绘图语句画机器猫（初学C语言的同学必看） http://blog.163.com/tab_98/blog/static/1192409720150316223680/

用 if ... else if if(i==0 && j==0) 的时候 后面的： if(i==0) 。。。 if(j==0) 。。。 还会执行

条件i == max - 1  && j == max - 1的时候是不是应该有一个回车？

我是根据这个写的

用 定位 X  Y 坐标的方法画 更直观 容易理解   for(int i=0;i<max*max;++i) { int x=i%max; int y=i/max; 在这上面两个表达式计算后 整个棋盘每个点的X ,Y坐标都可以唯一确定了,接着你就可以根据坐标画对应的符号 在画完符号后 接一个换行控制 if(i%max==max-1) 当此条件成立的时候输出换行 } 我一直是写的C++   C的输入输出不会写   所以就不具体写了

仅供参考：#pragma comment(lib,"user32") #pragma comment(lib,"gdi32") #include <stdio.h> #include <stdlib.h> #include <windows.h> HWND WINAPI GetConsoleWindow(); void HideTheCursor() {     CONSOLE_CURSOR_INFO cciCursor;     HANDLE hStdOut = GetStdHandle(STD_OUTPUT_HANDLE);      if(GetConsoleCursorInfo(hStdOut, &cciCursor)) {         cciCursor.bVisible = FALSE;         SetConsoleCursorInfo(hStdOut, &cciCursor);     } } void ShowTheCursor() {     CONSOLE_CURSOR_INFO cciCursor;     HANDLE hStdOut = GetStdHandle(STD_OUTPUT_HANDLE);      if(GetConsoleCursorInfo(hStdOut, &cciCursor)) {         cciCursor.bVisible = TRUE;         SetConsoleCursorInfo(hStdOut, &cciCursor);     } } int main() {     HWND  hwnd;     HDC   hdc;     HFONT hfont;      system("color F0");     system("cls");     HideTheCursor();     hwnd  = GetConsoleWindow();     hdc   = GetDC(hwnd);     hfont = CreateFont(48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "华文楷体");     SelectObject(hdc,hfont);     TextOut(hdc,10,10,"地球人都知道！",14);     MoveToEx(hdc,5,5,NULL);     LineTo(hdc,300,  5);     LineTo(hdc,300, 60);     LineTo(hdc,  5, 60);     LineTo(hdc,  5,  5);     DeleteObject(hfont);     ReleaseDC(hwnd,hdc);     getchar();     system("color 07");     system("cls");     ShowTheCursor();     return 0; }


Question: 华为oj——字符串最后一个单词的长度

问题有二： 1、严格的 c 语言遵循一条规则：所有的变量在函数一开始的地方集中申请，变量申请前不得有其他代码。你的 int the_count = 0; 应该提到前面来，放到 string_name 和 temp 一道申请。你的程序如果是 c 程序（扩展名用的.c）就会编译报错，如果是 c++ （扩展名用的.cpp），编译器会忽略这条规则。 2、string_name[128] 数组没初始化，输入完成后 c 的值是数组长度，cal 函数直接 p[c] 这样用是有问题的，得到的值是未知的。解决办法是初始化 string_name 或者输入完成后在 do…while 循环后面加句 string_name[c] = 0;

system("pause"); 这个命令只在windows有效吧，去掉试试

终于改对了，好久没敲过了，看样子编程真的要细心啊== #include <stdio.h> #include <string.h> #include <stdlib.h>  void main() { 	char string_name[128]; 	int c = 0; 	int n = 0; 	int t = 0;  	gets(string_name); 	c = strlen(string_name);  	while (!(string_name[c] >= 'a'&&string_name[c] <= 'z') && 		!(string_name[c] >= 'A'&&string_name[c] <= 'Z')) 	{ 		c--; 	} 	t = c; 	while (string_name[t] != '\0'&&string_name[t] != ' '&&t >= 0 		&& ((string_name[t] >= 'a'&&string_name[t] <= 'z') || (string_name[t] >= 'A'&&string_name[t] <= 'Z'))) 	{ 		t--; 		n++; 	}   	printf("%d\n", n); 	system("pause"); }

引用 8 楼 ghost129 的回复:for (t = c; p[t] != '\0' && p[t] != ' '; t--)改成 for (t = c; p[t] != '\0' && p[t] != ' ' && t >= 0; t--) 恩恩，这里忘记了。但提交后还是运行错误=_=

引用 6 楼 cfjtaishan 的回复:[quote=引用 4 楼 innocent_sheld 的回复:] [quote=引用 2 楼 cfjtaishan 的回复:]  #include "stdio.h" #include "string.h" #include "stdlib.h" /* #include <stdio.h> #include <string.h> #include <stdlib.h> #include <ctype.h> */ int cal(char p[128]); int c = 0;  int main() {     char string_name[128], temp;     int the_count = 0;      printf("Please input the string:");     do     {         temp = getchar();         string_name[c] = temp;         c++;     } while (temp != '\n');      the_count = cal(string_name);     printf("the length of the last word is %d\n", the_count);     //system("pause");      return 0; } int cal(char p[128]) {     int n = 0;     int t = 0; #ifndef  isalpha     puts("haha");     while (!(p[c] >= 'a'&&p[c] <= 'z') &&             !(p[c] >= 'A'&&p[c] <= 'Z'))     {         c--;     } #else     while (!isalpha(p[c]))         c--; #endif     for (t = c; p[t] != '\0' && p[t] != ' '; t--) {         n++;     }     return n; }  没有逻辑问题，对你的代码稍微改了一些格式。 请问： cal函数中的#ifndef不是用来预编译头的吗？在这里有什么用吗？ include把双引号换成尖括号有什么不同吗？[/quote] #ifndef这个是预编译，这里的使用和头文件里的使用效果是一样的； 一般函数库的头文件或者系统的头文件都用<>括起来，自定义的头文件用""括起来。[/quote] 搜嘎，但是我改了一下，还是运行错误=_=

引用 4 楼 innocent_sheld 的回复:[quote=引用 2 楼 cfjtaishan 的回复:]  #include "stdio.h" #include "string.h" #include "stdlib.h" /* #include <stdio.h> #include <string.h> #include <stdlib.h> #include <ctype.h> */ int cal(char p[128]); int c = 0;  int main() {     char string_name[128], temp;     int the_count = 0;      printf("Please input the string:");     do     {         temp = getchar();         string_name[c] = temp;         c++;     } while (temp != '\n');      the_count = cal(string_name);     printf("the length of the last word is %d\n", the_count);     //system("pause");      return 0; } int cal(char p[128]) {     int n = 0;     int t = 0; #ifndef  isalpha     puts("haha");     while (!(p[c] >= 'a'&&p[c] <= 'z') &&             !(p[c] >= 'A'&&p[c] <= 'Z'))     {         c--;     } #else     while (!isalpha(p[c]))         c--; #endif     for (t = c; p[t] != '\0' && p[t] != ' '; t--) {         n++;     }     return n; }  没有逻辑问题，对你的代码稍微改了一些格式。 请问： cal函数中的#ifndef不是用来预编译头的吗？在这里有什么用吗？ include把双引号换成尖括号有什么不同吗？[/quote] #ifndef这个是预编译，这里的使用和头文件里的使用效果是一样的； 一般函数库的头文件或者系统的头文件都用<>括起来，自定义的头文件用""括起来。

引用 1 楼 jianwen0529 的回复:system("pause"); 这个命令只在windows有效吧，去掉试试 去掉这个之后就显示不了最后的printf语句了==

引用 2 楼 cfjtaishan 的回复: #include "stdio.h" #include "string.h" #include "stdlib.h" /* #include <stdio.h> #include <string.h> #include <stdlib.h> #include <ctype.h> */ int cal(char p[128]); int c = 0;  int main() {     char string_name[128], temp;     int the_count = 0;      printf("Please input the string:");     do     {         temp = getchar();         string_name[c] = temp;         c++;     } while (temp != '\n');      the_count = cal(string_name);     printf("the length of the last word is %d\n", the_count);     //system("pause");      return 0; } int cal(char p[128]) {     int n = 0;     int t = 0; #ifndef  isalpha     puts("haha");     while (!(p[c] >= 'a'&&p[c] <= 'z') &&             !(p[c] >= 'A'&&p[c] <= 'Z'))     {         c--;     } #else     while (!isalpha(p[c]))         c--; #endif     for (t = c; p[t] != '\0' && p[t] != ' '; t--) {         n++;     }     return n; }  没有逻辑问题，对你的代码稍微改了一些格式。 请问： cal函数中的#ifndef不是用来预编译头的吗？在这里有什么用吗？ include把双引号换成尖括号有什么不同吗？


Question: int main

有参数是为了接受dos下运行时的传递参数或者文件关联时候传递文件路径等等信息 不管如何，你写上参数总是不会错了，而且就多打敲几下键盘的事情  _tmain 是vs兼容ASCII 和 宽字符版本参数的主函数入口 主要是参数的区别，前者使用char**传递过来，后者使用wchar_t**传递过来 其他方面应该没什么差别

在命令行中执行该程序时参数才有意义。 main和_tmain是一个东西，typedef定义的别名。

首先，这个_tmain()是为了支持unicode所使用的main一个别名而已，既然是别名，应该有宏定义过的，在哪里定义的呢？就在那个让你困惑的<stdafx.h>里，有这么两行 #include <stdio.h> #include <tchar.h> 我们可以在头文件<tchar.h>里找到_tmain的宏定义      #define _tmain      main 所以，经过预编译以后， _tmain就变成main了，这下明白了吧

第一个问题：是否需要传递参数，要看实际是否需要。如果需要在执行程序时由系统传递参数，则需要定义成：int main (int argc, char *argv[])否则，参数为void即可。 第二个问题，这两个接口意义是一样的，只是用在不同的环境下，Linux环境下编程就是使用int main(void)。

main（）在命令行中执行该程序时传递你需要的参数。 _tmain是typedef定义的别名，应该需要加上其他的头文件。还有许多类似的 比如常见的_bool.

VS IDE中，在不明白的符号上点鼠标右键，选转到定义。

问题1：在你需要处理命令行参数或者环境变量的时候  问题2：前者是多字节版本的，后者是多字节或UNICODE的通用版本（仅VS）


Question: 一个小程序的输出问题

另外，建议char ch;改成int ch;当然在你的这个函数里不影响，若是和EOF比较时若ch是char类型就会有问题了。

在Linux下，回车符的ASCII值是10，通过man ascii可以看到。也可以通过 putchar(10);看一下是否相当于一个回车或者相当于printf("\n");


Question: fread()与fwrite()在C语言中的运用

fread fwrite都是整块内容的io操作  你写文件是把整个结构体的内存写入（sizeof(struct student_score)大小） 读的时候就是一个逆向行为，把读取到的整块数据（sizeof(struct student_score)大小），赋给一个结构体

fwrite不会自动换行，只有在关闭文件的时候会自动添加结束符。 写入就是把内存中的数据放到文件中，读取是把文件中的数据取回内存中。因为写入的时候是按照sizeof(结构体)的大小写入的字节数，读取也是如此。又因为结构体大小已知，内存分布也已知：前10个字节是name，接着4个字节是num，以此类推。所以在读的时候按照这个内存分布分配数据就是了。

fwrite写入的数据是不会自动换行的，另外，以wb打开的文件，写入的数据也可能是有乱码，不过这是正常的，你只需要通过fread以相反方式读取即可得到写入的数据。fread和fwrite需要配套使用，即使用fwrite写入的数据，反过来使用fread可以读取到写入的数据。

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


Question: c

网上搜索 “c FILE”

#include <stdio.h> #include <sys/types.h> #include <fcntl.h> #include <unistd.h>  int main(void) {     int fd;     unsigned int pos = 1024 * 1024 * 1024;      fd = open("1.txt", O_CREAT|O_WRONLY, 0666);     if (fd <= 0) {         fprintf(stderr, "open error!\n");         return -1;     }      lseek(fd, pos, SEEK_SET);      write(fd, "a", 1);     close(fd);      return 0; } 试一下这种方式～1.txt文件大小超过1G

long writeFileData(const char * filename, const char * chScrData, size_t lenScrData,bool isAppend) {     if( filename==NULL||chScrData==NULL||lenScrData<=0 ) return -1;          FILE * file = NULL;     if( isAppend )     {         file = fopen(filename, "a");     }     else {         file = fopen(filename, "w");     }          if( file!=NULL)     {         long len = ftell(file);         if( len>0) fseek(file, len, SEEK_END);         fwrite(chScrData,sizeof(char),lenScrData,file);         fseek(file, 0,SEEK_END);         len = ftell(file);         fclose(file);         return len;     }     else      {         return -1;     } } int main(int argc, const char * argv[]) {     // insert code here...     long blockSize = 1024*4;     long blockCount = 1024*256;     char * data = (char*)malloc(blockSize);     memset(data, 0, blockSize);     long i = 0;     while (1)     {         if(i>=blockSize)             break;         data[i] = i;         i++;     }     for ( i=0; i<blockCount; i++)     {         writeFileData("/users/XXX/Desktop/abc", data, blockSize, true);     }         return 0; }

一直往文件中写数据不就好了吗。


Question: 误打误撞 不知为何要这样

谢谢大家  学习了

那个是取一个字符操作，把前一次未读取的换行符给读取出来并且弃用 那么就可以读下一行，否则读取字符串会为空  而gets会读取\n，并且转为\0，所以这个不需要getc读取换行符

引用 2 楼 paschen 的回复:接收了输入完留在缓冲区中的换行符\n  否则会被后面的接收了从而使得结果不正确 正解；可以设计puts函数来验证 gets_s(c);//真的gets_s是接收了输入完留在缓冲区的回车？ 	puts("Right?"); 	puts(c);//接收了回车;puts会打印出回车来

因为你在输入完组数后要输入字符串；在有了字符串之后才可以进行排序；

使用能读取回车符的输入函数前，应该注意输入缓冲区是否有遗留的字符（比如回车符）

scanf读取一个字符之后会在缓冲区留一个‘\n’，这个换行符会在下次正确读取前一直在缓冲区里， 你可以用你那个函数，也可以用getchar();

接收了输入完留在缓冲区中的换行符\n  否则会被后面的接收了从而使得结果不正确

应该是接收的输入数字后的回车


Question: 我这个链表头部怎么插不进去

你插入头部之所以失败，在于你else分支里的这句：s = current; 你要想在add函数内改变指针的指向必须传一级指针的引用或者二级指针才行（因为实参和形参并不是同一个指针，它们只是指向了一块相同的内存区域而已）

引用 1 楼 jianwen0529 的回复:void Add(struct Student *&s) // 让s成为引用，这样子才能真正修改指针值 // 其他代码 if     Student *temp = s;     while         temp = s->link; //此处启用临时指针，因为此时对s的修改会影响实参，所以不能直接赋值给s         position--;     current->link = temp->link;     temp->link = current;  else //同你的代码  修正下，红色标注位置  while         temp = temp->link; //此处启用临时指针，因为此时对s的修改会影响实参，所以不能直接赋值给s         position--;


Question: 请教一个问题大神们

你单步跟踪程序运行，观察程序执行流程以及变量变化情况，自己就可以想通原因了

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

prime number意思是质数。 3*3<=6false是跳出循环，之前为2是进入if 已经被判断为非质数了

num每自增1，下面的for语句都会先把div重置为2的，2*2=4，4<6,所以进入for循环


Question: C语言经典问题之读取到某字符串时停止读取

strstr

#include <stdio.h> #include <string.h> int main(int argc, const char * argv[]) {     // insert code here...      char s[100];     char *substr = 0;     while (1)     {         printf("Input string:");         fflush(stdout);         rewind(stdin);         fgets(s,100,stdin);         if((substr = strstr(s, "$$$")))         {             s[substr - s] = '\0';             printf("sub:%s\n",s);                  break;         }         else             printf("src:%s\n",s);     }          return 0; }

#include <stdio.h> #include <string.h>  #define  MAX_STR_LEN    1024  int main(void) {      char buff[MAX_STR_LEN], *substr;      while (fgets(buff, MAX_STR_LEN, stdin)) {         if ((substr = strstr(buff, "$$$"))) {             *substr = 0;             printf("%s\n", buff);             break;         }         printf("%s", buff);      }     return 0; }   建议使用fgets，因为从安全角度上考虑，fgets更安全，不会导致输入的数据越界。

私聊，给你代码，加我微信2423824433

纯手打，有什么编译错误你自己修正下  #include <stdio.h> #include <string.h>  int main(int argc, char **argv) {     char buf[1024];     while(!gets(buf))     {         char *substr = 0;         if(substr = strstr(buf, "$$$"))         {             *substr = '\0';             printf(buf);             break;         }         else             printf(buf);     } }


Question: 目前流行的操作系统到底有没有支持用户级线程

用户线程又不需要操作系统支持, 自己随手写个就是了,  我前不久写了个 javascript 版本的, 跑着还不错...

http://blog.csdn.net/debugingstudy/article/details/12668389 这篇博客或许对你的问题有帮助～

大部分linux或者unix的线程模型是1:1的，一个内核线程对应一个用户线程。单纯的用户级线程库应该很少，但是有这样一个机制可以实现：调度激活机制， 内核创建一个调度激活对象，通过upcall告诉用户线程库可以使用这个调度激活对象来执行线程，然后用户级线程库调度一个线程在该激活对象上来执行。但是具体哪个系统实现了不清楚。一般的情况是在线程上再使用协程，这个协程就可以认为是你说的完全是用户级“线程”。

jvm  ？


Question: 返回值为HANDLE 间接级别不同

typedef void * HANDLE;  直接把指针赋值给Int 需要强制转换， 64位系统下还有可能会被截短  建议就用 void *

谢谢各位！解决了

HANDLE  V_OpenProcess(int ProcessID) 试试


Question: C语言经典问题之显示字符串n次

谢啦

for(j=0;a[j]!='0';j++) 这一行应该是  for(j=0;a[j]!='\0';j++)  ‘0’只是一个普通的字符0，字符串的结尾是'\0'


Question: 如何通过SIMD指令做这样的操作？

Intel是小端,所以应该是0x0f,0x0f,0x0e,0x0e...这样逆序

https://msdn.microsoft.com/en-us/library/bb531427(v=vs.90).aspx 查MSDN是Windows程序员必须掌握的技能之一。

uint8_t a[32] = {0,1,2,3,4,5,6,7,8,                 9,10,11,12,13,14,15,16,                 17,18,19,20,21,22,23,24,                 25,26,27,28,29,30,31} ; __m256i aa = _mm256_loadu_si256((__m256i *)a); __m256i shuffle_1 = _mm256_set_epi8(0x00,0x00,0x01,0x01,0x02,0x02,0x03,0x03,0x04,0x04,0x05,0x05,0x06,0x06,0x07,0x07,                                     0x08,0x08,0x09,0x09,0x0a,0x0a,0x0b,0x0b,0x0c,0x0c,0x0d,0x0d,0x0e,0x0e,0x0f,0x0f);    aa = _mm256_shuffle_epi8 (aa, shuffle_1);         for(j=0;j<32;j++){                 printf("%d  ",((int8_t*)&aa)[j]);         }    这段代码的输出为什么是 15  15  14  14  13  13  12  12  11  11  10  10  9  9  8  8  23  23  22  22  21  21  20  20  19  19  18  18  17  17  16  16  非常不理解

求大家出手相助！


Question: c 语言的小问题 求解答

仅供参考：#include <stdio.h> int main() {     int a,b,n,v,r,k;     char buf[80];     char *p;      k=0;     r=EOF;     while (1) {         if (EOF==r) {             fgets(buf,80,stdin);             p=buf;         }         while (1) {             r=sscanf(p,"%d%n",&v,&n);             if (1==r) {k++;break;}             if (EOF==r) break;             p++;         }         if (EOF==r) continue;         p+=n;         if (1==k) a=v;         if (2==k) {             b=v;             break;         }     }     printf("%d,%d\n",a,b);     return 0; }

输入的内容不合格式，不会被scanf提取出去，仍然在输入流中 printf("wrong f,try again:\n"); 之前应该先清除输入流中的剩余内容 比如用 getchar 吃掉那些字符，包括最后的回车


Question: 求助！如何用SIMD指令完成如下的选择赋值?

引用 1 楼 zhao4zhong1 的回复:先浏览一遍intrin.h ？ 同时在MSDN里面参考其中的函数

先浏览一遍intrin.h ？


Question: 未声明标识符

谢谢老师们，问题解决了。

#include "stdio.h" #include<math.h> #define F(y,t)(y+2*exp(4*t)) #define w(t)((2.0/3.0)*exp(4.0*t)-(11.0/3)*exp(t)) void main() { 	int i, n = 10000; 	double h = 0.0001, y, t, y0 = -3, t0 = 0; 	y = y0; 	t = t0; 	printf("t y(t) w(t) error\n"); 	printf("===========================================================================\n"); 	printf("%.21f            %10.61f               %10.61f                   %10.61f\n", t, y, w(t), fabs(y - w(t))); 	for (i = 1; i <= n; i++) 	{  		y = y + h*F(y, t); 		t = t + h; 		if (i % 1000 == 0) 			printf("%.21f            %10.61f               %10.61f                   %10.61f\n", t, y, w(t), fabs(y - w(t))); 	} 	return; }

区分半角() 和全角（）


Question: 求解释算法

*(n_2+i)输出字符啊！n_2是字符串的首地址，倒序输出字符串每个地址为的字符！

自定义函数部分我算是明白了 else语句完全没用，p++也没用，只要while(m>0) {r=m%2; *p=r+48; m=m/2;} *p='\0'; 这几句就可以计算2进制结果， 回到主函数，for语句作用是把二进制得出的字符串倒序输出这个没问题，但是*(n_2+i)是什么意思？

如您所说，书确实有印错的地方，问题是运行结果是对的

不要迷信书、考题、老师、回帖； 要迷信CPU、编译器、调试器、运行结果。 并请结合“盲人摸太阳”和“驾船出海时一定只带一个指南针。”加以理解。 任何理论、权威、传说、真理、标准、解释、想象、知识……都比不上摆在眼前的事实！

书印错了。

r=m%2只能是0或1吧？为什么if语句条件是r<10？ *p=r+48是把数字r转换成ASCII码的数字赋值给p，p等于0或1，但是r>=10条件下，r+55是英文字母A、B？


Question: 栈遍历二叉树

仅供参考：#include <iostream> #include <stack> #include <queue> #include <locale.h> using namespace std; typedef struct BiTNode {//二叉树结点     char data;                      //数据     struct BiTNode *lchild,*rchild; //左右孩子指针 } BiTNode,*BiTree; int CreateBiTree(BiTree &T) {//按先序序列创建二叉树     char data;     scanf("%c",&data);//按先序次序输入二叉树中结点的值（一个字符），‘#’表示空树     if (data == '#') {         T = NULL;     } else {         T = (BiTree)malloc(sizeof(BiTNode));         T->data = data;         //生成根结点         CreateBiTree(T->lchild);//构造左子树         CreateBiTree(T->rchild);//构造右子树     }     return 0; } void Visit(BiTree T) {//输出     if (T->data != '#') {         printf("%c ",T->data);     } } void PreOrder(BiTree T) {//先序遍历     if (T != NULL) {         Visit(T);               //访问根节点         PreOrder(T->lchild);    //访问左子结点         PreOrder(T->rchild);    //访问右子结点     } } void InOrder(BiTree T) {//中序遍历     if (T != NULL) {         InOrder(T->lchild);     //访问左子结点         Visit(T);               //访问根节点         InOrder(T->rchild);     //访问右子结点     } } void PostOrder(BiTree T) {//后序遍历     if (T != NULL) {         PostOrder(T->lchild);   //访问左子结点         PostOrder(T->rchild);   //访问右子结点         Visit(T);               //访问根节点     } } void PreOrder2(BiTree T) {//先序遍历(非递归) //访问T->data后，将T入栈，遍历左子树；遍历完左子树返回时，栈顶元素应为T，出栈，再先序遍历T的右子树。     stack<BiTree> stack;     BiTree p = T;//p是遍历指针     while (p || !stack.empty()) {   //栈不空或者p不空时循环         if (p != NULL) {             stack.push(p);          //存入栈中             printf("%c ",p->data);  //访问根节点             p = p->lchild;          //遍历左子树         } else {             p = stack.top();        //退栈             stack.pop();             p = p->rchild;          //访问右子树         }     } } void InOrder2(BiTree T) {//中序遍历(非递归) //T是要遍历树的根指针，中序遍历要求在遍历完左子树后，访问根，再遍历右子树。 //先将T入栈，遍历左子树；遍历完左子树返回时，栈顶元素应为T，出栈，访问T->data，再中序遍历T的右子树。     stack<BiTree> stack;     BiTree p = T;//p是遍历指针     while (p || !stack.empty()) {   //栈不空或者p不空时循环         if (p != NULL) {             stack.push(p);          //存入栈中             p = p->lchild;          //遍历左子树         } else {             p = stack.top();        //退栈，访问根节点             printf("%c ",p->data);             stack.pop();             p = p->rchild;          //访问右子树         }     } }  typedef struct BiTNodePost{     BiTree biTree;     char tag; } BiTNodePost,*BiTreePost; void PostOrder2(BiTree T) {//后序遍历(非递归)     stack<BiTreePost> stack;     BiTree p = T;//p是遍历指针     BiTreePost BT;     while (p != NULL || !stack.empty()) {//栈不空或者p不空时循环         while (p != NULL) {//遍历左子树             BT = (BiTreePost)malloc(sizeof(BiTNodePost));             BT->biTree = p;             BT->tag = 'L';//访问过左子树             stack.push(BT);             p = p->lchild;         }         while (!stack.empty() && (stack.top())->tag == 'R') {//左右子树访问完毕访问根节点             BT = stack.top();             stack.pop();//退栈             printf("%c ",BT->biTree->data);         }         if (!stack.empty()) {//遍历右子树             BT = stack.top();             BT->tag = 'R';//访问过右子树             p = BT->biTree;             p = p->rchild;         }     } }  void LevelOrder(BiTree T) {//层次遍历     if (T == NULL) return;     BiTree p = T;     queue<BiTree> queue;//队列     queue.push(p);//根节点入队     while (!queue.empty()) {    //队列不空循环         p = queue.front();      //对头元素出队         printf("%c ",p->data);  //访问p指向的结点         queue.pop();            //退出队列         if (p->lchild != NULL) {//左子树不空，将左子树入队             queue.push(p->lchild);         }         if (p->rchild != NULL) {//右子树不空，将右子树入队             queue.push(p->rchild);         }     } } int main() {     BiTree T;      setlocale(LC_ALL,"chs");     CreateBiTree(T);      printf("先序遍历        ：");PreOrder  (T);printf("\n");     printf("先序遍历(非递归)：");PreOrder2 (T);printf("\n");                                                printf("\n");     printf("中序遍历        ：");InOrder   (T);printf("\n");     printf("中序遍历(非递归)：");InOrder2  (T);printf("\n");                                                printf("\n");     printf("后序遍历        ：");PostOrder (T);printf("\n");     printf("后序遍历(非递归)：");PostOrder2(T);printf("\n");                                                printf("\n");     printf("层次遍历        ：");LevelOrder(T);printf("\n");      return 0; } //ABC##DE#G##F### //先序遍历        ：A B C D E G F //先序遍历(非递归)：A B C D E G F // //中序遍历        ：C B E G D F A //中序遍历(非递归)：C B E G D F A // //后序遍历        ：C G E F D B A //后序遍历(非递归)：C G E F D B A // //层次遍历        ：A B C D E F G //  ///       A ///      / ///     B ///    / \ ///   C   D ///      / \ ///     E   F ///      \ ///       G

哦。但感觉还有别的问题啊，我把这两点试了但还是不对。。。

InitStack没有前置声明，所以我刚才在我的VS上跑了下报错了

那是要把AS->top的数据类型和p统一吗？  还有InitStack没有实现是什么意思。。

1.第112行p = AS->top; p是AnimalBiTree类型，AS->top是char *  2.第89行调用InitStack(AS);没看到你的InitStack实现啊？


Question: 回溯法做八皇后  哪里不对呢？？

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

#include <stdio.h>  int left[15]={0},right[15]={0},col[8]={0}; int q[8],top=-1; int cnt=0;  void print()  //按顺序输出  { 	int i,j; 	printf("这是第%d个解:\n",++cnt); 	for(i=0;i<8;i++) 	{ 		for(j=0;j<8;j++) 		{ 			if(q[i]==j) 				printf("Q "); 			else printf("X "); 		} 		printf("\n"); 	} }  void EightQueue () { 	int i=0,j=0; 	top=-1; 	while(i<8)  //从第一层开始  	{ 		while(j<8)  //从第一列开始  		{ 			if(col[j]==0&&left[i+j]==0&&right[i+7-j]==0)  //如果满足条件，则跳出循环  				break; 			j++; 		} 		if(j<8)  //如果跳出循环后j是在0~7，则放皇后  		{ 			q[++top]=j; 			left[i+j]=1; 			right[i+7-j]=1; 			col[j]=1; 			if(i<7)  //如果放的层数在0~7，则说明还没放完  			{ 				i++; 				j=0; 			} 			else  //8层全部放满了，输出棋盘  			{ 				print(); 				printf("\n"); 				if(top!=-1)  //如果这个时候栈非空，则回到栈顶皇后，并将其抹去  				{ 					i=top; 					j=q[top--]; 					left[i+j]=col[j]=right[i+7-j]=0; 					j++; 				} 			} 		} 		else  //如果在0~7中没找到合适的位置放皇后，则回到栈顶皇后，并将其抹去（栈不为空）  		{ 			if(top!=-1) 			{ 				i=top; 				j=q[top--]; 				left[i+j]=col[j]=right[i+7-j]=0; 				j++; 			} 		} 		if(i==-1) //当第一层的位置都已经使用过，则会使i跳到下面一层，即皇后的放法已经全部找出   			break; 	} }   int main (void) { 	EightQueue(); 	return 0; }


Question: 求解答if嵌套问题

1.if与else一般是就近原则。栈的原理。  2.为了避免这种情况，一般if else后面都加上{};

我觉得如果没有那个花括号的话，那个else会跟最近的那个if匹配，也就是你要括起来的那个if不会跟外面那个if匹配。

else总是与最近没匹配的if配对

else是就近匹配  没脸括号，else匹配的是 之前大括号里面的那个if

你这是什么IDE？

引用 7 楼 yaoqibbs 的回复:你这是什么IDE？像是vim

引用 5楼我是你的主体 的回复:引用 1楼几罗星人 的回复:没有的话,花括号下面的else就和if((len=cc[i] * MAXHIST……这个if配对了还有为什么cc【i】=1但是*打了五个出来这个知道了写完自己忘了

引用 1楼几罗星人 的回复:没有的话,花括号下面的else就和if((len=cc[i] * MAXHIST……这个if配对了如果和最近的if配对的话，那这两个if和else是如何执行的，是否第一个if没有语句执行了


Question: 求链表的中间节点有问题，大神看看

仅供参考：//不带表头结点的单向链表 #include <stdio.h> #include <stdlib.h> #include <malloc.h> #include <time.h> #include <locale.h> struct NODE {     int          data;     struct NODE *next; } *head,*p,*q,*s,*p1,*p2,*q1,**ta; int i,k,n,t,m,v,N=10; int main() {     setlocale(LC_ALL,"chs");     srand(time(NULL));      head=NULL;      printf("创建%d个节点的单链表:",N);//创建N个节点的单链表     p=head;     for (i=0;i<N;i++) {         q=(struct NODE *)malloc(sizeof(struct NODE));         if (NULL==q) exit(1);         q->data=rand()%100;//填写0..99的随机值         q->next=NULL;         if (NULL==p) {             head=q;             p=head;         } else {             p->next=q;             p=q;         }     }      //输出整个单链表     s=head;     while (1) {         if (NULL==s) {             printf("\n");             break;         }         printf("%02d->",s->data);         s=s->next;     }      k=3;     v=5;     printf("将值为%d的结点插入到单链表的第%d个结点前:",v,k);//将值为v的结点插入到单链表的第k个结点前     n=0;     p=head;     while (1) {         if (NULL==p) {             break;         }         n++;         if (k==1) {             q=(struct NODE *)malloc(sizeof(struct NODE));             if (NULL==q) exit(1);             q->data=v;             q->next=head;             head=q;             break;         } else {             if (k-1==n) {                 q=(struct NODE *)malloc(sizeof(struct NODE));                 if (NULL==q) exit(1);                 q->data=v;                 q->next=p->next;                 p->next=q;                 break;             }         }         p=p->next;     }      //输出整个单链表     s=head;     while (1) {         if (NULL==s) {             printf("\n");             break;         }         printf("%02d->",s->data);         s=s->next;     }      k=5;     printf("删除第%d个节点:",k);//删除第k个节点     n=0;     p=head;     while (1) {         if (NULL==p) {             break;         }         n++;         if (k==1) {             q=head;             head=head->next;             free(q);             break;         } else {             if (k-1==n) {                 q=p->next;                 if (q) {                     p->next=q->next;                     free(q);                 }                 break;             }         }         p=p->next;     }      //输出整个单链表     s=head;     while (1) {         if (NULL==s) {             printf("\n");             break;         }         printf("%02d->",s->data);         s=s->next;     }      printf("从小到大排序:");//从小到大排序     for (p=head,p1=NULL;p!=NULL;p1=p,p=p->next) {         for (q=p->next,q1=p;q!=NULL;q1=q,q=q->next) {             if (p->data > q->data) {                  //交换data //              printf("swap %02d %02d\n",p->data,q->data); //              t=p->data;p->data=q->data;q->data=t;                  //或者                  //交换next //              printf("swap %02d %02d\n",p->data,q->data);                 if (p==head) {//p是头                     if (p->next==q) {//pq挨着                         head=q;                         p->next=q->next;                         q->next=p;                         q=p;                         p=head;                     } else {//pq不挨着                         head=q;                         p2=p->next;                         p->next=q->next;                         q->next=p2;                         q1->next=p;                         q=p;                         p=head;                     }                 } else {//p不是头                     if (p->next==q) {//pq挨着                         p1->next=q;                         p->next=q->next;                         q->next=p;                         q=p;                         p=p1->next;                     } else {//pq不挨着                         p1->next=q;                         p2=p->next;                         p->next=q->next;                         q->next=p2;                         q1->next=p;                         q=p;                         p=p1->next;                     }                 }                  //输出整个单链表 //              s=head; //              while (1) { //                  if (NULL==s) { //                      printf("\n"); //                      break; //                  } //                  printf("%02d->",s->data); //                  s=s->next; //              } //              getchar();             }         }     }      //输出整个单链表并计算链表长度n     n=0;     s=head;     while (1) {         if (NULL==s) {             printf("\n");             break;         }         printf("%02d->",s->data);         n++;         s=s->next;     }      printf("将整个链表逆序:");//将整个链表逆序     if (n>=2) {         p=head;         q=p->next;         p->next=NULL;         while (1) {             q1=q->next;             q->next=p;             p=q;             q=q1;             if (NULL==q) break;         }         head=p;     }      //输出整个单链表     s=head;     while (1) {         if (NULL==s) {             printf("\n");             break;         }         printf("%02d->",s->data);         s=s->next;     }      m=4;     n=6;     printf("将单链表中前%d个结点和后%d个结点进行互换:",m,n);//将单链表中前m个结点和后n个结点进行互换,m+n为链表总长     k=0;     p=head;     while (1) {         if (NULL==p) {             break;         }         k++;         if (m==k) {             q=p;         }         s=p;         p=p->next;     }     q1=head;     head=q->next;     s->next=q1;     q->next=NULL;      //输出整个单链表     s=head;     while (1) {         if (NULL==s) {             printf("\n");             break;         }         printf("%02d->",s->data);         s=s->next;     }      //释放所有节点     p=head;     while (1) {         if (NULL==p) {             break;         }         q=p->next;         free(p);         p=q;     }      return 0; } //创建10个节点的单链表:08->74->07->23->03->99->31->56->88->16-> //将值为5的结点插入到单链表的第3个结点前:08->74->05->07->23->03->99->31->56->88->16-> //删除第5个节点:08->74->05->07->03->99->31->56->88->16-> //从小到大排序:03->05->07->08->16->31->56->74->88->99-> //将整个链表逆序:99->88->74->56->31->16->08->07->05->03-> //将单链表中前4个结点和后6个结点进行互换:31->16->08->07->05->03->99->88->74->56-> //

你们的代码是怎么弄上去的，为什么我的就整个对齐了

我刚看完链表

对你的代码做了修改，对比一下吧； 一些不合理的地方我做了修改，一些代码风格是按照我平时写的风格改的，不一定适合你； 一些逻辑我也做了更改，让逻辑更简单一些； 希望对你有用； 最后运行基本上没问题。

以下是main.c文件： #include <stdio.h> #include "list.h"  int main (void) {     int num;      printf ("input the numbers: ");      scanf ("%d", &num);      List *pList = NULL;      pList = CreateList (num);      if (!pList)         printf ("create failed!!!\r\n");     printf ("create ok\r\n");      ShowList (pList);      int iRet = 0;      iRet = ListLength (pList);      printf ("Listlength = %d\r\n", iRet);      int addnode;      printf ("input add element numbers: ");      scanf ("%d", &addnode);      pList = AddNode (pList, addnode);      ShowList (pList);      int pos;      printf ("input insert position: ");      scanf ("%d", &pos);      pList = InsertListItem (pList, pos);      if (!pList)         return -1;     printf ("insert ok\r\n");      ShowList (pList);      pList = ReverseList1 (pList);      if (!pList)         return -1;     printf ("reverse ok\r\n");      ShowList (pList);      int var = is_LoopList (pList);      printf ("var = %d\r\n", var);      if (var == 1)         printf ("The list is loop");     printf ("no loop\r\n");      List *point = ListMiddle (pList);     if (!point)         return -1;     printf ("find middlepoint\r\n");      ShowList (point);     ListSort (pList);      printf ("sort after");     ShowList (pList);      //delete node     int offset = 0;     data_t data;      printf ("input you want delete position: ");     scanf ("%d", &offset);      pList = DeleteItem (pList, &data, offset);      printf ("delete ok\r\n");      printf ("data = %d\r\n", data);      ShowList (pList);      int modnum;      printf ("input want modify data: ");      scanf ("%d", &modnum);      pList = UpdateList (pList, modnum);      if (NULL == pList)     {         printf ("update error\r\n");     }      ShowList (pList);      int searchnum;      printf ("input want search data: ");      scanf ("%d", &searchnum);      pList = SearchList (pList, searchnum);      DestoryList (pList);     pList = NULL;     return 0; }  以下是Makefile文件： SRC = $(wildcard *.c) OBJ = $(patsubst %.c, %.o, $(SRC))  CC = gcc  TARGET = app  CFLAGS := -Wall -g LDFLAGS := -pthread  all: $(TARGET)  %.o:%.c 	$(CC) -o $@ -c $< $(CFLAGS)  $(TARGET):$(OBJ) 	$(CC) -o $@ $^ $(LDFLAGS)  .PHONY: clean all  clean: 	$(RM) $(OBJ) 	$(RM) $(TARGET) 	$(RM) *~

以下是list.c文件： #include <stdio.h> #include <stdlib.h> #include <string.h> #include "list.h"  struct List {     data_t data;      struct List *pNext; };      List * CreateList (int n) {     int iCount = 0;      List *pNew, *pCur;     List *pList = NULL;     pCur = pList;      if (n < 1)         return pList;      pNew = (List *) malloc (sizeof (List));     if (!pNew) { /* malloc error then return */         printf ("new create failed!\r\n");         return NULL;     }     memset (pNew, 0, sizeof (List));      data_t data;      printf ("please input data: \r\n");      scanf ("%d", &data);      pNew->data = data;      pNew->pNext = NULL;      while (1)     {         if (!pList)             pList = pNew;         else             pCur->pNext = pNew;         pCur = pNew;         iCount++;          if (iCount >= n)             break;         pNew = (List *) malloc (sizeof (List));         scanf ("%d", &(pNew->data));     }     pCur->pNext = NULL;      return pList; }  int ListLength (List * pList) {     int length = 0;      if (!pList)         return 0;      List *pTmp = pList;      while (pTmp) {         length++;         pTmp = pTmp->pNext;     }      return length; }  List *AddNode (List * pList, int numbers) {     List *pNew, *pCur;     data_t data;      pCur = pList;      if (!pList || numbers <= 0) {         printf ("current list is empty,add fail!\r\n");         return pList;     } else {         while (pCur->pNext)             pCur = pCur->pNext;          pNew = (List *) malloc (sizeof (List));          if (!pNew) {             printf ("new create node failed!\r\n");             return pList;         }         memset (pNew, 0, sizeof (List));         printf ("please input data: ");         scanf ("%d", &data);          pNew->data = data;         pNew->pNext = NULL;          int ncount = 0;          while (1) {             pCur->pNext = pNew;             pCur = pNew;             ncount++;              if (ncount >= numbers) {                 break;             }             //再次创建节点，完成number个节点             pNew = (List *) malloc (sizeof (List));              printf ("again input data: ");             scanf ("%d", &data);             pNew->data = data;         }         pCur->pNext = NULL;     }     return pList; }  List *InsertListItem (List * pList, int num) {     data_t data;     int cnt;     List *pCur = NULL;      if (!pList || num < 0)         return pList;       pCur = pList;      List *insertnode = (List *) malloc (sizeof (List));      if (!insertnode)     {         printf ("malloc failed!\r\n");         return pList;     }      printf ("input you what want to insert: ");      scanf ("%d", &data);      insertnode->data = data;      insertnode->pNext = NULL;      if (!pCur) { /* the link is empty. */         pList = insertnode;         return pList;     }     if (num == 1) {         insertnode->pNext = pList;         pList = insertnode;         return pList;     }     cnt = 1;     pCur = pList;     while (pCur->pNext) {         cnt++;         if (cnt == num)                 break;         pCur = pCur->pNext;     }     insertnode->pNext = pCur->pNext;     pCur->pNext = insertnode;     /*     if (1 == num) {         pCur = pCur->pNext;          pList->pNext = insertnode;          insertnode->pNext = pCur;     } else if (num > 1 && num <= len)     {         int ncount = 0;         List *temp = NULL;          while (ncount != num - 1)         {             ncount++;              temp = pCur;              pCur = pCur->pNext;         }         temp->pNext = insertnode;          insertnode->pNext = pCur;     }     else if (len == num)     {         AddNode (pList, 1);     }     */     return pList; }   /* 链表的反转 */ List *ReverseList (List * pList) {     List *Current = pList;     List *Next = Current->pNext;     List *Prev = NULL;      if (!pList)         return pList;      while (Next) {         Prev = Next->pNext;          Next->pNext = Current;          Current = Next;          Next = Prev;     }     pList->pNext = NULL;      pList = Current;      return pList; }  /*链表的反转第二种方法*/     List * ReverseList1 (List * pList) {     if (NULL == pList)     {         return pList;     }     List *Current = pList;     List *pTemp = NULL;     while (Current->pNext)     {         pTemp = Current->pNext;          Current->pNext = pTemp->pNext;          //pTemp->pNext = pList->pNext;1//在头结点没有数据的情况下使用1和2          //pList->pNext = pTemp;2         pTemp->pNext = pList;          pList = pTemp;     }     Current->pNext = pList;      pList = Current->pNext;      Current->pNext = NULL;      return pList; }  /*判断是否有环*/ int is_LoopList (List * pList) {     List *p1, *p2;     p1 = p2 = pList;      if (!pList || !(pList->pNext))     {         return 0;     }      while (p2->pNext != NULL && p2->pNext->pNext != NULL)     {         p1 = p1->pNext;         p2 = p2->pNext->pNext;         if (p1 == p2)         {             return 1;         }     }      return 0; }  /*求链表的中点*/     List * ListMiddle (List * pList) {     if (!pList || !(pList->pNext))         return NULL;      List *pSlow = pList;     List *pFast = pList;      while (1)     {         if (pFast->pNext && pFast->pNext->pNext)         {             pFast = pFast->pNext->pNext;              pSlow = pSlow->pNext;         }         else         {             break;         }     }     //pList = pSlow;     return pSlow; }  /*链表排序*/ void ListSort (List * pList) {     int temp;      if (!pList || !(pList->pNext))     {         return;     }      List *pTmp = pList;      List *Tail = NULL;      while (pTmp != Tail)     {         while (pTmp->pNext != Tail)         {             if (pTmp->data < pTmp->pNext->data)             {                 temp = pTmp->data;                  pTmp->data = pTmp->pNext->data;                  pTmp->pNext->data = temp;             }             pTmp = pTmp->pNext;         }         Tail = pTmp;          pTmp = pList;     }     return; }  /* num is offset */ List *DeleteItem (List * pList, data_t * pData, int num) {     int len = ListLength (pList);      if (!pList || num < 1 || num > len)         return pList;      List *pDel = pList;     if (num == 1) { /* Del the head of link */         *pData = pList->data;         pList = pList->pNext;         free(pDel);         return pList;     }      int ncount = 0;     List *pCur = pList;     pDel = pCur->pNext;     while (pCur->pNext) {         ncount++;         if (ncount == num) {             pCur->pNext = pDel->pNext;             *pData = pDel->data;             free(pDel);             break;         }         pDel = pDel->pNext;     }      return pList;     /*     if (-1 == num)     {         List *pDel = pList;          if (NULL != pDel)         {             *pData = pList->data;              pList->pNext = pDel->pNext;              free (pDel);              pDel = NULL;         }     }      while (ncount != num - 1)     {         ncount++;          temp = pDel;          pDel = pDel->pNext;     }     *pData = pDel->data;      temp->pNext = pDel->pNext;      free (pDel);      pDel = NULL;     return pList;     */ }  List *UpdateList (List * pList, int data) {     if (NULL == pList)     {         return pList;     }     List *pTemp = pList;      int ncount = 0;     int value;      while (pTemp) {         ncount++;          if (pTemp->data == data) {             printf ("data in the list %d\r\n", ncount);             printf ("input new data:");             scanf ("%d", &value);             pTemp->data = value;             return pList;         }         pTemp = pTemp->pNext;      }     printf ("update failed!!!!\r\n");      return pList; }  List *SearchList (List * pList, int data) {     if (!pList) {         return NULL;     }     List *pTemp = pList;     int ncount = 0;      while (pTemp)     {         ncount++;         if (pTemp->data == data) {             printf ("data in the list %d\r\n", ncount);             return pTemp;         }         pTemp = pTemp->pNext;     }     printf("Not existed!\n");     return NULL; }  void DestoryList (List * pList) {     if (!pList)         return;      List *pNode = pList->pNext;     List *pTmp = NULL;      while (pNode) {         pTmp = pNode->pNext;         free (pNode);         pNode = pTmp;     }     free (pList);     pList = NULL; }  void ShowList (List * pList) {     printf ("show list: ");      if (!pList)         return;      List *pTmp = pList;     while (pTmp) {         printf ("%d  ",  pTmp->data);         pTmp = pTmp->pNext;     }     printf ("\r\n"); } 以下是list.h文件： #ifndef LIST_H_ #define LIST_H_  #define LIST_SIZE 10  enum LIST_TYPE { LIST_ERROR = -1,  LIST_OK };  typedef struct List List; typedef int data_t;  List *CreateList(int n);  int ListLength(List *pList);  List *AddNode(List *pList, int numbers);  List *InsertListItem(List *pList, int num);  List *ReverseList(List *pList);  List *ReverseList1(List *pList);  int is_LoopList(List *pList);  List *ListMiddle(List *pList);  void ListSort(List *pList);  List *DeleteItem(List *pList, data_t *pData, int num);  List *UpdateList(List *pList,int data);  List *SearchList(List *pList,int data);  void DestoryList(List *pList);  void ShowList(List *pList);  #endif

你可以描述下具体问题，还有格式弄得美观点，你这样子实在没法看


Question: accept函数返回0  write（0，buf，n）尽然可以输出。。。

0 1 2 分别对应 标准输入 标准输出 标准出错，（在没有重定向、管道的情况下 对应了键盘 显示器 显示器）。

有什么问题么？accept返回非负数就算是成功了，至于是否是0，就看当前进程可用的最小的文件描述符是多少。

网络编程？Linux下？

引用 6 楼 Demok_Long 的回复:[quote=引用 3 楼 ipqtjmqj 的回复:] write（0，buf，n）的功能是向文件描述符0的文件或设备（一般是标准输入，标准输入一般重定向到终端)写入n个字节，首地址为buf的内容。 至于accept返回0,你是不是把标准输入关了，这样系统是从值最小的文件描述符开始的，0没有使用，所以就返回了 参考http://stackoverflow.com/questions/36615243/accept-returning-0-zero-stdin-fd-in-c-socket-prog  一般是标准输入，标准输入一般重定向到终端 ，有这句话就是说write（0，buf，n）是可以写出来喽，我没有关闭0描述符，但是accept却自己返回0[/quote] 那就这样： int fd = open("/dev/null", O_RDONLY); dup2(fd, STDIN_FILENO); close(fd); 文件描述符分配给"/dev/null"再使用accept

引用 3 楼 ipqtjmqj 的回复:write（0，buf，n）的功能是向文件描述符0的文件或设备（一般是标准输入，标准输入一般重定向到终端)写入n个字节，首地址为buf的内容。 至于accept返回0,你是不是把标准输入关了，这样系统是从值最小的文件描述符开始的，0没有使用，所以就返回了 参考http://stackoverflow.com/questions/36615243/accept-returning-0-zero-stdin-fd-in-c-socket-prog  一般是标准输入，标准输入一般重定向到终端 ，有这句话就是说write（0，buf，n）是可以写出来喽，我没有关闭0描述符，但是accept却自己返回0

引用 1 楼 sum_TW 的回复:网络编程？Linux下？ @sum_TW 是的


Question: 图像数据编码后形成了码流，如何保存起来，以便比较

所有的数据都是二进制 你所说的编码成01是什么意思？  你读取时候是用什么形式存储的？你编码过程又是怎么存储的？

仅供参考：#pragma comment(lib,"user32") #pragma comment(lib,"gdi32") #include <stdlib.h> #include <stdio.h> #include <io.h> #include <conio.h> #include <windows.h> #include <atlimage.h> #include <objidl.h> void DrawPic(HDC hdc,char *buf,int len) {     HGLOBAL hMem=GlobalAlloc(GMEM_FIXED,len);     BYTE* pMem=(BYTE*)GlobalLock(hMem);     memcpy(pMem,buf,len);     IStream* pStream;     HRESULT hr=CreateStreamOnHGlobal(pMem,FALSE,&pStream);      CImage img;     img.Load(pStream);     img.Draw(hdc,CPoint(0,0));      img.Destroy();     pStream->Release();     GlobalUnlock(hMem);     GlobalFree(hMem); } //HWND WINAPI GetConsoleWindow(); void HideTheCursor() {     CONSOLE_CURSOR_INFO cciCursor;     HANDLE hStdOut = GetStdHandle(STD_OUTPUT_HANDLE);     if (GetConsoleCursorInfo(hStdOut, &cciCursor)) {         cciCursor.bVisible = FALSE;         SetConsoleCursorInfo(hStdOut, &cciCursor);     } } void ShowTheCursor() {     CONSOLE_CURSOR_INFO cciCursor;     HANDLE hStdOut = GetStdHandle(STD_OUTPUT_HANDLE);     if (GetConsoleCursorInfo(hStdOut, &cciCursor)) {         cciCursor.bVisible = TRUE;         SetConsoleCursorInfo(hStdOut, &cciCursor);     } } int main() {     HWND  hwnd;     HDC   hdc;     HFONT hfont;     HBITMAP hbm;     HDC hdcBits;     BITMAP bm;      system("color F0");     system("cls");     HideTheCursor();     hwnd  = GetConsoleWindow();     hdc   = GetDC(hwnd);     hfont = CreateFont(48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "华文楷体");     SelectObject(hdc,hfont);     TextOut(hdc,10,10,"这是泡泡",8);     DeleteObject(hfont);     hbm=(HBITMAP)LoadImage(0,"C:\\Windows\\Soap Bubbles.bmp",IMAGE_BITMAP,0,0,LR_DEFAULTSIZE|LR_LOADFROMFILE);     if (hbm) {         hdcBits = CreateCompatibleDC(hdc);         GetObject (hbm, sizeof(BITMAP), &bm);         SelectObject(hdcBits,hbm);         BitBlt(hdc,200,10,bm.bmWidth, bm.bmHeight,hdcBits,0,0,SRCCOPY);         DeleteDC(hdcBits);         DeleteObject(hbm);     }     getch();     FILE *f;     f=fopen("c:\\new\\tmp.jpg","rb");     if (f) {         int fl=filelength(fileno(f));         char *buf=(char *)malloc(fl);         if (buf) {             fread(buf,fl,1,f);         }         fclose(f);         if (buf) {             DrawPic(hdc,buf,fl);             free(buf);         }     }     ReleaseDC(hwnd,hdc);     getch();     system("color 07");     system("cls");     ShowTheCursor();     return 0; }


Question: c语言释放动态申请的二维数组问题；

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

申请空间时候是N-count 释放的循环写的是N-count+1

现在知道问题解决了，是有两个数组访问越界了，但是这两个数组和c1和loc1没关系啊？为什么为在这里报错求大神解释。

仅供参考：#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 //

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

调试的时候是在free(c1)报错的

求解答 卡了一天了

引用 4 楼 shihengzhen101 的回复:申请空间时候是N-count 释放的循环写的是N-count+1 中间有个count++没贴出来，不是这个问题； 怎么没人回复啦，，，

还能顶吗？，，，，

再顶一个！一会来看，麻烦大家了。

老规矩，自己先顶一个