Question: c

按照你的逻辑 int a=5 a不就是一个变量的值吗？  值=值是什么鬼   你搞错了一件事儿，  = 不是 ==，  =是赋值操作， 等号前面的是一个变量， 把后面的值赋予前面变量 否则的话，你就可以让  3 = x +2 ； 计算机自动帮你去求x是几啦， 可惜啊，c语言现在还没有这个功能

比如： 一维数组 a[10] a是首地址，即 a[0]的地址。 二维数组 a[10][10] a是首行地址，也就是第 0行的地址。 可以把行看成一个变量 ，则列就可以看成一个一维数组，这样就好理解了。

很简单，例如有 int a[13][17]; 那么 a 的类型是 int[13][17]，a + 0 的类型是 int(*)[17]，a[0] 的类型是 int[17]，a[0] + 0 的类型是 int*。你仔细梳理一下就会恍然大悟。

引用 2 楼 與蘤舊縐的回复:*(a+i)+j == &a[i][j]有问题吗  你觉得*(a+i)是数组里存储的值，但这是二维数组，不是一维数组，*(a+i)=a[i]，也就是第i行的首地址  注意a[0][0]!=a[0]，前面的是值，后面的是地址 int a[3];在一维数组中*(a+i)的值和a[i]内容一样，这我理解 但放在二维数组中我觉得*(a+i)是第i+1个元素的值 而二维中a[i]是个指针常量不是个数组元素，还没弄明白

二维数组a中，a[i]+j=*(a+i)+j a+i是指针移动，*（a+i）是一个具体数值，不是地址值啊，为什么*(a+i)+j被解释成了一个地址值


Question: 写入到stack时缓冲区溢出

引用 1 楼 寻开心 的回复:你确定文件打开正确了吗 scanf进来后，你printf一次数据看看 此外， 文本当中的字符串确实没有超过100吧，否则str数组最后一个可不是‘\0’, 会导致对str的访问溢出的    for (i = 0;str[i] != '\0'&&I<99;i++) {  这样更安全 这个I是用作什么的呢？ 结果为“匹配”时能够写入，“不匹配”就不行了


Question: 求大神 百思不得其解

引用 2 楼 初学小菜 的回复:你少考虑情况了 包含负数 完全平方数为零 没有问题啊

你少考虑情况了

提示说的很清楚了


Question: 萌新求助

希望对你有帮助：https://blog.csdn.net/it_xiangqiang/category_10581430.html 希望对你有帮助：https://blog.csdn.net/it_xiangqiang/category_10768339.html

引用 1 楼 寻开心的回复:Link * pHead 是头， 要插入的节点是pNode pNode->next = pHead->next; pHead->next = pNode;  这样就把pNode放在第一个节点，也就是头节点后面的第一个上面了呗 谢谢了，我发现我好像忘记malloc了


Question: while循环不跳出循环，感谢！

p和q怎么会为空呢 最初他有初始值的,后面p++,q++,地址空间从你软件的加载基址开始，你一直自增，等溢出回到null? 估计你的条件是*p&&*q吧


Question: 各位帅哥美女帮忙看下为啥控制台输不进去啊

文件不要用中文名字


Question: C语言杨辉三角

1 #include<stdio.h>  2 int main()  3 {  4     int n,i,j,a[100];  5     printf("请输入行数n:");  6     scanf("%d",&n);  7     printf("  1");  8     printf("\n");  9     a[1]=a[2]=1; 10     printf("%3d%3d\n",a[1],a[2]); 11     for(i=3;i<=n;i++) 12     { 13         a[1]=a[i]=1; 14         for(j=i-1;j>1;j--) 15             a[j]=a[j]+a[j-1]; 16         for(j=1;j<=i;j++) 17             printf("%3d",a[j]); 18         printf("\n"); 19     } 20     return 0; 21 }//没有注释将就看吧

嗯嗯，我试试，谢谢啦

引用 8 楼 Nx呐！ 的回复:[quote=引用 7 楼 最大风力17级的回复:]#include<stdio.h> int n; int in[1005],out[1005];//in[]包括上一层的数据，out[]用来计算本层的数据 int main(){ 	scanf("%d",&n);//输入需要输出的层数 	if(n==1)printf("1\n"); 	else if(n==2){ 		printf("1\n"); 		printf("1 1\n"); 	} 	else{ 		printf("1\n"); 		printf("1 1\n");//输出了前两层并且从第三层开始算； 		in[1]=in[2]=1;//初始化上一层的数据  		for(int i=3;i<=n;i++){//计算第i层数据数据 		    //memset(out,0,sizeof(out)); 			out[1]=out[i]=1; 			for(int j=2;j<i;j++)out[j]=in[j-1]+in[j];//计算下一层的第二位到第i-1  			for(int j=1;j<=i;j++)printf("%d ",out[j]);//输出  			printf("\n"); 			for(int j=1;j<=n;j++)in[j]=out[j];//将本层数据移到下一层的上一层数据 		}  	} 	return 0; }  会了会了，谢谢啦。。[/quote] 可以把数组的数据类型改一下，这个在大一点的数据下会超数据范围

引用 7 楼 最大风力17级的回复:#include<stdio.h> int n; int in[1005],out[1005];//in[]包括上一层的数据，out[]用来计算本层的数据 int main(){ 	scanf("%d",&n);//输入需要输出的层数 	if(n==1)printf("1\n"); 	else if(n==2){ 		printf("1\n"); 		printf("1 1\n"); 	} 	else{ 		printf("1\n"); 		printf("1 1\n");//输出了前两层并且从第三层开始算； 		in[1]=in[2]=1;//初始化上一层的数据  		for(int i=3;i<=n;i++){//计算第i层数据数据 		    //memset(out,0,sizeof(out)); 			out[1]=out[i]=1; 			for(int j=2;j<i;j++)out[j]=in[j-1]+in[j];//计算下一层的第二位到第i-1  			for(int j=1;j<=i;j++)printf("%d ",out[j]);//输出  			printf("\n"); 			for(int j=1;j<=n;j++)in[j]=out[j];//将本层数据移到下一层的上一层数据 		}  	} 	return 0; }  会了会了，谢谢啦。。

引用 5 楼 最大风力17级 的回复:可以一层一层往下推下去 我写下试试

可以一层一层往下推下去

引用 3 楼 最大风力17级的回复:必须要用两个一维数组吗？ 嗯呢，俩个一维数组，，，

必须要用两个一维数组吗？

就是用循环控制空格和字符数jiu xing

百度超级多的，不用一维数组都可以


Question: C语言求助，万分感谢！~

引用 4 楼 qybao的回复:上面遗漏了，修改一下 for ( int row=0; row<160; row++) {      for (int col=1; col<37; col++)            B[36*row+col-1] = A[40*row+col]; } 非常感谢😊已经成功解决了。

一维数组也一样啊，借用上面的代码  int A[160*40] ; int B[160*36];   for ( int row=0; row<160; row++) {      memcpy( &B[row*36], &A[row*40+1], 36*sizeof(int)); }  或者 for ( int row=0; row<160; row++) {      for (int col=1; col<37; col++)            B[row+col-1] = A[row+col]; }

请教一下 ，如果数组是一维的 应该怎样写哈？不知道哪里出错了 图像尾部总是出来的数据总是不对 。感谢！@~

int A[160][40] ; int B[160][36];   for ( int row=0; row<160; row++) {      memcpy( B[row], A[row]+1, 36*sizeof(int)); }  或者 for ( int row=0; row<160; row++) {      for (int col=1; col<37; col++)            B[row][col-1] = A[row][col]; }


Question: 有没有人能告诉我，这到底是为什么啊啊啊啊啊啊啊啊！

引用 3 楼 寻开心 的回复:你看你的警告提示哈 前两个警告：  size 和 get两个都未定义， 假定是返回int 最后一个警告： dog2的类型是明确的，  但是参数类型是不是int不确定，它假定是int的  你还有一个编译错误， 先把那个错误解决掉，后面也许会跟着改变  但是 去掉A处的代码，程序可以正常运行。 加上A后就有错了，报错信息指向B处。

引用 1 楼 真相重于对错 的回复:还是那句老话先把基本语法学好。不是自己在哪里瞎猜。 size是什么？你定义的函数吗？  嗯。


Question: 假设printf函数中有两个数字，先后计算哪个数字，先后输出哪个数字

你问得好奇怪哦，没定义就要看编译器了

不要浪费生命在错误的问题上

多个参数的函数， 这些参数是表达式的时候，这些表达式的执行顺序在c/c++标准当中是没有定义的 因为不同的编译器就会有不同的解释， 有的从左到右，有的从右到左 这就是未定义行为

属于c/c++当中的未定义行为， 不同编译器上执行的顺序不同


Question: 求解一道C语言题 求大神帮一下

main() {         int m=0;         int d=1;	/* 购买天数 */         int i=2;	/* 最近一天购买苹果数*/         int k=2;	/* 购买苹果总数 */         for(;d<100;)         {                 i=2*i;                 k=k+i;                 d++;                if(k>=100)                {                 break;                }         }         if(k<100)	/*感觉你们的代码都少了后面的判断，如果苹果总数少于100直接 总数/天数就可以  */         {                m= (k*1.8)/d;         }         else		/*但是如果苹果总数大于100，需要减去最后一天的苹果树，天数也要减1  */         {                 m=((k-i)*1.8)/(d-1);         }        /* printf("k = %d i=%d d = %d\n",k,i,d); */         printf("%d",m); } 结果是22

引用 6 楼 他们都管我叫郑老师 的回复：[quote=引用 4 楼 m0_46346717 的回复：][quote=引用 2 楼 他们都管我叫郑老师的回复:]我给你写，明天回复我，提醒我一下 兄弟写完了没。。。。。。。。[/quote]#include <stdio.h> main() { 	int n=2,day=0;	/*定义n，day为基本整型*/ 	float money=0,ave;	/*定义money，ave为单精度型*/ 	while(n<100)/*苹果个数不超过100，故while中表达式n小于100*/ 	{ 		money+=0.8*n;	/*将每天花的钱数累加求和*/ 		day++;	/*天数自加*/ 		n*=2;	/*每天买前一天个数的2倍*/ 	} 	ave=money/day;  /*求出平均每天花的钱数*/ 	printf("The result is %.6f\n",ave);	 /*将求出的ave输出*/ } [/quote]加油吧，少年，别等坐吃山空。

引用 4 楼 m0_46346717 的回复：[quote=引用 2 楼 他们都管我叫郑老师的回复:]我给你写，明天回复我，提醒我一下 兄弟写完了没。。。。。。。。[/quote]#include <stdio.h> main() { 	int n=2,day=0;	/*定义n，day为基本整型*/ 	float money=0,ave;	/*定义money，ave为单精度型*/ 	while(n<100)/*苹果个数不超过100，故while中表达式n小于100*/ 	{ 		money+=0.8*n;	/*将每天花的钱数累加求和*/ 		day++;	/*天数自加*/ 		n*=2;	/*每天买前一天个数的2倍*/ 	} 	ave=money/day;  /*求出平均每天花的钱数*/ 	printf("The result is %.6f\n",ave);	 /*将求出的ave输出*/ }

int main() {     float  unitPrice = 1.8f;     int    day = 1;     int    nPurchase = 2;     float  cost = nPurchase * unitPrice;     int    nTotal = 2;     while  ( nTotal < 100 ) {         printf("Day:%02d, Purchase:%02d, Total:%02d, cost:%5.2f\n", day, nPurchase, nTotal, cost);         day++;  nPurchase *=2; cost = nPurchase *unitPrice;         // cost *= 2; // 这样写也是可以的，反正购买量翻倍，花费也是翻倍         nTotal += nPurchase;     }     return 0; }

引用 2 楼 他们都管我叫郑老师的回复:我给你写，明天回复我，提醒我一下 兄弟写完了没。。。。。。。。

初学，也来做一下这个作业  #include <stdio.h> #define price 1.8 //苹果价钱  int main() {     int sum=0; //苹果总数     double sum_price=0.0; //苹果总价     int i=2;     int j=0;   //天数     while(sum<100)     {         sum += i;         i *= 2;         j++;     }     sum_price = sum * price;     printf("总共买了%d个苹果，用了%d天，共花费%.2f元。", sum, j, sum_price);     printf("平均每天花%.2f元。\n", sum_price/j);      return 0; }

我给你写，明天回复我，提醒我一下

做一个循环就可以解决的基础问题， 自己写代码，错了贴上来提问


Question: 在for循环中scanf的问题

希望对你有帮助：https://blog.csdn.net/it_xiangqiang/category_10581430.html 希望对你有帮助：https://blog.csdn.net/it_xiangqiang/category_10768339.html

scanf 遇到回车的处理， 看看scanf函数的说明， 它把回车留在缓冲区里面没有提取走， 所以下次getchar或者%c格式的scanf都会遇到它

我想先问问，你确定你的代码能跑吗？ #include<stdio.h> int main() { char shuzu[1000000]; int num,i; scanf("%d",&num); for(i=1;i<=n;i++ ) {  数组开1MB，堆栈没有溢出？ n没有定义，就可以循环？

引用 2 楼 apkipa1的回复:可以像 #1 那样做，也可以直接写 scanf(" %c", &shuzu[i])，看你个人偏好了。 呃，谢谢。 想问下为啥只有%c才会出现这种情况，而输入%d的时候不会发生录入回车键的情况。

因为\n也是一个字符，所以要用getchar来接收回车 for(i=1;i<=n;i++ ) { getchar(); scanf("%c",&shuzu[i]); }


Question: 字符数组变量在字符函数参数表中为什么取地址后会有warning？？

引用 4 楼 qybao 的回复:a是变量，&a是变量的地址（也就是变量类型的指针） 你的例子中a是数组，所以&a如LS所说是数组的指针，&a[0]才是char指针（也就是a[0]是char，所以&a就是char指针） 笔误，修正一下 （也就是a[0]是char，所以&a[0]就是char指针）

变量的名字就是char*类型了，  &a的类型是 char (*)[6] 是数组的指针， 类型不匹配了

噢噢，那请问是不是 &a是int * ，而a是char * ，所以不取地址才是对的 ， 可以这样理解吗？

编译器都告诉你了，指针类型不匹配。


Question: C语言编写的屏保程序

这全是英文看不太懂啊

可能有用： https://docs.microsoft.com/en-us/windows/win32/lwef/screen-saver-library


Question: 作业求助

设计什么?编程总要有需求或者要求的.编写的程序要用于做什么,需要描述清楚.这也叫需求分析

是输出 ******************** *     C程序设计      * ******************** 吗？ #include <stdio.h>  int main() { printf("********************\n*     C程序设计      *\n********************\n"); return 0; }

printf


Question: 初学c的小菜鸡，前来请教各路大佬。

可以这么理解。 int i=fa()+fb()+fc()*(fd()+fe()); 编译器并不保证五个函数的求值顺序。 但是可以保证先计算fd()+fe()的和（括号优先级） 再计算fc()*r3(算术优先级)  也就是说编译器并未假定按优先级，来顺序求值。

那具体应该怎么算才正确呢？

求值顺序和运算符优先级不是一回事~~~

优先级： 括号 > * > +。+从左至右执行。 答案为 A


Question: APFFT C语言代码

请问您实现了嘛？

请问您实现了么

居然。。。，没人

哈哈 俺也想求一个apfft的c代码

请问您求到了吗？


Question: 求助 指针内容 感谢大佬

LZ应该找本入门级别的教程好好看看，p=a后，*p是什么，*(p+1)是什么？它们和a[0]，a[1]是什么关系？弄清楚了就明白了。


Question: 【求助求助】C语言小问题：将数字变成0的次数

引用 楼主 weixin_45707268 的回复:题目： 给定一个非负整数，返回将其减少到零的步骤数。如果当前的数字是偶数,你要除以2,否则,你必须从中减去1 来源:力扣(LeetCode)链接:https://leetcode-cn.com/problems/number-of-steps-to-reduce-a-number-to-zero  递归代码： int numberOfSteps (int num) {     if(num%2==0) return numberOfSteps(num/2)+1;     if(num==1) return 1;     return numberOfSteps(num-1)+1; }  为什么要加1呀？  如果当前数字是偶数，需要把它除以 2 ；如果是奇数，需要减去 1。  如果是偶数，  numberOfSteps(num/2)的次数比numberOfSteps(num)少一次 如果是奇数， numberOfSteps(num -1)的次数比numberOfSteps(num)少一次 递归到1的时候 就是直接返回1了。 凡递归，就是处理本轮和前一轮的逻辑关系。

引用 1 楼 他们都管我叫郑老师的回复:不减1，你反悔的数据就会少1，最简单的是带入一个数据，去验证一下程序，你就会发现1的用处 举例容易，可是我理解的好困难呀


Question: 有没有会这道C语言循环题的，求详细步骤

希望对你有帮助：https://blog.csdn.net/it_xiangqiang/category_10581430.html 希望对你有帮助：https://blog.csdn.net/it_xiangqiang/category_10768339.html


Question: 新人求助，这个问题困扰我好几天了，一直找不到解决办法，要哭了

引用 6 楼 ?Victor.??的回复:抱歉，把f打成d了 ok。。。。。。。。

抱歉，把f打成d了

引用 3 楼 You're  Beautiful 的回复:[quote=引用 1 楼 ?Victor.??的回复:]你好像把lf打成了1f,scanf_s("%lf",&b) 奥 那为什么float类型printf和scanf用5f都行呢[/quote] float类型scanf(%5d)意思是接收位数（包括小数点） printf(%5d)意思是输出最小宽度（包括小数点） 而double类型lf应该是long float 的意思 double(%5lf)是一个意思

%f和%lf分别是float类型和double类型用于格式化输入输出时对应的格式符号。 其中： float，单精度浮点型，对应%f。 double,双精度浮点型，对应%lf。  在用于输出时: float类型可以使用%lf格式，但不会有任何好处。 double类型如果使用了%f格式可能会导致输出错误。  在用于输入时: double 类型使用了%f格式，会导致输入值错误。 float类型使用double类型不仅会导致输入错误，还可能引起程序崩溃。  所以在输入输出时，一定要区分好double和float，而使用对应的格式符号。

引用 1 楼 ?Victor.??的回复:你好像把lf打成了1f,scanf_s("%lf",&b) 奥 那为什么float类型printf和scanf用5f都行呢

奥 那为什么float类型printf和scanf用5f都行呢


Question: 请大佬瞧瞧

引用 1 楼 user-1 的回复:你得把你创建的链表头结点传入addnum中再操作，addnum中pStrHead=NULL了，函数返回指针地址都丢失了。 好的，问题解决，谢谢


Question: 求！！！

引用 4 楼 的amara的回复:[quote=引用 3 楼 RoseYui的回复:][quote=引用 2 楼 的amara的回复:]#include<stdio.h> int main() { 	int a=1; 	scanf("%d", &a); 	a += a -= a*a; 	printf("%d",a); 	return 0; }  //最后得到的值直接赋给a了 哇，谢谢您！！！那个地方是不是直接int a;?[/quote] 这个a是局部变量 初始化，也可以初始化为其他的值[/quote] 嗷嗷，好的，谢谢您啦啦啦啦啦啦啦啦啦啦啦啦

引用 3 楼 RoseYui的回复:[quote=引用 2 楼 的amara的回复:]#include<stdio.h> int main() { 	int a=1; 	scanf("%d", &a); 	a += a -= a*a; 	printf("%d",a); 	return 0; }  //最后得到的值直接赋给a了 哇，谢谢您！！！那个地方是不是直接int a;?[/quote] 这个a是局部变量 初始化，也可以初始化为其他的值

引用 2 楼 的amara的回复:#include<stdio.h> int main() { 	int a=1; 	scanf("%d", &a); 	a += a -= a*a; 	printf("%d",a); 	return 0; }  //最后得到的值直接赋给a了 哇，谢谢您！！！那个地方是不是直接int a;?

从右到左拆分成两步算


Question: C

你把你看到的原文发上来，

数组是数组，表示一串连续放置的相同类型变量，是一组变量组的集合 如 int a[10]; 数组a就是指这10个int的集合。 指针是指针，是一个存储了某个地址的变量或常量，指向某个变量或常量的存储位置,如     int av;      int *ptr=&av; 指针ptr就指向了整型变量av的存储位置  对于编译器而言，可以将数组名（注意是数组名，而非数组）作为指向数组第一个元素的指针 如 int a[10]; *a和a[0]是等价的，此时的数组名a和int* ptr=&a[0];时的指针ptr是基本等效的。  数组名作为指针与一般的指针变量又是不一样的，指针变量可以改变其自身的内容，既可以指向不同的变量（存储空间），如     int av,bv;       int* ptr=&av;//定义ptr,指向av      ptr=&bv;//ptr改变指向的位置 但数组名a就始终只能指向数组a的起始位置，int a[10],b[10]; //定义一旦结束，是不能让a重新指向b的空间的  所以说数组名是一个（指向数组首地址的）指针（常量），这就是有些书简单说数组名就是指针，有些书说不是指针，而有些书又说像一个指针的原因

引用 2 楼 apkipa1的回复:数组就是数组，你之所以会混淆数组和指针，只不过是因为数组名在绝大多数情况下可以自动变成指向首元素的指针罢了。你应当把数组和 int 等类型同等看待，再记住几个特性(例如数组不能赋值、数组名遇到取地址符或 sizeof 不退化为指针)，然后大多数问题就能解决了。 那个数组不能赋值是数组名不能被赋值吧


Question: 请求帮助我这到底出了啥问题

i的值未初始化，它的值是随机的。声明的时候int i=0;

引用 3 楼 weixin_40290083的回复:不是没有定义i,而是i没有初始化 第一段程序中的sum没有初始化。 第二段程序中的i没有初始化。 怎么初始化，我感觉没错啊

main15的i和main的i不是同一个i，是不同函数栈的局部变量。main函数的i没有初始化

引用 6 楼 weixin_40290083的回复:初始化就是在使用这个变量进行计算之前对它赋初值。 嗷嗷，这个叫初始化是吧😂😂明白了明白了

初始化就是在使用这个变量进行计算之前对它赋初值。

考二级c语言路上第一个问题，难搞哦


Question: [问＋求助]C语言

希望对你有帮助：https://blog.csdn.net/it_xiangqiang/category_10581430.html 希望对你有帮助：https://blog.csdn.net/it_xiangqiang/category_10768339.html


Question: 求详细代码！天平砝码问题，最后求左右加的砝码

引用 1 楼 真相重于对错的回复:提醒一下， 判断能称重的条件是 (w+1)%n==0 或者 (w-1)%n==0 或者 w%n==0 这个我之前看到过，但是是判断天平是否平衡的。。这道题目要求左右加的的砝码分别是多少


Question: 求大佬通俗地解释一下，这两段代码为什么相等

实际上两段代码不相等

引用 4 楼 qybao 的回复：while(*str)表示当前指针指向的字符不是字符串结尾符就一直循环 *dst++ = *str++ 等价于 *dst = *str，str++，dst++ 所以意思就是str指针走到字符串结尾符前一直循环把str指向的字符赋给dst，然后str，dst指针递增 第二个直接把*dst++ = *str++ 放在while里，上面说了，该语句等价于 *dst = *str，str++，dst++，整个while就等价于执行这些操作后，判断赋值后的*dst是不是字符串结尾符，如果不是则继续循环。 所以意思就是用*str当前指向的字符赋给*dst，然后str，dst指针递增，然后判断赋值后的dst指向的字符是不是字符串结尾符，如果不是则继续循环。 所以比较第一个和第二个的意思，其实是一样的。非常感谢

引用 2 楼 weixin_45906870 的回复：引用 1 楼 與蘤舊縐 的回复：首先*src++的值等于*src，下一个while括号中的一句相当于*dst++，相当于*src++，相当于*src，也就是第一个while括号里的内容，然后第一个while花括号中的内容就是第二个while括号中的内容，这一条语句在每次循环是都执行一次，两个while等效谢谢大佬，虽然没看到你的解释没看懂....


Question: 大学课本中的c语言是指c还是c++

引用 3 楼 ?Victor.??的回复:[quote=引用 2 楼 與蘤舊縐 的回复:] c和c++是两门语言，c自然就是c 大佬，有没有兴趣看看已解决区的第二篇帖子[/quote] 我是APP，看不了撒

引用 2 楼 與蘤舊縐 的回复:c和c++是两门语言，c自然就是c 大佬，有没有兴趣看看已解决区的第二篇帖子

c和c++是两门语言，c自然就是c

好强大的问题，据我所知，是c


Question: 求助

引用 1 楼 與蘤舊縐的回复:文件后缀为msi，是一个安装程序，应该是vs安装的中间产物，最后没有删除，直接删掉问题不大，前提是你的vs安装完成了 嗯好谢谢你了那我就删掉了


Question: C语言long double为啥输不出数字5

引用 9 楼 與蘤舊縐 的回复:好吧，这样子的我试过了，并不行，不过它显然是支持long double的，可以获取到长度为16我再看看吧 这是我用 msys2 测试的结果：  令我奇怪的是，我看 msys1 的头文件说 __USE_MINGW_ANSI_STDIO 已经被弃用了，要换别的宏，没想到 msys2 还在用，我还以为 mingw-w64 单纯是原始 mingw 的升级版呢。

引用 8 楼 apkipa1 的回复:[quote=引用 6 楼 與蘤舊縐 的回复:] 话说我两都不行，是不是得安装下扩展，别怀疑我装了假编译器mysy2配的mingw64工具链 我暂时用的是 msys1，这样子可以正确输出，你可以参考一下： [/quote]  好吧，这样子的我试过了，并不行，不过它显然是支持long double的，可以获取到长度为16我再看看吧

引用 6 楼 與蘤舊縐 的回复:话说我两都不行，是不是得安装下扩展，别怀疑我装了假编译器mysy2配的mingw64工具链 我暂时用的是 msys1，这样子可以正确输出，你可以参考一下：

#include <cstdio>  文件是cpp，你再跑一遍看看

引用 5 楼 apkipa1 的回复:[quote=引用 2 楼 AKK188888881 的回复:] 刚刚搞错了 图是这两张 可能的原因： 1. 你的编译器的 C99 是假的，或没有成功开启。 2. 你的编译器确实用了 C99，但是 Windows 本身不支持，于是编译器被微软坑了。 要解决的话你可以去网上搜下 mingw long double，看是否有解决方案。[/quote]  话说我两都不行，是不是得安装下扩展，别怀疑我装了假编译器mysy2配的mingw64工具链

引用 2 楼 AKK188888881 的回复:刚刚搞错了 图是这两张 可能的原因： 1. 你的编译器的 C99 是假的，或没有成功开启。 2. 你的编译器确实用了 C99，但是 Windows 本身不支持，于是编译器被微软坑了。 要解决的话你可以去网上搜下 mingw long double，看是否有解决方案。

说明lf不是指long double

和编译器有关，有的可以用Lf，有的可以用llf，有的都不行  用scanf+Lf赋值也不一定能改变结果  long double是C99开始支持的，但不同的编译器对其支持可能不同

刚刚搞错了 第一种： 第二种： 图是这两张

这两张图有区别吗？


Question: 哪个兄弟会！！！跪求

希望对你有帮助：https://blog.csdn.net/it_xiangqiang/category_10581430.html 希望对你有帮助：https://blog.csdn.net/it_xiangqiang/category_10768339.html

这么简单的总得自己先尝试一下吧  给你一个提示，使用字符数组存储学号


Question: [求助] warning C4133: “函数”: 从“student *”到“student *”的类型不兼容

引用 2 楼 寻开心 的回复:全局 和 main 函数里面各自提供了一个struct student结构， 这个不对。 删掉main函数里面的定义  刚刚才看到，一开始在main函数里定义，复制出来忘记删掉了


Question: 一个小白卑微在线求解，关于C语言中的strcpy

引用 4 楼 @__Chao - L的回复:啥编译器啊？居然有中文提示？ vs2013，装的时候选择中文，就像他们下面说的一样，也不是都是中文，大多数都是英文

引用 4 楼 @__Chao - L 的回复:啥编译器啊？居然有中文提示？  看不出来，大概vs，不过也不是什么提示都是中文，还是看洋文吧

啥编译器啊？居然有中文提示？

引用 2 楼 寻开心的回复:这种带_s的函数， 对于字符，字符串操作的时候，要指定目标地址的长度， 避免内存溢出 嗯，刚才看到，去试了一下成功了，谢谢

strcpy_s(ss.p.addr, 5, "yang")


Question: 大神们，写入位置时发生访问冲突


Question: C语言abc是浮点型 fabs=b*b-4*a*c fabs(a)<=1e-6为什么不写成a=0

浮点数和整数不一样，整数在有效范围内，所有数都可以精确的表达 float只能表达6～7位有效数字， double的13～14位有效数字 任何两个浮点数之间的比较，都要考虑到这个问题，不能直接比较 https://blog.csdn.net/happy__888/article/details/280627

你曲解了近似的意思。事实上，精度的损失就像你计算十进制 1 / 3 一样，结果必须用无限位小数表示，然而这对 double 来说是不可能的(况且 double 用的是二进制，所以分母必须是 2 的 n 次方)，所以就有了损失。类似的开方、指数也一样，不过 C 语言的数学函数往往是用特殊的方法实现的，这保证了数学函数必然有误差。总之，这些导致了浮点数不可以直接和某个值比较，而往往是在某个范围内比较。

没有大神解释下吗？


Question: 浮点类型float与double的什么区别,请教老师指点一下什么情况？

不客气，刚开始我也出过这样的问题，书上印刷傻傻分不清，我也是新手，没事到csdn上逛逛挺有益处的

还真是来，我一直认为是%11111f来，谢谢！~ %f和%lf分别是float类型和double类型用于格式化输入输出时对应的格式符号。 其中： float，单精度浮点型，对应%f. double,双精度浮点型，对应%lf. 在用于输出时: float类型可以使用%lf格式，但不会有任何好处。 double类型如果使用了%f格式可能会导致输出错误。 在用于输入时: double 类型使用了%f格式，会导致输入值错误。 float类型使用double类型不仅会导致输入错误，还可能引起程序崩溃。 所以在输入输出时，一定要区分好double和float，而使用对应的格式符号。

你好像把%lf打成了1f


Question: 大佬帮忙看看

引用 16 楼 寻开心 的回复:sprintf那里也是lld  这种状态是比较讨厌， 没有测试数据，只能猜 好了，大佬，改完结果是一样的，我决定give up了，也许这题它注定与我无缘 非常感谢您的帮助

sprintf那里也是lld  这种状态是比较讨厌， 没有测试数据，只能猜

引用 14 楼 寻开心 的回复:long long int Len[13]  long long int nStart[14] 这两个怎么不一样多啊  for(j = 1;j < 14;j++) 会访问到Len[13]吗？ 如果会就越界了  long long int  scanf("%d",&n); 这里是不是要改成  %lld啊 #include<stdio.h> int main() { 	char buffer[100]; 	long long int n = 0; 	long long int v = 0; 	long long int Len[14] = {0,9,180,2700,36000,450000,5400000,63000000,720000000,8100000000,90000000000,990000000000,10800000000000,1170000000000000}; 	long long int nStart[14] = {0,1,10,100,1000,10000,100000,1000000,10000000,100000000,1000000000,10000000000,100000000000,1000000000000}; 	int j = 0,k = 0; 	int T = 0; 	scanf("%d",&T); 	char c[100]; 	for(k = 0;k < T;k++) 	{ 		scanf("%lld",&n); 		for(j = 1;j < 14;j++) 		{ 			if(n > Len[j]) 				n-=Len[j]; 			else 				break; 		} 		n--; 		v = nStart[j]+n/j; 		sprintf(buffer,"%d",v); 		c[k] = buffer[n%j]; 	} 	for(k = 0;k < T;k++) 		printf("%c\n",c[k]); 	return 0; } 改成这样应该没问题了吧，可结果还是只通过一组，大佬，我是不是该放弃了

引用 11 楼 寻开心 的回复:测试程序， 用int，只能跑到 循环输出前300个 #include <stdio.h> #include <string.h>  #include<stdio.h> int main() {     int  nLen = 9;     int  v = 0;     int Len[13]    = { 0,9,180,2700,36000,450000,5400000,63000000,720000000};     int nStart[13] = { 0,1, 10, 100, 1000, 10000, 100000, 1000000, 10000000};     int j;     int n;      printf("Start....\n");     char buffer[100];     char output[301] = {0};     int index =0;     int k;     for ( k=1; k<300; k++ ) {         n = k;         for(j = 1; j<nLen;j++)         {             if(n > Len[j])                 n-=Len[j];             else                 break;         }         n--;         v = nStart[j]+ n/j;         sprintf(buffer,"%d",v);         output[index++] = buffer[n%j];     };     printf("%s", output);     return 0; }; #include<stdio.h> int main() { 	char buffer[100]; 	long long int n = 0; 	long long int v = 0; 	long long int Len[13] = {0,9,180,2700,36000,450000,5400000,63000000,720000000,8100000000,90000000000,990000000000,10800000000000}; 	long long int nStart[14] = {0,1,10,100,1000,10000,100000,1000000,10000000,100000000,1000000000,10000000000,100000000000,1000000000000}; 	int j = 0,k = 0; 	int T = 0; 	scanf("%d",&T); 	char c[100] = {0}; 	for(k = 0;k < T;k++) 	{ 		scanf("%d",&n); 		for(j = 1;j < 14;j++) 		{ 			if(n > Len[j]) 				n-=Len[j]; 			else 				break; 		} 		n--; 		v = nStart[j]+n/j; 		sprintf(buffer,"%d",v); 		c[k] = buffer[n%j]; 	} 	for(k = 0;k < T;k++) 		printf("%c\n",c[k]); 	return 0; } 这是最后的程序，我在编译器试了那两组数，结果正确 但到了它那里 却是这样，宝宝心里苦  请问这个程序还有什么错误吗

你说的对， 确实考虑不周 n -= nLen[j] 之后，都是从1开始不是从0开始 所以要这样  n--； v = nStart[j]+n/j;  不能这里减去1

引用 7 楼 寻开心 的回复:nStart[13] = {0,0， 10,100,1000,10000,100000,1000000,10000000,100000000,1000000000,10000000000,100000000000,1000000000000};  这里是0个零， 1位数是从0开始，2位数是从10开始 #include<stdio.h> int main() { 	char buffer[100]; 	long long int n = 0; 	long long int v = 0; 	long long int Len[13] = {0,9,180,2700,36000,450000,5400000,63000000,720000000,8100000000,90000000000,990000000000,10800000000000}; 	long long int nStart[14] = {0,0,10,100,1000,10000,100000,1000000,10000000,100000000,1000000000,10000000000,100000000000,1000000000000}; 	int j = 0; 	scanf("%d",&n); 	for(j = 1;j < 14;j++) 	{ 		if(n > Len[j]) 			n-=Len[j]; 		else 			break; 	} 	v = nStart[j]+n/j-1; 	printf("%d\n",v); 	sprintf(buffer,"%d",v); 	printf("%d",buffer[n%j]); } 结果总是得49，还有v=nStart[j]+n/j这里是不是要减1呀，因为个位是从0开始

引用 5 楼 寻开心 的回复:long long int可以表示20次方  char buffer[100]；  第一个这样一个变量 #include<stdio.h> int main() { 	char buffer[100]; 	long long int n = 0; 	long long int v = 0; 	long long int Len[13] = {0,9,180,2700,36000,450000,5400000,63000000,720000000,8100000000,90000000000,990000000000,10800000000000}; 	long long int nStart[13] = {0,10,100,1000,10000,100000,1000000,10000000,100000000,1000000000,10000000000,100000000000,1000000000000}; 	int j = 0; 	scanf("%d",&n); 	for(j = 1;j < 13;j++) 	{ 		if(n > Len[j]) 			n-=Len[j]; 		else 			break; 	} 	v = nStart[j]+n/j; 	sprintf(buffer,"%d",v); 	printf("%d",buffer[n%j]); } 这次能运行了，但是值不对

引用 1 楼 寻开心 的回复:不能用pow函数，它太慢了 做一个数组 int LenSize; // 数组元素的个数 int Len= {0， 9, 90*2, 900*3, 9000*4, 90000*5, 900000*6, 9000000*7 , ......}; int nStart= {0, 10, 100, 1000, 10000, 10000, 1000000, ....} 根据题目要求的输入数据的范围来做好这个数组的初始化 对于输入的n for (j=1; j<LenSize; j++）     if ( n  > Len[j] ) n -= Len[j]; else break; 此时j表示的输入的数字对应的那个数字的位数 如果j=3，表示输入的数位于3位数区，距离第一个三位数100的首字母1的距离是n（循环当中 -= 操作后的n，不是输入的n） v = nStart[j] + n/j;   这个数具体是几 v的从高位向低位的第 n%j 位就是答案 sprintf(buffer,  "%d",  v); 输出buffer[n%j]就可以了 大佬，n的范围到10的12次方，我只好用double了，但是之后sprintf,和之后的printf就出问题了，还说suffer未定义，该咋办啊，没学过sprintf和buffer,不知道用的对不对 #include<stdio.h> int main() { 	 	double n = 0; 	double v = 0; 	double Len[13] = {0,9,180,2700,36000,450000,5400000,63000000,720000000,8100000000,90000000000,990000000000,10800000000000}; 	double nStart[13] = {0,10,100,1000,10000,100000,1000000,10000000,100000000,1000000000,10000000000,100000000000,1000000000000}; 	int j; 	for(j = 1;j < 13;j++) 	{ 		if(n > Len[j]) 			n-=Len[j]; 		else 			break; 	} 	v = nStart[j]+n/j; 	sprintf(buffer,"%f",v); 	printf("%f",buffer[n%j]);

好的，谢谢

这些在循环当中经常用到的数值， 要么提前定义到数组里面，要么做一个初始化循环操作，全部赋值过去 不能在循环里面每次单独的去算， 太耗时间了


Question: 01背包为什么会出现这个结果啊有点懵

希望对你有帮助：https://blog.csdn.net/it_xiangqiang/category_10581430.html 希望对你有帮助：https://blog.csdn.net/it_xiangqiang/category_10768339.html


Question: 看一下我结构体代码的问题

VS2013中也提供了scanf_s()。在调用时，必须提供一个数字以表明最多读取多少位字符，以便建立缓冲区接收输入信息，防止越界。这就要求程序在设计过程中就明确输入的长度。

vs编译器用_s加强安全性,scanf_s("%s", &product1.color,20);需要加上你需要分配的字符串大小

引用 1 楼 ?Victor.?? 的回复:字符串输入不能加&，把12，14行&去掉试试 依然是同样的问题啊

字符串输入不能加&，把12，14行&去掉试试


Question: 刚开始学C，这两天在学习寻址，留个笔记；

引用 1 楼 user-2 的回复:笔记写到博客，论坛是讨论问题的 不好意思，刚混论坛~

笔记写到博客，论坛是讨论问题的


Question: 数据结构的图遍历，打了又打，我也不知道什么鬼，帮忙找错了，看你们找多少给分

这是遍历的代码，上面的main函数去掉，加上下面这几段： #define MAX 20 bool visited[MAX]; void (*FuncVisit)(Vertex v);  void visit(Vertex V) { 	printf("顶点%d访问完毕\n",V); }  Vertex FirstAdjVertex(MGraph Graph,Vertex V) { 	if(!Graph->adjmlist[V].firstEdge) 		return -1; 	else 		return Graph->adjmlist[V].firstEdge->jvertex; }  Vertex NextAdjVertex(MGraph Graph,Vertex V,Vertex W) { 	EdgeBox* p; 	for(p=Graph->adjmlist[V].firstEdge;p->data!=W;p=p->ilink)	 	{ 		if(!p->ilink) return -1; 	} 	printf("%d",p->data); 	return p->ilink->data; }  void DFS(MGraph Graph,Vertex V) { 	Vertex W; 	visited[V]=true; 	FuncVisit(V); 	for(W=FirstAdjVertex(Graph,V);W>=0;W=NextAdjVertex(Graph,V,W)) 	{ 		if(!visited[W])	DFS(Graph,W); 	} }  void DFSTraverse(MGraph Graph,void (*Visit)(Vertex v)) { 	Vertex V,W; 	FuncVisit=visit; 	for(V=0;V<Graph->vexnum;V++) 		visited[V]=false; 	for(V=0;V<Graph->vexnum;V++) 		if(!visited[V]) DFS(Graph,V); }    int main() { 	MGraph Graph=BuildGraph(); 	DFSTraverse(Graph,visit);  }

图是邻接多重表，遍历是深度优先遍历


Question: 踩雷游戏

后边那一步已经改成=，但还是运行不了


Question: 一道C语言问题，关于函数调用问题

1 形参和实参不一样的 void func（float a）；  // 声明     func（3）； // 调用  2 表达式 printf("%d",  1+2 ); // 1+2就是表达式 实参可以是常量、变量、表达式、函数都行  3和4     形参是在调用的时候，程序在栈中给分配的内存， 形参变量的地址就是这个栈空间    实参是在调用之前就存在的，哪怕是函数的返回值或者常量等也都是得到了最后的数值后， 把数值赋值给形参（栈中的变量）    所以他们不能共享内存，是赋值过去的，并不是同一个地址    哪怕是传递指针， 他们传递是指针的值（不是指针指向的数据） ，依然是赋值关系

第一个，实参和形参类型可以不一致，前提是它们的类型可以发生隐式转换。如形参为long，可以传int,short,char的值。 第二个，void f(int a);使用的时候可以是 f(2+4*6)，参数接受的是一个值，这个值可以有表达式结算所得。 第三个，C++的引用就是实参与形参共用内存，但是C没有这种用法。 第四个，调用函数是程序只会为形参分配内存空间，你传递的实参的内存与函数无关。 以上为个人总结。


Question: 新手学编程，大佬们帮忙解答一下这个题


Question: 大一新生，遇到了点问题。

还差一点，整数字面量都被编译为整形 即 temp = i/10 先以整形计算i/10为0，再把0转成double 赋给temp 但如果把 i 改成double，i/10就会把10转成double计算得结果0.5


Question: 一道C语言问题，关于函数调用问题

调用函数时，实参可以是表达式是对的，  调用函数时，程序会为实参和形参分配内存空间    这个也应该是对的

调用函数的时候，实参和形参类型可以不一致        形参：int类型 传递unsigned int；  或者int类型，传递char给它； 都可以    表达式肯定是对的  后面两个不对


Question: 函数返回值问题

a1和a是一样的，指向的地址是一样的

引用 2 楼 qybao 的回复:char *a1 = a 就是用a1记录a原来指向的地址 while里有a++，a指向的地址变了 返回a1就等于返回a原来指向的地址，因为不能返回a了，a指向的地址已经变了懂了  谢谢


Question: 数组的使用

scanf(“%f”, &floatI[intI]); 取地址&

除了1楼所说的问题。  1.计算最大、最小和平均，1次遍历就完成了   zuigao = floatI[0]; zuidi = floatI[0]; pingjun = floatI[0]; for(intI = 1; intI < 10;intI++) {      if(zuigao < floatI[intI]）      {            zuigao = floatI[intI];       }       if(zuidi > floatI[intI])       {            zuidi = floatI[intI];       }       pingjun += float[intI]; } pingjun /= 10;  2. 变量命名真是别扭

输入写错了，取地址符


Question: 二叉排序树建立


Question: 使用C语言用GTK写了一个linux下的数独程序


Question: free()函数问题

不是。只有你传给 free 的指针与 malloc / realloc 返回的指针一个 bit 都不差，才能正常释放，否则就会导致行为未定义。


Question: 一道关于数组指针和指针数组的疑问求解

纠正一下，以大端模式存储，应该是地址从高到低存储，所以1003存0x05，1002存0x06，1001存0x07，1000存0x08，所以答案是0x08，D

指针类型转换以及指针类型的内存信息储存的知识点 指针指向一维数组，指针可以像数组一样操作，也就是test_p[1]和*(test_p+1)是一样的，前者是数组的方式，后者是指针的方式 一个int占4个字节，一个char占1个字节，所以char数组原来的内存空间（8个字节），只够存储2个int，前一个int是前4个字节，即0x01到0x04，第二个int是后4个字节0x05到0x08，test_p[1]就是第二个int，所以1000地址存的是0x05，1001存0x06，1002存0x07，1003存0x08，所以答案应该是0x05


Question: C语言新手在指针方面遇到的疑惑

简单的说，b[10]={}这样的方式相当于给下标为10数组元素地址赋值（声明数组时除外），很显然，左边是整形，右边是数组列表，类型不匹配不能赋值。如果b是二维数组，那么b[10]就是下标为10的一维数组，那么就可以赋值。

初始化是在定义的时候初始化，初始化才能一股脑赋值，之后的赋值必须按正常赋值规则来赋值，你的get函数里面b的赋值是正常赋值，所以不能像你期望的那样赋值

你可以这样嘛 void fpp(int* b) { 	struct pp{ int a[10]; }; 	*(pp*)b = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; }

我感觉定义函数时int *get(int *p,int *b,int m)时相当于已经定义了数组，而b[10]={0,0,0.......}相当于赋值，众所周知，数组赋值需要循环，而b[10]={0,0,0.......}相当于给b[10]这一个元素付了10个值，所以不对，不知道这么理解对不对

{ 0, 0, ... } 这个叫初始化列表，只有在你声明一个对象的时候才能用，例如 int a[] = { 0, 0, 0 }; 其他地方用了会报语法错误。这里用循环的方法或者 memset 清 0 即可。


Question: C语言释放内存空间

引用 9 楼 真相重于对错的回复:就算自己设计内存池，我觉得也不应该提供这个功能。建议百度一下动态内存分配算法。 好的，感谢帮助（又要十个字）

引用 8 楼 真相重于对错的回复:另外你可能认为这样做会更省内存。 但实际上并不如此。前面我已经说malloc返回的是一段连续的内存。你应该知道内存碎片的概念。例如你malloc了100k的内存，如果系统中只剩下两块80k，你也会malloc失败。 那么如果允许从中间释放，原来的连续的内存，将非常容易变成碎片。 这倒是，碎片和占着茅坑不拉屎说不上一定哪个好，如果malloc多次，如果他们正好连续，我要free掉一个岂不也是中断了，如果不是连续的，那本身就那样了，从这方面来说，我不过相当于malloc了三段连续的小空间，抽走中间的罢了，我还是想说如果真有这么一个函数，他只是一个工具，能起多大作用，还是得看人怎么用了，如果开了一个大空间却因为一点点数据无法释放显然是得不偿失的，当然这种情况下把剩下的一部分拷贝，释放掉原空间也可以，但这样很可能会波及到前面用的到部分指针，当然这也可以人工避免。所以说了这么久不过是想捡个现成的工具而已，用不用怎么用，见仁见智而已

就算自己设计内存池，我觉得也不应该提供这个功能。建议百度一下动态内存分配算法。

引用 6 楼 真相重于对错的回复:[quote=引用 5 楼 與蘤舊縐 的回复:] [quote=引用 4 楼 真相重于对错的回复:]想一下，为什么要这么做，这么做的目的是什么？ 如果这么做可以，带来的后果是什么？ 后果不后果得看这函数具体的限制，还得看你怎么用了，如果足够信任程序员的话就可以给这个权限[/quote] 这不是信不信任程序员的问题。而是系统如何设计的问题。malloc是返回一段内存的首地址，free的参数是一段地址的首地址。那么可以推论堆内存的管理应该是一个表，表的每一项是标记已经用的内存。包括它的地址和长度，如果允许把一段已开的内存中间某段释放掉，那么就要修改整个的表，效率会怎样？而且如果删除中间一段，本来malloc/free只要记住首地址即可，现在还要记住下一段的地址。否则最后无法完全释放。[/quote] 我是觉得还是安全方面的问题比较麻烦，具体实现虽然不知如何才能高效，但至少不必记这么多，或者说记住空间首地址和长度即可，如果搜索起来麻烦，大可设置形参为原地址加起始位置，虽然在程序的不同位置可能无法获取到原指针，但既然是要指定删除的，自然知道起始位置到原指针的距离，原指针可能，如果中断那就是一段变两段，多一组数据，也不至于改了整个表吧，而且一开始判断该地址是否存在应当已经找到该内存在表中的位置不管需不需要再重找，都容易得多，再者要实现这个效果不一定非得改底层，就像一楼说的搞个内存池也行，不过一般的内存池显然是不好使的，最后呢这不过是扩展一个功能，用不用程序员说了算，考虑空间与时间，在必要的情况下未必不可拿时间换空间

引用 5 楼 與蘤舊縐 的回复:[quote=引用 4 楼 真相重于对错的回复:]想一下，为什么要这么做，这么做的目的是什么？ 如果这么做可以，带来的后果是什么？ 后果不后果得看这函数具体的限制，还得看你怎么用了，如果足够信任程序员的话就可以给这个权限[/quote] 这不是信不信任程序员的问题。而是系统如何设计的问题。malloc是返回一段内存的首地址，free的参数是一段地址的首地址。那么可以推论堆内存的管理应该是一个表，表的每一项是标记已经用的内存。包括它的地址和长度，如果允许把一段已开的内存中间某段释放掉，那么就要修改整个的表，效率会怎样？而且如果删除中间一段，本来malloc/free只要记住首地址即可，现在还要记住下一段的地址。否则最后无法完全释放。

引用 4 楼 真相重于对错的回复:想一下，为什么要这么做，这么做的目的是什么？ 如果这么做可以，带来的后果是什么？ 后果不后果得看这函数具体的限制，还得看你怎么用了，如果足够信任程序员的话就可以给这个权限

引用 1 楼 user-2的回复:简单来说：洗洗睡吧。 具体来说：操作系统本身就对用户态内存分配有限制，所有内存页都是操作系统管的，用户态管不着。再加上 C 运行库可能对从系统那获得的内存再做其它管理，最后指针才到用户代码那里，用户代码真的没什么好做的。(不过 C 提供了 realloc，可能可以满足你的部分需求，实在不行就写个内存池自娱自乐好了) 注意/主要   这APP怎么撤不回来

引用 1 楼 user-2的回复:简单来说：洗洗睡吧。 具体来说：操作系统本身就对用户态内存分配有限制，所有内存页都是操作系统管的，用户态管不着。再加上 C 运行库可能对从系统那获得的内存再做其它管理，最后指针才到用户代码那里，用户代码真的没什么好做的。(不过 C 提供了 realloc，可能可以满足你的部分需求，实在不行就写个内存池自娱自乐好了) 注意是想用来释放掉一个指向已申请内存中段的指针指向的之后的内存，realloc也是不行的，自己写是没问题，只是用起来麻烦，图个现成的，看来是没有了


Question: 新手小白，求大神帮忙解释一下下面两个二级c程序！感谢！

希望对你有帮助：https://blog.csdn.net/it_xiangqiang/category_10581430.html 希望对你有帮助：https://blog.csdn.net/it_xiangqiang/category_10768339.html

引用 3 楼 user-2的回复:花括号就相当于作用域，在同一对花括号里是同一级别。if后面跟花括号，是因为满足if就会执行花括号里的语句，如果没有花括号，只执行if后面第一条语句。 对于布尔类型来说，0是false，0以外是true，所以if(0)就是if(false)，所以这个if永远不会满足，if(1)就是if(true)，这个条件永远满足 这种都是最基础的知识，随便找本书看看就好了 好的，谢谢您的详细回答

引用 1 楼 user-2的回复:第一个程序a=5 第二个程序a=3 else总是和自己同一级别的最近的if匹配 第一个程序if0和else同一级别，也和else最近，所以是一对 第二个程序，if0在if1里，else不在if1里，所以if0和else不是同一级别，和else同一级别的只有if1，所以它两是一对 好的👌🏻，谢谢～不太懂if后面括号里的零和一是什么呀？


Question: C语言中指针的提出解决了什么问题

让用户可以直观的操作内存

指针是c中最具有特色的东西了， 只有和其他语言对比着才能体会出来它的不同  有了指针，让c费产的灵活，但是也很危险  没法细说，太多了， 应用当中逐步体会吧

仅供参考： http://c-faq.com/ptrs/goodfor.html


Question: 两字符串中的最大公共字符串个数及公共字符串

引用 4 楼 m0_46336373 的回复:[quote=引用 3 楼 與蘤舊縐的回复:][quote=引用 2 楼 m0_46336373 的回复:] [quote=引用 1 楼 與蘤舊縐的回复:]abcdef  defgab  公共字符串无非就是一样的字符子串，比如def和ab 那最大公共字符串是啥啊[/quote]  长度最大[/quote] 比如你写的那两串字符串，最大公共字符串是哪个[/quote]  def

引用 3 楼 與蘤舊縐的回复:[quote=引用 2 楼 m0_46336373 的回复:] [quote=引用 1 楼 與蘤舊縐的回复:]abcdef  defgab  公共字符串无非就是一样的字符子串，比如def和ab 那最大公共字符串是啥啊[/quote]  长度最大[/quote] 比如你写的那两串字符串，最大公共字符串是哪个

引用 5 楼 與蘤舊縐的回复:[quote=引用 4 楼 m0_46336373 的回复:] [quote=引用 3 楼 與蘤舊縐的回复:][quote=引用 2 楼 m0_46336373 的回复:] [quote=引用 1 楼 與蘤舊縐的回复:]abcdef  defgab  公共字符串无非就是一样的字符子串，比如def和ab 那最大公共字符串是啥啊[/quote]  长度最大[/quote] 比如你写的那两串字符串，最大公共字符串是哪个[/quote]  def[/quote] 哦哦懂了，谢谢哈

引用 2 楼 m0_46336373 的回复:[quote=引用 1 楼 與蘤舊縐的回复:]abcdef  defgab  公共字符串无非就是一样的字符子串，比如def和ab 那最大公共字符串是啥啊[/quote]  长度最大

引用 1 楼 與蘤舊縐的回复:abcdef  defgab  公共字符串无非就是一样的字符子串，比如def和ab 那最大公共字符串是啥啊

abcdef  defgab  公共字符串无非就是一样的字符子串，比如def和ab


Question: C语言数组

这只不过是数组的特性，事实上你用例如 a == &a 之类的式子，是无法正常编译通过的，这证明了其实这 4 个的类型以及意义是不同的。

编译期把这些变量都编译成一个偏移地址。变量只是代码层面的，机器码里没有变量，只有地址。


Question: 请教 (char)k  和 (char *)k 的区别

(char)k是把k转成char类型 (char*)k是把k转成char指针，指针就是个地址，地址其实也就是个无符号整形（对于32位机指针类型占用4个字节，和无符号整形一样）


Question: 指针变量的运算

引用 7 楼 lin5161678 的回复:引用 6 楼 gouyanfen 的回复:[quote=引用 5 楼 lin5161678 的回复:] [quote=引用 1 楼 gouyanfen 的回复:] 因为你的p和q定义的是int *，你定义为void *试试，或者定义为byte *试下。void* 不能相减 void *可以先转为uint直接用uint相减，指针就是个地址的值有什么不能减的。[/quote]你说得很清楚 那是uint相减 void* 是一个地址的值  是一个很不严谨的说法 并且和讨论的问题 没有关系 C里面 减法运算对操作数的类型有规定 这些规定里面void* 这个类型不能相减[/quote] 你严格按照规定操作没有什么问题,void *这个定义实际应用中大部分场景就是为了方便传递各种类型指针的通用类型，实际应用中最后基本都强转为了其它类型。习惯问题，我是随心所欲型，知道自己在做什么就行。当然为你的严谨点赞，这个只是我的个人习惯。

这里指针的加减是以数组中元素为单位进行加减的，而不是以字切为单位进行加减的。

引用 9 楼 gouyanfen 的回复: 实际上 你和我的操作都是一样的 转换为uint 相减 或者转换为 char* 相减 这里的回复主要是针对你回复中讲的 类型定义为void* 相减  这对新手来说 有些误导

指针相减的结果是整数， 但是这个整数的意思，并不是差几个BYTE， 而是差几个指针指向的数据的类型  printf指定%p类型输你的指针地址，你就能看到，指针地址具体是多少了， 他们之间的差距就BYTE

引用 6 楼 gouyanfen 的回复:引用 5 楼 lin5161678 的回复:[quote=引用 1 楼 gouyanfen 的回复:] 因为你的p和q定义的是int *，你定义为void *试试，或者定义为byte *试下。void* 不能相减 void *可以先转为uint直接用uint相减，指针就是个地址的值有什么不能减的。[/quote]你说得很清楚 那是uint相减 void* 是一个地址的值  是一个很不严谨的说法 并且和讨论的问题 没有关系 C里面 减法运算对操作数的类型有规定 这些规定里面void* 这个类型不能相减

引用 5 楼 lin5161678 的回复:引用 1 楼 gouyanfen 的回复:因为你的p和q定义的是int *，你定义为void *试试，或者定义为byte *试下。void* 不能相减 void *可以先转为uint直接用uint相减，指针就是个地址的值有什么不能减的。

你如果想知道移动了多少个字节，可以转成int后再加减 即 printf(“%d”, (int)q -(int)p);

指针减法是基于数组的下标运算建立的，指向同一个数组的不同元素的指针相减的结果等价于下标差。因而讨论单个元素的大小等是无意义的(除非你要理解汇编)。

你反过来思考就明白了 p = &a[1]; q = p + 2; 这时你觉得q指向数组的哪个元素？是不是指向&a[3]? 也就是指针的加减编译器会自动根据指针的类型来计算，这样能让用户不用关注每种类型占用的字节大小，只是单纯的考虑移动几个单元就可以了，否者用户做指针加减还要考虑每种类型占用的字节（每个系统可能占用的字节也不一样），这样会把编程复杂化，而且也不方便移植。


Question: 在C程序中读取秘密内容的最佳实践

希望对你有帮助：https://blog.csdn.net/it_xiangqiang/category_10581430.html 希望对你有帮助：https://blog.csdn.net/it_xiangqiang/category_10768339.html

引用 3 楼 qybao 的回复:我有一种想法，就是把密钥写成一个返回值的函数，把该函数编译为机器码，然后再你的解密函数里直接调用机器码获得密钥再解密。 机器码调用的例子，可以参考以下帖子 https://blog.csdn.net/bdss58/article/details/83387028 我觉得这样不太好，因为这种代码是需要调用系统 API 获取执行权限的，逆向的时候都是重点关照对象，一旦 API 被调试器 hook，很容易露馅，导致被破解。

引用 楼主 zhongxiangchen 的回复:我有一个程序运行时需要从文件中读取一些保密的内容，如何对这些保密的内容进行加密以及如果在应用程序中安全的存储这些密钥，有什么最佳实践可供参考吗？ 由于保密内容可能较大因此我理解应该使用AES加密保密内容，问题进而演变成如何安全的存储AES密钥。我计划使用RSA私钥加密AES密钥，使用硬编码在应用程序中的RSA公钥来解密AES密钥的密文。这种方式违反了公钥加密私钥解密的原则，但是如果硬编码私钥这会导致更大的问题。 我知道在应用程序中存储密钥没有绝对的安全但总比什么都不做的好，也并不是每个人都有逆向的能力。我了解到还有加密狗这种硬件的方式但是这需要给应用程序额外配置一个硬件并不总是那么方便。 求各位大神支招 从逆向的角度说说你的问题， 1.你的密文存在文件中，那必然会读到到内存中处理，就有两个破解点，一个readfile,第二个读取之后在密文上下内存访问断点，直接就可以找到你对密文处理的部分，进而反推到你的密文来源，并不是什么难事。 这方面你有两个方面处理，第一密文添加混淆内容，第二个逻辑分散处理 2.你用AES算法，那么基本上常用的库，比如openssl里面的加密部分，或者crpyto这些加密之后的汇编码也容易识别的，直接在库的算法入口断点基本就可以确定算法，再逆推参数来源。应对办法：1.用静态链接,2.增加花指令 3.善于利用异常处理改变正常的流程,比如自己制造异常，try{假的加密解密}catch{正常的加密解密部分} 3.就是加壳增加逆向难度，一般的壳就不用试了，只能劝退初学者 4.如果你的程序是C/S结构，是的话办法还可以多点，如果是单机的就只是是技巧性的. 没有绝对安全的加密，只是看逆向成本是否大于收益。

两个问题：  1 密钥的加密存储， 这个弄个大一点儿的数据区， 把密钥简单的可逆加密后， 分散开存储到一堆乱码当中就好了    甚至存储到多个不同文件里面去    密钥的生成，可以根据一些硬件信息来，确保机器码或者用户信息和密钥有唯一的匹配    这种加密算法有很多， 看那类适合用哪一类就好了。核心问题还是生成一个唯一的用户ID，和一个唯一对应的密钥    把密钥弄的长长的， 即便给予明文也不容易推算出关系，伪造密钥难度还是比较大的 2 密钥读取后解密的算法才是重点， 算法被破解加密的手段就统统失效    简单  if （ 验证成功 ） 执行正常代码。else。异常处理；   这种写法，会直接毁掉前面所有的密钥生成成果。    这个部分的解决方案就是把密钥的解密过程分散到多个不同的先后执行的函数当中，和正常的应用代码混合起来    每段代码解密密钥的不同部分， 防止被跟踪可以限定代码的执行时长， 甚至可以用汇编语言实现逆指令流防止被debug    可以检测调用程序的父进程是系统还是debug工具    这里花费的精力越多，破解越难， 响应的代码的维护也越难    因为正常业务的代码也要不断的升级改造， 他们改完了，你在源码的基础上去嵌入自己的加密源码    那种直接在不影响业务正常编码程序上面加壳的方法是可以简化工作难度，但是也降低了破解的难度    让密钥解码出来的数据成为程序正常执行所需的一些重要数据的初始化变量， 财务数据运算的一些常量也未尝不是一个好办法    没有明显的if else 和函数调用判断， 但是它错了， 业务执行就各种意外发生了    从这个角度去想办法，比明文和密钥之间的那些有限算法上，会灵活很多

引用 1 楼 apkipa1 的回复:只要你最终要把加密内容明文保存到内存里，就永远不能防止有心人进行数据窃取。我个人认为，如果你上了(多层)加密，而且保持解密、数据的使用不太明显，那么应该已经能劝退许多不想花太大功夫的人了。(然后再给程序上个壳，效果可能更好)  我也查了很多资料，密钥硬编码到程序中是没有办法保证安全的。这么做能挡住大部分的人其实就已经足够。如果要绝对安全那么要付出的成本就太大了。我之前没做过这样的事情也不知道这样是不是正常的做法。


Question: 求救


Question: C语言新手再次前来求教

怀疑是逗号表达式的问题吧，不同的编译器可以执行顺序不一样（从左到右或从右到左）。改成分号试试。

你先分开了赋值，看看问题出在哪里？


Question: Stack around the variable 'a' was corrupted

* (p + j + 1)，i=n,j<i p+j+1   i=10, j=9时，访问了p+10,这个就是越界了


Question: 删除字符串中指定字符

控制台在等待你输入要查找的字符吧

是不是delchar写错了，为什么要for循环char值？


Question: 哪位大佬逐行逐句地解释一下这段代码，我给他磕头了！！

#include <stdio.h> #include <stdlib.h>           int main() { //声明变量     double *ptd;//这是一个双精度小数类型的指针     int max;     int number;     int i = 0;          puts("What is the maximum number of type double entries?");//输出字符串     if (scanf("%d", &max) != 1)//输入数字到max变量     {         puts("Number not correctly entered -- bye.");         exit(EXIT_FAILURE);//退出，和return在main里面同样     }     ptd = (double *) malloc(max * sizeof(double));//分配内存     if (ptd == NULL)     {         puts("Memory allocation failed. Goodbye.");         exit(EXIT_FAILURE);     }          puts("Enter the values (q to quit):");     while (i<max && scanf("%lf", &ptd[i]) == 1)//一直输入         ++i;     printf("Here are your %d entries:\n", number = i);     for (i=0; i<number; i++)     {         printf("%7.2f ", ptd[i]);//输出         if (i%7==6)//i取余7             putchar('\n');//输出单个字符     }     if (i%7 != 0)         putchar('\n');     puts("Done.");     free(ptd);//释放变量占有的内存          return 0; }

输入一个数max ， scanf返回1才表示这个数被正确获得到      if (scanf("%d", &max) != 1) 建立一个动态数组，大小就是max        ptd = (double *) malloc(max * sizeof(double)); 输入max个浮点数       while (i<max && scanf("%lf", &ptd[i]) == 1)    ++i; 七个一行的输出， i%7 从0到6 ， 6的时候表示已经输出了7个，所以在此输出个回车好换行        if (i%7==6)   putchar('\n'); 最后一行不满七个也换行     if (i%7 != 0)         putchar('\n');  释放内存      free(ptd);


Question: 麻烦一些大神教我这道题。

对于常用的编译器来说，整数的字面量，会被编译为整形。打印以下结果就知道了。 double d1 = 1/5; //1和5都被编译为整形，所以结果是0 double d2 = 1.0/5; //因为1.0是浮点型，所以5也被转换为浮点型，所以结果是0.2 printf("%f, %f\n", d1, d2);

5是个整数，打错了

实型常量又称实数或浮点数。在C语言中可以用单精度型和双精度型两种形式表示实型常量，分别用类型名float和double进行定义  .5其实就是0.5，这在C++和C以及其他一些语言，比如python中都是支持的  5显然是个实数，当然你可能会说可以给一个float类型的变量赋值为5，实际上这里是有隐式类型转换的


Question: 【求助】求问各位大佬，自己的VS上能过，OJ上显示运行时出错

引用 10 楼 user-2的回复:有错是可能是因为少打了一个换行，在for打印前多加一行printf(“\n”);试试。  另外，如果OJ控制输入可以保证的话，也可以去掉一些判断输入错误的代码。 比如去掉 if(n > 100000) break;这一行 fgets这一行改成gets(s); 去掉if(strlen(s) != n) break;这一行，或者把它改成 n = n > strlen(s) ? n : strlen(s); 去掉fflush(stdin)这一行  至于逻辑，正确的做法应该是for(0到k)循环来计算tem，也就是重复k次，但这样做效率太低。你现在的逻辑直接用第一次指令后的x，y重复k-1，再计算最后一次指令的最大tem，好像是没问题的，主要是怎么证明这中间重复的k-1次没有出现最大的tem，能证明就没问题。 嗯对，就因为OJ能控制输入所以省略了几行。关于逻辑，我跟标准答案的文字讲解核对了一下，是符合标准答案的，所以这个想法没问题，是我写代码实现它的过程中出了问题。我再好好看看，前辈费心啦！

引用 8 楼 user-2的回复:因为有清空缓存了，if (strlen(s) != n) break; //输入长度保证一致 这行可以不要 谢谢前辈！然鹅按照你的代码修改以后依然显示答案错误，应该是我逻辑有问题，我自己再找找吧，不必麻烦你啦！晚安

引用 6 楼 qq_45855517 的回复:1.已修改 2.这个是OJ控制的输入，可以保证。把default改回case以后还是答案错误  算法对不对没太细看，但是我想表达的是这个意思（在注释里） int main(int argc, const char * argv[]) {     int T, n, i, j;     long long tem, k, y, x;     char s[100001];     scanf("%d", &T);     if (T < 0) return -1;     long long *ans = (long long*)malloc(sizeof(long long)*T); //ans要用long long，因为tem是long long     for (i = 0; i < T; i++)     {         y = 0, x = 0;         tem = 0;         scanf("%d%lld", &n, &k); //题目要求分两行         if (n > 100000) break;         while (getchar()!='\n');         memset(s, '\0', sizeof(s));         fgets(s, n+1, stdin); //输入长度保证一致         if (strlen(s) != n) break; //输入长度保证一致         for (j=0; j<n; j++)         {             switch (s[j])             {                 case 'U':y++; break;                 case 'D':y--; break;                 case 'R':x++; break;                 case 'L':x--; break;                 default: break; //如果是别的指令则忽略             }             tem = (tem >abs(x) + abs(y)) ? tem : abs(x) + abs(y);         }                  y *= (k - 1);         x *= (k - 1);         for (j=0; j<n; j++)         {             switch (s[j])             {                 case 'U':y++; break;                 case 'D':y--; break;                 case 'R':x++; break;                 case 'L':x--; break;                 default: break;             }             tem = (tem >abs(x) + abs(y)) ? tem : abs(x) + abs(y);         }         ans[i] = tem; //这里如果用int会丢失精度导致结果不对         fflush(stdin); //清空缓存，否则有脏数据，如果上面输入长度保证一致也是为了避免脏数据     }          for (i = 0; i < T; i++)         printf("%lld\n", ans[i]);          free(ans);     return 0; }

引用 5 楼 user-2的回复:具体算法没细看，但 for (m = 0;m < strlen(s); m++) s[m] = '\0'; 这样肯定不对，s[0]='\0'后，strlen(s)肯定是0，这个循环没意义 memset(s, '\0', sizeof(s));  我想说的是 scanf("%d%lld%s", &n, &k, s); //这里输入的n怎么保证不超过s字符串的长度 如果超过s的长度 switch (s[j]) 都会走入case的default，是你想要的结果吗？ 1.已修改 2.这个是OJ控制的输入，可以保证。把default改回case以后还是答案错误

引用 3 楼 user-2的回复:n和s的长度保证一致吗？比如n大于输入的s的长度时（s每次不清空，是否内存有垃圾数据），会不会导致后面计算是不是就不对了？而且switch如果不在case范围，是否需要特别处理？ #include<stdio.h> #include<stdlib.h> #include<string.h> #include<math.h> int main() { 	int T, n, i, j,m, ans[100001]; 	long long tem, k, y, x; 	char s[100001]; 	scanf("%d", &T); 	for (i = 0; i < T; i++) 	{ 		y = 0, x = 0; 		tem = 0; 		for (m = 0;m < strlen(s); m++) 			s[m] = '\0'; 		scanf("%d%lld%s", &n, &k, s); 		for (j = 0; j<n; j++) 		{ 			switch (s[j]) 			{ 			case 'U':y++; break; 			case 'D':y--; break; 			case 'R':x++; break; 			default :x--; break; 			} 			tem = (((tem) >(abs(x) + abs(y))) ? (tem) : (abs(x) + abs(y))); 		} 		y *= (k - 1); 		x *= (k - 1); 		for (j = 0; j<n; j++) 		{ 			switch (s[j]) 			{ 			case 'U':y++; break; 			case 'D':y--; break; 			case 'R':x++; break; 			default:x--; break; 			} 			tem = (((tem) >(abs(x) + abs(y))) ? (tem) : (abs(x) + abs(y))); 		} 		ans[i] = tem; 	} 	for (i = 0; i < T; i++) 		printf("%d\n", ans[i]); 	return 0; } 改成这样了，成答案错误了呜呜呜

引用 1 楼 user-2的回复:scanf("%d%", &T); 这个输入格式有问题吧，你确定你是以 数字% 这样的格式来输入？ 多打了个%，谢谢哈😁可是删掉以后还是运行时错误😭😭😭


Question: 一个简单入门C语言

希望对你有帮助：https://blog.csdn.net/it_xiangqiang/category_10581430.html 希望对你有帮助：https://blog.csdn.net/it_xiangqiang/category_10768339.html

建议在ubuntu下使用code blocks进行开发。

看不到具体情况，黔驴技穷了  要不换个编译器吧，dev、vs、CLion随便选

引用 5 楼 與蘤舊縐的回复:这什么软件，我觉得肯定是没编译成功，程序是没问题的，洋文也没这么菜，他说的是没有生成，我想你总不会没有保存文件吧，这样的话也是服了你了 。。。codeblocks

引用 3 楼 與蘤舊縐的回复:那你点"是"是什么反应 点了是之后还是有点是 否 和 取消这个窗口

那你点"是"是什么反应

引用 1 楼 與蘤舊縐的回复:没有问题，只是你还没有编译而已，先编译再运行 编译了凑够十个字凑够十个字

没有问题，只是你还没有编译而已，先编译再运行

程序对着呢。运行出来了


Question: 子函数的编程

其实，string.h中就有与之类似的函数：strcat()或strncat()  给出strcat()的实现方法（ my_strcat() ）：  char *my_strcat(char *dest, const char *src){ 	char				*str = dest; 	while(*dest) 		dest++; 	while(*dest++ = *src++); 	return str; }


Question: 有关排序的一小部分优化

引用 8 楼 寻开心的回复:这个是二路归并，求的是速度啊 那个释放内存麻烦不到哪儿去了， 结果出来后memmove / memcpy都可以，那个速度相比于算法来说不占时间啊 搞复杂了，效率反而下来，就丧失了归并算法的本意了是不是 不想耗内存，冒个泡就好了，  执行效率和 “麻烦” 你选什么呢？ 找个平衡而已，各种操作都试一下，没事干，就折腾呗

引用 5 楼 user-2的回复:你要是觉得移动数组可能耗时，可以改成内存拷贝试试 不用嵌套循环，两个数组一起循环也可以，也就是上面的变形 for(int i=0,j=0; i<len1+len2&&j<len2;) {     if (*(part1+i) > *(part2+j)) {         int t = *(part2+j);         memcpy(part1+i+1, part1+i, len1-i+j); //用内存拷贝的方式往后挪数组元素         j++;     }     i++; } 还有这种招数明天试试

上面的j++前漏了*(part1+i) = t;

引用 3 楼 user-2的回复:因为两个都是排好序的，所以在第一个数组的基础上插入第二个数组即可 for (int i=0,j=0; i<len2; i++) //第二个数组循环     for (; j<len1+len2; j++) //第一个数组从上次找到的插入位置循环（也就是j不变）         if (*(part1+j) > *(part2+i)) { //和第一个数组比较，找到插入位置             int t = *(part2+i);             for (int k=len1+len2-1-i; k>j; k--)  //第一个数组往后挪                 *(part1+k) = *(part1+k-1);              *(part1+j) = t; //插入位置变为第二个数组的元素             break;//第二个数组插入完后继续下一个元素         } 插排就是后移数组这很难受，本来想优化归并的，这一堆递归下来这么多插排不太确定和上面的比哪个效率高点，现在看起来想压缩空间有点压过头了，毕竟开一个放一个

引用 1 楼 user-2 的回复:既然数组内存连续，直接看作一个数组就好了。第一个数组下标越界就会到达第二个数组，所以直接用下标从第一数组的开始循环到两个数组的长度和即可。  这点我当然知道，本来就是一个数组拆分出来的  如果直接把两个数组当一个排序，那我给他拆出来干嘛呢，这就更慢了  我倒是想不依靠第三个数组，直接按那种方式排，但是暂时想到的办法很混乱，程序复杂度飙升


Question: C语言实验报告怎么写？

实话实说呗，只要你的程序足以让老师满意


Question: PAT A1051有人知道这个段错误是为什么吗

已经找到原因了，st.top() == str[checkPointer] && !st.empty()这句调个顺序就行了

感谢回复。我试了改大，还是没用

数组定义的小了


Question: 请大佬指点

引用 8 楼 sankernel 的回复:#include <algorithm> #include <iostream> #include <map> #include <vector>  struct Employee {     std::string id;     std::string name;     std::string birthDay;     int salary; };  // 按值升序排序 int CompUp(const std::pair<std::string, int>& x, const std::pair<std::string, int>& y)   {   	return x.second < y.second;   }  // 按值降序排序 int CompDown(const std::pair<std::string, int>& x, const std::pair<std::string, int>& y)   {   	return x.second > y.second;   }  void SortMapByValueUp(std::map<std::string, int>& tMap, std::vector<std::pair<std::string, int> >& tVector) {   	for(std::map<std::string,int>::iterator it = tMap.begin(); it != tMap.end(); it++)   	{   		tVector.push_back(make_pair(it->first,it->second)); 	}  	std::sort(tVector.begin(), tVector.end(), CompUp); }  void SortMapByValueDown(std::map<std::string, int>& tMap, std::vector<std::pair<std::string, int> >& tVector) {   	for(std::map<std::string,int>::iterator it = tMap.begin(); it != tMap.end(); it++)   	{   		tVector.push_back(make_pair(it->first,it->second)); 	}  	std::sort(tVector.begin(), tVector.end(), CompDown); }  void Test() {     std::map<std::string, Employee&> mapID2Employee;     std::map<std::string, int> mapID2Salary;      mapID2Salary.insert(std::pair<std::string, int>("1001", 20000));     mapID2Salary.insert(std::pair<std::string, int>("1002", 25000));     mapID2Salary.insert(std::pair<std::string, int>("1003", 15000));      std::vector<std::pair<std::string, int>> vecAfterSort;     SortMapByValueUp(mapID2Salary, vecAfterSort);     for (std::vector<std::pair<std::string, int>>::iterator it = vecAfterSort.begin(); it != vecAfterSort.end(); ++it)     {         std::string sID = it->first;         int salary = it->second;          std::cout << sID.c_str() << " " << salary << std::endl;          // 再根据mapID2Employee[ID]获取Employee信息     } }  int main() {     Test();      system("pause");      return 0; }   谢谢，这是c++版本吧

引用 4 楼 與蘤舊縐 的回复:插排容易点吧，简单例子给你一个，数组插入排序     void exchange_item(int *num, int i, int j) {     int temp = *(num + i);     for (int pos = i; pos > j; pos--) {         *(num + pos) = *(num + pos - 1);     }     *(num + j) = temp; }  //free to choose the sort range void insertion_sort(int *num, int len) {     for (int i = 1; i < len; i++) {         if (*(num + i) < *(num + i - 1)) {             for (int j = 0; j < i; j++) {                 if (*(num + j) >= *(num + i)) {                     exchange_item(num, i, j);                     break;                 }             }         }     } }  好的，谢谢，我消化消化

好的，谢谢，我试一试

好像说错了，输入过程排序好像效率高一些

怎么排序都可以，关键是考虑效率，每次输入都排序估计效率会低，个人觉得输入完后再排序好一点 排序方法和数组一样，只不过数组用下标(比如冒泡 if a[i] > a[i+1]) )，链表用next指针而已( if (a.data > a.next.data) )，思路都是一样的


Question: 绝对值排序

希望对你有帮助：https://blog.csdn.net/it_xiangqiang/category_10581430.html 希望对你有帮助：https://blog.csdn.net/it_xiangqiang/category_10768339.html

输入的话，用getchar读入一行字符，直到遇到换行符停止就可以了 排序的话随便冒泡什么都可以 LZ自己先写吧，有错再把代码贴出来

弄个结构体就行


Question: 数组赋值

可以是可以，但浪费空间，也不符合正常的使用原则，更容易出错，最好不要这么做 加一个={0}就能对不过是将数组初始化了，你的程序中多处用了a[i]与0的关系式，可能是由于未赋初值导致的一些错误，具体未细看


Question: c语言编程题

引用 3 楼 user-1的回复:[quote=引用 2 楼 狠狠摔了一跤 的回复:] 我输入的就是整型，但它显示出来就是这些英文 看错了，我还以为你是从文件读取信息 你这个相当于字符流写文件，所以整形都被转成字符了，像这种结构体写文件一般都用二进制，读取也用二进制 fp=fopen("d://stud.txt", "wb") //用二进制写文件  如果非要用文本来写文件，可以用个字符数组buf把结构体都转成字符串后再写 char buf[100] sprintf(buf, "%s %s %s %d", stu[i].num, stu[i].name, stu[i].sex, stu[i].ywscore); //转成字符串再写文本文件 fwrite(buf, sizeof(char)*strlen(buf), 1, fp); [/quote] 我试一下。谢谢你啦.

引用 2 楼 狠狠摔了一跤 的回复:我输入的就是整型，但它显示出来就是这些英文 看错了，我还以为你是从文件读取信息 你这个相当于字符流写文件，所以整形都被转成字符了，像这种结构体写文件一般都用二进制，读取也用二进制 fp=fopen("d://stud.txt", "wb") //用二进制写文件  如果非要用文本来写文件，可以用个字符数组buf把结构体都转成字符串后再写 char buf[100] sprintf(buf, "%s %s %s %d", stu[i].num, stu[i].name, stu[i].sex, stu[i].ywscore); //转成字符串再写文本文件 fwrite(buf, sizeof(char)*strlen(buf), 1, fp);

引用 1 楼 user-1的回复:语文成绩输入格式是整形，但你的文件内容是d，y，y，o，n，跟输入格式的类型不一样，你把这些改成数字试试 我输入的就是整型，但它显示出来就是这些英文


Question: malloc函数开辟空间的意义

懂了懂了懂了懂了谢谢大家

malloc是在堆上申请内存空间， 需要需要分配足够的长度 malloc（4）也就4个字节，后面的赋值和操作都越界了。

你这个只是申请了4个字节的内存空间，i指向了这块内存空间，程序没错，是因为这块内存空间后面的内存没有被其他程序占用，所以程序侥幸能运行 正常做法都是用多少内存就申请多少内存 i = (int*)malloc(10*sizeof(int)); //10个int大小的空间

之所以排在后面，是因为你使用的赋值是i[j]，但如果这部分空间被别的进程占用，那么程序就进行不下去了，所以为了安全考虑，必须开辟足够大的空间

输出是个随机数只是侥幸而已，你只开4个int的空间，只能存4个，其他的6个不过是正好排在你开辟的空间的后面，i[j]其实是*(i+j),正好给你取到了，但这样无疑是不安全的


Question:
建立单向链表
输入打乱顺序
输出按从小到大的顺序

就冒泡吧 #include <stdio.h> #include <stdlib.h> #include <string.h>   typedef struct ListType { int n; struct ListType * next; } List;  // 创建一个带有头节点的单项链表 List * CreateList(int n, int * v) {     if (n<=0 ) return NULL;     List * pHead = (List*) malloc(sizeof(List));     List *p = pHead;     pHead->n = n;  // 头节点的n，用来记录链表的长度了     while (n--) {         p->next = (List*) malloc(sizeof(List));         p->next->n = *v++;         p = p->next;     };     p->next = NULL;     return pHead; };  void PrintList(List * pList) {     List * p = pList;     while (p->next) {         printf("%d ", p->next->n);         p = p->next;     }     printf("\n"); }  void SortList(List * pList) {     if ( NULL == pList) return ; // 空     if ( pList->n <2 ) return;  // 只有一个或者是没有，排个屁     int x=0;     while ( x < pList->n ) {         List * p = pList->next;         List * pNext = p->next;         while ( p && p->next ) {             if ( p->n > pNext->n) {                 int t = p->n;                 p->n = pNext->n;                 pNext->n = t;             }             p = pNext; pNext=pNext->next;         }         x++;     } } int main() {     int init[] = {3, 8, 4, 7, 6, 2};     List * pList = CreateList(6,init);     PrintList(pList);     SortList(pList);     PrintList(pList);     return 0; }

研究几天也没 有木有别的方法

简单点的办法那就另建一个链表，首先搜索原链表里的数据，最好把数据和位置都记录下来，那么只需要挨个找到原链表的相应结点，复制一份接到新链表上，当然了有了数据直接按从小到大的顺序创建一个新链表更快，实在不行就这么做  正常的操作就直接修改原链表，排序和数组是一样的，你需要额外实现的是结点的交换、数据的查找

建立链表， 头插法插入数据， 冒泡进行排序。


Question: 请大佬指点

谢谢

没有，以前的vs在程序结束后都会自动关闭控制台窗口，从vs2019开始就由采用按任意键关闭了

引用 1 楼 與蘤舊縐 的回复:这个框原本好像是下面的一个标签吧，你给他抠出来了？  看看能不能拖回去  或者点一下右上角的倒三角形，看看能不能点出设置来 嗯，又把它摁回去了 还有这个东西，我记得起初没有这么复杂的东西，hello world下面的那些东西有什么影响吗


Question: c语言基础问题，char的数组

二维数组呗 char str[][36] = {"aaa", "bbb", "ccc"};

char *  type[] = {"aaa", "bbb", "ccc"};  我一开始也以为是可行的，试了下，不可以。因为“aaa”这些是const char*,不能初始化char*。 const char *  type[] = {"aaa", "bbb", "ccc"}; 这样倒是可以，可就是需要声明为const，后续没法修改了。

参考一下 char *  type[] = {"aaa", "bbb", "ccc"};  //字符指针数组

这么不行滴，你可以在编译器上运行试一下

//将数据拷贝到堆上去就可以修改了 #include <stdio.h> #include <string.h>  int main() {     const char *  type[] = {"aaa", "bbb", "ccc"};      char * arr[3];     for(int i=0; i<3; i++)     {         arr[i]=(char *)malloc(sizeof(strlen(type[i])));         strcpy(arr[i],type[i]);     }      for(int i=0; i<3; i++)     {         printf("%s\n",arr[i]);     }      return 0; }

“aaa”这种字符串当做指针来时使用的时候， 它就是const char* ，你无法修改的， 分配内存就分配到只读区域里面去了 要想初始化，并且能修改，那么    要么是数组，也就是二维数组那个样子    要么是动态的内存了，问题是动态内存的分配和初始化都是分开的，除非callc这种都初始化成0的  vector那种，相当是存在一个初始化构造函数，在里面实现内存分配和赋值的，只是代码表现上简洁了


Question: 用选择法排序

k没有赋开始值，也就是在min=p[i]的同时，要设定k=i，否则后来的if(i != k)没有意义


Question: C语言问题：为什么两次的b输出不一样？求解

希望对你有帮助：https://blog.csdn.net/it_xiangqiang/category_10581430.html 希望对你有帮助：https://blog.csdn.net/it_xiangqiang/category_10768339.html

引用 3 楼 qybao的回复:这个我也没想明白，怀疑是打印格式的问题。 如果是精度问题，那么一开始精度就丢失了，把丢失精度后的信息保存在b的内存里，之后b的内存没再变化（此时已经不存在精度问题）。所以即使精度丢失，因为b的内存信息没有再发生变化，所以两次打印的都是b的内存信息，而b的内存信息都是一样的，按理打印结果应该一样。如果不一样，只能怀疑是打印格式了，估计是b内存的二进制信息又做了什么转换才打印，导致两次转换结果不一样。 谢谢👍👍👍👍👍👍👍👍👍👍👍👍👍👍👍👍👍👍👍

精确度的问题吧，改个更高精度的数据类型应该就可以了

定义float而float有效数字（精度）只为7位，也就是说在1234567后面的几位数字已经不准确，把float改成double就好咯


Question: 问题

引用 1 楼 user-2的回复:你是不是看错答案了？而且题目应该要求a为小于10的正整数 我的理解 ① 应该是 term=0 ② 应该是 term = term*10 + a; 如果没有小于10的限制条件呢，是不是就变成a的a次方乘以10的n-1的阶乘的次方了呢？

很明显答案错了，楼上答案是对的

即使没有小于10的限制，你的推导也是不对的，比如a是2，n为2的情况下，你的推导结果就是2^2*10=40，明显不符合题目要求22


Question: 大佬帮忙看一下

引用 7 楼 寻开心 的回复: 先去找书，看看字符串，和字符串函数部分去  先补课，  再改代码去 好的，确实忘了好多

先去找书，看看字符串，和字符串函数部分去  先补课，  再改代码去

哦哦，好的，我再改一改

if （NULL ！= strchr（cNameTemp， ‘#’））  查找#是否在名字字符串当中出现  输入#作为名字结束，应该是判断cNameTemp[0] 是否是‘#’ 如果是判断名字里面是否有#，就用strchr函数来  字符和字符串整个理解就不到位， 好好看书去      gets_s(cNameTemp);     //添加结点，当输入#时结束     while (cNameTemp[0] != '#')     {     printf("input phonenumber");         gets_s(cNumberTemp);           //申请结点并填入数据         pStrPeoTemp = (struct people*)malloc(sizeof(struct people));         pStrPeoTemp->cName[20] = cNameTemp[20]; // 改   strcpy         pStrPeoTemp->cNumber[12] = cNumberTemp[12];  // strcpy         pStrPeoTemp->pStrNext = 0;         //接入链表         if (!pStrPeoHead)             //接入第一个结点，头指针，尾指针均指向该结点             pStrPeoHead = pStrPeoTail = pStrPeoTemp;         else         {             //接入非第一个结点             pStrPeoTail->pStrNext= pStrPeoTemp;             pStrPeoTail = pStrPeoTemp;         }         printf("input name ");         gets_s(cNameTemp);     }

pStrPeoTemp->cName[20] = cNameTemp[20];  pStrPeoTemp->cNumber[12] = cNumberTemp[12]; 这是做什么呢？   字符串赋值，不是这样， 要用strcpy(....) strcpy( pStrPeoTemp->cName, cNameTemp);  后面的相等判断也要用 strcmp(....) if ( strcmp( pStrPeoTemp->cName, cNameTemp)== 0 ) 这个才是两个字符串是否相等

if (pStrPeoTemp->cNumber[12] == cNumberTemp[12])你的查找条件有问题，存的是字符串，比较用strcmp

嗯，谢谢，改成cNameTemp[0] != '#'了，可以结束了，但查找时输入姓名却没有打印号码，是为什么呢？

while (cNameTemp[20] != '#')你的条件是[20]最后一个字母为#,输入用的是gets_s是串不能保证[20]的值的，你可以换个条件，         printf("input name ");         gets_s(cNameTemp);         printf("input phonenumber");         gets_s(cNumberTemp); 你的是先输入cNmameTemp,不管cNameTemp是不是结束符，都会要求输入下个


Question: C语言大数加法的一个疑问求解

这个注释就已经写的很明白了，是去掉前缀的0，只是处理不对 LS说的是一种情况，但如果输入合法数据 比如输入 s="9"， ss="98"，为了方便说明，把长度110改为5 保存到数组 a={9,0,0,0,0},b={8,9,0,0,0},max=2，max在红字位置 相加结果 c={7,0,1,0,0}; max在红字位置 要去掉前面的0，只需要定位max的位置，然后从max倒序 while(c[max]!=0&&max<数组长度5) max++; 就可以了，因为上面红字位置为'1', 所以while循环成立，max变为3，即蓝色的位置 {'7','0','1',0,0}，然后退出while循环 所以 for(i=max-1;i>=0;i--) 倒序输出（从上面的蓝色位置减1位开始，也就是就max-1开始）就可以得出结果  所以如果s和ss输入前面带0的数据，应该要去掉后再存入a和b才是正确的处理方法

别人写的程序，全靠猜。我猜1：防止输入0003  5 输出 0008；2：判断是否有进位~~不过写的是错的，应该将： while(c[max-1]==0&&max!=1)//去掉前缀0 max--; for(i=max-1;i>=0;i--)  改为： while(c[max]==0&&max!=0)//判断是否有进位，并去掉前缀0 max--; for(i=max;i>=0;i--)


Question: 大佬这什么情况

嗯，解决了，记性不太好

引用 3 楼 ?Victor.?? 的回复:所有用到malloc函数都要用这个头文件吗，还是只有vs 这是标准c的头文件库，不光是vc https://zh.cppreference.com/w/c/header

头文件问题 #include <stdlib.h>

所有用到malloc函数都要用这个头文件吗，还是只有vs

#include<stdlib.h>

#include<malloc.h>


Question: 请问这个gets为什么不对

引用 1 楼 與蘤舊縐 的回复:gets_s okk

估计是头文件吧 #include <iostream>


Question: 新手学c求指点

具体报错贴出来


Question: while(getchar() != '\n')         continue;这个命令怎么理解

发现上一句表达不准确，更正下， while(getchar() != '\n')用于回收scanf()遗留在输入缓冲里包括回车符在内的遗留数据，免得干扰下一个getchar()这类输入函数的功能

while(getchar() != '\n')用于回收scanf()遗留在输入缓冲里的回车符，免得干扰下一个getchar()这类单字符函数功能

相当于清空输入缓存，比如你在scanf的时候输入了 123 xxooxxooxxoo回车 num获得123后，后面的字符还在输入缓存里，如果不清空，会影响后面的s_gets(也就是fgets，它从标准输入读取数据，会得到有脏数据)

你这么写while(getchar() != '\n'){};完全没用呀，你得用变量来接受输入的字符，如果输入的是getchar就不会拿，直接跳出循环了

这个语句我理解的是为了解决用户一次性输入多个数字或者字母的问题，同理这个还可以这样写while(getchar() != '\n'){};


Question: c语言命令行*

希望对你有帮助：https://blog.csdn.net/it_xiangqiang/category_10581430.html 希望对你有帮助：https://blog.csdn.net/it_xiangqiang/category_10768339.html

引用 9 楼 qybao的回复:如果是在命令行输入3*5做成main的启动参数，就属于后者，用单引号或双引号括起来 即 experiment.exe “3*5” 评论不能发图片 我私信你 你回我一下 不然发不了消息

vs不是这样，

引用 4 楼 qq_46049078 的回复:那要怎么办 我是小白 写一个简单的计算程序 这个*在命令行里识别不了 我的程序就有问题 谢谢谢谢 你可以试试用单引号或双引号，或者用转义符 experiment.ext '*' //单引号 experiment.ext "*" //双引号 experiment.ext ^* //转义

你是在程序中输入还是在程序启动时作为main方法的参数传给程序？ 如果是前者，不需要转义，直接输入*就可以。 如果是后者，需要转义或用单引号双引号括起来。 你最初的问题描述应该属于后者，但你追加的提问却属于前者。最简单明的提问就是直接把你的代码贴出来。

引用 6 楼 qybao的回复:[quote=引用 4 楼 qq_46049078 的回复:] 那要怎么办 我是小白 写一个简单的计算程序 这个*在命令行里识别不了 我的程序就有问题 谢谢谢谢 你可以试试用单引号或双引号，或者用转义符 experiment.ext '*' //单引号 experiment.ext "*" //双引号 experiment.ext ^* //转义[/quote] 好像不太懂，我的意思是比如我在命令行输入3*5，然后程序就要识别那个计算符号是+-*\里的哪个，然后执行哪个函数，这个*号他和我写的程序里面*他不能相等，我怎么办

引用 2 楼 qybao的回复:c是命令行的特殊符号，默认是显示当前文件夹的所有文件 那要怎么办 我是小白 写一个简单的计算程序 这个*在命令行里识别不了 我的程序就有问题 谢谢谢谢

引用 1 楼 user-4的回复:* 在传到 main 之前被系统智能替换为当前目录的文件列表了。 那要怎么办 我是小白 写一个简单的计算程序 这个*在命令行里识别不了 我的程序就有问题 谢谢谢谢

c是命令行的特殊符号，默认是显示当前文件夹的所有文件

* 在传到 main 之前被系统智能替换为当前目录的文件列表了。


Question: 求助关于c11的几个问题

c的确不支持 gets_s 等带 _s 的函数，得另换函数。第二个问题不知道。

是的，然而这是一个可选组件，所以 gcc 有理由不去实现，事实上它也确实没实现。

引用 1 楼 apkipa1的回复:gcc 不支持 gets_s 等带 _s 的函数，请另换函数。第二个问题不知道。 gets_s()不是C11标准里面的吗？


Question: VS2017 能不能一次设置，对所有的项目都有效呢？

我的问题和你一样，我现在解决了，可以看一下这篇文章作参考 https://xcosmic.blog.csdn.net/article/details/107297837 如果你想把你那个属性变成默认的话直接改那个属性管理器user结尾的就行

配置所有管理器，增加你自己的定义选项，同类的程序直接选你定义的，不用DEBUG\release


Question: 求解啊

输入之后不能显示输出，直接报错是为什么


Question: 新手求指点

引用 6 楼 ?Victor.?? 的回复：[quote=引用 5 楼 Iced Tea 的回复:] [quote=引用 4 楼 ?Victor.?? 的回复：][quote=引用 3 楼 Iced Tea 的回复:] [quote=引用 2 楼 ?Victor.?? 的回复：]#include<stdio.h> int main() { 	int i; 	float sum=0,average; 	int num; 	float a[5]={0}; 	do{ 		printf("input number:"); 		scanf("%d",&num); 	}while(num<=0||num>5); 	printf("input score:"); 	for(i=0;i<num;i++){ 		scanf("%f",&a[i]); 		sum+=a[i]; 	} 	average = sum/num; 	printf("%5.2f\n",average); 	return 0; } 试试这个，好像没有问题还是不行呀[/quote] 你输入的是什么？[/quote]3  90 92 92显示30  2 4，16显示2怎么试平均值都是第一个值/num [/quote]   咦？？？[/quote]好吧

引用 5 楼 Iced Tea 的回复:[quote=引用 4 楼 ?Victor.?? 的回复：][quote=引用 3 楼 Iced Tea 的回复:] [quote=引用 2 楼 ?Victor.?? 的回复：]#include<stdio.h> int main() { 	int i; 	float sum=0,average; 	int num; 	float a[5]={0}; 	do{ 		printf("input number:"); 		scanf("%d",&num); 	}while(num<=0||num>5); 	printf("input score:"); 	for(i=0;i<num;i++){ 		scanf("%f",&a[i]); 		sum+=a[i]; 	} 	average = sum/num; 	printf("%5.2f\n",average); 	return 0; } 试试这个，好像没有问题还是不行呀[/quote] 你输入的是什么？[/quote]3  90 92 92显示30  2 4，16显示2怎么试平均值都是第一个值/num [/quote]   咦？？？

引用 4 楼 ?Victor.?? 的回复：[quote=引用 3 楼 Iced Tea 的回复:] [quote=引用 2 楼 ?Victor.?? 的回复：]#include<stdio.h> int main() { 	int i; 	float sum=0,average; 	int num; 	float a[5]={0}; 	do{ 		printf("input number:"); 		scanf("%d",&num); 	}while(num<=0||num>5); 	printf("input score:"); 	for(i=0;i<num;i++){ 		scanf("%f",&a[i]); 		sum+=a[i]; 	} 	average = sum/num; 	printf("%5.2f\n",average); 	return 0; } 试试这个，好像没有问题还是不行呀[/quote] 你输入的是什么？[/quote]3  90 92 92显示30  2 4，16显示2怎么试平均值都是第一个值/num

引用 3 楼 Iced Tea 的回复:[quote=引用 2 楼 ?Victor.?? 的回复：]#include<stdio.h> int main() { 	int i; 	float sum=0,average; 	int num; 	float a[5]={0}; 	do{ 		printf("input number:"); 		scanf("%d",&num); 	}while(num<=0||num>5); 	printf("input score:"); 	for(i=0;i<num;i++){ 		scanf("%f",&a[i]); 		sum+=a[i]; 	} 	average = sum/num; 	printf("%5.2f\n",average); 	return 0; } 试试这个，好像没有问题还是不行呀[/quote] 你输入的是什么？

引用 2 楼 ?Victor.?? 的回复：#include<stdio.h> int main() { 	int i; 	float sum=0,average; 	int num; 	float a[5]={0}; 	do{ 		printf("input number:"); 		scanf("%d",&num); 	}while(num<=0||num>5); 	printf("input score:"); 	for(i=0;i<num;i++){ 		scanf("%f",&a[i]); 		sum+=a[i]; 	} 	average = sum/num; 	printf("%5.2f\n",average); 	return 0; } 试试这个，好像没有问题还是不行呀😂

float a[5]={0}  改为 float a;  下面   scanf("%f", &a);

什么都没有，累计，while也是错的 #include<stdio.h> int main() {     int i;     float sum=0,average;     int num;     float a[5]={0};     do{         printf("input number:");         scanf("%d",&num);     }while(num<=0||num>5);     printf("input score:");     for(i=0;i<num;i++){         scanf("%f",&a[i]);         sum+=a[i];     }     average = sum/num;     printf("%5.2f\n",average);     return 0; }

你可以把所有值都初始化试试，在for循环里printf  a[i],sum,在循环外面也printf sum 试试，看哪步不对


Question: 如何解决“TAP-Windows”设备工作一段时间后停止工作的问题?

补充：         核对写入TAP设备的IP协议数据报都是有效的，这很好论证只需要把后面通过“WriteFile”写入到TAP设备的IP数据报文记录一些，在重启TAP设备之后写入TAP设备；查看运行TAP设备的操作系统主机是否可以处理（一般多为UDP协议数据报测试；TCP协议数据报基本是向外TCP_SYN、不太容易进行这样的测试）。


Question: 新手小白求助！自学C语言，学到循环语句部分，有个问题想求教！谢谢了！

这么大，unsigned long long也装不起

S 你可以用 unsigned long 变量表示，然后 while 循环的测试表达式把 50 换成小一点的数字试试

因为最后的乘积已经超出了 int 变量所能表示的最大范围

double来计算吧 如果要求必须是整数，就弄个长整数的乘法吧 34243224 702511976 248246432 895208185 975118675 053719198 827915654 463488000 000000000 double: 3.424322e+079  #include <stdio.h> #include <string.h> #define MAX 100 int facts[MAX]; int factd(int n) { // 10进制的乘法  	if ( 0==n ) { // 0！ = 1  		facts[0] = 1; 		return 1; 	} 	memset(facts, 0, MAX*sizeof(int)); 	facts[0] = 1;  int len = 1;   	for (int i=1; i<=n; i++) { 		int  extend = 0; 		long long int d; 		for ( int j=0; j<len; j++) { 			long long int a = facts[j]; 			d = a * i * 2 + extend; //a*i+extend就是算阶乘，多个2就是2*4*6这种  			if ( d > 1000000000) {		 				facts[j] = d % 1000000000; 				extend   = d / 1000000000; 			} else 				facts[j] = d, extend=0;  		} 		if ( extend>0) { 			facts[len] = extend; 			len ++; 			extend = 0; 		} 	} 	return len;   }  void printd(int len) { 	printf("len:%d\n", len); 	if (len>1) { 		printf("%d ", facts[len-1]); 		for ( int i=len-2; i>=0; i--)  			printf("%09d ", facts[i]); 	} else 		printf("%d", facts[0]); }  int main() {     int len = factd(50);  //参数50表示， 100*98*96*....*2;     printd(len);     double d=1;      for ( int i=2; i<=100;i+=2) d *= i;      printf("\ndouble: %le\n", d);      return 0; } ———————————————— 版权声明：本文为CSDN博主「寻开心」的原创文章，遵循 CC 4.0 BY-SA 版权协议，转载请附上原文出处链接及本声明。 原文链接：https://blog.csdn.net/happy__888/article/details/104024922

答案应该是3.52216025511551755696249024065e+79

结果数据范围太大，你可以选择 unsigned long long,如果还不行，就用高精度或大整数吧

可能是结果太大无法显示，你试试代码最前面定义一个typedef long long int;看看有没有结果


Question: 萌新

引用 5 楼 user-2 的回复:[quote=引用 3 楼 與蘤舊縐 的回复:] 找了半天没一个权威点的文档，C99是C99，C89可不认，这个问题几个月前也有人讨论，那篇帖子找不见了，不管是C还是C++，尽量别这么用吧 最权威的文档难道不应该在官网找吗，虽然只有草案是免费提供的。另外，我觉得现在都 2020 了，还讨论 C89 实在是有点不合时宜。VLA 的话我项目里肯定是不用的，不过一些小程序里会用到，毕竟方便。[/quote]  这样的话也没什么好说的，dev的确支持这种写法，他错的原因也确实像你说的那样，用不用看着办，不过提醒一句，学校的测试系统可能过不了  关于C++的话，它的const是真常量了，现在试一下C++98是可以的，后续版本自然也支持，那么就是偶然事件了

引用 4 楼 與蘤舊縐 的回复:话虽如此，但以前试过并不行，不排除编译器的问题 肯定是可以的，这是由于 C++ 不同于 C，会把 const 对象当常量表达式推导(类似的还有 constexpr)，不过我没学过 C++，不知道这是什么时候引入的特性。另外，VLA 是 C 语言独有的，C++ 不支持。

引用 3 楼 與蘤舊縐 的回复:找了半天没一个权威点的文档，C99是C99，C89可不认，这个问题几个月前也有人讨论，那篇帖子找不见了，不管是C还是C++，尽量别这么用吧 最权威的文档难道不应该在官网找吗，虽然只有草案是免费提供的。另外，我觉得现在都 2020 了，还讨论 C89 实在是有点不合时宜。VLA 的话我项目里肯定是不用的，不过一些小程序里会用到，毕竟方便。

话虽如此，但以前试过并不行，不排除编译器的问题

引用 2 楼 user-2 的回复:[quote=引用 1 楼 與蘤舊縐 的回复:] 不可以使用变量定义数组长度，即使用const修饰的变量也是一样  在C++中你这样的写法可能还可以，不过较新的编译器应该也不允许你这么做，而C语言是不支持的 C 语言是支持的，叫做 VLA，这里的问题是变长数组不能被初始化。[/quote]  找了半天没一个权威点的文档，C99是C99，C89可不认，这个问题几个月前也有人讨论，那篇帖子找不见了，不管是C还是C++，尽量别这么用吧

引用 1 楼 與蘤舊縐 的回复:不可以使用变量定义数组长度，即使用const修饰的变量也是一样  在C++中你这样的写法可能还可以，不过较新的编译器应该也不允许你这么做，而C语言是不支持的 C 语言是支持的，叫做 VLA，这里的问题是变长数组不能被初始化。


Question: C

引用 4 楼 apkipa1的回复:其实从语法的角度来讲，你说的并不完全正确。编译器在遇到 extern 时，会先去前文查找，例如： int x; void f() {     extern int x; // 这里编译器能找到上层定义的 x，所以不一定需要链接器帮忙 } 但是： extern int x; // 这里向前找不到 x，并且是纯声明，所以是单纯引用外部的 x void f() {     extern int x; // 编译器能找到上层声明的 x，但由于在引用外部的 x，肯定需要链接器帮忙 } 当然，编译器向前查找时是会出现例外情况的(例如遇到函数内定义的 x)，这时候编译器会默认声明一个具有外部链接的 x。 至于你所说的内层覆盖外层，从作用域来说，我认为是对的。 附：如果有可能的话，去 https://zh.cppreference.com/w/c 上看看，你绝对会受益匪浅。 好的，谢谢哥～～～～～～

extern 声明中的x是个全局变量，在整个程序中，就只有那一个int  x的x是，所以就是它  但找到定义联系起来是链接阶段的事，编译阶段只是 提示引用，放行，不报错（编译器并不知道引用的x实际定义） 但上文的int x行中x有了意思 所以我才说内层覆盖外层 这样理解正确吗？

引用 1 楼 寻开心的回复:你这样写， extern int x和全局的x就是同一个。 int x =3; int main() {     extern int x;     printf("%d", x);     // 这个输出就是3     return 0; }  extern int x; 这是声明， 不是定义， 所以它的作用域，不是在这个位置决定的 extern 的类型，都是全局变量 包含extern声明的作用域在上文不是块作用域吗


Question: c逻辑运算符

引用 2 楼 初学小菜的回复:最好用数组，数组更方便 老师要求的，要用逻辑运算符与或非

引用 1 楼 如风_Antoni的回复:#include<iostream> using namespace std; int main() { 	int a, b, c; 	cin >> a >> b >> c; 	int max, mid, min; 	max = (a > b) ? a : b; 	max = (c > max) ? c : max; 	min = (a < b) ? a : b; 	min = (c < min) ? c : min; 	mid = a + b + c - max - min; 	cout << min << mid <<  max << endl; 	return 0; } 同理四个数比较也可以，加一个变量就可以 要用逻辑运算符&&||！与或非

最好用数组，数组更方便


Question: 如何理解01背包的状态转移方程？

两个放入的不是同一包 对应的是两种不同的方案 所以要比较 如果<=总质量 则要选择在特定的包中放置该物品 如果>=总质量 则继承上面的在(包枚举中)特定的包

引用 楼主 Jennie Libra 的回复:感觉对这一段代码不是很理解  f[i][v]=max{f[i-1][v],f[i-1][v-c[i]]+w[i]}  “f[i-1][v]代表的就是不将这件物品放入背包，而f[i-1][v-c[i]]+w[i]则是代表将第i件放入背包之后的总价值，比较两者的价值，得出最大的价值存入现在的背包之中。” 可是，一个物体放入背包肯定比不放入时的价值大啊，这有什么比较的必要吗？  不放入该背包就不消耗容量，可能放后续背包后总的价值更大

f[i-1][v-c[I]] +.  w[I] 去掉一个    换上另一个

单看这个肯定没必要呀

有一个判断条件你没写，这个是容量作为下标，你得考虑背包是否放满


Question: 为什么代码运行之后输入a,b之后没有输出啊

算法有问题，通过追踪运行来找问题。下面这个代码提供参考： #include <math.h> #include <stdio.h>  int IsPrime(int i) {     int j = 2;     int k = sqrt(i);      if (i < 2)         return 0;      while (j <= k)     {         if (0 == i % j)         {             return 0;         }          ++j;     }      return 1; }  void FindPrime(int* primeArray, int count)// = 200) {     for (int i = 0, target = 2; i < count; ++target)     {         if (IsPrime(target))         {             primeArray[i] = target;             ++i;         }     } }  int main(void) {     int primeArray[200] = { 0 };     int m, n, t, sum = 0;     scanf("%d%d", &m, &n);     FindPrime(primeArray, 200);     if (m > n)     {         t = m;         m = n;         n = t;     }      if (n > 200)     {         printf("输入超范围");         return 0;     }      for (; m <= n; ++m)     {         sum += primeArray[m - 1];     }      printf("%d", sum);      return 0; }


Question: c语言中有类似java中ArrayList和LinkedList的库或者第三方代码用吗？

C需需要是面向过程的语言，没有面向对象那一套，有的只是函数和一堆数据类型，要学c就不要再用java的眼光去审视它，用面向过程的语言，就请先暂时忘记什么叫做面向对象。c语言有标准库，库里面都是函数，如果你想用arraylist这样的，就只能自己写结构体，将相关操作写成一个个函数。

自己写一个链表

评论区人人大牛，人家问你C又没问你C++，在那秀

内核链表了解一下，或者写个用 void* 存数据的

c++ 的 boost库了解下

引用 楼主 wow334的回复:java中，  同一类的东西放在一个集合中很方便，比如一群狗 放在一起，一群人放在一起。在c语言中我要怎么把同一类的放在一起？   我现在弄的链表，它只能把同一类的东西放在一起，比如people，等我要把一些book放一起时，又要重新写一条book链表的增删改查，很麻烦啊  但是java中，一个ArrayList 或者 LinkedList，   它只要   ArrayList  peopleList = new ArrayList  ;              ArrayList  bookList = new ArrayList  然后 peopleList 就可以存people , bookList就可以存book，完全不用为了book再写一条新链表。c语言中有类似java中ArrayList和LinkedList的库或者第三方代码用吗？ C++标准库有很多，

c语言应该没这种吧

引用 8 楼 寻开心的回复:c也可以啊， 无非把里面的节点的数据类型设置成为void *呗 然后自己想怎么解释就做强制数据转换了 是这个理，我在网上找到过linkedlist,hasmap的c语言版本

1. libcstl https://github.com/activesys/libcstl  2. glib2 https://developer.gnome.org/glib/2.26/glib-Doubly-Linked-Lists.html

直接自己写一个存void指针的list，不就行了，void 指针可以转成其他类型的指针。

应该改用java或者自己写结构然后想用的时候include一下

c标准定义在那里， 就是那样了， 在没有新标之前， c提供的就哪些 c++，java的标准里面，已经把template之类的东西都包含在里面， 所以变成了语言的直接支持部分 任何一个编译器自动支持  本质差异就在这儿， 因为只有一个c/c++的标准，  官方只有他， 其他的都不算官方 visual c++自己有一套mfc， 问题是dev c++认吗？  五花八门的编译器，哪一个算是正版官方？ 都不是，都有自己的特点，也有自己的所谓官方工具包，但是都是针对特定的目标的

有啊，去 github 上找一找，一大堆。

不是没有， 以前没有java 和 c++的时候，就是c的天下，软件包多多多的很

谢谢大家！ 我觉得奇怪的是java   c++ 都有官方的， c怎么不弄个类似功能的官方版本呢？

引用 8 楼 寻开心 的回复:c也可以啊， 无非把里面的节点的数据类型设置成为void *呗 然后自己想怎么解释就做强制数据转换了  好的，我用void * 试下， 谢谢！

感觉这些东西都不需要库，从某些开源软件里摘除源码来就可以了。 比如cJson

引用 7 楼 wow334 的回复:[quote=引用 6 楼 user-15 的回复:] array<T,N> (数组容器)  vector<T> (向量容器)  deque<T> (双向队列容器)  list<T> (链表容器)  forward list<T>  都可以用啊 STL基础类就可以  这些是c语言可用使用的吗？  我需要c语言能用的。不是c++的[/quote] 简单的，重封装一下,编译成dll,或lib,纯C代表调用，然后用void *想怎么转都行

引用 6 楼 user-15 的回复:array<T,N> (数组容器)  vector<T> (向量容器)  deque<T> (双向队列容器)  list<T> (链表容器)  forward list<T>  都可以用啊 STL基础类就可以  这些是c语言可用使用的吗？  我需要c语言能用的。不是c++的


Question: 拜托帮一下忙哈

引用 9 楼 牛不才的回复:scanf 这个回车问题，很多刚刚接触C语言的同学都会有疑问，建议去了解一下输入输出流和缓冲区 下面的链接可能有帮助 https://blog.csdn.net/tonglin12138/article/details/85534308 哥哥看下我的帖子，pta刷题只对了一个样例，不知道哪里错了😭

#include<stdio.h> #include<string.h> #include<math.h> int main() { 	int n; 	int l; 	int i, j = 0; 	int m; 	char s[10][8]; 	int x[10][16]; 	scanf("%d\n", &n);//抵消掉回车 	while (n--) { 		gets(s[j]); 		l = strlen(s[j]); 		printf("%d\n", l);//输出这里也加一个回车，好看一下 		j++; 	} 	return 0; }

引用 5 楼 qq_46311368 的回复:[quote=引用 4 楼 m0_46317256的回复:]那我要是想正常输入应该怎么办呢 直接把第一次的不用做正常数据输出吗 要是不想把第一个空间作废有办法改吗 第一次是输入数字，比如   3  然后按回车，计算机实际读入3\n   处理掉的只是这个，对后面的输入输出没有影响[/quote] 嗯嗯 刚刚试了已经好啦呢

引用 2 楼 qq_46311368 的回复:加一个while（getchar（）！=‘n‘） continue； 谢谢 好啦

引用 4 楼 m0_46317256的回复:那我要是想正常输入应该怎么办呢 直接把第一次的不用做正常数据输出吗 要是不想把第一个空间作废有办法改吗 第一次是输入数字，比如   3  然后按回车，计算机实际读入3\n   处理掉的只是这个，对后面的输入输出没有影响

引用 2 楼 qq_46311368的回复:加一个while（getchar（）！=‘n‘） continue； 少打个\     \n是换行符

加一个while（getchar（）！=‘n‘） continue；

scanf读完后会留下一个换行符，被gets读进去了


Question: 想知道为什么代码执行后，缓冲区无法关闭

引用 2 楼 寻开心 的回复：while(k!=1||k!=0){      n*=a;     k--;  }  这个逻辑不对吧， 这个条件永远成立啊，  没有任何数同时==0和==1的！=

引用 5 楼 他们都管我叫郑老师 的回复:[quote=引用 2 楼 寻开心 的回复：]  while(k!=1||k!=0){      n*=a;     k--;  }  这个逻辑不对吧， 这个条件永远成立啊，  没有任何数同时==0和==1的！=[/quote]  正是因为   ！=  所以这个条件才永远是真 如果是1， ！=0满足， ||的结果是真 如果是0， ！=1满足，||的结果还是真 如果其他  上述两个都满足， 结果更是真的不能再真  楼主属于光提问不结帖类型的，本来都不想继续回答了。既然还有人有疑问，就答复一次

“||”是或的意思吧

怎么又给你这个光提问不给分的家伙回答问题了，

很简单，你的程序死机了。


Question: 求助！菜鸟一枚，正在拼题a刷题，这题想半天了不知道怎么错的

问题是 输入的顺序错了 #include<stdio.h> #include<string.h> #include<stdlib.h> struct ifm { 	char name[80]; 	char both[80]; 	char sex[10]; 	char dianhua[80]; 	char phone[80]; }; int main() { 	int n,i, num; 	scanf("%d", &n); 	getchar();//吃掉回车  	struct ifm *uct = (struct ifm*)malloc(sizeof(struct ifm)*n); 	for (i=0;i < n; i++) 	{ 		//姓名 生日 性别 固话 手机 --这个顺序 		scanf("%s %s %s %s %s",  			uct[i].name, uct[i].both, uct[i].sex,uct[i].dianhua, uct[i].phone); 		getchar(); 	}  	scanf("%d", &num);  	int *a= (int*)malloc(sizeof(int)*num);  	for (i = 0; i < num; i++) 	{ 		scanf("%d", &a[i]); 	} 	for (i = 0; i < num; i++)//姓名 固话 手机 性别 生日 	{ 		if (a[i] < n) 		{ 			printf("%s %s %s %s %s\n",  				uct[a[i]].name, uct[a[i]].dianhua, uct[a[i]].phone, uct[a[i]].sex, uct[a[i]].both); 		} 		else 			printf("Not Found\n"); 	}  	free(uct); 	free(a); 	return 0;  }  输出 3 Chris 1984/03/10 F +86181779452 13707010007 LaoLao 1967/11/30 F 057187951100 +8618618623333 QiaoLin 1980/01/01 M 84172333 10086 3 0 1 2 Chris +86181779452 13707010007 F 1984/03/10 LaoLao 057187951100 +8618618623333 F 1967/11/30 QiaoLin 84172333 10086 M 1980/01/01

引用 3 楼 牛不才的回复:好像没什么问题  我也觉得没什么问题，但是他系统说我错了两个测试点，想了好久我都快吐了   我决定跳过这题了

引用 1 楼 牛不才的回复:2 1 7 输出2条数据 分别是 下标1的数据（存在） 下标7的数据（不存在，只有 0，1，2）  结果是对的呀 回复不了图片，这是pat给的三个测试点 0	sample 有查询越界	    答案正确 1 最长字符串，最小N	     答案错误 2	最大N，反复查询同一记录	答案错误

好像没什么问题


Question: 求大神支招，关于for循环跳出问题

引用 19 楼 Meng_Meng_Xin 的回复:他没有说是，一下把数据全部赋值完再输出结果，而且输出的答案和紧接着赋的值还不对应 道理很简单，C 语言有 stdin(标准输入流) 和 stdout(标准输出流)，printf 全部输出到 stdout，scanf 全部从 stdin 接受。在 OJ 上，stdin 和 stdout 对应着两个不同的文件，所以这样子完全可以。而在本地上，stdin 和 stdout 全部被接到了交互式的终端上，于是你就会看到图中输入和输出交叉显示的现象。

我试了上面的方法在题库运行是正确的 #include<stdio.h> int main() { 	int i,e; 	int x[100]; 	int y[100]; 	while(scanf("%d %d\n",&x[i],&y[i])!=EOF) 	{ 		printf("%d\n",x[i]+y[i]); 		i++; 	}  } 但是我自己运行它，觉得它不符合题目标准

while(scanf("%d%d",x[i],y[i])!=EOF){i++}

大概是这么个框架： while (scanf("...", ...) != EOF) {     // 单次操作的代码写在这儿 }

scanf()!=EOF，否则退出

机测不可能模拟人输入的，他多半是给程序提供一段字符串，"12\n23\n……"之类的，一般从文件中提取而来，那么判断EOF应该还是可行的

引用 12 楼 apkipa1的回复:[quote=引用 11 楼 Meng_Meng_Xin 的回复:] 刚刚那个方法超时了 OJ 的话要判断的不是换行符，而是 EOF，scanf 可以直接返回 EOF 的。[/quote] 可以写一下嘛，EFO还没学到呢

引用 11 楼 Meng_Meng_Xin 的回复:刚刚那个方法超时了 OJ 的话要判断的不是换行符，而是 EOF，scanf 可以直接返回 EOF 的。

引用 9 楼 apkipa1的回复:[quote=引用 4 楼 與蘤舊縐 的回复:] [quote=引用 3 楼 apkipa1 的回复:] 这样应该可以： if (getchar() == '\n' && getchar() == '\n')     break;  这样就把正常的输入给打乱了  挺为难的[/quote] 啊，对的，看来只能用 ungetc 来操作了。[/quote] 刚刚那个方法超时了

引用 8 楼 Meng_Meng_Xin 的回复:[quote=引用 7 楼 與蘤舊縐的回复:]其他办法还是有的，但具体函数不太清楚  比如只是到缓冲区查看一下输入的下一个字符是什么，不接收，用作判断  或者接收该字符后回退标志位，让这个字符再被接收一次  或者接收了，存起来，用scanf接收的时候把这部分缺的补上去 上面那个方法可以[/quote]  你试一下连续输入，不要直接两个回车推出了

引用 4 楼 與蘤舊縐 的回复:[quote=引用 3 楼 apkipa1 的回复:] 这样应该可以： if (getchar() == '\n' && getchar() == '\n')     break;  这样就把正常的输入给打乱了  挺为难的[/quote] 啊，对的，看来只能用 ungetc 来操作了。

引用 7 楼 與蘤舊縐的回复:其他办法还是有的，但具体函数不太清楚  比如只是到缓冲区查看一下输入的下一个字符是什么，不接收，用作判断  或者接收该字符后回退标志位，让这个字符再被接收一次  或者接收了，存起来，用scanf接收的时候把这部分缺的补上去 上面那个方法可以😊

引用 3 楼 apkipa1的回复:这样应该可以： if (getchar() == '\n' && getchar() == '\n')     break; 真的可以，谢谢指导

首先呢这个题挺过分的，什么退出条件都没有，但你还非得退出不可，不然肯定超时  唯一看起来可能的条件的大概就是这两个数的范围了，如果是机测的话看起来不靠谱  真想达到你的效果也是可以的，大不了接收字符串，空串退出，但这引来的问题就多了，暂时只能想到这了

引用 3 楼 apkipa1 的回复:这样应该可以： if (getchar() == '\n' && getchar() == '\n')     break;  这样就把正常的输入给打乱了  挺为难的

引用 1 楼 與蘤舊縐的回复:scanf是不会接受\n的，你把getchar放在scanf下面，那么你提交数据时按的回车会被getchar接收，就会立即退出循环 对啊我想按两下回车再退出循环，该怎么改呢


Question: C语言初学者求助！！！

引用 8 楼 cool99781的回复:是输入a 计算a+=a, a-=a, a*=a分开只是计算吗？ #include <iostream> #include <string> #include <cstdio>  using namespace std;  int main() { 	int a; 	cin >> a;//第一遍  	a += a - a * a;//对不对 	cin >> a;//第二遍 	int a1 = a * a;  	a += a - a1; 	//我也是菜鸡 	return 0; } 就是写一个程序，在键盘上录入a值之后，计算一下a+=a-=a*a还有另一个式子的值

引用 楼主 weixin_46316277的回复:第七个用C应该怎么写啊 我们老师的意思应该是编写一下计算这两个式子的程序，看看结果

引用 2 楼 cool99781的回复:比如1234 %10取出4个位数，再/10，留下123，这样每次就可以变成一种规律，每次%10 怎么办，想明白了吗？ 我只给你这一道题的代码  #include <iostream> #include <string> #include <cstdio>  using namespace std;  int main() { 	int n; 	cin >> n; 	while(n != 0) 	{ 		cout << n % 10 << endl; 		n /= 10; 	 }  	return 0; }  我没有懂这个，您说的这个是第七题嘛？ 第七题我是这么写的 #include<stdio.h> int main() {     int a,a1,a2;     printf("Input a:");     scanf("%d",&a);     a1 = a;     a2 = a;     a1+ = a1- = a1*a1;     a2+ = a2- = a2* = a2;     printf("%d,%d",a1,a2);     return 0; } 应该怎么改正？

引用 1 楼 初学小菜的回复:直接if语句把这两个数的结果进行比较就行，记得换个变量进行操作 #include<stdio.h> int main() {     int a,a1,a2;     printf("Input a:");     scanf("%d",&a);     a1 = a;     a2 = a;     a1+ = a1- = a1*a1;     a2+ = a2- = a2* = a2;     printf("%d,%d",a1,a2);     return 0; } 我这个应该怎么改？

…………//算出结果 //写一个if if(比较) { }

宏常量 #define ……     …… const常量 例： const int n = 100; n = n + 1; 就会报错

直接if语句把这两个数的结果进行比较就行，记得换个变量进行操作


Question: 指针做形参时，函数中用指针指示结果 可是编译器说必须返回一个值

引用 5 楼 qq_46316063 的回复:[quote=引用 4 楼 與蘤舊縐的回复:]你只是用指针直接把原来的变量的值改了，这样你就不用返回值了，看你函数的声明原本应当是想返回修改后变量的值，然后用对应变量接收这个值，达到改变变量值得效果  既然定义了返回值类型float就必须返回一个float类型的值  你这么说说明你完全不了解函数返回机制，先去看看资料吧 谢谢！那应该是用void定义函数吗[/quote]  没错，当然你也可以返回值，而不在函数里直接修改外部变量

引用 4 楼 與蘤舊縐的回复:你只是用指针直接把原来的变量的值改了，这样你就不用返回值了，看你函数的声明原本应当是想返回修改后变量的值，然后用对应变量接收这个值，达到改变变量值得效果  既然定义了返回值类型float就必须返回一个float类型的值  你这么说说明你完全不了解函数返回机制，先去看看资料吧 谢谢！那应该是用void定义函数吗

改下函数 float sum_diff(....) 把这个float 改成void就好了

引用 1 楼 與蘤舊縐的回复:返回值和形参有什么关系，你看你的函数定义的返回值是float类型，那么就需要返回一个float类型的变量 可是需要输出的结果在函数中已经用指针指示结果了，为什么编译器说必须有一个返回值呢


Question: 萌新for循环顺序遇到问题

引用 8 楼 寻开心的回复:就是告诉你，不明白程序怎么执行的时候，要通过输出这些参与运算的变量的值， 然后根据这些输出结果来看看他们如何执行的 十分感谢，我明白了，谢谢大佬直观的讲解，我能明白你的意思了。以后自己可以多练习练习这个对自己提高肯定很大，之前就比较迷，看不懂就看不懂了，现在我可以自己去研究了哈哈

你不是不理解代码是怎么运行的吗，那就把代码运行过程当中的各个变量情况输出出来 那个示例代码的意思，就是要输出 比较a[0],a[1]    []里面就是当前的i和j 比较a[0],a[2] 比较a[0],a[3]  调试就是直接在调试工具下看这些变量， 这里无非是把这些变量打印出来更直观的看 如果愿意，你还可以在if语句里面继续写 if ( a[i] > a[j] ) {      printf("\t交换%d和%d的数据\n", i, j);      t = a[i];      a[i]=a[j];      a[j]=t; } 这样看输出结果，就更清楚了，可能是 comapre a[0], a[1]      交换0,1 compare a[0], a[2] 。。。。。

引用 3 楼 寻开心的回复:在if比较前，自己加上printf语句把i和j输出出来，看看谁和谁在比较 for(i....)    for (j....){          printf("compare a[%d] and a[%d]\n", i, j);          if ( a[i]>a[j]) .......    }  这样就能看到执行流程了 不会用IDE调试，就先来最简单的直接打印输出 很不好意思，大佬。那个加的那句printf（...）没看懂。你说的调试是不是在自己写的那一行开头的小按钮按一下这一行变成红色，然后运行，运行过程只会运行到这红色的前一行呢？然后鼠标点某些变量会出现数值。我电脑上那个软件是c++的，但是调试过程中一调试就卡主了然后自己退出我挺懵的。那个直接打印输出又是什么。。就是你写的插入的这行printf吗，我看着有点像那个，之前看过一下东西，好像就是运行前加入这些，然后运行过程这些值都会显示出来不知道是不是这个意思

引用 4 楼 m0_46159488 的回复:[quote=引用 2 楼 N-n-N的回复:]i=0 -> (j=i+1=1->j++ until j<=9) -> i+1=1 ->  (j=i+1=2->j++ until j<=9)  -> i++ until i<=9  这个是嵌套循环，括号里面是第二个循环 感谢大佬，步骤我已经看懂了，就是这样子的我怎么能想到呢，我感觉看到题我只能想到一般的单循环，像这样子嵌套第一次看到，课里还没有听明白，看了你的步骤我才懂了，就像一楼说的有没有练习或者自己用调试思考弄明白，不然我也只是知道这个步骤的过程下次看到能知道这个步骤。[/quote]最好上手实操

引用 2 楼 N-n-N的回复:i=0 -> (j=i+1=1->j++ until j<=9) -> i+1=1 ->  (j=i+1=2->j++ until j<=9)  -> i++ until i<=9  这个是嵌套循环，括号里面是第二个循环 感谢大佬，步骤我已经看懂了，就是这样子的我怎么能想到呢，我感觉看到题我只能想到一般的单循环，像这样子嵌套第一次看到，课里还没有听明白，看了你的步骤我才懂了，就像一楼说的有没有练习或者自己用调试思考弄明白，不然我也只是知道这个步骤的过程下次看到能知道这个步骤。

内层循环进行完再进行外层循环  这种问题建议你自己拿张纸来写，实在搞不懂就单步调试，这样几个例子之后你就能搞明白了，单是看看用处不大


Question: 求大佬帮忙解答

虽然一楼也打错字了，但他说的没错  不过我倒是好奇这编译器怎么没给你的STudent报错呢，难不成你还定义了这个结构体不成

max（p）那行也有问题吧？ max是c++的标准函数， max（a，b）返回两个数大的  你这个max是什么？

print方法的参数是sTudent，注意大小写


Question: C语言

哦，明白了，谢谢大老

引用 6 楼 apkipa1的回复:[quote=引用 5 楼 與蘤舊縐 的回复:] return咱还是加上，总有不支持的编译器 好吧，补充一下，int main 不用写 return 0 是支持 C99 的编译器的特性，如果你在用 vc6 等 IDE / 编译器的话，请手动补上，或者换一个现代编译器。[/quote] 好像有点明白了，谢谢大佬

好像有点懂了，谢谢大佬

引用 5 楼 與蘤舊縐 的回复:return咱还是加上，总有不支持的编译器 好吧，补充一下，int main 不用写 return 0 是支持 C99 的编译器的特性，如果你在用 vc6 等 IDE / 编译器的话，请手动补上，或者换一个现代编译器。

return咱还是加上，总有不支持的编译器

总是写 int main(void) 或者 int main(int argc, char *argv[])，除非你的环境明确规定要使用另一种写法。当然，你可以把 int main 当 void main 的，反正都不需要写 return。

一般都是int，不是int的骚操作新手应该比较难接触到吧，main函数本身就是一个函数，int就是返回值类型，不是返回int当然不能用int main了

引用 1 楼 與蘤舊縐的回复:C99标准一般写int main()  C11一般为int main(void)  原则上C语言主函数必须有返回值，void main的写法早已被废弃 如果我的返回值不是int类型的也可以用into main吗？

引用 9 楼 QGHappyQL 的回复:const int **pp2; int *p1; const int n=13; /*pp2=&p1; *pp2=&n;*/       *p1=10; printf("%d\t%d",**pp2,n);  各位大佬们，请教一下，为何p1就变成指向n的指针了？ 做梦时候才会等， 正常情况下都不等 printf("%p  %p", p1, &n); // 输出指针，看看他们等不等  p1都没有赋值，就*p1 = 10； 这是野指针，错误的用法，没准发生什么后果


Question: C语言求助

1. c89中没有bool，需要自行定义 2. 素数的判定有更快捷的方法  #ifndef bool #define bool int #endif  #ifndef true #define true 1 #endif #ifndef false #define false 0 #endif  void get_valid_number(int *n); bool is_prime(int x);  bool is_prime(int n) { 	int i = 0; 	//if n is divisible by any number greater or equal to 2 and less than n, then n is not prime. 	for (i = 2; i < n; i++) { 		if (n%i == 0) { 			return false; 		} 	} 	return true;  }  void get_valid_number(int * n) { 	//The valid number is either -1 (to exit the program) or an integer greater than 2. 	//A loop is used to implement input validation, that is, user will be asked to  	//enter a valid number over and over again until a valid number is received. 	printf("Please enter an integer greater than 2 to test its primality, enter -1 to exit \n"); 	scanf("%d", n); 	while (*n != -1) { 		if (*n <= 2) 		{ 			printf("Please enter an integer greater than 2 to test its primality, enter -1 to exit \n"); 			scanf("%d", n); 		} 		else 		{ 			return; 		} 	} }  int main() { 	int n=0; 	get_valid_number(&n); //read 	while (n != -1) { //test 					  //process 		if (is_prime(n)) { 			printf("%d is a prime number!\n", n); 		} 		else { 			printf("%d is not a prime number!\n", n); 		} 		//read again then loop back to test 		get_valid_number(&n); 	} 	return 0; }


Question: C语言重定义错误

不一定准确，仅供参考： 1) int a; // 对 a 的试探性定义，此处表现为: 定义 a 为外部链接 ...     int a; // 定义 a 为无链接     extern int a; // 错误: 不能重复声明 a，因为 a 为无链接 ... 2) int x; // 对 x 的试探性定义，此处表现为: 定义 x 为外部链接 ...     extern int x; // 声明 x，引用到上层的 int x     int x; // 错误: 链接类型为无链接，与上层的 int x 的外部链接冲突 ... 3) 两个 int x 都被定义，且有外部链接，链接时自然冲突了。 相关资料: https://zh.cppreference.com/w/c/language/storage_duration https://zh.cppreference.com/w/c/language/extern

引用 1 楼 m0_46300909的回复:对于 1、   和     2、 不是说内层覆盖外层作用域吗，为啥重定义呢 发错了，只是1、中的内层覆盖外层

对于 1、   和     2、 不是说内层覆盖外层作用域吗，为啥重定义呢

1 在同一个作用域当中，你不能声明两个同名的变量     这是编译器的事儿， 它发现同一个作用域下两个同名变量就是不允许    不管是全局变量还是局部变量的区域， int a ； 和extern int a；放在一起声明就是错的  2 你要把extern int x放到主函数的前面，就可以  3 同一个工程当中，两个全局变量还是要共享的， 之所以编译过去，是编译的本c文件，链接是组装，这个时候会产生冲突


Question: 求大佬帮忙

编译器给了警告， 第二个参数缺少， leader_name可能没有自动在尾巴给你补充上0 编译器所有的警告一定要看， 并且消除它

scanf_s("%s", leader_name, 20);  第二个参数别省略了


Question: 萌新

引用 1 楼 與蘤舊縐 的回复：这种简单到没朋友的循环语句建议你自己列表解决，把所有变量列一行，接下来每一行在对应位置写上本次循环时对应变量的值，问别人拖你学习进度，很久都掌握不了斗胆问一下，continue和break在这里都可以吧？

就是33，么得毛病，就是一步一步运行的，这有什么好疑惑的

引用 4 楼 user-4 的回复:[quote=引用 3 楼 與蘤舊縐的回复:][quote=引用 2 楼 user-4 的回复:] [quote=引用 楼主 花海呀的回复:]这运行出来k和n都等于3，求指点，这咋来的 我怀疑你代码打错了，感觉是2，3。[/quote]  3 3没错的[/quote] 抱歉，想差了。k值变了循环也变了。大佬今天很活跃呀，下面好多帖子都有你。[/quote]  天天都有我，真的闲

引用 3 楼 與蘤舊縐的回复:[quote=引用 2 楼 user-4 的回复:] [quote=引用 楼主 花海呀的回复:]这运行出来k和n都等于3，求指点，这咋来的 我怀疑你代码打错了，感觉是2，3。[/quote]  3 3没错的[/quote] 抱歉，想差了。k值变了循环也变了。大佬今天很活跃呀，下面好多帖子都有你。

引用 2 楼 user-4 的回复:[quote=引用 楼主 花海呀的回复:]这运行出来k和n都等于3，求指点，这咋来的 我怀疑你代码打错了，感觉是2，3。[/quote]  3 3没错的

引用 楼主 花海呀的回复:这运行出来k和n都等于3，求指点，这咋来的 我怀疑你代码打错了，感觉是2，3。


Question: 萌新

i控制的是行，你看i的那个for循环每次打印一个回车  j和k控制的是列，一个是空格，一个是*  for(i……){for(j……)}，那么你看外层循环执行一次，i+1，比如一开始i=1，那么一次循环之后i=2，j一开始最大为1，之后最大为2，也就是打印一个空格和两个空格，k同理，所以随着行数的增加，列数也就相应增加

引用 1 楼 與蘤舊縐的回复:for(j=1;j<=i;j++) 注意到j的最大值是i，而每次外循环i的值都会加1，所以列数就多了 您的意思是i代表列数的多少吗？还是不大清楚诶


Question: C

引用 10 楼 apkipa1的回复:extern 根据上下文的不同，意思其实也不同，例如: int a; void f(void) {     extern int a; // 此处引用的是当前文件中的 a，别的文件也能用 } 但如果这么写: extern int a; void f(void) {     extern int a; // 此处引用的是外部的 a } 还能这么写: static int a; void f(void) {     extern int a; // 此处引用的还是当前文件中的 a，别的文件不能用 } 但是不能这么写: static int a; void f(void) {     int a;     {         extern int a; // 未定义行为     } } 受教了受教了～～

引用 8 楼 與蘤舊縐的回复:        ～～～～～～～

引用 4 楼 與蘤舊縐的回复: #include <stdio.h>  int main(void) {     extern int i;     printf("%d", i);     return 0; }   如上，这么一段代码过不了编译，由于i无法找到，如果移去printf这一句，则可以正常运行  “extern引用别处定义的变量，编译器碰见时放行，不报错”这一句你说对了，一旦遇到需要使用该变量或者又出来了一个同名者，那这时候就得算算账了，如你所言重定义或者未定义就可以阻断编译了 明白了，明白了，谢谢

引用 楼主 m0_46300909的回复:1、 _______________________ #include… extern int x;//x定义在别的文件中 ……… _________________________  我知道这个extern是引用别处定义的变量，链接时会处理  我可不可以理解为extern引用别处定义的变量，那么编译阶段编译器往下碰见这个d标识符时，会放行，也就是不报这个未定义错误（前提是这个标识符在extern声明的作用域内）     2、想用一下我对extern的理解 比如#include…… int  x; int main() {int x; extern int x;…}(会报重定义错误) extern引用别处定义的变量，编译器碰见时放行，不报错，内层的int x定义了个x 编译器往下碰见x时，分不清了（同一个x有了两个意思，不知道是哪个了） ，所以报了个重定义错误  问下大神，我这么简单的理解正确吗？ 这个1、中的未定义错误（x已在其他文件中定义）

引用 2 楼 與蘤舊縐的回复:那么只能告诉你，如果extern修饰的变量不存在，又在下面的程序中使用了该变量，即在可以联系到的外部无定义，连编译都过不去 如何x存在，我这粗略的理解正确吗

1、中 那个""d""是多余的，打错了


Question: C语言函数疑问

传入的是那个地址，那个就作为函数里的首地址

引用 3 楼 與蘤舊縐的回复:形参的值取决与你传入的实参，传入的是a+2，自然是a+2 谢谢大佬（至少十个字是咋回事。。）

形参的值取决与你传入的实参，传入的是a+2，自然是a+2

引用 1 楼 與蘤舊縐的回复:a+2（什么时候网页版也有字数限制了） 你的意思是会将a+2作为首地址吗

a+2（什么时候网页版也有字数限制了）


Question: 代码输出相应字符在键盘上的位置

不同的键盘的位置不一样吧，准确的获得要靠键盘的扫描码， 除了ps2这种标准键盘还有莫尔特键盘；  不过就你的问题来说， 做一个二维数组就好了 记录键盘位置     1234567890       qwertyuiop     asdfghjkl     zxcvbnm 按键后查找对应的位置，是比较笨的办法 更好的办法 unsigned int keyboard[256] = {};     keyboard['1']  =  0<<16 + 0;  // 0行0列。  整数的最低16位表示在第几列，高16位表示第几行 然后按什么键，直接查表输出

想来也就两个办法，要么手动录入键盘的键位，要么调用某些个已经实现的库  不明确你的具体需求，因此如何记录键位方法就多了


Question: 比较两个整数的大小，为什么输出的总是第一个数？

希望对你有帮助：https://blog.csdn.net/it_xiangqiang/category_10581430.html 希望对你有帮助：https://blog.csdn.net/it_xiangqiang/category_10768339.html

你那个scanf里应该用了中文逗号

关于这个问题的详细描述，请参考这个推文，点击这里 #include<stdio.h>  int main(){   int max(int x, int y);    int a,b,c;   scanf_s("%d,%d",&a,&b);   c=max(a,b);   printf("max = %d\n",c);    return 0; } int max(int x, int y){   int z;   if(x>y) z=x;   else z=y;   return z; }

你少了判断！

单步调试呗，你看y的值为一个随机值，你就知道传进去的y有问题了。

scanf_s("%d,%d", &a, &b);  注意输入的时候中间有逗号，也注意逗号的中英文，要和scanf_s中的逗号保持一致。

建议楼主调试一下，分步运行。这样容易知道具体原因。

局部变量最好别当返回值

建议楼主使用 scanf_s 函数时不要使用格式控制，因为你永远不知道程序使用者会怎样输入数据，所以会导致程序不健壮。

我也遇到一样的问题了，但是我用的就是英文逗号啊？

感谢楼上的及时且耐心细致的答复，我刚刚试了下，确实如此，问题解决了，非常感谢您！

比如你输入3 全角逗号 1，那么第二个数字的接收就会出现问题，所以始终是第一个大

极有可能你输入时用了中文逗号，scanf_s("%d,%d", &a, &b);%d逗号%d，需要你输入半角逗号


Question: 求各位大神解决一下，c语言顺序表问题

length记录的应该是有效的顺序表的长度， 0就空，1就是有一个 对应的element有效范围是0到length-1才对 可是看你的代码， element的length下标元素是可用的， 然后就导致了多个部分代码很奇怪   1 输出部分。for(i=0;i<=pt->length;i++)     如果只有length个有效， 那么就只能是i<pt->length;   2 insert部分  if(i<1||i>pt->length)//说明i不在范围之内  应该是if (I>=pt->length) 就是不在有效范围内 判断是否满，也应该是 length >= MAXSIZE   传参进来的i就是应该是从0开始的， 而不是i--后再来使用，很别扭的；  c/c++里面人都习惯了从0开始； 如果你非要让用户认为从1开始，那你在输入输出的部分做转化， 不去改代码，程序员从0开始是惯例  后面都是这样的问题


Question: 递归

引用 4 楼 victorial666 的回复:[quote=引用 1 楼 真相重于对错 的回复:] 举个例子下面的代码能看懂吗? void test1(){   cout<<"test1 call"<<endl;    test2();    cout<<"test1 call"<<endl; } void test2(){    cout<<"test2 call"<<endl; } int main(..) {    test1(); } 这个结果是 test1 call test2 call test1 call 吗？ 但是我问的并不是这个意思   [/quote] 你把test2改成test1不就一样啦。

引用 3 楼 寻开心 的回复:up_and_down(3) 调用了up_and_down(4), 那么up_and_down(4)执行完，就会回到up_and_down(3)去继续执行其他的代码 1    2        3            4            4       3    2 1 我有点懂了，谢谢

引用 1 楼 真相重于对错 的回复:举个例子下面的代码能看懂吗? void test1(){   cout<<"test1 call"<<endl;    test2();    cout<<"test1 call"<<endl; } void test2(){    cout<<"test2 call"<<endl; } int main(..) {    test1(); } 这个结果是 test1 call test2 call test1 call 吗？ 但是我问的并不是这个意思

if (n<4)     up_and_down(n+1); 如果n不小于4呢， 这个就不向下进行了，这个函数就要返回，返回就到了上层了， 那个位置n还是3


Question: c语言malloc

char  * func(int n) {       char *p = (char*) malloc( sizeof(char)*n);  // 子函数分配       ....       return p; };  int anotherFunc() {        char * str = func(3);        ....         free(str);   // 不再用这个str的时候就可以free掉         return 0; }

一样free啊？？？


Question: 求问dev-c++这是咋回事

引用 1 楼 寻开心的回复:1 不要用中文路径和文件名 2 换一下编译目标，改成64 debug或者改成32 debug模式再编译一下看看 改成64和32都不行

引用 1 楼 寻开心的回复:1 不要用中文路径和文件名 2 换一下编译目标，改成64 debug或者改成32 debug模式再编译一下看看 还是不行啊不知道为啥


Question: 如何理解这部分的代码呢

这是一坨非常古老的代码 main(_,l)char**l;{6*putchar(--_%20?_+_/21&56>_?strchr(1[l],_^"pt`u}rxf~c{wk~zyHHOJ]QULGQ[Z"[_/2])?111:46:32:10)^_&&main(2+_,l);}  main(_,l)char**l; 这是主函数入口，翻译过来就是 main（int _, char **l) 所以后面的_ 就是表示这个程序被调用时候参数的个数 I是字符串指针， I[0] 这个的程序执行文件的名字， I[1]开始是后面的跟随的一个个参数字符串  后面的代码仔细看也没有什么特别的，只是让那个_ 变量名字给搞的乱而已  main(int argc, char **argv ) {      return 6*putchar( --argc % 20. ? argc + argc/21 & 56 > argc ? strchr(1[l],argc^ "pt`u}rxf~c{wk~zyHHOJ]QULGQ[Z"[argc/2]) ?111:46:32:10) ^ argc && main(2+argc,argv); }  愿意做就继续往下拆解吧， 一坨有一坨

这个是输入字符之后找到字符在键盘上的位置，大概是这个意思，但是没有读懂这个代码。

不懂，只能帮你运行一下，结果是这样的：


Question: C语言求救   大佬捞我一下

我的if括号忘记括起来了。。。天哪，功夫不够，继续学习。 只记升温，如果两天温度连续则要重新计数。

用不到dp，就一次循环就出来了  楼主， 你的if(a<m） 配合的else放哪儿去了 ，  仔细看看吧！！       当这个条件不满足的时候，才是重新统计t，在这个时候更改ans才是最合适的地方， 没有必要每次都去比较t和ans   不确定连续两天温度相同算不算序列内， 自己测试测试吧

这个是最长上升子序列的题型，应该用dp做的，你这么写应该会有问题


Question: C语言函数调用名字改变调用结果会改变吗？

引用 3 楼 AKK188888881 的回复:C 库导出的符号还是 scanf 没变吗？  我并没有调用库函数！！！ 而是把库函数复制粘贴在用户自定义的"stdio.h" 此时不是<stdio.h>！！！然后我调用了它 把里面的scanf改成了scang相应的源文件scanf也改成了scang 我无语了，你只不过是改了 scanf 的声明而已，问题是 scanf 的函数体定义也要对应改名，然而 scanf 的实现在 C 标准库里，你根本改不了。

C 库导出的符号还是 scanf 没变吗？  我并没有调用库函数！！！ 而是把库函数复制粘贴在用户自定义的"stdio.h" 此时不是<stdio.h>！！！然后我调用了它 把里面的scanf改成了scang相应的源文件scanf也改成了scang  但是为什么还是现实scang没有定义？就算我现在还是scanf，scanf还是未定义，因为我调用的文件"stdio.h"的scanf被我改成了scang

头文件不能瞎改。这里是声明了 scang，但是 C 库导出的符号还是 scanf 没变，于是链接时编译器找不到 scang 在哪，然后报错。


Question: 关于freopen的用法问题

int main() {     int a, b;     FILE *stream1;     freopen_s(&stream1, "in.txt", "r", stdin);       freopen_s(&stream1, "out.txt", "w", stdout);     while (cin >> a >> b)     cout << a + b << endl; // 注意使用endl      fclose(stdin);//关闭文件      fclose(stdout);//关闭文件     return 0;  }

freopen_s 和 freopen 的用法不同，可以百度其用法或者选择关闭 SDL 检查。


Question: 求助一下，怎么让下面的代码无限次循环执行?

用 for(;;) 包起来也行

C莫得true

#include <stdio.h> int main(){     int t,i;         while（true） {     scanf("%d",&t);     for(i=1;t>0;i+=2){         t-=i;     }     if(t==0){         printf("Yes");     }     else{         printf("No");     }  }        return 0; }


Question: 我又卡住了

大佬，有点听不懂，我用fprintf和fscanf输出结果日期没错但是下面的都是0

内存结构到磁盘的写入工作， 用一个单独的函数完成 反向从磁盘读取的工作也是一个单独函数完成 程序启动的时候，从磁盘加载数据到内存 数据增删改之后，写入磁盘 查询就是内存结构直接出结果就好了 除非你的内存数据量特别大，有成千上万条，否则完没有必要处处从磁盘来操作

if (fwrite(&t[num], sizeof(struct  teacher), 1, fp) != 1) printf("file write error\n"); 这是写入数据，然后如果输入选择预览就 fread(&t[j], sizeof(struct  teacher), 1, fp); 这不行 fwrite之后，文件指针跑最后去了 fread读回来的只能是eof了 fwrite后，还要fflush或者直接fclose才会保证把数据写入磁盘，否则还在磁盘缓冲区里面呢，马上读也读不出来 fflsh（fp） fseek回到文件头再开始读  此外，为什么要用fread，而不是内存当中提取呢？ 这个逻辑不对 添加，修改了数据后写入文件，查询在内存当中的文件里面进行就好了


Question: 求助！！！C语言scanf()接受的值错误

把  %1s  改为 %s 或 %c 都无法解决

原因是溢出了 d只有1个长度， 读取字符串尾巴会自动加一个'\0' 覆盖了c的值


Question: 为什么不能输入输入listB是建立链表错了吗？

好了不用了我知道我哪错了我输入时没加逗号


Question: 谁能告诉我这个c代码错在哪里？

struct Student * p=(struct Student *)malloc(sizeof(struct Student)); pst->sid = 99; pst->age = 88; 注意,定义的变量名为p

struct Student *CreateStudent(void) { struct Student * p=(struct Student *)malloc(sizeof(struct Student)); pst->sid = 99; pst->age = 88; return p; }  pst又没有定义成全局变量， 这个函数里面就找不到pst的定义 你要把它如同ShowStudent(ps)的方式一样， 函数传参数进来才可以  c语言里面，所有的变量都有自己的有效范围的 函数里面定义的变量，只能在函数内有效。 ShowStudent里面作为参数使用的pst，只在ShowStudent函数内有效  这样改造吧 struct Student *CreateStudent(struct Student * pst) { 。。。。。 }

ShowStudent(ps)的

pst->sid = 99; pst->age = 88; 哪来的pst


Question: 在c语言中要用到  类似java中的ArrayList的功能，一般是怎么做的？

自己实现，或者第三方库，C++用stl，C应该是没了

标准C肯定没有。 用第三方库吧。


Question: 求讲解下公交查询程序换乘怎么整。

有没有人啊！！！！！！！

这个用到算法了，你们应该没有学吧

引用 3 楼 lipjsfds 的回复：[quote=引用 2 楼 初学小菜的回复:]这个用到算法了，你们应该没有学吧 没有学算法，请问怎么整呢。我现在只会让他在一条公交线上乘车[/quote]迪杰斯特拉求最短路径，显示所有路径，这个就看具体怎么yong l

引用 2 楼 初学小菜的回复:这个用到算法了，你们应该没有学吧 没有学算法，请问怎么整呢。我现在只会让他在一条公交线上乘车


Question: C语言extern关键字

我这里简单的定义了一个全局变量，

想用vs2010看一下针对特定的一个语句，编译器有什么操作，不知道如何查看

百度下“链接”，跨文件共享变量

引用 10 楼 apkipa1的回复:就拿你的例子来说一种可能的行为(实际行为会有差距)，extern int x; 告诉编译器当前翻译单元需要导入 _global_x，然后编译器在遇到 x = 10; 时就换成了 _global_x = 10 (汇编为 mov dword ptr ds:_global_x, 10)，而在另一个翻译单元里有一句 int x = 1; 告诉编译器需要将 1 存到内存里，并将其导出为 _global_x，最后就由链接器搜索对应的名称、重新计算内存偏移、重定向内存引用到正确的地方上。 懂了懂了 也就是说链接器去搜索_global_x，，搜索到了，10就能存到那块内存了

引用 2 楼 apkipa1的回复:1. 就是在当前翻译单元内引入这个外部对象，这样编译器好生成对应的符号，至于找实际定义并联系起来是链接器干的事情。 2. 选择调试模式即可。 /a.c中 int x； —————— //b.c中 #include…… extern int x; int main() {……;x=10;……} 编译器编译b. c这个翻译单元时 x=10；（按文件编译时，当前单元无x的定义啊） 编译器不就无法把10存到内存了 还是让连接器来做？

引用 7 楼 自信男孩的回复:找不到，提示警告甚至是错误；找到就会把变量指向内存的位置。 让          连接器找？

找不到，提示警告甚至是错误；找到就会把变量指向内存的位置。

找到之后，就拿来用呀。 就跟自己定义的一样。

引用 4 楼 m0_46300909 的回复:[quote=引用 3 楼 子衿兄的回复:]我这里简单的定义了一个全局变量，  我不懂汇编呀，反汇编的那些代码没看明白[/quote]   不用懂汇编，，你看到显示的符号，，对应就行。。 要理解深入的话，还是要能看懂一些基本的汇编代码

引用 3 楼 子衿兄的回复:我这里简单的定义了一个全局变量，  我不懂汇编呀，反汇编的那些代码没看明白


Question: PTA查验身份证

太感谢大佬了，真的是，好几天一直没有过，按照你说的我把输入和输出全部改成%s以后，就全部过了，我还是刚刚接触PTA上的这些题目，不胜感激啊

算法看不出来哪儿有问题 是所有的都不通过，还是个别的？  如果是所有的，你尝试修改三个地方看看 两个是关于k的循环， 有效范围 0到17， 不是<19 而是小于18； 甚至直接把那个%c输出，直接改成%s输出a[i]好了 最后return 0； 测试平台往往是用管道方式来把文件作为参数输入和输出，输出不可见字符0也许会有区别（k循环那里） return 返回值本来就是给调用它的系统使用的， 对于测试平台也一样  还有就是检查一下， 那个全部通过的单词， 是否和你的printf里面的完全一样，最好是复制粘贴过去

一个合法的身份证号码由17位地区、日期编号和顺序编号加1位校验码组成。校验码的计算规则如下： 首先对前17位数字加权求和，权重分配为：{7，9，10，5，8，4，2，1，6，3，7，9，10，5，8，4，2}；然后将计算的和对11取模得到值Z；最后按照以下关系对应Z值与校验码M的值： Z：0 1 2 3 4 5 6 7 8 9 10 M：1 0 X 9 8 7 6 5 4 3 2        现在给定一些身份证号码，请你验证校验码的有效性，并输出有问题的号码。 输入格式： 输入第一行给出正整数N（≤100）是输入的身份证号码的个数。随后N行，每行给出1个18位身份证号码。 输出格式： 按照输入的顺序每行输出1个有问题的身份证号码。这里并不检验前17位是否合理，只检查前17位是否全为数字且最后1位校验码计算准确。如果所有号码都正常，则输出All passed

原始题目要求是什么，要想通过除了算法没有问题外，你还要确保输出的格式和要求的完全一样 最好贴出题目的完整要求


Question: 如何用outtextxy函数在指定位置输出一个变量的值

引用 8 楼 apkipa1的回复:可能的话，请在出现问题时截图或录制动态图并发出来，这样更好解决问题。 好的谢谢！我刚来CDSN

引用 7 楼 與蘤舊縐的回复:可能就sprintf、_stprintf_s、_stprintf这几个函数的问题了，我自己在vs 2019上用过sprintf，没出问题，不过大半年前了 好的解决了，sprintf将score打印到数组中可能是会有溢出，改为sprintf_s就好啦，应该是这样解释的吧，刚刚只检查了数组，感谢！

可能的话，请在出现问题时截图或录制动态图并发出来，这样更好解决问题。

引用 4 楼 與蘤舊縐的回复:用法上没有问题，不过有可能是你的数字转化为字符串超出了字符数组的范围 扩大了数组范围也是一样的

以上只是猜测，感觉不会引起生成问题，以下是官方文档，可以参考一下   // 输出数值，先将数字格式化输出为字符串 (VC6) char s[5]; sprintf(s, "%d", 1024); outtextxy(10, 60, s); Copy // 输出数值 1024，先将数字格式化输出为字符串 (VC2008 / VC2010 / VC2012) TCHAR s[5]; _stprintf(s, _T("%d"), 1024);		// 高版本 VC 推荐使用 _stprintf_s 函数 outtextxy(10, 60, s);

用法上没有问题，不过有可能是你的数字转化为字符串超出了字符数组的范围

#include<stdio.h> #include<graphics.h> int score = 0;//总分 int rank = 0;//等级  //欢迎界面 void welcome(void) { 	//初始化画布 	initgraph(550,660); 	setbkcolor(BLACK); 	cleardevice(); 	//设置窗口标题 	HWND window = GetHWnd();//获取窗口 	SetWindowText(window, _T("俄罗斯方块  by炎黄c"));//设置窗口标题 	//设置文本字体样式 	settextstyle(40, 0, _T("微软雅黑"));/tfont无法使用，需要用setteststyle代替 	setcolor(WHITE); 	outtextxy(205, 200, _T("俄罗斯方块")); 	settextstyle(22, 0, _T("楷体")); 	setcolor(BLUE); 	outtextxy(175, 300, _T("编程，从俄罗斯方块开始"));  	Sleep(3000);//暂停3000毫秒，3秒钟   } //初始化游戏场景 void initGameScene(void) { 	char str[16]; 	 	//清除屏幕 	cleardevice(); 	rectangle(27,27,336,635); 	rectangle(29,29,334,633); 	rectangle(370,50,515,195); 	settextstyle(25, 0, _T("楷体")); 	setcolor(WHITE); 	outtextxy(405, 215, _T("下一个:")); 	settextstyle(25, 0, _T("楷体")); 	setcolor(RED); 	outtextxy(405, 280, _T("分数:")); 	settextstyle(25, 0, _T("楷体")); 	setcolor(RED); 	outtextxy(405, 375, _T("等级:")); 	sprintf(str, "%d", score); 	outtextxy(415, 310, str);   }  int main(void) { 	welcome(); 	initGameScene();   	system("pause"); 	closegraph(); 	return 0;  }

#include <wchar.h> int swprintf(wchar_t *buffer, const wchar_t *format, ...);  int main( void ) { wchar_t buf[100]; int len = swprintf( buf, L"%s", L"Hello world" ); printf( "wrote %d characters\n", len ); len = swprintf( buf, L"%s", L"Hello\xffff world" ); // swprintf fails because string contains WEOF (\xffff) printf( "wrote %d characters\n", len ); }

先sprintf格式化字符串，再用outtextxy输出，应当不会出问题，请贴代码


Question: 新手求大神帮忙解决一下问题，谢谢！！

如上可保证输入正确 算法自己改，对于特例输入1，结果是输出4显然是错的

整那么多重复的去掉清空缓冲区的办法做啥， 任何一样就够了  #include <stdio.h> #include <math.h> #include <stdlib.h>  int main()   {     int ret,day,i=1,sum=1;     printf("Input days:\n");     ret=scanf("%d",&day);     while((ret!=1) || ( day<=0))     {           fflush(stdin);           printf("Input days:\n"); 		  ret=scanf("%d",&day);     }     do  {        sum=(sum+1)*2;        i++;      }while(i<day);     printf("sum=%d\n",sum);     return 0;   }

好的，谢谢大神


C和C++完整教程:https://blog.csdn.net/it_xiangqiang/category_10581430.html C和C++算法完整教程:https://blog.csdn.net/it_xiangqiang/category_10768339.html

if (fp)     fclose(fp); 这样试试～

MSDN自己的例程都会报警告，求教楼主最后怎么解决的？

既然已经用errno_t检查过了，没问题是肯定的，不过编译器还是warning。亲测解决方式：if(fp&&!err); 解决了的话赞起来

想去掉警告很简单，下面再判断一次即可

fopen_s的第一个参数确实是二级指针，用二级指针修改一级指针的指向，没什么问题  这警告无非是想说fp可能指空了，既然你上面已经判断过err的情况，要么err不包括该情况，要么编译器检查不到位

fopen 函数里，第一个参数对对指针变量取地址好像不对吧，第二个参数加了双引号的话那文件名就叫“filename”了。


Question: 在用数组元素给变量多次赋值时，刚赋值结束，变量值就自动变化是为什么

开什么玩笑啊  x = Number[x-1][y-1].m ;   y = Number[x-1][y-1].n;     // 此时的x，已经被上一句赋值所替换了  发生变化有何奇怪？！


Question: C语言作用域

LZ看个简单的例子就明白了，局部变量编译后其实就变成了一个偏移地址，对变量的操作只是对变量这块内存地址的操作  int main() {     int *p1, *p2, *p3;     int a = 1;     p1 = &a;     {         int a = 2;         p2 = &a;     } //如果变量离开作用域块内存就被回收     {         int a = 3; //那么这里的内存地址应该和上面一样，但事实并非如此         p3 = &a;     }     printf("%p, %p, %p\n", p1, p2, p3); //所以每个变量的内存地址不一样，但可以看出地址是连续的，所以说明在编译时就决定了     printf("%d, %d, %d\n", *p1, *p2, *p3); //这里还说明了离开作用域块，变量的内存并没有被回收（因为方法栈没被回收），只不过不能通过作用域块里的变量标识符来访问该内存了，外层作用域块如果有相同的变量标识符则以外层的变量为有效标识，如果外层没有变量标识符则语法检测通不过编译失败。     return 0; }

要相信编译器，不会有问题 作用域本身就是为了 符号复用 (不同作用域的同一个符号表示不同意思) 特意设置的一个语法机制

作用域本身就是为了 符号复用 (不同作用域的同一个符号表示不同意思) 特意设置的一个语法机制 然后不存在什么本质的东西 为了符号复用这个目的设置的这个机制 编译器实现了这个机制 仅此而已

其实编译器会自动处理名称冲突的，给你举个实例吧，这是源代码：  这是编译器生成的代码：  可见编译器对重名的对象进行了适当修改。

不好意思，说错了，python的那个改名字的操作应该是设置私有属性的时候才使用的，不过python本身其实并不是很好地支持属性私有化，甚至可以直接拿变了的那个名字访问所谓的私有变量

讲不出啥，底层自有实现方法，而且C是编译型语言，底层实现可能更纯粹吧，像python的话，类属性和实例属性如果名称一致其实解释器是做了一点小手脚，大致就是在变量名前面加个下划线什么的，C不清楚，感觉他不需要这么拐弯抹角

int main() {    int I;    while (1) {        int I;        I = 0;   // 这就是内层的I，不是外层的I   } }  这没有什么原理啊。  编译器，把它当成完全不同的两个变量，对编译器来说，不同的变量名就是不同的内存地址而已 完全没技术含量

没什么本质，只是单纯地覆盖而已，或者可以说是 C 语言规定的特性。

大神 能讲讲本质性问题吗


Question: 程序算出来的数字精度不对，请问是我的程序写的有问题么，谢谢各位大神

可以认为是精度的问题，但是不完全是精度的问题 你把float换成doube也没用 关键是浮点数在计算机当中的保存方式的问题 浮点数不能完全的表示一个数， 1.3 很可能在电脑当中保存的就是1.29999999999999 long转换是截断的方式， 29.999999999 也认为是29  你可以先printf（“%10f”， amount[i]）；来看看1.3，2.3.等到底输出的是什么 之所以用.10f是因为printf是带有四舍五入功能的，只有超出了float的精度范围的输出才能体现出来，否则仅为后看不到  要想获得正确的结果，改一下 center[I] = (long)((m[I] - d[I] * 100 + 0.5); 类似这样的方式


Question: 读写空指针不会报错的情况

引用 11 楼 apkipa1的回复:顺便用 godbolt 跑了一下，同样能提示出错，我怀疑你配置的环境把程序错误给吃了。  唉，天知道，重配完事，明天再试，感谢帮助

各位，楼歪了(这app10个字真麻烦)

debug 和 release 不一样， 你弄个两个版本去测试去

引用 7 楼 user-3的回复:[quote=引用 4 楼 與蘤舊縐 的回复:] 是的，所以说只是在这个编译器下的侥幸事件，无需纠结，回归正题即可  [quote=引用 3 楼 apkipa1 的回复:] 我试了，在执行到第三个 printf 时程序崩溃了，不过我的系统有点毛病，没法弹出崩溃提示。不过用一些手段能看到抛出的异常： [/quote]  C语言的指针十分强大，但是要求使用者要谨慎使用。你们这个结果显示的是EXCEPTION_ACCESS_VIOLATION,字面意思就是试图访问不可访问的内存。可以使用C++运行这些代码，然后捕捉这个异常并做一下处理试试。[/quote] 崩溃这事上我还是留了一手，至少看到了program exit with code 0，不过调试真没试，看你这么一说突然想起来以前用mysy2配的mingw64工具链应当会对段错误做出反应的，而且报错还是赤裸裸的“段错误”三个字，看来得去检查一下配置了，感谢回复

引用 4 楼 與蘤舊縐 的回复:是的，所以说只是在这个编译器下的侥幸事件，无需纠结，回归正题即可  [quote=引用 3 楼 apkipa1 的回复:] 我试了，在执行到第三个 printf 时程序崩溃了，不过我的系统有点毛病，没法弹出崩溃提示。不过用一些手段能看到抛出的异常： [/quote]  C语言的指针十分强大，但是要求使用者要谨慎使用。你们这个结果显示的是EXCEPTION_ACCESS_VIOLATION,字面意思就是试图访问不可访问的内存。可以使用C++运行这些代码，然后捕捉这个异常并做一下处理试试。

这是在ubuntu18.04 Qt上调试显示的结果

在调用第三个pop时会有一个信号发出。在POSIX兼容的平台上，SIGSEGV是当一个进程执行了一个无效的内存引用，或发生段错误时发送给它的信号。 如果不设置捕捉该信号的情况下程序会自动终止。你可以在第三个pop后面打印一些字符串，你会发现并不会执行。Windows就不太清楚了，原理应该差不多。这种错只从执行结果上很难判断的，只要执行调试，出现信号时一般的调试器都还是能显示的。

是的，所以说只是在这个编译器下的侥幸事件，无需纠结，回归正题即可  引用 3 楼 apkipa1 的回复:我试了，在执行到第三个 printf 时程序崩溃了，不过我的系统有点毛病，没法弹出崩溃提示。不过用一些手段能看到抛出的异常：

引用 1 楼 apkipa1 的回复:神奇，有代码可以复现吗？  重写了个简单的，不同编译器下结果不同，当前编译器效果如下图（最后一句没有输出，没有报错）  这个情况估计是几率性事件，重点在于问题，网上查了一通找到些NULL指针的用法，关于该问题的信息不多，我还是觉得NULL指针不可读写，不过闲来无事碰碰运气，看看能不能搜集到一点特殊情况   typedef int elemType;  typedef struct stack {     elemType item;     struct stack *next; } stack;  stack *predecessor_stack(stack *s) {     if (NULL == s->next) {         return NULL;     } else if (NULL == s->next->next) {         return s;     } else {         return predecessor_stack(s->next);     } }  stack *pop(stack *s) {     stack *temp = s->next;     stack *pre = predecessor_stack(s);     if (NULL == pre) {         return NULL;     } else {         while (NULL != temp->next) {             temp = temp->next;         }         pre->next = NULL;         return temp;     } }  void push(stack *s, elemType x) {     stack *new = (stack *) malloc(sizeof(struct stack));     new->next = NULL;     new->item = x;     while (NULL != s->next) {         s = s->next;     }     s->next = new; }

神奇，有代码可以复现吗？


Question: 关于外部函数调用的问题

main（）函数里面又定义了局部变量  char option1,option2,option3,option4; 键盘输入都保存到这里了，根本就没有放到全局变量——extern所指定的变量里面去 把main里面的这四个局部变量删掉


Question: 关于函数返回值的一点小问题

引用 3 楼 燕子深藏花海 的回复:[quote=引用 1 楼 與蘤舊縐 的回复:] a=a++，那么问题来了，a=a++原本的值，也就是之前的a，那么++操作等于无效，还是等于a++操作之后的a，=赋值不正常  虽然没有明令禁止，但一般不会这么干的 后缀自增的话不是理解成完成其他运算后，再执行自增吗，即a=1 a=a++ 先执行赋值运算 再执行a自增 所以 之后a=2？ 可以这样看出程序的执行顺序？ 后缀自增是在其他运算（return）结束后才执行的？   我所要问的就是这里而已。[/quote]  首先，++不是这么判断顺序的，其次我为什么说先是a++，因为你这里自增操作在函数里完成，赋值运算右边先进行，当然是先执行函数，必然先++，后面是函数返回之后的事情了

return (*a)++; 在 return 执行完毕后，对 *a 的自增生效，同时 *a 的原始值被返回到上层。然后 a = f(&a)，在执行到分号后，对 a 的赋值生效，结果是 a 的值没变。

引用 5 楼 燕子深藏花海 的回复:为什么编译器会认为 a=a++ 后 a会自加 ， 而a=f（&a） 却不自加 ，但 b=f（&a） 自加？ 这才是我的问题  a = f(&a);  // a在f函数里面自增了，但是函数里面return的是自增之前的a， 这个值被赋值给了a， 所以覆盖了，导致没有加 b = f(&a); 就没有问题了， 返回的值给了b，a自增自己的，不影响   另外 a = a++； 这种代码属于未定义的行为 不要写，不同编译器结果会不同的

a=a++，先把=右边的表达式计算出来的结果（就是a）保存在一个临时变量，然后a自增1，然后再把临时变量赋给=左边的a，也就是重新覆盖了a自增的结果，所以最终a还是a

引用 1 楼 與蘤舊縐 的回复:a=a++，那么问题来了，a=a++原本的值，也就是之前的a，那么++操作等于无效，还是等于a++操作之后的a，=赋值不正常  虽然没有明令禁止，但一般不会这么干的 后缀自增的话不是理解成完成其他运算后，再执行自增吗，即a=1 a=a++ 先执行赋值运算 再执行a自增 所以 之后a=2？ 可以这样看出程序的执行顺序？ 后缀自增是在其他运算（return）结束后才执行的？   我所要问的就是这里而已。

你这个与与上述有所不同，很明显你的程序首先执行了a++，a变成了2，而后，return 1，a=1，a又变回1


Question: 关于C语言结构体部分，字体加粗部分不明白为什么，求助！

printf("s1.name = %s, s1.num = %d, s1.isMale = %d.\n",   s1.name, s1.num, s1.isMale);  %s要求是字符串，也就是数组， 所以name必须是char数组， 否则就错了呗

去掉之后name就变成char类型的了，对应的应当是%c，%s对应的是字符数组


Question: 这种溢出情况怎么解决啊，求各位大神看哈

引用 1 楼 寻开心的回复:你这个fact函数当中a没有赋予初值， 所以a>0.0001的判断没准儿是什么， 也许根本就没有执行  另外，你在for循环里面，也加上一句printf函数输出b和a，看看每次迭代的数据变化 谢谢谢谢

之所以出错，就是因为a没有初值， a就是你看到的那个所谓的溢出的那个数值， 他是负数， 不大于0.0001， 所以for循环根本没有执行，直接输出那个a了 应该初始a为1.0这样， 让它能进入for循环，之后a就有值了


Question: 照书敲出来的代码 为什么有bug啊 不知道怎么解决

引用 1 楼 user-1 的回复：建议你把这本书扔掉 void fun(int n)改为int fun(int n) void 表示无返回值，return s  s是一个int型数据表示返回的是一个int数据 建议你看下编译错误，提示写的很清楚了，实在不会把提示复制到百度搜索下就会明白了照着样子试了一下您说的改成int，运行了！ 感谢🙏 我上网查了 没查到


Question: 所有类成员都可以被外部访问为什么是错的

A private成员可以被外部访问很显然是对的，因为这么说不是绝对的，说的是“可以”。而B说的是所有类成员，对于抽象类，抽象类也属于类的范畴，纯虚函数也是抽象类的成员，但抽象类不能实例化，所以就没有可以被外部访问一说了。 以上全是对着这个答案死磕的，如有错误，望大家指正。

这题答案错了吧

引用 2 楼 初学小菜 的回复:保护的不能够被访问 友元也不行吗

保护的不能够被访问

考虑下继承，比如以私有方式继承了一个基类的私有成员，与此同时，基类没有提供任何访问该成员的接口，感觉对这个派生类而言，这个基类的私有成员就完全不可访问了，友元关系好像不能递归或继承的，你可以编码确认下。个人感觉这种题没啥意思


Question: 这两个程序有什么不一样呢 不懂求指导

o 不对 第二个的fun的判断就错了 按照第二个fun的逻辑，只要有一个收尾匹配就返回了，实际上应该全部首尾匹配才可以

fun函数的return情况，这两个例子刚好相反， 主程序里面对返回结果的判断也要相反才对。 后一个程序的 if ( func(s) ) printf(yes)就是错的   应该是 if( !func(s)) printf(yes)


Question: int a =5 ;  a这个变量与存储5的那一块内存的地址是怎么对应的？

引用 4 楼 o荞麦o 的回复:"int a" => 分配一块内块 "= 5" => 内存赋值为常量5    引用这位老兄的回答，再加上我的理解：  int a = 5； 1.我们假设int a 分配到的内存地址为0xaa。 2.int a存储空间最大为4个字节，也就是2^32，也就是可以存储的最大值为2^32. 3. = 5, 就是把这块地址0xaa，存储值为5.  综上所述，int a = 5.  a是这块地址的名称，程序员规定的。 0xaa是这块地址的地址，是计算机内存自动分配的。 5 是名字为a，地址为0xaa的内存存储的值。

这要看变量定义在哪儿了， 全局变量，和局部变量不一样 全局变量，是把5存到数据段里面了， 不需要额外的初始化， 程序加载的时候自动就带进俩了， 然后把变量和这个地址对应上 局部变量不一样，函数调用的时候， 要把栈里面为他分配内存，并且初始化为5，然后把指针和他对上  这个要研究一下编译原理去

代码编译后不存在a（也就是机器码里不存在a），a被编译为一个内存相对地址--相对于栈帧首地址的偏移地址 5就是写入a这块内存地址的信息（以二进制的形式保存在a这块内存区域里）

这个时候，你应该学一学汇编

"int a" => 分配一块内块 "= 5" => 内存赋值为常量5

compiler

由编译器来处理。理论来说你不应该去关心 a 到底对应着哪块内存，这种底层的活都是编译器干的，它甚至可以不给 a 分配任何内存。

编译成二进制代码后就没有了a这个变量名，所谓的a是源代码的概念。编译后只是指的一个内存的区域，那个区域里存放的是整形5.

看你int i定义在哪里，如果是全局变量，编译器分配，如果是局部变量，是运行的时候自动放在堆栈上的（当然还是编译器生成了相应的代码）。 所以你反汇编，可以看到类似 mov ptr[esp + 0x0000xxxx] 这样的指令，这个esp就是堆栈指针

定义一个Int型变量，这个时候会放在文本段中，要看是以什么形式定义，可能放的位置不一样，  运行时，反汇编可以看到，要用这个变量实际上是指的一个地址，从这个地址中取数据  去查看这个地址的内容，可以看到内容


Question: C语言二分法查找

引用 2 楼 寻开心 的回复：所以，如果要查找的数， 比*pa还大， 或者比*pb还小， 自然是不在这个范围内的啦懂了 非常感谢

那行的意思是如果要查找的数，不在这个数组的范围内，返回-1表示不存在  上一个sort函数里面说了，  这个数组是大的数在前面，小的数在后面 100 90  73  5 1   类似这样的排列关系


Question: 大神求解！！两次第二次输出为什么都是2？

希望对你有帮助：https://blog.csdn.net/it_xiangqiang/category_10581430.html 希望对你有帮助：https://blog.csdn.net/it_xiangqiang/category_10768339.html

两次都是i=1， 然后是i++，或者++i；  无论哪种，最后i都是自增一， 够二的条件了。 而～取反操作，只是用i的数值作为条件来的出新的数值，对i自身并无修改， 不影响i是几 最终就是二

~i++:  这里的++是postfix ++，所以优先级比~高，所以先做postfix ++，然后再取反。这然后的取反操作是后执行的，所以其结果成为整个表达式的值，被打印输出。postfix ++是先evaluate然后再increment。evaluate的结果送去~，在这之后i原先的值++。那么，i原先的值是1，是这个1被取反，结果是-2，作为整个表达式的值，被打印出来。同时i原先的值increment，变成2。因为我前面说的，表达式的值是~的结果，不是postfix ++的结果，所以是-2被送去打印，而不是2。

不是2，应该是什么？

i++与++i不同，i++取反是对1取反之后i为2，++i先i自增为2后取反

~++i: ~和prefix ++具有相同的优先级，这一层优先级是right associative，所以先做++i，然后再~。prefix ++的值是increment之后的结果，也就是2。然后对这个2进行~，结果就是-3。-3作为整个~++i表达式的值，送去打印。


Question: 求问各位博士，各位前辈，各位伙伴，我是调用函数求素数，能不能帮忙看一下我的问题到底出在哪里？怎么调用函数？这调用函数没有起到作用，这到底是为什么呢？

第一张图，里面没有花括号， 那for循环是对哪几行语句有效呢？  你自己加一个花括号， 那表示的是所有的花括号里面的语句都是要循环的， 这和第一个图的意思不同  好好看看书

自己再仔细看看第一张图 哪些代码在for的花括号范围内， 那些是在花括号范围外的

不好意思(T ^ T)，各位大神们，我新手入坑，图一发错了，刚才有幸大神指教，我prime里面多加多余的大括号，是for循环学习不足，让各位大神见笑了。在这，我谢谢您们了。


Question: 怎么获取鼠标在一个窗口中的坐标

引用 3 楼 寻开心 的回复:那是windows编程的api， 你这个用inigrph建立的没有这个功能吧  窗口也有自己的坐标范围， 也是屏幕坐标 你要取得窗口的屏幕坐标， 然后和鼠标的屏幕坐标就都是在统一的坐标系下的了； （只有在统一的坐标系下坐标才可以运算。）  鼠标的屏幕坐标 - 窗口左上角的屏幕坐标， 就是鼠标在窗口内的坐标了  还是那句话， 这取决于你的绘图工具能提供那些api来获取这些坐标 比如，你的窗口是怎么创建的， 创建的时候，就会指定窗口在屏幕上的坐标， 这个坐标就拿来可用  虽然还是不太明白其中的原理     但还是感谢大佬的解答

引用 1 楼 寻开心 的回复:先GetCursorPos,得到在屏幕中的坐标，然后再用ScreenToClient转换一下就好  或者获得屏幕坐标，以及窗口的屏幕坐标， 加加减减就出来了  看你的开发环境，和什么api可用了  感谢大佬        再求教一下这个ScreenToClient  这个函数的第一个参数需要一个窗口句柄，如果是initgraph建立的图形窗口该怎么获取它的句柄呢


Question: 多行文本框，读取不到换行符

有没有简单一点的代码啊，这个是他们的漏洞吗？明明它自己给我换的行，为什么却读不到他的换行符呢？

MSDN的官方示例: 先为Textbox绑定一个CEdit类的变量  int i, nLineCount = m_myEdit.GetLineCount(); CString strText, strLine; // Dump every line of text of the edit control. for (i=0; i < nLineCount; i++){  // length of line i:       int len = m_myEdit.LineLength(m_myEdit.LineIndex(i));       m_myEdit.GetLine(i, strText.GetBuffer(len), len);       strText.ReleaseBuffer(len);       strLine.Format(_T("line %d: '%s'\n"), i, strText);       AFXDUMP(strLine); }


Question: 大佬们帮忙看一下为什么这个结果是这样的

引用 1 楼 寻开心的回复:输入函数scanf并不能指定精度 对于你的输入数据，scanf里面要这样指定格式，"%d-%d",  这样输入1-84215021才会把1 和 84215021分别读入不同的变量里面去 懂了谢谢，辛苦了！😜


Question: 结构体的二级指针取值之后无法被识别为结构体或者联合，因而无法访问结构体字段

引用 6 楼 寻开心 的回复:因为优先级的原因。 *ep->item 和。**p.item 会被认为是 *(ep->item) 和 **(p.item)   吓了我一跳， 特地跑去写了段代码去测试。  坑货   莫慌莫慌，删减版指针写多了，还是我C原汁原味

引用 4 楼 寻开心 的回复:(*ep)->item  (**ep).item 怎么就不可以了呢？  哎C都还回去了，刚想起来了，就等你接分了

(*ep)->item  (**ep).item 怎么就不可以了呢？

(*ep)->item  (*e).item  我傻了

没人那我只好自圆其说了

如果是((example*)*ep)->item这也感觉不咋的  强行取值最为致命


Question: 萌新求教简单问题

希望对你有帮助：https://blog.csdn.net/it_xiangqiang/category_10581430.html 希望对你有帮助：https://blog.csdn.net/it_xiangqiang/category_10768339.html

15行   while ( getchars() !='\n');  作用就是从键盘缓冲区当中提取字符，直到把遇到的第一个回车键也提取完  应对情况前面那句， scanf获取整数输入的 如果要求输入整数，用户输入了一个字母x然后回车， 那么scanf那句会返回0， ret就是0 如果用户输入正确的一个整数， 然后回车，那么ret 就是1  对于ret是0的情况， 用户输入的x字符，也有可能后面还有一堆乱七八糟的别的内容， 这些东西都要清理做废掉 让用户重新输入正确的数字 15行的作用就是干这个，  把键盘缓冲区当中已经输入的这些用户不想要的统统清理光，让用户重新输入


Question: (codeblocks编程)编写的程序运行到一个函数后，编译器分配声明的第一个指针时显示越界

哦， 不对。 说错了。 你这个并不是局部数组太大的原因 而是 temp是野指针， 你没有给他初始化， 它的数值是多少都是可能的，毫无意义

局部变量分配在栈当中，如果MULSGLEN太大，超出了栈内存大小，就很可能造成这种后果 你的MULSGLEN是多少呢


Question: 这段程序哪错了为什么结果不对？

引用 1 楼 寻开心的回复:输入age的时候， scanf代码是错的， 传递的是age的值， 应该是age的地址，少了个取地址的&符号 scanf("%d",  p->age);   这是错的， 第二图，倒数第二行那里 好了，谢谢谢谢(*°∀°)=3