Question: 是浮点误差问题？

问题基本上是解决了，谢谢大家的解答！结贴啦

引用 6 楼 zy205817 的回复: #include <stdio.h>  int main() {     float a = 4.01;     int b;     b = a * 100;     printf("%d\n",b);     printf("%d\n",(int)(4.01 * 100));     return 0; }  double只是近似值 那float也是吧，只是精度不同了，换成float恰好从400变成401了（可能就是5楼所说的原因），不过如果再改一下，4.01换成1.01，问题还是存在的，以下代码： #include<stdio.h> int main() {     float a=1.01;     int b,n,m;     b=a*100;     printf("%d\n",b);     printf("%d\n",(int)(1.01*100)); } 输出为： 100 101 ——————五楼说的有道理——————

引用 11 楼 zjq9931 的回复:[quote=引用 10 楼 BensonLaur 的回复:] [quote=引用 2 楼 user-7 的回复:] 简单地说，浮点数无法精确表示4.01，只能表示成4.010000001或者4.009999999 上面这两个数只是距离，准确的说，浮点数无法精确表示任何“不等于2的-n次方的整数倍的小数” 那printf("%d\n",b);     printf("%d\n",(int)(4.01*100)); 这两句的结果感性来讲应该是结果相同的吧，结果不同也有点费解，这是不是因为5楼最后一句说的呢——“......这种误差无法预测，不同的编译器，或者不同的机器环境，使用不同的运算顺序、汇编指令运算，所以相同的代码，结果也是不能预测的”[/quote] 个人感觉最好看一下汇编代码，看看着两个句子在你的编译器中生成的汇编代码又什么不同。[/quote] 嗯嗯

引用 10 楼 BensonLaur 的回复:那printf("%d\n",b);     printf("%d\n",(int)(4.01*100)); 这两句的结果感性来讲应该是结果相同的吧，结果不同也有点费解，这是不是因为5楼最后一句说的呢——“......这种误差无法预测，不同的编译器，或者不同的机器环境，使用不同的运算顺序、汇编指令运算，所以相同的代码，结果也是不能预测的” [quote=引用 2 楼 user-7 的回复:] 简单地说，浮点数无法精确表示4.01，只能表示成4.010000001或者4.009999999 上面这两个数只是距离，准确的说，浮点数无法精确表示任何“不等于2的-n次方的整数倍的小数”[/quote] 个人感觉最好看一下汇编代码，看看着两个句子在你的编译器中生成的汇编代码又什么不同。

那printf("%d\n",b);     printf("%d\n",(int)(4.01*100)); 这两句的结果感性来讲应该是结果相同的吧，结果不同也有点费解，这是不是因为5楼最后一句说的呢——“......这种误差无法预测，不同的编译器，或者不同的机器环境，使用不同的运算顺序、汇编指令运算，所以相同的代码，结果也是不能预测的” 引用 2 楼 user-7 的回复:简单地说，浮点数无法精确表示4.01，只能表示成4.010000001或者4.009999999 上面这两个数只是距离，准确的说，浮点数无法精确表示任何“不等于2的-n次方的整数倍的小数”

哦，我用的是codeblocks下的mingw，系统是32位的。 引用 3 楼 zxh707wk 的回复:gcc编译都是401的说。。。

我用的是codeblocks下的mingw，系统是32位的。  引用 1 楼 zjq9931 的回复:用的什么编译器？我用的VC6都是401啊？你用的64位的编译器？ [quote=引用 楼主 BensonLaur 的回复:] #include<stdio.h> int main() {     double a=4.01;     int b;     b=a*100;     printf("%d\n",b);     printf("%d\n",(int)(4.01*100));  } 输出的结果是： 400 401  谁知道这是什么原因呀，有人说是因为“浮点误差”，并在表达式 b=a*100;上边加了 1e-7 (1的-7次方) 就解决了误差问题了，也就是赋值的那一句改为 b=a*100+1e-7,  结果就是了： 401 401  可我还是不知道为什么呀，哪位能够说个具体缘由来么 [/quote]

浮点数在计算机中无法精确存储，比如说你放到变量里的是20.000000，它就可能是20.000001或19.99999什么的，总之一般都不会精确存储

不要拿整数和浮点数直接运算，应该都转换成浮点数，最后四舍五入得到整数。  浮点误差主要是两个，一个是二进制数无法表示某些十进制数表示有限小数的数。好比3进制的1.1，相当于十进制的4/3，十进制就没法用有限小数表示。另一个是浮点数计算本身有误差，单精度浮点数运算大致只能取7位有效小数，而且多次运算会丢失更多精度。最后，这种误差无法预测，不同的编译器，或者不同的机器环境，使用不同的运算顺序、汇编指令运算，所以相同的代码，结果也是不能预测的。

同意二楼，浮点数本来就不能精确存储

gcc编译都是401的说。。。

用的什么编译器？我用的VC6都是401啊？你用的64位的编译器？ 引用 楼主 BensonLaur 的回复:#include<stdio.h> int main() {     double a=4.01;     int b;     b=a*100;     printf("%d\n",b);     printf("%d\n",(int)(4.01*100));  } 输出的结果是： 400 401  谁知道这是什么原因呀，有人说是因为“浮点误差”，并在表达式 b=a*100;上边加了 1e-7 (1的-7次方) 就解决了误差问题了，也就是赋值的那一句改为 b=a*100+1e-7,  结果就是了： 401 401  可我还是不知道为什么呀，哪位能够说个具体缘由来么


Question: winmain与字符集

Locale Use the setlocale function to change or query some or all of the current program locale information. “Locale” refers to the locality (the country and language) for which you can customize certain aspects of your program. Some locale-dependent categories include the formatting of dates and the display format for monetary values. For more information, see Locale Categories.   Locale-Dependent Routines   Routine  Use setlocale Category  Setting Dependence  atof, atoi, atol Convert character to floating-point, integer, or long integer value, respectively LC_NUMERIC  is Routines Test given integer for particular condition. LC_CTYPE  isleadbyte Test for lead byte () LC_CTYPE  localeconv Read appropriate values for formatting numeric quantities LC_MONETARY, LC_NUMERIC  MB_CUR_MAX Maximum length in bytes of any multibyte character in current locale (macro defined in STDLIB.H) LC_CTYPE  _mbccpy Copy one multibyte character LC_CTYPE  _mbclen Return length, in bytes, of given multibyte character LC_CTYPE  mblen Validate and return number of bytes in multibyte character LC_CTYPE  _mbstrlen For multibyte-character strings: validate each character in string; return string length  LC_CTYPE  mbstowcs Convert sequence of multibyte characters to corresponding sequence of wide characters LC_CTYPE  mbtowc Convert multibyte character to corresponding wide character LC_CTYPE  printf functions Write formatted output LC_NUMERIC (determines radix character output)  scanf functions Read formatted input LC_NUMERIC (determines radix character recognition)  setlocale, _wsetlocale Select locale for program Not applicable  strcoll, wcscoll Compare characters of two strings LC_COLLATE  _stricoll, _wcsicoll Compare characters of two strings (case insensitive) LC_COLLATE  _strncoll, _wcsncoll Compare first n characters of two strings  LC_COLLATE  _strnicoll, _wcsnicoll Compare first n characters of two strings (case insensitive) LC_COLLATE  strftime, wcsftime Format date and time value according to supplied format argument LC_TIME  _strlwr Convert, in place, each uppercase letter in given string to lowercase LC_CTYPE  strtod, wcstod, strtol, wcstol, strtoul, wcstoul Convert character string to double, long, or unsigned long value LC_NUMERIC (determines radix character recognition)  _strupr Convert, in place, each lowercase letter in string to uppercase LC_CTYPE  strxfrm, wcsxfrm Transform string into collated form according to locale LC_COLLATE  tolower, towlower Convert given character to corresponding lowercase character LC_CTYPE  toupper, towupper Convert given character to corresponding uppercase letter LC_CTYPE  wcstombs Convert sequence of wide characters to corresponding sequence of multibyte characters LC_CTYPE  wctomb Convert wide character to corresponding multibyte character LC_CTYPE  _wtoi, _wtol Convert wide-character string to int or long LC_NUMERIC

引用 3 楼 zhao4zhong1 的回复:_T("...")所有字符串我都加了这个的  其实我觉得用多字符集多省事，只要一个引号就搞定了，而且现在的系统一般都兼容两种字符集

正常情况不管切换unicode还是multibyte应该没事，可能你copy其它代码改动参数写法所以冒出了重载问题...

_tWinMain不是兼容两种字符集吗？我记得是吧


Question: 怎样用sizeof来表达结构中某一个字段的大小？

用减法 sizeof( INDEX ) - sizeof( int )    不就行了？ 鄙视赵老师刷分

#include <stdio.h> #define field_offset(s,f) (int)(&(((struct s *)(0))->f)) struct AD  { int a; char b[13]; double c;}; #pragma pack(push) #pragma pack(1) struct A1  { int a; char b[13]; double c;}; #pragma pack(2) struct A2  { int a; char b[13]; double c;}; #pragma pack(4) struct A4  { int a; char b[13]; double c;}; #pragma pack(8) struct A8  { int a; char b[13]; double c;}; #pragma pack(16) struct A16 { int a; char b[13]; double c;}; #pragma pack(pop) int main() {     printf("AD.a %d\n",field_offset(AD,a));     printf("AD.b %d\n",field_offset(AD,b));     printf("AD.c %d\n",field_offset(AD,c));     printf("\n");     printf("A1.a %d\n",field_offset(A1,a));     printf("A1.b %d\n",field_offset(A1,b));     printf("A1.c %d\n",field_offset(A1,c));     printf("\n");     printf("A2.a %d\n",field_offset(A2,a));     printf("A2.b %d\n",field_offset(A2,b));     printf("A2.c %d\n",field_offset(A2,c));     printf("\n");     printf("A4.a %d\n",field_offset(A4,a));     printf("A4.b %d\n",field_offset(A4,b));     printf("A4.c %d\n",field_offset(A4,c));     printf("\n");     printf("A8.a %d\n",field_offset(A8,a));     printf("A8.b %d\n",field_offset(A8,b));     printf("A8.c %d\n",field_offset(A8,c));     printf("\n");     printf("A16.a %d\n",field_offset(A16,a));     printf("A16.b %d\n",field_offset(A16,b));     printf("A16.c %d\n",field_offset(A16,c));     printf("\n");     return 0; } //AD.a 0 //AD.b 4 //AD.c 24 // //A1.a 0 //A1.b 4 //A1.c 17 // //A2.a 0 //A2.b 4 //A2.c 18 // //A4.a 0 //A4.b 4 //A4.c 20 // //A8.a 0 //A8.b 4 //A8.c 24 // //A16.a 0 //A16.b 4 //A16.c 24 // //

参考  1 楼的 得出这个，不知是否合适LZ #include <stdio.h>  typedef struct ST_INDEX { int offset; char c[4]; }INDEX;  void main() { 	INDEX A;  	printf("1: %d\n",sizeof(((INDEX*)0)->c));  	printf("2: %d\n",sizeof(A.c)); }

//  c++可以这么写，c语言就不太好搞了 #include "stdio.h" typedef struct _INDEX {  	int nlen; 	int offset; 	char c[4];  	_INDEX() 	{ 		nlen = sizeof(c); 	} }INDEX; void main() {  }

引用 5 楼 baichi4141 的回复:[quote=引用 4 楼 supermegaboy 的回复:] [quote=引用 1 楼 justin_bkdrong 的回复:] 使用宏就可以比如 #define INDEX_VAR_SIZE(name) sizeof(((INDEX*)0)->name)就可以达到您的要求。  (INDEX*)0->name实际上是错误行为，属于未定义行为。[/quote] sizeof内的表达式在编译时直接忽略的吧？[/quote]  晕，没留意前面有个sizeof，这里是没问题的。

(INDEX*)0->name 虽然表面看是一个取地址内的值,但是前面加入sizeof之后，这个地址不会被访问，而编译器仅仅取了INDEX 结构中的成员变量的大小。这个运行是完全正确的。

引用 4 楼 supermegaboy 的回复:[quote=引用 1 楼 justin_bkdrong 的回复:] 使用宏就可以比如 #define INDEX_VAR_SIZE(name) sizeof(((INDEX*)0)->name)就可以达到您的要求。  (INDEX*)0->name实际上是错误行为，属于未定义行为。[/quote] sizeof内的表达式在编译时直接忽略的吧？

引用 1 楼 justin_bkdrong 的回复:使用宏就可以比如 #define INDEX_VAR_SIZE(name) sizeof(((INDEX*)0)->name)就可以达到您的要求。  (INDEX*)0->name实际上是错误行为，属于未定义行为。

为什么要考虑外面的结构？你只是计算字段的大小，只考虑该字段就可以了吧，数组的大小可以=sizeof（char）*4 即sizeof（数组类型）*数组大小。

我个人想到的是这种办法：  #include<stdio.h>  typedef struct { 	int offset; }S_OFFSET; typedef struct { 	char c[4]; }S_C; typedef struct  { 	S_OFFSET offset; 	S_C c; }INDEX;  int main() { 	printf("%d\n", sizeof(S_C)); 	return 0; }  引用 楼主 screen12 的回复:比如有这样一个结构： struct INDEX { 	int offset; 	char c[4]; };  我现在想表达出第二个字段c[4]的大小，只能用它的一个具体的变量 INDEX index[10000];  然后用sizeof(index[0].c)来表示大小。  可是我觉得这样不是很方便，因为表达式比较长，而且还得具体到index[0]。  如果是整个结构的大小可以用sizeof(INDEX)来表达。可是它的一个字段用什么来表达大小比较方便呢？  sizeof(INDEX.c)好象非法？


Question: 数据精度问题，最后一位应该是0，却变成了1

浮点型 在计算机内存中 以32为存在内存中，也就是4个字节，后面0-22位是用来寸后面的小数部分的，你自己算下小数部分转化为二进制。是通过*2 ，直到基数部分为0 算下 0.29*2   基数为0 0.58*2      基数为1. 继续。。。。

不过这个是不能完全消除的，因为有些十进制的有限小数转换为二进制后会变成无限小数，有限位数的float、double总是会有精度的问题。最好的解决办法是限定一定精度四舍五入掉。4楼的方法其实也算一种四舍五入，因为printf会做这个

float只保证6到7位，超过7的其它范围不保证

引用 5 楼 zhao4zhong1 的回复:http://bbs.csdn.net/topics/390676437  找老师的回复太过高深，看不懂。。。

引用 4 楼 wu424602394 的回复:float形有效数字超过指定长度后,不能保证后面数字的精度，float和double的精度是由尾数的位数来决定的。  float的指数位有8位，而double的指数位有11位，分布如下：  float： 1bit（符号位） 8bits（指数位） 23bits（尾数位） double： 1bit（符号位） 11bits（指数位） 52bits（尾数位）  float：2^23 = 8388608，一共七位 double：2^52 = 4503599627370496一共16位 所以呢.. #include <stdio.h>  void main() { 	double f; 	scanf("%lf",&f);			 	printf("%f or %e\n",f,f);     return 0; }  恩恩，谢谢，的确可以。。。我开始也试过double，但是不行，对比你的代码，原因在  %lf  哈哈，原来如此。。。

某些数值的确会出现这种问题

引用 楼主 mao_miaoxi 的回复:  如图，第一个数据应该是21.290000的啊。。。 浮点数的这种问题，确实存在。即使换成double型的也是一样的。 所以判断两个浮点数相当，或者浮点数是否等于0，的程序一定要慎重。


Question: 求大神看一个链表建立的C语言

引用 3 楼 wwwzys 的回复:scanf("%d",m->grade);                  改写成             scanf("%d",&(m->grade));  楼上改的是对的，不过少改了  #include<stdio.h> #include<stdlib.h> typedef struct p{ char name[10]; int grade; int rank;  struct p *next; }STU; STU *s;   int input()//这里参数错误 {int n; printf("Please input the number of student"); reinput:scanf("%d",&n); if(n<1||n>10) {printf("mistake number,please reinput"); goto reinput; } else return n; }   void create(int n) {int i; STU *l; STU *m;  s=(STU*)malloc(sizeof(STU)); l=s;   for(i=0;i<n;i++) {m=(STU*)malloc(sizeof(STU)); printf("input the name:"); scanf("%s",m->name); printf("input the grade:"); scanf("%d",&(m->grade)); l->next=m; l=m;  } l->next=NULL;	//这里少了句  } void printp() {STU *l; l=s; l=l->next;//这里少了句 for(l;l!=NULL;l=l->next) {printf("name:%s,grade:%d\n",l->name,l->grade);}//最好加个换行\n或 \t }  main() {int num=0; num=input(); create(num); printp();  }

学会自己设断点调试。

是输入完第一个人名字和成绩。表述有误


Question: 求大神帮忙改下纯C语言实现的迷宫程序

再供参考#include <stdio.h> #include <stdlib.h> #include <conio.h> #include <graphics.h> int xs[10000]; int ys[10000]; int i=0,xx,yy; int fc,bc; void push(int x,int y) {     xs[i]=x;     ys[i]=y;     if (i<10000-1) {         i=i+1;     } else {         printf("stack overflow!\n");         exit(1);     } } void pop(void) {     i=i-1;     xx=xs[i];     yy=ys[i]; } int check(int x,int y) {     int c;      c=getpixel(x,y); /* 获取当前点的颜色 */     return ((c!=bc)&&(c!=fc));/* 如果颜色为边界色或填充色则不填充 */ } void seedfilling(int x,int y,int fill_color,int boundary_color) {     fc=fill_color;     bc=boundary_color;     push(x,y);     while (1) {         if (i<=0) return;         pop();         if (check(xx,yy)) {             putpixel(xx, yy, 14);getch();  /* 加上这行显示当前填充状态 */              putpixel(xx, yy, fill_color); /* 画点 */              if (check(xx-1,yy  )) push(xx-1,yy  );             if (check(xx  ,yy+1)) push(xx  ,yy+1);             if (check(xx  ,yy-1)) push(xx  ,yy-1);             if (check(xx+1,yy  )) push(xx+1,yy  );             /* 去掉下面四句就是四连通 */             if (check(xx-1,yy-1)) push(xx-1,yy-1);             if (check(xx-1,yy+1)) push(xx-1,yy+1);             if (check(xx+1,yy-1)) push(xx+1,yy-1);             if (check(xx+1,yy+1)) push(xx+1,yy+1);         }     } } void main() {     int a,b,color;     int gdriver = DETECT, gmode, errorcode;     int poly[10];      initgraph(&gdriver, &gmode, "d:\\bc\\bgi");     a=150;     b=140;     color=4;     poly[0]=110;/* 第一个点的x坐标以及y坐标 */     poly[1]=110;     poly[2]=200;/* 第二点 */     poly[3]=105;     poly[4]=170;/* 第三点 */     poly[5]=120;     poly[6]=150;/* 第四点 */     poly[7]=170;     poly[8]=110;/* 多边形的起点与终点一样 */     poly[9]=110;     drawpoly(5,poly);/* 显示各点连接起来的多边形 */      /* 保证边界对八连通是封闭的 */     setviewport(0,1,600,300,0);     drawpoly(5,poly);/* 显示各点连接起来的多边形 */     setviewport(1,0,600,300,0);     drawpoly(5,poly);/* 显示各点连接起来的多边形 */     setviewport(1,1,600,300,0);     drawpoly(5,poly);/* 显示各点连接起来的多边形 */      /* 恢复默认viewport */     setviewport(0,0,600,300,0);      seedfilling(a,b,color,15);  /* 种子填充多边形 */      getch();     closegraph(); }

仅供参考/**  * @Title  老鼠走迷宫  * @Author 孙琨  * @Date   2013-11-16  * @At     XUST  * @All Copyright by 孙琨  *  */  #include <iostream> using namespace std;  int maze[7][7] = { // 初始化迷宫，英文maze为“迷宫”     {2,2,2,2,2,2,2},     {2,0,0,0,0,0,2},     {2,0,2,0,2,0,2},     {2,0,0,2,0,2,2},     {2,2,0,2,0,2,2},     {2,0,0,0,0,0,2},     {2,2,2,2,2,2,2} };  int startI = 1,startJ = 1; // 入口行列坐标 int endI = 5,endJ = 5;     // 出口行列坐标 int success = 0;           // 判断路是否走通  int visit(int i,int j)  // 自动搜寻路径 {     maze[i][j] = 1;      if((i == endI) && (j == endJ))         success = 1;      if((success != 1) && (maze[i][j+1] == 0))  // 下         visit(i,j+1);     if((success != 1) && (maze[i+1][j]) == 0)  // 右         visit(i+1,j);     if((success != 1) && (maze[i][j-1] == 0))  // 上         visit(i,j-1);     if((success != 1) && (maze[i-1][j] == 0))  // 左         visit(i-1,j);      if(success != 1)         maze[i][j] = 0;      return success;  }  int main(void) {     int i,j;      cout << "显示迷宫: " << endl;     for(i=0; i<7; i++)     {         for(j=0; j<7; j++)         {             if(maze[i][j] == 2)                 cout << "■" ;             else                 cout << "  " ;         }         cout << endl;     }      if(visit(startI,startJ) == 0)     {         cout << endl << "没有找到出口!" << endl;     }     else     {         cout << endl << "显示路径: " << endl;         for(i=0; i<7; i++)         {             for(j=0; j<7; j++)             {                 if(maze[i][j] == 2)                     cout << "■";                 else if(maze[i][j] == 1)                     cout << "♀";                 else                     cout << "  ";             }             cout << endl;         }     }     return 0; }

引用 9 楼 zhao4zhong1 的回复:代码功能归根结底不是别人帮自己看或讲解或注释出来的；而是被自己静下心来花足够长的时间和精力亲自动手单步或设断点或对执行到某步获得的中间结果显示或写到日志文件中一步一步分析出来的。 提醒：再牛×的老师也无法代替学生自己领悟和上厕所！ 单步调试和设断点调试（VS IDE中编译连接通过以后，按F10或F11键单步执行，按Shift+F11退出当前函数；在某行按F9设断点后按F5执行停在该断点处。）是程序员必须掌握的技能之一。  崩溃的时候在弹出的对话框按相应按钮进入调试，按Alt+7键查看Call Stack里面从上到下列出的对应从里层到外层的函数调用历史。双击某一行可将光标定位到此次调用的源代码或汇编指令处。  谢谢赵老师。

引用 9 楼 zhao4zhong1 的回复:代码功能归根结底不是别人帮自己看或讲解或注释出来的；而是被自己静下心来花足够长的时间和精力亲自动手单步或设断点或对执行到某步获得的中间结果显示或写到日志文件中一步一步分析出来的。 提醒：再牛×的老师也无法代替学生自己领悟和上厕所！ 单步调试和设断点调试（VS IDE中编译连接通过以后，按F10或F11键单步执行，按Shift+F11退出当前函数；在某行按F9设断点后按F5执行停在该断点处。）是程序员必须掌握的技能之一。  崩溃的时候在弹出的对话框按相应按钮进入调试，按Alt+7键查看Call Stack里面从上到下列出的对应从里层到外层的函数调用历史。双击某一行可将光标定位到此次调用的源代码或汇编指令处。  赵老师说得对，现在自己已经解决了。

引用 9 楼 zhao4zhong1 的回复:代码功能归根结底不是别人帮自己看或讲解或注释出来的；而是被自己静下心来花足够长的时间和精力亲自动手单步或设断点或对执行到某步获得的中间结果显示或写到日志文件中一步一步分析出来的。 提醒：再牛×的老师也无法代替学生自己领悟和上厕所！ 单步调试和设断点调试（VS IDE中编译连接通过以后，按F10或F11键单步执行，按Shift+F11退出当前函数；在某行按F9设断点后按F5执行停在该断点处。）是程序员必须掌握的技能之一。  崩溃的时候在弹出的对话框按相应按钮进入调试，按Alt+7键查看Call Stack里面从上到下列出的对应从里层到外层的函数调用历史。双击某一行可将光标定位到此次调用的源代码或汇编指令处。  老师说的很对啊！

引用 5 楼 addsspu 的回复:[quote=引用 4 楼 zjq9931 的回复:] 语法错误给你改没了，但是逻辑错误得你自己查了。 谢谢，逻辑错误我目前查不出来啊，纠结中[/quote] 其实这个程序的逻辑我都没心思来看。这个有说明还好说，没有说明，你自己看吧。

引用 4 楼 zjq9931 的回复:语法错误给你改没了，但是逻辑错误得你自己查了。 谢谢，逻辑错误我目前查不出来啊，纠结中

语法错误给你改没了，但是逻辑错误得你自己查了。  //头文件SqStack.h #ifndef SQSTACK_H_ #define SQSTACK_H_  #ifndef constant #define constant  #define ElemType int #define OVERFLOW 0 #define OK 1 #define ERROR 0  typedef int Status;  #include <stdlib.h>  #endif /* constant */  typedef struct {     int x;     int y; }PosType;  typedef struct {     int ord;     PosType seat;     int di; }SElemType;  #define STACK_INIT_SIZE 100 #define STACKINCREMENT 10  typedef struct {     SElemType *base;     SElemType *top;     int stacksize; }SqStack;  Status InitStack_Sq(SqStack *S); Status CreateStack_Sq(SqStack *S,SElemType elem[],int n); Status DestroyStack_Sq(SqStack *S); Status ClearStack_Sq(SqStack *S); int EmptyStack_Sq(SqStack *S); int LengthStack_Sq(SqStack *S); Status GetTop_Sq(SqStack *S,SElemType *e); Status Push_Sq(SqStack *S,SElemType e); Status Pop_Sq(SqStack *S,SElemType *e);  #endif /* SQSTACK_H_ */ //栈实现，应该没有问题，测试过SqStack.c   #include "SqStack.h" int mutex; Status InitStack_Sq(SqStack *S){     if(mutex==1) {free(S->base);mutex=0;S->base=S->top=NULL;}     S->base=(SElemType *)malloc(STACK_INIT_SIZE*sizeof(SElemType));     if(!S->base) exit(OVERFLOW);     S->top=S->base;     S->stacksize=STACK_INIT_SIZE;     mutex=1;     return OK; }   Status CreateStack_Sq(SqStack *S,SElemType elem[],int n){     int i;     if(mutex==1) {free(S->base);mutex=0;S->base=S->top=NULL;}     S->base=(SElemType *)malloc((n/STACK_INIT_SIZE+1)*STACK_INIT_SIZE*sizeof(SElemType));     if(!S->base) exit(OVERFLOW);     S->top=S->base;     S->stacksize=STACK_INIT_SIZE*(n/STACK_INIT_SIZE+1);     mutex=1;     for(i=0;i<n;i++){         *S->top++=elem[i];     }     return OK; }   Status DestroyStack_Sq(SqStack *S){     if(mutex==1) {free(S->base);mutex=0;S->base=S->top=NULL;}     return OK; } Status ClearStack_Sq(SqStack *S){     S->top=S->base;     return OK; } int EmptyStack_Sq(SqStack *S){     return S->base==S->top; } int LengthStack_Sq(SqStack *S){     return S->top-S->base; } Status GetTop_Sq(SqStack *S,SElemType *e){     if(S->base==S->top)return ERROR;     *e=*(S->top-1);       return OK; }   Status Push_Sq(SqStack *S,SElemType e){     if(S->top-S->base>=S->stacksize){         S->base=(SElemType *)realloc(S->base,(STACK_INIT_SIZE+STACKINCREMENT)*sizeof(SElemType));         if(!S->base) exit(OVERFLOW);         S->top=S->base+S->stacksize;         S->stacksize=S->stacksize+STACKINCREMENT; }     *S->top++=e;     return OK; }   Status Pop_Sq(SqStack *S,SElemType *e){     if(S->top!=S->base)         *e=*--(S->top);     else         return ERROR;     return OK; }   //迷宫程序MazePath.c 不要求把迷宫路径，只要把路径压入栈中即可   #define M 8 #define N 8 #include "SqStack.h" #include <stdio.h>   PosType NextPos(PosType *pos,int di){     switch(di){     case 0:pos->x--;break;     case 1:pos->y++;break;     case 2:pos->x++;break;     case 3:pos->y--;break;     }     return *pos; }   Status MazePath(SqStack *S,int maze[][10],PosType start,PosType end){     PosType curpos=start;     int curstep=1;     SElemType e;     InitStack_Sq(S);//InitStack_Sq(&S);       do{           if(maze[start.x][start.y]==0){             e.ord=curstep;e.seat=curpos;e.di=1;             Push_Sq(S,e);//Push_Sq(&S,e);             if(curpos.x==end.x && curpos.y==end.y ) return OK;             curpos=NextPos(&curpos,1);             curstep++;         }         else{               if(!EmptyStack_Sq(S)){//if(!EmptyStack_Sq(&S)){                 Pop_Sq(S,&e);//Pop_Sq(&S,&e);                 while(e.di==4 && !EmptyStack_Sq(S)){//while(e.di==4 && !EmptyStack_Sq(&S)){                     maze[e.seat.x][e.seat.y]=1;                     Pop_Sq(S,&e);//Pop_Sq(&S,&e);                 }                   if(e.di<4){                     e.di++;                     Push_Sq(S,e);//Push_Sq(&S,e);                       curpos=NextPos(&e.seat,e.di);                 }               }           }       }while(!EmptyStack_Sq(S));//}while(!EmptyStack_Sq(&S));     return ERROR; }   int main(){     SqStack S;     int find=0;     int mg[M+2][N+2]={                 {1, 1, 1, 1, 1, 1, 1, 1, 1, 1},                 {1, 0, 0, 1, 0, 0, 0, 1, 0, 1},                 {1, 0, 1, 1, 0, 1, 0, 1, 0, 1},                 {1, 0, 0, 0, 0, 1, 1, 0, 0, 1},                 {1, 0, 1,  1, 1, 0, 1, 1, 0, 1},                 {1, 0, 0, 0, 1, 0, 0, 0, 1, 1},                 {1, 0, 1, 0, 0, 0, 1, 0, 0, 1},                 {1, 0, 1, 1, 1, 0, 1, 1, 0, 1},                 {1, 0, 0, 0, 0, 0, 1, 0, 0, 1},                 {1, 1, 1, 1, 1, 1, 1, 1, 1, 1}         };       PosType start,end;     char cc;     start.x=1;     start.y=1;     end.x=M;     end.y=N;     find=MazePath(&S,mg,start,end);     printf("%d\n",find);     return 0; }

引用 2 楼 user-4 的回复:要改什么东西你没说,改错误还是什么  程序运行不了啊

要改什么东西你没说,改错误还是什么

人呢


Question: 先定义的变量地址比后定义的变量地址高？

引用 5 楼 lin5161678 的回复: 纠正 这图是 A < C < B  C < A < B是这张图

楼上几位  所谓栈生长方向  所谓地址分配  误导够了  怎么定义顺序 和 分配顺序 没有必然联系

栈是从高地址向低地址分配的，堆是从低到高，overlap了就说明内存耗尽了。。

引用 1 楼 lin5161678 的回复:未必  怎么安排都有可能  顺序定义 ABC 内存顺序 可能是 ACB CAB CBA BAC..... 为什么我测出来的是 a>b>c>d>e>f

引用 楼主 u013491662 的回复: #include<stdio.h> int  main() { 	int a, b, c; 	int d, e, f; 	printf("%p\n", &a); 	printf("%p\n", &b); 	printf("%p\n", &c); 	printf("%p\n", &d); 	printf("%p\n", &e); 	printf("%p\n", &f); 	return  0; }  为什么a的地址要比b的高？a先声明，应该a的地址比b的低才是呀？ VC6 Release模式下，a的地址要比b的低 0012FF38 0012FF3C 0012FF40 0012FF44 0012FF48 0012FF4C VC6 Debug模式下，a的地址要比b的高 0012FF7C 0012FF78 0012FF74 0012FF70 0012FF6C 0012FF68 其实不要纠结变量的地址顺序，除非你想hack 从编译器的角度来说，变量的地址是可以随机安排的，又不影响寻址使用，不一定非要按排列顺序

引用 2 楼 u013491662 的回复:[quote=引用 1 楼 lin5161678 的回复:] 未必  怎么安排都有可能  顺序定义 ABC 内存顺序 可能是 ACB CAB CBA BAC..... 为什么我测出来的是 a>b>c>d>e>f[/quote]没有为什么  所谓怎么安排都有可能  除了包括 ACB CAB BAC之外 自然包括 CBA ABC 这样的情况  这才叫做 "都有可能"


while(1)//这个很重要的，楼主哥哥

多了个“；”。要多注意写，最好要一次性搞定！

引用 楼主 u010840578 的回复:视频里也能实现 视频里用的是符合C99标准或C++的编译器，变量可以在使用的地方声明，VC6.0必须在所以语句前声明变量

引用 楼主 u010840578 的回复:while(1); { frame = cvQueryFrame(capture); if(!frame)break;  cvShowImage("show",frame); char c=cvWaitKey(33); if(c==27)break;  cvReleaseCapture(&capture); cvDestroyWindow("show"); } 将char c;的声明提前 while(1) { char c; frame = cvQueryFrame(capture); if(!frame)break;  cvShowImage("show",frame); c = cvWaitKey(33); if(c==27)break;  cvReleaseCapture(&capture); cvDestroyWindow("show"); }

别用VC6.0了，换个编译器吧

引用 1 楼 u014444402 的回复:while(1)后面多了个分号，当然会报错了。 引用 1 楼 u014444402 的回复:while(1)后面多了个分号，当然会报错了。 引用 1 楼 u014444402 的回复:while(1)后面多了个分号，当然会报错了。  不想说什么了

while(1)后面多了个分号，当然会报错了。

不解释


Question: vc++6.0哪怕是打印hello都出来太慢，请问怎么了，怎么解决啊

什么配置？把360删掉再说

楼上正解可能是杀软问题。

有可能是杀毒软件的干扰，有360之类的吗

引用 1 楼 user-3 的回复:有可能是杀毒软件的干扰，有360之类的吗 一楼正解，终于好了，谢了

引用 2 楼 cf2d612 的回复:楼上正解可能是杀软问题。 嗯，试试

引用 1 楼 user-3 的回复:有可能是杀毒软件的干扰，有360之类的吗 嗯，有，360影响大么


Question: 如何用数组来模拟加法的进位？？

int add (int *a1 ,int *a2 ,int *s) { 	int i ; 	int carr ,temp ;  	carr = 0 ; 	for (i = 9 ; i >= 0 ; i--) 	{ 		temp = a1[i] + a2[i] + carr ; 		s[i] = temp % 10 ; 		carr = temp / 10 ; 	}  	return 0 ; }  两位数相加的结果还要加上进位 ,结果为对10取余 ,进位为除与10 话说计算机就适合计算2进制 ,先换成2进制计算然后换回去 ,效率会高很多

引用 8 楼 lm_whales 的回复:[quote=引用 7 楼 u011728480 的回复:] 可以实现，但是我不知道我的算法好不： 我的想法是这样的：int型数组，初始化每个为零，从零开始，遍历数组，依次判断是否满足次位是否大于=10  先实现一个正确的，可用的，算法可以慢慢调整。 实际上， char 数组就足够了。[/quote]   确实是这样的。只要先可行，算法可以优化/////////////

引用 7 楼 u011728480 的回复:可以实现，但是我不知道我的算法好不： 我的想法是这样的：int型数组，初始化每个为零，从零开始，遍历数组，依次判断是否满足次位是否大于=10  先实现一个正确的，可用的，算法可以慢慢调整。 实际上， char 数组就足够了。

仅供参考#include <stdio.h> #include <string.h> #define MAXLEN 1000 char a1[MAXLEN]; char a2[MAXLEN]; static int v1[MAXLEN]; static int v2[MAXLEN]; static int v3[MAXLEN]; int i,j,n,L,z; void main(void) {     scanf("%d",&n);     for (j=0;j<n;j++) {         scanf("%s%s",a1,a2);          L=strlen(a1);         for (i=0;i<L;i++) v1[i]=a1[L-1-i]-'0';          L=strlen(a2);         for (i=0;i<L;i++) v2[i]=a2[L-1-i]-'0';          for (i=0;i<MAXLEN;i++) v3[i]=v1[i]+v2[i];          for (i=0;i<MAXLEN;i++) {             if (v3[i]>=10) {                 v3[i+1]+=v3[i]/10;                 v3[i]=v3[i]%10;             }         }          printf("Case %d:\n", j+1);         printf("%s + %s = ", a1, a2);          z=0;         for (i=MAXLEN-1;i>=0;i--) {             if (z==0) {                 if (v3[i]!=0) {                     printf("%d",v3[i]);                     z=1;                 }             } else {                 printf("%d",v3[i]);             }         }         if (z==0) printf("0");          printf("\n");     } } //Sample Input //3 //0 0 //1 2 //112233445566778899 998877665544332211 // //Sample Output //Case 1: //0 + 0 = 0 //Case 2: //1 + 2 = 3 //Case 3: //112233445566778899 + 998877665544332211 = 1111111111111111110

#include <stdio.h>  void main() { 	unsigned char Sum[10] = {0,0,2,6,0,2,3,4,0,0};  //43206200     被加数，  低位在前 	unsigned char Add[10] = {7,5,9,8,0,0,0,0,0,0};  //8957    加数，低位在前 	int i,active,c,temp;  	active = 10; 	while((Add[active-1] == 0) && active != 0)			//查找Add数据内有效数据位(找到最高位是第几位就知道了),这里是4 		active--;  	c = 0;								//第一次是最低位相加，进位标志是0 	for(i=0; i<active; i++) 	{ 		temp = Sum[i] + Add[i] + c;		//带上一次计算进位标志加法 		c = temp/10; 		Sum[i] = temp%10; 	}  	Sum[i] += c;		//最后一次进位，在这里补回来  	  	active = 10; 	while((Sum[active-1] == 0) && active != 0)		//计算Sum内有效数据位   		active--;  	for(i=active; i >= 0; i--)				//显示有效数据 		printf("%c",Sum[i-1]+'0');  	printf("\n"); }

最简单的就是，和小学数学的竖式计算那样           A  B  C   D +      E   F  G   H              1   1 ------------------------         W   Z   Y    X        //和需要 进位，和减10，进位位置为1， 不进位保留原和，进位位置为0

引用 1 楼 linghuazaii 的回复:正常的话 应该是两个数据输入为两个数组 然后一个结果输出为一个结果 然后进位输出作为一个数组 其实门电路设计的时候也就是这样处理进位问题的 不过没有用一个数组来存 只是用一个锁存器来存进位信号或者溢出信号 楼主不是问的全加器的实现吧。。虽然原理差不多，但他的意思应该是高精度整数算法

如果只是要实现模拟所有大数的话，从高位到低位嵌套0~9的for循环就好了。 要实现两个数组代表的大数相加的话，就各位相加，和除以10的商加到高位去，余数成为新的低位。


Question: 类似word的章节的数据结构用哪种

引用 11 楼 lyb1900 的回复:用深度宽度表达不了1.2.4这类吧， 深度3，宽度4 ，，只会得到1.1.4  这不是单纯的二叉树，访问兄弟节点只会增加宽度而不是深度。 tree->firstchild->NextSibling->firstchild->NextSibling->NextSibling->NextSibling 1    .       1       |          2                 .      1        |      2            |           3            |         4  看这个章节生成方式。只有访问子树才增加章节深度。1.2.4表示方法

1.1.1这个值是不用存的。它表示子树的子树。 tree->firsttree->firsttree 1   .        1          .1 章节是一种树的访问方式，而不是节目值。 学过哈夫曼编码和哈夫曼树吗？从根节点一直访问到叶子节点，访问的路径一早编码。你这个章节是一样的道理。只不过用了m树

用深度宽度表达不了1.2.4这类吧， 深度3，宽度4 ，，只会得到1.1.4

引用 9 楼 lovesmiles 的回复:引用 7 楼 lyb1900 的回复:[quote=引用 6 楼 lyb1900 的回复:] [quote=引用 5 楼 u014444402 的回复:] [quote=引用 3 楼 lyb1900 的回复:] [quote=引用 2 楼 u014444402 的回复:] 这不是树吗？用什么树 还有什么树，普通 的M叉树就可以了。 typedef struct TreeNode *PtrToNode; struct TreeNode {     ElementType element;     PtrToNode FirstChild;//第一个孩子     PtrToNode NextSibling;//下一个兄弟 } 看数据结构树的第一节就是讲这个的。[/quote]那1.1，1.2.1这些信息如何在element 表达呢[/quote]M不确定时怎么办[/quote]  树的根接点是1，子树是1.1，兄弟树是2，子树的兄弟是1.2，子树的子树是1.1.1。用树的深度和宽度表示[/quote]  树的根接点是1，子树是1.1，兄弟树是2，子树的兄弟是1.2，子树的子树是1.1.1。用树的深度和宽度表示  可以这样表示，但怎么存1.1.1呢，这值怎么存呢

这不是树吗？

用STL中的map配合vector

引用 7 楼 lyb1900 的回复:引用 6 楼 lyb1900 的回复:[quote=引用 5 楼 u014444402 的回复:] [quote=引用 3 楼 lyb1900 的回复:] [quote=引用 2 楼 u014444402 的回复:] 这不是树吗？用什么树 还有什么树，普通 的M叉树就可以了。 typedef struct TreeNode *PtrToNode; struct TreeNode {     ElementType element;     PtrToNode FirstChild;//第一个孩子     PtrToNode NextSibling;//下一个兄弟 } 看数据结构树的第一节就是讲这个的。[/quote]那1.1，1.2.1这些信息如何在element 表达呢[/quote]M不确定时怎么办[/quote]  树的根接点是1，子树是1.1，兄弟树是2，子树的兄弟是1.2，子树的子树是1.1.1。用树的深度和宽度表示

你去好好看一下这种树吧， 不是M确定不确定的问题。 这跟M是多少没有关系。

引用 6 楼 lyb1900 的回复:引用 5 楼 u014444402 的回复:[quote=引用 3 楼 lyb1900 的回复:] [quote=引用 2 楼 u014444402 的回复:] 这不是树吗？用什么树 还有什么树，普通 的M叉树就可以了。 typedef struct TreeNode *PtrToNode; struct TreeNode {     ElementType element;     PtrToNode FirstChild;//第一个孩子     PtrToNode NextSibling;//下一个兄弟 } 看数据结构树的第一节就是讲这个的。[/quote]那1.1，1.2.1这些信息如何在element表达呢[/quote]M不确定时怎么办

引用 5 楼 u014444402 的回复:引用 3 楼 lyb1900 的回复:[quote=引用 2 楼 u014444402 的回复:] 这不是树吗？用什么树 还有什么树，普通 的M叉树就可以了。 typedef struct TreeNode *PtrToNode; struct TreeNode {     ElementType element;     PtrToNode FirstChild;//第一个孩子     PtrToNode NextSibling;//下一个兄弟 } 看数据结构树的第一节就是讲这个的。[/quote]那1.1，1.2.1这些信息如何在element表达呢

引用 3 楼 lyb1900 的回复:引用 2 楼 u014444402 的回复:这不是树吗？用什么树 还有什么树，普通 的M叉树就可以了。 typedef struct TreeNode *PtrToNode; struct TreeNode {     ElementType element;     PtrToNode FirstChild;//第一个孩子     PtrToNode NextSibling;//下一个兄弟 } 看数据结构树的第一节就是讲这个的。

引用 2 楼 u014444402 的回复:这不是树吗？在树中如何表达1.2，1.1.1

引用 2 楼 u014444402 的回复:这不是树吗？用什么树


Question: 字符转换

仅供参考#include <stdio.h> #include <stdlib.h> #include <conio.h> unsigned int iv,i; unsigned char BCD[5];//定长10位BCD码 unsigned char sv[11]; void main() {     iv=123456789;//最大10位无符号正整数     //INT2BCD     sprintf(sv,"%010u",iv);     for (i=0;i<10;i+=2) {         BCD[i/2]=(sv[i]<<4)|(sv[i+1]&0x0F);     }     printf("BCD=%02x%02x%02x%02x%02x\n",BCD[0],BCD[1],BCD[2],BCD[3],BCD[4]);     //BCD2INT     for (i=0;i<10;i+=2) {         sv[i]='0'|(BCD[i/2]>>4);         sv[i+1]='0'|(BCD[i/2]&0x0F);     }     sscanf(sv,"%010u",&iv);     printf("iv=%010u\n",iv);     getch(); }

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

引用 3 楼 linghuazaii 的回复:fread(buf,sizeof(buf),1,fp);//这个可是只读了一个字符哦不对不对 更正 这个没问题

虽然看不明白楼主的代码，但是根据题意可有如下代码。  #include <stdio.h>  int main () { 	char* buf = "12345"; 	int decimal = 0; 	int i = 0; 	for(; i < 5; i++){ 		decimal = decimal * 10 + buf[i] - '0'; 	} 	printf("decimal %d in hexadecimal is 0x%x\n", decimal, decimal); 	return 0; }  省略文件读写，只是给楼主提供思路。

12345变成 0x12345加 0x呗 如果想变成16进制的12345sprintf格式化函数可以吧


Question: foo和bar是什么？

甲、乙

每个编程语言都是用hello world来开始，这大概是第一个人这样子做了，所以后面的人就跟着这样子了。你搜一下马屁股决定航天飞机的宽度这个故事，你就会明白每个看似没意义的数字背后都是很有意思的

张三 李四 小明 小红之类的。

楼主是从哪本书上看到的？

好吧，我没有注意到，看来我看书不够深。甚至都没有一点印象。。。可能是没有看过。。。

引用 5 楼 u010957746 的回复:楼主给你解释下， foo 和 bar 就是外国人随便简单的起的一个名字，一般都会定义为一个没有实际意义的文件名字  比如中国的： 张三 李四 王二麻子 这个精辟，就是这样，每种语言里都有一些没有太多意思但作用很大的词，比如王二麻子

随便写的东西 demo性质

foobar是相当不错的音乐播放器哦 亲

http://en.wikipedia.org/wiki/Foobar 术语foobar, foo, bar, baz 和qux经常在计算机编程或计算机相关的文档中被用作占位符的名字。当变量，函数，或命令本身不太重要的时候，foobar, foo, bar, baz 和qux就被用来充当这些实体的名字，这样做的目的仅仅是阐述一个概念，说明一个想法。这些术语本身相对于使用的场景来说没有任何意义。Foobar经常被单独使用；而当需要多个实体举例的时候，foo，bar，和baz则经常被按顺序使用。

http://baike.baidu.com/view/1206486.htm?fr=aladdin 搜索了一下，呵呵，以前也没有特别搜索过

自己喜欢就行

估计是因为这两个都是单音节，当初写教程的人就随便取了这两种名字，然后所有人就都用它了。 反正我很不爽听到这两个，老感觉是在骂你傻瓜


Question: fseek读取外部文件结果出现空行

引用 5 楼 OU14563 的回复:打开的方式是“rb”，写入的方式是“wb”。 一行的长度是50个字节左右，那么是不固定的。你每次跳50个字节，就可能会出现跳到的地方不是行首。 这种最好的办法是。 char **ppcFile; ppcFile = new char*[行数]; fgets读一行。 ppcFile[i]=new char(strlen(一行)+1); strcpy(ppcFile[i], (一行)); 整个文件分行存放到内存里面。这样的方式来跳行。 以fseek来跳行，必须计算准确。50个字节，你得必须确定每一行算上回车是50个字节才行。

打开的方式是“rb”，写入的方式是“wb”。

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

打开方式是不是“r”？最好是用“rb”打开。

非常感谢赵4老师的回答！要从第十行的数据读取，指针通过偏移量移到第十行后读取文件的数据后并存储后，它的结果还是会空出前面的9行空间，数据依然是从第十行存储起来。这个就是赵4老师所说的情况呀，那fread和fwrite两个函数号称是随机读取文件，这样根本就没有达到随机读取和存储的效果呀。

文件是你写的吗？ 如果是，那么你需要问自己为什么要跳一行再写。 如果不是，那么问写的人。  问csdn......


Question: 用循环读入字符串的问题

试试这个 /*************************************************************************     > File Name: getstring.c     > Author: Jukay     > Mail: hellojukay@gmail.com      > Created Time: 2014年11月07日 星期五 13时46分24秒  ************************************************************************/  #include<stdio.h> int main() {     char sentence[40];     int i;     for(i = 0; i < 40  ;++i)     { 	scanf("%c",&sentence[i]); 	if(sentence[i] == '\n') 	    break;     }     sentence[i] = '\0';     printf("%s",sentence);     printf("\n");     return 0; }

应该是<40,没有=。。。

引用 8 楼 u013491662 的回复:跟6楼程序一样了。。。  #include <stdio.h> int main() { 	char sentence[40]; 	int length; 	int n; 	for (n = 0; n < 40; n++) 	{ 		scanf("%c", &sentence[n]); 		if (sentence[n] == '\n') 			break; 	} 	n = 0; 	while (sentence[n] != '\n') 	{ 		length = n; 		n++; 		if (n == 40) 		{ 			length = 39; 			break; 		} 	} 	for (n = length; n >= 0; n--) 	{ 		printf("%c", sentence[n]); 	} 	return 0; }  输出超过40也没问题！嗯。不过第39个字符和换行符之间的字符都被抛弃了。还是谢谢。

引用 7 楼 u013491662 的回复: #include <stdio.h> int main() { 	char sentence[40]; 	int length; 	int n; 	for (n = 0; n < 40; n++) 	{ 		scanf("%c", &sentence[n]); 		if (sentence[n] == '\n') 			break; 	} 	n = 0; 	while (sentence[n] != '\n') 	{ 		length = n; 		n++; 	} 	for (n = length; n >= 0; n--) 	{ 		printf("%c", sentence[n]); 	} 	return 0; }  程序不是很健壮，如果输入超出40个字符程序就出毛病了谢谢，我简化成这样了。 #include <stdio.h> int main(void) {     char sentence[40];     int n;      for(n = 0; n < 40; n++)     {         scanf("%c", &sentence[n]);         if(sentence[n] == '\n')             break;     }     for(n -= 1; n >= 0; n--)     {         printf("%c", sentence[n]);     }     return 0; }

#include <stdio.h> int main(void) {     char sentence[40];     int length;     int n = 0; 	scanf("%c", &sentence[n]); 	getchar(); 	while (sentence[n] != '\n') 	{ 		n++; 		scanf("%c", &sentence[n]);	 	}          while(n--)     {         printf("%c", sentence[n]);     }     return 0; }

char sentence[40];     int length;     int n;       for(n = 0; n <40; n++)/*应该是小于四十，不加等于号*/ 	{ 		char ch=getchar(); 		sentence[n]=ch; 		if(ch=='\n')    /*这里加一个判断语句就好了*/ 			break; 	}     n = 0;     while(sentence[n] != '\n')     {         length = n;         n++;     }     for(n = length; n >= 0; n--)     {         printf("%c", sentence[n]);     } 	getchar();

百度了半天了。到现在还是不知道怎么搞=。=

引用 2 楼 Intel0011 的回复:为什么把简单问题复杂化 #include <stdio.h>  int main(void) {    char sentence[40];     scanf("%40s", sentence);    puts(sentence);    return 0; }目的是反向输出字符串

引用 2 楼 Intel0011 的回复:为什么把简单问题复杂化 #include <stdio.h>  int main(void) {    char sentence[40];     scanf("%40s", sentence);    puts(sentence);    return 0; }题目要求用%c

这个是因为你的这一句： for(n = 0; n <= 40; n++)         scanf("%c", &sentence[n] 必须要循环41次才会结束。 否则执行不到下面。


Question: 三角形面积编程求看错误

"double"与"%d"不对应！

double a,b,c,p,s;          scanf("%lf%lf%lf",&a,&b,&c);     if (((a+b>c)&&(a-b<c))||((a+c>b)&&(a-c<b))||((b+c>a)&&(b-c<a)))         p=(a+b+c)/2;     s=sqrt(p*(p-a)*(p-b)*(p-c));     printf("三角形面积=%f\n",s);   输入值的时候 中间要加空格 。 格式字符串已改正

先贴代码  #include <stdio.h> #include <math.h>  int main () {   double a, b, c, p, s;   while(1){ 	printf("input edges of a triangle: "); 	scanf("%lf%lf%lf", &a, &b, &c); 	if((a + b) > c && (a + c) > b && (b + c) > a){ 		break; 	}else{ 		printf("%.2lf, %.2lf, %.2lf cannot construct a triangle!!\n", a, b, c); 	}   }   p = (a + b + c) / 2;   s = sqrt(p * (p - a) * (p - b) * (p - c));   printf("the area of the triangle is %.2lf.\n", s);   return 0; }  以上代码在VS2010 64位亲测可用。  楼主代码主要问题： 1. double类型在scanf和printf函数中都要用%lf； 2. 判断条件的“两边之差小于第三边”需加绝对值，或者干脆判断三次“两边之和大于第三边”； 3. if条件之后至main结束前加{ }， 不然条件不成立的情况下p无赋值，s计算会错乱。     正确的逻辑应该是条件不成立什么也不做。

引用 9 楼 pengqihang1009 的回复:把double改成float或许管用。把输入输出的格式字符串也改成%f

把double改成float或许管用。

三角形任意两边之和大于第三遍，中间判断用&&

输入那里 应该为%lf

引用 5 楼 yaoyao_xin 的回复:[quote=引用 2 楼 u013491662 的回复:] 对于double型变量 格式声明要用%lf  #include "stdio.h" #include "math.h" main() { 	double a, b, c, p, s; 	scanf("%lf%lf%lf", &a, &b, &c); 	if (((a + b>c) && (a - b<c)) || ((a + c>b) && (a - c<b)) || ((b + c>a) && (b - c<a))) 		p = (a + b + c) / 2; 	s = sqrt(p*(p - a)*(p - b)*(p - c)); 	printf("三角形面积=%lf\n", s); } 还是不对啊 输出0.000000[/quote]  把lf改成f

引用 2 楼 u013491662 的回复:对于double型变量 格式声明要用%lf  #include "stdio.h" #include "math.h" main() { 	double a, b, c, p, s; 	scanf("%lf%lf%lf", &a, &b, &c); 	if (((a + b>c) && (a - b<c)) || ((a + c>b) && (a - c<b)) || ((b + c>a) && (b - c<a))) 		p = (a + b + c) / 2; 	s = sqrt(p*(p - a)*(p - b)*(p - c)); 	printf("三角形面积=%lf\n", s); } 还是不对啊 输出0.000000

对于printf，最好不要用%lf  严格地讲，%lf在printf下是未定义的，但是很多系统可能会接受它。要确保可移植性，就要坚持使用%f

输出的时候。应用%f。因为c语言里面。浮点数和整型数在内存上的储存方式不同。如果控制符不对应就会输出0；  （一定要用对应的控制符输出对应类型的数据）

double a,b,c,p,s; ----> 变量是双浮点型 %d－－－－》用于int  #include <stdio.h> #include <math.h> int main(void) {    double a,b,c,p,s; scanf("%lf%lf%lf",&a,&b,&c);     if (((a+b>c)&&(a-b<c))||((a+c>b)&&(a-c<b))||((b+c>a)&&(b-c<a))) p=(a+b+c)/2; s=sqrt(p*(p-a)*(p-b)*(p-c)); printf("三角形面积=%f\n",s);    return 0; }


Question: 请问main()函数之前的代码怎么调用啊请给出完整程序。谢谢！

引用 楼主 developerof 的回复:#include<stdio.h>#define MAXSIZE 20typedef struct{ int data[20]; int length;}sqlist;int Get_element(sqlist l,int i,int *e){  if(l.length==0||i<1||i>l.length){     return 0;   }  else{  *e=l.data[i-1];   return 1;  } return 1;}int main(){ return 0;}   #include<stdio.h> #define MAXSIZE 20 typedef struct{  	int data[20];  	int length; }sqlist; int Get_element(sqlist l,int i,int *e) { 	if(l.length==0||i<1||i>l.length) 	{      		return 0;    	}   	else 	{   		*e=l.data[i-1];    		return 1;   	}  	return 1; } int main() { 	sqlist sAbc; 	int ix; 	int e; 	printf("请输入列表中元素的数量:"); 	scanf("%d", &sAbc.length); 	 	for(ix=0; ix<sAbc.length; ix++) 	{ 		scanf("%d", &sAbc.data[ix]); 	} 	 	printf("请输入要取到列表中的哪个元素的:"); 	scanf("%d", &ix); 	 	if( Get_element(sAbc, ix, &e)) 	{ 		printf("列表中的 %d 个元素是 %d\n", ix, e); 	} 	else 	{ 		printf("取出元素失败！\n"); 	} 	return 0; }

#include<stdio.h>  #define MAXSIZE 20 typedef struct{  int data[20];  int length; }sqlist;  int Get_element(sqlist l,int i,int *e) {   if(l.length==0||i<1||i>l.length) {      return 0;    }   else {       *e=l.data[i-1];    return 1;   }  return 1; }  int main() { sqlist sq; sq.data = {1,2,3}; sq.length = 3;  int v = 0; Get_element(sq, 2, &v);  printf("value = %d\n", v);   return 0; }


Question: sizeof 一个奇葩的问题 你又了解多少？

这也能称做奇葩问题？ 只怪你自己懂得少而已

sizeof是无符号的，无符号和有符号的运算都会扩展为无符号运算

大部分程序员coding的思路或者说习惯不应该是 if (sizeof x > y) 这样的吗

sizeof 表达式求值结果是size_t  而size_t是无符号类型   这点细节注意到就好了

恭喜,问题KO了

前面该说的都说了，我是来拿分的。

改成这样，if ((int)(iLen - sizeof(sTmp)) >= 0)，就正常了。  跟lz分享下我的过程吧(个人感觉过程重干结果)  ------------万能的分割线-----------------  一开始我也很好奇，怎么会这样，于是我就打开我的debian系统，亲自把代码输入，结果跟你的结果一样。 我就开始考虑，会不会编译器把前面那个负数当成一个很大的正数呢？(有点c++基础的应该都知道，不用解释了吧) 我就把两边同时强转成int 如：if ((int)(iLen - sizeof(sTmp)) >= (int)0) 发现结果正常了。。。  我又在想编译器，为什么把0也当成unsigned int 处理？是不是只要保留(int)0就可以了？ 试了下，结果是错误的， 我就保留前面一个强转成int，结果正常了。。（终于得出正常结果了）  我又在想着，为什么编译器把前面一个数当成unsigned int处理呢？ 突然灵光一闪，发现typedef unsinged int  sizeof.... 编译器中的sizeof返回的就是unsinged int .,  int - unsinged int = unsinged int  这就完善解释了为什么会出现这么奇怪的问题。。哈哈  看样子c++还得继续修炼呀！！！细节很重要。。。

菜鸟 对于这问题  学习了

sizeof返回的是size_t类型，平台上一般定义为unsigned integer  iLen - sizeof(sTmp) 的结果为unsigned integer，所以一个负数解释为unsigned integer时是一个很大的数 iLen - sizeof(sTmp) >= 0显然成立  要符合你的逻辑，可以这样强制转换一下 if (iLen - (int)sizeof(sTmp) >= 0)

sizeof 返回 unsigned 类型 iLen - sizeof(sTmp) 的结果也是unsigned

自己先顶一下，作为一名菜鸟，还没有查到类似的资料。 期待大神~~~

引用 10 楼 gfchen1989 的回复:无符号和有符号的运算都会扩展为无符号运算 别乱讲。

多谢大家跟帖，让我受益匪浅

程序 有 警告，可你却 忽视 了 它  问题不奇葩 只是你没去理会


Question: 刚刚开始自学C 好多奇怪的问题啊 先来一个

运行了楼主的代码，没有问题。 #include<stdio.h> int main() { 	int i=5; 	int m=20; 	int k;  	m=(8>5)&&(k=5); 	printf("m=%d,k=%d\n",m,k); 	return 0; }  应该是楼主标点符号的问题。

你把你的代码传上来看看，像23楼那样的代码格式，不要直接上图！

K=5属于真吧。因为非0

#include <stdio.h>  int main(void) {     int i = 5;     int m = 20;     int k;      m = (8 > 5) && (k =5);     printf("m = %d,k = %d\n",m,k);     return 0; }   你拿过去试试

换行符是\n。。。。

中文标点绝对禁止的，除非当作字符串。

你是不是使用了中文字符啊,,还有那个i没有用到,,会显示警告..... 其它的应该没问题

k,只定义了没有初始化,所以才有k = 5

逻辑与运算：当前面为假时，后面不会执行，前面为真时才会执行后面

改成k==5 可以让编译器判断k是否等于5 然后返回真假值吗？ ----> Yes

引用 1 楼 zjq9931 的回复:有全角符号。 就是有的标点符号是全角的，中文的标点符号。 报错的有行号，你那块没有截图下来，所以不知道是那一行错了。 根据你的截图，似乎是printf那一行的问题。 根据报错的行号看一下吧。

引用 2 楼 qq_16712389 的回复:[quote=引用 1 楼 zjq9931 的回复:] 有全角符号。 就是有的标点符号是全角的，中文的标点符号。 我用的是半角符号啊[/quote] 报错的有行号，你那块没有截图下来，所以不知道是那一行错了。

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

引用 3 楼 Intel0011 的回复:你可能是直接copy的代码 一般出现unknown character '0xa3' 表示出现了非法不可视字符，源代码文本是纯文本，不能有格式的 #include <stdio.h>  int main(void) {    int i = 5;    int m = 20;    int k;     m = (8 > 5) && (k = 5);    printf("m = %d, k = %d\n", m, k);     return 0; } k = 5这个是表达式，其值就是5，副作用是k被赋值为5 恩你说的我明白啦，但是我代码是写的啊 没有COPY啊。而且 我奇怪的是&&这个逻辑运算符，我想到了数学上的且命题，数学上且命题就是对两个命题进行判断，然后出真假结果，类推到C中，&&后面的k=5 是个赋值语句，改成k==5 可以让编译器判断k是否等于5 然后返回真假值吗？

结构-〉结果

1、代码里面有中文标点 中文的半角分号是；英文的标点是; 两个分号是不一样的  2、&&是必须左右都为真，才为真，否则为假，运算顺序是从左向右 现在&&的左边已经为假了，不管右边是真是假，这个式子的结构都为假，所以右边已经不需要再算了

引用 1 楼 zjq9931 的回复:有全角符号。 就是有的标点符号是全角的，中文的标点符号。 我用的是半角符号啊

有全角符号。 就是有的标点符号是全角的，中文的标点符号。

引用 18 楼 zhao4zhong1 的回复:[quote=引用 17 楼 zxhuser-14 的回复:] [quote=引用 16 楼 zhao4zhong1 的回复:] [quote=引用 14 楼 zxhuser-14 的回复:] 为什么你们都喜欢截图而不是直接贴代码呢？你这代码量还算小的，幸好不是大量代码 截图还是轻的，我还遇到过手机拍的呢！ [/quote]愿闻其详[/quote] 就是有人拿手机对着试卷拍了照片发帖子上求答案啊。[/quote] 哦，是那个帖子，我记起来了


Question: 如何找到文本中的某些行，并删除这些行的子字符串

内存映射文件

引用 3 楼 zilaishuichina 的回复:将 1.txt  读入内存  在内存中替换/删除你指定的字符串  将更新后的内存中数据写回 1.txt

唉，跟各位相比，自己真是太水了。

唉，我是新手，还不会这个。

引用 2 楼 zhao4zhong1 的回复:提醒：使用wchar_t，别用char 二次提醒。

引用 5 楼 yl1235 的回复:我这样写是不是效率很低啊 效率不能说低。 fopen的"r" “w”，最好用"rb","wb"，否则有可能会出现丢内容的情况。 逻辑错误，f9设置断点，F5跟踪，10单步执行，学会跟踪，很有帮助。

我这样写是不是效率很低啊

我的程序是这样的，不知道是哪里出现的问题，运行结果不对。 #include <conio.h> #include<stdio.h> #include<string.h> #include <windows.h>  int main( ) { FILE *fp1,*fp11;  char a[300],b[300];  char gj1[300]="郭家岗";      int A1[4]={1,2,3,7}; int i,j,h1;      if ((fp1=fopen("1.txt","r"))==NULL)     {  printf("cannot open file4/n"); }  if((fp11=fopen("11.txt","w"))==NULL)     {   printf("cannot open file\n");}   int i1;   for(i=0;i<4;i++) { i1=0;fp11=fopen("11.txt","w");fp1=fopen("1.txt","r"); 	while (fgets(a,sizeof(a),fp1)) 	   {i1++; 		if(A1[i]==i1) 			{for(i=strlen(gj1),j=0;a[i]!='\0';i++) 				{ 					b[j++]=a[i]; 										} 				b[j]='\0'; 				fputs(b,fp11); 				i++; 			} else fputs(a,fp11);}  fclose(fp1); fclose(fp11);    fp11=fopen("11.txt","r");  fp1=fopen("1.txt","w");  while (fgets(a,sizeof(a),fp11))  {fputs(a,fp1);  }  fclose(fp11); fclose(fp1); } }   运行结果是  预告警信号 郭家岗2#直流充电柜直流系统故障 郭家岗预告警信号 西陵:10kV1#消弧线圈自动调谐控制装置网络状态 西陵:10kV2#消弧线圈自动调谐控制装置网络状态 五峰GPS对时装置报警 郭家岗2#直流充电柜直流系统故障

三种方法。看看哪个需要的技术你不会。这是思路： 1.逐行读取，写入另一个文件，遇到指定的行后跳过，然后删除原来的文件。对新写的文件改名。 2.逐行读取，记录进内存，遇到指定的行后不记录进内存，然后写回原来的文件中。 3.整个文件读入内存，往回写的过程中，遇到指定的行后，跳过。

引用 10 楼 WUYUAN2011WOAINI 的回复:[quote=引用 3 楼 zilaishuichina 的回复:] 将 1.txt  读入内存  在内存中替换/删除你指定的字符串  将更新后的内存中数据写回 1.txt [/quote]如果有足够内存的话可以全部读入内存


Question: 用c语言编程呢读取游戏操纵杆数据(DirectX 9.0 Summer 2004 SDK+VC++6.0)

你看清楚红色的，没有个8字。即使报错也不会是这个错

我改过了，但还是报这个错误~~~~~~~~~~~

//创建DirectInput设备,    hresult=lpdi->CreateDevice(GUID_Joystick,&Joystick,NULL); 改成:    hresult=((LPDIRECTINPUT)lpdi)->CreateDevice(GUID_Joystick,&Joystick,NULL);


Question: 请问类似*(type **)(ptrdiff_t)container的是什么意思啊

要不要把宏定义都展开来再看比较好？

引用 2 楼 lovesmiles 的回复:记得有一more effective stl这本书有说过关于迭代器的情况。迭代器iterator.你可以将它当作指针来使用，因为它重载了*，对它做*运算，它将返回内部实际的type。但iterator事实上并非真的就一个指针，它只重是载了*使它看起来像指针而已。，要得到实际类型指针就要&（*iterator）.先取址再引用。  同样的，我觉得你应该结合你用到的container是什么东西，它的*，->运算符的重载情况才能搞清楚这个宏。  container就是一个简单的ops组合,里面定义了一个add指针指向一个函数 struct type { ... void (*add)(void *container, void *node); ... }

二楼说得也很有道理。定义一个map<map<type，type>*，type> *p。这个p指向一map指针.这个map的元素又是一个指针类型，现在要向这个容器添加元素，所以要多次调用*

不是解除，而是将container视作(type **)（数组的数组）再取它的数组的地址。  container是调用宏的人传进来的。


Question: c语言新手 字符统计问题

这个EOF用起来不顺手~

使用下面的程序就可以了，C语言回车键是用\n来表示的。 #include<stdio.h> #include<stdlib.h> main() {    long nc;    int c;    nc = 0;    while((c=getchar()) != '\n')        ++nc;    printf("nc=%ld,c=%d\n",nc,c);    system("pause");    return 0; } 运行结果如下： clear nc=5

Linux：Ctrl+D Windows：Enter，Ctrl+Z，Enter

引用 楼主 xiaot555 的回复:#include<stdio.h> main() {    long nc;     nc = 0;    while(getchar() != EOF)        ++nc;    printf("%ld\n",nc); } 来着c程序设计语言一书 为统计字符数 运行后只能不断的输入，无法统计（）  求大神教。。。 键盘输入EOF的办法是按CTRL+Z键。

Windows Ctrl-Z表示EOF，似乎你按enter是没用的吧。

需要从终端输入EOF, Windows下应该是 Ctrl-Z 吧

谢谢各位了，已经明白了


Question: 母函数问题求解

系数都是1这还要写代码来算吗？

代码调下格式啊

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

对于这种刚发的帖子，我总是毫不犹豫的顶了。如果火了就是个前排，可以混个脸熟，说不定谁好心就给粉了…稳赚不赔；如果沉了就感觉是我弄沉的，很有成就感，还能捞经验。


Question: 周末散分了

经纬度必须结合球面坐标计算 因为不同纬度的纬线，同一角度差，长度是不同的。 同样不同高度的，相同的经纬度差距，代表不同的长度。  如果可能，还需要把结果，改化到旋转椭球面上去。  根据你所说，改化到旋转椭球面上去，这一步可以不做。 但是经纬度和距离（长度）， 根本就不是同一个东西，一个是角度概念，一个是长度概念， 必须做一个坐标转换才能表示出来。  不想直接计算的话，看看可不可以查表。

不是说散分么，有这么散的吗

看来lz舍不得散分了，我也不奢求得分了。呵呵。 我的解法说一下，看一看对不对？ 以球心为原点，纬度为0的剖面，南北极为y轴的平面，求出x，y的值，然后再求出z的值。

引用 34 楼 ForestDB 的回复:纯粹接分，是不是要先讲清楚什么坐标系比较好？  就是不确定构建3D模型的时候，根据平面个顶点坐标和平面的每个顶点的高度值直接构建出3D模型么？  比如在一个平面有四个点，现在又给出了这四个点的高度值，这样是不是就能直接构建3D 模型了

接分

纯粹接分，是不是要先讲清楚什么坐标系比较好？

x,y 转成 x,y,h不就成了3d了。。

引用 25 楼 u012564309 的回复:加我一个 谢谢哥哥 OK   引用 26 楼 u010211892 的回复:不懂，强力接分 OK  引用 30 楼 u013697891 的回复:我知道分数与我无缘  相识即有缘  引用 27 楼 u012421456 的回复:可以是中心点 二维笛卡尔坐标系加个高度变成三维笛卡尔坐标系，现在只能这么简单的认为了...   引用 29 楼 u012184298 的回复:围观大神

不懂，强力接分

加我一个 谢谢哥哥

引用 22 楼 u014689964 的回复:可以直接接分吗。。感觉好难。。  围观既有分

引用 21 楼 zjq9931 的回复:[quote=引用 20 楼 N_sev7 的回复:] [quote=引用 3 楼 lovesmiles 的回复:] 这是球形地图还是平面地图？  取某个点为原点，坐标为(0,0，0),将这点的经，纬，高度(x,y,0)转成这个原点的坐标系。  这就是可以得得到3D模型啦。  哈哈，给分吧  怎么转呢？经纬度与高度单位都不一样的，而且转换后的坐标系的单位呢？解析几何我是小白型的....  引用 11 楼 u012421456 的回复:找一个原点  中心点么？  引用 5 楼 zjq9931 的回复:好吧，我觉得可以直接画，需要转换吗？ 我也觉得可以直接画，但是貌似不行。。。  引用 6 楼 zxh707wk 的回复:如果计算量大的话，先把三角函数的值全部算出来  有些不懂啊！！！[/quote] 画高度的比例尺是多少？ 然后画球面的比例尺也用那个，根据地球的半径，和经纬，比例尺，画出球面。[/quote] 我感觉没有那么复杂吧，不用考虑球面的问题，因为我说的那个面试比较小的面，比如一幢楼的楼顶面等等，应该可以看做一个平面了吧，我感觉大家可能想的有些复杂了吧  是么？

可以直接接分吗。。感觉好难。。

引用 20 楼 N_sev7 的回复:[quote=引用 3 楼 lovesmiles 的回复:] 这是球形地图还是平面地图？  取某个点为原点，坐标为(0,0，0),将这点的经，纬，高度(x,y,0)转成这个原点的坐标系。  这就是可以得得到3D模型啦。  哈哈，给分吧  怎么转呢？经纬度与高度单位都不一样的，而且转换后的坐标系的单位呢？解析几何我是小白型的....  引用 11 楼 u012421456 的回复:找一个原点  中心点么？  引用 5 楼 zjq9931 的回复:好吧，我觉得可以直接画，需要转换吗？ 我也觉得可以直接画，但是貌似不行。。。  引用 6 楼 zxh707wk 的回复:如果计算量大的话，先把三角函数的值全部算出来  有些不懂啊！！！[/quote] 画高度的比例尺是多少？ 然后画球面的比例尺也用那个，根据地球的半径，和经纬，比例尺，画出球面。

我知道分数与我无缘

引用 3 楼 lovesmiles 的回复:这是球形地图还是平面地图？  取某个点为原点，坐标为(0,0，0),将这点的经，纬，高度(x,y,0)转成这个原点的坐标系。  这就是可以得得到3D模型啦。  哈哈，给分吧  怎么转呢？经纬度与高度单位都不一样的，而且转换后的坐标系的单位呢？解析几何我是小白型的....  引用 11 楼 u012421456 的回复:找一个原点  中心点么？  引用 5 楼 zjq9931 的回复:好吧，我觉得可以直接画，需要转换吗？ 我也觉得可以直接画，但是貌似不行。。。  引用 6 楼 zxh707wk 的回复:如果计算量大的话，先把三角函数的值全部算出来  有些不懂啊！！！

引用 15 楼 c090869 的回复:太简单了，一定要给分呀, Y=(R+M)* SIN(纬度）， Z=(R+M)*COS(纬度）*sin(经度）， x=(R+M)*COS(WUDU)*COS(JINGDU)', 引用 16 楼 xiaot555 的回复:Y=(R+M)* SIN(纬度）， Z=(R+M)*COS(纬度）*sin(经度）， x=(R+M)*COS(WUDU)*COS(JINGDU)',  来个名词解释呗

引用 1 楼 zhao4zhong1 的回复:《算法精解（C语言描述）》中有一段计算给出经纬度的两点之间的弧长的代码。 不知楼主能不能拿来作参考。 引用 2 楼 zhao4zhong1 的回复:《球面几何》  就是不知道坐标系的单位是什么，原点又在哪里啊，中心点作为原点么，其实经纬度之间的单位长可以忽略，因为这些面是一些比较小的面。  PS：还是赵老师（别人都这么叫，也不知道您是不是真的姓赵）速度啊

围观大神

引用 18 楼 N_sev7 的回复:PS：还是赵老师（别人都这么叫，也不知道您是不是真的姓赵）速度啊 你看赵老师哪天不是论坛标兵


Question: 求帮忙解答？

要把scanf写在循环里面。

你的程序执行时，输入y，接着按Enter键 y被scanf读取放入c中，完成一次循环 第二次循环时，Enter键值被scanf读取放入c中，按你程序的逻辑，for循环结束后，while(c == 'y');中的判断不成立，main正常结束 scanf("%c", &c);   //标准中根本没有定义 fflush(stdin)。MSDN 文档里也清楚地写着fflush on input stream is an extension to the C standard（fflush 操作输入流是对 C 标准的扩充）。当然，如果你毫不在乎程序的移植性，用 fflush(stdin) 也没什么大问题。          //fflush(stdin);      {             int a;                 /* 通过 while 循环把输入流中的余留数据“吃”掉 */                 while ( (a = getchar()) != '\n' && a != EOF ) ;                       }        for(i=1; i<12; ++i)       {          if(c == 'Y'||'y')             break;          else if(c == 'N'||'n')             return 0;          else;       }

printf里面的%和变量的一一对应关系 scanf里面的%和变量以及变量前加不加&的一一对应关系 是C代码中非常容易出错的地方，而且通常编译还不出错。 所以在编译源代码之前值得专门仔细检查一遍甚至多遍。  在每个最后不带\n的printf后面加fflush(stdout); 在每个不想受接收缓冲区旧内容影响的scanf前面加rewind(stdin); 另外请检查scanf的返回值。


Question: C语言数组的问题

引用 5 楼 what_can_I_say 的回复:引用 1 楼 modyaj 的回复:length = strlen(word)-1好吧但最后为什么是空格，不是其他的东西？ 你可以考虑不给数组赋值就输出看看   或者是只赋值第一个  把剩下的输出看看！

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

因为'\0'是不可见字符。

引用 4 楼 anshiny 的回复:for(length = strlen(word); length >= 0; length--) 应为 for(length = strlen(word)-1; length >= 0; length--) 因为单词里的最后一个字符的下标是 strlen(word)-1。但最后为什么是空格，不是其他的东西？

引用 1 楼 modyaj 的回复:length = strlen(word)-1好吧我傻逼了=。=

下标是0---length-1 呵呵~~

length = strlen(word)-1好吧


Question: 一个被声明为静态的函数只可被这一模块内的其它函数调用

引用 2 楼 zhao4zhong1 的回复:我非我。 +1

只是强调不能被其它模块调用罢了。

这个，你确实有点道理。看看英文的原文是怎么写的。

因为一个完整的程序可能含有多个.c文件构成,,因此此静态函数只能在当前的一个.c文件中被使用...

昨天，我接到村里通知，一个被声明为静态的函数只可被这一模块内的其它函数调用。

我非我。

那就去掉其他二个字，自己调用自己当然没问题 一个被声明为静态的函数只可被这一模块内的其它函数调用 －－－》本意强调的是其他模块的函数不能调用


Question: RSA 公钥加密问题

仅供参考#pragma comment(lib, "crypt32.lib") #pragma comment(lib, "advapi32.lib") #define _WIN32_WINNT 0x0400 #include <stdio.h> #include <windows.h> #include <wincrypt.h> #define MY_ENCODING_TYPE  (PKCS_7_ASN_ENCODING | X509_ASN_ENCODING) #define KEYLENGTH  0x00800000 void HandleError(char *s); //-------------------------------------------------------------------- //  These additional #define statements are required. #define ENCRYPT_ALGORITHM CALG_RC4 #define ENCRYPT_BLOCK_SIZE 8 //   Declare the function EncryptFile. The function definition //   follows main. BOOL EncryptFile(     PCHAR szSource,     PCHAR szDestination,     PCHAR szPassword); //-------------------------------------------------------------------- //   Begin main. void main(void) {     CHAR szSource[100];     CHAR szDestination[100];     CHAR szPassword[100];     printf("Encrypt a file. \n\n");     printf("Enter the name of the file to be encrypted: ");     scanf("%s",szSource);     printf("Enter the name of the output file: ");     scanf("%s",szDestination);     printf("Enter the password:");     scanf("%s",szPassword);     //--------------------------------------------------------------------     // Call EncryptFile to do the actual encryption.     if(EncryptFile(szSource, szDestination, szPassword)) {         printf("Encryption of the file %s was a success. \n", szSource);         printf("The encrypted data is in file %s.\n",szDestination);     } else {         HandleError("Error encrypting file!");     } } // End of main //-------------------------------------------------------------------- //   Code for the function EncryptFile called by main. static BOOL EncryptFile(     PCHAR szSource,     PCHAR szDestination,     PCHAR szPassword) //-------------------------------------------------------------------- //   Parameters passed are: //     szSource, the name of the input, a plaintext file. //     szDestination, the name of the output, an encrypted file to be //         created. //     szPassword, the password. {     //--------------------------------------------------------------------     //   Declare and initialize local variables.     FILE *hSource;     FILE *hDestination;     HCRYPTPROV hCryptProv;     HCRYPTKEY hKey;     HCRYPTHASH hHash;     PBYTE pbBuffer;     DWORD dwBlockLen;     DWORD dwBufferLen;     DWORD dwCount;     //--------------------------------------------------------------------     // Open source file.     if(hSource = fopen(szSource,"rb")) {         printf("The source plaintext file, %s, is open. \n", szSource);     } else {         HandleError("Error opening source plaintext file!");     }     //--------------------------------------------------------------------     // Open destination file.     if(hDestination = fopen(szDestination,"wb")) {         printf("Destination file %s is open. \n", szDestination);     } else {         HandleError("Error opening destination ciphertext file!");     }     //以下获得一个CSP句柄     if(CryptAcquireContext(                 &hCryptProv,                 NULL,               //NULL表示使用默认密钥容器，默认密钥容器名                 //为用户登陆名                 NULL,                 PROV_RSA_FULL,                 0)) {         printf("A cryptographic provider has been acquired. \n");     } else {         if(CryptAcquireContext(                     &hCryptProv,                     NULL,                     NULL,                     PROV_RSA_FULL,                     CRYPT_NEWKEYSET))//创建密钥容器         {             //创建密钥容器成功，并得到CSP句柄             printf("A new key container has been created.\n");         } else {             HandleError("Could not create a new key container.\n");         }     }     //--------------------------------------------------------------------     // 创建一个会话密钥（session key）     // 会话密钥也叫对称密钥，用于对称加密算法。     // （注: 一个Session是指从调用函数CryptAcquireContext到调用函数     //   CryptReleaseContext 期间的阶段。会话密钥只能存在于一个会话过程）     //--------------------------------------------------------------------     // Create a hash object.     if(CryptCreateHash(                 hCryptProv,                 CALG_MD5,                 0,                 0,                 &hHash)) {         printf("A hash object has been created. \n");     } else {         HandleError("Error during CryptCreateHash!\n");     }     //--------------------------------------------------------------------     // 用输入的密码产生一个散列     if(CryptHashData(                 hHash,                 (BYTE *)szPassword,                 strlen(szPassword),                 0)) {         printf("The password has been added to the hash. \n");     } else {         HandleError("Error during CryptHashData. \n");     }     //--------------------------------------------------------------------     // 通过散列生成会话密钥     if(CryptDeriveKey(                 hCryptProv,                 ENCRYPT_ALGORITHM,                 hHash,                 KEYLENGTH,                 &hKey)) {         printf("An encryption key is derived from the password hash. \n");     } else {         HandleError("Error during CryptDeriveKey!\n");     }     //--------------------------------------------------------------------     // Destroy the hash object.     CryptDestroyHash(hHash);     hHash = NULL;     //--------------------------------------------------------------------     //  The session key is now ready.     //--------------------------------------------------------------------     // 因为加密算法是按ENCRYPT_BLOCK_SIZE 大小的块加密的，所以被加密的     // 数据长度必须是ENCRYPT_BLOCK_SIZE 的整数倍。下面计算一次加密的     // 数据长度。     dwBlockLen = 1000 - 1000 % ENCRYPT_BLOCK_SIZE;     //--------------------------------------------------------------------     // Determine the block size. If a block cipher is used,     // it must have room for an extra block.     if(ENCRYPT_BLOCK_SIZE > 1)         dwBufferLen = dwBlockLen + ENCRYPT_BLOCK_SIZE;     else         dwBufferLen = dwBlockLen;     //--------------------------------------------------------------------     // Allocate memory.     if(pbBuffer = (BYTE *)malloc(dwBufferLen)) {         printf("Memory has been allocated for the buffer. \n");     } else {         HandleError("Out of memory. \n");     }     //--------------------------------------------------------------------     // In a do loop, encrypt the source file and write to the source file.     do {         //--------------------------------------------------------------------         // Read up to dwBlockLen bytes from the source file.         dwCount = fread(pbBuffer, 1, dwBlockLen, hSource);         if(ferror(hSource)) {             HandleError("Error reading plaintext!\n");         }         //--------------------------------------------------------------------         // 加密数据         if(!CryptEncrypt(                     hKey,           //密钥                     0,              //如果数据同时进行散列和加密，这里传入一个                     //散列对象                     feof(hSource),  //如果是最后一个被加密的块，输入TRUE.如果不是输.                     //入FALSE这里通过判断是否到文件尾来决定是否为                     //最后一块。                     0,              //保留                     pbBuffer,       //输入被加密数据，输出加密后的数据                     &dwCount,       //输入被加密数据实际长度，输出加密后数据长度                     dwBufferLen))   //pbBuffer的大小。         {             HandleError("Error during CryptEncrypt. \n");         }         //--------------------------------------------------------------------         // Write data to the destination file.         fwrite(pbBuffer, 1, dwCount, hDestination);         if(ferror(hDestination)) {             HandleError("Error writing ciphertext.");         }     } while(!feof(hSource));     //--------------------------------------------------------------------     //  End the do loop when the last block of the source file has been     //  read, encrypted, and written to the destination file.     //--------------------------------------------------------------------     // Close files.     if(hSource)         fclose(hSource);     if(hDestination)         fclose(hDestination);     //--------------------------------------------------------------------     // Free memory.     if(pbBuffer)         free(pbBuffer);     //--------------------------------------------------------------------     // Destroy session key.     if(hKey)         CryptDestroyKey(hKey);     //--------------------------------------------------------------------     // Destroy hash object.     if(hHash)         CryptDestroyHash(hHash);     //--------------------------------------------------------------------     // Release provider handle.     if(hCryptProv)         CryptReleaseContext(hCryptProv, 0);     return(TRUE); } // End of Encryptfile //-------------------------------------------------------------------- //  This example uses the function HandleError, a simple error //  handling function, to print an error message to the standard error //  (stderr) file and exit the program. //  For most applications, replace this function with one //  that does more extensive error reporting. void HandleError(char *s) {     fprintf(stderr,"An error occurred in running the program. \n");     fprintf(stderr,"%s\n",s);     fprintf(stderr, "Error number %x.\n", GetLastError());     fprintf(stderr, "Program terminating. \n");     exit(1); } // End of HandleError


Question: 有个错误  不理解，有谁能帮我解释一下

格式化输出printf() 中int 类型对应了%d ，float 对应了%f，所以不能用%f 来输出%d 的变量

存储分配的字节都不一样，出栈会造成读取错误的。

引用 3 楼 yclsdju 的回复:float格式是谭浩强C语言上面的例子   我在学习时候发现输出不对，各位同仁可以自己复制两个程序，运行后看看结果  这个问题以前也有不少人问过，估计回复你的人都回答过不少了。你仔细看看别人的回复再自己思考一下。

一切还是看图说话。。。。。。。

楼主分别测试下这两段代码就能理解了： #include<stdio.h> int main() { 	int a=5; 	printf("%f",a); 	return 0; } #include<stdio.h> int main() { 	float a=5; 	printf("%f",a); 	return 0; }

类型不同，输出错误啊。

按int类型存储，结果按float类型提取，肯定错了。浮点数和整型数存储格式完全两样的

书上不是有吗？在讲输入输出的那章

前面定义的r类型和后面输出的r类型不一致

printf中，d对应int，f对应float和double d不能对应float，因为int和float的存储格式是不一样的，解码起来也不一样

那么楼主希望下面这句输出啥呢？ printf("%按照大熊猫的格式输出",CSDN的yclsdju);//

int和float的存储方式不同


Question: 求助，帮我推荐几本C的经典书籍

C语言书目，排名不分先后。好好读书吧。	  2. C程序设计语言 作者 : Brian W.Kernighan/Dennis M.Ritchie  出版社 : 清华大学出版社 评语 : 第1本 《C程序设计语言》 Brian W. Kernighan / Dennis M. Ritchie 这本书又称为 R&K C，还有谁能比C语言之父对C语言更有发言权的呢？推荐看英文版。你会惊讶于在短短不到200页的篇幅内，这两位牛人将C语言描述的这么清晰。即使不专门学C语言的人也可以拿出来翻翻    	 3. C陷阱与缺陷 作者 : 凯尼格  出版社 : 人民邮电出版社 评语 : 第2本 《C陷阱与缺陷》Andrew Koenig Andrew Koenig的成名作，能帮助初学者减少90%的错误。一些错误（比如赋值符、运算符优先级等）还是不时的会在自己的程序里出现，只是已经打过预防针了，很容易发现。另外作者写了一本《Accelerated C++》，据说是C++的最佳入门书，狠赞！！  	 4. C专家编程 作者 : Peter Van Der Linden  出版社 : 人民邮电出版社 评语 : 第3本 《C专家编程》（LinDen,P.V.D） 一看书名就知道这丫不能拿来入门用的，第一次看的时候够折磨大脑的。作者声称，编程的唯一原因是因为乐趣。相比之前的几本书，这本书还介绍C语言运行的环境，更全面地考察了C语言。深入分析了C语言中一些容易混淆的概念，如复杂的声明和定义、数组和指针、链接和运行时库、内存等。很值得一读。 顺便一提：链接库可参考《深入理解计算机系统》的动态链接库一章，写得更易读  	 5. 编程精粹 作者 : Steve Maguire  出版社 : 人民邮电出版社 评语 : 第4本 《编程精粹：编写高质量C语言代码》 《Writing Solid Code》 Steve Maguire 这是我读到C语言书中最惊叹的一本，尽管写出没有bug的程序不太可能，但按照作者提供的方法，可以离这个目标很近。本书关注的更多是怎么使用C语言开发工业级产品的问题。 这本书源自作者十几年不断的追问自己两个简单的问题： 1）怎样才能自动地查出这个错误？ 2）怎样才能避免这个错误？ “他的另一部名著Debugging the Development Process（中文版《微软  	 6. C Interfaces and Implementations 作者 : David R. Hanson  出版社 : Addison-Wesley Professional 评语 : 第5本 《C Interfaces and Implementations》 David R. Hanson 这本据说为唯一一本能和R&K C并驾齐驱的书，可惜中文版众口一致说太烂，无处可载电子版，影印版跳票多年，原版USD 54.99实在承受不起，囊中羞涩，奈何奈何。想念多年，至今不能一睹芳容，深以为憾。  	 7. C标准库 作者 : P. J. Plauger  出版社 : 人民邮电出版社 评语 : 前面5本差不多够了，另外推荐两本，精力过剩的可以翻翻 第6本 《C标准库》P. J. Plauger 本书介绍C标准库的实现，书中有较为详尽的代码。虽然这本书年代久远，现在的实现肯定和以前也有差别，但是还是很有参考价值，特别是对C标准库的实现有兴趣的人。中文版太贵，英文电子版看得太累，还是以后有地方借的时候再继续看。    K&R的The C  Programming Language  ==================================  《pointers on c》 C与指针 ==================================  c primer plus ==================================  	 8. C语言参考手册 作者 : 哈比森  出版社 : 机械工业出版社 评语 : 第7本 《C语言参考手册》 拿来备查的，C语言的任何细节几乎都能在其中找到借到。书的第一部分介绍C语言语法细节。第二部分介绍运行时库，可以和《C标准库》参考阅读。

嗨翻C语言，公司采购的书，正在看感觉还不错。

C Primer Plus 数据结构与算法－C语言描述 Windows程序设计 第五版 MSDN --> API文档

1.C语言程序设计 作者 : 谭浩强  出版社 : 清华大学出版社  评语 : 第0本 《C语言程序设计》谭浩强 我们很少有学C语言的启蒙书不是用这本的。如果你从来没接触过C语言，这本书还是适合作为入门的。尽管大学毕业之后就不再碰这本书，但是还记得当初这本书看了3遍、指针那部分看了至少5遍的那种心情。以后看了其它的书，才对C语言中的一些内容有更深的理解。相信大多数第一次接触C语言的人都有类似的感觉。不要期望一本启蒙的书带给你想要的一切，一切才刚刚开始。   	 2.C程序设计语言 作者 : Brian W.Kernighan/Dennis M.Ritchie  出版社 : 清华大学出版社  评语 : 第1本 《C程序设计语言》 Brian W. Kernighan / Dennis M. Ritchie 这本书又称为 R&K C，还有谁能比C语言之父对C语言更有发言权的呢？推荐看英文版。你会惊讶于在短短不到200页的篇幅内，这两位牛人将C语言描述的这么清晰。即使不专门学C语言的人也可以拿出来翻翻  	 3. C陷阱与缺陷 作者 : 凯尼格  出版社 : 人民邮电出版社  评语 : 第2本 《C陷阱与缺陷》Andrew Koenig Andrew Koenig的成名作，能帮助初学者减少90%的错误。一些错误（比如赋值符、运算符优先级等）还是不时的会在自己的程序里出现，只是已经打过预防针了，很容易发现。另外作者写了一本《Accelerated C++》，据说是C++的最佳入门书，狠赞！！  	 4. C专家编程 作者 : Peter Van Der Linden  出版社 : 人民邮电出版社  评语 : 第3本 《C专家编程》（LinDen,P.V.D） 一看书名就知道这丫不能拿来入门用的，第一次看的时候够折磨大脑的。作者声称，编程的唯一原因是因为乐趣。相比之前的几本书，这本书还介绍C语言运行的环境，更全面地考察了C语言。深入分析了C语言中一些容易混淆的概念，如复杂的声明和定义、数组和指针、链接和运行时库、内存等。很值得一读。 顺便一提：链接库可参考《深入理解计算机系统》的动态链接库一章，写得更易读  	 5. 编程精粹 作者 : Steve Maguire  出版社 : 人民邮电出版社  评语 : 第4本 《编程精粹：编写高质量C语言代码》 《Writing Solid Code》 Steve Maguire 这是我读到C语言书中最惊叹的一本，尽管写出没有bug的程序不太可能，但按照作者提供的方法，可以离这个目标很近。本书关注的更多是怎么使用C语言开发工业级产品的问题。 这本书源自作者十几年不断的追问自己两个简单的问题： 1）怎样才能自动地查出这个错误？ 2）怎样才能避免这个错误？ “他的另一部名著Debugging the Development Process（中文版《微软  	 6. C Interfaces and Implementations 作者 : David R. Hanson  出版社 : Addison-Wesley Professional  评语 : 第5本 《C Interfaces and Implementations》 David R. Hanson 这本据说为唯一一本能和R&K C并驾齐驱的书，可惜中文版众口一致说太烂，无处可载电子版，影印版跳票多年，原版USD 54.99实在承受不起，囊中羞涩，奈何奈何。想念多年，至今不能一睹芳容，深以为憾。  	 7. C标准库 作者 : P. J. Plauger  出版社 : 人民邮电出版社  评语 : 前面5本差不多够了，另外推荐两本，精力过剩的可以翻翻 第6本 《C标准库》P. J. Plauger 本书介绍C标准库的实现，书中有较为详尽的代码。虽然这本书年代久远，现在的实现肯定和以前也有差别，但是还是很有参考价值，特别是对C标准库的实现有兴趣的人。中文版太贵，英文电子版看得太累，还是以后有地方借的时候再继续看。  	 8. C语言参考手册 作者 : 哈比森  出版社 : 机械工业出版社  评语 : 第7本 《C语言参考手册》 拿来备查的，C语言的任何细节几乎都能在其中找到借到。书的第一部分介绍C语言语法细节。第二部分介绍运行时库，可以和《C标准库》参考阅读。

#pragma comment(lib,"user32") #pragma comment(lib,"gdi32") #include <windows.h> LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) {     PAINTSTRUCT ps;     HDC hdc;     HFONT hfont,ohfont;     RECT r;     COLORREF oc;      switch(message) {     case WM_CLOSE://按Alt+F4退出         PostQuitMessage(0);         break;     case WM_PAINT:         BeginPaint(hWnd, &ps);         hdc = ps.hdc; // the device context to draw in         GetClientRect(hWnd, &r); // Obtain the window's client rectangle         hfont = CreateFont(240, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "华文楷体");         ohfont=SelectObject(hdc,hfont);         oc=SetTextColor(hdc,0x00C080FF);         SetBkMode(hdc, TRANSPARENT);         TextOut(hdc,r.left+r.right/2-720, r.top+r.bottom/2-120,"最短画图程序",12);         SelectObject(hdc,ohfont);         SetTextColor(hdc,oc);         DeleteObject(hfont);         EndPaint(hWnd, &ps);         break;     default:         return DefWindowProc(hWnd, message, wParam, lParam);     }     return 0; } int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) {     MSG msg             = {0};     WNDCLASS wc         = {0};     HBRUSH hbrh;     hbrh=CreateSolidBrush(0x00000000);     wc.lpfnWndProc      = WndProc;     wc.hInstance        = hInstance;     wc.hbrBackground    = hbrh;     wc.lpszClassName    = "minwindowsapp";     wc.hCursor          = LoadCursor(NULL,IDC_ARROW);     if( FAILED(RegisterClass(&wc)) ) return 1;      if(FAILED(CreateWindow(wc.lpszClassName,                         "Minimal Windows Application",                         WS_POPUP|WS_VISIBLE,                         0,                         0,                         GetSystemMetrics(SM_CXSCREEN),                         GetSystemMetrics(SM_CYSCREEN),                         0,                         0,                         hInstance,                         NULL)))         return 2;      while( GetMessage( &msg, NULL, 0, 0 ) > 0 ) {         DispatchMessage( &msg );     }     DeleteObject(hbrh);     return 0; }  查MSDN是Windows程序员必须掌握的技能之一。


Question: 如何修改exe文件版本号和文件信息

你那应该是控制台程序吧，控制台程序也可以添加版本信息，项目右键 添加->资源...  选择Version 通过界面操作编辑好后，再重新编译一下。

请看我博客http://blog.csdn.net/func7/article/details/50556667#t9

引用 1 楼 zhao4zhong1 的回复: 引用 2 楼 Intel0011 的回复: 求教9楼的问题

我有一下几个问题： 1.我写了一个HelloWorld程序，为什么目录里没有rc后缀的文件？ 2.用ResHacker或eXeScope修改，可软件里能显示的只有这些？应该怎么修改？

一时半会还真没找到vs提供什么工具可以更改这些信息。

引用 6 楼 Intel0011 的回复:[quote=引用 4 楼 u013491662 的回复:] vs没有提供什么工具可以更改这些信息吗？ 如果你有源代码的话，在文件后缀为rc的资源文件中修改 没有的话，只能用ResHacker等工具，VS没提供[/quote]  我写了个HelloWorld!程序 发现目录下并没有后缀名为rc的文件！？？

引用 4 楼 u013491662 的回复:vs没有提供什么工具可以更改这些信息吗？ 如果你有源代码的话，在文件后缀为rc的资源文件中修改 没有的话，只能用ResHacker等工具，VS没提供

引用 4 楼 u013491662 的回复:vs没有提供什么工具可以更改这些信息吗？  [quote=引用 1 楼 zhao4zhong1 的回复:] 引用 2 楼 Intel0011 的回复: 引用 3 楼 zxhuser-4 的回复:[/quote] 只用过vc6.0，但老早就忘了怎么用了。。。

vs没有提供什么工具可以更改这些信息吗？  引用 1 楼 zhao4zhong1 的回复: 引用 2 楼 Intel0011 的回复: 引用 3 楼 zxhuser-4 的回复:

引用 2 楼 Intel0011 的回复:版本号和文件信息放在EXE文件的资源节中，可以使用资源查看、修改工具ResHacker或eXeScope软件+1

使用eXeScope软件？


Question: 来拿分吧，

因为表达式非零

打印的时候既然用了“||”，就表示要逻辑值喽。

逻辑表达式 或  一真全真，前面真就不不用再看后面

||截断运算，第一个非零就结束运算，结果为1

引用 楼主 li905663280 的回复: #include <stdio.h> int main(void) { int a,b=10,c=15; float x=12.345,y=0.1234;  printf("%d\n",x+y||a+b||c); getch();    }  结果为什么是1 因为这是逻辑“或”运算有非零，结果就是1

||操作符的结果只有0和1。你上面的操作结果刚好是1

程序判断真假是判断0和非0的，输出真假是输出0和1的 0为假 非0为真 x+y||a+b||c 第一个x+y因为是非0值 所以程序判断为真 此时整个表达式不再进行判断 x+y||a+b||c 的值为1

没想到这儿也有个优先级的问题

float x=12.345,y=0.1234;  printf("%d\n",x+y||a+b||c);  x+y  --->  1 a+b --->  1 c--->  1 1 || 1 || 1  --->  1

我来那分了..

老赵又在复制粘贴啦……

该说的都说了，我就打一下酱油算了

简单点说就是优先级问题 +的优先级大于|| 上面等式等价于printf("%d\n",(x+y)||(a+b)||c);  一目了然吧

计算机组成原理→DOS命令→汇编语言→C语言（不包括C++）、代码书写规范→数据结构、编译原理、操作系统→计算机网络、数据库原理、正则表达式→其它语言（包括C++）、架构……  对学习编程者的忠告： 眼过千遍不如手过一遍！ 书看千行不如手敲一行！ 手敲千行不如单步一行！ 单步源代码千行不如单步对应汇编一行！  VC调试时按Alt+8、Alt+7、Alt+6和Alt+5,打开汇编窗口、堆栈窗口、内存窗口和寄存器窗口看每句C对应的汇编、单步执行并观察相应堆栈、内存和寄存器变化，这样过一遍不就啥都明白了吗。 对VC来说，所谓‘调试时’就是编译连接通过以后，按F10或F11键单步执行一步以后的时候，或者在某行按F9设了断点后按F5执行停在该断点处的时候。 （Turbo C或Borland C用Turbo Debugger调试,Linux或Unix下用GDB调试时,看每句C对应的汇编并单步执行观察相应内存和寄存器变化。）  不要迷信书、考题、老师、回帖； 要迷信CPU、编译器、调试器、运行结果。 并请结合“盲人摸太阳”和“驾船出海时一定只带一个指南针。”加以理解。 任何理论、权威、传说、真理、标准、解释、想象、知识……都比不上摆在眼前的事实！  有人说一套做一套，你相信他说的还是相信他做的？ 其实严格来说这个世界上古往今来所有人都是说一套做一套，不是吗？  不要写连自己也预测不了结果的代码！

x+y||a+b||c  整个做为一个表达式  x+y 或上 a+ b 或上 c  x+y   a+b  c  中间有一个为1  ,或的结果就是1


Question: 关于Makefile的一点问题

首先明白makefile干嘛的，再去写~ makefile定义了一系列的规则来指定，哪些文件需要先编译，哪些文件需要后编译，哪些文件需要重新编译，甚至于进行更复杂的功能操作，因为 makefile就像一个Shell脚本一样，其中也可以执行操作系统的命令。

可以用makefile生成工具啊

注意：makefile中的Tab必须是真Tab字符而不能用4个或8个或若干个空格代替。

试试这个 -I不行的话改成-L试试  CC=gcc main:main.o 	$(CC) -I /usr/mongo-c-driver-0.98.0 -o main /usr/mongo-c-driver-0.98.0/src/*.o main.o: 	$(CC) -c /usr/mongo-c-driver-0.98.0/src/*.c

搜“跟我一起写makefile”


Question: 大写字母宽度

+1什么意思

引用 1 楼 u013491662 的回复:tm.tmPitchAndFamily & 1 ? 3 : 2 的意思是 tm.tmPitchAndFamily的2进制位的最低位是否为1 tm.tmPitchAndFamily & 1 为1此值为1 为0此值为0 根据这个值执行条件运算符的值为3还是为2+1

看不懂英文……

GetTextExtentPoint32 The GetTextExtentPoint32 function computes the width and height of the specified string of text.   BOOL GetTextExtentPoint32(   HDC hdc,           // handle to device context   LPCTSTR lpString,  // pointer to text string   int cbString,      // number of characters in string   LPSIZE lpSize      // pointer to structure for string size );   Parameters hdc  Handle to the device context.  lpString  Pointer to the string of text. The string does not need to be zero-terminated, since cbString specifies the length of the string.  cbString  Specifies the number of characters in the string.  lpSize  Pointer to a SIZE structure in which the dimensions of the string are to be returned.  Return Values If the function succeeds, the return value is nonzero.  If the function fails, the return value is zero.   Windows NT: To get extended error information, callGetLastError.   Remarks The GetTextExtentPoint32 function uses the currently selected font to compute the dimensions of the string. The width and height, in logical units, are computed without considering any clipping.   Because some devices kern characters, the sum of the extents of the characters in a string may not be equal to the extent of the string.   The calculated string width takes into account the intercharacter spacing set by the SetTextCharacterExtra function.   Windows CE: The GetTextExtentPoint32 function is identical to the GetTextExtentPoint function.  QuickInfo   Windows NT: Requires version 3.5 or later.   Windows: Requires Windows 95 or later.   Windows CE: Requires version 2.0 or later.   Header: Declared in wingdi.h.   Import Library: Use gdi32.lib.   Unicode: Implemented as Unicode and ANSI versions on Windows and Windows NT.  See Also Fonts and Text Overview, Font and Text Functions, SetTextCharacterExtra, SIZE

tmPitchAndFamily  Specifies information about the pitch, the technology, and the family of a physical font.  The four low-order bits of this member specify information about the pitch and the technology of the font. A constant is defined for each of the four bits: Constant Meaning  TMPF_FIXED_PITCH If this bit is set the font is a variable pitch font. If this bit is clear the font is a fixed pitch font. Note very carefully that those meanings are the opposite of what the constant name implies.  TMPF_VECTOR If this bit is set the font is a vector font.  TMPF_TRUETYPE If this bit is set the font is a TrueType font.  TMPF_DEVICE If this bit is set the font is a device font.     An application should carefully test for qualities encoded in these low-order bits, making no arbitrary assumptions. For example, besides having their own bits set, TrueType and PostScript fonts set the TMPF_VECTOR bit. A monospace bitmap font has all of these low-order bits clear; a proportional bitmap font sets the TMPF_FIXED_PITCH bit. A Postscript printer device font sets the TMPF_DEVICE, TMPF_VECTOR, and TMPF_FIXED_PITCH bits.   The four high-order bits of tmPitchAndFamily designate the font's font family. An application can use the value 0xF0 and the bitwise AND operator to mask out the four low-order bits of tmPitchAndFamily, thus obtaining a value that can be directly compared with font family names to find an identical match. For information about font families, see the description of the LOGFONT structure.    C:\Program Files\Microsoft Visual Studio\VC98\Include\WINGDI.H:     839: /* tmPitchAndFamily flags */     840: #define TMPF_FIXED_PITCH    0x01     841: #define TMPF_VECTOR             0x02     842: #define TMPF_DEVICE             0x08     843: #define TMPF_TRUETYPE       0x04

原来最低位为1是变宽字符  那程序运行中，按大小写切换键换成大写，由于不会触发create事件，cxCap不会改变，不是就出错了吗

tm.tmPitchAndFamily的低4位是字符间距，最低位是1有什么实际含义吗？这与求大写字母平均宽度有什么联系吗

if (0!=(tm.tmPitchAndFamily & 1)) {     cxCaps = 3 * cxChar / 2 ; } else {     cxCaps = 2 * cxChar / 2 ; }

也是  大一了还不能完全看懂真是有愧

英语也是一门计算机语言的说。


Question: c语言结构体初始化错误

C编译器，结构体初始化赋值才能定义赋值 需要如下这样： struct timeval time_start = time_end = time1 = time2 = time3 = time4 = time5 = {0，0};

好像结构体不能这样直接赋值，看看大神怎么解释。。。混分

Summary of Statements statement :  labeled-statement compound-statement expression-statement selection-statement iteration-statement jump-statement try-except-statement   /* Microsoft Specific */ try-finally-statement   /* Microsoft Specific */  jump-statement :  goto identifier ; continue; break; return expression opt ;  compound-statement :  { declaration-list opt statement-list opt }  declaration-list :  declaration declaration-list declaration  statement-list :  statement statement-list statement  expression-statement :  expression opt ;  iteration-statement :  while ( expression ) statement do statement while ( expression ); for ( expression opt ; expression opt ; expression opt ) statement  selection-statement :  if ( expression ) statement if ( expression ) statement else statement switch ( expression ) statement  labeled-statement :  identifier : statement case constant-expression : statement default : statement  try-except-statement :   /* Microsoft Specific */  __try compound-statement __except ( expression ) compound-statement  try-finally-statement :   /* Microsoft Specific */  __try compound-statement __finally compound-statement

Summary of Declarations declaration :  declaration-specifiers attribute-seq opt init-declarator-list opt ;                         /* attribute-seq is Microsoft Specific */  declaration-specifiers :  storage-class-specifier declaration-specifiers opt type-specifier declaration-specifiers opt type-qualifier declaration-specifiers opt  attribute-seq :            /* attribute-seq is Microsoft Specific */  attribute attribute-seq opt  attribute : one of      /* Microsoft Specific */  __asm __fastcall  __based __inline  __cdecl __stdcall    init-declarator-list :  init-declarator init-declarator-list , init-declarator  init-declarator :  declarator declarator = initializer /* For scalar initialization */  storage-class-specifier :  auto register static extern typedef __declspec ( extended-decl-modifier-seq ) /* Microsoft Specific */  type-specifier :  void char short int __int8       /* Microsoft Specific */ __int16      /* Microsoft Specific */ __int32      /* Microsoft Specific */ __int64      /* Microsoft Specific */ long float double signed unsigned struct-or-union-specifier enum-specifier typedef-name  type-qualifier :  const volatile  declarator :  pointer opt direct-declarator  direct-declarator :  identifier ( declarator ) direct-declarator [ constant-expression opt] direct-declarator ( parameter-type-list )   /* New-style declarator */ direct-declarator ( identifier-list opt )      /* Obsolete-style declarator */  pointer :  * type-qualifier-list opt * type-qualifier-list opt pointer  parameter-type-list :                           /* The parameter list */  parameter-list parameter-list , ...  parameter-list :  parameter-declaration parameter-list , parameter-declaration  type-qualifier-list :  type-qualifier type-qualifier-list type-qualifier  enum-specifier :  enum identifier opt { enumerator-list } enum identifier  enumerator-list :  enumerator enumerator-list , enumerator  enumerator :  enumeration-constant enumeration-constant = constant-expression  enumeration-constant :  identifier  struct-or-union-specifier :  struct-or-union identifier opt { struct-declaration-list } struct-or-union identifier  struct-or-union :  struct union  struct-declaration-list :  struct-declaration struct-declaration-list struct-declaration  struct-declaration :  specifier-qualifier-list struct-declarator-list ;  specifier-qualifier-list :  type-specifier specifier-qualifier-list opt type-qualifier specifier-qualifier-list opt  struct-declarator-list :  struct-declarator struct-declarator-list , struct-declarator  struct-declarator :  declarator type-specifier declarator opt : constant-expression  parameter-declaration :  declaration-specifiers declarator                /* Named declarator */ declaration-specifiers abstract-declarator opt /* Anonymous declarator */  identifier-list :      /* For old-style declarator */  identifier identifier-list , identifier  abstract-declarator :         /* Used with anonymous declarators */  pointer pointer opt direct-abstract-declarator  direct-abstract-declarator :  ( abstract-declarator ) direct-abstract-declarator opt [ constant-expression opt ] direct-abstract-declarator opt ( parameter-type-list opt )  initializer :  assignment-expression { initializer-list }   /* For aggregate initialization */  { initializer-list , }  initializer-list :  initializer initializer-list , initializer  type-name :  specifier-qualifier-list abstract-declarator opt  typedef-name :  identifier  extended-decl-modifier-seq :/*   Microsoft Specific */  extended-decl-modifier opt extended-decl-modifier-seq extended-decl-modifier  extended-decl-modifier :   /* Microsoft Specific */  thread naked dllimport dllexport

引用 2 楼 zhao4zhong1 的回复:“变量赋值”和“变量初始化”不是一回事！ “变量赋值”发生在运行期，其写法遵循赋值语法规定。 “变量初始化”发生在编译期或运行期，其写法遵循初始化列表语法规定。  有对应的赋值语法和初始化语法说明吗

对结构体用{}赋值只能在初始化中进行 struct timeval time_start, time_end,ime1, time2, time3, time4, time5 = { 0 }; time_start = time_end = time1 = time2 = time3 = time4 = time5;

C Assignment Operators An assignment operation assigns the value of the right-hand operand to the storage location named by the left-hand operand. Therefore, the left-hand operand of an assignment operation must be a modifiable l-value. After the assignment, an assignment expression has the value of the left operand but is not an l-value.  Syntax  assignment-expression :  conditional-expression unary-expression assignment-operator assignment-expression  assignment-operator : one of  =   *=   /=   %=   +=   –=   <<=   >>= &=   ^=   |=   The assignment operators in C can both transform and assign values in a single operation. C provides the following assignment operators:  Operator Operation Performed  =  Simple assignment  *=  Multiplication assignment  /=  Division assignment  %=  Remainder assignment  +=  Addition assignment  –=  Subtraction assignment  <<=  Left-shift assignment  >>=  Right-shift assignment  &=  Bitwise-AND assignment  ^=  Bitwise-exclusive-OR assignment  |=  Bitwise-inclusive-OR assignment    In assignment, the type of the right-hand value is converted to the type of the left-hand value, and the value is stored in the left operand after the assignment has taken place. The left operand must not be an array, a function, or a constant. The specific conversion path, which depends on the two types, is outlined in detail in Type Conversions.

这个也没有介绍两者具体的语法


Question: 自己写的程序在别人的电脑上运行不了?

用depends.exe查看exe依赖的dll，看缺哪些dll 将缺的dll放在exe相同目录下。

引用 14 楼 u013491662 的回复:感谢各位 我明白release版本是什么了 [quote=引用 7 楼 zjq9931 的回复:] 1.发布成release 2.使用静态库。 是发布成release的 同时 使用静态库才可以？ 还是发布成release 或者 使用静态库 选二者其一就可以了？[/quote] 两者都选。

感谢各位 我明白release版本是什么了 引用 7 楼 zjq9931 的回复:1.发布成release 2.使用静态库。 是发布成release的 同时 使用静态库才可以？ 还是发布成release 或者 使用静态库 选二者其一就可以了？

Release是程序的发布版本，如果你需要别人机器运行你的程序，应该使用这个版本，而不是Debug调试版。而且别人机器还需要2013的.net framework。

引用 7 楼 zjq9931 的回复:1.发布成release 2.使用静态库。 请问release是什么？干什么用的？有什么用？

引用 10 楼 zxh707wk 的回复:release 请问release是什么？干什么用的？有什么用？

release

平台工具集那个地方下拉一下，有个xp。。。（具体是什么忘记了）选项的，选择之 ,如果没有的话，应该是需要加装一些东西 然后选择在静态库中使用MFC静态库   vc6,vs2003相对来说耗资源少很多，2008以后就感觉太大了，跑起来慢

第一个选则： 静态连接CRT库: /MT(release),  /MTd(debug) 第二个选则： 在ta的电脑上安装vc++ 2013 redistributable packages(运行时库，CRT）

1.发布成release 2.使用静态库。

引用 12 楼 u013491662 的回复:[quote=引用 7 楼 zjq9931 的回复:] 1.发布成release 2.使用静态库。 请问release是什么？干什么用的？有什么用？[/quote] Debug通常称为调试版本，它包含调试信息，并且不作任何优化，便于程序员调试程序。Release称为发布版本，它往往是进行了各种优化，使得程序在代码大小和运行速度上都是最优的，以便用户很好地使用。

使用静态库。。

1，在“标准”工具栏中把“解决方案配置”改为release 2，下载msvcp120.dll复制到*/Windows/SYSTEM32下，即可解决问题。

引用 2 楼 lcy_888 的回复:使用Release方式，并这样设置：解决方案->属性->常规->MFC的使用->在静态库中使用MFC->确定。 编译后就可以在别的机子上正常运行了。 是这样吗？

引用 1 楼 u012421456 的回复:看有帮助没——http://zhidao.baidu.com/link?url=yckmLecaJ2OABlWl2NA_1axacHxhMi3u4zSkDyrW9ubZzigi5yCr4RPC901sHvlEgkbTWooOl_pyUvcjkO6IZHNIqgWlJUfdqyRxFZmU64K 我是新手 没接触过这类情况，能说的详细点吗？具体怎么操作？


Question: 指针指向的字符串是否可以进行数组的操作？

char *p = "ubantu"; 中，p是否可以利用p++操作获得每一个字符？ 可以！ char *p = "ubantu"; 中，申请的内存存放方式是如何的？ p存储在栈。 ”ubantu“存储在只读数据段中。

可读不可写。。。。

char *p = "ubantu"; 中，p是否可以利用p++操作获得每一个字符？ 可以，不过你要判断是否到了字符结束符‘\0’,防止越界 while（*p!='\0'） { 。。。*p。。。。           p++  } char *p = "ubantu"; 中，申请的内存存放方式是如何的？ 如果你是定义为局部变量的话，就是在栈上开辟一片连续的内存空间，依次存放'u' ,'b','a','n','t','u','\0'.

引用 9 楼 xhw88398569 的回复:可读不可写。。。。+1

引用 5 楼 robertbo 的回复:1、可以用p++，但注意内存越界。 2、p是临时变量，存储在栈区。"ubantu"存储在常量去，可以使用但不能修改。  +20

VMMap 是进程虚拟和物理内存分析实用工具。http://technet.microsoft.com/zh-cn/sysinternals/dd535533

#pragma comment(linker,"/SECTION:.rdata,RW") //加这句可以让常量区可写，后果自负！  不在调试时按Alt+6打开内存窗口看具体内存值，就想彻底弄明白内存存放方式？

引用 楼主 u014627144 的回复:char *p = "ubantu"; 中，p是否可以利用p++操作获得每一个字符？ char *p = "ubantu"; 中，申请的内存存放方式是如何的？ 可以读取，但不可修改。 因为这是字符串常量。  char *p = "ubantu"; 中，申请的内存存放方式是如何的？ --------------------------------------- 这个在内存的栈区。程序启动的时候就申请了内存。  如果想要修改字符串的内容可以这样： char *p= (char*)malloc(strlen("ubantu")+1); strcpy(p, "ubantu"); 这个时候是可以安全修改的。 用完记得free

char s[] = *p;

可以，别越界，最大范围为发现\0就要break

应该是ubuntu不是ubantu

char *p = "ubantu"; char s[] = &p;


Question: char s[]与char *有区别吗

引用 20 楼 hjgzj 的回复:[quote=引用 17 楼 zhao4zhong1 的回复:] #pragma comment(linker,"/SECTION:.rdata,RW") //加这句可以让常量区可写，后果自负！  举报你作弊[/quote] 程序员应当拥有对内存中每个字节读写的权利！

引用 17 楼 zhao4zhong1 的回复:#pragma comment(linker,"/SECTION:.rdata,RW") //加这句可以让常量区可写，后果自负！  举报你作弊

引用 1 楼 Intel0011 的回复:char s[]与char *s作为函数形参时没什么区别 但 char s[] = "test"; char *s= "test"; 有区别，前者s所指的字符串可以修改（因为编译器将字符串放在栈区），后者不可以（因为编译器将字符串放在常量区） +1  楼上正解！

引用 11 楼 mujiok2003 的回复: #include <iostream> int main() { 	char s1[] = "test"; 	char *s2= s1;  	*s1 = 'a'; 	*s2 = 'b';  	printf("%s %s\n",s1,s2);      return 0;   }   指向到哪一步都不会出错 char* 看来也可写吗?

引用 1 楼 Intel0011 的回复:char s[]与char *s作为函数形参时没什么区别 但 char s[] = "test"; char *s= "test"; 有区别，前者s所指的字符串可以修改（因为编译器将字符串放在栈区），后者不可以（因为编译器将字符串放在常量区）存放在所谓 常量区 的是 "test" 这个数组  而不是char* s 这个指针  什么后者不能修改 什么char* 不能修改 真是玩笑  说得好像 char str[10], *pstr = str; 没有人这样做似得  你所谓的区别是 字符串字面量的特殊条例  而且 这个条例不是 不可以修改 是修改了谁也不知道会发生什么[那是未定义行为 类似 i = i++]

引用 13 楼 xhw88398569 的回复:[quote=引用 9 楼 mujiok2003 的回复:] [quote=引用 7 楼 henry3695 的回复:] 前者可读写，后者只读  后者怎么就只读了？ [/quote]第二个“test”放在常量区，所以就只读了[/quote]  oh, yeah. i see what u talking about

引用 13 楼 xhw88398569 的回复:[quote=引用 9 楼 mujiok2003 的回复:] [quote=引用 7 楼 henry3695 的回复:] 前者可读写，后者只读  后者怎么就只读了？ [/quote]第二个“test”放在常量区，所以就只读了[/quote] 什么"test"

引用 9 楼 mujiok2003 的回复:[quote=引用 7 楼 henry3695 的回复:] 前者可读写，后者只读  后者怎么就只读了？ [/quote]第二个“test”放在常量区，所以就只读了

一个运行时赋值，一个编译时赋值

引用 10 楼 henry3695 的回复:[quote=引用 9 楼 mujiok2003 的回复:] [quote=引用 7 楼 henry3695 的回复:] 前者可读写，后者只读  后者怎么就只读了？ [/quote]   #include <iostream> int main() { 	char s1[] = "test"; 	char *s2= "test";  	*s1 = 'a'; 	*s2 = 'b';  	printf("%s %s\n",s1,s2);      return 0;   }     vc6 执行到  *s2 = 'b'; 这句话就报错了，试图去修改常量区域的数据，系统不让改  --------------------------- Microsoft Visual C++ --------------------------- Unhandled exception in test.exe: 0xC0000005: Access Violation. --------------------------- 确定    --------------------------- [/quote]  汗， 那是char*指向的内容， 不是char*本身只读。   这种情况本来该用char const*

引用 9 楼 mujiok2003 的回复:[quote=引用 7 楼 henry3695 的回复:] 前者可读写，后者只读  后者怎么就只读了？ [/quote]   #include <iostream> int main() { 	char s1[] = "test"; 	char *s2= "test";  	*s1 = 'a'; 	*s2 = 'b';  	printf("%s %s\n",s1,s2);      return 0;   }     vc6 执行到  *s2 = 'b'; 这句话就报错了，试图去修改常量区域的数据，系统不让改  --------------------------- Microsoft Visual C++ --------------------------- Unhandled exception in test.exe: 0xC0000005: Access Violation. --------------------------- 确定    ---------------------------

引用 7 楼 henry3695 的回复:前者可读写，后者只读  后者怎么就只读了？

一个是数组，一个是指针。 数组，在内存中所控制的范围不可变，即所指向的地址不可变。但地址中的内容，可变。除非程序中声明是const变量。 指针，在内存中所控制的范围可变，即所指向的地址可变。地址中的内容，根据程序启动时分配的范围来决定地址是否可变。

前者可读写，后者只读

char* s是字符串指针，char sz[]是字符数组。你可以用sizeof(sz)/sizeof(char)看sz里面有多少个字符，但是char* s只能用strlen(s); sizeof(s)==指针大小，32位是4个BYTE.. 作为形参，char sz[]传的是数组首地址，也是指针。。。这就和s一样了。。

有区别，其中前面都有提到过，还有一个就是char s[]中的s是作为常量，是不能做指针自加(++)的操作，但是char * 可以，这也是区别之一

本质上都是指针，只是一个看做数组而已。

看大牛们回答，是一种享受

引用 22 楼 henry3695 的回复:[quote=引用 21 楼 zhao4zhong1 的回复:] [quote=引用 20 楼 hjgzj 的回复:] [quote=引用 17 楼 zhao4zhong1 的回复:] #pragma comment(linker,"/SECTION:.rdata,RW") //加这句可以让常量区可写，后果自负！  举报你作弊[/quote] 程序员应当拥有对内存中每个字节读写的权利！[/quote]  感觉破坏了规则，总是会有些问题 不知道在什么情况下需要用到这种奇怪的需求 [/quote] 知道什么叫“热更新”吗？ http://bbs.csdn.net/topics/390627329


Question: qsort函数中的comp函数的一点问题

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

第一段代码的函数参数类型不符合要求， 第二段代码的效率有问题，用指针多好  int cmp1(const void* a,const void* b) {   node *i = (node*)a;   node *j = (node*)b;   return (-i->pos-3)*i->w - (-j->pos-3)*j->w; }

qsort的第四个参数要求输入一个指向函数的指针，stdlib.h里的定义是_In_ int (__cdecl * _PtFuncCompare)(const void *, const void *)，因为指向int cmp1(node i,node j)的函数指针，与要求的参数不匹配，所以不能作为qsort的参数，而int cmp1(const void* a,const void* b)可以作为qsort的参数

const void *a 这是定义了一个指针a，a可以指向任意类型的值，但它指向的值必须是常量。  在这种情况下，我们不能修改被指向的对象，但可以使指针指向其他对象。  例如：  const void *a；*a=0x123;//是编译通不过的，因为*a中放的是个const值。const值是不能被改变的。  const int  m=1;     const int n=2;  a=&m;    a=&n;//编译可以通过。     void* const  a 这是定义了一个const指针a，a可以指向任意类型的值，但a是指向某个对象的常量指针。  我们不能修改指针中存储的地址，但可以修改指针指向的对象。  例如：  void* const  a;这个定义：*a=0x123;是没问题的，  但是a=(void*)&b;是不行的，因为a是const变量。  如：  int  m=1;     nt n=2;  a=&m;    a=&n;//编译不成功。

qsort 是C库函数，实现对数组的快速排序， 要求传递，对指针所指对象比较的，比较函数（一个函数指针），作为参数。 这个函数指针的对应的函数， 两个指针参数，对应数组的两个元素的地址。 这个函数不适合链表排序。


Question: 求时间复杂度如何计算

指数形式的增长，计算的次数就是对数级的，也就是说时间复杂度是对数级。 对数形式的增长，计算次数是指数级，即指数级。 线性形式增长，时间复杂度也是线性的

1+2+4+8+... =2^(⌊lgn⌋+1)-1


Question: 关于平衡二叉树的问题

#define EH 0 #define LH +1 #define RH -1 void LeftBalance(BiTree *T) {     BiTree L,Lr; 	L=(*T)->lchild; 	switch(L->bf) 	{ 	case LH: 		(*T)->bf=L->bf=EH; 		R_Rotate(&(*T)->lchild); 		break; 	case RH: 		Lr=L->rchild; 		switch(Lr->bf) 		{ 		case LH: 		      (*T)->bf=RH; 			  L->bf=EH; 			  break; 		case EH: 			(*T)->bf=L->bf=EH; 		case RH: 			(*T)->bf=EH; 			L->bf=LH; 			break; 		} 		Lr->bf=EH; 		L_Rotate(&(*T)->lchild); 		R_Rotate(T); 		break; 	} }


Question: 这个C程序错在哪？

还不结贴在等啥！

if (fpout=fopen("ab.txt","r")==NULL)  -----> if ((fpout=fopen("ab.txt","r") )==NULL) 注意运算符优先级，赋值运算符的优先级是相当低的 下面还有一个类似的句子，楼主自己改吧


Question: 四舍五入

引用 3 楼 boxmanstan 的回复:[quote=引用 2 楼 lovesmiles 的回复:] float的精度是6至7位。超过七位的有效值它是不保证的。你最后一位已经是八位有效值了，float肯定表示不了。所以达不到你想要的效果。double可以表示到16位有效位，所以没有问题  你是说小数点前面的也算在内是吗[/quote]  明白了

引用 2 楼 lovesmiles 的回复:float的精度是6至7位。超过七位的有效值它是不保证的。你最后一位已经是八位有效值了，float肯定表示不了。所以达不到你想要的效果。double可以表示到16位有效位，所以没有问题  你是说小数点前面的也算在内是吗

double乘int  是double  这里也没有越界，怎么转float就不对了


Question: winpcap中的MAC源地址过滤的问题

用wireshark测试自己的语句


Question: 为什么指针参数里的vector数组不能正确返回数据

把代码简化一下，就好比你在练武功，练了一段让别人看不出套路的武功，哈哈

你的变量是Vector<>*，没看到你new Vector啊？ (我在其他地方NEW的，怕写全了搞乱的大家的思路，就简化了，没想到大家还是觉得乱，呵呵）  引用 2 楼 lucifer886 的回复:[quote=引用 楼主 xh5000 的回复:] TopoDeviceData* Device = (*mission)->Region->RegionSearch_Instance->List_Device_Retrieval[deviceID]; (*mission)->tempErrDevs->push_back( Device);  调用g_MissionControl.DevOperJudge(&mission);后得到的mission对象，tempErrDevs数组里没有数据了。 在函数里插入的一个Device对象不是临时NEW出来的，而是存储在一个全局变量中的。 也许可能你在TopoDeviceData* Device = (*mission)->Region->RegionSearch_Instance->List_Device_Retrieval[deviceID];取出来就有问题，你push一个空指针进去vector又不会给你报错。 [/quote] 我在获得这个对象的时候监视过，跟踪过，是有数据的。  我觉得是在这里vector数组里重新new了一次导致的数据返回不出来。不知道我猜测的是不是这样

好乱的代码。

引用 楼主 xh5000 的回复:TopoDeviceData* Device = (*mission)->Region->RegionSearch_Instance->List_Device_Retrieval[deviceID]; (*mission)->tempErrDevs->push_back( Device);  调用g_MissionControl.DevOperJudge(&mission);后得到的mission对象，tempErrDevs数组里没有数据了。 在函数里插入的一个Device对象不是临时NEW出来的，而是存储在一个全局变量中的。 也许可能你在TopoDeviceData* Device = (*mission)->Region->RegionSearch_Instance->List_Device_Retrieval[deviceID];取出来就有问题，你push一个空指针进去vector又不会给你报错。

你的变量是Vector<>*，没看到你new Vector啊？


Question: 求教一个C中的递归

题目内容：   有一堆石子，A，B两人轮流从中取出石子，每次取出的石子数目只能为1，3，7或8，最后一枚石子谁取到就是输方。A,B两人都足够聪明，不会做出错误的判断。现给出一定数目的石子，A先取石子，计算A最终是输是赢，赢用1表示，输用0表示.   输入描述   第一行为一个整数n(0< n <=100),表示玩n局，接下来n行每行有一个整数，表示对应的局提供的石子数（不大于10000），   输出描述   编程输出A对应的n局是赢是输，赢输出1，输输出0.  输入样例   3 1 3 10  输出样例   0 0 1

引用 8 楼 Idle_ 的回复:引用直接判断正负，然后%2不就行了吗 但是楼主给出的例子就是用另类的方法实现这个功能呀（也许为了教学递归或者考学生是否理解了递归）好BT的题目

引用 6 楼 Idle_ 的回复:针对输入数组中的正整数如果是奇数则输出0，偶数输出1， 0和负数输出0直接判断正负，然后%2不就行了吗

针对输入数组中的正整数如果是奇数则输出0，偶数输出1， 0和负数输出0

引用 楼主 chengyunyi123 的回复:代码： #include <stdio.h> int win(int ballnums) {  if(ballnums <= 1) return false;  if(ballnums == 3) return false;  if(ballnums == 7) return false;  if(ballnums == 8) return true;  else return  !win(ballnums - 1)||  !win(ballnums - 3)||  !win(ballnums - 7)||  !win(ballnums - 8); } int main() {  int save[100];  int i,n;  scanf("%d",&n);  for(i = 0;i < n;++i)  { 	scanf("%d",&save[i]);  }  for(i = 0;i < n;++i)  {  printf("%d\n",win(save[i]));  } } 子函数中的递归不知道怎么递归的 ，想知道具体讲解。求教C高手。 递归就是自己调用自己，直到符合一定的条件后返回。

你应该先告诉大伙你的程序是打算干嘛的。

引用 2 楼 chengyunyi123 的回复: 谢谢老师。毕竟是新手，还不会调试。。 个人意见：新手首先要学会调试。

谢谢老师。毕竟是新手，还不会调试。。

“给定一个小点的输入，完整单步跟踪(同时按Alt+7键查看Call Stack里面从上到下列出的对应从里层到外层的函数调用历史)一遍。”是理解递归函数工作原理的不二法门！ 递归函数关注以下几个因素 ·退出条件 ·参数有哪些 ·返回值是什么 ·局部变量有哪些 ·全局变量有哪些 ·何时输出 ·会不会导致堆栈溢出  代码功能归根结底不是别人帮自己看或讲解或注释出来的；而是被自己静下心来花足够长的时间和精力亲自动手单步或设断点或对执行到某步获得的中间结果显示或写到日志文件中一步一步分析出来的。 提醒：再牛×的老师也无法代替学生自己领悟和上厕所！ 单步调试和设断点调试（VS IDE中编译连接通过以后，按F10或F11键单步执行，按Shift+F11退出当前函数；在某行按F9设断点后按F5执行停在该断点处。）是程序员必须掌握的技能之一。


Question: 做了一个图书管理系统，出了点问题，求大神解答！

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

printf里面的%和变量的一一对应关系 scanf里面的%和变量以及变量前加不加&的一一对应关系 是C代码中非常容易出错的地方，而且通常编译还不出错。 所以在编译源代码之前值得专门仔细检查一遍甚至多遍。  在每个最后不带\n的printf后面加fflush(stdout); 在每个不想受接收缓冲区旧内容影响的scanf前面加rewind(stdin); 另外请检查scanf的返回值。


Question: C程序设计语言1.9一道字符数组例题

引用 5 楼 zxh707wk 的回复:引用 4 楼 u012184298 的回复:'\n'会被'\0'替换掉为什么会这样？如果我新定义一个字符数组 char[2]，初始化赋给'a'和'b'，它后面就会输出一堆乱码，这时为什么不把'b'替换为'\0'？ 应该是"a"和"b" [/quote]对啊，我记得编译器会在字符数组里字符串末尾加'\0'，不知道这种情况下它还会把原来有的东西替换掉。

引用 4 楼 u012184298 的回复:'\n'会被'\0'替换掉为什么会这样？如果我新定义一个字符数组 char[2]，初始化赋给'a'和'b'，它后面就会输出一堆乱码，这时为什么不把'b'替换为'\0'？[/quote] 应该是"a"和"b"

引用 3 楼 zxh707wk 的回复:[quote=引用 2 楼 u012184298 的回复:] 其实我想问，如果我在第array[9]输入'\n'的话，这个函数会怎么执行？ '\n'会被'\0'替换掉[/quote]为什么会这样？如果我新定义一个字符数组 char[2]，初始化赋给'a'和'b'，它后面就会输出一堆乱码，这时为什么不把'b'替换为'\0'？

引用 2 楼 u012184298 的回复:其实我想问，如果我在第array[9]输入'\n'的话，这个函数会怎么执行？ '\n'会被'\0'替换掉

引用 1 楼 user-2 的回复:int getline(char s[],int lim) {     int c,i; //向数组里写入字符, 其中字符不是结束符并且也不是换行符     for(i = 0;i < lim - 1 && (c=getchar())!=EOF && c!='\n'; ++i)         s[i] = c;  //如果是换行符的话,换行符也算一个字符     if(c=='\n'){         s[i] = c;         ++i;     } //最后一个写入结束符     s[i] = '\0';     return i; }   也就是说,数组的大小是10的话  array[0-7]是字符 , array[8]是'\n' array[9]是'\0'其实我想问，如果我在第array[9]输入'\n'的话，这个函数会怎么执行？


Question: 二维数组可以用一维数组表示吗？

谢谢707wk、lovesmiles 、zjq9931！

引用 楼主 lc_csdn 的回复:我用在学习C语言，碰到一个程序如下： # include<stdio.h> # define N 3 # define M 4 int main(void) { 	int arradd(int arr[],int n); 	static int a[N][M]={1,3,5,7,9,11,13,15,17,19,21,23}; 	int *p,total1,total2; 	int (*pt)(int arr[],int n); 	pt=arradd; 	p=a[0]; 	total1=arradd(p,N*M); 	total2=(*pt)(p,N*M); 	printf("total1=%d\ntotal2=%d\n",total1,total2); 	return 0; } int arradd(int a[],int n) { 	int i,sum=0; 	for(i=0;i<n;i++) 		sum+=a[i]; 	return sum; } 请问在被调用的函数arradd(int a[],int n)中怎么可用一个a[i]来表示主程序中的a[N][M]呢？请高手指点，谢谢！ 相当于把二维数组拉直了，就是一维数组。 1维数组相当于根线，而二维数组相当于由一根线织成的布，从宏观上看，这个布有了各种曲折，编制，但我们沿着一根线走下去还是可以把这片布过完的。

因为二维数组内存的排列也是线性的。所以用线性的一维来访问也没有问题。

按照数组的存储形式，二维数组可以当一维数组来用。。。 比如#include <stdio.h>  int main() { 	int a[2][3]; 	int i; 	for(i=0;i<6;i++) 	{ 		*(*a+i)=i; 	} 	for(i=0;i<6;i++) 	{ 		printf("%3d",*(*a+i)); 	} 	return 0; }

i = Row * M + Col

a[y*M+x]


Question: 耶稣有13个门徒,其中有一个就是出卖耶稣的人,报数,1,2,3,1,2,3,1,2,3...凡是报到3的就退出圈子,最后留在圈中的就是出卖耶稣的叛徒,请找出它原

能用数据结构编写么，约瑟夫

为啥我的答案是2.

终于有自己的耶稣了,哈哈哈.. #define M 13//M为总人数 #define N 3 //N为循环单元     int a[M] = {0}, count = 0, people = M;//count计数(0-3), people为当前人数     printf("原序列:\n");     for (int i = 1; i <= M; i++) {         a[i - 1] = i;         printf("%d ", a[i - 1]);     }//赋值     printf("\n开始排除...\n");     while (people > 1) {//当前人数大于一时,继续进入循环进行排除         for (int p = 0; p < M; p++) {//排除的趟数循环             if (a[p] != 0) {                 count++;             }//如果当前数不为0,则count加1,直到count为3             if (count == N) {                 printf("%d被排除\n排除后的序列为:\n", a[p]);//排除当前数                 a[p] = 0;//当前数标记为0,说明已被排除                 for (int i = 0; i < M; i++) {                     printf("%d ", a[i]);                 }//打印本趟排除后的序列结果                 printf("\n");                 count = 0;//重新计数                 people--;//当前人数减1             }         }     }     for (int i = 0; i < M; i++) {         if (a[i] != 0) {             printf("%d是叛徒\n", a[i]);         }//遍历序列,若不为0则为叛徒     }

引用 26 楼 u013491662 的回复: #include <stdio.h> int main() { 	int a[7] = { 0 }, count = 0, number = 7, p = 0, q = 0; 	for (int i = 0; i < 7; i++) { 		a[i] = i; 	} 	while (number > 0) { 		//数组a:0 1 2 3 4 5 6 		for (int i = count; i < number; i++, count++) { 			if ((count + 1) % 3 == 0) { 				printf("%d被排除\n", a[count]); 				a[count] = 8;//8为清除代码 				p = count + 1; 				q = count; 			} 		} 		//数组a:0 1 8 3 4 8 6 		int t[] = { 0 }, j = 0;//数组t:0   数组t里就一个元素！ 		for (j = 0; j < number % 3; j++, p++) { 			t[j] = a[p]; 			printf("新序列:%d ", t[j]); 		} 		//数组t：6 		//j等于1 		for (int i = 0; i < q; i++) { 			if (a[i] != 8) { 				t[j] = a[i];//第一次执行，j等于1，下标越界 				j++; 			} 		} 		p = 0; 		number -= (count / 3); 		count = 0; 		if (number == 1) { 			printf("出卖耶稣的人的序号为%d", a); 		} 	} 	return 0; }  果然是大神啊,我百思不得其解,最后放弃了,换了一种方法

来个数学解法，结果为13 //约瑟夫环问题数学解法,时间复杂度为O(n) //约瑟夫环问题数学解法,时间复杂度为O(n) #include <stdio.h>  #define N 13 #define M  3  int main(void)  {     int i, s = 0;           for (i = 2; i <= N; ++i)        s = (s + M) % i;        printf("叛徒 is %d\n", s + 1);    return 0; }

引用 22 楼 u013491662 的回复:那段代码是我刚学C的时候写的，所以跟别人的比不是很好，你的代码有什么bug？贴出来 int a[7] = {0}, count = 0, number = 7, p = 0, q = 0; for (int i = 0; i < 7; i++) {     a[i] = i; }while (number > 0) {     for (int i = count; i < number; i++, count++) {         if ((count + 1) % 3 == 0) {             printf("%d被排除\n", a[count]);             a[count] = 8;//8为清除代码             p = count + 1;             q = count;         }     }     int t[] = {0}, j = 0;     for (j = 0; j < number % 3; j++, p++) {         t[j] = a[p];         printf("新序列:%d ", t[j]);     }     for (int i = 0; i < q; i++) {         if (a[i] != 8) {             t[j] = a[i];             j++;         }     }     p = 0;     number -= (count / 3);     count = 0;     if (number == 1) {         printf("出卖耶稣的人的序号为%d", a);     } } 求大神帮一下

初学编程时遇到这类问题先甭管它属于什么问题，一定要先思考，再用循环加数组进行动手操作，这是最能锻炼的了。

最后那个人的编号是不是2呀！

引用 4 楼 henry3695 的回复: //我来个递归的 //.c代码还真不太好写，函数申明无参数，变量都要放到开头，不习惯呵呵  #include "stdio.h" int find_last(int*,int); void  main() { 	int a[13]; 	int i; 	int last_id; 	for(i=0;i<13;i++) 	{ 		a[i]=i+1; 	}	  	last_id =find_last(a,13);  	printf("出卖者:a[%d] = %d \n",last_id,a[last_id]);  }  int find_last(int* p,int nlen) { 	int size=0; 	int i=0; 	int t=0; 	for (;i<nlen;i++) 	{ 		if (p[i]>0) 		{ 			size++; 		} 	} 	if (size==1) 	{ 		for (i=0;i<nlen;i++) 		{ 			if (p[i]>0) 			{ 				return i; 			} 		} 		return -1; 	}	 	i = 0; 	while(1) 	{ 		if(i == nlen) 		{ 			i = 0; 		} 		 		if (p[i]>0) 		{ 			t++; 			if (t==3) 			{ 				p[i]=0; 				break; 			} 		} 		i++; 	} 	return find_last(p,nlen); }  方法和思路都很好, 但结果是不是不正确啊..

引用 1 楼 u013491662 的回复:仅供参考  #include <stdio.h> int main() { 	int a[13]; 	for (int i = 0; i < 13; i++) 		a[i] = 1; 	void fun(int *, int); 	fun(a, 13); 	return 0; } void fun(int *a, int size) { 	int flag = 0,mun = size,*yuan=a; 	while (mun > 1) 	{ 		for (flag = 1; flag < 4; flag++) 		{ 			if (a == yuan + size) 				a = yuan; 			while (*a == 0) 			{ 				a++; 				if (a == yuan + size) 					a = yuan; 			} 			if (flag == 3) 			{ 				*a = 0;  				mun--; 			} 			a++; 		} 	} 	a = yuan; 	for (; a < yuan + size;a++) 		if (*a != 0) 		{ 		printf("是原来第%d号！\n", a - yuan + 1); 		break; 		} }  大神啊,你的方法是对的,我都想了一天了这个题,但我的还是有bug

引用 18 楼 u013294728 的回复:int people[13] = {0}; int person = 0, i = 0, count3 = 0;  // 数组用来存放所有的人 一开始都为0 出来为1  person表示出来几个人， count3是一个关于3的计数器   while( person < 12) {  //13个人 出来12个人就OK  if(people[i] == 0) //为0 表示还没出来   { count3++; //计3计数器自加   if (count3 = 3)  //为3就出来 {   people[i] = 1;  //到3了 说明有人要出来了 把它变成1   person++; //出来一个人 person计数器自加 count3 = 0; //出来后清0 printf("%d", i); } }  i++;  //这一块控制循环做 if( 13 == i) {    i = 0; }  } 不对吧,count3 = 3的时候是第四个了,请问您运行过吗?

引用 14 楼 user-9 的回复:[quote=引用 13 楼 vaercly 的回复:] [quote=引用 8 楼 user-9 的回复:] 这种问题属于初学编程的练习题，不需要提问，直接google搜代码就有 自己写的话，稍微细心些都能写好 主要是想锻炼一下自己的逻辑,结果发现真的相不出来[/quote]  不用循环链表也能实现，std::list也行 甚至数组都行，就看你自己懒不懒了[/quote] 开始学的时候最好还是不要依赖STL，还是要自己研究一下算法会比较好点

引用 12 楼 vaercly 的回复:[quote=引用 9 楼 kannimad 的回复:] 为什么不用循环链表呢。。。感觉会好理解很多？？还是我哪里没考虑到 循环链表太高级,小弟学的不精啊[/quote] 没事，自己在开始学的时候在谭的书里看过也不会，现在自学数据结构，这种问题就会变得轻松多了

约瑟夫环 等会上code

引用 13 楼 vaercly 的回复:[quote=引用 8 楼 user-9 的回复:] 这种问题属于初学编程的练习题，不需要提问，直接google搜代码就有 自己写的话，稍微细心些都能写好 主要是想锻炼一下自己的逻辑,结果发现真的相不出来[/quote]  不用循环链表也能实现，std::list也行 甚至数组都行，就看你自己懒不懒了

引用 8 楼 user-9 的回复:这种问题属于初学编程的练习题，不需要提问，直接google搜代码就有 自己写的话，稍微细心些都能写好 主要是想锻炼一下自己的逻辑,结果发现真的相不出来

引用 9 楼 kannimad 的回复:为什么不用循环链表呢。。。感觉会好理解很多？？还是我哪里没考虑到 循环链表太高级,小弟学的不精啊


Question: 关于C语言堆栈溢出的问题

http://blog.csdn.net/henzox/article/details/38379277 这篇文章介绍了下简单的溢出，条件比较容易达到，可以试一试。

好像是(&a[3])>(&a[0])>&i ，a[3]和i并不是一个地址，记得面试的时候考的是a[10]当作a[12]来用，美其名曰内存4字节对齐，也不管编译器实际怎么优化的，被坑好几次

引用 9 楼 amoyman 的回复:作了一点点调整，在Debug下，得到以下结果 楼主是不是想要这样？（重点在于 a 和 i 的地址，要在正确的地方写入 6）   #include<iostream> using namespace std; int main() {     int i = 4;     int a[3] = {11,22,33};     a[5] = 6;      printf("addr a:%p, addr i:%p\n", a, &i);      printf("i=%d\n", i);  	system("pause"); 	return 0; }   addr a:0012FF4C, addr i:0012FF60 i=6 请按任意键继续. . .  楼上是在64位下做的测验吧，32位a[3]=6即可，注意压栈顺序，注意字节对齐即可，但是我用2012实验会直接 提示a的缓冲区溢出，应该是2012对缓冲区溢出操作做过处理

数组先压栈，然后压i， i的地址应该小于a

数组越界了，数组下表从0开始的哦

引用 3 楼 Henzox 的回复:不知道你在什么环境下测试的。不过要想溢出成功，需要保证以下几点： 1. 确保程序没有被优化； 2. 确保 i 分配在数组 a 的高地址； 3. 确保在 Release 下进行，且数组周围没有填充缓冲区溢出检查；  其实这几点是很难保证的，所以想成功还是按照这几点先做了再说吧。  此楼正解，特别在VS的Debug模式会增加很多调试信息，会影响本的分布，楼主还是反汇编看一下吧，总结出来后可以给大家分享一下

不知道。。。

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

&i 与 i时栈中的状态是不同的.   而你程序中a[3]这样的越界访问, 得到的当然就是不确定的东西.  我觉得楼主去研究这种错误的东西是没有意义的. 错误的东西得到未知的结果, 本身就是正常现象.

引用为什么会输出i = 4呢？如果我把第一个printf的i前面的取地址符号去掉就是正确的i=6。 可能&i的结果占用了一个临时变量，具体看看反汇编。

越界而已， 没有溢出哦。

局部变量存放位置要看编译器和它的优化结果。  你做这样的实验没有任何意义。

计算机组成原理→DOS命令→汇编语言→C语言（不包括C++）、代码书写规范→数据结构、编译原理、操作系统→计算机网络、数据库原理、正则表达式→其它语言（包括C++）、架构……  对学习编程者的忠告： 眼过千遍不如手过一遍！ 书看千行不如手敲一行！ 手敲千行不如单步一行！ 单步源代码千行不如单步对应汇编一行！  VC调试时按Alt+8、Alt+7、Alt+6和Alt+5,打开汇编窗口、堆栈窗口、内存窗口和寄存器窗口看每句C对应的汇编、单步执行并观察相应堆栈、内存和寄存器变化，这样过一遍不就啥都明白了吗。 对VC来说，所谓‘调试时’就是编译连接通过以后，按F10或F11键单步执行一步以后的时候，或者在某行按F9设了断点后按F5执行停在该断点处的时候。 （Turbo C或Borland C用Turbo Debugger调试,Linux或Unix下用GDB调试时,看每句C对应的汇编并单步执行观察相应内存和寄存器变化。）  不要企图依赖输出指针相关表达式的值【比如printf("%p\n",...)】来理解指针的本质， 而要依赖调试时的反汇编窗口中的C/C++代码【比如void *p=...】及其对应汇编指令以及内存窗口中的内存地址和内存值来理解指针的本质。

一个区地址，一个取内容

你去掉&，i还是4