Question: 求C语言大神解题！！！！

引用 3 楼 u010165006 的回复:这是很好的很基础的字符串练习题目，楼主应该自己练习写一遍，如果以后考C语言二级类似的很常见。  包括自己实现一遍strcpy,strcat,strlen等等（不要和库函数同名），都是基本功的练习。

好歹自己先想想，直接拿来的东西终究不是自己的……

#include<stdio.h> #include<string.h> int main() { 	char buffer[128] = {0}, str[128] = {0}; 	scanf("%s", buffer); 	int i, j = 0; 	for(i = 0; i < strlen(buffer); i++) 	{ 		if((buffer[i] >= '0' && buffer[i] <= '9') || (buffer[i] >= 'a' && buffer[i] <= 'z') || (buffer[i] >= 'A' && buffer[i] <= 'Z')) 			str[j++] = buffer[i]; 	} 	str[j] = '\0'; 	printf("%s\n", str); 	return 0; }


Question: vc中加入ege库图形化输出时莫名占cpu导致一段时间后图形无法输出

没有开其他线程的话， 那么还是死循环啊

检查是否资源泄漏的办法之一： 在任务管理器 进程 查看 选择列 里面选择：内存使用、虚拟内存大小、句柄数、线程数、USER对象、GDI对象 让你的程序(进程)不退出,循环执行主流程很多遍，越多越好，比如1000000次甚至无限循环，记录以上各数值，再隔至少一小时，越长越好，比如一个月，再记录以上各数值。如果以上两组数值的差较大或随时间流逝不断增加，则铁定有对应资源的资源泄漏！  搜“GDI泄露检测”

”程序中没有使用线程，死循环中有sleep函数“ 你的死循环是在哪个线程？  看起来像是消息处理出问题了，是不是消息死循环了？

改成多线程试试？

引用 1 楼 lunat 的回复:cpu占用前后是否有明显变化？你怎么判断是cpu占用导致无法输出？ 能看到运行到一分多钟Cpu占用就百分百，随即就不能正常输出

cpu占用前后是否有明显变化？你怎么判断是cpu占用导致无法输出？


Question: C中I/O的一点疑惑，请大家指点！

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

不同类型计算机（CPU可能也不同） 中间传递 文件。存为 文本文件 带格式的文件，一般存为文本文件 需要人识别的文件，存为文本文件  仅仅计算机才需要的， 存为二进制

Q1：看你文件的用途,假如是给人看的,建议使用文件流,否则使用二进制流 Q2：在Unix环境高级编程中有一章节专门讲操作数据流的i/o库以及以及read和write函数,他们的效率实际上并不会相差太大,你如何方便就如何使用,看你喜欢用哪个了 Q3:redis的话有一本书叫做redis设计与实现,讲的通俗易懂,不让去淘一本高仿的看看,我目前就在看.至于nginx恕我不太熟,就不给意见了.

一年分为春夏秋冬四个季节，我们通常处于哪个季节？


Question: c 指针写3*3的转置

请那些喜欢将数组作为函数参数传来传去的码农思考一下为什么不把整个互联网内容当作函数参数传来传去呢？

你的inv函数的第二个参数n好像没用到啊？ 而且int  (*q)[3]你用这种形式，必须要指定列数3，如果你的矩阵维数不固定的话限制很大

void inv(int (*q)[],int n);  改成：  void inv(int (*q)[3],int n);

引用 2 楼 小灸舞的回复:可以跑出结果 可是它调试的时候有提示错误这样没有关系吗？

可以跑出结果

#include<stdio.h> int main() {     void inv(int (*q)[],int n);     int a[3][3],i,j;     int (*p)[3];     printf("请输入一个3*3矩阵\n");     for(i=0;i<3;i++) 		for(j=0;j<3;j++) 			scanf("%d",&a[i][j]); 		p=a; 	inv(p,3);     for(i=0;i<3;i++) 	{ 		for(j=0;j<3;j++) 			printf("%d ",a[i][j]); 		printf("\n");  	} 	return 0; } void inv(int (*q)[3],int n) {     int i,j,t;     for(i=0;i<3;i++)         for(j=0;j<3;j++)             if(i<j)             {                 t=*(*(q+i)+j);                 *(*(q+i)+j)=*(*(q+j)+i);                 *(*(q+j)+i)=t;             }   }  我刚改了  不知道还有什么问题


Question: 链表操作为什么要双指针而顺序表只要单指针？

因为Create（）需要向main函数传递指针参数，需要改变指针参数。通过二级指针才能传递出去。还有一种方法可以通过引用来传递指针参数。  typedef struct LNode{        ElemType data;        struct LNode *next; }LinkList; void CreateList(LinkList *&L ,int n) {         int i=0;        LInkList *s;         L = (LinkList *)malloc(sizeof(LinkList));        L -> next = NULL;         for(i = 0; i < n ; i++)         {              s = (LinkList *)malloc(sizeof(LinkList));              s -> next = L -> next;              L ->next = s;         } }

引用 5 楼 qq423399099 的回复:你如果想在某个函数内改变指针的指向，那么需要传二级指针。 假设你main函数里定义了一个指针叫head,然后调用fun函数（形参名叫h2） 你如果传的是一级指针，那么仅仅只是head和h2所指的是同一块内存区域，而h2和head本身并不是同一个指针刚刚看到别人以前在CSDN发的类似问题，看了下底下的回答，差不多已经明白了，不过还是多谢你的回答。

引用 2 楼 lm_whales 的回复:链表的头指针，是个非常重要的东西 它在程序的使用中，代表整个链表。 创建链表，需要给头指针赋值，尤其是不带空头节点的单链表 一级指针，不能改变链表的头指针， 只有传递二级指针，才可以 另外一般都说 一级指针，二级指针，。。多级指针 很少有人说双重指针的，三重指针的1级链表为什么不能改变头指针呢，可否再具体一点。。。

引用 1 楼 user-4 的回复:"双重指针"是”二级指针”的意思？嗯，是啊

"双重指针"是”二级指针”的意思？


Question: 个人图书管理系统输入信息

book[i].bookISBN这是个int类型的，你用strcmp和"end"比较？ 而且变量名最好换个名字，别和结构体同名


Question: 这里我想请问大家一个用c语言编的俄罗斯方块的部分代码问题，请大家帮忙

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

HWND wnd = GetHWnd();  当你要关闭窗口时，你首先要获取到要关闭的窗口，这行代码就是达到获取窗口的目的； WORD c = g_Blocks[g_CurBlock.id].dir[g_CurBlock.dir];//.这个是确定生成图形的形状和颜色 setlinecolor(0x006060);//  这里的十六进制是一个颜色值.颜色可以用6位十六进制表示，从高到低每两位表示一个色的占位大小，分别是red，green，blue

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

源代码中 在对应按键操作的时候有两个case情况： case 0: case 0xE0: 然后对应山下左右按键操作。 请问那两个case是什么意思啊？？


Question: 马踏棋盘问题，探索路径的时候为什么要找到当前位置的下一个位置的可行路径条数？

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


Question: 用指针查找 第某个学生的成绩

谢谢版主  我知道啦

printf("%d ",*(search(p,n)+1));应该是printf("%d ",*(search(p,n)+i));  #include<stdio.h> int main() {     int *search(int (*s)[4],int n);     int sorce[3][4]={{65,67,70,60},{80,87,90,81},{90,99,100,98}};     int n,i;     int (*p)[4];     p=sorce;     printf("请输入你要搜索的学生号\n");     scanf("%d",&n);     for(i=0;i<4;i++)         printf("%d ",*(search(p,n)+i));     return 0; } int *search(int (*s)[4],int n) {     return *(s+n-1); }


Question: Ｃ＃面向对象

C语言栏目中一个C#的帖子是用来干什么的，求讲解。 构造函数是构造一个类的实例时，执行的初始化函数；类的方法是类的行为或者基于类数据的某个操作。 我觉得你的问题应该是：有没有C#入门的书推荐一下（注：零基础）？


Question: 申请空间的问题

引用 2 楼 qq423399099 的回复:List *P;这样写意味着你的P指向的是一个未知区域，然后进行写操作自然出现异常了。 List *P = (List *)malloc(sizeof(List)); 谢谢！

引用 1 楼 user-2 的回复:List P; P.con=(S)malloc(sizeof(Stu)); 初学者少用typedef，以免发生逻辑错误 谢谢！解决了！


Question: 为什么我装了VC助手之后不能输入“\”这个符号了

换个输入法再试试。


Question: 编译时：warning C4715: 'add' : not all control paths return a value

引用 3楼我是你的主体 的回复:[quote=引用 2 楼 小灸舞的回复:]要学会看错误信息： not all control paths return a value说的很清楚了 不是所有的路径都返回了值 只知道中文意思却不知道它为什么是这样也没用啊[/quote]把错误拿去一搜就行了。 大部分常见错误都能找到答案

引用 2 楼 小灸舞的回复:要学会看错误信息： not all control paths return a value说的很清楚了 不是所有的路径都返回了值 只知道中文意思却不知道它为什么是这样也没用啊

#include<stdio.h> #include<string.h>  int main() {     int num = 1, sn;      int add(int num);      sn = add(num);     printf("%d\n", sn);     return 0; }  int add(int num) {     static int sn;      sn += num;      if (num == 100) {         return sn;     }      return add(++num); }  并不是所有的控制路径都返回了一个值。 相对于这个警告，我更感兴趣的是你这个函数的设计。


Question: 前辈们，我这SetWindowsHookEx总提示参数错误

第三个参数 GetModuleHandleA("name.dll")

引用 3 楼 darksoulson 的回复:我会了，哈哈。。。。  我也碰到这个问题了，能解释一下吗？

帮结帖＋蹭分

我会了，哈哈。。。。

坐等大神，我一直等呢

在线等，希望前辈们赐教


Question: 音乐播放器实现上一首，下一首，循环，单曲，列表，随机，单曲循环功能非常感谢

引用 2 楼 qq_31540915 的回复:前面的变量已经给出，求尽快回复，非常感谢  你需要能控制一首歌的播放:开始,暂停(这个功能可以暂时别做),停止  所谓上一首,下一首:你将所有的歌曲都保存到一个列表中(vector list 都行).  当单击上一首的时候,先停止当前正在播放的.然后从列表中获取上一个变量,直接播放,下一首同理  -------  单曲:单曲的意思是这样的,当播放完一首之后,传递给同一首的路径给播放  列表:略  随机:获取列表中的歌曲数量,然后通过一个srand函数获取一个值n,从第一首歌开始在列表中往下走n步,获取该元素,播放 ------------------------- 大学时候就做过.祝你好运

仅供参考：#include <stdio.h> #include <stdlib.h> #include <time.h> int d[6]; int i,n,a,b,t; int c,j; void main() {     srand(time(NULL));     printf("shuffle 0..n-1 demo\n");     for (n=1;n<=5;n++) {/* 测试1～5个元素 */         printf("_____n=%d_____\n",n);         j=1;         for (c=1;c<=n;c++) j=j*c;/* j为n! */         j*=n*2;         for (c=1;c<=j;c++) {/* 测试n*2*n!次 */             for (i=0;i<n;i++) d[i]=i;/* 填写0～n-1 */             for (i=n;i>0;i--) {/* 打乱0～n-1 */                 a=i-1;b=rand()%i;                 if (a!=b) {t=d[a];d[a]=d[b];d[b]=t;}             }             printf("%04d:",c);             for (i=0;i<n;i++) printf("%d",d[i]);             printf("\n");         }     }     printf("shuffle 1..n demo\n");     for (n=1;n<=5;n++) {/* 测试1～5个元素 */         printf("_____n=%d_____\n",n);         j=1;         for (c=1;c<=n;c++) j=j*c;/* j为n! */         j*=n*2;         for (c=1;c<=j;c++) {/* 测试n*2*n!次 */             for (i=1;i<=n;i++) d[i]=i;/* 填写1～n */             for (i=n;i>1;i--) {/* 打乱1～n */                 a=i;b=rand()%i+1;                 if (a!=b) {t=d[a];d[a]=d[b];d[b]=t;}             }             printf("%04d:",c);             for (i=1;i<=n;i++) printf("%d",d[i]);             printf("\n");         }     } }

前面的变量已经给出，求尽快回复，非常感谢

// PC05Dlg.cpp : 实现文件 //  #include "stdafx.h" #include "PC05.h" #include "PC05Dlg.h" #include "afxdialogex.h"  #ifdef _DEBUG #define new DEBUG_NEW #endif   // 用于应用程序“关于”菜单项的 CAboutDlg 对话框  class CAboutDlg : public CDialogEx { public: 	CAboutDlg();  // 对话框数据 	enum { IDD = IDD_ABOUTBOX };  	protected: 	virtual void DoDataExchange(CDataExchange* pDX);    // DDX/DDV 支持  // 实现 protected: 	DECLARE_MESSAGE_MAP() };  CAboutDlg::CAboutDlg() : CDialogEx(CAboutDlg::IDD) { }  void CAboutDlg::DoDataExchange(CDataExchange* pDX) { 	CDialogEx::DoDataExchange(pDX); }  BEGIN_MESSAGE_MAP(CAboutDlg, CDialogEx) END_MESSAGE_MAP()   // CPC05Dlg 对话框     CPC05Dlg::CPC05Dlg(CWnd* pParent /*=NULL*/) 	: CDialogEx(CPC05Dlg::IDD, pParent) 	, m_playListStr(_T("")) 	, str4(_T("")) 	, m_index(-1) 	, zflag(0) { 	m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME); 	s=-1; 	m_id=NULL; 	m_isOpen=false;//打开 	m_isPlay=false;//播放 	length=L"00:00"; 	current=L"00:00"; 	h=0; 	len=0;//长度 	cur=0; 	volume=700; 	m_playListStr=_T(" ");//歌曲列表 	m_songIndex=-1;//当前歌曲位置 	zflag=0; }  void CPC05Dlg::DoDataExchange(CDataExchange* pDX) { 	CDialogEx::DoDataExchange(pDX); 	DDX_Control(pDX, IDC_VOLUME, m_volume); 	DDX_Control(pDX, IDC_LIST, m_playList); 	DDX_LBString(pDX, IDC_LIST, m_playListStr); }  BEGIN_MESSAGE_MAP(CPC05Dlg, CDialogEx) 	ON_WM_SYSCOMMAND() 	ON_WM_PAINT() 	ON_WM_QUERYDRAGICON() 	ON_BN_CLICKED(IDC_OPEN, &CPC05Dlg::OnClickedOpen) 	ON_BN_CLICKED(IDC_PLAY, &CPC05Dlg::OnClickedPlay) 	ON_BN_CLICKED(IDC_STOP, &CPC05Dlg::OnClickedStop) 	ON_BN_CLICKED(IDC_BEFORE, &CPC05Dlg::GoPrevious) 	ON_BN_CLICKED(IDC_NEXT, &CPC05Dlg::GoNext) 	ON_WM_TIMER()  	ON_WM_HSCROLL() //ON_BN_CLICKED(IDC_ADD_DLG, &CPC05Dlg::OnBnClickedAddDlg) ON_LBN_SELCHANGE(IDC_LIST, &CPC05Dlg::OnSelchangeList) ON_BN_CLICKED(IDC_FOLDER, &CPC05Dlg::OnClickedFolder) ON_LBN_DBLCLK(IDC_LIST, &CPC05Dlg::OnDblclkList) ON_BN_CLICKED(IDC_QIAN, &CPC05Dlg::OnBnClickedNext) ON_BN_CLICKED(IDC_HOU, &CPC05Dlg::OnBnClickedBefore) ON_BN_CLICKED(IDC_DELETE, &CPC05Dlg::OnBnClickedDelete) ON_BN_CLICKED(IDC_CLEAR, &CPC05Dlg::OnBnClickedClear) END_MESSAGE_MAP()


Question: double数组的第一个值调用函数中和调用函数后不一样？

读取前用fseek函数置头看看

原因找到了，就是txt下面多了一个回车，没有看出来，导致数组越界，对本次数组没影响，但是覆盖了前面读进去的数组的第一个值。

对不起，下结论太早了。feof（）虽然读取成功了，但是改变的还是不对。

非常感谢大家 问题解决了： 问题出在feof（）  假设"in.txt"中存放的内容是：ABCDFEFG 按照自己的想法，输出应该是：ABCDEFG，但是实际上的输出却是：ABCDEFGG，最后一个字符被输出了两次！  在官方帮助文档里查询feof，其返回值说明为：A non-zero value is returned in the case that the End-of-File indicator associated with the stream is set.Otherwise, a zero value is returned. 如果流的文件结束符（EOF）已经被设置，那么返回非零值，否则返回零。输入文件的最后一个字符是不可见的字符 '\0'，所以文件指针移动到指向'\0'的时候，还没有设置EOF，此时进行设置，因此再进入循环体一次。而fscanf()已经读取不到有效字符，所以返回EOF，而ch的值没有被改变（同样，参考文档里对fscanf()的说明），还是'G'，所以'G'第二次被输出。 由于fscanf()返回的读取的有效字符的个数，所以代码可以修改为： #include <stdio.h> #include <stdlib.h> int main() { char ch; FILE *fp = fopen("in.txt", "r"); while (fscanf(fp, "%c", &ch) > 0) printf("%c", ch); return 0; }

单步跟踪程序运行，观察分析变量变化情况，在哪发生了变化，然后分析原因

引用 1 楼 chendepeng17 的回复:读取前用fseek函数置头看看  嗯设置了 还不行。没理由啊，为啥只有第一个不对呢？后面的都正确。而且我单独把读取程序和调用过程，运行的话，就对着呢。如果原封不动的放回生态模型中，数组的第一个就不对，后面的都对。这真是太诡异了。


Question: 基本块用()包络是否是UB行为

不是标准C++而已 UB 是可以任意处理的 同一款编译器，编译的结果，都不一定一样

因为vs用的不是gcc编译器

GCC扩展了一些功能而已


Question: 求助：include conio.h头文件突然报错。

原本想两位版本都分20分的，结果点结贴自己变了，原来不能平均得分。。。。不好意思。  我摸索了一天。找到原因了。原来是VS2015的include文件路径指向了VS2013的include。因为我装两个版本，一个2015一个2013。。。 打开include 目录下的conio.h发现路径是vs2013里的include文件夹。不是VS2015的。。 自作自受。。

手机上传图片太小了。再次上传截图。。

网上重新下个conio.h替换试试

另外建议写成：#include <conio.h>


Question: C编译报错而C++通过且能执行，求解

可以讲得在具体一点吗，我是新手，你可以从上面代码中举个例子跟我讲解下，麻烦了

表达式语句,包括函数调用 return  if else  switch goto 甚至 标号定义语句 （一个名字加一个冒号） C中 这些语句，一旦出现，就不可以再 声明，定义，类型，变量。函数了 想声明，只有 用 ｛｝括起来，使得声明局限在在语句组内部  PS:表达式语句，就是一个表达式，后接分号 例如 a=b+c; //赋值表达式语句 a;//单变量表达式语句 a+b;//加法表达式语句 a?b:c;//?表达式语句 printf("%d",a); //函数调用表达式语句。

引用 3 楼 u011441923 的回复:什么是第一个非初始化语句，上面的代码哪里的变量定义在非初始化语句之后了，举个例子讲解一下  就是你要把变量声明放在执行语句前，比如在函数最前面先声明了所有要用到的变量

引用 12 楼 whhvc 的回复://SqList *namelist=(SqList *)malloc(sizeof(SqList));     SqList namelist;         char strInstruct[10];     int pos;     ElemType e; 	 InitList(&namelist); 这样编译通过 你试试试过了，编译通过了，我是新手，困惑半天。。。多谢！

引用 9 楼 lunat 的回复:上面讲的已经相当明确了。  int main()   {       //SqList *namelist=(SqList *)malloc(sizeof(SqList));     SqList namelist;     char strInstruct[10];     int pos;     ElemType e;      InitList(&namelist);      while(~scanf("%s",strInstruct))     {           if(!strcmp(strInstruct,"insert"))         {             scanf("%d%s",&pos,e.name);             ListInsert(&namelist,pos,e);         }           else if(!strcmp(strInstruct,"show"))         {             ListShow(&namelist);           }           else if(!strcmp(strInstruct,"delete"))           {               scanf("%s",e.name);               pos=LocateElem(&namelist,e,cmp);               ListDelete(&namelist,pos,&e);           }           else if(!strcmp(strInstruct,"search"))           {               scanf("%s",e.name);               printf("%d\n",LocateElem(&namelist,e,cmp));           }       }       return 0; }//C编译时报错，把文件改成cpp后缀，编译通过并且可以运行，以下是错误代码  真的可以了，多谢了，我是新手，上面说的那些对我来说有些抽象，看你这个就懂了，多谢了

引用 10 楼 lunat 的回复:另外，你的~scanf是哪个老师交给你的？？。。。我知道也可以用scanf("%s", strInstruct) != EOF，我看网上其他人这样用，我就尝试一下。。。

SqList namelist;     InitList(&namelist);     char strInstruct[10]; 你在执行函数后再定义变量 就不行啊

另外，你的~scanf是哪个老师交给你的？？

别用vc6了，换visual studio 2015 community版。

引用 5 楼 lm_whales 的回复:C++ 鼓励 变量用到再定义 C 函数内部所有声明定义  必须在 语句块的开头 一旦有一个 非声明定义语句出现。 就不可以再定义变量，类型，声明函数  外部声明定义的位置，可以随意点 因为 函数外部对C来说，只有 类型，函数，变量的声明定义 以及预编译语句。  预编译语句，严格来说， 只是编译控制语句，不是C语言的一部分，而是编译指令，  C99  好像也可以像C++一样随处定义了，不过编译器支持的很差，可以忽略多谢你回答这么多，不过我感觉还是有点抽象，因为我前几个题目都是类似这样做的，C编译没问题的，为什么这个题目不行呢，具体我上面代码怎么改才能让它在C编译通过呢，我用的是VC++6.0，那我以后编程都用.cpp的文件了吗，还是可以继续用.c的文件呢

C语言的变量定义必须在第一个非初始化语句之前。


Question: 大神们，帮忙看一下哪儿错了

文档上传失败了//////////////////////////////////

就几个头文件怎么看得出

去掉： 。。。。。。。。。。。。。。。。。。。。。。。。。


Question: 为什么会出现乱码的，用c写的定时关机

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

文件编码不是gbk

控制台在简体中文Windows下的编码一般是是ANSI编码(代码页936, GBK),先明确这点。 然后检查下文件的编码.


Question: 关于文件的

gets(str);       fprintf(fp,"%s\n",str);//后加\n即可       printf("continue?");

用 \r\n 代替 \n

#include <stdio.h> int main() {     int i, flag;     char str[80], c;     FILE*fp;     fp = fopen("text", "w");     flag = 1;      while (flag == 1) {         printf("input string:\n");         gets(str);         fprintf(fp, "%s\n", str);         printf("continue?");         c = getchar();         if ((c == 'N') || (c == 'n'))             flag = 0;         getchar();     }     fclose(fp);     fp = fopen("text", "r");     while (fscanf(fp, "%s", str) != EOF) {         for (i = 0; str[i] != '\0'; i++)             if ((str[i] >= 'a') && (str[i] <= 'z'))                 str[i] -= 32;         printf("%s\n", str);     }     fclose(fp);     return 0; }

不行哦！输入多个字符串最后会一起输出没有换行，但一个字符串中存在空格就会每隔一个空格换行一次。

好像没啥问题啊

试试 \r\n


Question: 关于汉诺塔用递归方法求解的问题

谢谢版主，我能弄懂

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


Question: c语言程序改错

程序功能应该是摘哦出年龄最大的人，并显示。程序修改如下 #define N 4 #include "stdio.h"   struct man {      char name[20];     int age; }person[N]={"li",18,"wang",19,"zhang",32,"sun",22};   main() {     struct man *q,*p;     int i,m=0;     p=person;     q=person;     for(i=0;i<N;i++)     {         if(m<p->age)        {             q=p++;            m=q->age;        }     }     if(m!=0)printf("%s,%d",q->name,q->age); }

static struct man {     char name[20];  int age; } person[N] = {     {    "li"    ,       18},     {    "wang"  ,       19},     {    "zhang" ,       32},     {    "sun"   ,       22}, };  http://bbs.csdn.net/topics/380157851

想输粗年龄最大的人吧，不要用累加了，直接指向person[i]

#include <stdio.h> #define N 4  static struct man {     char name[20];     int age; } person[N] = { {"li",18}, {"wang",19}, {"zhang",32}, {"sun",22} };  int main() {     struct man *q, *p;     int i, m = 0;      p = person;      for (i = 0; i < N; ++i, ++p) {         if (m < p->age) {             q = p;             m = q->age;         }     }      printf("%s,%d\n", q->name, q->age);     return 0; }  拜托，包含stdio.h用尖括号好不好？main函数别写成这样好不好？结构体初始化别太省事了，好不好？

打印 年龄最大的人   如下改   #define N 4 #include "stdio.h"  struct man {      char name[20];     int age; }person[N]={"li",18,"wang",19,"zhang",32,"sun",22};  void main1() {     struct man *q,*p;     int i,m=0;     p=person;     q=person;     for(i=0;i<N;i++)     {         if(m<p->age) 		{ 			m=p->age; 			q=p++;         }      	} 	TRACE("%s,%d\n",q->name,q->age); }  输出zhang,32

#define N 4 #include "stdio.h"  struct man {  	char name[20]; 	int age; }person[N]={"li",18,"wang",19,"zhang",32,"sun",22};  main() { 	struct man *q,*p; 	int i,m=0; 	p=person; 	for(i=0;i<N;i++) 	{ 		if(m<p->age) 		q=p++; 		m=q->age; 	} 	printf("%s,%d",q->name,q->age); }     程序有点问题 老师发的让改的代码是这个

#define N 4 #include "stdio.h"  struct man {  	char name[20]; 	int age; }person[N]={"li",18,"wang",19,"zhang",32,"sun",22};  main() { 	struct man *q,*p; 	int i,m=0; 	p=person; 	q=person; 	for(i=0;i<N;i++) 	{ 		if(m<p->age) 		{ 			q=p++; 			m=q->age; 		} 	} 	printf("%s,%d",q->name,q->age); }    m=q->age; 放到if里面吧

楼上那样改是不行的，有逻辑错误。比如person[N]={"li",18,"wang",11,"zhang",19,"sun",42};就得不出答案 你应该循环N次，每次都应该让m和p[i].age进行比较，而不是p->age，因为一旦进不了if循环，那么p就一直指着当前元素(后面的元素根本没有比较到)  #define N 4 #include "stdio.h"  struct man {  	char name[20]; 	int age; }person[N]={"li",18,"wang",19,"zhang",32,"sun",22};  void main() { 	struct man *q,*p; 	int i,m=0; 	p=person; 	for(i=0;i<N;i++) 	{ 		if(m<p[i].age) 		{ 			q=&p[i]; 			m=q->age; 		} 	} 	printf("%s,%d",q->name,q->age); }


Question: 为什么判断是否为偶数的第一个处理子程序中0没有输出？

isEven()返回的是m，所以m是0的时候也就和奇数一样返回0了。 而is()返回的就很明确，不是1就是0

明白了，谢谢你们

isEven(i)中，i=0,函数返回值是0，判断条件为假，所以0不会输出； is(i)中i=0,return m%2 == 0?1:0; 返回的是1，判断条件为真，所以0会输出。


Question: 新手求教：win32 api游戏设计关于定时器settimer的问题

谢谢大家我的问题已经解决了

漏消息映射？

OnTimer ?

检查SetTimer的返回值

不是，那些动作我都做了，我是说定时器它好像没有起到该有的作用，就是放下炸弹后，3秒爆炸，这些动作我敢保证没错

Setboom 仅设置了变量，你要做的是爆炸处理怎么根据这个变量做动作


Question: c语言中的指数函数输出

仅供参考：#include <stdio.h> #include <string.h> void trim0(char *s) { //  2.000000e-006→2e-6 //  1.234560e+002→1.23456e2 //  1.234560e+005→1.23456e5 //  1.000000e+000→1e0 // -1.000000e+000→-1e0 // -1.002000e+002→-1.002e2     char x[40];     char E[2];     int z,e,i;     if (4==sscanf(s,"%d.%39[0-9]%1[Ee]%4d",&z,x,E,&e)) {         i=strlen(x)-1;         while (1) {             if ('0'==x[i]) {                 x[i]=0;                 if (i<=0) break;                 i--;             } else break;         }         if (i<=0) {             sprintf(s,"%de%d",z,e);         } else {             sprintf(s,"%d.%se%d",z,x,e);         }     } } int main() {     char s[40];     double d;      while (1) {         printf("Input a float number(0 to exit):");         fflush(stdout);         rewind(stdin);         if (1==scanf("%lf",&d)) {             if (0.0==d) break;             sprintf(s,"%e",d);             trim0(s);             printf("%s\n",s);         }     }     return 0; } //Input a float number(0 to exit):0.000002 //2e-6 //Input a float number(0 to exit):123.456 //1.23456e2 //Input a float number(0 to exit):123456 //1.23456e5 //Input a float number(0 to exit):1 //1e0 //Input a float number(0 to exit):-1 //-1e0 //Input a float number(0 to exit):-100.2 //-1.002e2 //Input a float number(0 to exit):0 //

我vs2010上试了下，机器输出是2e-006。

sprintf输出到字符串，再自写一小段程序去掉多余的0


Question: 老师给的一个产生随机数的程序，看不太懂，大神解释下。。

感谢大伙，问题解决。。谢谢谢谢

我不知道你的 seed 哪里来的，我使用参数了。

function random: real:  begin   Seed: =125.0*(seed+1.0)         Seed: =Seed-8192.0*trunc (seed/8192)         random: = (Seed+0.5)/8192  end;  float random(int seed) { float Seed; Seed = 125.0 * (seed + 1.0); Seed -= 8192.0 * (int)(seed / 8192); return (Seed + 0.5) / 8192; }

Pascal   begin 约等于 C的｛  end  约等于C的｝ 函数返回值类型定义在后面 real 换成 float   或者 double 赋值:= 对应 = 想等比较 = 对应== /对应 浮点除法 div 对应整除 =在定义类型，常量的时候相当于 typedef ,=, trunc 是截断取整；正数的话， 对应 c 的floor 其他自行解决吧

我去。。那您能帮我把它改成C代码么，我不会Pascal

这是Pascal代码，而且行尾缺少分号。


Question: C程序顺序表操作求帮助

好的，明白了，谢了，分给你。

如果结构体内有指针成员，大部分情况下你需要为这个指针成员分配内存 因为你定义的结构体成员申请到的内存给指针成员的仅仅只是4个字节（用来存放指针本身的） 而指针成员指向的内存必须自己手动申请或者赋值才行

真的是这样啊，程序已经可以运行了，非常感谢！ 我本以为只要结构体内部指针分配内存就行了，没想到SqList结构体指针还要分配内存。 顺便问下，怎么理解SqList结构体内部指针分配的内存和SqList结构指针分配的内存之间的关系呢， 主要就是对结构体这个类型内部存在指针变量的理解，谢谢了。ps：第一次在CS上提问，很快就 得到回复，十分感谢。

因为你没有给main函数里的La分配空间。 SqList *La这样写，La是指向一块未知区域的内存，然后执行InitList_Sq函数， L->data=(ElemType *)malloc(LIST_INIT_SIZE*sizeof(ElemType));试图向未知区域写入值，自然就出现异常了。 改成这样： SqList *La = (SqList *)malloc(sizeof(SqList ));


Question: 数据结构二叉搜索树问题

大家帮帮忙

CreateList();//初始化顺序表 void p(BinTree t)//遍历创建好的二叉搜索树，二叉搜索树结构体包括Stu 定义的Data,Left,Right { //int i = 0; static j=0; if (t) { p(t->Right,);//先访问右子树 //e.score = t->Data.score;//把当前节点的内容赋给e，Stu 是一个结构体，包括学生学号、姓名、成绩 //s->con[i].score = e.score; //i++; P.con[j].score = t->Data.score; strcpy(P.con[j].name, t->Data.name); strcpy(P.con[j].num, t->Data.num); j++; p(t->Left); P.con[j].score = t->Data.score; strcpy(P.con[j].name, t->Data.name); strcpy(P.con[j].num, t->Data.num); j++; }  }

可以去我的博客看看二叉搜索树的类的建立和遍历

你这样贴了一段别人很难看出错误。 P.con[j].score = e.score;出错的话，你自己检查一下P有没有分配空间，它的成员变量con有没有分配空间，j是不是太大越界了 代码功能归根结底不是别人帮自己看或讲解或注释出来的；而是被自己静下心来花足够长的时间和精力亲自动手单步或设断点或对执行到某步获得的中间结果显示或写到日志文件中一步一步分析出来的。 提醒：再牛×的老师也无法代替学生自己领悟和上厕所！ 单步调试和设断点调试（VS IDE中编译连接通过以后，按F10或F11键单步执行，按Shift+F11退出当前函数；在某行按F9设断点后按F5执行停在该断点处。）是程序员必须掌握的技能之一。


Question: 在VMware模拟鼠标没反应

引用 3 楼 zhoujielunzhimi 的回复:#1说的很对。 另：在vmware中，SetCursorPos失效。因为vmware需要掌控cursor位置（我们在vmware中移动鼠标，光标不会跑到vmware外面）是的，谢谢，我再慢慢找解决办法吧

引用 2 楼 zhao4zhong1 的回复:添加消息循环： 将Sleep(1000); 替换为： MSG msg; int i; for (i=0;i<10;i++) {         Sleep(100);         if (GetMessage(&msg,NULL,0,0)) {             TranslateMessage(&msg);             DispatchMessage(&msg);         } }试过了，也没用，不过还是谢谢大神，在虚拟机里面就SetCursorpos没用，其他mouse_event,Keybord_event都正常

引用 1 楼 user-3 的回复:在学习win32 API？ 创建的是：Win32 -->win32控制台应用程序？ 建议将Sleep的时间改长一点。  典型的windows程序，需要创建窗口程序，消息循环之。建议创建win32-->win32项目看看。 有一本书挺不错的“VC++技术内幕”，个人推荐。  如果是学习c++语法，不要先扎进win32程序开发，可先看看 “C++ Primer”。创建的就是空项目，Sleep改长也没用，试了创建win32项目，一堆代码看不懂，不知道把代码放哪里，我是看视频学的，尹成老师讲的C基础


Question: 关于C语言全局资源的问题

引用 3 楼 zhao4zhong1 的回复:[quote=引用 2 楼 SXJIAKE 的回复:] [quote=引用 1 楼 zhao4zhong1 的回复:]WSAGetLastError 他这个应该不是 Windows 的，没有 WSAStartup...[/quote] errno[/quote]  谢谢，先去试试

引用 4 楼 paschen 的回复:用WSAGetLastError函数判断失败原因  谢谢版主，不过这个问题是在linux环境下，redhat6。

WSAGetLastError The Windows Sockets WSAGetLastError function gets the error status for the last operation that failed.  int  WSAGetLastError (void); Remarks The WSAGetLastError function returns the last network error that occurred. When a particular Windows Sockets function indicates that an error has occurred, this function should be called to retrieve the appropriate error code. This error code can be different from the error code obtained from getsockopt SO_ERROR, which is socket-specific since WSAGetLastError is for all thread-specific sockets.  A successful function call, or a call to WSAGetLastError, does not reset the error code. To reset the error code, use the WSASetLastError function call with iError set to zero. A getsockopt SO_ERROR also resets the error code to zero.  The WSAGetLastError function should not be used to check for an error value on receipt of an asynchronous message. In this case, the error value is passed in the lParam field of the message, and this can differ from the value returned by WSAGetLastError.  Return Values The return value indicates the error code for this thread's last Windows Sockets operation that failed.  QuickInfo   Windows NT: Yes   Windows: Yes   Windows CE: Use version 1.0 and later.   Header: Declared in winsock2.h.   Import Library: Link with ws2_32.lib.  See Also getsockopt, WSASetLastError

用WSAGetLastError函数判断失败原因

引用 2 楼 SXJIAKE 的回复:[quote=引用 1 楼 zhao4zhong1 的回复:]WSAGetLastError 他这个应该不是 Windows 的，没有 WSAStartup...[/quote] errno

引用 1 楼 zhao4zhong1 的回复:WSAGetLastError 他这个应该不是 Windows 的，没有 WSAStartup...


Question: Qt for iOS 组播接收真机收不到

楼主,我也是同样的问题,没解决

自己顶下，等解决这个问题以后，我把如果搭配qt for ios的完整过程写成一个帖子吧，网上的不是很完善。对于从没接触过mac系统的人来说，摸索起来好麻烦


Question: 关于音频可视化的实现

引用 1 楼 user-2 的回复:FFT 转频域啊, 网上代码太多...  暂时还没找到具体代码, 不过知道ffmpeg的库可以做fft,  能不能解释一下, 转了频域后再怎么做, 因为最终要显示是个频率的振幅吧?

推荐使用NCTAudioStudio控件。

FFT 转频域啊, 网上代码太多...


Question: c语言获取FTP文件夹中的文件信息

Everything  ,web ftp 局域网架设很简单

速度慢的话，可以自己起一个ftp服务器

还可以，值得看看

需要FTP服务端设置相应权限。

这个问题楼主也是刚开始摸索，wininet还不太清楚，我在连接上自己搭载的本地服务器后，用了一个socket的send函数将一个list命令传给服务器，然后将服务器返回的文件列表输出来，但是服务器根目录下文件夹的文件是无法输出，请问一下 这种问题需要怎么解决呢，想输出目录下所有的文件包括文件夹内的文件，以及文件夹包含的文件的数量。

如果你还要对子文件夹也要处理，这就麻烦了，需要把查找文件部分函数写成递归函数，并独立出来，以及要递归多少层，这些你自己去完成吧。

这里是一个用 Windows wininet API 写的例子：#include <stdio.h> #include <stdlib.h> #include <tchar.h> #include <windows.h> #include <wininet.h> #pragma comment(lib, "wininet.lib")  TCHAR szFtpUrl[] = _T("ftp://ftp.info-zip.org/pub/infozip"); TCHAR szUserAgent[] = _T("Mozilla/5.0 (Windows NT 6.1; Trident/7.0; rv:11.0) like Gecko");  int main(int argc, char *argv[]) {     TCHAR szHostName[INTERNET_MAX_HOST_NAME_LENGTH] = { 0 };     TCHAR szPathPart[INTERNET_MAX_PATH_LENGTH] = { 0 };     TCHAR szUserName[INTERNET_MAX_USER_NAME_LENGTH] = { 0 };     TCHAR szPassword[INTERNET_MAX_PASSWORD_LENGTH] = { 0 };     URL_COMPONENTS uc   = { 0 };     uc.dwStructSize     = sizeof(URL_COMPONENTS);     uc.lpszScheme       = NULL;     uc.dwSchemeLength   = 0;     uc.nScheme          = INTERNET_SCHEME_DEFAULT;     uc.lpszHostName     = szHostName;     uc.dwHostNameLength = ARRAYSIZE(szHostName);     uc.nPort            = 0;     uc.lpszUserName     = szUserName;     uc.dwUserNameLength = ARRAYSIZE(szUserName);     uc.lpszPassword     = szPassword;     uc.dwPasswordLength = ARRAYSIZE(szPassword);     uc.lpszUrlPath      = szPathPart;     uc.dwUrlPathLength  = ARRAYSIZE(szPathPart);     uc.lpszExtraInfo    = NULL;     uc.dwExtraInfoLength= 0;     if (InternetCrackUrl(szFtpUrl, 0, 0, &uc) && (uc.nScheme == INTERNET_SCHEME_FTP))     {         HINTERNET hSession = InternetOpen(szUserAgent, INTERNET_OPEN_TYPE_DIRECT, NULL, NULL, 0);         if (hSession != NULL)         {             HINTERNET hConnect = InternetConnect(hSession, szHostName, uc.nPort, szUserName, szPassword, INTERNET_SERVICE_FTP, INTERNET_FLAG_PASSIVE, 0);             if (hConnect == NULL)             {                 hConnect = InternetConnect(hSession, szHostName, uc.nPort, szUserName, szPassword, INTERNET_SERVICE_FTP, 0, 0);             }             if (hConnect != NULL)             {                 if (FtpSetCurrentDirectory(hConnect, szPathPart))                 {                     WIN32_FIND_DATA wfd = { 0 };                     HINTERNET hFindFile = FtpFindFirstFile(hConnect, NULL, &wfd, INTERNET_FLAG_RELOAD, 0);                     if (hFindFile != NULL)                     {                         do {                             if (wfd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)                             {                                 _tprintf(_T("%s/\n"), wfd.cFileName);                             }                             else                             {                                 _tprintf(_T("%s\n"), wfd.cFileName);                             }                         } while (InternetFindNextFile(hFindFile, (LPVOID)&wfd));                         InternetCloseHandle(hFindFile);                     }                 }                 InternetCloseHandle(hConnect);             }             InternetCloseHandle(hSession);         }     }     return 0; }由于这个 FTP 网站速度慢，所以可能要等几秒钟。 因为我暂时找不到快速的 FTP 来的测试，现在 FTP 服务器太少了。


Question: 大神帮看看这个算偏题吗？

实现了要求的功能就不偏题，至于是MFC还是VCL做界面不是主要的，甚至不是必要的（但肯定比控制台界面加分）

不算

为什么不问问你们老师呢，一般毕设不是自己可以自己选题吗，哪怕老师定的题目也可以商讨改动。个人觉得是可以，但我不敢保证你们老师心里到底怎么想的


Question: linux read函数

写个while循环，没有数据就持续读

文件本来缺省就阻塞的啊.   你要等着后来有人写了再读就在个循环里 select 有数据再读呗...

没有办法 设置堵塞么!

getchar（）； 只有当你在键盘上按一个字符时程序才会接着向下走 或者你先判断一下这个文件是不是空的，非空再继续


Question: 用C语言编写雅瑟夫问题。。。对！又是雅瑟夫。。。

就是malloc和free。

数组啊，因为负数编号不会出现，凡是出列的，置为 -1 或者 该书的相反数 即可 把数组当成循环队列用，其中 负数跳过（认为不是队列的成员即可）


Question: while（ch=getchar()!='#'）与while（（ch=getchar()）!='#'）有什么区别

2楼正解。 优先级问题

运算优先级不要依靠设定的来，还是要靠自己加括号，易读，不易出错，不需要去记忆各种优先级

引用 楼主 qq_34921840 的回复:下面这两个程序运行结果不一样 为什么？ #include <stdio.h> void main() { 	int line,space,other; 	char ch; 	line=0; 	space=0; 	other=0; 	while(ch=getchar()!='#') 	{ 		if(ch==' ')  			space++; 		else 			if(ch=='\n') line++; 				else  					other++; 		 	} 	printf("%d %d %d\n",space,line,other); }   #include <stdio.h> void main() { 	int line,space,other; 	char ch; 	line=0; 	space=0; 	other=0; 	while(（ch=getchar()）!='#') 	{ 		if(ch==' ')  			space++; 		else 			if(ch=='\n') line++; 				else  					other++; 		 	} 	printf("%d %d %d\n",space,line,other); }  倾向6楼的建议，多加（）好处多。

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

运算符优先级的问题，如果不清楚的话，建议多使用括号

楼上都给你说了，运算符优先级问题 所以写代码的时候，最好对于有多个运算符的增加括号明确运算顺序 不要交给默认的优先级 自己容易搞糊涂，别人读起来困难，出了问题也不好跟踪

优先级问题，前者ch等于  (getchar()!='#') 的计算结果（0或1），后者是ch = getchar()， 并判断ch是否等于'#'

前面的是将获取的字符先判断是否为字符#，然后在赋值给ch。 而后面的是先将获取的字符赋值给ch，在进行判断是否为字符#。只是!=和=的优先级的问题，你回去好好看下

遇到疑惑，不清楚走向的，还是多加括号，这可是个好习惯哦，尤其在那一堆运算符大杂烩的地方

!=的优先级大于= 所以你如果不加上括号的话while（ch=getchar()!='#'） 就会先计算getchar()!='#'，然后再将结果赋给ch


Question: [求助]我修改链表内某一成员后显示设备信息报错了 应该怎么改

引用 2 楼 qq423399099 的回复:稍微发现了几个问题 1.modifty函数内没有对p分配空间，直接就fread(p,sizeof(Equip),1,fp);了 2.modifty函数内i没有初始化 3.你fwrite以后应该重新fseek一下你的文件指针（你的代码里就算找到了equipCode也会循环到文件末尾）  代码功能归根结底不是别人帮自己看或讲解或注释出来的；而是被自己静下心来花足够长的时间和精力亲自动手单步或设断点或对执行到某步获得的中间结果显示或写到日志文件中一步一步分析出来的。 提醒：再牛×的老师也无法代替学生自己领悟和上厕所！  单步调试和设断点调试（VS IDE中编译连接通过以后，按F10或F11键单步执行，按Shift+F11退出当前函数；在某行按F9设断点后按F5执行停在该断点处。）是程序员必须掌握的技能之一。  所谓修改删除文件a某位置的内容，其实是读打开文件a，再将‘a中修改删除位置之前的内容＋修改删除的内容＋a中修改删除位置之后的内容’保存到文件b，关闭文件a，删除文件a，将文件b改名为与之前文件a相同的名字，仅此而已。 不要意思我又有问题了 大概这应该是最后一个了 typedef struct Equip   //定义结构体  {  	char equipCode[10];    //编号       	char equipType[20];    //种类   	char equipName[20];    //名称    	float  equipPrice;     //价格  	char buyDate[20];      //购买日期    	int   scrap;           //是否报废   	char  scrapDate[20];  //报废日期 	struct Equip *next;   }   Equip;  int addition(); int modifty(); int input(); int displayEquips(); //int total(); int main()        /*添加模块*/ {  int n,w,t;   	for(t=0;t<1;t++) 	{  	do  	{ 		system("cls");   		puts("\t\t**************************MENU***************************\n");  		puts("\t\t    **           0.     添加设备信息           **\n");  		puts("\t\t    **           1.     追加设备信息           **\n");  		puts("\t\t    **           2.     修改设备信息           **\n"); 	 	puts("\t\t    **           3.     分类统计信息           **\n"); 	 	puts("\t\t    **           4.     搜索设备信息           **\n");  		puts("\t\t    **           5.     退出管理系统           **\n");  		puts("\t\t    **           6.     显示设备信息           **\n");  		puts("\t\t**********************************************************\n"); 	 	printf("你想做什么？(0-6):");  		scanf("%d",&n);   		if(n<0||n>6)           /*对选择的数字作出判断*/ 	 	{  		w=1;   	  	getchar();  		}   		else  		w=0;	 	}   	while(w==1);    	switch(n)    	{         	case 0:t=addition(); break;    /*输入模块*/   	case 1:t=input();break; //追加模块      	case 2:t=modifty();break;  /*修改模块*/     	//case 3:t=total();break;     /*统计模块*/     //	case 4:t=search();break;   /*搜索模块*/     	case 5:exit(0);           /*退出*/ 	case 6:t=displayEquips();break;  	}		  	} }   int addition() { 	int c; 	FILE *fp;  	Equip *Head,*p;  	char st[]="No"; 	system("cls"); 	Head=(struct Equip*)malloc(sizeof(struct Equip));  	Head->next=NULL; 	printf("**********************************************************\n");    	printf("添加设备：\n");      	printf("**********************************************************\n");   	fp=fopen("Equip.txt","wb+");	 	if(fp==NULL) 	{ 		printf("不能打开Equip.txt文件\n"); 	}		 	fseek(fp,0,0); 	while(1) 	{ 		p=(struct Equip*)malloc(sizeof(struct Equip)); 		printf("请输入设备编号\n"); 		scanf("%s",&(p->equipCode)); 		printf("请输入设备种类\n"); 		scanf("%s",&(p->equipType));       		printf("请输入设备名称\n"); 		scanf("%s",&(p->equipName)); 		printf("请输入设备价格\n"); 		scanf("%f",&(p->equipPrice)); 		printf("输入购买日期\n");        		scanf("%s",&(p->buyDate));  		printf("是否报废？0/1\n"); 		scanf("%d",&(p->scrap)); 		 		if(p->scrap==1) 		{ 			printf("请输入报废日期\n"); 			scanf("%s",&(p->scrapDate));  		} 		else 		strcpy(p->scrapDate,st); 		fwrite(p,sizeof(Equip),1,fp); 		p->next=Head->next; 		Head->next=p; 		printf("还想继续输入吗？\n"); 		printf("1.是\n"); 		printf("2.不是\n");  		scanf("%d",&c); 		if(c==2) 		{ 		 		break;	 		} 	}	 	 		//p=Head->next; 		fseek(fp,0,0); 		fread(p,sizeof(Equip),1,fp); 		printf("编号\t种类\t名称\t价格\t\t购买日期\t是否报废\t报废日期\n"); 	//while(p!=NULL) 	while(!feof(fp))  	{ 		printf("%s\t%s\t%s\t%f\t%s\t\t%d\t\t%s\n",p->equipCode,p->equipType,p->equipName,p->equipPrice,p->buyDate,p->scrap,p->scrapDate); 		fread(p,sizeof(Equip),1,fp); 	//	p=p->next; }	 	printf("\n-----------------------\n");    	printf("返回菜单？   \n");                                                                                printf("1.是\n");   	printf("2.不，退出\n");  	scanf("%d",&c);  	if(c==1)return(-1);   	if(c==2)return(0);     } int input() { 		int c; 	FILE *fp;  	Equip *Head,*p;  	char st[]="No"; 	system("cls");	 	printf("**********************************************************\n");    	printf("添加设备：\n");      	printf("**********************************************************\n");   	fp=fopen("Equip.txt","ab+");	 	Head=(struct Equip*)malloc(sizeof(struct Equip));  	//p=(struct Equip*)malloc(sizeof(struct Equip));  	if(fp==NULL) 	{ 		printf("不能打开Equip.txt文件，自动执行系统初始化功能!\n"); 	}		 	fseek(fp,0,2); 	while(1) 	{ 		p=(struct Equip*)malloc(sizeof(struct Equip)); 		printf("请输入设备编号\n"); 		scanf("%s",&(p->equipCode)); 		printf("请输入设备种类\n"); 		scanf("%s",&(p->equipType));       		printf("请输入设备名称\n"); 		scanf("%s",&(p->equipName)); 		printf("请输入设备价格\n"); 		scanf("%f",&(p->equipPrice)); 		printf("输入购买日期\n");        		scanf("%s",&(p->buyDate));  		printf("是否报废？0/1\n"); 		scanf("%d",&(p->scrap));		 		if(p->scrap==1) 		{ 			printf("请输入报废日期\n"); 			scanf("%s",&(p->scrapDate));  		} 		else 		strcpy(p->scrapDate,st); 		fwrite(p,sizeof(Equip),1,fp); 		p->next=p; 		printf("还想继续输入吗？\n"); 		printf("1.是\n"); 		printf("2.不是\n");  		scanf("%d",&c); 		if(c==2) 		{ 		break;	 		} 		printf("\n------------------------------------\n");  		printf("返回菜单？   \n"); 	 	printf("1.是 \n"); 		printf("2.不，退出\n");  		scanf("%d",&c);  		if(c==1)return(-1); 	 	if(c==2)return(0);  }		 int modifty()        /*修改模块*/ {  	char st[]="No"; 	char code[10];  	int i=0,j,c; 	Equip *Head,*p;  	FILE *fp;    	system("cls");  	printf("**********************************************************\n"); 	printf("修改设备信息：\n");   	printf("**********************************************************\n"); 	printf("请输入要修改的设备编号：\n");   	scanf("%s",code);                        /*输入要修改的设备编号*/ 	printf("------------------------------------\n");   	if((fp=fopen("Equip.txt","rt+"))==NULL)  	{    		printf("\n不能打开文件!\n"); 	}   	p=(struct Equip*)malloc(sizeof(struct Equip)); 	fseek(fp,0,0); 	fread(p,sizeof(Equip),1,fp); 	while(!feof(fp))     //从文件头一个一个的读取字符，读到文件的结尾。 	{ 	 		if(strcmp(p->equipCode,code)==0)//判断文件中的数据与输入数是否匹配 	 	{  			printf("------------------\n"); 		 	printf("输入新设备编号\n"); 		 	scanf("%s",&(p->equipCode));  			printf("输入新设备种类\n");  			scanf("%s",&(p->equipType));  			printf("输入新设备名称\n"); 		 	scanf("%s",&(p->equipName));  			printf("输入新设备价格\n"); 		 	scanf("%f",&(p->equipPrice)); 		 	printf("输入新购买日期\n");  		 	scanf("%s",&(p->buyDate));                    //判断是否报废  		 	printf("输入新是否报废？0/1\n");  		  	scanf("%d",&(p->scrap)); 			  	if(p->scrap==1) 		{ 			printf("请输入新报废日期\n"); 			scanf("%s",&(p->scrapDate));  		} 		else 			strcpy(p->scrapDate,st); 			fseek(fp,sizeof(Equip)*(-1),1); 			fwrite(p,sizeof(Equip),1,fp);      		break; 		} 		fread(p,sizeof(Equip),1,fp); 		p=p->next; 		i++; 	} 		printf("修改后的设备信息:\n"); 		fseek(fp,sizeof(Equip)*(i),0); 		fread(p,sizeof(Equip),1,fp); 		printf("编号\t种类\t名称\t价格\t\t购买日期\t是否报废\t报废日期\n"); 		printf("%s\t%s\t%s\t%f\t%s\t\t%d\t\t%s\n",p->equipCode,p->equipType,p->equipName,p->equipPrice,p->buyDate,p->scrap,p->scrapDate);       	    printf("\n------------------------------------\n");  		printf("返回菜单？   \n"); 	 	printf("1.是 \n"); 		printf("2.不，退出\n");  		scanf("%d",&c);  		if(c==1)return(-1); 	 	if(c==2)return(0);  }  int displayEquips() { 	int c; 	FILE *fp; 	system("cls"); 	fp=fopen("Equip.txt","rb");	 	if(fp==NULL) 	{ 		printf("不能打开Equip.txt文件\n"); 	}		 	Equip *p; 	p=(struct Equip*)malloc(sizeof(struct Equip)); 	fseek(fp,0,0); 	printf("编号\t种类\t名称\t价格\t\t购买日期\t是否报废\t报废日期\n"); 	fread(p,sizeof(Equip),1,fp); 	while(!feof(fp)) 	{ 		printf("%s\t%s\t%s\t%f\t%s\t\t%d\t\t%s\n",p->equipCode,p->equipType,p->equipName,p->equipPrice,p->buyDate,p->scrap,p->scrapDate);     		fread(p,sizeof(Equip),1,fp); 	} 	printf("\n------------------------------------\n");  	printf("返回菜单？   \n"); 	printf("1.是 \n"); 	printf("2.不，退出\n");  	scanf("%d",&c);  	if(c==1)return(-1); 	if(c==2)return(0);  } }我想用input函数追加信息    把追加信息接到用p->next=p的接到p链表上   用displayEquips可以显示 但是用修改信息的函数我追加的信息就不能修改  但是我最开始用additon函数输入的信息就能修改  请给点看法和意见吧

引用 7 楼 qq423399099 的回复:[quote=引用 6 楼 zywd4200 的回复:] [quote=引用 2 楼 qq423399099 的回复:] 稍微发现了几个问题 1.modifty函数内没有对p分配空间，直接就fread(p,sizeof(Equip),1,fp);了 2.modifty函数内i没有初始化 3.你fwrite以后应该重新fseek一下你的文件指针（你的代码里就算找到了equipCode也会循环到文件末尾）  代码功能归根结底不是别人帮自己看或讲解或注释出来的；而是被自己静下心来花足够长的时间和精力亲自动手单步或设断点或对执行到某步获得的中间结果显示或写到日志文件中一步一步分析出来的。 提醒：再牛×的老师也无法代替学生自己领悟和上厕所！  单步调试和设断点调试（VS IDE中编译连接通过以后，按F10或F11键单步执行，按Shift+F11退出当前函数；在某行按F9设断点后按F5执行停在该断点处。）是程序员必须掌握的技能之一。  所谓修改删除文件a某位置的内容，其实是读打开文件a，再将‘a中修改删除位置之前的内容＋修改删除的内容＋a中修改删除位置之后的内容’保存到文件b，关闭文件a，删除文件a，将文件b改名为与之前文件a相同的名字，仅此而已。 不要意思我又有问题了 大概这应该是最后一个了 typedef struct Equip   //定义结构体  {  	char equipCode[10];    //编号       	char equipType[20];    //种类   	char equipName[20];    //名称    	float  equipPrice;     //价格  	char buyDate[20];      //购买日期    	int   scrap;           //是否报废   	char  scrapDate[20];  //报废日期 	struct Equip *next;   }   Equip;  int addition(); int modifty(); int input(); int displayEquips(); //int total(); int main()        /*添加模块*/ {  int n,w,t;   	for(t=0;t<1;t++) 	{  	do  	{ 		system("cls");   		puts("\t\t**************************MENU***************************\n");  		puts("\t\t    **           0.     添加设备信息           **\n");  		puts("\t\t    **           1.     追加设备信息           **\n");  		puts("\t\t    **           2.     修改设备信息           **\n"); 	 	puts("\t\t    **           3.     分类统计信息           **\n"); 	 	puts("\t\t    **           4.     搜索设备信息           **\n");  		puts("\t\t    **           5.     退出管理系统           **\n");  		puts("\t\t    **           6.     显示设备信息           **\n");  		puts("\t\t**********************************************************\n"); 	 	printf("你想做什么？(0-6):");  		scanf("%d",&n);   		if(n<0||n>6)           /*对选择的数字作出判断*/ 	 	{  		w=1;   	  	getchar();  		}   		else  		w=0;	 	}   	while(w==1);    	switch(n)    	{         	case 0:t=addition(); break;    /*输入模块*/   	case 1:t=input();break; //追加模块      	case 2:t=modifty();break;  /*修改模块*/     	//case 3:t=total();break;     /*统计模块*/     //	case 4:t=search();break;   /*搜索模块*/     	case 5:exit(0);           /*退出*/ 	case 6:t=displayEquips();break;  	}		  	} }   int addition() { 	int c; 	FILE *fp;  	Equip *Head,*p;  	char st[]="No"; 	system("cls"); 	Head=(struct Equip*)malloc(sizeof(struct Equip));  	Head->next=NULL; 	printf("**********************************************************\n");    	printf("添加设备：\n");      	printf("**********************************************************\n");   	fp=fopen("Equip.txt","wb+");	 	if(fp==NULL) 	{ 		printf("不能打开Equip.txt文件\n"); 	}		 	fseek(fp,0,0); 	while(1) 	{ 		p=(struct Equip*)malloc(sizeof(struct Equip)); 		printf("请输入设备编号\n"); 		scanf("%s",&(p->equipCode)); 		printf("请输入设备种类\n"); 		scanf("%s",&(p->equipType));       		printf("请输入设备名称\n"); 		scanf("%s",&(p->equipName)); 		printf("请输入设备价格\n"); 		scanf("%f",&(p->equipPrice)); 		printf("输入购买日期\n");        		scanf("%s",&(p->buyDate));  		printf("是否报废？0/1\n"); 		scanf("%d",&(p->scrap)); 		 		if(p->scrap==1) 		{ 			printf("请输入报废日期\n"); 			scanf("%s",&(p->scrapDate));  		} 		else 		strcpy(p->scrapDate,st); 		fwrite(p,sizeof(Equip),1,fp); 		p->next=Head->next; 		Head->next=p; 		printf("还想继续输入吗？\n"); 		printf("1.是\n"); 		printf("2.不是\n");  		scanf("%d",&c); 		if(c==2) 		{ 		 		break;	 		} 	}	 	 		//p=Head->next; 		fseek(fp,0,0); 		fread(p,sizeof(Equip),1,fp); 		printf("编号\t种类\t名称\t价格\t\t购买日期\t是否报废\t报废日期\n"); 	//while(p!=NULL) 	while(!feof(fp))  	{ 		printf("%s\t%s\t%s\t%f\t%s\t\t%d\t\t%s\n",p->equipCode,p->equipType,p->equipName,p->equipPrice,p->buyDate,p->scrap,p->scrapDate); 		fread(p,sizeof(Equip),1,fp); 	//	p=p->next; }	 	printf("\n-----------------------\n");    	printf("返回菜单？   \n");                                                                                printf("1.是\n");   	printf("2.不，退出\n");  	scanf("%d",&c);  	if(c==1)return(-1);   	if(c==2)return(0);     } int input() { 		int c; 	FILE *fp;  	Equip *Head,*p;  	char st[]="No"; 	system("cls");	 	printf("**********************************************************\n");    	printf("添加设备：\n");      	printf("**********************************************************\n");   	fp=fopen("Equip.txt","ab+");	 	Head=(struct Equip*)malloc(sizeof(struct Equip));  	//p=(struct Equip*)malloc(sizeof(struct Equip));  	if(fp==NULL) 	{ 		printf("不能打开Equip.txt文件，自动执行系统初始化功能!\n"); 	}		 	fseek(fp,0,2); 	while(1) 	{ 		p=(struct Equip*)malloc(sizeof(struct Equip)); 		printf("请输入设备编号\n"); 		scanf("%s",&(p->equipCode)); 		printf("请输入设备种类\n"); 		scanf("%s",&(p->equipType));       		printf("请输入设备名称\n"); 		scanf("%s",&(p->equipName)); 		printf("请输入设备价格\n"); 		scanf("%f",&(p->equipPrice)); 		printf("输入购买日期\n");        		scanf("%s",&(p->buyDate));  		printf("是否报废？0/1\n"); 		scanf("%d",&(p->scrap));		 		if(p->scrap==1) 		{ 			printf("请输入报废日期\n"); 			scanf("%s",&(p->scrapDate));  		} 		else 		strcpy(p->scrapDate,st); 		fwrite(p,sizeof(Equip),1,fp); 		p->next=p; 		printf("还想继续输入吗？\n"); 		printf("1.是\n"); 		printf("2.不是\n");  		scanf("%d",&c); 		if(c==2) 		{ 		break;	 		} 		printf("\n------------------------------------\n");  		printf("返回菜单？   \n"); 	 	printf("1.是 \n"); 		printf("2.不，退出\n");  		scanf("%d",&c);  		if(c==1)return(-1); 	 	if(c==2)return(0);  }		 int modifty()        /*修改模块*/ {  	char st[]="No"; 	char code[10];  	int i=0,j,c; 	Equip *Head,*p;  	FILE *fp;    	system("cls");  	printf("**********************************************************\n"); 	printf("修改设备信息：\n");   	printf("**********************************************************\n"); 	printf("请输入要修改的设备编号：\n");   	scanf("%s",code);                        /*输入要修改的设备编号*/ 	printf("------------------------------------\n");   	if((fp=fopen("Equip.txt","rt+"))==NULL)  	{    		printf("\n不能打开文件!\n"); 	}   	p=(struct Equip*)malloc(sizeof(struct Equip)); 	fseek(fp,0,0); 	fread(p,sizeof(Equip),1,fp); 	while(!feof(fp))     //从文件头一个一个的读取字符，读到文件的结尾。 	{ 	 		if(strcmp(p->equipCode,code)==0)//判断文件中的数据与输入数是否匹配 	 	{  			printf("------------------\n"); 		 	printf("输入新设备编号\n"); 		 	scanf("%s",&(p->equipCode));  			printf("输入新设备种类\n");  			scanf("%s",&(p->equipType));  			printf("输入新设备名称\n"); 		 	scanf("%s",&(p->equipName));  			printf("输入新设备价格\n"); 		 	scanf("%f",&(p->equipPrice)); 		 	printf("输入新购买日期\n");  		 	scanf("%s",&(p->buyDate));                    //判断是否报废  		 	printf("输入新是否报废？0/1\n");  		  	scanf("%d",&(p->scrap)); 			  	if(p->scrap==1) 		{ 			printf("请输入新报废日期\n"); 			scanf("%s",&(p->scrapDate));  		} 		else 			strcpy(p->scrapDate,st); 			fseek(fp,sizeof(Equip)*(-1),1); 			fwrite(p,sizeof(Equip),1,fp);      		break; 		} 		fread(p,sizeof(Equip),1,fp); 		p=p->next; 		i++; 	} 		printf("修改后的设备信息:\n"); 		fseek(fp,sizeof(Equip)*(i),0); 		fread(p,sizeof(Equip),1,fp); 		printf("编号\t种类\t名称\t价格\t\t购买日期\t是否报废\t报废日期\n"); 		printf("%s\t%s\t%s\t%f\t%s\t\t%d\t\t%s\n",p->equipCode,p->equipType,p->equipName,p->equipPrice,p->buyDate,p->scrap,p->scrapDate);       	    printf("\n------------------------------------\n");  		printf("返回菜单？   \n"); 	 	printf("1.是 \n"); 		printf("2.不，退出\n");  		scanf("%d",&c);  		if(c==1)return(-1); 	 	if(c==2)return(0);  }  int displayEquips() { 	int c; 	FILE *fp; 	system("cls"); 	fp=fopen("Equip.txt","rb");	 	if(fp==NULL) 	{ 		printf("不能打开Equip.txt文件\n"); 	}		 	Equip *p; 	p=(struct Equip*)malloc(sizeof(struct Equip)); 	fseek(fp,0,0); 	printf("编号\t种类\t名称\t价格\t\t购买日期\t是否报废\t报废日期\n"); 	fread(p,sizeof(Equip),1,fp); 	while(!feof(fp)) 	{ 		printf("%s\t%s\t%s\t%f\t%s\t\t%d\t\t%s\n",p->equipCode,p->equipType,p->equipName,p->equipPrice,p->buyDate,p->scrap,p->scrapDate);     		fread(p,sizeof(Equip),1,fp); 	} 	printf("\n------------------------------------\n");  	printf("返回菜单？   \n"); 	printf("1.是 \n"); 	printf("2.不，退出\n");  	scanf("%d",&c);  	if(c==1)return(-1); 	if(c==2)return(0);  } }我想用input函数追加信息    把追加信息接到用p->next=p的接到p链表上   用displayEquips可以显示 但是用修改信息的函数我追加的信息就不能修改  但是我最开始用additon函数输入的信息就能修改  请给点看法和意见吧[/quote] 还不如重新存一个新文件，然后删了旧文件[/quote]每次追加都重新存一个然后删掉旧的吗  0 0

引用 6 楼 zywd4200 的回复:[quote=引用 2 楼 qq423399099 的回复:] 稍微发现了几个问题 1.modifty函数内没有对p分配空间，直接就fread(p,sizeof(Equip),1,fp);了 2.modifty函数内i没有初始化 3.你fwrite以后应该重新fseek一下你的文件指针（你的代码里就算找到了equipCode也会循环到文件末尾）  代码功能归根结底不是别人帮自己看或讲解或注释出来的；而是被自己静下心来花足够长的时间和精力亲自动手单步或设断点或对执行到某步获得的中间结果显示或写到日志文件中一步一步分析出来的。 提醒：再牛×的老师也无法代替学生自己领悟和上厕所！  单步调试和设断点调试（VS IDE中编译连接通过以后，按F10或F11键单步执行，按Shift+F11退出当前函数；在某行按F9设断点后按F5执行停在该断点处。）是程序员必须掌握的技能之一。  所谓修改删除文件a某位置的内容，其实是读打开文件a，再将‘a中修改删除位置之前的内容＋修改删除的内容＋a中修改删除位置之后的内容’保存到文件b，关闭文件a，删除文件a，将文件b改名为与之前文件a相同的名字，仅此而已。 不要意思我又有问题了 大概这应该是最后一个了 typedef struct Equip   //定义结构体  {  	char equipCode[10];    //编号       	char equipType[20];    //种类   	char equipName[20];    //名称    	float  equipPrice;     //价格  	char buyDate[20];      //购买日期    	int   scrap;           //是否报废   	char  scrapDate[20];  //报废日期 	struct Equip *next;   }   Equip;  int addition(); int modifty(); int input(); int displayEquips(); //int total(); int main()        /*添加模块*/ {  int n,w,t;   	for(t=0;t<1;t++) 	{  	do  	{ 		system("cls");   		puts("\t\t**************************MENU***************************\n");  		puts("\t\t    **           0.     添加设备信息           **\n");  		puts("\t\t    **           1.     追加设备信息           **\n");  		puts("\t\t    **           2.     修改设备信息           **\n"); 	 	puts("\t\t    **           3.     分类统计信息           **\n"); 	 	puts("\t\t    **           4.     搜索设备信息           **\n");  		puts("\t\t    **           5.     退出管理系统           **\n");  		puts("\t\t    **           6.     显示设备信息           **\n");  		puts("\t\t**********************************************************\n"); 	 	printf("你想做什么？(0-6):");  		scanf("%d",&n);   		if(n<0||n>6)           /*对选择的数字作出判断*/ 	 	{  		w=1;   	  	getchar();  		}   		else  		w=0;	 	}   	while(w==1);    	switch(n)    	{         	case 0:t=addition(); break;    /*输入模块*/   	case 1:t=input();break; //追加模块      	case 2:t=modifty();break;  /*修改模块*/     	//case 3:t=total();break;     /*统计模块*/     //	case 4:t=search();break;   /*搜索模块*/     	case 5:exit(0);           /*退出*/ 	case 6:t=displayEquips();break;  	}		  	} }   int addition() { 	int c; 	FILE *fp;  	Equip *Head,*p;  	char st[]="No"; 	system("cls"); 	Head=(struct Equip*)malloc(sizeof(struct Equip));  	Head->next=NULL; 	printf("**********************************************************\n");    	printf("添加设备：\n");      	printf("**********************************************************\n");   	fp=fopen("Equip.txt","wb+");	 	if(fp==NULL) 	{ 		printf("不能打开Equip.txt文件\n"); 	}		 	fseek(fp,0,0); 	while(1) 	{ 		p=(struct Equip*)malloc(sizeof(struct Equip)); 		printf("请输入设备编号\n"); 		scanf("%s",&(p->equipCode)); 		printf("请输入设备种类\n"); 		scanf("%s",&(p->equipType));       		printf("请输入设备名称\n"); 		scanf("%s",&(p->equipName)); 		printf("请输入设备价格\n"); 		scanf("%f",&(p->equipPrice)); 		printf("输入购买日期\n");        		scanf("%s",&(p->buyDate));  		printf("是否报废？0/1\n"); 		scanf("%d",&(p->scrap)); 		 		if(p->scrap==1) 		{ 			printf("请输入报废日期\n"); 			scanf("%s",&(p->scrapDate));  		} 		else 		strcpy(p->scrapDate,st); 		fwrite(p,sizeof(Equip),1,fp); 		p->next=Head->next; 		Head->next=p; 		printf("还想继续输入吗？\n"); 		printf("1.是\n"); 		printf("2.不是\n");  		scanf("%d",&c); 		if(c==2) 		{ 		 		break;	 		} 	}	 	 		//p=Head->next; 		fseek(fp,0,0); 		fread(p,sizeof(Equip),1,fp); 		printf("编号\t种类\t名称\t价格\t\t购买日期\t是否报废\t报废日期\n"); 	//while(p!=NULL) 	while(!feof(fp))  	{ 		printf("%s\t%s\t%s\t%f\t%s\t\t%d\t\t%s\n",p->equipCode,p->equipType,p->equipName,p->equipPrice,p->buyDate,p->scrap,p->scrapDate); 		fread(p,sizeof(Equip),1,fp); 	//	p=p->next; }	 	printf("\n-----------------------\n");    	printf("返回菜单？   \n");                                                                                printf("1.是\n");   	printf("2.不，退出\n");  	scanf("%d",&c);  	if(c==1)return(-1);   	if(c==2)return(0);     } int input() { 		int c; 	FILE *fp;  	Equip *Head,*p;  	char st[]="No"; 	system("cls");	 	printf("**********************************************************\n");    	printf("添加设备：\n");      	printf("**********************************************************\n");   	fp=fopen("Equip.txt","ab+");	 	Head=(struct Equip*)malloc(sizeof(struct Equip));  	//p=(struct Equip*)malloc(sizeof(struct Equip));  	if(fp==NULL) 	{ 		printf("不能打开Equip.txt文件，自动执行系统初始化功能!\n"); 	}		 	fseek(fp,0,2); 	while(1) 	{ 		p=(struct Equip*)malloc(sizeof(struct Equip)); 		printf("请输入设备编号\n"); 		scanf("%s",&(p->equipCode)); 		printf("请输入设备种类\n"); 		scanf("%s",&(p->equipType));       		printf("请输入设备名称\n"); 		scanf("%s",&(p->equipName)); 		printf("请输入设备价格\n"); 		scanf("%f",&(p->equipPrice)); 		printf("输入购买日期\n");        		scanf("%s",&(p->buyDate));  		printf("是否报废？0/1\n"); 		scanf("%d",&(p->scrap));		 		if(p->scrap==1) 		{ 			printf("请输入报废日期\n"); 			scanf("%s",&(p->scrapDate));  		} 		else 		strcpy(p->scrapDate,st); 		fwrite(p,sizeof(Equip),1,fp); 		p->next=p; 		printf("还想继续输入吗？\n"); 		printf("1.是\n"); 		printf("2.不是\n");  		scanf("%d",&c); 		if(c==2) 		{ 		break;	 		} 		printf("\n------------------------------------\n");  		printf("返回菜单？   \n"); 	 	printf("1.是 \n"); 		printf("2.不，退出\n");  		scanf("%d",&c);  		if(c==1)return(-1); 	 	if(c==2)return(0);  }		 int modifty()        /*修改模块*/ {  	char st[]="No"; 	char code[10];  	int i=0,j,c; 	Equip *Head,*p;  	FILE *fp;    	system("cls");  	printf("**********************************************************\n"); 	printf("修改设备信息：\n");   	printf("**********************************************************\n"); 	printf("请输入要修改的设备编号：\n");   	scanf("%s",code);                        /*输入要修改的设备编号*/ 	printf("------------------------------------\n");   	if((fp=fopen("Equip.txt","rt+"))==NULL)  	{    		printf("\n不能打开文件!\n"); 	}   	p=(struct Equip*)malloc(sizeof(struct Equip)); 	fseek(fp,0,0); 	fread(p,sizeof(Equip),1,fp); 	while(!feof(fp))     //从文件头一个一个的读取字符，读到文件的结尾。 	{ 	 		if(strcmp(p->equipCode,code)==0)//判断文件中的数据与输入数是否匹配 	 	{  			printf("------------------\n"); 		 	printf("输入新设备编号\n"); 		 	scanf("%s",&(p->equipCode));  			printf("输入新设备种类\n");  			scanf("%s",&(p->equipType));  			printf("输入新设备名称\n"); 		 	scanf("%s",&(p->equipName));  			printf("输入新设备价格\n"); 		 	scanf("%f",&(p->equipPrice)); 		 	printf("输入新购买日期\n");  		 	scanf("%s",&(p->buyDate));                    //判断是否报废  		 	printf("输入新是否报废？0/1\n");  		  	scanf("%d",&(p->scrap)); 			  	if(p->scrap==1) 		{ 			printf("请输入新报废日期\n"); 			scanf("%s",&(p->scrapDate));  		} 		else 			strcpy(p->scrapDate,st); 			fseek(fp,sizeof(Equip)*(-1),1); 			fwrite(p,sizeof(Equip),1,fp);      		break; 		} 		fread(p,sizeof(Equip),1,fp); 		p=p->next; 		i++; 	} 		printf("修改后的设备信息:\n"); 		fseek(fp,sizeof(Equip)*(i),0); 		fread(p,sizeof(Equip),1,fp); 		printf("编号\t种类\t名称\t价格\t\t购买日期\t是否报废\t报废日期\n"); 		printf("%s\t%s\t%s\t%f\t%s\t\t%d\t\t%s\n",p->equipCode,p->equipType,p->equipName,p->equipPrice,p->buyDate,p->scrap,p->scrapDate);       	    printf("\n------------------------------------\n");  		printf("返回菜单？   \n"); 	 	printf("1.是 \n"); 		printf("2.不，退出\n");  		scanf("%d",&c);  		if(c==1)return(-1); 	 	if(c==2)return(0);  }  int displayEquips() { 	int c; 	FILE *fp; 	system("cls"); 	fp=fopen("Equip.txt","rb");	 	if(fp==NULL) 	{ 		printf("不能打开Equip.txt文件\n"); 	}		 	Equip *p; 	p=(struct Equip*)malloc(sizeof(struct Equip)); 	fseek(fp,0,0); 	printf("编号\t种类\t名称\t价格\t\t购买日期\t是否报废\t报废日期\n"); 	fread(p,sizeof(Equip),1,fp); 	while(!feof(fp)) 	{ 		printf("%s\t%s\t%s\t%f\t%s\t\t%d\t\t%s\n",p->equipCode,p->equipType,p->equipName,p->equipPrice,p->buyDate,p->scrap,p->scrapDate);     		fread(p,sizeof(Equip),1,fp); 	} 	printf("\n------------------------------------\n");  	printf("返回菜单？   \n"); 	printf("1.是 \n"); 	printf("2.不，退出\n");  	scanf("%d",&c);  	if(c==1)return(-1); 	if(c==2)return(0);  } }我想用input函数追加信息    把追加信息接到用p->next=p的接到p链表上   用displayEquips可以显示 但是用修改信息的函数我追加的信息就不能修改  但是我最开始用additon函数输入的信息就能修改  请给点看法和意见吧[/quote] 还不如重新存一个新文件，然后删了旧文件

引用 2 楼 qq423399099 的回复:稍微发现了几个问题 1.modifty函数内没有对p分配空间，直接就fread(p,sizeof(Equip),1,fp);了 2.modifty函数内i没有初始化 3.你fwrite以后应该重新fseek一下你的文件指针（你的代码里就算找到了equipCode也会循环到文件末尾）  代码功能归根结底不是别人帮自己看或讲解或注释出来的；而是被自己静下心来花足够长的时间和精力亲自动手单步或设断点或对执行到某步获得的中间结果显示或写到日志文件中一步一步分析出来的。 提醒：再牛×的老师也无法代替学生自己领悟和上厕所！  单步调试和设断点调试（VS IDE中编译连接通过以后，按F10或F11键单步执行，按Shift+F11退出当前函数；在某行按F9设断点后按F5执行停在该断点处。）是程序员必须掌握的技能之一。  所谓修改删除文件a某位置的内容，其实是读打开文件a，再将‘a中修改删除位置之前的内容＋修改删除的内容＋a中修改删除位置之后的内容’保存到文件b，关闭文件a，删除文件a，将文件b改名为与之前文件a相同的名字，仅此而已。 后面这段不是赵老师的名句么。。。

目测你的数据结构是一个链表。 问题应该出在 函数内部变量的生命周期。 链表的头。没有。

引用 2 楼 qq423399099 的回复:稍微发现了几个问题 1.modifty函数内没有对p分配空间，直接就fread(p,sizeof(Equip),1,fp);了 2.modifty函数内i没有初始化 3.你fwrite以后应该重新fseek一下你的文件指针（你的代码里就算找到了equipCode也会循环到文件末尾）  代码功能归根结底不是别人帮自己看或讲解或注释出来的；而是被自己静下心来花足够长的时间和精力亲自动手单步或设断点或对执行到某步获得的中间结果显示或写到日志文件中一步一步分析出来的。 提醒：再牛×的老师也无法代替学生自己领悟和上厕所！  单步调试和设断点调试（VS IDE中编译连接通过以后，按F10或F11键单步执行，按Shift+F11退出当前函数；在某行按F9设断点后按F5执行停在该断点处。）是程序员必须掌握的技能之一。  所谓修改删除文件a某位置的内容，其实是读打开文件a，再将‘a中修改删除位置之前的内容＋修改删除的内容＋a中修改删除位置之后的内容’保存到文件b，关闭文件a，删除文件a，将文件b改名为与之前文件a相同的名字，仅此而已。好的 我试试 谢谢！

添加设备信息的函数可以正常使用  主要是修改设备信息的那个函数出了问题   请各位帮我看看怎么改谢谢了


Question: gtk有没有ip地址输入控件？

能否说得详细点，刚开始学习GTK，谢谢啦

已经搞定了，谢谢这位大神。

CHAPTER 11 Creating Custom Widgets...... Deriving New Widgets........ Creating the MyIPAddress.......

有没有哪位大神知道，谢谢啦


Question: 假设有个1000万或者更多数据的数组，内容无序，如何快速的确定是否存在某个数？

先把数组由小到大排序，然后从n/2处与判断值比较，如果大，则从右边再n/2，以此内推，主要是利用二分法的思想

谢谢大家，是我没有问清楚面试官的意思，到底是 数组组织还是查找的问题

引用 3 楼 mickey736 的回复:建立 哈希表 也需要遍历一次数组吧？ 题目是考的是如何对数据进行索引，以便更加高效地查询；而不是只叫你从这堆无序的数据里面查一个数，如果是真是这样的话，这道题还有考的必要吗？

无序，一次遍历应该是少不了的。遇到就退出，感觉很好了  是不是考官没有把条件全部说出来呢？有其他隐藏的机关？

如果这些数据只是放在一个数组里面，并且你还只是查找这一次的话。 我觉得没有其他好方法，肯定是线性查询，一个一个的找。  反过来，我觉得这道题目是考你怎么组织这些数据，可能在组织数据的时候 需要更加花时间，但是以后多次查询就可以更加高效了。  那么可以使用的方法非常多，常见的方法有Hash法、Bit-map法、Bloom filter法、数据库优化法、倒排索引法、外排序法、Trie树、堆、双层桶法以及MapReduce法。

建立 哈希表 也需要遍历一次数组吧？

先做一次哈希，再查找

是位图吗？应该主要是因为数据大的问题，存不下吧？


Question: 关于常见哈希函数的疑问，求大神解惑！！

我认为不仅仅是要让index为正数,还要在计算散列时h(k) = k mod m中的k尽量分散,减少碰撞的发生吧

本质是去除hashcode的符号

引用 6 楼 qq423399099 的回复:第一个问题：是的，如果第一位大于7，意味着二进制第一位相与以后可能会出现1 第二个问题：malloc只是申请一片连续的内存空间，主要和你用什么来接收这个申请的内存首地址有关  OK，了解了。多谢

引用 2 楼 qq423399099 的回复:关键在于一个对象的 HashCode可以为负数，这样操作后可以保证它为一个正整数 0x7FFFFFFF is 0111 1111 1111 1111 1111 1111 1111 1111 : all 1 except the sign bit. (hash & 0x7FFFFFFF) 将会得到一个正整数 因为你的hash是要作为数组的index的，这样可以避免出现下标为负数而出现异常  在这里顺便再问你一个问题，就是对于动态数组形式比如说：  int **arr;  这种形式可以解释成是 int  型的二维数组，也可以解释成是 int * 型的一维数组，那么在 c 中是怎么分辨到底应该解释成那种形式呢？是根据 malloc 的时候 sizeof(类型) 这里确定吗？

引用 2 楼 qq423399099 的回复:关键在于一个对象的 HashCode可以为负数，这样操作后可以保证它为一个正整数 0x7FFFFFFF is 0111 1111 1111 1111 1111 1111 1111 1111 : all 1 except the sign bit. (hash & 0x7FFFFFFF) 将会得到一个正整数 因为你的hash是要作为数组的index的，这样可以避免出现下标为负数而出现异常  引用错了。。。  得到正整数是因为二进制第一位是 0 是吗？ 因为如果第一位大于 7 的话二进制的第一位会变成 1，1 的话同负数进行 & 运算还是负数。

引用 1 楼 user-4 的回复:0x7FFFFFFF 是质数，0xFFFFFFFF 不是  得到正整数是因为二进制第一位是 0 是吗？ 因为如果第一位大于 7 的话二进制的第一位会变成 1，1 的话同负数进行 & 运算还是负数。

0x7FFFFFFF 是质数，0xFFFFFFFF 不是


Question: 求助求助

引用 8 楼 xiaot_cs001 的回复:[quote=引用 4 楼 zhao4zhong1 的回复:] 理解和讨论之前请先学会如何观察！  计算机组成原理→DOS命令→汇编语言→C语言（不包括C++）、代码书写规范→数据结构、编译原理、操作系统→计算机网络、数据库原理、正则表达式→其它语言（包括C++）、架构……  对学习编程者的忠告： 多用小脑和手，少用大脑、眼睛和嘴，会更快地学会编程！ 眼过千遍不如手过一遍！ 书看千行不如手敲一行！ 手敲千行不如单步一行！ 单步源代码千行不如单步Debug版对应汇编一行！ 单步Debug版对应汇编千行不如单步Release版对应汇编一行！ 不会单步Release版对应汇编？在你想单步Release版C/C++代码片断的前面临时加一句DebugBreak();重建所有，然后在IDE中运行。（一般人我不告诉他！）  单步类的实例“构造”或“复制”或“作为函数参数”或“作为函数返回值返回”或“参加各种运算”或“退出作用域”的语句对应的汇编代码几步后，就会来到该类的“构造函数”或“复制构造函数”或“运算符重载”或“析构函数”对应的C/C++源代码处。  VC调试时按Alt+8、Alt+7、Alt+6和Alt+5,打开汇编窗口、堆栈窗口、内存窗口和寄存器窗口看每句C对应的汇编、单步执行并观察相应堆栈、内存和寄存器变化，这样过一遍不就啥都明白了吗。 对VC来说，所谓‘调试时’就是编译连接通过以后，按F10或F11键单步执行一步以后的时候，或者在某行按F9设了断点后按F5执行停在该断点处的时候。您好，借个楼请教一个问题：C语言怎么像从标准输入流那样从字符串中读取指定格式的数据？sscanf函数是可以，但是每次调用的时候都是从字符串的首部开始读，不能像从标准输入流读取那样，每次读取的会被取走，下一次会从之后的位置开始读取？[/quote] 答案就在3楼，请您老开法眼仔细观瞧。

引用 4 楼 zhao4zhong1 的回复:理解和讨论之前请先学会如何观察！  计算机组成原理→DOS命令→汇编语言→C语言（不包括C++）、代码书写规范→数据结构、编译原理、操作系统→计算机网络、数据库原理、正则表达式→其它语言（包括C++）、架构……  对学习编程者的忠告： 多用小脑和手，少用大脑、眼睛和嘴，会更快地学会编程！ 眼过千遍不如手过一遍！ 书看千行不如手敲一行！ 手敲千行不如单步一行！ 单步源代码千行不如单步Debug版对应汇编一行！ 单步Debug版对应汇编千行不如单步Release版对应汇编一行！ 不会单步Release版对应汇编？在你想单步Release版C/C++代码片断的前面临时加一句DebugBreak();重建所有，然后在IDE中运行。（一般人我不告诉他！）  单步类的实例“构造”或“复制”或“作为函数参数”或“作为函数返回值返回”或“参加各种运算”或“退出作用域”的语句对应的汇编代码几步后，就会来到该类的“构造函数”或“复制构造函数”或“运算符重载”或“析构函数”对应的C/C++源代码处。  VC调试时按Alt+8、Alt+7、Alt+6和Alt+5,打开汇编窗口、堆栈窗口、内存窗口和寄存器窗口看每句C对应的汇编、单步执行并观察相应堆栈、内存和寄存器变化，这样过一遍不就啥都明白了吗。 对VC来说，所谓‘调试时’就是编译连接通过以后，按F10或F11键单步执行一步以后的时候，或者在某行按F9设了断点后按F5执行停在该断点处的时候。您好，借个楼请教一个问题：C语言怎么像从标准输入流那样从字符串中读取指定格式的数据？sscanf函数是可以，但是每次调用的时候都是从字符串的首部开始读，不能像从标准输入流读取那样，每次读取的会被取走，下一次会从之后的位置开始读取？

这书写得非常不严谨。在书里这个地方应该说是“当在scanf()中指定按%d格式读取输入的时候”，才成立，否则就都是谬误。 因为当指定按照%d格式读取输入时，遇到非数字的字母，比如A，就不会当作数字读取了。

不要迷信书、考题、老师、回帖； 要迷信CPU、编译器、调试器、运行结果。 并请结合“盲人摸太阳”和“驾船出海时一定只带一个指南针。”加以理解。 任何理论、权威、传说、真理、标准、解释、想象、知识……都比不上摆在眼前的事实！  电脑内存或文件内容只是一个一维二进制字节数组及其对应的二进制地址； 人脑才将电脑内存或文件内容中的这个一维二进制字节数组及其对应的二进制地址的某些部分看成是整数、有符号数/无符号数、浮点数、复数、英文字母、阿拉伯数字、中文/韩文/法文……字符/字符串、汇编指令、函数、函数参数、堆、栈、数组、指针、数组指针、指针数组、数组的数组、指针的指针、二维数组、字符点阵、字符笔画的坐标、黑白二值图片、灰度图片、彩色图片、录音、视频、指纹信息、身份证信息……  推荐使用WinHex软件查看硬盘或文件或内存中的原始字节内容。

仅供参考：#include <stdio.h> char s[]="123 ab 4"; char *p; int v,n,k; void main() {     p=s;     while (1) {         k=sscanf(p,"%d%n",&v,&n);         printf("k,v,n=%d,%d,%d\n",k,v,n);         if (1==k) {             p+=n;         } else if (0==k) {             printf("skip char[%c]\n",p[0]);             p++;         } else {//EOF==k             break;         }     }     printf("End.\n"); } //k,v,n=1,123,3 //k,v,n=0,123,3 //skip char[ ] //k,v,n=0,123,3 //skip char[a] //k,v,n=0,123,3 //skip char[b] //k,v,n=1,4,2 //k,v,n=-1,4,2 //End.

1.通过scanf函数的返回值来验证输入的合法性。 2.scanf()函数接收输入数据时，遇以下情况结束一个数据的输入：（不是结束该scanf函数，scanf函数仅在每一个数据域均有数据，并按回车后结束）。 　　① 遇空格、“回车”、“跳格”键。 　　② 遇宽度结束。 　　③ 遇非法输入。 3.scanf()函数返回成功赋值的数据项数，读到文件末尾出错时则返回EOF。 如： scanf("%d %d",&a,&b); 如果a和b都被成功读入，那么scanf的返回值就是2 如果只有a被成功读入，返回值为1 如果a和b都未被成功读入，返回值为0 如果遇到错误或遇到end of file，返回值为EOF。 且返回值为int型.


Question: 第K极值C语言实现在VC上没有问题，但在OJ上测试出现问题

你点开你的OJ上有显示错误： error: expected ';', ',' or ')' before '&' token void SelectSort(SqList &L){ ^  Main.c:29:1: error: unknown type name 'bool' bool isPrimeNum(int x)  1.第一个错误是你使用了引用 2.第二个错误是你使用了bool (bool和引用都是C++才有的)

Compiler Error。C语言好像没有bool类型。

这样我就明白了，刚刚把引用和bool修改了一下，谢谢大家，看来还是基础不扎实啊

出了什么问题？

对啊，是数组

这里的序列，是数组吗？

补充： 输入格式： 第一行为2个数n，k（含义如上题） 第二行为n个数，表示这个序列  输出格式： 如果m为质数则 第一行为'YES'(没有引号） 第二行为这个数m 否则  第一行为'NO' 第二行为这个数m


Question: for循环的i不自增，只会0到1，然后1到0

建议楼主先学会数据断点：#include <time.h> #include <stdlib.h> #include <windows.h> int main() {     int a,b[11];//本来是b[10]，为判断哪句越界，故意声明为b[11]      srand((unsigned int)time(NULL));//按两次F11，等黄色右箭头指向本行时，调试、新建断点、新建数据断点，地址：&b[10]，字节计数：4，确定。     while (1) {//按F5，会停在下面某句，此时a的值为10，b[10]已经被修改为对应0..4之一。         b[(a=rand()%11)]=0;         Sleep(100);         b[(a=rand()%11)]=1;         Sleep(100);         b[(a=rand()%11)]=2;         Sleep(100);         b[(a=rand()%11)]=3;         Sleep(100);         b[(a=rand()%11)]=4;         Sleep(100);     }     return 0; }

引用 3 楼 luciferisnotsatan 的回复:values 这个二维数组多大？  谢谢   正如你提出的，数据分配的内存小了

引用 1 楼 qq423399099 的回复:建议贴出完整代码，maybe越界覆盖了你的j的值  谢谢   问题解决了    我申请的数组少了几行，所以在访问数组的时候出现修改别处内存值了    太感谢了   谢谢

values 这个二维数组多大？

建议贴出完整代码，maybe越界覆盖了你的j的值


Question: 使用线程时的错误提示Connection is not defined in thread local storage.

引用 2 楼 u011121708 的回复:[quote=引用 1 楼 zhao4zhong1 的回复:] 《Windows核心编程》  楼上,线程内调用API和外部是不一样吗,需要重新 connection[/quote] 如果你能加锁控制多个线程使用同一个连接时不冲突，就可以不重连。

引用 1 楼 zhao4zhong1 的回复:《Windows核心编程》  楼上,线程内调用API和外部是不一样吗,需要重新 connection

《Windows核心编程》


Question: c语言函数参数栈的研究

玩玩么,第一次写个帖子,大概是兴致来了。至于反汇编那种东西,我懒得说了，我自己写的代码反汇编出来自己都不认识,是很操蛋的东西

调用约定 https://msdn.microsoft.com/zh-cn/magazine/9b372w95.aspx

这样就没什么意思了. 还不如找个东西来反汇编,再改,到达自己想要的目的.


Question: C语言函数调用

加个默认返回值就好

问题应该是出在jsValue()函数体内，我把函数isTure删了，数组得到的值依然是0。但在1000到2000的范围内，应该是有值（例如：1010）满足条件的。为什么存不到数组a中去呢？找了好久了，哪位帮帮忙解决一下。

not all control paths return a value是说你的函数中有的分支没有返回值，你加了那个判断之后，如果流程走不进你的那个if中，函数就没有返回值了。应该在函数的末尾加上返回值的

main函数里void jsValue();改成jsValue(); 你写的那个是函数声明  #include <stdio.h> int a[100],cnt=0; /*double pjz1=0.0, pjz2=0.0;*/  void jsValue() { 	int m; 	int x,b,c,d; 	for (m=1000;m<=2000;m++) 	{ 		x=m/1000;   b=m/100%10; 		c=m/10%10;  d=m%10;	//千位数x   百位数b  十位数c 个位数d  		if(x+b==c+d) a[cnt++]=m; 	}	 } void main() { 	int i; 	jsValue(); 	for(i=0;i<100;i++) 		printf("a[%d]=%d\n",i,a[i]); }

引用 6 楼 qq423399099 的回复:数组没有值是因为你main函数里把函数调用写成了声明  void main() { 	int i; 	jsValue(); //void jsValue();是函数声明！！！！！！！！11 	for(i=0;i<100;i++) 		printf("a[%d]=%d\n",i,a[i]); }  好，我看下

引用 3 楼 qq423399099 的回复:加个默认返回值就好  #include <stdio.h> int a[100],cnt=0; /*double pjz1=0.0, pjz2=0.0;*/  void jsValue() { 	int m; 	int x,b,c,d; 	for (m=1000;m<=2000;m++) 	{ 		x=m/1000;   b=m/100%10; 		c=m/10%10;  d=m%10;			//千位数x   百位数b  十位数c 个位数d  		if(x+b==c+d) a[cnt++]=m; 	}		 } void main() { 	int i; 	void jsValue(); 	for(i=0;i<100;i++) 		printf("a[%d]=%d\n",i,a[i]); }  麻烦你看一下，我这样写的，为什么数组a里面还是没有值呢？所有元素为0

引用 4楼我是你的主体 的回复:[quote=引用 3 楼 qq423399099 的回复:] 加个默认返回值就好 加在哪里？怎么加？我是新手。主要问题是数组a中没有数值，问题出在哪里？结构上看没问题啊，我都快被这道题弄疯了。[/quote]照理这个问题一般不会报错的，一般都是给个警告。 你加上if的判断，一旦没有进入if分支，也就没有对应的return语句了。 如果其他函数调用那么此时接收到的返回值就是EAX寄存器里的值，所以应该在最后一行加上return 0  int isTure(int m) { 	int x,b,c,d; 	if(m>=1000&& m<10000)      //加上这一语句，提示not all control paths return a value 	{ 		x=m/1000;   b=m/100%10; 		c=m/10%10;  d=m%10;      //千位数x   百位数b  十位数c 个位数d  		if(x+b==c+d)  return 1; 		else return 0; 	} 	return 0; }

引用 3 楼 qq423399099 的回复:加个默认返回值就好 加在哪里？怎么加？我是新手。主要问题是数组a中没有数值，问题出在哪里？结构上看没问题啊，我都快被这道题弄疯了。


Question: AT命令拨打电话--AT+CLCC

好好看AT命令的说明了,一般命令会在后面说有返回信息的.一般的模块也会有一个基本的使用说明的.实在搞不定打电话找厂家他们会告诉你怎么用.


Question: [求助]输出链表总是开头两个出现乱码

都被你free了，输出自然不对了

if(c==2) { /*free(p);	*/ break;	 }

引用 1 楼 user-2 的回复:if(c==2) { /*free(p);	*/ break;	 } 解决了 谢谢

引用 2 楼 qq423399099 的回复:都被你free了，输出自然不对了恩恩 是我手贱了  现在改了好了 谢谢。


Question: Hash存储、查找中Hash表构造方法、冲突率问题

hash的计算应该尽量避免重复，但过程也不要太复杂，否则效率也未必会提高

冲突率就可以简单理解成重复率吧  重复率从原理上说，如果结果为1字节，那么当输入数据超过256种时，必然产生重复。  当输入数据小于256时，也有可能产生重复，这与算法设计有关，真正的算法是由数学证明过的，不是拍脑门想出来的。


Question: 新人求助

i = j*2.54; 放到后面，在前面的时候，j的值还不确定   #include <stdio.h> int main (void) { 	float i ;  	int j ; 	printf ("请输入身高(厘米)\n"); 	scanf ("%d",&j) ; 	i = j*2.54; 	printf ("你的身高为%f英寸\n",i); 	return 0 ; }

i = j*2.54; 这一句应该放在Scanf这句后面

顺序出差了，i=jx2.54 应该放在读取了scanf的后面

在各位都指教下，问题已经解决，多谢各位，好人一生平安！

计算机执行到i = j*2.54;时，j还是未知数的哦，之后你才输入j的值，但i的值已经确定了哦，

i，j都没有初始化，就做i = j*2.54;有可能是随机值。

楼主写的这份代码，问题在以下几点，首先，你定义了int j;  j 并未未进行初始化，怎么可以直接进行操作呢，  其次你的j * 2.54应该返回的是double类型的，不应该用float类型进行接收。  虽然不知道你输入了什么值，但是后面的小数点.000000一堆，说明你在程序进行前对于数据类型未进行判断。

# include <stdio.h> int main (void) { float i ;  int j ; /*i = j*2.54;*/ printf ("请输入身高(厘米)\n"); scanf ("%d",&j) ; i = j*2.54; printf ("你的身高为%f英寸\n",i); return 0 ;  }

看不出问题在哪，但是我把你的代码精简了一下，结果输出正确  #include<stdio.h> int main() { 	int i = 4 ; 	float ff = (float)(i * 2.50); 	printf ("%f",ff); 	getchar(); }  结果输出  10.000000


Question: 请问这里的us怎么取

我是照着这个位段写的。yes yello yes green dashed分别是1 3 1 2 2 那么我以为二进制应该是1011 0000 1010 1000 但是书上给出的二进制是0010 0101 0000 0111

引用 2 楼 qq423399099 的回复:没懂要问啥 不好意思没表达好。我是问us 也就是box.ui_view的二进制，怎么取

引用 1 楼 paschen 的回复:us形参 取自 box.ui_view实参 yes yello yes green dashed分别是 1 3 1 2 2 没说清楚，我是问us 也就是box.ui_view的二进制，怎么取

没懂要问啥

us形参 取自 box.ui_view实参

Bits序是 未定义的，由编译器自行确定


Question: read在读取socket的时候为何一直堵塞，如何处理让read读取完数据立即返回。

设置成 nonblocking 模式啊,  win 下就           unsigned long mode = 1; 	ioctlsocket(sock, FIONBIO, &mode);  Linux 下:    int flags = fcntl(sock, F_GETFL, 0);    flags |= flags|O_NONBLOCK;    fcntl(sock, F_SETFL, flags);

对啊, 你不是要立刻返回么,  返回 -1  , errno == EAGAIN,  EWOULDBLOCK 就是让你等段时间再读啊...   然后你可以 select/poll/epoll  等到有数据到达再去读啊 ...

设置成非阻塞模式，read不到任何东西就会直接返回。    int flags = fcntl(sock, F_GETFL, 0);    flags |= flags|O_NONBLOCK;    fcntl(sock, F_SETFL, flags); 我有尝试，没有解决问题。


Question: 这个函数怎么写，小白一个，还请大神们多多指教

引用 4 楼 paschen的回复:楼主写法没错，如果找到 m 就指向这该位置，否则m为NULL  http://en.cppreference.com/w/c/string/byte/strstr 恩，就是像你这样说的，我搞定了

char *strstr(char *haystack,char *needle) { 	char *p=haystack; 	char *q=needle; 	char *pos; 	while(*p) { 		pos = p; 		while(*p == *q && *q) { p++;q++; } 		if(!*q) return pos; 		else q=needle; 		p++; 	} 	return NULL; }

引用 1 楼 小灸舞的回复:要自己实现？  const char* StrStr(const char *str1, const char *str2) {       assert(NULL != str1 && NULL != str2);                    while(*str1 != '\0')       {           const char *p = str1;           const char *q = str2;           const char *res = NULL;           if(*p == *q)           {                 res = p;                 while(*p && *q && *p++ == *q++)                 ;                                  if(*q == '\0')                       return res;                               }           str1++;       }       return NULL; }   我是想利用strstr函数来查找子串所在的位置


Question: 保留两位小数的问题。输入一个数，输出却溢出？

输入改成scanf("%lf", &a); 输出随意。

引用 11 楼 qq_35069633 的回复:[quote=引用 5 楼 qq423399099 的回复:] 你sizeof(float)和sizeof(double)看一下，是不是4字节和8字节 如果是的话，你如果用scanf("%f", &a);那么a这个double变量只被写入了4字节的数据 输出的时候自然就输出一坨垃圾值了也就是说11输入时实际只有一部分。那11具体占多大内存，怎样看，然后选择合适的类型？ [/quote]你定义的double无论在64位还是32位系统都占8B=8*8b

引用 5 楼 qq423399099 的回复:你sizeof(float)和sizeof(double)看一下，是不是4字节和8字节 如果是的话，你如果用scanf("%f", &a);那么a这个double变量只被写入了4字节的数据 输出的时候自然就输出一坨垃圾值了也就是说11输入时实际只有一部分。那11具体占多大内存，怎样看，然后选择合适的类型？

"%f" 对应 float  %lf 对应 double

楼主可以看一下不同变量类型所占的内存大小的区别，还是有点用的

1楼正解，很多初学者用double时都按照%f来用，其实是lf，注意是L不是数字1

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

引用 2 楼 qq423399099 的回复:输入改成scanf("%lf", &a); 输出随意。为什么会输出这样的乱码

引用 1 楼 user-8 的回复:%f -> float %lf -> double为什么会输出这样的乱码

输入改成scanf("%lf", &a); 输出随意。

%f -> float %lf -> double


Question: 为什么这个地方exit(1)会被提示 exit was not declared in this scope

I了I了 这个bug把我整懵逼了

exit在头文件 <stdlib.h>里  http://en.cppreference.com/w/c/program/exit

加上头文件stdlib.h

引用 1 楼 qq423399099 的回复:加上头文件stdlib.h 版主好啊。我又回来了。 这是教程上的原代码，他的确没有stdlib.h这个头文件


Question: 帮忙看下有两段语句在程序中的作用

第一段程序是作  延时 用的，第二段程序 是串口中断服务程序


Question: 请教结构体处理问题

好，我试试看怎么能让编译器支持动态分配函数，多谢指教

别怕，动态分配，分配多少都是你自己可以决定的，这样才能物尽其用…… 用得好就跟你定义多种struct基本一样省内存，代码还整洁。

因为程序用在单片机中，资源有限，我怕用动态分配会有问题，比如内存大小不够之类的问题，不知道还有没有其他办法呢？

数据在中间根本不是问题，你可以“包头+数据+包尾”又或者“数据+包尾”完全放在结构体最后的数组里，注意最后的解析就好

那请楼主先告诉我，你的编译器支持什么动态分配内存的函数？

柔性数组需要用到malloc 函数，我用的KEIL编译器，不支持啊，还有就是柔性数组必须放在结构的最后成员，可我的数据是在中间的，包头+数据+包尾，数据是可变的，我发送的时候也是发送结构体，如果用较大的数组定义数据的话，比如u8 data[100]，如果数据只有10个字节，那么剩余的90个字节也要发出去，这就有悖协议了。

http://blog.csdn.net/ce123/article/details/8973073 建议用柔性数组

建议用字符串传输，在两端进行编解码。比如可以都编码为BCD字符串


Question: 散列表的优点在哪里呢

平均约一次查找，即可找到要找的元素

最主要的优点：这样查找效率高，计算一下哈希值就可以直接找到对应的元素，而不需要逐个去比较

明白了 谢谢各位

把散列表的名字改为哈希，再去琢磨。

数组  优点：插入块如果知道坐标可以快速去地存取  缺点：查找慢,删除慢,大小固定  有序数组  优点：比无序数组查找快  缺点：删除和插入慢，大小固定  栈  优点：提供后进先出的存取方式  缺点：存取其他项很慢  队列  优点：提供先进先出的存取方式  缺点：存取其他项都很慢  链表  优点：插入快，删除快  缺点：查找慢  二叉树  优点：查找，插入，删除都快（如果数保持平衡）  缺点：删除算法复杂  红-黑树  优点：查找，插入，删除都快，树总是平衡的  缺点：算法复杂   2-3-4树  优点：查找，插入，删除都快，树总是平衡的。类似的树对磁盘存储有用  缺点：算法复杂   哈希表  优点：如果关键字已知则存取速度极快，插入块  缺点：删除慢，如果不知道关键则存取很慢，对存储空间使用不充分  堆  优点：插入，删除块，对最大数据的项存取很快  缺点：对其他数据项存取很慢  图  优点：对现实世界建模  缺点：有些算法慢且复杂

分开储存的是链表....hash表是连续储存目的是将搜索时间复杂度降到O(1),  而一般数组搜索时间复杂度O(n)，二叉树是O(log(n))，哪个效率一看就知道了


Question: 新手求助 一个二叉排序树的问题

不好意思 你的这个程序实在有点费解 搞不懂返回true 有什么用 。你可以看看我以前提问过的一个帖子 也是关于删除的 里面的那个程序比较简洁明了

引用 2 楼 user-1 的回复:我也是刚刚学，不太懂你的意思。 你是说 删除只有一个孩子的结点时只是删除了这个结点，而没有把他的父节点连到他上面吗？ 我想说的是 这是一个递归程序，“现在”执行的删除操作是在许多个 查找 操作后进行的，当你的 删除操作执行完了后，会返回一个结点（当是 删除只有一个孩子的结点 时，这个结点是他的孩子结点），这一步的递归就退出了，这个结点又被赋给另一个结点（这个结点就是他的父亲）。这是个递归程序没错 是递归寻找到是否和key相等  相等就删除  我的意思是 如果这个要删除的结点是 左结点为空 或者右结点为空的时候 删除了这个结点要把后边的连上去 而不破坏排序二叉树的性质  那    *p = (*p)->lchild; 的意思就是*p指向左孩子  然后 然后free掉了q  那这个要删除结点的父结点 并没有连下去  就是不明白这点

引用 2 楼 user-1 的回复:我也是刚刚学，不太懂你的意思。 你是说 删除只有一个孩子的结点时只是删除了这个结点，而没有把他的父节点连到他上面吗？ 我想说的是 这是一个递归程序，“现在”执行的删除操作是在许多个 查找 操作后进行的，当你的 删除操作执行完了后，会返回一个结点（当是 删除只有一个孩子的结点 时，这个结点是他的孩子结点），这一步的递归就退出了，这个结点又被赋给另一个结点（这个结点就是他的父亲）。我想想

也就是  要删除的结点 左结点为空 或则右结点为空的时候  怎么连上去的？？？ 这句代码连不上去啊 *p = (*p)->lchild; 只是*p指向了lchild而已 他的双亲指向的结点(q)还是被释放了 求大神帮忙！！！


Question: 有些测试正确 有些不正确

Visual C++ 2010 Express简体中文版http://pan.baidu.com/s/1bnwRVLt 参考 C:\Program Files\Microsoft Visual Studio 10.0\VC\crt\src\qsort.c


Question: 9-((total-1)%10)  和 10-total%10为什么结果一样呢？

引用 4 楼 dustpg 的回复:#include <stdio.h>   int main() {     int total = 10;     int a = 9 - ((total - 1) % 10);     int b = 10 - total % 10;     printf("a: %d, b: %d", a, b); }  x % 10值域是0~9, 9 - (x % 10) 值域是0~9, 10-(x%10) 值域是1~10， 怎么是一样的... ++

total = k * 10 + r total - 1 = k * 10 + r - 1  total % 10 = r (total - 1) % 10 = r - 1  10 - total % 10 = 10 - r 9 - ((total-1)%10) = 9 - (r-1)  = 9- r+1 = 10 - r  所以相等

就是这两个表达式在编译器中结果相等，我想问问为什么结果相等，怎么用数学方法解释

想问什么？说清楚点

你想说 9-((total-1)%10)  在C89 和 C99 结果不一样?


Question: 求表达式在C89和C99下的值

引用 6 楼 renwotao2009的回复:-std=c89 -std=c99 谢谢啦！。。。。。。。。

-std=c89 -std=c99

你就编一个一模一样的程序  然后分别用支持c89的编译器编译运行 再用支持c99的编译器编译运行 比较结果就可以了

就是有两个题目，表达式一模一样，分别让我求在C89中和C99中的值，我不知道怎么去编写程序

什么分别求结果? 说不清楚?

在编辑器里面怎么分别求得结果呢？

基本没区别  出了 %运算符操作数小于0的情况  C89 和 C99 略有差异  其他情况都是一样的


Question: 提交OJ系统提示超时

你们的OJ好神奇，这样的程序居然是超时。 大部分OJ应该都会判为Wrong Answer。

题目是控制台输入  答案int CreateMGraph(MGraph &G) {    int va,vb,va1,vb1; 	int i,j,k,l; 	scanf("%d,%d",&G.numNodes,&G.numEdges); /* 输入顶点数和边数 */ 	fflush(stdin); 	for(i = 0;i <G.numNodes;i++) /* 读入顶点信息,建立顶点表 */ 		scanf("%d",&G.vexs[i]); 	for(i = 0;i <G.numNodes;i++) 		for(j = 0;j <G.numNodes;j++) 			G.arc[i][j].adj=0;	/* 邻接矩阵初始化 */ 	for(k = 0;k <G.numEdges;k++) /* 读入numEdges条边，建立邻接矩阵 */ 	{ 		scanf("%d,%d",&va,&vb); 	va1=0; 	vb1=0; 	if(G.vexs[0]){ 		for(l=0;l<G.numNodes&&G.vexs[l];l++){ 			if(va==G.vexs[l]) 			va1=1; 			if(vb==G.vexs[l]) 			vb1=1; 		} 		if(va1==0){ 			G.vexs[l]=va; 			if(vb1==0)G.vexs[l+1]=vb; 		} 		else  			if(vb1==0)G.vexs[l]=vb; 	} 	else { 		G.vexs[0]=va; 		G.vexs[1]=vb; 	} 	i=LocateVex(G,va); 	j=LocateVex(G,vb); 	G.arc[i][j].adj=1; 	} 	return 1; }     搞得很复杂很繁琐的样子，话说不可以直接赋值吗，就G.arc[va][vb].adj=1难道不行？？？

控制台输入（输出） 改成文件输入输出 人工输入非常耗时 控制台输出，也比文件输出慢很多 你的数据不大，只是数据录入，不可能超时的


Question: 怎样用notepad++运行C程序

个人感觉如果想自己组装编译环境IDE，可以下个code::blocks(不自带GCC)的那种，然后再单独下载一个GCC，最后根据需要，自己组装成IDE环境。

引用 10 楼 qq_35069633 的回复:引用 9 楼 renwotao2009 的回复:notepad++是编辑器，gcc是编译器，你得配合用才叫可视化编译环境怎样配合？  网上有讲解，楼主与其那么麻烦不如直接装个code::blocks或者VS用

引用 10 楼 qq_35069633 的回复:引用 9 楼 renwotao2009 的回复:notepad++是编辑器，gcc是编译器，你得配合用才叫可视化编译环境怎样配合？下载gcc，配置notepad++的编译环境，网上有资料可参考

notepad++是编辑器，gcc是编译器，你得配合用才叫可视化编译环境

怎样设置，然后就可以进行编译跟运行呢

有 VC++ 跟 dev C++ 了。Notepad ++看上去好用些 ，而且通用其他大部分语言。

notepad++ 只是个文本编辑工具。

还是这个吧，只有几十M，自带VC6和TC编译器，可设置： C与C++程序设计学习与实验系统 2013.3

你还得有编译器啊！！

你就折腾吧...

notepad之类的编辑器本身是不能编译c程序的，需要有专门的编译器，比如gcc。然后需要设置编译指令来编译。


Question: 关于*p++和*- -p的问题

应该是一致的， 只是你理解的栈顶， 和作者说的栈顶不同 作者说的栈顶元素，就是最后一个入栈的元素 栈顶就是最后入栈元素的位置 你理解的栈顶应该是当前的栈指针位置为栈顶  而实际上 很多堆栈都是向下生长的 和作者演示的堆栈不一样 假设用 数组模拟堆栈 int a[40] ; int *sp =a+40-1; //一种方式 初始化为第一个可以存放的元素位置 *sp-- =x;//入栈   x=*++sp; //出栈  //栈顶元素 是sp 上面一个元素 //判满  bool isfull(){return sp== a-1;}; //判空 bool isempty(){return sp== a+40-1;}; int *sp =a+40; //另一种方式 初始化为栈外一个元素的位置 *--sp =x;//入栈 x=*sp++;//出栈 栈顶元素 就是 sp所指元素 //判满  bool isfull(){return sp==a;}; //判空 bool isempty(){return sp== a+40;};  这只是两种不同的实现方式， 栈顶元素表示方法本质上是一致的， 都是最后一次入栈的元素。

引用 5 楼 qq423399099 的回复:栈顶指针一般都是指向栈顶元素的下一个位置。 所以要取栈顶元素，需要让栈顶指针先减1再取值才行。（所以这样注释完全OK） PS：谁也没说过栈顶指针一定要指着栈顶元素啊？ 哦哦，我看懂了，原来栈指针是指向栈顶下个位置的，谢谢～

引用 2 楼 qq423399099 的回复:*--p;当然是先执行--然后再*取值 其实你从上面的入栈也能看出来，它是先将值入栈，然后p才++，也就是说入栈玩，p指向的地方是没有值的 所以出栈的时候自然要先--然后才能取到值 这个我也懂得，只是第二句代码运行方式感觉跟注释写的不太一样，是这样吗？

引用 1 楼 user-3 的回复:[quote=引用 楼主 zhenqiu_chen 的回复:] 但是按照注释的说法，是把栈顶元素弹出栈并赋给val，然后栈指针才减1, 这也是符合出栈的过程的。 看不出有这个说法[/quote] pop top of stack into val 这个说把栈顶元素pop到val里面，应该是这个意思吧。

引用 楼主 zhenqiu_chen 的回复:但是按照注释的说法，是把栈顶元素弹出栈并赋给val，然后栈指针才减1, 这也是符合出栈的过程的。 看不出有这个说法


Question: 当/运算符和%运算符的操作数是负数时

这个算是简单的数学的问题吧。。。。。。

11%5的结果是1 11%-2的结果是1 -11%-5的结果是-1 -11%5的结果是-1  参见《c primer plus》第5章 5.3.2节

引用 4 楼 罗博士的回复:[quote=引用 3 楼 u012061345 的回复:] 除号操作符并不复杂，结果是确定的。  取余操作符只要记得一条：取余的结果与被除数的符号一致。  早期的C++98标准中，如果取余运算符的两个运算数是非负的，余数的符号是不做规定的，所以不同的编译器有可能不同。  但是在C语言以及新的C++标准中，这一条已经没有了。取余的结果应该保持一致。  早期的C89标准也是不规定的。不过C99、C11、C++11、C++14都已经规定死了。[/quote] 谢谢(*°∀°)=3

a % -b = a + a / b > 0 -a % -b = -a - a / b < 0

a > 0 ,b > 1 : a % b  = a - a / b > 0 -a % b = -a + a / b < 0

引用 3 楼 u012061345 的回复:除号操作符并不复杂，结果是确定的。  取余操作符只要记得一条：取余的结果与被除数的符号一致。  早期的C++98标准中，如果取余运算符的两个运算数是非负的，余数的符号是不做规定的，所以不同的编译器有可能不同。  但是在C语言以及新的C++标准中，这一条已经没有了。取余的结果应该保持一致。  早期的C89标准也是不规定的。不过C99、C11、C++11、C++14都已经规定死了。

除法应该是商与分母相乘吧。假如-9/7，结果可能为-2.也可能为5，是为什么呢？

首先先说余数，在C语言中余数的符号是和被除数的符号相同。即： (-10)%3==-1; 10%(-3)==1; (-10)%(-3)==-1; 做除法的时候，商是令其与分子相乘的积的绝对值不超过分母的绝对值且最接近的那个数， 所以 (-10)/3==-3; 10/(-3)==-3; (-10)/(-3)==3;  余数与被除数（即分子的符号）相同；先将各个带符号的数全部取正值再做除法，再根据负号的个数确定商的符号


Question: 这个图里的三角函数 要怎么用c语言打出来

引用 4 楼 youzi15 的回复:  如果atan是 -1的子集    我用atan 会不会不精确？  lz看清图片写的没有.....我的理解上函数f(x)，指定一个x, 有一个确定的 f(x),  但是图片上假定了多个f(x), 高等数学我已经忘光了, 所以不知道合不合法.  反正atan返回的是-π/2 ~ π/2, 而不是任意角度

关键看取值范围，atan取值范围是(-π/2,+π/2)，根据你的需要+-kπ

如果atan是 -1的子集    我用atan 会不会不精确？

这是反函数的写法 f-1 表示 f 的反函数  tan-1  数学上习惯用 tg-1---->arctg  C语言 tan（x） 表示tg( x) atan(x) 表示 arctg(x) atan2 (x,y) ===>表示 arctg(y/x)  这样的好处是  1）不会出现x=0 ，结果为无穷大，因而无法求出的问题 2）更精确 比 arctg(y/x) 先求出 y/x 再求  反三角函数更精确 ，因为 tg，一个周期内，有两个无穷大点， 这个点 附近的值，对应的 y/x 数据巨大，  表示为double 也是不精确地 所以计算结果也是不精确地，

-1 和atan 一样吗      我看到别人说 atan是 -1的子集 这是乍回事

#include<stdio.h> #include<math.h> int main() {   float y,x;   scanf("%f%f",&y,&x);   printf("%f\n",atan(y/x));   return 0; }


Question: 用CodeBlocks运行一个写的C语言程序有错误，一直找不出错在哪里，求大神帮忙指点一下啊

input()函数里面，char m;，m没有赋初值

Input函数声明的语句后面少了分号  int Input(Person p[],int n);

input函数的声明后面少了一个分号

听版主的，听赵老湿的，提问要掌握提问的技巧。

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


Question: 结构体求两个学生的平均分，这个怎么就错了，运行不了，求指点

引用 7 楼 赵4老师的回复:printf里面的%和变量的一一对应关系 scanf里面的%和变量以及变量前加不加&的一一对应关系 是C代码中非常容易出错的地方，而且通常编译还不出错。 所以在编译源代码之前值得专门仔细检查一遍甚至多遍。  在每个最后不带\n的printf后面加fflush(stdout); 在每个不想受接收缓冲区旧内容影响的scanf前面加rewind(stdin); 另外请检查scanf的返回值。 //请今后要用 int c; scanf("%c",&c); //时，都改为 char s[2]; int c; scanf("%1s",s); c=s[0]; 谢谢老师指导，蒽，以后注意

引用 3 楼 user-4的回复:#include<stdio.h> #define X 3 #define Y 2  struct student { 	char xuehao[10]; 	char name[10]; 	int cj[X]; 	float pj; };  int main() { 	int i, j; 	struct student stu[Y]; 	printf("请输入学号，姓名：\n"); 	for (i = 0; i < Y; i++){ 		fflush(stdin); 		scanf("%s%s", &stu[i].xuehao, &stu[i].name); 		stu[i].pj = 0.0; 	} 	printf("请输入成绩：\n"); 	for (i=0;i<Y;i++){ 		for (j = 0; j < X; j++) 		{ 			scanf("%d", &stu[i].cj[j]); 			stu[i].pj = stu[i].pj + stu[i].cj[j] ; 		} 	} 	for (i = 0; i < Y; i++) 	{	 		stu[i].pj = stu[i].pj /X; 		printf("%s\t%s\t", stu[i].xuehao, stu[i].name); 		printf("%f\n",stu[i].pj); 	} 	return 0; } 大概改了一下，不过这么写逻辑有点混乱。另外，建议for循环中即使只有一条语句也是用花括号，否则很容易导致自己逻辑错误 谢谢谢谢指导，明白了

引用 2 楼 sinat_35121480的回复:[quote=引用 1 楼 qq_35178267的回复:]scanf("%s%s", &stu[i].xuehao, &stu[i].name);把两个&去掉试试，换成scanf("%s%s", stu[i].xuehao, stu[i].name); 这样还是不对的，结果是运行不了的[/quote] 第二个循环改一下吧 for(i=0；i<Y;i++) {         for(j=0;j<X;j++)          scanf("%d",&stu[i].cj[j]); }

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

引用 1 楼 qq_35178267的回复:scanf("%s%s", &stu[i].xuehao, &stu[i].name);把两个&去掉试试，换成scanf("%s%s", stu[i].xuehao, stu[i].name); 这样还是不对的，结果是运行不了的


Question: 关于信号处理的问题

下面几种情况，可以把信号发送到某个指定的线程。 A..某个特定硬件指令执行后(在该线程内执行的),产生的信号，将会发送到该线程内。比如SIGBUS，SIGFPE，SIGILL，SIGSEGV。 B.当线程尝试向一个broken pipe写数据时，会产生一个SIGPIPE. C.使用pthread_kill()或者pthread_sigqueue()。这些函数允许一个线程发送信号到另一个线程（同一进程中）。  其他情况都是把信号发送到整个进程（比如，kill()和sigqueue()）。

《Windows核心编程》

信号是给进程的，不是给线程的。


Question: 使用指针按字符串长度排序到崩溃的困惑

if(strlen(s1[i])>strlen(s1[j]));这句后面多了分号  单步调试和设断点调试（VS IDE中编译连接通过以后，按F10或F11键单步执行，按Shift+F11退出当前函数；在某行按F9设断点后按F5执行停在该断点处。）是程序员必须掌握的技能之一。

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

自己应该学会调试

自己顶帖，坐等高人。

代码还没完全理解，但4楼说的有道理，if后面搞了个分号，那其下面的大括号内的语句就在for内每次都执行了，没有条件给其限制了


Question: 小白c语言文件读取问题 fscanf就是读不出数据

如果是写文本文件，打开文件标记那里加上 t   http://en.cppreference.com/w/c/io/fopen

文件写完后要fclose(fp); 把内容从缓冲区写入到文件才行  #include <stdio.h>  //函数f1,从键盘读入n个实数,将其写到一个文件上,文件名由用户输入 void f1() { 	int	n = 0; 	double data = 0; 	char name[20]; 	gets(name); 	FILE *fp; 	fp = fopen(name, "w+"); 	if (!fp) 	{ 		printf("Cannot open such a file"); 	} 	printf("请输入存入数字个数:"); 	scanf("%d", &n); 	for (int i = 0; i < n; i++) 	{ 		scanf("%lf", &data); 		fprintf(fp, "%.2lf\n", data); 	} 	fclose(fp); }  void f2() { 	int n = 0; 	printf("请输入要读取的数字的个数\n"); 	scanf("%d", &n); 	getchar(); 	double a[100] = {0}; 	char name[20]; 	printf("请输入要读取的文件名\n"); 	gets(name); 	FILE *fp; 	 	fp = fopen(name, "r"); 	if (!fp) 	{ 		printf("Cannot open such a file"); 	} 	for (int i = 0; i < n; i++) 	{    		int j = 0; 		j = fscanf(fp,"%lf",&a[i]); 		printf("%d ",j); 		printf("%lf",a[i]); 	}  }  int main(int argc, char* argv[]) { 	f1(); 	f2(); 	return 0; }

fscanf的返回值一直是-1 到底是哪里出了问题呢？

#include <stdio.h>  //函数f1,从键盘读入n个实数,将其写到一个文件上,文件名由用户输入 void f1() { 	int	n = 0; 	double data = 0; 	char name[20]; 	gets(name); 	FILE *fp; 	fp = fopen(name, "w+x"); 	if (!fp) 	{ 		printf("Cannot open such a file"); 	} 	printf("请输入存入数字个数:"); 	scanf("%d", &n); 	for (int i = 0; i < n; i++) 	{ 		scanf("%lf", &data); 		fprintf(fp, "%.2lf\n", data); 	} }  void f2() { 	int n = 0; 	printf("请输入要读取的数字的个数\n"); 	scanf("%d", &n); 	getchar(); 	double a[100] = {0}; 	char name[20]; 	printf("请输入要读取的文件名\n"); 	gets(name); 	FILE *fp; 	fp = fopen(name, "r"); 	if (!fp) 	{ 		printf("Cannot open such a file"); 	} 	for (int i = 0; i < n; i++) 	{    		int j = 0; 		j = fscanf(fp,"%lf",&a[i]);     	printf("%d ",j); 		printf("%lf",a[i]); 	}  }  int main(int argc, char* argv[]) { 	f1(); 	f2(); 	return 0; }


Question: 请问怎么通过预编译实现同一段语句的多次调用啊？

代码生成参考：//codegen.c // 输入一组字符串，比如 // aa ss ddd dd 33 dd // 然后自动生成一个函数 int A(const char*); // 实现A("aa")返回0  A("ss")返回1 依次类推 #include <stdio.h> int main(int argc,char **argv) {     int i;     if (argc<2) {         printf("%s p1 [p2 ...] [>result.c]\nGenerate code int A(const char *a); 0==A(\"p1\") 1==A(\"p2\") ...",argv[0]);         return 1;     }     //printf("#include <string.h>\n");     printf("int A(const char *a) {\n");     for (i=0;i<argc-1;i++) {         printf("    if (0==strcmp(a,\"%s\")) return %d;\n",argv[i+1],i);     }     printf("    return -1;\n");     printf("}\n");     return 0; } //C:\test\Debug>codegen.exe //codegen.exe p1 [p2 ...] [>result.c] //Generate code int A(const char *a); 0==A("p1") 1==A("p2") ... //C:\test\Debug>codegen.exe aa ss ddd dd 33 dd //int A(const char *a) { //    if (0==strcmp(a,"aa")) return 0; //    if (0==strcmp(a,"ss")) return 1; //    if (0==strcmp(a,"ddd")) return 2; //    if (0==strcmp(a,"dd")) return 3; //    if (0==strcmp(a,"33")) return 4; //    if (0==strcmp(a,"dd")) return 5; //    return -1; //} // //c:\test\Debug>codegen.exe aa ss ddd dd 33 dd >result.c // //c:\test\Debug>type result.c //int A(const char *a) { //    if (0==strcmp(a,"aa")) return 0; //    if (0==strcmp(a,"ss")) return 1; //    if (0==strcmp(a,"ddd")) return 2; //    if (0==strcmp(a,"dd")) return 3; //    if (0==strcmp(a,"33")) return 4; //    if (0==strcmp(a,"dd")) return 5; //    return -1; //} //

看来，想象力是创造力的源泉，虽然 实现比较麻烦 使用起来，还是很方便的  引用 6 楼 luciferisnotsatan 的回复:你这还不如用个循环。。。。。。  没要玩宏的话，可以看 http://bbs.csdn.net/topics/370167484 只有想不到，没有做不到的 不过，确实不如循环，因为编译器优化，也有这种能力

所以说，宏和模板都比不上代码生成。

也许可以 搞复杂点  #define  fun1 fun() #define  fun2 fun(), fun() #define  fun3 fun(),fun(),fun()  #define repCall(f,n) f##n repCall(fun,3)   没试验过 不知道成不成

和直接调用没什么多大区别的~

for(int i=0;i<3;i++) {      fun(); }  可能会展开成 fun();fun();fun();

这个不需要预编译语句，编译器会自动展开循环

不使用循环那没有，你就只能写成：  #define deffun (fun();fun();fun();fun();fun();fun();fun();fun();fun();fun();)  然后调用时：  deffun

这是什么鬼，为什么要这样做呢？有方法，最好还是用函数去循环调用，别乱用预编译啊。


Question: 这两个普利姆算法哪里不同？

实现同一功能可以写出不同的代码，但代码的执行效率可能完全不同

第一个是最直白的写法，效率低。 第二个做了一个标准的优化，在每一次加入点的时候，更新一下未加入点到已加入点的最短距离。效率高。

一个无耻的说法就是比较一下哪里不同。


Question: 关于padding bits

引用 5 楼 paschen 的回复:http://www.cnblogs.com/zhaoyl/archive/2012/04/21/2461077.html谢谢二楼和版主

你的具体情况我不知道，猜想是类似下面的情况： 比如数据有10位(value)，占用第0~9位；如果有要求必须把符号位(sign)放在第31位，那就需要在中间填上21位无意义的内容(padding)

padding一般是填充。他本身的内容没用，作用是占用一些空间使得有用的东西处在合适的位置上，达到内存对齐之类的效果。  举例： struct { char c; int i; }; 这里的c占用1个字节，为了让后面的i处在4字节对齐的位置，编译器通常会在c和i中间填进3个字节，这就是padding bytes

没人么。。。。

有人么。。。


Question: 浮点数做逻辑判断的效率是不是比整型做逻辑判断的效率低？

浮点处理器使用前后，需要处理处理器状态 因此指令越少，效率越低 指令多的时候，不必整数部件差  其中比较 就是一种低效操作 因为只需要几条指令 所以 效率偏低  浮点部件执行数学运算，很有效率 但不宜 只有少量计算 大量数学运算，效率反而高

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

整数的效率肯定要高一些

做四则运算，浮点数效率肯定比整型低？一般四则混合运算，没有特殊指令集的话, 现代CPU的浮点计算效率比整型高......不要想这些基本代码的效率，因为考虑的远远 没有编译器/硬件本身多


Question: 结构体作为函数参数，但是修改后为什么数值不一样？

我是想用结构体当做指针，然后进行修改后，在输出

哦 把字符当作字符串输出，是严重的错误 *（who）-> name ////这里的 优先级运算符 （） 不起任何作用，纯属骗人的 ===>* who -> name  ==>*(who->name)

字符串拷贝用strcpy  #include <stdio.h> #include <stdlib.h> #include <string.h> struct stu{  	char name[5]; 	int id; 	char sex[10]; }; void test(stu* who){  	who->id=23;  	strcpy(who->name, "bhj");  	strcpy(who->sex, "dkh");  	printf("%d %s %s\n",who->id,who->name,who->sex); } int main(){  	stu s1={"a",12,"m"};  	test(&s1);   	return 0; }

*(who)-> 这个代码是什么？？ ->操作符 的操作对象本身就是对结构体指针，你加个*以后，就是这个结构体的第一个元素的地址的内容了 也就是name[0]了（可能说得不大准确，大概就是这个意思了），反正就是语法已经乱了 所以才会报错“无法从 const char [4] 转换成 char”

#include <stdio.h> #include <stdlib.h> #include <string.h>  struct stu{ 	char name[5]; 	int  id; 	char sex[10]; };  void test(struct stu *who){ 	who->id=23; 	who->name[0]='b'; 	who->name[1]='h'; 	who->name[2]='j'; 	who->sex[0]='d'; 	who->sex[1]='k'; 	who->sex[2]='h'; 	printf("%d %s %s\n",who->id,who->name,who->sex); }  int main(){ 	stu s1={"a",12,"m"}; 	test(&s1); 	return 0; }  不知道你想要干嘛，只是改的没错了


Question: c语言中的time函数获得机器时间

“多一少一”问题占程序员常犯错误的10%以上！ 避免“多一少一”问题的方法之一是将比如<10甚至<5的数代入程序片断，搬手指头心算验证一下程序到底应该写为 x、x-1、x+1中的哪个？ <、<=、==、>、>=中的哪个？

是多算了一个月，，，

#include <time.h> #include <stdio.h>  int sum() { 	int p = 1970; 	int i; 	int sum=0; 	for (i = 0; i < 46; i++) { 		if (p % 4 == 0 && p % 400 != 0) { 			sum = sum +  366; 		} 		else { 			sum = sum +  365;  		} 		p++; 	} 	sum = sum + 31/*一月*/ 		+ 29/*二月*/ 		+ 31/*三月*/ 		+ 30/*四月*/ 		+ 31/*五月*/ 		+  3/*六月*/; 	time_t pu; 	long f = (int)time(&pu); 	f = f / (3600*24); 	printf("%ld\n",f); 	printf("sum=%d",sum); 	return sum;  }  int main (){ 	sum(); 	return 0; }

楼主你自己多算了一个月吧，sum = sum + 185; 1月1日到6月3日应该是：31+29+31+30+31+3=155


Question: linux下ping一个字符串都能通？

这台服务器管理的域叫做sdfsdf 改host文件 echo "0.0.0.0 sdfsdf" >> /etc/hosts

引用 3 楼 user-1 的回复:是一个本地域名 怎么个意思？那如何让他ping不通

是一个本地域名

这是个无效的域名。也会识别？

一个域名而已


Question: 如何读取行列都不定的整数集文件

fp = fopen("G:\\ExpQuery", "r");     vector<vector<int> > query_list;     while(1) {         vector<int> aarr;         int a;         while(1){             fscanf(fp,"%d",&a);             aarr.push_back(a);             if(feof(fp)) break;             if(fgetc(fp)=='\n') break;         }         query_list.push_back(aarr);         if(feof(fp)) break;     }     fclose(fp);

引用 2楼我是你的主体 的回复:我是这么想但具体操作不太会，也不知道怎么处理换行（检测换行符也不太会处理（总之就是不会文件相关操作用ifstream读，fread也行 建议楼主自己先写一些代码，然后单步调试，遇到问题了再发上来。 单步调试和设断点调试（VS IDE中编译连接通过以后，按F10或F11键单步执行，按Shift+F11退出当前函数；在某行按F9设断点后按F5执行停在该断点处。）是程序员必须掌握的技能之一。

每行都存成一个vector 一行行读，每行读到一个数字就push_back到对应的vector里


Question: c语言  数据读写

\代表转义符号，如果你要在字符串中表示出\ 必须同时写两个\\才行，代表一个‘\’ 参考：http://www.cnblogs.com/emanlee/archive/2010/05/14/1735274.html

能不能具体说明一下，不是很懂

\\  转义字符问题


Question: 请问 数组会造成内存泄漏

是不是管道1没有及时取走数据，导致数据在内存中堆积，最后溢出了。

你可以这样试，把写管道1的代码注释掉，其它的都不变，看看内存还会不会不断增大。

内存一直增大并不代表内存泄露  调用的一些系统函数也是会有资源消耗的

引用 9 楼 titan_ysl 的回复:是不是管道1没有及时取走数据，导致数据在内存中堆积，最后溢出了。 管道数据 在读出时应该就不占内存了 web那边接收数据我用ajax同步的  应该不会有数据堆积

我说下流程 大神们帮分析下感谢了   这是一个web - server 交互系统  web页面用定时器（0.5s）循环调用ajax去掉一个cgi程序，这个cgi通过管道实现和server进程间通讯，cgi再把server返回的数据发给页面 是同步的  我怀疑一个地方 但没有依据  管道开关快速读写对内存是否有影响    这是感觉像是 内存泄漏 可我没有malloc 处理数据的函数数组都是局部的 js在浏览器上运行，应该不会占用Linux内存的

引用 4 楼 qq_32778999 的回复:[quote=引用 2 楼 zhao4zhong1 的回复:] 检查是否资源泄漏的办法之一： 在任务管理器 进程 查看 选择列 里面选择：内存使用、虚拟内存大小、句柄数、线程数、USER对象、GDI对象 让你的程序(进程)不退出,循环执行主流程很多遍，越多越好，比如1000000次甚至无限循环，记录以上各数值，再隔至少一小时，越长越好，比如一个月，再记录以上各数值。如果以上两组数值的差较大或随时间流逝不断增加，则铁定有对应资源的资源泄漏！你好 程序是在arm板上的Linux跑的 我只能用free看已使用内存和剩余内存[/quote] Linux下可以使用top命令。

引用 3 楼 u012097721 的回复:运行内存 和其他因素也有关内存可以肯定被这个程序吃掉了 因为只运行了这一个程序。

引用 1 楼 qq423399099 的回复:用工具可以帮助定位 譬如vld 我下载过 但按照网上的步骤编译会出错 是不支持还是得方法不对 我的程序是在arm板子上跑的

引用 2 楼 zhao4zhong1 的回复:检查是否资源泄漏的办法之一： 在任务管理器 进程 查看 选择列 里面选择：内存使用、虚拟内存大小、句柄数、线程数、USER对象、GDI对象 让你的程序(进程)不退出,循环执行主流程很多遍，越多越好，比如1000000次甚至无限循环，记录以上各数值，再隔至少一小时，越长越好，比如一个月，再记录以上各数值。如果以上两组数值的差较大或随时间流逝不断增加，则铁定有对应资源的资源泄漏！你好 程序是在arm板上的Linux跑的 我只能用free看已使用内存和剩余内存

运行内存 和其他因素也有关

用工具可以帮助定位 譬如vld


static int hdc_pe4[256][4] = {     {0,0,0,0},{0,0,0,1},{0,0,0,2},{0,0,0,3},     {0,0,1,0},{0,0,1,1},{0,0,1,2},{0,0,1,3},     {0,0,2,0},{0,0,2,1},{0,0,2,2},{0,0,2,3},     {0,0,3,0},{0,0,3,1},{0,0,3,2},{0,0,3,3},     {0,1,0,0},{0,1,0,1},{0,1,0,2},{0,1,0,3},     {0,1,1,0},{0,1,1,1},{0,1,1,2},{0,1,1,3},     {0,1,2,0},{0,1,2,1},{0,1,2,2},{0,1,2,3},     {0,1,3,0},{0,1,3,1},{0,1,3,2},{0,1,3,3},     {0,2,0,0},{0,2,0,1},{0,2,0,2},{0,2,0,3},     {0,2,1,0},{0,2,1,1},{0,2,1,2},{0,2,1,3},     {0,2,2,0},{0,2,2,1},{0,2,2,2},{0,2,2,3},     {0,2,3,0},{0,2,3,1},{0,2,3,2},{0,2,3,3},     {0,3,0,0},{0,3,0,1},{0,3,0,2},{0,3,0,3},     {0,3,1,0},{0,3,1,1},{0,3,1,2},{0,3,1,3},     {0,3,2,0},{0,3,2,1},{0,3,2,2},{0,3,2,3},     {0,3,3,0},{0,3,3,1},{0,3,3,2},{0,3,3,3},     {1,0,0,0},{1,0,0,1},{1,0,0,2},{1,0,0,3},     {1,0,1,0},{1,0,1,1},{1,0,1,2},{1,0,1,3},     {1,0,2,0},{1,0,2,1},{1,0,2,2},{1,0,2,3},     {1,0,3,0},{1,0,3,1},{1,0,3,2},{1,0,3,3},     {1,1,0,0},{1,1,0,1},{1,1,0,2},{1,1,0,3},     {1,1,1,0},{1,1,1,1},{1,1,1,2},{1,1,1,3},     {1,1,2,0},{1,1,2,1},{1,1,2,2},{1,1,2,3},     {1,1,3,0},{1,1,3,1},{1,1,3,2},{1,1,3,3},     {1,2,0,0},{1,2,0,1},{1,2,0,2},{1,2,0,3},     {1,2,1,0},{1,2,1,1},{1,2,1,2},{1,2,1,3},     {1,2,2,0},{1,2,2,1},{1,2,2,2},{1,2,2,3},     {1,2,3,0},{1,2,3,1},{1,2,3,2},{1,2,3,3},     {1,3,0,0},{1,3,0,1},{1,3,0,2},{1,3,0,3},     {1,3,1,0},{1,3,1,1},{1,3,1,2},{1,3,1,3},     {1,3,2,0},{1,3,2,1},{1,3,2,2},{1,3,2,3},     {1,3,3,0},{1,3,3,1},{1,3,3,2},{1,3,3,3},     {2,0,0,0},{2,0,0,1},{2,0,0,2},{2,0,0,3},     {2,0,1,0},{2,0,1,1},{2,0,1,2},{2,0,1,3},     {2,0,2,0},{2,0,2,1},{2,0,2,2},{2,0,2,3},     {2,0,3,0},{2,0,3,1},{2,0,3,2},{2,0,3,3},     {2,1,0,0},{2,1,0,1},{2,1,0,2},{2,1,0,3},     {2,1,1,0},{2,1,1,1},{2,1,1,2},{2,1,1,3},     {2,1,2,0},{2,1,2,1},{2,1,2,2},{2,1,2,3},     {2,1,3,0},{2,1,3,1},{2,1,3,2},{2,1,3,3},     {2,2,0,0},{2,2,0,1},{2,2,0,2},{2,2,0,3},     {2,2,1,0},{2,2,1,1},{2,2,1,2},{2,2,1,3},     {2,2,2,0},{2,2,2,1},{2,2,2,2},{2,2,2,3},     {2,2,3,0},{2,2,3,1},{2,2,3,2},{2,2,3,3},     {2,3,0,0},{2,3,0,1},{2,3,0,2},{2,3,0,3},     {2,3,1,0},{2,3,1,1},{2,3,1,2},{2,3,1,3},     {2,3,2,0},{2,3,2,1},{2,3,2,2},{2,3,2,3},     {2,3,3,0},{2,3,3,1},{2,3,3,2},{2,3,3,3},     {3,0,0,0},{3,0,0,1},{3,0,0,2},{3,0,0,3},     {3,0,1,0},{3,0,1,1},{3,0,1,2},{3,0,1,3},     {3,0,2,0},{3,0,2,1},{3,0,2,2},{3,0,2,3},     {3,0,3,0},{3,0,3,1},{3,0,3,2},{3,0,3,3},     {3,1,0,0},{3,1,0,1},{3,1,0,2},{3,1,0,3},     {3,1,1,0},{3,1,1,1},{3,1,1,2},{3,1,1,3},     {3,1,2,0},{3,1,2,1},{3,1,2,2},{3,1,2,3},     {3,1,3,0},{3,1,3,1},{3,1,3,2},{3,1,3,3},     {3,2,0,0},{3,2,0,1},{3,2,0,2},{3,2,0,3},     {3,2,1,0},{3,2,1,1},{3,2,1,2},{3,2,1,3},     {3,2,2,0},{3,2,2,1},{3,2,2,2},{3,2,2,3},     {3,2,3,0},{3,2,3,1},{3,2,3,2},{3,2,3,3},     {3,3,0,0},{3,3,0,1},{3,3,0,2},{3,3,0,3},     {3,3,1,0},{3,3,1,1},{3,3,1,2},{3,3,1,3},     {3,3,2,0},{3,3,2,1},{3,3,2,2},{3,3,2,3},     {3,3,3,0},{3,3,3,1},{3,3,3,2},{3,3,3,3} }; 这是每个字节固定的查找或者建树的规则。

在网上查了资料，与我介绍的这种不同吧， 我设计的是一种树形的存储结构： ，每棵字节树含有256个节点，data节点后面再接入下一个字节树，数据存储的时候按照规则建树，查询的时候只要按照规则查询就行了。

搜“暴雪哈希算法”