Question: 下面的文件操作哪里出错了？急求解答，谢谢了

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

int get_run(LoserTree &ls,WorkArea &wa,int &rmax,int rc,FILE * &fi,FILE * &fo){     //求得一个初始归并段，fi为输入文件指针，f0为输出文件指针     int q,minimax;     while(wa[ls[0]].rnum==rc){//选得的MINIMAX记录属当前段时         q=ls[0];//q指示MINIMAX记录在wa中的位置         minimax=wa[q].key;         if(!fwrite(&wa[q].rec,sizeof(ElemType),1,fo)){//将刚选好的MINIMAX记录写入输出文件             cout<<"Fail to write data!"<<endl;             return ERROR;         }//if         if(feof(fi)){wa[q].rnum=rmax+1;wa[q].key=MAXKEY;}//输入文件结束，虚设记录（属”rmax+1"段）         else{             if(!fread(&wa[q].rec,sizeof(ElemType),1,fi)){//从输入文件读入下一记录                 cout<<"Fail to read data!"<<endl;                 return ERROR;             }//if             wa[q].key=wa[q].rec.key;//提取关键字             if(wa[q].key<minimax){//新读入的记录属下一段                 rmax=rc+1;wa[q].rnum=rmax;             }             else wa[q].rnum=rc;//新读入的记录属当前段         }         Select_MinMax(ls,wa,q);//选择新的MINIMAX记录     }//while     return OK; }//get_run  int Replace_Selection(LoserTree &ls,WorkArea &wa,FILE * &fi,FILE * &fo){     //在败者树ls和内存工作区wa上用置换-选择排序求初始归并段，fi为输入文件（只读文件）指针，fo为输出文件（只写文件）指针，两个文件均已打开     int rc,rmax;     if(!Construct_Loser(ls,wa,fi)){//初建败者树         cout<<"Fail to construct the loser_tree!"<<endl;         return ERROR;     }//if     rc=rmax=1;//rc指示当前生成的初始归并段的段号，rmax指示wa中的关键字所属初始归并段的最大段号     while(rc<=rmax){//“rc=rmax+1"标志输入文件的置换——选择排序已完成         if(!get_run(ls,wa,rmax,rc,fi,fo)){//求得一个初始归并段             cout<<"Fail to get initial merge section!"<<endl;             return ERROR;         }//if         if(!fwrite("*",sizeof(ElemType),1,fo)){//将段结束标志写入输出文件             cout<<"Fail to write symbol in the end!"<<endl;             return ERROR;         }//if         rc=wa[ls[0]].rnum;//设置下一段的段号     }     return OK; }//Replace_Selection int Replace_Selection_author(){     LoserTree ls;     WorkArea wa;     FILE * fi,*fo;     int i,a[LIST_INIT_SIZE-1];     fi=fopen("e:\\before_sort","rb");     fo=fopen("e:\\before_sort","wb");     //for(i=1;i<L.length;i++){     for(i=1;i<L.length;i++) 		cout<<L.r[i].key<<" ";     cout<<endl;     cout<<L.r+1<<endl;     i=fwrite(&L.r[1],sizeof(ElemType),L.length-1,fo);     cout<<i<<endl;         if(!i){//将待排数据写入文件             cout<<"Fail to write data to file before sorted!"<<endl;             return ERROR;         }//if     //}     //while(!feof(fi)){     cout<<a<<endl;         if(!fread(a,sizeof(ElemType),L.length-1,fi)){//从输出文件读入下一记录             cout<<"Fail to read data from file before sort!"<<endl;             return ERROR;         }//if     //}     cout<<"The list before sort is:";     for(i=1;i<L.length;i++) 		cout<<a[i]<<" ";     cout<<endl;     fo=fopen("e:\\after_sort.txt","at+");     if(!Replace_Selection(ls,wa,fi,fo)){         cout<<"Fail to sort data by Replace_Selection!"<<endl;         return ERROR;     }     fi=fopen("e:\\after_sort.txt","at+");     i=0;     cout<<"The list after sort is:";     while(!feof(fi)){         if(!fread(a+(i++),sizeof(ElemType),1,fi)){//从输出文件读入下一记录             cout<<"Fail to read data from file sorted!"<<endl;             return ERROR;         }//if         cout<<a[i]<<" ";     }     cout<<endl;     fclose(fi);     fclose(fo);     return OK; }//Replace_Selection_author int Sort_List(){     int choice=0;     while(1){         cout<<endl;         cout<<"*****************************************************"<<endl;         cout<<"*1、Sort the list by quick_sort created by author*"<<endl;         cout<<"*2、Sort the list by quick_sort created by system*"<<endl;         cout<<"*3、Sort the list by substitute_choice_sort created by author*"<<endl;         cout<<"*4、Sort the list by substitute_choice_sort created by system*"<<endl;         cout<<"*5、Return to main menu*"<<endl;         cout<<"*****************************************************"<<endl;         cout<<"please enter your choice(1~5):";         cin>>choice;         switch(choice){             case 1:if(!QuickSort())cout<<"Fail to sort the list by quick_sort created by author!"<<endl;break;             case 2:if(!QuickSort_system())cout<<"Fail to sort the list by quick_sort created by system!"<<endl;break;             case 3:if(!Replace_Selection_author())cout<<"Fail to sort the list by substitute_choice_sort created by author!"<<endl;break;             case 4:if(!QuickSort())cout<<"Fail to sort the list by substitute_choice_sort created by system!"<<endl;break;             case 5:return OK;             default:cout<<"Input Error!Please enter the integer between 1 and 5."<<endl;         }     } 	return OK; } /*int quiksort(SqList L){//快速排序     int choice=0;     cout<<endl;     cout<<"*****************************************************"<<endl;     cout<<"* 1、Use the quicksort by author       2、Use the quicksort by system*"<<endl;     cout<<"*****************************************************"<<endl;     cout<<"please enter your choice(1~2):";     while(1){         cin>>choice;         case 1:if(!QuickSort(L))cout<<"Fail to;     } }*/  int main(){     int i,choice,a[LIST_INIT_SIZE-1]={2,3,4,9,8,5,6,1,7,10}; 	ElemType e;     if(InitList_Sq()<1){         printf("Fail to initialize the list!\n");         return ERROR;     }//if     L.length=1;     for(i=2;i<=LIST_INIT_SIZE;i++){         e.key=a[i-2];         if(ListInsert_Sq(i,e)<1)return ERROR;     } 	while(1){         initialization();//输出主菜单         cin>>choice;         switch(choice){         case 1:             if(!initialize_list())//输入待排数据                 cout<<"Fail to create the list!"<<endl;             break;         case 2:             Show_List();//输出待排数据             break;         case 3:             Sort_List();//对数据进行排序             break;         case 4:             cout<<"Thank you for your use.Hope you use our system again!"<<endl;             return 0;         default:             cout<<"Input Error!Please enter 1~4";             break;         } 	} 	return 0; }

//整体存储用的是SqList，虽然此程序key为int,用数组存储比较方便，但考虑到以后数据的复杂性，还是用结构体比较好 #include<stdio.h> #include<stdlib.h> #include<iostream> #include<list> #include<algorithm> using namespace std; #define LIST_INIT_SIZE 11//线性表存储空间的初始分配量 #define LISTINCREMENT 10 #define ERROR 0 #define OK 1 #define OVERFLOW -1 #define w 5 #define MAXKEY 1000 typedef struct{     int key; }ElemType; typedef struct{     ElemType *r;//存储空间基址     int length;//当前长度     int listsize;//当前分配的存储容量（以sizeof(ElemType)为基本单位） }SqList; SqList L; typedef struct{     ElemType rec;//记录     int key;//从记录中抽取的关键字     int rnum;//所属归并段的段号 }RcdNode,WorkArea[w];//内存工作区，容量为w typedef int LoserTree[w]; int InitList_Sq(){//构造空顺序存储的线性表 	L.r=(ElemType *)malloc(LIST_INIT_SIZE*sizeof(ElemType)); 	if(!L.r)exit(OVERFLOW); 	L.length=0; 	L.listsize=LIST_INIT_SIZE; 	return OK; }//InitList_L int ListInsert_Sq(int i,ElemType e){     //在顺序线性表L中第i个位置之前插入新的元素e,i的合法值为1<=i<=L.length+1     int p,q;     ElemType* newbase;     if(i<1||i>L.length+1)return ERROR;//i值不合法     if(L.length>=L.listsize){//当前存储空间已满，增加分配         newbase=(ElemType *)realloc(L.r,(L.listsize+LISTINCREMENT)*sizeof(ElemType));         if(!newbase)exit(OVERFLOW);//存储分配失败         L.r=newbase;//新基址         L.listsize+=LISTINCREMENT;//增加存储容量     }     for(p=L.length-1,q=i-1;p>=q;--p)L.r[p+1]=L.r[p];//插入位置及之后的元素右移     L.r[q]=e;//插入e     ++L.length;//表长增1     return OK; }//ListInsert_Sq int Partition(int low,int high){     //交换顺序表L中子表L.r[low..high]的记录，使枢纽记录到位，并返回其所在位置，此时在它之前（后）的记录金不大（小）于它。     int pivotloc;     L.r[0]=L.r[low];//用子表的第一个记录作为枢纽记录     pivotloc=L.r[low].key;//枢纽记录关键字     while(low<high){//从表的两端交替地向中间扫描         while(low<high&&L.r[high].key>=pivotloc)--high;         L.r[low]=L.r[high];//将比枢纽记录小的记录交换到低端         while(low<high&&L.r[low].key<=pivotloc)++low;         L.r[high]=L.r[low];//将比枢纽记录大的记录交换到高端     }//while     L.r[low]=L.r[0];//枢纽记录到位     return low;//返回枢纽所在位置 }//Partition int QSort(int low,int high){     //对顺序表L中的子序列L.r[low.high]作快速排序     int pivotloc;     if(low<high){         pivotloc=Partition(low,high);//将L.r[low..high]一分为二         if(!QSort(low,pivotloc-1))return ERROR;//对低子表递归排序，pivotloc是枢纽位置         if(!QSort(pivotloc+1,high))return ERROR;//对低子表递归排序，pivotloc是枢纽位置     }//if     return OK; }//QSort int QuickSort(){     //对顺序表L作快速排序     int a[LIST_INIT_SIZE],i;     for(i=1;i<LIST_INIT_SIZE;i++)         a[i]=L.r[i].key;     if(!QSort(1,L.length-1))return ERROR;     printf("The list after sort is:");     for(i=1;i<LIST_INIT_SIZE;i++)         printf("%d ",L.r[i].key);     printf("\n");     for(i=1;i<LIST_INIT_SIZE;i++)         L.r[i].key=a[i];     return OK; }//QuickSort  //初始化系统界面 void initialization(){     cout<<endl;     cout<<"                 Welcome to Sort System"<<endl;     cout<<"*****************************************************"<<endl;     cout<<"* 1、Initialize the list           2、Show the list *"<<endl;     cout<<"* 3、Sort the list               4、Quit the game *"<<endl;     cout<<"*****************************************************"<<endl;     cout<<"please enter your choice(1~4):";     return; }  int initialize_list(){//输入待排数据     int i;     ElemType e;     printf("Please enter %d integers between 1 and 100(Example:1 2 3······):\n",LIST_INIT_SIZE-1);     L.length=1;     for(i=2;i<=LIST_INIT_SIZE;i++){         scanf("%d",&e.key);         if(ListInsert_Sq(i,e)<1)return ERROR;     }     printf("Success to initialize the list!\nThe list is ");     for(i=1;i<LIST_INIT_SIZE;i++)         printf("%d ",L.r[i].key);     return OK; }//initialize_list  int Show_List(){     int i;     printf("The list is ");     for(i=1;i<LIST_INIT_SIZE;i++)         printf("%d ",L.r[i].key);     printf("\n");     return OK; }  int QuickSort_system(){ 	//list<int>mylist; 	//list::vietor 	int i,a[LIST_INIT_SIZE]; 	//printf("The list before sort is:"); 	for(i=1;i<L.length;i++) 		a[i]=L.r[i].key; 		//mylist.push_back(L.r[i].key); 	//sort(mylist.begin(),mylist.end()); 	sort(a+1,a+L.length); 	cout<<"The list after sort is:"; 	for(i=1;i<L.length;i++) 		cout<<a[i]<<" "; 	cout<<endl; 	return OK; }  void Select_MinMax(LoserTree &ls,WorkArea wa,int q){     //从wa[q]起到败者树的根比较选择MINIMAX记录，并由q指示它所在的归并段     int t,p,temp;     for(t=(w+q)/2,p=ls[t];t>0;t=t/2,p=ls[t])         if(wa[p].rnum<wa[q].rnum||wa[p].rnum==wa[q].rnum&&wa[p].key<wa[q].key){             temp=q;q=ls[t];ls[t]=temp;//q指示新的胜利者         }     ls[0]=q; }//Select_MinMax int Construct_Loser(LoserTree &ls,WorkArea &wa,FILE * &fi){     //输入w个记录到内存工作区wa,建得败者树ls,选出关键字最小的记录并由s指示其在wa中的位置     int i;     for(i=0;i<w;i++)         wa[i].rnum=wa[i].key=ls[i]=0;//工作区初始化     for(i=w-1;i>=0;--i){         if(!fread(&wa[i].rec,sizeof(ElemType),1,fi)){//输入一个记录             cout<<"Fail to read data!"<<endl;             return ERROR;         }//if         wa[i].key=wa[i].rec.key;//提取关键字         wa[i].rnum=1;//其段号为“1”         Select_MinMax(ls,wa,i);//调整败者     }//for     return OK; }//Construct_Loser

需要看下完整代码？


Question: 帮我在main函数里面加上调用void ShortestPath(int num)的，不要报错

num应该等于几？


Question: 本人初学c++，有问题问一下各位大大

各自有不同的函数声明

来学习一下~~~~~~~~~~~

C/C++头文件一览  C、传统 C++ #include <assert.h>    //设定插入点 #include <ctype.h>     //字符处理 #include <errno.h>     //定义错误码 #include <float.h>     //浮点数处理 #include <fstream.h>    //文件输入／输出 #include <iomanip.h>    //参数化输入／输出 #include <iostream.h>   //数据流输入／输出 #include <limits.h>    //定义各种数据类型最值常量 #include <locale.h>    //定义本地化函数 #include <math.h>     //定义数学函数 #include <stdio.h>     //定义输入／输出函数 #include <stdlib.h>    //定义杂项函数及内存分配函数 #include <string.h>    //字符串处理 #include <strstrea.h>   //基于数组的输入／输出 #include <time.h>     //定义关于时间的函数 #include <wchar.h>     //宽字符处理及输入／输出 #include <wctype.h>    //宽字符分类 ////////////////////////////////////////////////////////////////////////// 标准 C++ （同上的不再注释） #include <algorithm>    //STL 通用算法 #include <bitset>     //STL 位集容器 #include <cctype> #include <cerrno> #include <clocale> #include <cmath> #include <complex>     //复数类 #include <cstdio> #include <cstdlib> #include <cstring> #include <ctime> #include <deque>      //STL 双端队列容器 #include <exception>    //异常处理类 #include <fstream> #include <functional>   //STL 定义运算函数（代替运算符） #include <limits> #include <list>      //STL 线性列表容器 #include <map>       //STL 映射容器 #include <iomanip> #include <ios>       //基本输入／输出支持 #include <iosfwd>     //输入／输出系统使用的前置声明 #include <iostream> #include <istream>     //基本输入流 #include <ostream>     //基本输出流 #include <queue>      //STL 队列容器 #include <set>       //STL 集合容器 #include <sstream>     //基于字符串的流 #include <stack>      //STL 堆栈容器     #include <stdexcept>    //标准异常类 #include <streambuf>    //底层输入／输出支持 #include <string>     //字符串类 #include <utility>     //STL 通用模板类 #include <vector>     //STL 动态数组容器 #include <cwchar> #include <cwctype> using namespace std; ////////////////////////////////////////////////////////////////////////// C99 增加 #include <complex.h>   //复数处理 #include <fenv.h>    //浮点环境 #include <inttypes.h>  //整数格式转换 #include <stdbool.h>   //布尔环境 #include <stdint.h>   //整型环境 #include <tgmath.h>   //通用类型数学宏

这都不是事，给楼主提一个建议：自主学习。虽然是初学，但百度一下自然就会明白。要不以后遇见其他问题你会更头疼的。

有字符串当然要#include <string.h>

引用 16 楼 zhao4zhong1 的回复:[quote=引用 6 楼 zhao4zhong1 的回复:] 楼主为什么不敢自己亲自打开include目录下的这些文件一探究竟呢？ 正解！[/quote]前提是楼主要知道#include作用

不同的头文件包含不同的内容。

这三个每个的意思都不同 #include <stdio.h>  C语言标准的输入输出函数 #include <stdlib.h>  C语言字符串转换函数，内存分配函数，过程控制函数 #include <string.h>  C语言字符串处理函数 都有各自的用处

需要调用函数就#include 对应的头文件  man strcpy  NAME      stpcpy, stpncpy, strcpy, strncpy -- copy strings  LIBRARY      Standard C Library (libc, -lc)  SYNOPSIS      #include <string.h>  man fprintf  NAME        printf, fprintf, sprintf, snprintf, vprintf, vfprintf, vsprintf, vsnprintf - formatted output conversion  SYNOPSIS        #include <stdio.h>         int printf(const char *format, ...);        int fprintf(FILE *stream, const char *format, ...);  man system NAME        system - execute a shell command  SYNOPSIS        #include <stdlib.h>         int system(const char *command);

恩恩，编译器的源码不一定一样，都包起来吧。不要纠结了。 而且使用相应函数就要包含相应h，所以多包涵是正确的，指望别的h包含的想法已执行是很差的 #include <stdio.h> 一般是printf之类的 #include <stdlib.h> 一般是malloc之类的 #include <string.h> 一般是memcpy之类的 不用也可以不包含

不同函数在不同的头文件的，有些函数在哪个头文件里，如果用户使用了，那么就将它的头文件包涵进来，就这么个意思！

不要纠结这个问题，想具体知道.h是干吗用的可以百度  对于编程来说，如果怕出错可以都加上，嫌看着不舒服就一个个去掉再编译，不报错就OK

引用 6 楼 zhao4zhong1 的回复:楼主为什么不敢自己亲自打开include目录下的这些文件一探究竟呢？ 正解！

不同头文件含有不同的声明

不要纠结这种问题，久了就自然知道了

楼主为什么不敢自己亲自打开include目录下的这些文件一探究竟呢？

引用 3 楼 promisehope 的回复:我也不清楚，就是看一个程序出下了3个头文件，我以前自己写的程序都是一个，就问问这3个有什么区别 你以前只用过#include <stdio.h>？ 还有更多的头文件值得你去了解。 网搜“C语言 头文件的使用”

头文件里有自己需要调用的函数。


Question: 程序跑一段时间崩溃，出现严重问题,求高手!!!

可能是内存泄露了，你程序里面有木有递归调用之类的函数。或者你可否代码贴出来看看。因为程序能运行起来应该是没有问题，而运行了之后再出现问题的话应该是内存不足照成之类的

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

请问楼主如何解决了

客服端跟服务器端进行socket通信时，服务器异常断开，而客户端并不知道服务器已经断开，继续向服务器发送数据，从而引发了SIGPIPE信号，内核响应这个信号，强行终止了程序； signal(SIGPIPE, SIG_IGN);

基本上就是内存泄露或是指针访问了无效地址。注意视频流获取后要及时释放。调试可以缩小范围，比如只保留视频流活取，其余的功能都去掉。然后逐次增加功能，直到出现问题。


Question: 新人求助  const声明的指针为什么没赋值也报错

在标准中，这样确实不允许，gcc请开启严格模式

引用 3 楼 我是冰的回复:int * a可以cast成const int * 反过来不行 朋友 我纠正一下，const_cast<T>只能脱去变量的const,即你可以把const int *转为int*

引用 1 楼 user-4 的回复:编译器做类型检查，const 指针不能赋值给非const指针，这个是语法规定，报错是应当的。至于你到底有没有修改内存，那是你自己的事。谢谢谢谢，那么这样就行了对吗？ #include"stdio.h" #include"stdbool.h" bool s(const int a[],int n,int key) { 	for(const int *i=a;i<a+n;i++) 	{ 		if(*i==key) 		{ 			return 1; 		} 	} 	return 0; } int main(void) { 	int a[5],b; 	for(int i=0;i<5;i++) 	{ 		a[i]=i; 	} 	scanf("%d",&b); 	printf("%d",s(a,5,b)); }

int * a可以cast成const int * 反过来不行

楼上说的对。问题就出在a赋值给i。出现类型错误，但是在不同的编译器下编译结果不一样，换句话linux下gcc编译只是一个警告。 	int i;	     for(i=0;i<n;i++)     {         if(*(a+i)==key) 这样写也挺好的，谁都能看懂。


Question: 问个#if预编译的问题，谢谢

最后发现是编译器的问题，谢谢各位

$ cpp a.c  # 1 "a.c" # 1 "<built-in>" # 1 "<command-line>" # 1 "a.c"        unsigned char i; i = (14/8+1);  这是预处理后的结果

我是在linux下用C 写的，使用gcc编译，得出结果是2。我感觉你问题应该出在 除号“/”上，C语言内 / 表示取整，不是到你那个编译器是怎么定义的。

vs 测试 2


Question: 基础问题：为什么extern声明二位数组时，列大小必须给出？

多维数组最好每一维都给出具体值  此外，其实压根不需要多维数组，就一维数组，自己计算偏移，还简单实用点

不要纠结，行列都给出

引用 5 楼 mymtom 的回复:extern char a[][]; 如果不给出第一维的大小，  a[1][1] = 1;  当访问元素a[1][1]时编译器无法计算地址的. 哦，明白了。你的意思是编译器不需要知道数组的大小，但必须能找到某个数组元素的位置。 一维数组的情况下，程序员写个a[3]，编译器根据首地址+3个单位就能找到a[3] 二维数组，程序员写个a[2][6]，编译器需要移动2*第一维大小+6就能找到，如果不写第一维大小，编译器就不知道乘于几，也就找不到a[2][6]。 多谢。谢谢大家。

因为数组只有一维，二维是一维的递归定义，除了一维的那维（行）可以省略，其余必须给出

如果连列维度都不想给出，那直接用二级指针即可。只不过编译器也就无法在编译期提供更多的数组维度的检查了。

一般来说根据数组的元素个数加上列的信息就可以计算出行的数目。

每个维数，最好都给出


Question: 二叉树的建立，采用while switch（）后执行起来就不对了，大神们帮忙看看

非常感谢您的修改

修改如下：  #include<stdio.h> #include<stdlib.h> #include<malloc.h> #define OVERFLOW -1 typedef char TElemType; typedef struct BitNode { 	TElemType data; 	struct BitNode *lchild, *rchild; }BitNode, *BitTree; typedef struct QNode { 	BitNode data; 	struct QNode *next; }QNode, *Queueptr; typedef struct { 	Queueptr front; 	Queueptr rear; }LinkQueue; //初始化，就是建一棵空树？ BitTree BitTreeInit(BitTree *pBT) { 	//BT = (BitTree)malloc(sizeof(BitNode)); 	*pBT = NULL; 	return *pBT; } BitTree BitTreeCreat(BitTree *pBT) { 	char c; 	scanf("%c", &c); 	getchar();   //zx 读入回车 	if (c == ' ')  *pBT = NULL; 	else 	{ 		if (!(*pBT = (BitTree)malloc(sizeof(BitNode)))) 			exit(OVERFLOW); 		(*pBT)->data = c; 		printf("%c的左节点：", c); 		BitTreeCreat(&((*pBT)->lchild)); 		printf("%c的右节点：", c); 		BitTreeCreat(&((*pBT)->rchild)); 	} 	return *pBT; } void BitTreeEmpty(BitTree BT) { 	if (!BT) printf("树为空!\n"); 	else printf("树非空!\n"); } void visit(BitTree BT) { 	printf("%c", BT->data); } void PreOrderTraverse(BitTree BT) { 	if (BT) 	{ 		visit(BT); 		PreOrderTraverse(BT->lchild); 		PreOrderTraverse(BT->rchild); 	} } void InOrderTraverse(BitTree BT) { 	if (BT) 	{ 		InOrderTraverse(BT->lchild); 		visit(BT); 		InOrderTraverse(BT->rchild); 	} } void PostOrderTraverse(BitTree BT) { 	if (BT) 	{ 		PostOrderTraverse(BT->lchild); 		PostOrderTraverse(BT->rchild); 		visit(BT); 	} } void InitQueue(LinkQueue *Q) { 	Q->front = Q->rear = (Queueptr)malloc(sizeof(QNode));  //zx 队头、队尾指向同一节点？ 	if (!Q->front) exit(OVERFLOW); 	Q->front->next = NULL; } int QueueEmpty(LinkQueue *Q) { 	if (Q->front == Q->rear) return 1;//是==不是= 	else return 0; } void EnQueue(LinkQueue *Q, BitNode e) { 	QNode *p; 	p = (Queueptr)malloc(sizeof(QNode)); 	if (!p) exit(OVERFLOW); 	p->data = e; 	p->next = NULL; 	Q->rear->next = p; 	Q->rear = p; } void DeQueue(LinkQueue *Q, BitTree e) { 	QNode *p; 	p = Q->front->next; 	*e = p->data; 	Q->front->next = p->next; 	if (Q->rear == p) Q->rear = Q->front; 	free(p); } //广度优先遍历 void BFSTraverse(BitTree BT) { 	BitNode m; 	LinkQueue Q; 	InitQueue(&Q); 	EnQueue(&Q, *BT); 	while (!QueueEmpty(&Q)) 	{ 		DeQueue(&Q, &m); 		visit(&m); 		if (m.lchild) EnQueue(&Q, *(m.lchild)); 		if (m.rchild) EnQueue(&Q, *(m.rchild)); 	} } int BitTreeDepth(BitTree BT)  //求树的深度 { 	int dep1, dep2; 	if (BT == NULL) return 0; 	else 	{ 		dep1 = BitTreeDepth(BT->lchild); 		dep2 = BitTreeDepth(BT->rchild); 		if (dep1 > dep2)  return dep1 + 1; 		else return dep2 + 1; 	} } void BitCountleaf(BitTree BT, int *count) { 	if (BT) 	{ 		if (!BT->lchild && !BT->rchild) 			(*count)++; 		BitCountleaf(BT->lchild, count); 		BitCountleaf(BT->rchild, count); 	} } void BitTreeClear(BitTree BT) { 	if (BT) 	{ 		BitTreeClear(BT->lchild); 		BitTreeClear(BT->rchild); 		free(BT); 		BT = NULL; 	} } int main() { 	int i = 1, j, count = 0; 	BitTree BT = NULL; 	while (1) { 		printf("-----------------欢迎使用-------------------\n"); 		printf("请选择要进行的操作\n"); 		printf("1.初始化一棵树  2.建立一棵树     3.判断树是否为空\n"); 		printf("4.按先序遍历树  5.按中序遍历树   6.按后序遍历树\n"); 		printf("7.按层次遍历树  8.求树的深度     9.求树的叶子节点个数\n"); 		printf("0.把树清空\n"); 		printf("-----------------感谢使用-------------------\n"); 		scanf("%d", &j); 		getchar(); 		switch (j) { 		case 1:BT = BitTreeInit(&BT); break; 		case 2:printf("请输入二叉树(空格代表树的元素为空,最后输入空格键结束输入):\n"); 			BT = BitTreeCreat(&BT); break; 		case 3:BitTreeEmpty(BT); break; 		case 4:printf("先序遍历: "); 			PreOrderTraverse(BT); printf("\n"); break; 		case 5:printf("中序遍历:"); 			InOrderTraverse(BT); printf("\n"); break; 		case 6: printf("后序遍历:"); 			PostOrderTraverse(BT); printf("\n"); break; 		case 7:printf("层次遍历："); 			BFSTraverse(BT); printf("\n"); break; 		case 8:printf("该树的深度是%d\n", BitTreeDepth(BT)); break; 		case 9:BitCountleaf(BT, &count); 			printf("二叉树的叶子节点个数为:%d\n", count); break; 		case 0:BitTreeClear(BT); break; 		default: return 0;  //zx 		} 	} 	return 0; }

仅供参考：#include <iostream> #include <stack> #include <queue> #include <locale.h> using namespace std; typedef struct BiTNode {//二叉树结点     char data;                      //数据     struct BiTNode *lchild,*rchild; //左右孩子指针 } BiTNode,*BiTree; int CreateBiTree(BiTree &T) {//按先序序列创建二叉树     char data;     scanf("%c",&data);//按先序次序输入二叉树中结点的值（一个字符），‘#’表示空树     if (data == '#') {         T = NULL;     } else {         T = (BiTree)malloc(sizeof(BiTNode));         T->data = data;         //生成根结点         CreateBiTree(T->lchild);//构造左子树         CreateBiTree(T->rchild);//构造右子树     }     return 0; } void Visit(BiTree T) {//输出     if (T->data != '#') {         printf("%c ",T->data);     } } void PreOrder(BiTree T) {//先序遍历     if (T != NULL) {         Visit(T);               //访问根节点         PreOrder(T->lchild);    //访问左子结点         PreOrder(T->rchild);    //访问右子结点     } } void InOrder(BiTree T) {//中序遍历     if (T != NULL) {         InOrder(T->lchild);     //访问左子结点         Visit(T);               //访问根节点         InOrder(T->rchild);     //访问右子结点     } } void PostOrder(BiTree T) {//后序遍历     if (T != NULL) {         PostOrder(T->lchild);   //访问左子结点         PostOrder(T->rchild);   //访问右子结点         Visit(T);               //访问根节点     } } void PreOrder2(BiTree T) {//先序遍历(非递归) //访问T->data后，将T入栈，遍历左子树；遍历完左子树返回时，栈顶元素应为T，出栈，再先序遍历T的右子树。     stack<BiTree> stack;     BiTree p = T;//p是遍历指针     while (p || !stack.empty()) {   //栈不空或者p不空时循环         if (p != NULL) {             stack.push(p);          //存入栈中             printf("%c ",p->data);  //访问根节点             p = p->lchild;          //遍历左子树         } else {             p = stack.top();        //退栈             stack.pop();             p = p->rchild;          //访问右子树         }     } } void InOrder2(BiTree T) {//中序遍历(非递归) //T是要遍历树的根指针，中序遍历要求在遍历完左子树后，访问根，再遍历右子树。 //先将T入栈，遍历左子树；遍历完左子树返回时，栈顶元素应为T，出栈，访问T->data，再中序遍历T的右子树。     stack<BiTree> stack;     BiTree p = T;//p是遍历指针     while (p || !stack.empty()) {   //栈不空或者p不空时循环         if (p != NULL) {             stack.push(p);          //存入栈中             p = p->lchild;          //遍历左子树         } else {             p = stack.top();        //退栈，访问根节点             printf("%c ",p->data);             stack.pop();             p = p->rchild;          //访问右子树         }     } }  typedef struct BiTNodePost{     BiTree biTree;     char tag; } BiTNodePost,*BiTreePost; void PostOrder2(BiTree T) {//后序遍历(非递归)     stack<BiTreePost> stack;     BiTree p = T;//p是遍历指针     BiTreePost BT;     while (p != NULL || !stack.empty()) {//栈不空或者p不空时循环         while (p != NULL) {//遍历左子树             BT = (BiTreePost)malloc(sizeof(BiTNodePost));             BT->biTree = p;             BT->tag = 'L';//访问过左子树             stack.push(BT);             p = p->lchild;         }         while (!stack.empty() && (stack.top())->tag == 'R') {//左右子树访问完毕访问根节点             BT = stack.top();             stack.pop();//退栈             printf("%c ",BT->biTree->data);         }         if (!stack.empty()) {//遍历右子树             BT = stack.top();             BT->tag = 'R';//访问过右子树             p = BT->biTree;             p = p->rchild;         }     } }  void LevelOrder(BiTree T) {//层次遍历     if (T == NULL) return;     BiTree p = T;     queue<BiTree> queue;//队列     queue.push(p);//根节点入队     while (!queue.empty()) {    //队列不空循环         p = queue.front();      //对头元素出队         printf("%c ",p->data);  //访问p指向的结点         queue.pop();            //退出队列         if (p->lchild != NULL) {//左子树不空，将左子树入队             queue.push(p->lchild);         }         if (p->rchild != NULL) {//右子树不空，将右子树入队             queue.push(p->rchild);         }     } } int main() {     BiTree T;      setlocale(LC_ALL,"chs");     CreateBiTree(T);      printf("先序遍历        ：");PreOrder  (T);printf("\n");     printf("先序遍历(非递归)：");PreOrder2 (T);printf("\n");                                                printf("\n");     printf("中序遍历        ：");InOrder   (T);printf("\n");     printf("中序遍历(非递归)：");InOrder2  (T);printf("\n");                                                printf("\n");     printf("后序遍历        ：");PostOrder (T);printf("\n");     printf("后序遍历(非递归)：");PostOrder2(T);printf("\n");                                                printf("\n");     printf("层次遍历        ：");LevelOrder(T);printf("\n");      return 0; } //ABC##DE#G##F### //先序遍历        ：A B C D E G F //先序遍历(非递归)：A B C D E G F // //中序遍历        ：C B E G D F A //中序遍历(非递归)：C B E G D F A // //后序遍历        ：C G E F D B A //后序遍历(非递归)：C G E F D B A // //层次遍历        ：A B C D E F G //  ///       A ///      / ///     B ///    / \ ///   C   D ///      / \ ///     E   F ///      \ ///       G


Question: 热烈庆祝六一国际儿童节！散分＋广告

现在分还有木有？急需啊

我也来抢个沙发。。。

.....哦哈哈，，，赶上一波。。。。

.....哈哈哈

祝赵老湿61快乐

接分，祝六一节快乐！

支持分享技术成果。

顶赵老师

接分~

实力接分

接分

赵老湿 没事多散分

谢主隆恩！！！！

多给点分吧。。真心的。我要常顶你啊

顶赵老师,哈


Question: C语言多文件的编写求教

谢谢！！！！！！

是一全局变量

result是一全局变量，它的生存期是整个进程。 第一次： sum(arr,5);后result=19; 第二次 sum(arr,5);首先，result=0;被清零，相当于重新来过。所以最后result=19;


Question: 求各位大神指点，在五子棋的AI部分卡住了

搜这方面的开源项目。


Question: 如何用指针数组接收输入的任意个字符串

引用 16 楼 zhangxiangDavaid 的回复:[quote=引用 14 楼 u013147600 的回复:] [quote=引用 7 楼 zhangxiangDavaid 的回复:] 这样可好：  #include <stdio.h> #include <string.h> #define LINE 5 int i = 0, n = LINE; int l, len; char **str; char buf[100];    //每个字符串100个字符够吗？ int main() { 	//分配原始内存大小 	if (NULL == (str = malloc(sizeof(char*)*n))) 	{ 		fprintf(stderr, "can not malloc(%d*%d)\n", sizeof(char*), n); 		return 1; 	} 	while (1) 	{ 		fgets(buf, 100, stdin); 		if ('\n' == buf[0]) break;     //读入空行，结束 		//内存已满，扩充 		if (i == n) 		{ 			n += LINE; 			if (NULL == (str = realloc(str, sizeof(char*)*n))) 			{ 				fprintf(stderr, "can not realloc(%d*%d)\n", sizeof(char*), n); 				return 1; 			} 		} 		len = strlen(buf); 		buf[len - 1] = 0;  //去'\n' 		if (NULL == (str[i] = malloc(len - 1))) 		{ 			fprintf(stderr, "can not malloc(%d)\n", len - 1); 			return 1; 		} 		strcpy(str[i], buf); 		i++; 	} 	//打印 	for (l = 0; l < i; l++) printf("%s\n", str[l]); 	return 0; } //111111 //222222 //3333333 //44444444 //555555555 //zhangxiang //David // //111111 //222222 //3333333 //44444444 //555555555 //zhangxiang //David  对了，请问下你上面定义的 line变量的作用是什么?没看明白[/quote] 宏LINE是初始字符串个数以及每次的增量[/quote]谢谢哦

引用 17 楼 ForestDB 的回复:还请看malloc的文档。 我知道要动态分配内存可是之前分配不来，总是会出现内存问题

引用 14 楼 u013147600 的回复:[quote=引用 7 楼 zhangxiangDavaid 的回复:] 这样可好：  #include <stdio.h> #include <string.h> #define LINE 5 int i = 0, n = LINE; int l, len; char **str; char buf[100];    //每个字符串100个字符够吗？ int main() { 	//分配原始内存大小 	if (NULL == (str = malloc(sizeof(char*)*n))) 	{ 		fprintf(stderr, "can not malloc(%d*%d)\n", sizeof(char*), n); 		return 1; 	} 	while (1) 	{ 		fgets(buf, 100, stdin); 		if ('\n' == buf[0]) break;     //读入空行，结束 		//内存已满，扩充 		if (i == n) 		{ 			n += LINE; 			if (NULL == (str = realloc(str, sizeof(char*)*n))) 			{ 				fprintf(stderr, "can not realloc(%d*%d)\n", sizeof(char*), n); 				return 1; 			} 		} 		len = strlen(buf); 		buf[len - 1] = 0;  //去'\n' 		if (NULL == (str[i] = malloc(len - 1))) 		{ 			fprintf(stderr, "can not malloc(%d)\n", len - 1); 			return 1; 		} 		strcpy(str[i], buf); 		i++; 	} 	//打印 	for (l = 0; l < i; l++) printf("%s\n", str[l]); 	return 0; } //111111 //222222 //3333333 //44444444 //555555555 //zhangxiang //David // //111111 //222222 //3333333 //44444444 //555555555 //zhangxiang //David  对了，请问下你上面定义的 line变量的作用是什么?没看明白[/quote] 宏LINE是初始字符串个数以及每次的增量

基本原理就是先放缓存，不够存放的时候，长度翻倍

引用 7 楼 zhangxiangDavaid 的回复:这样可好：  #include <stdio.h> #include <string.h> #define LINE 5 int i = 0, n = LINE; int l, len; char **str; char buf[100];    //每个字符串100个字符够吗？ int main() { 	//分配原始内存大小 	if (NULL == (str = malloc(sizeof(char*)*n))) 	{ 		fprintf(stderr, "can not malloc(%d*%d)\n", sizeof(char*), n); 		return 1; 	} 	while (1) 	{ 		fgets(buf, 100, stdin); 		if ('\n' == buf[0]) break;     //读入空行，结束 		//内存已满，扩充 		if (i == n) 		{ 			n += LINE; 			if (NULL == (str = realloc(str, sizeof(char*)*n))) 			{ 				fprintf(stderr, "can not realloc(%d*%d)\n", sizeof(char*), n); 				return 1; 			} 		} 		len = strlen(buf); 		buf[len - 1] = 0;  //去'\n' 		if (NULL == (str[i] = malloc(len - 1))) 		{ 			fprintf(stderr, "can not malloc(%d)\n", len - 1); 			return 1; 		} 		strcpy(str[i], buf); 		i++; 	} 	//打印 	for (l = 0; l < i; l++) printf("%s\n", str[l]); 	return 0; } //111111 //222222 //3333333 //44444444 //555555555 //zhangxiang //David // //111111 //222222 //3333333 //44444444 //555555555 //zhangxiang //David  对了，请问下你上面定义的 line变量的作用是什么?没看明白

引用 11 楼 mewiteor 的回复:#include<stdio.h> #include<stdlib.h> #include<malloc.h> #include<string.h> int main() { 	char *str=NULL,**strs=NULL,*p; 	unsigned int str_size=0,strs_size=0,i; 	do 	{ 		char *tmp=(char*)realloc(str,++str_size*sizeof(char)); 		if(!tmp) 		{ 			free(str); 			fputs("out of memory",stderr); 			return 1; 		} 		str=tmp; 		str[str_size-1]=getchar(); 	}while(str[str_size-1]!='\n'); 	str[str_size-1]=0; 	for(p=strtok(str," \t");p;p=strtok(NULL," \t")) { 		char **tmp=(char**)realloc(strs,++strs_size*sizeof(char*)); 		if(!tmp) 		{ 			free(str); 			free(strs); 			fputs("out of memory",stderr); 			return 1; 		} 		strs=tmp; 		strs[strs_size-1]=p; 	} 	for(i=0;i<strs_size;++i) 		printf("%u:%s\n",i+1,strs[i]); 	free(strs); 	free(str); 	return 0; } 大神呀，测试过可以实现我的要求，谢谢啦

引用 7 楼 zhangxiangDavaid 的回复:这样可好：  #include <stdio.h> #include <string.h> #define LINE 5 int i = 0, n = LINE; int l, len; char **str; char buf[100];    //每个字符串100个字符够吗？ int main() { 	//分配原始内存大小 	if (NULL == (str = malloc(sizeof(char*)*n))) 	{ 		fprintf(stderr, "can not malloc(%d*%d)\n", sizeof(char*), n); 		return 1; 	} 	while (1) 	{ 		fgets(buf, 100, stdin); 		if ('\n' == buf[0]) break;     //读入空行，结束 		//内存已满，扩充 		if (i == n) 		{ 			n += LINE; 			if (NULL == (str = realloc(str, sizeof(char*)*n))) 			{ 				fprintf(stderr, "can not realloc(%d*%d)\n", sizeof(char*), n); 				return 1; 			} 		} 		len = strlen(buf); 		buf[len - 1] = 0;  //去'\n' 		if (NULL == (str[i] = malloc(len - 1))) 		{ 			fprintf(stderr, "can not malloc(%d)\n", len - 1); 			return 1; 		} 		strcpy(str[i], buf); 		i++; 	} 	//打印 	for (l = 0; l < i; l++) printf("%s\n", str[l]); 	return 0; } //111111 //222222 //3333333 //44444444 //555555555 //zhangxiang //David // //111111 //222222 //3333333 //44444444 //555555555 //zhangxiang //David  这么厉害，测试过可以成功，谢谢啦

还请看malloc的文档。

引用 2 楼 jiqiang01234 的回复:类似这个吗？  char* a[n]; char* p1="hello"; char* p2="world"; char* pn=...  a[0]=p1; a[1]=p2; ... a[n-1]=pn;   不是： 类似这种， 输入n个字符串 char *buf[]; for ( i = 0; scanf("%s", buf[i]); ++i) 	{ 		if(getchar()=='\n') 		{ 			break; 		} } 这个语法是错的，表达下我的意思

对了，是用C语言

引用 6 楼 user-7 的回复:你缓存在buf中。一部分一部分的读取不好吗。怎么做呀？我不知道怎么弄

引用 5 楼 jiqiang01234 的回复:c恐怕无法实现，c语言中没有所谓的“无长度要求的字符串”。字符串使用前， 必须得分配内存，如果无法提供确切的长度，字符串是无法分配的。应该是要动态分配内存  可是我弄不来

引用 4 楼 zhao4zhong1 的回复:仅供参考：#include <stdio.h> #include <stdlib.h> #include <malloc.h> int **newarr2d(int rows,int cols) {     int **p,i;      p=(int **)malloc(rows*sizeof(int *));     if (NULL==p) exit(1);     for (i=0;i<rows;i++) {         p[i]=(int *)malloc(cols*sizeof(int));         if (NULL==p[i]) exit(1);     }     return p; } void deletearr2d(int **p,int rows) {     int i;      for (i=0;i<rows;i++) {         free(p[i]);     }     free(p); } int main() {     int **arr2d,i,j,r,c;      r=4;     c=5;     //在堆中开辟一个4×5的二维int数组     arr2d=newarr2d(r,c);     for (i=0;i<r;i++) {         for (j=0;j<c;j++) {             arr2d[i][j]=i*c+j;         }     }     for (i=0;i<r;i++) {         for (j=0;j<c;j++) {             printf(" %2d",arr2d[i][j]);         }         printf("\n");     }     deletearr2d(arr2d,r);      r=6;     c=3;     //在堆中开辟一个6×3的二维int数组     arr2d=newarr2d(r,c);     for (i=0;i<r;i++) {         for (j=0;j<c;j++) {             arr2d[i][j]=i*c+j;         }     }     for (i=0;i<r;i++) {         for (j=0;j<c;j++) {             printf(" %2d",arr2d[i][j]);         }         printf("\n");     }     deletearr2d(arr2d,r);      return 0; } //  0  1  2  3  4 //  5  6  7  8  9 // 10 11 12 13 14 // 15 16 17 18 19 //  0  1  2 //  3  4  5 //  6  7  8 //  9 10 11 // 12 13 14 // 15 16 17 // 恩恩 我好好看下

你缓存在buf中。一部分一部分的读取不好吗。


Question: c语言读取txt数据一个一个读

so easy:  int main(void) { 	FILE *fi = fopen("IND.txt", "r"); 	FILE *fo = fopen("wucha.txt", "w"); 	int d; 	char c; 	int r; 	while (1) 	{ 		r = fscanf(fi, "%d%c", &d, &c); 		if (-1 == r) break; 		fprintf(fo, "%lg,", 2 * d + 13.76); 	} 	fclose(fi); 	fclose(fo); 	return 0; }

#include<stdio.h> int main() { 	int n; 	FILE *fin=fopen("IND.txt","r"),*fout=fopen("wucha.txt","w"); 	if(fin&&fout) 	{ 		while(fscanf(fin,"%d,",&n)!=EOF) 		{ 			double wucha=2*n+13.76; 			fprintf(fout,"%f,",wucha); 		} 	} 	if(fin)fclose(fin); 	if(fout)fclose(fout); 	return 0; }


Question: 程序有问题求高手

你用这段程序生成文件，在工程目录下找到该文件，然后把内容粘贴过去，再测试以上代码  int main(void) { 	FILE *f = fopen("american.txt", "w"); 	fclose(f); 	return 0; }

引用 5 楼 qq_26710209 的回复:[quote=引用 4 楼 zhangxiangDavaid 的回复:] [quote=引用 3 楼 qq_26710209 的回复:] [/code] 有一点需要注意：最后一个字符串也需要以换行结束。 还是无法运行，不知道为什么[/quote] 这个文件有吗？american.txt 我都测试过[/quote] 这个文件就是我自己乱打的6行单词的文件而已。我用的是dev，编译时没有错误可以生成exe，但是显示已停止工作[/quote] 应该是文件的路径有问题

引用 4 楼 zhangxiangDavaid 的回复:[quote=引用 3 楼 qq_26710209 的回复:] [/code] 有一点需要注意：最后一个字符串也需要以换行结束。 还是无法运行，不知道为什么[/quote] 这个文件有吗？american.txt 我都测试过[/quote] 这个文件就是我自己乱打的6行单词的文件而已。我用的是dev，编译时没有错误可以生成exe，但是显示已停止工作

引用 3 楼 qq_26710209 的回复:[/code] 有一点需要注意：最后一个字符串也需要以换行结束。 还是无法运行，不知道为什么[/quote] 这个文件有吗？american.txt 我都测试过

引用 1 楼 zhangxiangDavaid 的回复:修改如下：  #include <stdio.h> #include <stdlib.h> int main() { 	char *file = "american.txt"; /*american是同目录下的txt文件，有6行，每行1个单词*/ 	char **word; 	char c;   //zx 	FILE *in; 	int i = 0, j = 0; 	int num = 6; 	in = fopen(file, "r"); 	if ((word = (char**)malloc(sizeof(char*)*num)) == NULL) { 		printf("Allocate error\n"); 		exit(-1); 	} 	for (i = 0; i < num; i++) { 		if ((word[i] = (char*)malloc(sizeof(char) * 40)) == NULL) { 			printf("Allocate err. at %d line\n", __LINE__);   //zx 			exit(-1); 		} 	} 	//for (i = 0; i < num; i++) 	//	while (fgetc(in) != '\n') { 	//		*(*(word + i) + j) = fgetc(in); 	//		j++; 	//	} 	for (i = 0; i < num; i++) { 		while ('\n' != (c = fgetc(in))) { 			*(*(word + i) + j) = c; 			j++; 		} 		*(*(word + i) + j) = 0; 		j = 0; 	} 	fclose(in); 	printf("%s\n", word[0]); 	return 0; }  有一点需要注意：最后一个字符串也需要以换行结束。 还是无法运行，不知道为什么

引用 1 楼 弓长羊羽的回复:修改如下：  #include <stdio.h> #include <stdlib.h> int main() { 	char *file = "american.txt"; /*american是同目录下的txt文件，有6行，每行1个单词*/ 	char **word; 	char c;   //zx 	FILE *in; 	int i = 0, j = 0; 	int num = 6; 	in = fopen(file, "r"); 	if ((word = (char**)malloc(sizeof(char*)*num)) == NULL) { 		printf("Allocate error\n"); 		exit(-1); 	} 	for (i = 0; i < num; i++) { 		if ((word[i] = (char*)malloc(sizeof(char) * 40)) == NULL) { 			printf("Allocate err. at %d line\n", __LINE__);   //zx 			exit(-1); 		} 	} 	//for (i = 0; i < num; i++) 	//	while (fgetc(in) != '\n') { 	//		*(*(word + i) + j) = fgetc(in); 	//		j++; 	//	} 	for (i = 0; i < num; i++) { 		while ('\n' != (c = fgetc(in))) { 			*(*(word + i) + j) = c; 			j++; 		} 		*(*(word + i) + j) = 0; 		j = 0; 	} 	fclose(in); 	printf("%s\n", word[0]); 	return 0; }  有一点需要注意：最后一个字符串也需要以换行结束。


Question: C语言中scanf

同意1L。。

__int64 ％I64d 或 long long int %lld

不指定宽度%1d，scanf会把连续的数字当做一个整数，一次性读入，而int放不下17位长的整数，于是出现错误。


Question: 为什么数组分配的内存空间不连续？？

哦~~~之前试验的代码没改过来，，，，蒙了，，谢谢！

嘎嘎……指向数组的指针……每次递进……增加一个数组的大小……嘎嘎……


Question: C语言读取TXT文件，忽略文件空格，把内容写入数组中应该怎么实现？

为什么我用struct写了一个读取txt表格数据的程序运行时输出了许多不应该出现的数据呀？

弄好了

引用 5 楼 zhangxiangDavaid 的回复:引用 4 楼 miss46799 的回复:回复3楼，太赞！ 能帮我看看我这个么？运行出来都是0，但p的值是对的，感觉像D矩阵写入不对，不知道哪里错了请各位指导一下 txt文件如下0.5 -0.5 0.0 1.0 0.0 0.0 -0.5 -0.5 0.0 0.0 1.0 0.0 0.0 0.5 0.0 0.0 0.0 1.0 6个数一行，每个数之间都有一个空格 [code=c#include "stdafx.h" #include <stdio.h> #define MAXDATA 1000 double D[MAXDATA][6];// char ln[80];//用于存取读出数据的数组 FILE *f; int i,n; char *p;  int main(){ 	f=fopen("D:\\todel\\opengl\\ConsoleApplication3\\Debug\\1.txt","r");//打开txt文件 	if(NULL==f){ 		printf("Can not open file 1.txt!\n");//判断是否可以打开文件 		return 1; 	} 	i=0; 	while (1){ 		if (NULL==fgets(ln,80,f)) break; 		 p = ln ;  	   sscanf(p,"%f%f%f%f%f",&D[i][0],&D[i][1],&D[i][2],&D[i][3],&D[i][4],&D[i][5]); 		i++; 	 	} 	 	n=i; 	for (i=0;i<n;i++){ 			printf("%f %f %f %f %f %f\n",D[i][0],D[i][1],D[i][2],D[i][3],D[i][4]),&D[i][5]; 		} 	       fclose(f); 		return 0; 	}][/code]

引用 4 楼 miss46799 的回复:回复3楼，太赞！

回复3楼，太赞！

这样可好：  #include <stdio.h> #include <stdlib.h> #define SIZE_view 50 struct view_info { 	int id; 	char name[20]; 	int code; 	char shortname[20]; 	char LName[100]; }views[SIZE_view]; FILE *f; char buf[256]; char *p; int i, n; int main(void) { 	if (NULL == (f = fopen("1.txt", "r"))) 	{ 		fprintf(stderr, "Can not open file : 1.txt"); 		return 1; 	} 	i = n = 0; 	while (1) 	{ 		if (n == SIZE_view) break; 		if (NULL == fgets(buf, 256, f)) break; 		if ('\n' == buf[0]) continue;     //空行继续 		p = buf; 		sscanf(p, "%d%s%d%s%s", &views[n].id, views[n].name, &views[n].code, views[n].shortname, views[n].LName); 		n++; 	} 	do 	{ 		printf("%d %s %d %s %s\n", views[i].id, views[i].name, views[i].code, views[i].shortname, views[i].LName); 		i++; 	} while (i < n); 	fclose(f); 	return 0; }

buf是什么啊，我还不知道怎么用

你一行行读到自己的buf中，然后从buf中过滤空格解析到你的结构体


Question: 二叉树

仅供参考：#include <iostream> #include <stack> #include <queue> #include <locale.h> using namespace std; typedef struct BiTNode {//二叉树结点     char data;                      //数据     struct BiTNode *lchild,*rchild; //左右孩子指针 } BiTNode,*BiTree; int CreateBiTree(BiTree &T) {//按先序序列创建二叉树     char data;     scanf("%c",&data);//按先序次序输入二叉树中结点的值（一个字符），‘#’表示空树     if (data == '#') {         T = NULL;     } else {         T = (BiTree)malloc(sizeof(BiTNode));         T->data = data;         //生成根结点         CreateBiTree(T->lchild);//构造左子树         CreateBiTree(T->rchild);//构造右子树     }     return 0; } void Visit(BiTree T) {//输出     if (T->data != '#') {         printf("%c ",T->data);     } } void PreOrder(BiTree T) {//先序遍历     if (T != NULL) {         Visit(T);               //访问根节点         PreOrder(T->lchild);    //访问左子结点         PreOrder(T->rchild);    //访问右子结点     } } void InOrder(BiTree T) {//中序遍历     if (T != NULL) {         InOrder(T->lchild);     //访问左子结点         Visit(T);               //访问根节点         InOrder(T->rchild);     //访问右子结点     } } void PostOrder(BiTree T) {//后序遍历     if (T != NULL) {         PostOrder(T->lchild);   //访问左子结点         PostOrder(T->rchild);   //访问右子结点         Visit(T);               //访问根节点     } } void PreOrder2(BiTree T) {//先序遍历(非递归) //访问T->data后，将T入栈，遍历左子树；遍历完左子树返回时，栈顶元素应为T，出栈，再先序遍历T的右子树。     stack<BiTree> stack;     BiTree p = T;//p是遍历指针     while (p || !stack.empty()) {   //栈不空或者p不空时循环         if (p != NULL) {             stack.push(p);          //存入栈中             printf("%c ",p->data);  //访问根节点             p = p->lchild;          //遍历左子树         } else {             p = stack.top();        //退栈             stack.pop();             p = p->rchild;          //访问右子树         }     } } void InOrder2(BiTree T) {//中序遍历(非递归) //T是要遍历树的根指针，中序遍历要求在遍历完左子树后，访问根，再遍历右子树。 //先将T入栈，遍历左子树；遍历完左子树返回时，栈顶元素应为T，出栈，访问T->data，再中序遍历T的右子树。     stack<BiTree> stack;     BiTree p = T;//p是遍历指针     while (p || !stack.empty()) {   //栈不空或者p不空时循环         if (p != NULL) {             stack.push(p);          //存入栈中             p = p->lchild;          //遍历左子树         } else {             p = stack.top();        //退栈，访问根节点             printf("%c ",p->data);             stack.pop();             p = p->rchild;          //访问右子树         }     } }  typedef struct BiTNodePost{     BiTree biTree;     char tag; } BiTNodePost,*BiTreePost; void PostOrder2(BiTree T) {//后序遍历(非递归)     stack<BiTreePost> stack;     BiTree p = T;//p是遍历指针     BiTreePost BT;     while (p != NULL || !stack.empty()) {//栈不空或者p不空时循环         while (p != NULL) {//遍历左子树             BT = (BiTreePost)malloc(sizeof(BiTNodePost));             BT->biTree = p;             BT->tag = 'L';//访问过左子树             stack.push(BT);             p = p->lchild;         }         while (!stack.empty() && (stack.top())->tag == 'R') {//左右子树访问完毕访问根节点             BT = stack.top();             stack.pop();//退栈             printf("%c ",BT->biTree->data);         }         if (!stack.empty()) {//遍历右子树             BT = stack.top();             BT->tag = 'R';//访问过右子树             p = BT->biTree;             p = p->rchild;         }     } }  void LevelOrder(BiTree T) {//层次遍历     if (T == NULL) return;     BiTree p = T;     queue<BiTree> queue;//队列     queue.push(p);//根节点入队     while (!queue.empty()) {    //队列不空循环         p = queue.front();      //对头元素出队         printf("%c ",p->data);  //访问p指向的结点         queue.pop();            //退出队列         if (p->lchild != NULL) {//左子树不空，将左子树入队             queue.push(p->lchild);         }         if (p->rchild != NULL) {//右子树不空，将右子树入队             queue.push(p->rchild);         }     } } int main() {     BiTree T;      setlocale(LC_ALL,"chs");     CreateBiTree(T);      printf("先序遍历        ：");PreOrder  (T);printf("\n");     printf("先序遍历(非递归)：");PreOrder2 (T);printf("\n");                                                printf("\n");     printf("中序遍历        ：");InOrder   (T);printf("\n");     printf("中序遍历(非递归)：");InOrder2  (T);printf("\n");                                                printf("\n");     printf("后序遍历        ：");PostOrder (T);printf("\n");     printf("后序遍历(非递归)：");PostOrder2(T);printf("\n");                                                printf("\n");     printf("层次遍历        ：");LevelOrder(T);printf("\n");      return 0; } //ABC##DE#G##F### //先序遍历        ：A B C D E G F //先序遍历(非递归)：A B C D E G F // //中序遍历        ：C B E G D F A //中序遍历(非递归)：C B E G D F A // //后序遍历        ：C G E F D B A //后序遍历(非递归)：C G E F D B A // //层次遍历        ：A B C D E F G //  ///       A ///      / ///     B ///    / \ ///   C   D ///      / \ ///     E   F ///      \ ///       G

求大神们帮帮忙！

贴下CSNode的定义

这都三叉了？


Question: 如何让堆排序稳定

引用 3 楼 fly_dragon_fly 的回复:以大顶为例, heapify从三个中选出一个最大值, 如果有两个值相等, 你选择那一个, 就是用到这索引的时候 嗯，的确可以实现

引用 1 楼 mymtom 的回复:排序的两个重要动作就是比较和移动 所谓稳定的排序指的是 对于键值比较的结果为相等（==）的元素A和B，如果排序前A在B前，排序后A保持在B前面。 增加索引的意思就是增加键值（比如排序前的位置），当其他键值相同的时候，进行位置的比较。  谢谢版主，我理解了

可以自己建立一个保存开始时候元素的相对位置信息，如果排序后发现两个相等的元素的相对位置发生了变化，就换回来，这样就稳定了

引用 1 楼 mymtom 的回复:排序的两个重要动作就是比较和移动 所谓稳定的排序指的是 对于键值比较的结果为相等（==）的元素A和B，如果排序前A在B前，排序后A保持在B前面。 增加索引的意思就是增加键值（比如排序前的位置），当其他键值相同的时候，进行位置的比较。 版主威武!


Question: 编译出错帮忙看下

写全路径试试

好吧，这么奇葩，俺也没有招了

偶遇到类似问题都是用 “每次用/*...*/注释掉不同部分再重新编译，直到定位到具体语法出错的位置。” 的方法解决的。

没用过  装2008以及以上，   vc6好多不支持，太老了

引用 3 楼 hnwyllmm 的回复:头文件的路径配置了吗  配置了，我安装的是SDK 日期是2003年2月的,13个文件包，include文件夹53兆，lib文件夹154兆，请问下是VC6支持的最新SDK么？

头文件的路径配置了吗

引用 1 楼 hnwyllmm 的回复:缺少头文件..... 加了#include <commctrl.h>和#include <prsht.h>依旧报错

缺少头文件.....


Question: 点击其他程序菜单怎么发送消息


Question: 新手求指导

引用 6 楼 zhangxiangDavaid 的回复:[quote=引用 5 楼 u013685226 的回复:] getchar（）目的在于刷新缓冲区，以免下一次读入时，读入了缓冲区中剩余的\n 常见的用法还有 ： while（getchar（））； getchar刷新缓冲区？这个比喻不对。 刷新缓冲区用fflush(stdin);[/quote] 没错，准确的说是读取缓存区中剩余的字符。和刷新还是有区别的。

引用 5 楼 u013685226 的回复:getchar（）目的在于刷新缓冲区，以免下一次读入时，读入了缓冲区中剩余的\n 常见的用法还有 ： while（getchar（））； getchar刷新缓冲区？这个比喻不对。 刷新缓冲区用fflush(stdin);

楼上正解

我们所有的键盘输入都会放在一个buffer中（stdin流）。scanf()和getchar()都从这个buffer中取得数据。getchar()是为了读出 \n 然后，将buffer的指针指向下一个键盘输入。scanf（）函数会在读取非%c的时候一般会忽略空白字符。所以，如果本例中，如果scanf()读入的是%d的话。。就不需要getchar()。 我就随便一说。。你别当真

不是删除，而是“吃掉”。免得换行符作为后序读入

这里的getcahr()是读入回车符，以免影响下一次的scanf


Question: unsigned long型数据转二进制

引用 9 楼 zhao4zhong1 的回复:笑口常开，笑天下可笑之人。  按赵老湿往常的逻辑，似乎不是这样的。赵老湿的逻辑应当是我笑天下人，天下人亦笑我。

笑口常开，笑天下可笑之人。

引用 7 楼 zhao4zhong1 的回复:[quote=引用 6 楼 sholber 的回复:] 看到楼上有些人用的语言是C，而编程风格和编程习惯还停留在BASIC，哥决定再写一个新的版本： # include <limits.h>  # include <stddef.h>     typedef unsigned long INT32U;     void num_binary (INT32U vari, char * str)   {      for (size_t x = sizeof (INT32U) * CHAR_BIT; x > 0; x --)            * (str ++) = (vari >> x - 1 & 1) + '0';      * str = '\0';   } 请牢记：源代码本身的书写是否结构化或面向对象或符合设计模式或敏捷…并不重要，重要的是你是否使用结构化或面向对象或符合设计模式或敏捷…的方法命名标识符、阅读、修改、检查、测试源代码。  意思是你程序结构看上去再合理，再简洁，也不一定比看上去一团乱麻的程序结构在运行或修改时更不易出错，更方便修改，出错了更容易找到哪里出错和具体出错的原因，更容易改正错误。  试对比 图书馆（对图书的分类够结构化了吧） 和 搜索引擎（可看作是扁平化任何结构数据，仅支持全文检索） 哪个处理信息更方便、更高效。  所以 与其费劲去重构代码让其看上去更简洁、更合理 不如费劲学习grep、sed、awk、……这类全文搜索和批处理编辑的工具。  结构越复杂，越难修改，越难除错。 有时（甚至大多数时候），看上去越合理、越简洁的代码，运行起来性能越差，出错时查找原因越难，找到出错原因后改正越费劲。  程序员要做的不是尽力避免错误，而是聚焦在快速发现并改正错误。真正以快速方式轻易解决错误，“快速的失败”远胜过“预防错误”。Fred George [/quote]  赵老湿不但会用 C写一些看起来不像 C的代码，还擅长纸上谈兵啊。就一个计算2+3的程序，居然还扯上了设计模式和敏捷。还没参加乡试和殿试呢，就开始考虑如何当一个清官了，真是可笑。

引用 6 楼 sholber 的回复:看到楼上有些人用的语言是C，而编程风格和编程习惯还停留在BASIC，哥决定再写一个新的版本： # include <limits.h>  # include <stddef.h>     typedef unsigned long INT32U;     void num_binary (INT32U vari, char * str)   {      for (size_t x = sizeof (INT32U) * CHAR_BIT; x > 0; x --)            * (str ++) = (vari >> x - 1 & 1) + '0';      * str = '\0';   } 请牢记：源代码本身的书写是否结构化或面向对象或符合设计模式或敏捷…并不重要，重要的是你是否使用结构化或面向对象或符合设计模式或敏捷…的方法命名标识符、阅读、修改、检查、测试源代码。  意思是你程序结构看上去再合理，再简洁，也不一定比看上去一团乱麻的程序结构在运行或修改时更不易出错，更方便修改，出错了更容易找到哪里出错和具体出错的原因，更容易改正错误。  试对比 图书馆（对图书的分类够结构化了吧） 和 搜索引擎（可看作是扁平化任何结构数据，仅支持全文检索） 哪个处理信息更方便、更高效。  所以 与其费劲去重构代码让其看上去更简洁、更合理 不如费劲学习grep、sed、awk、……这类全文搜索和批处理编辑的工具。  结构越复杂，越难修改，越难除错。 有时（甚至大多数时候），看上去越合理、越简洁的代码，运行起来性能越差，出错时查找原因越难，找到出错原因后改正越费劲。  程序员要做的不是尽力避免错误，而是聚焦在快速发现并改正错误。真正以快速方式轻易解决错误，“快速的失败”远胜过“预防错误”。Fred George

仅供参考：#include <stdio.h> #include <stdlib.h> #include <string.h> #include <locale.h> int main() {     int i,v;     char bs[33];     char b[33];     char hs[9];     char h[9];     char s[4];     char *e;  // 十进制整数转二进制串；     i=1024;     ltoa(i,b,2);     sprintf(bs,"%032s",b);     printf("i=%d,bs=%s\n",i,bs); // 十进制整数转十六进制串；     i=1024;     ltoa(i,h,16);     sprintf(hs,"%08s",h);     printf("i=%d,hs=%s\n",i,hs); // 十六进制字符串转成十进制数     strcpy(hs,"00000400");     sscanf(hs,"%x",&i);     printf("hs=%s,i=%d\n",hs,i); // 二进制字符串转化为十六进制字符串；     strcpy(bs,"00000000000000000000010000000000");     i=strtol(bs,&e,2);     ltoa(i,h,16);     sprintf(hs,"%08s",h);     printf("bs=%s,hs=%s\n",bs,hs); // 二进制字符串转化为十进制数；     strcpy(bs,"00000000000000000000010000000000");     i=strtol(bs,&e,2);     printf("bs=%s,i=%d\n",bs,i); // 十六进制字符串转成二进制串     strcpy(hs,"00000400");     sscanf(hs,"%x",&i);     ltoa(i,b,2);     sprintf(bs,"%032s",b);     printf("hs=%s,bs=%s\n",hs,bs); // ASC\GBK字符串转十六进制串     strcpy(s,"a汉");     i=0;     while (1) {         if (0==s[i]) break;         sprintf(hs+i*2,"%02X",(unsigned char)s[i]);         i++;     }     setlocale(LC_ALL,"chs");     printf("s=%s,hs=%s\n",s,hs); // 十六进制字符串转成汉字（GBK）及字符(ASC)     strcpy(hs,"61BABA");     i=0;     while (1) {         if (1!=sscanf(hs+i*2,"%2x",&v)) break;         s[i]=(char)v;         i++;     }     s[i]=0;     printf("hs=%s,s=%s\n",hs,s);      return 0;  } //i=1024,bs=00000000000000000000010000000000 //i=1024,hs=00000400 //hs=00000400,i=1024 //bs=00000000000000000000010000000000,hs=00000400 //bs=00000000000000000000010000000000,i=1024 //hs=00000400,bs=00000000000000000000010000000000 //s=a汉,hs=61BABA //hs=61BABA,s=a汉

测试可用  #include <stdio.h> #include <stddef.h>  typedef unsigned long INT32U;  void num_binary (INT32U vari, char *str) {     INT32U temp = 1;     char c;     int i = sizeof(vari) * 8;     int m = 0;     printf("lenght of INT32U:%d\n",i);     for(m = 0; m < i; m++){         //printf("m = %d\n",m);         //c = (vari & temp) + '0';         //printf("c = %c\n",c);         int n = 0;         if(vari & temp)             n = 1;         *(str+m) = (char) ( n + '0');         temp = temp << 1;     }     *(str+i) = '\0'; }  int main(void) {     char *str = NULL;     int in;     str = (char*)malloc(100*sizeof(char));     INT32U i = 8858;     num_binary(i, str);     printf("i = %d is %s\n",i, str);      scanf("%d",&in);     num_binary(in,str);     printf("in = %d is %s\n",in, str);      free(str); //    printf("str = %.8s %.8s %.8s %.8s\n", *str,*str+8, *str+16, *str+32); }

有bug char str[32]; 改为 char str[33];

没什么问题：  typedef unsigned int INT32U; void Num_Binary(INT32U vari, char *str) { 	int i; 	//temp = vari; 	for (i = 31; i != -1; i--) 	{ 		*(str + i) = (vari & 1) + '0'; 		vari = vari >> 1; 		//temp2 = vari; 	} 	*(str + 32) = 0; } int main(void) { 	INT32U i = 32; 	char str[32]; 	Num_Binary(i, str); 	printf("str=%.8s %.8s %.8s %.8s\n", str, str + 8, str + 16, str + 24); 	return 0; } //00000000 00000000 00000000 00100000

# include <limits.h> # include <stddef.h>  typedef unsigned long INT32U;  void num_binary (INT32U vari, char * str)  {      union {INT32U v; unsigned c:1;} u;      for (size_t x = 0; x < sizeof (INT32U) * CHAR_BIT; x ++)         * (str ++) = (u.v = vari >> x, u.c + '0');     * str = '\0';  }


Question: c/c++怎样定义int a[10个G]的全局变量才能使用

另外， 这么大的数据放内存没意义，可以考虑放硬盘，如果哪部分读取频率高，把那一部分提到内存

这么大的内存，只有动态分配，否则你栈哪够这么多，而且动态分配也不一定能分配得到这么大

引用 10 楼 zhao4zhong1 的回复:[quote=引用 7 楼 zhao4zhong1 的回复:] 用文件读写模拟内存读写，参考_fseeki64函数（Windows），fseeko64（Linux）。 如果你硬盘空间够的话， int a[10个T];也毫无违和感！（刚学会这套词，可找到地方捅一捅啦！）[/quote]  要看楼主要的是真正的数组，还是一个类似缓冲区的东西。 如果要的是一个真正的数组，那么，首要的问题是进程的虚拟地址空间是否足够。指针的加、减、++、--、地址比较运算以及解引用倒还可以通过底层转换来对用户透明，但是，最最要命和核心的问题是，请考虑一下，如果要输出每个元素的（线性）地址，底层该怎么办。 举个例子，对于32位x86体系+WINDOWS，考虑到OS内核占用每个任务（进程）的一半虚拟地址空间，故理论上的数组长度为2^32个char。 如果要的仅仅是一个类似于缓冲区的东西，对元素地址的连续性没有要求，多大内存都不是问题。

引用 12 楼 Zof_A 的回复:[quote=引用 7 楼 zhao4zhong1 的回复:] 用文件读写模拟内存读写，参考_fseeki64函数（Windows），fseeko64（Linux）。 就是只要求应用全局整型10G数组，只在内存应用，其它软硬件，编译器什么都可以调整，都用什么、还需要调配什么，求推荐[/quote]不要挣扎了。谁也满足不了你

引用 7 楼 zhao4zhong1 的回复:用文件读写模拟内存读写，参考_fseeki64函数（Windows），fseeko64（Linux）。 就是只要求应用全局整型10G数组，只在内存应用，其它软硬件，编译器什么都可以调整，都用什么、还需要调配什么，求推荐

引用 10 楼 zhao4zhong1 的回复:[quote=引用 7 楼 zhao4zhong1 的回复:] 用文件读写模拟内存读写，参考_fseeki64函数（Windows），fseeko64（Linux）。 如果你硬盘空间够的话， int a[10个T];也毫无违和感！（刚学会这套词，可找到地方捅一捅啦！）[/quote] 莫非你LOL的时候也爱用赵信？

为什么有这样的需求，可以提下具体需求场景...

这么大的空间，已经不是编译器的事情了，而是你自己的事情了。

等进程空间破了4G再说吧

目前应该不太可能，编译器不允许这么大，就算允许，系统也没地方能运行

引用 7 楼 zhao4zhong1 的回复:用文件读写模拟内存读写，参考_fseeki64函数（Windows），fseeko64（Linux）。 如果你硬盘空间够的话， int a[10个T];也毫无违和感！（刚学会这套词，可找到地方捅一捅啦！）

表示RAM放不下

你有这么大的物理内存？

10G*8,内存就要80G,还不如放数据库里

10G=2^31 那至少是64位，并且是static才有可能编译通过吧


Question: C语言如何调用DOS命令

包含stdlib.h库 使用system（）。 格式为system（”命令行”）； 比如system（“pause”）；

system("F:\\xxxxx.bat"); //可以这样试一下，把那段代码放到一个批处理文件里面


Question: 如何将无符号char数组转为相应字符串

学习了，非常感谢！ 引用 3 楼 bjym1987 的回复: unsigned char c1 = (0x00F0 & src[0]) > 1;  //第二位 unsigned char c2 = 0x000F & src[0]; //第一位 其它依次类推，然后拼起来就好了

谢谢一休哥~~ 引用 4 楼 zhangxiangDavaid 的回复: int main(void) { 	//“2132658709ba” 	unsigned char src[6] = { 0x12, 0x32, 0x56, 0x78, 0x90, 0xab }; 	char s[13] = { 0 }; 	int i; 	char c1, c2; 	for (i = 0; i < 6; i++) 	{ 		c1 = src[i] & 0xFu; 		c2 = (src[i] >> 4) & 0xFu; 		sprintf(s + i * 2, "%x%x", c1, c2); 	} 	printf(s); 	return 0; } //2132658709ba

相当感谢赵4老师的再次帮助~~学习啦，哈哈！ 引用 5 楼 zhao4zhong1 的回复:[quote=引用 2 楼 lion7beckham 的回复:] 赞一个，太感谢啦！~~ 此外再请教下， 如果要转成“2121658709ba”，有没有比较方便的方法？ [quote=引用 1 楼 bjym1987 的回复:]  	unsigned char src[6] = {0x12, 0x32,0x56,0x78,0x90,0xab}; 	char a[12]; 	sprintf(a, "%0x%0x%0x%0x%0x%0x", src[0],src[1],src[2],src[3],src[4],src[5]); [/quote] #include <stdio.h> unsigned char src[6] = {0x12,0x32,0x56,0x78,0x90,0xab}; unsigned char v; char a[13]; int i; int main() {     for (i=0;i<6;i++) {         v=src[i]%16;         a[i*2]=v+((v>=10)?'a'-10:'0');         v=src[i]/16;         a[i*2+1]=v+((v>=10)?'a'-10:'0');     }     a[i*2]=0;     printf("[%s]\n",a);     return 0; } //[2123658709ba] // [/quote]

赞一个，太感谢啦！~~ 此外再请教下， 如果要转成“2121658709ba”，有没有比较方便的方法？ 引用 1 楼 bjym1987 的回复: 	unsigned char src[6] = {0x12, 0x32,0x56,0x78,0x90,0xab}; 	char a[12]; 	sprintf(a, "%0x%0x%0x%0x%0x%0x", src[0],src[1],src[2],src[3],src[4],src[5]);

引用 2 楼 lion7beckham 的回复:赞一个，太感谢啦！~~ 此外再请教下， 如果要转成“2121658709ba”，有没有比较方便的方法？ [quote=引用 1 楼 bjym1987 的回复:]  	unsigned char src[6] = {0x12, 0x32,0x56,0x78,0x90,0xab}; 	char a[12]; 	sprintf(a, "%0x%0x%0x%0x%0x%0x", src[0],src[1],src[2],src[3],src[4],src[5]); [/quote] #include <stdio.h> unsigned char src[6] = {0x12,0x32,0x56,0x78,0x90,0xab}; unsigned char v; char a[13]; int i; int main() {     for (i=0;i<6;i++) {         v=src[i]%16;         a[i*2]=v+((v>=10)?'a'-10:'0');         v=src[i]/16;         a[i*2+1]=v+((v>=10)?'a'-10:'0');     }     a[i*2]=0;     printf("[%s]\n",a);     return 0; } //[2123658709ba] //


Question: 是不是我的电脑注定用不了Visual c++ 6.0?!

总是发现Path环境变量被某些软件安装时错误修改。比如带空格的目录名未加引号、带汉字的目录引起目录查找混乱等问题，严重影响系统查找可执行文件和dll。 编译此源代码，生成PathShortener.exe，然后在cmd窗口里面运行PathShortener.exe>path.txt，打开path.txt，手动将其内容拷贝粘贴覆盖修改‘我的电脑、属性、高级、环境变量、系统变量、Path、编辑、变量值’即可纠正设置错误的Path http://download.csdn.net/detail/zhao4zhong1/2652343

要不装个win98试试看

把这个批处理文件运行一下，配置下环境

可以考虑虚拟机

出错的原因可能是没有找到cl.exe  打开vc界面 点击VC“TOOLS（工具）”—>“Option（选择）” —>“Directories（目录）”重新设置“ Excutable Fils  如果你是按照初始路径安装vc6.0的，路径应为： executatble files: C:\Program Files\Microsoft Visual Studio\VC98\BIN  看一下上面的路径是否正确, CL.exe就存在于上面的路径中。

建议楼主用英文版的VC6，换个路径重新安装，全路径名不要包含中文。如果是做新项目就用VS。

msdn.microsoft.com  一大把开发工具可以下载  就是你们这种人懂一点皮毛就以为开发Windows应用了

vc不好,vs好

vs2012 好，现在回头看vc6的界面这不好看  同问，机器的操作系统是啥？

不知楼主什么操作系统?

你确定代码没问题吗/

已经不建议用VC6.0了，现在C++增了很多新东西了，而且编译器最新已经有VS2013了（需要WIN8系统），WIN7可以用VS2012，建议楼主直接用VS了

换版本重装呗...


Question: 求大神 为什么我这个链表编译器报错

大致看下来逻辑没有错误，应该把错误也贴出的。  那个int i 的地方，把int i放到最前面，放前面。有些编译器是对c语言是要先声明的。   ----------------- 个人理解。

你定义struct cl了吗？ 还有提问编译器报错的时候，希望你把编译器报错的内容贴出来，这样方便找错误。


Question: 用C或C++读取文件中send之后的数据，求指导

正常的读文件，稍微加下判断就好了

不知道程序怎么编写

你这有啥问题么。不就是显示了send之后的？

仅供参考：//NAME: essaie bla bla //DIMENSION: 8 //DATA //1  14  15 //2  11  10 //3  6   4 //4  7   13 //5  9   21 //6  19  3 //7  1   5 //8  8   8 //EOF // // 文本文件中可能还含有其他内容，但是需要用到的内容即以上  //比如data.txt: //NAME: essaie bla bla //其它内容 //DIMENSION: 8 //其它内容 //DATA //其它内容 //1  14  15 //其它内容 //2  11  10 //其它内容 //3  6   4 //其它内容 //4  7   13 //其它内容 //5  9   21 //其它内容 //6  19  3 //其它内容 //7  1   5 //其它内容 //8  8   8 //其它内容 //EOF  // 目标是要获取NAME后字串，DIMENSION后数值，以及DATA以下的数值 // 其中NAME就是随便个字句，DIMENSION是城市数量，DATA以下是城市编号，X坐标，Y坐标 // 所有的这些将赋值给一个事先定义好的结构 #include <stdio.h> #include <string.h> #define MAXCPL   80   //每行最大字符数 #define MAXCITY  100  //每组数据中DATA最多项数，DIMENSION的最大值 #define MAXNAMEL 32   //NAME最大长度 struct S {     char NAME[MAXNAMEL+1];     int  DIMENSION;     struct D {         int NO;         int X;         int Y;     } DATA[MAXCITY]; } s; FILE *f; int st,n,i; char ln[MAXCPL]; int main() {     f=fopen("data.txt","r");     if (NULL==f) {         printf("Can not open file data.txt!\n");         return 1;     }     st=0;     n=0;     while (1) {         if (NULL==fgets(ln,MAXCPL,f)) break;         if (st==0) {             if (1==sscanf(ln,"NAME: %32[^\n]",s.NAME)) st=1;         } else if (st==1) {             if (1==sscanf(ln,"DIMENSION: %d",&s.DIMENSION)) st=2;         } else if (st==2) {             if (0==strcmp(ln,"DATA\n")) st=3;         } else if (st==3) {             if (3==sscanf(ln,"%d%d%d",&s.DATA[n].NO,&s.DATA[n].X,&s.DATA[n].Y)) {                 n++;                 if (n>=MAXCITY || n>=s.DIMENSION) break;             }         }     }     fclose(f);     printf("s.NAME=[%s]\n",s.NAME);     printf("s.DIMENSION=%d\n",s.DIMENSION);     for (i=0;i<n;i++) {         printf("s.DATA[%d].NO,X,Y=%d,%d,%d\n",i,s.DATA[i].NO,s.DATA[i].X,s.DATA[i].Y);     }     return 0; } //s.NAME=[essaie bla bla] //s.DIMENSION=8 //s.DATA[0].NO,X,Y=1,14,15 //s.DATA[1].NO,X,Y=2,11,10 //s.DATA[2].NO,X,Y=3,6,4 //s.DATA[3].NO,X,Y=4,7,13 //s.DATA[4].NO,X,Y=5,9,21 //s.DATA[5].NO,X,Y=6,19,3 //s.DATA[6].NO,X,Y=7,1,5 //s.DATA[7].NO,X,Y=8,8,8

MFC  CStdioFile类 CStdioFile  f1,f2; f1.Open("文本的路径"，CFile：：ModeRead)； f2.Open("写入文本路径"，CFile::ModeCreate|CFile::ModeWrite:); CString line；  if(f1.ReadString(line)) {    if(line.Find("send:")!=-1)    {      f2.WriteString(line.Left(line.Getlength()-5));     }  }


Question: c语言新手求助~

分享下曾经做过的类似题目,希望可以对楼主学习有些帮助. 字符串2插入到字符串1中 http://www.cnblogs.com/xingyunblog/p/3657691.html 字符串插入以及字符串结束标志的考察 http://www.cnblogs.com/xingyunblog/p/3951053.html

#include <stdio.h> #include <stdlib.h> void SwapString(char *source ,char *des); int main(void) {     char *str1="Japan";     char *str2="Chine";      printf("%c\n",*(str1+1));//a     printf("%c\n",*(str2+1));//h     // *(str1+1)=*(str2+1);//这句会导致程序崩溃.     SwapString(str1,str2);     return 0; } void SwapString(char *source, char *des) {     printf("%c\n",*(source+0));// J     printf("%c\n",*(source+1));// a     printf("%c\n",*(source+2));// p     printf("%c\n",*(source+3));// a     printf("%c\n",*(source+4));// n      printf("----------------------\n");     printf("%c\n",*(des+0));// C     printf("%c\n",*(des+1));// h     printf("%c\n",*(des+2));// i     printf("%c\n",*(des+3));// n     printf("%c\n",*(des+4));// e     printf("%c\n",*(des+5));// s     printf("%c\n",*(des+6));// e      printf("----------------------\n");      printf("%s\n",source+0);//Japan     printf("%s\n",source+1);//apan     printf("%s\n",source+2);//pan     printf("%s\n",source+3);//an     printf("%s\n",source+4);//n      printf("----------------------\n");      int i=0;     char temp;     while(temp!='\0')     {         temp=*(source+i);         *(source+i)=*(des+i);         *(des+i)=temp;         i++;     } }  我是这么理解的.  类似题目

char *str1="Japan"; char *str2="Chinese";  这种写法表明str1和str2是常量字符串，不可写入 修改如下：  #include<stdio.h> #include<string.h> void SwapString(char *source, char *des); int main(void) { 	//char *str1 = "Japan"; 	char str1[10] = "Japan"; 	//char *str2 = "Chinese"; 	char str2[10] = "Chinese"; 	SwapString(str1, str2, 10); 	printf("%s\n", str1); 	printf("%s\n", str2); 	return 0; } void SwapString(char *source, char *des, int n) { 	int i = 0; 	char temp; 	while (i < n) 	{ 		temp = *(source + i); 		*(source + i) = *(des + i);//这个步骤的调试为什么会报错呢？错在哪里了呢？求解答，3q 		*(des + i) = temp; 		i++; 	} }


Question: 深入阐释指针的定义

再供参考：//在堆中开辟一个2×3×4×5的4维int数组 #include <stdio.h> #include <malloc.h> int ****p; int h,i,j,k; void main() {     p=(int ****)malloc(2*sizeof(int ***));     if (NULL==p) return;     for (h=0;h<2;h++) {         p[h]=(int ***)malloc(3*sizeof(int **));         if (NULL==p[h]) return;         for (i=0;i<3;i++) {             p[h][i]=(int **)malloc(4*sizeof(int *));             if (NULL==p[h][i]) return;             for (j=0;j<4;j++) {                 p[h][i][j]=(int *)malloc(5*sizeof(int));                 if (NULL==p[h][i][j]) return;             }         }     }     for (h=0;h<2;h++) {         for (i=0;i<3;i++) {             for (j=0;j<4;j++) {                 for (k=0;k<5;k++) {                     p[h][i][j][k]=h*60+i*20+j*5+k;                 }             }         }     }     for (h=0;h<2;h++) {         for (i=0;i<3;i++) {             for (j=0;j<4;j++) {                 for (k=0;k<5;k++) {                     printf(" %3d",p[h][i][j][k]);                 }                 printf("\n");             }             printf("--------------------\n");         }         printf("=======================\n");     }     for (h=0;h<2;h++) {         for (i=0;i<3;i++) {             for (j=0;j<4;j++) {                 free(p[h][i][j]);             }             free(p[h][i]);         }         free(p[h]);     }     free(p); } //   0   1   2   3   4 //   5   6   7   8   9 //  10  11  12  13  14 //  15  16  17  18  19 //-------------------- //  20  21  22  23  24 //  25  26  27  28  29 //  30  31  32  33  34 //  35  36  37  38  39 //-------------------- //  40  41  42  43  44 //  45  46  47  48  49 //  50  51  52  53  54 //  55  56  57  58  59 //-------------------- //======================= //  60  61  62  63  64 //  65  66  67  68  69 //  70  71  72  73  74 //  75  76  77  78  79 //-------------------- //  80  81  82  83  84 //  85  86  87  88  89 //  90  91  92  93  94 //  95  96  97  98  99 //-------------------- // 100 101 102 103 104 // 105 106 107 108 109 // 110 111 112 113 114 // 115 116 117 118 119 //-------------------- //======================= //

没错 ，就是二级指针

仅供参考：#include <stdio.h> #include <stdlib.h> #include <malloc.h> int **newarr2d(int rows,int cols) {     int **p,i;      p=(int **)malloc(rows*sizeof(int *));     if (NULL==p) exit(1);     for (i=0;i<rows;i++) {         p[i]=(int *)malloc(cols*sizeof(int));         if (NULL==p[i]) exit(1);     }     return p; } void deletearr2d(int **p,int rows) {     int i;      for (i=0;i<rows;i++) {         free(p[i]);     }     free(p); } int main() {     int **arr2d,i,j,r,c;      r=4;     c=5;     //在堆中开辟一个4×5的二维int数组     arr2d=newarr2d(r,c);     for (i=0;i<r;i++) {         for (j=0;j<c;j++) {             arr2d[i][j]=i*c+j;         }     }     for (i=0;i<r;i++) {         for (j=0;j<c;j++) {             printf(" %2d",arr2d[i][j]);         }         printf("\n");     }     deletearr2d(arr2d,r);      r=6;     c=3;     //在堆中开辟一个6×3的二维int数组     arr2d=newarr2d(r,c);     for (i=0;i<r;i++) {         for (j=0;j<c;j++) {             arr2d[i][j]=i*c+j;         }     }     for (i=0;i<r;i++) {         for (j=0;j<c;j++) {             printf(" %2d",arr2d[i][j]);         }         printf("\n");     }     deletearr2d(arr2d,r);      return 0; } //  0  1  2  3  4 //  5  6  7  8  9 // 10 11 12 13 14 // 15 16 17 18 19 //  0  1  2 //  3  4  5 //  6  7  8 //  9 10 11 // 12 13 14 // 15 16 17 //

多谢各位，我提这个问题其实是因为在学二叉链表的建立时有疑惑，即void creat(BiTree *T)=void creat(BiTNode **T),这得用二级指针不能用一级指针开辟空间，不过我用楼上的几位大神的建议用汇编干了一次，知道了这是开辟的空间能否联系实参。多谢你们，我学到了方法，thinks

读对应的汇编代码

yes。you are right 《c和指针》说的很详细，可以看看

先上结论：指针就是内存的别名。 当我们声明一个变量是，实际是在内存中开辟了一块空间用于存放数据。当我们向这个变量赋值时，就是将数据放入了与这个变量绑定的内存空间中。 由此，我们可以通过变量名来直接访问内存中的数据。如 int number = 1； 除了访问内存中的数据外，有时还有确定数据在内存中位置的需求，这时候就用到了指针，如 &number。 实际上，指针就是某个特定内存单元的一个别名。这样，当我们需要确定数据在内存中的地址时，就有一种比较方便的途径。 如果你观察 代码的反汇编或者直接使用汇编写，可以观察到编译器将所有的指针都翻译成了一个标签，在汇编 中标签代表的就是标签所在位置的地址 （这里不提偏移值之类的问题，假设是在Ix86的 flat模式下汇编）。所以root的意识说的是： root是一个指针的指针。root本身存放的是一个地址a，这个地址的内存空间存放的是另外一个地址b。 就是这样，个人浅见。

你不已经理解了，需要解释什么

学习debugger吧，想怎么理解就怎么理解。

wbtree* root 很显然，你需要传入wbtree类型变量的地址

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


Question: 新手, 在线等, 为什么包发不全呢?

应该是拆成多个包发送了

12807一包发不完吧


Question: 在c/c++中如何理解，函数也是种数据类型

在c/c++中，函数就不是一种数据类型，它属于二等公民。如果是一等公民就不用搞出函数指针了，c++也不用添加Lambd概念了。

说函数是一种数据类型的，你得去找他才能知道原委。

冯·诺依曼体系。 仅供参考：//仅对VC6 #include <stdio.h> void fun1() {     int f1=1;     printf("fun1\n");     printf("fun1\n"); } void fun2() {     int f2=2;     printf("fun2\n"); } void fun3() { } void main() { #ifdef _DEBUG     printf("sizeof(fun1)==%d\n",*(int *)((int)fun2+1)-*(int *)((int)fun1+1));     printf("sizeof(fun2)==%d\n",*(int *)((int)fun3+1)-*(int *)((int)fun2+1)); //sizeof(fun1)==59 //sizeof(fun2)==43 #else     printf("sizeof(fun1)==%d\n",(int)fun2-(int)fun1);     printf("sizeof(fun2)==%d\n",(int)fun3-(int)fun2); //sizeof(fun1)==32 //sizeof(fun2)==16 #endif }

简化版： 对于C来说，“类型”意味着可以声明该类型的变量，变量有地址，有内容，可以做操作。 比如int是种类型，可以声明该类型变量a，如int a = 0; a有地址：&a； a有内容：0； 可以对a做操作：a + 1；  函数类似，不过诚如LS某位所讲，函数不是first class的，所以某些概念需用指针来表达： typedef void (*func)(); 可以近似认为func为函数类型 可以声明变量： void foo() {} func a = foo; a有地址：&a； a有内容：foo； a可操作：a();；  个人认为“类型”最重要的特征就是“有操作”（某种意义上来说就是OO中的method）。

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


Question: 帮我看看这个程序怎么改啊，初学者

引用 5 楼 zhao4zhong1 的回复:只会对着屏幕拍，不会拷贝粘贴代码到帖子上 或者 只愿意对着屏幕拍（比较轻松），不愿意拷贝粘贴代码到帖子上（比较繁琐）  我劝楼主还是趁早改行，知难而退吧。我是学机械的在校大学生，只是开了课，然而并没有什么卵用，呵呵哒

引用 5 楼 zhao4zhong1 的回复:只会对着屏幕拍，不会拷贝粘贴代码到帖子上 或者 只愿意对着屏幕拍（比较轻松），不愿意拷贝粘贴代码到帖子上（比较繁琐）  我劝楼主还是趁早改行，知难而退吧。 赵老师一针见血

修改如下：  #include <stdio.h> //index用于统计字符串t在字符串s中出现的次数 int index(char *s, char *t) { 	if (NULL == s || NULL == t) return 0; 	int count = 0; 	int i, j; 	for (i = 0; s[i]; i++) 	{ 		for (j = 0; s[i + j] && t[j]; j++) 		{ 			if (s[i + j] != t[j]) break; 		} 		if (0 == t[j]) count++; 	} 	return count; } int main(void) { 	int count = 0; 	char f[100], g[50]; 	printf("Please input:\n"); 	scanf("%s%s", f, g); 	count = index(f, g); 	printf("%d\n", count); 	return 0; } //abczxdefzxhizx //zx //3

引用 1 楼 syrchina 的回复:图片根本看不清，你还是贴代码吧看楼下

图好像看不太清

图片根本看不清，你还是贴代码吧


Question: 大神帮我解释解释这个代码！！！完全看不懂啊！！！！是一个计算器代码   包括（）和+-*/以及小数运算

单步跟一下，顺序完成加减乘除，忽略优先级

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

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

有bug，这段代码无法处理运算符优先级的问题。

实在看不懂，放个例子，一步步跟踪下...

#include "stdafx.h" #include <stdio.h> #include <string.h>  int main() {     double d[100], *dp = d;     int m, k;     char t[50], *tp = t;     char s[100], *c = s;     char* op = "+-*/";          //定义加减乘除     char* fg = "0123456789.";      gets(s);// 输入计算的字符串 ##如输入1+2  -->s="1+2"        while(*c) {//遍历 1 + 2 分离操作数 和运算符 ##指针c指向s         if(strchr(op, *c)) {//如果遍历到的字符是 +-*/ 取出那个字符 放入tp ##查找*c指向字符是否存在于op里             *tp++ = *c;             k = 0;         }else             if(strchr(fg, *c)) {//如果遍历到的字符是操作数  取出那个字符 放入dp                 sscanf(c, "%lf%n", dp++, &m);//sscanf() - 从一个字符串中读进与指定格式相符的数据.                 c += m - 1;                 ++k;             }             ++c;             while((dp - d > 1 && k == 2) || !*c && dp - d >= 1) {//取出dp操作数 tp运算符进行运算 计算结果存入dp                 switch(*--tp) {                 case '+': dp[-2] = dp[-2] + dp[-1]; break;                 case '-': dp[-2] = dp[-2] - dp[-1]; break;                 case '*': dp[-2] = dp[-2] * dp[-1]; break;                 case '/': dp[-2] = dp[-2] / dp[-1]; break;                 }                 --dp;             }     }     printf("%f", *dp); }


Question: c语言&问题

&是取地址运算符

&是取地址符，通过地址来访问变量。

取地址。。。

&是取地址符 scanf("%d", &hisAge);的含义是 把读到的数据方法地址为&hisAge的内存单元中。

//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 | //+------------------+-----------------------------------------+---------------+


Question: 大神围观

换成double的时候 你scanf里面的参数是否做相应修改呢

换成double后，scanf后接%lf，而不是%f，如果只是把float改成double，后面的代码没有相应改变，肯定会出错


Question: C语言一个诡异的问题，百思不得其解

引用 2 楼 FightForProgrammer 的回复:第一种方式，当b==0输出    0.00 第二种方式，当b==0输出    -0.00 当然，a要是正数才有负号输出

第一种方式，当b==0输出    0.00 第二种方式，当b==0输出    -0.00

简单总结一下我的问题，应该就是：  if(b == 0)   printf("%.2f", 0.00) else   printf("%.2f", -b/2/a) 和   printf("%.2f", -b/2/a)  这两段代码在什么情况下会不一样? 其中a,b都是double

#include <stdio.h> #include <string.h>  int main(int argc, char *argv[]) {     int    i, n;     char   s[sizeof(double)];     double a = -1.0;     double b = +1.0;      n = sizeof(s);      while (a != 0.0) {         a = a / 2.0;     }     printf("a=%.2g\n", a);     memcpy(s, &a, sizeof(s));     for (i = 0; i < n; i++) {         printf("%02x ", (unsigned char)s[i]);     }     printf("\n");      while (b != 0.0) {         b = b / 2.0;     }     printf("b=%.2g\n", b);     memcpy(s, &b, sizeof(s));     for (i = 0; i < n; i++) {         printf("%02x ", (unsigned char)s[i]);     }     printf("\n");      return 0; }  /* 输出: a=0 00 00 00 00 00 00 00 80 b=0 00 00 00 00 00 00 00 00 */

楼主的这个问题的原因在于浮点数(float/double)的表示方法，按照IEEE754的标准，零是区分正零和负零的(-0.0, +0.0)

计算机不会骗人，只会按照程序的意图去执行的。 楼主的这个问题的原因在于浮点数(float/double)的表示方法，按照IEEE754的标准，零是正零和负零的(-0.0, +0.0) 题目的意思要求 b==0的时候要按正零输出，这就是你所说的"结果就会有一个测试点通不过" 看下面的程序你就会明白了。  #include <stdio.h> #include <string.h>  int main(int argc, char *argv[]) {     int    i, n;     char   s[sizeof(double)];     double a = -1.0;     double b = +1.0;      n = sizeof(s);      while (a != 0.0) {         a = a / 2.0;     }     printf("a=%.2f\n", a);     memcpy(s, &a, sizeof(s));     for (i = 0; i < n; i++) {         printf("%02x ", (unsigned char)s[i]);     }     printf("\n");      while (b != 0.0) {         b = b / 2.0;     }     printf("b=%.2f\n", b);     memcpy(s, &b, sizeof(s));     for (i = 0; i < n; i++) {         printf("%02x ", (unsigned char)s[i]);     }     printf("\n");      return 0; }  /* 输出: a=-0.00 00 00 00 00 00 00 00 80  b=0.00 00 00 00 00 00 00 00 00  */  a=-0.00 00 00 00 00 00 00 00 80  b=0.00 00 00 00 00 00 00 00 00

double数值 不能跟0直接比较吧 一般不是用 |a-0| < 0.0000001 这种方式么？


Question: 关于内存分配和指针移动，请教大家

搞定了 问题出在 p -= first_row_coord;  在子函数内部，P指针移动了 到了主函数内，需要反向移位相同长度才能free掉

/*  主程序*/  // matrixleaktest.cpp : 定义控制台应用程序的入口点。 //  #include "stdafx.h" //  #include "vld.h" void myfree(void *p) {     printf("free %p\n",p);//★★★★★★★★★★★★     free(p); } int _tmain(int argc, _TCHAR* argv[]) {     int nrows,ncols;     nrows = 5 ;     ncols = 3 ;      float **row, **col,**theta,**y;     unsigned char  **edgemap;       /* 源程序提供的内存机制，-1等参数设置存在问题 */     row = (float **)matrix(nrows, ncols, 0, 0, sizeof(float));      //  内存能够申请且后面可以释放     col = (float **)matrix(nrows, ncols, 0, 0, sizeof(float));      //  内存能够申请且后面可以释放     edgemap = (unsigned char **) matrix(nrows,ncols,0,0,sizeof(char));      //  内存能够申请且后面可以释放     theta = (float **)matrix(nrows+2, ncols+2, -1, -1, sizeof(float));      //  内存能够申请但后面不能释放     y = (float **)matrix(nrows+2, ncols+2, -1, -1, sizeof(float));      //  内存能够申请但后面不能释放       if ( row != NULL ) myfree( row );   // 释放成功     if ( col != NULL ) myfree( col );   // 释放成功     if ( edgemap != NULL )  myfree( edgemap );   // 释放成功      if ( theta != NULL )  myfree( theta );   // 释放失败     if ( y != NULL ) myfree( y );   // 释放失败      return 0; }    /*  子函数  */ void **matrix(int nrows, int ncols, int first_row_coord,int first_col_coord, int element_size) {   void **p;   int alignment;   long i;    if(nrows < 1 || ncols < 1) return(NULL);   i = nrows*sizeof(void *);   /* align the addr of the data to be a multiple of sizeof(long double) */   alignment = i % sizeof(long double);   if(alignment != 0) alignment = sizeof(long double) - alignment;   i += nrows*ncols*element_size+alignment;   if((p = (void **)malloc((size_t)i)) != NULL)   {     printf("malloc return %p\n",p);//★★★★★★★★★★★★     /* compute the address of matrix[first_row_coord][0] */     p[0] = (char *)(p+nrows)+alignment-first_col_coord*element_size;     for(i = 1; i < nrows; i++)       /* compute the address of matrix[first_row_coord+i][0] */       p[i] = (char *)(p[i-1])+ncols*element_size;     /* compute the address of matrix[0][0] */     p -= first_row_coord;   }   return(p); }

free Deallocates or frees a memory block.  void free( void *memblock );  Function Required Header Compatibility  free <stdlib.h> and <malloc.h> ANSI, Win 95, Win NT    For additional compatibility information, see Compatibility in the Introduction.  Libraries  LIBC.LIB Single thread static library, retail version  LIBCMT.LIB Multithread static library, retail version  MSVCRT.LIB Import library for MSVCRT.DLL, retail version    Return Value  None  Parameter  memblock  Previously allocated memory block to be freed  Remarks  The free function deallocates a memory block (memblock) that was previously allocated by a call to calloc, malloc, or realloc. The number of freed bytes is equivalent to the number of bytes requested when the block was allocated (or reallocated, in the case of realloc). If memblock is NULL, the pointer is ignored and free immediately returns. Attempting to free an invalid pointer (a pointer to a memory block that was not allocated by calloc, malloc, or realloc) may affect subsequent allocation requests and cause errors.  After a memory block has been freed, _heapmin minimizes the amount of free memory on the heap by coalescing the unused regions and releasing them back to the operating system. Freed memory that is not released to the operating system is restored to the free pool and is available for allocation again.  When the application is linked with a debug version of the C run-time libraries, free resolves to _free_dbg. For more information about how the heap is managed during the debugging process, see Using C Run-Time Library Debugging Support.  Example  /* MALLOC.C: This program allocates memory with  * malloc, then frees the memory with free.  */  #include <stdlib.h>         /* For _MAX_PATH definition */ #include <stdio.h> #include <malloc.h>  void main( void ) {    char *string;     /* Allocate space for a path name */    string = malloc( _MAX_PATH );    if( string == NULL )       printf( "Insufficient memory available\n" );    else    {       printf( "Memory space allocated for path name\n" );       free( string );       printf( "Memory freed\n" );    } }   Output  Memory space allocated for path name Memory freed   Memory Allocation Routines  See Also   _alloca, calloc, malloc, realloc, _free_dbg, _heapmin

matrix函数的实现要求first_row_coord和first_col_coord必须≥0

以下几句貌似不仅仅只是生成一个nrows*ncols的数组      i = nrows*sizeof(void *);   /* align the addr of the data to be a multiple of sizeof(long double) */   alignment = i % sizeof(long double);   if(alignment != 0) alignment = sizeof(long double) - alignment;   i += nrows*ncols*element_size+alignment;   //  不仅仅只是得到一大小为nrows*ncols的二维数组   if((p = (void **)malloc((size_t)i)) != NULL)

分配二级指针，以后要先释放第二级，再free第一级

p -= first_row_coord; //你这步啥意思？

仅供参考：#include <stdio.h> #include <stdlib.h> #include <malloc.h> int **newarr2d(int rows,int cols) {     int **p,i;      p=(int **)malloc(rows*sizeof(int *));     if (NULL==p) exit(1);     for (i=0;i<rows;i++) {         p[i]=(int *)malloc(cols*sizeof(int));         if (NULL==p[i]) exit(1);     }     return p; } void deletearr2d(int **p,int rows) {     int i;      for (i=0;i<rows;i++) {         free(p[i]);     }     free(p); } int main() {     int **arr2d,i,j,r,c;      r=4;     c=5;     //在堆中开辟一个4×5的二维int数组     arr2d=newarr2d(r,c);     for (i=0;i<r;i++) {         for (j=0;j<c;j++) {             arr2d[i][j]=i*c+j;         }     }     for (i=0;i<r;i++) {         for (j=0;j<c;j++) {             printf(" %2d",arr2d[i][j]);         }         printf("\n");     }     deletearr2d(arr2d,r);      r=6;     c=3;     //在堆中开辟一个6×3的二维int数组     arr2d=newarr2d(r,c);     for (i=0;i<r;i++) {         for (j=0;j<c;j++) {             arr2d[i][j]=i*c+j;         }     }     for (i=0;i<r;i++) {         for (j=0;j<c;j++) {             printf(" %2d",arr2d[i][j]);         }         printf("\n");     }     deletearr2d(arr2d,r);      return 0; } //  0  1  2  3  4 //  5  6  7  8  9 // 10 11 12 13 14 // 15 16 17 18 19 //  0  1  2 //  3  4  5 //  6  7  8 //  9 10 11 // 12 13 14 // 15 16 17 //

大家，保持队形啊，help !


Question: pNodeAccount=(p_node_account)malloc(sizeof(node_account));求帮忙

你 把错误翻译一下就知道了

偶遇到类似问题都是用 “每次用/*...*/注释掉不同部分再重新编译，直到定位到具体语法出错的位置。” 的方法解决的。


Question: 北大ACM1936，Wrong answer

LZ你仔细看一看Input和Sample Input，哪有n呀,直接用scanf(..)!=EOF判断结尾

根据你的代码，猜测意图：判断字符串s中的字符是否都在字符串t中。 如果真的是这样，你的算法有些问题。 可以这样：  int cmp(void *pa, void *pb) { 	return *(char*)pa - *(char*)pb; } int main() { 	char t[100001], s[100001]; 	int n, i, j; 	scanf("%d", &n); 	while (n--) { 		int k = 0; 		scanf("%s", s); 		scanf("%s", t); 		int m = strlen(s), n = strlen(t); 		qsort(s, m, 1, cmp); 		qsort(t, n, 1, cmp);  		for (i = 0, j = 0; i<m, j<n; i++, j++) { 			if (s[i] == t[j]) 			{ 				k++; 				j--;    //加一句 			} 			else 				i--; 		} 		if (k == m) 			printf("Yes"); 		else 			printf("No"); 	} 	return 0; }  //以上效率不高，只是为了保留你的for循环

t,s太大，移到外面作全局变量

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


Question: 数据结构二叉树遍历遇到了问题。我想使用链栈来存储结点信息，但是一直有问题，想尽了办法。

引用 2 楼 FightForProgrammer 的回复:还要我们帮你找问题么。。。那你的问题是啥  不好意思，是我忽略了。问题在于先序非递归遍历。入栈退栈那总是出错。

引用 1 楼 u011916206 的回复:lz  出了什么问题呢  大致说一下 不好意思，是我忽略了。问题在于先序非递归遍历。入栈退栈那总是出错。

不好意思，是我忽略了。问题在于先序非递归遍历。入栈退栈那总是出错。

Pop(top,p);  //ERROR 这个pop函数第二个参数是char *,而从的p类型是Btree

仅供参考：#include <iostream> #include <stack> #include <queue> #include <locale.h> using namespace std; typedef struct BiTNode {//二叉树结点     char data;                      //数据     struct BiTNode *lchild,*rchild; //左右孩子指针 } BiTNode,*BiTree; int CreateBiTree(BiTree &T) {//按先序序列创建二叉树     char data;     scanf("%c",&data);//按先序次序输入二叉树中结点的值（一个字符），‘#’表示空树     if (data == '#') {         T = NULL;     } else {         T = (BiTree)malloc(sizeof(BiTNode));         T->data = data;         //生成根结点         CreateBiTree(T->lchild);//构造左子树         CreateBiTree(T->rchild);//构造右子树     }     return 0; } void Visit(BiTree T) {//输出     if (T->data != '#') {         printf("%c ",T->data);     } } void PreOrder(BiTree T) {//先序遍历     if (T != NULL) {         Visit(T);               //访问根节点         PreOrder(T->lchild);    //访问左子结点         PreOrder(T->rchild);    //访问右子结点     } } void InOrder(BiTree T) {//中序遍历     if (T != NULL) {         InOrder(T->lchild);     //访问左子结点         Visit(T);               //访问根节点         InOrder(T->rchild);     //访问右子结点     } } void PostOrder(BiTree T) {//后序遍历     if (T != NULL) {         PostOrder(T->lchild);   //访问左子结点         PostOrder(T->rchild);   //访问右子结点         Visit(T);               //访问根节点     } } void PreOrder2(BiTree T) {//先序遍历(非递归) //访问T->data后，将T入栈，遍历左子树；遍历完左子树返回时，栈顶元素应为T，出栈，再先序遍历T的右子树。     stack<BiTree> stack;     BiTree p = T;//p是遍历指针     while (p || !stack.empty()) {   //栈不空或者p不空时循环         if (p != NULL) {             stack.push(p);          //存入栈中             printf("%c ",p->data);  //访问根节点             p = p->lchild;          //遍历左子树         } else {             p = stack.top();        //退栈             stack.pop();             p = p->rchild;          //访问右子树         }     } } void InOrder2(BiTree T) {//中序遍历(非递归) //T是要遍历树的根指针，中序遍历要求在遍历完左子树后，访问根，再遍历右子树。 //先将T入栈，遍历左子树；遍历完左子树返回时，栈顶元素应为T，出栈，访问T->data，再中序遍历T的右子树。     stack<BiTree> stack;     BiTree p = T;//p是遍历指针     while (p || !stack.empty()) {   //栈不空或者p不空时循环         if (p != NULL) {             stack.push(p);          //存入栈中             p = p->lchild;          //遍历左子树         } else {             p = stack.top();        //退栈，访问根节点             printf("%c ",p->data);             stack.pop();             p = p->rchild;          //访问右子树         }     } }  typedef struct BiTNodePost{     BiTree biTree;     char tag; } BiTNodePost,*BiTreePost; void PostOrder2(BiTree T) {//后序遍历(非递归)     stack<BiTreePost> stack;     BiTree p = T;//p是遍历指针     BiTreePost BT;     while (p != NULL || !stack.empty()) {//栈不空或者p不空时循环         while (p != NULL) {//遍历左子树             BT = (BiTreePost)malloc(sizeof(BiTNodePost));             BT->biTree = p;             BT->tag = 'L';//访问过左子树             stack.push(BT);             p = p->lchild;         }         while (!stack.empty() && (stack.top())->tag == 'R') {//左右子树访问完毕访问根节点             BT = stack.top();             stack.pop();//退栈             printf("%c ",BT->biTree->data);         }         if (!stack.empty()) {//遍历右子树             BT = stack.top();             BT->tag = 'R';//访问过右子树             p = BT->biTree;             p = p->rchild;         }     } }  void LevelOrder(BiTree T) {//层次遍历     if (T == NULL) return;     BiTree p = T;     queue<BiTree> queue;//队列     queue.push(p);//根节点入队     while (!queue.empty()) {    //队列不空循环         p = queue.front();      //对头元素出队         printf("%c ",p->data);  //访问p指向的结点         queue.pop();            //退出队列         if (p->lchild != NULL) {//左子树不空，将左子树入队             queue.push(p->lchild);         }         if (p->rchild != NULL) {//右子树不空，将右子树入队             queue.push(p->rchild);         }     } } int main() {     BiTree T;      setlocale(LC_ALL,"chs");     CreateBiTree(T);      printf("先序遍历        ：");PreOrder  (T);printf("\n");     printf("先序遍历(非递归)：");PreOrder2 (T);printf("\n");                                                printf("\n");     printf("中序遍历        ：");InOrder   (T);printf("\n");     printf("中序遍历(非递归)：");InOrder2  (T);printf("\n");                                                printf("\n");     printf("后序遍历        ：");PostOrder (T);printf("\n");     printf("后序遍历(非递归)：");PostOrder2(T);printf("\n");                                                printf("\n");     printf("层次遍历        ：");LevelOrder(T);printf("\n");      return 0; } //ABC##DE#G##F### //先序遍历        ：A B C D E G F //先序遍历(非递归)：A B C D E G F // //中序遍历        ：C B E G D F A //中序遍历(非递归)：C B E G D F A // //后序遍历        ：C G E F D B A //后序遍历(非递归)：C G E F D B A // //层次遍历        ：A B C D E F G //  ///       A ///      / ///     B ///    / \ ///   C   D ///      / \ ///     E   F ///      \ ///       G

还要我们帮你找问题么。。。那你的问题是啥

lz  出了什么问题呢  大致说一下


Question: 如何能显示字符个数

你都算出来了，逗我们玩的吧

char str[ ][40] strlen(str[0]) + strlen(str[1]);

引用 3 楼 bjym1987 的回复:你都算出来了，逗我们玩的吧 人家是菜鸟小辈。

理解循环：   for(int i=0;i<2;i++)  //find the lengths of  string     while(str[i][count[i]])   //count[i]充当二维数组的下标      count[i]++;  count[0]记录了字符串 "Today is fine day" 的长度 count[1]记录了字符串"Yes you are say that again"的长度


Question: Linux Socket  recv  send  重复多次接受发送

linux中的select里的坑不小心就掉进去了，比如第一参数的含义 nfds is the highest-numbered file descriptor in any of the three sets, plus 1 即最大fd加1 linux里有效率更高的poll或者epoll，为何不用呢？

查到了，如果活动不是发生在服务器套接字上，那肯定是客户的活动。如果接收到的活动是close，就说明客户已经离开。 需要在服务器端代码的第58行加上 ioctl(fd,FIONREAD,&nread); if(nread == 0) {     close(fd);     FD_CLR(FD,&readfds); } else { //原服务器代码58-64行 }

为什么会多"发送"两次产生的原因简单，但要说明这个过程有点复杂。 要知道 stdin  stdout   stderr 的 fd 是 0 1 2 而代码中有  for( fd = 0; fd < maxfd; fd++)   ... .... ...  楼主搞错了几处 1) 搞错 select 的参数 select(FD_SETSIZE, &testfds, NULL, NULL, NULL); 这个 FD_SETSIZE 应该是 maxfd， 这个参数是说明在  FD_SET 中的 fd 的范围， 而不是个数  2) 搞错 fd  应该有一个记录所有 fd 的数组...每当有新的 fd ,就把fd 记录到数组中, fd 个数++ 如 fds[MAX_NUM]; fd_count;              // fd 个数统计  select(maxfd, &testfds, NULL, NULL, NULL); for( i = 0; i < fd_count; ++i)  {  if(FD_ISSET(fds[i],&testfds)) {    ...  楼主再查查资料吧

不知道有多少前人掉在TCP Socket send(人多)send(病少)send(财富) recv(人多病)recv(少财富) 陷阱里面啊！ http://bbs.csdn.net/topics/380167545


Question: Linux下用C写个连接wifi程序，已知SSID，无密码

Linux是开源的。


Question: 牛客网上的一道题。。。

引用 7 楼 mewiteor 的回复:[quote=引用 3 楼 u012675103 的回复:] [quote=引用 1 楼 mewiteor 的回复:] *(p+1)相当于p[1],其数据类型为int[2],int[2]赋值给int肯定会报错的。 原题里*(p+2)相当于p[2],应该等价于,x[2],题目问的是指向哪,相当于问*(p[2]),结果就是x[2][0]了  *(p+1)为什么会相当于p[1]，int  (*p)[2]中的p是表示数组指针吧，即指向 一个   包含2个元素的   一维数组，如果是int *p[2]，*p(+1)才是p[1]吧。。。。这里而x应该是一个 三行二列的二维数组的指针，如果是*(x+2)肯定是x[0][2]，这里将二维数组的首地址强制赋给了一维数组的指针，本想验证一下，还是不太明白为什么会报错，能再说一下吗？谢谢~[/quote] *:当前地址指向的值. [i]:当前地址指向的第i个元素的值 然而第i个元素的地址就是当前地址加上i*sizeof(TYPE) p+i  C语言会自动转成 p+i*sizeof(TYPE)    (所以void*指针不能进行加减运算) 那么p+i就是p[i]的地址,*(p+i)就是p[i]的值. 比如：int x[6],*p=x;p[i]==i[p]==*(p+i)==x[i]==i[x]==*(x+i),然后把int换成其它数据类型比如int[4],就变成原题了。 另外,不管x怎么定义,*(x+2)就是x[2],*(p+1)就是p[1],它们的数据类型是一样的 二维数组变量就是一个二级指针,取地址后得到一级指针,再取地址后才得到数. 所以 *(x+2) 是 x[2],不是x[0][2],x[0][2]是*(*x+2) p是个二级指针,*(p+1)就是个一级指针,然后将一级指针赋给一个数就会报错了。[/quote]  噢，明白了，结贴。

引用 3 楼 u012675103 的回复:[quote=引用 1 楼 mewiteor 的回复:] *(p+1)相当于p[1],其数据类型为int[2],int[2]赋值给int肯定会报错的。 原题里*(p+2)相当于p[2],应该等价于,x[2],题目问的是指向哪,相当于问*(p[2]),结果就是x[2][0]了  *(p+1)为什么会相当于p[1]，int  (*p)[2]中的p是表示数组指针吧，即指向 一个   包含2个元素的   一维数组，如果是int *p[2]，*p(+1)才是p[1]吧。。。。这里而x应该是一个 三行二列的二维数组的指针，如果是*(x+2)肯定是x[0][2]，这里将二维数组的首地址强制赋给了一维数组的指针，本想验证一下，还是不太明白为什么会报错，能再说一下吗？谢谢~[/quote] *:当前地址指向的值. [i]:当前地址指向的第i个元素的值 然而第i个元素的地址就是当前地址加上i*sizeof(TYPE) p+i  C语言会自动转成 p+i*sizeof(TYPE)    (所以void*指针不能进行加减运算) 那么p+i就是p[i]的地址,*(p+i)就是p[i]的值. 比如：int x[6],*p=x;p[i]==i[p]==*(p+i)==x[i]==i[x]==*(x+i),然后把int换成其它数据类型比如int[4],就变成原题了。 另外,不管x怎么定义,*(x+2)就是x[2],*(p+1)就是p[1],它们的数据类型是一样的 二维数组变量就是一个二级指针,取地址后得到一级指针,再取地址后才得到数. 所以 *(x+2) 是 x[2],不是x[0][2],x[0][2]是*(*x+2) p是个二级指针,*(p+1)就是个一级指针,然后将一级指针赋给一个数就会报错了。

b = *(p+1);  类型不匹配，p指向二维数组，*（p+1）是这个x[1]这个数组的地址，而不是某个元素的地址。

引用 2 楼 zhao4zhong1 的回复:仅供参考：//char (*(*x[3])())[5];//x是什么类型的变量? // //分析C语言声明，关键是搞清楚这个变量是个什么东西（函数、指针、数组）， //是函数那么剩下的就是他的参数和返回值， //是指针那剩下部分是说明他指向什么， //是数组剩下的部分就是说明数组的成员是什么类型。 //解析C语言声明规则： //从左侧第一个标识符开始，按照优先级进行结合。*表示是..的指针，const表示只读的，volatile表示可变的，[]表示是数组，()表示是函数。 // //x和[3]结合说明是一个大小为3的数组，该数组的每个元素为一类指针，该类指针指向一类函数，该类函数无参数，返回一类指针，该类指针指向一个大小为5的char型数组 #include <stdio.h> #include <typeinfo.h> char num[5]; char (*x00())[5] {     return # } int main() {     char (*(*x[3])())[5];//是个数组，大小为3     char (*(*x0  )())[5];//数组的元素，是个函数指针     char (*( x00 )())[5];//函数原型，参数为空，返回值为指针     char (*  x000   )[5];//返回值      x0 = x00;     x[0] = x0;     x[1] = x0;     x[2] = x0;     printf("typeid(x).name() is %s\n",typeid(x).name());     return 0; } //typeid(x).name() is char (* (__cdecl**)(void))[5]  多谢老师的回答，复杂函数指针好像有个右左规则，这里只是涉及到二维数组的首地址赋给  指向一个包含2元素的1维数组指针,，指针加1后所指情况，老师能具体说一吗？谢谢

引用 1 楼 mewiteor 的回复:*(p+1)相当于p[1],其数据类型为int[2],int[2]赋值给int肯定会报错的。 原题里*(p+2)相当于p[2],应该等价于,x[2],题目问的是指向哪,相当于问*(p[2]),结果就是x[2][0]了  *(p+1)为什么会相当于p[1]，int  (*p)[2]中的p是表示数组指针吧，即指向 一个   包含2个元素的   一维数组，如果是int *p[2]，*p(+1)才是p[1]吧。。。。这里而x应该是一个 三行二列的二维数组的指针，如果是*(x+2)肯定是x[0][2]，这里将二维数组的首地址强制赋给了一维数组的指针，本想验证一下，还是不太明白为什么会报错，能再说一下吗？谢谢~