Question: 在线等一道C语言问题在线等求助，指针地址如何交换

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

你的定义方式是 int a=99; a 其实本质上可以认为是一块地址，地址的内容是99，你只能改变内容，无法改变自己的地址。打个比方就是你没办法举起你自己。 你应该将a定义成指针 int data=99; int* a=&data;

你想在函数中改变某个变量，就需要传入他的地址。 因为你想要改变指针，所以就要传入指针的地址。也就是 *aa的地址**aa

根源上，楼主还是没有理解， 传参数传递进入函数的到底是什么  int swap(int *a, int *b);  这是函数的定义，它只说明了， 要传递的两个参数的类型都是int *  主函数main当中，对函数的调用语句： swap(&a,  &b); 这里的两个参数部分， 是表达式，  只要这个表达式，返回的类型是函数定义时刻所有要求的类型就符合语法规范 所以， 可以swap（&a +1， &b-1 ） 这种调用都是合法的  这里，看不到的是，编译器在把代码转换成机器码去实际执行时刻的部分 实际上， 编译器会在对这个函数做具体调用之前，完成几个工作 1 完成表达式的计算， 得到真正的返回值；        楼主代码当中，&a和&b返回的是a和b变量的地址 2 把返回值放到系统栈当中，做为被调用函数的局部变量供函数来使用 3 条转到函数的执行入口  进入函数的入口后， 开始执行函数体内的代码部分 这个时候， 函数定义部分的参数， 和系统栈当中的放入的表达式返回值对应起来 楼主的代码当中a和b，在这个时候才和主函数当中a和b变量的地址对应上了 函数定义的参数名字，叫做ab也好，叫做cd也罢，都是一个符号， 他们只是和栈里面的表达式返回值对应上 和原始的调用参数时刻的表达式里面的变量名字之间没有任何关系 也就是说，函数里面的a和b， 与主函数的a和b是风牛马不相及的  swap函数当中的a和b，是int *类型； 主函数当中的a和b是int类型； 他们只是名字相同，但是完全不是一个东西 我们完全可以把swap函数定义的参数改名为c和d， 对整个函数的执行没有任何影响 swap函数里面的a变量，保存的是主函数当中a变量的地址， 他们的关系仅此而已 既然是地址，要赋值就是要 *a = 。。。。 这种操作了  函数内部所实现的改变， 只有两种方式能够带回到主函数 1 利用return命令， 把要返回到内容（语法上也是一个表达式， return命令会把表达式计算的结果计算出来），放到系统堆栈和系统寄存器里面。  外部调用函数 ret = swap（。。。。） 语句，通过 = 这个赋值语句从寄存器或者堆栈当中获得返回值  2 函数体内部改变了全局变量，或者是通过传递到指针，改变了指针所指向的内容的方式，间接的把计算结果带回了主函数  无论哪种方式， 都没有涉及到对传递进来的参数值的使用， 所以对参数自身的改变是带不出函数体的 传递进来的参数值，在函数return的那一刻，堆栈弹出，所对应的内存失效了， 函数体内对他的改变因此而全部消失了   仔细看看书， 关于函数参数，任何一本书都会有特别的说明的， 尤其是这个swap例子，几乎是每本c的书，都拿它来做为例子讲参数的问题

引用 1 楼 henhaowoxini 的回复:  其中在调用swap函数时  swap(&a, &b);  将在main 中将局部变量 a,b 的内存地址值赋给寄存器 或 main栈内存中，然后跳转执行 swap 函数  在swap函数中  void swap(int *aa, int *bb) {     int *temp = aa;     aa = bb;     bb = aa; }  将从传参寄存器或父（main）栈中取实参&a, &b于局部变量(形参)aa, bb中。swap后续语句都是在操作swap中的局部变量，所以不会影响父栈中的变量的值。  若要交互父栈中两个变量的值，可以实现如下:  #include <stdio.h> #include <stdint.h>  static void _swap(int **aa, int **bb) {     uintptr_t t = (uintptr_t)*aa;      *aa = *bb;     *bb = (void *)t;      return ; }  int main(void) {     int a, b;     int *aa = &a;     int *bb = &b;      fprintf(stderr, "before _swap aa=%p, bb=%p\n", aa, bb);      _swap(&aa, &bb);      fprintf(stderr, " after _swap aa=%p, bb=%p\n", aa, bb);      return 0; }

现在能看懂了吗，你只是改变了a b 对应的值， a b 的地址是不变的

引用 7 楼 henhaowoxini 的回复:[quote=引用 2 楼 與蘤舊縐 的回复:] 函数传入的是a和b的地址 aa指向a，bb指向b  temp指向了a aa指向了b bb指向了temp所指的位置即原a  你只是把指针aa和bb的指向互换了而已，而这两个指针在函数结束后不再有用，要换内容必须用*取值交换 四楼那个图为什么就实现互换了[/quote]  我不是说了吗，用*取值交换，这不就是取值交换了吗 temp接收了指针a指向的值即a b指向的值赋值给a指向的值 temp的值，即原来的a，赋值给b指向的值 这不就交换了原来的ab吗

引用 2 楼 與蘤舊縐 的回复:函数传入的是a和b的地址 aa指向a，bb指向b  temp指向了a aa指向了b bb指向了temp所指的位置即原a  你只是把指针aa和bb的指向互换了而已，而这两个指针在函数结束后不再有用，要换内容必须用*取值交换 四楼那个图为什么就实现互换了

老哥你交换的值，又不是对应的地址

引用 3 楼 比卡丘不皮 的回复:你没有理解指针的含义，还有有关左值右值的感念。首先当你 a b 定义下来的时候，他们的地址是不变的，当你&a  &b  分别去地址的是时候是临时变量指针，aa->a  bb ->b  当你只是让 aa  bb 互相换了值 aa->b   bb-> a,  aa  bb是两个临时变量  当你&a &b 的时候，与 aa bb 没有任何的关联。  麻烦看下楼上哪个，为什么就互换了


Question: 在很大的二进制文件中怎么查有没有重复出现的128bit

16个bytes相等是特殊情况， 如果要遍历就不要这种特例就好了 如果是遍历连续130个bits，会是认为3个不同的128bits的匹配 要不要遍历算法控制上的简单问题   15个连续的bytes，也就是120bits存在的可能性是比16个bytes（128bits）的可能性高 但是作为查找算法， 先找到15个byte的效率绝对比直接找128bits高得多 bits比较就要从byte里面摘出来，然后逐个位去比较。 而byte，cpu支持直接比较二者是否相同 之所以放大到long long int，64bits，因为同样的cpu可以完成一次64位的比较  至于结果缓存不缓存，那是基础问题， 这个理解不了，这个题目对你就太难了

引用 4 楼 寻开心 的回复:这个肯定是可以加速的 吓人的是要按照bits来， 听起来要移位，可是真的需要吗？！  128bits是16个Byte， 无论按照bits是怎么排列的，不管怎样跨Byte的边界，最终一定有15个Bytes是连续的 所以在大文件当中，先找到所有的15个连续Byte的可能， 如果有16个直接结束就ok了 如果没有， 15个的基础上再想前或者后相邻的2个byte上找能不能在凑出8个bits的相同位来，这个很比较狠容易解决，最多14次比较而已。  要求是遍历所有的。。不能因为有了就停下来，而且15个连续的bytes的可能性太多了吧。。是要存放起来吗，，，不太理解呀

这样把按照bits移位，转化成按照bytes移位来比较了。  同样的道理， 不按照bytes比较15个，而是进一步把数据整合， 整合到long long int类型， 也就是64位的int 这样每次移位64位，就更快了  64位也是最大的整合了。 long doulbe是128位的，可以把数据认为是long double数组并能进行比较，问题是移位bits就绕不过去了

使用内存映射文件，CreateFileMapping

按照1bit，不是按照整字节操作的

你这个对齐是按8位呢，还是按1位呢？


Question: 求助

引用 1 楼 寻开心 的回复：你到你要闹哪样啊？ double get_input(void) {     double a;     while(scanf("%lf",&a)!=1)  // 输入的是double内容，那么while循环体不执行； 如果不是double，键盘缓冲区的内容并没有变化，还是原来的内容，所以一直在这儿死循环        {         printf("\nEnter a number\n");     }     return a; }   陷入循环...  但是添加  double get_input(void) {     double a;     char ch;     while(scanf("%lf",&a)!=1)    {   // 输入的不是一个double类型数据， 会进入这个while循环体          while ((ch=getchar())!='\n') // 把缓冲区的字符一个一个的提取出来， 包括最后的回车符， 也就是放弃了这一整行的数据了             putchar(ch);         printf("\nEnter a number\n");     }     return a; } 后面的这个函数，因为可以把键盘缓冲区清空，让用户重新输入数据，所以可以继续进行下去 前面的那个函数，因为没有清理缓冲区， 所以读取double的条件始终无法达到  如果只是这个目的。 循环体里面用一个fflush（stdin）就好了或者gets函数也可以解决。谢谢🙏


Question: 求解

你是小的除大的，会得0余小的，所以后面的不等于0是成立的，不会退出循环

（20%20！=0 ）  || （ 5%20！=0） 显然||后面的不是0啊， 5%20是5， 所以没有退出循环


Question: C语言指针

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

典型的代码测试如下  printf("%p %p", b, b+1); //  输出这两个指针， 看看他们之间的差是多少  如果是int类型就是sizeof（int）， 如果是int【3】，差距就是3*sizeof（int） 从而可以证明，b是什么类型的指针了

引用 6 楼 寻开心的回复:p和b的类型不一样 p类型是int* b烈性是int[3]*  二维数组，和一维数组不同 int*q， c[3];  q = 3;  这个没有毛病，  q和c都可以认为是int*  二维数组不是这样，b【2】【3】 是两个 int【3】数组相邻摆放，  b的类型就是 int【3】这个类型，并不是int类型 好的，了解了，谢谢你

引用 4 楼 林涅槃的回复:[quote=引用 3 楼 寻开心的回复:]p的指针可以指向b，p=&b【0】【0】 这就是正确的指向方法  你的解释不通！ 原因是，数据都在内容同一个地址放着， 如何解释要靠对应它的指针的类型 比如 int a；  放的是一个整数， 你要用一个float类型指针指向它，行不行呢？  float *f = &a; 行， 但是，上面这样写是错的，原因就是 类型不匹配， 正确写法是：  f = （float*） &a；  p = （int *) b; 这是可以的， 强制转换  强制类型转换， 顾名思义， 强制性的一个类型转换成另外的类型， 也许他们根本就不匹配 那么为什么a可行，b不可行呢？[/quote] a，b的类型都是int吧

引用 3 楼 寻开心的回复:p的指针可以指向b，p=&b【0】【0】 这就是正确的指向方法  你的解释不通！ 原因是，数据都在内容同一个地址放着， 如何解释要靠对应它的指针的类型 比如 int a；  放的是一个整数， 你要用一个float类型指针指向它，行不行呢？  float *f = &a; 行， 但是，上面这样写是错的，原因就是 类型不匹配， 正确写法是：  f = （float*） &a；  p = （int *) b; 这是可以的， 强制转换  强制类型转换， 顾名思义， 强制性的一个类型转换成另外的类型， 也许他们根本就不匹配 那么为什么a可行，b不可行呢？

引用 1 楼 寻开心的回复:因为类型不匹配 p= &b[0][0]  这样是可以的  int (*p2)[3] = b; //这才可以，   b是一个指向int[3]这种类型的指针， 它和int*不一样。 可第一行地址和第二行地址是连续的，从地址上来看，第一行地址6000，第二行6012，地址上是看跟一维数组是没有区别的吧，也可以看成是一维数组a[6]吧，此时a和b如果地首址相同，那么a[6]的大小和地址是和b[2][3]一致的，那么为什么p指针不能指向b

好的，谢谢你!😊😊😊😊😊😊😊


Question: pta问题求救

引用 1 楼 寻开心的回复:if(len/N==0) { lie = len/N; } else { lie = len/N + 1; }  应该是 if  ( 0 == len%N )  而不应该是  len/N  只有当len<N的时候，这个除法才是0 擦→_→ 原来是这里不对，想写整除来着。写顺手，就写成除法了。改完就对了。谢谢哥

lie = (len + N - 1 ) / N;  // 这样写一行就搞定了


Question: 大神救救我呀！

获取字符串s长度，作为数组dp的长度。

引用 2 楼 qq_1457346882的回复:dp[i] = dp[i-1] + dp[i-dp[i-1]-2] + 2 这是干嘛用的？ 没睡醒，给个思路吧。你可以定义一个数组记录他的有多少个，看题目来说，()才算，那就是遍历，判断前一个是（且后一个是）或者前一个是）且后一个是（j++，其余的把j置零，同时判断j/2是不是大于0，是就把j/2写到记录数组中，最后循环判断记录的最大数，输出有最大数*2个，再输出最大数个() 看四楼凑字数哈哈哈哈哈

引用 2 楼 qq_1457346882 的回复:dp[i] = dp[i-1] + dp[i-dp[i-1]-2] + 2 这是干嘛用的？ 没睡醒，给个思路吧。你可以定义一个数组记录他的有多少个，看题目来说，()才算，那就是遍历，判断前一个是（且后一个是）或者前一个是）且后一个是（j++，其余的把j置零，同时判断j/2是不是大于0，是就把j/2写到记录数组中，最后循环判断记录的最大数，输出有最大数*2个，再输出最大数个()

按题目要求  strstr 用好像比较简单哈 int finds(const char *s, const char *key) {   int iCnt = 0;   while(s && key && (s=strstr(s, key))!=NULL)   {     s = s + strlen(key);     iCnt += strlen(key);   }   return iCnt; }  void Test() {   VERIFY(finds("(()", "()") == 2);   VERIFY(finds(")()())", "()") == 4);  }

错了啊！

几行代码的事儿 int longestValidParentheses(char * str) {     char *p = str;     int maxLen=0, curLen = 0;     while ( *p != '\0' ) {         if ( *p == '('  && *(p+1)==')' ) {             curLen +=2;    p += 2;         } else {             if ( curLen > maxLen ) maxLen = curLen;             curLen = 0;    p++;         }     }     return maxLen; }  如果答案满意就结贴给分儿， 老问问问题不给分儿， 下次就不搭理你了


Question: c语言小新手的求助

c-free也可以

我去年用的vc精简版32&64bit，初学阶段完全够用，要的话传送门->https://pan.baidu.com/s/1ClKUb6tjk4ab1RE7tBCssg 提取码:5bpz

我用的也是笔记本64位 vc6.0没问题呀 具体怎么无法执行 报什么错

64位兼容32位的，无法执行肯定不是这个原因 visual c++实在太老了，你能找到这软件看来你自学用的教材也有点老了 visual studio，现在的笔记本大多都可以承受得起vs，你要觉得太占地方那就算了 dev C++，也比较老了，不过对初学者比较友好 CLion，挺智能的，可以用学生邮箱申请免费使用，当然还有那啥啥 visual studio code，省省吧，太恶心人了

1 下载dev c++ 腾讯电脑管家 - 软件管家 - 搜索 dev， 找到48M的那个  2 下载 visual studio community 2019版本就好


Question: feof读写最后会再读入一次FF怎么解决

fread（buffer， 1， 1024， fp）； 少写了个参数

feof（fp） 必须是到尾巴了还读了一下，才发生设置eof的标记 可以如下方式 while （1） {      c = fgetc(fp);      if ( c == eof ) break;      else    buf[selectBitSize]=c;  } 但是一个一个的读效率太低了 fread一次读一个数组，这个函数了解下 比如，定义一个char buffer[1024] int nReadOK = fread(bufer, 1024, fp); 根据nReadOK来判断读取成功了多少，如果nReadOK是1024表示文件还有可能有剩余，继续读 如果不足1024表示到尾巴了，结束了


Question: 为什么排序的不对？

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

#include<stdio.h>  void choose(int num[],int length) {     int i, j, min, tmp;      for (i = 0; i < length; i++) {         min = i;          for (j = i+1; j < length; j++)             if (num[min] > num[j])                 min = j;         if (min != i) {             tmp = num[min];             num[min] = num[i];             num[i] = tmp;         }     } #if 0     int i,j,temp;     for(i=0;i<=length-1;i++)     {         for(j=length-1;j>=length-1-i;j--)         {             if(num[i]>num[j])             {/*                 temp=num[i];                 temp=num[j];                 num[j]=num[i];                 */                 temp = num[i];                 num[i] = num[j];                 num[j] = temp;             }         }     } #endif } int main() {     int length=8;     int num[8]={5,6,8,4,1,2,7,3};     printf("排序前:\n");     for(int i=0;i<length;i++)     {         printf("%d,",num[i]);     }     choose(num,length);     printf("排序后:\n");     for(int i=0;i<length;i++)     {         printf("%d,",num[i]);     }     printf("\n");     return 0; } 供参考～  选择排序

别的暂且不看，你的交换  temp=num[i];     temp=num[j];     num[j]=num[i]; temp的作用是中间的介质，你两次对他进行改变然后后面有没有用，而是直接赋值一个数组值给另一个，肯定都是最大的啊， 交换交换，你根本就没有换啊  temp=num[i];  num[i]=num[j];  num[j]=temp; 这样 才是交换

首先你要明白你要用什么方法，看看初始条件和判断条件是否正确，最重要的看看if交换数据对了吗？

对啊

if(num[i]>num[j])    {     temp=num[i];     temp=num[j];     num[j]=num[i];     }  这是交换数据吗？


Question: 结果和预想的不一样

return 在exit前面

为什么是1 2你调用print打引2以后return代表函数调用结束，没有其他操作了，自然是返回主函数继续执行啊

谢谢  明白了


Question: q to quit是什么意思？？

说错了， sorry！ 程序实现了 这里 while (scanf("%d",&num)==1) 如果用户输入的是数字，然后回车。 scanf返回就是1 否则scanf返回是0， 也就退出了  你不输入数字，随便输入一个或者几个字符回车，就能退出  scanf返回值，是表示成功的获取了指定格式的数据的个数， 要求整数，你输入的了字符什么的， 返回就是0

不输入数字，输入字符q，程序退出，否则程序一直循环下去  只是程序代码并没有实现这个功能， 所以这个提示没有意义了


Question: 急求c语言大神

引用 11 楼 @__Chao - L的回复:[quote=引用 10 楼 @__Chao - L的回复:][quote=引用 7 楼 ?Victor.??的回复:][quote=引用 6 楼 寻开心的回复:]你自己写吧， 不知道啥是你能看得懂的  把有问题的代码贴出来， 不要贴图哈，  有问题大家帮你解决， 不能上来就要被人给你完整的源码， “看别人的比自己写还难”，相信这句话吧， 直接要答案也无助于自己的提高 //2020,1,17 //p115,3 #include<stdio.h> int main() { 	int a,p; 	char level; 	printf("输入等级请按1,输入分数请按2\n"); 	scanf("%d",&a); 	if(a==1) 	{ 		printf("请输入等级:\n"); 		scanf("%c",&level); 		switch(level) 		{ 			case 'A': 				printf(">=85"); 				break; 			case 'B': 				printf("70-85");	 				break; 			case 'C': 				printf("60-70"); 				break; 			case 'D': 				printf("<60");	 				break; 			default: 				printf("输入成绩有错!"); 				break;	 	 		} 	} 	if(a==2) 	{ 		printf("请输入分数:\n"); 		scanf("%d",&p); 		if(p>=85) 		printf("A"); 		else if(p>=70&&p<85) 		printf("B"); 		else if(p>=60&&p<70) 		printf("D");  	} 	return 0; } 这个输入1之后，直接输出成绩有错，该怎么办呀[/quote] 应该是错在scanf("%c",&level)改成scanf("%c",level)，你要用&的话是在使用指针的时候用[/quote] 我上面说错了，c语言最近比较少看了[/quote] 嗯，谢谢帮助

谢谢大家

你输入1的时候敲了一个回车，level接收了这个回车\n，自然就错了 scanf("%d\n")会让你多敲一个回车，也有可能引起错误，加个getchar()接收掉\n即可

引用 6 楼 寻开心的回复:你自己写吧， 不知道啥是你能看得懂的  把有问题的代码贴出来， 不要贴图哈，  有问题大家帮你解决， 不能上来就要被人给你完整的源码， “看别人的比自己写还难”，相信这句话吧， 直接要答案也无助于自己的提高 //2020,1,17 //p115,3 #include<stdio.h> int main() { 	int a,p; 	char level; 	printf("输入等级请按1,输入分数请按2\n"); 	scanf("%d",&a); 	if(a==1) 	{ 		printf("请输入等级:\n"); 		scanf("%c",&level); 		switch(level) 		{ 			case 'A': 				printf(">=85"); 				break; 			case 'B': 				printf("70-85");	 				break; 			case 'C': 				printf("60-70"); 				break; 			case 'D': 				printf("<60");	 				break; 			default: 				printf("输入成绩有错!"); 				break;	 	 		} 	} 	if(a==2) 	{ 		printf("请输入分数:\n"); 		scanf("%d",&p); 		if(p>=85) 		printf("A"); 		else if(p>=70&&p<85) 		printf("B"); 		else if(p>=60&&p<70) 		printf("D");  	} 	return 0; } 这个输入1之后，直接输出成绩有错，该怎么办呀

引用 10 楼 @__Chao - L的回复:[quote=引用 7 楼 ?Victor.??的回复:][quote=引用 6 楼 寻开心的回复:]你自己写吧， 不知道啥是你能看得懂的  把有问题的代码贴出来， 不要贴图哈，  有问题大家帮你解决， 不能上来就要被人给你完整的源码， “看别人的比自己写还难”，相信这句话吧， 直接要答案也无助于自己的提高 //2020,1,17 //p115,3 #include<stdio.h> int main() { 	int a,p; 	char level; 	printf("输入等级请按1,输入分数请按2\n"); 	scanf("%d",&a); 	if(a==1) 	{ 		printf("请输入等级:\n"); 		scanf("%c",&level); 		switch(level) 		{ 			case 'A': 				printf(">=85"); 				break; 			case 'B': 				printf("70-85");	 				break; 			case 'C': 				printf("60-70"); 				break; 			case 'D': 				printf("<60");	 				break; 			default: 				printf("输入成绩有错!"); 				break;	 	 		} 	} 	if(a==2) 	{ 		printf("请输入分数:\n"); 		scanf("%d",&p); 		if(p>=85) 		printf("A"); 		else if(p>=70&&p<85) 		printf("B"); 		else if(p>=60&&p<70) 		printf("D");  	} 	return 0; } 这个输入1之后，直接输出成绩有错，该怎么办呀[/quote] 应该是错在scanf("%c",&level)改成scanf("%c",level)，你要用&的话是在使用指针的时候用[/quote] 我上面说错了，c语言最近比较少看了

引用 7 楼 ?Victor.??的回复:[quote=引用 6 楼 寻开心的回复:]你自己写吧， 不知道啥是你能看得懂的  把有问题的代码贴出来， 不要贴图哈，  有问题大家帮你解决， 不能上来就要被人给你完整的源码， “看别人的比自己写还难”，相信这句话吧， 直接要答案也无助于自己的提高 //2020,1,17 //p115,3 #include<stdio.h> int main() { 	int a,p; 	char level; 	printf("输入等级请按1,输入分数请按2\n"); 	scanf("%d",&a); 	if(a==1) 	{ 		printf("请输入等级:\n"); 		scanf("%c",&level); 		switch(level) 		{ 			case 'A': 				printf(">=85"); 				break; 			case 'B': 				printf("70-85");	 				break; 			case 'C': 				printf("60-70"); 				break; 			case 'D': 				printf("<60");	 				break; 			default: 				printf("输入成绩有错!"); 				break;	 	 		} 	} 	if(a==2) 	{ 		printf("请输入分数:\n"); 		scanf("%d",&p); 		if(p>=85) 		printf("A"); 		else if(p>=70&&p<85) 		printf("B"); 		else if(p>=60&&p<70) 		printf("D");  	} 	return 0; } 这个输入1之后，直接输出成绩有错，该怎么办呀[/quote] 应该是错在scanf("%c",&level)改成scanf("%c",level)，你要用&的话是在使用指针的时候用

你这就把他当作两个题写就好了啊。或者你可以定义一个变量，先提示选择什么方式输入成绩，比较变量，如果是百分制执行一段代码，如果是等级制执行另一段代码，用一个变量去控制两种输入方法

引用 2 楼 寻开心的回复:int     score [] = {100， 85,   70,   60,   0   } char* level [] = {  "S",    "A", "B",  "C", "D" }  输入程序成绩s，就在score里面查询，      for ( i=1; i<4; i++ )          if( s>score[i] )  {printf("%s", level[i]); break;}  如果输入等级l， 就在level里面查找    for ( i=1; i<4; i++ )        if （strcmpy（l， level[i] )  printf("%d - %d", score[i], score[i-1]), break; 能发一下完整的代码吗，有点看不懂（＃－.－），谢谢

引用 1 楼 與蘤舊縐的回复:不是写明白了吗，A对应85-100，B……，一个swith可以搞定，第二个switch比较难想的话就if else if else if ……吧 但是我要把他们统一到一起，就是输入字母，输出分数段，输入分数，输出等级，在一个程序里


Question: linux环境下使用fclose后出现段错误

你的代码中有越界到fclose的部分,fclose时就会出错.

缓存最好是 buffer_size+1, 且最后一个元素设置为0 避免buffer自身满的时候用strcat这种函数，从buffer当中读字符串的时候就越界  fclose之后， fpCon也赋值为NULL，避免二次调用close，当然二次处理怎么都是错  是否要关闭，应该是eof是否到达或者是不再使用了，是常规的判断基础

引用 2 楼 beastsam 的回复:[quote=引用 1 楼 user-3 的回复:] strlen(total) 结果是BUFFER_SIZE 说明必然是越界了 处理边界的时候 注意一下  谢谢，我修改了一下果然没报错。 可是我还是有个疑问，当我把这段单独写出一个测试用例，多次运行，结果却是正常的，请问这个是什么原因？[/quote]内存布局无法确定 越界之后修改了什么数据无法确定 导致什么结果无法确定 从崩溃到什么事都没发生都是正常的

我觉得是因为文件很长 每次读取buffer_size长度， 并进行处理， buffer是满的 所以长度等于buffer_size的部分被多次调用 因此fclose被多次调用，所以完蛋了  fclose后给这个文件做一个=NULL的赋值，你再看看

引用 1 楼 user-3 的回复:strlen(total) 结果是BUFFER_SIZE 说明必然是越界了 处理边界的时候 注意一下  谢谢，我修改了一下果然没报错。 可是我还是有个疑问，当我把这段单独写出一个测试用例，多次运行，结果却是正常的，请问这个是什么原因？


Question: 程序显示错误

引用 2 楼 user-2 的回复:第一个if最后少了一个括号)，你自己check一下 谢谢提醒，括号有点多

引用 1 楼 與蘤舊縐 的回复:else if (a=b)???? 你看你前面怎么写的 else if((a==b)||(a==c)||(b==c)) printf("等腰三角形"); 这样改了之后还是显示语法错误

引用 3 楼 與蘤舊縐 的回复:好吧，前面没有== else if((a==b)||(a==c)||(b==c)) printf("等腰三角形"); 我等号搞错了

好吧，前面没有==

第一个if最后少了一个括号)，你自己check一下

else if (a=b)???? 你看你前面怎么写的


Question: scanf输入字符串中有空格，再用strlen函数计算长度问题跪求大佬解答

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

还是仔细看看函数的说明吧，  默认的遇到空格 tab 和回车的时候， scanf是如何工作的  函数帮助文档还是要仔细的去看的 scanf("%[^\n]%*c", str);  类似这样的代码也得看懂啊

引用 2 楼 與蘤舊縐的回复:你可以用gets接收，无视空格 原来是这样 那我明白了 感谢感谢

原来是这样 那我明白了 感谢感谢

你可以用gets接收，无视空格

空格和\n都是scanf的分隔符，也就是%s部分遇到空格就结束了，不是说空格是结束符，直接初始化自然没问题


Question: 大佬们救救孩子吧...

引用 6 楼 寻开心的回复:#include<stdio.h> double com(double x,double y); double fact(double n); int main() { int a,b,c; double s=0; for(a=0;a<=3;a++) { for(b=0;b<=6-a;b++) { for(c=0;c<=9-a-b;c++) { s = s+(com(a,13)*com((9-a),32)/com(9,45))*(com(b,(13-a))*com((9-b),(23+a))/com(9,36))*(com(c,(13-a-b))*com((9-c),(14+a+b))/com(9,27)); } } } printf("%lf",s); return 0; } double com(double x,double y)              //计算yCx  { int num; num=fact(y)/(fact(x)*fact(y-x)); return num; } double fact(double n)              //计算n的阶乘  { double pro=1,i; if(n>=1) for(i=1;i<=n;i++) { pro=pro*i; } else pro=1; return pro; } 把你的int都改成double就得到0.659902啦 再说double不够还有long double那个可是128位的浮点数， 还不够吗  可以吗？那可能是我中途某个地方写错了，我再试试，谢谢

谢谢楼上的各位大佬，问题已解决 double型似乎也承受不了，网述超大数四则运算过于麻烦，萌新无法理解...所以我把n的阶乘结果除以10的n次方，在组合数公式中分子分母恰好可把10的n次方全部抵消，避免了出现超大数 还用了x，y，z分别代表三个超几何分布算式结果，输出后任取了几个用计算器验算，均正确，最终结果0.655902 诸多不足，请多赐教！

程序代码除了溢出问题以外，还有问题 1 printf（“%ld”， s）； 这是错的， s是double类型，  要%lf方式来输出  2 com（a） / com（b） 这些都是整数除法， 整数除法的结果依然是整数， 比如 1/3 就是0.  不是0.333333   你确定这些除法都是整数吗？

个人感觉45的阶层整型已经接收不了了，包括double，要用字符串类型才能接收

因为int有符号，正数最多容纳21亿。阶乘算数直接溢出了。如果是需要长期用这个公式，需要一位一位算，把结果装到数组里，类似字符串。你可以查一下100的阶乘怎么算，网上是有的。不是用算数迭代或者递归。谢谢！

用int类型计算阶乘溢出了， int表达的范围没有那么大， 我记得13！就要冒了 改成double类型去运行看看吧


Question: C语言为什么我们尽量不使用goto语句？

你最后两句话不是解答了吗

老师说频繁用可能会导致程序崩溃，我没见到过，可能程序太小也没咋用，不过试过死循环，不小心放错了位置，就死循环了。放的多了还不好找错

性能损失  goto是由硬件汇编衍生过来的，对应汇编的jump或者long jump。但是在过去时间里面cpu的主频比较低，但是还是会有基本的流水线结构，一般执行当前指令时，会预取两条指令存储在寄存器中。但是goto回直接让cpu进行跳转，这样的结果就是预取的指令用不上了，然后需要重新预取指令进行执行。早一些的cpu的跳转能力还很差，多次的跳转会让cpu性能损失比较严重。

引用 6 楼 寻开心的回复:是执行效率的问题 现代计算机都可以预取指令， goto就打破了这个方式了 不同意效率的说法 是代码逻辑需要跳指令 goto只是手段 用break 用return 都会造成预读指令失效的情况

此外就是goto实际上会把结构化和模块化的方式打破， 多了就更难理解程序的结构了 不是不能用， 可以用

引用 3 楼 HZHI123 的回复:不加限制地使用goto：破坏了清晰的程序结构，使程序的可读性变差,甚至成为不可维护的"面条代码"。经常带来错误或隐患，比如它可能跳过了某些对象的构造、变量的初始化、重要的计算等语句。 关于使用goto语句的原则： （1）使用goto语句只能goto到同一函数内，而不能从一个函数里goto到另外一个函数里。 （2） 使用goto语句在同一函数内进行goto时，goto的起点应是函数内一段小功能的结束处，goto的目的label处应是函数内另外一段小功能的开始处。 （3）不能从一段复杂的执行状态中的位置goto到另外一个位置，比如，从多重嵌套的循环判断中跳出去就是不允许的。 （4）应该避免像两个方向跳转。这样最容易导致"面条代码"。  原则1 毫无意义 goto 本来就没有跨函数的功能 原则3 跳出多层循环本来就是goto 使用场景之一 不用goto用什么?

是执行效率的问题 现代计算机都可以预取指令， goto就打破了这个方式了

想要一次性跳出多层循环用下goto省事呗，还有些喜欢用goto跳到错误处理的，另外可能不太用 像从一个函数跳到另一个函数的这种太可怕了，严重的新手不友好

没人举例子吗？


Question: 二分法找数字位置，大师帮忙看看

二分查找的条件是： 序列有序; 序列之内无重复值。

二分查找是对有序数组的

怎么不科学呢。 都是按照你的代码逻辑走的啊 输入133，一直找到没有找到，但是mid的数值还是一直有效的啊，最后要输出，剩下什么就输出什么了 你的代码一直查右边， left=right=9就是结束情况，mid也是它  关键是二分法查找，先决条件是数组是排序过的，你这个没有排， 二分法也不好使

最好直接贴代码，不要贴图片了。测试过程和结果可以贴图片的

说错了， 你的流程是 while 进来后      mid =4。（9/2就是4）       find=133     第一个if不符合条件     第一个else符合条件          left=6         然后break退出了while循环  打印了mid+1 也就是5出来了  按照你的思路走 while 里面的部分要如下修改    if  成立的部分       只留一句break就可以了    第一个else里面         删除break那行    第二个else里面         不用改 } while 循环体外面， 到这里只有两种情况发现结果break出来的， 或者是left<right不满足 所以这里才是    if（left<right)          输出找到的结果   数组不是有序数组， 二分法无效的问题要先解决，否则前面的算法就是废柴


Question: 循环提前结束，循环的条件无故被修改

我用vs2017运行了一下你这代码，没问题。建议你打个断点调试一下。

T[i].Left=cl-'0'; 重点看一下这个Left值是不是会导致check越界，越界操作可能就会修改N的值。

为什么N会被修改呢？

#include<stdio.h>  #define MaxTree 10 #define ElementType char #define Tree int #define Null -1  struct TreeNode {     ElementType Element;     Tree Left;     Tree Right; }T1[MaxTree],T2[MaxTree];   Tree BuildTree(struct TreeNode T[]) {     Tree N,i,Root;     ElementType cl,cr;     printf("输入结点数\n");     scanf("%d",&N);//N的输入值为8     getchar();    //for '\n'     Tree check[20];     printf("输入每个结节的信息\n");     if(N){         for(i=0;i<N;i++){             check[i]=0;         }         for(i=0;i<N;i++){             printf("%d %d\n",i, N);             scanf("%c %c %c", &T[i].Element,&cl,&cr);             getchar();             if(cl!='-'){                 T[i].Left=cl-'0';                 check[T[i].Left]=1;             }             else T[i].Left=Null;         }         printf("i=%d N=%d\n", i,N);//循环提前结束，N的值也被无故修改         for(i=0;i<N;i++){             if(!check[i]){                 break;             }         }         Root=i;     }     return Root; }  int main(void) {     BuildTree(T1);      return 0; } 供参考～   加一条getchar();在第一个scanf之后，然后测试输出i = 8, N = 8

因为 cr还没有被处的缘故吧 cl处理了，cr读入但是没有处理 check检查的时候遇到了没有被设置过的节点了  if(cl!='-'){                 T[i].Left=cl-'0';                 check[T[i].Left]=1;             }             else T[i].Left=Null; 这个后面应该有 if (cr != '-') 对T[I].Right 赋值和设置check【t【I】.Right】


Question: C语言小白求助！！！！！！！！！！！！！！

这个就是可以无限输入哈，正数0负数都可以输入，楼上说的有些问题哈

应该是只要输入就执行循环吧

scanf函数返回值是int，就是返回你成功输入的数量，而while是判断0或非零的，所以可以放在判断里，有输入则执行，没有为零跳出

有看过书或者看视频学习吗？没有的话，建议百度一下。


Question: 急求，c语言大神

尴尬，main 昏头了

至于这个错误，我们是main函数，不是mian函数

printf里面\n不是空格，空格隔开最后在换行 你第一个的if比较完了a=b？那不是改变了变量本身的值？下面在用变量值会出错 第二个max>a[i]了那max都是大的了为啥要赋小的值？min同理；max跟min的判断可以放在一个循环，两个if就好了，没必要另开一个循环


Question: so库运行时出现undefined symbol: max的错误

编译时有一个警告：警告：隐式声明函数‘max’


Question: C语言求解

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

switch语句在执行时 到case 1以后会在向下执行case直到遇到break

缺少break，未必不是程序设计者的本意啊

#include<stdio.h> int main(void) { 	int x=1,y=1; 	int m,n; 	m=n=1; 	switch(m) 	{ 		case 0: 			x=x+2; 			break; 		case 1: 			{ 				switch(n) 					{ 						case 1:x=x*2;break; 						case 2:y=y*2;break; 						case 3:x++;break; 					} 				break; 			} 		case 2: 			x++;y++; 			break; 		case 3: 			x*=2;y*=2; 			break; 		default: 			x++; 			y++; 			break; 	} 	printf("%d %d\n",x,y); 	return 0; }

缺少break吧

没有加break的case会从你判断进入的case开始一直往下执行，不论下面的case的值是不是匹配，知道遇到break或执行结束为止

了解 谢谢大佬

case 1: x*=2; case 2:y*=2; break;  因为 x*=2; 后面没有break， 它就会继续向下运行 case 2:部分的语句， 一直到遇到break为止  从内层的switch case语句出来，继续运行到break才推出外层的switch语句  看看书上关于case语句的描述， 有break和没有break的区别


Question: C语言求助！！！！！关于getchar（）的问题！！

getchar（）这个函数就是获取一个字符，只要你用了就会去获取，ch = getchar(); 就会把这个字符赋值给ch变量，跟ch有没有加一没有关系，其次你这个是字符不是数组，ch加一也只是去找下一个字符输出出去，也不会改变ch的值，你输出ch+1的时候ch是不变的，只是放到输出的结果的对应值会加一输出

引用 1 楼 寻开心 的回复：ch = getchar();    //这里不懂！为什么会自动获取下一个字符，不是应该获取原字符吗？ch又没有+1 自动获取下一个字符，应该表述为，获得下一个键盘输入的字符 不是ASCII字母表顺序的下一个字符  while循环里面， 不断的获取键盘输入字符判断是什么内容并做不同的处理，直到遇到回车字符为止但是ch没有+1啊！为什么就获取了键盘输入的下一个字符？


我是个小学生，说实话，每一次用visual studio 2019时经常会产生“我能行”的错觉。

可以考虑换一个编译器。例如全能强大vs2017，小一点的devc++。跨平台的编辑器vscode。

如果一定要在WINDOWS 10下用VC++，不说装VS 2019，最低也要安装VS 2005啊。  我个人装了VS 2012, 2015, 2019，但最喜欢还是2015.  虚拟机里倒是有2005.

用啊， 我们用turbo c的时候，谭浩强还很年轻呢

引用 10 楼 寻开心的回复:还是 tubro c 2.0 比较好，  cmd窗口里面就可以跑。 大哥，你们还用谭浩强的书吗

顶...................

给你们科普一下，现在的大学，大一学C，老师都让用祖传的VC6.0

开启虚拟机，在虚拟机中早先的系统，然后安装VC6

winworldpc我知道，其中vs97日文版就是我提供的（我提供给 betaarchive，然后又被人从ba搬运到winworldpc） visual c++ 4.0我有正版的光盘

微软开放了 Visual Studio SDK和Visual Studio Shell 实际上 SQL Server Management Studio、InstallShield、Python tools for Visual Studio等都是基于 VS Shell的“第三方”产品。

虽然我没有仔细去分析过VS 6.0的组件和结构，但根据我以前使用的印象，MSDEV和VC++的编辑器，本质上，应该，貌似，是一个东西？或者说，一个编辑器，两套配置？ 原因有两点： 1.MSDEV的界面，和VC++ 6.0编辑器的界面很相似。而完全版的VS 6.0里面，貌似是包含了MSDEV的； 2.VC++ 6.0的编辑器，其实不像VB 6.0和VFP 6.0那样，和编译器绑定得很死，它的编译器其实是分离开来的，我记得很早以前还用VC++ 6.0的编辑器，写过ARM代码，然后可以配置ARM编译器的，所以，我觉得把它配成写WEB代码的玩意，不出奇。  另外，看你提到VC++ 4.0，我也发一个网址，以前在CSDN上看到的，里面有很多古老的软件和工具（含操作系统、编译器什么的）： https://winworldpc.com/library 引用 23 楼 贵阳老马马善福专业维修游泳池堵漏防水工程 的回复:微软本来是想搞一个统一的开发环境的 最初的项目叫做 Developer Studio 以 Visual C++ 为基础，后来整合进了 Visual J++ 1.0 但是这个环境很不好用。 于是微软又搞了 MSDEV。在VS 6.0中，这是 Visual Interdev和Visual J++公用的 IDE，后来微软又把js的脚本调试器也整合进来。 到了2002年，微软才把Visual Basic Visual C++加上Visual C#塞入这个IDE 这个IDE一直到现在都没换。  当我98年第一次见到 MSDEV 那清新脱俗的界面，我就断定，这个IDE会统治世界，后来的发展果然如此。

其实我初学时用的IDE是：Code:Blocks 这个W10是可以兼容的

初学可以用dev c++，之后慢慢转VS

引用 22 楼 super_admi 的回复:微软的这套开发软件，貌似VS 6.0是最后一个编辑器和编译器绑定得很死的版本吧，VS 6.0中的三大块：VC++ 6.0, VB 6.0, VFP 6.0，都是一个编辑器配一个编译器，不过VC++ 6.0还好些，编辑器和编译器绑定貌似没那么紧。  所以，我看到很多人说什么：不要用VC++，要用VS，我就一头雾水：微软的VS不是从很早开始就一直包含了VC++?即使VS不同版本所包含的内容不一样，但VC++一直是VS的保留项目吧？  从VS 2002开始，微软就开始统一了编辑器，使用同一个编辑器+不同的编译器，来做开发，而近几年的VS Code，更是可以说，完全把编译器抛开了，成了一个独立的编辑器了。  微软本来是想搞一个统一的开发环境的 最初的项目叫做 Developer Studio 以 Visual C++ 为基础，后来整合进了 Visual J++ 1.0 但是这个环境很不好用。 于是微软又搞了 MSDEV。在VS 6.0中，这是 Visual Interdev和Visual J++公用的 IDE，后来微软又把js的脚本调试器也整合进来。 到了2002年，微软才把Visual Basic Visual C++加上Visual C#塞入这个IDE 这个IDE一直到现在都没换。  当我98年第一次见到 MSDEV 那清新脱俗的界面，我就断定，这个IDE会统治世界，后来的发展果然如此。

用visual studio：https://visualstudio.microsoft.com/zh-hans/vs/ community版，功能足够用，而且免费。现在要是再用vc6.0真的是没事找罪受。

最新的visual studio安装一个就好了，搞那么老的工具 界面看着不累吗

用VS吧，以后基本也都用的VS

vc community 2012及以上版本都可以 引用 12 楼 lxx15731198095 的回复:[quote=引用 11 楼 lxx15731198095的回复:][quote=引用 2 楼 user-15的回复:]珍惜下生命吧。现在2020年了。你在学编程，不是学考古！ 换个新点的编译器。 能建议一个吗？我是刚学的大学生[/quote] 能兼容win10好安装好操作的，谢谢！[/quote]

引用 11 楼 lxx15731198095的回复:[quote=引用 2 楼 user-15的回复:]珍惜下生命吧。现在2020年了。你在学编程，不是学考古！ 换个新点的编译器。 能建议一个吗？我是刚学的大学生[/quote] 能兼容win10好安装好操作的，谢谢！


Question: C语言初学者之10个数字排序问题

引用 1 楼 自信男孩 的回复：注意j < 10时，j+1已经越界了。  第二层循环内改成： for (j = 0; j < 10 -1 -i; j++) if (a[j] > a[j+1]) {     temp = a[j];    a[j] = a[j+1];     a[j+1] = temp; }点赞


Question: 求助，这道题怎么做

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

从小到大排序，是不是初始堆应该建立为大顶堆

7  3 7  1 7 3  1 7 3 8  1 6    3 8 7   1 6    2 8 7 3  1 6    2 8 7 3 4  1 5    2 6 7 3 4 8

min-heap

那就要么都写，要么就写一个后面坠上大还是小就好了啊，反正作业，练得是你会不会用，会了老师都会过的


Question: 结构体指针p指向结构体变量stu，在引用指针时（*p）以此形式出现，当中（*p）表示p指向的结构体变量stu，但*p不是表示取p指向的变量stu的值吗？

p是指针，不能p.num，只能p->num， p->num和stu.num是一样的 (*p).num和p->num，stu.num是一样的

p不是指向stu的指，而是指向stu的地址 即 赋值时 your_struct* p = &stu //声明一个结构体指针，指向stu的地址 所以 p->num 等价于 stu.num，等价于(*p).num

struct {      int num； } stu， *p； p = &stu; 如果是这样的话 那么    p->num   stu.num     (*p).num   这三者是一致的


Question: visual studio添加curl库

你看下到底include文件夹下到底有没有这个文件就知道了，估计你编的有问题


Question: C语言小白求助！！！！！！！！！！！

打印格式不对吧，而且打印参数和打印格式的个数也不一致 printf("%*s,%*s\n", 10, first_name, 10, last_name); //打印格式只有2个而且有误，打印参数有4个

getchar用于吸收scanf留到键盘缓冲区的回车键 一般是数字和字符混合输入的时候使用， 输入一个数字，再要求输入一个字符的时候， 需要在输入字符前用这个getchar函数或者fflush函数把键盘缓冲区清空， 否则获取的字符就是之前输入的回车键  从你的代码上，后面没有输入，这个getchar没有什么意义

scanf_s("%s", first_name, 40); 缺少参数。  可以不用。自己试试不用是否可以正常运行呢，自己完全可以自己试试


Question: 有关scanf的参数为函数或字符串的问题

也可以去修改那个itobs函数， 在里面malloc一个空间， 然后return出去，用完了之后再去free它 这样他爱写多长的printf都可以，只要调用前用一个char*指针缓存这个返回值，回头用完了free掉就好了 itobs函数第二个参数都不必需要了

#include <stdio.h> #include <limits.h>  unsigned int lrotate(unsigned int, int); char * itobs(unsigned int, char *); int main() { 	unsigned int test; 	int bits; 	char bstr1[CHAR_BIT * sizeof(unsigned int) + 1]; 	char bstr2[CHAR_BIT * sizeof(unsigned int) + 1]; 	printf("请输入一个无符号整数\n"); 	while (scanf("%u", &test)) 	{ 		printf("请输入要旋转的位数\n"); 		scanf("%d", &bits); 		int ret; 		char *ret_bin1,*ret_bin2; 		ret_bin1 = itobs(test, bstr1); 		ret = lrotate(test, bits); 		ret_bin2 = itobs(ret, bstr2); 		printf("%u(%s) 向左旋转%d位后是%u(%s)\n", test, ret_bin1, bits, ret, ret_bin2); 		printf("请输入下一个无符号整数\n"); 	} 	return 0; } unsigned int lrotate(unsigned int dec, int n) { 	unsigned int mask = 0; 	unsigned int loss; 	unsigned int newdec;  	n = n % (CHAR_BIT * sizeof(unsigned int));  	for (int i = 0; i < CHAR_BIT * sizeof(unsigned int); i++) 	{ 		mask <<= 1; 		if (i < n) 			mask++; 	} 	loss = mask & dec; 	newdec = (dec << n) + loss; 	return newdec; }  char * itobs(unsigned int ori, char * pt) { 	const int size = CHAR_BIT * sizeof(int); 	for (int i = size - 1; i >= 0; i--, ori >>= 1) 		pt[i] = (1 & ori) + '0'; 	pt[size] = '\0'; 	return pt; } VS2015 C++环境调试

存在两个问题 一  最关键在这个itobs(test, bstr)上面 printf函数里面调用了它两次， 而两次都对bstr做了修改， 这就是问题所在 c语言函数调用的时候，参数本身是函数，那么所有的函数都计算完成后，把结果作为参数完成真正的调用 你想想，此时这两个参数是什么？ 都是bstr这个字符串！！！ 所以，这两个参数是同一个值   二 为什么是代码上第一个 itobs调用后的bstr值，而不是第二个 这是因为，c语言当中并没有规定，函数的参数的执行顺序， 多个参数表达式谁先执行，谁后执行是未定义行为， 编译器可以自行规定 所以，这个结果在不同的编译器上，很有可能是不同的。 这种未定义行为必须避免  如何改 两次调用itobs用不同的bstr参数就好啦


Question: c/c++里，一段int类型怎么转成float？

必须用普通循环逐个进行转换并赋值，复杂度为 O(kn)。 在实践中，如果你的平台支持 SIMD，则可以通过手动/编译器优化代码来减小常数 k。

你没办法用memcpy啊， 两者之间的内存结构差异太大 只有同种类型的，你用memcpy取代赋值是可行的， int 1和float 1都是32位，但是内存结构上完全不同的， 不能用内存拷贝替代  如果只是char，short，int， long这些可以用memcpy 但是他们和float，double这种之间就没有办法了 赋值不是简单的memcpy，还包含了格式转换这一步

引用 2 楼 自信男孩的回复:float表示的范围应该是大于int，所以直接赋值就好了。 当数据量大的时候，赋值比memcpy多2~3倍的时间

没啥好办法， 只能再开个floa他数组，挨个赋值转换后再使用

引用 1 楼 寻开心的回复:分配一个int类型的动态内存 和float有什么关系啊  float * data = (float*) malloc(sizeof(float)*(1<<23));   2^23在c里面可不是2的23次方，而是位预算当中的异或操作。   data是4*1024*1024*8 大概32MB的内存不算大 2^23是一个表示。 我有int的数据，要转成float来调用函数来运算，接口给的float。

需要重新拷贝一遍吧

float表示的范围应该是大于int，所以直接赋值就好了。


Question: 安装C语言的可选扩展，使完整支持C11，需要搜点什么装一下

引用 3 楼 user-1的回复:C语言写的代码不死，但是C语言本身已经死了。 在硬件领域仍然在动的是C89甚至是k & r C [quote=引用 2 楼 與蘤舊縐 的回复:] [quote=引用 1 楼 user-1的回复:]C语言已死，没人折腾C11了吧。 这么嚣张的嘛不管怎么说至少在硬件领域依旧是王者[/quote][/quote] 原来如此，我只是喜欢新的，想了解下

C语言写的代码不死，但是C语言本身已经死了。 在硬件领域仍然在动的是C89甚至是k & r C 引用 2 楼 與蘤舊縐 的回复:[quote=引用 1 楼 user-1的回复:]C语言已死，没人折腾C11了吧。 这么嚣张的嘛不管怎么说至少在硬件领域依旧是王者[/quote]

引用 1 楼 user-1的回复:C语言已死，没人折腾C11了吧。 这么嚣张的嘛不管怎么说至少在硬件领域依旧是王者

C语言已死，没人折腾C11了吧。


Question: c中如何对浮点数进行位运算？如果不能，怎么读取浮点数二进制内容？

错了，这样弄不成，兜兜转转还是要转换。 妙啊!

引用 4 楼 寻开心 的回复:long long itobs(long long int n) {  	long long int s=0; int i; int size=8*sizeof(long long); for(i=size-1;i>=0;i--,n>>=1)     { s|=(1&n); // 这里s最多也就是1， 因为之前的s是0    	s>>=1;  // 再右侧移， 结果必然是0     }     printf("%lld\n",s); return s; }  没明白你这个函数要做什么  主函数里面 long long int t = *((long long int*)&num);  这样才是把num强制转换成long long printf("%#llX", t); // 就可以直接输出16进制的long long类型  通过了   原来的思路是想通过位运算，把t的二进制数字复制到s中，把s中的数字弄到字符串里，用itoa。。。。不过貌似不能实现，itoa进的是十进制intger  这个是仿照c primer plus里的一个显示二进制的程序改编的，但是貌似这里好像用不了这么麻烦。。。。  我想实现以二进制形式的copy，虽然及其笨拙。。。但是我调试的时候，s的值有1啊。我觉得这个逻辑没问题。

引用 2 楼 寻开心 的回复:double d = 123.456； long long int  t = (long long int *) &d; 然后把t按照位输出就行了  double是8位， float是4位 int 和 long int 在windows下都是 4位， long long int 才是8位 #include <stdlib.h> #include <stdio.h> long long itobs(long long int n) {  	long long int s=0; 	int i; 	int size=8*sizeof(long long); 	for(i=size-1;i>=0;i--,n>>=1)     {    		s|=(1&n);    		s>>=1;     }     printf("%lld\n",s); 	return s; } int main(void) {     double num;     char str[65];     scanf("%lf",&num);     long long int t=(long long int)*#     itoa(itobs(t),str,16);     printf("%s",str);     return 0; } 不知道怎么回事，这个t用longlong输出是0，调试的时候位操作有效，但这个好像只截了一部分

源题 7-35 研究：双精度实数的机内码* (10分)  输入格式 十进制实数  输出格式 机内码(十六进制)  要求：十六进制机内码中的字母均为大写。  例如：实数 3.6 转换成二进制是 11.1001100110011001...，科学计数法记为：1.11001100110011001...×10^ 1  ，因此 64 位的机内码为：0100000000001100110011001100110011001100110011001100110011001101，用十六进制书写则为：400CCCCCCCCCCCCD。


Question: 哪位大佬帮忙按照我的思路改一下，是主函数的错误，不要大幅度修改，刚接触链表，求大佬指点

引用 6 楼 ?Travelers的回复:[quote=引用 4 楼 自信男孩的回复:]#include <stdio.h> #include <stdlib.h> struct node {     int data;     struct node *next; };// *node[5]={{1},{3},{5},{7},{9},{11}}; int main() {     struct node *insertnode(struct node *head,int key,int vaule);     struct node *head = NULL, *p;     //printf("insertnode(head,3,5)");     head = insertnode(head,3,5);     head = insertnode(head,4,7);      p = head;      while(p) {          printf("%d\t", p->data);          p = p->next;      }      putchar(10);      return 0;  } struct node *insertnode(struct node *head,int key,int vaule)     /*head是链表头指针，在值为key的结点前插入值为vaule的结点*/ {     struct node *p,*r;     r=(struct node*)malloc(sizeof(struct node));/*为待插入的结点分配空间*/     r->data=vaule;/*赋值数据域*/     //if(head=NULL||head->next=key)/*如果颠倒顺序可能错误*/     if(head==NULL||head->data==key)/*如果颠倒顺序可能错误*/     {         r->next=head;         head=r;         return(r);     }/*链表为空或者 结点为key的情况*/     p=head;     //while(p->next!=NULL&&p->data=key)     while(p->next!=NULL&&p->data !=key)     {         p=p->next;         //return(r);     } /*寻找key的结点*/     r->next=p->next;     p->next=r;/*插入新结点*/      return head; } 供参考～  不是很理解你的需求，上面的代码执行没问题～ 就是用struct node *(struct node *head,int key,int value )这个函数编写一个程序[/quote] 是不是还需要增加一个输出函数？

引用 4 楼 自信男孩的回复:#include <stdio.h> #include <stdlib.h> struct node {     int data;     struct node *next; };// *node[5]={{1},{3},{5},{7},{9},{11}}; int main() {     struct node *insertnode(struct node *head,int key,int vaule);     struct node *head = NULL, *p;     //printf("insertnode(head,3,5)");     head = insertnode(head,3,5);     head = insertnode(head,4,7);      p = head;      while(p) {          printf("%d\t", p->data);          p = p->next;      }      putchar(10);      return 0;  } struct node *insertnode(struct node *head,int key,int vaule)     /*head是链表头指针，在值为key的结点前插入值为vaule的结点*/ {     struct node *p,*r;     r=(struct node*)malloc(sizeof(struct node));/*为待插入的结点分配空间*/     r->data=vaule;/*赋值数据域*/     //if(head=NULL||head->next=key)/*如果颠倒顺序可能错误*/     if(head==NULL||head->data==key)/*如果颠倒顺序可能错误*/     {         r->next=head;         head=r;         return(r);     }/*链表为空或者 结点为key的情况*/     p=head;     //while(p->next!=NULL&&p->data=key)     while(p->next!=NULL&&p->data !=key)     {         p=p->next;         //return(r);     } /*寻找key的结点*/     r->next=p->next;     p->next=r;/*插入新结点*/      return head; } 供参考～  不是很理解你的需求，上面的代码执行没问题～ 就是用struct node *(struct node *head,int key,int value )这个函数编写一个程序

#include <stdio.h> #include <stdlib.h> struct node {     int data;     struct node *next; };  struct node *insertnode(struct node *head,int key,int vaule); void printLink(struct node * pHead);  int main() {     struct node * head = NULL, *t=NULL;     int i=0;     for ( ; i<5; i++) {         if ( NULL == head ) {             t = head = (struct node *) malloc(sizeof(struct node));             head->data = 1;             continue;         }         t->next = (struct node *) malloc( sizeof(struct node));         t->next->data = 2*i+1;         t = t->next;     }     t->next = NULL;     printf("InitLink:");     printLink(head);     printf("Insert 3,4:");     insertnode(head, 3, 4);     printLink(head);     printf("Insert 6, 6:");     insertnode(head, 6, 6);     printLink(head);     printf("Insert 6,12:");     insertnode(head, 6,12);     printLink(head);     return 0; } struct node *insertnode(struct node *head,int key,int vaule) /*head是链表头指针，在值为key的结点前插入值为vaule的结点*/ {     struct node *p, *r;     r=(struct node*)malloc(sizeof(struct node));/*为待插入的结点分配空间*/     r->data=vaule; /*赋值数据域*/     p = head;     while ( p->next !=NULL && p->data !=key ) p=p->next;     if ( p->data==key) {         r->next = p->next;         p->next = r;     } else if ( p->next == NULL ) {         p->next = r;         r->next = NULL;     }     return r; }  void printLink(struct node * pHead) {     struct node * p = pHead;     while(p != NULL ) {         printf("%d -> ", p->data);         p = p->next;     }     printf("NULL\n"); }

#include <stdio.h> #include <malloc.h>  struct node {     int data;     struct node *next; };   int append(struct node *head, int data) {     if (head == NULL) {         return 0;     }     struct node *temp = (struct node *) malloc(sizeof(struct node));     struct node *tmp = head;     while (tmp->next != NULL) {         tmp = tmp->next;     }     temp->data = data;     temp->next = NULL;     tmp->next = temp;     return 1; }  int showChain(struct node *head) {     if (head == NULL || head->next == NULL) {         return 0;     }     struct node *temp = head->next;     int count = 1;     while (temp->next != NULL) {         printf("第%d个结点的值为%d\n", count, temp->data);         temp = temp->next;         count++;     }     return 1; }  int insert(struct node *head, int key, int data) {     if (head == NULL) {         return 0;     }     int loop = 0;     struct node *temp = head;     while (temp->next != NULL) {         if (temp->data != key) {             temp = temp->next;             continue;         }         loop = 1;         struct node *tmp = (struct node *) malloc(sizeof(struct node));         tmp->data = data;         tmp->next = temp->next;         temp->next = tmp;         break;     }     if (loop == 0) {         printf("未找到指定结点");         return 0;     }     return 1; }  int main(void) {     struct node *head;     for (int i = 0; i < 7; i++) {         append(head, 2 * i + 1);     }     insert(head, 7, 13);     showChain(head);     return 0; }

head->next->data打错了~~

head=NULL||head->next=key？？？？？== printf("insertnode(head,3,5)");？？？？？输出字符串呢这是 if(head=NULL||head->next=key)？？？？head->next.data==key ~~~~无语了，这程序可能跑起来


Question: 请教C中文件的写入

引用 7 楼 lin5161678 的回复:默认行缓冲 遇到\n 缓冲区满 关闭文件  才会自动触发写入文件  这里一次循环不会触发写入文件 等到第二次循环 追加模式打开文件的时候 文件还是空的 所以 内容顺序乱了 好的 谢谢啦 我再思考思考

引用 5 楼 自信男孩 的回复:把fopen放到循环外，你要打开三次文件吗？如果打开文件三次，那么每次写入都是从文件头开始的。 我用的是追加

引用 1 楼 lin5161678 的回复:加 fflush(fp); 就没这个问题了 另外 循环fopen 没fclose 是错的  请替我解惑一下上面两条疑问，麻烦了

就单论正确的方式，是要在循环中有fopen的同时有fclose，但不在循环中这种错误导致的特殊情况是什么原理造成的方便解释一下吗？唯独最后一个结果到了最前面蛮有趣的，想深入了解

我好奇的是，为什么会出现这样子的情况呢？ 能解释一下 原理吗


Question: c语言，急求大神

scanf("%d",aStudents[i1].money); 这个参数要传递money的地址进去才行 name不需要是因为它是数组，数组名本身就代表一个地址

缺少头文件，加一下<stdlib.h>试试～

#include<stdlib.h> #include <conio.h>  一个对应exit的，一个对应getch函数的


Question: 请教c语言基础问题

引用 3 楼 自信男孩的回复:在第二个scanf后面加一个getchar();用于接收输入第二个数据之后的'\n'换行符。否则第三个scanf，即%c接收的是'\n'换行符。 看了你们的分析，真的学到了，我应该再仔细点。

引用 1 楼 寻开心的回复:不是跳过了，而是把上一句scanf留到键盘缓冲区的'\n'字符获得到了。 在你这个scanf之前，增加一个getchar（）函数，把这个回车字符提取出来，然后再scanf这个字符就好了 哦哦，吸收回车，这我之前不知道，学到了，谢谢你。

你可以在scanf("%c", &Fh); 之后增加一句 printf("Fh:%d\n", Fh); 来验证这点。 它会输出一个10， 也就是'\n'这个回车字符的ASCII值  getchar(); scanf("%c", &Fh); 这样过滤掉前面的回车键


Question: 为什么调用函数保存不了数据呢？一直输出0%，谢谢

引用 3 楼 weixin_46024012 的回复:谢谢各位，我其实知道是要传地址，但我想看看主函数和子函数的同一个变量名的变量能等同用吗？现在我知道好像不能了 名字一样但是属于不同的函数栈，可以理解为两个不同的变量。

或许你还要再看看作用域的知识。

#include<stdio.h>  //int *pointer1,int *pointer2,int *pointer3,int *pointer4) void calculate_sum(int *age,int *sum1, int *sum2, int *sum3,int *sum4) {     if(*age>=0&&*age <= 18)         (*sum1)++;     if(*age>=19&&*age<=35)         (*sum2)++;     if(*age>=36&&*age<=60)         (*sum3)++;     if(*age>=61)         (*sum4)++;  }//写了一个给单个元素分类的函数。  int main() {     int a[10000],n,i,sum1=0,sum2=0,sum3=0,sum4=0;     scanf("%d", &n);     for(i=0;i<=n-1;i++)     {         scanf("%d",&a[i]);         calculate_sum(&a[i], &sum1, &sum2, &sum3, &sum4);     }     printf("%.2f%%\n%.2f%%\n%.2f%%\n%.2f%%",100.0*sum1/n,100.0*sum2/n,100.0*sum3/n,100.0*sum4/n);     return 0; } 供参考～  类似swap交换连个变量值一个道理，需要传地址过去。

int calculate_sum(int *age,int sum1,int sum2,int sum3,int sum4) 函数传递sum1，sum2，sum3，sum4进去，并不能获得返回值 要想获得返回值，必须是传这些变量的地址进去  好好看看函数的形参和实参部分的说明， 基本每本书都会说的交换两个数的swap函数，什么情况可以交换，什么无效


Question: getch()用法

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

引用 1 楼 寻开心 的回复:实在看不出问题 编译跑了一遍，也没有发现楼主说的现象啊 asdw四个键都能控制着*移动， 不需要按回车键 哈哈，不是代码的问题，我清空了一下数据就可以运行了。

输入函数都会阻塞，你可能需要借助kbhit函数

因为标准输入是行缓冲，需要输入回车才能将输入缓存里的数据刷到内存。不然，还是在输入缓存里～


Question: main.c(31) : fatal error C1004: unexpected end of file found（这是咋回事？）

写代码的时候，好好按照规律缩进排版， 这种不匹配的地方就很容易看出来。 第一个while前面少了一个 }

你的do while是怎么写的？根本不匹配


Question: scanf取入时，实数的类型

哦哦哦，明白了，我是看到实数赋值时默认double所以想确认一下

不是呢，scanf需要制定数据类型的，实数有单精度和双精度类型：%f（单精度）和%lf（双精度）

scanf读取的时候指定是什么类型就是什么类型 %lf  double %f  float 指定的类型，必须和你传入的参数的类型保持一致， 否则就不能读入正确的结果

看你前面指定的数据类型


Question: 点击调试以后不出现蓝条怎么回事

那么程序运行了没有，cmd窗口没出来压根没运行，看你这边没有  蓝条标记当前位置，应该不至于直接跳过去断点结束了，而且dev不会自动关闭cmd

不太懂蓝条  . 同问


Question: 求解

好的，已解决，谢谢你了

新建个工程，main里面不要添加业务代码， 看link是否成功 如果失败，那就是系统或者开发环境的问题


Question: 为什么没有输出所有字符？

#include <stdio.h> int main() {     char c;     printf("请输入:");     c=getchar();     /*     printf("\n输出为:");     putchar(c);     */     //while(c!='\0'){     while(c!='\n'){         //if('a'==getchar()){         if('a'==c){             printf("\n结束\n");             return 0;         }         else{             printf("\n输出为:");             putchar(c);         }         c=getchar();     }     putchar(10);      return 0; } 供参考～  注意c与'\0'比较，那么'\0'是无法从终端输入的。因此这样的判断是没有意义的～所以改成了与'\n'的比较～

谢谢！！！

把'a'==getchar()改为c=='a'或者'a'==c，这里你应该跟c比较，而不是跟getchar，getchar只要你用了就会读走一个，如果你把a的位置输在偶数位甚至不会结束还会把a打引出来，就是因为你这个判度的同时读走了一个字符，比如fadb你判等的时候把f读走，那么不符合进入else会读取a输出a然后下一次循环判等读走d不满足进入else输出b，就会出现这种跳着输出的现象且a不会结束

你调用一次getchar就接受一个，你在while循环里把第一个o接受了，输出的是第二个o，然后d又被while循环条件里的getchar接收了


Question: c语言课设

建议自己设置断点调试

#include<stdio.h> #include<string.h> #include<stdlib.h>  struct  aa{     char name[100];     char phone[100];     char address[100]; } company[100],person[100];  int com_idx, per_idx;  static void input_company(void) {     int i = com_idx;      scanf("%s %s %s", company[i].name,company[i].phone,company[i].address);     com_idx++; }  static void input_person(void) {     int i;      for(i = per_idx;i < 5; i++)         scanf("%s %s %s",person[i].name,person[i].phone,person[i].address);     per_idx += 5; }  static void del_company(void) {     char com_name[32];     int i, j;      printf("请输入公司的名字:\n");     scanf("%s", com_name);      for (i = 0; i < com_idx; i++) {         if (strcmp(com_name, company[i].name))             continue;         for (j = i; j < com_idx-1; j++)             company[j] = company[j+1];         break;     }     if (i < com_idx) {         com_idx--;         return;     }      printf("Not find company name: %s!\n", com_name); }  static void del_person(void) {     char name[32];     int i, j;      printf("请输入个人名字:\n");     scanf("%s", name);      for (i = 0; i < per_idx; i++) {         if (strcmp(name, person[i].name))             continue;         for (j = i; j < per_idx-1; j++)             person[j] = person[j+1];         break;     }     if (i < per_idx) {         per_idx--;         return;     }      printf("Not find name: %s!\n", name); }  static void mod_company(void) {     char com_name[32];     int i;      printf("请输入要修改的公司的名字:\n");     scanf("%s", com_name);      for (i = 0; i < com_idx; i++) {         if (strcmp(com_name, company[i].name))             continue;         break;     }     if (i < com_idx) {         scanf("%s %s", company[i].phone, company[i].address);         return;     }      printf("Not find company name: %s!\n", com_name); }  static void mod_person(void) {     char name[32];     int i;      printf("请输入要修改的个人名字:\n");     scanf("%s", name);      for (i = 0; i < per_idx; i++) {         if (strcmp(name, person[i].name))             continue;         break;     }     if (i < per_idx) {         scanf("%s %s", person[i].phone, person[i].address);         return;     }      printf("Not find name: %s!\n", name); }  static void find_company(void) {     char com_name[32];     int i;      printf("请输入要查询的公司名字:\n");     scanf("%s", com_name);      for (i = 0; i < com_idx; i++) {         if (strcmp(com_name, company[i].name))             continue;         break;     }     if (i < com_idx) {         printf("%s %s %s", company[i].name, company[i].phone, company[i].address);         return;     }      printf("Not find company name: %s!\n", com_name); }  static void find_person(void) {     char name[32];     int i;      printf("请输入要查询个人名字:\n");     scanf("%s", name);      for (i = 0; i < per_idx; i++) {         if (strcmp(name, person[i].name))             continue;         break;     }     if (i < per_idx) {         printf("%s %s %s\n", person[i].name, person[i].phone, person[i].address);         return;     }      printf("Not find name: %s!\n", name); }  int main() {     int opt, choice;     char pwd[] = "12345", input_pwd[8];       while (1) {         printf("管理员or顾客(管理员请按1,顾客按其他)\n");         scanf("%d", &opt);         if (opt == 1) {             printf("请输入密码:\n");             scanf("%s", input_pwd);             if (strcmp(input_pwd, pwd))                 continue;              printf("密码正确");             printf("进入管理员系统\n");             printf("选择 录入(1) 删除(2) 修改(3)\n");             scanf("%d", &opt);             switch (opt) {                 case 1:                     printf("录入公司(1)or个人信息(其他)\n");                     scanf("%d", &choice);                     printf("开始录入:\n");                     if (choice == 1)                         input_company();                     else                         input_person();                     break;                  case 2:                     printf("请输入要删除个人信息(1)还是公司信息(其他)\n");                     scanf("%d", &choice);                     if (choice == 1)                         del_person();                     else                         del_company();                     break;                  case 3:                     printf("修改公司信息(1)or个人信息(其他)\n");                     scanf("%d", &choice);                     if (choice == 1)                         mod_company();                     else                         mod_person();                     break;                  case 4:                     printf("Not support!\n");                     break;             }         } else if (opt == 2) {             printf("欢迎进入顾客系统\n");             printf("选择进入公司or个人(公司按1,个人按其他)\n");             scanf("%d", &choice);             if (choice == 1)                 find_company();             else                 find_person();         } else {             continue;         }     } }   建议楼主对比代码找出自己的问题，楼主的基础还需要强化，写出来的代码问题很多，不一一给指出了，自己对比学习吧

请您试试这个，VS2015 C++调试 #include<stdio.h> #include<string.h> #include<stdlib.h> struct  aa { 	char name[100]; 	char phone[100]; 	char address[100]; } company[100], person[100]; int main() { 	int f, i, h; 	char w, a, o, g, b[100], e[6] = { '1','2','3','4','5','\0' }, c[100], d[100], k[100], l[100], m[100], n[100]; quit: 	printf("管理员or顾客(管理员请按1,顾客按其他)\n"); 	a = getchar(); 	getchar(); 	if (a == '1') 	{ 		printf("请输入密码:\n"); 		gets_s(b); 		if (strcmp(b, e) == 0) 		{ 			printf("密码正确"); 			printf("进入管理员系统\n"); 			printf("选择 录入(1) 删除(2) 修改(3)\n"); 			g = getchar(); 			getchar(); 			switch (g) 			{  			case '1': {printf("录入公司(1)or个人信息(其他)\n"); 				if (getchar() == '1') 				{ 					printf("开始录入:\n"); 					for (i = 0; i<1; i++) 					{ 						scanf("%s %s %s", company[i].name, company[i].phone, company[i].address); 						getchar(); 					} 					printf("录入结束\n"); 					break; 				} 				else 				{ 					for (i = 0; i < 5; i++) 					{ 						scanf("%s %s %s", person[i].name, person[i].phone, person[i].address); 						getchar(); 					} 				} 				break; 			} 			case '2': {printf("请输入要删除个人信息(1)还是公司信息(其他)\n"); 				if (getchar() == '1') 				{ 					getchar(); 					printf("请输入个人名字:\n"); 					gets_s(k); 					for (i = 0; i<2; i++) 					{ 						if (strcmp(k, person[i].name) == 0) 						{ 							strcpy(person[i].name, "000"); 							strcpy(person[i].phone, "000"); 							strcpy(person[i].address, "000"); 						} 						else; 					} 					break; 				} 				else 				{ 					printf("请输入公司的名字:\n"); 					gets_s(l);  					for (i = 0; i<5; i++) 					{ 						if (strcmp(l, company[i].name) == 0) 						{ 							strcpy(company[i].name, "000"); 							strcpy(company[i].phone, "000"); 							strcpy(company[i].address, "000"); 						} 						else; 					} 					break; 				}  			} 			case '3': {printf("修改公司信息(1)or个人信息(其他)\n"); 				if (getchar() == '1') 				{ 					printf("请输入要修改的公司名字:\n"); 					getchar(); 					gets_s(m); 					for (i = 0; i<5; i++) 						if (strcmp(m, company[i].name)==0) 							scanf("%s %s", company[i].phone, company[i].address); 					break; 				} 				else 				{ 					printf("请输入要修改的个人名字:\n"); 					gets_s(n); 					for (i = 0; i<5; i++) 						if (strcmp(n, person[i].name)==0) 							scanf("%s %s", person[i].phone, person[i].address); 				}  				break; 			} 			} 			goto quit; 		} 		else 		{ 			printf("密码错误"); 			goto quit; 		} 	} 	else 	{ 		printf("欢迎进入顾客系统\n"); 		printf("选择进入公司or个人(公司按1,个人按其他)\n"); 		w = getchar(); 		getchar(); 		if (w == '1') 		{ 			printf("欢迎查询公司\n"); 			printf("请输入公司名字:\n"); 			gets_s(c); 			for (i = 0; i<100; i++) 				if (strcmp(c, company[i].name) == 0) 					printf("%s %s\n", company[i].phone, company[i].address); 			goto quit; 		} 		else 		{ 			printf("欢迎查询个人\n"); 			printf("请输入查询人名字\n"); 			gets_s(d); 			for (i = 0; i<100; i++) 				if (strcmp(d, person[i].name) == 0) 					printf("%s %s", person[i].phone, person[i].address); 			goto quit; 		}  	} 	return 0; }

#include<stdio.h> #include<string.h> #include<stdlib.h>  struct  aa{     char name[100];     char phone[100];     char address[100]; } company[100],person[100];  int com_idx, per_idx;  static void input_company(void) {     int i = com_idx;      scanf("%s %s %s", company[i].name,company[i].phone,company[i].address);     com_idx++; }  static void input_person(void) {     int i;      for(i = per_idx;i < 5; i++)         scanf("%s %s %s",person[i].name,person[i].phone,person[i].address);     per_idx += 5; }  static void del_company(void) {     char com_name[32];     int i, j;      printf("请输入公司的名字:\n");     scanf("%s", com_name);      for (i = 0; i < com_idx; i++) {         if (strcmp(com_name, company[i].name))             continue;         for (j = i; j < com_idx-1; j++)             company[j] = company[j+1];         break;     }     if (i < com_idx) {         com_idx--;         return;     }      printf("Not find company name: %s!\n", com_name); }  static void del_person(void) {     char name[32];     int i, j;      printf("请输入个人名字:\n");     scanf("%s", name);      for (i = 0; i < per_idx; i++) {         if (strcmp(name, person[i].name))             continue;         for (j = i; j < per_idx-1; j++)             person[j] = person[j+1];         break;     }     if (i < per_idx) {         per_idx--;         return;     }      printf("Not find name: %s!\n", name); }  static void mod_company(void) {     char com_name[32];     int i;      printf("请输入要修改的公司的名字:\n");     scanf("%s", com_name);      for (i = 0; i < com_idx; i++) {         if (strcmp(com_name, company[i].name))             continue;         break;     }     if (i < com_idx) {         scanf("%s %s", company[i].phone, company[i].address);         return;     }      printf("Not find company name: %s!\n", com_name); }  static void mod_person(void) {     char name[32];     int i;      printf("请输入要修改的个人名字:\n");     scanf("%s", name);      for (i = 0; i < per_idx; i++) {         if (strcmp(name, person[i].name))             continue;         break;     }     if (i < per_idx) {         scanf("%s %s", person[i].phone, person[i].address);         return;     }      printf("Not find name: %s!\n", name); }  static void find_company(void) {     char com_name[32];     int i;      printf("请输入要查询的公司名字:\n");     scanf("%s", com_name);      for (i = 0; i < com_idx; i++) {         if (strcmp(com_name, company[i].name))             continue;         break;     }     if (i < com_idx) {         printf("%s %s %s", company[i].name, company[i].phone, company[i].address);         return;     }      printf("Not find company name: %s!\n", com_name); }  static void find_person(void) {     char name[32];     int i;      printf("请输入要查询个人名字:\n");     scanf("%s", name);      for (i = 0; i < per_idx; i++) {         if (strcmp(name, person[i].name))             continue;         break;     }     if (i < per_idx) {         printf("%s %s %s\n", person[i].name, person[i].phone, person[i].address);         return;     }      printf("Not find name: %s!\n", name); }  int main() {     int opt, choice;     char pwd[] = "12345", input_pwd[8];       while (1) {         printf("管理员or顾客(管理员请按1,顾客按其他)\n");         scanf("%d", &opt);         if (opt == 1) {             printf("请输入密码:\n");             scanf("%s", input_pwd);             if (strcmp(input_pwd, pwd))                 continue;              printf("密码正确");             printf("进入管理员系统\n");             printf("选择 录入(1) 删除(2) 修改(3)\n");             scanf("%d", &opt);             switch (opt) {                 case 1:                     printf("录入公司(1)or个人信息(其他)\n");                     scanf("%d", &choice);                     printf("开始录入:\n");                     if (choice == 1)                         input_company();                     else                         input_person();                     break;                  case 2:                     printf("请输入要删除个人信息(1)还是公司信息(其他)\n");                     scanf("%d", &choice);                     if (choice == 1)                         del_person();                     else                         del_company();                     break;                  case 3:                     printf("修改公司信息(1)or个人信息(其他)\n");                     scanf("%d", &choice);                     if (choice == 1)                         mod_company();                     else                         mod_person();                     break;                  case 4:                     printf("Not support!\n");                     break;             }         } else if (opt == 2) {             printf("欢迎进入顾客系统\n");             printf("选择进入公司or个人(公司按1,个人按其他)\n");             scanf("%d", &choice);             if (choice == 1)                 find_company();             else                 find_person();         } else {             continue;         }     } }  /*    int f,i,h; //char w,a,o,g,b[100],e[5]={'1','2','3','4','5'},c[100],d[100],k[100],l[100],m[100],n[100]; char w,a,o,g,b[100],e[6]={'1','2','3','4','5'},c[100],d[100],k[100],l[100],m[100],n[100]; quit: printf("管理员or顾客(管理员请按1,顾客按其他)\n"); a=getchar(); getchar(); if(a=='1') {printf("请输入密码:\n"); gets(b); if (strcmp(b,e)==0) { printf("密码正确"); printf("进入管理员系统\n"); printf("选择 录入(1) 删除(2) 修改(3)\n"); g=getchar(); getchar(); switch(g) {  case '1':{printf("录入公司(1)or个人信息(其他)\n"); if(getchar()=='1') {printf("开始录入:\n"); for(i=0;i<1;i++) {scanf("%s %s %s",company[i].name,company[i].phone,company[i].address); } printf("录入结束\n"); break; } else {for(i=0;i<5;i++) scanf("%s %s %s",person[i].name,person[i].phone,person[i].address); } break; } case '2':{printf("请输入要删除个人信息(1)还是公司信息(其他)\n"); if(getchar()=='1') {printf("请输入个人名字:\n"); gets(k); for(i=0;i<2;i++) {if(strcmp(k,person[i].name)==0) {strcpy(person[i].name,"000"); strcpy(person[i].phone,"000"); strcpy(person[i].address,"000"); } else ;} break;} else {printf("请输入公司的名字:\n"); gets(l);  for(i=0;i<5;i++) {if(strcmp(l,company[i].name)==0) {strcpy(company[i].name,"000"); strcpy(company[i].phone,"000"); strcpy(company[i].address,"000"); } else; } break;}  } case '3':{printf("修改公司信息(1)or个人信息(其他)\n"); if(getchar()=='1') {printf("请输入要修改的公司名字:\n"); gets(m); for(i=0;i<5;i++) if(strcmp(m,company[i].name)) scanf("%s %s \n",company[i].phone,company[i].address); break; } else {printf("请输入要修改的个人名字:\n");     gets(n);     for(i=0;i<5;i++)         if(strcmp(n,person[i].name))             scanf("%s %s \n",person[i].phone,person[i].address); }  break; } } goto quit; } else {     printf("密码错误");     goto quit; } } else {     printf("欢迎进入顾客系统\n");     printf("选择进入公司or个人(公司按1,个人按其他)\n");     w=getchar();     getchar();     if(w=='1')     {printf("欢迎查询公司\n");         printf("请输入公司名字:\n");         gets(c);         for(i=0;i<100;i++)             if(strcmp(c,company[i].name)==0)                 printf("%s %s\n",company[i].phone,company[i].address);     }     else     {printf("欢迎查询个人\n");         printf("请输入查询人名字\n");         gets(d);         for(i=0;i<100;i++)             if(strcmp(d,person[i].name)==0)                 printf("%s %s\n",person[i].phone,person[i].address);     }  } } */ 供参考～  能用int， %d输入，就不建议用getchar();因为getchar()是字符包括换行符。

person[i].name,person[i].phone,person[i].address);你定义的是数组，这里应该用指针的方法访问地址，试试person[i]->name,person[i]->phone,person[i]->address);其他同理，直接访问变量用.，地址用->，数组等同于指针，除非你取数组中的某个值，不过这里是赋值肯定是首地址，所以要去-》数组名

愁死个人， 你自己在每个scanf后面你配一个c = getchar（）  然后看看就知道是不是了啊 scanf遇到 空格， tab和回车自动过滤去找下一个， 所以对持续用scanf的没有影响 但是scanf和getchar混合，你就必须考虑scanf遗留在键盘缓冲区里面的回车

引用 3 楼 ฅ( ̳• ◡ • ̳)ฅ~的回复:是查询是嗯w=getchar()获取的是回车吗？为什么呢？ 我把goto quit的位置换了，应该没那个问题了，可是录入数据后还是有问题

引用 2 楼 寻开心的回复:scanf之后再getchar返回的也都是回车， 还需要继续过滤掉，否则goto quit后getchar获得都是回车键 是查询是嗯w=getchar()获取的是回车吗？为什么呢？

是查询是嗯w=getchar()获取的是回车吗？为什么呢？

这么长 没仔细看，给个建议，用while代替goto，和你的问题关系不大，只是程序结构上优化一下


Question: c语言有没有替代getch()的函数

不行，接收不了~~~vs应该支持下划线  _getch()  吧

可以有个简单方法，可能效率不咋的，每次接收一个字符，printf("\b*")，回退光标打个*把输入的覆盖掉


Question: 对文件中的数据进行整理

这个不很难呢，建议fgets读取之后用strtok/strtok_r，一步操作就好了。

strlen（buffer）获取字符串的长度 int i=0； int nLen  = strlen(buffer); for ( ; i<nLen; i++ ) if ( '.' == buffer[i]  )break; if ( i==strlen ) { // 没找到. 可能是空行，或者其他的情况     printf("%s", buffer);     fputs(buffer, fpw); } else {     printf("%s", buffer+i+1);     fputs(buffe+i+1, fpw); }

引用 3 楼 寻开心的回复:自己写吧 文件的读写，书上关于文件的那一章一定有 没有可以看网上的：https://www.runoob.com/cprogramming/c-file-io.html    打开要读的文件和要写的文件后 fgets读取一行字符串 从字符串里面找‘.’字符， 把它后面的剩余的部分用puts输出屏幕，fputs写入文件 然后关闭文件  自己尝试写，然后贴上代码的文本，求助 我不知道怎么处理数字和其后面的点

前辈，救救孩子吧

求助各位


Question: C11有函数返回值适配器吗

引用 4 楼 taodm的回复:哦，那，自己实现一个也必然是一个大问题，没这么简单的。 [quote=引用 2 楼 與蘤舊縐 的回复:] [quote=引用 1 楼 taodm 的回复:] 啊，std::tuple啊 老哥C啊[/quote][/quote] 那到不需要搞个万能的，具体情况具体实现还是简单的

啊，std::tuple啊

哦，那，自己实现一个也必然是一个大问题，没这么简单的。 引用 2 楼 與蘤舊縐 的回复:[quote=引用 1 楼 taodm 的回复:] 啊，std::tuple啊 老哥C啊[/quote]

没有

引用 1 楼 taodm 的回复:啊，std::tuple啊 老哥C啊


Question: 求助FOXPRO相关知识，回答有谢

太古老了，30年前的流行趋势

谢谢你的回答

论坛有VFP板块，还有一个梅子论坛，好象国内就这两处了


Question: C语言新手，纯小白，学习困惑求帮助

还要编码的时候一定要注意书写习惯，建议看下林锐的《c/c++ 高效编程指南》

这个需要靠你的积累和不停地学习，实践来探索。多学习别人的，然后开拓自己的视野吧

计算机是实践性很强的科目，不要停留在看书上，看书一定要敲代码！

引用 2 楼 不忘初心20191013 的回复:[quote=引用 1 楼 qq_1457346882的回复:]这个说实话没有什么捷径，编程不是看出来的，是动手敲出来的。之前有一段时间我也是简单的就想想没敲，后来发现不会了。真要给建议那就是不要去看代码，哪怕是例题也跟着敲一遍，完了可以想想有没有简单的方法之类的，逐渐的思路就开拓出来了 谢谢你，我每个示例，习题，例题的代码都上机运行，都是自己在vs2019中敲出来的，可能还是学的时间短吧，头脑中还没行程验证的编程思维方式[/quote]  买本 c primer plus学一下，100经典习题做两遍，第一遍不会就照抄，第二遍就要回忆思考。

引用 1 楼 qq_1457346882的回复:这个说实话没有什么捷径，编程不是看出来的，是动手敲出来的。之前有一段时间我也是简单的就想想没敲，后来发现不会了。真要给建议那就是不要去看代码，哪怕是例题也跟着敲一遍，完了可以想想有没有简单的方法之类的，逐渐的思路就开拓出来了 谢谢你，我每个示例，习题，例题的代码都上机运行，都是自己在vs2019中敲出来的，可能还是学的时间短吧，头脑中还没行程验证的编程思维方式

引用 9 楼 不忘初心20191013 的回复:[quote=引用 3 楼 走好每一步的回复:][quote=引用 2 楼 不忘初心20191013 的回复:] [quote=引用 1 楼 qq_1457346882的回复:]这个说实话没有什么捷径，编程不是看出来的，是动手敲出来的。之前有一段时间我也是简单的就想想没敲，后来发现不会了。真要给建议那就是不要去看代码，哪怕是例题也跟着敲一遍，完了可以想想有没有简单的方法之类的，逐渐的思路就开拓出来了 谢谢你，我每个示例，习题，例题的代码都上机运行，都是自己在vs2019中敲出来的，可能还是学的时间短吧，头脑中还没行程验证的编程思维方式[/quote]  买本 c primer plus学一下，100经典习题做两遍，第一遍不会就照抄，第二遍就要回忆思考。[/quote] 我们现在学的是谭浩强的《C程序设计 第五版》，这个教材怎么样？[/quote]  习题不错，英文不好当入门也可以，但是你需要花时间去改编程习惯。 真正编程的时候，变量名不能是a，b，c这种的

谭浩强的书很经典，但也很老了，推荐cprimerplus ，另外基础学会了可以开始学习数据结构

引用 3 楼 走好每一步的回复:[quote=引用 2 楼 不忘初心20191013 的回复:] [quote=引用 1 楼 qq_1457346882的回复:]这个说实话没有什么捷径，编程不是看出来的，是动手敲出来的。之前有一段时间我也是简单的就想想没敲，后来发现不会了。真要给建议那就是不要去看代码，哪怕是例题也跟着敲一遍，完了可以想想有没有简单的方法之类的，逐渐的思路就开拓出来了 谢谢你，我每个示例，习题，例题的代码都上机运行，都是自己在vs2019中敲出来的，可能还是学的时间短吧，头脑中还没行程验证的编程思维方式[/quote]  买本 c primer plus学一下，100经典习题做两遍，第一遍不会就照抄，第二遍就要回忆思考。[/quote] 我们现在学的是谭浩强的《C程序设计 第五版》，这个教材怎么样？

引用 6 楼 走好每一步的回复:还要编码的时候一定要注意书写习惯，建议看下林锐的《c/c++ 高效编程指南》 我们现在学的是谭浩强的《C程序设计 第五版》，这个教材怎么样？

我们现在学的是谭浩强的《C程序设计 第五版》，这个教材怎么样？


Question: goto quit 中的getchar问题

#include<stdio.h> #include<string.h> #include<stdlib.h>  struct  aa{     char name[100];     char phone[100];     char address[100]; } company[100],person[100];  int com_idx, per_idx;  static void input_company(void) {     int i = com_idx;      scanf("%s %s %s", company[i].name,company[i].phone,company[i].address);     com_idx++; }  static void input_person(void) {     int i;      for(i = per_idx;i < 5; i++)         scanf("%s %s %s",person[i].name,person[i].phone,person[i].address);     per_idx += 5; }  static void del_company(void) {     char com_name[32];     int i, j;      printf("请输入公司的名字:\n");     scanf("%s", com_name);      for (i = 0; i < com_idx; i++) {         if (strcmp(com_name, company[i].name))             continue;         for (j = i; j < com_idx-1; j++)             company[j] = company[j+1];         break;     }     if (i < com_idx) {         com_idx--;         return;     }      printf("Not find company name: %s!\n", com_name); }  static void del_person(void) {     char name[32];     int i, j;      printf("请输入个人名字:\n");     scanf("%s", name);      for (i = 0; i < per_idx; i++) {         if (strcmp(name, person[i].name))             continue;         for (j = i; j < per_idx-1; j++)             person[j] = person[j+1];         break;     }     if (i < per_idx) {         per_idx--;         return;     }      printf("Not find name: %s!\n", name); }  static void mod_company(void) {     char com_name[32];     int i;      printf("请输入要修改的公司的名字:\n");     scanf("%s", com_name);      for (i = 0; i < com_idx; i++) {         if (strcmp(com_name, company[i].name))             continue;         break;     }     if (i < com_idx) {         scanf("%s %s", company[i].phone, company[i].address);         return;     }      printf("Not find company name: %s!\n", com_name); }  static void mod_person(void) {     char name[32];     int i;      printf("请输入要修改的个人名字:\n");     scanf("%s", name);      for (i = 0; i < per_idx; i++) {         if (strcmp(name, person[i].name))             continue;         break;     }     if (i < per_idx) {         scanf("%s %s", person[i].phone, person[i].address);         return;     }      printf("Not find name: %s!\n", name); }  static void find_company(void) {     char com_name[32];     int i;      printf("请输入要查询的公司名字:\n");     scanf("%s", com_name);      for (i = 0; i < com_idx; i++) {         if (strcmp(com_name, company[i].name))             continue;         break;     }     if (i < com_idx) {         printf("%s %s %s", company[i].name, company[i].phone, company[i].address);         return;     }      printf("Not find company name: %s!\n", com_name); }  static void find_person(void) {     char name[32];     int i;      printf("请输入要查询个人名字:\n");     scanf("%s", name);      for (i = 0; i < per_idx; i++) {         if (strcmp(name, person[i].name))             continue;         break;     }     if (i < per_idx) {         printf("%s %s %s\n", person[i].name, person[i].phone, person[i].address);         return;     }      printf("Not find name: %s!\n", name); }  int main() {     int opt, choice;     char pwd[] = "12345", input_pwd[8];       while (1) {         printf("管理员or顾客(管理员请按1,顾客按其他)\n");         scanf("%d", &opt);         if (opt == 1) {             printf("请输入密码:\n");             scanf("%s", input_pwd);             if (strcmp(input_pwd, pwd))                 continue;              printf("密码正确");             printf("进入管理员系统\n");             printf("选择 录入(1) 删除(2) 修改(3)\n");             scanf("%d", &opt);             switch (opt) {                 case 1:                     printf("录入公司(1)or个人信息(其他)\n");                     scanf("%d", &choice);                     printf("开始录入:\n");                     if (choice == 1)                         input_company();                     else                         input_person();                     break;                  case 2:                     printf("请输入要删除个人信息(1)还是公司信息(其他)\n");                     scanf("%d", &choice);                     if (choice == 1)                         del_person();                     else                         del_company();                     break;                  case 3:                     printf("修改公司信息(1)or个人信息(其他)\n");                     scanf("%d", &choice);                     if (choice == 1)                         mod_company();                     else                         mod_person();                     break;                  case 4:                     printf("Not support!\n");                     break;             }         } else if (opt == 2) {             printf("欢迎进入顾客系统\n");             printf("选择进入公司or个人(公司按1,个人按其他)\n");             scanf("%d", &choice);             if (choice == 1)                 find_company();             else                 find_person();         } else {             continue;         }     } }    楼主的代码有问题，不建议用getchar();而是用scanf %d，即用int类型选择  上面的代码没测试，建议楼主试试，有问题再提出来～

前面思想是对的，getchar把回车读走，难你case里也要把读走，你把循环里的也getchar一下试试。练习可以，真正写的话能循环就循环，尽量避免用goto。教我们的老师说容易导致程序崩掉

是上一轮的scanf后遗留在缓冲区的回车没有清理 scanf后getchar获得的是之前的回车键


Question: 帮忙找简单链表代码实现的bug

int main() {    int** p;    *p=(int*)malloc(sizeof(int));    **p=6;    printf("%d",*p);    printf("%d",**p); }   这段代码运行卡顿后什么结果都没有就结束了，为什么

怎么给分。。。。。。。。

引用 10 楼 KID6200 的回复:知道了，但是有一点要问假如head是单指针，p是双指针，且p=&head。我要做引用调用是不是应该iniList(&head)，而传址调用是iniList(LNode** p)？ 而且这两者都能改变*head，即**p。  是的 参数入栈的毕竟是数值，而不是变量本身，所以函数体内部就无法修改这个变量；  传递变量的地址进去，通过地址就可以修改变量本身，而无法修改变量的地址；

定义变量，并在变量里面保存了这个指针。  再取这个变量的地址，就是二级指针。  int **p; 定义了变量， 但是变量的内容是什么呢， 一个（int*）类型的地址。 定义变量可以满足这个条件。  int **pp p = (int ** ) malloc( sizeof(int*)); *p = (int*) malloc(sizeof(int)); 这样也是可以  不同就是： 两个malloc的这个例子里面，  p指向的一个动态内存地址， 动态内存当中保存的是另外一个动态内存的地址 前面的例子当中，p指向的是一个栈变量（局部变量）的地址， 这个栈变量内容是一个动态内存的地址；  你还可以这样 int **p; int  v[] = {1,2,3}; int q = v; p = &q; 这里p指向的是局部变量的地址， 局部变量内容是另外一个数组的地址， 这样**p也是有效的   这三种p都是有效的int **类型，只是一层层指向的内存地址不同而已

引用 8 楼 寻开心的回复:简单的类比， 等号两边各自扔掉一个星  int * p; *p = 3; 这样一眼就能看明白吧。 p是野指针， 直接赋值自然不行。  int **p 一样的情况 p还是野外指针， *p 同样不知道是哪儿去了 定义变量和申请内存有什么区别

引用 5 楼 KID6200 的回复:int main() {    int** p;  *p=(int*)malloc(sizeof(int)); // p是什么还不知道呢， 哪儿来的*p啊     **p=6;    printf("%d",*p);    printf("%d",**p); }   这段代码运行卡顿后什么结果都没有就结束了，为什么  你可以这样  int* q = (int*) malloc(sizeof(int)); p = &q;  ** p = 6;

int** p;这里有问题，p是双指针（指针的指针），你应该先给p申请内存，再给*p申请内存 即 p = (int**)malloc(sizeof(int*)); 再 *p = (int*)malloc(sizeof(int)); 这个和上面说的 LNode* head; iniList(&head); 是不一样的，head是单指针，它的地址&head就是双指针

还有一个问题，你这个add是头添加？NOW申请内存，now.val=val,这传一个字符用.传字符串用-> 不过字符串那你定义就要char val[]定义成数组 下面 now->next=last->next; last->next=now;这是从头加，你的应该是从尾加？个人建议你从尾加代码加个遍历到最后一个，不然你没有接收他的指针，那么下次再用就错了，你就需要每一次传的都必须是最后一个的指针不能错，记最后一个有点烦，所以建议你加个遍历，每次传头指针

楼上已经指出问题所在了。  看到一点小瑕疵，printf("%d", head->next)，这里的next是指针，一般不这么用。如果一定要用的话， printf("%p", head->next)或者printf("%08X\n", p)，这样更直观点。  另外，楼主没有释放内存。如果楼主只是举个例子倒没啥。如果是项目的一部分的话，一定要记得释放内存，这是一个好习惯。

把void iniList(LNode *head) 改成 LNode* iniList() {     LNode* head = (LNode*)malloc(sizeof(LNode));     head->Next = NULL;     return head; } main调用改成 LNode* head = iniList();  或者改成 LNode* iniList(LNode** head) { //双指针     *head = (LNode*)malloc(sizeof(LNode));     (*head)->Next = NULL; } main调用改成 iniList(&head);  原因：方法内部改变指针指向，不影响外部的指针指向。

传一个指针给函数，在函数内部修改指针的地址，函数返回后那个指针的地址不变，起不到效果 要改变那个指针，需要传入指针的指针


Question: 为啥输入后没反应？

scanf中只放你的输入数据类型（%d%lf等）和格式就好了，不要换行 输出格式printf中前面是原封不动要显示的字符加你要替换的变量的数据类型，同样是%d%f这种，然后后面逗号接要替换的变量，一个数据类型对应后面的一个变量，从左往右依次。他会自己去把你后面的变量的值放到你前面的对应位置输出，不要%变量名，这是错的

int main(){ 	int n,m; 	float s; 	do { 		printf("Please enter two numbers n and m:\n"); 		scanf("%d%d",&n,&m); // 这里删除了 是“%d”后面的\n 	} while (n<m); 	s = cp(n,m); printf("%d!/(%d!(%d-%d)!)=%d",n,m,n,m,s);  	return 0; }

把你scanf中的\n去掉

输入4 和1 后，后面的程序似乎没有运行了。。。


Question: stateflow中如果c环境下，如果将数据的最低位输出给布尔类型？

硬件编程很久没接触过了，具体原因不太清楚。 看错误提示，是因为数据传送尺寸错误造成的。

Error: Evaluation of elaborate function on class hdldefaults.Stateflow failed with the error message: hdlcoder:pirudd:StateflowIRGenFailed: Error: HDL code generation from Stateflow failed: Stateflow:Build Failed to eliminate a use of the MATLAB function 'bitget'. For non-simulation builds, uses of unsupported MATLAB functions are eliminated if they do not effect the model outputs.   使用了matlab的函数 bitget后，仿真波形有 但是导出hdl代码的时候报错

引用 4 楼 真相重于对错 的回复:你说的环境我没用过，具体为何错误，不清楚。 多问一句，抱什么错？ 论文的网址在这里 https://www.ixueshu.com/document/b182fab31af30eb10d51a0751563d625318947a18e7f9386.html

引用 4 楼 真相重于对错 的回复:你说的环境我没用过，具体为何错误，不清楚。 多问一句，抱什么错？  Cannot reshape Local Data 'tmp' ([8]) to Output Data 'txd' (scalar) for operator =. Please refer to object 'rshift'. Component:Stateflow | Category:CodererrorOpen Size mismatch errors occurred in shape propagation. Aborting code generation Component:Stateflow | Category:Codererror Size mismatch errors occurred in shape propagation. Aborting code generation   我将txd配置成fixdt(0,1,0)或者布尔类型 好像 都不行

你说的环境我没用过，具体为何错误，不清楚。 多问一句，抱什么错？

因为看一篇论文里面表述的是如下写法  txd=tmp%2; tmp=tmp>>1;  但是我按上面这个写法好像也不对，也是报错  不知道是哪个地方配置的问题

引用 1 楼 真相重于对错 的回复:移位并不能获得最低位，移位相当于除2 获取最低位 用 &0x1; 我在simulink的stateflow里面的一个状态中如下表述总是不对  条件转移是 tmp=datain  都定位为无符号的uint8，txd是设成布尔的二进制输出  在其中一个状态里面写： txd=tmp & 0x01; tmp=tmp>>1;  其中tmp在stateflow里面我配置成local类型的局部变量  运行仿真总提示 不能reshapeloca的数据tmp到输出的txd

移位并不能获得最低位，移位相当于除2 获取最低位 用 &0x1;


Question: C语言小白求助！！

getchar()是从终端接收一个字符，!= '\n'是指接收到的这个字符与'\n'比较。

getchar()是获取一个字符，!=\n就是从缓存区获取的这个字符不是换行符，unix，linux下一般都是相当于你的回车键，window和mac用\r或\r\n     这两个里\r是回车\n是换行 '\r'是回车，前者使光标到行首，（carriage return） '\n'是换行，后者使光标下移一格，（line feed）


Question: 运行超时问题

float的比较应该用范围方式if(y<0.000001||y>-0.000001),这个精度由你自己定，如果还是不行那就是循环了，看你的数据能不能达到你break的条件

不要用float和0比较，要避免，你的循环退出条件为y==0因为精度问题，没有返回为0的，所以不能退出循环,可以在你的func中改一下返回值


Question: 问一个C语言关于文件的题目

写错写错，是if(strcmp(结构体数组名[i].出版年份,输入的年份)==0)

上面有点错误，如果是字符串，那就if(strcmp(结构体数组名[i].出版年份,输入的年份))，把找出来的结构体数组元素用一个新的结构体数组存放，最后写入新文件就好了。

把原文件的东西读进系统用结构体数组保存，再定义一个变量存放输入的年份，然后用循环来匹配出相应年份出版的书本。如果循环控制变量是i，年份是整型变量，那就if(结构体数组名[i].出版年份==输入的年份)，如果是字符串，那就if(strcmp(结构体数组名[i],输入的年份))

求下源代码 1111111

定义好你的结构体，然后按格式获取你book里的信息存到数组就好了啊，然后关闭这个文件打开另一个，循环判断你结构体数组里年份的那个变量值，满足条件就把结构体按格式写道stack里就好了啊


Question: C语言小白求助!

不但多一个a，而且还会多一个e 正像楼上朋友说的，if else语句最好还是加上大括号吧 	for (ps = str1; *ps != '\0'; ps++) 	{ 		if (*ps == 'a' || *ps == 'e') 			putchar(*ps); 		else 		{ 			(*ps)--; 			putchar(*ps); 		} 	} VS2015 C++调试结果

引用 8 楼 user-4 的回复：[quote=引用 6 楼 weixin_45906870 的回复:] [quote=引用 2 楼 寻开心 的回复：] if (*ps=='a'||*ps=='e')             putchar(*ps);         else             (*ps)--，putchar(*ps);  这样也可以， 把分号改逗号 第二个问题怎么解释呢？[/quote] printf("%c",i%3?str2[i] : '*'); 相当于  if(i%3 != 0) printf("%c",str2[i]);   else  printf("%c" ,'*'); i%3?str2[i] : '*'   这是个三目运算符，    ？前面的表达式非0则取：之前的值，反之取：后面的值，针对你这个而言就是i%3如果不等于0，就取str2[i] ，反之取'*'[/quote]非常感谢您！帮我大忙了！

引用 6 楼 weixin_45906870 的回复:[quote=引用 2 楼 寻开心 的回复：] if (*ps=='a'||*ps=='e')             putchar(*ps);         else             (*ps)--，putchar(*ps);  这样也可以， 把分号改逗号 第二个问题怎么解释呢？[/quote] printf("%c",i%3?str2[i] : '*'); 相当于  if(i%3 != 0) printf("%c",str2[i]);   else  printf("%c" ,'*'); i%3?str2[i] : '*'   这是个三目运算符，    ？前面的表达式非0则取：之前的值，反之取：后面的值，针对你这个而言就是i%3如果不等于0，就取str2[i] ，反之取'*'

引用 2 楼 寻开心 的回复：if (*ps=='a'||*ps=='e')             putchar(*ps);         else             (*ps)--，putchar(*ps);  这样也可以， 把分号改逗号 第二个问题怎么解释呢？

引用 1 楼 qq_1457346882 的回复：又是省略大括号的问题，  if (*ps=='a'||*ps=='e')             putchar(*ps);         else             (*ps)--;         putchar(*ps); 等价于  if (*ps=='a'||*ps=='e'){             putchar(*ps); }         else{             (*ps)--; }         putchar(*ps); 也就是说你最后的putchar不管上面判断的怎么样都会输出一次，加上你if的，就是两次ae，不加大括号相当于对应的语句只有下面的一句已。一个大括号麻烦不到哪去，掌握不好就都加上，后面查错也好查那第二个问题怎么解释呢？

那第二个问题怎么解释呢？


Question: 横线上应该填什么语句。。。

引用 2 楼 m0_46132054 的回复:[quote=引用 1 楼 寻开心 的回复：]这个最基础的东西必须要自己写啊 看书啊，看书啊，看书啊 重要事情说三遍我这样写了：a=%c，b=%%，c=%cla [/quote] 输入输出格式都差不多  可以参考下输入格式，有条件最好拿电脑跑一下代码

看看printf 的输出格式

引用 1 楼 寻开心 的回复：这个最基础的东西必须要自己写啊 看书啊，看书啊，看书啊 重要事情说三遍我这样写了：a=%c，b=%%，c=%cla

这个最基础的东西必须要自己写啊 看书啊，看书啊，看书啊 重要事情说三遍


Question: 这是怎么回事？

用VS2015就可以看出问题出在哪里  所以代码修改为 #include <stdio.h>  int main() { 	char c;//--------类型改为char-------- 	char enter; 	printf("请输入:"); 	c = getchar(); 	enter = getchar();//-------屏蔽回车按键------------- 	printf("输出为:"); 	printf("%c", c); 	putchar(c); 	while (c>0) { 		printf("\n请输入:"); 		c = getchar(); 		enter = getchar();//--------屏蔽回车按键--------- 		printf("输出为:"); 		printf("%c", c);//--------%s改为%c，添加c-------- 		putchar(c); 	} 	return 0; } VS2015 C++环境调试

除了printf（“%s”）这里该指定参数没有指定之外，没有明显的问题  你的编译器是什么？ 也许是编译器在printf里面看到了%s， 随便从堆栈找了个地址就当中字符串输出了


Question: 关于C语言中puts函数的问题

十分感谢

局部变量的之间的地址关系，c/c++标准没有定义， 是编译器自己的行为， 不能把你发现的结果作为所有的编译器通用行为 它只对你所有的编译器和所在的系统环境有效，换一个不一定对

printf("%p : %p %p", sida_a, dont, side_b); 你看看三个指针，他们的关系，到底哪一个地址高，哪个一个地址低  函数里面的局部变量，都是栈内存， 在你用的这个编译器里面，地址向下增长的.

就是把字符数组当字符串使用的时候， 必须在数组里面，人工的填写一个'\0'字符放到最后，即：  char dont[] = {'W','O','W','!' ,'\0'};  而 char side_a[] = "Side A"; 这种定义，因为字符串自带'\0'字符在尾巴，就无需人工补这个0字符了

因为它是数组， 里面没有一个 ‘\0’这样的一个值 把它当做字符串输出的时候， puts会在数组里面一直输出，直到遇到了'\0'字符为止 显然，在输出的过程当中越界了， 跑到了side_a数组里面还在继续输出，直到遇到了“Side A”这个字符串结尾的'\0'字符才结束


Question: c语言小白求解，向各位大神请教。写一个求解函数，编译没问题，答案不对呀

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

按要求格式化输入就好

第一，scanf输入数据格式要一致，第二，你的测试数据判别式不能小于0

注意scanf输入格式，代码中写了逗号过或空格，那控制台也要输入逗号或空格，还有建议你定义变量的时候尽量做到见名之意，写好注释，养成好习惯

可能是逗号中英文不对应，要区分中英文逗号。

scanf("%f,%f,%f",&a,&b,&c); 注意输入格式要和scanf中的保持一致，尤其是逗号的中英文要和scanf中的保持一致。

VS2015 C++环境调试没问题  原因可能就是像楼上朋友说的，输入的时候要注意有逗号，就是上图红线内容 请参考《scanf()函数的用法》 希望能够帮到你！

#include <stdio.h> #include "math.h" int main() {     float a,b,c,d,x1,x2,q;     scanf("%f,%f,%f",&a,&b,&c);     printf("%f, %f, %f\n", a, b, c);     d=b*b-4*a*c;     if (d<0) {         printf("No answer!");         return -1;     }      q=sqrt(d);     x1=(-b+q)/(2*a);     x2=(-b-q)/(2*a);     printf("x1=%.2f,x2=%.2f",x1,x2);     return 0; }   注意return -1;    引用 1 楼 寻开心 的回复:#include <stdio.h> #include "math.h" int main() {     float a,b,c,d,x1,x2,q;     scanf("%f,%f,%f",&a,&b,&c);     printf("%g, %g, %g\n", a, b, c);     d=b*b-4*a*c;     if (d<0) {     	printf("No answer!"); 	} 	q=sqrt(d);     x1=(-b+q)/(2*a);     x2=(-b-q)/(2*a);     printf("x1=%.2f,x2=%.2f",x1,x2);     return 0; }  其实没有改什么 严重怀疑你的输入不对，  一定是1,4,4这样的输入， 数字之间必须有逗号，因为你的scanf格式指定要求的 输入后，增加了一行输出，就是用来比对，看你是否真的正确的输入了数据

scanf("%f,%f,%f",&a,&b,&c); 估计如一楼所说，你输入的格式用逗号隔开，你的输入也需要一致，用逗号隔开


Question: windows的换行符

ide的输入输出窗口是ide自己做的一个模拟器， 它的效果未必和exe执行的效果一致的， 毕竟不是同一个东西 比如，再XCode的模拟窗口里面，用输入法就不可用，输入汉字都变成了拼音，而做成发布执行程序就可以输入汉字  c语言就要用c语言的函数规则来理解， 跨到另外一个语言是有助于更好的理解，但是他们毕竟不同，还要注意差异的地方  输入输出在绝大部分程序当中都是重头戏（界面也是输入输出的一种），是要好好研究的， 否则输入都不对，何谈后面的算法执行呢。 初学的人往往都会犯的错误就是不检验输入数据是否正确就开始执行后面的操作，还老抱怨算法不对。  Go语言不太熟悉， 只是拿来做个比喻，希望有帮助吧

引用 8 楼 寻开心的回复:类似输入一个整数后面再回车，而后再输入一个整数的这种情况 Go语言是scanfln函数两次，或者是第一次scanf的时候格式指定尾巴带一个\n,  "%d\n",否则下次的scanf调用遇到它会直接返回  这个机制和c的scanf是不一样的， c里面会把回车当做分隔符，自动过滤掉 我查过这个，也在go论坛问过，但不一定对应最新版本，再举个例子吧，如果用ide编译运行，在ide的输入窗口中输入(这不是终端，编译指令是一致的，和在cmd中运行是一样的，只是换了个地方输入)，可以达到c语言的效果，这在win10和win7下都一样，这一点同样难解释，另外我自学时看到视频里老师的结果都与此相悖，他的结果都是和C一致，当然也是在cmd中的，win7下。另外我知道您讲的在后面加\n的操作，但这样写，当在同一行用空格分隔两个语句输入时，第二段会丢失一个字符，这我想虽然正常讲不该这么输入，但还是需要避免的。感谢您的耐心回答

引用 6 楼 寻开心的回复:go语言的语法规则和c语言的语法规则不是你说差不多就差不多的啊 看看它的函数定义吧  再说即便都是c语言，在不同的编译器，不同的版本下函数的实现代码都有可能不相同的 c语言只定义了一些标准， 并没有限定编译器必须如何实现，是有可能造成不同的效果的 大佬，他编译靠自己，独此一家，别无分号，而且我试过把编译好的exe文件复制过去，您别纠结语言啦，这不重要，我想您这意思应该是这两系统的换行符并没有差别，那我去翻翻源码吧，可能实现方式涉及到别的东西吧

引用 3 楼 寻开心的回复:键盘输入什么内容，是键盘驱动程序返回给系统的，系统通过标准的接口来获取输入的内容 scanf你可以看看函数的说明，键盘只有敲入回车的时候，scanf才开始启动接收并处理数据 比如，你scanf指定输入1个整数， 你输入了 1  3   5  7 然后一个回车 scanf做了什么呢， 他把第一个整数提取走了， 后面的字符都给扔了吗？ 并没有， 它是留给下一次的输入使用了 后面你有scanf的代码，还是可以继续从后面获取3，5，7等数据的 所以你的解释扔掉\n是错误的理解  键盘输入的内容是放到一个缓冲区里面的， 叫做键盘缓冲， 它并不是遇到了\n字符，后面就没有数据或者清理了前面的数据 scanf从键盘缓冲提取这些输入的字符，然后来根据指定的格式来提取数据，默认遇到空格，tab和回车都是（除非是%c的格式读取）当做数据的分隔符来处理的，或忽略这些字符找下一个匹配的数据的。 如果你只取一个整数，那么取完数字遇到了分隔符（空格 tab和回车）会如何？ scanf什么都不干，返回了，把分隔符依然留在键盘缓冲区了。 等待下一次scanf发生的时候，它遇到了这些分隔符，它会跳过去找下一个非分隔符的数据的。这就是你感觉第二个数据获取的时候前面的回车被放弃的原因。  getchar是键盘缓冲区里面是什么都直接提取一个返回， 不存在分隔符的说法， 所以能直接获得 要理解scanf的机制就好了  你说的win10和win7的区别，没有看明白你的意思 。  win10和 win7下scanf表现有什么不同了 我试过别的终端，win10下都是这样的

引用 3 楼 寻开心的回复:键盘输入什么内容，是键盘驱动程序返回给系统的，系统通过标准的接口来获取输入的内容 scanf你可以看看函数的说明，键盘只有敲入回车的时候，scanf才开始启动接收并处理数据 比如，你scanf指定输入1个整数， 你输入了 1  3   5  7 然后一个回车 scanf做了什么呢， 他把第一个整数提取走了， 后面的字符都给扔了吗？ 并没有， 它是留给下一次的输入使用了 后面你有scanf的代码，还是可以继续从后面获取3，5，7等数据的 所以你的解释扔掉\n是错误的理解  键盘输入的内容是放到一个缓冲区里面的， 叫做键盘缓冲， 它并不是遇到了\n字符，后面就没有数据或者清理了前面的数据 scanf从键盘缓冲提取这些输入的字符，然后来根据指定的格式来提取数据，默认遇到空格，tab和回车都是（除非是%c的格式读取）当做数据的分隔符来处理的，或忽略这些字符找下一个匹配的数据的。 如果你只取一个整数，那么取完数字遇到了分隔符（空格 tab和回车）会如何？ scanf什么都不干，返回了，把分隔符依然留在键盘缓冲区了。 等待下一次scanf发生的时候，它遇到了这些分隔符，它会跳过去找下一个非分隔符的数据的。这就是你感觉第二个数据获取的时候前面的回车被放弃的原因。  getchar是键盘缓冲区里面是什么都直接提取一个返回， 不存在分隔符的说法， 所以能直接获得 要理解scanf的机制就好了  你说的win10和win7的区别，没有看明白你的意思 。  win10和 win7下scanf表现有什么不同了 我明白您的意思，所谓扔掉了是表述问题，我太不专业，我的意思是同样的程序，同样的语言版本，那么排除程序问题，在win10下fmt.Scanf，(go语言怎么实现的我不清楚，应该和C大致相同，但这不是重点)，问题是win7下和C语言的效果完全相同，win10下第一个fmt.Scanf接收回车前面输入的，第二个接收\n，所以想来想去是不是win10和win7下的回车或者说换行符不太一样，还是说在cmd中输入不太一样

引用 1 楼 寻开心的回复:不用纠结，windows键盘输入就没有\r产生，就是\n  在文本文件里面才牵涉到这个\r\n的说法，有的这个叫做dos文本格式（linux系统下文本都是\n换行的） 我之前查了下确实这样，但想半天就是想不通win10和win7怎么就不一样了，既然都只有\n，那最多就是这个函数设计的不太好，也不至于两边不一样吧


Question: 请教一个汇编语言的问题

除法  eax保留商2， edx保留余数  1E 乘法  相当于1E*1E ,  eax保留低位,因为没有仅为，eax = 1E*1E = 384   没学过汇编，你跑这儿show什么汇编代码啊


Question: 对称矩阵排列问题，请各位麻烦给个编程实现的思路或者伪代码，谢谢！！

引用 9 楼 寻开心 的回复:如果需要R，就自己合成吧。 原来想简单的依靠交换行列来实现， 看来是不行 在MatrixSort代码当中，每个步骤下都是生成了一个r， 用这个r每次新的在左侧，老的r在右侧， 做矩阵乘法吧  好的，谢谢您的解答和代码！

引用 6 楼 寻开心 的回复:#include <stdio.h> #include <memory.h>  #define LEN 6  void MatrixPrint(int (*m)[LEN]); void MatrixMul(int (*a)[LEN], int (*b)[LEN], int (*c)[LEN])  { 	int t[LEN][LEN] = {0};  	int i, j, k; 	for (i=0; i<LEN;i++) {     	for ( j=0; j<LEN; j++ ) {     		for ( k=0; k<LEN; k++)       		  t[i][j]  += a[i][k]*b[k][j]; 		} 	} 	memcpy(c, t, LEN*LEN*sizeof(int)); }  void MatrixNormal(int (*m)[LEN] ) { 	memset(m, 0, LEN*LEN*sizeof(int)); 	for (int i=0; i<LEN; i++) m[i][i] = 1; }  void MatrixChange(int (*m)[LEN], int i, int j) { 	int t; 	for (int k=0; k<LEN; k++)  	     t=m[i][k], m[i][k]=m[j][k], m[j][k]=t; }   void MatrixSort(int(*m)[LEN]) { 	int d[LEN]={0}; 	int i, j, k; 	int r[LEN][LEN]; 	for ( i=0; i<LEN; i++ ) {  		d[i]=m[i][i]; 	} 	for ( i=0; i<LEN-1; i++) { 		for (j=i+1; j<LEN; j++) { 			if ( d[i]>d[j] ) { 				int t=d[i]; 				d[i]=d[j]; 				d[j]= t; 				MatrixNormal(r); 				MatrixChange(r, i, j); 				MatrixMul(r, m, m); 				MatrixMul(m, r, m); 			} 		} 	} 	for ( i=0; i<LEN; i++) 		printf("%d ", d[i]); 	printf("\n"); }  void MatrixPrint(int (*m)[LEN]) { 	for (int i=0; i<LEN;i++) {     	for ( int j=0; j<LEN; j++ ) {     			printf("%3d", m[i][j]);     		 		} 		printf("\n"); 	} } int main( void ) {     /*int a[LEN][LEN] = { 3,1,8,10, 1, 2,25,37, 8,25,5,70, 10,37,70,4};     */ 	int a[LEN][LEN] = {6,2,4,8,14,22, \ 		2,1,6,10,16,24, \ 		4,6,3,12,18,26, \ 		8,10,12,2,20,28, \ 		14,16,18,20,5,30, \ 		22,24,26,28,30,8}; 		 	int r[LEN][LEN]; 	MatrixSort(a);     MatrixPrint(a);	 	return 0; }   先不合成R了， 主元排序的时候，同步更新矩阵。 最后我还是要把那个R阵求出来的，用于还原回去，可以按照您的算法实现吧？

引用 6 楼 寻开心 的回复:#include <stdio.h> #include <memory.h>  #define LEN 6  void MatrixPrint(int (*m)[LEN]); void MatrixMul(int (*a)[LEN], int (*b)[LEN], int (*c)[LEN])  { 	int t[LEN][LEN] = {0};  	int i, j, k; 	for (i=0; i<LEN;i++) {     	for ( j=0; j<LEN; j++ ) {     		for ( k=0; k<LEN; k++)       		  t[i][j]  += a[i][k]*b[k][j]; 		} 	} 	memcpy(c, t, LEN*LEN*sizeof(int)); }  void MatrixNormal(int (*m)[LEN] ) { 	memset(m, 0, LEN*LEN*sizeof(int)); 	for (int i=0; i<LEN; i++) m[i][i] = 1; }  void MatrixChange(int (*m)[LEN], int i, int j) { 	int t; 	for (int k=0; k<LEN; k++)  	     t=m[i][k], m[i][k]=m[j][k], m[j][k]=t; }   void MatrixSort(int(*m)[LEN]) { 	int d[LEN]={0}; 	int i, j, k; 	int r[LEN][LEN]; 	for ( i=0; i<LEN; i++ ) {  		d[i]=m[i][i]; 	} 	for ( i=0; i<LEN-1; i++) { 		for (j=i+1; j<LEN; j++) { 			if ( d[i]>d[j] ) { 				int t=d[i]; 				d[i]=d[j]; 				d[j]= t; 				MatrixNormal(r); 				MatrixChange(r, i, j); 				MatrixMul(r, m, m); 				MatrixMul(m, r, m); 			} 		} 	} 	for ( i=0; i<LEN; i++) 		printf("%d ", d[i]); 	printf("\n"); }  void MatrixPrint(int (*m)[LEN]) { 	for (int i=0; i<LEN;i++) {     	for ( int j=0; j<LEN; j++ ) {     			printf("%3d", m[i][j]);     		 		} 		printf("\n"); 	} } int main( void ) {     /*int a[LEN][LEN] = { 3,1,8,10, 1, 2,25,37, 8,25,5,70, 10,37,70,4};     */ 	int a[LEN][LEN] = {6,2,4,8,14,22, \ 		2,1,6,10,16,24, \ 		4,6,3,12,18,26, \ 		8,10,12,2,20,28, \ 		14,16,18,20,5,30, \ 		22,24,26,28,30,8}; 		 	int r[LEN][LEN]; 	MatrixSort(a);     MatrixPrint(a);	 	return 0; }   先不合成R了， 主元排序的时候，同步更新矩阵。 好的，大概我看懂您的算法了，十分感谢，我要是对一维数组操作的时候，就按照上面的算法相应的改一下就可以了吧？ 比如读进去的一维数组是这样的	int a[36] = {6,2,4,8,14,22,  		                                                   2,1,6,10,16,24,  		                                                   4,6,3,12,18,26,  		                                                   8,10,12,2,20,28,  		                                                  14,16,18,20,5,30,  		                                                  22,24,26,28,30,8};

引用 1 楼 寻开心 的回复:0 1 0 0  1 0 0 0 0 0 0 1 0 0 1 0 用这个矩阵作为R去就做乘法就可以了， R在左边乘法，完成了行交换， 再在右侧乘完成了列交换  算法无非是根据主对角线元素排序的结果构造这个R矩阵 初始化R为单位矩阵 对主对角线元素用冒泡方法排序， 在这个排序过程当中要交换下标i，j两个位置的元素的时候，同步对R矩阵实施行交换 主对角线排列完毕， R也就构造完毕了  查了下矩阵变换的理论，变换后的矩阵这样实现是不是合理一些：A1 = Rn' * A * Rn ，(Rn'为Rn转置)，因为一般Rn都是正交阵，Rn^-1=Rn'

引用 2 楼 寻开心 的回复:#include <stdio.h> #include <memory.h> void MatrixMul(int (*a)[4], int (*b)[4], int (*c)[4])  { 	int t[4][4] = {0};  	int i, j, k; 	for (i=0; i<4;i++) {     	for ( j=0; j<4; j++ ) {     		for ( k=0; k<4; k++)       		  t[i][j]  += a[i][k]*b[k][j]; 		} 	} 	memcpy(c, t, 4*4*sizeof(int)); }  void MatrixChange(int (*m)[4], int i, int j) { 	int t; 	for (int k=0; k<4; k++) t=m[k][i], m[k][i]=m[k][j], m[k][j]=t; }  void MatrixSort(int(*m)[4], int(*r)[4]) { 	int d[4]; 	int i, j, k; 	memset(r, 0, 4*4*sizeof(int)); 	for ( i=0; i<4; i++ ) {  		d[i]=m[i][i]; 		r[i][i]=1; 	} 	for ( i=0; i<3; i++)  		for (j=i+1; j<4; j++) { 			if ( d[i]>d[j] ) { 				int t=d[i]; 				d[i]=d[j]; 				d[j]= t; 				MatrixChange(r, i, j); 			} 		} }  void MatrixPrint(int (*m)[4]) { 	for (int i=0; i<4;i++) {     	for ( int j=0; j<4; j++ ) {     			printf("%3d", m[i][j]);     		 		} 		printf("\n"); 	} } int main( void ) {     int a[4][4] = { 3,1,8,10, 1, 2,25,37, 8,25,5,70, 10,37,70,4};     int r[4][4]; 	MatrixSort(a, r); 	MatrixPrint(r); 	MatrixMul(r,a, a);     MatrixMul(a,r,a);     MatrixPrint(a);	 	return 0; }  感谢楼主码了代码，但是我重新测试6x6的对称阵，比如这个矩阵Q1=[6,2,4,8,14,22;                                                                                2,1,6,10,16,24;                                                                                4,6,3,12,18,26;                                                                                8,10,12,2,20,28;                                                                                14,16,18,20,5,30;                                                                                22,24,26,28,30,8;] 代码运行结果是不对的，我在想是不是每次冒泡产生交换时，都要交换N阶单位矩阵对应的行生成当前一个初等变换阵，然后最后得到Rn=R1*R2*...*Rn ???希望和楼主讨论一下怎么才能实现这种矩阵排序，谢谢

引用 1 楼 寻开心 的回复:0 1 0 0  1 0 0 0 0 0 0 1 0 0 1 0 用这个矩阵作为R去就做乘法就可以了， R在左边乘法，完成了行交换， 再在右侧乘完成了列交换  算法无非是根据主对角线元素排序的结果构造这个R矩阵 初始化R为单位矩阵 对主对角线元素用冒泡方法排序， 在这个排序过程当中要交换下标i，j两个位置的元素的时候，同步对R矩阵实施行交换 主对角线排列完毕， R也就构造完毕了  这个算法理论上是这样构造初等矩阵R，但是对于多维的对称方阵进行冒泡排序，然后根据冒泡过程中，只要发生交换就要对单位阵行交换，是不是应该每次交换就生成一个Ri，最终的Rn=R1*R2*...*Rn，变换后的矩阵A1=Rn*A*Rn ?


Question: 关于malloc函数的问题

好的，谢谢大佬！我明白了。

malloc(sizeof(struct Node)) 和  (struct Node*)malloc(sizeof(struct Node) malloc函数的返回值是void *你用别的类型的指针去接收，如果编译器允许这种，会自己给你转化的话是不会出问题的，但是如果不会给你转就会报错，错误大意就是把什么类型赋给什么类型是出错，不允许之类的 (struct Node*)malloc(sizeof(struct Node)中前面的(struct Node*)是强制转换，它是把你申请好的先强制转换成你所需要的类型，这样再进行“赋值”操作的时候类型一致，就不会报错了 所以为了避免麻烦，还是建议直接用后面的方式，比较好

因为malloc返回的是void*


Question: c语言求助

引用 5 楼 與蘤舊縐的回复:这个习惯建议改一下，有的语言不支持把大括号放到下一行的写法 java好像就是不能把大括号放下一行我这样写是c老师教的，说是好看点

引用 4 楼 user-3的回复:else if 懂了谢谢大佬else后面不能加括号的

懂了谢谢大佬else后面不能加括号的

else(a < number) 改成 else if(a < number)

这个习惯建议改一下，有的语言不支持把大括号放到下一行的写法

else if

do{  }

提示我加分号，可是加前面的就变成空语句了

#include<stdio.h> #include<stdlib.h> #include<time.h> int main() { 	srand(time(0)); 	int number = rand() % 100 + 1;//游戏需要的数为1到100，所以需要加一 	int count = 0; 	int a; 	do 	{ 		printf("请输入你下注的号码："); 		scanf_s("%d", &a); 		count++; 		if (a > number) 		{ 			printf("您输入的数比中奖数大\n"); 		} 		else(a < number) 		{ 			printf("您输入的数比中奖数小\n"); 		} 	} while (a != number); 	printf("恭喜你已经中奖了,您用了%d的人民币就中奖了",count); 	return 0; }


Question: 关于\0截断的问题

作为数组，无论是不是\0都不会截断，存放在那里的数据，怎么会少呢 只有 strcpy printf strlen sscanf 这些函数操作的时候，会


Question: c语言

您的这个代码主要看do while循环 1第一次循环a=-1, b=0，此时执行 n = m + n; 	      a += 2,b++; 执行之后，a=1,b=1，n=2，m=1，此时while循环条件成立，进行第二次循环； 2第二次循环，此时执行 m = 2 * n; 	     b++; 执行之后，a=1,b=2，n=2，m=4，此时while循环条件不成立，循环结束； 在VS2015 C++环境下

想看图片上的代码，但是我脖子歪不到90°，没辙了

打字会不会？打开 https://tool.lu/coderunner/ 选择c语言，然后把你的程序输入进去，点运行。


Question: C语言

m的倍数，1倍、2倍、3倍的往上遍历，比k++要效率很多

懂了，谢谢大佬的指点

a和b的最小公倍数是m m显然是a的倍数，也是b的倍数 对于a来说， m是a， 2a，3a， ..... ka 当中的一个， k<=b 所以，从a开始判断是不是b的倍数，不是就看2a是不是，。。。。。   加上一个a和b大小的判断，用大的来做这个操作循环次数少一点儿


Question: C语言文件处理

假如路正确的话 字符串就是你输入的双引号中间的那个部分， 输入的时候不要带上双引号 有双引号那是c语言里面的语法表达，字符串本身并没有两端的那个双引号 而且那个\\也是不需要的， 那也是c语法里面的转义字符带来的，也可以用/符号来取代 你可以用c:/user/administrator/desktop/1.txt 这样的字样从键盘输入

你输入的时候，不要带上两边的双引号


Question: 萌新提问

printf少了，  问题楼上说了都对，我就是好奇想来问问，现在只有一句语句体不加{}是书上的，声明写在main函数里是书上的。现在的新书又出了main函数返回值是void不用return了嘛

先说你的程序，问题楼上的朋友已经说了，printf()函数中少一个逗号，修改之后 VS2015 C++环境输出为  我觉得你的意思是想问超出该类型表示范围时应该怎么处理，但是int的长度是32位，所以你的代码应该改为 #include <stdio.h>  int main() { 	short a, b;//-------int改为short-------- 	a = 32767; 	b = a + 1; 	printf("%d,%d\n", a, b);//--------添加逗号-------- 	return 0; }  应为short类型的长度是16位，因此此时的输出为  主要原因是a的值32767，其二进制表示形式为0x0111 1111 1111 1111，b的值是0x1000 0000 0000 0000，因为short是有符号的，其范围是-32768~32767，0x1000 0000 0000 0000表示-32768

printf("%d,%d\n" a, b); 引号后面少一个逗号 改成 printf("%d,%d\n",a, b);

int main() {      .....      return 0; } 这才是标准的结构。 不要void main（）  printf("%d,%d\n", a, b); 这里a的前面少了一个逗号


Question: 如何理解链表的游标实现

是的，理解正确

谢谢您的回复 我想了想，总结了一下，麻烦您看一下我说的对不对？感谢  数组下标其实也就是代表着一个结构体的地址，而NodeArray[i].next 就可以看做存储着下个结构体的地址。虽然数组在内存中是连续的，但是用游标实现的链表却在内存中不连续，每个元素之间是由结构体中的next来连接的。

我的理解是就是用数组实现的链表：实现的链表实际上并不是真正的动态内存组成的，没有malloc 和 free的内存操作 而是用事先定义的一个大数组来保存数据，数组元素是一个结构， 其中一个属性是next，指向下一个元素的数组下标 struct Node {      struct ata {      } data；     int next； } NodeArray[1000]； 大概就这个一个结构， 初始化next都是-1， 表示空的。 因为数组的下标从0开始  链表就是用NodeArray[i].next --> NodeArray[j].next --> NodeArray[k] ....... 这里的next就是游标，不是指针  这个更适合一些没有指针的语言来使用。 c使用也可以， 没有内存的分配和释放，效率也高一些；限制就是数组的大小不能改了。


Question: 请问char*与unsigned char*传参不同会有问题吗

你传的什么数据过去，用的时候记得用相应的指针去取就好，中间传递过程可以不用考虑指针类型

没有影响，同一平台上，指针类型的大小相同，不会发生截断造成地址变动丢失数据，更不会造成数据变更

不会，只是会影响到指针类型，不会动到里面的数据的


Question: C语言文件处理出现问题

c定义成int类型，定义成char无法跟EOF比较。楼主输入了a和回车吧


Question: 请问一下这个题该怎么做？一个小白，大神可否有完整代码，指点迷津

就是存放位置不同啊，用数组或链表去存数据，数组的话要定的大点，不然添加的话会越界 实现的话你要分别去定义那几个操作函数执行操作，然后main函数把数组或链表初始化之后就直接一个死循环，while（1）//这边建议也写一个运行函数run，menu都单出来了不差个run，把main简化，调用run，run里跟上面方法一样，靠死循环，先定义一个接收输入的变量，然后进去while，调用Menu，接收输入的变量值，这个你自己约定，建议用整型，如果你要输入DA这种，那就字符串接收，然后比较出是那个然后给int变量一个值，switch（int的变量）case去调用你实现的操作函数 说的比较啰嗦，你看一下吧


Question: 小白求解

字符串里面的字符存的都是其 ASCII码，你查一下ASCII码表会发现 ‘0’对应的刚好是0x30， 所以用这些字符减下来刚好如2楼所说

7+2+3+4+4+5本来就是25啊，哪有为什么还是说你想每个s都打印一下？那就把{}补全，不加括号只算下面的一句 判断*p的是不是一到九，是就让s加上*p的大小的值


Question: 急求！！！！

这工作量也不小，要人无偿给你写一个这个东西，难啊  朋友

你自己写的代码呢


Question: 为什么只输出了h，小白提问

printf("%d\b, x); 先输出x的当前值，然后再将其消掉，就像我们打字时 按退格键一样。  建议查一下\b的用法

我用DEVC++和VS2019只输出了h，用在线编译器全输出， 了

为什么会异常退出？

为什么会内存溢出

你的控制台是中文的，\b会往回两个字符，两个\b就是4个字符，实际上你只输出了两个字符，导致内存溢出了

是printf的问题  输出第二个\b的时候 异常退出了 你再前面多输出几个字母就正常了

h     j k 我输出的是这个

小白求助。。。。。


Question: 一个很简单的问题却绊住了

我换了一种方法，也可以 三个数可以这样比较，4个数，或者8个数呢？有没有更好的办法？用排序法？   还有，我之前写scanf("%d,%d,%d"，&a,&b,&c) 是错的，d后面应该没有逗号的

引用 1 楼 user-4 的回复:建议先学习下基本的C语言赋值的语法吧  max = a>=b? a:b; max = c>=max? c:max; 我太糊涂了  引用 5 楼 柒贰伍玖 的回复: #include "stdio.h" #include "stdlib.h" //#include<windows.h>  int main() { 	int a, b, c, max; 	scanf("%d,%d,%d",&a, &b, &c); 	(a >= b) ? (max = a) : (max = b); 	(max >= c) ? (max = max) : (max = c); 	printf("\r\nmax is:%d\r\n",max); 	system("pause"); }   输入输出： 1,2,3  max is:3 请按任意键继续. . .你说的非常棒，启发很大

scanf("%d,%d,%d",&a, &b, &c); 你的输入格式里面 是用“，”分开的，你的数据输入也需要逗号隔开 例如输入：1,2,3,  三目运算符这样用没有语法错误，但是不是这样用的 应该是 max = (a > b)  ?  a  :  b;

从语法上说，虽然楼主这样写很啰嗦，但也是可以的，没毛病。 等于号赋值，会返回赋值后的值。  引用 1 楼 user-4 的回复:建议先学习下基本的C语言赋值的语法吧  max = a>=b? a:b; max = c>=max? c:max;  引用 2 楼 qq_1457346882 的回复:三目运算符不是这么用的啊，变量=表达式？成立的取值：不成立的取值

三目运算符不是这么用的啊，变量=表达式？成立的取值：不成立的取值


Question: 分子量问题

勉强能跑  #include<stdio.h> //#include<syslib.h> #include<ctype.h> #include<stdlib.h> #include<string.h> #define min 101 struct yuansu { 	char name; 	float hight; };   int aa(void) { 	struct yuansu *ss; 	ss = (struct yuansu *)malloc(sizeof(struct yuansu)*4); 	if (ss != NULL) 	{ 		printf("\n动态内存申请成功\n"); 	} 	int n = 4;//元素的种类 	for (int i = 0; i < n; i++) //输入元素的种类 	{ 		//flush(); 		printf("\n请输入第%d个元素名称与原子量\n", i + 1); 		scanf_s("%c %f", &ss[i].name,1, &ss[i].hight, 4); 		fflush(stdin); 		printf("输入为%c - %.2f", ss[i].name, ss[i].hight); 	} 	int j =0; 	printf("\n\n请输入要求的物质个数\n"); 	scanf_s("%d", &j); 	for (int ji = 1; ji <= j; ji++) 	{ 		double sum = 0.0; 		char a[min];// , p[10]; 		int i = 0; 		printf("\n请输入第%d个物质的分子式\n", ji); 		scanf_s("%s", a, min); 		double preHight = 0; 		while (a[i] != '\0') 		{ 			if (isdigit(a[i])) 			{ 				printf("输入物质分子式错误\n"); 				break;; 			}  			int r = 0; 			for (; r < n; r++) 			{ 				if (a[i] == ss[r].name) 					break; 			} 			if (r >= n) 			{ 				printf("输入物质分子式错误\n"); 				break;; 			} 			i++;  			if (!isdigit(a[i])) 			{ 				sum += ss[r].hight; 				continue; 			}   			int dv = 0; 			while (isdigit(a[i])) 			{ 				dv = dv * 10 + a[i] - '0'; 				i++; 			} 			sum += ss[r].hight *dv; 			 		} 		printf("%s的分子量为%.3f\n", a, sum); 	} 	free(ss); 	return 0; }

看编译报错  isdight  写错了，应该是isdigit

isdigit 你输错了


Question: 程序在Dev-c++上可以正确运行，但是在Vs2019下却报错了，这个错误是为什么？怎么解决，求大神指教！

引用 2 楼 寻开心 的回复:scanf_s("%d%c%c%d", &x1, &t, 1, &j, 1, &x2); 我网上百度， 而我这里输入的是字符，也要加上字符限制吗？

scanf_s("%d%c%c%d", &x1, &t, 1, &j, &x2);  要这样，输入字符或者字符串的时候要指定长度的大小。  你的程序还有别的问题，但是这里的问题就是这样了

查一下scanf_s在输入%c, %s等数据时的参数个数和参数信息。  %c， %s都需要多一个参数，_s就是相比scanf更安全，如何保证安全，那就是增加数据长度

解决方法楼上已经说了，我这里提一下你百度到的那段话，其实它说得不太清楚，微软的 scanf_s 在指定 %s、%c 等格式说明符时要求额外传入一个 unsigned int 来确定缓冲长度，概括一下就是: 在输入一串字符时需要指定缓冲长度。注意缓冲长度不是字符个数，例如你定义了 char str[5]，那么就要写成 scanf_s("%4s", str, 5) 或者 scanf_s("%5c", str, 5) 等。

你试过不就知道了嘛。  加上就好用， 不加就报错。 你说有效还是无效啊


Question: 哪个大佬有空解释一下吗？急

引用 2 楼 金。金。金。的回复:#include<stdio.h> #include<stdlib.h> #include<string.h>  #define max 100 #define len sizeof(Book) typedef struct Book{ 	char title[10]; 	char outher[10]; 	int time; 	int price; }Book; Book book[max]; int n; void use()////从information.dat中调出信息到book[max] { 	FILE *fp; 	if((fp=fopen("information.dat","rb"))==NULL){ 		printf("open file error"); 		return; 	} 	for(int i=0;i<n;i++){ 		if(fread(&book[i],len,1,fp)!=0); 	} 	fclose(fp); } void input()//录入图书信息到book[max] { 	printf("请输入要录入的图书个数n=");     scanf("%d",&n); 	printf("请输入图书信息：\n书名 作者名 出版时间 价格\n"); 	for(int i=0;i<n;i++){ 		scanf("%s%s%d%d",&book[i].title,&book[i].outher,&book[i].time,&book[i].price); 	} }  void save() //把book[max]的信息存入information.dat文件里 { 	FILE *fp; 	if((fp=fopen("information.dat","wb"))==NULL){ 		printf("open file error"); 		return; 	} 	for(int i=0;i<n;i++){ 		if(fwrite(&book[i],len,1,fp)!=1) 			printf("file write error"); 	} 	fclose(fp); 	printf("已存入图书信息!\n"); } void output()//从information.dat中调出信息到book[max]并输出 { 	FILE *fp; 	if((fp=fopen("information.dat","rb"))==NULL){ 		printf("open file error"); 		return; 	} 	for(int i=0;i<n;i++){ 		if(fread(&book[i],len,1,fp)!=0) 			printf("%-10s %-10s %d %d\n",book[i].title,book[i].outher,book[i].time,book[i].price); 	} 	fclose(fp); } void search()//从information.dat中调出信息到book[max]并查找 { 	Book b[max]; 	FILE *fp; 	char bookname[10]; 	printf("请输入要查找的书名：\n"); 	scanf("%s",&bookname); 	if((fp=fopen("information.dat","rb"))==NULL){ 		printf("open file error"); 		return; 	} 	for(int i=0;i<n;i++){ 		if((fread(&b[i],len,1,fp)!=0)&&(strcmp(b[i].title,bookname)==0)) 			printf("%-10s %-10s %d %d\n",b[i].title,b[i].outher,b[i].time,b[i].price); 	} 	fclose(fp); } void sort()//从information.dat中调出信息到在book[max]中排序后再输出 { 	use(); 	printf("按照时间排序如下：\n"); 	Book t; 	for(int i=0;i<n;i++) 		for(int j=i+1;j<n;j++) 			if(book[i].time<book[j].time){ 				t=book[i]; 				book[i]=book[j]; 				book[j]=t; 			} 	for(int k=0;k<n;k++){ 		printf("%-10s %-10s %d %d\n",book[k].title,book[k].outher,book[k].time,book[k].price); 	}  }  void dele()// { 	Bo 排序那里没问题了，之前的错误是	for(int k=0;k<n;k++){ 		printf("%-10s %-10s %d %d\n",book[i].title,book[i].outher,book[i].time,book[i].price); for括号里面是k，但是printf里面是i，已经改了

引用 2 楼 金。金。金。的回复:#include<stdio.h> #include<stdlib.h> #include<string.h>  #define max 100 #define len sizeof(Book) typedef struct Book{ 	char title[10]; 	char outher[10]; 	int time; 	int price; }Book; Book book[max]; int n; void use()////从information.dat中调出信息到book[max] { 	FILE *fp; 	if((fp=fopen("information.dat","rb"))==NULL){ 		printf("open file error"); 		return; 	} 	for(int i=0;i<n;i++){ 		if(fread(&book[i],len,1,fp)!=0); 	} 	fclose(fp); } void input()//录入图书信息到book[max] { 	printf("请输入要录入的图书个数n=");     scanf("%d",&n); 	printf("请输入图书信息：\n书名 作者名 出版时间 价格\n"); 	for(int i=0;i<n;i++){ 		scanf("%s%s%d%d",&book[i].title,&book[i].outher,&book[i].time,&book[i].price); 	} }  void save() //把book[max]的信息存入information.dat文件里 { 	FILE *fp; 	if((fp=fopen("information.dat","wb"))==NULL){ 		printf("open file error"); 		return; 	} 	for(int i=0;i<n;i++){ 		if(fwrite(&book[i],len,1,fp)!=1) 			printf("file write error"); 	} 	fclose(fp); 	printf("已存入图书信息!\n"); } void output()//从information.dat中调出信息到book[max]并输出 { 	FILE *fp; 	if((fp=fopen("information.dat","rb"))==NULL){ 		printf("open file error"); 		return; 	} 	for(int i=0;i<n;i++){ 		if(fread(&book[i],len,1,fp)!=0) 			printf("%-10s %-10s %d %d\n",book[i].title,book[i].outher,book[i].time,book[i].price); 	} 	fclose(fp); } void search()//从information.dat中调出信息到book[max]并查找 { 	Book b[max]; 	FILE *fp; 	char bookname[10]; 	printf("请输入要查找的书名：\n"); 	scanf("%s",&bookname); 	if((fp=fopen("information.dat","rb"))==NULL){ 		printf("open file error"); 		return; 	} 	for(int i=0;i<n;i++){ 		if((fread(&b[i],len,1,fp)!=0)&&(strcmp(b[i].title,bookname)==0)) 			printf("%-10s %-10s %d %d\n",b[i].title,b[i].outher,b[i].time,b[i].price); 	} 	fclose(fp); } void sort()//从information.dat中调出信息到在book[max]中排序后再输出 { 	use(); 	printf("按照时间排序如下：\n"); 	Book t; 	for(int i=0;i<n;i++) 		for(int j=i+1;j<n;j++) 			if(book[i].time<book[j].time){ 				t=book[i]; 				book[i]=book[j]; 				book[j]=t; 			} 	for(int k=0;k<n;k++){ 		printf("%-10s %-10s %d %d\n",book[k].title,book[k].outher,book[k].time,book[k].price); 	}  }  void dele()// { 	Bo void dele()// { 	Book b[max]; 	FILE *fp; 	char bookname[10]; 	printf("请输入要删除的书名：\n");                       	scanf("%s",&bookname); 	if((fp=fopen("information.dat","rb"))==NULL){ 		printf("open file error"); 		return; 	} 	int j=0; 	for(int i=0;i<n;i++) 		if(fread(&book[i],len,1,fp)!=0) 			printf("%-10s %-10s %d %d\n",book[i].title,book[i].outher,book[i].time,book[i].price); 		 	for(i=0;i<n;i++){ 		if(strcmp(book[i].title,bookname)==0) 		{ 			printf("已找到待删除书名i=%d\n",i); 			j=i; 			n=n-1; 		} 	}//找到待删除的记录  	for(i=j;i<n;i++) 		book[i]=book[i+1]; //	for(int t=0;t<n;t++) //		printf("%-10s %-10s %d %d\n",book[t].title,book[t].outher,book[t].time,book[t].price);//输出修改后book  	//（上文）删除源文件内容        	               //（下文）删除后保存到ne文件中     FILE *fpnew; 	if((fpnew=fopen("ne.dat","wb"))==NULL){ 		printf("open file error"); 		return; 	} 	for(int k=0;k<n;k++){ 		if(fwrite(&book[i],len,1,fpnew)!=1) 			printf("file write error"); 	} 	fclose(fpnew);  	if(remove("information.dat")==0) 		printf("have removed");//删除原文件 	if(rename("ne.dat","information.dat")==0) 		printf("filename change");//把临时文件名改为原文件名 	output(); } void main() { 	int login=180070120; 	int l; 	char function; 	printf("请输入登录号：(180070120)"); 	for(int i=1;i<=3;i++){ 		scanf("%d",&l); 		if(l!=login){ 			printf("密码错误！"); 		} 		else 			break; 	} 	if(i==4) 		return; 	printf("\n"); 	printf("......录入.图书信息 请输入A\n"); 	printf("......保存.图书信息 请输入B\n"); 	printf("......浏览.图书信息 请输入C\n"); 	printf("......按书名查询    请输入D\n"); 	printf("......按作者名查询  请输入E\n"); 	printf("......排序.图书信息 请输入F\n"); 	printf("......删除.图书信息 请输入G\n"); 	printf("......修改.图书信息 请输入H\n"); 	printf("......结束 请输入#\n"); 	getchar();     while(function!='#'){ 		printf("请输入指令："); 		scanf("%c",&function); 		switch(function){ 		case 'A':  input();break; 		case 'B':  save();break; 		case 'C':  output();break; 		case 'D':  search();break; 		case 'E':  sort();break; 		case 'F':  dele();break; 		case 'G':  ;break; 		case 'H':  ;break; 		} 	} }

你这什么东西啊，太绕了，你要把错误和问题写详细啊，好像排序哪里用一个循环就够了，两层虽然墨迹了，但是没问题的话也不会报错，删除那里应该是相等删除吧！=0是不相等的时候了啊，还有下面那1到24又是啥

for(i=0;i<n;i++){ if(strcmp(book[i].title,bookname)==0) { printf("已找到待删除书名i=%d\n",i); j=i; n=n-1; } }//找到待删除的记录  for(i=j;i<n;i++) book[i]=book[i+1]; // for(int t=0;t<n;t++) // printf("%-10s %-10s %d %d\n",book[t].title,book[t].outher,book[t].time,book[t].price);//输出   改： for(i=0;i<n;i++){ if(strcmp(book[i].title,bookname)==0) { printf("已找到待删除书名i=%d\n",i); j=i; } }//找到待删除的记录  for(i=j;i<n;i++){ book[i]=book[n-1]; n=n-1; } // for(int t=0;t<n;t++) // printf("%-10s %-10s %d %d\n",book[t].title,book[t].outher,book[t].time,book[t].price);//输出 你试试行不行，直接把最后的位置的内容替换掉你要删的，然后再把数量减一，直接不显示最后的 我只看了这一段附近的，n要是全局变量，你要确保变量值这里都是对的 如果可以用，建议你简化一下代码，很多一个循环能搞定的就不要用太多循环了 for(i=0;i<n;i++){ if(strcmp(book[i].title,bookname)==0) { printf("已找到待删除书名i=%d\n",i); book[i]=book[n-1];   //最后一本移到这个位置，删除当前书 n=n-1;    //位置前移一个 } }//找到待删除的记录


Question: c语言编程（结构体）

1.先声明一个结构体 struct 结构体名称{ 变量1类型  变量1； 变量2类型  变量2； …… 变量n类型  变量n； }；  2.在你需要用的地方定义一个结构体变量 struct 结构体名称  结构体变量  3.剩下的就跟正常使用变量一样使用它就行

引用 3 楼 與蘤舊縐 的回复：就是设计一个结构体，里面有三个字段，性别、年龄、姓名，或者再加个id，给出获取结构体年龄和姓名字段的函数，也就是传入结构体指针，返回字段值，其他功能自己加，包括怎么存储结构体等等抱歉，我没太懂

引用 1 楼 等风、来 的回复：朋友，你学到结构体这个章节了没有学了，就是这个题我有点不太明白

朋友，你学到结构体这个章节了没有


Question: 无输出问题

分不能浪费啊，给个回复我好结贴

噢 学了几天python，把.c的地址符忘了，丢人了。

后面的代码也是 scanf("%d",b)  改成 scanf("%d",&b)

while((scanf("%d",b) != EOF),b != 0)   输入要把变量地址传进去，你的程序执行完这句就异常退出了，没有执行后面的代码  改成  while((scanf("%d",&b) != EOF),b != 0)


Question: glib Socket Client通信异常问题

抱歉，问题定位了。 原因是我们的系统有一个守护进程，我每次启动后关闭再开就导致系统启动了两个一模一样的进程，干着同样的事。这就导致服务器发送了一组数据后，其中一个收到了中断和数据，另一个就只有中断而没有数据了...


Question: double溢出，换成long double输出为0

引用 4 楼 寻开心 的回复:改成1.0/i/i 应该可以。  i*i是两个int乘法。   1.0/i/i是两个double类型的运算，这样不用去改i的类型 谢谢了大哥。

引用 4 楼 寻开心 的回复:改成1.0/i/i 应该可以。  i*i是两个int乘法。   1.0/i/i是两个double类型的运算，这样不用去改i的类型 我得好好想一会。

你这个是i*i溢出， 把i的类型改了才有效，改sum没有用

引用 1 楼 寻开心 的回复:#include<stdio.h> int main(void) {     int m,n;     while(scanf("%d%d",&n,&m) != EOF,n != 0&&m != 0)     {         int i;         long double sum = 0;         for(i = n;i <= m;i++)         {             sum += 1.0 / (i * i);         }  printf("%.6Lf\n",sum); // long double的时候这里是 %.6Lf, double是%.6lf， float是%.6f     }     return 0; }  所说的double溢出是怎么回事儿， 倒数和，达不到溢出的标准啊  你现在输出0是因为参数是long double，而%。6lf指定的是double类型不匹配造成的 但是他给的例子太大了  65536 655360


Question: windows下的这个参数怎么输入

把数据文件（比如 data.txt）和你编译出来的执行文件（比如：test.exe文件）放到同一个目录下 方法1: 为你的exe文件创建一个快捷方式，编辑快捷方式， 在参数输入  data.txt 然后双击你的快捷方式，运行 方法2 运行cmd命令， 进入到这个文件夹后，人工输入。test data.txt 方法3 在你的编辑器里面，更改工程设置， 找到执行命令的部分，把参数设置为“ data.txt”

运行时跟在后面就是参数 比如 a.exe "bbb.txt"


Question: 改不出错误。。

代码里除了汉字剩下的都用英文，养成习惯，你输入学号之类的提示哪里为什么会想输出num？上面那个是函数嘛？没有返回值类型，参数也没有参数类型

在哪里就按照哪里的规矩啊 在论坛就是贴代码，贴图。

引用 3 楼 wsxedaa 的回复:用了分号错更多。。。 那说明本身就有很多错误，只是编译器发现这处错误就没有继续编译。所以，贴出源码吧，所有的

引用 7 楼 寻开心的回复:18行， 缺少分号那行后面 要写成 void insertYouXi(Linklist L, Lintlist p)   你这个bug太多， 还是贴完整的源代码提问吧 能不能QQ聊一下，这个不方便

错误都是从头开始改的，改了前面的影响后面的， 这个必须一步一步的来。  注意看你的编译器错误提示， 大多数情况都能清晰的定位语法错误在哪里

引用 2 楼 自信男孩的回复:直接贴代码吧，不建议贴图片~   缺少一个分号;  creatIncreLink函数声明后面缺少一个分号;  即创建链表的函数声明 大神能不能QQ说一下，这个不方便弄

中文那个改过了。。。还是不对。。

用了分号错更多。。。

你那个 %d 的%是中文的全角符号， 要改成英文符号才可以 第17行，尾巴明显少了一个分号


Question: 用C语言编写一个音乐播放器程序

mciSendString("open D:\\CloudMusic\\motherland. alias 1.mp3 ",NULL,0,NULL); 去掉文件名里面的点 试试，改成 mciSendString("open D:\\CloudMusic\\alias 1.mp3 ",NULL,0,NULL);

如果你不使用微软的 Visual Studio 开发，请在对应的编译器选项里添加链接库 winmm(如果不支持，就在命令行选项里加上 -lwinmm)，否则会造成链接失败(即你的情况)。


Question: 求助！

程序输出结果的层次，要求按照从n、n-1、n-2、……、1的顺序，将移除掉n号环的全部过程作为一个段落输出，然后将移除n-1号环的全部过程也作为一个段落输出，其余依此类推。  不仅需要最少次数 还需要移出n到1过程。这个不会啊，只想到移除n需要移出1到n-2.，这个怎么用非递归做出来

那就多读几遍，多看看， 思路都已经告诉你了啊， 伪代码也有了  拒绝提供原码，只提供思路，   不自己动脑子，哪里会有进步  你可以自己写的， 不对了再上来贴代码提问

程序还需要锁链过程描述

能不能再具体点，还是有点蒙

int ary[N] = {1, 2}; for ( I=3; I<N; I++)     ary[I] = ary[I-1] * 2*ary[n-2] + 1;  这不就不是递归了，

这个是递归的吧？我需要的是非递归

不就是九连环嘛?! 还编出一个外国故事  先弄出递归公式来 假定把前n个全部弄下来需要的操作次数是f（n） 那么把前n个从空白全套上去的次数也是f（n）次  要把第n个拿下的步骤 step1:  把先前n-2个都拿下（ 也就是用了f(n-2)次操作 ） step2: 拿下第n个，  此时第n-1个还在上面 step3: 把前n-2个再套上 step4: 把前n-1个都拿下  所以 ：  f(n)  = f(n-2） + 1 + f(n-2) + f(n-1)  =. f(n-1) + 2*f(n-2) + 1  f(1) = 1, f(2) = 2 从这里开始就可以用递推的方式把所有的步骤都算出来了 int ary[N] = {1, 2}; for ( I=3; I<N; I++)     f(I) = f(I-1) * 2*f(n-2) + 1; 剩下的代码自己写吧


Question: 一个萌新有关c语言文件的问题

谢谢你，忘记了fp的地址变化了

写入文件之后，fp指针的位置就变化了了，所以你读取时是读取的上次写的内容之后的位置。另外，写文件是写到缓存里，当缓存满时才会真正的写入文件。建议调用一下刷新操作，即把缓存里的刷到文件里去。试一下：fflush(fp);然后再把文件指针重新指向文件头，即rewind(fp);最后再读取试试

肯定的啊，你输入文件以后关闭了才会保存下来，这时候再打开读取内容才能读得到。而你没有关闭文件的话，你这个文件打开的还是空内容的状态，你没办法获取到内容的，所以没有输出。就像你打开txt文本，要保存或关闭再打开才有内容，如果写完了不保存直接换另一个打开，就是一个空的

写完文件以后关闭啊


Question: (codeblocks编程)使用debug运行fopen函数失败

编译器里面是可以设置执行路径和执行时候的调用参数的，不同的编译器方法不一样

引用 10 楼 apkipa1的回复:如果使用相对路径要注意程序当前所设置的工作目录是否是你想要的，这可以通过 SetCurrentDirectory 和 GetCurrentDirectory 实现。IDE、快捷方式或者其它程序可以在启动你的程序时修改程序默认的工作目录，而不使用直接双击打开时的程序所在的目录，所以会导致你所述的现象产生。 好的，谢谢111111

引用 7 楼 寻开心的回复:在设计你的程序的时候，就要考虑到执行文件和你的数据文件之间的位置关系，这样才可以写出正确的相对路径 或者你也可以让用户自己来输入文件的路径地址，绝对的也好相对的也罢都可以 是这样的。后来我把要打开的文件放到可执行文件同一目录问题就解决了。但是最后发现编译器打开的文件路径和可执行文件打开的文件路径不一样。

贴代码吧，如果代码没问题是不是编译器配置问题

引用 2 楼 寻开心的回复:看你的fopen文件路径是否正确吧。  如果不是写死的绝对路径，就要看debug下默认的路径和你生成文件夹所在路径与要打开文件的路径关系是否正确。 怀疑是上面的原因可能性较大  此外，你可以输出fopen的错误代码，看看具体原因 问题解决了，但是相对路径得输入到盘符，这样通过.exe才可以执行。不过这样的话可移植性不就变差了吗？有没有解决方法啊？

引用 2 楼 寻开心的回复:看你的fopen文件路径是否正确吧。  如果不是写死的绝对路径，就要看debug下默认的路径和你生成文件夹所在路径与要打开文件的路径关系是否正确。 怀疑是上面的原因可能性较大  此外，你可以输出fopen的错误代码，看看具体原因 我用的是相对路径，，，

引用 1 楼 柒贰伍玖的回复:是不是跟文件目录有关系 在编译器中能够正常运行，但是通过.exe在遇到fopen后无法正常打开文件，这样的话是文件路径的关系吗？

是不是跟文件目录有关系