Question: C语言数据结构，关于图的遍历的问题，求大神指导一下

深度和广度的算法我懂，但是我不知道怎么修改让它输出所有可能的结果，就像我一楼写的那样

#include <stdio.h> #include <stdlib.h>   #define MAXVEX  100                      //最大顶点数 #define INFINITY    65535               //用65535来代表无穷大   int visited[MAXVEX]={0};   typedef struct {     char vexs[MAXVEX];            //顶点表     int  arc[MAXVEX][MAXVEX];         //邻接矩阵，可看作边     int  numVertexes, numEdges;      //图中当前的顶点数和边数 }Graph;     void CreateGraph(Graph *g) {     int i,j,k,w,t;     printf("输入顶点数，边数和t（中间用空格）:");     scanf("%d %d %d", &(g->numVertexes), &(g->numEdges),&t);     printf("\n");     for(i=1;i<=g->numVertexes;i++)     {         getchar();         printf("输入第%d顶点信息vexs[%d]=",i,i);         scanf("%c",&(g->vexs[i]));     }     printf("\n");     for(i=1;i<=g->numVertexes;i++)         for(j=1;j<=g->numVertexes;j++)             if (t>2)                 g->arc[i][j] = INFINITY;             else                 g->arc[i][j]=0;     for(k=1;k<=g->numEdges;k++)     {         printf("输入i j（中间用空格）:");         scanf("%d %d",&i,&j);         if(i>g->numVertexes ||j>g->numVertexes)             exit(0);         if(t>2)         {             printf("输入w:");             scanf("%d",&w);             g->arc[i][j]=w;             if(t==3)                 g->arc[j][i]=w;         }         else         {             g->arc[i][j]=1;             if (t==1)                 g->arc[j][i]=1;         }     }     printf("\n");     printf("输出邻接矩阵:\n");     for(i=1;i<=g->numVertexes ;i++)     {           for(j=1;j<=g->numVertexes ;j++)         {             printf("%8d",g->arc[i][j]);              if(t>2&&g->arc[i][j]==65535)                 g->arc[i][j]=0;             else if(t>2&&g->arc[i][j]!=65535)                 g->arc[i][j]=1;         }         printf("\n");     }  }  void dfs (Graph g,int i)         //广度优先搜索，从顶点i开始遍历 {     int j;     printf("%d->",i);         //输出访问顶点     visited[i]=1;            //全局数组访问标记置1表示已经访问     for(j=1; j<=g.numVertexes; j++)         if ((g.arc[i][j]==1)&&(!visited[j]))             dfs (g,j); }   void bfs (Graph g,int i) {     int visited[MAXVEX]={0};     int  q[g.numVertexes+1] ;     int  f,r,j ;     f=r=0 ;     printf("%d->",i);     visited[i]=1 ;     r++;     q[r]=i ;     while (f<r)     {    f++; i=q[f] ;         for (j=1; j<=g.numVertexes; j++)             if ((g.arc[i][j]==1)&&(!visited[j]))             {    printf("%d->",j);    ;     visited[j]=1 ;     r++; q[r]=j ;  }     } }   int main() {     Graph g;     int i;     printf("t为1~4,分别表示无向图、有向图、带权无向图、带权有向图\n");     CreateGraph(&g);     printf("\n输入i:");     scanf("%d",&i);     printf("\n深度优先搜索遍历：");     dfs (g,i);     printf("NULL\n");     printf("广度优先搜索遍历：");     bfs (g,i);      printf("NULL\n");     return 0; }  参考博客： http://blog.csdn.net/zhang0xu0/article/details/53258136

大神不好意思能直接复制发出来嘛   好像下载不了

https://zh.wikipedia.org/wiki/%E5%B9%BF%E5%BA%A6%E4%BC%98%E5%85%88%E6%90%9C%E7%B4%A2  https://zh.wikipedia.org/wiki/%E6%B7%B1%E5%BA%A6%E4%BC%98%E5%85%88%E6%90%9C%E7%B4%A2

这是我的源代码，在线等大神指导   #include<stdio.h>   #include<malloc.h>   #include<process.h>   #include"stdafx.h" #include <stdio.h> #define MaxVex        100            //最大顶点数 #define TRUE        1 #define FALSE        0 typedef int			VRType;			//顶点关系类型 typedef char        VertexType;    //顶点类型 typedef int         Bool; Bool    visited[MaxVex];//访问标志数组  typedef struct ArcCell//邻接矩阵结构体 { 	VRType adj; }ArcCell, AdjMatrix[MaxVex][MaxVex];  typedef struct {     VertexType    vexs[MaxVex];            //顶点数组     AdjMatrix    arc;					   //邻接矩阵     int    vexnum, arcnum;            //当前图中的结点数以及边数 }MGraph;    //广度优先遍历需要的循环队列 typedef struct {     int    data[MaxVex];     int    front, rear; }Queue;   /****************************************/ //队列的相关操作  //初始化 void InitQueue(Queue *Q) {     Q->front = Q->rear = 0; }  //入队 void EnQueue(Queue *Q, int e) {     if ((Q->rear+1)%MaxVex == Q->front)         return ;      Q->data[Q->rear] = e;     Q->rear = (Q->rear+1)%MaxVex; }  //判空 Bool QueueEmpty(Queue *Q) {     if (Q->front == Q->rear)         return TRUE;     else         return FALSE; }  //出队 void DeQueue(Queue *Q, int *e) {     if (Q->front == Q->rear)         return ;          *e = Q->data[Q->front];     Q->front = (Q->front+1)%MaxVex; } /****************************************/   //建立图的邻接矩阵 void CreateMGraph(MGraph *G) {     int i, j, k;     printf("输入顶点数和边数: ");     scanf("%d%d", &G->vexnum,&G->arcnum);     fflush(stdin);//清除标准输入设备（一般是键盘）的缓存。消除输入字符时回车的影响     printf("==============================\n");     printf("输入各个顶点:\n");     for (i=0; i<G->vexnum; ++i)     {         printf("顶点%d: ",i+1);         scanf("%c", &G->vexs[i]);         fflush(stdin);//清除标准输入设备（一般是键盘）的缓存。消除输入字符时回车的影响     }     for (i=0; i<G->vexnum; ++i)//初始化邻接矩阵     {         for (j=0; j<G->vexnum; ++j)             G->arc[i][j].adj = 0;     }     printf("==============================\n");     for (k=0; k<G->arcnum; ++k)     {         printf("输入边(vi, vj)中的下标i和j: ");         scanf("%d%d", &i,&j);         G->arc[i][j].adj=1;         G->arc[j][i] = G->arc[i][j];//设置对称弧     } }   //输出 void DisMGraph(MGraph *G) {     int i, j, k;     k = G->vexnum;     for (i=0; i<k; ++i)     {         for (j=0; j<k; ++j)         {             printf("%5d ", G->arc[i][j]);         }         putchar('\n');     } }   /****************************************/ //图的深度优先遍历 void DFS(MGraph G, int i) {     int j;     visited[i] = TRUE;     printf("%c ",    G.vexs[i]);      for (j=0; j<G.vexnum; ++j)     {         if (G.arc[i][j].adj!=0  &&  !visited[j])             DFS(G, j);     } }  void DFSTraverse(MGraph G) {     int i;     for (i=0; i<G.vexnum; ++i)         visited[i] = FALSE;      for (i=0; i<G.vexnum; ++i)     {         if (!visited[i])             DFS(G, i);     }  }   //图的广度优先遍历 void BFSTraverse(MGraph *G) {     int i, j;     Queue Q;      for (i=0; i<G->vexnum; ++i)         visited[i] = FALSE;      InitQueue(&Q);      for (i=0; i<G->vexnum; ++i)     {         if (!visited[i])         {             visited[i] = TRUE;             printf("%c ", G->vexs[i]);             EnQueue(&Q, i);              while (!QueueEmpty(&Q))             {                 DeQueue(&Q, &i);                 for (j=0; j<G->vexnum; ++j)                 {                     if (!visited[j] && G->arc[i][j].adj!=0)                     {                         visited[j] = TRUE;                         printf("%c ", G->vexs[j]);                         EnQueue(&Q, j);                     }                 }             }         }     } } /****************************************/  //程序入口 int main(){     MGraph G;     CreateMGraph(&G);     printf("\n图的深度优先遍历为: ");     DFSTraverse(G);         printf("\n图的广度优先遍历为: ");     BFSTraverse(&G);     printf("\n"); 	system("pause");     return 0; }


Question: 希望大神指导一下

for (i=2;i <= sqrt(num); i++) 循环里发现能整除说明不是质数， 然而不能整除并不能说明是质数，因为循环还没有结束 只有循环结束了，所有小于平方根的数都判断过了才能知道是不是质数

#include <stdio.h> #include <math.h> main() {     int num,i;     printf ("请输入一个整数！:");     scanf ("%d", &num);     if (num <= 1)     {         printf("这个不是素数！:");     }     for (i=2; i <= sqrt(num); i++)     {         if ((num % i) == 0)         {             printf ("这个不是素数！ :");             break;         }     }     if (i > sqrt(num))         printf ("这个是素数！ :");      return 0; }

有大神指导一下么？帮我修改一下啦，真心不会啊啊，


Question: 输入一个字符。用指针表示法删除字符串中与该字符相同的字符。用函数实现。。

char *de_char(char* src, char ch) {     char *ret = src;     char *dst = src;     while (*src) {         if (*src != ch)             *dst++ = *src;         src++;     }     *dst = '\0';      return ret; }

void d(char *p, char c2) { 	char	*q; 	int		n; 	for (; *p != '\0'; p++) 	{ 		if (*p == c2) 		{ 			q = p + 1; 			while (*q == c2) 				q++; 			n = q - p; 			q = p; 			for (; *q != '\0'; q++) 				*q = *(q + n); 		} 	} }


Question: 急，，求助大佬解释下。。。。双向循环链表的尾删

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

int is_null(node *head)             //判断是否为空 {     if (head->next == head && head->prior == head)         return 1;     else         return 0;  } 判断链表为空，其实用一个条件就可以了。如果链表头节点的next是本身了，那么就是空的嘛，如果头结点的prior是本身，一样可以证明链表是null； 因此可以用||替换&&，或者用一种判断条件吧

问题不是出在尾删函数，而是出在尾插函数出问题，即尾插法创建链表时就出问题，参考一下吧  void list_add_tail(node *p, node *head)                       //尾插法 { #if 1     p->prior = head->prior;     p->next = head;     head->prior->next = p;     head->prior = p; #else     p->prior = head->prior->next;     p->next = head;     head->prior->next = p;     head->prior = p; #endif }  我的验证方法是，在你的这个函数里，运用倒序输出：  void ShowLinklist(node *head, void (*show_func)(void *))           //头遍历 {     node *p;     //p = NULL;     p = head->next;      while (p != head)     {         show_func(p->data);         p = p->next;     }     //倒序输出     p = head->prior;     while (p != head) {         printf("HELLO");         show_func(p->data);         p = p->prior;     } } 看这个地方，我用倒序输出时，如果用你的尾插法创建的双链表不能正常倒序输出；可以试一下；


Question: 不是说函数不要返回内部变量吗？

不要返回局部变量说的是返回局部变量的地址，你这里返回是按值返回，返回后是复制了局部变量的值，之后使用的并不是你函数中的局部变量，所以没有问题

其实不明白这些，因为只知其然，不知其所以然

引用 7 楼 xsklld 的回复:[quote=引用 5 楼 cfjtaishan 的回复:] [quote=引用 4 楼 xsklld 的回复:] [quote=引用 3 楼 cfjtaishan 的回复:] 这个局部变量是一个指针，这个指针指向的是堆上的空间；堆上的空间生命周期是从malloc开始知道free才会结束；  若返回的是局部的数组，那么就会有问题，因为局部数组是在栈上申请的，它的生命周期是从定义开始，到函数结束；函数结束后就会将其释放； 那也是复制构造函数没有写好的锅，跟返回局部变量没有关系。[/quote] 怎么跟局部变量没关系呢？局部变量可能是一个指针变量，也可能是数组等等；[/quote] 我看错了，我以为他的PriorityQueue是个类。[/quote] 哦，楼主的是C语言，不会涉及到类。

引用 5 楼 cfjtaishan 的回复:[quote=引用 4 楼 xsklld 的回复:] [quote=引用 3 楼 cfjtaishan 的回复:] 这个局部变量是一个指针，这个指针指向的是堆上的空间；堆上的空间生命周期是从malloc开始知道free才会结束；  若返回的是局部的数组，那么就会有问题，因为局部数组是在栈上申请的，它的生命周期是从定义开始，到函数结束；函数结束后就会将其释放； 那也是复制构造函数没有写好的锅，跟返回局部变量没有关系。[/quote] 怎么跟局部变量没关系呢？局部变量可能是一个指针变量，也可能是数组等等；[/quote] 我看错了，我以为他的PriorityQueue是个类。

返回变量的值没什么问题，本来就是复制的。比如函数内部的x=3，返回这个x没问题 不要返回内部变量指的是不能返回内部变量的地址（即指针）。

引用 4 楼 xsklld 的回复:[quote=引用 3 楼 cfjtaishan 的回复:] 这个局部变量是一个指针，这个指针指向的是堆上的空间；堆上的空间生命周期是从malloc开始知道free才会结束；  若返回的是局部的数组，那么就会有问题，因为局部数组是在栈上申请的，它的生命周期是从定义开始，到函数结束；函数结束后就会将其释放； 那也是复制构造函数没有写好的锅，跟返回局部变量没有关系。[/quote] 怎么跟局部变量没关系呢？局部变量可能是一个指针变量，也可能是数组等等；

引用 3 楼 cfjtaishan 的回复:这个局部变量是一个指针，这个指针指向的是堆上的空间；堆上的空间生命周期是从malloc开始知道free才会结束；  若返回的是局部的数组，那么就会有问题，因为局部数组是在栈上申请的，它的生命周期是从定义开始，到函数结束；函数结束后就会将其释放； 那也是复制构造函数没有写好的锅，跟返回局部变量没有关系。

而且，不是不能够返回函数内部的变量，而是不能返回内部变量的引用

它返回的是指针


Question: Program received signal SIGSEGV, Segmentation fault.错误

来晚了，也学到了东西。 楼主如果太大的数组就动态分配吧

非常感谢您！！！！您实在是太厉害了！头文件忘记粘出来了。。。程序需要读入一个比较大的数组，所以需要建立一个大数组。

问题的关键可能在input_loc，你提供的代码中看不出它的大小。你先是执行strcpy把它复制到了docu_loc1，这时候docu_loc1用掉了多少字节很重要，因为后面strcat又给连接上IA_out了，这里一不小心就造成溢出。

代码不全呢， non_num太大，作为JA和AA的数组长度，那么可能会超出栈的大小，即越界；可能导致段错误；  栈上的空间是有限的，大的数组不建议在栈上申请，如果需要创建这么大的数组，建议在堆上（malloc/free)或数组端（全局的）； strcpy(docu_loc1,input_loc); input_loc未定义；  程序虽然简单，但是你定义的数组太大，如果不是必须的，不建议定义这么大的数组，尤其是在函数里定义局部变量


Question: C语言从一个文件中读取乱序内容，并排序，数据量比较大怎么弄？谢谢

1、内存足够，读一次文件，所有数据排序，再写新文件，是最快的，比逐个读记录边读边插入肯定快。 2、我说的先提取排序关键字和偏移，排序后再读取再写入，是2次文件读取1次写，是慢一点，但是可以对付内存不够放下整个文件的情况。 3、至于排序的关键字不是记录的首字节，并不是很麻烦的事情，偏移是该条记录的首字节对应在文件中的位置，是需要解析记录再获取的。如果记录不等长，还需要一个字段记录该条记录的长度。 4、操作系统读文件，如果读某个偏移开始的位置，应该不是从头开始读磁盘的，可以根据文件分配表的内容，直接找到该偏移对应的物理扇区。不是偏移量越大，每次读取的时间越长。

这样第一条记录就是id为1的记录了

引用 25 楼 sys0613 的回复:[quote=引用 23 楼 xg436 的回复:] 又看了一遍，你是可以直接缓存A中所有数据？那就新建个数组，和字符串数组，第一条的id是100，那就int【100】=1，string【0】=内容，然后写b就string【int【i++】】 完全没看懂，缓存了不是还要排序么？[/quote] 不需要了 比如A里的ID依次为35214，存储到str[]里面，那么你按我说的int数组里int[1,2,3,4,5]对应的是[4,3,1,5,2]，然后str[int[1]]=str[4]=1

命令提示实用工具    bcp 实用工具 bcp 实用工具在 Microsoft® SQL Server™ 2000 实例和数据文件之间以用户指定的格式复制数据。  语法 bcp {[[database_name.][owner].]{table_name | view_name} | "query"}     {in | out | queryout | format} data_file     [-m max_errors] [-f format_file] [-e err_file]     [-F first_row] [-L last_row] [-b batch_size]     [-n] [-c] [-w] [-N] [-V (60 | 65 | 70)] [-6]     [-q] [-C code_page] [-t field_term] [-r row_term]     [-i input_file] [-o output_file] [-a packet_size]     [-S server_name[\instance_name]] [-U login_id] [-P password]     [-T] [-v] [-R] [-k] [-E] [-h "hint [,...n]"]  参数database_name  指定的表或视图所在数据库的名称。如果未指定，则为用户默认数据库。  owner  表或视图所有者的名称。如果执行大容量复制操作的用户拥有指定的表或视图，则 owner 是可选的。如果没有指定 owner 并且执行大容量复制操作的用户不拥有指定的表或视图，则 Microsoft® SQL Server™ 2000 将返回错误信息并取消大容量复制操作。  table_name  是将数据复制到 SQL Server 时 (in) 的目的表名，以及从 SQL Server 复制数据时 (out) 的源表名。  view_name  是将数据复制到 SQL Server 时 (in) 的目的视图名，以及从 SQL Server 复制数据时 (out) 的源视图名。只有其中所有列都引用同一个表的视图才能用作目的视图。有关将数据复制到视图的限制的更多信息，请参见 INSERT。  Query  是返回一个结果集的 Transact-SQL 查询。如果查询返回多个结果集，例如指定 COMPUTE 子句的 SELECT 语句，只有第一个结果集将复制到数据文件，随后的结果集被忽略。使用双引号引起查询语句，使用单引号引起查询语句中嵌入的任何内容。在从查询中大容量复制数据时，还必须指定 queryout。  in | out | queryout | format  指定大容量复制的方向。in 是从文件复制到数据库表或视图，out 是指从数据库表或视图复制到文件。只有从查询中大容量复制数据时，才必须指定 queryout。根据指定的选项（-n、-c、-w、-6 或 -N）以及表或视图分隔符，format 将创建一个格式文件。如果使用 format，则还必须指定 -f 选项。    说明  Microsoft SQL Server 6.5 中的 bcp 实用工具不支持大容量复制到包含 sql_variant 或 bigint 数据类型的表。   data_file  大容量复制表或视图到磁盘（或者从磁盘复制）时所用数据文件的完整路径。当将数据大容量复制到 SQL Server 时，此数据文件包含将复制到指定表或视图的数据。当从 SQL Server 大容量复制数据时，该数据文件包含从表或视图复制的数据。路径可以有 1 到 255 个字符。  -m max_errors  指定在大容量复制操作取消之前可能产生的错误的最大数目。bcp 无法复制的每一行都将被忽略并计为一个错误。如果没有包括该选项，则默认为 10。  -f format_file  指定格式文件的完整路径，该格式文件包含以前在同一个表或视图上使用 bcp 时的存储响应。当使用由 format 选项所创建的格式文件大容量复制入或复制出数据时，使用此选项。格式文件的创建是可选的。在提示几个格式问题之后，bcp 将提示是否在格式文件中保存回答。默认文件名为 Bcp.fmt。大容量复制数据时，bcp 可引用一个格式文件，因此不必重新交互输入以前的回答。如果未使用此选项，也没有指定 –n、-c、-w、-6 或 -N，则 bcp 将提示输入格式信息。  -e err_file  指定错误文件的完整路径，此错误文件用于存储 bcp 无法从文件传输到数据库的所有行。来自 bcp 的错误信息将发送到用户工作站。如果未使用此选项，则不创建错误文件。  -F first_row  指定要大容量复制的第一行的序数。默认值是 1，表示在指定数据文件的第一行。  -L last_row  指定要大容量复制的最后一行的序数。默认值是 0，表示指定数据文件中的最后一行。  -b batch_size  指定所复制的每批数据中的行数。每个批处理作为一个事务复制至服务器。SQL Server 提交或回滚（在失败时）每个批处理的事务。默认情况下，指定的数据文件中的所有数据都作为一批复制。请不要与 -h "ROWS_PER_BATCH = bb" 选项一起使用。  -n  使用数据的本机（数据库）数据类型执行大容量复制操作。此选项不提示输入每一字段，它将使用本机值。  -c  使用字符数据类型执行大容量复制操作。此选项不提示输入每一字段；它使用 char 作为存储类型，不带前缀，\t（制表符）作为字段分隔符，\n（换行符）作为行终止符。  -w  使用 Unicode 字符执行大容量复制操作。此选项不提示输入每一字段；它使用 nchar 作为存储类型，不带前缀，\t（制表符）作为字段分隔符，\n（换行符）作为行终止符。不能在 SQL Server 6.5 版或更早版本中使用。  -N  对非字符数据使用数据的本机（数据库）数据类型和对字符数据使用 Unicode 字符类型执行大容量复制操作。这是可替代 -w 选项的性能更高的选项，其目的是使用数据文件将数据从一个 SQL Server 传输到另一个 SQL Server 中。它不提示输入每一字段。在需要传输包含 ANSI 扩展字符的数据以及想利用本机模式的性能时，可以使用这一选项。不能在 SQL Server 6.5 版或更早版本中使用 -N 选项。  -V (60 | 65 | 70)  使用 SQL Server 早期版本中的数据类型执行大容量复制操作。此选项与字符 (-c) 或本机 (-n) 格式一起使用。此选项并不提示输入每一字段，它使用默认值。例如，若要将 SQL Server 6.5 中的 bcp 实用工具所支持（但 ODBC 不再支持）的日期格式大容量复制到 SQL Server 2000，可使用 -V 65 参数。    重要  将数据从 SQL Server 大容量复制到数据文件时，即使指定了 –V，bcp 实用工具也不会为任何 datetime 或 smalldatetime 数据生成 SQL Server 6.0 或 SQL Server 6.5 的日期格式。日期将始终以 ODBC 格式写入。另外，由于 SQL Server 6.5 版或更早版本不支持可为空的 bit 数据，因此 bit 列中的空值写为值 0。   -6  使用 SQL Server 6.0 或 SQL Server 6.5 数据类型执行大容量复制操作。仅为保持向后兼容性。改为使用 –V 选项。  -q  在 bcp 实用工具和 SQL Server 实例的连接中执行 SET QUOTED_IDENTIFIERS ON 语句。使用该选项指定包含空格或引号的数据库、所有者、表或视图的名称。将由三部分组成的整个表名或视图名引在双引号 (" ") 中。  -C code_page  仅为保持向后兼容性。作为代替，请在格式文件或交互式 bcp 中为每一列指定一个排序规则名。  指定数据文件中的数据代码页。只有当数据中包含字符值大于 127 或小于 32 的 char、varchar 或 text 列时，code_page 才有用。  代码页值 描述  ACP ANSI/Microsoft Windows® (ISO 1252)。  OEM 客户程序使用的默认代码页。如果未指定 -C，则这是 bcp 使用的默认代码页。  RAW 不发生从一个代码页到另一个代码页的转换。因为不发生转换，所以这是最快的选项。  <值> 特定的代码页号码，例如 850。    -t field_term  指定字段终止符。默认的字段终止符是 \t（制表符）。使用此参数替代默认字段终止符。  -r row_term  指定行终止符。默认的行终止符是 \n（换行符）。使用此参数替代默认行终止符。  -i input_file  指定响应文件的名称，使用交互模式（未指定 –n、-c、-w、-6 或 -N）执行大容量复制时，响应文件包含对每一字段命令提示问题的响应。  -o output_file  指定接收 bcp 输出（从命令提示重定向）的文件的名称。  -a packet_size  指定发送到和发送自服务器的每个网络数据包的字节数。可以使用 SQL Server 企业管理器（或 sp_configure 系统存储过程）设置服务器配置选项。但是，使用此选项可以单个地替代服务器配置选项。packet_size 可以设置为 4096 到 65535 字节，默认值为 4096。  数据包大小的增加能够提高大容量复制操作的性能。如果要求一个较大的数据包而得不到，则使用默认设置。bcp 生成的性能统计显示出所使用数据包的大小。  -S server_name[\instance_name]  指定要连接到的 SQL Server 实例。指定 server_name 以连接该服务器上的 SQL Server 默认实例。指定 server_name\instance_name 以连接到该服务器上的 SQL Server 2000 命名实例。如果未指定服务器，则 bcp 连接到本地计算机上的 SQL Server 默认实例。从网络上的远程计算机执行 bcp 时，要求此选项。  -U login_id  指定用于连接到 SQL Server 的登录 ID。  -P password  指定登录 ID 的密码。如果未使用此选项，则 bcp 将提示输入密码。如果不带密码将此选项用于命令提示行末尾，则 bcp 将使用默认密码 (NULL)。  -T  指定 bcp 使用网络用户的安全凭据，通过信任连接连接到 SQL Server。不需要 login_id 和 password。  -v  报告 bcp 实用工具的版本号和版权。  -R  指定使用为客户端计算机的区域设置定义的区域格式，将货币、日期和时间数据大容量复制到 SQL Server 中。默认情况下，将会忽略区域设置。  -k  指定在大容量复制操作中空列应保留一个空值，而不是对插入的列赋予默认值。  -E  指定标识列的值出现在要导入的文件中。如果没有给出 -E，则正导入的数据文件中此列的标识值将被忽略，而且 SQL Server 2000 会根据创建表期间指定的种子值和增量值自动指派唯一的值。如果数据文件的表或视图中不包含标识列的值，则使用格式文件指定导入数据时应跳过表或视图中的标识列；SQL Server 2000 将自动为该列指派唯一值。有关详细信息，请参见 DBCC CHECKIDENT。  -h "hint [,...n]"  指定在大容量复制数据到表或视图时所使用的提示。在大容量复制数据到 SQL Server 6.x 或更早版本时，不能使用此选项。  提示 描述  ORDER (column [ASC | DESC] [,...n]) 数据文件中数据的排序次序。如果要装载的数据已根据表中的聚集索引排序，则会提高大容量复制的性能。如果数据文件按不同次序排序，或者该表没有聚集索引，则将忽略 ORDER 提示。所提供的列名必须是目的表中的有效列。默认情况下，bcp 假设数据文件没有排序。  ROWS_PER_BATCH = bb 每批中数据的行数（即 bb）。在未指定 -b 时使用，这将使整个数据文件作为单个事务发送到服务器。服务器根据值 bb 优化大容量装载。默认情况下，ROWS_PER_BATCH 未知。  KILOBYTES_PER_BATCH = cc 每批中数据的千字节 (KB) 近似数量（即 cc）。默认情况下，KILOBYTES_PER_BATCH 未知。  TABLOCK 大容量复制操作期间将获取表级锁。由于只在大容量复制操作期间才控制锁减少了表中锁的争夺，因此此提示可以显著提高性能。如果表没有索引并且指定了 TABLOCK，则该表可以同时由多个客户端装载。默认情况下，锁定行为是由表选项 table lock on bulk load 决定的。  CHECK_CONSTRAINTS 大容量复制操作期间，将检查目的表上的所有约束。默认情况下，将会忽略约束。  FIRE_TRIGGERS 与 in 参数一起指定，在目的表上定义的任何插入触发器将在大容量复制操作期间执行。如果没有指定 FIRE_TRIGGERS，则不执行插入触发器。对于 out、queryout 和 format 参数，将忽略 FIRE_TRIGGERS。    注释 将忽略要导入的数据文件中计算列或 timestamp 列的值，SQL Server 2000 自动赋值。如果数据文件不包含表中的计算列或 timestamp 列的值，可用格式文件指定应在导入数据时跳过表中的计算列和 timestamp 列；SQL Server 将自动为该列赋值。  计算列和 timestamp 列照常会从 SQL Server 大容量复制到一个数据文件。  SQL Server 标识符（包括数据库名称、表名或视图名、登录和密码）可以包含诸如嵌入空格和引号等字符。当在命令提示符处指定包含空格或引号的标识符或文件名时，需要将该标识符引在双引号 (" ") 内。另外，对于包含嵌入空格或引号的所有者、表或视图的名称，可以指定 -q 选项，或者将所有者、表或视图的名称在双引号内用方括号 ([ ]) 括起来。  例如，Northwind 数据库内有表 Jane's Orders，该表由用户 Jane Doe 所拥有。若要使用登录 Jane Doe 和密码 go dba 将该表从 Northwind 数据库大容量复制到 Orders.txt 文件，请执行下列命令之一：  bcp "Northwind.Jane Doe.Jane's Orders" out "Jane's Orders.txt" -c -q -U"Jane Doe" -P"go dba"  bcp "Northwind.[Jane Doe].[Jane's Orders]" out "Jane's Orders.txt" -c -U"Jane Doe" -P"go dba"  若要指定包含空格或引号的数据库名称，必须使用 -q 选项。  有关此实用工具位置和运行方式的信息，请参见命令提示实用工具入门。   请参见  在不同排序规则间复制数据  使用 bcp 和 BULK INSERT  并行数据装载  SET QUOTED_IDENTIFIER  sp_tableoption  使用格式文件  ©1988-2000 Microsoft Corporation。保留所有权利。   管理 SQL Server     指定数据格式 如果正在 Microsoft® SQL Server™ 实例和其它程序（例如另一个数据库程序）之间复制数据，则默认的数据类型格式（本机、字符或 Unicode）可能与其它程序所预期的数据结构不兼容。因此，bcp 实用工具允许指定有关数据文件结构的更详细的信息。  如果没有指定 -n、-c、-w 或 -N 开关，则 bcp 实用工具会交互式地提示输入正在复制的每个列的进一步信息：   文件存储类型   前缀长度   字段长度   字段终止符    说明  在使用 BULK INSERT 语句时不能使用交互模式。  根据源列或目的列的 SQL Server 数据类型，bcp 实用工具在每个提示中都会提供默认值。接受 bcp 在这些提示中提供的默认值将生成与本机格式 (-n) 相同的结果，并提供一种方法，以将数据从其它程序中大容量复制出来，以便日后重新装载到 SQL Server 中。  可以创建一个格式文件，用来存储对数据文件各字段的提示的响应，以便重复使用相同的响应而不必再次输入它们。格式文件可以提供将数据大容量复制到 SQL Server 实例，或从 SQL Server 实例大容量复制数据时所需的所有格式信息。格式文件提供了一种灵活的系统，用来写入很少需要或不需要编辑即可符合其它数据格式的数据文件，或者用来从其它软件中读取数据文件。  例如，若要交互式地将 publishers 表大容量复制到 Publ.txt 文件中，可以使用以下命令：  bcp pubs..publishers out publ.txt -Sservername -Usa -Ppassword  对 publishers 表的每一列，都会出现四个提示，并且在方括号中显示 bcp 提供的默认值。以下示例只是 publishers 表中 pub_id 列的情况。  Enter the file storage type of field pub_id [char]: Enter prefix length of field pub_id [0]: Enter length of field pub_id [4]: Enter field terminator [none]:  按 ENTER 键接受所提供的默认值。若要指定与默认值不同的值，请在命令提示符下输入新值。   请参见  使用格式文件  ©1988-2000 Microsoft Corporation。保留所有权利。

引用 23 楼 xg436 的回复:又看了一遍，你是可以直接缓存A中所有数据？那就新建个数组，和字符串数组，第一条的id是100，那就int【100】=1，string【0】=内容，然后写b就string【int【i++】】 完全没看懂，缓存了不是还要排序么？

引用 15 楼 ananluowei 的回复:先读取每条记录的id，记下这条记录在文件中的偏移，用一个结构保存这2个数据。读完整个文件，对这个结构的数组排序。 根据排序后的内容，逐条id读取每条记录，存到新文件。 还有个问题，如果id不是每个数据结构的第一个，这个id是没用的，无法计算偏移的。。。可能id是第6个属性，前五个属性长度无法确定，所以是找不到文件偏移的，是吧？？如果找不到的话，这个偏移就不行吧？谢谢  引用 21 楼 zhao4zhong1 的回复:参考SQL Server中的bcp命令行工具。 数据有规律，就能导入进数据库？谢谢

不想用数据库就用文件代替吧。 你的文件是1G的，最大的id是一百万。然后新建100个文本，标记为1-100，然后新建100个字符串，然后读A，id在1-1w的加到第一个字符串里面，id在1-2w的写到第二个...，内存到上限了就写到对应的文本里去。读取完以后，读取文件1到缓存，排序，写到B里，然后是文件2.3.4..。

参考SQL Server中的bcp命令行工具。

引用 13 楼 hongwenjun 的回复:放出 示例的 几行出来看下，可以用不相关 代替文字信息 您是想从数据上找规律么？呵呵，数据上不是按照行分的，例如数据就是，head：id:001 内容：abc 语言：英语 end head：id:002 内容：abc 语言：汉语 end，就是这么一个挨着一个的，通过head头和end尾区分，head和end中间夹着的内容属性一样，没有换行区分。属性我这举例子就3个，实际每个属性也是10几个。

引用 15 楼 ananluowei 的回复:先读取每条记录的id，记下这条记录在文件中的偏移，用一个结构保存这2个数据。读完整个文件，对这个结构的数组排序。 根据排序后的内容，逐条id读取每条记录，存到新文件。 谢谢了，我想问下如果文件很大的话，再次找到这个偏移时候会不会很慢？？再就是对id排序和对从文件中读取的整个数据进行排序，效率上会有很大提升么？感谢了

引用 14 楼 hdt 的回复:几十万条数据，估计一二百兆，不想用数据库，可以用内存映射文件 具体请查msdn目前就是用的内存映射文件，读取文件这里的速度应该可以了

我电脑里所有文件 的 全路径 记录 24.66万， list.txt  15.5M 排序的时间

http://bbs.csdn.net/topics/380117760  #include <iostream> #include <string> #include <vector> #include <algorithm> #include <cstring> #include <cctype> #include <fstream> #include <sstream>  #define WIN32 //VC 编译器开关 #include <time.h> #ifdef WIN32 #   include <windows.h> #else #   include <sys\time.h> #endif #ifdef WIN32 int gettimeofday(struct timeval* tp, void* tzp) {     time_t clock;     struct tm tm;     SYSTEMTIME wtm;     GetLocalTime(&wtm);     tm.tm_year     = wtm.wYear - 1900;     tm.tm_mon     = wtm.wMonth - 1;     tm.tm_mday     = wtm.wDay;     tm.tm_hour     = wtm.wHour;     tm.tm_min     = wtm.wMinute;     tm.tm_sec     = wtm.wSecond;     tm. tm_isdst    = -1;     clock = mktime(&tm);     tp->tv_sec = clock;     tp->tv_usec = wtm.wMilliseconds * 1000;     return (0); } #endif /* WIN32 */ using std::stringstream; using std::vector; using std::string; using std::fstream; void help(); // 调用使用帮助 bool isdigit(const std::string& str); // overload function  重载函数 bool isalpha(const std::string& str); stringstream& load_sstream(stringstream& oss, fstream& infile);  // 加载文件到sstream vector<string> & sortVecData(vector<string> & vecData); // 排序和删除重复   int main(int argc, char* argv[]) {     using namespace std;     if ((1 == argc) || (2 == argc)) {    //错误输入处理         help();         return -1;     }     string Value = argv[1];     fstream inFile;     inFile.open(argv[2], ios_base::in);     if (!inFile) {         cerr << "文件错误：不能打开输入文件: " << argv[2] << endl << endl ;         help();         return -1;     }     bool sortData = false;     // 排序开关     if (argc >= 4 && ('s' == argv[3][1] || 'S' == argv[3][1])) {         sortData = true;     }       stringstream oss;     ofstream ofDataFile;     ofDataFile.open("LineData.txt"); //保存到 新的数据档文件     long ixold = 0, ixnew = 0;     string::size_type pos;     string  strLine;     vector<string> vecLine;     cout << "当前搜索关键字：" << Value << endl;     // 取时间断点     timeval tv;     gettimeofday(&tv, NULL);     double cl = tv.tv_sec + (double)tv.tv_usec / 1000000;       while (getline(inFile , strLine)) {  // 整行处理，数据文件 数据输入         if (strcmp(argv[1] , "ALL")  == 0 ) {   // 所有数据排序用             vecLine.push_back(strLine);         } else {             pos = strLine.find(Value);             if (pos != string::npos) {                 vecLine.push_back(strLine);      //数据记录到容器             }         }           ixold++;  // 旧数据计数器         if (ixold % 100000 == 0) cout << ">";     }       gettimeofday(&tv, NULL);     cl = (tv.tv_sec + (double)tv.tv_usec / 1000000) - cl;     cout << "\n原来数据记录数目：" << ixold << "\t";     cout << "新的数据记录数目：" << vecLine.size() << endl;     cout << "提取数据花费时间：" << cl << " 秒\n";       if (sortData) {  // 判断排序         cout << "正在排序优化中，请等候....\n";         gettimeofday(&tv, NULL);         cl = tv.tv_sec + (double)tv.tv_usec / 1000000;           sortVecData(vecLine);  //数据排序 删除重复         cout << "排序优化后数据量：" << vecLine.size() << "\t";         gettimeofday(&tv, NULL);         cl = (tv.tv_sec + (double)tv.tv_usec / 1000000) - cl;         cout << "排序数据花费时间：" << cl << " 秒\n";     }     cout << "正在把数据写到新文件中......\t如果数据重复,可以最后加参数 -S 优化排序\n" ;     gettimeofday(&tv, NULL);     cl = tv.tv_sec + (double)tv.tv_usec / 1000000;     vector<string>::iterator iter = vecLine.begin();     while (iter != vecLine.end()) {         oss << *iter++ << endl;  // 数据写到缓存流         if (ixnew++ % 100000 == 0) cout << "<";    //新数据计数器     }     ofDataFile << oss.str();   // 缓冲区写文件     gettimeofday(&tv, NULL);     cl = (tv.tv_sec + (double)tv.tv_usec / 1000000) - cl;     cout << "保存新数据文件花费时间：" << cl << " 秒\n";     cout << "\n已经生成新的包含关键字的数据文件 LineData.txt" << endl;     inFile.close();     ofDataFile.close();     return 0; } // overload function  重载函数 isdigit bool isdigit(const std::string& str) {     bool flag = true;     for (std::string::size_type i = 0; i < str.length(); i++) {         while (!isdigit(str[i])) {             flag = false;             break;         }     }     return flag; } bool isalpha(const std::string& str) {     bool flag = true;     for (std::string::size_type i = 0; i < str.length(); i++) {         while (!isalpha(str[i])) {             flag = false;             break;         }     }     return flag; } void help() {     using std::cerr;     cerr << "本工具可以从文件中按关键字搜索数据行 并且有排序功能 [版本 0.98] BY Hong Wenjun\n\n";     cerr << "示例 1 ：D:\\>LineExtraction.exe  \"关键字\"  D:\\原始数据.txt  \n" ;     cerr << "示例 2 ：D:\\>LineExtraction.exe  \"关键字\"  D:\\原始数据.txt  -S\n" ;     cerr << "示例 3 ：D:\\>LineExtraction.exe    ALL     D:\\原始数据.txt  -S\n\n" ;     cerr << "请输入一个关键字！！[ \"关键字\"    ALL    ] 按两种方式选择一种\n";     cerr << "ALL 关键字  提取所有数据，和-S参数配合排序\n";     cerr << "-S  参数   排序优化，删除重复数据\n"; }   stringstream& load_sstream(stringstream& oss, fstream& infile)  // 加载文件到sstream {     oss << infile.rdbuf();     return oss; }   vector<string> & sortVecData(vector<string> &vecData) // 排序和删除重复 数字序列 {     sort(vecData.begin(), vecData.end());  //数据排序     vector<string>::iterator end_unique = unique(vecData.begin(), vecData.end());  // 移动重复到最后     vecData.erase(end_unique, vecData.end());  //删除重复     return vecData; }  看你的文件多大    280M的 600W记录某站 数据档，使用这个程序所有记录排序 写文件时，使用大内存缓冲，代价是多使用1G内存

几十万条数据，估计一二百兆，不想用数据库，可以用内存映射文件 具体请查msdn

放出 示例的 几行出来看下，可以用不相关 代替文字信息

引用 10 楼 sys0613 的回复:[quote=引用 8 楼 cfjtaishan 的回复:] [quote=引用 5 楼 sys0613 的回复:] [quote=引用 2 楼 cfjtaishan 的回复:] 如果将所有的数据从文件里读取，然后再排序，确实很占内存，数据项目多，排序也会比较耗时。 是否可以根据ID的特点，比如ID是从1到多少，先从文件里读，若读到ID为1的，则写入B文件，读到ID位2的写入文件，然后记录一下目前B文件里的ID号，每次写B文件前，先从内存里查找是否已经符合写文件的ID，若没有继续从A文件里读，若读到直接写B文件，若没有继续读； 比如,读到的ID信息的顺序是 3 4 7 8 1，此时将ID位1的信息写入B文件，记录目前B文件里的ID，接下来从已经读到的缓存里查找2，若没有继续从文件里读；知道读到ID为2，写入B文件，然后从已经读到的文件里查找3。。。 这样的好处是，可以减少内存里的消耗，还能减少排序的耗时，但是有个缺点，ID需要符合已经规律； 根据你的ID信息来确定我的方法是否可行了。 谢谢您了，我这个id很大可能是倒序，如果先都存到内存中，每轮进到内存中去扫描，还是相当于将剩下数据扫描了一遍吧？这种场景是不是就效率没变啊？[/quote] 要看你的文件里ID是否位倒序，如果是完全的倒序那么效率没怎么提高 如果是完全的倒序，如果占用内存很多，想用时间换空间，可以考虑写入多个文件，每个文件是有序的。最后再将文件集中到一个文件里。这个会比较麻烦，但也是一种办法[/quote]  谢谢您了，我现在是想用空间换时间，目前执行的太慢了[/quote] 我说反了，写入多个文件是以空间换时间；数据量大，排序会很占时间，另外，你的数据放在局部数组里还是全局数组或者在堆上申请的空间，另外，你的排序是用什么方法，可以考虑用快排或者堆排实现

引用 9 楼 hdt 的回复:[quote=引用 7 楼 sys0613 的回复:] [quote=引用 6 楼 hdt 的回复:] 个人感觉这样的情况还是把数据导入到数据库里面处理比较好！ 就是将文件中的数据都存到数据库中，然后利用数据库进行排序？因为这个id只是一条数据中的一项，一条数据有好多属性，id只是作为排序的关键字了。 唉，不知道不用数据库的话能不能提高点效率呢。好尴尬。今天跑70w数据，直接就没看到结束。。强制停止了。。。[/quote] 如果文本文件的格式比较规范，完全可以通过数据库自带的工具导入到数据库中。几十万数对于像oracle,mssql之类数据库，完全是小case[/quote] 现在是想用最少的软件来完成此项工作，两个文件的交互不想带上数据库。如果纯两个文件来排序，不用数据库的话有什么更好的办法么？谢谢了

引用 8 楼 cfjtaishan 的回复:[quote=引用 5 楼 sys0613 的回复:] [quote=引用 2 楼 cfjtaishan 的回复:] 如果将所有的数据从文件里读取，然后再排序，确实很占内存，数据项目多，排序也会比较耗时。 是否可以根据ID的特点，比如ID是从1到多少，先从文件里读，若读到ID为1的，则写入B文件，读到ID位2的写入文件，然后记录一下目前B文件里的ID号，每次写B文件前，先从内存里查找是否已经符合写文件的ID，若没有继续从A文件里读，若读到直接写B文件，若没有继续读； 比如,读到的ID信息的顺序是 3 4 7 8 1，此时将ID位1的信息写入B文件，记录目前B文件里的ID，接下来从已经读到的缓存里查找2，若没有继续从文件里读；知道读到ID为2，写入B文件，然后从已经读到的文件里查找3。。。 这样的好处是，可以减少内存里的消耗，还能减少排序的耗时，但是有个缺点，ID需要符合已经规律； 根据你的ID信息来确定我的方法是否可行了。 谢谢您了，我这个id很大可能是倒序，如果先都存到内存中，每轮进到内存中去扫描，还是相当于将剩下数据扫描了一遍吧？这种场景是不是就效率没变啊？[/quote] 要看你的文件里ID是否位倒序，如果是完全的倒序那么效率没怎么提高 如果是完全的倒序，如果占用内存很多，想用时间换空间，可以考虑写入多个文件，每个文件是有序的。最后再将文件集中到一个文件里。这个会比较麻烦，但也是一种办法[/quote]  谢谢您了，我现在是想用空间换时间，目前执行的太慢了


Question: 新手学习：请问我输入一个数组，然后从到大排序输出，为什么不出结果呢？

#include <stdio.h>  int main() {     int a[10] = { 0 };     int i, j, t;      printf("Please enter the array:\n");     for (i = 0; i < 10; i++)         scanf_s("%d", &a[i]);     printf("The sorted array:\n");     for(i=0;i<10;i++)         printf("%d ",a[i]);     for (i = 0; i < 9; i++)     {         for (j = i + 1; j <10; j++)             if (a[i] > a[j])             {                 t = a[i];                 a[i] = a[j];                 a[j] = t;             }     }     printf("The order is:\n");     for (i = 0; i <= 9; i++)         printf("%2d ", a[i]);     printf("\n");     getchar(); } 需要连续输入10个整数，以空格分开； 建议看一下输入的数是否够10个。

把getchar()去掉了，直接ctrl+f5调试就好了。谢谢各位！

二楼大神代码可以打印出来,你是不是要加system("pause");

逐过程调试都可以通过，且输入、赋值、排序都没问题，但最终结果就是不能打印出来。

好像不对哦！

错误在第7行，输入函数书写错误，去掉取地址符。


Question: 数值计算的程序跑的很慢是怎么回事啊？

原因可能是多个，建议贴出相关的代码，然后具体问题具体分析

你换个超级计算机

大量的循环计算，频繁的IO操作都有可能，你发代码上来才好分析。

可能很多原因，比如算法不好，循环太多

代码还挺复杂，这么多循环嵌循环的，慢是正常的了。你可以在关键位置输出一下时间，统计一下最终哪一部分耗费时间最多，再考虑优化。  如果算法没多少优化空间了，考虑一下多线程吧。

还有我之前发的那个帖子，你给我回复了，两个程序的区别是什么？谢谢

逻辑看着好复杂。 另外，有这么多循环（while（1）和for）怎么能不跑的慢； 建议优化一下程序吧； 不要把所有功能代码都写到main函数里，这样很不容易理解代码逻辑，另外，代码看着也很臃肿； 变量一下子定义这么多，如果变量能够复用的就要复用。比如循环变量，就用i, j, k就好了，基本上就够了。

#include <stdio.h> #include <stdlib.h> #include <math.h> #define r    3.14159265358979 #define pi  3.14159265358979 #define ex  0.000001 #define h   0.01 #define a   0 #define b   300 #define n   4 #define um 2.0 #define uc  0.05 #define uk  6.6 #define q  0.2 #define f0  0.8 #define uv  0.1 #define us  0.1 #define td  0.05 #define fu1 1.0               //摩擦力1，定值fu1=1.0 #define fu2 1 / (1 + um)      //摩擦力2，fu1 > fu2       /************Coulomb model************/ double fp1(double k)   //fp1=sign， k=c[3] { 	if (k > ex) 		return fu1; 	else if (k < -ex) 		return -fu1; 	else 		return 0.0; }  double fp2(double s, double z)    //s = c[1], z = c[3] { 	if (s - z > ex) 		return fu2; 	else if (s - z < -ex) 		return -fu2; 	else 		return 0.0; }  dun(double f[n], double t, double w1, double r1, int b1, int b2, int b3, int b4, int b5, int b6) { 	double g[n]; int i; 	g[0] = f[1]; 	g[1] = (b1 + b2)*(f0*cos(w1*t + r1) + (f[2] - f[0]) + 2 * uc*(f[3] - f[1]) - fp2(f[1], f[3])) 		+ (b3 + b6)*((f0*cos(w1*t + r1) - fp1(f[3])) / (1 + um)) 		+ (b4 + b5)*(f0*cos(w1*t + r1) + (f[2] - f[0]) + 2 * uc*(f[3] - f[1]) + uk*(f[2] - f[0] + q) - fp2(f[1], f[3])); 	g[2] = (b2 + b5)*f[3] + (b3 + b6)*f[1]; 	g[3] = b2*(((f[0] - f[2]) + 2 * uc*(f[1] - f[3]) + fp2(f[1], f[3]) - fp1(f[3])) / um) 		+ (b3 + b6)*((f0*cos(w1*t + r1) - fp1(f[3])) / (1 + um)) 		+ b5*(((f[0] - f[2]) + 2 * uc*(f[1] - f[3]) + uk*(f[0] - f[2] - q) + fp2(f[1], f[3]) - fp1(f[3])) / um); 	for (i = 0; i<n; i++) 		f[i] = g[i]; }

main() { 	int i, m, j = 0, b1, b2, b3, b4, b5, b6; 	double k[n], c[n], sum[n], e2[n], h1, h2, x, x1, x2, y1, y2, y3, w1, r1 = r;  	FILE* fp1; 	fp1 = fopen("模型二-相图.txt", "w");  	for (i = 0; i<n; ++i) 		c[i] = 0;  	b1 = 1; b2 = 0; b3 = 0; b4 = 0; b5 = 0; b6 = 0;  	for (w1 = 0.6; w1 <= 0.6; w1 = w1 + 0.001) 	{ 		printf("%lf\n", w1); 		x = x1 = y2 = y3 = a; 		h1 = h; 		h2 = h / 2;  		m = 0;  		while (w1*x <= 10000) 		{ 			//printf("%lf\n", w1*x); 			for (j = 0; j < n; j++) 			{ 				k[j] = c[j]; e2[j] = c[j]; 			} 			y1 = x; 			y3 = y2; 			if (h1 < 0.005) 				h1 = h;  			h2 = h1 / 2; 			lk(c, h1, x, w1, r1, b1, b2, b3, b4, b5, b6); 			lk(e2, h2, x, w1, r1, b1, b2, b3, b4, b5, b6); 			x1 = x + h2; 			lk(e2, h2, x1, w1, r1, b1, b2, b3, b4, b5, b6);  			while (norm1(e2, c, ex)) 			{ 				h1 = h2; 				h2 = h2 / 2; 				for (j = 0; j < n; j++) 				{ 					c[j] = k[j]; e2[j] = k[j]; 				} 				lk(c, h1, x, w1, r1, b1, b2, b3, b4, b5, b6); 				lk(e2, h2, x, w1, r1, b1, b2, b3, b4, b5, b6); 				x1 = x + h2; 				lk(e2, h2, x1, w1, r1, b1, b2, b3, b4, b5, b6); 			}  			for (i = 0; i<n; i++) 				c[i] = (16 * e2[i] - c[i]) / 15.0;  			x = x + h1; 			y2 = y2 + h1; 			/**************************************************/ 			if ((k[0] - k[2]) - q < -ex && (c[0] - c[2]) - q > ex) 			{ 				x = y1;  y2 = y3; 				for (i = 0; i < n; i++) 					c[i] = k[i];  				while (1) 				{ 					lk(c, h1, x, w1, r1, b1, b2, b3, b4, b5, b6); 					while ((c[0] - c[2]) - q > ex) 					{ 						h1 = h1 / 2; 						for (i = 0; i < n; i++) 							c[i] = k[i]; 						lk(c, h1, x, w1, r1, b1, b2, b3, b4, b5, b6); 					} 					if ((c[0] - c[2]) - q >= -ex) 					{ 						x = x + h1; y2 = y2 + h1; break; 					} 					for (i = 0; i < n; i++) 						k[i] = c[i]; 					x = x + h1; 					y2 = y2 + h1; 				} 			} 			/**************************************************/ 			if ((k[0] - k[2]) - q > ex && (c[0] - c[2]) - q < -ex) 			{ 				x = y1;  y2 = y3; 				for (i = 0; i < n; i++) 					c[i] = k[i];  				while (1) 				{ 					lk(c, h1, x, w1, r1, b1, b2, b3, b4, b5, b6); 					while ((c[0] - c[2]) - q < -ex) 					{ 						h1 = h1 / 2; 						for (i = 0; i < n; i++) 							c[i] = k[i]; 						lk(c, h1, x, w1, r1, b1, b2, b3, b4, b5, b6); 					} 					if ((c[0] - c[2]) - q <= ex) 					{ 						x = x + h1; y2 = y2 + h1; break; 					} 					for (i = 0; i < n; i++) 						k[i] = c[i]; 					x = x + h1; 					y2 = y2 + h1; 				} 			} 			/**************************************************/ 			if (k[3] > ex && c[3] < -ex) 			{ 				x = y1;  y2 = y3; 				for (i = 0; i < n; i++) 					c[i] = k[i];  				while (1) 				{ 					lk(c, h1, x, w1, r1, b1, b2, b3, b4, b5, b6); 					while (c[3] < -ex) 					{ 						h1 = h1 / 2; 						for (i = 0; i < n; i++) 							c[i] = k[i]; 						lk(c, h1, x, w1, r1, b1, b2, b3, b4, b5, b6); 					} 					if (c[3] <= ex) 					{ 						x = x + h1; y2 = y2 + h1; break; 					} 					for (i = 0; i < n; i++) 						k[i] = c[i]; 					x = x + h1; 					y2 = y2 + h1; 				} 			} 			/**************************************************/ 			if (k[3] < -ex && c[3] > ex) 			{ 				x = y1;  y2 = y3; 				for (i = 0; i < n; i++) 					c[i] = k[i];  				while (1) 				{ 					lk(c, h1, x, w1, r1, b1, b2, b3, b4, b5, b6); 					while (c[3] > ex) 					{ 						h1 = h1 / 2; 						for (i = 0; i < n; i++) 							c[i] = k[i]; 						lk(c, h1, x, w1, r1, b1, b2, b3, b4, b5, b6); 					} 					if (c[3] >= -ex) 					{ 						x = x + h1; y2 = y2 + h1; break; 					} 					for (i = 0; i < n; i++) 						k[i] = c[i]; 					x = x + h1; 					y2 = y2 + h1; 				} 			} 			/**************************************************/ 			if (k[1] - k[3] > ex && c[1] - c[3] < -ex) 			{ 				x = y1;  y2 = y3; 				for (i = 0; i < n; i++) 					c[i] = k[i];  				while (1) 				{ 					lk(c, h1, x, w1, r1, b1, b2, b3, b4, b5, b6); 					while (c[1] - c[3] < -ex) 					{ 						h1 = h1 / 2; 						for (i = 0; i < n; i++) 							c[i] = k[i]; 						lk(c, h1, x, w1, r1, b1, b2, b3, b4, b5, b6); 					} 					if (c[1] - c[3] <= ex) 					{ 						x = x + h1; y2 = y2 + h1; break; 					} 					for (i = 0; i < n; i++) 						k[i] = c[i]; 					x = x + h1; 					y2 = y2 + h1; 				} 			} 			/**************************************************/ 			if (k[1] - k[3] < -ex && c[1] - c[3] > ex) 			{ 				x = y1;  y2 = y3; 				for (i = 0; i < n; i++) 					c[i] = k[i];  				while (1) 				{ 					lk(c, h1, x, w1, r1, b1, b2, b3, b4, b5, b6); 					while (c[1] - c[3] > ex) 					{ 						h1 = h1 / 2; 						for (i = 0; i < n; i++) 							c[i] = k[i]; 						lk(c, h1, x, w1, r1, b1, b2, b3, b4, b5, b6); 					} 					if (c[1] - c[3] >= -ex) 					{ 						x = x + h1; y2 = y2 + h1; break; 					} 					for (i = 0; i < n; i++) 						k[i] = c[i]; 					x = x + h1; 					y2 = y2 + h1; 				} 			} 			/***********Poincare截面***********/ 			if ((c[0] - c[2]) - q >= -ex && (c[0] - c[2]) - q <= ex && c[1] - c[3] > ex) 			{ 				m = m + 1; 				if (m == 200) 				{ 					r1 = w1*x + r1; 					while (r1 >= 2 * pi) 						r1 = r1 - 2 * pi; 					x = a; 					c[0] = c[0] - c[2]; 					c[2] = 0.0; 				} 			} 			/***********(1)m1与plate分别自由振动，capsule静止***********/ 			/***********(2)m1与plate分别自由振动，capsule运动***********/ 			if ((c[0] - c[2]) - q < -ex) 			{ 				if (fabs(c[3]) > ex) 				{ 					if (fabs(c[1] - c[3]) > ex) 					{ 						b1 = 0; 						b2 = 1; 						b3 = 0; 						b4 = 0; 						b5 = 0; 						b6 = 0; 					} 					else 					{ 						if (fabs(f0*cos(w1*x + r1) + (c[2] - c[0]) + 2 * uc*(c[3] - c[1])) <= fu2) 						{ 							b1 = 0; 							b2 = 0; 							b3 = 1; 							b4 = 0; 							b5 = 0; 							b6 = 0; 							c[1] = c[3]; 						} 						else 						{ 							b1 = 0; 							b2 = 1; 							b3 = 0; 							b4 = 0; 							b5 = 0; 							b6 = 0; 							c[1] = c[3]; 						} 					} 				} 				else 				{ 					if (fabs(c[1] - c[3]) > ex) 					{ 						if (fabs((c[0] - c[2]) + 2 * uc*(c[1] - c[3]) + fp2(c[1], c[3])) <= fu1)  						{ 							b1 = 1; 							b2 = 0; 							b3 = 0; 							b4 = 0; 							b5 = 0; 							b6 = 0; 							c[3] = 0.0; 						} 						else 						{ 							b1 = 0; 							b2 = 1; 							b3 = 0; 							b4 = 0; 							b5 = 0; 							b6 = 0; 							c[3] = 0.0; 						} 					} 				} 			} 			/***********(3)m1冲击plate后发生粘滞，capsule静止***********/ 			/***********(4)m1冲击plate后发生粘滞，capsule运动***********/ 			if ((c[0] - c[2]) - q >= -ex  && uk*(c[0] - c[2] - q) > 0) 			{ 				if (fabs(c[3]) > ex) 				{ 					if (fabs(c[1] - c[3]) > ex) 					{ 						b1 = 0; 						b2 = 0; 						b3 = 0; 						b4 = 0; 						b5 = 1; 						b6 = 0; 					} 					else 					{ 						if (fabs(f0*cos(w1*x + r1) + (c[2] - c[0]) + 2 * uc*(c[3] - c[1]) + uk*(c[2] - c[0] + q)) <= fu2) 						{ 							b1 = 0; 							b2 = 0; 							b3 = 0; 							b4 = 0; 							b5 = 0; 							b6 = 1; 							c[1] = c[3]; 						} 						else 						{ 							b1 = 0; 							b2 = 0; 							b3 = 0; 							b4 = 0; 							b5 = 1; 							b6 = 0; 							c[1] = c[3]; 						} 					} 				} 				else 				{ 					if (fabs(c[1] - c[3]) > ex) 					{ 						if (fabs((c[0] - c[2]) + 2 * uc*(c[1] - c[3]) + uk*(c[0] - c[2] - q) + fp2(c[1], c[3])) <= fu1) 						{ 							b1 = 0; 							b2 = 0; 							b3 = 0; 							b4 = 1; 							b5 = 0; 							b6 = 0; 							c[3] = 0.0; 						} 						else 						{ 							b1 = 0; 							b2 = 0; 							b3 = 0; 							b4 = 0; 							b5 = 1; 							b6 = 0; 							c[3] = 0.0; 						} 					} 				} 			} 			/********************************************/ 			if (m >= 200) 			{ 				fprintf(fp1, "%lf\t%lf\t%lf\t%lf\t%lf\t%lf\t%lf\n", w1, w1*x, c[0], c[2], c[0] - c[2], c[1] - c[3], c[3]); 			} 			if (m >= 200 && w1*x >= 30) 				break; 			/********************************************/ 			/* 			if (x >= 44) 			fprintf(fp1, "%lf\t%lf\t%lf\t%lf\t%lf\t%lf\t%lf\n", w1, x, c[0], c[2], c[0] - c[2], c[1] - c[3], c[3]); 			/********************************************/ 		} 	} 	fclose(fp1); 	system("pause"); }


Question: 求助，链表输出乱码

引用 2 楼 cfjtaishan 的回复:#include <stdio.h> #include <stdlib.h> #include <string.h>  struct book //链表结构声明 {     char name[32];     char phone[12];     char address[32];     struct book *next; }; typedef struct book BOOK;  BOOK *create() //创建链表并将文件内的内容赋给链表 {      FILE *fp;     BOOK *head, *ptr, *p; //链表的节点     head = (BOOK *)malloc(sizeof(BOOK)); //分配内存     if (!head)     {         printf("内存分配失败\n");         exit(1);     }     char nh[100],deli[]="\\";     char *buf = NULL;     if ((fp=fopen("date.dat","r"))==NULL)     {         exit(1);     }     //初始化head     strcpy(head->name, "姓名");     strcpy(head->phone, "电话");     strcpy(head->address, "地址");     head->next = NULL;     ptr = head;     while (!feof(fp)) //将后面行的字符串分割赋给链表     {         p = (BOOK *)malloc(sizeof(BOOK));         if (!p)         {             exit(1);         }         fgets(nh, 100, fp);         buf = strtok(nh, deli);         if (!buf)             continue;         strcpy(p->name,  buf);         buf = strtok(NULL, deli);         if (!buf)             continue;         strcpy(p->phone, buf);         buf = strtok(NULL, deli);         if (!buf)             continue;         strcpy(p->address, buf);         p->next = ptr->next;         ptr->next = p;         ptr = ptr->next;     }     return head; }  void PrintNode(BOOK *ptr) //链表输出 {     while (ptr) //链表遍历循环     {         printf("%s\t%s\t%s\n",ptr->name,ptr->phone,ptr->address); //输出节点数据         ptr = ptr->next; //指向下一个节点     }     printf("\n"); }  int main() {     BOOK *head;     head = create();     PrintNode(head);     system("pause"); }非常感谢，原来问题是字符串赋给链表的时候出问题了

岐岐\12345678901\岐岐家	 叽叽\12345678901\叽叽家	 溜溜\12345678901\溜溜家 这是文件里的内容   用 while (!feof(fp)) 	{ 		fgets(ch, 100, fp); 		se=strtok(ch, de); 		printf("%s\n", se); 		se = strtok(NULL, de); 		printf("%s\n", se); 		se = strtok(NULL, de); 		printf("%s\n", se); 	} 输出又没问题


Question: c文件i/o 不知道写的这段程序哪里有问题，写到记事本上都是乱码

引用 5 楼 zhao4zhong1 的回复:[quote=引用 4 楼 cfjtaishan 的回复:] 只有int类型的ch才能与EOF匹配。因为EOF是int类型的。 根本原因其实是 EOF被宏定义为-1 char的范围通常是-128..127 int的范围通常是-32768..32767或-2147483648..2147483647 如果读到字符'\xff'，使用char，会被误认为是-1即EOF；使用int，因为是255而不会被误认为是-1即EOF。[/quote] 对，是啊，就是这样呢；

引用 4 楼 cfjtaishan 的回复:只有int类型的ch才能与EOF匹配。因为EOF是int类型的。 根本原因其实是 EOF被宏定义为-1 char的范围通常是-128..127 int的范围通常是-32768..32767或-2147483648..2147483647 如果读到字符'\xff'，使用char，会被误认为是-1即EOF；使用int，因为是255而不会被误认为是-1即EOF。

只有int类型的ch才能与EOF匹配。因为EOF是int类型的。

改一下两个地方， 第一个地方： while((ch=getc(fp))!=EOF) 根据优先级，=的优先级低于!=判断的优先级；所以getc(fp) != EOF先执行，然后将结果（判断结果，1或0）返给ch，所以写入文件里的都是1（数值）  第二个地方，ch的类型，改成int类型；

如楼上 while((ch=getc(fp))  !=EOF) //这里加个括号

void copy(char file1[],char file2[]) { 	FILE *fp,*fp2; 	char ch; 	if((fp=fopen(file1,"r"))==NULL) 	{ 		printf("file1 open failed\n"); 		getchar(); 		exit(0); 	} 	if((fp2=fopen(file2,"w"))==NULL) 	{ 		printf("file2 open failed\n"); 		getchar(); 		exit(0); 	} 	while((ch=getc(fp))  !=EOF) //这里加个括号 	{ 		fputc(ch,fp2); 	} 	fclose(fp); 	fclose(fp2); } //----------- while((ch=getc(fp))  !=EOF) //这里加个括号


Question: for循环的条件

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

引用 1楼user-4 的回复:第一个for的最后， *p可能是\n。 看起来p--是跳过这个\n。但是代码还有其他问题。  下次不要贴图片。不方便。好的，下次不贴图了。。。求解还有什么问题

上一个p指向了'\n'，所以在你循环时，不需要输出'\n'，将p--使其指向'\n'的前一个字符；

上一个循环p多加一 所以这个先p-- 让其回来


Question: VisualCode无法识别ANSI颜色

搜“ANSI.SYS”

windows不支持  #include <stdio.h> #include <windows.h>  int main() {     HANDLE hdl = GetStdHandle(STD_OUTPUT_HANDLE);     SetConsoleTextAttribute(hdl, FOREGROUND_RED | FOREGROUND_INTENSITY);     printf("Hello ");     SetConsoleTextAttribute(hdl, FOREGROUND_GREEN | FOREGROUND_INTENSITY);     printf("world!\n");      getchar(); }


Question: 新手求助，bin文件转换为数组文件输出

仅供参考：#include <stdio.h> #include <string.h> #include <conio.h> FILE *fi,*fo; unsigned int n; int c; //------------------------------------------------------- void main(int argc,char *argv[]) {     if (argc<3) {         cprintf("Bin2Hex srcfile desfile");         return;     }     if ((fi=fopen(argv[1],"rb"))==NULL) {         cprintf("Can not find file %s",argv[1]);         return;     }     if ((fo=fopen(argv[2],"w"))==NULL) {         fclose(fi);         cprintf("Can not create file %s",argv[2]);         return;     }     n=0;     while (1) {         c=fgetc(fi);         if (EOF==c) break;         n++;         if (1==n)        fprintf(fo,  "0x%02X",c);         else {             if (1==n%16) fprintf(fo,"\n0x%02X",c);             else         fprintf(fo, ",0x%02X",c);         }     }     fcloseall();     cprintf("OK to Bin2Hex %u bytes.",n); }

不好意思，可能需要纠正一下，读二进制用fread，即以下这行：  		fscanf(fp, "%c%c%c", &temp_data[0], &temp_data[1], &temp_data[2]);  替换为：  		fread(&temp_data, 3, 1, fp);

只是按思路写了出来，没有测试，仅供参考。你自己调试和完善吧。   #include <stdio.h> #include <stdlib.h>  typedef struct _data_array { 	int a; 	char b; } DATA_ARRAY;  int main(int argc, char **argv) { 	DATA_ARRAY arrays[1024]; 	FILE *fp = NULL; 	char temp_data[3] = { 0 }; 	int i = 0; 	 	fp = fopen("your path", "b"); 	if (fp == NULL) 		return -1; 	 	for (i = 0; i < 1024 && !feof(fp); i ++) 	{ 		fscanf(fp, "%c%c%c", &temp_data[0], &temp_data[1], &temp_data[2]); 		arrays[i].a = temp_data[1] << 8 + temp_data[0]; 		arrays[i].b = temp_data[2]; 	} 	 	return 0; }

有没有大神给些代码啊，要不小弟要被被人叼了

#include <stdio.h> #include <fcntl.h> #include <malloc.h> #include <io.h> #include <errno.h> #include<string.h> #include<sys/types.h> #include<unistd.h> #include<stdlib.h> #include <fcntl.h> #include <malloc.h> #include <io.h> #include <errno.h>  #define  DEST_FILE  "1.h" #define  SRC_FILE   "1.bin" 1 int main(void) { 	FILE* fpSrc; 	Int32 fpSrcTmp,fpDest; 	Int32 fpDestStm; 	char *array = "static const S_Config_first[] = \n{"; 	  	if(!(access(DEST_FILE,0)<0)) 	{ 		 		system("1.h -R"); 		remove("1.h"); 	}  	 if((fpSrcTmp = open(SRC_FILE, O_RDONLY | O_BINARY)) == -1) 	{ 	 		puts("1.bin 不存在，按任意键退出"); 		getch(); 		return 0; 	} 	close(fpSrcTmp);  	fpDest = open("1.h", O_RDWR|O_BINARY|O_CREAT); 	if(fpDest==-1) 	{ 	    printf("errno=%d\n",errno); 	     	    puts("创建文件失败1.h,请重新尝试，按任意键退出！"); 	    getch(); 	    return 0; 	}  	fpSrc = fopen(SRC_FILE,"r"); 	while(!feof(fpSrc)) 	{     	} 我写到这里就不会写了

自己先写个小程序去读这个bin文件，然后按你要的格式输出成文本，然后再复制到你的数组那里

引用 1 楼 hzy_76 的回复:按二进制打开文件，然后按一个双字节整数一个char型的方式循环读取至文件结束。可以给些代码吗，我比新手还菜啊

按二进制打开文件，然后按一个双字节整数一个char型的方式循环读取至文件结束。


Question: c51，数码管，大佬围观

主要改动了显示函数和主函数，亲测有效！  #include <reg52.h> #define uchar unsigned char #define uint unsigned int #define LED P0//段选线									    /*********我使用的是开发板，硬件连接是，两个573锁存器左边接P0口 **********和位选 段选（一个接位选 一个接段选）通过软件切换段选 位选*******/ sbit  du_EN = P2^6;//段选线   sbit  we_EN = P2^7;//位选线  uint num;  sbit key_up = P3^0;//开关  使用的是开发板硬件连接的按键 sbit key_down = P3^1; uchar code dis_code[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,//段码表0,1,2,3,4,5,6,7 0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71,0x00,0x40};//段码表8,9,a,b,c,d,e,f,灭(16)，-(17) unsigned char SegBuf[2]={0}; //---延时函数---// void delayled(uchar N) {    uchar i,j;    for(i=0;i<N;i++)    for(j=0;j<125;j++); } //---填充显示缓冲区函数---// void convert(uint n)	  { 	SegBuf[0] =n%10;  	SegBuf[1] =n/10%10; } //---显示函数---// void display(void) { 	du_EN = 1; 	LED=dis_code[SegBuf[1]];	  	du_EN = 0; 	P0 = 0xff; 	we_EN = 1; 	P0 = 0xfe; 	we_EN = 0; 	delayled(5);  	 	du_EN = 1; 	LED=dis_code[SegBuf[0]];	  	du_EN = 0; 	P0 = 0xff; 	we_EN = 1; 	P0 = 0xfd; 	we_EN = 0; 	delayled(5); } //---显示数据---// void Disp(uint n)  { 	convert(n); 	display() ; } //---主函数---// void main() { 	num=0;//开始显示的数字为0 	while(1) 	{   		Disp(num); 		if(key_up == 0) 		{ 			delayled(10); 			if(key_up == 0) 			{ 				while(!key_up) 				{ 					display(); 				} 				num++; 			} 		}  		if(key_down == 0) 		{ 			delayled(10); 			if(key_down == 0) 			{ 				while(!key_down) 				{ 					display(); 				} 				num--; 			} 		} 	     }   }

引用 5 楼 zhao4zhong1 的回复:参考《编译原理》中的词法分析和有限状态自动机。 仅供参考：//有字符串 //1_22_333,,4444__55555,_666666 //需要解析为 //1 //22 //333 //_ //4444 //55555 //666666 #include <stdio.h> char s[]="1_22_333,,4444__55555,_666666"; char c,*p,*p1; int st; void main() {     st=0;     p=s;     while (1) {         c=*p;         if (0==c) {             switch (st) {             case 1:printf("_\n");    break;             case 2:printf("%s\n",p1);break;             }             break;//         }         switch (st) {         case 0:                  if ('_'==c) {                            st=0;}             else if (','==c) {                            st=1;}             else             {p1=p;                       st=2;}         break;         case 1:                  if ('_'==c) {                            st=1;}             else if (','==c) {printf("_\n");              st=1;}             else             {p1=p;                       st=2;}         break;         case 2:                  if ('_'==c) {*p=0;printf("%s\n",p1);*p=c;st=0;}             else if (','==c) {*p=0;printf("%s\n",p1);*p=c;st=1;}             else             {                            st=2;}         break;         }         p++;     } } //1 //22 //333 //_ //4444 //55555 //666666

希望老师能具体点，感谢！

感谢，但是您能针对以上代码写出减得程序吗？而不是自己重写，希望您能费下力，若合适，分将全给你了！

参考《编译原理》中的词法分析和有限状态自动机。

if(key==0) {       for(i=0;i<200;i++);     if(key==0) {     while(key==0);    num++; Disp(num);  } } if(key1==0) {       for(i=0;i<200;i++);     if(key1==0) {     while(key1==0);    num--; Disp(num);  } }

我是想再加一个key1，按一次减一，当num>=1时实现前面我说的功能，您写的这个不行，能在思考一下给我写一下吧，可以的话我把分就都给您了，再次感谢！

while (key==0)//键按下，显示，标志f0=0 {        if(key1 == 1)               num = num - 1;        Disp(num);         f0=0; }


Question: 用指针实现两个字符串连接

引用 9 楼 qq_41093250 的回复:[quote=引用 8 楼 cfjtaishan 的回复:] #include<stdio.h> #include<string.h> int main() {     char a[32]="dsad";     char *b="dsdffff";     char *p = a;     while(*p++)         ;     p--;   /*后退一个字符，指向a的'\0'*/     while(*p++ = *b++)         ;     *p = 0;    /* 添加'\0'*/      printf("%s\n",a);      return 0; } 三个问题： 1. 字符串常量不能修改，所以*a++= *b++;就会对a修改； 2. 即使a可以修改，那么*a++ = *b++;指针a已经指向了字符串的末尾，直接输出a不能将连接后的字符串输出； 3. 字符串的'\0'没有赋值给a； 你好，为什么不能printf（"%s\n",p）;[/quote] 道理是一样的，因为p指向了字符串的末尾位置。

引用 8 楼 cfjtaishan 的回复:#include<stdio.h> #include<string.h> int main() {     char a[32]="dsad";     char *b="dsdffff";     char *p = a;     while(*p++)         ;     p--;   /*后退一个字符，指向a的'\0'*/     while(*p++ = *b++)         ;     *p = 0;    /* 添加'\0'*/      printf("%s\n",a);      return 0; } 三个问题： 1. 字符串常量不能修改，所以*a++= *b++;就会对a修改； 2. 即使a可以修改，那么*a++ = *b++;指针a已经指向了字符串的末尾，直接输出a不能将连接后的字符串输出； 3. 字符串的'\0'没有赋值给a； 你好，为什么不能printf（"%s\n",p）;

引用 4 楼 qq_41093250 的回复:引用 1 楼 user-5 的回复:你的指针a指向了字面量字符串，那是不可修改的常量，不能拼接能不能详细讲讲指针指向字符串为什么不可修改呢，拜托大神  因为这个指针指向的是常量区的字符串，之所以不需要const char*是历史原因，楼主记住就行

百度 字符串常量为什么不能修改 建议 用char数组 字符串变量

引用 3 楼 paschen 的回复:你的指针是指向常量区的字符串，不能修改，否则程序会崩，如果你要修改，用字符数组的形式保存，写成：char a[100]="dsad"; 能不能详细讲讲指针指向字符串为什么不可修改呢

引用 1 楼 user-5 的回复:你的指针a指向了字面量字符串，那是不可修改的常量，不能拼接 能不能详细讲讲指针指向字符串为什么不可修改呢，拜托大神

把改成char 数组、然后用指针指向数组，应该就可以了

你的指针a指向了字面量字符串，那是不可修改的常量，不能拼接


Question: 哪位大佬帮忙解决一下呀

“多一少一”问题占程序员常犯错误的10%以上！ 避免“多一少一”问题的方法之一是将比如<10甚至<5的数代入程序片断，掰手指头心算验证一下程序到底应该写为 x、x-1、x+1中的哪个？ <、<=、==、>、>=中的哪个？  判断是否越界访问，可以在数组的最后一个元素之后对应的地址处设置数据读写断点。如果该地址对应其它变量干扰判断，可将数组多声明一个元素，并设置数据读写断点在该多出元素对应的地址上。 #include <time.h> #include <stdlib.h> #include <windows.h> int main() {     int a,b[11];//本来是b[10]，为判断哪句越界，故意声明为b[11]      srand((unsigned int)time(NULL));//按两次F11，等黄色右箭头指向本行时，调试、新建断点、新建数据断点，地址：&b[10]，字节计数：4，确定。     while (1) {//按F5，会停在下面某句，此时a的值为10，b[10]已经被修改为对应0..4之一。         b[(a=rand()%11)]=0;         Sleep(100);         b[(a=rand()%11)]=1;         Sleep(100);         b[(a=rand()%11)]=2;         Sleep(100);         b[(a=rand()%11)]=3;         Sleep(100);         b[(a=rand()%11)]=4;         Sleep(100);     }     return 0; }

发现了，是插入这里  if (index < 0 || index > Length )                 throw new IndexOutOfRangeException();

引用 5 楼 cfjtaishan 的回复: for (int i=Length ;i>index ;i--)             {                 _dataset [i]=_dataset[i-1];             } 此处有越界； i应该从Length-1开始吧 lst.Insert(3 * i, Console.ReadLine());                                 Console.WriteLine("请输入姓名:");                                 lst.Insert(3 * i + 1, Console.ReadLine());                                 Console.WriteLine("请输入成绩:");                                 lst.Insert(3 * i + 2, Console.ReadLine()); Insert函数中第一个参数可能会导致越界吧， 3 * i + 2等等

数组越界了-

for (int i=Length ;i>index ;i--)             {                 _dataset [i]=_dataset[i-1]; 数组是从0开始计数 也就是说最多就是length-1 您尽然从lenght开始访问，焉能不出错？

IndexOutOfRangeException不是你抛出的吗……


Question: 如何显示文件新增的内容[实现简单"tail -f"功能]

虽然我没有看过 tail 的源代码，但是明显 cfjtaishan 说的是对的。这个需要你自己循环的打开关闭文件，但是需要自己记录一个偏移量，二次打开的话，直接偏移到这个位置，如果后面有新增数据，就从这里开始继续读取。

tail的源代码又不是搜不到。

引用 2 楼 Freeforce_CN 的回复:[quote=引用 1 楼 cfjtaishan 的回复:] 需要重新打开，因为你在另一个终端里编辑增加的内容，这个终端上打开的文件“感知”不到。 修改文件后 特意用sync 同步过了[/quote] 程序没有重新去读文件的大小呀，所以需要先关闭，然后在打开一次，这样能获取最新的文件大小；

引用 1 楼 cfjtaishan 的回复:需要重新打开，因为你在另一个终端里编辑增加的内容，这个终端上打开的文件“感知”不到。 修改文件后 特意用sync 同步过了


Question: 请教大佬们：#ifndef 和 #program once的区别

因为新的不一定能完全淘汰旧的，所以只好新旧并存了。

#program once 不是平台相关，而是编译器相关。老的编译器不支持，至少八几年到九几年年初的都不支持，甚至零几年都有不支持的的编译器。该指令保证一个物理文件在一个源代码中只被绝对包含一次。比如 A.c 引用了 B.h 也引用了 C.h，而 C.h 里面也引用了 B.h。那么编译器保证 B.h 只被引用一次。而宏定义的方式， 仍以 B.h 为例。假定它的内容如下：#ifndef _B_H // 或 _XXX_INCLUDED 等，习惯命名，没有固定规则。 #define _B_H // 头文件体 #endif这样对于编译器而言的处理方式就是：如果没有定义常量 _B_H，就定义常量 _B_H，并引用整个头文件体。如果因为上述所说的嵌套引用导致了单个源文件中二次引用 B.h，由于第一次已经定义过 _B_H 常量，所以 #ifndef _B_H 这个判断就不成立，“定义常量 _B_H，并引用整个头文件体”这段就被跳过了。两种其实没有什么了不同，但是相对来说第一种更好的，第二种的弊端就是：一、预处理器要对要代码内容进行分析；二、保证同一个源代码引用的所有头文件中，该常量的名称不能有任何重复。因为这样的编译不是针对单个物理文件的，而是根据 _B_H 这个名字来的，如果和其他头文件的宏名字冲突了，则第二个引用的头文件可能不是物理上的同一个文件，但是仍然被排除，因此有可能导致莫名的编译错误。一般的，_B_H 的这个名字有两种规则：一是根据头文件文件名本身，加上前置一到多个下划线，全大写的文件名，以 _H 或 _INCLUDED 后缀结尾，如：_STDIO_H 或 __C_STDIO_H——当然，实际的头文件不一定如此，我只是举例。二是 IDE 自动生成，比如 VS 现在喜欢用一串随机生成的超长的名称做前缀，尽可能减少用户定义宏名称与系统的重复的可能性。如今的编译器几乎都支持 #pragma once，但也兼容老的指令，因此可能会在头文件顶部看到类似这样的内容：#pragma once #ifndef _XXX_H #define _XXX_H  // ... #endif上面这种通常出现在内置头文件，说明当前特定的编译器已支持这种语法。或者：#if _MSC_VER > 1000 #pragma once #endif #ifndef _XXX_H #define _XXX_H  // ... #endif上面这种通常出现在第三方的头文件，是因为编写头文件的人要适配任何编译器版本。这个简单例子比较常见，是判断微软 C 编译器版本不低于某个版本才使用这个功能，实际上可能有更复杂的，比如判断 Borland C++ Compiler、GCC 等，具体就不列举了。

编写几个小程序试一下，理论联系实际嘛；

以前没有#program once只有#ifndef

我感觉博客解释的不错 多自己编一些程序实践一下吧  光说说不清的

#program once 平台相关 有的平台用来方式重复包含  有的平台用不了   #ifndef 用于防止重复包含是标准内存 在标准编译器里面都可以使用   另外 #ifndef 防止重复包含 只是一个常见用法 这个预编译指令用途不只是防止重复包含  他只是检查 后面的宏有没有定义 如果对应的宏有定义  就把对应的内容删除


Question: 关于读写文件

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

看看 FILE 结构体在哪里定义的。

void writePts(const CvMat* mat, struct FILE* f) 第二个参数，应该是去掉struct，直接是FILE *f吧

你的struct FILE 并不是 标准库中的 FILE，去掉你struct FILE的定义

FILE本来就是一个结构：typedef struct XXX FILE; 前面再加struct有问题。 VS2015报错：“error C2371: “FILE”: 重定义；不同的基类型” 再看看函数writePts的声明和调用时传递的参数是否也有struct，一并去掉试试。

去掉 struct

引用第二个参数，应该是去掉struct，直接是FILE *f吧跟那个没有关系，去掉struct还是报同样的错， error C2664: “fprintf”: 不能将参数 1 从“FILE *”转换为“FILE *”


Question: 敲代码的方法

学编程，要多思考，多实践，书上看懂了尽量不看书按自己的逻辑去写，到于速度方面你可以使用一些插件，比如VS下你可以使用VAX，通常输几个字母就可以自动补全，括号缩进等都自动的

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

我觉得不要用带向导的软件，也不要经常复制粘贴代码节省时间，打代码就是要时间的积累，只有不断地练习，总结才能让个人成长-【个人见解】

另外、初学的话、尽量50行以下的代码就行了， 要么是你前面基础没打好，要么是书的难度设置不太好。

200多行代码、要是对你来说比较难的话。一个星期不算慢

引用 3 楼 cfjtaishan 的回复:个人建议是先1后2，即先抄别人的，调试别人的，改动别人的，让自己有别人的思想，思路；然后做练习时就可以运用自己了解的思路去编写；  个人也是从抄别人到熟悉别人的思路，养成编程的思维。然后再根据自己的总结，独立写出实现新需求的代码； 表述错了，个人建议先2后1；

第一遍，可以先按方法二，请注意：书上的程序不一定是对的！所以验证一遍，一来可以更好理解，二来甚至还可以知道书上的错误。但是方法一才是帮你真正学到东西的，慢也要坚持，最终你要利用学到的知识解决问题的，实际中的问题可跟书上不一样，属于方法一的提升。

刚开始从简单代码入手，我记得我的第一个代码就是输出“hello world！”，那时候并没有特别关注敲代码的方法，但只要你坚持每天撸，等你代码量上一万行时你就会发现自己的水平有了一个质的提升。


Question: 关于序列点以及副作用的问题。

另参看：关于C,C++表达式求值顺序 http://bbs.csdn.net/topics/370153775

后置的++表示：先与65比较，比较完age自加1，比较完之后，age变为了21，此时不满足后面的if，故不进行输出，又进行下一次循环....

不要迷信书、考题、老师、回帖； 要迷信CPU、编译器、调试器、运行结果。 并请结合“盲人摸太阳”和“驾船出海时一定只带一个指南针。”加以理解。 任何理论、权威、传说、真理、标准、解释、想象、知识……都比不上摆在眼前的事实！  理解和讨论之前请先学会如何观察！  计算机组成原理→DOS命令→汇编语言→C语言（不包括C++）、代码书写规范→数据结构、编译原理、操作系统→计算机网络、数据库原理、正则表达式→其它语言（包括C++）、架构……  对学习编程者的忠告： 多用小脑和手，少用大脑、眼睛和嘴，会更快地学会编程！ 眼过千遍不如手过一遍！ 书看千行不如手敲一行！ 手敲千行不如单步一行！ 单步源代码千行不如单步Debug版对应汇编一行！ 单步Debug版对应汇编千行不如单步Release版对应汇编一行！ 不会单步Release版对应汇编？在你想单步Release版C/C++代码片断的前面临时加一句DebugBreak();重建所有，然后在IDE中运行。（一般人我不告诉他！）  单步类的实例“构造”或“复制”或“作为函数参数”或“作为函数返回值返回”或“参加各种运算”或“退出作用域”的语句对应的汇编代码几步后，就会来到该类的“构造函数”或“复制构造函数”或“运算符重载”或“析构函数”对应的C/C++源代码处。  VC调试时按Alt+8、Alt+7、Alt+6和Alt+5,打开汇编窗口、堆栈窗口、内存窗口和寄存器窗口看每句C对应的汇编、单步执行并观察相应堆栈、内存和寄存器变化，这样过一遍不就啥都明白了吗。 对VC来说，所谓‘调试时’就是编译连接通过以后，按F10或F11键单步执行一步以后的时候，或者在某行按F9设了断点后按F5执行停在该断点处的时候。

%20 值在0 - 19

因为while循环比较条件时，age++是一个整体，因为其优先级高，所以先跟age结合，这样age++与65比较，即20 <= 65; 循环条件判断之后，然后age++，自然是21，所以循环体里的age是21

age++<=65 等价于 age <= 65; age += 1; age % 20 中age已经为21了


Question: 求帮助

引用 2 楼 cfjtaishan 的回复:#include <stdio.h>  int main() {     int num;     double sum = 0;      while(scanf("%d",&num)!= EOF)     {         if(num <= 70)             sum += 0.1;         else if(num > 70)         {             if(num % 70 == 0)                 sum += 0.1 * num / 70;             else                 sum += 0.1 * (num / 70 + 1);         }     }     printf("%.1lf\n", sum);      return 0; } 去掉一个头文件，逻辑可以微调一下，其他没问题； 另外，去掉一个变量，个人认为这个变量是多余的

#include <stdio.h> #include <stdlib.h> int main() {     int num;     double sum=0,sum3=0;     while(scanf("%d",&num)!= EOF)     {         if(num<=70)               sum=0.1;         else              (num%70) ? (sum=0.1*(num/70+1)) :  (sum=0.1*num/70);        sum3 += sum;     }     printf("%.1lf",sum3);     return 0; }


Question: C语言页式虚存管理

#ifndef _PAGEM_H #define _PAGEM_H  #include "FIFO.h"  //enum EXISTS{NON_EXIST, EXIST}; //enum Update{Update_N, Update_Y}; typedef struct PMT{ 	unsigned char   PageID;         //页号 	unsigned char   F_EXISTS;       //是否在主存 	unsigned char   PframeID;       //页框号 	unsigned char   F_Update;       //是否修改过 	unsigned char   DiskPosition;   //磁盘位置 	struct  PMT *NEXT;             //保存下一页面地址 }pmt;    //指令 typedef struct AccQueue{ 	unsigned char   PageID;         //页号 	unsigned int    offset;         //页内偏移量 	unsigned char   F_Instruction;   //是否存指令    1:存 0:不存  -1:退出 	struct AccQueue  *next; 	unsigned char AccInfo[3];   //用于输出 	unsigned char F_interrupt;   //页面中断 }AccQue;   typedef struct{ 	node    *front; 	node    *rear; }FIFO;   pmt* SetPMT(void);  void AccessQueue(pmt **P_page, FIFO **fifo, AccQue **structaccque, AccQue **accque); void PMTInfo(pmt ** P_page);     FIFO* SetFIFO(pmt ** P_page); void Callingorder(pmt **P_page, FIFO **fifo, pmt **page); void Performance(AccQue **accque);    #endif    #include <stdio.h> #include <malloc.h> #include <stdio.h> #include <string.h> #include "PageM.h"    const unsigned char M = 3;    //主存容量 const unsigned char PageNum = 7;  //该作业页面数 const unsigned int Msize = 1024;   //  pmt* SetPMT(void) { 	pmt *P_page = (pmt *)malloc(sizeof(pmt)); 	(pmt *)memset(P_page, 0x00, sizeof(pmt)); 	P_page->NEXT = NULL; 	 	for(int i = 0; i < PageNum; ++i) 	{ 		pmt *P_npage = (pmt *)malloc(sizeof(pmt));   //建立页面 		(pmt *)memset(P_npage, 0x00, sizeof(pmt)); 		P_npage->NEXT = NULL; 		P_npage->PageID = i; 		if(i < M) 		{ 			P_npage->F_EXISTS = 1; 			P_npage->PframeID = (i | 0xA) + (i & 0xA) + ((i << 1) & 0xA) - 0X9; 		} 		else 		{ 			P_npage->F_EXISTS = 0; 			P_npage->PframeID = -1; 		} 		 		P_npage->F_Update = 0; 		P_npage->DiskPosition = (i | 0xA) + (i & 0xA) + ((i << 1) & 0xA) + ((i << 1) | 0xA); 		 		pmt *page = P_page; 		while(page->NEXT) 			page = page->NEXT; 		page->NEXT = P_npage; 		page = NULL; 	} 	 	return P_page; }  //访问 void AccessQueue(pmt **P_page, FIFO **fifo, AccQue **structaccque, AccQue **accque) { 	if(!P_page && !*P_page) 		fprintf(stderr, "P_page Error!\n"); 	if(!fifo && !*fifo) 		fprintf(stderr, "fifo Error!\n"); 	if(!structaccque && !*structaccque) 		fprintf(stderr, "structaccque Error!\n"); 	if(!accque && !*accque) 		fprintf(stderr, "accque Error!\n"); 	//遍历PMT表，查看访问页面是否在PMT表中 	pmt *pagetmp = (*P_page)->NEXT; 	unsigned char Pflag = 0;   //页面不在 	while(pagetmp) 	{ 		if(pagetmp->PageID == (*structaccque)->PageID) 		{ 			Pflag = 1; 			//存指令 			if(1 == (*structaccque)->F_Instruction)  //是否更新 				pagetmp->F_Update = 1; 			break; 		} 		pagetmp = pagetmp->NEXT; 		 	} 	if(!Pflag) 	{ 		fprintf(stderr, "\t==>>没有该页面.\n"); 		return ; 	} 	 	//访问顺序保存到AccQue; 	/*AccQue *accque = (AccQue *)malloc(sizeof(AccQue));   //连接有效访问信息 	(AccQue *)memset(accque, 0x00, sizeof(AccQue));*/ 	AccQue *acctmp = (*accque); 	while(acctmp->next) 		acctmp = acctmp->next; 	 	acctmp->next = (*structaccque); 	 	//将主存中的信息装入数组 	 	node *Pageid = (*fifo)->front; 	unsigned char i = 0; 	while(Pageid != (*fifo)->rear->next) 	{ 		(*accque)->AccInfo[i++] = Pageid->PageID; 		Pageid = Pageid->next; 	} 	if(i < 2) 		for(i; i <= 2; (*accque)->AccInfo[i++] = -1) 			; 	 	//遍历队列  没有:需要调入   有:刷新 	node *fifotmp = (*fifo)->front; 	unsigned char Fflag = 0; //不在队列中 	while(fifotmp != (*fifo)->rear->next) 	{ 		if(fifotmp->PageID == (*structaccque)->PageID) 		{ 			Fflag = 1; 			(*structaccque)->F_interrupt = 0; 			//在队列 			unsigned char i = 0; 			node *Pageidt = (*fifo)->front; 			while(Pageidt != (*fifo)->rear->next) 			{ 				(*structaccque)->AccInfo[i++] = Pageidt->PageID; 				Pageidt = Pageidt->next; 			} 			if(i < 2) 				for(i; i <= 2; (*structaccque)->AccInfo[i++] = -1) 					; 			break; 		} 		fifotmp = fifotmp->next; 	} 	 	if(!Fflag)	 //调入 	{ 		(*structaccque)->F_interrupt = 1; 		Callingorder(P_page, fifo, &pagetmp); 		node *Pageidtmp = (*fifo)->front; 		unsigned char i = 0; 		while(Pageidtmp != (*fifo)->rear->next) 		{ 			(*structaccque)->AccInfo[i++] = Pageidtmp->PageID; 			Pageidtmp = Pageidtmp->next; 		} 		if(i < 2) 			for(i; i <= 2; (*structaccque)->AccInfo[i++] = -1) 				; 	} 	else if(1 == Fflag) 	{ 		fprintf(stderr, "\t==>>页面[%d]在主存中.", (*structaccque)->PageID); 		fprintf(stderr, "\t==>>地址: %d \n.", (*structaccque)->PageID * Msize + (*structaccque)->offset); 	} 	 	return; }  void PMTInfo(pmt ** P_page) { 	if(!P_page || !*P_page) 		fprintf(stderr, "Error!"); 	 	 	fprintf(stderr, "\t+--------------------------------------------------------+\n"); 	fprintf(stderr, "\t|  页号  |  标志  |  页框号  |  修改标志  |  在磁盘位置  |\n"); 	fprintf(stderr, "\t+--------------------------------------------------------+\n"); 	 	pmt *pagetmp = *P_page; 	while(pagetmp->NEXT) 	{ 		pmt *page = pagetmp->NEXT;  		fprintf(stderr, "\t|   %d    |    %d   |", page->PageID, page->F_EXISTS); 		if(255 == page->PframeID) 			fprintf(stderr, "          "); 		else  			fprintf(stderr, "    %2d    ", page->PframeID); 		fprintf(stderr, "|     %d      |       %2X     |\n", page->F_Update, page->DiskPosition); 		//fprintf(stderr, "\t|--------------------------------------------------------|\n"); 		 		pagetmp = pagetmp->NEXT;    // 		page = NULL; 	} 	fprintf(stderr, "\t+--------------------------------------------------------+\n");  	 	return ; }    #ifndef _FIFO_H #define _FIFO_H  #include "PageM.h"   typedef struct Node{ 	unsigned char   PageID; //页号 	struct Node     *next; }node;    #endif    #include <stdio.h> #include <malloc.h> #include <string.h> #include "PageM.h" #include "FIFO.h"  extern const unsigned char M;  FIFO* SetFIFO(pmt ** P_page) { 	if(!P_page || !*P_page) 		fprintf(stderr, "Error!"); 	 	FIFO *fifo = (FIFO *)malloc(sizeof(FIFO)); 	(FIFO*)memset(fifo, 0x00, sizeof(FIFO)); 	fifo->front = (node *)malloc(sizeof(node)); 	(node *)memset(fifo->front, 0x00, sizeof(node)); 	fifo->front->next = NULL; 	 	fifo->rear = (node *)malloc(sizeof(node)); 	(node *)memset(fifo->rear, 0x00, sizeof(node)); 	fifo->rear = fifo->front; 	 	 	pmt *page = (*P_page)->NEXT; 	int capacity = 0; 	while(page && capacity++ < M) 	{ 		node *P_node = (node *)malloc(sizeof(node)); 		(node *)memset(P_node, 0x00, sizeof(node)); 		P_node->PageID = page->PageID; 		P_node ->next = NULL; 		 		if(1 == capacity) 			fifo->front = P_node; 		fifo->rear->next = P_node; 		fifo->rear = P_node; 		 		page = page->NEXT; 	} 	 	return fifo; }  //调入指令  void Callingorder(pmt **P_page, FIFO **fifo, pmt **page) { 	if(!page && !*page) 		fprintf(stderr, "Error!"); 	if(!fifo && !*fifo) 		fprintf(stderr, "Error!"); 	 	// 调出处理 	pmt *pagetmp = (*P_page); 	while(pagetmp->NEXT) 	{ 		if(pagetmp->NEXT->PageID == (*fifo)->front->PageID) 		{ 			pagetmp->NEXT->F_EXISTS = 0;   //设置不在主存 			if(1 == pagetmp->NEXT->F_Update) 			{ 				fprintf(stderr, "\t==>>页面[%d]的内容写回磁盘。\n", pagetmp->NEXT->PageID); 				pagetmp->NEXT->F_Update = 0; 			} 			//pagetmp->NEXT->PframeID = -1; 			fprintf(stderr, "\t==>>页面[%d]调出.\n", pagetmp->NEXT->PageID); 			break; 		} 		pagetmp = pagetmp->NEXT; 	} 	 	node *temp = (*fifo)->front;             //队首 	(*fifo)->front = (*fifo)->front->next; 	free(temp); 	 	node *P_node = (node *)malloc(sizeof(node)); 	(node *)memset(P_node, 0x00, sizeof(node)); 	P_node->PageID = (*page)->PageID; 	unsigned char i = (*page)->PageID; 	(*page)->PframeID = pagetmp->NEXT->PframeID; 	pagetmp->NEXT->PframeID = -1; 	(*page)->F_EXISTS = 1; 	P_node->next = NULL; 	 	(*fifo)->rear->next = P_node; 	(*fifo)->rear = P_node; 	 	fprintf(stderr, "\t==>>页面[%d]调入.\n", P_node->PageID); 	 	 	return ; }  //FIFO性能分析  void Performance(AccQue **accque) { 	AccQue *acctmp = (*accque)->next; 	if(!acctmp) 	{ 		fprintf(stderr, "\t==>>访问队列为空.\n"); 		return ; 	} 	fprintf(stderr, "\t+--------------------------------------------------------+\n"); 	fprintf(stderr, "\t|   时刻   |"); 	unsigned char time = 1; 	while(acctmp) 	{ 		fprintf(stderr, "  %d  |", time++); 		acctmp = acctmp->next; 	} 	fprintf(stderr, "\n"); 	 	acctmp = (*accque)->next; 	fprintf(stderr, "\t| 页面走向 |"); 	while(acctmp) 	{ 		fprintf(stderr, "  %d  |", acctmp->PageID); 		acctmp = acctmp->next; 	} 	fprintf(stderr, "\n"); 	 	acctmp = (*accque)->next; 	fprintf(stderr, "\t|          |"); 	while(acctmp) 	{ 		fprintf(stderr, "  %d  |", acctmp->AccInfo[2]); 		acctmp = acctmp->next; 	} 	fprintf(stderr, "\n"); 	 	fprintf(stderr, "\t| 主存容量 |"); 	acctmp = (*accque)->next;  	while(acctmp) 	{ 		fprintf(stderr, "  %d  |", acctmp->AccInfo[1]); 		acctmp = acctmp->next; 	} 	fprintf(stderr, "\n"); 	 	fprintf(stderr, "\t|          |"); 	acctmp = (*accque)->next;  	while(acctmp) 	{ 		fprintf(stderr, "  %d  |", acctmp->AccInfo[0]); 		acctmp = acctmp->next; 	} 	fprintf(stderr, "\n"); 	 	unsigned char tmp = 0; 	fprintf(stderr, "\t| 缺页中断 |"); 	acctmp = (*accque)->next;  	while(acctmp) 	{ 		fprintf(stderr, "  %d  |", acctmp->F_interrupt); 		acctmp = acctmp->next; 	} 	fprintf(stderr, "\n"); 	 	fprintf(stderr, "\t+--------------------------------------------------------+\n"); 	 	int rate = 0; 	acctmp = (*accque)->next; 	while(acctmp) 	{ 		if(1 == acctmp->F_interrupt) 			++rate; 		acctmp = acctmp->next; 	} 	 	fprintf(stderr, "\t 缺页率: %d / %d = %.2lf\n", rate , time-1, ((float)rate/(time-1))); 	 	return ; }


Question: 顺序队列!!!新手问题！！求大神指教！！明天就要交作业了！！

C++ 直接用容器

if(front == Q->rear) {         printf("队列为空\n");         return;     } 若队列已空，就应该直接退出函数，而不是继续执行出队列操作；

引用 1 楼 hefashion0190 的回复:仅供参考 #include<stdio.h> #include<stdlib.h>  #define MAXQSIZE 10  typedef struct worker { int id; char name[20]; }WORKER;  typedef struct queue { WORKER data[MAXQSIZE]; int front;	//队头  int rear;	//队尾  }QUE; //初始化	构建一个空队列  void initQueue(QUE *Q) { Q->front = Q->rear = 0;	//无须重复队头和队尾分配空间 	  }   //入队 void enterQueue(QUE *Q,WORKER newWor)	//队尾入队  { if(Q->front == (Q->rear+1) % MAXQSIZE)	 printf("%s","队列已满");   Q->data[Q->rear] = newWor;	//队尾入新的元素  Q->rear=(Q->rear+1) % MAXQSIZE;	//队尾指针向后移动一个元素  //若到最后则转到数组头部 } void deleteQueue(QUE *Q) { if(Q->front == Q->rear) //f=r printf("队列已空\n");  else    //对头出队 {       //先进先出  Q->front = (Q->front+1) % MAXQSIZE;     //队头指针向后移动一个元素 //若到最后则转到数组头部 deleteQueue(Q); } } //输出队列元素 void outPutQueue(QUE *Q) { int front = Q->front; //if(Q->front == Q->rear) if(front == Q->rear) printf("队列为空\n");  while(front != Q->rear) //while(Q->front != Q->rear) { //printf("编号：%d \t姓名：%s\n",Q->data[Q->front].id,Q->data[Q->front].name); printf("编号：%d \t姓名：%s\n",Q->data[front].id,Q->data[front].name); //Q->front = (Q->front+1) % MAXQSIZE; front = (front+1) % MAXQSIZE; }  }  int main(int argc, char *argv[]) { WORKER W1 = {12345,"zhangsan"}; WORKER W2 = {23456,"lisi"}; WORKER W3 = {34567,"wangwu"};  QUE Q; initQueue(&Q);  enterQueue(&Q,W1); enterQueue(&Q,W2); enterQueue(&Q,W3);  outPutQueue(&Q); printf("\n"); //这里我要再次插入元素才能删除，要不然就显示为空 //我知道为空的原因是  调用outPutQueue(&Q)函数  导致  Q->front == Q->rear //现在我想实现是只用插入一次元素 //而不是现在这样子才能实现删除功能并把元素输出出来 //求大神指教！！！！！ //enterQueue(&Q,W1); //enterQueue(&Q,W2); //enterQueue(&Q,W3);  deleteQueue(&Q); outPutQueue(&Q);  return 0; } 谢谢大神，豁然开朗


Question: C语言 数组问题

http://edu.csdn.net/course/detail/2516 C语言指针与汇编内存地址-三.数组和二维数组

#define MAX_STACK_SIZE 100; #define FALSE 1; #define TRUE 0; #define ERROR -1; 第一个问题，宏定义需要都去掉分号；  int InitStack(Stack *sta) {     sta->base = (Node*)malloc(sizeof(Node) * MAX_STACK_SIZE);     if (sta->base == NULL) {         return FALSE;     }     sta->top = sta->base;     sta->stacksize = MAX_STACK_SIZE;     return TRUE; } 第二个问题，应该传地址到InitStack函数，这样才能获取申请的空间； 并且申请的大小应该乘以MAX_STACK_SIZE;

ElemType Point[][3]= {0}; 等价于 Point[1][3] = {0}; InitPoint 会出现越界访问数组Point  可能原本的想法是  ElemType Point[12][3] = {0};


Question: 求助，错误:register 1 is no vfp register

请在PC上使用VS2010编程。 Visual C++ 2010 Express简体中文版http://pan.baidu.com/s/1bnwRVLt


Question: 求助，求助C语言结构体

数据结构对单链表进行数据排序 http://bbs.csdn.net/topics/392201633

还有其他的问题： 1.create_list函数中，第一次分配内存是给了L，而循环中是输入到p中，注意第一次循环时p是个野指针。应该改为第一次分配内存就给p。 2.函数M做什么用的？看起来好像有排序，但La和Lb都不是有序链表，M做排序有什么意义？搞清楚目标，才知道这个函数该怎么改。

LinkList是struct LNODE **的别名，因此，LinkList *L就是struct LNODE **L;所以，L无法直接使用next结构体成员，需要(*L)->next; M 函数里一样； pa = (*La)->next; pb = (*Lb)->next;  程序存在内存泄露，比如La和Lb链表插入到Lc链表里，没有用到的La或Lb节点应该free掉；

请注意，你已经把LinkList定义为struct LNODE *了，因此所有的LinkList *都是struct LNODE **。比如create_list中的这一句：  L->next = NULL;  应该改为  (*L)->next = NULL;   其他各处也按此修改。


Question: 初学者求帮助

看来已经解决。

引用 6 楼 zhao4zhong1 的回复:scanf函数的内部实现源代码就是crt\src\input.c，你调用scanf，变量前忘加&，导致input.c中的对应语句写非法内存，故弹出input.c，显示写非法内存的那句话。  其实电脑开机后物理内存的每个字节中都有值且都是可读写的，从来不会因为所谓的new、delete或malloc、free而被创建、销毁。区别仅在于操作系统内存管理模块在你读写时是否能发现并是否采取相应动作而已。操作系统管理内存的粒度不是字节而是页，一页通常为4KB。 正解！

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

scanf中%d对应的输入变量，需要加& 出现截图二的原因是程序调试遇到问题，到编译的底层，或者汇编

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

我知道错在哪里，我意思是当我调试的时候弹出来了 我想问问这个是什么东西，为什么会弹出来这个，

scanf("%d", year); 改成 scanf("%d", &year);

scanf第二个参数应该是地址，即输入的数据写到该地址开始的4个字节里，因为year是int，占4个字节； 但是现在是year，首先定义时，year没有初始化，所以是随机值。那么，若不加&，即想year所在的内存里写数据，year是随机值，这个地址就是year所开始的位置； 建议先把year这个随机值打印出来，建议用%u打印或%x，因为地址是无符号数。看看这个随机值是不是编译器提示的地址值。


Question: 递归中的参数是如何变化的？

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

这里len是值传递，所以len在每次调用HuffManCoding返回时保持调用前的值，永远记住这一点。

建议在函数里static int a[10];后添加一句   printf("len = %d\n", len);  这样每次递归都能看到传进来的len的值，也就可以看到其变化了。


Question: 用c编了一个温度对照表，运行正常，但是没有任何显示

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

while 后面是不是多了个分号？

噢，这样啊。谢谢。

去掉while();后面的分号即可； 若在while后面加分号，那么while就没有循环体了。


Question: C语言类型定义导致指针为NULL

引用 4 楼 destory27 的回复:[quote=引用 3 楼 cfjtaishan 的回复:] [quote=引用 2 楼 lin5161678 的回复:] unsigned char 1个字节 假设 int 4个字节 scanf %d 会向参数指定的内存写入4个字节的数据 但chosse只有1个字节 所以有3个字节是越界写入 这里刚刚好写到了 P_page的内存里面了 修改了P_page的数据  所以 scanf 格式控制字符 要和参数的类型 对应 所以 不要出现数组越界的操作 有可能是这种情况导致的。 建议将choose定义成unsigned int或int类型。对应的scanf输入格式%u和%d 主要是%d是4个字节，unsigned char是一个字节；[/quote]  我用unsigned char 主要是 我要存的值很小，1个字节够了[/quote] 如果内存不紧张，即使是用一个字节，那么定义成int类型又何妨？

unsigned类型不能用%d去接收输入

引用 3 楼 cfjtaishan 的回复:[quote=引用 2 楼 lin5161678 的回复:] unsigned char 1个字节 假设 int 4个字节 scanf %d 会向参数指定的内存写入4个字节的数据 但chosse只有1个字节 所以有3个字节是越界写入 这里刚刚好写到了 P_page的内存里面了 修改了P_page的数据  所以 scanf 格式控制字符 要和参数的类型 对应 所以 不要出现数组越界的操作 有可能是这种情况导致的。 建议将choose定义成unsigned int或int类型。对应的scanf输入格式%u和%d 主要是%d是4个字节，unsigned char是一个字节；[/quote]  我用unsigned char 主要是 我要存的值很小，1个字节够了

引用 2 楼 lin5161678 的回复:unsigned char 1个字节 假设 int 4个字节 scanf %d 会向参数指定的内存写入4个字节的数据 但chosse只有1个字节 所以有3个字节是越界写入 这里刚刚好写到了 P_page的内存里面了 修改了P_page的数据  所以 scanf 格式控制字符 要和参数的类型 对应 所以 不要出现数组越界的操作 有可能是这种情况导致的。 建议将choose定义成unsigned int或int类型。对应的scanf输入格式%u和%d 主要是%d是4个字节，unsigned char是一个字节；


Question: 请问图片转换成二进制后正常的大小是多少

引用 19 楼 SXJIAKE 的回复:[quote=引用 18 楼 ckc 的回复:]真没看出来你的重点。 打开文件的flag不用二进制或而是使用字符串的原因是为了不同平台上的兼容性，用二进制或的换了个cpu，换了个编译器，换了个操作系统 就有可能失灵，也就是你写的代码不怎么跨平台，所以才认识不到用字符串的重要意义。 参数区分文本和二进制是历史遗留问题，只是为了让古老的代码在今天的环境下编译的时候尽可能兼容，事实上今天完全可以不加这个参数。 fp是第一个参数还是最后一个参数也是历史遗留问题，可能是当年不同的人写的库函数，所以没能统一，这个是多大的原则问题？完全是小事情好吧 传递size和count两个参数也看不出有什么大不了，按块读写文件的时候一个指定块大小，一个指定读的块的数量，也很方便。你完全可以指定size， count用1就可以了，也就是多写一个参数的事情，这要是都受不了那你看看windows的函数调用，一大堆垃圾参数的情况多的是。 就你这3点，我看不出这些函数有什么十恶不赦的大罪。 至于你的所谓坚持用本机api，丢失了最宝贵的兼容性，你这个思路自己用用也就拉倒了， 还要在这教坏小朋友，所以我才好心劝你看看这两套api的差异。 你要是觉得你很NB，那就当我没说吧。我从未说我有多牛，差异我当然知道。我只想说明一点，fopen 这个默认文本模式的设计坑了不少人，如果读出来的内容都不是原始内容的话，这还能叫读取文件吗？这叫读取文本。你不能保证所有用 fopen 的人都清楚文本模式和二进制模式的区别，并且知道默认是文本模式。虽然这个是历史包袱，但有时候坑不熟悉的人是事实。参数不用二进制位或运算，以及 fp 参数的位置等，这是我个人顺带吐槽一下。[/quote] 嗯，你说的也很有道理。类似的地方其实还挺多的，我个人就对ftp的文本模式很反感，早些年遇到过很多次有人用文本模式传输二进制文件，然后文件被改掉了出故障。 不过这是两难的问题，所有的自动优化处理都可能会给不熟悉的人带来困扰。

楼上的大神，人家还在学习怎么走路，你却教别人怎么跑步

引用 18 楼 ckc 的回复:真没看出来你的重点。 打开文件的flag不用二进制或而是使用字符串的原因是为了不同平台上的兼容性，用二进制或的换了个cpu，换了个编译器，换了个操作系统 就有可能失灵，也就是你写的代码不怎么跨平台，所以才认识不到用字符串的重要意义。 参数区分文本和二进制是历史遗留问题，只是为了让古老的代码在今天的环境下编译的时候尽可能兼容，事实上今天完全可以不加这个参数。 fp是第一个参数还是最后一个参数也是历史遗留问题，可能是当年不同的人写的库函数，所以没能统一，这个是多大的原则问题？完全是小事情好吧 传递size和count两个参数也看不出有什么大不了，按块读写文件的时候一个指定块大小，一个指定读的块的数量，也很方便。你完全可以指定size， count用1就可以了，也就是多写一个参数的事情，这要是都受不了那你看看windows的函数调用，一大堆垃圾参数的情况多的是。 就你这3点，我看不出这些函数有什么十恶不赦的大罪。 至于你的所谓坚持用本机api，丢失了最宝贵的兼容性，你这个思路自己用用也就拉倒了， 还要在这教坏小朋友，所以我才好心劝你看看这两套api的差异。 你要是觉得你很NB，那就当我没说吧。我从未说我有多牛，差异我当然知道。我只想说明一点，fopen 这个默认文本模式的设计坑了不少人，如果读出来的内容都不是原始内容的话，这还能叫读取文件吗？这叫读取文本。你不能保证所有用 fopen 的人都清楚文本模式和二进制模式的区别，并且知道默认是文本模式。虽然这个是历史包袱，但有时候坑不熟悉的人是事实。参数不用二进制位或运算，以及 fp 参数的位置等，这是我个人顺带吐槽一下。

引用 15 楼 SXJIAKE 的回复:[quote=引用 13 楼 ckc 的回复:]建议去搜索一下“fopen和open的差异"，多了解一些再发表结论。 建议看清楚我想表达的意思，确定我说的重点再发表结论。[/quote] 真没看出来你的重点。 打开文件的flag不用二进制或而是使用字符串的原因是为了不同平台上的兼容性，用二进制或的换了个cpu，换了个编译器，换了个操作系统 就有可能失灵，也就是你写的代码不怎么跨平台，所以才认识不到用字符串的重要意义。 参数区分文本和二进制是历史遗留问题，只是为了让古老的代码在今天的环境下编译的时候尽可能兼容，事实上今天完全可以不加这个参数。 fp是第一个参数还是最后一个参数也是历史遗留问题，可能是当年不同的人写的库函数，所以没能统一，这个是多大的原则问题？完全是小事情好吧 传递size和count两个参数也看不出有什么大不了，按块读写文件的时候一个指定块大小，一个指定读的块的数量，也很方便。你完全可以指定size， count用1就可以了，也就是多写一个参数的事情，这要是都受不了那你看看windows的函数调用，一大堆垃圾参数的情况多的是。 就你这3点，我看不出这些函数有什么十恶不赦的大罪。 至于你的所谓坚持用本机api，丢失了最宝贵的兼容性，你这个思路自己用用也就拉倒了， 还要在这教坏小朋友，所以我才好心劝你看看这两套api的差异。 你要是觉得你很NB，那就当我没说吧。

引用 13 楼 ckc 的回复:建议去搜索一下“fopen和open的差异"，多了解一些再发表结论。 建议看清楚我想表达的意思，确定我说的重点再发表结论。

24k大小, 现在的网络都是秒传的.  文件内容本身就是二进制了啊, 还要你转什么????  fopen  之后, fread到缓冲区, 然后用socket的send直接发送这个缓冲区就可以了.   不需要转换.   想到的转换的, 都是对数据内存或者数据表示方式理解不到位.

引用 4 楼 SXJIAKE 的回复:二进制还需要转吗？读出来难道不是二进制？ 当然，我从不用 fopen、fread、fwrite、fclose 这套设计奇葩的 API： 1. 打开文件的 flag 不用二进制位或，而是字符串，参数还区分文本和二进制模式——这本来不应该是标准所该干预的。 2. fread 和 fwrite 居然不是以 fp 作为第一个参数，却放最后一个，但 fprintf 却是放在第一个。 3. fread 和 fwrite 居然要传 size 和 count 两个参数？除了这俩奇葩之外，哪个读写类 API 不是只传一个地址和长度(大小)？ 我一向坚持用本机 API： Linux 用 open、read、lseek、write、close Windows 用 CreateFile、ReadFile、SetFilePointer、WriteFile、CloseHandle 文件内容是怎么样，读出来就应该是怎么样。 杜绝使用 C 系列文件读写 API，从我做起。 建议去搜索一下“fopen和open的差异"，多了解一些再发表结论。

电脑内存或文件内容或传输内容只是一个一维二进制字节数组及其对应的二进制地址； 人脑才将电脑内存或文件内容或传输内容中的这个一维二进制字节数组及其对应的二进制地址的某些部分看成是整数、有符号数/无符号数、浮点数、复数、英文字母、阿拉伯数字、中文/韩文/法文……字符/字符串、汇编指令、函数、函数参数、堆、栈、数组、指针、数组指针、指针数组、数组的数组、指针的指针、二维数组、字符点阵、字符笔画的坐标、黑白二值图片、灰度图片、彩色图片、录音、视频、指纹信息、身份证信息……

图片本身就是二进制的啊 图片有多大 传输的内容就应该是多少，不知道你代码怎么写的

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

引用 6 楼 zhao4zhong1 的回复:可惜教C语言的老师都只教 C 系列文件读写 API。

// Windows #include <windows.h>  int main(int argc, const TCHAR *argv[]) { 	PCTSTR pszFile = argv[1]; 	HANDLE hFile1 = CreateFile(pszFile, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); 	if (hFile1 != INVALID_HANDLE_VALUE) 	{ 		BYTE Buffer[1024] = { 0 }; 		DWORD dwReadBytes = 0; 		ReadFile(hFile1, Buffer, sizeof(Buffer), &dwReadBytes, NULL); 		CloseHandle(hFile1); 	} 	HANDLE hFile2 = CreateFile(pszFile, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); 	if (hFile2 != INVALID_HANDLE_VALUE) 	{ 		BYTE Buffer[1024] = { 0 }; 		DWORD dwWrittenBytes = 0; 		WriteFile(hFile2, Buffer, sizeof(Buffer), &dwWrittenBytes, NULL); 		CloseHandle(hFile2); 	} 	return 0; }// Linux #include <fcntl.h> #include <unistd.h> #include <sys/stat.h> #include <sys/mman.h>  int main(int argc, const char *argv[]) { 	const char *file = argv[1]; 	int fd1 = open(file, O_RDONLY); 	if (fd1 != -1) 	{ 		char buf[1024] = { 0 }; 		read(fd1, buf, sizeof(buf)); 		close(fd1); 	} 	int fd2 = open(file, O_WRONLY | O_CREAT, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH); 	if (fd2 != -1) 	{ 		char buf[1024] = { 0 }; 		write(fd2, buf, sizeof(buf)); 		close(fd2); 	} 	return 0; }

引用 4 楼 SXJIAKE 的回复:二进制还需要转吗？读出来难道不是二进制？ 当然，我从不用 fopen、fread、fwrite、fclose 这套设计奇葩的 API： 1. 打开文件的 flag 不用二进制位或，而是字符串，参数还区分文本和二进制模式——这本来不应该是标准所该干预的。 2. fread 和 fwrite 居然不是以 fp 作为第一个参数，却放最后一个，但 fprintf 却是放在第一个。 3. fread 和 fwrite 居然要传 size 和 count 两个参数？除了这俩奇葩之外，哪个读写类 API 不是只传一个地址和长度(大小)？ 我一向坚持用本机 API： Linux 用 open、read、lseek、write、close Windows 用 CreateFile、ReadFile、SetFilePointer、WriteFile、CloseHandle 文件内容是怎么样，读出来就应该是怎么样。 杜绝使用 C 系列文件读写 API，从我做起。 可惜教C语言的老师都只教 C 系列文件读写 API。

图片，可以看成普通文件吧，每次读一定大小的数据到缓存里，然后通过socket发送到对端，对端写文件（文件格式和源端一致），等源端读完，发送完，目的端也写完数据。可以在目的端打开以下图片，是否和源端一致； 没必要一次性读完文件，然后一次性发送到对端；因为一次性读完，可能需要申请很大的空间，其次，一次发送很大的包，网络需要分包，分片；因此不一定提高效率，反而会降低效率；

理解和讨论之前请先学会如何观察！  在PS中将一幅比如200x200像素的图片用图像、模式中的各种模式和文件、存储为、格式中的各种格式都保存一遍，实际观察一下保存的文件都多少个字节。   不要迷信书、考题、老师、回帖； 要迷信CPU、编译器、调试器、运行结果。 并请结合“盲人摸太阳”和“驾船出海时一定只带一个指南针。”加以理解。 任何理论、权威、传说、真理、标准、解释、想象、知识……都比不上摆在眼前的事实！

图片文件本来就是二进制的，不是文本文件。不同分辨率的图片大小不一样。相同分辨率的图片保存格式不一致也会造成图片文件的大小不一样。

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

我感觉并不大呀 多大啊

怎么转的，你的代码呢?


Question: C语言3个数求最大数的问题

#include <stdio.h> int main() { 	int a , b, c , t; 	int *p1, *p2, *p3 ; 	scanf("%d%d%d",&a,&b,&c); 	 p1=&a; 	 p2=&b; 	 p3=&c; 	 if(*p1>*p2) 	 { 		 t=*p1; 		*p1=*p2; 		 *p2=t; 	 } 	 if(*p1>*p3) 	 { 		 t=*p1; 		 *p1=*p3; 		 *p3=t; 	 } 	 if(*p2>*p3) 	 { 		 t=*p2; 		 *p2=*p3; 		 *p3=t; 	 } 	 printf("%d,%d,%d\n",*p1,*p2,*p3); 	 return 0; }

#include<stdio.h>      int max(int x,int y,int z);  int main() {     int a,b,c,d;     scanf("%d,%d,%d",&a,&b,&c);      d = max(a,b,c);     printf("max=%d\n",d);     return 0; } int max(int x,int y,int z) {     int e,f;     if(x>y)         e=x;     else         e=y;     if(e>z)         f=e;     else         f=z;     return(f); } 函数声明建议放在main函数外，man函数之上。其他逻辑没问题； 输入的时候注意加,比如输入:5,8,2；否则无法和a,b,c一一匹配。这是因为scanf中格式%d,%d,%d要求的。

楼主你输入的时候要这样打:a,b,c 不然b,c都传不进去，代码本身没问题，如果你想这样打a b c，那么请改为这样输入:scanf("%d %d %d",&a,&b,&c);

#include<stdio.h> int max(int*p1,int*p2,int*p3) { 	int max; 	max=*p1; 	if(max>*p2&&max>*p3) 	{ 	return max; 	} 	else if(max<*p2&&*p2>*p3) 	{ 		max=*p2; 		return max; 	} 	else 	{ 		max=*p3; 		return max; 	} } int main() { 	int a,b,c,d; 	int*p1=&a;int*p2=&b;int*p3=&c; 	scanf("%d,%d,%d",&a,&b,&c); 	d=max(p1,p2,p3); 	printf("%d\n",d); 	return 0; }

有什么问题？

代码没问题啊


Question: 文件读取练习题的问题

#include <stdio.h> #include <stdlib.h>  int main(void) {     char str[10] = {0};     FILE *fp,*fp2;     if((fp=fopen("test.txt","r"))==NULL)     {         printf("cannot open this file.\n");         exit(0);     }     if((fp2=fopen("test2.txt","w"))==NULL)     {         printf("cannot open this file.\n");         exit(0);     }     while(!feof(fp))//设置断点的行         fputc(fgetc(fp),fp2);     rewind(fp);    /* or fseek(fp, 0l, SEEK_SET);*/     fgets(str,3,fp);//出问题的地方     printf("%s",str);     fclose(fp);     fclose(fp2);     return 0; } 改一下fp的位置，使用rewind或fseek

fp这个指针的值不会变，但文件位置指针会变化（不是fp），你读一个字节就往后移动一个，你可以用fseek设置文件指针位置，可以用ftell得到文件指针离开头的偏移距离


Question: 哪里出现问题

i 没初值     scanf() 执行一次

使用循环输入,只输入一个是不行的。  for (i = 0; i < 10; i++)     scanf("%d", &a[i]);   导致程序挂到的原因是内存越界； 开始i是随机值，可能很大。然后scanf("%d", &a[i]); a[i]就已经越界了（下表不能超过9，<=9)；所以会导致多错误； 若现将i = 0;就不会出现程序无法继续运行，只不过数组除了第一个元素是固定的，其他都是随机值。

1数组要进行初始化 2赋值循环进行。

for(i = 0; i < 10; ++i) {     scanf("%d", &a[i]); }

错误太明显了，你的i未初始化就用scanf来输入数据，看你的意思，最起码也得用个for循环输入吧


Question: 未使用的变量会被编译器优化掉么？会分配内存么？

不同编译器，就VS来说的话，debug模式下一般是不会优化掉未使用的局部变量的，release模式下就比较凶残了，就连使用的空函数体都会被优化掉，for循环都帮你展开

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

subq $4194336,%rsp这才是分配局部变量空间，不是你指的那行。

编译优化也会分级别，gcc -O1(或2），每个优化级别分别做不同的优化；建议查询一下优化级别；  若不用的变量，编译器一般会提示，若能优化则最好，若不会优化会占用内存空间。建议不适用的变量直接删掉；  另外，不建议在函数内定义较大的数组，比如1024 * 1024；因为栈上的空间是有限的，在栈上使用较大的空间会影响程序的运行效率

优不优化没有明确规定，不同编译器有不同处理。 即使是同一编译器，比如gcc， 不加优化选项时：https://godbolt.org/g/JSquKz 加-O1时：https://godbolt.org/g/ZexJfN

Debug下不会被优化，Release通常是会被优化掉的


Question: C中的一道和大数有关的题目，不会做，各位大佬提个意见呗

C中现有的数据类型满足不了这个大数的，想着用数组做，不知道如何实现，数据太大了。

直接求数太多了，，，可以先找出每个数的因子，，在因子中找满足条件的   感觉也比较复杂 意见而已

运行的时间非常久，算法比较普通  仅供参考 #include <stdio.h>    #define N 10000000000  int main(int argc, char *argv[]) {         unsigned long long j,k,sum = 0;         for(k=2;k<=N;k++)         {                 sum=0;                 for(j=1;j<=k/2;j++)                         if(k%j==0)                                 sum=sum+j;                 if(sum==k)                         printf("%lld\n",k);         }          return 0; }


Question: 二维数组的输入

引用 2 楼 m0_37243410 的回复:int a[n][m];  for(int i=0;i<n;i++)      for(int j=0;j<m;j++)      scanf("%d",&a[i][j]);  scanf()不需要回收垃圾字符，遇到空格或者Enter回车结束数据在读入 引用 2 楼 m0_37243410 的回复:int a[n][m];  for(int i=0;i<n;i++)      for(int j=0;j<m;j++)      scanf("%d",&a[i][j]);  scanf()不需要回收垃圾字符，遇到空格或者Enter回车结束数据在读入    scanf 需要回收垃圾   int main(void) { 	int a; 	 	while((scanf("%d", &a)) == 0) 	{ 		//fflush(stdin);  或  getchar();    若没有  死循环 		printf("secew"); 	} 	printf("%d", a); 	 	return 0; }

两层for循环呗，注意用getchar()回收垃圾字符


Question: PTA B1057.c 数零壹

char str[100001];

#include<stdio.h> int main(void) {     int s,l=0,y=0;     char c;     do     {         scanf("%c",&c);         if ((c>='a')&&(c<='z')) s+=c-96;         if ((c>='A')&&(c<='Z')) s+=c-64;     }while(c!='\n');     while(s!=0)     {         if(s%2==0) l++;         else y++;         s=s/2;     }     printf("%d %d\n",l,y);     return 0; }  这是我的程序，都过了，希望能帮到你

fgets代替gets要注意去掉最末尾的'\n'

#include<stdio.h> #include<string.h> #include <ctype.h>  #define     MAX_STR_LEN     128  int get_char_value(const char *str, int len); void count_bits(unsigned int num, int *arr);  int main() {     char str[MAX_STR_LEN];     int bits[2] = {0};     int val;      fgets(str, MAX_STR_LEN, stdin);      val = get_char_value(str, strlen(str));     printf("val = %d\n", val);     count_bits(val, bits);      printf("0: %d, 1: %d\n", bits[0], bits[1]);     return 0; }  int get_char_value(const char *str, int len) {     int i = 0, sum = 0;      while (i < len) {         if (islower(str[i]))             sum += str[i] - 'a' + 1;         else if (isupper(str[i]))             sum += str[i] - 'A' + 1;         i++;     }     return sum; }  void count_bits(unsigned int num, int *arr) {     int i = 31;     while (i > 0 && (num & (1<<i)) == 0)         i--;     arr[1]++;      for (; i > 0; i--)         if ((num & (1 << i)))             arr[1]++;         else             arr[0]++; } 参考一下吧

给定一串长度不超过105的字符串，本题要求你将其中所有英文字母的序号（字母a-z对应序号1-26，不分大小写）相加，得到整数N，然后再分析一下N的二进制表示中有多少0、多少1。例如给定字符串“PAT (Basic)”，其字母序号之和为：16+1+20+2+1+19+9+3=71，而71的二进制是1000111，即有3个0、4个1。  输入格式：  输入在一行中给出长度不超过105、以回车结束的字符串。  输出格式：  在一行中先后输出0的个数和1的个数，其间以空格分隔。  输入样例： PAT (Basic) 输出样例： 3 4   这是题目要求，谢谢你提的建议哦

建议楼主贴出程序需求和测试用例。 程序可以优化的地方是太大的数组建议定义成全局变量；


Question: PTA B1019.c

百尺竿头，更进一步。 说起来容易，做起来难。


Question: 这是个哈弗慢数，有没有人能在此基础上写一下报文编码和译码，

基本差不多了，自己再完善一下

百度搜相关关键字。


Question: 网络推荐好友问题，进来看看

边界条件 输入输出格式 ……


Question: 写一个函数，用起泡法对输入的10个字符按由小到大顺序排列

不要意思呀 我都弄傻了 没看到交换语句那里是怎么搞出来的错误 但是我改成int类型 出来的结果是五个空格12345

#include <stdio.h> int main() { 	int a[10]; 	int i,j,k; 	printf("input 10 numbers :\n"); 	for(i=0;i<10;i++) 		scanf("%d",&a[i]); 	printf("\n"); 		for(j=0;j<9;j++) 			for(i=0;i<9-j;i++) 				if(a[i]>a[i+1]) 				{ 					k=a[i];a[i]=a[i+1];a[i+1]=k; 				} 				printf("the sorted number :\n"); 				for(i=0;i<10;i++) 					printf("%d\n",a[i]); 				printf("\n"); 				return 0; }

#include <stdio.h>   void q(char a[10]) {     char t;     int i,j,k;     for(i=0;i<9;i++)      {           k=i;         for(j=i+1;j<10;j++)             if(a[i] > a[j])               {                k=j;             }             if(i!=k)               {t=a[i];a[i]=a[k];a[k]=t;}      } } int main() {     int i;     char a[10];       printf("请输入10个字符");     for(i=0;i<10;i++)         scanf("%c",&a[i]);     q(a); 	for(i=0;i<10;i++) 	printf("%c\n",a[i]);     return 0;   } 也可以这样写

#include <stdio.h>  char q(char a[10]) {     char t;     int i,j;     for(i=0;i<9;i++)         for(j= 0;j<10-1 - i;j++)             if(a[j] > a[j+1])    /*这儿应该是判断，而不是赋值*/             {                 t      = a[j];                 a[j]   = a[j+1];                 a[j+1] = t;             }     for(i=0;i<10;i++)         printf("%c",a[i]);      return 0; } int main() {     int i;     char a[10];      printf("请输入10个字符");     for(i=0;i<10;i++)         scanf("%c",&a[i]);     q(a);     printf("\n");      return 0;  } 参考一下吧；注意if后的括号里是判断表达式，不应该是赋值表达式；

算法有一小部分问题，重点是数据类型不太对。如果定义为char类型 你那样就算是输入19个数据了    输入的10就算是两个char类型的数据

if(a[i]>a[j]){t=a[i];a[i]=a[j];a[j]=t;} 由小到大排序应该这样吧

if(a[i]<a[j]){t=a[i];a[i]=a[j];a[j]=t;}交换要这么写啊。其他有没有问题不知道了，没调试。


Question: 誠心求助，一点小疑问，关于梯形法与辛普森法积分的

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


Question: C数组初始化问题

不说别的，就这个缩进本身就有问题：while (num) { 	tmp = num%10; 	// 这不是 python。if 之后没有花括号，作用范围只有一行“num += 1;”。 	if (tmp % 2 != 0) 		num += 1; 		result = (num % 10) * pow(10,i) + result; 	i++; 	num /= 10; }

全局变量默认初始值是0,局部变量没有初始值，给数组某个元素赋值，其它元素并没有被赋值。

不对，其他值仍然是垃圾值。

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

测试一下，我记得是定义的时候赋值例如:int a[10]={0};那么a的全部都为0，如果是int a[10]; a[0]=0;那么只赋值了a[0] 其他都未知值(随机整数) 一些数组初始化也可用memset(a,0,sizeof(a));去给数组全赋值0，或者full(a,0)

做编程，还是要多动手，敲敲代码，这样印象深刻

不对，对任意元素赋值，并不会改变其余元素的值

引用 8 楼 qq_37347705 的回复:咦，不对吧。  :!./a.out 0 0 0 0 4195712 10 4195392 0 1948630112 32767     楼上的代码，这是结果。 所以，若定义时不对数组初始化，然后对任意元素赋值，不会导致其他元素都位0；

引用 6 楼 darker0019527 的回复:[quote=引用 4 楼 cfjtaishan 的回复:] 建议楼主试一下，结果是否定的。对某个下表对应的数组元素赋值，只能改变对应的元素值，而不能对其他元素有影响； int a[5] = {0};  这句话是对a[0]赋值还是对数组 [/quote] 这个是对数组初始化；即所有元素都初始化位0；  如果对数组任意元素赋值，那么数组的其它元素就会被赋值为 0 这句话，怎么理解呢？ 我的理解是这样的，比如： #include <stdio.h>   int main(void) {     int arr[10];       arr[5] = 10;       for (int i = 0; i < 10; i++)         printf("%d\n", arr[i]);     return 0; }

引用 4 楼 cfjtaishan 的回复:建议楼主试一下，结果是否定的。对某个下表对应的数组元素赋值，只能改变对应的元素值，而不能对其他元素有影响； int a[5] = {0};  这句话是对a[0]赋值还是对数组

int a[5] = {0};  这句话是对a[0]赋值还是对数组

引用 1 楼 user-11 的回复:对  你尝试一下不就可以了吗= = 引用 2 楼 cfjtaishan 的回复:[quote=引用 1 楼 user-11 的回复:] 对  你尝试一下不就可以了吗= = 对吗？ 尝试一下对不对； #include <stdio.h> #include <math.h>  int change_to_pmh_number(int num) {     int i = 0;     int tmp, result = 0;      while (num) {         tmp = num%10;         if(tmp % 2 != 0)             num += 1;             result = (num % 10) * pow(10,i) + result;         i++;         num /= 10;     }      return result; }  int main( void ) {     int num;      while (scanf("%d", &num) != EOF)         printf("%d\n", change_to_pmh_number(num));      return 0; }[/quote] 发错了 #include <stdio.h>  int main(void) {     int arr[10];      arr[5] = 10;      for (int i = 0; i < 10; i++)         printf("%d\n", arr[i]);     return 0; }

引用 1 楼 user-11 的回复:对  你尝试一下不就可以了吗= = 对吗？ 尝试一下对不对； #include <stdio.h> #include <math.h>  int change_to_pmh_number(int num) {     int i = 0;     int tmp, result = 0;      while (num) {         tmp = num%10;         if(tmp % 2 != 0)             num += 1;             result = (num % 10) * pow(10,i) + result;         i++;         num /= 10;     }      return result; }  int main( void ) {     int num;      while (scanf("%d", &num) != EOF)         printf("%d\n", change_to_pmh_number(num));      return 0; }

对  你尝试一下不就可以了吗= =


Question: 请问如何把txt中的字符用c转为二维向量

..文件读取 用fstream 或者FILE fscanf

引用 1 楼 user-1 的回复:int arr[height][wide]; char ch; for(int i=0;i<height;++i) 	for (int j = 0; j < wide; ++j) { 		scanf("%c", &ch); 		arr[i][j] = ch == '1' ? 1 : 0; 	}  这样？ 请问那ch要怎么从txt中间读取呢。。。


Question: 关于c语言动态规划0-1背包问题

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

给你认为可能发生错误的地方插入断点，进行调试

上面程序是从底层到顶层打表，但是运行时输入完数据显示exe.已停止工作？？哪里错了

#include <stdio.h> int v[1000]; int w[1000]; int m[1000][1000]; int x[1000];  int main() {     int i,j,n,c;     scanf("%d%d",&n,&c);     getchar();     for(i=1; i<=n; i++)     {         scanf("%d",&w[i]);     }     getchar();     for(i=1; i<=n; i++)     {         scanf("%d",&v[i]);     }     for(j=0;i<=c;j++)     {         if(j>=w[n])             m[n][j]=v[n];         else             m[n][j]=0;     }     for(i=n-1;i>=1;i--)     {         for(j=0;j<=c;j++)         {             if(j>=w[i])                 m[i][j]=m[i+1][j]>(m[i+1][j-w[i]]+v[i])?m[i+1][j]:m[i+1][j-w[i]]+v[i];             else                 m[i][j]=m[i+1][j];          }     }     printf("最大值是： %d\n",m[1][c]);     for(i=1;i<n;i++)     {         if(m[i][c]==m[i+1][c])             x[i]=0;         else         {             x[i]=1;             c=c-w[i];         }     }     if(m[n][c]!=0)         x[n]=1;     else         x[n]=0;     printf("最优解是： ");     for(i=1;i<=n;i++)     {         printf("%d ",x[i]);     }     return 0;   }


Question: 请问如何把一个数变成所有位数均是偶数的数？

感谢各位的帮助

#include <stdio.h> #include <math.h>  int change_to_pmh_number(int num) {     int i = 0;     int tmp, result = 0;      while (num) {         tmp = num%10;         if(tmp % 2 != 0)             num += 1;             result = (num % 10) * pow(10,i) + result;         i++;         num /= 10;     }      return result; }  int main( void ) {     int num;      while (scanf("%d", &num) != EOF)         printf("%d\n", change_to_pmh_number(num));      return 0; } 参考一下吧

引用 1 楼 wyyy2088511 的回复:#include <stdio.h> int Pow(int x, int y) { 	int result =1;      for(int i=0; i<y; i++) 	 { 	    result  = result*x; 	 } 	 return result; } int ChangeNum(int num) { 	int tmp; 	int result; 	int i=0;     while(num) 	{ 		tmp = num%10; 	    if(tmp%2!=0) 		{ 		    num+=1; 		} 		if(i!=0) 		{ 			result = (num%10)*Pow(10,i)+result;		 		} 		else 		{ 		    result = num%10; 		} 		i++; 		num/=10; 	} 	return result; } void main( void ) { 	int N[]={3,88,298,909,9999,99998};  	for(int i=0; i<sizeof(N)/4; i++) 	{ 	    printf("%d\n",ChangeNum(N[i])); 	}    getchar(); } #include <stdio.h> #include <math.h>  int ChangeNum(int num) {     int i = 0;     int tmp, result = 0;      while (num) {         tmp = num%10;         if(tmp % 2 != 0)             num += 1;             result = (num % 10) * pow(10,i) + result;         i++;         num /= 10;     }      return result; }  int main( void ) {     int N[]={3,88,298,909,9999,99998};     int i;      for(i=0; i<sizeof(N)/4; i++)     {         printf("%d\n",ChangeNum(N[i]));     }     getchar();      return 0; } 这样是不是更好一些，减少对i的判断；  if(i!=0) { result = (num%10)*Pow(10,i)+result; } else {     result = num%10; } 把result赋值为0；