Question: 线性表的问题  大神们帮我改改吧  谢谢了

哇  谢谢了  终于找到Insert循环错了 其他也改过来了

#include<stdio.h> #include<malloc.h> #define MAXSIZE 50 #define N 10 typedef int elemtype; typedef struct {     elemtype data[MAXSIZE];     int last; }Sequenlist;  Sequenlist* InitList(Sequenlist*L) {     L=(Sequenlist*)malloc(sizeof(Sequenlist));     L->last=0;     return(L); }  int Judge(Sequenlist*L) {     if(L->last==0)     {         printf("List is empty.\n");     }     return 0; }  int Insert(Sequenlist*L) {     int x,i;     if(L->last==MAXSIZE-1)     {         printf("overflow.\n");         return 0;     }     else     {         printf("Input %d data:\n");         for(i=L->last;i<L->last+N;i++)         {             scanf("%d",&x);             L->data[i]=x;             L->last++;         }     }     for(i=0;i<L->last;i++)       printf("%d",L->data[i]);     return 0; }  int DelItem(Sequenlist*L,int i) {     int j;     if(L->last==0)     {         printf("List is empty.\n");         return 0;     }     else if((i<1)||(i>=L->last))     {         printf("Delete item fail.\n");         return 0;     }     else     {         for(j=i;j<=L->last-1;j++)             L->data[j-1]=L->data[j];         L->last--;         for(i=0;i<L->last;i++)           printf("%d",L->data[i]);         return 0;      } }  int InsItem(Sequenlist*L,int i,elemtype item) {     int j;     if(L->last==0)     {         printf("List is empty.\n");         return 0;     }     else if((i<1)||(i>L->last))     {         printf("Insert item fail.\n");         return 0;     }     else     {         for(j=L->last;j>=i;j--)             L->data[j]=L->data[j-1];         L->last++;         for(i=0;i<L->last;i++)            printf("%d",L->data[i]);         return 0;     } }  int LocItem1(Sequenlist*L,elemtype item) {     int i,j;     j=L->last;     if(j==0)     {         printf("List is empty.\n");         return 0;     }     for(i=0;i<j;i++)     {         if(L->data[i]==item)         {             return(i+1);         }     }     printf("The item is not in this sequenlist");     return 0; }  int LocItem2(Sequenlist*L,elemtype item) {     int i,j;     j=L->last;     if(j==0)     {         printf("List is empty.\n");         return 0;     }     for(i=0;i<j;i++)     {         if(L->data[i]==item)         {             return(i+1);         }     }     printf("The item is not in this sequenlist");     return 0; }  int LocItem3(Sequenlist*L,elemtype item) {     int i,j;     j=L->last;     if(j==0)     {         printf("List is empty.\n");         return 0;     }     for(i=0;i<j;i++)     {         if(L->data[i]==item)         {             printf("前驱为%d",L->data[i-1]);             printf("后继为%d",L->data[i+1]);         }     }     printf("The item is not in this sequenlist");     return 0; }  int main() {     int i,item;     Sequenlist*L;    Sequenlist* InitList(Sequenlist*L);     int Judge(Sequenlist*L);     printf("依次在顺序表尾部(第n+1位，n位线性表长度)插入数据元素\n");     int Insert(Sequenlist*L);     printf("删除第i个元素,请输入i:");     scanf("%d",&i);     printf("删除第%d个元素\n",i);     int DelItem(Sequenlist*L,int i);     printf("在线性表的第i位插入数据item,请输入i和item:");     scanf("%d%d",&i,&item);     int InsItem(Sequenlist*L,int i,elemtype item);     printf("在线性表中查找值为item的元素在第几位,请输入item:");     scanf("%d",&item);     int LocItem1(Sequenlist*L,elemtype item);     printf("在线性表中查找值为item的元素在第几位,请输入item:");     scanf("%d",&item);     int LocItem2(Sequenlist*L,elemtype item);     printf("查找线性表中，值为item的元素的前驱元素以及后继元素的值,请输入item:");     scanf("%d",&item);     int LocItem3(Sequenlist*L,elemtype item);     return 0;  }

因为循环完了  i的值就等于j了，意思就是i=L->last。。。、。。。。所以if条件成立，LZ还是认真点吧

为什么后面两个if语句都会在一起执行 int LocItem1(Sequenlist*L,elemtype item) {     int i,j;     j=L->last;     if(j==0)     {         printf("List is empty.\n");         return 0;     }     for(i=0;i<j;i++)     {         if(L->data[i]==item)         {             printf("%d在第%d位\n",item,i+1);          }     }     if(i>=j)         printf("The item is not in this sequenlist");     return 0; }

int LocItem1(Sequenlist*L,elemtype item) {     int i,j;     j=L->last;     if(j==0)     {         printf("List is empty.\n");         return 0;     }     for(i=0;i<j;i++)     {         if(L->data[i]==item)         {             printf("%d在第%d位\n",item,i+1);          }     }     if(i>=j)         printf("The item is not in this sequenlist");     return 0; }  为什么最后两个if语句都会执行啊  #include<stdio.h> #include<malloc.h> #define MAXSIZE 50 #define N 10 typedef int elemtype; typedef struct {     elemtype data[MAXSIZE];     int last; }Sequenlist;  Sequenlist*InitList(Sequenlist*L) {     L->last=0;     return(L); }  int Judge(Sequenlist*L) {     if(L->last==0)     {         printf("List is empty.\n");     }     return 0; }  int Insert(Sequenlist*L) {     int x,i;     if((*L).last==MAXSIZE-1||(*L).last+N>MAXSIZE)     {         printf("overflow.\n");         return 0;     }     else     {         printf("Input %d datas:",N);         for(i=(*L).last;i<(*L).last+N;i++)         {             scanf("%d",&x);             (*L).data[i]=x;         }         (*L).last=(*L).last+N;     }     for(i=0;i<(*L).last;i++)       printf("%d  ",(*L).data[i]);     return 0; }  int DelItem(Sequenlist*L,int i) {     int j;     if(L->last==0)     {         printf("List is empty.\n");         return 0;     }     else if((i<1)||(i>=L->last))     {         printf("Delete item fail.\n");         return 0;     }     else     {         for(j=i;j<L->last;j++)             L->data[j-1]=L->data[j];         L->last--;         for(i=0;i<L->last;i++)           printf("%d  ",L->data[i]);         return 0;      } }  int InsItem(Sequenlist*L,int i,elemtype item) {     int j;     if(L->last==0)     {         printf("List is empty.\n");         return 0;     }     else if((i<1)||(i>L->last))     {         printf("Insert item fail.\n");         return 0;     }     else     {         for(j=L->last;j>=i;j--)             L->data[j]=L->data[j-1];         L->data[i-1]=item;         L->last++;         for(i=0;i<L->last;i++)            printf("%d  ",L->data[i]);         return 0;     } }  int LocItem1(Sequenlist*L,elemtype item) {     int i,j;     j=L->last;     if(j==0)     {         printf("List is empty.\n");         return 0;     }     for(i=0;i<j;i++)     {         if(L->data[i]==item)         {             printf("%d在第%d位\n",item,i+1);          }     }     if(i>=j)         printf("The item is not in this sequenlist");     return 0; }  int LocItem2(Sequenlist*L,elemtype item) {     int i,j;     j=L->last;     if(j==0)     {         printf("List is empty.\n");         return 0;     }     for(i=0;i<j;i++)     {         if(L->data[i]==item)         {             printf("%d在第%d位\n",item,i+1);         }     }     if(i>=j)         printf("The item is not in this sequenlist");     return 0; }  int LocItem3(Sequenlist*L,elemtype item) {     int i,j;     j=L->last;     if(j==0)     {         printf("List is empty.\n");         return 0;     }     for(i=0;i<j;i++)     {         if(L->data[i]==item)         {             if(L->data[i-1]==L->data[0])                 {                     printf("第一个没有前驱\n");                     printf("%d后继为%d\n",L->data[i],L->data[i+1]);                 }             else if(L->data[i-1]==L->data[L->last-1])                 {                     printf("%d前驱为%d\n",L->data[i],L->data[i-1]);                     printf("最后一个没有后继\n");                 }             else                 {                     printf("%d前驱为%d\n",L->data[i],L->data[i-1]);                     printf("%d后继为%d\n",L->data[i],L->data[i+1]);                 }         }     }     return 0; }  int main() {     int i,item;     Sequenlist*L;     L=(Sequenlist*)malloc(sizeof(Sequenlist));     InitList(L);     Judge(L);     printf("依次在顺序表尾部(第n+1位，n位线性表长度)插入数据元素\n");     Insert(L);     printf("\n删除第i个元素,请输入i:");     scanf("%d",&i);     printf("删除第%d个元素\n",i);     DelItem(L,i);     printf("\n在线性表的第i位插入数据item,请输入i和item:");     scanf("%d%d",&i,&item);     InsItem(L,i,item);     printf("\n在线性表中查找值为item的元素在第几位,请输入item:");     scanf("%d",&item);     LocItem1(L,item);     printf("\n在线性表中查找值为item的元素在第几位,请输入item:");     scanf("%d",&item);     LocItem2(L,item);     printf("\n查找线性表中值为item的元素的前驱元素以及后继元素的值,请输入item:");     scanf("%d",&item);     LocItem3(L,item);     return 0; }

把循环里的L->last++放到循环外面=L->last+N，循环条件部分为<=

你插入函数里面的循环永远不会结束，你洗仔细看看

不是啊  last是记录最后一个数据的  N是插入的个数 应该是不一样的

你理解错了吧，题里面所谓的，N就是你在结构体内定义的last吧……

你理解错了吧，题里面所谓的，N就是你在结构体内定义的last吧……

分配内存的函数返回值为 Sequenlist *  不是 int     for(i=L->last;i<L->last+N;i++)          {              scanf("%d",&x);              L->data[i]=x;              L->last++;          } L->last+N如果大于Max怎么办？。。。。

建立一张顺序存储结构的线性表(顺序表)，表中数据元素为整型数，能够存储的最大元素数量为50。在该顺序表上依次完成以下操作： （1）判定线性表是否为空。 （2）依次在顺序表尾部(第n+1位，n位线性表长度)插入数据元素：15、207、36、79、21、97、652、109、66、81，然后输出整张线性表（依次输出所有元素）。 （3）删除第5个元素，然后输出整张线性表。 （4）在线性表的第3位插入数据92，然后输出整张线性表。 （5）在线性表中查找值为79的元素，如果存在输出它是第几位，不存在输出提示信息。 （6）线性表中查找值为31的元素，如果存在输出它是第几位，不存在输出提示信息。 （7）查找线性表中，值为652的元素的前驱元素以及后继元素的值。

你们的作业要求是什么啊？

我写的是线性表顺序表  不是链式的  我们的作业要求是写顺序表

链表的成员中除了数据域，应当还有指向下个结点的指针域！！！！   #include<stdio.h> #include<malloc.h> #include<stdlib.h>    typedef struct node { 	int data; 	struct node *pnode; }*PNODE,NODE;  PNODE CreateList( int ); int LengthList(PNODE );								 void ShowList( PNODE );									 PNODE InsertList(PNODE ,PNODE ,int);   int main(int argc ,char *argv[]) { 	int len ,posi; 	PNODE pHead = NULL; 	PNODE pEle = (PNODE )malloc(sizeof(NODE)); 	printf("请输出链表长度 len ="); 	scanf("%d",&len); 	pHead = CreateList(len); 	ShowList(pHead); 	if(pEle == NULL) 	{ 		printf("分配内存失败，程序结束"); 		exit(-1); 	} 	pEle->data = 100; 	printf("请输入插入位置 posi ="); 	scanf("%d",&posi); 	if(!InsertList(pHead ,pEle, posi)) 		free(pEle); 	ShowList(pHead); 	getchar(); 	return 0; }   /* 	函数功能：创建一个由用户指定的链表并返回链表的头结点 */ PNODE CreateList(int len) { 	PNODE pHead = (PNODE)malloc(sizeof(NODE));			//创建头结点 	PNODE pTemp = pHead;								//临时指针 	int val = 0;								 	if( len <= 0) 	{ 		printf("传入数值有误，链表创建失败\n"); 		exit(-1); 	} 	 	if(pHead == NULL) 	{ 		printf("程序分配内存失败，程序结束\n"); 		exit(-1); 	} 	 	pTemp ->pnode =	NULL; 	while(len--) 	{ 		pTemp ->pnode = (PNODE) malloc(sizeof(NODE)); 		if(pTemp ->pnode ==NULL) 			{ 				printf("程序分配内存失败，程序结束\n"); 				exit(-1); 			} 		printf("请输入数据 val = "); 		scanf("%d",&val); 		pTemp ->pnode ->data = val; 		pTemp ->pnode ->pnode = NULL; 		pTemp = pTemp ->pnode ; 	} 	return pHead; }   /* 	函数功能：显示链表数据域 */ void ShowList(PNODE pHead ) { 	PNODE pTemp = pHead; 	while(pTemp ->pnode !=NULL) 	{ 		printf("%-6d",pTemp ->pnode ->data); 		pTemp = pTemp ->pnode; 	} 	printf("\n"); 	return ; }  /*     函数功能：测量链表长度 */ int LengthList(PNODE pHead ) { 	int i = 0; 	PNODE pTemp = pHead ; 	while(pTemp ->pnode !=NULL) 	{ 		pTemp = pTemp ->pnode; 		i++; 	} 	return i; } /* 	函数功能：在链表的posi位置插入链表 				返回首地址 */ PNODE InsertList(PNODE pHead ,PNODE pEle ,int posi) { 	PNODE pTemp = pHead; 	int len = LengthList(pHead); 	if(posi < 0 || posi > len )		 		return false; 	 	if(posi ==0)			//首结点插入 	{ 		pEle ->pnode = pHead ->pnode; 		pHead ->pnode = pEle;  	} 	else 	{ 		while(posi --) 			pTemp = pTemp ->pnode; 		pEle ->pnode = pTemp ->pnode; 		pTemp ->pnode = pEle; 	} 	return pHead; }   这里没有写删除部分。不过删除很简单 通过传入的头结点地址来遍历链表 找到对应元素然后改变前一个结点的指针域并释放查找元素空间！

还是不行啊 为什么建立线性表并判定线性表是否为空 不能执行 还有插入Insert 函数也不行 能帮我看下吗

#include<stdio.h> #include<malloc.h> #define MAXSIZE 50 #define N 10 typedef int elemtype; typedef struct {     elemtype data[MAXSIZE];     int last; } Sequenlist;  Sequenlist* InitList(Sequenlist*L) {     L=(Sequenlist*)malloc(sizeof(Sequenlist));     L->last=0;     return(L); //L是一个指针，返回类型自然要是指针类型。 }  int Judge(Sequenlist*L) {     if(L->last==0)     {         printf("List is empty.\n");     }     return 0; }  int Insert(Sequenlist*L) {     int x,i;     if(L->last==MAXSIZE-1)     {         printf("overflow.\n");         return 0;     }     else     {         printf("Input %d data:\n");         for(i=L->last; i<L->last+N; i++)         {             scanf("%d",&x);             L->data[i]=x;             L->last++;         }     }     for(i=0; i<L->last; i++)         printf("%d",L->data[i]);     return 0; }  int DelItem(Sequenlist*L,int i) {     int j;     if(L->last==0)     {         printf("List is empty.\n");         return 0;     }     else if((i<1)||(i>=L->last))     {         printf("Delete item fail.\n");         return 0;     }     else     {         for(j=i; j<=L->last-1; j++)             L->data[j-1]=L->data[j];         L->last--;         for(i=0; i<L->last; i++)             printf("%d",L->data[i]);         return 0;      } }  int InsItem(Sequenlist*L,int i,elemtype item) {     int j;     if(L->last==0)     {         printf("List is empty.\n");         return 0;     }     else if((i<1)||(i>L->last))     {         printf("Insert item fail.\n");         return 0;     }     else     {         for(j=L->last; j>=i; j--)             L->data[j]=L->data[j-1];         L->last++;         for(i=0; i<L->last; i++)             printf("%d",L->data[i]);         return 0;     } }  int LocItem1(Sequenlist*L,elemtype item) {     int i,j;     j=L->last;     if(j==0)     {         printf("List is empty.\n");         return 0;     }     for(i=0; i<j; i++)     {         if(L->data[i]==item)         {             return(i+1);         }     }     printf("The item is not in this sequenlist");     return 0; }  int LocItem2(Sequenlist*L,elemtype item) {     int i,j;     j=L->last;     if(j==0)     {         printf("List is empty.\n");         return 0;     }     for(i=0; i<j; i++)     {         if(L->data[i]==item)         {             return(i+1);         }     }     printf("The item is not in this sequenlist");     return 0; }  int LocItem3(Sequenlist*L,elemtype item) {     int i,j;     j=L->last;     if(j==0)     {         printf("List is empty.\n");         return 0;     }     for(i=0; i<j; i++)     {         if(L->data[i]==item)         {             printf("前驱为%d",L->data[i-1]);             printf("后继为%d",L->data[i+1]);         }     }     printf("The item is not in this sequenlist");     return 0; }  int main() {     int i,item;     Sequenlist*L;     int InitList(Sequenlist*L);     int Judge(Sequenlist*L);     printf("依次在顺序表尾部(第n+1位，n位线性表长度)插入数据元素\n");     int Insert(Sequenlist*L);     printf("删除第i个元素,请输入i:");     scanf("%d",&i);     printf("删除第%d个元素\n",i);     int DelItem(Sequenlist*L,int i);     printf("在线性表的第i位插入数据item,请输入i和item:");     scanf("%d%d",&i,&item);     int InsItem(Sequenlist*L,int i,elemtype item);     printf("在线性表中查找值为item的元素在第几位,请输入item:");     scanf("%d",&item);     int LocItem1(Sequenlist*L,elemtype item);     printf("在线性表中查找值为item的元素在第几位,请输入item:");     scanf("%d",&item);     int LocItem2(Sequenlist*L,elemtype item);     printf("查找线性表中，值为item的元素的前驱元素以及后继元素的值,请输入item:");     scanf("%d",&item);     int LocItem3(Sequenlist*L,elemtype item);     return 0;  }  帮你改了改

int InitList(Sequenlist*L) {     L=(Sequenlist*)malloc(sizeof(Sequenlist));     L->last=0;     return(L); } 这段代码的返回至应该是 Sequenlist* 因为malloc返回指像所分配内存的指针


Question: 求大神解答，程序哪里有问题！

再纠正为： if ((a%4==0 && a%100!=0) || a%400==0) {  printf("这是闰年%d年的",a);  switch(b) {   case  1:printf("第%d天\n",c    );break;   case  2:printf("第%d天\n",c+ 31);break;   case  3:printf("第%d天\n",c+ 60);break;   case  4:printf("第%d天\n",c+ 91);break;   case  5:printf("第%d天\n",c+121);break;   case  6:printf("第%d天\n",c+152);break;   case  7:printf("第%d天\n",c+182);break;   case  8:printf("第%d天\n",c+213);break;   case  9:printf("第%d天\n",c+244);break;   case 10:printf("第%d天\n",c+274);break;   case 11:printf("第%d天\n",c+305);break;   case 12:printf("第%d天\n",c+335);break;  } } else {  printf("这是平年%d年的",a);  switch(b) {   case  1:printf("第%d天\n",c    );break;   case  2:printf("第%d天\n",c+ 31);break;   case  3:printf("第%d天\n",c+ 59);break;   case  4:printf("第%d天\n",c+ 90);break;   case  5:printf("第%d天\n",c+120);break;   case  6:printf("第%d天\n",c+151);break;   case  7:printf("第%d天\n",c+181);break;   case  8:printf("第%d天\n",c+212);break;   case  9:printf("第%d天\n",c+243);break;   case 10:printf("第%d天\n",c+273);break;   case 11:printf("第%d天\n",c+304);break;   case 12:printf("第%d天\n",c+334);break;  } }

上帖纠正为： if ((a%4==0 && a%100!=0) || a%400==0) {  printf("这是闰年%d年的",a); } else {  printf("这是平年%d年的",a); } switch(b) {  case  1:printf("第%d天\n",c    );break;  case  2:printf("第%d天\n",c+ 31);break;  case  3:printf("第%d天\n",c+ 60);break;  case  4:printf("第%d天\n",c+ 91);break;  case  5:printf("第%d天\n",c+121);break;  case  6:printf("第%d天\n",c+152);break;  case  7:printf("第%d天\n",c+182);break;  case  8:printf("第%d天\n",c+213);break;  case  9:printf("第%d天\n",c+244);break;  case 10:printf("第%d天\n",c+274);break;  case 11:printf("第%d天\n",c+305);break;  case 12:printf("第%d天\n",c+335);break; }

if ((a%4==0 && a%100!=0) || a%400==0) {  printf("这是闰年%d年的",a); } else {  printf("这是平年%d年的",a); } switch(b) {  case  1:printf("第%d天\n",a,c    );break;  case  2:printf("第%d天\n",a,c+ 31);break;  case  3:printf("第%d天\n",a,c+ 60);break;  case  4:printf("第%d天\n",a,c+ 91);break;  case  5:printf("第%d天\n",a,c+121);break;  case  6:printf("第%d天\n",a,c+152);break;  case  7:printf("第%d天\n",a,c+182);break;  case  8:printf("第%d天\n",a,c+213);break;  case  9:printf("第%d天\n",a,c+244);break;  case 10:printf("第%d天\n",a,c+274);break;  case 11:printf("第%d天\n",a,c+305);break;  case 12:printf("第%d天\n",a,c+335);break; }

引用 2 楼 changyuanchn 的回复:switch语句就不应该是这样用的。switch里面套用if，这个貌似没有这么用的吧 +1，没见过这么用的，这样有错误

int CalculateAbsoluteDays (int year, char month, char day) { 	/* 实现功能 */ 	int LeapYear; 	if((year>0)&&((month>=1)&&(month<=12))) 	{ 		if(((year%4==0)&&(year%100 !=0))||(year%400==0)) 			LeapYear = 1; 		else 			LeapYear = 0; 		if((day>=1)&&(day<=31)) 		{ 			if((month==2)&&(LeapYear==1)&&(day>29)) 				return 0; 			if((month==2)&&(LeapYear==0)&&(day>28)) 				return 0; 			if(((month==4)||(month==6)||(month==9)||(month==11))&&(day>30)) 				return 0; 			int MonArr[12] = {31,28,31,30,31,30,31,31,30,31,30,31}; 			int i; 			int ActualDay = 0; 			for(i=0;i<(month-1);i++) 			{ 				ActualDay = ActualDay + MonArr[i]; 			} 			ActualDay = ActualDay+(day-0); 			return ((LeapYear==1)?(ActualDay+1):(ActualDay)); 		} 		else 			return 0; 	} 	else 		return 0; }

f((a%4==0 && a%100!=0) || a%400==0)前面应该加case : else前面应该加case :


Question: C语言文件处理的问题

while(1){ 						fread(&c,sizeof(char),1,pFile); 						if(feof(pFile)){ 							break; 						} 						n++; 					} 					pMemory=(char *)malloc(n);		 					fseek(pFile,0,SEEK_SET); 					for(i=0;i<n;i++){ 						fread(&c,sizeof(char),1,pFile); 						*pMemory=c;						//数据存入动态缓冲区 						pMemory++; 					} 					pMemory-=n; 					fclose(pFile); 					//数据写操作，放在动态内存中 					if((pFile=fopen(szFileNameBuffer,"wb"))==NULL){ 						exit(0); 					} 					i=0; 					j=n; 					while(n--){ 						if(k==i){ 							i=0; 						} 						c=*pMemory; 						pMemory++; 						c+=szKey[i++]; 						fwrite(&c,sizeof(char),1,pFile); 					}

我就是想读文件的一个数据，在把它加上一个数，在写到相应的位置

我是fgetc（）后读出1，指针指向2，fseek()后又指向1，fputc（）后指向2，再次fgetc()，读的是2呀？不是么？

fseek会改变 文件的读写位置  注意是读和写 读了一个，然后退回去写一个，再读一个的时候其实读的就是退回去的那个，一直这样下去～ 假设文件内容为：12345 文件打开后，文件读指针指向1，fgetc后指向2，调用fseek之后，把读写位置又都指向1，又读1...

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

而且从lz的代码看来，兼有读写操作fgetc(),fputc()。

lz多提供信息。  至于feof，常有误用，下面的代码feof的使用范例： /* feof example: byte counter */ #include <stdio.h>  int main () {   FILE * pFile;   int n = 0;   pFile = fopen ("myfile.txt","rb");   if (pFile==NULL) perror ("Error opening file");   else   {     while (fgetc(pFile) != EOF) {       ++n;     }     if (feof(pFile)) {       puts ("End-of-File reached.");       printf ("Total number of bytes read: %d\n", n);     }     else puts ("End-of-File was not reached.");     fclose (pFile);   }   return 0; }  该示例代码来自《C++ Reference》。


Question: 合并线性表

弄好了！谢谢你！

有道理！我试试！

#include "stdio.h" #include "stdlib.h" #include "malloc.h"  #define Element int //to adjust Element's type #define turn int //to adjust which point to choice printup or printdown  //if change "int",The scanf's number in it must be change too;  typedef struct Single { 	Element D; 	Single *next;//to back }list; //single list type  //单链表例程 void init_single(list *&L); void creatlist_single(list *&L,Element n); void printlist_single(list *&L); void mergelist(list *&L,list *&Q,list *&head);  void init_single(list *&L)//has been done { 	L=(list*)malloc(sizeof(list)); 	L->next=NULL; }  void creatlist_single(list *&L,int n)//has been done { 	list *s,*r; 	init_single(L); 	r=L; 	while(n!=0) 	{ 		s=(list*)malloc(sizeof(list)); 		scanf("%d",&s->D); 		r->next=s; 		r=r->next;//use plus to position to position 		n--; 	} 	r->next=NULL; }  void printlist_single(list *&L)//has been done { 	list *p; 	p=L; 	while(p->next!=NULL) 	{ 		p=p->next; 		printf("%d",p->D); 		if(p->next==NULL) 			printf(" "); 	} }  void mergelist(list *&L,list *&Q,list *&head) { 	init_single(head); 	list *p,*q; 	p=L->next; 	q=Q->next; 	while(p!=NULL && q!=NULL) 	{ 		if(p->D>=q->D) 		{ 			head->next=p; 			p=p->next; 		} 		else if(p->D<q->D) 		{ 			head->next=q; 			q=q->next; 		} 		head=head->next; 	} 	while(p!=NULL) 	{ 		head->next=p; 		p=p->next; 		head=head->next; 	} 	while(q!=NULL) 	{ 		head->next=q; 		q=q->next; 		head=head->next; 	} 	head->next=NULL;  }  int main() { 	int n,m; 	list *L,*Q; 	list *p; 	init_single(p); 	scanf("%d",&n); 	creatlist_single(L,n); 	scanf("%d",&m); 	creatlist_single(Q,m); 	mergelist(L,Q,p); 	printlist_single(p); 	return 0; }   如图，这种建表方法是我们ACM里面教的，我看的数据结构的书建表方法也不是如此→_→，他们用的typedef，但那种方法我还没太明白，可以的话能不能帮忙改一下？

引用 2 楼 u012514377 的回复: void printlist_single(list *&L)//has been done { 	list *p; 	p=L; 	while(p->next!=NULL) 	{ 		p=p->next; 		printf("%d",p->D); 		if(p->next==NULL) 			printf(" "); 	} }  void mergelist(list *&L,list *&Q,list *&head) { 	init_single(head); 	list *p,*q; 	p=L->next; 	q=Q->next; 	while(p!=NULL && q!=NULL) 	{ 		if(p->D>=q->D) 		{ 			head->next=p; 			p=p->next; 		} 		else if(p->D<q->D) 		{ 			head->next=q; 			q=q->next; 		} 		head=head->next; 	} 	while(p!=NULL) 	{ 		head->next=p; 		p=p->next; 		head=head->next; 	} 	while(q!=NULL) 	{ 		head->next=q; 		q=q->next; 		head=head->next; 	} 	head->next=NULL;  }   改成了还是不行呀！ 木有输出。  另外，这个链表是有头结点的链表  你贴的这部分我看好像没什么问题 不过你的函数参数为什么又是指针又是引用的，你的list是怎么定义的？

while(p!=NULL || q!=NULL)  ||应为&&


Question: 求教~~~，逗号运算符的问题。

月经贴了！讨论没意思！看看置顶吧

我的意思是执行完（a++，b++）后，此时b的值是多少？如果通过程序结果来分析，应该是此时a的值是2，b的值是1，所以接着执行a+b，结果是3，然后输出，最后再执行b++。但是，感觉应该是先执行b++，把b的值变成2，然后再执行a+b，。这点想不明白。

函数参数的运算顺序标准没有规定。所以这代码和a++ + a同一个性质。

b++是b操作完后自加1，所以第一个（逗号表达式）的输出值是1，而第二个%d和第一个%d同级，所以此时b仍为1，a已经自加一次，变成了2，所以输出为3，输完后，b才自加1 # include <stdio.h>  int main() { 	int a = 1, b = 1; 	printf("%d, %d\n", (a++, b++), a+b); 	printf("%d\n", b);  	return 0; } lz可以看看这个——http://bbs.csdn.net/topics/370153775

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

不同的编译器有不同的结果，想这种问题等于慢性自杀

结果是不确定的，不用想了


Question: 关于sizeof函数问题

引用 7 楼 ZJQLOVELYY 的回复:[quote=引用 2 楼 czarten 的回复:] 没太看懂 首先sizeof不是函数，其次你说的"指针指向的内存大小"是什么概念？？ 就是要求函数调用时 比如前面char Merroy[20]; 调用时是copy_n(Merroy,...)这样，然后在函数里面求Merroy数组的大小[/quote]  不能的，指针只是一个地址，它只包含“从哪里开始”的信息，不包含“有多大”的信息

sizeof无能为力。 调用函数时，传入的是一个指针，任何类型(int/char....struct)的指针大小都是一样的（32位系统4字节），sizeof值一样。 解决办法： 1.商定所有char *字符串都是以 '\0'结尾，用strlen求长度 2.传入长度

sizeof是编译时就已经计算完成了，不是运行时才计算的！

sizeof是编译的时候计算好了, 所以没办法知道你程序运行到这里会有多大空间.  老老实实传一个长度进去吧, 最正规的做法了.

先说明一下sizeof不是函数 是关键字。和int，for， while等等是一类东西。 //下面这两句话你没有查仔细，你这么写是不对的 const int lenDst = sizeof(dst)/sizeof(dst[0]);//计算dst数组长度 const int lenSrc = sizeof(src)/sizeof(src[0]);//计算src数组长度 你这里sizeof（dst）中的dst仅仅是一个形参，它的类型是指针，所以这个就是计算一下指针的大小，等于4。 所以你这个绝对的不能进行字符串的复制。 往我的邮箱里发一个邮件我把答案和详细的解释给你发过去  很简单的。

引用 5 楼 ZJQLOVELYY 的回复:[quote=引用 4 楼 PDD123 的回复:] 1.无法实现你想要的功能 2.     /*经过查资料，以下两行是直接计算dst的内存字节大小而不是计算数组长度*/    const int lenDst = sizeof(dst)/sizeof(dst[0]);//计算dst数组长度    const int lenSrc = sizeof(src)/sizeof(src[0]);//计算src数组长度 这段是错的。两个长度结果都为4，sizeof(dst)计算的是，dst变量所占的空间，指针类型都为4。  如果你定义了一个变量，char dat[100];那么sizeof(dat)的结果就为100；  不是的，在函数中不一样的。你可以去试下[/quote]  我看到你说你查了资料之后再去验证一下，才回复的，要不我就是一楼 了。  sizeof(dst)，在定义dst的时候，定义成了指针，那么结果就是4，如果定义成了数组，那么结果就是数组元素大小乘以数组元素个数。而在函数void copy_n(char* const dst, char* const src,const int n)中，括号里面的“char* const dst”实际上是定义了dst，定义成了指针。  编译器在编译一个函数的时候，是只考虑函数本身的，函数是独立的。

引用 12 楼 czarten 的回复:[quote=引用 7 楼 ZJQLOVELYY 的回复:] [quote=引用 2 楼 czarten 的回复:] 没太看懂 首先sizeof不是函数，其次你说的"指针指向的内存大小"是什么概念？？ 就是要求函数调用时 比如前面char Merroy[20]; 调用时是copy_n(Merroy,...)这样，然后在函数里面求Merroy数组的大小[/quote]  不能的，指针只是一个地址，它只包含“从哪里开始”的信息，不包含“有多大”的信息[/quote] 指针包含了多大，但是没包含这个之后还有多少个～～

首先数组名作为参数处理的时候表示指针 sizeof其大小4.. 你可以通过循环判断'\0',来确定数组长度。

引用 2 楼 czarten 的回复:没太看懂 首先sizeof不是函数，其次你说的"指针指向的内存大小"是什么概念？？ 就是要求函数调用时 比如前面char Merroy[20]; 调用时是copy_n(Merroy,...)这样，然后在函数里面求Merroy数组的大小

引用 3 楼 akirya 的回复:1 sizeof理解有误 2 不能  也就是说只能通过显示传递数组大小参数了？

引用 4 楼 PDD123 的回复:1.无法实现你想要的功能 2.     /*经过查资料，以下两行是直接计算dst的内存字节大小而不是计算数组长度*/    const int lenDst = sizeof(dst)/sizeof(dst[0]);//计算dst数组长度    const int lenSrc = sizeof(src)/sizeof(src[0]);//计算src数组长度 这段是错的。两个长度结果都为4，sizeof(dst)计算的是，dst变量所占的空间，指针类型都为4。  如果你定义了一个变量，char dat[100];那么sizeof(dat)的结果就为100；  不是的，在函数中不一样的。你可以去试下

1 sizeof理解有误 2 不能

不知道你什么意思，你的参数的内存大小不是已经在实现中求出来了。


Question: esql / c求大神帮忙啊

引用 1 楼 user-1 的回复:居然还有人用ESQL啊， 用ODBC不好么？ 免得informix换成其他数据库就杯具了 哎，你以为我想啊，给我出的题就是这样的。。


Question: Program received signal SIGSEGV, Segmentation fault.

我按你的意思研究了下，发现没什么名堂嘛 #0  0x0804857b in edit (pattern=0x8048630 "*#,###", digits=0x8048637 "1234")     at 1.c:55 #1  0x0804842a in main () at main.c:7

进程意外退出会在当前目录下产生‘core’文件或形如‘core.数字’的文件比如‘core.1234’ 使用命令 gdb 运行程序名 core或core.数字 进入gdb然后使用bt命令 可以查看进程意外退出前函数调用的堆栈，内容为从上到下列出对应从里层到外层的函数调用历史。 如果进程意外退出不产生core文件，参考“ulimit -c core文件最大块大小”命令


Question: 一个C语言需求，求大神分析下

五楼大神！顶一个！

引用 10 楼 huangaqz001 的回复:[quote=引用 5 楼 zhao4zhong1 的回复:] 没实际编译链接调试，仅供参考： 请对以下源文件内容的各种测试用例分别测试： ◆0字节 ◆一行含error ◆两行，其中一行含error ◆五行，第三行含error ◆六行，第三行含error ◆六行，第三行和第四行含error ◆七行，第三行和第五行含error ◆…… #include <stdio.h> #include <string.h> static char ln[3][10000]; int i,s; FILE *f; int main() {     f=fopen("input.txt","r");     if (NULL==f) {         printf("Can not open file input.txt!\n");         return 1;     }     s=0;     i=0;     while (1) {         if (NULL==fgets(ln[i],10000,f)) break;         if (strstr(ln[i],"error")) {             if (s==0) {                 printf("%s",ln[(i+1)%3]);                 printf("%s",ln[(i+2)%3]);                 s=3;             }         }         if (s>0) {             printf("%s",ln[i]);             s--;         }         i=(i+1)%3;     }     fclose(f);     return 0; }   大侠，非常感谢你的回答，你这个代码我测试过了，是好使的。 我是菜鸟，我想问下如果那个行数要通过参数传入，那么这个改怎么实现。数组怎么定义[/quote] #include <stdio.h> #include <stdlib.h> #include <string.h> #define MAXL 1000 int L; static char ln[MAXL][10000]; int i; int j; int s; FILE *f; int main(int argc,char **argv) {     if (argc<3) {         printf("Usage: %s filename lines\n",argv[0]);         return 1;     }     f=fopen(argv[1],"r");     if (NULL==f) {         printf("Can not open file [%s]!\n",argv[1]);         return 2;     }     L=atoi(argv[2]);     if (L<2 || 1000<L) L=2;     s=0;     i=0;     while (1) {         if (NULL==fgets(ln[i],10000,f)) break;         if (strstr(ln[i],"error")) {             if (s==0) {                 for (j=1;j<L;j++) printf("%s",ln[(i+j)%L]);                 s=L;             }         }         if (s>0) {             printf("%s",ln[i]);             s--;         }         i=(i+1)%L;     }     fclose(f);     return 0; }

引用 5 楼 zhao4zhong1 的回复:没实际编译链接调试，仅供参考： 请对以下源文件内容的各种测试用例分别测试： ◆0字节 ◆一行含error ◆两行，其中一行含error ◆五行，第三行含error ◆六行，第三行含error ◆六行，第三行和第四行含error ◆七行，第三行和第五行含error ◆…… #include <stdio.h> #include <string.h> static char ln[3][10000]; int i,s; FILE *f; int main() {     f=fopen("input.txt","r");     if (NULL==f) {         printf("Can not open file input.txt!\n");         return 1;     }     s=0;     i=0;     while (1) {         if (NULL==fgets(ln[i],10000,f)) break;         if (strstr(ln[i],"error")) {             if (s==0) {                 printf("%s",ln[(i+1)%3]);                 printf("%s",ln[(i+2)%3]);                 s=3;             }         }         if (s>0) {             printf("%s",ln[i]);             s--;         }         i=(i+1)%3;     }     fclose(f);     return 0; }   大侠，非常感谢你的回答，你这个代码我测试过了，是好使的。 我是菜鸟，我想问下如果那个行数要通过参数传入，那么这个改怎么实现。数组怎么定义

引用 5 楼 zhao4zhong1 的回复:没实际编译链接调试，仅供参考： 请对以下源文件内容的各种测试用例分别测试： ◆0字节 ◆一行含error ◆两行，其中一行含error ◆五行，第三行含error ◆六行，第三行含error ◆六行，第三行和第四行含error ◆七行，第三行和第五行含error ◆…… #include <stdio.h> #include <string.h> static char ln[3][10000]; int i,s; FILE *f; int main() {     f=fopen("input.txt","r");     if (NULL==f) {         printf("Can not open file input.txt!\n");         return 1;     }     s=0;     i=0;     while (1) {         if (NULL==fgets(ln[i],10000,f)) break;         if (strstr(ln[i],"error")) {             if (s==0) {                 printf("%s",ln[(i+1)%3]);                 printf("%s",ln[(i+2)%3]);                 s=3;             }         }         if (s>0) {             printf("%s",ln[i]);             s--;         }         i=(i+1)%3;     }     fclose(f);     return 0; }    额，刚引用错了，是这位大侠。  要的就是这位大侠这样的，用代码来分析需求。前几个大侠那种光说，没啥用。

引用 4 楼 yy21yeyu 的回复:这个直接用两个缓冲区，记录当前行的上面两行不就完了，这样就是效率低了点。回读效率高，就是控制有点麻烦，可以用两个int记录一下当前行的上面两行起始位置的offset，然后setfilepointer或者fseek  要的就是这位大侠这样的，用代码来分析需求。前几个大侠那种光说，没啥用。

引用 6 楼 Ronux 的回复:5楼的代码很完美。  1.总是保存最近3行的数据 2.如果最近一行包含error，则输出前两行，并设置标记 3.输出含error的一行，并输出接下来的两行。 这个实现不错

每读完一行，首先判断是否有error，有则把上一行缓存的打印出来，同时也把下一行打印出来，并缓存；没有则缓存该行 用变量保存一行字符串就可以了

把文件内容搞进内存里  加一个行索引

读关键字已经没啥问题了，关键是这个上下几行，不知道怎么实现比较好。


Question: 哎,看似没问题的地方恰恰是问题的所在.

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

lz最近在学习linux内核？

把不开心的说出来 大家开心下嘛

小河沟里经常翻船！

大水笔，给分。

我们经常被嵌入式坑。  引用 楼主 nadleeh123 的回复: 又给内核坑了一把


Question: 循环链表解决约瑟夫环问题，有段代码不懂，有大神解释啊

vector<int> yuesefeng(int n,int m)//n代表初始人数，m代表初始号码 { 	vector<int> out; 	list<int> in; 	list<int>::iterator pos; 	int i; 	for(i=1;i<=n;i++) 		in.push_back(i); 	pos=in.begin(); 	int kk=m;     while(in.size()!=0) 	{	 		if(kk!=1) 		  { 			  pos++; 			  kk--; 		   if(pos==in.end())//注意要判断是否到尾部了，到尾部就指向头部 			pos=in.begin(); 		   } 		else 		{ 			out.push_back(*pos);//到数了，点到的人保存到输出 			pos=in.erase(pos);///将此人从列表中删除，注意erase返回的是下个人的指针 			if(pos==in.end()) 				pos=in.begin(); 		}	     	} 	return out; } 这是我自己写的。。没优化过。。用list实现

引用 1 楼 truelance 的回复:这段代码里错误不是一般多啊. 明显是一本误人子弟的书.+1,简单问题不要复杂化

for循环没有问题，有一点要知道：while循环开始时，x指向的是循环链表的尾节点，你再分析分析； 这个代码不但没有错，而且还有些经典

/**adv30@126.com  *内容：  * 有n个猴子，按顺时针方向围成一个圈选大王。  * 从第1号开始报数1，2，……，数到m号时该猴子退出到圈外，  * 如此报数直到圈内只剩下一个猴子时，此猴子便是大王。  * 由键盘输入 n，m，打印出猴子大王序号。  *输入说明：  * 一行2个整数  *输出说明：  * 一行一个整数  *输入样例：  * 10 3  *输出样例 ：  * 4  */ #include <stdio.h> typedef struct Noier {     int number;     int onoff; } NOIER ; int main(void) {     int n,m,i,k=1,cnt=0;     NOIER noier[1000];     scanf("%d %d",&n,&m);     for(i=0; i<n; i++)     {         noier[i].number=i+1;         noier[i].onoff=1;     }     i=0;     while ((n-cnt) > 1)     {         if(noier[i].onoff)         {             if(k%m==0)             {                 noier[i].onoff=0;                 cnt++;             }             k=(k+1)%m;         }         i=(i+1)%n;     }     while(noier[i].onoff == 0)     {         i++;     }     printf("%d\n",noier[i].number);     return 0; }

//假设有n个人团团围做，从第1个人开始数数，数到第m个人时候，第m个人出列， //然后继续从1开始数数，数到第m个人退出 #include <stdio.h> #include <conio.h> int i,k,t; int n,m; static char f[1001];//0该座位未出圈,1该座位已出圈 void main() {     while (1) {         printf("Input n m(1000>=n>=m>=1):");         fflush(stdout);         rewind(stdin);         if (2==scanf("%d%d",&n,&m)) {             if (1000>=n && n>=m && m>=1) break;         }     }     t=0;//已出圈总人数     i=1;//座位编号     k=1;//当前要数的数     while (1) {         if (0==f[i]) {             if (m==k) {                 t++;                 f[i]=1;                 printf("%3d ",i);                 if (0==t%10) printf("\n");                 if (t>=n) break;             }             k++;if (k>m) k=1;         }         i++;if (i>n) i=1;     }     cprintf("Press any key ...");     getch(); }

代码就不看了，自己看wiki百科吧：  http://zh.wikipedia.org/zh-cn/%E7%BA%A6%E7%91%9F%E5%A4%AB%E6%96%AF%E9%97%AE%E9%A2%98 英文版有例子程序 http://en.wikipedia.org/wiki/Josephus_problem

约瑟夫环问题可以抽象出一个数学模型，比用循环链表简单多了。 http://blog.csdn.net/changyuanchn/article/details/20653215 and你这段代码太凌乱了。

这段代码里错误不是一般多啊. 明显是一本误人子弟的书.


Question: IOCP 服务 线程  和缓存问题

如果你的工作线程是CPU计算密集型的，那么根据CPU核心数量确定工作线程数的做法是正确的，这就好像是4车道满满的跑了4两车，没有浪费。 否则工作线程数据与计算/IO比例相关，IO阻塞的时候可以把车道让给别的车。  工作线程不是收数据，而是从缓存池里面去数据出来处理，缓存池中的数据应该包含对应的连接信息。

引用 2 楼 user-3 的回复:[quote=引用 1 楼 zhao4zhong1 的回复:] 参考Microsoft SDK\samples\netds\WinSock\iocp\*.* ? 膜拜大神，什么帖子里都有您的脚印[/quote]

引用 1 楼 zhao4zhong1 的回复:参考Microsoft SDK\samples\netds\WinSock\iocp\*.* ? 膜拜大神，什么帖子里都有您的脚印


Question: linux c编程 文件内容为空时，读取文件出现乱码

feof（）很少用这个函数

参考 http://blog.csdn.net/bingqing07/article/details/5785080

不要用feof()来判断文件的结束，一般都是用fread() 或read()的返回值来判断文件是否结束，你可以看一下man手册 一般文件结束的时候会返回0。


Question: 关于读写文件的问题

当前进程目录下

FILE* f; f = fopen(“/home/file”, "w"); fputs(“abcd”，f)； fclose(f)； 这样的话，你写的内容就存放在了/home/file文件中了

工程文件夹下面，找找debug目录

FILE* f;只是定义了一个文件类型指针变量。在你的代码中并未关联一个文件。这段代码错误。

file不就是你的文件路径吗？f是文件指针


Question: 看c语言源码，其中有好多回调函数，求方法

emacs + cscope

这个没办法避免的！回调也只是一个指针而已！要习惯！  很多开源的东西都是回调来搞的

代码功能归根结底不是别人帮自己看或讲解或注释出来的；而是被自己静下心来花足够长的时间和精力亲自动手单步或设断点或对执行到某步获得的中间结果显示或写到日志文件中一步一步分析出来的。 提醒：再牛×的老师也无法代替学生自己领悟和上厕所！ 单步调试和设断点调试是程序员必须掌握的技能之一。

SourceInsight  引用 楼主 a971124568 的回复:小弟现在正在看c语言的一个开源项目的源码，但里面都是回调函数，看起来十分麻烦，一会就把自己转晕了，想请问一下大家，有没有好的方法或者工具


Question: 关于镜像子串！！

什么镜像串，就是回文串，楼上正解用 manacher 回文字串算法。

回文串，你可以看下manacher算法。线性时间复杂度。


Question: 怎么避免两个指向同一个地址的多次释放问题

引用 49 楼 zeng_c_j 的回复:这相当于共享资源问题了，可以加上一个引用计数，释放之前先查看引用计数是否清零，清零代表已释放，未清零表示还未释放。 恩恩，说白了就是shard_ptr问题 谢谢

引用 51 楼 xihu1364 的回复:我觉得楼主想提的问题是 线程1 char* p = malloc.....  将p传给线程2  线程2将p free了并且置空  线程1就不知道如何是好了，因为线程2置空的是p的拷贝 置空了  线程1的p还是指着那块内存  是这个意思，你可以看我的另外一个帖子。。。。就是实际的问题

忘了C里面有没有引用一说 要么用智能指针 或者 int *&ptr2 = ptr;

楼主的代码逻辑上就不对啊，malloc和free是要一一配对的，这里malloc了一次却有两个free，肯定错的啊

如果想自己实现，那么可以让内存由对象管理，对象负责内存引用计数的增加和减小。  template <class T> class CRefCs : public T {  public: 	CRefCs() 		:m_cRef(0) 	{  	} 	virtual ~CRefCs() 	{  	} public:      inline static ULONG ourmax( const ULONG & a, const ULONG & b ) 	{ 		return a > b ? a : b; 	} 	ULONG AddRef() 	{ 		LONG lRef = InterlockedIncrement( &m_cRef ); 		_ASSERTE(lRef > 0);  		return ourmax(ULONG(m_cRef), 1ul); 	}  	ULONG Release() 	{ 		LONG lRef = InterlockedDecrement( &m_cRef ); 		//_ASSERTE(lRef >= 0); 		if (lRef == 0) 		{ 			m_cRef++;  			delete this; 			return ULONG(0); 		} else  		{ 			return ourmax(ULONG(m_cRef), 1ul); 		} 	} 	  #if (_MSC_VER > 1310) 	volatile LONG	m_cRef; #else 	LONG	m_cRef; #endif };

引用 35 楼 derekrose 的回复:[quote=引用 34 楼 wallwind 的回复:] [quote=引用 33 楼 derekrose 的回复:] 这问题一般学生时代 每天能问出来五六个类似的 后来发现我真是浪费时间  透过问题看本质。。。  你是高人，如果简单就无视吧，不要在这里炫耀，你是版主怎么样呢？你是大牛怎么样呢？莫装逼，装逼遭雷劈。  。。我是在多个系统异步状态机会遇到的问题。。。然后简单的随手写的一个东西来讨论。。。。  最后问你一个问题，你这版主怎么当上的。。。这csdn算是完蛋了。  [/quote]  看本质就是在c++里面一般选择用对象管理资源，要不自己构建对象管理handle，要不使用别人写好的类库，或者使用智能指针。c语言中就办法少了一点，你说出你的需求，然后我给你解决方案。我推荐大部分的学生都不要针对某些奇思淫巧进行拓展，这真的是对时间的浪费，学生时间非常宝贵。  我只是阐述一个事实，这种事情本来就是无意义的，我的初衷就是你写了什么代码之后产生了某些联系，然后想到的这个问题，我也可以告诉你去使用智能指针来代替，但是这种类似的提问，在这里几乎天天可见，所以我认为我可以去引导一些学生，让他们可以知道什么东西是重要的，什么是不重要的，我只是这个目的。  对于您对csdn的版主审核制度，你可以去系统管理员处举报或者提出更好的建议。  另外我有没有炫耀，另外你可以去考量一下佛印和苏东坡的故事。[/quote]  你也可以去看一个故事：上山的人问下山的人山顶风景如何，但是上山的人依然还是上去的故事。。。

很明显楼主的代码是纯C代码。那些C++里的解决方案统统不行

你的情况，学名叫“double free”，可以google下学习  用内存池，锁也要自己加好

怎么避免两个指向同一个地址的多次释放问题 怎么避免两个人同时蹲一个茅坑蹲完冲水时的多次冲水问题   怎么避免两个不同用途的指针指向同一个地址导致释放这两个指针所指对象时发生多次释放问题 怎么避免两个不同屁股的人同时蹲一个茅坑导致蹲完冲水时发生多次冲水问题

c++ 的话，使用智能指针是个好选择。c 的话，貌似只能人为避免了。

引用 41 楼 supermegaboy 的回复:楼主的纠结是自找的，C++各本论著一直都在阐述类似问题的解决与避免方法，只是很多人都没有理解大师的良苦用心，相反还自以为是垃圾、缺陷，这是自找的。  这类问题有不少代替方法，通常来说，你可以用标准库的容器，把内存管理交给标准库，要么，也可以选择RAII，使用各类smart pointer，楼主的问题可以使用share_pointer。  NONO 楼主问的是c 我刚开始也看错了 我也以为是c++

引用 39 楼 wallwind 的回复:[quote=引用 35 楼 derekrose 的回复:] [quote=引用 34 楼 wallwind 的回复:] [quote=引用 33 楼 derekrose 的回复:] 这问题一般学生时代 每天能问出来五六个类似的 后来发现我真是浪费时间  透过问题看本质。。。  你是高人，如果简单就无视吧，不要在这里炫耀，你是版主怎么样呢？你是大牛怎么样呢？莫装逼，装逼遭雷劈。  。。我是在多个系统异步状态机会遇到的问题。。。然后简单的随手写的一个东西来讨论。。。。  最后问你一个问题，你这版主怎么当上的。。。这csdn算是完蛋了。  [/quote]  看本质就是在c++里面一般选择用对象管理资源，要不自己构建对象管理handle，要不使用别人写好的类库，或者使用智能指针。c语言中就办法少了一点，你说出你的需求，然后我给你解决方案。我推荐大部分的学生都不要针对某些奇思淫巧进行拓展，这真的是对时间的浪费，学生时间非常宝贵。  我只是阐述一个事实，这种事情本来就是无意义的，我的初衷就是你写了什么代码之后产生了某些联系，然后想到的这个问题，我也可以告诉你去使用智能指针来代替，但是这种类似的提问，在这里几乎天天可见，所以我认为我可以去引导一些学生，让他们可以知道什么东西是重要的，什么是不重要的，我只是这个目的。  对于您对csdn的版主审核制度，你可以去系统管理员处举报或者提出更好的建议。  另外我有没有炫耀，另外你可以去考量一下佛印和苏东坡的故事。[/quote]  你也可以去看一个故事：上山的人问下山的人山顶风景如何，但是上山的人依然还是上去的故事。。。[/quote]  这不叫故事  只是臆想 或者说叫寓言，本质上是虚无的，逻辑和构思建立在思维的维度上，俗话说就是在xxx。我只说一点，你缺乏信仰，崇拜情绪，你认为论坛上的话只要不加以标注，就都是对你有敌意的，而我对于你的敌意认为是emotion，这就是思维维度。  而我让你看的是一件 historical fact .并没有要求你去如何解释，你只需要看一下即可，你可以讲给自己听，你需要去讲给自己听，因为比c++能力比什么编程能力更重要的是find you！而不是继续lost。而你给我看的是一个a fabricated story， i like read when i was young

引用 30 楼 wallwind 的回复:[quote=引用 14 楼 nadleeh123 的回复:] [quote=引用 楼主 wallwind 的回复:] 比如以下代码 #include<stdlib.h> #include<stdio.h>  int main() {   int *ptr = malloc(10*sizeof(int));   int *ptr2 = ptr;    if(ptr)   {      free(ptr);     ptr =NULL;     printf("delete one");   }    if(ptr2)   {     free(ptr2);     ptr2=NULL;        printf("delete two");   }   return 0;   }  以上代码肯定有问题。。。这种怎么避免？  谁用谁释放，非要自己弄个1对多的平级关系，错了怪谁[/quote]  yin  引用 2 楼 user-13 的回复:看不出这代码的用途。。。 所以，正常情况下不会写这样的代码，就自然而然避免了。 引用 21 楼 bug1190 的回复:[quote=引用 14 楼 nadleeh123 的回复:] [quote=引用 楼主 wallwind 的回复:] 比如以下代码 #include<stdlib.h> #include<stdio.h>  int main() {   int *ptr = malloc(10*sizeof(int));   int *ptr2 = ptr;    if(ptr)   {      free(ptr);     ptr =NULL;     printf("delete one");   }    if(ptr2)   {     free(ptr2);     ptr2=NULL;        printf("delete two");   }   return 0;   }  以上代码肯定有问题。。。这种怎么避免？  谁用谁释放，非要自己弄个1对多的平级关系，错了怪谁[/quote] 这个回复我喜欢，比其它楼的回复都要好，其它人说的再多再精彩本质上都是一砣翔[/quote]   你们遇到过异步回调函数，携带指针过去的代码？然后需要在携带回来的？  需要多个子系统合作，异步状态机制的代码问题？  那个道理我们都懂。。。。同一个地址内容在不同类的之间使用的时候。。。。。等到你们遇到一些复杂的代码就。。。[/quote] 用个全局的不就ok了？ 或者直接先申请一段内存来放指针。

引用 36 楼 lming_08 的回复:这个是没办法避免的，只能靠程序员自己控制了！ 另外回复楼上的，研究这个问题绝对不是浪费时间，在开发过程中遇到很正常，记得当年找ｂｕｇ时就碰到莫名其妙的挂掉问题，然后花很长时间才发现是内存重复释放 很好避免啊，引用计数 count 为 0 才真的 free 。

引用 34 楼 wallwind 的回复:[quote=引用 33 楼 derekrose 的回复:] 这问题一般学生时代 每天能问出来五六个类似的 后来发现我真是浪费时间  透过问题看本质。。。  你是高人，如果简单就无视吧，不要在这里炫耀，你是版主怎么样呢？你是大牛怎么样呢？莫装逼，装逼遭雷劈。  。。我是在多个系统异步状态机会遇到的问题。。。然后简单的随手写的一个东西来讨论。。。。  最后问你一个问题，你这版主怎么当上的。。。这csdn算是完蛋了。  [/quote]  看本质就是在c++里面一般选择用对象管理资源，要不自己构建对象管理handle，要不使用别人写好的类库，或者使用智能指针。c语言中就办法少了一点，你说出你的需求，然后我给你解决方案。我推荐大部分的学生都不要针对某些奇思淫巧进行拓展，这真的是对时间的浪费，学生时间非常宝贵。  我只是阐述一个事实，这种事情本来就是无意义的，我的初衷就是你写了什么代码之后产生了某些联系，然后想到的这个问题，我也可以告诉你去使用智能指针来代替，但是这种类似的提问，在这里几乎天天可见，所以我认为我可以去引导一些学生，让他们可以知道什么东西是重要的，什么是不重要的，我只是这个目的。  对于您对csdn的版主审核制度，你可以去系统管理员处举报或者提出更好的建议。  另外我有没有炫耀，另外你可以去考量一下佛印和苏东坡的故事。

引用 33 楼 derekrose 的回复:这问题一般学生时代 每天能问出来五六个类似的 后来发现我真是浪费时间  透过问题看本质。。。  你是高人，如果简单就无视吧，不要在这里炫耀，你是版主怎么样呢？你是大牛怎么样呢？莫装逼，装逼遭雷劈。  。。我是在多个系统异步状态机会遇到的问题。。。然后简单的随手写的一个东西来讨论。。。。  最后问你一个问题，你这版主怎么当上的。。。这csdn算是完蛋了。


Question: 中缀转后缀的 递归，处理括号有问题，求指教

建议LZ针对出现的问题检查代码是否正确实现了关于左右括号的语法规则. 函数factor中要删除3行以保证出现了左括号后必须有右括号: void factor() {   char s;   if(expr[i] >= 48 && expr[i] <= 57){     s = expr[i];     i++;     printf("%c",s);   }   else{     if(expr[i] == '('){       i++;       total();     //删 }     //删 else{     //删   printf("the char is :  %c\n",expr[i]);       if(expr[i] == ')'){         i++;         if(expr[i] == '+' || expr[i] == '-')           rest1();         else           rest2();       }       else         printf("Error\n");     }   } }

代码功能归根结底不是别人帮自己看或讲解或注释出来的；而是被自己静下心来花足够长的时间和精力亲自动手单步或设断点或对执行到某步获得的中间结果显示或写到日志文件中一步一步分析出来的。 提醒：再牛×的老师也无法代替学生自己领悟和上厕所！ 单步调试和设断点调试是程序员必须掌握的技能之一。


Question: 在ubuntu 64bit上怎么交叉编译libffi for android

使用ndk standalone-toolchain 成功 host=arm-linux-androideabi i686linux-androideabi都成功了，只是mipsel没有成功 谢谢大家

引用 2 楼 nadleeh123 的回复:[quote=引用 楼主 blackant2 的回复:] 不太会用gcc,使用ndk-build也行,gcc更好  一般的开源资源都有 configure 这个脚本,直接help 里面有--build 和 --host参数[/quote] ./configura --build=i386/i686 --host=arm make 一般都这样,某些比较非主流的或许要自己改改make或者借助某些补丁,比如那个坑爹的perl解释器源码

引用 楼主 blackant2 的回复:不太会用gcc,使用ndk-build也行,gcc更好  一般的开源资源都有 configure 这个脚本,直接help 里面有--build 和 --host参数

参考http://sourceware.org/libffi/ 参考http://blog.sina.com.cn/s/blog_79b04d6d0100rt2d.html  引用 楼主 blackant2 的回复:不太会用gcc,使用ndk-build也行,gcc更好


Question: 语法错误

引用 楼主 u012523688 的回复:while( j <= n ) 	{ 		scanf("%d",&a[j++]); 	} 想要往数组中输入n个数，上述错误在哪里，楼主懵了！ 。。。我怎么犯这么低级的错误，谢谢！

j==n的时候也能进循环，但这个时候已经越界了。


Question: 求指教

环境问题或者是头文件包含问题

#include <stdio.h> 集成环境最好改用Code::Blocks(http://www.codeblocks.org/)  引用 楼主 u013926949 的回复:getchar在DEV-C++5.6.1中运行为什么会出错?


Question: 关于《C陷阱》中不明白的部分，求指教！

多谢楼上网友细心解释，谢谢大家啦

详细补充一下：例如你在gcc下编译这程序，生成a.out可执行文件，你同一目录下有1.txt文件，文件里存的内容就是0 1 2 3 4。那么你在字符终端下输入"./a.out < 1.txt"命令，那么就会和作者得到结果一模一样。这个不属于语言范畴的问题不理解也很正常。

进来学习一下，长知识了

第二个问题：标准输入不一定是字符终端输入，标准输入如果重定向为文件就会有文件结束符的意义，在 linux下编程应该知道重定向的含义。

谢谢这位网友的答复，我已经基本上明白了这些问题，关键是在文件结束符上！当scanf接受到文件结束符时就会不再执行然后在输出1234.但是我在之前只是出入了5个数据，并没有输入文件结束符，所以显然，scanf仍然在执行。所以无法输出1234.

可能影响了i的高位，或者符号位，导致循环第五次后i值>=5了，这个每个编译器不一样的表现。你可以在for循环后，再将i值print出来看一下，应该是个负数，或者比较大。  main() { int i; char c; for(i = 0; i < 5; i++) { scanf("%d", &c); printf("%d", i); }  printf("%d",i); //这里加一句看一下就知道了。  printf("/n"); }


Question: 试着写了一个判断是否继续的函数，能运行但是这几个警告是什么意思？

select=(char*)malloc(sizeof(char));  只分配了一个字节空间 可以sizeof(char)写成100规定最大输入100字节 然后初始化memset(select,0,100); 然后main()之前加返回值void 或者int char *a="yes";

感谢

一切的根源在于： char* select,a="yes";  这样的定义相当于是char a="yes"，所以应该改为： char* select,*a="yes";   另外有些编译器会要求源代码的最后一行留空，你在最后回车一下添加一个空行即可。  引用 楼主 wpx9184 的回复: #include <stdio.h> #include <stdlib.h> #include <string.h>  int choice()					//判断是否继续的函数  { 	char* select,a="yes";  	select=(char*)malloc(sizeof(char)); 	printf("是否继续输入？\n"); 	gets(select); 	if(strcmp(select,a)==1) 		{ 		free(select); 		return 0; 		} 	else 		{ 		free(select); 		return 1;	 		} }  main() { 	int choice(); 	int count=1; 	while(choice()) 	{ 		printf("%d\n",count); 		count++; 	} 	printf("The End!\n"); 	return 0; }   --------------------配置: mingw5 - CUI Debug, 编译器类型: MinGW--------------------  检查文件依赖性... 正在编译 D:\KNNR\test.c... [Warning] D:\KNNR\test.c:7: warning: initialization makes integer from pointer without a cast [Warning] D:\KNNR\test.c:11: warning: passing arg 2 of `strcmp' makes pointer from integer without a cast [Warning] D:\KNNR\test.c:34:2: warning: no newline at end of file 正在连接...  完成构建 test: 0 个错误, 3 个警告 生成 D:\KNNR\test.exe  想搞清楚这几个警告是什么意思


Question: C语言中关于指针和++的问题。。

引用 4 楼 u013106556 的回复:[quote=引用 3 楼 happyperson 的回复:] p是int型的指针，p++是按照sizeof(int)加的，最后*p是取的随机值 *p的值为随机值，意思是每次运行都不相同？但是每次运行后其值是相同的，都是1638212。。不知道你这个随机是如何理解的。。。[/quote] 这个跟编译器有关系。vs2012以上，就是会变的值。vs2010是固定的值。

引用 19 楼 changyuanchn 的回复: 请注意他们的associativity。[/quote]  associativity 本身没有先后顺序 ++ 可以左结合，这时它是p++，即后缀++ 也可以右结合，这时它是++p,即前缀++  编译器，先判断出是前缀++，还是后缀++，然后区分++这个运算符的优先级 因为实质上++是两个不同的运算符，但是识别的时候，只能先识别 ++ ，再去判断 ++是前缀++，还是后缀++  *p++ 根据结合性，不能判定先执行哪一个。因为后缀++，--的特殊性，先计算 表达式 p++ 的值，在使用 p 的值（p++ ==p） 然后通过p 的值，得到*p 的值 结合性从来不是，判断先计算和后计算的依据，优先级才是 结核性判断的是这个符号，该和左边的表达式结合，还是右边的表达式  一旦判断出来结合性以后，就会用通过优先级，和操作数的个数，判断如何解读表达式。 associativity 结合性，是 判断符号（运算符）该和谁----左边的表达式，还是右边的表达式----结合，而不是判断一个变量或者表达式，该优先和那个符号（运算符）结合。  变量不过是表达式的一种终结符---原子表达式？不可分割的表达式的一种---在表达式的计算中，并无其他特殊含义。  associativity， priority 结合性和优先级，是两种不同的概念associativity 表明运算符该和哪一边结合 分为左结合，右结合，两边结合 ；++，-- 是一个形式，两种运算符，所以 是左，右二选一结合的，不是纯粹左结合的，也不是纯粹右结合的，也不是 两边结合的。  一般来说，双目运算符是两面结合的，单目运算符是单边结合的，一般是右结合的  单目运算符中，算术运算符，只有 ++，-- 可以左结合   因为++，--是单目运算符，，只能是单边结合的，但是这++，-- 运算符， 都有前缀形式，和后缀形式，所以必须先判断结合性，再在解读优先级，  其他运算符，优先级，结合性是直接给出的，不用判断。  哦，双目运算符[]，等也是比较特殊的， 左边是左操作数， []内部，是右操作数 因为右操作数，在运算符内部，所以这个运算符，是左结合的。  运算符的结合性，不能判断计算的顺序，比如 a+b/c

引用 17 楼 changyuanchn 的回复:/quote] 在*iter++根本是不存在你说的“++优先级比*高”，对于这个问题的，你所谓的“++优先级比*高”是没有任何意义的，不去做无谓的戏份也是能够得到正确答案的。  *和++ 是相邻的两个运算符 如果 *的优先级高 ，那么 先  *p 结合，再对 (*p) 做++  ，就是 (*p)++了 如果 ++ 优先级高 ，那么 先 p++结合， 再对 (p++) 这个表达式 做 *  操作, 就是*(p++)了  *p++,*++p 这里的优先级是起作用的 ++的优先级，比一元 *的优先级高 所以 先 执行++ 在对表达式 p++执行 *操作   结果分别是是  1)*p++; *p++  的结果是 *p;副作用是 p++;  先后顺序是 *p; p++; 2)*++p *++p  的结果是 *(p+1);副作用是 ++p;  先后顺序是  ++p;*p 此时的 *p, 等于 ++前的*(p+1)   运算符的优先级，是指表达式计算过程中，相邻的两个运算符的优先级。 ++ 这种运算符和优先级的关系，是表达式计算的优先级，而不是 p ++这个表达式中， p自增的优先级。 ++ 在前， 自增先算； ++在后，自增后算；  自增的计算先后，只和 ++ 在前，在后有关；和优先级并无关系，有关系的是表达式的值。  ++在前， 使用的是自增后的结果。 ++在后，使用的是自增前的结果。  *p是从地址中取出其中储存的数据，这也是要计算的。 表达式计算的是表达式的结果，而不是 其中变量的值，  变量在计算表达式中，发生变化，是表达式计算的副作用，不是计算的主要任务 虽然，我们实际上需要的可能是变量的值，但是那不是表达式计算过程必须的。 只有在代码优化的时候，才有可能用取消表达式求值过程中，不需要的那部分。  比如  p++； 自增是我们需要的，但是 求 p++ 这个表达式的值， 才是表达式求值的任务，自增只是副作用而已。  使用C，C++始终要记住，变量，函数调用，等等都能够成为表达式，函数的实参实际上也是表达式。 C,C++语言一直都在计算表达式。 *iter++,*++iter 和指针 *p++,*++p;是一样的  因为  1）iterator 本来就可以实现为指针，也可以实现为类，结构这只和实现有关系 2）iterator 如果是个对象类型的化，那他 就必然实现 operator++(),operator--(), operator*()       那么，它的++，--，*的优先级和指针的一致。 3）STL 中的容器相关的算法，可以对指针使用，也可以对iterator 使用，因为这是 STL的设计目标。     就是说，数组也是为视为容器，虽然取数组大小比较麻烦。   PS： 如果，只从变量，来理解 *p++,*++p;这种表达式，显然是不够的。 这里是要考虑优先级的； 变量，只是构成表达式的一种元素，不是全部元素。

我来指出一个问题和回答一个问题吧。 指出的问题是（！！接着，将p所存的内容加1）你把m=*p++后面过程理解错了。正解是这样的，实现m=*p，之后p指针自加一，因为你定义p是int型指针，那么p++就相当于（地址p）=（地址p）+（4bit），结果就是p还是一个地址，并且指向了下一个int型数据，而不是将p中的内容加1。 回答（*p的值又是如何确定的）：这么跟你解释吧，当计算机运行程序时，代码汇编成机器语言放在代码段（内存）中，而程序中的数据放在数据段（内存）中，当你定义int a=1是系统就在数据段中按照一定的算法找到不用的4bit地址，擦除它原来的数据重新赋值为2（注意是先擦除后赋值）。所以当p++之后p就指向了接下来的4bit地址，注意这个地址中的数据是没有擦除的（我们不知道有或者没有），总之它是一个随机数，因此*p的值是个随机数。 希望能帮到你，不用谢。

引用查了一些资料，*p++本质是*(p++),即先考虑p++！而p++计算时，先使用p的值 对这些资料，只想说呵呵

引用 18 楼 lm_whales 的回复:[quote=引用 17 楼 changyuanchn 的回复:] /quote] 在*iter++根本是不存在你说的“++优先级比*高”，对于这个问题的，你所谓的“++优先级比*高”是没有任何意义的，不去做无谓的戏份也是能够得到正确答案的。  *和++ 是相邻的两个运算符 如果 *的优先级高 ，那么 先  *p 结合，再对 (*p) 做++  ，就是 (*p)++了 如果 ++ 优先级高 ，那么 先 p++结合， 再对 (p++) 这个表达式 做 *  操作, 就是*(p++)了  *p++,*++p 这里的优先级是起作用的 ++的优先级，比一元 *的优先级高 所以 先 执行++ 在对表达式 p++执行 *操作   结果分别是是  1)*p++; *p++  的结果是 *p;副作用是 p++;  先后顺序是 *p; p++; 2)*++p *++p  的结果是 *(p+1);副作用是 ++p;  先后顺序是  ++p;*p 此时的 *p, 等于 ++前的*(p+1)   运算符的优先级，是指表达式计算过程中，相邻的两个运算符的优先级。 ++ 这种运算符和优先级的关系，是表达式计算的优先级，而不是 p ++这个表达式中， p自增的优先级。 ++ 在前， 自增先算； ++在后，自增后算；  自增的计算先后，只和 ++ 在前，在后有关；和优先级并无关系，有关系的是表达式的值。  ++在前， 使用的是自增后的结果。 ++在后，使用的是自增前的结果。  *p是从地址中取出其中储存的数据，这也是要计算的。 表达式计算的是表达式的结果，而不是 其中变量的值，  变量在计算表达式中，发生变化，是表达式计算的副作用，不是计算的主要任务 虽然，我们实际上需要的可能是变量的值，但是那不是表达式计算过程必须的。 只有在代码优化的时候，才有可能用取消表达式求值过程中，不需要的那部分。  比如  p++； 自增是我们需要的，但是 求 p++ 这个表达式的值， 才是表达式求值的任务，自增只是副作用而已。  使用C，C++始终要记住，变量，函数调用，等等都能够成为表达式，函数的实参实际上也是表达式。 C,C++语言一直都在计算表达式。 *iter++,*++iter 和指针 *p++,*++p;是一样的  因为  1）iterator 本来就可以实现为指针，也可以实现为类，结构这只和实现有关系 2）iterator 如果是个对象类型的化，那他 就必然实现 operator++(),operator--(), operator*()       那么，它的++，--，*的优先级和指针的一致。 3）STL 中的容器相关的算法，可以对指针使用，也可以对iterator 使用，因为这是 STL的设计目标。     就是说，数组也是为视为容器，虽然取数组大小比较麻烦。   PS： 如果，只从变量，来理解 *p++,*++p;这种表达式，显然是不够的。 这里是要考虑优先级的； 变量，只是构成表达式的一种元素，不是全部元素。  [/quote] 请注意他们的associativity。

引用 15 楼 oYinGui1 的回复:[quote=引用 14 楼 changyuanchn 的回复:] [quote=引用 13 楼 oYinGui1 的回复:] [quote=引用 10 楼 changyuanchn 的回复:] 错了楼主，*p++的意思是先取p所指向的值，然后在将p++。因为*，++的优先级是一样的，结合度是从右向左，但是p++是先取p的值，然后在去++，而取出来的p，要先进性*p的运算。 ++优先级比*高，不论前缀还是后缀。。。。你说的优先级一样是从哪个表里看来的。。。[/quote] The C programming language. 二者的优先级是一致的，并没有去细分他们的高低，谭浩强的书中好像是有分吧，但是这没有什么意义。[/quote] 看对什么问题，CP5里是明确指出*iter++这种表达式的解释方法的，++优先级比*高。对于这种表达式确实要了解一下优先级。[/quote] 在*iter++根本是不存在你说的“++优先级比*高”，对于这个问题的，你所谓的“++优先级比*高”是没有任何意义的，不去做无谓的戏份也是能够得到正确答案的。

引用 13 楼 oYinGui1 的回复:[quote=引用 10 楼 changyuanchn 的回复:] 错了楼主，*p++的意思是先取p所指向的值，然后在将p++。因为*，++的优先级是一样的，结合度是从右向左，但是p++是先取p的值，然后在去++，而取出来的p，要先进性*p的运算。 ++优先级比*高，不论前缀还是后缀。。。。你说的优先级一样是从哪个表里看来的。。。[/quote] The C programming language. 二者的优先级是一致的，并没有去细分他们的高低，谭浩强的书中好像是有分吧，但是这没有什么意义。

如果搞不清楚操作符优先级的顺序，用下面的方法 1. () 你要明确地操作， 如 *(p++), (*p)++ 2. 分成多行书写：    a = *p++; -->      a = *p;     p++;

引用 14 楼 changyuanchn 的回复:[quote=引用 13 楼 oYinGui1 的回复:] [quote=引用 10 楼 changyuanchn 的回复:] 错了楼主，*p++的意思是先取p所指向的值，然后在将p++。因为*，++的优先级是一样的，结合度是从右向左，但是p++是先取p的值，然后在去++，而取出来的p，要先进性*p的运算。 ++优先级比*高，不论前缀还是后缀。。。。你说的优先级一样是从哪个表里看来的。。。[/quote] The C programming language. 二者的优先级是一致的，并没有去细分他们的高低，谭浩强的书中好像是有分吧，但是这没有什么意义。[/quote] 看对什么问题，CP5里是明确指出*iter++这种表达式的解释方法的，++优先级比*高。对于这种表达式确实要了解一下优先级。

引用 10 楼 changyuanchn 的回复:错了楼主，*p++的意思是先取p所指向的值，然后在将p++。因为*，++的优先级是一样的，结合度是从右向左，但是p++是先取p的值，然后在去++，而取出来的p，要先进性*p的运算。 ++优先级比*高，不论前缀还是后缀。。。。你说的优先级一样是从哪个表里看来的。。。

m = *p++; 这句，考的是运算符优先级的问题，如果是题目，那么你就按照教科书上的优先级来做，具体哪个运算符优先，我也拿不实在了。如果是编写实际的项目，那么你遇到这种有可能有歧义的情况，最好用括号表明优先级，因为有些编译器并不标准，这种情况可能不同的编译器有不同的结果。  ————————  P是指向a的指针，而a只是一个变量，进行p++运算之后，p就指到了a后面，但是a后面不一定是b，这也是依赖于编译器的，a、b、m的存放顺序病没有一个标准。

//C++ Operators //  Operators specify an evaluation to be performed on one of the following: //    One operand (unary operator) //    Two operands (binary operator) //    Three operands (ternary operator) //  The C++ language includes all C operators and adds several new operators. //  Table 1.1 lists the operators available in Microsoft C++. //  Operators follow a strict precedence which defines the evaluation order of //expressions containing these operators.  Operators associate with either the //expression on their left or the expression on their right;    this is called //“associativity.” Operators in the same group have equal precedence and are //evaluated left to right in an expression unless explicitly forced by a pair of //parentheses, ( ). //  Table 1.1 shows the precedence and associativity of C++ operators //  (from highest to lowest precedence). // //Table 1.1   C++ Operator Precedence and Associativity // The highest precedence level is at the top of the table. //+------------------+-----------------------------------------+---------------+ //| Operator         | Name or Meaning                         | Associativity | //+------------------+-----------------------------------------+---------------+ //| ::               | Scope resolution                        | None          | //| ::               | Global                                  | None          | //| [ ]              | Array subscript                         | Left to right | //| ( )              | Function call                           | Left to right | //| ( )              | Conversion                              | None          | //| .                | Member selection (object)               | Left to right | //| ->               | Member selection (pointer)              | Left to right | //| ++               | Postfix increment                       | None          | //| --               | Postfix decrement                       | None          | //| new              | Allocate object                         | None          | //| delete           | Deallocate object                       | None          | //| delete[ ]        | Deallocate object                       | None          | //| ++               | Prefix increment                        | None          | //| --               | Prefix decrement                        | None          | //| *                | Dereference                             | None          | //| &                | Address-of                              | None          | //| +                | Unary plus                              | None          | //| -                | Arithmetic negation (unary)             | None          | //| !                | Logical NOT                             | None          | //| ~                | Bitwise complement                      | None          | //| sizeof           | Size of object                          | None          | //| sizeof ( )       | Size of type                            | None          | //| typeid( )        | type name                               | None          | //| (type)           | Type cast (conversion)                  | Right to left | //| const_cast       | Type cast (conversion)                  | None          | //| dynamic_cast     | Type cast (conversion)                  | None          | //| reinterpret_cast | Type cast (conversion)                  | None          | //| static_cast      | Type cast (conversion)                  | None          | //| .*               | Apply pointer to class member (objects) | Left to right | //| ->*              | Dereference pointer to class member     | Left to right | //| *                | Multiplication                          | Left to right | //| /                | Division                                | Left to right | //| %                | Remainder (modulus)                     | Left to right | //| +                | Addition                                | Left to right | //| -                | Subtraction                             | Left to right | //| <<               | Left shift                              | Left to right | //| >>               | Right shift                             | Left to right | //| <                | Less than                               | Left to right | //| >                | Greater than                            | Left to right | //| <=               | Less than or equal to                   | Left to right | //| >=               | Greater than or equal to                | Left to right | //| ==               | Equality                                | Left to right | //| !=               | Inequality                              | Left to right | //| &                | Bitwise AND                             | Left to right | //| ^                | Bitwise exclusive OR                    | Left to right | //| |                | Bitwise OR                              | Left to right | //| &&               | Logical AND                             | Left to right | //| ||               | Logical OR                              | Left to right | //| e1?e2:e3         | Conditional                             | Right to left | //| =                | Assignment                              | Right to left | //| *=               | Multiplication assignment               | Right to left | //| /=               | Division assignment                     | Right to left | //| %=               | Modulus assignment                      | Right to left | //| +=               | Addition assignment                     | Right to left | //| -=               | Subtraction assignment                  | Right to left | //| <<=              | Left-shift assignment                   | Right to left | //| >>=              | Right-shift assignment                  | Right to left | //| &=               | Bitwise AND assignment                  | Right to left | //| |=               | Bitwise inclusive OR assignment         | Right to left | //| ^=               | Bitwise exclusive OR assignment         | Right to left | //| ,                | Comma                                   | Left to right | //+------------------+-----------------------------------------+---------------+

Addition (+) The addition operator (+) causes its two operands to be added. Both operands can be either integral or floating types, or one operand can be a pointer and the other an integer.    When an integer is added to a pointer, the integer value (i) is converted by multiplying it by the size of the value that the pointer addresses. After conversion, the integer value represents i memory positions, where each position has the length specified by the pointer type. When the converted integer value is added to the pointer value, the result is a new pointer value representing the address i positions from the original address. The new pointer value addresses a value of the same type as the original pointer value and therefore is the same as array indexing (see One-Dimensional Arrays and Multidimensional Arrays). If the sum pointer points outside the array, except at the first location beyond the high end, the result is undefined. For more information, see Pointer Arithmetic.   Subtraction (–) The subtraction operator (–) subtracts the second operand from the first. Both operands can be either integral or floating types, or one operand can be a pointer and the other an integer.    When two pointers are subtracted, the difference is converted to a signed integral value by dividing the difference by the size of a value of the type that the pointers address. The size of the integral value is defined by the type ptrdiff_t in the standard include file STDDEF.H. The result represents the number of memory positions of that type between the two addresses. The result is only guaranteed to be meaningful for two elements of the same array, as discussed in Pointer Arithmetic.   When an integer value is subtracted from a pointer value, the subtraction operator converts the integer value (i) by multiplying it by the size of the value that the pointer addresses. After conversion, the integer value represents i memory positions, where each position has the length specified by the pointer type. When the converted integer value is subtracted from the pointer value, the result is the memory address i positions before the original address. The new pointer points to a value of the type addressed by the original pointer value.  Pointer Arithmetic Additive operations involving a pointer and an integer give meaningful results only if the pointer operand addresses an array member and the integer value produces an offset within the bounds of the same array. When the integer value is converted to an address offset, the compiler assumes that only memory positions of the same size lie between the original address and the address plus the offset.  This assumption is valid for array members. By definition, an array is a series of values of the same type; its elements reside in contiguous memory locations. However, storage for any types except array elements is not guaranteed to be filled by the same type of identifiers. That is, blanks can appear between memory positions, even positions of the same type. Therefore, the results of adding to or subtracting from the addresses of any values but array elements are undefined.  Similarly, when two pointer values are subtracted, the conversion assumes that only values of the same type, with no blanks, lie between the addresses given by the operands.

引用 7 楼 u013106556 的回复:[quote=引用 6 楼 czarten 的回复:] [quote=引用 5 楼 u013106556 的回复:] [quote=引用 2 楼 czarten 的回复:] 关于*p，首先我这边试了一下结果是6，其次输出指针不应该用%d 我这边运行最后*p的值不是6；其次，不用%d??  说下原因吧！！！[/quote]  确实应该是随机值，因为你的p前面一直指向a，而在最后一句p++使得p指向了a后面的一格内存，而这格内存上没有你的变量，因此结果不定  不用%d是说你前面的p和&a，应该用%p输出[/quote]谢谢 你怎么了熊吉！！  还是不清楚这个随机值是怎么随机的。。。[/quote]  此处的“随机”不是说你每次运行会得到一个不同的值，而是说结果无法预料，可能取决于编译器和运行环境等。 比如我这边，输出*p是6，这意味着我的编译器把b变量放在紧接着a的后面，所以原先指向a指针++之后刚好指向了b，但这并不是C语言规定的，换个编译器可能就不这么放了

引用 6 楼 czarten 的回复:[quote=引用 5 楼 u013106556 的回复:] [quote=引用 2 楼 czarten 的回复:] 关于*p，首先我这边试了一下结果是6，其次输出指针不应该用%d 我这边运行最后*p的值不是6；其次，不用%d??  说下原因吧！！！[/quote]  确实应该是随机值，因为你的p前面一直指向a，而在最后一句p++使得p指向了a后面的一格内存，而这格内存上没有你的变量，因此结果不定  不用%d是说你前面的p和&a，应该用%p输出[/quote]谢谢 你怎么了熊吉！！  还是不清楚这个随机值是怎么随机的。。。

引用 5 楼 u013106556 的回复:[quote=引用 2 楼 czarten 的回复:] 关于*p，首先我这边试了一下结果是6，其次输出指针不应该用%d 我这边运行最后*p的值不是6；其次，不用%d??  说下原因吧！！！[/quote]  确实应该是随机值，因为你的p前面一直指向a，而在最后一句p++使得p指向了a后面的一格内存，而这格内存上没有你的变量，因此结果不定  不用%d是说你前面的p和&a，应该用%p输出

引用 2 楼 czarten 的回复:关于*p，首先我这边试了一下结果是6，其次输出指针不应该用%d 我这边运行最后*p的值不是6；其次，不用%d??  说下原因吧！！！

引用 3 楼 happyperson 的回复:p是int型的指针，p++是按照sizeof(int)加的，最后*p是取的随机值 *p的值为随机值，意思是每次运行都不相同？但是每次运行后其值是相同的，都是1638212。。不知道你这个随机是如何理解的。。。


Question: 新人求教~~~

先下载Win-TC，然后参考C:\Win-TC\tcstudy.chm

《C Prime Plus》就看这一本书就够了

先随便找本C语言的书入个门，看到指针前面的部分就可以了，要看完数组。然后开始啃英文版的《The C programming language》就可以达到真正的入门级别了。然后就是看很多的书，编写大量的程序。

引用 1 楼 turingo 的回复:参考http://blog.csdn.net/turingo/article/details/8115042  引用 楼主 u013925826 的回复:本人想自学C语言 之前几乎完全没接触过，想去买点书或者下载电子本 视频教学之类的，请给小弟点推荐适合初学者入门的 万分感谢     +1  《C Prime Plus》把里面的例子多抄写,理解这本书的80%多...基本可以入门了

坚持，多敲代码！  找一个好点的入门教材

《C Prime Plus》 +1

入门推荐《c语言入门经典》，初学看《C plus primer plus》感觉难看懂

郝斌C语言视频，适合入门，推荐——http://www.xuexi111.com/jiaocheng/shipin/26243.html

范磊的C语言视频教程——《零起点学通C语言》 希望可以帮到你

C语言教程, 清华大学谭浩强版


Question: 函数和函数指针和指针：int f(); int* pf=f;和int (*f2)();的问题。

函数指针也是有类型的

//C++ Operators //  Operators specify an evaluation to be performed on one of the following: //    One operand (unary operator) //    Two operands (binary operator) //    Three operands (ternary operator) //  The C++ language includes all C operators and adds several new operators. //  Table 1.1 lists the operators available in Microsoft C++. //  Operators follow a strict precedence which defines the evaluation order of //expressions containing these operators.  Operators associate with either the //expression on their left or the expression on their right;    this is called //“associativity.” Operators in the same group have equal precedence and are //evaluated left to right in an expression unless explicitly forced by a pair of //parentheses, ( ). //  Table 1.1 shows the precedence and associativity of C++ operators //  (from highest to lowest precedence). // //Table 1.1   C++ Operator Precedence and Associativity // The highest precedence level is at the top of the table. //+------------------+-----------------------------------------+---------------+ //| Operator         | Name or Meaning                         | Associativity | //+------------------+-----------------------------------------+---------------+ //| ::               | Scope resolution                        | None          | //| ::               | Global                                  | None          | //| [ ]              | Array subscript                         | Left to right | //| ( )              | Function call                           | Left to right | //| ( )              | Conversion                              | None          | //| .                | Member selection (object)               | Left to right | //| ->               | Member selection (pointer)              | Left to right | //| ++               | Postfix increment                       | None          | //| --               | Postfix decrement                       | None          | //| new              | Allocate object                         | None          | //| delete           | Deallocate object                       | None          | //| delete[ ]        | Deallocate object                       | None          | //| ++               | Prefix increment                        | None          | //| --               | Prefix decrement                        | None          | //| *                | Dereference                             | None          | //| &                | Address-of                              | None          | //| +                | Unary plus                              | None          | //| -                | Arithmetic negation (unary)             | None          | //| !                | Logical NOT                             | None          | //| ~                | Bitwise complement                      | None          | //| sizeof           | Size of object                          | None          | //| sizeof ( )       | Size of type                            | None          | //| typeid( )        | type name                               | None          | //| (type)           | Type cast (conversion)                  | Right to left | //| const_cast       | Type cast (conversion)                  | None          | //| dynamic_cast     | Type cast (conversion)                  | None          | //| reinterpret_cast | Type cast (conversion)                  | None          | //| static_cast      | Type cast (conversion)                  | None          | //| .*               | Apply pointer to class member (objects) | Left to right | //| ->*              | Dereference pointer to class member     | Left to right | //| *                | Multiplication                          | Left to right | //| /                | Division                                | Left to right | //| %                | Remainder (modulus)                     | Left to right | //| +                | Addition                                | Left to right | //| -                | Subtraction                             | Left to right | //| <<               | Left shift                              | Left to right | //| >>               | Right shift                             | Left to right | //| <                | Less than                               | Left to right | //| >                | Greater than                            | Left to right | //| <=               | Less than or equal to                   | Left to right | //| >=               | Greater than or equal to                | Left to right | //| ==               | Equality                                | Left to right | //| !=               | Inequality                              | Left to right | //| &                | Bitwise AND                             | Left to right | //| ^                | Bitwise exclusive OR                    | Left to right | //| |                | Bitwise OR                              | Left to right | //| &&               | Logical AND                             | Left to right | //| ||               | Logical OR                              | Left to right | //| e1?e2:e3         | Conditional                             | Right to left | //| =                | Assignment                              | Right to left | //| *=               | Multiplication assignment               | Right to left | //| /=               | Division assignment                     | Right to left | //| %=               | Modulus assignment                      | Right to left | //| +=               | Addition assignment                     | Right to left | //| -=               | Subtraction assignment                  | Right to left | //| <<=              | Left-shift assignment                   | Right to left | //| >>=              | Right-shift assignment                  | Right to left | //| &=               | Bitwise AND assignment                  | Right to left | //| |=               | Bitwise inclusive OR assignment         | Right to left | //| ^=               | Bitwise exclusive OR assignment         | Right to left | //| ,                | Comma                                   | Left to right | //+------------------+-----------------------------------------+---------------+  //char (*(*x[3])())[5];//x是什么类型的变量? // //分析C语言声明，关键是搞清楚这个变量是个什么东西（函数、指针、数组）， //是函数那么剩下的就是他的参数和返回值， //是指针那剩下部分是说明他指向什么， //是数组剩下的部分就是说明数组的成员是什么类型。 //解析C语言声明规则： //从左侧第一个标识符开始，按照优先级进行结合。*表示是..的指针，const表示只读的，volatile表示可变的，[]表示是数组，()表示是函数。 // //x和[3]结合说明是一个大小为3的数组，该数组指向了一个指针，该指针指向一个函数，该函数的无参数，返回一个指针，该指针指向一个大小为5的char型数组 #include <stdio.h> #include <typeinfo.h> char num[5]; char (*x00())[5] {     return # } int main() {     char (*x000)[5];//返回值     char (*(x00)())[5];//函数原型，参数为空，返回值为指针     char (*(*x0)())[5];//数组的元素，是个函数指针     char (*(*x[3])())[5];//是个数组，大小为3      x0 = x00;     x[0] = x0;     x[1] = x0;     x[2] = x0;     printf("typeid(x).name() is %s\n",typeid(x).name());     return 0; } //typeid(x).name() is char (* (__cdecl**)(void))[5]

1.int (*f2)(void)既然NS   f2是一个指向没有参数，返回值类型为int的函数的指针，不是一个函数。  2.int* pf=f   pf是一个指向int的指针，f是int (__cdecl *)(void )，也就是一个指向没有参数，返回值类型为int的函数的指针，两个类型不同，所以会有警告。  3.int (*pf)(void) = f; 因为括号的优先级要高于*，所以*pf要加括号，表示pf是一个指针。

不能沉啊，求大神指点啊。指点啊。

自己顶起。


Question: 怎样在c语言链表中插入字符串？请看代码

引用 5 楼 starytx 的回复:c语言中不可以直接对数组进行=(赋值)，字符数组也不例外  明白了，谢谢哈

引用 4 楼 zczyde 的回复:[quote=引用 3 楼 starytx 的回复:] strcpy(s->name ,name);就可以了  谢谢你啊，真的可以，赞一个。 就是不知道为什么strcpy可以呢，为什么给字符数组赋值一定要用strcpy(s->name ,name)呢 [/quote]  多看看基础知识，会有很大帮助的呦

c语言中不可以直接对数组进行=(赋值)，字符数组也不例外

引用 3 楼 starytx 的回复:strcpy(s->name ,name);就可以了  谢谢你啊，真的可以，赞一个。 就是不知道为什么strcpy可以呢，为什么给字符数组赋值一定要用strcpy(s->name ,name)呢

strcpy(s->name ,name);就可以了

引用 1 楼 truelance 的回复:void InsertElem(LinkList *list,char *name,float y) 或者 void InsertElem(LinkList *list,char name[],float y) 都可以, 两者是一样的  谢谢你的回复。如果形参改成char *name或者char name[]时，在函数体里面，是怎么赋值的呢 我试了s->name=name;和s->name=name;都会报错的，提示“表达式必须是可修改的左值”    void InsertElem(LinkList *list,int i,char name[], float y)//在第i个元素之前插入y { 	int j; 	LinkList p,s; 	p=*list;//让p指向第一个结点 	j=1; 	while(p&&j<i) 	{ 		p=p->next; 		++j; 	} 	s=(LinkList)malloc(sizeof(struct student)); 	s->score=y; 	s->name=name;//就是这句报错。。。。。。。。。。。。。。。。。。。。。 	s->next=p->next; 	p->next=s;//插入在p结点之后 }


Question: C语言中自增符++优先级及内存中运行方式？先自增还是先计算再自增？

引用 楼主 u010450836 的回复:近在讨论一个问题，引出来这个。 比如 i = j + k++;这里边的k++的运行顺序是什么？经常说这一种是先求和再自增，但是++的优先级明明高于+，不是先算k++吗？所以有人提出k++和++k优先级是不一样的。但是++作为运算符，优先级应该不会因为放在那里就改变。所以，简单编译了一下，在汇编中貌似还是先算k++，但是把k,和k++都放在寄存器中，用的时候先用了k。（不知道理解对不对）。这样来说，还是先自增，再计算，不过没用自增的值而已。 总结一下： 1.k++和++k中优先级，有没有区别？ 2.在内存计算时候，先自增还是先计算再自增？ 把谭大爷的书扔掉，再去看顶置贴

最好不会产生歧义的编程方式,尽量不依赖默认的优先级 不知道楼主要实现什么目的 如果是加2,就k+=2;

先算 k++ 但是 k++ 算的结果是k啊 k的值是k+1  但那是k的值  别混淆了   表达式的值 和 操作数的值

引用 5 楼 a345485527 的回复:这个不是置顶帖的内容么  这个跟置顶两回事 这个式子的结果有明确定义

这个不是置顶帖的内容么

i = j + k++  假设k=3，j=2 ++优先级最高，首先计算k++，此时k=4，但（k++）这个表达式的返回值是3，所以第二步是计算j+3，这个表达式不改变j的值，仍为2，但返回值是5，第三步计算i=5，这个表达式改变i的值，i变为5，而表达式的返回值是i的引用  一句话，就是分清楚运算符的参数和运算符的返回值的区别  如果把k++写成一个函数，你就不会有此困惑  int jiajia(int& k) {     k++;     return 原来的k; }  i = j + jiajia(k)

不好意思，++k和k++的优先级是不同的 k++的优先级更高

参考http://bbs.csdn.net/topics/370153775  引用 楼主 u010450836 的回复:近在讨论一个问题，引出来这个。 比如 i = j + k++;这里边的k++的运行顺序是什么？经常说这一种是先求和再自增，但是++的优先级明明高于+，不是先算k++吗？所以有人提出k++和++k优先级是不一样的。但是++作为运算符，优先级应该不会因为放在那里就改变。所以，简单编译了一下，在汇编中貌似还是先算k++，但是把k,和k++都放在寄存器中，用的时候先用了k。（不知道理解对不对）。这样来说，还是先自增，再计算，不过没用自增的值而已。 总结一下： 1.k++和++k中优先级，有没有区别？ 2.在内存计算时候，先自增还是先计算再自增？

1. 优先级是相同的 2. 这个计算的过程，编译器可以自己定，就是说这样写，得出来的结果是依赖于编译器的


Question: 函数指针的疑问

引用 4 楼 njdyne 的回复:在程序中定义了一个函数，在编译时，会为函数代码分配一段存储空间，就有了地址。可以定义一个指向函数的指针变量来存储这个地址。 C语言中，表达式中的函数可以被解读成指向函数的指针。  这是我想要的.

[quote=引用 3 楼 turingo 的回复:] 可以的，直接强制类型转换就好了。  之前就没理解不强转类型，怎么可以，现在知道了.

引用 1 楼 a345485527 的回复:对于函数来说 加不加取地址 & 都是一样的 你也可以加上&  是这样啊，知道了.

指针类型可以任意转换。操作的正确性只能在程序员层面进行保证。

对于函数来说 加不加取地址 & 都是一样的 你也可以加上&

可以的，直接强制类型转换就好了。  引用 楼主 u013431701 的回复:1.typedef unsigned int (*callback)(STATUS_E Status); 2.int32 status_cbk(STATUS_E status) { ； }  3.callback  status = status_cbk; 4.SetStatusCallback(status );  想问一下能把一个函数指针status指向一个返回值是int32的函数status_cbk， 这样可以吗？  指针不应该是指向一个地址吗？


Question: 有一个c实现的所有文件，不知道怎么编译运行

去linux下执行以下make就行了

我编译了一下好像有错误

在windows下面？ mingw32-make

不要沉......求解释

make是linux下的命令, 在windows下你得装一个编译器

引用 2 楼 derekrose 的回复:在windows下面？ mingw32-make 斑竹能加下你qq吗，我qq675722402

引用 3 楼 derekrose 的回复:我编译了一下好像有错误 斑竹，还有一个java版的 http://sourceforge.net/projects/ntru/files/NTRU%201.2/


Question: 请大家帮忙分析一下这代码错误提示的原因

引用 4 楼 xihu1364 的回复:[quote=引用 3 楼 cyycxz 的回复:] [quote=引用 1 楼 vrace 的回复:] LRESULT 打错了 WinMain 打错了 WM_ 很多打错了 还有很多东西注意大小写  打字的时候注意点……你让我出大丑了。。。[/quote][/quote]

引用 楼主 cyycxz 的回复:以下是摘自《windows程序设计》的代码（精简）： #include<windows.h> LRESUALT CALLBACK wndproc(HWND,UNIT,WPARAM,LPARAM);  int WINAPI winmain(HINSTANCE hinstance,HINSTANCE hprevinstance,PSTR szcmdline,int icmdshow)    {     static TCHAR szappname[]=TEXT("hello");       HWND hwnd;       MSG msg;       WNDCLASS wndclass;     wndclass.style=CS_HREDRAW|CS_VREDRAW;    wndclass.lpfnwndclass=wndproc;    wndclass.cbclsextra=0;    wndclass.cbwndextra=0;    wndclass.hinstance=hinstance;    wndclass.hicon=loadicon(NULL,IDI_APPLICATION);    wndclass.hcursor=loadcursor(NULL,IDC_ARROW);    wndclass.hbrbackground=(HBRUSH) getstockobject(WHITE_BRUSH);    wndclass.lpszmenuname=NULL;    wndclass.lpszclassname=szappname;  if(!registerclass(&wndclass))  { messagebox(NULL,TEXT("WO CAO"),szappname,MB_ICONERROR);    return 0;}  hwnd=createwindow(szappname,TEXT("the hello program"),WS_OVERLAPPEDWINDOW,CW_USEDFAULT,CW_USEDFAULT,CW_USEDFAULT,CW_USEDFAULT,NULL,NULL,hinstance,NULL);  showwindow(hwnd,icmdshow); updatewindow(hwnd);  while(getmessage(&msg,NULL,0,0))   {translatemessage(&msg);    dispatchmessage(&msg);}  return msg.wapram;}  LRESAULT CALLBACK wndproc(HWND hwnd,UINT message,WPARAM wparam,LPARAM lparam)    {HDC hdc;    PAINTSTRUCT ps;    RECT rect;   switch(message)   {case MWM_PAINT:hdc=beginpaint(hwnd,&ps);gecclientrect(hwnd,&rect); drawtext(hdc,TEXT("hello,windows 98"),-1,&rect,DT_SINGLELINE|DT_CENTER|DT_VCENTER);return 0;    case MWM_DESTROY:postquitmessage(0);return 0;} return defwindowproc(hwnd,message,wparam,lparam);}  以下是错误提示： d:\vc++ 6.0projects\fsb.c(2) : error C2143: syntax error : missing '{' before '__stdcall' d:\vc++ 6.0projects\fsb.c(2) : error C2081: 'UNIT' : name in formal parameter list illegal d:\vc++ 6.0projects\fsb.c(2) : error C2081: 'WPARAM' : name in formal parameter list illegal d:\vc++ 6.0projects\fsb.c(2) : error C2081: 'LPARAM' : name in formal parameter list illegal d:\vc++ 6.0projects\fsb.c(12) : error C2039: 'lpfnwndclass' : is not a member of 'tagWNDCLASSA'         d:\vc++6.0\microsoft visual studio\vc98\include\winuser.h(1184) : see declaration of 'tagWNDCLASSA' d:\vc++ 6.0projects\fsb.c(13) : error C2039: 'cbclsextra' : is not a member of 'tagWNDCLASSA'         d:\vc++6.0\microsoft visual studio\vc98\include\winuser.h(1184) : see declaration of 'tagWNDCLASSA' d:\vc++ 6.0projects\fsb.c(14) : error C2039: 'cbwndextra' : is not a member of 'tagWNDCLASSA'         d:\vc++6.0\microsoft visual studio\vc98\include\winuser.h(1184) : see declaration of 'tagWNDCLASSA' d:\vc++ 6.0projects\fsb.c(15) : error C2039: 'hinstance' : is not a member of 'tagWNDCLASSA'         d:\vc++6.0\microsoft visual studio\vc98\include\winuser.h(1184) : see declaration of 'tagWNDCLASSA' d:\vc++ 6.0projects\fsb.c(16) : error C2039: 'hicon' : is not a member of 'tagWNDCLASSA'         d:\vc++6.0\microsoft visual studio\vc98\include\winuser.h(1184) : see declaration of 'tagWNDCLASSA' d:\vc++ 6.0projects\fsb.c(16) : warning C4013: 'loadicon' undefined; assuming extern returning int d:\vc++ 6.0projects\fsb.c(17) : error C2039: 'hcursor' : is not a member of 'tagWNDCLASSA'         d:\vc++6.0\microsoft visual studio\vc98\include\winuser.h(1184) : see declaration of 'tagWNDCLASSA' d:\vc++ 6.0projects\fsb.c(17) : warning C4013: 'loadcursor' undefined; assuming extern returning int d:\vc++ 6.0projects\fsb.c(18) : error C2039: 'hbrbackground' : is not a member of 'tagWNDCLASSA'         d:\vc++6.0\microsoft visual studio\vc98\include\winuser.h(1184) : see declaration of 'tagWNDCLASSA' d:\vc++ 6.0projects\fsb.c(18) : warning C4013: 'getstockobject' undefined; assuming extern returning int d:\vc++ 6.0projects\fsb.c(19) : error C2039: 'lpszmenuname' : is not a member of 'tagWNDCLASSA'         d:\vc++6.0\microsoft visual studio\vc98\include\winuser.h(1184) : see declaration of 'tagWNDCLASSA' d:\vc++ 6.0projects\fsb.c(20) : error C2039: 'lpszclassname' : is not a member of 'tagWNDCLASSA'         d:\vc++6.0\microsoft visual studio\vc98\include\winuser.h(1184) : see declaration of 'tagWNDCLASSA' d:\vc++ 6.0projects\fsb.c(22) : warning C4013: 'registerclass' undefined; assuming extern returning int d:\vc++ 6.0projects\fsb.c(23) : warning C4013: 'messagebox' undefined; assuming extern returning int d:\vc++ 6.0projects\fsb.c(26) : warning C4013: 'createwindow' undefined; assuming extern returning int d:\vc++ 6.0projects\fsb.c(26) : error C2065: 'CW_USEDFAULT' : undeclared identifier d:\vc++ 6.0projects\fsb.c(26) : warning C4047: '=' : 'struct HWND__ *' differs in levels of indirection from 'int ' d:\vc++ 6.0projects\fsb.c(28) : warning C4013: 'showwindow' undefined; assuming extern returning int d:\vc++ 6.0projects\fsb.c(29) : warning C4013: 'updatewindow' undefined; assuming extern returning int d:\vc++ 6.0projects\fsb.c(31) : warning C4013: 'getmessage' undefined; assuming extern returning int d:\vc++ 6.0projects\fsb.c(32) : warning C4013: 'translatemessage' undefined; assuming extern returning int d:\vc++ 6.0projects\fsb.c(33) : warning C4013: 'dispatchmessage' undefined; assuming extern returning int d:\vc++ 6.0projects\fsb.c(34) : error C2039: 'wapram' : is not a member of 'tagMSG'         d:\vc++6.0\microsoft visual studio\vc98\include\winuser.h(1226) : see declaration of 'tagMSG' d:\vc++ 6.0projects\fsb.c(34) : warning C4033: 'winmain' must return a value d:\vc++ 6.0projects\fsb.c(36) : error C2143: syntax error : missing '{' before '__stdcall' d:\vc++ 6.0projects\fsb.c(38) : warning C4028: formal parameter 2 different from declaration d:\vc++ 6.0projects\fsb.c(38) : warning C4028: formal parameter 3 different from declaration d:\vc++ 6.0projects\fsb.c(38) : warning C4028: formal parameter 4 different from declaration d:\vc++ 6.0projects\fsb.c(43) : error C2065: 'MWM_PAINT' : undeclared identifier d:\vc++ 6.0projects\fsb.c(43) : error C2051: case expression not constant d:\vc++ 6.0projects\fsb.c(43) : warning C4013: 'beginpaint' undefined; assuming extern returning int d:\vc++ 6.0projects\fsb.c(43) : warning C4047: '=' : 'struct HDC__ *' differs in levels of indirection from 'int ' d:\vc++ 6.0projects\fsb.c(43) : warning C4013: 'gecclientrect' undefined; assuming extern returning int d:\vc++ 6.0projects\fsb.c(43) : warning C4013: 'drawtext' undefined; assuming extern returning int d:\vc++ 6.0projects\fsb.c(44) : error C2065: 'MWM_DESTROY' : undeclared identifier d:\vc++ 6.0projects\fsb.c(44) : error C2051: case expression not constant d:\vc++ 6.0projects\fsb.c(44) : warning C4013: 'postquitmessage' undefined; assuming extern returning int d:\vc++ 6.0projects\fsb.c(45) : warning C4013: 'defwindowproc' undefined; assuming extern returning int 执行 cl.exe 时出错.  fsb.obj - 1 error(s), 0 warning(s)  以上代码运行环境是VC++ 6.0，请高手分析一下是什么原因  参考某赵的打字训练

引用 3 楼 cyycxz 的回复:[quote=引用 1 楼 vrace 的回复:] LRESULT 打错了 WinMain 打错了 WM_ 很多打错了 还有很多东西注意大小写  打字的时候注意点……你让我出大丑了。。。[/quote]

引用 1 楼 vrace 的回复:LRESULT 打错了 WinMain 打错了 WM_ 很多打错了 还有很多东西注意大小写  打字的时候注意点……你让我出大丑了。。。

同意#1 ，主要是抄写错误（键盘输入错误），多练习练习就好。


Question: 关于malloc的问题，坐等

晕，打印出了，p所指的地址确实改变了。晕死

调用malloch后，p指向内存块A; 运行p = "hello";后，p指向字符串"hello"的存储空间。 之后free(p)就是试图释放字符串"hello"的存储空间。 呵呵，这样子是不允许的，free只能释放堆空间。

机智的楼主，你答对了

“难道”是对的

你自己分析的是对的


Question: 往控制台上打印 数组内容 请教

引用 1 楼 zjq9931 的回复: //PerIoData->Buffer[BytesTransferred]='\0'; //printf("%s \n",PerIoData->Buffer); int ix; for(ix=0; ix<strlen(pc); ix++) { 	printf("%x ", (unsigned char)PerIoData->Buffer[ix]); }     我的意思，能不能像字符串数组那样，，直接打印出16进制的数组内容  比如像： printf("%s \n",PerIoData->Buffer); 就把数组内的字符都打印出来了  如果数组里是 16进制的内容   printf("？？？",PerIoData->Buffer);   只在“？？？” 里约束格式，能不把数组里的16进制内容，以16进制字符串打印出来...

每个字符printf("%x")是最简单的方法

引用 2 楼 wanyeye 的回复:[quote=引用 1 楼 zjq9931 的回复:]  //PerIoData->Buffer[BytesTransferred]='\0'; //printf("%s \n",PerIoData->Buffer); int ix; for(ix=0; ix<strlen(pc); ix++) { 	printf("%x ", (unsigned char)PerIoData->Buffer[ix]); }     我的意思，能不能像字符串数组那样，，直接打印出16进制的数组内容  比如像： printf("%s \n",PerIoData->Buffer); 就把数组内的字符都打印出来了  如果数组里是 16进制的内容   printf("？？？",PerIoData->Buffer);   只在“？？？” 里约束格式，能不把数组里的16进制内容，以16进制字符串打印出来...  [/quote] 你说的16进制字符是什么？


Question: 求教一道C语言题目 急！

谢谢各位高手的鼎力支持 我还需要继续努力消化 谢谢~

大师 还有一事我在想 如果下面5个周六 要排到2015了 我要阻止2015年中6月份的出现 这个代码怎么加

void main() {     int year,day,fsn;     cout<<"Enter the year number:";     cin>>year;     while(year<1970)     {         cout<<"please enter ther year number(>1970):";         cin>>year;     }     cout<<"Enter the day number (1 - 365):";     cin>>day;     while(day>366||day<1)     {         cout<<"please enter the day number (1 - 365):";         cin>>day;     }     cout<<"Enter desired number of future Saturdays:";     cin>>fsn;     while(fsn>12||fsn<1)     {         cout<<"please enter desired number of future Saturdays(1-12):";         cin>>fsn;     }       time a;     a.year=year;     a.monthday=day;     a.month=1;     a.weekday=0;     a=newtime(a);     cout<<"Input date:"<<a.year<<"年"<<a.month<<"月"         <<a.monthday<<"日"<<" "<<"星期"<<a.weekday<<endl;       for (int i=1;i<=monthtotalday(year,fsn);++i)     {         time b;         b.year=year;         b.month=fsn;         b.monthday=i;         b.weekday=0;         b=newtime(b);         if (6==b.weekday)         {             cout<<"Next Saturday:"<<b.year<<"年"<<b.month<<"月"                 <<b.monthday<<"日"<<" "<<"星期"<<b.weekday<<endl;         }     }     system("pause"); } 大师 这段我没怎么想明白啊 求解惑

讲的好透彻了，谢谢分享

145行改为dayNum += (3 - weekDay);

#include <stdio.h> #include "test.h"  const char daysOfEachMonth[12] = { 	31,		/* 1 */ 	28,		/* 2, not leap year */ 	31,		/* 3 */ 	30,		/* 4 */ 	31,		/* 5 */ 	30,		/* 6 */ 	31,		/* 7 */ 	31,		/* 8 */ 	30,		/* 9 */ 	31,		/* 10 */ 	30,		/* 11 */ 	31		/* 12 */ };  const char *monthName[] = { 	"January",		/* 1 */ 	"February",		/* 2 */ 	"March",		/* 3 */ 	"April",		/* 4 */ 	"May",			/* 5 */ 	"June",			/* 6 */ 	"July",			/* 7 */ 	"August",		/* 8 */ 	"September",	/* 9 */ 	"October",		/* 10 */ 	"November",		/* 11 */ 	"December"		/* 12 */ };  const char *weekName[] = { 	"Thursday",		/* 4, 1.1.1970 */ 	"Friday",		/* 5 */ 	"Saturday",		/* 6 */ 	"Sunday",		/* 7 */ 	"Monday",		/* 1 */ 	"Tuesday",		/* 2 */ 	"Wednesday",	/* 3 */ };   int isYearLeap(unsigned int year) { 	if(year%400 == 0 || (year%100 != 0 && year%4 == 0)) 		return 1; 	else 		return 0; }  unsigned int totalDays(unsigned int year, unsigned int month) { 	unsigned int i, days;   	days = isYearLeap(year);  	if(month == 1) 		return 31; 	else{ 		for(i = 0; i < month; i++)  			days += daysOfEachMonth[i];  	} 								 	return days; 	 }  unsigned int weekday(unsigned int year, unsigned int dayNum) { 	unsigned int i, days = 0;  	unsigned int remainder; 	 	for(i = 1970; i < year; i++) 		days += (isYearLeap(i) ? 366 : 365);  	days += dayNum; 	remainder = days % 7; 								 	return remainder; 	 }  unsigned int days2month(unsigned int yearNum, unsigned int dayNum) { 	unsigned int month;  	if(0 < dayNum && dayNum <= totalDays(yearNum, 1)) 		month = 1; 	else if(totalDays(yearNum, 1) < dayNum && dayNum <= totalDays(yearNum, 2)) 		month = 2; 	else if(totalDays(yearNum, 2) < dayNum && dayNum <= totalDays(yearNum, 3)) 		month = 3; 	else if(totalDays(yearNum, 3) < dayNum && dayNum <= totalDays(yearNum, 4)) 		month = 4; 	else if(totalDays(yearNum, 4) < dayNum && dayNum <= totalDays(yearNum, 5)) 		month = 5; 	else if(totalDays(yearNum, 5) < dayNum && dayNum <= totalDays(yearNum, 6)) 		month = 6; 	else if(totalDays(yearNum, 6) < dayNum && dayNum <= totalDays(yearNum, 7)) 		month = 7; 	else if(totalDays(yearNum, 7) < dayNum && dayNum <= totalDays(yearNum, 8)) 		month = 8; 	else if(totalDays(yearNum, 8) < dayNum && dayNum <= totalDays(yearNum, 9)) 		month = 9; 	else if(totalDays(yearNum, 9) < dayNum && dayNum <= totalDays(yearNum, 10)) 		month = 10; 	else if(totalDays(yearNum, 10) < dayNum && dayNum <= totalDays(yearNum, 11)) 		month = 11; 	else if(totalDays(yearNum, 11) < dayNum && dayNum <= totalDays(yearNum, 12)) 		month = 12; 	else{ 		printf("Enter the ERROR day number!!!\r\n"); 		return 0; 	}  	return month; }   void days2date(unsigned int yearNum, unsigned int dayNum) { 	unsigned int month; 	unsigned int day; 	unsigned int weekDay;  	month = days2month(yearNum, dayNum); 	if(month == 0) 		return;  	day = dayNum - totalDays(yearNum, month-1); 	weekDay = weekday(yearNum, dayNum);  	printf("Input date: %s %s %d %d\r\n", weekName[weekDay-1], monthName[month-1], day, yearNum); }  void getDesiredFutureDay(unsigned int yearNum, unsigned int dayNum,  int desiredNum) { 	unsigned int weekDay; 	unsigned int month, day; 	int i;  	weekDay = weekday(yearNum, dayNum);  	if(weekDay <= 3) 		dayNum += (weekDay - 3); 	else 		dayNum += (10 - weekDay);  	for(i = 0; i < desiredNum; i++){ 		if(dayNum > (365+isYearLeap(yearNum))){ 			yearNum++; 			dayNum -= (365+isYearLeap(yearNum)); 		} 		month = days2month(yearNum, dayNum); 		if(month == 0) 			return; 		day = dayNum - totalDays(yearNum, month-1); 		printf("Next Saturday: %s %d %d\r\n", monthName[month-1], day, yearNum); 		dayNum += 7; 	}  }   int main(int argc, char** argv) { 	int yearNum; 	int dayNum; 	int desiredNum;  	printf("Enter the year number: "); 	scanf("%d", &yearNum);  	printf("Enter the day number (1-365): "); 	scanf("%d", &dayNum);  	printf("Enter desired number of future Saturdays: "); 	scanf("%d", &desiredNum);      days2date(yearNum, dayNum); 	getDesiredFutureDay(yearNum, dayNum, desiredNum);      return 0; }写了一个，C的

上面代码 把第211行 换到 193-194之间，必须要先转换时间，然后再进行判断！

看看这是不是你要的结果  #include <iostream> #include <string> using namespace std;  struct time{ 	int year; 	int month; 	int monthday; 	int weekday; };  //leapyear 计算 year是否为闰年 是返回true 否返回false bool leapyear(int year) { 	if((year%4==0&&year%100!=0)||(year%400==0)) return true; 	else return false; }  //返回某年份中某月份天数 int monthtotalday(int year,int month) { 	switch(month) 	{ 	case 2: 		if (true==leapyear(year))return 29; 		else return 28; 		break; 	case 1:;case 3:;case 5:;case 7:;case 8:;case 10:;case 12: 		return 31; 		break; 	case 4:;case 6:;case 9:;case 11: 		return 30; 		break; 	default: 		return 0; 		break; 	} }  //以年月日为基础计算星期 int weekday(time t) { 	int a; 	int totalday=0;//从格林威治开始时间计算到输入年份总天数 	for(int i=1970;i<t.year;++i)//以格林威治标准年份计算1970.1.1为星期四 	{ 		if (leapyear(i)==true)//闰年加366 平年加365 		{ 			totalday+=366; 		}else 		{ 			totalday+=365; 		} 	} 	for (int i=1;i<=t.month;++i)//加上每个月的天数 	{ 		totalday+=monthtotalday(t.year,i-1); 	} 	totalday+=t.monthday-1;//加上剩余天数（这里需要-1） 	totalday+=4;//加上格林威治的初始星期 	a=totalday%7;//总天数+初始星期数再摩除7得星期数。周日为0 	return a; }  //将时间格式重新转换 time newtime(time oldtime) { 	while(oldtime.monthday>monthtotalday(oldtime.year,oldtime.month))//天数大约当月最大天数进入循环 	{ 		oldtime.monthday-=monthtotalday(oldtime.year,oldtime.month);//天数大于当月最大天数进位 		oldtime.month++; 		if (oldtime.month>12)//月份数大于12则进位 		{ 			oldtime.month-=12; 			oldtime.year++; 		} 	} 	oldtime.weekday=weekday(oldtime);//计算星期 	return oldtime; }  string putenglishmonth(int month)//输出英文月份 { 	string englishmonth; 	switch(month) 	{ 	case 1:englishmonth="January"; 		break; 	case 2:englishmonth="February"; 		break; 	case 3:englishmonth="March"; 		break; 	case 4:englishmonth="April"; 		break; 	case 5:englishmonth="May"; 		break; 	case 6:englishmonth="June"; 		break; 	case 7:englishmonth="July"; 		break; 	case 8:englishmonth="August"; 		break; 	case 9:englishmonth="September"; 		break; 	case 10:englishmonth="October"; 		break; 	case 11:englishmonth="November"; 		break; 	case 12:englishmonth="December"; 		break; 	} 	return englishmonth; }  string putenglishweekday(int weekday)//输出英文星期 { 	string englishweekday; 	switch(weekday) 	{ 	case 0:englishweekday="Sunday"; 		break; 	case 1:englishweekday="Monday"; 		break; 	case 2:englishweekday="Tuesday"; 		break; 	case 3:englishweekday="Wednesday"; 		break; 	case 4:englishweekday="Thursday"; 		break; 	case 5:englishweekday="Friday"; 		break; 	case 6:englishweekday="Saturday"; 		break; 	} 	return englishweekday; }  void main() { 	int recordyear;//记录输入时的年份 	int year,day,fsn; //year 输入年份（>1970） //day 输入一年中的天数（1-365） //输入要输出的未来星期六数(>0) 	cout<<"Enter the year number:"; 	cin>>year; 	recordyear=year; 	while(year<1970) 	{ 		cout<<"please enter ther year number(>1970):"; 		cin>>year; 	} 	cout<<"Enter the day number (1 - 365):"; 	cin>>day; 	while(day>366||day<1) 	{ 		cout<<"please enter the day number (1 - 365):"; 		cin>>day; 	} 	cout<<"Enter desired number of future Saturdays:"; 	cin>>fsn; 	while(fsn<1) 	{ 		cout<<"please enter desired number of future Saturdays(>0):"; 		cin>>fsn; 	}  	time a;//定义一个时间 	a.year=year;//初始化年份 	a.monthday=day;//初始化天数 	a.month=1;//这个一定要初始化为1 如果输入2014 56  初始化时间表示为2014年1月56日 	a.weekday=0;//随意初始化星期，也可不初始化，因为星期是根据年月日计算出来的 	a=newtime(a);//将时间重新计算  	cout<<"Input date:"<<putenglishweekday(a.weekday)<<" "<<putenglishmonth(a.month)<<" " 		<<a.monthday<<" "<<a.year<<endl;  	int b=0; 	while(0==b)//找到输入日期的下一个周六 	{ 		a.monthday++; 		a=newtime(a); 		if (6==a.weekday) 		{ 			b++; 		} 	} 	for (int i=0;i<fsn;i++)//输出接下来fsn个周六的日期 	{ 		if (0!=i)//第一次不加一周输出，以后都加一周输出 		{ 			a.monthday+=7; 		} 		if (a.year>recordyear)//跨年则判断是否继续输出，输入1继续输出 输入0结束输出 		{ 			int pass; 			cout<<recordyear<<"has gone by,whether to show "<<a.year<<" <yes put 1 or no put 0>"; 			cin>>pass; 			while(pass!=0&&pass!=1) 			{ 				cout<<recordyear<<"has gone by,whether to show "<<a.year<<" <yes put 1 or no put 0>"; 				cin>>pass; 			} 			if (0==pass) 			{ 				system("pause"); 				return; 			} 			recordyear=a.year; 		} 		a=newtime(a);//时间转换 并输出 		cout<<"Next Saturday:"<<putenglishweekday(a.weekday)<<" "<<putenglishmonth(a.month)<<" " 			<<a.monthday<<" "<<a.year<<endl; 	} 	system("pause"); }

#include <stdio.h>  int week_calc[2][12] = {0, 3, 3, 6, 1, 4, 6, 2, 5, 0, 3, 5 ,                          0, 3, 4, 0, 2, 5, 0, 3, 6, 1, 4, 6};  char str_month[12][10] = {"January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"};  char str_week[7][10] = {"Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"};  int ifLeapYear(int year) {   return (           year % 400 == 0 ||            (year % 4 == 0 && year % 100 != 0)           )           ? 1 : 0; }  int getDate(int year, int num_day, int *month, int *date) {   int days_month[12]={31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};   int i = 0;   for (; i < 12; ++i)   {     int days = days_month[i] + (1 == i ? ifLeapYear(year) : 0);     if (num_day <= days)     {       *month = i;       *date = num_day;       return 1;     }     num_day -= days;   }   *month = -1; *date = -1;   return 0; }  int getWeek(int year, int month, int date) {   return (year-1 + (year-1)/4 - (year-1)/100 + (year-1)/400 + week_calc[ifLeapYear(year)][month] + date) % 7; }  int getMaxDays(int year) {   return 365 + ifLeapYear(year); }  main() {   int num_year, num_day;   printf("Enter the year number: ");   scanf("%d", &num_year);   printf("\n");   int year = num_year;   int max_days = getMaxDays(year);    printf("Enter the year number (1 - %d): ", max_days);   scanf("%d", &num_day);   printf("\n");    int month = -1, date = -1;   getDate(year, num_day, &month, &date);   int num_week = getWeek(year, month, date);      int prev_day = num_day - (num_week - 0), next_day = num_day + (6 - num_week);   if (prev_day == num_day)     prev_day = num_day - 7;   else if (next_day == num_day)     next_day = num_day + 7;    int prev_year = year, next_year = year;   if (prev_day <= 0)   {     --prev_year;     prev_day = getMaxDays(prev_day) - prev_day;   }   if (next_day > max_days)   {     ++ next_year;     next_day = next_day - max_days;   }    int prev_month = -1, prev_date = -1, next_month = -1, next_date = -1;   getDate(prev_year, prev_day, &prev_month, &prev_date);    getDate(next_year, next_day, &next_month, &next_date);    printf("Input date: %s %s %d, %d\n", str_week[num_week], str_month[month], date, year);   printf("Previous Sunday: %s %d, %d\n", str_month[prev_month], prev_date, prev_year);   printf("Next Saturday: %s %d, %d\n", str_month[next_month], next_date, next_year);    return 0; } 这个应该是计算的代码 但是需要实现Enter desired number of future Saturdays: 5 这个样子的 这段代码没有 麻烦帮我看下吧

引用 2 楼 jacksto 的回复:首先先谢谢您的分析  顺便大师 求代码。。。 最好有注释 谢谢！ 还有如果输入不出5行数据 这个怎么处理啊 你已经有代码了？发出来看一下。 主要输不知道这个在考什么，有现成的函数可以用。但如果是在考计算日期，那用现成的函数好像不行。

Enter the year number: 2014 输入年份 Enter the day number (1 - 365): 56 输入一年当中的已经过去的天数（从结果中猜出来的） Enter desired number of future Saturdays: 5 希望列出未来是是星期6的日期的个数 Input date: Tuesday February 25, 2014 输入：星期2,2月25,2014 Next Saturday: March 1, 2014 Next Saturday: March 8, 2014 Next Saturday: March 15, 2014 Next Saturday: March 22, 2014 Next Saturday: March 29, 2014  程序需要做的工作。 根据日期，计算出已经过去的天数（函数1） 根据提供的日期是星期几，计算出后面每个星期六的天数（函数2） 根据天数，计算出日期（函数1的反函数）  OK了。分析的应当比较明白了，还要代码？

误会你最后一问的意思了，我以为是某一月份中所有周六的天数 更改如下，把下方注释掉的换成上面代码即可  	int b=0; 	while(0==b) 	{ 		a.monthday++; 		a=newtime(a); 		if (6==a.weekday) 		{ 			b++; 		} 	} 	for (int i=0;i<fsn;i++) 	{ 		if (0!=i) 		{ 			a.monthday+=7; 		} 		a=newtime(a); 		cout<<"Next Saturday:"<<a.year<<"年"<<a.month<<"月" 			<<a.monthday<<"日"<<" "<<"星期"<<a.weekday<<endl; 	}  	//for (int i=1;i<=monthtotalday(year,fsn);++i) 	//{ 	//	time b; 	//	b.year=year; 	//	b.month=fsn; 	//	b.monthday=i; 	//	b.weekday=0; 	//	b=newtime(b); 	//	if (6==b.weekday) 	//	{ 	//		cout<<"Next Saturday:"<<b.year<<"年"<<b.month<<"月" 	//			<<b.monthday<<"日"<<" "<<"星期"<<b.weekday<<endl; 	//	} 	//}

万分感谢您的支援 带我细细拜读下您的算法

忘记注释了 然后没有严格按照你的格式用英文输出，相信你可以解决了  #include <iostream> using namespace std;  struct time{ 	int year; 	int month; 	int monthday; 	int weekday; };  //leapyear 计算 year是否为闰年 是返回true 否返回false bool leapyear(int year) { 	if((year%4==0&&year%100!=0)||(year%400==0)) return true; 	else return false; }  //返回某年份中某月份天数 int monthtotalday(int year,int month) { 	switch(month) 	{ 	case 2: 		if (true==leapyear(year))return 29; 		else return 28; 		break; 	case 1:;case 3:;case 5:;case 7:;case 8:;case 10:;case 12: 		return 31; 		break; 	case 4:;case 6:;case 9:;case 11: 		return 30; 		break; 	default: 		return 0; 		break; 	} }  //以年月日为基础计算星期 int weekday(time t) { 	int a; 	int totalday=0;//从格林威治开始时间计算到输入年份总天数 	for(int i=1970;i<t.year;++i)//以格林威治标准年份计算1970.1.1为星期四 	{ 		if (leapyear(i)==true)//闰年加366 平年加365 		{ 			totalday+=366; 		}else 		{ 			totalday+=365; 		} 	} 	for (int i=1;i<=t.month;++i)//加上每个月的天数 	{ 		totalday+=monthtotalday(t.year,i-1); 	} 	totalday+=t.monthday-1;//加上剩余天数（这里需要-1） 	totalday+=4;//加上格林威治的初始星期 	a=totalday%7;//总天数+初始星期数再摩除7得星期数。周日为0 	return a; }  //将时间格式重新转换 time newtime(time oldtime) { 	while(oldtime.monthday>monthtotalday(oldtime.year,oldtime.month))//天数大约当月最大天数进入循环 	{ 		oldtime.monthday-=monthtotalday(oldtime.year,oldtime.month);//天数大于当月最大天数进位 		oldtime.month++; 		if (oldtime.month>12)//月份数大于12则进位 		{ 			oldtime.month-=12; 			oldtime.year++; 		} 	} 	oldtime.weekday=weekday(oldtime);//计算星期 	return oldtime; }  void main() { 	int year,day,fsn; 	cout<<"Enter the year number:"; 	cin>>year; 	while(year<1970) 	{ 		cout<<"please enter ther year number(>1970):"; 		cin>>year; 	} 	cout<<"Enter the day number (1 - 365):"; 	cin>>day; 	while(day>366||day<1) 	{ 		cout<<"please enter the day number (1 - 365):"; 		cin>>day; 	} 	cout<<"Enter desired number of future Saturdays:"; 	cin>>fsn; 	while(fsn>12||fsn<1) 	{ 		cout<<"please enter desired number of future Saturdays(1-12):"; 		cin>>fsn; 	}  	time a; 	a.year=year; 	a.monthday=day; 	a.month=1; 	a.weekday=0; 	a=newtime(a); 	cout<<"Input date:"<<a.year<<"年"<<a.month<<"月" 		<<a.monthday<<"日"<<" "<<"星期"<<a.weekday<<endl;  	for (int i=1;i<=monthtotalday(year,fsn);++i) 	{ 		time b; 		b.year=year; 		b.month=fsn; 		b.monthday=i; 		b.weekday=0; 		b=newtime(b); 		if (6==b.weekday) 		{ 			cout<<"Next Saturday:"<<b.year<<"年"<<b.month<<"月" 				<<b.monthday<<"日"<<" "<<"星期"<<b.weekday<<endl; 		} 	} 	system("pause"); }

#include <iostream> using namespace std;  struct time{ 	int year; 	int month; 	int monthday; 	int weekday; };  bool leapyear(int year) { 	if((year%4==0&&year%100!=0)||(year%400==0)) return true; 	else return false; }  int monthtotalday(int year,int month) { 	switch(month) 	{ 	case 2: 		if (true==leapyear(year))return 29; 		else return 28; 		break; 	case 1:;case 3:;case 5:;case 7:;case 8:;case 10:;case 12: 		return 31; 		break; 	case 4:;case 6:;case 9:;case 11: 		return 30; 		break; 	default: 		return 0; 		break; 	} }  int weekday(time t) { 	int a; 	int totalday=0; 	for(int i=1970;i<t.year;++i)//以格林威治标准年份计算1970.1.1为星期四 	{ 		if (leapyear(i)==true) 		{ 			totalday+=366; 		}else 		{ 			totalday+=365; 		} 	} 	for (int i=1;i<=t.month;++i) 	{ 		totalday+=monthtotalday(t.year,i-1); 	} 	totalday+=t.monthday-1; 	totalday+=4; 	a=totalday%7; 	return a; }  time newtime(time oldtime) { 	while(oldtime.monthday>monthtotalday(oldtime.year,oldtime.month)) 	{ 		oldtime.monthday-=monthtotalday(oldtime.year,oldtime.month); 		oldtime.month++; 		if (oldtime.month>12) 		{ 			oldtime.month-=12; 			oldtime.year++; 		} 	} 	oldtime.weekday=weekday(oldtime); 	return oldtime; }  void main() { 	int year,day,fsn; 	cout<<"Enter the year number:"; 	cin>>year; 	while(year<1970) 	{ 		cout<<"please enter ther year number(>1970):"; 		cin>>year; 	} 	cout<<"Enter the day number (1 - 365):"; 	cin>>day; 	while(day>366||day<1) 	{ 		cout<<"please enter the day number (1 - 365):"; 		cin>>day; 	} 	cout<<"Enter desired number of future Saturdays:"; 	cin>>fsn; 	while(fsn>12||fsn<1) 	{ 		cout<<"please enter desired number of future Saturdays(1-12):"; 		cin>>fsn; 	}  	time a; 	a.year=year; 	a.monthday=day; 	a.month=1; 	a.weekday=0; 	a=newtime(a); 	cout<<"Input date:"<<a.year<<"年"<<a.month<<"月" 		<<a.monthday<<"日"<<" "<<"星期"<<a.weekday<<endl;  	for (int i=1;i<=monthtotalday(year,fsn);++i) 	{ 		time b; 		b.year=year; 		b.month=fsn; 		b.monthday=i; 		b.weekday=0; 		b=newtime(b); 		if (6==b.weekday) 		{ 			cout<<"Next Saturday:"<<b.year<<"年"<<b.month<<"月" 				<<b.monthday<<"日"<<" "<<"星期"<<b.weekday<<endl; 		} 	} 	system("pause"); }


Question: 关于CB使用时出现的一些意想不到的问题（C语言）

这跟C++有关系？可是我用的是C语言啊。不过我还是去问问吧，多谢啦~

这个。。。lz要不去C++ Builder那儿问问吧


Question: Socket接收文件以后网断开

你调试是用的开发板么？  这里操作系统是否一直？

问题解决了，我在发送端设置了一个心跳，每5s发送一个字符，这样就不会断了

不知道有多少前人掉在TCP Socket send(人多)send(病少)send(财富) recv(人多病)recv(少财富) 陷阱里面啊！ http://topic.csdn.net/u/20120210/09/51109ed0-07b9-41f2-b487-a51597f2ca01.html

驱动问题？在你的电脑上不使用USB wifi网卡测试一下不就知道了么？

我好像发现问题了，我发送文件的时间间隔有20s左右，如果我很快的发送第二个，就不会有问题，但我程序里没有任何超时的指令，而且朋友的机子间隔1分钟以上也能接受第二个文件，难道是linux本身有什么设置么？

引用 2 楼 xihu1364 的回复:应该不是程序的问题吧   在弄几个同事电脑上试试，排除程序的bug。  至于网卡的问题，这个得去驱动版块去问 试了两台了，都没问题，就我的开发板有问题，如果是驱动的话，请问下大概是缺少了什么您知道么？

引用 楼主 zgzg177 的回复:本人在linux下用C编写了一个server端接收文件的程序,第一个文件接收没有问题(几MB~几百MB都能成功接收),可是接收第二个文件的时候就只能接受50~60KB,而且网也上不去了,同样的server程序我拿到我朋友的linux上能正常接收多个文件,区别是我用的是USB wifi网卡,我朋友的就是正常的笔记本配置的无线网卡.请问下这是什么原因? THX 我的那个不是个电脑，是一块安装了ubuntu的开发板，所以只能使用usb wifi网卡，因为是开发板，所以上面我只装了适合我这个网卡的5个模块，其他的都没装，请问还有什么是需要装的么？


Question: fgetc的用法

多谢大家的回答，我最近也参考了《c primer plus》上面说fgetc需要读到结尾的下一位才会知道文本结束。

这个问题就像 char a,b; a=getchar(); b=getchar();  你在程序中输入一个字母k回车这时候 a=k; b='回车符' 一个道理

改成这样。  ch[i]=fgetc(fp); while(!feof(fp)) {     i++;     ch[i]=fgetc(fp); }

引用 楼主 hb0810096672 的回复:大家好，我用fgetc读取一个文本文件里的字符，里面只有4个字符为什么会读出5个呢？下面代码和执行截图，请大家给解答一下。  代码 #include<stdio.h> #include<stdlib.h> #include<string.h> int main() {     FILE *fp;     fp = fopen("E://文本编辑//文件夹//hellow.txt","r");     if(fp==NULL)exit(0);     char ch[10]={0};     int i=0;     while(!feof(fp))     {         ch[i]=fgetc(fp);         i++;     }     int k = strlen(ch);     printf("%d\n",k);     printf("%s",ch);     printf("%c",ch[k-1]);     printf("%d",ch[k-1]);     printf("%d",EOF);     fclose(fp);     return 0; }   截图 这是执行情况  这是hellow.txt  文本文件由个EOF结束符。所以是5个字符。如果是以字符串读出，这个EOF不会读出。

用hex模式看看文件


Question: 初学C语言，有个素数问题求教，代码如下，请尽量不要使用一些初学者不熟悉的函数什么的。。。谢谢

谢谢大家谢谢大家 写明白了 修改后如下： #include "stdio.h" #include "stdlib.h" #include "math.h" int main(void) {     int i=0,m=0,j=0,a=0; //注意初始化     int grade[10];     double k;     printf("请输入一个数字:\n");     scanf("%d",&i);     for(m=0;i>=2 &&  m<10;i--)     {         k=sqrt(i);         for(j=2;j<=floor(k);j++)         {             if (i%j==0)             {                 break;             }         }         if (j>floor(k))         {             grade[m]=i;             m++;         }     }     for(i=0; i<m; i++)     {         a +=grade[i];         printf("第%d个素数为%d\n", i+1,grade[i]);     }     printf("sum is %d\n", a);     system("pause"); }

引用 5 楼 martenyong 的回复:最后多输出了两个%d。 另外“2.试了很多次找不到将1,0，负数那些去掉；” 这句话是什么意思啊，是说如果你输入0.1.负数这些的话，系统还是会继续按照条件查找“质数”而不是停止吗？ 这个问题的话，你可以限制一下判断条件。 如果在2到你输入的值之间，素数没有那么多的话，那么最小判断到二，然后停止判断，提示系统不够10个，然后能输出几个输出几个。  那个，其他的问题都解决了，就是那个你说的第二个，我的意思是在判断素数的时候不把1,0，负数也算作素数然后输出，就像输入30以下数字的话，就没有十个素数，程序显示结果还是十个数，就会显示1,0，-1。。。那些，这个希望您能够解答

printf("%d %d %d %d %d %d %d %d %d %d %d %d" 有12个

利用循环才可以发挥数组的作用，不然要数组这样的连续内存干嘛。输出数组时用for循环即可一次性输出

而且，不要用这种一长串的相加，一长串的printf 你看你会用for循环 写个for(int i=0;i<10;i++) {printf("%d ",grade[i]);} 不就好了么

很简单，你数数你printf了几个%d