Question: 求大婶来帮忙，小弟不胜感激~~~~

上面还加个0

20！=243290200817664000 这么大的数字，还要相加，而且用double......

引用 3 楼 AnYidan 的回复:[quote=引用 2 楼 max_min_ 的回复:] 求不了那么大的数据的！ 越界了！ 下面是修改了你的程序，但是越界问题还是用的！  #include<stdio.h> void main() {     int i ;     unsigned long long n=1,sum=0;     for(i=1;i<=10;i++)     {         n=n*i;         sum=sum+n;     }     printf("sum=%llu",sum); }   大婶，大神，傻傻分不清楚！[/quote]

引用 2 楼 max_min_ 的回复:求不了那么大的数据的！ 越界了！ 下面是修改了你的程序，但是越界问题还是用的！  #include<stdio.h> void main() {     int i ;     unsigned long long n=1,sum=0;     for(i=1;i<=10;i++)     {         n=n*i;         sum=sum+n;     }     printf("sum=%llu",sum); }   大婶，大神，傻傻分不清楚！

自己打断点调试


Question: 编程，在屏幕上输出2~n间所有的素数，n从键盘上输出，但以下的程序不知错在哪，求解？

#include <stdio.h>  int main() {     int n;     int x, y;     int flag;          printf("请输入一个整数n: ");     scanf("%d", &n);      for (x = 2; x <= n; x++) {         flag = 1;          for (y = 2; y < x; y++) {             if (x % y == 0) {                 flag = 0;                 break;             }         }          if (1 == flag)             printf("%5d\n", x);     } }  请输入一个整数n: 10     2     3     5     7

#include<stdio.h>  int main()  {  int n;  int x,y;  int flag; printf("请输入一个整数n:");  scanf("%d",&n);    for(x=2;x<=n;x++)  {  flag=1;  for(y=2;y<x;y++)  {   if(x%y==0)  flag=0;  }  if(1==flag)  printf("%5d\n",x);  }   } 你这这nb啊，这程序写的

printf("5%d",x)； //换成这个，程序没发现什么问题 printf("%d  ",x)；

bool isPrime(int number)				// 求素数 {  	int i; 	int k;  	k = (int)sqrt((double)number);      // 用平方根，而非用number/2，相对提高速度sqrt(number)/2倍 	for(i = 2; i <= k; i++) 	{ 		if(number%i==0)  			break; 	} 	if (i > k)  return true;	// 没有找到可以整除的除数，被除数是 prime number 	else   return false; }


Question: gcc编译错误

编译时加上 -mcmodel=large试试，或者禁止编译器使用common段试试，编译时加上 -fno-common

代码贴出来看看呗！


Question: 把一个长字符串用空格分割成几个小字符串，哪错了？

引用 1 楼 user-1 的回复:多次new！  #include <stdio.h> #include <stdlib.h> #include <iostream>  using namespace std;  char **func(char *str, char *a[5]);  int main(void) { 	int i = 0; 	char str[] = "today is a beautifly day"; 	char *a[6] = {0};  	func(str, a);  	for(; i < 5; i++) 		printf("%s\n", a[i]);  	return 0; }  char **func(char *str, char *a[5]) { 	int row = 0; 	int col = 0; 	int i = 0; 	bool ifNew = true;  	for(; str[i]; i++) 	{ 		 		if(str[i] != ' ') 		{ 			if(ifNew) 				a[row] = (char *)malloc(20); 			a[row][col] = str[i]; 			col++; 			ifNew = false; 			 		} 		else 		{ 			a[row][col] = '\0'; 			row++; 			col = 0; 			ifNew = true; 		} 	} 	a[row][col] = '\0'; 	 	return a; }  //正解   晕了。。。


Question: 多出的两个字节是什么啊？

内存对齐，看下这两篇文章就知道了 http://blog.csdn.net/mbh_1991/article/details/10241785 http://blog.csdn.net/insistGoGo/article/details/8960555

谢谢斑竹大人

引用 2 楼 flowingfirefly 的回复:输出： 10,4,4 20  struct date {     char day[10];     char res[2]; //这里多余了空余2个字节的！内存字节对齐！                 //可以google下，很基础的知识，内存对齐可以提高访问效率        int month;     int year; };

输出： 10,4,4 20

#include <stdio.h> #include <string.h> #include <stdlib.h>  struct date {     char day[10];     int month;     int year; };  int main() {     struct date *object = malloc(sizeof(struct date));     strcpy(object->day, "Good day");     object->month = 6;     object->year = 2013;     printf("%d,%d,%d\n", sizeof(object->day), sizeof(object->month), sizeof(object->year));     printf("%d\n", sizeof(struct date));     FILE *file = fopen("output", "wb");     if (file != NULL) {         fwrite(object, sizeof(struct date), 1, file);         fclose(file);     }     return 0; }


Question: 数组元素不能作形参，那么结构体成员可以作形参使用么？

引用 29 楼 u010412073 的回复:[quote=引用 25 楼 angel_su 的回复:] 不要纠结这个，无实质意义算了吧... 就是爱纠结，喜欢对比。所以。。。。。o(︶︿︶)o 唉。。不过终于解决了。自己写了看过了。反正我的编译环境不支持类似于x.x格式作为参数。所以不纠结了，还是谢谢各位耐心解答。。。继续看书吧。。。。[/quote]我只是有点不理解你的需求，为什么要事先定义好结构体成员，调用的时候传递给形参不就好了么？

值是在调用的时候传进去的，不是一开始就定义好这些类型的。

引用 25 楼 angel_su 的回复:不要纠结这个，无实质意义算了吧... 就是爱纠结，喜欢对比。所以。。。。。o(︶︿︶)o 唉。。不过终于解决了。自己写了看过了。反正我的编译环境不支持类似于x.x格式作为参数。所以不纠结了，还是谢谢各位耐心解答。。。继续看书吧。。。。

按错了... void A(int x,int y){}//普通定义  A(p.x,p.y)//传递指定的结构体成员  void A(Point p){}//结构体做整体定义  A(point);//传递整个结构体

引用 16 楼 u010412073 的回复:感觉这时候x.x已经就是一个类似指定好数据类型的变量，把它看作整体，比如结构体x的成员int x  可以看作int x.x x.x当作整体。不就可以作为形参出现了么？ 那么是编译器不通过这中格式？ 可以不可以把x.x赋给一个类型相同的变量，就可以作为形参了？  这样不就意味着它实际是可以？ 只是不支持x.x这种格式？ 好吧，我都没办法用具体的函数实现，所以都是臆想的。。。 做形参的时候不可以啊，实参的时候才会传递指定的结构体过来。如果做为一个整体的话就是这样写了

非用不可你就自己写个例子试试不就知道了吗，看各位的回答多努力

不要纠结这个，无实质意义算了吧...

引用 21 楼 u010412073 的回复:[quote=引用 19 楼 max_min_ 的回复:] [quote=引用 16 楼 u010412073 的回复:] [quote=引用 6 楼 Adol1111 的回复:] 在参数里使用数组，实际上会退化成普通的指针。 结构体的话不是这样用的，参数是有参数类型和类型名组成的。参数名只是个普通的名称，不能定义成XX.YY的形式。你想要传递结构体的成员，这是你调用时的事情，你调用的时候可以A（p.x,p.y），但不能实现指定好。或者你可以让完整的一个结构体类型做参数，也可以是这个结构体的指针或引用（C++）感觉这时候x.x已经就是一个类似指定好数据类型的变量，把它看作整体，比如结构体x的成员int x  可以看作int x.x x.x当作整体。不就可以作为形参出现了么？ 那么是编译器不通过这中格式？ 可以不可以把x.x赋给一个类型相同的变量，就可以作为形参了？  这样不就意味着它实际是可以？ 只是不支持x.x这种格式？ 好吧，我都没办法用具体的函数实现，所以都是臆想的。。。[/quote]  理解有点不妥！函数传参的时候，只要类型和函数的原型匹配就好了！至于是结构体的成员，还是结构体中成员的成员都是没有关系的！因为编译器也不会知道！它只是检查传进来的参数和函数原型是否匹配就好！ [/quote] 所以说void days(int judge.year，int judge.month，int judge.day) 这样的格式也可以？只不过把judge.year作为一个int型的变量看待？因为显然可以用比如int a，来作为 judge.year的形参，那同样可以把 judge.year作为形参吧，虽然完全没必要如此。另外a.b这样的格式形参支持么？ . [/quote] 恩！对的！只要参数的类型匹配就好啦！

引用 14 楼 zh19921107 的回复:#include <iostream> using namespace std;  struct Date { 	int year; 	int month; 	int day; };  void ShowDate(Date &d) { 	cout<<"引用传参！"<<endl; 	cout<<"年份："<<d.year<<endl 		<<"月份："<<d.month<<endl 		<<"天数："<<d.day<<endl; }  void ShowDate(Date *d) { 	cout<<"指针传参！"<<endl; 	cout<<"年份："<<d->year<<endl 		<<"月份："<<d->month<<endl 		<<"天数："<<d->day<<endl; }  //个人觉得，形参就是体现实参的类型和个数而已。 //如果要数组元素做形参，直接定义个和数组元素 //同类型的形参不就行了吗？不是很明白这句话。 void ShowDate(int year,int month,int day) { 	cout<<"结构体成员传参！"<<endl; 	cout<<"年份："<<year<<endl 		<<"月份："<<month<<endl 		<<"天数："<<day<<endl; }  int main() { 	Date date={2013,11,18}; 	ShowDate(date); 	ShowDate(&date); 	ShowDate(date.year,date.month,date.day); 	return 1; } 个人见解，不足之处还望见谅！楼主加油！共勉！ 恩呢。这样自然是很好的。我的目的就是如果里面写个是具体的成员，便于对应，所以想知道这种格式作为参数有问题么？

引用 20 楼 angel_su 的回复:感觉int judge.year完全不合语法的东西能用吗？真心没看过... 就想知道这种格式正确么？因为显然可以用比如int a，来作为 judge.year的形参，那同样可以把 judge.year作为形参吧，虽然完全没必要如此。但是用的话如果格式支持也是可以的吧？唯一的好处在于便于对应。因为如果有多个int 类型的时候这样写，便于对应成员。所以有这样的想法，当然也是由于数组的那点问题所以这样想。

引用 19 楼 max_min_ 的回复:[quote=引用 16 楼 u010412073 的回复:] [quote=引用 6 楼 Adol1111 的回复:] 在参数里使用数组，实际上会退化成普通的指针。 结构体的话不是这样用的，参数是有参数类型和类型名组成的。参数名只是个普通的名称，不能定义成XX.YY的形式。你想要传递结构体的成员，这是你调用时的事情，你调用的时候可以A（p.x,p.y），但不能实现指定好。或者你可以让完整的一个结构体类型做参数，也可以是这个结构体的指针或引用（C++）感觉这时候x.x已经就是一个类似指定好数据类型的变量，把它看作整体，比如结构体x的成员int x  可以看作int x.x x.x当作整体。不就可以作为形参出现了么？ 那么是编译器不通过这中格式？ 可以不可以把x.x赋给一个类型相同的变量，就可以作为形参了？  这样不就意味着它实际是可以？ 只是不支持x.x这种格式？ 好吧，我都没办法用具体的函数实现，所以都是臆想的。。。[/quote]  理解有点不妥！函数传参的时候，只要类型和函数的原型匹配就好了！至于是结构体的成员，还是结构体中成员的成员都是没有关系的！因为编译器也不会知道！它只是检查传进来的参数和函数原型是否匹配就好！ [/quote] 所以说void days(int judge.year，int judge.month，int judge.day) 这样的格式也可以？只不过把judge.year作为一个int型的变量看待？因为显然可以用比如int a，来作为 judge.year的形参，那同样可以把 judge.year作为形参吧，虽然完全没必要如此。另外a.b这样的格式形参支持么？ .

感觉int judge.year完全不合语法的东西能用吗？真心没看过...

引用 16 楼 u010412073 的回复:[quote=引用 6 楼 Adol1111 的回复:] 在参数里使用数组，实际上会退化成普通的指针。 结构体的话不是这样用的，参数是有参数类型和类型名组成的。参数名只是个普通的名称，不能定义成XX.YY的形式。你想要传递结构体的成员，这是你调用时的事情，你调用的时候可以A（p.x,p.y），但不能实现指定好。或者你可以让完整的一个结构体类型做参数，也可以是这个结构体的指针或引用（C++）感觉这时候x.x已经就是一个类似指定好数据类型的变量，把它看作整体，比如结构体x的成员int x  可以看作int x.x x.x当作整体。不就可以作为形参出现了么？ 那么是编译器不通过这中格式？ 可以不可以把x.x赋给一个类型相同的变量，就可以作为形参了？  这样不就意味着它实际是可以？ 只是不支持x.x这种格式？ 好吧，我都没办法用具体的函数实现，所以都是臆想的。。。[/quote]  理解有点不妥！函数传参的时候，只要类型和函数的原型匹配就好了！至于是结构体的成员，还是结构体中成员的成员都是没有关系的！因为编译器也不会知道！它只是检查传进来的参数和函数原型是否匹配就好！

引用 8 楼 u012348978 的回复:是的。数组和结构体积巨大，不合适在栈使用和传递。以引用的方式使用（也就是指针的方式）。 typedef struct { char *ch; }st,*pst;  void fun( pst s){ s->ch = ( char*)malloc(1024*1024); }  char* func(void){ 	char *p = (char*)malloc(1024*1024); 	return p; } 这个例子十分夸张，这里这是想说明为什么是引用而不是传值。  void days(int judge.year，int judge.month，int judge.day)这个不需要这样做。  void fun( pst s){      s->成员名；这样你就可以访问结构的任意成员。 }  你想单独使用结构成员，区分一下指针和变量就可以了。 函数声明 void days(int a，int b，int c) 如果是结构指针，这样传递void days(judge->year， judge->month， judge->day) 如果是结构变量，这样传递void days( judge.year， judge.month， judge.day) 为什么都不看重点，我是说非用不可的话，可以么？

引用 7 楼 derekrose 的回复:4L。。。 楼主很明显的说了结构体成员，还写了例子，不知所云 5L说得对 楼主你听他的吧我也觉得五楼说的太好了。可是还是没告诉我，到底能不能把结构体成员作为参数？ 虽然没必要这样写，完全可以用其他方法代替，可是我就是想知道。非用不可的话，可以么？

引用 6 楼 Adol1111 的回复:在参数里使用数组，实际上会退化成普通的指针。 结构体的话不是这样用的，参数是有参数类型和类型名组成的。参数名只是个普通的名称，不能定义成XX.YY的形式。你想要传递结构体的成员，这是你调用时的事情，你调用的时候可以A（p.x,p.y），但不能实现指定好。或者你可以让完整的一个结构体类型做参数，也可以是这个结构体的指针或引用（C++）感觉这时候x.x已经就是一个类似指定好数据类型的变量，把它看作整体，比如结构体x的成员int x  可以看作int x.x x.x当作整体。不就可以作为形参出现了么？ 那么是编译器不通过这中格式？ 可以不可以把x.x赋给一个类型相同的变量，就可以作为形参了？  这样不就意味着它实际是可以？ 只是不支持x.x这种格式？ 好吧，我都没办法用具体的函数实现，所以都是臆想的。。。

引用 5 楼 AnYidan 的回复:不知　lz　为何会有此种需求，  如果函数定义中需要使用某中聚集型数据类型中的多个元素，一般用此聚集型数据类型作形参（数组用指针，结构体可以用指针也可以用其本身）  如果函数定义中只需要使用某中聚集型数据类型中的某一个元素，一般用此元素的数据类型作形参恩呢，说的很好，我也是这样总结的，只要用其对应数据的类型就可以，可是我就是纠结，到底可不可以用judge.year这中它本来的格式作为形参。为什么会这样问，也是由于，看到数组时有一句话，说数组元素不能作为参数，比如int a【5】显然指的是不能按照本来的元素格式a【i】作为形参（因为这样i没意义，a代表数组名，其实是一个数组名作为形参了），当然按照你的说法，可以定义int a；只要是类型相同就可以，作为数组中元素的形参。但是对于结构体，我想知道，可不可以把本来的形式作为形参？就是想知道，自己又写不出具体的例子验证。。。

引用 11 楼 u010412073 的回复:[quote=引用 4 楼 max_min_ 的回复:] 可以的！其实只是一个地址而已了！在参数的时候，数组和指针差不多！几乎一样的！  结构体也比较简单了！只是一个地址进去就好！  typedef struct Judge {   int year;   int month;   int day; }Judge_s;  void days(Judge_s *pJudge) {   // TODO something; } 我的意思是结构体成员，不是结构体，就是说结构体里面的每一个具体成员 比如申明函数时void days(int judge.year，int judge.month，int judge.day)可以么？  事先定义好judge含有year，month，day三个成员。  [/quote] 可以的啊！如果只是需要某一个成员的话，那就把这个成员当成参数传进去就好了！ 一个结构体成员传参也是一样的！只有类型匹配就好！


Question: 你敢看不敢看

标题党。。。

引用 9 楼 Adol1111 的回复:[quote=引用 7 楼 u011488256 的回复:] [quote=引用 1 楼 user-9 的回复:] 哎，当j==0的时候，只是判断前面的语句，p[j-1] == p[i-1]不进行判断了，谢谢  为什么大家都不注意后面的问题··这种语句是不是有危险性？ 是不是不应该这样写？[/quote] 没有危险性，因为||是任意条件为真整个表达式就为真，所以第一个为真时就不会判断第二个。同理&&第一个为假时，就不会判断第二个了。 比如，在链表里经常这样写if(p!=NULL&&p->value==value)类似的语句，但却不会写if(p->value == value && p!=NULL)一样。一旦判断到p为空了，那么整个表达式不可能成立，所以就不会判断后面的一句了。但反过来就不对了，p为空时，不能取p的value值，这是访问非法区域，触发段错误。[/quote] nice

引用 7 楼 u011488256 的回复:[quote=引用 1 楼 user-9 的回复:] 哎，当j==0的时候，只是判断前面的语句，p[j-1] == p[i-1]不进行判断了，谢谢  为什么大家都不注意后面的问题··这种语句是不是有危险性？ 是不是不应该这样写？[/quote] 没有危险性，因为||是任意条件为真整个表达式就为真，所以第一个为真时就不会判断第二个。同理&&第一个为假时，就不会判断第二个了。 比如，在链表里经常这样写if(p!=NULL&&p->value==value)类似的语句，但却不会写if(p->value == value && p!=NULL)一样。一旦判断到p为空了，那么整个表达式不可能成立，所以就不会判断后面的一句了。但反过来就不对了，p为空时，不能取p的value值，这是访问非法区域，触发段错误。

记得短路这种是被规范保证的，跟普通运算不一样，放心用。

引用 1 楼 user-9 的回复:哎，当j==0的时候，只是判断前面的语句，p[j-1] == p[i-1]不进行判断了，谢谢  为什么大家都不注意后面的问题··这种语句是不是有危险性？ 是不是不应该这样写？

|| 和 && 被称为“短路”运算符

楼主if判断语句括号内用的逻辑运算符为或(||)，其意思是两者之中有一者成立皆可执行if花括号内的函数体~由此，当||前面的条件已经满足，计算机不会理会||后面的内容。若楼主想计算机判断完前面的内容再判断后面的内容应该用逻辑运算符 且（&&）。

看了，shortcut。

引用 1 楼 user-9 的回复:哎，当j==0的时候，只是判断前面的语句，p[j-1] == p[i-1]不进行判断了，谢谢  对的！||的情况，当前面为真的话，后面就不再判断了！       &&的情况，当前面为假的话，后面也不会再判断的！

如果j==0的话，那么||后面就不会再理会了。  引用 楼主 u011488256 的回复:问题如下 	while (*T)    //如果长度为n，只循环n-1次！！！ 	{ 		 		if(j==0||p[j-1]==p[i-1])   //如果这里这里j=0 ， 那么p【-1】就已经溢出了，想请问下当电脑判断前面已经可以进入条件还会算后面的p[-1]么，就算不会这种代码有没有危险性？！ 		{ 			i++; 			j++; 			next[i]=j; 			T++; 		} 		else 			j=next[j]; 		 	} }


Question: 怎么在buf中追加字符串

用 snprintf(buf,sizeof(buf),"%d",i); 安全函数。

引用 1 楼 user-8 的回复:sprintf 指向 buf 中起始地址, 确保 buf 中空间足够 ++ 也可以使用snprintf。

sprintf 这个函数会用么？

//下面几个函数都可以完成这个功能的！  strcat(); //注意越界 sprintf(); //注意格式 strcpy()/ memcpy(); //注意对应偏移地址

char buf[10240]; strcpy(buf,"bula bula bula ..."); sprintf(buf+19,"expected:%d 0x:%x  but  was:%d 0x:%x",expected,expected, actual,actual)； printf("%s\n",buf);

fprintf

#include <string.h>  strcat 字符串连接函数

sprintf 指向 buf 中起始地址, 确保 buf 中空间足够


Question: 信号量的问题，大神们来帮忙

引用 1 楼 user-1 的回复:生产者消费者问题是不能用SEM_UNDO的.  为神马？

更正一下：  138行到151行的代码为：   if(!set_semvalue(ID[0], 1)){     fprintf(stderr, "Failed to initilize mutex_semaphore\n");     exit(1);   }       if(!set_semvalue(ID[1], N)){     fprintf(stderr, "Failed to initilize empty_semaphore\n");     exit(1);   }       if(!set_semvalue(ID[2], 0)){     fprintf(stderr, "Failed to initilize full_semaphore\n");     exit(1);   }    原本代码里的mutex的值为1，full的值为0。应为多次改动，这里疏忽了。  但改成相应的值以后，代码还是有问题。。。

自己顶一下。 哪位大神给指一下错啊


Question: 原始套接字如何与流套接字建立连接

google ping源代码

引用 5 楼 mmzhzjia 的回复:网上都说调用connect就可以建立连接，你怎么看？ 抓包吧！然后通过信息自己填充进去，发送！

网上都说调用connect就可以建立连接，你怎么看？

相当于自己实现一部分tcp/udp协议。在IP协议包后加上tcp包头信息。用wireshark抓包，然后模仿编写应该问题不大，估计比较费时间。

完全没有解决

原始套接字与标准套接字（流套接字和数据报套接字）的区别在于：原始套接字可以读写内核没有处理的IP数据包，而流套接字只能读取TCP协议的数据，数据报套接字只能读取UDP协议的数据。  所以要自己封包解包。

自己顶一下  在线等


Question: C语言大数加法程序！这个怎么无法输出结果的，菜鸡求救啊？

引用 5 楼 u010652507 的回复:[quote=引用 2 楼 zhao4zhong1 的回复:] 仅供参考#include <stdio.h> #include <string.h> #define MAXLEN 1000 char a1[MAXLEN]; char a2[MAXLEN]; static int v1[MAXLEN]; static int v2[MAXLEN]; static int v3[MAXLEN]; int i,j,n,L,z; void main(void) {     scanf("%d",&n);     for (j=0;j<n;j++) {         scanf("%s%s",a1,a2);          L=strlen(a1);         for (i=0;i<L;i++) v1[i]=a1[L-1-i]-'0';          L=strlen(a2);         for (i=0;i<L;i++) v2[i]=a2[L-1-i]-'0';          for (i=0;i<MAXLEN;i++) v3[i]=v1[i]+v2[i];          for (i=0;i<MAXLEN;i++) {             if (v3[i]>=10) {                 v3[i+1]+=v3[i]/10;                 v3[i]=v3[i]%10;             }         }          printf("Case %d:\n", j+1);         printf("%s + %s = ", a1, a2);          z=0;         for (i=MAXLEN-1;i>=0;i--) {             if (z==0) {                 if (v3[i]!=0) {                     printf("%d",v3[i]);                     z=1;                 }             } else {                 printf("%d",v3[i]);             }         }         if (z==0) printf("0");          printf("\n");     } } //Sample Input //3 //0 0 //1 2 //112233445566778899 998877665544332211 // //Sample Output //Case 1: //0 + 0 = 0 //Case 2: //1 + 2 = 3 //Case 3: //112233445566778899 + 998877665544332211 = 1111111111111111110  引用 2 楼 zhao4zhong1 的回复:仅供参考#include <stdio.h> #include <string.h> #define MAXLEN 1000 char a1[MAXLEN]; char a2[MAXLEN]; static int v1[MAXLEN]; static int v2[MAXLEN]; static int v3[MAXLEN]; int i,j,n,L,z; void main(void) {     scanf("%d",&n);     for (j=0;j<n;j++) {         scanf("%s%s",a1,a2);          L=strlen(a1);         for (i=0;i<L;i++) v1[i]=a1[L-1-i]-'0';          L=strlen(a2);         for (i=0;i<L;i++) v2[i]=a2[L-1-i]-'0';          for (i=0;i<MAXLEN;i++) v3[i]=v1[i]+v2[i];          for (i=0;i<MAXLEN;i++) {             if (v3[i]>=10) {                 v3[i+1]+=v3[i]/10;                 v3[i]=v3[i]%10;             }         }          printf("Case %d:\n", j+1);         printf("%s + %s = ", a1, a2);          z=0;         for (i=MAXLEN-1;i>=0;i--) {             if (z==0) {                 if (v3[i]!=0) {                     printf("%d",v3[i]);                     z=1;                 }             } else {                 printf("%d",v3[i]);             }         }         if (z==0) printf("0");          printf("\n");     } } //Sample Input //3 //0 0 //1 2 //112233445566778899 998877665544332211 // //Sample Output //Case 1: //0 + 0 = 0 //Case 2: //1 + 2 = 3 //Case 3: //112233445566778899 + 998877665544332211 = 1111111111111111110   z=0;                        for (i=MAXLEN-1;i>=0;i--) 		{             if (z==0) 			{                 if (v3[i]!=0) 				{                     printf("%d",v3[i]);                     z=1;                 }             }  			else  			{                 printf("%d",v3[i]);             }         }         if (z==0)  			printf("0");             printf("\n");     }  这段代码是什么意思 看不懂啊 我知道是输出v3数组的[/quote]  从数组最后开始读取，如果数组最后有不等于0的值，就以后的数不必判断，直接输出，如果是 0就什么都不做，读取数组下一个值。这样就把v3[]中的结果输出了。

引用 2 楼 zhao4zhong1 的回复:仅供参考#include <stdio.h> #include <string.h> #define MAXLEN 1000 char a1[MAXLEN]; char a2[MAXLEN]; static int v1[MAXLEN]; static int v2[MAXLEN]; static int v3[MAXLEN]; int i,j,n,L,z; void main(void) {     scanf("%d",&n);     for (j=0;j<n;j++) {         scanf("%s%s",a1,a2);          L=strlen(a1);         for (i=0;i<L;i++) v1[i]=a1[L-1-i]-'0';          L=strlen(a2);         for (i=0;i<L;i++) v2[i]=a2[L-1-i]-'0';          for (i=0;i<MAXLEN;i++) v3[i]=v1[i]+v2[i];          for (i=0;i<MAXLEN;i++) {             if (v3[i]>=10) {                 v3[i+1]+=v3[i]/10;                 v3[i]=v3[i]%10;             }         }          printf("Case %d:\n", j+1);         printf("%s + %s = ", a1, a2);          z=0;         for (i=MAXLEN-1;i>=0;i--) {             if (z==0) {                 if (v3[i]!=0) {                     printf("%d",v3[i]);                     z=1;                 }             } else {                 printf("%d",v3[i]);             }         }         if (z==0) printf("0");          printf("\n");     } } //Sample Input //3 //0 0 //1 2 //112233445566778899 998877665544332211 // //Sample Output //Case 1: //0 + 0 = 0 //Case 2: //1 + 2 = 3 //Case 3: //112233445566778899 + 998877665544332211 = 1111111111111111110  引用 2 楼 zhao4zhong1 的回复:仅供参考#include <stdio.h> #include <string.h> #define MAXLEN 1000 char a1[MAXLEN]; char a2[MAXLEN]; static int v1[MAXLEN]; static int v2[MAXLEN]; static int v3[MAXLEN]; int i,j,n,L,z; void main(void) {     scanf("%d",&n);     for (j=0;j<n;j++) {         scanf("%s%s",a1,a2);          L=strlen(a1);         for (i=0;i<L;i++) v1[i]=a1[L-1-i]-'0';          L=strlen(a2);         for (i=0;i<L;i++) v2[i]=a2[L-1-i]-'0';          for (i=0;i<MAXLEN;i++) v3[i]=v1[i]+v2[i];          for (i=0;i<MAXLEN;i++) {             if (v3[i]>=10) {                 v3[i+1]+=v3[i]/10;                 v3[i]=v3[i]%10;             }         }          printf("Case %d:\n", j+1);         printf("%s + %s = ", a1, a2);          z=0;         for (i=MAXLEN-1;i>=0;i--) {             if (z==0) {                 if (v3[i]!=0) {                     printf("%d",v3[i]);                     z=1;                 }             } else {                 printf("%d",v3[i]);             }         }         if (z==0) printf("0");          printf("\n");     } } //Sample Input //3 //0 0 //1 2 //112233445566778899 998877665544332211 // //Sample Output //Case 1: //0 + 0 = 0 //Case 2: //1 + 2 = 3 //Case 3: //112233445566778899 + 998877665544332211 = 1111111111111111110   z=0;                        for (i=MAXLEN-1;i>=0;i--) 		{             if (z==0) 			{                 if (v3[i]!=0) 				{                     printf("%d",v3[i]);                     z=1;                 }             }  			else  			{                 printf("%d",v3[i]);             }         }         if (z==0)  			printf("0");             printf("\n");     }  这段代码是什么意思 看不懂啊 我知道是输出v3数组的

引用 3 楼 qq695181966 的回复:引用 1 楼 junlinfushi 的回复:设置断点，逐步调试哈哈哈~发现你好喜欢说这句话哟~~被发现了

设置断点，逐步调试


Question: 翻译

由一个整形不需要任何转换“做了”一个指针  我省去了主语

函数send的第一个参数，没有类型转换的情况下，将整型当指针传入

引用 4 楼 derekrose 的回复:[quote=引用 2 楼 u012453424 的回复:] [quote=引用 1 楼 derekrose 的回复:] 无需类型转换 翻译得不好[/quote]  老师请批评指正[/quote] 还有整句话没好好翻译呢

引用 2 楼 u012453424 的回复:[quote=引用 1 楼 derekrose 的回复:] 无需类型转换 翻译得不好[/quote]  老师请批评指正

忘了转换

引用 1 楼 derekrose 的回复:无需类型转换 翻译得不好

无需类型转换


Question: C语言如何返回字符串

char s[buffer_size]; foo(s, buffer_size); 推荐这种。

没有十全十美的方法，合适的最好

楼主你说的两种方法都是可以的。

引用 6 楼 max_min_ 的回复:两种方法都可以！都有用到，看具体需求吧！ 如果可以改结构的话，无疑传参数，传地址会比较好好点 动态分配的话，容易产生内存碎片，而且费时！ [quote=引用 楼主 netbooting 的回复:] 我了解两种方法  一、将一个字符指针或数组作为参数传入调用方法。     这种方式有点麻烦，要多声明一个参数，不太符合使用其它语言的习惯，另外不知道这种方式能不能动态扩充字符串大小。  二、在方法中声明一个静态字符数组，动态分配内存，返回这个数组     这种方式导致字符串的生存周期为程序运行期，浪费内存。   不知道我理解的对不对，大神指点，一般都用哪种方法？？[/quote]+1

一般有固定的内存记录字符串，返回const指针来用

两种方法都可以！都有用到，看具体需求吧！ 如果可以改结构的话，无疑传参数，传地址会比较好好点 动态分配的话，容易产生内存碎片，而且费时！ 引用 楼主 netbooting 的回复:我了解两种方法  一、将一个字符指针或数组作为参数传入调用方法。     这种方式有点麻烦，要多声明一个参数，不太符合使用其它语言的习惯，另外不知道这种方式能不能动态扩充字符串大小。  二、在方法中声明一个静态字符数组，动态分配内存，返回这个数组     这种方式导致字符串的生存周期为程序运行期，浪费内存。   不知道我理解的对不对，大神指点，一般都用哪种方法？？

参考C语言库函数所用方法。

第一种方法比较好

函数内划分内存有释放问题 静态数组有调用问题 还是传入参数好  之所以和其他语言不一样，是因为C语言算不得高级语言

类似第一种，传入一个缓冲区，在函数里，对缓冲区填值。这种方式不能动态扩充字符串缓冲区大小，所以传入的缓冲区一定要足够大否则会溢出导致错误，最好将缓冲区的大小也传入函数。  如果需要在函数里分配空间，这样需要将实参的指针的地址传入方法，即二级指针。 int func(char **str) {     *str = malloc(size); }

反正只要注意不返回局部变量都行


Question: ^符号问题，谢谢、、、新手

对于如下集合，结果是不正确的。 {1,2,4,7} {1,2,3};

另外  1^2^4^7 =0 1^2^3 =0

引用 5 楼 Adol1111 的回复:^是异或 以二进制来看这2个数，然后对比相同位置上的数，不同取1，相同取0 就是楼上说的0^1=1   0^0=0   1^0=1   1^1=0 以一个4位二进制来举例 3^5 3：0011 5：0101    0110 所以结果是6  如果这个数出现了两次，那么就会互相抵消变成0,0与任何数异或就是这个数本身，所以就是用这个方法找出单独的数字。但是如果有2个以上的数字是单个的就不不能用这方式来求解了。 ++

c 就那么几个操作符

抑或 0^1=1   0^0=0   1^0=1   1^1=0

引用 2 楼 netbooting 的回复:  single ^= array[i];  single = single ^ array[i];  异或：相同为假，相异为真。1^1或0^0=0  1^0或0^1=1 +1

异或....................


Question: 编程1至100相加

引用 1 楼 user-10 的回复:算的是s，输出的是sum ++

引用 楼主 u012876050 的回复:编程1至100相加，下面是我做的程序，怎么得数是错误的。求解？ #include<stdio.h> int main() {     int sum,n,s;     s=0;     for(n=1;n<=100;n++)     {          s+=n; } 	printf("1+2+3+...+100=%d\n",sum);     return sum; }  写代码的时候不要睡觉啊！注意，注意

果断发现了一个跟我一样的好基友，马大哈早晚会被自己坑死的，计算的是s,输出的是sum

引用 1 楼 user-10 的回复:算的是s，输出的是sum +10086

#include<stdio.h> int main() {     int sum,n;     sum = 0;     for(n=1;n<=100;n++)     {              sum += n;     }     printf("1+2+3+...+100=%d\n",sum);     return 0; }

不是有算数法则吗 前1到n个数的和等于 n *（n+1）/2

加了s，然后打印sum，怎么有可能得到正确的结果？

引用 1 楼 user-10 的回复:算的是s，输出的是sum+1

#include<stdio.h> int main() {     int n,s;     s=0;     for(n=1;n<=100;n++)     {          s+=n; } printf("1+2+3+...+100=%d\n",s);     return s; }  引用 楼主 u012876050 的回复:编程1至100相加，下面是我做的程序，怎么得数是错误的。求解？ #include<stdio.h> int main() {     int sum,n,s;     s=0;     for(n=1;n<=100;n++)     {          s+=n; } 	printf("1+2+3+...+100=%d\n",sum);     return sum; }

算的是s，输出的是sum


Question: 初学c语言关于语法问题

非常感谢你们的解答，对于初次使用CSDN的我好像瞬间交了好多朋友，亲爱的朋友：谢谢你们！！！

语法错误就是机器不能识别的错误，语法错误就是你编写的程序里面使用了不规范的关键字或者变量名之类的错误，笼统得说就是编译都无法通过的程序，编译器无法识别你写的程序。（百度） 另外，for后面加了；是语法错误，语法错误后程序是否可以运行输出结果？ 答：不能！

在for()后面加，就是语法错误！ 语法错误vc6.0是不会给予编译通过的，所以不能执行代码

不要迷信书、考题、老师、回帖； 要迷信CPU、编译器、调试器、运行结果。 并请结合“盲人摸太阳”和“驾船出海时一定只带一个指南针。”加以理解。 任何理论、权威、传说、真理、标准、解释、想象、知识……都比不上摆在眼前的事实！  偶有时遇到莫名其妙的编译错误提示时，都是用 “每次用/*...*/注释掉不同部分再重新编译，直到定位到具体语法出错的位置。” 的方法解决的。

for (i = 1; i < 100; i++)  ;和,             printf("%d ", i);  // for后面不能加逗号,但可以加分号; // 因为for后面必须接一个语句，逗号是表达式，不是语句，接分号表示一个空语句

逗号运算符可以连接两个有返回值的表达式，如赋值，比较等，但是不能连接逻辑操作语句

语法错误简单来说就是“鸡同鸭讲”，你所写的语句C语言不认识。语法错误直接导致编译不会成功，所以也无法运行。  引用 楼主 u012505341 的回复:请问在c语言中何为语法错误？在for()之后加“,"是否为语法错误？语法错误后程序是否可以运行输出结果？请求各位大神帮忙~~~~~

楼主把注意力多放在其他的实质性的问题上，比如学习个排序算法，查找算法等等；不要在这种问题上纠结；你在for()后面加个,有什么用

就好比你和别人说话 你的语法和别人都不是一样的 别人听不懂一样！

语法错误就是错误的  编译时通不过不了的 计算机读不懂你的语言因为你没有按照它的语法规则来

语法错误就是 计算机看不懂你写的是什么东西 你写的程序是保存在文本中 通过计算机的词法分析器 和语法分析器 去把它转换成汇编语言 在通过汇编器变成二进制的机器语言  计算机在去执行 因为计算机只认识机器语言 汇编语言是机器语言的助记符 所以呢 你的语言错误正如 你写错字 根本就没这个字 多一笔 少一笔 没人认识所以就是语言错误 写文章 句子是病句也不行 因为计算机毕竟不是智能的 它要遵循一定规则去识别 识别的程序也是人写的

多看书，多敲几个代码，一旦语法错误，编译是不通过的，别说运行了。语法这东西，代码敲多了自然就知道了

语法错误，都没有编译过，还怎么运行程序啊？ 代代码看看那


Question: c语言的程序的小问题

先找到数学规律，再写代码实现

#include <stdio.h> #include <stdlib.h>  int main(void) {     int   i, j;     int   n = 5;      for (i = 1; i < n + 1; i++) {           // 控制层数         for (j = 0; j < (n - i) * 2 ; j++)  // 打印前导空格             printf(" ", j);         for (j = 1; j <= i; j++)            // 打印每一层前半部分的数字             printf("%d ", j);         for (j = j - 2; j >= 1; j--)        // 打印每一层后半部分的数字             printf("%d ", j);         printf("\n");     }     return 0; }  输出结果：         1       1 2 1     1 2 3 2 1   1 2 3 4 3 2 1 1 2 3 4 5 4 3 2 1

前几天好像有人问过一模一样的题……

当输入的数 代表的是俩位数 甚至更多 想要对齐的话 需要进一步处理 判断数的位数 特殊处理

#include <stdio.h> #include <stdlib.h>  int main() {     int num;     int i;     int j;     int k;     scanf("%d",&num);//输入几层      for(i = 1 ; i < num+1 ;i++)        for(j = i ; j < num+1 ;j++){              if(j == num ){                 for(k = 1 ;k < i + 1 ;k++)                   printf("%d",k);                 for(k = i -1  ; k >= 1; k--)                   printf("%d",k);                    printf("\n");             }            //输出数字             else                 printf(" ");//判断要输入几层 要输出几个空格在开头        }     return 0; }


Question: Windows SDK 编程方式的问题

Spy++软件会用吗？

请问, 消息体是从什么地方传入的?

不会的。  不同的消息由不同的winproc解决。这个你不用担心。你要做的是编写一个winproc，来响应消息。  如果你需要其他窗口协调工作，那就向那个窗口发送消息好了。这里唯一需要关心的是，就是如何获得那个窗口的HWND.   只有消息才会唤醒win程序，否则win程序是休眠的。

GDI32/USER32 还要存在一阵子

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

这个说法不完全正确 每一级窗口(或菜单)都是这样的: 　　　　1. 注册窗口类, 使用到的结构 WNDCLASSEX, 函数 RegisterClassEx.//每个窗口类都需要，但不是每个窗口需要 　　　　2. 创建窗口, 函数 CreateWindowEx.//每个窗口需要 　　　　3. 消息循环, 结构 MSG, 函数 GetMessage, TranslateMessage, DispatchMessage. 　　　　4. 进入无限循环, 消息处理 :-) //3，4:每个线程需要,每个线程的所有窗口共用一个消息循环

Windows不是纸糊的，不用担心。  当然，另一方面，软件的设计也要合理。比如说有人看了excel和扫雷，自己模仿，前者他用了几千个文本框，后者用了几百个按钮，这个就是不合理。

程序设计不当消耗了大量了cpu导致死机是有可能的！ 所以理清楚各个消息控制就好，思路清楚！

消息循环并不等于是while(1)这样的循环, 因为你会发现它并不会像while(1)这样的死循环一样, 占用30%以上的CPU.  windows就是基于消息的, 所以你不用担这个问题.

合理的划分模块,消息不怕多,就怕乱

最多程序死掉了。那就用进程管理器杀掉好了。 或者电脑死机了。那也没事，重启就好了


Question: 缓冲区的问题

引用 2 楼 lgf2002 的回复:函数fgets、fputs封装了read、write函数，在fgets、fputs函数里有另外一个buf，就是标准I/O缓冲。拿fgets函数来说，它调用read函数，从文件中读出的数据先放到这个buf，当buf里的字节数达到fgets函数传递的n-1字节时，然后才将这个buf里的n-1字节数据加上空字符0共n个字节的字符拷贝到用户定义的buf中。 这样做，为了减少系统级的I/O来提高效率  标准I/O库实现了一个 buffer

标准I/O缓冲区应该是内核里的缓冲区，用户程序的行缓冲区是用户空间的缓冲区，我是这么觉得的 具体答案还是坐等大牛回答吧


Question: 请教一下，char * const *p是真么意思呢

非常感谢，这个是把const类型的指针转换成char*

(char * const *) p1 应该是强制类型转换，将p1转换成，指向char*类型的const指针。

return里的(char * const *) p1呢

const void *p1, const void *p2的写法是为了防止p1和p2所指向的内容被改写，起保护作用。  引用 楼主 cytzrs 的回复:man了一下qsort，它里边的compar函数是这么写的： cmpstringp(const void *p1, const void *p2)        {            /* The actual arguments to this function are "pointers to               pointers to char", but strcmp(3) arguments are "pointers               to char", hence the following cast plus dereference */             return strcmp(* (char * const *) p1, * (char * const *) p2);        }   请问一下大家* (char * const *) p1, * (char * const *) p2)，这种写法是什么意思，和*const(char**p),含义一样吗


Question: 想看一下VS2010中abs函数的写法

引用 8 楼 zhao4zhong1 的回复:C:\Program Files\Microsoft Visual Studio 10.0\VC\crt\src\abs.c /*** *abs.c - find absolute value * *       Copyright (c) Microsoft Corporation. All rights reserved. * *Purpose: *       defines abs() - find the absolute value of an int. * *******************************************************************************/  #include <cruntime.h> #include <stdlib.h>  #pragma function(abs, _abs64)  int __cdecl abs (         int number         ) {         return( number>=0 ? number : -number ); } __int64 __cdecl _abs64(         __int64 num         ) {         return (num >=0 ? num : -num); }  还是赵老师好人啊 即给源码又给路径。真是明白我的难处啊

引用 6 楼 netbooting 的回复:     return a < 0 ? -a : a;  我最开始也是这样写，然后就想用位运算取反+1会不会更好些。。 因此想看看VS里是怎么写的~~~  谢谢了

C:\Program Files\Microsoft Visual Studio 10.0\VC\crt\src\abs.c /*** *abs.c - find absolute value * *       Copyright (c) Microsoft Corporation. All rights reserved. * *Purpose: *       defines abs() - find the absolute value of an int. * *******************************************************************************/  #include <cruntime.h> #include <stdlib.h>  #pragma function(abs, _abs64)  /*** *int abs(number) - find absolute value of number * *Purpose: *       Returns the absolute value of number (if number >= 0, returns number, *       else returns -number). * *Entry: *       int number - number to find absolute value of * *Exit: *       returns the aboslute value of number * *Exceptions: * *******************************************************************************/  int __cdecl abs (         int number         ) {         return( number>=0 ? number : -number ); } __int64 __cdecl _abs64(         __int64 num         ) {         return (num >=0 ? num : -num); }

return a < 0 ? -a : a;

求好人~\(≧▽≦)/~

引用 3 楼 zhaowech 的回复:你对源代码抱有什么样的疑问呢？  木有疑问，就想看看它是怎么写的. 学习一下他的写法。

你对源代码抱有什么样的疑问呢？

引用 1 楼 user-5 的回复:abs上点右键，看有无“跳转到定义”这一命令。  嗯嗯。主要是手头没有安装VS，没办法查看函数的内容。 设个断点，然后调试进入到函数内部也是可以看到的。

abs上点右键，看有无“跳转到定义”这一命令。


Question: c编程问题

引用 4 楼 AnYidan 的回复:估计 void delay(unsigned char);谢谢

引用 3 楼 makezwl 的回复:你把delay函数贴出来嗯 解决了

估计 void delay(unsigned char);

你把delay函数贴出来

引用 1 楼 focuslight 的回复:看晶振不同, 研时不同 具体说说没明白

看晶振不同, 研时不同


Question: (a+b)/2 = a&b + (a^b)>>1     求解释

引用 10 楼 a627088424 的回复:[quote=引用 9 楼 a627088424 的回复:] [quote=引用 8 楼 a627088424 的回复:] [quote=引用 6 楼 baichi4141 的回复:] [quote=引用 4 楼 a627088424 的回复:] (a>>1)+(b>>1)不行吗，有什么缺陷 a=1;b=1;[/quote]（a+b）/2这样ne[/quote]换成这样a&b + (a^b)>>1，有点在哪[/quote]除法一般能比位运算慢多少[/quote] 优点就在于位运算不可能溢出 实际工作中根本不会这么用，这就是用来考察学生是否懂不懂数据溢出的教学用问题

引用 1 楼 baichi4141 的回复:没啥可解释的，二进制基本运算而已，先求相同部分，再把不同部分除2就是中值了 举例来说，111和101求中值，首先分成(101+101)+(10)，然后除以2就是(101)+(10>>1)+1

引用 9 楼 a627088424 的回复:[quote=引用 8 楼 a627088424 的回复:] [quote=引用 6 楼 baichi4141 的回复:] [quote=引用 4 楼 a627088424 的回复:] (a>>1)+(b>>1)不行吗，有什么缺陷 a=1;b=1;[/quote]（a+b）/2这样ne[/quote]换成这样a&b + (a^b)>>1，有点在哪[/quote]除法一般能比位运算慢多少

引用 8 楼 a627088424 的回复:[quote=引用 6 楼 baichi4141 的回复:] [quote=引用 4 楼 a627088424 的回复:] (a>>1)+(b>>1)不行吗，有什么缺陷 a=1;b=1;[/quote]（a+b）/2这样ne[/quote]换成这样a&b + (a^b)>>1，有点在哪

引用 6 楼 baichi4141 的回复:[quote=引用 4 楼 a627088424 的回复:] (a>>1)+(b>>1)不行吗，有什么缺陷 a=1;b=1;[/quote]（a+b）/2这样ne

lz 什么项目，如此计较速度？如果两个数是 singned int 呢？

引用 4 楼 a627088424 的回复:(a>>1)+(b>>1)不行吗，有什么缺陷 a=1;b=1;

引用 4 楼 a627088424 的回复:[quote=引用 3 楼 baichi4141 的回复:] [quote=引用 2 楼 a627088424 的回复:] [quote=引用 1 楼 baichi4141 的回复:] 没啥可解释的，二进制基本运算而已，先求相同部分，再把不同部分除2就是中值了 举例来说，111和101求中值，首先分成(101+101)+(10)，然后除以2就是(101)+(10>>1)你一说，以下就明白了。但是开始的时候，怎么我就看着那么不直觉呢，以下看不出来。 [/quote] 二进制运算规则，用穷举法就能总结归纳了，毕竟就1和0两个数字而已[/quote](a>>1)+(b>>1)不行吗，有什么缺陷[/quote] a与b为数组下标

引用 3 楼 baichi4141 的回复:[quote=引用 2 楼 a627088424 的回复:] [quote=引用 1 楼 baichi4141 的回复:] 没啥可解释的，二进制基本运算而已，先求相同部分，再把不同部分除2就是中值了 举例来说，111和101求中值，首先分成(101+101)+(10)，然后除以2就是(101)+(10>>1)你一说，以下就明白了。但是开始的时候，怎么我就看着那么不直觉呢，以下看不出来。 [/quote] 二进制运算规则，用穷举法就能总结归纳了，毕竟就1和0两个数字而已[/quote](a>>1)+(b>>1)不行吗，有什么缺陷

引用 2 楼 a627088424 的回复:[quote=引用 1 楼 baichi4141 的回复:] 没啥可解释的，二进制基本运算而已，先求相同部分，再把不同部分除2就是中值了 举例来说，111和101求中值，首先分成(101+101)+(10)，然后除以2就是(101)+(10>>1)你一说，以下就明白了。但是开始的时候，怎么我就看着那么不直觉呢，以下看不出来。 [/quote] 二进制运算规则，用穷举法就能总结归纳了，毕竟就1和0两个数字而已

引用 1 楼 baichi4141 的回复:没啥可解释的，二进制基本运算而已，先求相同部分，再把不同部分除2就是中值了 举例来说，111和101求中值，首先分成(101+101)+(10)，然后除以2就是(101)+(10>>1)你一说，以下就明白了。但是开始的时候，怎么我就看着那么不直觉呢，以下看不出来。


Question: 呃```初学者求大神解惑，关于C语言变量和函数的问题

初学者语法什么的都没搞清楚，搞个程序那么多错误，还不如实实在在多看点书。

帮你修改了一些语法错误，看看吧！学会调试程序阿！  #include <stdio.h> #include <string.h>  char user[24]; char password[24]; void XTjiemian() {     printf("\n\n\n(按1注册帐号，按2登录系统，按0退出系统)\n\n\n");     printf("1.注册帐号        2.登录\n\n\n0.退出系统\n\n\n");     printf("请输入您要选择您要选择的操作: "); }  void QKjiemian() {     printf("\n\n\n请选择您需要取款的数目\n\n\n");     printf("1.100        2.200\n\n\n3.500        4.1000\n\n\n");     printf("本银行比较穷，最大只支持1000元的取款，谢谢您的谅解，就算您不谅解也没关系！");     printf("请输入您要选择的操作：\n"); } void CKjiemian(){     printf("\n\n\n请将钞票放入机器\n\n\n");     printf("请输入您的存款数目：\n"); } void GNjiemian(){     printf("\n\n\n请选择您需要进行的操作\n\n\n");     printf("1.存款        2.存款        3.存款        4.取款        5查询余额        0.退出\n\n\n");     printf("请输入您要选择的操作：\n");  } void DLuser(char *euser,char *epassword) {     int num = 0;     do{          printf("请输入您的帐号：\n");         fgets(euser,18,stdin);         printf("请输入您的密码：\n");         fgets(epassword,6,stdin);         if(strcmp(euser,user) == 0 && strcmp(epassword,password) == 0)         {                printf("登录成功！\n");             break;         }            else         {             num++;             printf("您的帐号或者密码输入错误！try again\n");             continue;         }     }while(num < 3);     if(num >= 3)     {         printf("three times error for try! your card hac clocked!\n");     }     else     {         GNjiemian();     } } int main() {     char euser[24] = {0};     char epassword[24] = {0};     int num = 0;     XTjiemian();     do{         scanf("%d",&num);         getchar();         switch(num)         {             case 0:                 printf("感谢使用本系统，欢迎下次再来！\n");                 break;             case 1:                 printf("请输入您要注册的帐号：\n");                 fgets(user,18,stdin);                 printf("请输入您要注册的密码(密码长度限制在6位)：\n");                 fgets(password,6,stdin);                 printf("您的帐号注册成功！\n");                 DLuser(euser,epassword);                 break;             case 2:                 DLuser(euser, epassword);                 break;         }     }while(num);     return 0; }

一般做什么银行软件的 都需要错误处理机制 校验scanf返回值啊  还有错误恢复什么的 还有函数指针定义析构函数啊 留给用户处理的接口

基本语法错误很多，建议先打好基础：  #include <stdio.h> #include <string.h>  char user[18]; char password[6]; void XTjiemian(){ printf("\n\n\n(按1注册帐号，按2登录系统，按0退出系统)\n\n\n"); printf("1.注册帐号        2.登录\n\n\n0.退出系统\n\n\n"); printf("请输入您要选择您要选择的操作"); }  void QKjiemian(){ printf("\n\n\n请选择您需要取款的数目\n\n\n"); printf("1.100        2.200\n\n\n3.500        4.1000\n\n\n"); printf("本银行比较穷，最大只支持1000元的取款，谢谢您的谅解，就算您不谅解也没关系！"); printf("请输入您要选择的操作：\n"); }  void CKjiemian(){ printf("\n\n\n请将钞票放入机器\n\n\n"); printf("请输入您的存款数目：\n"); }  void GNjiemian(){ printf("\n\n\n请选择您需要进行的操作\n\n\n"); printf("1.存款        2.存款        3.存款        4.取款        5查询余额        0.退出\n\n\n"); printf("请输入您要选择的操作：\n"); }   void DLuser(char *euser,char *epassword){ int num = 0; do{ printf("请输入您的帐号：\n"); fgets(euser,18,stdin); printf("请输入您的密码：\n"); fgets(epassword,6,stdin); if(strcmp(euser,user) == 0 && strcmp(epassword,password) == 0){ printf("登录成功！"); break; } else{ num++; printf("您的帐号或者密码输入错误！"); continue; } }while(num < 3); if(num >= 3){ return; } else{ GNjiemian(); printf("请选择您的操作：\n"); } }  int main(){ int num = 0; XTjiemian(); do{ scanf("%d",&num); switch(num){ case 0: printf("感谢使用本系统，欢迎下次再来！\n"); case 1: printf("请输入您要注册的帐号：\n"); fgets(user,18,stdin); printf("请输入您要注册的密码(密码长度限制在6位)：\n"); fgets(password,6,stdin); printf("您的帐号注册成功！\n"); DLuser(user,password); continue; case 2: DLuser(user,password); continue; } }while(num != 0); return 0; }  引用 楼主 u012527966 的回复:#include <stdio.h> #include <string.h>  char user; char password; void XTjiemian(){ 	printf("\n\n\n(按1注册帐号，按2登录系统，按0退出系统)\n\n\n"); 	printf("1.注册帐号        2.登录\n\n\n0.退出系统\n\n\n"); 	printf("请输入您要选择您要选择的操作"); }  void QKjiemian(){ 	printf("\n\n\n请选择您需要取款的数目\n\n\n"); 	printf("1.100        2.200\n\n\n3.500        4.1000\n\n\n"); 	printf("本银行比较穷，最大只支持1000元的取款，谢谢您的谅解，就算您不谅解也没关系！"); 	printf("请输入您要选择的操作：\n"); }  void CKjiemian(){ 	printf("\n\n\n请将钞票放入机器\n\n\n"); 	printf("请输入您的存款数目：\n"); }  void GNjiemian(){ 	printf("\n\n\n请选择您需要进行的操作\n\n\n"); 	printf("1.存款        2.存款        3.存款        4.取款        5查询余额        0.退出\n\n\n"); 	printf("请输入您要选择的操作：\n"); }   void DLuser(char *euser,char *epassword){ 	int num = 0; 	do{ 		printf("请输入您的帐号：\n"); 		fgets(euser,18,stdin); 		printf("请输入您的密码：\n"); 		fgets(epassword,6,stdin); 		if(strcmp(euser,user) == 0 && strcmp(epassword,password) == 0){ 			printf("登录成功！"); 			break; 		} 		else{ 			num++; 			printf("您的帐号或者密码输入错误！"); 			continue; 		} 	}while(num < 3); 	if(num >= 3){ 		return 0; 	} 	else{ 		GNjiemian(); 		printf("请选择您的操作：\n"); 	} }  int main(){ 	char euser,epassword; 	int num = 0; 	XTjiemian(); 	do{ 		scanf("%d",&num); 		switch(num){ 			case 0: 				printf("感谢使用本系统，欢迎下次再来！\n"); 			case 1: 				printf("请输入您要注册的帐号：\n"); 				fgets(user,18,stdin); 				printf("请输入您要注册的密码(密码长度限制在6位)：\n"); 				fgets(password,6,stdin); 				printf("您的帐号注册成功！\n"); 				DLjiemian(euser,epassword); 				continue; 			case 2: 				DLjiemian(euser,epassword); 				continue; 		} 	} }     老师说，要做一个模拟ATM的程序，我关于指针做参数那里实在是有点迷糊，老师也没讲清楚 结果写着写着一大堆错误 哪位大神告诉我哪里错了```````这是还没写完的，关于字符串行参有点不懂，求解释 能改一下错误的地方最好了，容易懂些，非常感谢非常感谢

看你那么低的结贴率本不想回的.......  指针做参数一般在函数调用的时候用的多，字符串，数组，等一些需要修改的数据都要用到指针，以为指针传递就是地址传递这个区别于值传递，  void f(int *a), 比如这个就是用a 来接收传过来的int 数组,记住是一维数组，至于其他的话，自己多看看书吧


Question: C的文件读写fread，fwrite问题

引用 8 楼 InSpirit1 的回复:[quote=引用 1 楼 vrace 的回复:] 其实是读进去了的，但是呢 printf("%s\n", str); 输出到第一个参数里面的结束符\0的时候，就不会输出了。也就是说，你这样写是看不到完整输出的。 哦，我可不可以理解为，每fwrite一个结构体对象，在这个对象的结尾就会有一个\0 ？[/quote]  No， 你错了，fwrite 并不会多写东西。在你的这个例子中，你的结构是两个字符串+2个int, 所以printf显示出来的是第一个字符串。

引用 9 楼 InSpirit1 的回复:[quote=引用 3 楼 max_min_ 的回复:]  fwrite(&task1, sizeof(task1), 1, stream); /* 写的struct文件*/ sleep(1); //可以文件还没写完，就被关闭了！ 试下， 下面的同理     fclose(stream); /*关闭文件*/  //还有你读出来的文件应该按照结构体解析 出来再打印的，不然会有乱码的 struct task *str = (struct task *) malloc(sizeof(task1)); fread(str, fileLen, 1, fp); //这样就可以直接打印各个成员了，不能一下子%s的  //当然也可以用char*读出来，最后强转一下也行！  你好，你的方法我试了试： 	struct task *str = (struct task *)malloc( sizeof(task1)); 	printf("%s", str->TaskNo); 无法编译，报错"不允许指针指向不完整的类类型"，报错位置为str处，这是为什么？[/quote] 把你修改的源码贴出来吧！估计是哪里写错了吧！

引用 3 楼 max_min_ 的回复: fwrite(&task1, sizeof(task1), 1, stream); /* 写的struct文件*/ sleep(1); //可以文件还没写完，就被关闭了！ 试下， 下面的同理     fclose(stream); /*关闭文件*/  //还有你读出来的文件应该按照结构体解析 出来再打印的，不然会有乱码的 struct task *str = (struct task *) malloc(sizeof(task1)); fread(str, fileLen, 1, fp); //这样就可以直接打印各个成员了，不能一下子%s的  //当然也可以用char*读出来，最后强转一下也行！  你好，你的方法我试了试： 	struct task *str = (struct task *)malloc( sizeof(task1)); 	printf("%s", str->TaskNo); 无法编译，报错"不允许指针指向不完整的类类型"，报错位置为str处，这是为什么？

引用 1 楼 vrace 的回复:其实是读进去了的，但是呢 printf("%s\n", str); 输出到第一个参数里面的结束符\0的时候，就不会输出了。也就是说，你这样写是看不到完整输出的。 哦，我可不可以理解为，每fwrite一个结构体对象，在这个对象的结尾就会有一个\0 ？

引用 3 楼 max_min_ 的回复: fwrite(&task1, sizeof(task1), 1, stream); /* 写的struct文件*/ sleep(1); //可以文件还没写完，就被关闭了！ 试下， 下面的同理     fclose(stream); /*关闭文件*/  //还有你读出来的文件应该按照结构体解析 出来再打印的，不然会有乱码的 struct task *str = (struct task *) malloc(sizeof(task1)); fread(str, fileLen, 1, fp); //这样就可以直接打印各个成员了，不能一下子%s的  //当然也可以用char*读出来，最后强转一下也行！ ++

lz 最好查看二进制的文件

你可以将str 定义为结构体的指针 然后str动态分配空间 printf("%s %s %d %d\n", str->TaskNo,str->TaskDesc,str->Timeout,str->Priority); 用上面语句输出，

我觉得楼主 看看二进制的方式。查看数据在底层存放的方式 就会明白

1、用fwrite存入本地文件后，打开文件发现int型的两个数1,2没有写进去，但是task1结构体里面有数 ——“打开文件”？你大概是用windows自带的记事本软件打开a.txt文件的，记事本软件并不是上帝出品，它只负责把文件中的所有二进制数据以ASCII码形式显示在屏幕上，以fwrite直接写到文件中的int型数据它显示不出来。 2、用fread读取文件后，发现只有第一个数据，即NO.0001被读到str中去了，后面的都没读进去 ——printf("%s\n", str);这条语句只打印str指针指向的内存对应的ASCII码，直到遇到第一个0位置，自然不会显示这个0后面的第二个字符串和int型整数等等等等  结论就是，楼主“发现”的方式有问题。文件中有什么，请使用十六进制查看软件查看数据，而不是用记事本打开看ASCII码。结构体中有什么数据，请逐一按格式printf字符串和整型数据，而不是用一个%s代表一切。


Question: 大一新生求解答~0 0

哈哈哈哈哈~~大牛们多谢赐教！！ 我懂了！ 谢谢~~

崩溃啊！再看了看，t等于0了，n=t不也是0了吗

while（t!=0)要是m不小于n就没有t赋值，就出错了

引用 5 楼 u011930458 的回复:[quote=引用 4 楼 Adol1111 的回复:] 改成这样吧：#include<stdio.h> int main() {      int m,n,i,t,s,n1;      scanf("%d%d",&m,&n);      if(m<n)      {          t=m;          m=n;          n=t;      }      t=m%n;      while(t!=0)      {          m=n;          n=t;          t=m%n;//把这句放到最后，n记录上一个余数值      }      printf("%d",n); }  是这样的[/quote] +++ 问题就是两个地方，第一个地方是在比较m和n的大小时，如需要交换m和n的值，则需要用大括号括起来，另一个地方是，t需要初始化，在while中判断之前。

引用 4 楼 Adol1111 的回复:改成这样吧：#include<stdio.h> int main() {      int m,n,i,t,s,n1;      scanf("%d%d",&m,&n);      if(m<n)      {          t=m;          m=n;          n=t;      }      t=m%n;      while(t!=0)      {          m=n;          n=t;          t=m%n;//把这句放到最后，n记录上一个余数值      }      printf("%d",n); }  是这样的

楼上的看错了if(m<n){t=m;m=n;n=t;}//这样才是3句话 你的问题比较多，t没有被指定，if(m<n)成立时，t有确定值，但不成立时t的值是未知的。 还有这里：while(t!=0)     {         t=m%n;//当t=0时，下面的n=t就会变成0，那你打印出来的就是0         m=n;         n=t;     }

if(m<n)      {t=m,m=n,n=t;}//交换记得加{}，这是3句话不是1句话

设置断点，逐步调试，分析结果。这是新手必须要学会的技能，这也是寻找BUG必须会的。


Question: SOCKET 编程  提示找不到send.c

引用 3 楼 user-1 的回复:[quote=引用 2 楼 hfcenter 的回复:] [quote=引用 1 楼 user-1 的回复:] 提示找不到文件是什么意思？应该不是代码问题吧，是环境问题吧！  但是是在执行send()函数4次之后才提示找不到源文件[/quote] 你不是生成一个可执行文件么？执行文件就好了，已经独立开源文件了，还要找不到提示源文件，什么情况？ [/quote] 我是在eclipse中调试，结果运行了几次就出现这种情况

引用 2 楼 hfcenter 的回复:[quote=引用 1 楼 user-1 的回复:] 提示找不到文件是什么意思？应该不是代码问题吧，是环境问题吧！  但是是在执行send()函数4次之后才提示找不到源文件[/quote] 你不是生成一个可执行文件么？执行文件就好了，已经独立开源文件了，还要找不到提示源文件，什么情况？

引用 1 楼 user-1 的回复:提示找不到文件是什么意思？应该不是代码问题吧，是环境问题吧！  但是是在执行send()函数4次之后才提示找不到源文件

提示找不到文件是什么意思？应该不是代码问题吧，是环境问题吧！


Question: 有没有时间复杂度为O（n）空间复杂度为1的排序算法？

你说的对，是我想错了，忽略了使用分离链处理冲突时指针所占用的空间。多谢指正。

引用 14 楼 sbwwkmyd 的回复:有一种桶排序的实现是这样的，先O(n)计算每个桶的大小，然后直接在原数组中定位M个指针交换数据。 有一种桶排序的实现是这样的，先O(n)计算每个桶的数据数量，然后直接在原数组中定位M个指针交换数据。

引用 12 楼 pinghegood 的回复:一般来说对超过基本类型表示的大数或字符串排序，使用基数排序比较好。桶排序适用于基于整形的数值排序（对字符串非要用桶排序的话，需要将字符串使用某种方式转换成整形数值）。对于桶排序，当M = 10，N = 10时我可以排序，N = 100时也可以排序，只是时间复杂度会增加，略大于O(n)，但是空间复杂度还是O(1)。不知道我这样理解是否正确，请指正。这样做的话，时间复杂度难道不是与数据长度成正比吗？引用 13 楼 Adol1111 的回复:桶排序的空间复杂度好像的确不是O(1)，空间复杂度一般算的是辅助空间的大小，如果这个辅助空间的大小不随元素N变化那么就是O(1)。比如冒泡排序，需要的辅助空间是一个作交换用的临时变量，而且无论任何情况下都只要这一个，所以空间复杂度就是O(1)。但桶排序就不同了，他本身需要M个桶，桶的数量是人为决定的，然后需要N个结点，去装原本的N个元素，所以空间复杂度就是O(M+N)，看下图： 有一种桶排序的实现是这样的，先O(n)计算每个桶的大小，然后直接在原数组中定位M个指针交换数据。

好吧，来个实例。我现在要对大数或者字符串排序，请为这个桶大小取个任意值。

可以是任意值，只要这个值不随着待排序数目的变化而变化就行。

桶大小会是O(1)的话，请问这个值是多少？

不好意思，上面的开始的“时间复杂度”改成“空间复杂度”，笔误。完整的为“在算法中所谓的空间复杂度为O(1)并不是说只使用一个空间，而是说在待处理的数据量变化的情况下使用的空间量是不变的。所以，桶排序是空间复杂度为O（1），时间复杂度为O(n)的算法。”

在算法中所谓的时间复杂度为O(1)并不是说只使用一个空间，而是说在待处理的数据量变化的情况下使用的空间量是不变的。所以，桶排序是空间复杂度为O（1），时间复杂度为O(n)的算法。

引用 5 楼 czarten 的回复:基于比较的排序算法nlogn是极限 更快的算法通常有额外条件，或者特殊硬件 另外桶排序的空间不是O（1）吧  记得还有个O(1)时间的排序算法，需要依靠重力

引用 3 楼 taodm 的回复:有啊，桶排序。 +1  设排序数量为N，桶的数量为M，那么： 时间复杂度是：O(N+N*logN-N*logM)，当N=M时就是O(N)了。

有啊，桶排序。

要看有什么额外条件。比如值域固定的话那就有。

没有!!!!!


Question: 数据结构的一个程序有问题，求指点

引用 3 楼 darkucking 的回复:引用 2 楼 u011375704 的回复:首先你这个里面有些函数里面的取地址符号在调试时会被当做引用，C语言引用不行，只有在C++才可以吧那么该怎么改成c的格式呢？ 把引用换成指针形式！赋值的时候取下地址！

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

引用 4 楼 max_min_ 的回复:引用 3 楼 darkucking 的回复:[quote=引用 2 楼 u011375704 的回复:] 首先你这个里面有些函数里面的取地址符号在调试时会被当做引用，C语言引用不行，只有在C++才可以吧那么该怎么改成c的格式呢？ 把引用换成指针形式！赋值的时候取下地址！[/quote]版主大大  我对指针有些头疼  能不能改改一小段让我参考一下

设置断点，逐步调试，分析结果。这是自己解决问题最好的办法。


Question: win7 进程隐藏

引用 2 楼 zhao4zhong1 的回复:奉劝楼主不要把有限的生命浪费在无限的加密解密死循环中！ 实现困难吗？

windows内核编程,hook微软没有公布的API

http://www.codeproject.com/Articles/167583/Driver-to-Hide-Processes-and-Files-Second-Edition 仅供参考。不一定支持Win7

奉劝楼主不要把有限的生命浪费在无限的加密解密死循环中！

没有大神回答么？


Question: 来看看指针字符串细节

因为不懂我还到灌水的地方去问了，跟着他们的做了，我用了平均给分，有5个人，平均每个人8分，但是我到这里因为技术区好像不能平均给分的，所以结贴是给你填的是40的，但是一直出现给的分数和总分数不符和，后来我填20 不行在填10也不行，后面填了3也不行，所以我猜是不是我的分数没有了，我真的不是非常懂，不要误会。

我的意思是我的分好像为0了，本来想给你的，不知到为啥出现给的分与总分数不符和，所以推测分数为零的，我没用过这里的结贴，真的不懂，不要误会哟，真的很感谢你们的

引用 8 楼 cainiao366 的回复:特别感谢大家，我看了，AzraelLamber推荐的帖子，明白了，这贴子我会经常看看，我想结贴贴给分但是出现总分与给分不符和，我知道已经穷了，  分留着吧，帖子结了就行。要不还不知道多少人来吐槽呢。

大家是来帮助你的，随便给点分，结贴就成了，不够攒点分，结贴就成了。 我这是帮你摆脱困境的，提个建议，不必给分。

学而不思则罔，思而不学则殆

不是的！char * str1 = "Made in china";你这杨定义的是在静态区的，数据在静态区的 只能读不可以修改的！当你试图修改它的话，运行起来内存肯定出错了！ 如果char  str1[] = "Made in china"; 后面的拷贝应该是可以的了!  ps:建议楼主看看内存管理这块知识，补补这方面的欠缺！

你的代码大致的意思是  2 =1+1，也就是"Made in china" ="Made in china"+"Where are"  如果你的代码成立的话。那么 n=n+1,就不必存在了。我们应该写成 5=5+1；就行了。  一个玩笑不要介意。

char * str1 = "Made in china";   这个的内存的确不能修改

先看看人家总结的吧： http://blog.csdn.net/lollipop_jin/article/details/8314304

个人建议：遇到问题的时候，别忙着在自己脑中空想各种各样的解释，先去查查有没有相关的基础知识

。。。大哥,你这是企图通过char*指针给常量存放区域的内存赋值，那是不可修改的内存，当然运行出错。 不论你循环不循环，长短不长短都不会成功的，你就死了那条心吧！


Question: 大二数据结构要掌握到什么程度

引用 4 楼 Adol1111 的回复:[quote=引用 3 楼 u012686437 的回复:] [quote=引用 2 楼 Adol1111 的回复:] 不存在大二要掌握多少的问题，如果你真心想学好就必须都会。顺序表、链表、栈、队列、树、图的相关知识及算法。最好看下《算法导论》。  开始的时候先不要在意实现的部分，应该在意的是理论基础，原理是什么，能不能用手写过程求出相应的结果。如果这步都做不到就不要写后面的代码了。实现的部分是指？我是想学好，只是现在代码实在看不大懂，又要考试呢。你的意思是我先看算法先不管代码？[/quote] 对，我说的是代码实现，这部分先不要去管。比如二叉树的先序后序遍历，能否直接根据算法描述用纸笔写出。如果连这些都做不到，那么代码就更加不用写了。还有些理论基础，比如二叉树的度等等，这些也要了解下。  至于代码的部分还是要看你的语言基础，C、C++、Java等等，如果你有语言基础应该没什么问题。如果你语言不好的话，还是回去多练练，多看看书。[/quote]有的比如遍历，求叶子数没给算法直接给代码看得很头疼。但是如果算法看懂了一句一句翻译成代码还是没有问题的。算法导论我觉得现在有点早。毕竟我在学数据结构，一些基本的算法都还没接触到呢。

引用 3 楼 u012686437 的回复:[quote=引用 2 楼 Adol1111 的回复:] 不存在大二要掌握多少的问题，如果你真心想学好就必须都会。顺序表、链表、栈、队列、树、图的相关知识及算法。最好看下《算法导论》。  开始的时候先不要在意实现的部分，应该在意的是理论基础，原理是什么，能不能用手写过程求出相应的结果。如果这步都做不到就不要写后面的代码了。实现的部分是指？我是想学好，只是现在代码实在看不大懂，又要考试呢。你的意思是我先看算法先不管代码？[/quote] 对，我说的是代码实现，这部分先不要去管。比如二叉树的先序后序遍历，能否直接根据算法描述用纸笔写出。如果连这些都做不到，那么代码就更加不用写了。还有些理论基础，比如二叉树的度等等，这些也要了解下。  至于代码的部分还是要看你的语言基础，C、C++、Java等等，如果你有语言基础应该没什么问题。如果你语言不好的话，还是回去多练练，多看看书。

引用 2 楼 Adol1111 的回复:不存在大二要掌握多少的问题，如果你真心想学好就必须都会。顺序表、链表、栈、队列、树、图的相关知识及算法。最好看下《算法导论》。  开始的时候先不要在意实现的部分，应该在意的是理论基础，原理是什么，能不能用手写过程求出相应的结果。如果这步都做不到就不要写后面的代码了。实现的部分是指？我是想学好，只是现在代码实在看不大懂，又要考试呢。你的意思是我先看算法先不管代码？

顺序表，堆栈，链表，二叉树，几种排序算法。

我觉得吧，数据结构学习的精髓还是一种思想，一种思考问题的方式，语言知识工具，你学会了这种算法，用什么语言都可以写出来，只不过需要学习一下这种语言的简单语法罢了。所以，数据结构中的递归，调用，将一些数据封装到结构体中，对于一个结构体定义一些基本操作，再利用基本操作去进行编程，这些思考问题的方式才是真正应该掌握的。

引用 9 楼 chenailun1990 的回复:刚开始上数据结构吗上了有一段时间了，不过不太习惯

引用 10 楼 szllong123 的回复:很现实的告诉你，如果仅为了考试一个都不用会写出来。实际应用的话自然是都需要了。但是考试肯定会有程序设计的题目的，不会怎么行呢

读书学习：http://bbs.csdn.net/topics/390090123

很现实的告诉你，如果仅为了考试一个都不用会写出来。实际应用的话自然是都需要了。

刚开始上数据结构吗

引用 7 楼 Adol1111 的回复:你不需要写出算法的代码，只要算法的步骤就可以了。最好学会用伪代码、流程图写出过程。嗯。我会试着自己想算法的。谢谢啦

引用 5 楼 u012686437 的回复:有的比如遍历，求叶子数没给算法直接给代码看得很头疼。但是如果算法看懂了一句一句翻译成代码还是没有问题的。算法导论我觉得现在有点早。毕竟我在学数据结构，一些基本的算法都还没接触到呢。 你应该先了解下基础，比如什么是叶子节点等等，然后根据你自己的理解去设计算法，然后和书上的比对（当然书上可能分成了递归版和非递归版），这样学习更有效率些。  至于算法导论的话，里面有数据结构的部分和算法部分，没说让你直接学算法，而且这本书也不一定要按顺序看。你可以去了解下，这本书学算法、数据结构都很不错的。


Question: 求帮助！一个菜鸟遇到的C语言编程题

引用 1 楼 max_min_ 的回复: // 是素数返回true，不是返回false， 调用这个函数就好！楼主找本基础书补补基础吧！ bool testfunc( int a) {     int i= 0;     if (a == 2 )          return true;     for(i=2; i<a; i++)     {            if(a%i == 0)             return false;     }        return true; }  这里a可以优化为sqrt(a)+1

参考http://blog.csdn.net/turingo/article/details/8161061  引用 楼主 u012435478 的回复:最近学了调用函数，遇到了问题。问题是：用调用函数的方法判断一个数字是不是素数。请求各位帮助

只要 i<sqr(a) 就够了。

引用 5 楼 AnYidan 的回复: bool isPrime(int number)				// 求素数 {  	int i; 	int k;  	k = (int)sqrt((double)number);      // 用平方根，而非用number/2，相对提高速度sqrt(number)/2倍 	for(i = 2; i <= k; i++) 	{ 		if(number%i==0)  			break; 	} 	if (i > k)  return true;	// 没有找到可以整除的除数，被除数是 prime number 	else   return false; }  ++ 这种方法的效率还是比较高的。

[quote=引用 1 楼 max_min_ 的回复:] [code=c] // 是素数返回true，不是返回false， 调用这个函数就好！楼主找本基础书补补基础吧！ bool testfunc( int a) {     int i= 0

// 是素数返回1，否则返回0 int isSuShu(unsigned x) {     int i = 0;     if (x == 2 )          return 1;     for(i = 2; i < x; i++)     {            if(x % i == 0)             return 0;     }        return 1; }


Question: typedef 如何理解

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

引用 7 楼 AnYidan 的回复:const char* ptr: ptr is a pointer, point to a constant character  char* const ptr: ptr is a constant pointer, point to a characterre

const Stu_pst stu3; Stu_pst const stu4;  这2个表达了同一个意思，区别就是没有给stu4初始化，而typedef的理解很简单  const Stu_pst stu3; 表示 stu3这个struct的内容是可以修改的，但stu3所在的内存地址不可变。  Stu_pst const stu4; 表示stu4指针本身不能被修改，而stu4指向的数组内容是可以修改的。即stu4只能指向固定地址，不可改变。

看完就明白了 http://www.cnblogs.com/csyisong/archive/2009/01/09/1372363.html

const Stu_pst stu3; 指针常量  Stu_pst const stu4; 常量指针 具体的不明白可以google下两者的区别！

typedef就是其别名，就比如int类型，我们可以给它另一个名字，不过代表的都是同样的类型。就像一个人有两个名字，大名和小名。

const Stu_pst stu3; Stu_pst const stu4;  其实这两句是一样的，只是两种不同的写法，都表示常量指针，也就是说这两个指针都必须初始化而且不能再被赋值，不信的话你可以试试不初始化stu3和stu4肯定编译报错  另外一种叫指向常量的指针 如:const Stu_st *stu_p; 这种指针可以不初始化

const type*是该变量指向的内容不能修改. type* const是指针变量自己不能被修改.


Question: VC下用C语言控制串口接收数据

引用 5 楼 singaporeraining 的回复:[quote=引用 2 楼 lt114896 的回复:] 串口的操作和socket操作是差不多的，看你用什么方式打开串口了。用writefile方式打开的话，可以一直读，线程循环去读就可以了  您好，我就是打算用ReadFile这种方式打开（因为我刚开始接触，只知道这一种方法），如果我这么一直循环读下去的话，能否出现读取返回值和判断的时候，错过了下位机发给串口的数据这种现象？ 谢谢您！[/quote] windows串口一般有两种方式，windows API 或者使用控件。 如果是那种主从模式，使用windows API比较好，发了数据之后就等待接收。 否则就使用控件，当收到数据时，触发系统的中断事件，控件已经分装好了，在对应位置填代码就行。 串口有自己的缓冲，不会出现你所说的错过数据的现象。

已经结贴完毕，谢谢各位的指点！~

引用 2 楼 lt114896 的回复:串口的操作和socket操作是差不多的，看你用什么方式打开串口了。用writefile方式打开的话，可以一直读，线程循环去读就可以了  您好，我就是打算用ReadFile这种方式打开（因为我刚开始接触，只知道这一种方法），如果我这么一直循环读下去的话，能否出现读取返回值和判断的时候，错过了下位机发给串口的数据这种现象？ 谢谢您！

引用 3 楼 baichi4141 的回复:PC会一直操作串口接收数据并轮询串口接收的buffer，查看是否有数据收到 那我在程序中应该循环发送ReadFile，发送之后就检查Bool类型的返回值，查到返回值为TRUE时，再读取buffer？类似于： do {     tmp= ReadFlie（...);     if(tmp == TRUE)     {         读取buffer；  break；     } } while（1）； 您是这个意思么？还是这个过程由PC完成，如果PC能完成，我需要怎么写呢？多谢您了！~

PC会一直操作串口接收数据并轮询串口接收的buffer，查看是否有数据收到

只能遍历查询, 没有数据则sleep一会, 一般Sleep(10).  串口本身就是低速设备

不会错过的，下位机发送东西上来的时候是在你的缓冲区里，你不读的话他不会消失，你在while循环里检测是可以检测到的

网上有很多 vc++写的串口程序

可以考虑创建线程处理数据


Question: 关于循环语句

//e是循环执行条件，满足继续执行，不满足结束循环。 do {   s; }while(e); //为了和while循环区别开来， // do 。。。while循环的 while语句， //直接写在大括号后面,是个好习惯。 //

1.一般的情况是：在循环次数已经知道的情况下，都可用。而在循环次数未知，但结束循环的条件知道的情况下，一般用while。 2.如果想在判断条件之前，先执行一次，就可用do  while 3.至于花括号，如果你的语句不止一句，则需要花括号，否则不需要，很好判断的。

挑选循环类型，可以通过以下方法：  1）执行前，要做一点初始化的，用 for  2）不做初始化，上来就判断是否可以执行的,用 while //先判断，后执行。  3）不做初始化，上来就执行一次，才开始判断是否可以继续执行的用 do{ s ;}while(e);////先执行，后判断，

不知道，怎么用循环，一律带大括号即可。  //  e2 是循环执行条件，满足执行，不满足结束循环。 //  e1 在循环开始，执行一些代码。 //  e3;循环体，执行后；在执行一些代码，一般是自增，自减等等。  for(e1;e2;e3){    s; } //e是循环执行条件，满足执行，不满足结束循环。 while(e){   s; } //e是循环执行条件，满足继续执行，不满足结束循环。 do {   s; }while(e);

//1)用while 实现 for 的功能。    for(e1;e2;e3)s;    //while 实现 for 的功能     {        e1;//       while(e2){         s;         e3;       }    } //2)用while 实现 do ...while(); 的功能。      do s while(e);     //while 实现 do ...while(); 的功能     s;     while(e)s; 3)用 for 实现 do ...while(); 的功能。     do s while(e);     //for 实现 do ...while(); 的功能    s;    for(;e;)s;        4)用 for 实现 while(); 的功能。     while(e)s;     //for 实现 do ...while(); 的功能     for(;e;)s;   5) 用do ... while(); 实现 while(); 的功能。    while(e) s;    do ... while(); 实现 while(); 的功能。     {       bool started =false;       do {       if (!started){started =true;}       else s ;      }while(e);    } 6）用do ... while(); 实现for; 的功能。    for(e1,e2,e3) s;    do ... while(); 实现for; 的功能。          {       bool started =false;       e1;         do {       if (!started){started =true;}       else s ;       e3;       }while(e2);    }  PS： C,C++ 三种循环，几乎是一样的。 区别很小，都是当型循环。

差别不大，并且可以互相转换，语句格式有所差别而已，正常使用下 for和while、do while(....){...}都是先判断条件是否成立而做块的操作 do { }while(...) 这种形式是先干一下，再由while决定是否继续干

一般情况都是可以通用的！用那个主要是个人习惯而已， 可能有些特定的语境需要才有细微的区别！ 个人习惯：无限循环一般都是while，条件循环用for，do while很少用，除非特别需要，什么先运行再判断的

花括号在C语言里是一个语句块的标示，就是说花括号括起来的语句是一个语句快，在循环里称之为循环体，就是每次循环都会执行的语句。

条件具有不确定性，条件不成立不执行的用while,给出明确条件的用for,条件具有不确定性但必须执行的用do{}while,

花括号对称就好

等你用多了，你就知道用哪个了。循环都差不多的。多敲几遍代码，自然就明白了

都是循环，想用那个就用那个。关于总是写错的问题， 1.你写的太少了 2.你编程习惯不怎么好，注意书写格式和排版问题就可以了

我觉得do-while语句基本上可以不用，因为while语句完全可以取代 主要是用for和while 其次for也可以取代while for( ; ; ) {  } 其实就相当于 while(1) {     }  格式其实就是: 关键字 (条件) {   循环体 }  do-while特别一点 do {  } while (); //分号不能忘


Question: C语言奇怪指针问题

T++之后，移动了指针位置，当然没了！

正常输出结果！没有破坏上面的！楼主重新编译下试试吧！可能是环境的原因吧！  $ ./a.out  a  a

估计Get_Next里下标越界操作破坏数组b了，学习用debugger自己调试代码...

while (*T)     {         //这里的T 在自己加 所以要多一个P          //因为题目要求不能求子串的长度         //然后这里的字符串给近来从0开始 但是这里计算的是从1开始         if(j==0||p[j-1]==p[i-1])         {             i++;             j++;             next[i]=j;             T++;         }         else             j=next[j];               } 看看这里有没有越界 看看    char a[10]="abaabc";     char b[40]="abaaabaabcababaabc"; 的地址，是不是越界把b里的值改变了

引用 10 楼 u011488256 的回复:[quote=引用 9 楼 szllong123 的回复:] int main() {         //下面的代码是子串和主串做比较的         char a[10]="abaabc";         char b[40]="abaaabaabcababaabc";         char *q=b;         printf("%c\n",*q);   //问题 出在这里 这个时候*q可以正常的输出a         printf("the pointer add of q is %ld:\n",q);         int next[7];         int i=0;         int count=0;         Get_Next(a,next);         printf("the pointer add of q is %ld:\n",q);         printf("%c\n",*q);   //每次执行了上面的函数后这个*q系统就没有值了 不知道 为什么  很奇怪         return 0; }  附上更改的地方  我跟你在相同的地方 加上了输出地址，第二次输出位置的时候就死了··[/quote] e,那就不晓得了，这个地址就是b[0]的地址，应该不会有问题

引用 9 楼 szllong123 的回复:int main() {         //下面的代码是子串和主串做比较的         char a[10]="abaabc";         char b[40]="abaaabaabcababaabc";         char *q=b;         printf("%c\n",*q);   //问题 出在这里 这个时候*q可以正常的输出a         printf("the pointer add of q is %ld:\n",q);         int next[7];         int i=0;         int count=0;         Get_Next(a,next);         printf("the pointer add of q is %ld:\n",q);         printf("%c\n",*q);   //每次执行了上面的函数后这个*q系统就没有值了 不知道 为什么  很奇怪         return 0; }  附上更改的地方  我跟你在相同的地方 加上了输出地址，第二次输出位置的时候就死了··

引用 7 楼 szllong123 的回复:[quote=引用 6 楼 u011488256 的回复:] 什么说b被破坏的朋友··看看我的函数根本就没有 传b这个数组， b这个数组一直都没有用到的！   我的T++ 改变了   [quote=引用 5 楼 szllong123 的回复:] T++之后，移动了指针位置，当然没了！  什么东西没了？ 能先看下代码行不大哥[/quote] 不好意思确实是我看错了，我运行了你的程序是没问题的，并且打印q指向的地址也是没问题的，不知道你出错在什么地方。 附上打印结果：a the pointer add of q is 140733257222288: the pointer add of q is 140733257222288: a 我用的是，gcc 版本 4.8.2 20131017 (Red Hat 4.8.2-1) (GCC)编译器 [/quote] 郁闷了啊··我用的VC 6.0  奇怪了 那我自己在看看

引用 6 楼 u011488256 的回复:什么说b被破坏的朋友··看看我的函数根本就没有 传b这个数组， b这个数组一直都没有用到的！   我的T++ 改变了   [quote=引用 5 楼 szllong123 的回复:] T++之后，移动了指针位置，当然没了！  什么东西没了？ 能先看下代码行不大哥[/quote] 不好意思确实是我看错了，我运行了你的程序是没问题的，并且打印q指向的地址也是没问题的，不知道你出错在什么地方。 附上打印结果：a the pointer add of q is 140733257222288: the pointer add of q is 140733257222288: a 我用的是，gcc 版本 4.8.2 20131017 (Red Hat 4.8.2-1) (GCC)编译器

什么说b被破坏的朋友··看看我的函数根本就没有 传b这个数组， b这个数组一直都没有用到的！   我的T++ 改变了   引用 5 楼 szllong123 的回复:T++之后，移动了指针位置，当然没了！  什么东西没了？ 能先看下代码行不大哥


Question: 动态分配内存这样做出问题了？想了很久，求解！

引用 5 楼 CCZZGG1111 的回复:按你的讲的，改了是对的？但想不清楚哪里搞错了。这里是指针函数，返回值是个地址，p指向这个地址？怎么会编译出错？  函数返回的是一个指针的值，然后用一个同类型的指针变量去接收一下就好了。 就相当于一个赋值。所以int*那里是多余的。  类比一下普通的，比如下面：  int num = fun();  int fun(){ 	int temp = 10086; 	return temp; } 不可能写成int num = int fun();这个样子吧。。。

此外，malloc后分配的空间，记得在程序最后要free掉~~~ 还有就是美观上再看看。

你进行编译时，编译器肯定会提示你错误的位置吖~~ 这个地方p=int*pSt(&n)，int*是多余的。

p=int*pSt(&n);  这里写错了吧，你是想 (int*)pSt(&n);吧

最好避免分配0个字节的内存，VS2008在调试版本下分配0个字节会成功，但在释放的时候会由于断点挂掉。


Question: 新人求助，关于 Tiny C Compiler如何配置

而且，TCC很小，你把他放到VC里编译吧，很容易的。

TCC的所谓效率，是指“编译效率”，编译速度快。并不是说，它编译生成的代码真比VC或者GCC快。

其实，效率概念对于编译器来说，是个很不确定性的概念。比如说memcopy这样的函数，对于常量长度，它会给你转换成指令序列，对于变量会转换成循环。对于特别高性能英语，你会发现一段特别没意思的代码，那是为常量准备的。不管你是初学还是什么学，gcc足够你用了。

我下载了winGL，但是……晕了

参考：C:\Tiny C Compiler\Tiny C Compiler Reference Documentation.mht

这个我也想研究下。


Question: C语言函数指针问题

引用 14 楼 jiandingzhe 的回复:[quote=引用 5 楼 szllong123 的回复:] [quote=引用 2 楼 user-7 的回复:] 函数参数为函数指针类型或函数类型时，传递的都是函数指针，应该无区别 int f(int(*alg)(int a,int b),int a,int b)  //参数1为函数指针类型 int f(int(alg)(int a,int b),int a,int b)   //参数1为函数类型 我是想问这两种在实际中有什么差别，是按照传值传地址什么说法么，怎么运行的？[/quote] 函数体传个啥值, 就是简便写法而已.  你如果要简化, 可以用typedef.  typedef int (*AlgorithmType) (int, int);  ... MyFunc(AlgorithmType op, ......) [/quote] 这个我知道，就是从这样改过来的！

引用 5 楼 szllong123 的回复:[quote=引用 2 楼 user-7 的回复:] 函数参数为函数指针类型或函数类型时，传递的都是函数指针，应该无区别 int f(int(*alg)(int a,int b),int a,int b)  //参数1为函数指针类型 int f(int(alg)(int a,int b),int a,int b)   //参数1为函数类型 我是想问这两种在实际中有什么差别，是按照传值传地址什么说法么，怎么运行的？[/quote] 函数体传个啥值, 就是简便写法而已.  你如果要简化, 可以用typedef.  typedef int (*AlgorithmType) (int, int);  ... MyFunc(AlgorithmType op, ......)

用gcc汇编之后是这样的，我gcc 版本 4.8.2 20131017 (Red Hat 4.8.2-1) (GCC)         .file   "main.cpp"         .text         .globl  _Z2f1PFiiiEii         .type   _Z2f1PFiiiEii, @function _Z2f1PFiiiEii: .LFB0:         .cfi_startproc         pushq   %rbp         .cfi_def_cfa_offset 16         .cfi_offset 6, -16         movq    %rsp, %rbp         .cfi_def_cfa_register 6         subq    $16, %rsp         movq    %rdi, -8(%rbp)         movl    %esi, -12(%rbp)         movl    %edx, -16(%rbp)         movl    -16(%rbp), %ecx         movl    -12(%rbp), %edx         movq    -8(%rbp), %rax         movl    %ecx, %esi         movl    %edx, %edi         call    *%rax         leave         .cfi_def_cfa 7, 8         ret         .cfi_endproc .LFE0:         .size   _Z2f1PFiiiEii, .-_Z2f1PFiiiEii         .globl  _Z2f2PFiiiEii         .type   _Z2f2PFiiiEii, @function _Z2f2PFiiiEii: .LFB1:         .cfi_startproc         pushq   %rbp         .cfi_def_cfa_offset 16         .cfi_offset 6, -16         movq    %rsp, %rbp         .cfi_def_cfa_register 6         subq    $16, %rsp         movq    %rdi, -8(%rbp)         movl    %esi, -12(%rbp)         movl    %edx, -16(%rbp)         movl    -16(%rbp), %ecx         movl    -12(%rbp), %edx         movq    -8(%rbp), %rax         movl    %ecx, %esi         movl    %edx, %edi         call    *%rax         leave         .cfi_def_cfa 7, 8         ret         .cfi_endproc .LFE1:         .size   _Z2f2PFiiiEii, .-_Z2f2PFiiiEii         .globl  _Z3addii         .type   _Z3addii, @function _Z3addii: .LFB2:         .cfi_startproc         pushq   %rbp         .cfi_def_cfa_offset 16         .cfi_offset 6, -16         movq    %rsp, %rbp         .cfi_def_cfa_register 6         movl    %edi, -4(%rbp)         movl    %esi, -8(%rbp)         movl    -8(%rbp), %eax         movl    -4(%rbp), %edx         addl    %edx, %eax         popq    %rbp         .cfi_def_cfa 7, 8         ret         .cfi_endproc .LFE2:         .size   _Z3addii, .-_Z3addii         .globl  _Z3subii         .type   _Z3subii, @function _Z3subii: .LFB3:         .cfi_startproc         pushq   %rbp         .cfi_def_cfa_offset 16         .cfi_offset 6, -16         movq    %rsp, %rbp         .cfi_def_cfa_register 6         movl    %edi, -4(%rbp)         movl    %esi, -8(%rbp)         movl    -8(%rbp), %eax         movl    -4(%rbp), %edx         subl    %eax, %edx         movl    %edx, %eax         popq    %rbp         .cfi_def_cfa 7, 8         ret         .cfi_endproc .LFE3:         .size   _Z3subii, .-_Z3subii         .section        .rodata .LC0:         .string " %d+%d=%d\n" .LC1:         .string " %d-%d=%d\n"         .text  .globl  main         .type   main, @function main: .LFB4:         .cfi_startproc         pushq   %rbp         .cfi_def_cfa_offset 16         .cfi_offset 6, -16         movq    %rsp, %rbp         .cfi_def_cfa_register 6         subq    $16, %rsp         movl    $1, -4(%rbp)         movl    $2, -8(%rbp)         movl    -8(%rbp), %edx         movl    -4(%rbp), %eax         movl    %eax, %esi         movl    $_Z3addii, %edi         call    _Z2f1PFiiiEii         movl    %eax, %ecx         movl    -8(%rbp), %edx         movl    -4(%rbp), %eax         movl    %eax, %esi         movl    $.LC0, %edi         movl    $0, %eax         call    printf         movl    -8(%rbp), %edx         movl    -4(%rbp), %eax         movl    %eax, %esi         movl    $_Z3subii, %edi         call    _Z2f2PFiiiEii         movl    %eax, %ecx         movl    -8(%rbp), %edx         movl    -4(%rbp), %eax         movl    %eax, %esi         movl    $.LC1, %edi         movl    $0, %eax         call    printf         movl    $0, %eax         leave         .cfi_def_cfa 7, 8         ret         .cfi_endproc .LFE4:         .size   main, .-main         .ident  "GCC: (GNU) 4.8.2 20131017 (Red Hat 4.8.2-1)"         .section        .note.GNU-stack,"",@progbits

我觉得我得把源码再贴出来一边  #include <stdio.h>  int f1(int(*alg)(int a,int b),int a,int b) {         return alg(a,b); } int f2(int(alg)(int a,int b),int a,int b) {         return alg(a,b); } int add(int a,int b) {         return a+b; } int sub(int a,int b) {         return a-b; } int main() {         int a=1,b=2;         printf(" %d+%d=%d\n",a,b,f1(add,a,b));         printf(" %d-%d=%d\n",a,b,f2(sub,a,b));         return 0; }

_Z2f1PFiiiEii: .LFB0:         .cfi_startproc         pushq   %rbp         .cfi_def_cfa_offset 16         .cfi_offset 6, -16         movq    %rsp, %rbp         .cfi_def_cfa_register 6         subq    $16, %rsp         movq    %rdi, -8(%rbp)         movl    %esi, -12(%rbp)         movl    %edx, -16(%rbp)         movl    -16(%rbp), %ecx         movl    -12(%rbp), %edx         movq    -8(%rbp), %rax         movl    %ecx, %esi         movl    %edx, %edi         call    *%rax         leave         .cfi_def_cfa 7, 8         ret         .cfi_endproc .LFE0:         .size   _Z2f1PFiiiEii, .-_Z2f1PFiiiEii         .globl  _Z2f2PFiiiEii         .type   _Z2f2PFiiiEii, @function _Z2f2PFiiiEii: .LFB1:         .cfi_startproc         pushq   %rbp         .cfi_def_cfa_offset 16         .cfi_offset 6, -16         movq    %rsp, %rbp         .cfi_def_cfa_register 6         subq    $16, %rsp         movq    %rdi, -8(%rbp)         movl    %esi, -12(%rbp)         movl    %edx, -16(%rbp)         movl    -16(%rbp), %ecx         movl    -12(%rbp), %edx         movq    -8(%rbp), %rax         movl    %ecx, %esi         movl    %edx, %edi         call    *%rax         leave         .cfi_def_cfa 7, 8         ret         .cfi_endproc  我自己汇编了下是这样的

就好比形参你用个数组，也会退化成指针。typedef吧，让代码清楚易读...

引用 7 楼 u012503290 的回复:23:       printf(" %d+%d=%d\n",a,b,f(add,a,b)); 0040B8A6   mov         eax,dword ptr [ebp-8] 0040B8A9   push        eax 0040B8AA   mov         ecx,dword ptr [ebp-4] 0040B8AD   push        ecx 0040B8AE   push        offset @ILT+10(_add) (0040100f) 0040B8B3   call        @ILT+5(_f) (0040100a) 0040B8B8   add         esp,0Ch 0040B8BB   push        eax 0040B8BC   mov         edx,dword ptr [ebp-8] 0040B8BF   push        edx 0040B8C0   mov         eax,dword ptr [ebp-4] 0040B8C3   push        eax 0040B8C4   push        offset string " %d+%d=%d\n" (00420fa8) 0040B8C9   call        printf (00401090) 0040B8CE   add         esp,10h 25:       printf(" %d+%d=%d\n",a,b,ff(add,a,b)); 0040B8FC   mov         edx,dword ptr [ebp-8] 0040B8FF   push        edx 0040B900   mov         eax,dword ptr [ebp-4] 0040B903   push        eax 0040B904   push        offset @ILT+10(_add) (0040100f) 0040B909   call        @ILT+20(_ff) (00401019) 0040B90E   add         esp,0Ch 0040B911   push        eax 0040B912   mov         ecx,dword ptr [ebp-8] 0040B915   push        ecx 0040B916   mov         edx,dword ptr [ebp-4] 0040B919   push        edx 0040B91A   push        offset string " %d+%d=%d\n" (00420fa8) 0040B91F   call        printf (00401090) 0040B924   add         esp,10h 两种调用方法都一样，都是直接push函数指针。 你这个汇编有问题把，我在主函数中已经改成了两个都用的函数f

引用 8 楼 szllong123 的回复:[quote=引用 7 楼 u012503290 的回复:] 23:       printf(" %d+%d=%d\n",a,b,f(add,a,b)); 0040B8A6   mov         eax,dword ptr [ebp-8] 0040B8A9   push        eax 0040B8AA   mov         ecx,dword ptr [ebp-4] 0040B8AD   push        ecx 0040B8AE   push        offset @ILT+10(_add) (0040100f) 0040B8B3   call        @ILT+5(_f) (0040100a) 0040B8B8   add         esp,0Ch 0040B8BB   push        eax 0040B8BC   mov         edx,dword ptr [ebp-8] 0040B8BF   push        edx 0040B8C0   mov         eax,dword ptr [ebp-4] 0040B8C3   push        eax 0040B8C4   push        offset string " %d+%d=%d\n" (00420fa8) 0040B8C9   call        printf (00401090) 0040B8CE   add         esp,10h 25:       printf(" %d+%d=%d\n",a,b,ff(add,a,b)); 0040B8FC   mov         edx,dword ptr [ebp-8] 0040B8FF   push        edx 0040B900   mov         eax,dword ptr [ebp-4] 0040B903   push        eax 0040B904   push        offset @ILT+10(_add) (0040100f) 0040B909   call        @ILT+20(_ff) (00401019) 0040B90E   add         esp,0Ch 0040B911   push        eax 0040B912   mov         ecx,dword ptr [ebp-8] 0040B915   push        ecx 0040B916   mov         edx,dword ptr [ebp-4] 0040B919   push        edx 0040B91A   push        offset string " %d+%d=%d\n" (00420fa8) 0040B91F   call        printf (00401090) 0040B924   add         esp,10h 两种调用方法都一样，都是直接push函数指针。 你这个汇编有问题把，我在主函数中已经改成了两个都用的函数f[/quote] 自己改了下： f(int(*alg)(int a,int b),int a,int b) ff(int(alg)(int a,int b),int a,int b) so~

实际中编译的时候都是按函数指针来处理的，后者是“隐式”的

引用 2 楼 user-7 的回复:函数参数为函数指针类型或函数类型时，传递的都是函数指针，应该无区别 int f(int(*alg)(int a,int b),int a,int b)  //参数1为函数指针类型 int f(int(alg)(int a,int b),int a,int b)   //参数1为函数类型 我是想问这两种在实际中有什么差别，是按照传值传地址什么说法么，怎么运行的？

2楼，果断mark！

typedef

搞错了，没注意到，这是从网上直接拷贝的，主函数应该是 void main() {//函数指针初步应用 	int a=1,b=2; 	printf(" %d+%d=%d\n",a,b,f(add,a,b)); 	printf(" %d-%d=%d\n",a,b,f(sub,a,b)); }


Question: typedef的用法

引用 3 楼 liuhongwei110 的回复:[quote=引用 楼主 qdlgdx_lsy 的回复:] 下面的代码来自《unix环境高级编程》中一个关于“遍历文件层次结构，得到各种类型的文件数”的程序。下面是声明部分：  typedef int Myfunc(const char *, const struct stat *, int) static Myfunc myfunc; static int myftw(char *, Myfunc *); static int dopath(Myfunc *); 不知道typedef在这里是什么意思？并且有什么好处？  typedef int Myfunc(const char *, const struct stat *, int) 这里typedef的意思是申明一个Myfunc函数类型，它的返回类型为int ,参数有三个，第一个为const char*,第二个为const struct stat*,第三个为int.  谭浩强的C语言上关于typedef讲得很详细，建议去看看。  [/quote]  这里typedef的意思是申明一个Myfunc函数类型，它的返回类型为int ,参数有三个，第一个为const char*,第二个为const struct stat*,第三个为int.  ++

typedef主要就是把复杂的类型声明变成简单的名称，方便以后使用。还有一点就是可以方便修改，比如：typedef long long Long; Long A(Long){}如果我有很多地方使用了这个类型，但我突然发现我现在想改成unsigned long，那我只要修改typedef就可以了。 typedef int Myfunc(const char *, const struct stat *, int);//这里声明的是一个函数指针类型 static Myfunc myfunc;//用新定义的类型，声明一个变量 static int myftw(char *, Myfunc *);//用该类型的变量做参数 static int dopath(Myfunc *);看下这里一个简单的函数指针的例子

接下来就可以用Myfunc去申明变量了，如下面的一句static  Myfunc myfunc;

引用 楼主 qdlgdx_lsy 的回复:下面的代码来自《unix环境高级编程》中一个关于“遍历文件层次结构，得到各种类型的文件数”的程序。下面是声明部分：  typedef int Myfunc(const char *, const struct stat *, int) static Myfunc myfunc; static int myftw(char *, Myfunc *); static int dopath(Myfunc *); 不知道typedef在这里是什么意思？并且有什么好处？  typedef int Myfunc(const char *, const struct stat *, int) 这里typedef的意思是申明一个Myfunc函数类型，它的返回类型为int ,参数有三个，第一个为const char*,第二个为const struct stat*,第三个为int.  谭浩强的C语言上关于typedef讲得很详细，建议去看看。

好处就是简洁，明了

用途四：   为复杂的声明定义一个新的简单的别名。方法是：在原来的声明里逐步用别名替换一部  分复杂声明，如此循环，把带变量名的部分留到最后替换，得到的就是原声明的最简化  版。   http://www.cnblogs.com/csyisong/archive/2009/01/09/1372363.html  用在这里使得后来的开发者可以通过替换myfunc来改变这个函数的实现。自定义功能。


Question: 写一程序判断栈是否破坏

引用 4 楼 worldy 的回复:栈破坏了，程序还能运行？还能有机会检查是否被破坏？ 栈可以自行设置，虽然我们一般都不设置。  你在调用某个函数前，把堆栈切换到一个专用堆栈； 可以用这个专用堆栈，检测栈破坏问题。  因为你可以通过捕获异常，检测堆栈破坏。  这是只是一种测试技巧，而不是通用技术。

栈破坏了，程序还能运行？还能有机会检查是否被破坏？

引用 2 楼 lm_whales 的回复:假设栈空间大小为 x个页面， 申请x+2个页面 并设置page 0,page x+1 的属性为警戒页面  如果有警戒异常发生，则为栈被破坏 你貌似解决了我无法检测的问题，我要去实践一下。

栈被破坏的标准是什么呢？ 我谈谈自己的看法吧：假如入栈的顺序是a,b,c,d.则出栈的顺序应该有：d,c,b,a ; a,b,c,d; b,c,d,a; c,d,b,a;  现在你可以用一道程序判断，使得当前栈中的元素全部出栈，然后看看是否匹配预期的出栈方式中的一种，假如不匹配的话说明栈被破坏了。 还有一种破坏是栈使用的空间不合法，比如开辟包含了比本身所能容纳的更多元素，这中破坏我没办法检测。


Question: 关于for循环的一个很奇怪的问题，望大神解决~~

引用 13 楼 Adol1111 的回复:[quote=引用 4 楼 u011248694 的回复:] [quote=引用 2 楼 user-6 的回复:] The c programming language里面有这样一段话：In C, all variables must be declared before they are used, usually at the beginning of the function before any executable statements.   变量的声明要在一个函数可执行语句的前面。或者是在语句块（被{}包括的一段代码）的最前面（同样也是在可执行语句的前面）。 但是我并没有在最前面也可以啊，就是在strcpy函数前面就可以了啊。[/quote] 变量声明、定义不是执行语句，函数调用，赋值操作（定义时赋值不算）、for、while等等都是执行语句。  只要执行语句一出现，后面就不能再定义和声明对象了。第一句执行语句之前的都算最前面...[/quote] 非常感谢，我现在懂了。

引用 4 楼 u011248694 的回复:[quote=引用 2 楼 user-6 的回复:] The c programming language里面有这样一段话：In C, all variables must be declared before they are used, usually at the beginning of the function before any executable statements.   变量的声明要在一个函数可执行语句的前面。或者是在语句块（被{}包括的一段代码）的最前面（同样也是在可执行语句的前面）。 但是我并没有在最前面也可以啊，就是在strcpy函数前面就可以了啊。[/quote] 变量声明、定义不是执行语句，函数调用，赋值操作（定义时赋值不算）、for、while等等都是执行语句。  只要执行语句一出现，后面就不能再定义和声明对象了。第一句执行语句之前的都算最前面...

引用 10 楼 baichi4141 的回复:[quote=引用 4 楼 u011248694 的回复:] [quote=引用 2 楼 user-6 的回复:] The c programming language里面有这样一段话：In C, all variables must be declared before they are used, usually at the beginning of the function before any executable statements.   变量的声明要在一个函数可执行语句的前面。或者是在语句块（被{}包括的一段代码）的最前面（同样也是在可执行语句的前面）。 但是我并没有在最前面也可以啊，就是在strcpy函数前面就可以了啊。[/quote] 如果你知道什么叫可执行语句[/quote] 好吧，我错了。

VS下.c文件默认调用的是C编译器，.cpp默认调用C++编译器  C89标准不支持任意位置定义变量，只能定义在函数的开头。C99可以定义在任意位置，不过目前只有CLang是默认C99的编译器，gcc要加-std=c99编译选项，比如gcc -std=c99 tset.c -o test，VS下还不支持C99标准。不过听说VS2013已经完全支持C99了，不过我没试过。

引用 4 楼 u011248694 的回复:[quote=引用 2 楼 user-6 的回复:] The c programming language里面有这样一段话：In C, all variables must be declared before they are used, usually at the beginning of the function before any executable statements.   变量的声明要在一个函数可执行语句的前面。或者是在语句块（被{}包括的一段代码）的最前面（同样也是在可执行语句的前面）。 但是我并没有在最前面也可以啊，就是在strcpy函数前面就可以了啊。[/quote] 如果你知道什么叫可执行语句

引用 8 楼 u012503290 的回复:在C89标准中，变量声明语句必须放在在执行语句前，否则会报错。  C99标准中以支持变量声明语句放在函数中任意位置(使用前)，但是VS/VC++6.0对C99并不是很兼容，so~

在C89标准中，变量声明语句必须放在在执行语句前，否则会报错。

引用 5 楼 u011248694 的回复:[quote=引用 3 楼 worldy 的回复:] 你用的c编译器，不是c++，c变量必须在可执行语句之前定义好 c/c++的编译器怎么区分的呢？[/quote] 保存为cpp吧

引用 3 楼 worldy 的回复:你用的c编译器，不是c++，c变量必须在可执行语句之前定义好 ++ 应该是应该是是c文件文件引起的吧！c语言不支持在函数中间定义变量的！ 所以把文件改成cpp文件吧！

引用 3 楼 worldy 的回复:你用的c编译器，不是c++，c变量必须在可执行语句之前定义好 c/c++的编译器怎么区分的呢？

引用 2 楼 user-6 的回复:The c programming language里面有这样一段话：In C, all variables must be declared before they are used, usually at the beginning of the function before any executable statements.   变量的声明要在一个函数可执行语句的前面。或者是在语句块（被{}包括的一段代码）的最前面（同样也是在可执行语句的前面）。 但是我并没有在最前面也可以啊，就是在strcpy函数前面就可以了啊。

你用的c编译器，不是c++，c变量必须在可执行语句之前定义好


Question: 请教：这个代码中有些地方看不明白

引用 1 楼 user-1 的回复:搜赵老师名言：程序的功能不是看出来的.... 谢谢，我已看明白是怎么回事了。还是那句话，书读百遍，其义自现。

搜赵老师名言：程序的功能不是看出来的....


Question: 求 sscanf 函数过滤空白字符的格式串

有没有大侠啊。。。。。


Question: 跪求大牛查错poj1006 感觉都对呀 虽然办法很笨 输出应该是对的 WA了N次了 快崩溃了

测试用例是从网上搜来的.有了反例,就容易分析了.

引用 2 楼 logiciel 的回复:LZ程序不能通过以下测试用例:  19 0 1 364 24 29 34 1  如下修改2处可AC: #include<stdio.h> #define N 21252 typedef struct{   int amount;   int period; }bio,*pbio;  int main(){   bio ph,em,in;   int p,e,i,d,co;   ph.period=23;   em.period=28;   in.period=33;   co=1;   scanf("%d %d %d %d",&p,&e,&i,&d);   while(p>=0&&e>=0&&i>=0&&d>=0){     if(p==e&&p==i){       printf("Case %d: the next triple peak occurs in %d days.\n",co,p>d?p-d:N+p-d);     }else{       ph.amount=p;       em.amount=e;       in.amount=i;        /* while(ph.amount<21253&&em.amount<21253&&in.amount<21253){         if(ph.amount==em.amount&&em.amount==in.amount){           break;         }       改为以下1行*/       while(ph.amount!=em.amount||em.amount!=in.amount){           if(ph.amount>=em.amount&&ph.amount>=in.amount){           if(em.amount>in.amount){             in.amount+=in.period;           }else{             em.amount+=em.period;           }         }else{           if(em.amount>=ph.amount&&em.amount>=in.amount){             if(ph.amount>in.amount){               in.amount+=in.period;             }else{               ph.amount+=ph.period;             }           }else{             if(ph.amount>em.amount){               em.amount+=em.period;             }else{               ph.amount+=ph.period;             }           }         }         //               printf("%d %d %d\n",ph.amount,em.amount,in.amount);       }       //           printf("%d %d %d\n",ph.amount,em.amount,in.amount);        //改为以下2行 printf("Case %d: the next triple peak occurs in %d days.\n",co,ph.amount-d?ph.amount-d:ph.amount);       ph.amount=ph.amount%N;       printf("Case %d: the next triple peak occurs in %d days.\n",co,ph.amount>d? ph.amount-d : N+ph.amount-d);      }     scanf("%d %d %d %d",&p,&e,&i,&d);     co++;   }    return 0; } 万分感谢，，大牛就是大牛。请问您是怎么做测试的呀，怎么去发现错误的呢

设置断点，逐步调试，分析结果。 这是必须掌握的技能。对你以后遇到类似问题更加容易处理。


Question: 遇到C语言编程中的一个问题。代码如下。

引用 10 楼 gaohuaid 的回复:[quote=引用 4 楼 u012804737 的回复:] 首先我要感谢你们，其次，我是想知道，为什么char * ptr  ptr定义在常量区是什么意思？还有就是，内存地址也可以比较大小吗？内存地址是以二进制存储在内存中的，是不是二进制转换为10进制在比较？万分感谢！ 引用 3 楼 mars_tl 的回复:char *ptr = "how are you"; ptr定义在常量区，不可更改。用字符串数组 ， 1L正解。  这个并不是ptr不可更改，而是"how are you" 不可更改，因为它是字符串常量。也就是说当前ptr的值为字符串常量的首地址。 [/quote] 恩，是这个意思，我没有表达清楚。

引用 4 楼 u012804737 的回复:首先我要感谢你们，其次，我是想知道，为什么char * ptr  ptr定义在常量区是什么意思？还有就是，内存地址也可以比较大小吗？内存地址是以二进制存储在内存中的，是不是二进制转换为10进制在比较？万分感谢！ 引用 3 楼 mars_tl 的回复:char *ptr = "how are you"; ptr定义在常量区，不可更改。用字符串数组 ， 1L正解。  这个并不是ptr不可更改，而是"how are you" 不可更改，因为它是字符串常量。也就是说当前ptr的值为字符串常量的首地址。

引用 8 楼 u012804737 的回复:谢谢了，虽然我对那个只读（linux）数据段不是太明白，因为没接触过，不过到时候找点资料看看。谢谢大家。明天结贴。看来我的C语言之路还很漫长。顺便问一句，如果学习数据结构，看什么书比较好 看看内存管理这块吧！就是知道静态区的内容只是可读不可更改的！ 分很多找点资料看阿卡呢！至于书嘛，看看这个链接 http://bbs.csdn.net/topics/390638386

首先字符串常量在只读（linux）数据段，所以不可修改。 其次是，while中的判断是比较的地址值，由于字符串的首地址小于指向字符串末尾的地址，所以比较是有效的。

[quote=引用 1 楼 lg1544650023 的回复:] 首先你的程序编译出错是应为你没有在调用函数之前声明函数 然后你不能用char *ptr定义字符串，应该用数组 代码修改如下: [code=c]#include <stdio.h> int main() { 	void reverse_string(char *string)

引用 1 楼 lg1544650023 的回复:首先你的程序编译出错是应为你没有在调用函数之前声明函数 然后你不能用char *ptr定义字符串，应该用数组 代码修改如下: #include <stdio.h> int main() { 	void reverse_string(char *string); 	char ptr[500] = "how are you"; 	reverse_string(ptr); 	printf("%s\n", ptr); } void reverse_string(char *string) { 	char * last_string; 	for (last_string = string; *last_string != '\0'; last_string++) 		; 	last_string--; 	while (string < last_string) 	{ 		char temp; 		temp = *string; 		*string++ = *last_string; 		*last_string-- = temp; 	} }  说明： while(string < last_string)是比较的地址大小 在for循环结束时last_string指向字符串的最后一个字符，也就是'\0' 所以后面要执行last_string--， 让last_string指向字符串的倒数第二个字符，也就是我们可见的最后一个字符，然而string仍然是指向字符串的第一个字符的。 while(string < last_string)表示当string还在last_string前面的时候执行循环 循环体的内容是就是交换字符串前后的内容实现倒转 注意每次交换要移动指针，代码中的string++,和last_string--的作用就在此+1

while语句中比较的就是地址的大小。。


Question: [咨询]关于不同类型之间使用memcpy

引用 3 楼 akirya 的回复:[quote=引用 2 楼 u010102271 的回复:] [quote=引用 楼主 u010102271 的回复:] 比如我想将char*拷贝到unsigned long  unsigned long ulVar = 0;      memcpy((char*)(&ulVar),"00000001",8);  实际打印的值是：3544385890265608240  ps：按照我之前的理解，还以为是按位copy了，那么得到的值就是1了  重新算了下： ‘0’为00110000 ‘1’为00110001 “00000001”就应该为:0011000000110000001100000011000000110000001100000011000000110001 计算的结果为：3472328296227680305（10进制）[/quote] 你忽略了大小端问题[/quote] 受教，确实是这样的

引用 2 楼 u010102271 的回复:[quote=引用 楼主 u010102271 的回复:] 比如我想将char*拷贝到unsigned long  unsigned long ulVar = 0;      memcpy((char*)(&ulVar),"00000001",8);  实际打印的值是：3544385890265608240  ps：按照我之前的理解，还以为是按位copy了，那么得到的值就是1了  重新算了下： ‘0’为00110000 ‘1’为00110001 “00000001”就应该为:0011000000110000001100000011000000110000001100000011000000110001 计算的结果为：3472328296227680305（10进制）[/quote] 你忽略了大小端问题

引用 楼主 u010102271 的回复:比如我想将char*拷贝到unsigned long  unsigned long ulVar = 0;      memcpy((char*)(&ulVar),"00000001",8);  实际打印的值是：3544385890265608240  ps：按照我之前的理解，还以为是按位copy了，那么得到的值就是1了  重新算了下： ‘0’为00110000 ‘1’为00110001 “00000001”就应该为:0011000000110000001100000011000000110000001100000011000000110001 计算的结果为：3472328296227680305（10进制）

的确是按位拷贝 3544385890265608240对应的16进制值是 3130303030303030 '0'对应的ascii字符是0x30


Question: SIGSEGV

你的字符串是常量，无法使用 *(str-sublen*sizeof(char *))=*str;

源代码 #include "62.h" int del_substr(char *str,char const *substr) { 	int flag=0; 	int sublen=0; 	char *start2=str; 	char const *start=substr; 	while(*substr++!='\0') 		sublen++; 	char const*end=(substr-1); 	substr=start; 	while (*str!='\0') 	{ 		if(*substr!=*end&&*str==*substr) 		{ 			substr++; 			flag++; 		} 		else if(*substr==*end) 		{ 			char const *end2=str; 			break; 		} 		else 		{ 			substr=start; 			flag=0;  		} 		str++; 	} 	if(sublen==flag) 	{ 		prstr(str,sublen,start2); 		return 1; 	} 	else 		return 0; } void prstr(char *str,int sublen,char *start2) { 	*(str-sublen*sizeof(char *))=*str; 	puts(start2); } #include <stdio.h> int main(void) { 	char *str="ABCDEFG"; 	char const *substr="CDE"; 	printf("%d\n",del_substr(str,substr)); 	return 0; }

引用 2 楼 skysoshy 的回复:*(str-sublen) = *str 这句： str地址是0x400781 sublen=3 *str的值是'F’. 所以上述语句试图给 (0x400781 - 3)的地址设置为'F'。  这么说应该明白了吧？ 明白了点，但我应该怎么做呢？

SIGSEGV ,这里可能是操作了无效的指针吧！ 源码贴出看看字符串“ABCDEFG" 是如何定义的呢？ 是不是修改了可读区间？或者访问越界？


Question: 简单问题：如何使用c语言中的变长数组

变长数组只是声明时可以用变量指定大小，一旦指定，就不能变了，否则就是动态数组了。

如果输入前已知数量，malloc申请该数量长度的内存存放输入数值 如果输入前不知数量，malloc申请一定长度的内存存放输入数值，超了就申请一段更长长度的内存，再把已经存放的那些数值复制过去  数组的长度必须在源代码编译成可执行程序时已确定。 C语言中哪来的vector？

这个确实不能用数组来实现，因为数组的大小是固定的 所以要么用数据结构动态分配内存，要么用一个很大的数组

使用链表， 或者树等等动态数据结构来存放。 数组是在编译时已经固定了大小， 为了足够用要定一很大的数组。当输入的数量少的时候，浪费内存， 输入多的时候， 又会越界破坏其他数据。

引用 8 楼 u012857025 的回复:[quote=引用 7 楼 angel_su 的回复:] 不行吧，除非你要求用户第一次输入是代表有几个数据，而不是以最后输入0来判断...  我看书上的例题貌似是这样的 所以我来问一问。。[/quote]  malloc是可以输入指定长度大小的数组！但是想要同时把数据存在数组里面就不适合用数组了！ 因为你是要在知道总数之后才能知道数组大小，这个时候动态分配了数组长度，但是想要同时存储数据的话，就比较困难了！ 所以建议你用vector向量，你不知道，我和你提了，你也应该区查一下资料吧！艾，学习的积极性真心不高。。

引用 7 楼 angel_su 的回复:不行吧，除非你要求用户第一次输入是代表有几个数据，而不是以最后输入0来判断...  我看书上的例题貌似是这样的 所以我来问一问。。

malloc...

我想把10000换成n怎么做？

引用 1 楼 max_min_ 的回复:用vector吧！输入一个丢进来一个，判断0结束！  vector是？  我知道可以定义一个数组长度很大的数组，譬如a[10000] 然后写一个丢一个进去，但是我想知道可不可以用变长数组？

引用 2 楼 szllong123 的回复:很显然直接写死一个常量在里边是不行的。所以就用动态数组吧。  我想的是括号里面能不能用到变量？譬如说int n 然后在用n++循环录入新的数。

很显然直接写死一个常量在里边是不行的。所以就用动态数组吧。

用vector吧！输入一个丢进来一个，判断0结束！


Question: vs和constexpr

引用 4 楼 lg1544650023 的回复:vs2012确实是把constexpr拒绝了，但是为什么2013又能够识别但是不能实现功能 正在开发中吧。

引用 1 楼 user-3 的回复:很少用这么偏僻的关键字的了，而且通常情况下 const已经能满足需求了！ vs之前是不支持此关键字的！ C++11还没普及开来，普及开来的话constexpr就不会是偏门的关键字了。

2013不支持. http://msdn.microsoft.com/en-us/library/vstudio/hh567368.aspx


Question: 都是常量指针

你的Stu_pst应该是下面这样的吧？  typedef type *Stu_pst;  然后Stu_pst就是(type *)，即编译器将Stu_pst解释为(type *)这个整体。  那么const (type *) stu3; he (type *) const stu4;中const修饰的是（type *）这个整体。  也即是说这两个表达式是一样的咯，stu3和stu4都是指向type类型的const指针。

Stu_ps是怎么定义的？  你说的是指针常量和常量指针么？


Question: 分享我写的2D格斗游戏，C语言实现

大三学生能把握上万行代码的开发，已经非常棒了。你在小学或者初中高中是不是有了基础？参加过ACM或者数学建模竞赛不？ 如果真正爱编程，就要找一个可以自己把握需求，并可以充分发挥想象力的行业作为自己的人生规划。 一，避免选择做直接与不懂计算机的最终用户打交道的项目。在甲方不懂计算机，乙方又执着于技术的情况下，会因为理解不同，产生误会。在被迫屈从甲方时，原本享受开发的你会暴跳如雷，从而渐渐失去兴趣。二，选择一门学科做主业，并充分发挥编程能力，如虎添翼。建议选择一门学科，比如信号处理，通信，图像处理，人工智能为主业，在研究生阶段好好精深专业知识，毕业后，你会发现身边的人很会理论，但大多无法独立实现，而实现能力不是一两天具备的。三，建议先进入大公司干。风雨飘摇得小公司为了生存，容易急功近利，大公司，会有一定的实力让你自己完成本职的同时去发挥。

新手学习下，谢谢楼主

不错，支持。我要加油了！

谢谢分享谢谢分享

厉害！赞一下！！

谢谢楼主分享！！！

非常不错，支持

厉害，要向楼主学习！！！

大三啊，当年我在干嘛呢？？？？？我在玩别人的游戏，LOL。。。。。

LZ牛逼

感谢楼主分享!!!!!

厉害啊，不错不错！

不错，赞一个，值得学习！

求好心人发一份给我，没分了，810544912@qq.com，先谢谢了！

楼主大神级别啊

大神！

楼主好厉害。。。

楼楼牛

支持楼主,现在工作找到了吗？

厉害！楼主加油~


Question: c语言

嗯！严蔚敏的不错，而且网上有对应的视频。

其实网上很多的，哪本数据结构都差不多内容。你找C语言版的就行了。

清华大学出版社，严蔚敏那本，虽然看起来很枯燥，但是你可以下与那本书对应的视频来看 最好是自己用Ｃ语言把书上面的算法都用程序来实现

c语言版 数据结构！


Question: anyview系统题，无需输入与输出，求指教

int main() {     int i = 0;     intc[26] = {0};     char *s = "AbcijKaBcdEXyzuvwx";     while(s[i]!='\0')     {         if (s[i]>='a'&& s[i]<='z')         c[s[i]-'a']++;         if (s[i]>='A' && s[i]<='Z')         c[s[i]-'A']++;     }     return 0; }


Question: 求两个日期的天数，刚学C语言，求帮助

#include <stdio.h>  int mon[12]={31,28,31,30,31,30,31,31,30,31,30,31};                  /*储存12个月的天数*/ void main() {  int spec_year(int);  void scan(int *year,int *month,int *day);  long com_year(int y1,int y2);  int com_month(int y1,int m1,int y2,int m2);  int com_day(int y1,int m1,int d1,int y2,int m2,int d2);   int year1,month1,day1;  int year2,month2,day2;   long sum=0;  int k=0;   /*输入两个日期，做合法性检查*/   printf("Enter the first date,like 1988 11 30:");  scan(&year1,&month1,&day1);  printf("Enter the second date,like 1988 11 30:");  scan(&year2,&month2,&day2);   /*当输入的第一个日期比第二个日期大时，将二者对换*/   if((year1>year2)||((year1==year2)&&(month1>month2))||((year1==year2)&&(month1==month2)&&(day1>day2)))  {   int temp;   temp=year1;year1=year2;year2=temp;   temp=month1;month1=month2;month2=temp;   temp=day1;day1=day2;day2=temp;  }   /*计算两个日期之间的天数*/  sum+=com_year(year1,year2);                                /*计算两个年份之间的天数*/  sum+=com_month(year1,month1,year2,month2);                 /*计算两个月份之间的天数*/  sum+=com_day(year1,month1,day1,year2,month2,day2);         /*计算两天之间的天数*/   /*输出*/  printf("There are %ld days between them.\n",sum); }  void scan(int *year,int *month,int *day)                          /*输入日期函数，合法性判断*/ {  int k=0;  do  {   if(k!=0)    printf("\nWrong date!\n");   k++;   /*printf("Please write down the day,like 1988 11 30:");*/   scanf("%d%d%d",year,month,day);   if(spec_year(*year))    mon[1]=29;  }while(*day>mon[*month-1]||*month>13||*year<1900||*year>3000);  mon[1]=28; }  long com_year(int y1,int y2)                                      /*计算两个年份之间的天数*/ {  int i;  long sum=0;   for(i=y1+1;i<y2;i++)  {   if(spec_year(i))    sum+=366;   else    sum+=365;     }  return sum;  }  int com_month(int y1,int m1,int y2,int m2)                       /*计算两个月份之间的天数*/ {  int i;  int sum=0;  if(y1!=y2)  {   if(spec_year(y1))   {    mon[1]=29;   }   if(m1!=m2)   {    for(i=m1;i<12;i++)   {    sum+=mon[i];       }   mon[1]=28;    if(spec_year(y2))   {    mon[1]=29;   }    for(i=0;i<m2-1;i++)   {    sum+=mon[i];      }   mon[1]=28;   }   else   {   for(i=m1-1;i<12;i++)   {    sum+=mon[i];       }   mon[1]=28;    if(spec_year(y2))   {    mon[1]=29;   }    for(i=0;i<m2-1;i++)   {    sum+=mon[i];      }   mon[1]=28;   }  }  else  {    if(spec_year(y1))   {    mon[1]=29;     }   for(i=m1;i<m2-1;i++)   {    sum+=mon[i];   }     mon[1]=28;  }   return sum;  }  int com_day(int y1,int m1,int d1,int y2,int m2,int d2)             /*计算两天之间的天数*/ {  int i;  int sum=0;    if(m1!=m2)  {   if(spec_year(y1))   {    mon[1]=29;     }       sum+=(mon[m1-1]-d1);       sum+=d2;      mon[1]=28;   }  else  {   sum+=d2-d1;     }    return sum; }  int spec_year(int year)                                           /*判断是否为闰年*/ {  if((year%400==0)||((year%4==0)&&(year%100!=0)))   return 1;  else   return 0; }

引用do    {printf("\nd1="); scanf("%d",&d1);    if(d1>cmonth(b)) printf("\nerror");    }while(cmonth(b)<d1);  实在看不出LZ这个cmoth(b)参数是什么


Question: DEV-C++问题

感谢版主的回复，对我很有用哦，第一个问题我自己已经解决了，第二个灰常感谢。

点击菜单帮助，查看其功能说明

菜单栏里,工具-->编辑器选项-->编辑器属性-->显示-->行号.  至于你说的改成c文件，这个没改过。。


Question: C/C++中，一个数组，如何与一个整型数比较？

其实两种不同表示方法，转换成同一种表示方法，进行比较最简单，不会出错。  不怕麻烦的话，可以一边转换以便比较。

多写了一个六 引用 16 楼 lm_whales 的回复: char a[16]={1,1,1,1,1,0,1,0,1,1,1,1,1,0,1,0};//一个字节表示一个位的二进制，字符数组。 char s[]="1111101011111010"; //字符串表示的二进制 （ASCII 码表示）  unsigned short b =0xFAFA;   //十六进制常量表示。C,C++语言中0xFAFA，                             //是个一些字符,编译后得到一个二进制整型常数。 unsigned short d = 64250;   //十进制常量表示。C,C++语言中0xFAFA，                             //是个一些字符,编译后得到一个二进制整型常数。 // b == d; 这两个常数，都是二进制的 1111101011111010 ; //C,C++  直接写成1111101011111010，不能表示 2 进制 //编译结果就是二进制的 1111101011111010 。（计算机内部表示，每个数字占一个位）

C，C++整型数据，是标准的二进制数据，  不过常量用 一个十进制或者8进制，16进制字符串表示。 //明确写成 1111101011111010 是   十进制常量，编译后实际是二进制，但是不是 1111101011111010这样的二进制。  C,C++ 包括格式化输入输出在内，没有二进制数的直接表示方法。  所以只能用16进制常量，代表二进制； 或者读入字符串后转换成整型数据，输出时转换为字符串输出。  所以1111101011111010 只是你认为，二进制的形式，不是C，C++ 可以表示的。 1111 1010 1111 1010 可以用字符数组，或者字符串数组表示。  不然用16进制常量表示。 这不就是 0x FAFA 么。   不然可以这么处理  char a[16]={1,1,1,1,1,0,1,0,1,1,1,1,1,0,1,0};//一个字节表示一个位的二进制，字符数组。 char s[]="1111101011111010"; //字符串表示的二进制 （ASCII 码表示）  unsigned short b =0xFAFA;   //十六进制常量表示。C,C++语言中0xFAFA，                             //是个一些字符,编译后得到一个二进制整型常数。 unsigned short d = 64250;   //十六进制常量表示。C,C++语言中0xFAFA，                             //是个一些字符,编译后得到一个二进制整型常数。 // b == d; 这两个常数，都是二进制的 1111101011111010 ; //C,C++  直接写成1111101011111010，不能表示 2 进制 //编译结果就是二进制的 1111101011111010 。     b在编译以后，就是二进制的了。 a 转换成s  s[i] =a[i] +'0'; s 转换成 a; a[i] =s[i] -'0'; a 转换成b b = (a[0])*2^N-1 +......+ (a[N]); b转换成a 就是除以二。求余数即可。  b转换成 s itoa(b,s,2);就可以了。具体实现，就是除以二。求余数，转成ASCII表示。 a转换成s 一一对应，把1，0 转换成ASCII 表示（‘1’，‘0’ ）就可以了。

int a = 7, b =8; char* buf = (char*)&a; bool res = (*(int*)buf) == b;

你把b也转换成字符串

CString str; str.Format("%d",b); for(...) {    compare: str.at(i).atoi()== a[i]; } 上面的方法应该可以，而且不复杂

引用 1 楼 lm_whales 的回复:1）统一格式 2）诸位比较  PS： C，C++ 不能这么定义二进制，这么定义的是10进制，已经溢出了。 int b=1111101011111010。  嗯，溢出了。 想表达“1111101011111010”对应的10进制数。 其实想知道的是C语言中怎么实现

C++用 bitset 吧。

不知道楼主需要干什么

用指针读值比较、不知道可不可以……

int n=sizeof(a); int m=0; for(int i=0;i<n;i++) {     m=m*10+(a[i]-'0'); } if(m==b) {      }

引用 9 楼 whizer 的回复:[quote=引用 8 楼 whizer 的回复:] char a[16]={1,1,1,1,1,0,1,0,1,1,1,1,1,0,1,0}; int b=230; int atmp=0;  for(i=15; i>0; i--)    atmp+= (15-i)<<a[i];  if(atmp != b)    printf("equal"); else    printf("Not equal"); if(atmp != b)    printf("Not equal"); else    printf("equal");[/quote]  另外， 左移是这个的：atmp+=a[i]<<(15-i);

引用 9 楼 whizer 的回复:[quote=引用 8 楼 whizer 的回复:] char a[16]={1,1,1,1,1,0,1,0,1,1,1,1,1,0,1,0}; int b=230; int atmp=0;  for(i=15; i>0; i--)    atmp+= (15-i)<<a[i];  if(atmp != b)    printf("equal"); else    printf("Not equal"); if(atmp != b)    printf("Not equal"); else    printf("equal");[/quote]  貌似只有这个方法最好了

不能用c++ stl吗，那把int b，通过位操作，把每一位提取出来，与数组a[]中的对应位进行比较就行了。

引用 8 楼 whizer 的回复:char a[16]={1,1,1,1,1,0,1,0,1,1,1,1,1,0,1,0}; int b=230; int atmp=0;  for(i=15; i>0; i--)    atmp+= (15-i)<<a[i];  if(atmp != b)    printf("equal"); else    printf("Not equal"); if(atmp != b)    printf("Not equal"); else    printf("equal");

第一个数组专成整形就是了。


Question: 多线程编程的面试题

但是妈妈先做好饭就比较麻烦了，小明要不断的检查一个标志位，看妈妈是否叫了他。感觉很浪费资源。有没有好办法？  为什么要这样做？没别的办法？

考线程的同步，可以用信号量实现

考的是线程的同步异步

其实没明白楼主写的意思！ 这里两个线程无非就是同步问题了！  注意一点就是：妈妈煮好饭，小明才可以吃饭，所以这里同步下就没什么吧！

不太清楚这个题的考点，LZ可以看看我这个角度是否对：饭是共享内存，做饭是写内存，吃饭是读内存，而小明的玩耍就是访问属于小明的独享内存。小明去玩耍时给“饭”加读锁，由于妈妈给“饭”加了写锁，因此小明无法读。如果小明的独享内存已经操作完了，写锁还没释放，证明饭还没做好，继续试图加读锁。而妈妈和小明一块吃饭就是一同给“饭”加了读锁。当然在小明玩的过程中，也需要不断地试图给“饭”加读锁，所以也会浪费资源，所以。。。


Question: 问个问题，关于全局变量和局部静态变量

不过按这么说，七楼的理解也有偏差啊！

引用 10 楼 hanhuiyu2012 的回复:那个经常说的全局变量和局部静态变量在编译的时候值就定下来了是什么意思？  我怎么从来没听过类似的话……

那个经常说的全局变量和局部静态变量在编译的时候值就定下来了是什么意思？

还是不太懂，头都大了！

编译时哪来的赋值一说

引用 楼主 hanhuiyu2012 的回复:全局变量是什么时候赋初值的，是预编译的时候还是编译的时候还是执行的时候？ 还有个就是局部静态变量是什么时候初始化的？ 全局变量在编译的时候在对应的存储位置填入初始值 局部变量由于创建在栈上，每次进入时初始化 局部静态变量是建立在数据区，也是在编译的时候初始化，不需要代码

加下Q吧，大神，详细聊下！45442017

理解了，赋初值不代表就开了内存，编译的时候是确定了程序执行时变量的存放位置！

引用 10 楼 hanhuiyu2012 的回复:那个经常说的全局变量和局部静态变量在编译的时候值就定下来了是什么意思？ 你制定了明年去美国的计划，你明年身处的位置就已经定了，但那不代表你现在就在美国 全局变量和局部静态变量的初始值是在代码里确定的，编译的时候代码已经不会再更改所以已经可以知道其在内存中出现后的初始值，但那不代表它们已经在内存中出现，直到这个程序被执行

引用 12 楼 hanhuiyu2012 的回复:好吧，看来我是被度娘误导了，一搜一大堆这种说法，搞得我晕头转向！那就是说编译的时候程序还没形成，更没执行，只有编译结束后，形成目标文件执行的时候才会给全局变量和静态变量分配空间！是吗？ 对

编译的时候就已经赋值

引用 4 楼 hanhuiyu2012 的回复:恩，这个答案比较靠谱，不过我想说的跟你说的不是一个过程。我说的是程序写好了，进行预处理或者编译的时候，会不会就已经对局部静态变量和全局变量初始化了？ 预处理和编译是“把文本代码变成机器命令”的过程，程序尚未形成，自然没有分配任何资源，连内存都不存在，更不用提内存中的变量了 你想说什么我不清楚，我只知道“编译”和“变量”完全不是一个领域内的概念

引用 2 楼 hanhuiyu2012 的回复:额。楼上的没听懂我的意思呀，我是想说我在main函数外定义了一个全局变量，想知道他是什么时候被赋值的。因为程序执行肯定是从main进去呀。 全局变量在进入main函数之前初始化 局部静态变量在第一次进入该函数的时候初始化

一般变量的定义时就要初始化，这是个好习惯。


Question: 这个括号匹配程序怎么改啊？我做不出来了

贼长的代码，受不了

先搞清楚你的括号是否只有小括号，如果是的话是不需要这么多代码的，三五行代码就够了，如果还有中括号和大括号另当别论。

i=0, 遇到（ i++ 遇到 ) i--  最后看i是否为0


Question: C语言的操作符中有这个符号吗？是什么意思？

引用 5 楼 worldy 的回复:指针相减求出小的指针块的大小吧 是啊！谢谢！在做一个题时参考《C函数速查》，一下子没往那上面去想！

指针相减求出小的指针块的大小吧

引用 2 楼 max_min_ 的回复:ptr-string 指针相减啊！ 这里表示中间相差多少个字符！ 多谢，多谢！哈哈，闹笑话了！昏了，昏了！

引用 1 楼 user-3 的回复:减号啊  指针相减 哈哈，这些天事情多，都昏头了！多谢提醒！

ptr-string 指针相减啊！ 这里表示中间相差多少个字符！

减号啊  指针相减


Question: 为什么我的快排速度这么慢。。。。。。。。。。求解释 跪求

可能是因为待排列的数字有很多重复，造成类似冒泡的算法， 用了>=符号。

引用 4 楼 lm_whales 的回复:[quote=引用 3 楼 guo1105094218 的回复:] 谢谢了哦 但是我拷贝别人的在我电脑上运行超级块 100000输入只要0.34s，，，，，我也在研究 希望大牛解惑下面附别人代码  void swap(int *a,int *b){     int s;     s=*a;     *a=*b;     *b=s; }  int *split (int *head , int *tail) {    int middle = *(head + (tail  -  head) / 2);    while (1)    {        while (*head  <  middle)             head++;        tail--;        while (*tail  >  middle)             tail--;        if (head >= tail)             return head;        swap (head , tail);        head++;    } } //快速排序 , 递归调用 void QuickSort(int * first , int *last)           //这个快排太强悍了 1024000输入 耗时0.43s {      if (last  >  first+1)     {          int *t=split(first, last); //返回中间值所在的位置          //判断前一段和后一段的长度，  为了提高效率长度小的先操作 ，          if (last -t < t - first)          {               QuickSort(t, last);               QuickSort(first , t);          }          else          {               QuickSort(first , t);               QuickSort(t, last);          }     } } 这个就是，标准的三数中值分割，快排算法，  唯一的小改进，就是长度小的先操作，这也能稍微改进效率。 速度当然快了。  如果，能够在数据量小的时候， 用插入排序替换，效率更高。  三数中值分割，一般来说，比随即算法要好；  因为随即数生成算法，代价太高。 理论上，随即算法是最快的。 而且没有最坏的情况发生。  不过，由于随即数生成算法，代价太高； 随即算法只有理论价值，并无实用意义。  三数中值分割，的随即性已经比较好了， 所以已经算是，实际意义上的，快速排序的最快的算法了。 最坏情况几乎不会发生。  据说，用堆排序改进的快速排序 （当递归深度到一定层次，改为堆排序） 可以实现最坏 O(Nlog(N))时间复杂度的快速排序。   [/quote] 嗯嗯  我再去研究研究 谢谢了 自己太菜了

引用 3 楼 guo1105094218 的回复:谢谢了哦 但是我拷贝别人的在我电脑上运行超级块 100000输入只要0.34s，，，，，我也在研究 希望大牛解惑下面附别人代码  void swap(int *a,int *b){     int s;     s=*a;     *a=*b;     *b=s; }  int *split (int *head , int *tail) {    int middle = *(head + (tail  -  head) / 2);    while (1)    {        while (*head  <  middle)             head++;        tail--;        while (*tail  >  middle)             tail--;        if (head >= tail)             return head;        swap (head , tail);        head++;    } } //快速排序 , 递归调用 void QuickSort(int * first , int *last)           //这个快排太强悍了 1024000输入 耗时0.43s {      if (last  >  first+1)     {          int *t=split(first, last); //返回中间值所在的位置          //判断前一段和后一段的长度，  为了提高效率长度小的先操作 ，          if (last -t < t - first)          {               QuickSort(t, last);               QuickSort(first , t);          }          else          {               QuickSort(first , t);               QuickSort(t, last);          }     } } 这个就是，标准的三数中值分割，快排算法，  唯一的小改进，就是长度小的先操作，这也能稍微改进效率。 速度当然快了。  如果，能够在数据量小的时候， 用插入排序替换，效率更高。  三数中值分割，一般来说，比随即算法要好；  因为随即数生成算法，代价太高。 理论上，随即算法是最快的。 而且没有最坏的情况发生。  不过，由于随即数生成算法，代价太高； 随即算法只有理论价值，并无实用意义。  三数中值分割，的随即性已经比较好了， 所以已经算是，实际意义上的，快速排序的最快的算法了。 最坏情况几乎不会发生。  据说，用堆排序改进的快速排序 （当递归深度到一定层次，改为堆排序） 可以实现最坏 O(Nlog(N))时间复杂度的快速排序。

head，tail距离比较小的时候 （1~20之间） 使用插入排序就会加快，快排的速度。

正常10w的话1秒绝对够。这代码也没什么明显的问题。上完整代码+cpu配置


Question: c语言课程设计封装

可以到我QQ空间中看一下一篇文章  写代码学习Win32编程之动态链接库   应该可以解决你的问题 因为是很久之前写的了 没有放到CSDN博客里... 扣扣：284941821


Question: C语言菜鸟一个小小问题

引用 6 楼 junlinfushi 的回复:[quote=引用 4 楼 mcmay 的回复:]     printf()和putchar，scanf和getchar()的一个最明显区别在于，printf()除了可以输出单个字符之外，还可以为该字符的输出规定一些格式（这也是为什么printf()和scanf()这两个I/O函数被称为格式化输出、输入函数的原因）。例如：     用printf("%c\n", 'h');，你可以输出字母h（这里的h是一个字符常量，当然h所在的位置也可以是字符变量），但屏幕上的光标会移动到下一行（以为有了\n这个具有换行功能的转义字符）。而putchar('h');只能一行之中输出字母h，而无法给它规定任何输出格式。要实现输出后换行的效果，就要再写一个putchar('\n');才能实现。     假设a是一个字符变量，用scanf("%c\t", &a); 就表示要求用户除了从键盘上输入一个字符之外还要再按下一个TAB键，然后按Enter键才能成功完成输入。而getchar();没有这样的规定，只用输入一个字母然后按下Enter键就可以完成输入。     printf()和scanf()能完成的输出、输入功能很多很多，总体比putchar()和getchar()要强大多了。建议像楼上各位提出的那样，多看看相关参考资料。还真耐心[/quote] 呵呵，一方面看看能不能帮到楼主，另一方面也是看看自己能不能把概念讲清楚。

引用 4 楼 mcmay 的回复:printf()和putchar，scanf和getchar()的一个最明显区别在于，printf()除了可以输出单个字符之外，还可以为该字符的输出规定一些格式（这也是为什么printf()和scanf()这两个I/O函数被称为格式化输出、输入函数的原因）。例如：     用printf("%c\n", 'h');，你可以输出字母h（这里的h是一个字符常量，当然h所在的位置也可以是字符变量），但屏幕上的光标会移动到下一行（以为有了\n这个具有换行功能的转义字符）。而putchar('h');只能一行之中输出字母h，而无法给它规定任何输出格式。要实现输出后换行的效果，就要再写一个putchar('\n');才能实现。     假设a是一个字符变量，用scanf("%c\t", &a); 就表示要求用户除了从键盘上输入一个字符之外还要再按下一个TAB键，然后按Enter键才能成功完成输入。而getchar();没有这样的规定，只用输入一个字母然后按下Enter键就可以完成输入。     printf()和scanf()能完成的输出、输入功能很多很多，总体比putchar()和getchar()要强大多了。建议像楼上各位提出的那样，多看看相关参考资料。还真耐心

scanf(),printf(); //格式化输入输入函数 ，格式化 getchar(); //在标准输入流中取出一个字符 putchar; // 在标准输出流中取出一个字符  // 再不懂的话，找一个基础的书籍看看理论基础知识吧！

引用 2 楼 AnYidan 的回复:先别管这些，先把基本概念搞清楚 ++，确实意义不大。学习一些基本概念先

先别管这些，先把基本概念搞清楚

看到这种贴。。 翻翻书或者度娘就可以解决的问题就不要来这里了，没有其他意思~~~


Question: 用VS怎样读取GeoTiff图像

听说可以用GDAL，有没有这方面的参考资料？ 请用过的人推荐一下。 谢谢！

这个不清楚。。。


Question: 深入理解计算机系统里面的一个小疑惑

了个单词，errata，勘误表

应该是 t = 4 * counter + 6; counter = counter  + 4; return t;

这代码对毛线，勘误表都不看的？明显就是错误代码。查看CSAPP errta

引用 14 楼 bai12345633 的回复:[quote=引用 7 楼 mujiok2003 的回复:] [quote=引用 1 楼 baipv008 的回复:] 应该是书里代码错了  这代码是对的。 以下是gcc 4.7.3 -O3下结果 [/quote]  你列的汇编是正确的，但是理解有问题，你列的代码里面是先把counter的值保存了（也就是4），再利用%eax算出的t，而此时的%eax的值是以前的counter(也就是0)，而不是已经写入内存的4. [/quote] 不是很理解你的意思.我讲讲我的理解    0x004016f0 <+0>:     push   ebp    0x004016f1 <+1>:     mov    ebp,esp    0x004016f3 <+3>:     and    esp,0xfffffff0    0x004016f6 <+6>:     sub    esp,0x10    0x004016f9 <+9>:     call   0x4011e0 <__main>    0x004016fe <+14>:    mov    eax,ds:0x404018    0x00401703 <+19>:    mov    DWORD PTR [esp],0x402080    0x0040170a <+26>:    mov    DWORD PTR [esp+0x4],eax    0x0040170e <+30>:    call   0x4011e8 <printf> => 0x00401713 <+35>:    mov    eax,ds:0x404018 // cnt-> eax    0x00401718 <+40>:    lea    edx,[eax+0x4]     0x0040171b <+43>:    mov    DWORD PTR ds:0x404018,edx // cnt += 4     0x00401721 <+49>:    lea    eax,[eax*4+0x6] //返回eax * 4 + 6, 也就是自增前的cnt*4 + 6      0x00401728 <+56>:    leave    0x00401729 <+57>:    ret

引用 20 楼 ForestDB 的回复:http://csapp.cs.cmu.edu/public/errata.html Chapter 5: Optimizing Program Performance     p. 479, Second block of code in aside on “Optimizing function calls by inline substitution”. Line four should read     counter = counter + 4 +1  去看看这本书的勘误表就好了，比较负责的书一般都会有这个。这里很明显是书印错了。

引用 9 楼 yulinlang 的回复:书错了，应该是counter = counter + 4 反汇编也证明了 mov  eax, ds:0x404018 lea  edx, [eax+0x4] mov  DWORD PTR ds:0x404018  要是这样写还差不多：  int t = counter; counter = t + 4; t = 4 * counter + 6;  你这样又不对了。 应该是：  t = 4 * counter + 6; counter = t + 4; return t;

引用 3 楼 erhou134 的回复:优化后 counter = counter + 4 吧re

引用 16 楼 zhao4zhong1 的回复:[quote=引用 2 楼 maoshuoqiong 的回复:] 赵老师一会回来教导你,不要迷信课本的 不要迷信书、考题、老师、回帖； 要迷信CPU、编译器、调试器、运行结果。 并请结合“盲人摸太阳”和“驾船出海时一定只带一个指南针。”加以理解。 任何理论、权威、传说、真理、标准、解释、想象、知识……都比不上摆在眼前的事实！  有人说一套做一套，你相信他说的还是相信他做的？ 其实严格来说这个世界上古往今来所有人都是说一套做一套，不是吗？ [/quote]SB

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

引用 7 楼 mujiok2003 的回复:[quote=引用 1 楼 baipv008 的回复:] 应该是书里代码错了  这代码是对的。 以下是gcc 4.7.3 -O3下结果 [/quote]  你列的汇编是正确的，但是理解有问题，你列的代码里面是先把counter的值保存了（也就是4），再利用%eax算出的t，而此时的%eax的值是以前的counter(也就是0)，而不是已经写入内存的4.

引用错误  引用 1 楼 baipv008 的回复:应该是书里代码错了  同意，贩书的人不负责。

引用 楼主 bai12345633 的回复:直接上图：  问题是func1in()怎么能优化成func1opt()呢？counter的值都不一样了啊。不知道有没有看过的朋友知道为什么，本人小菜，谢谢了。counter是全局变量。  同意，贩书的人不负责。

抱歉，上面的写法也是错误的

counter++执行4次后， 相当于counter += 4

引用 1 楼 baipv008 的回复:应该是书里代码错了  这代码是对的。 以下是gcc 4.7.3 -O3下结果

引用 5 楼 user-12 的回复:没看懂。。。。。。。

没看懂。。。。。。。