Question: pthread条件变量问题

2楼给出了问题的原因了。

引用 3 楼 rejoy2009 的回复:[quote=引用 1 楼 q3733353520 的回复:]  #include <stdio.h> #include <pthread.h>  pthread_mutex_t count_lock; pthread_cond_t count_nonzero; unsigned count = 1;  #define MAX_COUNT 100  void mutex_clean(void *mutex) { 	pthread_mutex_unlock((pthread_mutex_t *) mutex); }  void *decrement_count(void *arg) { 	while (count < MAX_COUNT) 	{ 		pthread_mutex_lock(&count_lock); 		printf("decrement acq lock\n"); 		while(count % 2 != 0) 		{ 			printf("%d\n", count);  //放进来  			pthread_cond_wait(&count_nonzero, &count_lock); 		} 		pthread_mutex_unlock(&count_lock); 	//	Sleep(1); 	} 	return NULL; }  void *increment_count(void *arg) {     int i;     for (i = 0; i < MAX_COUNT; i++)     { 		pthread_mutex_lock(&count_lock); 		count++; 		pthread_cond_signal(&count_nonzero); 		pthread_mutex_unlock(&count_lock); 	  //	Sleep(1);     }     return NULL; }  int main(void) { 	pthread_t tid1, tid2;  	pthread_mutex_init(&count_lock, NULL); 	pthread_cond_init(&count_nonzero, NULL);  	pthread_create(&tid1, NULL, decrement_count, NULL); 	//Sleep(2); 	pthread_create(&tid2, NULL, increment_count, NULL);  	pthread_join(tid1, NULL); 	pthread_join(tid2, NULL);  	return 0; }   发现一般死循环是打印101,所以，是加到了101,然后唤醒 decrement_count，而 101%2  为1 又使 decrement_count 挂起，但是  increment_count 进不去for 那么线程结束，但是 decrement_count 一直在等待唤醒而没有结束那为啥加了Sleep就可以了呢？[/quote]  可能加到 100的时候 decrement_count在sleep而increment_count加到了101（时间很短）, 唤醒decrement_count时还在sleep，那么 decrement_count在sleep完后直接结束线程

引用 1 楼 q3733353520 的回复: #include <stdio.h> #include <pthread.h>  pthread_mutex_t count_lock; pthread_cond_t count_nonzero; unsigned count = 1;  #define MAX_COUNT 100  void mutex_clean(void *mutex) { 	pthread_mutex_unlock((pthread_mutex_t *) mutex); }  void *decrement_count(void *arg) { 	while (count < MAX_COUNT) 	{ 		pthread_mutex_lock(&count_lock); 		printf("decrement acq lock\n"); 		while(count % 2 != 0) 		{ 			printf("%d\n", count);  //放进来  			pthread_cond_wait(&count_nonzero, &count_lock); 		} 		pthread_mutex_unlock(&count_lock); 	//	Sleep(1); 	} 	return NULL; }  void *increment_count(void *arg) {     int i;     for (i = 0; i < MAX_COUNT; i++)     { 		pthread_mutex_lock(&count_lock); 		count++; 		pthread_cond_signal(&count_nonzero); 		pthread_mutex_unlock(&count_lock); 	  //	Sleep(1);     }     return NULL; }  int main(void) { 	pthread_t tid1, tid2;  	pthread_mutex_init(&count_lock, NULL); 	pthread_cond_init(&count_nonzero, NULL);  	pthread_create(&tid1, NULL, decrement_count, NULL); 	//Sleep(2); 	pthread_create(&tid2, NULL, increment_count, NULL);  	pthread_join(tid1, NULL); 	pthread_join(tid2, NULL);  	return 0; }   发现一般死循环是打印101,所以，是加到了101,然后唤醒 decrement_count，而 101%2  为1 又使 decrement_count 挂起，但是  increment_count 进不去for 那么线程结束，但是 decrement_count 一直在等待唤醒而没有结束那为啥加了Sleep就可以了呢？

如果A线程还没执行到wait处，B线程就发送了信号，那么A执行到wait时依然会阻塞即得不到唤醒。


Question: typeof问题

引用 1 楼 user-3 的回复:应该是不可以的，这个应该是gcc的扩展吧。 语义上有点类似typedef定义一个类型别名。 从搜索到的资料上看，使用这个操作符有两种形式的参数 一种参数是表达式：显然如果你直接typeof(member)是不行的，因为member到底是那个结构体的成员不得而知。 而typeof( ((type *)0)->member )有足够的信息获取member这个成员类型 第二种参数是类型定义符：  比如 typeof(int*)这种 明白了，以前以为给个变量就能直接知道变量类型了。

有很多blog分析这个macro的 http://www.cnblogs.com/Anker/p/3472271.html

这个宏，很吊的黑客技术！感觉linux有了它，很多工作才成为可能！ 不可以，当它要访问的是结构体的成员！它必须知道结构体的结构信息，才能取得成员member。如果替换成typeof( (member )就识别不了它是结构体的成员，成为一种未定以行为！这个宏主要用处就是知道成员，反查出结构体的基值！kernel用处多多！


Question: 最简单的递归知识，不懂求解释

引用 9 楼 xia_xiao_xiao 的回复:什么一级级往上返回？返回的时候没有声明变量是怎么保存这些值的？  当一个函数执行时，调用它的那个函数还在呢。被调用的函数返回后，调用它的函数接着执行。明白？

《C专家编程》对应章节讲解

什么一级级往上返回？返回的时候没有声明变量是怎么保存这些值的？

当N=1的时候，不是直接return返回1了吗？直接结束函数了吗？什么一级级返回。听不懂啊

是搞不清楚那些数字是怎么存放的，也没有变量是怎么存放的？

首先我要简化一下你的函数定义（本人有代码洁癖，再说C表达能力强，写臃肿的代码是对C的侮辱。不要告诉我什么可读性，什么可维护性，都是狗屁。忘了那些该死的规则吧）： long f (int n) {     return (n == 1) ? n : f (n-1) * n; }  1，在一个函数内部可以调用另一个函数，并使用那个函数的返回值。这个过程是递归的。 2，你可以将递归地调用自己想像成调用的是其它函数：函数f调用f1，f1调用f2……一直调用到n==1时，一级一级返回。而返回到每一级时，那一级的函数使用下一级的返回值。

当n=6是，走else， 当n=5时，走else， 当n=4时，走else， 当n=3时，走else， 当n=2时，走else， 当n=1时，走if，此时返回1， 然后return 2×f(1)=2, 然后return3×f(2)=6, 然后return4×f(3)=24, 然后return5×f(4)=120, 然后return6×f(5)=720,  诺，720就是最后结果，也就是6的阶乘

什么fun，说清楚啊，我是新手

fun里边打个断点，查看n的变化

有具体步骤吗？比如先执行哪一步，然后又是哪一步？

跟着程序一步一步往下执行就明白了 第一次调用 n =6  -> f(6-1) * 6; ->f(5-1) * f(6-1) * 6; ->f(4-1) * f(5-1) * f(6-1) * 6; ->f(3-1) * f(4-1) * f(5-1) * f(6-1) * 6; ->f(2-1) * f(3-1) * f(4-1) * f(5-1) * f(6-1) * 6; ->1 * f(2-1) * f(3-1) * f(4-1) * f(5-1) * f(6-1) * 6;   //这里满足n==1， 函数return， 于是一级级往上返回，  递归的两个要素，一定要有退出条件，  n个步骤必须能拆分为n-1个步骤。


Question: keil 警告问题

引用 5 楼 sholber 的回复:才发现，这题仅仅20分，你说我何苦费这个劲。 分少，谅解，20分都给你了

MDK编译会有警告类型不匹配，但是运行的时候是没有问题的。

参数类型不一致。。。

才发现，这题仅仅20分，你说我何苦费这个劲。

引用 1 楼 zhao4zhong1 的回复:我觉得没问题。 引用 2 楼 a30037338 的回复:那你定义的时候就 把unsigned char 8* 改成 const char *， kell对类型要求很严格， 或者用数组来存字符串 引用 3 楼 sprawling 的回复:这个有没有问题看实际情况，这样不规范的用法应当避免，不能说你错，但是可以有多种解释。  说没有问题的赵老湿，建议再看看书。说keil对类型要求很严格，这是夸keil呢，还是贬低keil？这不是keil的问题。说有没有问题看实际情况，这个实际情况是什么情况？唵？  翻一下ISO/IEC 9899:201x Committee Draft 文件N1570，strlen函数的原型如下： # include <string.h> size_t strlen (const char * s); 很清楚，strlen函数的参数类型是const char *。  N1570，6.5.2.2 Function calls In preparing for the call to a function, the arguments are evaluated, and each parameter is assigned the value of the corresponding argument. 这即是说，参数传递类似于赋值。那么，我们再看赋值时，如果=运算符左右两个操作数都是指针类型时，有什么样的要求--> N1570，6.5.16.1 Simple assignment the left operand has atomic, qualified, or unqualified pointer type, and (considering the type the left operand would have after lvalue conversion) both operands are pointers to qualified or unqualified versions of compatible types, and the type pointed to by the left has all the qualifiers of the type pointed to by the right; 简言之，左右两个指针所指向的类型，在去掉限定符后，应当是兼容类型。而且，左边那个指针所指向的类型，应当具有右边那个指针所指向的类型的所有限定符。 因为strlen函数的参数类型是const char *，传递给该函数的参数类型是unsigned char *，那么， 1，左边指针所指向的类型具有const限定符，右边指针指向的类型没有限定符。可以视为，左边指针指向的类型具有自己的限定符const，加上右边指针所指向的类型的限定符（无）。这一条件通过； 2，两个指针所指向的类型在去掉限定符后，一个是char，另一个是unsigned char。不管char等价于unsigned char，还是等价于signed char，它们都是三种彼此不兼容的类型。问题就出在这里。  N1570，6.2.7  Compatible type and composite type Two  types  have compatible type if their types are the same.  N1570，第45页，注脚45： CHAR_MIN, defined in <limits.h>, will have one of the values 0 or SCHAR_MIN, and this can be used to distinguish the two options.  Irrespective of the choice made,char is a separate type from the other two and is not compatible with either.

我觉得没问题。


Question: 新手菜鸟的简单问题，关于函数参数的

引用 3 楼 FightForProgrammer 的回复:printf函数不就是这样么。 http://blog.csdn.net/fengrx/article/details/4135090 三q

引用 2 楼 starytx 的回复:搜索”C 不定参“ 谢谢星哥

引用 1 楼 march0912 的回复:省略形参，具体的自己去看书吧！ 谢谢大哥

参数个数不确定，所以省略。在函数的开始处，可以用宏把参数个数和具体的参数内容解析出来。

传送门：省略形参

搜索”C 不定参“

省略形参，具体的自己去看书吧！


Question: 怎么让BitBlt生成BMP图片是黑底红字~~求助~~~~

都解决 了，那就接分吧

那我就不凑热闹了，免的被踩死。

问题已经解决了，随便散分了散分了....

我生成后的效果是这样的， 明显不对，我要的是黑底，红字，大神帮忙看看

我要的效果是黑底红字，但是生成的效果是背景是黑色，但是字的部分是红底黑字

看看，我说的吧，4楼就刚刚在我眼前被活活踩死了。那叫一个惨哪！可惜没拍下来传到网上！


Question: 如何将const类型的数组从中间开始取出值给const类型的变量

ptrData = Special_CharInfo_tbl; 这句，还不如你这句： *((CharInfo**)&ptrData) = (const CharInfo*)&Special_CharInfo_tbl[10]； 你当大家都是傻瓜？

引用 20 楼 sholber 的回复:光给分算怎么回事？ 起码说说俺的办法好用不 明显不如12楼好用！

光给分算怎么回事？ 起码说说俺的办法好用不

引用 18 楼 sholber 的回复:[quote=引用 17 楼 zhao4zhong1 的回复:] 电脑内存或文件内容只是一个一维二进制字节数组及其对应的二进制地址； 人脑才将电脑内存或文件内容中的这个一维二进制字节数组及其对应的二进制地址的某些部分看成是整数、有符号数/无符号数、浮点数、复数、英文字母、阿拉伯数字、中文/韩文/法文……字符/字符串、汇编指令、函数、函数参数、堆、栈、数组、指针、数组指针、指针数组、数组的数组、指针的指针、二维数组、字符点阵、字符笔画的坐标、黑白二值图片、灰度图片、彩色图片、录音、视频、指纹信息、身份证信息……  推荐使用WinHex软件查看硬盘或文件或内存中的原始字节内容。 没想到赵丝老湿是用WinHex听音乐看大片的啊……follow u[/quote] 嗯，这样才能看得更深入，更本质嘛！

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

引用 15 楼 sholber 的回复:屁大个事，争得脸红脖子粗，看，把赵四老湿都急出汗来了。少废话，赶快结帖给分。赵老湿零分！ 不要纠结各种常量了，这个世界上唯一不变的就是变化。用API WriteProcessMemory还能修改正运行的其它进程的内存里面的所谓常量呢！

没见过const数组。你给出一个例子呗。不要告诉我是  const int a [22];  这不是const数组，是const int类型的数组，元素类型是const int。而我需要数组本身是const的。

引用 2 楼 FightForProgrammer 的回复: 引用 3 楼 starytx 的回复: 引用 4 楼 zhao4zhong1 的回复: 引用 5 楼 ForestDB 的回复:  感谢大家的回复，我的描述只是表达了代码的逻辑，实际上的代码很多，所以看起来很乱，const不能去掉，这个ptrData在整个工程里其他地方已经用的很频繁了，它实际上是结构体里面的一个元素，而包括它的结构体又是另一个结构体的元素，且不是const了，所以不需要初始化。  现在我将一个数组拆成两个数组解决了，帖子先留在这，看有没有更好的方法

引用 1 楼 user-7 的回复:你的ptrData是const u8* 类型? 如果是，就这样 ptrData=Special_Char_FillVol5+80仔细看，我的ptrData是const CharInfo*  类型

copy一份。

把const去掉！  不要纠结各种常量了，这个世界上唯一不变的就是变化。用API WriteProcessMemory还能修改正运行的其它进程的内存里面的所谓常量呢！

如2楼所说，const要初始化的，要不然之后怎么赋值呢，因为他是const。总之你的描述有点乱

const类型定义的时候就给它初始化，要么就不要用const啊。为啥一定要呢。  const CharInfo*     ptrData = ...;定义的时候初始化试试？

const CharInfo*     ptrData;  这句，ptrData本身不是const限定的，它指向的类型才是限定的，怎么说ptrData只读呢？不是的。  你想取数组第80个元素的值，那很简单嘛： /*  **以下，数组Special_CharInfo_tbl转换为指向其首元素的指针。即，转换为 **const CharInfo  *。这正好与=运算符左边ptrData的类型一致，可以赋值。 */ ptrData = Special_CharInfo_tbl;   /*  **以下通过ptrData取出数组元素的值，并赋给x。 **表达式ptrData [0]的类型是const CharInfo； **表达式ptrData [0].pData的类型是const u8 *； **表达式ptrData [0].pData [80]的类型是const u8； */ u8 x = ptrData [0].pData [80]; 格式一下，美观美观。

这次才认真看了你的问题。 说实话，没太明白你这题目的意思。 const CharInfo*     ptrData; 这句，ptrData本身不是const限定的，它指向的类型才是限定的，怎么说ptrData只读呢？不是的。 你想取数组第80个元素的值，那很简单嘛： /* **以下，数组Special_CharInfo_tbl转换为指向其首元素的指针。即，转换为 **const CharInfo  *。这正好与=运算符左边ptrData的类型一致，可以赋值。 */ ptrData = Special_CharInfo_tbl;  /* **以下通过ptrData取出数组元素的值，并赋给x。 **表达式ptrData [0]的类型是const CharInfo； **表达式ptrData [0].pData的类型是const u8 *； **表达式ptrData [0].pData [80]的类型是const u8； */ u8 x = ptrData [0].pData [80];


Question: 如何定义数据格式

用两个字节去表示“UPDATE"字符，除非你用枚举类型吧，两个字节存储6个字节的内容是不现实的。

引用 4 楼 u013163178 的回复:[quote=引用 3 楼 zhao4zhong1 的回复:] 为什么要有数据结构这个东东？ 因为要将现实世界或者抽象理论中的各种数据保存在计算机外存（光盘、硬盘、U盘……）或内存（ROM、RAM、SRAM……）里面的二进制字节数组中。 然后让CPU这个只会执行预先保存好的加减乘除移位条件转移……等机器指令的家伙按照人的意志去处理这些数据。至于具体如何处理就是所谓算法。赵老师，什么是数据格式，什么是文件格式[/quote] http://www.baidu.com/s?wd=%E6%95%B0%E6%8D%AE%E6%A0%BC%E5%BC%8F%20%E6%96%87%E4%BB%B6%E6%A0%BC%E5%BC%8F&rsv_spt=1&issp=1&f=8&rsv_bp=0&rsv_idx=2&ie=utf-8&tn=baiduhome_pg

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

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

0-1字节是报文头“UPDATE”   你觉得2个字节能装下“UPDATE” 这么多东西吗.  一般是这样处理;   定义一个2字节的包头常量:  #define UPDATE  0x1FF1   //这个字段最好是能达到4字节以上, 否则很容易被其它数据匹配,  定义2字节的产品名, 可以是一张表.当然如果可以更长些, 那么可以使用字符串.  如果2字节, 那就写在表的索引. 然后是版本号;  内存数据就是这个样子:  F1 1F 01 20 01 00  然后转化成一个结构体就是这样; struct Data {      WORD wHeadFlag;      WORD wNameIndex;      WORD wVersion; };  struct Data da; da.wHeadFalg = 0x1FF1; da.wNameIndex = 0x2001 da.wVersion = 0x0001  BYTE *pBuf = (BYTE*)&da; 这时pBuf指向的数据就是这个样子  F1 1F 01 20 01 00


Question: 紧急求助：如何把文本里面的汉字转换为中国的形式

#include <stdio.h> #include <windows.h> int main() {     char gbk[]="中国";     wchar_t wc;     char d[256];     int i;      d[0]=0;     for (i=0;i<2;i++) {         MultiByteToWideChar(CP_ACP,MB_PRECOMPOSED,gbk+i*2,2,&wc,1);         sprintf(d,"%s&#%d;",d,wc);     }     printf("%s",d);      return 0; } //中国

就是UNicode

up@ updwn


Question: C语言 嵌入式 数组 指针 定义

恩，明白了，谢谢各位~

方法2只是定义的同时赋初始值， 其等同于 uchar *p; p=Number; 不能理解为 uchar *p; *p=Number;

还理解个屁！ 你所要做的，是理解赋值运算符和声明（包括初始化器）这两个东西的形式。

在C语言核心技术中提到，你的uchar *p=Number 只是初始化，是一条声明。而楼上的那种是一种赋值语句，编译器用不同的方式对待两者。所以第一种第二种都是正确的！

你的方法2也是正确的；  多一个方法3： uchar Number[6]={0,0,0,0,0,0}; uchar *p; *p=Number; 这个才是错误的。。。正如你所理解，p是一个指针，它只想一个地址，但这个地址里面的内容不应该用数组number的地址编号来赋值


Question: 一个C工程 vc6.0引用库正常，VS08出现连接错误

工程、设置、Link、分类：Input、附加库路径：填写附加依赖库所在目录 分号间隔多项 工程、设置、Link、分类：Input、对象/库模块：填写附加依赖库的名字.lib 空格间隔多项

不同版本的C++编译器不能兼容，你要把GMP用VS2008重新编译，然后再引用lib文件


Question: 字符串传递之后数据没传全，具体看一楼

该文件所在工程是多字节字符集格式的


Question: 求大神看看哪里错了

#define max 1000 #define temp 1 //下移，遵守下定义后使用的原则 typedef struct name {     char lastname[max];     char secondname[max];     char firstname[max]; }Name; typedef struct personal {     int ID;     Name person; }P; void print(P s);  另外，宏定义建议你使用大写$define    MAX    32 从你定义的名字数组的长度可以看出你真是“内存大款”，平时测试能用到1000个字节吗？所以，根据需要定义数组的长度，因为这些在实际操作中都是需要考虑内存呢，当然你这是局部变量还好。从这个定义可以看出你是一个新手，不过我也是这样过来的，对内存的分配还是要“吝啬”一些，需要多少，分配的时候只要比需要的多分配一些，就可以。

将print函数的声明放到结构体定义的后面


Question: 今天这个问题我已疯 只求解释

引用 37 楼 zhao4zhong1 的回复:[quote=引用 33 楼 misskissC 的回复:] [quote=引用 18 楼 zhao4zhong1 的回复:] 有时越是常识性问题，越难理解和学会。 何解[/quote] 比如 程序员的常识之一：不要将程序源代码或项目或exe放在桌面这种复杂（多半带空格和汉字且在防火墙或杀毒软件严密控制的C盘上）的目录下。 [/quote] 赵老湿，那怎么补常识

引用 33 楼 misskissC 的回复:[quote=引用 18 楼 zhao4zhong1 的回复:] 有时越是常识性问题，越难理解和学会。 何解[/quote] 比如 程序员的常识之一：不要将程序源代码或项目或exe放在桌面这种复杂（多半带空格和汉字且在防火墙或杀毒软件严密控制的C盘上）的目录下。

我感觉入手《Linux程序设计》，前面几章看看先入门为好。

引用 38 楼 misskissC 的回复:[quote=引用 37 楼 zhao4zhong1 的回复:] [quote=引用 33 楼 misskissC 的回复:] [quote=引用 18 楼 zhao4zhong1 的回复:] 有时越是常识性问题，越难理解和学会。 何解[/quote] 比如 程序员的常识之一：不要将程序源代码或项目或exe放在桌面这种复杂（多半带空格和汉字且在防火墙或杀毒软件严密控制的C盘上）的目录下。 [/quote] 赵老湿，那怎么补常识[/quote] 多犯常识性错误并及时纠正。

./a.out

这么长时间还不结帖，论坛的人都已疯

引用 18 楼 zhao4zhong1 的回复:有时越是常识性问题，越难理解和学会。 何解

居然还有闲情回复我……有这个功夫，还不如直接翻翻LINUX编程指南之类的书籍，问题就解决了。  引用 14 楼 zy_dream 的回复:[quote=引用 12 楼 super_admi 的回复:] 目测楼主是来秀下限的。   呵呵是啊  我就是来秀的 怎么 影响到你了？您是大神 NB嘛  我很坦诚的说我自己才开始学习 自己学习 就什么都不知道 才要学习  任你怎么说[/quote]

引用 18 楼 zhao4zhong1 的回复:有时越是常识性问题，越难理解和学会。是滴，入门最难

linux下就不想ＩＤＥ一键直达了

既然都会了，就给分吧，俺是来接分滴。

引用 11 楼 zy_dream 的回复:[quote=引用 4 楼 firetreeSF 的回复:] 简单来说，执行以下两步即可： 1.     $gcc -o h h.c 2.     $./h   多谢多谢 终于可以运行了 因为我们上学期学的是python 那在vim下怎么很简单的样子 所以到c这块自己完全不太清楚[/quote]  其实这是Linux系统的基础知识，和语言本身无关，补Linux基础推荐《鸟哥的私房菜基础篇》

有时越是常识性问题，越难理解和学会。

引用 13 楼 zy_dream 的回复:[quote=引用 10 楼 lucifer886 的回复:] 醉了……你手上没资料么？ 已经知道了 超新手 没有关于vim的资料 只有C primer plus[/quote]看下鸟哥的私房菜吧

1.     $gcc -o h h.c 2.     ./h  有的时候 得到一个答案是一件很简单的事  但是很少有人会反思在答案背后的东西，如果你可以对这俩行代码做了背后到底做了什么有所了解，就已经迈出C语言的第二步了，或者说编译型语言的第二步。如果你连想都没想 怎么这俩条命令就可以执行的话，那你就已经走错路了。  这个俩行操作 涵盖了四个过程 :1 预处理 2 编译 3 汇编 4 链接

Linux的哲学，no news is good news。 cc h.c 没有报任何错误，说明该命令执行成功。 只是该命令只是把h.c编译成a.out而已。 如果要执行编译好的程序，还有这样： ./a.out

引用 12 楼 super_admi 的回复:目测楼主是来秀下限的。   呵呵是啊  我就是来秀的 怎么 影响到你了？您是大神 NB嘛  我很坦诚的说我自己才开始学习 自己学习 就什么都不知道 才要学习  任你怎么说

引用 10 楼 lucifer886 的回复:醉了……你手上没资料么？ 已经知道了 超新手 没有关于vim的资料 只有C primer plus

目测楼主是来秀下限的。

引用 4 楼 firetreeSF 的回复:简单来说，执行以下两步即可： 1.     $gcc -o h h.c 2.     ./h   多谢多谢 终于可以运行了 因为我们上学期学的是python 那在vim下怎么很简单的样子 所以到c这块自己完全不太清楚


Question: C语言求助！！！

引用 2 楼 configerss 的回复:指针不大会啊，能帮忙改下吗？相当于把m代入f中，再用gs积分 // HELK.cpp : Defines the entry point for the console application. //  #include "stdafx.h" #include<stdio.h> #include<math.h>  //高斯公式 并没有给你改成你想要的直接答案 只提示你出错在哪里   /*typedef double (*D_dd_Fun_Ptr)(double,double);*/  double fun(double x,double m); double gs(double f(double x,double m),double a,double b);//这种写法 已经把第一个参数声明为了函数指针    int main() {     /*D_dd_Fun_Ptr f = fun;*/     double a,b,s,m,x;     //b,a为积分上下限     a=0.0;b=1.0;m=1.0;     s=gs(fun,a,b);// gs的第一个参数 你定义为了函数指针 这就不能传入gs(fun(x,m),a,b);     printf("s=%lf\n",s);     return 0; } double fun(double x,double m)      //积分函数 {     return (m+x*x); }  double gs(double f(double x,double m),double a,double b)  //高斯积分法 {     double z1,z2,h,d,h0,eps,pi;     int i,j,n;     n=1;eps=0.000001;pi=3.1415926525;     z1=z2=0.0;     static double x[5]={-0.906179845938664,-0.538469310105683,0.0,0.538469310105683,0.906179845938664};     static double A[5]={0.236926885056189,0.478628670499366,0.568888888888888,0.478628670499366,0.236926885056189};     h0=fabs(0.001*(b-a));     h=(b-a)/n;     for(i=0;i<n;i++)         for(j=0;j<5;j++)             z1+=A[j]*f(h*(x[j]+2*i+1)/2.0+a,double(0)); // 你程序 f已经是函数指针 而你只传了一个参数      z1=z1*h/2.0;     do     {         n=2*n;         h=h/2.0;         for(i=0;i<n;i++)             for(j=0;j<5;j++)                 z2+=A[j]*f(h*(x[j]+2*i+1)/2.0+a ,double(0)); // 你程序 f已经是函数指针 而你只传了一个参数         z2=z2*h/2.0;         d=fabs(z2-z1);         z1=z2;     }     while((d>eps)&&(h>h0));     return z1; }

指针不大会啊，能帮忙改下吗？相当于把m代入f中，再用gs积分

double gs(double f(double x,double m),double a,double b);  这种写法 貌似不存在吧   这种声明编译器不认 如果需求要传这种形式 可以以函数指针的方式存进去。  或者 用其他的实现方式 达到你想要的目的。实际问题转换成语言是要一定规则的，你可以把问题拆分成小问题。  一步步的实现，调用小的函数，在组合成你要的，如果你一定要按照这种实现，可以看看函数指针。


Question: c primer plus 第6章练习题16

引用 4 楼 u013163178 的回复:#include<stdio.h>  int remain_money(double n) { 	static int cnt = 0; 	double remain; 	remain = n * (1 + 0.08) - 10.0; 	cnt++; 	if( remain > 0) 		remain_money(remain); 	else 		return cnt; }  int main(int argv,char **argc) { 	printf("%d\n",remain_money(100.0)); 	return 0; }   感谢你的解答，我还想请问下main函数后面括号里的2个变量的用法，请不吝赐教，谢谢、

#include<stdio.h> int year(double); int main(void) { printf("年数为：%d",year(108.)); return 0; } int year(double money) { int years=1; double remain=money*(1+8./100)-10; while(remain>=0) { remain=remain*(1+8./100)-10; years++; } return years; }

这都不会，还怎么理财。

年金公式直接算答案

这不是数学公式吗

每年还需要取出来10W呢，你没有在总数里面减去


引用 4 楼 u011608191 的回复:程序员面试宝典上看到的 改为这样后：     unsigned int a = 0xFFFFFFF7;     unsigned char i = (unsigned char)a;     unsigned char * b = (unsigned char *)&a;     unsigned  char c = 0xFFFFFFF8;      printf("%08x,  %08x,   %08x  , %d\n",i,*b,c,sizeof(c));      结果是：     000000f7    000000f7    000000f8      1      得到的结果是：char类型是fffffff7  ，  unsigned char 是000000f7  这是不对的。 C/C++中有个字符类型, char, signed char, unsigned char。 其中char可能是signed char, 也可能是unsigned char, 这个取决于编译器。  一个结果取决于编译器实现的结果，当然是不确定的。

不要迷信书、考题、老师、回帖； 要迷信CPU、编译器、调试器、运行结果。 并请结合“盲人摸太阳”和“驾船出海时一定只带一个指南针。”加以理解。 任何理论、权威、传说、真理、标准、解释、想象、知识……都比不上摆在眼前的事实！  有人说一套做一套，你相信他说的还是相信他做的？ 其实严格来说这个世界上古往今来所有人都是说一套做一套，不是吗？  不要写连自己也预测不了结果的代码！

我最后就我的理解做一下总结： 1，输出时，%x,是按照整形来输出的，会将字符转换为整形进行输出。 2，如果是无符号字符，其最高位不是符号位，在转换时补0。 3，如果是有符号字符，其最高位是符号位，在转换时，会用符号位补齐。  所以，就会出现我提到的现象。  这是我的理解，如有问题，请多多指教。

题目不大，其中的东西不少 可怜的人，你都不了解printf，也不了解类型转换，也不了解整数提升，也不知道常规算术转换…… 最重要的，你不明白char可能等价于unsigned char，也可能等价于signed char，所以，结果也就不好说了……

引用 7 楼 u013163178 的回复:#include<stdio.h> int main(int argv, char **argc) { 	unsigned char a = 'c'; 	printf("%08x",a);  	return 0; }+1,类型转换不对

不管什么宝典都是个错题。

char 只有1个字节  但是 %x 会处理4个字节的数据

这是一个面试题

你输出格式错了 这种情况下 再分析都意义不大

你是以16进制的形式输出的，即以unsigned int类型输出的。


Question: 用writefile函数可以修改文件内容吗？

引用 4 楼 sholber 的回复:赵老湿不要告诉我你用的是瑞星…… 我用的是McAfee

赵老湿不要告诉我你用的是瑞星……

引用 1 楼 zhao4zhong1 的回复:关掉杀毒软件。 #include <windows.h> #include <stdio.h> int main() { char buffer[11]={0x6F,0x68,0x6D,0x79,0x67,0x6F,0x64,0x21,0x21,0x21,0x21}; DWORD dwWriteSize=11; HANDLE hFile = CreateFile("c:\\1.exe",     //创建文件的名称。    GENERIC_WRITE,          // 写文件。    0,                      // 不共享读写。                                    NULL,                   // 缺省安全属性。                                    OPEN_EXISTING,          // 如果文件存在，则打开。                                    FILE_ATTRIBUTE_NORMAL, // 一般的文件。                                             NULL);                 // 模板文件为空。   SetFilePointer(hFile,0x4B383,0,FILE_BEGIN);         WriteFile(hFile,buffer,sizeof(buffer),&dwWriteSize,NULL);  CloseHandle(hFile);  return 0; }   窝哈哈哈，赵老湿，我闻到你学术上的腐朽味道罗…… 既然 dwWriteSize没有什么用处，为什么不这样写： WriteFile (hFile, buffer, sizeof (buffer),& (DWORD) {11}, NULL); 关掉杀毒软件……赵老湿原来不是裸奔……

你的代码可以，注意偏移，PE文件最好用filemapping


Question: 马上就要期末考试了， 函数指针还有些不明白

int fun(int (*p)(),int a,int b)//在变量声明或函数参数声明中，*前缀表示指向某类型的指针 {  return (*p)(a,b);//在可执行语句中，*前缀表示取后面指针变量所指的内容 } //请注意区别上面两种*的不同之处！

引用 5 楼 zhao4zhong1 的回复:http://bbs.csdn.net/topics/390969965 引用 5 楼 zhao4zhong1 的回复:http://bbs.csdn.net/topics/390969965 非常感谢！

int fun(int (*p)(),int a,int b)//书上是这样子写的 {  return (*p)(a,b); } ------------------------------------------------------------- result=fun(add,a,b); //意思是运行到的时候会转到执行fun函数,然后 return (*p)(a,b);，（*p）代表add这样理解对吗？   @user-3 @yuzhenxiong0823

看在40分的份上：（英雄为五斗米折腰！） #include<stdio.h> int add(int m,int n) {  return m+n; } int mul(int m,int n) {  return m*n; } int fun(int (*p)(),int a,int b)//声明函数fun,带3个参数，第1个参数的类型为int (*p)()，即一个指向某类函数的指针，该类函数无参数，返回int {  return (*p)(a,b);//调用p指向的函数,并将参数a,b传入。 } void main() {  int result,a,b;  printf("请输入两个整数a和b的值：");  scanf("%d%d",&a,&b);  result=fun(add,a,b);//调用fun函数，参数分别为add,a,b  printf("两个数的和为：%d\n",result);  result=fun(mul,a,b);////调用fun函数，参数分别为mul,a,b  printf("两个数的积为：%d\n",result); } 该代码后缀需要用.c而非.cpp才能编译通过。因为C编译器不会阻止 int (*A)() 和 int (*B)(int,int) 这两种类型的变量之间互相赋值。

引用 1 楼 user-3 的回复:int (*p)()，定义了一个函数指针，它指向一个函数（其实就是一个函数的地址），该函数返回值为int，没有参数。   int fun(int (*p)(),int a,int b) {  return (*p)(a,b); }  该fun函数有三个参数，第一个是一个函数指针，第二个第三个都是一个int变量  这个函数的实现应该是错误的，因为给出的函数指针指向的函数应该是没有参数的，但是在使用的时候确传了两个参数进去 这个函数指针应该是这样的：  int fun(int (*p)(int, int),int a,int b) {  return (*p)(a,b); }  上面的说的很清楚，好好的去看看 函数指针 相关的学习内容


Question: c语言调用TTS的问题，求指导？

用了这个 成功实现     int len=MultiByteToWideChar(CP_ACP,0,p, -1, NULL,0);     wchar_t *w_string = new wchar_t[len];     memset(w_string,0,sizeof(wchar_t)*len);     MultiByteToWideChar(CP_ACP, 0, p,-1,w_string, len);

CString是个typedef，根据程序设置，对应CStringW（宽字符）或CStringA（窄字符）。把你的工程改为Unicode，或者直接用CStringW。  还有，如果你使用的字符串本来就是窄字符的，那还需要转下编码。  当然，你也可以看看pSpVoice->Speak这个pSpVoice的类型有没有提供使用窄字符串的函数或整个类。

MultiByteToWideChar The MultiByteToWideChar function maps a character string to a wide-character (Unicode) string. The character string mapped by this function is not necessarily from a multibyte character set.   int MultiByteToWideChar(   UINT CodePage,         // code page   DWORD dwFlags,         // character-type options   LPCSTR lpMultiByteStr, // address of string to map   int cchMultiByte,      // number of bytes in string   LPWSTR lpWideCharStr,  // address of wide-character buffer   int cchWideChar        // size of buffer );   Parameters CodePage  Specifies the code page to be used to perform the conversion. This parameter can be given the value of any code page that is installed or available in the system. You can also specify one of the following values: Value Meaning  CP_ACP ANSI code page  CP_MACCP Macintosh code page  CP_OEMCP OEM code page  CP_SYMBOL Symbol code page (42)  CP_THREAD_ACP The current thread's ANSI code page  CP_UTF7 Translate using UTF-7  CP_UTF8 Translate using UTF-8    dwFlags  A set of bit flags that indicate whether to translate to precomposed or composite wide characters (if a composite form exists), whether to use glyph characters in place of control characters, and how to deal with invalid characters. You can specify a combination of the following flag constants: Value Meaning  MB_PRECOMPOSED Always use precomposed characters — that is, characters in which a base character and a nonspacing character have a single character value. This is the default translation option. Cannot be used with MB_COMPOSITE.  MB_COMPOSITE Always use composite characters — that is, characters in which a base character and a nonspacing character have different character values. Cannot be used with MB_PRECOMPOSED.  MB_ERR_INVALID_CHARS If the function encounters an invalid input character, it fails and GetLastError returns ERROR_NO_UNICODE_TRANSLATION.   MB_USEGLYPHCHARS Use glyph characters instead of control characters.    A composite character consists of a base character and a nonspacing character, each having different character values. A precomposed character has a single character value for a base/non-spacing character combination. In the character è, the e is the base character and the accent grave mark is the nonspacing character.   The function's default behavior is to translate to the precomposed form. If a precomposed form does not exist, the function attempts to translate to a composite form.   The flags MB_PRECOMPOSED and MB_COMPOSITE are mutually exclusive. The MB_USEGLYPHCHARS flag and the MB_ERR_INVALID_CHARS can be set regardless of the state of the other flags.   lpMultiByteStr  Points to the character string to be converted.  cchMultiByte  Specifies the size in bytes of the string pointed to by the lpMultiByteStr parameter. If this value is –1, the string is assumed to be null terminated and the length is calculated automatically.  lpWideCharStr  Points to a buffer that receives the translated string.  cchWideChar  Specifies the size, in wide characters, of the buffer pointed to by the lpWideCharStr parameter. If this value is zero, the function returns the required buffer size, in wide characters, and makes no use of the lpWideCharStr buffer.  Return Values If the function succeeds, and cchWideChar is nonzero, the return value is the number of wide characters written to the buffer pointed to by lpWideCharStr.   If the function succeeds, and cchWideChar is zero, the return value is the required size, in wide characters, for a buffer that can receive the translated string.   If the function fails, the return value is zero. To get extended error information, call GetLastError. GetLastError may return one of the following error codes:  ERROR_INSUFFICIENT_BUFFER ERROR_INVALID_FLAGS ERROR_INVALID_PARAMETER ERROR_NO_UNICODE_TRANSLATION  Remarks The lpMultiByteStr and lpWideCharStr pointers must not be the same. If they are the same, the function fails, and GetLastError returns the value ERROR_INVALID_PARAMETER.   The function fails if MB_ERR_INVALID_CHARS is set and it encounters an invalid character in the source string. An invalid character is one that would translate to the default character if MB_ERR_INVALID_CHARS was not set, but is not the default character in the source string, or when a lead byte is found in a string and there is no valid trail byte for DBCS strings. When an invalid character is found, and MB_ERR_INVALID_CHARS is set, the function returns 0 and sets GetLastError with the error ERROR_NO_UNICODE_TRANSLATION.  Windows CE: Windows CE does not support the CP_UTF7 and CP_UTF8 values for the CodePage parameter.  QuickInfo   Windows NT: Requires version 3.1 or later.   Windows: Requires Windows 95 or later.   Windows CE: Requires version 1.0 or later.   Header: Declared in winnls.h.   Import Library: Use kernel32.lib.  See Also Unicode and Character Sets Overview, Unicode and Character Set Functions, WideCharToMultiByte


Question: 关于ip设计哈希表的问题

引用 10 楼 ForestDB 的回复:ip就是个unsigned int32。 之前我错以为是__int64了。

ip就是个unsigned int32。

谢谢大家的帮助。。我弄好了。。结贴a

用经典的time33，每个字节乘33后加在一起做为key，考虑怎么开链就行了，或者更简单用2^n-1取&为key，按需决定n

IP地址本质上就是unsigned __int64 将ip区间和unsigned __int64的区间对应起来， 适合unsigned __int64用的hash函数就适合IP地址。

很感谢你的帮助。但是我想要的是C语言来完成。首先是设计一个适用于IP地址的哈希函数。然后通过这个哈希函数的值来判断是否存在于一个自定义的ip区间中。

不好意思。刚刚学C语言不久。能详细点说下吗？

使用map 判断区间用unsigned __int64;


Question: 怎么实现简单计算机加减乘除的优先级啊

#include <iostream> #include <stdio.h> using namespace std; ///简易计算器 char op;  int addOrMul(int sum){     int v;     scanf("%d",&v);     if(op=='*'){         sum*=v;     }     if(op=='/'){         sum/=v;     }     scanf("%c",&op);     if(op=='='){         return sum;     }     if(op=='*' || op=='/'){         return addOrMul(sum);     }else{          return sum;     } }  int main() {     int sum,value;     scanf("%d%c",&sum,&op);     while(op!='='){         switch(op){             case '*':                 sum=addOrMul(sum);                 break;             case '/':                 sum=addOrMul(sum);                 break;             case '+':                 scanf("%d%c",&value,&op);                 if(op=='*' || op=='/'){                     sum+=addOrMul(value);                 }else{                     sum+=value;                 }                 break;             case '-':                 scanf("%d%c",&value,&op);                 if(op=='*' || op=='/'){                     sum-=addOrMul(value);                 }else{                     sum-=value;                 }                 break;             default:                 printf("输入异常，程序终止\n");                 return 0;         }     }      printf("result is %d\n",sum);     return 0; }

仅供参考/*--------------------------------------- 函数型计算器(VC++6.0,Win32 Console)程序由 yu_hua 于2007-07-27设计完成 功能： 目前提供了10多个常用数学函数:     ⑴正弦sin     ⑵余弦cos     ⑶正切tan     ⑷开平方sqrt     ⑸反正弦arcsin     ⑹反余弦arccos     ⑺反正切arctan     ⑻常用对数lg     ⑼自然对数ln     ⑽ｅ指数exp     ⑾乘幂函数∧ 用法： 如果要求2的32次幂，可以打入2^32<回车> 如果要求30度角的正切可键入tan(Pi/6)<回车> 注意不能打入：tan(30)<Enter> 如果要求1.23弧度的正弦，有几种方法都有效： sin(1.23)<Enter> sin 1.23 <Enter> sin1.23  <Enter> 如果验证正余弦的平方和公式,可打入sin(1.23)^2+cos(1.23)^2 <Enter>或sin1.23^2+cos1.23^2 <Enter> 此外两函数表达式连在一起,自动理解为相乘如：sin1.23cos0.77+cos1.23sin0.77就等价于sin(1.23)*cos(0.77)+cos(1.23)*sin(0.77) 当然你还可以依据三角变换，再用sin(1.23+0.77)也即sin2验证一下。 本计算器充分考虑了运算符的优先级因此诸如：2+3*4^2 实际上相当于：2+(3*(4*4)) 另外函数名前面如果是数字,那么自动认为二者相乘. 同理，如果某数的右侧是左括号，则自动认为该数与括弧项之间隐含一乘号。 如：3sin1.2^2+5cos2.1^2 相当于3*sin2(1.2)+5*cos2(2.1) 又如：4(3-2(sqrt5-1)+ln2)+lg5 相当于4*(3-2*(√5 -1)+loge(2))+log10(5) 此外，本计算器提供了圆周率 Pi键入字母时不区分大小写,以方便使用。 ----------------------------------------*/ #include <iostream> #include <iomanip> #include <cstdlib> #include <cstring> #include <cctype> #include <cmath> #include <stdio.h> #include <string.h> #include <windows.h> using namespace std; const char Tab=0x9; const int  DIGIT=1; const int MAXLEN=16384; char s[MAXLEN],*endss; int pcs=15; double fun(double x,char op[],int *iop) {     while (op[*iop-1]<32) //本行使得函数嵌套调用时不必加括号,如 arc sin(sin(1.234)) 只需键入arc sin sin 1.234<Enter>         switch (op[*iop-1]) {         case  7: x=sin(x);  (*iop)--;break;         case  8: x=cos(x);  (*iop)--;break;         case  9: x=tan(x);  (*iop)--;break;         case 10: x=sqrt(x); (*iop)--;break;         case 11: x=asin(x); (*iop)--;break;         case 12: x=acos(x); (*iop)--;break;         case 13: x=atan(x); (*iop)--;break;         case 14: x=log10(x);(*iop)--;break;         case 15: x=log(x);  (*iop)--;break;         case 16: x=exp(x);  (*iop)--;break;         }     return x; } double calc(char *expr,char **addr) {     static int deep; //递归深度     static char *fname[]={ "sin","cos","tan","sqrt","arcsin","arccos","arctan","lg","ln","exp",NULL};     double ST[10]={0.0}; //数字栈     char op[10]={'+'}; //运算符栈     char c,*rexp,*pp,*pf;     int ist=1,iop=1,last,i;      if (!deep) {         pp=pf=expr;         do {             c = *pp++;             if (c!=' '&& c!=Tab)                 *pf++ = c;         } while (c!='\0');     }     pp=expr;     if ((c=*pp)=='-'||c=='+') {         op[0] = c;         pp++;     }     last = !DIGIT;     while ((c=*pp)!='\0') {         if (c=='(') {//左圆括弧             deep++;             ST[ist++]=calc(++pp,addr);             deep--;             ST[ist-1]=fun(ST[ist-1],op,&iop);             pp = *addr;             last = DIGIT;             if (*pp == '('||isalpha(*pp) && strnicmp(pp,"Pi",2)) {//目的是：当右圆括弧的右恻为左圆括弧或函数名字时，默认其为乘法                 op[iop++]='*';                 last = !DIGIT;                 c = op[--iop];                 goto operate ;             }         }         else if (c==')') {//右圆括弧             pp++;             break;         } else if (isalpha(c)) {             if (!strnicmp(pp,"Pi",2)) {                 if (last==DIGIT) {                     cout<< "π左侧遇）" <<endl;exit(1);                 }                 ST[ist++]=3.14159265358979323846264338328;                 ST[ist-1]=fun(ST[ist-1],op,&iop);                 pp += 2;                 last = DIGIT;                 if (!strnicmp(pp,"Pi",2)) {                     cout<< "两个π相连" <<endl;exit(2);                 }                 if (*pp=='(') {                     cout<< "π右侧遇（" <<endl;exit(3);                 }             } else {                 for (i=0; (pf=fname[i])!=NULL; i++)                     if (!strnicmp(pp,pf,strlen(pf))) break;                 if (pf!=NULL) {                     op[iop++] = 07+i;                     pp += strlen(pf);                 } else {                     cout<< "陌生函数名" <<endl;exit(4);                 }             }         } else if (c=='+'||c=='-'||c=='*'||c=='/'||c=='^') {             char cc;             if (last != DIGIT) {                 cout<< "运算符粘连" <<endl;exit(5);             }             pp++;             if (c=='+'||c=='-') {                 do {                     cc = op[--iop];                     --ist;                     switch (cc) {                     case '+':  ST[ist-1] += ST[ist];break;                     case '-':  ST[ist-1] -= ST[ist];break;                     case '*':  ST[ist-1] *= ST[ist];break;                     case '/':  ST[ist-1] /= ST[ist];break;                     case '^':  ST[ist-1] = pow(ST[ist-1],ST[ist]);break;                     }                 } while (iop);                 op[iop++] = c;             } else if (c=='*'||c=='/') { operate:        cc = op[iop-1];                 if (cc=='+'||cc=='-') {                     op[iop++] = c;                 } else {                     --ist;                     op[iop-1] = c;                     switch (cc) {                     case '*':  ST[ist-1] *= ST[ist];break;                     case '/':  ST[ist-1] /= ST[ist];break;                     case '^':  ST[ist-1] = pow(ST[ist-1],ST[ist]);break;                     }                 }             } else {                 cc = op[iop-1];                 if (cc=='^') {                     cout<< "乘幂符连用" <<endl;exit(6);                 }                 op[iop++] = c;             }             last = !DIGIT;         } else {             if (last == DIGIT) {                 cout<< "两数字粘连" <<endl;exit(7);             }             ST[ist++]=strtod(pp,&rexp);             ST[ist-1]=fun(ST[ist-1],op,&iop);             if (pp == rexp) {                 cout<< "非法字符" <<endl;exit(8);             }             pp = rexp;             last = DIGIT;             if (*pp == '('||isalpha(*pp)) {                 op[iop++]='*';                 last = !DIGIT;                 c = op[--iop];                 goto operate ;             }         }     }     *addr=pp;     if (iop>=ist) {         cout<< "表达式有误" <<endl;exit(9);     }     while (iop) {         --ist;         switch (op[--iop]) {         case '+':  ST[ist-1] += ST[ist];break;         case '-':  ST[ist-1] -= ST[ist];break;         case '*':  ST[ist-1] *= ST[ist];break;         case '/':  ST[ist-1] /= ST[ist];break;         case '^':  ST[ist-1] = pow(ST[ist-1],ST[ist]);break;         }     }     return ST[0]; } int main(int argc,char **argv) {     int a;      if (argc<2) {         if (GetConsoleOutputCP()!=936) system("chcp 936>NUL");//中文代码页         cout << "计算函数表达式的值。"<<endl<<"支持(),+,-,*,/,^,Pi,sin,cos,tan,sqrt,arcsin,arccos,arctan,lg,ln,exp"<<endl;         while (1) {             cout << "请输入表达式：";             gets(s);             if (s[0]==0) break;//             cout << s <<"=";             cout << setprecision(15) << calc(s,&endss) << endl;         }     } else if (argc==2 && 0==strcmp(argv[1],"/?")) {         if (GetConsoleOutputCP()!=936) system("chcp 936>NUL");//中文代码页         cout << "计算由≥1个命令行参数给出的函数表达式的值。最后一个参数是.0～.15表示将计算结果保留小数0～15位"<<endl<<"支持(),+,-,*,/,^^,Pi,sin,cos,tan,sqrt,arcsin,arccos,arctan,lg,ln,exp"<<endl;     } else {         strncpy(s,argv[1],MAXLEN-1);s[MAXLEN-1]=0;         if (argc>2) {             for (a=2;a<argc-1;a++) strncat(s,argv[a],MAXLEN-1);//将空格间隔的各参数连接到s             if (1==sscanf(argv[a],".%d",&pcs) && 0<=pcs && pcs<=15) {//最后一个参数是.0～.15表示将计算结果保留小数0～15位                 printf("%.*lf\n",pcs,calc(s,&endss));             } else {                 strncat(s,argv[a],MAXLEN-1);                 printf("%.15lg\n",calc(s,&endss));             }         } else {             printf("%.15lg\n",calc(s,&endss));         }     }     return 0; }


Question: typedef struct究竟怎么用？

引用 17 楼 sholber 的回复:[quote=引用 15 楼 cfjtaishan 的回复:] [quote=引用 14 楼 sholber 的回复:] [quote=引用 7 楼 cfjtaishan 的回复:] 结构体成员怎么没有名字呢？怎么会出现这样的定义？  这有什么奇怪的，如果仅仅是想占个位，可以没有名字。[/quote] 即使是没有问题的定义，但为什么要这样定义呢？为了与众不同，还是其他原因。在实际工作中没有那个工程师这样去定义一个结构体，因为这样定义的数据结构怎么样让读代码的人理解和接收。写好代码的另一个目的就是能让别人看懂，这样定义的数据结构应该会让读者一头雾水吧。[/quote] C标准好多年才修改一回，我相信标准委员会的人不是白痴，会加入一个工程师从来不会使用的特性。看懂看不懂，会不会一头雾水是一回事，C应该怎么样是另一回事。再说，你用不到不等于别人用不到。有些时候就是需要用无名成员来达到严格对齐的目的。[/quote] 首先，不能说标准委员会“白痴”，这是不礼貌的。“严格对齐”这个用途没有考虑到，不过，这个完全也可以被其他方式替代。C语言的规则可能是多样的，兼容性也可以是变得更好，不过，从人性化考虑，从大众化考虑可能写出的代码更具可读性为最佳；当然，也不是绝对的，为了可读性而放弃效率也是不可取的。可读性可以用注释来弥补，为了效率可以牺牲可读性而采用注释去弥补。我提出的是在效率不相上下的情况下，代码的可读性是比较重要的！

引用 15 楼 cfjtaishan 的回复:[quote=引用 14 楼 sholber 的回复:] [quote=引用 7 楼 cfjtaishan 的回复:] 结构体成员怎么没有名字呢？怎么会出现这样的定义？  这有什么奇怪的，如果仅仅是想占个位，可以没有名字。[/quote] 即使是没有问题的定义，但为什么要这样定义呢？为了与众不同，还是其他原因。在实际工作中没有那个工程师这样去定义一个结构体，因为这样定义的数据结构怎么样让读代码的人理解和接收。写好代码的另一个目的就是能让别人看懂，这样定义的数据结构应该会让读者一头雾水吧。[/quote]  C标准好多年才修改一回，我相信标准委员会的人不是白痴，会加入一个工程师从来不会使用的特性。看懂看不懂，会不会一头雾水是一回事，C应该怎么样是另一回事。再说，你用不到不等于别人用不到。有些时候就是需要用无名成员来达到严格对齐的目的。

我感觉凡是让别人、让读者容易产生二义性或者不易理解的代码最好不要写，除了能显摆一下自己“独特”的编程能力，其他的都不是很好的结果：别人看不懂，容易遭骂；同事看不懂，容易找你麻烦；老大看不懂，容易对你“另眼相待”；将来自己看不懂，那就是自欺欺人了。

引用 14 楼 sholber 的回复:[quote=引用 7 楼 cfjtaishan 的回复:] 结构体成员怎么没有名字呢？怎么会出现这样的定义？  这有什么奇怪的，如果仅仅是想占个位，可以没有名字。[/quote] 即使是没有问题的定义，但为什么要这样定义呢？为了与众不同，还是其他原因。在实际工作中没有那个工程师这样去定义一个结构体，因为这样定义的数据结构怎么样让读代码的人理解和接收。写好代码的另一个目的就是能让别人看懂，这样定义的数据结构应该会让读者一头雾水吧。

引用 7 楼 cfjtaishan 的回复:结构体成员怎么没有名字呢？怎么会出现这样的定义？  这有什么奇怪的，如果仅仅是想占个位，可以没有名字。

int ;char  哈哈，有趣得紧。

引用 5 楼 user-7 的回复:好好看书吧！！+1,看书

楼主仔细看上面的代码，看看什么诡秘的

#include<stdio.h>  int main() { 	struct 	{ 		int a; 		char b; 	}test; 	test.a = 1; 	test.b = 'h';   	printf("%d\n%c\n",test.a,test.b);  	return 0; }

int ;char//h这是什么意思

什么意思。。。。

结构体成员怎么没有名字呢？怎么会出现这样的定义？

关于自己是否适合编程的很简单的测试： 在报纸或杂志上随便找一段约1000字的文章，在Word中输入一遍。输完后再参考下面答案：  A里面有10处以上文字或标点错误 B里面没有文字或标点错误并敢为此跟人打赌 C里面没有文字或标点错误并且字体和排版完全与原稿一致 D打印在半透明的纸上和原稿重叠在一起检查一模一样，且自我感觉很有成就感  A不适合编程（理由：打字准确度偏低、粗心大意） B初级程序员（理由：打字准确度很高、认真细致、自信、理解全角半角概念） C高级程序员（理由：在B的基础上理解字体和排版也是电脑打印的重要因素、但相比D还不够偏执、精益求精、结果可验证） D软件项目经理（理由：能针对项目给出令人信服的细致到极点的需求说明和典型测试用例。用户几乎挑不出毛病。专业！）  如果想从A变成B的话，到我的资源http://download.csdn.net/detail/zhao4zhong1/4084259里面下载“适合程序员的键盘练习”

好好看书吧！！

#include <stdio.h> #include <stdlib.h>  typedef struct person {     int  i;      char str;  } Person;    void rank(Person s) {     s.i = 12;     s.str = 'A';      printf("s.i = %d, s.str = %c\n", s.i, s.str);  }  int main() {     Person s;     rank(s);     return 0; }

typedef struct person ｛      int  i;     char  str; ｝Person; void rank(Person s) { }

2楼是我出错的语法，这是为什么啊

#include<stdio.h> #include<stdlib.h> #define max 1000 #define temp 1 void disk(P s); typedef struct name { 	char lastname[max]; 	char secondname[max]; 	char firstname[max]; }Name; typedef struct personal { 	int ID; 	Name person; }P; int main(void) { 	P man[temp]; 	for (int i = 0; i < temp; i++) 	{ 		printf("请输入姓："); 		gets(man[i].person.firstname); 		printf("请输入姓与名中间的名字："); 		gets(man[i].person.secondname); 		printf("请输入名："); 		gets(man[i].person.lastname); 	} 	for (int i = 0; i < temp; i++) 	{ 		disk(man[i]); 	} 	system("pause"); 	return 0; } void disk(P s) { 	if (s.person.secondname[0] != '\0') 	{ 		s.person.secondname[1] = '.'; 		for (int i = 0; s.person.firstname[i] != '\0'; i++) 			printf("%c", s.person.firstname[i]); 		printf(" "); 		for (int i = 0; i < 2; i++) 		{ 			printf("%c", s.person.secondname[i]); 		} 		printf(" "); 		for (int i = 0; s.person.lastname[i] != '\0'; i++) 		{ 			printf("%c", s.person.lastname[i]); 		} 		printf("\n"); 	} 	else 	{ 		for (int i = 0; s.person.firstname[i] != '\0'; i++) 			printf("%c", s.person.firstname[i]); 		printf(" "); 		for (int i = 0; s.person.lastname[i] != '\0'; i++) 		{ 			printf("%c", s.person.lastname[i]); 		} 		printf("\n"); 	} }


Question: DWORD  对应c# 里什么类型

LS 能看下这帖子吗？ http://bbs.csdn.net/topics/390969821

DWORD （26）=26 Params = 0x00731000


Question: 用C语言读取bmp文件的像素值  结果有错误

11楼正解！

引用 4 楼 lwclsq 的回复:谢谢。bmp宽度为450，又因为有rgb三个分量，每行有1350个细节，而且有要是4的倍数，最后成为1352.这点没问题。 当读取少量像素值，比如30个的时候没问题，但是超过某个值的时候就出错了 你说的没错，读取少量像素的时候，没有遇到 0x0d 0x0a 序列，所以不会出错，在Windows下fopen(..., "r")这样打开文件的话， 文件里的0x0d 0x0a会被替换成0x0a的。 楼主自己试试下面这个程序就明白为啥了。  #include <stdio.h>  static int dump(char *buf, int len) { 	int i;   	printf("len=%02d: ", len); 	for (i = 0; i < len; i++) { 		printf("%02x ", (unsigned char)buf[i]); 	} 	printf("\n");  	return 0; }  int main(int argc, char *argv[]) { 	FILE *fp; 	int len; 	char buf[1024] = {0x01, 0x02, 0x0d, 0x0a, 0x03, 0x04};  	len = 6; 	dump(buf, len);  	fp = fopen("mymtom.dat", "wb"); 	fwrite(buf, 1, len, fp); 	fclose(fp);  	fp = fopen("mymtom.dat", "r"); 	len = fread(buf, 1, sizeof(buf), fp); 	fclose(fp); 	dump(buf, len);  	return 0; }  /* Windows环境下的输出: len=06: 01 02 0d 0a 03 04 len=05: 01 02 0a 03 04 */

用开源库吧，wxWidgets之内的，有专门的封装好的图形处理函数。

1 读写文件都加上b(rb，WB) 2 确定是24位图，直接跳过54字节，像素是连续，不需seek 3 图像处理用连续内存，一维指针足矣，每个RGB分配一次内存太浪费 4写回去不对，那个神奇数字1352忘了吧，每行要写这么多字节才行

if((fp=fopen( "d:\\1.bmp", "r"))==NULL)  和    if((fp=fopen( "d:\\1.bmp", "rb"))==NULL)  不是一回事！  不要把 fopen("...","...");fscanf,fprintf,fgets,fgetc,fclose //读时把\r\n替换成\n，写时把\n替换成\r\n;读到\x1a就设置EOF;读写的内容当字符看待 和 fopen("...","...b");fseek,fread,fwrite,fgetc,fclose  //不作以上替换，遇到\x1a仍继续读;读写的内容当字节看待 弄混了

for(i=0;i<height;i++)            //行数  height { for (j=0;j<width;j++)           //列数 width  { fseek(fp, 54+1352*i+3*j, SEEK_SET); fread(&A[i][j],1,1,fp); } }这个有没有错。。。。。。读取少量值没问题，全部读取就会出错。。是不是VC++6.0平台的问题？

1. 永远用二进制模式打开文件 		fopen时mode参数加上"b"否则你可能花了一个通宵也弄不明白为什么一星期 	前正常运行的运行程序为什么最近老是出错。(Windows平台上才会出现哦！)  2. 避免以更新模式打开文件 		fopen时mode参数不要用"+"，只要可能，要么读方式打开，要么写方式打开。 如果 	必须以更新模式打开文件，  记得在读写之间进行文件刷新 （flush） 或文件定位操作 	（fseek , fsetpos , rewind）。

常量也有类型： C++ Integer Constants Integer constants are constant data elements that have no fractional parts or exponents. They always begin with a digit. You can specify integer constants in decimal, octal, or hexadecimal form. They can specify signed or unsigned types and long or short types.  Syntax  integer-constant :  decimal-constant integer-suffixopt octal-constant integer-suffixopt hexadecimal-constant integer-suffixopt 'c-char-sequence'  decimal-constant :  nonzero-digit decimal-constant digit  octal-constant :  0 octal-constant octal-digit  hexadecimal-constant :  0x hexadecimal-digit 0X hexadecimal-digit hexadecimal-constant hexadecimal-digit  nonzero-digit : one of  1 2 3 4 5 6 7 8 9  octal-digit : one of  0 1 2 3 4 5 6 7  hexadecimal-digit : one of  0 1 2 3 4 5 6 7 8 9 a b c d e f A B C D E F  integer-suffix :  unsigned-suffix long-suffixopt long-suffix unsigned-suffixopt  unsigned-suffix : one of  u U  long-suffix : one of  l L  64-bit integer-suffix :  i64  To specify integer constants using octal or hexadecimal notation, use a prefix that denotes the base. To specify an integer constant of a given integral type, use a suffix that denotes the type.  To specify a decimal constant, begin the specification with a nonzero digit. For example:  int i = 157;   // Decimal constant int j = 0198;  // Not a decimal number; erroneous octal constant int k = 0365;  // Leading zero specifies octal constant, not decimal  To specify an octal constant, begin the specification with 0, followed by a sequence of digits in the range 0 through 7. The digits 8 and 9 are errors in specifying an octal constant. For example:  int i = 0377;   // Octal constant int j = 0397;   // Error: 9 is not an octal digit  To specify a hexadecimal constant, begin the specification with 0x or 0X (the case of the “x” does not matter), followed by a sequence of digits in the range 0 through 9 and a (or A) through f (or F). Hexadecimal digits a (or A) through f (or F) represent values in the range 10 through 15. For example:  int i = 0x3fff;   // Hexadecimal constant int j = 0X3FFF;   // Equal to i  To specify an unsigned type, use either the u or U suffix. To specify a long type, use either the l or L suffix. For example:  unsigned uVal = 328u;             // Unsigned value long lVal = 0x7FFFFFL;            // Long value specified                                    //  as hex constant unsigned long ulVal = 0776745ul;  // Unsigned long value

谢谢。也不行.这是读取b分量的值 有没有问题 for(i=0;i<height;i++)            //行数  height { for (j=0;j<width;j++)           //列数 width  { fseek(fp, 54+1352*i+3*j, SEEK_SET); fread(&A[i][j],1,1,fp); } }

54+1352*i+3*j 改为 54UL+1352UL*i+3UL*j

if((fp=fopen( "d:\\1.bmp", "r"))==NULL)  ===> if((fp=fopen( "d:\\1.bmp", "rb"))==NULL)

提醒：bmp每行像素数据的字节数必须是4的倍数。  推荐使用WinHex软件查看硬盘或文件或内存中的原始字节内容。

引掉也没问题，其实LineLength已经修正过了，就是下面的1352 fseek(fp, 54+1352*i+3*j, SEEK_SET); fread(&A[i][j],1,1,fp);  我是想说读取少量像素值没问题，但是要全部读完结果就有问题了

//r=LineLength%4; //if(r!=0) //r=4-r; //else r=0; //while( LineLength % 4 != 0 )             // 修正LineLength使其为4的倍数    // ++LineLength;  这块不能注释掉的哦，图像中每行字节数必须是4的倍数，否则取得数值就会有偏差，并且分配的内存有可能偏小导致内存溢出


Question: C语言错哪了？照着书敲的。求x1*x1+x1*x2

实在不想将.cpp后缀改为.c的话： #include<stdio.h> double f1(double x) {  return x*x; } double f2(double x,double y) {  return x*y; } double fun(double a,double b) {  double (*f)();  double r1,r2;  f=(double (*)())f1;  r1=(*(double (*)(double))f)(a);  f=(double (*)())f2;  r2=(*(double (*)(double,double))f)(a,b);  return r1+r2; } void main() {  double x1,x2,r;  printf("请输入x1x2:");  scanf("%lf%lf",&x1,&x2);  r=fun(x1,x2);  printf("x1=%.2f,x2=%.2f,x1*x1+x1*x2=%.2f\n",x1,x2,r); }

既然是C语言而不是C ，请楼主将你的源代码文件名后缀由.cpp改为.c

把Vc扔了 换一个就好了，  估计刚刚建立错了

把书扔掉，换一本！


Question: 用C做语音处理

推荐使用NCTAudioStudio控件处理音频。

fopen就可以吗


Question: 《数据恢复技术深度揭秘》

这个是帮助你学习磁盘格式 MBR DBR NTFS header等知识

下完才看到二楼。有分就是任性。

我只会用“EasyRecovery Professional”软件。

下你这资源，30分就没了，我也贴个不要分的给资源分不够的同学们用   数据恢复技术深度揭秘   中文名: 数据恢复技术深度揭秘 作者: 图书 分类: 网络 资源格式: PDF 版本: 扫描版 出版社: 电子工业出版社 书号: 9787121106637 发行时间: 2010年5月21日 地区:  语言:  简介:    - 内容介绍：  　　本书是中国电子信息产业发展研究院培训中心数据恢复技术培训指定教材，是从逻辑类和物理类两个方面全面讲解数据恢复技术的专业书籍。 　　 在逻辑类数据恢复方面，本书包括mbr磁盘分区、动态磁盘分区、gpt磁盘分区、solaris分区、apm分区、bsd分区的恢复技术，windows平台的fat32、fatl6、ntfs、exfat文件系统的恢复技术，unix平台的ufs文件系统恢复技术，apple平台的hfs+文件系统恢复技术，linux平台的ext3、ext4文件系统恢复技术，以及windows、unix、apple、linux平台的raid-0、raid-1、raid-5、raid-5ee、raid-6、hp双循环等磁盘阵列恢复技术。 　　 在物理类数据恢复方面，本书包括各大品牌硬盘出现电路故障、磁头故障、电机故障、扇区读取故障、固件故障后数据恢复的方法及优盘无法识别的恢复方法。 　　 如果您是数据恢复技术的初学者，本书可以由浅入深，一步步将您引入数据恢复技术的神秘殿堂；如果您已经是数据恢复技术的高手，本书同样可以带来令您惊喜的经验和技巧。

lz是来这发广告赚资源分的？

你这个不是高清，58M,  我的130多M


Question: 求助，将二叉树中所有符合要求的节点都删除该怎么写

仅供参考#include <iostream> #include <stack> #include <queue> #include <locale.h> using namespace std; typedef struct BiTNode {//二叉树结点     char data;                      //数据     struct BiTNode *lchild,*rchild; //左右孩子指针 } BiTNode,*BiTree; int CreateBiTree(BiTree &T) {//按先序序列创建二叉树     char data;     scanf("%c",&data);//按先序次序输入二叉树中结点的值（一个字符），‘#’表示空树     if (data == '#') {         T = NULL;     } else {         T = (BiTree)malloc(sizeof(BiTNode));         T->data = data;         //生成根结点         CreateBiTree(T->lchild);//构造左子树         CreateBiTree(T->rchild);//构造右子树     }     return 0; } void Visit(BiTree T) {//输出     if (T->data != '#') {         printf("%c ",T->data);     } } void PreOrder(BiTree T) {//先序遍历     if (T != NULL) {         Visit(T);               //访问根节点         PreOrder(T->lchild);    //访问左子结点         PreOrder(T->rchild);    //访问右子结点     } } void InOrder(BiTree T) {//中序遍历     if (T != NULL) {         InOrder(T->lchild);     //访问左子结点         Visit(T);               //访问根节点         InOrder(T->rchild);     //访问右子结点     } } void PostOrder(BiTree T) {//后序遍历     if (T != NULL) {         PostOrder(T->lchild);   //访问左子结点         PostOrder(T->rchild);   //访问右子结点         Visit(T);               //访问根节点     } } void PreOrder2(BiTree T) {//先序遍历(非递归) //访问T->data后，将T入栈，遍历左子树；遍历完左子树返回时，栈顶元素应为T，出栈，再先序遍历T的右子树。     stack<BiTree> stack;     BiTree p = T;//p是遍历指针     while (p || !stack.empty()) {   //栈不空或者p不空时循环         if (p != NULL) {             stack.push(p);          //存入栈中             printf("%c ",p->data);  //访问根节点             p = p->lchild;          //遍历左子树         } else {             p = stack.top();        //退栈             stack.pop();             p = p->rchild;          //访问右子树         }     } } void InOrder2(BiTree T) {//中序遍历(非递归) //T是要遍历树的根指针，中序遍历要求在遍历完左子树后，访问根，再遍历右子树。 //先将T入栈，遍历左子树；遍历完左子树返回时，栈顶元素应为T，出栈，访问T->data，再中序遍历T的右子树。     stack<BiTree> stack;     BiTree p = T;//p是遍历指针     while (p || !stack.empty()) {   //栈不空或者p不空时循环         if (p != NULL) {             stack.push(p);          //存入栈中             p = p->lchild;          //遍历左子树         } else {             p = stack.top();        //退栈，访问根节点             printf("%c ",p->data);             stack.pop();             p = p->rchild;          //访问右子树         }     } }  typedef struct BiTNodePost{     BiTree biTree;     char tag; } BiTNodePost,*BiTreePost; void PostOrder2(BiTree T) {//后序遍历(非递归)     stack<BiTreePost> stack;     BiTree p = T;//p是遍历指针     BiTreePost BT;     while (p != NULL || !stack.empty()) {//栈不空或者p不空时循环         while (p != NULL) {//遍历左子树             BT = (BiTreePost)malloc(sizeof(BiTNodePost));             BT->biTree = p;             BT->tag = 'L';//访问过左子树             stack.push(BT);             p = p->lchild;         }         while (!stack.empty() && (stack.top())->tag == 'R') {//左右子树访问完毕访问根节点             BT = stack.top();             stack.pop();//退栈             printf("%c ",BT->biTree->data);         }         if (!stack.empty()) {//遍历右子树             BT = stack.top();             BT->tag = 'R';//访问过右子树             p = BT->biTree;             p = p->rchild;         }     } }  void LevelOrder(BiTree T) {//层次遍历     if (T == NULL) return;     BiTree p = T;     queue<BiTree> queue;//队列     queue.push(p);//根节点入队     while (!queue.empty()) {    //队列不空循环         p = queue.front();      //对头元素出队         printf("%c ",p->data);  //访问p指向的结点         queue.pop();            //退出队列         if (p->lchild != NULL) {//左子树不空，将左子树入队             queue.push(p->lchild);         }         if (p->rchild != NULL) {//右子树不空，将右子树入队             queue.push(p->rchild);         }     } } int main() {     BiTree T;      setlocale(LC_ALL,"chs");     CreateBiTree(T);      printf("先序遍历        ：");PreOrder  (T);printf("\n");     printf("先序遍历(非递归)：");PreOrder2 (T);printf("\n");                                                printf("\n");     printf("中序遍历        ：");InOrder   (T);printf("\n");     printf("中序遍历(非递归)：");InOrder2  (T);printf("\n");                                                printf("\n");     printf("后序遍历        ：");PostOrder (T);printf("\n");     printf("后序遍历(非递归)：");PostOrder2(T);printf("\n");                                                printf("\n");     printf("层次遍历        ：");LevelOrder(T);printf("\n");      return 0; } //ABC##DE#G##F### //先序遍历        ：A B C D E G F //先序遍历(非递归)：A B C D E G F // //中序遍历        ：C B E G D F A //中序遍历(非递归)：C B E G D F A // //后序遍历        ：C G E F D B A //后序遍历(非递归)：C G E F D B A // //层次遍历        ：A B C D E F G //  ///       A ///      / ///     B ///    / \ ///   C   D ///      / \ ///     E   F ///      \ ///       G

很复杂 你要考虑一下 删除掉之后的替换策略 如果是个面试题 需要问题清楚是左子树替换上来还是右子树替换上来

不遍历还能咋办。。。。必须遍历。原树有序的话，还得调整树的结构

只能遍历删除


Question: C语言下苦恼的多线程，需求如下，求大神指点。

等楼主完全弄懂我的代码的那一天早日到来。

引用 2 楼 zhao4zhong1 的回复:仅供参考//循环向a函数每次发送200个字节长度（这个是固定的）的buffer, //a函数中需要将循环传进来的buffer，组成240字节（也是固定的）的新buffer进行处理， //在处理的时候每次从新buffer中取两个字节打印 #ifdef WIN32     #pragma warning(disable:4996) #endif #include <stdio.h> #include <stdlib.h> #include <string.h> #ifdef WIN32     #include <windows.h>     #include <process.h>     #include <io.h>     #define  MYVOID             void     #define  vsnprintf          _vsnprintf #else     #include <unistd.h>     #include <sys/time.h>     #include <pthread.h>     #define  CRITICAL_SECTION   pthread_mutex_t     #define  MYVOID             void * #endif //Log{ #define MAXLOGSIZE 20000000 #define MAXLINSIZE 16000 #include <time.h> #include <sys/timeb.h> #include <stdarg.h> char logfilename1[]="MyLog1.log"; char logfilename2[]="MyLog2.log"; static char logstr[MAXLINSIZE+1]; char datestr[16]; char timestr[16]; char mss[4]; CRITICAL_SECTION cs_log; FILE *flog; #ifdef WIN32 void Lock(CRITICAL_SECTION *l) {     EnterCriticalSection(l); } void Unlock(CRITICAL_SECTION *l) {     LeaveCriticalSection(l); } void sleep_ms(int ms) {     Sleep(ms); } #else void Lock(CRITICAL_SECTION *l) {     pthread_mutex_lock(l); } void Unlock(CRITICAL_SECTION *l) {     pthread_mutex_unlock(l); } void sleep_ms(int ms) {     usleep(ms*1000); } #endif void LogV(const char *pszFmt,va_list argp) {     struct tm *now;     struct timeb tb;      if (NULL==pszFmt||0==pszFmt[0]) return;     vsnprintf(logstr,MAXLINSIZE,pszFmt,argp);     ftime(&tb);     now=localtime(&tb.time);     sprintf(datestr,"%04d-%02d-%02d",now->tm_year+1900,now->tm_mon+1,now->tm_mday);     sprintf(timestr,"%02d:%02d:%02d",now->tm_hour     ,now->tm_min  ,now->tm_sec );     sprintf(mss,"%03d",tb.millitm);     printf("%s %s.%s %s",datestr,timestr,mss,logstr);     flog=fopen(logfilename1,"a");     if (NULL!=flog) {         fprintf(flog,"%s %s.%s %s",datestr,timestr,mss,logstr);         if (ftell(flog)>MAXLOGSIZE) {             fclose(flog);             if (rename(logfilename1,logfilename2)) {                 remove(logfilename2);                 rename(logfilename1,logfilename2);             }         } else {             fclose(flog);         }     } } void Log(const char *pszFmt,...) {     va_list argp;      Lock(&cs_log);     va_start(argp,pszFmt);     LogV(pszFmt,argp);     va_end(argp);     Unlock(&cs_log); } //Log} #define ASIZE    200 #define BSIZE    240 #define CSIZE      2 char Abuf[ASIZE]; char Cbuf[CSIZE]; CRITICAL_SECTION cs_HEX ; CRITICAL_SECTION cs_BBB ; struct FIFO_BUFFER {     int  head;     int  tail;     int  size;     char data[BSIZE]; } BBB; int No_Loop=0; void HexDump(int cn,char *buf,int len) {     int i,j,k;     char binstr[80];      Lock(&cs_HEX);     for (i=0;i<len;i++) {         if (0==(i%16)) {             sprintf(binstr,"%03d %04x -",cn,i);             sprintf(binstr,"%s %02x",binstr,(unsigned char)buf[i]);         } else if (15==(i%16)) {             sprintf(binstr,"%s %02x",binstr,(unsigned char)buf[i]);             sprintf(binstr,"%s  ",binstr);             for (j=i-15;j<=i;j++) {                 sprintf(binstr,"%s%c",binstr,('!'<buf[j]&&buf[j]<='~')?buf[j]:'.');             }             Log("%s\n",binstr);         } else {             sprintf(binstr,"%s %02x",binstr,(unsigned char)buf[i]);         }     }     if (0!=(i%16)) {         k=16-(i%16);         for (j=0;j<k;j++) {             sprintf(binstr,"%s   ",binstr);         }         sprintf(binstr,"%s  ",binstr);         k=16-k;         for (j=i-k;j<i;j++) {             sprintf(binstr,"%s%c",binstr,('!'<buf[j]&&buf[j]<='~')?buf[j]:'.');         }         Log("%s\n",binstr);     }     Unlock(&cs_HEX); } int GetFromRBuf(int cn,CRITICAL_SECTION *cs,FIFO_BUFFER *fbuf,char *buf,int len) {     int lent,len1,len2;      lent=0;     Lock(cs);     if (fbuf->size>=len) {         lent=len;         if (fbuf->head+lent>BSIZE) {             len1=BSIZE-fbuf->head;             memcpy(buf     ,fbuf->data+fbuf->head,len1);             len2=lent-len1;             memcpy(buf+len1,fbuf->data           ,len2);             fbuf->head=len2;         } else {             memcpy(buf     ,fbuf->data+fbuf->head,lent);             fbuf->head+=lent;         }         fbuf->size-=lent;     }     Unlock(cs);     return lent; } MYVOID thdB(void *pcn) {     char        *recv_buf;     int          recv_nbytes;     int          cn;     int          wc;     int          pb;      cn=(int)pcn;     Log("%03d thdB              thread begin...\n",cn);     while (1) {         sleep_ms(10);         recv_buf=(char *)Cbuf;         recv_nbytes=CSIZE;         wc=0;         while (1) {             pb=GetFromRBuf(cn,&cs_BBB,&BBB,recv_buf,recv_nbytes);             if (pb) {                 Log("%03d recv %d bytes\n",cn,pb);                 HexDump(cn,recv_buf,pb);                 sleep_ms(1);             } else {                 sleep_ms(1000);             }             if (No_Loop) break;//             wc++;             if (wc>3600) Log("%03d %d==wc>3600!\n",cn,wc);         }         if (No_Loop) break;//     } #ifndef WIN32     pthread_exit(NULL); #endif } int PutToRBuf(int cn,CRITICAL_SECTION *cs,FIFO_BUFFER *fbuf,char *buf,int len) {     int lent,len1,len2;      Lock(cs);     lent=len;     if (fbuf->size+lent>BSIZE) {         lent=BSIZE-fbuf->size;     }     if (fbuf->tail+lent>BSIZE) {         len1=BSIZE-fbuf->tail;         memcpy(fbuf->data+fbuf->tail,buf     ,len1);         len2=lent-len1;         memcpy(fbuf->data           ,buf+len1,len2);         fbuf->tail=len2;     } else {         memcpy(fbuf->data+fbuf->tail,buf     ,lent);         fbuf->tail+=lent;     }     fbuf->size+=lent;     Unlock(cs);     return lent; } MYVOID thdA(void *pcn) {     char        *send_buf;     int          send_nbytes;     int          cn;     int          wc;     int           a;     int          pa;      cn=(int)pcn;     Log("%03d thdA              thread begin...\n",cn);     a=0;     while (1) {         sleep_ms(100);         memset(Abuf,a,ASIZE);         a=(a+1)%256;         if (16==a) {No_Loop=1;break;}//去掉这句可以让程序一直循环直到按Ctrl+C或Ctrl+Break或当前目录下存在文件No_Loop         send_buf=(char *)Abuf;         send_nbytes=ASIZE;         Log("%03d sending %d bytes\n",cn,send_nbytes);         HexDump(cn,send_buf,send_nbytes);         wc=0;         while (1) {             pa=PutToRBuf(cn,&cs_BBB,&BBB,send_buf,send_nbytes);             Log("%03d sent %d bytes\n",cn,pa);             HexDump(cn,send_buf,pa);             send_buf+=pa;             send_nbytes-=pa;             if (send_nbytes<=0) break;//             sleep_ms(1000);             if (No_Loop) break;//             wc++;             if (wc>3600) Log("%03d %d==wc>3600!\n",cn,wc);         }         if (No_Loop) break;//     } #ifndef WIN32     pthread_exit(NULL); #endif } int main() { #ifdef WIN32     InitializeCriticalSection(&cs_log);     InitializeCriticalSection(&cs_HEX );     InitializeCriticalSection(&cs_BBB ); #else     pthread_t threads[2];     int threadsN;     int rc;     pthread_mutex_init(&cs_log,NULL);     pthread_mutex_init(&cs_HEX,NULL);     pthread_mutex_init(&cs_BBB,NULL); #endif     Log("Start===========================================================\n");      BBB.head=0;     BBB.tail=0;     BBB.size=0;  #ifdef WIN32     _beginthread((void(__cdecl *)(void *))thdA,0,(void *)1);     _beginthread((void(__cdecl *)(void *))thdB,0,(void *)2); #else     threadsN=0;     rc=pthread_create(&(threads[threadsN++]),NULL,thdA,(void *)1);if (rc) Log("%d=pthread_create %d error!\n",rc,threadsN-1);     rc=pthread_create(&(threads[threadsN++]),NULL,thdB,(void *)2);if (rc) Log("%d=pthread_create %d error!\n",rc,threadsN-1); #endif      if (!access("No_Loop",0)) {         remove("No_Loop");         if (!access("No_Loop",0)) {             No_Loop=1;         }     }     while (1) {         sleep_ms(1000);         if (No_Loop) break;//         if (!access("No_Loop",0)) {             No_Loop=1;         }     }     sleep_ms(3000);     Log("End=============================================================\n"); #ifdef WIN32     DeleteCriticalSection(&cs_BBB );     DeleteCriticalSection(&cs_HEX );     DeleteCriticalSection(&cs_log); #else     pthread_mutex_destroy(&cs_BBB);     pthread_mutex_destroy(&cs_HEX);     pthread_mutex_destroy(&cs_log); #endif     return 0; } 基本看不太懂啊，谢谢您！

引用 楼主 qq_25054087 的回复:我刚学线程不久，要完成如下功能。 要求有两个函数A和B，函数A每次都执行，函数B在A执行了5次后才执行一次，这时B中会生成一些数据，需要传递到A中，函数A更新完这个数据后才接着执行第6次。所以我建了两个线程和一个互斥体。可是根本无法按我想象地运行啊，怎么办？  我写的部分代码如下： void main()   {   	int i; 	// creat the mutex 	hVarMutex=CreateMutex(NULL,FALSE,NULL);   	for(i=1;i<=20;i++) 	{ 		// creat the threads 		hThread1=CreateThread(NULL,0,AFunc,NULL,0,NULL);       		CloseHandle(hThread1);    		if(i%5==0) 		{		 			hThread2=CreateThread(NULL,0,BFunc,NULL,0,NULL);  			CloseHandle(hThread2); 		} 	}  	//All threads done. Clean up handles. 	CloseHandle(hVarMutex); 	system("pause"); }    [quote=引用 1 楼 user-2 的回复:] 你该仔细跟踪你的代码。 hThread1=CreateThread(NULL,0,AFunc,NULL,0,NULL);       CloseHandle(hThread1);   创建了你就关闭了。。还怎么玩？？先想好在修改，看看书上线程一般是如何使用的您好，请问您有推荐的好书吗？我看的书都只讲基础的创建之类，感觉很简单。也可能是我理解地不到位。谢谢您！


Question: opencv的widthstep问题

代码功能归根结底不是别人帮自己看或讲解或注释出来的；而是被自己静下心来花足够长的时间和精力亲自动手单步或设断点或对执行到某步获得的中间结果显示或写到日志文件中一步一步分析出来的。 提醒：再牛×的老师也无法代替学生自己领悟和上厕所！ 单步调试和设断点调试（VS IDE中编译连接通过以后，按F10或F11键单步执行，按Shift+F11退出当前函数；在某行按F9设断点后按F5执行停在该断点处。）是程序员必须掌握的技能之一。  不要迷信书、考题、老师、回帖； 要迷信CPU、编译器、调试器、运行结果。 并请结合“盲人摸太阳”和“驾船出海时一定只带一个指南针。”加以理解。 任何理论、权威、传说、真理、标准、解释、想象、知识……都比不上摆在眼前的事实！  有人说一套做一套，你相信他说的还是相信他做的？ 其实严格来说这个世界上古往今来所有人都是说一套做一套，不是吗？


Question: 菜鸟问题，关于for语句

引用 3 楼 misskissC 的回复:这语句“ for(ch='$' , ch!='g';scanf("%c",&ch))  ”会输出“输出：abcd” Are you 确定？  被我改了...

GCC:

这语句“ for(ch='$';ch!='g';scanf("%c",&ch))  ”会输出“输出：abcd” Are you 确定？

for语句可以这样用？


Question: 如何连续打开显示内容然后关闭 连续文件名的txt文件

Sleep The Sleep function suspends the execution of the current thread for a specified interval.   VOID Sleep(   DWORD dwMilliseconds   // sleep time in milliseconds );   Parameters dwMilliseconds  Specifies the time, in milliseconds, for which to suspend execution. A value of zero causes the thread to relinquish the remainder of its time slice to any other thread of equal priority that is ready to run. If there are no other threads of equal priority ready to run, the function returns immediately, and the thread continues execution. A value of INFINITE causes an infinite delay.  Return Values This function does not return a value.   Remarks A thread can relinquish the remainder of its time slice by calling this function with a sleep time of zero milliseconds.   You have to be careful when using Sleep and code that directly or indirectly creates windows. If a thread creates any windows, it must process messages. Message broadcasts are sent to all windows in the system. If you have a thread that uses Sleep with infinite delay, the system will deadlock. Two examples of code that indirectly creates windows are DDE and COM CoInitialize. Therefore, if you have a thread that creates windows, use MsgWaitForMultipleObjects or MsgWaitForMultipleObjectsEx, rather than Sleep.  QuickInfo   Windows NT: Requires version 3.1 or later.   Windows: Requires Windows 95 or later.   Windows CE: Requires version 1.0 or later.   Header: Declared in winbase.h.   Import Library: Use kernel32.lib.  See Also Processes and Threads Overview, Process and Thread Functions, MsgWaitForMultipleObjects, MsgWaitForMultipleObjectsEx, SleepEx

仅供参考//将c:\\tmp文件夹下的所有文件的内容全部放到用malloc分配的内存中 #include <stdio.h> #include <stdlib.h> #include <string.h> #include <io.h> struct FB {     char fn[256];     size_t fl;     char *b;     struct FB *next;     struct FB *prev; } *fh,*fb,*ft; char ln[256]; char fpn[256]; FILE *af; FILE *f; int L,n; int main() {     system("dir /b /a-d c:\\tmp\\*.* >c:\\allfn.txt");     af=fopen("c:\\allfn.txt","r");     if (NULL==af) {         printf("Can not open file c:\\allfn.txt!\n");         return 1;     }     fh=NULL;     fb=NULL;     n=0;     while (1) {         if (NULL==fgets(ln,256,af)) break;         L=strlen(ln);         if ('\n'==ln[L-1]) ln[L-1]=0;         printf("read %s\n",ln);         strcpy(fpn,"c:\\tmp\\");         strcat(fpn,ln);         ft=(struct FB *)malloc(sizeof(struct FB));         if (NULL==ft) {             printf("Can not malloc ft!\n");             fclose(af);             return 2;//之前的malloc在main退出后由操作系统自动free         }         printf("ft[%d]==%p\n",n,ft);         strcpy(ft->fn,fpn);         f=fopen(fpn,"rb");         if (NULL==f) {             printf("Can not open file %s!\n",fpn);             fclose(af);             return 3;//之前的malloc在main退出后由操作系统自动free         }         ft->fl=_filelength(fileno(f));         ft->b=malloc(ft->fl);         if (NULL==ft->b) {             printf("Can not malloc ft->b!\n");             fclose(f);             fclose(af);             return 4;//之前的malloc在main退出后由操作系统自动free         }         printf("ft[%d]->b==%p\n",n,ft->b);         if (ft->fl!=fread(ft->b,1,ft->fl,f)) {             printf("fread error!\n");             fclose(f);             fclose(af);             return 5;//之前的malloc在main退出后由操作系统自动free         }         fclose(f);         ft->next=NULL;          if (NULL==fh) {             ft->prev=NULL;             fh=ft;         } else {             fb->next=ft;             ft->prev=fb;         }         fb=ft;         n++;     }     fclose(af);     printf("-----list-----\n");     for (ft=fh;NULL!=ft;ft=ft->next) {         printf("%8d %s\n",ft->fl,ft->fn);         if (NULL!=ft) fb=ft;     }     printf("-----free-----\n");     n--;     if (NULL!=fh) {         for (ft=fb->prev;NULL!=ft;ft=ft->prev) {             if (NULL!=ft->next->b) {                 printf("ft[%d]->b==%p\n",n,ft->next->b);                 free(ft->next->b);             }             if (NULL!=ft->next) {                 printf("ft[%d]==%p\n",n,ft->next);                 free(ft->next);             }             n--;         }         if (NULL!=fh->b) {             printf("ft[0]->b==%p\n",fh->b);             free(fh->b);         }         printf("ft[0]==%p\n",fh);         free(fh);     }     return 0; } //C:\tmp\tmp\Debug>dir /a-d c:\tmp // 驱动器 C 中的卷是 C_HD5_1 // 卷的序列号是 1817-D526 // // c:\tmp 的目录 // //找不到文件 // //C:\tmp\tmp\Debug>tmp //找不到文件 //-----list----- //-----free----- // //C:\tmp\tmp\Debug>dir /a-d c:\tmp // 驱动器 C 中的卷是 C_HD5_1 // 卷的序列号是 1817-D526 // // c:\tmp 的目录 // //2011-06-30  18:04            44,840 my_c.rar //2011-06-30  17:18             1,036 err.frm //2011-06-30  14:32            14,243 出租.txt //2011-06-28  12:08            23,681 MSDN98书签.txt //             4 个文件         83,800 字节 //             0 个目录 17,041,870,848 可用字节 // //C:\tmp\tmp\Debug>tmp //read my_c.rar //ft[0]==00421800 //ft[0]->b==00520068 //read err.frm //ft[1]==00421670 //ft[1]->b==0052AFC0 //read 出租.txt //ft[2]==00421530 //ft[2]->b==00378F28 //read MSDN98书签.txt //ft[3]==004213F0 //ft[3]->b==0052B3F8 //-----list----- // 44840 c:\tmp\my_c.rar //  1036 c:\tmp\err.frm // 14243 c:\tmp\出租.txt // 23681 c:\tmp\MSDN98书签.txt //-----free----- //ft[3]->b==0052B3F8 //ft[3]==004213F0 //ft[2]->b==00378F28 //ft[2]==00421530 //ft[1]->b==0052AFC0 //ft[1]==00421670 //ft[0]->b==00520068 //ft[0]==00421800 // //C:\tmp\tmp\Debug>

1、把文件名存入数组，然后循环打开 2、遍历该目录下的文件，逐个打开


Question: 用一重循环对整型数组排序,大神求解!!!!!!

引用 2 楼 zxh707wk 的回复:地精排序 ++

地精排序

可以用 桶式排序


Question: C语言：求高手解决这道题的时间问题

Finding prime numbers - Kenneth Haugland Different schemas for finding prime numbers explained with code http://www.codeproject.com/Articles/429694/Finding-prime-numbers

计算时间是不是应该建立在一个什么样的硬件配置和软件环境里。这样单纯的要求执行时间，未免有歧义。

上面的代码忘记释放num那个数组本身了，请在main函数return之前加上 free(num);

在屏幕上输出10000以内不太现实吧。。计算可以在1s以内，输出差不多要一二十秒 比如下面的程序输出到Console，计算花了0.4s，输出花了23s   如果是输出到文件那还可以，以下是将输出定向到文件的结果   简单写了一下，基本没有考虑异常，不过一般这种题目重点也不在异常处理上吧 #include <stdio.h> #include <stdlib.h> #include <math.h> #include <time.h>  typedef struct _comb { 	int a; 	int b; 	struct _comb *next; } Comb; // 这个函数计算出小于等于n的素数，注意没有包括第一个素数2因为不需要它 void find_primes(int *arr, int n) { 	int i, j, m, s, r; 	 	arr[0] = 3; 	for (i = 5, m = 1; i <= n; i += 2) { 		s = (int)sqrt(i); 		for (j = 0, r = 1; arr[j] <= s && (r = i % arr[j]); j++); 		if (r) { 			arr[m++] = i; 		} 	} } // 这个函数会将任意两个素数组合，如果能组成一个偶数就记录下来，注意num数组的每一个元素都是一个单链表 void find_combs(int *primes, Comb **num, int n) { 	int i, j, m; 	Comb *comb; 	 	for (i = 0; primes[i] < n; i++) { 		for (j = i; (m = primes[i] + primes[j]) <= n; j++) { 			if (!(m & 1)) { 				if (!(comb = num[m >> 1])) { 					comb = (Comb *)malloc(sizeof(Comb)); 					comb->a = primes[i]; 					comb->b = primes[j]; 					comb->next = NULL; 					num[m >> 1] = comb; 				} else { 					while (comb->next) { 						comb = comb->next; 					} 					comb->next = (Comb *)malloc(sizeof(Comb)); 					comb = comb->next; 					comb->a = primes[i]; 					comb->b = primes[j]; 					comb->next = NULL; 				} 			} 		} 	} } // 这个函数输出结果，并且释放堆内存 void print_combs(Comb **num, int n) { 	int i, m; 	Comb *comb, *next; 	 	printf("4=2+2\n"); 	for (i = 3, m = n >> 1; i <= m; i++) { 		comb = num[i]; 		while (comb->next) { 			next = comb->next; 			printf("%d=%d+%d\n", comb->a + comb->b, comb->a, comb->b); 			free(comb); 			comb = next; 		} 		printf("%d=%d+%d\n", comb->a + comb->b, comb->a, comb->b); 		free(comb); 	} }  int main() { 	int primes[1228], n;  //10000以内有1229个素数，因为不需要2所以只用1228个 	Comb **num; 	clock_t start, calc_finish, end; 	 	printf("Enter n:\n"); 	scanf("%d", &n); 	start = clock(); 	 	find_primes(primes, 10000);  // 实际上不需要每次都把10000以内所有素数算出来，但是这个几乎不耗什么时间所以无所谓 	// num[i] 代表数2(i + 3)的所有表示方法，比如num[0]记录6的表示方法，num[1]记录8的表示方法 	// 之所以这样因为1.不需要记录奇数2.小于6的也不需要记录(至于4=2+2因为不管什么输入都要输出这个所以也不用记录) 	num = (Comb **)calloc((n - 4) / 2, sizeof(Comb *)); 	find_combs(primes, num - 3, n); 	calc_finish = clock(); 	 	print_combs(num - 3, n); 	end = clock(); 	 	printf("\nCalculation time: %dms\n", 				(calc_finish - start) * 1000 / CLOCKS_PER_SEC);  	printf("\nTotal running time: %dms\n", 				(end - start) * 1000 / CLOCKS_PER_SEC); 	return 0; }


Question: c语言学生管理系统

一本比较好的C语言书可以解决你的问题，比如C primer plus

1、学习如何调用函数 2、学习如何构造程序逻辑：比如顺序结构、分支结构 3、学习结构体

额，刚看了一下结构体，实在是不怎么懂，但实验还是得尝试着做。老师要求高直接就是工程，我c语言也是在自学过程中。。。。。

你函数都没调用，结构体对象也没啊


Question: 对指针初始化的动态分配问题

有兴趣可以自己封装一个函数，实现根据输入字符串长度，自动扩展空间大小，保证其不越界~C++，java这些也不过是已经封装好了类及其方法，你直接用就好了。

引用 7 楼 onlycaocao 的回复:手动输入n的值也不算特别自动吧，如果要输入的字符串很长，不知道n的值怎么办 取名动态分配而不是自动分配，还是有讲究的，这意味着该变量所指向的空间大小可以动态地改变，而不是说该变量指向的空间根据变量长度自动扩展。字符串很长，不是还有realloc()么。很多自动的含义都是针对用户说的，对于开发者来说，还是要自己去实现一个逻辑

int n = 10; char str[n]; //error char *a=malloc(sizeof(char) * n); //ok  这就是动态分配

引用 11 楼 onlycaocao 的回复:[quote=引用 9 楼 Evankaka 的回复:] 那就上vector...这个就能满足你的要求了，不够它自己会扩大空间   这个是Java里的吧。。我用的c。我看到有个方法是自己写一个类似getstring的函数，里面增加空间是一个一个增加，用的realloc。[/quote] Java里有，C/C++里也有啊，在STL中，还有list,deque,map,set,,,这些都是STL中的，你可以百度下

引用 9 楼 Evankaka 的回复:那就上vector...这个就能满足你的要求了，不够它自己会扩大空间   这个是Java里的吧。。我用的c。我看到有个方法是自己写一个类似getstring的函数，里面增加空间是一个一个增加，用的realloc。

那就上vector...这个就能满足你的要求了，不够它自己会扩大空间

引用 4 楼 Evankaka 的回复:手动输入1000这种数字。。谁叫你一定要输入1000个字了。。？ 你可以定义一个int. n来输入你要的数组的大小 。。 然后再char *a=（char *）malloc(sizeof(char)*n);//这样才叫动态。。你要多大给多大，点儿都不浪费   手动输入n的值也不算特别自动吧，如果要输入的字符串很长，不知道n的值怎么办

引用 2 楼 kino_chen 的回复:一般来说，动态分配就是指用了mallco等函数分配内存。动态分配还是要指定大小的，并不会根据你的输入长度给你申请合适的内存大小。换个角度方便你理解：如果你定义的是数组如char a[100]，那么它就是100个字节大小，再不会变了，无论你怎么操作，这是静态。但是你用malloc，比如以下的方式scanf("%d",&len);malloc(sizeof(char) * len);你输入几，系统就给你分配多少内存，这就是动态。  手动输入n的值也不算特别自动吧，如果要输入的字符串很长，不知道n的值怎么办

@kino_chen 是不是这样回复的。。。。 手动输入n的值也不算特别自动吧，如果要输入的字符串很长，不知道n的值怎么办

存十多个字符本身就是毛病。你只有1个字节。

char *a=（char *）malloc(sizeof(char));.这样写好一点

记住就行了，这样就叫动态分配


Question: 结构体空指针的问题（高手进）

用于得到成员在结构内的偏移量。 有些C的实现允许在->运算符左边使用NULL指针。对结果采用地址运算符&和将这个结果转换成整数类型可以得到结果成员的偏移量（以字节计）。标准没有提到这种做法，没有允许也没有禁止，但显然是可行的： #define OFFSETOF (type,field) ((size_t) & ((type *) 0) -> field)

#define offsetof(type, field)	((long) &((type *)0)->field)  这个是计算type结构中，field成员偏移大小。  CatCTup    *ct = (CatCTup *) (((char *) tuple) -  offsetof(CatCTup, tuple));  这句是从CatCTup结构中tuple成员地址获取tuple所在结构的首地址。tuple地址减去它的偏移大小就是结构的首地址。  这种用法在Linux内核列表的实现中就有用到，你可以去研究一下。


Question: c语言中与（&）的问题（高手进）

hash函数， sz为2的幂级数，如2，8，16这些，减1后二进制看就是全1，得到一个位置。

(Index) ((h) & ((sz) - 1))) ((h) & ((sz) - 1))的结果强制转换i为index类型


Question: 求助C语言popen问题，一直返回为空

加上ping就行了 FILE *pipe=popen("ping www.baidu.com","r");

仅供参考  #include <stdio.h>    #include <netdb.h>    #include <stdlib.h>    #include <arpa/inet.h>  int main(int argc, char *argv[]){    	 	struct addrinfo * res, *pt;    	struct sockaddr_in *sinp;    	const char *addr;    	char abuf[INET_ADDRSTRLEN];    	int succ=0,i=0;     	if(argc == 1)    	{    		printf("USAGE: getip <server name>\nFor example:\n    getip www.google.com\n");    		exit(1);    	}     	succ = getaddrinfo(argv[1], NULL, NULL, &res);    	if(succ != 0)    	{    		printf("Can't get address info! error code = %d", succ);    		exit(succ);    	}     	for(pt=res, i=0; pt != NULL; pt=pt->ai_next, i++){    		sinp = (struct sockaddr_in *)pt->ai_addr;    		addr = (const char *)inet_ntop(AF_INET, &sinp->sin_addr, abuf, INET_ADDRSTRLEN);    		printf("%2d. IP=%s\n", i, addr);    	}    }

这哪跟哪啊。。。popen干嘛的先？

popen是管道操作，跟www.baidu.com有半毛钱关系。 要获取ip得用到网络的函数，跟域名解析有关，好好baidu一下，或者参考下ping的代码 楼主请不要再任性个四小时了。


Question: c程序为什么会报错，求解

pArr->pBase[pArr->cnt] = val;//这行为什么会报错？这一行，首先从语法上就不对，看一下pBase是什么类型，而val是什么类型。类型不匹配而去赋值，至少会给提警告。

pArr->pBase[pArr->cnt] = val;//这行为什么会报错？ pArr->pBase[pArr->cnt] //这个指向的是结构变量 ((pArr->pBase)[pArr->cnt])->cnt = val;

你的pArr->pBase是一个指向struct  Arr的指针，又不是一个指针数组。显然你的val是整形。怎么能赋值。   typedef struct _st_arr tArr;    struct _st_arr   {         int* element;         int  len;         int  cnt;   };  //或者     struct _st_arr  {        void** element;        int    len;       int    cnt;  };

C语言里面没有bool关键字，可以改成int试一试，把true、false改成0、1。

pArr->pBase[pArr->cnt] 这句本来就有问题吧？？ pArr->pBase = null；都没错！

引用 楼主 xia_xiao_xiao 的回复:# include <stdio.h> # include <stdlib.h>//包含exit函数 # include <malloc.h>  struct Arr { 	struct Arr * pBase;//动态数组 	int len;//数组的大小 	int cnt;//数组有效的元素 };  bool is_full_arr (struct Arr * pArr);//判断数组是否为满 bool is_empty_arr (struct Arr * pArr);//判断数组是否为空 void init_arr (struct Arr * pArr, int user_array_length);//初始化 bool show_arr (struct Arr * pArr);//显示数组中的内容 bool append_arr (struct Arr * pArr, int val);//添加   int main (void) { 	struct Arr arr; //	int val; 	int user_array_length;//定义用户键入变量  	printf ("请输入要分配素组的大小：");//提示 	scanf ("%d", &user_array_length);//输入分配的大小 	init_arr (&arr, user_array_length);//调用初始化函数 	 	show_arr (&arr);//显示数组中的内容  	append_arr (&arr,4);//添加  	show_arr (&arr);//显示数组中的内容  	  	return 0; }  bool is_full_arr (struct Arr * pArr)//判断数组是否为满 { 	if (pArr->len == pArr->cnt ) 	{ 		return true; 	} 	else 	{ 		return false; 	} }  bool is_empty_arr (struct Arr * pArr)//判断数组数组为空 { 	if (0 == pArr->cnt) 	{ 		return true; 	} 	else 	{ 		return false; 	} }  void init_arr (struct Arr * pArr, int user_array_length)//初始化 { 	pArr->pBase = (struct Arr *)malloc(sizeof(struct Arr) * user_array_length); /*	注意：pArr一定要指向pBase,类型是sruct Arr类型*/ 	if (NULL == pArr) 	{ 		printf ("数组分配失败！\n"); 	} 	else 	{ 		pArr->len = user_array_length; 		pArr->cnt = 0; 		printf ("数组分配成功！\n"); 		printf ("初始化成功！\n"); 	} 	return; }  bool show_arr (struct Arr * pArr)//显示数组中的内容 { 	if ( is_empty_arr(pArr) ) 	{ 		printf ("数组没有内容可显示！\n"); 		return false; 	} 	else 	{ 		int i; 		for (i=0; i<pArr->len; i++) 		{ 			printf ("%d", pArr->pBase[i]); 		} 		return true; 	} }  bool append_arr (struct Arr * pArr, int val)//添加 { 	if ( is_full_arr(pArr) ) 	{ 		printf ("数组满了，添加失败！\n"); 		return false; 	} //		int user_figure; //		printf ("数组还有空间，请输入要添加的数值："); //		scanf ("%d", &user_figure); 		pArr->pBase[pArr->cnt] = val;//这行为什么会报错？ 		(pArr->cnt)++; 		return true; }  求解释啊  你这是将一个链表的下一个节点等于一个整形数字，这就好比别人问你家在哪？你说在13那。你说能对吗？

楼主是不是定义的结构有问题啊 pbase里面的struct arr类型元素 可以直接printf出来吗？ C++里面这种类似的操作好像要重载<<操作符。

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

不是这个原因，c里面有bool关键字的，报错的是113行


Question: 这个程序我是想从大到小输入数字到数组里面的，然后再用折半查找法来查询，但不知道哪里出错了，请大神详细指点一下，谢谢

哪里是从小到大查询  不明白

输入从大到小，查找又是按从小到大的？


Question: 直接写不行, 定义一个临时变量就可以了, 是什么情况

引用 10 楼 zhao4zhong1 的回复:intel CPU在宽变量未Align时，仍可以操作，只是效率略低。 arm CPU在宽变量未Align时，报错。 计算机组成原理→DOS命令→汇编语言→C语言（不包括C++）、代码书写规范→数据结构、编译原理、操作系统→计算机网络、数据库原理、正则表达式→其它语言（包括C++）、架构……  《The Intel 64 and IA-32 Architectures Software Developer's Manual》 对应这个手册arm也有类似手册。  CPU特性是计算机软件的重要基础知识之一。

格式一定呀正确

对齐的问题...

引用 11 楼 ma100 的回复:  #include <iostream>    using namespace std; #define __int64 long long #pragma pack (  1 ) struct A_STRUCT //  {  	bool bOffsetON[6]; 	__int64 StartF[6]; }x;   template <typename T > T CalculGP ( const T &x1  ) { 	 return x1;  }  int main() { 	x.StartF[0] = 100; 	  	cout << CalculGP ( x.StartF[0] ) << endl; //输出1677721600  	return 0; }  	   我只是觉得有点奇怪 pack(1)了后面不用pack()取消掉后面的字节对齐状态。 另外你确定你模板没写<x>会编译通过么……我觉得一般来说编译器不会出这种错误吧……

arm编译器， 应该是字节对齐错了 把 template <typename T > T CalculGP ( const T &x1  ) {      return x1;  }  改为普通函数也错 ------------------------------------------------------------------ 这属于编译器的缺陷还是arm的缺陷还是程序的呢？

引用 11 楼 ma100 的回复:  #include <iostream>    using namespace std; #define __int64 long long #pragma pack (  1 ) struct A_STRUCT //  {  	bool bOffsetON[6]; 	__int64 StartF[6]; }x;   template <typename T > T CalculGP ( const T &x1  ) { 	 return x1;  }  int main() { 	x.StartF[0] = 100; 	  	cout << CalculGP ( x.StartF[0] ) << endl; //输出1677721600  	return 0; }  	   啥编译器啊，这么牛叉？我试了几个都是输出的 100。

把代码上全了，中间的 ... 都干啥了。

引用 7 楼 ma100 的回复:[quote=引用 5 楼 mujiok2003 的回复:] 在call之前data的值是否一致?  怎么看是否一致?  有初始化和赋值, ...省略了[/quote] 调试或加log

引用 5 楼 mujiok2003 的回复:在call之前data的值是否一致?  怎么看是否一致?  有初始化和赋值, ...省略了

上告警信息吧！

在call之前data的值是否一致?

1、调试看看具体是什么问题 2、把data换成全局变量试试看  引用 楼主 ma100 的回复:在一段代码中  { __int64 data; ... ;  fun (  data ); //作为参数传入  函数执行失败  改为 __int64 data; ... ; __int64 t = data;  fun (  t ); //执行成功 }   这种情况是不是栈空间不够用了? (在pc上成功, 在arm上失败的)

“函数执行失败”是几个意思？

看不出栈不够用。

data没有初始化。。pc上编译器和arm处理未初始化的变量机制不同吧

应该是Data为初始化


Question: C语言文本文件操作问题

就第一行的“301101”来说 这是6个字符 在机器的内存里就是48个BIT  难道在输出到屏幕的时候 %ld格式读取了这48个BIT然后 得出值301101 然后将它输出到屏幕？

你处理的文本文件里面就是文本字符，读到流里面也是文本字符，只是你读入的时候将这些文本字符进行了格式化

fscanf就是按字符处理的。

不明白你指的“这里”是哪里，详细一点说明下咯

你这里就是字符啊，只是说数字字符被你格式化输入了而已


Question: 热烈庆祝本人受关注人数即将突破7000大关！散分！！＋“代码修改自身”例子

修改自身也是打补丁的一个好手段啊！

马上六一儿童节了，是不是除了关注以外，顺带给个六一儿童节的慰问啊，好让我们这群大宅男开心

赵老师，我也要接分，关注你多时了

哈哈，来论坛看过楼主几次，膜拜一下，顺便关注一下。

嗯，关于赵老师你问的那个问题，说实话我也不懂。抱歉，不能给你一个答案。

都快过年了赵老师依旧为自己喜欢的东西去努力，赵老师真的是太认真、太努力了。在问一下赵老师，为什么有些人总是喜欢骂你呢？我感觉赵老师您做人挺热心的呀？

赵老师要普天同庆啊

糊里糊涂的进来 糊里糊涂的 走  已关注

拜访下赵老师

nice，欢欢喜喜过大年！

恭喜恭喜，小白前来道贺

虽然不是前排，但不耽误围观赵老师  不明而觉厉

吊炸天。。。膜拜一下，不知道老师对阅读源代码有何建议吗？我打算将一部分源代码抽出来进行编译。。。

厉害，赵老师

哈哈，来论坛看过楼主几次，膜拜一下，顺便关注一下。

接分，接分，接赵老师的分。

300分全给我，我顶你

引用 33 楼 u010399796 的回复:我是来看29楼的.. 那我给不给分呢？


Question: 【求教】一个关于头文件的问题

引用 4 楼 jinling4388 的回复:这个一般都没什么特定的含义，但是一般都是有意义的单词组合起来的，有时会加上时间等产生的随机数  恩呢 懂了 谢赐教，嘿嘿

引用 3 楼 a30037338 的回复:[quote=引用 2 楼 xinwei1295 的回复:] [quote=引用 1 楼 a30037338 的回复:] 这个就是一般的防止头文件钻石包含的语法啊 正常我们这么写 #ifndef    XXX_H_ #define XXX_H_  #endif 这里括号里的一大串就是一个宏， 开始判断如果这个宏没定义， 那么就定义这个宏  也就是这个宏并没有什么特殊的含义是吧？[/quote] 是的[/quote]  哦了 懂了  万分感谢

引用 2 楼 xinwei1295 的回复:[quote=引用 1 楼 a30037338 的回复:] 这个就是一般的防止头文件钻石包含的语法啊 正常我们这么写 #ifndef    XXX_H_ #define XXX_H_  #endif 这里括号里的一大串就是一个宏， 开始判断如果这个宏没定义， 那么就定义这个宏  也就是这个宏并没有什么特殊的含义是吧？[/quote] 是的

引用 1 楼 a30037338 的回复:这个就是一般的防止头文件钻石包含的语法啊 正常我们这么写 #ifndef    XXX_H_ #define XXX_H_  #endif 这里括号里的一大串就是一个宏， 开始判断如果这个宏没定义， 那么就定义这个宏  也就是这个宏并没有什么特殊的含义是吧？


Question: 指针类型转换

引用 7 楼 q3733353520 的回复:[quote=引用 4 楼 zhao4zhong1 的回复:] 作为一个C程序员，对  scanf,sscanf,fscanf  printf,sprintf,fprintf 这类函数的用法，还是要做到“拳不离手，曲不离口”的。  printf里面的%和变量的一一对应关系 scanf里面的%和变量以及变量前加不加&的一一对应关系 是C代码中非常容易出错的地方，而且通常编译还不出错。 所以在编译源代码之前值得专门仔细检查一遍甚至多遍。  #include <stdio.h>  int main(void){     int n=2147483647;     int*  p=&n;     short* s=(short*)p;      printf("%p,%x,%d\n",p,*p,*p);      printf("%p,%hx,%hd\n\n",s,(unsigned short)*s,( short)*s);     printf("%p,%hx,%hd\n\n",s,( short)*s,( short)*s);      printf("%p,%hx,%hd\n\n",s,*s,*s);         return 0 ; } Size and Distance Specification The optional prefixes to type, h, l, and L, specify the “size” of argument (long or short, single-byte character or wide character, depending upon the type specifier that they modify). These type-specifier prefixes are used with type characters in printf functions or wprintf functions to specify interpretation of arguments, as shown in the following table. These prefixes are Microsoft extensions and are not ANSI-compatible.  Table R.6   Size Prefixes for printf and wprintf Format-Type Specifiers  To Specify Use Prefix With Type Specifier  long int l d, i, o, x, or X  long unsigned int l u  short int h d, i, o, x, or X  short unsigned int h u  __int64 I64 d, i, o, u, x, or X  Single-byte character with printf functions  h c or C  Single-byte character with wprintf functions h c or C  Wide character with printf functions l c or C  Wide character with wprintf functions l c or C  Single-byte – character string with printf functions h s or S  Single-byte – character string with wprintf functions h s or S  Wide-character string with printf functions l s or S  Wide-character string with wprintf functions l s or S    Thus to print single-byte or wide-characters with printf functions and wprintf functions, use format specifiers as follows.  To Print Character As Use Function With Format Specifier  single byte printf c, hc, or hC  single byte wprintf C, hc, or hC  wide wprintf c, lc, or lC  wide printf C, lc, or lC    To print strings with printf functions and wprintf functions, use the prefixes h and l analogously with format type-specifiers s and S.如何输出 7fff?[/quote]  我知道了    #include <stdio.h>  int main(void){ 	int n=2147483647; 	int*  p=&n; 	short* s=(short*)p;  	printf("%p,%x,%d\n",p,*p,*p);  	printf("%p,%hx,%hd\n\n",s,(unsigned short)*s,( short)*s); 	printf("%p,%hx,%hd\n\n",s,( short)*s,( short)*s);  	printf("%p,%hx,%hd\n\n",s,*(++s),*s);   	return 0 ; }

引用 4 楼 zhao4zhong1 的回复:作为一个C程序员，对  scanf,sscanf,fscanf  printf,sprintf,fprintf 这类函数的用法，还是要做到“拳不离手，曲不离口”的。  printf里面的%和变量的一一对应关系 scanf里面的%和变量以及变量前加不加&的一一对应关系 是C代码中非常容易出错的地方，而且通常编译还不出错。 所以在编译源代码之前值得专门仔细检查一遍甚至多遍。  #include <stdio.h>  int main(void){     int n=2147483647;     int*  p=&n;     short* s=(short*)p;      printf("%p,%x,%d\n",p,*p,*p);      printf("%p,%hx,%hd\n\n",s,(unsigned short)*s,( short)*s);     printf("%p,%hx,%hd\n\n",s,( short)*s,( short)*s);      printf("%p,%hx,%hd\n\n",s,*s,*s);         return 0 ; } Size and Distance Specification The optional prefixes to type, h, l, and L, specify the “size” of argument (long or short, single-byte character or wide character, depending upon the type specifier that they modify). These type-specifier prefixes are used with type characters in printf functions or wprintf functions to specify interpretation of arguments, as shown in the following table. These prefixes are Microsoft extensions and are not ANSI-compatible.  Table R.6   Size Prefixes for printf and wprintf Format-Type Specifiers  To Specify Use Prefix With Type Specifier  long int l d, i, o, x, or X  long unsigned int l u  short int h d, i, o, x, or X  short unsigned int h u  __int64 I64 d, i, o, u, x, or X  Single-byte character with printf functions  h c or C  Single-byte character with wprintf functions h c or C  Wide character with printf functions l c or C  Wide character with wprintf functions l c or C  Single-byte – character string with printf functions h s or S  Single-byte – character string with wprintf functions h s or S  Wide-character string with printf functions l s or S  Wide-character string with wprintf functions l s or S    Thus to print single-byte or wide-characters with printf functions and wprintf functions, use format specifiers as follows.  To Print Character As Use Function With Format Specifier  single byte printf c, hc, or hC  single byte wprintf C, hc, or hC  wide wprintf c, lc, or lC  wide printf C, lc, or lC    To print strings with printf functions and wprintf functions, use the prefixes h and l analogously with format type-specifiers s and S.如何输出 7fff?

引用 2 楼 user-6 的回复:注意大小端的问题啊 如何输出 7fff

什么大端小端，什么sprintf之类的，你连值的对象表示都搞不清楚，还谈什么输出。

引用 10 楼 u012683733 的回复:引用 9 楼 BuleRiver 的回复:有大小端问题吧short类型应该是2字节，为什么（short）*s的输出会是字节的ffff ffff？？？ 参考 C:\Program Files\Microsoft Visual Studio 10.0\VC\crt\src\output.c

尝试把一段不是声明类型的指针指向的地址强制转换未另外一种指针时，尝试用一种不属于他自身的含义去解释那段内存时，后果都是很严重的。。。

有大小端问题吧

short* s=(short*)p;  --可能是未定义的行为。--A pointer to an object type may be converted to a pointer to a different object type. If the resulting pointer is not correctly aligned68) for the referenced type, the behavior is undefined.        别的就不评论了。以某种类型访问另一种不同的类型，还涉及到对象表示（object representation）。标准对对象表示中的字节顺序没有强加约束，输出不同自然也不奇怪。

引用 2 楼 user-6 的回复:注意大小端的问题啊大神，能不能详细解释下？？请多多指教！！

注意大小端的问题啊


Question: windows编程新手提问,<关于声音>

谢谢，是我没有放到里面。。。

PlaySound The PlaySound function plays a sound specified by the given filename, resource, or system event. (A system event may be associated with a sound in the registry or in the WIN.INI file.)   BOOL PlaySound(   LPCSTR pszSound,     HMODULE hmod,        DWORD fdwSound     );   Parameters pszSound  A string that specifies the sound to play. If this parameter is NULL, any currently playing waveform sound is stopped. To stop a non-waveform sound, specify SND_PURGE in the fdwSound parameter.  Three flags in fdwSound (SND_ALIAS, SND_FILENAME, and SND_RESOURCE) determine whether the name is interpreted as an alias for a system event, a filename, or a resource identifier. If none of these flags are specified, PlaySound searches the registry or the WIN.INI file for an association with the specified sound name. If an association is found, the sound event is played. If no association is found in the registry, the name is interpreted as a filename.   hmod  Handle of the executable file that contains the resource to be loaded. This parameter must be NULL unless SND_RESOURCE is specified in fdwSound.  fdwSound  Flags for playing the sound. The following values are defined:  SND_APPLICATION  The sound is played using an application-specific association.  SND_ALIAS  The pszSound parameter is a system-event alias in the registry or the WIN.INI file. Do not use with either SND_FILENAME or SND_RESOURCE.  SND_ALIAS_ID  The pszSound parameter is a predefined sound identifier.  SND_ASYNC  The sound is played asynchronously and PlaySound returns immediately after beginning the sound. To terminate an asynchronously played waveform sound, call PlaySound with pszSound set to NULL.  SND_FILENAME  The pszSound parameter is a filename.  SND_LOOP  The sound plays repeatedly until PlaySound is called again with the pszSound parameter set to NULL. You must also specify the SND_ASYNC flag to indicate an asynchronous sound event.  SND_MEMORY  A sound event's file is loaded in RAM. The parameter specified by pszSound must point to an image of a sound in memory.  SND_NODEFAULT  No default sound event is used. If the sound cannot be found, PlaySound returns silently without playing the default sound.  SND_NOSTOP  The specified sound event will yield to another sound event that is already playing. If a sound cannot be played because the resource needed to generate that sound is busy playing another sound, the function immediately returns FALSE without playing the requested sound.  If this flag is not specified, PlaySound attempts to stop the currently playing sound so that the device can be used to play the new sound.   SND_NOWAIT  If the driver is busy, return immediately without playing the sound.  SND_PURGE  Sounds are to be stopped for the calling task. If pszSound is not NULL, all instances of the specified sound are stopped. If pszSound is NULL, all sounds that are playing on behalf of the calling task are stopped.  You must also specify the instance handle to stop SND_RESOURCE events.   SND_RESOURCE  The pszSound parameter is a resource identifier; hmod must identify the instance that contains the resource.  SND_SYNC  Synchronous playback of a sound event. PlaySound returns after the sound event completes.  Return Values Returns TRUE if successful or FALSE otherwise.  Remarks The sound specified by pszSound must fit into available physical memory and be playable by an installed waveform-audio device driver. PlaySound searches the following directories for sound files: the current directory; the Windows directory; the Windows system directory; directories listed in the PATH environment variable; and the list of directories mapped in a network. For more information about the directory search order, see the documentation for the OpenFile function.  If it cannot find the specified sound, PlaySound uses the default system event sound entry instead. If the function can find neither the system default entry nor the default sound, it makes no sound and returns FALSE.  QuickInfo   Windows NT: Requires version 3.1 or later.   Windows: Requires Windows 95 or later.   Windows CE: Unsupported.   Header: Declared in mmsystem.h.   Import Library: Use winmm.lib.   Unicode: Implemented as Unicode and ANSI versions on Windows NT.  See Also Waveform Audio Overview, Waveform Functions

都这样了 还新手 比我厉害好多

.wav文件只能和你打开的那个.exe文件放在一起……然后你再看看.wav的文件名对不对，试试它在.exe的那个文件夹里能不能正常播放~

引用 1 楼 u010982299 的回复:你有没有把声音文件与exe文件放在同一目录 有

不错，还知道显式地加入winmm.lib

你有没有把声音文件与exe文件放在同一目录


Question: 为什么有人说我这个程序是输入从大到小，查找又是按从小到大的？....我不明白查找还分从小到大，，，小弟理解能力不行，就知道这是折半查找法，还有这程序输出结果错误

引用 楼主 qq2060792279 的回复:#include <stdio.h> #define N 5 void main() {int a[N],i,num,flag=1,bot,end,mid,loc,sign; char c; printf("请从大到小输入N个数:"); scanf("%d",&a[0]); i=1; while(i<N) {scanf("%d",&a[i]); if(a[i]<=a[i-1])    i++; else printf("输入错误,请重新输入：");} while(flag) {printf("请输入要查找的数:"); scanf("%d",&num); if(num>a[0]||num<a[N-1])                         求大神详细告诉我我这个程序怎么个从小到大查找的，，，，，，谢谢 loc=-1; bot=0; end=N-1; sign=0; while((!sign)&&(bot<=end)) {mid=(bot+end)/2; if(num==a[mid]) {loc=mid; printf("%d是第%d个数\n",num,loc+1); sign=1;} else if(num<a[mid]) end=mid-1; else bot=mid+1;} if(loc==-1||!sign) printf("此数不在范围内.\n"); printf("是否继续查找?(Y/N):"); getchar(); scanf("%c",&c); if(c=='N'||c=='n') flag=0;} }  这不是很明显吗？ 从大到小输入N个数那么最小的数是不是num【n-1】里的数？？  你这个查找算法有问题吧，而且是大问题。效率太低了

我好像之前回过这个贴子 举个例子 [ 6，5，4，3，2，1，0]， bot=0,end=6,mid=3,如果num==5,你回答一下bot和end分别应该是多少？


Question: apue  第一章 程序1-5

(pid = fork() < 0)谁是这么写的

引用 2 楼 user-2 的回复:((pid=fork())<0)

#include "ourhdr.h"  int main() { 	char buf[MAXLINE]; 	pid_t pid; 	int status;  	printf("%% ");  	while(fgets(buf,MAXLINE,stdin) != NULL) 	{ 		buf[strlen(buf) -1] = 0; 	 		printf("buf = [%s]\n", buf); 		if(pid = fork() < 0) 			err_sys("fork error"); 		else if(pid == 0) 		{ 			execlp(buf, buf, NULL); 			err_sys("couldn't execute: %s pid = [%d]", buf,getpid()); 			exit(127); 		}else if(pid > 0){  			printf("parent pid = [%d]\n", getpid()); 			if( (pid = waitpid(pid, &status,0)) <0) 				err_sys("waitpid error"); 			printf("%% "); 		 		 		}  	} 	exit(0); }   代码重贴


Question: 自学C语言求助

直接学习编译原理  和 计算机组成原理

最简单的办法，去某个新华书店，买一本全国二级C语言过级的书去，那个也是从最初级的讲起的，要钱还少。

引用 12 楼 zhao4zhong1 的回复:[quote=引用 11 楼 puxinping 的回复:] 这么牛逼的问题没有我的偶像赵老师真是美中不足。 先下载Win-TC，然后参考C:\Win-TC\tcstudy.chm [/quote] 直接看文档不太好，还是建议先去看视频教程，再看c prime之类进阶的书

引用 19 楼 sholber 的回复:[quote=引用 12 楼 zhao4zhong1 的回复:] [quote=引用 11 楼 puxinping 的回复:] 这么牛逼的问题没有我的偶像赵老师真是美中不足。 先下载Win-TC，然后参考C:\Win-TC\tcstudy.chm [/quote]  某学生：第一次玩计算机，WINDOWS 7不会用，请问有什么好推荐？ 赵老湿：请买一台80386，然后安装MS-DOS 3.3 某学生：……[/quote] zhao4zhong1：请买一把电烙铁，然后……

引用 20 楼 sholber 的回复:[quote=引用 12 楼 zhao4zhong1 的回复:] [quote=引用 11 楼 puxinping 的回复:] 这么牛逼的问题没有我的偶像赵老师真是美中不足。 先下载Win-TC，然后参考C:\Win-TC\tcstudy.chm [/quote]  路人甲：赵老板，有草纸吗？ 赵老湿：木有草纸，有上好的砂纸要不要？[/quote] zhao4zhong1：有正品粘蝇纸要不要？

C和指针。这本书我觉得真心不错。

我推荐一个fenby的视频网站吧... 看书之前看看这个网站的视频我觉得应该会有点帮助

《C primer plus》严重推荐啊

引用 12 楼 zhao4zhong1 的回复:[quote=引用 11 楼 puxinping 的回复:] 这么牛逼的问题没有我的偶像赵老师真是美中不足。 先下载Win-TC，然后参考C:\Win-TC\tcstudy.chm [/quote]  路人甲：赵老板，有草纸吗？ 赵老湿：木有草纸，有上好的砂纸要不要？

引用 12 楼 zhao4zhong1 的回复:[quote=引用 11 楼 puxinping 的回复:] 这么牛逼的问题没有我的偶像赵老师真是美中不足。 先下载Win-TC，然后参考C:\Win-TC\tcstudy.chm [/quote]  某学生：第一次玩计算机，WINDOWS 7不会用，请问有什么好推荐？ 赵老湿：请买一台80386，然后安装MS-DOS 3.3 某学生：……

找本好书，比如上面说的C primer plus 另外，主要的是多动手练习，多敲代码

引用 14 楼 zsl_2014 的回复:1.谭浩强的《C程序设计》最基础了 2.《C primer plus》 谭浩强那本是坑代码不规范还一堆错,建议还是C primer plus

谭浩强的也行，英语的话就是C primer plus了，还是得多敲代码才行

C primer plus

1.谭浩强的《C程序设计》最基础了 2.《C primer plus》

C primer plus

引用 11 楼 puxinping 的回复:这么牛逼的问题没有我的偶像赵老师真是美中不足。 先下载Win-TC，然后参考C:\Win-TC\tcstudy.chm

这么牛逼的问题没有我的偶像赵老师真是美中不足。

谭浩强的最基础了

是进来看赵老师回复的


Question: 求高手帮忙指导指导 分析下我这个程序实现的难度

如果不要求很细的话，考虑用下libcurl，如果我没记错一次HTTP请求libcurl的API会将其阻塞直到超时或者数据返回（也就是同步），记录下请求时间和回调返回时间就好了。

或者参考Linux源代码中相关片断。

先学会使用抓包软件比如wireshark 然后搜winpcap相关例子代码。


Question: 为什么字符移位解密文件后，文件的内容后面会多出一个问号（急求解答）

循环次数多啦！ 1. ch 的类型应该是int而不是char 2. 用 fgetc 返回值判断是否EOF，不要用feof  #include<stdio.h> #include<stdlib.h>  //1.txt加密以后保存到1jia.txt,解密以后保存到1jie.txt void jia() { 	int ch; 	FILE *pfr;//读取1.txt 	FILE *pfw;//写入1jia.txt 	char pathr[100]="1.txt"; 	char pathw[100]="1jia.txt";  	pfr=fopen(pathr,"rb");//用读的模式打开被加密的文件 	pfw=fopen(pathw,"wb");//用写的模式打开要写入加密的文件 	if (pfr==NULL || pfw==NULL) 	{ 		printf("文件故障,加密失败"); 		return; 	} 	while ((ch=fgetc(pfr)) != EOF)//一直读到要加密的文本的末尾 	{ 		ch=ch+1;//字符移位加密 		fputc(ch,pfw);//写入文本 	} 	fclose(pfw); 	fclose(pfr); }  void jie() { 	int ch; 	FILE *pfr;//读取1jia.txt 	FILE *pfw;//写入1jie.txt 	char pathr[100]="1jia.txt"; 	char pathw[100]="1jie.txt"; 	pfr=fopen(pathr,"rb");//用读的模式打开加密以后的文件 	pfw=fopen(pathw,"wb");//用写的模式打开要写入解密的文件 	if (pfr==NULL || pfw==NULL) 	{ 		printf("文件故障,解密失败"); 		return; 	} 	while ((ch=fgetc(pfr)) != EOF)//一直读到要解密的文本的末尾 	{ 		ch=ch-1;//字符移位解密 		fputc(ch,pfw);//写入文本 	} 	fclose(pfw); 	fclose(pfr); }  int main(void) {  	jia(); 	jie(); 	return 0; }

？是-51 给最后一个元素赋值0

是不是你解密最后解错了，最后出了不可打印字符。然后自动给你替换为 ？ 显示了

while (1)//一直读到要加密的文本的末尾 { char ch=fgetc(pfr);//读取文本 if( feof(pfr) ) break; ch=ch+1;//字符移位加密 fputc(ch,pfw);//写入文本 }

用VS2013编译器就不会出现这个问题,这应该是VC6编译器的BUG吧?

用十六进制编辑器看看问号是什么，一般是只有\r 没有\n 会出现问号

不要使用 while (条件) 更不要使用 while (组合条件) 要使用 while (1) {  if (条件1) break;  //...  if (条件2) continue;  //...  if (条件3) return;  //... } 因为前两种写法在语言表达意思的层面上有二义性，只有第三种才忠实反映了程序流的实际情况。 典型如： 下面两段的语义都是当文件未结束时读字符 while (!feof(f)) {  a=fgetc(f);  //...  b=fgetc(f);//可能此时已经feof了！  //... } 而这样写就没有问题： while (1) {  a=fgetc(f);  if (feof(f)) break;  //...  b=fgetc(f);  if (feof(f)) break;  //... } 类似的例子还可以举很多。


Question: 求指导  最近在学c语言，看什么书比较好

看赵老师回复

话说DOS命令还要学吗？感觉不是非常重要。。

谢谢！对我帮助很大！！

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

感觉自己c语言水平太低了。。有没有什么好书推荐一下

计算机专业c语言掌握的应该差不多了吧， 数据结果算法可以搞一搞， 链表，二叉树，的增删改查，  栈， 队列的实现，  查找算法(二分法)， 排序算法(冒泡， 插入， 选择， 快速等)，  这些都搞完了， 就尝试搞些小项目练手， 看别人的开源代码， 都是可以的。


Question: 用C语言读取计算机cpu、硬盘等主要硬件信息并输出到文本文件、MS Word

PS：上面获取的CPU ID和硬盘ID是伪ID； CPU信息想要获取更详细的要内嵌汇编； 硬盘ID，可以考虑CWMI； 不过两种方法都比较麻烦。

LS的太偷懒了。。。。 这个是我写的批处理脚本，LZ可以自己移植到C上，难度不大。 @echo off&setlocal ENABLEDELAYEDEXPANSION set sig=0 for /f %%i in ('wmic DISKDRIVE get Caption') do ( set /a sig+=1 if !sig!==2 set pcid=%%i ) echo 硬盘 ID为	: %pcid%  set sig=0 for /f %%i in ('wmic cpu get ProcessorId') do ( set /a sig+=1 if !sig!==2 set pcid=%%i ) echo CPU ID为	: %pcid%  set sig=0 for /f %%i in ('wmic BASEBOARD get SerialNumber') do ( set /a sig+=1 if !sig!==2 set pcid=%%i ) echo 主板 ID为	: %pcid%  set sig=0 for /f %%i in ('wmic computersystem get caption') do ( set /a sig+=1 if !sig!==2 set pcid=%%i ) echo 计算机名为	: %pcid%  set sig=0 for /f %%i in ('wmic computersystem get name') do ( set /a sig+=1 if !sig!==2 set pcid=%%i ) echo 用户名为	: %pcid%  set sig=0 for /f %%i in ('wmic NICCONFIG where "index='1'" get ipaddress') do ( set /a sig+=1 if !sig!==2 set pcid=%%i ) echo IP地址为	: %pcid%  set sig=0 for /f %%i in ('wmic NICCONFIG where "index='1'" get macaddress') do ( set /a sig+=1 if !sig!==2 set pcid=%%i ) echo MAC地址为	: %pcid%  echo. pause

system("systeminfo >sysinfo.txt"); //然后读文件sysinfo.txt的内容。