Question: 新手求助

嗯嗯嗯，是有多个文件有main函数,已经不报错了

是不是在一个项目里多个文件都是main函数？  还有scanf(里面\n去掉)

引用 1 楼 ?Victor.??的回复:https://blog.csdn.net/qq_45861670/article/details/104015023  也许对你有帮助  没帮助的话建议贴一下代码 就这个，我看着也没错啊

引用 1 楼 ?Victor.??的回复:https://blog.csdn.net/qq_45861670/article/details/104015023  也许对你有帮助  没帮助的话建议贴一下代码 #include <stdio.h> void PrintN(int N); int main() { int N; scanf("%d\n",&N) ; PrintN(N); return 0; } void PrintN(int N) {int i; for(i=1;i<=N;i++) {printf("%d\n",i); } return; }

按你的代码我试了一下，我编译没问题但是跑不出结果不知道为啥


Question: 大佬解决一问题呗

引用 1 楼 lin5161678的回复:洗牌  4个一组 完事 大佬，能教教吗

题目规则没有写，不知道是否有这个需求，只能说出题太随意了

引用 2 楼 ggglivw 的回复:男性和女性能分配到一个房子吗？感觉出题的人不严谨哦 的确是个问题 得男女分开 要么从输入限制男女人数都是 4的倍数 要么不是平均4人

男性和女性能分配到一个房子吗？感觉出题的人不严谨

洗牌  4个一组 完事

引用 6 楼 千梦一生 的回复:其实吧，这玩意儿，可能就是出题人的意思。啥意思呢？就是让你自己去判断一些情况，就比如男女自然地在寻常的普遍的观念中住一个宿舍是要不得的。不是一个班的同学，如果可以的情况下，自然也是能分开就分开的，是吧。 明显是一个开放性的问题。 想的越全面，自然越好，分数都应该给你打高一点  话不能这么说，那么策划存在的意义是啥，是不是说我要一个魔兽世界，剩下的就全是程序员的问题了？

引用 2 楼 ggglivw 的回复:男性和女性能分配到一个房子吗？感觉出题的人不严谨 这个我喜欢


Question: c++  "%.3f%c%.3f=%.3f" 提示表达式必须含类类型 怎么解决

引用 1 楼 user-1 的回复：最后一行print的参数错误， print(“%.3f%c%.3f=%.3f, data1, op, data2, r);//注意格式字符串之后是逗号，不是点号好了 谢谢🙏

现在有提示这个


Question: 能不能帮我解释一下什么意思啊

引用 5 楼 weixin_46294972的回复:[quote=引用 4 楼 老英捉小奇的回复:][quote=引用 2 楼 weixin_46294972的回复:][quote=引用 1 楼 老英捉小奇的回复:]就是3位的意思，比如你输了12345,xyz那么输出a就是123，c就是4 那xyz是什么意思啊[/quote] 没啥意思啊，就是输入的时候，a是整型的，并且要求截取3位，那么123就赋值给了a，c是字符，接下来不管输入多少，就只是把4当做字符赋值给了c[/quote] 那c前面的3是什么意思啊[/quote] 没啥实质性的意义，不用管他，打个次方，如果scanf输入的是%c，那么随便输入一个按回车就会输出，如果scanf输入用的是%3c那么你随便输入一个再按回车是不会出结果的，这时候你按的回车相当于一个字符，还要再按回车才会有结果，你拿电脑试试就知道了

引用 4 楼 老英捉小奇的回复:[quote=引用 2 楼 weixin_46294972的回复:][quote=引用 1 楼 老英捉小奇的回复:]就是3位的意思，比如你输了12345,xyz那么输出a就是123，c就是4 那xyz是什么意思啊[/quote] 没啥意思啊，就是输入的时候，a是整型的，并且要求截取3位，那么123就赋值给了a，c是字符，接下来不管输入多少，就只是把4当做字符赋值给了c[/quote] 那c前面的3是什么意思啊

引用 2 楼 weixin_46294972的回复:[quote=引用 1 楼 老英捉小奇的回复:]就是3位的意思，比如你输了12345,xyz那么输出a就是123，c就是4 那xyz是什么意思啊[/quote] 没啥意思啊，就是输入的时候，a是整型的，并且要求截取3位，那么123就赋值给了a，c是字符，接下来不管输入多少，就只是把4当做字符赋值给了c

引用 1 楼 老英捉小奇的回复:就是3位的意思，比如你输了12345,xyz那么输出a就是123，c就是4 那xyz是什么意思啊

就是3位的意思，比如你输了12345,xyz那么输出a就是123，c就是4


Question: c语言

引用 5 楼 北极光~ 的回复:[quote=引用 4 楼 5250 的回复:] [quote=引用 2 楼 qq_45916742 的回复:] [quote=引用 1 楼 user-3的回复:]建议你用gcc， windows的话，装个MINGW，迷你型的虚拟机 很轻便 Codeblocks咋样？？[/quote]  挺好 我们刚开始学的时候 都用那个[/quote]初学还是老手，应该是新手，老手不会问这种无聊的问题。 初学用Dev-c++挺好的，地带MinGW，不需要配置太多，直接选择中文版，没有任何问题，还推荐VScode，只不过配置比较麻烦，配置好了比IDE还要好！[/quote]自带，不是地带

引用 4 楼 5250 的回复:[quote=引用 2 楼 qq_45916742 的回复:] [quote=引用 1 楼 user-3的回复:]建议你用gcc， windows的话，装个MINGW，迷你型的虚拟机 很轻便 Codeblocks咋样？？[/quote]  挺好 我们刚开始学的时候 都用那个[/quote]初学还是老手，应该是新手，老手不会问这种无聊的问题。 初学用Dev-c++挺好的，地带MinGW，不需要配置太多，直接选择中文版，没有任何问题，还推荐VScode，只不过配置比较麻烦，配置好了比IDE还要好！

引用 2 楼 qq_45916742 的回复:[quote=引用 1 楼 user-3的回复:]建议你用gcc， windows的话，装个MINGW，迷你型的虚拟机 很轻便 Codeblocks咋样？？[/quote]  挺好 我们刚开始学的时候 都用那个

引用 2 楼 qq_45916742 的回复：[quote=引用 1 楼 user-3的回复:]建议你用gcc， windows的话，装个MINGW，迷你型的虚拟机 很轻便 Codeblocks咋样？？[/quote]没用过哦，这是一个集成开发环境，他实际上也是用第三方编译器，比如gcc和vc

引用 1 楼 user-3的回复:建议你用gcc， windows的话，装个MINGW，迷你型的虚拟机 很轻便 Codeblocks咋样？？

建议你用gcc， windows的话，装个MINGW，迷你型的虚拟机 很轻便


Question: 链表 尾插法 错误求解

同在复习链表，话说你用malloc动态分配内存的时候没有报空指针异常吗 有可能是malloc返回了一个空指针 你要不写个判断条件看看？


Question: 小白的疑问－为什么ShowListData函数中需要head=head－＞next，哪一步说明head==NULL？

引用 3 楼 一晴方觉夏已深的回复:[quote=引用 2 楼 山师19计算机小毛孩 的回复:] [quote=引用 1 楼 一晴方觉夏已深的回复:]你肯定得移动指针，才能遍历整个链表中的每个节点啊 当指针移动到了最后一个元素，打印以后指针再往后移动，最后一个节点的后继是NULL 我想问循环外那句[/quote]  因为这个链表是有头结点的，头结点是不储存数据的，所以得把指针移动到第一个节点再打印[/quote] 好的谢谢您嘞

引用 2 楼 山师19计算机小毛孩 的回复:[quote=引用 1 楼 一晴方觉夏已深的回复:]你肯定得移动指针，才能遍历整个链表中的每个节点啊 当指针移动到了最后一个元素，打印以后指针再往后移动，最后一个节点的后继是NULL 我想问循环外那句[/quote]  因为这个链表是有头结点的，头结点是不储存数据的，所以得把指针移动到第一个节点再打印

引用 1 楼 一晴方觉夏已深的回复:你肯定得移动指针，才能遍历整个链表中的每个节点啊 当指针移动到了最后一个元素，打印以后指针再往后移动，最后一个节点的后继是NULL 我想问循环外那句


Question: 可以把一个实数赋给整型变量吗

浮点数赋值给整型数据，可以认为是取整运算。

引用 3 楼 Mawkish_ 的回复:会自动四舍五入吗 不会  这种问题自己试试就知道了

会自动四舍五入吗

整形变量只会接收到实数的整数部分，你要全部赋值的话就赋给个float或者double

可以，变量的值为实数的整数部分


Question: 求助 PAT 乙级1045 测试点35过不了

引用 4 楼 939493 的回复:引用 3 楼 user-1 的回复：楼主你弄明白了没啊，我测试点3和5也通过不了，不知道哪里错了。。。通过了。 你想想看有没有那种可能就是它中间某个数刚好跟排序后的数相等  但是这个数并不是主元好的，我去试试，谢谢楼主~

楼主你弄明白了没啊，我测试点3和5也通过不了，不知道哪里错了。。。

想了好久没想明白

题目要求如下 著名的快速排序算法里有一个经典的划分过程：我们通常采用某种方法取一个元素作为主元，通过交换，把比主元小的元素放到它的左边，比主元大的元素放到它的右边。 给定划分后的 N 个互不相同的正整数的排列，请问有多少个元素可能是划分前选取的主元？  例如给定 $N = 5$, 排列是1、3、2、4、5。则：  1 的左边没有元素，右边的元素都比它大，所以它可能是主元； 尽管 3 的左边元素都比它小，但其右边的 2 比它小，所以它不能是主元； 尽管 2 的右边元素都比它大，但其左边的 3 比它大，所以它不能是主元； 类似原因，4 和 5 都可能是主元。 因此，有 3 个元素可能是主元。  输入格式： 输入在第 1 行中给出一个正整数 N（≤10 5  ）； 第 2 行是空格分隔的 N 个不同的正整数，每个数不超过 10 9  。  输出格式： 在第 1 行中输出有可能是主元的元素个数；在第 2 行中按递增顺序输出这些元素，其间以 1 个空格分隔，行首尾不得有多余空格。  输入样例： 5 1 3 2 4 5              输出样例： 3 1 4 5


Question: 交换函数问题

引用 4 楼 zedd3337502212 的回复:引用 3 楼 千梦一生 的回复:[quote=引用 2 楼 zedd3337502212 的回复:] [quote=引用 1 楼 早打大打打核战争 的回复:] D，A的p是野指针可是括号里不是对*p进行赋值了吗？还是说赋值的只是野指针的地址的值？ *p = *x意思是将指针x所指向的位置的int值，赋值给，指针p所指向的位置中。那么此时p所指向的位置是哪里呢？[/quote] 那么也就是说p指向的位置还是那个野指针的地址，只不过是那个地址所指向的int值被改变了[/quote]  p的值就是一个地址。p其实就是一个特殊的int（准确的说法说是int也不太好，准确的说法是4B的空间、或者8B），专门用来存储地址的int。   那么此时p所指向的位置是哪里呢？<=>这个p的值是哪儿的地址呢？不知道，可能是任何地方。 随便说一个，比如说 是0x12345678这里。那执行*p = 3；就是向0x12345678这里开始的int（指针的类型）长度（即：4B,也可能是8B）中把值写为3。

引用 3 楼 千梦一生 的回复:引用 2 楼 zedd3337502212 的回复:[quote=引用 1 楼 早打大打打核战争 的回复:] D，A的p是野指针可是括号里不是对*p进行赋值了吗？还是说赋值的只是野指针的地址的值？ *p = *x意思是将指针x所指向的位置的int值，赋值给，指针p所指向的位置中。那么此时p所指向的位置是哪里呢？[/quote] 那么也就是说p指向的位置还是那个野指针的地址，只不过是那个地址所指向的int值被改变了

引用 2 楼 zedd3337502212 的回复:引用 1 楼 早打大打打核战争 的回复:D，A的p是野指针可是括号里不是对*p进行赋值了吗？还是说赋值的只是野指针的地址的值？ *p = *x意思是将指针x所指向的位置的int值，赋值给，指针p所指向的位置中。那么此时p所指向的位置是哪里呢？

D，A的p是野指针


Question: 从1加到100的结果总不对

引用 3 楼 潇湘游子的回复:这错误就犯的低级了！你输出的数据都不指定，这是个位置的数据 是啊，好低级的错误

引用 2 楼 chxchxkkk的回复:printf("sum的值等于：%d\n", sum); 谢谢指正，我还是太粗心了

引用 1 楼 user-4的回复:输出代码错了，双引号把sum括起来了。 这种小错误实在是不应该

你的双引号把sum业扩进去了。所以输出的是一个随机值吧。注意检查一下你的printf

这错误就犯的低级了！你输出的数据都不指定，这是个位置的数据

printf("sum的值等于：%d\n", sum);

输出代码错了，双引号把sum括起来了。


Question: 求助大佬，测试点6一直过不了，恳求看一下代码

希望审核快点通过啊啊啊啊

好了，我知道了，是头文件的问题，给跪了

#include<stdio.h>改成#include <cstdio>


Question: C语言if判断

引用 1 楼 ?Victor.??的回复:if(leap)  即  if(leap != 0) 原来如此。。。

if(leap)  即  if(leap != 0)


Question: C语言编译出错

感觉这种字体好奇怪

引用 1 楼 真相重于对错的回复:注意拼写错误。。。。。 OK 谢谢😜

注意拼写错误。。。。。


Question: 求救急

引用 2 楼 GKatHere的回复:还用递归吗？ 解方程：v0 *t = 1/2 *g*t*t，就行了 用C语言编程，就是不知道怎么写

还用递归吗？ 解方程：v0 *t = 1/2 *g*t*t，就行了

能量守恒和加速度定律就可以算出来了？难道你还要推导过程？


Question: 将文件中的信息读入到单链表person中

#include <stdio.h>  void scanfCareer(struct career **person) { 	struct career tmp, *p, *pnew;  	FILE *fp; 	if ((fp=fopen("car.text","r"))==NULL) { 		printf("打开文件失败了……6666!\n"); 		exit(1); 	} 	pnew = (struct career *)malloc(sizeof(struct career)); 	if (!pnew) 		exit(1); 	while((fscanf(fp, "%s%s%s", pnew->c_num,pnew->c_nam,pnew->c_car))==3) { 		if (*person == NULL) { 			*person = pnew; 			pre = pnew; 		} else { 			pre->next = pnew; 			pre = pnew; 		} 		pnew = (struct career *)malloc(sizeof(struct career)); 		if (!pnew) 			exit(1); 	} 	free(pnew); 	pre->next = NULL; #if 0  	struct career *p ; 	struct career *mp; 	struct career *temp;  	FILE *fp; 	if ((fp=fopen("car.text","r"))==NULL) 	{ 		printf("打开文件失败了……6666!\n"); 		exit(1); 	}  	while((fscanf(fp,"%s%s%s",p->c_num,p->c_nam,p->c_car))==3) 	{ 		if(pool !=NULL) { 			mp=pool; 			pool=pool->next; 			count--; 		} 		//内存池为空时 		else 		{ 			mp=(struct career *)malloc(sizeof(struct career)); 			if (mp==NULL) 			{ 				printf("Failure 内存分配失败\n"); 				exit(1); 			} 		} 		mp=p;  		if (*person!=NULL) 		{  			temp=*person; 			*person=mp; 			mp->next =temp;  		} 		else 		{ 			*person =p; 			p->next =NULL; 		}    	} #endif 	fclose(fp);  }  int main {  	struct career *person=NULL; 	scanfCareer(&person); } 供参考～  你的p是野指针，怎么可以直接使用呢？


Question: 为什么字符指针地址传入printf函数后指针自动初始化为0？以至进入不了for循环。

引用 5 楼 egtre678 的回复:[quote=引用 4 楼 user-3 的回复:] s1没赋初始值，属于野指针，也就是垃圾内存信息，所以它的值是不确定的，可能是0，也可能能不是0，这取决于main函数栈当时的内存信息 而且指针和0不能这么比较，要用NULL来比较 for(; s1!=NULL;)  那为什么，另外NULL不是等于0吗？[/quote]  说实话我没明白你的意思，什么是“打印printf("%d",s1);指针不会被初始化为0” 另外，s1!=0和s1!=NULL是等价的。用for (;s1;)也没问题。

是不是因为不应该取地址啊？久了没用过了，我猜的 printf("%x",&s1); 改成 printf("%x",s1); 这个？

不同类型的指针不能用来比较，除非强行转换。 有些编译器可能s1!=0还不能编译通过。 NULL虽然值为0，但类型和意义不一样，NULL是空指针，也就是适用于各种指针类型，因为不管哪种指针类型都有空指针。 所以你这样比较属于未定义行为，你无法知晓编译器会运行出什么结果。 参考以下链接未定义行为第7条 https://m.jb51.net/article/105305.htm

引用 4 楼 user-3 的回复:s1没赋初始值，属于野指针，也就是垃圾内存信息，所以它的值是不确定的，可能是0，也可能能不是0，这取决于main函数栈当时的内存信息 而且指针和0不能这么比较，要用NULL来比较 for(; s1!=NULL;)  那为什么打印printf("%d",s1);指针不会被初始化为0，另外NULL不是等于0吗？

引用 1 楼 均陵鼠侠 的回复:for(;s1!=0;)   你怎么知道 第一次进入for时，s1的值非0  因为调试过，所以打印&s1时进入for的值是0。

for(;s1!=0;)   你怎么知道 第一次进入for时，s1的值非0


Question: 怎么才算死循环呢？

整形数据的大小也是有范围的，超出了范围就结束了

k 是int类型 这个循环最后会导致 k 溢出 有符号类型溢出是未定义行为  结果没意义 具体在这里 可能死循环可能不会 出题人水平太低胡乱扯的 不用管 如果k是无符号类型这题目就没什么问题

for(k = 1; k--; k++)printf("%d ", k); 这样应该能死掉

注意k是有范围的：-2,147,483,648~2,147,483,647。因此k++总会变成0.

0x00000001 0x00000002 ... ... 0xFFFFFFFF 0x00000000  GAME OVER !!

死循环就是程序一直周期性的运行某段指令，永远不会停止，图中所给语句不算是死循环，因为判断条件k是int类型，k不会一直增大，当k超过了它的最大表示边界，会从另一个负边界开始增长，然后当增长到0的时候，结束循环


Question: 排序

老铁，今天好不容易休息所以没看帖子。 我刚才试了一下：把M-1改成n-1,然后穿n的时候传5（数组元素个数），然后结果是对的。 解释：for循环一边之后，最小的已经在前面了，所以你a+1，但是你下次再进入pxfunc2中的循环再用M-1作为下标就越界了（因为这时候你的数组元素个数相当于减少了1，因为你a+1了嘛。you know?）

引用 1 楼 脏不张的回复:[quote=引用 楼主 qq_45883336的回复:]升序。 为啥不能达到预期效果？俺小白。 #include <stdio.h> #define M 5 int pxfunc2 (int a[],int n) { 	if(n==0) 		return 0;  	int j,m; 	for(j=M-1;j>0;j--) 		if(a[j]<a[j-1])  		{ 			m=a[j]	; 			a[j]=a[j-1]; 			a[j-1]=m; 		} 	pxfunc2(a+1,n-1);//每运行一次把最小的值放在数组的最前面  } int main() { 	int a[M]={3,1,2,9,8}; 	pxfunc2(a,3); 	for(int q=0;q<M;q++) 		printf("%2d",*(a+q)); } n是数组元素数量吗，pxfunc2中M换成n试下。还有main中n为啥传了个3[/quote] 3到0是四次，五个数只需要递归四次就行。俺是这样想的

n应该是数组的长度吧，传个3是想把数组第一个元素的值传进去？

引用 楼主 qq_45883336的回复:升序。 为啥不能达到预期效果？俺小白。 #include <stdio.h> #define M 5 int pxfunc2 (int a[],int n) { 	if(n==0) 		return 0;  	int j,m; 	for(j=M-1;j>0;j--) 		if(a[j]<a[j-1])  		{ 			m=a[j]	; 			a[j]=a[j-1]; 			a[j-1]=m; 		} 	pxfunc2(a+1,n-1);//每运行一次把最小的值放在数组的最前面  } int main() { 	int a[M]={3,1,2,9,8}; 	pxfunc2(a,3); 	for(int q=0;q<M;q++) 		printf("%2d",*(a+q)); } n是数组元素数量吗，pxfunc2中M换成n试下。还有main中n为啥传了个3


Question: 求大神解答一个小问题

sort()函数需要比较两个char 型变量的大小怎么办？

#include<stdio.h> #include<stdlib.h> #include<string.h>    struct Member { 	char number[10]; 	char name[10]; 	char gender[10]; 	int birth; 	char yuanxi[10]; 	char zhiwu[10]; 	int sushehao; 	int phonenumber;  }; struct Member lib[10];  int num=0;  void jiemian(); void rush()  ; int display(char s[]); void delete_member(); void jiemian();  void sort(); void save_t(); void search(); void modify();    void jiemian() {  	printf("简单社团管理系统\n");     printf("选择想要进行的操作：\n"); 	printf("1添加学生信息  2删除学生信息  3修改学生信息 4查找学生信息 5显示学生信息 6保存程序 7按学号排序 8退出程序\n");   }      void rush()                //新成员入社 { 	int i=num;	 	printf("请输入第%d个同学信息\n",i+1); 	printf("请输入学号："); 	scanf("%s",lib[i].number);  	printf("请输入姓名："); 	scanf("%s",lib[i].name);  	printf("请输入性别："); 	scanf("%s",lib[i].gender);  	printf("请输入生日："); 	scanf("%d",&lib[i].birth);  	printf("请输入院系："); 	scanf("%s",lib[i].yuanxi);  	printf("请输入职务："); 	scanf("%s",lib[i].zhiwu);  	printf("请输入宿舍号："); 	scanf("%d",&lib[i].sushehao);  	printf("请输入手机号："); 	scanf("%d",&lib[i].phonenumber);    	num++; 	printf("已输入%d个同学的信息\n",num);   }  void sort()//按学号排序 { 	int i,j; 	struct Member temp; 	for(j=1;j<=num;j++) 		for(i=0;i<num;i++) 			if(lib[i].number>lib[i+1].number) 			{ 				temp=lib[i]; 				lib[i]=lib[i+1]; 				lib[i+1]=temp; 			}      	printf("排序后结果为：\n"); 	for(i=0;i<num;i++) 			{ 				printf("该同学学号：%s",lib[i].number); 				printf("\n"); 				printf("该同学姓名：%s",lib[i].name); 				printf("\n"); 				printf("该同学性别：%s",lib[i].gender); 				printf("\n"); 				printf("该同学生日：%d",lib[i].birth); 				printf("\n"); 				printf("该同学院系：%s",lib[i].yuanxi); 				printf("\n"); 				printf("该同学职务：%s",lib[i].zhiwu); 				printf("\n"); 				printf("该同学宿舍号：%d",lib[i].sushehao); 				printf("\n"); 				printf("该同学电话号码：%d",lib[i].phonenumber); 				printf("\n"); 			}  }   void delete_member()  //删除 { 	int i=1,j; 	char s[20]; 	printf("输入所要删除同学的学号："); 	scanf("%s",&s); 	j=display(s); 	if(j!=-1) 	{ 		num--; 		for(i=j;i<num;i++) 		  { 		   lib[i]=lib[i+1]; 		  } 	printf("已删除");  	}  }  void modify() { 	int j; 	char s[20]; 	printf("请输入需要修改的学生学号"); 	scanf("%s",s); 	j=display(s); 	if(j!=-1); 	{ 		printf("\n请重新输入该学生的信息\n"); 			printf("\n请输入学号："); 			scanf("%s",lib[j].number); 			printf("修改姓名："); 			scanf("%s",lib[j].name); 			printf("请输入性别："); 			scanf("%s",lib[j].gender); 			printf("请输入生日："); 			scanf("%d",&lib[j].birth); 			printf("请输入院系："); 			scanf("%s",lib[j].yuanxi); 			printf("请输入职务："); 			scanf("%s",lib[j].zhiwu); 			printf("请输入宿舍号："); 			scanf("%d",&lib[j].sushehao); 			printf("请输入电话号码："); 			scanf("%d",&lib[j].phonenumber); 	} }   int display(char s[]) {     int k=-1,i;     if(strlen(s)==0) 	{ 	    if(num>0) 		{ 		    for(i=0;i<num;i++) 			{ 				printf("该同学学号：%s",lib[i].number); 				printf("\n"); 				printf("该同学姓名：%s",lib[i].name); 				printf("\n"); 				printf("该同学性别：%s",lib[i].gender); 				printf("\n"); 				printf("该同学生日：%d",lib[i].birth); 				printf("\n"); 				printf("该同学院系：%s",lib[i].yuanxi); 				printf("\n"); 				printf("该同学职务：%s",lib[i].zhiwu); 				printf("\n"); 				printf("该同学宿舍号：%d",lib[i].sushehao); 				printf("\n"); 				printf("该同学电话号码：%d",lib[i].phonenumber); 				printf("\n"); 			} 		} 		else 		      printf("无学生信息");    	} 	else 	{ 	   for(i=0;i<num;i++) 	   if(strcmp(s,lib[i].number) == 0) 	   {             printf("该同学学号：%s",lib[i].number); 			printf("\n"); 			printf("该同学姓名：%s",lib[i].name); 			printf("\n"); 			printf("该同学性别：%s",lib[i].gender); 			printf("\n"); 			printf("该同学生日：%d",lib[i].birth); 			printf("\n"); 			printf("该同学院系：%s",lib[i].yuanxi); 			printf("\n"); 			printf("该同学职务：%s",lib[i].zhiwu); 			printf("\n"); 			printf("该同学宿舍号：%d",lib[i].sushehao); 			printf("\n"); 			printf("该同学电话号码：%d",lib[i].phonenumber); 			printf("\n"); 			k=i; 	   }  	       if(k==-1) 		   printf("没有找到此学生");   	}  	return k; }//返回k=-1就是出错，否则返回数组下标    void search(struct Member lib[])//按学号查找 {  	char s[20]; 	printf("请输入同学学号"); 	scanf("%s",&s); 	display(s);  }    void save_t() { 	int i; 	FILE *fp; 	char fname[20]; 	printf("输入文件名（  .txt）"); 	scanf("%s",fname); 	if((fp=fopen(fname,"w"))==NULL); 	{ 		printf("文件保存失败\n"); 		return; 	} 	for(i=0;i<num;i++) 	{ 		fprintf(fp,"%s,%s,%s,%d,%s,%s,%d,%d",lib[i].number,lib[i].name,lib[i].gender,lib[i].birth,lib[i].yuanxi,lib[i].zhiwu,lib[i].sushehao,lib[i].phonenumber); 		printf("成功保存文件"); 	} 	fclose(fp); }  main() {  	int n;      system("cls");  	for(;;) 	{ 		jiemian(); 		printf("输入选项数字"); 		scanf("%d",&n); 		// while(n!=EOF&&n>0&&n<6)          switch(n) 	{     case 1: 		{ 			rush();			  			break;  		} 	case 3: 		{ 			modify(); 			break; 		} 	case 2: 		{ 			delete_member(); 			break; 		} 	case 4: 		{ 			search(); 			break; 		} 	case 5: 		{ 			display(""); 			break; 		} 	case 6: 		{ 			save_t(); 			break; 		} 	case 7: 		{ 			sort(); 			break; 		} 	case 8: 		{ 			exit(0); 		}   	}     	} }

在你的 void rush函数里面，是一个while（1）死循环，所以，你每输入完成后，又接着输入第二个。这样循环下去。 如果你只需要每次输入一个，就重新选择，你就可以把这个函数里的while循环去掉。或者在循环的最后面的i++后面加一句return；就可以了。你试试。

int rt = scanf("%d",&n);//检测下是是返回==1


Question: 课程设计

函数是怎样声明的，如果是 void 就不用 return 0


Question: 内存释放问题

引用 4 楼 tiyager 的回复:[quote=引用 2 楼 ggglivw 的回复:] new 的需要delete, malloc的需要free，其他的看你逻辑实现，你别混用，你这个接口设计的不好，提供了分配就要给别个提供destroy。别个不管你内部实现，这个是你的事情 你的意思是函数如果malloc了就应该在函数内部free掉，对吧。不应该作为返回值，让别人释放是吧[/quote] 1L说得对。动态分配的内存才需要用free()函数手动释放，动态内存即使用 malloc calloc 函数等方式 申请的内存，自动分配的不需要，程序会自动释放。 2L的意思应该是，一个接口内会包括多个函数，只要在这个接口内部释放掉就行了，并不是说一个函数内malloc开辟出来的空间就一定要在该函数内释放。事实上一般会设计一个函数专门malloc，一个函数专门用来free。像这种在main函数内malloc开辟的空间，不一定要手动free，因为main函数结束后，系统会自动回收掉这些空间。但是在大型的程序里面，程序一运行可能会花很长时间，甚至不会停下来。所以这时候就要及时释放掉这些空间，避免发生内存溢出。 因此如果是这种测试用的小程序，free不free都没什么关系，但是养成习惯最好还是释放掉。

引用 4 楼 tiyager 的回复:[quote=引用 2 楼 ggglivw 的回复:] new 的需要delete, malloc的需要free，其他的看你逻辑实现，你别混用，你这个接口设计的不好，提供了分配就要给别个提供destroy。别个不管你内部实现，这个是你的事情 你的意思是函数如果malloc了就应该在函数内部free掉，对吧。不应该作为返回值，让别人释放是吧[/quote]  不是，你可以自己内部malloc，然后将内存交出去给外部用，但是外部如果不用了要调用你自己的destroy将内存还给你，你拿到以后free，当然你要做验证，比如重复归还，还的东西不是你交出去的，等等

引用 2 楼 ggglivw 的回复:new 的需要delete, malloc的需要free，其他的看你逻辑实现，你别混用，你这个接口设计的不好，提供了分配就要给别个提供destroy。别个不管你内部实现，这个是你的事情 你的意思是函数如果malloc了就应该在函数内部free掉，对吧。不应该作为返回值，让别人释放是吧

记得如果new [] 就要用delete []

引用 楼主 tiyager 的回复: #include <stdio.h> #include <string.h> #include <stdlib.h>  char* proc_usr_name(const char* uid){     uid_t my_uid;     my_uid = atoi(uid);     struct passwd *my_info;     if(my_uid)         my_info = getpwuid( my_uid );     if(my_info)         return my_info->pw_name ;  //my_info需要这样释放吗？ 为什么？     return "N/A"; } int main(){ 	char* str = proc_usr_name("1"); 	printf("str:%s\n",str); 	free(str)//需要这样释放吗 ？ 为什么？ 	return 0; }   有的时候调用的函数返回char*那这个内存需不需要释放，不是很明白。   动态分配的内存才需要用free()函数手动释放，动态内存即使用 malloc calloc 函数等方式 申请的内存，自动分配的不需要，程序会自动释放。


Question: c语言

char id[m]; char name[m]; 这两个字符数组能存储 n 个学生的学号和姓名吗？ 建议用结构体数组来存储学生信息

char id[m]; char name[m]; 这里错了，两个id，如果id不是一个数的话，应该是二维数组id[2][m];name[2][m]； 这里错了导致你输出的时候 printf("%s %s %.1f %.1f %.1f\n",id[k],name[k],a[k],b[k],c[k]);这里也错了 应该是printf("%s %s %.1f %.1f %.1f\n",&id[k][0],&name[k][0],a[k],b[k],c[k]);  for(i=0;i<n;i++) { sum1=a[i]+b[i]+c[i]; if(sum1>sum2) { sum2=sum1; k=i; } } 这里错了，两次都是用的sum1算的总分。    两个id 应该是个二维数组


Question: 解决一个问题呗，就是C语言中字符串常量，'

两个\得到一个\， 所以，"\\\"先得到"\\"，再得到"\"； \"得到一个双引号，但这个双引号不被认为是用于结束字面串，所以这个串缺少一个配对的 "

我要成为你的铁粉，

\是转义符，就是把\后面的字符转义，比如\t是tab符，\n是换行符。所以单独一个\的字符串（”\”）会出错，因为它把\后面的”转义了。 想得到一个\字符串，就要”\\” “\\\”前两个\\得到一个\，后一个\把”转义了，所以“\\\”是错的。


Question: 输出大于X的n个素数，不知道为什么没有输出结果，想问问怎么改

啊！谢谢改对了   那为什么不可以是==呢

while(count==n) 改为while(count<n) 这样while循环的内部才能运行

引用 2 楼 Vennus? 的回复:啊！谢谢改对了   那为什么不可以是==呢   你输入的n非0的话 n!=count(0)，while循环永远进不去  所以没有输出


Question: 看题

就是个函数调用

0*0+1  +   10*10+1   +     20*20+1


Question: C中嵌入汇编，有没有有经验的老师提示我一下，谢谢啦

https://docs.microsoft.com/en-us/cpp/assembler/inline/using-and-preserving-registers-in-inline-assembly?view=vs-2019 这里对我的问题进行了解释，

解决这个问题，首先要把汇编学好。。。。。。

引用 9 楼 千梦一生 的回复:哈哈，我个人的观点是多知道些知识总是好的。不能在思想上就将自己拘泥与任何地方。 就像老师说的，我觉得一个java、.net程序员真的能问出这个问题的时候就至少已经说明在思考，就算不考虑到内存泄漏，也会在实际应用中面临资源调度的问题，内存其实就是资源啊。干好本职的工作、且专精，那毋庸置疑值得称赞。只是我也同样觉得保持有发现问题、且尝试解决问题的精神也是应该做的。就像不学好基础的人，真的很难说能搞透彻上层的问题。 最后，还是要谢谢两位老师的回复与提出的一些建议。 俗话说学而不思则罔，你的问题不是在于你去思考，思考当然对，关键在于思考的方向，有个成语叫南辕北辙，可以百度一下， 汇编如过做好的话，对于计算机几乎无所不能。所以你说用汇编如何避免寄存器错误，除了把计算机基础结构和汇编学好，几乎没有办法。就好比一个小孩子，给他一把枪，却去告诉问别人如何避免伤到他自己一个样子。。。。。。。。

看到这个问题，我想到一个习惯java，.net的程序员，来问c++如何保证内存不泄露。

写判断呗 je jnz  可能我说的也不对 但是我平时判断寄存器的值都是写判断

引用 5 楼 千梦一生 的回复:[quote=引用 4 楼  的回复:] DWORD a = 0; __asm{ mov eax,1 mov a,eax } a = 1了 用变量来存放          其实我想的问题是  function（） { ... __asm { mov eax,1//您这里使用了通用寄存器eax。可是用的时候，该eax内的值是否有意义。如果有意义，却在这里直接用1进行了覆盖，那不得凉凉吗? mov a,eax } ... }[/quote]  因为这里是在程序可能任意位置嵌入的汇编。并非从头到尾写完的汇编。不知道此时的处在一个怎样的上下文环境中，无法肯定某寄存器的值是否有效。所以我就想问一问大佬们是怎么处理这种问题的。刚刚找到了前辈们的解释，说在嵌入的__asm块中，一般而言不用担心这种情况发生，因为编译器会尽量避开你使用的寄存器。或者不行的话，它会帮助程序员在首位去push/和pop的

引用 4 楼  的回复:DWORD a = 0; __asm{ mov eax,1 mov a,eax } a = 1了 用变量来存放          其实我想的问题是  function（） { ... __asm { mov eax,1//您这里使用了通用寄存器eax。可是用的时候，该eax内的值是否有意义。如果有意义，却在这里直接用1进行了覆盖，那不得凉凉吗? mov a,eax } ... }

一般而言，嵌入汇编块的话，不是特殊情况下，这种问题编译器会考虑如何解决的。 即，就是否保护寄存器、如何保护寄存器，将由编译器去做。 push 、pop确实属于常见方式之一


Question: C语言循环的题目，不知道哪里有问题

我知道哪里错了，不是在针对x输出后面的三个数，要找出的是三个素数

4 4的话也应该输出4个素数，不是两个

很忌讳在for的时候修改终止迭代条件的值. 有可能造成死循环

就是我要是输入 6 3 结果只有7，不能返回正确的结果

不知你出的是啥问题，是没有输出？还是结果不符合要求？用你的代码跑了一下，能正常输出。  #include <stdio.h>  int main(void) { 	int x,n,i,j; 	scanf("%d%d",&x, &n); 	for (i=1; i<=n; i++) 	{ 		++x; 		for (j=2; j<=x; j++) 		{ 			if (x % j == 0) 			   break;		     		} 		if (x==j) 		    printf("%d ", x); 	} 	return 0; }


Question: 大佬们，我在VS2017上面弄opencv时出现的问题，该怎么解决啊，谢谢啦

你创建的项目类型是Xaml::Application 不要修改系统自动给你生成的函数   引至大佬：每个人都有一个梦才不会孤单的说话就有天堂 问题已解决


Question: 推箱子如何进入下一关，出现点问题，为什么我的两次判断箱子数的代码不行求各位大佬指点

引用 1 楼 user-1的回复:没有项目背景，没有数据，例子 强撸不完整的代码，真的浪费时间，一般人不会干 谢谢，受教了

没有项目背景，没有数据，例子 强撸不完整的代码，真的浪费时间，一般人不会干


Question: 求助

引用 1 楼 user-1的回复:题外话 1，首先你传进来的这个head，没法把链表返回出去 2.，就一个简单的链表操作而言，你的代码写得太复杂了，千回百转，各种绕，虽然最后看起来是链起来了        但是让人看得头疼，相信你自己再过一遍也是头疼 3.   描述问题的时候也没说清楚，循环怎么个无法停止，       是输入停不了，还是输出 言归正传  应该是输入吧，从你的scanf("%s", new->id);来推断，这个id应该是个字符数组 然后下面的循环 while(new->id != '#') 这里new->id是什么，数组的名字，是一个指针变量对不对， new->id就是id这个字符数组的首地址， 这个条件判断就是判断一个指针值会不会等于'#'这个字符，， 明显怎么样都不会相等，所以这个语句永远为真。  这种语句编译器应该是会给你告警的，你重新编译下应该能看到  你把他改成while(new->id[0] != '#')应该就OK了 好的我试试，非常感谢你


Question: 新人C语言问题

你这不是求助吧？


Question: 请问我这个C程序要怎么改？

谢谢你的用心，对于一个初学者来说帮助很大！

你混淆了两个数组，关于学生的结构数组，和每个学生自己的分数数组， 你的代码试图把这2个交叉的数组组成一个二维数组，思维上混乱了    暂且抛去设计上的逻辑问题，你定义的函数int aver(int scores[5][4]) 这个函数实际只有一个参数，就是二维数组（指针），你调用的时候却传4个参数进去，这本身也是一个问题  言归正传，先做需求分析，你对需求的理解应该是错误的 平均分，一般来说是针对一门课程的群体的平均分，而不是针对一个人来计算，（你代码里计算的是个人的4门平均分） 比如英语，数学，大学里数学假设是百分制，英语是150分制， 你计算个人的平均分没什么意义 一般统计的是一个班级的某科的平均分， 或者更一般的，所有人总分的平均分  为了使问题简单化，就不做太多复杂的东西了，供参考，可以对照下 #include <stdio.h> #include <stdlib.h>  /* 为了不使问题复杂化，沿用你的思路 scores[0],[1] [2] [3]分别代表  线代 微积分 程序设计 英语  ----  但是从设计思想来看，这是不好的，  隐含信息，这种对应关系只有你知道  没法用程序去约束他，建立对应关系  对于初学语言特性的你来说，先这样吧 */ struct student_st {     int num;     char name[16];     char sex;     int age;     int scores[4]; }; typedef struct student_st student;  /*根据student集合，计算每门功课平均分 存储到avg_score中, 这里其实有一些设计细节，比如要使用本 函数，传入的数组要能装得下student的课程数 更由甚者，这里默认用严格的一一对应关系， 留给你去思考吧，这些思考能帮助你设计出 更好的软件 */ int aver(student *s, double *avg_score) //与aver(student s[], int avg_score[])是一样的 {     int sum = 0;     for (int i = 0; i < 4; i++) //4门课程，按课程平均     {         sum = 0; //每次都要初始化，不然就会累加到上次的结果了         for (int j = 0; j < 5; j++)         {             /*嵌套关系，数组里包含数组，逐层解开访问它就好了             要访问第j个学生的数据怎么办，先s[j],             第j个学生的分数呢, s[j].score*/             /*             这里恶搞一下，指针真有你想的那么优雅高级？              */             sum += *((s + j)->scores + i); //使用s[j].scores[i];搞定, 经常来说用下标访问数组使你生活更容易些         }         *(avg_score + i) = (double)sum / 5; //avg_score[i] = sum / 4.0;         //printf("第%d门课程的平均成绩: %f\n", i + 1, *(avg_score + i));     } } int main() {     int ret;     /*分行对齐，好看些，护眼护脑     很快就发现问题，名字里有空格     帮你把数据改了一下，体现出你程序的价值，     能计算平均分，不然分数都一样，不用算都知道平均分了     最后愿你成为最后那个学霸，送你了female，女的！*/     student stu[5] = {{1, "小周", 'm', 19, 81, 40, 70, 84},                       {136, "小黄", 'm', 19, 40, 50, 88, 30},                       {137, "小郑", 'm', 19, 60, 20, 89, 0},                       {13822, "小小", 'm', 19, 80, 70, 66, 77},                       {139, "小朱", 'f', 20, 97, 100, 99, 99}};     student *p;     printf("\n-------------------------------学生信息总览-------------------------------\n\n");     /*一种简单的输出对齐方法*/     printf("%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\n", "学号", "姓名", "性别", "年龄", "线代", "微积分", "程序设计", "英语");     /*直接用数字就好了，但是从练习熟悉指针来说，没毛病*/     for (p = stu; p < stu + 5; p++)     {         /*单个字符 用%c, 字符串用%s         character,  string,,,中文字符printf输出对齐是噩梦, 不齐的时候自己加\t对齐*/         printf("%d\t%s\t%c\t%d\t%d\t%d\t%d\t\t%d\n", p->num, p->name, p->sex, p->age,                p->scores[0], p->scores[1], p->scores[2], p->scores[3]);     }     /*平均分     沿用前面的隐含约定，     [0],[1] [2] [3]分别代表     线代 微积分 程序设计 英语     ----知道这样做的麻烦了吧，每一次涉及科目成绩的处理（编程），都得回头看看     确认一次，到底代表什么     */     double avg_score[4];      ret = aver(stu, avg_score);      printf("\n\n-----------------各科平均成绩-----------------\n\n");     printf("%s\t%s\t%s\t%s\n", "线代", "微积分", "程序设计", "英语");     printf("%.2f\t%.2f\t%.2f\t\t%.2f\n\n", avg_score[0], avg_score[1],            avg_score[2], avg_score[3]);     system("PAUSE");     return 0; }

我和你运行的不是同一个程序，我直接编译不过。aver定义的数字，调用传递的4个值


Question: 我想问下这个代码怎么改才能比较5次才得到结果呢

谢谢。谢谢真的行了

引用 20 楼 嘿嘿٩(๑`н´๑)۶的回复:[quote=引用 19 楼 老英捉小奇的回复:][quote=引用 18 楼 嘿嘿٩(๑`н´๑)۶的回复:][quote=引用 16 楼 老英捉小奇的回复:][quote=引用 15 楼 嘿嘿٩(๑`н´๑)۶的回复:][quote=引用 14 楼 老英捉小奇的回复:][quote=引用 13 楼 嘿嘿٩(๑`н´๑)۶的回复:][quote=引用 12 楼 老英捉小奇的回复:][quote=引用 11 楼 老英捉小奇的回复:]void arrsort(int a[],int n){ int i,j; i=0; j=0; for( i=0;i<n-1;i++){  for( j=0;j<n-1-i;j++){  if(a[j]>a[j+1]){    int temp =a[j+1];   a[j+1] = a[j];   a[j] = temp;  } arrout(a,NUM); }  }    } 这样不就循环一次输出一次了吗[/quote] 为啥没有那个#include呀⊙_⊙[/quote] 我只是复制了一部分…………   这是个比较大小的函数   ，该调用还是要调用的[/quote] 什么东西⊙_⊙[/quote] #include <stdio.h>  #define NUM 5  void arrsort(int[],int);  void arrout(int[],int);  main(){   int a[NUM]={16,25,9,90,23};   arrout(a,NUM);//输出a数组中原始数据   arrsort(a,NUM);//对a数组中的数进行排序并输出  }  void arrsort(int a[],int n){ int i,j; i=0; j=0; for( i=0;i<n-1;i++){  for( j=0;j<n-1-i;j++){  if(a[j]>a[j+1]){    int temp =a[j+1];   a[j+1] = a[j];   a[j] = temp;  }  } arrsort(a,NUM); }    }  void arrout(int a[],int n){  int i;  for(i=0;i<n;i++){  printf("%3d",a[i]);  }  printf("\n");  } 这样就行了，  不懂的时候你拿电脑或手机运行试试就知道了[/quote] 这样也不行。。现在都，不排序了，直接就输出那个原来的数[/quote] ，，，我下课拿电脑试试吧[/quote] 那个工具是vc6[/quote] #include <stdio.h> #define NUM 5 void arrsort(int[],int); void arrout(int[],int); void main() { 	int a[NUM]={16,25,9,90,23}; 	arrout(a,NUM);//输出a数组中原始数据 	printf("******************\n");//分割线 	arrsort(a,NUM);//对a数组中的数进行排序并输出 } void arrsort(int a[],int n) { 	int i,j,temp; 	for( i=0;i<n-1;i++) 	{ 		for( j=0;j<n-1-i;j++) 			if(a[j]>a[j+1]) 			{  				temp =a[j+1]; 				a[j+1] = a[j]; 				 a[j] = temp; 			} 			arrout(a,NUM); 	} } void arrout(int a[],int n) { 	int i; 	for(i=0;i<n;i++) 		printf("%3d",a[i]); 	printf("\n"); } 这样就行了

引用 19 楼 老英捉小奇的回复:[quote=引用 18 楼 嘿嘿٩(๑`н´๑)۶的回复:][quote=引用 16 楼 老英捉小奇的回复:][quote=引用 15 楼 嘿嘿٩(๑`н´๑)۶的回复:][quote=引用 14 楼 老英捉小奇的回复:][quote=引用 13 楼 嘿嘿٩(๑`н´๑)۶的回复:][quote=引用 12 楼 老英捉小奇的回复:][quote=引用 11 楼 老英捉小奇的回复:]void arrsort(int a[],int n){ int i,j; i=0; j=0; for( i=0;i<n-1;i++){  for( j=0;j<n-1-i;j++){  if(a[j]>a[j+1]){    int temp =a[j+1];   a[j+1] = a[j];   a[j] = temp;  } arrout(a,NUM); }  }    } 这样不就循环一次输出一次了吗[/quote] 为啥没有那个#include呀⊙_⊙[/quote] 我只是复制了一部分…………   这是个比较大小的函数   ，该调用还是要调用的[/quote] 什么东西⊙_⊙[/quote] #include <stdio.h>  #define NUM 5  void arrsort(int[],int);  void arrout(int[],int);  main(){   int a[NUM]={16,25,9,90,23};   arrout(a,NUM);//输出a数组中原始数据   arrsort(a,NUM);//对a数组中的数进行排序并输出  }  void arrsort(int a[],int n){ int i,j; i=0; j=0; for( i=0;i<n-1;i++){  for( j=0;j<n-1-i;j++){  if(a[j]>a[j+1]){    int temp =a[j+1];   a[j+1] = a[j];   a[j] = temp;  }  } arrsort(a,NUM); }    }  void arrout(int a[],int n){  int i;  for(i=0;i<n;i++){  printf("%3d",a[i]);  }  printf("\n");  } 这样就行了，  不懂的时候你拿电脑或手机运行试试就知道了[/quote] 这样也不行。。现在都，不排序了，直接就输出那个原来的数[/quote] ，，，我下课拿电脑试试吧[/quote] 那个工具是vc6

引用 18 楼 嘿嘿٩(๑`н´๑)۶的回复:[quote=引用 16 楼 老英捉小奇的回复:][quote=引用 15 楼 嘿嘿٩(๑`н´๑)۶的回复:][quote=引用 14 楼 老英捉小奇的回复:][quote=引用 13 楼 嘿嘿٩(๑`н´๑)۶的回复:][quote=引用 12 楼 老英捉小奇的回复:][quote=引用 11 楼 老英捉小奇的回复:]void arrsort(int a[],int n){ int i,j; i=0; j=0; for( i=0;i<n-1;i++){  for( j=0;j<n-1-i;j++){  if(a[j]>a[j+1]){    int temp =a[j+1];   a[j+1] = a[j];   a[j] = temp;  } arrout(a,NUM); }  }    } 这样不就循环一次输出一次了吗[/quote] 为啥没有那个#include呀⊙_⊙[/quote] 我只是复制了一部分…………   这是个比较大小的函数   ，该调用还是要调用的[/quote] 什么东西⊙_⊙[/quote] #include <stdio.h>  #define NUM 5  void arrsort(int[],int);  void arrout(int[],int);  main(){   int a[NUM]={16,25,9,90,23};   arrout(a,NUM);//输出a数组中原始数据   arrsort(a,NUM);//对a数组中的数进行排序并输出  }  void arrsort(int a[],int n){ int i,j; i=0; j=0; for( i=0;i<n-1;i++){  for( j=0;j<n-1-i;j++){  if(a[j]>a[j+1]){    int temp =a[j+1];   a[j+1] = a[j];   a[j] = temp;  }  } arrsort(a,NUM); }    }  void arrout(int a[],int n){  int i;  for(i=0;i<n;i++){  printf("%3d",a[i]);  }  printf("\n");  } 这样就行了，  不懂的时候你拿电脑或手机运行试试就知道了[/quote] 这样也不行。。现在都，不排序了，直接就输出那个原来的数[/quote] ，，，我下课拿电脑试试吧

引用 16 楼 老英捉小奇的回复:[quote=引用 15 楼 嘿嘿٩(๑`н´๑)۶的回复:][quote=引用 14 楼 老英捉小奇的回复:][quote=引用 13 楼 嘿嘿٩(๑`н´๑)۶的回复:][quote=引用 12 楼 老英捉小奇的回复:][quote=引用 11 楼 老英捉小奇的回复:]void arrsort(int a[],int n){ int i,j; i=0; j=0; for( i=0;i<n-1;i++){  for( j=0;j<n-1-i;j++){  if(a[j]>a[j+1]){    int temp =a[j+1];   a[j+1] = a[j];   a[j] = temp;  } arrout(a,NUM); }  }    } 这样不就循环一次输出一次了吗[/quote] 为啥没有那个#include呀⊙_⊙[/quote] 我只是复制了一部分…………   这是个比较大小的函数   ，该调用还是要调用的[/quote] 什么东西⊙_⊙[/quote] #include <stdio.h>  #define NUM 5  void arrsort(int[],int);  void arrout(int[],int);  main(){   int a[NUM]={16,25,9,90,23};   arrout(a,NUM);//输出a数组中原始数据   arrsort(a,NUM);//对a数组中的数进行排序并输出  }  void arrsort(int a[],int n){ int i,j; i=0; j=0; for( i=0;i<n-1;i++){  for( j=0;j<n-1-i;j++){  if(a[j]>a[j+1]){    int temp =a[j+1];   a[j+1] = a[j];   a[j] = temp;  }  } arrsort(a,NUM); }    }  void arrout(int a[],int n){  int i;  for(i=0;i<n;i++){  printf("%3d",a[i]);  }  printf("\n");  } 这样就行了，  不懂的时候你拿电脑或手机运行试试就知道了[/quote] 这样也不行。。现在都，不排序了，直接就输出那个原来的数

引用 16 楼 老英捉小奇的回复:[quote=引用 15 楼 嘿嘿٩(๑`н´๑)۶的回复:][quote=引用 14 楼 老英捉小奇的回复:][quote=引用 13 楼 嘿嘿٩(๑`н´๑)۶的回复:][quote=引用 12 楼 老英捉小奇的回复:][quote=引用 11 楼 老英捉小奇的回复:]void arrsort(int a[],int n){ int i,j; i=0; j=0; for( i=0;i<n-1;i++){  for( j=0;j<n-1-i;j++){  if(a[j]>a[j+1]){    int temp =a[j+1];   a[j+1] = a[j];   a[j] = temp;  } arrout(a,NUM); }  }    } 这样不就循环一次输出一次了吗[/quote] 为啥没有那个#include呀⊙_⊙[/quote] 我只是复制了一部分…………   这是个比较大小的函数   ，该调用还是要调用的[/quote] 什么东西⊙_⊙[/quote] #include <stdio.h>  #define NUM 5  void arrsort(int[],int);  void arrout(int[],int);  main(){   int a[NUM]={16,25,9,90,23};   arrout(a,NUM);//输出a数组中原始数据   arrsort(a,NUM);//对a数组中的数进行排序并输出  }  void arrsort(int a[],int n){ int i,j; i=0; j=0; for( i=0;i<n-1;i++){  for( j=0;j<n-1-i;j++){  if(a[j]>a[j+1]){    int temp =a[j+1];   a[j+1] = a[j];   a[j] = temp;  }  } arrsort(a,NUM); }    }  void arrout(int a[],int n){  int i;  for(i=0;i<n;i++){  printf("%3d",a[i]);  }  printf("\n");  } 这样就行了，  不懂的时候你拿电脑或手机运行试试就知道了[/quote] 谢谢你

引用 15 楼 嘿嘿٩(๑`н´๑)۶的回复:[quote=引用 14 楼 老英捉小奇的回复:][quote=引用 13 楼 嘿嘿٩(๑`н´๑)۶的回复:][quote=引用 12 楼 老英捉小奇的回复:][quote=引用 11 楼 老英捉小奇的回复:]void arrsort(int a[],int n){ int i,j; i=0; j=0; for( i=0;i<n-1;i++){  for( j=0;j<n-1-i;j++){  if(a[j]>a[j+1]){    int temp =a[j+1];   a[j+1] = a[j];   a[j] = temp;  } arrout(a,NUM); }  }    } 这样不就循环一次输出一次了吗[/quote] 为啥没有那个#include呀⊙_⊙[/quote] 我只是复制了一部分…………   这是个比较大小的函数   ，该调用还是要调用的[/quote] 什么东西⊙_⊙[/quote] #include <stdio.h>  #define NUM 5  void arrsort(int[],int);  void arrout(int[],int);  main(){   int a[NUM]={16,25,9,90,23};   arrout(a,NUM);//输出a数组中原始数据   arrsort(a,NUM);//对a数组中的数进行排序并输出  }  void arrsort(int a[],int n){ int i,j; i=0; j=0; for( i=0;i<n-1;i++){  for( j=0;j<n-1-i;j++){  if(a[j]>a[j+1]){    int temp =a[j+1];   a[j+1] = a[j];   a[j] = temp;  }  } arrsort(a,NUM); }    }  void arrout(int a[],int n){  int i;  for(i=0;i<n;i++){  printf("%3d",a[i]);  }  printf("\n");  } 这样就行了，  不懂的时候你拿电脑或手机运行试试就知道了

引用 14 楼 老英捉小奇的回复:[quote=引用 13 楼 嘿嘿٩(๑`н´๑)۶的回复:][quote=引用 12 楼 老英捉小奇的回复:][quote=引用 11 楼 老英捉小奇的回复:]void arrsort(int a[],int n){ int i,j; i=0; j=0; for( i=0;i<n-1;i++){  for( j=0;j<n-1-i;j++){  if(a[j]>a[j+1]){    int temp =a[j+1];   a[j+1] = a[j];   a[j] = temp;  } arrout(a,NUM); }  }    } 这样不就循环一次输出一次了吗[/quote] 为啥没有那个#include呀⊙_⊙[/quote] 我只是复制了一部分…………   这是个比较大小的函数   ，该调用还是要调用的[/quote] 什么东西⊙_⊙

引用 13 楼 嘿嘿٩(๑`н´๑)۶的回复:[quote=引用 12 楼 老英捉小奇的回复:][quote=引用 11 楼 老英捉小奇的回复:]void arrsort(int a[],int n){ int i,j; i=0; j=0; for( i=0;i<n-1;i++){  for( j=0;j<n-1-i;j++){  if(a[j]>a[j+1]){    int temp =a[j+1];   a[j+1] = a[j];   a[j] = temp;  } arrout(a,NUM); }  }    } 这样不就循环一次输出一次了吗[/quote] 为啥没有那个#include呀⊙_⊙[/quote] 我只是复制了一部分…………   这是个比较大小的函数   ，该调用还是要调用的

引用 12 楼 老英捉小奇的回复:[quote=引用 11 楼 老英捉小奇的回复:]void arrsort(int a[],int n){ int i,j; i=0; j=0; for( i=0;i<n-1;i++){  for( j=0;j<n-1-i;j++){  if(a[j]>a[j+1]){    int temp =a[j+1];   a[j+1] = a[j];   a[j] = temp;  } arrout(a,NUM); }  }    } 这样不就循环一次输出一次了吗[/quote] 为啥没有那个#include呀⊙_⊙

引用 11 楼 老英捉小奇的回复:void arrsort(int a[],int n){ int i,j; i=0; j=0; for( i=0;i<n-1;i++){  for( j=0;j<n-1-i;j++){  if(a[j]>a[j+1]){    int temp =a[j+1];   a[j+1] = a[j];   a[j] = temp;  } arrout(a,NUM); }  }    } 这样不就循环一次输出一次了吗

引用 9 楼 老英捉小奇的回复:[quote=引用 7 楼 嘿嘿٩(๑`н´๑)۶的回复:][quote=引用 5 楼 老英捉小奇的回复:][quote=引用 4 楼 嘿嘿٩(๑`н´๑)۶的回复:][quote=引用 3 楼 老英捉小奇的回复:]输出放那个比较大小的里面  比一次输出一次 啥@_@可否说的详细一点[/quote] 你写的那个比较大小的函数，在外循环里放一个输出的函数，比较一次就输出一次   …………  其实我不大明白你想问的是啥[/quote] 对呀就是要比较一次输出一次的意思[/quote] 那就在比较大小的外循环里写个输出的语句， 程序能写出来，不应该想不到啊[/quote] 。。。不好意思😣我复制粘贴的。。。

引用 7 楼 嘿嘿٩(๑`н´๑)۶的回复:[quote=引用 5 楼 老英捉小奇的回复:][quote=引用 4 楼 嘿嘿٩(๑`н´๑)۶的回复:][quote=引用 3 楼 老英捉小奇的回复:]输出放那个比较大小的里面  比一次输出一次 啥@_@可否说的详细一点[/quote] 你写的那个比较大小的函数，在外循环里放一个输出的函数，比较一次就输出一次   …………  其实我不大明白你想问的是啥[/quote] 对呀就是要比较一次输出一次的意思[/quote] 那就在比较大小的外循环里写个输出的语句， 程序能写出来，不应该想不到啊

引用 6 楼 user-2的回复:想问的是把每一步比较结果都输出来吗？ 对呀对呀

引用 5 楼 老英捉小奇的回复:[quote=引用 4 楼 嘿嘿٩(๑`н´๑)۶的回复:][quote=引用 3 楼 老英捉小奇的回复:]输出放那个比较大小的里面  比一次输出一次 啥@_@可否说的详细一点[/quote] 你写的那个比较大小的函数，在外循环里放一个输出的函数，比较一次就输出一次   …………  其实我不大明白你想问的是啥[/quote] 对呀就是要比较一次输出一次的意思

想问的是把每一步比较结果都输出来吗？

引用 4 楼 嘿嘿٩(๑`н´๑)۶的回复:[quote=引用 3 楼 老英捉小奇的回复:]输出放那个比较大小的里面  比一次输出一次 啥@_@可否说的详细一点[/quote] 你写的那个比较大小的函数，在外循环里放一个输出的函数，比较一次就输出一次   …………  其实我不大明白你想问的是啥

引用 3 楼 老英捉小奇的回复:输出放那个比较大小的里面  比一次输出一次 啥@_@可否说的详细一点

输出放那个比较大小的里面  比一次输出一次


Question: 用递归写了一个3x3的小迷宫，想知道为什么return不能直接跳出递归，如过想强制跳出递归，该怎么做，附上原码加运行结果。

把向上走 if (i - 1 >= 0 && a[i - 1][j] < 2)//向上走 		{ 			AI(a, i - 1, j); 		} 放在else里面试试 	if (i == 2 && j == 2)  //找到出口 	{ 		printf("you are win !\n"); 		return; 	} 	else 	{ 		// 右，下，左，上 		if (j + 1 <= 2 && a[i][j + 1] < 2)//向右走 		{ 			AI(a, i, j + 1); 		} 		if (i + 1 <= 2 && a[i + 1][j] < 2)//向下走 		{ 			AI(a, i + 1, j); 		} 		if (j - 1 >= 0 && a[i][j - 1] < 2)//向左走 		{ 			AI(a, i, j - 1); 		} 		if (i - 1 >= 0 && a[i - 1][j] < 2)//向上走 		{ 			AI(a, i - 1, j); 		} 	}

递归有堆栈， return了当前堆栈，但是以前的东西得继续，你可以把这个想象成编号，0->1->2这样， N执行完毕了就执行N-1执行位置剩下，直到最上层完毕.

改成指针后仔细看了一下才发现，其实没必要改成指针，因为递归完本来就结束了 所以你的问题是调用递归的分支没用else if，所以递归结束后又进入了下一个if继续递归了 所以改成else if 就可以了 void AI(int a[3][3], int i, int j)  //递归走出迷宫 { a[i][j] = 3; //走过的路 show(a);  //显示当前位置 if (i == 2 && j == 2)  //找到出口 { printf("you are win !\n"); return; } else { // 右，下，左，上 if (j + 1 <= 2 && a[i][j + 1] < 2)//向右走 { AI(a, i, j + 1);     j += 1; } else if (i + 1 <= 2 && a[i + 1][j] < 2)//向下走 { AI(a, i + 1, j); } else if (j - 1 >= 0 && a[i][j - 1] < 2)//向左走 { AI(a, i, j - 1); } else if (i - 1 >= 0 && a[i - 1][j] < 2)//向上走 { AI(a, i - 1, j); } } }

void AI(int a[3][3], int *i, int *j)  //改成指针形式 { a[*i][*j] = 3; //走过的路 show(a);  //显示当前位置 if (*i == 2 && *j == 2)  //找到出口 { printf("you are win !\n"); return; } else { // 右，下，左，上 if (*j + 1 <= 2 && a[*i][*j + 1] < 2)//向右走 { //AI(a, i, j + 1);     *j += 1; } if (*i + 1 <= 2 && a[*i + 1][*j] < 2)//向下走 { //AI(a, i + 1, j);     *i += 1; } if (*j - 1 >= 0 && a[*i][*j - 1] < 2)//向左走 { //AI(a, i, j - 1);     *j -= 1; } if (*i - 1 >= 0 && a[*i - 1][*j] < 2)//向上走 { //AI(a, i - 1, j);     *i -= 1; }     AI(a, i, j); //递归调用     if (*i==2 && *j==2) return; //递归结束返回到这里，然后判断 i，j 退出递归 } }

递归return只是结束当前递归层处理，然后返回上一层的调用递归的地方。如果你希望继续结束上一层递归，就要在上一层调用递归的下一条语句做判断，然后退出递归。 在你这个程序，可以把递归的i，j参数用指针的方式传入传出，然后在调用递归的下一条语句判断i，j结束递归。


Question: 向老师们请教一个问题：为什么俺的预处理指令，它不认呢？

各位老师们见笑了。见识还是太少了些。 谢谢大家的帮助与回复。

C# 虽然带一个C， 但是和C/C++确实一毛钱关系都没有啊

C#用 #if A #elif B #endif

引用 楼主 千梦一生 的回复: 这是wpf的代码，#if它认为是预处理指令。 可这 #ifdef、#ifndef、#if define...好些个都被视为无效的预处理指令了。  向老师们请教一下这个问题。谢谢啦 wpf？？？？你这是c/c++吗？？

好了，问题得到解决了，C#的预处理指令和一般C/C++有些地方是不大一样的。

#ifdef A ... #elsif defined(b) ... #endif

#if defined(A) .... #elsif defined(B)  #endif


Question: 求大佬解答

程序通过了吗？我用了malloc和二分查找，程序还是超时了。

i<n&&c==0 换成i<n 就行，c一旦为1，就直接break掉了。

开始定义一个 int w=0；  最后一个for 开始，换成如下。 for(j=0;j<m;j++){         c=0;         for(i=w;i<n&&c==0;i++){             if(b[j]==a[i]){                 c=1;                  w=i;break;}             if(b[j]<a[i])                 break;        }         if(c==1)         printf("Yes\n");         else         printf("No\n");         }     return 0;}

引用 2 楼 寻开心 的回复:[quote=引用 1 楼 ?Victor.?? 的回复:] scanf("%d",&n); int a[n];  这样做是对的吗？ 我记得好像不可以呀  这个在某些编译器上是允许的   超时的问题是算法的问题 不能直接数组保存，硬查询，那效率太低太低  1 数据是有重复的， 一个人可以提交多次，每一次提交保存一个记录太浪费，也影响查询的速度  2 查询数量大，就要改查询方法， 可以对记录先排序，有序后折半查找，可提速  看题目要求， 学生编号Ai的范围，也就是最多有1，000，000个学生， 以此来建立一个数组， 全局变量unsigned char students[1000010]; 读入n行， 读入的数据如果是v，那么设置students[v] = 1; 这样，students就是记录了每个学生是否交作业的状态了 查询从这里进行， 直接获取是否交作业输出 这个查询就是下标索引，不用循环查找 所以，整个算法是O（1）  代码自己写吧[/quote]我是直接用数组写的，没有TLE，主要是这个题目的数字太大，导致不能像普通的那样申请内存空间，不过可以试试malloc来申请。

引用 1 楼 ?Victor.?? 的回复:scanf("%d",&n); int a[n];  这样做是对的吗？ 我记得好像不可以呀  这个在某些编译器上是允许的   超时的问题是算法的问题 不能直接数组保存，硬查询，那效率太低太低  1 数据是有重复的， 一个人可以提交多次，每一次提交保存一个记录太浪费，也影响查询的速度  2 查询数量大，就要改查询方法， 可以对记录先排序，有序后折半查找，可提速  看题目要求， 学生编号Ai的范围，也就是最多有1，000，000个学生， 以此来建立一个数组， 全局变量unsigned char students[1000010]; 读入n行， 读入的数据如果是v，那么设置students[v] = 1; 这样，students就是记录了每个学生是否交作业的状态了 查询从这里进行， 直接获取是否交作业输出 这个查询就是下标索引，不用循环查找 所以，整个算法是O（1）  代码自己写吧


Question: 为什么二维数组直接传递数组名做参数访问会出错？

类型不匹配，二维数组data对应的类型是：int (*p)[2];即列数是要确定的。  int **p;对应的数组是int *data[200];


Question: 请教指针数组的问题

有一说一这个用数组搞确实麻烦。不是一点点麻烦。代码多且效率低。 1.数组a【10|12|13|15|11】 2.插入一个，说明长度增加了所以需要一个b【||||||】6个空间的数组。为什么不直接加在a的后面呢？因为那样做的话是越界操作。不安全的 3--------好了，我们暂时有a【5个int单位长度】的原数组，以及一个刚刚搞到手的全新的b【6个int单位长度】的没有数据干净的数组 4.执行一个插入操作，比如我们插入数字999到第n个后面 5.这个操作就意味着：前n个不变，后面5-n个全部后移，给999让座儿。（这个话都讲到这儿了，稍微想想应该有能力解决的了）

如果一定要插入到原数组中再输出的话，要么直接把原数组创建成a[6],a[2]=50,其余不变。然后用指针int *b =a,输出*b++或b[0]~b[6]; 要么先 int* a= (int *)malloc(sizeof(int)*5)，再a = (int *)realloc(sizeof(int)*6),然后把a[2]~a[4]往后移到a[3]~a[5]后，再赋值a[2]=50; 然后输出a[0]~a[5]; 不知道你说的用指针怎么写出来是什么意思。 对于一维数组来说，其实没有必要用指向数组的指针，用指向数组首元素的指针int *p = a，然后用p[0],p[1]或*(p+1),*(p+2)来表示数组元素,或者直接a[0],a[1]; 如果一定要用指向数组的指针来表示，那就 int (*p)[5] = &a; 然后用(*p)[0],(*p)[1]来表示。

写的不一定好，但基本能实现要求。供参考  #include <stdio.h>  int main(void) { 	int a[5] = {0}; 	int *p; 	int i, n, d, tmp; 	p = (int *)malloc(sizeof(int)*6); 	 	for (i=0; i<5; i++) 	{ 		scanf("%d", &a[i]); 	} 	printf ("请输入要插入的数字和要插入到第几个数后面：\n"); 	scanf("%d%d", &n, &d); 	 	for (i=0; i<6; i++) 	{ 	 	if (i < d)		 		    p[i] = a[i]; 		else if (i==d) 			p[i] = n; 		else 		    p[i] = a[i-1]; 	    	 	 	} 	for (i=0; i<6; i++) 	{ 		printf("%d ", p[i]); 	} 	 	free(p);	 	return 0; 	 }


Question: Program received signal SIGSEGV,Segmentation fault.

引用 5 楼 自信男孩的回复:#include <stdio.h> #include <stdlib.h>  typedef struct node { 	int data; 	struct node *next; }LinkQueueNode;  typedef struct { 	LinkQueueNode *front; 	LinkQueueNode *rear; }LinkQueue;  int InitQueue(LinkQueue *Q) { 	Q->front=(LinkQueueNode *)malloc(sizeof(LinkQueueNode)); 	if(Q->front!=NULL) 	{ 		Q->rear=Q->front; 		Q->front->next=NULL; 		return 1; 	} 	else 	{ 		return 0; 	} }  int EnterQueue(LinkQueue *Q,int x) { #if 1 	LinkQueueNode *p; 	p = (LinkQueueNode *)malloc(sizeof(LinkQueueNode)); 	if (!p) 		exit(0); 	p->data=x; 	p->next=NULL; 	Q->rear->next=p; 	Q->rear=p;  #else 	LinkQueueNode *p; 	p=(LinkQueueNode *)malloc(sizeof(LinkQueueNode)); 	if(p!=NULL) 	{ 		p->data=x; 		p->next=NULL; 		Q->rear->next=p; 		Q->rear=p; 		return 1; 	} 	else 		return 0; #endif } int DeleteQueue(LinkQueue *Q,int *x) { #if 1 	LinkQueueNode *p; 	if(Q->front == Q->rear) 		return 0; 	p = Q->front->next; 	Q->front->next = p->next; 	if(Q->rear == p) 		Q->rear=Q->front; 	*x = p->data; 	free(p); 	return 1;  #else 	LinkQueueNode *p; 	if(Q->front->next!=Q->rear) 	{ 		p=Q->front->next; 		Q->front->next=p->next; 		if(Q->rear==p) 			Q->rear=Q->front; 		*x=p->data; 		free(p); 		return 1; 	} 	else 		return 0; #endif }  int main() { 	LinkQueue *Q; 	Q = (LinkQueue *)malloc(sizeof(LinkQueue)); 	if (!Q) 		return -1;  	InitQueue(Q); 	printf("请输入数据（-1表示结束）："); 	int x; 	int f = 0; 	scanf("%d",&x); 	while(x!=-1) 	{ 		EnterQueue(Q,x); 		scanf("%d",&x); 		f=1; 	} 	if (f!=1) { 		printf("未输入数据！\n"); 		return 0; 	} 	//if(f==1) //	{ 		printf("输入数据为："); 		//while(Q->front->next != Q->rear) 		while(Q->front != Q->rear) 		{ 			DeleteQueue(Q,&x); 			printf("%d ",x); 		} //	} //	else //		printf("未输入数据！\n"); 	return 0; }   供参考～ 感谢！！🙏🙏🙏

引用 3 楼 user-2的回复:[quote=引用 2 楼 hua____hua 的回复:] [quote=引用 1 楼 user-2的回复:]段错误，检查下是否有数组越界，或者说malloc的时候是否有类型的不符合，比如将一个int类型的数赋给了一个malloc出来的char数组。 是因为我的data类型是int的原因嘛。。。[/quote]  看了下 你这里陷入死循环了 scanf("%d",&x);     while(x!=-1)     {         EnterQueue(Q,x);         f=1;     } 随便输个不等于-1的数就死循环了  你是不是想这样写     //scanf("%d",&x);     while(scanf("%d",&x) && x!=-1)     {         EnterQueue(Q,x);         f=1;     }  这样我运行了一下能运行，但好像输出的不是想要的结果，你再看看吧。 [/quote] 好的感谢！我再去试试！

引用 2 楼 hua____hua 的回复:[quote=引用 1 楼 user-2的回复:]段错误，检查下是否有数组越界，或者说malloc的时候是否有类型的不符合，比如将一个int类型的数赋给了一个malloc出来的char数组。 是因为我的data类型是int的原因嘛。。。[/quote]  看了下 你这里陷入死循环了 scanf("%d",&x);     while(x!=-1)     {         EnterQueue(Q,x);         f=1;     } 随便输个不等于-1的数就死循环了  你是不是想这样写     //scanf("%d",&x);     while(scanf("%d",&x) && x!=-1)     {         EnterQueue(Q,x);         f=1;     }  这样我运行了一下能运行，但好像输出的不是想要的结果，你再看看吧。

引用 1 楼 user-2的回复:段错误，检查下是否有数组越界，或者说malloc的时候是否有类型的不符合，比如将一个int类型的数赋给了一个malloc出来的char数组。 是因为我的data类型是int的原因嘛。。。


Question: 为什么包含了头文件还是不能在主函数中调用已经在头文件中申明过的函数

我也出现这个问题了 请问怎么解决的？

看看是不是在diceroll.c文件里面忘了包含diceroll.h。如果不是的话，看看是不是函数名打错了。 编译报错，显示未定义roll_n 函数。 这里的roll_n函数和上面的roll_n_dice是同一个吗？ 是你简写了，还是报错就是这样报的？

这是diceroll.c的头部 #include "diceroll.h" #include<stdio.h> #include<stdlib.h> 在这个源文件里面也定义了roll_n_dice函数 int roll_n_dice(int dice,int sides) 下面是保存为diceroll.h的头文件 extern int roll_count; int roll_n_dice(int dice,int sides); 然后在主函数源文件中包含了头文件 #include<stdio.h> #include<stdlib.h> #include<time.h> #include "diceroll.h" 编译报错，显示未定义roll_n_dice 函数。

extern 這裡檢查下？這個說明在別的地方定義了 如果沒有 可能造成問題


Question: 现在还有没有靠谱的C语言开发工具？

vs 2019吧，毕竟dev啥的都太老了好多新新的标准都不支持，而且相对来说vs对代码的审查更加严格，有警告啥的第一时间就能看出来，也可以帮助自己养成良好的编程习惯。也可以直接使用gcc或是mingw，可以更加熟悉程序的编译过程，过分的依赖编译器也是不好的习惯。

不懂啊，没学过

引用 30 楼 青蛙工作室 的回复:楼主是来钓鱼的？ 起人耸人听闻的标题让人以为是大佬，实则青铜。 同感！   引用 31 楼 Chen_jiajie1234 的回复:搭建系统是系统工程师的事。我这学编程的可操不起那心。 搭建的非系统，是开发环境！

搭建系统是系统工程师的事。我这学编程的可操不起那心。

楼主是来钓鱼的？ 起人耸人听闻的标题让人以为是大佬，实则青铜。

学习语言基本知识的话，不必搞清楚太多不想关的事情。下载个集成开发环境。专注于学习，写代码即可。

我手上有Java、JSP、C的书，Java和JSP的环境我配置不出来。最后，找到了MS的TurboC，就只能用C编程了。

楼主 ，现在是2020年 ，你不要活在90年代，turbo C 那是多古老的编译器了， 问题一大堆

VC、Java之类的的文件一大堆，又是WEB又是DB的，看着头痛，更别说把他们收集齐并协同工作了。 只想写些小程序练练手，开发环境自然是越小越好。

这个锅没办法甩给编译器 指针传进去也是值传递的方式， 函数内部的交换了，但参数没有任何改变。

给楼主一个在线的编译器吧，你可以试一下你的程序能否在此正常工作！ https://gcc.godbolt.org/

建议改为void f1(&x,&y)

vs系列，支持c++的都支持c

vs系列，支持c++的都支持c

Visual Studio 2019

MSVC太大了，也找不到。 没有MSVC，MSTC也行。MSTC看起来跟TurboC差不多，问题是我现在用的MSTC跟我当时课本上的标准不一致。

引用 19 楼 Chen_jiajie1234 的回复:#18,f1的定义原本是void f1(int x,int y)的，要做的事情是把x,y的数据互换。可是，在main里调用它之后没有实现数据交换。后来查了书才知道可能用地址交换才能实现，所以f1就改成void f1(int *x,int *y)。结果还是不行。所以，我才确定我用的这个MSTC(微软TurboC）不是正版的。 turbo pascal、C、C++都是borland公司早年的产品，现在公司都不在了（改名了）。所以，不可能再买到正版的软件了。但是，楼主是学艺不精，程序写错了，不要瞎怪编译器或IDE。  推测：MSTC(微软TurboC）推测是某人开发的在windows下面仿真dos从而能运行turbo c的东东，所以这个玩意应该是没有问题的，可以正常运行古老的C程序。但是，现在还这么干的人，纯属是脑壳有包！

1、首先是楼主的程序写错了，和编译器无关； 2、windows下面的编程工具太多了，基本上不会导致系统重装的，如果说哪个好，首先是全部能用（包括上面推荐的），要说够用且适合初学者的，那就是MS的VC2010（VS2010）了。

26M的VC6   不是也很爽吗？


Question: 一元多项式相加，帮忙修改

引用 1 楼 自信男孩的回复:#include <stdio.h> #include <stdlib.h>  typedef struct Polynode {     int coef,exp;     struct Polynode *next;  }Polynode,*Polylist;  void polycreate(Polylist &head) {     Polylist rear,s; int c,e;      head=(Polynode *)malloc(sizeof(Polynode));     if (!head)         exit(0);      rear=head;      scanf("%d %d",&c,&e);      while(c!=0){          s=(Polynode *)malloc(sizeof(Polynode));         if (!s)             exit(0);         s->coef=c;         s->exp=e;          rear->next=s;         rear=s;          scanf("%d %d",&c,&e);     }     rear->next=NULL; } //polyadd(Polylist polya,Polylist polyb) Polylist polyadd(Polylist polya,Polylist polyb) {     Polynode *pa,*pb,*pc,*r, *polyc;     int sum;      polyc = (Polylist)malloc(sizeof(Polynode));     if (!polyc)         exit(0);     pa = polya->next;      //pb=polya->next;     pb=polyb->next;     pc = polyc;   //*pre指向和多项式的尾节点      while(pa!=NULL&&pb!=NULL)      {         if(pa->exp<pb->exp)         {             pc->next=pa; pc=pa; pa=pa->next;}          else if(pa->exp==pb->exp)         {             sum=pa->coef+pb->coef;              if(sum!=0)             {                 pa->coef=sum; pc->next=pa;                  pc=pa;pa=pa->next;                  r=pb;pb=pb->next;free(r);             }             else             {                 r=pa;pa=pa->next;free(r);                  r=pb;pb=pb->next;free(r);             }         } else         {     pc->next=pb; pc=pb; pb=pb->next;}     }     if(pa!=NULL) pc->next=pa;      else pc->next=pb;      return polyc; }  void PrintPoly(Polylist p) {     Polylist s;      s=p->next;      while(s)     {         //printf("%0.2f x^%d",s->coef,s->exp);         printf("%d x^%d",s->coef,s->exp);         s=s->next;         if(s!=NULL)             if(s->coef>=0) printf("+");     }     printf("\n"); }  int main() {     Polylist polya,polyb;     polycreate(polya);     polycreate(polyb);     PrintPoly(polyadd(polya,polyb));  } 供参考～ 能编译通过但是不能结果不对

引用 1 楼 自信男孩的回复:#include <stdio.h> #include <stdlib.h>  typedef struct Polynode {     int coef,exp;     struct Polynode *next;  }Polynode,*Polylist;  void polycreate(Polylist &head) {     Polylist rear,s; int c,e;      head=(Polynode *)malloc(sizeof(Polynode));     if (!head)         exit(0);      rear=head;      scanf("%d %d",&c,&e);      while(c!=0){          s=(Polynode *)malloc(sizeof(Polynode));         if (!s)             exit(0);         s->coef=c;         s->exp=e;          rear->next=s;         rear=s;          scanf("%d %d",&c,&e);     }     rear->next=NULL; } //polyadd(Polylist polya,Polylist polyb) Polylist polyadd(Polylist polya,Polylist polyb) {     Polynode *pa,*pb,*pc,*r, *polyc;     int sum;      polyc = (Polylist)malloc(sizeof(Polynode));     if (!polyc)         exit(0);     pa = polya->next;      //pb=polya->next;     pb=polyb->next;     pc = polyc;   //*pre指向和多项式的尾节点      while(pa!=NULL&&pb!=NULL)      {         if(pa->exp<pb->exp)         {             pc->next=pa; pc=pa; pa=pa->next;}          else if(pa->exp==pb->exp)         {             sum=pa->coef+pb->coef;              if(sum!=0)             {                 pa->coef=sum; pc->next=pa;                  pc=pa;pa=pa->next;                  r=pb;pb=pb->next;free(r);             }             else             {                 r=pa;pa=pa->next;free(r);                  r=pb;pb=pb->next;free(r);             }         } else         {     pc->next=pb; pc=pb; pb=pb->next;}     }     if(pa!=NULL) pc->next=pa;      else pc->next=pb;      return polyc; }  void PrintPoly(Polylist p) {     Polylist s;      s=p->next;      while(s)     {         //printf("%0.2f x^%d",s->coef,s->exp);         printf("%d x^%d",s->coef,s->exp);         s=s->next;         if(s!=NULL)             if(s->coef>=0) printf("+");     }     printf("\n"); }  int main() {     Polylist polya,polyb;     polycreate(polya);     polycreate(polyb);     PrintPoly(polyadd(polya,polyb));  } 供参考～ Poly list polyadd(Polylist polya,Polylist polyb)     polya和polyb之前不应该加引用符号&吗？


Question: 求助

%d只能输出4个字节的内存内容（32位系统下）。而long long是8字节的内存，因此要输出8字节的内容需要用%lld

输出long long类型的数最好用%lld替换%d

数据类型不同,编译器也有关系

引用 25 楼 ggglivw 的回复:文章虽好，还是要以编译器为准，楼主和我都是2017，同样代码他出问题我不出。所以得看编译器设置和实现。一切以代码执行为准引用N个输入对应N个地址 纠正你这个错误

引用 25 楼 ggglivw 的回复:文章虽好，还是要以编译器为准，楼主和我都是2017，同样代码他出问题我不出。所以得看编译器设置和实现。一切以代码执行为准编译器为准就是 题主在出错了 而你认为不会出错 我介绍一下为什么会出错 明白了么

引用 22 楼 ggglivw 的回复:我这边只能看到stdio.h里面的接口实现，看不到内部实现. __crt_va_start和__stdio_common_vfprintf都无法单步跟踪进去。 va_list原理及用法

{         int _Result;         va_list _ArgList;         __crt_va_start(_ArgList, _Format);         _Result = _vfprintf_l(stdout, _Format, NULL, _ArgList);         __crt_va_end(_ArgList);         return _Result;     } 我只能看到这些纯接口，内部实现无法跟踪进入

引用 18 楼 ggglivw的回复:下一个%d，从第二个的地址开始取，再下一个从第三个地址开始取. 所以说 你是没看stdarg.h文件 还是看不懂？ 读了4个字节 第二个%d当然是从第5个字节开始读数据 就是你写的0x00000000FFFFFFFF的高4位

我发现输出这样的结果好像是在输出读取时，是按照连续内存读取的，这应该和编译器有关。

输入类型是动态的，肯定是不会是按照一个类型做吧，而是N个输入对应N个地址，每个地址的取值转换范围由类型决定.

下一个%d，从第二个的地址开始取，再下一个从第三个地址开始取.

数据类型不同

引用 16 楼 ggglivw 的回复:0x00000000ffffffff. 读取的是后面的4字节，只要不超过32的最大值，为啥会出错？下一个 %d 呢?

引用 14 楼 ggglivw 的回复:对啊，我8字节，你解析4字节，不应该出错才对没睡醒? 先去洗脸

对啊，我8字节，你解析4字节，不应该出错才对

引用 12 楼 ggglivw 的回复:过程中确实是用的地址，只是按道理，我大转小不应该出错才对，又不是小转大，放了了不应该访问的地方。不定参数类型 根本不知道你传入参数是多少字节  按照格式确定类型  按照类型确定解析多少个字节 printf看到 %d 就解析4字节  不管你入栈多少字节  没有大转小 没有小转大


Question: C语言解释

引用 3 楼 m0_44977681 的回复：就是运算符优先级的问题 第一行 x，y都非零那么!x  !y都是0，相乘还是0 !!!x相当于!x还是0 第二行 x或i结果为真值1，j-3也不为0，结果还是真值1 x＜y为假，结果为假值0 第三行 c是k的ASC码107，5且c是真值1，j被赋值为8不为0，两者且还是真值1，由于i是1即i＝＝1为真，所以最后结果为真值1 x＋y不为0，最后结果为真值1 输出结果为 0    0 1    0 1    1 不明白优先级和结合性就多查查谢谢

引用 1 楼 老英捉小奇的回复:电脑运行一下就知道了 一个一个试着来 就懂了

电脑运行一下就知道了


Question: C语言金字塔求助！！！

引用 1 楼 老英捉小奇 的回复：#include<stdio.h> int main() {  	int m,n,i,j,k; 	scanf("%d",&n);				//输入行数 	m=2*n-1;					//列数 	for(i=1;i<=n;i++)			//循环次数 	{ 		for(j=i;j<=m/2;j++)		//每行输出的空格 			printf(" "); 		for(k=1;k<=2*i-1;k++)	//每行输出的*号 			printf("*"); 		putchar('\n'); 	} 	return 0; }就是*不太会处理啊 感觉是这里出的问题

引用 1 楼 老英捉小奇的回复:#include<stdio.h> int main() {  	int m,n,i,j,k; 	scanf("%d",&n);				//输入行数 	m=2*n-1;					//列数 	for(i=1;i<=n;i++)			//循环次数 	{ 		for(j=i;j<=m/2;j++)		//每行输出的空格 			printf(" "); 		for(k=1;k<=2*i-1;k++)	//每行输出的*号 			printf("*"); 		putchar('\n'); 	} 	return 0; } 有些花括号不用加的话就别加了，看得眼花缭乱的


Question: 哪位大佬帮看看这个C代码哪里错了，谢谢各位大佬捧场，卑微程序小白跪求

函数grade的形参名与函数内使用不一致，形参名改为array。  另外，程序内有个不好的习惯：       1.函数grade的实参变量m，没有限制其最小、最大值，这样可能会导致指针访问出问题，得不到正确的值，m < 0，指针访问到数组a之前的内存，m>=数组a的行数，则指针访问到数组a之后的内容       2.for循环中 i 值没有初始值（变量i定义时未赋初值），这样可能导致for循环条件不满足而无法循环（ i 初值>=4）；i初值<0，则会导致上面m<0时类似的问题，指针访问异常

double *grade(double (*array)[4], int n)//---arrry改为array

变量名不对 参数变量名是 arrry 处理代码的变量名是 array 修改一致即可


Question: 谢谢各位大佬倾力相助，编程小白弟感激不尽，

22行  就是int mian()  {  对应的大括号

引用 1 楼 ?Victor.??的回复:从错误上说是少了一个大括号  在最后加上即可  程序可以简化一下  考虑一下把闰年判断条件集中一下 在哪个位置少了大括号？能不能帮我写一下，谢谢谢谢，我刚学没有多久，有点懵谢谢大佬

在哪个位置少了大括号？嘿嘿😁有点懵，能不能帮我加一下，刚学没多久

if((a%4 == 0 && a%100!=0) || a%400 == 0)  这一个判断就可以了


Question: 3的倍数

这里的主要问题应该不是编译器不支持变长数组，而是int范围的数组无法储存最大值为10的1000次方，所以要建立数组的话就要建立int a[t][1001]这样的数组，或者说用malloc开辟二维数组。 然后用数组来储存最大值为10的1000次方这样的大数，通过判断每一位数字的和是否能被3整除来判断该大数是否能被3整除。

想使用可变长度数组，五楼正解，但记得用完后free

（1）数组元素的维度必须是常量  （2）超出了int的范围

题目让你注意取值范围你注意了没有 最大值 10的1000次方 写起来就是1后面1000个0 int怎么可能存得下

你说报错了，报的啥错怎么不贴出来？

有的编译器不支持用变量定义数组长度 改成动态申请内存

楼上正解建议申请内存

数组长度需要是固定的，而不能是可变长的。建议用int *a = (int *)malloc(sizeof(int) * t);代替int a[t];


Question: 关于栈的问题 救救小弟吧！

上面某些回复void printstack(sqstack *s) 暴露了太多内部细节，你看看了解一下原理就行，实际开发中不能这样写，你自己独立完成了一个list或者队列，不管好不好，先完成，哪怕你暴露了很多细节。 然后你再去看看std::list, std::deque的接口，思考下别个咋个暴露接口得，有没有暴露很多不应该你知道的细节，当然，现在要你懂std的东西也有点为难你，只是想让你感受下别个的思想，让你知道你和别个的差距在哪里。写代码一定要多写，多思考，思考很重要，如果不思考只会拷贝代码这条路走不长的

引用 7 楼 m0_46472878 的回复:[quote=引用 5 楼 ggglivw的回复:]接口没有定义好，push我就不说了，你至少pop得告诉别个操作结果吧，你如果都取出失败了，你能随便操作？ 老哥，我是真的不太懂这个原理，所以就照着书上写的，一知半解 ，然后就这样了[/quote]  这个不是原理的问题，而是简单常识逻辑问题。你要取出某个东西(pop), 你得告诉别个一个结果，你取成功了还是取失败了。你不告诉结果，你让下一个逻辑如何执行？

感觉好抽象，地址是干什么的，一直不明白

引用 5 楼 ggglivw的回复:接口没有定义好，push我就不说了，你至少pop得告诉别个操作结果吧，你如果都取出失败了，你能随便操作？ 老哥，我是真的不太懂这个原理，所以就照着书上写的，一知半解 ，然后就这样了

引用 3 楼 m0_46472878 的回复:[quote=引用 2 楼 m0_46472878的回复:][quote=引用 1 楼 user-3的回复:]你的原意是想用数组还是链表实现一个栈呢？,看你的意思是想用数组, 我根据你写的写个给你吧 真的C语言对于没有一些计算机基础的人，特别难，你唯一能做的是练习练习 关键还看懂的人，能不能讲到你懂位置，自己还要去体悟，理解需要一个过程 #include <stdio.h> #include <stdlib.h> /*数组实现栈*/ #define MAXSIZE 256 /*程序命名风格，要么都用大写开头，命名类型和函数，要么都用小写 与厦门的sqstack， pop等保持一致，不要混用两种风格 */ typedef  int elemtype;       typedef struct list {     elemtype *bottom;   //命名规范，bottom 对top，，high对low，，     elemtype *top; //既然想通过typedef 来方便修改类型就统一用这个，而不是int*     int capability; //栈的总容量，不是栈中元素个数 }sqstack;  /* 1   变量命名用小写，不要大写 2   sqstack *s 用指针， 就已经表示传的是地址了， 指针变量是变量的一种     都是这么定义的，而不是用&s     调用的时候才用取地址符号     比如 sqstack stack_test；         init(&stack_test) */ /*考虑到栈有建立，就要有响应的销毁过程与之对应 以便释放内存，这里将init改成create， 同时新增destroy函数*/  /* return: 0成功， 1 失败 不要对同一个s重复调用，否则会内存泄漏 */ int create(sqstack *s) {     s->bottom = (elemtype *)malloc(MAXSIZE * sizeof(elemtype)); //*申请连续空间----,而不是申请一个     if(!s->bottom){ //等价于 if(s->bottom == NULL)         printf("malloc memory error\n");         return 1;     }     s->top = s->bottom; //指针访问成员，用箭头->，而不是.     s->capability = MAXSIZE;     return 0;       // } /*要求使用者很小心，必须是成功create过的s，才能调用*/ void destroy(sqstack *s) {     if(s->bottom)   //bottom是不变的，用于记录申请的空间，     {         free(s->bottom);         s->bottom = NULL;     }     return; }  int push(sqstack *s, elemtype e) {     /*指针让人产生歧义的地方，有时候图方便，你会想当然的认为，要取栈顶元素，直接拿top就是了 	 * 事实上，要取栈顶元素的时候，是top-1，而不是top！！ 	 * 既然top开始指向可放元素的地方，即入栈位置，那么他表示top入完栈之后，你把他加1, 显然top指示的是一个未知元素，，， 	 * 继续看后面的实现，就知道top指针多尴尬     */     if(s->top - s->bottom == s->capability)     {         //栈满了，扩容         printf("stack full, realloc a larger space\n");         elemtype *new_ptr = (elemtype *)realloc(s->bottom, s->capability * 2);         if(new_ptr == NULL)//重新分配失败，原来的保留         {             printf("fail to realloc more memory\n");             return 1;         }         s->bottom = new_ptr;         s->capability = 2 * s->capability;     }          *s->top++ = e;     return 0; }  /* return : 0 ok,  1 err 栈为空，无法再弹出(pop)元素出来 */ int pop(sqstack *s, elemtype *e) {     if(s->top == s->bottom)     {         printf("stack is empty\n");         return 1;     }      *e = *--s->top;     return 0; } /*自顶向下打印栈*/ void printstack(sqstack *s) {     /*     这里要减1，用简单情况进行推理     比如栈只有1个元素的时候，这个元素就在第0个位置     C语言连续内存，比如数组，总是从0开始     */     if(s->top == s->bottom)      {         printf("stack is empty, nothing in it\n");         return;     }       printf("print stack s from top to bottom\n"); 	elemtype *itor = s->top;	//因为只是打印，不要去改变这个栈，所以用临时变量来进行遍历     while (itor != s->bottom)	//虽然是很不好的风格，，谁让你用指针呢, 而且指针绕到你头疼     {         /*这里假定elemtype 是int(用%d打印)，这就是C语言麻烦的地方         先不多扯了，想想如果是double，是不是要另外写函数，         一般要用函数指针来实现，你先了解下就好*/          /*%d 后面有空格，2d表示用两个位置来打印一个数，         额额，如果3位数? 3d，如果不确定几位，那就不对齐了，，，         这里只是在对比的时候能对齐，好看*/         printf("%2d ", *--itor);	//如果用 *--s->top;,,那你一边打印，一遍出栈了。。。     }     printf("\n");   //换行 } /*反转栈  虽然这样写比较没效率，但是想象一下 你有一叠盘子，嗯，底下的盘子大，上面的盘子小 现在，你从顶部开始一个一个拿下来，一次叠到另外一个地方,想象一下        -                  ----        --     -->          ---        ---                  --        ----                  -       */ /*略去了错误处理，你可以考虑下，可能哪里会异常 为了配合create，并演示上面的过程，这个实现显得有些古怪，你习惯就好*/ void reverse(sqstack *s) {     sqstack tmp;    //你把盘子拿出来，总得有地方放，弄一个tmp栈来接纳他     create(&tmp);      /*反转的过程*/     while(s->top != s->bottom)     {         elemtype e;         pop(s, &e); //出栈，弹出元素暂时放到e         push(&tmp, e);  //入栈，盘子从s拿出来，放到tmp，一次循环拿一个         //这里不用执行s->size --, tmp->size++ 因为在pop和push中做了     }     /*到这里，已经成功把元素搬到tmp了，，，     本来规范一点的做法是把新的栈返回给调用者，但是为了沿用你定义的接口     咱们偷梁换柱一下，把内存互换，内存就是容器，想象一下，两叠盘子底下都有个篮子用来装他们     假设篮子都贴着标签，第一个篮子签写着A， 搬动后放到篮子B上面，     问：你如何在不搬动盘子的情况下，让这叠盘子依然在篮子A里面呢（盘子都从A搬到B了）     聪明的你也许已经想到答案了，把篮子B的标签撕下来，然后把篮子A的标签贴到B上，     很流氓是不是？下面的代码就是这么干的 s->bottom就是这个所谓的标签     */     elemtype *labtmp;   //什么？ 换个标签也这么麻烦？要找个地方现暂放一下，而不是把A直接贴到B上     labtmp = s->bottom; //想象一下，把A撕了，暂时贴到一块干净的玻璃上吧，免得把上面的胶水粘没了     s->bottom = tmp.bottom;  //既然A撕掉了，B可以直接贴过来了，A篮子变成了标签B     tmp.bottom = labtmp;    //原来的标签A贴过去，偷梁换柱完成。 	s->top = tmp.top;	//别忘记还有这个      /*至此完成反转 打印出来验证下看*/     //printf("after reverse:\n");     //printstack(s);      destroy(&tmp);      //别忘了tmp只是暂时借来放东西的，把他释放掉吧，     /*再次强调，这并不是一个很好的实现，只是为了知识点简单一些，不引入更复杂的技巧的情况下的无奈之举*/ }  int main () {     sqstack s;     int e;  //从数字几开始入栈     int count;  //推几个数字入栈     char buf[256];  //存放用户输入      printf("enter the start num:\n");     fgets(buf, 256, stdin);  //stdin 表示标准输入     e = atoi(buf);		//字符串解释成整型     printf("enter the total count \n");     fgets(buf, 256, stdin);     count = atoi(buf);      if(create(&s) != 0){         return -1;     }      while(count > 0)     {         push(&s, e);         e++;         count--;     }      printf("origin stack :\n");     printstack(&s);      reverse(&s);      printf("after reverse:\n");     printstack(&s);      destroy(&s);     return 0; }    附上我在linux环境下的编译运行过程    顺带说一下，你要注意提问题的方式，提问的时候，最好是源代码复制上来，而不是贴图 这样别人在阅读和修改你的代码都会很方便，千万千万别截图，这是尊重他人的体现。 想让人帮忙，但是截图简直是浪费别人时间。 感觉CSDN这个社区已经运营得烂掉了，没人在乎你是否截图提问，只知道骗人买会员，， 哇  早上醒来就看见这么多代码 还有讲解， 好感动 ，老哥 我是一名学生 前面根本不学习，现在后悔了想学了 就是看不懂了 哎   谢谢老哥  老哥我关注你一下吧  [/quote] 以后会附代码的，我也是不知道， c语言我真的是一知半解， 算得上是半路出家，难一点我就不会，尤其是指针，总是懵逼，但这东西也不能着急，就得慢慢消化，所以我现在很煎熬  害~[/quote]  对指针我有一种理解，可以参考： 指针就是int，只不过是特殊的int。特殊在它被明确指出其内容应是一个地址。  int a = 0； void* p = &a; //就相当于有一个int p 存了a的地址。  指针的使用： int x = *p//相当于把地址对应的位置开始取一个int（整数）出来。 然后就没了。理解一句话就足够了：指针就是int，只不过是特殊的int。特殊在它被明确指出其内容应是一个地址。

引用 2 楼 m0_46472878的回复:[quote=引用 1 楼 user-3的回复:]你的原意是想用数组还是链表实现一个栈呢？,看你的意思是想用数组, 我根据你写的写个给你吧 真的C语言对于没有一些计算机基础的人，特别难，你唯一能做的是练习练习 关键还看懂的人，能不能讲到你懂位置，自己还要去体悟，理解需要一个过程 #include <stdio.h> #include <stdlib.h> /*数组实现栈*/ #define MAXSIZE 256 /*程序命名风格，要么都用大写开头，命名类型和函数，要么都用小写 与厦门的sqstack， pop等保持一致，不要混用两种风格 */ typedef  int elemtype;       typedef struct list {     elemtype *bottom;   //命名规范，bottom 对top，，high对low，，     elemtype *top; //既然想通过typedef 来方便修改类型就统一用这个，而不是int*     int capability; //栈的总容量，不是栈中元素个数 }sqstack;  /* 1   变量命名用小写，不要大写 2   sqstack *s 用指针， 就已经表示传的是地址了， 指针变量是变量的一种     都是这么定义的，而不是用&s     调用的时候才用取地址符号     比如 sqstack stack_test；         init(&stack_test) */ /*考虑到栈有建立，就要有响应的销毁过程与之对应 以便释放内存，这里将init改成create， 同时新增destroy函数*/  /* return: 0成功， 1 失败 不要对同一个s重复调用，否则会内存泄漏 */ int create(sqstack *s) {     s->bottom = (elemtype *)malloc(MAXSIZE * sizeof(elemtype)); //*申请连续空间----,而不是申请一个     if(!s->bottom){ //等价于 if(s->bottom == NULL)         printf("malloc memory error\n");         return 1;     }     s->top = s->bottom; //指针访问成员，用箭头->，而不是.     s->capability = MAXSIZE;     return 0;       // } /*要求使用者很小心，必须是成功create过的s，才能调用*/ void destroy(sqstack *s) {     if(s->bottom)   //bottom是不变的，用于记录申请的空间，     {         free(s->bottom);         s->bottom = NULL;     }     return; }  int push(sqstack *s, elemtype e) {     /*指针让人产生歧义的地方，有时候图方便，你会想当然的认为，要取栈顶元素，直接拿top就是了 	 * 事实上，要取栈顶元素的时候，是top-1，而不是top！！ 	 * 既然top开始指向可放元素的地方，即入栈位置，那么他表示top入完栈之后，你把他加1, 显然top指示的是一个未知元素，，， 	 * 继续看后面的实现，就知道top指针多尴尬     */     if(s->top - s->bottom == s->capability)     {         //栈满了，扩容         printf("stack full, realloc a larger space\n");         elemtype *new_ptr = (elemtype *)realloc(s->bottom, s->capability * 2);         if(new_ptr == NULL)//重新分配失败，原来的保留         {             printf("fail to realloc more memory\n");             return 1;         }         s->bottom = new_ptr;         s->capability = 2 * s->capability;     }          *s->top++ = e;     return 0; }  /* return : 0 ok,  1 err 栈为空，无法再弹出(pop)元素出来 */ int pop(sqstack *s, elemtype *e) {     if(s->top == s->bottom)     {         printf("stack is empty\n");         return 1;     }      *e = *--s->top;     return 0; } /*自顶向下打印栈*/ void printstack(sqstack *s) {     /*     这里要减1，用简单情况进行推理     比如栈只有1个元素的时候，这个元素就在第0个位置     C语言连续内存，比如数组，总是从0开始     */     if(s->top == s->bottom)      {         printf("stack is empty, nothing in it\n");         return;     }       printf("print stack s from top to bottom\n"); 	elemtype *itor = s->top;	//因为只是打印，不要去改变这个栈，所以用临时变量来进行遍历     while (itor != s->bottom)	//虽然是很不好的风格，，谁让你用指针呢, 而且指针绕到你头疼     {         /*这里假定elemtype 是int(用%d打印)，这就是C语言麻烦的地方         先不多扯了，想想如果是double，是不是要另外写函数，         一般要用函数指针来实现，你先了解下就好*/          /*%d 后面有空格，2d表示用两个位置来打印一个数，         额额，如果3位数? 3d，如果不确定几位，那就不对齐了，，，         这里只是在对比的时候能对齐，好看*/         printf("%2d ", *--itor);	//如果用 *--s->top;,,那你一边打印，一遍出栈了。。。     }     printf("\n");   //换行 } /*反转栈  虽然这样写比较没效率，但是想象一下 你有一叠盘子，嗯，底下的盘子大，上面的盘子小 现在，你从顶部开始一个一个拿下来，一次叠到另外一个地方,想象一下        -                  ----        --     -->          ---        ---                  --        ----                  -       */ /*略去了错误处理，你可以考虑下，可能哪里会异常 为了配合create，并演示上面的过程，这个实现显得有些古怪，你习惯就好*/ void reverse(sqstack *s) {     sqstack tmp;    //你把盘子拿出来，总得有地方放，弄一个tmp栈来接纳他     create(&tmp);      /*反转的过程*/     while(s->top != s->bottom)     {         elemtype e;         pop(s, &e); //出栈，弹出元素暂时放到e         push(&tmp, e);  //入栈，盘子从s拿出来，放到tmp，一次循环拿一个         //这里不用执行s->size --, tmp->size++ 因为在pop和push中做了     }     /*到这里，已经成功把元素搬到tmp了，，，     本来规范一点的做法是把新的栈返回给调用者，但是为了沿用你定义的接口     咱们偷梁换柱一下，把内存互换，内存就是容器，想象一下，两叠盘子底下都有个篮子用来装他们     假设篮子都贴着标签，第一个篮子签写着A， 搬动后放到篮子B上面，     问：你如何在不搬动盘子的情况下，让这叠盘子依然在篮子A里面呢（盘子都从A搬到B了）     聪明的你也许已经想到答案了，把篮子B的标签撕下来，然后把篮子A的标签贴到B上，     很流氓是不是？下面的代码就是这么干的 s->bottom就是这个所谓的标签     */     elemtype *labtmp;   //什么？ 换个标签也这么麻烦？要找个地方现暂放一下，而不是把A直接贴到B上     labtmp = s->bottom; //想象一下，把A撕了，暂时贴到一块干净的玻璃上吧，免得把上面的胶水粘没了     s->bottom = tmp.bottom;  //既然A撕掉了，B可以直接贴过来了，A篮子变成了标签B     tmp.bottom = labtmp;    //原来的标签A贴过去，偷梁换柱完成。 	s->top = tmp.top;	//别忘记还有这个      /*至此完成反转 打印出来验证下看*/     //printf("after reverse:\n");     //printstack(s);      destroy(&tmp);      //别忘了tmp只是暂时借来放东西的，把他释放掉吧，     /*再次强调，这并不是一个很好的实现，只是为了知识点简单一些，不引入更复杂的技巧的情况下的无奈之举*/ }  int main () {     sqstack s;     int e;  //从数字几开始入栈     int count;  //推几个数字入栈     char buf[256];  //存放用户输入      printf("enter the start num:\n");     fgets(buf, 256, stdin);  //stdin 表示标准输入     e = atoi(buf);		//字符串解释成整型     printf("enter the total count \n");     fgets(buf, 256, stdin);     count = atoi(buf);      if(create(&s) != 0){         return -1;     }      while(count > 0)     {         push(&s, e);         e++;         count--;     }      printf("origin stack :\n");     printstack(&s);      reverse(&s);      printf("after reverse:\n");     printstack(&s);      destroy(&s);     return 0; }    附上我在linux环境下的编译运行过程    顺带说一下，你要注意提问题的方式，提问的时候，最好是源代码复制上来，而不是贴图 这样别人在阅读和修改你的代码都会很方便，千万千万别截图，这是尊重他人的体现。 想让人帮忙，但是截图简直是浪费别人时间。 感觉CSDN这个社区已经运营得烂掉了，没人在乎你是否截图提问，只知道骗人买会员，， 哇  早上醒来就看见这么多代码 还有讲解， 好感动 ，老哥 我是一名学生 前面根本不学习，现在后悔了想学了 就是看不懂了 哎   谢谢老哥  老哥我关注你一下吧  [/quote] 以后会附代码的，我也是不知道😂， c语言我真的是一知半解， 算得上是半路出家，难一点我就不会，尤其是指针，总是懵逼，但这东西也不能着急，就得慢慢消化，所以我现在很煎熬  害~

引用 1 楼 user-3的回复:你的原意是想用数组还是链表实现一个栈呢？,看你的意思是想用数组, 我根据你写的写个给你吧 真的C语言对于没有一些计算机基础的人，特别难，你唯一能做的是练习练习 关键还看懂的人，能不能讲到你懂位置，自己还要去体悟，理解需要一个过程 #include <stdio.h> #include <stdlib.h> /*数组实现栈*/ #define MAXSIZE 256 /*程序命名风格，要么都用大写开头，命名类型和函数，要么都用小写 与厦门的sqstack， pop等保持一致，不要混用两种风格 */ typedef  int elemtype;       typedef struct list {     elemtype *bottom;   //命名规范，bottom 对top，，high对low，，     elemtype *top; //既然想通过typedef 来方便修改类型就统一用这个，而不是int*     int capability; //栈的总容量，不是栈中元素个数 }sqstack;  /* 1   变量命名用小写，不要大写 2   sqstack *s 用指针， 就已经表示传的是地址了， 指针变量是变量的一种     都是这么定义的，而不是用&s     调用的时候才用取地址符号     比如 sqstack stack_test；         init(&stack_test) */ /*考虑到栈有建立，就要有响应的销毁过程与之对应 以便释放内存，这里将init改成create， 同时新增destroy函数*/  /* return: 0成功， 1 失败 不要对同一个s重复调用，否则会内存泄漏 */ int create(sqstack *s) {     s->bottom = (elemtype *)malloc(MAXSIZE * sizeof(elemtype)); //*申请连续空间----,而不是申请一个     if(!s->bottom){ //等价于 if(s->bottom == NULL)         printf("malloc memory error\n");         return 1;     }     s->top = s->bottom; //指针访问成员，用箭头->，而不是.     s->capability = MAXSIZE;     return 0;       // } /*要求使用者很小心，必须是成功create过的s，才能调用*/ void destroy(sqstack *s) {     if(s->bottom)   //bottom是不变的，用于记录申请的空间，     {         free(s->bottom);         s->bottom = NULL;     }     return; }  int push(sqstack *s, elemtype e) {     /*指针让人产生歧义的地方，有时候图方便，你会想当然的认为，要取栈顶元素，直接拿top就是了 	 * 事实上，要取栈顶元素的时候，是top-1，而不是top！！ 	 * 既然top开始指向可放元素的地方，即入栈位置，那么他表示top入完栈之后，你把他加1, 显然top指示的是一个未知元素，，， 	 * 继续看后面的实现，就知道top指针多尴尬     */     if(s->top - s->bottom == s->capability)     {         //栈满了，扩容         printf("stack full, realloc a larger space\n");         elemtype *new_ptr = (elemtype *)realloc(s->bottom, s->capability * 2);         if(new_ptr == NULL)//重新分配失败，原来的保留         {             printf("fail to realloc more memory\n");             return 1;         }         s->bottom = new_ptr;         s->capability = 2 * s->capability;     }          *s->top++ = e;     return 0; }  /* return : 0 ok,  1 err 栈为空，无法再弹出(pop)元素出来 */ int pop(sqstack *s, elemtype *e) {     if(s->top == s->bottom)     {         printf("stack is empty\n");         return 1;     }      *e = *--s->top;     return 0; } /*自顶向下打印栈*/ void printstack(sqstack *s) {     /*     这里要减1，用简单情况进行推理     比如栈只有1个元素的时候，这个元素就在第0个位置     C语言连续内存，比如数组，总是从0开始     */     if(s->top == s->bottom)      {         printf("stack is empty, nothing in it\n");         return;     }       printf("print stack s from top to bottom\n"); 	elemtype *itor = s->top;	//因为只是打印，不要去改变这个栈，所以用临时变量来进行遍历     while (itor != s->bottom)	//虽然是很不好的风格，，谁让你用指针呢, 而且指针绕到你头疼     {         /*这里假定elemtype 是int(用%d打印)，这就是C语言麻烦的地方         先不多扯了，想想如果是double，是不是要另外写函数，         一般要用函数指针来实现，你先了解下就好*/          /*%d 后面有空格，2d表示用两个位置来打印一个数，         额额，如果3位数? 3d，如果不确定几位，那就不对齐了，，，         这里只是在对比的时候能对齐，好看*/         printf("%2d ", *--itor);	//如果用 *--s->top;,,那你一边打印，一遍出栈了。。。     }     printf("\n");   //换行 } /*反转栈  虽然这样写比较没效率，但是想象一下 你有一叠盘子，嗯，底下的盘子大，上面的盘子小 现在，你从顶部开始一个一个拿下来，一次叠到另外一个地方,想象一下        -                  ----        --     -->          ---        ---                  --        ----                  -       */ /*略去了错误处理，你可以考虑下，可能哪里会异常 为了配合create，并演示上面的过程，这个实现显得有些古怪，你习惯就好*/ void reverse(sqstack *s) {     sqstack tmp;    //你把盘子拿出来，总得有地方放，弄一个tmp栈来接纳他     create(&tmp);      /*反转的过程*/     while(s->top != s->bottom)     {         elemtype e;         pop(s, &e); //出栈，弹出元素暂时放到e         push(&tmp, e);  //入栈，盘子从s拿出来，放到tmp，一次循环拿一个         //这里不用执行s->size --, tmp->size++ 因为在pop和push中做了     }     /*到这里，已经成功把元素搬到tmp了，，，     本来规范一点的做法是把新的栈返回给调用者，但是为了沿用你定义的接口     咱们偷梁换柱一下，把内存互换，内存就是容器，想象一下，两叠盘子底下都有个篮子用来装他们     假设篮子都贴着标签，第一个篮子签写着A， 搬动后放到篮子B上面，     问：你如何在不搬动盘子的情况下，让这叠盘子依然在篮子A里面呢（盘子都从A搬到B了）     聪明的你也许已经想到答案了，把篮子B的标签撕下来，然后把篮子A的标签贴到B上，     很流氓是不是？下面的代码就是这么干的 s->bottom就是这个所谓的标签     */     elemtype *labtmp;   //什么？ 换个标签也这么麻烦？要找个地方现暂放一下，而不是把A直接贴到B上     labtmp = s->bottom; //想象一下，把A撕了，暂时贴到一块干净的玻璃上吧，免得把上面的胶水粘没了     s->bottom = tmp.bottom;  //既然A撕掉了，B可以直接贴过来了，A篮子变成了标签B     tmp.bottom = labtmp;    //原来的标签A贴过去，偷梁换柱完成。 	s->top = tmp.top;	//别忘记还有这个      /*至此完成反转 打印出来验证下看*/     //printf("after reverse:\n");     //printstack(s);      destroy(&tmp);      //别忘了tmp只是暂时借来放东西的，把他释放掉吧，     /*再次强调，这并不是一个很好的实现，只是为了知识点简单一些，不引入更复杂的技巧的情况下的无奈之举*/ }  int main () {     sqstack s;     int e;  //从数字几开始入栈     int count;  //推几个数字入栈     char buf[256];  //存放用户输入      printf("enter the start num:\n");     fgets(buf, 256, stdin);  //stdin 表示标准输入     e = atoi(buf);		//字符串解释成整型     printf("enter the total count \n");     fgets(buf, 256, stdin);     count = atoi(buf);      if(create(&s) != 0){         return -1;     }      while(count > 0)     {         push(&s, e);         e++;         count--;     }      printf("origin stack :\n");     printstack(&s);      reverse(&s);      printf("after reverse:\n");     printstack(&s);      destroy(&s);     return 0; }    附上我在linux环境下的编译运行过程    顺带说一下，你要注意提问题的方式，提问的时候，最好是源代码复制上来，而不是贴图 这样别人在阅读和修改你的代码都会很方便，千万千万别截图，这是尊重他人的体现。 想让人帮忙，但是截图简直是浪费别人时间。 感觉CSDN这个社区已经运营得烂掉了，没人在乎你是否截图提问，只知道骗人买会员，， 哇  早上醒来就看见这么多代码 还有讲解， 好感动 ，老哥 我是一名学生 前面根本不学习，现在后悔了想学了 就是看不懂了 哎   谢谢老哥  老哥我关注你一下吧


Question: visual studio 直接把.c 和.h文件复制进项目不行吗？

你电脑卡了吧。。。。


Question: 答案是不是这样啊

引用 4 楼 user-1的回复:最后一个你是15.6000吧，不是 156.000吧 可能写的时候没注意

最后一个你是15.6000吧，不是 156.000吧

引用 2 楼 weixin_46294972 的回复:那其他的都正确吗 其它没问题

引用 1 楼 user-1的回复:第四题应该是 2.0 那其他的都正确吗

第四题应该是 2.0


Question: 大二刚学数据结构，程序有bug求请教

最后的核心check逻辑就这么几行             char top = gettop(&L);             /*看新进的字符能否关闭掉栈顶*/             if(close_check((unsigned char)top, (unsigned char)c[i]))             {                 pop(&L, &e);             }             else{                 push(&L, c[i]);             }         }

你的check方式让人看不懂，这个就是类似玩消消乐， （）这种括号对，左边的我们管他叫open，右边的我们管他叫close ()是合法的)(则是非法的，只要close能匹配open，我们就消掉他，否则就压栈进去 又比如 [([)] 看起来是匹配的，但是消不掉，， 你自己弄一些例子，然后一步步手工消解下看，就能明白其中思想了  思想是，看看能跟栈顶匹配就消，（不要入栈，入栈前看能不能消），不能消才入栈， 你的逻辑太复杂了，没有一步一步分解开来，  以下是代码，有做简单测试，可行。 有加了一些注释，希望你能看明白 #include<stdio.h> #include<stdlib.h>  #define maxsize 30  typedef char elemtype; typedef struct stack {     elemtype *top;     elemtype *base; 	int size; }sqstack;  void creatstack(sqstack *L) { 	L->base=(char *)malloc(maxsize*sizeof(char)); 	L->top=L->base; 	L->size = maxsize; } void push(sqstack *L,char x) { 	if(L->top-L->base>=L->size) { 		L->base=(char *)realloc(L->base, (L->size+20)*sizeof(char)); 		L->top=L->base+L->size; 		//L->size = L->size+10; 		L->size = L->size + 20; 	} 	*(L->top) = x; 	L->top++;  }  int pop(sqstack *L,char *e) { 	if(L->top==L->base) { 		printf("栈为空\n"); 		return 1; 	} 	L->top--; 	*e=*(L->top);  	return 0; }  /*返回栈顶元素，注意这里不同于pop操作，只是复制一份出来看看  * 如果栈为空，返回'_'  *这个代码是为了匹配用的，虽然返回'_'怪怪的  只要不与哈希表 g_ch_pair中的内容相同就好了  * */ elemtype gettop(sqstack *L) { 	if(L->top == L->base) 		return '_'; 	else 		return *(L->top - 1); }  /*栈是否为空   如果空返回true 否则返回false*/ int empty(sqstack *l) { 	return l->top == l->base; }   char print(sqstack *L) { 	elemtype *p; 	p=L->top; 	return *(p-2); }  /*简单的匹配哈希*/ static char g_ch_pair[256] = {0}; void init_hash() { 	/*这里有一个隐含条件，只有右括号 ｝ ] )才能找到他对应的东西 	 * 右括号习惯上又叫close， 左括号叫open，打开 	 * 类似于开门，关门，，，， 	 * 我们只有在遇到右括号的时候，匹配才有意义， 	 * 所以用左括号来匹配的时候，返回是默认值0, 肯定不允许关闭*/ 	g_ch_pair[(unsigned char)'}'] = '{'; 	g_ch_pair[(unsigned char)']'] = '['; 	g_ch_pair[(unsigned char)')'] = '('; } /*  *右边是后进来的，看后来者是不是能close掉前者  能关闭则返回成功，否则false  比如left = '{', right = '}' 成功  但是 left = '}', right = '{'是失败的，切记，因为'{'是open标志，是不可能用来关闭别人的  * */ int  close_check(unsigned char left, unsigned char right) { 	return (unsigned char)g_ch_pair[right] == left; }  int main() { 	int i=0; 	char e; 	char c[256]; 	elemtype *p,*q; 	sqstack L; 	creatstack(&L); 	p = L.top; 	//q=L->base; 	q = L.base; 	 	init_hash(); 	printf("请输入字符串："); 	scanf("%s",c);  	while(c[i]!='\0') 	{ 		/*输入有效性检查，确保c 只能是三个字符中的一个*/ 		if(c[i] != '{' && c[i] != '(' && c[i] != '[' 			&&c[i] != '}' && c[i] != ')' && c[i] != ']')  		{ 			printf("非法字符串\n"); 			return 0; 		} 		 		/*	 		 *	因为为空的时候 gettop(&L),会返回 '_' 		 *	因此close_check肯定会失败，那么就会走push流程， 		 *	所以这个empty的代码去掉，因为这个条件下，不用这段代码也会执行相同的操作 		if(empty(&L)){ 			push(&L, c[i]); 		} 		else  		*/ 		{ 			char top = gettop(&L); 			/*看新进的字符能否关闭掉栈顶*/ 			if(close_check((unsigned char)top, (unsigned char)c[i])) 			{ 				pop(&L, &e); 			} 			else{ 				push(&L, c[i]); 			} 		} 		i++; 	} 	/*!!!!要赋值,也是在这里赋值 	 *其实更好的方法是调用empty(&L)函数来判断 	 * */ 	p = L.base; 	q = L.top; 	if(p==q) 	{ 		printf("合法字符串\n"); 	} 	else 	{ 		printf("非法字符串\n"); 	} 	return 0; }

p = L.top; 	q = L.base;

#include<stdio.h> #include<stdlib.h>  #define maxsize 30  typedef char elemtype; typedef struct stack {     elemtype *top;     elemtype *base;     int size; }sqstack;  void creatstack(sqstack *L) {     L->base=(char *)malloc(maxsize*sizeof(char));     L->top=L->base;     L->size = maxsize; } void push(sqstack *L,char x) {     if(L->top-L->base>=L->size) {         L->base=(char *)realloc(L->base, (L->size+20)*sizeof(char));         L->top=L->base+L->size;         //L->size = L->size+10;         L->size = L->size + 20;     }     *(L->top) = x;     L->top++;  }  int pop(sqstack *L,char *e) {     if(L->top==L->base) {         printf("栈为空\n");         return 1;     }     L->top--;     *e=*(L->top);      return 0; }  char print(sqstack *L) {     elemtype *p;     p=L->top;     return *(p-2); } int main() {     int i=0;     char e;     char c[30];     elemtype *p,*q;     sqstack L;     creatstack(&L);     //p=L->top;     p = L.top;     //q=L->base;     q = L.base;     printf("请输入字符串：");     scanf("%s",c);      while(c[i]!='\0')     {         if((c[i]=='['||c[i]=='{'||c[i]=='(')&&(i==0))  //第一个为 [ { (         {             push(&L,c[i]);         }         else if((c[i]==']'||c[i]=='}'||c[i]==')')&&(i==0))//第一个为 ] } )         {             printf("非法字符串\n");             return 1;         }         else if((c[i]=='['||c[i]=='{'||c[i]=='(')&&(i!=0))//第二个为[ {  (         {             if(print(&L)==']'||print(&L)=='}'||print(&L)==')')// ][  }{ )( 情况             {                 printf("非法字符串\n");                 return 1;             } else         {             push(&L,c[i]);  // [[  {{ ((  [{ [(情况         }         }         else //if((c==']'||c=='}'||c==')')&&(i!=0))第二个为 ] } )         {             if((print(&L)=='['&&c[i]==']')||(print(&L)=='{'&&c[i]=='}')||(print(&L)=='('&&c[i]==')')) // [] {} ()情况，若不成立则为 [[             {                 pop(&L,&e);             }             else // ]] }} ))情况             {                 push(&L,c[i]);             }     }     i++;     }     if(p==q)     {         printf("合法字符串\n");     }     } 代码编译通过，供参考～  建议楼主把main函数里的if else关系弄清楚了，并且该加的大括号加上大括号。


Question: 求大神告知哪里错了

大括号前面没有小括号 while for 后面不需要加分号 而且这个函数第一个参数不是整数呀 FillRectangle thiz：自身指针变量，类似this指针的变量；属于DirectFB的招牌写法。

两个for后面和while后面都多了分号; 注意分号代表一条一条语句，即while的循环体是；即什么都不执行，是死循环，并且很占CPU，导致你的电脑变卡～

为啥while 和for 后面都有分号

后面的括号呢？


Question: C语言链表查找功能总是失败，请各位帮忙看看到底哪里有问题。

感谢您，我看到我哪里有问题了。 指针那块也没学好。等会在复习一下。

#include<stdio.h> #include<stdlib.h>  typedef struct list {     int data;     //struct lista* next;     struct list* next; }lista;   lista* newlist(int n) {     int i = 0;     lista* listaone; //普通结点     lista* listahead;//头结点     lista* listend; //尾结点     listahead = (lista*)malloc(sizeof(lista));     if (!listahead)         exit(0);     listend = listahead;       for (i = 0; i < n; i++)     {         listaone = (lista*)malloc(sizeof(lista));         scanf("%d", &listaone->data);         listend->next = listaone;         listend = listaone;     }     listend->next = NULL;      return listahead; }  //int foundlist(lista *x) int foundlist(lista *phead) {     lista *x = phead->next;     int j = 0;     int n = 0;     printf("请输入需要查找到数\n");     scanf("%d", &n);     do     {         /*         if (x->data != n) //执行判断不等于         {             x = x->next; // 指向下一个结点         }         else if (x->data == n)         {             j++;//记录次数         }         */         if (x->data == n)             j++;         x = x->next;     } while (x!= NULL);//判断是否为空了，空就退出      return j;//返回e的个数 }  //void main() int main(void) {      lista* f, * y;     int x = 0;     int k = 0;     printf("新建链表，输入需要个数结束\n");     scanf("%d", &k);     f = newlist(k);     y = f;      printf("输入的数为\n");     while (f->next != NULL)     {         f = f->next;         printf("%d", f->data);     }      printf("\n");     x = foundlist(y);     printf("找到该数，出现%d次", x); } 供参考～  参数应该输入y而不是f，因为f已经变化了。 另外，查找函数也有问题，


Question: C语言runtime error的SIGSEGV问题

有一个单词 W，输出它在字符串 S 中从左到右第一次出现的位置 IDX(设 S 中的第 1 个字符的位置为 1)。W 只由英文字母组成，S 除英文字母和汉字之外在任何位置（包括头和尾）另有一个或多个连续的空格。  查找单词时，不区分大小写，但要求完全匹配，即单词 W 必须与 S 中的某一独立单词在不区分大小写的情况下完全匹配。W 仅是 S 中某一单词的一部分就不算匹配。 输入格式  第 1 行：一个整数 T (1≤T≤10) 为问题数。  接下来共 2T 行，对应每个问题有 2 行，表示 W 和 S (1≤W长度≤10;1≤S长度≤1000000)。 输出格式  对于每个问题，输出一行问题的编号（0 开始编号，格式：case #0: 等）。  然后对应每个问题在一行中输出 IDX。 S 中没有找到 W 时输出 None。 样例 Input  3 IN Find a word within a string in English and in Chinese. to     Find a word within a string in English and in Chinese. In     Find a word within a string in English and in Chinese.  Output  case #0: 29 case #1: None case #2: 33


Question: C语言小作业

改一下：用scanf接收3个数据， %d, %d, %d，&year, &month， &day 题目要求往后一个星期，就是加7天呗，你先day+7，并判断month最大是多少天（2月的话还要往前判断year是不是闰年），超过了30天或者31天的month加1，否则day加7就完了。

简单，用scanf接收3个数据，&year, &month， &day， %d, %d, %d，题目要求往后一个星期，就是加7天呗，你先day+7，并判断month最大是多少天（2月的话还要往前判断year是不是闰年），超过了30天或者31天的month加1，否则day加7就完了。


Question: 请问下列程序中的x应如何赋值，才能输出正确结果！！

引用 2 楼 qybao的回复:x不需要输入，而且你少了最后一个else（或者少了个默认值），比如所有的分支都不满足，那x就没有值了。 还有打印格式不对，你这样只是打印一位长度，所以打印结果不对 另外，你的计算公式是不是不对？ int main() {     float x=0.0f, y; //这里要么给x赋个初始值     scans("%f", &y);     if (y<=100000)     {         x = y*0.1f;     }     else if (y>100000 && y<=200000)      {         x = 100000*0.1f + (y-100000)*0.075f; //10万的部分应该是固定的吧，不是用y乘0.1吧？     }     else if (y>200000 && y<=400000)     {         x = 100000*0.1f + 100000*0.075f + (y-200000)*0.05;     }     esle     {         x = 0.0f; //要么这里加个else分支给x赋个默认值     }     printf("%.0f", x); //打印格式，这里给你保留到整数部分     return 0; } 不过确实少了用来限定y>4000000的一个分支！多谢指教！说实话，就怕一个人在那儿抓瞎！

引用 2 楼 qybao的回复:x不需要输入，而且你少了最后一个else（或者少了个默认值），比如所有的分支都不满足，那x就没有值了。 还有打印格式不对，你这样只是打印一位长度，所以打印结果不对 另外，你的计算公式是不是不对？ int main() {     float x=0.0f, y; //这里要么给x赋个初始值     scans("%f", &y);     if (y<=100000)     {         x = y*0.1f;     }     else if (y>100000 && y<=200000)      {         x = 100000*0.1f + (y-100000)*0.075f; //10万的部分应该是固定的吧，不是用y乘0.1吧？     }     else if (y>200000 && y<=400000)     {         x = 100000*0.1f + 100000*0.075f + (y-200000)*0.05;     }     esle     {         x = 0.0f; //要么这里加个else分支给x赋个默认值     }     printf("%.0f", x); //打印格式，这里给你保留到整数部分     return 0; } 不过还是多谢了！

引用 2 楼 qybao的回复:x不需要输入，而且你少了最后一个else（或者少了个默认值），比如所有的分支都不满足，那x就没有值了。 还有打印格式不对，你这样只是打印一位长度，所以打印结果不对 另外，你的计算公式是不是不对？ int main() {     float x=0.0f, y; //这里要么给x赋个初始值     scans("%f", &y);     if (y<=100000)     {         x = y*0.1f;     }     else if (y>100000 && y<=200000)      {         x = 100000*0.1f + (y-100000)*0.075f; //10万的部分应该是固定的吧，不是用y乘0.1吧？     }     else if (y>200000 && y<=400000)     {         x = 100000*0.1f + 100000*0.075f + (y-200000)*0.05;     }     esle     {         x = 0.0f; //要么这里加个else分支给x赋个默认值     }     printf("%.0f", x); //打印格式，这里给你保留到整数部分     return 0; } 100000以下提10%，是指按利润值提相应奖金！不是100000以下，通通以100000为基准，计算奖金的！

说真的，没读懂你的意思，，，x不需要赋值吧，它是通过输入的y计算出来的。


Question: 求助！！vs2013这个情况怎么办

引用 5 楼 weixin_54174104 的回复: 出错信息已经表达了，不要用fp去接受返回值啊，你的fp已经在参数列表里起到作用了。

嗯，第一参数是FILE ** 类型。

您好！我遇到了相同的问题请问你能详细说一下具体怎么解决的吗？谢谢！

引用 1 楼 user-3的回复:fopen_s( FILE* pFile, const char *filename, const char *mode);  打开文件成功返回0，否则返回其他值。  这是函数原型，你看你用法对不对  fopen_s(&fp,"E:\\ngm.txt", "w"); 我已经解决了，谢谢哈

引用 1 楼 user-3的回复:fopen_s( FILE* pFile, const char *filename, const char *mode);  打开文件成功返回0，否则返回其他值。  这是函数原型，你看你用法对不对  fopen_s(&fp,"E:\\ngm.txt", "w"); 谢谢，括号里的已经解决，那请问，第一个不能将“errno_t”类型的值分配到“FILE*”类型的实体，这个怎么解决


Question: 柔性数组中free的问题

引用 1 楼 akari10032 的回复:staff结构体定义里面info前面的*去掉试试， 这样应该是不行，当然我也试了下  void staff_free(staff **worker) {     int Len = (*worker)->num;     //free((*worker)->infor);     for (int i = 0; i < Len; i++)     {         printf("loop: the %d staff addr is %p\n", i, &((*worker)->infor[i]));         free(&((*worker)->infor[i]));     }     free(*worker); }  把改成数组，地址要不以首元素表示free((*worker)->infor);，要不这样free(&((*worker)->infor[i])); 以首元素作为地址应该不行，因为柔性数组，系统不知道我申请了多少。 以第二种方式表示，我试过了。结果如图  其实我觉得错误是我对free没搞明白，虽然是free掉malloc申请的空间。但一般都是对指针指向的free，我没见过直接free空间地址的，我不知道这样可以不，感觉应该没问题，可好像是这样才会段错误的。

staff结构体定义里面info前面的*去掉试试，

引用 7 楼 user-2 的回复:你那样不是指针数组，而是数组指针，不能用数组指针的，因为数组指针需要数组的长度固定 char (*)c[5]; c++;指针会移动 sizeof(char)*5 个字节的地址，如果是柔性数组[]，c++就不知道该移动多少个字节了 正如你所说，你不用指针，用数组就好了 typedef struct _staff {     int num;     info infor[]; //柔性数组 } staff;  (*worker)->infor[1].age = 5;  谢谢

引用 5 楼 user-2 的回复:解释太费劲，你自己好好体会以下代码，好好看注释，看看正确做法和你的非正确做法的区别  struct Empty {     int num;     int *a[]; }; int main(int argc, const char * argv[]) {     int n = 5;     printf("正确做法：\n");     Empty *e = (Empty*)malloc(sizeof(Empty) + sizeof(int*)*n); //注意这里用int*     e->num = n;     for (int i=0; i<e->num; i++) {         e->a[i] = (int*)malloc(sizeof(int)); //申请的内存属于a[i]，所以这个释放a[i]         *e->a[i] = i+1; //能正常赋值         printf("%p, %d\n", e->a[i], *e->a[i]); //注意看这里的内存地址，这里能正常访问*a[i]     }     for (int i=0; i<e->num; i++) {         free(e->a[i]); //因为a[i]申请过内存，所以可以释放内存     }     free(e); //释放内存          printf("非正确做法：\n"); //这就是你的做法     e = (Empty*)malloc(sizeof(Empty) + sizeof(int)*n); //这里用int来申请内存，内存空间比int*大，数组访问没问题m，但a[i]都是野指针     e->num = 5;     for (int i=0; i<e->num; i++) {         //*e->a[i] = i+1; //a[i]是野指针，看看这里赋值是否正常？         //printf("%p, %d\n", e->a[i], *e->a[i]); //注意看这里的内存地址，这里是否能正常访问*a[i]？         printf("%p\n", e->a[i]); //能正常打印地址又如何，还不是野指针一个？     }     for (int i=0; i<e->num; i++) {         //free(e->a[i]); //这里没给a[i]申请过内存，所以不能给a[i]释放内存，也就是不能释放野指针     }     free(e); //申请的内存属于e，所以只能释放e     return 0; } 哦哦，多谢，我其实看到你前面说的就之前已经改成你的这个样子。只是一直没想明白是野指针。  *worker = (staff *)malloc(sizeof(staff) + num * sizeof(info)); 过去是我原来没想明白，柔性数组申请的空间是不是worker指向的，看了你的解释，我可以不写成指针，就写数组，然后free(worker)就行了。 最后一个问题哈，柔性数组是不是不能写指针数组。 typedef struct _staff {     int num;     info (*infor)[]; } staff; 我下面比如这样赋值(*worker)->infor[1]->age = 5;编译器就会告诉我"表达式必须指向完整类型的指针"。我如果不是柔性数组，这样写是没问题的，所以是我写法有问题，还是不支持此种格式？ 但是指针也是数据格式一种，我想应该支持吧？

引用 3 楼 user-2 的回复:free((*worker)->infor[i]); 没问题，问题是你每它分配过内存 你要先分配内存再释放 比如 (*worker)->num = num; printf("worker addr is %p\n", *worker); for (int i = 0; i < num; i++)     //printf("the %d staff addr is %p\n", i, &((*worker)->infor[i]));     (*worker)->infor[i] = (info*)malloc(sizeof(info)); //先申请内存，再释放 不是吧，我*worker = (staff *)malloc(sizeof(staff) + num * sizeof(info));这一开始申请了空间。 我想我知道是咋回事了，我在staff_free函数里又打印了一下，  void staff_free(staff **worker) {     int Len = (*worker)->num;     for (int i = 0; i < Len; i++)     {         printf("loop: the %d staff addr is %p, adr is %p\n", i, &((*worker)->infor[i]), (*worker)->infor[i]);         printf("The free %d worker's info is: age = %d, name = %s\n", i, (*worker)->infor[i]->age, (*worker)->infor[i]->name);         //free((*worker)->infor[i]);     }     free(*worker); }   show loop: the 0 staff addr is 0x887018, adr is 0x7ffe9421d4e0 The 0 worker's info is: age = 10, name = ZhangSan show loop: the 1 staff addr is 0x887020, adr is 0x7ffe9421d4e0 The 1 worker's info is: age = 10, name = ZhangSan show loop: the 2 staff addr is 0x887028, adr is 0x7ffe9421d4e0 The 2 worker's info is: age = 10, name = ZhangSan show loop: the 3 staff addr is 0x887030, adr is 0x7ffe9421d4e0 The 3 worker's info is: age = 10, name = ZhangSan show loop: the 4 staff addr is 0x887038, adr is 0x7ffe9421d4e0 The 4 worker's info is: age = 10, name = ZhangSan show loop: the 5 staff addr is 0x887040, adr is 0x7ffe9421d4e0 The 5 worker's info is: age = 10, name = ZhangSan show loop: the 6 staff addr is 0x887048, adr is 0x7ffe9421d4e0 The 6 worker's info is: age = 10, name = ZhangSan show loop: the 7 staff addr is 0x887050, adr is 0x7ffe9421d4e0 The 7 worker's info is: age = 10, name = ZhangSan show loop: the 8 staff addr is 0x887058, adr is 0x7ffe9421d4e0 The 8 worker's info is: age = 10, name = ZhangSan show loop: the 9 staff addr is 0x887060, adr is 0x7ffe9421d4e0 The 9 worker's info is: age = 10, name = ZhangSan  age应该是1到10的， 结果却是age全为10，有两种可能： 1. 后面的把前面的覆盖了 2. 都指向了最后的一个空间 我感觉第二种可能是对的，因为我free时候，i=0是可以free的，因为这个age是10，是申请过的。后面的没申请，所以不能free。 所以我觉得我打印的两个addr我理解的有问题，我之前理解的第一个&((*worker)->infor[i])应该是那个数组i的空间地址，(*worker)->infor[i]是指针的地址。 但如果是这样，就指向没出问题。我理解的哪里有问题？


Question: c语言萌新调试遇到问题

引用 1 楼 老英捉小奇的回复:除以3.0      ， 谢谢谢谢大佬

引用 2 楼 chxchxkkk的回复:1、写的c程序，文件后缀名 cpp 改为 c 更符合要求 。 2、a 要么定义成 int a,  要么就像楼上兄弟说的 / 3.0 谢谢谢谢谢谢大佬

除以3.0      ，


Question: 请看一下这一段代码错在什么地方

给定一个句子，要求将其字符重新排序输出，其中的英文字母按照字母表顺序输出，其他字符的顺序和位置不变，输出后的单词长度与原句子相同。 输入格式  第 1 行：一个整数 T (1≤T≤10) 为问题数。  第 2 ~T+1 行，每组测试数据一行，包括一个字符串（长度最大为 200），由英文字母（均为大写字母）及其他字符组成，由空格分开的连续字符串视作一个单词。 输出格式  对于每个问题，输出一行问题的编号（0 开始编号，格式：case #0: 等），然后在一行中输出重新排序后的字符串。 样例 Input  3 THE BREAD IS SOLD AT $10 PER POUND 500 DONGCHUAN ROAD EAST CHINA NORMAL UNIVERSITY SHANGHAI CHINA 200241 #9724 $500 1234  Output  case #0: AAB DDDEE EH ILNO OP $10 PRR SSTTU case #1: 500 AAAAAAAAC CCDD EEGG HHHHH IIIIIL MNNNNNNNOO ORRRSSST TUUVY 200241 case #2: #9724 $500 1234


Question: a=2,printf("a++=%d\n,++a=%d",a++,++a),为什么输出a++=3,++a=4,不应该是a++=2,++a=4吗？

有些编译器 printf是从右向左结合的。

1. 项目中没有人写这种代码 2. 考试中应该也不会考， 因为不同编译器可能会有不同的行为。 3. 如果楼主真想了解原因，可以简单学一点汇编，把代码反编译出汇编代码，一目了然。而且这个程序用到的汇编知识不多，了解一点就可以。

谁出的题或者谁让做的题。 给它两jio。 记住一个事情就是了。 实际使用中： 只有两种用法：  i++；//<=>i+=1; ++i；//<=>i+=1;  避免了不必要的歧义；可读性强 两行代码。完了

这个问题没有研究的必要，如果在公司这么写要挨骂的，相信我，你会被骂得狗血淋头的.

建议楼主这种问题不要钻进去过于研究了，问题正如楼上所说。另外，在项目中写代码时，正常人不会这样写的，否则会被吐槽。


Question: 求助！我想写一个既可以两个数字运算也可以三个数字运算的代码，写出来之后却不能运行。求大家帮忙指点一下！

没太看懂，可以再看一下

引用 18 楼 千梦一生的回复:[quote=引用 17 楼 千梦一生 的回复:] [quote=引用 16 楼 qq_46499695 的回复:] [quote=引用 12 楼 Chen_jiajie1234的回复:]换个思路：一次只运算两个数，得出的结果保存在变量iSum里。下次输入另一个数和运算符号，跟iSum运算，得出的结果仍保存到iSum里。这样不就实现了三个数的预算了吗？ 我去试试。谢谢。[/quote]   #include<stdio.h> int main() { 	float  a, b, c; 	int leap; 	char m, n; 	printf("please:"); 	scanf("%f%c%f", &a, &m, &b);//输入表达式  	n = getchar(); 	if(n == '\n') 		leap = 3; 	else 	{ 		leap = 5; 		scanf("%f", &c); 	} 	switch (leap)//判断是两个数字计算     	{ 	case 3: 		switch (m) 		{ 		case '+':printf("%f", a + b);//加法 			break; 		case '-':printf("%f", a - b);//减法 			break; 		case '*':printf("%f", a*b);//乘法 			break; 		case '/':printf("%f", a / b);//除法    			break; 		default:printf("error"); 		} 		break; 	case 5: 		switch (m)//三个数运算 		{ 		case '+': 			switch (n)//加法  			{ 			case '+':printf("%f", a + b + c);//加法     				break; 			case '-':printf("%f", a + b - c);//减法     				break; 			default:printf("error"); 			} 			break; 		case '-': 			switch (n)//减法    			{ 			case '+': 				printf("%f", a - b + c);//加法    				break; 			case '-': 				printf("%f", a - b - c);//减法     				break; 			default: 				printf("error"); 			} 			break; 		} 	} }   这样搞就能运行起来就能感觉稍微人性化了一点。 那个你需要的是搞明白 scanf和getchar这些函数的功能[/quote]  我这里只测试过加法。没有测试其它算法。代码写的很有趣，从代码就能看出来你是一个很有想法的人。蛮不错的。加油！[/quote] 可以跑了！哈哈哈，谢谢！

引用 18 楼 千梦一生的回复:[quote=引用 17 楼 千梦一生 的回复:] [quote=引用 16 楼 qq_46499695 的回复:] [quote=引用 12 楼 Chen_jiajie1234的回复:]换个思路：一次只运算两个数，得出的结果保存在变量iSum里。下次输入另一个数和运算符号，跟iSum运算，得出的结果仍保存到iSum里。这样不就实现了三个数的预算了吗？ 我去试试。谢谢。[/quote]   #include<stdio.h> int main() { 	float  a, b, c; 	int leap; 	char m, n; 	printf("please:"); 	scanf("%f%c%f", &a, &m, &b);//输入表达式  	n = getchar(); 	if(n == '\n') 		leap = 3; 	else 	{ 		leap = 5; 		scanf("%f", &c); 	} 	switch (leap)//判断是两个数字计算     	{ 	case 3: 		switch (m) 		{ 		case '+':printf("%f", a + b);//加法 			break; 		case '-':printf("%f", a - b);//减法 			break; 		case '*':printf("%f", a*b);//乘法 			break; 		case '/':printf("%f", a / b);//除法    			break; 		default:printf("error"); 		} 		break; 	case 5: 		switch (m)//三个数运算 		{ 		case '+': 			switch (n)//加法  			{ 			case '+':printf("%f", a + b + c);//加法     				break; 			case '-':printf("%f", a + b - c);//减法     				break; 			default:printf("error"); 			} 			break; 		case '-': 			switch (n)//减法    			{ 			case '+': 				printf("%f", a - b + c);//加法    				break; 			case '-': 				printf("%f", a - b - c);//减法     				break; 			default: 				printf("error"); 			} 			break; 		} 	} }   这样搞就能运行起来就能感觉稍微人性化了一点。 那个你需要的是搞明白 scanf和getchar这些函数的功能[/quote]  我这里只测试过加法。没有测试其它算法。代码写的很有趣，从代码就能看出来你是一个很有想法的人。蛮不错的。加油！[/quote] 嗯嗯，谢谢了！多谢！

引用 17 楼 千梦一生 的回复:[quote=引用 16 楼 qq_46499695 的回复:] [quote=引用 12 楼 Chen_jiajie1234的回复:]换个思路：一次只运算两个数，得出的结果保存在变量iSum里。下次输入另一个数和运算符号，跟iSum运算，得出的结果仍保存到iSum里。这样不就实现了三个数的预算了吗？ 我去试试。谢谢。[/quote]   #include<stdio.h> int main() { 	float  a, b, c; 	int leap; 	char m, n; 	printf("please:"); 	scanf("%f%c%f", &a, &m, &b);//输入表达式  	n = getchar(); 	if(n == '\n') 		leap = 3; 	else 	{ 		leap = 5; 		scanf("%f", &c); 	} 	switch (leap)//判断是两个数字计算     	{ 	case 3: 		switch (m) 		{ 		case '+':printf("%f", a + b);//加法 			break; 		case '-':printf("%f", a - b);//减法 			break; 		case '*':printf("%f", a*b);//乘法 			break; 		case '/':printf("%f", a / b);//除法    			break; 		default:printf("error"); 		} 		break; 	case 5: 		switch (m)//三个数运算 		{ 		case '+': 			switch (n)//加法  			{ 			case '+':printf("%f", a + b + c);//加法     				break; 			case '-':printf("%f", a + b - c);//减法     				break; 			default:printf("error"); 			} 			break; 		case '-': 			switch (n)//减法    			{ 			case '+': 				printf("%f", a - b + c);//加法    				break; 			case '-': 				printf("%f", a - b - c);//减法     				break; 			default: 				printf("error"); 			} 			break; 		} 	} }   这样搞就能运行起来就能感觉稍微人性化了一点。 那个你需要的是搞明白 scanf和getchar这些函数的功能[/quote]  我这里只测试过加法。没有测试其它算法。代码写的很有趣，从代码就能看出来你是一个很有想法的人。蛮不错的。加油！

引用 12 楼 Chen_jiajie1234的回复:换个思路：一次只运算两个数，得出的结果保存在变量iSum里。下次输入另一个数和运算符号，跟iSum运算，得出的结果仍保存到iSum里。这样不就实现了三个数的预算了吗？ 我去试试。谢谢。

引用 16 楼 qq_46499695 的回复:[quote=引用 12 楼 Chen_jiajie1234的回复:]换个思路：一次只运算两个数，得出的结果保存在变量iSum里。下次输入另一个数和运算符号，跟iSum运算，得出的结果仍保存到iSum里。这样不就实现了三个数的预算了吗？ 我去试试。谢谢。[/quote]   #include<stdio.h> int main() { 	float  a, b, c; 	int leap; 	char m, n; 	printf("please:"); 	scanf("%f%c%f", &a, &m, &b);//输入表达式  	n = getchar(); 	if(n == '\n') 		leap = 3; 	else 	{ 		leap = 5; 		scanf("%f", &c); 	} 	switch (leap)//判断是两个数字计算     	{ 	case 3: 		switch (m) 		{ 		case '+':printf("%f", a + b);//加法 			break; 		case '-':printf("%f", a - b);//减法 			break; 		case '*':printf("%f", a*b);//乘法 			break; 		case '/':printf("%f", a / b);//除法    			break; 		default:printf("error"); 		} 		break; 	case 5: 		switch (m)//三个数运算 		{ 		case '+': 			switch (n)//加法  			{ 			case '+':printf("%f", a + b + c);//加法     				break; 			case '-':printf("%f", a + b - c);//减法     				break; 			default:printf("error"); 			} 			break; 		case '-': 			switch (n)//减法    			{ 			case '+': 				printf("%f", a - b + c);//加法    				break; 			case '-': 				printf("%f", a - b - c);//减法     				break; 			default: 				printf("error"); 			} 			break; 		} 	} }   这样搞就能运行起来就能感觉稍微人性化了一点。 那个你需要的是搞明白 scanf和getchar这些函数的功能

引用 11 楼 千梦一生的回复:[quote=引用 9 楼 qq_46499695 的回复:] [quote=引用 6 楼 千梦一生的回复:]那你要把你的代码贴一下。我看看能否帮到什么 nclude<stdio.h>int main(){    float  a , b , c ;    int leap ;    char m , n ;    printf("please:");    leap=scanf("%f%c%f%c%f",&a,&m,&b,&n,&c);//输入表达式    switch(leap)//判断是两个数字计算    {        case 3:switch(m)        {            case '+':printf("%f",a+b);//加法            break;            case '-':printf("%f",a-b);//减法            break;            case '*':printf("%f",a*b);//乘法            break;            case '/':printf("%f",a/b);//除法            break;            default:printf("error");        }break;        case 5:switch(m)//三个数运算        {            case '+':switch(n)//加法            {                case '+':printf("%f",a+b+c);//加法            break;                case '-':printf("%f",a+b-c);//减法            break;                default:printf("error");            }break;            case '-':switch(n)//减法            {                case '+':printf("%f",a-b+c);//加法            break;                case '-':printf("%f",a-b-c);//减法            break;                default:printf("erro[/quote]  这个兄弟，很不好意思。今天有点不舒服。我明天一定给你想一想怎么能改一下。有点累，就不动脑子了[/quote] 嗯嗯，好！谢谢了！

引用 9 楼 qq_46499695 的回复:[quote=引用 6 楼 千梦一生的回复:]那你要把你的代码贴一下。我看看能否帮到什么 nclude<stdio.h>int main(){    float  a , b , c ;    int leap ;    char m , n ;    printf("please:");    leap=scanf("%f%c%f%c%f",&a,&m,&b,&n,&c);//输入表达式    switch(leap)//判断是两个数字计算    {        case 3:switch(m)        {            case '+':printf("%f",a+b);//加法            break;            case '-':printf("%f",a-b);//减法            break;            case '*':printf("%f",a*b);//乘法            break;            case '/':printf("%f",a/b);//除法            break;            default:printf("error");        }break;        case 5:switch(m)//三个数运算        {            case '+':switch(n)//加法            {                case '+':printf("%f",a+b+c);//加法            break;                case '-':printf("%f",a+b-c);//减法            break;                default:printf("error");            }break;            case '-':switch(n)//减法            {                case '+':printf("%f",a-b+c);//加法            break;                case '-':printf("%f",a-b-c);//减法            break;                default:printf("erro[/quote]  这个兄弟，很不好意思。今天有点不舒服。我明天一定给你想一想怎么能改一下。有点累，就不动脑子了

我看了下，是scanf函数你的理解不足造成的。我运行了一下，三个相加的还是能跑的对吧。两个相加就GG了。我后头看看怎么改。你空了可以去学习一下scanf的返回值相关的知识。明天摸鱼的时候给你看看。

引用 6 楼 千梦一生的回复:那你要把你的代码贴一下。我看看能否帮到什么 nclude<stdio.h>int main(){    float  a , b , c ;    int leap ;    char m , n ;    printf("please:");    leap=scanf("%f%c%f%c%f",&a,&m,&b,&n,&c);//输入表达式    switch(leap)//判断是两个数字计算    {        case 3:switch(m)        {            case '+':printf("%f",a+b);//加法            break;            case '-':printf("%f",a-b);//减法            break;            case '*':printf("%f",a*b);//乘法            break;            case '/':printf("%f",a/b);//除法            break;            default:printf("error");        }break;        case 5:switch(m)//三个数运算        {            case '+':switch(n)//加法            {                case '+':printf("%f",a+b+c);//加法            break;                case '-':printf("%f",a+b-c);//减法            break;                default:printf("error");            }break;            case '-':switch(n)//减法            {                case '+':printf("%f",a-b+c);//加法            break;                case '-':printf("%f",a-b-c);//减法            break;                default:printf("erro

引用 6 楼 千梦一生的回复:那你要把你的代码贴一下。我看看能否帮到什么 怎么搞啊。。。我不会。。。

引用 3 楼 自信男孩的回复:看着头大呢， /*************************************************************************     > File Name: abb.cpp     > Author: cfjtaishan     > Mail: cfj20080302@163.com      > Created Time: 2020年03月18日 星期三 20时29分46秒  ************************************************************************/  #include <stdio.h> #include <math.h>  float get_result(float a, char opt, float b);  int main(void) { 	char opt1, opt2; 	float a, b, c, result; 	int choice;  	printf("Please input your choice: (1: two number opt, 2: three nubers opt)"); 	scanf("%d", &choice);  	if (choice != 1 && choice != 2) { 		printf("Input error!\n"); 		return -1; 	}  	if (choice == 1) { 		printf("Please input your operation: (eg: 1*2)"); 		scanf("%f%c%f", &a, &opt1, &b); 		printf("=%.2f\n", get_result(a, opt1, b)); 		return 0; 	} 	printf("Please input your operation: (eg: 1*2*3)"); 	scanf("%f%c%f%c%f", &a, &opt1, &b, &opt2, &c); 	if (opt1 == '*' || opt1 == '/') { 		result = get_result(a, opt1, b); 		printf("=%.2f\n", get_result(result, opt2, c)); 	} else if (opt2 == '*' || opt2 == '/') { 		result = get_result(b, opt2, c); 		printf("=%.2f\n", get_result(a, opt1, result)); 	}  	return 0; }   float get_result(float a, char opt, float b) { 	float result;  	switch (opt) { 		case '+':  			result = a+b; 			break;  		case '-': 			result = a-b; 			break;  		case '*': 			result = a*b; 			break;  		case '/': 			if (fabsf(b) > 1e-6) 				result = a/b; 			break; 	}  	return result; }  供参考～ 谢谢，很有帮助！

那你要把你的代码贴一下。我看看能否帮到什么

引用 2 楼 千梦一生的回复:我有个想法。可以不用写的这么麻烦。比如循环呀。怎么样，你觉得？或者有这个需要一定得在此基础上修改吗？ 我正好在学循环，会考虑一下的！不过我现在想知道为啥这个代码运行不了。。。

引用 1 楼 千梦一生的回复:贴代码。虽然有注释很棒，但格式看的有点晕 知道了，会改进的！谢谢！

贴代码。虽然有注释很棒，但格式看的有点晕


Question: 萌新 求大佬帮忙~~

如果g_gard_count为0 ，哼哼

只要不进外层循环不就没有返回值了嘛

前者如果进入不了循环，自然就不会有返回值。

前者是有的，进入循环后，每条路都会有返回值，不是说一定要在最后返回才是返回值。只要在每一条路返回就行

有返回值是肯定的，假如你的数组中第一个就不符合条件，那么就直接返回-1了。后面即使有相同的ID号的也没有比较，因为return了

没太看明白楼主的意思，但是简单说一下吧。 明显第一段代码是有问题的（最起码那个break不应该放在return后面）。  函数要找到与参数cardId相匹配的那一项并返回。 肯定是需要让数组中的元素一个一个地去比较，如果不匹配，那就下一个来比较，直到找到相匹配的元素或者数组中没有（就返回-1）。 但是第一段代码只能比较第一个元素，无法让数组所有元素进行比较。 因为第一个元素时，执行到if语句，肯定会返回，也就是结果函数。（if-else两个子句都返回了） 也就不再比较第二个，第三个元素。。。。  正确的处理逻辑应该是第二段代码中那么，如果找到，就返回相应下标，当前元素不匹配的话，就换下一个元素，直接比较完整个数组后，还没有找到匹配的元素，说明这个数组中没有要找的东西，那就返回-1, 表示没找到。


Question: 初学者，关于C语言栈的应用问题，求大神指点

#include <stdio.h> #include <stdlib.h> #include <malloc.h> #include <unistd.h> //#include<process.h>  /* exit() */ #define STACK_INIT_SIZE 100 //初始栈空间分配能够存储的ElementType元素个数  #define STACKINCREMENT 10 //栈空间不够用后每次增加的存储量  typedef short Status;//返回状态值  typedef struct{  	char value;  }ElementType; //typedef char ElementType;  typedef struct{  	ElementType *base;//栈底指针；  	ElementType *top;//栈顶指针；  	int stacksize;//当前栈总共能容纳多少个ElementType元素，也就是最大容量  }SqStack;    //根据以上定义，完成如下功能（使用顺序存储结构）  Status InitStack(SqStack &S)//构造一个空栈，分配栈空间 { 	S.base = (ElementType*)malloc(STACK_INIT_SIZE*sizeof(ElementType)); 	if(!S.base) 		exit(0); 	S.top = S.base; 	S.stacksize =  STACK_INIT_SIZE; 	return 1; }  Status DestoryStack(SqStack &S)//销毁一个已分配的栈，回收栈空间 { 	free(S.base); 	S.base = NULL; 	S.top = NULL; 	S.stacksize = 0;  	return 1; }  Status StackEmpty(SqStack S)//判断S是否为空栈，是返回1，否则返回0 { 	if(S.base == S.top) 		return 1; 	else 		return 0; }  int StackLength(SqStack S)//返回S中元素个数 { 	return S.top-S.base; }  Status GetTop(SqStack S,ElementType &e)//返回栈顶元素给e，如果空栈函数返回-1，正常返回1 { 	if (S.top <= S.base) 		return -1;  	e = *(S.top-1); 	printf("栈顶元素为：%c\n",e.value); 	return 1;  	/* 	   if(S.top > S.base) 	   { 	   e = *(S.top-1); 	   printf("栈顶元素为：%c\n",e.value); 	   return 1;  	   }else 	   return -1; 	 */ }  Status Push(SqStack &S,ElementType e)//插入e为新的栈顶元素，如果栈空间不够，自动扩充（realloc函数） {  	if(S.top-S.base>=S.stacksize) 	{ 		//S.base = (ElementType *)realloc(S.base,(S.stacksize + STACK_INIT_SIZE)); 		S.base = (ElementType *)realloc(S.base,(S.stacksize + STACK_INIT_SIZE) * sizeof(ElementType)); 		if(!S.base) 			exit(0); 		S.top = S.base+S.stacksize; 		S.stacksize = S.stacksize+STACKINCREMENT; 	}  	//*(S.top) = e; 	*(S.top) = e; 	S.top++;  	return 1; }  Status Pop(SqStack &S,ElementType &e)//从栈中删除栈顶元素，并放在e中，空栈函数返回-1，正常返回1 { 	//if(S.top == S.base) 	if(S.top <= S.base) 		return 0; 	else 		//S.top = S.top-1; 		S.top--; 	e = *(S.top);  	return 1; }  Status Judge(SqStack S,ElementType &e) { 	while(S.top>S.base) 	{ 		if((S.top-1)->value==(S.base)->value) 		{ 			S.top = S.top-1; 			S.base = S.base+1; 		} 		else 			return 0; 	} 	if((S.top)->value =='&'||(S.base)->value =='&') 		return 1; 	else 		return 0; }  void print(SqStack S) { 	if (S.top <= S.base) 		return; 	printf("++此时栈内元素为："); 	while(S.top>S.base) 	{ 		// printf("此时栈内元素为：\n"); 		S.top = S.top-1; 		printf("%c(%d)\t",S.top->value, S.top->value); 	} 	printf("\n");  }  int main() { 	SqStack s; 	ElementType x; 	int a; 	int i; 	InitStack(s); 	printf("请选择测试内容（1为实验一，2为实验2）\n"); 	scanf("%d",&a); 	getchar();    // for '\n' 	switch(a) 	{ 		case 1:{  				   //ElementType c; 				   printf("请输入5个字符：\n"); 				   //for(i=0;i<6;i++) 				   for(i=0;i<5;i++) 				   {  					   scanf("%c",&x.value); 					   Push(s,x); 				   } 				   //printf("111"); 				   //print(s); 				   do{ 					   GetTop(s,x); 					   print(s); 					   Pop(s,x); 				   }while(StackLength(s)>0); 				   puts("\n"); 			   };break; 		case 2: 			   //{ 				   printf("请输入奇数个字符（要以序列1&序列2的形式输入，中间用&隔开,其中序列1和序列2为逆序）\n"); 				   int d; 				   printf("请输入要输入的字符数："); 				   scanf("%d",&d); 				   printf("请输入字符：\n"); 				   for(i=1;i<=d;i++) 				   { 					   scanf("%c",&x.value); 					   Push(s,x); 				   } 				   if(Judge(s,x)) 					   printf("符合要求！\n"); 				   else 					   printf("不符合要求！\n"); 				   //printf("正在开发中..."); 			  // }; 			   break; 		default: 			   printf("正在开发..");break; 	}  }   供参考～  注意提示输入5个，其实是输入6个。 另外，输入a之后的换行符。  其他认为有问题的也一并改了，详见上面的代码～


Question: 提取单词这部分代码有点问题。如果我在输入的英文句子后面加上一个字母，他就能够提取出单词；如果不加字母就不行，代码和运行截图如下希望各位帮忙看看，谢谢谢谢！！！

嗯嗯，谢谢！！！

嗯嗯，我明白了，谢谢！！！

int get_words(char *str, char ***words) {     int i,j=0,ln=strlen(str);       char *p1=&str[0];     char *p2=&str[0];  while(*p2 == ' '||*p2 == ',')         {             p2++;         }  p1 =p2;       for(i=0;*p2!='\0';i++)     {         while(*p2 != 0 && *p2 != ' '&& *p2 != ',')         {             p2++;         }          if (*p2 == 0) { if (*p1) //xx           {   (*words)[j] = p1;             j++; }             break;         }         //words[i] = p1;         (*words)[j] = p1;         *p2=0;         j++;       //  p1 = p2+1;//xx        // p2 = p1;//xx        p2++; while(*p2 == ' '||*p2 == ',')         {             p2++;         }  p1 =p2;      }       return j; }

#include<stdio.h> #include<string.h>  int get_words(char *str, char **words[]); void sort_words(char *strs[], int count);  int main() { 	char str[1024]; 	char *words[200], **ppwords; 	int n_words = 0; 	int i;  	printf("please input the sentence: "); 	fgets(str, 1024, stdin); 	str[strlen(str)-1] = 0;   	ppwords = words; 	n_words = get_words(str, &ppwords); 	printf("%d\n", n_words); 	for (i = 0; i < n_words; i++) 	{ 		puts(words[i]); 	} 	sort_words(words, n_words);  	printf("the result: ");  	for (i = 0; i < n_words; i ++) 	{ 		puts(words[i]); 	}  	return 0; }  int get_words(char *str, char ***words) { 	int i,j=0,ln=strlen(str);  	char *p1=&str[0]; 	char *p2=&str[0];  	for(i=0;*p2!='\0';i++) 	{ 		while(*p2 != 0 && *p2 != ' '&& *p2 != ',') 		{ 			p2++; 		}  		if (*p2 == 0) { 			(*words)[j] = p1; 			j++; 			break; 		} 		//words[i] = p1; 		(*words)[j] = p1; 		*p2=0; 		j++; 		p1 = p2+1; 		p2 = p1+1; 	}  	return j; }  void sort_words(char *strs[], int count) { 	int i,j; 	char *t;  	for (i = 0;i < count; i ++) 	{ 		for (j = i+1; j < count; j++) 		{ 			if (strcmp(strs[i],strs[j]) > 0) 			{ 				t = strs[i]; 				strs[i] = strs[j]; 				strs[j] = t; 			} 		} 	}  } 供参考～  注意传递三重指针，原因是实参是二重指针；其他问题，详见上面的代码～


Question: 栈  关于十进制转换八进制整数

引用 5 楼 m0_46472878的回复:[quote=引用 4 楼 user-1的回复:]找本基础入门级别的书，好好理解一下形参和实参传递这部分知识 老哥 那个 s!＝null那里不对啊  它告诉我缺少 )  没明白[/quote] 哦 没事了 😂

引用 4 楼 user-1的回复:找本基础入门级别的书，好好理解一下形参和实参传递这部分知识 老哥 那个 s!＝null那里不对啊  它告诉我缺少 )  没明白

找本基础入门级别的书，好好理解一下形参和实参传递这部分知识

引用 1 楼 user-1的回复:我晕，形参和实参的关系你都搞不清楚 最简单的修改方法是 void push(stack*S, Elememt n) 改成 void push(stack* &S, Elememt n)  //改成引用类型  int pop(stack*S, Elememt n) 改成 int pop(stack* &S) //改成引用类型，去掉参数n或者改成引用类型int pop(stack* &S, Elememt &n)  void converson(stack*S, int N) 改成 void converson(stack* &S, int N) //改成引用类型 while (S!=null) {     n = pop(S);     printf("%d", n); }  main S=NULL; 改成  S->next = NULL; 能帮我讲讲有什么区别吗 就是通俗的讲

引用 1 楼 user-1的回复:我晕，形参和实参的关系你都搞不清楚 最简单的修改方法是 void push(stack*S, Elememt n) 改成 void push(stack* &S, Elememt n)  //改成引用类型  int pop(stack*S, Elememt n) 改成 int pop(stack* &S) //改成引用类型，去掉参数n或者改成引用类型int pop(stack* &S, Elememt &n)  void converson(stack*S, int N) 改成 void converson(stack* &S, int N) //改成引用类型 while (S!=null) {     n = pop(S);     printf("%d", n); }  main S=NULL; 改成  S->next = NULL; 老哥  我真的不清楚 原来没有学习 半路学的


Question: 大佬们帮帮忙吧。

引用 3 楼 weixin_45215324 的回复:就是上位机发送的数据可以从下位机上显示出来我意思是你让我们全部写出来，这个太耗时了，所以没有什么人回复。。。你可以把你写的代码贴出来，有啥问题大家可以帮你一起看。

就是上位机发送的数据可以从下位机上显示出来

你这需求有点广啊

单片机与计算机的串口通信系统设计


Question: C语言

第一个 数据溢出，变成-1 第二个 字符串数组最后一位是 '\0'

第一个 printf("num_max=%u\n",num_max); 第二个  char str[6]="apple";


Question: keil c99支持

#define LEN 你的define没有指定长度呢？  比如： #define LEN 10