Question: char s[] = "abcdef";"abcdef"是在栈区还是堆区？

C版的那只老鼠呢？他解释的最好！  C. FAQ 1.32 http://c-faq.com/decl/strlitinit.html  C.FAQ 6.2 http://c-faq.com/aryptr/aryptr2.html

引用 18 楼 lm_whales 的回复:[quote=引用 17 楼 u012942555 的回复:] [quote=引用 11 楼 lm_whales 的回复:] 第3）种情况，没有什么简单有效的手段，可以找到 “abcdef”存储在哪里。         初始化之前，数据不在a[] 内，初始化完成后， “abcdef”在a[] 内 所以，即便你认为 “abcdef” 在数组 a[]内部，其实也不算错。  我理解的这句话的意思是，在初始化之前“abcdef”在常量区，初始化之后在a[]内部？不知道是不是这样 这样的话岂不是两份“abcdef”了，实在是Yun[/quote] 就是这么做的， 因为局部非静态变量，在函数运行的过程中初始化。 这样，编译器无法预先把数据，存放到 a[] 中。 于是，只好先存起来，然后再用。 a[]中这份，你可以随便处理， 预存的那份，你根本摸不清它在哪里， 所以根本不能处理它，不能读，不能写。 如果你可以读写了，那么编译器就不能保证初始化，是正确的了。 [/quote] 另外， 像 int a[20] =｛0｝ ，//C,C++   int a[20]｛｝, //C++11 等 int a [20]={}   //C++11，等 这种，可以直接生成填充代码， 也可以用一批全零数据，预先存下来，再复制过去。  关于堆对象  C malloc 函数分配的数据，不能初始化  C++11 标准之前： C++ 运算符 new 只能初始化 类对象，内置类型，new[]不能初始化数组.  C++11算符 new 可以初始化类对象，内置类型, new[] 数组也可以初始化 C++11 new[] 初始化如下  T *p= new T[100] {1,2,3,4,5,6,}; //用 初始化列表初始化数组， T *q; q =new T[100]{1,2,3,4,5,6} //用 初始化列表初始化数组，

引用 10 楼 lm_whales 的回复:这个是有这么几种情况的：    char s[] = "abcdef"; //1） s在静态区，"abcdef"无需额外存放，就是数组s内部，总共占用一个串的内存 const char *p ="abcdef";//2）p在静态区,"abcdef",必须额外存放（在常量区，通常也在静态区）                                     //总共占用一个指针，和一个串的内存 int main(){ char a[]= "abcdef" ; //3）a在栈区,"abcdef" 必须额外存放（在常量区，通常也在静态区）,这个初始化，一般就是复制数据。                              //编译器，一般不会把串中的字符，编译成立即数，一个一个装填 a[i]; printf("s=%s\np=%s\na=%s\n",s,p,a); return 0; } s,p,a "abcdef" 各在什么位置： 第1）种情况，不需要再寻找了，二者占用同一个位置s，"abcdef"是一家，不必骑驴找驴。 第2）种情况，你可以简单的通过代码，找到 “abcdef”，存储的位置。也就是指针的值。 第3）种情况，没有什么简单有效的手段，可以找到 “abcdef”存储在哪里。 数组和指针不同的是 指针只是一个表示地址的数据，它的类型指的是，那个地址中存放的数据的类型。 数组，是一批同一类型数据组合。它就是这一批数据。 数组，可以用 数据存储位置（指针）和数据量（元素个数）两个特征来表征。    楼主，好好看下这楼的解释，这是正解，理解最深刻的一位。

引用 17 楼 u012942555 的回复:[quote=引用 11 楼 lm_whales 的回复:] 第3）种情况，没有什么简单有效的手段，可以找到 “abcdef”存储在哪里。         初始化之前，数据不在a[] 内，初始化完成后， “abcdef”在a[] 内 所以，即便你认为 “abcdef” 在数组 a[]内部，其实也不算错。  我理解的这句话的意思是，在初始化之前“abcdef”在常量区，初始化之后在a[]内部？不知道是不是这样 这样的话岂不是两份“abcdef”了，实在是Yun[/quote] 就是这么做的， 因为局部非静态变量，在函数运行的过程中初始化。 这样，编译器无法预先把数据，存放到 a[] 中。 于是，只好先存起来，然后再用。 a[]中这份，你可以随便处理， 预存的那份，你根本摸不清它在哪里， 所以根本不能处理它，不能读，不能写。 如果你可以读写了，那么编译器就不能保证初始化，是正确的了。

引用 11 楼 lm_whales 的回复:第3）种情况，没有什么简单有效的手段，可以找到 “abcdef”存储在哪里。         初始化之前，数据不在a[] 内，初始化完成后， “abcdef”在a[] 内 所以，即便你认为 “abcdef” 在数组 a[]内部，其实也不算错。  我理解的这句话的意思是，在初始化之前“abcdef”在常量区，初始化之后在a[]内部？不知道是不是这样 这样的话岂不是两份“abcdef”了，实在是Yun

这是字符数组，是在栈上（不是楼上所说的常量区），只有用动态分配的才是在堆上

你们的回答让我彻底找不到北了   findfun能不能详细点

都是在常量区，只不过在栈区有映射。

理解 char s[ ] = "abc"; 与 char *s = "abc"; 的区别。

引用 4 楼 u012942555 的回复:char *s="abcdef";//"abcdef"是在常量区 char s[]="abcdef";//"abcdef"应该不在常量区，但我不知道在哪里 char s[]="abcdef";//"abcdef"应该在堆区.

引用 2 楼 u012942555 的回复:char *s="abcdef";//"abcdef"是在常量区  这个不是  楼主，你想说什么？

char *s="abcdef";//"abcdef"是在常量区  这个不是

"abcdef"在常量区

引用 13 楼 u012942555 的回复:[quote=引用 11 楼 lm_whales 的回复:] 第3）种情况，没有什么简单有效的手段，可以找到 “abcdef”存储在哪里。         初始化之前，数据不在a[] 内，初始化完成后， “abcdef”在a[] 内 所以，即便你认为 “abcdef” 在数组 a[]内部，其实也不算错。  第3中情况  如果在常量区，常量区的内容可以修改吗，第三种的情况内容可以被修改a[2]='w';，如果在常量区，内容应该是不能修改的啊[/quote] 第3）种情况这个常量区，你根本就不能修改，你找不到它的位置，你的程序不认识它，它是匿名的。 你只能修改，已经被初始化为 “abcdef”的数组 a[] 的元素。

引用 14 楼 u012942555 的回复:[quote=引用 12 楼 user-8 的回复:] 1) char *s = "abcd".  s 是一个字符指针，指向“abcd”字符串，也就是存放该字符的地址。 “abcd”实际存放在该进程地址空间的全局数据区，或者叫常量区。证明： #include<stdio.h>  char *s1 = "abcd";   void func() { 	char *s2 = "abcd"; 	printf("address of s2: %x\n", s2); }  int main(void) { 	char *s3 = "abcd"; 	printf("address of s1: %x\n", s1); 	func(); 	printf("address of s3: %x\n", s3); 	return 0; }  以上程序的s1, s2, s3定义在不同地方，但他们的值相等。  2)  char s[] = "abcd". "abcd"在s所在的栈区。 证明： #include<stdio.h>  char s1[] = "abcd";   void func() { 	char s2[] = "abcd"; 	printf("address of s2: %x\n", s2); }  int main(void) { 	char s3[] = "abcd"; 	printf("address of s1: %x\n", s1); 	func(); 	printf("address of s3: %x\n", s3); 	return 0; }  显示三个地址不一样。 只有当用new，或者malloc，比如 char *s = new char[5].  分配的空间才在堆区。   我认为是s2,s3在栈区，s1在常量区[/quote]  你说的对，我忘了还有个全局指针。

引用 12 楼 user-8 的回复:1) char *s = "abcd".  s 是一个字符指针，指向“abcd”字符串，也就是存放该字符的地址。 “abcd”实际存放在该进程地址空间的全局数据区，或者叫常量区。证明： #include<stdio.h>  char *s1 = "abcd";   void func() { 	char *s2 = "abcd"; 	printf("address of s2: %x\n", s2); }  int main(void) { 	char *s3 = "abcd"; 	printf("address of s1: %x\n", s1); 	func(); 	printf("address of s3: %x\n", s3); 	return 0; }  以上程序的s1, s2, s3定义在不同地方，但他们的值相等。  2)  char s[] = "abcd". "abcd"在s所在的栈区。 证明： #include<stdio.h>  char s1[] = "abcd";   void func() { 	char s2[] = "abcd"; 	printf("address of s2: %x\n", s2); }  int main(void) { 	char s3[] = "abcd"; 	printf("address of s1: %x\n", s1); 	func(); 	printf("address of s3: %x\n", s3); 	return 0; }  显示三个地址不一样。 只有当用new，或者malloc，比如 char *s = new char[5].  分配的空间才在堆区。   我认为是s2,s3在栈区，s1在常量区

引用 11 楼 lm_whales 的回复:第3）种情况，没有什么简单有效的手段，可以找到 “abcdef”存储在哪里。         初始化之前，数据不在a[] 内，初始化完成后， “abcdef”在a[] 内 所以，即便你认为 “abcdef” 在数组 a[]内部，其实也不算错。  第3中情况  如果在常量区，常量区的内容可以修改吗，第三种的情况内容可以被修改a[2]='w';，如果在常量区，内容应该是不能修改的啊


Question: 程序运行出错，求大神帮助

引用 楼主 csdn_mr_l 的回复: 文件及头函数并无语法错误，可还是运行出错 下面是程序#include<stdio.h> #include<stdlib.h> #include<time.h> #include"linear.h"  #define M 20 //A数组元素个数 #define N 20 //B数组元素个数 main()     {             sqlist listA,listB;             elemtype *pA,*pB;             pA=listA.elem;             pB=listB.elem;             Linear_initlist(listA);             Linear_initlist(listB);//创建线性表AB             srand((unsigned)time(NULL));             while(pA<=listA.elem+M-1)             {                     *pA=rand()%RAND_MAX;                     pA++;                     listA.length++;             }             while(pB<=listB.elem+M-1)             {                     *pB=rand()%RAND_MAX;                     pB++;                     listB.length++;             }             pA=listA.elem;             pB=listB.elem;             printf("A数组中的元素是：\n");             while(pA<=listA.elem+listA.length-1)             {                     printf("%d\t",*pA++);             }             printf("\n");             printf("B数组中的元素是：\n");             while(pB<=listB.elem+listB.length-1)             {                     printf("%d\t",*pB++);             }             printf("\n");//对AB表赋值并输出     } 下面是头函数/此头函数用于存放对线性表操作的函数 #ifndef LINEAR_H_INCLUDED #define LINEAR_H_INCLUDED #define LIST_INIT_SIZE 20//初始线性表总结点个数 #define LISTINCERMENT  10 //新增节点个数 typedef int elemtype; typedef struct //用于指向线性表地址，并保存线性表的长度与空间大小     {             elemtype *elem;    //用于存放线性表首地址             int length;        //用于存放线性表中的数据个数             int listsize;      //用于存放线性表的总单元个数     }sqlist;  void Linear_initlist(sqlist L);void Linear_initlist(sqlist L) //此函数用于创建空的线性表     {             L.elem=(elemtype*)malloc(LIST_INIT_SIZE*sizeof(elemtype));             if(!L.elem)                 exit(-1);             L.length=0;             L.listsize=LIST_INIT_SIZE;     }//Linear_initlist 运行后就出现“程序无响应”的问题了 修改后的参考代码(希望对你有帮助): #include<stdio.h> #include<stdlib.h> #include<time.h> #ifndef LINEAR_H_INCLUDED #define LINEAR_H_INCLUDED #define LIST_INIT_SIZE 20//初始线性表总结点个数 #define LISTINCERMENT  10 //新增节点个数 typedef int elemtype; typedef struct				//用于指向线性表地址，并保存线性表的长度与空间大小     {             elemtype elem[20];    //用于存放线性表首地址             int length;        //用于存放线性表中的数据个数             int listsize;      //用于存放线性表的总单元个数     }sqlist; #endif  #define M 20 //A数组元素个数 #define N 20 //B数组元素个数 main()     {             sqlist *listA,*listB;             elemtype *pA,*pB; 			listA=(sqlist *)malloc(sizeof(sqlist));             if(!listA)                 exit(-1);             listA->length=0;             listA->listsize=LIST_INIT_SIZE; 			listB=(sqlist *)malloc(sizeof(sqlist));             if(!listB)                 exit(-1);             listB->length=0;             listB->listsize=LIST_INIT_SIZE; 			pA=listA->elem;             pB=listB->elem; 			srand((unsigned)time(NULL));             while(pA<=listA->elem+M-1)             {                     *pA=rand()%RAND_MAX;                     pA++;                     listA->length++;             }             while(pB<=listB->elem+N-1)             {                     *pB=rand()%RAND_MAX;                     pB++;                     listB->length++;             }             pA=listA->elem;             pB=listB->elem;             printf("A数组中的元素是：\n");             while(pA<=listA->elem+listA->length-1)             {                     printf("%d\t",*pA++);             }             printf("\n");             printf("B数组中的元素是：\n");             while(pB<=listB->elem+listB->length-1)             {                     printf("%d\t",*pB++);             }             printf("\n");//对AB表赋值并输出     }

因为你Linear_initlist函数是传值，函数对L初始化，对外是无效的，主函数的listA,listB都没有初始化，为空值，所以pA，pB也是0，取值时崩溃。

楼主你可插下断点，自己调试下，看看程序在哪崩溃的，然后再分析下崩溃时，各变量的值情况，一般是指针越界，或者未初始化访问，或者为NULL还继续访问


Question: 用vs学习c，出错“lnk 1120两个无法解析的外部命令，还有两个错误”今天刚装，望指教

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

mian->main

函数名写错了…

有可能是缺少库文件

把mian改为main  sacanf改为scanf

main scanf 请仔细检查

int main()  不是mian()……

跟着教材打的代码，应该没错吧


Question: 求大神来帮忙  最后一步一直运行不了

#include<stdio.h> #include<string.h> #define N 5 int main() { 	int num[N]; 	char name[N][10]; 	char str[10]; 	int i,j,temp,top,mid,g,n,end; 	for(i=0;i<N;i++)             // 输入员工号跟姓名 	{ 		printf("Please input number : "); 		scanf("%d",&num[i]); 		printf("Please input name : "); 		scanf("%s",&name[i]); 	} 	for(i=0;i<N;i++) 	{ 		printf("%d %s\n",num[i],name[i]); 	} 	for(i=0;i<N-1;i++)             //开始排序 	{ 		for(j=0;j<N-1;j++) 		{ 			if(num[j]>num[j+1]) 			{ 				temp=num[j]; 				num[j]=num[j+1]; 				num[j+1]=temp; 				strcpy(str,name[j]); 				strcpy(name[j],name[j+1]); 				strcpy(name[j+1],str); 			} 		} 	} 	printf("This is new rank :");          //排序的结果 	for(i=0;i<N;i++) 	{ 		printf("%d   %s\n",num[i],name[i]); 	} 	printf("Please input you wanna seach number : ");         //准备查找 	scanf("%d",&n); 	top=0; 	end=N-1; 	g=0; 	while(g==0) 	{ 		mid=(top+end)/2; 		if(n == num[mid]) 		{ 			printf("This is your seach result: %d %s\n",num[mid],name[mid]); 			g=1; 		} 		else if(n < num[mid]) 		{ 			end=mid-1; 		} 		else if(n>num[mid]) 		{ 			top=mid+1; 		} 	} 	if(g==0)	 		printf("cannot find !\n"); 	return 0; }  建议楼主贴代码时点下图按钮编辑下，这样方便读代码：

引用 4 楼 qq_31757983 的回复:[quote=引用 2 楼 user-2 的回复:] while(g==0);  多打了一个分号，导致在while死循环。 大哥  这个while 循环如果把所有结果寻找一遍 还没有会不会自己跳出去  显示查找不到？[/quote]  while循环体的内容没有执行，一直在检查g==0. 多打一个分号相当于如下效果：  while(g == 0) {}    // 循环体内容为空

引用 2 楼 user-2 的回复:while(g==0);  多打了一个分号，导致在while死循环。 大哥  这个while 循环如果把所有结果寻找一遍 还没有会不会自己跳出去  显示查找不到？

引用 2 楼 user-2 的回复:while(g==0);  多打了一个分号，导致在while死循环。 我试试

while(g==0);  多打了一个分号，导致在while死循环。

这是运行的结果


Question: VS 2013 关于scanf_s 的问题

你在scanf_s("%lf,%lf,%lf",...);时，输入参数的时候也要把逗号加上的 。

Collapse AllExpand All      Code: All Code: Multiple Code: Visual Basic Code: C# Code: Visual C++ Code: J# Code: JScript   Visual Basic C# Visual C++ J# JScript Run-Time Library Reference  Format Specification Fields: scanf and wscanf Functions  See Also  Send Feedback     The information here applies to the entire scanf family of functions, including the secure versions and describes the symbols used to tell the scanf functions how to parse the input stream, such as the input stream stdin for scanf, into values that are inserted into program variables.  A format specification has the following form:  % [width] [{h | l | ll | I64 | L}]type  The format argument specifies the interpretation of the input and can contain one or more of the following:   White-space characters: blank (' '); tab ('\t'); or newline ('\n'). A white-space character causes scanf to read, but not store, all consecutive white-space characters in the input up to the next non–white-space character. One white-space character in the format matches any number (including 0) and combination of white-space characters in the input.  Non–white-space characters, except for the percent sign (%). A non–white-space character causes scanf to read, but not store, a matching non–white-space character. If the next character in the input stream does not match, scanf terminates.  Format specifications, introduced by the percent sign (%). A format specification causes scanf to read and convert characters in the input into values of a specified type. The value is assigned to an argument in the argument list.  The format is read from left to right. Characters outside format specifications are expected to match the sequence of characters in the input stream; the matching characters in the input stream are scanned but not stored. If a character in the input stream conflicts with the format specification, scanf terminates, and the character is left in the input stream as if it had not been read.  When the first format specification is encountered, the value of the first input field is converted according to this specification and stored in the location that is specified by the first argument. The second format specification causes the second input field to be converted and stored in the second argument, and so on through the end of the format string.  An input field is defined as all characters up to the first white-space character (space, tab, or newline), or up to the first character that cannot be converted according to the format specification, or until the field width (if specified) is reached. If there are too many arguments for the given specifications, the extra arguments are evaluated but ignored. The results are unpredictable if there are not enough arguments for the format specification.  Each field of the format specification is a single character or a number signifying a particular format option. The type character, which appears after the last optional format field, determines whether the input field is interpreted as a character, a string, or a number.   The simplest format specification contains only the percent sign and a type character (for example, %s). If a percent sign (%) is followed by a character that has no meaning as a format-control character, that character and the following characters (up to the next percent sign) are treated as an ordinary sequence of characters, that is, a sequence of characters that must match the input. For example, to specify that a percent-sign character is to be input, use %%.  An asterisk (*) following the percent sign suppresses assignment of the next input field, which is interpreted as a field of the specified type. The field is scanned but not stored.  The secure versions (those with the _s suffix) of the scanf family of functions require that a buffer size parameter be passed immediately following each parameter of type c, C, s, S or [. For more information on the secure versions of the scanf family of functions, see scanf_s, _scanf_s_l, wscanf_s, _wscanf_s_l.  See Also Concepts scanf Width Specification scanf Type Field Characters scanf, _scanf_l, wscanf, _wscanf_l scanf_s, _scanf_s_l, wscanf_s, _wscanf_s_l Send feedback on this topic to Microsoft.

你输入时加了逗号没？而且逗号要紧紧跟在数字的后面，如： 1.1,           2.2, 3.3

只有cs需要指定大小, d,f不需要的,问题是什么?

比如:char d[20];写成scanf_s("%s",d,20);才是正确的

引用 1 楼 zxhuser-6 的回复:http://baike.baidu.com/link?url=B3XgHngm0C0j5jZmFcbszWiAtkisTGsdKjDlGOrEYXSPqT6wTwylvY-qYVAQcEPq-a7gL44Odxj-BiYv__4xIa 求正确代码

能不能给个正确的改写代码，你发的链接我也看了，不是很懂欸


Question: 疑惑CreateFile参数设置为FILE_SHARE_READ，其他程序还是不能读？

记事本再打开文件时会试图请求所有权限，如果不能读取就会提示被占用。如果能读不能写则修改才会提示被占用。如果有别的程序占用了一部分权限，那么记事本将会请求剩下的所有权限。但是别忘了，记事本打开文件时请求了所有权限但仅仅使用了读取权限一项，而如果请求到了写入权也仅会在修改时使用，也就是说请求到的权限不会都使用。所以你要实现这个读写就要再单独写一个以只读打开文件的程序来读文件。 但是记住，如果记事本不能读取文件，哪怕写入权限开放也不能写入，但是自己的程序是可以的。 希望我能帮到你。

你好，请问你的这个问题解决了吗？

引用 13 楼 bluewanderer 的回复:[quote=引用 8 楼 wqte45 的回复:] [quote=引用 6 楼 bluewanderer 的回复:] 首先，题外话写文件开share_read本来就是作死。 然后，Notepad根本不支持只读打开。 最后，搞清楚share_read是允许别的程序用读模式打开文件，这个时候如果别的程序请求读以外的权限就会失败，而不是只要请求了读权限就能成功。  首先，您在回帖之前一定没做测试吧，另外我不得不说  你没看明白我问的问题，其次记事本是可以打开已创建share_read属性文本文件的，CreateFile("gp.txt",GENERIC_WRITE,FILE_SHARE_READ,NULL,CREATE_ALWAYS,FILE_ATTRIBUTE_NORMAL,NULL);  比如这句 是用FILE_ATTRIBUTE_NORMAL正常属性创建的文件，即使后面还有代码运行 以及文件句柄还没关闭，此时就可以 用记事本打开刚创建的gp.txt。我的问题是 为什么 我用FILE_FLAG_DELETE_ON_CLOSE属性创建文件，FILE_SHARE_READ标记就不起作用了。。。。。FILE_FLAG_DELETE_ON_CLOSE属性的意思是 创建一个文件 关闭句柄时会被自动删除，  #include <windows.h> #include <stdio.h> int main() { 	DWORD dwBytes; 	char data[] = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"; 	HANDLE hFile = CreateFile("temp.txt",GENERIC_WRITE,FILE_SHARE_READ,NULL,CREATE_ALWAYS,FILE_ATTRIBUTE_NORMAL,NULL); 	WriteFile(hFile,data,sizeof(data)-1,&dwBytes,NULL);     WinExec("notepad temp.txt",SW_SHOW);  //此时就能打开，楼上的说GENERIC_WRITE写文件同时FILE_SHARE_READ共享，不能用。扯淡 	getchar();  	CloseHandle(hFile);          	return 0; }  下面我用FILE_FLAG_DELETE_ON_CLOSE属性替换FILE_ATTRIBUTE_NORMAL属性  #include <windows.h> #include <stdio.h> int main() { 	DWORD dwBytes; 	char data[] = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"; 	HANDLE hFile = CreateFile("temp.txt",GENERIC_WRITE,FILE_SHARE_READ,NULL,CREATE_ALWAYS,FILE_FLAG_DELETE_ON_CLOSE,NULL); 	WriteFile(hFile,data,sizeof(data)-1,&dwBytes,NULL);     WinExec("notepad temp.txt",SW_SHOW);  //此时就不能打开 提示被占用  同样都是,FILE_SHARE_READ,。 	getchar();  	CloseHandle(hFile);         	return 0; }  所以我质疑使用 FILE_FLAG_DELETE_ON_CLOSE 属性 ，FILE_SHARE_READ会不起作用，但我不确定，就上来请教大家。FILE_FLAG_DELETE_ON_CLOSE属性不懂自己查，当用此属性创建文件时候，关闭句柄后 会自动删除所创建的文件，做临时文件最适合。但我需要在被创建后  被第三方程序调用读取加载，正常属性都可以，除了这个 FILE_FLAG_DELETE_ON_CLOSE，所有就出现了此贴。 如果真不行  我只能用普通属性创建 ，最后用deletefile来删除了。  以上就是我的第一个问题。我就不明白了  我用CreateFile("temp.txt",GENERIC_WRITE,FILE_SHARE_READ,NULL,CREATE_ALWAYS,FILE_ATTRIBUTE_NORMAL,NULL);  怎么就作死了  我按照msdn来写文件  到你这里就作死了。我这样写也没提示错误 啊[/quote]  没仔细看，发现Notepad进化了=-=... 不过既然你看文档了就应该知道还有个share_delete吧。[/quote]  share_delete  对我没什么用。我就想用FILE_FLAG_DELETE_ON_CLOSE，既然用此属性的时候  不能共享给其他程序读，那我就在关闭句柄后  DeleteFile就好了，用不着share_delete。我又不着急是否在关闭句柄前删除。

引用 8 楼 wqte45 的回复:[quote=引用 6 楼 bluewanderer 的回复:] 首先，题外话写文件开share_read本来就是作死。 然后，Notepad根本不支持只读打开。 最后，搞清楚share_read是允许别的程序用读模式打开文件，这个时候如果别的程序请求读以外的权限就会失败，而不是只要请求了读权限就能成功。  首先，您在回帖之前一定没做测试吧，另外我不得不说  你没看明白我问的问题，其次记事本是可以打开已创建share_read属性文本文件的，CreateFile("gp.txt",GENERIC_WRITE,FILE_SHARE_READ,NULL,CREATE_ALWAYS,FILE_ATTRIBUTE_NORMAL,NULL);  比如这句 是用FILE_ATTRIBUTE_NORMAL正常属性创建的文件，即使后面还有代码运行 以及文件句柄还没关闭，此时就可以 用记事本打开刚创建的gp.txt。我的问题是 为什么 我用FILE_FLAG_DELETE_ON_CLOSE属性创建文件，FILE_SHARE_READ标记就不起作用了。。。。。FILE_FLAG_DELETE_ON_CLOSE属性的意思是 创建一个文件 关闭句柄时会被自动删除，  #include <windows.h> #include <stdio.h> int main() { 	DWORD dwBytes; 	char data[] = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"; 	HANDLE hFile = CreateFile("temp.txt",GENERIC_WRITE,FILE_SHARE_READ,NULL,CREATE_ALWAYS,FILE_ATTRIBUTE_NORMAL,NULL); 	WriteFile(hFile,data,sizeof(data)-1,&dwBytes,NULL);     WinExec("notepad temp.txt",SW_SHOW);  //此时就能打开，楼上的说GENERIC_WRITE写文件同时FILE_SHARE_READ共享，不能用。扯淡 	getchar();  	CloseHandle(hFile);          	return 0; }  下面我用FILE_FLAG_DELETE_ON_CLOSE属性替换FILE_ATTRIBUTE_NORMAL属性  #include <windows.h> #include <stdio.h> int main() { 	DWORD dwBytes; 	char data[] = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"; 	HANDLE hFile = CreateFile("temp.txt",GENERIC_WRITE,FILE_SHARE_READ,NULL,CREATE_ALWAYS,FILE_FLAG_DELETE_ON_CLOSE,NULL); 	WriteFile(hFile,data,sizeof(data)-1,&dwBytes,NULL);     WinExec("notepad temp.txt",SW_SHOW);  //此时就不能打开 提示被占用  同样都是,FILE_SHARE_READ,。 	getchar();  	CloseHandle(hFile);         	return 0; }  所以我质疑使用 FILE_FLAG_DELETE_ON_CLOSE 属性 ，FILE_SHARE_READ会不起作用，但我不确定，就上来请教大家。FILE_FLAG_DELETE_ON_CLOSE属性不懂自己查，当用此属性创建文件时候，关闭句柄后 会自动删除所创建的文件，做临时文件最适合。但我需要在被创建后  被第三方程序调用读取加载，正常属性都可以，除了这个 FILE_FLAG_DELETE_ON_CLOSE，所有就出现了此贴。 如果真不行  我只能用普通属性创建 ，最后用deletefile来删除了。  以上就是我的第一个问题。我就不明白了  我用CreateFile("temp.txt",GENERIC_WRITE,FILE_SHARE_READ,NULL,CREATE_ALWAYS,FILE_ATTRIBUTE_NORMAL,NULL);  怎么就作死了  我按照msdn来写文件  到你这里就作死了。我这样写也没提示错误 啊[/quote]  没仔细看，发现Notepad进化了=-=... 不过既然你看文档了就应该知道还有个share_delete吧。

引用 9 楼 wqte45 的回复:[quote=引用 7 楼 bluewanderer 的回复:] 准确地说是你这操作一边写还一边开share_read属于作死，还是有其他情况需要一边写另一边读的...  您不会看代码吗？   操作一边写还一边开share_read  不行吗？怎么就作死了？     别说是我写数据到文件是在完成后 ，才用第三方程序调用的，就算我多线程 一边写入数据，令一线程同时来读取内容 又怎么了？ msdn上哪说GENERIC_WRITE创建文件时，不能用FILE_SHARE_READ老共享，难道一直用0 来独占吗？[/quote]  引用 9 楼 wqte45 的回复:[quote=引用 7 楼 bluewanderer 的回复:] 准确地说是你这操作一边写还一边开share_read属于作死，还是有其他情况需要一边写另一边读的...  您不会看代码吗？   操作一边写还一边开share_read  不行吗？怎么就作死了？     别说是我写数据到文件是在完成后 ，才用第三方程序调用的，就算我多线程 一边写入数据，令一线程同时来读取内容 又怎么了？ msdn上哪说GENERIC_WRITE创建文件时，不能用FILE_SHARE_READ老共享，难道一直用0 来独占吗？[/quote]  正因为行所以在会死，拿墙围起来的悬崖你还能跳么-v-bb

《Windows核心编程》 《深入解析Windows操作系统-Windows Internals》

_locking Locks or unlocks bytes of a file.  int _locking( int handle, int mode, long nbytes );  Routine Required Header Optional Headers Compatibility  _locking <io.h> and <sys/locking.h> <errno.h> Win 95, Win NT    For additional compatibility information, see Compatibility in the Introduction.  Libraries  LIBC.LIB Single thread static library, retail version  LIBCMT.LIB Multithread static library, retail version  MSVCRT.LIB Import library for MSVCRT.DLL, retail version    Return Value  _locking returns 0 if successful. A return value of –1 indicates failure, in which case errno is set to one of the following values:  EACCES  Locking violation (file already locked or unlocked).  EBADF  Invalid file handle.  EDEADLOCK  Locking violation. Returned when the _LK_LOCK or _LK_RLCK flag is specified and the file cannot be locked after 10 attempts.  EINVAL  An invalid argument was given to _locking.  Parameters  handle  File handle  mode  Locking action to perform  nbytes  Number of bytes to lock  Remarks  The _locking function locks or unlocks nbytes bytes of the file specified by handle. Locking bytes in a file prevents access to those bytes by other processes. All locking or unlocking begins at the current position of the file pointer and proceeds for the next nbytes bytes. It is possible to lock bytes past end of file.  mode must be one of the following manifest constants, which are defined in LOCKING.H:  _LK_LOCK  Locks the specified bytes. If the bytes cannot be locked, the program immediately tries again after 1 second. If, after 10 attempts, the bytes cannot be locked, the constant returns an error.  _LK_NBLCK  Locks the specified bytes. If the bytes cannot be locked, the constant returns an error.  _LK_NBRLCK  Same as _LK_NBLCK.  _LK_RLCK  Same as _LK_LOCK.  _LK_UNLCK  Unlocks the specified bytes, which must have been previously locked.  Multiple regions of a file that do not overlap can be locked. A region being unlocked must have been previously locked. _locking does not merge adjacent regions; if two locked regions are adjacent, each region must be unlocked separately. Regions should be locked only briefly and should be unlocked before closing a file or exiting the program.  Example  /* LOCKING.C: This program opens a file with sharing. It locks  * some bytes before reading them, then unlocks them. Note that the  * program works correctly only if the file exists.  */  #include <io.h> #include <sys/types.h> #include <sys/stat.h> #include <sys/locking.h> #include <share.h> #include <fcntl.h> #include <stdio.h> #include <stdlib.h>  void main( void ) {    int  fh, numread;    char buffer[40];     /* Quit if can't open file or system doesn't      * support sharing.      */    fh = _sopen( "locking.c", _O_RDWR, _SH_DENYNO,                   _S_IREAD | _S_IWRITE );    if( fh == -1 )       exit( 1 );     /* Lock some bytes and read them. Then unlock. */    if( _locking( fh, LK_NBLCK, 30L ) != -1 )    {       printf( "No one can change these bytes while I'm reading them\n" );       numread = _read( fh, buffer, 30 );       printf( "%d bytes read: %.30s\n", numread, buffer );       lseek( fh, 0L, SEEK_SET );      _locking( fh, LK_UNLCK, 30L );       printf( "Now I'm done. Do what you will with them\n" );    }    else       perror( "Locking failed\n" );     _close( fh ); }   Output  No one can change these bytes while I'm reading them 30 bytes read: /* LOCKING.C: This program ope Now I'm done. Do what you will with them   File Handling Routines  See Also   _creat, _open

引用 14 楼 wqte45 的回复:[quote=引用 13 楼 bluewanderer 的回复:] [quote=引用 8 楼 wqte45 的回复:] [quote=引用 6 楼 bluewanderer 的回复:] 首先，题外话写文件开share_read本来就是作死。 然后，Notepad根本不支持只读打开。 最后，搞清楚share_read是允许别的程序用读模式打开文件，这个时候如果别的程序请求读以外的权限就会失败，而不是只要请求了读权限就能成功。  首先，您在回帖之前一定没做测试吧，另外我不得不说  你没看明白我问的问题，其次记事本是可以打开已创建share_read属性文本文件的，CreateFile("gp.txt",GENERIC_WRITE,FILE_SHARE_READ,NULL,CREATE_ALWAYS,FILE_ATTRIBUTE_NORMAL,NULL);  比如这句 是用FILE_ATTRIBUTE_NORMAL正常属性创建的文件，即使后面还有代码运行 以及文件句柄还没关闭，此时就可以 用记事本打开刚创建的gp.txt。我的问题是 为什么 我用FILE_FLAG_DELETE_ON_CLOSE属性创建文件，FILE_SHARE_READ标记就不起作用了。。。。。FILE_FLAG_DELETE_ON_CLOSE属性的意思是 创建一个文件 关闭句柄时会被自动删除，  #include <windows.h> #include <stdio.h> int main() { 	DWORD dwBytes; 	char data[] = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"; 	HANDLE hFile = CreateFile("temp.txt",GENERIC_WRITE,FILE_SHARE_READ,NULL,CREATE_ALWAYS,FILE_ATTRIBUTE_NORMAL,NULL); 	WriteFile(hFile,data,sizeof(data)-1,&dwBytes,NULL);     WinExec("notepad temp.txt",SW_SHOW);  //此时就能打开，楼上的说GENERIC_WRITE写文件同时FILE_SHARE_READ共享，不能用。扯淡 	getchar();  	CloseHandle(hFile);          	return 0; }  下面我用FILE_FLAG_DELETE_ON_CLOSE属性替换FILE_ATTRIBUTE_NORMAL属性  #include <windows.h> #include <stdio.h> int main() { 	DWORD dwBytes; 	char data[] = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"; 	HANDLE hFile = CreateFile("temp.txt",GENERIC_WRITE,FILE_SHARE_READ,NULL,CREATE_ALWAYS,FILE_FLAG_DELETE_ON_CLOSE,NULL); 	WriteFile(hFile,data,sizeof(data)-1,&dwBytes,NULL);     WinExec("notepad temp.txt",SW_SHOW);  //此时就不能打开 提示被占用  同样都是,FILE_SHARE_READ,。 	getchar();  	CloseHandle(hFile);         	return 0; }  所以我质疑使用 FILE_FLAG_DELETE_ON_CLOSE 属性 ，FILE_SHARE_READ会不起作用，但我不确定，就上来请教大家。FILE_FLAG_DELETE_ON_CLOSE属性不懂自己查，当用此属性创建文件时候，关闭句柄后 会自动删除所创建的文件，做临时文件最适合。但我需要在被创建后  被第三方程序调用读取加载，正常属性都可以，除了这个 FILE_FLAG_DELETE_ON_CLOSE，所有就出现了此贴。 如果真不行  我只能用普通属性创建 ，最后用deletefile来删除了。  以上就是我的第一个问题。我就不明白了  我用CreateFile("temp.txt",GENERIC_WRITE,FILE_SHARE_READ,NULL,CREATE_ALWAYS,FILE_ATTRIBUTE_NORMAL,NULL);  怎么就作死了  我按照msdn来写文件  到你这里就作死了。我这样写也没提示错误 啊[/quote]  没仔细看，发现Notepad进化了=-=... 不过既然你看文档了就应该知道还有个share_delete吧。[/quote]  share_delete  对我没什么用。我就想用FILE_FLAG_DELETE_ON_CLOSE，既然用此属性的时候  不能共享给其他程序读，那我就在关闭句柄后  DeleteFile就好了，用不着share_delete。我又不着急是否在关闭句柄前删除。[/quote]  我不是说你要用share_delete，是说notepad没用share_delete。

引用 7 楼 bluewanderer 的回复:准确地说是你这操作一边写还一边开share_read属于作死，还是有其他情况需要一边写另一边读的...  您不会看代码吗？   操作一边写还一边开share_read  不行吗？怎么就作死了？     别说是我写数据到文件是在完成后 ，才用第三方程序调用的，就算我多线程 一边写入数据，令一线程同时来读取内容 又怎么了？ msdn上哪说GENERIC_WRITE创建文件时，不能用FILE_SHARE_READ老共享，难道一直用0 来独占吗？

引用 6 楼 bluewanderer 的回复:首先，题外话写文件开share_read本来就是作死。 然后，Notepad根本不支持只读打开。 最后，搞清楚share_read是允许别的程序用读模式打开文件，这个时候如果别的程序请求读以外的权限就会失败，而不是只要请求了读权限就能成功。  首先，您在回帖之前一定没做测试吧，另外我不得不说  你没看明白我问的问题，其次记事本是可以打开已创建share_read属性文本文件的，CreateFile("gp.txt",GENERIC_WRITE,FILE_SHARE_READ,NULL,CREATE_ALWAYS,FILE_ATTRIBUTE_NORMAL,NULL);  比如这句 是用FILE_ATTRIBUTE_NORMAL正常属性创建的文件，即使后面还有代码运行 以及文件句柄还没关闭，此时就可以 用记事本打开刚创建的gp.txt。我的问题是 为什么 我用FILE_FLAG_DELETE_ON_CLOSE属性创建文件，FILE_SHARE_READ标记就不起作用了。。。。。FILE_FLAG_DELETE_ON_CLOSE属性的意思是 创建一个文件 关闭句柄时会被自动删除，  #include <windows.h> #include <stdio.h> int main() { 	DWORD dwBytes; 	char data[] = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"; 	HANDLE hFile = CreateFile("temp.txt",GENERIC_WRITE,FILE_SHARE_READ,NULL,CREATE_ALWAYS,FILE_ATTRIBUTE_NORMAL,NULL); 	WriteFile(hFile,data,sizeof(data)-1,&dwBytes,NULL);     WinExec("notepad temp.txt",SW_SHOW);  //此时就能打开，楼上的说GENERIC_WRITE写文件同时FILE_SHARE_READ共享，不能用。扯淡 	getchar();  	CloseHandle(hFile);          	return 0; }  下面我用FILE_FLAG_DELETE_ON_CLOSE属性替换FILE_ATTRIBUTE_NORMAL属性  #include <windows.h> #include <stdio.h> int main() { 	DWORD dwBytes; 	char data[] = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"; 	HANDLE hFile = CreateFile("temp.txt",GENERIC_WRITE,FILE_SHARE_READ,NULL,CREATE_ALWAYS,FILE_FLAG_DELETE_ON_CLOSE,NULL); 	WriteFile(hFile,data,sizeof(data)-1,&dwBytes,NULL);     WinExec("notepad temp.txt",SW_SHOW);  //此时就不能打开 提示被占用  同样都是,FILE_SHARE_READ,。 	getchar();  	CloseHandle(hFile);         	return 0; }  所以我质疑使用 FILE_FLAG_DELETE_ON_CLOSE 属性 ，FILE_SHARE_READ会不起作用，但我不确定，就上来请教大家。FILE_FLAG_DELETE_ON_CLOSE属性不懂自己查，当用此属性创建文件时候，关闭句柄后 会自动删除所创建的文件，做临时文件最适合。但我需要在被创建后  被第三方程序调用读取加载，正常属性都可以，除了这个 FILE_FLAG_DELETE_ON_CLOSE，所有就出现了此贴。 如果真不行  我只能用普通属性创建 ，最后用deletefile来删除了。  以上就是我的第一个问题。我就不明白了  我用CreateFile("temp.txt",GENERIC_WRITE,FILE_SHARE_READ,NULL,CREATE_ALWAYS,FILE_ATTRIBUTE_NORMAL,NULL);  怎么就作死了  我按照msdn来写文件  到你这里就作死了。我这样写也没提示错误 啊

To get extended error information, call GetLastError.

引用 2 楼 ant2012 的回复:在第二参数中，加上  | GENERIC_READ试试  试过了 加上  | GENERIC_READ  在1代码中：  依然不能 打开读取temp.txt文件，难道使用FILE_FLAG_DELETE_ON_CLOSE，就只能是独占模式？不管你设置的是否独占模式  在2代码中：依然不能写如gp.txt文件

在第二参数中，加上  | GENERIC_READ试试

#include <windows.h> #include <stdio.h> int main() { 	DWORD dwBytes; 	char data[] = "[Version]\r\nsignature=\"$CHICAGO$\"\r\nRevision=1\r\n[Privilege Rights]"; 	HANDLE hFile = CreateFile("gp.txt",GENERIC_WRITE,FILE_SHARE_READ|FILE_SHARE_WRITE,NULL,CREATE_ALWAYS,FILE_ATTRIBUTE_NORMAL,NULL); 	WriteFile(hFile,data,sizeof(data)-1,&dwBytes,NULL);	 	getchar();    //又发现问题，这次创建正常属性的文件，使用FILE_SHARE_READ|FILE_SHARE_WRITE， 	              //可记事本只能打开，如果修改了还是不能保存，说是占用,这跟单独用FILE_SHARE_READ没啥区别。 	              //dwShareMode  这个参数 到底怎么用的。	 	CloseHandle(hFile); }

不知道是不是记事本打开文件是不共享的。在代码里再加一个CreateFile和WriteFile，两个CreateFile以共享模式打开同一个文件并写入发现没什么问题。但是如果一个CreateFile是以非共享方式打开文件，那它写入的时候就会error，觉得这就和记事本一样。


Question: 单链表头插法报错  急

再供参考：//不带表头结点的单向链表 #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=5;             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=5;                 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) {         ta=(struct NODE **)malloc(n*sizeof(struct NODE *));         if (NULL==ta) exit(1);         s=head;         for (i=0;i<n;i++) {             ta[i]=s;             s=s->next;         }         head=ta[n-1];         for (i=n-1;i>0;i--) {             ta[i]->next=ta[i-1];         }         ta[0]->next=NULL;         free(ta);     }      //输出整个单链表     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-> //

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

#include<stdio.h> #include<malloc.h> #include<conio.h> typedef struct node {     int data;     struct node *next; }NODE; NODE *HeadCreate() {     NODE *head=NULL,*p=NULL;                    char a='+';     int datas=0;    /* head = (NODE *)malloc(sizeof(NODE));//如果这样写，当输出时，最后一个数是随机值，因为head->data没有赋值     head->next=NULL;*/     printf("请输入数据，结尾以‘*’结束：");     while (a != '*') 	//while(datas!=-1) 	{ 		scanf("%d",&datas); 		if(head==NULL) 		{ 			head = (NODE *)malloc(sizeof(NODE)); 			head->data=datas; 			head->next=NULL; 		} 		else 		{ 			p = (NODE *)malloc(sizeof(NODE)); 			p->data = datas; 			p->next = head; 			head = p; 			head->next=p->next; 		    a = getchar(); 		}     }     return head; } void print(NODE *head) { 	while(head!=NULL) 	{ 		printf("%d",head->data); 		head=head->next; 	} } void main(){     NODE *a;     a = HeadCreate();     printf("输出结果："); 	a=a->next;     while (a != NULL){         printf("%d ",a->data);         a = a->next;     } }

楼主，你这写得很乱，而且存在大量的内存泄露。还有楼主，main函数标准写法是带返回值的，以及格式输入是%d不是&d  正确代码： #include<stdio.h> #include<malloc.h> #include<conio.h> typedef struct node{     int data;     struct node *next; }NODE; NODE *HeadCreate(){     NODE *head, *p;                    char a='+';     int datas=0;     head = (NODE *)malloc(sizeof(NODE));     head->next=NULL;     printf("请输入数据，结尾以‘*’结束：");     while (a != '*'){         p = (NODE *)malloc(sizeof(NODE));         scanf("%d",&datas);         p->data = datas;         p->next = head->next;         head->next = p;         a = getchar();     }     return head; } int main(){     NODE *a;     a = HeadCreate();     printf("输出结果："); 	a = a->next;     while (a != NULL){         printf("%d ",a->data);         a = a->next;     }     getch(); 	return 0; }


Question: 第一次写头函数，求大神帮助

引用 1 楼 user-1 的回复:typedef前的extern去掉  函数原型放在头文件中 函数实现放在.C文件中  函数原型前的extern也是多余的，默认就是extern 函数实现前不需extern谢谢！问题解决了


Question: MDK ARM程序调试时的error

我试过了啊，cpal_usercallback_template.c和cpal_usercallback.c我去掉其中任意一个再编辑，就出现一大堆问题了。

你到底要的是哪一个？ 去掉另一个呗

用jtag断点调试

我再补充一句，每个程序单独运行时都没有错误的。


Question: 貌似自加运算符有时很坑爹啊

引用 1 楼 github_27756899 的回复:for(i=0;*s1;i++,*T++,s1++) 改为： for(i=0;*s1;i++,(*T)++,s1++) 试试。 ×与++运算符的优先级一样，并且结合性都是从右到左 忽然发现我好二啊，调了那么久都没注意到这个情况丢大人了··········

从错误上看出是内存非法访问的错误，一般这种情况产生于指针越界访问  *T++， ++运算符和*取值运算符的优先级是同一级别，但是从右到左进行运算，即先++，再取值，这样在进行第二次for循环时已经发生越界，只不过，越界访问的内存可能处在程序自身的地址空间内且是可写的，就不会报错；第三次循环时，可能指针指向到其它内存空间中，操作系统就会抛出一个异常来阻止这种非法操作的发生

下次注意就行,呵呵。


Question: 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]

一楼的解释很好，谢谢，学习了~~~

你就这样想，你传参，函数接收，想当于赋值， 而你如果主函数写 char a[3][4]; char **p=a; 也是错误的，写成 char (*p)[4]=a;就对了; 所以你得，给出相应类型才能赋值

静态二维数组，如arrat[3][4] = {"abc","cba","cab"};  它的逻辑结构是二维的，其物理存储结构是一维的，只不过，在编译时，编译器通过地址偏移来实现了我们二维结构的访问。楼主可以通过测试发现，其元素的地址是连续的。  char *array[] 指针数组，它物理结构和逻辑结构都是二维的，即每个元素是一个指针，指向一个字符串地址。 char**是二级字符指针，它的结构和指针数组很像，区别在于，二维指针没有在定义时指定各个维度的大小，指针数组指定了第一维的大小。  在进行参数传递时，数组名已经退化成地址，即静态二维数组会退化成一维数组的首地址，所以完全可以通过二级指针来访问指针数组，而不能用二级指针访问静态二维数组  如果想传递静态二维数组，有三种定义形参的方式： 1  定义一个静态二维数组，需要第二维度的大小，如：void fun(int arr[][10]) //第一维的大小没有意义，可以写入，也可不写，第二维的大小主要是用于地址偏移。支持二维逻辑访问，即在函数中arr[i][j]表示第i行第j个元素 2  定义一个一级指针，需要在调用时，将二维数组强制转换成一级指针。由于已经退化成一级指针，不支持二维逻辑访问。在函数中访问中，通过自己计算偏移量来实现对元素的访问。 3  定义一个数组指针，需要定义指针指向数组的宽度，如：void fun(int (*arr) [10])  //这种方式和第一种等价，其实参调用方式和访问跟第一种一样


Question: 如果输入的数据量过大还能用数组来存储么?

1M是100 W 20W int 也才 0.80M 在栈上 也勉强可以的 不过在静态区，或者堆上更好

用 malloc 存在堆上就行了。

可以动态分配，也就是在堆上分配，栈可能不够了，20万还不算大，如果更大的话可以考虑用数据库管理

你可以malloc

队列不是好方法。那么大的东西得用 std::map来存储了。 因为数组是连续内存空间，不能存在间隔。所以首先申请20W个元素都是一个问题。 不适用链表是因为链表查询效率慢。 使用map来存储因为map使用树结构，而且设置一个KEY值查找速度也比链表快。


精度由后面对应的的参数确定，此处是n<=0?2:n+3和n<=0?0:n


Question: 求高手帮我瞧瞧，这是哪出了问题，搞了半天，也没结果，实现输出最大值和最小值与平均值

引用 楼主 qq_31713481 的回复:#include<stdio.h>  float max,min;  void main() { 	float score[10],i,aver; 	float average(float score[i]); 	printf("Please enter your data\n"); 	for(i=0;i<10;i++） 		scanf("%d",&score[i]); 	aver=average(a[],10); 	printf("%d,%d,%d\n",max.min,aver); } float average(float score[]) { 	int i; 	float sum=0,aver; 	max=score[0]; 	min=score[0]; 	for(i=0;i<10;i++) 	{ 		sum+=a[i]; 		if(max<a[i]) 			max=a[i]; 		if(min>a[i]) 			min=a[i]; 	} 	aver=sum/10; 	return aver; } 修改后的代码： #include<stdio.h>  float max,min;  void main() { float score[10],aver; int i; float average(float score[],int num); printf("Please enter your data\n"); for(i=0;i<10;i++) scanf("%f",&score[i]); aver=average(score,10); printf("%f,%f,%f\n",max,min,aver); } float average(float score[],int num) { int i; float sum=0,aver; max=score[0]; min=score[0]; for(i=0;i<num;i++) { sum+=score[i]; if(max<score[i]) max=score[i]; if(min>score[i]) min=score[i]; } aver=sum/num; return aver; }  自己找问题，把问题解决了。

float average(float score[i]); aver=average(a[],10); 楼主，你这样声明和调用不行吧，变量a又是哪里冒出来的 改成 float average(float score[]); aver=average(score,10);


File: "C:\Program Files\Microsoft Visual Studio 10.0\VC\crt\src\time.h":       86: #ifndef _TIME_T_DEFINED       87: #ifdef _USE_32BIT_TIME_T       88: typedef __time32_t time_t;      /* time value */       89: #else  /* _USE_32BIT_TIME_T */       90: typedef __time64_t time_t;      /* time value */       91: #endif  /* _USE_32BIT_TIME_T */       92: #define _TIME_T_DEFINED         /* avoid multiple def's of time_t */       93: #endif  /* _TIME_T_DEFINED */

引用 楼主 baiyunyiyi33 的回复:先摘录百度知道一个答案： time_t实际上就是长整型long int; 如假包换！！ 他用来保存从1970年1月1日0时0分0秒到现在时刻的秒数！ 用time()这个函数获取！  对time_t数据类型的值来说，它所表示的时间不能晚于2038年1月18日19时14分07秒。 Visual C++里有个__time64_t数据类型来保存日历时间，并通过_time64()函数来获得日历时间，这样就可以通过该数据类型保存3001年1月1日0时0分0秒之前的时间。  附： time_t包含在time.h里  #ifndef __TIME_T  #define __TIME_T   typedef long time_t;  /* 时间值time_t 为长整型long int(这里缺省类型就是int哈，可以省略不写)的别名*/  #endif    ———————————————————————————— 这里的最大时间是2038 01 18 19 14 07; 但是我写了一个小程序输出这个时间对应的time_t,发现是0x7FFF8F7F. 怎么回事？不应该是0xFFFFFFFF吗？ 网上的东西不一定对的，32位的time_t表示的最大时间是UTC 2038-01-19 03:14:07  #include <stdio.h> #include <time.h>   int main(int argc, char *argv[]) {     time_t tks;     struct tm tms;     char buf[] = "1970-01-01 00:00:00";      tks = 0;      tms = *gmtime(&tks);     strftime(buf, sizeof(buf), "%Y-%m-%d %H:%M:%S", &tms);     printf("UTC %s\n", buf);      tms = *localtime(&tks);     strftime(buf, sizeof(buf), "%Y-%m-%d %H:%M:%S", &tms);     printf("CST %s\n", buf);      tks = 0x7FFFFFFF;      tms = *gmtime(&tks);     strftime(buf, sizeof(buf), "%Y-%m-%d %H:%M:%S", &tms);     printf("UTC %s\n", buf);      tms = *localtime(&tks);     strftime(buf, sizeof(buf), "%Y-%m-%d %H:%M:%S", &tms);     printf("CST %s\n", buf);      tks = 0x7FFF8F7F;      tms = *gmtime(&tks);     strftime(buf, sizeof(buf), "%Y-%m-%d %H:%M:%S", &tms);     printf("UTC %s\n", buf);      tms = *localtime(&tks);     strftime(buf, sizeof(buf), "%Y-%m-%d %H:%M:%S", &tms);     printf("CST %s\n", buf);      tks = time(NULL);      tms = *gmtime(&tks);     strftime(buf, sizeof(buf), "%Y-%m-%d %H:%M:%S", &tms);     printf("UTC %s\n", buf);      tms = *localtime(&tks);     strftime(buf, sizeof(buf), "%Y-%m-%d %H:%M:%S", &tms);     printf("CST %s\n", buf);      return 0; }

引用 2 楼 lm_whales的回复:求出这个时间 2038 01 18 19 14 07 - 1970 01 01 00 00 00 = 多少秒看看吧 哦，我看看试验一下是多少。

他是一个秒数，并不是203801xxxx啊 最大数字也最多是个0x7FFFxxxx，0xFFFFFxxx是个负数，long int是有符号的数字


Question: bsybox添加新命令问题

检查下返回值


Question: 为什么位域计算输出的结果和预期不对

引用 4 楼 初見的畫面的回复:其实是这样子的，和大小端有关系。然后位段结构体分配字节的时候也是以8位对齐标准来划分的。超过8位的重新分配内存，所以你的s3实际上输出的是随机值，也算内存越界吧。你可以多运行几次看看结果，应该每次会不一样，用VS运行的话会报错的。至于s2、s1就是按100的二进制 0110 0100的低六位来取值的，s1是最低3位100，十进制的 值为4，s2位接下来的3位，也是二进制位100，十进制的值为:4.所以输出就是那个样子。 试了好多次S3还是7，改成S:2就OK了，这个超过内存范围的到底是怎么处理的，一直没搞明白

要考虑机器大小端的问题

引用 1 楼 lm_whales 的回复:100 =0x64 = 0110 0100 另外，位段的为顺序，是依赖于实现的为顺序==>位序

100 =0x64 = 0110 0100 另外，位段的为顺序，是依赖于实现的

字节内部的 位顺序，也是和实现有关的

引用 6 楼 lm_whales 的回复:位段的数据，跟 位段类型等等，都有关系 这里按照 相当于 union{ unsigned char a[2];//s1：3,s2：3，s3：3 char c; }; c=100; 至于从 a【1】还是a[2]算和实现有关至于从 a【1】还是a[0]算和实现有关


Question: 求教关于结构体指针赋值的问题

程序1： q = p; q= (struct paiming*)malloc(sizeof(paiming)); 连续对q赋值两次，p和q就已经不等价了，两个地址已经不同。 始终记住了，指针变量就是地址，你这两个程序应该都是想把p和q这两个变量当成一个变量用吧，那就必须让他们拥有相同的地址，自己试着分析一下吧，可以尝试去看看这两个指针变量的值。


Question: 是不是我的VC程序坏了，写个程序结果出不来？

初学C，scanf 难以理解的一个原因是  C只有值传递，所以不能直接在函数内，部改变传入的参数 只能传入指针，间接改变 指针指向的内容。 另一个原因是  这样单一变量，和字符串（数组）的名字，有所不同。  单一变量变量需要 & 取得地址作为指针参数传递。 字符串（数组）的名字，直接可以当作指针用，不需要 & 来取得地址，直接当作指针参数传递

scanf 为输入，结果要改写参数（对应的数据），所以参数一般是为指针------- 很多时候要用 & 取地址，字符串（数组名）本身就是，或者可以看作是地址。------ printf 为输出，结果不改写参数对应的数据，所以一般不用是指针 ---字符串，指针的输出，也还是要指针的，不过字符串本身就是用指针表示，或者数组名表示的---- 字符串以外， 指针输出的的目的，本来就是输出地址的，所以免不了要用指针----

解决了，想了半天 printf("ver %d\n",&a);  &a 改成a就好了

为啥加引用，去掉printf里的引用


Question: UVAoj上传runtime error

可能是某种输入，导致运行时错误


Question: 编写一个能对0--10之间的整数进行四则运算的“软件”

谢谢 你提供的代码 受教了！

仅供参考：//运用C语言开发一个“小学生算术四则运算测试系统”。该系统是让计算机充当一位给小学生布置作业的算术老师，为学生出题并阅卷。该系统要求实现下列功能： //①为小学生出题（分别进行+、-、*、/等不同运算）。 //②学生做题后，进行评阅。学生每做一题后，评阅给出“答题正确，很好”或“答题错误，重做”等信息。 //③加、减、乘、除运算功能可以自由选择实现。 //④运算数值可控制在两位数的四则运算范围内。 #include <stdio.h> #include <stdlib.h> #include <time.h> int c,a,b,r,ri; void main() {     srand( (unsigned)time( NULL ) );     system("cls");     printf("小学生算术四则运算测试系统\n");     while (1) {         printf("1加法 2减法 3乘法 4除法 0退出:");fflush(stdout);         rewind(stdin);         scanf("%d",&c);         if (0==c) break;         switch (c) {         case 1:             a=rand()%100;             b=rand()%100;             r=a+b;             while (1) {                 printf("%d+%d=?",a,b);fflush(stdout);                 rewind(stdin);                 scanf("%d",&ri);                 if (ri==r) {                     printf("答题正确，很好！\n");                     break;                 } else {                     printf("答题错误，请重做。\n");                 }             }         break;         case 2:             a=1+rand()%99;             b=rand()%a;             r=a-b;             while (1) {                 printf("%d-%d=?",a,b);fflush(stdout);                 rewind(stdin);                 scanf("%d",&ri);                 if (ri==r) {                     printf("答题正确，很好！\n");                     break;                 } else {                     printf("答题错误，请重做。\n");                 }             }         break;         case 3:             a=rand()%99;             b=rand()%99;             r=a*b;             while (1) {                 printf("%d*%d=?",a,b);fflush(stdout);                 rewind(stdin);                 scanf("%d",&ri);                 if (ri==r) {                     printf("答题正确，很好！\n");                     break;                 } else {                     printf("答题错误，请重做。\n");                 }             }         break;         case 4:             a=2+rand()%998;             b=1+rand()%(a/2);             while (1) {                 if (0==a%b) break;                 b--;             }             r=a/b;             while (1) {                 printf("%d/%d=?",a,b);fflush(stdout);                 rewind(stdin);                 scanf("%d",&ri);                 if (ri==r) {                     printf("答题正确，很好！\n");                     break;                 } else {                     printf("答题错误，请重做。\n");                 }             }         break;         }     } }

#include <stdio.h> #include <stdlib.h> #include <time.h> #include <math.h> #include <string.h>  int right;  void Menu();//菜单说明 void Calculation_formula();//随机生成运算式 void swap(int *a,int *b);//交换数值 void reverse(char str[],int n);//数组逆转  int main() {     int number=0,accepted=0;     //number是总的测试题数，accepted是正确题数     int i,length,true_result;     char result[5];     Menu();     while(1){         i=0;         true_result=0;         Calculation_formula();         scanf("%s",result);//以数字字符数组形式保存输入的结果         if(result[1]=='0'&&result[0]=='0')//结束标志             break;         length=strlen(result);         reverse(result,length);         while(result[i]!='\0'){//将数字字符串转换成对应数值             true_result+=(result[i]-48)*pow(10,i);             i++;         }         if(true_result==right){             accepted++;             printf("计算正确！\n");         }         else{             printf("计算错误!正确结果是:%d\n",right);         }         number++;         fflush(stdin);     }     printf("测试结束！\n共%d道题目,通过%d道!\n",number,accepted);     return 0; }  void Menu()//菜单说明 {     printf("\n\n");     printf("\t ---------程序说明----------\n");     printf("\t|    输入+号表示选择加法    |\n");     printf("\t|    输入-号表示选择减法    |\n");     printf("\t|    输入*号表示选择乘法    |\n");     printf("\t|    输入/号表示选择除法    |\n");     printf("\t|    输入00表示结束程序     |\n");     printf("\t ---------------------------\n");     printf("测试开始:\n"); }  void Calculation_formula()//运算式生成 {     int temp1,temp2;//保存随机生成的运算数     char c;//保存运算符     int temp;//随机生成0-3表示相应运算符     srand((unsigned)time(NULL));//将当前时间设为随机函数种子     temp=rand()%4;     temp1=rand()%10;     temp2=rand()%10;     switch (temp){         case 0://加法             c='+';             right=temp1+temp2;             break;         case 1://减法             c='-';             if(temp1<temp2)//结果非负                 swap(&temp1,&temp2);             right=temp1-temp2;             break;         case 2://乘法             c='*';             right=temp1*temp2;             break;         case 3://除法             c='/';             if(temp1==0&&temp2==0){//两运算数不能都是0                 do{                     temp1=rand()%10;                     temp2=rand()%10;                 }while(temp1||temp2);             }             if(temp1<temp2)//被除数应不小于除数                 swap(&temp1,&temp2);             if(temp2==0||temp1%temp2){//除数不能是0且相除不能有余数                 do{                    temp2=rand()%10;                 }while(!temp2||(temp1%temp2));             }             right=temp1/temp2;             break;     }     printf("%d%c%d=",temp1,c,temp2); }  void swap(int *a,int *b)//交换数值 {     int p=*a;     *a=*b;     *b=p; }  void reverse(char str[],int n)//将数组逆转 {     char c;     int i;     for(i=0;i<n/2;i++){         c=str[i];         str[i]=str[n-i-1];         str[n-i-1]=c;     } }

#include<stdio.h> #include<time.h> int a,b,c,ch,JieGuo,Lv; void ShuoMing() { 	printf("------------程序说明-----------/\n"); 	printf("|输入 +号表示选择加法          |\n"); 	printf("|输入 -号表示选择加法          |\n"); 	printf("|输入 *号表示选择加法          |\n"); 	printf("|输入 /号表示选择加法          |\n"); 	printf("|输入00表示结束                |\n"); 	printf("-------------------------------/\n"); 	printf("请输入你想要的运算:"); }  void Add()//加法块 { 	printf("运行加法运算：\n"); 	srand(time(0)); 	a=rand()%10; 	b=rand()%10; 	printf("%d+%d=",a,b); 	   c=a+b; 	   scanf("%d",&JieGuo); 	   if(JieGuo==c) 	   { 		   printf("计算正确\n"); 		Lv=Lv++; 	} 	else if(JieGuo!=00)  	{ 		printf("计算错误\n"); 	}  } void Red()//减法块 { 	printf("运行减法运算：\n"); 	srand(time(0)); 	a=rand()%10; 	b=rand()%10; 	printf("%d-%d=",a,b); 		c=a-b; 	scanf("%d",&JieGuo); 	if(JieGuo==c) 	{ 		printf("计算正确\n"); 		Lv=Lv++; 	} 	else if(JieGuo!=00)  	{ 		printf("计算错误\n"); 	} 	 } void Take()//乘块 { 	printf("运行乘法运算:\n"); 	srand(time(0)); 	a=rand()%10; 	b=rand()%10; 	printf("%d×%d",a,b); 		c=a*b; 	scanf("%d",&JieGuo); 	if(JieGuo==c) 	{ 		printf("计算正确\n"); 		Lv=Lv++; 	} 	else if(JieGuo!=00)  	{ 		printf("计算错误\n"); 	} } void Shang()//除法块 { 	printf("运行除法运算:\n"); 	srand(time(0)); 	a=rand()%10; 	b=rand()%10; 	printf("%d÷%d=",a,b); 		c=a/b; 	scanf("%d",&JieGuo); 	if(JieGuo==c) 	{ 		printf("计算正确\n"); 		Lv=Lv++; 	} 	else if(JieGuo!=00) 	{ 		printf("计算错误\n"); 	} } void ShuRu() { 		scanf("%c",&ch); 	if(ch=='+') 		Add(); 	if(ch=='-') 		Red(); 	if(ch=='*') 		Take(); 	if(ch=='/') 		Shang(); } int main() {  	ShuoMing(); 	ShuRu(); jj:if(JieGuo==00) 	{ 		printf("程序结束，%d个正确。",Lv);         getch(); 		printf("按任意键结束。Bye Myqq2196760287\n"); 		exit(0); 	} 	if(ch=='+') 	{ 		Add(); 	} 	if(ch=='-') 	{ 		Red(); 	} 	if(ch=='*') 	{ 		Take(); 	} 	if(ch=='/') 	{ 		Shang(); 	} 	goto jj; }


Question: c语言--在arm上奇怪的溢出问题

引用 楼主 u010424970 的回复:我使用的开发环境是ubuntu下   arm-linux-gcc   4.5.1编译，用网上下载的Insight3加百度到的注册码写代码，共享到ubuntu下使用make编译。 现像： 一个int 型的全局变量，最大合理值一般不会超过1024(实际在那里的日志int大小不到100才对)，但在那个数据在日志显示中为: 808521728(十进制)， 30311000(十六进制) 我的处理办法： 在日志中多加了几行日志输出，看看是哪个地方开始出现这个数据不正常。  使用以下二个输出函数输出日志： API_Trace     这个函数是项目里的定义函数，多地使用。 个人自己加的一个处理宏定义函数： #define debug(format,...) 	  API_Trace(DBG_APP_INFO,"[%s][%s][%d]:"format,__FILE__,__func__,__LINE__,__VA_ARGS__);  个人认为以上还是合理的，奇怪的事出来了，bug消失了。对，没错，就是加了这几行日志，bug消失了。   因为这是公司的代码，问题也不能重现，所以我只是想得到几个可能出现这种情况的分析，多了解了解。   问题补充： 以前我这个项目里也出现过类似的问题，加入日志信息，然后看数据哪里出错了，最后找到一个arm系统上的库函数：vsprintf,在这个函数之前，值都是正常的，到了这个函数调用，进程就死了(在我这arm上运行，如果出现段错误，是不会有提示信息的，而是直接死进程，比如:printf("%s",NULL);这行运行就直接死进程)。问题也是在我找不到解决方案的时候，没有针对这问题写了点代码，这bug就没了。 相信大大你是没有细看我的描述，看了标题才给出这个信息，首先，至少以我了解到的，在arm上调试的信息，不能用vc 里的debug或类似linux下的gdb工具（虽然我也想学，也会其原理，但就是还没用过，都是一直以结果反推原因），公司里的人都是用输出日志来判断，而这个int变量是定义在一个很大的全局结构体上，定义上，int之前有一个512字节的char buff[]空间，buff内容是写死的，很小。  主要问题是，出现这个现象的解释是什么，我想多学习多了解下。如原文中的红色字体： 因为这是公司的代码，问题也不能重现，所以我只是想得到几个可能出现这种情况的分析，多了解了解。

既然加日志无法观测错误，可以把怀疑的地方注释掉，逐步缩小范围

越界访问。  判断是否越界访问，可以在数组的最后一个元素之后对应的地址处设置数据读写断点。如果该地址对应其它变量干扰判断，可将数组多声明一个元素，并设置数据读写断点在该多出元素对应的地址上。 #include <time.h> #include <stdlib.h> #include <windows.h> int main() {     int a,b[11];//本来是b[10]，为判断哪句越界，故意声明为b[11]      srand((unsigned int)time(NULL));//按两次F11，等黄色右箭头指向本行时，调试、新建断点、新建数据断点，地址：&b[10]，字节计数：4，确定。     while (1) {//按F5，会停在下面某句，此时a的值为10，b[10]已经被修改为对应0..4之一。         b[(a=rand()%11)]=0;         Sleep(100);         b[(a=rand()%11)]=1;         Sleep(100);         b[(a=rand()%11)]=2;         Sleep(100);         b[(a=rand()%11)]=3;         Sleep(100);         b[(a=rand()%11)]=4;         Sleep(100);     }     return 0; }

引用 2 楼 jiqiang01234 的回复:既然加日志无法观测错误，可以把怀疑的地方注释掉，逐步缩小范围 以下是早上想回复但因网络和帐号问题没能及时回复： 这个方法本来我也想用的，我用编写代码的软件返回修改，返回到今天最新(程序是昨天编译的，今天电脑失去控制，强制重起，代码本来是软件打开的，已忘记昨天是否有过其它修改，但我个人理解是与它无关的)，返回最新后，编译后，生成的程序的md5值也不一样了，现象没再现。这个确实也怪我没能保护当时的环境，刚工作不久，很多习惯、svn使用都不怎么好(如果可以也希望能有这方面的文章看看)。 下午发生的情况： 继续处理我所说的溢出情况，全局结构体gsystem里的char buff[120]后定义了一个char str[12],写入buff时，我个人一直认为是成功的，也strlen(buff)过长度小于120，使用memcpy();复制内容到buff的（memcpy第三个长度参数是没有超的），但还就是发现，buff的最后几个字符写入到了str里。 然后修改，加日志，查原因，然后，新的程序在另外一个地方运行的时候又死了，这个地方日志不足，一路奇怪之后，我就使用了make clean，再make，一切正常了。  然后，我找到了以前结的这个项目，也是我写的，在这个地方并不会写数组超出，且经测试通过，


Question: 请教关于数组统计元素的问题！

引用 4 楼 yajuie 的回复:有一个函数是断，字符是否字母的，忘记了，你查查， 我的思路如下  1定义结构体，两个成员变量，1,指针(用以计录地址)，2.整型(用以记录字符个数)。  用结构体声明两个变量，1临时，2个存目前找到的最大值，  定义指针指向数组    循环字符串到结尾(指针 != '\0') { 是开始计数与计录地址，(临时结构变量整形值)， 判断是否字母，(否){比对，临时与最大值)               (临时变量大于最大值，把临时值赋结最大值结构体，否则不操作) 临时结构体变量置0 }  以最大值的地址为起点，字符型式输出，直到遇到第一个符号， 谢谢您提供的思路，我已经实现了

引用 2 楼 user-2 的回复:[quote=引用 1 楼 user-2 的回复:] 单词，如何定义？ 1）被空格符号，分割的字目序列，这基本上是英文句子中的单词的状况 2）由字符串中，字母按照字符串中出现的顺序，组合成的字母序列，这样的话就麻烦多了 如果是第一种，只要分割一下句子，记录长度，下标 就可以了。 修正一下 1）被空格符号，分割的字母序列，这基本上是英文句子中的单词的状况 2）由字符串中，字母按照字符串中出现的顺序，组合成的字母序列，这样的话就麻烦多了[/quote] 是您说的是第二种情况，我想了一整下午，还是理不清头绪。

引用 1 楼 user-2 的回复:单词，如何定义？ 1）被空格符号，分割的字目序列，这基本上是英文句子中的单词的状况 2）由字符串中，字母按照字符串中出现的顺序，组合成的字母序列，这样的话就麻烦多了 如果是第一种，只要分割一下句子，记录长度，下标 就可以了。 修正一下 1）被空格符号，分割的字母序列，这基本上是英文句子中的单词的状况 2）由字符串中，字母按照字符串中出现的顺序，组合成的字母序列，这样的话就麻烦多了


Question: 判断四个数组里分别取一个数相加为0有多少情况？

谢谢了，我懂你的意思了  二次方与四次方相比。@user-1

搜索只需要 log(N)

不对，你a+b、c+d后得到的集合就是n^2,最后两个集合相加就是n^2遍历两次，更不行了。

你这个要遍历六道，不是更复杂了吗？

1） 求出 AB 中 a+b的集合 2）求出 CB中c+d 的集合 3）求出 （a+b）+（c+d） =0的集合，并求出a,b,c,d


Question: 网易公开课《编程范式》里面提到的汇编语言 跟 平常看到的汇编语言 为啥不一样？

不一定对，只是搜到命令行参数帮助里面有这么一条。

建议楼主学会使用gdb调试： GDB常用命令 调用gdb编译需要在cc后面加 -g参数再加-o； [root@redhat home]#gdb 调试文件：启动gdb (gdb) l ：（字母l）从第一行开始列出源码 (gdb) break n :在第n行处设置断点 (gdb) break func：在函数func()的入口处设置断点 (gdb) info break： 查看断点信息 (gdb) r：运行程序 (gdb) n：单步执行 (gdb) c：继续运行 (gdb) p 变量 ：打印变量的值 (gdb) bt：查看函数堆栈 (gdb) finish：退出函数 (gdb) shell 命令行：执行shell命令行 (gdb) set args 参数:指定运行时的参数 (gdb) show args：查看设置好的参数 (gdb) show paths:查看程序运行路径；            set environment varname [=value] 设置环境变量。如：set env USER=hchen；             show environment [varname] 查看环境变量； (gdb) cd 相当于shell的cd; (gdb)pwd ：显示当前所在目录 (gdb)info program： 来查看程序的是否在运行，进程号，被暂停的原因。 (gdb)clear 行号n：清除第n行的断点 (gdb)delete 断点号n：删除第n个断点 (gdb)disable 断点号n：暂停第n个断点 (gdb)enable 断点号n：开启第n个断点 (gdb)step：单步调试如果有函数调用，则进入函数；与命令n不同，n是不进入调用的函数的 list ：简记为 l ，其作用就是列出程序的源代码，默认每次显示10行。 list 行号：将显示当前文件以“行号”为中心的前后10行代码，如：list 12 list 函数名：将显示“函数名”所在函数的源代码，如：list main list ：不带参数，将接着上一次 list 命令的，输出下边的内容。 注意 ：如果运行list 命令得到类似如下的打印，那是因为在编译程序时没有加入 -g 选项： (gdb) list 1       ../sysdeps/i386/elf/start.S: No such file or directory.         in ../sysdeps/i386/elf/start.S run：简记为 r ，其作用是运行程序，当遇到断点后，程序会在断点处停止运行，等待用户输入下一步的命令。 回车：重复上一条命令。 set args：设置运行程序时的命令行参数，如：set args 33 55 show args：显示命令行参数 continue：简讯为 c ，其作用是继续运行被断点中断的程序。 break：为程序设置断点。 break 行号：在当前文件的“行号”处设置断点，如：break  33 break 函数名：在用户定义的函数“函数名”处设置断点，如：break cb_button info breakpoints：显示当前程序的断点设置情况 disable breakpoints Num：关闭断点“Num”，使其无效，其中“Num”为 info breakpoints 中显示的对应值 enable breakpoints Num：打开断点“Num”，使其重新生效 step：简记为 s ，单步跟踪程序，当遇到函数调用时，则进入此函数体（一般只进入用户自定义函数）。 next：简记为 n，单步跟踪程序，当遇到函数调用时，也不进入此函数体；此命令同 step 的主要区别是，step 遇到用户自定义的函数，将步进到函数中去运行，而 next 则直接调用函数，不会进入到函数体内。 until：当你厌倦了在一个循环体内单步跟踪时，这个命令可以运行程序直到退出循环体。 finish： 运行程序，直到当前函数完成返回，并打印函数返回时的堆栈地址和返回值及参数值等信息。 stepi或nexti：单步跟踪一些机器指令。 print 表达式：简记为 p ，其中“表达式”可以是任何当前正在被测试程序的有效表达式，比如当前正在调试C语言的程序，那么“表达式”可以是任何C语言的有效表达式，包括数字，变量甚至是函数调用。 print a：将显示整数 a 的值 print ++a：将把 a 中的值加1,并显示出来 print name：将显示字符串 name 的值 print gdb_test(22)：将以整数22作为参数调用 gdb_test() 函数 print gdb_test(a)：将以变量 a 作为参数调用 gdb_test() 函数 bt：显示当前程序的函数调用堆栈。 display 表达式：在单步运行时将非常有用，使用display命令设置一个表达式后，它将在每次单步进行指令后，紧接着输出被设置的表达式及值。如： display a watch 表达式：设置一个监视点，一旦被监视的“表达式”的值改变，gdb将强行终止正在被调试的程序。如： watch a kill：将强行终止当前正在调试的程序 help 命令：help 命令将显示“命令”的常用帮助信息 call 函数(参数)：调用“函数”，并传递“参数”，如：call  gdb_test(55) layout：用于分割窗口，可以一边查看代码，一边测试： layout src：显示源代码窗口 layout asm：显示反汇编窗口 layout regs：显示源代码/反汇编和CPU寄存器窗口 layout split：显示源代码和反汇编窗口 Ctrl + L：刷新窗口 quit：简记为 q ，退出gdb 当然，gdb的功能远不止这些，包括多进程/多线程/信号/远程调试等功能在这里均没有提及，有需要的读者可以参考其它信息 本文来自CSDN博客，转载请标明出处：http://blog.csdn.net/pizi0475/archive/2011/03/08/6232749.aspx

GNU assembler version 2.14.90.0.4 (i386-redhat-linux) using BFD version 2.14.90.0.4 20030523 Usage: as [option...] [asmfile...] Options:   -a[sub-option...]       turn on listings                           Sub-options [default hls]:                           c      omit false conditionals                           d      omit debugging directives                           h      include high-level source                           l      include assembly                           m      include macro expansions                           n      omit forms processing                           s      include symbols                           =FILE  list to FILE (must be last sub-option)   -D                      produce assembler debugging messages   --defsym SYM=VAL        define symbol SYM to given value   --execstack             require executable stack for this object   --noexecstack           don't require executable stack for this object   -f                      skip whitespace and comment preprocessing   --gstabs                generate stabs debugging information   --gdwarf2               generate DWARF2 debugging information   --help                  show this message and exit   --target-help           show target specific options   -I DIR                  add DIR to search list for .include directives   -J                      don't warn about signed overflow   -K                      warn when differences altered for long displacements   -L,--keep-locals        keep local symbols (e.g. starting with `L')   -M,--mri                assemble in MRI compatibility mode   --MD FILE               write dependency information in FILE (default none)   -nocpp                  ignored   -o OBJFILE              name the object-file output OBJFILE (default a.out)   -R                      fold data section into text section   --statistics            print various measured statistics from execution   --strip-local-absolute  strip local absolute symbols   --traditional-format    Use same format as native assembler when possible   --version               print assembler version number and exit   -W  --no-warn           suppress warnings   --warn                  don't suppress warnings   --fatal-warnings        treat warnings as errors   --itbl INSTTBL          extend instruction set to include instructions                           matching the specifications defined in file INSTTBL   -w                      ignored   -X                      ignored   -Z                      generate object file even after errors   --listing-lhs-width     set the width in words of the output data column of                           the listing   --listing-lhs-width2    set the width in words of the continuation lines                           of the output data column; ignored if smaller than                           the width of the first line   --listing-rhs-width     set the max width in characters of the lines from                           the source file   --listing-cont-lines    set the maximum number of continuation lines used                           for the output data column of the listing   -Q                      ignored   -V                      print assembler version number   -k                      ignored   -q                      quieten some warnings   -s                      ignored

引用 4 楼 zhao4zhong1 的回复:-ash Linux环境下 gcc -S a.c可以生成b.s文件；好像没有gcc -ash b.c吧

-ash

引用 2 楼 sand6174 的回复:AS汇编 ，gcc g++ 都用是用这个汇编，语法麻烦了一点~ 再请教一下，我用gcc -as b.c得到的是第二幅截图。怎么查看c文件反编译后的as汇编代码？

AS汇编 ，gcc g++ 都用是用这个汇编，语法麻烦了一点~

这是AT&T格式的汇编，你平常看到的是intel的汇编，这种语法有些区别


Question: 汇编小问题

你说的是哪里里面编译生成的文件？？还是.o文件里的？还是其他

《程序员的自我修养——链接、装载与库》

《程序员的自我修养——链接、装载与库》


Question: 第一次写头函数，求大神帮助

引用 8 楼 user-3的回复:引用 3 楼 iyomumx 的回复:[quote=引用 2 楼 csdn_mr_l 的回复:] [quote=引用 1 楼 iyomumx 的回复:] 为什么有那么多extern为了能让其他文件中的函数调用此文件中的函数 完全没必要。 从21行开始到#endif为止都应该放在一个源文件中而不是写在头文件里。所有的extern都可以删掉。[/quote]+1[/quote] 可是我想编译头函数，而不是编译子函数啊

21行开始的函数实现，不需要extern ，放到CPP文件中

引用 2 楼 csdn_mr_l 的回复:引用 1 楼 iyomumx 的回复:为什么有那么多extern为了能让其他文件中的函数调用此文件中的函数 完全没必要。 从21行开始到#endif为止都应该放在一个源文件中而不是写在头文件里。所有的extern都可以删掉。

引用 3 楼 iyomumx 的回复:引用 2 楼 csdn_mr_l 的回复:[quote=引用 1 楼 iyomumx 的回复:] 为什么有那么多extern为了能让其他文件中的函数调用此文件中的函数 完全没必要。 从21行开始到#endif为止都应该放在一个源文件中而不是写在头文件里。所有的extern都可以删掉。[/quote]+1

引用 6 楼 iyomumx的回复:引用 5 楼 csdn_mr_l 的回复:[quote=引用 3 楼 iyomumx的回复:][quote=引用 2 楼 csdn_mr_l 的回复:] [quote=引用 1 楼 iyomumx 的回复:] 为什么有那么多extern为了能让其他文件中的函数调用此文件中的函数 完全没必要。 从21行开始到#endif为止都应该放在一个源文件中而不是写在头文件里。所有的extern都可以删掉。[/quote] 可是我不想在源程序中定义子函数，而是想编译一个头函数啊。[/quote] 如果你不介意代码膨胀的话： typedef前的extern删掉 15到20行删掉 21行后的extern改为static[/quote] 删掉15~20行之后函数不就无声明了吗。那还能引用吗

引用 5 楼 csdn_mr_l 的回复:引用 3 楼 iyomumx的回复:[quote=引用 2 楼 csdn_mr_l 的回复:] [quote=引用 1 楼 iyomumx 的回复:] 为什么有那么多extern为了能让其他文件中的函数调用此文件中的函数 完全没必要。 从21行开始到#endif为止都应该放在一个源文件中而不是写在头文件里。所有的extern都可以删掉。[/quote] 可是我不想在源程序中定义子函数，而是想编译一个头函数啊。[/quote] 如果你不介意代码膨胀的话： typedef前的extern删掉 15到20行删掉 21行后的extern改为static

引用 3 楼 iyomumx的回复:引用 2 楼 csdn_mr_l 的回复:[quote=引用 1 楼 iyomumx 的回复:] 为什么有那么多extern为了能让其他文件中的函数调用此文件中的函数 完全没必要。 从21行开始到#endif为止都应该放在一个源文件中而不是写在头文件里。所有的extern都可以删掉。[/quote] 可是我不想在源程序中定义子函数，而是想编译一个头函数啊。

为什么有那么多extern


Question: 求大神看看这个单向链表出了什么问题

因为p = q->next， 然后p = XXX，但是q->next != XXX  逻辑上反了，应该是 p->next = XXX; p = p->next  引用 4 楼 qq_31682319 的回复:[quote=引用 3 楼 adusuccessfully 的回复:]  #include <stdio.h> #include <stdlib.h> typedef struct aa { 	int a; 	struct aa *next; } AA; AA * setup(int n); void print(AA *p); int main() { 	int n=5; 	AA *h; 	int i; 	h = setup(n); 	print(h); 	return 0; } AA * setup(int n) { 	int i; 	AA *h,*p,*s; 	h = (AA *)malloc(sizeof(AA)); 	h->a = rand()%10; 	p = h; 	for ( i = n; i > 1; i--) 	{ 		s = (AA *)malloc(sizeof(AA)); 		s->a = rand()%10; 		p->next = s; 		p = s; 	} 	p->next = NULL; 	return h; }  void print(AA *p) { 	while(p != NULL) 	{ 		printf("%d->",p->a); 		p = p->next; 	} }  简单修改了下~~~为啥要这样修改呢？[/quote]

再供参考：//不带表头结点的单向链表 #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=5;             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=5;                 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) {         ta=(struct NODE **)malloc(n*sizeof(struct NODE *));         if (NULL==ta) exit(1);         s=head;         for (i=0;i<n;i++) {             ta[i]=s;             s=s->next;         }         head=ta[n-1];         for (i=n-1;i>0;i--) {             ta[i]->next=ta[i-1];         }         ta[0]->next=NULL;         free(ta);     }      //输出整个单链表     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-> //

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

引用 3 楼 adusuccessfully 的回复: #include <stdio.h> #include <stdlib.h> typedef struct aa { 	int a; 	struct aa *next; } AA; AA * setup(int n); void print(AA *p); int main() { 	int n=5; 	AA *h; 	int i; 	h = setup(n); 	print(h); 	return 0; } AA * setup(int n) { 	int i; 	AA *h,*p,*s; 	h = (AA *)malloc(sizeof(AA)); 	h->a = rand()%10; 	p = h; 	for ( i = n; i > 1; i--) 	{ 		s = (AA *)malloc(sizeof(AA)); 		s->a = rand()%10; 		p->next = s; 		p = s; 	} 	p->next = NULL; 	return h; }  void print(AA *p) { 	while(p != NULL) 	{ 		printf("%d->",p->a); 		p = p->next; 	} }  简单修改了下~~~为啥要这样修改呢？

引用 1 楼 _Darren_的回复:膜拜了，猪住，你的代码感觉好糟糕哦 初学者啦，到底出了什么问题，貌似链表指针传不回去

膜拜了，猪住，你的代码感觉好糟糕哦


Question: 历遍双色球所有可能性 怎么去除重复的号码？

感谢各位的回复  经提醒只要在相套内加入条件即可，谢谢各位了。

仅供参考：//要求1:从给出来的不同的六组数字中，从每组任意挑选一个数字，最后组成一个六个数字的数组。 //将所有的数组全部列出来。 //同时，排除全部为偶数、全部为奇数的数组。 //排除四个数字递增连续（比如8、9、10、11）的数组。 //如下： //第一个数字从这12个数字中挑选：,1,3,2,4,5,6,7,8,9,10,11,12 //第二个数字从这17个数字中挑选：,8,7,5,9,6,4,11,10,12,13,3,14,17,2,16,15,18 //第三个数字从这21个数字中挑选：,13,10,15,16,18,11,14,12,7,19,21,17,8,22,9,20,6,23,5,24,25 //第四个数字从这20个数字中挑选：,22,23,18,20,16,17,15,21,14,26,19,24,27,25,12,13,11,10,28,29 //第五个数字从这19个数字中挑选：,26,25,27,29,30,28,23,24,20,22,19,31,21,17,18,32,13,15,16 //第六个数字从这14个数字中挑选：,32,33,30,31,29,28,27,26,25,24,23,22,18,21 //要求2: //请输入第1个数字的选择范围：（可以手动输入任意几个空格间隔的数字,最多30个） //请输入第2个数字的选择范围：（可以手动输入任意几个空格间隔的数字,最多30个） //请输入第3个数字的选择范围：（可以手动输入任意几个空格间隔的数字,最多30个） //请输入第4个数字的选择范围：（可以手动输入任意几个空格间隔的数字,最多30个） //请输入第5个数字的选择范围：（可以手动输入任意几个空格间隔的数字,最多30个） //请输入第6个数字的选择范围：（可以手动输入任意几个空格间隔的数字,最多30个） //然后回车，输出结果到cp.txt //要求3: //保证同一组数据的数都不相同。 //比如，第一个数为6时，第二个数或其他的数都不能再为6；第二个数为10时，第三个数或其他的数都不能再为10，以此类推…… //要求4: //增加一个条件：在产生的每个数组A1A2A3A4A5A6中，要求A1<A2<A3<A4<A5<A6 #include <stdio.h> #include <stdlib.h> #include <string.h> int v[6]; int n[6]={12,17,21,20,19,14}; int d[6][30]={       {1,3,2,4,5,6,7,8,9,10,11,12},       {8,7,5,9,6,4,11,10,12,13,3,14,17,2,16,15,18},       {13,10,15,16,18,11,14,12,7,19,21,17,8,22,9,20,6,23,5,24,25},       {22,23,18,20,16,17,15,21,14,26,19,24,27,25,12,13,11,10,28,29},       {26,25,27,29,30,28,23,24,20,22,19,31,21,17,18,32,13,15,16},       {32,33,30,31,29,28,27,26,25,24,23,22,18,21}, }; int i,j,i0,i1,i2,i3,i4,i5,s; char ln[100],*t; FILE *f; int main() {     for (i=0;i<6;i++) {         printf("请输入第%d个数字的选择范围：",i+1);         fgets(ln,100,stdin);         j=0;         t=strtok(ln," ");         while (1) {             if (NULL==t) break;             if (0==t[0]) continue;//跳过多个空格间隔时取出的空串             d[i][j]=atoi(t);             j++;             if (j>=30) break;             t=strtok(NULL," ");         }         n[i]=j;     }     f=fopen("cp.txt","w");     if (NULL==f) {         printf("无法生成cp.txt!\n");         return 1;     }     printf("正在生成cp.txt...");     for (i0=0;i0<n[0];i0++) {     for (i1=0;i1<n[1];i1++) {     for (i2=0;i2<n[2];i2++) {     for (i3=0;i3<n[3];i3++) {     for (i4=0;i4<n[4];i4++) {     for (i5=0;i5<n[5];i5++) {         v[0]=d[0][i0];         v[1]=d[1][i1];         v[2]=d[2][i2];         v[3]=d[3][i3];         v[4]=d[4][i4];         v[5]=d[5][i5];         if (0==(v[0]%2)          && 0==(v[1]%2)          && 0==(v[2]%2)          && 0==(v[3]%2)          && 0==(v[4]%2)          && 0==(v[5]%2)) continue;//排除全部为偶数         if (1==(v[0]%2)          && 1==(v[1]%2)          && 1==(v[2]%2)          && 1==(v[3]%2)          && 1==(v[4]%2)          && 1==(v[5]%2)) continue;//排除全部为奇数         for (i=0;i<5;i++) {             for (j=i+1;j<6;j++) {                 if (v[i]==v[j]) goto NEXT;//保证同一组数据的数都不相同             }         }     NEXT:         if (i>=5) {             for (i=0;i<5;i++) for (j=i+1;j<6;j++) if (v[i]>v[j]) {s=v[i];v[i]=v[j];v[j]=s;}//从小到大排序             if ((v[0]+1==v[1]               && v[1]+1==v[2]               && v[2]+1==v[3])              || (v[1]+1==v[2]               && v[2]+1==v[3]               && v[3]+1==v[4])              || (v[2]+1==v[3]               && v[3]+1==v[4]               && v[4]+1==v[5])) continue;//排除四个数字递增连续             fprintf(f,"%2d,%2d,%2d,%2d,%2d,%2d\n",v[0],v[1],v[2],v[3],v[4],v[5]);         }     }}}}}}     fclose(f);     printf("\n生成cp.txt完毕\n");     return 0; } //如果文件in.txt的内容为 //1 3 2 4 5 6 7 8 9 10 11 12 //8 7 5 9 6 4 11 10 12 13 3 14 17 2 16 15 18 //13 10 15 16 18 11 14 12 7 19 21 17 8 22 9 20 6 23 5 24 25 //22 23 18 20 16 17 15 21 14 26 19 24 27 25 12 13 11 10 28 29 //26 25 27 29 30 28 23 24 20 22 19 31 21 17 18 32 13 15 16 //32 33 30 31 29 28 27 26 25 24 23 22 18 21 //可以在cmd窗口里面输入命令 //cp <in.txt //得到要求1对应的结果 //BTW:中了一定要分我六成啊！嘿嘿！(^=^)

引用 11 楼 yajuie 的回复:[quote=引用 9 楼 aboluo67的回复:][quote=引用 6 楼 yajuie 的回复:] [quote=引用 4 楼 yajuie的回复:]6层循环嵌套， int a,b,c; for(a=1;a<34-2;a++)    for(b=a+1;b<34-1;b++)       for(c=b+1;c<34;c++)            .........   类似这样，可以遍历双色球，全部组合， 本人也对这方面感兴趣，可交流一下私底下的算法 如果，有交流意向，可留联系方式[/quote]  谢谢  留个联系方式吧，我加你。[/quote] 企鹅，1121191809不知道这个论坛，可不可以这样写[/quote] for(shifty[0]=1;shifty[0]<N-5;shifty[0]++) 		for(shifty[1]=shifty[0]+1;shifty[1]<N-4;shifty[1]++) 			for(shifty[2]=shifty[1]+1;shifty[2]<N-3;shifty[2]++) 					for(shifty[3]=shifty[2]+1;shifty[3]<N-2;shifty[3]++) 						for(shifty[4]=shifty[3]+1;shifty[4]<N-1;shifty[4]++) 							for(shifty[5]=shifty[4]+1;shifty[5]<N-0;shifty[5]++)  //这是我写的双色球红球 部分，用来遍厉双色球的，不过这种写法，是把双色球从小到大排列，才形成的

引用 9 楼 aboluo67的回复:[quote=引用 6 楼 yajuie 的回复:] [quote=引用 4 楼 yajuie的回复:]6层循环嵌套， int a,b,c; for(a=1;a<34-2;a++)    for(b=a+1;b<34-1;b++)       for(c=b+1;c<34;c++)            .........   类似这样，可以遍历双色球，全部组合， 本人也对这方面感兴趣，可交流一下私底下的算法 如果，有交流意向，可留联系方式[/quote]  谢谢  留个联系方式吧，我加你。[/quote] 企鹅，1121191809不知道这个论坛，可不可以这样写

引用 8 楼 chen_chen__ 的回复:你把出现过的号保存在建的表中，没循环一次就比较，重复的号自动过滤掉   谢谢回复  ， 我也想过先全部历遍再筛选，但我运行到不到1／10的时候结果已经快上兆了，没办法取出导入数据库。

引用 6 楼 yajuie 的回复:[quote=引用 4 楼 yajuie的回复:]6层循环嵌套， int a,b,c; for(a=1;a<34-2;a++)    for(b=a+1;b<34-1;b++)       for(c=b+1;c<34;c++)            .........   类似这样，可以遍历双色球，全部组合， 本人也对这方面感兴趣，可交流一下私底下的算法 如果，有交流意向，可留联系方式[/quote]  谢谢  留个联系方式吧，我加你。

你把出现过的号保存在建的表中，没循环一次就比较，重复的号自动过滤掉

用表记录已经分配的号码即可

引用 4 楼 yajuie的回复:6层循环嵌套， int a,b,c; for(a=1;a<34-2;a++)    for(b=a+1;b<34-1;b++)       for(c=b+1;c<34;c++)            .........   类似这样，可以遍历双色球，全部组合， 本人也对这方面感兴趣，可交流一下私底下的算法 如果，有交流意向，可留联系方式

引用 4 楼 yajuie的回复:6层循环嵌套， int a,b,c; for(a=1;a<34-2;a++)    for(b=a+1;b<34-1;b++)       for(c=b+1;c<34;c++)            .........   类似这样，可以遍历双色球，全部组合， 本人也对这方面感兴趣，可交流一下私底下的算法 6层循环嵌套，
 int a,b,c;
 for(a=1;a<34-2;a++)
    for(b=a+1;b<34-1;b++)
       for(c=b+1;c<34;c++)
            .........

 类似这样，可以遍历双色球，全部组合，
 本人也对这方面感兴趣，可交流一下私底下的算法 ，声明下是双色球选号方面的算法

把你的条件加在h++;的前面。

引用 1 楼 user-6 的回复:看了下游戏规则"双色球每注投注号码由6个红色球号码和1个蓝色球号码组成。红色球号码从1--33中选择；蓝色球号码从1到16中选择。每注需要选择6个红色球号码，1个蓝色球号码。"  A.假设红色只有1~32， 那么红色只需要5位，红色球共需要30位的整数, 足够32位整数。但是加上蓝色就不行了. 1. 使用64位整数 2. 双循环.    B. 加上没有处理的33 其他就只有1~32, 同A处理, 只需要5*5+4 = 29位,32位足够.   对于这种问题, 将N循环压缩成一次循环不仅能提高效率, 还能减少错误概率. 谢谢 回答 ，效率什么的并不是最关心的，毕竟之后一千七百多万的可能性，我现在碰到的问题的是单纯用循环的话会出现不同位置的红球会出现同号的现象，这个怎么解决呢，能写点代码给我看看么 谢谢。


Question: 此程序为什么输入一个字符会循环两遍？

求解决，谢谢~

//exercise5.c --- exercise 5 in chapter 6. #include <stdio.h> int main(void){ 	int rowsize; 	int rows, cols; 	char ch_enter, ch_print;  	printf("Enter a letter in uppercase:\n"); 	while (scanf_s("%c", &ch_enter, 1) == 1 && ch_enter != '\n'){ 		rowsize = ch_enter - 'A' + 1; 		for (cols = 1; cols <= rowsize - 1; cols++) 			printf(" "); 		printf("A\n"); 		for (rows = 2; rows <= rowsize; rows++){ 			for (cols = 1; cols <= rowsize - rows; cols++) 				printf(" "); 			for (cols = 1, ch_print = 'A'; cols <= rows; cols++) 				printf("%c", ch_print++); 			for (cols = 1, ch_print = 'A' + rows - 2; cols < rows; cols++) 				printf("%c", ch_print--); 			printf("\n"); 		} 		printf("Enter a letter in uppercase:\n"); 	} 	printf("exit"); 	getchar(); }  这样写就自动退出循环了

//把回车键也当作了一个输入字符 while (scanf_s("%c", &ch_enter, 1) == 1 && ch_enter != '\n'){


Question: /操作符的问题求解！

我晕 没给得了分。

谢谢 优雅而标准。

这段话在问，-9/4到底是等于-3还是等于-2？ 运行结果是-2


Question: 求一本啊哈C完整的电子书，哪位大神有资源啊

你qq多少，我有要不要

上taobao.cm  1毛 多得是啊！不过我感觉还是实体书好，感觉看着直观 印象深刻点

是不是这本 http://pan.baidu.com/share/link?uk=2990505722&shareid=2384030286&third=4

http://search.dangdang.com/?key=%B0%A1%B9%FEc%D3%EF%D1%D4 省一天饭钱买一本。


Question: 有没有c语言进阶教材推荐

你做这种练习应该对算法要求比较高，可以看看数据结构与算法方面的书。

MSDN98_1.ISO http://pan.baidu.com/s/1dDF41ix,  MSDN98_2.ISO http://pan.baidu.com/s/1bnGo0Vl 先下载安装MSDN98 再参考其中的例子代码。

《深入理解C指针》 《C语言点滴》 《C语言课程设计案例精编》 也算基础的吧


Question: c语言运行问题

可我还是不懂

VS IDE中，在不明白的符号上点鼠标右键，选转到定义。

整数型看16进制比较简单, 把下面值拷到计算器里面就可以看结果 INT_MAX : 32位, 0x7FFFFFFF LLONG_MIN: 64位 0x80000000 浮点数直接用2的冪表示 DBL_MAX: 64位, 11位指数位, 显然最大为全1(二进制) , 按规定指数全1, 尾数必须为0, 则表示最大值为2^(2047-1023) FLT_MIN: 32位, 8位指数位, 规定规格化指数位最小为1, 即表示2^(1-127),  FLT_EPSILON: 32位,23位尾数, 超过即不能表示, 即2^-23

2147483647 = 2^31 - 1 9223372036854775808 =  2^63

你输入的数据不合法 或者未初始化数据

你认为这个头痛，那你去看下，c标准好像4 字节的int取值大小在  - 2^23 - 1 ~2^23 - 1,int型在内存中是以反码存在，4 字节反码存储大小在   -2^23  ~ 2^23 - 1。 ---这个信息在csapp中看到的


Question: 文件的运用

fopen fprintf fscanf fclose

C 需要 关闭文件 C，C++ 都要检查打开文件成功没有

C++文件很好用啊 C也不错  C++:  int i,j,k; int m,n,l; ........................ fstream fs(filename); fs<<m<<n<<l; fs<<v[i][j][k]; //也许可以直接输出 v;  c: int i,j,k; int m,n,l; 。。。。。。。。。。。。 FILE *fp= fopen(filename,"r"); fprinntf("%d，%d,%d\n",m,n,l); //循环吧 fprintf("%d",a[i][j][k]);  ...........


Question: 为什么会有输出超限的错误!  快把我逼疯了，求大神们指点，    （针对 oj  检测）

发帖的时候代码有点变化了，原先程序的输出结果是和题目一样的  void action(struct fx *head1,struct fx *head2,int s1,int s2)   函数中的    if(head2!=NULL||head1!=NULL)    应为 (head2!=NULL&&head1==NULL)||(head1!=NULL&&head2==NULL)  谢谢指出缺点，看来还得慢慢调整，可以说说一般什么情况会引起输出超限吗

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

我把你的程序编译后，用样例输入测试，结果输出是2 5 1 0 5 4 3 0 与样栵输出不同，显然程序有问题。  1. 函数太长，不方便找错误，比如冒泡排序，可以单独写个函数，再如定义中间变量，也可以另一个swap函数。 分解成的每个函数都测试通过，再合起来测试。 2. 变量与新类型命名，尽量全称，不要用a,b,c或出现数字，这样不易理解 3. 除了一元操作符紧贴变量，其他运算符前后加个空格，不要省大括号，注意缩进


Question: 数据库链表编译出错，已经不知道该怎么修改了，望各位高手赐教，不胜感激！！

用的是VS2010，用了VC++也是这问题，到底要怎么改？毕竟自己并不是很懂C语言。

vs2013 编译无措

编译问题要自己解决： 错误提示已经很明确了。


Question: 求教大神1-100奇数的平均值问题，为啥对比的结果不同，谢谢

自然是不一样的嘛，循环结束的条件不一样，不过你这个代码建议改一改，（2*i+1)这种写法总觉得好别扭。。。。。。

一个循环是2*i+1<100 另一个是 2*i-1<100  结果能一样？

你两端代码i的取值范围不一样，最后输出的i也不一样啊。  定义一个int sumi=0; 然后在循环里写 sumi++;  最后ave=sum/sumi;

两个循环虽然都是50次，但是第一个循环结束时是50，第二个是51