Question: txt文档显示在mini2440开发板上   急急急

我硬件开放方面并不熟，似乎 @anyidan 很熟，可以找下他。

引用 4 楼 Y_yueyueyue 的回复:我的开发板就是320*240的   然后每页是20*15个字    40*15个字符   m=i/40-15*x;//第几行,m 控制行   这个减号是什么意思呢 buff[120000]={0}   这个数组  我百度了    // 字符 40x15=600个ASC, 300个汉字       但是还是不懂 i是第几个字符/40,算出来第几行。 x=jj/600;一屏幕有600个字节40*15，x应当是页数的意思吧？ 行数，减去已经翻过的页数，得出应当是在当前屏幕的第几行。 应当是这个意思。  buff[120000]={0}   -------------------- 这个就是显示缓冲区吧，用来存储要显示的字符的。可以存储12W个字节。

路过。。。

你讲的都是正确的

引用 7 楼 Y_yueyueyue 的回复:非常感谢，已经帮我解答了这么多问题了，从没想过网友也这么乐于助人  。  嘿嘿嘿 ……    我会找@anyidan 的  ，希望他也想你这么热心 ，   嘿嘿嘿……

前面三句不用猜了吧？  m=i/40-15*x;//第几行,m 控制行 -------------------------- 一行40个字节，字符高度占15个像素？  j=16*m;// j换行 ---------------- 一行占16个像素，行与行之间有一个像素的空闲？  我大概只能猜这么多。

char buff[120000]={0}; n = fread(buff,1,120000,fp);//man  fread 	memset(tempbuf,0,sizeof(tempbuf)); 	x=jj/600; 	for(i=jj,k=0;i<jj+600;) 	{ 		m=i/40-15*x;//第几行,m 控制行 		j=16*m;// j换行 		if((i%40)==0)	 		k=0;	 //x坐标复位    能帮我解释下着段程序么

定宽字符： 屏幕的大小（总像素数-留白像素数）/单个字像素数=一屏的字数。 如果一行的宽度会有不完整的字，那么只取整数部分就可以。 变宽字符： 每个字所占的像素数累计。 一行一行计算。  翻页无非就是计算出现在显示到哪个字符了，然后下一页从哪个字符开始显示。


Question: 新手做题的时候有一个疑惑，希望各位能帮我解答

好的！！谢谢各位！！谢谢！！我会好好努力！

引用 3 楼 wangqing008 的回复:2,3楼正解啊+1

直接发代码不行吗，怎么又是发图片的

楼上都说了，楼主可以仔细阅读下相关书籍里关于scanf，printf这一类函数介绍，这种问题以后就不会犯了。scanf是会忽略空白字符（如空格，tab，'\n'等）的。像楼主程序中，它一直试图匹配'\n'，那肯定永远也匹配不了（因为看不见），它一直苦苦的找啊找啊，这时候来了一个非空白字符，它总算看到了，结果发现不是自己要找的，就结束寻觅了，把这玩意留给后面了。

scanf("%f",&r); 不要添加换行符。

2,3楼正解啊

scanf("%f\n",&r); 其中的\n和空格匹配多个空白符，所以要直到出现非空白符scanf才返回，继续执行之后的语句  正确的是 scanf("%f",&r);

吧 scanf中的 \n 去掉试试


Question: /lib/modules/3.11.0-15-generic/build is not configured

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

试试吧。我编译源代码，一般都是这个步骤 chmod -R 777 文件名 ./configure

root@ubuntu:/home/openvswitch-2.0.0# ./configure CC=gcc-4.2   checking for a BSD-compatible install... /usr/bin/install -c checking whether build environment is sane... yes checking for a thread-safe mkdir -p... /bin/mkdir -p checking for gawk... no checking for mawk... mawk checking whether make sets $(MAKE)... yes checking for gcc... gcc-4.2 checking whether the C compiler works... no configure: error: in `/home/openvswitch-2.0.0': configure: error: C compiler cannot create executables See `config.log' for more details   root@ubuntu:/home/openvswitch-2.0.0# dpkg -l gcc Desired=Unknown/Install/Remove/Purge/Hold | Status=Not/Inst/Conf-files/Unpacked/halF-conf/Half-inst/trig-aWait/Trig-pend |/ Err?=(none)/Reinst-required (Status,Err: uppercase=bad) ||/ Name                        Version                     Description +++-===========================-===========================-====================================================================== ii  gcc                         4:4.6.3-1ubuntu5            GNU C compiler   这是什么情况？


Question: 求高手 函数调用 跟传入值不一致 GDB

没有满意答案 结贴 给分

想知道是什么原理 导致了这样的错误

guint service_id  gint64 service_id  两种类型在内存中的表示方式不一样。改成一至的试下。同时检查A函数内部有没有改变这个参数值的代码

还有哪位能给出更详细的解释吗

gdb bug 更新至最新版

再猜测一下，你是没有前向声明gint A (gint64 service_id, GList **list, gboolean single)这个函数吧，导致调用该函数的时候，编译器默认为传递参数类型是int型的了，结果你取值用的是别的类型的方式，那值肯定就不对了

刚去验证了一下，打印地址出错的确就是上面说的那样。至于值不对，我这没发现

我猜测一下：部分参数传递只用到寄存器，并没有放入栈。所以你打印地址就会出错，因为寄存器没有地址


Question: 不知道创建链表的时候出现了什么问题，求指导

#include<stdio.h> #include<malloc.h> #define NULL 0 #define LEN sizeof(struct student) struct student { 	long num; 	char name[10]; 	char sex; 	int years; 	struct student *next; }; int n,m; struct student *creat() { 	struct student *head; 	struct student *p1,*p2; 	n=0; 	p1=p2=(struct student *)malloc(LEN); 	scanf("%d%s%c%d",&p1->num,p1->name,&p1->sex,&p1->years); 	head=NULL; 	while(p1->num!=0) 	{ 		n=n+1; 		if(n==1) 			head=p1; 		else 			p2->next=p1; 		p2=p1; 		p1=(struct student *)malloc(LEN); 		scanf("%d%s%c%d",&p1->num,p1->name,&p1->sex,&p1->years); 	} 	p2->next=NULL; 	return(head); } struct student *del_a(struct student *heada,int y) { 	struct student *pa1,*pa2,*head; 	head=heada; 	pa1=pa2=heada; 		while(y!=pa1->years&&pa1!=NULL) 		{ 			pa2=pa1; 			pa1=pa1->next; 		} 		if(y==pa1->years) 		{ 			if(pa1->next!=NULL) 			{ 				if(pa1==head) 				{ 					pa1=pa2=head=pa1->next; 				} 				else 				{ 					pa1=pa1->next; 					pa2->next=pa1; 				} 			} 			else 			{ 				if(pa1==head) 				{ 					head=NULL; 				} 				else 					pa2->next=pa1=NULL; 			} 			n--; 		} 	return(head); } void print(struct student *head) { 	struct student *p; 	printf("\nNow,These %d records are:\n",n); 	p=head; 	if(head!=NULL) 		do 		{ 			printf("%ld,%s,%c,%d\n",p->num,p->name,p->sex,p->years); 			p=p->next; 		}while(p!=NULL); } void main() { 	int y; 	struct student *qa; 	qa=creat(); 	print(qa); 	scanf("%d",&y); 	qa=del_a(qa,y); 	print(qa); }

引用 1 楼 user-1 的回复:倒数第二行，printf，少个f 其他的没看，，代码好乱 你发帖的时候有专门贴代码的地方的这是引用的一个函数


Question: [求助]char类型的数组在栈内存中的分配问题，请教一下大家

引用 4 楼 lin5161678 的回复:和入栈完全没关系   你这里定义的2个数组 唯一可以确定是只有  数组a 的内存绝对不会和 数组b 的内存发生任何形式的重叠  除此之外的包括 a在b之前 a在b之后 a和b直接有没有填充 a和b之间填充多少字节 都是不做任何保证 不做任何约束的   另外 内存对齐只是填充字节的理由之一  填充字节还有许多其他原由 包括不限于 检查是否读写越界的保护字节 为其他变量准备的字节 编译器作者的恶趣味 [就是老子高兴] ......  回答的深入浅出！应该是最对我胃口的答案了，感谢！

引用 3 楼 henry3695 的回复:  #include <stdio.h>  void abc(int a,int b,int c) { 	printf("a=0x%p\nb=0x%p\nc=0x%p\n",&a,&b,&c); } int main() { // 	char a[64]; // 	char b[64]; //  // 	printf("a[63] = %d \na[0]  = %d  \nb[63] = %d  \nb[0]  = %d\n", &a[63], a, &b[63], b);   	int a,b,c; 	abc(a,b,c); 	return 0; }  //楼主那个是在栈区分配内存，这个分配是随机的吧，就是随计算机系统来分配的，看到哪里有空的内存，他就给你分配一块 //所以两个数组不一定相邻的， //看下我写的例子，a,b,c的地址就是相邻的，楼主可以这样思考问题，必成大牛  看来函数内部的变量，只有入参是有入栈和出栈的操作的。  基础太薄弱，还有很多要学的，十分感谢！

引用 1 楼 user-7 的回复:引用按照入栈的顺序，a先入，b后入  但是为什么a[0]和b[63]之间相差了几个字节呢？应该也不存在内存对齐的问题啊？  这里没有入栈出栈哦。  相差多少都是可以的， 编译器有这个自由。  输出地址要用%p 学习了，看来以前我一直在概念上有错误。 为了理解这个小程序，我用vc把他弄成汇编的看了下，确实这种局部变量不是push和pop操作，而是系统直接在栈内申请内存。

输出地址应该用%p 下图是我运行程序输出的结果  a[63] 与 a[0] 相差3F转换成十进制也就是63，char是占用1个字节，而你数组长度也就是64个字节，所以并没有什么问题

怎么看都是输出从a[63]开始连续4字节中位置存放的一个int而不是输出&a[63]地址。  输出的内容和连续不连续有一毛钱关系吗？

学习了。。。。。

换成release版本的，就不会有疑问了，呵呵呵  别问细节，太基础了，要讲的东西太多

入栈的顺序也是不确定的。


Question: 求解释两段代码

无限制的死循环进入while（）之后C的值不会改变没法调出循环。

建议楼主要自己去调试调试，这问题马上就会发现了

看书还是要仔细的，字符串什么的最后必须以‘\0'结尾，不然类似strlen(s)，printf("%s\n",s)等等，都可能会出错，表面看上去没出错也只是随机情况。 #include <stdio.h>  int main() { 	int i =0, c; 	char s[10];  	while (i < 9){ 		while (c = getchar()){ 			while (c != '\n'){ 				while (c != EOF){    //因为c的值不会变化，一旦进入循环就是个死循环 					s[i] = c; 					i = i + 1; 				} 			} 		} 	} 	s[i] = '\0'; 	printf("%s", s);  	return 0; }

printf("%s", s);输出字符串就是一个'\0'为标识的，遇到‘\0’就停止输出。如果字符数组最后没有'\0'结束符，则printf会一直沿内存输出，直到遇到'\0'

引用 1 楼 lisong694767315 的回复: #include <stdio.h>   int main() {     int i =0, c;     char s[10];       while (i < 9){         if (c = getchar()){             if (c != '\n'){                 if (c != EOF){                     s[i] = c;                 }             }         } 	++i;     }     s[9] = '\0';     printf("%s", s);       return 0; }   s[9] = '\0';错了，应该是 s[i] = '\0';

第一段代码：里面三个while应该改成if条件判断，每次都要更新变量++i，字符数组最后应该添加'\0'结束符   #include <stdio.h>   int main() {     int i =0, c;     char s[10];       while (i < 9){         if (c = getchar()){             if (c != '\n'){                 if (c != EOF){                     s[i] = c;                 }             }         } 	++i;     }     s[9] = '\0';     printf("%s", s);       return 0; }


Question: 关于C语言中的【图】结构，遍历不出来，谁能帮帮我

买本书吧，一般书上都有。

都看到图了，还在新手乐园里发帖，肯定沉了，转分类吧

Hi Yuiliet   fishc有个关于数据结构的教学，其中就有图的介绍，里面讲解的还可以吧。 希望对你有所帮助。  http://blog.fishc.com/category/structure/page/5


Question: 关于带参宏的一个小问题。

引用 1 楼 Falleyes 的回复:应当避免在同一个表达式使用两次++，结果并不好预测。 宏尽量这样写： M(y) ((y)*(y)) 不是好不好预测的问题，这属于“未定义行为”，是有严重问题的代码

不要这么写，这表达式完全依赖编译器的实现，不同编译器可能有不同结果

引用 2 楼 dbzhang800 的回复:[quote=引用 1 楼 Falleyes 的回复:] 应当避免在同一个表达式使用两次++，结果并不好预测。 宏尽量这样写： M(y) ((y)*(y)) 不是好不好预测的问题，这属于“未定义行为”，是有严重问题的代码[/quote]我只是说的委婉点，上次看到一个帖也是这种问题，被喷得很惨。。。  楼主去看置顶帖吧！

只能作为一个题目来做做，实际开发写这种代码要挨骂

你的理解没有错， 编译器也是对的。 这是执行顺序不确定的代码。

对于有参数的宏，应该避免传入i++或者++i这样的表达式。 楼主不要拘泥于这种问题。几年后，你就会发现这种问题没有意义，因为我们会尽量避免这样写。


Question: MS dos cmd 如何 设置回滚行数

右键点菜单顶部  属性  选项  缓冲区大小  自己设置

设置高度值


自己顶顶.....

引用 3 楼 zxhuser-1 的回复:不要写连自己也预测不了结果的代码！  我觉得 我应该写得对的，但是就是没有勾到信息 代码如下： HOOK.dll：  #include "stdafx.h" #include <stdio.h>  HINSTANCE			g_hinstDLL = NULL; HHOOK				g_hHook = NULL;  BOOL APIENTRY DllMain( HMODULE hModule, DWORD  ul_reason_for_call, LPVOID lpReserved) { 	g_hinstDLL = hModule; 	switch (ul_reason_for_call) 	{ 	case DLL_PROCESS_ATTACH: 	case DLL_THREAD_ATTACH: 		break; 	case DLL_THREAD_DETACH: 	case DLL_PROCESS_DETACH: 		if(g_hHook != NULL) 				UnhookWindowsHookEx(g_hHook); 		break; 	} 	return TRUE; }  LRESULT CALLBACK WndPro(int nCode,WPARAM wParam,LPARAM lParam) { 	printf("1"); 	return CallNextHookEx(g_hHook,nCode,wParam,lParam); }   BOOL WINAPI StartHook() {  	if(g_hHook != NULL) 		return false;  	g_hHook = SetWindowsHookEx(WH_CALLWNDPROCRET, WndPro, g_hinstDLL, NULL);  	if(g_hHook == NULL) 		return false; 	return true; }  main.exe int _tmain(int argc, _TCHAR* argv[]) { 	if(StartHook()) 		printf("OK"); 	MSG msg; 	Sleep(2000); 	//::SendMessage(HWND_BROADCAST, WM_SYSCOMMAND, SC_MONITORPOWER, 2); 	while(GetMessage(&msg, NULL, 0, 0)) 	{ 		TranslateMessage(&msg); 		DispatchMessage(&msg); 	} 	return 0; }

不要写连自己也预测不了结果的代码！

引用 1 楼 zxhuser-1 的回复:http://bbs.csdn.net/topics/442464  这个也没有给出实例呀.... 我根据自己理解写了个HOOK，但是好像勾不到任何消息


Question: (type)和(type name)的区别是什么？

//C++ Operators //  Operators specify an evaluation to be performed on one of the following: //    One operand (unary operator) //    Two operands (binary operator) //    Three operands (ternary operator) //  The C++ language includes all C operators and adds several new operators. //  Table 1.1 lists the operators available in Microsoft C++. //  Operators follow a strict precedence which defines the evaluation order of //expressions containing these operators.  Operators associate with either the //expression on their left or the expression on their right;    this is called //“associativity.” Operators in the same group have equal precedence and are //evaluated left to right in an expression unless explicitly forced by a pair of //parentheses, ( ). //  Table 1.1 shows the precedence and associativity of C++ operators //  (from highest to lowest precedence). // //Table 1.1   C++ Operator Precedence and Associativity // The highest precedence level is at the top of the table. //+------------------+-----------------------------------------+---------------+ //| Operator         | Name or Meaning                         | Associativity | //+------------------+-----------------------------------------+---------------+ //| ::               | Scope resolution                        | None          | //| ::               | Global                                  | None          | //| [ ]              | Array subscript                         | Left to right | //| ( )              | Function call                           | Left to right | //| ( )              | Conversion                              | None          | //| .                | Member selection (object)               | Left to right | //| ->               | Member selection (pointer)              | Left to right | //| ++               | Postfix increment                       | None          | //| --               | Postfix decrement                       | None          | //| new              | Allocate object                         | None          | //| delete           | Deallocate object                       | None          | //| delete[ ]        | Deallocate object                       | None          | //| ++               | Prefix increment                        | None          | //| --               | Prefix decrement                        | None          | //| *                | Dereference                             | None          | //| &                | Address-of                              | None          | //| +                | Unary plus                              | None          | //| -                | Arithmetic negation (unary)             | None          | //| !                | Logical NOT                             | None          | //| ~                | Bitwise complement                      | None          | //| sizeof           | Size of object                          | None          | //| sizeof ( )       | Size of type                            | None          | //| typeid( )        | type name                               | None          | //| (type)           | Type cast (conversion)                  | Right to left | //| const_cast       | Type cast (conversion)                  | None          | //| dynamic_cast     | Type cast (conversion)                  | None          | //| reinterpret_cast | Type cast (conversion)                  | None          | //| static_cast      | Type cast (conversion)                  | None          | //| .*               | Apply pointer to class member (objects) | Left to right | //| ->*              | Dereference pointer to class member     | Left to right | //| *                | Multiplication                          | Left to right | //| /                | Division                                | Left to right | //| %                | Remainder (modulus)                     | Left to right | //| +                | Addition                                | Left to right | //| -                | Subtraction                             | Left to right | //| <<               | Left shift                              | Left to right | //| >>               | Right shift                             | Left to right | //| <                | Less than                               | Left to right | //| >                | Greater than                            | Left to right | //| <=               | Less than or equal to                   | Left to right | //| >=               | Greater than or equal to                | Left to right | //| ==               | Equality                                | Left to right | //| !=               | Inequality                              | Left to right | //| &                | Bitwise AND                             | Left to right | //| ^                | Bitwise exclusive OR                    | Left to right | //| |                | Bitwise OR                              | Left to right | //| &&               | Logical AND                             | Left to right | //| ||               | Logical OR                              | Left to right | //| e1?e2:e3         | Conditional                             | Right to left | //| =                | Assignment                              | Right to left | //| *=               | Multiplication assignment               | Right to left | //| /=               | Division assignment                     | Right to left | //| %=               | Modulus assignment                      | Right to left | //| +=               | Addition assignment                     | Right to left | //| -=               | Subtraction assignment                  | Right to left | //| <<=              | Left-shift assignment                   | Right to left | //| >>=              | Right-shift assignment                  | Right to left | //| &=               | Bitwise AND assignment                  | Right to left | //| |=               | Bitwise inclusive OR assignment         | Right to left | //| ^=               | Bitwise exclusive OR assignment         | Right to left | //| ,                | Comma                                   | Left to right | //+------------------+-----------------------------------------+---------------+

type name？？构造函数吧，也可以看作强制类型转换运算符，相当于调用构造那函数，进行强制类型转换

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


Question: 关于const 引用的一个疑问。

谢谢各位的解答。

引用 1 楼 lisong694767315 的回复:const int &refVal只是限定不能通过refVal去修改内存中的值，但是可以通过其他途径去改变内存中的值啊+1

第二个printf输出 100 100

如一楼说的。   #include <stdlib.h> #include <stdio.h>  int main(int argc, char** argv) {     int value = 10;     const int*p = &value;     printf("%d\n", *p);  // 10      int* q = &value;     *q = 100;     printf("%d %d\n", value, *p);     return 0; }

refVal 是引用，引用就是某一变量（目标）的一个别名，对引用的操作与对变量直接操作完全一样

引用 2 楼 bubbles_ 的回复:[quote=引用 1 楼 lisong694767315 的回复:] const int &refVal只是限定不能通过refVal去修改内存中的值，但是可以通过其他途径去改变内存中的值啊 是不是说，变量只是改变内存中的值的一种方式，如果这种方式被const修饰了，就不能用其再修改内存的值了。但是可以用其他指向这块内存的变量来修改内存的值？[/quote]  对的。

引用 1 楼 lisong694767315 的回复:const int &refVal只是限定不能通过refVal去修改内存中的值，但是可以通过其他途径去改变内存中的值啊 是不是说，变量只是改变内存中的值的一种方式，如果这种方式被const修饰了，就不能用其再修改内存的值了。但是可以用其他指向这块内存的变量来修改内存的值？


Question: 网络通信数据同步的问题

谢谢各位，问题已解决，多谢！

搜索" 生产者消费者问题"

可以搜一下“循环缓冲”

读写队列，，，如果是数据包，就分帧，，，前提是数据包，足够大，做下队满处理


Question: CreateFile找不到指定路径

引用 8 楼 lcg_1010 的回复:@go_and_see:我利用QueryDosDeviceA想获取C盘在全局名字空间下的路径，不是获取某一个文件的路径，我最终的目的是获取硬盘每个分区的容量，每个逻辑磁盘的容量。  那你不应该使用这个API，俺还以为你要在C盘下面创建一个文件呢。你要用这个GetDiskFreeSpaceEx，具体参数查MSDN吧。另外，你要是想通知俺，点引用即可，不用@

引用 9 楼 go_and_see 的回复:[quote=引用 8 楼 lcg_1010 的回复:] @go_and_see:我利用QueryDosDeviceA想获取C盘在全局名字空间下的路径，不是获取某一个文件的路径，我最终的目的是获取硬盘每个分区的容量，每个逻辑磁盘的容量。  那你不应该使用这个API，俺还以为你要在C盘下面创建一个文件呢。你要用这个GetDiskFreeSpaceEx，具体参数查MSDN吧。另外，你要是想通知俺，点引用即可，不用@  [/quote] 好的，知道了，才注册的csdn.

@go_and_see: 你说得很好，确实应该学会看MSDN，我当时的本意是“在CreateFileA函数中传递的第一个参数为调用QueryDosDeviceA函数的获得的路径呀！”，说话不严谨，原谅下

@haifeng3326: QueryDosDeviceA函数返回25，也就是cPath:"\\Device\\HarddiskVolume1",这个函数执行没有问题；

靠，少写了个斜杠。   QueryDosDeviceA( "C:\\test.txt", cPath, MAX_PATH );

引用 2 楼 lcg_1010 的回复:"\\Device\\HarddiskVolume1",关键是我调用QueryDosDeviceA函数成功了呀，而我在CreateFileA函数中传递的第一个参数为QueryDosDeviceA返回的路径呀！实在想不通！！！  你要学会看MSDN，注意返回值： If the function succeeds, the return value is the number of TCHARs stored into the buffer pointed to by lpTargetPath.  QueryDosDevice第一个参数应该这么写:  QueryDosDeviceA( "C:test.txt", cPath, MAX_PATH );

你看看QueryDosDeviceA( "C:", cPath, MAX_PATH );函数返回值是0吗

在CreateFileA那行设断点，看下cPath中的内容是什么


Question: 新人请教，不知道在创建链表时出现了无限循环

仅供参考//假设带表头结点的单向链表头指针为head，试编写一个算法将值为5的结点插入到连接表的第k个结点前，删除第k个节点，并对该链表进行排序。 #include <stdio.h> #include <stdlib.h> #include <malloc.h> #include <time.h> struct NODE {     int          data;     struct NODE *next; } H,*head,*p,*q,*s1,*s2,*s3,*s4,*s; int i,j,k,n,t,m; int main() {     srand(time(NULL));      //填写头节点数据     H.data=-1;     H.next=NULL;     head=&H;      //创建10个节点的单链表     p=head;     for (i=0;i<10;i++) {         q=(struct NODE *)malloc(sizeof(struct NODE));         if (NULL==q) return 1;         q->data=rand()%100;//填写0..99的随机值         q->next=NULL;         p->next=q;         p=q;     }      //输出整个单链表     s=head->next;     while (1) {         if (NULL==s) {             printf("\n");             break;         }         printf("%02d->",s->data);         s=s->next;     }      //将值为5的结点插入到单链表的第k个结点前     k=3;     n=0;     p=head;     while (1) {         if (NULL==p) {             break;         }         n++;         if (k==n) {             q=(struct NODE *)malloc(sizeof(struct NODE));             if (NULL==q) return 1;             q->data=5;             q->next=p->next;             p->next=q;             break;         }         p=p->next;     }      //输出整个单链表     s=head->next;     while (1) {         if (NULL==s) {             printf("\n");             break;         }         printf("%02d->",s->data);         s=s->next;     }      //删除第k个节点     k=5;     n=0;     p=head;     while (1) {         if (NULL==p) {             break;         }         n++;         if (k==n) {             q=p->next;             if (q) {                 p->next=q->next;                 free(q);             }             break;         }         p=p->next;     }      //输出整个单链表     s=head->next;     while (1) {         if (NULL==s) {             printf("\n");             break;         }         printf("%02d->",s->data);         s=s->next;     }      //从小到大排序     for (p=head;p!=NULL && p->next!=NULL;p=p->next) {         for (q=p->next;q!=NULL && q->next!=NULL;q=q->next) {             if (p->next->data > q->next->data) {                  //交换data //              printf("swap %02d %02d\n",p->next->data,q->next->data); //              t=p->next->data;p->next->data=q->next->data;q->next->data=t;                  //或者                  //交换next //              printf("swap %02d %02d\n",p->next->data,q->next->data);                 s1=p->next;                 s2=p->next->next;                 s3=q->next;                 s4=q->next->next;                  if (s2!=s3) {                      p->next=s3;                     s3->next=s2;                      q->next=s1;                     s1->next=s4;                 } else {                      p->next=s3;                     s3->next=s1;                            q=s3;                     s1->next=s4;                 }                  //输出整个单链表 //              s=head->next; //              while (1) { //                  if (NULL==s) { //                      printf("\n"); //                      break; //                  } //                  printf("%02d->",s->data); //                  s=s->next; //              } //              getchar();             }         }     }      //输出整个单链表     s=head->next;     while (1) {         if (NULL==s) {             printf("\n");             break;         }         printf("%02d->",s->data);         s=s->next;     }      //将单链表中前 m 个结点和后 n 个结点进行互换,m+n为链表总长10     m=4;     n=6;     k=0;     p=head;     while (1) {         if (NULL==p) {             break;         }         k++;         if (m+1==k) {             q=p;         }         s=p;         p=p->next;     }     s1=head->next;     head->next=q->next;     s->next=s1;     q->next=NULL;      //输出整个单链表     s=head->next;     while (1) {         if (NULL==s) {             printf("\n");             break;         }         printf("%02d->",s->data);         s=s->next;     }      //释放所有节点     p=head->next;     while (1) {         if (NULL==p) {             break;         }         q=p->next;         free(p);         p=q;     }      return 0; } //18->94->58->17->27->20->43->57->75->78-> //18->94->05->58->17->27->20->43->57->75->78-> //18->94->05->58->27->20->43->57->75->78-> //05->18->20->27->43->57->58->75->78->94-> //43->57->58->75->78->94->05->18->20->27-> //

引用 3 楼 lisong694767315 的回复:scanf("%ld%s%c%d",&p1->num,p1->name,&p1->sex,&p1->years); scanf的输入格式不要连着，要以空格或者逗号隔开:  scanf("%ld %s %c %d",&p1->num,p1->name,&p1->sex,&p1->years); // 或者 scanf("%ld,%s,%c,%d",&p1->num,p1->name,&p1->sex,&p1->years);   你相应的输入也要用空格或者逗号隔开 加了空格，确实问题没有了。但是请教一下，课本上scanf的输入格式是连着的，而且有时连着也是对的，想问一下原因。 	scanf("%d%s%d",&i,name,&m); 	printf("%d,%s,%d\n",i,name,m); 这样也是对的

这里有创建链表的范例 http://pan.baidu.com/s/17yIcQ

"%ld%s%c%d"加空格 "%ld %s %c %d" 输入时也得有空格

本想设置颜色，却出现了点问题，程序 struct student *creat() { 	struct student *head,*p1,*p2; 	p1=p2=(struct student *)malloc(LEN); 	scanf("%ld%s%c%d",&p1->num,p1->name,&p1->sex,&p1->years); 	printf("1\n"); 	n=0; 	head=NULL; 	while(p1->num!=0) 	{ 		//printf("1\n"); 		n=n+1; 		if(n==1) 			head=p1; 		else 			p2->next=p1; 		p2=p1; 		p1=(struct student *)malloc(LEN); 	//	printf("2\n"); 		scanf("%ld%s%c%d",&p1->num,p1->name,&p1->sex,&p1->years); 		printf("%d\n",n); 	} 	p2->next=NULL; 	return(head); }


Question: 杭电OJ 1020为什么错啊

引用 8 楼 zxh707wk 的回复:引用 7 楼 Falleyes 的回复:[quote=引用 6 楼 u012509810 的回复:] [quote=引用 5 楼 Falleyes 的回复:]这题目好像在哪见过ACM都很像的

引用 7 楼 Falleyes 的回复:[quote=引用 6 楼 u012509810 的回复:] [quote=引用 5 楼 Falleyes 的回复:] 这道题目的意思是要你把相同的字母序列变为数字加字母，比如AABAA，你应该输出2AB2A，而不是4AB。 按你说的我修改了代码通过了，话说题目里哪里说是这样的输出的呀？[/quote]  看这句： Each sub-string containing k same characters should be encoded to "kX" where "X" is the only character in this sub-string. 每一个截取的字符串包含k个一样的字符，把他替换成kX，而这里X是这段截取字符串中唯一一种字符。 所以要求2A，就必须是AA，4A就一定是AAAA。[/quote]这题目好像在哪见过

引用 6 楼 u012509810 的回复:[quote=引用 5 楼 Falleyes 的回复:] 这道题目的意思是要你把相同的字母序列变为数字加字母，比如AABAA，你应该输出2AB2A，而不是4AB。 按你说的我修改了代码通过了，话说题目里哪里说是这样的输出的呀？[/quote]  看这句： Each sub-string containing k same characters should be encoded to "kX" where "X" is the only character in this sub-string. 每一个截取的字符串包含k个一样的字符，把他替换成kX，而这里X是这段截取字符串中唯一一种字符。 所以要求2A，就必须是AA，4A就一定是AAAA。

引用 5 楼 Falleyes 的回复:这道题目的意思是要你把相同的字母序列变为数字加字母，比如AABAA，你应该输出2AB2A，而不是4AB。 按你说的我修改了代码通过了，话说题目里哪里说是这样的输出的呀？

引用 2 楼 lovesmiles 的回复: int find;     scanf("%d", &line);     getchar();  这里为什么还要getchar? 回收回车和空格

这是我当年的代码： #include<iostream> #include<string>  using namespace std;  void main() { 	int N; 	cin >> N; 	while (N--) 	{ 		string str; 		cin >> str;  		char a = str[0]; 		int num = 1;  		for (int i = 1; i<str.size(); i++) 		{ 			if (str[i] == str[i - 1])    //打印该元素之前的字母 				num++; 			else 			{ 				if (num == 1) 					cout << str[i - 1]; 				else 					cout << num << str[i - 1]; 				a = str[i]; 				num = 1; 			} 			if (i == str.size() - 1)    //最后一个元素 			{ 				if (num == 1) 					cout << str[i] << endl; 				else 					cout << num << str[i] << endl; 			} 		} 	} 	return; }

边界数据过不了或者其他数据过不去，编译通过只能说明你的代码在语法上没有错误，不代表在逻辑上也没有错误


Question: 求C语言大神关于即时输出的问题

已经解决，谢谢各位大神为我指点迷津，小弟在这里感激不尽

用共享内存的 程序1 #include <stdio.h> #include <stdlib.h> #include <string.h> #include <unistd.h> #include <sys/ipc.h> #include <sys/shm.h> #define KEY 12345 #define HAVE_ADDEND 1 #define NO_ADDEND 0  int main() { 	int a,b; 	int shmid; 	int *shmaddr;  	shmid = shmget((key_t)KEY,512,IPC_CREAT); 	shmaddr = (int *)shmat(shmid,NULL,0); 	memset(shmaddr,0,512); 	while(1) 	{ 		while(*shmaddr == NO_ADDEND) 		{ 			printf("please input addends:"); 			scanf("%d%d",&a,&b); 			*(shmaddr+1) = a; 			*(shmaddr+2) = b; 			*shmaddr = HAVE_ADDEND;	 		} 	} 	return 0; } 程序2 #include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <sys/ipc.h> #include <sys/shm.h> #define KEY 12345 #define HAVE_ADDEND 1 #define NO_ADDEND 0  int main() { 	int shmid; 	int *shmaddr;  	shmid = shmget((key_t)KEY,512,IPC_CREAT|0644); 	shmaddr = (int *)shmat(shmid,NULL,0); 	while(1) 	{ 		while(*shmaddr == HAVE_ADDEND) 		{ 			printf("sum = %d\n",*(shmaddr+1)+*(shmaddr+2)); 			*shmaddr = NO_ADDEND;	 		} 	} 	return 0; }

参考一下吧，把加数当参数通过exec函数传给第二个程序。 程序1 #include<stdio.h> #include<stdlib.h> #include<unistd.h> #define N 10 int main() { 	char a[N],b[N];  	printf("please input addends:"); 	scanf("%s%s",a,b); 	if(execl("/root/program2","program2",a,b,(char *)0) < 0) 	{ 		printf("exec error\n"); 		exit(1); 	} 	return 0; } 程序2 #include<stdio.h> #include <stdlib.h> int main(int argc,char *argv[]) { 	printf("sum = %d\n",atoi(argv[1])+atoi(argv[2])); 	return 0; }

直接在输入数据之后用system(程序名)函数不就行了吗？

//这是读管道文件 #include <stdio.h> #include <fcntl.h> #include <sys/types.h> #include <sys/stat.h> #include <errno.h> #include <string.h> #include <stdlib.h> #include <unistd.h>  #define PATH	"./fifo_buf" #define MAX		1024  int main() { 	int fd; 	char buf[MAX]; 	int fread;  	//打开管道 	fd = open(PATH, O_RDONLY, 0644); 	if (0 > fd) 	{ 		printf("open error!\n"); 		return -1; 	}  	while (1) 	{ 		memset(buf, 0, MAX);  		//从管道中读取数据 		if (0 > (fread = read(fd, buf, MAX))) 		{ 			printf("read error!\n"); 			return -1; 		}  		//quit退出 		if (0 == strncmp(buf, "quit", 4)) 		{ 			printf("read : %s\n", buf); 			break; 		}  		printf("read : %s\n", buf); 	}  	return 0; }   //这是写管道文件 #include <stdio.h> #include <fcntl.h> #include <sys/types.h> #include <sys/stat.h> #include <errno.h> #include <string.h> #include <stdlib.h> #include <unistd.h>  #define PATH	"./fifo_buf" #define MAX		1024  int main() { 	int fd; 	char buf[MAX]; 	int fwrite;  	//创建管道文件 	if ((0 > mkfifo(PATH, 0777)) && (errno != EEXIST)) 	{ 		printf("mkfifo error!\n"); 		return -1; 	}  	//打开管道文件，读写方式打开 	fd = open(PATH, O_RDWR | O_NONBLOCK, 0); 	if (0 > fd) 	{ 		printf("open error!\n"); 		return -1; 	}  	while (1) 	{ 		memset(buf, 0, MAX);  		printf("please enter:"); 		scanf("%[^1023\n]", buf); 		while(getchar() != '\n');  		//往管道中写入数据 		if (0 > (fwrite = write(fd, buf, MAX))) 		{ 			printf("write error!\n"); 			return -1; 		}  		//quit退出 		if (0 == strncmp(buf, "quit", 4)) 		{ 			close(fd); 			break; 		} 	}  	return 0; }    写的不好，希望理解。

能不能写个例子程序让我参考一下，我已经卡在这里2天了一点进展都没有。。。

多进程，加互斥锁

如果你要实现即时输出那只能通过这种互斥的机制来实现，因为你不可能对同一样东西进行两种操作，就像你取钱一样，不能一边打钱到你的卡上，一边从你的卡上取钱。而且这种同步互斥机智在C语言中很常见，而且运用也比较广泛，可以借这个机会学习一下。

用管道是不是编程很难啊？之前没学过，唉。。

可以用同步互斥的机制实现，一边写，另一边则等待，写的同时不能读，等到写结束后，另外一边才能读该文件。用管道可以，一边在管道中写入数据，一边在管道中读取数据。

是要重新编写一个程序来实现还是在程序里面加上fflush()?

你需要保证，你的第二个程序读文件的时候，你的第一个程序已经将 数据写进了文件！  fflush()

不要沉，不要沉


Question: 已知字符串形式的内存地址，求其在内存中的值（C实现）

事实上，类型只是给我们看，也可以说看编译器看，编译器根据每种类型的size作操作的。内存里的东西都是数字，int类型的内存是数字，字符串类型里的东西就不是数字？  你上面的语句printf("%s",*c);错就错在这个C本身是指针，然后你写了*C，*C就是将这个str内容的前4个字节的内存数值。当然这个数值也可以是一个指针，因为指针在内存中本身也是数字。那print出错是因为这个指针所指向的内存越界了。正确的应该是printf("%s",c);这样。

="0022114E"; 何必那么麻烦，字符串中的每个字符相对应：str[0]、str[1]、str[2]、str[3]……

引用 27 楼 crf_net 的回复:读取其他进程的内存地址，确认无解么？ 汇编可以实现么？ bool AdjustPrivileges() {     HANDLE hToken;     TOKEN_PRIVILEGES tp;     TOKEN_PRIVILEGES oldtp;     DWORD dwSize=sizeof(TOKEN_PRIVILEGES);     LUID luid;      if (!OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hToken)) {         if (GetLastError()==ERROR_CALL_NOT_IMPLEMENTED) return true;         else return false;     }     if (!LookupPrivilegeValue(NULL, SE_DEBUG_NAME, &luid)) {         CloseHandle(hToken);         return false;     }     ZeroMemory(&tp, sizeof(tp));     tp.PrivilegeCount=1;     tp.Privileges[0].Luid=luid;     tp.Privileges[0].Attributes=SE_PRIVILEGE_ENABLED;     /* Adjust Token Privileges */     if (!AdjustTokenPrivileges(hToken, FALSE, &tp, sizeof(TOKEN_PRIVILEGES), &oldtp, &dwSize)) {         CloseHandle(hToken);         return false;     }     // close handles     CloseHandle(hToken);     return true; } BOOL HackWriteProcessMemory(HANDLE hProc, void * pDest, void * pSource, DWORD nSize, DWORD * pWritten) {     MEMORY_BASIC_INFORMATION mbi;      if (!WriteProcessMemory(hProc,pDest,pSource,nSize,pWritten)) {         VirtualQueryEx(hProc,pDest, & mbi, sizeof(mbi));         #ifdef _DEBUG             printf("Info:addr=%08x,size=%08x,allocprot=%08x,currprot=%08x\n",mbi.BaseAddress,mbi.RegionSize,mbi.AllocationProtect,mbi.Protect);         #endif         if (VirtualProtectEx(hProc,mbi.BaseAddress, mbi.RegionSize, PAGE_READWRITE, & mbi.Protect)) {             if (!WriteProcessMemory(hProc,pDest,pSource,nSize,pWritten)) {                 #ifdef _DEBUG                     printf("Error:VirtualProtectEx succ,but WriteProcessMemory GetLastError=%d\n",GetLastError());                 #endif                 return FALSE;             } else {                 return TRUE;             }         } else {             #ifdef _DEBUG                 printf("Error:VirtualProtectEx GetLastError=%d\n",GetLastError());             #endif             return FALSE;         }     }     return TRUE; }

char *str="0022114E"; int addr; sscanf(str,"%x",&addr); printf("%02x",((unsigned char *)addr)[0]);   推荐使用WinHex软件查看硬盘或文件或内存中的原始字节内容。

引用 27 楼 crf_net 的回复:读取其他进程的内存地址，确认无解么？ 汇编可以实现么？ 去看看80x86保护模式吧，有助于你理解。

读取其他进程的内存地址，确认无解么？ 汇编可以实现么？

程序员写的程序都是面向逻辑地址的，你取的地址值肯定是在本进程的逻辑地址内部（当然该地址值必须是合理的），转换成物理地址之后也肯定在系统分给你的物理内存中，怎么样都不可能访问到别的进程的内存的。运行出错也只是因为你访问了你自己进程空间中系统规定不能访问的地方而已。

引用 10 楼 crf_net 的回复:根据内存地址，读取其他进程对应地址的内容不能实现？当然不可以！你没有其他进程的内存权限。都能访问别人的内存不就乱套了。

楼主要的是访问其他进程地址空间的内容，而且似乎他对系统API也不了解，大家都别在误导他了。不然讨论来讨论去都是当前进程空间，而1楼对此已经给出答案

不用API 除非是子进程，并且和主进程共享地址空间，，否则没有办法

1）把地址转换为指针对应的整型数据。。。即地址格式 2）调用API中的读写其他进程内存的读写函数，对其它进程的数据读写  对于 Windows 就是 ReadProcessMemory，WriteProcessMemory  3）可能有权限问题

引用int a=100; int *p; p=&a; printf("%d",*p); 肯定没问题 我不但知道这个没问题  我还知道 int a=100; int *p; p=&a; printf("%s",*p); 肯定有问题

引用 2 楼 crf_net 的回复:这个方式，可以骗过编译器，但是运行报错别逗  你给的地址如果是不可访问的  你用任何方式 都会运行出错  你给的地址可以访问 这样操作就OK  另外%s 输出一个 int 你是怎么想的 ??

你的是字符串，得转换成整形，再转为地址，然后给相应的指针p,然后*p

强转，然后给相应的指针p,然后*p不行吗？

int *c;   char *str="0022114E";   c=(int*)str;    printf("%s",*c); 编译没问题，运行报错！ 如果是： int a=100; int *p; p=&a; printf("%d",*p); 肯定没问题

这个方式，可以骗过编译器，但是运行报错

int n ; sscanf str %d &n 假设你想那这个地址存储的int 的值  *(int*)n 假设你想拿这个地址存储的char的值  *(char*)n

引用 20 楼 crf_net 的回复:你这里用了很多C++的东西，在C下编译不了。他没用什么C++的东西  倒是用了不少平台相关的东西  BYTE WINAPI LPCSTR

引用 15 楼 Sandrer 的回复:LPCSTR hex_table_a = "0123456789abcdef"; int _hexIndex(char pch) {     int index = 0;     for (int i = 0; i < 16; i++)     {         if (pch == hex_table_a[i])         {             index = i;             break;         }     }     return index; }  int WINAPI Hex2ByteA(LPCSTR pszHexString, BYTE *pDataBuffer, int nBufferSize) {     int nResult = 0;     while (*pszHexString)     {         if (nResult >= nBufferSize) break;          *pDataBuffer++ = ((_hexIndex(*(char *)(pszHexString++)) << 4) | \             _hexIndex(*(char *)(pszHexString++))) & 0xff;          nResult++;     }      return nResult; }  int main() {     char *p = "0022114E";     BYTE data[16];     Hex2ByteA(p, data, 16);     void *pData = (void *)data;      return 0; }  你这里用了很多C++的东西，在C下编译不了。


Question: 如何能扫描局域网内的IP

引用 2 楼 mrlgy 的回复:用套接字一个个的ping 不知道网上有没有用C编写的代码？想学习一下；

用套接字一个个的ping

首先得知道有哪些网段， 逐个ping这些网段，有回应就记下来。无回应就扔掉。

既然都提到文本框了，那么你肯定是用MFC框架了。 MFC里面有现成的类和函数可以使用，不用自己造了

你是用纯C还是MFC开发啊？如果是MFC有现成的。C语言就有点麻烦。

百度。。。


Question: wsprintf用法有疑惑?

这跟你工程选的字符集有关多字符或者是unicode下的有关

1、字符串前面加一个L表明是UNICODE字符 一般使用_T("")，在VC下  2、不加L，是在strTime为非宽字符，工程设置也为非UNICODE的情况下才能编译通过


Question: 求大神帮助如何合并两个c语言代码

C语言没有函数重载 有同名函数，把其中一些，重新命名。  没有同名函数，直接拷贝到一起就可以了。  其实，既然是不同的文件，只要函数命名无重复，完全没有必要合并。 需要使用哪些函数，就直接把对应的头文件，实现文件复制过去，就可以了  再不然，把这些文件， 放在一起链接生成动态库或者静态库，即可。  动态库：把动态库，和它的导入库，以及头文件交给用户，就可以用了。 静态库： 把静态库，和头文件交给用户，就可以用了。  另外，如果直接把算法写在main函数中， 基本上main改成一个有意义的名字就行了。  如果需要编译成可执行文件，并有多个main 保留一个就行了，其他main改名  在保留的那个main中按照需要， 调用其他已经改名的main函数即可。

引用 5 楼 liupeiran734562257 的回复:那大概是个什么方法？因为对c语言了解的不多，对于这种情况该如何处理？ 直接往一起粘贴就行了。

那大概是个什么方法？因为对c语言了解的不多，对于这种情况该如何处理？

引用 3 楼 liupeiran734562257 的回复:是有5个.h头文件，两个代码用的头文件都是相同的 直接动手做，遇到问题，看，修改就好了。

是有5个.h头文件，两个代码用的头文件都是相同的

头文件相同？一个头文件，两个实现文件？直接copy粘贴。

都有主函数？ 还书名有没有相同的？ 头文件都有防止重复包含的宏定义吧？ 如果基本上可以直接合并。


Question: 菜鸟请教一个问题

点击“生成”->清空项目->全部重新生成。然后按F5运行！！！！

引用 楼主 LarryKeNn 的回复:请教 在VS2010中编写C语言程序，出现这种情况是什么原因？求大神帮忙解决下！  看你这张图片，debug状态都没有进入，一看就知道 是直接拖exe文件入cmd窗口，然后回车运行。你这样直接拖文件入cmd窗口，它会自动加双引号，你这样是没有办法运行它的。

是设置的问题，你没看到路径的提示里有个双引号？和中文不中文无关

引用 9 楼 lovesmiles 的回复:[quote=引用 楼主 LarryKeNn 的回复:] 请教 在VS2010中编写C语言程序，出现这种情况是什么原因？求大神帮忙解决下！  看你这张图片，debug状态都没有进入，一看就知道 是直接拖exe文件入cmd窗口，然后回车运行。你这样直接拖文件入cmd窗口，它会自动加双引号，你这样是没有办法运行它的。[/quote]+1

引用 8 楼 lovesmiles 的回复:是设置的问题，你没看到路径的提示里有个双引号？和中文不中文无关+1

1、永远不使用中文路径； 2、代码风格需要修炼。

个人建议：不要出现中文路径

你这可能是格式问题！

拿分来吧。  你的VS2010可能不支持中文路径。

补充一点,scanf();  %d%d之间的逗号最好去掉, 不知道是不是问题所在, 但是这是一个不好的习惯..................我也是新手~

帮顶. 不是高手. 但是. 楼主的代码风格需要改..

问题补充

顺便说一下我的系统是64位的win7


Question: 进程检测问题

引用 1 楼 Oringe_new 的回复:申请共享内存  新进程创建了就往那里注册信息  父进程去那里爱干啥就干啥把 本人新手 ,不明白怎么获得后续的进程句柄 可能我没说清楚啊 ,是这样的B进程是另外一个应用程序的 ,我不清楚它是怎么工作的 ,但是A程序必须在其结束后进行某些工作 ,所以必须要知道B进程(包括其创建的进程)在什么时候停止的 显然B进程一停止A就要做出反应 ,要不B进程刚停下 ,这个程序又被打开了而且还使用如同刚才进程的PID会引发我不想见到的结果

申请共享内存  新进程创建了就往那里注册信息  父进程去那里爱干啥就干啥把


Question: w25x80 如何往下一块内写数据

addr 定义的是unsigned long


Question: 有没有谁有安装后不出问题的vc6.0 啊、、

引用 7 楼 Yuiliet 的回复:VC6.0++没有32和64位之分  一般win8不兼容VC6.0  win7使用VC6.0会有兼容性问题，忽略掉就行了。 如果是win7的问题，就详细点，可以帮你解决  XP不会有问题的 找个好点的资源点下载吧 引用 2 楼 TopBand 的回复:VS2010 比VC6好用多吧?  你出问题的是VC6的中文版吧?  英文版不会出问题的.我试试。。

引用 楼主 u014201928 的回复:初学者，，用vc2010感觉还是难了点，但网上下的vc6.0安装后都出问题，安在64位和32位上都有问题。。。哪个大神给我发个初学者试用的开发环境把 初学者更不应该选VC6了，太老，15年前的东西，而且与当前的C/C++标准格格不入。

如果是学生用的话足以： http://download.csdn.net/detail/zidane_2014/7689689

小一些的话用codeblocks就可以。

我写小程序一般用在线编译器： http://codepad.org/ 和http://ideone.com/

用 Code::Blocks 吧。。。


Question: 请教

嗯，是少了%，真为犯这样愚蠢的错误难过。。。 谢谢哈

少了% 改成这样： fscanf(fp1,"%f",&n);  或者这样： fscanf(fp1,"%lf",&n);


Question: 我不想要这个程序的某些功能，怎么改？

删代码

[quote=引用 3 楼 fanyue1989 的回复:] 在while(1)里面删除  Key_num=Read_Key();          //读出数据  同时把Key_arrange(Key_num,i); 的Key_num换成你想显示的数字。  没有用哦，还是一样的

看懂了就好改了，没看懂就是瞎改。

这个似乎较容易改，只要看懂了就可以。 一段段注释，一段段改。 看不懂的地方说出来，可以帮你说明。


Question: 新手求帮忙

输入的要用逗号隔开，因为你的scanf里面是用逗号

输入格式和定义的格式不一致

输入 1,45,5 而不是1 45 5再试试

#include <stdio.h> int main() { 	int a,b,c,t; 	printf("intput a,b,c:"); 	scanf("%d,%d,%d",&a,&b,&c); 	if(a<b) 	{ 		t=a; 		a=b; 		b=t; 	} 	if(a<c) 	{ 		t=a; 		a=c; 		c=t; 	} 	if(b<c) 	{ 		t=b; 		b=c; 		c=t; 	} 	printf("%d,%d,%d\n",a,b,c); 	return 0; }   输出：  intput a,b,c:1,45,5 45,5,1   输入需要用逗号隔开，而不是空格。

程序很简单，学会自己分析很重要。 可以跟踪一下，看看在哪里出的问题。 最简单的方法是，在每一步后面加上输出语句，看那一步变的不正常了。 还有就是，如果是VC的环境，F9设置断点，F5调试运行，F10单步跟踪。必须掌握的基本技能。 肯定可以查出问题的所在的。


Question: 路在何方？当个程序猿为什么这么难！！！

这位哥们： 这都能忍？果断换工作！  我们公司开发人员的标配是：ThinkPad W520/530/540  这位哥们的公司： 这都能忍？果断炒掉！  我们公司的开发人员用的VS有：VS 6.0/2002/2005/2008/2010

是好难。。。。

公司有问题，你也有问题 你们公司也太惨了吧，现在这个年代还给你个低配台式机用，还不能装机？这和公司大小已经没关系了，真正做技术的公司，再穷这点钱也是会出的吧。 还有，你自己没个笔记本吗，你看搞开发的有几个没有笔记本的，要是真没有那花点钱自己买个吧，买个次点的2000多也够你VS、KEIL这些软件用的了 还有工作进度非常缓慢这种事情，是自己努力不够，还是比较内向和同事没交流，还是这家公司根本不是真心搞开发以至于学不到东西，这得你自己找原因了

引用 8 楼 Zidane_2014 的回复:我现在读大二。在自学很多的东西。 有的时候遇到一个很小的问题都会弄很久。 但是最终能够解决掉问题。  虽然过程很艰苦，但是问题解决后真的很快乐。  我想说的是： 既然选择了自己的道路，就一直走下去吧。+1

不喜欢就换啦，退一步海阔天空

电脑作为生产资料，申请换一台也无可厚非。

现在就顶不住了以后要怎么做啊，自我感觉写程序确实是一件很麻烦的事

诚恳建议 去培训吧，如果资金略微开点的话。。不行的话，就慢慢搞吧，，需要耐着性子。。也是刚从SQA转过来的，，

总之，如果是自己选定的道路就一直走下去，别放弃，VC至今都没有装好还是把VC重新配置好，把和VC有关的一些软件全部卸载干净，然后重新装一遍，其次就是编程有很多平台与软件，自己要选定一个自己擅长的，这样不仅对编写代码的效率有帮助，而且不用花太多的精力去熟悉一个新的开发工具的快捷键之类的东西，至于要不要培训，这就得看自己所学的知识能不能满足社会的需求。最后就是200%的努力了。

引用 9 楼 call_from_dream 的回复:[quote=引用 3 楼 xiaohuh421 的回复:] 从你的问题来看, 就是因为一个VC++6.0,  编译平台出问题, 就让你想到这么多, 差不多就是求安尉, 决定是否跳了.  我觉得你何不向公司申请一台新电脑? 实在不行, 用自己的电脑也不是不可以的. 如果再不行, 你可以在公司电脑的其中一个盘中安装新系统.(多系统). 解决办法很多. 当一个人遇到问题: 如果想解决他, 那么会去想办法. 如果想逃避他, 那么会去找借口.我想，你误会了。安慰对问题的解决毫无帮助，我不需要，更不会去“求”。去向公司申请一台电脑？貌似你在你们公司很NB，可能“国情”不同吧，如果这么简单就能解决问题，我也不至于感觉有些迷茫了！公司的电脑配置很低，是那种老式台式机（没有光驱的那种，硬盘160G不到）。电脑里的资料不能随便动。 叉着腰，唾液横飞的话就免了。要来就来点实在！如果不想解决问题、逃避问题，我也不会向大家征求一些建议了！ [/quote]  这年月， 还为那点硬件所困，有些悲哀。。。 大胆说，实在不行自己看着办, 难道你想让网友或者微软给你开发专门的系统不成。。 要用微软的硬件必须上去， 乡间小道跑火车能成吗？？？？ 有公司这种技术需求， 不妨吃下苦，很学一下， 把C/C++ 学好， 就能混开了。。

原文传送门 很久以前电脑装的VC++6.0,最近心血来潮写了个程序，拿到里面去编译，可是报以下错误  不能启动工具. 操作成功完成。 不能启动工具. Error spawning 'vcspawn.exe'. The build could not be performed.  prg4_2.obj - 1 error(s), 0 warning(s)  还以为是程序有错误，可是怎么都查不出来，后来怀疑是VC++6.0本身的错误，就用以前运行过的正确程序编译了下，结果报同样的错误。  接着就上网查资料，可是按照网上说的除了重装没做，其他都做了，还是没用，特向csdn的高手请求帮助。谢谢  网上的处理资料：   症状 可能会生成应用程序从集成开发环境 (IDE) 失败, 并随后输出窗口中显示以下消息：  ' vcspawn.exe ' 生成错误。 无法执行生成。  消息不能识别为什么不能执行生成。  回到顶端  原因 有几个已知原因用于此消息： • 使用由 IDE 环境没有要搜索这些工具作为 Vcspawn.exe 正确目录。   • 正确定义 ComSpec 环境变量。   • 系统的 NULL 设备可能被禁用或缺少只 (Microsoft Windows NT)。   尽管所有这些都生成, 无法有效理由 VisualC++ 不提供足够信息来识别特定原因的故障或如何解决它。  回到顶端  解决方案 以下是四建议分辨率：  解析 1： 安装或启用 NULL 设备 （仅限于 WindowsNT） 有轻微变化显示错误文本上。 这些变化有时有助于确定是什么导致了问题。 如果错误文本类似以下, 可能必须打开 NULL 设备问题：  无法启动工具。 系统找不到指定文件。 系统找不到指定文件。 ' vcspawn.exe ' 生成错误。 无法执行生成。  使用下列步骤检查 NULL 设备上： 1. 从 控制面板 , 打开 设备 管理器。  2. 查找 Null 设备的设备列表中。 如果您没有 Null 设备, 必须重新安装 Null.sys。   3. Null 设备应显示状态 = Started 和启动 = 系统。   4. 以更正状态设置, 选择 Null 设备并单击 开始 。   5. 要纠正启动设置, 选择 Null 设备， 单击 启动 , 然后选择 系统 。    解决方案 2： 更正 IDE 环境 如果有下列错误文本变种, 可能有 ComSpec 定义或 IDE 环境, 指定哪里可以找到工具中错误：  无法启动工具。 成功完成操作。 无法启动工具。 ' vcspawn.exe ' 生成错误。 无法执行生成。  有关更正 ComSpec 定义信息请参见下面解析 4。 要纠正 IDE 环境： 1. 从 工具 菜单, 单击 选项 。  2. 单击 目录 选项卡, 并在 用于显示目录 , 选择 可执行文件 。  3. 应按此顺序列出以下五目录： 纠正目录列表指向有效目录：   a.  （您 VC 安装位置） \Common\MSDev98\Bin;   b.  （您 VC 安装位置） \VC98\BIN;  c.  （您 VC 安装位置） \Common\TOOLS;  d.  Windows 系统目录 （这通常是 C:\WINNT\system32   e.  Windows 目录 （通常是 C:\WINNT）     4. 通过双击其, 测试这些目录， 然后单击省略号 [ ]。 此外, 将目录复制到剪贴板。 然后, 在 开始 菜单上, 单击 运行 , 并在 打开 文本框中粘贴目录。 此方法应将备份 WindowsExplorer 与该目录。   5. 要添加新目录, 双击空框， 然后单击省略号 [ ]。   注意 "： … 目录包含 Vcspawn.exe 并且应该列表中第一个： " \MSDev98\Bin。    解决方案 3： 使用系统环境 另一种指定可执行路径为启动 MSDEV (Visual C++) 时使用 /USEENV 参数。 命令行类似以下内容： Msdev /USEENV  此操作强制 VisualC 用于系统环境设置而不在 工具 菜单 选项 中指定目录。 这有助于是否正确 ； 所有系统环境变量例如, 如果从命令提示符成功建立。   注意 ： 解析 2 通常建议通过使用 /USEENV 开关。 请有关, Service Pack 3 中已修复错误请单击下面的文章编号， 以查看 Microsoft 知识库中相应  216854 (http://support.microsoft.com/kb/216854/EN-US/) 一旦运行 msdev / useenv 使环境用于永久 FIX：  更正 ComSpec 环境变量定义解决方案 4： 如果路径查找正确 （参见解析 2）, 问题可能与 ComSpec 环境变量。 ComSpec 环境变量标识执行命令提示符。 WindowsNT, 上这通常如下所示： ComSpec=C:\WINNT\system32\cmd.exe  在 Windows 95 或 Windows 98, 它通常如下所示： ComSpec=C:\Windows\COMMAND.COM  要检查, 设置, 或者更改 ComSpec 环境变量的值： • 在 WindowsNT：1. 从 开始 菜单, 指向 设置 , 然后单击 控制面板 。  2. 双击 系统 图标 （此操作显示所有现有环境变量和值）。   3. 添加或修改 ComSpec 变量, 必要。     • 在 Windows9x x：1. 从 MS-DOS 提示符, 输入 set ComSpec . 此操作或者显示 ComSpec 环境变量或未定义 " 环境变量 ComSpec " 的当前值。   2. 编辑 Autoexec.bat 文件以修改或添加到系统必要 ComSpec。      回到顶端  状态 Microsoft 已确认这是 " 适用于 " 一节中列出 Microsoft 产品中存在问题。  此问题已得到解决 Microsoft VisualC++.NET 中。  回到顶端  参考 有关详细信息, 请单击下列文章编号， 查看 Microsoft 知识库文章中文章：  189138 (http://support.microsoft.com/kb/189138/) PRB： " 错误 spawning empfile.exe " 生成 WINCE 应用  188720 (http://support.microsoft.com/kb/188720/) PRB： 错误执行 ~ 编译 vcecho !

什么系统?  win7装vc6可能会有问题, XP偶尔也会有问题. 不要着急,找个有经验的帮你看看

哈哈 今天 和 老总谈了一下  果断 买 新电脑了  没人 两台 台式机

首先说明一下，我不是过来人，只是个正在学习的人 不能换编译器吗？C-Free或Dev C++什么的？

装了那些绿色版的 或者精简版的vc6了吧

引用 12 楼 xiaohuh421 的回复:U盘装系统.  160盘已经不小了. XP也只占不了10G吧. 如果这电脑20G空闲空间都没有,  那只能说呵呵了.  现在换一台普通电脑, 也就2,3千的样子吧 我不信哪个公司连这点钱都没有. 因为这已经影响到工作, 申请换并不是过分的要求, 如果真的是2,3K都不愿意出的公司, 那还是换吧.  非要把宝贵的时候,浪费在整编译环境上, 我觉得不值.好吧！晋惠帝听说饥民没饭吃，问大臣，为什么他们不喝肉粥。。。不过，还是谢谢你的回复了

4K,自己买一台手提电脑不舍得？

引用 9 楼 call_from_dream 的回复:[quote=引用 3 楼 xiaohuh421 的回复:] 从你的问题来看, 就是因为一个VC++6.0,  编译平台出问题, 就让你想到这么多, 差不多就是求安尉, 决定是否跳了.  我觉得你何不向公司申请一台新电脑? 实在不行, 用自己的电脑也不是不可以的. 如果再不行, 你可以在公司电脑的其中一个盘中安装新系统.(多系统). 解决办法很多. 当一个人遇到问题: 如果想解决他, 那么会去想办法. 如果想逃避他, 那么会去找借口.我想，你误会了。安慰对问题的解决毫无帮助，我不需要，更不会去“求”。去向公司申请一台电脑？貌似你在你们公司很NB，可能“国情”不同吧，如果这么简单就能解决问题，我也不至于感觉有些迷茫了！公司的电脑配置很低，是那种老式台式机（没有光驱的那种，硬盘160G不到）。电脑里的资料不能随便动。 叉着腰，唾液横飞的话就免了。要来就来点实在！如果不想解决问题、逃避问题，我也不会向大家征求一些建议了！ [/quote] 话说我个人用的电脑还是256+512内存，40G硬盘的，没有光驱的电脑。老掉牙的机器了。 公司的电脑比我的电脑好很多。。。

引用 7 楼 call_from_dream 的回复:引用 6 楼 zjq9931 的回复:[quote=引用 5 楼 call_from_dream 的回复:] [quote=引用 1 楼 zjq9931 的回复:] 修复系统，再重装VC。可以具体点儿吗？ 用系统盘，安装（不是克隆盘，是安装盘），安装的时候选择修复。[/quote] 老式的台式机，没有光驱[/quote] 没光驱，装个虚拟光驱，然后下个IOS文件，把安装文件拷贝出来放在硬盘上也是可以安装的。


Question: C初学者，请问什么前提下可以用递归啊？麻烦说得通俗点，谢谢了

...这问题问的，实现某算法时不知不觉就考虑了递归的时候用！什么前提用？没具体应用哪来的前提？ 并不是刻意去用的。

引用 楼主 lankun1234 的回复:第一次发帖，我看过有邀请回复，我随便点的，如果打扰到你了，不好意思啊 个人建议是，任何情况下都不应该首先考虑递归  写的时候不容易保证递归的逻辑完整性，出了bug查bug又不好查，而且运行中可能会遭遇内存不足的问题，比如内核空间。并且cpu的执行逻辑是先后顺序的，代码表现上并不贴合这一特性，导致阅读代码费事，反正linux内核代码我是没见过递归

打印二叉树，文件夹中所有文件都可以

引用 4 楼 mujiok2003 的回复:[quote=引用 2 楼 lisong694767315 的回复:] 递归一般具有很好的可读性和可维护性，但是大部分情况下效率都很低。所以如果用非递归不是很复杂的话，就尽量不要用递归。 尾递归一搬于迭代同样高效。 非尾递归都可以改写成尾递归。 非尾递归函数， 注意避免栈溢出就好。 [/quote]+1,没特别要求就别用递归

引用 2 楼 lisong694767315 的回复:递归一般具有很好的可读性和可维护性，但是大部分情况下效率都很低。所以如果用非递归不是很复杂的话，就尽量不要用递归。 尾递归一搬于迭代同样高效。 非尾递归都可以改写成尾递归。 非尾递归函数， 注意避免栈溢出就好。

支持2楼，能写成迭代形式就写成迭代。 递归效率低，甚至会出现栈溢出的情况

引用 15 楼 cfvmario 的回复:[quote=引用 12 楼 zjq9931 的回复:] [quote=引用 11 楼 zjq9931 的回复:] 感觉这种情况下要用。递归。 遍历文件夹下的所有子文件夹。 补充一下，除了递归其他的方法似乎都不太好。[/quote] 用队列不就行了。一开始队列就放一个根目录，每次都是访问队列头指向的目录，然后把所有子目录压进队列[/quote] 队列是可以，但这里是C语言区，所以，我就说这个要递归了^_^ 队列是模拟了递归压栈出栈的操作^_^，而且更节省资源消耗。 换成循环的资源消耗就少了。

应该这么说，比如上面说的子目录问题，是“思想上”使用递归。 递归应该尽量只在思想中用。很多算法思想是递归的，但在具体实现的时候尽量使用其非递归方式。 当然，个别问题确实不容易转换成非递归，比如汉诺塔。。汉诺塔有循环算法，但是那循环算法和递归的思想基本可以说没关系，而且一般人极难想到。。那另当别论

引用 12 楼 zjq9931 的回复:[quote=引用 11 楼 zjq9931 的回复:] 感觉这种情况下要用。递归。 遍历文件夹下的所有子文件夹。 补充一下，除了递归其他的方法似乎都不太好。[/quote] 用队列不就行了。一开始队列就放一个根目录，每次都是访问队列头指向的目录，然后把所有子目录压进队列

在一个文件目录下面搜索一个文件，基本上会想到用递归去遍历这些目录

搞算法研究的时候可以用递归 对性能无要求，内存无限大可以用递归 一般少用递归，出了问题你都不知道找谁哭去

引用 11 楼 zjq9931 的回复:感觉这种情况下要用。递归。 遍历文件夹下的所有子文件夹。 补充一下，除了递归其他的方法似乎都不太好。

感觉这种情况下要用。递归。 遍历文件夹下的所有子文件夹。

数据结构在心中，看到要实现的功能时，就会想到用什么来实现~我觉得一般是特别清晰特别了解才会用吧。

不熟悉的情况下完全不用

能使用数学归纳法的，可以用递归


Question: 文件指针使用问题

你要往文件写东西，为什么以只读的方式打开文件呢？应该以w或w+模式打开：   fp=fopen("E:\\nihao.txt","w");

改好了，但变量窗口中fp指针中ptr，cnt会显示错误指针


Question: 关于结构体的初始化问题

引用 2 楼 whw_sirius 的回复:GPIO_Pin_3 和 GPIO_Pin_6应该是定义的宏吧， 全局变量没有初始化，自动初始化为零，这句就是个 位操作，应该是将3位和6位设为1的赋值操作。  的确，经过上面那位的讲解明白了 是将第三引脚和第六引脚的地址值进行或运算后作为初始化参数代入初始化函数。  但还是没搞懂为什么或一下就可以把这两个引脚都初始化了。。。感谢！我再看看底层

GPIO_Pin_3 | GPIO_Pin_6应该是按位或吧


Question: 关于内存池感觉网上资料好乱，内存分配和释放的问题，求大神指教（分不多了）

这是一个内存池，仅供参考

引用 4 楼 truexf 的回复:个人认为，内存池不存在通用解决方案，他只适用于特定的应用环境。这些环境都有对内存频繁申请和释放的情况。 而且用malloc处理做内存池也不一定靠谱，因为malloc分配的是虚拟内存，操作系统啥时候把他交换到磁盘你不能控制。 而应该用操作系统本身提供的api函数，来管理内存池，以便你可以控制内存不被交换出去。  各方实现c运行库的malloc和free函数本身就支持了一定的内存池功能。我个人倾向于直接增加内存条简单有效低成本来解决问题。这类情况一般多是64位的服务器系统。  不合理的内存池方案，导致物理内存块长期锁定，反而可能造成更大的内存碎片。操作系统一定比ring3层的应用程序更懂硬件，更懂内存管理。谢谢啊，想练练手，可能是好高骛远了。。。。基础有待加强

人真少啊，自己顶

预分配大内存给程序使用 降低在运行的时候频繁跟系统申请内存造成的碎片 影响效能


Question: 求更快的算法～

引用 12 楼 lin5161678 的回复:[quote=引用 8 楼 lovesmiles 的回复:] 你这样是不行的，abc不符合，不代表abd不符合，abd如果符合，一定比bcd长。你的算法根本求不到最优解。 abc不符合就是说条件  b+c > a 不成立  而 c比d 大的情况下  b+d >a 绝对不会成立  所以 c后面的任何数字 和ab组合都绝对不可能完成三角形  我这么说你能理解吗?[/quote]  有道理，是我没有考虑清楚。

我理解错了，忘记两边长和不能小于第三边

引用 2 楼 lnetant 的回复:出这题目的是不是脑袋被驴踢了？ 三角形周长=三边之和吧？ 你的输入已经是逆序了吧？ 直接取前三位最大的数字不就可以了？干吗还去计算？  小学数学是体育老师教的？随便三条边就能组成三角形吗？

唉。。2楼小学数学老师。。

排序法 	最差时间分析 	平均时间复杂度 	稳定度 	空间复杂度 冒泡排序 	O(n2) 	O(n2) 	稳定 	O(1) 快速排序 	O(n2) 	O(n*log2n) 	不稳定 	O(log2n)~O(n) 选择排序 	O(n2) 	O(n2) 	稳定 	O(1) 二叉树排序 	O(n2) 	O(n*log2n) 	不一顶 	O(n)  插入排序 	O(n2) 	O(n2) 	稳定 	O(1) 堆排序 	O(n*log2n) 	O(n*log2n) 	不稳定 	O(1) 希尔排序 	O 	O 	不稳定 	O(1)

引用 13 楼 lin5161678 的回复:[quote=引用 11 楼 benma378 的回复:] 麻烦看一下第二种算法，貌似有点类似。但时间复杂度不是O（n）这样的算法是O(n)的   其实就是扫描了数组元素个数-2  不管数组规模如何  这个算法都是 N-2 次循环 [/quote]  好像还真是，我这里没有细想了。。。。  加上数组排序需要nlogn  那我就找到了合适的算法了  谢谢！

引用 11 楼 benma378 的回复:麻烦看一下第二种算法，貌似有点类似。但时间复杂度不是O（n）这样的算法是O(n)的   其实就是扫描了数组元素个数-2  不管数组规模如何  这个算法都是 N-2 次循环

引用 8 楼 lovesmiles 的回复:你这样是不行的，abc不符合，不代表abd不符合，abd如果符合，一定比bcd长。你的算法根本求不到最优解。 abc不符合就是说条件  b+c > a 不成立  而 c比d 大的情况下  b+d >a 绝对不会成立  所以 c后面的任何数字 和ab组合都绝对不可能完成三角形  我这么说你能理解吗?

引用 7 楼 lin5161678 的回复:对于已经逆序的序列 abcdef 你可以测试 abc  可以组成三角形就输出 a+b+c 不行就测试 bcd  可以输出三角形就输出 b+c+d ........ 一直测到def  这是On 复杂度   麻烦看一下第二种算法，貌似有点类似。但时间复杂度不是O（n）

引用 1 楼 shucheng36 的回复:贪心嘛，可以这样，先排序 假设顺序排序后的数组为array[N] 那么 1. 从数组最后一个元素开始(下标为tail = N - 1) 2. 比较 array[tail - 2] + array[tail - 1] 与 array[tail]  3. 如果前者小于或等于后者，tail--; 重复步骤2 4. 如果前者大于后者，算法完成，array[tail - 2], array[tail - 1], array[tail] 就是结果  排序的复杂度可以做到O(nlogn)，后面这些步骤的复杂度是O(n)  你的思路感觉跟我的一样，这样的算法复杂度不是O（n）吧。。。。

引用 1 楼 shucheng36 的回复:贪心嘛，可以这样，先排序 假设顺序排序后的数组为array[N] 那么 1. 从数组最后一个元素开始(下标为tail = N - 1) 2. 比较 array[tail - 2] + array[tail - 1] 与 array[tail]  3. 如果前者小于或等于后者，tail--; 重复步骤2 4. 如果前者大于后者，算法完成，array[tail - 2], array[tail - 1], array[tail] 就是结果  排序的复杂度可以做到O(nlogn)，后面这些步骤的复杂度是O(n)二楼的数学老师。。。

引用 7 楼 lin5161678 的回复:对于已经逆序的序列 abcdef 你可以测试 abc  可以组成三角形就输出 a+b+c 不行就测试 bcd  可以输出三角形就输出 b+c+d ........ 一直测到def  这是On 复杂度 你这样是不行的，abc不符合，不代表abd不符合，abd如果符合，一定比bcd长。你的算法根本求不到最优解。


Question: 算数运算符

后半句不用管  前半句，你把除数和被除数正负号都试试，就4种情况，很容易的  具体机子具体说，你也不用管，在你机子上正常就行，一般问题不大

不管是取决于机器架构还是编译器，总之一句话，结果不确定。 理论上讲，这个可以和机器架构有关，比如不同CPU的div指令在有负数的时候行为可以不同。实际应该主要是取决于编译器。 不过纠结这个没什么意义吧。总之结果不确定，编程的时候不要依赖于它的结果就行了

路过。。。

引用 楼主 moyac 的回复:　　“在有负操作数的情况下,整数除法截取的方向及取模运算结果的符号取决于具体机器的，这和处理上溢和下溢的情况是一样的。”——取自《The C programming Language》。 　　能详细地解释一下这段话吗，不太明白。 取决于具体机器，这个感觉有点不合适的，个人感觉应当是区别于具体的操作系统，编译器。 因为64位的机器也可以运行32位的编译器。当然我说的是应用级别的软件。不是系统级别的软件。 完全个人感觉，请高手指正。


Question: 小白求助啊 为什么结果一直是1..

输入double变量时，必须使用%lf，输出时倒是可以用%f，不过在这里最好不要让输入变量是浮点数（因为存储不精确），可以改用int变量，示例如下 # include <stdio.h>  int main(void) { 	int n, i; 	double sum = 0.0, sign = 1.0; 	printf("please enter a number:\n"); 	scanf("%d", &n);   	for (i=1; i<=n; i++) 	{ 		sum += sign/i; 		sign = -sign; 	} 	printf("the sum=%f\n",sum); 	 	return 0; }

引用 2 楼 shayne000 的回复:想输入n，得出1-1/2+1/3-1/4+1/5........1/n #include<iostream> #include<math.h> using namespace std;  int main() {     int n;     cout << "input n = " ;     cin >> n;     cout << endl;     int i = 1;     double sum = 0.0;     while (i <= n)     {           sum = sum + pow(-1, i + 1)/i;           i++;     }     cout << "The sum is:" << sum << endl;     system("pause");     return 0; }

#include<stdio.h> int main() { 	double a,b,c,d,sum; 	printf("please enter a number:\n"); 	scanf("%lf",&c);        //此处改为%lf 	a=1.0;b=1.0;sum=1.0; 	while(a<c) 	{ 		a=a+1; 		b=-b; 		d=b/a; 		sum=sum+d; 	} 	printf("the sum=%f\n",sum); 	return 0; }

引用 5 楼 Falleyes 的回复:好吧，现在图片能看了，改scanf语句： scanf("%lf",&c); 如果你使用float精度，用%f没问题，double的话，要用lf%  ++

scanf的格式问题,使用%lf

int main() { 	double sum = 0; 	int i,n; 	scanf("%d",&n); 	for(i=1; i<=n; ++i) 	{ 		if(i%2 == 0) 			sum -= (double)1/i; 		else 			sum += (double)1/i; 	} 	printf("The sum is: %f\n", sum); 	return 0; }

图片看不了，估计问题在数据类型。 两个整形相除的结果是把小数点后全部去掉啊，比如1/2是0. 你应该这么写，比如n是分母，依次递增，那你应该改成1.0/n，或者1/(double)n.

谢谢各位啦

为什么结果一直是1 啊


Question: 如何清空标准输入流？

#include <stdio.h> #include <windows.h> #include <conio.h> int main() {   	Sleep(5000); 	while(_kbhit()) 	{ 		_getch(); 	}  	_getch();     return 0; }   kbhit和getch的下划线是否添加，取决于你的编译器。

getch不是标准输出入函数，不想按回车的，system("pause")吧...

引用 3 楼 user-4 的回复:cin.clear(); cin.sync(); 可以结贴了。c的好不好。。。

cin.clear(); cin.sync(); 可以结贴了。

引用 1 楼 zxh707wk 的回复:第三个注释是这个while((ch=getchar())!='\n'&&ch!=EOF);  不要纠结这个 我调试代码的时候也是写的\n 为了发这个帖子 我在网上现粘贴的！


Question: 堆排序 比 快排 快很多？

引用 6 楼 lisong694767315 的回复:[quote=引用 4 楼 Falleyes 的回复:] 二楼的表就很说明问题，快排是不稳定排序，而堆排序是稳定排序。   堆排序是不稳定的[/quote]  哦，没有表述清楚，是性能稳定。

堆排序 比 快排 快很多？ 如果单单说那个更快一些这个 不能直接比较的。  堆排序性能稳定，但是操作指令跟排序处理时间开消要比快速排序高， 虽然 时间复杂度 堆排序 nlogn  快排 n*n  所以一般数据量小 建议用快排， 数据量大了  用堆排， 楼主可以了解下 stl sort 函数的机制，  或者是看看 算法导论线性排序。

引用 4 楼 Falleyes 的回复:二楼的表就很说明问题，快排是不稳定排序，而堆排序是稳定排序。   堆排序是不稳定的

楼上说了这么多，不解释了。。。

二楼的表就很说明问题，快排是不稳定排序，而堆排序是稳定排序。

T(N) =O(f(n)) 的含义是 T(N) <= c * f(n);  快排 ,常数项c比较小。  相对的，堆排序常数项c比较大。 所以，实用上，块排比堆排序要快。  理论上：  引用 1 楼 lisong694767315 的回复:堆排序 最好情况、平均情况、最坏情况都是nlogn； 快排 最好情况、平均情况为nlogn，最坏情况为n^2； ++


Question: 如何高效地判断两个数是否有一个等于0

引用 46 楼 JLU_Leven 的回复:[quote=引用 45 楼 zhao4zhong1 的回复:] [quote=引用 30 楼 hjgzj 的回复:] 可惜没赵老师的模版 理解和讨论之前请先学会如何观察！  对学习编程者的忠告： 眼过千遍不如手过一遍！ 书看千行不如手敲一行！ 手敲千行不如单步一行！ 单步源代码千行不如单步Debug版对应汇编一行！ 单步Debug版对应汇编千行不如单步Release版对应汇编一行！  无profiler不要谈效率！！尤其在这个云计算、虚拟机、模拟器、CUDA、多核 、多级cache、指令流水线、多种存储介质、……满天飞的时代！  [/quote] profiler是什么东东[/quote] VC6：   Articles That Tell About Performance Tuning Home |  Overview |  How Do I  Feature Only in Professional and Enterprise Editions   Profiling is supported only in Visual C++ Professional and Enterprise Editions. For more information, see Visual C++ Editions.  The profiler-related articles are as follows:   PREP   PROFILE   PLIST   Profiler Won't Merge Statistics from Two Different Operating Systems on the Same Computer   Profiler Will Not Profile DLLs That Are Freed, Then Reloaded   Onboard System Memory Cache and Disk Caches May Affect Profile Times   Profiling Windows NT Services   Error Writing to .PDB File After Line Profile Operation   PRB: Profiler Fatal Errors PRF1012 and PRF1306   VS 20XX：  全部折叠全部展开      代码：全部 代码：多个 代码：Visual Basic 代码：C# 代码：Visual C++ 代码：J# 代码：JScript   Visual Basic C# Visual C++ J# JScript Visual Studio Team System  使用分析工具对应用程序性能进行分析  请参见  发送反馈意见     使用 Visual Studio Team Edition for Developers 中的性能工具，开发人员可以测量和评估代码中的性能相关问题，并以这些问题作为目标。这些工具与集成开发环境完全 (IDE) 全面集成，提供无缝的用户体验。性能工具支持两种分析方法，即取样和检测。  分析应用程序的过程非常简单。首先，创建一个新的性能会话。在 Visual Studio Team Edition for Developers 中，可以使用性能会话向导创建新的性能会话。性能会话结束后，分析过程中收集的数据将保存到 .vsp 文件中。可以在 IDE 中查看 .vsp 文件。有几个报告视图用于根据收集的数据可视化和检测性能问题。  通过命令行可以使用性能工具。因此，用户可以灵活选择是从命令行运行这些工具，还是使用它们自动完成使用脚本的任务。  有关与性能和分析相关的当前/高级主题的更多信息，请搜索 Microsoft Developer Network 以获取主题和 Microsoft 博客。使用关键字 Enterprise Performance Tools Team。  本节内容 分析工具入门  了解当您使用分析工具收集、查看和分析代码性能时要应用的概念和任务。  常见任务（分析工具）  了解如何使用性能工具为不同类型的应用程序创建性能会话和收集性能数据。  高级任务（分析工具）  了解如何使用分析工具收集有关复杂或困难情况的性能数据。  查看分析工具报告  了解如何查看性能数据以检测问题。  演练：分析应用程序  通过分析样本应用程序来获得实际体验。  命令行分析工具  了解如何从命令行提示符下使用性能工具。  请参见 其他资源 MSDN Online 发送反馈意见，就此主题向 Microsoft 发送反馈意见。

引用 30 楼 hjgzj 的回复:可惜没赵老师的模版 理解和讨论之前请先学会如何观察！  对学习编程者的忠告： 眼过千遍不如手过一遍！ 书看千行不如手敲一行！ 手敲千行不如单步一行！ 单步源代码千行不如单步Debug版对应汇编一行！ 单步Debug版对应汇编千行不如单步Release版对应汇编一行！  无profiler不要谈效率！！尤其在这个云计算、虚拟机、模拟器、CUDA、多核 、多级cache、指令流水线、多种存储介质、……满天飞的时代！

引用 43 楼 angel_su 的回复:貌似这个效率可以无视，即便a*b真的快点，换来bug得不偿失... if (65536*65536 == 0) why is true ? 我说了*会溢出，不可取

引用 45 楼 zhao4zhong1 的回复:[quote=引用 30 楼 hjgzj 的回复:] 可惜没赵老师的模版 理解和讨论之前请先学会如何观察！  对学习编程者的忠告： 眼过千遍不如手过一遍！ 书看千行不如手敲一行！ 手敲千行不如单步一行！ 单步源代码千行不如单步Debug版对应汇编一行！ 单步Debug版对应汇编千行不如单步Release版对应汇编一行！  无profiler不要谈效率！！尤其在这个云计算、虚拟机、模拟器、CUDA、多核 、多级cache、指令流水线、多种存储介质、……满天飞的时代！  [/quote] profiler是什么东东

楼主也太钻牛角了吧？ 1.项目中的代码，清晰是第一原则，宁可稍微慢点（可忍受范围内）； 2.1-2次比较，0-1次逻辑运算，这已经很快了，做一次乘法运算的消耗，远大于这个。如果改为一次逻辑运算，或许会快点，但你确认联系程序的上下文，这样更容易读懂？

最简单的，也是这最快的！楼主想多了

你又不是直接写汇编，现在编译器智能程度很高了，一般的优化，编译器都帮你做了

引用 28 楼 yangyunzhao 的回复:[quote=引用 楼主 JLU_Leven 的回复:] 给定两个unsigned的数a和b，要判断a和b中是否有一个数等于0，用两次判断（a == 0 || b == 0）肯定能行，用一次判断 a * b == 0容易越界，想问一下有没有其他只使用一次判断就能达到效果的方法  a*b==0的判断 与（a == 0 || b == 0）有多少区别呢？？   	int a = 1, b = 0; 00ECFCBD  mov         dword ptr [ebp-14h],1  00ECFCC4  mov         dword ptr [ebp-20h],0  	if (a*b == 0) 00ECFCCB  mov         eax,dword ptr [ebp-14h]  00ECFCCE  imul        eax,dword ptr [ebp-20h]  00ECFCD2  test        eax,eax  00ECFCD4  jne         main+63h (0ECFCE3h)  	{ 		printf("a"); 00ECFCD6  push        offset string "a" (0FE4CACh)  00ECFCDB  call        @ILT+5515(_printf) (0EC1590h)  00ECFCE0  add         esp,4  	}  	if (a==0 || b==0) 00ECFCE3  cmp         dword ptr [ebp-14h],0  00ECFCE7  je          main+6Fh (0ECFCEFh)  00ECFCE9  cmp         dword ptr [ebp-20h],0  00ECFCED  jne         main+7Ch (0ECFCFCh)  	{ 		printf("b"); 00ECFCEF  push        offset string "b" (0FE4C84h)  00ECFCF4  call        @ILT+5515(_printf) (0EC1590h)  00ECFCF9  add         esp,4  	}  [/quote] 下面有两次je和jne，会中断流水线

引用 31 楼 hemowolf 的回复:楼主搞什么样的应用领域啊，需要考虑这些差异带来的效率影响？ 导弹的实时弹道计算、修正？ 随便想的

引用 9 楼 taodm 的回复:没有经过性能测试，基本上写啥都是误导。 因为，这么简单的用途，没有编译器不能做出强力优化的。 编译器都怎么优化啊，会不会看&&的两个操作数不相关分开计算，从而减少一次有条件跳转

换来bug得不偿失

楼主，对于这个的讨论要看情况，如果是一般外部代码，就不要优化了，如果你是要写一个内核这类的，你就对你的想法进行反汇编，看汇编代码的条数就行了。。。。。。。。。。。

int main(){ 	int a,b ;  	__asm mov  eax,a 	__asm and  eax,b 	__asm test eax,eax 	__asm je   code }

（a == 0 || b == 0）就是效率最高的，不信可以关优化看汇编

或判断足矣，，练好基本功吧先

引用 9 楼 taodm 的回复:没有经过性能测试，基本上写啥都是误导。 因为，这么简单的用途，没有编译器不能做出强力优化的。  恩，需要benchmark来说话，  不过不知道他的目的是什么，感觉上，他一开始提到的（a == 0 || b == 0）要比他想要追求的一次判断的要简单而且效率要高。

我能说学习了嘛

引用 21 楼 xiaohuh421 的回复:debug环境下都看不到, 那只能说明你开了优化.  if(a==0 || b==0) 00923E1B  cmp         dword ptr [a],0    00923E1F  je          CTestDllDlg::OnBnClickedMfcbutton1+67h (0923E27h)   00923E21  cmp         dword ptr [b],0   00923E25  jne         CTestDllDlg::OnBnClickedMfcbutton1+6Eh (0923E2Eh) 怎么关掉？编译器用的还不熟。 我用的是VC6看的。

（a == 0 || b == 0）从汇编层面来说已经优化到最好，没有必要从语言的角度来找更优办法


Question: //1、输入10个整数，将其中最小的数与第一个数对换，把最大的数和最后一个数对换，写三个函数:1.输入10个数,2.进行处理.3输出10个数 //输入10个数

谢谢楼上回答

void solveArr(int *p, int count){     for (int i = 0; i< count; i++) {         int min = *p;         int temp = 0,index = 0;         if (min > *(p + i)) {             min = *(p + i);  //这里并不是最小值，而是比min小的值             index = i;             temp = *p;      //存储第一个元素             *p = min;       //将最小数赋予第一位上             *(p + index) = temp;//将第一个数赋予最小值所在的位置.         }     }     for (int j = 0; j < count; j++) {         int max = *p;         int temp1 = 0,index1 = 0;         if (max < *(p + j)) {             max = *(p + j);//这里也不是最大值，而是比max大的值             index1 = j;  //存储最大值所在的下标             temp1 = *(p + 9);  //存储最后一个元素             *(p + count - 1) = max;//将最大数赋予最后一个位置             *(p + index1) = temp1;//将最后一个元素赋予最大值所在的位置         }     } }  所谓最小值最大值，是你循环完整个数组得到的结果。你在循环中只要找到比暂时的结果（max，min）就认为是最小值或者最大值进行交换，这是不对的。你的顺序应该这样调： void solveArr(int *p, int count){ 	int min = *p; 	int temp = 0, index = 0; 	for (int i = 0; i< count; i++) { 		 		if (min > *(p + i)) { 			min = *(p + i);  //找出最小值 			index = i;			 		} 	} 	temp = *p;      //存储第一个元素 	*p = min;       //将最小数赋予第一位上 	*(p + index) = temp;//将第一个数赋予最小值所在的位置.  	int max = *p; 	int temp1 = 0, index1 = 0; 	for (int j = 0; j < count; j++) {		 		if (max < *(p + j)) { 			max = *(p + j);//找出最大值 			index1 = j;  //存储最大值所在的下标 		} 	} 	temp1 = *(p + 9);  //存储最后一个元素 	*(p + count - 1) = max;//将最大数赋予最后一个位置 	*(p + index1) = temp1;//将最后一个元素赋予最大值所在的位置 }  顺便给你一个选择排序的代码，其实就是这个题目要求的拓展： #include<stdio.h> #include<limits.h>  int* find_max(int* start, int sum){ 	int max = 0, *p = start; 	for (int i = 0; i < sum; ++i){ 		p = (max < *(start + i) ? start + i : p); 		max = (max < *(start + i) ? *(start + i) : max); 	} 	return p; }  int* find_min(int* start, int sum){ 	int min = INT_MAX, *p = start; 	for (int i = 0; i < sum; ++i){ 		p = (min > *(start + i) ? start + i : p); 		min = (min>*(start + i) ? *(start + i) : min); 	} 	return p; }  void exchange(int* a, int* b){ 	int temp = *a; 	*a = *b; 	*b = temp; }  void sort(int* a, int count){ 	for (int i = 0, j = count - 1; i < j; ++i, --j){ 		exchange(find_min(a + i, count - i * 2), a + i); 		exchange(find_max(a + i, count - i * 2), a + j); 	} }  int main(){ 	int a[] = { 2, 1, 3, 4, 5, 6, 7, 8, 10, 9 }; 	sort(a, 10); 	for (int i = 0; i < 10; ++i) 		printf("%d ", a[i]); }

把事情分开做  第一找出最小值 第二交换最小值到第一个位置  最大值同样分开做即可  不过，如果最大最小值位置有重叠，交换的结果哦，，不能确定是否正确


Question: 关于nginx内存池实现的一个疑惑(可能真是bug)

考虑到nginx不是给别人用的库， 如果nginx本身没有泄露的话， 不算问题吧。

昨天想了下，这里加这个偏移量是因为后续的pool只需要pool_data_t中信息，后续的管理信息是不需要的，只有第一块pool是需要整个pool_t的。


Question: C语言问题  变量声明在函数名和大括号（“{”）间，能编译通过，求解释

C 语言，还支持这种形式的函数定义。 C++ 就不一定支持了 如果需要编译这种函数 把他放在 .c文件里，参与编译。

引用 9 楼 shenmafuyunnan 的回复:我想知道我的第二个问题，就是变量的定义必须定义在函数体的开头，也是因为这个代码比较早的原因吗?  这是你所用编译器不支持C99的原因

涨姿势...

确实是很老了。最新的编译器应该都支持的。

叫做 K&R  式样的函数定义

谢谢大神的回答，这是一个10年前开始的项目了，一直升级沿用到现在，而且是日本一线厂商的智能蓝光播放器里的代码，不过貌似这一段没用了，但是没有删。 我想知道我的第二个问题，就是变量的定义必须定义在函数体的开头，也是因为这个代码比较早的原因吗?

涨知识了。。。。。。。。。

C程序设计语言 K&R C

这得多老的代码了

这是老式函数定义  叫做 K&C 式样的函数定义 具体做法是 函数参数表里只写参数名 参数在参数表的小括号后面定义（声明） ； 参数声明语句(若干个)，有语句结束符分号； 然后才是函数体 static//函数存储类型 int     //函数（返回值）类型  mem_write(b , in , inl) //函数头 参数表的小括号里，只有参数名字。 BIO *b;   //一个结构体指针  //参数 b的声明 char *in;//参数 in的声明 int inl;//参数 inl的声明 {//函数体开始的大括号    ...   //具体就不写了，用到了上面的变量 }//函数体结束的大括号


Question: 一道国人通信的笔试题

a = a + b;     b = a - b;     a = a - b; 溢出对结果无影响

引用 楼主 u010867462 的回复:有字符串 char a[] = "A1A2A3...An"; 不定义任何变量(注意 是任何，嵌入汇编的AX都不行哈)。 升序排序！！！  这个有人会做不！ 昨年12月国人通信的笔试题！ 出这种题的人就是蛋疼，正常的东西不用，非让用烧火棍

引用 楼主 u010867462 的回复:有字符串 char a[] = "A1A2A3...An"; 不定义任何变量(注意 是任何，嵌入汇编的AX都不行哈)。 升序排序！！！  这个有人会做不！ 昨年12月国人通信的笔试题！  首先要定义一个void swap(char* A) {*A=*A+*(A+1); *(A+1)=*A-*(A+1); *A=*A-*(A+1);} 再定义2元素的排序void sort_2_F(char*A){if(*A>*(A+1) ) swap(A);  } void sort_2_B(char* A){if(*A<*(A-1) )  swap(A-1); } 有了这个两个函数，可以实现冒泡。因为没有中间变量定义指针的初始位置，只能移动（移动了就失去了初始位置），所以采用了双向的冒泡，冒泡两趟回到初始位置，并且每一趟都遍历了整个数组。时间效率是正常冒泡法的4倍。 void Bbl_Sort(char* A, int n){ while(n>1) {while(++A) sort_2_F(A-1); while(--A) sort_2_B(A+1); --n; } } 顺便吐槽，编译器都给你加了不知道多少的临时变量。

用字典树存贮后输出就可以吧

数组算一个变量，n算一个变量，两个变量足以。 比如使用冒泡排序  交换变量时(a是数组的变量，b是n) a=10;b=12; a=b-a; //a=2;b=12 b=b-a; //a=2;b=10 a=b+a; //a=10;b=10。   发下其他几种不需要临时变量的交换方式   1） 指针地址操作 因为对地址的操作实际上进行的是整数运算，比如：两个地址相减得到一个整数，表示两个变量在内存中的储存位置隔了多少个字节；地址和一个整数相加即“a+10”表示以a为基地址的在a后10个a类数据单元的地址。所以理论上可以通过和算术算法类似的运算来完成地址的交换，从而达到交换变量的目的。即： int *a,*b; //假设 *a=new int(10); *b=new int(20); //&a=0x00001000h,&b=0x00001200h a=(int*)(b-a); //&a=0x00000200h,&b=0x00001200h b=(int*)(b-a); //&a=0x00000200h,&b=0x00001000h a=(int*)(b+int(a)); //&a=0x00001200h,&b=0x00001000h 通过以上运算a、b的地址真的已经完成了交换，且a指向了原先b指向的值，b指向原先a指向的值了吗？上面的代码可以通过编译，但是执行结果却令人匪夷所思！原因何在？ 首先必须了解，操作系统把内存分为几个区域：系统代码/数据区、应用程序代码/数据区、堆栈区、全局数据区等等。在编译源程序时，常量、全局变量等都放入全局数据区，局部变量、动态变量则放入堆栈区。这样当算法执行到“a=(int*)(b-a)”时，a的值并不是0x00000200h，而是要加上变量a所在内存区的基地址，实际的结果是：0x008f0200h，其中0x008f即为基地址，0200即为a在该内存区的位移。它是由编译器自动添加的。因此导致以后的地址计算均不正确，使得a,b指向所在区的其他内存单元。再次，地址运算不能出现负数，即当a的地址大于b的地址时，b-a<0，系统自动采用补码的形式表示负的位移，由此会产生错误，导致与前面同样的结果。 有办法解决吗？当然！以下是改进的算法： if(a<b) { a=(int*)(b-a); b=(int*)(b-(int(a)&0x0000ffff)); a=(int*)(b+(int(a)&0x0000ffff)); } else { b=(int*)(a-b); a=(int*)(a-(int(b)&0x0000ffff)); b=(int*)(a+(int(b)&0x0000ffff)); } 算法做的最大改进就是采用位运算中的与运算“int(a)&0x0000ffff”，因为地址中高16位为段地址，后16位为位移地址，将它和0x0000ffff进行与运算后，段地址被屏蔽，只保留位移地址。这样就原始算法吻合，从而得到正确的结果。 此算法同样没有使用第三变量就完成了值的交换，与算术算法比较它显得不好理解，但是它有它的优点即在交换很大的数据类型时，它的执行速度比算术算法快。因为它交换的时地址，而变量值在内存中是没有移动过的。（以下称为地址算法）  2） 位运算 int a=10,b=12; //a=1010^b=1100; a=a^b; //a=0110^b=1100; b=a^b; //a=0110^b=1010; a=a^b; //a=1100=12;b=1010; 此算法能够实现是由异或运算的特点决定的，通过异或运算能够使数据中的某些位翻转，其他位不变。这就意味着任意一个数与任意一个给定的值连续异或两次，值不变。   3）栈实现。不多解释了，栈和相关函数定义省去。 int exchange(int x,int y)  {   stack S;   push(S,x);   push(S,y);   x=pop(S);   y=pop(S);  }  以上算法均实现了不借助其他变量来完成两个变量值的交换，相比较而言算术算法和位算法计算量相当，地址算法中计算较复杂，却可以很轻松的实现大类型（比如自定义的类或结构）的交换，而前两种只能进行整形数据的交换（理论上重载“^”运算符，也可以实现任意结构的交换）。 介绍这三种算法并不是要应用到实践当中，而是为了探讨技术，展示程序设计的魅力。

只用一个变量，和一个数组的冒泡排序。  char a[]="abcdiopwerqefgabcd"; int n;  #define swap(a,b) do{a^=b;b^=a;a^=b;}while(0)   void sort() { 	do{ 		for(n =0;n< strlen(a)-1;n++) 		{ 			if(a[n]>a[n+1])  				swap(a[n],a[n+1]); 		}  		for(n =0;n< strlen(a)-1;n++){ 			if(a[n]>a[n+1])break; 		} 		printf("n= %d",n);  	}while(n < strlen(a)-1 ); 	 	 //	for(n= 0;n<strlen(a);n++){ // //		printf("%c",a[n]); //			    //a[n]='\0';  //	}  }

另外 可以从后向前冒泡排序 n做循环变量 代码大致如下  char a[]="iopwerqefgabcd"; int n;  #define swap(a,b) do{a^=b;b^=a;a^=b;}while(0) void sort() { 	do{ 		for(n =0;n< strlen(a)-1;n++) 		{ 			if(a[n]< a[n+1])  				swap(a[n],a[n+1]); 		}  		for(n =0;n< strlen(a)-1;n++){ 			if(a[n]<a[n+1])break; 		} 		//printf("n= %d",n); 		if(n >= strlen(a)-1){  			for(n= strlen(a)-1;n>=0;n--){  				printf("%c",a[n]); 			    a[n]='\0';  			} 		} 	} 	while(strlen(a)>0); }

补充一下， if(a[n]||a[n+1])  return;//这鼐逻辑写错了 改为 if(!a[n+1]) return; //当a[n+1]为'\0'时退出

引用 7 楼 lovesmiles 的回复:第一，二个变量互换不用其它变量这是可以做到的，四楼已经有写。 第二，指针a，变量n和a[n]='\0'这三个条件只要保持二个不变，是可以换算出第三个条件的。 所以可以将n腾出来做临时变量。  根据上面二个条件完成一次冒泡是不难的，中间不需要用到任何其它变量。  剩下的还需要记录什么时候停止冒泡，当然如果死循环到最后也是能有序的。 其它的方法之一就是放弃a永远指向数组首地址，让它通过自加的形式参加到记录循环次数。  这样就一个变量也不用了。  太夜了，明天再想想代码  好了，早上醒了，想了一下，想到了用n记录停止冒泡的问题。 代码如下  char a[]="abcdiopwerqefgabcd"; int n;  sort() {    while(1) {//这是一个死循环，唯一满足退出的条件就是遍历一次后，没有发生交换的情况。否则，一直冒泡下去。    n=0;    while(a[n]&&a[n+1])//这个while遍历一次，以确认是否还需要冒泡;      {        if(a[n]>a[n+1])break;         n++;      }   if(a[n]||a[n+1]) return;//n到了数组尾，说明没有需要交换的了。可以退出。  else  {//还有需要交换的情况，则进行一次冒泡。    n=0;        while(a[n]&&a[n+1])      {//这个while循环完成一次冒泡        if(a[n]>a[n+1])          {//交换                a[n] =a[n]^a[n+1];                a[n+1]=a[n]^a[n+1];                 a[n] =a[n]^a[n+1];          }         n++;      }   }  } }    呵呵，我的代码怎么样？连一个strlen也没有用到，没有形参，没有递归调用。啦啦，哈哈

引用 19 楼 vnvlyp 的回复:“不定义任何变量(注意 是任何，嵌入汇编的AX都不行哈)”  难道CPU可以直接在内存中运算？如果不能那肯定要用寄存器，如果用到寄存器那为什么程序不允许用运算无论如何都要用的寄存器？你想太多了。。。

void swap(char &a, char &b) {     a ^= b;     b ^= a;     a ^= b; }  void asc2(char *s) {     if(*s && *(s + 1))     {         asc2(s + 1);         while(*(s + 1))         {             if(*s > *(s + 1))                 swap(*s, *(s + 1));             ++s;         }     } }  看了下。。有人说n是常量。。所以重写了一个。。

难道要的是这个？ C : //除了数组a， 程序里，没额外定义任何变量 //只是借用一些，库里的外部变量，这个算没定义变量么？？？ #include<stdlib.h> char a[] = "abcdiopwerqefgabcd"; #define n (sizeof(a)/sizof(a[0])-1)          //常量 n  void sort_str() {         //_asm push errno 	do{ 		for(errno=0;errno< n;errno++) 		{ 			if(a[errno]>a[errno+1])  				swap(a[errno],a[errno+1]); 		}  		for(errno =0;errno< n-1;errno++){ 			if(a[errno]>a[errno+1])break; 		} 				 	}while(errno < n - 1 ); 	//_asm pop errno       //  printf("%s",a);            }

引用 13 楼 u010867462 的回复:我想说的是 n可以用 但是这个n是常量啊 人家字符串里面定义的！！！ 你们全部拿来当变量用。。。照你这么说，只能这样了 非递归实现 #include <stdio.h> #include <string.h>  #define N strlen(a)  void swap(char* a, char* b) { 	*a ^= *b; 	*b ^= *a; 	*a ^= *b; }  void sort_str(char str[],int len) { 	len=0; 	while (len < strlen(str)) 	{ 		if (len == 0 || str[len - 1] <= str[len]) 		{ 			len++; 		} 		else 		{ 			swap(str+len,str+len - 1); 			len--; 		} 	} }  int main() { 	char a[]="abcdiopwerqefgabcd"; 	sort_str(a,N); 	puts(a); 	return 0; }

引用 13 楼 u010867462 的回复:我想说的是 n可以用 但是这个n是常量啊 人家字符串里面定义的！！！ 你们全部拿来当变量用。。。照你这么说，只能这样了 非递归实现 void swap(char &a, char &b) { 	a ^= b; 	b ^= a; 	a ^= b; }  void sort(char str[],int len) { 	len=0; 	while (len < strlen(str)) 	{ 		if (len == 0 || str[len - 1] <= str[i]) 		{ 			len++; 		} 		else 		{ 			swap(str+i,str+i - 1]); 			len--; 		} 	} }

C++: 你要的是这个？  sort(a,a+n); cout<<a<<endl;

引用 4 楼 qq506657335 的回复: void swap(char &a, char &b) {     a ^= b;     b ^= a;     a ^= b; }  void asc(char *s, int n) {     if(n > 1)     {         asc(s, n - 1);         --n; //避免处理掉'\0'         while(n > 0)         {             if(s[n] < s[n - 1])                 swap(s[n], s[n - 1]);             --n;         }     } }   应该是这样吧=。=

这个根本不需要排列好吗？？？        根据n的值，推算出A的个数，在推算出数字（1,2.。。。。。。。）的个数   'A'>'数字'，从你上面的来看。。。整个数组后面部分全是‘A’，前面部分项依次为数字。。。。。。。。。。


Question: 帮分析一下，这个程序的结果是怎么来的

其实这个和你编译时变量内存分配有关，  很有可能是 n[2] 数组空间后紧接着分配了 i 或 j 的空间，所以循环完成后， i，j 都为2， 所以输出的其实是 i 或 j 如果编译器编译规则不一样，或者说你把 i和j 定义放在数组之前， 结果应该就不一样了。

数组输出明显越界

由此可见，结果必须是一个随机数，但是由于在当时你的n[1]的下一个内存单元存的数恰好是2，所以打出来是2

“不确定”去看置顶帖；随机 是一个“确定”的规律。 引用 4 楼 lovesmiles 的回复:[quote=引用 2 楼 taodm 的回复:] 谁跟你说的是随机数，离那货远点。 是不确定值。   抛开内存访问错误这种可能， 不确定值和随机数有什么区别？[/quote]

引用 2 楼 taodm 的回复:谁跟你说的是随机数，离那货远点。 是不确定值。   抛开内存访问错误这种可能， 不确定值和随机数有什么区别？

int main() {  	int n[2]={0},i,j,k=2; 	for(i=0;i<k;i++) 		for(j=0;j<k;j++) 			n[j]=n[i]+1; 	printf("%d\n",n[k]); 	return 0; }   我的输出是4195392，是越界了啊

谁跟你说的是随机数，离那货远点。 是不确定值。

是随机数，gcc编译表示为0


Question: fopen()打开文件失败

引用 5 楼 user-10 的回复:[quote=引用 3 楼 user-10 的回复:] fgets会在读入的字符串最后加上一个\n，它也包括到文件名里面了。从你的输出就能看出来，两个引号不在同一行 更正一下，这个\n也不能说是fgets加上的，其实就是你输入一行之后敲的那个回车，他也被fgets读到字符串里面了。[/quote]  这就是问题了

引用 14 楼 myclass242 的回复: if((fp=fopen("nuhv","rb"))==NULL) {        fprintf(stderr,"打开文件\"%s\"错误\n","nulv");        exit(1); }  我这样改还是错误 你这样改的话，你的当前目录下有nuhv这个文件么。。。。要打开成功，要保证你fopen的第一个参数是正确的路径+文件名

你自己看看输出的语句 打开xxx 失败。  输出总是分成二行，你难道没有觉得奇怪？这个换行符是怎么来的？

引用 12 楼 zxh707wk 的回复:引用 9 楼 u011728480 的回复:很乐意看到你在Linux下工作，。。。。。。。。简单的文件名称，为啥你要使用的输入方式那么复杂。。。。。。。。。就一个char 数组，加上普通的输入就可以额。。。。。。。。如果输入的文件名太长，可能会越界       这个完全有办法判断的。。。。。。对于越界行为。。。。。。。

不是我想这么写，这是《c primer plus》第十三章程序清单13.5里的例题程序。

楼主估计是闲着蛋疼才这么写。。。。

引用 8 楼 blueroger07 的回复:可以这样改,在第12行后面加上 file[strlen(file)-1] = 0;+1

引用 4 楼 lisong694767315 的回复:因为用fgets读取字符串，会自动在字符串后添加'\0'结束符，假设文件名为test.h，则读取后的字符串为“test.h\0”，所以打开文件会失败！  而用scanf读取就是“test.h”。是'\n'，不是'\0'

在当前目录下打开文件要用./

哦，3楼说的是对的，最后自动加的是‘\n’换行符。

引用 3 楼 user-10 的回复:fgets会在读入的字符串最后加上一个\n，它也包括到文件名里面了。从你的输出就能看出来，两个引号不在同一行 更正一下，这个\n也不能说是fgets加上的，其实就是你输入一行之后敲的那个回车，他也被fgets读到字符串里面了。

能说说这样修改的理由吗？还有我的string.h头文件里好像没有bezero()函数

用scanf代替fgets：  scanf("%s", file);  文件名字符数组最好先置0：  char file[SLEN]; bzero(file,SLEN);  // 头文件#include<string.h>


Question: c知识

强烈支持新手VC++6.0，这个可是经典中的经典

有个c语言编译器就行了，如vc6.0

支持楼上的。。

直接下载一个较新商业化的新的编译器玩玩吧， 不要总是从0开始。   visual studio express 2013很不错。

为什么我觉得C FREE这么好呐

如果只是初学的话在windows（32位系统）上可以用wintc学算法 linux上用gcc，不过有IDE可以下载的（32位/64位）

引用 3 楼 lisong694767315 的回复:Windows下，建议楼主安装Dev-C++或者Code::Blocks，这两个集成开发环境比较小巧，适合初学； Linux下，建议使用vim编辑器编写代码，然后用gcc编译。 顶！

楼上都说完了！！！

建议楼主下载一个winTC的软件来玩

只要有一个编译器就可以，学习的话，使用gcc就可以了。


Question: 求助

宏定义时多了一个分号 #define Stack_Init_Size1 100; 改为 #define Stack_Init_Size1 100

宏定义的问题，解决办法同楼上， 其实也可以用定义常变量替代宏定义，还有就是最好不要用void main了


感觉相当于 #ifndef #define #endif 不知道对不对 mark一下。。。。

条件编译 The #if, #elif, #else, and #endif Directives The #if directive, with the #elif, #else, and #endif directives, controls compilation of portions of a source file. If the expression you write (after the #if) has a nonzero value, the line group immediately following the #if directive is retained in the translation unit.  Syntax  conditional :  if-part elif-partsopt else-partopt endif-line  if-part :  if-line text  if-line :  #if constant-expression #ifdef identifier #ifndef identifier  elif-parts :  elif-line text elif-parts elif-line text  elif-line :  #elif constant-expression  else-part :  else-line text  else-line :  #else  endif-line :  #endif  Each #if directive in a source file must be matched by a closing #endif directive. Any number of #elif directives can appear between the #if and #endif directives, but at most one #else directive is allowed. The #else directive, if present, must be the last directive before #endif.   The #if, #elif, #else, and #endif directives can nest in the text portions of other #if directives. Each nested #else, #elif, or #endif directive belongs to the closest preceding #if directive.  All conditional-compilation directives, such as #if and #ifdef, must be matched with closing #endif directives prior to the end of file; otherwise, an error message is generated. When conditional-compilation directives are contained in include files, they must satisfy the same conditions: There must be no unmatched conditional-compilation directives at the end of the include file.  Macro replacement is performed within the part of the command line that follows an #elif command, so a macro call can be used in the constant-expression.  The preprocessor selects one of the given occurrences of text for further processing. A block specified in text can be any sequence of text. It can occupy more than one line. Usually text is program text that has meaning to the compiler or the preprocessor.  The preprocessor processes the selected text and passes it to the compiler. If text contains preprocessor directives, the preprocessor carries out those directives. Only text blocks selected by the preprocessor are compiled.  The preprocessor selects a single text item by evaluating the constant expression following each #if or #elif directive until it finds a true (nonzero) constant expression. It selects all text (including other preprocessor directives beginning with #) up to its associated #elif, #else, or #endif.  If all occurrences of constant-expression are false, or if no #elif directives appear, the preprocessor selects the text block after the #else clause. If the #else clause is omitted and all instances of constant-expression in the #if block are false, no text block is selected.  The constant-expression is an integer constant expression with these additional restrictions:   Expressions must have integral type and can include only integer constants, character constants, and the defined operator.   The expression cannot use sizeof or a type-cast operator.   The target environment may not be able to represent all ranges of integers.   The translation represents type int the same as type long, and unsigned int the same as unsigned long.   The translator can translate character constants to a set of code values different from the set for the target environment. To determine the properties of the target environment, check values of macros from LIMITS.H in an application built for the target environment.    The expression must not perform any environmental inquiries and must remain insulated from implementation details on the target computer.  The preprocessor operator defined can be used in special constant expressions, as shown by the following syntax:  Syntax  defined( identifier )  defined identifier  This constant expression is considered true (nonzero) if the identifier is currently defined; otherwise, the condition is false (0). An identifier defined as empty text is considered defined. The defined directive can be used in an #if and an #elif directive, but nowhere else.  In the following example, the #if and #endif directives control compilation of one of three function calls:  #if defined(CREDIT)     credit(); #elif defined(DEBIT)     debit(); #else     printerror(); #endif  The function call to credit is compiled if the identifier CREDIT is defined. If the identifier DEBIT is defined, the function call to debit is compiled. If neither identifier is defined, the call to printerror is compiled. Note that CREDIT and credit are distinct identifiers in C and C++ because their cases are different.  The conditional compilation statements in the following example assume a previously defined symbolic constant named DLEVEL.  #if DLEVEL > 5     #define SIGNAL  1     #if STACKUSE == 1         #define STACK   200     #else         #define STACK   100     #endif #else     #define SIGNAL  0     #if STACKUSE == 1         #define STACK   100     #else         #define STACK   50     #endif #endif #if DLEVEL == 0     #define STACK 0 #elif DLEVEL == 1     #define STACK 100 #elif DLEVEL > 5     display( debugptr ); #else     #define STACK 200 #endif  The first #if block shows two sets of nested #if, #else, and #endif directives. The first set of directives is processed only if DLEVEL > 5 is true. Otherwise, the statements after #else are processed.  The #elif and #else directives in the second example are used to make one of four choices, based on the value of DLEVEL. The constant STACK is set to 0, 100, or 200, depending on the definition of DLEVEL. If DLEVEL is greater than 5, then the statement   #elif DLEVEL > 5 display(debugptr);  is compiled and STACK is not defined.  A common use for conditional compilation is to prevent multiple inclusions of the same header file. In C++, where classes are often defined in header files, constructs like the following can be used to prevent multiple definitions:  // EXAMPLE.H - Example header file  #if !defined( EXAMPLE_H ) #define EXAMPLE_H  class Example { ... };  #endif // !defined( EXAMPLE_H )  The preceding code checks to see if the symbolic constant EXAMPLE_H is defined. If so, the file has already been included and need not be reprocessed. If not, the constant EXAMPLE_H is defined to mark EXAMPLE.H as already processed.  Microsoft Specific   Conditional compilation expressions are treated as signed long values, and these expressions are evaluated using the same rules as expressions in C++. For example, this expression:  #if 0xFFFFFFFFL > 1UL  is true.  END Microsoft Specific

regVal 应该是个16bit的数据类型 读取的值应该是高位有效，低位无效的  如果是12bit的ADC，则regVal 左移4位，将无效位去掉


Question: 如何将char[]数组中的数据放进shor int[]的数组中

引用 6 楼 user-4 的回复:照lz后来补充的意思， 不考虑大小端不同的话4楼ok啊 或者 for (int i=0;i<bytes;i++) s[i]=(short int)pkt_data[i]);  改成 for (int i=0;i<bytes;i+=2) s[i/2]=(short int)pkt_data[i]); 恩恩，的确有大小端的问题，当时我试了一下就发现了，现已解决。不过是memcpy之后解决的，而且只能一个一个的解决，阁下有什么高招？？

直接指针转一下好了啊 short int* psht = (short int*)p; 这样就可以用了啊，而且效率高，就是需要注意，操作的时候这块内存确保不要释放了 等操作完成了后释放

不知道有多少前人掉在TCP Socket send(人多)send(病少)send(财富) recv(人多病)recv(少财富) 陷阱里面啊！ http://bbs.csdn.net/topics/380167545

直接memcpy进入short int的数组中就可以，如果不是网络接收的数据的话，可以直接拷贝过去的

引用 4 楼 aaa763602742 的回复:[quote=引用 2 楼 zhao4zhong1 的回复:] short int s[MAXBYTES]; int bytes; bytes=100; for (int i=0;i<bytes;i++) s[i]=(short int)pkt_data[i]); 赵老师，忘了说了，pkt_data[]的大小为：1012，因为我们定义的一帧数据就是1012个字节。你看我这么做有问题没：short int s[506];memcpy(s, pkt_data, 1012);[/quote] 取决于后续怎样处理s

引用 2 楼 zhao4zhong1 的回复:short int s[MAXBYTES]; int bytes; bytes=100; for (int i=0;i<bytes;i++) s[i]=(short int)pkt_data[i]); 赵老师，忘了说了，pkt_data[]的大小为：1012，因为我们定义的一帧数据就是1012个字节。你看我这么做有问题没：short int s[506];memcpy(s, pkt_data, 1012);

引用 2 楼 zhao4zhong1 的回复:short int s[MAXBYTES]; int bytes; bytes=100; for (int i=0;i<bytes;i++) s[i]=(short int)pkt_data[i]); 这个貌似不对吧。你这样是吧pkt_data中的一个元素强转成short int 类型，我要的是把pkt_data中的两个元素当成short in[]中的一个元素，比如把pkt_data[i]和pkt_data[i+1]赋值给s[i],是这么个意思。


Question: 哪儿有破解版的Visual studio 2013下载？

引用 5 楼 Intel0011 的回复:http://www.itopdog.cn/soft/visualstudio2013.html网页下方有Key http://blog.csdn.net/skykingf/article/details/12883655    真的 太感谢您了

Visual studio 2013去官网下啊！

VS 系列都没见过破解版，网上随便搜点序列号试用版就变成正式版了。

http://pan.baidu.com/s/1qWydFwo 额，直接下载了输入key不就可以了，编程工具不是问题哟

抱歉，还没用，所以不知道

用express版也挺好的，学生用的好像高级版也免费。

http://www.itopdog.cn/soft/visualstudio2013.html Visual Studio 2013旗舰版KEY:BWG7X-J98B3-W34RT-33B3R-JVYW9


Question: 自己写的2048的C语言小程序，可是就是编译不了，求大神赐教

程序首发地址 http://wapwenku.baidu.com/view/54b562e0f524ccbff12184f6.html

这程序是我编的！！！根本不是楼主编的！！！ 注意看程序代码有一行Made by Yanjisheng，那就是我！！！此程序2014年4月9日首发百度文库。 对楼主无耻盗用程序的行为表示强烈鄙视！！！

跳到错误行，然后把代码规范化一下，就会发现问题在哪里。

偶遇到类似问题都是用 “每次用/*...*/注释掉不同部分再重新编译，直到定位到具体语法出错的位置。” 的方法解决的。

我试了试  copy了你的代码 我在 return change; 后面加上了个}      后花括号  然后直接运行 没啥问题！连你那些编译错误都没有！！如图

}while(t<=3);/*重复多次*/     return change;           <------------缺了个'}'     int main(void){     int gameover=0;/*判断游戏是否结束，1结束，0继续*/

引用 6 楼 modyaj 的回复:[quote=引用 5 楼 hell0_wor1d 的回复:] [quote=引用 4 楼 modyaj 的回复:] [quote=引用 3 楼 hell0_wor1d 的回复:] [quote=引用 1 楼 modyaj 的回复:] 把问题写清楚  把错误指出来  大家才可以参考 --------------------Configuration: 2048 - Win32 Debug-------------------- Compiling...  2048.c  E:\离散作业\x\2048.c(118) : error C2143: syntax error : missing ';' before 'type'  E:\离散作业\x\2048.c(120) : error C2143: syntax error : missing ';' before 'type'  E:\离散作业\x\2048.c(121) : error C2143: syntax error : missing ';' before 'type'  E:\离散作业\x\2048.c(122) : error C2143: syntax error : missing ';' before 'type'  E:\离散作业\x\2048.c(125) : error C2065: 'gameover' : undeclared identifier  E:\离散作业\x\2048.c(132) : error C2065: 'j' : undeclared identifier  E:\离散作业\x\2048.c(145) : error C2065: 'input' : undeclared identifier 执行 cl.exe 时出错.  2048.exe - 1 error(s), 0 warning(s) 这是系统的显示  不好意思 我是新手 可能比较低级的错误 请指教！ [/quote] 双击错误提示，这时候光标就跳到了错误行，看英文错误报告，前面几个都是缺少分号 后面几个都是变量未定义！！[/quote]  这个我是看得懂的  ！可是怎么解决才是关键。[/quote] 缺少分号就在相应的位置输入英文字符的分号  没有定义就在引用之前定义一下就是了！自己能写这个代码 应该知道语句结束要分号  变量如何定义了[/quote] 好  首先谢谢你  不过我靠自己做好了最后 程序并不是好像你说的 没有定义就定义一下这么简单的货。 这个谁都会  不过还是谢谢你了

引用 5 楼 hell0_wor1d 的回复:[quote=引用 4 楼 modyaj 的回复:] [quote=引用 3 楼 hell0_wor1d 的回复:] [quote=引用 1 楼 modyaj 的回复:] 把问题写清楚  把错误指出来  大家才可以参考 --------------------Configuration: 2048 - Win32 Debug-------------------- Compiling...  2048.c  E:\离散作业\x\2048.c(118) : error C2143: syntax error : missing ';' before 'type'  E:\离散作业\x\2048.c(120) : error C2143: syntax error : missing ';' before 'type'  E:\离散作业\x\2048.c(121) : error C2143: syntax error : missing ';' before 'type'  E:\离散作业\x\2048.c(122) : error C2143: syntax error : missing ';' before 'type'  E:\离散作业\x\2048.c(125) : error C2065: 'gameover' : undeclared identifier  E:\离散作业\x\2048.c(132) : error C2065: 'j' : undeclared identifier  E:\离散作业\x\2048.c(145) : error C2065: 'input' : undeclared identifier 执行 cl.exe 时出错.  2048.exe - 1 error(s), 0 warning(s) 这是系统的显示  不好意思 我是新手 可能比较低级的错误 请指教！ [/quote] 双击错误提示，这时候光标就跳到了错误行，看英文错误报告，前面几个都是缺少分号 后面几个都是变量未定义！！[/quote]  这个我是看得懂的  ！可是怎么解决才是关键。[/quote] 缺少分号就在相应的位置输入英文字符的分号  没有定义就在引用之前定义一下就是了！自己能写这个代码 应该知道语句结束要分号  变量如何定义了

引用 4 楼 modyaj 的回复:[quote=引用 3 楼 hell0_wor1d 的回复:] [quote=引用 1 楼 modyaj 的回复:] 把问题写清楚  把错误指出来  大家才可以参考 --------------------Configuration: 2048 - Win32 Debug-------------------- Compiling...  2048.c  E:\离散作业\x\2048.c(118) : error C2143: syntax error : missing ';' before 'type'  E:\离散作业\x\2048.c(120) : error C2143: syntax error : missing ';' before 'type'  E:\离散作业\x\2048.c(121) : error C2143: syntax error : missing ';' before 'type'  E:\离散作业\x\2048.c(122) : error C2143: syntax error : missing ';' before 'type'  E:\离散作业\x\2048.c(125) : error C2065: 'gameover' : undeclared identifier  E:\离散作业\x\2048.c(132) : error C2065: 'j' : undeclared identifier  E:\离散作业\x\2048.c(145) : error C2065: 'input' : undeclared identifier 执行 cl.exe 时出错.  2048.exe - 1 error(s), 0 warning(s) 这是系统的显示  不好意思 我是新手 可能比较低级的错误 请指教！ [/quote] 双击错误提示，这时候光标就跳到了错误行，看英文错误报告，前面几个都是缺少分号 后面几个都是变量未定义！！[/quote]  这个我是看得懂的  ！可是怎么解决才是关键。

引用 3 楼 hell0_wor1d 的回复:[quote=引用 1 楼 modyaj 的回复:] 把问题写清楚  把错误指出来  大家才可以参考 --------------------Configuration: 2048 - Win32 Debug-------------------- Compiling...  2048.c  E:\离散作业\x\2048.c(118) : error C2143: syntax error : missing ';' before 'type'  E:\离散作业\x\2048.c(120) : error C2143: syntax error : missing ';' before 'type'  E:\离散作业\x\2048.c(121) : error C2143: syntax error : missing ';' before 'type'  E:\离散作业\x\2048.c(122) : error C2143: syntax error : missing ';' before 'type'  E:\离散作业\x\2048.c(125) : error C2065: 'gameover' : undeclared identifier  E:\离散作业\x\2048.c(132) : error C2065: 'j' : undeclared identifier  E:\离散作业\x\2048.c(145) : error C2065: 'input' : undeclared identifier 执行 cl.exe 时出错.  2048.exe - 1 error(s), 0 warning(s) 这是系统的显示  不好意思 我是新手 可能比较低级的错误 请指教！ [/quote] 双击错误提示，这时候光标就跳到了错误行，看英文错误报告，前面几个都是缺少分号 后面几个都是变量未定义！！

引用 1 楼 modyaj 的回复:把问题写清楚  把错误指出来  大家才可以参考 --------------------Configuration: 2048 - Win32 Debug-------------------- Compiling...  2048.c  E:\离散作业\x\2048.c(118) : error C2143: syntax error : missing ';' before 'type'  E:\离散作业\x\2048.c(120) : error C2143: syntax error : missing ';' before 'type'  E:\离散作业\x\2048.c(121) : error C2143: syntax error : missing ';' before 'type'  E:\离散作业\x\2048.c(122) : error C2143: syntax error : missing ';' before 'type'  E:\离散作业\x\2048.c(125) : error C2065: 'gameover' : undeclared identifier  E:\离散作业\x\2048.c(132) : error C2065: 'j' : undeclared identifier  E:\离散作业\x\2048.c(145) : error C2065: 'input' : undeclared identifier 执行 cl.exe 时出错.  2048.exe - 1 error(s), 0 warning(s) 这是系统的显示  不好意思 我是新手 可能比较低级的错误 请指教！

把问题写清楚  把错误指出来  大家才可以参考

偶直接跳到错误行去看的


Question: onvif客户端接收告警问题

你先用抓包工具看看发送的包是否正确


Question: C语言源代码分析器

多点介绍不行么？已经我们老板让我们做过一种给C代码打分的分析器。

自己开发的吗，　挺好的想法

试用就知道了! 让你阅读或分析别人的C源代码更方便! 这是一个不完全的版本, 更多功能正在开发中...

分析代码的什么的？

自己写的编辑工具吗？

分析源代码?没弄懂lz的意思


Question: Mayday！Mayday！！

[quote=引用 7 楼 zhao4zhong1 的回复:] 看这个帖子标题，我还以为又即将发生一起空难呢！ 那不敢呀，这个月够多了！！

不要和五月天的歌迷吵架。。。。 楼上的 难道是程序员的女朋友来卖萌的？

五月天、五月天

C primer plus这本书挺不错的，去网上下载看看，最好买一本

看这个帖子标题，我还以为又即将发生一起空难呢！

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

引用 3 楼 yangyangsnr 的回复:C语言关键字，具体意义，还是先去看下书吧，没记错的话，这些都是印一块的。 是的，但是他就说那是整数变量类型，那是无符号整数变量类型，那些是浮点数变量类型，具体是怎麽用？

引用 2 楼 CCQ2014 的回复:[quote=引用 1 楼 modyaj 的回复:] 把这些字符放到百度中去！！ 是[/quote]

C语言关键字，具体意义，还是先去看下书吧，没记错的话，这些都是印一块的。

引用 1 楼 modyaj 的回复:把这些字符放到百度中去！！ 是

把这些字符放到百度中去！！

标题党啊

其实楼主是想表达“黑色星期五”吧。。。。。

lz故意的吧

这帖子有点水啊

引用 楼主 CCQ2014 的回复:各位大神如下符号（字母）都是干啥用的？（求详解）   char       short    int    long      long long        float    double    long double C语言的类型关键字 定义类型变量的时候需要用到 C语言中的变量都是需要定义相应的类型的

Mayday,这是要打飞机的节奏么？


Question: 怎么样写点亮一个LED的C程序

你百度下“ET6202 程序”，有个键盘的程序，可以参考下里面的写命令子程序和写数据子程序。接下来，我也帮不了你了。SORRY 16楼正解

引用 11 楼 Dore_Woo 的回复:[quote=引用 9 楼 lovesmiles 的回复:] 你手上没有例子程序可以用吗？一般上会有一些简单的例子C代码。可以在上面改成你要的功能。或者你上网找一下这个型号的看看有没有例子代码。 就是没有例子程序啊，都不知道怎么搞了，我一个从来没有写过一个程序的新手叫我干这些...[/quote]  keil c 编译器之类的工具总会有吧？你们用什么编译工具？怎么烧板子？这些工具软件配套齐没有？

引用 9 楼 lovesmiles 的回复:你手上没有例子程序可以用吗？一般上会有一些简单的例子C代码。可以在上面改成你要的功能。或者你上网找一下这个型号的看看有没有例子代码。 就是没有例子程序啊，都不知道怎么搞了，我一个从来没有写过一个程序的新手叫我干这些...

共阴极led高电平有效

引用 4 楼 cyd54454 的回复:1.芯片手册里找到控制寄存器，数据寄存器的地址，看看怎么设置这些寄存器。2.原理图上找到led对应的引脚，看看点亮是需要高电平还是低电平。3.设置控制寄存器，往数据寄存器对应的位写1或0。完成了   它没有写寄存器的地址

拿引脚控制就行了，你买板子的话应该有教程

引用 14 楼 cyd54454 的回复:仔细看看给你的手册，工具书，我没弄过这个，但应该都是相通的。  它就是一个驱动ic吧，没有给头文件哦，我好像找到地址了，但是不知道怎么看，你知道怎么看吗？

仔细看看给你的手册，工具书，我没弄过这个，但应该都是相通的。

引用 8 楼 Dore_Woo 的回复:[quote=引用 4 楼 cyd54454 的回复:] 1.芯片手册里找到控制寄存器，数据寄存器的地址，看看怎么设置这些寄存器。2.原理图上找到led对应的引脚，看看点亮是需要高电平还是低电平。3.设置控制寄存器，往数据寄存器对应的位写1或0。完成了  它没有写寄存器的地址[/quote] 那板子供应商应该提供了一个头文件，在头文件里已经定义好了的，你找找看具体的名字，这名字应该就是管脚名。

单片机吧。。。。。请把板子图贴出来。。。。。。

这个一般要有实验板  是单片机吧？ 找芯片手册看下 对应高低电平 其实简单的程序汇编写也行

引用 4 楼 cyd54454 的回复:1.芯片手册里找到控制寄存器，数据寄存器的地址，看看怎么设置这些寄存器。2.原理图上找到led对应的引脚，看看点亮是需要高电平还是低电平。3.设置控制寄存器，往数据寄存器对应的位写1或0。完成了  +10086找到led灯对应的引脚。找芯片手册，在这个引脚输出电平。led就亮了

引用 楼主 Dore_Woo 的回复:目前手里有一个LED driver 电路板及电路图，怎么样去点亮这个LED，输出的线有led-cs；led-clk；led-dat；vdd；gnd； 该怎么下手写这个程序，求大神指点 嵌入式硬件方面不太懂。。。。

cs clk gnd 这些代表什么意思，先弄明白了   然后编程是很简单的  就是一个入口main 函数，里面控制这些输出信号就行了

你需要烧写一个程序到这个板子上


Question: 文件读取

给你写了一个现成的，拿去用吧 #include<stdio.h> #include<stdlib.h> #include<string.h> #define LEN 40 int main(int argc,char *argv[]) {         FILE *in,*out;         int ch;         char name[LEN];         int count=0;         if(argc<2)              //检查命令行参数         {                 fprintf(stderr,"Usage:%s Filename\n",argv[0]);                 getchar();                 exit(1);         }         if((in=fopen(argv[1],"r"))==NULL)         {                 fprintf(stderr,"打开文件\"%s\"失败\n",argv[1]);                 getchar();                 exit(2);         }         strcpy(name,argv[1]);         strcat(name,".B");            //生成一个后缀为.B的新文件名         if((out=fopen(name,"w+"))==NULL)         {                 fprintf(stderr,"打开文件\"%s\"失败\n",name);                 getchar();                 exit(3);         }         while((ch=getc(in))!=EOF)               //         {                 if(ch>=0 && ch<= 9)//提取数字输出                 {                         putc(ch,out);                 }         }                  if(fclose(in)!=0||fclose(out)!=0)         {                 fprintf(stderr,"关闭文件\"%s\"或\"%s\"失败\n",argv[1],name);                 getchar();                 exit(4);         }         return 0; }

1.fopen打开A文件。 2.fgetc读取文件的一个字符 3.判断是否为数字，是则写入B文件，不是continue  4.循环2,直到读取到EOF。 gcc编译OK

引用 1 楼 user-4 的回复:vim不会编译vim只会编辑

vim不会编译


Question: 用VC6.0调试c语言代码，碰到输入输出语句会弹出窗口，然后崩溃。。。

因为如果用单步进入的话，就会进入到scanf函数的内部，所以崩溃了

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

单步调试用f10 不要用f11  功能自己查。

碰到过类似的，请楼主检查一下你的参数类型对不，比如scanf中的&

引用 2 楼 Zidane_2014 的回复:个人建议：路径尽量不要使用中文。+1

个人建议：路径尽量不要使用中文。

路径设置问题  你在option里 env里找找，应该是有工程路径没设置对，导致这个文件没有找到


Question: C程序猿怎么提升自己能力，需要掌握那些能力？

引用 24 楼 baijiaheizhiganmao 的回复:[quote=引用 23 楼 call_from_dream 的回复:] [quote=引用 22 楼 baijiaheizhiganmao 的回复:] [quote=引用 1 楼 call_from_dream 的回复:] 你的情况我很能理解。我勉强学完了C基础。VC++6.0出问题了，一直解决不了，结果卸载了重装都不行。非常崩溃！不用VC++6.0，咬牙自学Visual  Studio2005&2008.可发现卸载VC++6.0的时候，把Visual  Studio2005和Visual  Studio2008的组件也给误删了。现在Visual  Studio2005和Visual  Studio2008也使用不了。那种崩溃的感觉，作为菜鸟，如果心理不够强大，估计想死的心都有了 最简单的方法是将电脑C盘格式化以便，然后再重装vs。[/quote]电脑里装了很多其他软件，许多配置文件不能随便懂。C盘格式化后，我估计我真的想死了[/quote] 下次把其他的软件安装到其他盘，养成习惯。这样电脑就不会乱。 还有，安装一个系统最多花费你两小时（包括其他软件安装以及安装补丁。）你可以将有用的资料先备份到其他盘，如D盘，然后安装的时候先格式化c盘，再将系统安装到C盘，其他的盘是不会被格式化的。[/quote]格式化C盘对环境变量、注册表什么的有没有影响？电脑没光驱，可以把光盘里的东西Copy到U盘，用U盘装系统吗？

引用 25 楼 call_from_dream 的回复:[quote=引用 24 楼 baijiaheizhiganmao 的回复:] [quote=引用 23 楼 call_from_dream 的回复:] [quote=引用 22 楼 baijiaheizhiganmao 的回复:] [quote=引用 1 楼 call_from_dream 的回复:] 你的情况我很能理解。我勉强学完了C基础。VC++6.0出问题了，一直解决不了，结果卸载了重装都不行。非常崩溃！不用VC++6.0，咬牙自学Visual  Studio2005&2008.可发现卸载VC++6.0的时候，把Visual  Studio2005和Visual  Studio2008的组件也给误删了。现在Visual  Studio2005和Visual  Studio2008也使用不了。那种崩溃的感觉，作为菜鸟，如果心理不够强大，估计想死的心都有了 最简单的方法是将电脑C盘格式化以便，然后再重装vs。[/quote]电脑里装了很多其他软件，许多配置文件不能随便懂。C盘格式化后，我估计我真的想死了[/quote] 下次把其他的软件安装到其他盘，养成习惯。这样电脑就不会乱。 还有，安装一个系统最多花费你两小时（包括其他软件安装以及安装补丁。）你可以将有用的资料先备份到其他盘，如D盘，然后安装的时候先格式化c盘，再将系统安装到C盘，其他的盘是不会被格式化的。[/quote]格式化C盘对环境变量、注册表什么的有没有影响？电脑没光驱，可以把光盘里的东西Copy到U盘，用U盘装系统吗？[/quote] 格式还后原来的环境变量以及注册表全都没用了。 可以使用U盘安装系统，将系统解压到U盘后，插入U盘，开机时按Ｆ１２(或者其他)选择U盘启动，会进入安装界面。你可以学习一下，不是非常难。

引用 23 楼 call_from_dream 的回复:[quote=引用 22 楼 baijiaheizhiganmao 的回复:] [quote=引用 1 楼 call_from_dream 的回复:] 你的情况我很能理解。我勉强学完了C基础。VC++6.0出问题了，一直解决不了，结果卸载了重装都不行。非常崩溃！不用VC++6.0，咬牙自学Visual  Studio2005&2008.可发现卸载VC++6.0的时候，把Visual  Studio2005和Visual  Studio2008的组件也给误删了。现在Visual  Studio2005和Visual  Studio2008也使用不了。那种崩溃的感觉，作为菜鸟，如果心理不够强大，估计想死的心都有了 最简单的方法是将电脑C盘格式化以便，然后再重装vs。[/quote]电脑里装了很多其他软件，许多配置文件不能随便懂。C盘格式化后，我估计我真的想死了[/quote] 下次把其他的软件安装到其他盘，养成习惯。这样电脑就不会乱。 还有，安装一个系统最多花费你两小时（包括其他软件安装以及安装补丁。）你可以将有用的资料先备份到其他盘，如D盘，然后安装的时候先格式化c盘，再将系统安装到C盘，其他的盘是不会被格式化的。

引用 22 楼 baijiaheizhiganmao 的回复:[quote=引用 1 楼 call_from_dream 的回复:] 你的情况我很能理解。我勉强学完了C基础。VC++6.0出问题了，一直解决不了，结果卸载了重装都不行。非常崩溃！不用VC++6.0，咬牙自学Visual  Studio2005&2008.可发现卸载VC++6.0的时候，把Visual  Studio2005和Visual  Studio2008的组件也给误删了。现在Visual  Studio2005和Visual  Studio2008也使用不了。那种崩溃的感觉，作为菜鸟，如果心理不够强大，估计想死的心都有了 最简单的方法是将电脑C盘格式化以便，然后再重装vs。[/quote]电脑里装了很多其他软件，许多配置文件不能随便懂。C盘格式化后，我估计我真的想死了

引用 1 楼 call_from_dream 的回复:你的情况我很能理解。我勉强学完了C基础。VC++6.0出问题了，一直解决不了，结果卸载了重装都不行。非常崩溃！不用VC++6.0，咬牙自学Visual  Studio2005&2008.可发现卸载VC++6.0的时候，把Visual  Studio2005和Visual  Studio2008的组件也给误删了。现在Visual  Studio2005和Visual  Studio2008也使用不了。那种崩溃的感觉，作为菜鸟，如果心理不够强大，估计想死的心都有了 最简单的方法是将电脑C盘格式化以便，然后再重装vs。

引用 20 楼 xhw88398569 的回复:[quote=引用 19 楼 nadleeh123 的回复:] [quote=引用 楼主 xhw88398569 的回复:] 上班三周了，原来是学嵌入式的，不好找工作（当然自己学的也不行，大学都在逃课打游戏，后来感觉总这么下去不行，就开始自己学嵌入式）。就找了个做C开发的，网络信息安全的，公司比较小，做接口的这边缺人就让先用python（核心用C做的），学了两天做了两周这一块的。然后看了几天python的代码。  看完了比较闲了，想学C++就下了本《C++primer》 学C++，想做个简单的文本编辑器练练手，赵老师推荐看一下notepad++的源码，感觉很吃力。  自己反省了下：C语言本来就没有学好，却又想着学C++，有点浮躁了，也有点好高骛远，所以先打算学好C。  买几本书：《C primer plus》当初就是靠这本书学的C，《算法导论》，《你必须知道的495个C语言问题》但是感觉即使看完了，还是不会做什么啊，就像心跳、内存池、线程池这些都还是不会，即使下午看了一下内存池，但是还是不清楚具体该怎么应用。  现在还没接触到C语言的项目，经理给的python那本书看完了，当然没有仔细研究，大多是知道有哪个东西，那东西有什么用，大概怎么用。。。  有几个问题： 我看项目里他们说的心跳只是定时任务，我以前了解的是心跳防护，重启程序（也有点类似的地方）。 内存池里一般是使用一个块，来分配内存；还是使用多个块，根据不同的数据大小来选择使用合适的内存块分配？  另外：请大神知道学习的方向，算法，知识点，项目经验分别该怎么学。。。   谢了 c语言知识让你真正进入计算机世界的一把工具而已，真正学的是cpu，控制器/寄存器，硬件协议，操作系统[/quote]不是都抽象出来了么，为什么还那么重要啊？[/quote]  所以说有的人一行代码值几万,有的人一行代码不到一毛钱,关键是后者还累死累活的.

引用 19 楼 nadleeh123 的回复:[quote=引用 楼主 xhw88398569 的回复:] 上班三周了，原来是学嵌入式的，不好找工作（当然自己学的也不行，大学都在逃课打游戏，后来感觉总这么下去不行，就开始自己学嵌入式）。就找了个做C开发的，网络信息安全的，公司比较小，做接口的这边缺人就让先用python（核心用C做的），学了两天做了两周这一块的。然后看了几天python的代码。  看完了比较闲了，想学C++就下了本《C++primer》 学C++，想做个简单的文本编辑器练练手，赵老师推荐看一下notepad++的源码，感觉很吃力。  自己反省了下：C语言本来就没有学好，却又想着学C++，有点浮躁了，也有点好高骛远，所以先打算学好C。  买几本书：《C primer plus》当初就是靠这本书学的C，《算法导论》，《你必须知道的495个C语言问题》但是感觉即使看完了，还是不会做什么啊，就像心跳、内存池、线程池这些都还是不会，即使下午看了一下内存池，但是还是不清楚具体该怎么应用。  现在还没接触到C语言的项目，经理给的python那本书看完了，当然没有仔细研究，大多是知道有哪个东西，那东西有什么用，大概怎么用。。。  有几个问题： 我看项目里他们说的心跳只是定时任务，我以前了解的是心跳防护，重启程序（也有点类似的地方）。 内存池里一般是使用一个块，来分配内存；还是使用多个块，根据不同的数据大小来选择使用合适的内存块分配？  另外：请大神知道学习的方向，算法，知识点，项目经验分别该怎么学。。。   谢了 c语言知识让你真正进入计算机世界的一把工具而已，真正学的是cpu，控制器/寄存器，硬件协议，操作系统[/quote]不是都抽象出来了么，为什么还那么重要啊？

引用 楼主 xhw88398569 的回复:上班三周了，原来是学嵌入式的，不好找工作（当然自己学的也不行，大学都在逃课打游戏，后来感觉总这么下去不行，就开始自己学嵌入式）。就找了个做C开发的，网络信息安全的，公司比较小，做接口的这边缺人就让先用python（核心用C做的），学了两天做了两周这一块的。然后看了几天python的代码。  看完了比较闲了，想学C++就下了本《C++primer》 学C++，想做个简单的文本编辑器练练手，赵老师推荐看一下notepad++的源码，感觉很吃力。  自己反省了下：C语言本来就没有学好，却又想着学C++，有点浮躁了，也有点好高骛远，所以先打算学好C。  买几本书：《C primer plus》当初就是靠这本书学的C，《算法导论》，《你必须知道的495个C语言问题》但是感觉即使看完了，还是不会做什么啊，就像心跳、内存池、线程池这些都还是不会，即使下午看了一下内存池，但是还是不清楚具体该怎么应用。  现在还没接触到C语言的项目，经理给的python那本书看完了，当然没有仔细研究，大多是知道有哪个东西，那东西有什么用，大概怎么用。。。  有几个问题： 我看项目里他们说的心跳只是定时任务，我以前了解的是心跳防护，重启程序（也有点类似的地方）。 内存池里一般是使用一个块，来分配内存；还是使用多个块，根据不同的数据大小来选择使用合适的内存块分配？  另外：请大神知道学习的方向，算法，知识点，项目经验分别该怎么学。。。   谢了 c语言知识让你真正进入计算机世界的一把工具而已，真正学的是cpu，控制器/寄存器，硬件协议，操作系统

引用 15 楼 super_admi 的回复:1.需要掌握泡妞的能力，否则你会没老婆的； 2.需要掌握神侃的能力，否则你没法应付客户；  呵呵貌似可以从侧边了解问题

引用 14 楼 lovesmiles 的回复:书是看完了，感觉没有收获，我的建议就是看第二遍。因为你看第一次时仅仅是为了完成看书这个任务而去看书。很多内容你没有理解就翻过去了。看第二次效果会好很多。如果你tcp.socket这些还不熟悉，去看心跳之类的东西会非常吃力。多线程的基本功能也没有看过，就看内存池也是不知所云的太对了，C基础和进程、线程、数据结构都是这样，都知道些，简单的练习也会，但是一旦复杂点了就感觉力不从心了

C语言源代码实例200多个典型小程序 我希望你看这些代码，每一个都上机去调试一下 就像打游戏一样，去打通关，都搞熟悉了，可以差不多了

兴趣是最好的老师, 读码,写码

引用 11 楼 mujiok2003 的回复:python挺好的，很实用。 你也可以研究python编译器源码， C语言写的， 可以学习的东西很多。 说的是cpython

引用 6 楼 addsspu 的回复:[quote=引用 4 楼 addsspu 的回复:] 研究数据结构吧，用纯C语言实现，最好是有数据结构理论基础，然后是在实践中研究。 推荐两本书，严蔚敏《数据结构》，这个是用类c描述的，学习起来比较难，不过是经典，可配合李春葆的数据结构一起学，这个容易懂一些[/quote]《算法导论》里差不多都有，而且比较全面

引用 7 楼 xhw88398569 的回复:引用 4 楼 addsspu 的回复:研究数据结构吧，用纯C语言实现，最好是有数据结构理论基础，然后是在实践中研究。学的都是简单的链表，树，而且都是练习，图和哈希算法什么的都不会，反正得一步步来的  盗用赵老师的提醒：再牛×的老师也无法代替学生自己领悟和上厕所！

最好的办法，找个老师教，不懂什么问什么 瞬间学会一点点  入门了就好了


Question: 文件I/O函数

指针到结尾了，除非你重新打开，或者使用fseek让指针再指向开始位置

引用 1 楼 lovesmiles 的回复:你的in和out已经移到文件的末节了，要把它移到文件头，加上下面红色的二句  	fseek(out,0,SEEK_SET); 	while((ch=getc(out))!=EOF)              //打印文件内容 	{ 		putc(ch,stdout); 	} 	fseek(in,0,SEEK_SET); 	 while((ch=getc(in))!=EOF) 		 putc(ch,stdout); 指针到了末尾

38行之前加 fseek(out,0L,0);  42行之前加 fseek(in,0L,0);  原因么，你自己琢磨一下，呵呵~~~


Question: 【菜鸟贴】一个宏定义，在两个c文件都要用到。怎么办？

引用 1 楼 Cabbage_c 的回复:你这样描述谁知道啊，理论上这样是可行的，肯定是你中间出了什么问题。果然，解决了，感谢！

既然 是 宏定义 那么 只需要在 一个 C的头文件里面 定义 即可。  其他文件 只需要 引用 这个 头文件   而后 用 这个 宏即可

你这样描述谁知道啊，理论上这样是可行的，肯定是你中间出了什么问题。


Question: keil

你们都是大神好吗，我坑了

做事做的脑袋快爆了，没事上来打打酱油，没想到碰到了倒霉的LZ

不是说你的程序为定义main函数么， 那就看main函数啊，是main main！！！

引用 1 楼 JiMoKuangXiangQu 的回复:mian --> main  楼上正解，楼主键盘敲的太快！

mian --> main


Question: 标准库随机函数怎样使用？

参考下这个

用百度，google去搜索用法岂不是更快。。。 #include<stdlib.h>/*用到了srand函数，所以要有这个头文件*/ #include<stdio.h> #defineMAX10   intmain(void) {     intnumber[MAX]={0};     inti;     unsignedintseed;     scanf("%d",&seed);/*手动输入种子*/     srand(seed);     for(i=0;i<MAX;i++)     {         number[i]=rand()%100;/*产生100以内的随机整数*/         printf("%d",number[i]);     }     printf("\n");     return0; }

好像是srand产生一个类似key的值，rand根据这个值然后产生随机数，而且每次都是随机的，一次srand，后面rand都可以用。不知道对不对

我记得是直接用rand就行了吧


Question: 全局变量声明的问题

学习一下。。。

C 和C++ const 全局变量有所不同. C const 全局变量（没有写 static）也是外部变量，不要在头文件里初始化. C++ 似乎没问题，因为缺省 const 是 内部链接，也就是 相当于static const classX x={.....}; 其实C，没有真正的 const 类型的常量， 只有常量表达式,enum 常量，以及#define 常量 ， 而#define 常量仅仅是个替换。 对于C, const变量，例如 const T x=10;仅仅表示不可能通过名字x,直接修改x的值。 const Type * cp=a; 仅仅表示指针cp,不可修改所指向的对象*cp的值;  而C++中 const int x=100; 可以一定程度的，把x 看作常量表达式100. 因此 C++中 const 全局变量，被定义为内部链接。 不同实现文件中，可以有多个const int x=100; 所以可以写在 .h中。

我还发现一个问题，定义的时候用const， 在A.H声明的是也要加const的,但是在别的C文件声明就不需要了

A.h extern int g_test;  A.c #include "A.h" int  g_test = 0  B.c #include "A.h" printf("%d",g_test);

类、结构体声明在.h文件中；inline函数声明与定义在.h文件中；一般函数的声明也在.h中，一般函数的定义在.c文件中；声明全局变量必须加extern关键字，在.h文件中  我的智能创意，请支持一下！

加extern关键字就行了

声明全局变量的时候要用extern 在B.h中声明，如果加了extern应该也能编译，但是这样不好，还是放到A.h里面声明更合理。

在哪定义结构体 -- A.h 在哪定义结构体全局变量 -- A.c 在哪声明全局变量 -- A.h, 不要用B.h


Question: C用Direct Odbc连接Access，怎么存取二进制数据

您好，谢谢你的回复！在VS上工具菜单下的 连接到数据库 连接到Access后，查看那个字段类型为ole对象，在这个上面显示它的数据类型为：DbType.Binary，这个都显示了二进制类型了。今天又查了点相关资料，可以存二进制数据，但就是不知道怎么存进去和读出来，         InitSqlConn()；         rc = SQLAllocStmt(hDbc,&hStmt); 	rc = SQLPrepare(hStmt, execSql, SQL_NTS);  	/* Run the query and create a record set */ 	rc = SQLExecute(hStmt);  	rc = SQLFreeStmt(hStmt, SQL_DROP);         FreeSqlConn()； execSql为SQLCHAR*类型，放的就是sql语句

短的话直接当整数存，转化一下进制也行。长一点的话直接字符串存，再长一点直接当文件存。 基础不好可以多做一些语法算法题，简单的类似二级、蓝桥杯，会一点算法可以去ACM。 天天写代码写什么这个很难说，您可以去找一些小程序去做，例如:XX管理系统、俄罗斯方块、魂斗罗。 对窗口程序有兴趣可以学一下windows编程，到时候可以做一些界面比较华丽的东西。 对操作系统、驱动程序之类的感兴趣可以去看一下内核书，例如:windows内核原理与实现、linux内核详解，到时候可以试着写一下操作系统内核 对机器人之类的单片机编程有兴趣可以去学C51之类的 C语言内嵌汇编也是一个不错的工具 等等等等，当然您得先把基础打好


Question: 如何获得程序的返回值？

命令行？ cmd里运行完了， echo %errorlevel%

exec 吧

CMD下执行你的程序，然后 echo %errorlevel% 显示的就是你的程序的返回值

这个更明白了

我滴是答案，这个我关注过，你看图片就明白了 编译器会给你出的

如果要获得这个程序的返回值，请单步调试或者在最后设置断点。。。。。。。。。。

另外 同步的 _spawnl 函数，返回值就是子进程的退出码。

WIndows GetExitCodeProcess  可以得到子进程的返回值

这个返回值是返回给操作系统的 6L 的方法可行

2楼的答案就很好,我是初学者,这两天正在学函数调用,就是第二种方法,不过如果函数代码多的话,可以分开,一个声明,一个定义,主函数只负责调用就好了.

引用 6 楼 zxh707wk 的回复:把你的那份代码编译成exe文件，命名为temp.exe,然后将这段代码保存为一个新文件，编译运行 #include <stdio.h>  int main() { 	printf("%d\n",system("temp.exe")); 	return 0; } +10086

请学习批处理或者shell

dos可以用变量errorlevel http://blog.csdn.net/hudashi/article/details/7042237

引用 3 楼 user-12 的回复:linux里面可以用变量$?获取上一个命令的返回值 $ ./a.out $ echo $? 0  额 抱歉 是我没有说明！ 感谢你的回答 我用的是win8,1 编译器是vs2013

额 我是想获得程序的返回值。 不是想获得函数的返回值。。。。  引用 1 楼 zxh707wk 的回复:#include <stdio.h> [/u] int fun(int n)[/u] { 	if (n % 2 == 0)         return 2;     else         return 1; }  int main() {     int n;     printf("请输入一个数：");     scanf("%d", &n);     printf("%d\n",fun(n));     return 0; }  这样吗？

#include <stdio.h>  int fun(int n) { 	if (n % 2 == 0)         return 2;     else         return 1; }  int main() {     int n;     printf("请输入一个数：");     scanf("%d", &n);     printf("%d\n",fun(n));     return 0; }  这样吗？


Question: 求两个有序链表序列的交集 运行超时怎么办

引用 1 楼 user-1 的回复:你这个思路完全忽视了“有序”这个重要的条件。 我这个O(n+m)，我没测试，目测应该可以。 void find_inter(Node *pHead1, Node *pHead2) {   int found = 0;   while (pHead1 != NULL && pHead2 != NULL) {     if (pHead1->s < pHead2->s) {       pHead1 = pHead1->next;     } else if (pHead1->s > pHead2->s) {       pHead2 = pHead2->next;     } else {       found = 1;       printf("%d ", pHead1->s);       pHead1 = pHead1->next;       pHead2 = pHead2->next;     }   }   if (!found) {     printf("NULL");   }   printf("\n"); }  引用 1 楼 user-1 的回复:你这个思路完全忽视了“有序”这个重要的条件。 我这个O(n+m)，我没测试，目测应该可以。 void find_inter(Node *pHead1, Node *pHead2) {   int found = 0;   while (pHead1 != NULL && pHead2 != NULL) {     if (pHead1->s < pHead2->s) {       pHead1 = pHead1->next;     } else if (pHead1->s > pHead2->s) {       pHead2 = pHead2->next;     } else {       found = 1;       printf("%d ", pHead1->s);       pHead1 = pHead1->next;       pHead2 = pHead2->next;     }   }   if (!found) {     printf("NULL");   }   printf("\n"); }  引用 1 楼 user-1 的回复:你这个思路完全忽视了“有序”这个重要的条件。 我这个O(n+m)，我没测试，目测应该可以。 void find_inter(Node *pHead1, Node *pHead2) {   int found = 0;   while (pHead1 != NULL && pHead2 != NULL) {     if (pHead1->s < pHead2->s) {       pHead1 = pHead1->next;     } else if (pHead1->s > pHead2->s) {       pHead2 = pHead2->next;     } else {       found = 1;       printf("%d ", pHead1->s);       pHead1 = pHead1->next;       pHead2 = pHead2->next;     }   }   if (!found) {     printf("NULL");   }   printf("\n"); }  thx a lot，对对，想的太简单了，刚开始做算法题，开始以为是语言上面的问题


Question: 《The C programming Language》中的一个困惑

引用 7 楼 swgshj 的回复:引用Enumerations provide a convenient way to associate constant values with names, an alternative to #define with the advantage that the values can be generated for you. Although variables of enum types may be declared, compilers need not check that what you store in such a variable is a valid value for the enumeration. Nevertheless, enumeration variables offer the chance of checking and so are often better than #defines. In addition, a debugger may be able to print values of enumeration variables in their symbolic form. 上面是英文原文，我理解作者的意思是： 虽然枚举变量不提供枚举值的合法性检查，但是提供了（枚举）类型的检查的可能（取决于编译器如何设计），这比#define也是有优势的。 你说的“枚举变量”和“枚举类型的变量”应该是一回事。  补充一下，下面的例子可以看出，枚举类型提供了一定的检查，但是跟int类型类似（但不完全一样），也是存在一些隐式类型转换的，在符合编译器的隐式类型转换时，不会产生编译失败。                                                                 1,5           Top #include <stdio.h>  typedef enum month { JAN = 1, FEB, MAR, APR, MAY, JUN, JUL, AUG, SEP, OCT, NOV, DEC  }MON;  typedef struct {     int a;     int b; }STest;  void foo(MON mon) {     printf("Month=%d\n", mon);     return; }  int main() {     MON e_month;     int i_month = 1000;     float f_month = 1.11;     double d_month = 2.22;     char *p_month = "hello";     STest s_test = {0};      e_month = JAN;      //OK     e_month = 100;      //OK     foo(i_month);       //OK      e_month = i_month;  //OK          i_month = f_month;  //OK, no warning     e_month = f_month;  //OK, no warning          i_month = d_month;  //OK, no warning     e_month = d_month;  //OK, no warning      i_month = p_month;  //warning: assignment makes integer from pointer without a cast     e_month = p_month;  //error: incompatible types when assigning to type 'MON' from type 'char *'      i_month = s_test;   //error: incompatible types when assigning to type 'int' from type 'STest'     e_month = s_test;   //error: incompatible types when assigning to type 'MON' from type 'STest'      return 0; }   编译报错： [pc@server ~/c]$ gcc -Wall enum.c enum.c: In function 'main': enum.c:39: warning: assignment makes integer from pointer without a cast enum.c:40: error: incompatible types when assigning to type 'MON' from type 'char *' enum.c:42: error: incompatible types when assigning to type 'int' from type 'STest' enum.c:43: error: incompatible types when assigning to type 'MON' from type 'STest' [pc@server ~/c]$  GCC版本：  $ gcc -v Using built-in specs. Target: x86_64-redhat-linux Configured with: ../configure --prefix=/usr --mandir=/usr/share/man --infodir=/usr/share/info --with-bugurl=http://bugzilla.redhat.com/bugzilla --enable-bootstrap --enable-shared --enable-threads=posix --enable-checking=release --with-system-zlib --enable-__cxa_atexit --disable-libunwind-exceptions --enable-gnu-unique-object --enable-languages=c,c++,objc,obj-c++,java,fortran,ada --enable-java-awt=gtk --disable-dssi --with-java-home=/usr/lib/jvm/java-1.5.0-gcj-1.5.0.0/jre --enable-libgcj-multifile --enable-java-maintainer-mode --with-ecj-jar=/usr/share/java/eclipse-ecj.jar --disable-libjava-multilib --with-ppl --with-cloog --with-tune=generic --with-arch_32=i686 --build=x86_64-redhat-linux Thread model: posix gcc version 4.4.7 20120313 (Red Hat 4.4.7-3) (GCC)

引用 3 楼 moyac 的回复:enum WEEKDAY{Monday, Tuesday, Wednesday}; enum WEEKDAY w; 称enum WEEKDAY为枚举类型，称w为枚举变量，称Monday等为枚举值（好像也有叫枚举常量的）。 如果是这样的话，是不是说，枚举变量w的值是{0， 1 ，2}啊 是的

特意下个英文版的去看了下原话， 原话的大意是：编译器不需要检查你存放在枚举变量里面的值是否在枚举类型的值的范围内，但是编译器提供了检查的机会（这里说的检查应该是指类型的检查）。而且你可以在调试的时候输出枚举变量的值

那个例子不好， 强制类型转换（）跳过了类型检查。

枚举有类型检查， 类型更安全， 这是好事。


Question: C#替换路径的分隔符"\"为"|”

谢谢“FENGQIYUNRAN”的回答，我已经对你的创意投了一票哦

谢谢，你们的回答，非常感谢

我的智能创意，请支持一下http://html5tv.csdn.net/m/product/tcl/works_detail?id=2521&action=creative&product_type=12！

引用 1 楼 user-2 的回复:string path = @"G:\Files\Code\C#"; string path1 = path.Replace(@"\", "|");  正解，另一方法采用Regex正则的Replace替换方法也可 我的智能创意，请支持一下！


Question: socket 调用connect 异常 Transport endpoint is not connected.

引用 6 楼 hulongchuan 的回复:[quote=引用 1 楼 user-3 的回复:] 是不是地址没有写对。 地址没问题啊[/quote] 确实是IP地址的问题，IP地址是动态获取的，有时候IP前面带个空格， 做了一个过滤的处理，就好了，谢谢你啊！

也许是对端要求不能同时连接太多，或者断开和重连之间至少要间隔一定时间。  或者网络连接不稳定，错包太多（用netstat -s命令查看错包统计信息）。

引用 1 楼 user-3 的回复:是不是地址没有写对。 地址没问题啊

引用 2 楼 zmlovelx 的回复:用tcp & udp 调试工具查看下，能否连上服务器， 再用调试工具模拟个服务器，让客户端 连，这样就知道是哪端出现问题了。 我把程序单独拿出来， 只连接可以连上，一直不报错，但整个程序就有时候卡在这报错， 大概6次左右才能有一次正确连接上

引用 3 楼 zhao4zhong1 的回复:先得能ping或telnet通吧。 能ping通，也能telnet 那个端口

先得能ping或telnet通吧。

是不是地址没有写对。