Question: 题目是poj1008，问题是结构体数组中数组成员变量的调用

仅供参考：//codegen.c // 输入一组字符串，比如 // aa ss ddd dd 33 dd // 然后自动生成一个函数 int A(const char*); // 实现A("aa")返回0  A("ss")返回1 依次类推 #include <stdio.h> int main(int argc,char **argv) {     int i;     if (argc<2) {         printf("%s p1 [p2 ...] [>result.c]\nGenerate code int A(const char *a); 0==A(\"p1\") 1==A(\"p2\") ...",argv[0]);         return 1;     }     //printf("#include <string.h>\n");     printf("int A(const char *a) {\n");     for (i=0;i<argc-1;i++) {         printf("    if (0==strcmp(a,\"%s\")) return %d;\n",argv[i+1],i);     }     printf("    return -1;\n");     printf("}\n");     return 0; } //C:\test\Debug>codegen.exe //codegen.exe p1 [p2 ...] [>result.c] //Generate code int A(const char *a); 0==A("p1") 1==A("p2") ... //C:\test\Debug>codegen.exe aa ss ddd dd 33 dd //int A(const char *a) { //    if (0==strcmp(a,"aa")) return 0; //    if (0==strcmp(a,"ss")) return 1; //    if (0==strcmp(a,"ddd")) return 2; //    if (0==strcmp(a,"dd")) return 3; //    if (0==strcmp(a,"33")) return 4; //    if (0==strcmp(a,"dd")) return 5; //    return -1; //} // //c:\test\Debug>codegen.exe aa ss ddd dd 33 dd >result.c // //c:\test\Debug>type result.c //int A(const char *a) { //    if (0==strcmp(a,"aa")) return 0; //    if (0==strcmp(a,"ss")) return 1; //    if (0==strcmp(a,"ddd")) return 2; //    if (0==strcmp(a,"dd")) return 3; //    if (0==strcmp(a,"33")) return 4; //    if (0==strcmp(a,"dd")) return 5; //    return -1; //} //

代码，不是这么写滴。

switch(ch) ... case要求ch是整型数，字符串是不可以的。

case 不支持字符串，只能用 if(strcmp(s1, s2) == 0) 以及 else if 这样多个逐一判断。

字符串能case的吗？

基础知识的问题，switch语句用的不对。首先，明确switch语句中，语法格式是这样的： switch (e) { 		case c1: 			//执行相应语句  		break; 		case c2: 		    //执行相应语句 		break; 			//. . . 其他case事件 . . . 		default: 			//执行相应语句 		break; 	} 其中，e为一个整型的常量，！！当switch中的e的值恰好与case语句前的数字相同的时候执行相应的语句。因此你前面定义的是char类型的数组，后面将它用在switch语句中，就会出现不存在从char类型转换成int类型的错误。这个问题的

我觉得你倒不如来个二维字符数组 。。。

case后面的值必须是编译时就能确定的常量，否则不能用swich，你可以使用if去判断


Question: 萌新，请教一个问题。

【code=c】将代码放在这里【/code】 以上【】用[]代替

引用 6 楼 rongxin712 的回复:[quote=引用 3 楼 zhao4zhong1 的回复:] 仅供参考：  请问这是什么IDE ？[/quote]  应该是老赵一百年不动摇的VC6

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

引用 2 楼 rongxin712 的回复:[quote=引用 1 楼 cfjtaishan 的回复:] C 语言支持变长数组，这个支持变长应该是针对二维数组的行数可变，列数需要是固定的。 因此在定义二维数组作为形参时，需要确定列数，行数可以不用指定； 形参：int matrix[nRows][nCols];等价：int (*matrix)[nCols];因此需要固定行数nCols，建议将nCols定义成一个宏。   可能是vs2017 不支持这么写？[/quote] C语言不支持完全意义的变长数组，不过在C++里是支持的。

gcc作为c代码编译是可以的，基于clang/llvm的编译器，比如C++Builder也是可以通过的。

引用 1 楼 cfjtaishan 的回复:C 语言支持变长数组，这个支持变长应该是针对二维数组的行数可变，列数需要是固定的。 因此在定义二维数组作为形参时，需要确定列数，行数可以不用指定； 形参：int matrix[nRows][nCols];等价：int (*matrix)[nCols];因此需要固定行数nCols，建议将nCols定义成一个宏。    可能是vs2017 不支持这么写？


Question: 打字小游戏

游戏开发（一）——控制台 贪吃蛇 游戏开发（二）——控制台 俄罗斯方块

楼主如果想用C玩玩图形、小游戏编程，可以了解一下EasyX，EasyX是Windows平台最简单的绘图函数库（名副其实），兼容BC和TC的绘图函数，在VC下用EasyX来编程跟在TC下编程绘图差不多是完全一样的。EasyX既可以绘图，也支持图像显示和处理。  下载一个EasyX包，里面有完整的函数手册EasyX_Help.chm，有示例。EasyX官网有很多网友上传的实例，包括游戏。  仅供参考： 用绘图语句画机器猫（初学C语言的同学必看） http://blog.163.com/tab_98/blog/static/1192409720150316223680/


Question: 关于if（）后面加；号的问题

引用 18 楼 琢光 的回复:[quote=引用 1 楼 自信男孩 的回复:]#include<stdio.h> int main() {     int a,b;     a=1;     b=2;     if (a>b)         ;     printf("1");         } 这个能输出1是因为不论if判断的条件是否为真，都会执行printf打印； 而去掉;（分号），printf的打印要看if条件是否为真，若为真则执行，否则不执行； 简单理解，加了分号，就是printf不在if的控制范围之内了；  去掉分号，结果不为真，还是一样打印出来”1“。[/quote] 那不可能，你测试一下试试。或者把你修改之后的代码再贴出来～

引用 1 楼 自信男孩 的回复:#include<stdio.h> int main() {     int a,b;     a=1;     b=2;     if (a>b)         ;     printf("1");         } 这个能输出1是因为不论if判断的条件是否为真，都会执行printf打印； 而去掉;（分号），printf的打印要看if条件是否为真，若为真则执行，否则不执行； 简单理解，加了分号，就是printf不在if的控制范围之内了；  去掉分号，结果不为真，还是一样打印出来”1“。

加了；号后，后面的那句打印就不属于if块了

a的初始值为1，b的初始值为2，if判断语句是if(a>b)，如果不加；这个条件是不满足的所以不输出，加上；号这个语句执行完毕，才会输出1

这是基础问题，“if();”    这条语句判断后执行  “；”，完了再顺序的执行  ” printf("1");  "， “   if() printf("1");  "这条语句判断后执行  ” printf("1");  " 然后main()函数结束。

分号代表的是一个语句的结束。'if （a > b）; 表示判断完成之后，就结束，因为判断后并没有要求做什么。然后程序继续执行接下来的操作，输出1. 下一句if (a>b)  printf("1"); 表示的是，先判断条件是否成立，成立，后面没分号代表语句还没有结束。因此在前面的判断条件下看看是否执行输出1的操作

分号 阻断了if进行条件判断 即结束if语句块

;将条件判断和输出分开了~无论里面结果如何按照顺序流程，都会输出1。

if加；后，if下面不执行，直接打印

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

加了";"表示这个if语句已经结束了，无论判断结果如何，都不执行任何操作。

加了;相当于if的执行语句是一条空语句，后边的printf是一条独立的语句 二不加;时，后边的printf是if语句的执行语句，只有当前边的if条件成立时，才执行

if (a>b);   printf("1"); 相当于 if (a>b) ;  printf("1"); 其实就是空语句

if 后面如果不是大括号，if的范围只是紧接着的后一条语句，如果加了分号，if的范围只是这个分号的语句（一个空语句），后面的prinf不属于if的范围，即if成立只是执行一个空语句，prinf无论if是否成立均会执行

你这个有点类似悬挂if，建议在使用if else的时候，不管语句长短，都用{}括起来

条件语句 后加 ； 相当于一条语句


Question: char声明一个量等于1的时候为什么输出为笑脸

谢谢谢谢谢谢谢谢

建议参考ASCII码，%c输出，1不是一个可以显示的字符，比如若b = 48,输出的是0，因为48对应的ascii码为'0'


Question: 求助，关于C语言栈的实现的错误，请前辈们看下。

好的，现在通了，谢谢。

int full(StackPtr s) {     return (s->top == MAXSTACK - 1); } 是判断表达式不应该是赋值表达式；  #include<stdio.h> #include<stdlib.h>  #define MAXSTACK 100  typedef struct stack {     int top;     int entry[MAXSTACK]; }Stack,*StackPtr;  int init(StackPtr s); int push(StackPtr s, int i); int full(StackPtr s); int pop(StackPtr s, int *p);  int main(void) {     int temp = 0;     StackPtr s = (StackPtr)malloc(sizeof(stack));     init(s);     printf("%d  ", s->top);     //int number[5] = { 1,2,3,4,5 };     //for (int i = 0;i < 5;i++)     //{push(s, number[i]);}     push(s,1);     //for (int i = 0;i <= s->top; i++)     printf("%d  ", s->entry[s->top]);     pop(s, &temp);     printf("%d\n", temp);     getchar();     return 0;  }  int init(StackPtr s) {     s->top = -1;     return 0; }  int push(StackPtr s, int i) {     if (full(s))         return -1;      s->top++;     s->entry[s->top] = i;     return 0; }  int full(StackPtr s) {     return (s->top == MAXSTACK - 1); }  int is_empty(StackPtr s) {     return (s->top == -1); }  int pop(StackPtr s, int *num) {     if (is_empty(s))         return -1;      *num = s->entry[s->top];     s->top--;      return 0; } 参考一下吧 另外需要加一个判断栈是否为空的函数，在pop时需要判断栈是否为空，若为空则停止出栈，如上的代码；


Question: C语言指针问题

引用 2 楼 jianwen0529 的回复:printf("%s\n",*str); //%s格式是输出字符串，*str是一个字符，值是72，然后就会把0x00000072当作一个字符串，0x00000072这个地址可能是系统保护的 换成 %c 这个才是输出字符 个人认为不是把0x00000072当成一个字符串（况且，72的16进制也不是0x00000072,而是0x00000048吧）而是输出以0x00000048开始内存单元的数据，直到遇到'\0'停止输出。

首先，你的指针定义有问题，*左边或右边多了个空格，删除一个，然后把下一行的*删掉就可以了

引用 5 楼 paschen 的回复:*str类型是char，%d需要的是int类型整数，%s需要的是一个字符指针且需要以\0结尾，char转换为int是没有问题的，但转换为指针将导致程序崩溃，因为printf按你这个char的值作为一个地址去输出该地址的字符串内容 同样感谢你的回复，你和3#的回复同样正确！

引用 3 楼 cfjtaishan 的回复:printf("%s\n", str); 把*去掉就好了。 因为%s是输出字符串，对应的参数应该是一个地址值，若直接传str，由于str是字符数组名，本身就是地址，因此是没问题的。 但是若是*str，那么*str的值是72，那么就是输出地址为72开始的字符串（直到遇到'\0'才会结束输出），由于72是一个不能读写的位置，所以会导致段错误，程序异常 感谢你的回复，让我豁然开朗，原来格式控制%s是需要地址作为参数的，我原先一直以为参数就是第一个字符，感谢！

*str不是字符串


Question: 为什么int a[5]不行，哪一步越界了？（ int a[6]就可以）

数组下标从0开始

数组都是基于0（base-0）开始的，萌新； 0在C++中是很特殊的一个存在。 函数返回0，一般代表运行正确 0还可以表示空指针，表示C字符串结束符号 0还表示false

数组下标从0开始 PS：话说我好像也不太清楚什么时候用==，<=,>=什么的

数组下标都是从0开始计数的  建议多看一些基础书籍 多加练习

数组下表是从0开始的

i小于等于5呀..i等于5的话只能到a4哦亲

“多一少一”问题占程序员常犯错误的10%以上！ 避免“多一少一”问题的方法之一是将比如<10甚至<5的数代入程序片断，掰手指头心算验证一下程序到底应该写为 x、x-1、x+1中的哪个？ <、<=、==、>、>=中的哪个？

a[6]的数组下标是从0-5的

若定义的数组长度为5，目前的排序算法是不可以的。输入的时候也已经越界了。因为下表是从0开始的。所以，若定义的长度位5，则下表应该是[0,4]；包括0,4 目前的代码是没问题的，可以对5个数据排序，因为定义的数组长度为6，下表为0的位置没有用。  #include <stdio.h> #include <stdlib.h>  int main () {     int a[5],i,j,b;     for (i = 0; i < 5; i++)         scanf ("%d", &a[i]);      for (i = 0; i <= 4;i++)     {         for (j = 0;j < 5 - i - 1; j++)         {             if (a[j] > a[j+1])             {                 b = a[j];                 a[j] = a[j+1];                 a[j+1] = b;             }         }     }     for (i = 0;i < 5; i++)         printf ("%d ",a[i]);     system ("pause");     return 0; } 参考一下吧

数组小标从0开始计数，到小于数组个数N，即0 ~ （N-1）

引用 2楼5fai 的回复:不知道你为什么要从1开始计数，int a［6］你确定可以？

不知道你为什么要从1开始计数，int a［6］


Question: 求大神帮我看看，啊啊啊啊啊啊啊

输入输出样例有没有？

引用 2 楼 cfjtaishan 的回复:#include<stdio.h> int main() {      int i,j;     int a[3];     int b[100];      b[0]=1;     b[1]=2;      for(i=0;i<3;i++)         scanf("%d",&a[i]);     for(i=0;i<3;i++){         for(j=2;j<a[i];j++) {             b[j]=b[j-1]+b[j-2];             printf("No.%d = %d\n", j + 1, b[j]);         }         printf("::%d\n",b[j-1]);   /*此处用j-1,因为第二层循环里，j是j++后跳出循环的，所以输出时应该是是j-1*/     } } 参考一下吧 原因详见上面代码注释 正解   可以不用遍历  用数学表达式求

这不就是斐波那契数列吗？小样，换个马甲我就不认识你了？


Question: 求解为什么我的信号集清空和增加函数打印出来的与理论不符合呢？

信号集，是一个集合呀，怎么可以直接整数表示信号值？


Question: 二分查找

int bisearch(int v[],int x,int low,int high) { 	int mid=(low+high)/2; 	while(low<=high&&x!=v[mid]) 	{ 		if(x>v[mid]) 			low=mid+1; 		else 			high=mid-1; 		mid=(low+high)/2; 	} 	if(x==v[mid]) 		return mid; 	else if(low>high) 		return (x>v[low])?low+1:low; } int binarySearch(int a[], int item, int low, int high) {     if (high <= low)         return (item > a[low])?  (low + 1): low;      int mid = (low + high)/2;      if(item == a[mid])         return mid+1;      if(item > a[mid])         return binarySearch(a, item, mid+1, high);     return binarySearch(a, item, low, mid-1); }

下面的我写的，上面的是正确的，很抱歉图发错了

引用 8 楼 hdt 的回复:int bisearch(int v[],int x,int low,int high) { 	int mid; 	while( low<high-1) 	{ 		mid= low+(high-low)/2; 		if(x>v[mid]) 		{ 		   low=mid; 		} 		else 		{ 			high=mid; 		} 	} 	if( x==v[low]) 		return low; 	else if( x==v[high]) 		return high; 	else 		return -1; } 非常感谢点拨，最后一个else确实应该加上

引用 4 楼 cfjtaishan 的回复:int bisearch(int v[],int x,int low,int high) {     int mid=(low+high)/2;     while(low < high&&x!=v[mid])     {         if(x>v[mid])             low=mid+1;         else             high=mid-1;         mid=(low+high)/2;     }     if(x==v[mid])         return mid;     else if(low >= high)         return (x>v[low])?low+1:low; } 试一下这个。 改一下while循环的条件，另外，再改一下最后一个else if判断条件。即将上面的low <= high等号放到下面去判断 非常感谢点拨！可以的，当while的测试条件如此改变后，就避免了溢出的情况

int bisearch(int v[],int x,int low,int high) {     int mid=(low+high)/2; //这里如果low和high足够大，将溢出。     while(low<=high&&x!=v[mid])     {         if(x>v[mid])             low=mid+1;         else             high=mid-1;         mid=(low+high)/2;     }     if(x==v[mid])         return mid;     else if(low>high)         return (x>v[low])?low+1:low; //   缺少一个else   如果要找的数不在序列中将出错 ，还有因为缺少一个分支所以要求严格的编译器将无法通过编译 }

引用 5 楼 hdt 的回复:我看到两处bug 求教

我看到两处bug

binarySearch和binsearch都怎么实现的？没看到啊


Question: 连续使用scanf（）遇到的一个问题

引用 3 楼 weixin_41703094 的回复:用C方法可以fflush()清空缓冲区 fflush有时候是未定义的，可能跟具体实现有关。

在每个最后不带\n的printf后面加fflush(stdout); 在每个不想受接收缓冲区旧内容影响的scanf前面加rewind(stdin)、scanf(“%*[^\n]%*c”); scanf里面的%和变量以及变量前加不加&的一一对应关系.

printf( "Enter first group of five digits: " ); fseek(stdin, 0, SEEK_END);  scanf( "%1d%1d%1d%1d%1d", &i1, &i2, &i3, &i4, &i5 ); printf( "Enter second group of five digits: " ); fseek(stdin, 0, SEEK_END);  scanf( "%1d%1d%1d%1d%1d", &j1, &j2, &j3, &j4, &j5 );

在每个最后不带\n的printf后面加fflush(stdout); 在每个不想受接收缓冲区旧内容影响的scanf前面加rewind(stdin); 另外请检查scanf的返回值。 //请今后要用 char c; scanf("%c",&c); //时，都改为 char s[2]; char c; scanf("%1s",s); c=s[0]; //自动跳过一个或多个空格或Tab字符或回车换行，读取下一个字符。

格式化输入串中加入分隔符号.

引用 3 楼 weixin_41703094 的回复:用C方法可以fflush()清空缓冲区 这个是未定义行为，不保证所有正常编码器下都有效 详情可以参考http://bbs.csdn.net/topics/320073944

加个清楚缓冲区的就行了

rewind(stdin);

用C方法可以fflush()清空缓冲区

scanf是根据输入的内容，一一匹配 如果第一次输入6个数字，那么不能通过返回值来判断，判断了也不会返回出错，因为第六个输入不会进入第一个scanf对应的变量里。它还在输入缓存里。  printf( "Enter first group of five digits: " );     scanf( "%1d%1d%1d%1d%1d", &i1, &i2, &i3, &i4, &i5 );     while (getchar() != ‘\n') ;     printf( "Enter second group of five digits: " );     scanf( "%1d%1d%1d%1d%1d", &j1, &j2, &j3, &j4, &j5 ); 简单处理，考虑用这种方法   #include<stdio.h> int main() {       int i1, i2, i3, i4, i5;     int j1, j2, j3, j4, j5;      printf( "Enter first group of five digits: " );     scanf( "%1d%1d%1d%1d%1d", &i1, &i2, &i3, &i4, &i5 );      while (getchar() != '\n')         ;     printf("%d %d %d %d %d\n", i1, i2, i3, i4, i5);     printf( "Enter second group of five digits: " );     scanf( "%1d%1d%1d%1d%1d", &j1, &j2, &j3, &j4, &j5 );     printf("%d %d %d %d %d\n", j1, j2, j3, j4, j5); } 建议试一下

判斷scanf的返回值，小於要輸入的變量個數就是出現錯誤了；在下一次調用之前清空緩衝區，就可以避免取到多輸入的内容。


Question: 写任务计划

项目属性——链接器——清单文件——UAC执行级别：改成：requireAdministrator (/level='requireAdministrator')

引用 3 楼 paschen 的回复:以管理员方式打开CMD窗口执行 只能这样吗? 哎 版主 有程序获取管理员权限demo不 vc的

引用 2 楼 user-2 的回复:DOS是以管理员方式运行的吗？有没有使用兼容WIN7的方式运行过？ 只有在win10上只有管理员权限才能吗? 那我要是在vc++中 那不是还得提示本程序管理权限?

以管理员方式打开CMD窗口执行

DOS是以管理员方式运行的吗？有没有使用兼容WIN7的方式运行过？

顶


Question: C代码使用GetDiskFreeSpaceEx获得磁盘分区大小信息，返回值是以字节数表示，我想用字节数/512，表示成扇区数，为什么不成功？谢谢！

不能简单除以 512 的，用 GetDiskFreeSpace 获取扇区大小，再除。

#ifndef UNICODE #define UNICODE #endif // UNICODE  #include<stdio.h>  #include<windows.h>  #include <stdlib.h>   CHAR buf1[52428800]; //定义全局字符数组变量，大小50M   BOOL GetDiskSpaceInfo(LPCWSTR pszDrive){  DWORD64 qwFreeBytesToCaller = 0, qwTotalBytes = 0, qwFreeBytes = 0;  BOOL bResult = FALSE;  //使用GetDiskFreeSpaceEx获取磁盘信息并打印结果 bResult = GetDiskFreeSpaceEx(pszDrive,  (PULARGE_INTEGER)&qwFreeBytesToCaller,  (PULARGE_INTEGER)&qwTotalBytes,  (PULARGE_INTEGER)&qwFreeBytes);  if (bResult){  printf("使用GetDiskFreeSpaceEx获取磁盘信息\n");  printf("可获得的空闲空间（字节）：\t%I64d\n", qwFreeBytesToCaller);  printf("空闲空间（字节）：\t\t%I64d\n", qwFreeBytes);  printf("磁盘总容量（字节）：\t\t%I64d\n", qwTotalBytes);  }  return bResult;  }  int main(int argc, PCHAR argv[]){  GetDiskSpaceInfo(L"D:");   int i = 0;  int a = 0;  int num_str = 0;  DWORD RSize = 0;   DWORD64 qwFreeBytesToCaller = 0, qwTotalBytes = 0, qwFreeBytes = 0;  BOOL bResult = FALSE;  //使用GetDiskFreeSpaceEx获取磁盘信息并打印结果 bResult = GetDiskFreeSpaceExA("C:",  (PULARGE_INTEGER)&qwFreeBytesToCaller,  (PULARGE_INTEGER)&qwTotalBytes,  (PULARGE_INTEGER)&qwFreeBytes);   if (bResult){  printf("使用GetDiskFreeSpaceEx获取磁盘信息\n");  printf("可获得的空闲空间（字节）：\t%I64d\n", qwFreeBytesToCaller);  printf("空闲空间（字节）：\t\t%I64d\n", qwFreeBytes);  printf("磁盘总容量（字节）：\t\t%I64d\n", qwTotalBytes);  };  printf("磁盘总容量（扇区）：\t\t%I64d\n", qwTotalBytes/512);          return 0;  }

就是这样，提示：未找到源

不成功是什麽意思？輸出不符合預期？還是segment fault？


Question: 新人自学求助，第一次发帖，关于C99标准和C89标准引起的问题

楼主可以参考13楼的说法，哈哈

http://en.cppreference.com/w/c/io/fprintf 这里写的，对于printf，c99中%lf是double，c89中%f是double。（对于scanf，没有标准差别，都是%f是float，%lf是double）  LZ还是说下编译器的名称吧，因为我用的gcc，-std=c89和-std=c99编译后都能出正确的结果。

我之前选中了支持C99标准，结果编译这段代码没有任何问题，但在运行时，不管输入什么，输出都是0. 然后取消了支持C99。就正常了。 楼主的这句话是不是有问题呢， 因为C89对于double类型和float类型都用%f格式输出，不识别%lf的输出。 在C99上，%lf和%f表示同一个意思。所以，在C89上会出问题，在C99上不会出问题吧？ 建议楼主澄清这个问题的问题。

引用 14 楼 lin5161678 的回复:[quote=引用 11 楼 cfjtaishan 的回复:] 如果是编译器的问题，建议拿出依据。我要是误导的别人那是我的问题，但是提出一个观点起码需要论据支持，如果能够拿出编译器问题的依据出来，这样大家才会信服和支持。 编译器的bug，这个锅不能随便甩出去的。建议拿出更多的依据出来。 另外，建议楼主提供更多的信息，比如编译器版本，编译器环境（Windows，Linux等更多的详细版本）； 有疑问? 那你自己所说楼主的代码问题在哪里  你说不是编译器bug  请你解释一下 题主遇到的错误 [/quote] 首先你反驳我的意见，  引用 14 楼 lin5161678 的回复:[quote=引用 11 楼 cfjtaishan 的回复:] 如果是编译器的问题，建议拿出依据。我要是误导的别人那是我的问题，但是提出一个观点起码需要论据支持，如果能够拿出编译器问题的依据出来，这样大家才会信服和支持。 编译器的bug，这个锅不能随便甩出去的。建议拿出更多的依据出来。 另外，建议楼主提供更多的信息，比如编译器版本，编译器环境（Windows，Linux等更多的详细版本）； 有疑问? 那你自己所说楼主的代码问题在哪里  你说不是编译器bug  请你解释一下 题主遇到的错误 [/quote] 首先你提出我在误导大家，给大家传递错误的知识。然后你提出是编译器的bug，所以这些论据应该你先提供。至少需要提供两个论据：反驳我的观点论据，其二，提供编译器bug的论据。

引用 11 楼 cfjtaishan 的回复:如果是编译器的问题，建议拿出依据。我要是误导的别人那是我的问题，但是提出一个观点起码需要论据支持，如果能够拿出编译器问题的依据出来，这样大家才会信服和支持。 编译器的bug，这个锅不能随便甩出去的。建议拿出更多的依据出来。 另外，建议楼主提供更多的信息，比如编译器版本，编译器环境（Windows，Linux等更多的详细版本）； 有疑问? 那你自己所说楼主的代码问题在哪里  你说不是编译器bug  请你解释一下 题主遇到的错误

引用 10 楼 lin5161678 的回复:[quote=引用 7 楼 cfjtaishan 的回复:] [quote=引用 6 楼 super_admi 的回复:] 我建议你还是先弄清楚再说，免得误导了别人。 从网上的讨论，以及标准说明来看，对于printf，%lf和%f其实是一回事；而对于scanf，%lf和%f是有区别的。  [quote=引用 5 楼 cfjtaishan 的回复:] [quote=引用 2 楼 super_admi 的回复:] printf输出格式，不要使用%lf，而使用%f  我看了下网上的说法，怀疑这里可能是编译器的BUG。 这也是问题，double类型不是%lf输出吗？你的回答正好反过来吧  double和float的输出格式是不一样的。建议不要混为一谈。[/quote][/quote] printf既然是一回事，那么楼主的输入是%lf，定义的double类型，怎么解释输出结果是0？[/quote] 无知不是错 但无知还到处误导人就是你的不对了  C89 printf 没有%lf 不管是 double还是float都用 %f %lf 部分编译器扩展的实现  C99开始 printf里面 %lf 和 %f 行为完全一样  这里编译器的行为和标准要求不一致 如果楼主描述没错  的确是编译器bug  C89的情况下 %lf 输出0 符合标准要求 当然结果是错的 因为代码本身不规范 C99的情况下 %lf 必须得到正确的结果 做不到就是编译器的问题  有疑问? 那你自己所说楼主的代码问题在哪里[/quote] 如果是编译器的问题，建议拿出依据。我要是误导的别人那是我的问题，但是提出一个观点起码需要论据支持，如果能够拿出编译器问题的依据出来，这样大家才会信服和支持。 编译器的bug，这个锅不能随便甩出去的。建议拿出更多的依据出来。 另外，建议楼主提供更多的信息，比如编译器版本，编译器环境（Windows，Linux等更多的详细版本）；

引用 7 楼 cfjtaishan 的回复:[quote=引用 6 楼 super_admi 的回复:] 我建议你还是先弄清楚再说，免得误导了别人。 从网上的讨论，以及标准说明来看，对于printf，%lf和%f其实是一回事；而对于scanf，%lf和%f是有区别的。  [quote=引用 5 楼 cfjtaishan 的回复:] [quote=引用 2 楼 super_admi 的回复:] printf输出格式，不要使用%lf，而使用%f  我看了下网上的说法，怀疑这里可能是编译器的BUG。 这也是问题，double类型不是%lf输出吗？你的回答正好反过来吧  double和float的输出格式是不一样的。建议不要混为一谈。[/quote][/quote] printf既然是一回事，那么楼主的输入是%lf，定义的double类型，怎么解释输出结果是0？[/quote] 无知不是错 但无知还到处误导人就是你的不对了  C89 printf 没有%lf 不管是 double还是float都用 %f %lf 部分编译器扩展的实现  C99开始 printf里面 %lf 和 %f 行为完全一样  这里编译器的行为和标准要求不一致 如果楼主描述没错  的确是编译器bug  C89的情况下 %lf 输出0 符合标准要求 当然结果是错的 因为代码本身不规范 C99的情况下 %lf 必须得到正确的结果 做不到就是编译器的问题  有疑问? 那你自己所说楼主的代码问题在哪里

引用 8 楼 super_admi 的回复:"对于printf，%lf和%f其实是一回事"，这句话的前提是：“从网上的讨论，以及标准说明来看”。 所以，我才说“怀疑这里可能是编译器的BUG”。 阁下小学语文是体育老师教的？  [quote=引用 7 楼 cfjtaishan 的回复:] [quote=引用 6 楼 super_admi 的回复:] 我建议你还是先弄清楚再说，免得误导了别人。 从网上的讨论，以及标准说明来看，对于printf，%lf和%f其实是一回事；而对于scanf，%lf和%f是有区别的。  [quote=引用 5 楼 cfjtaishan 的回复:] [quote=引用 2 楼 super_admi 的回复:] printf输出格式，不要使用%lf，而使用%f  我看了下网上的说法，怀疑这里可能是编译器的BUG。 这也是问题，double类型不是%lf输出吗？你的回答正好反过来吧  double和float的输出格式是不一样的。建议不要混为一谈。[/quote][/quote] printf既然是一回事，那么楼主的输入是%lf，定义的double类型，怎么解释输出结果是0？[/quote][/quote] 对体育老师教的，但是怀疑编译器的bug，也是找不到原因的一个借口。

拉不出屎赖茅房。

"对于printf，%lf和%f其实是一回事"，这句话的前提是：“从网上的讨论，以及标准说明来看”。 所以，我才说“怀疑这里可能是编译器的BUG”。 阁下小学语文是体育老师教的？  引用 7 楼 cfjtaishan 的回复:[quote=引用 6 楼 super_admi 的回复:] 我建议你还是先弄清楚再说，免得误导了别人。 从网上的讨论，以及标准说明来看，对于printf，%lf和%f其实是一回事；而对于scanf，%lf和%f是有区别的。  [quote=引用 5 楼 cfjtaishan 的回复:] [quote=引用 2 楼 super_admi 的回复:] printf输出格式，不要使用%lf，而使用%f  我看了下网上的说法，怀疑这里可能是编译器的BUG。 这也是问题，double类型不是%lf输出吗？你的回答正好反过来吧  double和float的输出格式是不一样的。建议不要混为一谈。[/quote][/quote] printf既然是一回事，那么楼主的输入是%lf，定义的double类型，怎么解释输出结果是0？[/quote]

引用 6 楼 super_admi 的回复:我建议你还是先弄清楚再说，免得误导了别人。 从网上的讨论，以及标准说明来看，对于printf，%lf和%f其实是一回事；而对于scanf，%lf和%f是有区别的。  [quote=引用 5 楼 cfjtaishan 的回复:] [quote=引用 2 楼 super_admi 的回复:] printf输出格式，不要使用%lf，而使用%f  我看了下网上的说法，怀疑这里可能是编译器的BUG。 这也是问题，double类型不是%lf输出吗？你的回答正好反过来吧  double和float的输出格式是不一样的。建议不要混为一谈。[/quote][/quote] printf既然是一回事，那么楼主的输入是%lf，定义的double类型，怎么解释输出结果是0？

我建议你还是先弄清楚再说，免得误导了别人。 从网上的讨论，以及标准说明来看，对于printf，%lf和%f其实是一回事；而对于scanf，%lf和%f是有区别的。  引用 5 楼 cfjtaishan 的回复:[quote=引用 2 楼 super_admi 的回复:] printf输出格式，不要使用%lf，而使用%f  我看了下网上的说法，怀疑这里可能是编译器的BUG。 这也是问题，double类型不是%lf输出吗？你的回答正好反过来吧  double和float的输出格式是不一样的。建议不要混为一谈。[/quote]

引用 2 楼 super_admi 的回复:printf输出格式，不要使用%lf，而使用%f  我看了下网上的说法，怀疑这里可能是编译器的BUG。 这也是问题，double类型不是%lf输出吗？你的回答正好反过来吧  double和float的输出格式是不一样的。建议不要混为一谈。

谢谢各位的回答

参考帖子：  http://bbs.csdn.net/topics/380160601

關鍵應該在%lf上，但我手頭沒環境可以驗證你的問題。


Question: c语言设计时间差的问题

引用 3 楼 qq_41603109 的回复:我写的没错啊 注意看一下你的双引号引到哪儿了？

我写的没错啊

scanf("%d %d,&hour1,&minute1");     scanf("%d %d,&hour2,&minute2");

引用 2 楼 cfjtaishan 的回复:#include <stdio.h> int main() {     int hour1,minute1;     int hour2,minute2;           scanf("%d %d",&hour1,minute1);     scanf("%d %d",&hour2,minute2);           int t1 = hour1 * 60 + minute1;     int t2 = hour2 * 60 + minute2;           int t = t2 - t1;           printf("时间差的%d小时%d分钟。", t/60, t%60);       return 0;  }   scanf编译应该会提示警告，至少会有警告；因为scanf的参数不对。 改成这样：     scanf("%d %d",&hour1,minute1);     scanf("%d %d",&hour2,minute2); minute1,2也需要加&  scanf("%d %d",&hour1, &minute1);     scanf("%d %d",&hour2, &minute2);

scanf("%d %d,&hour1,minute1"); scanf("%d %d,&hour2,minute2");   改为   scanf("%d %d",&hour1,&minute1); scanf("%d %d",&hour2,&minute2);

引用 6 楼 user-5 的回复:scanf("%d %d,&hour1,minute1"); 改成： scanf("%d %d",&hour1,minute1);  注意右引号位置谢谢  我已经改了

引用 4 楼 cfjtaishan 的回复:[quote=引用 3 楼 qq_41603109 的回复:] 我写的没错啊 注意看一下你的双引号引到哪儿了？[/quote]哦好低级的错误  主要是编译没问题没警告  但是我改了后怎么在命令窗口输入  一回车就强行停止


Question: 请问大神我这道题的算法错在哪里？

引用 2 楼 liugc2008 的回复:没跑过，我是看着，2<=n,m<=20，就这个条件，你的程序就不满足，ACM肯定通不过的。。。 啊？   应该怎么改？     我刚刚传了代码的截图，看得更清楚一些。。。

引用 1 楼 hdt 的回复:怎么个加密？ 就是原来是一个n*m的二维数组，解码的过程就是对其从上往下以“弓形”的方式读取 ，得到一个数字序列。

怎么个加密？


Question: c语言程序有问题，求解答，菜鸟求轻踩

單步調試看在哪裏出問題了

#include <stdio.h> #include <stdlib.h> #include <time.h> #include <string.h>  enum        NumberDefine     {two, three, four, five, six, seven, eight, nine, ten, jack, queen, king, ace, joker  }; const char* NumberString[] = {"2", "3",   "4",  "5",  "6", "7",   "8",   "9",  "10","J",  "Q",   "K",  "A", "Joker"}; enum        ColourDefine     {spade, heart, club, diamond}; const char* ColourString[] = {"黑桃","红桃","梅花","方块"}; const int   CountOfNumber = 13; const int   CountOfColour = 4; const int   CountOfJoker  = 2; const int   CountOfCards  = 52;  typedef unsigned char byte;  typedef struct tagPoker {     byte number;     byte colour; }Poker;  void swapCards(Poker* cards, int first, int second) {     Poker temp;     if(first != second)     {         memcpy(&temp,          &cards[first],  sizeof(Poker));         memcpy(&cards[first],  &cards[second], sizeof(Poker));         memcpy(&cards[second], &temp,          sizeof(Poker));     } }  Poker* produceCards(int countOfPack) {     Poker* cards = (Poker*)malloc(sizeof(Poker)*CountOfCards*countOfPack);     int pack = 0, colour = 0, number = 0, index = 0;     for(pack = 0; pack < countOfPack; pack++)     {         for(colour = 0; colour < CountOfColour; colour++)         {             for(number = 0; number < CountOfNumber; number++)             {                 cards[index].number = number;                 cards[index].colour = colour;                 index++;             }         }     }     return (cards); }  void shuffleCards(Poker* cards, int countOfPack) {     int count = countOfPack*CountOfCards;     int i = 0;     srand((unsigned)time(NULL));     for(i = 0; i < count; i++)     {         swapCards(cards, i, rand()%count);     } }  void displayCards(Poker* cards, int countOfPack) {     int count = countOfPack*CountOfCards;     int i = 0;     for(i = 0; i < count; i++)     {         printf("%003d: %s%s\n", i, ColourString[cards[i].colour], NumberString[cards[i].number]);     } }  void destroyCards(Poker* cards) {     free(cards); }  int main(void) {     int countOfPack = 1;     Poker* cards = produceCards(countOfPack);     printf("------------------------------\n");     displayCards(cards, countOfPack);     shuffleCards(cards, countOfPack);     printf("------------------------------\n");     displayCards(cards, countOfPack);     destroyCards(cards);     return (0); }


Question: 关于在消息响应函数中创建窗口的问题

会不会是同步、异步的区别

《深入浅出MFC》

引用 3 楼 leetow2006 的回复:会不会是同步、异步的区别 能详细说下嘛？

引用 1 楼 liugc2008 的回复:你理解偏差了，有一种是虚函数，比如PostNcDestroy，这种是即时响应的。当然我说的是MFC，但是殊途同归。 而所有的消息响应机制中，消息的处理过程也是有队列的，你POST了WM_XXX，也要等到系统取到这个消息之后才响应。所以说，无论什么消息，只要消息队列不空，就没法即时响应，除非调用别的类似GetMessage或查看消息队列的函数，具体名称忘记了。  这点我之前查的时候有看到，PostQuitMessage在将WM_QUIT放入队列后不会等到它响应会直接退出来，但是还是不懂为什么WM_CLOSE中放入队列的WM_QUIT会一直得不到响应，但是WM_DESTROY中放入队列的WM_QUIT可以得到响应呢？ 不好意思，新手有点转不过这个弯


Question: C语言中：栈的伸展方向到底是什么啊？ 我今天被嘲笑了。。

栈的伸展方向和处理器有关。早一些的51系列是向高地址生长的，称为正向生长。8086系列是向低地址生长的，称为逆向生长。

你没有控制变量，输出的地址谁大谁小受栈生长方向和局部变量分配顺序两个英雄。 栈的生长方向是取决于处理器所采用的指令架构的。 而你的使用的测试代码的输出不但涉及到栈的生长方向；还涉及到编译器给局部变量分配空间的顺序问题，而对于这个问题（实际上标准是没有规定的，因为没必要，因为编程者想要的只是一个抽象的可以存储东西的变量，而不关心a和b在内存中的绝对位置或者相对位置，如果你需要固定相对位置的话，可以通过struct或者数组解决），既然没有规定，那么编译器的实现者就可以自由发挥了。 另外，从编译原理的角度来看，debug和release两种模式下的编译器是两个编译器，因为它们生成的目标代码不一样（虽然目标代码所属的种类一样）。当然，debug和release出现这样的差异的确比较神奇（不过可能debug和release是两个小组的人员分别实现不同的部分，然后共有部分又是一批人实现的），对于语言标准没定，而且又不怎么要紧的实现细节出现不一致也不是什么难以理解的事） 当然，虽然局部变量的分配顺序没定，但是函数调用时参数传递压栈的顺序是有规定的（如果需要详细了解细节，应当查看调用规范。__cdecl,__fastcall,__stdcall,__pascal）。 当然，你在debug和release模式下的运行不一致，说明应该是两种模式下编译器的解释不一致，具体可以生成汇编代码查看。

栈的伸展方向是不确定的，这一点在<UNP>中有谈到，栈的伸展方向并没有统一的规定，只区分地址的大小端。可能是自顶而下，也可能是自下而上。

8086的堆栈指针，压栈时，SP减去2，是按照地址递减的方向生成堆栈； 8031的堆栈指针，压栈时，SP加上1，是按照地址递增的方向生成堆栈。 arm 甚至可以改变。

理解和讨论之前请先学会如何观察！  计算机组成原理→DOS命令→汇编语言→C语言（不包括C++）、代码书写规范→数据结构、编译原理、操作系统→计算机网络、数据库原理、正则表达式→其它语言（包括C++）、架构……  对学习编程者的忠告： 多用小脑和手，少用大脑、眼睛和嘴，会更快地学会编程！ 眼过千遍不如手过一遍！ 书看千行不如手敲一行！ 手敲千行不如单步一行！ 单步源代码千行不如单步Debug版对应汇编一行！ 单步Debug版对应汇编千行不如单步Release版对应汇编一行！ 不会单步Release版对应汇编？在你想单步Release版C/C++代码片断的前面临时加一句DebugBreak();重建所有，然后在IDE中运行。（一般人我不告诉他！）  VC调试时按Alt+8、Alt+7、Alt+6和Alt+5,打开汇编窗口、堆栈窗口、内存窗口和寄存器窗口看每句C对应的汇编、单步执行并观察相应堆栈、内存和寄存器变化，这样过一遍不就啥都明白了吗。 对VC来说，所谓‘调试时’就是编译连接通过以后，按F10或F11键单步执行一步以后的时候，或者在某行按F9设了断点后按F5执行停在该断点处的时候。  不要迷信书、考题、老师、回帖； 要迷信CPU、编译器、调试器、运行结果。 并请结合“盲人摸太阳”和“驾船出海时一定只带一个指南针。”加以理解。 任何理论、权威、传说、真理、标准、解释、想象、知识……都比不上摆在眼前的事实！

特别是2#3#答乃所问

和所使用的cpu硬件结构有关,如同 大小 端 问题。

由高地址向低地址生长

你可以用struct包起来再看，struct里按顺序来的

栈的伸展方向说白了，就是入栈时堆栈指针是从高地址向低地址递减还是堆栈指针是从低地址向高地址递增。       具体中哪种，和所使用的单片机硬件结构有关。

这个楼主看一下反汇编，变量声明通常是顺序生命的，也就是IP(Instruction Pointer)增长的方向，这样便于人的理解，而楼主所说的栈，是程序调用栈，是在函数调用之前，即汇编call之前的函数参数入栈过程，即push，这个栈的顺序是逆IP方向的，这样的设计好处是充分利用地址空间。楼上所说的调用约定（Calling Convention），跟你说的我觉得是不一样的。楼主可以看一下函数调用，稍微学一下汇编，就懂了。

该语言标准并没有规定，可以向上可以向下，，但操作系统规定是向下的

四种物件的生存方式(in stack、int heap、global、local static)

并没有规定栈一定要向哪个方向伸展，这个跟具体的cpu架构有关，有向上的有向下的 int a,b这个也没有规定哪个先入栈哪个后入栈，不同的编译器不同的情况有不同完全是可能的  最后，这个问题其实并不重要，绝大多数情况下你并不应该关心它向上增长还是向下增长 记得先进后出就好了

其实我是看到“嘲笑”两个字进来的。  1.会嘲笑别人的人，一般都是半桶水，区别只是大半桶还是小半桶而已； 2.想学东西，或者想做事情，就不要怕嘲笑，脸皮一定要厚实才行。

栈确实是从高到低增长  你写的代码需要注意编译器的调用方式：  cdecl、stdcall、fastcall函数调用  详细文档http://blog.csdn.net/fly2k5/article/details/544112

从C语言层面上不好解释,在汇编层面又是基础知识. 局部变量申请一般都是sub esp 8这类的指令,也可以说是由高地址向低地址生长,建议看下汇编相关的知识,不是很复杂的.

int a,b; 标准并没有要求编译器非得把a放在b的前面，你定义a b变量也不是一个压栈的过程，和栈生长方向没什么关系


Question: 第十一行是什么意思，有什么用？？？

将数组里面的值初始化为0


Question: sha1.c调用计算内存中文件hash值

百度搜相关关键字。


Question: realloc(): invalid next size求助

直接把sizeof(char **)改成4

sizeof前面加个(unsigned)试试

array = (char ***)realloc(array, sizeof(char **) * capacity); 这个扩容有问题吧，大小没变化呢，是不是应该是： array = (char ***)realloc(array, sizeof(char **) * sum);

单步跟踪程序运行，观察变量变化情况，分析原因


Question: 求回答

就是想修改文件的名字吧？那可以搜一下函数rename() 这里有具体的例子http://www.yiibai.com/c_standard_library/c_function_rename.html

引用 4 楼 cfjtaishan 的回复:已建立的意思是已经创建？ 如果是，建议搜一下系统函数rename 这个函数有印象,

这么不通顺的句子都能看懂

已建立的意思是已经创建？ 如果是，建议搜一下系统函数rename

int rename(char * oldname, char * newname);

文件操作  rname

可以啊，用C语言的方式修改。 linux就可以。Shell 指令


Question: float 怎么就近似成0了

这里发生了隐式类型转换 a 是int ，3也是整形，所以 (a/3)运算的结果，c++规定为int。 b=a/3.0;改为 这样就对了。 更详细的只是，楼主请看 c++primer 隐式类型转换这一节

两个整数相除结果还是整数 然后把整数存到一个浮点数变量中 其中一个为浮点数 则结果也为浮点数

你这里进行的是整数除法，所以结果是0，你要浮点数除法的话写成：b=a/3.0f;  或者 b=(float)a / 3;


Question: 关于在lcd上显示一张jpg图片的程序~~编译通过了，但启动程序后没有任何显示~~求解！！

沒錯，先分模塊測試，一點點來。

看你代码的逻辑，可以分开测试一下 先读取一个rgb数据的文件，写入lcd设备，是否能够正常显示 如果可以正常显示，读取jpg文件转成rgb数据，在写入lcd设备，是否能够正常显示

程序这么长，总得自己慢慢调试啊。别人拿去一般也只能通过调试发现问题。


Question: 新手关于continue的问题

if ('\n' == ch)             continue; 注意一下换行符是：'\n'不是'/n'


Question: 学了C的困惑

给自己定一个学习的方向和目标，再定向学习和看相关的书籍，做好笔记，这样进步会快些~~

參加一個實際的項目，雖然不一定是技術很深的，但能讓你看到技術在業務上的應用。

学C是一个渐进的过程，学习的过程注重实践，总结；实践是不停的写和调试，也可以抄写别人的代码，然后分析和修改，再调试。遇到问题，或多某个问题认识模糊，建议自己先解决，不论是通过写代码调试还是通过看书找答案，都要自己先动手。然后，还可以考虑上网搜，对于初学者遇到问题在网上基本上都能找到答案。  http://blog.csdn.net/cfjtaishan/article/details/53672594

学习c函数的源码。

题库刷题&&看下纯面向对象的java

楼主如果想用C玩玩图形、小游戏编程，可以了解一下EasyX，EasyX是Windows平台最简单的绘图函数库（名副其实），兼容BC和TC的绘图函数，在VC下用EasyX来编程跟在TC下编程绘图差不多是完全一样的。EasyX既可以绘图，也支持图像显示和处理。  下载一个EasyX包，里面有完整的函数手册EasyX_Help.chm，有示例。EasyX官网有很多网友上传的实例，包括游戏。  仅供参考： 用绘图语句画机器猫（初学C语言的同学必看） http://blog.163.com/tab_98/blog/static/1192409720150316223680/


Question: C 的一个小基础问题

数组的大小必须在开始给定的吧

不可以，你不要纠结这个，  这个是c语言标准规定的 只能初始化的时候可以那样写， 但你可以有好多其他方法来修改数组内容的  实际上你没初始化 也不代表数组里面就没有内容

不可以！！！！！！书里说只能在初始化时用char a[] = "aaaaaaaaaaa";不可以在初始化后使用这种形式

你这个代码应该是编译都无法通过的吧！数组像这样赋值只能在定义的时候，像这样： char a[] = "aaaaaaaaaaaaaaaaxxxxxxxxxxx";

理解和讨论之前请先学会如何观察！  计算机组成原理→DOS命令→汇编语言→C语言（不包括C++）、代码书写规范→数据结构、编译原理、操作系统→计算机网络、数据库原理、正则表达式→其它语言（包括C++）、架构……  对学习编程者的忠告： 多用小脑和手，少用大脑、眼睛和嘴，会更快地学会编程！ 眼过千遍不如手过一遍！ 书看千行不如手敲一行！ 手敲千行不如单步一行！ 单步源代码千行不如单步Debug版对应汇编一行！ 单步Debug版对应汇编千行不如单步Release版对应汇编一行！ 不会单步Release版对应汇编？在你想单步Release版C/C++代码片断的前面临时加一句DebugBreak();重建所有，然后在IDE中运行。（一般人我不告诉他！）  单步类的实例“构造”或“复制”或“作为函数参数”或“作为函数返回值返回”或“参加各种运算”或“退出作用域”的语句对应的汇编代码几步后，就会来到该类的“构造函数”或“复制构造函数”或“运算符重载”或“析构函数”对应的C/C++源代码处。  VC调试时按Alt+8、Alt+7、Alt+6和Alt+5,打开汇编窗口、堆栈窗口、内存窗口和寄存器窗口看每句C对应的汇编、单步执行并观察相应堆栈、内存和寄存器变化，这样过一遍不就啥都明白了吗。 对VC来说，所谓‘调试时’就是编译连接通过以后，按F10或F11键单步执行一步以后的时候，或者在某行按F9设了断点后按F5执行停在该断点处的时候。  http://edu.csdn.net/course/detail/2344 C语言指针与汇编内存地址-一.代码要素

不可以的哦亲..看看数组的使用..放括号不写数字就得赴初值哦

c语言没有字符串这种类型，是通过字符数组实现字符串的， 赋值要么对数组一位一位赋值，要么函数实现

首先，char a[]; 这是一个不合理的定义。如果想定义数组的话，在没有初始化语句的话，需要指定数组大小，这涉及到变量a将被分配多少栈上的内存空间。第二个问题“aaaaafa”这样写的话，其实表明这个字符串是在静态存储区的。也有自己的内存首地址。如果想把这个内容从静态区报到栈上。那么就做一次memcpy操作就好了。 char a[strlen(“aaaaafa”)+1] ={0}; memcpy(a,”aaaaafa”,strlen(“aaaaafa”)); printf(“%s”,a);   如果只是想用一个内容为“aaaaafa”的字符串。就直接定义一个字符变量，去存储这个静态区字符的首地址 char *a =“aaaaafa”;  就好了！

可以在后面再赋值，但定义的时候需要先指定数组的大小，同时赋值时不能写成： a[]= "aaaaaafa";，要用strcpy(a,"aaaaaafa");，或者一个元素一个元素的指定

不可以，  引用 3 楼 faihung 的回复:[quote=引用 1 楼 hdt 的回复:] #include<stdio.h> main() {         char a[];         strcpy(a, "aaaaaafa");         printf("%s\n", a);         return 0; }memcpy也是可以的，哈哈。虽然这个是内存拷贝[/quote] 有没有考虑a的长度，这样操作不会越界吗？ char a[]和char *a（基本上）没什么区别。其实就是定义了一个野指针

C语言可以借助字符串操作函数实现字符串的拷贝，但是前提得给a申请足够存放的空间，否则会导致段错误。

引用 2 楼 hdt 的回复:sorry 有些问题   [quote=引用 1 楼 hdt 的回复:] #include<stdio.h> main() {         char a[20];//copy paster 没注意         strcpy(a, "aaaaaafa");         printf("%s\n", a);         return 0; }[/quote] 这样可以的

引用 5 楼 cfjtaishan 的回复:不可以，  [quote=引用 3 楼 faihung 的回复:] [quote=引用 1 楼 hdt 的回复:] #include<stdio.h> main() {         char a[];         strcpy(a, "aaaaaafa");         printf("%s\n", a);         return 0; }memcpy也是可以的，哈哈。虽然这个是内存拷贝[/quote] 有没有考虑a的长度，这样操作不会越界吗？ char a[]和char *a（基本上）没什么区别。其实就是定义了一个野指针[/quote]嗯，有道理。

引用 3 楼 faihung 的回复:[quote=引用 1 楼 hdt 的回复:] #include<stdio.h> main() {         char a[];         strcpy(a, "aaaaaafa");         printf("%s\n", a);         return 0; }memcpy也是可以的，哈哈。虽然这个是内存拷贝[/quote] 嗯 memcpy 要确定长度!

引用 1 楼 hdt 的回复:#include<stdio.h> main() {         char a[];         strcpy(a, "aaaaaafa");         printf("%s\n", a);         return 0; }memcpy也是可以的，哈哈。虽然这个是内存拷贝

sorry 有些问题   引用 1 楼 hdt 的回复:#include<stdio.h> main() {         char a[20];//copy paster 没注意         strcpy(a, "aaaaaafa");         printf("%s\n", a);         return 0; }


Question: 一个程序 求大神解答一下

include <stdio.h>  int main(void) {     float a;     int b;     int c;     int d;     int e;     printf("请输入你的分数:");     scanf("%f", &a);      b = (a<=100) && (a>=85);     c = (a<85) && (a>=70);     d = (a<70) && (a>=60);     e = (a<60) && (a>=0);      if (b==1)     {         printf("优秀");     }     else if (c==1)     {         printf("良好");     }     else if (d==1)     {         printf("及格");     }     else if (e==1)     {         printf("补考");     }     else     {         printf("请重新输入");     }     return 0;  } 判断表达式变成了字符串，去掉双引号即可。  另外，对于多个判断，建议使用switch case

楼上正解 你那个是一串字符串 if 恒为true

else if ("d==1") else if ("e==1")  ?? 你是复制粘贴的吧，条件判断没有“”的


Question: 关于C语言指针的一个问题 新人求大牛指点

q并沒有靜態分配，這一點理解有誤了，他是未分配狀態。

此int *p 非*p=8;

#include<stdio.h> #include<malloc.h>  int main() {     int* q;     int* p=(int*)malloc(sizeof(int));     if (!p)         return 1;      *p = 5;     *q = 6;      printf("%d",*p);     printf("%d",*q);      return 0; } 因为p指向了堆上的空间，是有效的空间。 q指针是野指针，指向的区域是随机的。若指向的是不可读写的区域，那么就会导致段错误～

q就没有分配内存呀，所以报错

一般我们用指针，用到两个概念：指针本身，称之为 P (Pointer)，指针指向的值，称之为 V (Value)。事实上，指针指向的值 V，也只是人为定的一个概念。因为指针指向的值和指针的值，其实就是两个独立的值。但值 P 其实是 V 的地址，这就人为将其建立了关联。通俗点讲，P 的值是 V 的“家庭住址”。不过 P 自身也有“家庭住址”，但不在我们讨论之列。你用 *P 这种写法，表示通过家庭住址来更换这个家庭中的东西，那前提是 P 这个“家庭住址”是有效的，并且你有权访问的。  一般我们在 C 中声明指针：int *p;如果仅仅是这样声明，没有初始化或赋值，只能称之为野指针。你没初始化，他的值是不确定的。你通过 *p 来读取（实地考察观看）这个不确定的“家庭住址”，那是没问题的。但是你如果要修改这个地址，一般只有两种可能：这个地址是别的程序的数据空间（已经有人居住，别人家的房子），或者说这里你没有权限写入（无法居住，没有房子，甚至连地都没有，比如大海）。当然是无效的了！通过指针访问数据，当然得有对应的实体，要不你访问哪的数据呢？  要通过指针间接更改其他变量的值：int n = 1;                    // 声明整型 n int *p = &n;                  // 声明指针 p 指向整型变量 n *p = 2;                       // 通过指针修改 n 的值为 2int *p = malloc(sizeof(int)); // 声明一块能够存放得下一个 int 大小的新空间 *p = 2;                       // 通过指针修改该新申请的空间以 int 方式储存值为 2 的整数 free(p);                      // 告诉系统你不再使用这块空间int *p; *p = 1;                       // WTF！自己写了一个存单就想去银行取钱？自己随便写了一个房产证就想强行入住？

int* q 的意思不是 给它分配一个int*类型的空间么？q不是有空间了么？

没有分配空间 赋的值往哪里存 指针只有分配空间或者说指向一片内存才可以直接赋值


Question: segmentation fault :11错误

scanf("%d",&data);包含回车符。

引用 5 楼 user-2的回复:你这个不是最后指针为空的问题。最后的指针为空是对的。你这里主要是参数的问题，你没理解参数是怎么传递的。 按照你的想法，我把代码做了些优化：   #include <stdio.h> #include <stdlib.h>  typedef struct tagNode {     int             data; 	struct tagNode* next; }Node;  Node* getNode(int data) {     Node* node = (Node*)malloc(sizeof(Node));     node->data = data;     node->next = NULL;     return (node); }  void append(Node* last) { 	int data = 0; 	printf("准备赋值："); 	scanf("%d",&data); 	if(data > 0) 	{ 	    last->next = getNode(data); 	    append(last->next); 	} }  void display(Node *head) {     Node* node = head;     int data = 0; 	printf("准备输出：\n"); 	while(NULL != node)     {         printf("data: %d\n", (data = node->data, node = node->next, data));     } }  void destroy(Node* head) {     Node* node = head;     int data = 0; 	printf("准备释放：\n"); 	while(NULL != node)     {         printf("free: %d\n", (data = node->data, head = head->next, free(node), node= head, data));     } }  int main() {     Node *head = getNode(-1); 	append(head); 	display(head); 	destroy(head); 	return (0); }  好的，谢谢，我再研究一下

引用 3 楼 user-2的回复: #include <stdio.h> #include <stdlib.h> typedef struct node {	int data; 	struct node *next;  }linklist; void Insert_list(linklist **rear,int entag)//利用尾插法插入元素。 { 	int val; 	//int x =0; 	//linklist *rear=L; 	printf("准备赋值"); 	scanf("%d",&val); 	if(val==entag) 		(*rear) =NULL; 		//printf("完成"); 		//{rear = (linklist*)malloc(sizeof(linklist));rear->next=NULL;rear->data=45;printf("完成");} 	else 	{ 		(*rear) = (linklist*)malloc(sizeof(linklist)); 		(*rear)->data = val; 		printf("\n————————————完成————————————\n"); 		Insert_list(&((*rear)->next),entag);  	} } void init_list(linklist **head) { 	(*head) = (linklist*)malloc(sizeof(linklist)); 	(*head)->next = NULL; 	printf("\n初始化完成\n"); }  void print_list(linklist *head) {	linklist *p=head->next; 	printf("准备输出：\n"); 	while(p!=NULL) 	{ 		printf("%d\n",p->data); 		p=p->next; 	} printf("链表为空"); }  int main() {	linklist *L;  	printf("创建成功"); 	//L = (linklist*)malloc(sizeof(linklist)); 	//linklist *rear = L; 	init_list(&L); 	Insert_list(&(L->next),4); 	print_list(L);  return 0;}  那为什么之前写法不行呢，链表最后指针为空不也应该可以吗？

引用 1 楼 user-2的回复:大坑！！！！！ 什么意思啊!

大坑！！！！！


Question: 请问下这个函数中有两个return怎么回事呢？

判断N为0则return   非0继续第一个return后的逻辑

满足某一特定条件后返回

第一个return是递归条件结束，也就是递归出口 第二个return是函数结束，其实不用加的，多此一举

根据不同的判断条件看，来返回

if ( !N )   成立就直接退出了

看来是个递归，第一个return是当N为0时返回void，第二个return是函数执行完了的标志。

if ( !N )  //递归结束条件     return;  递归函数一定要有结束条件

用断点看一下，有利于你的理解

第一个是对if（） ，第二个是对函数void（）。

引用 5 楼 user-17 的回复:我写程序的时候，还有用过 3 个 return 的呢。  好厉害的样子

后面就是     多此一举

N=2或者3时，一步一步走个单步看看，就知道两个return是什么意思了。其实就是个递归函数。

return是直接返回的意思，退出函数执行；即return后面的代码不会继续执行。 return返回的内容根据函数定义的返回值来定，若没有返回值，则直接跳出函数执行，释放函数资源；

一个函数中有多个return是很正常的，return就是函数返回嘛，没什么呀！

if ( !N )  //递归结束条件     return;  return; //这个是最后的返回，void类型，其实要不要都可以，通常这种情况不写这个return

不同结束程序的条件

我写程序的时候，还有用过 3 个 return 的呢。


Question: 新手求教

冒个泡。。。

scanf("%s", &a);这个有问题吧，a是数组名，就是数组的首地址，所以scanf("%s", a);

代码没问题， VS2015编译时需要在 预处理器->预处理器定义里添加一个_CRT_SECURE_NO_WARNINGS，否则会报scanf不安全的错误（如楼上所说用scanf_s，如果想继续用scanf就按前面说的添加一个_CRT_SECURE_NO_WARNINGS就OK）

推荐看一下scanf的原型 int scanf(const char *format, ...); The  scanf()  family  of  functions  scans input according to format as        described below.  This format may  contain  conversion  specifications;        the  results from such conversions, if any, are stored in the locations        pointed to by the pointer arguments that follow format.   Each  pointer        argument  must  be of a type that is appropriate for the value returned        by the corresponding conversion specification.         If the number of conversion specifications in format exceeds the number        of  pointer  arguments,  the  results  are undefined.  If the number of        pointer arguments exceeds the number of conversion specifications, then        the excess pointer arguments are evaluated, but are otherwise ignored.         The  scanf() function reads input from the standard input stream stdin,        fscanf() reads input from the stream pointer stream, and sscanf() reads        its input from the character string pointed to by str.

scanf("%s", a); 去掉a前的&;因为a是字符数组，数组名本身就是地址，因此不需要加&;

vc6编译环境很低，你换c-free试试，程序没啥问题

代码在vc6.0中可以运行，说明代码没有问题。 VS2015在创建工程的时候，和vc6.0是不一样的，很明显VS2015的编译环境你不熟悉。你百度一下、关于vs单个文件编译运行的问题。

输入到a数组的时候 不要加&       只写个a试试 scanf(.....,&a)  ->  scanf(...,a)


Question: 关于if的问题

浮点数是有精度的，你的理解是110 < 100 * 1.1是不成立的 但是100*1.1的结果可能是110.00000001,在满足精度的情况下，他是合理的，所以可能会输出OK

是，可能是精度问题

运算符优先级你看一下

这是有可能的。因为a,b都是浮点数，浮点数是有精度的，普通输出%lf都是小数点保留6位，可以通过%.20lf或者更多，就可以找到为什么会a < b * 1.1为真了。  #include<stdio.h>  int main() {     double a,b,c,x;     scanf("%lf %lf",&a, &b);     printf("%.0lf %.0lf\n",a,(a-b)/b*100);      printf("%.20lf %.20lf\n", a, b);     printf("%.20lf \n", b * 1.1);     if(a < b * 1.1) {         printf("OK\n");     }     else if(a>=b*1.1&&a<b*1.5){         printf("Exceed %.0lf%%. Ticket 200\n",(a-b)/b*100);     }     else if(a>=b*1.5){         printf("Exceed %.0lf%%. License Revoked\n",(a-b)/b*100);     }      return 0; } 对于浮点数判断大小不能按照整数判断大小的方法了，建议使用如下方法：  如果fabs(a-b)<=1e-6，那么就是相等了。 fabs是求浮点数绝对值的函数。 类似的 判断大于的时候，就是if(a>b && fabs(a-b)>1e-6)。 判断小于的时候，就是if(a<b&&fabs(a-b)>1e-6)。


Question: 请教大神，字符串长度有限制吗，最长多少。

c标准里是没有限制的，具体看你怎么定义的字符串，以及存放在什么地方了   像你这么定义的 char a[]的局部变量 一般都是在栈内存中存放 栈内存使用大小系统是有限制的， 建议使用malloc来申请内存空间存放  这样存放的地方是堆内存里  想存多少存多少  记得free

# include <stdio.h> # define N 100000000 char A[N],B[N]; //返回b在a中的个数 int BF(char a[],char b[]){     int i=0,j=0,k=0;     do{         if (b[j]&&a[i++]==b[j])             ++j;         else         {             b[j]?(i-=j):k++;             j=0;         }     }while(a[i-1]);         return k; } int main(){    gets(A);    gets(B);    printf("B在A中出现的次数:%d\n",BF(A,B)); }  能运行 你试试

用全局变量: # include<stdio.h> # define N 100000000 char A[N],B[N]; int main(){     return 0; }

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

从语法上来说, 字符串长度是可以无限长的. 但实际应用中, 会受到内存大小限制字符串长度. 如果是栈中分配字符串空间, 默认口有1M大小, 可以通过编译选项修改这个值 . 在堆中申请的话, 理论上来说内存条的内存还剩多大, 就是分配多大. 但实际情况需要考虑有没有这么大的连续内存. 其它静态区, 常量区也类似.

引用 6 楼 ttkl1108 的回复:mallo动态申请空间不行呀，总是失败。 说明你系统里的可用内存不够，才会失败。 但是你说母字符串长度至少为10的7次方， 10M都不到，现在的系统不应该分配不出来， 除非是嵌入式小系统，内存不够。 你看看你自己到执行分配多少了？

你确定栈的空间够大？

编译器设定里面把栈定义加大,默认是1M。  VC++堆栈默认大小是1M，如果你分配大于1M的堆，一般会出异常，这里你要把堆调大些，下面是VC++6.0与VC++2010的设置方法http://blog.csdn.net/mingojiang/article/details/17580021

在占用内存空间较大的局部数组声明的前面加static将其从堆栈数据段挪到全局数据段即可避开因局部数组大小超过默认堆栈大小1MB造成程序不能正常运行的问题。 字符串这么长可以放在文件里进行读取固定长度数据到缓冲区

既然长度“至少”10的7次方，就算申请成功了恐怕也不行的，还是仔细想想别的办法吧。

字符串的长度没有限制，但是存储字符串的内存是有限制的，具体要看你的编译环境和程序位数，在不超过机器内存和限制的情况下，局部变量的限制最大，一般只有1M左右，超过这个限制，程序无法运行，你可以使用new或者malloc来动态的申请空间，如果只是简单的小程序，可以把变量申请放在全局区域，这样内存可以申请的大一些

引用 6 楼 ttkl1108 的回复:mallo动态申请空间不行呀，总是失败。 还是太大。字符串没有长度限制，但是内存空间有限制，尤其是栈空间，是比较少的。 建议不要一次性申请那么大的空间。根据需要申请比需要的大一点的空间。

mallo动态申请空间不行呀，总是失败。

引用 10 楼 antuicang9886 的回复:[quote=引用 9 楼 cfjtaishan 的回复:] [quote=引用 8 楼 antuicang9886 的回复:] 局部变量使用的占内存空间，尽量别占用太多  [quote=引用 7 楼 cfjtaishan 的回复:] [quote=引用 6 楼 ttkl1108 的回复:] mallo动态申请空间不行呀，总是失败。 还是太大。字符串没有长度限制，但是内存空间有限制，尤其是栈空间，是比较少的。 建议不要一次性申请那么大的空间。根据需要申请比需要的大一点的空间。[/quote]  我觉得不对的，malloc申请的并非是栈内存空间，而局部变量的栈内存其实也就一个char *，没多少空间的： #include<stdio.h>  void test() { 	char *a;  	a = malloc(10000000*sizeof(char)); 	printf("done!\n"); }  main() { 	test(); }  楼主说malloc不行要不然代码写的有问题，要不然内存有泄漏风险（没有free），要不然PC太老配置太差，我感觉一般PC，申请10000000字节还是没问题的。 [/quote] 我没说malloc申请的是栈上空间，malloc申请的是堆上空间。 空间申请要根据实际需要来定，不能一下子申请太多的空间，不然会导致系统的其他功能模块运行不稳定或流畅。也会导致系统运行迟缓[/quote]   不好意思，看错了。建议与上述几位相同，局部变量不易过大，可改为static或者全局变量，在函数调用时，可再用指针访问。局部变量过大容易引起栈内存空间耗尽，尤其是在运用递归的时候。[/quote]  static定义的也是全局的，叫做静态全局变量，不过static限制了其作用域，static定义的变量的生命周期和全局变量的生命周期是一样的

引用 9 楼 cfjtaishan 的回复:[quote=引用 8 楼 antuicang9886 的回复:] 局部变量使用的占内存空间，尽量别占用太多  [quote=引用 7 楼 cfjtaishan 的回复:] [quote=引用 6 楼 ttkl1108 的回复:] mallo动态申请空间不行呀，总是失败。 还是太大。字符串没有长度限制，但是内存空间有限制，尤其是栈空间，是比较少的。 建议不要一次性申请那么大的空间。根据需要申请比需要的大一点的空间。[/quote]  我觉得不对的，malloc申请的并非是栈内存空间，而局部变量的栈内存其实也就一个char *，没多少空间的： #include<stdio.h>  void test() { 	char *a;  	a = malloc(10000000*sizeof(char)); 	printf("done!\n"); }  main() { 	test(); }  楼主说malloc不行要不然代码写的有问题，要不然内存有泄漏风险（没有free），要不然PC太老配置太差，我感觉一般PC，申请10000000字节还是没问题的。 [/quote] 我没说malloc申请的是栈上空间，malloc申请的是堆上空间。 空间申请要根据实际需要来定，不能一下子申请太多的空间，不然会导致系统的其他功能模块运行不稳定或流畅。也会导致系统运行迟缓[/quote]   不好意思，看错了。建议与上述几位相同，局部变量不易过大，可改为static或者全局变量，在函数调用时，可再用指针访问。局部变量过大容易引起栈内存空间耗尽，尤其是在运用递归的时候。

引用 8 楼 antuicang9886 的回复:局部变量使用的占内存空间，尽量别占用太多  [quote=引用 7 楼 cfjtaishan 的回复:] [quote=引用 6 楼 ttkl1108 的回复:] mallo动态申请空间不行呀，总是失败。 还是太大。字符串没有长度限制，但是内存空间有限制，尤其是栈空间，是比较少的。 建议不要一次性申请那么大的空间。根据需要申请比需要的大一点的空间。[/quote]  我觉得不对的，malloc申请的并非是栈内存空间，而局部变量的栈内存其实也就一个char *，没多少空间的： #include<stdio.h>  void test() { 	char *a;  	a = malloc(10000000*sizeof(char)); 	printf("done!\n"); }  main() { 	test(); }  楼主说malloc不行要不然代码写的有问题，要不然内存有泄漏风险（没有free），要不然PC太老配置太差，我感觉一般PC，申请10000000字节还是没问题的。 [/quote] 我没说malloc申请的是栈上空间，malloc申请的是堆上空间。 空间申请要根据实际需要来定，不能一下子申请太多的空间，不然会导致系统的其他功能模块运行不稳定或流畅。也会导致系统运行迟缓

局部变量使用的占内存空间，尽量别占用太多  引用 7 楼 cfjtaishan 的回复:[quote=引用 6 楼 ttkl1108 的回复:] mallo动态申请空间不行呀，总是失败。 还是太大。字符串没有长度限制，但是内存空间有限制，尤其是栈空间，是比较少的。 建议不要一次性申请那么大的空间。根据需要申请比需要的大一点的空间。[/quote]  我觉得不对的，malloc申请的并非是栈内存空间，而局部变量的栈内存其实也就一个char *，没多少空间的： #include<stdio.h>  void test() { 	char *a;  	a = malloc(10000000*sizeof(char)); 	printf("done!\n"); }  main() { 	test(); }  楼主说malloc不行要不然代码写的有问题，要不然内存有泄漏风险（没有free），要不然PC太老配置太差，我感觉一般PC，申请10000000字节还是没问题的。

不能运行的原因是你定义的该变量是局部变量吧，建议定义成全局或通过malloc/free，new/delete申请堆上的空间。 什么字符串要这么多大，不能一段一段的遍历和比较吗？这么大的空间，若用一段一段的处理会更好吧

1、编译器设定里面把栈定义加大 2、改成 char* p = new char[10000];


Question: 求高手解答strcpy()的一点疑问

完全可以那样写啊！把不等于0去掉也没问题啊

'\0'实际值是0，所以省略掉实际是一样的，只是可读性没那么好

引用 1 楼 cfjtaishan 的回复:while (*strDest++=*strSrc++;);  是可以的。个人认为没问题；因为'\0'对应的十进制值就是0；0就是判断false，退出循环； while (*strDest++=*strSrc++);  抱歉手误，多加了一个分号


Question: 请教各位大大一个指针问题，有关strtok函数的。

这是一个返回局部地址内容的操作，当split函数调用结束后，backup会被自动释放，那么你返回backup中的一个子串是没有意义的，也是未定义的行为； 建议这样操作；  char* split(char *buf, int pos, char *token, char *substr) {     char *hehe;     char *content;     char backup[100];     memcpy(backup, buf, 20);     content = strtok_s(backup, token,&hehe);     for (int i = 0; i < (pos-1); i++)     {         content = strtok_s(NULL, token, &hehe);     }     memcpy(substr, backup, strlen(backup) + 1);     //printf("%s\n", backup);      return substr; }  int main() {     char string_test[] = "no,yes,love,you";     char substr[32];     char *obj = split(string_test, 3, ",", substr);     printf("%s\n", obj);      return 0; } 这只是其中一种方法，如果有更好的，建议采纳更好的

这里有使用方法和例子：https://msdn.microsoft.com/en-us/library/ftsafwz3.aspx

content每次返回的是下一次字符串的首地址，因为分隔符被替换为/0了。最后一个分割，content会指向字符串的最末位置的下一位置，就是无效字符串 还有你既然分割字符串，那肯定是很多个子串，你单单返回一个字符串是什么作用？


Question: 新手C求教指导~~~

puts(++ptr);以后指针移动了

#include<stdio.h> int main(void) { char note[] = "See you at the snack bar."; char * ptr; ptr = note; puts(ptr); puts(ptr+1); note[7] = '\0'; puts(note); puts(ptr); puts(++ptr); return 0; }  你在开始的时候已经对指针进行更改了。。。

这是因为第一个puts(++ptr);此时的ptr已经指向了字符串node的第二个字符，即'e'，所以再次puts(ptr)时，应该是从"See"的第一个'e'开始输出；最后一个puts(++ptr);ptr指向了“See"的第二个字符'e'，因此输出是"e you"  个人建议通过打印出ptr的地址，这样能更好的分析原因： #include<stdio.h>  int main(void) {     char note[] = "See you at the snack bar.";     char * ptr;     printf("0. note: %p\n", note);     ptr = note;     printf("1. pstr: %p\n", ptr);     puts(ptr);      puts(++ptr);     printf("2. pstr: %p\n", ptr);     note[7] = '\0';     puts(note);     puts(ptr);     puts(++ptr);     printf("3. pstr: %p\n", ptr);     return 0; }


Question: 我是新手，请问大神这里是什么情况，怎么错了？

信息不够，结构体声明没有提出来； 从目前贴出的代码来看，code是野指针，直接给野指针赋值会导致运行时段错误； 建议楼主将完整代码贴出来，不要帖图片，若是编译结果可以贴图片。

除了上面两位说的，你是不是库文件没有调用完全啊。 信息量太少了，你错误代码都没有

用malloc分配一下空间，没有分配内存应该是


Question: 新手求助

不仅仅是变量还包含格式 %0.2f之类的，还有你让printf如何判断你的数据是什么类型，这需要运行时信息的支撑吧？

一个int变量，由于根据需要要各种格式输出，比如%c输出，%lu，%d， %lf, %f。那么printf需要根据格式来判定应该输出什么数据; 最重要的是printf函数接收的不是变量，而是变量值，比如  int val = 5; printf("%d", val);  这个操作是val传递给printf，其实是将val变量对应内存空间的值传给printf而不是变量。


Question: 【求助】我是c语言初学者，关于for循环我有问题要问大神

for(j=0,k=5;j<6,k>=0;j++,k--) 这句需要注意，如果j < 6 和 k >= 0是逗号连接，那么根据逗号运算符的特点，取最后一个表达式的值，那么for循环的判断就是根据k >=0是否为真，那么j < 6就没有意义了。 这一点需要注意，看一下你的想法是不是这样的，还是j < 6 && k >= 0；这个&&标识两个表达式同时为真才可以继续循环，否则退出循环；


Question: 搞不懂的C输入

按照楼上改了之后本地运行成功，上交网上测评仍然失败，按照下面的输入格式来就都成功了 int main(void) { 	int p=0; 	char tmp;  //p条道路 	scanf("%d",&p); 	int i=0; 	for(i=0;i<p;i++){//输入a，b牧场以及他们之间的距离 		input(); 	} 	run(25,0); 	printf("%c %d\n",minC+'A',min); 	return 0; } void input() { 	char a=' ',b=' '; 	int t; 	while(a==' '||a=='\r'||a=='\n') a = getchar(); 	while(b==' '||b=='\r'||b=='\n') b = getchar(); 	scanf("%d",&t); 	a = (a>='A'&&a<='Z'?a-'A':a-'a'+26);       //用0～25代表大写字母，用26～52代表小写字母 	b = (b>='A'&&b<='Z'?b-'A':b-'a'+26); 	if(map[a][b]!=0&&t>map[a][b]){      //如果a，b此前已经录入过，则比较a，b之间道路的距离，录入距离短的 		return; 	} 	map[a][b] = t;  //a-b距离为t 	map[b][a] = t;  //b-a距离为t 	check[a] = 1;  //标记a，b农场此时已经被写入map 	check[b] = 1; }

void input(int n) {     char a=' ',b=' ',tmp;     int t;     int i=0;     for(i=0;i<n;i++){//输入a，b牧场以及他们之间的距离         getchar();    /*recv ‘\n'上次输入的换行符*/         scanf("%c %c %d",&a,&b,&t);         a = (a>='A'&&a<='Z'?a-'A':a-'a'+26);       //用0～25代表大写字母，用26～52代表小写字母         b = (b>='A'&&b<='Z'?b-'A':b-'a'+26);         printf("a = %d, b = %d\n", a, b);   /*check a, b*/         if(map[a][b]!=0&&t>map[a][b]){      //如果a，b此前已经录入过，则比较a，b之间道路的距离，录入距离短的             continue;         }         map[a][b] = t;  //a-b距离为t         map[b][a] = t;  //b-a距离为t         check[a] = 1;  //标记a，b农场此时已经被写入map         check[b] = 1;     } }  出现段错误是因为数组下标越界，导致数组下标越界的是因为输入的数据不能和a, b, c对上号，对不上号的原因是%c比较特殊，因为它会匹配上次输入残留在输入缓存里的换行符'\n'； 解决办法详见上面的代码; 另外，判断是不是下标越界导致的段错误，可以打出a, b的值。  a = (a>='A'&&a<='Z'?a-'A':a-'a'+26);       //用0～25代表大写字母，用26～52代表小写字母         b = (b>='A'&&b<='Z'?b-'A':b-'a'+26); 这两行代码只能接收'a' ~'z'或'A' ~'Z'的字母，其他字符就很可能导致下标越界；

printf里面的%和变量的一一对应关系 scanf里面的%和变量以及变量前加不加&的一一对应关系 是C代码中非常容易出错的地方，而且通常编译还不出错。 所以在编译源代码之前值得专门仔细检查一遍甚至多遍。  在每个最后不带\n的printf后面加fflush(stdout); 在每个不想受接收缓冲区旧内容影响的scanf前面加rewind(stdin); 另外请检查scanf的返回值。 //请今后要用 char c; scanf("%c",&c); //时，都改为 char s[2]; char c; scanf("%1s",s); c=s[0]; //自动跳过一个或多个空格或Tab字符或回车换行，读取下一个字符。

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


Question: \b,\t和空格键  C语言

cprintf比printf更靠谱。

\t         光标向右跳到下一个Tab位置（如果Tab宽度约定为8，就是往右的下一个8*n+1处，从1开始数，n为整数） \b        退格（光标往左挪一个位置） 空格   空一格

没什么原理吧，如果找原理，那么就是标准规定，规定'\t', '\b', ' '的输出格式


Question: 请教一个基础习题所出现的问题

Linux:Ctrl+D Windows:Enter,Ctrl+Z,Enter

实测可以： 环境：windows 10            vs2017 commu.. 操作：ctrl c 和 ctrl z作为结束都可以达到目的

引用 3 楼 destory27 的回复:ctrl + z   ctrl + c 都可以 ctrl+c直接退出了，没有输出了。 Linux下使用ctrl + d, windows下使用ctrl+z输入EOF； 可以根据你的变成环境输入对应的组合键

linux中，ctrl-c好像也可以结束

ctrl + z   ctrl + c 都可以

结束键好像是ctrl + z 吧


Question: 新手求助

想了解更多，建议从网上搜一下缓冲区分类（行缓冲，全缓冲以及无缓冲）。

因为我们的输入是行缓冲，不输入回车我的输入的其他字符还在输入缓冲区里，没有进入内存里进行执行。所以，每次都需要输入回车才会将输入缓存里的字符刷到内存里，才会执行你的逻辑。


Question: 下面的代码运行后出现一堆乱码，请大神指导

#include<stdio.h>  double max(double a[3][5]);  int main(void) {     int i,j;     double ar[3][5];      printf("Please enter 3 couples of numbers and every includes 5 point-numbers:");     for(i=0;i<3;i++)     {         for(j=0;j<5;j++)             scanf("%lf", &ar[i][j]);         printf("Continue!\n");     }     for(i=0;i<3;i++)     {         for(j=0;j<5;j++)             printf(" %lf",ar[i][j]);         printf("\n");     }      double sum;     double total=0;     for(i=0;i<3;i++)     {         sum = 0;         for(j=0;j<5;j++)         {             sum = sum+ar[i][j];             total=total+ar[i][j];         }         printf("\nThe average of couple%d is %lf\n", i+1, sum/5);     }     printf("\nThe average of total is:%lf\n",total/15);     printf("\nThe maximum of these numbers is %f\n",max(ar));     printf("\nDONE!");      return 0; }  double max(double a[3][5]) {     int x,y;     double maximum = a[0][0];     for(x = 0; x < 3; x++)     {         for(y=0;y<5;y++)         {             if(a[x][y]>maximum)                 maximum=a[x][y];         }     }      return maximum; } 参考一下吧  主要是输入的格式应该用%lf。另外，输出时建议加上换行符'\n'

多谢大家了。

多谢大家了。

很明显是你格式化输入或者是格式化输出的时候有问题。 代码本身应该没有太大的问题，不然程序没法运行。

double型数据输入是scanf("%lf",&ar[i][j]); %f  改为%lf


Question: \b的用法

仅供参考：#include <conio.h> #include <stdio.h> char pw[40]; int i,ch; FILE *f; void main() { 	cprintf("\r\nPassword:"); 	i=0;pw[i]=0; 	while (1) { 		ch=getch(); 		if (ch==13 || i>=39) break; 		switch (ch)	{ 		case 27: 			cprintf("\rPassword: %40s"," "); 			cprintf("\rPassword: "); 			i=0;pw[i]=0; 			break; 		case 8: 			if (i>0) { 				i--; 				pw[i]=0; 				cprintf("\b \b"); 			} 			break; 		default: 			pw[i]=ch; 			i++; 			pw[i]=0; 			cprintf("*"); 			break; 		} 	} 	cprintf("\r\n"); 	f=fopen("password.txt","w"); 	fprintf(f,"%s\n",pw); 	fclose(f); }

你用的啥编译器？vc？ 建议你编译出汇编代码来看看，一般来说遇到古怪的问题从c这一级看不出什么问题可以到更低层看看怎么回事。

可能是编译环境不一样，\b的作用表现的也不一样

结果是一样的呢： 0 	1-2 >>0-1  2

cprintf


Question: 关于函数参数的疑问？

引用 8 楼 cfjtaishan 的回复:[quote=引用 7 楼 jianwen0529 的回复:] [quote=引用 5 楼 tmog66 的回复:] [quote=引用 3 楼 jianwen0529 的回复:] 默认参数，默认参数只能定义在函数声明或者定义中的其中一个，不能同时拥有。 因为h是作为接口的，通常大家有共识定义在函数声明那个地方，告诉使用者这里可以使用默认参数。如果在函数定义那里，接口使用者可能根本没机会知道可以使用默认参数 这个会提高程序的灵活性吗？我感觉这么用会降低程序的可读性呀。[/quote] 那是因为你读的代码不多，默认参数用得很广泛的[/quote] 是呀，第一次见这种用法。不太习惯，估计看多了就还好。

引用 7 楼 jianwen0529 的回复:[quote=引用 5 楼 tmog66 的回复:] [quote=引用 3 楼 jianwen0529 的回复:] 默认参数，默认参数只能定义在函数声明或者定义中的其中一个，不能同时拥有。 因为h是作为接口的，通常大家有共识定义在函数声明那个地方，告诉使用者这里可以使用默认参数。如果在函数定义那里，接口使用者可能根本没机会知道可以使用默认参数 这个会提高程序的灵活性吗？我感觉这么用会降低程序的可读性呀。[/quote] 那是因为你读的代码不多，默认参数用得很广泛的[/quote] 你说的是函数重载（C++）吗？如果是C语言编程没听说默认参数，只是有可变参数，但是可变参数又不是默认参数的概念。

引用 5 楼 tmog66 的回复:[quote=引用 3 楼 jianwen0529 的回复:] 默认参数，默认参数只能定义在函数声明或者定义中的其中一个，不能同时拥有。 因为h是作为接口的，通常大家有共识定义在函数声明那个地方，告诉使用者这里可以使用默认参数。如果在函数定义那里，接口使用者可能根本没机会知道可以使用默认参数 这个会提高程序的灵活性吗？我感觉这么用会降低程序的可读性呀。[/quote] 那是因为你读的代码不多，默认参数用得很广泛的

引用 3 楼 jianwen0529 的回复:默认参数，默认参数只能定义在函数声明或者定义中的其中一个，不能同时拥有。 因为h是作为接口的，通常大家有共识定义在函数声明那个地方，告诉使用者这里可以使用默认参数。如果在函数定义那里，接口使用者可能根本没机会知道可以使用默认参数 这个会提高程序的灵活性吗？我感觉这么用会降低程序的可读性呀。

引用 5 楼 tmog66 的回复:[quote=引用 3 楼 jianwen0529 的回复:] 默认参数，默认参数只能定义在函数声明或者定义中的其中一个，不能同时拥有。 因为h是作为接口的，通常大家有共识定义在函数声明那个地方，告诉使用者这里可以使用默认参数。如果在函数定义那里，接口使用者可能根本没机会知道可以使用默认参数 这个会提高程序的灵活性吗？我感觉这么用会降低程序的可读性呀。[/quote] 怎么回这么想呢？

.h文件中的定义告诉编译器：如果这个地方调用的时候没有填值，那么就给它填一个0进去。  至于.cpp，这个地方是必须要传入一个值的。

baidu 默认参数

这个是属于函数重载吧，看一下你的编译器是C++吗？C++支持函数重载


Question: 在B.h中定义一个结构体，在A.C中中使用该结构体报错提示Undefine

引用 楼主 执念丶丶的回复:多谢各位回答，已解决。 总结： 1、语法没错 2、程序结构有问题 问题如下： （1）我定义了一个head.h文件，所有的include都在这个.head文件下写着， （2）然后include 就不需要在其他.h文件中出现了，我在所有的.h中又引用了一下head.h文件 （3）这个问题导致head.h嵌套head.h文件，从而导致了 （4）另外，其他的.h文件，需要用到哪个.h就只引用哪个就行不需要引用太多。  多谢大家，卡了几个小时的问题终于解决了。
请问你的意思就是说head.h其实根本不需要吗

谢谢，很强，谢谢

head.h 中加入 #pragma once

引用 1 楼 user-5 的回复:我还是觉得是头文件加入的路径不对，再检查一下。 解决方法：反正程序也不大，要求也不多，索性直接在.c文件里定义吧。  头文件结构方式不对。所有的.h文件不需要重新引用head.h文件。否则导致了head.h嵌套head.h出错。

多谢各位回答，已解决。 总结： 1、语法没错 2、程序结构有问题 问题如下： （1）我定义了一个head.h文件，所有的include都在这个.head文件下写着， （2）然后include <head.h>就不需要在其他.h文件中出现了，我在所有的.h中又引用了一下head.h文件 （3）这个问题导致head.h嵌套head.h文件，从而导致了 （4）另外，其他的.h文件，需要用到哪个.h就只引用哪个就行不需要引用太多。  多谢大家，卡了几个小时的问题终于解决了。

引用 3 楼 cfjtaishan 的回复:把hw.config.h头文件加入到hw_config.c源文件里。 通过编译错误的提示，应该是hw_config.h没有找到BUFFER的声明 通过编译错误的提示，应该是hw_config.c没有找到BUFFER的声明

声明函数不需要加 extern，只有变量需要。 结构体中可以用 volatile 关键字吗？我不确定。 检查 BUFFER 这个名字是不是冲突了。


Question: VS怎么打断点，移动光标，在输出窗口显示结果

引用 2 楼 faihung 的回复:鼠标点击之后，直接F9就是断点、F11单步执行，F10 step over 、CTRL+F11 step out、CTRL+F10 直接跳到光标所在的行。好像编译器都是这样的。F5运行程序

这种满大街的答案百度就可以了！ 编辑界面，左侧空白栏点击或者F9打断点，F10单步调试，F11内部跟踪

引用 4 楼 fycmugua 的回复:我是先打断点，再按F9，光标是一行一行往下跳，但输出窗口没反应，只有跳到程序结束，窗口才一次性出现总的结果F9就是断点啊，为什么你打了断点后又按F9呢？ 你说的程序结束跳出结果那是说明你没有调出相应的窗口视图，在view里面可以选出来的。


Question: PHP的扩展回调PHP中的函数多参数的问题

学会使用grep（linux）和findstr（windows）命令

array 你用操作系统的搜索功能，就不必一个个打开了

引用 13 楼 xuzuning 的回复:在你的机器中搜索一下不就有了 不要说你没有 php 源码， php的源代码还真多，那个函数在哪个文件 哪个模块下呢

引用 9 楼 xuzuning 的回复:你不是写扩展码？ 那你就只看教程，不看现场? usort 是php 的 用户自定义排序函数，你在 php 源码中去找他的实现方法，不是比你看教程实际的多吗  可是我不知道usort  源码在哪里，  引用 13 楼 xuzuning 的回复:在你的机器中搜索一下不就有了 不要说你没有 php 源码， 我机器上有刚好最近编译安装。但是没有也正常呀，我不是高PHP的，而是最近需要给别人做个PHP的扩展包住我们的lib'库而已

引用 20楼xuzuning 的回复:你们用快捷安装的 php 是没有源码的，应到 php 官网去下载 写扩展没有源码包是不行的，编译不了我有源码，可是我找不到那个函数，能告诉我怎么找吗

引用 16 楼 xuzuning 的回复:array 你用操作系统的搜索功能，就不必一个个打开了 我在php-7.2.0\ext\standard\tests\array 文件夹里面看到 一堆.phpt 和几个不是想要的.c文件，没有看到我想要的

引用 17 楼 zhao4zhong1 的回复:学会使用grep（linux）和findstr（windows）命令  系统下可以查文档里面的某字符（不是文件名）？ 比如：usort

看源码，usort 的回调就是两个参数的

引用 1 楼 user-3 的回复:是否可将参数变为数组形式，数组里面存放各个参数php里面的吗？ 我试过$args=array(110,120,"hello",15); 单这样做不行，应该扩展中call_function的源码需要做相应的修改吧

是否可将参数变为数组形式，数组里面存放各个参数

在你的机器中搜索一下不就有了 不要说你没有 php 源码，

引用 9 楼 xuzuning 的回复:你不是写扩展码？ 那你就只看教程，不看现场? usort 是php 的 用户自定义排序函数，你在 php 源码中去找他的实现方法，不是比你看教程实际的多吗  可是我不知道usort  源码在哪里，我不是做PHP的 我只是这几天需要做这个事情，顺便看了下

引用 5 楼 bandaoyu 的回复:发现了一些线索，希望有人能比我早研究出来：  http://blog.csdn.net/zhyl8157121/article/details/53032997     应该是第二个参数这里控制后面的参数个数和参数类型："ss"，"s|s"     参数  对应C里的数据类型  b   zend_bool  l   long  d   double  s   char*, int 前者接收指针，后者接收长度  r   zval*  a   zval*  o   zval*  O   zval*, zend_class_entry*  z   zval*  Z   zval**  http://blog.csdn.net/leonpengweicn/article/details/12946993?%3E  补充资料：https://my.oschina.net/jackin/blog/172926 ZEND_API int call_user_function_ex(     HashTable *function_table,     zval **object_pp,     zval *function_name,     zval **retval_ptr_ptr,     zend_uint param_count,     zval **params[],     int no_seperation,     HashTable *symbol_table TSRMLS_DC); params is an array of pointers to zval pointers. Note: this is _not_ a PHP/zval array, it is a C array. Example:  zval *foo; zval *bar; zval **params[2]; params[0] = &foo; params[1] = bar;


Question: 如何用C语言获取服务器的路由表信息

route print >>result.txt

router >> 文件

引用 2 楼 paschen 的回复:http://blog.csdn.net/itcastcpp/article/details/8183859 谢谢。 GetIpForwardTable这个API好像是windows下的？ 我在linux下没有找到这个接口的描述。

最笨和最简单的方法就是字符解析吧，可以考虑将route命令执行的结果重定向到一个文件里，然后再根据路由表的格式进行读文件解析

引用 2 楼 paschen 的回复:http://blog.csdn.net/itcastcpp/article/details/8183859 这个要保存，好好看看。不知道Linux下怎么做？

直接运行cmd->router 获取输出！ 具体方式参考 http://bbs.csdn.net/topics/392313123

调用linux系统函数system，并获取返回值即可。


Question: 这个语句时间复杂度是多少？

如果 N趋近于无穷大是， pow(2,i)+pow(w,i-1)+.... 和 pow(2*i) 需要求二者商的极限, 极限为1 ，可以认为时间复杂都相同.

引用 10 楼 weixin_40281816 的回复:[quote=引用 7 楼 zilaishuichina 的回复:] 计算一下你的i的变化就知道了  1    初始值 2    第一次i*=2之后 3    第一次i++之后      pow(2,2) - 1 6    第二次i*=2之后  7    第二次i++之后      pow(2,3) - 1 14  第三次i*=2之后 15  第三次i++之后      pow(2,4) - 1 30  第四次i*=2之后 31  第四次i++之后      pow(2,5) - 1   所以时间复杂度就是  log2(n)    这样算好像不大对，  第一次：i=1 第二次：i=2+1 第三次：i=pow(2,2)+pow(2,1)+1 第四次：i=pow(2,3)+pow(2,2)+pow(2,1)+1 ...... 第i+1次： pow(2,i)+pow(w,i-1)+.....  这次算下来，应该是：pow(2,i)+pow(w,i-1)+.....<n,   求i,  但这i怎么求呀？[/quote]   第一次：i=1                     这是初始值  第二次：i=2+1                 不就是pow(2,1) + 1么  ，  不就是pow(2,2) - 1么 第三次：i=pow(2,2)+pow(2,1)+1                               不就是pow(2,3) - 1么 第四次：i=pow(2,3)+pow(2,2)+pow(2,1)+1               不就是pow(2,4) - 1么 第i+1次： pow(2,i)+pow(2,i-1)+.....                            不就是pow(2,i+1) - 1么   ......

上面算式有错误，但结果正确，懒得改了！

1  2*1=2+0               2  2*(2+1)=2*2+2; 3  2*(2*2+2)=2*2*2+4 4  2*(2*2*2+4)=2*2*2*2+8 5  2*(2*2*2+2+8)=2*2*2*2*2+16 .... N  2^N+2*(N-1) 最后 求 lim(( 2^N+2*(N-1)) / 2^N)=1 因此 时间复杂度 等于 O(lgN)

引用 7 楼 zilaishuichina 的回复:计算一下你的i的变化就知道了  1    初始值 2    第一次i*=2之后 3    第一次i++之后      pow(2,2) - 1 6    第二次i*=2之后  7    第二次i++之后      pow(2,3) - 1 14  第三次i*=2之后 15  第三次i++之后      pow(2,4) - 1 30  第四次i*=2之后 31  第四次i++之后      pow(2,5) - 1   所以时间复杂度就是  log2(n)    这样算好像不大对，  第一次：i=1 第二次：i=2+1 第三次：i=pow(2,2)+pow(2,1)+1 第四次：i=pow(2,3)+pow(2,2)+pow(2,1)+1 ...... 第i+1次： pow(2,i)+pow(w,i-1)+.....  这次算下来，应该是：pow(2,i)+pow(w,i-1)+.....<n,   求i,  但这i怎么求呀？

时间复杂度和循环次数是相关的。计算一下循环次数就可以知道时间复杂度了

http://www.cppblog.com/haosola/archive/2013/11/06/204115.aspx 和你想知道的的基本上一样

O(logN)

O(log n)

O(lgN)

i*=2;      n-1次   O（n）

i*=2;      n-1次   O（n）

i*=2;      n-1次   O（n）


Question: c编程入门 如何打印大于长度大于5个字符的所有输入行

仅供参考：#include <stdio.h> #include <string.h> #define MAXLEN 1000 char ln[MAXLEN]; FILE *f; int i,z; int b,n,L; int main(int argc,char **argv) {     if (argc<2) {         printf("Usage:%s fullpathfilename.ext\nget total blank/non-blank/total linenumbers.\n",argv[0]);         return 1;     }     f=fopen(argv[1],"r");     if (NULL==f) {         printf("Can not open file [%s]!\n",argv[1]);         return 2;     }     z=0;     b=0;     n=0;     L=0;     while (1) {         if (NULL==fgets(ln,MAXLEN,f)) break;         L=strlen(ln);         if ('\n'==ln[L-1]) {             if (0==z) {                 for (i=0;i<L-1;i++) {                     if (!(' '==ln[i] || '\t'==ln[i])) break;                 }                 if (i<L-1) z=1;//当前行不是空行             }             if (0==z) b++; else n++;             z=0;         } else {             if (0==z) {                 for (i=0;i<L;i++) {                     if (!(' '==ln[i] || '\t'==ln[i])) break;                 }                 if (i<L) z=1;//当前行不是空行             }         }     }     fclose(f);     if (L>0 && '\n'!=ln[L-1]) {         if (0==z) b++; else n++;//最后一行末尾无'\n'也计算     }     printf("File:[%s] total blank/non-blank/total linenumbers is %d/%d/%d\n",argv[1],b,n,b+n);     return 0; }

从代码的角度看不出来你要做什么？要实现什么。


Question: 请问各位大神，怎么利用libHaru库生成划线的pdf文件

建议先找到该库的说明，如果有readme可以看readme，找该库的接口说明


Question: 请问在Ubuntu 17 服务器里面，用它带的C编译器怎么写程序可以读出键盘上方向键的左键和右键？

这个问题后来查了资料用 curses.h解决了，谢谢大家的帮助！

引用 2 楼 ipqtjmqj 的回复:装下ncurses库, 链接时加上-lncurses, 写法参考https://stackoverflow.com/questions/10463201/getch-and-arrow-codes 谢谢你的提示，很有帮助！ 但是我看了你下面的“解决ubuntu中vi不能正常使用方向键和退格键的问题”的链接准备安装完整版的vim的时候，虽然能删除原来的vim common版，但是不能安装完整版的vim,连接外网一直报错： Err:1 http://it.archive.ubuntu.com/ubuntu zesty/main i386 vim-common all 2:8.0.0095-1ubuntu3 404 Not Found怎么办？你是怎么用apt-get的？

引用 3 楼 youyiyang 的回复:[quote=引用 2 楼 ipqtjmqj 的回复:] 装下ncurses库, 链接时加上-lncurses, 写法参考https://stackoverflow.com/questions/10463201/getch-and-arrow-codes 谢谢你的提示，很有帮助！ 但是我看了你下面的“解决ubuntu中vi不能正常使用方向键和退格键的问题”的链接准备安装完整版的vim的时候，虽然能删除原来的vim common版，但是不能安装完整版的vim,连接外网一直报错： Err:1 http://it.archive.ubuntu.com/ubuntu zesty/main i386 vim-common all 2:8.0.0095-1ubuntu3 404 Not Found怎么办？你是怎么用apt-get的？[/quote] 那是CSDN的外链接，不是我们给你的回答。目前，CSDN这样做很烦人，什么都给提示，提示有时候也是驴唇不对马嘴

这个问题，一般人回答不了你。你最正确的做法应该是去查系统API。


Question: 这个是通过字符串s1和s2判断坏键的问题，我不太明白这个里面hashtable的作用，最好说得简单易懂一点，求指导。

引用 4 楼 u012844474 的回复:是的，是用来判断字符串1中的字符， 有没有在字符串2中出现过，  输出未出现过的字符，求指导，这个hashtable[c1]=1是什么意思？ hashtable是数组，下表是对应的字符（在字符1中出现的也在字符串2出现的字符），下表对应的值为0或1，若为0则说明没出现过，若为1说明是出现过。 下表就是其出现的字符。

什么叫坏键。。。。    你贴的这段代码， 应该是用来判断字符串1中的字符， 有没有在字符串2中出现过，  输出未出现过的字符

百度搜相关关键字。


Question: 我想在里面加一个前序遍历的函数..用来打印族谱 求大佬教一下

《算法精解（C语言描述）》


Question: VC6.0中的RC资源文件怎么打不开，求解

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

左侧选项栏，选择 “ResourceView” 选项

其实是打开了 因为rc是空的啊

VC++ 2005以上版本，右击rc文件，可以选择打开方式，默认是图形化编辑方式打开的，所以你看不到资源源代码。  VC++ 6.0，貌似只能在资源浏览器中编辑。

rc文件可以在资源视图中打开

rc文件一般不直接编辑，在资源视图中创建各种资源  右键--打开代码可查看里面内容


Question: 一个C语言常见的例题

//编写嵌套循环显示下面的输出内容： //0 //01 //012 //0123 //01234 //012345 //01234 //0123 //012 //01 //0 #include <stdio.h> #define abs(a) ((a)>=0?(a):(-(a))) int main() {     for (int i=-5;i<=5;i++) printf("%.*s\n",6-abs(i),"012345");     return 0; }


Question: 交换指针（直接赋值）与交换字符串（字符串复制函数）的区别，为什么下面1不能用字符串复制函数和2为什么两种都可以用？谢谢。

引用 2 楼 cfjtaishan 的回复:主要是看传入函数sort内的实参是指针数组，还是二维字符数组。如果实参是字符指针数组，那么没问题，可以用直接交换指针的形式实现字符串排序，若是二维字符数组，那么就只能用交换字符串实现字符串排序；  char*str[10]={NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL}; 没必要这么初始化，这样一样可以实现将所有指针初始化 char*str[10]={NULL}; 初始化了一个，后面都是默认初始化位0（void *)

把一个值传进一个函数，函数中修改了这个值，函数返回后值不变 同理！把一个指针传给一个函数，函数中修改了这个指针的地址，函数返回后这个指针指向的地址，不变！


Question: 有关指针和初始化的问题

t==(bintree*)malloc(sizeof(bintree));是什么？==是比较运算符

下面一个是对的，因为它传递的是一个指针指向的值，在整个过程中指针的本身的值（地址）并没有改变。 上面一个是错的，是因为你在main函数中的地址值以形参的形式传递过去，而之后你却又重新malloc一块内存（这里地址应该是不一样的），改变了指针本身的地址，所以是错的。

void change(bintree** t) {     *t==(bintree*)malloc(sizeof(bintree));     (*t)->num=123; } 因为t是局部变量，它不能将申请到的空间和赋值的123带到main函数里。但是若用二重指针就可以了。因为使用二重指针，形参指向的是main函数里的b，对*t申请空间和对t的num元素赋值就是对main函数里的b变量申请空间（其实就是将堆上申请的空间首地址给了b）和赋值 调用时注意b前加&

上面的代码是不行的， 因为函数是按值传递的 直接对指针操作，只能修改指针的值 要对指针进行修改，就需要使用指针的指针

前者t==(bintree*)malloc(sizeof(bintree)); 这里==应该是=，但就算这样，也是错的，因为你函数参数是按值传递的，你函数中的参数只是外面的一个复制品，你将申请的内存赋值给它并不会影响到main中的变量t，后者是对的，因为你函数中并没有修改指针的值，而是修改指针指向的内存中的值


Question: linux下c语言字符串指针问题

其实电脑开机后物理内存的每个字节中都有值且都是可读写的，从来不会因为所谓的new、delete或malloc、free而被创建、销毁。区别仅在于操作系统内存管理模块在你读写时是否能发现并是否采取相应动作而已。操作系统管理内存的粒度不是字节而是页，一页通常为4KB。

“多一少一”问题占程序员常犯错误的10%以上！ 避免“多一少一”问题的方法之一是将比如<10甚至<5的数代入程序片断，掰手指头心算验证一下程序到底应该写为 x、x-1、x+1中的哪个？ <、<=、==、>、>=中的哪个？

首先越界访问本身就会出现未定义行为。就是出现的结果是随机的，当然你可以根据结果来推断可能的执行方向，但是这个不是一定出现的。比如在我的Linux环境下执行的结果是： before, i=0	after, i=0 before, i=1	after, i=1 before, i=2	after, i=2 before, i=3	after, i=3 before, i=4	after, i=4 before, i=5	after, i=5 before, i=6	after, i=6 before, i=7	after, i=7 before, i=8	after, i=8 before, i=9	after, i=9 welcome...   因此不要做越界访问的操作

引用 3楼faihung 的回复:首先，c的ASCII码的值为99 其次，你前面定义变量区域，发现没有dest［3］之后，就是int i了。 其实这里就是一个栈区间，根据入栈的顺序，dest［3］之后就是变量i了。 所以&dest3就是&i。因为dest数组越界，所以就会影响到i的值，i前一刻还是3，这里就会变成99了。

试着输出dest[3] 和 i的地址比较 应该相同

数组越界 将c赋给越界的位置 也就是i i=c  = 99


Question: 建立一个指针数组，存储n种颜色的单词，然后把它们按字典序排序后输出。      我怎么出现了这样子，哪里错了

-------可以了

#include <stdio.h> #include <stdlib.h> #include <string.h>  int main() { 	int n, i, j; 	char **str, *c;    	while(scanf("%d", &n) != EOF) 	{ 		str = (char **)malloc(sizeof(char *) * n); 		if (!str) { 			fprintf(stderr, "malloc error!\n"); 			exit(0); 		} 		for(i = 0; i < n; i++) 		{ 			str[i] = (char *)malloc(sizeof(char) * 80); 			if (!str[i]) { 				fprintf(stderr, "malloc error!\n"); 				exit(0); 			} 			scanf("%s", str[i]); 		} 		for (i = 0;i < n - 1; i++) 		{ 			for (j = 0; j < n - i - 1; j++) { 				if(strcmp(str[j], str[j+1]) > 0) { 					c = str[j]; 					str[j] = str[j+1]; 					str[j+1] = c; 				} 			} 		} 		putchar(10); 		for(i=0;i<n;i++) { 			printf("%s\n", str[i]); 			free(str[i]); 		} 		free(str); 	} 	return 0; }  for(int j=0;j<n-i;j++) j < n - i会导致越界； 字符串比较应该用strcmp

j<n-i    i=0时   j最大为n-1

j+1 最大可能是n 越界了


Question: C语言中直接常量是不是表达式的一种

引用 1 楼 cfjtaishan 的回复:http://blog.csdn.net/astrotycoon/article/details/50857326 这个博客似乎可以回答你的问题  好的。之前在百度文库看到一篇PPT，里面讲表达式必须要有运算符。现在知道了，谢谢啦


Question: C语言time库time()函数源码问题

Return value  Current calendar time encoded as time_t object on success, (time_t)(-1) on error. If arg is not a null pointer, the return value is also stored in the object pointed to by arg.

(time_t) -1 表示的是出错的情况，此时这个值不作为一个时间，你可以检没函数返回值，如果为(time_t)(-1)表示函数执行失败。  http://en.cppreference.com/w/c/chrono/time

baidu一下 time_t; struct tm; time()函数 和gmtime（）函数 另外给你一段代码，比较一下p1,p2,t1,t2 是否相等，另外两次cout输出是否一样！ tm *p1,*p2; 	time_t t1,t2; 	t1= time(NULL); 	cout<<ctime(&t1)<<endl; 	t2= time(NULL); 	cout<<ctime(&t2)<<endl; 	p1 = gmtime(&t1); 	p2 = gmtime(&t2);


Question: C语言运行突然变得很慢，请问这是为什么？

是啊 不只是你运行C++ 程序比较慢吧 比如打个游戏怎么样 任务管理器看一下CPU、内存使用情况

能慢到这么夸张， 那应该是所有的程序运行都慢吧

事件查看器里面看一下系统事件中有没有硬盘读写坏块相关事件。 关闭UAC、防火墙、杀毒软件 以管理员身份运行 ……

是品牌机的正规售后吗，那应该不会换你的配件。

无profiler不要谈效率！！尤其在这个云计算、虚拟机、模拟器、CUDA、多核 、多级cache、指令流水线、多种存储介质、……满天飞的时代！

告诉你一个恐怖的事，怕不是店家把你硬盘换了个旧的哦！！！哈哈。你自己换个系统再看看嘛。

是不是因为电脑坏了影响了性能。不知道你说的电脑坏了一次，是哪方面出了问题。另外，新装的c++编译器和上次的是同一个版本吗？


Question: 有关C语言文件的操作求助

#include <stdio.h> #include <stdlib.h>   int main(void) { 	FILE *in, *out; 	 	in = fopen("./stdin", "r"); 	if(in == NULL){ 		exit(-1); 	}  	out = fopen("./stdout", "a"); 	if(out == NULL){ 		exit(-1); 	}  	int ch, cnt = 0; 	while((ch = fgetc(in)) != EOF){ 		(void)fputc(ch, out);  		if(ch == '$'){ 			cnt++; 		} 	}  	(void)fclose(in); 	(void)fclose(out);  	printf("\'$\' exsit %d times\n", cnt);  	return 0; }  '$' exsit 3 times

也学习到了！

以文本方式读写，因为根据你题目要求，需要读入和写入的都是文本，此外，ch = getchar()并不是从文件中读取字符，而是从控件台读取，你可以使用fgetc

#include <stdio.h> #include <stdlib.h>  int main() { 	/* 	FILE *fp; 	FILE *fp2; 	fp2 = fopen("stdout","a+");  	char count=48; 	char ch; 	if((fp=fopen("stdin","wb+"))==NULL) { 		printf("can not open the file"); 		exit(0); 	} 	*/ 	int count = 0, ch;  	ch = getchar(); 	while (ch != EOF) 	{ 		fputc(ch, stdout); 		ch = getchar(); 		if(ch == '$') 			count++; 	} 	printf("%d\n", count); 	/* 	fclose(fp); 	fclose(fp2); 	*/ 	return 0; }  标准输入输出已经是打开状态，不需要再打开。 标准输入比如键盘，标准输出比如终端，显示器等。


Question: 这是一个按照数学成绩排列学生信息的程序，xcode里面运行时bad access

“多一少一”问题占程序员常犯错误的10%以上！ 避免“多一少一”问题的方法之一是将比如<10甚至<5的数代入程序片断，掰手指头心算验证一下程序到底应该写为 x、x-1、x+1中的哪个？ <、<=、==、>、>=中的哪个？

此外student[i + 1]已经越界了，当是为N的时候，i可以为N-1，student[i + 1]则为student[N]，越界了，有效索引值只是0~N-1

for (int j = N;j > 0;j++) 这里应该是j--吧

#include<string.h> #include<iostream> //#include<vector> #include<stdio.h> #include<stdlib.h>  using namespace std;  void bubble_sort(struct students student[],int s);  struct students{ 	char a[32]; 	int math; 	int computer; };  int main() { 	int N; 	printf("Please input the number of the students:\n"); 	scanf("%d",&N); 	struct students *student; 	//struct students student[N]; 	student=(struct students*) malloc(N*sizeof(struct students)); 	for(int i=0;i<N;i++) 	{   printf("Please input the information of the %d th student",i+1); 		scanf("%s%d%d",student[i].a,&student[i].math,&student[i].computer); 		printf("\n"); 	} 	struct students temp; 	for(int j = N;j>0;j--) 		for(int i = 0;i < j-1;i++) { 			printf("i = %d\n", i); 			if(student[i].math > student[i+1].math)    //就是这句话bad access 			{ 				temp=student[i]; 				student[i]=student[i+1]; 				student[i+1]=temp; 			} 		}  	for(int i=0;i<N;i++) 	{ 		printf("%s  %d  %d",student[i].a,student[i].math,student[i].computer); 		printf("\n"); 	} 	return 0; }  参考一下吧  出现的原因是因为地址越界； for(int j=N;j>0;j++) 看一下这个循环，j是从N开始，但是j还是j++;很明显已经越界了。 另外：    for(int i=0;i<j;i++)  这个地方也越界，比如当j=N时， i < j即i < N;那么交换时i+1就会越界。


Question: 新人，请教各位~~帮我看看程序哪里错了

#include <stdio.h>  int s(int *a[],int n);  int main(void) { 	int a[4][3]={{1,2,3},{4,5,6},{7,8,9}}; 	int *b[12]; 	int k = 0; 	for(int i = 0; i < 4; i++) 	{ 		for(int j = 0; j < 3; j++) 		{ 			b[k] = &a[i][j]; 			k++; 		} 	}   	int sum; 	sum=s(b,12); 	printf("%d ",sum); 	return 1; } int s(int *a[],int n) { 	int i,sum = 0;  	for(i = 0; i < n; i++) { 		printf("%d\t", *a[i]); 		sum += *a[i]; 	} 	return sum; } 参考一下； 数组下表是从0开始不是从1开始。出现异常，主要是数组越界。

C语言中数组下标从0开始.....

#include <stdio.h> int s(int a[],int n); int main(void) { 	int a[3][3]={{1,2,3},{4,5,6},{7,8,9}}; 	int *b[9]; 	int k=1; 	for(int i=1;i<4;i++) 	{ 		for(int j=1;j<3;j++) 		{ 			b[k]=&a[i][j]; 			k++; 		} 	}  	 	int sum; 	sum=s(*b,9); 	printf("%d ",sum); 	return 0; } int s(int a[],int n) { 	int i,sum=1; 	for(i=1;i<n;i++) 	{sum+=a[i];} 	return sum; } 改成这样，编译通过 但结果显示（段错误，核心已转储）

你4行3列的数组怎么变成了，3行3列的。


Question: c 语言 malloc  写入数据

p[0] = "aaaaa";得到的地址其实是常字符串"aaaaa"的地址。不是你malloc出来的内存地址. 另外就是变量的作用域的问题了.  最后想说一句，楼主写代码还是要先释放下内存，再置为NULL

引用 3 楼 qq_21193563 的回复:malloc后最好要对malloc分配的内存进行初始化，因为malloc分配得到的是一个虚拟地址，不一定会有指向的物理地址，而malloc,后然后用memset对其进行初始化后就一定会有对应的物理内存。详细自己看看系统内存管理。  这句话“malloc,后然后用memset对其进行初始化后就一定会有对应的物理内存”有歧义吧，那么这么说不用memset，就不能往malloc申请的空间里写数据，那么用malloc做啥呢？ 虚拟内存和物理内存有一个映射，这是由于MMU做的。我们看到虚拟内存（连续的内存）在物理内存上可能不是连续的，但是malloc的空间也是对应物理内存的（虚拟内存比物理内存大也是有可能的，MMU会通过其他方式换页，使用磁盘空间也好，都是有对应物理内存的）

从createcontent函数的两种赋值（写入）方法，没发现有什么问题，问题应该不是出在这个函数的写入操作里。建议查一下其他的函数。  另外，建议将错误信息贴出来之外，也将代码贴出来，这样定位问题会更全面一些。

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


Question: 为什么要加#ifdef __cplusplus ？

答案是贾可说的： 源码扩展名如果如果是 c 或 cc 时，也就是必须按 C 语言来解释。如果 extern "C" 不报错的话，那编译器就有问题。一个正常的 C 编译器都不应该支持 extern "C" 这种写法。

同样的问题，应该就是.c文件不能这么用

引用 16 楼 SXJIAKE 的回复:源码扩展名如果如果是 c 或 cc 时，也就是必须按 C 语言来解释。如果 extern "C" 不报错的话，那编译器就有问题。一个正常的 C 编译器都不应该支持 extern "C" 这种写法。果真如此

如果是c语言就不需要加extern "C" 吧，应该是有些C编译器不支持extern "C" ，嗯嗯

主要是为了兼容性，当然还有其它

如果按照C++编译/或者是C++工程，那么就用extern "C"进行导出。否则（C）不需要使用这个

_cplusplus 应该是按照c++的方式编译！

引用 3楼勤奋的执着 的回复:你这篇帖子的推荐里的链接~  http://blog.csdn.net/y511374875/article/details/72846266 http://blog.csdn.net/u012234115/article/details/43272441我不是问这个，我是问为什么加ifdefine那一句，为什么不直接extern C

引用 5楼paschen 的回复:C语言里没有 extern "C" { 这种用法嗯，不过我在gcc下也编得过去。可能这样写是因为某些编译器编不过吧

C语言里没有 extern "C" { 这种用法

引用 2 楼 bandaoyu 的回复:[quote=引用 1 楼 cfjtaishan 的回复:] https://www.cnblogs.com/stonecrazyking/archive/2006/09/23/512552.html http://www.cppblog.com/ownwaterloo/archive/2009/04/20/predefined_macro___cplusplus.html  答非所问[/quote] 那好吧，请其他人来回答你的所问。

引用 1 楼 cfjtaishan 的回复:https://www.cnblogs.com/stonecrazyking/archive/2006/09/23/512552.html http://www.cppblog.com/ownwaterloo/archive/2009/04/20/predefined_macro___cplusplus.html  答非所问

引用 13楼自信男孩 的回复:[quote=引用 8 楼 bandaoyu 的回复:] [quote=引用 3楼勤奋的执着 的回复:]你这篇帖子的推荐里的链接~  http://blog.csdn.net/y511374875/article/details/72846266 http://blog.csdn.net/u012234115/article/details/43272441我不是问这个，我是问为什么加ifdefine那一句，为什么不直接extern C[/quote] 别人给你推荐的链接为啥不看呢，链接里除了回答你的问题之外，还有其他知识。非要针对你的问题，来一个专场博客你才喜欢呢。 两个问题：一个问题是如何去寻找答案（路径），一个是如何在在大量信息中找出自己需要的答案。这个都需要自己亲力亲为的去做，而不是坐享其成[/quote]嗯，你的其中的一篇文章才有说明，但我要的就只是那一句话而已，其他整篇内容都是多余的，我又不是不知道为什用extern C。另外一篇对我来说通票废话。为了一句话让我看2篇文章，简直不能忍。  另外我在gcc下 直接extern C 通过了……这才是导致我问这个问题的原因

引用 8 楼 bandaoyu 的回复:[quote=引用 3楼勤奋的执着 的回复:]你这篇帖子的推荐里的链接~  http://blog.csdn.net/y511374875/article/details/72846266 http://blog.csdn.net/u012234115/article/details/43272441我不是问这个，我是问为什么加ifdefine那一句，为什么不直接extern C[/quote] 别人给你推荐的链接为啥不看呢，链接里除了回答你的问题之外，还有其他知识。非要针对你的问题，来一个专场博客你才喜欢呢。 两个问题：一个问题是如何去寻找答案（路径），一个是如何在在大量信息中找出自己需要的答案。这个都需要自己亲力亲为的去做，而不是坐享其成

如果你用 C 编译器来编译， extern "C" 是错误的语法。 她只能使用 extern 。

应该是有些C编译器不认识extern “C”


Question: c/c++ 编程求教

浮点数格式 http://bbs.csdn.net/topics/390676437

引用 2 楼 user-3 的回复:因为你的b是float类型，float的有效位数（不是小数位数）只有7~8位，你用double就正常了一语惊醒梦中人...

楼主说的是小数点第3位吧，为什么.789变成.781。我也很好奇，下面一个就是正确的，b的精度是浮点型的。


Question: 求大神帮忙啊，文件的读取与链表

引用 7 楼 cfjtaishan 的回复:#include <stdio.h> #include <stdlib.h> #include <string.h> //#include <conio.h>  typedef struct exams {     int num;     char question[30];     char a[10];     char b[10];     char c[10];     char d[10];     char ans[30]; }exams_obj, *exams_handle;  typedef struct test {     exams_obj exam;     struct test *next; }tests;  tests *add_exams_list(tests **pphead) {     int choice;     tests *pnew, *prev, *pcur;     pnew = (tests *)malloc(sizeof(tests));     if (!pnew) {         fprintf(stderr, "malloc error!\n");         exit(0);     }     printf("请开始添加试题!\n");      prev = *pphead;     if (prev) {         pcur = prev->next;         while (pcur) {             prev = pcur;             pcur = pcur->next;         }     }      while(1) {         printf("请输入题号:\n");         scanf("%d", &pnew->exam.num);         printf("第%d题题干为:\n", pnew->exam.num);         scanf("%s", pnew->exam.question);         printf("请输入A:\n");         scanf("%s", pnew->exam.a);         printf("请输入B:\n");         scanf("%s", pnew->exam.b);         printf("请输入C:\n");         scanf("%s", pnew->exam.c);         printf("请输入D:\n");         scanf("%s", pnew->exam.d);         printf("请输入答案(a,b,c,d)\n");         scanf("%s", pnew->exam.ans);         if (!(*pphead)) {             *pphead = pnew;             prev = *pphead;         } else {             prev->next = pnew;             prev = pnew;         }         pnew = (tests *)malloc(sizeof(tests));         if (!pnew) {             fprintf(stderr, "malloc error!\n");             exit(0);         }         printf("是否继续添加题目(0/1)(0退出，1继续)\n");         scanf("%d", &choice);         if (choice == 0)             break;     }      prev->next = NULL;     free(pnew);      printf("添加成功!\n");      return (*pphead); }  tests *remove_exams_list(tests **pphead) {     test *pcur, *prev;     int num;     printf("请输入你想删除的题目的序号:\n");     scanf("%d",&num);     prev = *pphead;     if(num == 1) {         prev = *pphead;         *pphead = (*pphead)->next;         free(prev);         printf("删除成功!");         return(*pphead);     }     pcur = prev->next;     while (pcur) {         if (pcur->exam.num == num) {             prev->next = pcur->next;             free(pcur);             break;         }         pcur = pcur->next;     }     printf("删除成功!");     return(*pphead); }  tests *modify_exams_list(tests **pphead)//更改题目 {     int num;     tests *pcur = *pphead;;     printf("请输入你想更改的题目的题号:\n");     scanf("%d", &num);      while (pcur) {         if(pcur->exam.num == num)             break;         pcur = pcur->next;     }     if (!pcur) {         fprintf(stdout, "Can't find the number!\n");         return *pphead;     }     printf("请输入第%d题的题干:\n",num);     scanf("%s",pcur->exam.question);     printf("请输入A:\n");     scanf("%s",pcur->exam.a);     printf("请输入B:\n");     scanf("%s",pcur->exam.b);     printf("请输入C:\n");     scanf("%s",pcur->exam.c);     printf("请输入D:\n");     scanf("%s",pcur->exam.d);     printf("请输入答案(a,b,c,d)\n");     scanf("%s",pcur->exam.ans);     printf("更改成功!\n");      return(*pphead); }  void load_exams_list(tests **pphead) {     FILE *fp;     tests *pnew, *prev = *pphead;      if (!(fp = fopen("tests2.txt","r"))) {         printf("can not open file\n");         return;     }     pnew = (tests *)malloc(sizeof(tests));     if (!pnew) {         fprintf(stderr, "malloc error!\n");         exit(0);     }     if (1 != fread(&pnew->exam, sizeof(exams_obj), 1, fp)) {         free(pnew);         return;     }     if (!(*pphead)) {         *pphead = pnew;         prev = *pphead;     } else {         prev->next = pnew;         prev = pnew;     }      while (!feof(fp)) {         pnew = (tests *)malloc(sizeof(tests));         if (!pnew) {             fprintf(stderr, "malloc error!\n");             exit(0);         }         if (1 != fread(&pnew->exam, sizeof(exams_obj), 1, fp))             break;         prev->next = pnew;         prev = pnew;     }      prev->next = NULL; }  void show_exams_list(tests *phead) {     tests *pcur = phead;      while (pcur) {         printf("第%d题\nquestion:%s\nA.%s\nB.%s\nC.%s\nD.%s\nanswer:%s\n",                 pcur->exam.num, pcur->exam.question, pcur->exam.a,                 pcur->exam.b, pcur->exam.c, pcur->exam.d, pcur->exam.ans);         pcur = pcur->next;     } }  void save_exams_list(tests *phead) {     FILE *fp;     tests *pcur;      fp = fopen("tests2.txt","w");     if (!fp) {         fprintf(stderr, "open file error!\n");         return;     }      pcur = phead;     while (pcur) {         if (fwrite(&pcur->exam, sizeof(exams_obj), 1, fp) != 1)             printf("file write error!\n");         pcur = pcur->next;     }     printf("保存成功!\n按回车键返回!\n");     fclose(fp); }  void menu(void) {     printf("                            ^^^^^^^***^^^^^^^\n");     printf("                    ------- 欢迎进入考试系统 -------\n");     printf("                         ^^^^^ 1:题目管理 ^^^^^\n");     printf("                           *** 2:开始考试 ***\n");     printf("                             ~ 3:退出系统 ~\n");     printf("                           ^^^^^^^***^^^^^^^\n"); }  void submenu(void) {     printf("                        *-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\n");     printf("                        *          1:添加题目         *\n");     printf("                        *          2:修改题目         *\n");     printf("                        *          3:删除题目         *\n");     printf("                        *          4:显示题目         *\n");     printf("                        *          5:保存题目         *\n");     printf("                        *          6:返回主菜单       *\n");     printf("                        *-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*\n"); }  void manage_exams(tests **pphead) {     int choice;      while (1) {         submenu();         printf("Please input your choice: ");         scanf("%d", &choice);          switch (choice) {             case 1:                 add_exams_list(pphead);                 break;              case 2:                 modify_exams_list(pphead);                 break;              case 3:                 remove_exams_list(pphead);                 break;              case 4:                 show_exams_list(*pphead);                 break;              case 5:                 save_exams_list(*pphead);                 break;              case 6:                 return;              default:                 printf("Input error!\n");         }     } }  int main() {     tests *phead = NULL;      load_exams_list(&phead);      int choice;     while (1) {         menu();         printf("Please input your choice: ");         scanf("%d", &choice);         switch (choice) {             case 1:                 manage_exams(&phead);                 break;              case 2:                 break;              case 3:                 exit(0);                 break;              default:                 printf("Input error!\n");                 break;         }     }     return 0; }  如果让我去做这个题目，我会考虑这样实现；还有很多地方需要优化，包括数据结构的定义，函数的调用等等；  参考一下吧 如果想继续做编程，建议还是要学好基础知识  谢谢大神

推荐使用WinHex软件查看硬盘或文件或内存中的原始字节内容。  不要把 fopen("...","...");fscanf,fprintf,fgets,fgetc,fclose //读时把\r\n替换成\n，写时把\n替换成\r\n;读到\x1a就设置EOF;读写的内容当字符看待 和 fopen("...","...b");fseek,ftell,fread,fwrite,fgetc,fclose //不作以上替换，遇到\x1a仍继续读;读写的内容当字节看待 弄混了

#include<stdio.h> #include<stdlib.h> #include<string.h> #include<conio.h>  #define LEN sizeof(struct Test)  struct Test { 	int num; 	char que[100]; 	char a[30]; 	char b[30]; 	char c[30]; 	char d[30]; 	char ans[30]; 	struct Test *next; }; typedef struct Test Test; Test *head=NULL; //保存试题  void save(Test *head) { 	system("cls"); 	FILE *fp; 	Test *p; 	p=head; 	if(p==NULL)  	{ 		printf("无法保存文件!\n"); 		printf("输入任意键返回上一级\n");          getch();         Mmenu2();		 	} 	fp=fopen("Test.dat","wb"); 	while(p!=NULL) 	{ 		fwrite(&p,LEN,1,fp); 		p=(*p).next; 	} 	fclose(fp); 	printf("保存成功！\n") ; 	printf("输入任意键返回上一级\n");      getch();     Mmenu2();		 } //查看题目  void print() {        system("cls");     FILE *fp;     Test *p;     if((fp=fopen("Test.dat","rb"))==NULL) 	{ 		printf("无法打开文件!\n"); 		printf("输入任意键返回上一级\n");          getch();         Mmenu2();		 	} 	else 	{    	    fp=fopen("Test.dat","rb"); 		rewind(fp); 	    printf("数据加载成功!\n"); 	    fread(&p,LEN,1,fp); 		while(p!=NULL)         {            	printf("题号：");             printf("%d\n",(*p).num);             printf("问题：");             printf("%s\n",(*p).que);             printf("A选项：");             printf("%s\n",(*p).a);             printf("B选项：");             printf("%s\n",(*p).b);             printf("C选项：");             printf("%s\n",(*p).c);             printf("D选项：");             printf("%s\n",(*p).d);             printf("答案：");             printf("%s\n",(*p).ans);             p=(*p).next;         } 	} 	fclose(fp);  	printf("输入任意键返回上一级\n");      getch();     Mmenu2();      } //新增题目  Test *add(Test *head) { 	system("cls"); 	int i; 	head=NULL; 	Test *p1,*p2; 	p1=p2=(Test *)malloc(LEN); 	printf("请输入题号："); 	scanf("%d",&(*p1).num); 	printf("请输入问题："); 	scanf("%s",(*p1).que); 	printf("请输入A选项："); 	scanf("%s",(*p1).a); 	printf("请输入B选项："); 	scanf("%s",(*p1).b); 	printf("请输入C选项："); 	scanf("%s",(*p1).c); 	printf("请输入D选项："); 	scanf("%s",(*p1).d); 	printf("请输入答案："); 	scanf("%s",(*p1).ans); 	printf("添加成功！\n\n");  	while(1) 	{ 		if((*p1).num==1) 		{ 			head=p1; 		} 		else 		{ 			(*p2).next=p1; 			p2=p1; 		} 		printf("是否继续添加？ 1.是 2.退出\n"); 		scanf("%d",&i);		 		if(i==2) break; 		p1=(Test *)malloc(LEN); 		printf("请输入题号："); 	    scanf("%d",&(*p1).num); 	    printf("请输入问题："); 	    scanf("%s",(*p1).que); 	    printf("请输入A选项："); 	    scanf("%s",(*p1).a); 	    printf("请输入B选项："); 	    scanf("%s",(*p1).b); 	    printf("请输入C选项："); 	    scanf("%s",(*p1).c); 	    printf("请输入D选项："); 	    scanf("%s",(*p1).d); 	    printf("请输入答案："); 	    scanf("%s",(*p1).ans); 	    printf("添加成功！\n\n");  	} 	(*p2).next=NULL;     return(head); } //删除题目 Test *del(Test *head) { 	system("cls");  	int num; 	Test *p1,*p2; 	p1=head; 	if(p1==NULL) 	{ 		printf("没有已添加题目!\n"); 		printf("输入任意键返回上一级\n");          getch();         Mmenu2();		 	} 	printf("输入需要删除的题号:"); 	scanf("%d",&num); 	if(num==1) 	{ 		head=(*p1).next; 		free(p1); 		printf("删除成功!\n"); 		return(head); 	} 	while(1) 	{ 	 	if(p1->next->num==num) break; 		else p1=(*p1).next;     } 	if((*p1).next!=NULL) 	{ 		p2=(*p1).next; 		(*p1).next=(*p2).next; 		free(p2); 		printf("删除成功!\n"); 	}      return(head); } //修改题目  Test *cha(Test *head)  { 	system("cls");  	int num; 	Test *p1; 	p1=head; 	if(p1==NULL) 	{ 		printf("没有已添加题目!\n"); 		printf("输入任意键返回上一级\n");          getch();         Mmenu2();		 	} 	printf("输入需要更改的题号:"); 	scanf("%d",&num); 	while(1) 	{ 		if((*p1).num==num) break; 		p1=(*p1).next; 	} 	printf("请输入问题：",num); 	scanf("%s",(*p1).que); 	printf("请输入A选项："); 	scanf("%s",(*p1).a); 	printf("请输入B选项："); 	scanf("%s",(*p1).b); 	printf("请输入C选项："); 	scanf("%s",(*p1).c); 	printf("请输入D选项："); 	scanf("%s",(*p1).d); 	printf("请输入答案："); 	scanf("%s",(*p1).ans); 	printf("更改成功!\n");     return(head); } //主菜单 void Mmenu1() { 	    system("cls"); 	    int n; 		printf("************************************************\n"); 	    printf("\t\t欢迎进入考试系统!\n");  	    printf("\t\t1.题目管理\n"); 	    printf("\t\t2.开始考试\n"); 	    printf("\t\t3.退出\n");  	    printf("************************************************\n"); 	    printf("请输入你的选择：");  	    scanf("%d",&n); 	    switch(n)         { 		    case 1:Mmenu2();break; 		    case 2:Mmenu3();break; 		    case 3:system("cls");printf("感谢您的使用！\n");exit(0); 		    default:system("cls");printf("输入错误，输入任意键返回上一级！\n");getch();Mmenu1(); 	      } } //题目管理菜单  void Mmenu2() { 	    system("cls"); 	    int n; 		printf("************************************************\n"); 	    printf("\t\t1.新增题目\n");  	    printf("\t\t2.删除题目\n"); 	    printf("\t\t3.修改题目\n"); 	    printf("\t\t4.查看题目\n"); 	    printf("\t\t5.保存题目\n"); 	    printf("\t\t6.返回上一级\n"); 	    printf("************************************************\n"); 	    printf("请输入你的选择："); 		scanf("%d",&n); 	    switch(n) 	    { 		    case 1:head=add(head);Mmenu2();break; 		    case 2:head=del(head);printf("输入任意键返回上一级\n");getch();Mmenu2();break; 		    case 3:head=cha(head);printf("输入任意键返回上一级\n");getch();Mmenu2();break; 		    case 4:print();break;  		    case 5:save(head);break;  		    case 6:Mmenu1();break;  		    default:system("cls");printf("输入错误，输入任意键返回上一级！\n");getch();Mmenu2();  	      } } //开始考试菜单 void Mmenu3() { 	 }  int main() { 	Mmenu1(); 	 	return 0; }

引用 3 楼 ck823718831 的回复:[quote=引用 2 楼 cfjtaishan 的回复:] 删除上一个帖子，然后重新发帖，那么别人回复的内容有没有思考和尝试呢。 还是建议好好学习吧，不要等到期末考试或要编程做项目时再来临时抱佛脚； 本来链表就是比较难理解和使用的地方，对指针要求比较高。 不好意思，上一个帖子的回复还没看到就被删除了。 项目要求添加完题目后要保存到文件，关闭程序后，重新打开可直接读取文件数据。[/quote] 但是从这个需求上没说，要在显示的时候去读文件，因此，显示就是显示，通过遍历链表输出即可，加载文件内容，可以在main函数第一件事情去做，不论文件有没有，存不存在。

引用 2 楼 cfjtaishan 的回复:删除上一个帖子，然后重新发帖，那么别人回复的内容有没有思考和尝试呢。 还是建议好好学习吧，不要等到期末考试或要编程做项目时再来临时抱佛脚； 本来链表就是比较难理解和使用的地方，对指针要求比较高。 不好意思，上一个帖子的回复还没看到就被删除了。 项目要求添加完题目后要保存到文件，关闭程序后，重新打开可直接读取文件数据。

void look(test*head)//显示题目 { system("cls"); FILE *fp;     test*p;     if((fp=fopen("tests2.txt","r"))==NULL)     {      printf("can not open file\n");      fclose(fp); } while(p!=NULL) { fread(p,sizeof(tests),1,fp); printf("第%d题\nquestion:%s\nA.%s\nB.%s\nC.%s\nD.%s\nanswer:%s\n",p->num,p->question,p->a,p->b,p->c,p->d,p->ans); p=p->next; } fclose(fp); printf("试题显示完成!\n按回车键返回!\n"); getch(); menu2(); }  问题出在p是野指针，没有分配空间呢。我记得在另一个帖子里已经回复这个问题了。 再说你定义形参head做什么？定义了，没有用。 个人认为，程序启动时，就要先从文件里去读（若文件存在并有数据，否则链表头为NULL）；显示题目功能，只需要遍历链表输出即可，没必要从文件里读，因为最新数据应该是在内存里，而非文件里。


Question: 关于进程同步。。

引用 1 楼 paschen 的回复:比如使用事件,CreateEvent  我的前提是这两个进程都会维护同一个数据结构，也就是说如果进程A在干别的事情时，进程B会往这个数据结构里添加节点，当进程A再次操作该数据结构时，他能感知到进程B往这个数据结构上添加到节点。

《Windows核心编程》 《Unix编程艺术》

可以考虑一下信号量，若是两个进程间同步，可以用互斥信号量，其实和锁机制类似的，适用于进程间同步和线程间同步； 若是多进程间通信，可以考虑PV操作  https://www.cnblogs.com/bizhu/archive/2012/05/17/2506285.html

引用 2 楼 JerKii的回复:[quote=引用 1 楼 paschen 的回复:] 比如使用事件,CreateEvent  我的前提是这两个进程都会维护同一个数据结构，也就是说如果进程A在干别的事情时，进程B会往这个数据结构里添加节点，当进程A再次操作该数据结构时，他能感知到进程B往这个数据结构上添加到节点。[/quote] 共享内存那就只有使用内存映射机制，可配合其他同步方法如事件、信号量等

加锁同步，信号量 等

用共享锁控制，只有获得共享锁的句柄才能使用共同的资源

比如使用事件,CreateEvent


Question: spintf格式化double类型怎样保证小数精度准确？

你自己应该知道自己需要多少位精度，在满足需要的情况下尽可能少输出 比如你举的第一个例子，实际上输出小数点后14位应该就不错了 普通应用很少有需要这么多小数位的精度要求

sprintf_s(buf, "%.2f", d);

double类型的数据应该用%lf输出。  精度本身就是有有效值的。

1、很多十进制浮点数在二进制本身就没法精确表示，要精确表示可用BCD等方式存储，所以浮点数本身就是会存在精度误差的  2、如果不加%.n控件符的话默认就只有那么多位，你可以通过%.n设置你希望的值

引用 3 楼 zhao4zhong1 的回复:%.15g


Question: 结构体被强制转换问题？？？求解  谢谢！！！！！！

引用 1 楼 cfjtaishan 的回复:不一定需要一样。  efg_t* BBB= (efg_t*)( (char*)AAA+ 2 ); 这个操作是AAA指向的内存向后偏移2个字节，然后把地址赋值给指针BBB;为什么是偏移2个字节呢，因为AAA在偏移前做了强制类型转换char *，否则偏移的长度就不是2了，而是sizeof(abc_t) * 2个字节了。  另外赋值的是内存首地址，因为不论是abc_t类型的指针，还是efg_t的指针，都是存放的地址值，因此不能说BBB编程AAA，而是AAA偏移2个字节的地址赋值给了BBB，这样BBB就可以按照efg_t类型去访问这块地址。若AAA指向的的空间小于BBB的空间，在使用BBB访问结构体成员时会导致越界。因此，需要AAA指向有效内存空间需要比BBB的结构体类型长度要大，至少大于等于sizeof(abc_t) - 2分析的很全面，学习了。

非常感谢层主，但是还有点小疑问，应该是至少大于等于sizeof(efg_t) + 2吧？？？ 因为最终转换是要转换为efg_t类型，因此应该是要满足sizeof（abc_t）>=（efg_t）+2 ， +2是因为考虑到AAA偏移了两个字节。

AAA给地址到BBB，不是表示BBB变成了AAA，而是按BBB的方式去解释AAA内存中的值，对于你的例子，(char*)AAA+ 2是AAA地址后面2个字节的位置，这个位置强制转换成了BBB结构体指针，这个地址可以是任意数据，但通常情况下应该刚好是个BBB类型的成员

http://edu.csdn.net/course/detail/2344 C语言指针与汇编内存地址-一.代码要素


Question: 为什么fwrite写入的用fread读出再打印是乱码

电脑内存或文件内容或传输内容只是一个一维二进制字节数组及其对应的二进制地址； 人脑才将电脑内存或文件内容或传输内容中的这个一维二进制字节数组及其对应的二进制地址的某些部分看成是整数、有符号数/无符号数、浮点数、复数、英文字母、阿拉伯数字、中文/韩文/法文……字符/字符串、汇编指令、函数、函数参数、堆、栈、数组、指针、数组指针、指针数组、数组的数组、指针的指针、二维数组、字符点阵、字符笔画的坐标、黑白二值图片、灰度图片、彩色图片、录音、视频、指纹信息、身份证信息……   推荐使用WinHex软件查看硬盘或文件或内存中的原始字节内容。  不要把 fopen("...","...");fscanf,fprintf,fgets,fgetc,fclose //读时把\r\n替换成\n，写时把\n替换成\r\n;读到\x1a就设置EOF;读写的内容当字符看待 和 fopen("...","...b");fseek,ftell,fread,fwrite,fgetc,fclose //不作以上替换，遇到\x1a仍继续读;读写的内容当字节看待 弄混了

引用 2 楼 自信男孩的回复:#include<stdio.h> #include <stdlib.h> #include <string.h> #include <errno.h>  typedef struct data { 	char xuehao[12]; 	char xingming[6]; 	int math; 	int wuli; 	int yuwen; 	int huaxue; }DA;  int main() { 	DA student[50]; 	DA student1[50]; 	int i=0; 	FILE *fp = fopen("D:\\zuoye\\stu.txt","r"); 	if (!fp) { 		fprintf(stderr, "Open file error: %s\n", strerror(errno)); 		exit(0); 	}  	while(!feof(fp)) 	{ 		fscanf(fp,"%s%s%d%d%d%d\n", 				student[i].xuehao, 				student[i].xingming, 				&student[i].math, 				&student[i].wuli, 				&student[i].yuwen, 				&student[i].huaxue); 		i++; 	} 	//打印信息  	for(i=0;i<30;i++) { 		printf("%s  %s  %d  %d  %d  %d\n", 				student[i].xuehao, 				student[i].xingming, 				student[i].math, 				student[i].wuli, 				student[i].yuwen, 				student[i].huaxue); 	} 	fclose(fp); 	FILE *fp1 = fopen("D:\\zuoye\\stu.dat","w"); 	if (!fp1) { 		fprintf(stderr, "Open file error: %s\n", strerror(errno)); 		exit(0); 	}  	/* 	for(i=0;i<30;i++) 		fwrite(&student[i], sizeof(DA), 1, fp1); 		*/ 	fwrite(student, sizeof(DA), 30, fp1); 	fclose(fp1);  	FILE *fp2 = fopen("D:\\zouye\\stu.dat","r"); 	if (!fp2) { 		fprintf(stderr, "Open file error: %s\n", strerror(errno)); 		exit(0); 	}  	for(i=0;i<30;i++) 	{ 		fread(&student1[i],sizeof(DA),1,fp2); 		printf("%s  %s  %d  %d  %d  %d\n", 				student1[i].xuehao, 				student1[i].xingming, 				student1[i].math, 				student1[i].wuli, 				student1[i].yuwen, 				student1[i].huaxue); 	}  	fclose(fp2); } 参考一下吧  有两个地方需要注意： 第一个地方，fscanf读，如果你的txt文件是每个学生信息占一行，那么fscanf读取时注意加'\n'； 第二个地方，也是主要的错误所在。fwrite没问题，一次性写了30个学生信息到文件中，但是读的时候有问题了，因为不是一次读30个学生信息，而是一次读一个学生信息，因此fread的第一个参数应该是&student1[i]，而不是student1. 建议自己思考一下fread的第一个参数应该是什么 我又写了一边读二进制形式的文本代码，发现一样的代码，新的代码可以读出，谢谢大神了

建议对文件的打开做判断，并且使用strerror(errno)会对调试有很大的帮助

求大神给解答，我很困扰啊。。。。。


Question: 一段c语言代码转换为c#代码

uint8_t = byte uint16_t= ushort


Question: 对C语言sqrt函数的一些的疑问

浮点数格式 http://bbs.csdn.net/topics/390676437

浮点数的比较是否相等是两个浮点数相减得到的差值的绝对值小于1e-6即表示两个浮点数相等；

浮点数的计算是有精度误差的，不要直接比较两数是否相等，应该比较两数的差的绝对值是否足够小，如小于1e-6