Question: url的编码问题(linux爬虫)

应该时网站编码不同导致的。 举个例子：网站A为gb2312编码，下面包含一些中文链接a,b,c，这些中文链接应该时经过gb2312编码过的，获取a,b,c后通过creat写入到文件中， 然后在read到爬取队列中，然后通过socket发送 html请求（GET 中文链接a），这是发送过去的就是乱码了，请问是什么原因！

抓包处理下！看发送出去的时候是否已经乱码还是网站解析编码不同导致乱码的！


Question: 这是我仅有的结帖分了，我真的不会了，麻烦给改改吧。。。

还有一点哦 你那个应该返回类型是 double类型的 要是除法 会有小数的  你自己改吧 那个就

我帮你解决了啊 你把分都给我吧 一个是你 int EvaluateExpression() {      int a, b, c;     char theta, x;     InitStack(optr);     InitStack(opnd);     Push1(optr,'#');      c = getchar();      while(c != '#' || GetTop1(optr) != '#')     { 	         if(!In(c))  		{ 			if(isspace(c)){ 			c = getchar(); 			continue; 			}  //吃掉空格 32 			Push2(opnd,c); 		 			c = getchar(); 		}          else          switch(Precede(GetTop1(optr),c))         {        case '<':         Push1(optr,c); c = getchar();         break;        case '=':         Pop1(optr,x); c = getchar();         break;        case '>':         Pop1(optr,theta);         Pop2(opnd,b);         Pop2(opnd,a);         Push2(opnd,Operate(a,theta,b));         break;         }     } 	printf("end /n");     return GetTop2(opnd);     return 0; } int main() {     printf("输入表达式:");     printf("the result: %d\n",EvaluateExpression());     system("pause");// 让程序停下来 看结果     return 0; }

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

你加我q吧，毛病太多这里没法数清楚1179675084

你这个程序很混乱，想要做计算机，本身很简单吗，将左右操作数当做字符串存储，用的时候转换成证书不就可以

貌似getchar（） 取数有问题

会调试有时候比会写代码更重要，好好练习一下这个技能吧。。。


Question: 小白路在何方- -

从我的体会来看，对新手来说，学习语言，你能熟练地用它写代码，能看懂别人写的代码。那么，这么语言你就可以先学到这为止了，深入语言是以后的事情。  现在更重要的是掌握业务逻辑方面的知识，掌握常用的算法，图像处理，tcp/ip协议，socket编程等等，音视频压缩编码格式等等。因为公司需要的是这些，而不是个语言大师。掌握这些才能让你更好地找工作。  当你有学有余力时，要不要去深入语言就看你的兴趣了。  所以，我觉得你可以看看你想从事的工作方面的专业知识了。

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

算法数据结构为主，语言为辅，之后最好进行高级主题的研究。譬如数据挖掘，机器学习，模式识别等。

在我脚下——走别人的路，让别人无路可走

如果你是小白的话 想成为大师级别的 我有几个建议 第一 当然是泡网站了啊 看雪论坛 学习OD 天天看汇编这样你会发现你进步会很大的 第二 CSDN 你就在菜鸟区先开始  看每天有人回答菜鸟的问题  你每天拿个小本本 记下来 之后去试试 这样365 * 5 基本基础就有了 而且你以后就可以回答很多新手问题了 因为看过历史的 必然知道这个世界 是陷入无限循环的圈子。不必创新 无限循环懂了 你才能跳出去 第三 之后找一个地方实习 写上6个月代码 之后你的技巧也有了 之后弄6个月API 例如linux你就看UNIX环境 高级编程 windos 就是windos API 找特点方向的API实现一个项目。 第四 天天玩玩OD 这样你看汇编比看你女朋友还亲 你看就知道什么情况 大事何愁不成啊 第五 通信 串口 UDP TCP 无线通信 还有那个自己写协议的通信 你工作都会遇到 之后就是网络方向 搞搞wireshark  天天抓包看看。 第六 前面你已经搞定 遇到瓶颈 或者感觉可以了 之后再家待业，看半年数据结构。差不多了这就。

你要知道自己学习语言是为了学习计算机还是想写软件，如果是后者，你可以暂停学习语言，接下来试试写个软件。不管是windows下的还是linux下的，都需要开始学习系统编程了。

学学c++咯

可以继续学习c语言啊！ 看c和指针，c专家编程！ 然后向Linux编程方向发展，前景还是比较可以的！  坚持就好！

不好意思大多了一个字！是数据结构！

学习一下数据结构体！或者算法与分析!


Question: 怎么在windows应用窗体里面编写c语言程序啊

跟随MSDN里面的教程一步一步慢慢来。

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

楼主可以了解一下Windows SDK，用C语言的API编程。

vs2008创建了一个windows应用窗体那是C++的 MFC吧 里面最好用C++写程序吧  你要写C代码的话 不是要用控制台程序的啊  你要用MFC写C做什么 你要说要MFC里面 用C封装成的类在在MFC里面用还行

在界面资源上找到那个按钮，双击后，会自动添加响应函数，在那个函数里写入要执行的代码，当程序运行时，你单击按钮，填入的代码就会执行


Question: C语言出现 烫烫的乱码 求助求助！！！！

使用前先ZeroMemory一下 或者是加个‘\0’

请判断fscanf函数的返回值！

对电脑而言没有乱码，只有二进制字节；对人脑才有乱码。啊 GBK:0xB0 0xA1,Unicode-16 LE:0x4A 0x55,Unicode-16 BE:0x55 0x4A,UTF-8:0xE5 0x95 0x8A

ZeroMemory

while(! feof(fp)) { fscanf(fp,"%s%s%s%s%s",stu[i].name,stu[i].num,stu[i].donum,stu[i].qq,stu[i].telenum);	     	 i++; } fscanf是格式化读取文件，要根据你在文件里数据的存放方式，根据这个方式读取。比如，看到你下面的fprintf格式，那么你的读取也应该是： fscanf(fp,"%s  %s  %s  %s %s\n",stu[n].name, stu[n].num, stu[n].donum, stu[n].qq, stu[n].telenum); 一般出现乱码是因为字符串找不到'\0'。

fscanf(fp,"%s%s%s%s%s",stu[i].name,stu[i].num,stu[i].donum,stu[i].qq,stu[i].telenum);	  用gets/fgets 吧

发错表情了别理解错了亲

一般出现这种情况就是你引用了你没有初始化的内存空间的

数组没能正确初始化内容（应该是读取的时候没能有正确的'\0'结束符），是VC堆栈的默认值 0xcc。 "烫"用UE二进制方式查看就是 cc cc，即VC对战默认值。

肯定不是加取地址符号。你输入每一个字符串时是否输入过回车呢？

使用前，对你的 数组 变量memset一下

fscanf(fp,"%s%s%s%s%s",&stu[i].name,&stu[i].num,&stu[i].donum,&stu[i].qq,&stu[i].telenum);    加上取地址符 你在试试

谢谢你们了啊 我明白了。

内存没有初始化嘛~ 方法1:二楼说的那样memset一下，例如：memset(a, 0, sizeof(a); 方法2:初始化一下结构体的值，例如struct student stu[100] = {NULL};


Question: 我的本科毕业设计是用VS开发，C语言编写基于无文本的说话人检索系统，不知道怎么做，求大神指导！

matlab可以看看音频处理

可能要傅里叶变换转换成频谱方式，书店买一本专门的语音处理的书看一下，里面有原理和算法。

推荐使用  Audition软件 和  NCTAudioStudio控件 处理音频。

这个要是我做的话 就是用kinect XBOX 360 这个微软的体感器 把声音提取出来的API去搞  你的意思是声音已经录好了 不是实时甄别的 那么思路也就是声音的二进制文件 通过windows的API进行播放它 然而在处理过程中 这些API中的结构体应该是可以取出你想要的东西吧 具体也不是很懂。我大都是都在搞图像处理。


Question: 今天面试被问了个问题。

看看unix网络编程或者windows网络编程等。具体方法比较多，看应用场景了。阻塞，非阻塞，io复用，信号驱动式以及异步io都是可以的。

lz 可以看看  Windows网络编程   的  Winsock 简介 和  Winsock IO 方法

一个就够了，循环accept就好了（处理好阻塞问题）！ accept每次都会返回一个和客户端通信的套接字的 干嘛要建立多个！  网上搜下 网络编程！很基础的东西！


Question: 看深入理解计算机系统，关于移位负数乘法

引用 2 楼 cuisanzhang 的回复:汗一个>_<，我搞错了_，x*6 = x*2*2 + x*2 = (x<<2)+(x<<1);这个是对的。    x*-6 = -(x*6) = -( (x<<2) + (x<<1)) 不是我说，这么简单？？？就是把符号移到外边？？？  沒錯...

你这个题本身都是错的.  比如 x * 6, 可以用移位 + 加法实现;(x << 3) + ( x << 2); 这个条件都是不成立的.  因为计算的原理都是一些逻辑运算, 与,或,非. 所以乘除都可以转换成基本运算.  原理是这样的: x每向左移动一位, 相当于乘以2. 所以你就要相办法把*N,使用分配律把算式分解, 比如你的例子: x*6 = x*4 + x*2 = x*2*2 + x*2  x*6 = x*2*2 + x*2 = (x<<2)+(x<<1);  同理, x*-6 = -(x*6) = -( (x<<2) + (x<<1))


Question: 求助关于链表，不输出结果

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

1) 输出有问题，其实输出可以做个函数，直接调用。  L=Creat_Linklist(); LinkList p=L->next; 如果插入的节点，在p前面或者p==NULL， 插入的节点输出不了。  2）LNode *Get_LinkList(LinkList L,int i)     单链表插入节点，或者数据，应该取第i个节点的前一个节点。    第一个数据的前一个节点是头结点，这个函数无论如何都取不到。    3）int Insert_LinkList(LinkList L,int i,DataType x) { LNode *p,*s; p=Get_LinkList(L,i-1); 第一个数据的前一个节点是头结点，Get_LinkList,这个函数无论如何都取不到。 这样如果插入位置，是第一个位置。    p = Get_LinkList(L,i-1);就没有取到头结点,而是取到头结点的下一个节点了。 于是插入到第二个位置，插入的位置就错误了。  所以    Insert_LinkList(L,1,1); 这个找错位置了 Insert_LinkList(L,2,2);  这个没问题  Insert_LinkList(L,3,3); 这个没问题 Insert_LinkList(L,4,4);  这个没问题  因为输出有问题 所以，依赖输出检查错误，检查不出来。 因为，编译没问题，也没有运行错误； 只有逻辑不对，所以错误不好查找。  因为，编译器，不是逻辑检查器，所以检查不出逻辑错误。 因为，程序运行没有问题，所以逻辑错误，很难检查。  这种情况，先画个流程图什么的，把程序逻辑理一理，也许就出来了。

我把楼主的代码拷贝下来，然后做了必要的缩进就运行了，结果很合理。楼主检查下自己的代码吧，可能是某个小细节的问题

L=Creat_Linklist(); LinkList p=L->next;  因为你的Creat_Linklist函数中会让L->next为NULL, 所以你的p就会NULL.  然后你的循环中判断p!=NULL就不可能成立.  这种问题, 只要你下断, 一步一步执行(F10), 自己就看得到原因了.  编程, 下断点调试是必须要会的东西.


Question: socket 自身有没有并包的属性？

我也是只知道 分包协议会处理好，貌似没设置过这玩意

可以确定的是有自动分包的特性

记得貌似有取消并包优化的设置.不过做一个分包也不麻烦

系统会定期从socket缓冲取出数据，如果数据过多自然就会并包，你说的并包属性并不存在，你可以自己接一个buffer，到达一定大小后send。


Question: 数字母出现个数

你没有调试吧  #include<stdio.h> #include<string.h> int main() { 	int t,k=0,i,j,max,len,l[26]={0}; 	char s[1010]; 	scanf("%d",&t); 	getchar(); 	while(t--) 	{ 		memset (l,0,sizeof (l));//每次清0，或者改在这里定义int l[26]={0}; 		gets(s); 		len=strlen(s); 		for(i=0;i<len;i++) 		{ 			j=s[i]-'a'; 			l[j]++; 		} 		max=l[0]; 		for(i=0;i<26;i++) 		{ 			if(l[i]>max) 			{ 				max=l[i]; 				k=i; 			} 		} 		printf("%c\n",'a'+k); 	} 	return 0; }  代码逻辑是对的，不过数组重复使用，没有清0，上次的数据还都保留着。这是自己挖坑自己跳啊。 你把计算部分程序，写成函数。然后循环调用，就没有这个问题了。  #include<stdio.h> #include<string.h>  void alphacount(){ 	int k=0,i,j,max,len,l[26]={0}; 	char s[1010]; 	gets(s); 	len=strlen(s); 	for(i=0;i<len;i++) 	{ 		j=s[i]-'a'; 		l[j]++; 	} 	max=l[0]; 	for(i=0;i<26;i++) 	{ 		if(l[i]>max) 		{ 			max=l[i]; 			k=i; 		} 	} 	printf("%c\n",'a'+k); }  int main() { 	int t; 	scanf("%d",&t); 	getchar(); 	while(t--) 		alphacount(); 	return 0; }

#include<stdio.h> #include<string.h> int main() { int t,k=0,i,j,max,len; char s[1010]; scanf("%d",&t); getchar();     while(t--) { l[26]={0}//把这个数组初始化放在这里面貌似就好了 gets(s); len=strlen(s); for(i=0;i<len;i++) { j=s[i]-'a';     l[j]++; }          max=l[0]; for(i=0;i<26;i++)	 { if(l[i]>max) {	     	max=l[i];         k=i; }         } printf("%c\n",'a'+k); } return 0; }

引用 5 楼 lm_whales 的回复:从文件读取数据，结果写入文件。 文件读写，比控制台读写快多了。 我觉得不是时间限制的问题，而是代码有点问题，试过几次有bug

从文件读取数据，结果写入文件。 文件读写，比控制台读写快多了。

但是我也不知道怎么做，坐等解释

刚才运行了一下，貌似不能实现所说目的

看样子没什么大问题，如果是时间因素过不了，可以把下面语句改一下 //len=strlen(s); //for(i=0;i<len;i++) for (i = 0; s[i] != '\0'; i++)


Question: Floating point exception (core dumped) 的问题

有可能是溢出，然后sum =0；然后p(x)=0 或者p(y)=0; 然后除法错中断。。。。。。。。。。。

core dumped 一般是 fatal error，   换个小点的输入确认一下

溢出应该不会core dumped吧。  引用 1 楼 user-4 的回复:unsigned long 溢出了， 试了下代码，把 x，y 都相对改小点是OK的！ 这里估计要特别作大数处理了，不能这么简单的用unsigned long long 了


Question: 实数数组的文件读写问题

#include <stdio.h> double d[200*100000]; FILE *f; int y,x; int main() {     for (y=0;y<200;y++) {         x=0;         d[y*100000+x]=(double)y*100000.0+(double)x;         x=99999;         d[y*100000+x]=(double)y*100000.0+(double)x;     }     f=fopen("d.dat","wb");     fwrite(d,sizeof(double),200*100000,f);     fclose(f);      for (y=0;y<200;y++) {         x=0;         d[y*100000+x]=0.0;         x=99999;         d[y*100000+x]=0.0;     }       f=fopen("d.dat","rb");     fread(d,sizeof(double),200*100000,f);     fclose(f);      for (y=0;y<200;y++) {         x=0;         printf("%.15lg,",d[y*100000+x]);         x=99999;         printf("%.15lg\n",d[y*100000+x]);     }      return 0; } //0,99999 //100000,199999 //200000,299999 //300000,399999 //400000,499999 //500000,599999 //600000,699999 //700000,799999 //800000,899999 //900000,999999 //1000000,1099999 //1100000,1199999 //1200000,1299999 //1300000,1399999 //1400000,1499999 //1500000,1599999 //1600000,1699999 //1700000,1799999 //1800000,1899999 //1900000,1999999 //2000000,2099999 //2100000,2199999 //2200000,2299999 //2300000,2399999 //2400000,2499999 //2500000,2599999 //2600000,2699999 //2700000,2799999 //2800000,2899999 //2900000,2999999 //3000000,3099999 //3100000,3199999 //3200000,3299999 //3300000,3399999 //3400000,3499999 //3500000,3599999 //3600000,3699999 //3700000,3799999 //3800000,3899999 //3900000,3999999 //4000000,4099999 //4100000,4199999 //4200000,4299999 //4300000,4399999 //4400000,4499999 //4500000,4599999 //4600000,4699999 //4700000,4799999 //4800000,4899999 //4900000,4999999 //5000000,5099999 //5100000,5199999 //5200000,5299999 //5300000,5399999 //5400000,5499999 //5500000,5599999 //5600000,5699999 //5700000,5799999 //5800000,5899999 //5900000,5999999 //6000000,6099999 //6100000,6199999 //6200000,6299999 //6300000,6399999 //6400000,6499999 //6500000,6599999 //6600000,6699999 //6700000,6799999 //6800000,6899999 //6900000,6999999 //7000000,7099999 //7100000,7199999 //7200000,7299999 //7300000,7399999 //7400000,7499999 //7500000,7599999 //7600000,7699999 //7700000,7799999 //7800000,7899999 //7900000,7999999 //8000000,8099999 //8100000,8199999 //8200000,8299999 //8300000,8399999 //8400000,8499999 //8500000,8599999 //8600000,8699999 //8700000,8799999 //8800000,8899999 //8900000,8999999 //9000000,9099999 //9100000,9199999 //9200000,9299999 //9300000,9399999 //9400000,9499999 //9500000,9599999 //9600000,9699999 //9700000,9799999 //9800000,9899999 //9900000,9999999 //10000000,10099999 //10100000,10199999 //10200000,10299999 //10300000,10399999 //10400000,10499999 //10500000,10599999 //10600000,10699999 //10700000,10799999 //10800000,10899999 //10900000,10999999 //11000000,11099999 //11100000,11199999 //11200000,11299999 //11300000,11399999 //11400000,11499999 //11500000,11599999 //11600000,11699999 //11700000,11799999 //11800000,11899999 //11900000,11999999 //12000000,12099999 //12100000,12199999 //12200000,12299999 //12300000,12399999 //12400000,12499999 //12500000,12599999 //12600000,12699999 //12700000,12799999 //12800000,12899999 //12900000,12999999 //13000000,13099999 //13100000,13199999 //13200000,13299999 //13300000,13399999 //13400000,13499999 //13500000,13599999 //13600000,13699999 //13700000,13799999 //13800000,13899999 //13900000,13999999 //14000000,14099999 //14100000,14199999 //14200000,14299999 //14300000,14399999 //14400000,14499999 //14500000,14599999 //14600000,14699999 //14700000,14799999 //14800000,14899999 //14900000,14999999 //15000000,15099999 //15100000,15199999 //15200000,15299999 //15300000,15399999 //15400000,15499999 //15500000,15599999 //15600000,15699999 //15700000,15799999 //15800000,15899999 //15900000,15999999 //16000000,16099999 //16100000,16199999 //16200000,16299999 //16300000,16399999 //16400000,16499999 //16500000,16599999 //16600000,16699999 //16700000,16799999 //16800000,16899999 //16900000,16999999 //17000000,17099999 //17100000,17199999 //17200000,17299999 //17300000,17399999 //17400000,17499999 //17500000,17599999 //17600000,17699999 //17700000,17799999 //17800000,17899999 //17900000,17999999 //18000000,18099999 //18100000,18199999 //18200000,18299999 //18300000,18399999 //18400000,18499999 //18500000,18599999 //18600000,18699999 //18700000,18799999 //18800000,18899999 //18900000,18999999 //19000000,19099999 //19100000,19199999 //19200000,19299999 //19300000,19399999 //19400000,19499999 //19500000,19599999 //19600000,19699999 //19700000,19799999 //19800000,19899999 //19900000,19999999 //

怎么从文件里，把这些数据读出来，继续放在一个二维数组里面？ 这个好像比较复杂一点。。。  引用 6 楼 u012373530 的回复:不好意思，写错了一点点

引用 5 楼 u012373530 的回复:double buf[200][10000]; double** p=buf; FILE* p_file=fopen("文件名","w"); while(*p!=NULL){     fwrite(*p,sizeof(double),10000,p_file);     p++; } fclose(p_file); 读的话差不多。 不好意思，写错了一点点

double buf[200][10000]; double** p=buf; FILE* p_file=fopen("文件名","w"); while(*p!=NULL){     fwrite(*p,sizeof(double)*10000,1,p_file);     p++; } fclose(p_file); 写的话差不多。

引用 2 楼 youth0826 的回复:给几句代码参考一下吧  [quote=引用 1 楼 turingo 的回复:] 用fread/fwrite分批读写。  google

给几句代码参考一下吧

用fread/fwrite分批读写。  引用 楼主 youth0826 的回复:问题应该很简单吧 假设有一个double的二位数组，大概200x10000维 其实就是个数据文件 10000可能是变动的，不是固定的。 怎么把这个数组存到一个txt或者dat文件什么的？ 然后，怎么从文件里，把这些数据读出来，继续放在一个二维数组里面？ 大家有什么好方法？谢谢！


Question: 顺序栈操作：可以从栈底向栈顶依次遍历元素么？

栈是基于LIFO概念的一种表现形式，你的行为违反了LIFO思想

你提出的问题是可以实现的，栈结构是你自己设置的，你当然可以从栈底到栈顶，但是这也不叫栈了? 栈的特点应该是先入后出

这是做什么？你要输出S 中的data数组中小于top的值？

typedef struct{ 	elemtype data[maxsize]; 	int top; } seqstack;


Question: 这代码邪门了

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

楼主这是在android上用C开发？NDK？

安卓的c4droid ，头文件没那么大，编译比VC 快，立马出结果，适合学习

实际上，好像不是超范围的缘故，但是说是编译器原因更大

不会的，读文件内容单引号内的内容，最长的也只有32个字符。

换个编译器，看看是否结果还这样。

楼主，你能告诉我你头像是什么图片吗，我很好奇哎

楼主用的什么IDE啊

文件指针p/pp和数组str都可能超出范围。  引用 楼主 u010211892 的回复:难道是内存出了问题吗？很明显bb,dd应该一样，但结果居然。。。 // awesome #include"stdio.h" #include"time.h" int main() { 	int cc = 0, bb = 0, aa = 0, dd = 0; 	long yy = 0; 	char t[7], str[40]; 	long t1 = 1; 	t[2] = 0; 	FILE *p = NULL, *pp = NULL; 	p = fopen("/sdcard/sqlN.txt", "r+"); 	pp = fopen("/sdcard/gottenN.txt", "w+"); 	while (1) 	{ 		aa++; 		cc++; 		while ((t[3] = fgetc(p)) != '\'') 		{ 		} 		while ((str[t[2]++] = fgetc(p)) != '\''); 		str[t[2] - 1] = 0, t[2] = 0; 		fprintf(pp, "%s", str); 		 		bb++; 		dd++; 		if (dd > 76212) 		{ 			printf("aa=%d,dd=%d,cc=%d,bb=%d\n", aa, dd, cc, bb); 			return (1); 		} 	}  } 结果：

(str[t[2]++] = fgetc(p) --》 str超过40， 把后面的内存（包括dd）给覆盖了吧。


Question: 填数字的问题

我只是随便看一眼 要是我的话 我会观察 x + y + z = 1 那么也就是说 x小于1 y小于1 z小于1 这样会快些了多 还有当前俩个大于1的时候 也不满足 最后也是最重要的一点就是 你会发现最后竟然是等于1 而且他们都是几十分之几 竟然最后能通分等于1 你把他们分母统一一下 你会发现原来也不是很难 分子等于分母

2楼基本正解。。。 按2楼思路写了个小程序，竟然唯一解（去除交换律）  #include <stdio.h> #include <algorithm> #include <functional> using namespace std ;  int main() { 	int a[] = {1,2,3,4,5,6,7,8,9}; 	do 	{ 		int ef = a[4]*10+a[5]; 		int bc =a[1]*10+a[2]; 		int hi =a[7]*10+a[8]; 		if (a[0]*ef*hi+a[3]*bc*hi+a[6]*bc * ef ==bc*ef*hi ) 		{ 			printf("%d/%d+%d/%d+%d/%d=1\n",a[0],bc,a[3],ef,a[6],hi); 		} 	}while (next_permutation(a,a+9)); 	getchar(); 	return 0; }

全排列

我这也是个笨办法 观察一下 a/(bc) +d/(ef) +g/(hi) =1 其中： bc = b*10+c ef = e*10 + f hi = h*10+i 于是： a/(bc) +d/(ef) +g/(hi) =1 <==> a*ef *hi +d *bc*hi + g* bc * ef = bc*ef*hi   先求组合，然后对每一个组合，检查 a*ef *hi +d *bc*hi + g* bc * ef == bc*ef*hi 是否成立  这里都是整数计算 2位*2位*2 位, 结果是6位数 ,不超过 32Bits.


Question: 两个char型数据比较大小的疑惑

sorry,其它地方有些异常导致这个问题出现异常.谢谢.

b 和c已经被设置为unsignd char 了,这个还需要吗?

if((unsigned char)a.b[1]>(unsigned char)a.c[1])

试了解决不了问题

根据需要 明确写成  signed char 类型  或者是 unsigned char 类型


Question: 请教 sscanf 的写法！

if (6!=sscanf(buf,"\"%[^\"]\",\"%[^\"]\",\"%[^\"]\",\"%[^\"]\",%d,\"%[^\"]",zd1,zd2,zd3,zd4,&zd5,zd6)) {  printf("[%s]格式错误!\n",buf);  exit(1); } else {  //格式正确 }

引用 1 楼 user-2 的回复:sscanf(buf,"\"%[^\"]\",\"%[^\"]\",\"%[^\"]\",\"%[^\"]\",%s\,\"%[^\"]",zd1,zd2,zd3,zd4,zd5,zd6);  你的%s 胃口好 把剩下的全部一口吃进去了 另外什么是 \, ??  请教 该怎么改呢


Question: 赋值出现异常

引用 4 楼 zhao4zhong1 的回复:scale_val = (double)(var1/var2); 似应改为 scale_val = (double)var1/(double)var2;  ++

引用 1 楼 u012071720 的回复:temp_val = scale_val * i + avg2 - scale_val * avg1 + 0.5; 各个值得数据类型不相同，会发生类型转换，这些类型彼此之间有优先级，级别低的数和级别高的运算后，类型会转换成级别高的数据类型，从未会引起精度变化 这样结果就会变了。。。。。。。。。

scale_val = (double)(var1/var2);  var1, var2没赋值


Question: 关于自增自减的一个问题求指教

引用 6 楼 z1179675084 的回复:我给你好好说说关于第一个q = 15，这基本是没有问题的，所有编译器结果都应该相同，但是为什么是这么个结果呢？在C语言里面存在顺序点！至于什么是顺序点你百度一下，我就不浪费时间了，在这个语句中顺序点是”；“但赋值发生在顺序点之前，其副作用已经产生，所以结果是5 + 5 + 5，你可以写个程序验证  int a = 5; a = (a++) + (a++) + (a++); printf("%d",a);  这个结果是18，为什么？同上5+5+5 = 15；之后遇到”；“遇到顺序点时所有的赋值都会反馈回去，所以这里15要加3次，结果是18. 再看你的p = 24还是22，这个结果还真是不确定的，C里面没有给出其计算顺序，看做编译器的人了。 22 = 7 + 7 + 8； 24 = 8 + 8 + 8； 不要问我为什么这么算，问问做编译器的人吧。我个人觉得不要纠缠这东西，没有任何意义，只有大学老师才拿些这玩意来显示他很有水平，其实他自己都不一定真的懂！ 最后一个，为什么顺序是反的，其实从你自己的结果来看就很明白了，其实不光是你这里的printf函数是反的，其他函数也是的，瞧瞧下面这个！  #include <stdio.h> void print(int i,int j) { 	printf("%d\n",i); 	printf("%d\n",j); } int main() {  	int a = 5; 	print(a++,a++); 	return 0; }  这里也是和顺序点相关的，但是这里需要注意一下，楼上很多都说printf结果和编译器有关，确实有关系（函数参数的求职顺序依赖于编译器的实现），但是你的那个结果和我的这个例子它是由顺序点决定的，不管编译器是哪种，结果都一样，希望别搞混了。 写了这么多了，我就再多费几句话说说什么是顺序点吧！ 顺序点是指在执行过程中修改变量值的最晚时刻，在程序到达顺序点的时候，之前所做的一切操作必须反映到后续的访问中。顺序点存在于： 每个完整表达式结束时； && || ？： 以及逗号表达式的每个云端对象之后 函数调用中对所有实际参数的求值完成之后（进入函数体之前）。 不好意思，现在才看到，虽然看的云里雾里，不过写了这么多，感谢！！

总结：就是尽量不要写这样的代码，太水，误导了自己，后期也比较难维护！ 如果实在要写，就分多个语句来完成！

引用 6 楼 z1179675084 的回复:我给你好好说说关于第一个q = 15，这基本是没有问题的，所有编译器结果都应该相同， 既然能说错序列点 既然知道副作用  怎么还会有 所有编译器结果都是 15 这种奇怪的想法 别说能举出反例  http://ideone.com/jkGwfP 就在找不到反例 能确定是未定义行为就别指望结果有意义

编译环境不同造成的，

1)这个是标准，规定的，未定义行为，结果有编译器厂商决定，想咋搞就咋搞。 2）编译器，可以从左向右计算，也可以从右向左计算，也可以从两头向中间计算。 想在那里获得结果，就在那里获得结果，甚至 VC的不同版本，结果都不一样。  有那功夫，你就自己去分析吧。 没工夫就别管他。

函数调用也许和顺序点有关。 不过实际上，许多编译器，按照参数的入栈顺序，计算参数的值。  然而 ++,--确实，有很大的不确定性： int a = 5; print(a++,a++);   VC6   结束才行动，输出 5，5 VC9   一边输出一边行动，输出6，5 VC10  结束才行动，输出 5，5

不要把有限的生命浪费在这种结果不确定的代码上。

看的云里雾里，不过还是谢了~ 引用 楼主 a1385341 的回复:  为什么这里P的值是24？我自己的理解是b最后的值是8，所以就是8+8+8=24；继续：  在VC6.0中这里的值又是22了，我的理解是可能编译环不同，这里计算方式为6+7+8=21；问题是这里居然是22， 我在书上看到这里p是自增了1，我又把这个问题理解为++（6+7+8）;这样理解到底对不对？ 还有一个问题，   这里最后一行不应该是输出8，9吗？怎么反了？ 请大神指点； 以为自己看了几本书C语言算是知道一点点语法了，没想到在上课的时候老师讲到这里才发现自己对自增自减都不清楚，真是惭愧啊！

参考http://bbs.csdn.net/topics/370153775  引用 楼主 a1385341 的回复:  为什么这里P的值是24？我自己的理解是b最后的值是8，所以就是8+8+8=24；继续：  在VC6.0中这里的值又是22了，我的理解是可能编译环不同，这里计算方式为6+7+8=21；问题是这里居然是22， 我在书上看到这里p是自增了1，我又把这个问题理解为++（6+7+8）;这样理解到底对不对？ 还有一个问题，   这里最后一行不应该是输出8，9吗？怎么反了？ 请大神指点； 以为自己看了几本书C语言算是知道一点点语法了，没想到在上课的时候老师讲到这里才发现自己对自增自减都不清楚，真是惭愧啊！


Question: 一道strlen（）笔试题

感谢楼上 我知道了

楼上都正解，你这样写char a[10] = {};//初始化一下 然后再执行看看。其实就你的代码，你可以把字符串a打印出来看看里面到底是什么。

真正的核心问题是  没有字符串结尾的 '\0'  清空是解决这个问题的一个很拙略的做法  strlen 要求传入参数是 c风格字符串[以\0结尾]

没有清空 ，不管是 5 还是15 都是错的！  man  下strlen的用法，

strlen（）测试字符串长度的原理是遇到\0即0x00才会认为字符串结束，从而得到长度，楼主char a[10]字符串并没有初始化，也就是里面放的什么数都可能，在gcc中也许a[5]=0x00,在vc中可能越界后第六个字节为0x00，这才导致了如上所述的结果，所以应该在使用字符串时要有初始化的好习惯，应该用memset(a,0x00,10)来将刚申请的字符串置0.。。。希望对您有帮助

for前面先memset一下。清下零，数组里面存的是随机数据，但是strlen要见到0才停止。


Question: 如何隐藏u盘部分空间

U盘不像硬盘，U盘就算你分了多个区分，Windows还是只能识别最前面的一个分区，例如：4GU盘分为2G，2G，那么插上电脑后，它显示为2G盘，后面的2G盘发现不了，也写不进数据，分区工具可用DiskGenius即可，

引用 3 楼 xiaokuiing 的回复:引用 1 楼 cwt8805 的回复:fdisk给u盘分区我试了下，没分区的空间是被隐藏了，但是我能往那里面写入数据么，c语言有对应的接口么 应该说没有格式化的分区是被隐藏了吧，或者你可以把一个分区格式化为windows无法识别的文件系统。比如ext。这个分区就可以在linux下正常读写，或者借助于软件在windows下读写。当然如果你想自己实现这个软件的话，就必须得研究下ext文件系统。

奉劝楼主不要把有限的生命浪费在无限的加密解密死循环中！

这个可以学习下

fdisk给u盘分区


Question: 输出结果为什么是126

引用 1 楼 Idle_Cloud 的回复:-130的整数二进制是0xffffff7e 把它赋值给char，且都是有符号类型。就剩下后面的了7e 打印出来就是126 谢谢


Question: 建立链栈出现逻辑错误，希望大家帮我

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

引用 5 楼 user-4 的回复:既然都使用二级指针了 建议统一的函数都使用二级指针 统一风格 同时能避免粗心的错误 这有些太极端了吧！

还得在加一级指针 否则的话 linkStack top;// InitStack(top);//建立 实参top赋值给形参S后 S改变了（也就是分配了内存），指向了新的地方 但是它并没有在最后把这个地址返回给实参 所以 实参最后还是没有被初始化[/quote] 这样的话也就是进栈和出栈需要用二级指针，其他的不用？

引用 2 楼 u012282088 的回复:[quote=引用 1 楼 max_min_ 的回复:]   linkStack *top = NULL;//     InitStack(top)； 对应的操作栈的接口参数都改成传递指针的形式先 int InitStack(linkStack *S); void StackEmpty(linkStack *S); 我在定义函数的时候已经有传递指针，还有在弄一次么？  typedef struct sNode{//定义函数     ElemType data;//数据域     struct sNode *next;//指针 }sNode,*linkStack; [/quote] 还得在加一级指针 否则的话 linkStack top;// InitStack(top);//建立 实参top赋值给形参S后 S改变了（也就是分配了内存），指向了新的地方 但是它并没有在最后把这个地址返回给实参 所以 实参最后还是没有被初始化

引用 1 楼 max_min_ 的回复:linkStack *top = NULL;//     InitStack(top)； 对应的操作栈的接口参数都改成传递指针的形式先 int InitStack(linkStack *S); void StackEmpty(linkStack *S); 我在定义函数的时候已经有传递指针，还有在弄一次么？  typedef struct sNode{//定义函数     ElemType data;//数据域     struct sNode *next;//指针 }sNode,*linkStack;


Question: C语言笔试的一道题

多谢指点，明白了

long long 类型占据了两个%d的位置，你运行出的界面中并未显示出t.y的值。 你在printf第一个参数里面再加一个%d就能打印t.y变量的值了


Question: 一到数据结构问题 求改错

1)Push,Pop做啥用的????? 2)分配的内存要释放  void DestroyStack(Stack &s){     delete[] s.base; } int main() {     Stack s;     InitStack (s,20);     char ch[50];       cout << "输入表达式"<<endl;     cin>>ch;         for(int i;i<strlen(ch);i++){           //简洁版，可能会出错。          if(ch[i]=='(')             Push(s,ch[i]);         else if (ch[i]==')')              Pop(s);                 }     if(s.top == s.base)      {         cout<<"表达式的括号是配对的。"<<endl;     }     else      {         cout<<"表达式的括号不是配对的。"<<endl;     }     DestroyStack(s);     return 0; }  //精细版 int main(){     Stack s;     InitStack (s,20);     char ch[50];     int error=0;       cout << "输入表达式"<<endl;     cin>>ch;         for(int i;i<strlen(ch);i++)       {               if(ch[i] != ')') Push(s,ch[i]);        else {               while(s.top !=s.base && *(s.top) !='(')               {                    Pop(s);               }               if(*s.top !='('){                      cout<<"表达式的括号不是配对的,丢失左括号 \'(\'。"<<endl;                       error++;                   }           }            }     if(error ==0 ){        if(s.top == s.base)         {            cout<<"表达式的括号是配对的。"<<endl;        }        else         {            cout<<"表达式的括号不是配对的。丢失右括号 \')\'"<<endl;         }     }      DestroyStack(s);     return 0; }

第49行i需要初始化吧，int i=0；


Question: 关于双向循环链表运行Locate函数的一些问题

你写的这个代码没有使用面向对象的设计思想，你这个还是面向过程的，看起来有点费劲，全局变量最好不要这么用，这么用很容易出错，也不便于阅读，malloc可以换成new可能会好点，和链表相关的操作可以放在类里面，这样容易理解，也不容易出错。

对不起哦，换个算法，这个算法已经完善但是就是输出的时候可能会有指针指错的地方。。 #include <iostream> #include <malloc.h> #include <stdlib.h> #include <stdio.h> using namespace std;  typedef int ListData; typedef struct dnode  { 	int data;  	int freq;                             struct dnode * prior, * next;      } DblNode; typedef DblNode * DblList; DblList first;  void CreateDblList ( int n )  {   first = ( DblNode * ) malloc ( sizeof ( DblNode ) );   if ( first == NULL )   {  		printf ( "存储分配错!\n" );   		exit (1);    }   first->prior = first->next = first;   DblList c,l=first;   for(int i=1;i<=n;i++)   {         c=(DblNode *)malloc(sizeof(DblNode));         c->data=i;         c->prior=l; 	    c->next=first; 	    c->freq=0; 	    l->next=c; 	    first->prior=c; 	    l=l->next;   }     }  void locate(int &x) { 	DblNode *p = first->next; 	while ( p != first && p->data != x ) p = p->next; 	if ( p != first )  	{	 		 p->freq++; 		 DblNode *current=p;          current->prior->next=current->next;          current->next->prior=current->prior;          p=current->prior;          while(p!=first && current->freq>p->freq ) p=p->prior;          current->next= p->next ;          current->prior=p;          p->next->prior=current;          p->next= current ; 	} 		else	cout<<"Sorry. Not find!\n";					//没找到 }   	    	   int main() {     int n,x;     cout<<"please input the link list length: "<<endl;     cin>>n;     CreateDblList(n);     cout<<"The link list data are: " <<endl;     DblNode *k=first->next;     for(int i=1;i<=n;i++)     { 		cout<<"The   1 node is "<<k->data<<", its frequency is "<<"0."<<endl; 		k=k->next; 	} 	k=first->next; 	cout<<"Let's start to test the Locate Function.<-1 means stopping input number>"<<endl; 	cout<<"please input number:"; 	cin>>x; 	while(x>=0) 	{ 		locate(x); 		cout<<"please input number:"; 		cin>>x; 	} 	cout<<"After the test,the link list data are:"<<endl; 	for(int i=1;i<=n;i++)     { 		cout<<"The   1 node is "<<k->data<<", its frequency is "<<k->freq<<endl; 		k=k->next; 	} 	return 0; 	 }


Question: 自己写的8皇后递归移位实现

#include "iostream"       using namespace std;       #include "time.h"        // sum用来记录皇后放置成功的不同布局数；upperlim用来标记所有列都已经放置好了皇后。       long sum = 0, upperlim = 1;             // 试探算法从最右边的列开始。       void test(long row, long ld, long rd)       {           if (row != upperlim)           {               // row，ld，rd进行“或”运算，求得所有可以放置皇后的列,对应位为0，               // 然后再取反后“与”上全1的数，来求得当前所有可以放置皇后的位置，对应列改为1               // 也就是求取当前哪些列可以放置皇后               long pos = upperlim & ~(row | ld | rd);                while (pos)    // 0 -- 皇后没有地方可放，回溯               {                   // 拷贝pos最右边为1的bit，其余bit置0                   // 也就是取得可以放皇后的最右边的列                   long p = pos & -pos;                                                                  // 将pos最右边为1的bit清零                   // 也就是为获取下一次的最右可用列使用做准备，                   // 程序将来会回溯到这个位置继续试探                   pos -= p;                                               // row + p，将当前列置1，表示记录这次皇后放置的列。                   // (ld + p) << 1，标记当前皇后左边相邻的列不允许下一个皇后放置。                   // (ld + p) >> 1，标记当前皇后右边相邻的列不允许下一个皇后放置。                   // 此处的移位操作实际上是记录对角线上的限制，只是因为问题都化归                   // 到一行网格上来解决，所以表示为列的限制就可以了。显然，随着移位                   // 在每次选择列之前进行，原来N×N网格中某个已放置的皇后针对其对角线                   // 上产生的限制都被记录下来了                   test(row + p, (ld + p) << 1, (rd + p) >> 1);                                             }           }           else              {               // row的所有位都为1，即找到了一个成功的布局，回溯               sum++;           }       }        int main(int argc, char *argv[])       {           time_t tm;           int n = 16;            if (argc != 1)               n = atoi(argv[1]);           tm = time(0);            // 因为整型数的限制，最大只能32位，           // 如果想处理N大于32的皇后问题，需要           // 用bitset数据结构进行存储           if ((n < 1) || (n > 32))                            {               printf(" 只能计算1-32之间\n");               exit(-1);           }           printf("%d 皇后\n", n);            // N个皇后只需N位存储，N列中某列有皇后则对应bit置1。           upperlim = (upperlim << n) - 1;                     test(0, 0, 0);           printf("共有%ld种排列, 计算时间%d秒 \n", sum, (int) (time(0) - tm));           system("pause");           return 0;       }    测试过最快的一个

引用 1 楼 Benjaminzhou93 的回复:不知道这算不算高效，明天研究研究网络上写的算法 ps（怎么传源代码可复制图片，就是带颜色的那种）  这个八皇后高效问题，可以网上搜索下！很多的！  至于代码格式，在发贴或者编译回复的时候，上方有个添加代码格式的选择<>， 加载人头和笑脸之间的， 点击下c/c++，把想要添加的代码加中出现的[code]之间就好了！

引用 3 楼 zhao4zhong1 的回复:仅供参考：（绝对不高效）#include <stdio.h> int d[8][8]; int n; void queen8(int L) {     int x,y;      if (8==L) {         n++;         printf("%d\n",n);         for (y=0;y<8;y++) {             for (x=0;x<8;x++) { //              printf("%d",d[y][x]);                 if (d[y][x]) printf("■");                 else         printf("□");             }             printf("\n");         }         return;     }     for (x=0;x<8;x++) {         for (y=0;y<L;y++) {             if  (              d[y][x      ]              || (x-(L-y)>=0 && d[y][x-(L-y)])              || (x+(L-y)< 8 && d[y][x+(L-y)]))                 break;         }         if (y>=L) {             d[L][x]=1;             queen8(L+1);             d[L][x]=0;         }     } } int main() {     int y,x;     for (y=0;y<8;y++) {         for (x=0;x<8;x++) {             d[y][x]=0;         }     }     queen8(0);     return 0; }  多了一种参考方案

引用 6 楼 baipv008 的回复:试了下，求解耗时基本为0吧。时间全是花在输出上。 //*八皇后 void printQueen(int* queen,int top) { 	for(int j=0;j<top;j++) 	{ 		for(int i=0;i<8;i++) 			if(i==queen[j]) 				printf("Q"); 			else 				printf("."); 		printf("\n"); 	} 	printf("\n");  } int issolution(int* queen,int top) { 	for(int i=0;i<top;i++) 		for(int j=0;j<top;j++) 			if(j!=i) 			{ 				if(abs(i-j)==abs(queen[i]-queen[j]) || queen[i]==queen[j]) 					return 0; 			} 	return 1; } int main() { 	clock_t ct_begin, ct_end; 	ct_begin = clock();  	int queen[8],top=-1,count=0; 	queen[++top]=0; 	while(1) 	{ 		if(!issolution(queen,top+1)) 			queen[top]++; 		else if(top==7) 		{ //			printQueen(queen,top+1); 			queen[top]++; 			count++; //			getchar(); 		} 		else 			queen[++top]=0; 		while(queen[top]>=8) 		{ 			top--; 			if(top<0) 				break; 			queen[top]++; 		} 		if(top<0) 			break; 	} 	ct_end = clock(); 	printf("一共%d个解",count); 	printf("used time: %f\n", (double)(ct_end - ct_begin)/CLOCKS_PER_SEC );  	getchar(); }//*/ 收下了

引用 5 楼 max_min_ 的回复:[quote=引用 1 楼 Benjaminzhou93 的回复:] 不知道这算不算高效，明天研究研究网络上写的算法 ps（怎么传源代码可复制图片，就是带颜色的那种）  这个八皇后高效问题，可以网上搜索下！很多的！  至于代码格式，在发贴或者编译回复的时候，上方有个添加代码格式的选择<>， 加载人头和笑脸之间的， 点击下c/c++，把想要添加的代码加中出现的[code]之间就好了！[/quote]好

引用 1 楼 Benjaminzhou93 的回复:不知道这算不算高效，明天研究研究网络上写的算法 ps（怎么传源代码可复制图片，就是带颜色的那种） 我的奔腾cpu上大概需要1.5~1.9才能解的出来


Question: gerchar使用

getchar();接收前面输入的回车，这样后面的代码scanf("%c",&choice);就不会接收回车符，而是等待用户输入字符。其实通常在接收字符型数据前用fflush(stdin);清空输入缓冲区，确保不影响后面的数据读取.

楼上两位说的很对，getchar()是吃掉回车，要不然后面scanf字符的时候会读入回车  其实也以不使用getchar()函数，在scanf("%c",&choice);函数中的%c前面加空格也是可以的  改为 scanf(" %c", &choice);

scanf(); 格式化输入函数的 如果员工的工资需要小数的话， 最好把wage定义float或者double， 如果是定义成的是int的话， 就得用scanf("%d", &wage);  getchar是取出输入缓冲区里的一个字节而已！当然这里是取出回车符了！

一般scanf()后跟的getchar()是吃掉回车，使的下一次调用时scanf()不出错

术语是scanf 属于‘行缓冲’的 你要了解 无缓冲 行缓冲 和全缓冲的区别和用法


Question: 急！！！！后天交！！！栈的后缀式求值，请大家帮忙！！！

引用 1 楼 N_sev7 的回复:     InitStack(OPTR);   ///你传了一个类型，没有传参数     InitStack(OPND);  改为  typedef struct {     char *base;     char *top;     int stacksize; }OPTR;//运算符栈  typedef struct {     int *base;     int *top;     int stacksize; }OPND;//运算数栈 OPTR optr; OPND opnd;    ...    ... InitStack(optr);   ///你传了一个类型，没有传参数 InitStack(opnd);       太感谢你了，哈哈，谢谢


Question: 好久不写代码，最简单的c程序不知哪错了

恩，我知道输入格式不对，有谁可以深入说一下为什么格式输入错误，b就是随机数吗？

#include<stdio.h>少了空格

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

引用 11 楼 zwb8848happy 的回复:哦，我输入数据的时候是以空格分开的； 这样b就是一个随机数，这为什么？  输入用逗号隔开。

哦，我输入数据的时候是以空格分开的； 这样b就是一个随机数，这为什么？

一个问题并不是找到了问题的正确方式就是懂了  而是由这个问题引发的思考  这才是重要的  C标准库 scanf的实现为（主要理解变长变元表） /* _Scanf function */ #include <ctype.h> #include <limits.h> #include <stdlib.h> #include <string.h>  fscanf(fp,"%s%s%s%s%s",stu[i].name,stu[i].num,stu[i].donum,stu[i].qq,stu[i].telenum);    int _Scanf(int (*pfn)(void *,int),void *arg,const char *fmt,va_list ap) { 	const char *s; 	int nconv = 0; 	_Sft x; 	x.pfn = pfn; 	x.arg = arg; 	x.ap = ap; 	x.nchar = 0; 	for(s = fmt;;++s) 	{ 		int ch; 		int n; 		wchar_t wc; 		_Mbsave state = {0}; 		while(0 <(n = _Mbtowc(&wc,s,MB_CUR_MAX,&state))) 		{                       //check type of multibyte char  			s+= n; 			if(wc =='%') 				break; 		else if(wc <= UCHAR_MAX && isspace(wc))//判断是否为空格 如果是跳过 			{ 				while (isspace(*s)) 				++s;	/*match any white-space */ 				while(isspace(ch = GET(&x))); 				UNGET(&x,ch); 			} 			else {// 识别变量 			 ...       			}	/* match literal text */  			if(*s == '\0') 				return (nconv); 		} 此处略去300字

代码没问题，应该是输入问题，楼上正解

代码本身没有问题！输入格式注意下就好！楼上正解

你得输入 1,2 注意逗号。

这样写的scanf似乎会把逗号赋值给b

感觉把SCANF语句里面的逗号删去就应该行了

引用 楼主 zwb8848happy 的回复: #include<stdio.h>  int main() { 	int a,b;       scanf("%d,%d",&a,&b);      printf("%d\n",a+b);  	return 0; }  代码没看出什么问题，会不会分号是全角的！

#include "stdio.h" 看看。

应该没错啊，你输入时候是以逗号隔开的吗


Question: 当有按键发生时，程序结束，不知道放的位置是不是很正确？

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

只能执行哈看看是不是完成哦你想要的功能了！


Question: 如何将写在TXT文件中的英语题目以结构体数组的形式存储并读取？

谢谢七楼，我在看代码，已经初步实现了当初自己所做课程设计所需的功能。

#include <stdio.h>  #define N 256 struct test { 	char problem[N]; 	char A      [N]; 	char B      [N]; 	char C      [N]; 	char D      [N]; 	char answer[N]; };  void print_test(struct test *test) { 	printf("%s\n", test->problem); 	printf("%s\n", test->A); 	printf("%s\n", test->B); 	printf("%s\n", test->C); 	printf("%s\n", test->D); 	printf("%s\n", test->answer); }  int main() { 	FILE * pFile; 	struct test mytest; 	 	char string[N]; 	pFile = fopen ("mytest.txt" , "r"); 	if (pFile == NULL) perror ("Error opening file"); 	else { 		while (!feof(pFile)) 		{ 			if ( fgets (mytest.problem, N, pFile) != NULL && fgets (mytest.A, N, pFile) != NULL &&\ 				fgets (mytest.B, N, pFile) != NULL && fgets (mytest.C, N, pFile) != NULL &&\ 				fgets (mytest.D, N, pFile) != NULL && fgets (mytest.answer, N, pFile) != NULL) 			print_test(&mytest); 			getchar(); 			fgets(string, N, pFile);//跳过空行，这个只能对两道题之间有一行空行 		} 		fclose (pFile); 	} 	return 0; }

这样放在文本里面似乎很难确保格式，一些手误就可能造成解析程序不能正确运行。 建议可以将这些文本放入格式化的文件（如xml），然后再用一些成熟的模块来解析文件。 这样相对更容易维护，可扩充性也更强。  P.S.: 似乎这样的文本解析更适合用Python,Perl类的脚本来解析，耗费时间成本更低。 否则用c语言来解析，要把程序调试调试正确，承受得起一些变动，也不是一件简单的事情。 当然，如果楼主以学习的目的来做，那又另作他论了，呵呵。  个人意见，仅供参考。

#include <stdio.h> #include <string.h> #define QN   200 #define AN   50 #define MAXQ 100 typedef struct test {      char problem[QN];      char A      [AN];      char B      [AN];      char C      [AN];      char D      [AN];      char answer [AN]; } TEST; FILE *f; TEST t[MAXQ]; int i,n,L; char tmp[QN]; int main() {     f=fopen("test.txt","r");     if (NULL==f) {         printf("Can not open file test.txt!\n");         return 1;     }     i=0;     n=0;     while (1) {         n++;if (NULL==fgets(t[i].problem,QN,f)) break;L=strlen(t[i].problem);if ('\n'==t[i].problem[L-1]) t[i].problem[L-1]=0; else goto QERR;         n++;if (NULL==fgets(t[i].A      ,AN,f)) break;L=strlen(t[i].A      );if ('\n'==t[i].A      [L-1]) t[i].A      [L-1]=0; else goto AERR;         n++;if (NULL==fgets(t[i].B      ,AN,f)) break;L=strlen(t[i].B      );if ('\n'==t[i].B      [L-1]) t[i].B      [L-1]=0; else goto AERR;         n++;if (NULL==fgets(t[i].C      ,AN,f)) break;L=strlen(t[i].C      );if ('\n'==t[i].C      [L-1]) t[i].C      [L-1]=0; else goto AERR;         n++;if (NULL==fgets(t[i].D      ,AN,f)) break;L=strlen(t[i].D      );if ('\n'==t[i].D      [L-1]) t[i].D      [L-1]=0; else goto AERR;         n++;if (NULL==fgets(t[i].answer ,AN,f)) break;L=strlen(t[i].answer );if ('\n'==t[i].answer [L-1]) t[i].answer [L-1]=0; else goto AERR;         i++;         if (i>=MAXQ) {             printf("Too many tests!(>%d tests ignored.)",MAXQ);             break;         }         n++;if (NULL==fgets(tmp         ,QN,f)) break;     }     fclose(f);     n=i;     for (i=0;i<n;i++) {         printf("tests(%d):\n",i+1);         printf("%s\n",t[i].problem);         printf("%s\n",t[i].A      );         printf("%s\n",t[i].B      );         printf("%s\n",t[i].C      );         printf("%s\n",t[i].D      );         printf("%s\n",t[i].answer );         printf("\n");     }     return 0; QERR:     printf("line %d too long!(>%d characters)\n",n,QN);     return 2; AERR:     printf("line %d too long!(>%d characters)\n",n,AN);     return 3; }

没实际编译链接调试，不保证对。仅供参考：   1.In  ___ a job or adancing in one , the ability to read and comprehend quickly can mean the difference between success and failure.  A getting  B applying  C doing  D offering  B   2.You were working too hard. You'd better keep a ___ between work and relaxation.  A promise  B lead  C balance  D diary  C   3.The dog may be a good companion for the old. ___ , the need to take it for walks may be a disadvantage.  A Besides  B However  C Therefore  D Instead  B   #include <stdio.h> #include <string.h> #define QN   200 #define QNQ "200" #define AN   50 #define ANQ "50" #define MAXQ 100 typedef struct test {      char problem[QN];      char A      [AN];      char B      [AN];      char C      [AN];      char D      [AN];      char answer [AN]; } TEST; FILE *f; TEST t[MAXQ]; int i,n,L; char tmp[QN]; int main() {     f=fopen("test.txt","r");     if (NULL==f) {         printf("Can not open file test.txt!\n");         return 1;     }     i=0;     n=0;     while (1) {         n++;if (NULL==fgets(t[i].problem,QN,f)) break;L=strlen(t[i].problem);if ('\n'==t[i].problem[L-1]) t[i].problem[L-1]=0; else goto QERR;         n++;if (NULL==fgets(t[i].A      ,AN,f)) break;L=strlen(t[i].A      );if ('\n'==t[i].A      [L-1]) t[i].A      [L-1]=0; else goto AERR;         n++;if (NULL==fgets(t[i].B      ,AN,f)) break;L=strlen(t[i].B      );if ('\n'==t[i].B      [L-1]) t[i].B      [L-1]=0; else goto AERR;         n++;if (NULL==fgets(t[i].C      ,AN,f)) break;L=strlen(t[i].C      );if ('\n'==t[i].C      [L-1]) t[i].C      [L-1]=0; else goto AERR;         n++;if (NULL==fgets(t[i].D      ,AN,f)) break;L=strlen(t[i].D      );if ('\n'==t[i].D      [L-1]) t[i].D      [L-1]=0; else goto AERR;         n++;if (NULL==fgets(t[i].answer ,AN,f)) break;L=strlen(t[i].answer );if ('\n'==t[i].answer [L-1]) t[i].answer [L-1]=0; else goto AERR;         i++;         if (i>=MAXQ) {             printf("Too many tests!(>%d tests ignored.)",MAXQ);             break;         }         n++;if (NULL==fgets(tmp         ,QN,f)) break;     }     fclose(f);     n=i;     for (i=0;i<n;i++) {         printf("tests(%d):\n",i+1);         printf("%s\n",t[i].problem);         printf("%s\n",t[i].A      );         printf("%s\n",t[i].B      );         printf("%s\n",t[i].C      );         printf("%s\n",t[i].D      );         printf("%s\n",t[i].answer );         printf("\n");     }     return 0; QERR:     printf("line %d too long!(>%d characters)\n",n,QN);     return 2; AERR:     printf("line %d too long!(>%d characters)\n",n,AN);     return 3; }

基础的一些文件操作而已！楼主自己先想想思路，整理下基本的代码思路 自己多动手写写，而且需要用的api也都告诉你了！

参考http://www.cnitblog.com/guopingleee/archive/2009/01/18/53850.html 参考http://hi.baidu.com/lulyon/item/7009fde698587e226cabb8a4  引用 楼主 woyaozhucednCS 的回复:上个学期学完了c语言，现在在基于c语言做一个课程练习，遇到了问题，对我来说是瓶颈，做不出来，才请教网上的各位大神.希望走过路过的看看，谢谢了！  以下是我存在txt文件中的三个例题： 1.In  ___ a job or adancing in one , the ability to read and comprehend quickly can mean the difference between success and failure. A getting B applying C doing D offering B  2.You were working too hard. You'd better keep a ___ between work and relaxation. A promise B lead C balance D diary C  3.The dog may be a good companion for the old. ___ , the need to take it for walks may be a disadvantage. A Besides B However C Therefore D Instead B  (注：题目从开头一直写，直到写完题目后换行，在下一行写选项A，写完选项A后换行至下一行写选项B，写完选项B后换行至下一行写选项C，写完选项C后换行至下一行写选项D，最后换行写正确选项，再空一行书写题目2.等等)  #define N 100 结构体代码如下： typedef struct test {     char problem[N];//存放N个问题     char A[N];//存放N个答案A     char B[N];//存放N个答案B     char C[N];//存放N个答案C     char D[N];//存放N个答案D     char answer[N];//存放N个正确答案 }TEST; （注：problem[i],A[i],B[i],C[i],D[i],answer[i]构成一个题目.比如当i=1时，可以从文件中读取到上述的题目1，并显示在屏幕上.一开始只读取题目和四个选项，待用户答题后再读出正确答案并显示在屏幕上.） （注：文件操作时，存和读的时候请用fgets或fputs） （请附代码，谢谢！）

文件读取是按指针形式一个字符一个字符扫描的 不能直接从中读取指定位置的结构体 只能是自己一行一行的读 然后用结构体数组把它存放起来


Question: 如何成为一位成功的程序员

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

引用 8 楼 buyong 的回复:[quote=引用 楼主 u012222078 的回复:] 进了大学一年了，最初的梦想是当兵保卫国家，却阴差阳错进了大学学习计算机，初知计算机的我却爱上了这个以前相对陌生的东西，想要学好它，学习计算机远非想的那么简单，这一年来也沉沦过，认真学过，却总是感觉成绩平平，对于自己想成为一名优秀的程序员的目标还很远很远，今天就是怀着勇气与盼望，希望各位学成的大师们讲讲经，说点学习之道，学习技巧，都要学习什么东西，谢谢您们。                                                                 以为想学好计算机的初学者  你可以写小说[/quote]谢谢

引用 6 楼 ForestDB 的回复:首先，没有捷径； 然后，什么是成功？ 个人片面的的感觉就是能写出一些自己引以为傲的东西得到别人的认可，有个喜欢的岗位这就是我希望的成功！

引用 楼主 u012222078 的回复:进了大学一年了，最初的梦想是当兵保卫国家，却阴差阳错进了大学学习计算机，初知计算机的我却爱上了这个以前相对陌生的东西，想要学好它，学习计算机远非想的那么简单，这一年来也沉沦过，认真学过，却总是感觉成绩平平，对于自己想成为一名优秀的程序员的目标还很远很远，今天就是怀着勇气与盼望，希望各位学成的大师们讲讲经，说点学习之道，学习技巧，都要学习什么东西，谢谢您们。                                                                 以为想学好计算机的初学者  你可以写小说

平时也多做一些笔记和总结性的笔记。把平时学习和写程序的问题都记下来，并且把答案也记下来。对于以后，遇到同样的问题好解决。 多思考、多练习；在困难的时候，不要灰心，要坚持努力和总结哦！！！

首先，没有捷径； 然后，什么是成功？

什么是好的程序员？同问

只要你爱，你就能成功！！！如果不爱或者只是以为自己爱，那还是另寻新欢吧！ 学习不只是上课学的，你蹲厕所，走在路上，做梦时都可以思考可以想，然后写成代码看看！然后毕业的时候你就发现你与众不同

更多的还是理解！以及平时的练习！多动脑，勤动手！这样效果更好

语言学习，没有捷径！先从基础学起！ 多练敲代码多看书，不懂多问，多思考！慢慢来，不要急躁！

如果您碰巧看见我的问题，谢谢您把它看完


Question: DFS深度优先搜索（非递归）求改错

void DFS_2(VNode G[],int v){     int S[VEXNUM];     int top=-1;     int w,k;     visited[v]=1;     S[++top]=v;//将第一个元素放入栈     printf("%d ",G[v].data);     while(top!=-1){         k=S[top];//得到栈顶元素         visited[k]=1;         if(FirstAdj(G,k)!=-1&&visited[FirstAdj(G,k)]!=1){//如果栈顶元素有未访问的邻接点，就将邻接点压入栈顶             w=FirstAdj(G,k);             printf("%d ",G[w].data);             S[++top]=w;         }         else{             int t;             if(NextAdj(G,S[top])!=-1&&visited[NextAdj(G,S[top])]!=1){                 t=NextAdj(G,S[top]);                 printf("%d ",G[t].data);                 S[top]=t;             }             else{                 top--;             }         }     } }

请大神指点！

坚决消灭零回复.

大神说话呀！

在线等大神！


Question: 在编译的时候出现了一个段错误，虽然知道是哪句，不过看不懂为什么

在不确定操作符先后顺序的情况在最好用括号

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

谢谢 ，晕啊， 好久没写代码了这个居然都忘了

这样char* cStr = "asdfgh";定义的话，相当于cStr是常量指针，其指向的内容是不允许修改的，所以要改为char cStr[] = "asdfgh";数组的方式。  引用 楼主 xubuju 的回复:#include <stdio.h>  int del_substr (char* cStr, char const* cSubStr);  int main () { 	char* cStr = "asdfgh"; 	char* cSubStr = "df";  	if (1 == del_substr (cStr, cSubStr)) 	{ 		printf ("%s\n", cStr); 	} 	else 	{ 		printf ("NULL\n"); 	}  	return 0; }  int del_substr (char* cStr, char const* cSubStr) { 	int iLoop = 0; 	int ch; 	char* cTemp; 	char const* cSubTemp;  	while ('\0' != (ch = *cStr)) 	{ 		if (ch == *cSubStr) 		{ 			cTemp = cStr; 			cSubTemp = cSubStr;  			while ('\0' != *cSubTemp) 			{ 				if (*cSubTemp == *cTemp) 				{ 					cSubTemp++; 					cTemp++; 				} 				else 				{ 					break; 				} 			} 		}  		if ('\0' == *cSubTemp) 		{ 			while('\0' != *cTemp) 			{ 			printf ("%c %c\n", *cStr, *cTemp);／／这里打印d,g 				*cStr++ = *cTemp++;  ／／  这里出现段错误 			} 			*cStr = '\0';  			return 1; 		}  		cStr++; 	}  	return 0; }


Question: 整型数组为啥不能用字符串初始化

智者的梦再美，也不如愚人实干的步伐！ 讲一千遍理论，不如写一行代码！  任何语言不落实到实际行动上都等于白说， 没读过MSDN例子代码的程序员实在让人感到可怕！  用C语言1000行源码能完成的工作千万不要用C++重写， 整天把高级技术放在嘴边那是一种浮夸！  少年啊，千万要重视单步调试和设置断点， 用VC调试时记得按下Alt+5、Alt+6、Alt+7和Alt+8。   对学习编程者的忠告： 眼过千遍不如手过一遍！ 书看千行不如手敲一行！ 手敲千行不如单步一行！ 单步源代码千行不如单步对应汇编一行！  VC调试时按Alt+8、Alt+7、Alt+6和Alt+5,打开汇编窗口、堆栈窗口、内存窗口和寄存器窗口看每句C对应的汇编、单步执行并观察相应堆栈、内存和 寄存器变化，这样过一遍不就啥都明白了吗。 对VC来说，所谓‘调试时’就是编译连接通过以后，按F10或F11键单步执行一步以后的时候，或者在某行按F9设了断点后按F5执行停在该断点处的时 候。  不要迷信书、考题、老师、回帖； 要迷信CPU、编译器、调试器、运行结果。 并请结合“盲人摸太阳”和“驾船出海时一定只带一个指南针。”加以理解。 任何理论、权威、传说、真理、标准、解释、想象、知识……都比不上摆在眼前的事实！  有人说一套做一套，你相信他说的还是相信他做的？ 其实严格来说这个世界上古往今来所有人都是说一套做一套，不是吗？  不要写连自己也预测不了结果的代码！  电脑内存或文件内容只是一个一维二进制字节数组及其对应的二进制地址； 人脑才将电脑内存或文件内容中的这个一维二进制字节数组及其对应的二进制地址的某些部分看成是整数、有符号数/无符号数、浮点数、复数、英文 字母、阿拉伯数字、中文/韩文/法文……字符/字符串、汇编指令、函数、函数参数、堆、栈、数组、指针、数组指针、指针数组、数组的数组、指针 的指针、二维数组、字符点阵、字符笔画的坐

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

引用 楼主 fl260919784 的回复:字符串常量不也是一个const的地址吗，为嘛不能赋值给整型数组：int ss[100] = "0123456789";  楼主可以参考这篇 http://www.360doc.com/content/10/0929/11/1091158_57257411.shtml

字符串常量也是一个const的地址，可以赋值给一个整数 至于赋值给一个整型数组——总有人以为他们可以写出他们自己都没想清楚的代码

引用 楼主 fl260919784 的回复:字符串常量不也是一个const的地址吗，为嘛不能赋值给整型数组：int ss[100] = "0123456789";   这样写是有语法错误的。 #include <stdio.h>  int main(int argc,char *argv[]) {    int ss[100];  //声明一个整形数组。    int ss[100]="0123456789"; //这样写是错误的，相当于把字符串赋值给数组元素ss[100] 而不是整个数组    int ss ="0123456789"; //这样写也是不对的，因为ss是一个指针常量。      return 0;  }

char *ptr = "123456";  用字符串初始化一个指针是特例，c 语法中只允许 char* 如此

语言规则，规则就是规则

不符合语法，而且没有意义，到底要0123组成一个int，还是0123分别来，不太好去区别。  引用 楼主 fl260919784 的回复:字符串常量不也是一个const的地址吗，为嘛不能赋值给整型数组：int ss[100] = "0123456789";

各路大神太给力了！

这没啥好说的,编译器遇到这样的字符串,就把字符串放.rodata段,然后在对应的地方以该字符串的起始地址替换,这是语法规则

1）int a[10]={(int)"1234567",(int)"4554657"};这是可以的 2）需要显式转换。 3）这样写有何意义？？？？？？？？


Question: 为什么这个程序运行到一半就自动停止了？

scanf("%d%d",&x,&y);这句话意思是让你输入两个值赋给x和y所以在这里你应该输入两个数字，程序就继续执行了。

写代码前，要把自己的思路的目的弄清楚！ 即使调试别人代码，也要先弄清楚别人的目的，再看别人的思路！

lz 不知道自己写的程序吗？

scanf("%d%d",&x,&y); 这句是让你输入一个两个值，当然要中断一下


Question: switch里的break好像不能用了

break 只能退出一层  做个判断用return吧

再次break、goto、return、exit、……随你挑。

不知你的要求，好像很奇怪

switch中的break退出的是switch，不能退出while(1)循环的，若想退出while(1)循环，需要在while这一层在添加一个break.

void main() { int i,j; int s[N]; for(i=0;i<N;i++) { s[i]=rand()%20000; } while(1) {  printf("              各种排序算法的性能比较        \n\n"); printf("             1.冒泡排序                     \n"); printf("             2.选择排序                     \n"); printf("             3.直接插入排序                 \n"); printf("             4.退出                         \n\n"); printf("请输入选择(1~4):\n");     scanf("%d",&j);  switch(j) { case 1: sort_mp(s); break; case 2: sort_xz(s);break; case 3: sort_charu(s);break; case 4: exit(0);break; default: printf("输入的数字错误!\n"); } } } 你的代码也不能实现重复输入啊。。。scanf应该放在while里面吧

增加变量：bool exitflag = false; case 4: flag = true;break; 在switch外判断flag == true条件是否满足，满足直接break

break 是在 while(1)  里面

goto比较好，但是一般不是很建议用

引用 4 楼 u010659346 的回复:[quote=引用 3 楼 chenyegui 的回复:] [quote=引用 2 楼 u010659346 的回复:] [quote=引用 1 楼 chenyegui 的回复:] break只是退出了switch判断语句。。但是没有退出死循环啊！！！ 求改正？？？[/quote] 把break改为return0；[/quote] 你这样改就不能重复使用了，我以前都这样用，都可以，就这个程序老是不行。你那改法，是解决了，丹达不到要求了。[/quote]  什么要求？ break 退出最内层的switch 或 循环，如果要退出while(1), 在 switch 外在加 break.

吧while 删除

引用 5 楼 chenyegui 的回复:需要什么要求就写判断语句直接退出呗！！ 我知道怎么搞的了。

需要什么要求就写判断语句直接退出呗！！

引用 3 楼 chenyegui 的回复:[quote=引用 2 楼 u010659346 的回复:] [quote=引用 1 楼 chenyegui 的回复:] break只是退出了switch判断语句。。但是没有退出死循环啊！！！ 求改正？？？[/quote] 把break改为return0；[/quote] 你这样改就不能重复使用了，我以前都这样用，都可以，就这个程序老是不行。你那改法，是解决了，丹达不到要求了。

引用 2 楼 u010659346 的回复:[quote=引用 1 楼 chenyegui 的回复:] break只是退出了switch判断语句。。但是没有退出死循环啊！！！ 求改正？？？[/quote] 把break改为return0；

引用 1 楼 chenyegui 的回复:break只是退出了switch判断语句。。但是没有退出死循环啊！！！ 求改正？？？

break只是退出了switch判断语句。。但是没有退出死循环啊！！！


Question: 客户端socket connect建立成功但recv挂起

Windows下调用所有socket函数前请先调用WSAStartup

“发送方不send，接收方recv阻塞”再正常不过了。

把能想到的防火墙先关了再试

引用 1 楼 Idle_Cloud 的回复:可以用别人的客户端或服务端来测试，以确定你的软件问题在服务端还是客户端。也可以抓包看看吧。 引用 2 楼 wangdahu888 的回复:windows下用wireshark linux下用tcpdump 抓包看看吧 引用 3 楼 max_min_ 的回复:查查代码确保server端数据发送成功，client端接收处理是否正确  方法都用过了，没找到哪里有异常。有什么可能会导致这种现象大家说说。

查查代码确保server端数据发送成功，client端接收处理是否正确

windows下用wireshark linux下用tcpdump 抓包看看吧


Question: linux环境下如何将格林威治时间转换成本地时间呢，如若有可以设置时令的操作最好了

楼上怎么总是弄英文的啊  直接回答 查看man page 3 的相关函数就好了 man 3 localtime  之后查查 see also

CTIME Section: Linux Programmer's Manual (3 ) Updated: 2004-11-16  --------------------------------------------------------------------------------    NAME asctime, ctime, gmtime, localtime, mktime, asctime_r, ctime_r, gmtime_r, localtime_r - transform date and time to broken-down time or ASCII    SYNOPSIS #include <time.h>  char *asctime(const struct tm *tm);  char *asctime_r(const struct tm *tm, char *buf);  char *ctime(const time_t *timep);  char *ctime_r(const time_t *timep, char *buf);  struct tm *gmtime(const time_t *timep);  struct tm *gmtime_r(const time_t *timep, struct tm *result);  struct tm *localtime(const time_t *timep);  struct tm *localtime_r(const time_t *timep, struct tm *result);  time_t mktime(struct tm *tm);     DESCRIPTION The ctime(), gmtime() and localtime() functions all take an argument of data type time_t which represents calendar time. When interpreted as an absolute time value, it represents the number of seconds elapsed since 00:00:00 on January 1, 1970, Coordinated Universal Time (UTC).  The asctime() and mktime() functions both take an argument representing broken-down time which is a representation separated into year, month, day, etc.   Broken-down time is stored in the structure tm which is defined in <time.h> as follows:     struct tm {         int     tm_sec;         /* seconds */         int     tm_min;         /* minutes */         int     tm_hour;        /* hours */         int     tm_mday;        /* day of the month */         int     tm_mon;         /* month */         int     tm_year;        /* year */         int     tm_wday;        /* day of the week */         int     tm_yday;        /* day in the year */         int     tm_isdst;       /* daylight saving time */ };   The members of the tm structure are:   tm_sec  The number of seconds after the minute, normally in the range 0 to 59, but can be up to 61 to allow for leap seconds.  tm_min  The number of minutes after the hour, in the range 0 to 59.  tm_hour  The number of hours past midnight, in the range 0 to 23.  tm_mday  The day of the month, in the range 1 to 31.  tm_mon  The number of months since January, in the range 0 to 11.  tm_year  The number of years since 1900.  tm_wday  The number of days since Sunday, in the range 0 to 6.  tm_yday  The number of days since January 1, in the range 0 to 365.  tm_isdst  A flag that indicates whether daylight saving time is in effect at the time described. The value is positive if daylight saving time is in effect, zero if it is not, and negative if the information is not available.  The call ctime(t) is equivalent to asctime(localtime(t)). It converts the calendar time t into a string of the form    "Wed Jun 30 21:49:08 1993\n"  The abbreviations for the days of the week are `Sun', `Mon', `Tue', `Wed', `Thu', `Fri', and `Sat'. The abbreviations for the months are `Jan', `Feb', `Mar', `Apr', `May', `Jun', `Jul', `Aug', `Sep', `Oct', `Nov', and `Dec'. The return value points to a statically allocated string which might be overwritten by subsequent calls to any of the date and time functions. The function also sets the external variable tzname (see tzset(3)) with information about the current time zone. The re-entrant version ctime_r() does the same, but stores the string in a user-supplied buffer of length at least 26. It need not set tzname.   The gmtime() function converts the calendar time timep to broken-down time representation, expressed in Coordinated Universal Time (UTC). It may return NULL when the year does not fit into an integer. The return value points to a statically allocated struct which might be overwritten by subsequent calls to any of the date and time functions. The gmtime_r() function does the same, but stores the data in a user-supplied struct.   The localtime() function converts the calendar time timep to broken-time representation, expressed relative to the user's specified time zone. The function acts as if it called tzset(3) and sets the external variables tzname with information about the current time zone, timezone with the difference between Coordinated Universal Time (UTC) and local standard time in seconds, and daylight to a non-zero value if daylight savings time rules apply during some part of the year. The return value points to a statically allocated struct which might be overwritten by subsequent calls to any of the date and time functions. The localtime_r() function does the same, but stores the data in a user-supplied struct. It need not set tzname.   The asctime() function converts the broken-down time value tm into a string with the same format as ctime(). The return value points to a statically allocated string which might be overwritten by subsequent calls to any of the date and time functions. The asctime_r() function does the same, but stores the string in a user-supplied buffer of length at least 26.   The mktime() function converts a broken-down time structure, expressed as local time, to calendar time representation. The function ignores the specified contents of the structure members tm_wday and tm_yday and recomputes them from the other information in the broken-down time structure. If structure members are outside their legal interval, they will be normalized (so that, e.g., 40 October is changed into 9 November). Calling mktime() also sets the external variable tzname with information about the current time zone. If the specified broken-down time cannot be represented as calendar time (seconds since the epoch), mktime() returns a value of (time_t)(-1) and does not alter the tm_wday and tm_yday members of the broken-down time structure.     RETURN VALUE Each of these functions returns the value described, or NULL (-1 in case of mktime()) in case an error was detected.    NOTES The four functions asctime(), ctime(), gmtime() and localtime() return a pointer to static data and hence are not thread-safe. Thread-safe versions asctime_r(), ctime_r(), gmtime_r() and localtime_r() are specified by SUSv2, and available since libc 5.2.5.  In many implementations, including glibc, a 0 in tm_mday is interpreted as meaning the last day of the preceding month.   The glibc version of struct tm has additional fields    long tm_gmtoff;           /* Seconds east of UTC */ const char *tm_zone;      /* Timezone abbreviation */  defined when _BSD_SOURCE was set before including <time.h>. This is a BSD extension, present in 4.3BSD-Reno.     CONFORMING TO SVID 3, POSIX, BSD 4.3, ISO 9899    SEE ALSO date(1), gettimeofday(2), time(2), utime(2), clock(3), difftime(3), strftime(3), strptime(3), tzset(3)  --------------------------------------------------------------------------------

我在做这个东西的时候没有现成的转换，都是自己转的，设置时令，你指的是夏令时?这个你需要建表，根据不同的夏令时，进行操作。在linux系统中有tm结构体，里面有夏令时，而时区的话我记得linux里面也有个全局变量标明时区的，在使用的时候要记得使用安全函数，也就是函数结尾加_r的。如果有时间的哈可以参考下qt中的类。


Question: C语言如何实现一个线程通过队列向另一个线程发送数据？

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


Question: 小弟创建了一个win32 console application 应用程序出现错误windows.h也加了就是找不到错误求解啊

PROCESSENTRY32 Describes an entry from a list that enumerates the processes residing in the system address space when a snapshot was taken.   typedef struct tagPROCESSENTRY32 {      DWORD dwSize;      DWORD cntUsage;      DWORD th32ProcessID;      DWORD th32DefaultHeapID;      DWORD th32ModuleID;      DWORD cntThreads;      DWORD th32ParentProcessID;      LONG  pcPriClassBase;      DWORD dwFlags;      char szExeFile[MAX_PATH];  } PROCESSENTRY32;  typedef PROCESSENTRY32 *  PPROCESSENTRY32;  typedef PROCESSENTRY32 *  LPPROCESSENTRY32;    Members  dwSize  Specifies the length, in bytes, of the structure. Before calling the Process32First function, set this member to sizeof(PROCESSENTRY32). If you do not initialize dwSize, Process32First will fail.  cntUsage  Number of references to the process. A process exists as long as its usage count is nonzero. As soon as its usage count becomes zero, a process terminates.  th32ProcessID  Identifier of the process. The contents of this member can be used by Win32 API elements.  th32DefaultHeapID  Identifier of the default heap for the process. The contents of this member has meaning only to the tool help functions. It is not a handle, nor is it usable by Win32 API elements.  th32ModuleID  Module identifier of the process. The contents of this member has meaning only to the tool help functions. It is not a handle, nor is it usable by Win32 API elements.  cntThreads  Number of execution threads started by the process.  th32ParentProcessID  Identifier of the process that created the process being examined. The contents of this member can be used by Win32 API elements.  pcPriClassBase  Base priority of any threads created by this process.  dwFlags  Reserved; do not use.  szExeFile  Path and filename of the executable file for the process.  QuickInfo   Windows NT: Requires version 5.0 or later.   Windows: Requires Windows 95 or later.   Windows CE: Unsupported.   Header: Declared in tlhelp32.h.  See Also Tool Help Library Overview, Tool Help Structures

#include <TlHelp32.h>


Question: 刚刚进入大二, 数据结构该怎么学习?

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

很多遍的看，最终会看懂的。主要还是练习。

书上给的那些伪代码看不看的懂都是次要的，主要是要理解其中的思想，理解之后就可以实践了，要想学的好的话你必须得花大量的时间去实现书上的那些算法，在你实践调试程序的时候也能加深你对数据结构的基本认识，当然这些前提必须得你有一定的语言基础（感觉基础不怎么好的话就把你们大一学C的那本书的习题全部做上一遍）

自己慢慢来！先看数据结构！c语言版的那本！然后看看算法导论

引用 2 楼 user-12 的回复:http://www.cse.unr.edu/~bebis/CS308/ 好站点！慢慢琢磨一下。谢谢了！

引用 3 楼 u011477577 的回复:[quote=引用 1 楼 mcmay 的回复:]      我和楼主也有相似的问题，啥时候开始学数据结构比较合适。更具体来说，一门编程语言（例如 C）学到那个阶段可以开始接触数据结构？和楼主共同等待前辈们的经验分享。 全是英文, 看不懂[/quote] 全是英文？您引用错楼层了吧这是？

都说数据结构加算法就是程序。数据结构不管什么语言都能用的到，加油吧！

视频看郝斌的数据结构！！

硬着头皮学，第一遍，第二遍不一定要理解。 不要因为不理解就放弃。

自己动手把书中的数据结构都实现一遍,就行了,别无他法

数据结构、算法在正式编程前，请优先理解原理，能够简单的手动计算、画图什么的。比如怎么建立hash表，如何建立最小生成树什么的。如果这些都没搞清楚，就不要谈用语言编程了。  还有数据结构和语言本身并不冲突，语言只不过是数据结构的一种实现罢了，重要的是数据结构的原理。当然理解原理后要转换为实现，这个一个是看你对原理的理解程度，还有就是你的语言基础，能否把自己心里想的用计算机语言表述出来了。等你转换完了，再去看看标准的算法实现，看看是否有细节没有考虑等等。  语言只要会基础的就可以了，语句上用来用去就是for、if之类的，然后还有函数调用等等，都不是很复杂的东西，当然用C语言实现的话最好要学会指针、struct之类的，不过都不是很复杂。还有就是要会简单的调试，如何单步查错，排除错误。

如果你在学习C语言的时候把链表学习好学习数据结构的话会入手的快一些。

引用 1 楼 mcmay 的回复:我和楼主也有相似的问题，啥时候开始学数据结构比较合适。更具体来说，一门编程语言（例如 C）学到那个阶段可以开始接触数据结构？和楼主共同等待前辈们的经验分享。 全是英文, 看不懂


Question: dll无法使用，求助，急！

有用def文件吗，没有的话应该要extenr C下吧。

把调用dll的文件中__declspec(dllexport) int add(int a,int b); 改成__declspec(dllimport) int add(int a,int b);

引用 楼主 u010781369 的回复:首先是Dll文件的代码 #include <windows.h> BOOL APIENTRY DllMain( HANDLE hModule,                         DWORD  ul_reason_for_call,                         LPVOID lpReserved 					 ) {     return TRUE; }  __declspec(dllexport) int add(int a,int b){ 	return a+b; }  下面是调用dll的文件的代码 #include <stdio.h> #pragma comment(lib,"dll1")  __declspec(dllexport) int add(int a,int b);  int main() { 	printf("%d\n",add(1,2)); 	return 0; } 已经把LIB和DLL拷到文件目录下了 提示[Error] C:\Users\Documents\yu\main.c:8: undefined reference to `add'  __declspec(dllexport)  改成__declspec(dllimport)，由导出改为导入

试试#pragma comment(lib,"dll1.lib")  引用 楼主 u010781369 的回复:首先是Dll文件的代码 #include <windows.h> BOOL APIENTRY DllMain( HANDLE hModule,                         DWORD  ul_reason_for_call,                         LPVOID lpReserved 					 ) {     return TRUE; }  __declspec(dllexport) int add(int a,int b){ 	return a+b; }  下面是调用dll的文件的代码 #include <stdio.h> #pragma comment(lib,"dll1")  __declspec(dllexport) int add(int a,int b);  int main() { 	printf("%d\n",add(1,2)); 	return 0; } 已经把LIB和DLL拷到文件目录下了 提示[Error] C:\Users\Documents\yu\main.c:8: undefined reference to `add'

__declspec(dllexport) int add(int a,int b); 这是定义动态库的导出函数用的。 __declspec(dllimport) int add(int a,int b); 这才是从动态库导入函数用的。  VC自己是这么做的 // defined with this macro as being exported. #ifdef XXX_EXPORTS #define XXX_API __declspec(dllexport) #else #define XXX_API __declspec(dllimport) #endif  // This class is exported from the Hello.dll class XXX_API CHello { public: 	CHello(void); 	// TODO: add your methods here. };  extern XXX_API int nHello;  XXX_API int fnHello(void);

看信息你是用ld的，到构建选项里添加链接路径和库名，vc那套#pragma comment(lib,"dll1")不行的...

把调用DLL文件中  __declspec(dllexport) int add(int a,int b); 改成__declspec(dllimport) int add(int a,int b); 看看  都是用同一个编译器编译的  不用extern C应该也没问题吧


Question: C调用mysql 存储过程的问题

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


Question: 有高手指点一下，为什么C代码下extern "C"引用C++代码一直报错！！！！

extern "C"{ //宣布这里是C代码区域，写的函数都是，C那个样子的,缺省调用约定是cdecl，也不会有函数重载这种东西。 //类，名空间的定义，当然也不会有，不过 在此区域外部定义的一切。 //在此区域内部的函数中,可以使用。 //PS:C++缺省调用约定是 stdcall //stdcall // cdecl 返回值通过寄存器传递，32BITS X86 是 char,short,int,(long?)，void*,==>  eax,  //long long(__int64), ===>edx:eax   ,float,double===> 浮点寄存器堆栈存放 // //参数用堆栈传递，参数从右向左入栈 //参数尺寸 char,short,int,(long?),void*===> int //float,double ===>double //函数名，前面加下划线 后加 @ 加 参数长度  _fun@N      n是数字，表示参数总长度。 //被调用者（callee）清栈32BITS Windoes X86 用 ret N 指令 N 就是函数名字中的数字， //所以,即使编译成库代码，也可以获得参数长度  // //--------------------------------- // cdecl 返回值通过寄存器传递，32BITS Windoes X86 是 char,short,int,(long?)，void*,==>  eax,  //long long(__int64), ===>edx:eax   ,float,double===> 浮点寄存器堆栈存放 // //参数用堆栈传递，参数从右向左入栈 //参数尺寸 char,short,int,(long?),void*===> int //float,double ===>double //函数名，前面加下划线  //调用者（caller）清栈，32BITS Windoes X86 ，一般add esp，n 这种指令。 // ｝  extern "C" int add(int x,int y){ return x + y ; //这个函数是C 式样的，返回值和参数最好不要有类类型。 //否则，没有必要定义为extern "C" //此函数编译成 cdecl 函数 函数名编译成 _add }  extern "C" __stdcall int fun(int x,int y){ 	return x + y; //标准调用约定，是C++采用的调用约定,也希望编译成 C 式样的 函数名 编译成 _fun@8 ，8 是参数字节数 extern "C" int x=0;  // x 编译成 _x

extern "C"{  //一般只是一些函数，偶尔可以有一些变量。 //一般不会有，类，名空间的定义，更不会有继承。  }

extern "C"{  //一般只是一些函数，偶尔可以有一些变量。  }  extern "C"; extern "C++" 这两种用法只在C++ 中会有，C 中是不会有的。  extern "C" ;可以写函数，编译成.lib,.dll供 C 调用； 也可以写函数声明，导出动态库的函数,供C++调用

c++是向前的， 反了

extern "C" 是调用C代码，C中无法调用c++

ｃ　是　ｃ＋＋　的子集

extern "C" 是让C++调用C用的，你用反了吧


Question: C语言倒水问题

一个最基本的深度搜索或广度搜索，加已遍历状态来剪枝。 借助stl的话，代码可能就20行。

用程序，暂时还没想到如何写。

要4升，直接用4升杯。  倒2升的方法： 　　10升水，倒入3升杯；再把这3升倒入4升。 　　再从10升杯中，把水倒入3升杯；再把3升中的水倒入4升杯，4升杯满时，就是2升和4升的了。

m剩下（m-(n-m)）上面打错了

规律是这样，一个m杯一个n杯倒x升水(m<n,x<n)； m%n==x? 2m%n==x? 3m%n==x? 举个例子，2m%n若等于x,即  n-m（n剩下n-m），然后 m-(n-m) m剩下（n-(n-m)） 不过对于迅速判断能否倒出x，还没想到好方法

坐等高手提供思路，，，

提一个较简单的方法，先灌满10升水杯，把10升水杯的水倒满3升水杯，再把3升水杯的水倒到4升水杯中，然后把10升水杯的剩余的水继续倒满3升水杯中，这时10升水杯的水就只剩下4升

坚决消灭领会副.

大哥！我就是这么问呢！

额,想了一下,只能写出一个很复杂,占用很多RAM的穷举法. 有没有什么巧妙一点的方法,得出所有结果

编程语言只是实现的手段，楼主先要考虑好整体思路，具体是如何操作，而不是语言本身。


Question: C语言版数据结构——栈的初始化问题

[color=#FF0000]我把pint函数修改了下[/color] #include <stdio.h> #include <stdlib.h> #define FLASE 0 #define OK 1 #define ERROR 0 #define INFEASIBLE -1 #define OVERFLOW -2 #define STACK_INIT_SIZE 100 #define STACKCREMENT    10  typedef struct {     int * base;     int * top;     int stacksize; }SqStack; ////////////////////////////////////////////// int InitStack(SqStack *S); int Push(SqStack *S, int e); int Pop(SqStack *S, int *e); void Print(SqStack *S); ////////////////////////////////////////////// int main() {     int N = 4;     SqStack *S;     InitStack(S);//初始化一个栈     Push(S,5);    //放一个数字5进去     Print(S);    //看看能不能输出来    system("pause");  return 0; } int InitStack(SqStack *S)    //初始化一个空栈 {     S->base = (int *)malloc(STACK_INIT_SIZE * sizeof(int));     if(!S->base)exit(OVERFLOW);     S->top = S->base;     S->stacksize = STACK_INIT_SIZE;     return OK; } int Push(SqStack *S, int e)//压栈操作 {     if(S->top - S->base >= S->stacksize)     {         S->base = (int *)malloc((S->stacksize + STACKCREMENT) * sizeof(int));         if(!S->base)exit(OVERFLOW);         S->top = S->base + S->stacksize;//         S->stacksize += STACKCREMENT;             }    // printf("xx");//debug     *(S->top) = e;     printf("%d\n",*(S->top));     S->top++;     return OK; } int Pop(SqStack *S)//出栈 {     if(S->base == S->top)return ERROR;     int e = *(S->top);     --S->top;     return OK; } void Print(SqStack *S)//打印 {     int *p;     p=S->base;      if(S->base == S->top) exit(ERROR);     /*{         printf("\n空栈！没有数据用来输出！\n");         exit(FLASE);     }*/     while(p != S->top)     {         printf("%d  \n",*p);         p++;     } }

引用 3 楼 huiguimoyu 的回复:引用 2 楼 zhaokai115 的回复:明显的S野指针，没初始化就用上了请问下该怎么改呢？谢谢 第25行简单地改成     SqStack S;    // SqStack *S;

引用 9 楼 huiguimoyu 的回复:[quote=引用 7 楼 buyong 的回复:] [quote=引用 6 楼 huiguimoyu 的回复:] [quote=引用 5 楼 user-7 的回复:] [quote=引用 4 楼 huiguimoyu 的回复:] [quote=引用 1 楼 jerry_dqh 的回复:] 在发生问题后，看一下在哪儿断住的  	S->base = (SElemType *)malloc(STACK_INIT_SIZE * sizeof(SElemType)); 这一句断掉了[/quote]  s 初始化了吗？[/quote]我没搞懂啊。但是书上就是这么干的啊。。。请问要怎么初始化，S指向谁呢，我就是想初始化S，InitStack()函数就是用来初始化S的啊。。。[/quote]  把你的书扔了吧。 S没有初始化，居然就S->base 看来你可以这样试试： void main() {     int N = 4;     SqStack S;     InitStack(&S);//初始化一个栈     Push(&S,5);    //放一个数字5进去     Print(&S);    //看看能不能输出来   }[/quote]但是写成&S会报错啊，因为形参的类型是*S,这不也是传个地址进去吗？ [/quote] 可以的，&s取地址。

Status Push(SqStack *S, SElemType e)//压栈操作 {     if(S->top - S->base >= S->stacksize)     {         S->base = (SElemType *)malloc((S->stacksize + STACKCREMENT) * sizeof(SElemType));         if(!S->base)exit(OVERFLOW);         S->top = S->base + S->stacksize;//         S->stacksize += STACKCREMENT;             }     printf("xx");//debug     *(S->top) = e;     printf("%d",*(S->top));     S->top++;     return OK; } 改成  Status Push(SqStack *S, SElemType e)//压栈操作 { #define USE_REALLOC 1     if(S->top - S->base >= S->stacksize)     {         //申请一块更大的内存 #if USE_REALLOC         // realloc 重新申请更大内存。会自动搬迁数据。                 SElemType * p  =(SElemType *)realloc(S->base,(S->stacksize + STACKCREMENT) * sizeof(SElemType));         if( !p ){ free(S->base); exit(OVERFLOW);}          S->base = p;   #else //if USE_MALLOC         //malloc 版重新申请更大内存,自己搬迁数据。                  SElemType * p  = (SElemType *)malloc((S->stacksize + STACKCREMENT) * sizeof(SElemType));         if(!S->base){            free(S->base);            exit(OVERFLOW);         }         memcpy(p,S->base,S->stacksize * sizeof(SElemType));         free(S->base);         S->base = p;    #endif             S->top = S->base + S->stacksize;//         S->stacksize += STACKCREMENT;             }     printf("xx");//debug     *(S->top) = e;     printf("%d",*(S->top));     S->top++;     return OK; #undef USE_REALLOC }  void PrintElem(const SElemType *e) {       printf("%d ",*e); }  void Print(SqStack *S)//打印 {     SElemType *p;     p=S->base;     if(S->base == S->top)     {         printf("\n空栈！没有数据用来输出！\n");         exit(FLASE);     }     else     { //printf("%d"); 开玩笑，这能输出啥子？？缺少参数 %d，格式需要一个整形参数。       //  p++;        while(p!= S->top)           PrintElem(p++);  //输出栈里存放的所有数。          } }  添加一个函数,释放内存。 Destroy(SqStack *S){ free(S->base); } //修改main，释放内存。 int main() {     int N = 4;     SqStack S;     InitStack(&S);//初始化一个栈     Push(&S,5);    //放一个数字5进去     Print(&S);    //看看能不能输出来     Destroy(&S);  //释放内存     return 0; }

引用 7 楼 buyong 的回复:[quote=引用 6 楼 huiguimoyu 的回复:] [quote=引用 5 楼 user-7 的回复:] [quote=引用 4 楼 huiguimoyu 的回复:] [quote=引用 1 楼 jerry_dqh 的回复:] 在发生问题后，看一下在哪儿断住的  	S->base = (SElemType *)malloc(STACK_INIT_SIZE * sizeof(SElemType)); 这一句断掉了[/quote]  s 初始化了吗？[/quote]我没搞懂啊。但是书上就是这么干的啊。。。请问要怎么初始化，S指向谁呢，我就是想初始化S，InitStack()函数就是用来初始化S的啊。。。[/quote]  把你的书扔了吧。 S没有初始化，居然就S->base 看来你可以这样试试： void main() {     int N = 4;     SqStack S;     InitStack(&S);//初始化一个栈     Push(&S,5);    //放一个数字5进去     Print(&S);    //看看能不能输出来   }[/quote]但是写成&S会报错啊，因为形参的类型是*S,这不也是传个地址进去吗？

S->base = (SElemType *)malloc(STACK_INIT_SIZE * sizeof(SElemType)); S 是野指针的，进去这样用会有问题的！ 最好给S 一个有效的地址先！（初始化下）

引用 6 楼 huiguimoyu 的回复:[quote=引用 5 楼 user-7 的回复:] [quote=引用 4 楼 huiguimoyu 的回复:] [quote=引用 1 楼 jerry_dqh 的回复:] 在发生问题后，看一下在哪儿断住的  	S->base = (SElemType *)malloc(STACK_INIT_SIZE * sizeof(SElemType)); 这一句断掉了[/quote]  s 初始化了吗？[/quote]我没搞懂啊。但是书上就是这么干的啊。。。请问要怎么初始化，S指向谁呢，我就是想初始化S，InitStack()函数就是用来初始化S的啊。。。[/quote]  把你的书扔了吧。 S没有初始化，居然就S->base 看来你可以这样试试： void main() {     int N = 4;     SqStack S;     InitStack(&S);//初始化一个栈     Push(&S,5);    //放一个数字5进去     Print(&S);    //看看能不能输出来   }

引用 5 楼 user-7 的回复:[quote=引用 4 楼 huiguimoyu 的回复:] [quote=引用 1 楼 jerry_dqh 的回复:] 在发生问题后，看一下在哪儿断住的  	S->base = (SElemType *)malloc(STACK_INIT_SIZE * sizeof(SElemType)); 这一句断掉了[/quote]  s 初始化了吗？[/quote]我没搞懂啊。但是书上就是这么干的啊。。。请问要怎么初始化，S指向谁呢，我就是想初始化S，InitStack()函数就是用来初始化S的啊。。。

引用 4 楼 huiguimoyu 的回复:[quote=引用 1 楼 jerry_dqh 的回复:] 在发生问题后，看一下在哪儿断住的  	S->base = (SElemType *)malloc(STACK_INIT_SIZE * sizeof(SElemType)); 这一句断掉了[/quote]  s 初始化了吗？

引用 1 楼 jerry_dqh 的回复:在发生问题后，看一下在哪儿断住的  	S->base = (SElemType *)malloc(STACK_INIT_SIZE * sizeof(SElemType)); 这一句断掉了

明显的S野指针，没初始化就用上了

在发生问题后，看一下在哪儿断住的


Question: 有什么SDK/API的书吗？

套接字的话从unix/linux开始学起吧，所谓一通百通，全身轻松。

参考http://blog.csdn.net/21aspnet/article/details/6694485  引用 6 楼 u012419374 的回复:[quote=引用 2 楼 max_min_ 的回复:] 学些Linux网络编程！   图形的学习Qt吧 夸平台 不像MFC太局限！ 学C语言网络编程有什么好的书吗[/quote]

引用 2 楼 max_min_ 的回复:学些Linux网络编程！   图形的学习Qt吧 夸平台 不像MFC太局限！ 学C语言网络编程有什么好的书吗

个人觉得，研究linux核心吧！当然如果需要在window上开饭，你还是需要端它的碗——API

《Windows API编程》 挺具有代码性的

《Windows API编程》（http://product.china-pub.com/25130#ml）比较符合你的需求。 另外《Windows API开发详解》（http://product.china-pub.com/55442）也可以参考一下。 有激情的话，还可以研究一下《Windows环境下32位汇编语言程序设计》（http://product.china-pub.com/3768243）。   引用 楼主 u012419374 的回复:看完了windows程序设计第五版后想继续学SDK编程，但是实在不想学MFC  买了本王艳平的windows程序设计第二版，看着挺不错的，但是看到第五章居然开始讲MFC了....  就没什么纯SDK的书吗，  我想学钩子和套接字编程等等实用性强的东西

学些Linux网络编程！   图形的学习Qt吧 夸平台 不像MFC太局限！

windows核心编程，windows网络编程 还是多动手练练吧，比看书强...


Question: 【C语言】有关gcc优化和全局变量的疑惑

一般选离自己最近的变量

这个应该和GCC参数有关！就像你说的那样，优化了！全局变量都是放在data段中，是容的不得重复的！

也就是说：两个int a;都是声明，那声明与定义的具体区别呢？网上有说 “声明一个变量意味着向编译器描述变量的类型，但并不为变量分配存储空间。 定义一个变量意味着在声明变量的同时还要为变量分配存储空间。”  这句话我怎么认为不对呢  #include <stdio.h> #include "fun.h"   int a; int main(void) {     printf("[main] &a = %p\n", &a);      fun();       printf("[main] &a = %p\n", &a);     printf("[main] a = 0x%X\n", a); }  结果： [main] &a = 0x804a01c [fun1] &a = 0x804a01c [fun1] a = 0xFF [main] &a = 0x804a01c [main] a = 0xFF 第一条printf的&a是有地址的啊？

要加上 -Wredundant-decls选项才会警告，默认是关闭的：  gcc -Wredundant-decls -o main main.c fun.c  引用 楼主 js_xj 的回复:现有文件main.c  fun.c  fun.h，编译环境ubuntu10.10，gcc-4.4.3。 main.c  #include <stdio.h> #include "fun.h"  int a; int main(void) { 	fun();  	printf("[main] &a = %p\n", &a); 	printf("[main] a = 0x%X\n", a); }  fun.c  #include <stdio.h> #include "fun.h"  int a; void fun(void) { 	a = 0xff;  	printf("[fun] &a = %p\n", &a); 	printf("[fun] a = 0x%X\n", a); }  fun.h  #ifndef _FUN__H #define _FUN__H  void fun(void);  #endif   编译：gcc -o main main.c fun.c(无警告无错) 执行：./main 结果： [fun] &a = 0x804a01c [fun] a = 0xFF [main] &a = 0x804a01c [main] a = 0xFF  请问：定义了两个全局变量a，为什么在连接的过程中，连接器没有报重复定义的错呢？ ps:我是看了《C陷阱与缺陷》书 “【第4章 连接】 4.2声明与定义”做的实验。

#include <stdio.h> #include <stdlib.h>  int a= 2; int a; int main() {     printf("%d\n",a);     printf("Hello world!\n");     return 0; } 可以通过编译 #include <stdio.h> #include <stdlib.h>  int a; int a = 2; int main() {     printf("%d\n",a);     printf("Hello world!\n");     return 0; } 也可以通过编译 #include <stdio.h> #include <stdlib.h>  int a = 5 ; int a = 4; int main() {     printf("%d\n",a);     printf("Hello world!\n");     return 0; } 错误不可以通过编译 说明int a; 在作为全局变量的时候  只有在用与赋值的时候 才是真正意义上的定义  所以不会报重复定义

因为这是俩个int a是声明   #include <stdio.h> #include <stdlib.h>  int a; int a; int main() {     printf("Hello world!\n");     return 0; } 可以通过编译 不报错 是因为编译器给优化掉了吧


Question: 请教这个错误怎么处理：error C2040: “int”与“char [256]”的间接寻址级别不同

提示烂了点！

很明显噻，自己辛苦算完喽，然后自己又把它扔了！它只是一个表达式，算出结果是个临时值，没有直接体现到a中去，  最起码也得：a|=(1<<3)

回复ls几位： 1. 源代码有错，根本不能置位 正确代码如下： #define SETBIT3(a)  (a=a|(1<<3))  2. 源代码保存为c可以正常编译和执行，保存为cpp不能正常编译，会出现如上错误  3. 谢谢ls几位了~

改个变量名 把a换成别的变量名试试

把主函数放到最后去 你这个程序就这三句话 是没问题的 是可以编译通过的 你试试这个程序 #include <stdio.h> #include <stdlib.h>  #define SETBIT3(a)  (a|(1<<3))   int a = 0;   int main() {     SETBIT3(a);       printf("\n");     return 0; } 这说明你的程序 有别的地方错误 或者你是用VC 或者C++ 的环境吧

所给出的代码片断没什么问题的。  引用 楼主 lllgyt327 的回复:　　Windows C; 　　出错代码： 　　#define SETBIT3(a)  (a|(1<<3)) 	int a=0; 　　SETBIT3(a); 　　错误提示： 　　error C2040: “a”: “char”与“char [256]”的间接寻址级别不同 　　error C2296: “|”: 非法，左操作数包含“char [256]”类型   -------------------  谢谢各位   --------------------------------


Question: C语言有没有从文件中读取一行字符串的方法

char* a; gets(a); 这就OK了！

引用 11 楼 AnYidan 的回复:The input and output functions, types, and macros defined in <stdio.h>http://en.cppreference.com/w/c/io 总能找到合适你的函数

上面的几个没看明白要求，是C语言，getline是C++的好不

fgets是符合C语言最好的方法。  引用 楼主 nabasasun 的回复:C语言，用传统的方法，谢谢！  以换行符作为结尾，并记录行号。  把得到的字符串存放在char数组中。

fgets 可以 fscanf 更好[如果只需要获取行数 使用fscanf可以不考虑缓冲区大小的问题]

fgets()就可以  FILE *fp; char str[256]; fgets(str, 256, fp); 意思为从fp中读一行，放入str中  记录行号的话，设定个量计数就行了

getline有C++版本和linux下的C版本。 标准C函数：char *fgets(char *buf, int bufsize, FILE *stream);

ssize_t getline(char **lineptr, size_t *n, FILE *stream);

getline()

仅供参考#include <stdio.h> #include <string.h> #define MAXLEN 1000 char ln[MAXLEN]; FILE *f; int i,z; int b,n,L; int main(int argc,char **argv) {     if (argc<2) {         printf("Usage:%s fullpathfilename.ext\nget total blank/non-blank/total linenumbers.\n",argv[0]);         return 1;     }     f=fopen(argv[1],"r");     if (NULL==f) {         printf("Can not open file [%s]!\n",argv[1]);         return 2;     }     z=0;     b=0;     n=0;     L=0;     while (1) {         if (NULL==fgets(ln,MAXLEN,f)) break;         L=strlen(ln);         if ('\n'==ln[L-1]) {             if (0==z) {                 for (i=0;i<L-1;i++) {                     if (!(' '==ln[i] || '\t'==ln[i])) break;                 }                 if (i<L-1) z=1;//当前行不是空行             }             if (0==z) b++; else n++;             z=0;         } else {             if (0==z) {                 for (i=0;i<L;i++) {                     if (!(' '==ln[i] || '\t'==ln[i])) break;                 }                 if (i<L) z=1;//当前行不是空行             }         }     }     fclose(f);     if (L>0 && '\n'!=ln[L-1]) {         if (0==z) b++; else n++;//最后一行末尾无'\n'也计算     }     printf("File:[%s] total blank/non-blank/total linenumbers is %d/%d/%d\n",argv[1],b,n,b+n);     return 0; }

getline是C++的  6楼说的函数不错 不过似乎不能判断行