Question: c primer plus 第六版中文电子书谁有

引用 7 楼 hurryboylqs 的回复:[quote=引用 6 楼 qq_36409192 的回复:] 想好好学，个人建议你还是去买一本实体书，没必要省那几十块钱，电子书看的很伤眼睛，而且还不能简单的勾画，学起来效果比较差。  我是教，不是学，呵呵，我想看下里面的内容[/quote] 哦，你试试这个 https://pan.baidu.com/share/link?shareid=1931156646&uk=3308986765

引用 8 楼 qq_36409192 的回复:[quote=引用 7 楼 hurryboylqs 的回复:] [quote=引用 6 楼 qq_36409192 的回复:] 想好好学，个人建议你还是去买一本实体书，没必要省那几十块钱，电子书看的很伤眼睛，而且还不能简单的勾画，学起来效果比较差。  我是教，不是学，呵呵，我想看下里面的内容[/quote] 哦，你试试这个 https://pan.baidu.com/share/link?shareid=1931156646&uk=3308986765[/quote]  还是一样，C++的，不找了

引用 6 楼 qq_36409192 的回复:想好好学，个人建议你还是去买一本实体书，没必要省那几十块钱，电子书看的很伤眼睛，而且还不能简单的勾画，学起来效果比较差。  我是教，不是学，呵呵，我想看下里面的内容

引用 4 楼 hurryboylqs 的回复:出了，书店有卖 买一本。

出了，书店有卖

C Primer Plus 第六版还没出来吧？  引用 2 楼 hurryboylqs 的回复:[quote=引用 1 楼 turingo 的回复:] 参考http://down.51cto.com/data/823025 这是C++ primer plus 不是c primer plus 又被骗了一次[/quote]

引用 1 楼 turingo 的回复:参考http://down.51cto.com/data/823025 这是C++ primer plus 不是c primer plus 又被骗了一次


Question: 安装nemesis问题

错误信息提示你，去那个网站下载libnet头文件。

引用 3 楼 u010165006 的回复:看最后的Error提示信息最后错误信息我都查了百度1天多 我也很绝望 安装不上

最后错误信息我都查了百度1天多 我也很绝望 安装不上

你当我是什么?这么简单的复制去百度搜索还要教 水的可以  赵老师 这个逼装的66

必应、谷歌、……

将错误提示信息放在百度搜索框里面搜一下。

看最后的Error提示信息

求大神指导 感激不尽


Question: 如何将十进制数转换为十六进制并转换为ascii码

参考一下这个博文，最后的转换说明符 http://blog.csdn.net/libing403/article/details/72934198

你给点击发送0x64和100都是一样的，电机应该都认为是同样的结果！

char 类型不就是整数么。 还转换什么？

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

如果是数字 100，如楼上所说直接赋值。如果是字符串，转换一下即可： buff[5] = atoi(s);

16进制或10进制输出，是我们要求以什么形式输出的。但在内存里，10进制的100和16进制的100都是二进制形式存放的。所以，如果将100存放在到buff，直接赋值100即可。除非你的通信另一方不能识别十进制数。 当然用snprintf或sprintf可以实现你要求的。或者用下面的dec_to_hex转换 #include <stdio.h>  int dec_to_hex(char *buf, int len, int num); int main(void) {     int size, i;     char buf[12];      size = dec_to_hex(buf, 12, 100);      for (i = 0; i < size; i++)         putchar(buf[i]);      putchar(10);     return 0; }  int dec_to_hex(char *buf, int len, int num) {     int cnt = 2, i;     int tmp;      buf[0] = '0';     buf[1] = 'x';     while (num) {         if (num % 16 >= 10)             buf[cnt] = num % 16 - 10 + 'A';         else             buf[cnt] = num % 16 + '0';         num = num / 16;         cnt++;         if (cnt >= len)             break;     }     for (i = 0; i < (cnt - 2) / 2; i++) {         tmp = buf[i+2];         buf[i+2] = buf[cnt-1-i];         buf[cnt - 1 - i] = tmp;     }      return cnt; }

所谓八进制十进制十六进制都是表现形式，所有的数据都是二进制表示  所以你buff[5] 是一个字符，十进制整形解析表示为100，十六进制整形解析表示为64 所有的一切都是都是表现，显示出来都是字符图形。你需要的话可以变成任何进制  所以你需要让buff[5]在界面显示为十六进制，那么： sprintf(buff, "%#x", buff[5]);

sprintf(buff, "%#x", 100);


Question: 按贪心算法的原理求背包问题最优解的方法

引用 4 楼 qq_36409192 的回复:贪心算法的本质在于你的单步的准则要确定，一定要保证程序的每一步是最优解。  所以背包问题最重要的就是每一次放哪个好，在满足条件的情况下，尽量放性价比最高的。  PS：纠正一下楼主，贪心算法求的不一定是最优解，但是肯定是一个比较接近最优解的一个解。

有木有大神可以给出源代码让大家都学习学习~

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

理解和讨论之前请先学会如何观察！  仅供参考：//http://www.cnblogs.com/chinazhangjie/archive/2010/11/16/1878400.html //多边形游戏 //描述 //    一个多边形，开始有n个顶点。每个顶点被赋予一个正整数值，每条边被赋予一个运算符“+”或“*”。所有边依次用整数从1到n编号。 //    现在来玩一个游戏，该游戏共有n步： //    第1步，选择一条边，将其删除 //    随后n-1步，每一步都按以下方式操作： //    （1）选择一条边E以及由E连接着的2个顶点v1和v2； //    （2）用一个新的顶点取代边E以及由E连接着的2个顶点v1和v2，将顶点v1和v2的整数值通过边E上的运算得到的结果值赋给新顶点。 //    最后，所有边都被删除，只剩一个顶点，游戏结束。游戏得分就是所剩顶点上的整数值。那么这个整数值最大为多少？ //输入 //    第一行为多边形的顶点数n（n ≤ 20），其后有n行，每行为一个整数和一个字符， //    整数为顶点上的正整数值，字符为该顶点到下一个顶点间连边上的运算符“+”或“*” //    （最后一个字符为最后一个顶点到第一个顶点间连边上的运算符）。 //输出 //    输出仅一个整数，即游戏所计算出的最大值。 //样例输入 //4 //4 * //5 + //5 + //3 + //样例输出 //70 // //分析： //最优子结构性质 //按照顺时针顺序，多边形和顶点的顺序可以写成： //  op[1], v[1], op[2], v[2], …, op[n], v[n] //在所给多边形中，从顶点i(1 <= i <= n)开始，长度为j(链中有j个顶点)的顺时针链p(i，j) 可表示为 //v[i], op[i+1], v[i+1],…, op[i+j-1], v[i+j-1] // //如果这条链在op[i + s]处进行最后一次合并运算(1 <= s <= j-1)，则可在op[i+s]处将链分割为2个子链： // //从i开始长度为s的链：  p(i，s) //从i + s开始，长度为j - s的链：p(i + s，j-s)。 //设: //m1是对子链p(i，s)的任意一种合并方式得到的值，而a和b分别是在所有可能的合并中得到的最小值和最大值。 // //m2是p(i+s，j-s)的任意一种合并方式得到的值，而c和d分别是在所有可能的合并中得到的最小值和最大值。 // //依此定义有a <= m1 <= b，c <= m2 <= d // //(1)当op[i+s] = ‘+’时，显然有a + c <= m <= b + d // //(2)当op[i+s] = ’*’时，有 // //min {ac，ad，bc，bd} <= m <= max {ac，ad，bc，bd} //换句话说，主链的最大值和最小值可由子链的最大值和最小值得到。 #include <windows.h> #include <stdio.h> #include <string.h> #include <conio.h> #include <locale.h> int n; char o[21];//op int  d[21];//vertex data int maxv; struct SEGINFO {//阶段信息     int maxv;     int minv; } sg[21][21],si; int X,Y; void getXY() {     CONSOLE_SCREEN_BUFFER_INFO csbi;     GetConsoleScreenBufferInfo(GetStdHandle(STD_OUTPUT_HANDLE),&csbi);     X=csbi.dwCursorPosition.X;     Y=csbi.dwCursorPosition.Y; } void gotoXY(int x, int y) {     COORD coord = {x, y};     SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), coord); } void ConPrintAt(int x, int y, char *CharBuffer, int len) {     DWORD count;     COORD coord = {x, y};     HANDLE hStdOut = GetStdHandle(STD_OUTPUT_HANDLE);     SetConsoleCursorPosition(hStdOut, coord);     WriteConsole(hStdOut, CharBuffer, len, &count, NULL); } void ClearCon() {     HANDLE hStdOut = GetStdHandle(STD_OUTPUT_HANDLE);     COORD coord = {0, 0};     DWORD count;     CONSOLE_SCREEN_BUFFER_INFO csbi;     if (GetConsoleScreenBufferInfo(hStdOut, &csbi)) {         FillConsoleOutputCharacter(hStdOut, (TCHAR) 32, csbi.dwSize.X * csbi.dwSize.Y, coord, &count);         FillConsoleOutputAttribute(hStdOut, csbi.wAttributes, csbi.dwSize.X * csbi.dwSize.Y, coord, &count);         SetConsoleCursorPosition(hStdOut, coord);     } } void show(char *p) {     int y,x;     static char ss[128];      for (y=1;y<n;y++) {         sprintf(ss,"%c",o[y]);         ConPrintAt(0,y,ss,1);         for (x=1;x<n;x++) {             sprintf(ss,"%2d ",sg[y][x].maxv);             ConPrintAt(x*3,y,ss,3);         }     }     sprintf(ss,"%-128s",p);     ConPrintAt(1,n,ss,128);     gotoXY(0,n); } void pmt(char *p) {     static char ss[128];      sprintf(ss,"%-128s",p);     ConPrintAt(1,n,ss,128);     gotoXY(0,n); } void getmaxmin(int i, int s, int j) {// 从i开始，长度为j，s为切分位置     int minL;     int maxL;     int minR;     int maxR;     int r;     int mm[4];     int vmin;     int vmax;     static char p[128];      minL=sg[i][s].minv;     maxL=sg[i][s].maxv;         sprintf(p,"总长j:%d 上开始i:%d,长度  s:%d,maxL:%d",j,i,s  ,maxL);pmt(p);getXY();gotoXY(s    *3,i);getch();gotoXY(X,Y);       r=(i+s-1)%(n-1)+1;     minR=sg[r][j - s].minv;     maxR=sg[r][j - s].maxv;     sprintf(p,"总长j:%d 下开始r:%d,长度j-s:%d,maxR:%d",j,r,j-s,maxR);pmt(p);getXY();gotoXY((j-s)*3,r);getch();gotoXY(X,Y);      if (o[r] == '+') {// 处理加法         si.minv=minL + minR;         si.maxv=maxL + maxR;    sprintf(p,"上下合并maxv:%d=maxL:%d + maxR:%d",si.maxv,maxL,maxR);pmt(p);getch();     } else {// 处理乘法         mm[0]=minL * minR;         mm[1]=minL * maxR;         mm[2]=maxL * minR;         mm[3]=maxL * maxR;         vmin=mm[0];         vmax=mm[0];         for (i=1;i<4;i++) {             if (mm[i]<vmin) vmin=mm[i];             if (mm[i]>vmax) vmax=mm[i];         }         si.minv=vmin;         si.maxv=vmax;           sprintf(p,"上下合并maxv:%d=maxL:%d * maxR:%d",si.maxv,maxL,maxR);pmt(p);getch();     } } void pg() {     int i,j,s;     static char p[128];      ClearCon();     for (i=1;i<n;i++) {         sg[i][1].maxv=d[i];         sg[i][1].minv=d[i];     }     show("init");getch();     for (j=2;j<n;j++) {//长度         for (i=1;i<n;i++) {//起点             for (s=1;s<j;s++) {//子切分位置                 getmaxmin(i,s,j);                 if (sg[i][j].minv > si.minv) sg[i][j].minv=si.minv;                  sprintf(p,"sg[开始i:%d][长度j:%d].maxv:%d < maxv=%d ?",i,j,sg[i][j].maxv,si.maxv);pmt(p);                 getXY();gotoXY(j*3,i);getch();gotoXY(X,Y);                 if (sg[i][j].maxv < si.maxv) {                     sg[i][j].maxv=si.maxv;                     show("");                     sprintf(p,"Yes, sg[开始i:%d][长度j:%d].maxv:%d <-- maxv=%d",i,j,sg[i][j].maxv,si.maxv);pmt(p);                     getXY();gotoXY(j*3,i);getch();gotoXY(X,Y);                 } else {                     sprintf(p,"sg[开始i:%d][长度j:%d].maxv:%d < maxv=%d ? No",i,j,sg[i][j].maxv,si.maxv);pmt(p);                     getch();                 }             }         }     }     sprintf(p,"规划完毕，下一步计算总maxv...");pmt(p);getch();     maxv=sg[1][n-1].maxv;     sprintf(p,"总maxv=sg[1][n-1].maxv:%d",maxv);pmt(p);     getXY();gotoXY((n-1)*3,1);getch();gotoXY(X,Y);     for (i=2;i<n;i++) {         sprintf(p,"总maxv:%d < sg[开始i:%d][长度n-1:%d].maxv:%d ?",maxv,i,n-1,sg[i][n-1].maxv);pmt(p);         getXY();gotoXY((n-1)*3,i);getch();gotoXY(X,Y);         if (maxv < sg[i][n-1].maxv) {             maxv=sg[i][n-1].maxv;             sprintf(p,"Yes,总maxv:%d <-- sg[开始i:%d][长度n-1:%d].maxv:%d",maxv,i,n-1,sg[i][n-1].maxv);pmt(p);             getXY();gotoXY((n-1)*3,i);getch();gotoXY(X,Y);         } else {             sprintf(p,"总maxv:%d < sg[开始i:%d][长度n-1:%d].maxv:%d ? No",maxv,i,n-1,sg[i][n-1].maxv);pmt(p);             getch();         }     }     sprintf(p,"计算出总maxv:%d",maxv);pmt(p);getch();     gotoXY(0,n+1); }  int main() {     int i;     char b[2];      setlocale(LC_ALL,"chs");     scanf("%d",&n);     for (i=1;i<=n;i++) {         scanf("%d%1s",&d[i],b);o[(i%n)+1]=b[0];     }     n++;     pg();//PolyGame     printf("%d\n",maxv);     return 0; } //4 //1 + //2 + //4 + //8 +

参考 http://blog.csdn.net/qq_16234613/article/details/52235082


Question: c语言里面的高位值-0x30是什么意思啊

请查看有关2进制10进制16进制问题 http://blog.csdn.net/zhangyandong16/article/details/20203227

0x表示16进制数，0x30表示16进制的30，16进制的30转化成10进制就是48

0x30等于十进制的48，48也是0的ASCII值，，1-9的ASCII值是49-57，，所以某一个值－0x30，，就是将字符0-9转换为0-9

‘0'～'9' -0x30 变成 0～9

要看楼主这个0x30是那个地方用的？


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

std::string

改好了，谢谢~

String 是小写


Question: 大哥帮改一下错

#include<stdio.h>  char count(char *str) {     int i = 0,j = 0, k, num;     char (*p)[10],r[10][10];      p = r;     for(k = 0;*(str + k)!='\0'; k++)     {         if(*(str + k)>='0'&&*(str+k)<='9')         {             *(*(p + i) + j) = *(str + k);             j++;         }         if(!(*(str+k)>='0'&&*(str+k)<='9'))         {             if(j >= 1)             {                 *(*(p + i) + j) = 0;                 i++;                 j = 0;             }         }     }     num = i;     for(i = 0; i < num;i++)     {         for(j=0;j < 10 && p[i][j];j++)         {             printf("%c",*(*(p+i)+j));         }         printf("\n");     }     return 0; } int main() {     char a[100]={"sjd2342hg4346.hg54353hj35?et47865fd4fdg54675f64dg:566,yt678"};     count(a);     return 0; } 对比一下，有些地方是需要改一下的

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

j == 0;  改成：  j = 0;


Question: 一个简单的表格问题，虚心请教各位

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

引用 1楼user-2 的回复:


Question: 格式化输出的问题

有区别，9是整数，9.0是浮点数，具体可以参考一下这篇博文 http://blog.csdn.net/libing403/article/details/72934198

为什么不参考printf的源代码比如 C:\Program Files\Microsoft Visual Studio 10.0\VC\crt\src\output.c 呢？   printf里面的%和变量的一一对应关系 scanf里面的%和变量以及变量前加不加&的一一对应关系 是C代码中非常容易出错的地方，而且通常编译还不出错。 所以在编译源代码之前值得专门仔细检查一遍甚至多遍。  printf("%鱼类",CSDN的qq_37824129);//你希望输出啥呢？

两种编译器，产生了不同的结果。额，这个有什么解释么。

引用 5 楼 wanggui2015 的回复:楼上说的float格式的问题，楼主应该是懂的额，其实楼主应该想问的是这两种输出方式为什么得到不一样的结果吧？？  我在我的编译器上试了，结果都是0额，不晓得什么情况，网上找了篇资料，也许能帮到你。  http://blog.csdn.net/solomon1558/article/details/40798901 嗯嗯，关于浮点数的二进制表示，我查过资料，了解了一些。 但是同样是  将浮点数以%d输出，或者  将整数以%f输出，但是得到的结果确不相同的。 不明白。所以，前来请教。 我是0基础学习，没有学过什么计算机基础知识，更不知道什么叫做编译原理。这是我在看C Primer Plus时候，在书上看到的一句话想到的问题。so，还请详细解答下。

建议了解一下float类型在内存中的存储方式。int类型的存储相对比较简单，float就不一样了，建议了解一下就能回答你这些问题了。 http://blog.csdn.net/xieyihua1994/article/details/51659379 还有  http://www.cnblogs.com/little-white/archive/2013/08/04/3236493.html

看一下ieee754里的floa格式你就明白了。

int类型和float类型的存储格式完全是不相通的，直接取地址这样的做法是错误的。

你这是在玩编译器啊，使用正确的格式化符号才能正确的输出对应的值

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

引用 9 楼 qq_36409192 的回复:请参考：http://blog.csdn.net/solomon1558/article/details/40798901 谢谢你。

引用 7 楼 zhao4zhong1 的回复:为什么不参考printf的源代码 C:\Program Files\Microsoft Visual Studio 10.0\VC\crt\src\output.c 呢？  谢谢赵老师的回复。


Question: 求助！光电计数在8*8点阵LED显示0—99,下面程序哪里出错了

1、延迟有问题的话，最后用示波器实际测量一下； 2、软件的角度看看延迟程序是否被优化掉了，尝试加volatile修饰符，例如volatile uint x,y;   引用 楼主 qy06007aili 的回复:#include<reg51.h>  #define uchar unsigned char  #define uint unsigned int  uchar code tab[]={0xfe,0xfd,0xfb,0xf7,0xef,0xdf,0xbf,0x7f}; uchar code number_l[][4]={ {0xff,0xc1,0xdd,0xc1}, //0 {0xff,0xff,0xff,0xc1}, //1 {0xff,0xc5,0xd5,0xd1}, //2 {0xff,0xd5,0xd5,0xc1},//3 {0xff,0xf1,0xc1,0xf7},//4  {0xff,0xd1,0xd5,0xc5}, //5 {0xff,oxc1,0xd5,0xd5},//6 {0xff,0xfd,0xfd,0xc1}, //7 {0xff,0xc1,0xd5,0xc1},//8 {0xff,0xd1,0xd5,0xc1}//9  }   void delay(uint z){    uint x,y;    for(x=z;x>0;x--)     for(y=110;y>0;y--);  }    void display(uchar num){  uchar decade,unit,a,b;   decade=num/10;   unit=num%10;   b=0;  for(a=0;a<8;a++){   P2=tab[b];   if(a<4){        P0=~number_l[decade][a];        delay(1);    }    else{        P0=~number_l[unit][a-4];        delay(1);        }     b++;    }  }  void main() {    EA=1;     EX0=1;    IT0=1;    num=0;    P0=0xff;     P2=0x00; 	delay(1000);  	P0=0x00;  	delay(1000);   	P0=0xff; 	delay(1000); 	while(1){ 	 display(num);  	} 	  }   void exter0() interrupt 0 { 	  num++; 	  if(num==100) { 	  num=0; 	  }  }   用keil编程的时候显示延迟程序有错误，求大神帮忙，看一下整体程序有什么错误嘛？


Question: 大哥帮忙看看

A[B] *(A+B) *(B+A) B[A] //以上四行等价  "abc"[1] *("abc"+1) *(1+"abc") 1["abc"] //以上四行等价  A[0] *(A) 0[A] //以上三行等价  理解和讨论之前请先学会如何观察！ 仅供参考：//char (*(*x[3])())[5];//x是什么类型的变量? // //分析C语言声明，关键是搞清楚这个变量是个什么东西（函数、指针、数组）， //是函数那么剩下的就是他的参数和返回值， //是指针那剩下部分是说明他指向什么， //是数组剩下的部分就是说明数组的成员是什么类型。 //解析C语言声明规则： //从左侧第一个标识符开始，按照优先级进行结合。*表示是..的指针，const表示只读的，volatile表示可变的，[]表示是数组，()表示是函数。 // //x和[3]结合说明是一个大小为3的数组，该数组的每个元素为一类指针，该类指针指向一类函数，该类函数无参数，返回一类指针，该类指针指向一个大小为5的char型数组 #include <stdio.h> #include <typeinfo.h> char num[5]; char (*x00())[5] {     return # } int main() {     char (*(*x[3])())[5];//是个数组，大小为3     char (*(*x0  )())[5];//数组的元素，是个函数指针     char (*( x00 )())[5];//函数原型，参数为空，返回值为指针     char (*  x000   )[5];//返回值      x0 = x00;     x[0] = x0;     x[1] = x0;     x[2] = x0;     printf("typeid(x).name() is %s\n",typeid(x).name());     return 0; } //typeid(x).name() is char (* (__cdecl**)(void))[5]

y是指向 char[5]类型的指针，指向的是char数组  而j是一个char*类型的指针  它们是两种完全不同类型的指针，不能进行隐式转换

我只想输出一个字母。

#include<stdio.h> int main() {     char h[2][6] = {"gffdy","usfd"}, (*y)[6], *j;     y = h;     j = y[1];     printf("%c\n",*j);     return 0; } 注意字符串"gffdy"，若用%s输出就已经越界了。 j = y[1] 表示第二行（从0开始）的首地址。也可以写成： j = *(y+1) y表示的是长度为6的指针。y是数组指针，和j的类型是有区别的。


Question: C语言文件的读取和写入不成功是什么原因啊。

如果要读的文件以"w"打开，那么文件就会被截断，即源文件的内容就为空。即无法从源文件里读到数据。while循环就不会执行。 要写的文件以”r"形式打开，那么它是没有写权限的。

引用 1 楼 zhao4zhong1 的回复:to = fopen("1.txt", "w"); from = fopen("2.txt", "r"); 一语中第，要写的文件的以读的形式打开，会有问题，要读的以写的形式打开没问题

吃饭用碗，拉屎用马桶。


Question: 关于进制转换的问题

这个资料可能对你有用---转换说明符 http://blog.csdn.net/libing403/article/details/72934198

引用 1 楼 cfjtaishan 的回复:十进制转十六进制，在循环取余时，注意看余数是否大于等于10，若大于等于10，则加‘A’，若小于10，则加'0'，比如  if (num % 16 >= 10) hex[i] = num % 16 + 'A'; else hex[i] = num % 16 + '0';  if (num % 16 >= 10)     hex[i] = num % 16 + 'A' - 10; else     hex[i] = num % 16 + '0'; 更改一下

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

引用 3楼实娃星哥 的回复:更正一下 // 10进制转化为16进制字符串 std::string t10216(int x) { 	static std::string str; 	int m = x / 16; 	int n = x % 16; 	char c[2] = { 0 }; 	if (n < 10) 	{ 		sprintf_s(c ,"%d",n); 	} 	else 	{ 		sprintf_s(c,"%c" ,'A'+n-10); 	} 	str = c + str; 	if (m > 0) 	{ 		return t10216(m); 	} 	std::string strResult = str; 	str.clear(); 	return strResult; }谢谢，放学后试一下

仅供参考 // 10进制转化为16进制字符串 std::string t10216(int x) { 	static std::string str; 	int m = x / 16; 	int n = x % 16; 	char c[2] = { 0 }; 	if (n < 10) 	{ 		sprintf_s(c ,"%d",n); 	} 	else 	{ 		sprintf_s(c,"%c" ,'A'+n-10); 	} 	str = c + str; 	if (m > 0) 	{ 		t10216(m); 	} 	 	return str; }  // 16进制字符串(不带前缀0X,字母都是大写)转化为10进制整型 int t16210(LPCSTR str16) { 	int nResult = 0; 	const char *p = str16+strlen(str16)-1; 	int iStep = 0; 	while (p >= str16) 	{ 		int nTemp = 0; 		if (*p > 64) 		{ 			nTemp = 10 + *p - 'A'; 		} 		else 			nTemp = *p - '0'; 		for (int i = 0; i != iStep;++i) 		{ 			nTemp *= 16; 		}  		nResult += nTemp ; 		iStep++; 		p--; 	} 	return nResult; }


Question: 软输入软输出频域均衡算法研究(基于MMSE算法)


Question: 求教如何通过算法对数列走势做筛选

你确定用信号系统的相关知识处理这个问题是最简便的方法么？大学学过，不过忘得差不多了。有没有更简便的算法？

搜“低通滤波”

引用 3 楼 DelphiGuy 的回复:简单判断：用第二个数减去第一个数得到一个差值...第N个数减去第N-1个数得到一个差值，总共得到N-1个差值，分析这个差值序列就可以判断，比如其中至少有2/3是负值并且至少有连续若干个小于0的数就可以断定为大致降序，标准可以自己设定。


Question: 关于排序的一个小问题，求指导

只考虑基于比较的排序，不限制比较排序的方法，关于5个数排序的最少比较次数应该是7次，这个在 D.E.Knuth 的著作 《计算机程序设计艺术》  第三卷(排序和查找) 的<5.3.1 极少比较排序>中可以找到详细的解释。

找一个排序算法，对于最多比较几次，最少比较几次。这个跟排序的时间复杂度有关的，时间复杂度约低的比较次数应该越小，相反越多。 对于最多和最少，5个数据记录，那么若是从大到校排序，原数据本身是从小到大的顺序，时间复杂度是最大的，相反应该是最小的吧（比如冒泡排序，选择排序）

”则至少需要比较——次，至多需要比较——次“ 你这句话是需求呢，还是问题？

第一次发帖，真的没有人回一下吗？


Question: 头文件不存在

也许是没放在同一目录下吧。

引用 6 楼 yechuan710 的回复:[quote=引用 5 楼 shihengzhen101 的回复:] [quote=引用 3 楼 yechuan710 的回复:] 我用的是vc，那些解决问题的都是vs 这和环境没什么关系，你还是在工程下或者整个电脑中搜索一下到底有没有这个文件，如果有的话调整一下目录，如果没有那肯定会报错了，找找是不是少安装什么东西了，或者工程缺失了部分文件[/quote] 找不到，这个好像不是头文件，怎么找[/quote] http://blog.csdn.net/anobodykey/article/details/34126291 这个里边有解释，仔细看一下，文章中搜索winapifamily.h

引用 4 楼 zhao4zhong1 的回复:[quote=引用 3 楼 yechuan710 的回复:] 我用的是vc，那些解决问题的都是vs vc不是vs的一部分吗？[/quote] 没用过vs

引用 5 楼 shihengzhen101 的回复:[quote=引用 3 楼 yechuan710 的回复:] 我用的是vc，那些解决问题的都是vs 这和环境没什么关系，你还是在工程下或者整个电脑中搜索一下到底有没有这个文件，如果有的话调整一下目录，如果没有那肯定会报错了，找找是不是少安装什么东西了，或者工程缺失了部分文件[/quote] 找不到，这个好像不是头文件，怎么找

引用 3 楼 yechuan710 的回复:我用的是vc，那些解决问题的都是vs 这和环境没什么关系，你还是在工程下或者整个电脑中搜索一下到底有没有这个文件，如果有的话调整一下目录，如果没有那肯定会报错了，找找是不是少安装什么东西了，或者工程缺失了部分文件

引用 3 楼 yechuan710 的回复:我用的是vc，那些解决问题的都是vs vc不是vs的一部分吗？

我用的是vc，那些解决问题的都是vs

这个是自定义的头文件，或者你在引用别人的库函数时需要加入别人函数的声明或者部分数据结构的使用。建议找一下库里头文件。  这些朋友的解决方法，可以借鉴一下： http://blog.csdn.net/andux1/article/details/52152564 还有 http://www.cnblogs.com/duguxue/p/4666967.html  遇到问题，建议先去网上搜索一下，看看别人有没有遇到相同或类似的问题。

参考：http://www.cnblogs.com/duguxue/p/4666967.html 参考：http://blog.csdn.net/anobodykey/article/details/34126291


Question: 通用链表

引用 5 楼 qq_29137325 的回复:你们还不知道什么是通用链表吗 我要的是和数据类型无关的链表 参考4楼。

C做类型无关的好像比较难。用C++的模板才好做吧？

你们还不知道什么是通用链表吗 我要的是和数据类型无关的链表

高兴了楼主还可以参考Linux源代码相关片断。

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

//带表头结点的单向链表 #include <stdio.h> #include <stdlib.h> #include <malloc.h> #include <time.h> struct NODE {     int          data;     struct NODE *next; } H,*head,*p,*q,*q1,*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;     }      //将整个链表逆序     if (head->next!=NULL && head->next->next!=NULL) {         p=head->next;         q=p->next;         p->next=NULL;         while (1) {             q1=q->next;             q->next=p;             p=q;             q=q1;             if (NULL==q) break;         }         head->next=p;     }      //输出整个单链表     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; } //84->28->20->23->96->19->59->97->29->41-> //84->28->05->20->23->96->19->59->97->29->41-> //84->28->05->20->96->19->59->97->29->41-> //05->19->20->28->29->41->59->84->96->97-> //97->96->84->59->41->29->28->20->19->05-> //41->29->28->20->19->05->97->96->84->59-> //

建议改一改别人的链表，然后编程自己的。 通用链表没遇到过，没有那个人写的链表正好适合你的。代码都是这样，不然大家做什么项目都用一套”通用“的代码多好，那还要需求分析做什么。 我感觉网上的代码大部分还是能运行的，不能运行的原因可能跟你用的编译器有关系，也可能跟你的编译环境和系统有关系的。 所以，你没有说你的运行，编译环境。即使下面的朋友给你写一个”通用“的链表，不还成了”阿猫阿狗“的嘛。 问问题，先要端正态度哦。不要说这些让帮助你的人还得听些不舒服的话。


Question: 关于使用C语言在windows控制台应用程序下打印表格问题？

不能运行是什么错误

引用 3楼赵4老师 的回复:再供参考:#pragma comment(lib,"user32") #pragma comment(lib,"gdi32") #include <conio.h> #include <stdio.h> #include <stdlib.h> #include <windows.h> wchar_t a2w[256]={ 0x0020,0x263a,0x263b,0x2665,0x2666,0x2663,0x2660,0x2022, 0x25d8,0x25cb,0x25d9,0x2642,0x2640,0x266a,0x266b,0x263c, 0x25ba,0x25c4,0x2195,0x203c,0x00b6,0x00a7,0x25ac,0x21a8, 0x2191,0x2193,0x2192,0x2190,0x221f,0x2194,0x25b2,0x25bc, 0x0020,0x0021,0x0022,0x0023,0x0024,0x0025,0x0026,0x0027, 0x0028,0x0029,0x002a,0x002b,0x002c,0x002d,0x002e,0x002f, 0x0030,0x0031,0x0032,0x0033,0x0034,0x0035,0x0036,0x0037, 0x0038,0x0039,0x003a,0x003b,0x003c,0x003d,0x003e,0x003f, 0x0040,0x0041,0x0042,0x0043,0x0044,0x0045,0x0046,0x0047, 0x0048,0x0049,0x004a,0x004b,0x004c,0x004d,0x004e,0x004f, 0x0050,0x0051,0x0052,0x0053,0x0054,0x0055,0x0056,0x0057, 0x0058,0x0059,0x005a,0x005b,0x005c,0x005d,0x005e,0x005f, 0x0060,0x0061,0x0062,0x0063,0x0064,0x0065,0x0066,0x0067, 0x0068,0x0069,0x006a,0x006b,0x006c,0x006d,0x006e,0x006f, 0x0070,0x0071,0x0072,0x0073,0x0074,0x0075,0x0076,0x0077, 0x0078,0x0079,0x007a,0x007b,0x007c,0x007d,0x007e,0x2302, 0x00c7,0x00fc,0x00e9,0x00e2,0x00e4,0x00e0,0x00e5,0x00e7, 0x00ea,0x00eb,0x00e8,0x00ef,0x00ee,0x00ec,0x00c4,0x00c5, 0x00e9,0x00e6,0x00c6,0x00f4,0x00f6,0x00f2,0x00fb,0x00f9, 0x00ff,0x00d6,0x00dc,0x00a2,0x00a3,0x00a5,0x20a7,0x0192, 0x00e1,0x00ed,0x00f3,0x00fa,0x00f1,0x00d1,0x00aa,0x00ba, 0x00bf,0x2310,0x00ac,0x00bd,0x00bc,0x00a1,0x00ab,0x00bb, 0x2591,0x2592,0x2593,0x2502,0x2524,0x2561,0x2562,0x2556, 0x2555,0x2563,0x2551,0x2557,0x255d,0x255c,0x255b,0x2510, 0x2514,0x2534,0x252c,0x251c,0x2500,0x253c,0x255e,0x255f, 0x255a,0x2554,0x2569,0x2566,0x2560,0x2550,0x256c,0x2567, 0x2568,0x2564,0x2565,0x2559,0x2558,0x2552,0x2553,0x256b, 0x256a,0x2518,0x250c,0x2588,0x2584,0x258c,0x2590,0x2580, 0x03b1,0x00df,0x0393,0x03c0,0x03a3,0x03c3,0x00b5,0x03c4, 0x03a6,0x0398,0x03a9,0x03b4,0x221e,0x03c6,0x03b5,0x2229, 0x2261,0x00b1,0x2265,0x2264,0x2320,0x2321,0x00f7,0x2248, 0x00b0,0x2219,0x00b7,0x221a,0x207f,0x00b2,0x25a0,0x00ff, }; extern "C" HWND WINAPI GetConsoleWindow(); void HideTheCursor() {     CONSOLE_CURSOR_INFO cciCursor;     HANDLE hStdOut = GetStdHandle(STD_OUTPUT_HANDLE);      if(GetConsoleCursorInfo(hStdOut, &cciCursor)) {         cciCursor.bVisible = FALSE;         SetConsoleCursorInfo(hStdOut, &cciCursor);     } } void ShowTheCursor() {     CONSOLE_CURSOR_INFO cciCursor;     HANDLE hStdOut = GetStdHandle(STD_OUTPUT_HANDLE);      if(GetConsoleCursorInfo(hStdOut, &cciCursor)) {         cciCursor.bVisible = TRUE;         SetConsoleCursorInfo(hStdOut, &cciCursor);     } } int main() {     HWND  hwnd;     HDC   hdc;     HFONT hfont;     wchar_t ws[256];     unsigned char s[256];     int i;       system("color F0");     system("cls");     HideTheCursor();     hwnd  = GetConsoleWindow();     hdc   = GetDC(hwnd);     hfont = CreateFont(16,  0, 0, 0, 0, 0, 0, 0, 0           , 0, 0, 0, 0, "Lucida Console");     SelectObject(hdc,hfont);     TextOutW(hdc,10,10,L"你好",2);     for (i=0;i<256;i++) s[i]=i;     for (i=0;i<256;i++) ws[i]=a2w[s[i]];     TextOutW(hdc,10, 40,ws    ,32);     TextOutW(hdc,10, 80,ws+ 32,32);     TextOutW(hdc,10,120,ws+ 64,32);     TextOutW(hdc,10,160,ws+ 96,32);     TextOutW(hdc,10,200,ws+128,32);     TextOutW(hdc,10,240,ws+160,32);     TextOutW(hdc,10,280,ws+192,32);     TextOutW(hdc,10,320,ws+224,32);     DeleteObject(hfont);     ReleaseDC(hwnd,hdc);     getch();     system("color 07");     system("cls");     ShowTheCursor();     return 0; }  老师有心了，谢谢您

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


Question: C语言结构体函数

哦哦哦，好的，已经解决了   谢谢

引用 5 楼 xiaohuh421 的回复:上面错了 修改成 int binsearch(char *word, struct key *tab, int n) 这两种方法编译器都能正常识别（[], *)，主要是bsearch所在的源文件里找不到struct key的声明吧

int binsearch(char *word, struct key tab[ ], int n)  修改成 int binsearch(char *word, struct key tab*, int n)

#include<stdio.h> #include<ctype.h> #include<string.h>  struct key{     char *word;     int count; }; struct key keytab[] = {     {"auto", 0},     {"break", 0},     {"case", 0},     {"char", 0},     {"const", 0} };  #define NKEYS (sizeof keytab / sizeof(struct key)) #define MAXWORD 100  int getword(char *, int); int binsearch(char *, struct key *, int);  int main() {     int i;     char word[MAXWORD];      //while(getword(word, MAXWORD) != EOF)     while(fgets(word, MAXWORD, stdin) != NULL) {         word[strlen(word) - 1] = 0;         if(isalpha(word[0]))             if((i = binsearch(word, keytab, NKEYS)) >= 0)                 keytab[i].count++;     }     for(i = 0; i < NKEYS; i++)         if(keytab[i].count > 0)             printf("%4d %s\n", keytab[i].count, keytab[i].word);     return 0; }  int binsearch(char *word, struct key tab[ ], int n) {     int cond;     int low, high, mid;      low = 0;     high = n - 1;     while(low <= high) {         mid = (low+high) / 2;         if((cond = strcmp(word, tab[mid].word)) < 0)             high = mid - 1;         else if(cond > 0)             low = mid + 1;         else             return mid;     }     return -1; } 这个方法是都写到一个源文件里，如果是多个源文件同时存在，建议添加一个头文件，将结构体的声明放在头文件里，然后多个源文件include该头文件

bsearch是在另一个文件里，这个文件找不到struct key数据结构，所以会提示这个错误。解决办法是：两个方法。 1. 把bsearch放在main同源文件里。 2. 将struct key单独放在一个头文件里，在两个源文件里都引用该头文件。 两种方法都可以。

#include<stdio.h> #include<ctype.h> #include<string.h> #define NKEYS (sizeof keytab / sizeof(struct key)) #define MAXWORD 100   struct key{     char word[10];     int count; }; key keytab[] = {     //关键字列表必须按升序存储在keytab中     {"auto", 0},     {"break", 0},     {"case", 0},     {"char", 0},     {"const", 0}  };   int getword(char *, int); int binsearch(char *, struct key *, int);   //统计输入中C语言关键字的个数 int main() {     int n;     char word[MAXWORD];       while(getword(word, MAXWORD) != EOF)         if(isalpha(word[0]))    //isalpha判断字符是否为英文字母，yes，return 非0；No，return 0；             if((n = binsearch(word, keytab, NKEYS)) >= 0)                 keytab[n].count++;     for(n=0; n<NKEYS; n++)         if(keytab[n].count > 0)             printf("%4d %s\n", keytab[n].count, keytab[n].word);     return 0; }


Question: 请问栈溢出该怎么解决，我希望数组能大一点，因为我要读的文件挺长的

三种方法 1、一块一块读 2、用new、malloc等动态分配内存，但是不能超过2g左右 3、用内存映射

声明成static最容易

建议这种情况使用malloc和realloc，malloc是申请初始大小，realloc可以增加申请的空间的大小，也可以逐步增加。

容量大小从小到大：栈≤全局数据≤堆≤文件≤硬盘≤磁盘阵列≤云存储 当程序需要使用比如2GB～1TB左右的存储时，最简单的办法恐怕得是用文件读写模拟内存读写了吧。windows参考_fseeki64函数，linux参考fseeko64函数。 FILE *fA;fA=fopen("A","rb+");_fseeki64(fA,10000000000i64*sizeof(int),SEEK_SET);fputc(fA,0);//int A[10000000000]; int B; _fseeki64(fA,9999999999i64*sizeof(int),SEEK_SET);fread(&B,1,sizeof(int),fA);//B=A[9999999999]; _fseeki64(fA,9999999999i64*sizeof(int),SEEK_SET);fwrite(&B,1,sizeof(int),fA);//A[9999999999]=B; fclose(fA);

在占用内存空间较大的局部数组声明的前面加static将其从堆栈数据段挪到全局数据段即可避开因局部数组大小超过默认堆栈大小1MB造成程序不能正常运行的问题。

对于很大的缓冲区, 请使用new 当然, new也不能无限制申请.  对于文件的处理, 不是整个全部读取到内存中, 而是读取一部分, 处理一部分. 这样就不需很大的缓冲区了


Question: 新人求纠错基于Hamilton回路算法的C语言程序

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


Question: 做了1星期了，还是没有结果

引用 2 楼 weixin_38332783 的回复:引用 1楼幻夢之葉 的回复:有什么难点吗？不知道怎么操控变长数组，实现增加删改查……主要是想通过一个二维数组打印出来一个表格来，该怎么样操作呢。 变长数组，C语言是不支持的。但是可以通过malloc，realloc来实现变长数组。通过realloc来增加列数

只能通过malloc来定义变长数组，不能用a[x]的方式

char **p; int n,m; scanf("%d%d",&n,&m); p=(char **)malloc(n*sizeof(char *)); for(int i =0, i < n; i++) { 	p[i]=(char *)malloc(m*sizeof(char)); }

引用 5楼赵4老师 的回复:仅供参考：#include <windows.h> #include <stdio.h>  void ConPrint(char *CharBuffer, int len); void ConPrintAt(int x, int y, char *CharBuffer, int len); void gotoXY(int x, int y); void ClearConsole(void); void ClearConsoleToColors(int ForgC, int BackC); void SetColorAndBackground(int ForgC, int BackC); void SetColor(int ForgC); void HideTheCursor(void); void ShowTheCursor(void);  int main(int argc, char* argv[]) {    HideTheCursor();    ClearConsoleToColors(15, 1);    ClearConsole();    gotoXY(1, 1);    SetColor(14);    printf("This is a test...\n");    Sleep(5000);    ShowTheCursor();    SetColorAndBackground(15, 12);    ConPrint("This is also a test...\n", 23);    SetColorAndBackground(1, 7);    ConPrintAt(22, 15, "This is also a test...\n", 23);    gotoXY(0, 24);    SetColorAndBackground(7, 1);    return 0; }  //This will clear the console while setting the forground and //background colors. void ClearConsoleToColors(int ForgC, int BackC) {    WORD wColor = ((BackC & 0x0F) << 4) + (ForgC & 0x0F);    //Get the handle to the current output buffer...    HANDLE hStdOut = GetStdHandle(STD_OUTPUT_HANDLE);    //This is used to reset the carat/cursor to the top left.    COORD coord = {0, 0};    //A return value... indicating how many chars were written    //not used but we need to capture this since it will be    //written anyway (passing NULL causes an access violation).    DWORD count;     //This is a structure containing all of the console info    // it is used here to find the size of the console.    CONSOLE_SCREEN_BUFFER_INFO csbi;    //Here we will set the current color    SetConsoleTextAttribute(hStdOut, wColor);    if(GetConsoleScreenBufferInfo(hStdOut, &csbi))    {       //This fills the buffer with a given character (in this case 32=space).       FillConsoleOutputCharacter(hStdOut, (TCHAR) 32, csbi.dwSize.X * csbi.dwSize.Y, coord, &count);        FillConsoleOutputAttribute(hStdOut, csbi.wAttributes, csbi.dwSize.X * csbi.dwSize.Y, coord, &count);       //This will set our cursor position for the next print statement.       SetConsoleCursorPosition(hStdOut, coord);    } }  //This will clear the console. void ClearConsole() {    //Get the handle to the current output buffer...    HANDLE hStdOut = GetStdHandle(STD_OUTPUT_HANDLE);    //This is used to reset the carat/cursor to the top left.    COORD coord = {0, 0};    //A return value... indicating how many chars were written    //   not used but we need to capture this since it will be    //   written anyway (passing NULL causes an access violation).    DWORD count;    //This is a structure containing all of the console info    // it is used here to find the size of the console.    CONSOLE_SCREEN_BUFFER_INFO csbi;    //Here we will set the current color    if(GetConsoleScreenBufferInfo(hStdOut, &csbi))    {       //This fills the buffer with a given character (in this case 32=space).       FillConsoleOutputCharacter(hStdOut, (TCHAR) 32, csbi.dwSize.X * csbi.dwSize.Y, coord, &count);       FillConsoleOutputAttribute(hStdOut, csbi.wAttributes, csbi.dwSize.X * csbi.dwSize.Y, coord, &count);       //This will set our cursor position for the next print statement.       SetConsoleCursorPosition(hStdOut, coord);    } }  //This will set the position of the cursor void gotoXY(int x, int y) {    //Initialize the coordinates    COORD coord = {x, y};    //Set the position    SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), coord); }  //This will set the forground color for printing in a console window. void SetColor(int ForgC) {    WORD wColor;    //We will need this handle to get the current background attribute    HANDLE hStdOut = GetStdHandle(STD_OUTPUT_HANDLE);    CONSOLE_SCREEN_BUFFER_INFO csbi;     //We use csbi for the wAttributes word.    if(GetConsoleScreenBufferInfo(hStdOut, &csbi))    {       //Mask out all but the background attribute, and add in the forgournd color       wColor = (csbi.wAttributes & 0xF0) + (ForgC & 0x0F);       SetConsoleTextAttribute(hStdOut, wColor);    } }  //This will set the forground and background color for printing in a console window. void SetColorAndBackground(int ForgC, int BackC) {    WORD wColor = ((BackC & 0x0F) << 4) + (ForgC & 0x0F);;    SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), wColor); }  //Direct console output void ConPrint(char *CharBuffer, int len) {    DWORD count;    WriteConsole(GetStdHandle(STD_OUTPUT_HANDLE), CharBuffer, len, &count, NULL); }  //Direct Console output at a particular coordinate. void ConPrintAt(int x, int y, char *CharBuffer, int len) {    DWORD count;    COORD coord = {x, y};    HANDLE hStdOut = GetStdHandle(STD_OUTPUT_HANDLE);    SetConsoleCursorPosition(hStdOut, coord);    WriteConsole(hStdOut, CharBuffer, len, &count, NULL); }  //Hides the console cursor void HideTheCursor() {    CONSOLE_CURSOR_INFO cciCursor;    HANDLE hStdOut = GetStdHandle(STD_OUTPUT_HANDLE);     if(GetConsoleCursorInfo(hStdOut, &cciCursor))    {       cciCursor.bVisible = FALSE; 	  SetConsoleCursorInfo(hStdOut, &cciCursor);    } }  //Shows the console cursor void ShowTheCursor() {    CONSOLE_CURSOR_INFO cciCursor;    HANDLE hStdOut = GetStdHandle(STD_OUTPUT_HANDLE);     if(GetConsoleCursorInfo(hStdOut, &cciCursor))    {       cciCursor.bVisible = TRUE; 	  SetConsoleCursorInfo(hStdOut, &cciCursor);    } }  谢谢赵老师。上次回复我的被系统删除了所以就找不到了

有什么难点吗？


Question: 请问有没有什么办法可以往程序里自动加一小段代码？

开源性能分析项目难道就找不到吗？！

引用 8 楼 zhu339111520 的回复:  然后根据分析结果，可以看到每个函数执行时间，独占时间意思是函数本身运行时间(不包括函数里调用的其它函数运行实现)， 非独占就是包括函数里调用的其它函数执行时间咯，从我这简单的测试截图可以看到，创建文件还是比较耗时的。   教授要我做个小程序 类似于VS这种功能的。。。。

用调试 API 监控它运行啊，  WaitForDebugEvent  ptrace 啥的，  修改要监控的函数入口点代码， 跳到自己计时的代码转一圈就是了， 不麻烦... 如果别人程序检查自身完整性就只能用几个 DR 寄存器， 监控几个函数还行， 如果人还反调试就洗洗睡了。

无profiler不要谈效率！！尤其在这个云计算、虚拟机、模拟器、CUDA、多核 、多级cache、指令流水线、多种存储介质、……满天飞的时代！

基本不可能，但是查看特定线程的cpu占用还是能做到的。

引用 4 楼 weixin_38194305 的回复:[quote=引用 2 楼 cfjtaishan 的回复:] 程序自动加，如果是已经编译好的程序，恐怕是很难做到的。把事先做好的函数放到里面，然后通过某个接口来调用是可行的。  程序没有编译 只想另外写个程序往被测试的程序里加代码[/quote] 很难做到，不建议继续走着条路了。

引用 2 楼 cfjtaishan 的回复:程序自动加，如果是已经编译好的程序，恐怕是很难做到的。把事先做好的函数放到里面，然后通过某个接口来调用是可行的。  程序没有编译 只想另外写个程序往被测试的程序里加代码


Question: 为什么要将char*重新赋值

src完全可以不用重新赋值，并没有锦上添花，而是画蛇添足，跟const也毫无关系。

引用 4 楼 u010647109 的回复:[quote=引用 1 楼 starytx 的回复:] dest指向的目标字符串，如果不重新定义一个指针的话，这个会在循环中移动到末尾，return 就有问题了。所以需要保留目标字符串首地址 src呢？为什么也要重新赋值，它并不return啊[/quote] 这个可以不做重新赋值，但是也是考虑不改变src的内容和位置。以便于调用之后不改变实参src

引用 4 楼 u010647109 的回复:[quote=引用 1 楼 starytx 的回复:] dest指向的目标字符串，如果不重新定义一个指针的话，这个会在循环中移动到末尾，return 就有问题了。所以需要保留目标字符串首地址 src呢？为什么也要重新赋值，它并不return啊[/quote]直接使用形参也可以的，没有必要性

引用 12 楼 u010647109 的回复:[quote=引用 10 楼 cfjtaishan 的回复:] [quote=引用 4 楼 u010647109 的回复:] [quote=引用 1 楼 starytx 的回复:] dest指向的目标字符串，如果不重新定义一个指针的话，这个会在循环中移动到末尾，return 就有问题了。所以需要保留目标字符串首地址 src呢？为什么也要重新赋值，它并不return啊[/quote] 这个可以不做重新赋值，但是也是考虑不改变src的内容和位置。以便于调用之后不改变实参src[/quote]   src定义的也是const char *src，不过看大家都认为它重定义可有可无，那好吧。[/quote] const修饰的是src指向的数据，即字符串。const修饰之后字符串的内容不可以修改，而不是指针指向的地址值不可以修改

引用 10 楼 cfjtaishan 的回复:[quote=引用 4 楼 u010647109 的回复:] [quote=引用 1 楼 starytx 的回复:] dest指向的目标字符串，如果不重新定义一个指针的话，这个会在循环中移动到末尾，return 就有问题了。所以需要保留目标字符串首地址 src呢？为什么也要重新赋值，它并不return啊[/quote] 这个可以不做重新赋值，但是也是考虑不改变src的内容和位置。以便于调用之后不改变实参src[/quote]   src定义的也是const char *src，不过看大家都认为它重定义可有可无，那好吧。

引用 8 楼 u010808402 的回复:既然dest知道我就不解释了，src请注意前面你的 const修饰符，意在使其成为const指针，避免对其内容做出修改。 锦上添花，在较长函数或代码串中较有优势，不加也不影响，就是使用过程中要更加小心。  src定义的也是const char *src，不过看大家都认为它重定义可有可无，那好吧。

引用 2 楼 cfjtaishan 的回复:在循环过程中，修改的是pdest和psrc，这样src和dest都还指向两个串的首地址，所以return和dest得到的都是新串的首地址，否则用dest和src做循环，返回的就是目标串的某位。 最后一个小问题，最后一个*pdest = '';需要改一下，改成如下才对。 *pdest = 0; /* 0 is equal '\0' */   其实dest我知道，但是src这个一直没想明白，也许是一直编程习惯，但是既然是好的编程习惯那肯定是有原因的

引用 5 楼 SXJIAKE 的回复:没说一定要，这代码自己应该看的懂，也应该自己会改。比如改成这样：char *my_strcpy(char *dest, const char *src) {     char *ret = dest;     while (*src != '\0')     {         *dest++ = *src++;     }     *dest = '\0';     return ret; }   其实dest我知道，但是src这个一直没想明白，也许是一直编程习惯，但是既然是好的编程习惯那肯定是有原因的

引用 1 楼 starytx 的回复:dest指向的目标字符串，如果不重新定义一个指针的话，这个会在循环中移动到末尾，return 就有问题了。所以需要保留目标字符串首地址 src呢？为什么也要重新赋值，它并不return啊

楼上版主说的对，如果不需要返回地址的话可以不重新赋值


Question: DHT11温湿度测量送LCD1602显示，从STC89C51移植到STC12C5A60S2就用不起了怎么解决？

我是个小白，对我来说，太难了

引用 1 楼 user-4 的回复:这两个速度有差异吧，跟延时有关的地方需要调整一下 对啊 89C是12T的51 12C5A60是1T的。 楼主，检查一下和指令执行时间有关的代码

用一个空闲管脚，使用示波器测量，修改函数中的循环值，  先把 Delay 和 Delay1 调准了  比如 sbit DbgP = P3^1;  while(1) {    DbgP = 0;   Delay(10);  //10ms    DbgP = 1;   Delay1(); //xxx ms }

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

延时部分已做处理，还是没有用，不知道是不是ISP,IPA那部分的地址不对，因为原程序是用的STC89C52部分的ISP,IPA的地址。

这两个速度有差异吧，跟延时有关的地方需要调整一下


Question: 求大神解决 no appropriate default constructor available

Readarg *RA=new Readarg[1]; 改成 Readarg *RA = (Readarg *)malloc(sizeof(Readarg) * 1); Writearg *WA=new Writearg[2]; 改成 Writearg *WA = (Writearg *)malloc(sizeof(Writearg) * 2);  或者，添加两个struct的构造函数


Question: c语言小白，一道作业题，不知道哪错了

最后的max错了，if要{把三个赋值语句括起来}

不知道怎么传参数，就简单点按照你的逻辑定义个全局变量，   float score[M][N];

#include <stdio.h>   #define M 2 #define N 5  void input(float (*score)[N]); void aver(float (*score)[N]); void class_aver(float (*score)[N]); void max(float (*score)[N]);  int  main() {     float score[M][N];     input(score);     aver(score);     class_aver(score);     max(score); }  void input(float (*score)[N]) {          int i,j;     printf("请输入成绩:\n");     for(i=0;i<M;i++)     {         for(j=0;j<N;j++)         {          scanf("%f", &score[i][j]);         }     } }  void aver(float (*score)[N]) {        float a[M];     int i,j;     float sum=0;     printf("学生平均成绩:\n");     for(i=0;i<M;i++)     {            for(j=0;j<N;j++)         {             sum=sum+score[M][N];                      }         a[i]=sum/M;         printf("学号:%d,平均成绩:%f\n",i+1,a[i]);     } }  void class_aver(float (*score)[N]) {        float b[N];     int i,j;     float sum = 0;     printf("每门课的平均成绩:\n");     for(j=0;j<N;j++)     {         for(i=0;i<M;i++)         {             sum=sum+score[M][N];                      }             b[j]=sum/N;             printf("学科号:%d,平均成绩:%f\n",j+1,b[j]);     } }  void max(float (*score)[N]) {     int i,j,g,h;     float max;     printf("最高分及对应的学生和科目:\n");     max=score[0][0];     {         for(i=0;i<M;i++)         for(j=0;j<N;j++)             if(max<score[i][j])              max=score[i][j];         g=i;         h=j;     }     printf("最高分:%f,学号:%d,学科号:%d\n",max,g+1,h+1); }  试一下这个代码；

传参啊！否则数据穿不进去的

这个是我写的一小段代码，你可以参考着改一下，因为你们还没有学到指针，所以我的代码里面也没有出现指针  这是运行结果截图：    这是代码：  #include<stdio.h>  float aver(float,float,float,float,float);//传入学生的5科成绩  int main() { 	float score[5]={0}; 	int i;  	printf("请输入该学生的5科成绩：\n"); 	for(i=0;i<5;i++)           scanf("%f",&score[i]);  	//传入5科成绩,并打印结果 	printf("平均成绩为：%f\n",aver(score[0],score[1],score[2],score[3],score[4]));  	return 0; }   float aver(float score1,float score2,float score3,float score4,float score5) { 	float avr=(score1+score2+score3+score4+score5)/5.0; 	return avr; }

引用 3 楼 qq_38681484 的回复:[quote=引用 1 楼 user-7的回复:]定义的是局部变量，没用指针，也没有传值，其他函数是访问不到的 我们还没有学习指针，刚开始学调用函数[/quote]  你发的那个没有传数据进去

引用 3 楼 qq_38681484 的回复:[quote=引用 1 楼 user-7的回复:]定义的是局部变量，没用指针，也没有传值，其他函数是访问不到的 我们还没有学习指针，刚开始学调用函数[/quote]  那你也要把数值传入到函数中，这样那个函数才可以对数据进行操作的

引用 2 楼 user-7 的回复:把题目顺便发一下吧

引用 1 楼 user-7的回复:定义的是局部变量，没用指针，也没有传值，其他函数是访问不到的 我们还没有学习指针，刚开始学调用函数

把题目顺便发一下吧

定义的是局部变量，没用指针，也没有传值，其他函数是访问不到的


Question: 哈夫曼树编码C语言实现 程序有错误 求解

百度搜“C源代码 huffman编码”

主要是先了解哈夫曼编码的原理，建议先从网上学习一下～


Question: 大家帮忙看看这道面试题，怎么实现比较好？

我上面的排序是从小到大的排序，输出的时候可以考虑从最后一个输出。

#include <stdio.h> #include <stdlib.h>  typedef struct node {     int num;     int cnt; }num_node;  static int cmp_as_num(const void *a, const void *b) {     return (((num_node *)a)->num - ((num_node *)b)->num); }  static int cmp_as_cnt(const void *a, const void *b) {     return (((num_node *)a)->cnt - ((num_node *)b)->cnt); }  num_node *new_space(num_node *p, int num) {     p = (num_node *)realloc(p, num * sizeof(num_node));     if (!p) {         fprintf(stderr, "malloc error!\n");         exit(-1);     }      return p; }  void show_nums(num_node *p, int num) {     int i;      for (i = 0; i < num; i++)         printf("%d : %d (times)\n", p[i].num, p[i].cnt); }  int init_num_nodes(num_node **p, int *arr, int arr_len) {     int i, j, cnt = 0;     num_node *pnum = NULL;     pnum = new_space(pnum, 1);     pnum->num = arr[0];     pnum->cnt = 1;     cnt = 1;      for (i = 1; i < arr_len; i++) {         for (j = 0; j < cnt; j++) {             if (pnum[j].num == arr[i]) {                 pnum[j].cnt++;                 break;             }         }         if (j >= cnt) {             pnum = new_space(pnum, cnt + 1);             pnum[j].num = arr[i];             pnum[j].cnt = 1;             cnt++;         }     }     *p = pnum;      return cnt; }  int main(void) {     int arr[] = { 1, 3, 2, 5, 9, 0, 7, 2, 2, 4, 6, 5, 1, 6};     int len = sizeof(arr) / sizeof(arr[0]);     num_node *pnum = NULL;     int num_cnt = 0;      num_cnt = init_num_nodes(&pnum, arr, len);     show_nums(pnum, num_cnt);      qsort(pnum, num_cnt, sizeof(num_node), cmp_as_num);     qsort(pnum, num_cnt, sizeof(num_node), cmp_as_cnt);     printf("\nAfter sort: \n");     show_nums(pnum, num_cnt);      return 0; } 参考一下吧～

#include <stdio.h> #include <stdlib.h> void sort(int a[],int n) { 	int i,j,tmp; 	for(i=0;i<n-1;i++) 		for(j=0;j<n-i-1;j++) 		{ 			if(a[j]<a[j+1]) 			{ 				tmp=a[j]; 				a[j]=a[j+1]; 				a[j+1]=tmp; 			} 		} } void show(int a[],int n) { 	int i; 	for(i=0;i<n;i++) 		printf("%d  ",a[i]); } void tongji(int a[],int n,int b[][10]) { 	int i,tmp=a[0],c=1; 	for(i=1;i<n;i++) 	{ 		if(tmp==a[i]) 			c++; 		else 		{ 			b[c][tmp]=1; 			printf("%d:%d ",tmp,c); 			tmp=a[i]; 			c=1; 		} 	} } void show2(int b[][10]) { 	int i,j; 	for(i=9;i>=0;i--) 		for(j=9;j>=0;j--) 		{ 			if(b[i][j]==1)printf("%d:%d\n",j,i); 		} } void main() { 	int b[10][10]={0}; 	int a[]={1,3,2,5,9,0,7,2,2,4,6,5,1,6}; 	int len=sizeof(a)/sizeof(*a); 	sort(a,len); 	show(a,len); 	printf("\n"); 	tongji(a,len,b); 	printf("\n"); 	show2(b); 	system("pause"); }

一个0~9的计数排序呀 很简单吧

#include <stdio.h> #include <stdlib.h>   void swap(int *a,int *b){     int temp = *a;     *a = *b;     *b = temp; }   typedef struct SortVal{     int value;     int count;     struct SortVal *next; }SortValue;   SortValue *head = NULL;   SortValue *newValue(int value,int count) {     SortValue *ret = (SortValue*)malloc(sizeof(SortValue));     ret->value = value;     ret->count = count;     ret->next = NULL;     return ret; }   void pushSortValue(int value,int count) {//插入排序     if (head == NULL){         head = newValue(value,count);     }     else if (count > head->count){         SortValue *next = head;         head = newValue(value,count);         head->next = next;     }     else {         SortValue *cur = head;         while(cur->next != NULL && count <= cur->next->count){             cur=cur->next;         }          SortValue *next = cur->next;         cur->next = newValue(value,count);         cur->next->next = next;     } }   int main(void) {      int a[] = {1,3,2,5,9,0,7,2,2,4,6,5,1,6};     int i,j;     int length = sizeof(a)/sizeof(int);     int valueCount = 0;     for(i=0;i<length;i++){//选择排序         int maxIndex = i;         for(j=i+1;j<length;j++){             if(a[j] > a[maxIndex]){                 maxIndex = j;             }            }         if (maxIndex != i){             swap(&a[maxIndex],&a[i]);         }         if (i!=0 && a[i] != a[i-1]){             pushSortValue(a[i-1], valueCount);             valueCount = 1;         }         else {             valueCount++;         }         if(i == length - 1){ //刚才有bug 补上             pushSortValue(a[i],valueCount);         }     }           while (head!=NULL){         printf("%d:%d\n",head->value,head->count);         head = head->next;     }     return 0; }

#include <stdio.h> #include <stdlib.h>  void swap(int *a,int *b){     int temp = *a;     *a = *b;     *b = temp; }  typedef struct SortVal{     int value;     int count;     struct SortVal *next; }SortValue;  SortValue *head = NULL;  SortValue *newValue(int value,int count) {     SortValue *ret = (SortValue*)malloc(sizeof(SortValue));     ret->value = value;     ret->count = count;     ret->next = NULL;     return ret; }  void pushSortValue(int value,int count) {//插入排序     if (head == NULL){         head = newValue(value,count);     }     else if (count > head->count){         SortValue *next = head;         head = newValue(value,count);         head->next = next;     }     else {         SortValue *cur = head;         while(cur->next != NULL && count <= cur->next->count){             cur=cur->next;         }          SortValue *next = cur->next;         cur->next = newValue(value,count);         cur->next->next = next;     } }  int main(void) {      int a[] = {1,3,2,5,9,0,7,2,2,4,6,5,1,6};     int i,j;     int length = sizeof(a)/sizeof(int);     int valueCount = 0;     for(i=0;i<length-1;i++){//选择排序         int maxIndex = i;         for(j=i+1;j<length;j++){             if(a[j] > a[maxIndex]){                 maxIndex = j;             }            }         if (maxIndex != i){             swap(&a[maxIndex],&a[i]);         }         if (i!=0 && a[i] != a[i-1]){             pushSortValue(a[i-1], valueCount);             valueCount = 1;         }         else {             valueCount++;         }     }          while (head!=NULL){         printf("%d:%d\n",head->value,head->count);         head = head->next;     } 	return 0; }

#include <stdio.h> #include <stdlib.h>  typedef struct node {     int num;     int cnt; }num_node;  static int cmp_as_num(const void *a, const void *b) {     return (((num_node *)b)->num - ((num_node *)a)->num); }  static int cmp_as_cnt(const void *a, const void *b) {     return (((num_node *)b)->cnt - ((num_node *)a)->cnt); }  num_node *new_space(num_node *p, int num) {     p = (num_node *)realloc(p, num * sizeof(num_node));     if (!p) {         fprintf(stderr, "malloc error!\n");         exit(-1);     }      return p; }  void show_nums(num_node *p, int num) {     int i;      for (i = 0; i < num; i++)         printf("%d : %d (times)\n", p[i].num, p[i].cnt); }  int init_num_nodes(num_node **p, int *arr, int arr_len) {     int i, j, cnt = 0;     num_node *pnum = NULL;     pnum = new_space(pnum, 1);     pnum->num = arr[0];     pnum->cnt = 1;     cnt = 1;      for (i = 1; i < arr_len; i++) {         for (j = 0; j < cnt; j++) {             if (pnum[j].num == arr[i]) {                 pnum[j].cnt++;                 break;             }         }         if (j >= cnt) {             pnum = new_space(pnum, cnt + 1);             pnum[j].num = arr[i];             pnum[j].cnt = 1;             cnt++;         }     }     *p = pnum;      return cnt; }  int main(void) {     int arr[] = { 1, 3, 2, 5, 9, 0, 7, 2, 2, 4, 6, 5, 1, 6};     int len = sizeof(arr) / sizeof(arr[0]);     num_node *pnum = NULL;     int num_cnt = 0;      num_cnt = init_num_nodes(&pnum, arr, len);     show_nums(pnum, num_cnt);      qsort(pnum, num_cnt, sizeof(num_node), cmp_as_num);     qsort(pnum, num_cnt, sizeof(num_node), cmp_as_cnt);     printf("\nAfter sort: \n");     show_nums(pnum, num_cnt);      return 0; } 改一下两个函数:cmp_as_num, cmp_as_cnt中a和b的位置即可实现从大到小排序，注意两个程序的差异


Question: c语言小问题

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

对于c语言的问题我也不是很懂，也在通过写博客的方式提高自己，欢迎你来参观https://www.cnblogs.com/zhanqingheng

这个题存在隐式类型转换   当无符号与有符号相同类型比较时，会自动转换成无符号类型，  当不同类型进行比较时，会自动转换成较大字节的类型，防止内存数据丢失

同意2楼，顺便关注了。哈哈

这个题目主要考察数据类型的范围和类型转换。 a+b表达式的值计算，编译器首先将b的类型转换成unsigned int，这是隐饰类型转换，因为unsigned int  表示范围大于int所以，向较大范围的类型转换。自然将-10转换成unsigned int，值肯定是一个很大的值，再加上10，自然是大于0的

(a+b>0?printf("a+b=%d\n",a+b):printf("a=%d b=%d\n",a,b)); 相当于 if(a+b>0)printf("a+b=%d\n",a+b); else printf("a=%d b=%d\n",a,b);


Question: 关于http响应的问题

不知道你是怎么写到文件里的。


Question: 求问C语言学习阅读开源项目时遇到的问题.

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

本代码段是一些跨编译器的配置，结合 SourceInsight 工具能提高效率，然后就是多查多在纸上画。  引用 楼主 u013467105 的回复:因为工作需要,会阅读开源项目snort.一个IPS项目.很多时候会看到一些这样的代码:     有些跟本没办法去看懂.好多语法原来学习C语言时也没有学到过.我想问一下有没有专门介绍这种开源项目,当中括glibc特性,GCC编译器特性,一些C的高级用法的书籍呢?大家在碰到这种问题的时候一般是怎么去看懂这些代码的啊?

大部分是宏，条件编译时会用到。这些C语言课程里也是有讲的，比如定义头文件。开头就需要判断文件宏是否已定义。 建议专门看一下宏，条件编译类似#ifdef #ifndef， #else #endif等等这些。 其他，比如__attribute__建议网上查一下，这个我们平时编程可能用的比较少，包括上面的宏，所以可以专门详细了解一下

去网上搜下宏指令学习下，这没什么难的，不要一开始就被吓到


Question: c语言二级链表问题

我知道我第一个struct后面少了个分号；但是并没有解决问题


Question: c语言作业，程序总是向文件输出一堆烫，新手求解！！

烫烫更健康！

在使用之前进行初始化是个良好的编程习惯。

#include<stdio.h> #include<string.h> #include<stdlib.h> #include<conio.h> #include<windows.h>  struct Book {     int num; //图书编号     char aut[50]; //作者     float price; //图书价格     char pub[50]; //出版商     char name[50]; //书名     int kc; //库存 }; void jieshu();  //借阅 void jskc(Book b);  void jieshu() {     struct Book b;     int s;     int w;     char sr[50];     printf("请输入要借阅的书籍（格式：《-书名-》）：\n");     scanf("%s", sr); /* remove '&' */     FILE*fp;     fp=fopen("allbook.txt","r");     fscanf(fp,"%d%s%s%s%f%d",&b.num, b.name, b.aut, b.pub, &b.price,&b.kc);     if(strcmp(sr,b.name)==0&&b.kc!=0)     {         printf("是否借阅（1.YES \ 2.NO）");         scanf("%d", &s);         switch(s)         {             case 1:                 jskc(b);                 printf("借阅成功！\n");                 break;             case 2:                 ex();         }     }     else     {         printf("无法借阅！该图书可能不存在或库存不足！\n");         printf("是否需要查询？(1.yes \ 2.no)\n");         scanf("%d",&w);         switch(w)         {             case 1:                 findbook();             case 2:                 ex();         }     }     fclose(fp); } void jskc(Book b) {     FILE*fp;     Book c[1010];     int i,j;     i = 0;     fp=fopen("allbook.txt","r");     while(fscanf(fp,"%d%s%s%s%f%d", &c[i].num, c[i].name, c[i].aut, c[i].pub,&c[i].price,&c[i].kc)!=EOF)    /* remove '&' */         i++;     fclose(fp);     fp = fopen("allbook.txt","w");     for(j = 0;j<i;j++)     {         if(b.num ==c[i].num&&b.name == c[i].name&&b.aut == c[i].aut&&b.pub == c[i].pub&&b.price == c[i].price&&b.kc == c[i].kc)         {             fprintf(fp,"%d  %s  %s  %s  %f  %d\n",b.num,b.name,b.aut,b.pub,b.price,b.kc-1);         }         else             fprintf(fp,"%d  %s  %s  %s  %f  %d\n",c[i].num,c[i].name,c[i].aut,c[i].pub,c[i].price,c[i].kc);     }      fclose(fp); } 出现特殊字符，主要是字符串没有找到结束标记，注意你的输入是否导致了字符串越界。 scanf和fscanf有写输入不需要加&的，因为数组名本身就是地址。建议对比一下，那些是不需要&的。 最后，建议注意下代码风格：比如 fprintf(fp, "%d  %s  %s  %s  %f  %d\n", c[i].num, c[i].name, c[i].aut, c[i].pub, c[i].price, c[i].kc); 加空格，让代码读起来更方便。

请仔细检查scanf，fscanf，sscanf函数的返回值！

任何字符串或者结构在使用之前建议初始化,

这种情况就是你的程序输出文件的时候要输出的字符串没有初始化过，但分配了内存。你自己看看哪里出了问题（注意所有字符串数组，调试一下看哪个字符串数组都是“烫”）

每次基本上涉及到字符串指针的内容时，一般新手都容易有些错误（我也是）  【转】C++常识“屯”和“烫” VC++中，在Debug模式下，会把未初始化的栈内存全部填成0xCC（204）。会把未初始化的堆内存全部填成0xCD（205）。但是Release模式下不会有这种动作，原来那块内存里是什么就是什么（Debug模式下这样干是为了让程序员知道是否被初始化）。0xCC和0xCD都超过了ASCII码0-127这个范围，因此它就被系统当成了宽字符组成的字符串，即两个字节数据组成一个字符，而0xCCCC表示的宽字符正好是“烫”字。同理，0xCDCD就是“屯”字。  这下明白了吗？（我以前也很不解）如果你在VC中选择Release模式就不会出现这种情况了（但是如果操作这个栈内存或堆内存有可能会崩溃） 如果还不明白的话可以加我QQ3300469945


Question: 如何用C语言分别实现SJF和HRRF这两种作业调度算法

百度搜相关关键字。


Question: 素数的求和方式

第三种 在循环外面k＝sqrt（n） i＜＝k  应该对算法有点优化吧

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

引用 3 楼 cfjtaishan 的回复:[quote=引用 2 楼 cyfcsd 的回复:] 把最后那个的开方写到循环外面，不要每次都做开方运算，时间会更快一些 这个编译器会优化吧？！ [/quote] 我没做实验，但编译器对函数调用优化比较难吧，因为很难确定函数有没有改变其他内容，比如改变了n值或者i值

引用 2 楼 cyfcsd 的回复:把最后那个的开方写到循环外面，不要每次都做开方运算，时间会更快一些 这个编译器会优化吧？！

把最后那个的开方写到循环外面，不要每次都做开方运算，时间会更快一些

从时间复杂度来讲三种方法的复杂度一次减少；所以第三种是判断素数的最优方法（3种方法里）


Question: 霍夫曼编码入门

引用 5 楼 qq_36790578 的回复:这个我用快速排序应该不会比这个时间多吧，为什么他过了，我TLE了 你用快速排序每次必须重排整个数组，单次操作nlogn，整体复杂度就n^2logn 而用堆只是操作两三个元素，并不碰其他无关的元素，单次操作O(logn)。 堆调节并不是对整个数组重新做堆排序。如果对整个数组做堆排序的话那和你的快排是一样慢的。

引用 5 楼 qq_36790578 的回复:[quote=引用 2 楼 cfjtaishan 的回复:] #include <stdio.h> #include <stdlib.h> #include <ctype.h>  int c;  int get() {     int num = 0;     while (isdigit(c = getchar())) {         num = num * 10 + c - '0';     }     return num; } int a[105];  void swap(int *a, int *b) {     int t = *a;     *a = *b;     *b = t; } int cmp(const void *a, const void *b) {     return *(int *)b - *(int *)a; } int main() {     int t,i,n,sum;     scanf("%d", &t);     while(t--) {         scanf("%d%*c",&n);         sum = 0;         for(i = 0; i < n; i++) {             printf("%d\n", a[i] = get());         }         qsort(a, n, sizeof(int), cmp);         while(--n){             a[n-1] += a[n];             sum += a[n-1];             for(i = n - 1; i > 0; i--){                 if(a[i]<a[i-1])                     break;                 else                     swap(a+i, a+i-1);             }         }         printf("sum = %d\n", sum);     }     return 0; } 只对程序评论，算法建议参考一下网上的。 程序而言，定义过大的数组，作为一个简单的测试程序，你的输入会超过10个吗？那么即使超过10个，那么你能输入100个吗？我估计不会，输入超过10个已经不错了。但是定义了100005，幸好定义了全局变量，不然定义成局部，这样会导致栈的损耗很大，因为栈的空间是有限的，很少的。建议使用大数组，在堆上申请（全局也可以的）。 其他没发现啥问题。 建议c定义成int类型，当然你的使用没啥问题，因为不是和EOF比较。 这个网上就找到一个用堆排序过得 这个我用快速排序应该不会比这个时间多吧，为什么他过了，我TLE了 至于不用scanf（“%d”，&n）只是因为之前做过一道用scanf超时的，用字符才能规定时间内完成，就get（）了， [/quote] 你说的超时是那个超时？如果有输入，除非提前写好输入，否则有输入就很容易超时

引用 1 楼 zhao4zhong1 的回复:百度搜“huffman编码” 这个真搜不到 定义已经看了很多了 这道题目一样的只看到一个有用的，看了还是不明白

引用 2 楼 cfjtaishan 的回复:#include <stdio.h> #include <stdlib.h> #include <ctype.h>  int c;  int get() {     int num = 0;     while (isdigit(c = getchar())) {         num = num * 10 + c - '0';     }     return num; } int a[105];  void swap(int *a, int *b) {     int t = *a;     *a = *b;     *b = t; } int cmp(const void *a, const void *b) {     return *(int *)b - *(int *)a; } int main() {     int t,i,n,sum;     scanf("%d", &t);     while(t--) {         scanf("%d%*c",&n);         sum = 0;         for(i = 0; i < n; i++) {             printf("%d\n", a[i] = get());         }         qsort(a, n, sizeof(int), cmp);         while(--n){             a[n-1] += a[n];             sum += a[n-1];             for(i = n - 1; i > 0; i--){                 if(a[i]<a[i-1])                     break;                 else                     swap(a+i, a+i-1);             }         }         printf("sum = %d\n", sum);     }     return 0; } 只对程序评论，算法建议参考一下网上的。 程序而言，定义过大的数组，作为一个简单的测试程序，你的输入会超过10个吗？那么即使超过10个，那么你能输入100个吗？我估计不会，输入超过10个已经不错了。但是定义了100005，幸好定义了全局变量，不然定义成局部，这样会导致栈的损耗很大，因为栈的空间是有限的，很少的。建议使用大数组，在堆上申请（全局也可以的）。 其他没发现啥问题。 建议c定义成int类型，当然你的使用没啥问题，因为不是和EOF比较。 这个网上就找到一个用堆排序过得 这个我用快速排序应该不会比这个时间多吧，为什么他过了，我TLE了 至于不用scanf（“%d”，&n）只是因为之前做过一道用scanf超时的，用字符才能规定时间内完成，就get（）了，

引用 3 楼 FancyMouse 的回复:50000个1和50000个50001估计就TLE了 这个为什么就不超时了 #include <iostream>   #include <ctime>   using namespace std;      int a[100002];      void swap(int& a, int& b)   {       int temp = a;       a = b;       b = temp;   }      void heapAdjust(int h[], int s, int m)   {       int rc = h[s];       int j;       for(j = 2 *s; j <= m; j *= 2)       {           if(j < m && h[j + 1] < h[j])           {               j ++;           }           if(rc <= h[j])           {               break;           }           h[s] = h[j];           s = j;       }       h[s] = rc;   }      int calc_huff(int h[], int n)   {       int i;       for(i = n / 2; i > 0; i --)       {           heapAdjust(h, i, n);       }       i = n;       int sum = 0;       while(i > 1)       {           swap(h[1], h[i]);           heapAdjust(h, 1, i - 1);           i --;           swap(h[1], h[i]);           heapAdjust(h, 1, i - 1);           sum = sum + h[i] + h[i + 1];           h[i] = h[i] + h[i + 1];       }       return sum;   }      int main()   {       int t;       cin >> t;       while(t --)       {           int n;           cin >> n;           int i;           for(i = 1; i <= n; i ++)           {               cin >> a[i];           }           cout << calc_huff(a, n) << '\n';       }       return 0;   }   堆排序怎么就来的及了 快速排序就算加上引用时间也就不过15ms罢了，不会增加多少的吧

百度搜“huffman编码”


Question: c的平方函数,10的2次方为“99”是怎么回事

666酱油党路过

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

引用 3楼宋寒松 的回复: pow() 函数用来求 x 的 y 次幂（次方），其原型为：     double pow(double x, double y);  pow()用来计算以x 为底的 y 次方值，然后将结果返回。设返回值为 ret，则 ret = xy。  可能导致错误的情况： 如果底数 x 为负数并且指数 y 不是整数，将会导致 domain error 错误。 如果底数 x 和指数 y 都是 0，可能会导致 domain error 错误，也可能没有；这跟库的实现有关。 如果底数 x 是 0，指数 y 是负数，可能会导致 domain error 或 pole error 错误，也可能没有；这跟库的实现有关。 如果返回值 ret 太大或者太小，将会导致 range error 错误。  错误代码： 如果发生 domain error 错误，那么全局变量 errno 将被设置为  EDOM； 如果发生 pole error 或 range error 错误，那么全局变量 errno 将被设置为 ERANGE。   浮点数有误差很正常的。  引用 楼主 a15615667061 的回复:恩 明白了 谢谢

引用 1楼幻夢之葉 的回复:pow 参数接收和返回的是浮点数？  b = pow(10, 2) + 1e-6;好吧 谢谢


Question: c语言程序小问题

printf函数参数的压栈顺序是从右向左压栈，那么最右边的参数表达式先计算，所以c = c * 2;并且将计算结果放入的c，所以c的值已经发生了改变。

#include〈stdio.h〉 int main（） 〔      int a=10，b=20，c=30；      c=c*2；       b=b*c；        a=a+b+c；          printf（“%d  %d＼n，b，c”）；           printf（“%d＼n”，a）；             return 0； 〕

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

先算c=c*2 得到60，再算b=b*c得到1200 然后a+b+c=10+1200+60=1270,最后printf返回打印的字符个数“1270”是4个所以最后输出了4

谢谢楼上！！没有什么想装一下啦，只是在做题的时候碰到了不能理解，感谢感谢

参数从右开始往左计算，所以计算的步骤如下： c=c*2 b=b*c a+b+c  printf("%d\n",printf("%d",a+b+c)); 这一行先打打印a+b+c的值为1270，它的长度是4个字节，所以又打印出一个4，由于1270没有换行，所这个4和前面的1270连在一起  建议楼主在开始学习的时候不要弄这么"高深"的写法，最好是按照步骤拆开来写，步骤清晰，错误也好查。如果一开始就把精力放到所谓的“技巧”上面，就算弄清楚了，偶尔可以在他人面前装一下，也没有实际意义


Question: 有关一个全排列（递归）的问题

楼主是个有志青年！

引用 3 楼 zhao4zhong1 的回复:再供参考：//全排列的生成算法 //  全排列的生成算法就是对于给定的字符集，用有效的方法将所有可能的全排列无重复无遗漏地枚举出来。任何n个字符集的排列都可以与1～n的n个数字的排列一一对应， //  因此在此就以n个数字的排列为例说明排列的生成法。 //  n个字符的全体排列之间存在一个确定的线性顺序关系。所有的排列中除最后一个排列外，都有一个后继；除第一个排列外，都有一个前驱。每个排列的后继都可以从 //  它的前驱经过最少的变化而得到，全排列的生成算法就是从第一个排列开始逐个生成所有的排列的方法。 //  全排列的生成法通常有以下几种： //  字典序法 //  递增进位数制法 //  递减进位数制法 //  邻位交换法 //  递归类算法 //1.字典序法 效率高且顺序自然 //  字典序法中，对于数字1、2、3......n的排列，不同排列的先后关系是从左到右逐个比较对应的数字的先后来决定的。例如对于5个数字的排列12354和12345，排列12345在前， //  排列12354在后。按照这样的规定，5个数字的所有的排列中最前面的是12345，最后面的是54321。 //  字典序算法如下： //  设P是1～n的一个全排列:p=p1p2......pn=p1p2......pj-1pjpj+1......pk-1pkpk+1......pn //  1）从排列的右端开始，找出第一个比右边数字小的数字的序号j（j从左端开始计算），即 j=max{i|pi<pi+1} //  2）在pj的右边的数字中，找出所有比pj大的数中最小的数字pk，即 k=max{i|pi>pj}（右边的数从右至左是递增的，因此k是所有大于pj的数字中序号最大者） //  3）对换pi，pk //  4）再将pj+1......pk-1pkpk+1pn倒转得到排列p’’=p1p2.....pj-1pjpn.....pk+1pkpk-1.....pj+1，这就是排列p的下一个下一个排列。 //  例如839647521是数字1～9的一个排列。从它生成下一个排列的步骤如下： //  自右至左找出排列中第一个比右边数字小的数字4 839647521 //  在该数字后的数字中找出比4大的数中最小的一个5 839647521 //  将5与4交换 839657421 //  将7421倒转 839651247 //  所以839647521的下一个排列是839651247。 //2.递增进位数制法 //  在递增进位制数法中，从一个排列求另一个排列需要用到中介数。如果用 ki表示排列p1p2...pi...pn中元素pi的右边比pi小的数的个数，则排列的中介数就是对应的 //  排列k1 ...... ki...... kn-1。 //  例如排列839647521的中介数是72642321，7、2、6、......分别是排列中数字8、3、9、......的右边比它小的数字个数。 //  中介数是计算排列的中间环节。已知一个排列，要求下一个排列，首先确定其中介数，一个排列的后继，其中介数是原排列中介数加1，需要注意的是，如果中介数的 //  末位kn-1+1=2，则要向前进位，一般情形，如果ki+1=n-i+1，则要进位，这就是所谓的递增进位制。例如排列839647521的中介数是72642321，则下一个排列的中介数 //  是67342221+1=67342300（因为1+1=2，所以向前进位，2+1=3，又发生进位，所以下一个中介数是67342300）。 //  得到中介数后，可根据它还原对应得排列。 //  算法如下： //  中介数k1、k2、......、kn-1的各位数字顺序表示排列中的数字n、n-1、......、2在排列中距右端的的空位数，因此，要按k1、k2、......、kn-1的值从右向左 //  确定n、n-1、......、2的位置，并逐个放置在排列中：i放在右起的ki+1位，如果某位已放有数字，则该位置不算在内，最后一个空位放1。 //  因此从67342300可得到排列849617523，它就是839647521的后一个排列。因为9最先放置，k1=6，9放在右起第7位，空出6个空位，然后是放8，k2=7，8放在右起第8位， //  但9占用一位，故8应放在右起第9位，余类推。 //3.递减进位制数法 //  在递增进位制数法中，中介数的最低位是逢2进1，进位频繁，这是一个缺点。把递增进位制数翻转,就得到递减进位制数。 //  839647521的中介数是67342221(k1k2...kn-1)，倒转成为12224376(kn-1...k2k1)，这是递减进位制数的中介数：ki(i=n-1,n-2,...,2)位逢i向ki-1位进1。给定排列p， //  p的下一个排列的中介数定义为p的中介数加1。例如p=839647521，p的中介数为12224376，p的下一个排列的中介数为12224376+1=12224377，由此得到p的下一个 //  排列为893647521。 //  给定中介数，可用与递增进位制数法类似的方法还原出排列。但在递减进位制数中，可以不先计算中介数就直接从一个排列求出下一个排列。具体算法如下： //  1）如果p(i)=n且i<>n，则p(i)与p(i-1)交换 //  2）如果p(n)=n，则找出一个连续递减序列9、8、......、i，将其从排列左端删除，再以相反顺序加在排列右端，然后将i-1与左边的数字交换 //  例如p=893647521的下一个排列是983647521。求983647521的下一个排列时，因为9在最左边且第2位为8，第3位不是7，所以将8和9从小到大排于最右端364752189， //  再将7与其左方数字对调得到983647521的下一个排列是367452189。又例如求987635421的下一个排列，只需要将9876从小到大排到最右端并将5与其左方数字3对调， //  得到534216789。 //4.邻位对换法 效率最高但顺序不自然 //  邻位对换法中下一个排列总是上一个排列某相邻两位对换得到的。以4个元素的排列为例，将最后的元素4逐次与前面的元素交换，可以生成4个新排列： //  1 2 3 4, 1 2 4 3, 1 4 2 3, 4 1 2 3 //  然后将最后一个排列的末尾的两个元素交换，再逐次将排头的4与其后的元素交换，又生成四个新排列： //  4 1 3 2, 1 4 3 2, 1 3 4 2, 1 3 2 4 //  再将最后一个排列的开头的两个元素交换，将4从后往前移： //  3 1 2 4, 3 1 4 2, 3 4 1 2, 4 3 1 2 //  如此循环4!次既可求出全部排列。 //5.元素增值法（n进制法）效率低 //  1）从原始排列p=p1p2......pn开始，第n位加n-1，如果该位的值超过n，则将它除以n，用余数取代该位，并进位（将第n-1位加1） //  2）再按同样方法处理n-1位，n-2位，......，直至不再发生进位为止，处理完一个排列就产生了一个新的排列 //  3）将其中有相同元素的排列去掉 //  4）当第一个元素的值>n则结束 //  以3个数1、2、3的排列为例：原始排列是1 2 3，从它开始，第3个元素是3，3+2=5，5 Mod 3=2，第2个元素是2，2+1=3，所以新排列是1 3 2。通过元素增值，顺序产生的 //  排列是：1 2 3，1 3 2，2 1 1，2 1 3，2 2 2，2 3 1，2 3 3，3 1 2，3 2 1 //  有下划线的排列中存在重复元素，丢弃，余下的就是全部排列。 //6.递归类算法 //  全排列的生成方法用递归方式描述比较简洁，实现的方法也有多种。 //  1）回溯法 //  回溯法通常是构造一颗生成树。以3个元素为例；树的节点有个数据，可取值是1、2、3。如果某个为0，则表示尚未取值。 //  初始状态是(0，0，0)，第1个元素值可以分别挑选1，2，3，因此扩展出3个子结点。用相同方法找出这些结点的第2个元素的可能值，如此反复进行，一旦出现新结点的3个 //  数据全非零，那就找到了一种全排列方案。当尝试了所有可能方案，即获得了问题的解答。 //  2）递归算法 //  如果用P表示n个元素的排列，而Pi表示不包含元素i的排列，(i)Pi表示在排列Pi前加上前缀i的排列，那么，n个元素的排列可递归定义为： //  如果n=1，则排列P只有一个元素i //  如果n>1，则排列P由排列(i)Pi构成（i=1、2、....、n-1）。 //  根据定义，容易看出如果已经生成了k-1个元素的排列，那么，k个元素的排列可以在每个k-1个元素的排列Pi前添加元素i而生成。例如2个元素的排列是1 2和2 1，对与个 //  元素而言，p1是2 3和3 2，在每个排列前加上1即生成1 2 3和1 3 2两个新排列，p2和p3则是1 3、3 1和1 2、2 1，按同样方法可生成新排列2 1 3、2 3 1和3 1 2、3 2 1。 //  3）循环移位法 //  如果已经生成了k-1个元素的排列，则在每个排列后添加元素k使之成为k个元素的排列，然后将每个排列循环左移（右移），每移动一次就产生一个新的排列。 //  例如2个元素的排列是1 2和2 1。在1 2 后加上3成为新排列1 2 3，将它循环左移可再生成新排列2 3 1、3 1 2，同样2 1 可生成新排列2 1 3、1 3 2和3 2 1。   谢谢讲解，很详细，准备将每种方法都做一遍。

“给定一个小点的输入，完整单步跟踪(同时按Alt+7键查看Call Stack里面从上到下列出的对应从里层到外层的函数调用历史)一遍。”是理解递归函数工作原理的不二法门！ 递归函数关注以下几个因素 ·退出条件 ·参数有哪些 ·返回值是什么 ·局部变量有哪些 ·全局变量有哪些 ·何时输出 ·会不会导致堆栈溢出  仅供参考：//qplw.cpp #include <stdio.h> #include <string.h> #include <stdlib.h> int v=0; int w=0; int m;//记录字符串长度 int n;//记录字符串中的字符种类数 char map[256];//记录是哪几种字符 int count[256];//记录每种字符有多少个 int stack[1000];//递归用的栈，并记录当前生成的排列 void Make_Map(char *str) {//统计字符串的相关信息     int s[256];     int i;     memset(s,0,sizeof(s));     memset(count,0,sizeof(count));     m=strlen(str);     if (w<1 || m<w) w=m;     while(*str) {         s[*str]++;         str++;     }     n=0;     for (i=0;i<256;i++)         if (s[i]) {             map[n]=i;             count[n]=s[i];             n++;         } } void Find(int depth) {//递归式回溯法生成全排列     if (depth==w) {         int i;         for (i=0;i<depth;i++) putchar(map[stack[i]]);         putchar('\n');     } else {         int i;         if (v && depth>0) {             for (i=0;i<depth;i++) putchar(map[stack[i]]);             putchar('\n');         }         for (i=0;i<n;i++)             if (count[i]) {                 stack[depth]=i;                 count[i]--;                 Find(depth+1);                 count[i]++;             }     } } void main(int argc,char**argv) {     if (argc<2) {         printf("%s 要产生全排列的字符串 [限定长度|-1]\n",argv[0]);         return;     }     if (argc>=3) w=atoi(argv[2]);     if (-1==w) v=1;     Make_Map(argv[1]);     Find(0); } //C:\test>qplw //qplw 要产生全排列的字符串 [限定长度|-1] // //C:\test>qplw 123 //123 //132 //213 //231 //312 //321 // //C:\test>qplw 123 2 //12 //13 //21 //23 //31 //32 // //C:\test>qplw 122333 3 //122 //123 //132 //133 //212 //213 //221 //223 //231 //232 //233 //312 //313 //321 //322 //323 //331 //332 //333 // //C:\test>qplw 123 -1 //1 //12 //123 //13 //132 //2 //21 //213 //23 //231 //3 //31 //312 //32 //321 //

这个思想就是把后面的元素和第i个逐次交换，然后产生后面的排列，递归刚开始都是这种似懂非懂的感觉，看的多了就习惯了，不要想太深太多了，否则容易陷进去反而用不好递归


Question: 基于winpcap的数据包捕获代码，运行时发生冲突

引用 7 楼 yuncaidaishu 的回复:找到问题了，如果用while循环就不会有问题，用for循环就会出问题，为什么 跟使用那种循环形式没关系，二者是可以互换的，但是需要改变条件；我觉得主要是判断条件和退出循环的条件导致的

参考 http://blog.csdn.net/u012866869/article/details/40361575

网卡设置为混杂模式了吗？ 要接受网卡过来的所有数据包，然后再分析

找到问题了，如果用while循环就不会有问题，用for循环就会出问题，为什么

还有一种可能就是越界，访问了非法空间会出错

有时成功，有时失败，可能跟程序有关系，程序还有问题。有可能是野指针导致的

表示一脸懵逼

关闭UAC、防火墙、杀毒软件、…… 以管理员身份运行 以XP兼容模式运行 ……  有时不将“调用函数名字＋各参数值，进入函数后各参数值，中间变量值，退出函数前准备返回的值，返回函数到调用处后函数名字＋各参数值＋返回值”这些信息写日志到文件中是无论如何也发现不了问题在哪里的，包括捕获各种异常、写日志到屏幕、单步或设断点或生成core或dmp文件、……这些方法都不行！ 写日志到文件参考下面： //循环向a函数每次发送200个字节长度（这个是固定的）的buffer, //a函数中需要将循环传进来的buffer，组成240字节（也是固定的）的新buffer进行处理， //在处理的时候每次从新buffer中取两个字节打印 #ifdef _MSC_VER     #pragma warning(disable:4996) #endif #include <stdio.h> #include <stdlib.h> #include <string.h> #ifdef _MSC_VER     #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 _MSC_VER 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,struct 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 _MSC_VER     pthread_exit(NULL); #endif } int PutToRBuf(int cn,CRITICAL_SECTION *cs,struct 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 _MSC_VER     pthread_exit(NULL); #endif } int main() { #ifdef _MSC_VER     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 _MSC_VER     _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 _MSC_VER     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: _read()函数的指针是怎么个情况？

fd是文件描述符，这个值是不变的，因为打开一个文件，就是给了一个文件描述符，跟其他文件的描述符不一样，这个是文件系统维护的一张表，fd可以看成标识这个文件的ID（详细的请查阅文件系统）。但是读文件是，对于文件的节点都会维护一个位置，即读取的位置，这个位置会随着读写过程中跟着变化。 buffer是读到的数据放到buffer里，buffer也不会跟着变化，它还是指向其首地址。

就c语言啊 额x86  按字节读，那放入的时候怎么放入 ？填满了int再往下一int放（4个字节放入一个int中） 还是说一个字节放入到低位再补满（一个字节放入一个int中），

引用 5 楼 a271256939 的回复:引用 4 楼 cfjtaishan 的回复:引用 3 楼 a271256939 的回复:如果说buffer是一个int 型(4个字节）指针，而read是按照一个字节一个字节读的那么在buffer里的存储是如何的/？这个要根据系统是大端还是小端了，比如一次存入4个字节00, 00, 00, 01（16进制），如果是小端系统，那么是该int值是0x10000000，如果是大端系统，那么是0x00000001我的意思是 读入四个字节放入int  还是读一个字节放入int，int其他位填充 再读下一个字节放入下一个int read应该是按字节读的吧，你这个函数在什么场景下使用？

函数参数都是传值，所以不变。变的是由内核维护的文件的偏移量


Question: 求助！文件操作的bug，用fseek函数把txt数据导入数组之后，就不进行后面的操作了。

#include <stdio.h> #include <stdlib.h> #include<math.h> #include<time.h> #include <conio.h>  main (){ 	double**A; 	double**B; 	FILE *fp; 	FILE *op; 	int i,j; 	//double C[10];/*存放最佳匹配位置的数据*/ 	char ch; 	int row=0,column=0; 	int row1=0,column1=0; 	//打开文件 	if((fp=fopen("rf1_data.txt","r"))==NULL){ 		printf("打开文件失败！\n"); 		return 1; 	}  	while(!feof(fp)&&(ch=fgetc(fp))!='\n'){ 		if(ch=='	'){ 			column++; 		} 	} 	column++; 	if(column==1){ 	printf("没有数据！\n"); 	return 1; 	} 	printf("column=%d\n",column); 	fseek(fp,0L,0); 	while(!feof(fp)){ 		if(fgetc(fp)=='\n'){ 			row++;	 		} 	} 	row++; 	if(row==1){ 	printf("没有数据！\n"); 	return 1;	 	}  	printf("行数=%d\n",row); 	A=(double**)malloc(sizeof(int*)*row); 	if(A==NULL){ 		printf("no memory\n"); 		return 1; 	} 	for(i=0;i<row;i++) 	{ 		A[i]=(double*)malloc(sizeof(int)*column); 		if(A[i]==NULL) 	{ 	printf("no memory\n"); 	return 1; 	} 	} 	printf("内存分配完成成功1！\n"); 	fseek(fp,0L,SEEK_SET); 	//rewind(fp);	 	while(!feof(fp)){ 		for(i=0;i<row;i++){ 			for(j=0;j<column;j++){ 					fscanf(fp,"%Lf",&A[i][j]); 			} 		} 	} 	printf("读取数据成功1！\n"); 	printf("A=%.16lf\n",A[0][0]); 	printf("A=%.16lf\n",A[2][0]); 	system("Pause"); 	//printf("内存分配完成成功2！\n"); 	if((op=fopen("rf2_data.txt","r"))==NULL){ 		printf("打开文件失败！\n"); 		return 1; 	}  	printf("代码运行到这！\n"); 	while(!feof(op)&&(ch=fgetc(op))!='\n'){ 		if(ch=='	'){ 			column1++; 		} 	} 	column1++; 	if(column1==1){ 	printf("没有数据！\n"); 	return 1; 	} 	printf("column1=%d\n",column1); 	fseek(op,0L,0); 	while(!feof(op)){ 		if(fgetc(op)=='\n'){ 			row1++;	 		} 	} 	row1++; 	if(row1==1){ 	printf("没有数据！\n"); 	return 1;	 	}  	printf("行数1=%d\n",row1); 	B=(double**)malloc(sizeof(int*)*row1); 	if(B==NULL){ 		printf("no memory\n"); 		return 1; 	} 	for(i=0;i<row1;i++) 	{ 		B[i]=(double*)malloc(sizeof(int)*column1); 		if(B[i]==NULL) 	{ 	printf("no memory\n"); 	return 1; 	} 	} 	printf("内存分配完成成功2！\n"); 	fseek(op,0L,SEEK_SET);	 	while(!feof(op)){ 		for(i=0;i<row1;i++){ 			for(j=0;j<column1;j++){ 					fscanf(op,"%lf",&B[i][j]); 			} 		} 	} 	printf("B=%.16lf\n",B[0][0]); 	printf("读取数据成功2！\n"); 	 	//printf("关闭文件！\n"); 	system("Pause"); //关闭文件 printf("关闭文件！\n"); 	fclose(fp); 	//fclose(op); 	//释放内存 	for(i=0;i<row;i++){ 		free(A[i]); 		free(B[i]); 		//free(B[i]); 	} 	free(A); 	free(B); 	//free(B); 	return 0;  } 这是完整代码，我第一个运行到 A的值显示之后就直接结束了，是不是文件指针的问题啊

推荐使用WinHex软件查看硬盘或文件或内存中的原始字节内容。  不要把 fopen("...","...");fscanf,fprintf,fgets,fgetc,fclose //读时把\r\n替换成\n，写时把\n替换成\r\n;读到\x1a就设置EOF;读写的内容当字符看待 和 fopen("...","...b");fseek,ftell,fread,fwrite,fgetc,fclose //不作以上替换，遇到\x1a仍继续读;读写的内容当字节看待 弄混了

fseek做不到导入数组，它只负责更改文件指针的位置。 后面的操作是指什么操作。 建议，将问题描述更清晰一些，还有将完整代码贴出来，方便大家给你分析问题。

引用 6 楼 自信男孩的回复:[quote=引用 5 楼 weixin_38207316 的回复:] [quote=引用 4 楼 自信男孩的回复:] A=(double**)malloc(sizeof(int*)*row); A[i]=(double*)malloc(sizeof(int)*column); 改成：   A=(double**)malloc(sizeof(double*)*row); A[i]=(double*)malloc(sizeof(double)*column); 同理下面的B也需要更改。 第一个对A的申请行数，虽然指针的sizeof都是一样的，建议还要sizeof(double *)， 下面的申请A[i]就必须使用sizeof(double)了。同理B的申请一样。  #include <stdio.h> #include <stdlib.h> #include<math.h> #include<time.h> //#include <conio.h>  int main () {     double**A;     double**B;     FILE *fp;     FILE *op;     int i,j;     //double C[10];/*存放最佳匹配位置的数据*/     char ch;     int row = 0, column = 0;     int row1 = 0,column1 = 0;     //打开文件     if((fp=fopen("rf1_data.txt", "r"))==NULL){         printf("打开文件失败！\n");         return 1;     }     while(!feof(fp) && (ch = fgetc(fp)) != '\n') {         if(ch==' '){             column++;         }     }     column++;     if(column==1){         printf("没有数据！\n");         return 1;     }     printf("column=%d\n",column);     fseek(fp,0L,0);     while(!feof(fp)){         if(fgetc(fp)=='\n'){             row++;         }     }     row++;     if(row==1){         printf("没有数据！\n");         return 1;     }     printf("行数=%d\n",row);     A=(double**)malloc(sizeof(double *) * row);     if(A==NULL){         printf("no memory\n");         return 1;     }     for(i=0;i<row;i++)     {         A[i]=(double*)malloc(sizeof(double)*column);         if(A[i]==NULL)         {             printf("no memory\n");             return 1;         }     }     printf("内存分配完成成功1！\n");     fseek(fp,0L,SEEK_SET);     //rewind(fp);     while(!feof(fp)){         for(i=0;i<row;i++){             for(j=0;j<column;j++){                 fscanf(fp,"%lf", &A[i][j]);             }         }     }     printf("读取数据成功1！\n");     printf("A=%.16lf\n", A[0][0]);     printf("A=%.16lf\n", A[2][0]);     system("Pause");     //printf("内存分配完成成功2！\n");     if((op=fopen("rf2_data.txt","r"))==NULL){         printf("打开文件失败！\n");         return 1;     }     printf("代码运行到这！\n");     while(!feof(op)&&(ch=fgetc(op))!='\n'){         if(ch==' '){             column1++;         }     }     column1++;     if(column1==1){         printf("没有数据！\n");         return 1;     }     printf("column1=%d\n",column1);     fseek(op,0L,0);     while(!feof(op)){         if(fgetc(op)=='\n'){             row1++;         }     }     row1++;     if(row1==1){         printf("没有数据！\n");         return 1;     }     printf("行数1=%d\n",row1);     B=(double**)malloc(sizeof(int*)*row1);     if(B==NULL){         printf("no memory\n");         return 1;     }     for(i=0;i<row1;i++)     {         B[i]=(double*)malloc(sizeof(double)*column1);         if(B[i]==NULL)         {             printf("no memory\n");             return 1;         }     }     printf("内存分配完成成功2！\n");     fseek(op,0L,SEEK_SET);     while(!feof(op)){         for(i=0;i<row1;i++){             for(j=0;j<column1;j++){                 fscanf(op,"%lf", &B[i][j]);             }         }     }     printf("B=%.16lf\n",B[0][0]);     printf("读取数据成功2！\n");      //printf("关闭文件！\n");     system("Pause");     //关闭文件     printf("关闭文件！\n");     fclose(fp);     //fclose(op);     //释放内存     for(i=0;i<row;i++){         free(A[i]);         free(B[i]);         //free(B[i]);     }     free(A);     free(B);      return 0;  } 其他地方暂未发现问题，起码如果有数据应该能够读到。 另外，建议提供一下要读文件的内容，我怀疑你读的数据格式和你的处理方式不对。fscanf是格式化读取的，数据之间就没有空格或者其他隔开吗？ 我的数据是用excel转过来的。可能是数据指针那里的问题吧。。除了fscanf还能用其他的么？文件指针是不是有问题？[/quote] 文件指针没问题，如果excel转过来的，那么第一次读之后再次读的时候是不是需要中间隔着一个'\t'呢 所以，你的fscanf每次读都要加一个'\t' fscanf(op,"%lf\t", &B[i][j]); 读到末尾还要改成\n[/quote] 嗯嗯解决了。还是自己不够仔细。功底太差了。。谢谢啊。

引用 5 楼 weixin_38207316 的回复:[quote=引用 4 楼 自信男孩的回复:] A=(double**)malloc(sizeof(int*)*row); A[i]=(double*)malloc(sizeof(int)*column); 改成：   A=(double**)malloc(sizeof(double*)*row); A[i]=(double*)malloc(sizeof(double)*column); 同理下面的B也需要更改。 第一个对A的申请行数，虽然指针的sizeof都是一样的，建议还要sizeof(double *)， 下面的申请A[i]就必须使用sizeof(double)了。同理B的申请一样。  #include <stdio.h> #include <stdlib.h> #include<math.h> #include<time.h> //#include <conio.h>  int main () {     double**A;     double**B;     FILE *fp;     FILE *op;     int i,j;     //double C[10];/*存放最佳匹配位置的数据*/     char ch;     int row = 0, column = 0;     int row1 = 0,column1 = 0;     //打开文件     if((fp=fopen("rf1_data.txt", "r"))==NULL){         printf("打开文件失败！\n");         return 1;     }     while(!feof(fp) && (ch = fgetc(fp)) != '\n') {         if(ch==' '){             column++;         }     }     column++;     if(column==1){         printf("没有数据！\n");         return 1;     }     printf("column=%d\n",column);     fseek(fp,0L,0);     while(!feof(fp)){         if(fgetc(fp)=='\n'){             row++;         }     }     row++;     if(row==1){         printf("没有数据！\n");         return 1;     }     printf("行数=%d\n",row);     A=(double**)malloc(sizeof(double *) * row);     if(A==NULL){         printf("no memory\n");         return 1;     }     for(i=0;i<row;i++)     {         A[i]=(double*)malloc(sizeof(double)*column);         if(A[i]==NULL)         {             printf("no memory\n");             return 1;         }     }     printf("内存分配完成成功1！\n");     fseek(fp,0L,SEEK_SET);     //rewind(fp);     while(!feof(fp)){         for(i=0;i<row;i++){             for(j=0;j<column;j++){                 fscanf(fp,"%lf", &A[i][j]);             }         }     }     printf("读取数据成功1！\n");     printf("A=%.16lf\n", A[0][0]);     printf("A=%.16lf\n", A[2][0]);     system("Pause");     //printf("内存分配完成成功2！\n");     if((op=fopen("rf2_data.txt","r"))==NULL){         printf("打开文件失败！\n");         return 1;     }     printf("代码运行到这！\n");     while(!feof(op)&&(ch=fgetc(op))!='\n'){         if(ch==' '){             column1++;         }     }     column1++;     if(column1==1){         printf("没有数据！\n");         return 1;     }     printf("column1=%d\n",column1);     fseek(op,0L,0);     while(!feof(op)){         if(fgetc(op)=='\n'){             row1++;         }     }     row1++;     if(row1==1){         printf("没有数据！\n");         return 1;     }     printf("行数1=%d\n",row1);     B=(double**)malloc(sizeof(int*)*row1);     if(B==NULL){         printf("no memory\n");         return 1;     }     for(i=0;i<row1;i++)     {         B[i]=(double*)malloc(sizeof(double)*column1);         if(B[i]==NULL)         {             printf("no memory\n");             return 1;         }     }     printf("内存分配完成成功2！\n");     fseek(op,0L,SEEK_SET);     while(!feof(op)){         for(i=0;i<row1;i++){             for(j=0;j<column1;j++){                 fscanf(op,"%lf", &B[i][j]);             }         }     }     printf("B=%.16lf\n",B[0][0]);     printf("读取数据成功2！\n");      //printf("关闭文件！\n");     system("Pause");     //关闭文件     printf("关闭文件！\n");     fclose(fp);     //fclose(op);     //释放内存     for(i=0;i<row;i++){         free(A[i]);         free(B[i]);         //free(B[i]);     }     free(A);     free(B);      return 0;  } 其他地方暂未发现问题，起码如果有数据应该能够读到。 另外，建议提供一下要读文件的内容，我怀疑你读的数据格式和你的处理方式不对。fscanf是格式化读取的，数据之间就没有空格或者其他隔开吗？ 我的数据是用excel转过来的。可能是数据指针那里的问题吧。。除了fscanf还能用其他的么？文件指针是不是有问题？[/quote] 文件指针没问题，如果excel转过来的，那么第一次读之后再次读的时候是不是需要中间隔着一个'\t'呢 所以，你的fscanf每次读都要加一个'\t' fscanf(op,"%lf\t", &B[i][j]); 读到末尾还要改成\n

引用 4 楼 自信男孩的回复: A=(double**)malloc(sizeof(int*)*row); A[i]=(double*)malloc(sizeof(int)*column); 改成：   A=(double**)malloc(sizeof(double*)*row); A[i]=(double*)malloc(sizeof(double)*column); 同理下面的B也需要更改。 第一个对A的申请行数，虽然指针的sizeof都是一样的，建议还要sizeof(double *)， 下面的申请A[i]就必须使用sizeof(double)了。同理B的申请一样。  #include <stdio.h> #include <stdlib.h> #include<math.h> #include<time.h> //#include <conio.h>  int main () {     double**A;     double**B;     FILE *fp;     FILE *op;     int i,j;     //double C[10];/*存放最佳匹配位置的数据*/     char ch;     int row = 0, column = 0;     int row1 = 0,column1 = 0;     //打开文件     if((fp=fopen("rf1_data.txt", "r"))==NULL){         printf("打开文件失败！\n");         return 1;     }     while(!feof(fp) && (ch = fgetc(fp)) != '\n') {         if(ch==' '){             column++;         }     }     column++;     if(column==1){         printf("没有数据！\n");         return 1;     }     printf("column=%d\n",column);     fseek(fp,0L,0);     while(!feof(fp)){         if(fgetc(fp)=='\n'){             row++;         }     }     row++;     if(row==1){         printf("没有数据！\n");         return 1;     }     printf("行数=%d\n",row);     A=(double**)malloc(sizeof(double *) * row);     if(A==NULL){         printf("no memory\n");         return 1;     }     for(i=0;i<row;i++)     {         A[i]=(double*)malloc(sizeof(double)*column);         if(A[i]==NULL)         {             printf("no memory\n");             return 1;         }     }     printf("内存分配完成成功1！\n");     fseek(fp,0L,SEEK_SET);     //rewind(fp);     while(!feof(fp)){         for(i=0;i<row;i++){             for(j=0;j<column;j++){                 fscanf(fp,"%lf", &A[i][j]);             }         }     }     printf("读取数据成功1！\n");     printf("A=%.16lf\n", A[0][0]);     printf("A=%.16lf\n", A[2][0]);     system("Pause");     //printf("内存分配完成成功2！\n");     if((op=fopen("rf2_data.txt","r"))==NULL){         printf("打开文件失败！\n");         return 1;     }     printf("代码运行到这！\n");     while(!feof(op)&&(ch=fgetc(op))!='\n'){         if(ch==' '){             column1++;         }     }     column1++;     if(column1==1){         printf("没有数据！\n");         return 1;     }     printf("column1=%d\n",column1);     fseek(op,0L,0);     while(!feof(op)){         if(fgetc(op)=='\n'){             row1++;         }     }     row1++;     if(row1==1){         printf("没有数据！\n");         return 1;     }     printf("行数1=%d\n",row1);     B=(double**)malloc(sizeof(int*)*row1);     if(B==NULL){         printf("no memory\n");         return 1;     }     for(i=0;i<row1;i++)     {         B[i]=(double*)malloc(sizeof(double)*column1);         if(B[i]==NULL)         {             printf("no memory\n");             return 1;         }     }     printf("内存分配完成成功2！\n");     fseek(op,0L,SEEK_SET);     while(!feof(op)){         for(i=0;i<row1;i++){             for(j=0;j<column1;j++){                 fscanf(op,"%lf", &B[i][j]);             }         }     }     printf("B=%.16lf\n",B[0][0]);     printf("读取数据成功2！\n");      //printf("关闭文件！\n");     system("Pause");     //关闭文件     printf("关闭文件！\n");     fclose(fp);     //fclose(op);     //释放内存     for(i=0;i<row;i++){         free(A[i]);         free(B[i]);         //free(B[i]);     }     free(A);     free(B);      return 0;  } 其他地方暂未发现问题，起码如果有数据应该能够读到。 另外，建议提供一下要读文件的内容，我怀疑你读的数据格式和你的处理方式不对。fscanf是格式化读取的，数据之间就没有空格或者其他隔开吗？ 我的数据是用excel转过来的。可能是数据指针那里的问题吧。。除了fscanf还能用其他的么？文件指针是不是有问题？


Question: C语言调用winsocket,WSAConnectByName和WSAConnectByList怎么使用？

百度搜 “WSAConnectByName WSAConnectByList site:microsoft.com”

引用 2 楼 u011311291 的回复:看了MSDN还是不会写 这些个网页上难道没有能用的例子代码？

看了MSDN还是不会写


我想练习STL模版，用的#include <string>，这应该不存在问题，对于你的第二个问题，我觉得也不存在什么问题，毕竟答案摆在那里的，我觉得自己的错误应该是在忽略了某个细小的点，没把它编上去。 不过，多谢回帖了！

两个问题, 1. 头文件是不是应该是. include <string.h> 2. a, b数组的类型，定义成int类型即可。两个整数的相加减不会出现浮点数。 另外，对输入的数据没有判断范围（严格上将这个扣分更多）