Question: 求组合数

1楼代码的功能是求100!

引用 3 楼 zhao4zhong1 的回复:[quote=引用 2 楼 hongss 的回复:] 根据公式来 double ZuHe( int n_C, int n_r ) { 	int n_Sum[3] = { 1, 1, 1 }; 	for(int i=1; i<=n_C; i++) 	{ 		n_Sum[0] *= i; 	} 	for(int i=1; i<=n_r; i++) 	{ 		n_Sum[1] *= i; 	} 	for(int i=1; i<=( n_C - n_r ); i++) 	{ 		n_Sum[2] *= i; 	}  	return n_Sum[0] / ( n_Sum[1] * n_Sum[2] * 1.0f ); } 万一n是12345678901234567890123456789012345678901234567890123456789012345678901234567890呢？！[/quote]  呵呵，没考虑到会有那么大~~~ 这是以前做的一个检测程序里的片段，求两片模板配合度的，每天的量也就几十对~~~

引用 2 楼 hongss 的回复:根据公式来 double ZuHe( int n_C, int n_r ) { 	int n_Sum[3] = { 1, 1, 1 }; 	for(int i=1; i<=n_C; i++) 	{ 		n_Sum[0] *= i; 	} 	for(int i=1; i<=n_r; i++) 	{ 		n_Sum[1] *= i; 	} 	for(int i=1; i<=( n_C - n_r ); i++) 	{ 		n_Sum[2] *= i; 	}  	return n_Sum[0] / ( n_Sum[1] * n_Sum[2] * 1.0f ); } 万一n是12345678901234567890123456789012345678901234567890123456789012345678901234567890呢？！

仅供参考：#include <iostream> #include <string> #include <algorithm> using namespace std; inline int COMPARE(string str1,string str2) {//相等返回0，大于返回1，小于返回-1          if (str1.size()>str2.size()) return 1; //长度长的整数大于长度小的整数     else if (str1.size()<str2.size()) return -1;     else                              return str1.compare(str2); //若长度相等，则头到尾按位比较 } string PLUS(string number1,string number2) {     int i;     int length1 = number1.size();     int length2 = number2.size();      string result="";      reverse(number1.begin(), number1.end());     reverse(number2.begin(), number2.end());      for(i = 0; i < length1 && i < length2; i++) {         char c = (char)(number1[i] + number2[i] - 48);         result = result + c;     }      while(i < length1) {         result = result + number1[i];         ++i;     }      while(i < length2) {         result = result + number2[i];         ++i;     }      int carry = 0;     for(i = 0; i < (int)result.size(); ++i) {         int value = result[i] - 48 + carry;         result[i] = (char)(value % 10 + 48);         carry = value / 10;     }      if(carry !=0 ) {         result = result + (char)(carry + 48);     }      for(i = result.size() - 1; i >= 0; i--) {         if(result[i] != '0') break;     }      result = result.substr(0, i + 1);      reverse(result.begin(), result.end());     if(result.length() == 0) result = "0";     return result; } string MULTIPLY(string number1, string number2) {     int i, j;     int *iresult;     int length1 = number1.size();     int length2 = number2.size();     string result = "";      reverse(number1.begin(), number1.end());     reverse(number2.begin(), number2.end());      iresult = (int*)malloc(sizeof(int) * (length1 + length2 + 1));     memset(iresult, 0, sizeof(int) * (length1 + length2 + 1));      for(i = 0; i < length1; i++) {         for(j = 0; j < length2; j++) {             iresult[i+j] += ((number1[i] - 48) * (number2[j] - 48));         }     }      int carry = 0;     for(i = 0; i < length1 + length2; i++) {         int value = iresult[i] + carry;         iresult[i] = value % 10;         carry = value / 10;     }      for(i = length1 + length2 - 1; i >= 0; i--) {         if(iresult[i] != 0)break;     }      for(; i >= 0; i--) {         result = result + (char)(iresult[i]+48);     }      free(iresult);      if(result == "") result = "0";     return result; } string factorial(string n) {     string temp = "1";     string i;     for(i = "1"; COMPARE(i, n) <= 0; i = PLUS(i, "1")) {         temp = MULTIPLY(temp, i);     }     return temp; } int main(void) {     cout << factorial("100") << endl;     return 0; } //93326215443944152681699238856266700490715968264381621468592963895217599993229915608941463976156518286253697920827223758251185210916864000000000000000000000000 //

其实就是这个题目  Racebug出门春游，需要带一些食物，包括薯片，巧克力，矿泉水，汉堡，牛奶和糖果。经过估计，他觉得带n(n<=100000)件食物比较合适，但他还有一些癖好：  最多带1个汉堡  巧克力的块数是5的倍数  最多带4瓶矿泉水  薯片的包数是一个偶数  最多带3罐牛奶  糖果的个数是4的倍数  问 Racebug有多少种方式来准备这次旅行所带的食物 其实直接求公式也能运行出来 ...但是要求用到数据结构

能引入不超过50行的库函数源代码，决不引入库函数本身！

既然要求很明确，那就来一个简单的答案吧！ C(n+2, 2) = (n+2) * (n+1) / 2 当 n 是偶数时 = (n+2) / 2 * (n+1) 否则 = (n+1) / 2 * (n+2）  用C/C++可以这么写： return (n & 1) ? (n + 1) / 2 * (n + 2) : (n + 2) / 2 * (n + 1);  如果n非常大，引入一个大整数的库来计算就可以了；上一个语句按照大整数库的要求改写一下就OK

C(n+2,2)=(n+2)*(n+1)/2，显然n+2和n+1中必然有一个偶数，判断一下把它除以2再乘另一个数就可以了。


Question: 关于C语言链表求教

引用 10 楼 waitti 的回复:[quote=引用 9 楼 cfjtaishan 的回复:] #include <stdio.h> #include <stdlib.h> #include <math.h>  const double esp = 1e-6;  struct stu_info {     char ID[12];     char name[10];     char sex[6];     char Class[10];     float score[3]; };  struct stu_msg {     struct stu_info info;     struct stu_msg *next; };   typedef int (*cmp)(struct stu_info *, struct stu_info *);  int compare_as_chinese (struct stu_info *a, struct stu_info *b) {     return  (a->score[0] > b->score[0]             && fabs(a->score[0] - b->score[0]) > esp); }  int compare_as_math (struct stu_info *a, struct stu_info *b) {     return  (a->score[1] > b->score[1]             && fabs(a->score[1] - b->score[1]) > esp); }  int compare_as_english(struct stu_info *a, struct stu_info *b) {     return  (a->score[2] > b->score[2]             && fabs(a->score[2] - b->score[2]) > esp); }  void swap_stu_info(struct stu_info *a, struct stu_info *b, cmp compare_as_score) {     struct stu_info tmp;      if (compare_as_score(a, b)) {         tmp = *a;         *a = *b;         *b = tmp;     } }  void sort(struct stu_msg **head, cmp cmp_score) {     struct stu_msg *p, *q;      for (p = *head; p; p = p->next)         for (q = *head; q->next; q = q->next)             swap_stu_info(&q->info, &q->next->info, cmp_score); }  int main(void) {      return 0; } 参考一下吧有点疑惑，就是，为什么不直接在含有数据结构那里建立链表，而是选择再创一个结构体；还有一点就是cmp_score并没有这个，就直接用吗？[/quote] 第一个问题：这样做可以更快速的拷贝数据（减少编码的行数），将数据和地址（next)分开有很多好处； 第二个问题：cmp_score是函数指针变量，即sort函数里第二个参数是一个函数指针变量，用于接收一个函数名； 调用sort函数时，第二个参数可以根据排序的要求传入compare_as_chinese或compare_as_math或compare_as_english

引用 9 楼 cfjtaishan 的回复:#include <stdio.h> #include <stdlib.h> #include <math.h>  const double esp = 1e-6;  struct stu_info {     char ID[12];     char name[10];     char sex[6];     char Class[10];     float score[3]; };  struct stu_msg {     struct stu_info info;     struct stu_msg *next; };   typedef int (*cmp)(struct stu_info *, struct stu_info *);  int compare_as_chinese (struct stu_info *a, struct stu_info *b) {     return  (a->score[0] > b->score[0]             && fabs(a->score[0] - b->score[0]) > esp); }  int compare_as_math (struct stu_info *a, struct stu_info *b) {     return  (a->score[1] > b->score[1]             && fabs(a->score[1] - b->score[1]) > esp); }  int compare_as_english(struct stu_info *a, struct stu_info *b) {     return  (a->score[2] > b->score[2]             && fabs(a->score[2] - b->score[2]) > esp); }  void swap_stu_info(struct stu_info *a, struct stu_info *b, cmp compare_as_score) {     struct stu_info tmp;      if (compare_as_score(a, b)) {         tmp = *a;         *a = *b;         *b = tmp;     } }  void sort(struct stu_msg **head, cmp cmp_score) {     struct stu_msg *p, *q;      for (p = *head; p; p = p->next)         for (q = *head; q->next; q = q->next)             swap_stu_info(&q->info, &q->next->info, cmp_score); }  int main(void) {      return 0; } 参考一下吧有点疑惑，就是，为什么不直接在含有数据结构那里建立链表，而是选择再创一个结构体；还有一点就是cmp_score并没有这个，就直接用吗？

引用 3 楼 cfjtaishan 的回复:p1, p2无需申请空间，因为前面申请了空间，在for循环里, p1 = head已经将申请的空间的首地址覆盖了，p2 = p1->next，也是同样的覆盖，这样会导致内存泄漏。因为被覆盖后再也找不到刚刚申请的空间的位置了。 既然是排序操作，什么会有free操作呢？ 个人建议，为了好理解，可以考虑将数据部分交换，保留指针部分（地址部分） for (p1 = head; p1 != NULL; p1 = p1->next) 		for (p2 = p1->next; p2 != NULL; p2 = p2->next) 			if (p1->score[0] == p2->score[0]) 				if (p1->score[2] < p2->score[2])  				{ 					strcpy_s(t->Class, strlen(p2->Class) + 1, p2->Class); 					strcpy_s(p2->Class, strlen(p1->Class) + 1, p1->Class); 					strcpy_s(p1->Class, strlen(t->Class) + 1, t->Class); 					strcpy_s(t->name, strlen(p2->name) + 1, p2->name); 					strcpy_s(p2->name, strlen(p1->name) + 1, p1->name); 					strcpy_s(p1->name, strlen(t->name) + 1, t->name); 					strcpy_s(t->sex, strlen(p2->sex) + 1, p2->sex); 					strcpy_s(p2->sex, strlen(p1->sex) + 1, p1->sex); 					strcpy_s(p1->sex, strlen(t->sex) + 1, t->sex); 					strcpy_s(t->ID, strlen(p2->ID) + 1, p2->ID); 					strcpy_s(p2->ID, strlen(p1->ID) + 1, p1->ID); 					strcpy_s(p1->ID, strlen(t->ID) + 1, t->ID); 					t->score[0] = p2->score[0]; 					p2->score[0] = p1->score[0]; 					p1->score[0] = t->score[0]; 					t->score[1] = p2->score[1]; 					p2->score[1] = p1->score[1]; 					p1->score[1] = t->score[1]; 					t->score[2] = p2->score[2]; 					p2->score[2] = p1->score[2]; 					p1->score[2] = t->score[2]; 				}  struct student_message {     xxx data;    /*数据部分*/     struct student_message *next;    /*地址部分*/ }; 可是如果只是把数据部分调换，系统就会直接崩溃

引用 2 楼 hzy_76 的回复:你有多處這樣的操作：  t = p2; p2 = p1; p1 = p2; free(t);  注意這是鏈表，刪除節點必須在斷開處重新連接，比如p->next = x，缺了這步操作，以後遍歷鏈表到這裏時就會訪問到已釋放的内存，所以崩潰了。  另外，你的代碼縮進不太好，看著眼花，建議盡量不要在一行中寫多個語句。但我现在不是删除节点，而是想让两个节点的内容调换，应该怎么修改呢

数据结构对单链表进行数据排序 http://bbs.csdn.net/topics/392201633

p1, p2无需申请空间，因为前面申请了空间，在for循环里, p1 = head已经将申请的空间的首地址覆盖了，p2 = p1->next，也是同样的覆盖，这样会导致内存泄漏。因为被覆盖后再也找不到刚刚申请的空间的位置了。 既然是排序操作，什么会有free操作呢？ 个人建议，为了好理解，可以考虑将数据部分交换，保留指针部分（地址部分）   struct student_message {     xxx data;    /*数据部分*/     struct student_message *next;    /*地址部分*/ };

引用 7 楼 cfjtaishan 的回复:[quote=引用 6 楼 waitti 的回复:] [quote=引用 3 楼 cfjtaishan 的回复:] p1, p2无需申请空间，因为前面申请了空间，在for循环里, p1 = head已经将申请的空间的首地址覆盖了，p2 = p1->next，也是同样的覆盖，这样会导致内存泄漏。因为被覆盖后再也找不到刚刚申请的空间的位置了。 既然是排序操作，什么会有free操作呢？ 个人建议，为了好理解，可以考虑将数据部分交换，保留指针部分（地址部分） for (p1 = head; p1 != NULL; p1 = p1->next) 		for (p2 = p1->next; p2 != NULL; p2 = p2->next) 			if (p1->score[0] == p2->score[0]) 				if (p1->score[2] < p2->score[2])  				{ 					strcpy_s(t->Class, strlen(p2->Class) + 1, p2->Class); 					strcpy_s(p2->Class, strlen(p1->Class) + 1, p1->Class); 					strcpy_s(p1->Class, strlen(t->Class) + 1, t->Class); 					strcpy_s(t->name, strlen(p2->name) + 1, p2->name); 					strcpy_s(p2->name, strlen(p1->name) + 1, p1->name); 					strcpy_s(p1->name, strlen(t->name) + 1, t->name); 					strcpy_s(t->sex, strlen(p2->sex) + 1, p2->sex); 					strcpy_s(p2->sex, strlen(p1->sex) + 1, p1->sex); 					strcpy_s(p1->sex, strlen(t->sex) + 1, t->sex); 					strcpy_s(t->ID, strlen(p2->ID) + 1, p2->ID); 					strcpy_s(p2->ID, strlen(p1->ID) + 1, p1->ID); 					strcpy_s(p1->ID, strlen(t->ID) + 1, t->ID); 					t->score[0] = p2->score[0]; 					p2->score[0] = p1->score[0]; 					p1->score[0] = t->score[0]; 					t->score[1] = p2->score[1]; 					p2->score[1] = p1->score[1]; 					p1->score[1] = t->score[1]; 					t->score[2] = p2->score[2]; 					p2->score[2] = p1->score[2]; 					p1->score[2] = t->score[2]; 				}  struct student_message {     xxx data;    /*数据部分*/     struct student_message *next;    /*地址部分*/ }; 可是如果只是把数据部分调换，系统就会直接崩溃 [/quote] 不会崩溃，交换数据部分，不改变next指针的指向。如果你认为我的想法会导致程序崩溃，那么你理解我的交换方法有问题 建议将你的数据结构贴出来，我可以给你写个只交换数据部分，不修改next地址部分的排序[/quote]char ID[12]; 	char name[10]; 	char sex[6]; 	char Class[10]; 	float score[3]; 对分数进行排序，首先语文优先，是score[0]，然后在语文排好序的时候，对语文成绩相等的进行数学排序，同理再对英语

引用 6 楼 waitti 的回复:[quote=引用 3 楼 cfjtaishan 的回复:] p1, p2无需申请空间，因为前面申请了空间，在for循环里, p1 = head已经将申请的空间的首地址覆盖了，p2 = p1->next，也是同样的覆盖，这样会导致内存泄漏。因为被覆盖后再也找不到刚刚申请的空间的位置了。 既然是排序操作，什么会有free操作呢？ 个人建议，为了好理解，可以考虑将数据部分交换，保留指针部分（地址部分） for (p1 = head; p1 != NULL; p1 = p1->next) 		for (p2 = p1->next; p2 != NULL; p2 = p2->next) 			if (p1->score[0] == p2->score[0]) 				if (p1->score[2] < p2->score[2])  				{ 					strcpy_s(t->Class, strlen(p2->Class) + 1, p2->Class); 					strcpy_s(p2->Class, strlen(p1->Class) + 1, p1->Class); 					strcpy_s(p1->Class, strlen(t->Class) + 1, t->Class); 					strcpy_s(t->name, strlen(p2->name) + 1, p2->name); 					strcpy_s(p2->name, strlen(p1->name) + 1, p1->name); 					strcpy_s(p1->name, strlen(t->name) + 1, t->name); 					strcpy_s(t->sex, strlen(p2->sex) + 1, p2->sex); 					strcpy_s(p2->sex, strlen(p1->sex) + 1, p1->sex); 					strcpy_s(p1->sex, strlen(t->sex) + 1, t->sex); 					strcpy_s(t->ID, strlen(p2->ID) + 1, p2->ID); 					strcpy_s(p2->ID, strlen(p1->ID) + 1, p1->ID); 					strcpy_s(p1->ID, strlen(t->ID) + 1, t->ID); 					t->score[0] = p2->score[0]; 					p2->score[0] = p1->score[0]; 					p1->score[0] = t->score[0]; 					t->score[1] = p2->score[1]; 					p2->score[1] = p1->score[1]; 					p1->score[1] = t->score[1]; 					t->score[2] = p2->score[2]; 					p2->score[2] = p1->score[2]; 					p1->score[2] = t->score[2]; 				}  struct student_message {     xxx data;    /*数据部分*/     struct student_message *next;    /*地址部分*/ }; 可是如果只是把数据部分调换，系统就会直接崩溃 [/quote] 不会崩溃，交换数据部分，不改变next指针的指向。如果你认为我的想法会导致程序崩溃，那么你理解我的交换方法有问题 建议将你的数据结构贴出来，我可以给你写个只交换数据部分，不修改next地址部分的排序

在调试模式运行程序，崩溃了点中断，通过调用堆栈定位到相关代码，结合各变量值观察分析原因


Question: 一个简单的c程序，调试时候出现错误，求问是什么原因？

好，懂了，谢谢上面两位大佬

#include <stdio.h> #include <string.h>        //提供strlen()函数的原型  #define DENSITY 62.4    //人的密度（单位是：英镑/每立方英尺）  int main() {     float weight, volume;    //重量，密度     int size, letters;     char name[40]; //name是一个有40个字符的数组      printf("Hi,what's your first name?\n");     scanf_s("%s", name, 40);     printf("%s,what's your weight in pounds?\n", name);     scanf_s("%f", &weight);     size = sizeof name;     letters = strlen(name);     volume = weight / DENSITY;     printf("well,%s,your volume is %2.2f cubic feet.\n", name, volume);     printf("Also,your first name has %d letters.\n", letters);     printf("and we have %d bytes to score it in\n", size);      getchar();      return 0; } 参考一下吧  注意name是字符数数组，%s输入时去掉name前的&，因为name是数组名，本身就是地址，因此不需要再加& 另外，scanf_s需要对于%s指定字符数组的长度

scanf_s输入字符串时还需要一个数组大小的参数    #include <stdio.h> #include <string.h>        //提供strlen()函数的原型 #define DENSITY 62.4    //人的密度（单位是：英镑/每立方英尺）  int main() { 	float weight, volume;    //重量，密度 	int size, letters; 	char name[40]; //name是一个有40个字符的数组  	printf("Hi,what's your first name?\n"); 	scanf_s("%s", name, 40); 	printf("%s,what's your weight in pounds?\n", name); 	scanf_s("%f", &weight); 	size = sizeof name; 	letters = strlen(name); 	volume = weight / DENSITY; 	printf("well,%s,your volume is %2.2f cubic feet.\n", name, volume); 	printf("Also,your first name has %d letters.\n", letters); 	printf("and we have %d bytes to score it in\n", size);  	getchar();  	return 0; }


Question: 求100以内的素数，且每5个为一行。 哪里错了，求指导。

#include<stdio.h> int i,j,n=0,a[101]; void main() { 	for(i=0;i<100;i++)		//将数组赋值 		a[i]=i+1; 	printf("输出素数:\n"); 	a[0]=0; 	for(i=1;i<100;i++) 	{ 		for(j=2;j<i;j++) 		{ 			if(a[i]%j==0) 				a[i]=0;		//将不是素数的变为零 		} 	} 	for(i=0;i<100;i++) 	{ 		if(a[i]!=0) 		{ 		printf("%d ",a[i]); 		n++;				//换行 		if(n%5==0) 			printf("\n"); 		} 	}  } 不好意思啊，前两天一直有事。我已经改好了，谢谢各位的帮忙。

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

“多一少一”问题占程序员常犯错误的10%以上！ 避免“多一少一”问题的方法之一是将比如<10甚至<5的数代入程序片断，掰手指头心算验证一下程序到底应该写为 x、x-1、x+1中的哪个？ <、<=、==、>、>=中的哪个？

#include<stdio.h>   int main() {     int i, j, n = 0,a[100];     for(i = 0; i < 100;i++)         a[i] = i + 1;      printf("输出素数:\n");     for(i = 0; i < 100;i++) {         if (a[i] == 1)             a[i] = 0;         for(j = 2;j<i;j++)         {             if(a[i] % j == 0)                 a[i] = 0;         }         if(a[i]!=0) {             printf("%2d ",a[i]);             n++; //换行             if(n%5==0)                 printf("\n");         }     }  } 参考一下吧，程序有多个逻辑错误。建议对比参考一下

引用 3 楼 qq_41761210 的回复:啥边界条件？？？ 这个地方就是注意边界： for(i=1;i<=100;i++) //将数组赋值 a[i]=i; 应该改成：     for(i = 0; i < 100;i++) //将数组赋值         a[i] = i; 因为数组长度是100，下表应该从0开始，即[0, 99]，下表若为100，则属于越界访问

啥边界条件？？？

printf("/n");   =====> printf("\n");      斜杠反了

边界条件 输入输出格式 ……

刚才在上课回复慢了


Question: 大神帮帮忙-数字图像处理-图像旋转-fclose处无故跳出

仅供参考：#include <math.h> #include <string.h> #include <stdio.h> #include <windows.h> #include <gdiplus.h> #pragma comment(lib, "gdiplus.lib") using namespace Gdiplus; wchar_t formats[5][11]={     L"image/bmp",     L"image/jpeg",     L"image/gif",     L"image/tiff",     L"image/png", }; wchar_t exts[5][5]={     L".bmp",     L".jpg",     L".gif",     L".tif",     L".png", }; int GetEncoderClsid(const WCHAR* format, CLSID* pClsid) {    UINT  num = 0;          // number of image encoders    UINT  size = 0;         // size of the image encoder array in bytes    ImageCodecInfo* pImageCodecInfo = NULL;    GetImageEncodersSize(&num, &size);    if(size == 0) return -1;  // Failure    pImageCodecInfo = (ImageCodecInfo*)(malloc(size));    if(pImageCodecInfo == NULL) return -1;  // Failure    GetImageEncoders(num, size, pImageCodecInfo);    for (UINT j = 0; j < num; ++j) {       if ( wcscmp(pImageCodecInfo[j].MimeType, format) == 0 ) {          *pClsid = pImageCodecInfo[j].Clsid;          free(pImageCodecInfo);          return j;  // Success       }    }    free(pImageCodecInfo);    return -1;  // Failure } int wmain(int argc,wchar_t *argv[]) {     int r=1;     if (argc<4) {     USAGE:         wprintf(L"%s srcimg.{bmp|jpg|gif|tif|png|wmf|emf|ico}  desimg.{bmp|jpg|gif|tif|png}  angle\n",argv[0]);         return r;     }     int i;     for (i=0;i<5;i++) {         if (0==_wcsicmp(argv[1]+wcslen(argv[1])-4,exts[i])) break;     }     if (i>=5) goto USAGE;     for (i=0;i<5;i++) {         if (0==_wcsicmp(argv[2]+wcslen(argv[2])-4,exts[i])) break;     }     if (i>=5) goto USAGE;     GdiplusStartupInput gdiplusstartupinput;     ULONG_PTR gdiplustoken;     GdiplusStartup(&gdiplustoken, &gdiplusstartupinput, NULL);     {         Image img(argv[1]);         if (Ok==img.GetLastStatus()) {             UINT height = img.GetHeight();             UINT width  = img.GetWidth();             REAL angle;             if (1==swscanf_s(argv[3],L"%f",&angle)) {                 REAL size;                 size=(REAL)sqrt(1.0*width*width+1.0*height*height);                 Matrix mat;                 mat.Translate(size / -2.0f, size / -2.0f);                 mat.Rotate(-angle, MatrixOrderAppend);                 mat.Translate(size / 2.0f, size / 2.0f, MatrixOrderAppend);                 PointF pfTL((size-width)/2.0f      ,(size-height)/2.0f       );                 PointF pfTR((size-width)/2.0f+width,(size-height)/2.0f       );                 PointF pfBL((size-width)/2.0f      ,(size-height)/2.0f+height);                 PointF pfBR((size-width)/2.0f+width,(size-height)/2.0f+height);                 Graphics tgp(&img);                 Bitmap bmp((UINT)size,(UINT)size,&tgp);//Let bmp Resolution equal to img Resolution                 Graphics gp(&bmp);                 gp.SetTransform(&mat);                 gp.DrawImage(&img,pfTL);                 REAL xmin,ymin,xmax,ymax,x,y,rw,rh;                 mat.TransformPoints(&pfTL);                 xmin=xmax=pfTL.X;                 ymin=ymax=pfTL.Y;                 mat.TransformPoints(&pfTR);                 if (xmin>pfTR.X) xmin=pfTR.X;                 if (xmax<pfTR.X) xmax=pfTR.X;                 if (ymin>pfTR.Y) ymin=pfTR.Y;                 if (ymax<pfTR.Y) ymax=pfTR.Y;                 mat.TransformPoints(&pfBL);                 if (xmin>pfBL.X) xmin=pfBL.X;                 if (xmax<pfBL.X) xmax=pfBL.X;                 if (ymin>pfBL.Y) ymin=pfBL.Y;                 if (ymax<pfBL.Y) ymax=pfBL.Y;                 mat.TransformPoints(&pfBR);                 if (xmin>pfBR.X) xmin=pfBR.X;                 if (xmax<pfBR.X) xmax=pfBR.X;                 if (ymin>pfBR.Y) ymin=pfBR.Y;                 if (ymax<pfBR.Y) ymax=pfBR.Y;                 x=xmin;                 y=ymin;                 rw=xmax-x;                 rh=ymax-y;                 Bitmap* clone;                 clone = bmp.Clone(x,y,rw,rh,PixelFormat24bppRGB);//bmp.GetPixelFormat()                 CLSID encoderClsid;                 if (0<=GetEncoderClsid(formats[i],&encoderClsid)) {                     if (Ok==clone->Save(argv[2],&encoderClsid)) {                         wprintf(L"OK to %s  %s  %s  %s\n",argv[0],argv[1],argv[2],argv[3]);                         r=0;                     } else {                         wprintf(L"Error to save %s\n",argv[2]);                         r=4;                     }                 } else {                     wprintf(L"Error to GetEncoderClsid(%s,...)\n",formats[i]);                     r=3;                 }                 delete clone;             } else {                 wprintf(L"Error to get angle %s\n",argv[3]);                 r=2;             }         } else {             wprintf(L"Error to load %s\n",argv[1]);             r=5;         }     }     GdiplusShutdown(gdiplustoken);     return r; }

printf("输入影像文件名: "); scanf("%s", &file_name); 这个地方有问题，file_name是数组名，本身就是地址。 因此应改成这样：去掉& printf("输入影像文件名: "); scanf("%s", file_name);


Question: 关于 数据结构 队 的结构体类型的问题

1、节点类型是一样的啊，都是QNode，第二个只是一个结构体，装指向前和后的节点指针，具体没在你代码中看到有应用，当然链并不一定要求一写要是双链，你也可以只是一个单链，如第一个结构体，只有next指针  2、QNode是一个节点的指针，而LiQueue需要根据实际代码判断含义，也可能表示最前与最后的指针  3、如果没初始，这个值是一个随机值，只有上帝知道它指向哪。。

2、data存的是该节点的数据信息  3、对整体没什么影响，只是影响各个节点存的数据的情况

1、表示一个结点的，但这个节点除了记录自己的信息，还记录了前一个和后一个节点的地址


Question: 请问这段代码错在哪儿？

引用 6 楼 flybird7070 的回复:不是的，写错了。  前面提问时，我写的 if(fangfa==atoi ((char  *)(strstr(buf, B)+6)))//这一句出错，编译通过，运行当掉 strstr(buf, B);这句若返回NULL没有去处理,atoi返回值肯定会导致程序异常退出。另外，buf是否给予分配空间？

谢谢各位，问题解决了，是超出边界了。

strstr(buf, B)+6超出边界或者不是数字字符串

if(fangfa==atoi ((char  *)(strstr(buf, B)+6))) 改为 char* temp = strstr(buf, B)+6;这里加断点，调试 if( fangfa == atoi(tmp) ) {  // }

int fangfa=3; if (strcmp(B,B_文本)==0){//判断是否是相同字符串   if(atoi ((char  *)(strstr(buf, B)+6))==*fangfa)  int类型是这样子用的吗

提醒一下 不要刻意的去隐藏中间变量

我的目的是在文本文件中，读取一行  这行的内容是这样的：“================文本46”  一下代码我运行正常，结果也准确  int* weizhi_标记_文本; if (strcmp(B,B_文本)==0){//判断B中是否有字符串“==文本”   * weizhi_标记_文本=atoi ((char  *)(strstr(buf, B)+6))-1;//如果有“文本”字符串，就把“文本”后的数字存入* weizhi_标记_文本 }  然而，我想如果文本后的数字等于3，就把数字3存入* weizhi_标记_文本，修改如下：  int fangfa=3;  if (strcmp(B,B_文本)==0){//判断是否是相同字符串   if(atoi ((char  *)(strstr(buf, B)+6))==*fangfa){//这里出错，不能运行，请修正           * weizhi_标记_文本=atoi ((char  *)(strstr(buf, B)+6))-1;      } }

buf没有初始就使用，其次strstr查找不到返回的是NULL，此时传atoi也会导致崩溃

前面是通过内存映射，得到lpbMapAddress  然后有const char* buf = lpbMapAddress;   省略了


Question: 怎么在头文件中定义一个在运行时确定的地址常量？

定义成全局变量，初始化为一个地址值是可以的。怎么不可以呢？ 也可以定义一个函数，然后将地址值赋值给这个全局变量。运用该全局变量前就去调用一下该函数（建议定义成内敛函数inline）

xxx.h中写：  const char * GetAddr();   xxx.cpp中写  const char * GetAddr() {     return strcat((char*)getcwd(NULL,0),"/..."); }   需要用到addr的地方就include这个xxx.h，调用GetAddr()就可以了

头文件声明，实现文件定义并且指向一个变量？


Question: C语言program received signal sigsegv是怎么回事

引用 3 楼 user-1 的回复:scanf（%c）前要有getchar（）！ 已改  但还是不行

仔细检查一下！应该没什么大问题！

scanf（%c）前要有getchar（）！

最基础的错误:等于号是“＝＝”！


百度搜“netbd.h”。


Question: 新手 定义问题

#include<stdio.h> #include <stdlib.h>  void average(int *parr, int len) {     int *end = parr + len;     float sum = 0.0, aver;      for(; parr < end; parr++)         sum = sum + *parr;     aver = sum / len;      printf("平均成绩为：%5.2f\n", aver); }  //void average(int *n, int m);  int main() {      int *p, **arr;     int i, j, f, g;     int col, row;      printf("请输入您的数据组数:\n");     scanf("%d", &row);     scanf("%d", &col);     arr = (int **)malloc(sizeof(int*) * row);     if (!arr)         exit(0);     for (i = 0; i < row; i++) {         arr[i] = (int *)malloc(sizeof(int) * col);         if (!arr[i])             exit(0);     }      printf("请输入您的数据:\n");     for (i = 0; i < row; i++)         for (j = 0; j < col; j++)         scanf("%d", &arr[i][j]);      p = &arr[0][0];     average(p, row * col);      printf("请输入你想要第几组第几个数据：");     scanf("%d%d", &f, &g);     if ((f >= 0 && f < row) && (g>= 0 && g < col))         printf("%d\n", arr[f][g]);     return 0; } 参考一下吧； 对于二维数组作为参数search，至少要确定列数。 基础知识还需要巩固，以上的代码参考一下吧

VC不支持如下写法，也不支持可变长数组VLA：  void search(int a[h][y]) int h,y;

求大佬们指教


Question: 这个哪里错了？

#include<stdio.h> #include <stdlib.h>  struct Student {     long int num;     char name[32];    /*name应该是用字符数组*/     float score; };  int main() {     int i,n;     float average,sum=0;     //struct Student temp;     scanf("%d",&n);     struct Student *stu = (struct Student *)malloc(sizeof(struct Student) * n);     if (!stu)         exit(0);     for(i=0;i<n;i++)     {         scanf("%ld %s %f",&stu[i].num, stu[i].name, &stu[i].score);         sum+=stu[i].score;     }     average=sum/n;     printf("%.2f",average);     for(i=0;i<n;i++)     {         if(stu[i].score<average)             printf("%s %ld\n",stu[i].name,stu[i].num);     }     free(stu);      return 0; }  参考一下吧  2个问题: 第一个：name因该是用字符数组，用%s，则后面直接跟数组名即可(stu[i].name) 第二个：由于数组长度不是在编译时确定，因此建议使用动态申请空间方式获取stu

建议把程序改成几个函数，更容易找出错误

补充一下题目 给定N个学生的基本信息，包括学号（由5个数字组成的字符串）、姓名（长度小于10的不包含空白字符的非空字符串）和成绩（[0,100]区间内的整数），要求计算他们的平均成绩，并顺序输出平均线以下的学生名单。  输入格式： 输入在一行中给出正整数N（≤10）。随后N行，每行给出一位学生的信息，格式为“学号 姓名 成绩”，中间以空格分隔。  输出格式： 首先在一行中输出平均成绩，保留2位小数。然后按照输入顺序，每行输出一位平均线以下的学生的姓名和学号，间隔一个空格。  输入样例： 5 00001 zhang 70 00002 wang 80 00003 qian 90 10001 li 100 21987 chen 60 输出样例： 80.00 zhang 00001 chen 21987


Question: 请教大佬帮我看看代码为什么打印不出嵌套结构体的内容？要怎么修改

#include <stdio.h> #include <stdlib.h> #include <string.h> #include <ctype.h>  void save(char *name, int n); int readout(char *name, char *type); void outwait(char *name); void deletefile(char*name);   //声明定义结构体 struct student_info {     char name[30];     char ifbook[5];     int cnt;     struct bookman{         char waitname[30];     }book[40]; } info[170];  //char filename[50] = "D:\\progra.txt"; char filename[50] = "a.txt"; char type[10]; char *p;  void save(char *name, int n) {     FILE *fp;     int i;     if ((fp = fopen(name, "w")) == NULL) {         printf("文件打开错误\n");         exit(0);     }     for (i = 0; i < n; i++) {         if (fwrite(&info[i], sizeof(struct student_info), 1, fp) != 1)             printf("文件写入错误");     }     fclose(fp);     printf("Write successfully!\n"); } int readout(char *name, char *type) {     int i,a;     FILE *fp;     if ((fp = fopen(name, type)) == NULL) {         printf("文件打开错误\n");         system("pause");         exit(0);     }      printf("\n=================================\n");     printf(" 名称\t是否预约 *\n");     for (i = 0; fread(&info[i], sizeof (struct student_info), 1, fp) != 0; i++) {         printf("%s\t  %s*\n", info[i].name, info[i].ifbook);     }     printf("=========================================\n");     printf("共有 %d 条记录\n\n", i);     fclose(fp);     return i; } void deletefile(char *name) {     FILE *fp;     int choice;     char delfilename[50];     printf("确定删除当前文件?\n");     printf("1、确定    2、取消\n您的选择是：");     scanf("%d", &choice);     switch (choice) {         case 1:             printf("确定\n");             if (remove(filename) == 0)                 printf("文件删除成功!\n");             else                 printf("文件删除失败!\n");             break;         case 2:             printf("取消\n");             break;         default:             printf("选择错误 !\n");             break;     } }  void outwait(char*name) {     char find[30];     int i, l, number;     strcpy(type, "r");     number = readout(filename, type);     /*     FILE *fp;     if ((fp = fopen(name, "r")) == NULL)     {         printf("文件打开错误\n");         system("pause");     }     */     printf("Read info number = %d\n", number);     printf("请输入名称：");     scanf("%s", find);     printf("预约名单如下\n名称\n");     for ( i = 0; i < number; i++)     {         if(strcmp(find,info[i].name)==0)         {             printf("%d\n", i);             printf("wait number = %d\n", info[i].cnt);             for (l = 0; l < info[i].cnt; l++) {                 printf("%s\n", info[i].book[l].waitname);             }          }     }     printf("\n%d",l);     //fclose(fp); } int main() {     int i, n,choice,l,t;     char boname[30];     int y,m,d;     printf("请输入您要添加的个数：");     scanf("%d", &n);     printf("\n您将会将 %d 信息记录存储到 %s 文件中\n\n", n, filename);      for (i = 0; i < n; i++) {         printf("请输入名称:");         scanf("%s",info[i].name);         printf("\n是否有人预约\n【1】有\t【2】无\n您的选择是：");         scanf("%d",&choice);         switch(choice){             case 1:                 {                     strcpy(info[i].ifbook,"是");                     printf("请输入您要添加的预约人数:");                     scanf("%d",&t);                     info[i].cnt = t;                     for(l=0;l<t;l++)                     {                         printf("\n请输入预约人名字：");                         scanf("%s",info[i].book[l].waitname);                      }                     break;                 }             case 2:                 {                     strcpy(info[i].ifbook,"否");                     break;                 }         }     }     save(filename, n);     outwait(filename);     deletefile(filename); }  参考一下吧  readout已经将waitname从文件里读取到了，不需要再次通过fread读取。 个人建议所有的操作都在内存里进行，而不用实时的去文件里读取

调试是基本功


Question: [C语言]C语言小白求解答

引用 楼主 feitianqixia的回复:char sex; 	int count = 0; 	for (;;) 	{ 		printf("请输入性别："); 		scanf("%c",&sex); 		fflush(stdin); 		if (sex != 'm' && sex != 'M' && sex != 'f' && sex != 'F') 		{ 			break; 		} 		count++; 	} 	printf("您一共输入正确%d次\n", count); 为什么输入字符f后按回车，程序直接跳出循环结束了？求解答，谢谢 没有进去for 循环的条件

在每个最后不带\n的printf后面加fflush(stdout); 在每个不想受接收缓冲区旧内容影响的scanf前面加rewind(stdin); 另外请检查scanf的返回值。 //请今后要用 char c; scanf("%c",&c); //时，都改为 char s[2]; char c; scanf("%1s",s); c=s[0]; //自动跳过一个或多个空格或Tab字符或回车换行，读取下一个字符。

int main(void) {     char sex;     int count = 0;     for (;;)     {         printf("请输入性别：");         scanf("%c",&sex);         getchar();         if (sex != 'm' && sex != 'M' && sex != 'f' && sex != 'F')         {             break;         }         count++;     }     printf("您一共输入正确%d次\n", count);     return 0; } 参考一下吧 因为fflush(stdin);没有起作用。该fflush对于stdin是未定义的。即它不能起到刷新输入缓冲区的作用。建议用getchar();但是这个需要每次只能输入一个字符然后换行，否则结果也是未定义的。

应该是没用getchar（）,这个错误很常见，用它吃空格！

scanf("%c",&sex); 		getchar();

回车不属于 'm' 'M', 'f', 'F' 自然就 break 结束了呀


Question: 关于结构体类型转换

不是逻辑问题，而是单词拼写错误问题：student_message不要写成student_messsge，message是多个s少个a


Question: 编写函数统计单词个数，为什么n的返回值是1（求改正，谢谢！）

#include <stdio.h>  int Fun(char cString[]) {     int iWord = 1, i;      for(i = 0; cString[i]!='\0'; i++) {         putchar(cString[i]);         if(cString[i] == ' ' && cString[i+1] != ' ')             iWord++;      }      return iWord; }  int main() {     char str[100];     int iResult = 0;      printf("请输入一个字符串:\n");     //scanf("%s",str);     fgets(str, 100, stdin);     iResult = Fun(str);     printf("单词个数是:%d\n",iResult);     return 0; }  scanf(“%s”, str);是格式化输入，以空格作为多个输入的分割，遇到空格则完成对str的输入。 建议使用fgets

统计单词个数，简单点可以这样判断，逐个判断字符串的字符，判断当前这个是有效字符（比如A-Z，a-z,0-9，我这里只把英文和数字作为判断是属于单词的有效字符），并且下一个字符不是有效字符的话，单词数就增加1 #include<stdio.h>  int isNumber(char chtmp) //判断是否数字 {   if(chtmp>='0'&&chtmp<='9')   {     return 1;   }   return 0; } int isAlpha(char chtmp)  //判断是否字母 A-Z，a-z {   if(chtmp>='a'&&chtmp<='z')   {     return 1;   }   else if(chtmp>='A'&&chtmp<='Z')   {     return 1;   }   else   {     return 0;   } } int isWord(char chtmp)//判断是否有效字符（字母或者数字） {   if(isNumber(chtmp)||isAlpha(chtmp))   {     return 1;   }   else   {     return 0;   } }  int countWord(char* stringtmp)//计算单词个数 {   int i=0;   int countword=0;   while(stringtmp[i]!=0)//直到结束字符位置   {      if((isWord(stringtmp[i])==1)&&(isWord(stringtmp[i+1])==0))//满足当前字符是有效字符，下一个字符不是有效字符就自增      {        countword++;      }      i++;   }   return countword; }   int main() { char str[100]; int iResult=0; printf("请输入一个字符串:\n"); scanf("%s",str); iResult=countWord(str); printf("单词个数是:%d\n",iResult); return 0;  }  //比如这里的计算单词数量 只执行这两句 char chtest[]="hello   world!this  is 100";    int count=countWord(chtest);//这里的单词数量是5


Question: 关于用 顺序栈 判断 括号是否匹配 的问题

这个不应该是 不匹配 么？

引用 2 楼 not_Englishname 的回复:还是不对呀，程序依旧不是正确结果 你测试的demo发一下，或者截个图； 我在我的环境里测试没有问题

还是不对呀，程序依旧不是正确结果

#include<stdio.h> #include<string.h>  int match(char exp[],int n) {     //char stack[100];     int top = -1, i;      for(i=0;i<n;i++)     {         if(exp[i]=='(')         {             ++top;             //stack[top]='(';         }         else if(exp[i]==')')         {             if(top==-1)                 return 0;             else                 --top;         }     }     if(top==-1)         return 1;     else         return 0; }  int main() {     char exp[100];     int ret;      printf("请输入要判断的字符串：\n");     gets(exp);     printf("%s\n",exp);      ret = match(exp,strlen(exp));     if(ret)         printf("匹配");     else         printf("不匹配");      return 0; } gets没什么问题，只是会影响安全（不能确定输入的长度）； 并且，已经输出了exp的内容，只要保证输入的输出的一致就没问题。


Question: C语言\t的相关问题

检查下你%s连接的字符串里面是不是有换行符？

建议贴出你的code，\t一般是table键，不会是换行

求解


Question: while(scanf("%s",p)!=EOF)循环为什么无法结束？

LINUX：ctrl+d,windows: ctrl+z输入EOF

<Enter> <Ctrl-Z> <Enter>

VS要连续输入三次<ctrl+z>、Enter才行

引用 3 楼 Micope 的回复:那标准输入如何判断数据是否结束？ 输入ctrl+d或ctrl+z就是表示文件的末尾，scanf会返回EOF。

那标准输入如何判断数据是否结束？

EOF是文件结束标志，标准输入要输入EOF需要通过通过输入键盘组合键，ctrl+d（Linux）或ctrl+z（Windows)

用 Ctrl + D(Linux) 或者 Ctrl + Z(Windows) 结束输入


Question: c语言求解

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

原因1，浮点存储的是底数+指数。你看一个符号字节，表示 -128 ~ 127的范围，负数能表示的绝对值要比正数多1. 指数， 也有正负。负的指数范围稍稍宽一倍。其实，没有什么用处。 原因2，浮点溢出后，会产生INF这样的异常值，导致很多不可预测的行为。与INF运算后，很多后续结果都会溢出。而换成倒数后，会溢出为0，这个是一个无穷小的近似值，不会引起后续计算的异常。

数字太大存不下就会溢出  存到什么变量里?

引用 1 楼 das白的回复:数字太大存不下就会溢出  存到什么变量里? 而且 我觉得这两个式子不是等价的吗，为啥一个溢出一个不溢出

引用 1 楼 das白的回复:数字太大存不下就会溢出  存到什么变量里? 范围是什么？？实际数据也没超过int的范围阿 输入6位数就溢出了。


Question: c语言求助

这里不是定义了，STU  n={10006,"ZhaoSi", 55, 70, 68}, ss[N];  这里同时定义了一个STU类型的n并初始，同时定义了一个STU[N]类型的ss  如果觉得这种写法可读性不强，建议分成两行来写

STU  n={10006,"ZhaoSi", 55, 70, 68}, ss[N]; 注意此处。定义了n并初始化了，后面同时定义了ss数组，这个是属于逗号运算符，ss也是被定义了。

在這一行中  STU  n={10006,"ZhaoSi", 55, 70, 68}, ss[N];  ss是一個長度為N的STU結構體數組


Question: 关于字符数组问题

越界访问不是每次都能出现异常的（比如段错误），这是这个越界操作是未定义行为，即有可能越界的数据没有占用不可以写的内存，此时是正常的，但是若越过了不能写的区域，那么就会导致异常，比如段错误；越界访问也可能会将别的数据覆盖，导致程序运行异常。因此越界访问不是编译能检测出来的，而是需要编程的人去控制和避免；

对于你的问题我感觉很疑惑  这是一个基础问题 对于char[]来讲 如果你的下标是5 那么你只能输入4个数字 最后一个保存\0 如果对于int[]来讲 如果你的下标是5  那么你可以输入5个数字 只要每个数字不超过int所支持的最大数字就行 如果你越界保存 可能有问题 也可能没问题 但是这是大忌 小心内存越界

大于就越界啦，越界不是编译问题，可能覆盖了其他数据，造成程序崩溃，就算没崩溃也证明不了什么，最多说明运气好


Question: 建造BST的问题，之后中序遍历时候结果正确，时而错误，恳请各位帮忙解答一下

引用 1 楼 hdt 的回复:BiTree Insert(BiTree T,int v){ if(T==NULL){ T=(BiTree)malloc(sizeof(BiTree));//这句话改为 T=(BiTree)malloc(sizeof(TNode));谢谢~


Question: 请教大神，LCC-WIN32下编译问题

这执行结果不是一样吗

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

非常感谢，我去试试

换一下文件的目录, 不要使用中文和空格试试

求大神不吝赐教啊...拜谢...


Question: 求大神

有可能用的中文分号

他的其实也有问题， 及格 后面没有break 你的 switch后面有分号，语法错误

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

switch  后的分号去掉

不是长得帅，而是缺少一个break；在printf("及格\n");后面缺少一个break; 可能是不全本身就是一种美，所以你比他长得帅。  另外，第二个switch后面去掉分号

switch那一行仔细看看

switch  后的分号应该没有。

switch語句後面的分號，刪掉。


Question: 新手，为什么（*B）.name 输出的是地址

注意对于结构体中，name是数组名，数组名本身就是数组的首地址，并且以%d输出，自然是输出的地址（但是这个地址可能不正确，因为地址是无符号数，一般是%u或者%p格式输出的）。

#include<stdio.h> #include"stdafx.h" struct student { 	int  name[20]; }; struct student A[100]; int main() { struct student *B; //struct student A[100]; int count=0; int y,C=0;    do   {   scanf("%d",&A[count++].name);    }while((y=getchar()) != '\n');  /*for(B=A;C<1;B++)   C++;*/  B=A;  printf("%d\n",(*B).name[0]);   return 0; } 你先将程序改成这样看看为什恶魔这样就能输出3，看看数组是怎么赋值的，还有的for循环有问题。

谢谢大佬们，解决了

求大佬们教导


Question: 大一新生 学完c后怎么提升

编点感兴趣的小程序练手

要多练习才能更好的进步，自己给自己找一些项目来做；

我觉得先不要多看语言，先把基础打牢，基础不牢看得越多就越散，基础打牢了学其他语言就快，而且有一个主打的语言，不会一盘散沙。谭浩强的书我不觉得差，但从知识来说只能算入门的一半。

算法了解下，我倒是觉得大学培养兴趣很重要，要达到工作水平太难了，因为工作做得项目有具体的框架支撑和针对性，这样的东西在学校是很难接触到的，打好基础吧

lz试试编写一些自己上网用得上的东西 在编写一些较难的东西 这就是在应用中进步 对以后搞程序总规划也有好处  引用 40 楼 zhao4zhong1 的回复:[quote=引用 14 楼 pkuzhx 的回复:] 楼主是要参加acm的，楼上好几位都指偏了 个人意见：参加acm才是真偏了！[/quote]

看你以后打算往哪方面发展.....C只是一个基础，一个开端，但你学了C之后以后学其他语言压力就会小很多。如果你只是想磨炼你的C语言技术，强烈推荐你多动手编程序而不是看书，比如从网上下一个编程100题，他的难度都是递增的，要是觉得太简单可以跳着做，然后写一点简单的游戏啦，比如猜数字，贪吃蛇这类。或者别的你感兴趣的事物，比如判断密码强度的程序，图书管理程序啦这种很多。如果你想了解以后到底往那方向发展，建议你多问问老师，用纯C的不多，像我们专业是学习嵌入式开发、单片机这一类的，纯C用的比较多，别的我不知道哪里还有纯C的....有也用的，但是用的很少吧。

Compiler Theory, 编译理论。

引用 14 楼 pkuzhx 的回复:楼主是要参加acm的，楼上好几位都指偏了 个人意见：参加acm才是真偏了！

上面有很多误导人的，别入坑~

多看书，多敲代码

楼主，如果你觉得C基础都学完了，精通了，那么请把C标准库手动敲上几遍，把它弄懂就差不多了，那些非标准库在要用到时再了解也来的及的

把其他课程作业用C认真实现就好了。数据结构、算法导论/计算方法、数字信号处理、计算机图形学等等，动手第一。

笨办法学C 中文版  https://caimaoy.gitbooks.io/learn-c-the-hard-way/content/ 了解一下

慢慢做呗。每天比别人多做2小时，不够再加2小时。只要努力能解决大部分问题。

C语言教程（附带C语言100例）http://download.csdn.net/detail/zhao4zhong1/8830817

引用 6 楼 wyyy2088511 的回复:c++，windows编程，linux下编程 Windows编程还是直接略过吧

个人觉得还是基础打牢

第一阶段<<C primier plus>> <<C专家编程>> 还有林锐的《高质量C编码》 第二阶段 数据结构C语言版，弄本国外经典的教材，国内严蔚敏的太深奥 第三阶段LINUX C编程，弄本国外经典的教材

套接字、网络编程tcp，ip 进程 结合系统命令的C语言编程 C语言结合图形化编程 嵌入式C语言编程 C语言数据结构（算法） …………很多的其实……

没什么好办法，找Ｃ代码敲敲在敲，熟悉了在说，这是最笨也是最有效的办法。


Question: c语言问题

第一个getchar()若是接收了一个除换行符之外的字符，那么第二个getchar()就接收了一个换行符，因为输入缓冲区是属于行缓冲，即只有输入换行符才会将输入缓冲区里的数据刷到内存里，而输入回车后，换行符也会残留在内存里，此时第二个getchar()就接收了这个换行符，所以输出的是一个空行和123 解决办法是：要么去掉第一个getchar();要么第一个输入直接输入一个换行符，再次输入有效字符；

想要什么结果...

编译没有问题，运行不出想要的结果怎么办？？？


Question: 求大牛解惑，单链表的问题

感觉...自己设置断点调试一下吧 看哪些值不符合预期 调试是程序员必备技能啊

9 7这个是两个字符 不是九十七

大牛在哪里？

引用 8 楼 user-2的回复:[quote=引用 7 楼 not_Englishname 的回复:] [quote=引用 5 楼 user-2的回复:]如果你要按数字存储，需要对程序相应地方进行调整，如char data; 要改成int data;  接收输出时用%d，以及输入结束的判断等等 用char定义的话 是不是要定义字符串 char*？[/quote]  是的，字符数组，char*你需要先分配好内存[/quote] 感谢大牛  新年快乐啊！

引用 7 楼 not_Englishname 的回复:[quote=引用 5 楼 user-2的回复:]如果你要按数字存储，需要对程序相应地方进行调整，如char data; 要改成int data;  接收输出时用%d，以及输入结束的判断等等 用char定义的话 是不是要定义字符串 char*？[/quote]  是的，字符数组，char*你需要先分配好内存

引用 3 楼 das白的回复:9 7这个是两个字符 不是九十七 那用char定义的，想要输出97就得定义字符串 char*么？

因为你是一个字符一个字符存进去的，而不是一个数字整体存储的

引用 5 楼 user-2的回复:如果你要按数字存储，需要对程序相应地方进行调整，如char data; 要改成int data;  接收输出时用%d，以及输入结束的判断等等 用char定义的话 是不是要定义字符串 char*？


Question: 新手问个简单的异常问题了

数组名称 本身就代表整个数组第一个元素的地址 你用指针去指向一个地址 不是不可以 你可以使用二级指针，不过不推荐。

上边笔误  &a 代表一个指针，它指向的内容是一个包含两个元素的整形数组，不能简单的把&a理解为一个二级指针

int a[2]; int *p=&a ;//错误 int **p = &a;//错误 &a 代表一个指针，它指向的内容是一个包含两个元素的整形数组，不能简单的把&a理解为一个二级数组 int (*p)[] = &a;//错误，因为p指向的数组没有定义大小 int (*p)[3]=&a;//错误，因为p 指向的数组长度与a不符 正确的写法是 int (*p)[2]=&a; 当然你也可以强制转换 比如 int *p =(int*)(&a);

去掉& i本身就代表数组首地址

int *p = i;  或者：  int *p = &i[0];  否则类型不对


Question: 这段代码有错误么，为什么老是显示ld.exe||cannot open output file D:\Documents\XU.exe Permission d

有的时候不知道怎么确认环境问题~

#include<stdio.h> #include<stdlib.h> #include<string.h>  struct link {     char name[20];     char password[20];     struct link *next; } link,*linklist;   int main() {      struct link *L;     L = (struct link*)malloc(sizeof(struct link));     if (!L)         exit(0);     strcpy(L->name,"oooo");     strcpy(L->password,"pppp");      printf("%s\n",L->name);     printf("%s\n",L->password);     L->next=NULL;     free(L);      return 0; } 程序没问题，建议检查配置环境

代码没问题，出现原因可能是杀软或什么占用着，以致不能重新生成程序，一般重启或者去任务管理器结束了，或者新建另一个工程可正常

现在去编译又很正常，这段代码没有什么实际意义，但是昨天老是出错


Question: 关于“无法将参数 1 从“int”转换为“const char *””的问题

引用 1 楼 真相重于对错的回复:和库函数重名了 scanf改个名字 可以了，非常感谢啊！

和库函数重名了 scanf改个名字


Question: 求大牛解答 头插法建立单链表 以及 输出

输入输出类型不一样 输出改为 %c 别%d

printf("%d", p->next->data);  应该改成：  printf("%c", p->next->data);  你里面存的是字符，你按整数输出实际输出的是对应的ASCII码

大牛们在哪里。。

#include <stdio.h>   #include <malloc.h>      typedef struct list   {       char data;       struct list *next;   }linklist;   linklist *CreateList_Front();    void ShowLinklist(linklist *h);   linklist *CreateList_Front() { 	linklist* head; 	linklist* p; 	char x; 	head=(linklist*)malloc(sizeof(linklist)); 	head->next=NULL; 	printf("请输入元素：\n"); 	scanf("%c",&x); 	while(x!='\n') 	{ 		p=(linklist*)malloc(sizeof(linklist)); 		p->data=x; 		p->next=head->next; 		head->next=p; 		scanf("%c",&x); 	}	 	return head; }  void ShowLinklist(linklist *h) { 	linklist* p; 	p=h; 	while(p->next!=NULL) 	{ 		printf("%d",p->next->data); 		p=p->next; 	} }  int main() { 	linklist* head; 	head=CreateList_Front(); 	ShowLinklist(head); 	return 0; 	 }


Question: 新手指针数组问题求助

main() 中 for(i=1;i<10;i++)  scanf("%d",p++); ===> for(i=0;i<10;i++)  scanf("%d",p++); for(i=1;i<10;i++){ printf("%d",*p); p++; } ===> for(i=0;i<10;i++){ printf("%d",*p); p++; } sort 中 for(j=i+1;i<n;j++) ===> for(j=i+1;j<n;j++)

代码运行不报错，但是运行到最后会卡死，不知道什么原因


Question: “初始化”: 无法从“const char [3]”转换为“TCHAR *”

加const可以了，谢谢！

此外，你写成这样试试：   struct { 	const TCHAR *pszCaption; }button = { TEXT("yi") };

引用 4 楼 yi19861209 的回复:怎么检查TCHAR宏和TEXT定义  右键，转到定义

怎么检查TCHAR宏和TEXT定义

引用 2 楼 yi19861209 的回复:为什么我的有错啊，我用vs2007  检查下TCHAR宏和TEXT定义是否被更改

为什么我的有错啊，我用vs2007

在我这测试没问题，无论是UNICODE还是多字节字符


Question: 关于C语言一个数n的n次方可以分解为n个奇数之和的问题

#include <iostream> #include <math.h> using namespace std; int _tmain(int argc, _TCHAR* argv[]) { 	int N; 	int start =0; 	cout<<"Input N:"; 	cin>>N; 	int item = pow((double)N,N-1); 	if(N%2==0) 		start = -2*(N/2)+1; 	else 		start = -2*(N/2); 	for( int i=1; i<=N ;i++ ) 	{ 		cout<<item+start<<endl; 		start +=2; 	} 	return 0; }

没仔细看你的代码，具体错误不清楚！ 我认为用暴力求解不合适。 N的N次方肯定能被N整除 然后对商加一个数，同时减一个数，必然会得到一个序列，且和不变 比如3的3次方为27 27除以3 为9 得到的序列为 9 9 9  然后对 9-2 9 9+2  -》7 9 11  或者9-4 9 9+4 ->5 9 13


Question: 好好的小数，输出始终只有2位，我也是醉了！

%10.8f --> 将其中的10改为更大的数字，如20

outfile << fixed<< setprecision(10) << num[i][j].s <<endl;


Question: 怎么给p指向的二维数组赋值

如：p[0][0] = 1;


Question: 关于由times++引起的无法读取冲突的问题如何解决？？

哇，谢谢！！！

times是库函数，不要用这样的变量名


Question: 新手求大佬解决问题

#include <stdio.h> int main(void) {     int age;//变量     float assets;//变量     char pet[40];//字符数组，用于储存字符串     printf("Enter your age ,assets,and fovorite pet.\n");     scanf_s("%d %f", &age, &assets);     scanf_s("%s", pet, 40);     printf("%d $%.2f %s\n", age, assets, pet);     return 0;  } pet输入格式有问题。 建议注意一下scanf_s对于%s的输入

$是什么鬼  是%吧

scanf_s("$S", pet);改为 scanf_s("%s, pet); scanf没有$S格式，字符串格式用%s

重新建立一个项目 别用.cpp，最好用纯C，后缀名.c 再检查一下是不是在一个文件里定义了多个main()函数  最好一个文件/项目只有这个项目应该有的内容


Question: 生成的 exe文件无法运行

建议还是使用当前流行的编译器

TC不支持64的吧，或者说TC编译生成的exe还是32位的。

C与C++程序设计学习与实验系统 2013.3 可以不用建立项目（单文件），简单的试验代码甚至不用保存为文件，直接编译运行观察结果，比较方便。 只有几十M大小。自带VC 6.0编译器和TC编译器（选项可设置），自带DOSBox运行TC生成的exe程序。  TC（Turbo C）老代码（比如小游戏）最好看懂了以后，理解了算法和过程，用VC改写成Windows平台的。  楼主如果想用C玩玩图形、小游戏编程，可以了解一下EasyX，EasyX是Windows平台最简单的绘图函数库（名副其实），兼容BC和TC的绘图函数，在VC下用EasyX来编程跟在TC下编程绘图差不多是完全一样的。EasyX既可以绘图，也支持图像显示和处理。  下载一个EasyX包，里面有完整的函数手册EasyX_Help.chm，有示例。EasyX官网有很多网友上传的实例，包括游戏。  仅供参考： 用绘图语句画机器猫（初学C语言的同学必看） http://blog.163.com/tab_98/blog/static/1192409720150316223680/

TC软件非常老了，生成的是16位的软件，而Win 64位的系统已经不支持16位的软件了，只支持32位和64位 所以请换一个能生成32位或64位软件的编译器就可以了

TC软件最好在DosBox环境下使用。  或者你干脆改用这个得了：Visual C++ 2010 Express简体中文版http://pan.baidu.com/s/1bnwRVLt

现在还用什么TC？vs搞起


Question: 关于 顺序表 的初始化和建立 求大牛解答！！！

#include <stdio.h> #include <stdlib.h> #include <malloc.h>  typedef struct {     int* pBase;     int len; }SeqList;  void InitList(SeqList **L); void CreatList(SeqList *L); void ShowList(SeqList *L);  void InitList(SeqList **L) {     *L = (SeqList *)malloc(sizeof(SeqList));     (*L)->len = 0; }  void CreatList(SeqList *L) {     int i;     printf("请输入所需顺序表长度:");     scanf("%d", &L->len);     L->pBase = (int *)malloc(sizeof(int) * L->len);     if (!L->pBase)         exit(0);      printf("请输入顺序表元素:");     for(i = 0; i < L->len; i++)         scanf("%d", &L->pBase[i]); }  void ShowList(SeqList* L) {     int i;     for(i = 0;i < L->len;i++)         printf("%d", L->pBase[i]); }  int main() {     SeqList *L;     InitList(&L);     CreatList(L);     ShowList(L);     return 0; } 参考一下吧 除了InitList有问题，需要用二重指针外，pBase没有申请空间，并且pBase的下表应该从0开始，详见上面的代码；

感谢 感谢 感谢大牛！！！ 提前祝您和家人春节快乐

SeqList* L;     InitList(&L);

void InitList(SeqList ** L) {     *L=(SeqList*)malloc(sizeof(SeqList));     *L->len=0; }

马上过年了，知道大牛们都很忙。但求百忙之中抽空解答一下，谢谢。


Question: 求救

for(b = 0;b < MAX - 1;b++) { for( c = 0;c < MAX - 1;c++) 加上两个-1

PS不要其它冒泡法实现，只要改正


Question: 64位的hello world程序，你们编译出来有多少kb？

引用 6 楼 BAO BAO 的回复:[quote=引用 1 楼 zilaishuichina 的回复:] 请问这个问题有什么意义 没有意义 我就不会发帖问了，你想不明白有何用处  就以为没意义吗？   好多环境要求极小的二进制文件，我只是想知道大家的一般是多少字节 经常看别人的帖子里  有人不回答问题 反问楼主提问有何意义？  且先不论人家的意义是什么？  你觉得什么才是有意义呢？   有科学家去证明鸡和蛋的先后？  你觉得有什么意义？ 有科学家证明1+1 为什么等于2   你觉得有什么意义？   看的多了  今天忍不住吐槽一下，。。。。 好多事情不是你看到的表象  你想不到的用途 不能说没意义  我是要编译别的代码  要求最小2kb     如果修改函数入口64位可以做到3.5kb 我还觉得有点大  如果实在不行就用汇编写了  最后我就发这个帖以简单的 Hello world 为例子     问下大家编译的默认Release版本  是多大？  用的哪个版本  做个参考而已      [/quote] 一般的程序员就会编写代码运行，OK没问题。 能做到楼主这样想到的去优化缩小应用程序体积的都是高级程序员。一般的小程序员根本无法理解，楼主无视就好了，没有必要与不在一个层次上的人论长短。

引用 6 楼 wqte45 的回复:[quote=引用 1 楼 zilaishuichina 的回复:] 请问这个问题有什么意义 没有意义 我就不会发帖问了，你想不明白有何用处  就以为没意义吗？   好多环境要求极小的二进制文件，我只是想知道大家的一般是多少字节 经常看别人的帖子里  有人不回答问题 反问楼主提问有何意义？  且先不论人家的意义是什么？  你觉得什么才是有意义呢？   有科学家去证明鸡和蛋的先后？  你觉得有什么意义？ 有科学家证明1+1 为什么等于2   你觉得有什么意义？   看的多了  今天忍不住吐槽一下，。。。。 好多事情不是你看到的表象  你想不到的用途 不能说没意义  我是要编译别的代码  要求最小2kb     如果修改函数入口64位可以做到3.5kb 我还觉得有点大  如果实在不行就用汇编写了  最后我就发这个帖以简单的 Hello world 为例子     问下大家编译的默认Release版本  是多大？  用的哪个版本  做个参考而已      [/quote]  没有意义是因为，你希望可以参考，实际上不一定有参考价值。大部分情况下，我们不会针对“要求极小的二进制文件”去做特别优化，所以就算我现在写一个hello world，用的普通默认的release编译参数，得出来的结果，也许我现在编出来，几百K，比加了各种优化选项的大上很多，那是不是代表只有几K的，甚至不到1K的，把编译器提供的各种优化选项加上，那就是最小的，就已经优化到位了呢？没有最小，只有更小。hello world也许可以做教学例子，但是能举个例子不等于是一个有代表性的例子。  你可以给出你的代码，你实际要实现的功能需求，然后你做了哪些优化了，现在是一个什么结果，然后你希望它能更小一点，还可以怎么做，而不是上来先问别人的程序多大，来给你做参考。就像一个学生考试考了95，然后问别人考多少分，如果有人只考了90分，你会觉得比他考的好，如果还有人考100分，你会觉得这次没考好，还有人附加题全对，考了120，你觉得这是大神，这有意义么。  具体情况具体分析吧，我相信lz你实际要优化的肯定不是hello world（如果是的话，也不用来提问了，网上很多TinyHelloWorld可以参考，最小的貌似能优化到100B左右的样子）。但是一个产品级的项目，你有你实际的生产环境，实际的项目需求。可能你们的产品经理修改了一下项目需求，你不需要再链接某个库了，你的最终的二进制文件就能小上很多。如果增加了某个需求，需要多链接一个库，你之前好不容易降下来的大小，一夜回到解放前。很多优化都是在程序之外的。比如我是不是可以考虑把一些功能需求放到脚本里去做，程序里面就调用各种脚本就好了。  网上有很多专门针对hello world做优化的奇技淫巧，但是都是为了研究可执行程序的链接，库的装载。lz如果是要编译windows程序，还可以考虑PE头的优化。但是不一定适用于你正真想要优化的那个程序，  最后，如果你只是想做技术研究的话，可以推荐你一本书《程序员的自我修养-链接,装载与库》，实现了一个minicrt，可以参考。

使用c库，动态链接到msvcrt或者libc，也可以比较小，小于1K。

低于512字节的在64位系统上都无法运行。

“你想不明白有何用处  就以为没意义吗？   ” 自以为是。 引用 6 楼 wqte45 的回复:[quote=引用 1 楼 zilaishuichina 的回复:] 请问这个问题有什么意义 没有意义 我就不会发帖问了，你想不明白有何用处  就以为没意义吗？   好多环境要求极小的二进制文件，我只是想知道大家的一般是多少字节 经常看别人的帖子里  有人不回答问题 反问楼主提问有何意义？  且先不论人家的意义是什么？  你觉得什么才是有意义呢？   有科学家去证明鸡和蛋的先后？  你觉得有什么意义？ 有科学家证明1+1 为什么等于2   你觉得有什么意义？   看的多了  今天忍不住吐槽一下，。。。。 好多事情不是你看到的表象  你想不到的用途 不能说没意义  我是要编译别的代码  要求最小2kb     如果修改函数入口64位可以做到3.5kb 我还觉得有点大  如果实在不行就用汇编写了  最后我就发这个帖以简单的 Hello world 为例子     问下大家编译的默认Release版本  是多大？  用的哪个版本  做个参考而已      [/quote]

gcc 用 ldscript， 控制起来比 link 更精细些， 稍微麻烦点， 效果差不多 ..

链接器——清单文件——生成清单文件 改成：否，还可以再小掉512KB，因为默认的文件对齐是512

WIN10  64 位完全正常，   把除  .idata 外的段全部合并掉， 段属性RWE， 不会不可执行 ...   这样子 784 字节 ... 就比 汇编多 exception table 不知道咋移除了 .... cl -O1 1.c -nologo -link -entry:main -merge:.data=.text -merge:.rdata=.text -merge:.pdata=.text kernel32.lib -align:16 -release -nocoffgrpinfo   引用 14 楼 wqte45 的回复:[quote=引用 12 楼 mLee79的回复:]忘加 align 了， 加了 1.1K  cl -O1 1.c -nologo -link -entry:main -merge:.data=.text kernel32.lib -align:16 你用的vc?    我用的tdm-gcc   没发现有合并节表的merge类似参数啊？ 而且用align参数设置文件对齐字节，像你设置这么小的话   windows xp下是可以运行的  但是在windows 7 64bit系统上是运行不了的   windows 7上只要设置文件的align小于512字节（200h）  编译后的文件都不能运行呢?[/quote]

引用 12 楼 mLee79的回复:忘加 align 了， 加了 1.1K  cl -O1 1.c -nologo -link -entry:main -merge:.data=.text kernel32.lib -align:16 你用的vc?    我用的tdm-gcc   没发现有合并节表的merge类似参数啊？ 而且用align参数设置文件对齐字节，像你设置这么小的话   windows xp下是可以运行的  但是在windows 7 64bit系统上是运行不了的   windows 7上只要设置文件的align小于512字节（200h）  编译后的文件都不能运行呢?

1008  cl -O1 1.c -nologo -link -entry:main -merge:.data=.text -merge:.rdata=.text -merge:.pdata=.text kernel32.lib -align:16

2.5K ,  win 下直接 syscall 写控制台很麻烦， 不然可以很小， linux 下很简单     $ cat 1.c ; cl -O1 1.c -nologo -link -entry:main -merge:.data=.text kernel32.lib ; ls -l 1.exe ; ./1.exe #include <windows.h>  #define MESSAGE         "Hello world!\n"  int main() {         DWORD dwWr = 0;         WriteConsole(                 GetStdHandle(STD_OUTPUT_HANDLE ),                 MESSAGE, sizeof(MESSAGE)-1, &dwWr, NULL); return 0; } 1.c LINK : warning LNK4254: 节“.data”(C0000040)合并到具有不同特性的“.text”(60000020) -rwxr-xr-x 1  None 2.5K 2月  18 22:21 1.exe* Hello world!

链接C库，大小为6k

引用 7 楼 那年那人的回复:[quote=引用 4 楼 paschen 的回复:] VS2015，不使用C/C++标准库，仅使用WIN32 API的话，我这里32位程序大小：3584字节，64位程序大小：4096字节  需要使用c标准库的，请问版主你的api版本的代码  修改函数入口了吗  还是默认编译就4096字节？[/quote] 有修改入口，用C/C++语言，但没使用标准库，后面发的链接是那个工程的下载链接，你可以下载了看下

其次，如果使用标准库，使用MT（静态）与MD（动态）会有较大差异，编译时按大小优化，以及对映像文件的一些设置都会影响到其最终大小

引用 1 楼 zilaishuichina 的回复:请问这个问题有什么意义 没有意义 我就不会发帖问了，你想不明白有何用处  就以为没意义吗？   好多环境要求极小的二进制文件，我只是想知道大家的一般是多少字节 经常看别人的帖子里  有人不回答问题 反问楼主提问有何意义？  且先不论人家的意义是什么？  你觉得什么才是有意义呢？   有科学家去证明鸡和蛋的先后？  你觉得有什么意义？ 有科学家证明1+1 为什么等于2   你觉得有什么意义？   看的多了  今天忍不住吐槽一下，。。。。 好多事情不是你看到的表象  你想不到的用途 不能说没意义  我是要编译别的代码  要求最小2kb     如果修改函数入口64位可以做到3.5kb 我还觉得有点大  如果实在不行就用汇编写了  最后我就发这个帖以简单的 Hello world 为例子     问下大家编译的默认Release版本  是多大？  用的哪个版本  做个参考而已

引用 4 楼 paschen 的回复:VS2015，不使用C/C++标准库，仅使用WIN32 API的话，我这里32位程序大小：3584字节，64位程序大小：4096字节  需要使用c标准库的，请问版主你的api版本的代码  修改函数入口了吗  还是默认编译就4096字节？

只要连接了C库就不可能很小，汇编写的可以到2.5K。


Question: 求给定精度的简单交错序列部分和为什么不能用while

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

while 和 do while是有区别的 while 是先算 后面括号里面bool表达式，如果 为真，执行大括号内的循环体。 do while是先执行大括号里面的语句，最后算while后面括号里面的bool表达式，为真就重新执行循环体。否则退出循环 fabs(0) >eps 只要eps不输入负数永远为假，所以不执行循环体。

引用 3 楼 weixin_41732739 的回复:可我的初始值定的就是1啊，怎么会出现fab（0）这种情况啊？？？？ double num; 我并没有看到double num=1的写法

我知道了，因为我进行while循环的时候，还没有赋值，等于里面的判断条件是无效的，所以不能进入循环，会直接跳出 谢谢一楼大佬解答，二楼的亲。。没看懂你什么意思。。

可我的初始值定的就是1啊，怎么会出现fab（0）这种情况啊？？？？


Question: 大神们帮我看看我这样申请内存有没有问题啊

感谢各位！！！！   已找到错误

“多一少一”问题占程序员常犯错误的10%以上！ 避免“多一少一”问题的方法之一是将比如<10甚至<5的数代入程序片断，掰手指头心算验证一下程序到底应该写为 x、x-1、x+1中的哪个？ <、<=、==、>、>=中的哪个？

应该可以吧，只是为啥分配length长度的内存，却要读length + 1的字符呢？是不是应该length - 1，然后最后一个字节做字符串结束？


Question: 关于c和windows文本文件行结束符的问题

理解和讨论之前请先学会如何观察！

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

我不知道是不是我问题说的有点怪，因为关于Enter与换行和回车的关系，Enter把字符送入缓冲器里面，然后再送如字符\n，以及文本文件的行结束符的关系有点蒙（关于结束符的关系比如：在上面的两个图上，都按Enter键的话，不考虑是否加\r，单纯就Enter的话代表的是哪个字符？？？是回车还是换行，还是两个都有，还是不管是回车还是换行都一个意思），关系对我来说有点复杂。问题有点多，能否建议一下这些知识在哪有？？？c语言书上根本不详细

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

第一，一般不是判断什么环境，而是直接看有没有\r 第二，\r存在于文件中，而不是编辑环境。换句话说，如果编辑文件时有\r，保存时就会有，否则就没有。  说的还是有点绕。一般来说，Windows文本编辑器会用\r\n换行，于是其保存的文件中会有\r，而Linux文本编辑不带\r，保存的文件就没有。当打开文件时，Windows文本编辑器会找\r，没有的话不换行，Linux文本编辑器则以\n换行，遇到\r时显示一个特殊符号^M。  类似于UltraEdit之类的软件会提供转换功能，所谓DOS转UNIX或反之即是如此，这个功能就是加入或删除\r。在Linux环境下，则可以用dos2unix来把文件中的\r删除掉。


Question: 关于tinyxml2 插入字符串的疑问

你要理解转义的用途, 只有转义之后, <和>才能正常读出来, 如果不转义, <>就是一个新的节点.

你想实现XML注入攻击？

仅供参考：//+-------------------------------------------------------------------------  //  //  Method:     CSpecialCharHashTable::CSpecialCharHashTable  //  //  Synopsis:   Constructor  //  //--------------------------------------------------------------------------    CSpecialCharHashTable::CSpecialCharHashTable()  {      for (unsigned i=0; i<SPECIAL_CHAR_HASH_TABLE_SIZE; i++)          _aHashTable[i] = 0;        //      // Initialize the table with various Ascii string->Unicode mappings      //        //      // For lt and gt, use Unicode chars from private use area to avoid      // collision with '<' and '>' chars in Html tags. These will be      // mapped back to '<' and '>' by the scanner.      //      Add(L"lt",      PRIVATE_USE_MAPPING_FOR_LT);      Add(L"gt",      PRIVATE_USE_MAPPING_FOR_GT);        Add(L"amp",     0x26);      Add(L"quot",    0x22);      Add(L"nbsp",    0xa0);      Add(L"shy",     0xad);      Add(L"Agrave",  0xc0);      Add(L"agrave",  0xe0);      Add(L"Aacute",  0xc1);      Add(L"aacute",  0xe1);      Add(L"Acirc",   0xc2);      Add(L"acirc",   0xe2);      Add(L"Atilde",  0xc3);      Add(L"atilde",  0xe3);      Add(L"Auml",    0xc4);      Add(L"auml",    0xe4);      Add(L"Aring",   0xc5);      Add(L"aring",   0xe5);      Add(L"AElig",   0xc6);      Add(L"aelig",   0xe6);      Add(L"Ccedil",  0xc7);      Add(L"ccedil",  0xe7);      Add(L"Egrave",  0xc8);      Add(L"egrave",  0xe8);      Add(L"Eacute",  0xc9);      Add(L"eacute",  0xe9);      Add(L"Ecirc",   0xca);      Add(L"ecirc",   0xea);      Add(L"Euml",    0xcb);      Add(L"euml",    0xeb);      Add(L"Igrave",  0xcc);      Add(L"igrave",  0xec);      Add(L"Iacute",  0xcd);      Add(L"iacute",  0xed);      Add(L"Icirc",   0xce);      Add(L"icirc",   0xee);      Add(L"Iuml",    0xcf);      Add(L"iuml",    0xef);      Add(L"ETH",     0xd0);      Add(L"eth",     0xf0);      Add(L"Ntilde",  0xd1);      Add(L"ntilde",  0xf1);      Add(L"Ograve",  0xd2);      Add(L"ograve",  0xf2);      Add(L"Oacute",  0xd3);      Add(L"oacute",  0xf3);      Add(L"Ocirc",   0xd4);      Add(L"ocirc",   0xf4);      Add(L"Otilde",  0xd5);      Add(L"otilde",  0xf5);      Add(L"Ouml",    0xd6);      Add(L"ouml",    0xf6);      Add(L"Oslash",  0xd8);      Add(L"oslash",  0xf8);      Add(L"Ugrave",  0xd9);      Add(L"ugrave",  0xf9);      Add(L"Uacute",  0xda);      Add(L"uacute",  0xfa);      Add(L"Ucirc",   0xdb);      Add(L"ucirc",   0xfb);      Add(L"Uuml",    0xdc);      Add(L"uuml",    0xfc);      Add(L"Yacute",  0xdd);      Add(L"yacute",  0xfd);      Add(L"THORN",   0xde);      Add(L"thorn",   0xfe);      Add(L"szlig",   0xdf);      Add(L"yuml",    0xff);      Add(L"iexcl",   0xa1);      Add(L"cent",    0xa2);      Add(L"pound",   0xa3);      Add(L"curren",  0xa4);      Add(L"yen",     0xa5);      Add(L"brvbar",  0xa6);      Add(L"sect",    0xa7);      Add(L"die",     0xa8);      Add(L"copy",    0xa9);      Add(L"laquo",   0xab);      Add(L"reg",     0xae);      Add(L"macron",  0xaf);      Add(L"deg",     0xb0);      Add(L"plusmn",  0xb1);      Add(L"sup2",    0xb2);      Add(L"sup3",    0xb3);      Add(L"acute",   0xb4);      Add(L"micro",   0xb5);      Add(L"para",    0xb6);      Add(L"middot",  0xb7);      Add(L"cedil",   0xb8);      Add(L"supl",    0xb9);      Add(L"raquo",   0xbb);      Add(L"frac14",  0xbc);      Add(L"frac12",  0xbd);      Add(L"frac34",  0xbe);      Add(L"iquest",  0xbf);      Add(L"times",   0xd7);      Add(L"divide",  0xf7);  }

引用 3 楼 steedhorse 的回复:不转义的话，概念上应该算“创建新结点”，而不是“入字符串”。  <data name="xxx">      Hello<TinyXml>Hello TinyXml .... </data>  对 是插入新的节点，但是节点的内容是一个字符串，目前是因为 xml内置了‘<’ '>'  '&' 等等好多的字符，这些放不进去，如果要插入这些已经预定义好的字符，那么我应该做些什么

不转义的话，概念上应该算“创建新结点”，而不是“入字符串”。

引用 1 楼 zhao4zhong1 的回复:你想实现XML注入攻击？  就是单纯的想把其中一个节点的内容拿出来，然后单独给他加密压缩之后再把加密的内容放回去


Question: 小白自学c语言，用的devc++编程，这个报错不知道哪错了？希望大神帮我看一下

(⊙o⊙)…，我也是新手，但是你这样没有头文件，没有主函数main的编程是没法通过编译阶段的。互勉互助，你先试试。

从你的截图看来，编译器没有找到main函数。因为程序都是从main函数开始执行的。你定义的函数，需要在main函数里调用才会执行。

头文件和main函数都没有

提示的意思是，在main函数中没有找到winmain函数。 好吧，你的程序应当是没有main函数，或者winmain函数。

main函数都没有。。。。。

除非你是编译lib或dll，否者请写个main函数调用你的函数

还有这张，谢谢


Question: 数组问题，求大佬

引用 6 楼 自信男孩的回复:第一个是初始化赋值，这样是可以的。 第二个，根据数组名不能做左值的规则，这样赋值是不可以的。注意这儿不是初始化，而是赋值。因为上一条语句char str[20];已经定义了str，并且数组内的数组是随机值。 第二条语句就是赋值，因此不可以。可以考虑使用strcpy/memcpy给str赋值 多谢！

引用 1 楼 user-4的回复:第一种是执行的初始化的过程，第二种则是执行的赋值的过程，数组的赋值要用memcpy,strcpy等函数，不能直接用等于号 谢谢大佬。。。。。。。

“变量赋值”和“变量初始化”不是一回事！ “变量赋值”发生在运行期，其写法遵循赋值语法规定。 “变量初始化”发生在编译期或运行期，其写法遵循初始化列表语法规定。

第一种为：在内存堆上开辟20个字节的空间，并把后面的值填进去（赋值）。 第二种为：县开辟空间，然后后面的数值会先放在内存中的静态常量区，然后再将值赋过去。

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


Question: win32 API子窗口不显视

我这用VS测试会显示啊，检查下你各函数返回值有没执行成功，此外ShowWindow后面加上UpdateWindow

楼主也许可以试试C++ Builder。  图形用户界面（GUI）编程可以学习C++ Builder，架构先进（和C#一样拖控件），入门比较容易。  C++ Builder的较新版本——RAD Studio XE3以上版本添加对iOS和Android的支持工具包，让开发者编写的Delphi/C++应用可以同时在Windows、OS X、iOS和Android平台上运行。现在最新版本是RAD Studio 10.2。  仅供参考： 初学者学习C++ Builder第一个程序（模拟聊天室），经典！ http://blog.163.com/tab_98/blog/static/11924097201693033057497/ C++ Builder绘图示例（模拟时钟） http://blog.163.com/tab_98/blog/static/11924097201611324819376/ 从C语言的菜单界面管理系统到C++ Builder的图形用户界面，一个简单的电话簿Demo例子 http://blog.163.com/tab_98/blog/static/1192409720158673337998/   书籍推荐： 《C++Builder 6程序设计教程（第二版）》 （陆卫忠，刘文亮　等编著 /2011-04-01 /科学出版社）（当当网） 《C++Builder 6编程实例精解》（赵明现），PDF，是数字版的，非扫描版的，里面还有一个俄罗斯方块游戏的完整实现。 《精彩C++Builder 6程序设计》（台湾 吴逸贤），里面有10几个简单小游戏的实现，可以自己看懂以后再重写，才是自己掌握的。 《C++ Builder 5高级编程实例精解》（刘滨 编著）都是较大的实用的程序。


Question: 读取内存中字符串的一个小问题

这个不太好弄吧，在不知道长度情况下你不知道字符串编码就不知道它是以\0还是\0\0结束的

不就是乱码字符串引起的吗？

遇到.dll就认为字符串结束？

至少地址范围能知道吧？而且其中不应该存在不允许访问的地址？

c/c艹的字符串以\0表示结尾

引用 3 楼 u011377435 的回复:但是乱码位置的字符无法访问，访问就会崩溃 既然无法访问, 可否代表该内存不是运行程序分配的空间, 不是运行程序的使用内存, 为什么要去访问? 如果你非要这么做, 建议你一个字符一个字符读, 读到崩了, 然后抛异常处理, 代表你已经没法往下读了

但是DbgPrint可以输出

但是乱码位置的字符无法访问，访问就会崩溃

一般是调用strcpy() memcpy()这些函数。 想从无序乱码中读到有效的字符，而你又不知道字符的长度，建议全部读取出来。 用你认为是有效的字符进行条件判断或者比较，然后重新组合。


Question: 字符单元化和拷贝的问题？

char ion[] = ",.";

理解和讨论之前请先学会如何观察！  计算机组成原理→DOS命令→汇编语言→C语言（不包括C++）、代码书写规范→数据结构、编译原理、操作系统→计算机网络、数据库原理、正则表达式→其它语言（包括C++）、架构……  对学习编程者的忠告： 多用小脑和手，少用大脑、眼睛和嘴，会更快地学会编程！ 眼过千遍不如手过一遍！ 书看千行不如手敲一行！ 手敲千行不如单步一行！ 单步源代码千行不如单步Debug版对应汇编一行！ 单步Debug版对应汇编千行不如单步Release版对应汇编一行！ 不会单步Release版对应汇编？在你想单步Release版C/C++代码片断的前面临时加一句DebugBreak();重建所有，然后在IDE中运行。（一般人我不告诉他！）  VC调试时按Alt+8、Alt+7、Alt+6和Alt+5,打开汇编窗口、堆栈窗口、内存窗口和寄存器窗口看每句C对应的汇编、单步执行并观察相应堆栈、内存和寄存器变化，这样过一遍不就啥都明白了吗。 对VC来说，所谓‘调试时’就是编译连接通过以后，按F10或F11键单步执行一步以后的时候，或者在某行按F9设了断点后按F5执行停在该断点处的时候。  不要迷信书、考题、老师、回帖； 要迷信CPU、编译器、调试器、运行结果。 并请结合“盲人摸太阳”和“驾船出海时一定只带一个指南针。”加以理解。 任何理论、权威、传说、真理、标准、解释、想象、知识……都比不上摆在眼前的事实！

版主说的对，我看了一下，是不是和什么内存重叠有关呢？而且我发现原来的代码只会把偶数个o去掉，奇数的时候不会，比如wow.sohu.bob.fof.com，结果为wow s hu bob f f com，不是很明白为啥，等待高人了

strcpy(numm,temp); printf("%s ",numm);  这两句直接换成  printf("%s ", temp);  不就行了  否则你都把numm污染了，后面出现这样的结果也就不足为奇了


Question: 写一个串口接收程序，不想要补0 ，如何做，跪求各位大神！源码如下

void hexdump(unsigned char * buf, unsigned int len) { int i; char buffer[1024]; char buffer2[64]; strcpy(buffer2,""); for(i=0;i<len;i++) { sprintf(buffer2,"%02X",buf[i]&0x0ff); /*if((i+1)%16 == 0)*/ buffer2[3] = 0;  strcat(buffer,buffer2);  } printf("%s\n",buffer);  memset(buffer,0,sizeof(buffer));  return; }

for(i=0;i<len;i++) { sprintf(buffer2[2*i],"%02X",buf[i]&0x0ff); } buffer2[2*len] = '\0'; 试试

引用 4 楼 tuotuomasi 的回复:[quote=引用 3 楼 zhao4zhong1 的回复:] sprintf(buffer2,"%02X",(unsigned char)buf[i]);  感谢赵老师 还有个问题是 为什么收到 两个字节就直接打印出来 并不能在一行打印出我发送的一串字符串。[/quote] 参考《编译原理》中的词法分析和有限状态自动机？

引用 3 楼 zhao4zhong1 的回复:sprintf(buffer2,"%02X",(unsigned char)buf[i]);  去掉memset 就是这样的 FF FFAC FFAC03

引用 3 楼 zhao4zhong1 的回复:sprintf(buffer2,"%02X",(unsigned char)buf[i]);  感谢赵老师 还有个问题是 为什么收到 两个字节就直接打印出来 并不能在一行打印出我发送的一串字符串。


Question: //利用指针实现字符串的反转

#include <stdio.h> #include <string.h>  #define MAX 100  void reverse_string(char *string) {     char *last_char, temp;      for(last_char = string; *last_char != '\0'; last_char++)         ;     last_char--;    /* pointer last character (not '\0')*/      while(string < last_char)     {          temp = *last_char;         *last_char-- = *string;         *string++ = temp;      }  }  void reverse_str(char *str) {     char *end_str = str + strlen(str) - 1, tmp;      while (str < end_str) {         tmp = *end_str;         *end_str = *str;         *str = tmp;         str++;         end_str--;     } }  int main() {     char str[MAX];     printf("请输入一个字符串:\n");     gets(str);     reverse_string(str);     //reverse_str(str);     printf("翻转后的字符串是:\n%s\n", str);     return 0; } 参考一下吧

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

你for循环不能那样判断。

for (last_char = string; *string != '\0'; last_char++)  这里是个死循环吧，每次递增的是last_char，*string 一开始不为'\0'则永远不会为 '\0'


Question: 【求解答】PAT乙级 switch函数 字符串的拼接问题

你好，请问我可以向你求一下那个Java语言程序设计第十版11-20章的答案吗？😭我没有积分，不能下载答案😭拜托你啦

谢谢各位大佬，弄明白了

/*PAT.1002. 写出这个数   读入一个自然数n，计算其各位数字之和，用汉语拼音写出和的每一位数字。*/ #include <stdio.h> #include <string.h>  #if 0 void pop(int N,int sum) {     sum=0;     while (1)     {         sum += N%10;         N/=10;         if (N==0) break;     } } #endif #define MAX_SIZE    80  int main() {     //char py[128] = "\0";     char digits[10][8] = { "Ling", "Yi", "Er", "San", "Si", "Wu", "Liu", "Qi", "Ba", "Jiu"};     int i,j;     int sum = 0;     char num_list[MAX_SIZE];     scanf("%s", num_list);      i = 0;     while (i < strlen(num_list)) {         sum += num_list[i++] - '0';     }      for (i = MAX_SIZE-1; sum && i >= 0; i--) {         num_list[i] = sum % 10;         sum /= 10;     }      for (j = i + 1; j < MAX_SIZE; j++)         printf("%s ", digits[num_list[j]]);     putchar(10);      /*     for (i=1;i <= 100; i++)     {         num[i]=summary%10;         summary/=10;         if (summary==0) break;     }     for (j=i;j>0;j--)     {switch (num[j]){                         case 0 : strcat(py,"Ling "); break;                         case 1 : strcat(py,"Yi"); break;                         case 2 : strcat(py,"Er"); break;                         case 3 : strcat(py,"San"); break;                         case 4 : strcat(py,"Si"); break;                         case 5 : strcat(py,"Wu"); break;                         case 6 : strcat(py,"Liu"); break;                         case 7 : strcat(py,"Qi"); break;                         case 8 : strcat(py,"Ba"); break;                         case 9 : strcat(py,"Jiu"); break;                     }     }     printf("%s",py);     */      return 0; } 参考一下吧  楼主的for循环有问题，第二个表达式应该是判断表达式，第三个表达式才是自增表达式

char N[101]; char STR[10][5] = { {"Ling"}, {"Yi"}, {"Er"}, {"San"}, {"Si"}, {"Wu"}, {"Liu"}, {"Qi"}, {"Ba"}, {"Jiu"}  };  int main() { 	char  result[3][5]; 	scanf_s("%s", N,100); 	int lenght = strlen(N); 	int total = 0; 	for (int i = 0; i < lenght; i++) 	{ 		if (isdigit(N[i])) 			total += N[i] - '0'; 		else 		{ 			printf("不是数字"); 			return 1; 		} 	} 	printf("和为：%d\n", total); 	int sp = 0; 	while (total) 	{ 		int tmp = total % 10; 		 		total = total / 10; 		strcpy_s(result[sp++],4,STR[tmp]); 	} 	for (int i = sp-1; i >= 0; i--) 	{ 		printf("%s ", result[i]); 	}     return 0; }

思路有问题把 人家要求是10的100次方 想一想计算机整数最大表示是多少？

這個for語句寫錯了，循環繼續條件在中間：  for (i=1;i++;i<=100)


Question: 关于结构体的问题  困扰了一晚都没睡好

假设n = 3 那么即创建了动态数组p[3] 发送到函数的形参时应该也只有*(p2+2)就是极限了吧 怎么我p2+10都可以。。但是如果我直接*p2就会报错  甚至我删掉这一句 都不会报错，这又是为什么。。max没有初始化直接就和（*（p2+i）).aver 比较却没问题 这是碰巧的吗。。

#include<stdio.h> #include<stdlib.h>  struct student {     int   num;     char  name[20];     float score[3];     float aver; };      void input(struct student *p1,int);     struct student *max(struct student *p2,int n);     void print(struct student *p3);  int main(void) {      int n;     struct student *p;      printf("请输入学生的人数\n");     scanf("%d",&n);      p = (struct student *)malloc(n * sizeof(struct student));      input(p,n);     print(max(p,n));  //省了定义max(p)的值的步骤      return 0; }  void input(struct student *p1,int n) {     int i;      printf("请输入学号、姓名、3科成绩\n");      for(i = 0;i<n;i++)     {         //scanf("%d %s %f %f %f", &(*(p1+i)).num,(*(p1+i)).name,&(*(p1+i)).score[0],&(*(p1+i)).score[1],&(*(p1+i)).score[2]);         //(*(p1+i)).aver = ((*(p1+i)).score[0] + (*(p1+i)).score[1] + (*(p1+i)).score[2]) / 3.0;         scanf("%d %s %f %f %f", &p1[i].num, p1[i].name, &p1[i].score[0], &p1[i].score[1], &p1[i].score[2]);         p1[i].aver = (p1[i].score[0] + p1[i].score[1] + p1[i].score[2]) / 3.0;     } }  struct student *max(struct student *p2,int n)//假设n等于3 {     int i;     struct student *pmax_aver = NULL;      pmax_aver = p2 + 0;      for(i = 1; i< n; i++)         if(p2[i].aver > pmax_aver->aver)             pmax_aver = p2 + i;      return (pmax_aver); }  void print(struct student *p3) {     printf("成绩最高的学生信息如下:\n");      //printf("学号:%d\n姓名:%s\n课程1:%f\n课程2:%f\n课程3:%f\n平均成绩:%f\n\n",(p3).num,(p3).name,(p3).score[0],(p3).score[1],(p3).score[2],(p3).aver);     printf("学号:%d\n姓名:%s\n课程1:%f\n课程2:%f\n课程3:%f\n平均成绩:%f\n\n",             p3->num, p3->name, p3->score[0], p3->score[1], p3->score[2], p3->aver); }   参考一下吧  max.aver = (p2+10)->aver;  //为什么直接是(p2)->aver会出现乱码 为什么p2+10都可以，我明明没有创建这么多 为什么这一句甚至删掉都可以  这个地方不能用p2->aver，因为p2可以理解为数组，这样用会类型不匹配；但是可以这样用(p2+0)->aver；虽然p2和p2+0的地址值一样，但是类型是不一样的。p2接收到的是数组（n个学生信息的首地址）。p2+0是表示第一个学生的地址，所以可以用(p2+0)->aver p2+10若n位小于10，则该操作会导致越界，越界是未定义行为。之所以(p2+10)->aver没问题，是因为类型匹配。但这样做存在很大的危险，很容易导致段错误；  我对max函数做了一些改动，返回aver最大的学生信息的地址，这样在print函数里就可以使用了，因为print函数是输出一个学生信息，因此n参数就是多余，既然多余建议删除，让代码整洁，提高可读性；返回地址而不是返回结构体变量还会节省空间，因为一个指针占用的是int类型大小的空间，而结构体的长度至少大于这个值，因此会节省空间，还会提高函数的执行效率，为什么呢，因为参数传递若是结构变量则要穿很大的结构体（结构体里的值），而传指针可以节省很多的拷贝，节省执行时间，提高效率； 虽然一个小小的程序，但是还是可以往深入的研究的（时间复杂度，空间复杂度）


Question: 排序问题

“多一少一”问题占程序员常犯错误的10%以上！ 避免“多一少一”问题的方法之一是将比如<10甚至<5的数代入程序片断，掰手指头心算验证一下程序到底应该写为 x、x-1、x+1中的哪个？ <、<=、==、>、>=中的哪个？

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

#include <stdio.h>  void px(int a[]) {     int temp;     if(a[0] < a[1] && a[1] < a[2] && a[2] < a[3])         return;     for(int c = 0;c<=(3-1);)     {         for(int b = 0;b<=3;)         {             if(a[b] > a[b+1])             {                 temp = a[b];                 a[b+1] = a[b];                 a[b] = temp;             }             b++;         }         c++;     }     return; }  void bubble_sort(int *arr, int len) {     int i, j;     int tmp;      for (i = 0; i < len - 1; i++)         for (j = 0; j < len - i -1; j++)             if (arr[j] > arr[j+1]) {                 tmp = arr[j];                 arr[j] = arr[j+1];                 arr[j+1] = tmp;             } }  int main(void) {     int dpx[4];     printf("输入待排序数据(4个):\n");     scanf("%d%d%d%d", &dpx[0], &dpx[1], &dpx[2], &dpx[3]);     printf("%d %d %d %d\n",dpx[0],dpx[1],dpx[2],dpx[3]);     //px(&dpx[0]);     bubble_sort(dpx, 4);     printf("%d %d %d %d\n",dpx[0],dpx[1],dpx[2],dpx[3]);     return 0; }  参考一下吧

引用 3 楼 lexnewgate 的回复: void swap(int *a, int *b) {     int temp;     temp = *a;     *a = *b;     *b = temp; }  void bubble_sort(int a[], int length) {     for (int j = 0; j < length-2; j++)     {         for (int i = 0; i < length - 1-j; i++)         {             if (a[i] > a[i + 1])             {                 swap(&a[i], &a[i + 1]);             }         }     } } #include <stdio.h>  int main(void) {     int dpx[4];     printf("输入待排序数据(4个):\n");     scanf("%d%d%d%d", &dpx[0], &dpx[1], &dpx[2], &dpx[3]);     printf("%d %d %d %d\n", dpx[0], dpx[1], dpx[2], dpx[3]);     bubble_sort(&dpx[0],sizeof dpx/sizeof (int));     printf("%d %d %d %d\n", dpx[0], dpx[1], dpx[2], dpx[3]);     return 0; }    1. scanf用错了 需要传地址,而非int值. http://www.cplusplus.com/reference/cstdio/scanf/ 2. 排序写错了. 写了个冒泡仅供参考 冒泡排序中，第一层循环是不是应该是length - 1而不是-2呢？  void bubble_sort(int *arr, int len) {     int i, j;     int tmp;      for (i = 0; i < len - 1; i++)         for (j = 0; j < len - i -1; j++)             if (arr[j] > arr[j+1]) {                 tmp = arr[j];                 arr[j] = arr[j+1];                 arr[j+1] = tmp;             } }

引用 6 楼 cfjtaishan 的回复:[quote=引用 3 楼 lexnewgate 的回复:]  void swap(int *a, int *b) {     int temp;     temp = *a;     *a = *b;     *b = temp; }  void bubble_sort(int a[], int length) {     for (int j = 0; j < length-2; j++)     {         for (int i = 0; i < length - 1-j; i++)         {             if (a[i] > a[i + 1])             {                 swap(&a[i], &a[i + 1]);             }         }     } } #include <stdio.h>  int main(void) {     int dpx[4];     printf("输入待排序数据(4个):\n");     scanf("%d%d%d%d", &dpx[0], &dpx[1], &dpx[2], &dpx[3]);     printf("%d %d %d %d\n", dpx[0], dpx[1], dpx[2], dpx[3]);     bubble_sort(&dpx[0],sizeof dpx/sizeof (int));     printf("%d %d %d %d\n", dpx[0], dpx[1], dpx[2], dpx[3]);     return 0; }    1. scanf用错了 需要传地址,而非int值. http://www.cplusplus.com/reference/cstdio/scanf/ 2. 排序写错了. 写了个冒泡仅供参考 冒泡排序中，第一层循环是不是应该是length - 1而不是-2呢？  void bubble_sort(int *arr, int len) {     int i, j;     int tmp;      for (i = 0; i < len - 1; i++)         for (j = 0; j < len - i -1; j++)             if (arr[j] > arr[j+1]) {                 tmp = arr[j];                 arr[j] = arr[j+1];                 arr[j+1] = tmp;             } }[/quote]  对的,是应该length-1,而非length-2. 我的写错了,感谢纠正.

scanf("%d%d%d%d",dpx[0],dpx[1],dpx[2],dpx[3]); 这个函数用错了，你们好快把我要说的都说了

for(int i=0;i<length-1;i++)     {         if(a[i]>a[i+1])         {             swap(&a[i],&a[i+1]);         }     }  1. scanf用错了 需要传地址,而非int值. http://www.cplusplus.com/reference/cstdio/scanf/ 2. 排序写错了. 写了个冒泡仅供参考

scanf("%d%d%d%d", dpx[0], dpx[1], dpx[2], dpx[3]);  改成：  scanf("%d%d%d%d", &dpx[0], &dpx[1], &dpx[2], &dpx[3]);


Question: 【求助散分】我自己写了个简单的加密，但是解密跟加密竟然不对称，求解

加密解密不对称

引用 3 楼 ckc 的回复:加减应该是相同的数据。  每字节明文有255种可能，密文也是255种可能，是一一对应关系，加密解密没问题的 因为字符串用0表示结尾，所以要绕过0 比如加10的时候，对于-10到-1之间的数据，+10之后再+1就可以了对 结尾那个我绕过了

引用 1 楼 cfjtaishan 的回复:两个问题： 第一个：加密是+5，而解密是-10，很明显是不对称的。 第二个：解密方法，-10后会不会导致*str == 0？若这个表达式成立，那么解密之后数据（字符串）就可能不全。用-10就可以

引用 1 楼 cfjtaishan 的回复:两个问题： 第一个：加密是+5，而解密是-10，很明显是不对称的。 第二个：解密方法，-10后会不会导致*str == 0？若这个表达式成立，那么解密之后数据（字符串）就可能不全。关键是我用-5 还原不了数据

即使Decode里改成减5也未必完全还原为原来的，因为判断条件也不对称


Question: 这个for循环错在哪，

忘了加括号，，，，，，，，，，，，，，，尴尬，

看你的逻辑应该是将sum += score[index];放到第一个循环里。但是实际逻辑没有这么做，只是将index = SIZE时加到了sum里。这个也是对于score数组来讲已经越界。 解决办法是：加大括号，将scanf和sum += score[index]括到第一个for循环里。  下次提问建议直接贴代码，而不是帖代码截图。


Question: 段错误吐核

信息太少了，但从这个函数不能确定是什么导致的段错误；

Windows: 崩溃的时候在弹出的对话框按相应按钮进入调试，按Alt+7键查看Call Stack即“调用堆栈”里面从上到下列出的对应从里层到外层的函数调用历史。双击某一行可将光标定位到此次调用的源代码或汇编指令处，看不懂时双击下一行，直到能看懂为止。  Linux: 进程意外退出会在当前目录下产生‘core’文件或形如‘core.数字’的文件比如‘core.1234’ 使用命令 gdb 运行程序名 core或core.数字 进入gdb然后使用bt命令 可以查看进程意外退出前函数调用的堆栈，内容为从上到下列出对应从里层到外层的函数调用历史。 如果进程意外退出不产生core文件，参考“ulimit -c core文件最大块大小”命令


Question: 请问如何保存摄像头传输的图像矩阵？

引用 2 楼 zhao4zhong1 的回复:    /** Read camera data.      *      * @return true if successful      */     bool read() {         bool success = true;         try         {             // Read data from the Camera             ROS_DEBUG_STREAM("[" << camera_name_ << "] reading data");             unsigned char *frame = NULL;             uint32_t bytes_used;             int buf_idx = cam_->grab(&frame, bytes_used);             if (buf_idx < 0) {                 ROS_WARN("Could not grab image");             }             else if (frame)             {                 FILE *f;                 f=fopen("d:\\lastframe.dat","wb");                 fwrite((const void *)frame,1,(size_t)(config_.height*config_.width*3),f);                 fclose(f);                 //cv::WImageBuffer3_b image( frame );                 //cv::Mat data(height, width, CV_8UC1, frame, 3 * width);                                 sensor_msgs::fillImage(image_, "bgr8", config_.height, config_.width,                                     3*config_.width, frame);                 cam_->release(buf_idx);             }             ROS_DEBUG_STREAM("[" << camera_name_ << "] read returned");         }         catch (uvc_cam::Exception& e)         {             ROS_WARN_STREAM("[" << camera_name_                     << "] Exception reading data: " << e.what());             success = false;         }         return success;     }   你好  感谢~ 我试了一下  因为我是在Ubuntu系统下使用的   所以把那个地址改成了/home/ros 这种形式  但是运行之后没有找到这个dat文件啊

引用 1 楼 iloveyou418 的回复:不断覆盖~图像需要处理么？如果只是单纯的覆盖的话应该没什么难度啊 你好   图像不需要处理  请问这个要怎么保存然后覆盖啊  谢了~

不断覆盖~图像需要处理么？如果只是单纯的覆盖的话应该没什么难度啊


Question: 关于scanf返回值的测试

引用 9 楼 helloxkcd 的回复:[quote=引用 6 楼 DelphiGuy 的回复:] #include <conio.h> // ...     while(1)     {         x = scanf("%d %d %d",&a,&b,&c);         printf("%d\n",x);         printf("if continue please input 1, or enter 0\n");         fflush(stdin);         if (getchar() != '1') break; //... 不行！！！！！！[/quote]  昨天凭记忆写的没测试，经实测，C++Builder、gcc是可以的，VC++不行。究其原因，fflush(stdin);是未定义行为，能否清除输入缓冲区是实现相关的，稍微修改一下就好了。   #include <stdio.h>  int main() {   int x, a, b, c;    while(1)   {     x = scanf("%d %d %d", &a, &b, &c);     printf("%d %d %d %d\n", x, a, b, c);     printf("if continue please input 1, or enter 0\n");     // fflush(stdin);     fseek(stdin, 0, SEEK_END);  // :)     if (getchar() != '1') break;   }    return 0; }

谢谢我明白了！

仅供参考：#include <stdio.h> char s[]="123 ab 4"; char *p; int v,n,k; void main() {     p=s;     while (1) {         k=sscanf(p,"%d%n",&v,&n);         printf("k,v,n=%d,%d,%d\n",k,v,n);         if (1==k) {             p+=n;         } else if (0==k) {             printf("skip char[%c]\n",p[0]);             p++;         } else {//EOF==k             break;         }     }     printf("End.\n"); } //k,v,n=1,123,3 //k,v,n=0,123,3 //skip char[ ] //k,v,n=0,123,3 //skip char[a] //k,v,n=0,123,3 //skip char[b] //k,v,n=1,4,2 //k,v,n=-1,4,2 //End.

引用 6 楼 DelphiGuy 的回复:#include <conio.h> // ...     while(1)     {         x = scanf("%d %d %d",&a,&b,&c);         printf("%d\n",x);         printf("if continue please input 1, or enter 0\n");         fflush(stdin);         if (getchar() != '1') break; //... 不行！！！！！！

因为第二个%d没有读取成功，导致后面的都留在缓冲区里。

在每个最后不带\n的printf后面加fflush(stdout); 在每个不想受接收缓冲区旧内容影响的scanf前面加rewind(stdin); 另外请检查scanf的返回值。 [code=c]//请今后要用 char c; scanf("%c",&c); //时，都改为 char s[2]; char c; scanf("%1s",s); c=s[0]; //自动跳过一个或多个空格或Tab字符或回车换行，读取下一个字符。 [/code]

引用 3 楼 waitti 的回复:@自信男孩 可是他下面显示0，又是为什么 因为第一次输入的a 还在输入缓存里，在与变量a匹配时不匹配呢，直接返回了，因此一个也没匹配，所以返回0了。

#include<stdio.h> int main() {     int x;     int a,b,c;     int flag = 1;     while(flag == 1)     {         x = scanf("%d %d %d",&a,&b,&c);         printf("%d\n",x);         while (3 - x + 1) {             getchar();             x++;         }         printf("if continue please input 1, or enter 0\n");         scanf("%d",&flag);         printf("flag = %d\n", flag);     }     return 0; } 这种方法可以避免死循环，但是方法不够好，如果有更好的，建议采用更好的方法；

@自信男孩 可是他下面显示0，又是为什么

可是他下面显示0，又是为什么

进入死循环了，这是因为输入并没有立即进入内存里，而是在输入缓存里。由于输入的a并不和b类型匹配，所以一直在输入缓存里，下面的flag也是从输入缓存里拿，也是不匹配，然后flag还是1，所以继续循环，由于在输入缓存里的a不能和变量a匹配，所以直接返回0，继续。同样flag也不和a匹配，因此继续循环，flag还是为1，继续循环。  可能会会问，scanf("%d", &flag);为啥不让从终端输入，因为输入缓存里有数据，第一次输入的a, 2


Question: objective-c新手求助。有前辈能指导吗？

这是你的签名:  void drawShapes(id shapes, int count)   这是我的签名:  void drawShapes(id *shapes, int count)

引用 1 楼 lexnewgate 的回复: void drawShapes(id *shapes, int count)  shapes你定义的为id的数组,drawShapes的签名不能为id了. 那解决方案是啥？


Question: 简单指针问题

char *str = "abcdef"; 指向是常量区的字符串，不能进行修改

#pragma comment(linker,"/SECTION:.rdata,RW") //加这句可以让常量区可写，后果自负！

char *str = "abcdef";这条语句是将字符串的地址存放在指针变量str中；由于该字符串是一个常量，常量是不能修改的。所以reverse_string函数由于对字符常量修改，导致段错误； 若是用char str[MAX] = “abcdef";数组，那么这条表达式就是现将字符串常量拷贝到字符数组中，由于字符数组是可读可写的（在栈上申请的空间），因此调用reverse_string对str修改是没问题的。

http://blog.csdn.net/yanbober/article/details/8713250 参考上面链接，"abcdef"存放在文字常量区，不能被写入

这样定义指针，他指向的是常量，不允许修改的。正确的用法是定义后用malloc分配内存。


Question: 超大数与操作

引用 3 楼 mstlq 的回复:https://gmplib.org/ 大数运算直接用gmp库呗，省的自己造轮子 我还就喜欢造轮子！ #include <iostream> #include <string> using namespace std; inline int compare(string str1,string str2) {//相等返回0，大于返回1，小于返回-1          if (str1.size()>str2.size()) return 1; //长度长的整数大于长度小的整数     else if (str1.size()<str2.size()) return -1;     else                              return str1.compare(str2); //若长度相等，则头到尾按位比较 } string SUB_INT(string str1,string str2); string ADD_INT(string str1,string str2) {//高精度加法     int sign=1; //sign 为符号位     string str;     if (str1[0]=='-') {         if (str2[0]=='-') {             sign=-1;             str=ADD_INT(str1.erase(0,1),str2.erase(0,1));         } else {             str=SUB_INT(str2,str1.erase(0,1));         }     } else {         if (str2[0]=='-') {             str=SUB_INT(str1,str2.erase(0,1));         } else { //把两个整数对齐，短整数前面加0补齐             string::size_type L1,L2;             int i;             L1=str1.size();             L2=str2.size();             if (L1<L2) {                 for (i=1;i<=L2-L1;i++) str1="0"+str1;             } else {                 for (i=1;i<=L1-L2;i++) str2="0"+str2;             }             int int1=0,int2=0; //int2 记录进位             for (i=str1.size()-1;i>=0;i--) {                 int1=(int(str1[i])-'0'+int(str2[i])-'0'+int2)%10;                 int2=(int(str1[i])-'0'+int(str2[i])-'0'+int2)/10;                 str=char(int1+'0')+str;             }             if (int2!=0) str=char(int2+'0')+str;         }     }     //运算后处理符号位     if ((sign==-1)&&(str[0]!='0')) str="-"+str;     return str; } string SUB_INT(string str1,string str2) {//高精度减法     int sign=1; //sign 为符号位     string str;     int i,j;     if (str2[0]=='-') {         str=ADD_INT(str1,str2.erase(0,1));     } else {         int res=compare(str1,str2);         if (res==0) return "0";         if (res<0) {             sign=-1;             string temp =str1;             str1=str2;             str2=temp;         }         string::size_type tempint;         tempint=str1.size()-str2.size();         for (i=str2.size()-1;i>=0;i--) {             if (str1[i+tempint]<str2[i]) {                 j=1;                 while (1) {//zhao4zhong1添加                     if (str1[i+tempint-j]=='0') {                         str1[i+tempint-j]='9';                         j++;                     } else {                         str1[i+tempint-j]=char(int(str1[i+tempint-j])-1);                         break;                     }                 }                 str=char(str1[i+tempint]-str2[i]+':')+str;             } else {                 str=char(str1[i+tempint]-str2[i]+'0')+str;             }         }         for (i=tempint-1;i>=0;i--) str=str1[i]+str;     }     //去除结果中多余的前导0     str.erase(0,str.find_first_not_of('0'));     if (str.empty()) str="0";     if ((sign==-1) && (str[0]!='0')) str ="-"+str;     return str; } string MUL_INT(string str1,string str2) {//高精度乘法     int sign=1; //sign 为符号位     string str;     if (str1[0]=='-') {         sign*=-1;         str1 =str1.erase(0,1);     }     if (str2[0]=='-') {         sign*=-1;         str2 =str2.erase(0,1);     }     int i,j;     string::size_type L1,L2;     L1=str1.size();     L2=str2.size();     for (i=L2-1;i>=0;i--) { //模拟手工乘法竖式         string tempstr;         int int1=0,int2=0,int3=int(str2[i])-'0';         if (int3!=0) {             for (j=1;j<=(int)(L2-1-i);j++) tempstr="0"+tempstr;             for (j=L1-1;j>=0;j--) {                 int1=(int3*(int(str1[j])-'0')+int2)%10;                 int2=(int3*(int(str1[j])-'0')+int2)/10;                 tempstr=char(int1+'0')+tempstr;             }             if (int2!=0) tempstr=char(int2+'0')+tempstr;         }         str=ADD_INT(str,tempstr);     }     //去除结果中的前导0     str.erase(0,str.find_first_not_of('0'));     if (str.empty()) str="0";     if ((sign==-1) && (str[0]!='0')) str="-"+str;     return str; } string DIVIDE_INT(string str1,string str2,int flag) {//高精度除法。flag==1时,返回商；flag==0时,返回余数     string quotient,residue; //定义商和余数     int sign1=1,sign2=1;     if (str2 == "0") {  //判断除数是否为0         quotient= "ERROR!";         residue = "ERROR!";         if (flag==1) return quotient;         else         return residue ;     }     if (str1=="0") { //判断被除数是否为0         quotient="0";         residue ="0";     }     if (str1[0]=='-') {         str1   = str1.erase(0,1);         sign1 *= -1;         sign2  = -1;     }     if (str2[0]=='-') {         str2   = str2.erase(0,1);         sign1 *= -1;     }     int res=compare(str1,str2);     if (res<0) {         quotient="0";         residue =str1;     } else if (res == 0) {         quotient="1";         residue ="0";     } else {         string::size_type L1,L2;         L1=str1.size();         L2=str2.size();         string tempstr;         tempstr.append(str1,0,L2-1);         for (int i=L2-1;i<L1;i++) { //模拟手工除法竖式             tempstr=tempstr+str1[i];             tempstr.erase(0,tempstr.find_first_not_of('0'));//zhao4zhong1添加             if (tempstr.empty()) tempstr="0";//zhao4zhong1添加             for (char ch='9';ch>='0';ch--) { //试商                 string str;                 str=str+ch;                 if (compare(MUL_INT(str2,str),tempstr)<=0) {                     quotient=quotient+ch;                     tempstr =SUB_INT(tempstr,MUL_INT(str2,str));                     break;                 }             }         }         residue=tempstr;     }     //去除结果中的前导0     quotient.erase(0,quotient.find_first_not_of('0'));     if (quotient.empty()) quotient="0";     if ((sign1==-1)&&(quotient[0]!='0')) quotient="-"+quotient;     if ((sign2==-1)&&(residue [0]!='0')) residue ="-"+residue ;     if (flag==1) return quotient;     else         return residue ; } string DIV_INT(string str1,string str2) {//高精度除法,返回商     return DIVIDE_INT(str1,str2,1); } string MOD_INT(string str1,string str2) {//高精度除法,返回余数     return DIVIDE_INT(str1,str2,0); } int main() {     char ch;     string s1,s2,res;      while (cin>>s1>>ch>>s2) {         switch (ch) {             case '+':res=ADD_INT(s1,s2);break;             case '-':res=SUB_INT(s1,s2);break;             case '*':res=MUL_INT(s1,s2);break;             case '/':res=DIV_INT(s1,s2);break;             case '%':res=MOD_INT(s1,s2);break;             default :                   break;         }         cout<<res<<endl;     }     return(0); }

基本类型没可以表示这样的数，如果需要超大数，需要自己定义结构体，分解为多个基本类型

网上有很多大数运算的类，也有一些第三方写的开源的，可供参考


“变量赋值”和“变量初始化”不是一回事！ “变量赋值”发生在运行期，其写法遵循赋值语法规定。 “变量初始化”发生在编译期或运行期，其写法遵循初始化列表语法规定。

引用 2 楼 paschen 的回复:union只能对第一个元素进行初始化，共享部分内存的值以此初始化值共享，建议像你注释那样写，毕竟程序是给人读的  感谢版主的回答，我刚想到办法 union是可以 指定对象初始化的

引用 4 楼 zhao4zhong1 的回复:sockaddr_in servAddr = {     /* servAddr.sin_family      = */ AF_INET,     /* servAddr.sin_port        = */ htons(9092),     {     /* servAddr.sin_addr.s_addr = */ inet_addr("118.85.207.85")     } };   http://bbs.csdn.net/topics/380157851 http://bbs.csdn.net/topics/390150105   这么写 不行呢，我是在Windows下编译   in_addr里不是一个成员  windows下头文件里的是个共用体 里面有三个成员

结构体初始化，一般就是直接赋值。内存拷贝memcpy、字符串拷贝strcpy等。

sockaddr_in addr = {0} 不就这样么


把暴力美学进行到底   #define GETNUM4(num) (((num) % 10000) / 1000) #define GETNUM3(num) (((num) % 1000) / 100) #define GETNUM2(num) (((num) % 100) / 10) #define GETNUM1(num) ((num) % 10) void fun() { 	for (int i = 182; i <= 786; i++)  // 被乘数，三位数，十位是8且数字无重复的 最小三位数182， 最大三位数786 	{ 		for (int j = 1; (GETNUM2(i) == 8) && (j <= 7); j++) // 被乘数第二位必须是8，且 乘数，一位数，1-7 		{ 			int k = i * j; // 乘积 			if	( 					// 乘积，四位数，不包含数字8且数字无重复的 最小四位数1234， 最大四位数7654 					(k >= 1234) && (k <= 7654) &&  					// 总共8个数字是1-8无重复 					((1 << GETNUM3(i)) + (1 << GETNUM2(i)) + (1 << GETNUM1(i)) + (1 << GETNUM1(j)) + (1 << GETNUM4(k)) + (1 << GETNUM3(k)) + (1 << GETNUM2(k)) + (1 << GETNUM1(k))) == 0x1fe 				) 			{ 				printf("%d * %d = %d\n", i, j, k); 			} 		} 	} }

写个全排试一下，不过稍微分析一下就可以加快不少，比如3位数*一位数=四位数，那么三位数的百位肯定不是1，一位数也不能是1，再比如位数还有一些限制，其实还是暴力搜索省脑子

引用 24 楼 DelphiGuy 的回复:呃... 好像不能再短了（这话听起来有点暧昧）  写了几回代码，结果换来这样的一句话，我感觉自己中了圈套

呃... 好像不能再短了（这话听起来有点暧昧）

引用 10 楼 bluestar2009 的回复:[quote=引用 8 楼 zhao4zhong1 的回复:] 闲着也是闲着！//将1到7的数填入括号不能重复()8()×()=()()()() #include <stdio.h> #include <string.h> int next_pl(char * f, char * l) {     char t;     char *ff,*ll;      char * i = l;     if (f == l || f == --i) return (0);     while (1) {         char * p = i;         if (*--i < *p) {             char * j = l;             while (1) {                 j--;                 if (*i<*j) break;//             }             t=*i;*i=*j;*j=t;             ff=p;             ll=l;             for (; ff < ll; ++ff) {                 ll--;                 t=*ff;*ff=*ll;*ll=t;             }             return (1);         }         if (i == f) {             ff=f;             ll=l;             for (; ff < ll; ++ff) {                 ll--;                 t=*ff;*ff=*ll;*ll=t;             }             return (0);         }     } } int main() {     char a[]="\x01\x02\x03\x04\x05\x06\x07";      do {         if ((a[0]*100+80+a[1])*a[2]==a[3]*1000+a[4]*100+a[5]*10+a[6])             printf("%d8%d*%d=%d%d%d%d\n",a[0],a[1],a[2],a[3],a[4],a[5],a[6]);     } while (next_pl(a,a+7));     return 0; } //582*3=1746 //  高人！！我写了53行···[/quote] 楼主想要短的？ 那试试这个咯 #include <stdio.h> void _swap(char *l, char *r){ char t = *l; *l = *r; *r = t; } void fun(char* arr, char* end, char *cur) {     if (cur == end){         if ((arr[0] * 100 + 80 + arr[1])*arr[2] == arr[3] * 1000 + arr[4] * 100 + arr[5] * 10 + arr[6])             printf("%d8%d*%d=%d%d%d%d\n", arr[0], arr[1], arr[2], arr[3], arr[4], arr[5], arr[6]);         return;     }     for (char *sw = cur; sw != end; sw++){         _swap(cur, sw);         fun(arr,end,cur+1);         _swap(cur, sw);     } } int main() {     char a[7] = { 1, 2, 3, 4, 5, 6, 7 };     fun(a, a + 7, a);     return 0; }

引用 21 楼 DelphiGuy 的回复:那个很厚道，而且是优化算法，利用个位数的乘机关系把搜索次数从720降到240。 不过受你的启发，我又写了一个更短的，效率肯定不如#19的代码，但是比#20的要好很多：  #include <stdio.h>  int main() {   int x[10][3] = {{2,3,6},{2,7,4},{3,2,6},{3,4,2},{3,7,1},{4,3,2},{6,7,2},{7,2,4},{7,3,1},{7,6,2}}, y[10];   for (y[4] = 0, y[7] = (1 << x[y[4]][0]) + (1 << x[y[4]][1]) + (1 << x[y[4]][2]); y[4] < 10; y[4]++)     for (y[5] = 1234; y[5] < 7655; y[5]++) {       for (y[6] = 0, y[8] = y[5], y[9] = y[7]; y[6] < 4; y[6]++) {y[y[6]] = y[8] % 10; y[8] /= 10; y[9] += 1 << y[y[6]];}       if (y[9] == 254 && (y[0] * 100 + 80 + x[y[4]][0]) * x[y[4]][1] == y[1] * 1000 + y[2] * 100 + y[3] * 10 + x[y[4]][2])         printf("%d8%d * %d = %d%d%d%d\n", y[0], x[y[4]][0], x[y[4]][1], y[1], y[2], y[3], x[y[4]][2]);     }   return 0; }  从优化效率来说，你这个确实厚道 但是如果是以短为目标，hardcode一个4！的全排列就显得太鸡贼了，不正派哇  还有，请不要跟20楼比效率，20楼本来就没考虑效率，这等于跟秃子比头发多，这么计较纯粹拉低你自己的档次。。。  受你启发，我又写了个更短的，不要跟我比效率，我直接认输。。 #include <stdio.h>  int main() {     for (int v = 1234567; v <= 7654321; v++){                for (int f[10] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, vl = v; (f[vl % 10] = 1), vl; vl /= 10)             if (vl<10 && f[1] + f[2] + f[3] + f[4] + f[5] + f[6] + f[7] == 7 && ((v / 1000000) * 100 + 80 + ((v / 100000) % 10)) * ((v / 10000) % 10) == v % 10000)                 printf("%d8%d * %d = %d\n", v / 1000000, (v / 100000) % 10, (v / 10000) % 10, v % 10000);     }     return 0; }

引用 17 楼 mstlq 的回复:[quote=引用 10 楼 bluestar2009 的回复:] [quote=引用 8 楼 zhao4zhong1 的回复:] 闲着也是闲着！//将1到7的数填入括号不能重复()8()×()=()()()() #include <stdio.h> #include <string.h> int next_pl(char * f, char * l) {     char t;     char *ff,*ll;      char * i = l;     if (f == l || f == --i) return (0);     while (1) {         char * p = i;         if (*--i < *p) {             char * j = l;             while (1) {                 j--;                 if (*i<*j) break;//             }             t=*i;*i=*j;*j=t;             ff=p;             ll=l;             for (; ff < ll; ++ff) {                 ll--;                 t=*ff;*ff=*ll;*ll=t;             }             return (1);         }         if (i == f) {             ff=f;             ll=l;             for (; ff < ll; ++ff) {                 ll--;                 t=*ff;*ff=*ll;*ll=t;             }             return (0);         }     } } int main() {     char a[]="\x01\x02\x03\x04\x05\x06\x07";      do {         if ((a[0]*100+80+a[1])*a[2]==a[3]*1000+a[4]*100+a[5]*10+a[6])             printf("%d8%d*%d=%d%d%d%d\n",a[0],a[1],a[2],a[3],a[4],a[5],a[6]);     } while (next_pl(a,a+7));     return 0; } //582*3=1746 //  高人！！我写了53行···[/quote] 楼主想要短的？ 那试试这个咯 #include <stdio.h> void _swap(char *l, char *r){ char t = *l; *l = *r; *r = t; } void fun(char* arr, char* end, char *cur) {     if (cur == end){         if ((arr[0] * 100 + 80 + arr[1])*arr[2] == arr[3] * 1000 + arr[4] * 100 + arr[5] * 10 + arr[6])             printf("%d8%d*%d=%d%d%d%d\n", arr[0], arr[1], arr[2], arr[3], arr[4], arr[5], arr[6]);         return;     }     for (char *sw = cur; sw != end; sw++){         _swap(cur, sw);         fun(arr,end,cur+1);         _swap(cur, sw);     } } int main() {     char a[7] = { 1, 2, 3, 4, 5, 6, 7 };     fun(a, a + 7, a);     return 0; }[/quote] 高人啊 递归一直不怎么明白

乘机关系 -> 乘积关系

引用 19 楼 DelphiGuy 的回复:谁能写个更短的（不要删空行之类的）：   #include <stdio.h>  int x[10][7] = {{1, 4, 5, 7, 2, 3, 6}, {1, 3, 5, 6, 2, 7, 4}, {1, 4, 5, 7, 3, 2, 6},   {1, 5, 6, 7, 3, 4, 2}, {2, 4, 5, 6, 3, 7, 1}, {1, 5, 6, 7, 4, 3, 2}, {1, 3, 4, 5, 6, 7, 2},    {1, 3, 5, 6, 7, 2, 4}, {2, 4, 5, 6, 7, 3, 1}, {1, 3, 4, 5, 7, 6, 2}}, y[24][4] = {{0, 1, 2, 3}, {0, 1, 3, 2}, {0, 2, 1, 3}, {0, 2, 3, 1}, {0, 3, 1, 2}, {0, 3, 2, 1},   {1, 0, 2, 3}, {1, 0, 3, 2}, {1, 2, 0, 3}, {1, 2, 3, 0}, {1, 3, 0, 2}, {1, 3, 2, 0},   {2, 0, 1, 3}, {2, 0, 3, 1}, {2, 1, 0, 3}, {2, 1, 3, 0}, {2, 3, 0, 1}, {2, 3, 1, 0},   {3, 0, 1, 2}, {3, 0, 2, 1}, {3, 1, 0, 2}, {3, 1, 2, 0}, {3, 2, 0, 1}, {3, 2, 1, 0}}, i, j;  int main() {   for (i = 0; i < 10; i++)     for (j = 0; j < 24; j++)       if ((x[i][y[j][0]] * 100 + 80 + x[i][4]) * x[i][5] == x[i][y[j][1]] * 1000 + x[i][y[j][2]] * 100 + x[i][y[j][3]] * 10 + x[i][6])         printf("%d8%d * %d = %d%d%d%d\n", x[i][y[j][0]], x[i][4], x[i][5], x[i][y[j][1]], x[i][y[j][2]], x[i][y[j][3]], x[i][6]);    return 0; }   这么打表不大厚道嘛。。。 我还可以直接hack一下  #include <stdio.h>  int main() {     printf("582*3=1746\n");     return 0; }  如果不求效率，只要短，也可以这样 #include <stdio.h>  int main() {     for (int v = 1234567; v <= 7654321; v++){         int f[10] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };         for (int vl = v; vl; vl /= 10)             f[vl % 10] = 1;         if (f[1] + f[2] + f[3] + f[4] + f[5] + f[6] + f[7] == 7 && ((v / 1000000) * 100 + 80 + ((v / 100000) % 10)) * ((v / 10000) % 10) == v % 10000)             printf("%d8%d * %d = %d\n", v / 1000000, (v / 100000) % 10, (v / 10000) % 10, v % 10000);     }     return 0; }

zhao4zhong1一般不生产代码，他只是代码的搬运工。

zhao4zhong1一旦不复制粘贴，一般都是精品。

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

我是用字符串处理的··  贴一下我的拙劣代码 #include <stdio.h> #include <stdlib.h> #include <string.h>  int main() { 	int aa[9] ={0}; 	int i=0,j=0,k=0,m=0,flag=0,cs=0,bcs=0,len=0; 	char res[5]= {0},ccs[4]={0},cbcs[2]={0},total[9]={0}; 	for (i=1;i<8;i++) 	{ 		for (j=1;j<8;j++) 		{ 			for (k=1;k<8;k++) 			{ 				cs = (i*100) + 80 + j; 				bcs = k; 				itoa(cs*bcs,res,10); 				if (strlen(res)!=4) 				{ 					continue; 				} 				itoa(cs,ccs,10); 				itoa(bcs,cbcs,10); 				strcpy(total,ccs); 				strcat(total,cbcs); 				strcat(total,res); 				len = strlen(total); 				if (len==8) 				{ 					memset(&aa,0,sizeof(int)*9); 					for (m=0;m<len;m++) 					{ 						aa[total[m]-48]++; 					} 					flag = 0; 					for (m=1;m<9;m++) 					{ 						if (aa[m]!=1) 						{ 							flag = 1; 							break; 						} 					} 					if (flag!=1) 					{ 						printf("cs[%d]bcs[%d]res[%d]\n",cs,bcs,cs*bcs); 						return 0; 					} 				} 			} 		} 	} }

开来→看来

引用 2 楼 mstlq 的回复:最无脑就是写个全排列，每个排列验证一下是否符合条件 开来我比无脑还无脑！连全排列都懒得写。 无脑非无脑，何处惹尘埃。

引用 8 楼 zhao4zhong1 的回复:闲着也是闲着！//将1到7的数填入括号不能重复()8()×()=()()()() #include <stdio.h> #include <string.h> int next_pl(char * f, char * l) {     char t;     char *ff,*ll;      char * i = l;     if (f == l || f == --i) return (0);     while (1) {         char * p = i;         if (*--i < *p) {             char * j = l;             while (1) {                 j--;                 if (*i<*j) break;//             }             t=*i;*i=*j;*j=t;             ff=p;             ll=l;             for (; ff < ll; ++ff) {                 ll--;                 t=*ff;*ff=*ll;*ll=t;             }             return (1);         }         if (i == f) {             ff=f;             ll=l;             for (; ff < ll; ++ff) {                 ll--;                 t=*ff;*ff=*ll;*ll=t;             }             return (0);         }     } } int main() {     char a[]="\x01\x02\x03\x04\x05\x06\x07";      do {         if ((a[0]*100+80+a[1])*a[2]==a[3]*1000+a[4]*100+a[5]*10+a[6])             printf("%d8%d*%d=%d%d%d%d\n",a[0],a[1],a[2],a[3],a[4],a[5],a[6]);     } while (next_pl(a,a+7));     return 0; } //582*3=1746 //  难得呀，这回居然不是复制粘贴

引用 8 楼 zhao4zhong1 的回复:闲着也是闲着！//将1到7的数填入括号不能重复()8()×()=()()()() #include <stdio.h> #include <string.h> int next_pl(char * f, char * l) {     char t;     char *ff,*ll;      char * i = l;     if (f == l || f == --i) return (0);     while (1) {         char * p = i;         if (*--i < *p) {             char * j = l;             while (1) {                 j--;                 if (*i<*j) break;//             }             t=*i;*i=*j;*j=t;             ff=p;             ll=l;             for (; ff < ll; ++ff) {                 ll--;                 t=*ff;*ff=*ll;*ll=t;             }             return (1);         }         if (i == f) {             ff=f;             ll=l;             for (; ff < ll; ++ff) {                 ll--;                 t=*ff;*ff=*ll;*ll=t;             }             return (0);         }     } } int main() {     char a[]="\x01\x02\x03\x04\x05\x06\x07";      do {         if ((a[0]*100+80+a[1])*a[2]==a[3]*1000+a[4]*100+a[5]*10+a[6])             printf("%d8%d*%d=%d%d%d%d\n",a[0],a[1],a[2],a[3],a[4],a[5],a[6]);     } while (next_pl(a,a+7));     return 0; } //582*3=1746 //  高人！！我写了53行···


Question: 求从内存4区指导分析这个执行结果

VMMap 是进程虚拟和物理内存分析实用工具。http://technet.microsoft.com/zh-cn/sysinternals/dd535533

i和buf尽管是函数栈里的局部变量，但是它们存在时总是在某个位置的，所以你能得到这些局部变量的地址；  局部变量的生命周期由编译器控制的，函数执行结束时就会释放，你无法判断这个时候这些地址指向的内容有没有被改变，所以不要试图去获取已被释放的局部变量所在地址指向的内容

为什么老师到哪都发这个。。。

栈中的变量通常包括函数参数和函数里声明的临时变量。 栈中的基本变量退出其作用域时，没有谁执行一段代码去释放/销毁/析构它所占用的内存，仅仅是没人再去理会的留在当前栈顶上方的若干遗留下来可被后续压栈操作覆盖的无用数据而已。 而栈中的类变量退出其作用域时，会自动执行其析构函数，……  计算机组成原理→DOS命令→汇编语言→C语言（不包括C++）、代码书写规范→数据结构、编译原理、操作系统→计算机网络、数据库原理、正则表达式→其它语言（包括C++）、架构……  对学习编程者的忠告： 多用小脑和手，少用大脑、眼睛和嘴，会更快地学会编程！ 眼过千遍不如手过一遍！ 书看千行不如手敲一行！ 手敲千行不如单步一行！ 单步源代码千行不如单步Debug版对应汇编一行！ 单步Debug版对应汇编千行不如单步Release版对应汇编一行！ 不会单步Release版对应汇编？在你想单步Release版C/C++代码片断的前面临时加一句DebugBreak();重建所有，然后在IDE中运行。（一般人我不告诉他！）  VC调试时按Alt+8、Alt+7、Alt+6和Alt+5,打开汇编窗口、堆栈窗口、内存窗口和寄存器窗口看每句C对应的汇编、单步执行并观察相应堆栈、内存和寄存器变化，这样过一遍不就啥都明白了吗。 对VC来说，所谓‘调试时’就是编译连接通过以后，按F10或F11键单步执行一步以后的时候，或者在某行按F9设了断点后按F5执行停在该断点处的时候。

首先,*i);传了一个值。 buf只传了地址，之后又被修改了。

这两个都是返回局部变量地址，需要注意的是局部变量是在函数栈上申请的，作用域是函数内，生命周期是从函数调用开始，函数调用结束（得到返回值），函数栈就会被释放，什么意思呢，释放了就是在使用也没有意义，释放之后就可能被其他的函数栈再次使用，如果别的函数栈使用了，上一个函数用于存放buf和i的地址，那么你得到的buf/i的内容就是随机的了，如果没有被使用，那么可能会得到你想要的结果；因此返回局部变量的地址具有不确定性，那么使用它就失去了我们编程的逻辑和确定性。

引用 2 楼 muniq 的回复:引用 1 楼 user-6 的回复:两个都是不对的，局部变量在函数调用完就销毁了，你例子什么都不能说明，如果输出的值是你期望的，最多也只能说明这个地址还没有被其他数据覆盖，你试下在system("pause");前再输出下i的值看还是不是你期望的我知道这个不能说明什么 ，栈内存在执行完就会被析构，只是想知道为什么会有这样的结果  什么样的结果都是可能的，使用销毁的内存是一个未定义行为，局部变量销毁不代表清0，只是移动了栈顶指针

引用 1 楼 user-6 的回复:两个都是不对的，局部变量在函数调用完就销毁了，你例子什么都不能说明，如果输出的值是你期望的，最多也只能说明这个地址还没有被其他数据覆盖，你试下在system("pause");前再输出下i的值看还是不是你期望的 我知道这个不能说明什么 ，栈内存在执行完就会被析构，只是想知道为什么会有这样的结果


Question: linbids，libpcap运行时错误

跟cnt参数没关系，这明显是从网卡度报文过程中发什么异常导致循环被终止，看看你的网卡是否有什么异常吧


Question: Mac上执行gcc命令出现xcrun: error: invalid active developer path....如何解决？

直接命令行输入：xcode-select --install 你会有惊喜 记得给积分哦

http://blog.csdn.net/kedongjun/article/details/51470506 https://www.cnblogs.com/espooky/p/5979920.html


Question: 小白求教基本函数问题（double与float）

楼上正解。。。。。。

因为double和float的占用内存大小不一样。  若定义double a，那么输入时需要注意应该用%lf 因为%f是针对float，而%lf是对应double