Question: 【Github for Windows】客户端Login Failed

github客户端不错，可惜没有中文版，在网上找到一篇是图文教程还是不错的。 http://www.ihref.com/read-16514.html

同问呀.我去下载了.net framework的组件,windows update现在检查更新也已经全部更新了...但是还是一样的结果...

引用 7 楼 thini 的回复:问题已解决。  并不是像网上说的那样设置代理。只需要更新.net framework组件，虽然安装客户端时也会先装.net framework，但github for windows自己安装的不是最新。 要怎么更新？我的是XP，有一个.NET Framework 4，是最新的吗？我在win8的电脑上就可以登陆

这个链接里边有讨论这个问题： https://github.com/gitextensions/gitextensions/issues/2044 尝试更新最新的.net framework 框架，网址是： http://support.microsoft.com/kb/2468871 应该可以吧。。。我也在试、、、、

我也遇到了一样的问题，呜呜

抓包比较两种连接方法的不同？

引用 2 楼 zhao4zhong1 的回复:网页可能设置用了代理。 网页没有设置代理的喔。。

网页可能设置用了代理。

都没人的么。。


Question: 0xC0000005:Access Violation

大神们，能告诉我一下在运行程序的时候（即代码在编译器中编译连接）的时候查看他的底层汇编代码么，就像出问题时点击调试能显示可是不出问题时就显示不了，我用的是vc++6.0和codeblocks这两款编译器!

initsq(head);没用申请内存空间的！不能直接使用 需要自己手动分配使用的内存空间的！ 在传参之前分配或者在函数体分配都是可以的！

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

0xC0000005非法读写内存，大多由指针未初始化和数组越界造成

这个错误的基本都是指针问题

sqqueue *head=new sqqueue; //指针使用之前 要进行申请空间，


Question: 谁能帮解释一下这个程序

例子： s[3]="123AB" for(val=0.0;isdigit(s[i]);i++)//isdigit(s[i])判断s[i]是否是数字，这里将会循环三次    val=10.0 * val + (s[i]-'0');//(s[i]-'0')算出对应的数值，分别为1，2，3. 三次循环结果及100.0+20.0+3.0=123.0

自己做个十进制字符串，转整型数的程序，对照一下就可一知道了。

代码功能归根结底不是别人帮自己看或讲解或注释出来的；而是被自己静下心来花足够长的时间和精力亲自动手单步或设断点或对执行到某步获得的中间结果显示或写到日志文件中一步一步分析出来的。 提醒：再牛×的老师也无法代替学生自己领悟和上厕所！ 单步调试和设断点调试是程序员必须掌握的技能之一。

代码都不贴全…… i大概是指的s字符串的位数，0就是第一位 val就是转换后的double值，s的每一位转换后就往val上面加

首先排版规范点啊，这代码

引用 3 楼 u010334406 的回复:[quote=引用 2 楼 u010334406 的回复:] [quote=引用 1 楼 ganpengjin1 的回复:] 你还是好好找本书看下吧 你这不叫神马指点，但是我忽然间领悟道理了。[/quote] (s[i]-'0')这个值为1,val大概就等于1.0；下一次循环s[i]取3,那val就是13.0，然后s[i]再取2,那么val就是132.0[/quote] 是的，先看书，实在不懂得就提问！

引用 2 楼 u010334406 的回复:[quote=引用 1 楼 ganpengjin1 的回复:] 你还是好好找本书看下吧 你这不叫神马指点，但是我忽然间领悟道理了。[/quote] (s[i]-'0')这个值为1,val大概就等于1.0；下一次循环s[i]取3,那val就是13.0，然后s[i]再取2,那么val就是132.0

引用 1 楼 ganpengjin1 的回复:你还是好好找本书看下吧 你这不叫神马指点，但是我忽然间领悟道理了。

你还是好好找本书看下吧


Question: C语言printf函数问题

6楼正解！

在缓冲区了 会把所有的数都存着 存的是1.2345 而你输出是按float格式输出的 所以··只会去前面的一部分··

总结；跟编译器有关，但定义float型加f更明了，且没有错。

float f = 1.2345;这句报的，1.2345是double类型，1.2345F才是float类型。

没有问题，跟你的编译器有关

什么提示都没  正常运行-.-

引用 13 楼 sai_johnny 的回复:MSDN《C Floating-Point Constants》中“A floating-point constant without an f, F, l, or L suffix has type double.” 即，没有f, F, l, L后缀的浮点常量是double型。 这估计在微软的编译器中才有体现。 再结合我的情况，这么说来就是微软的问题了--这估计在微软的编译器中才有体现。。

f加一个，解决问题

你定义的数，应该在后面加一个 f，否则会被看成是 double 类型的

那要看編譯器,我用的都不會警告,可能跟設定有關 但以常量來說,整數都會被當INT類型(除非比INT大) 小數點都會被當DOUBLE類形  有需要加上后缀就好啦

float初始化就应该加f，否则会自动转化成double类型。

引用 楼主 heyuntao112356 的回复:#include <stdio.h>  int main(int argc,char *argv[]) { 	float f = 1.2345;  	printf("%f",f);  	return 0; }  编译为什么会有警告，'initializing' : truncation from 'const double ' to 'float ' printf函数入栈时已经将f转换成double类型了，为什么还有警告？  这个警告不是print的警告，而是定义f时，用1.2345初始化f的警告呀

学会看提示，可以查网上字典或自动翻译

引用 3 楼 mgy4938 的回复:1.2345默认数据类型是double，你将它定义为float，精度肯定是不够滴，高精度向低精度转换是不允许滴，会截断的。为什么是double呢？gcc下编译，运行都正常。

引用 3 楼 mgy4938 的回复:1.2345默认数据类型是double，你将它定义为float，精度肯定是不够滴，高精度向低精度转换是不允许滴，会截断的。++

就是说f是double类型的。 应该定义为double

常量也有类型。 C++ Floating-Point Constants Floating-point constants specify values that must have a fractional part. These values contain decimal points (.) and can contain exponents.  Syntax  floating-constant :  fractional-constant exponent-partopt floating-suffixopt digit-sequence exponent-part floating-suffixopt  fractional-constant :  digit-sequenceopt . digit-sequence digit-sequence .  exponent-part :  e signopt digit-sequence E signopt digit-sequence  sign : one of  + –  digit-sequence :  digit digit-sequence digit  floating-suffix :one of  f l F L  Floating-point constants have a “mantissa,” which specifies the value of the number, an “exponent,” which specifies the magnitude of the number, and an optional suffix that specifies the constant’s type. The mantissa is specified as a sequence of digits followed by a period, followed by an optional sequence of digits representing the fractional part of the number. For example:  18.46 38.  The exponent, if present, specifies the magnitude of the number as a power of 10, as shown in the following example:  18.46e0      // 18.46 18.46e1      // 184.6  If an exponent is present, the trailing decimal point is unnecessary in whole numbers such as 18E0.  Floating-point constants default to type double. By using the suffixes f or l (or F or L — the suffix is not case sensitive), the constant can be specified as float or long double, respectively.  Although long double and double have the same representation, they are not the same type. For example, you can have overloaded functions like  void func( double );  and   void func( long double );  C++ Integer Constants Integer constants are constant data elements that have no fractional parts or exponents. They always begin with a digit. You can specify integer constants in decimal, octal, or hexadecimal form. They can specify signed or unsigned types and long or short types.  Syntax  integer-constant :  decimal-constant integer-suffixopt octal-constant integer-suffixopt hexadecimal-constant integer-suffixopt 'c-char-sequence'  decimal-constant :  nonzero-digit decimal-constant digit  octal-constant :  0 octal-constant octal-digit  hexadecimal-constant :  0x hexadecimal-digit 0X hexadecimal-digit hexadecimal-constant hexadecimal-digit  nonzero-digit : one of  1 2 3 4 5 6 7 8 9  octal-digit : one of  0 1 2 3 4 5 6 7  hexadecimal-digit : one of  0 1 2 3 4 5 6 7 8 9 a b c d e f A B C D E F  integer-suffix :  unsigned-suffix long-suffixopt long-suffix unsigned-suffixopt  unsigned-suffix : one of  u U  long-suffix : one of  l L  64-bit integer-suffix :  i64  To specify integer constants using octal or hexadecimal notation, use a prefix that denotes the base. To specify an integer constant of a given integral type, use a suffix that denotes the type.  To specify a decimal constant, begin the specification with a nonzero digit. For example:  int i = 157;   // Decimal constant int j = 0198;  // Not a decimal number; erroneous octal constant int k = 0365;  // Leading zero specifies octal constant, not decimal  To specify an octal constant, begin the specification with 0, followed by a sequence of digits in the range 0 through 7. The digits 8 and 9 are errors in specifying an octal constant. For example:  int i = 0377;   // Octal constant int j = 0397;   // Error: 9 is not an octal digit  To specify a hexadecimal constant, begin the specification with 0x or 0X (the case of the “x” does not matter), followed by a sequence of digits in the range 0 through 9 and a (or A) through f (or F). Hexadecimal digits a (or A) through f (or F) represent values in the range 10 through 15. For example:  int i = 0x3fff;   // Hexadecimal constant int j = 0X3FFF;   // Equal to i  To specify an unsigned type, use either the u or U suffix. To specify a long type, use either the l or L suffix. For example:  unsigned uVal = 328u;             // Unsigned value long lVal = 0x7FFFFFL;            // Long value specified                                    //  as hex constant unsigned long ulVal = 0776745ul;  // Unsigned long value

gcc不会有警告。  引用 楼主 heyuntao112356 的回复:#include <stdio.h>  int main(int argc,char *argv[]) { 	float f = 1.2345;  	printf("%f",f);  	return 0; }  编译为什么会有警告，'initializing' : truncation from 'const double ' to 'float ' printf函数入栈时已经将f转换成double类型了，为什么还有警告？


Question: 段错误（核心已转移）

设置观察点(WatchPoint) 观察点一般用来观察某个表达式(变量也是一种表达式)的值是否变化了。如果有变化，马上停住程序。有下面的几种方法来设置观察点： watch <expr> 为表达式(变量)expr设置一个观察点。一旦表达式值有变化时，马上停住程序。 rwatch <expr> 当表达式(变量)expr被读时，停住程序。 awatch <expr> 当表达式(变量)的值被读或被写时，停住程序。 info watchpoints 列出当前设置的所有观察点。

引用 6 楼 zhao4zhong1 的回复:linux: 进程意外退出会在当前目录下产生‘core’文件或形如‘core.数字’的文件比如‘core.1234’ 使用命令 gdb 运行程序名 core或core.数字 进入gdb然后使用bt命令 可以查看进程意外退出前函数调用的堆栈，内容为从上到下列出对应从里层到外层的函数调用历史。 如果进程意外退出不产生core文件，参考“ulimit -c core文件最大块大小”命令  我试过了可是还是木有啥效果= = 是我看错了么？？？？

段错误: 非法读写内存，大多由指针未初始化和数组越界造成

少打了几个字，补充下。  在没有对 g_argv 指针元素进行内存分配的情况下，试图写向地址位置0（g_argv的所有元素均为0）的空间，自然出现段错误。

数组 g_argv 为指针数组，里面存放的是指针，g_argv[x] 需要指向一块内存空间，才能对其进行操作。 而函数 get_command() 的语句： strncpy(g_argv[g_argc], (oop+count-num), num); 在没有对 g_argv 情况下，试图写向地址位置0（g_argv的所有元素均为0）的空间，自然出现段错误。

是你的数组越界了，你仔细找找在哪里设置了它的下标

引用 4 楼 zhao4zhong1 的回复:崩溃的时候在弹出的对话框按相应按钮进入调试，按Alt+7键查看Call Stack里面从上到下列出的对应从里层到外层的函数调用历史。双击某一行可将光标定位到此次调用的源代码或汇编指令处。  判断是否越界访问，可以在数组的最后一个元素之后对应的地址处设置数据读写断点。如果该地址对应其它变量干扰判断，可将数组多声明一个元素，并设置数据读写断点在该多出元素对应的地址上。 #include <time.h> #include <stdlib.h> #include <windows.h> int main() {     int a,b[11];//本来是b[10]，为判断哪句越界，故意声明为b[11]      srand((unsigned int)time(NULL));//按两次F11，等黄色右箭头指向本行时，调试、新建断点、新建数据断点，地址：&b[10]，字节计数：4，确定。     while (1) {//按F5，会停在下面某句，此时a的值为10，b[10]已经被修改为对应0..4之一。         b[(a=rand()%11)]=0;         Sleep(100);         b[(a=rand()%11)]=1;         Sleep(100);         b[(a=rand()%11)]=2;         Sleep(100);         b[(a=rand()%11)]=3;         Sleep(100);         b[(a=rand()%11)]=4;         Sleep(100);     }     return 0; }    赵老师粗心了, 下面有一行小字, 写的是liunx, 这个环境下似乎没有: "崩溃的时候在弹出的对话框按相应按钮进入调试，按Alt+7键查看Call Stack里面从上到下列出的对应从里层到外层的函数调用历史。双击某一行可将光标定位到此次调用的源代码或汇编指令处。"


Question: 关于段错误的问题，求前辈解惑，非常感谢

可以用gdb调试错误，死了之后看死的时候的函数位置。自己找用法去……

引用 6 楼 Adol1111 的回复:这样说吧，在C++中，char *zh="";这个等价于const char *zh=""; 为什么等价，是因为要兼容老代码，但最好现在写成这样。如果你知道const什么意思的话，就应该知道，这样写zh是一个只读的指针。是不允许更改内容的。 如果你强行修改，就会造成非法的地址访问，也就是段错误。如果一定要使用指针，最好先用malloc动态分配下，或者用数组的形式。总之这样写不好，误人误己。  刚开始学的话，最好多了解下标准和好的编程习惯，不然习惯了以后想改就很麻烦了。  楼上写的代码都可以，不过你看仔细了，如果你输入的内容，超过分配的长度同样会出错。  #include <stdio.h>   int main (){     char *zh=0;     zh=(char *)malloc(sizeof(char)*20);//分配了20个空间     scanf("%s",zh);//%s是输入字符串，%c是单个字符     //scanf("%c",&zh); 这样用zh，应该是char类型，而不是char*     if(strcmp(zh,"good")==0){ //字符串要用strcmp比较，=表示赋值，不一样。                               //如果zh是刚才说的char类型，应该用zh=='g',和单个字符比较             printf("成功");     }     else{         printf("输入错误");     }     return 0; }  非常感谢，我终于懂了```因为看的不是入门书籍，所以看起来生涩难懂，所以想多写写，觉得可能会更容易理解一点，不过这里终于是懂了，非常感谢

写的有点问题，改下： #include <stdio.h> #include<string.h> //strcmp要string头文件 int main (){     char *zh=0;     zh=(char *)malloc(sizeof(char)*20);     scanf("%s",zh);     if(strcmp(zh,"good")==0){              printf("成功");     }     else{         printf("输入错误");     }     free(zh);//和malloc对应，有malloc就要有对应的free     return 0; }

引用 4 楼 u012527966 的回复:[quote=引用 2 楼 max_min_ 的回复:]  #include <stdio.h> #include <string.h>  int main(void) { 	char buf[10] = {0}; 	if (scanf("%s", buf) == 1) 	{ 		if(strcmp(buf,"good") == 0) 		{ 			printf(" You are success!\n"); 		} 		else  		    printf("You are failed!\n"); 	} 	 	return 0; } 上面的例子参考下！ 出现段错误是因为没有分配内存地址引起的！  这段代码我看明白了，但是关键是编译运行之后会出现同样的错误，段错误，核心已转储。求解，我检查了几遍真的没抄错。 还有strcmp这个函数是在string.h里面的吗？[/quote]  呃‵‵是我错了，忘记重新编译了

引用 1 楼 hnwyllmm 的回复:void main (){     char *zh="";   // 存放数组需要内存，但是这个zh只是一个指针     scanf("%c",zh);// %c是输入一个字符，不是一个字符串，用%s     if(zh = "good"){  字符串比较用strcmp函数，‘=’是赋值不是比较             printf("成功");     }     else{         printf("输入错误");     } }  楼主的C基础没有看到，建议再多看点基础，按照教程做几道基础的练习题，包括数组、字符串和指针 因为才刚刚开始接触C语言，基础确实不怎样，但是在看数组和指针的时候很多东西不能一下子理解，可不可以在我代码里错误的地方写出修改方案？因为就算知道问题在哪里可能我一下子真的修改不好，非常感谢！

引用 2 楼 max_min_ 的回复: #include <stdio.h> #include <string.h>  int main(void) { 	char buf[10] = {0}; 	if (scanf("%s", buf) == 1) 	{ 		if(strcmp(buf,"good") == 0) 		{ 			printf(" You are success!\n"); 		} 		else  		    printf("You are failed!\n"); 	} 	 	return 0; } 上面的例子参考下！ 出现段错误是因为没有分配内存地址引起的！  这段代码我看明白了，但是关键是编译运行之后会出现同样的错误，段错误，核心已转储。求解，我检查了几遍真的没抄错。 还有strcmp这个函数是在string.h里面的吗？

非法访问内存，会出现段错误！ 1. char *zh="";//zh只是一个指针，而且这里又指向一个空字符串，空字符串是个数值常量，后文不能修改，你却尝试修改了 //如果作为存储字符，必须使用数组或者动态分配 char zh[32]=""; or char *zh = malloc(32);   2.采集字符串，使用的控制符是scanf("%s", zh);c是采集单个字符


Question: 为什么while 里的输出 语句执行了2次，。，

怎么解决这个问题呢？？

有回车，   printf("请输入下一个字符:"); scanf("%c",&ch);       ---------------- 读了输入buffer里的回车

在while循环体内，scanf之前加上这句  fflush(stdin);   或者修改while循环条件

引用 2 楼 u012661911 的回复:怎么解决这个问题呢？？  printf("请输入 第一个字符:"); scanf("%c",&ch); getchar();  //因为输入的时候，有一个回车符在输入缓冲区里，可以用这个吃掉回车符，避免影响正常程序 //下面的scanf最好也加上getchar，来吃掉回车符！

引用 2 楼 u012661911 的回复:怎么解决这个问题呢？？ while (ch !='.' && ch != '\n')


Question: 菜鸟求指导

引用 1 楼 JiMoKuangXiangQu 的回复:fscanf() : 格式化解析，要求每一行都规范。 fgets() : 每次读取一行，然后提取。能详细点吗

引用 2 楼 u012701423 的回复:[quote=引用 1 楼 JiMoKuangXiangQu 的回复:] fscanf() : 格式化解析，要求每一行都规范。 fgets() : 每次读取一行，然后提取。能详细点吗 [/quote] 已经可以的了！就差源码了！如果还是不懂的话，可以看看c语言的基础书上的 基本文件操作的几个函数，自己也写例程实验实验下，多动手！


Question: 关于数组长度的疑问

上面有一点搞错了  char *arr[3] ={arr[0],arr[1],arr[2]}; //3.4）让指针数组的元素,                                               //指向二维数组的一维数组元素的首地址. 改为  char *arr[3] ={a[0],a[1],a[2]}; //3.4）让指针数组的元素,                                               //指向二维数组的一维数组元素的首地址.

这个函数没法调用，因为char (*p)[]是0长度数组的指针，不能确定数组大小。 如果这个函数编译可以通过，那就强制转换吧。 不过不能保证结果是对的。 即使，行得通，你也没有办法直接，用这个指针输出数据。    引用 楼主 aore2010 的回复: #include <iostream>  using namespace std;  int fun(char (*p)[]) { 	cout<<(*p)[1]<<endl; 	return 0; }  int main() { 	char *arr[3] = {"hello","word","wan"}; 	fun(arr);    //这里调用方式不对 在不改变int fun(char (*p)[]) 中的参数的基础之上,怎么才能调用成功呢 	return 0; }    就是说一直保持 char (*p)[] 在不指定(*p)数组长度基础之上, 我该怎么正确调用这个函数呢.  这个程序编译通过，也不能保证调用结果是对的 因为 char *arr[3] = {"hello","word","wan"}; 是指针数组，不是数组指针，也不是二维数组。 即便编译成功，所以参数传递的结果也是错误的。 如果改成 char arr[3][10]= {"hello","word","wan"}; 也许行。  这样是可以的 1）二维数组，作为一维数组的指针传递，必须是定长的一维数组指针。  #include <iostream>  using namespace std;  int fun(char (*p)[10]) { 	cout<<p[1]<<","<<p[2]<<","<<p[3]<<endl; 	return 0; }  int main() { 	char arr[3][10] = {"hello","word","wan"}; 	fun(arr);    	return 0; }  2）指针数组，作为指针数组传递，或者作为二级指针传递。 int fun(char *p[]);和int fun(char **p) 是同一函数形式的不同写法。作用一样。  作为函数参数的数组，可以看作指针，最后那个维度的大小不起作用。 可以把数组名的最后的中括号去掉，改为在数组名前面加个星号（*）。 C++引用例外。     #include <iostream> using namespace std; //int fun(char **p) 和int fun(char *p[]) 都可以。 int fun(char *p[]) //参数改成char *p[3]，char *p[4]和不写长度作用一致。所以一般不写。 { 	cout<<p[0]<<","<<p[1]<<","<<p[2]<<endl; 	return 0; }  int main() { 	char *arr[3] = {"hello","word","wan"}; 	fun(arr);    	return 0; }    3）指针数组和数组指针，以及二维数组同时使用。   #include <iostream> using namespace std;  //3.1）指针数组参数，就是二级指针参数。 //int fun(char **p) 和int fun(char *p[]) 都可以。 int fun(char *p[]) //参数改成char *p[3]，char *p[4]和不写长度作用一致。所以一般不写。 { 	cout<<p[0]<<","<<p[1]<<","<<p[2]<<endl; 	return 0; } //3.2 数组指针,必须是定长的数组的指针。 int fun_arr_ptr(char (*p)[10]) { 	cout<<p[1]<<","<<p[2]<<","<<p[3]<<endl; 	return 0; } int main() { 	char a[3][10] = {"hello","word","wan"};//3.3）二维数组         char *arr[3] ={arr[0],arr[1],arr[2]}; //3.4）让指针数组的元素,                                               //指向二维数组的一维数组元素的首地址.         char *ptr_arr[]={"hello","word","wan"};//3.5）指针数组，大概只有字符指针数组可以这么做。          	fun(arr);  //3.6）指针数组         fun(ptr_arr);  //3.7）指针数组         fun_arr_ptr(a);//3.8）数组指针    	return 0; }   3.5） 大致相当于3.3），3.4） 的联合写法。不过不论数组和字符串，都不必是确定长度的， 编译系统，可以自动检测出，数组的元素个数，和字符串的长度。 其实 char *ptr_arr[]={"hello","word","wan"};//3.5）指针数组，大概只有字符指针数组可以这么做。 相当于  char *ptr0="hello",*ptr1="word",*ptr2 ="wan";  char *ptr_arr[]=｛ptr0,ptr1,ptr2｝; 由于ptr0，ptr1,*ptr2，是不需要在程序里出现的，所以并不占用空间。 只有常量"hello"等和指针数组ptr_arr占用空间。

数组名本身就是一个指针

类型不一样  fun里面的参数为指向一维数组的指针（数组指针）  而     char *arr[3] = {"hello","word","wan"};中的arr是一个指针数组

char (*p)[]数组指针是指向数组首元素的地址的指针，其本质为指针； 指针数组是数组元素为指针的数组(例如 char *arr[3]定义了arr[0],arr[1],arr[2]三个指针)，其本质为数组。 数组指针的使用在某些情况下与指针数组很相似，要注意区别。 楼主这种情况不能这样传参吧。fun((char (*)[])arr);我试了下强制转换能传，但是传过去的指针的值是一个不可预料的地址。达不到程序的要求。

int main() {    char * arr[3] = {"hello","word","wan"};  fun((char (*)[])arr);     return 0; }

//是不是写错了？ 看看这个  int fun(char *p[]) {     cout<< p[1]<<endl;     return 0; }

程序员自己维护数组长度就那么难吗？

引用 7 楼 buyong 的回复:char *arr[3] = {"hello","word","wan"}; 这能编译？  这样可以的。。   但是不懂楼主为什么去把指针数组转换为数组指针。。。这两个混合用。。。有点。

似乎应该编译错误，才对！！！！

你要传递长度为0的数组指针，很难保证结果是对的。

就是一个数组指针和指针数组的关系，需要了解这两个名字定义的不同。char *arr[3] = {"hello","word","wan"}; 这个是指针数组， 形参是数组指针。

lz没搞清数组指针和指针数组的区别 char (*p)[3]是数组指针，是一个指向char[3]的指针，char *arr[3]是指针数组，数组里面有3个char*

引用 7 楼 buyong 的回复:char *arr[3] = {"hello","word","wan"}; 这能编译？难道你也弄混淆了？

感谢大家关注, 我一般是定义大小的, 只是今天有人问我 我竟然不知道这样该怎么调用 丢人了, 所以请教大家这个函数该怎么调用

引用 6 楼 shangyu0801 的回复:int fun(char *p[]) { 	cout<<p[1]<<p[0]<<p[2]<<endl; 	return 0; } 函数写成这样形式，可以呀。 ++ 这种就可以。  而下面这种 int fun(char (*p)[]) { 	cout<<p[1]<<p[0]<<p[2]<<endl; 	return 0; } 只怕不可以。

引用 7 楼 buyong 的回复:char *arr[3] = {"hello","word","wan"}; 这能编译？ 这个真行！


Question: 求解

引用 4 楼 li744831579 的回复:[quote=引用 楼主 li744831579 的回复:]  求解释，求说明 左上p = (char*)malloc(100) 这个在程序中，用过后，是不是也应该释放下。[/quote]  对的！只要是自己malloc或者new的空间都需要自己来释放的！

引用 5 楼 zhao4zhong1 的回复:计算机组成原理→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对应的汇编并单步执行观察相应内存和寄存器变化。）  想要从本质上理解C指针，必须学习汇编以及C和汇编的对应关系。 从汇编的角度理解和学习C语言的指针，原本看似复杂的东西就会变得非常简单！ 指针即地址。“地址又是啥？”“只能从汇编语言和计算机组成原理的角度去解释了。” 但我又不得不承认：  有那么些人喜欢或者适合用“先具体再抽象”的方法学习和理解复杂事物；  而另一些人喜欢或者适合用“先抽象再具体”的方法学习和理解复杂事物。 而我本人属前者。  这辈子不看内存地址和内存值；只画链表、指针示意图，画堆栈示意图，画各种示意图，甚至自己没画过而只看过书上的图……能从本质上理解指针、理解函数参数传递吗？本人深表怀疑！ 这辈子不种麦不收麦不将麦粒拿去磨面；只吃馒头、吃面条、吃面包、……甚至从没看过别人怎么蒸馒头，压面条，烤面包，……能从本质上理解面粉、理解面食吗？本人深表怀疑！！  提醒： “学习用汇编语言写程序” 和 “VC调试(TC或BC用TD调试)时按Alt+8、Alt+7、Alt+6和Alt+5,打开汇编窗口、堆栈窗口、内存窗口和寄存器窗口看每句C对应的汇编、单步执行并观察相应堆栈、内存和寄存器变化，这样过一遍不就啥都明白了吗。 （Linux或Unix下可以在用GDB调试时,看每句C对应的汇编并单步执行观察相应内存和寄存器变化。） 想要从本质上理解C指针，必须学习C和汇编的对应关系。” 不是一回事！  不要迷信书、考题、老师、回帖； 要迷信CPU、编译器、调试器、运行结果。 并请结合“盲人摸太阳”和“驾船出海时一定只带一个指南针。”加以理解。 任何理论、权威、传说、真理、标准、解释、想象、知识……都比不上摆在眼前的事实！  有人说一套做一套，你相信他说的还是相信他做的？ 其实严格来说这个世界上古往今来所有人都是说一套做一套，不是吗？  不要写连自己也预测不了结果的代码！  电脑内存或文件内容只是一个一维二进制字节数组及其对应的二进制地址； 人脑才将电脑内存或文件内容中的这个一维二进制字节数组及其对应的二进制地址的某些部分看成是整数、有符号数/无符号数、浮点数、复数、英文字母、阿拉伯数字、中文/韩文/法文……字符/字符串、汇编指令、函数、函数参数、堆、栈、数组、指针、数组指针、指针数组、数组的数组、指针的指针、二维数组、字符点阵、字符笔画的坐标、黑白二值图片、灰度图片、彩色图片、录音、视频、指纹信息、身份证信息……  十字链表交换任意两个节点C源代码（C指针应用终极挑战）http://download.csdn.net/detail/zhao4zhong1/5532495虽然说你这个帖子我见过N多次了吧，但是说的还不错，哈哈

引用 楼主 li744831579 的回复: 求解释，求说明 左上p = (char*)malloc(100) 这个在程序中，用过后，是不是也应该释放下。

有点腻害的呀，一个学生社团竟然都要考这样的笔试了。。。

引用 1 楼 max_min_ 的回复:左上：str没有分配内存，在test函数中还地址还是空，调用的接口出现内存泄露，        test函数拷贝函数str内存还是为空，没有内存空间  程序崩溃 右上: 返回局部指针，结果未知！结果可能得到 hello world 但是可能出错，！是一个错误的做法！ 左下：拷贝字符串成功，可以输出 hello world 但是有内存泄露， 右下：释放空间应该在str试用后不再试用之时同时把str置空，       上题这样释放可能还能访问地址能输出 hello world 但是是个错误的！  ps：很基础，多看看基础书籍！


Question: 关于链表的问题 （急！！在线等）

printf("请输入学号:");         scanf("%d",&p1->num); //这里输入学号以后会有一个回车符，在输入缓冲区中的，         printf("请输入姓名:");         fgets(p1->name,100,stdin); //执行到这里的时候就会取出上次一次输入的回车符了，所以直接跳过         printf("请输入性别:"); //所以每次输入之后，下一次输入之前应该吃掉上一次输入的时候带入的回车符 //当然也可以刷新缓冲区的 getchar();// 吃掉回车符 fflush(stdin);//刷新缓冲区， 任选一个！

在每个最后不带\n的printf后面加fflush(stdout); 在每个不想受接收缓冲区旧内容影响的scanf前面加rewind(stdin); 另外请检查scanf的返回值。

scanf("%[^\n]",p1->name);除了 换行符号 都可以 存入 字符串 中

引用 1 楼 max_min_ 的回复: fflush(stdin);//刷新缓冲区， 任选一个！   fflush 针对 输出流或更新流  用在输入流上面是未定义行为


Question: 关于有符号数与无符号数互转的问题

电脑内存或文件内容只是一个一维二进制字节数组及其对应的二进制地址； 人脑才将电脑内存或文件内容中的这个一维二进制字节数组及其对应的二进制地址的某些部分看成是整数、有符号数/无符号数、浮点数、复数、英文字母、阿拉伯数字、中文/韩文/法文……字符/字符串、汇编指令、函数、函数参数、堆、栈、数组、指针、数组指针、指针数组、数组的数组、指针的指针、二维数组、字符点阵、字符笔画的坐标、黑白二值图片、灰度图片、彩色图片、录音、视频、指纹信息、身份证信息……

自认为应该是将-25转为二进制补码，然后将此补码按照无符号数转回来即可 似乎也行，不过是做无用功， 因为， 有符号数就是补码数，正有符号数和0就是原码表示，负数就是补码表示。  有符号数和无符号数，之间的强制转换； 就是不做转换，原数不动，一个Bit也没有改变。 改变的只是数据类型。

unsigned int s = ( unsigned int )( -25 ); 好色部分不会有任何可执行代码，只是编译的时候将其解释为无符号，然后拷贝给s

有符号与无符号的相互转化是直接复制位的

无符号数, 有符号数 的二进制编码相同


Question: 用C模拟了一个http请求，但是recv函数接收的数据不完整且不安顺序获取信息

引用 55 楼 towaywu 的回复:各位这个已经弄明白了，主要还是中文乱码的原因，访问英文网站没问题，那个不明的字符串就不会出现了 对电脑而言没有乱码，只有二进制字节；对人脑才有乱码。啊 GBK:0xB0 0xA1,Unicode-16 LE:0x4A 0x55,Unicode-16 BE:0x55 0x4A,UTF-8:0xE5 0x95 0x8A

引用 46 楼 pathletboy 的回复:[quote=引用 44 楼 towaywu 的回复:] 你们说的都做了，还是出现 你#18的代码获取的html已经是正常的，出现的那个你认为是莫名的数字，#10帖子里的连接已经解释了，那个数字没有是不正常的，有才是正常的，他服务器端用chunked编码发，你只能按chunked编码解析，你控制不了人家服务器端，就好好的按照http协议进行规范通讯。[/quote]不是数字，是莫名其妙的字符串

引用 44 楼 towaywu 的回复:你们说的都做了，还是出现 你#18的代码获取的html已经是正常的，出现的那个你认为是莫名的数字，#10帖子里的连接已经解释了，那个数字没有是不正常的，有才是正常的，他服务器端用chunked编码发，你只能按chunked编码解析，你控制不了人家服务器端，就好好的按照http协议进行规范通讯。

引用 44 楼 towaywu 的回复:你们说的都做了，还是出现 出现什么，没明白你意思，我看你现在收到的完全正常的包。

你们说的都做了，还是出现

引用 42 楼 zilaishuichina 的回复:[quote=引用 39 楼 pathletboy 的回复:] [quote=引用 37 楼 towaywu 的回复:] [quote=引用 35 楼 zilaishuichina 的回复:]  while( 1 ) {         memset(recvbuf, 0x00, sizeof(char)*1024);//加上这一行 你的输出就没有乱码的小尾巴了          bytesRecv = recv(m_socket, recvbuf,1024 , 0);         printf("%s",recvbuf);               // printf("\n%d\n",bytesRecv);         if(bytesRecv<=0){             break;         }                   } 依然存在[/quote] 这代码2个问题都会导致输出乱码1、虽然1024字节是给清0了，如果收到1024长度的内容\0终止符还是没有了，只需要依据长度，长度+1的地方补个0就可以，不用清零1024字节，这样运行效率还高些。2、你收到的recv返回<=0你还是把内容输出了，那么把<=0的判断移动到输出前就可以。  按我这么改完就是我#1的代码。[/quote]  哦 写错了一个地方 memset(recvbuf, 0x00, sizeof(char)*1024);//加上这一行 你的输出就没有乱码的小尾巴了 bytesRecv = recv(m_socket, recvbuf,1023 , 0);  因为你是用tcp模拟的http  跟 你用tcp发送一段普通文本信息 没有任何区别  recvbuf是需要清0的  因为recv函数不会帮你清0  你的这些乱码的小尾巴 是因为： 比如你 第一次收到了 “GET / HTTP/1.1\r\n”  放在了recvbuf里面 第二次收到了 “Host: www.” 如果你没有清0 那么你第二次printf出来的就会变成  Host: www./1.1\r\n  当然你觉得memset效率低 可以简单一点处理  char sendbuf[1024]; bytesRecv = recv(m_socket, recvbuf,1023 , 0); if (bytesRecv <= 0)      break; recvbuf[bytesRecv] = '\0'; printf("%s",recvbuf); [/quote] 还是错，收1023时候，1023字节被你0覆盖了，参照我#1吧。

引用 39 楼 pathletboy 的回复:[quote=引用 37 楼 towaywu 的回复:] [quote=引用 35 楼 zilaishuichina 的回复:]  while( 1 ) {         memset(recvbuf, 0x00, sizeof(char)*1024);//加上这一行 你的输出就没有乱码的小尾巴了          bytesRecv = recv(m_socket, recvbuf,1024 , 0);         printf("%s",recvbuf);               // printf("\n%d\n",bytesRecv);         if(bytesRecv<=0){             break;         }                   } 依然存在[/quote] 这代码2个问题都会导致输出乱码1、虽然1024字节是给清0了，如果收到1024长度的内容\0终止符还是没有了，只需要依据长度，长度+1的地方补个0就可以，不用清零1024字节，这样运行效率还高些。2、你收到的recv返回<=0你还是把内容输出了，那么把<=0的判断移动到输出前就可以。  按我这么改完就是我#1的代码。[/quote]  哦 写错了一个地方 memset(recvbuf, 0x00, sizeof(char)*1024);//加上这一行 你的输出就没有乱码的小尾巴了 bytesRecv = recv(m_socket, recvbuf,1023 , 0);  因为你是用tcp模拟的http  跟 你用tcp发送一段普通文本信息 没有任何区别  recvbuf是需要清0的  因为recv函数不会帮你清0  你的这些乱码的小尾巴 是因为： 比如你 第一次收到了 “GET / HTTP/1.1\r\n”  放在了recvbuf里面 第二次收到了 “Host: www.” 如果你没有清0 那么你第二次printf出来的就会变成  Host: www./1.1\r\n  当然你觉得memset效率低 可以简单一点处理  char sendbuf[1024]; bytesRecv = recv(m_socket, recvbuf,1023 , 0); if (bytesRecv <= 0)      break; recvbuf[bytesRecv] = '\0'; printf("%s",recvbuf);

while( 1 ) {     //bytesRecv = recv(m_socket, recvbuf,1024 , 0);     //printf("%s",recvbuf);     // printf("\n%d\n",bytesRecv);    // if(bytesRecv<=0){     //    break;    // }    bytesRecv = recv(m_socket, recvbuf,1024 , 0);     if (bytesRecv <= 0) break; //  recvbuf[bytesRecv+1] = 0; //  printf("%s",recvbuf);     HexDump(recvbuf,bytesRecv); }

C刚弄，还得多向前辈们学习学习

参考41楼。 recv收到的是字节数组，不是ASCIIZ串。

引用 51 楼 zilaishuichina 的回复:[quote=引用 43 楼 pathletboy 的回复:] [quote=引用 42 楼 zilaishuichina 的回复:] [quote=引用 39 楼 pathletboy 的回复:] [quote=引用 37 楼 towaywu 的回复:] [quote=引用 35 楼 zilaishuichina 的回复:]  while( 1 ) {         memset(recvbuf, 0x00, sizeof(char)*1024);//加上这一行 你的输出就没有乱码的小尾巴了          bytesRecv = recv(m_socket, recvbuf,1024 , 0);         printf("%s",recvbuf);               // printf("\n%d\n",bytesRecv);         if(bytesRecv<=0){             break;         }                   } 依然存在[/quote] 这代码2个问题都会导致输出乱码1、虽然1024字节是给清0了，如果收到1024长度的内容\0终止符还是没有了，只需要依据长度，长度+1的地方补个0就可以，不用清零1024字节，这样运行效率还高些。2、你收到的recv返回<=0你还是把内容输出了，那么把<=0的判断移动到输出前就可以。  按我这么改完就是我#1的代码。[/quote]  哦 写错了一个地方 memset(recvbuf, 0x00, sizeof(char)*1024);//加上这一行 你的输出就没有乱码的小尾巴了 bytesRecv = recv(m_socket, recvbuf,1023 , 0);  因为你是用tcp模拟的http  跟 你用tcp发送一段普通文本信息 没有任何区别  recvbuf是需要清0的  因为recv函数不会帮你清0  你的这些乱码的小尾巴 是因为： 比如你 第一次收到了 “GET / HTTP/1.1\r\n”  放在了recvbuf里面 第二次收到了 “Host: www.” 如果你没有清0 那么你第二次printf出来的就会变成  Host: www./1.1\r\n  当然你觉得memset效率低 可以简单一点处理  char sendbuf[1024]; bytesRecv = recv(m_socket, recvbuf,1023 , 0); if (bytesRecv <= 0)      break; recvbuf[bytesRecv] = '\0'; printf("%s",recvbuf); [/quote] 还是错，收1023时候，1023字节被你0覆盖了，参照我#1吧。[/quote]  你那1楼的代码 才是不对的   recvbuf[bytesRecv+1] = 0;  这个+1是不需要的 收10个字节  那就是recvbuf[10] = 0;   应该是[/quote] 你是对的，楼主在我1楼代码上把recvbuf[bytesRecv+1]=0修改为recvbuf[bytesRecv]=0吧，当时想着收到后的末尾+1的字节给终止符，忽略了数组从0开始。

引用 43 楼 pathletboy 的回复:[quote=引用 42 楼 zilaishuichina 的回复:] [quote=引用 39 楼 pathletboy 的回复:] [quote=引用 37 楼 towaywu 的回复:] [quote=引用 35 楼 zilaishuichina 的回复:]  while( 1 ) {         memset(recvbuf, 0x00, sizeof(char)*1024);//加上这一行 你的输出就没有乱码的小尾巴了          bytesRecv = recv(m_socket, recvbuf,1024 , 0);         printf("%s",recvbuf);               // printf("\n%d\n",bytesRecv);         if(bytesRecv<=0){             break;         }                   } 依然存在[/quote] 这代码2个问题都会导致输出乱码1、虽然1024字节是给清0了，如果收到1024长度的内容\0终止符还是没有了，只需要依据长度，长度+1的地方补个0就可以，不用清零1024字节，这样运行效率还高些。2、你收到的recv返回<=0你还是把内容输出了，那么把<=0的判断移动到输出前就可以。  按我这么改完就是我#1的代码。[/quote]  哦 写错了一个地方 memset(recvbuf, 0x00, sizeof(char)*1024);//加上这一行 你的输出就没有乱码的小尾巴了 bytesRecv = recv(m_socket, recvbuf,1023 , 0);  因为你是用tcp模拟的http  跟 你用tcp发送一段普通文本信息 没有任何区别  recvbuf是需要清0的  因为recv函数不会帮你清0  你的这些乱码的小尾巴 是因为： 比如你 第一次收到了 “GET / HTTP/1.1\r\n”  放在了recvbuf里面 第二次收到了 “Host: www.” 如果你没有清0 那么你第二次printf出来的就会变成  Host: www./1.1\r\n  当然你觉得memset效率低 可以简单一点处理  char sendbuf[1024]; bytesRecv = recv(m_socket, recvbuf,1023 , 0); if (bytesRecv <= 0)      break; recvbuf[bytesRecv] = '\0'; printf("%s",recvbuf); [/quote] 还是错，收1023时候，1023字节被你0覆盖了，参照我#1吧。[/quote]  你那1楼的代码 才是不对的   recvbuf[bytesRecv+1] = 0;  这个+1是不需要的 收10个字节  那就是recvbuf[10] = 0;   应该是

引用 49 楼 pathletboy 的回复:[quote=引用 47 楼 towaywu 的回复:] [quote=引用 46 楼 pathletboy 的回复:] [quote=引用 44 楼 towaywu 的回复:] 你们说的都做了，还是出现 你#18的代码获取的html已经是正常的，出现的那个你认为是莫名的数字，#10帖子里的连接已经解释了，那个数字没有是不正常的，有才是正常的，他服务器端用chunked编码发，你只能按chunked编码解析，你控制不了人家服务器端，就好好的按照http协议进行规范通讯。[/quote]不是数字，是莫名其妙的字符串 [/quote] 图我再发一次，你再仔细看下。 [/quote] 好的，谢谢！我在研究研究

引用 47 楼 towaywu 的回复:[quote=引用 46 楼 pathletboy 的回复:] [quote=引用 44 楼 towaywu 的回复:] 你们说的都做了，还是出现 你#18的代码获取的html已经是正常的，出现的那个你认为是莫名的数字，#10帖子里的连接已经解释了，那个数字没有是不正常的，有才是正常的，他服务器端用chunked编码发，你只能按chunked编码解析，你控制不了人家服务器端，就好好的按照http协议进行规范通讯。[/quote]不是数字，是莫名其妙的字符串 [/quote] 图我再发一次，你再仔细看下。

引用 47 楼 towaywu 的回复:[quote=引用 46 楼 pathletboy 的回复:] [quote=引用 44 楼 towaywu 的回复:] 你们说的都做了，还是出现 你#18的代码获取的html已经是正常的，出现的那个你认为是莫名的数字，#10帖子里的连接已经解释了，那个数字没有是不正常的，有才是正常的，他服务器端用chunked编码发，你只能按chunked编码解析，你控制不了人家服务器端，就好好的按照http协议进行规范通讯。[/quote]不是数字，是莫名其妙的字符串 [/quote]  26a 是16进制

代码有bug, 抓包看看！看看发送的数据是否正确！ 接受buf初始化下，另外检查接受数据的返回值！实际接收的数据的长度是多少！

引用 38 楼 Simba888888 的回复:楼主看看我以前写的这篇文章 http://blog.csdn.net/jnu_simba/article/details/12352379 我觉得问题出在判断退出条件上吧，返回小于0的情况除非是-1表示出错了，可你既没有设置超时也没有被信号打断，所以不会返回-1吧？返回0表示对等方关闭连接了，但很难说对等方发完数据就会立马关闭连接，所以可能出现后面完整html之后还出现乱串。

引用 37 楼 towaywu 的回复:[quote=引用 35 楼 zilaishuichina 的回复:]  while( 1 ) {         memset(recvbuf, 0x00, sizeof(char)*1024);//加上这一行 你的输出就没有乱码的小尾巴了          bytesRecv = recv(m_socket, recvbuf,1024 , 0);         printf("%s",recvbuf);               // printf("\n%d\n",bytesRecv);         if(bytesRecv<=0){             break;         }                   } 依然存在[/quote] 这代码2个问题都会导致输出乱码1、虽然1024字节是给清0了，如果收到1024长度的内容\0终止符还是没有了，只需要依据长度，长度+1的地方补个0就可以，不用清零1024字节，这样运行效率还高些。2、你收到的recv返回<=0你还是把内容输出了，那么把<=0的判断移动到输出前就可以。  按我这么改完就是我#1的代码。


Question: ERROR C2143 求大神解释

linklist不是类型，你需要定义，typedef struct linklist mylinklist;好低级的错误

引用 4 楼 jerry_dqh 的回复:[quote=引用 3 楼 u012692671 的回复:] [quote=引用 1 楼 focuslight 的回复:] 可能需要加空格 加在哪里  指针前么 [/quote] 你这个代码编译错误太多了。 CreateListF()这个函数有返回指针 ，为啥用void 做为返回类型。[/quote] #include <stdlib.h>  #include <stdio.h>   struct node {  int num;  struct node *next;  }    main( )   {   struct node *creat();  void print();   struct node *head; head=NULL; head=creat(head);/*创建单链表*/  print(head);/*打印单链表*/  }    /******************************************/   struct node*creat( structnode*head)  {    struct node*p1,*p2;    p1=p2=(structnode*)malloc(sizeof(structnode));  scanf("%d",&p1->num);/*输入节点的值*/   p1->next=NULL;/*将新节点的指针置为空*/   while(p1->num>0)/*输入节点的数值大于0*/  {  if(head==NULL)head=p1;/*空表，接入表头*/   elsep2->next=p1;/*非空表，接到表尾*/  p2=p1;   p1=(structnode*)malloc(sizeof(structnode)); scanf("%d",&p1->num);/*输入节点的值*/  }   return head; }    /*******************************************/    void print(struct node*head) {   struct node *temp;   temp=head;/*取得链表的头指针*/   while(temp!=NULL)   {  printf("%6d",temp->num);/*输出链表节点的值*/  temp=temp->next;/*跟踪链表增长*/  }  }     这个是在网上找的代码  error C2143: syntax error : missing ')' before '*' 还是不明白 这里为什么出错

引用 4 楼 jerry_dqh 的回复:[quote=引用 3 楼 u012692671 的回复:] [quote=引用 1 楼 focuslight 的回复:] 可能需要加空格 加在哪里  指针前么 [/quote] 你这个代码编译错误太多了。 CreateListF()这个函数有返回指针 ，为啥用void 做为返回类型。[/quote] 哦 有返回值的函数不用制定类型吗？

引用 3 楼 u012692671 的回复:[quote=引用 1 楼 focuslight 的回复:] 可能需要加空格 加在哪里  指针前么 [/quote] 你这个代码编译错误太多了。 CreateListF()这个函数有返回指针 ，为啥用void 做为返回类型。

引用 1 楼 focuslight 的回复:可能需要加空格 加在哪里  指针前么

加在哪里 指针前么

可能需要加空格


Question: 如何在DEV-Cpp(4.9.9.2) 添加库函数，如

项目属性中添加包含目录、库目录

不建议用dos下的软件,如果一定要用.现在的xp对以前的软件支持不太好. 练习画图,下载个vc6即可.。

引用 楼主 linyeokka 的回复:本人C语言新手一枚，想用C语言作图，发现需要添加库函数graphics.h 在网上找到了一些解答： 1.将下载好的graphics.header file添加到include文件夹中 2.将下载好的libbig.A文件 添加到lib文件夹中  之后在网上下载了如下程序： #include <graphics.h> int main(void) {     int gdriver,gmode;     gdriver=DETECT;     initgraph(&gdriver,&gmode,"C:\\Dev-Cpp");     line(100,100,200,200);     getch();     closegraph();     return 0; }   出现了这样的错误：   [Linker error] undefined reference to `initgraph'......  在网上并没有找到相应的解答，请高人详细指点一下 楼主，我给你一个100分的答复，你把分给我。你去下载一个软件叫《C与C++程序设计学习与实验系统2015.5》 这个软件有Turbo C,C++ 3.0 VC,和GCC，四个编译器合成的，非常好用，你说的那些画图什么的，都完全含在里面，你不用再为这些琐事耽误学习时间。直接就上手；  你用的那个DEV 之类的软件，也是一样做C语言学习，彼此无二异，你关注的是编程，而不是编译器，何况那上面带了4个编译器，足够你使用！～～～

将你下载好的库函数复制粘贴到你安装dev的路径中的MinGW32文件夹下的include文件夹中，你会发现该路径中有很多.h的头文件，比如如下是我的安装路径中应该添加的位置：D:\Program Files (x86)\Dev-Cpp\MinGW32\include

感谢版主回复： graphics.h 放在include文件夹中了 绝对路径是：C:\Dev-Cpp\include  “修改makefile对应的引导头文件目录”没明白 makefile是什么，，，

首先这个应该是TC图像库的吧？ 你的graphics.h是放在什么目录下，绝地路径是啥？如果不是放在标准库的头文件里的话， 改成#include "graphics.h " 并修改makefile对应的引导头文件目录！


Question: 用C写的数据结构实在看不懂，求高手指点一二

为什么要有数据结构这个东东？ 因为要将现实世界或者抽象理论中的各种数据保存在计算机外存（光盘、硬盘、U盘……）或内存（ROM、RAM、SRAM……）里面的二进制字节数组中。 然后让CPU这个只会执行预先保存好的加减乘除移位条件转移……等机器指令的家伙按照人的意志去处理这些数据。至于具体如何处理就是所谓算法。

计算机组成原理→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对应的汇编并单步执行观察相应内存和寄存器变化。）  想要从本质上理解C指针，必须学习汇编以及C和汇编的对应关系。 从汇编的角度理解和学习C语言的指针，原本看似复杂的东西就会变得非常简单！ 指针即地址。“地址又是啥？”“只能从汇编语言和计算机组成原理的角度去解释了。” 但我又不得不承认：  有那么些人喜欢或者适合用“先具体再抽象”的方法学习和理解复杂事物；  而另一些人喜欢或者适合用“先抽象再具体”的方法学习和理解复杂事物。 而我本人属前者。  这辈子不看内存地址和内存值；只画链表、指针示意图，画堆栈示意图，画各种示意图，甚至自己没画过而只看过书上的图……能从本质上理解指针、理解函数参数传递吗？本人深表怀疑！ 这辈子不种麦不收麦不将麦粒拿去磨面；只吃馒头、吃面条、吃面包、……甚至从没看过别人怎么蒸馒头，压面条，烤面包，……能从本质上理解面粉、理解面食吗？本人深表怀疑！！  提醒： “学习用汇编语言写程序” 和 “VC调试(TC或BC用TD调试)时按Alt+8、Alt+7、Alt+6和Alt+5,打开汇编窗口、堆栈窗口、内存窗口和寄存器窗口看每句C对应的汇编、单步执行并观察相应堆栈、内存和寄存器变化，这样过一遍不就啥都明白了吗。 （Linux或Unix下可以在用GDB调试时,看每句C对应的汇编并单步执行观察相应内存和寄存器变化。） 想要从本质上理解C指针，必须学习C和汇编的对应关系。” 不是一回事！  不要迷信书、考题、老师、回帖； 要迷信CPU、编译器、调试器、运行结果。 并请结合“盲人摸太阳”和“驾船出海时一定只带一个指南针。”加以理解。 任何理论、权威、传说、真理、标准、解释、想象、知识……都比不上摆在眼前的事实！  有人说一套做一套，你相信他说的还是相信他做的？ 其实严格来说这个世界上古往今来所有人都是说一套做一套，不是吗？  不要写连自己也预测不了结果的代码！  电脑内存或文件内容只是一个一维二进制字节数组及其对应的二进制地址； 人脑才将电脑内存或文件内容中的这个一维二进制字节数组及其对应的二进制地址的某些部分看成是整数、有符号数/无符号数、浮点数、复数、英文字母、阿拉伯数字、中文/韩文/法文……字符/字符串、汇编指令、函数、函数参数、堆、栈、数组、指针、数组指针、指针数组、数组的数组、指针的指针、二维数组、字符点阵、字符笔画的坐标、黑白二值图片、灰度图片、彩色图片、录音、视频、指纹信息、身份证信息……  十字链表交换任意两个节点C源代码（C指针应用终极挑战）http://download.csdn.net/detail/zhao4zhong1/5532495

一般这种属于自定义操作，没什么规定，如果你想看优秀的代码，可以看看stl container部分的add操作时如何实现

引用 3 楼 AnYidan 的回复:[quote=引用 楼主 u012686437 的回复:] 举一个最简单的例子，顺序线性表的插入元素。开头 void InserElem(ElemType Sqlist[],int &n,int i ElemType item)这一行表示向顺序表中第I个位置插入元素item,该顺序表长度为n,我不知道为什么这样写，学c的时候从来没见过这种格式的。还有比如 删除的时候 void dELelem (Sqlist *L,int i)什么时候L前面是指针，什么时候是地址，什么时候什么时候什么也不加。。我都混乱了，都没有个说明规定啊。 学c的时候从来没见过这种格式的 那就说明不是c 的程序，不符合 c 的语法[/quote] 这是c++的语法，是c语言所没有的。不过在c数据结构的伪算法是经常能发现的，因为这种表示比较形象，说明要影响输入的参数的值。仅此而已，不是c语法

引用 楼主 u012686437 的回复:举一个最简单的例子，顺序线性表的插入元素。开头 void InserElem(ElemType Sqlist[],int &n,int i ElemType item)这一行表示向顺序表中第I个位置插入元素item,该顺序表长度为n,我不知道为什么这样写，学c的时候从来没见过这种格式的。还有比如 删除的时候 void dELelem (Sqlist *L,int i)什么时候L前面是指针，什么时候是地址，什么时候什么时候什么也不加。。我都混乱了，都没有个说明规定啊。 学c的时候从来没见过这种格式的 那就说明不是c 的程序，不符合 c 的语法

引用 1 楼 czarten 的回复:int &n这不是C的写法，这是C++的引用 你可以简单地理解为，int n作参数，在函数内部对n的修改不会影响传入的那个n，而int &n则会  也就是说，int &n这里的&符号跟C里面的取地址符号是两码事，不相关 至于void dELelem (Sqlist *L,int i)这句 如果是Sqlist L，那么作为参数传入的是一个Sqlist，你在函数里面对这个Sqlist的任何改变都不影响到外面，这显然是不符合函数的要求的 而Sqlist *L，传入的是Sqlist的指针，这样才能实现在函数内部更改外面的东西


Question: 递归转goto

引用 3 楼 user-8 的回复:goto非必要还是不要使用的好，这个很多书上应该都有提到。 几乎每本基础的书上都有

引用 8 楼 u011717322 的回复:[quote=引用 1 楼 worldy 的回复:] 使用沟通和递归一点都没有关系 任何的while for都可以转为if goto的结构  for(i=a1;i<a2;i++)  ==> i=a1; loop: if(i<a2) { .... i++; goto loop }  红色部分对应于for的三个要素  while(i<a) { .... }  loop: if(i<a) { .....//和实际使用while一样，要有让i增大的语句，否则就是死循环 goto loop } 我也认为是这样的。 goto也是一种循环，只不过有很多的弊端。 很少用而已。[/quote]  goto也不是有什么弊端，汇编后就是一个jump语句。之所以很多书教人尽量少用goto，只是因为goto会破坏代码的模块化！但在一些场合，使用沟通会使得代码更加简洁，比如，一个函数中的现场清理，如果在每个子块中都加清理现场的代码，也是很郁闷的，还不如goto到一个地方统一处理

引用 1 楼 worldy 的回复:使用沟通和递归一点都没有关系 任何的while for都可以转为if goto的结构  for(i=a1;i<a2;i++)  ==> i=a1; loop: if(i<a2) { .... i++; goto loop }  红色部分对应于for的三个要素  while(i<a) { .... }  loop: if(i<a) { .....//和实际使用while一样，要有让i增大的语句，否则就是死循环 goto loop } 我也认为是这样的。 goto也是一种循环，只不过有很多的弊端。 很少用而已。

goto有goto的好处，但是滥用就不对了。使用的时候只要符合几个基本原则，比如不跨函数跳跃等等，基本还是可以的  至于goto提高程序效率，Kunth是经过严格论证的，他认为使用goto在某些场合，可以是算法效率提高到一种极致。但他并不否认Dijkstra的goto有害论，goto的确会破坏结构化程序的结构，滥用会带来不可预测的结果。  现在像Java等语言中虽然保留了关键字，但却不允许使用。总之尽可能的避免吧，除非你觉得能提高效率，不然不要用太多，虽然听说linux中用了特别多的goto...

第一个例子是尾递归，容易变为循环 第二个不是尾递归，所以不能仿照上面变成循环

引用 2 楼 mujiok2003 的回复:仅供参考 #include <stdio.h> //iterative version  int power(int a, int n) {     int res = 1;     while (n--) res *= a;     return res; } //tail recursive version int power2_au(int a, int n, int res) {   if(n)    {     return power2_au(a, n-1, res * a);   }   return res;    }   int power2(int a, int n) {   return power2_au(a, n, 1); }  int main() {   printf("%d\n", power(8, 3));   printf("%d\n", power2(8, 3));      return 0; } 这个是求幂的啊，我关心的是foo怎么转化为循环

看看这个。

goto非必要还是不要使用的好，这个很多书上应该都有提到。


Question: 这个算是VC编译器的BUG吗？

Trigraphs The source character set of C source programs is contained within the 7-bit ASCII character set but is a superset of the ISO 646-1983 Invariant Code Set. Trigraph sequences allow C programs to be written using only the ISO (International Standards Organization) Invariant Code Set. Trigraphs are sequences of three characters (introduced by two consecutive question marks) that the compiler replaces with their corresponding punctuation characters. You can use trigraphs in C source files with a character set that does not contain convenient graphic representations for some punctuation characters.   Table 1.1 shows the nine trigraph sequences. All occurrences in a source file of the punctuation characters in the first column are replaced with the corresponding character in the second column.   Table 1.1   Trigraph Sequences  Trigraph Punctuation Character  ??= #  ??( [  ??/ \  ??) ]  ??’ ^  ??< {  ??!  |  ??> }  ??-  ~    A trigraph is always treated as a single source character. The translation of trigraphs takes place in the firsttranslation phase, before the recognition of escape characters in string literals and character constants. Only the nine trigraphs shown in Table 1.1 are recognized. All other character sequences are left untranslated.   The character escape sequence, \?, prevents the misinterpretation of trigraph-like character sequences. (For information about escape sequences, see Escape Sequences.) For example, if you attempt to print the string What??! with this printf statement  printf( "What??!\n" );  the string printed is What| because ??! is a trigraph sequence that is replaced with the | character. Write the statement as follows to correctly print the string:  printf( "What?\?!\n" );  In this printf statement, a backslash escape character in front of the second question mark prevents the misinterpretation of ??! as a trigraph.

推荐使用WinHex软件查看硬盘或文件或内存中的原始字节内容。

没遇到过啊。。。。。奇怪啊。。

一般 if    else  注释向下面那样  //注释 if（）//注释     。。。。         else   //注释    。。。。  你这个注释方式有点奇怪

引用 7 楼 zhaokai115 的回复:莫非是trigraph??  if (cond) { } //??/ else {    // executing always ... } 有可能是这种情况。

重建所有

引用 14 楼 zhao4zhong1 的回复:偶遇到类似问题都是用 “每次用/*...*/注释掉不同部分再重新编译，直到定位到具体语法出错的位置。” 的方法解决的。 我确实这样做了，一行一行的进行，最后才发现是else的问题，不论当时程序是否为正确的，但是while下面就一个if和else，使用了if(1);发现else执行了，去掉注释后，运行就正确了，有可能是字符编码的问题。

引用 6 楼 max_min_ 的回复:这说的，贴上你的源代码就知道其中原委了的 任何一个编译器都不会出现这么明显的bug的，更不用说vc了！ 应该是字符码的问题，原码如下  //闈為€掑綊鍚庣画閬嶅巻 Status NotRecursionAft(btNode *T) { 	ElemType elem;SqStack s; 	InitStack(&s); 	elem.NodePointer = T; 	while(elem.NodePointer || !StackEmpty(&s)) 	{ 		if(elem.NodePointer) 		{ 			elem.tag = 1; 			Push(&s,elem); 			//缁х画鍚戝乏閬嶅巻瀛愭爲 			elem.NodePointer = elem.NodePointer->lchild; 		} 		//杩欓噷鏄敞閲婁唬鐮佺殑鍦版柟 		else 		{ 			//灏嗘爤椤跺厓绱犵殑tag鍊煎姞1 			(s.top - 1)->tag++; 			GetTop(&s,&elem); 			while(elem.tag == 3) 			{ 				Pop(&s,&elem); 				printf("%c ",elem.NodePointer->data); 				//灏嗘爤椤跺厓绱犺嚜澧? 				(s.top - 1)->tag++; 				if(!GetTop(&s,&elem)) 					break; 			} 			if(GetTop(&s,&elem)) 				elem.NodePointer = elem.NodePointer->rchild; 			else 				elem.NodePointer = NULL; 		} 	} }  在else前面注释了一行，程序确实出现了问题，但是我今天测试代码又像昨天那样，没有出现问题。。

如果你的注释是中文的，有的编译器会将中文的双字节分开读取，造成 /* */ 的“提前”匹配，这就是有些编程规则中要求注释必须用 标准ascii 的原因

你加的注释估计是宽字符，因为文件编码支持问题，换行符被编译器看成宽字符的一部分（比如当成半个汉字），导致else行被当做注释的一部分而忽略掉。在一些编译器中遇到过。

文件编码的问题，有一些老的编译器不支持某些编码的文件，而VC6毕竟相当古老了。

最好能帖上C++源码和调试时的汇编码

引用 2 楼 czarten 的回复:[quote=引用 1 楼 czarten 的回复:] 是不是乱码影响到了对换行的判断  如果是/**/呢？[/quote]  有可能，但是我在VC中看见的代码，确实是注释还是注释，颜色区分相当明显，虽然同样是乱码，我在Eclipse上(Java)却没有出现过这样的情况。

引用 1 楼 czarten 的回复:是不是乱码影响到了对换行的判断  如果是/**/呢？

是不是乱码影响到了对换行的判断


Question: 关于字符数组中存在字符串结束符的问题

@lunat  我就是想要这个，但是\0我想要显示出来   @buyong  这个运行之后就异常中止了。。 至于C语言的东西我不是很懂，学C++的

char chaStr = "13\\0ds";  引用 楼主 tianminghahaha 的回复:如果字符数组中存在字符串结束符，如下所示： char chaStr = {'1','3','\0','d','s'}; string lstr(chaStr); 字符串lstr得到的是13，怎么让lstr的值为13\0ds？

引用 楼主 tianminghahaha 的回复:如果字符数组中存在字符串结束符，如下所示： char chaStr = {'1','3','\0','d','s'}; string lstr(chaStr); 字符串lstr得到的是13，怎么让lstr的值为13\0ds？      string lstr;     lstr.resize(5);     for(int i=0; i<sizeof(chaStr); ++i)     {         lstr[i] = chaStr[i];     }

例如： char chaStr[] = "13\000ds\000\000"; //‘\0’是字符串的结束符的哦！ int i=0; int c=0,c0=0; while((c = chaStr[i++])!=0 || c0 != 0 ) {          if(c)  		putchar(c); 	 	if(c0==0 && c==0)break; 	c0 = c;     if(c0 == 0)  		putchar('\n');          }

多字符串，当作一个用，没有具体的方式，不过可以自己实现。

\\0 就会显式\0

帖主要求很无理。

别用c 字符串函数，自己实现想要的功能

引用 1 楼 wangdahu888 的回复:char chaStr[] = {'1','3','\\','0','d','s'};  这个跟楼主要的不一样了吧

char chaStr[] = {'1','3','\0','d','s'}; string lstr(chaStr, sizeof(chaStr));

//这里的吧！ char chaStr[] = {'1','3','\0','d','s'}; //‘\0’是字符串的结束符的哦！ int i=0; for(i=0; i< 5; i++) {     printf("%c ", chaStr[i]); } printf("\n");


Question: ACM中ACSII码排序问题。

手误。确实在这儿出的错误。。

if(str[0],str[2])  这是毛线个意思？


Question: 求各位大神帮忙

引用 3 楼 user-4 的回复:[quote=引用 2 楼 u012705655 的回复:] 谢谢喽，这么说的话，如果将sum定义成全局变量，在哪都可以调用了？那如果不是全局变量呢，该怎么做？ 如果是在.cpp文件中，那么在此源文件中都是可以调用的！ 如果是.h文件中，只要包含了此头文件也都可以使用！ 如果不是全局的话，就在看它的作用域的范围了，只有在其范围内才有效！  楼主可以找一本基础的c语言书籍看看 推荐个 http://download.csdn.net/detail/user-4/6333711[/quote] 谢了，问题已经解决了。。  void xksz(void)  {  	HWND hWnd = GetHWnd(); 	 	SetWindowText(hWnd, "线宽设置");  	InputBox(xk,10,"请选择线宽\n（1：1像素；2：2像素；3：3像素）");    //InputBox弹出一个对话框 	 	sscanf(xk, "%d", &xk);  	if(xk[0]==1)  		setlinestyle(PS_SOLID,1);  	else if(xk[0]==2)  		setlinestyle(PS_SOLID,2);  	if(xk[0]==3)  		setlinestyle(PS_SOLID,3); } 这个线宽设置的结果怎么在 setlinestyle(xk[0]);这里调用？？

int y; ...... ...... y = sum;

把sum用作参数然后return再赋给原来的sum

引用 2 楼 u012705655 的回复:谢谢喽，这么说的话，如果将sum定义成全局变量，在哪都可以调用了？那如果不是全局变量呢，该怎么做？  用参数传入地址 *ptr++;

引用 2 楼 u012705655 的回复:谢谢喽，这么说的话，如果将sum定义成全局变量，在哪都可以调用了？那如果不是全局变量呢，该怎么做？ 如果是在.cpp文件中，那么在此源文件中都是可以调用的！ 如果是.h文件中，只要包含了此头文件也都可以使用！ 如果不是全局的话，就在看它的作用域的范围了，只有在其范围内才有效！  楼主可以找一本基础的c语言书籍看看 推荐个 http://download.csdn.net/detail/user-4/6333711

可以调用的！ 从上面的代码看， sum应该是个全局的值！所以函数都是可以调用的！


Question: C语言。动态储存数据问题

malloc realloc free

临时保存使用内存，如果需要长期保存或者数字多到内存放不下，可以保存到磁盘文件。

引用 2 楼 M173475237 的回复:[quote=引用 1 楼 user-3 的回复:] 那就动态分配内存呗！  char *buf = (char*)malloc(MAX_LEN); //MAX_LEN是最终你知道的数据长度！ // 如果不够，可以继续用realloc继续分配内存空间！  关键是在哪里储存输入的数据？[/quote] buf这里就是有效的内存空间的啊！安全使用的啊！

引用 1 楼 user-3 的回复:那就动态分配内存呗！  char *buf = (char*)malloc(MAX_LEN); //MAX_LEN是最终你知道的数据长度！ // 如果不够，可以继续用realloc继续分配内存空间！  关键是在哪里储存输入的数据？


Question: 嵌入式sql sybase数据库数据中转 C实现

没有搞过，帮顶

int main() {  	char begintime[20]=""; 	int transnum=0; 	char endtime[20]=""; 	char errostr[20]=""; 	//定义变量 	EXEC SQL BEGIN DECLARE SECTION;  	/*连接数据库参数*/ 	char *SERVER_SLP=NULL; 	char *USER_SLP=NULL; 	char *PWD_SLP=NULL; 	char *DBNAME_SLP=NULL; 	 	char *SERVER_CARD=NULL; 	char *USER_CARD=NULL; 	char *PWD_CARD=NULL; 	char *DBNAME_CARD=NULL; 	/*查询清理情况表变量*/ 	int clpernum; 	 	int clcode; 	char clper[30]; 	char cltype; 	char clflag ; 	int cld_slpcard_num;  	 	char localTime[256]=""; 	/*取新删表中期数、卡号*/ 	int Acode; 	char Aperiodname[30]=""; 	char Acardno[20]=""; 	char Aflag[10]=""; 	 	int AMcode; 	char AMperiodname[30]=""; 	char AMcardno[20]=""; 	 	/*取新增表中期数、卡号*/ 	int Ccode; 	char Cperiodname[30]=""; 	char Ccardno[20]=""; 	 	int CMcode; 	char CMperiodname[30]=""; 	char CMcardno[20]="";  	/*已清理数据*/ 	int cleannum=0; 	/* 传输日志*/ 	char logtime[20]; 	char logms[500]; 	char logvalue[512]; 	char logflag[10];  	/* 记录传输情况记录表中有多少期记录要处理 */ 	int countpernum; 	EXEC SQL END DECLARE SECTION; 	 	 	//获取连接睡眠卡数据库参数 	//getInforFromConfig(CONFIG_PATH_SLP,USER_SLP,line_user_slp); 	//getInforFromConfig(CONFIG_PATH_SLP,PWD_SLP,line_pwd_slp); 	//getInforFromConfig(CONFIG_PATH_SLP,DBNAME_SLP,line_dbname_slp); 	strcpy(SERVER_SLP,"gcard31"); 	strcpy(USER_SLP,"sld"); 	strcpy(PWD_SLP,"123456"); 	strcpy(DBNAME_SLP,"sld");    	//连接睡眠卡数据库 	EXEC SQL CONNECT :USER_SLP IDENTIFIED BY :PWD_SLP USING:SERVER_SLP; 	 	EXEC SQL USE DBNAME; 	if(sqlca.sqlcode!=0) 		printf("connect slpdatabase failed!%d\n",__LINE__); 	/*	判断清理情况记录表中是否有数据要处理*/ 	//获取表中要清理记录个数 	  	/*如果没有直接退出*/ 	if(clpernum==0) 	{ 		printf("clean_record list has not anything to move!\n"); 		return ;  	}   	 	//查询睡眠卡库清理清况记录表 	EXEC SQL 		DECLARE serch_clean_record CURSOR FOR 		//按期数、操作类型、传输标志、传输数目查询 	 	SELECT  code,periodname,opetype,flag ,d_slpcard_num FROM clean_record WHERE flag='1';  	/* 打开游标*/ 	EXEC SQL OPEN serch_clean_record;  	//处理数据中传输标志为1的相应数据表 	for (;;) 	{ 		/* 记录传输情况记录表中有多少期记录要处理 */  		 		EXEC SQL FETCH serch_clean_record  INTO :clcode,:clper, 			:cltype,:clflag,:clslpcard_num; 			//记录传输开始时间 			//***************************** 			begintime=getLocalTime(); 			 			 //**************************** 		//新删表有数据要传 		if ( cltype == 1) 		{ 			cleannum=0; 			//根据期数查询新删表 			EXEC SQL 				DECLARE serch_activatelist_slp CURSOR FOR 				//根据规则编码、期数、卡号查询指定期号，标志为0未传输的数据 	 			SELECT code,periodname,cardno,FROM activatelist_slp 	 	 	 			WHERE periodname=issue,flag='0';  			/* 打开游标*/ 			EXEC SQL OPEN serch_activatelist_slp; 			 			//获取连接交易卡数据库参数 				//getInforFromConfig(CONFIG_PATH_CARD,SERVER_CARD,USER_CARD,PWD_CARD,DBNAME_CARD,line_server_card, 				//		line_user_card,line_pwd_card,line_dbname_card); 				   			strcpy(SERVER_CARD,"gcard"); 			strcpy(DBNAME_CARD,"XUNI3"); 			strcpy(USER_CARD,"oiler"); 			strcpy(PWD_CARD,"2D23C731"); 				//连接交易卡数据库 				EXEC SQL CONNECT :USER_CARD IDENTIFIED BY :PWD_CARD USING:SERVER_CARD; 				 				EXEC SQL USE DBNAME; 			/*如果连接省中心交易库失败写入省中心睡眠卡库传输日志  */ 			if(sqlca.sqlcode!=0) 			{ 				printf("connect carddatabase failed !%d\n",__LINE__); 				logtime=getLocalTime(void); 				strcpy(logms,"connect carddatabase "); 				strcpy(logvalue,"connect carddatabase failed."); 				strcpy(logflag,"-1") 				EXEC SQL  					insert into trans_log(code,periodname,opetime,opems,opevalue,flag) 					values(clcode,clper,logtime,logms,logvalue,logflag); 			} 			while(1) 			{ 				 				//获取每一行结果,插入新删中间表中 				EXEC SQL FETCH serch_activatelist_slp  INTO :Acode, 							:Aperiodname,:Acardno; 				 				 				EXEC SQL INSERT INTO ActivateListMid_slp(code,periodname,cardno)	 					VALUES (Acode,Aperiodname,Acardno); 				//插入完成后修改标志位为1(即已传输) 				EXEC SQL UPDATE activatelist_slp 　　				SET flag = '1' 　　				WHERE cardno = :Acardno;  				/*记录传输数目并打印出传输内容 */ 				transnum++; 				printf("%d %s %s",Acode,Aperiodname,Acardno); 			} 			//记录传输的数据数目(利用sql语句读取省中心交易卡库新删中间表中所有数据，即为已传输数据数目) 			//写入本期传输记录表 			//***************************** 			endtime=getLocalTime(); 			 			EXEC SQL INSERT INTO trans_record(code,periodname,begtime,endtime,trans_num,logvalue,flag) 					VALUES (); 			/*如果cleannum==transnum则没有重复，cleannum>transnum则有重复数据  */ 			//复制新增清理清单中间表到相应新增清理清单表中(没有重复数据) 			EXEC SQL INSERT INTO cleanlist_slp 				SELECT distinct code,periodname,cardno from cleanlistmid_slp; 			/* 关闭查询新删表游标*/ 			EXEC SQL CLOSE serch_activatelist_slp; 		} 		//新增表有数据要传 		if(cltype ==0) 		{ 			cleannum=0; 			//根据期数查询新增表 			EXEC SQL 				DECLARE serch_cleanlist_slp CURSOR FOR 				//期号、卡号查询指定期号，标志为0未传输的数据 	 			SELECT code,periodname,cardno FROM CleanList_slp 	 	 	 			WHERE periodname=issue,flag=0;  			/* 打开游标*/ 			EXEC SQL OPEN serch_cleanlist_slp; 			//获取连接交易卡数据库参数 				getInforFromConfig(CONFIG_PATH_CARD,SERVER_CARD,USER_CARD,PWD_CARD,DBNAME_CARD,line_server_card, 						line_user_card,line_pwd_card,line_dbname_card); 				    				//连接交易卡数据库 				EXEC SQL CONNECT :USER_CARD IDENTIFIED BY :PWD_CARD USING:SERVER_CARD; 				 				EXEC SQL USE DBNAME; 			/*如果连接省中心交易库失败写入省中心睡眠卡库传输日志  */ 			if(sqlca.sqlcode!=0) 			{ 				printf("connect carddatabase failed !%d\n",__LINE__); 				logtime=getLocalTime(); 				strcpy(logms,"connect carddatabase "); 				strcpy(logvalue,"connect carddatabase failed."); 				strcpy(logflag,"-1") 				EXEC SQL  					insert into trans_log(code,periodname,opetime,opems,opevalue,flag) 					values(clcode,clper,logtime,logms,logvalue,logflag); 			}  			while(1) 			{ 				//获取每一行结果,插入新删中间表中 				EXEC SQL FETCH serch_CleanList_slp  INTO :Ccode, 							:Cperiodname:Ccardno; 				 				 				EXEC SQL INSERT INTO CleanListMid_slp(code,periodname,cardno)	 					VALUES (:Ccode,:Cperiodname,:Ccardno); 				//插入完成后修改标志位为1(即已传输) 				EXEC SQL UPDATE CleanList_slp 　　				SET flag = '1' 　　				WHERE cardno = :Ccardno;  				/*记录传输数目并打印出传输内容 */ 				transnum++; 				printf("%d %s %s",Ccode,Cperiodname,Ccardno); 			} 			//写入本期传输记录表 			//***************************** 			endtime=getLocalTime(); 			 		 			EXEC SQL USE trans_record; 			 			EXEC SQL INSERT INTO trans_record(code,periodname,begtime,endtime,trans_num,logvalue,flag) 					VALUES (); 			 			 			//复制新删清理清单中间表到相应新删清理清单表中(没有重复数据) 				 					EXEC SQL INSERT INTO activateList_slp 						SELECT distinct code,periodname,cardno from activateListMid_sle; 			/*关闭新增查询游标*/ 			EXCE SQL CLOSE serch_cleanlist_slp; 		} 		 		 		 		/*关闭清理清单查询游标*/ 		EXCE SQL CLOSE serch_clean_record; 		//处理的期数并打印出期号 		countpernum++; 		printf("%s\n",clper); 	} 	//传输完成，清除传输标志为1的数据(即已传输数据) 	EXEC SQL DELETE FROM activateList_slp  	WHERE flag = '1';  	//修改清理情况记录表 	EXEC SQL UPDATE clean_record 　　				SET flag = '1'; 　　				WHERE periodname= :issue;  	  	  	//断开所有连接 	EXEC SQL DISCONNECT ALL; //==============================================transdata end====================================   	return 0; }

我可以把我代码放上面你帮我看看有什么问题不？

数据库1中表1的数据转到表2中：             server1               server2             dbname1               dbname2             user1                 user2             pwd1                  pwd2             表1                   表2 我想用嵌入式sql C程序实现 数据库是sybase

解析一种数据表，获取到有效数据后组合成另外一种数据表！


Question: 计算机计算除法的原理

计算机组成原理中有。。。

二进制除法竖式

仿照竖式笔算

按照二进制多项式除法来做，如图电路

数字电路上面有解答

c语言深度剖析这本书有提到一点


Question: 地址访问冲突是怎么回事

传递过来的参数出了问题吧？感觉这个函数中的数组并没有越界。

我在vs2010下运行，没有访问冲突呀 	double a1=1,a2=2,a3=3,a4=4;     calcAzEl(&a1,&a2,&a3,&a4);

传递进来的变量 sat_pos_temp, jz_data.pos, Az, El 都分配空间了吗？ 初始化的只有 Az=NULL; E1=NULL; 让这些指针都指向可用的空间。 如果这些都做了，那就是数组下表越界造成了一些非法内存访问。

calcAzEl(sat_pos_temp, jz_data.pos, Az,El);  调用这个接口之前是不是给Az和E1分配的内存空间呢？


Question: 新人求教-C语言如何调用DOS命令？

引用 1 楼 user-1 的回复:system()函数，或者其他创建进程的函数，如windows下的CreateProcess(). 已用system(),CreateProcess没用过


Question: 新人真心求教！！这次真给跪了！求帮助！

参考下别人的源码！自己再动手试试 http://blog.csdn.net/nupt123456789/article/details/8331312 http://download.csdn.net/download/liwenfeng521/2760250

那你还是把课本拿出来好好再看一下吧，花点时间，不难的。这题目的代码网上应该可以找到很多，但是你看不懂也没用，害了自己。

这个不难呀，少打会LOL，多看会书就有了


Question: sprintf函数调用的问题

引用 7 楼 zaixiankaifa 的回复:[quote=引用 3 楼 max_min_ 的回复:] 因为你每次sprintf都是用的line，所以会把前一次的覆盖掉！要加一个移动标志位  如;  unsigned int flag = 0; for(i=1;i<MAX_OBJECTS;i++) { 	// 这里你得确保line的内存空间是足够的！     sprintf(line + flag,"%d,%f,%f,%s\n",objects[i].id,objects[i].x_coord,objects[i].y_coord,objects[i].name);    flag += sizeof(MY_TYPE_T); }   刚才试了一下如你所说的修改，结果发现，只输出第一组数据，好怪异。。。。[/quote] 后面的写入不要有fputs，换一个写文件函数，然后检查函数的返回值，确认写入有效数据是多少！

引用 4 楼 lixiang201101 的回复:for(i=1;i<MAX_OBJECTS;i++) { sprintf(line,"%d,%f,%f,%s\n",objects[i].id,objects[i].x_coord,objects[i].y_coord,objects[i].name); }   fputs(line,fout); 首先你这里只有两组数据，第二组开始的，因为i=1；而不是三组数据、 然后sprintf执行后前一组数据会被后一组覆盖掉。 你这里这样改 for(i=1;i<MAX_OBJECTS;i++) { sprintf(line,"%d,%f,%f,%s\n",objects[i].id,objects[i].x_coord,objects[i].y_coord,objects[i].name);  fputs(line,fout); }   这样就可以了。   其实我是想把这些数据一次性先输入到数组里面，然后再输出到文件流

引用 3 楼 max_min_ 的回复:因为你每次sprintf都是用的line，所以会把前一次的覆盖掉！要加一个移动标志位  如;  unsigned int flag = 0; for(i=1;i<MAX_OBJECTS;i++) { 	// 这里你得确保line的内存空间是足够的！     sprintf(line + flag,"%d,%f,%f,%s\n",objects[i].id,objects[i].x_coord,objects[i].y_coord,objects[i].name);    flag += sizeof(MY_TYPE_T); }   刚才试了一下如你所说的修改，结果发现，只输出第一组数据，好怪异。。。。

引用 3 楼 max_min_ 的回复:因为你每次sprintf都是用的line，所以会把前一次的覆盖掉！要加一个移动标志位  如;  unsigned int flag = 0; for(i=1;i<MAX_OBJECTS;i++) { 	// 这里你得确保line的内存空间是足够的！     sprintf(line + flag,"%d,%f,%f,%s\n",objects[i].id,objects[i].x_coord,objects[i].y_coord,objects[i].name);    flag += sizeof(MY_TYPE_T); }   意思即是说，每次将一组数据放到line的时候，由于每次都是line这个数组元素首地址，所以每次都覆盖掉上一次的数据？

引用 4 楼 lixiang201101 的回复:for(i=1;i<MAX_OBJECTS;i++) { sprintf(line,"%d,%f,%f,%s\n",objects[i].id,objects[i].x_coord,objects[i].y_coord,objects[i].name); }   fputs(line,fout); 首先你这里只有两组数据，第二组开始的，因为i=1；而不是三组数据、 然后sprintf执行后前一组数据会被后一组覆盖掉。 你这里这样改 for(i=1;i<MAX_OBJECTS;i++) { sprintf(line,"%d,%f,%f,%s\n",objects[i].id,objects[i].x_coord,objects[i].y_coord,objects[i].name);  fputs(line,fout); }   这样就可以了。  ++

flag += sizeof(MY_TYPE_T);加上结构大小不对位吧，改下用printf的返回值计算偏移，类似：  for(i = 0, n = 0; i < MAX_OBJECTS; i++) {     n += sprintf(line + n, ... }

用fprint不是很好吗  后面的那个还要考虑字节空间

把fputs（line，fout）写到for循环去，应该就解决问题了。

后面的覆盖掉了前面的。自然只剩最后一组了。


Question: 简单问题求解

引用 1 楼 user-4 的回复:#include <stdio.h> #include <string.h>  void tx(char a[20][10], int n) { 	int i, j, k; 	char c[30], d[30];  	for (i = 0; i < n-1; i++) 	{ 		for (j = i+1; j <= n-1; j++) 		{ 			for (k = 0; k < 30; k++) 			{ 				c[k] = '\0'; 				d[k] = '\0'; 			} 			strcat(c, a[i]); 			strcat(c, a[j]); 			strcat(d, a[j]); 			strcat(d, a[i]); 			if (strcmp(c, d) < 0) { 				strcpy(c, a[i]); 				strcpy(a[i], a[j]); 				strcpy(a[j], c); 			} 		} 	} }  int main(void) { 	FILE *f1, *f2; 	int i, j, n; 	char a[20][10];  	f1 = fopen("1.txt", "r"); 	f2 = fopen("2.txt", "w");  	fscanf(f1, "%d", &n); 	for (i = 0; i < n; i++) 		fscanf(f1, "%s", &a[i]); 	tx(a, n); 	for (i = 0; i < n; i++) 		fprintf(f2, "%s", a[i]);  	fclose(f1); 	fclose(f2);  	return 0; } 将函数tx()里面的循环语句 for (k = 0; k <= 30; k++) 修改为： for (k = 0; k < 30; k++)  输入文件 1.txt 3 13 312 343  运行程序，输出结果文件 2.txt 34331213 ++

很明显，数组越界了。30的大小，下标是0-29，其中的for(k=0;k<=30;k++)，却到下标30

将函数tx()里面的循环语句


Question: 新手求指教

先下载Win-TC，然后参考C:\Win-TC\tcstudy.chm

各位大神能留个QQ号不，以后有问题在直接请教了

搞个Ubuntu吧，装虚拟机或者双系统都可以，GNU工具集太强大了。  看书的话，c和指针，c缺陷和陷阱，c专家编程，数据结构与算法分析-c语言描述

引用 楼主 u012691264 的回复:本人中专计算机应用毕业，现在想自学C语言，英语数学水平基本还给老师了，请问各位大神要买什么书跟哪个软件好点，最好能告诉下在什么地方能买到这些。在这谢谢了！还想问下没有文凭的学这个会找的到工作吗？ 一定要多写代码。一个一个敲，不要copy。

文凭只是敲门用的，可能找工作比别人困难点，只要技术学好了，找工作还是很容易的！  可以先看看 c primer plus 入门基础 再看看 c语言程序设计，c和指针这些基础书籍 ！ 书上的例程多敲敲！ 新手推荐环境用 c-free吧，比较适合新手，后期可以考虑用vs或者g++！


Question: strtok多次调用，会出现之前数据重复赋值问提

struct log_form{//定义结构体变量 		char year[5]; 		char month[3]; 		char day[3]; 		char hour[3]; 		char minute[3]; 		char second[3]; 	};	 /* define struct log_form a */

结构里定义的数组不够大越界操作NULL被覆盖掉，每个数组起码加大1容纳NULL结尾


Question: 循环打印文件出的不同方式出现疑问

数据量大于LEN，一次读不完，所以要while

不是一定要用循环的！两者都是可以的！ 至于你说的ctrl+d在windows下相当于文件结束符EOF了  至于fgets判断返回值而已了


Question: 关于C的FILE结构体

To break when the value at a specified memory address changes   From the Edit menu, click Breakpoints.   Click the Data tab of the Breakpoints dialog box.   In the Expression text box, type the memory address for the byte.  For a word or doubleword memory address, enclose the address in parentheses, and precede it with a cast operator. For example, WO(21406036) for the word at memory location 21406036. Use the cast operator BY for a byte (optional), WO for a word, or DW for a doubleword. (The debugger interprets all integer constants as decimal unless they begin with zero (0) for octal or zero and x (0x) for hexadecimal.)  In the Number Of Elements text box, type the number of bytes, words, or doublewords to monitor. If you used the BY operator in the Expression field, specify the number of bytes. If you used WO, specify the number of words. If you used DW, specify the number of doublewords.    Click OK to set the breakpoint.

char   *_ptr;                  //文件输入的下一个位置   你既然知道这个结构体的具体意思, 怎么就不仔细看呢?  明明说了是"下一个位置", 那肯定是看不到你才写入的东西的.  但是, 如果你打开一个已经写入了很多东西的文件, 这个指针应该是有文件内容的.  fopen是一个库函数, 并不是API fopen封装了API, 并且_ptr指向的是一个文件缓冲区而不是一个字符串,虽然是char*类型, 只是为了按1字节计算,定义成char*.  所以这个指针指向的内容并不一定有\0结尾, 但调试的时候,调试器中显示是把char*看作串的给你显示, 所以就会看到乱码了. 就跟你自己申请的一个char数组, 但是不给它放\0结尾, 效果是一样的.

别直接操作FILE结构体，请使用API。

屯  tún  聚集，储存：屯粮。屯积。屯聚。  驻军防守：屯兵。屯垦。屯田（驻军开垦田地）。  村庄：皇姑屯。屯子（村庄）。

引用 1 楼 user-4 的回复:屯屯屯。。一般都是未初始化的缘故，还有那个啥烫烫烫烫烫烫。。。。  struct   _iobuf   {           char   *_ptr;                  //文件输入的下一个位置           int       _cnt;                //当前缓冲区的相对位置           char   *_base;                 //指基础位置(应该是文件的其始位置)           int       _flag;               //文件标志           int       _file;              //文件的有效性验证           int       _charbuf;           //检查缓冲区状况,如果无缓冲区则不读取           int       _bufsiz;            //文件的大小           char   *_tmpfname;            //临时文件名  };  typedef   struct   _iobuf   FILE;  这写我都知道，百度一下就出来了，关键是每个变量被赋予值时所代表的含义。 还有就是什么叫做未初始化，文本文件没有初始化是什么含义？并且虽然出现了屯屯屯屯，但我的文件读写还是成功了。


Question: 请教个问题啊！

引用 5 楼 u012207185 的回复:[quote=引用 4 楼 jerry_dqh 的回复:] [quote=引用 3 楼 u012207185 的回复:] 只说了结果，怎么操作，没有说！  if(count++ % 3==0) putc(ch,out);  这个就是算法啊，每隔几个取一个字符，就是一个简单的示例，不是真正的算法[/quote] 这个程序怎么运行啊？怎么运行后把So even Eddy came oven ready压缩成Send money？[/quote]  你不是写了吗，命令行直接运行，reducto eddy

我是先把reducto.exe文件拖入命令行，再把eddy.txt再拖入命令行，再执行reducto eddy！结果错了！

引用 8 楼 user-2 的回复:执行这个命令的方法：./reducto eddy 这个程序的意思就是把eddy文件的内容压缩，然后再保存在eddy.red文件中。 在linux里面不是用后缀名来区分文件的，所以eddy就是一个字符文件而已，类似于windows里面的eddy.txt。 这些都是基础，楼主需要好好去学习下基础。 我开始是用记事本写了eddy，在命令行执行了这个命令，不成功啊！生成了一个eddy.txt.red文件，里面是空的，没有Send money！

引用 6 楼 jerry_dqh 的回复:[quote=引用 5 楼 u012207185 的回复:] [quote=引用 4 楼 jerry_dqh 的回复:] [quote=引用 3 楼 u012207185 的回复:] 只说了结果，怎么操作，没有说！  if(count++ % 3==0) putc(ch,out);  这个就是算法啊，每隔几个取一个字符，就是一个简单的示例，不是真正的算法[/quote] 这个程序怎么运行啊？怎么运行后把So even Eddy came oven ready压缩成Send money？[/quote]  你不是写了吗，命令行直接运行，reducto eddy[/quote] 我是刚接触这个命令行！一些基本的东西我还不知道怎么弄！比如说eddy怎么产生的，是个什么文件类型，应该存储在什么地方。。。 执行这个操作才有用！

引用 4 楼 jerry_dqh 的回复:[quote=引用 3 楼 u012207185 的回复:] 只说了结果，怎么操作，没有说！  if(count++ % 3==0) putc(ch,out);  这个就是算法啊，每隔几个取一个字符，就是一个简单的示例，不是真正的算法[/quote] 这个程序怎么运行啊？怎么运行后把So even Eddy came oven ready压缩成Send money？

引用 3 楼 u012207185 的回复:只说了结果，怎么操作，没有说！  if(count++ % 3==0) putc(ch,out);  这个就是算法啊，每隔几个取一个字符，就是一个简单的示例，不是真正的算法

只说了结果，怎么操作，没有说！

引用 1 楼 jerry_dqh 的回复:send money是压缩合的结果吧？ 是的！

send money是压缩合的结果吧？


Question: 求好心的大神带

先下载Win-TC，然后参考C:\Win-TC\tcstudy.chm  bc++3.1 帮助里面对每个函数都有一小段能拷贝出来运行看效果的例子程序。非常适合初学C语言。相比较而言VC带的帮助MSDN就没有。http://download.csdn.net/source/2805028  计算机组成原理→DOS命令→汇编语言→C语言（不包括C++）、代码书写规范→数据结构、编译原理、操作系统→计算机网络、数据库原理、正则表达式→其它语言（包括C++）、架构……

自己做项目？做什么项目？大神们给点具体实用性的建议呀、、

看了一遍基础，可以自己去做个开源项目。

引用 楼主 u012688976 的回复:我像学习c语言   但不知怎么学   从何学起   因此想求大神带入门   再次跪谢 这个要靠自己的，任何人带不如自己做项目，先看一下C和指针

c语言程序设计  谭浩强         第三版

引用 2 楼 u012688976 的回复:我现在就在看那本书，看到第四章了，感觉还是什么都不会呀   求大神指导指导  哪本书？读C语言程序设计 要有一定的基础

引用 2 楼 u012688976 的回复:我现在就在看那本书，看到第四章了，感觉还是什么都不会呀   求大神指导指导 没事的啦，慢慢来了，不要急于求成了，上面的代码，自己下个环境都敲敲

我现在就在看那本书，看到第四章了，感觉还是什么都不会呀   求大神指导指导

C语言程序设计，可以读读！ c primer plus 基础入门，


Question: 将两个递增链表中B链表插入A中，保持增序，但不改变B,请大师帮看下对么？

你没有结构体啊，大致看了一下，有点乱，我还是给你写了一个，供参考。  struct node  { 	int data; 	struct node *next; };  void Great_link(struct node *ha,struct node *hb) { 	struct node  *p,*q, *s; 	struct node *temp;  	p = ha->next; 	q = hb->next;  	while(q) 	{ 		if (p->data < q->data) 		{ 			p = p->next; 			continue; 		} 		 		//无论插入到哪里，不改变b那么就要新建结点 		temp = (struct node *)malloc(sizeof(struct node)); 		temp->data = q->data;  		//将temp插入到p之后 		temp->next = p->next; 		p->next = temp;  		//如果p->data = q->data不做处理，如果p->data > q->data，把数据交换一下即可 		if (p->data > q->data) 		{ 			temp->data = p->data; 			p->data = q->data; 		}  		p = temp;//p下移 		if (q) 		{ 			q = q->next; 		} 		else 			break;//链表b处理完毕 		 		if (p->next == NULL) 		{ 			s = p;//为下一个while提供服务 		} 		 	} 	 	while(q)//到a末尾，b未处理完毕 	{ 		temp = (struct node *)malloc(sizeof(struct node)); 		temp->data = q->data;  		temp->next = s->next;//实际上就是NULL 		s->next = temp; 		s = temp; 		q = q->next; 	} }


Question: 链表打印 ，循环出现 segmentation fault ,急急急

以上代码中对函数int2GE略有修改，以避免输入为0时出现异常和输入为负数时输出2个负号。

当输入为0时，因函数int2GE返回NULL，在执行affiche10时有异常。 当输入不为0时，没有发现异常。 LZ在输入什么数据时遇到segmentation fault？  以下是我在VS2010运行的lz代码： #include <stdio.h> /*下面两个是我定义的结构*/ struct element {     int n; /*le n de base B*/   int c; /*le c de GE*/   struct element *g_next; };  struct GrandEntier {   int B; /*Base de GE*/   int L; /*length de GE*/   int signe;   struct element *premier; };  typedef struct element element; typedef struct GrandEntier GE;    GE *Init_GE() {       GE *ge;   ge=(GE*)malloc(sizeof(GE));        ge->B=10;   ge->L=0;   ge->signe=1;      ge->premier=NULL;       return ge; }   GE *int2GE(int n) {   GE *ge;   element *p,*q;   /*删   if(n==0)   {     return NULL;   }*/   ge=Init_GE();   //ge->signe=(n>0)? 1:-1; 改为以下语句以免输出两个负号   if (n >0 ) ge->signe = 1;   else   {     ge->signe = -1;     n = -n;   }    while(n!=0)   {     if(ge->L==0)     {       q=(element*)malloc(sizeof(element));       q->c=n%ge->B;       q->n=ge->L;       q->g_next=NULL;       ge->premier=q;       ge->L++;       n=n/ge->B;      }     else     {       p=(element*)malloc(sizeof(element));       p->c=n%ge->B;       p->n=ge->L;       p->g_next=NULL;       q->g_next=p;       q=p;        n=n/ge->B;       ge->L++;      }    }   return ge; }  /*打印函数，逐个显示ge x的值*/ void affiche10(GE *X) {   element *a;   a=X->premier;   if(a)   {     printf("\nAffiche en base 10 le GE X sur stdout.\n");     for(;a;a=a->g_next)     {       printf("%c%d*%d^%d",(X->signe>0)? '+':'-',a->c,X->B,a->n);     }   } }  void main() {   int a,b;   GE *X,*Y,*Z;   printf("insere deux entier:");   scanf("%d%d",&a,&b);   printf("%d,%d\n",a,b);   X=int2GE(a);   Y=int2GE(b);   affiche10(X);   affiche10(Y); }

我知道原因了，删掉free(a);就可以了。 谢谢各位的帮助。

你好，我输入的是123和456。     我改了一下main()，写了两遍打印：	         affiche10(X); 	affiche10(Y);	 	affiche10(X); 	affiche10(Y);   结果是： Affiche en base 10 le GE X sur stdout:  3*10^0+2*10^1+1*10^2 Affiche en base 10 le GE X sur stdout:  6*10^0+5*10^1+4*10^2 Affiche en base 10 le GE X sur stdout:  3*10^0+2*10^1+-572662307*10^-572662307Press any key to continue

检查越界问题，或者初始化失败，内存非法访问会出现段错误提示！

segmentation fault 非法读写内存，多由指针未初始化和数组越界导致

我单独打印Y->premier->c是有值的,然后继续g_next->c也是有值。  代码如下：   GE *Init_GE() {     	GE *ge; 	ge=(GE*)malloc(sizeof(GE));      	ge->B=10; 	ge->L=0; 	ge->signe=1;    	ge->premier=NULL;     	return ge; }   GE *int2GE(int n) { 	GE *ge; 	element *p,*q; 	if(n==0) 	{ 		return NULL; 		} 	ge=Init_GE(); 	ge->signe=(n>0)? 1:-1; 	while(n!=0) 	{ 		if(ge->L==0) 		{ 			q=(element*)malloc(sizeof(element)); 			q->c=n%ge->B; 			q->n=ge->L; 			q->g_next=NULL; 			ge->premier=q; 			ge->L++; 			n=n/ge->B; 			 		} 		else 		{ 			p=(element*)malloc(sizeof(element)); 			p->c=n%ge->B; 			p->n=ge->L; 			p->g_next=NULL; 			q->g_next=p; 			q=p; 			 			n=n/ge->B; 			ge->L++; 		 		}  	} 	return ge; }

X=int2GE(a)； Y=int2GE(b);确认下函数调用是否成功！ Y分配地址是否成功！

可能 Y=int2GE(b); 没有初始化好


Question: 我建立二叉树有什么问题啊

其实，这个问题我已经解决啦，还有别的问题，不过，很开心是自己一个人给完成了，不过还是谢谢大家啦！

只是一个回车符在缓冲区里， getchar或者多一次scanf吃掉都是可以的！

恩恩，这个我知道啦，问题我已解决，谢谢啦

do     {         cout << "Please input three character to discribe children-node:\n";         scanf("%s",charray);         QElementType e;         e.myself = charray[0];         e.parent = charray[1];         e.side = charray[2];         EnQueue(Q,e);         if(e.parent == '#')         B->mydata = e.myself;         else{             cout <<"cdskcvsd";             PreTree(B,e);         }         cout << "Do you want to continue your input?\n";         scanf("%c",&ch);     }while(ch == 'Y');  嗯，曾经有过这样的问题，原因是scanf函数遇到空白符（回车、tab、空格）即停止本次读输入的操作，但是空白符仍会留在输入流中，所以你上面scanf("%s",charray);之后的操作scanf("%c",&ch);，ch会读到一个空白符，不等于'Y'，所以do{}while循环即停止了 解决方法：scanf(" %s",charray); scanf(" %c",&ch);，注意这里百分号前有一个空格！作用是跳过输入流前面的空白符，具体还请lz自己去查一下scanf的用法


Question: 一道题目

楼上的，我用的gcc里面对NULL竟然没定义，所以我自己定义了，下面那部分内容太烦了就没仔细看。 结贴的时候没发现你的帖子，对不住了

引用 楼主 u012453424 的回复:#define NULL (void *)0//我这里是不是有错误？ char *find_char(char const *source,char const *chars) { 	if(source==NULL||chars==NULL|| 	*source=='\0'||*chars=='\0') 		return NULL; 	while(*chars!='\0') 	{ 		while(*source!='\0') 			if(*chars==*source) 				return source;//12行就是这一行 			else 				source++; 		chars++; 	} 	return NULL; } gcc编译时显示如下错误： 61.c:12:5: 警告： return discards ‘const’ qualifier from pointer target type [默认启用] 运行程序时显示： 段错误 (核心已转储) 当然最主要的文件就是上述内容，错误肯定在这里面  （1）#define NULL (void *)0//我这里是不是有错误？ 这个是没错的，但是lz不必自己定义NULL这个宏变量，C标准中已经有这个定义了 （2）看lz的代码，意图好像是在source之中找到第一个存在于chars之中的字符，并返回这个字符在source中的指针，c++中string::find_first_of()即可以实现这一目标。目标字符不多的时候可以用如下的两重循环：  char* find_first_of(char* src, const char* target) {     char c;     const char* p;     for(; c = *src; ++src){         for(p = target; *p; ++p){             if(*p == c) return src;         }     }     return NULL; }  目标字符比较多的时候，用hash可能会更好些：  char* find_first_of(char* src, const char* target) {     char ascii[127] = {0};     for(; *target; ++target) ascii[*target] = 1;     for(; *src; ++src){         if(ascii[*src]) return src;     }     return NULL; }  但是lz的C代码中，实现的并不是这样的目的，例如 *source = "babbc", *chars = "abc"，则按lz的代码，得到的结果是&source[1]，即source中字符a对应的指针，对lz的需求表示不懂

算法是错滴。不过，就单从你的代码来看，应该这样写：   char *find_char(char const *source,char const *chars) {     if(source==NULL||chars==NULL||     *source=='\0'||*chars=='\0')         return NULL;      while(*chars!='\0')     { char* s = source;         while(*s!='\0')             if(*chars==*s)                 return s;//12行就是这一行             else                 s++;         chars++;     }     return NULL; }

引用 1 楼 user-4 的回复:函数原型是返回char*, 而source是const char* 从const char* 强制转换成char* 当然要警告老，const的意义就是让编译器帮你检查，防止误操作修改了变量的值 这个问题解决了，还有第二个子问题怎么办？注意看我问题


Question: 无操作系统嵌入式环境下实现web页面

nginx

你这个相当于做一个IIS服务器

引用 3 楼 zhao4zhong1 的回复:用TCP模拟HTTP 抓HTTP包，用TCP模拟实现之。 加我qq：能加qq深入探讨下吗。。加我：2051418146。。深入请教下

能详细探讨下吗

用TCP模拟HTTP 抓HTTP包，用TCP模拟实现之。

LZ所谓的“嵌入式装置（没有操作系统、网络、文件系统都不完整）”不会是单片机系统吧？ 否则的话最简单的方式就是移植开源的web服务器即可。


Question: 请问以下基于双向链表的直接插入排序正不正确?

好像已经有个类似的帖子了，我已经回复了。交换两个结点的操作。这里不再赘述 再提供另外一种方案，如果你是在搞不清楚怎么交换，且结点数据域不多，那么采用这种方式最快捷，简单方便  比较需要交换,则交换数据，注意只交换数据，不要交换next，prev指针域	 { 	数据类型 temp; 		memcpy(temp, pList->CurItem->数据); 		memcpy(pList->CurItem->数据, pTmp->CurItem->数据); 		memcpy(pTmp->CurItem->数据, temp); }  over！

以下是这种交换方式产生的串口信息, 看上去还正确一些  //exchange   A B<->C D  E pTmpA->CurItem->next = pTmpC->CurItem; //A->C B D pTmpC->CurItem->prev = pTmpA->CurItem;  //A<->C B D  pTmpB->CurItem->next = pTmpD->CurItem;  //A<->C B-> D pTmpD->CurItem->prev = pTmpB->CurItem;  //A<->C B<-> D  pTmpC->CurItem->next = pTmpB->CurItem;    //A<->C->B<-> D pTmpB->CurItem->prev=	 pTmpC->CurItem;  //A<->C<->B<-> D //exchange   .........0..........init.................filename: 155067.chm.....4.... .........0..........init.................filename: DAO360.CHM.....4.... .........0..........init.................filename: moviemk.chm.....4.... .........0..........init.................filename: wmplayer.chm.....4.... ......A: wmplayer.chm, B: 155067.chm, C: DAO360.CHM, D: moviemk.chm.....  ....exchage....DAO360.CHM..<-->..155067.chm....inloop 1..;.................................   .................outloop....i=1.............  ......A: wmplayer.chm, B: 155067.chm, C: DAO360.CHM, D: moviemk.chm.....  ....exchage....DAO360.CHM..<-->..155067.chm....inloop 2..;.......exchage....DAO360.CHM..<-->..155067.chm....inloop 1..;.................................   .................outloop....i=2.............  ......A: wmplayer.chm, B: 155067.chm, C: DAO360.CHM, D: moviemk.chm.....  ....exchage....DAO360.CHM..<-->..155067.chm....inloop 3..;.......exchage....DAO360.CHM..<-->..155067.chm....inloop 2..;.......exchage....DAO360.CHM..<-->..155067.chm....inloop 1..;.................................   .................outloop....i=3.............

引用 1 楼 user-2 的回复:参考下 a b 互换 a->prev->next = b;  b->prev = a->prev a->next = b->next;  b->next->prev = a;            b->next = a; a->prev = b;  试过了,换位有问题. 程序的排序框架也可能有问题.  以下是串口信息:...........................  .........0..........init.................filename: 155067.chm.....4.... .........0..........init.................filename: DAO360.CHM.....4.... .........0..........init.................filename: moviemk.chm.....4.... .........0..........init.................filename: wmplayer.chm.....4.... ......A: wmplayer.chm, B: 155067.chm, C: DAO360.CHM, D: moviemk.chm.....  ....exchage....DAO360.CHM..<-->..155067.chm....inloop 1..;.................................   .................outloop....i=1.............  ......A: wmplayer.chm, B: 155067.chm, C: DAO360.CHM, D: moviemk.chm.....  ....exchage....DAO360.CHM..<-->..155067.chm....inloop 2..;.......exchage....DAO360.CHM..<-->..155067.chm....inloop 1..;.................................   .................outloop....i=2.............  ......A: wmplayer.chm, B: 155067.chm, C: DAO360.CHM, D: moviemk.chm.....  ....exchage....DAO360.CHM..<-->..155067.chm....inloop 3..;.......exchage....DAO360.CHM..<-->..155067.chm....inloop 2..;.......exchage....DAO360.CHM..<-->..155067.chm....inloop 1..;.................................   .................outloop....i=3.............


Question: C语言如何判断非文本文件的结尾

图像数据是放在最后也是.bmp文件中占控空间最大的 读完了不是到最后了吗  仅供参考

引用 5 楼 yulitingfeng 的回复:按bmp数据格式来读取，查一下bmp的数据结构。 其中有bmp数据的起始位置，颜色深度，长和宽。以此为依据算出数据结束的偏移量。 有很多bmp读写的例子，可以看下嗯，我看过bmp的数据结构，其实我要读取的就是图像数据，其它的都不要。

int getc ( FILE * stream );   13.1 这样的代码有什么问题？ char c; while((c = getchar()) != EOF) ... 第一, 保存 getchar 的返回值的变量必须是 int 型。getchar() 可能返回任何字符 值, 包括 EOF。如果把 getchar 的返回值截为 char 型, 则正常的字符可能会被错误 的解释为 EOF, 或者 EOF 可能会被修改 (尤其是 char 型为无符号的时候), 从而永不出现。

还有一个问题请教，我这个程序的目的就是讲bmp文件的数据写入到bin文件里面： 那么我同时批量的将一个目录下的所有bmp文件数据写入到bin文件中。 为了方便操作，不考虑要逐个的输入bmp的文件名，只需要执行exe文件就将数据全部写入到bin文件 求知道的朋友，告诉一下思路，非常感谢！！

数据没有读完就跳出While（）了显然是没有判断对文件的结尾。 现在我用获取文件长度的方法解决了这个问题 请问还有什么其它的方法吗

不用着急知道文件结尾，2进制一般用fread按格式多次读取，分析获得的数据申请合适大小的缓存继续读入，检测返回值有问题，或者无法分析就该停止读取做特殊处理。你的方式即使能知道结尾，一口读到尾那也是塞内存做白工而已...

引用 8 楼 user-8 的回复:int ch; 而不是 char ch; 否则无法区分是读到了字节0xFF还是读到了文件尾EOF即-1

bmp数据是固定格式的 BITMAPFILEHEADER 中的bfOffBits 表示位图数据----包括BITMAPINFOHEADER和颜色表在内的数据----的起始位置。 第一 文件头，BITMAPFILEHEADER，是固定大小的； 第二位图信息头，BITMAPINFOHEADER，是固定大小的（不同版本不一样） 第三颜色表，和位图的位数有关，每种位图都是固定大小，有些位图，无颜色表。  最后的图像数据，无压缩格式大小，可以直接计算。就是 高的绝对值* 每行字节数。 压缩格式，BITMAPINFOHEADER，有个biSizeImage，表示图像的数据大小。

int ch; 而不是 char ch;


Question: 跪求指导

《算法导论》

看看算法导论。这本书就差不多了。系统的学一遍，以后做项目用到什么算法再看吧。没有必要花费很长时间去研究各种算法。除非是搞这方面研究的。就算学了很多算法，项目中也不一定能用上。

先看 严蔚敏的 c语言 数据结构！ 再看算法导论吧！

最经典的书籍《算法导论》  http://download.csdn.net/detail/wangyudong211/6466521

好空荡啊，我抢个沙发，http://tieba.baidu.com/p/1144136835


Question: 怎么学好递归

说实话，我对递归也是一知半解，尤其复杂的递归，直接把自己绕晕了。

理解递归的前提是你理解每一句程序，程序如果都看不懂，就别提理解递归了，然后就是自己慢慢体会这种思想了，你可以debug一步步来

引用 4 楼 max_min_ 的回复:递归也是函数调用的啊！只不过调用的是自己本身而已！ 递归最重要的是 退出条件！防止无限递归下去直中要害！

“给定一个小点的输入，完整单步跟踪(同时按Alt+7键查看Call Stack里面从上到下列出的对应从里层到外层的函数调用历史)一遍。”是理解递归函数工作原理的不二法门！ 递归函数关注以下几个因素 ·退出条件 ·参数有哪些 ·返回值是什么 ·局部变量有哪些 ·全局变量有哪些 ·何时输出 ·会不会导致堆栈溢出

1, 要理解递归是怎么回事. 2. 再编写程序, 并跟踪执行的每一步.  最重要的是你要理解,函数的调用与参数压栈

引用 8 楼 Vurteon 的回复:其实递归我个人感觉有点像数学中的归纳法，知道第一步正确，随便中间一步正确，就可以得出最后的答案，递归多了的是结束条件，递归一般是和分治联系起来的，为什么递归在二叉树或者韩罗塔问题上面显得这么强大简洁，就是每一个小问题都具有和大问题相同的性质，这样的问题使用递归比较合适。所以，我觉得，学好递归，先理解问题，在通过问题看本质，最后看代码，明白底层机制。以后写递归就按数学中的归纳法，不要过于转入细节，不然，递归如果复杂了，就不好理解了。由于，最近我们在上数据结构，对递归也一知半解，薄言见谅。 ++

多编一些小的递归程序，理解递归的定义。注意问题的划分，和结束的条件。

递归是要看状态的

按照数学知识中的递推关系来理解，可以参阅《组合数学》相关递归知识

如果楼主领悟了以上三条，递归就会成为你最喜欢用的算法，因为它语意清晰，表达简洁！！！

以下是我对递归的总结： 1.要从函数语意上来思考递归，理解递归，这样做有事半功倍的效果，从这个角度上来重新思考一下汉诺塔问题，必有收获，希望楼主能有所顿悟。  2.试着先把循环改成递归，体会一下，参数的作用。  3.递归要有一个出口点，要不然就无限执行下去了。

把递归程序单步调试一次，记录每个过程在一边，注意函数执行到那层

主要体会递归这种思想，一般使用递归算法还是很好判断的，很有规律。 适用于重复性的情况。如二叉树的递归遍历。 适用于本次结果依赖于前一次结果的情况，将前一次的结果看成是已知的（虽然真实情况不是这样的），这样就很这一次结果就很好求解了，典型的是汉诺塔问题。

关键是对状态的理解，lz可去将回溯法搜些资料进行学习


Question: 双向链表前后项交换是不是这样的过程?

//exchange   A B C D        pTmpD->CurItem->prev= pList->CurItem->next->prev;    //D          pTmpChg->CurItem->prev= pList->CurItem->prev;    //C        pTmpChg->CurItem->next= pList->CurItem->next;          pTmpA->CurItem->next = pList->CurItem->prev->prev->next;   //A         pList->CurItem->prev = pList->CurItem->prev->prev;        pList->CurItem->next = pList->CurItem->prev->next;         pList->CurItem->prev->prev = pTmpChg->CurItem->prev;          pList->CurItem->prev->next = pTmpChg->CurItem->next;           pList->CurItem->prev->prev->next= pTmpA->CurItem->next;     //<--A           pList->CurItem->next->prev = pTmpD->CurItem->prev;    //<--D         //exchange

//exchange        pTmpChg->CurItem->prev= pList->CurItem->prev;         pTmpChg->CurItem->next= pList->CurItem->next;          pList->CurItem->prev = pList->CurItem->prev->prev;        pList->CurItem->next = pList->CurItem->prev->next;         pList->CurItem->prev->prev = pTmpChg->CurItem->prev;          pList->CurItem->prev->next = pTmpChg->CurItem->next;          //exchange

引用 3 楼 hgjyts65fg 的回复:A B C D,  B C交换 自身要改变两个指针（B两个，C两个） A指向B和D指向C也要改变（B C都不是头尾的情况）。 所以，不包括临时操作，最少要改变6个指针.++

建议，自己写个小程序测试下！多练下手！

谢谢. 标点符号要点清楚， 不然看不清.

既然是双向链表，那就意味着，你可以根据一个给出的节点，prev next两个成员就可以知道前节点和后节点 交换节点的话其实并不是换位置，只是改一下指针的指向。 prevA nodeA nextA A节点和它的前后节点 prevB nodeB nextB B节点和它的前后节点 交换可以这样实现 prevA的next成员指向改为nodeB nextA的prev成员指向改为nodeB,再将nodeB的prev next成员 指向改为prevA 和 nextA 这样一弄，就把nodeB放到了prevA 和 nextA之间了(“之间"只是一个形象的说法，实际内存地址是没有移动的，链表本来就不是一个顺序存储的结构) 然后只要把nodeA放到prevB和nextB之间就行，这个和上面同理。 因为是双向链表，所以不用考虑头尾节点的特殊情况。

lz 的模型还停留在数组上

引用 楼主 huabinsir 的回复:双向链表前后项交换是不是这样的过程?  后项->临时交换, 前项->后项, 临时交换->前项  pTmpChg->CurItem = pList->CurItem;  //后项->临时交换 pList->CurItem->next = pList->CurItem->prev;  //前项->后项 pList->CurItem->prev = pTmpChg->CurItem;     //临时交换->前项  实在不习惯骚年变量命名的习惯，要是我的话就这样  typedef int ValueType; struct node{     ValueType value;     struct node* pre, *next; }; 至于你说的交换前后项，有两种实现方式： （1）纯指针操作 void swapWithBehind(struct node* p) {     struct node* q;     if(p == NULL || p == p->next) return; //connect p->pre with p->next     q = p->pre;     q->next = p->next;     p->next->pre = q; //connect p with p->next->next     q = p->next->next;     p->next = q;     q->pre = p; } （2）值操作(ValueType复制比较简单时还是比较好用的说) void swapWithBehind(struct node* p) {     ValueType tmp;     if(p == NULL || p == p->next) return;     tmp = p->value;     p->value = p->next->value;     p->next->value = tmp; }

//(B)前pList->CurItem->prev; (C)后pList->CurItem     //exchange   A B<->C D  pList->CurItem->prev->prev->next = pList->CurItem; //A->C B D  pList->CurItem->prev = pList->CurItem->prev->prev;  //A<->C B D  pList->CurItem->prev->next = pList->CurItem->next;  //A<->C B-> D  pList->CurItem->next->prev = pList->CurItem->prev;  //A<->C B<-> D  pList->CurItem->next = pList->CurItem->prev;    //A<->C->B<-> D  pList->CurItem->prev->prev =	 pList->CurItem;  //A<->C<->B<-> D   <---试过，这样不行

//(B)前pList->CurItem->prev; (C)后pList->CurItem           //exchange   A B<->C D       pList->CurItem->prev->prev->next = pTmp->CurItem; //A->C B D       pList->CurItem->prev = pList->CurItem->prev->prev;  //A<->C B D       pList->CurItem->prev->next = pList->CurItem->next;  //A<->C B-> D       pList->CurItem->next->prev = pList->CurItem->prev;  //A<->C B<-> D       pList->CurItem->next = pList->CurItem->prev;    //A<->C->B<-> D       pList->CurItem->prev->prev =	 pList->CurItem;  //A<->C<->B<-> D   ?

引用 7 楼 my_live_123 的回复:1<=>p<=>q<=>2 以交换pq为例说明：  p->prev->next = q;//1->q<=>2 q->prev = p->prev;//1<=>q<=>2 p->next = q->next;//1<=>q..p->2 q->next->prev = p;//1<=>q..p<=>2 q->next = p;//1<=>p->q<=>2 p->prev = q;//1<=>q<=>p<=>2  中间有些步骤可以调换，不做说明 1<-->p<-->q<-->2 以交换pq为例说明： p->prev->next = q;           //1    ->q       p       2 q->prev            = p->prev;//1<-->q       p       2 p->next            = q->next;//1<-->q       p    ->2 q->next->prev = p;           //1<-->q       p<-->2 q->next            = p;           //1<-->q   ->p<-->2 p->prev            = q;           //1<-->q<-->p<-->2

//exchange   A B<->C D        pTmpD->CurItem = pList->CurItem->next;    //D         pTmpA->CurItem = pList->CurItem->prev->prev;   //A         pTmpChg->CurItem = pList->CurItem;  //C ->tmp        pList->CurItem = pList->CurItem->prev;  //B->C        pList->CurItem->prev = pTmpChg->CurItem;  //tmp->B           pTmpA->CurItem->next = pList->CurItem->prev;   //A下一个是B        pList->CurItem->prev->prev = pTmpA->CurItem;   //B上一个是A         pList->CurItem->prev->prev->next = pList->CurItem; //B下一个是C        pList->CurItem->prev = pList->CurItem->prev;        //C上一个是B        pList->CurItem->next = pTmpD->CurItem;      //C下一个是C        pTmpD->CurItem->prev = pList->CurItem;	 //D上一个是C        //exchange    这样应是OK 的


Question: VC分配内存问题，实际分配和计算值不符

patch_table[i].per_frame = &pe[5*i]; //类型不匹配 *(patch_table[i].fra_pos) = ...//未初始化便解用  认真研读文档，完全掌握里面定义的数据结构，不能胡猜的...

引用 3 楼 u011896413 的回复:每个数组元素都进行一次动态分配，造成大量的内存碎片垃圾。 还有sizeof(Matching_block)应该是4+4个字节，不是4+1.每个指针占4字节 --------------------------------------------------------- 预防产生内存碎片：首先，尽量少使用动态内存。在大多数情况下，你可能使用静态或自动存储或者是STL容器。第二，尽量分配大块的内存而不是一次只分配少量内存。举个例子：一次分配一个数组实例所需的内存，而不是一次只分配一个数组元素的内存。  看了回复，豁然开朗。。。是不是我开始直接开辟个1920*1080*5(5是那个for里面一个指针和一个uchar的大小)的空间，然后再在把那个空间的地址再次分配给结构体里面的指针吗？ struct Matching_block	 { 	unsigned char *per_frame;	 	unsigned **fra_pos;		 }; int main() { 	 int he_wi = 1920*1080;      int i; 	 Matching_block	*patch_table = NULL; 	patch_table = (Matching_block *)calloc( he_wi,sizeof(Matching_block) ); 	unsigned char *pe;     //unsigned char *pi; 	pe = (unsigned char*)calloc( 1920*1080*5,sizeof(unsigned char) ); 	for (i = 0; i < 1920*1080; i++ )									 	{						 		patch_table[i].per_frame = &pe[5*i];		 		*(patch_table[i].fra_pos) = (unsigned*)&pe[1+5*i]; 	}     return 0;  }

太多内存碎片了！不推荐这么玩！浪费资源！

引用 1 楼 user-5 的回复:130M少了。 你每次分配1字节，至少浪费8字节，有效空间太少。都用来记录，分配的内存了。  google 有关介绍内存动态分配的文章看看


Question: 多线程问题，过来瞧瞧

引用 3 楼 lunat 的回复:有问题, 多核CPU下，多线程单纯读写字节都会造成未定义动作。 就算是单核CPU，因为你不能确定主线程执行if(!g_str[0])return;时，线程一是否正在对g_str进行操作，所以依据这个判断做出的任何假设都不具有有效性。 [quote=引用 楼主 wallwind 的回复:] 一个线程对一个char 字符数组更新数据，主线程会读取这个数组的数据，但是，读之前都会进判空， 比如char g_str[200]={'0'};  线程一 update g_str  主线程  if(!g_str[0]) return;  请问是否有问题？[/quote]  开启的线程单纯的写。主线程只去读。。。会有未定义行为么？

加锁吧, 锁本身损耗不大, 竞争锁引起的等待代价比较高, 看大约有多少时间多少机会是会引发竞争.

引用 13 楼 max_min_ 的回复:其实还是需要结合实际业务需求的！如果不想出现不必要的bug，还是建议加上锁吧！ 安全可靠点！  加锁的确是安全可靠。就是因为 上级觉得我不加锁，不行。把我一竿子否定。。。  加锁是最好的。我知道。谢谢了

引用 8 楼 lunat 的回复:因为你不知道你的编译器会生成什么样的汇编指令，所以你不能单纯的依赖C++代码，推测线程之间的同步关系。  编译器不知道你在多个线程之间有共享数据，它不知道你在一个线程中写的数据，另外一个线程会使用。写的线程可能只是把数据写到寄存器或者缓存中，而不产生写入内存的指令；读的线程也可能只是从寄存器或者缓存中读取，而不产生读取内存的指令。  不是说读写本身会导致未定义行为，是你使用这些数据时，特别是依赖于这些数据有效性的代码，可能导致未定义行为。多核CPU下的特殊性是多个CPU同时执行的指令（每个指令分为数个步骤）可能涉及同一个内存地址。如果两个线程同时写，那么最终结果什么值都有可能。仅分别读写，读到的数据可能是改之前的也可能是改之后的。 引用 7 楼 liquanhai 的回复:有可能是读的过程中，正在写数据，读时候判断的长度和内容，读的过程中另一个线程会改写，最好是加锁，这是习惯问题。看看这篇文章吧，http://www.doc88.com/p-330763974969.html  是，之前是想加锁来着，但是我觉得加锁解锁影响我的效率。 另外读线程，即使读到脏数据 ，主线程都没关系，

看业务逻辑，如果主线程有其他活可干，循环检测是可以简单不上锁，确定要进一步读取再加锁。不过你直接return，看不出是啥逻辑...

有问题  判空时候就算正确  读取的时候另一个线程正好修改了

读出来脏数据能正确处理的话那可以不锁

共享资源应该加锁，除非你确定读写都是原子操作或不可被打断

有问题, 多核CPU下，多线程单纯读写字节都会造成未定义动作。 就算是单核CPU，因为你不能确定主线程执行if(!g_str[0])return;时，线程一是否正在对g_str进行操作，所以依据这个判断做出的任何假设都不具有有效性。 引用 楼主 wallwind 的回复:一个线程对一个char 字符数组更新数据，主线程会读取这个数组的数据，但是，读之前都会进判空， 比如char g_str[200]={'0'};  线程一 update g_str  主线程  if(!g_str[0]) return;  请问是否有问题？

一个线程写,一个线程读,难道不加锁

没有问题！但是有点浪费！当数据没有发什么变法的时候，就不需要再进行主线程的判断！ 所以在线程一应该更新到一个局部变量，全局量来上一次更新的数据！


Question: 超声波避障模块程序

发出来，学习一下吧


(1) 算法错.试以下输入: 1 1 1  (2) printf("case %d:\n",c+1)中c不是大写的C.  (3) 最后一行输出后面多了空行.

你就是复制了一下啊。。。。。？

#include<stdio.h> int main(void) { int c,T,i,n,a[100000],j,k,sum; scanf("%d",&T); for(c = 0;c < T;c++) { sum = 0; for(i = 0;i < 100000;i++) a[i] = 0; scanf("%d",&n); for(i = 0;i < n;i++) scanf("%d",&a[i]); if(a[0] >= a[n-1]) { j = 1;k = n-1; } else { j = 2;k = n; } for(i = j-1;i < k;i++) sum = sum + a[i];  printf("case %d:\n",c+1); printf("%d %d %d\n\n",sum,j,k); } return 0; }


Question: c语言定时执行 计时器

C:\>schtasks /?  SCHTASKS /parameter [arguments]  描述:     允许管理员创建、删除、查询、更改、运行和中止本地或远程系统上的计划任     务。替代 AT.exe。  参数列表:     /Create         创建新计划任务。      /Delete         删除计划任务。      /Query          显示所有计划任务。      /Change         更改计划任务属性。      /Run            立即运行计划任务。      /End            中止当前正在运行的计划任务。      /?              显示帮助消息。  示例:     SCHTASKS     SCHTASKS /?     SCHTASKS /Run /?     SCHTASKS /End /?     SCHTASKS /Create /?     SCHTASKS /Delete /?     SCHTASKS /Query  /?     SCHTASKS /Change /?  C:\>schtasks /Create /?  SCHTASKS /Create [/S system [/U username [/P [password]]]]     [/RU username [/RP password]] /SC schedule [/MO modifier] [/D day]     [/M months] [/I idletime] /TN taskname /TR taskrun [/ST starttime]     [/RI interval] [ {/ET endtime | /DU duration} [/K] ]     [/SD startdate] [/ED enddate] [/IT] [/Z] [/F]  描述:     允许管理员在本地或远程系统上创建计划任务。  参数列表:     /S           system            指定要连接到的远程系统。如果省略这个                                    系统参数，默认是本地系统。      /U           username          指定命令执行的用户上下文。      /P           [password]        指定给定用户上下文的密码。如果省略则                                    提示输入。      /RU          username          指定任务在其下运行的“运行方式”用户                                    帐户(用户上下文)。对于系统帐户，有效                                    值是 ""、"NT AUTHORITY\SYSTEM" 或                                    "SYSTEM"。      /RP          [password]        指定“运行方式”用户的密码。要提示输                                    入密码，值必须是 "*" 或无。系统帐户                                    会忽略该密码。      /SC          schedule          指定计划频率。                                    有效计划任务: MINUTE, HOURLY,                                    DAILY, WEEKLY, MONTHLY, ONCE,                                    ONSTART, ONLOGON, ONIDLE.      /MO          modifier          改进计划类型以允许更好地控制计划重复                                    周期。有效值列于下面“修改者”部分中。      /D           days              指定该周内运行任务的日期。有效值:                                    MON, TUE,WED, THU, FRI, SAT, SUN                                    和对 MONTHLY 计划的 1 - 31                                    (某月中的日期)。通配符“*”指定所有                                    日期。      /M           months            指定一年内的某月。默认是该月的第一天。                                    有效值: JAN, FEB, MAR, APR, MAY, JUN,                                    JUL, AUG, SEP, OCT, NOV, DEC。通配符                                    “*” 指定所有的月。      /I           idletime          指定运行一个已计划的 ONIDLE 任务之前                                    要等待的空闲时间。                                    有效值范围: 1 到 999 分钟。      /TN          taskname          指定唯一识别这个计划任务的名称。      /TR          taskrun           指定在这个计划时间运行的程序的路径                                    和文件名。                                    例如: C:\windows\system32\calc.exe      /ST          starttime         指定运行这个任务的开始时间。时间格式                                    是 HH:mm (24 小时时间) 例如 14:30 为                                    2:30 PM。默认到当前时间。      /RI          interval          用分钟指定重复间隔。这无法应用于                                    已计划的类型: MINUTE, HOURLY,                                    ONSTART, ONLOGON, ONIDLE。                                    有效范围: 1 - 599940 分钟。                                    如果指定了 /ET 或 /DU，它会默认到                                    10 分钟。      /ET          endtime           指定运行任务的结束时间。                                    时间格式是 HH:mm (24 小时时间)                                    例如 14:50 为 2:50 PM。这无法运用于                                    计划类型: ONSTART, ONLOGON, ONIDLE。      /DU          duration          指定运行此任务的持续时间。                                    时间格式是 HHHH:mm。                                    这不适用于 /ET 和计划类型: ONSTART，                                     ONLOGON, ONIDLE。如果指定了 /RI，                                    那么默认为 1 小时。      /K                             在结束时间或持续时间终止此任务。                                    这不适用于计划类型: ONSTART,                                    ONLOGON, ONIDLE。必须指定 /ET                                    或 /DU。      /SD          startdate         指定第一次运行这个                                    任务的日期。格式是 yyyy/mm/dd。                                    默认为当前时间。这不适用于计划                                    类型: ONCE, ONSTART, ONLOGON,                                    ONIDLE.      /ED          enddate           指定此任务运行的最后一天的日期。                                    格式是 yyyy/mm/dd。                                    这不适用于计划类型: ONCE, ONSTART,                                    ONLOGON, ONIDLE。      /IT                            /RU 用户在此作业运行时登录才启                                    用此任务用交互方式运行。                                    用户登录后此任务才运行。      /Z                             如果此任务没有计划再次运行，                                    会删除此任务。      /F                             如果指定的任务已经存在，强行                                    创建此任务并不显示警告。      /?                             显示该帮助消息。  修改者: 按计划类型的 /MO 开关的有效值:     MINUTE:  1 到 1439 分钟。     HOURLY:  1 到 23 小时。     DAILY:   1 到 365 天。     WEEKLY:  1 到 52 周。     ONCE:    无修改者。     ONSTART: 无修改者。     ONLOGON: 无修改者。     ONIDLE:  无修改者。     MONTHLY: 1 到 12，或              FIRST, SECOND, THIRD, FOURTH, LAST, LASTDAY。  示例:     ==> 在远程机器 "ABC" 上创建计划任务 "doc"，         该机器每小时在 "runasuser" 用户下运行 notepad.exe。          SCHTASKS /Create /S ABC /U user /P password /RU runasuser                  /RP runaspassword /SC HOURLY /TN doc /TR notepad      ==> 在远程机器 "ABC" 上创建计划任务 "accountant"，         在指定的开始日期和结束日期之间的开始时间和结束时间内，         每隔五分钟运行 calc.exe。          SCHTASKS /Create /S ABC /U domain\user /P password /SC MINUTE                  /MO 5 /TN accountant /TR calc.exe /ST 12:00 /ET 14:00                  /SD 2002/12/30 /ED 2002/12/30 /RU runasuser /RP      ==> 创建计划任务 "gametime"，在每月的第一个星期天         运行“空当接龙”。          SCHTASKS /Create /SC MONTHLY /MO first /D SUN /TN gametime                  /TR c:\windows\system32\freecell      ==> 在远程机器 "ABC" 创建计划任务 "report"，         每个星期运行 notepad.exe。          SCHTASKS /Create /S ABC /U user /P password /RU runasuser                  /RP runaspassword /SC WEEKLY /TN report /TR notepad.exe      ==> 在远程机器 "ABC" 创建计划任务 "logtracker"，         每隔五分钟从指定的开始时间到无结束时间，         运行 notepad.exe。将提示输入 /RP         密码。          SCHTASKS /Create /S ABC /U domain\user /P password /SC MINUTE                  /MO 5 /TN logtracker                  /TR c:\windows\system32\notepad.exe /ST 18:30                  /RU runasuser /RP      ==> 创建计划任务 "gaming"，每天从 12:00 点开始到         14:00 点自动结束，运行 freecell.exe。          SCHTASKS /Create /SC HOURLY /TN gaming /TR c:\freecell /ST 12:00                  /ET 14:00 /K

Linux下的计划任务服务crond   可以实现。

引用 2 楼 xt646449830 的回复:[quote=引用 1 楼 u011779875 的回复:] 取系统时间啊 如果是0点就发呗 这有什么 如何指定时间执行一项任务确不知道如何实现 创建进程 线程 想怎么搞怎么搞 看需求 一触发就创建上传的进程 发送完 干掉  ok每秒都去取系统时间。。。。[/quote] 这个随便写了啊 当然 当你服务器一直开启的时候 前提  不重启 那么你没很长时间取一次时间啊  当你取时间发现 马上0点之前的5分钟 你就要改变取法了啊 这都是你说的算 那只是比喻 也就100行代码 处理下

用Timer每隔一段时间（比如10分钟）执行一次你的程序就是。在程序中判断当前时间是否是零点前后。 貌似你这程序对实时性要求又不高。  引用 2 楼 xt646449830 的回复:[quote=引用 1 楼 u011779875 的回复:] 取系统时间啊 如果是0点就发呗 这有什么 如何指定时间执行一项任务确不知道如何实现 创建进程 线程 想怎么搞怎么搞 看需求 一触发就创建上传的进程 发送完 干掉  ok每秒都去取系统时间。。。。[/quote]

引用 1 楼 u011779875 的回复:取系统时间啊 如果是0点就发呗 这有什么 如何指定时间执行一项任务确不知道如何实现 创建进程 线程 想怎么搞怎么搞 看需求 一触发就创建上传的进程 发送完 干掉  ok每秒都去取系统时间。。。。


Question: 右键进入函数的定义，怎么退回写代码的窗口？

首先你确定这是汇编？？ 其次，那只是打开了新窗口而已，你可以直接点右上角的X关掉，或者在窗口里，切换下就OK了。 当然也可以用快捷键，不过我不是很熟。ctrl+Tab？

Ctrl+Tab 或者Alt+左箭头

编辑 |Bookmarks                       |Alt+F2                | 编辑 |BookmarkToggle                  |Ctrl+F2               |Toggles a bookmark for the current line on and off 编辑 |BookmarkClearAll                |Ctrl+Shift+F2         |Clears all bookmarks in the window 编辑 |BookmarkNext                    |F2                    |Moves to the line containing the next bookmark 编辑 |BookmarkPrev                    |Shift+F2              |Moves to the line containing the previous bookmark Visual Studio 6开发环境下的所有热键一览表 http://download.csdn.net/detail/zhao4zhong1/2196516

引用 1 楼 lipoor1234 的回复: 视图->解决方案资源管理器 然后双击你的点c文件 嗯，虽然只是看到了vs2010的方法，但是我想vc++6.0也差不多。

视图->解决方案资源管理器 然后双击你的点c文件


Question: 有关cvSetImageROI()和cvResetImageROI()函数的困惑

cvCloneImage()函数不但会复制图像数据，而且会拷贝图像头，也就是说，会连原图像的typedef struct _IplImage结构数据，你设置了ROI，其实只是更改了原图像typedef struct _IplImage结构中中roi成员，而其他成员并没有改变，所以你克隆后的图像width和height当然会等于原图像，

的确，因为clone的时候大概把其他参数也clone过来，建议你先根据ROI大小，Create dstimg，这样dstimg的大小就是ROI的大小了

你应当在cvResetImageROI(img); 这一语句前输出你想要的结果

上一页  目　录  下一页  SetImageROI     SetImageROI 基于给定的矩形设置感兴趣区域   void cvSetImageROI( IplImage* image, CvRect rect ); image  图像头.  rect  ROI 矩形.  函数 cvSetImageROI 基于给定的矩形设置图像的 ROI（感兴趣区域） . 如果ROI是NULL 并且参数RECT的值不等于整个图像, ROI被分配. 不像 COI, 大多数的 OpenCV 函数支持 ROI 并且处理它就像它是一个分离的图像 (例如, 所有的像素坐标从ROI的左上角或左下角（基于图像的结构）计算。       收录时间：2007年7月18日，15点15分 编辑时间：2007年7月18日，15点15分

cvShowImage("dst",dst); 用的是roi参数里面的值 而这个值 就是cvRect(0,0,120,120);

typedef struct CvRect {int x; /* 方形的最左角的x-坐标 */ int y; /* 方形的最上或者最下角的y-坐标 */ int width; /* 宽 */ int height; /* 高 */ }  IplImage 结构解读：  typedef struct _IplImage  {  int nSize;                    /* IplImage大小 */   int ID;                         /* 版本 (=0)*/   int nChannels;           /* 大多数OPENCV函数支持1,2,3 或 4 个通道 */  int alphaChannel; /* 被OpenCV忽略 */  int depth; /* 像素的位深度: IPL_DEPTH_8U, IPL_DEPTH_8S, IPL_DEPTH_16U, IPL_DEPTH_16S, IPL_DEPTH_32S, IPL_DEPTH_32F and IPL_DEPTH_64F 可支持 */  char colorModel[4]; /* 被OpenCV忽略 */  char channelSeq[4]; /* 同上 */   int dataOrder; /* 0 - 交叉存取颜色通道, 1 - 分开的颜色通道. cvCreateImage只能创建交叉存取图像 */  int origin; /* 0 - 顶—左结构,1 - 底—左结构 (Windows bitmaps 风格) */   int align; /* 图像行排列 (4 or 8). OpenCV 忽略它，使用 widthStep 代替 */  int width; /* 图像宽像素数 */   int height; /* 图像高像素数*/   struct _IplROI *roi; /* 图像感兴趣区域. 当该值非空只对该区域进行处理 */  struct _IplImage *maskROI; /* 在 OpenCV中必须置NULL */   void *imageId; /* 同上*/   struct _IplTileInfo *tileInfo; /*同上*/   int imageSize; /* 图像数据大小(在交叉存取格式下imageSize=image->height*image->widthStep），单位字节*/   char *imageData; /* 指向排列的图像数据 */ int widthStep; /* 排列的图像行大小，以字节为单位 */ int BorderMode[4]; /* 边际结束模式, 被OpenCV忽略 */ int BorderConst[4];   以下为网上验证  结论 cvSetImageROI(img,cvRect(0,0,120,120));  最后还有一个重要参数roi(region of interest 感兴趣的区域),这个参数是IplROI结构体类型的变量。IplROI结构体包含了xOffset,yOffset,height,width,coi成员变量，其中xOffset,yOffset是x,y坐标，coi代表channel of interest(感兴趣的通道)。有时候，OpenCV图像函数不是作用于整个图像，而是作用于图像的某一个部分。这是，我们就可以使用roi成员变量了。如果IplImage变量中设置了roi，则OpenCV函数就会使用该roi变量。如果coi被设置成非零值，则对该图像的操作就只作用于被coi指定的通道上了。不幸的是，许多OpenCV函数忽略了coi的值。  访问图像中的数据

引用 2 楼 gaoping15106203675 的回复:我返回他们的width,height, "cout<<"img width = "<< img->width<<endl; cout<<"img height ="<< img->height<<endl; cout<<"dst width = "<<dst->width<<endl; cout<<"dst height ="<< dst->height<<endl;" 得到的结果都255,255；255,255；可是显示的图像大小却是（255,255），（120,120），不理解的就是这里，不好意思，表述不清晰。 第一 声明 我只看过很少的学习opencv 我想你也是书上的例子吧 第二 遇到问题 分析问题 解决问题 其实你也可以得 只是你没静下心来  你可以去用程序验证你的问题了 其实你已经解决了百分之80了 剩下的就是反推了 cvSetImageROI(img,cvRect(0,0,120,120)); dst = cvCloneImage(img); 第一个函数 cvSetImageROI 里面的参数cvRect(0,0,120,120) 只是改变图片的显示位置 和像素的大小 并没有改变这副图片的像素  所以cout<<"img width = "<< img->width<<endl; cout<<"img height ="<< img->height<<endl; cout<<"dst width = "<<dst->width<<endl; cout<<"dst height ="<< dst->height<<endl; 他们都是一样的  也就是说取cvResetImageROI() 只是改变img的显示位置的参数cvRect 这是一种类型 你按f12 查看 或者百度查看，这个函数并不改变图片的本身  推理完毕 按道理讲 没有第二种解释 会比我这个好 所以我的回答是正确的  我也是新手 只不过接触了2天opencv 剩下的就是你自己的逻辑分析 以结果 分析结果

虽然我很想回答你这个opencv的问题 但是我没看懂你的问题问的是什么 获取两图像的width和height，却是一样大小 是什么意思 啊 你那个分明就不是一样大小的啊 不是获取原图的某部分区域吗 从 0 0开始120 120像素吗 你还想要多大的啊


Question: 怎么解决3n+1，溢出问题？

n =3*n+1;     n/=2 ; 改成             n = n+ (n+1)/2;  原来 3倍+1，现在降到 1.5 左右，正符合适度缓解的情况。 64位，则可以提高表示范围，更大精度缓解了溢出问题。  你要确保没问题，高精度计算估计跑不了。

否则你就高精度吧。

引用 3 楼 lm_whales 的回复:n =3*n+1;     n/=2 ; 改成             n = n+ (n+1)/2;   [quote=引用 楼主 zhang5476499 的回复:] 3n+1问题是一个简单有趣而又没有解决的数学问题。这个问题是由L. Collatz在1937年提出的。克拉兹问题（Collatz problem）也被叫做hailstone问题、3n+1问题、Hasse算法问题、Kakutani算法问题、Thwaites猜想或者Ulam问题。 问题如下： （1）输入一个正整数n； （2）如果n=1则结束； （3）如果n是奇数，则n变为3n+1，否则n变为n/2； （4）转入第（2）步。    #include<stdio.h> #include<math.h> int main() { 	int n; 	int count=0; 	scanf("%d",&n); 	while(1<n) 	{ 		if(n%2==1) 		{ 			n=3*n+1; 			n/=2; 		} 		else 		{ 			n=n/2; 		} 		count++; 		if(n==1) break; 	} 	printf("%d\n",count);  	return 0; } 刘汝佳的书上就写着：因为n为奇数时候3n+1一定是偶数，下一步将其立刻除以2.如果将将两次操作一起做，可以在一定程度上缓解这个问题。我就是这么做的，但是输出987654321时候还是溢出拉。[/quote]  接着改成zhao4那种形式

#include<stdio.h> #include<math.h> #include <conio.h> int main() { 	unsigned int n; 	int count=0; 	scanf("%d",&n);  	while(n>1) 	{ 		if(n & 1) 		{ 			//n=3*n+1; 			n=n+(n+1)/2; 			//n/=2; 			count++; 		} 		else 		{ 			n=n/2; 		} 		count++; 	} 	printf("%d\n",count); 	getch(); 	return 0; }  LZ验证一下吧

#用python吧，不用担心溢出 def n3n1(n):     count=0     while n>1:         if n%2==1:             n=3*n+1             n=n/2         else:             n=n/2         count+=1         if n==1:             break     return count  print n3n1(1000000000000000000000000000000000000000000)  #输出517

(3n+1)/2==> n+(n+1)/2

32位的int，去掉符号位，最大不是2147483648吗？  你的987654321*3+1肯定大于这个值，能不溢出吗？  所以老赵使用64位的int是正解。但如果你要无限运算下去，则需要自己写一个大数计算函数，自己通过数组来完成四则运算。

#include <iostream> #include <string> using namespace std; inline int compare(string str1,string str2) {//相等返回0，大于返回1，小于返回-1          if (str1.size()>str2.size()) return 1; //长度长的整数大于长度小的整数     else if (str1.size()<str2.size()) return -1;     else                              return str1.compare(str2); //若长度相等，则头到尾按位比较 } string SUB_INT(string str1,string str2); string ADD_INT(string str1,string str2) {//高精度加法     int sign=1; //sign 为符号位     string str;     if (str1[0]=='-') {         if (str2[0]=='-') {             sign=-1;             str=ADD_INT(str1.erase(0,1),str2.erase(0,1));         } else {             str=SUB_INT(str2,str1.erase(0,1));         }     } else {         if (str2[0]=='-') {             str=SUB_INT(str1,str2.erase(0,1));         } else { //把两个整数对齐，短整数前面加0补齐             string::size_type L1,L2;             int i;             L1=str1.size();             L2=str2.size();             if (L1<L2) {                 for (i=1;i<=L2-L1;i++) str1="0"+str1;             } else {                 for (i=1;i<=L1-L2;i++) str2="0"+str2;             }             int int1=0,int2=0; //int2 记录进位             for (i=str1.size()-1;i>=0;i--) {                 int1=(int(str1[i])-'0'+int(str2[i])-'0'+int2)%10;                 int2=(int(str1[i])-'0'+int(str2[i])-'0'+int2)/10;                 str=char(int1+'0')+str;             }             if (int2!=0) str=char(int2+'0')+str;         }     }     //运算后处理符号位     if ((sign==-1)&&(str[0]!='0')) str="-"+str;     return str; } string SUB_INT(string str1,string str2) {//高精度减法     int sign=1; //sign 为符号位     string str;     int i,j;     if (str2[0]=='-') {         str=ADD_INT(str1,str2.erase(0,1));     } else {         int res=compare(str1,str2);         if (res==0) return "0";         if (res<0) {             sign=-1;             string temp =str1;             str1=str2;             str2=temp;         }         string::size_type tempint;         tempint=str1.size()-str2.size();         for (i=str2.size()-1;i>=0;i--) {             if (str1[i+tempint]<str2[i]) {                 j=1;                 while (1) {//zhao4zhong1添加                     if (str1[i+tempint-j]=='0') {                         str1[i+tempint-j]='9';                         j++;                     } else {                         str1[i+tempint-j]=char(int(str1[i+tempint-j])-1);                         break;                     }                 }                 str=char(str1[i+tempint]-str2[i]+':')+str;             } else {                 str=char(str1[i+tempint]-str2[i]+'0')+str;             }         }         for (i=tempint-1;i>=0;i--) str=str1[i]+str;     }     //去除结果中多余的前导0     str.erase(0,str.find_first_not_of('0'));     if (str.empty()) str="0";     if ((sign==-1) && (str[0]!='0')) str ="-"+str;     return str; } string MUL_INT(string str1,string str2) {//高精度乘法     int sign=1; //sign 为符号位     string str;     if (str1[0]=='-') {         sign*=-1;         str1 =str1.erase(0,1);     }     if (str2[0]=='-') {         sign*=-1;         str2 =str2.erase(0,1);     }     int i,j;     string::size_type L1,L2;     L1=str1.size();     L2=str2.size();     for (i=L2-1;i>=0;i--) { //模拟手工乘法竖式         string tempstr;         int int1=0,int2=0,int3=int(str2[i])-'0';         if (int3!=0) {             for (j=1;j<=(int)(L2-1-i);j++) tempstr="0"+tempstr;             for (j=L1-1;j>=0;j--) {                 int1=(int3*(int(str1[j])-'0')+int2)%10;                 int2=(int3*(int(str1[j])-'0')+int2)/10;                 tempstr=char(int1+'0')+tempstr;             }             if (int2!=0) tempstr=char(int2+'0')+tempstr;         }         str=ADD_INT(str,tempstr);     }     //去除结果中的前导0     str.erase(0,str.find_first_not_of('0'));     if (str.empty()) str="0";     if ((sign==-1) && (str[0]!='0')) str="-"+str;     return str; } string DIVIDE_INT(string str1,string str2,int flag) {//高精度除法。flag==1时,返回商; flag==0时,返回余数     string quotient,residue; //定义商和余数     int sign1=1,sign2=1;     if (str2 == "0") {  //判断除数是否为0         quotient= "ERROR!";         residue = "ERROR!";         if (flag==1) return quotient;         else         return residue ;     }     if (str1=="0") { //判断被除数是否为0         quotient="0";         residue ="0";     }     if (str1[0]=='-') {         str1   = str1.erase(0,1);         sign1 *= -1;         sign2  = -1;     }     if (str2[0]=='-') {         str2   = str2.erase(0,1);         sign1 *= -1;     }     int res=compare(str1,str2);     if (res<0) {         quotient="0";         residue =str1;     } else if (res == 0) {         quotient="1";         residue ="0";     } else {         string::size_type L1,L2;         L1=str1.size();         L2=str2.size();         string tempstr;         tempstr.append(str1,0,L2-1);         for (int i=L2-1;i<L1;i++) { //模拟手工除法竖式             tempstr=tempstr+str1[i];             tempstr.erase(0,tempstr.find_first_not_of('0'));//zhao4zhong1添加             if (tempstr.empty()) tempstr="0";//zhao4zhong1添加             for (char ch='9';ch>='0';ch--) { //试商                 string str;                 str=str+ch;                 if (compare(MUL_INT(str2,str),tempstr)<=0) {                     quotient=quotient+ch;                     tempstr =SUB_INT(tempstr,MUL_INT(str2,str));                     break;                 }             }         }         residue=tempstr;     }     //去除结果中的前导0     quotient.erase(0,quotient.find_first_not_of('0'));     if (quotient.empty()) quotient="0";     if ((sign1==-1)&&(quotient[0]!='0')) quotient="-"+quotient;     if ((sign2==-1)&&(residue [0]!='0')) residue ="-"+residue ;     if (flag==1) return quotient;     else         return residue ; } string DIV_INT(string str1,string str2) {//高精度除法,返回商     return DIVIDE_INT(str1,str2,1); } string MOD_INT(string str1,string str2) {//高精度除法,返回余数     return DIVIDE_INT(str1,str2,0); } int main() {     char ch;     string s1,s2,res;      while (cin>>s1>>ch>>s2) {         switch (ch) {             case '+':res=ADD_INT(s1,s2);break;             case '-':res=SUB_INT(s1,s2);break;             case '*':res=MUL_INT(s1,s2);break;             case '/':res=DIV_INT(s1,s2);break;             case '%':res=MOD_INT(s1,s2);break;             default :                   break;         }         cout<<res<<endl;     }     return(0); }

#include<stdio.h> #include<math.h> int main() {     unsigned long long n;     unsigned long long =0ull;     scanf("%llu",&n);     while(1ull<n)     {         if(n%2ull==1ull)         {             n=3ull*n+1ull;             n/=2ull;         }         else         {             n=n/2ull;         }         count++;         if(n==1ull) break;     }     printf("%llu\n",count);      return 0; }

引用 3 楼 lm_whales 的回复:n =3*n+1;     n/=2 ; 改成             n = n+ (n+1)/2;   [quote=引用 楼主 zhang5476499 的回复:] 3n+1问题是一个简单有趣而又没有解决的数学问题。这个问题是由L. Collatz在1937年提出的。克拉兹问题（Collatz problem）也被叫做hailstone问题、3n+1问题、Hasse算法问题、Kakutani算法问题、Thwaites猜想或者Ulam问题。 问题如下： （1）输入一个正整数n； （2）如果n=1则结束； （3）如果n是奇数，则n变为3n+1，否则n变为n/2； （4）转入第（2）步。    #include<stdio.h> #include<math.h> int main() { 	int n; 	int count=0; 	scanf("%d",&n); 	while(1<n) 	{ 		if(n%2==1) 		{ 			n=3*n+1; 			n/=2; 		} 		else 		{ 			n=n/2; 		} 		count++; 		if(n==1) break; 	} 	printf("%d\n",count);  	return 0; } 刘汝佳的书上就写着：因为n为奇数时候3n+1一定是偶数，下一步将其立刻除以2.如果将将两次操作一起做，可以在一定程度上缓解这个问题。我就是这么做的，但是输出987654321时候还是溢出拉。[/quote]改了，还是溢出。按照你的代码，计数器count要进行修改。代码如下； #include<stdio.h> #include<math.h> int main() { 	int n; 	int count=0; 	scanf("%d",&n); 	while(1<n) 	{ 		if(n%2==1) 		{ 			n =(3*n+1)/2; 			count++; 			count++; 		} 		else 		{ 			n=n/2; 			count++; 		} 		if(n==1) break; 	} 	printf("%d\n",count);  	return 0; }

引用 1 楼 zhao4zhong1 的回复:#include<stdio.h> #include<math.h> int main() {     unsigned __int64 n;     unsigned __int count=0ui64;     scanf("%I64u",&n);     while(1ui64<n)     {         if(n%2ui64==1ui64)         {             n=3ui64*n+1ui64;             n/=2ui64;         }         else         {             n=n/2ui64;         }         count++;         if(n==1ui64) break;     }     printf("%I64u\n",count);       return 0; } 赵老师，你的代码，目前超出我的范围，不过没关系，以后再慢慢看。

n =3*n+1;     n/=2 ; 改成             n = n+ (n+1)/2;   引用 楼主 zhang5476499 的回复:3n+1问题是一个简单有趣而又没有解决的数学问题。这个问题是由L. Collatz在1937年提出的。克拉兹问题（Collatz problem）也被叫做hailstone问题、3n+1问题、Hasse算法问题、Kakutani算法问题、Thwaites猜想或者Ulam问题。 问题如下： （1）输入一个正整数n； （2）如果n=1则结束； （3）如果n是奇数，则n变为3n+1，否则n变为n/2； （4）转入第（2）步。    #include<stdio.h> #include<math.h> int main() { 	int n; 	int count=0; 	scanf("%d",&n); 	while(1<n) 	{ 		if(n%2==1) 		{ 			n=3*n+1; 			n/=2; 		} 		else 		{ 			n=n/2; 		} 		count++; 		if(n==1) break; 	} 	printf("%d\n",count);  	return 0; } 刘汝佳的书上就写着：因为n为奇数时候3n+1一定是偶数，下一步将其立刻除以2.如果将将两次操作一起做，可以在一定程度上缓解这个问题。我就是这么做的，但是输出987654321时候还是溢出拉。

引用 1 楼 zhao4zhong1 的回复:#include<stdio.h> #include<math.h> int main() {     unsigned __int64 n;     unsigned __int count=0ui64;     scanf("%I64u",&n);     while(1ui64<n)     {         if(n%2ui64==1ui64)         {             n=3ui64*n+1ui64;             n/=2ui64;         }         else         {             n=n/2ui64;         }         count++;         if(n==1ui64) break;     }     printf("%I64u\n",count);       return 0; }  ++


Question: 用Ｃ语言生成页面并送到客户端显示？？、

简单的通信！ 可能组xml文件有点棘手，网上搜搜！应该有源码

TCP socket 80端口 send符合HTTP头＋HTML体的文本  用wireshark抓包软件抓一个显示最简单网页过程中的TCP包往来内容参考一下。


Question: ++*cp++

引用 5 楼 u012453424 的回复:[quote=引用 4 楼 derekrose 的回复:] [quote=引用 3 楼 u012453424 的回复:] [quote=引用 2 楼 derekrose 的回复:] 优先级就自己去查嘛~ 这不单单是优先级[/quote]  还涉及到什么？？[/quote] 见2楼[/quote]  2楼是我啊？你说1楼？1楼和优先级有什么区别？

引用 4 楼 derekrose 的回复:[quote=引用 3 楼 u012453424 的回复:] [quote=引用 2 楼 derekrose 的回复:] 优先级就自己去查嘛~ 这不单单是优先级[/quote]  还涉及到什么？？[/quote] 见2楼

引用 3 楼 u012453424 的回复:[quote=引用 2 楼 derekrose 的回复:] 优先级就自己去查嘛~ 这不单单是优先级[/quote]  还涉及到什么？？

引用 2 楼 derekrose 的回复:优先级就自己去查嘛~ 这不单单是优先级

优先级就自己去查嘛~

++(*(cp++)) =====================> ++*cp cp++