Question: 全排列求指导 递归怎么用

“给定一个小点的输入，完整单步跟踪(同时按Alt+7键查看Call Stack里面从上到下列出的对应从里层到外层的函数调用历史)一遍。”是理解递归函数工作原理的不二法门！ 递归函数关注以下几个因素 ·退出条件 ·参数有哪些 ·返回值是什么 ·局部变量有哪些 ·全局变量有哪些 ·何时输出 ·会不会导致堆栈溢出 //qplw.cpp #include <stdio.h> #include <string.h> #include <stdlib.h> int v=0; int w=0; int m;//记录字符串长度 int n;//记录字符串中的字符种类数 char map[256];//记录是哪几种字符 int count[256];//记录每种字符有多少个 int stack[1000];//递归用的栈，并记录当前生成的排列 void Make_Map(char *str) {//统计字符串的相关信息     int s[256];     int i;     memset(s,0,sizeof(s));     memset(count,0,sizeof(count));     m=strlen(str);     if (w<1 || m<w) w=m;     while(*str) {         s[*str]++;         str++;     }     n=0;     for (i=0;i<256;i++)         if (s[i]) {             map[n]=i;             count[n]=s[i];             n++;         } } void Find(int depth) {//递归式回溯法生成全排列     if (depth==w) {         int i;         for (i=0;i<depth;i++) putchar(map[stack[i]]);         putchar('\n');     } else {         int i;         if (v && depth>0) {             for (i=0;i<depth;i++) putchar(map[stack[i]]);             putchar('\n');         }         for (i=0;i<n;i++)             if (count[i]) {                 stack[depth]=i;                 count[i]--;                 Find(depth+1);                 count[i]++;             }     } } void main(int argc,char**argv) {     if (argc<2) {         printf("%s 要产生全排列的字符串 [限定长度|-1]\n",argv[0]);         return;     }     if (argc>=3) w=atoi(argv[2]);     if (-1==w) v=1;     Make_Map(argv[1]);     Find(0); } //C:\test>qplw //qplw 要产生全排列的字符串 [限定长度|-1] // //C:\test>qplw 123 //123 //132 //213 //231 //312 //321 // //C:\test>qplw 123 2 //12 //13 //21 //23 //31 //32 // //C:\test>qplw 122333 3 //122 //123 //132 //133 //212 //213 //221 //223 //231 //232 //233 //312 //313 //321 //322 //323 //331 //332 //333 // //C:\test>qplw 123 -1 //1 //12 //123 //13 //132 //2 //21 //213 //23 //231 //3 //31 //312 //32 //321 //

仅供参考：//全排列的生成算法 //  全排列的生成算法就是对于给定的字符集，用有效的方法将所有可能的全排列无重复无遗漏地枚举出来。任何n个字符集的排列都可以与1～n的n个数字的排列一一对应， //  因此在此就以n个数字的排列为例说明排列的生成法。 //  n个字符的全体排列之间存在一个确定的线性顺序关系。所有的排列中除最后一个排列外，都有一个后继；除第一个排列外，都有一个前驱。每个排列的后继都可以从 //  它的前驱经过最少的变化而得到，全排列的生成算法就是从第一个排列开始逐个生成所有的排列的方法。 //  全排列的生成法通常有以下几种： //  字典序法 //  递增进位数制法 //  递减进位数制法 //  邻位交换法 //  递归类算法 //1.字典序法 效率高且顺序自然 //  字典序法中，对于数字1、2、3......n的排列，不同排列的先后关系是从左到右逐个比较对应的数字的先后来决定的。例如对于5个数字的排列12354和12345，排列12345在前， //  排列12354在后。按照这样的规定，5个数字的所有的排列中最前面的是12345，最后面的是54321。 //  字典序算法如下： //  设P是1～n的一个全排列:p=p1p2......pn=p1p2......pj-1pjpj+1......pk-1pkpk+1......pn //  1）从排列的右端开始，找出第一个比右边数字小的数字的序号j（j从左端开始计算），即 j=max{i|pi<pi+1} //  2）在pj的右边的数字中，找出所有比pj大的数中最小的数字pk，即 k=max{i|pi>pj}（右边的数从右至左是递增的，因此k是所有大于pj的数字中序号最大者） //  3）对换pi，pk //  4）再将pj+1......pk-1pkpk+1pn倒转得到排列p’’=p1p2.....pj-1pjpn.....pk+1pkpk-1.....pj+1，这就是排列p的下一个下一个排列。 //  例如839647521是数字1～9的一个排列。从它生成下一个排列的步骤如下： //  自右至左找出排列中第一个比右边数字小的数字4 839647521 //  在该数字后的数字中找出比4大的数中最小的一个5 839647521 //  将5与4交换 839657421 //  将7421倒转 839651247 //  所以839647521的下一个排列是839651247。 //2.递增进位数制法 //  在递增进位制数法中，从一个排列求另一个排列需要用到中介数。如果用 ki表示排列p1p2...pi...pn中元素pi的右边比pi小的数的个数，则排列的中介数就是对应的 //  排列k1 ...... ki...... kn-1。 //  例如排列839647521的中介数是72642321，7、2、6、......分别是排列中数字8、3、9、......的右边比它小的数字个数。 //  中介数是计算排列的中间环节。已知一个排列，要求下一个排列，首先确定其中介数，一个排列的后继，其中介数是原排列中介数加1，需要注意的是，如果中介数的 //  末位kn-1+1=2，则要向前进位，一般情形，如果ki+1=n-i+1，则要进位，这就是所谓的递增进位制。例如排列839647521的中介数是72642321，则下一个排列的中介数 //  是67342221+1=67342300（因为1+1=2，所以向前进位，2+1=3，又发生进位，所以下一个中介数是67342300）。 //  得到中介数后，可根据它还原对应得排列。 //  算法如下： //  中介数k1、k2、......、kn-1的各位数字顺序表示排列中的数字n、n-1、......、2在排列中距右端的的空位数，因此，要按k1、k2、......、kn-1的值从右向左 //  确定n、n-1、......、2的位置，并逐个放置在排列中：i放在右起的ki+1位，如果某位已放有数字，则该位置不算在内，最后一个空位放1。 //  因此从67342300可得到排列849617523，它就是839647521的后一个排列。因为9最先放置，k1=6，9放在右起第7位，空出6个空位，然后是放8，k2=7，8放在右起第8位， //  但9占用一位，故8应放在右起第9位，余类推。 //3.递减进位制数法 //  在递增进位制数法中，中介数的最低位是逢2进1，进位频繁，这是一个缺点。把递增进位制数翻转,就得到递减进位制数。 //  839647521的中介数是67342221(k1k2...kn-1)，倒转成为12224376(kn-1...k2k1)，这是递减进位制数的中介数：ki(i=n-1,n-2,...,2)位逢i向ki-1位进1。给定排列p， //  p的下一个排列的中介数定义为p的中介数加1。例如p=839647521，p的中介数为12224376，p的下一个排列的中介数为12224376+1=12224377，由此得到p的下一个 //  排列为893647521。 //  给定中介数，可用与递增进位制数法类似的方法还原出排列。但在递减进位制数中，可以不先计算中介数就直接从一个排列求出下一个排列。具体算法如下： //  1）如果p(i)=n且i<>n，则p(i)与p(i-1)交换 //  2）如果p(n)=n，则找出一个连续递减序列9、8、......、i，将其从排列左端删除，再以相反顺序加在排列右端，然后将i-1与左边的数字交换 //  例如p=893647521的下一个排列是983647521。求983647521的下一个排列时，因为9在最左边且第2位为8，第3位不是7，所以将8和9从小到大排于最右端364752189， //  再将7与其左方数字对调得到983647521的下一个排列是367452189。又例如求987635421的下一个排列，只需要将9876从小到大排到最右端并将5与其左方数字3对调， //  得到534216789。 //4.邻位对换法 效率最高但顺序不自然 //  邻位对换法中下一个排列总是上一个排列某相邻两位对换得到的。以4个元素的排列为例，将最后的元素4逐次与前面的元素交换，可以生成4个新排列： //  1 2 3 4, 1 2 4 3, 1 4 2 3, 4 1 2 3 //  然后将最后一个排列的末尾的两个元素交换，再逐次将排头的4与其后的元素交换，又生成四个新排列： //  4 1 3 2, 1 4 3 2, 1 3 4 2, 1 3 2 4 //  再将最后一个排列的开头的两个元素交换，将4从后往前移： //  3 1 2 4, 3 1 4 2, 3 4 1 2, 4 3 1 2 //  如此循环4!次既可求出全部排列。 //5.元素增值法（n进制法）效率低 //  1）从原始排列p=p1p2......pn开始，第n位加n-1，如果该位的值超过n，则将它除以n，用余数取代该位，并进位（将第n-1位加1） //  2）再按同样方法处理n-1位，n-2位，......，直至不再发生进位为止，处理完一个排列就产生了一个新的排列 //  3）将其中有相同元素的排列去掉 //  4）当第一个元素的值>n则结束 //  以3个数1、2、3的排列为例：原始排列是1 2 3，从它开始，第3个元素是3，3+2=5，5 Mod 3=2，第2个元素是2，2+1=3，所以新排列是1 3 2。通过元素增值，顺序产生的 //  排列是：1 2 3，1 3 2，2 1 1，2 1 3，2 2 2，2 3 1，2 3 3，3 1 2，3 2 1 //  有下划线的排列中存在重复元素，丢弃，余下的就是全部排列。 //6.递归类算法 //  全排列的生成方法用递归方式描述比较简洁，实现的方法也有多种。 //  1）回溯法 //  回溯法通常是构造一颗生成树。以3个元素为例；树的节点有个数据，可取值是1、2、3。如果某个为0，则表示尚未取值。 //  初始状态是(0，0，0)，第1个元素值可以分别挑选1，2，3，因此扩展出3个子结点。用相同方法找出这些结点的第2个元素的可能值，如此反复进行，一旦出现新结点的3个 //  数据全非零，那就找到了一种全排列方案。当尝试了所有可能方案，即获得了问题的解答。 //  2）递归算法 //  如果用P表示n个元素的排列，而Pi表示不包含元素i的排列，(i)Pi表示在排列Pi前加上前缀i的排列，那么，n个元素的排列可递归定义为： //  如果n=1，则排列P只有一个元素i //  如果n>1，则排列P由排列(i)Pi构成（i=1、2、....、n-1）。 //  根据定义，容易看出如果已经生成了k-1个元素的排列，那么，k个元素的排列可以在每个k-1个元素的排列Pi前添加元素i而生成。例如2个元素的排列是1 2和2 1，对与个 //  元素而言，p1是2 3和3 2，在每个排列前加上1即生成1 2 3和1 3 2两个新排列，p2和p3则是1 3、3 1和1 2、2 1，按同样方法可生成新排列2 1 3、2 3 1和3 1 2、3 2 1。 //  3）循环移位法 //  如果已经生成了k-1个元素的排列，则在每个排列后添加元素k使之成为k个元素的排列，然后将每个排列循环左移（右移），每移动一次就产生一个新的排列。 //  例如2个元素的排列是1 2和2 1。在1 2 后加上3成为新排列1 2 3，将它循环左移可再生成新排列2 3 1、3 1 2，同样2 1 可生成新排列2 1 3、1 3 2和3 2 1。

引用 4 楼 kakabulusi的回复:先了解一下递归原理， 按你的理解这道题该怎么做？

引用 3 楼 qq_37919314的回复:不好意思 看了半天 没有看明白 按你的理解这道题该怎么做？

先了解一下递归原理，

不好意思 看了半天 没有看明白

有没有人啊  递归这里总是不明白

是  f(a,n,t+1);


Question: 求大神看一下这个CRC校验的实现原理

仅供参考：/***** crc16.c *****/ #include <stdio.h>  #define CRC16_DNP   0x3D65u     // DNP, IEC 870, M-BUS, wM-BUS, ... #define CRC16_CCITT 0x1021u     // X.25, V.41, HDLC FCS, Bluetooth, ...  //Other polynoms not tested #define CRC16_IBM   0x8005u     // ModBus, USB, Bisync, CRC-16, CRC-16-ANSI, ... #define CRC16_T10_DIF   0x8BB7u     // SCSI DIF #define CRC16_DECT  0x0589u     // Cordeless Telephones #define CRC16_ARINC 0xA02Bu     // ACARS Aplications  #define POLYNOM     CRC16_DNP   // Define the used polynom from one of the aboves  // Calculates the new crc16 with the newByte. Variable crcValue is the actual or initial value (0). unsigned short crc16(unsigned short crcValue, unsigned char newByte) {     int i;      for (i = 0; i < 8; i++) {         if (((crcValue & 0x8000u) >> 8) ^ (newByte & 0x80u)){             crcValue = (crcValue << 1)  ^ POLYNOM;         } else {             crcValue = (crcValue << 1);         }         newByte <<= 1;     }     return crcValue; }  unsigned short exampleOfUseCRC16(unsigned char *Data, int len){      unsigned short crc;     int aux = 0;      crc = 0x0000u; //Initialization of crc to 0x0000 for DNP     //crc = 0xFFFFu; //Initialization of crc to 0xFFFF for CCITT      while (aux < len){         crc = crc16(crc,Data[aux]);         aux++;     }      return (~crc); //The crc value for DNP it is obtained by NOT operation      //return crc; //The crc value for CCITT }  int main() {     unsigned char d[10]={0,1,2,3,4,5,6,7,8,9};      printf("0x%04hX\n",exampleOfUseCRC16(d,10));//0x1078     return 0; }

一般CRC16都是用CCITT,你这个很特殊啊。。 你这个表达式已经说得很清楚了啊关于你这种CRC，每个字节向右移动8位再求和：  >>8的意思是向右移动8位，就是说对应字节的二进制向右移动8位，比如： 如果AngleAcceleArry[0] = 256（10进制） 对应二进制：0000 0001 0000 0000 右移8位：0000 0000 0000 0001 所以256>>8  =  1


Question: 数据结构学习问题

//第一种：使用引用 int InitStack(SqStack &S) {     S.base = (ElemType *)malloc(STACK_INIT_SIZE * sizeof(ElemType));     if (!S.base)exit(0);     S.top = S.base;     S.stacksize = STACK_INIT_SIZE;     return 1; } //... SqStack s; InitStack(s);  //第二种：使用指针 int InitStack(SqStack *ps) {     ps->base = (ElemType *)malloc(STACK_INIT_SIZE * sizeof(ElemType));     if (!ps->base)exit(0);     ps->top = ps->base;     ps->stacksize = STACK_INIT_SIZE;     return 1; } //... SqStack s; InitStack(&s);

[quote=引用 4 楼 zhao4zhong1 的回复: int InitStack(SqStack &S) { 	S.base = (ElemType *)malloc(STACK_INIT_SIZE * sizeof(ElemType)); 	if (!S.base)exit(0); 	S.top = S.base; 	S.stacksize = STACK_INIT_SIZE; 	return 1; }这是第一种的栈建立的例程，如果用第二种代码需要改变吗

函数定义时，在C语言中，应该是第二种Status InitList(Sqtaack *S) 引用是C++中特殊的用法；

指针即地址。 引用即别名。

理解和讨论之前请先学会如何观察！  //char (*(*x[3])())[5];//x是什么类型的变量? // //分析C语言声明，关键是搞清楚这个变量是个什么东西（函数、指针、数组）， //是函数那么剩下的就是他的参数和返回值， //是指针那剩下部分是说明他指向什么， //是数组剩下的部分就是说明数组的成员是什么类型。 //解析C语言声明规则： //从左侧第一个标识符开始，按照优先级进行结合。*表示是..的指针，const表示只读的，volatile表示可变的，[]表示是数组，()表示是函数。 // //x和[3]结合说明是一个大小为3的数组，该数组的每个元素为一类指针，该类指针指向一类函数，该类函数无参数，返回一类指针，该类指针指向一个大小为5的char型数组 #include <stdio.h> #include <typeinfo.h> char num[5]; char (*x00())[5] {     return # } int main() {     char (*(*x[3])())[5];//是个数组，大小为3     char (*(*x0  )())[5];//数组的元素，是个函数指针     char (*( x00 )())[5];//函数原型，参数为空，返回值为指针     char (*  x000   )[5];//返回值      x0 = x00;     x[0] = x0;     x[1] = x0;     x[2] = x0;     printf("typeid(x).name() is %s\n",typeid(x).name());     return 0; } //typeid(x).name() is char (* (__cdecl**)(void))[5]

区别不大，一个是引用一个是指针，反正都是关于地址的

(Sqtaack &S) -> &表示参数是引用形式(C++语法，C不支持)，使用时，S是传过来的参数的别名，对S的操作就是对传过来的参数的操作，注意这里不需要*号 (Sqtaack *S) -> &表示参数是指针形式(C++和C都支持)，使用时，S是传过来的参数的地址，对*S的操作就是对传过来的参数的操作，注意这里需要*号


Question: 内核驱动 UNICODE_STRING 字符串截取

可以直接修改 Length 的值，需要注意这个是字节数。

直接对buffer操作就越过了结构的长度字段的更新，除非自己进行修改长度字段 还不如直接取得buffer中所要的字符，重新初始化一个UNICODE_STRING变量，释放原变量

并且由于 unicode_string buffer 有可能并不以NULL结尾，所以单独对buffer进行操作，是不是会有问题


Question: libjson-c中的引用计数和对象所有权

以我的理解，那个put的释放对象，只是将对象的引用计数变为了0，当引用计数变为了0后就会释放掉内存；而你重新用对象的时候，它又会将该对象的引用计数加1了。所以用完后，你还是得看情况，判断它是否得释放掉。

以下是代码，请大神们看看，为什么最后new_field还可以使用？ #include <stdio.h> #include <stdlib.h> #include <json-c/json.h> #include <string.h>    //该函数用于接收一个json格式的字符串，转换成json_object格式 //参数为字符串、字符串长度、要返回的json_object对象 //成功返回0，失败返回-1 //注意josn如果获取成功将在函数内部开辟存储空间，不要忘记在函数外面释放空间  int string_to_json(char *string, unsigned long len, json_object **json) { 	json_tokener *tok = json_tokener_new();//创建一个json_tokener对象，以便进行转换,记得要释放 	enum json_tokener_error jerr; 	do 	{ 		*json = json_tokener_parse_ex(tok, string, len); 	}while((jerr = json_tokener_get_error(tok)) == json_tokener_continue); 	if(jerr != json_tokener_success  || tok->char_offset < (int)len) 	{ 		json_tokener_free(tok); 		return -1; 	} 	if(json_object_get_type(*json) == json_type_object) 	{ 		json_tokener_free(tok); 		return 0; 	} 	json_tokener_free(tok); 	return -1; }  int main() { 	char json[65535] = {0}; 	FILE * json_file; 	json_file = fopen("/home/han/桌面/tempro/json/json.txt","r"); 	if(json_file == NULL) 	{ 		printf("shibai \n"); 		return -1; 	} 	fread(json, 65535, 1, json_file); 	//printf("%s",json); 	json_object *new_json = NULL; 	unsigned long  len = strlen(json); 	json_object *new_field = NULL;  	if(string_to_json(json, len, &new_json) == 0) 	{	 		const char *str = json_object_get_string(new_json); 		printf("转换成功的json为：\n%s\n",str); 		new_field = json_object_new_string("周杰伦"); 		json_object_object_add(new_json, "最爱的歌手", new_field); 		printf("\n\n添加后的json为：\n%s\n",str); 	} 	if(json_object_get_type(new_json) != json_type_null) 	{ 		printf("释放空间\n"); 		json_object_put(new_json); 	} 	const char *after_put = json_object_get_string(new_field); 	printf("竟然还存在：%s\n",after_put); 	return 0; }

引用 6 楼 u013910218 的回复:[quote=引用 5 楼 zhao4zhong1 的回复:] https://www.baidu.com/s?wd=libjson-c中的引用计数和对象所有权  并没有找到想要的[/quote] 大神，能不能解释一下，为什么我用json_object_add将A添加都B上，释放B之后，A依然可以继续使用呢？看文档里写的，json_object_add之后，释放B的同时A也就释放了，但是我发现A依然可以继续使用

略改搜索用关键字，继续搜。

引用 5 楼 zhao4zhong1 的回复:https://www.baidu.com/s?wd=libjson-c中的引用计数和对象所有权  并没有找到想要的

引用 3 楼 zhao4zhong1 的回复:百度搜相关关键字。就是因为百度不出满意的结果，才来scdn求大神的呀

百度搜相关关键字。

自己顶一下，求大神们指点

没有人回答吗？自己顶一下


Question: 急急急！！卡了我一周了，还是得请教大神

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

函数声明或全局变量引用，建议都放在函数外。

到了if 这里我step into 就是进不去，但是看看方法栈，那里，其实是进入了方法的。可是就是定位不到执行的位置。

引用 1 楼 user-3 的回复:可以看汇编定位跳转位置，或者执行到if那句点步入  要看你搜索出的yyparse函数是不是，可以在你找到的yyparse里下断点，看能不能断下  我有在if 开始步入，进不去，同时我也在全局搜索到那个函数里面第一句打了个断点，也是不行啊。


Question: 关于数字格式的转化

这是转换说明符的问题，各种输出格式可以参考这个博客 http://blog.csdn.net/libing403/article/details/72934198

问题已解决，谢谢大家！

引用 11 楼 zhao4zhong1 的回复:[quote=引用 10 楼 qq_38115230 的回复:] [quote=引用 7 楼 zhao4zhong1 的回复:] #include <stdio.h> #include <string.h> char s[2][11]={ "9.36849+0", "5.87654+5", }; double d[2]; int i; char *p; int main() {     for (i=0;i<2;i++) {         p=strchr(s[i],'+');         if (p) {             memmove(p+1,p,strlen(p)+1);             *p='E';         }         sscanf(s[i],"%lf",&d[i]);         printf("%d %s %e\n",i,s[i],d[i]);     }     return 0; } //0 9.36849E+0 9.368490e+000 //1 5.87654E+5 5.876540e+005 // 非常感谢您的回答，对我很有帮助，只是识别的字符不仅有“+”还有“-”[/quote]         p=strchr(s[i],'+');         if (p) {             memmove(p+1,p,strlen(p)+1);             *p='E';         } else {             p=strchr(s[i],'-');             if (p) {                 memmove(p+1,p,strlen(p)+1);                 *p='E';             }         } [/quote]非常感谢您赵老师！再问个其他的问题，怎样批量处理多个数组？比如说，我现在有10个数组，都要插入E，有没有什么方法同时处理？还是只能一个数组一个数组地插入E ？

引用 15 楼 paschen 的回复:引用 13 楼 qq_38115230的回复:[quote=引用 12 楼 paschen 的回复:] [quote=引用 8 楼 qq_38115230 的回复:] ~[quote=引用 6 楼 paschen 的回复:] [quote=引用 3 楼 qq_38115230 的回复:] [quote=引用 1 楼 paschen 的回复:] printf("%e", 9.36849);这种方法不行的啊，不是输出的时候转化，因为有很多数啊，而且我是直接从文件里读的根本不知道这个数是多少  这里我不是很懂你要表达什么意思  如果你不是在输出的时候转换，可以用字符串版本的，仍然是用%e，它是按科学技术法输出  其次，你说有很多数，很多数就循环操作就行，没有可以一次帮你全部转换掉的函数，除非你自己写一个[/quote]谢谢你的解答~我再详细说一下，从文件里读一些数据，我把文件的内容截图发到楼下，里面的数不是科学记数法的形式，少了中间的E，c语言无法识别这样的数据，只能当成字符串，但是我想把他转化成可以处理的数据格式如整形浮点型，因为要对这些数据做一些运算处理，所以我的思路是将这些数字中间加上E，可是我不太会这个。[/quote]  维修建议，记事本有个功能叫替换，将+换成 E+，将-换成 E-[/quote]额……要在程序里替换……[/quote] 程序中替换也一样，整体读入，然后按我上面说的替换，不需要先转换成数值  字符串替换的函数网上大把[/quote]有道理！这部分代码我是这样写的（读取的数据还是和截图一样），运行不出来，可不可以帮我看一下哪里的错误？因为我读取的时候是一下子读一行数据到一个二维数组data[][]中，所以我引用字符串是通过引用data[i]，我感觉这里出了问题  for(i=0;i<300;i++)     {     fgets(data[i],512,ip);     *m=data[i];       m=strstr(data[i],'+');         if (m) {         memmove(m+1,m,strlen(m)+1);         *m="E+";             } else  {             m=strchr(data[i],'-');             if (m) {                 memmove(m+1,m,strlen(m)-1);                 *m="E-";             }         }         }

只能一个数组一个数组地插入E

引用 13 楼 qq_38115230的回复:引用 12 楼 paschen 的回复:[quote=引用 8 楼 qq_38115230 的回复:] ~[quote=引用 6 楼 paschen 的回复:] [quote=引用 3 楼 qq_38115230 的回复:] [quote=引用 1 楼 paschen 的回复:] printf("%e", 9.36849);这种方法不行的啊，不是输出的时候转化，因为有很多数啊，而且我是直接从文件里读的根本不知道这个数是多少  这里我不是很懂你要表达什么意思  如果你不是在输出的时候转换，可以用字符串版本的，仍然是用%e，它是按科学技术法输出  其次，你说有很多数，很多数就循环操作就行，没有可以一次帮你全部转换掉的函数，除非你自己写一个[/quote]谢谢你的解答~我再详细说一下，从文件里读一些数据，我把文件的内容截图发到楼下，里面的数不是科学记数法的形式，少了中间的E，c语言无法识别这样的数据，只能当成字符串，但是我想把他转化成可以处理的数据格式如整形浮点型，因为要对这些数据做一些运算处理，所以我的思路是将这些数字中间加上E，可是我不太会这个。[/quote]  维修建议，记事本有个功能叫替换，将+换成 E+，将-换成 E-[/quote]额……要在程序里替换……[/quote] 程序中替换也一样，整体读入，然后按我上面说的替换，不需要先转换成数值  字符串替换的函数网上大把

引用 12 楼 paschen 的回复:引用 8 楼 qq_38115230 的回复:~[quote=引用 6 楼 paschen 的回复:] [quote=引用 3 楼 qq_38115230 的回复:] [quote=引用 1 楼 paschen 的回复:] printf("%e", 9.36849);这种方法不行的啊，不是输出的时候转化，因为有很多数啊，而且我是直接从文件里读的根本不知道这个数是多少  这里我不是很懂你要表达什么意思  如果你不是在输出的时候转换，可以用字符串版本的，仍然是用%e，它是按科学技术法输出  其次，你说有很多数，很多数就循环操作就行，没有可以一次帮你全部转换掉的函数，除非你自己写一个[/quote]谢谢你的解答~我再详细说一下，从文件里读一些数据，我把文件的内容截图发到楼下，里面的数不是科学记数法的形式，少了中间的E，c语言无法识别这样的数据，只能当成字符串，但是我想把他转化成可以处理的数据格式如整形浮点型，因为要对这些数据做一些运算处理，所以我的思路是将这些数字中间加上E，可是我不太会这个。[/quote]  维修建议，记事本有个功能叫替换，将+换成 E+，将-换成 E-[/quote]额……要在程序里替换……

引用 8 楼 qq_38115230 的回复:~引用 6 楼 paschen 的回复:[quote=引用 3 楼 qq_38115230 的回复:] [quote=引用 1 楼 paschen 的回复:] printf("%e", 9.36849);这种方法不行的啊，不是输出的时候转化，因为有很多数啊，而且我是直接从文件里读的根本不知道这个数是多少  这里我不是很懂你要表达什么意思  如果你不是在输出的时候转换，可以用字符串版本的，仍然是用%e，它是按科学技术法输出  其次，你说有很多数，很多数就循环操作就行，没有可以一次帮你全部转换掉的函数，除非你自己写一个[/quote]谢谢你的解答~我再详细说一下，从文件里读一些数据，我把文件的内容截图发到楼下，里面的数不是科学记数法的形式，少了中间的E，c语言无法识别这样的数据，只能当成字符串，但是我想把他转化成可以处理的数据格式如整形浮点型，因为要对这些数据做一些运算处理，所以我的思路是将这些数字中间加上E，可是我不太会这个。[/quote]  维修建议，记事本有个功能叫替换，将+换成 E+，将-换成 E-

引用 10 楼 qq_38115230 的回复:[quote=引用 7 楼 zhao4zhong1 的回复:] #include <stdio.h> #include <string.h> char s[2][11]={ "9.36849+0", "5.87654+5", }; double d[2]; int i; char *p; int main() {     for (i=0;i<2;i++) {         p=strchr(s[i],'+');         if (p) {             memmove(p+1,p,strlen(p)+1);             *p='E';         }         sscanf(s[i],"%lf",&d[i]);         printf("%d %s %e\n",i,s[i],d[i]);     }     return 0; } //0 9.36849E+0 9.368490e+000 //1 5.87654E+5 5.876540e+005 // 非常感谢您的回答，对我很有帮助，只是识别的字符不仅有“+”还有“-”[/quote]         p=strchr(s[i],'+');         if (p) {             memmove(p+1,p,strlen(p)+1);             *p='E';         } else {             p=strchr(s[i],'-');             if (p) {                 memmove(p+1,p,strlen(p)+1);                 *p='E';             }         }

引用 7 楼 zhao4zhong1 的回复:#include <stdio.h> #include <string.h> char s[2][11]={ "9.36849+0", "5.87654+5", }; double d[2]; int i; char *p; int main() {     for (i=0;i<2;i++) {         p=strchr(s[i],'+');         if (p) {             memmove(p+1,p,strlen(p)+1);             *p='E';         }         sscanf(s[i],"%lf",&d[i]);         printf("%d %s %e\n",i,s[i],d[i]);     }     return 0; } //0 9.36849E+0 9.368490e+000 //1 5.87654E+5 5.876540e+005 // 非常感谢您的回答，对我很有帮助，只是识别的字符不仅有“+”还有“-”

~引用 6 楼 paschen 的回复:引用 3 楼 qq_38115230 的回复:[quote=引用 1 楼 paschen 的回复:] printf("%e", 9.36849);这种方法不行的啊，不是输出的时候转化，因为有很多数啊，而且我是直接从文件里读的根本不知道这个数是多少  这里我不是很懂你要表达什么意思  如果你不是在输出的时候转换，可以用字符串版本的，仍然是用%e，它是按科学技术法输出  其次，你说有很多数，很多数就循环操作就行，没有可以一次帮你全部转换掉的函数，除非你自己写一个[/quote]谢谢你的解答~我再详细说一下，从文件里读一些数据，我把文件的内容截图发到楼下，里面的数不是科学记数法的形式，少了中间的E，c语言无法识别这样的数据，只能当成字符串，但是我想把他转化成可以处理的数据格式如整形浮点型，因为要对这些数据做一些运算处理，所以我的思路是将这些数字中间加上E，可是我不太会这个。【还有您刚才提到的字符串版本输出科学记数法的格式应该不行吧？】

引用 3 楼 qq_38115230 的回复:引用 1 楼 paschen 的回复:printf("%e", 9.36849);这种方法不行的啊，不是输出的时候转化，因为有很多数啊，而且我是直接从文件里读的根本不知道这个数是多少  这里我不是很懂你要表达什么意思  如果你不是在输出的时候转换，可以用字符串版本的，仍然是用%e，它是按科学技术法输出  其次，你说有很多数，很多数就循环操作就行，没有可以一次帮你全部转换掉的函数，除非你自己写一个

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

引用 3 楼 qq_38115230 的回复:引用 1 楼 paschen 的回复:printf("%e", 9.36849);这种方法不行的啊，不是输出的时候转化，因为有很多数啊，而且我是直接从文件里读的根本不知道这个数是多少 要看读到是什么数据？另外，想转换成科学计数法，以字符串的形式输出可以用snprintf或sprintf

double     m; int            e; double    res;  scanf("%lf+%d", &m, &e); res = m * pow(10, e); printf("%e\n", res);

printf("%e", 9.36849);


Question: 请教大家我使用fgets遇到段错误

引用 5 楼 zhao4zhong1 的回复:其实电脑开机后物理内存的每个字节都是可读写的，从来不会因为所谓的new、delete或malloc、free而被创建、销毁。区别仅在于操作系统内存管理模块在你读写时是否能发现并是否采取相应动作而已。操作系统管理内存的粒度不是字节而是页，一页通常为4KB。 感谢你多次回答我的问题。谢谢你。

野指针很容易导致段错误；char *arg;这是一个野指针，野指针就是该指针指向的位置不确定（随机的），若指向不可写或不可读的区域都会导致段错误；因为fgets是将标准输入的内容，放到内存里的某个区域，这个区域是指针arg指向的区域，若arg指向的区域不可写，那么就会出段错误了。 char arg[5]；是栈上的数组，fgets输入就会将输入的内容放到栈上的数组里。

这是我的运行结果。谢谢～

引用 1 楼 user-3 的回复:char *arg; 这只是一个指针，你都没有初始化，都没分配空间怎么用？ 你要char *arg = new char[5];才行。  另外fgets不会把换行符换成NULL，不过并不会像你说的输出abcd%吧。。我试了并不是这样啊 谢谢。我刚才试着加了个 arg  = malloc(5),段错误没有了。 我的第二个问题 意思是既然fgets里面我给的参数是5，那么假如我输入abcd，然后回车enter，那么fgets读进去的是abcd加'\0'吧。我在linux环境运行的结果有个%在最后。


Question: 使用OPENSLL加解密码问题

MODULUS PUBLIC_EXPONENT PRIVATE_EXPONENT的值是多少啊？满足不满足RSA所要求的基本关系啊？

仅供参考：void HexDump(char *buf,int len,int addr) {     int i,j,k;     char binstr[80];      for (i=0;i<len;i++) {         if (0==(i%16)) {             sprintf(binstr,"%08x -",i+addr);             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]:'.');             }             printf("%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]:'.');         }         printf("%s\n",binstr);     } }

被加密的对象不是字符串，是字节数组。


Question: 为什么会提示未定义的引用？

Visual C++ 2010 Express简体中文版http://pan.baidu.com/s/1bnwRVLt

大兄弟，这个问题解决了嘛？

引用 12 楼 tjroamer 的回复:[quote=引用 8 楼 coverlo 的回复:] [quote=引用 6 楼 user-6 的回复:] strnlen_s 是M$对strnlen函数的安全加强版，VS版本中可以使用 你的IDE是Dev C++版本貌似不提供strnlen_s 你直接使用strnlen算了，记得比strnlen_s少个参数 正在下载vs2012，看能不能通过编译[/quote]  MS定义了strnlen_s，应该没有问题的。如果用gcc来编译，肯定会出现你的问题，因为gcc的库函数里面没有定义strnlen_s[/quote] 确实没有man到strnlen_s  man string 里面也没有strnlens

引用 8 楼 coverlo 的回复:[quote=引用 6 楼 user-6 的回复:] strnlen_s 是M$对strnlen函数的安全加强版，VS版本中可以使用 你的IDE是Dev C++版本貌似不提供strnlen_s 你直接使用strnlen算了，记得比strnlen_s少个参数 正在下载vs2012，看能不能通过编译[/quote]  MS定义了strnlen_s，应该没有问题的。如果用gcc来编译，肯定会出现你的问题，因为gcc的库函数里面没有定义strnlen_s

引用 9 楼 coverlo 的回复:[quote=引用 7 楼 xsklld 的回复:] [quote=引用 4 楼 coverlo 的回复:] [quote=引用 2 楼 xsklld 的回复:] strnlen_s之类的函数即使在C11也是可选实现的，你可以通过检查__STDC_LIB_EXT1__是否定义来判断编译器有没有实现这类函数。 检查了可以实现的， 但是编译就是通不过啊[/quote]  据我所知glibc是没有实现这类函数的，除非你用的不是glibc库，但Dev-C++默认使用的MinGW应该是用的glibc库。 你怎么检查的？应该这么检查（参考strcpy）： #ifdef __STDC_LIB_EXT1__     // output something #endif 注意我说的是__STDC_LIB_EXT1__，不是你定义的__STDC_WANT_LIB_EXT1__。前者由库决定是否定义，后者是在库定义了前者的前提下由用户定义以便使用strnlen_s之类的函数。[/quote] #include<stdio.h>  int main(void) { 	#if defined _STDC_LIB_EXT1_ 		printf("Optional functions are defined.\n"); 	#else 		printf("Optional functions are not defined.\n"); 	#endif 		return 0; } 代码如上，在centos下是可以支持。 会输出Optional functions are defined[/quote]  那就不知道了，你gcc用的是什么版本？我用最新版的gcc运行输出的是not defined，编译选项只是多了警告选项，应该不会有影响： 运行结果

引用 7 楼 xsklld 的回复:[quote=引用 4 楼 coverlo 的回复:] [quote=引用 2 楼 xsklld 的回复:] strnlen_s之类的函数即使在C11也是可选实现的，你可以通过检查__STDC_LIB_EXT1__是否定义来判断编译器有没有实现这类函数。 检查了可以实现的， 但是编译就是通不过啊[/quote]  据我所知glibc是没有实现这类函数的，除非你用的不是glibc库，但Dev-C++默认使用的MinGW应该是用的glibc库。 你怎么检查的？应该这么检查（参考strcpy）： #ifdef __STDC_LIB_EXT1__     // output something #endif 注意我说的是__STDC_LIB_EXT1__，不是你定义的__STDC_WANT_LIB_EXT1__。前者由库决定是否定义，后者是在库定义了前者的前提下由用户定义以便使用strnlen_s之类的函数。[/quote] Dev c++是不支持可选函数，我只是截的dev c++的图，因为他们的错误提示都是一样的

引用 7 楼 xsklld 的回复:[quote=引用 4 楼 coverlo 的回复:] [quote=引用 2 楼 xsklld 的回复:] strnlen_s之类的函数即使在C11也是可选实现的，你可以通过检查__STDC_LIB_EXT1__是否定义来判断编译器有没有实现这类函数。 检查了可以实现的， 但是编译就是通不过啊[/quote]  据我所知glibc是没有实现这类函数的，除非你用的不是glibc库，但Dev-C++默认使用的MinGW应该是用的glibc库。 你怎么检查的？应该这么检查（参考strcpy）： #ifdef __STDC_LIB_EXT1__     // output something #endif 注意我说的是__STDC_LIB_EXT1__，不是你定义的__STDC_WANT_LIB_EXT1__。前者由库决定是否定义，后者是在库定义了前者的前提下由用户定义以便使用strnlen_s之类的函数。[/quote] #include<stdio.h>  int main(void) { 	#if defined _STDC_LIB_EXT1_ 		printf("Optional functions are defined.\n"); 	#else 		printf("Optional functions are not defined.\n"); 	#endif 		return 0; } 代码如上，在centos下是可以支持。 会输出Optional functions are defined

引用 6 楼 user-6 的回复:strnlen_s 是M$对strnlen函数的安全加强版，VS版本中可以使用 你的IDE是Dev C++版本貌似不提供strnlen_s 你直接使用strnlen算了，记得比strnlen_s少个参数 正在下载vs2012，看能不能通过编译

引用 4 楼 coverlo 的回复:[quote=引用 2 楼 xsklld 的回复:] strnlen_s之类的函数即使在C11也是可选实现的，你可以通过检查__STDC_LIB_EXT1__是否定义来判断编译器有没有实现这类函数。 检查了可以实现的， 但是编译就是通不过啊[/quote]  据我所知glibc是没有实现这类函数的，除非你用的不是glibc库，但Dev-C++默认使用的MinGW应该是用的glibc库。 你怎么检查的？应该这么检查（参考strcpy）： #ifdef __STDC_LIB_EXT1__     // output something #endif 注意我说的是__STDC_LIB_EXT1__，不是你定义的__STDC_WANT_LIB_EXT1__。前者由库决定是否定义，后者是在库定义了前者的前提下由用户定义以便使用strnlen_s之类的函数。

附上清晰的程序和错误信息

引用 2 楼 xsklld 的回复:strnlen_s之类的函数即使在C11也是可选实现的，你可以通过检查__STDC_LIB_EXT1__是否定义来判断编译器有没有实现这类函数。 检查了可以实现的， 但是编译就是通不过啊

引用 1 楼 nothingbutpassion 的回复:链接时出的问题，有几点可疑: 1) 程序开始的#define 2) 编译过程中的warning 3) 用的gcc版本支持c11标准么? 4) 链接的c库中是否有strnlen_s之类的符号? 1)开头的是#define _STDC_WANT_LIB_EXT1_    1 2)warnning 说的很清楚啊 3)支持c11的啊 4)我用 man strnlen_s 没有查到，提示没有strnlen_s entry  我也不知道怎么出错了，我在其他地方查了一下，说可选函数要在vs2012,2015这些ide才可以实现 哎，一头雾水啊


Question: C语言链表的问题

仅供参考：//带表头结点的单向链表 #include <stdio.h> #include <stdlib.h> #include <malloc.h> #include <time.h> struct NODE {     int          data;     struct NODE *next; } H,*head,*p,*q,*q1,*s1,*s2,*s3,*s4,*s; int i,j,k,n,t,m; int main() {     srand(time(NULL));      //填写头节点数据     H.data=-1;     H.next=NULL;     head=&H;      //创建10个节点的单链表     p=head;     for (i=0;i<10;i++) {         q=(struct NODE *)malloc(sizeof(struct NODE));         if (NULL==q) return 1;         q->data=rand()%100;//填写0..99的随机值         q->next=NULL;         p->next=q;         p=q;     }      //输出整个单链表     s=head->next;     while (1) {         if (NULL==s) {             printf("\n");             break;         }         printf("%02d->",s->data);         s=s->next;     }      //将值为5的结点插入到单链表的第k个结点前     k=3;     n=0;     p=head;     while (1) {         if (NULL==p) {             break;         }         n++;         if (k==n) {             q=(struct NODE *)malloc(sizeof(struct NODE));             if (NULL==q) return 1;             q->data=5;             q->next=p->next;             p->next=q;             break;         }         p=p->next;     }      //输出整个单链表     s=head->next;     while (1) {         if (NULL==s) {             printf("\n");             break;         }         printf("%02d->",s->data);         s=s->next;     }      //删除第k个节点     k=5;     n=0;     p=head;     while (1) {         if (NULL==p) {             break;         }         n++;         if (k==n) {             q=p->next;             if (q) {                 p->next=q->next;                 free(q);             }             break;         }         p=p->next;     }      //输出整个单链表     s=head->next;     while (1) {         if (NULL==s) {             printf("\n");             break;         }         printf("%02d->",s->data);         s=s->next;     }      //从小到大排序     for (p=head;p!=NULL && p->next!=NULL;p=p->next) {         for (q=p->next;q!=NULL && q->next!=NULL;q=q->next) {             if (p->next->data > q->next->data) {                  //交换data //              printf("swap %02d %02d\n",p->next->data,q->next->data); //              t=p->next->data;p->next->data=q->next->data;q->next->data=t;                  //或者                  //交换next //              printf("swap %02d %02d\n",p->next->data,q->next->data);                 s1=p->next;                 s2=p->next->next;                 s3=q->next;                 s4=q->next->next;                  if (s2!=s3) {                      p->next=s3;                     s3->next=s2;                      q->next=s1;                     s1->next=s4;                 } else {                      p->next=s3;                     s3->next=s1;                            q=s3;                     s1->next=s4;                 }                  //输出整个单链表 //              s=head->next; //              while (1) { //                  if (NULL==s) { //                      printf("\n"); //                      break; //                  } //                  printf("%02d->",s->data); //                  s=s->next; //              } //              getchar();             }         }     }      //输出整个单链表     s=head->next;     while (1) {         if (NULL==s) {             printf("\n");             break;         }         printf("%02d->",s->data);         s=s->next;     }      //将整个链表逆序     if (head->next!=NULL && head->next->next!=NULL) {         p=head->next;         q=p->next;         p->next=NULL;         while (1) {             q1=q->next;             q->next=p;             p=q;             q=q1;             if (NULL==q) break;         }         head->next=p;     }      //输出整个单链表     s=head->next;     while (1) {         if (NULL==s) {             printf("\n");             break;         }         printf("%02d->",s->data);         s=s->next;     }      //将单链表中前 m 个结点和后 n 个结点进行互换,m+n为链表总长10     m=4;     n=6;     k=0;     p=head;     while (1) {         if (NULL==p) {             break;         }         k++;         if (m+1==k) {             q=p;         }         s=p;         p=p->next;     }     s1=head->next;     head->next=q->next;     s->next=s1;     q->next=NULL;      //输出整个单链表     s=head->next;     while (1) {         if (NULL==s) {             printf("\n");             break;         }         printf("%02d->",s->data);         s=s->next;     }      //释放所有节点     p=head->next;     while (1) {         if (NULL==p) {             break;         }         q=p->next;         free(p);         p=q;     }      return 0; } //84->28->20->23->96->19->59->97->29->41-> //84->28->05->20->23->96->19->59->97->29->41-> //84->28->05->20->96->19->59->97->29->41-> //05->19->20->28->29->41->59->84->96->97-> //97->96->84->59->41->29->28->20->19->05-> //41->29->28->20->19->05->97->96->84->59-> //

引用 3 楼 qq_25956141 的回复:首先谢过二位，2楼更改之后的代码，好像还是我的第一个问题，也就是在删除第一个节点的时候，虽然删除了，他还是会打印 找不到该节点这句话，，， 我又重新看了一下代码，删除了第一个几点后，main后面紧接着对index为0的节点进行changeInf(head,0,inf);修改，上一步已经将其删除了，下面在对其修改怎么可能找到呢？

仅供参考：//不带表头结点的单向链表 #include <stdio.h> #include <stdlib.h> #include <malloc.h> #include <time.h> #include <locale.h> struct NODE {     int          data;     struct NODE *next; } *head,*p,*q,*s,*p1,*p2,*q1,**ta; int i,k,n,t,m,v,N=10; int main() {     setlocale(LC_ALL,"chs");     srand(time(NULL));      head=NULL;      printf("创建%d个节点的单链表:",N);//创建N个节点的单链表     p=head;     for (i=0;i<N;i++) {         q=(struct NODE *)malloc(sizeof(struct NODE));         if (NULL==q) exit(1);         q->data=rand()%100;//填写0..99的随机值         q->next=NULL;         if (NULL==p) {             head=q;             p=head;         } else {             p->next=q;             p=q;         }     }      //输出整个单链表     s=head;     while (1) {         if (NULL==s) {             printf("\n");             break;         }         printf("%02d->",s->data);         s=s->next;     }      k=3;     v=5;     printf("将值为%d的结点插入到单链表的第%d个结点前:",v,k);//将值为v的结点插入到单链表的第k个结点前     n=0;     p=head;     while (1) {         if (NULL==p) {             break;         }         n++;         if (k==1) {             q=(struct NODE *)malloc(sizeof(struct NODE));             if (NULL==q) exit(1);             q->data=v;             q->next=head;             head=q;             break;         } else {             if (k-1==n) {                 q=(struct NODE *)malloc(sizeof(struct NODE));                 if (NULL==q) exit(1);                 q->data=v;                 q->next=p->next;                 p->next=q;                 break;             }         }         p=p->next;     }      //输出整个单链表     s=head;     while (1) {         if (NULL==s) {             printf("\n");             break;         }         printf("%02d->",s->data);         s=s->next;     }      k=5;     printf("删除第%d个节点:",k);//删除第k个节点     n=0;     p=head;     while (1) {         if (NULL==p) {             break;         }         n++;         if (k==1) {             q=head;             head=head->next;             free(q);             break;         } else {             if (k-1==n) {                 q=p->next;                 if (q) {                     p->next=q->next;                     free(q);                 }                 break;             }         }         p=p->next;     }      //输出整个单链表     s=head;     while (1) {         if (NULL==s) {             printf("\n");             break;         }         printf("%02d->",s->data);         s=s->next;     }      printf("从小到大排序:");//从小到大排序     for (p=head,p1=NULL;p!=NULL;p1=p,p=p->next) {         for (q=p->next,q1=p;q!=NULL;q1=q,q=q->next) {             if (p->data > q->data) {                  //交换data //              printf("swap %02d %02d\n",p->data,q->data); //              t=p->data;p->data=q->data;q->data=t;                  //或者                  //交换next //              printf("swap %02d %02d\n",p->data,q->data);                 if (p==head) {//p是头                     if (p->next==q) {//pq挨着                         head=q;                         p->next=q->next;                         q->next=p;                         q=p;                         p=head;                     } else {//pq不挨着                         head=q;                         p2=p->next;                         p->next=q->next;                         q->next=p2;                         q1->next=p;                         q=p;                         p=head;                     }                 } else {//p不是头                     if (p->next==q) {//pq挨着                         p1->next=q;                         p->next=q->next;                         q->next=p;                         q=p;                         p=p1->next;                     } else {//pq不挨着                         p1->next=q;                         p2=p->next;                         p->next=q->next;                         q->next=p2;                         q1->next=p;                         q=p;                         p=p1->next;                     }                 }                  //输出整个单链表 //              s=head; //              while (1) { //                  if (NULL==s) { //                      printf("\n"); //                      break; //                  } //                  printf("%02d->",s->data); //                  s=s->next; //              } //              getchar();             }         }     }      //输出整个单链表并计算链表长度n     n=0;     s=head;     while (1) {         if (NULL==s) {             printf("\n");             break;         }         printf("%02d->",s->data);         n++;         s=s->next;     }      printf("将整个链表逆序:");//将整个链表逆序     if (n>=2) {         p=head;         q=p->next;         p->next=NULL;         while (1) {             q1=q->next;             q->next=p;             p=q;             q=q1;             if (NULL==q) break;         }         head=p;     }      //输出整个单链表     s=head;     while (1) {         if (NULL==s) {             printf("\n");             break;         }         printf("%02d->",s->data);         s=s->next;     }      m=4;     n=6;     printf("将单链表中前%d个结点和后%d个结点进行互换:",m,n);//将单链表中前m个结点和后n个结点进行互换,m+n为链表总长     k=0;     p=head;     while (1) {         if (NULL==p) {             break;         }         k++;         if (m==k) {             q=p;         }         s=p;         p=p->next;     }     q1=head;     head=q->next;     s->next=q1;     q->next=NULL;      //输出整个单链表     s=head;     while (1) {         if (NULL==s) {             printf("\n");             break;         }         printf("%02d->",s->data);         s=s->next;     }      //释放所有节点     p=head;     while (1) {         if (NULL==p) {             break;         }         q=p->next;         free(p);         p=q;     }      return 0; } //创建10个节点的单链表:08->74->07->23->03->99->31->56->88->16-> //将值为5的结点插入到单链表的第3个结点前:08->74->05->07->23->03->99->31->56->88->16-> //删除第5个节点:08->74->05->07->03->99->31->56->88->16-> //从小到大排序:03->05->07->08->16->31->56->74->88->99-> //将整个链表逆序:99->88->74->56->31->16->08->07->05->03-> //将单链表中前4个结点和后6个结点进行互换:31->16->08->07->05->03->99->88->74->56-> //

/*get函数中这句是冗余的代码，没必要写，如果p == NULL了，那么循环也结束了*/ if(p == NULL){                                                                                1     |   |   printf("没有找到该节点");   2     |   |   break;   3     |   }  以下是我修改后的代码，主要是加了一个debug，你看一下，有问题继续沟通～ #include <stdio.h> #include <stdlib.h> #include <string.h> /**  * 单链表  * 编写一个单链表，并且拥有增删改查功能  *  */  #define SIZE 20 #define DEBUG  struct CHAIN{     int index; //当前表id,链表索引，逻辑递增     char *inf; //记录信息     struct CHAIN *next; //始终指向下一个元素 } ;   struct CHAIN * create(); int printfChain(struct CHAIN * head); struct CHAIN * deleteNote(struct CHAIN * head); int selectChainLen(struct CHAIN * head); int changeInf(struct CHAIN * head,int index,char *inf); int clear(struct CHAIN * head);  //函数入口 int main() {     struct CHAIN *head = NULL;      head = create();     printf("After create: \n");     printfChain(head);       //遍历前先删除一个节点     printf("\n");     head = deleteNote(head);     printfChain(head);      //改变某个节点的信息     char inf[SIZE] = "hehehehe";     changeInf(head,0,inf);    /*若已删除，这个函数就不能修改index为0的*/      //遍历之前先打印一下链表的长度     printf("\n");     printf("当前链表长度为%d\n",selectChainLen(head));      //遍历     printf("\n\n");     printfChain(head);      //释放内存     clear(head);     return 0; }   /**  * 创建链表的函数  */ struct CHAIN * create() {     //head为头元素，tail为后继元素，p为临时构造元素     struct CHAIN * head , *tail , *p;     char x, flag = 1;     int index = 0;     //char inf[20];     head = tail = NULL;     //使用while输入数字来控制是否继续创建表     while(1){         printf("请输入命令(y,n)------>Y继续创建，N为退出创建为\n");         if (!flag) {             getchar();         }         scanf("%c",&x);         flag = 0;         if(x != 'y'){             break;         }         p = (struct CHAIN *)malloc(sizeof(struct CHAIN));         p->index = index;         printf("请输入你要存入的数据，不能超过%d个字符\n",SIZE);         p->inf = (char *)malloc(sizeof(char)*SIZE);         scanf("%s",p->inf);         //gets(p->inf); //输入字符信息         if(head == NULL){             head = tail = p;//只有一个元素，那么头和尾都是自己             head->next = NULL;         } else {             tail->next = p;             tail = tail->next; //tail.next就是当前的p             //由于五环链表，所以节点的后驱应该为NULL             tail ->next = NULL;         }         index++;     }      return head; }   /**  * 遍历链表的函数  */  int printfChain(struct CHAIN * head) {     if(head == NULL){         printf("head is empty\n");         return 0;     }     printf("---------现在开始遍历链表数据---------\n");     struct CHAIN * p = NULL;     while (head) {         printf("索引%d\n",head -> index);         printf("存入的数据%s\n",head -> inf);         //把他的下一个元素的地址给p         p = head->next;         head = p;     }     return 0; }  /**  * 删除链表的函数，循环遍历，查找索引，根据索引删除元素  * @Return 返回指向第一个表元的指针  * 由于该链表为无环链表，所以指向为空就直接退出循环  */ struct CHAIN * deleteNote(struct CHAIN * head) {     if(head == NULL){         printf("head is empty\n");         return NULL;     }     int index;      printf("请输入要删除的节点的索引\n");     scanf("%d",&index);  #ifdef DEBUG     struct CHAIN *pcur, *prev;     pcur = head;     if (head->index == index) {         head = head->next;         free(pcur->inf);         free(pcur);         return head;     }     pcur = head->next;     prev = head;     while (pcur) {         if (pcur->index == index) {             prev->next = pcur->next;             free(pcur->inf);             free(pcur);             return head;         }         pcur = pcur->next;         prev = prev->next;     }      printf("没有找到要删除的节点\n");      return head; #else     //p为head的下一个元素，q为下下个元素,s用来记录head     struct CHAIN *p = NULL, *q = NULL, *s = head;      while(s){         p = s -> next;         if(index == 0){             free(s->inf);             free(s);             head = p;             break;         }         //如果s的后继不存在，那么就跳出循环         if(p == NULL){             printf("没有找到要删除的节点\n");             break;         }         q = p -> next;         if(p->index == index){             s ->next = q;             free(p->inf);             free(p);             break;         }         //如果没有找到节点，那么让s指向p         s = p;     }     return head; #endif }  /**  * @Return 返回链表逻辑长度  *  */ int selectChainLen(struct CHAIN * head) {     if(head == NULL){         printf("head is empty\n");         return 0;     }     struct CHAIN *p = head;     int len = 0;      while(p){         len ++;         if(p->next == NULL){             break;         }         p = p->next;     }     return len; }  /**  * 根据索引，改变链表中的信息  *  */ int changeInf(struct CHAIN * head,int index,char *inf) {     if(head == NULL){         printf("head is empty\n");         return 0;     }     struct CHAIN * p = head;     while(p){         if(p->index == index){             //释放掉原来节点占用的内存空间             free(p->inf);             p->inf = inf;             break;         }         p = p->next;     }     if(!p)         printf("没有找到节点\n");     return 0; }  /**  * 清空链表中的元素  */ int clear(struct CHAIN * head) {     if(head == NULL){         printf("head is empty\n");         return 0;     }     struct CHAIN * p = head,*q = NULL;     printf("\n------------开始释放数据-------------\n");     while(p){          q = p->next;         //释放p之前需要释放inf         free(p->inf);         free(p);         p = q;     }     printf("\n------------释放数据成功-------------\n");     return 0; }  /**  * 根据索引，返回节点  * @Return 节点  */ struct CHAIN * get(struct CHAIN * head,int index) {     if(head == NULL){         printf("head is empty\n");         return NULL;     }     struct CHAIN * p = head;     while(p){         if(p->index == index){             break;         }         p = p->next;         if(p == NULL){             printf("没有找到该节点");             break;         }     }     return p; }


Question: C语言，想用顺序栈做教师信息系统，遇到点问题（谢谢）

#include<stdio.h> #include<stdlib.h>  struct Tea//声明结构体数组 {     int number;     char name[10];  };  typedef struct//声明并定义结构体 {     struct Tea tea[5]; //定义结构体数组     int top;  }teacher;   teacher* init(teacher **s)//初始化 {     *s = (teacher*)malloc(sizeof(teacher));     (*s)->top = -1;     return *s; }  teacher* push (teacher *s, int x, char *y)//结构体指针 {     int i = 0;     s->top++;     s->tea[s->top].number=x;     while(y[i]!='\0') {         s->tea[s->top].name[i]= y[i];         i++;     }     s->tea[s->top].name[i]='\0';     //printf("%s",s->tea[s->top].name[1]);     //while(1);     return s; }   int main(void) {     int ch, X;     int j=0;     char Y[10];     teacher* h = NULL;//定义基本结构体指针     init(&h);//初始化结构体     char* p;//定义指向Y[10]的指针     p = Y;      printf("一:输入教师信息");     scanf("%d", &ch);      switch(ch) {         case 1:             printf("输入学号");             scanf("%d",&X);             printf("输入教师姓名");             getchar(); /* '\n' */             while((Y[j] = getchar()) != '\n' && j < 10-1)                 j++;             Y[j] = '\0';             h = push(h,X,p);             break;      }      return 0; } 崩溃的原因是main中变量h是野指针，init函数并没有将申请的空间返回至main函数里，所以需要传二重指针来实现获取申请的空间。 注意下其他问题，不一一表述了。 注意代码风格。


Question: 跪求大神，帮忙修改下c语言链表，将本地数据读入链表中的 函数read()，跪求大神！

有几个问题： 1，看你的程序里是先去读文件，为什么要读两次呢？还有该文件是你手动创建的？ 2. read函数没有将创建的链表返回到main函数； 3. 文件是否已存在，因为open文件是一个rb方式读取的。所以，需要文件已存在，那么该文件是否是手动创建的。

仅供参考：//将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>

跪求大神帮忙修改下，read()函数！~小弟感激不尽！~


Question: 求教nrf24l01 如何把所发送的数据数组大小也发过去

我感觉行不通了，2401在接收的时候是用这个函数SPI1_ReadWriteByte(reg);    读取RD_RX_PLOAD 这个寄存器中的数据，读取的数据大小必须先事先规定好，就是说 接收的时候2401只能就收结构体中的数组数据而无法接收数组大小


Question: 【求助】关于缓冲区清除的问题

建议是用字符串，因为你要反复的读取；这样你用缓存的方式接收要输入的内容，这样就会不用fflush。

在每个最后不带\n的printf后面加fflush(stdout); 在每个不想受接收缓冲区旧内容影响的scanf前面加rewind(stdin); 另外请检查scanf的返回值。 //请今后要用 char c; scanf("%c",&c); //时，都改为 char s[2]; char c; scanf("%1s",s); c=s[0];

~~1楼正解

引用 1 楼 user-4 的回复:fflush只能用于stdout 你可以用while循环getchar读光，直到EOF 这个我也有想过过。打比方说，如果我在循环结尾处里多加一句printf("...\n");，在不暂停每”。。。”持续输出的情况下清除键盘输入的多余的数据该怎么办呢？用WHILE能避免程序暂停吗？


Question: 急！急！急！关于bin文件中0x00的打包发送处理问题

那你把长度发送过去呗

对于8位的数组我已用sizeof成功发送接收0x00,但对于不满8位的，我无法使tmp_buf[8]={0x11,0x22,0x00,0x33,0x00,0x00} 的数组长度为6，有什么好的办法能做到这个么

你要提前算好数组长度啊。。难道你还想用strlen之类的得到长度？  另外数据你给漏了几个字节肯定也是不行的啊，这些0x00很有可能是某些int类型的高位字节，你给去掉了那还不seg fault？

刚才试了试用成员为数组和数组长度的结构体指针去传参数，对于24l01 他是读寄存器的值放到rx_buf中，而读取的数组长度我用结构指针的成员len去接受 是接收不到数值的 就是说len 数组长度发不过去 而发送端24l01显示的是send ok啊


Question: Eclipse C/++ 调试分析

但是他会直接把调试信息直接存到字符串啊，影响我的调试，明白？ 并不是调试输出麻烦，而是这个数据直接进入到了缓冲区，直接给字符串进行了赋值，我是没又办法调试的啊

你是没有输入，那是debug调试信息的输出，

赵老师，我也试了一下，不是这个原因，我换了一个eclipse的版本就可以了，感谢你们。 可能是这个版本的问题。

puts("请输入信息："); rewind(stdin);     scanf("%s", str);


Question: ……分配了一个不兼容的指针类型？

看一下你的数据结构定义

引用 4 楼 user-2 的回复:[quote=引用 3 楼 Lamuna 的回复:] [quote=引用 2 楼 user-2 的回复:] 你看下你的ITEM结构体中，next成员的类型是不是ITEM*类型  typedef struct Item{   int id;   char name[255];   struct Item *next; }ITEM;   应该就是ITEM吧？[/quote]  那你给的这部分代码应该没问题  你试下：item = (ITEM*)item->next;[/quote]  啊！非常感谢，我找到问题了。  我之前是struct item，后来改成了Struct Item，但是next的部分还是写成了struct item *next，所以错了。 非常感谢指导！

引用 3 楼 Lamuna 的回复:[quote=引用 2 楼 user-2 的回复:] 你看下你的ITEM结构体中，next成员的类型是不是ITEM*类型  typedef struct Item{   int id;   char name[255];   struct Item *next; }ITEM;   应该就是ITEM吧？[/quote]  那你给的这部分代码应该没问题  你试下：item = (ITEM*)item->next;

引用 2 楼 user-2 的回复:你看下你的ITEM结构体中，next成员的类型是不是ITEM*类型  typedef struct Item{   int id;   char name[255];   struct Item *next; }ITEM;   应该就是ITEM吧？

你看下你的ITEM结构体中，next成员的类型是不是ITEM*类型


Question: code blocks使用过程中字体突变！求大神解决

编程时直接改成英文模式，不用中文输入法。注释建议也写英文的。

注意看一下你输入法，是不是碰到的这个键正好是输入法的热键呢。 注意编程是用英文，半角模式

应该是输入法从半角变成了全角，切换一下输入法就行了。

我的天，为什么没办法标红了？，就是那句（zhe shi zen me le ?）

while(s[i] == 'e'||s[i] == 'E'){         if(s[++i] == '-'){             for(p = 1;p <= s[++i];++p){                 p = p * 0.1;                 return sum * p;             }         }         else{             for(p = 1;p <= s[i];++p){                 p = p * 10;                 return sum　    （ｚｈｅ　ｓｈｉ　ｚｅｎ　ｍｅ　ｌｅ？）             }         }     } }


引用 2 楼 jianwen0529 的回复:你ReadElement之前是不是使用getchar了？  确实在一个函数不小心读取了一个字符

你ReadElement之前是不是使用getchar了？

应该是因为回车符存在流缓存区种，使用如下代码在每次输入后执行流清空 char ch; while((scanf("%c",&ch)!=EOF)&&(ch!='\n'));


Question: 求大佬看看

vs里面，每一个.cpp文件或者说源文件都要包含stdafx.h文件，可以理解为硬性规定，iostream.h?这是C版本的iosream头文件了，如果是在vs里面写，直接#include<iostream> 欢迎指正。

还是没用，是不是没有头文件

#include<iostream>这样用


Question: 数据结构，一元多项式求和，改错

仅供参考：//链表实现一元多项式的加法减法乘法 #include <stdio.h> #include <stdlib.h> typedef struct node {     float coef;   //系数     int expn;     //指数     struct node *next; } PolyNode;      //多项式节点 polynomial node typedef PolyNode* Polynomial; Polynomial createPolynomial() {  //创建多项式     PolyNode *p, *q, *head = (PolyNode *)malloc(sizeof(PolyNode));   //头节点     head->next = NULL;     float coef;     int expn;     printf("输入该多项式每一项的系数和指数，每项一行，输入0 0结束！\n");     while (scanf("%f %d", &coef, &expn) && coef) {   // 默认，按指数递减排列         if (head->next) {             p = head;             while (p->next && expn < p->next->expn)                 p = p->next;             if (p->next) {                 if (expn == p->next->expn) { //有相同指数的直接把系数加到原多项式                     p->next->coef += coef;                     if (p->next->coef > -0.000001 && p->next->coef < 0.000001) { //若是相加后系数为0，则舍弃该节点                         q = p->next;                         p->next = q->next;                         free(q);                     }                 } else {                     q = (PolyNode*)malloc(sizeof(PolyNode));                     q->coef = coef;                     q->expn = expn;                     q->next = p->next;                     p->next = q;                 }             } else {                 p->next = (PolyNode*)malloc(sizeof(PolyNode));                 p = p->next;                 p->coef = coef;                 p->expn = expn;                 p->next = NULL;             }         } else {             head->next = (PolyNode*)malloc(sizeof(PolyNode));             head->next->coef = coef;             head->next->expn = expn;             head->next->next = NULL;         }     }     return head; } Polynomial multiply(Polynomial poly, float coef, int expn) {  //多项式与指定单项式相乘，该单项式为 coefx^expn     PolyNode *p, *q, *Poly = (PolyNode*)malloc(sizeof(PolyNode));     p = Poly;     q = poly->next;     while (q) {         p->next = (PolyNode*)malloc(sizeof(PolyNode));         p = p->next;         p->coef = (q->coef*coef);         p->expn = (q->expn + expn);         q = q->next;     }     p->next = NULL;     return Poly; } void add(Polynomial poly1, Polynomial poly2) {  //把 poly2 加到 poly1 上     PolyNode *p, *q, *r;     r = poly1;     p = poly1->next;  //指向第一个节点     q = poly2->next;     poly2->next = NULL;     while (p && q) {         if (p->expn > q->expn) {             r->next = p;             p = p->next;             r = r->next;         } else if (p->expn < q->expn) {             r->next = q;             q = q->next;             r = r->next;         } else {             PolyNode *t;             p->coef += q->coef;             if (!(p->coef > -0.000001 && p->coef < 0.000001)) //系数不为0             {                 r->next = p;                 r = r->next;                 p = p->next;             } else {                 t = p;                 p = p->next;                 free(t);             }             t = q;             q = q->next;             free(t);         }     }     if (p)         r->next = p;     if (q)         r->next = q; } Polynomial polySubtract(Polynomial poly1, Polynomial poly2) {  //多项式减法 poly1-poly2形成一个新的多项式     //把poly2的系数取相反数，形成一个新的多项式     Polynomial poly = (PolyNode*)malloc(sizeof(PolyNode)); //构造头节点     PolyNode *p, *q;     p = poly;     q = poly2->next;     while (q) {         p->next = (PolyNode*)malloc(sizeof(PolyNode));         p = p->next;         p->coef = -(q->coef);  //系数取反         p->expn = q->expn;         q = q->next;     }     p->next = NULL;     add(poly, poly1);  //利用加法     return poly; } Polynomial polyAdd(Polynomial poly1, Polynomial poly2) { //多项式相加 poly1+poly2形成一个新的多项式     Polynomial poly = (PolyNode*)malloc(sizeof(PolyNode));  //和多项式的头节点     poly->next = NULL;     PolyNode *p, *q, *r;     r = poly;     p = poly1->next;     q = poly2->next;     while (p&&q) {         if (p->expn > q->expn) {             r->next = (PolyNode*)malloc(sizeof(PolyNode));             r = r->next;             r->coef = p->coef;             r->expn = p->expn;             p = p->next;         } else if (p->expn < q->expn) {             r->next = (PolyNode*)malloc(sizeof(PolyNode));             r = r->next;             r->coef = q->coef;             r->expn = q->expn;             q = q->next;         } else {             float m = p->coef + q->coef;             if (!(m > -0.000001 && m < 0.000001)) {                 r->next = (PolyNode*)malloc(sizeof(PolyNode));                 r = r->next;                 r->coef = m;                 r->expn = p->expn;             }             q = q->next;             p = p->next;         }     }     while (p) {         r->next = (PolyNode*)malloc(sizeof(PolyNode));         r = r->next;         r->coef = p->coef;         r->expn = p->expn;         p = p->next;     }     while (q) {         r->next = (PolyNode*)malloc(sizeof(PolyNode));         r = r->next;         r->coef = q->coef;         r->expn = q->expn;         q = q->next;     }     r->next = NULL;     return poly; } Polynomial polyMultiply(Polynomial poly1, Polynomial poly2) {  //多项式相乘     Polynomial poly = (PolyNode*)malloc(sizeof(PolyNode));  //创建多项式和的头节点     poly->next = NULL;     PolyNode *p;     p = poly2->next;     while (p) {         add(poly, multiply(poly1, p->coef, p->expn));         p = p->next;     }     return poly; } void printPoly(Polynomial poly) {  //打印多项式     if (poly && poly->next) {         PolyNode *p = poly->next;  //p指向第一个节点         while (p->next) {             printf("%gx^%d", p->coef, p->expn);             p = p->next;             if (p && (p->coef > 0))                 printf("+");         }         if (p->expn == 0)             printf("%g", p->coef);   //打印常数项         else             printf("%gx^%d", p->coef, p->expn);         printf("\n");     } } void freePoly(Polynomial poly) {  //释放内存     if (poly && poly->next) {         PolyNode *p, *q;         p = poly;         while (p) {             q = p->next;             free(p);             p = q;         }     }     poly = NULL; } int main() {     printf("用链表实现多项式的加减法\n");     Polynomial poly1, poly2, poly3;     printf("创建多项式一\n");     poly1 = createPolynomial();     printf("多项式一：\n");     printPoly(poly1);     printf("创建多项式二\n");     poly2 = createPolynomial();     printf("多项式二：\n");     printPoly(poly2);     printf("两多项式相加，和为：\n");     poly3 = polyAdd(poly1, poly2);     printPoly(poly3);     freePoly(poly3);     printf("两个多项式相乘，积为：\n");     poly3 = polyMultiply(poly1, poly2);     printPoly(poly3);     freePoly(poly3);     printf("两多项式相减，差为：\n");     poly3 = polySubtract(poly1, poly2);     printPoly(poly3);     freePoly(poly1);     freePoly(poly2);     freePoly(poly3);     system("pause");     return 0; }

#include <stdio.h> #include <stdlib.h> #include <string.h>  #define OK 1 #define ERROR 0 #define TRUE 1 #define FALSE 0  typedef int Status; typedef int Elemtype;  typedef struct Node{     Elemtype cof;     Elemtype inx;     struct Node *next; }Node,*LinkList;  Status visit(Elemtype a, Elemtype b) {     //打印     printf("%d %d", a, b);     return OK; }    Status InitList(LinkList *L) {     (*L)=(LinkList)malloc(sizeof(Node));     if (!(*L))         return ERROR;      (*L)->next = NULL;     return OK; }  //计算表长 int ListLength(LinkList L) {     int i = 0;     LinkList p;      p = L->next;     while (p) {         i++;         p = p->next;     }      return i; }   //将表中第I个节点的值取出来，i从1开始 Status GetElem(LinkList L, int i, Elemtype *cof, Elemtype *inx) {     LinkList p;     int j;      p = L;     j = 1;     while (p && j < i) {         p = p->next;         j++;     }     if (!p)         return ERROR;     *cof=p->next->cof;     *inx=p->next->inx;      return OK; }    Status ListInsert(LinkList *L, int i, Elemtype cof, Elemtype inx) {     if(i < 1||i > ListLength(*L)+1)         return ERROR;      int j;     LinkList p, q;       p = *L;     j = 1;     while(p && j<i)     {         p = p->next;         j++;     }     if (!p || j > i)         return ERROR;      q = (LinkList)malloc(sizeof(Node));     if (!q) {         fprintf(stderr, "malloc error!\n");         return ERROR;     }     q->cof = cof;     q->inx = inx;      q->next = p->next;     p->next = q;      return OK; }   //打印L中系数非零的项 Status ListTraverse(LinkList L) {     LinkList p;     int juge;     juge = 0;     p = L;      while(p){         juge = p->cof;         if(juge)             break;         p = p->next;     }     if(!juge){         printf("0\n");         return OK;     }     p = L->next;      while (p) {         if (p->cof != 0) {             visit(p->cof, p->inx);             printf(" ");         }         p = p->next;     }     printf("\n");     /*        while(p && p->next != NULL){        if(p->cof != 0){        visit(p->cof, p->inx);        printf(" ");        }        p = p->next;        }        visit(p->cof, p->inx);        printf("\n");        */     return OK; }    Status PlusList(LinkList *L3,LinkList L1,LinkList L2) {     int i;//L1循环     int j;//L2循环     int k;//L3循环     Elemtype cof1, inx1;     Elemtype cof2, inx2;     k = 1;    i=1;      j=1;     while ((i<=ListLength(L1))&&(j<=ListLength(L2))) {         GetElem(L1, i, &cof1, &inx1);         GetElem(L2, j, &cof2, &inx2);         if (inx1 == inx2) {             ListInsert(L3, k++, cof1 + cof2, inx1);             i++;j++;         }         else if (inx1>inx2)         {             ListInsert(L3, k++, cof1, inx1);             i++;         }         else         {             ListInsert(L3, k++, cof2, inx2);             j++;         }     }      return OK; } int main() {     LinkList L1, L2, L3;     int cofn, inxn;//输入的系数和指数     int i;//循环     InitList(&L1);     InitList(&L2);     InitList(&L3);     i = 1;     while(scanf("%d%d", &cofn, &inxn) == 2 && inxn != -1){    /*此处注意 && */         ListInsert(&L1, i++, cofn, inxn);     }     i = 1;     while(scanf("%d%d", &cofn, &inxn) == 2 && cofn != -1){    /*此处注意  &&*/         ListInsert(&L2, i++, cofn, inxn);     }     PlusList(&L3, L1, L2);     ListTraverse(L3);     return 0; }  整体写的不错，有些地方做了微调，请详见代码； 编译测试通过了你的样例

哦，对了，特作说明，我作业是抄了一个博客的对“一元多项式相乘”的代码的一部分。原博主地址http://blog.csdn.net/u011753266/article/details/38384293，感谢博主祝我作业一臂之力


Question: 请大神帮助解决函数的有关问题，谢谢！

引用 5 楼 qq_36100960 的回复:接楼上的话，如果s是“abcabc”，t是"abc"，那么t在s中出现的最后一次，是最后三个字母，此时t中的字符'a'，对应到s中，索引值（数组下标）是3 谢谢，理解了

引用 4 楼 caine12345 的回复:[quote=引用 3 楼 paschen 的回复:] [quote=引用 2 楼 caine12345 的回复:] [quote=引用 1 楼 paschen 的回复:] 引用练习4-1 编写函数strrindex(s,t)，它返回字符串t在s中最右边出现的位置。如果s中不包含t，则返回-1  首先这个问题我就感觉很别扭，他想表达的意思我不理解，比如说我输入(abcdefg,bcdefg abc,efg)这串字符，  题目的意思就是：  如果字符串要s是"abcabc'，字符串t是“abc”，那么最右边出现的位置就是3，如果s中不包含t，就返回-1  弱弱问一句，为啥是3？3代表的是什么意思呢？[/quote]  索引号，最左边是0[/quote]  不好意思，我还是有点不明白您说的索引号是什么意思，最左边是0 是什么意思？[/quote]  a  b  c  a  b  c 0  1  2  3  4  5

引用 3 楼 paschen 的回复:[quote=引用 2 楼 caine12345 的回复:] [quote=引用 1 楼 paschen 的回复:] 引用练习4-1 编写函数strrindex(s,t)，它返回字符串t在s中最右边出现的位置。如果s中不包含t，则返回-1  首先这个问题我就感觉很别扭，他想表达的意思我不理解，比如说我输入(abcdefg,bcdefg abc,efg)这串字符，  题目的意思就是：  如果字符串要s是"abcabc'，字符串t是“abc”，那么最右边出现的位置就是3，如果s中不包含t，就返回-1  弱弱问一句，为啥是3？3代表的是什么意思呢？[/quote]  索引号，最左边是0[/quote]  不好意思，我还是有点不明白您说的索引号是什么意思，最左边是0 是什么意思？

引用 2 楼 caine12345 的回复:[quote=引用 1 楼 paschen 的回复:] 引用练习4-1 编写函数strrindex(s,t)，它返回字符串t在s中最右边出现的位置。如果s中不包含t，则返回-1  首先这个问题我就感觉很别扭，他想表达的意思我不理解，比如说我输入(abcdefg,bcdefg abc,efg)这串字符，  题目的意思就是：  如果字符串要s是"abcabc'，字符串t是“abc”，那么最右边出现的位置就是3，如果s中不包含t，就返回-1  弱弱问一句，为啥是3？3代表的是什么意思呢？[/quote]  索引号，最左边是0

引用 1 楼 paschen 的回复:引用练习4-1 编写函数strrindex(s,t)，它返回字符串t在s中最右边出现的位置。如果s中不包含t，则返回-1  首先这个问题我就感觉很别扭，他想表达的意思我不理解，比如说我输入(abcdefg,bcdefg abc,efg)这串字符，  题目的意思就是：  如果字符串要s是"abcabc'，字符串t是“abc”，那么最右边出现的位置就是3，如果s中不包含t，就返回-1  弱弱问一句，为啥是3？3代表的是什么意思呢？


Question: 创建二叉树的代码编译错误，求大神帮看看

不好意思刚没在线。我这把树的结构发一下 struct BinTreeNode; typedef struct BinTreeNode *PBinTreeNode; typedef char Datatype; struct BinTreeNode { 	Datatype info; 	PBinTreeNode llink; 	PBinTreeNode rlink; }; typedef struct BinTreeNode *BinTree; typedef BinTree *PBinTree;

双击错误提示，定位到具体位置。这里看不出有什么问题  1：检查是否有左右操作数类型不能匹配的情况 2：BinTreeNode在这个文件中是否是完全类型（能看到定义的）

*pbt类型和createBinTreeNode的返回值类型不一样吧； 感觉这个地方怪怪的。 我认为你应该是pbt类型里的一个元素是PBinTreeNode类型的。  主要还是要看你的数据结构定义。

这些类型怎么定义的啊


Question: 函数中局部变量在-O0选项下奇怪的执行过程

引用 5 楼 chenzheng1030 的回复:这个问题很有意思，其实这个问题的难点不在-O0的情况下为什么出现循坏打印，我觉得难点在为什么-O2会出现segment fault。 花时间看了下，贴下来跟群主分享一下。 首先说说-O0，为什么出现循环打印。其实这个问题很简单，因为编译器在编译的时候就会为每个局部变量在栈上分配空间，打印一下变量i和指针p的地址以及p的内容，楼主就知道为什么会循环了。 下面是我再X86 64位上的结果：带上-g，然后用gdb去调试。 (gdb) p &i $1 = (int *) 0xbffff258 (gdb) p &p $2 = (int **) 0xbffff25c (gdb) p p $3 = (int *) 0xbffff248 (gdb)   局部变量i在栈上的地址是(int *) 0xbffff258，指针p指向ss1，ss1的地址是0xbffff248,所以每次循环4次之后，*(p+4)的地址实际上是0xbffff258，这个地址是i的地址，所以这个赋值实际上是将i的地址又赋为了0，所以会出现循环打印。  其实我重点想说的是-O2的情况下为什么会出现core dump。 这个问题也分为两个部分。 首先第一个部分想说的是，为什么-O2为什么不像-O0一样出现循环打印呢。这个其实是因为编译器做了优化，将循环变量i存在了寄存器里面，将变量i的值不再保存在栈上了，每次循环的时候都是从寄存器里取i的值，所以*(p+4)的值，不可能会改变i的值。这个结论可以在编译的时候加上-g，然后查看调试信息里的变量i是怎么取值得到的。  <4><42d>: Abbrev Number: 26 (DW_TAG_variable)     <42e>   DW_AT_name        : i	     <430>   DW_AT_decl_file   : 1	     <431>   DW_AT_decl_line   : 16	     <432>   DW_AT_type        : <0x3b>	     <436>   DW_AT_location    : 0x5c	(location list)    //i是从location list中取值      0000005c 08048510 0804851c (DW_OP_reg3 (ebx))   //location 0x5c表示的是从寄存器3中取值，也就是i是存在ebx中的     0000005c <End of list>  第二个是解释为什么-O2会出现core dump。这个概括的说是因为*(p+i) = 0 是这条语句破坏了程序的运行布局。包括改了只读存储区的内容或者是改了其他的东西，比如改了返回地址。 比如，我将程序稍微改了一下，将循环次数从10000次改为8次，程序仍然会出现core dump。（8这个数字是个临界值） 调试core文件： gdb a.out core Core was generated by `./a.out'. Program terminated with signal 11, Segmentation fault. #0  0x00000000 in ?? () (gdb) p $pc $1 = (void (*)()) 0 发现问题了，发生crash的时候，pc值指向了0，这个pc值就是在函数test2中，进行*(p+i) = 0的时候，由于栈是从大到小，而且程序的返回地址是存在局部变量之前，即高地址，所以*(p+i)=0，会将pc值改为了0，这样在test2返回的时候，返回到了地址0，所以就出现了crash。  之前说过8是个临界数字，如果大于等于8会出现crash，为7或者更小就不会出现crash，但是局部变量的值可能会出现意想不到的的改变。 高手；分析细致入微，真是专家级别；

越界是未定义行为，不能用没有运行出错来证明正确

进程意外退出会在当前目录下产生‘core’文件或形如‘core.数字’的文件比如‘core.1234’ 使用命令 gdb 运行程序名 core或core.数字 进入gdb然后使用bt命令 可以查看进程意外退出前函数调用的堆栈，内容为从上到下列出对应从里层到外层的函数调用历史。 如果进程意外退出不产生core文件，参考“ulimit -c core文件最大块大小”命令

我怀疑，跟编译选项没关系。起码错误（段错误）跟编译选项没关系

for(int i=0;i<10000;++i){                   *(p+i)=0;                   printf("%d %p\n",i,p+i);                   //sleep(2);         } 这部分代码可能会遇到非法地址访问，因为p+i，指向的地址很有可能会越过此函数栈，并访问非法地址，所以会导致段错误。 如果要验证局部变量在函数栈上是如何分配的，分配顺序是怎样的，建议你定义一个局部数组，然后打印数组中的元素和它的地址。这样起码不会越界（10000太大了，10000  * 4，访问的大小约40k字节，这个函数栈不会有这么大，因为你定义的这个函数里没有局部变量需要这么大的。


Question: 十进制0.81转成IEEE规格的问题

谢谢各位答复

引用 3 楼 zhao4zhong1 的回复:浮点数格式 http://bbs.csdn.net/topics/390676437额，马上还看不懂，才学到给变量赋值，先存着，再往后看看估计就懂了。

引用 1 楼 user-2 的回复:应该是浮点舍入模式的问题吧 0.81第23位后面是111...，所以就进了一位 应该就是了，刚又试了几个数，23位后面有1就进一位，0就不进位。

应该是浮点舍入模式的问题吧 0.81第23位后面是111...，所以就进了一位


Question: 关于数组的顺序存储的问题

引用 7 楼 cfjtaishan 的回复:#include<stdio.h> #include<stdarg.h> #include<stdlib.h> #define OK 1 #define ERROR 0 #define OVERFLOW -2 //#define NULL 0 #define    MAX_ARRAY_DIM 8 typedef int ElemType; typedef struct {     ElemType *base;     int dim;     int *bounds;     int *constants; }Array; //构造 int InitArray(Array *A, int dim,...) {     int i;     int elemtotal=1;     va_list ap;     if(dim<1||dim>MAX_ARRAY_DIM)         return ERROR;     A->dim = dim;     A->bounds = (int *)malloc(dim * sizeof(int));     if(!A->bounds) exit (OVERFLOW);     va_start(ap,dim);     for(i = 0; i < dim; i++)     {         A->bounds[i] = va_arg(ap,int);         if(A->bounds[i]<0)             return OVERFLOW;         elemtotal *= A->bounds[i];     }     va_end(ap);     A->base=(ElemType *)malloc(elemtotal * sizeof(ElemType));     A->constants=(int *)malloc(dim * sizeof(int));     if(!A->constants)         exit (OVERFLOW);     A->constants[dim-1]=1;     for(i=dim-2;i>=0;i--)         A->constants[i] = A->bounds[i+1] * A->constants[i+1];     return OK; } //销毁 int DestroyArray(Array *A) {     if(!A->base)         return ERROR;     free(A->base);     A->base=NULL;     if(!A->bounds)         return ERROR;     free(A->bounds);     A->bounds=NULL;     if(!A->constants)         return ERROR;     free(A->constants);     A->constants=NULL;      return OK; } //定位 int LocateArray(Array A,va_list ap,int *off) {     int ind,i;     //off=0;     for(i=0;i<A.dim;i++)     {         ind=va_arg(ap,int);         if(ind<0||ind>=A.bounds[i])             return OVERFLOW;         *off += A.constants[i] * ind;     }     return OK; } //分配 int AssignArray(Array *A,ElemType e,...) {     va_list ap;     int off = 0, result;    /* Initize the argu: off */     va_start (ap,e);     if((result = LocateArray(*A, ap, &off))<=0)         return result;     *(A->base+off)=e;     va_end(ap);     return OK; } //显示值 int ValueArray(Array A, ElemType *e,...) {     va_list ap;     int off = 0,result;    /* Initize the argu: off*/     va_start (ap,e);     if((result=LocateArray(A, ap, &off))<=0)         return result;     *e = *(A.base + off);     va_end(ap);     return OK; } int main() {     Array A;     ElemType e,n;     int i,j,k,a[3];     int dim=3;     printf("请输入各维长度（三维）：\n");     for(i=0;i<3;i++)         scanf("%d",&a[i]);     InitArray(&A, dim, a[0], a[1], a[2]);     printf("请输入各元素：\n");     for(i=0; i < a[0];i++)         for(j=0;j<a[1];j++)             for(k=0;k<a[2];k++)             {                 scanf("%d",&e);                 AssignArray(&A,e,i,j,k);             }     for(i=0;i<a[0];i++)         for(j=0;j<a[1];j++)             for(k=0;k<a[2];k++)             {                 ValueArray(A, &e,i,j,k);                 printf("%d\t",e);             }     return 0; } 试试这个版本，我之前是这样实现的，然后把指针都改成了引用，因为C语言不支持&引用的定义。 另外，遇到问题急我没有用，主要是拿出时间好好研究一下问题。 确实这样就可以了，十分感谢！

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

引用 5 楼 cfjtaishan 的回复:[quote=引用 4 楼 weixin_37969367 的回复:] [quote=引用 2 楼 cfjtaishan 的回复:] #include<stdio.h> #include<stdarg.h> #include<stdlib.h> #define OK 1 #define ERROR 0 #define OVERFLOW -2 //#define NULL 0 #define    MAX_ARRAY_DIM 8 typedef int ElemType; typedef struct {     ElemType *base;     int dim;     int *bounds;     int *constants; }Array; //构造 int InitArray(Array &A, int dim,...) {     int i;     int elemtotal=1;     va_list ap;     if(dim<1||dim>MAX_ARRAY_DIM)         return ERROR;     A.dim=dim;     A.bounds = (int *)malloc(dim * sizeof(int));     if(!A.bounds) exit (OVERFLOW);     va_start(ap,dim);     for(i=0;i<dim;i++)     {         A.bounds[i]=va_arg(ap,int);         if(A.bounds[i]<0)             return OVERFLOW;         elemtotal *= A.bounds[i];     }     va_end(ap);     A.base=(ElemType *)malloc(elemtotal * sizeof(ElemType));     A.constants=(int *)malloc(dim * sizeof(int));     if(!A.constants) exit (OVERFLOW);     A.constants[dim-1]=1;     for(i=dim-2;i>=0;i--)         A.constants[i]=A.bounds[i+1]*A.constants[i+1];     return OK; } //销毁 int DestroyArray(Array &A) {     if(!A.base) return ERROR;     free(A.base); A.base=NULL;     if(!A.bounds) return ERROR;     free(A.bounds); A.bounds=NULL;     if(!A.constants) return ERROR;     free(A.constants); A.constants=NULL;     return OK; } //定位 int LocateArray(Array A,va_list ap,int &off) {     int ind,i;     //off=0;     for(i=0;i<A.dim;i++)     {         ind=va_arg(ap,int);         if(ind<0||ind>=A.bounds[i])             return OVERFLOW;         off +=A.constants[i] * ind;     }     return OK; } //分配 int AssignArray(Array &A,ElemType e,...) {     va_list ap;     int off = 0,result;    /* Initize the argu: off */     va_start (ap,e);     if((result=LocateArray(A,ap,off))<=0)         return result;     *(A.base+off)=e;     va_end(ap);     return OK; } //显示值 int ValueArray(Array A,ElemType &e,...) {     va_list ap;     int off = 0,result;    /* Initize the argu: off*/     va_start (ap,e);     if((result=LocateArray(A,ap,off))<=0)         return result;     e=*(A.base+off);     va_end(ap);     return OK; } int main() {     Array A;     ElemType e,n;     int i,j,k,a[3];     int dim=3;     printf("请输入各维长度（三维）：\n");     for(i=0;i<3;i++)         scanf("%d",&a[i]);     InitArray(A,dim,a[0],a[1],a[2]);     printf("请输入各元素：\n");     for(i=0; i < a[0];i++)         for(j=0;j<a[1];j++)             for(k=0;k<a[2];k++)             {                 scanf("%d",&e);                 AssignArray(A,e,i,j,k);             }     for(i=0;i<a[0];i++)         for(j=0;j<a[1];j++)             for(k=0;k<a[2];k++)             {                 ValueArray(A,e,i,j,k);                 printf("%d\t",e);             }     return 0; }   两个问题： 1. NULL不用在define，因为stdio.h文件里已经定义，如果重定义建议定义成如下： #define NULL (void*)0 2. 初始化off，代码里有注释，否则随机数会导致越界，出现段错误。这个是导致输出错误的关键。 但是这样改了之后输出的结果还是8个8，不是我输入的12345678啊[/quote] 你用我改过之后的代码测试的吗？ 我是改了你的代码，并测试的。[/quote] 对啊，就用的你改过的代码，原封不动，输入12345678出来的结果还是88888888，这是怎么回事呀？

引用 4 楼 weixin_37969367 的回复:[quote=引用 2 楼 cfjtaishan 的回复:] #include<stdio.h> #include<stdarg.h> #include<stdlib.h> #define OK 1 #define ERROR 0 #define OVERFLOW -2 //#define NULL 0 #define    MAX_ARRAY_DIM 8 typedef int ElemType; typedef struct {     ElemType *base;     int dim;     int *bounds;     int *constants; }Array; //构造 int InitArray(Array &A, int dim,...) {     int i;     int elemtotal=1;     va_list ap;     if(dim<1||dim>MAX_ARRAY_DIM)         return ERROR;     A.dim=dim;     A.bounds = (int *)malloc(dim * sizeof(int));     if(!A.bounds) exit (OVERFLOW);     va_start(ap,dim);     for(i=0;i<dim;i++)     {         A.bounds[i]=va_arg(ap,int);         if(A.bounds[i]<0)             return OVERFLOW;         elemtotal *= A.bounds[i];     }     va_end(ap);     A.base=(ElemType *)malloc(elemtotal * sizeof(ElemType));     A.constants=(int *)malloc(dim * sizeof(int));     if(!A.constants) exit (OVERFLOW);     A.constants[dim-1]=1;     for(i=dim-2;i>=0;i--)         A.constants[i]=A.bounds[i+1]*A.constants[i+1];     return OK; } //销毁 int DestroyArray(Array &A) {     if(!A.base) return ERROR;     free(A.base); A.base=NULL;     if(!A.bounds) return ERROR;     free(A.bounds); A.bounds=NULL;     if(!A.constants) return ERROR;     free(A.constants); A.constants=NULL;     return OK; } //定位 int LocateArray(Array A,va_list ap,int &off) {     int ind,i;     //off=0;     for(i=0;i<A.dim;i++)     {         ind=va_arg(ap,int);         if(ind<0||ind>=A.bounds[i])             return OVERFLOW;         off +=A.constants[i] * ind;     }     return OK; } //分配 int AssignArray(Array &A,ElemType e,...) {     va_list ap;     int off = 0,result;    /* Initize the argu: off */     va_start (ap,e);     if((result=LocateArray(A,ap,off))<=0)         return result;     *(A.base+off)=e;     va_end(ap);     return OK; } //显示值 int ValueArray(Array A,ElemType &e,...) {     va_list ap;     int off = 0,result;    /* Initize the argu: off*/     va_start (ap,e);     if((result=LocateArray(A,ap,off))<=0)         return result;     e=*(A.base+off);     va_end(ap);     return OK; } int main() {     Array A;     ElemType e,n;     int i,j,k,a[3];     int dim=3;     printf("请输入各维长度（三维）：\n");     for(i=0;i<3;i++)         scanf("%d",&a[i]);     InitArray(A,dim,a[0],a[1],a[2]);     printf("请输入各元素：\n");     for(i=0; i < a[0];i++)         for(j=0;j<a[1];j++)             for(k=0;k<a[2];k++)             {                 scanf("%d",&e);                 AssignArray(A,e,i,j,k);             }     for(i=0;i<a[0];i++)         for(j=0;j<a[1];j++)             for(k=0;k<a[2];k++)             {                 ValueArray(A,e,i,j,k);                 printf("%d\t",e);             }     return 0; }   两个问题： 1. NULL不用在define，因为stdio.h文件里已经定义，如果重定义建议定义成如下： #define NULL (void*)0 2. 初始化off，代码里有注释，否则随机数会导致越界，出现段错误。这个是导致输出错误的关键。 但是这样改了之后输出的结果还是8个8，不是我输入的12345678啊[/quote] 你用我改过之后的代码测试的吗？ 我是改了你的代码，并测试的。

引用 2 楼 cfjtaishan 的回复:#include<stdio.h> #include<stdarg.h> #include<stdlib.h> #define OK 1 #define ERROR 0 #define OVERFLOW -2 //#define NULL 0 #define    MAX_ARRAY_DIM 8 typedef int ElemType; typedef struct {     ElemType *base;     int dim;     int *bounds;     int *constants; }Array; //构造 int InitArray(Array &A, int dim,...) {     int i;     int elemtotal=1;     va_list ap;     if(dim<1||dim>MAX_ARRAY_DIM)         return ERROR;     A.dim=dim;     A.bounds = (int *)malloc(dim * sizeof(int));     if(!A.bounds) exit (OVERFLOW);     va_start(ap,dim);     for(i=0;i<dim;i++)     {         A.bounds[i]=va_arg(ap,int);         if(A.bounds[i]<0)             return OVERFLOW;         elemtotal *= A.bounds[i];     }     va_end(ap);     A.base=(ElemType *)malloc(elemtotal * sizeof(ElemType));     A.constants=(int *)malloc(dim * sizeof(int));     if(!A.constants) exit (OVERFLOW);     A.constants[dim-1]=1;     for(i=dim-2;i>=0;i--)         A.constants[i]=A.bounds[i+1]*A.constants[i+1];     return OK; } //销毁 int DestroyArray(Array &A) {     if(!A.base) return ERROR;     free(A.base); A.base=NULL;     if(!A.bounds) return ERROR;     free(A.bounds); A.bounds=NULL;     if(!A.constants) return ERROR;     free(A.constants); A.constants=NULL;     return OK; } //定位 int LocateArray(Array A,va_list ap,int &off) {     int ind,i;     //off=0;     for(i=0;i<A.dim;i++)     {         ind=va_arg(ap,int);         if(ind<0||ind>=A.bounds[i])             return OVERFLOW;         off +=A.constants[i] * ind;     }     return OK; } //分配 int AssignArray(Array &A,ElemType e,...) {     va_list ap;     int off = 0,result;    /* Initize the argu: off */     va_start (ap,e);     if((result=LocateArray(A,ap,off))<=0)         return result;     *(A.base+off)=e;     va_end(ap);     return OK; } //显示值 int ValueArray(Array A,ElemType &e,...) {     va_list ap;     int off = 0,result;    /* Initize the argu: off*/     va_start (ap,e);     if((result=LocateArray(A,ap,off))<=0)         return result;     e=*(A.base+off);     va_end(ap);     return OK; } int main() {     Array A;     ElemType e,n;     int i,j,k,a[3];     int dim=3;     printf("请输入各维长度（三维）：\n");     for(i=0;i<3;i++)         scanf("%d",&a[i]);     InitArray(A,dim,a[0],a[1],a[2]);     printf("请输入各元素：\n");     for(i=0; i < a[0];i++)         for(j=0;j<a[1];j++)             for(k=0;k<a[2];k++)             {                 scanf("%d",&e);                 AssignArray(A,e,i,j,k);             }     for(i=0;i<a[0];i++)         for(j=0;j<a[1];j++)             for(k=0;k<a[2];k++)             {                 ValueArray(A,e,i,j,k);                 printf("%d\t",e);             }     return 0; }   两个问题： 1. NULL不用在define，因为stdio.h文件里已经定义，如果重定义建议定义成如下： #define NULL (void*)0 2. 初始化off，代码里有注释，否则随机数会导致越界，出现段错误。这个是导致输出错误的关键。 但是这样改了之后输出的结果还是8个8，不是我输入的12345678啊

引用 1 楼 jack960330 的回复:请把问题讲明白，这样别人怎么知道出了啥事 就是想让最后输出的结果是我之前输入的各元素值，不是88888888


Question: VS2013编程，查找内存方面的错误

有一些办法是能检测内存泄露的  http://blog.csdn.net/windows_nt/article/details/8652191

如果是要检查申请的内存有没释放可参看： http://blog.csdn.net/windows_nt/article/details/8652191  除了分配的内存会泄露，你使用的各种资源（GDI、位图、画刷）等没释放也会泄露

检查是否资源泄漏的办法之一： 在任务管理器 进程 查看 选择列 里面选择：内存使用、虚拟内存大小、句柄数、线程数、USER对象、GDI对象 让你的程序(进程)不退出,循环执行主流程很多遍，越多越好，比如1000000次甚至无限循环，记录以上各数值，再隔至少一小时，越长越好，比如一个月，再记录以上各数值。如果以上两组数值的差较大或随时间流逝不断增加，则铁定有对应资源的资源泄漏！  搜“GDI泄露检测”


Question: C语言定义函数形参是结构体指针，引用函数时参数用的是（&+结构体变量）

声明时，A *a表示a是指向A类型的指针，A &a表示a是A类型的引用； 调用时，*a表示取a指向的内容，&a表示取a的地址。

引用 1 楼 cfjtaishan 的回复:形参的星号是指指针，就是结构体类型的指针，函数形参是一个结构体指针，实参也需要一个该结构体类型的指针，也就是要实参是一个地址传给形参；故在函数调用是使用的是&符号，就是区地址，将结构体变量的地址传过去。这样在函数里对于形参的修改就是对实参结构体变量的修改。  其实我发帖提问的是，因为还看到有其它的函数 也是这样声明： void func(MyTypeDef* adc)        //MyTypeDef  是结构体类型 {  }  但是引用时却是 func(Initabc);   //MyTypeDef   Initabc;   此处实参中无取地址符&  这是如何理解的？

Init需要的参数类型是指向这种结构体的指针类型，所以用*  调用时的&是取地址


Question: 统计一个整数中某数字的出现次数

#include <stdio.h>  int Count_Didit(const int N,const int D);  int main() { 	int N,D; 	scanf("%d %d",&N,&D); 	printf("%d\n",Count_Digit(N,D)); 	return 0; }  int Count_Digit(int N, int D) { 	int a=0,b; 	N = N<0 ? -N:N; 	while(N > 0) 	{ 		b = N%10; 		if(b == D) 		{ 			a++; 		} 		N = N/10; 	} 	return a; }  你main函数为什么要整一大堆东西

哦哦，会了#include<stdio.h>  void main(){  int countdigit(long number,int digit); int i,repeat; int count; long in; printf("Input repeat:\n"); scanf("%d",&repeat); for(i=1;i<=repeat;i++){ printf("Input a number:\n"); scanf("%ld",&in); count=countdigit(in,2); printf("count=%d\n",count); } } int countdigit(long number,int digit) { int num,count=0; number=number<0?-number:number; while(number)     {     num=number%10;     if(num==digit)count++;     number/=10;     }     return count; }

刚开始用，不太会，怎么表示啊

一个小小的建议,下次具体的代码能不能像二楼那样子表现出来?

什么情况？？？？

谢谢

注意代码风格，函数声明建议放在函数外。代码可以写的更条理一些，需要空格或者换行的还是要换行，这样有利于代码的阅读。

#include <stdio.h>  int countdigit(long number,int digit);  int main(void) {     int i,repeat;     int count;     long in;      printf("Input repeat:\n");     scanf("%d", &repeat);     for (i = 1; i <= repeat; i++) {         printf("Input a number:\n");         scanf("%ld", &in);         count = countdigit(in,2);         printf("count=%d\n",count);     }     return 0; } int countdigit(long number,int digit) {     int num,count=0;      number = number < 0 ? -number : number;      while (number) {         num = number % 10;    /*should number, not num,*/         if(num == digit)             count++;         number/=10;     }     return count; }  原因很简单，就是这句改成这样： num = number % 10;


Question: 新手困惑，求解（在下在此先谢过了）

兄弟刚入门的吧？先去听听老师怎么讲的！

小六六，别急，先回去听课。听完课了就懂了

引用 1 楼 cfjtaishan 的回复:这些问题基本上都是很基础的C语言语法： 1. 大括号在for后面还是另起一行这是属于代码风格的问题，即coding style.不同的公司可能有不同的代码风格，这个跟写代码的爱好也有一定关系；跟程序逻辑没关系； 2. //后面的内容是注释，//是表示后面的内容不属于代码逻辑的一部分，仅用于说明下面的一句或前面一句的逻辑或功能； 3. 是可以的，至于为什么用，你可以通过两种形式加以对比，%2d是表示占用2个字符的位置，为了是使输出对齐。 4. 这个是约定，因为main函数是int类型的，你平时学习的可能定义main函数的类型都是void，所以不需要一个return 0; 看来已经有人解决了。


Question: 在不支持64位数据类型的环境中，如何把两个32位数表示的64位数据转换成十进制?

引用 6 楼 JerKii 的回复:我倒是想到一个办法，不过如果数据太大，性能可能会是问题  你怎么知道性能会是问题？你测试过了？ printf, sprintf什么的可能都是类似的写法，也没见几个说性能太差

引用 3 楼 cfjtaishan 的回复:[quote=引用 2 楼 JerKii 的回复:]  谢谢~~~ 但是我没有sprintf这类函数可以使用。即使有，他也不支持 %llx 。  [quote=引用 1 楼 cfjtaishan 的回复:] #include <stdio.h>   int main(void) {      unsigned int h32 = 0xd;      unsigned int l32 = 0xBDA6FC24;      unsigned long long u64;      char u64tostring[32];       u64 = 0xd;      u64 = (u64 << 32) + l32;       printf("u64 = %llu\n", u64);       sprintf(u64tostring, "%llu", u64);      puts(u64tostring);       return 0; } 在32为系统里，long long类型是8个字节（64位），所以可以满足你的需求；[/quote] 不会吧，怎么还有sprintf，但是不支持%llu的？那么直接用u64的形式吧，通过移位得到一个64位的数据。[/quote] C90编译器？不会都不支持long long吧。。

找到一篇文章，跟大家分析一下 http://blog.csdn.net/zhaopeng2511/article/details/6766804

事实上我不是在c里面实现这个功能。我需要在一个嵌入式lua里面实现64位数据的十进制输出。而且当前嵌入式设备里面使用的lua不支持64位数据的操作。  我倒是想到一个办法，不过如果数据太大，性能可能会是问题： int u64tostring(unsigned int hi32, unsigned int lo32, char *buf, int blen) {     unsigned int HH = hi32, LL = lo32;     unsigned int H = 0, L = 0, t, n = 0, len = 0, i;     do     {         do         {             t = lo32 / 10;             lo32 %= 10;             if (t > 0xffffffff - L)                 H += 1;             L += t;              if (hi32 == 0)                 break;             hi32 -= 1;             lo32 = 0xffffffff - 10 + lo32 + 1;             n += 1;         } while (1);         if (n > 0xffffffff - L)             H += 1;         L += n;         buf[blen - ++len] = lo32 + '0';         hi32 = H;         lo32 = L;         H = L = n = 0;     } while (hi32 || lo32);      buf[len] = 0;     printf("\r\n ==> %x-%08x : %s", HH, LL, buf);     return len; } 引用 4 楼 vnvlyp 的回复:[quote=引用 3 楼 cfjtaishan 的回复:] [quote=引用 2 楼 JerKii 的回复:]  谢谢~~~ 但是我没有sprintf这类函数可以使用。即使有，他也不支持 %llx 。  [quote=引用 1 楼 cfjtaishan 的回复:] #include <stdio.h>   int main(void) {      unsigned int h32 = 0xd;      unsigned int l32 = 0xBDA6FC24;      unsigned long long u64;      char u64tostring[32];       u64 = 0xd;      u64 = (u64 << 32) + l32;       printf("u64 = %llu\n", u64);       sprintf(u64tostring, "%llu", u64);      puts(u64tostring);       return 0; } 在32为系统里，long long类型是8个字节（64位），所以可以满足你的需求；[/quote] 不会吧，怎么还有sprintf，但是不支持%llu的？那么直接用u64的形式吧，通过移位得到一个64位的数据。[/quote] C90编译器？不会都不支持long long吧。。[/quote]

最好使用标准的64位类型   如果你要自己做，就是  union u64 { struct { int high; int low; }a; long long b; };

引用 2 楼 JerKii 的回复:谢谢~~~ 但是我没有sprintf这类函数可以使用。即使有，他也不支持 %llx 。  [quote=引用 1 楼 cfjtaishan 的回复:] #include <stdio.h>   int main(void) {      unsigned int h32 = 0xd;      unsigned int l32 = 0xBDA6FC24;      unsigned long long u64;      char u64tostring[32];       u64 = 0xd;      u64 = (u64 << 32) + l32;       printf("u64 = %llu\n", u64);       sprintf(u64tostring, "%llu", u64);      puts(u64tostring);       return 0; } 在32为系统里，long long类型是8个字节（64位），所以可以满足你的需求；[/quote] 不会吧，怎么还有sprintf，但是不支持%llu的？那么直接用u64的形式吧，通过移位得到一个64位的数据。

谢谢~~~ 但是我没有sprintf这类函数可以使用。即使有，他也不支持 %llx 。  引用 1 楼 cfjtaishan 的回复:#include <stdio.h>   int main(void) {      unsigned int h32 = 0xd;      unsigned int l32 = 0xBDA6FC24;      unsigned long long u64;      char u64tostring[32];       u64 = 0xd;      u64 = (u64 << 32) + l32;       printf("u64 = %llu\n", u64);       sprintf(u64tostring, "%llu", u64);      puts(u64tostring);       return 0; } 在32为系统里，long long类型是8个字节（64位），所以可以满足你的需求；


Question: C语言命令行参数问题

引用 6 楼 cfjtaishan 的回复:[quote=引用 5 楼 bcai_yuan 的回复:] [quote=引用 3 楼 cfjtaishan 的回复:] [quote=引用 2 楼 bcai_yuan 的回复:] [quote=引用 1 楼 cfjtaishan 的回复:] #include<stdio.h> #include<string.h>  #define MAXLINE 1000  //int getline(char *s,int lim);  char pattern[] = "ould";  int main(int argc,char *argv[]) {     int found = 0, i;      if (argc < 2) {         printf("Usage: find pattern\n");     } else {         for (i = 1; i < argc; i++) {             puts(argv[i]);             if(strstr(argv[i], pattern)) {                 printf("%s\n", argv[i]);                 found++;             }         }     }     printf("found = %d\n", found);     return found; } 需要分清终端输入和程序里getline输入的区别；终端输入的数据会保存在argv字符指针数组里，这些字符串是以空格为分割的。 getline是程序里要输入的。 之所以你输入command could you help me不能运行while里的getline，因为argc的值此时为5 != 2  这样的话我不就是检测我在终端输入的字符串里面是否含有pattern了吗？但是我运行的时候无论终端输入是否含有“ould”，都能运行出来，而且也不打印found的值，这是为什么？  如果我想引用getline函数又怎么引用呢？这样可以让程序更加灵活一点。[/quote] 你是用我的demo测试的吗？[/quote] 不是，我就直接在cmd里测试的。我不懂什么是demo测试[/quote] 就是用我的代码测试，先编译我的代码，然后用我的代码测试[/quote] 直接编译测试就是这样啊

引用 5 楼 bcai_yuan 的回复:[quote=引用 3 楼 cfjtaishan 的回复:] [quote=引用 2 楼 bcai_yuan 的回复:] [quote=引用 1 楼 cfjtaishan 的回复:] #include<stdio.h> #include<string.h>  #define MAXLINE 1000  //int getline(char *s,int lim);  char pattern[] = "ould";  int main(int argc,char *argv[]) {     int found = 0, i;      if (argc < 2) {         printf("Usage: find pattern\n");     } else {         for (i = 1; i < argc; i++) {             puts(argv[i]);             if(strstr(argv[i], pattern)) {                 printf("%s\n", argv[i]);                 found++;             }         }     }     printf("found = %d\n", found);     return found; } 需要分清终端输入和程序里getline输入的区别；终端输入的数据会保存在argv字符指针数组里，这些字符串是以空格为分割的。 getline是程序里要输入的。 之所以你输入command could you help me不能运行while里的getline，因为argc的值此时为5 != 2  这样的话我不就是检测我在终端输入的字符串里面是否含有pattern了吗？但是我运行的时候无论终端输入是否含有“ould”，都能运行出来，而且也不打印found的值，这是为什么？  如果我想引用getline函数又怎么引用呢？这样可以让程序更加灵活一点。[/quote] 你是用我的demo测试的吗？[/quote] 不是，我就直接在cmd里测试的。我不懂什么是demo测试[/quote] 就是用我的代码测试，先编译我的代码，然后用我的代码测试

引用 3 楼 cfjtaishan 的回复:[quote=引用 2 楼 bcai_yuan 的回复:] [quote=引用 1 楼 cfjtaishan 的回复:] #include<stdio.h> #include<string.h>  #define MAXLINE 1000  //int getline(char *s,int lim);  char pattern[] = "ould";  int main(int argc,char *argv[]) {     int found = 0, i;      if (argc < 2) {         printf("Usage: find pattern\n");     } else {         for (i = 1; i < argc; i++) {             puts(argv[i]);             if(strstr(argv[i], pattern)) {                 printf("%s\n", argv[i]);                 found++;             }         }     }     printf("found = %d\n", found);     return found; } 需要分清终端输入和程序里getline输入的区别；终端输入的数据会保存在argv字符指针数组里，这些字符串是以空格为分割的。 getline是程序里要输入的。 之所以你输入command could you help me不能运行while里的getline，因为argc的值此时为5 != 2  这样的话我不就是检测我在终端输入的字符串里面是否含有pattern了吗？但是我运行的时候无论终端输入是否含有“ould”，都能运行出来，而且也不打印found的值，这是为什么？  如果我想引用getline函数又怎么引用呢？这样可以让程序更加灵活一点。[/quote] 你是用我的demo测试的吗？[/quote] 不是，我就直接在cmd里测试的。我不懂什么是demo测试

引用 2 楼 bcai_yuan 的回复:[quote=引用 1 楼 cfjtaishan 的回复:] #include<stdio.h> #include<string.h>  #define MAXLINE 1000  //int getline(char *s,int lim);  char pattern[] = "ould";  int main(int argc,char *argv[]) {     int found = 0, i;      if (argc < 2) {         printf("Usage: find pattern\n");     } else {         for (i = 1; i < argc; i++) {             puts(argv[i]);             if(strstr(argv[i], pattern)) {                 printf("%s\n", argv[i]);                 found++;             }         }     }     printf("found = %d\n", found);     return found; } 需要分清终端输入和程序里getline输入的区别；终端输入的数据会保存在argv字符指针数组里，这些字符串是以空格为分割的。 getline是程序里要输入的。 之所以你输入command could you help me不能运行while里的getline，因为argc的值此时为5 != 2  这样的话我不就是检测我在终端输入的字符串里面是否含有pattern了吗？但是我运行的时候无论终端输入是否含有“ould”，都能运行出来，而且也不打印found的值，这是为什么？  如果我想引用getline函数又怎么引用呢？这样可以让程序更加灵活一点。[/quote] 你是用我的demo测试的吗？

引用 1 楼 cfjtaishan 的回复:#include<stdio.h> #include<string.h>  #define MAXLINE 1000  //int getline(char *s,int lim);  char pattern[] = "ould";  int main(int argc,char *argv[]) {     int found = 0, i;      if (argc < 2) {         printf("Usage: find pattern\n");     } else {         for (i = 1; i < argc; i++) {             puts(argv[i]);             if(strstr(argv[i], pattern)) {                 printf("%s\n", argv[i]);                 found++;             }         }     }     printf("found = %d\n", found);     return found; } 需要分清终端输入和程序里getline输入的区别；终端输入的数据会保存在argv字符指针数组里，这些字符串是以空格为分割的。 getline是程序里要输入的。 之所以你输入command could you help me不能运行while里的getline，因为argc的值此时为5 != 2  这样的话我不就是检测我在终端输入的字符串里面是否含有pattern了吗？但是我运行的时候无论终端输入是否含有“ould”，都能运行出来，而且也不打印found的值，这是为什么？  如果我想引用getline函数又怎么引用呢？这样可以让程序更加灵活一点。


Question: Fibonacci数列

肯定是用动态规划呀，递归太耗时了。

x%100000%10007不等于x%10007。  比如x=100001，x%100000%10007=1，而x%10007=（懒得算了，反正不是1）

引用 楼主 lifeevents 的回复:问题描述 Fibonacci数列的递推公式为：Fn=Fn-1+Fn-2，其中F1=F2=1。  当n比较大时，Fn也非常大，现在我们想知道，Fn除以10007的余数是多少。  输入格式 输入包含一个整数n。 输出格式 输出一行，包含一个整数，表示Fn除以10007的余数。 说明：在本题中，答案是要求Fn除以10007的余数，因此我们只要能算出这个余数即可，而不需要先计算出Fn的准确值，再将计算的结果除以10007取余数，直接计算余数往往比先算出原数再取余简单。  样例输入 10 样例输出 55 样例输入 22 样例输出 7704 数据规模与约定 1 <= n <= 1,000,000。    #include <stdio.h> int f(int n); int main() { 	int c,a; 	scanf("%d",&a); 	 	c=f(a)%100000%10007; 	printf("%d",c); 	return 0; } int f(int n) { 	if(n==1 || n==2) return 1; 	else return (f(n-1)%100000+f(n-2)%100000); }  老是错误啊。。 什么错误，样例测试没有问题；但是输入较大的值会比较慢，建议使用循环代替递归，递归会非常消耗栈空间，导致由于反复申请函数栈导致运行慢。

这不是简单的代数题吗。。。。 假设n>2 f(n-2)=10007*a+x f(n-1)=10007*b+y f(n)=f(n-2)+f(n-1)=10007*(a+b)+(x+y) 可知f(n)除以10007的余数就是(x+y)%10007，而x、y正好分别是f(n-2)和f(n-1)除以10007的余数，所以代码就出来了。。。#include<iostream> using namespace std; int main() { 	int n; 	while (true) 	{ 		cin>>n; 		if (n<1||n>1000000) break;  		int fn; 		for (int i=3,f1=1,f2=1;i<=n;i++) 		{ 			fn=(f1+f2)%10007; 			f1=f2; 			f2=fn; 		} 		cout<<fn<<endl; 	}  	return 0; }

#include <stdio.h>   int func(int n) { 	if(n>2) 		return func(n-1)+func(n-2); 	else return 1; }  int main () { 	int n,ans; 	scanf("%d",&n); 	if(n<=0&&n>1000000) 		return 0; 	ans=func(n)%10007; 	printf("%d\n",ans); 	return 0; }


Question: C语言，如何将数据转成字符串啊？

sprintf

#include <stdio.h> #include <string.h>   int main(void) {     char buf[200];     char tmp[1024] = { 0 };     int i;      for (i = 0; i < 200; i++) {           buf[i] = i;     }      for (i = 0; i < 200; i++)         sprintf(tmp+strlen(tmp), "%d", buf[i]);     puts(tmp);     return 0; }


Question: c语言I/O操作，io和buf长度有关？

电脑内存或文件内容或传输内容只是一个一维二进制字节数组及其对应的二进制地址； 人脑才将电脑内存或文件内容或传输内容中的这个一维二进制字节数组及其对应的二进制地址的某些部分看成是整数、有符号数/无符号数、浮点数、复数、英文字母、阿拉伯数字、中文/韩文/法文……字符/字符串、汇编指令、函数、函数参数、堆、栈、数组、指针、数组指针、指针数组、数组的数组、指针的指针、二维数组、字符点阵、字符笔画的坐标、黑白二值图片、灰度图片、彩色图片、录音、视频、指纹信息、身份证信息……  推荐使用WinHex软件查看硬盘或文件或内存中的原始字节内容。  对电脑而言没有乱码，只有二进制字节；对人脑才有乱码。啊 GBK:0xB0 0xA1,Unicode-16 LE:0x4A 0x55,Unicode-16 BE:0x55 0x4A,UTF-8:0xE5 0x95 0x8A

兄弟们别沉啊，帮下我，好奇的潘多拉

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

user-2：什么意思哦！字符串本来就有\0哦

char buf[] ="123\0";

赵4老师：意思是txt文本不支持我这种编码格式吗？，刚我用notepad++打开确实是可以显示12了


Question: Visual C++ 6.0安装失败

win8及以上版本都装不上6.0的,建议装visual studio 2016

悲夫！计算机发展太快，计算机老师老书却阴魂不散

要分清c++语法  和编译器的区别，        语法是相同的，vc6.0只是一个编译器版本， 一些早该烧掉的书，只有学校还在用它们来误人子弟。  更高版本的编译器意味着更多的功能，更好的语法支持和优化，想学c++，建议直接上手c++11的语法，或者直接上手c++14语法，   学语法看  primer最新版，   学写代码看  代码大全

引用 12楼source03 的回复:微软的操作系统都升级好几代了，还是有很多人在用着这些十多年前的版本。 主要是目前很多书籍还是介绍VC6.0。对啊，书基本都是讲VC6.0，考试也是用VC6.0！

电脑是32位还是64位呢？

这个应该不是win10跟6.0不兼容的情况吧，不知道还要安装什么东西才行

win10不支持了，换成VS吧，貌似现在趋向64位，VC6不支持

这个软件应该是比较老了，几年之前就有，并且当时是在XP下安装的。Win10估计不支持了吧。 建议安装其他的，去网上搜一下C++编译器

win10装不了，换个绿色版的吧，msdv.exe换成英文的

直接上VS吧，现在都免费，很好用的。

引用 2 楼 qq_34417707的回复:引用 1楼weixin_36764539 的回复:电脑是32位还是64位呢？win10系统64位 Windows10别装VC6了。 你可以尝试VS  2008或者2010

请问大神这个是支持win10的包么

Visual C++ 2010 Express简体中文版http://pan.baidu.com/s/1bnwRVLt


Question: c语言写一个目录下移除指定文件夹的程序

如果按照赵四的说法，用 cmd 来删除，用标准 C 时间函数，就是这样：#include <stdio.h> #include <stdlib.h> #include <time.h>  int main (int argc, char *argv[]) { 	time_t rawtime = 0; 	struct tm *timeinfo = NULL; 	char buffer[1024] = { 0 };  	time (&rawtime); 	timeinfo = localtime (&rawtime); 	// 这里一次到位把命令包括路径格式化好直接执行 	strftime (buffer, sizeof(buffer), "cmd /c rd /s /q \"X:\\Path\\%Y%m%d\"", timeinfo); 	system(buffer);  	return 0; }如果全部自己实现，时间函数也采用 Windows 版本，那么我自己曾经写过递归删除目录的代码：#include <stdio.h> #include <stdlib.h> #include <windows.h> #include <shlwapi.h> #pragma comment(lib, "shlwapi.lib")  static BOOL IsDotOrDotDot(PCTSTR pszName) { 	if (*pszName++ == _T('.')) { 		switch (*pszName++) { 		case _T('\0'): 			return TRUE; 		case _T('.'): 			return !*pszName; 		} 	} 	return FALSE; }  static BOOL PASCAL InternalRemoveDirectoryRecursively(PCTSTR pszPath) { 	BOOL bResult = PathIsDirectory(pszPath); 	if (bResult) { 		TCHAR szWildcard[MAX_PATH] = { 0 }; 		if (PathCombine(szWildcard, pszPath, _T("*.*")) != NULL) { 			WIN32_FIND_DATA wfd = { 0 }; 			HANDLE hFind = FindFirstFile(szWildcard, &wfd); 			if (hFind != INVALID_HANDLE_VALUE) { 				TCHAR szFile[MAX_PATH] = { 0 }; 				do { 					if (!IsDotOrDotDot(wfd.cFileName)) { 						if (PathCombine(szFile, pszPath, wfd.cFileName) != NULL) { 							if (wfd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) { 								bResult = InternalRemoveDirectoryRecursively(szFile); 							} else { 								bResult = DeleteFile(szFile); 							} 						} 					} 				} while (FindNextFile(hFind, &wfd)); 				FindClose(hFind); 			} 		} 		if (bResult) { 			bResult = RemoveDirectory(pszPath); 		} 	} 	return bResult; }  BOOL PASCAL RemoveDirectoryRecursively(PCTSTR pszPath) { 	int nLength = lstrlen(pszPath); 	if ((nLength > 0) && (nLength < MAX_PATH)) { 		TCHAR szCanonical[MAX_PATH] = { 0 }; 		if (PathCanonicalize(szCanonical, pszPath)) { 			return InternalRemoveDirectoryRecursively(szCanonical); 		} 	} 	return FALSE; }  int main (int argc, char *argv[]) { 	SYSTEMTIME st = { 0 }; 	TCHAR szPath[MAX_PATH] = { 0 };  	GetLocalTime(&st); 	wsprintf(szPath, _T("X:\\Path\\%04u%02u%02u"), st.wYear, st.wMonth, st.wDay); 	BOOL bResult = RemoveDirectoryRecursively(szPath); 	printf("RemoveDirectoryRecursively: %d\n", bResult);  	return 0; }当然，我原本的实现比这个更复杂一些，还包括相对路径的判断、过滤路径中的无效字符、无法删除则标记为重启删除等等。主要是把核心的递归删除这部分提取出来了。

system("dir /b /a-d c:\\*.* >d:\\allfiles.txt"); //读文件d:\\allfiles.txt的内容即C:\\下所有文件的名字 system("dir /b /a-d /s c:\\*.* >d:\\allfilesinsub.txt"); //读文件d:\\allfilesinsub.txt的内容即C:\\下所有文件的名字包含子目录 system("dir /b /ad  c:\\*.* >d:\\alldirs.txt"); //读文件d:\\alldirs.txt的内容即C:\\下所有子目录的名字 请记住，能用shell命令获取文件、文件夹信息或者操作文件、文件夹最好用shell命令获取或者操作，而不要用各种API获取或者操作，因为当遇到非法文件夹名或非法文件名或非法文件长度、非法文件日期、压缩文件、链接文件、稀疏文件……等各种意料之外的情况时，API会处理的不全面或陷入死循环，而shell命令不会。 如果嫌system黑窗口一闪，将system("...")替换为WinExec("cmd /c ...",SW_HIDE);  C:\>rd /? 删除一个目录。  RMDIR [/S] [/Q] [drive:]path RD [/S] [/Q] [drive:]path      /S      除目录本身外，还将删除指定目录下的所有子目录和             文件。用于删除目录树。      /Q      安静模式，带 /S 删除目录树时不要求确认

是windows系统，我比较小白，可以简单给我讲下思路吗

这个要看系统的API， 比如说linux, windows, windows你可以看msdn

上帖第5行改为：sprintf(cmdstr,"cmd /c rd /s /q \“%s\”",adir);

引用 5 楼 qq_37350941 的回复:赵老师，想再请教您一下： 删除文件夹现在掌握了，目前的问题是： 如何实现输入一个文件夹的名称，然后将其删除 char adir[256]; char cmdstr[1024]; fgets(adir,256,stdin); if ('\n'==adir[strlen(adir)-1]) adir[strlen(adir)-1]=0; sprintf(cmdstr,"cmd /c rd /s /q \'%s\'",adir); WinExec(cmdstr,SW_HIDE);

赵老师说的对， 直接用WinExec执行系统命令


Question: 关于openmp的race condition

引用 2 楼 katorirea2017 的回复:[quote=引用 1 楼 zhao4zhong1 的回复:] 百度搜相关关键字。 可以说的更明白一点吗？我百度主要解决方法就是靠critical，但是要保护的变量太多了，都用crtical的吧跟单线程不是一样了吗？[/quote] 《Windows核心编程》 仅保护读时可能被其它线程写的局部数据。

引用 1 楼 zhao4zhong1 的回复:百度搜相关关键字。 可以说的更明白一点吗？我百度主要解决方法就是靠critical，但是要保护的变量太多了，都用crtical的吧跟单线程不是一样了吗？

百度搜相关关键字。


Question: 关于c语言和c++中的const问题

c++编译的时候默认把const修饰的变量转换为常量了

引用 2 楼 huamao1023 的回复:[quote=引用 1 楼 user-8的回复:]有点意思，我在Ubuntu上测了一下，首先  int *p = &a; 这句要做个强制转换，否则c编译出警告，c++编译报错。改成 int *p = (int*) &a;  用 gcc -S和g++ -S 选项生成汇编看，发现c编译器在处理a时按照普通变量处理，而c++编译器处理a时做了值替换，也就是:  printf("a=%d\n", a );这句话，c++编译器里面处理成 printf("a=%d\n", 10); 如果c编译器把变量a当成普通变量处理，那为什么如果在中间添加a=30；给a重新赋值，编译器又会报错?又把a当成常量了??[/quote] a就是普通变量，const是修饰a里的值，就是const是限制a里的值不能通过a去修改。所以，将30赋值给a，编译器会报错，因为a里的值不能通过a在次改变。但是*p是指针，const不能限制指针p，所以通过p可以去修改a里的值。

这个跟编译器有关，在      程序员的自我修养--编译、链接与库   那本书讲过

C里面的是假的，C++里面的是真的。

编译器帮你处理了，用到a的地方，通通改为10，与宏定义类似。 const只是编译期常量关键字。

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

修改常量，未定义行为

引用 1 楼 user-8的回复:有点意思，我在Ubuntu上测了一下，首先  int *p = &a; 这句要做个强制转换，否则c编译出警告，c++编译报错。改成 int *p = (int*) &a;  用 gcc -S和g++ -S 选项生成汇编看，发现c编译器在处理a时按照普通变量处理，而c++编译器处理a时做了值替换，也就是:  printf("a=%d\n", a );这句话，c++编译器里面处理成 printf("a=%d\n", 10); 如果c编译器把变量a当成普通变量处理，那为什么如果在中间添加a=30；给a重新赋值，编译器又会报错?又把a当成常量了??


Question: C语言malloc之后指针指向内存空间问题

直接在VC上新建个工程，单步调试查看，就知道结果了。

引用 2 楼 cfjtaishan 的回复:pstu++是偏移8个字节，如何来知道偏移了多少个字节呢？通过sizeof(student)，可以查看数据结构是占多少个字节。pstu是student类型的变量，pstu++的偏移长度就是sizeof(student).  这个稍微看一眼就知道sizeof(student) 是多少了

第一 这和字节对齐有关系，默认的4字节对齐的情况下，结构体中的成员按4的倍数占用存储空间，结构体大小按4字节补齐，因为结构体本身就只有4字节的2个成员，因此一个结构体完整大小是8字节（不填充任何字节，紧密存储）

已知：  typedef struct  {   int  score;   int  age; }student;  这里假设int是4个Byte的 student * pstu = malloc(sizeof(student)*100);  求P

sizeof *pstu 结果是8 pstu+1 就是 + 8 这个是指针算术的内容 和pstu存储的数据没有关系  哪怕你的pstu 里面存储的是 0  pstu+1 一样是 +8

引用student * pstu = malloc(sizeof(student)*100);  这时候P++，内存偏移的地址是否还是8？  P是什么？？  T类型的指针+1移动的距离是sizeof(T)  pstu + 1 就移动了一个结构体的大小

不要迷信书、考题、老师、回帖； 要迷信CPU、编译器、调试器、运行结果。 并请结合“盲人摸太阳”和“驾船出海时一定只带一个指南针。”加以理解。 任何理论、权威、传说、真理、标准、解释、想象、知识……都比不上摆在眼前的事实！


Question: 输入10个学生5门课的成绩

scanf读入有问题

scanf 错了，另外，函数直接传二维数组，有些牵强啊

请那些喜欢将数组作为函数参数传来传去或作为函数返回值的码农思考一下为什么不把整个互联网内容当作函数参数传来传去或作为函数返回值呢？

函数声明建议放在函数外，同时注意coding style.

#include<stdio.h>  void std_average(float (*array)[5], float *pstu_ave); void sub_average(float (*array)[5], float *psub_ave);  int main() {      float a[10][5], student_ave[10], subject_ave[5];     int i,j;      printf("Input scores:\n");     for(i = 0; i < 10; i++) {         printf("student %d:\n", i + 1);         for(j = 0; j < 5; j++)             scanf("%f", &a[i][j]);         printf("\n");     }       printf("student average score is:\n");     std_average(a, student_ave);     for(i = 0; i < 10; i++) {         printf("5.2%f", student_ave[i]);         if(i == 5)             printf("\n");     }      printf("subject average score is:\n");     sub_average(a, subject_ave);     for(i = 0; i < 5; i++)         printf("5.2%f",subject_ave[i]);       return 0; }   void std_average(float array[10][5], float *pstu_ave) {     int i, j;      for(i = 0; i < 10; i++) {         for(j = 0; j < 5; j++)             pstu_ave[i] = array[i][j];         pstu_ave[i] = pstu_ave[i] / 5;     } }  void sub_average(float array[10][5], float *psub_ave) {     int i,j;      for(i = 0; i < 5; i++)     {         for(j = 0; j < 10; j++)             psub_ave[i] = array[j][i];         psub_ave[i] = psub_ave[i] / 5;     } } 两个问题： 1. scanf输入时，需要加&;  2. 求学生平均成绩和科目平均成绩直接平均成绩的数组传进处理函数，这样节省函数栈空间，同时还能提高程序效率。


Question: ACM谜题问题

引用 1楼自信男孩 的回复:应该是输入的时候不能输入空格，但是空格有ASCII对应的值，这个值是32； 建议输入空格的地方输入一个特殊字符（比如-1）然后再数组进行重新赋值，遇到特殊字符（-1）赋值32即可。十分感谢！

引用 1 楼 cfjtaishan 的回复:应该是输入的时候不能输入空格，但是空格有ASCII对应的值，这个值是32； 建议输入空格的地方输入一个特殊字符（比如-1）然后再数组进行重新赋值，遇到特殊字符（-1）赋值32即可。 程序可以运行了，十分感谢，问下，除了这种赋值的方式外，有直接输入空格的操作方法吗？


Question: 提问如何解此题:将一组任意长度的数组从大到小排列输出

引用 3楼自信男孩 的回复:直接写一个不定长度的冒泡排序算法即可，数据长度可以通过参数传递进去。比如： void bubble_sort(int *arr, int len) {     int i,j;     int tmp;      for(i = 0; i < len - 1; i++)         for(j = 0; j < len - 1 - i; j++)             if (arr[j] > arr[j + 1]) {                 tmp = arr[j];                 arr[j] = arr[j + 1];                 arr[j + 1] = tmp;             } } 数组长度len是需要传递到bubble_sort函数里。想明白了谢大神⁄(⁄ ⁄ ⁄ω⁄ ⁄ ⁄)⁄

排序做为最基本的算法题，网上一搜一大把。 所谓任意长度，对于C语言，事先都是要先知道的，传参就行了。

在c中，数组在定义的时候就必须要知道长度了，因为在编译阶段就要分配存储单元，你这种可以采用宏定义来做，每次只需要改最初的宏定义的数值就可以了。


Question: static的用法还不太懂，大家帮忙看看

你可以简单认为static int n   n就是一个全局变量 （这样认为肯定错误） void aaa() { ....static int n = 0; ....n++; } 你可以认为是 int n = 0; void aaa() { ....n++;  } 并且n只能在aaa()里面才能使用。

引用 8 楼 m0_37481440 的回复:我想 应该是函数执行时它的参数只是值的 拷贝,get(int n=0)那个函数里第一次的n 和第二次的n是两个n了,然后第二次的n为2返回给第一次2,但第一次的n还是1返回给外层1.  然后static 修饰的局部变量是导致这个变量就存在于程序运行的整个阶段了不会被第二次static 修饰赋值,并且维持它上一次改变的值,它不会被拷贝,也不像普通的局部变量会在用完后即空间被释放. static修饰过后会被放在静态区(程序运行存在),普通的局部变量放在的是栈区(用完就释放空间). 可能你需要熟悉一下 哪些数据 存在于 哪些地方.比如堆和栈还有静态区等等. 太感谢了！完美解决问题

请忽略我上面的答案。

static 标注的语句，只执行一次，后面n变量在整个程序中永久存在，只是它的作用域在get函数内，而不在整个程序中，说明白一些只是个永久的局部变量，不管get函数调用多少次，都只执行一次，也就是说哪怕函数结束了，n的值也不会丢失。

引用 2 楼 qq_36009365 的回复:进去调用get(1)，之后n变成2，返回2给get(1)，然后返回1给main，所以最后主函数中显示的是1。上面的打错字。。 谢谢，我知道n是如何变化的，我想知道的是n为什么会那样变化。有static关键字的，只返回最后一个结果，没static关键字的就相当于 int get(int n=0) {     n++; //    if(n<2) get(n);     return n; }

引用 2 楼 qq_36009365 的回复:进去调用get(1)，之后n变成2，返回2给get(1)，然后返回1给main，所以最后主函数中显示的是1。上面的打错字。。  谢谢，我知道n是如何变化的，我想知道的是n为什么会那样变化。有static关键字的，只返回最后一个结果，没static关键字的就相当于int get(int n=0) {     n++; //    if(n<2) get(n);     return n; }

你可以在if后面加一句输出。跟踪一下n的值是如何变化的。

老司机说一句，static一般只在涉及到线程的类里，或者做单例模式的时候用，其它时候static就是个摆设

进去调用get(1)，之后n变成2，返回2给get(1)，然后返回1给main，所以最后主函数中显示的是2