Question: 这是一段通过队列进行建立二叉树的代码，但是create函数运行结束后程序中断。

在Create中 Queue *Q; InitQueue(Q);这样无法初始化, 要么为Q分配地址, 要么定义成变量,传地址进去

检查指针是否有效

将初始化函数initate（）中的分配空间malloc删除 就可以了。 现在又出现新问题，定义在create函数前必须有个printf，如果定义的指针型，必须在分配空间后 create函数前加一个printf.....不然不能正常运行。

提示无法写入


Question: 关于实现链表的操作

ptail与phead都指向同一个节点，懂了

ptail->next=NULL; 改成 ptail->pnext=NULL;  代码是对ptail进行的操作 为什么此处返回的是phead而不是ptail；  返回pHead就可以顺着得到后面的链啦


Question: 数据结构图的Prims算法问题

Prims函数中MinEdge你使用前没有进行初始化操作


Question: 学习日记六：同构二叉树

Isomorphic函数里面的逻辑有点乱，很多后面的判断都是没有必要的判断，改成这样，应该也可以的，会相对简洁一些     if( (Root1== Null) && (Root2== Null)  )          return 1 ;      else if( (Root1== Null) || (Root2 == Null) )         return 0 ;      else if( Tree1[Root1].Element != Tree2[Root2].Element  )         return 0 ;      else   if ( Isomorphic(Tree1[Root1].Left,Tree2[Root2].Left) &&  		Isomorphic( Tree1[Root1].Right,Tree2[Root2].Right ) )  		return 1;     else         if ( Isomorphic( Tree1[Root1].Left,Tree2[Root2].Right ) && 			Isomorphic( Tree1[Root1].Right,Tree2[Root2].Left ) )  			return 1; 	return 0;


Question: 不知道下一步该怎么做。求大神指导，谢谢!

引用 5 楼 qq_32736835 的回复:好 #include<stdlib.h> #include<stdio.h> void subfun11(void) {  FILE*fq1; char text[1024]; fq1=fopen("d:\\a.txt","r"); while(fgets(text,1024,fq1)!=NULL) { 	puts(text); } 	fclose(fq1); } void subfun12(void) { char str[40]; printf("请输入要显示的客户信息航班号:"); scanf("%s",&str); printf("%s",str); //这里就不会了 } void subfun13(void) { } void subfun21(void) { } void subfun22(void) { } void subfun23(void) { } void subfun31(void) { } void subfun32(void) { } void subfun33(void) { } void fun1(void) { 	int n; 		for(;;) 		{ 		 printf("*************************\n"); 	     printf("   显示各航空信息子菜单    \n"); 	     printf("    1.显示所有航线       \n"); 		 printf("    2.显示订票客户       \n"); 		 printf("    3.显示等待客户       \n"); 		 printf("    4.返回主菜单         \n"); 		 printf("*************************\n"); 		scanf("%d",&n); 		switch(n) 		{ 		case 1:subfun11();break; 	    case 2:subfun12();break; 		case 4:return; 		default:printf("输入错误\n");break; 		} 	} } void fun2(void) {  	int t; 	for(;;) 	{ 		printf("*************************\n"); 	     printf("   航线信息查询子菜单    \n"); 	     printf("    1.按航班号查询      \n"); 		 printf("    2.按起点站查询       \n"); 		 printf("    3.按终点站查询       \n"); 		 printf("    4.返回主菜单         \n"); 		 printf("*************************\n"); 		 scanf("%d",&t); 		switch(t) 		{ 		case 1:subfun21();break; 		case 2:subfun22();break; 		case 3:subfun23();break; 		case 4:return; 		default:printf("输入错误\n");break; 		} 	} } void fun3(void) {  	int t; 	for(;;) 	{ 		printf("*************************\n"); 	     printf("   编辑航线信息子菜单    \n"); 	     printf("    1.新增航线      \n"); 		 printf("    2.删减航线       \n"); 		 printf("    3.修改航线       \n"); 		 printf("    4.返回主菜单         \n"); 		 printf("*************************\n"); 		 scanf("%d",&t); 		switch(t) 		{ 		case 1:subfun31();break; 		case 2:subfun32();break; 		case 3:subfun33();break; 		case 4:return; 		default:printf("输入错误\n");break; 		} 	} } void fun4(void) { char str[40]; printf("请输入要订票的航班号:"); scanf("%s",&str); printf("%s",str); } void fun5(void) { char str[40]; printf("请输入要退票的航班号:"); scanf("%s",&str); printf("%s",str); } void main(void) { 	for(;;) { printf("  欢迎进入航空订票系统   \n");   printf("***********************");   printf("\n");   printf("      航空客运系统       \n");   printf("***********************");   printf("\n");   printf("   1.显示各航线信息     \n");   printf("   2.查询各航线信息     \n");   printf("   3.编辑各航线信息     \n");   printf("   4.订          票     \n");   printf("   5.退          票     \n");   printf("   0.退出      系统     \n");   printf("***********************");   printf("\n");   int a; 	 scanf("%d",&a); 	 switch(a) 	 {case 1:fun1();break; 	 case 2:fun2();break; 	 case 3:fun3();break; 	 case 4:fun4();break; 	 case 5:fun5();break; 	 default:printf("输入错误\n");break; 	 }  }  }  我看了下，你数据是从d:\\a.txt这具文件中读到的，所以在输入航班号后，你重新文件，然后输出的时候进行判断，满足的才输出

大神，看到了吗？

引用 3 楼 qq_32736835 的回复:就是用什么函数？  用什么方式都好啊，程序根据用户选择，执行相应的功能，发你代码来啊，不然不好说

就是用什么函数？

不懂，能详细点吗？ 谢谢

程序从之前记录中检查此航班的客户信息，然后输出显示


Question: 一个写入文件的有意思现象

在文件大小相同的前提下：  读刚读过的文件比头次读没读过的文件快  读转速快的硬盘上的文件比读转速慢的硬盘上的文件快  读没有磁盘碎片的文件比读有磁盘碎片的文件快  读文件不处理比边读边处理快  单线程从头到尾一次读文件比多线程分别读文件各部分快（非固态硬盘上）  读固态硬盘上的文件比读普通硬盘上的文件快  写文件类似。

机械硬盘中有一个非常重要的概念：寻道时间 而且寻道时间比读写时间大一两个数量级 小文件读写，时间都花费在寻道上了，当然忙啊

我很奇怪，你这程序居然不会堆栈溢出。那个p数组是在栈上面的，如果真的是512M，你的栈得多大啊

fwrite 所使用的时间，与它写了多少东西关系不太大。

楼主解决了@ 下我，我也想知道

这个得看内核的实现了吧。楼主可在多个系统上尝试？


Question: 帮帮忙 新手很困惑

#include <stdio.h> #define M 3 #define N 5 void pr(double array[M][N]); double MAX(double array[M][N]); double average(double array[M][N]); int main(void) { 	printf("please 请输入三个数集每个数集包括5个double值"); 	int i,j;double array[M][N]; 	for(i=0;i<M;i++) 	{ 		printf("请输入第%d个数集",i+1); 		for(j=0;j<N;j++) 			array[i][j]=getchar(); 	} 	pr(array); 	printf("%f",average(array)); 	printf("%f",MAX(array)); 	return 0; } double average(double array[M][N])   { 	double sum;double average; 	int i,j; 	for(i=0,sum=0;i<M;i++) 		for(j=0;j<N;j++) 			sum=sum+array[i][j]; 	average=sum/N; 	return average; }  double MAX(double array[M][N]) { 	double MAX=0.; 	int i,j; 	for(i=0;i<M;i++) 		for(j=0;j<N;j++) 			if(MAX<array[i][j]) MAX=array[i][j]; 	return MAX; } void pr(double array[M][N]) { 	int i,j; 	for(i=0;i<M;i++) 		for(j=0;j<N;j++) 			printf("%f\n",array[i][j]); }

看上去原型错了 void pr(double array[M][N]); double MAX(double array[M][N]); double average(double array[M][N]);

我觉得是主函数中你定义的三个函数传递的实参有错误，你实际上传递的是指针，而你定义的是double类型


Question: 求解释一下为什么停止工作

语言基础：如何使用scanf;

scanf中要求给出变量地址，如给出变量名则会出错  for(j=0;j<N;j++){  scanf("%lf",&array[i][j]);}

对函数参数传递理解不深入，如果你只是把该变量的值传递进去，函数内修改的只是这个值的一个副本 scanf需要的是将数据输入到指定的变量，所以传递进去的必须是变量的地址

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


Question: 如何串连两个数组

int a[5],b[5]; int *c[10]={a,a+1,a+2,a+3,a+4,b,b+1,b+2,b+3,b+4}; for(int i=0;i<10;i++)       printf("%d",*c[i]); 可以这么做不过，太麻烦了，通常是不值得。

建议用7楼的   思维

#include <stdio.h> int arr1[]={1,2,3,4,5}; int arr2[]={6,7,8,9,10}; int main() {     int i,*a;  	a=arr1; for(i=0;i<sizeof(arr2)/4;i++) { 	a[5+i]=arr2[i]; } for (i=0;i<10;i++)   	printf("AA%d ",*a++);     return 0; }

仅适用于Debug版： #include <stdio.h> int arr1[]={1,2,3,4,5}; int arr2[]={6,7,8,9,10}; int main() {     int larr2[]={16,17,18,19,20};     int larr1[]={11,12,13,14,15};      int i,*a;      a=arr1;     for (i=0;i<10;i++) printf("%d ",a[i]);     printf("\n");      a=larr1;     for (i=0;i<10;i++) printf("%d ",a[i]);     printf("\n");      return 0; } //1 2 3 4 5 6 7 8 9 10 //11 12 13 14 15 16 17 18 19 20 //

我想把某两个数组合并后，赋给一个指针，用这个指针可以检索到两个数组的值，有没有此类方法谢谢

引用 1 楼 paschen 的回复:如果你要连在一起，你定义数组时就要多分配一些空间，int  arr1[]={1,2,3,4,5}; 其实你的arr数组只能存5个元素，你没空间放合并后的，你需要定义时写成int  arr1[100]={1,2,3,4,5}; 这种  你意思是合并后相当于放在ARR1里面？ 我这代码空间有限，不能定义太多空间，因为我想动态合并，在实际运行中，有可能是ARR1和ARR2合并，有可能是ARR1和ARR3和合并。

int length = strlen(arr1)  + strlen(arr2); char *a = (char *)malloc(sizeof(char)*length); memset(a, 0,  length);  strcat(a,arr1); strcat(a,arr2);  不重新申请空间的话你原来没有足够的成片的空间可以放置两个数组，你的函数相当于在arr1之后直接放arr2的内容，那片内存你不一定能用

使用sprintf函数.

引用 2 楼 ding_suki 的回复:[quote=引用 1 楼 paschen 的回复:] 如果你要连在一起，你定义数组时就要多分配一些空间，int  arr1[]={1,2,3,4,5}; 其实你的arr数组只能存5个元素，你没空间放合并后的，你需要定义时写成int  arr1[100]={1,2,3,4,5}; 这种  你意思是合并后相当于放在ARR1里面？ 我这代码空间有限，不能定义太多空间，因为我想动态合并，在实际运行中，有可能是ARR1和ARR2合并，有可能是ARR1和ARR3和合并。[/quote]  你想用一个指针就可以用一个指针访问，你就得把合并后都放到一个数组里，不然你是指什么意思


Question: c语言二叉树后序遍历非递归算法问题

引用 1 楼 anzi5091104 的回复:第120行isemptystack在为空时返回1还是0 代码是这样的：  跟这个地方应该没关系，主要是设置某个节点的isPrintOut为true之后，再获取的isPrintOut还是false

//感觉逻辑应该是这样的 else { 	p = GetTop(stack); 	if(IsChildsAllPrintOut(p)) 	{ 		printf("%c",p->val); 		p->isPrintOut = true; 		Pop(statck);	 		p = NULL; 	} 	else p = p->right; }

栈定义得有问题，算法也写得不对


Question: 新人求教啊！这个不知道要怎么写

直接枚举好了, 编程也简单 bool solve(int n){     for(int i=0;i<5;i++){         if(n<6|| n%5!=1) return false;         n =(n-1)/5*4;     }     return true; }  int main() {     int i;     for(i=6;!solve(i);i+=5);     cout<<i<<endl;     return 0; }

假设每个人的一堆为xi个 最后一人的数量数总数量 5*x5+1 最后一人，自己得到 x5，猴子得到1 ，还剩 4x5,总数是 x5+1  x至少为一个，所以计算的起点为 x5=1 第四个人 剩余 的数量时 x4 = (5 x5 + 1)/4 递推公式是 x【i】 = (5 *x【i+1】+1)/4; total【i] = (5 *x【i】+1) 可以从最后一个人向前推,下标也就反过来了  这样就变成 x[i]=  (5* x【i-1】+1)/4; total【i] = (5 *x【i】+1) 注意，每个步骤中 x[i] 为整数。不能除尽的x[i]  的方案，就可以排除了，直到找到第一个可行方案，就是最小的数量了

听说用倒推法


Question: c语言作业求助

#include<stdio.h>  void main() { 	int m,n,i,j; 	char que[30]; 	scanf("%s",&que); 	printf("please input m and n:\n"); 	scanf("%d%d",&m,&n);  	if(m>sizeof(que)&&n>sizeof(que)) 		printf("NULL!\n");  	else if(m<sizeof(que)&&n>sizeof(que)) 	{ 		for(i=m-1;i<sizeof(que);i++) 		{ 			printf("%c",que[i]); 		} 	} 	else if(m==n)  		printf("%c",que[m]);  	else if(m<sizeof(que)&&n<sizeof(que)) 	{ 		for(j=m-1;j<n;j++) 		{ 			printf("%c",que[j]); 		} 	}  }

#include<stdio.h> #include<stdlib.h> #include<string.h>  #define N 100  void print(char chr[N],int m,int n);  void main() { 	char chr[N]; 	int m,n; 	gets(chr); 	printf("please input first number:"); 	scanf("%d",&m); 	printf("please input second number:"); 	scanf("%d",&n); 	print(chr,m,n);  	system("pause"); }  void print(char chr[N],int m,int n) { 	int i=0; 	int length=strlen(chr); 	char *p=chr; 	if(p==NULL||(m>=length && n>=length)) 		return; 	else 	{ 		if(m<=length && n>=length) 			printf("%s",p+m-1); 		if(m==n) 			printf("%c",*(p+m-1)); 		if(m<length && n<length) 			for(i=m-1;i<n;i++) 				printf("%4c",*(p+i)); 	} }


Question: 试着写个简单计算器，结果是悲催的。。。

#include <stdio.h> int main() {     char s[40];     int a,b;      scanf("%39s",s);          if(2==sscanf(s,"%d*%d",&a,&b)) printf("%d\n",a*b);     else if(2==sscanf(s,"%d-%d",&a,&b)) printf("%d\n",a-b);     else if(2==sscanf(s,"%d+%d",&a,&b)) printf("%d\n",a+b);     else if(2==sscanf(s,"%d/%d",&a,&b)) printf("%d\n",a/b);     else                                printf("error\n");     return 0; }

引用 2楼paschen 的回复:这样不行，因为他每次判断都要重新读入，所以只有第一个if行    #include<stdio.h> int main() { 	int a,b; 	char ch; 	scanf("%d%c%d",&a,&ch,&b); 	if(ch == '*') 		printf("%d\n",a*b); 	else if(ch == '-') 		printf("%d\n",a-b); 	else if(ch == '+') 		printf("%d\n",a+b); 	else if(ch == '/') 		printf("%d\n",a/b); 	else 		printf("error"); 	return 0; } 这样，懂了，谢啦

引用 1楼user-3 的回复:不行, 得读进来自己判断 %d%c%d嗯嗯，知道了，谢啦

不行, 得读进来自己判断 %d%c%d


Question: C语言问题

指针数组没必要吧； while里的判断表达式和一般的赋值混了

先去把书多看几遍吧。数组定义都没搞明白。

gets()函数接收的是char *类型，楼主确定实现字符串的连接需要定义指针数组*a[N]么？ 还有，printf("%s",strcat);楼主这是要打印连接后的字符串吗？这个只是函数的入口地址，不是 字符串a的存储地址

头文件，申明。要加#include <string.h>

strcat(a, b); printf("%s", strcat); 建议你还是把基础先看好


if (fopen_s(&fp, name, "wb") == 1) 改成 if (fopen_s(&fp, name, "wb") != 0)   fopen_s的返回值：Zero if successful; an error code on failure.   具体看：https://msdn.microsoft.com/library/z5hh6ee9(v=vs.110).aspx

换scanf试试，是不是编译器对安全模式支持的问问题。再在中间加空格试试。

引用 1 楼 paschen 的回复:我调试没出错啊，你是编译出错还是运行出错，错误信息是什么运行出错，在第一次输入score[i].neme这一行回车时，出现上面图片中的情况

我调试没出错啊，你是编译出错还是运行出错，错误信息是什么


Question: C语言的存储类

引用 2 楼 ID870177103 的回复:存储类可分为auto、register、static、extern、mutable、thread_local等。 你说的是这个吗 auto自动变量，生存周期为当前语句、语句块，默认类型 register希望使用寄存器来储存，适用于操作频繁的数据 static静态，生存周期为整个程序周期（主线程） extern变量不是在这里定义，这里只是一个引用，显然它是对应static的 mutable即使结构变量是const的，它的mutable成员也可以被修改 thread_local静态，但是每个线程有它自己的副本，生存周期是关联线程的周期

动态储存：auto 自动的，register 寄存器                  特点：默认初始未定 静态储存：extern 外部的  static 静态的                   特点：默认初始为0 局部变量：auto  register static 全局变量：extern static extern:外文件能调用该变量的值 static:           1.局部static:该函数结束后，变量的值被保存。函数再次被调用时，变量的值是函数结束时保存的值。           2.全局static：外文件不能通过全局变量extern来调用static的变量值

引用 3 楼 qq_31361473的回复:我正好看书看到这里，c primer plus 第十一章讲的就是这个。 大学c基础课没有这种东西，我打算好好看看   是十二章

什么叫存储类  你是指变量的存储类型吗？


Question: 求帮忙看一道有问题的ACM的代码

X[i + 1] <= X[i] 不代表最长为1,应该是d(i)=max( d(j)+1) j<i && x[j]<x[i]


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

编译没错，运行错了，被指针什么的搞蒙了。。。


Question: 输入一串用空格隔开的数字串,对于数字串的奇数位按升序排序,偶数位按降序排序.

用Java的话试试这个。。 import java.util.*;  public class Main { 	public static void main(String args[]) { 		Scanner scan = new Scanner(System.in); 		String inStr = scan.nextLine(); 		scan.close(); 		String[] strs = inStr.split(" "); 		int N = strs.length; 		int[] inNums = new int[N]; 		for (int i = 0; i < N; i++) { 			inNums[i] = Integer.parseInt(strs[i]); 			// System.out.println(strs[i]); 		}  		int tmp = 0; 		//奇数位升序 		for (int i = 0; i < N - 1; i = i + 2) { 			for (int j = i; j < N - 1; j = j + 2) { 				if (inNums[i] > inNums[j]) { 					tmp = inNums[i]; 					inNums[i] = inNums[j]; 					inNums[j] = tmp; 				} 			} 		} 		//偶数位降序 		for (int i = 1; i < N - 1; i = i + 2) { 			for (int j = i; j < N - 1; j = j + 2) { 				if (inNums[i] < inNums[j]) { 					tmp = inNums[i]; 					inNums[i] = inNums[j]; 					inNums[j] = tmp; 				} 			} 		} 		  		for (int i = 0; i < N; i++) { 			System.out.print(inNums[i]); 			System.out.print(" "); 		}  	}  }

你可以查一下ShellSort


Question: 入门的一道OJ题卡勒

表示都用了一次 提交还是AC 不了 打算先结帖 吧 多谢各位的指点,等我跟老师要了标程再发上来

用fabs

引用 17 楼 logiciel 的回复:我加了abs后在vs2010中运行的结果如下： 9.21 5 0.21313 -9.21 5 -0.21313  #include<stdio.h> #include<math.h> #define pow(x,y) pow((double)x, (double)y) /*加*/ double fun(int c); int main(){   double sum,x;int n;//改 double sum;int n,x;   while(scanf("%lf %d",&x,&n)!=EOF){ //改 while(scanf("%d %d",&x,&n)!=EOF){     int i=1,q=0;sum=0;     while(i){       if(abs(pow(x,i)/fun(i))>=pow(10,-n)){//改 if(pow(x,i)/fun(i)>=pow(10,-n)){         sum=sum+pow(-1,q)*pow(x,i)/fun(i);         i=i+2;         q=q+1;       }       else         break;     }     sum=sum+pow(-1,q)*pow(x,i)/fun(i);     printf("%.*lf\n",n,sum);   }   return 0; }  double fun(int c){   double m=1;   for(int j=1;j<=c;j++){     m=m*j;   }   return(m); }  我用了ACM考试用的编译器CodeBlocks13.12输入 他显示了错误 |error: 'abs' was not declared in this scope| 这是什么情况

void main(){ 	double angle; 	int precision; 	printf("请输入弧度和精度:"); 	scanf("%lf %d",&angle,&precision);  	double delta = pow(10.0,-precision); 	double ai = angle; 	double x2 = angle * angle; 	double result = ai; 	 	for(int i=3;;i+=2){ 		ai = ai*x2/i/(1-i);  		if(ai < 0){ 			if(-ai < delta) break; 		}else{ 			if(ai < delta) break; 		} 		result += ai; 	}  	printf("sin(%lf)=%lf",angle,result); 	 }

这种 幂级数，不要求阶乘， 1效率低，2精度差 直接用除法乘法递推，就可以了，起码精度还可以的

引用 11 楼 logiciel 的回复:还要改2行：   double sum,x;int n;//改 double sum;int n,x;   while(scanf("%lf %d",&x,&n)!=EOF){ //改 while(scanf("%d %d",&x,&n)!=EOF){  俄 那个X是可以取小数的比如9.21  所以用INT的话是肯定不行的

引用 15 楼 logiciel 的回复:#12的含义是把 if(pow(x,i)/fun(i)>=pow(10,-n)){ 改为 if(abs(pow(x,i)/fun(i))>=pow(10,-n)){ 加个ABS 以后然后运行 输入9.21 5                                          输出了 0.13975    但是答案是0.21313 好奇怪啊

再改一行： if(abs(pow(x,i)/fun(i))>=pow(10,-n)){//改 if(pow(x,i)/fun(i)>=pow(10,-n)){  这样当x为负数时结果就对了。

引用 13 楼 H_Joden 的回复:[quote=引用 11 楼 logiciel 的回复:] 还要改2行：   double sum,x;int n;//改 double sum;int n,x;   while(scanf("%lf %d",&x,&n)!=EOF){ //改 while(scanf("%d %d",&x,&n)!=EOF){  俄 那个X是可以取小数的比如9.21  所以用INT的话是肯定不行的 [/quote]我是建议你把x改为double。注意“//改"左边是更改后的语句。

引用 9 楼 user-6 的回复:[quote=引用 8 楼 H_Joden 的回复:] [quote=引用 7 楼 paschen 的回复:] [quote=引用 4 楼 H_Joden 的回复:]   帮你调试半天，终于找到了原因：  求阶乘时数字太大，溢出了int能表示的最大值，用double表示就可以正常了   double fun(int c){ 	double m=1; 	for(int j=1;j<=c;j++){ 		m=m*j; 	} 	return(m); } [/quote]  大哥万分感谢 终于不抱错了 但是提交之后系统给了我wa 感觉是不是精度问题 我又看了半个小时没看出来 求各为邦我看看 http://paste.ubuntu.com/13388997/[/quote] scanf应该是第1个应该%lf, 并且x是double型[/quote] 改了还是报错 感觉不出有问题啊

引用 4 楼 H_Joden 的回复:  帮你调试半天，终于找到了原因：  求阶乘时数字太大，溢出了int能表示的最大值，用double表示就可以正常了   double fun(int c){ 	double m=1; 	for(int j=1;j<=c;j++){ 		m=m*j; 	} 	return(m); }

引用 8 楼 H_Joden 的回复:[quote=引用 7 楼 paschen 的回复:] [quote=引用 4 楼 H_Joden 的回复:]   帮你调试半天，终于找到了原因：  求阶乘时数字太大，溢出了int能表示的最大值，用double表示就可以正常了   double fun(int c){ 	double m=1; 	for(int j=1;j<=c;j++){ 		m=m*j; 	} 	return(m); } [/quote]  大哥万分感谢 终于不抱错了 但是提交之后系统给了我wa 感觉是不是精度问题 我又看了半个小时没看出来 求各为邦我看看 http://paste.ubuntu.com/13388997/[/quote] scanf应该是第1个应该%lf, 并且x是double型

引用 7 楼 paschen 的回复:[quote=引用 4 楼 H_Joden 的回复:]   帮你调试半天，终于找到了原因：  求阶乘时数字太大，溢出了int能表示的最大值，用double表示就可以正常了   double fun(int c){ 	double m=1; 	for(int j=1;j<=c;j++){ 		m=m*j; 	} 	return(m); } [/quote]  大哥万分感谢 终于不抱错了 但是提交之后系统给了我wa 感觉是不是精度问题 我又看了半个小时没看出来 求各为邦我看看 http://paste.ubuntu.com/13388997/

不知道为什么我用VC++6.0可以   那个我是代码貌似是写错了 就是运行以后得到的结果和答案不同  而且是个负数   各位帮我瞧瞧是不是我犯了(水)低级错误

引用 3 楼 H_Joden 的回复:那个跟q=q++每关系的 这是C 可以这样用 你这么自信，你没试过吗，我帮你试了一下http://ideone.com/0zqc9M 这是未定义行为，有些编译器结果是你预想的，有些不是。

那个跟q=q++每关系的 这是C 可以这样用


Question: 用C语言编写一个购物车的系统

这个能改成C++的格式吗？

不明觉厉

感谢,但是没有注释很多地方看不太懂


Question: 关于函数调用数组的问题

thank you1！！

修改后的代码:   #include<stdio.h>     int fun(float s[],int n,float below[])     {         int num=0,i,j;         float sum=0,ev;         for(i=0;i<n;i++)             sum=sum+s[i];         ev=sum/n;         for(j=0;j<n;j++)             if(s[j]<ev)             {             below[num]=s[j];                num++;             }                     return num;     }     int main()     {         float s[20];         float below[20]={0};         int n,i,k;         printf("请输入要输入的数的个数：\n");         scanf("%d",&n);         printf("请输%d个数\n",n);         for (i=0;i<n;i++)             scanf("%f",&s[i]);         k=fun(s,n,below);         printf("低于平均分的个数是%d\n",k);             for(i=0;i<k;i++)             printf("%f ",below[i]);         return 0;     }  你的主要问题是:int s[20]; scanf("%f",&s[i]);


Question: 输入字符串问题

#include <stdio.h>  int main() {    char buf[80];    scanf("%30s", buf);     return 0; }

注意buf前面不能加&

scanf("%30s", &buf);

%30s，改成这个试试


Question: 关于C语言文件读写  删除一行的问题

所谓修改删除文件a某位置的内容，其实是读打开文件a，再将‘a中修改删除位置之前的内容＋修改删除的内容＋a中修改删除位置之后的内容’保存到文件b，关闭文件a，删除文件a，将文件b改名为与之前文件a相同的名字，仅此而已。

如果是在linux下c的话可以看看sed命令 使用system调用

读出来 原来的 Colour = 35 也不会消失  你再写进去 也是一样

把这行数值部分先全部删掉，然后再写，这样行不行啊

你先把这行内容Colour = 35 读出来 然后用8替换 而不是直接在3位置写8这样肯定是85


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

deleteNode函数出的问题

deleteNode将free掉所有结点, 之后root已经无效了,显示什么应该不知道了

可上面说4必须有，只是在主函数不动的前提下说的

贴出编译信息给大牛看看， 数据结构我也生疏了


Question: 如何读取文件

FILE *f; unsigned char a[100],v,i=0; f=fopen(...,"r"); while (1) {  if (1!=fscanf(f,"%i",&v)) break;  a[i]=(unsigned char)v;  i++;  if (i>=100) break; } fclose(f);

每次读一行为字符串 然后字符串转为整形 最后放入数组中

要读成字符串还是数字 用文本方式打开文件读


Question: 承接昨天的帖子继续询问

#include <stdio.h> #include <stdlib.h> #define LEN    64 #define M 3 #define N 3 char *get_message(char *message2, int message1[M][N]); int main(void) {     int message1[M][N] = { { 1,1,1 },{ 0,0,0 },{ 0,0,0 } };     char *message2 = "help";     message2 = get_message(message2, message1);     printf("%s", message2);     return 0; } char *get_message(char *message2, int message1[M][N]) {     int i, j;     static char message[LEN];     char *p=message;     p+=sprintf(p, "%s", message2);     for (i = 0;i < M;i++)         for (j = 0;j < N;j++)         {             p+=sprintf(p,"%d",message1[i][j]);         }     return message; } //help111000000

不要询问为什么错误的程序可以得到期望的结果。  错误的程序可能得到任何结果。

char *p=message; p+=sprintf(p,"%s",message2); for (i = 0;i < M;i++)         for (j = 0;j < N;j++)         {             p +=sprintf(p, "%d",message1[i][j]);         }

引用 3 楼 zyzy577048814 的回复:[quote=引用 2 楼 paschen 的回复:] 返回char的话return message;这句会错误 返回char*的话return 1;这句会错误 那无解了？[/quote]  不明白你函数要做什么，如果返回类型必须一致，如果想返回多个变量，可以通过函数参数实现返回

引用 2 楼 paschen 的回复:返回char的话return message;这句会错误 返回char*的话return 1;这句会错误 那无解了？


Question: [求助]指针问题  大神们来看看啊

额，没仔细看居然没发现

swap2里面传递的参数应该是pc，pd；后面的swap3也是一样。


Question: 求分析代码。

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

引用 8 楼 qq_31361473的回复:因为0%2是0啊，第一个当然不会进入循环。 另外，'A'-'a'不应该就是26吗，←_←，其实就是转换大小写吧   是判断不是循环，手机客户端的锅

引用 2 楼 tamaaaa 的回复:[quote=引用 1 楼 paschen 的回复:] printf("\n");  双引号  确实，这个应该是印刷错了，能帮忙分析一下代码吗，为什么输入labce12df会输出lAbCeD12dF[/quote]  如果满足if，即字符是在字符串中的第奇数个，且为小写字母，则将该字母转换成大写，否则不转换。最后输出

if(a%2!=0&&(ch>='a'&&ch<='z'))ch=ch-'a'+'A';当a为奇数且ch是小写字母时，把ch换成对应大写字母，不满足if条件，直接输出ch

引用 1 楼 paschen 的回复:printf("\n");  双引号  确实，这个应该是印刷错了，能帮忙分析一下代码吗，为什么输入labce12df会输出lAbCeD12dF

printf("\n");  双引号

引用 4 楼 paschen 的回复:[quote=引用 2 楼 tamaaaa 的回复:] [quote=引用 1 楼 paschen 的回复:] printf("\n");  双引号  确实，这个应该是印刷错了，能帮忙分析一下代码吗，为什么输入labce12df会输出lAbCeD12dF[/quote]  如果满足if，即字符是在字符串中的第奇数个，且为小写字母，则将该字母转换成大写，否则不转换。最后输出[/quote]那请问起初a的值为0时不也满足条件吗？为什么输入的第一个字符l不转化成大写L

引用 5 楼 zyzy577048814 的回复:#include<stdio.h> int main(void) {          char a=0,ch;//定义了a和ch         while((ch=getchar())!='\n'){//获取键盘值，直到回车结束           if(a%2!=0&&(ch>='a'&&ch<='z'))//判断条件（a的值为奇数并且ch在a到z之间（指的都是ASCM值））          ch=ch-'a'+'A';//ch的值加上（‘A’-'a'）....具体多少忘了。。           a++;//a自加1,也就是向后退一位，计算下一个           putchar(ch);//输出ch值。          }         printf('\n');         return 0;  }谢谢，但起初a的值为0时不也满足条件吗？为什么输入的第一个字符l不转化成大写L


Question: 求人帮忙看看代码问题出在哪里？栈的应用——进制转换

引用 2 楼 baidu_32899011 的回复:S.base=(int*)malloc(100*sizeof(int));//为什么这里的100不能用STACK_INIT_SIZE代替？ #define后面不需要分号，除非你确定需要

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


Question: 新手小白   对编程完全不懂    请问这是怎么回事

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

printf()后面出现中文分号…

引用 10 楼 paschen的回复:[quote=引用 8 楼 qq_32947505 的回复:] [quote=引用 6 楼 maydaysar的回复:][quote=引用 5 楼 qq_32947505的回复:][quote=引用 2 楼 maydaysar的回复:][quote=引用 1 楼 maydaysar的回复:]这个有错吗？应该没错吧？ 括号，是大括号…………[/quote] 我也该过括号了  还是不行[/quote] 我刚才试了下，可以啊，就一个括号，具体为啥你不能我就不太清楚了[/quote] 你说你刚才用我的这个  把括号该后就好了？[/quote]  小括号也要全改成英文下的啊[/quote] 恩 好   我在试一下

引用 7 楼 paschen的回复: #include <stdio.h> #include <stdlib.h>  int main( void ) { 	printf( "Hello world!\n");  system( "pause" ); return 0; }   函数中的内容是放在大括号里，另外你其中一些括号是中文状态下的，编程中用的都是英文下的，这个要注意 现在这样就行了吗？   小白什么都不懂    正在学习中

引用 6 楼 maydaysar的回复:[quote=引用 5 楼 qq_32947505的回复:][quote=引用 2 楼 maydaysar的回复:][quote=引用 1 楼 maydaysar的回复:]这个有错吗？应该没错吧？ 括号，是大括号…………[/quote] 我也该过括号了  还是不行[/quote] 我刚才试了下，可以啊，就一个括号，具体为啥你不能我就不太清楚了[/quote] 你说你刚才用我的这个  把括号该后就好了？

引用 8 楼 qq_32947505 的回复:[quote=引用 6 楼 maydaysar的回复:][quote=引用 5 楼 qq_32947505的回复:][quote=引用 2 楼 maydaysar的回复:][quote=引用 1 楼 maydaysar的回复:]这个有错吗？应该没错吧？ 括号，是大括号…………[/quote] 我也该过括号了  还是不行[/quote] 我刚才试了下，可以啊，就一个括号，具体为啥你不能我就不太清楚了[/quote] 你说你刚才用我的这个  把括号该后就好了？[/quote]  小括号也要全改成英文下的啊

引用 5 楼 qq_32947505的回复:[quote=引用 2 楼 maydaysar的回复:][quote=引用 1 楼 maydaysar的回复:]这个有错吗？应该没错吧？ 括号，是大括号…………[/quote] 我也该过括号了  还是不行[/quote] 我刚才试了下，可以啊，就一个括号，具体为啥你不能我就不太清楚了

引用 2 楼 maydaysar的回复:[quote=引用 1 楼 maydaysar的回复:]这个有错吗？应该没错吧？ 括号，是大括号…………[/quote] 我也该过括号了  还是不行

引用 3 楼 qq_32947505的回复:[quote=引用 1 楼 maydaysar的回复:]这个有错吗？应该没错吧？ 总是生成失败   我还是头都晕了   琢磨一天了[/quote] 我也比较白，正在学习中……

引用 1 楼 maydaysar的回复:这个有错吗？应该没错吧？ 总是生成失败   我还是头都晕了   琢磨一天了

引用 1 楼 maydaysar的回复:这个有错吗？应该没错吧？ 括号，是大括号…………

这个有错吗？应该没错吧？


Question: 关于“局部变量存储周期”的一个小问题

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

佩服楼上大牛！ c primer plus  指针那块有讲说局部变量是独立的，生存周期就不太懂了-_-||

局部变量是栈变量, 第一次可以用是因为在fun之后, 这个值没有其它函数用,在调用printf之后, 这地址就被用到了, 它的值就不确定

int *p; int *q; int a = 21;   void fun() {     int b = 23; //这个是局部变量 栈内存 生命周期在两个括号之间，     p = &b;   //在括号内p的值是正确，除了括号就不知道了，就看这块栈内存有没有被再次利用覆盖     q = &a; //这个是全局变量， 静态区，生命周期直到程序关闭，所以一直是正确的 } //总之 不能用指针这样指向局部对象，后果未知，如果内存被复用，你用p操作此块内存，后果未知   int main(int argc, const char * argv[]) {       fun();     printf("%d\n", *p);      //p指向栈内存，此时fun函数已经结束，      printf("%d\n", *q);     printf("%d\n", *q);       printf("%d\n", *p);     printf("%d\n", *p);     return 0; } 对于(*p)来说，只要写在fun()函数后，就可以调用正确，反之，不行？ 对于你这句话，我的回答就是只要出了fun函数，所有的调用都是不正确的，有可能会导致未知结果  是不是系统对于局部变量的处理机制就是这样规定的讷？为什么用malloc()函数分配出来的空间会一直存在，而局部变量不是讷？ 局部变量：栈内存的变量 出了作用域也就是括号，变量被释放相应的内存也会被程序释放，具体内存中的数据有没有改变就，就看此内存有没有被复用 malloc()函数分配出来的空间，是堆内存，堆内存C++是不会主动去释放的，需要你人工去free释放，否则一直存在，就会造成所谓的内存泄露 我就说这么多了 推荐书籍 C++primer

对于p，其所指的地址你没有改当然没变了，只是他指向一个局部变量，其在函数结束时生命周期已结束 你说第一次调用还可以显示其值，那是因为那时该内存上的数据还没有被覆盖（调用函数是先把参数压栈），而你第一次使用printf之后，其值将会被prinft覆盖，所以不要在返回局部变量的指针

malloc是动态分配，程序员负责分配，也由程序员负责释放，而局部变量是在栈上分配的，不需要程序员自己释放，函数结束时会自动被回收


Question: C语言问题

#include<stdio.h> #include<stdlib.h>  int main() { 	int N,n; 	int i=0; 	int a[] ={11,15,18,20,29,31,43,50,}; 	int b[sizeof(a)/sizeof(a[0])+1] = {0}; 	 	printf("请输入插入的数字：\n"); 	scanf("%d", &N); 	 	for ( i=0; i<sizeof(a)/sizeof(a[0]); i++) 	{ 		if ( N >= a[i] ) 		{ 			b[i] = a[i]; 			n ++; 		} 		b[n] =N; 		if ( N < a[i] )  		{ 			b[i+1] = a[i]; 		} 	} 	 	for ( i=0; i<sizeof(a)/sizeof(a[0]); i++) 	{ 		printf("a[%d]=%d ",i,a[i]); 	 	} 	printf("\n"); 	for ( i=0; i<sizeof(a)/sizeof(a[0])+1; i++) 	{ 		printf("b[%d]=%d ",i,b[i]);	 	} 	 	return 0; }  你写的有问题，int　类型和　char　类型 混淆了（或者你有别的想法）。这是我写的  试了一下没有发现问题，你试试，有问题和我说一声

同意3楼，strlen放到初始化后再用吧

在strlen处使用sizeof不是更好吗

strlen(char*）函数求的是字符串的实际长度，它求得方法是从开始到遇到第一个'\0'，如果你只定义没有给它赋初值，这个结果是不定的，它会从aa首地址一直找下去，直到遇到'\0'停止。 strlen 是求字符串的实际长度  应为 char a[N]

给你说了初始化，你不初始化，长度是不对的，你试试就知道

还是不对，有大神帮我求解吗

引用 1 楼 user-5 的回复:int a[N]; 改成 char a[N];  因为根据你的代码判断你的a应该是要存储字符串  你看下这样呢：   # include <stdio.h> # include <string.h> # define N 100 int main() { 	char a[N]; 	int b[N+1]; 	int n; 	int len; 	int i = 0; 	printf("请输入一串有序数"); 	gets(a); 	len = strlen(a); 	printf("请输入一个数"); 	scanf_s("%d", &n); 	for (i = 0; i < len ; i++) 	{ 		if (n > a[i]) 			b[i] = a[i]; 		else 		{ 			b[i] = n; 			b[i + 1] = a[i]; 		} 	} 	for (i = 0; i < len + 1; i++) 	{ 		printf("%d", b[i]); 	} 	return 0; }

Len=strlen(a)不是代表数组a的长度吗，为何还要初始化

Len=strlen(a)你的a没有初始化，你把a初始化就可以了

为什么要改成char型，我照着你的改了，但是还是不对

int a[N]; 改成 char a[N];


Question: 【C新手求助】编译错误，不知道哪里错了，老提示缺失分号。源码已粘贴！

在vs下，双击错误，可以定位到出错行

引用 1 楼 user-2 的回复:调用函数时不需要加void  void avg(s); 改成  avg(s); void sort(avg1); 改成 sort(avg1);   #include "stdio.h"        main() { 	void avg(float s[4][3]); 	float s[4][3]; 	int i,j; 	for(i=0;i<4;i++) 	{ 		for(j=0;j<3;j++) 		{ 			printf("请输入第%d个学生的第%d门课程的成绩：",i+1,j+1); 			scanf("%f",&s[i][j]); 		} 		printf("\n"); 	} 	avg(s); } void avg(float s[4][3]) { 	void sort(float avg1[4]); 	float avgs,avgc,sum,avg1[4],avg2[3]; 	int i,j; 	for(i=0;i<4;i++) 	{ 		sum=0; 		for(j=0;j<3;j++) 		{ 			sum+=s[i][j]; 		} 		avgs=sum/4; 		avg1[i]=avgs; 	} 	for(i=0;i<4;i++) 	{ 		printf("第%d个学生的平均成绩是：%.2f",i+1,avg1[i]); 	} 	for(i=0;i<3;i++) 	{ 		sum=0; 		for(j=0;j<4;j++) 		{ 			sum+=s[j][i]; 		} 		avgc=sum/3; 		avg2[i]=avgc; 	} 	for(i=0;i<3;i++) 	{ 		printf("第%d门课程的平均成绩是：%.2f",i+1,avg2[i]); 	} 	sort(avg1); } void sort(float avg1[4]) { 	int i; 	float t; 	for(i=0;i<4;i++) 	{ 		if(avg1[i]>avg1[i+1]) 		{ 			t=avg1[i]; 			avg1[i]=avg1[i+1]; 			avg1[i+1]=t; 		} 	} 	printf("学生平均成绩排序："); 	for(i=0;i<4;i++) 	{ 		printf("%.2f",avg1[i]); 	} }  OK  谢了  看老一阵子没看出来  原来是这个不是问题的问题哈哈


Question: 关于CONST和define的区别

引用 15 楼 paschen 的回复:你这书上的不清楚，在优化的情况况下，如果没有对const常量取地址等操作，一般也会把其作立即数处理  在没优化下，你定义N个const变量，也会有N个内存空间  这什么书，我觉得写得很烂   好吧~

引用 11 楼 paschen 的回复:[quote=引用 10 楼 sinat_26551021 的回复:] [quote=引用 2 楼 paschen 的回复:] 问题3： #define是一个真常量，编译时会将其全部进行替换，而const却是由编译器判断实现的常量，是一个假常量。 使用const定义的变量，最终还是一个变量，只是在编译器内进行了检查，发现有修改则报错，所以如果想修改其值也是有办法的，可以强制去掉const修饰   这个怎么理解呢 [/quote]  哪里不理解呢[/quote]    我不清楚为什么const只分配一次内存，#define却是多次。  不是都定义了两个变量吗？ 两个变量不应该都分配内存吗

向前排的大牛致敬，学习了！ 预编译是编译器的事；变量名和指针不一样；小弟愚见：const更多在于帮你对一些不能修改值的变量把关，编译的时候如果你不小心改动了本该const的值就好报错——至于编译原理，小弟也是不懂

宏替换完全是在源文件上的文本操作。  ===========  只要程序的对外表现与标准规定是一致的，程序可以使用任何自己认为合适的方式实现一段代码，包括是否为一个常量/变量分配内存。  实际上，编译器连变量都可以不分配空间，何况常量。

引用 10 楼 sinat_26551021 的回复:[quote=引用 2 楼 paschen 的回复:] 问题3： #define是一个真常量，编译时会将其全部进行替换，而const却是由编译器判断实现的常量，是一个假常量。 使用const定义的变量，最终还是一个变量，只是在编译器内进行了检查，发现有修改则报错，所以如果想修改其值也是有办法的，可以强制去掉const修饰   这个怎么理解呢 [/quote]  哪里不理解呢

引用 2 楼 paschen 的回复:问题3： #define是一个真常量，编译时会将其全部进行替换，而const却是由编译器判断实现的常量，是一个假常量。 使用const定义的变量，最终还是一个变量，只是在编译器内进行了检查，发现有修改则报错，所以如果想修改其值也是有办法的，可以强制去掉const修饰   这个怎么理解呢

引用 6 楼 paschen 的回复:另外你不可能对#define定义的常量取地址，const则是可以的，因为他是一个假常量   define 和内存是没有什么关系的！！楼主你不要纠结这个，你可以理解为define 是一种工具而已

你看我才1级，这可能是我有生之年CSDN第一分，20分20分 快到碗里来

楼主你是不是骗人的，不是说有20分吧，我还没得过分呢，给我分给我分，都别和我抢啊

i,j是普通变量，i=M；是值M拷贝到i的存储空间里；同理I,J也是；

引用 1 楼 paschen 的回复:问题1，i、j不是指针，不需要指向任何内存地址，两个变量各自有各自的地址，其地址中的值均为5 问题2，是的   栈内存。也是内存吧。i j也是有内存地址的

1.在上面的程序中，i,j是指向同一个const定义的内存空间吗？ 不是，不同的栈内存 2.在上面的程序中，I=N、J=N中的5是在内存中开辟了两个值都5的空间吗？ 然后分别命名为I和J？ 是 3const和define在内存使用上有什么区别？ define  和内存怎么分配没关系。是预编译宏，可以理解为在代码中遇到N替换给5  建议，把这几个变量的地址 printf出来就很明显了


Question: 这字符型数据输入是怎么一回事啊，输入出错了？？

在每个最后不带\n的printf后面加fflush(stdout); 在每个不想受接收缓冲区旧内容影响的scanf前面加rewind(stdin); 另外请检查scanf的返回值。 //请今后要用 int c; scanf("%c",&c); //时，都改为 char s[2]; int c; scanf("%1s",s); c=s[0];

引用 3 楼 u010107248 的回复:[quote=引用 2 楼 zhangxiangDavaid 的回复:]  scanf("%d\n",&N ) ; //直接 scanf("%d",&N ) ;   scanf("%c %c %c\n" , &Tree[i].Element , &cl , &cr ) ; //改为 rewind(stdin); scanf("%c %c %c" , &Tree[i].Element , &cl , &cr ) ;  结果对了，正在看scanf语句中\n，空格的作用。。。亲最好能对我说下 [/quote]  接收最后的换行符

引用 1 楼 paschen 的回复:改成这样呢：   			scanf("%c %c %c" , &Tree[i].Element , &cl , &cr ) ; 			getchar();  引用 1 楼 paschen 的回复:改成这样呢：   			scanf("%c %c %c" , &Tree[i].Element , &cl , &cr ) ; 			getchar();  我还是弱逼啊

引用 2 楼 zhangxiangDavaid 的回复: scanf("%d\n",&N ) ; //直接 scanf("%d",&N ) ;   scanf("%c %c %c\n" , &Tree[i].Element , &cl , &cr ) ; //改为 rewind(stdin); scanf("%c %c %c" , &Tree[i].Element , &cl , &cr ) ;  结果对了，正在看scanf语句中\n，空格的作用。。。亲最好能对我说下


Question: 实现用数组存储二叉树的代码

搜“二叉树 序列化”


Question: 怎么根据带条件跳转的C语言生成的汇编代码写出对应的C程序

引用 10 楼 qq_31361473 的回复:学习c的终极形态就是学汇编吗 对学习编程者的忠告： 多用小脑和手，少用大脑、眼睛和嘴，会更快地学会编程！ 眼过千遍不如手过一遍！ 书看千行不如手敲一行！ 手敲千行不如单步一行！ 单步源代码千行不如单步Debug版对应汇编一行！ 单步Debug版对应汇编千行不如单步Release版对应汇编一行！

引用 1 楼 user-3 的回复:看《C++反汇编与逆向分析技术揭秘》 if 部分的讲解  另外什么叫返回值的默认值  就是返回值的初始化的值？主要就是这个没法确定，因为GCC编译的时候会进行某些优化，导致汇编代码的顺序和C语言代码顺序不一致！

学习c的终极形态就是学汇编吗

引用 8 楼 user-3 的回复:[quote=引用 7 楼 td901105td 的回复:] [quote=引用 6 楼 zhao4zhong1 的回复:] https://msdn.microsoft.com/zh-cn/magazine/7572ztz4.aspx   C代码形式是： int test(int x,int y) {     int  val = _____;     if()     .......      return val; }  对应的汇编代码如下：    请问val的初始值应该计算？ [/quote]  int val = 1;  产生的反汇编： mov   dword ptr [val],1 [/quote]  标准的答案是

引用 7 楼 td901105td 的回复:[quote=引用 6 楼 zhao4zhong1 的回复:] https://msdn.microsoft.com/zh-cn/magazine/7572ztz4.aspx   C代码形式是： int test(int x,int y) {     int  val = _____;     if()     .......      return val; }  对应的汇编代码如下：    请问val的初始值应该计算？ [/quote]  int val = 1;  产生的反汇编： mov   dword ptr [val],1

引用 6 楼 zhao4zhong1 的回复:https://msdn.microsoft.com/zh-cn/magazine/7572ztz4.aspx   C代码形式是： int test(int x,int y) {     int  val = _____;     if()     .......      return val; }  对应的汇编代码如下：    请问val的初始值应该计算？

16位下是AX 32位下是EAX 64位下是RAX  https://msdn.microsoft.com/zh-cn/magazine/9b372w95.aspx

引用 3 楼 zhao4zhong1 的回复:0 ？？？？？？？？？？？？？？？？？？？？


Question: c语言初学，结构体问题

#include <stdio.h> struct Worker {    //职工     int   num     ;//职工号     char  name[20];//姓名     char  sex     ;//性别     int   age     ;//年龄     int   years   ;//工龄     float salary  ;//工资     char  addr[20];//地址 }; int main() {     struct Worker a[3];     int i;     printf("\n请输入"         "职工号" ","         "姓名"   ","         "性别"   ","         "年龄"   ","         "工龄"   ","         "工资"   ","         "地址"   "\n"     );     for (i=0;i<3;i++) {         if (7!=scanf(             "%d,"             "%19[^,],"             "%c,"             "%d,"             "%d,"             "%f,"             "%19[^\n]"             ,&a[i].num             , a[i].name             ,&a[i].sex             ,&a[i].age             ,&a[i].years             ,&a[i].salary             , a[i].addr)) {                 i--;                 printf("格式错误！\n");                 rewind(stdin);             }     }     printf("\n"         "职工号" ","         "姓名"   ","         "性别"   ","         "年龄"   ","         "工龄"   ","         "工资"   ","         "地址"   "\n"     );     for (i=0;i<3;i++) {         printf(             "%d" ","             "%s" ","             "%c" ","             "%d" ","             "%d" ","             "%g" ","             "%s" "\n"             , a[i].num             , a[i].name             , a[i].sex             , a[i].age             , a[i].years             , a[i].salary             , a[i].addr);     }     return 0; }

请判断scanf函数的返回值。

这样呢：   #include <stdio.h> int main() { 	struct Worker 	{ 		int num; 		char name[20]; 		char sex; 		int age; 		int years; 		float salary; 		char addr[20]; 	}; 	struct Worker a[3]; 	int i; 	printf ("\n 请输入职工号，姓名，性别，年龄，工龄，工资，地址\n"); 	for (i=0;i<3;i++) 		scanf("%d\n%s\n%c\n%d\n%d\n%f\n%s\n",&a[i].num,a[i].name,&a[i].sex,&a[i].age,&a[i].years,&a[i].salary,a[i].addr); 	printf ("\n职工号，姓名，性别，年龄，工龄，工资，地址\n"); 	for (i=0;i<3;i++) 		printf("%6d %10s %6c %4d %4d %7.2f %10s\n",a[i].num,a[i].name,a[i].sex,a[i].age,a[i].years,a[i].salary,a[i].addr) ; 	return 0; }

对啊   就是用修改过的运行还不对 是我输入数据方式的问题么

引用 2 楼 xwdshiwo 的回复:为什么我运行了是这样的呢  请输入职工号，姓名，性别，年龄，工龄，工资，地址 2 nan n 2 2 2 add  职工号，姓名，性别，年龄，工龄，工资，地址      2        nan           0 3954064    0.00          ?      2          2           2    0    0.00     58                    -1   58    0.00            -------------------------------- Process exited after 11.63 seconds with return value 0 请按任意键继续. . .  用getchar接收了换行符

#include <stdio.h> int main() { 	struct Worker 	{ 		int num; 		char name[20]; 		char sex; 		int age; 		int years; 		float salary; 		char addr[20]; 	}; 	struct Worker a[3]; 	int i; 	printf ("\n 请输入职工号，姓名，性别，年龄，工龄，工资，地址\n"); 	for (i=0;i<3;i++) 	{ 		scanf("%d%s%c%d%d%f%s",&a[i].num,a[i].name,&a[i].sex,&a[i].age,&a[i].years,&a[i].salary,a[i].addr); 		getchar(); 	} 	printf ("\n职工号，姓名，性别，年龄，工龄，工资，地址\n"); 	for (i=0;i<3;i++) 		printf("%6d %10s %6c %4d %4d %7.2f %10s\n",a[i].num,a[i].name,a[i].sex,a[i].age,a[i].years,a[i].salary,a[i].addr) ; 	return 0; }   用getchar接收了换行符

另外请检查scanf的返回值。 //请今后要用 int c; scanf("%c",&c); //时，都改为 char s[2]; int c; scanf("%1s",s); c=s[0];  每天将下面的文字的意思揣摩三遍： Format Specification Fields: scanf and wscanf Functions A format specification has the following form:  % [width] [{h | l | I64 | L}]type  The format argument specifies the interpretation of the input and can contain one or more of the following:   White-space characters: blank (' '); tab ('\t'); or newline ('\n'). A white-space character causes scanf to read, but not store, all consecutive white-space characters in the input up to the next non–white-space character. One white-space character in the format matches any number (including 0) and combination of white-space characters in the input.   Non–white-space characters, except for the percent sign (%). A non–white-space character causes scanf to read, but not store, a matching non–white-space character. If the next character in stdin does not match, scanf terminates.   Format specifications, introduced by the percent sign (%). A format specification causes scanf to read and convert characters in the input into values of a specified type. The value is assigned to an argument in the argument list.  The format is read from left to right. Characters outside format specifications are expected to match the sequence of characters in stdin; the matching characters in stdin are scanned but not stored. If a character in stdin conflicts with the format specification, scanf terminates, and the character is left in stdin as if it had not been read.  When the first format specification is encountered, the value of the first input field is converted according to this specification and stored in the location that is specified by the first argument. The second format specification causes the second input field to be converted and stored in the second argument, and so on through the end of the format string.  An input field is defined as all characters up to the first white-space character (space, tab, or newline), or up to the first character that cannot be converted according to the format specification, or until the field width (if specified) is reached. If there are too many arguments for the given specifications, the extra arguments are evaluated but ignored. The results are unpredictable if there are not enough arguments for the format specification.  Each field of the format specification is a single character or a number signifying a particular format option. The type character, which appears after the last optional format field, determines whether the input field is interpreted as a character, a string, or a number.   The simplest format specification contains only the percent sign and a type character (for example, %s). If a percent sign (%) is followed by a character that has no meaning as a format-control character, that character and the following characters (up to the next percent sign) are treated as an ordinary sequence of characters, that is, a sequence of characters that must match the input. For example, to specify that a percent-sign character is to be input, use %%.  An asterisk (*) following the percent sign suppresses assignment of the next input field, which is interpreted as a field of the specified type. The field is scanned but not stored.

反复试了下。  觉得是char sex 占的字节不对。  char sex[2];   后面输入的时候 也把&去掉。   编译运行  没发现问题

但是有一点不太明白 为什么scanf正常输入会读不到呢，先输入整形num，然后输入的姓名字符串没法正确赋值给结构体的name么

ok 已经明白啦 谢谢大家


Question: help help 苦逼的计科妹子遇到了一个大难题。

同二楼，你的gys的while里的else多余吧

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

妹子 我按照你的思路 改了下，你看看

#include <stdio.h> int gys(int ,int ); int gbs(int ,int ,int );  int _tmain(int argc, _TCHAR* argv[]) { 	int m,n,l,s; 	printf("请输入两个整数"); 	scanf("%d,%d",&m,&n); 	l = gys(m,n); 	s = gbs(m,n,l); 	printf("最大公约数为%d最小公倍数为%d\n",l,s); 	system("pause"); 	return 0;       }  int gys(int m,int n) {	 	if(m>n) 		std::swap(m,n);  	int i=m; 	while(m!=0) 	{ 		if(m>n) 			std::swap(m,n);  		n=n-m; 	} 	if(n>0) 	  return (n); 	else 		return i; }  int gbs(int m,int n,int h) { 	int k,d; 	k=m*n; 	d=k/h;//改了 	return (d); }

你的gys取的名字叫公约数, 最后感觉象是要返回公倍数, 错了有2处 m>n改成m>=n,退出循环直接返回n, 公倍数的代码就不要,函数也不要了


Question: C语言中指针：不能通过改变指针形参的值而使指针实参的值改变

还是不太懂呀

引用 5 楼 paschen 的回复:[quote=引用 2 楼 Heessy 的回复:] =.=茅厕蹲开~~~！，那么代码1里面是不是要理解为这个函数将实参所指向的内存里面的内容发生交换？而代码2只是形参所拥有 的地址发生交换，并没有什么卵用？？  是的，代码1中 实参与形参（指针）的地址是不同的，但所指的内容是相同的 代码2 实参与形参（指针）的地址是不同的，交换形参没什么用[/quote] 66666666666茅厕蹲开，愁了我一晚上，总觉得是哪里不对，现在终于想明白了。

引用 2 楼 Heessy 的回复:=.=茅厕蹲开~~~！，那么代码1里面是不是要理解为这个函数将实参所指向的内存里面的内容发生交换？而代码2只是形参所拥有 的地址发生交换，并没有什么卵用？？  是的，代码1中 实参与形参（指针）的地址是不同的，但所指的内容是相同的 代码2 实参与形参（指针）的地址是不同的，交换形参没什么用

代码1在功能函数中是对指针所指向的栈地址中所存储的值进行操作，该地址的值是个主函数中的变量，除了主函数结束，不然值不会销毁，故能达到交换的效果，代码二和代码三是对功能函数的变量（形参的值）进行操作，待功能函数结束后即销毁。

引用 1 楼 paschen 的回复:代码2与3都不会达到交换，因为你形参只是实参的一个副本，交换的只是一个复制后的数，然后函数结束时就清除了 代码1中形参是实参的一个副本，但他们所指向的内存确是同一个地方，所以可以达到交换 =.=茅厕蹲开~~~！，那么代码1里面是不是要理解为这个函数将实参所指向的内存里面的内容发生交换？而代码2只是形参所拥有 的地址发生交换，并没有什么卵用？？


Question: 菜鸟 求救 uint16 转 char

这玩应自己有个函数 搞明白了

如果是c语言只支持 (char)adc这样的写法。

这 中国最大 IT 论坛  我终于来了


Question: 可变参函数的实现

http://blog.chinaunix.net/uid-21736802-id-1817658.html http://www.cnblogs.com/cpoint/p/3368993.html


Question: const int interval=RAND_MAX/10是什么意思？

引用 4 楼 zhao4zhong1 的回复:VS IDE中，在不明白的符号上点鼠标右键，选转到定义。 方法很好，可是偷懒，我建议把头文件能背的都背下来最好～～

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

引用 楼主 baidu_32921867 的回复:求解答，我是C语言菜鸟 楼主，我告诉你，你把分给我。。。  RAND_MAX 是一个宏定义，宏定义你应该知道，这个是头文件里面的宏定义。  具体在stdlib.h这个头文件中  打开这个头文件，搜索RAND_MAX，可以看到这一句：  #define RAND_MAX 0x7FFF  意思就是，它不是一般的变量，是头文件里面已经定义好的，用于随机数方面的应用；  —————————————————— 这个论坛里面难道就没人吗？？还是知道的太少？？我就奇怪了～～

楼上正解！！


Question: 求助帖，修改改良小游戏程序！

有点小卡，抖得厉害


Question: 进来看看这个代码，按理说交换不了数据吧？

仅供参考：#include <stdio.h> #define SWAP(a,b) do ((&(a))!=(&(b)))?((a)^=(b)^=(a)^=(b)):((a)=(a)); while (0) char   *p1="1" ,*p2="2" ; char    c1=1   , c2=2   ; short   s1=1   , s2=2   ; int     i1=1   , i2=2   ; __int64 I1=1i64, I2=2i64; float   f1=1.0f, f2=2.0f; double  d1=1.0 , d2=2.0 ; void main() {     SWAP((int)p1,(int)p2);                printf("char *     %5s,   %5s\n",p1,p2);     SWAP(c1,c2);                          printf("char       %5d,   %5d\n",c1,c2);     SWAP(s1,s2);                          printf("short      %5d,   %5d\n",s1,s2);     SWAP(i1,i2);                          printf("int        %5d,   %5d\n",i1,i2);     SWAP(I1,I2);                          printf("__int64 %5I64d,%5I64d\n",I1,I2);     SWAP(*(int     *)&f1,*(int     *)&f2);printf("float      %5g,   %5g\n",f1,f2);     SWAP(*(__int64 *)&d1,*(__int64 *)&d2);printf("double    %5lg,  %5lg\n",d1,d2);      SWAP(c1,c1);     printf("%d\n",c1); } //char *         2,       1 //char           2,       1 //short          2,       1 //int            2,       1 //__int64     2,    1 //float          2,       1 //double        2,      1 //2

void inv(int x[],int n)  //这里 数组会被退化成指针，所以呢，传入得实际上是数组的地址，故此会改变数组内容                                 //它操作的实际上是数组的地址内容，会改变原数组，而不是拷贝数组内容，拷贝的是数组的地址哟 {     int temp,i,j,m=(n-1)/2;     for(i=0;i<=m;i++)     {         j=n-1-i;         temp=x[i];         x[i]=x[j];         x[j]=temp;     }     return; }

数组作为函数参数都是通过指针传递，而不是复制，这主要考虑了效率，所以你的函数等价于是void inv(int* x,int n)，传进去的是指向数组首地址的指针，你修改指针取到的地址上的值当然在main中会得到体现

一楼说得对，inv传的a其实是指针哟，然后调用函数利用被调函数改了指针指向的值

inv的形式参数x得到了实际参数a的值，是一个地址，利用该地址找到了一片内存，把内存中的东西给改了


Question: printf

char *str="char *str=%c%s%c;main(){printf(str,34,str,34);}" ;   int main()   {    printf(str,34,str,34); //%c= 34 ,%s ="char *str=%c%s%c;main(){printf(str,34,str,34);}", %c=34    return 0;   } 所以是这样的啊

34替换%c，34对应" ，%s对应str  printf(str,34,str,34); 中第一个参数是要格式的字符串，后面的34 str 34 依次替换了%c %s %c

实现你没有理解 printf() 这个输出函数 其实第一个参数 就是一个字符串地址，可以是任何东西 ，它只不过会判断，该字符串中有没有 % 即格式占位符，如果有 它会向后寻找参数，然后替换；   str 代替了 以往我们自己写的 " "

想自己打印自己吗， 真霸气，看不懂

类似于 printf("char *str=%c%s%c;main(){printf(str,34,str,34);}", 34, "char *str=%c%s%c;main(){printf(str,34,str,34);}", 34);


Question: 逗号表达式与return

这个叫条件运算符，并不是逗号表达式

return i>45 ?*p: *q;

return i>45 ?  (*p): (*q);

引用 2 楼 akirya 的回复:return i>45 ?*p: *q; 这个是可以的；建议加上括号吧；

错误也贴上来啊

return (i>45) ? (*p): return(*q);

给1、2楼点赞

return i>45 ?*p: *q;

改成 if 。  =============  return 不是表达式


Question: C语言：写入某位置时，冲突，可能不止一处，希望有人帮我看看

#include <stdio.h> #include <stdlib.h>  #define STACK_INIT_SIZE 100; #define STACK_INCREMENT 10;  typedef struct Stack {     int *base;     int *top;     int stacksize; }Stack,*PStack;  /********???????********  *     第一个错误  *S作为参数传递 会造成浅拷贝  *初始化对象变成了拷贝对象而  *不是S本身，使用&引用，是对  *S本身进行操作，不会产生拷  *贝对象  ********???????********/ void Init_Stack(PStack &S); int StackEmpty(PStack S); void Push(PStack S,int e); void Pop(PStack S,int *e); void Detection(PStack S);  int main() {     PStack S=NULL;     int e=0;     int *c=NULL;     Init_Stack(S);     printf("请输入一行字符包含[](){}：");     e=getchar();     while(StackEmpty(S))     {         switch(e)         {             case '{':Push(S,e);break;             case '[':Push(S,e);break;             case '(':Push(S,e);break;             case '}':Pop(S,c);break;             case ']':Pop(S,c);break;             case ')':Pop(S,c);break;         }     }     if(StackEmpty(S))     {         printf("括号匹配成功!\n");     }     else printf("括号匹配不成功!\n");     return 1; }  void Init_Stack(PStack &S) {     /********???????********     *        第二个错误     *S为空指针 不能直接使用使用     ********???????********/     S = new  Stack;//申请空间          S->base=(int*)malloc(sizeof(int));          if(!S->base)     {         printf("内存分配失败！\n");         exit (0);     }     S->top=S->base;     S->stacksize=STACK_INIT_SIZE; }  int StackEmpty(PStack S) {     if(S->base==S->top) return 1;     else return 0; }  void Push(PStack S,int e) {     if(S->top-S->base>=S->stacksize)     {         S->base=(int*)realloc(S->base,(S->stacksize+10)*sizeof(int));//这里为何不能用STACK_INCREMENT代替10？         S->stacksize=S->stacksize+STACK_INCREMENT;     }     *(S->top)=e;     S->top++; }  void Pop(PStack S,int *e) {     if(S->base==S->top)     {         printf("空栈使用！\n");         exit (0);     }     S->top--;     e=S->top; }

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


Question: C语言main函数批处理的问题

写在C语言里

这个是在cmd中运行还是写在C语言里呢？

system("cmd /c test.bat");


Question: C语言新手 一个问题求解答

引用 9 楼 Azkrale 的回复:warning能消除最好，主要是我不知道她为什么要warning  改成3.0f也不行？

warning能消除最好，主要是我不知道她为什么要warning

真的是，warnning嘛，又不是error

可能是你编译器的问题吧，我用vc6.0能通过。

谢了，搞明白了 但是为什么我第六行f1=fun(3.0) 没加f就没有提示warning啊

把3.0与0.8分别写成3.0f与0.8f  如果不加f，常量默认当double处理

只是一个warning而已~

换成double 试试

#include<stdio.h> float fun(float x); int main() {     float f1,f2;     f1=fun(3.0f);     f2=fun(0.8f);     printf("f1=%f,f2=%f\n",f1,f2);     return 0; } float fun(float x) {     float y;     y=(x*x)+(4.0f*x)-5.0f;     return(y); }  常量也有类型： C++ Floating-Point Constants Floating-point constants specify values that must have a fractional part. These values contain decimal points (.) and can contain exponents.  Syntax  floating-constant :  fractional-constant exponent-partopt floating-suffixopt digit-sequence exponent-part floating-suffixopt  fractional-constant :  digit-sequenceopt . digit-sequence digit-sequence .  exponent-part :  e signopt digit-sequence E signopt digit-sequence  sign : one of  + –  digit-sequence :  digit digit-sequence digit  floating-suffix :one of  f l F L  Floating-point constants have a “mantissa,” which specifies the value of the number, an “exponent,” which specifies the magnitude of the number, and an optional suffix that specifies the constant’s type. The mantissa is specified as a sequence of digits followed by a period, followed by an optional sequence of digits representing the fractional part of the number. For example:  18.46 38.  The exponent, if present, specifies the magnitude of the number as a power of 10, as shown in the following example:  18.46e0      // 18.46 18.46e1      // 184.6  If an exponent is present, the trailing decimal point is unnecessary in whole numbers such as 18E0.  Floating-point constants default to type double. By using the suffixes f or l (or F or L — the suffix is not case sensitive), the constant can be specified as float or long double, respectively.  Although long double and double have the same representation, they are not the same type. For example, you can have overloaded functions like  void func( double );  and   void func( long double );

你用的是什么编译器，我用tcc 0.9.26 -win64 的编译不会出错呀， f1=16.000000，f2=-1.160000


Question: 求 C99 资料!!

引用 2 楼 paschen 的回复:参看：http://download.csdn.net/detail/computerclpp/7536039 谢谢

有官方标准文档吧。


Question: 在函数定义中能否使得一个结构体中的成员作为形式参数？

谢谢诸位，同志

引用 3 楼 akirya 的回复:成员变量指针 typedef struct A {     int S; }B ;  void func( int (B::*p) ) { 	B x; 	(x.*p) = 3; 	printf( "%d",x.S); }  int main ()  { 	int (B::*p) = &B::S;//没必要添加吧！ 	func(&B::S);     return 0; }  int (B::*p) = &B::S;//没必要添加吧！

引用 4 楼 CjavaC01 的回复:[quote=引用 3 楼 akirya 的回复:] 成员变量指针 typedef struct A {     int S; }B ;  void func( int (B::*p) ) { 	B x; 	(x.*p) = 3; 	printf( "%d",x.S); }  int main ()  { 	int (B::*p) = &B::S;//没必要添加吧！ 	func(&B::S);     return 0; }  int (B::*p) = &B::S;//没必要添加吧！[/quote] 没必要，只是顺手写上去的。

成员变量指针 typedef struct A {     int S; }B ;  void func( int (B::*p) ) { 	B x; 	(x.*p) = 3; 	printf( "%d",x.S); }  int main ()  { 	int (B::*p) = &B::S; 	func(&B::S);     return 0; }

#include <stdio.h>  typedef struct A{ 	int s; }B;  /*你用形参就是传地址*/ void la(int *t){ 	printf("%d\n",*t); } int main(void){ 	B b; 	b.s=10; 	la(&(b.s)); 	return 0; }

void la(int S) {     //.... }  调用时假如a是该结构体对象： la( a. S );


Question: 关于数据结构的问题

解决了就不看你代码了，有问题再回复，没问题接分哈

好吧，我知道了，等会回去编译一下，应该没问题了，等会更正


Question: 最后剩下的是几号，求大神指导，最好每一步都解析一下

仅供参考：//假设有n个人团团围做，从第1个人开始数数，数到第m个人时候，第m个人出列， //然后继续从1开始数数，数到第m个人退出 #include <stdio.h> #include <conio.h> int i,k,t; int n,m; static char f[1001];//0该座位未出圈,1该座位已出圈 void main() {     while (1) {         printf("Input n m(1000>=n>=m>=1):");         fflush(stdout);         rewind(stdin);         if (2==scanf("%d%d",&n,&m)) {             if (1000>=n && n>=m && m>=1) break;         }     }     t=0;//已出圈总人数     i=1;//座位编号     k=1;//当前要数的数     while (1) {         if (0==f[i]) {             if (m==k) {                 t++;                 f[i]=1;                 printf("%3d ",i);                 if (0==t%10) printf("\n");                 if (t>=n) break;             }             k++;if (k>m) k=1;         }         i++;if (i>n) i=1;     }     cprintf("Press any key ...");     getch(); }

#include<stdio.h> #include<stdlib.h> void main() { 	int m,n; 	int i = 0 ; 	int *start; 	int *p; 	int sum = 0; 	int j; 	printf("please input m\n"); 	scanf("%d",&m); 	printf("please input n\n"); 	scanf("%d",&n); 	start = malloc(m * sizeof(int)); 	if(start ==NULL) 		exit(1); 	 	/* 	**全部赋值为1 	*/ 	for(p = start,j = 0;j < m;j++) 	{ 		*p++ = 1; 	} 	 	 	while(i < m) 	{ 		for(j = 0,p = start;j < m;p++,j++) 		{ 			sum = sum + *p; 			if(sum ==n) 			{ 				i++; 				printf("%d\n",j+1); 				sum = 0; 				*p = 0; 			} 		} 		sum = n-1; 	} }  供参考，这里是m个人，n为周期


Question: 数组与字符串合并

#include <stdio.h> #include <stdlib.h>  #define    LEN    64  int main(void) { 	int message1[3][3] = { { 1,0,0 },{ 0,0,0 },{ 0,0,0 } }; 	const char *message2 = "help"; 	//char *message = new char[100]; 	char *message = NULL; 	message = (char *)malloc(sizeof(char) * LEN); 	if (NULL == message) { 		fprintf(stderr, "malloc error: %s\n", strerror(errno)); 		return 1; 	} 	//memset(message, 0, 100); 	memset(message, 0, LEN); 	sprintf(message, "%s%d%d%d%d%d%d%d%d%d", 		message2, 		message1[0][0], message1[0][1], message1[0][2], 		message1[1][0], message1[1][1], message1[1][2], 		message1[2][0], message1[2][1], message1[2][2]); 	printf("%s", message);         free(message); 	return 0; } C语言中通过malloc/realloc/calloc来申请堆上的空间；

引用 6 楼 zyzy577048814 的回复:[quote=引用 5 楼 jiht594 的回复:] #include <iostream> #include <stdio.h> #include <stdlib.h> #include <string.h>  using namespace std;   int main () {     int message1[3][3] = {{1,0,0},{0,0,0},{0,0,0}};     const char *message2 = "help";     char *message = new char[100];     memset(message, 0, 100);     sprintf(message, "%s%d%d%d%d%d%d%d%d%d",             message2,             message1[0][0], message1[0][1], message1[0][2],             message1[1][0], message1[1][1], message1[1][2],             message1[2][0], message1[2][1], message1[2][2]);     cout << message << endl;     return 0 ; }  我把他修改成c语言怎么不对了，能帮我看一看吗？ int main() { 	int message1[3][3] = { { 1,0,0 },{ 0,0,0 },{ 0,0,0 } }; 	const char *message2 = "help"; 	//char *message = new char[100]; 	char *message = NULL; 	//memset(message, 0, 100); 	sprintf(message, "%s%d%d%d%d%d%d%d%d%d", 		message2, 		message1[0][0], message1[0][1], message1[0][2], 		message1[1][0], message1[1][1], message1[1][2], 		message1[2][0], message1[2][1], message1[2][2]); 	printf("%c", message); 	return 0; }[/quote] 可以了，我把 char *message = NULL;改成 char message[100]; 输出来了，不过这个sprintf得手工把数组一个一个打进去。要是数组大了就不太实用啊，要是能有for就好了！

引用 5 楼 jiht594 的回复:#include <iostream> #include <stdio.h> #include <stdlib.h> #include <string.h>  using namespace std;   int main () {     int message1[3][3] = {{1,0,0},{0,0,0},{0,0,0}};     const char *message2 = "help";     char *message = new char[100];     memset(message, 0, 100);     sprintf(message, "%s%d%d%d%d%d%d%d%d%d",             message2,             message1[0][0], message1[0][1], message1[0][2],             message1[1][0], message1[1][1], message1[1][2],             message1[2][0], message1[2][1], message1[2][2]);     cout << message << endl;     return 0 ; }  我把他修改成c语言怎么不对了，能帮我看一看吗？ int main() { 	int message1[3][3] = { { 1,0,0 },{ 0,0,0 },{ 0,0,0 } }; 	const char *message2 = "help"; 	//char *message = new char[100]; 	char *message = NULL; 	//memset(message, 0, 100); 	sprintf(message, "%s%d%d%d%d%d%d%d%d%d", 		message2, 		message1[0][0], message1[0][1], message1[0][2], 		message1[1][0], message1[1][1], message1[1][2], 		message1[2][0], message1[2][1], message1[2][2]); 	printf("%c", message); 	return 0; }

顶一下。有人知道吗？

你这个效率略低。

引用 9 楼 zhao4zhong1 的回复:狗尾续貂： #include <stdio.h> #include <stdlib.h> #include <string.h> #define    LEN    64 int main() {     int L,message1[3][3] = { { 1,0,0 },{ 0,0,0 },{ 0,0,0 } };     char *message2="help";     char *message = NULL,*p;     message = (char *)malloc(sizeof(char) * LEN);     if (NULL == message) {         fprintf(stderr, "malloc error: %s\n", strerror(errno));         return 1;     }     p=message;     L=sprintf(p,"%s",message2);p+=L;     for (int y=0;y<3;y++)     for (int x=0;x<3;x++) {         L=sprintf(p,"%d",message1[y][x]);p+=L;     }     printf("[%s]\n", message);     free(message);     return 0; } //[help100000000] //  嗯嗯，我中午写出来了，弄了个小封装，写成子函数了，不过还是谢谢啦！  #include <stdio.h> #include <stdlib.h>  #define    LEN    64 #define M 3 #define N 3 int get_message(char *message2, int message1[M][N]); int main(void) { 	 	int message1[M][N] = { { 1,0,0 },{ 0,0,0 },{ 0,0,0 } }; 	const char *message2 = "help"; 	message2=get_message(message2, message1); 	printf("%s", message2); 	return 0; }      int get_message(char *message2,int message1[M][N]) { 	int i, j; 	char *message = NULL; 	message = (char *)malloc(sizeof(char) * LEN); 	if (NULL == message) { 		fprintf(stderr, "malloc error: %s\n", strerror(errno)); 		return 1; 	} 	memset(message, 0, LEN); 	sprintf(message, "%s",message2); 	//printf("%s", message); 	for (i = 0;i < M;i++) 		for (j = 0;j < N;j++) 		{  			sprintf(message, "%s%d", 			message, 		    message1[i][j]); 		} 	//printf("%s", message); 	return message; 	free(message); }

作为一个C程序员，对  scanf,sscanf,fscanf  printf,sprintf,fprintf 这类函数的用法，还是要做到“拳不离手，曲不离口”的。

引用 1 楼 user-4 的回复:你期望得到的结果是什么？期望得到“help100000000”

你期望得到的结果是什么？


Question: 求Sn=a+aa+aaa+⋯+aa⋯aaa（有n个a）之值，其中a是一个数字。例如：2+22+222+2222+22222（n=5），n由键盘输入。

原来二维码还可以表示一个字符！涨姿势了！！

引用 9 楼 mewiteor 的回复:[quote=引用 8 楼 zhao4zhong1 的回复:] [quote=引用 6 楼 fly_dragon_fly 的回复:] 我记得这有个坑, a不一定是个位数, 如果a=10了 10是一个数字吗？[/quote]那万一a不是十进制数字呢？[/quote] 万一a是一亿进制数呢？哪找一亿个不同的字符表示其各位数字呢？！

引用 8 楼 zhao4zhong1 的回复:[quote=引用 6 楼 fly_dragon_fly 的回复:] 我记得这有个坑, a不一定是个位数, 如果a=10了 10是一个数字吗？[/quote]10有2位, 它应该是一个数字吧, 好吧, 题目要求确实不明确, 可能确实只要一位数

引用 11 楼 zhao4zhong1 的回复:[quote=引用 9 楼 mewiteor 的回复:] [quote=引用 8 楼 zhao4zhong1 的回复:] [quote=引用 6 楼 fly_dragon_fly 的回复:] 我记得这有个坑, a不一定是个位数, 如果a=10了 10是一个数字吗？[/quote]那万一a不是十进制数字呢？[/quote] 万一a是一亿进制数呢？哪找一亿个不同的字符表示其各位数字呢？！[/quote]                                                                            100000000

int main(int argc, char *argv[]) {     int i = 0;     int n = 0;     int a = 0;     unsigned long long t = 0;     unsigned long long s = 0;      while (1) {         printf("请输入 a 和 n：\n");         scanf("%d %d", &a, &n);         if (a < 1 || a > 9) {             printf("数字 a 不合法！\n");             continue;         }         if (n < 1 || a > 18) {             printf("数字 n 不合法！\n");             continue;         }         break;     }      while (i++ < n) {         t *= 10;         t += a;         printf("%llu%c", t, i < n ? '+' : '=');         s += t;     }     printf("%llu\n", s);          return 0; }

我记得这有个坑, a不一定是个位数, 如果a=10了

引用 8 楼 zhao4zhong1 的回复:[quote=引用 6 楼 fly_dragon_fly 的回复:] 我记得这有个坑, a不一定是个位数, 如果a=10了 10是一个数字吗？[/quote]那万一a不是十进制数字呢？

引用 6 楼 fly_dragon_fly 的回复:我记得这有个坑, a不一定是个位数, 如果a=10了 10是一个数字吗？

你上面那个应该是%d%d

最后一个代码中：a=a*10+a;之后,a就不是一位数了，而上一个代码中b=b*10+a;中的a一直没有变，一直是一位数。

sum和s没有初始化

#include <stdio.h> void main() {  double a,b,sn=0;  int i,n;  printf("please input a:");  scanf("%lf",&a);  printf("please input n:");  scanf("%d",&n);  b=a;  for(i=1;i<=n;i++){   sn+=b;   b=b*10+a;  }   printf("Sn=%.0lf",sn); 这是对的

#include <stdio.h> void main() {  double a,b,sn=0;  int i,n;  printf("please input a:");  scanf("%lf",&a);  printf("please input n:");  scanf("%d",&n);   for(i=1;i<=n;i++){   sn+=a;   a=a*10+a;  }   printf("Sn=%.0lf",sn); 这是错的


Question: 初学C语指针 这个例题如何解答？求大神！谢！

我觉得好像在输出的时候改一下 伪代码 for(int i=0; i<NUM-2;i++)   if(a[i]为字符&&a[i+1]为字符）输出a[i]#   else 输出a[i] 输出a[NUM-1] 判断是否字符std空间中有此函数

先malloc足够的内存，copy字符串到 *p ,strlen求长度，在从后往前插，比如： *(p+len+1)=*p(len);len--  以此类推知道len=1;   len初始为len=strlen(p).  我理解这样写最好，望高手指点

这样连*p 的使用都省了 完全满足需求O(∩_∩)O

char a[NUM],*p;     p =a;     while(~(*p=getchar())){         if(*p==' '||*p=='\n') {             *--p ='\0';             p =a;             printf("%s\n",a);             continue;         }         if(p!=a) p[-1] ='#';         p+=2;     }

不能存为新数组吧？

//从键盘输入字符串以回车键结束，在每两个字符间插入一个“#”构成新的字符串。例如输入abc，输出a#b#c #include <string.h> #include <stdio.h> int main() {     char a[2];     //不允许再定义新的变量     a[0]=getchar();     while (1) {         if (a[0]=='\n') {             putchar(a[0]);             break;         } else {             a[1]=getchar();             if (a[1]=='\n') {                 putchar(a[0]);                 putchar(a[1]);                 break;             } else {                 putchar(a[0]);                 putchar('#');                 a[0]=a[1];             }         }     }     return 0; } //输入：回车 //输出：回车 // //输入：1回车 //输出：1回车 // //输入：12回车 //输出：1#2回车 // //输入：123回车 //输出：1#2#3回车 //

应该没办法存为新的数组吧， 是不是直接在打印的时候遍历并穿插#呢

引用 2 楼 paschen的回复: int main() { 	char a[100]; //输入的字符串 	scanf("%s", a); 	char b[200]; //修改后的字符串 	char* p; 	p = a; 	int i; 	i = 0; 	while(*p) 	{ 		b[i++] = *p++; 		b[i++] = '#'; 	} 	b[i-1] = '\0'; 	printf("\n%s", b); 	return 0; }  他不让定义新的变量

简单的办法就是插入咯。从后往前差


Question: 打印函数名,函数名前加n个*为什么结果相同?

C11 draft n1570 6.3.2.1 Lvalues, arrays, and function designators 4 A function designator is an expression that has function type. Except when it is the operand of the sizeof operator, the _Alignof operator, or the unary & operator, a function designator with type ‘‘function returning type’’ is converted to an expression that has type ‘‘pointer to function returning type’’.  6.5.3.2 Address and indirection operators 4 The unary * operator denotes indirection. If the operand points to a function, the result is a function designator; if it points to an object, the result is an lvalue designating the object. If the operand has type ‘‘pointer to type’’, the result has type ‘‘type’’. If an invalid value has been assigned to the pointer, the behavior of the unary * operator is undefined.  function designator 会自动转换成 pointer to function, 加一个 * 之后变成 function designator ，然后又自动转换成 pointer to function，周而复始，无论你加多少 * ，最后拿到的还是一个 pointer to function 。

typedef void (*FUNC) (); FUNC p =func; 你可以想想上面的代码 函数会转换成它的指针类型 就像数组会变成指针一样


Question: c语言求大神指点，提交题目时出现了问题，数组访问越界

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

人家要求1000你只有100当然越界


Question: C语言主函数gets（）自动输入了子函数内容！求解！

在每个最后不带\n的printf后面加fflush(stdout); 在每个不想受接收缓冲区旧内容影响的scanf前面加rewind(stdin); 另外请检查scanf的返回值。 //请今后要用 int c; scanf("%c",&c); //时，都改为 char s[2]; int c; scanf("%1s",s); c=s[0];

引用 11 楼 qq_26122039 的回复:printf_max()函数中，每次执行完 printf("Please enter your choice 1-5："); scanf("%d", &i)；后缓冲区中都有一个换行符，然而gets()就把这个换行符都进去了，终止了gets的输入   如果没有getchar()（吃掉scanf留下来的回车符 ）gets（）会吃掉回车符 那为什么这条puts("****************************");会出现在 printf("max [%d] = Continue input: ", i);后面 ，表示不理解！

参考2楼。  在现实世界中，除时间和空间可能是无限的以外，其它任何事物都是有限的。

引用 9 楼 zhao4zhong1 的回复:char max[10] = { 0 }; 应改为 char max[10][80];  赵4老师 char max[10]和char max[10][80];的区别是什么？ 我一直认为max[10]用指针输入字符串每个max[i]都可以无限放字符串 这样的理解是不是有错误？

引用 13 楼 libinden71的回复:[quote=引用 11 楼 qq_26122039 的回复:] printf_max()函数中，每次执行完 printf("Please enter your choice 1-5："); scanf("%d", &i)；后缓冲区中都有一个换行符，然而gets()就把这个换行符都进去了，终止了gets的输入   如果没有getchar()（吃掉scanf留下来的回车符 ）gets（）会吃掉回车符 那为什么这条puts("****************************");会出现在 printf("max [%d] = Continue input: ", i);后面 ，表示不理解！ [/quote] 因为printf函数执行完后，没有换行，而且因缓冲区的换行符gets停止输入，则马上执行printf-max函数

求帮忙解决！哎！ 怎么感觉学了指针内存之后 感觉要考虑的东西好多好多！特别是内存的问题是不是因为本人太笨了   感觉越学越不懂C了

有getchar（）输出则正常！

引用 5 楼 zhao4zhong1 的回复:越界访问数组max[10]，会覆盖数组后的变量p的值。  判断是否越界访问，可以在数组的最后一个元素之后对应的地址处设置数据读写断点。如果该地址对应其它变量干扰判断，可将数组多声明一个元素，并设置数据读写断点在该多出元素对应的地址上。 #include <time.h> #include <stdlib.h> #include <windows.h> int main() {     int a,b[11];//本来是b[10]，为判断哪句越界，故意声明为b[11]      srand((unsigned int)time(NULL));//按两次F11，等黄色右箭头指向本行时，调试、新建断点、新建数据断点，地址：&b[10]，字节计数：4，确定。     while (1) {//按F5，会停在下面某句，此时a的值为10，b[10]已经被修改为对应0..4之一。         b[(a=rand()%11)]=0;         Sleep(100);         b[(a=rand()%11)]=1;         Sleep(100);         b[(a=rand()%11)]=2;         Sleep(100);         b[(a=rand()%11)]=3;         Sleep(100);         b[(a=rand()%11)]=4;         Sleep(100);     }     return 0; }   赵4老师 有个问题 真弄不明白啊！求解答啊！完全蒙了！跪求老师帮忙！ int prinf_max(void) { 	int i = 0; 	puts("****************************"); 	puts("1. Output string list."); 	puts("2. ASCII code output string."); 	puts("3. Sequence output string by length."); 	puts("4. Output string by the length of the first word in the string."); 	puts("5. quit!"); 	puts("****************************"); 	printf("Please enter your choice 1-5："); 	scanf("%d", &i);  	return i; }  int main() { 	int i = 0, number = 0; 	char max[10] = { 0 }; 	char *p = max;  	printf("Enter the 10 strings, confirm that please press enter\n"); 	while (i< 10) 	{ 		getchar(); 		printf("max [%d] = Continue input: ", i); 		gets(&p[i++]);  		number = prinf_max();  		switch (number) 		{ 			case 1:puts(""); break; 			case 2:puts(""); break; 			case 3:puts(""); break; 			case 4:puts(""); break; 			case 5:puts(""); break; 		} 	}  	return 0; } 终端：  getchar（）起到什么作用？为什么没有getchar（）输出则是：  没了getchar（）为什么会自动输入puts("****************************");  （执行完一遍后到了gets(&p[i++]); 都还没调用number = prinf_max();为什么会自动输入puts("****************************");  ）我表示无法理解

引用 2 楼 zhao4zhong1 的回复:char max[10];//只够保存9个半角字符和末尾的'\0'，保存不下10个字符串。 char max[10][80];//够保存max[0..9]共10个字符串，每个字符串中够保存79个半角字符和末尾的'\0'   是这个原因导致 自动输入puts("****************************");？

在线等！


Question: C语言的gets（）问题！

我明白怎么回事了 感谢赵4老师！

引用 5 楼 zhao4zhong1 的回复://1个长度为N的字符串a_str是N+1个字符的数组 char a_str[N+1]; //10个长度为N的字符串ten_str是10个（N+1个字符的数组）组成的数组 char ten_str[10][N+1];    我搞不明白的就是 我定义的是char *p = max;     gets(p+i++);  从max[0] 开始每次都输入字符串“aaa”然后回车（自动附上‘\0’） 到max[9]的时候 输入完毕 回车 也没越界啊！为什么会错误！而且我用的是指针，按理上来说指针指向了p[9]的空间往里面存字符串不可能会照成这样的情况啊？这种输入方式和char max="......"不是一样的吗？我在qt creator下试了完美通过 表示完全蒙了！  是不是我哪理解错了？

char max[10];//里面最多保存9个半角字符和一个末尾的'\0'，存不下10个字符串。   不是很明白！每个字符串末尾不是已经有‘\0’了吗？  为什么还要在max[10]在存个‘\0’   能解释在详细点吗？  我表示一头雾水啊！

楼上的代码怎么不全呢？ #include <stdio.h> #include <string.h> int main() {     int i = 0,j;     char strs[10][8];     char *p = &strs[0][0];     puts("Please enter 10 strings");     while (i<10) {         printf("strs [%d] = Continue input: ",i);         fflush(stdout);         rewind(stdin);         fgets(p,8,stdin);         if ('\n'==p[strlen(p)-1]) p[strlen(p)-1]=0;         i++;         for (j=0;j<i;j++) {             printf("strs [%d] = [%s]\n",j,strs[j]);         }         p+=8;     }     return 0; } //Please enter 10 strings //strs [0] = Continue input: 1234567890 //strs [0] = [1234567] //strs [1] = Continue input: //strs [0] = [1234567] //strs [1] = [] //strs [2] = Continue input: a //strs [0] = [1234567] //strs [1] = [] //strs [2] = [a] //strs [3] = Continue input: ab //strs [0] = [1234567] //strs [1] = [] //strs [2] = [a] //strs [3] = [ab] //strs [4] = Continue input: abc //strs [0] = [1234567] //strs [1] = [] //strs [2] = [a] //strs [3] = [ab] //strs [4] = [abc] //strs [5] = Continue input: X //strs [0] = [1234567] //strs [1] = [] //strs [2] = [a] //strs [3] = [ab] //strs [4] = [abc] //strs [5] = [X] //strs [6] = Continue input: XYZ //strs [0] = [1234567] //strs [1] = [] //strs [2] = [a] //strs [3] = [ab] //strs [4] = [abc] //strs [5] = [X] //strs [6] = [XYZ] //strs [7] = Continue input: 哈哈 //strs [0] = [1234567] //strs [1] = [] //strs [2] = [a] //strs [3] = [ab] //strs [4] = [abc] //strs [5] = [X] //strs [6] = [XYZ] //strs [7] = [哈哈] //strs [8] = Continue input: !@#$%^&*() //strs [0] = [1234567] //strs [1] = [] //strs [2] = [a] //strs [3] = [ab] //strs [4] = [abc] //strs [5] = [X] //strs [6] = [XYZ] //strs [7] = [哈哈] //strs [8] = [!@#$%^&] //strs [9] = Continue input: end //strs [0] = [1234567] //strs [1] = [] //strs [2] = [a] //strs [3] = [ab] //strs [4] = [abc] //strs [5] = [X] //strs [6] = [XYZ] //strs [7] = [哈哈] //strs [8] = [!@#$%^&] //strs [9] = [end] //

char max[10];//里面最多保存9个半角字符和一个末尾的'\0'，存不下10个字符串。  崩溃的时候在弹出的对话框按相应按钮进入调试，按Alt+7键查看Call Stack即“调用堆栈”里面从上到下列出的对应从里层到外层的函数调用历史。双击某一行可将光标定位到此次调用的源代码或汇编指令处，看不懂时双击下一行，直到能看懂为止。  其实电脑开机后物理内存的每个字节都是可读写的，从来不会因为所谓的new、delete或malloc、free而被创建、销毁。区别仅在于操作系统内存管理模块在你读写时是否能发现并是否采取相应动作而已。操作系统管理内存的粒度不是字节而是页，一页通常为4KB。 #include <stdio.h> #include <string.h> int main() {     int i = 0,j;     char strs[10][8];     char *p = &strs[0][0];     puts("Please enter 10 strings");     while (i<10) {         printf("strs [%d] = Continue input: ",i);         fflush(stdout);         rewind(stdin);         fgets(p,8,stdin);         if ('\n'==p[strlen(p)-1]) p[strlen(p)-1]=0;         i++;         for (j=0;j<i;j++) {             printf("strs [%d] = [%s]\n",j,strs[j]);         }         p+=8;     }     return 0; } //Please enter 10 strings //strs [0] = Continue input: 1234567890 //strs [0] = [1234567] //strs [1] = Continue input: //strs [0] = [1234567] //strs [1] = [] //strs [2] = Continue input: a //strs [0] = [1234567] //strs [1] = [] //strs [2] = [a] //strs [3] = Continue input: ab //strs [0] = [1234567] //strs [1] = [] //strs [2] = [a] //strs [3] = [ab] //strs [4] = Continue input: abc //strs [0] = [1234567] //strs [1] = [] //strs [2] = [a] //strs [3] = [ab] //strs [4] = [abc] //strs [5] = Continue input: X //strs [0] = [1234567] //strs [1] = [] //strs [2] = [a] //strs [3] = [ab] //strs [4] = [abc] //strs [5] = [X] //strs [6] = Continue input: XYZ //strs [0] = [1234567] //strs [1] = [] //strs [2] = [a] //strs [3] = [ab] //strs [4] = [abc] //strs [5] = [X] //strs [6] = [XYZ] //strs [7] = Continue input: 哈哈 //strs [0] = [1234567] //strs [1] = [] //strs [2] = [a] //strs [3] = [ab] //strs [4] = [abc] //strs [5] = [X] //strs [6] = [XYZ] //strs [7] = [哈哈] //strs [8] = Continue input: !@#$%^&*() //strs [0] = [1234567] //strs [1] = [] //strs [2] = [a] //strs [3] = [ab] //strs [4] = [abc] //strs [5] = [X] //strs [6] = [XYZ] //strs [7] = [哈哈] //strs [8] = [!@#$%^&] //strs [9] = Continue input: end //strs [0] = [1234567] //strs [1] = [] //strs [2] = [a] //strs [3] = [ab] //strs [4] = [abc] //strs [5] = [X] //strs [6] = [XYZ] //strs [7] = [哈哈] //strs [8] = [!@#$%^&] //strs [9] = [end] //

求回答啊！求顶起啊！


Question: C语言字符串查找函数问题

已经知道了 谢谢老师  fgets 读入字符串 默认会把回车一起读进去 导致关键字后面跟个回车。。。。。。 所以提取不出来

引用 2 楼 qq_31741093 的回复:调半天了  就是不知道 那里出问题 只要关键字位置 不要出现在第一个位置 就没事 否则就出不来 有时不将“调用函数名字＋各参数值，进入函数后各参数值，中间变量值，退出函数前准备返回的值，返回函数到调用处后函数名字＋各参数值＋返回值”这些信息写日志到文件中是无论如何也发现不了问题在哪里的，包括捕获各种异常、写日志到屏幕、单步或设断点或生成core文件、……这些方法都不行！ 写日志到文件参考下面： #include <stdio.h> #include <stdlib.h> #include <string.h> #ifdef WIN32     #include <windows.h>     #include <io.h> #else     #include <unistd.h>     #include <sys/time.h>     #include <pthread.h>     #define  CRITICAL_SECTION   pthread_mutex_t     #define  _vsnprintf         vsnprintf #endif //Log{ #define MAXLOGSIZE 20000000 #define MAXLINSIZE 16000 #include <time.h> #include <sys/timeb.h> #include <stdarg.h> char logfilename1[]="MyLog1.log"; char logfilename2[]="MyLog2.log"; static char logstr[MAXLINSIZE+1]; char datestr[16]; char timestr[16]; char mss[4]; CRITICAL_SECTION cs_log; FILE *flog; #ifdef WIN32 void Lock(CRITICAL_SECTION *l) {     EnterCriticalSection(l); } void Unlock(CRITICAL_SECTION *l) {     LeaveCriticalSection(l); } #else void Lock(CRITICAL_SECTION *l) {     pthread_mutex_lock(l); } void Unlock(CRITICAL_SECTION *l) {     pthread_mutex_unlock(l); } #endif void LogV(const char *pszFmt,va_list argp) {     struct tm *now;     struct timeb tb;      if (NULL==pszFmt||0==pszFmt[0]) return;     _vsnprintf(logstr,MAXLINSIZE,pszFmt,argp);     ftime(&tb);     now=localtime(&tb.time);     sprintf(datestr,"%04d-%02d-%02d",now->tm_year+1900,now->tm_mon+1,now->tm_mday);     sprintf(timestr,"%02d:%02d:%02d",now->tm_hour     ,now->tm_min  ,now->tm_sec );     sprintf(mss,"%03d",tb.millitm);     printf("%s %s.%s %s",datestr,timestr,mss,logstr);     flog=fopen(logfilename1,"a");     if (NULL!=flog) {         fprintf(flog,"%s %s.%s %s",datestr,timestr,mss,logstr);         if (ftell(flog)>MAXLOGSIZE) {             fclose(flog);             if (rename(logfilename1,logfilename2)) {                 remove(logfilename2);                 rename(logfilename1,logfilename2);             }         } else {             fclose(flog);         }     } } void Log(const char *pszFmt,...) {     va_list argp;      Lock(&cs_log);     va_start(argp,pszFmt);     LogV(pszFmt,argp);     va_end(argp);     Unlock(&cs_log); } //Log} int main(int argc,char * argv[]) {     int i; #ifdef WIN32     InitializeCriticalSection(&cs_log); #else     pthread_mutex_init(&cs_log,NULL); #endif     for (i=0;i<10000;i++) {         Log("This is a Log %04d from FILE:%s LINE:%d\n",i, __FILE__, __LINE__);     } #ifdef WIN32     DeleteCriticalSection(&cs_log); #else     pthread_mutex_destroy(&cs_log); #endif     return 0; } //1-78行添加到你带main的.c或.cpp的那个文件的最前面 //81-85行添加到你的main函数开头 //89-93行添加到你的main函数结束前 //在要写LOG的地方仿照第87行的写法写LOG到文件MyLog1.log中

贴完整的代码上来，不要贴截图。

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


Question: 如何学习 才能掌握C#这门语言呢？

感谢！感谢！感谢！感谢！感谢！感谢！感谢！

C#入门经典，多看书多思考多实践，编程经验需要积累，只要有兴趣，学编程并不难

紧跟MSDN中的C#入门教程一步一个脚印走。


Question: 关于注释

/* */   可以跨越多行，这两个符号之间的都算注释的内容 //  这个只是从此符号开始，到该行结束部分做为注释  注释只是为了让人读的，方便更好的去理解代码，不影响程序的执行，编译时注释均会被忽略

要注释why 不要注释what、how、who、when


Question: C#怎么写发送彩信的程序？新手求指教！！！！！！！最好有开源代码

楼主可以移步到C#社区提问啊，这是C/C++社区


Question: C语言如何从外部，屏蔽掉调用API时所抛出的消息提示框

引用 2 楼 chen_zhi_heng 的回复:[quote=引用 1 楼 paschen的回复:]后台线程监视，如果找到该窗口，发消息关闭之 可是这个api会报很多不同的消息框，请问我该如何获得它的句柄？句柄是固定的吗？仅仅用活动窗口去取句柄会不会有问题？[/quote]  也可以根据窗口名，FindWindow

改为用WinExec("xxx.exe e ... ",SW_HIDE);调用命令行版本的xxx.exe解压。

引用 1 楼 paschen的回复:后台线程监视，如果找到该窗口，发消息关闭之 可是这个api会报很多不同的消息框，请问我该如何获得它的句柄？句柄是固定的吗？仅仅用活动窗口去取句柄会不会有问题？

后台线程监视，如果找到该窗口，发消息关闭之

引用 5 楼 chen_zhi_heng 的回复:[quote=引用 4 楼 paschen的回复:][quote=引用 2 楼 chen_zhi_heng 的回复:] [quote=引用 1 楼 paschen的回复:]后台线程监视，如果找到该窗口，发消息关闭之 可是这个api会报很多不同的消息框，请问我该如何获得它的句柄？句柄是固定的吗？仅仅用活动窗口去取句柄会不会有问题？[/quote]  也可以根据窗口名，FindWindow[/quote] 感谢。再追问一下，findwindow这个函数传入的标题名称必须完全匹配。有没有方法只匹配一部分？比如我要屏蔽的报错窗口标题都是（unlha32。。。。）开头。[/quote]  那就需要用EnumWindow遍历窗口然后进行判断

引用 4 楼 paschen的回复:[quote=引用 2 楼 chen_zhi_heng 的回复:] [quote=引用 1 楼 paschen的回复:]后台线程监视，如果找到该窗口，发消息关闭之 可是这个api会报很多不同的消息框，请问我该如何获得它的句柄？句柄是固定的吗？仅仅用活动窗口去取句柄会不会有问题？[/quote]  也可以根据窗口名，FindWindow[/quote] 感谢。再追问一下，findwindow这个函数传入的标题名称必须完全匹配。有没有方法只匹配一部分？比如我要屏蔽的报错窗口标题都是（unlha32。。。。）开头。


Question: C语言

可用分和技术分是两码事，可用分只能每天回帖一次拿10分，帖子的评分是增加的技术分，也就是版块等级，说实话，那个一点意义也没有，因为部分会员是CSDN内部人员，每天有固定的技术分增长点数的（数据库里直接刷）

const long long int MOD =100000000LL; long long int a[40]={1LL};  int main() {     int l=1;     for(int i=2;i<=100;i++){         long long int cy=0LL;         for(int j=0;j<l;j++){             cy +=a[j]*(long long int)i;             a[j] =cy%MOD;             cy  /=MOD;         }         if(cy) a[l++]=cy;     }     printf("%lld",a[l-1]);     for(int i=l-2;i>=0;i--) printf("%08lld",a[i]);     puts("");     return 0; }

引用 6 楼 cfjtaishan 的回复:[quote=引用 2 楼 v1eejing 的回复:] [quote=引用 楼主 ljtyllr001 的回复:] 100的阶乘怎么写 楼主，我写给你，你把分给我（我的分快用完了）：  （1）如果用常规的数据类型无法存储，用数组来相乘  （2）100的阶乘大概有160多位，所以先建立一个170个元素的整型数组； 0 0 0 0 0 .............................................1 先把这个数组全部清零，然后把末位置为1；  是因为准备从后往前乘数，依此乘1，2，3，4，5，一直到100. ...  但是每一次乘以一个数，都要把这170个元素都乘以一遍； 原因是： 假如从计算结果中间来看； 有这样一种情况： 00000000000000000000000000000  ~~~~ 1 2 0 这个结果是5！，假如再乘以6呢，就相当于把每一位都乘以6  这里就出现进位问题，有三句经典代码： a[n]=a[n]*k+Tp;   //k依次为1，2，3，4，5，Tp是进位值，初始化的时候为0； Tp=a[n]/10;  //得到进位，如果所在元素不满10，就没有进位，得到0； a[n]=a[n]%10;  //同理，如果该元素不满10，就还是原值，如果超过10，就只能得到余数， __________________________ 这是一个思路，具体可以自己修改，但是得到正确结果是没有问题 的； ———————————————— [code=c#]include <iostream> #include <cmath> using namespace std; int main() { 	int Tp=0,n,k; 	int a[170]; //定义170个元素的数组; 	 	for(n=0;n<170;n++)//数组全部置0; 	a[n]=0; 	 	a[169]=1;//末尾置1，准备乘2； 	 	for(k=1;k<=100;k++) //外层循环，100的阶乘； 					  //外层循环的数可以改写，比如写成5进行验证;     	for(n=169;n>=0;n--)//内层循环，每乘一个数需要乘170次；     		{     			a[n]=a[n]*k+Tp;     			Tp=a[n]/10;//得到进位值Tp;     			a[n]=a[n]%10;   			     		}     for(n=0;n<170;n++) //输出结果；     	cout<<a[n];      return 0; } [/code]  [/quote] +++，验证过了；不错哦；理解起来还不算难；赞一个~[/quote] 那是当然，我的想法就是编程平民化，不要搞高大上的术语，只要识字就能看的懂什么意思。所有的思维，一通俗化就变的很简单，问题是总有一波人要把简单的问题复杂化。但是我的分呢？？？

const int MOD =10000; int a[40]={1};  int main() {     int l=1;     for(int i=2;i<=100;i++){         int cy=0;         for(int j=0;j<l;j++){             cy +=a[j]*i;             a[j] =cy%MOD;             cy  /=MOD;         }         if(cy) a[l++]=cy;     }     printf("%d",a[l-1]);     for(int i=l-2;i>=0;i--) printf("%04d",a[i]);     puts("");     return 0; }

引用 7 楼 v1eejing 的回复:[quote=引用 6 楼 cfjtaishan 的回复:] [quote=引用 2 楼 v1eejing 的回复:] [quote=引用 楼主 ljtyllr001 的回复:] 100的阶乘怎么写 楼主，我写给你，你把分给我（我的分快用完了）：  （1）如果用常规的数据类型无法存储，用数组来相乘  （2）100的阶乘大概有160多位，所以先建立一个170个元素的整型数组； 0 0 0 0 0 .............................................1 先把这个数组全部清零，然后把末位置为1；  是因为准备从后往前乘数，依此乘1，2，3，4，5，一直到100. ...  但是每一次乘以一个数，都要把这170个元素都乘以一遍； 原因是： 假如从计算结果中间来看； 有这样一种情况： 00000000000000000000000000000  ~~~~ 1 2 0 这个结果是5！，假如再乘以6呢，就相当于把每一位都乘以6  这里就出现进位问题，有三句经典代码： a[n]=a[n]*k+Tp;   //k依次为1，2，3，4，5，Tp是进位值，初始化的时候为0； Tp=a[n]/10;  //得到进位，如果所在元素不满10，就没有进位，得到0； a[n]=a[n]%10;  //同理，如果该元素不满10，就还是原值，如果超过10，就只能得到余数， __________________________ 这是一个思路，具体可以自己修改，但是得到正确结果是没有问题 的； ———————————————— [code=c#]include <iostream> #include <cmath> using namespace std; int main() { 	int Tp=0,n,k; 	int a[170]; //定义170个元素的数组; 	 	for(n=0;n<170;n++)//数组全部置0; 	a[n]=0; 	 	a[169]=1;//末尾置1，准备乘2； 	 	for(k=1;k<=100;k++) //外层循环，100的阶乘； 					  //外层循环的数可以改写，比如写成5进行验证;     	for(n=169;n>=0;n--)//内层循环，每乘一个数需要乘170次；     		{     			a[n]=a[n]*k+Tp;     			Tp=a[n]/10;//得到进位值Tp;     			a[n]=a[n]%10;   			     		}     for(n=0;n<170;n++) //输出结果；     	cout<<a[n];      return 0; } [/code]  [/quote] +++，验证过了；不错哦；理解起来还不算难；赞一个~[/quote] 那是当然，我的想法就是编程平民化，不要搞高大上的术语，只要识字就能看的懂什么意思。所有的思维，一通俗化就变的很简单，问题是总有一波人要把简单的问题复杂化。但是我的分呢？？？[/quote] 赞

引用 2 楼 v1eejing 的回复:[quote=引用 楼主 ljtyllr001 的回复:] 100的阶乘怎么写 楼主，我写给你，你把分给我（我的分快用完了）：  （1）如果用常规的数据类型无法存储，用数组来相乘  （2）100的阶乘大概有160多位，所以先建立一个170个元素的整型数组； 0 0 0 0 0 .............................................1 先把这个数组全部清零，然后把末位置为1；  是因为准备从后往前乘数，依此乘1，2，3，4，5，一直到100. ...  但是每一次乘以一个数，都要把这170个元素都乘以一遍； 原因是： 假如从计算结果中间来看； 有这样一种情况： 00000000000000000000000000000  ~~~~ 1 2 0 这个结果是5！，假如再乘以6呢，就相当于把每一位都乘以6  这里就出现进位问题，有三句经典代码： a[n]=a[n]*k+Tp;   //k依次为1，2，3，4，5，Tp是进位值，初始化的时候为0； Tp=a[n]/10;  //得到进位，如果所在元素不满10，就没有进位，得到0； a[n]=a[n]%10;  //同理，如果该元素不满10，就还是原值，如果超过10，就只能得到余数， __________________________ 这是一个思路，具体可以自己修改，但是得到正确结果是没有问题 的； ———————————————— [code=c#]include <iostream> #include <cmath> using namespace std; int main() { 	int Tp=0,n,k; 	int a[170]; //定义170个元素的数组; 	 	for(n=0;n<170;n++)//数组全部置0; 	a[n]=0; 	 	a[169]=1;//末尾置1，准备乘2； 	 	for(k=1;k<=100;k++) //外层循环，100的阶乘； 					  //外层循环的数可以改写，比如写成5进行验证;     	for(n=169;n>=0;n--)//内层循环，每乘一个数需要乘170次；     		{     			a[n]=a[n]*k+Tp;     			Tp=a[n]/10;//得到进位值Tp;     			a[n]=a[n]%10;   			     		}     for(n=0;n<170;n++) //输出结果；     	cout<<a[n];      return 0; } [/code]  [/quote] +++，验证过了；不错哦；理解起来还不算难；赞一个~

小白们难道都不会小学三年级乘法竖式吗？

引用 4 楼 赵4老师的回复:小白们难道都不会小学三年级乘法竖式吗？ 让老师见笑了

引用 2楼胖熊二 的回复:[quote=引用 楼主 ljtyllr001 的回复:] 100的阶乘怎么写 楼主，我写给你，你把分给我（我的分快用完了）：  （1）如果用常规的数据类型无法存储，用数组来相乘  （2）100的阶乘大概有160多位，所以先建立一个170个元素的整型数组； 0 0 0 0 0 .............................................1 先把这个数组全部清零，然后把末位置为1；  是因为准备从后往前乘数，依此乘1，2，3，4，5，一直到100. ...  但是每一次乘以一个数，都要把这170个元素都乘以一遍； 原因是： 假如从计算结果中间来看； 有这样一种情况： 00000000000000000000000000000  ~~~~ 1 2 0 这个结果是5！，假如再乘以6呢，就相当于把每一位都乘以6  这里就出现进位问题，有三句经典代码： a[n]=a[n]*k+Tp;   //k依次为1，2，3，4，5，Tp是进位值，初始化的时候为0； Tp=a[n]/10;  //得到进位，如果所在元素不满10，就没有进位，得到0； a[n]=a[n]%10;  //同理，如果该元素不满10，就还是原值，如果超过10，就只能得到余数， __________________________ 这是一个思路，具体可以自己修改，但是得到正确结果是没有问题 的； ———————————————— [code=c#]include <iostream> #include <cmath> using namespace std; int main() { 	int Tp=0,n,k; 	int a[170]; //定义170个元素的数组; 	 	for(n=0;n<170;n++)//数组全部置0; 	a[n]=0; 	 	a[169]=1;//末尾置1，准备乘2； 	 	for(k=1;k<=100;k++) //外层循环，100的阶乘； 					  //外层循环的数可以改写，比如写成5进行验证;     	for(n=169;n>=0;n--)//内层循环，每乘一个数需要乘170次；     		{     			a[n]=a[n]*k+Tp;     			Tp=a[n]/10;//得到进位值Tp;     			a[n]=a[n]%10;   			     		}     for(n=0;n<170;n++) //输出结果；     	cout<<a[n];      return 0; } [/code]  [/quote]人家一个小白，你是说的多么复杂

引用 楼主 ljtyllr001 的回复:100的阶乘怎么写 楼主，我写给你，你把分给我（我的分快用完了）：  （1）如果用常规的数据类型无法存储，用数组来相乘  （2）100的阶乘大概有160多位，所以先建立一个170个元素的整型数组； 0 0 0 0 0 .............................................1 先把这个数组全部清零，然后把末位置为1；  是因为准备从后往前乘数，依此乘1，2，3，4，5，一直到100. ...  但是每一次乘以一个数，都要把这170个元素都乘以一遍； 原因是： 假如从计算结果中间来看； 有这样一种情况： 00000000000000000000000000000  ~~~~ 1 2 0 这个结果是5！，假如再乘以6呢，就相当于把每一位都乘以6  这里就出现进位问题，有三句经典代码： a[n]=a[n]*k+Tp;   //k依次为1，2，3，4，5，Tp是进位值，初始化的时候为0； Tp=a[n]/10;  //得到进位，如果所在元素不满10，就没有进位，得到0； a[n]=a[n]%10;  //同理，如果该元素不满10，就还是原值，如果超过10，就只能得到余数， __________________________ 这是一个思路，具体可以自己修改，但是得到正确结果是没有问题 的； ———————————————— [code=c#]include <iostream> #include <cmath> using namespace std; int main() { 	int Tp=0,n,k; 	int a[170]; //定义170个元素的数组; 	 	for(n=0;n<170;n++)//数组全部置0; 	a[n]=0; 	 	a[169]=1;//末尾置1，准备乘2； 	 	for(k=1;k<=100;k++) //外层循环，100的阶乘； 					  //外层循环的数可以改写，比如写成5进行验证;     	for(n=169;n>=0;n--)//内层循环，每乘一个数需要乘170次；     		{     			a[n]=a[n]*k+Tp;     			Tp=a[n]/10;//得到进位值Tp;     			a[n]=a[n]%10;   			     		}     for(n=0;n<170;n++) //输出结果；     	cout<<a[n];      return 0; } [/code]

100阶乘后的结果太大，用double保存吧  如下；   int main() { 	double num = 1.0; 	for(int i = 1; i < 101; ++i) 		num *= (double)i; 	printf("%g", num); 	return 0; }


Question: 问

合法字符为 字母,数字,下划线, 不能以数字开头, 不能用保留字, 大小写敏感

注意是大写，C中的关键字是for


Question: 浮点数float的范围分析有疑惑

问题在于阶码不能全为1, 全为1用于特殊用途, 尾数0则为INF, 不为0则为NAN float 最大时阶码为127, 尾数全1, 应该就是2^127*(二进制小数)(1.1111...(小数点后23位1) 略接近于2^128

我已经理解了，具体分析在博客：http://blog.csdn.net/changlishuang/article/details/49853327  简单描述原因就是：根据IEEE754规定，第一种是规约数，第二种是非规约数       规约数尾数前面默认加1，非规约数尾数前面默认加0      而且指数为1-254，不是0-255，实际指数就是-126-127      在而且非规约数的指数偏移值比规约数小1；规约数最小有偏移指数1，对应实际值-126；那么非规约数最小有偏移指数为0，对应实际值-126        float的最大绝对值:0111  1111  0111  1111 1111 1111 1111  1111 (规约数)       即              + (1.1..1)  *      (2^127)    ≈   (2-2^-23) * 2^128   ≈    3.4 * 10^38        float的最小绝对值:0000  0000  0000  0000  0000 0000 0000 0001 (非规约数)       即              +(0.0...1)  *      (2^-126）≈   (1*2^-23) * 2^-126 = 2 ^-149  ≈  1.4 * 10^-45  其实最终的原因都是归于IEEE754规定设定来的。

1) 指数部分 FF 被用来表示 Infinity （无穷大）。正常数字指数部分只到 FE 。  2) 指数部分 00 用来 0.0， -0.0 和 denormalized number 。denormalized number 表示方法与其它正常数字不同，即它开始的一位并不是一个隐含的1，而是0.  +(0.0..01)  *    (2^-127)   ≈    1  *  (2^-149)

最大绝对值肯定不会后面全是1啊，全是1指数就是负数了

测试一下  #include<iostream> #include <limits> using namespace std;  int main() {     cout<<endl<<endl;     cout<<"float:  \t"<<sizeof(float)<<"  字节";     cout<<"\t值 域   +-  "<<(numeric_limits<float>::max)();     cout<<"\t……    " <<(numeric_limits<float>::min)()<<endl;     cout<<"double: \t"<<sizeof(double)<<"  字节";     cout<<"\t值 域   +-  "<<(numeric_limits<double>::max)();     cout<<"\t……    "<<(numeric_limits<double>::min)()<<endl;     cout<<"long double:\t"<<sizeof(long double)<<"  字节";     cout<<"\t值 域   +-  "<<(numeric_limits<long double>::max)();     cout<<"\t……    "<<(numeric_limits<long double>::min)()<<endl;     return 0; }


Question: 求大神为我讲解

下一行比上一行少输出一个空格，多输出两个*，就行成了这个图形哈        *      ***     *****    *******   *********  *********** *************


Question: 麻烦大神们看一下，很简单的一道题。代码正确，但是输入好像有问题

我还一本正经的找了半天资料，真无语，多谢

scanf("%d-%month-%day",&year,&month,&day); 这句应该改成 scanf("%d-%d-%d",&year,&month,&day); 吧


Question: 如何使用内嵌汇编获得斐波那契数列

#include <stdio.h> #include <stdlib.h>  //int fib(int n){ //  if(n==0) return 0; //  if(n==1) return 1; //  return fib(n-2)+fib(n-1); //}  int main(int argc, char *argv[]) {     int n, r=0;     if (argc < 2) {         printf("Usage: %s number(<40)\n", argv[0]);         return -1;     }     n = atoi(argv[1]); //  r=fib(n);     __asm {      // FILL YOUR CODE HERE     // evaluate r = f(n)  //r=fib(n);            mov         ecx,n            push        ecx            call        fib            add         esp,4            mov         r,eax            jmp         lbEnd fib://int fib(int n){            push        ebp            mov         ebp,esp            sub         esp,0x40            push        ebx            push        esi            push        edi //        if(n==0) return 0;            cmp         dword ptr [ebp+8],0            jne         step2            xor         eax,eax            jmp         endfunc //        if(n==1) return 1; step2:     cmp         dword ptr [ebp+8],1            jne         step3            mov         eax,1            jmp         endfunc //        return fib(n-2)+fib(n-1); step3:     mov         eax,dword ptr [ebp+8]            sub         eax,2            push        eax            call        fib            add         esp,4            mov         esi,eax            mov         ecx,dword ptr [ebp+8]            sub         ecx,1            push        ecx            call        fib            add         esp,4            add         eax,esi //    } endfunc:   pop         edi            pop         esi            pop         ebx            mov         esp,ebp            pop         ebp            ret lbEnd:     }     printf("fib(%d) = %d\n", n, r);     return 0; }

VC调试时按Alt+8打开汇编窗口看每句C对应的汇编。

#include <stdio.h> #include <stdlib.h>  int fib(int n){     if(n==0) return 0;     if(n==1) return 1;     return fib(n-2)+fib(n-1); }  int main(int argc, char *argv[]) {     int n, r=0;     if (argc < 2) {         printf("Usage: %s number(<40)\n", argv[0]);         return -1;     }     n = atoi(argv[1]);     r=fib(n);     __asm {      // FILL YOUR CODE HERE     // evaluate r = f(n)         nop     }     printf("fib(%d) = %d\n", n, r);     return 0; } 1:    #include <stdio.h> 2:    #include <stdlib.h> 3: 4:    int fib(int n){ 00401020   push        ebp 00401021   mov         ebp,esp 00401023   sub         esp,40h 00401026   push        ebx 00401027   push        esi 00401028   push        edi 5:        if(n==0) return 0; 00401029   cmp         dword ptr [ebp+8],0 0040102D   jne         fib+13h (00401033) 0040102F   xor         eax,eax 00401031   jmp         fib+42h (00401062) 6:        if(n==1) return 1; 00401033   cmp         dword ptr [ebp+8],1 00401037   jne         fib+20h (00401040) 00401039   mov         eax,1 0040103E   jmp         fib+42h (00401062) 7:        return fib(n-2)+fib(n-1); 00401040   mov         eax,dword ptr [ebp+8] 00401043   sub         eax,2 00401046   push        eax 00401047   call        @ILT+5(fib) (0040100a) 0040104C   add         esp,4 0040104F   mov         esi,eax 00401051   mov         ecx,dword ptr [ebp+8] 00401054   sub         ecx,1 00401057   push        ecx 00401058   call        @ILT+5(fib) (0040100a) 0040105D   add         esp,4 00401060   add         eax,esi 8:    } 00401062   pop         edi 00401063   pop         esi 00401064   pop         ebx 00401065   mov         esp,ebp 00401067   pop         ebp 00401068   ret 9: 10:   int main(int argc, char *argv[]) 11:   { 00401080   push        ebp 00401081   mov         ebp,esp 00401083   sub         esp,48h 00401086   push        ebx 00401087   push        esi 00401088   push        edi 12:       int n, r=0; 00401089   mov         dword ptr [ebp-8],0 13:       if (argc < 2) { 00401090   cmp         dword ptr [ebp+8],2 00401094   jge         main+2Fh (004010af) 14:           printf("Usage: %s number(<40)\n", argv[0]); 00401096   mov         eax,dword ptr [ebp+0Ch] 00401099   mov         ecx,dword ptr [eax] 0040109B   push        ecx 0040109C   push        offset string "Usage: %s number(<40)\n" (0041302c) 004010A1   call        dword ptr [__imp__printf (004150a8)] 004010A7   add         esp,8 15:           return -1; 004010AA   or          eax,0FFh 004010AD   jmp         main+6Ah (004010ea) 16:       } 17:       n = atoi(argv[1]); 004010AF   mov         edx,dword ptr [ebp+0Ch] 004010B2   mov         eax,dword ptr [edx+4] 004010B5   push        eax 004010B6   call        dword ptr [__imp__atoi (004150a4)] 004010BC   add         esp,4 004010BF   mov         dword ptr [ebp-4],eax 18:       r=fib(n); 004010C2   mov         ecx,dword ptr [ebp-4] 004010C5   push        ecx 004010C6   call        @ILT+5(fib) (0040100a) 004010CB   add         esp,4 004010CE   mov         dword ptr [ebp-8],eax 19:       __asm { 20: 21:       // FILL YOUR CODE HERE 22:       // evaluate r = f(n) 23:           nop 004010D1   nop 24:       } 25:       printf("fib(%d) = %d\n", n, r); 004010D2   mov         edx,dword ptr [ebp-8] 004010D5   push        edx 004010D6   mov         eax,dword ptr [ebp-4] 004010D9   push        eax 004010DA   push        offset string "fib(%d) = %d\n" (0041301c) 004010DF   call        dword ptr [__imp__printf (004150a8)] 004010E5   add         esp,0Ch 26:       return 0; 004010E8   xor         eax,eax 27:   } 004010EA   pop         edi 004010EB   pop         esi 004010EC   pop         ebx 004010ED   mov         esp,ebp 004010EF   pop         ebp 004010F0   ret

啊，这两条：     jge __start     jmp __exit 可以改成：     jl __exit  思维短路了。

这个很容易用非递归实现：  int fib(int n) {   __asm{     //push ebx  //     //push esi  // not necessary for cl and icl compilers     mov ecx,n     mov eax,0     mov ebx,1     mov edx,3     cmp ecx,eax     jle __exit     inc eax     cmp ecx,edx     jge __start     jmp __exit   __start:     cmp edx,ecx     jg __done     mov esi,eax     mov eax,ebx     add esi,ebx     inc edx     mov ebx,esi     jmp __start   __done:     mov eax,esi   __exit:     //pop esi     //pop ebx   } }

引用 2 楼 user-4 的回复:很明显你这个是递归，递归很深，栈空间溢出了请问下怎么解决呢？我不太会用汇编

我不太会用汇编 应该怎么使用呢？上面的汇编代码是我根据C反汇编写上去的

fib是个函数, 没看到ret在那里

很明显你这个是递归，递归很深，栈空间溢出了

我用的VS反汇编 再放到__asm里面 就不行呢


Question: 求知一下：C语言中奇怪的interrupt（），

bc++3.1 帮助里面对每个函数都有一小段能拷贝出来运行看效果的例子程序。非常适合初学C语言。相比较而言VC带的帮助MSDN就没有。http://download.csdn.net/source/2805028  在DosBox中使用TurboDebug调试以下代码：  /***NOTE:     This is an interrupt service routine.  You can NOT compile this     program with Test Stack Overflow turned on and get an executable     file which will operate correctly. */  #include <stdio.h> #include <dos.h> #include <conio.h>  #define INTR 0X1C    /* The clock tick interrupt */  #ifdef __cplusplus     #define __CPPARGS ... #else     #define __CPPARGS #endif  void interrupt ( *oldhandler)(__CPPARGS);  int count=0;  void interrupt handler(__CPPARGS) { /* increase the global counter */    count++;  /* call the old routine */    oldhandler(); }  int main(void) { /* save the old interrupt vector */    oldhandler = getvect(INTR);  /* install the new interrupt handler */    setvect(INTR, handler);  /* loop until the counter exceeds 20 */    while (count < 20)       printf("count is %d\n",count);  /* reset the old interrupt handler */    setvect(INTR, oldhandler);     return 0; }

引用 1 楼 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]   老师，我下午翻遍了资料，终于找到这个interrupt的说明，是在《Turbo C2.0实用大全》这本书中看到的，它的意思是：这个interrupt只有TURBO C这个古董才用的，但是我还是很有兴趣，书上写的内容不多，我还是没看明白，想请教一下：    我想问的是这个函数到底在做什么？返回的又是什么？？

主要是不知道那个interrupt是什么类型；希望知道的能解释一下

引用 4 楼 user-2 的回复:[quote=引用 3 楼 v1eejing 的回复:] [quote=引用 1 楼 zhao4zhong1 的回复:]  [/code]老师，你回复的是复杂声明，这个有了解； 刚才又去网上看了一下，大概意思是说BIOS的时钟问题，老师能不能通俗的讲下BIOS时钟中断大概是什么意思；[/quote]  是这个吗；http://wenku.baidu.com/link?url=1QMslMwIxRcccJBV1mBaAk5A4ZEY4_84yVsK7sgEu-hxPay5XG0M62PwFxqndFOB9RBQwqKabfhjFlId028Xe44cxLhg62JiCZOMzx8tPXm[/quote]  这个介绍了1A，有没有介绍1CH的？？我刚才查了一下，也看到了这篇，就是没找到关于1CH的说明；

引用 3 楼 v1eejing 的回复:[quote=引用 1 楼 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] 老师，你回复的是复杂声明，这个有了解； 刚才又去网上看了一下，大概意思是说BIOS的时钟问题，老师能不能通俗的讲下BIOS时钟中断大概是什么意思；[/quote]  是这个吗；http://wenku.baidu.com/link?url=1QMslMwIxRcccJBV1mBaAk5A4ZEY4_84yVsK7sgEu-hxPay5XG0M62PwFxqndFOB9RBQwqKabfhjFlId028Xe44cxLhg62JiCZOMzx8tPXm

引用 1 楼 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] 老师，你回复的是复杂声明，这个有了解； 刚才又去网上看了一下，大概意思是说BIOS的时钟问题，老师能不能通俗的讲下BIOS时钟中断大概是什么意思；


Question: 宏调用实现小写转大写的问题

VC编译选项加/EP /P（项目、属性、配置属性、C/C++、预处理器、预处理到文件：是，预处理取消显示行号：是），重新编译，查看宏展开后对应的.i文件。gcc加-E http://bbs.csdn.net/topics/391003898

宏展开后是这个样子：buf2[i] = ((*p++)>='a'&&(*p++)<='z'?(*p++)+('A'-'a'):(*p++));

用内联函数吧，用宏很容易出错，你宏中的每一处c都会换成*p++，执行时p会执行多次p++操作，估计并不是楼主想要的