Question: 请教一下，我执行到了fges()，函数遇到了段错误

引用 11 楼 zjq9931 的回复:[quote=引用 8 楼 遥_望 的回复:] 刚才加上了，还是不行。我把其他逻辑处理的都注释掉了，只是运行fgets函数，还是出错 那就跟踪调试吧，这个会不？ 读取66次就会有问题？ 简单的就是增加一个变量，增加一个条件，66次的时候，设置一个断点，看看是因为什么错误了。 [/quote] 刚才用gdb调试过了  这是不知道是不是我的rewind错了呢，突然出现rewind.c没有那个文件或目录，这个怎么解决呢

引用 8 楼 遥_望 的回复:刚才加上了，还是不行。我把其他逻辑处理的都注释掉了，只是运行fgets函数，还是出错 那就跟踪调试吧，这个会不？ 读取66次就会有问题？ 简单的就是增加一个变量，增加一个条件，66次的时候，设置一个断点，看看是因为什么错误了。

引用 9 楼 qybao 的回复:把static FILE *fp = NULL;改成非static试试，也就是每次都重新打开文件，读完关闭文件，看看会不会也出错，如果不出错，那就是rewind(fp);失败了 另外，sprintf(energy_str,"%f",energy);之类的处理最好指定小数长度，如%.4f（保留4位小数）之类的，否则小数过多数组也可能越界 刚才试了一下，如果读完关闭文件，执行fclose()会出现 free(): invalid next size (normal): 0xb5d00c88错误。 要崩溃，不知道怎么搞，我这又只是单线程的读文件，也没有用到动态内存

引用 7 楼 zjq9931 的回复:fgets(strLine,MAX_LINE,fp);   这一句改成 fgets(strLine,MAX_LINE-1,fp);   开始读取循环之前记得初始化一下 memset(strLine,  0,  MAX_LINE);  char strLine[MAX_LINE] = {0}; 	 	static FILE *fp = NULL; 	static int i = 1; 	if(fp == NULL) 	{ 		fp = fopen(GE_FILE_PATH,"r"); 		if(fp == NULL) 			exit(0); 	} 	 	printf("energy:%f\n",energy); 	sprintf(energy_str,"%f",energy); 	printf("energy_str:%s\n",energy_str); 	rewind(fp); 	printf("************************************************************************    i= %d\n",i); 	i++; 	while(1)									 	{  		memset(strLine,0,MAX_LINE); 		fgets(strLine,MAX_LINE-1,fp);		 		break; 		/* if(feof(fp))  			break; 		//printf("%s\n",strLine); 		//获取到第一列数据(能量)，如果与传入进来的能量不一样，则不往下执行，继续获取下一行数据。 		char *p = strtok(strLine, " "); 		sprintf(temp,"%f",atof(p)); 		//printf("temp:%s\n",temp); 		//printf("energy_str:%s\n",energy_str); 		strcpy(cmp_str,energy_str);  刚才加上了，还是不行。我把其他逻辑处理的都注释掉了，只是运行fgets函数，还是出错

总结： 1、经过gdb单步调试了一上午，所有的变量都没有出错，文件指针、strLine 都为正确的值 2、如果没有flose()，free()那么程序就不会出现段错误。只要一执行，就会报出非法地址，看情况像是文件指针和strLine出错，但是gdb调试看出地址是绝对没错的，这是一个奇怪的现象。 3、在调用Analy_G_File（）函数的函数中，使用了malloc()分配了动态内存。因此我将这里改成了栈分配，至此程序一切正常了 4、问题不在fgets()，rewind()。  在另一个函数用malloc分配时，如果我free掉Analy_G_File()中的strLine，会出现非法指针或者重释放错误（这两种错误是概率出现其中一个），如果改成栈分配了，程序就正常了。  具体什么原因，实在想不明白。因为项目进度问题，就此结贴。 谢谢各位大佬了。

if(feof(fp))              break; 改成： if(!feof(fp))              break;  feof若文件结束返回0，文件不结束返回非0.

引用 12 楼 遥_望 的回复:这是不知道是不是我的rewind错了呢，突然出现rewind.c没有那个文件或目录，这个怎么解决呢 这个程序的第43行，rewind(fp)出错了。 rewind34行是库的源文件了。 打出来最开始fp啊。然后对比戳戳之后的fp啊。 估计程序是有越界，导致fp的值被修改了。

大佬们走过路过帮忙解答一下，小弟不才，找不出原因来

引用 3 楼 qybao的回复:static FILE *fp = NULL; //文件指针，静态，打开一次就不会重复打开了 用了静态变量，每次进入函数不是从头开始读的，所以有eof的可能，所以应该先判断不为eof再读取数据 不是，我前面有执行指针偏移了！rewind(fp);

不是，我前面有执行指针偏移了！rewind(fp);

引用 1 楼 qybao的回复:是不是读到文件结尾了已经eof了 下面两句代码交换一下位置，先判断是否eof，不为eof再读数据 fgets(strLine,MAX_LINE,fp);                if(feof(fp)) 试过了不行！我这里是每次进入这个函数都是从头开始读的，在第66次进去的时候，就段错误了！


Question: 帮忙改进一下程序

建议把代码贴出来，不建议用图片～

加printf打印调试下，get_correct逻辑非常混乱，不知道while循环里再加一个while循环是什么用意

#include<stdio.h> void get_num(char le); float get_correct(void); char get_first(void); int main(void) { 	char ch; 	while (1) 	{ 		printf("Enter the operation of your choice:\n"); 		printf("a. add\t\t\ts. subtract\n"); 		printf("m.multiply\t\td.divide\n"); 		printf("q.quit\n"); 		ch = get_first(); 		while (ch != 'a' && ch != 's' && ch != 'm' && ch != 'd' && ch != 'q') 			continue; 		get_num(ch); 	} 	return 0; } void get_num(char le) { 	float n1, n2; 	printf("Enter first number:"); 	n1 = get_correct(); 	printf("Enter second number:"); 	n2 = get_correct(); 	if (le == 'a') 		printf("%f + %f = %f", n1, n2, n1 + n2); 	else if (le == 's') 		printf("%f - %f = %f", n1, n2, n1 - n2); 	else if (le == 'm') 		printf("%f * %f = %f", n1, n2, n1 * n2); 	else if (le == 'd') 	{ 		if (n2 == 0) 			printf("Enter a nulmber other than 0:"); 		scanf_s("%f",&n2); 		printf("%f / %f = %f", n1, n2, n1 / n2); 	} 	else if (le == 'q') 	{ 		printf("Bye!\n"); 	} } float get_correct(void) { 	char ch; 	float n; 	while (scanf_s("%f", &n) != 1); 	{ 		while ((ch = getchar()) != '\n'); 			putchar(ch); 		printf(" is not a number.\n"); 		printf("Please enter a number such as 2.5,-1.78E8,or 3:1"); 		scanf_s("%f", &n); 	} 	return n; } char get_first(void) { 	char ch; 	ch = getchar(); 	while (getchar() != '\n') 		continue; 	return ch; } 回复晚了，上课。不知道还有就救不,,,,


Question: C语言 将 结构体数组的成员地址 赋值给 指向结构体的指针 问题

引用 3 楼 覆陇黄 的回复:头一次见指针指向结构体的成员，而不是结构体的，长知识了。 同时这个问题我看了评论还没想明白 看你楼下那个大神写的就明白了

引用 4 楼 Hippop314 的回复:这里面有几个错误： 1、结构体数组赋值，应该是{元素1, 元素2, ...}，其中元素是一个结构体，因此，元素1赋值为{成员1, 成员2, ...}，所以正确的赋值方法为：struct student st[2] = {{110, "zhang"}, {2, "li"}};直接按照你写的来做，编译器会报警告，在某些情况下，元素二没有被正确赋值。 2、st[0].name的类型是字符串，因此，应该使用char *s; s = st[0].name; 3、st[0].num的类型是int，因此，应该使用 int p; p = st[0].num; 4、至于为什么st[0].name和st[0].num通过类型强制转换赋值给类型为struct student *的s, p。最后还能正确打印出它的值。这是因为，类型强制转换除了float, double的强制转换之外，都不会改变变量内的值。因此，st[0].name强制转换赋值给s，但是，s存放的依旧是name成员的地址。printf中%s只认指针指向的地址的内容，因此，s还是指向的是字符串，打印依旧正确。对于，st[0].num强制转换赋值给p，但是，p的值依旧是num，也就是说，p指向了地址为110的内存。而110是一个无效的地址，不能使用*p取它的内容。但是，printf中的%d只关心变量的值，不关心它的内容，因此，使用%d就会将p指向的地址打出来，就是110。看上去也是对的。  原来是看上去是对的，恍然大悟哈哈哈，这题我是在看谭浩强的教材的时候看到结构体指针那一块，书上强转了stu[0].name，同时我对如果强转对象如果不是字符数组产生了好奇，才写的这一串代码，主要是为了明白它这样的结果是为啥啦

对于地址的打印，一般是用%p，p， s都是指针，并且是结构体指针，s = (struct student*)st[0].name; p = (struct student*)st[0].num; 这样的赋值在实际中基本上没什么意义（实际中不这么用），还不好理解。

引用 1 楼 kuangbao9 的回复:关键不在于是不是数组或者值，而是因为强制转换了，所以可以直接复赋值，*p是指向结构体的指针，因此以%d打印*p是没有内容的，肯定是打印p的 也就是说这里的p就是直接被赋予了强转后的变量值，而不是指向某个地址吗


Question: 求助，c语言的指针是不是可以这样理解，求助啊啊啊

完全正确，+10分

恩，理解是没问题的。*p = 3就是对p指向的内存单元做引用，又由于p指向i，所以*p = 3;等同于i = 3;

理解得没错哈

可以这么说。但是需要注意用字符指针初始化一个字符串常量的时候，不可以改变其中元素。

来啦来啦，我觉得行

来人啊！！！！


Question: 用顺序表让两个多项式相加 以下这个程序怎么改

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


Question: code blocks无法运行

编译一下,应该是报错了


Question: 这是啥意思？为啥我gcc编译不出来，还有这是握在网上弄得win系统一键装，可是我感觉这win10系统怪怪的，请各位大神帮我鉴定一下

引用 1 楼 durant 的回复：先去安装gcc啊为啥我这win10没有1920*1080的分辨率，难道这个是盗版吗？

先去安装gcc啊

引用 3 楼 赵4老师 的回复：Visual C++ 2010 Express简体中文版http://pan.baidu.com/s/1bnwRVLt请问您有win7或win10系统的网盘吗？我这在第三方软件里面下载了个盗版的，分辨率之类的各项功能都不好用后悔死了，以前的win7没有备份直接就被删除了


Question: C语音

自己不熟悉的、感兴趣的用法都写一写，可以边写边参考书里或者函数手册。

从刷题开始。@*/@

引用 1 楼 轻箬笠的回复:1.每天都要写代码。 2.每天来论坛回答问题，不会的可以百度，加深记忆 嗯嗯  谢谢指点  我现在每天都在写

1.每天都要写代码。 2.每天来论坛回答问题，不会的可以百度，加深记忆


Question: 二维数组与双重指针的关系、区别

引用 1 楼 user-3的回复:有很多地方存在认识偏差 还是不要到处贴比较好 本人小白一个，正在学习中  偏差请指正一下，谢谢

你好，我不太懂这方面知识  在博客看到了这个，觉得好像又解释的通，就想找个地方标记一下 能说说这个博客哪些方面有偏差吗？  https://blog.csdn.net/u013684730/article/details/46565577?utm_source=app

http://edu.csdn.net/course/detail/2516 C语言指针与汇编内存地址-三.数组和二维数组

你的问题是什么？

有很多地方存在认识偏差 还是不要到处贴比较好


Question: C语言  C控制语句:循环

你想说啥？

如果要做笔记，建议用印象笔记或有道笔记～

引用 1 楼 英雄@末路的回复:你想说啥？ 这仅仅是笔记而已😊😊

“多一少一”问题占程序员常犯错误的10%以上！ 避免“多一少一”问题的方法之一是将比如<10甚至<5的数代入程序片断，掰手指头心算验证一下程序到底应该写为 x、x-1、x+1中的哪个？ <、<=、==、>、>=中的哪个？  for (A;B;C) D; //等价于 {  A;  while (1) {   if (!(B)) break;   D;   C;  } }


Question: 为什么我写的两个源文件，调试出来的却是一个源文件

引用 2 楼 user-3 的回复：程序只能有main一个入口，如果需要调用其他源文件，则需调用其中的函数，但是此时需要增加函数声明和相应头文件怎么弄呢？

文件是文件，函数是函数 你的目的是啥啊，写两个，你可以只编译一个文件啊

引用 6 楼 轻箬笠 的回复：引用 5 楼 weixin_45584476 的回复:[quote=引用 1 楼 轻箬笠 的回复：]程序入库是main，没有main01。一般程序的入库名称是固定的可是如果都用main的话另一个就会调试失败，我该怎么处理啊 创建两个控制台项目。[/quote]是重新创建吗？可是为啥我在网上看视频的时候看见别人直接就在源文件上面就直接创建了，我一直不明白

引用 5 楼 weixin_45584476 的回复:引用 1 楼 轻箬笠 的回复：程序入库是main，没有main01。一般程序的入库名称是固定的可是如果都用main的话另一个就会调试失败，我该怎么处理啊 创建两个控制台项目。

引用 3 楼 weixin_45584476 的回复：引用 1 楼 轻箬笠 的回复：程序入库是main，没有main01。一般程序的入库名称是固定的如果两个源文件都是main的话调试会失败啊请问我应该怎么处理啊

程序入库是main，没有main01。一般程序的入库名称是固定的


Question: 我是国科大本科材料专业 如果想从事半导体、电子方面的材料研究是否有必要去学习C语言 是否有用

有用 写个算法啥的 仿真里面写个测试程序啥的，都可以用C来实现。

曾经的研究生院，现在也有本科了，好像退步了哟~~~


Question: 程序小白关于Visual studio2019中c语言++和--运算符的疑问

对头，我编译器运算结果为  1  1   1 ，并且可以理解为啥是这个结果

传参顺序跟编译器有关系，因此这样的代码不建议写，能避免就尽可能的避免写这样的代码

引用 5 楼 liups的回复:[quote=引用 1 楼 Italink 的回复:] 因为函数传参的顺序是从右往左的 标准中没有规定求值的顺序，只能说楼主这里是这样的顺序。所以，楼主应该避免这样的写法[/quote] 好的ヾ ^_^♪。。

引用 3 楼 user-6的回复:引用 1 楼 Italink 的回复:因为函数传参的顺序是从右往左的错 记住了。。。。。。

还有如下程序，其运行结果可能更让初学者不得要领。个人非常认同裘教授观点，C/C++教学者、从业者不要去钻这种牛角尖，没有意义。除非有某种非常非常特殊的目的，否则类似这种代码在实际开发中绝对应该禁止。 #include <stdio.h>  void Fun(int i, int j, int k) {     printf("%d %d %d\n", i, j, k); }  int main() {     int a = 1;     Fun(a += 1, a += 1, a += 1);      return 0; }

谢谢大佬指点，以后应该避免这样写程序

引用 1 楼 Italink 的回复:因为函数传参的顺序是从右往左的 标准中没有规定求值的顺序，只能说楼主这里是这样的顺序。所以，楼主应该避免这样的写法

代码错 结果没意义 这是未定义行为

引用 1 楼 Italink 的回复:因为函数传参的顺序是从右往左的错

printf后面的逗号不是逗号运算符。类似这种问题的研究没有多少意义，最好不要这么写程序。 建议看看这个https://bbs.csdn.net/topics/370153775。

因为函数传参的顺序是从右往左的


Question: CS app第五章优化程序有点不太懂

对不起，我就是个睿智


Question: C语言

精度问题，你可以继续往后面看

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

printf %f 本身自带舍入  你想看不准确值 %.40f 就看到了

IEEE 754浮点数标准详解


Question: WinMain的疑问

引用 9 楼 六道佩恩 的回复:这个0x00400000我以前也查看过值， windows现在既然这么设计，应该能说明现在在逐渐脱离对实例句柄的使用了吧？我学windows编程几个月了，基本都没用到过实例句柄，一般都是设置的NULL。 也不能这样说，那是你还没涉及到复杂的情况，其实hInstance句柄还是很有用的 比如说上面的用于标识自定义资源的所在位置，还有类所在的空间等  The window class name is not sufficient to identify the class uniquely. Each process has its own window class list, and each entry in the window class list consists of an instance handle and a class name. For example, here's what the window class list might look like if a program has two DLLs, both of which register a class name "MyClass", passing the DLL's handle as the HINSTANCE.      HINSTANCE   Class name 1. USER32.DLL   Static 2. USER32.DLL   Button 3. USER32.DLL   Listbox 4. USER32.DLL   Combobox 5. USER32.DLL   Edit 6. A.DLL             MyClass 7. B.DLL             MyClass  When it comes time to create a window, each module then passes its own HINSTANCE when creating the window, and the window manager uses the combination of the instance handle and the class name to look up the class. CreateWindow("MyClass", ..., hinstA, ...); // creates class 6 CreateWindow("MyClass", ..., hinstB, ...); // creates class 7 CreateWindow("MyClass", ..., hinstC, ...); // fails  This is why it is okay if multiple DLLs all register a class called "MyClass"; the instance handle is used to tell them apart.  There is an exception to the above rule, however. If you pass the CS_GLOBALCLASS flag when registering the class, then the window manager will ignore the instance handle when looking for your class. All of the USER32 classes are registered as global. Consequently, all of the following calls create the USER32 edit control: CreateWindow("edit", ..., hinstA, ...); CreateWindow("edit", ..., hinstB, ...); CreateWindow("edit", ..., hinstC, ...);  If you are registering a class for other modules to use in dialog boxes, you need to register as CS_GLOBALCLASS, because as we saw earlier the internal CreateWindow call performed during dialog box creation to create the controls passes the dialog's HINSTANCE as the HINSTANCE parameter. Since the dialog instance handle is typically the DLL that is creating the dialog (since that same HINSTANCE is used to look up the template), failing to register with the CS_GLOBALCLASS flag means that the window class lookup will not find the class since it's registered under the instance handle of the DLL that provided the class, not the one that is using it.  In 16-bit Windows, the instance handle did other things, too, but they are no longer relevant to Win32.  A common mistake is to pass the HINSTANCE of some other module (typically, the primary executable) when registering a window class. Now that you understand what the HINSTANCE is used for, you should be able to explain the consequences of registering a class with the wrong HINSTANCE.  另外，路径中其实有中文和空格也是可以的，甚至有括号也无妨，加双引号括起来就OK MessageBox(NULL, GetCommandLine(), TEXT("Title"), MB_OK);  例如 "E:\T43\ASM\MASM32\Windows\Windows 核心编程\Windows 核心编程(第5版)\HelloWin\HelloWin.exe" 123 "avbc 123"

引用 8 楼 Intel0011 的回复:https://stackoverflow.com/questions/15462064/hinstance-in-createwindow  I found in MSDN dated from 2001 for CreateWindow and CreateWindowEx  hInstance  Windows 95/98/Me: [in] Handle to the instance of the module to be associated with the window.  Windows NT/2000/XP: This value is ignored.   这是一个实例的句柄，在98等系统下是有不同意义的，而在2000中你会发现它的默认值都是0x00400000 这个0x00400000我以前也查看过值， windows现在既然这么设计，应该能说明现在在逐渐脱离对实例句柄的使用了吧？我学windows编程几个月了，基本都没用到过实例句柄，一般都是设置的NULL。

刚查看了一下MSDN，这个LoadCursor出错方式确实比较奇葩 Remarks The LoadCursor function loads the cursor resource only if it has not been loaded; otherwise, it retrieves the handle to the existing resource. This function returns a valid cursor handle only if the lpCursorName parameter is a pointer to a cursor resource. If lpCursorName is a pointer to any type of resource other than a cursor (such as an icon), the return value is not NULL, even though it is not a valid cursor handle.

引用 2 楼 六道佩恩 的回复:很奇怪，LoadCursor那里，我测试了，结果也一样，按理说不是应该NULL报错吗，怎么用NULL反而正确，用实例句柄反而出问题？包括CreateWindow也是一样，我指定NULL也没有产生错误。这是不是说，现在Windows内部在逐渐脱离对示例句柄的使用？ 这个是没有问题的，给LoadCursor传NULL表示加载系统预先定义图标，传hInstance表示加载自定义的图标，你没有定义图标资源当然报错。对于CreateWindow，现在版本的Windows确实是对hInstance变为可选的参数了，可以不用传hInstance 另外，含空格和中文字符的路径确实比较容易出现问题

引用 4 楼 轻箬笠 的回复:看楼主这路径，有没有可能是中文的问题。我测试的时候，没碰到路径只有一半的问题 一语惊醒梦中人！感谢！

看楼主这路径，有没有可能是中文的问题。我测试的时候，没碰到路径只有一半的问题

引用 1 楼 Intel0011 的回复://第三问：目前没发现你说的问题，只是要注意，如果路径中含有空格需要使用双引号将之括起来 你看看我的测试结果：  我最开始也是以为有空格，但你看第二行GetCommandLine的结果，是没有空格的，实际上也确实没有空格。我还把代码文件放不同地方测试，都有这种问题，放桌面甚至什么都不显示。

引用 1 楼 Intel0011 的回复://* #define UNICODE #define _UNICODE //*/ #include <Windows.h> #include <tchar.h> #include <stdio.h>  #pragma comment(lib, "gdi32") #pragma comment(lib, "user32")  #pragma comment(linker, "/subsystem:windows,5.1.2600")  LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);  int WINAPI _tWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPTSTR szCmdLine, int iCmdShow) {    static TCHAR szAppName[] = TEXT("HelloWin");    HWND         hwnd;    MSG          msg;    WNDCLASS     wndclass;        //*    {       TCHAR str[MAX_PATH];       //wsprintf(str, TEXT("%d"), Number_Object);       //第一问：下面的结果表明hPrevInstance确实已经不使用了       //其实hPrevInstance是Win16下的产物，之所以现在还保留是因为将Win16程序迁移到Win32时不必修改Win16的代码       //如果Win32模型中去掉hPrevInstance，则将Win16程序迁移到Win32时将修改大量已存在的Win16代码       _stprintf(str, TEXT("%p %p"), hInstance, hPrevInstance); // hInstance:00400000 hPrevInstance:00000000       MessageBox(GetActiveWindow(), str, TEXT("Test"), MB_OK);    }    //*/     RtlZeroMemory(&wndclass, sizeof(wndclass));    wndclass.style         = CS_HREDRAW | CS_VREDRAW;    wndclass.lpfnWndProc   = WndProc;    wndclass.hInstance     = hInstance;    wndclass.hIcon         = LoadIcon(NULL, TEXT("#32512"));        SetLastError(0);    //第二问：hInstance还是有用的    wndclass.hCursor       = LoadCursor(NULL, IDC_ARROW); // GetLastError:0(操作成功完成), wndclass.hCursor:00010003    //wndclass.hCursor       = LoadCursor(hInstance, IDC_ARROW); // GetLastError:1812(指定的映像文件不包含资源区域), wndclass.hCursor:00000000    //*    {       TCHAR str[MAX_PATH];       wsprintf(str, TEXT("%u %p"), GetLastError(), wndclass.hCursor);       MessageBox(GetActiveWindow(), str, TEXT("Test"), MB_OK);    }    //*/    wndclass.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);    wndclass.lpszMenuName  = NULL;    wndclass.lpszClassName = szAppName;        //第三问：目前没发现你说的问题，只是要注意，如果路径中含有空格需要使用双引号将之括起来    //*    {       TCHAR str[MAX_PATH];       wsprintf(str, TEXT("%s"), szCmdLine);       MessageBox(GetActiveWindow(), str, TEXT("Test"), MB_OK);    }    //*/     if (!RegisterClass(&wndclass))    {       MessageBox(NULL, TEXT("This program requires Windows NT series!"), szAppName, MB_ICONERROR);       return -1;    }          hwnd = CreateWindowEx(WS_EX_APPWINDOW,         // A tool window does not appear in the task bar or in the window that appears when the user presses ALT+TAB.                          szAppName,                  // window class name                          TEXT("The Hello Program"),  // window caption                          WS_OVERLAPPEDWINDOW,        // window style                          500,//CW_USEDEFAULT,              // initial x position                          200,//CW_USEDEFAULT,              // initial y position                          320,//CW_USEDEFAULT,              // initial x size                          320,//CW_USEDEFAULT,              // initial y size                          NULL,                       // parent window handle                          NULL,                       // window menu handle                          hInstance,                  // program instance handle                          NULL);                      // creation parameters     //第四问：第四个参数是另一个程序运行此程序时给这个程序制定的显示状态吗？ --> 是的，你可以为你写的程序建立一个快捷方式，然后右键单击快捷方式，在运行方式项选择"常规窗口"、"最小化"、"最大化"看看运行结果即可    //第四个参数传给ShowWindow    ShowWindow(hwnd, iCmdShow);    UpdateWindow(hwnd);        {       BOOL bRet;       while ((bRet = GetMessage(&msg, NULL, 0, 0)) != 0)       {          if (bRet == -1)          {             MessageBox(NULL, TEXT("GetMessage Error."), TEXT("Message"), MB_ICONERROR);             return -1;          }          else          {             TranslateMessage(&msg);             DispatchMessage(&msg);          }       }    }        return msg.wParam; }  LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) {      switch (message)    {       case WM_DESTROY:          PostQuitMessage(0);          return 0;    }    return DefWindowProc(hwnd, message, wParam, lParam); }  很奇怪，LoadCursor那里，我测试了，结果也一样，按理说不是应该NULL报错吗，怎么用NULL反而正确，用实例句柄反而出问题？包括CreateWindow也是一样，我指定NULL也没有产生错误。这是不是说，现在Windows内部在逐渐脱离对示例句柄的使用？


Question: 求助，急！！！

程序员的常识之一：不要将程序源代码或项目或exe放在桌面这种复杂（多半带空格和汉字且在防火墙或杀毒软件严密控制的C盘上）的目录下。

路径不要有中文名  把那个永恒名字改了先


Question: 关于c中eof用法，多组输入输出的     程序运行顺序问题  求大佬解答

好吧，我来接分，可以结帖了，哈哈哈

好吧其实我看错了  acm题目不分样例一样例二  我才以为是先输完全部数据再输出全部答案


Question: 怎么判断窗口是不是最底层窗口，最顶端窗口可以用GetTopWindow实现，那最底端呢

GetNextWindow The GetNextWindow function retrieves a handle to the next or previous window in the Z order. The next window is below the specified window; the previous window is above. If the specified window is a topmost window, the function retrieves a handle to the next (or previous) topmost window. If the specified window is a top-level window, the function retrieves a handle to the next (or previous) top-level window. If the specified window is a child window, the function searches for a handle to the next (or previous) child window.   HWND GetNextWindow(   HWND hWnd,  // handle to current window   UINT wCmd   // direction flag );   Parameters hWnd  Handle to a window. The window handle retrieved is relative to this window, based on the value of the wCmd parameter.  wCmd  Specifies whether the function returns a handle to the next window or of the previous window. This parameter can be either of the following values: Value Meaning  GW_HWNDNEXT Returns a handle to the window below the given window.  GW_HWNDPREV Returns a handle to the window above the given window.    Return Values If the function succeeds, the return value is a handle to the next (or previous) window. If there is no next (or previous) window, the return value is NULL. To get extended error information, callGetLastError.   Remarks Using this function is the same as calling the GetWindow function with the GW_HWNDNEXT or GW_HWNDPREV flag set.   QuickInfo   Windows NT: Requires version 3.1 or later.   Windows: Requires Windows 95 or later.   Windows CE: Unsupported.   Header: Declared in winuser.h.   Import Library: Use user32.lib.  See Also Windows Overview, Window Functions, GetTopWindow     Window Functions The following functions are used to create and manage windows.        AdjustWindowRect   AdjustWindowRectEx   AnimateWindow   ArrangeIconicWindows   BeginDeferWindowPos   BringWindowToTop   CascadeWindows   ChildWindowFromPoint   ChildWindowFromPointEx   CloseWindow   CreateWindow   CreateWindowEx   DeferWindowPos   DestroyWindow   EnableWindow   EndDeferWindowPos   EnumChildProc   EnumChildWindows   EnumThreadWindows   EnumThreadWndProc   EnumWindows   EnumWindowsProc   FindWindow   FindWindowEx   GetClientRect   GetDesktopWindow   GetForegroundWindow   GetLastActivePopup   GetNextWindow   GetParent   GetTopWindow   GetWindow   GetWindowPlacement   GetWindowRect   GetWindowText   GetWindowTextLength   GetWindowThreadProcessId   IsChild   IsIconic   IsWindow   IsWindowUnicode   IsWindowVisible   IsZoomed   MoveWindow   OpenIcon   SetForegroundWindow   SetParent   SetWindowLong   SetWindowPlacement   SetWindowPos   SetWindowText   ShowOwnedPopups   ShowWindow   ShowWindowAsync   TileWindows   WindowFromPoint   WinMain


Question: 在c语言中，怎么在数组的特定位置插入字符

贴出你的代码吧，看看逻辑有什么麻烦的。

引用 2 楼 weixin_43925997 的回复:如果做循环的话，给一个\n后，会覆盖掉下一个字符，做自增的话，要是这么简单我就不来发帖了 怕覆盖，得从后面开始处理，你得先计算好。大致是：最后一个应该是\n吧，它的位置是多少，然后是原最后一个字符的新位置，把它复制过去，接下来是倒数第二个或者\n

最简单的是再分配个数组，长度是原来数组长多的 6/5取对其，然后循环拷贝，每拷5个赋值一个\n ，当然空间，时间都没啥效率可言。  或者realloc原来的缓冲区，算好长度，从后往前拷，算长度的时候记得最后几个不是5的倍数的处理，空间省点，时间没啥差别。

麻烦在哪里？创建个临时数组呗，每拷贝5个字符加个\n，最后再把临时数组拷贝回去


Question: 求大佬

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

如果对嵌入式感兴趣，建议了解一下Linux系统和该系统下的编辑和编译系统。

你指的是IDE工具吗？VS呗~

Code::Blocks  比vs要小，但是用来学习还是够的

notepad++  sublime  编译器用 mingw(windows)


Question: 求大佬帮看一下我写的代码，怎么把一个函数传到另一个函数里啊？

typedef double (* _f1)(int n,double a[],double x); void F(void *函数指针,int n double a[],double x) {  (_f1*)函数指针(n,a,x);  } 把函数做为指针传入另一个函数,在内部再用(f1*)转换为f1类型的指针。这个你看怎么定义，void * 是为了适应不同的函数做为参数，你如果只传一种函数可以直接定义为f1* 函数指针。

引用 1 楼 user-1 的回复:void f(void * f,int n,double a[],double x) {   (f1*)f(n,a,x);  }能不能详细说一下呀，看不太懂QAQ


Question: 请教如何使用c语言实现图形化界面输出

个人觉得SDK纯API方式编写Windows程序已经不推荐了，效率太低，了解一下原理就可以了，主要是消息机制。  图形用户界面（GUI）编程可以学习C++ Builder，架构先进（和C#一样拖控件），入门比较容易。  　　C++ Builder是真正的可视化的开发工具。C++ Builder可以用鼠标拖拉控件加上设置属性轻松的“设计”出一个程序的图形用户界面，利用可视的组件/控件像“搭积木”一样，以“所见即所得”的方式搭建应用程序的界面，这也是C++ Builder这个名字中Builder的概念。这样，只需要用C++语言编写业务逻辑代码，类似于DOS下文本界面编程，只要专注于实现业务逻辑功能就可以了，代码非常简洁。数据的输入和表现，都在图形用户界面，非常直观、易用。这就是RAD开发（Rapid Application Development，快速应用程序开发）。  书籍推荐： 《C++Builder 6程序设计教程（第二版）》 （陆卫忠，刘文亮　等编著 /2011-04-01 /科学出版社）（当当网） 《C++Builder 6编程实例精解》（赵明现），PDF，是数字版的，非扫描版的，里面还有一个俄罗斯方块游戏的完整实现。 《精彩C++Builder 6程序设计》（台湾 吴逸贤），里面有10几个简单小游戏的实现，可以自己看懂以后再重写，才是自己掌握的。 《C++ Builder 5高级编程实例精解》（刘滨 编著）都是较大的实用的程序。  C++ Builder书籍下载： https://pan.baidu.com/s/13n9hxwVj9ai1p5L2rQC83Q

c语言的话，查一下win32的api，或者学一下GTK+？ 会C++的话也可以用QT或者MFC

qt   mfc


Question: 求大佬

用VSCode 吧 codeblock也可以 但是可能有些老了

貌似用VC6.0就可以了


Question: 求助

#include<stdio.h> #include<stdlib.h> extern int action1(char *s); extern int action2(char *s); /* 	输入字符串对比 输出相同字符的个数  	程序有很多问题 	1、字符数组作为函数的参数问题 	2、return关键字的使用问题 	3、函数的返回值类型问题 	4、粗心问题switch 2 函数不存在 */ int main() { 	char a1[6] = { "hello" }; 	char a2[6] = { "world" }; 	int number; 	int samecount; 	printf("请输入1或2\n"); 	scanf("%d", &number); 	switch (number) 	{ 		case 1: 			samecount = action1(a1); 			break; 		case 2: 			samecount = action2(a2); 			break; 	} 	printf("%d\n",samecount); 	system("pause"); 	return 0; } int action1(char *s) { 	char b1[6]; 	int samecount = 0; 	printf("%s\n", s); 	scanf("%s", b1); 	for (int i = 0; i < 6; i++) 	{ 		if (b1[i] == s[i]) 		{ 			samecount++; 		} 	} 	return samecount; } int action2(char *s) { 	char b2[6]; 	int samecount = 0; 	printf("%s\n", s); 	scanf("%s", b2); 	for (int i = 0; i < 6; i++) 	{ 		if (b2[i] == s[i]) 		{ 			samecount++; 		} 	} 	return samecount; }

太感谢了 ，我一定会改正

太感谢了 ，我一定会改正

报错啥，发出来看看


Question: libwebsocket单进程创建多客户端怎么实现

查找资料发现https://github.com/cocos2d/cocos2d-x.git中的websocket模块使用了libwebsocket，需要借鉴其源码修改

没用过。不过感觉libcurl会不会更好用点。

目前的问题是，lws_protocol_vh_priv_zalloc是给per_vhost_data__minimal分配内存的，per_vhost_data__minimal中存放的读写需要的锁和ring，但是看api文档需要在INIT回调中调用的，这个执行一次， 那如果想创建多个client，per_vhost_data__minimal该放在哪里初始化呢？


Question: 求助大佬

希望对你有帮助：https://blog.csdn.net/it_xiangqiang/category_10581430.html 希望对你有帮助：https://blog.csdn.net/it_xiangqiang/category_10768339.html

引用 1 楼 轻箬笠的回复:直接发众包平台吧。 具体怎么操作，可以帮我介绍一下吗？

提供个思路：  1、如果数据要持久化的可以采用mysql数据库（你要用文件存也可以） 2、设计数据结构（都是对数据的操作）商家，买家，管理员 ，订单等 考虑好需要哪些字段 如：订单肯定有订单编号吧。 3、数据访问层（这部分功能主要是对数据的基本访问，如增 删 改 查） 4、业务层 （如注册 登录 下单等） 5、表现层 （数据的展示）

直接发众包平台吧。


Question: dll与宿主交互

引用 4 楼 赵4老师 的回复:WinAPIOverride http://jacquelin.potier.free.fr/winapioverride32/ 不会用这个，有什么其他解决办法吗，因为是要在dllmain里面实现对宿主交互的

引用 1 楼 赵4老师 的回复:仅供参考： HMODULE ldlib = LoadLibraryA("Kernel32.dll");     addr = GetProcAddress(ldlib, "CreateProcessA");     addr2 = GetProcAddress(ldlib, "ExitThread");  你这里是加载dll然后调用dll里面的函数是吧？但是我现在的需求是将dll注入exe里面，然后调用或者给exe里面某个private函数，用GetProcAddress(“某exe”, "private函数A")一直无法获取函数地址，这是一个C#写的exe，目的是将dll注入进去调用或者取代 "private函数A"，这样

仅供参考：/*     Application:    Code Injection in Explorer     Author:     @_RT     Compiled on:    Feb 2014     URL:http://www.codeproject.com/Tips/732044/Code-Injection-2      We will see the different steps involved to perform a code injection into an already running process.      Following are the quick steps through the process of injection.     1.Get the API addresses that you will be calling from the injected code.     2.Prepare shell code of your function that you want to get executed from the injected process.     3.Get the process ID of the running process that you wish to inject into by enumerating through the       list of processes or by finding the process's window (in case it's a GUI application) by class name or title.     4.Open the process using its Pid with All Access rights.     5.Allocate different memory spaces in the process that you are going to inject to with desired access       rights for holding different segments of your shell code.         Code part (executable instructions)         Data part (strings, function parameters, etc.)     6.Write the allocated memories with the respective values (code and data).     7.Call CreateRemoteThread API and pass to it the start of allocated memory address where you have       written your shell code from the process we are injecting. */  #include <windows.h> #pragma comment(lib,"user32.lib")  LPVOID addr; LPVOID addr2;  BOOL InjectExecutable(DWORD dwPid,LPVOID si,LPVOID pi,int sisize,int pisize) {     LPVOID hNewModule;     HANDLE hProcess;     CHAR S[]    = { "C:\\Windows\\system32\\notepad.exe" };     BYTE byt[]  = {0x6A, 0x00, 0x6A, 0x00, 0x6A, 0x00, 0x6A, 0x01, 0x6A, 0x00, 0x6A, 0x00, 0x6A, 0x00, 0x68};                  //push  0   , push     0, push     0, push     1, push     0, push     0, push     0, push 0xXXXXXXXX     BYTE byt2[] = {0xE8};//call 0xXXXXXXXX     BYTE byt3[] = {0x68};//push 0xXXXXXXXX      hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, dwPid);     if (hProcess == NULL)     {         return FALSE;     }      LPVOID staddr = VirtualAllocEx(hProcess, NULL, sizeof(S), MEM_COMMIT, PAGE_READWRITE);     WriteProcessMemory(hProcess, staddr, S, sizeof(S), NULL);     LPVOID fnaddr = VirtualAllocEx(hProcess, NULL, 4, MEM_COMMIT, PAGE_READWRITE);     WriteProcessMemory(hProcess, fnaddr, pi, sisize, NULL);     LPVOID fnaddr2 = VirtualAllocEx(hProcess, NULL, 4, MEM_COMMIT, PAGE_READWRITE);     WriteProcessMemory(hProcess, fnaddr2, si, pisize, NULL);      hNewModule = VirtualAllocEx(hProcess, NULL, 100, MEM_COMMIT, PAGE_EXECUTE_READWRITE);     if (hNewModule == NULL)     {         return FALSE;     }     LPTHREAD_START_ROUTINE strtaddr = (LPTHREAD_START_ROUTINE)hNewModule;      WriteProcessMemory(hProcess, hNewModule, byt3, sizeof(byt3), NULL);     hNewModule = (LPVOID)((int)hNewModule + sizeof(byt3));     WriteProcessMemory(hProcess, hNewModule, &fnaddr, sizeof(fnaddr), NULL);     hNewModule = (LPVOID)((int)hNewModule + sizeof(fnaddr));                    // push &pi ;lpProcessInformation     WriteProcessMemory(hProcess, hNewModule, byt3, sizeof(byt3), NULL);     hNewModule = (LPVOID)((int)hNewModule + sizeof(byt3));     WriteProcessMemory(hProcess, hNewModule, &fnaddr2, sizeof(fnaddr2), NULL);     hNewModule = (LPVOID)((int)hNewModule + sizeof(fnaddr2));                   // push &si ;lpStartupInfo     WriteProcessMemory(hProcess, hNewModule, byt, sizeof(byt), NULL);           // push 0 , push 0, push 0, push 1, push 0, push 0, push 0, push 0xXXXXXXXX==&S[0];"C:\\Windows\\system32\\notepad.exe"     hNewModule = (LPVOID)((int)hNewModule + sizeof(byt));                       // lpCurrentDirectory,lpEnvironment,dwCreationFlags,bInheritHandles,lpThreadAttributes,lpProcessAttributes,lpCommandLine,lpApplicationName     WriteProcessMemory(hProcess, hNewModule, &staddr, sizeof(staddr), NULL);     hNewModule = (LPVOID)((int)hNewModule + sizeof(staddr));     WriteProcessMemory(hProcess, hNewModule, byt2, sizeof(byt2), NULL);     hNewModule = (LPVOID)((int)hNewModule + sizeof(byt2));                      // call CreateProcessA     addr = (LPVOID)((int)addr - ((int)hNewModule + 4));     WriteProcessMemory(hProcess, hNewModule, &addr, sizeof(addr), NULL);     hNewModule = (LPVOID)((int)hNewModule + sizeof(addr));     WriteProcessMemory(hProcess, hNewModule, byt, 2, NULL);     hNewModule = (LPVOID)((int)hNewModule + 2);                                 // push 0 ;DWORD dwExitCode   // exit code for this thread     WriteProcessMemory(hProcess, hNewModule, byt2, sizeof(byt2), NULL);     hNewModule = (LPVOID)((int)hNewModule + sizeof(byt2));                      // call ExitThread     addr2 = (LPVOID)((int)addr2 - ((int)hNewModule + 4));     WriteProcessMemory(hProcess, hNewModule, &addr2, sizeof(addr2), NULL);      CreateRemoteThread(hProcess, 0, 0, strtaddr, NULL, 0, NULL);     return TRUE; }  int main() {     _STARTUPINFOA si;     PROCESS_INFORMATION pi;      ZeroMemory(&si, sizeof(si));     si.cb = sizeof(si);     ZeroMemory(&pi, sizeof(pi));      DWORD dwPid;     HMODULE ldlib = LoadLibraryA("Kernel32.dll");     addr = GetProcAddress(ldlib, "CreateProcessA");     addr2 = GetProcAddress(ldlib, "ExitThread");     HWND hWnd1=FindWindow(NULL, "Program Manager");     if (NULL==hWnd1) {         return 1;     }     GetWindowThreadProcessId(hWnd1, &dwPid);      InjectExecutable(dwPid,&si,&pi,sizeof(si),sizeof(pi));      return 0; }


Question: 在做电影院选座系统时，怎么实现选择的座位与已被选则

可以考虑做标记～已经选择的做上标记，已经做上标记的就不能选择了～

用正则表达式匹配

这个标题加后面的主题才看明白问题。。。。 同一行的话，最土的方法就是轮询呗，座位序号+2，-2（不考虑列）范围内有被选中的就放弃，下一个点继续（可以优化下找下个点的方法）。  再加上边界和列的处理，有点繁琐但不困难。

定义一个位图，加标记，0/1,0表示未选择，1表示选择。内存好像就是这样判断使用和未使用的。

申请个二维数组，每个元素和座位一一对应，对于不存在的座位，标记负数，对于没选的座位，标记0，对于选择的座位，标记1，显示座位的选择情况的时候，就遍历这个数组，根据数组元素的情况，将相应的图标显示在对应的座位上


Question: 初学DirectX12，怎么能够使用颜色的Alpha通道呢

求解~~~~~~~~

这边我看了书上后面的，说是要启用混合技术什么的，然后这是我改了的代码，也不知道对不对，反正还是没用   void BoxApp::BuildPSO() {     D3D12_GRAPHICS_PIPELINE_STATE_DESC psoDesc;     ZeroMemory(&psoDesc, sizeof(D3D12_GRAPHICS_PIPELINE_STATE_DESC));     psoDesc.InputLayout = { mInputLayout.data(), (UINT)mInputLayout.size() };     psoDesc.pRootSignature = mRootSignature.Get();     psoDesc.VS =  	{  		reinterpret_cast<BYTE*>(mvsByteCode->GetBufferPointer()),  		mvsByteCode->GetBufferSize()  	};     psoDesc.PS =  	{  		reinterpret_cast<BYTE*>(mpsByteCode->GetBufferPointer()),  		mpsByteCode->GetBufferSize()  	};     psoDesc.RasterizerState = CD3DX12_RASTERIZER_DESC(D3D12_DEFAULT);     psoDesc.BlendState = CD3DX12_BLEND_DESC(D3D12_DEFAULT);     psoDesc.DepthStencilState = CD3DX12_DEPTH_STENCIL_DESC(D3D12_DEFAULT);     psoDesc.SampleMask = UINT_MAX;     psoDesc.PrimitiveTopologyType = D3D12_PRIMITIVE_TOPOLOGY_TYPE_TRIANGLE;     psoDesc.NumRenderTargets = 1;     psoDesc.RTVFormats[0] = mBackBufferFormat;     psoDesc.SampleDesc.Count = m4xMsaaState ? 4 : 1;     psoDesc.SampleDesc.Quality = m4xMsaaState ? (m4xMsaaQuality - 1) : 0;     psoDesc.DSVFormat = mDepthStencilFormat; //这后面这一段是跟着书后面看到的加的，也不知道对不对 	D3D12_RENDER_TARGET_BLEND_DESC transparentcyBlendDesc; 	transparentcyBlendDesc.BlendEnable = true; 	transparentcyBlendDesc.LogicOpEnable = false; 	transparentcyBlendDesc.SrcBlend = D3D12_BLEND_SRC_ALPHA; 	transparentcyBlendDesc.DestBlend = D3D12_BLEND_INV_SRC_ALPHA; 	transparentcyBlendDesc.BlendOp = D3D12_BLEND_OP_ADD; 	transparentcyBlendDesc.SrcBlendAlpha = D3D12_BLEND_ONE; 	transparentcyBlendDesc.DestBlendAlpha = D3D12_BLEND_ZERO; 	transparentcyBlendDesc.BlendOpAlpha = D3D12_BLEND_OP_ADD; 	transparentcyBlendDesc.LogicOp = D3D12_LOGIC_OP_NOOP; 	transparentcyBlendDesc.RenderTargetWriteMask = D3D12_COLOR_WRITE_ENABLE_ALL;  	psoDesc.BlendState.RenderTarget[0] = transparentcyBlendDesc; //      ThrowIfFailed(md3dDevice->CreateGraphicsPipelineState(&psoDesc, IID_PPV_ARGS(&mPSO)));   还是说，也不是用这个开启混合的，那应该怎么做呢


Question: 求大佬帮帮我

引用 2 楼 Michael_Hzs的回复:我更好奇 你这手机版的编译器哪里来的  可以分享一下吗 大佬 网上搜x语言编译器就有了

我更好奇 你这手机版的编译器哪里来的  可以分享一下吗 大佬

我很好奇，你这个hello world是怎么运行出下面这个结果的？


Question: 大神们帮帮小白吧！

引用 6 楼 自信男孩的回复:[quote=引用 5 楼 Michael_Hzs 的回复:] 可是我用一个for循环的话他会连续打印验证分数啊，怎么样才能让一个循环的输出和三个循环的输出一样呢？求解。刚想了半天了也没相处所以然来。 就不能用嵌套循环，楼上已经给出了代码，可以试一下。[/quote] 懂了，谢谢。感谢你的回答

引用 5 楼 Michael_Hzs 的回复:可是我用一个for循环的话他会连续打印验证分数啊，怎么样才能让一个循环的输出和三个循环的输出一样呢？求解。刚想了半天了也没相处所以然来。 就不能用嵌套循环，楼上已经给出了代码，可以试一下。

引用 3 楼 Michael_Hzs 的回复:您的意思就是这个不用三层循环，而只用一个循环就可以了是吗？一个循环或者三个循环都可以实现，没有差别的是吧？三个单独的循环是没问题的，但是你要是用嵌套循环那就是有问题了

#include <stdio.h>  #define SIZE 10 #define PAR 72  int main(void) {     int index, scores[SIZE];     int sum = 0;     float vaerage;      printf("输入%d个分数：\n ",SIZE); #if 0     for ( index = 0; index < SIZE; index++)     {         scanf_s("%d", &scores[index]);//获取分数         for ( index = 0; index < SIZE; index++)         {             printf("%5d", scores[index]);//验证分数             printf("\n");             for ( index = 0; index < SIZE; index++)             {                 sum += scores[index];//求总分             }         }      } #else     for (index = 0; index < SIZE; index++) {         scanf_s("%d", &scores[index]);//获取分数         printf("%5d", scores[index]);//验证分数         sum += scores[index];//求总分     } #endif     vaerage = (float) sum / SIZE;//平均分     printf("总分是：%d，平均分是：%.2f.", sum, vaerage);     printf("与平均分相差：%.0f", (double)vaerage - PAR);      return 0; }  供参考～  用一层循环就可以了，若用三层循环，注意这是三层循环，不是三个循环（独立的）。 第一层循环会执行SIZE次，第二个循环输出会执行SIZE * SIZE次，  第三个循环sum会计算SIZE *SIZE * SIZE次，并且会有很多随机值。

上面的代码for循环语句缩进不是很清楚吗？  。。。。。。。。。。。。 for ( index = 0; index < SIZE; index++) { scanf_s("%d", &scores[index]);//获取分数  }  for ( index = 0; index < SIZE; index++) { printf("%5d", scores[index]);//验证分数  }  printf("\n"); for ( index = 0; index < SIZE; index++) { sum += scores[index];//求总分 } 。。。。。。。。。。。。


Question: c语言疑惑

就是统计所输入的数据中0——9的个数，下标和输入的数据对应，然后对应的元素自增1.就统计出来 了。

用数组实现的，数组长度为10 (0-9),数组的下标表示你输入的数字，数组的值表示这个数字输入的次数。 比如你输入的是3，那么arr[3]++ 就表示3这个数字输入的次数加1.


Question: both pointer to int *

指针没有隐氏类型转换之说，一个double类型的指针接收int类型的指针，类型不匹配。 注意一个double类型的指针变量，*pd引用的内存是8字节的，*pl引用的内存是4字节的。

二维数组和int **p, 其直接指向的数据不是int，而是指向int的指针。 举个例子，不管初始化啥的啦 int **p; // 二维指针  *p // 指针，对应的是指向整形的指针  **p // 整数  赋值可以是 **p = 1,   如果是 *p = 1, 至少会有个warning,而且结果应该不是你想要的，可以是   int a;  *p = &a;    查不到这个意思吧

int* 指向int类型的指针~

引用 6 楼 user-4 的回复：[quote=引用 5 楼 马振宇 的回复:] [quote=引用 4 楼 user-4 的回复：]int *pt; //一个指向int型变量的指针（内存里面放的是指向某个整型变量的地址）。 int **p2; //一个指向指针的指针，所以p2的值是个地址，该地址存放一个指向int型变量的指针。 *p2 = &pt;// 这里对pt使用取地址符，实际上就是取得pt这个指针所存放的内存的地址，即一个指向指针的指针。所以说两者“ 都是指向int* ”也就是说对指针取址得到的是一个指针？[/quote]  是的[/quote]谢谢

引用 5 楼 马振宇 的回复:[quote=引用 4 楼 user-4 的回复：]int *pt; //一个指向int型变量的指针（内存里面放的是指向某个整型变量的地址）。 int **p2; //一个指向指针的指针，所以p2的值是个地址，该地址存放一个指向int型变量的指针。 *p2 = &pt;// 这里对pt使用取地址符，实际上就是取得pt这个指针所存放的内存的地址，即一个指向指针的指针。所以说两者“ 都是指向int* ”也就是说对指针取址得到的是一个指针？[/quote]  是的

引用 4 楼 user-4 的回复：int *pt; //一个指向int型变量的指针（内存里面放的是指向某个整型变量的地址）。 int **p2; //一个指向指针的指针，所以p2的值是个地址，该地址存放一个指向int型变量的指针。 *p2 = &pt;// 这里对pt使用取地址符，实际上就是取得pt这个指针所存放的内存的地址，即一个指向指针的指针。所以说两者“ 都是指向int* ”也就是说对指针取址得到的是一个指针？


Question: C语言数据抽取

如果用C语言，就是要字符串解析了，比如strlen, strcmp, strtok/strtok_r等等

fgets 函数读取行 字符串查找X-From，X-To（strstr），  找到的就提取后面的字符串  找不到读下一行

可以学一下正则表达式


Question: C语言的题目编程，欢迎高手解答，本人新手，三克油

你不是再找高手，而是再找比较闲的人给你写这些功能。为啥不自己动手写写呢？


Question: 结构体错误，求大佬解答

不会有中文的分号吧，哈哈

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

引用 4 楼 lwc1205 的回复:懂了感谢，我已经知道错在哪了 错在哪里了?

懂了感谢，我已经知道错在哪了

注释掉那个出错的代码，直到不出错为止，然后一步步解除注释，直到出错为止。看看具体哪个代码出错。

引用 1 楼 自信男孩的回复:只有这三个成员有问题吗？ 是的，后面引用这三个的地方就都有问题

只有这三个成员有问题吗？


引用 5 楼 爱吃鱼的橙子 的回复:scanf_s()参数与scanf()不同； 例如scanf(“%s”,&name,n)，整形n为name类型的大小，如果name是数组，那n就是该数组的大小。 不好意思，这里写错了， scanf_s(“%s”,&name,n)，整型n为name类型的大小，如果name是数组，那n就是该数组的大小。 scanf(“%s”,&name)。

可以的，爱你们。 知道scanf_s需要第三个参数但以前不加也没出现问题.....

引用 2 楼 老犯錯誤 的回复:大哥，图上的写法有错误吗？用的是vs呀 是我scanf函数的打开方式不对吗？  scanf_s("%s", name, 40);  试试这样～scanf_s缺少一个参数，即字符串的长度

scanf_s输入字符串需要设置字符串的长度，如果不太会的话，还是用scanf，提示不安全需要关闭SDL检查（百度）

大哥，图上的写法有错误吗？用的是vs呀 是我scanf函数的打开方式不对吗？

#include <stdio.h> int main(void) {     int a,b,c;     printf("Give me the value of a,b,c seperated with whitespaces:\n");     scanf("%d%d%d",&a,&b,&c);     printf("a=%d,b=%d,c=%d\n",a,b,c);     return 0; }


Question: 一个简单c语言指针的传值问题

我也明白了一点

引用 1 楼 六道佩恩 的回复：f里的变量i是局部变量，f函数结束后即释放，建议加static再测试正确

引用 4 楼 flamesP 的回复:感谢老铁的解答，确实是这个原因。 另外还有个问题 我想请教下，就是要想知道像你说的栈地址以及printf函数压栈这些是不是得在数据结构中学习。  堆栈相关的操作和系统有关，不是数据结构里面学的。

引用 4 楼 flamesP 的回复:感谢老铁的解答，确实是这个原因。 另外还有个问题 我想请教下，就是要想知道像你说的栈地址以及printf函数压栈这些是不是得在数据结构中学习。 恩，会学到，栈/堆是都是内存，只是运用的不一样

在这句： *i=*p; printf("%d\n",*i); 之后，你再打印下*p，看是不是变了 *p 再你的f()里面返回的是个栈地址，里面的数据是随时可能被覆盖的，出现什么结果都有可能。 printf函数的压栈动作很大机会把原来的内容覆盖掉，你第一次打印前赋值，看两个地址的打印是不是就一样了。

但是这不影响主函数中的指针i

f里的变量i是局部变量，f函数结束后即释放，建议加static再测试


Question: C语言字符串数组长度统计的问题

引用 9 楼 爱吃鱼的橙子 的回复:可以规定输入的char[]不能连续两个为0，否则认为后续全为0，然后添加判断条件，非0和0的下一个非0，统计+1，这样的。 感觉何必这么为难自己，哈哈我也不想难为自己。。。但是对称加密里面，前置IV是可以设置为 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x02, 0x30, 0x40, 0x50, 0x00, 0x00 }的。。。

引用 10 楼 自信男孩 的回复:[quote=引用 2 楼 rk4k94 的回复:] [quote=引用 1 楼 自信男孩 的回复:] 这个可以自己试一下，如果按照字符串的接口strlen，那么这个长度应该是2。0x00就是0，'\0'就是0。 如果用sizeof，那么长度应该是10.是的，我之前都试了，但是我想打印出来的是5，所以咋整。。。求教了。。。。[/quote] 把你的代码贴出来吧，不知道你怎么实现的输出是5[/quote]我是想让他输出5，但实际上确实是strlen是2，sizeof是10。。所以才想求教有没有好方法。。问题背景是我要做一个C/C++的对称加密程序，由于可以让用户自行设置前置IV和秘钥引起的，比如我的一个前置IV就可以设置为 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x65, 0x66, 0x67, 0x68, 0x00, 0x00 }，长度虽然是固定16，但需要监测里面是否真的存放了16个字节。。。

没有现成的方法，只能自己按某种规律遍历计算或者统计

表示看不懂！看回复学习学习

引用 2 楼 rk4k94 的回复:[quote=引用 1 楼 自信男孩 的回复:] 这个可以自己试一下，如果按照字符串的接口strlen，那么这个长度应该是2。0x00就是0，'\0'就是0。 如果用sizeof，那么长度应该是10.是的，我之前都试了，但是我想打印出来的是5，所以咋整。。。求教了。。。。[/quote] 把你的代码贴出来吧，不知道你怎么实现的输出是5

引用 2 楼 rk4k94 的回复:[quote=引用 1 楼 自信男孩 的回复:] 这个可以自己试一下，如果按照字符串的接口strlen，那么这个长度应该是2。0x00就是0，'\0'就是0。 如果用sizeof，那么长度应该是10.是的，我之前都试了，但是我想打印出来的是5，所以咋整。。。求教了。。。。[/quote] 5的标准是什么？这个非常重要！ 你可能想的是我保存了5个进去，所以是5。但是电脑不会知道这个。所以就是两个方法： 1、自己做下计数；2、用特殊字符标记结束

引用 5 楼 英雄@末路 的回复:后面没有附初值的元素可不一定是0哦，所以还是仔细想想吧 可以测试一下，一定是0。 所以这样赋值，就是把所有的数组元素都赋值为0.  int array[10] = {0};

引用 5 楼 英雄@末路 的回复:后面没有附初值的元素可不一定是0哦，所以还是仔细想想吧一定是0 还是仔细想想吧

后面没有附初值的元素可不一定是0哦，所以还是仔细想想吧

说白了，你就是想忽略掉末尾全部的0，从有数据开始到最前面都算数是吧？这好办，你写个相关函数，从末尾遍历到头，遇到非0就跳出，返回遇到的下标+1，比如你发是这个例子，会在下标4跳出，那么返回4+1，就是它的长度

引用 2 楼 rk4k94 的回复:[quote=引用 1 楼 自信男孩 的回复:] 这个可以自己试一下，如果按照字符串的接口strlen，那么这个长度应该是2。0x00就是0，'\0'就是0。 如果用sizeof，那么长度应该是10.是的，我之前都试了，但是我想打印出来的是5，所以咋整。。。求教了。。。。[/quote]自己定义一个变量记录你使用了数组多少个元素 没有现成的做法

引用 1 楼 自信男孩 的回复:这个可以自己试一下，如果按照字符串的接口strlen，那么这个长度应该是2。0x00就是0，'\0'就是0。 如果用sizeof，那么长度应该是10.是的，我之前都试了，但是我想打印出来的是5，所以咋整。。。求教了。。。。


Question: 创建控制台后，无法输出到控制台是怎么回事？

当然，恰恰相反，我比你老师牛多了！

引用 8 楼 Intel0011 的回复:FreeConsole(); 相当于将输入输出流与"显示屏"脱离了，输入输出流虽然有数据显示，但却无"显示屏"，当然显示不了 AllocConsole();相当于创建了一个"显示屏"，但却无数据流与之相连，故无法显示 只有将输入输出流与"显示屏"相连才能正常显示，重定向相当于将两者相连 至于IDE上编译运行的时候没有这问题，我猜是IDE帮你做连接工作 我对界面不是很熟悉，有很多问题也没弄清楚，没时间折腾，你折腾清楚了记得告诉我 回答你的问题可不容易，但你的问题还是很有质量的，一般人问不了，估计你老师也很难回答你 当然我比你老师菜多了 大佬您可别这么说，你是很厉害的，至少是我觉得来CSDN以来遇到的最给力的朋友了，每次都简洁明了直指核心，可谓一针见血，让我豁然开朗，一直以来都非常感谢您的帮助。我没有老师，是在自学瞎琢磨，感谢有你！

你忘了一件事--输出重定向 小改了一下你的程序，可以看到输出  #include <windows.h> #include <stdio.h>  #pragma comment(lib, "user32") #pragma comment(lib, "gdi32")  LRESULT WINAPI MyProc(HWND h , UINT msg , WPARAM wParam , LPARAM lParam) {    static int i = 0;     switch (msg)    {    case WM_TIMER:                    //每隔1秒尝试向控制台输出       //MessageBox(h , "A" , "B", 0);        printf("%d ", ++i);       return 0;     /*    case WM_MBUTTONDOWN:       {          HWND h = GetConsoleWindow();          if(h == NULL)             MessageBox(h , "A" , "A", 0);           else             MessageBox(h , "B" , "B", 0);           return 0;       }    //*/        case WM_LBUTTONDOWN:            //单击左键新建控制台        AllocConsole();       freopen("CONIN$",  "r+t", stdin);  // 重定向输入       freopen("CONOUT$", "w+t", stdout); // 重定向输出       freopen("CONOUT$", "w+t", stderr); // 重定向错误输出       SetTimer(h, 1, 1000, NULL);       i = 0;       //AttachConsole(GetCurrentProcessId);       //printf("ABCDE");       return 0;     case WM_RBUTTONDOWN:            //单击右键脱离控制台        fclose(stderr);          fclose(stdout);          fclose(stdin);       KillTimer(h, 1);       FreeConsole();        return 0;     case WM_DESTROY:            PostQuitMessage(0);       return 0;    }    return DefWindowProc(h , msg , wParam , lParam); }  void SetWNDCLASS(WNDCLASS *a, WNDPROC proc, LPCTSTR ClassName) {    a->style         = CS_HREDRAW | CS_VREDRAW;            a->lpfnWndProc   = proc;                                a->cbClsExtra    = 0;            a->cbWndExtra    = 0;        a->hInstance     = GetModuleHandle(NULL);    a->hIcon         = NULL;                a->hCursor       = NULL;    a->hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);        a->lpszMenuName  = NULL;        a->lpszClassName = ClassName;     }   ATOM RegMyClass(const char *name , WNDPROC proc) {    WNDCLASS MyClass;    SetWNDCLASS(&MyClass, proc, name);        return RegisterClass(&MyClass); }  int main(void) {    FreeConsole();                        //在一开始就去掉控制台     RegMyClass("MYCLASS", MyProc);    CreateWindow("MYCLASS", "控制台测试", WS_OVERLAPPEDWINDOW | WS_VISIBLE, 400, 400, 300, 300, NULL, NULL, NULL, NULL);    MSG msg;    while (GetMessage(&msg, NULL, 0, 0))     {       DispatchMessage(&msg);    }    return 0; }

你创建的窗口，句柄都不要了么？

引用 7 楼 六道佩恩 的回复:请问为什么需要这个重定向，但IDE上编译运行的时候没有这问题的呀 FreeConsole(); 相当于将输入输出流与"显示屏"脱离了，输入输出流虽然有数据显示，但却无"显示屏"，当然显示不了 AllocConsole();相当于创建了一个"显示屏"，但却无数据流与之相连，故无法显示 只有将输入输出流与"显示屏"相连才能正常显示，重定向相当于将两者相连 至于IDE上编译运行的时候没有这问题，我猜是IDE帮你做连接工作 我对界面不是很熟悉，有很多问题也没弄清楚，没时间折腾，你折腾清楚了记得告诉我 回答你的问题可不容易，但你的问题还是很有质量的，一般人问不了，估计你老师也很难回答你 当然我比你老师菜多了

引用 3 楼 Intel0011 的回复:你忘了一件事--输出重定向 小改了一下你的程序，可以看到输出 请问为什么需要这个重定向，但IDE上编译运行的时候没有这问题的呀

引用 1 楼 英雄@末路 的回复:你创建的窗口，句柄都不要了么？ 对，不需要，用不着

引用 2 楼 英雄@末路 的回复:没看你定义的实现，但是CreateWindow 创建完返回的句柄，然后传递给GetMessage 作为参数应该是最基本的操作，否则你message从NULL里面能获取到啥？ NULL可以让GetMessage获取当前线程创建的所有窗口的消息

console屏幕处理例子程序。终端窗口屏幕处理相关API使用例子。来自MSVC20\SAMPLES\win32\console\ http://download.csdn.net/detail/zhao4zhong1/3461309


Question: 为什么理论值是64没有懂？？

内存对齐。地址从0开始 num 占 4个字节  地址扩充到4 name[20]占20个字节，地址扩充到24 sex占1个字节地址扩充到25 age占4个字节，25不是4的倍数，先扩充到28再加4个字节扩充到32 float占4个字节，地址扩充到36 addr[30] 占30个字节 扩充到66 整个结构对齐到4的整数倍 扩充到68。 结果应该是68； 我写程序验证了一下，确实是68.

为什么我觉得理论上是68呢？自动优化了？ 把sex和 addr放一起才是64把？

看着费劲，没仔细看


Question: 怎么制作五颜六色闪烁的文字？

#include <windows.h> #include <stdio.h>  int Color[] = { FOREGROUND_GREEN, FOREGROUND_BLUE, FOREGROUND_RED, FOREGROUND_RED | FOREGROUND_BLUE, FOREGROUND_RED | FOREGROUND_GREEN, FOREGROUND_BLUE | FOREGROUND_GREEN, FOREGROUND_RED | FOREGROUND_BLUE | FOREGROUND_GREEN };  int main(void) {    CONSOLE_SCREEN_BUFFER_INFO csbiInfo;    char str[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";    size_t i, len = sizeof(str) / sizeof(str[0]);     HANDLE hConsole = GetStdHandle(STD_OUTPUT_HANDLE);     srand(time(NULL));    GetConsoleScreenBufferInfo(hConsole, &csbiInfo);    for (i = 0; i < len; ++i)    {       SetConsoleTextAttribute(hConsole, Color[i % 7] | FOREGROUND_INTENSITY);       printf("%c", str[i]);       Sleep(300);    }    SetConsoleTextAttribute(hConsole, csbiInfo.wAttributes);    printf("\n");    return 0; }

用循环加上Sleep。如果是Windows程序可以用定时器。

引用 4 楼 狂风乱吼 的回复:[quote=引用 3 楼 六道佩恩 的回复:]  #include "stdio.h" #include "windows.h" int main( void ) { 	HANDLE out= GetStdHandle(STD_OUTPUT_HANDLE);    	DWORD num= 0; 	WORD  attr= 0xf0, x=0; 	int  i= 0,  len= printf("ABCDEFGHIJKLMNOPQRSTUVWXYZ\n"); 	while(1) 	{	 		for( i=0 ; i<len ; i++ )				 		{ 			attr = 0xf0 + (x++ & 0xf);		 			FillConsoleOutputAttribute (out , attr , 1 , (COORD){i,0} , &num); 		} 		Sleep(100);						 	} 	return 0; }  大神的代码看不懂呀[/quote] 你先运行看看是不是你要的效果，是的话就逐个查阅其中的函数

引用 3 楼 六道佩恩 的回复: #include "stdio.h" #include "windows.h" int main( void ) { 	HANDLE out= GetStdHandle(STD_OUTPUT_HANDLE);    	DWORD num= 0; 	WORD  attr= 0xf0, x=0; 	int  i= 0,  len= printf("ABCDEFGHIJKLMNOPQRSTUVWXYZ\n"); 	while(1) 	{	 		for( i=0 ; i<len ; i++ )				 		{ 			attr = 0xf0 + (x++ & 0xf);		 			FillConsoleOutputAttribute (out , attr , 1 , (COORD){i,0} , &num); 		} 		Sleep(100);						 	} 	return 0; }  大神的代码看不懂呀

引用 1 楼 ooolinux 的回复:不断用不同颜色重画上去。

不断用不同颜色重画上去。


Question: 窗口最小化后复原却无法响应是怎么回事？

MSDN98_1.ISO http://pan.baidu.com/s/1dDF41ix,  MSDN98_2.ISO http://pan.baidu.com/s/1bnGo0Vl

引用 3 楼 六道佩恩 的回复:[quote=引用 1 楼 赵4老师 的回复:] https://bbs.csdn.net/topics/390374955  您这个帖子我以前看过，如果您知道原因的话，还请透露一点，这么大范围你只让我读官方例子，无异于大海捞针[/quote] 请使用 grep https://download.csdn.net/download/zhao4zhong1/4381913 或 findstr 命令大海捞针。

引用 1 楼 赵4老师 的回复:https://bbs.csdn.net/topics/390374955  您这个帖子我以前看过，如果您知道原因的话，还请透露一点，这么大范围你只让我读官方例子，无异于大海捞针


Question: 找不到标识符

第一行写  #include "stdio.h"

头文件在哪呢？需要包含标准库的头文件

没有包含相关头文件吧


Question: 关于bit操作的问题（数据压缩）

一般使用硬件解决，线路传输方案中有专用的系统解决方案。

引用 13 楼 lin5161678 的回复:[quote=引用 12 楼 早打大打打核战争 的回复:] 实际上楼主这个压缩没有多少意义，不如把数据用zlib之类的压缩再传输 同意  我也是这样想的 昨天 楼主C语言贴吧也发过同一个问题的帖子 当时我就对他说 现成的压缩算法挑一个 [/quote]  我其实是用过数据压缩算法，一次压缩后才产生了这个14bit的东东。看了下大家的回复，也没什么好的方法，最后写的代码也只能是移位加填充这么搞定了。

引用 7 楼 幻夢之葉 的回复:[quote=引用 6 楼 幻夢之葉 的回复:] 位移+位或就处理完了啊 short src[4] unsigned long long dst = 0; dst |= ((unsigned long long)src[0] << 0); dst |= ((unsigned long long)src[1] << 14); dst |= ((unsigned long long)src[2] << 28); dst |= ((unsigned long long)src[3] << 42);  其中dst有一个字节的内容可能是随变的，是否要处理掉看你实际流程 上面的有问题，应该是这样子才对，并且忽略红色标注那句话 short src[4] unsigned long long dst = 0; dst |= ((unsigned long long)src[0] & 3FFF) << 0; dst |= ((unsigned long long)src[1] & 3FFF)<< 14); dst |= ((unsigned long long)src[2] & 3FFF)<< 28); dst |= ((unsigned long long)src[3] & 3FFF) << 42); [/quote]对了 补充一下 因为第二个unsigned long long 先填充了6bit 所以不能在使用 0 14 28 42... 作为位移操作数 应该是6 20 34 48 .....  现在还觉得直接位移够用吗?

引用 7 楼 幻夢之葉 的回复:[quote=引用 6 楼 幻夢之葉 的回复:] 位移+位或就处理完了啊 short src[4] unsigned long long dst = 0; dst |= ((unsigned long long)src[0] << 0); dst |= ((unsigned long long)src[1] << 14); dst |= ((unsigned long long)src[2] << 28); dst |= ((unsigned long long)src[3] << 42);  其中dst有一个字节的内容可能是随变的，是否要处理掉看你实际流程 上面的有问题，应该是这样子才对，并且忽略红色标注那句话 short src[4] unsigned long long dst = 0; dst |= ((unsigned long long)src[0] & 3FFF) << 0; dst |= ((unsigned long long)src[1] & 3FFF)<< 14); dst |= ((unsigned long long)src[2] & 3FFF)<< 28); dst |= ((unsigned long long)src[3] & 3FFF) << 42); [/quote]你的做法还没有涉及到最麻烦的地方  unsigned long long 64bit每次填充14bit 那么最后是有8bit 不够直接填充 需要把14bit拆成8+6 8bit填充这个unsigned long long 6bit填充下一个unsigned long long 而第二个unsigned long long先填充了6bit  那么最后会有2bit 不够直接填充 依次类推  这才是最麻烦的

引用 12 楼 早打大打打核战争 的回复:实际上楼主这个压缩没有多少意义，不如把数据用zlib之类的压缩再传输 同意  我也是这样想的 昨天 楼主C语言贴吧也发过同一个问题的帖子 当时我就对他说 现成的压缩算法挑一个

实际上楼主这个压缩没有多少意义，不如把数据用zlib之类的压缩再传输

引用 10 楼 早打大打打核战争 的回复:这个不是问题，他可以只使用56位，不必填满64位，每次存7字节有效数据即可，麻烦的是处理零头，每次写8字节（写的地址按7字节步进）最后一次可能越界，需要分配的缓冲区大一些才行。unsigned long long 做中转 存7字节有效数据之后 再用&操作写到目标缓冲区 这样的确方便很多  那么就只剩下2个问题了 一个是你所说的零头  另一个是必须有至少64bit并且支持位操作的类型   备注: 不能用memcpy一次性操作7字节

引用 6 楼 幻夢之葉 的回复:位移+位或就处理完了啊 short src[4] unsigned long long dst = 0; dst |= ((unsigned long long)src[0] << 0); dst |= ((unsigned long long)src[1] << 14); dst |= ((unsigned long long)src[2] << 28); dst |= ((unsigned long long)src[3] << 42);  其中dst有一个字节的内容可能是随变的，是否要处理掉看你实际流程 上面的有问题，应该是这样子才对，并且忽略红色标注那句话 short src[4] unsigned long long dst = 0; dst |= ((unsigned long long)src[0] & 3FFF) << 0; dst |= ((unsigned long long)src[1] & 3FFF)<< 14); dst |= ((unsigned long long)src[2] & 3FFF)<< 28); dst |= ((unsigned long long)src[3] & 3FFF) << 42);

引用 4 楼 lin5161678 的回复:[quote=引用 3 楼 幻夢之葉 的回复:] 7个字节装下4个数据 那么用一个8字节的类型的整数，比如long long 按顺序移位+位或即可，每次填装四个数据  第二次和后续，先转char*指针，取7的倍数偏移，再转成long long*类型，填装下一组的四个数据  如果不是c11标准不支持long long，可以用个系统或者API提供的其他64位整形类型替代你理解错了  是2个字节里面2bit不用 直接移位是不行的[/quote] 位移+位或就处理完了啊 short src[4] unsigned long long dst = 0; dst |= ((unsigned long long)src[0] << 0); dst |= ((unsigned long long)src[1] << 14); dst |= ((unsigned long long)src[2] << 28); dst |= ((unsigned long long)src[3] << 42);  其中dst有一个字节的内容可能是随变的，是否要处理掉看你实际流程

用unsigned char 传输，取8 bit 和14 bit的最小公倍数（56），移位来填满每个字节。 只在乎带宽而不在乎CPU的或者凑字节用并行硬件执行的可以考虑，否则性价比太低。

引用 3 楼 幻夢之葉 的回复:7个字节装下4个数据 那么用一个8字节的类型的整数，比如long long 按顺序移位+位或即可，每次填装四个数据  第二次和后续，先转char*指针，取7的倍数偏移，再转成long long*类型，填装下一组的四个数据  如果不是c11标准不支持long long，可以用个系统或者API提供的其他64位整形类型替代你理解错了  是2个字节里面2bit不用 直接移位是不行的

低效的代码也行

没有


Question: bit操作求助

看错了，bit的话麻烦一点，不过还是有规律可循的 int main() {     short src[] = {0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF};     short dest[10]; 	short src_bit[] = {0x3FFF, 0x3FFC, 0x3FF0, 0x3FC0, 0x3F00, 0x3C00, 0x3000}; 	short dest_bit[] = {0x3, 0xF, 0x3F, 0xFF, 0x3FF, 0xFFF, 0x3FFF}; 	int len = sizeof(src) / sizeof(short); 	int index = 0; 	int i = 0; 	int temp; 	while(i < len) 	{ 		temp = i % 7; 		dest[index++] = ((src[i] & src_bit[temp]) >> (temp * 2))  + ((src[i + 1] & dest_bit[temp]) << (14 - temp * 2)); 	    i++; 	} 	 	for (i = 0; i < index; i++) 	{ 	    printf("0x%X\n", dest[i]); 	} }

引用 9 楼 636f6c696e 的回复:memcpy(dest, src, 14)； dest+=14; src+=16;是bit为单位 不是字节

你写两个函数，一个函数遍历原数组，每次返回一个位上的1或0，用static变量记录输出的比特位的位置。 然后不断循环调用这个函数，将获得的0或1每8个排满一个字节（新数组）。

不是为了节约时间，目前问题是带宽受限，处理能力足够

如果不是奇缺这点传输性能和带宽，真不建议这么做。 因为想要实现你的方案，必然要实现一个bitstream，这个对象最起码要封装实现读写操作，并且还需要做不少的异常处理，你在传输中节约的时间，会在这里消耗掉。 一定要实现的话可以这样: short数组中每连续的7个元素读取完毕后，将获取的7个元素通过移位操作再合成第八个

数据是传输用的，节约八分之一带宽是什么概念懂吗

引用 3 楼 Oberon_H 的回复:我的数据是用于传输的，目的是节约传输的字节数放弃这种毫无价值的想法

我的数据是用于传输的，目的是节约传输的字节数

性价比太低

没有  并且这个思路极其低效


Question: c语言题 求助

引用 4 楼 Lighthouses的回复:[quote=引用 3 楼 Lighthouses的回复:][quote=引用 2 楼 Lighthouses的回复:]读两个字符串，用char类型数组，用两个伪在两个指针数组上进行有顺序的遍历查找，统计出结果 打漏了，是  伪指针[/quote] 貌似是  动态规划的题目[/quote] 可以写出代码 看看吗 拜托大佬

引用 10 楼 早打大打打核战争 的回复:x当前一轮扫描中两个字符串的匹配数量 y历史最大匹配数量 因为字符串长度为n，如果y已经达到n，就没必要继续扫描了好的谢谢

引用 7 楼 早打大打打核战争 的回复:简单一点：  #include <stdio.h> #include <string.h>  int main() {   int n, i, j, x, y = 0;   char a[4096], b[2048];    scanf("%d\n", &n);   gets_s(a, 2048);   gets_s(b, 2048);   memcpy(&a[strlen(a)], a, n);   for (i = 0; x = 0, i < n; i++, x > y ? y = x : 0, y == n ? i = n : 0)     for (j = 0; j < n; j++) if (a[i + j] == b[j]) x++;   printf("%d\n", y);    return 0; }  x > y ? y = x : 0, y == n ? i = n : 0) 求解答主 带问号这段是什么意思 谢谢

引用 6 楼 Lighthouses 的回复:我是一名蒟蒻 我什么都不知道  自认为一套玄学解法 把两个字符串在最后复制一份，构成一个环 然后就是 动态规划 求最长连续字串的题目  #include <cstdio> #include <iostream> #include  <string> #include <algorithm> #define maxn 100000 using namespace std;  string str1, str2; int dp[1000][1000]; int length; int res; char ch;  int main() { 	scanf("%d", &length); 	cin >> str1; 	cin >> str2;          //关键     str1 += str1;     str2 += str2;     length = length * 2 - 1;     //动态规划 	for (int i = 0; i < length; ++i) 	{ 		for (int k = 0; k < length; ++k) 		{ 			if (str1[i] == str2[k]) 			{ 				if (i > 0  && k > 0) 					dp[i][k] = dp[i - 1][k - 1] + 1; 				else 					dp[i][k] = 1; 				 				res = max(dp[i][k], res); 			} 		} 	}  	printf("%d\n", res);  	return 0; }  谢谢答主 不过我试了一下 比如abeak 3次变eakab        bkace  1次变ebkac 应该有三个对应相同的 1.3.4位 可是代码运行显示为2 能不能帮着看看 万分感谢

引用 3 楼 Lighthouses的回复:[quote=引用 2 楼 Lighthouses的回复:]读两个字符串，用char类型数组，用两个伪在两个指针数组上进行有顺序的遍历查找，统计出结果 打漏了，是  伪指针[/quote] 貌似是  动态规划的题目

引用 2 楼 Lighthouses的回复:读两个字符串，用char类型数组，用两个伪在两个指针数组上进行有顺序的遍历查找，统计出结果 打漏了，是  伪指针

跪求 谢谢！！


Question: 使用keil编译程序出现11.c(6): error C202: 'bl': undefined identifier怎么解决

bl没有声明就使用了，加个声明


Question: c程序设计（第五版）谭浩强例题7.12

上面那位老师的方法试了，程序执行完成后没有进行排序，还是按照输入数字的顺序输出的结果。现在这个图是我一步一步调试的，还是不明白：当判断条件为假时不是应该不走if中的语句吗，虽说并没有被赋于新值，但总与自己学过的知识对不上。还请各位老师看在通宵到现在的份上，发下慈悲，给解解惑

t = array[k]和后面的两句放到这个判断语句里：  if (k != i) {     t = array[k];     array[k] = array[i];     array[i] = t; }

没有仔细看。给个建议：循环体、if语句的子句，语法上都是一条语句，如果不是，则应用{}进行组合。


Question: 求助贴

可以判断奇数和偶数来输出不同的符号

哪种？能说清楚吗？不明白你在说什么


Question: 求助

引用 1 楼 自信男孩的回复:楼主是什么意思？是修改程序实现输入是负值是不执行换行符？ 应该是你说的意思，但还是不懂怎么弄

引用 1 楼 自信男孩的回复:楼主是什么意思？是修改程序实现输入是负值是不执行换行符？ 上面那个程序就是4-5，我截图不到

我就是不懂，它叫我把上面的程序改为输入负数后不执行换行操作，应该是你说的意思。

楼主是什么意思？是修改程序实现输入是负值是不执行换行符？


Question: C语言

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

举一个你计算的例子，并把你的代码贴一下。

帖下你的数据和输出内容

引用 4 楼 qq_45541848 的回复:float num_a=198903.19f 2进制无法精确表示这个十进制，在内存中其实是保存为了010001111100001000111101110001100 转换为十进制是198903.1875 但是在输出时变为了198903.2 这是精度问题

那串二进制数输错了，不好意思


Question: 书上的知识在实践中遇到了问题。exe不是可执行程序吗？

你是win系统小白哦。你控制台里的路径是c:\windows\system32 下面当然没有你这个程序echo_eof.exe  学会cd d:\

D: cd "visual studio\程序设计\echo_eof\x64\Release"

D: cd "visual studio\程序设计\echo_eof\x64"


Question: Error in cor(data) : 'x'必需为数值

因为某个列的值不是numeric，因此需要把所有数值变成numeric才行，可以重新构建data.frame

data <- read.csv("mtcars.csv",header = TRUE,row.names = 1)就可以了

找了两个多小时，终于找到可以解决的办法了 感谢~

可能是数据的原因

引用 4 楼 user-6 的回复:这是erlang？ 没接触过erlang，这里是c/c++，似乎楼主应该移步。 推测一下 data 可能是字符串变量， cor_matr = cor(data)//这里可能要求是数值，请把data转为数值。 不同erlang,瞎说莫怪。

这是erlang？

你的代码不是c/c++吧？

引用 1 楼 user-6 的回复:不明所以，你这个有完整代码吗？ data = read.csv("mtcars.csv",header = TRUE) head(mtcars) matcar.cor <- cor(mtcars) matcar.cor 用这个代码就不会提示那个错误； data = read.csv("mtcars.csv",header = TRUE) head(mtcars) cor_matr = cor(data) cor_matr 用这个代码就会提示错误

不明所以，你这个有完整代码吗？


Question: C语言求解

如果实在visual 6.0的环境下， scanf的作用是通过键盘，向内存中输入一些内容，用法如下  scanf("%d",&number)  //输入一个整数 scanf("%c",&character)  //输入一个整数 //特别注意要加&，这是个取地址符，就好比你要给一个房间放一本书，必须先打开门，而&就是一把钥匙 char                            //这是一个关键字，用来定义字符型变量，比如上面的character就可以用这个定义 char character            //而这也是char的四个字母的来源 puts("%s",str)            //输出某个字符串  修德兼修身，万物与我共存，天地与我为一


Question: 纯c语言 MessageBoxTimeout 问题？？

加上#pragma也是不行的，gcc不认啊！

3楼正解，MessageBoxTimeoutA和MessageBoxTimeoutW是在user32中导出的  #include <windows.h>  int WINAPI MessageBoxTimeoutA(IN HWND hWnd, IN LPCSTR lpText, IN LPCSTR lpCaption, IN UINT uType, IN WORD wLanguageId, IN DWORD dwMilliseconds); int WINAPI MessageBoxTimeoutW(IN HWND hWnd, IN LPCWSTR lpText, IN LPCWSTR lpCaption, IN UINT uType, IN WORD wLanguageId, IN DWORD dwMilliseconds);  #ifdef UNICODE #define MessageBoxTimeout MessageBoxTimeoutW #else #define MessageBoxTimeout MessageBoxTimeoutA #endif    #pragma comment(lib, "user32")  int main(void) {    MessageBoxTimeout(0,"ttttt","111111",0,0,2000);    return 0; }

#include <windows.h>  #pragma comment(lib, "user32.lib")

VB6 里   Private Declare Function MessageBoxTimeout Lib "user32" Alias "MessageBoxTimeoutA" (ByVal hwnd As Long, ByVal lpText As String, ByVal lpCaption As String, ByVal wType As Long, ByVal wlange As Long, ByVal dwTimeout As Long) As Long  这个没问题！！！！！

是缺什么连接库吗？ 我用下面编译也是这种错误？？  gcc 1111.c -luser32 -o 1111.exe


Question: 刚学习C语言，请教一个嵌套语句出现的问题

你可以使用一些更加集成化的开发工具，比如说，visual stdio 2017，可以在网上找到下载

编译器的问题

不同的编译器对缩进的处理不同

C语言是不管缩进的，缩进只是人看着比较舒服，编译器自己有语法分析，不管缩进 你自己可以手动缩进或使用编辑器提供的格式化功能自动缩进美化一下

这和语言有啥关系，这是编译器，IDE的事


Question: switch不知道可不可以这样用，一个人搞不定了。格式什么的实在搞不定了,TAB键粘到这里来，没效果

很简单的计算被你写成那样 :)  #include<stdio.h>  //typedef enum {SINGLE, HOUSE, M_S, M_D} tax_bracket; float tax_brackets[] = {17850, 23900, 29750, 14875}; float tax_rate[] = {0.15, 0.28};  int main() {   char c;   float n;    while (1)   {     for (; printf("how much you earned?(q to quit)\n"), scanf_s("%f", &n, 13) != 1;)       while ((c = getchar()) != 10) if (c == 'q' || c == 'Q') return 0;     for (; printf("Enter a character:((A)for single person (B)for house owner. (C)for married. (D)for divorce.)\n"),            scanf_s("\n%c", &(c = 0), 13), !((c >= 'A' && c <= 'D') || (c >= 'a' && c <= 'd')););     c < 'E' ? c -= 65 : c -= 97;     printf("the tax is %f\n",        n > tax_brackets[c] ? tax_brackets[c] * tax_rate[0] + (n - tax_brackets[c]) * tax_rate[1] :       n * tax_rate[0]);   }    return 0; }

1 scanf_s("%c", &en, 5);用scanf_s输入字符的时候，后面加个数字，大小看心情，随意； 2 如果你搞不定的其中一个原因是老是输出how much you earned?(q to quit)这句话，那就看看你的while（1），删了吧，凡在这含义是什么，没看懂； 3 scanf_s用来直接输入数据，你把他用在赋值上，通过输入n，赋值给了k，我没跑通，把k=删了，可以跑；

题目： 1988年的美国联邦税收计划是近代最简单的税收方案 以下：  类别                                           |    税金 单身                                                 17850美元按%15计，超出部分按%28计算 户主                                                 23900美元按%15计，超出部分按%28计算 已婚，共有                                       29750美元按%15计，超出部分按%28计算 已婚，离异                                       14875美元按%15计，超出部分按%28计算


Question: 萌新求助

引用 1 楼 SuperDay的回复:double应该是8字节的，float是4字节，执行scanf之后，double只被填充了4个字节，剩余4个字节是不确定的 哦哦，该用lf是吧，谢谢大哥

引用 3 楼 自信男孩的回复:用%lf格式输入。如果用%f输入，那么是按照float的格式输入的。 大哥，我还有一个其他的问题

用%lf格式输入。如果用%f输入，那么是按照float的格式输入的。


Question: c语言编译错误

看下change定义那里第二个参数n，没指明类型。

子函数中引入 n 时没写int

引用 1 楼 轻箬笠 的回复:把函数声明放到最前面看看。c语言的声明需要放在最前面，不像C++一样，只要用到之前声明下就可以了+1

1楼正解  int main(void) {    void change(int x[], int n); //放在最前面    .... }


Question: C

大端序小端序问题，内存的基本单位是字节（8个bit），一个字节最多能表示2^8个数（0-255）；32位系统c语言中int类型占4个字节，每个字节内存单元都有自己的地址编号，比如这个4个字节的地址编号是 0x56,0x57,0x58,0x59。现在有一个数是1023（二进制：11111111 11，十六进制：0x00 00 03 ff），大端序： 0x56,0x57存00，03存到0x58中，ff存到0x59中 （高字节存于内存低地址）。小端序就反过来。

低位高字节，这是对大小端系统来讲的吧。 比如unsigned int x = 0x12345678;在内存中存放，0x12是高字节，0x78是低字节，低位（位是指位置）是指内存的低地址，内存有 高地址和地地址之分，比如0x7ffd491d1270 , 0x7ffd491d1264。地址值大的就是高地址。 低位高字节，就是低地址存放0x12，在高地址存放0x78；


Question: PAT1088 三人行测试点3不通过，跪求大佬指点！SOS

//p1个位可以为0，p2可以是一位数，即j == 0; p1确定是两位数，即i >= 1; for (j = 1; j <= 9; j++)改为j = 0，通过了，审题太重要了。


Question: [Error] no match for 'operator[]' (operand types are 'person

struct person{ int dei,cai,sum; char id[20];  int flag; }per[100010]; 这个是数组吗？用“[]”符号


Question: 大佬们求解

你这个是什么样的需求，不只是一句话这样的笼统


Question: linux下使用read读取socket数据时间较长

用fputs和fgets

问题解决了，read方法不能放在while循环中，设备有请求时会及时响应，并且每隔40秒定期发送数据，read放在while时，在一直等待网络数据，那么while就死循环了，write就只执行了一次。

说一个啊，你的时间计算有问题，1 秒(sec) = 1000毫秒(ms,millisecond) = 1000000微秒(usec, microsecond)


Question: 指针问题

没有，while判断真假，NULL/0为假，其他为真。 NULL是(void *)0

引用 2 楼 user-3 的回复:没有 因为大多数平台 NULL 被定义为 0 但是不排除某些子系统中的 NULL 不为 0 的情况，但是这种情况极少出现NULL是不是0 都一样

没有


Question: 关于数据结构链表的原理，初学，请各位大佬请教！！！

引用 1 楼 user-1 的回复：Node* currentnode = linkList->next;这一句是指针赋值语句，*currentnode和*（linkList->list）指的是同一个地址的值，而不是指向两个不同地址的相同值（即不是将值复制一份给currentnode）。这里是指针的概念，建议复习一下指针好的，我懂了，谢谢！


标准滚动条的滑块的大小一般根据窗口大小和所要显示的内容大小成比例显示（如果内容大小不变的话，窗口越小滑块越小），当然，如果内容实在太大，按比例的话滑块几乎为零，此时系统还是会显示滑块的，就不按比例显示  case WM_SIZE:       cxClient = LOWORD(lParam);       cyClient = HIWORD(lParam);        //设定垂直滚动条范围和页面大小       si.cbSize = sizeof(si);       si.fMask  = SIF_RANGE | SIF_PAGE;       si.nMin   = 0;       si.nMax   = cyBitmap - 1;       si.nPage  = cyClient;       SetScrollInfo(hwnd, SB_VERT, &si, TRUE);        //设定水平滚动条范围和页面大小       /*       si.cbSize = sizeof(si);       si.fMask  = SIF_RANGE | SIF_PAGE;       si.nMin   = 0;       //*/       si.nMax   = cxBitmap - 1;       si.nPage	 = cxClient;       SetScrollInfo(hwnd, SB_HORZ, &si, TRUE);       return 0;

引用 3 楼 Intel0011 的回复:滚动条的SB_TOP和SB_BOTTOM的这两个消息需要Shift键的配合才有效 SB_TOP:	      //置顶(先按下Shift键不放,然后点击滚动条方块上侧区域就能置顶) SB_BOTTOM: //置顶(先按下Shift键不放,然后点击滚动条方块下侧区域就能置底) 话说标准滚动条的滑块的大小可以修改吗？

引用 7 楼 六道佩恩 的回复:也就是说，标准滚动条在用户操作的情况下是不产生SB_TOP和SB_BOTTOM的是吧？ 是的,按文档上的说明应该是这样的

引用 6 楼 Intel0011 的回复:貌似SB_TOP和SB_BOTTOM是滚动条控件类的属性，窗口自带的标准滚动条没有 如果需要的话，需要自己在WM_KEYDOWN中模拟 case WM_KEYDOWN: 		switch (wParam)       { 		case VK_HOME: 			SendMessage(hwnd, WM_VSCROLL, SB_TOP, 0); 			break; 		case VK_END: 			SendMessage(hwnd, WM_VSCROLL, SB_BOTTOM, 0); 			break; 	   case VK_PRIOR: 			SendMessage(hwnd, WM_VSCROLL, SB_PAGEUP, 0); 			break; 		case VK_NEXT: 			SendMessage(hwnd, WM_VSCROLL, SB_PAGEDOWN, 0); 			break; 		case VK_UP: 			SendMessage(hwnd, WM_VSCROLL, SB_LINEUP, 0); 			break; 		case VK_DOWN: 			SendMessage(hwnd, WM_VSCROLL, SB_LINEDOWN, 0); 			break;       case VK_LEFT: 			SendMessage(hwnd, WM_HSCROLL, SB_LINELEFT, 0); 			break; 		case VK_RIGHT: 			SendMessage(hwnd, WM_HSCROLL, SB_LINERIGHT, 0); 			break; 	   case VK_BROWSER_BACK: 	      SendMessage(hwnd, WM_HSCROLL, SB_PAGELEFT, 0); 			break; 	   case VK_BROWSER_FORWARD: 	      SendMessage(hwnd, WM_HSCROLL, SB_PAGERIGHT, 0); 			break; 		} 	   return 0;  https://docs.microsoft.com/zh-cn/windows/win32/controls/about-scroll-bars  A scroll bar is included in a window either as a standard scroll bar or as a scroll bar control.  A standard scroll bar is located in the nonclient area of a window. It is created with the window and displayed when the window is displayed.  A scroll bar control is a control window that belongs to the SCROLLBAR window class. A scroll bar control appears and functions like a standard scroll bar, but it is a separate window.   A scroll bar control provides a built-in keyboard interface that enables the user to issue scrolling requests by using the keyboard; a standard scroll bar does not. When a scroll bar control has the keyboard focus, it sends WM_HSCROLL and WM_VSCROLL messages to its parent window when the user presses the arrow keys. The request code is sent with each message corresponding to the arrow key the user has pressed. Following are the arrow keys and their corresponding request codes.  Arrow key   Request code DOWN       SB_LINEDOWN or SB_LINERIGHT  END           SB_BOTTOM  HOME       SB_TOP  LEFT          SB_LINEUP or SB_LINELEFT  PGDN       SB_PAGEDOWN or SB_PAGERIGHT  PGUP        SB_PAGEUP or SB_PAGELEFT  RIGHT      SB_LINEDOWN or SB_LINERIGHT  UP           SB_LINEUP or SB_LINELEFT   If you want a keyboard interface for a standard scroll bar, you can create one yourself by processing the WM_KEYDOWN message in your window procedure and then performing the appropriate scrolling action based on the virtual-key code that accompanies the message.  也就是说，标准滚动条在用户操作的情况下是不产生SB_TOP和SB_BOTTOM的是吧？

可能是它看到“SB”两个字母，不想理睬你了。

引用 3 楼 Intel0011 的回复:滚动条的SB_TOP和SB_BOTTOM的这两个消息需要Shift键的配合才有效 SB_TOP:	      //置顶(先按下Shift键不放,然后点击滚动条方块上侧区域就能置顶) SB_BOTTOM: //置顶(先按下Shift键不放,然后点击滚动条方块下侧区域就能置底) 没有，按住Shift再按的效果是立刻到达该位置，，不是到底或到顶

引用 1 楼 飞雪蝶映 的回复:应该是应用错了吧。你得贴你的应用代码。 wParam == SB_TOP  		case WM_VSCROLL: 			switch( LOWORD(wParam) ) 			{ 				case SB_TOP:			printf("1\n"); 	break; 				case SB_BOTTOM:			printf("2\n"); 	break; 				case SB_LINEUP:			printf("3\n");	break; 				case SB_LINEDOWN:		printf("4\n");	break; 				case SB_PAGEUP:			printf("5\n");	break; 				case SB_PAGEDOWN:		printf("6\n");	break; 				case SB_THUMBPOSITION:	printf("7\n");	break; 				case SB_THUMBTRACK: 	printf("8\n");	break; 			} 			return 0;

应该是应用错了吧。你得贴你的应用代码。 wParam == SB_TOP


Question: c语言程序题

把第三个for语句后面的分号去了

请注意编码格式和规范，这样写虽然可以但是自己查bug都费脑子， for()后的语句用大括号圈起来，别管几行。 缩进格式也得注意

注意一下，第三for后面多了一个;。然后x向y赋值的循环就没有执行， 因为第三for之后j = 4;此时k = j; k < 4;所以第四个for一次也不执行。


Question: 布尔变量有大小吗？c99对布尔变量的定义

引用 6 楼 luckyboy1024 的回复:为什么是int，因为发生了整型提升，不能说布尔类型是int吧类型提示说的是操作数a本身的变化 和表达式 !a的类型 没关系 !a 是一个int类型 不管操作数怎么做妖  你也提到最新规范了 最新规范是C11  你自己看一看就行了  顺便 vs主要是C++ 对C语言标准的支持很弱 别用vs验证 vs直到2015都不支持C99的一些新特性呢 比如VLA 别指望vs

为什么是int，因为发生了整型提升，不能说布尔类型是int吧

引用 4 楼 luckyboy1024 的回复:前面忘提了，a定义时定义为char和a的类型没关系 不管什么类型 !运算符结果就是int a定义成指针 !a是int a定义成浮点数 !a是int  顺便强调一下 C和C++ 在这里是有区别的

这段代码和C99布尔类型没什么关系 说出来你可能不信 ! 运算符求值结果是 int类型 所以这段代码输出结果 和 输出sizeof(int)的结果一样 GG

<windef.h>typedef int BOOL;

前面忘提了，a定义时定义为char

在最新的规范中，它并没有定义布尔类型为int，！运算符按理会使a发生整形提升，但这两行代码在VS2013及之后的版本中编辑输出结果是1，换用老一点的编译器VC或者gcc结果都是4


Question: RGB三色数据生成CImage

可能RGB数据别人也是使用OpenCV写入文件中的

三个readSubImage是取RGB数据的，上面函数是生成MAT的，但最终图要放到CList里，要转成CBitmap才能放入CImageList，我就想直接把这函数里用取出的三个RGB数据生成CBitmap(不使用OpenCV)

cv::Mat &errImgMat是返回的结果，你不修改调用者的代码，你怎么能改成CImage呢？！

参考CImage的构造函数或成员函数。

上面是使用Opencv的，想直接使用CImage

//根据CErrImgDExplorerDlg结构填充图像 bool CErrImgDExplorerDlg::readImage(stSubErrInfo& sub, cv::Mat &errImgMat, int& nError) { 	const int m_channelSize = 25000;  	char* m_pbufferR = new char[m_channelSize]; 	char* m_pbufferG = new char[m_channelSize]; 	char* m_pbufferB = new char[m_channelSize];  	memset(m_pbufferR, 0, m_channelSize); 	memset(m_pbufferG, 0, m_channelSize); 	memset(m_pbufferB, 0, m_channelSize); 	bool bRead = true;  //读取数据成功标识 	bool bret = true; 	std::ifstream file; 	file.open(CStringA(sub.path), std::ios_base::_Nocreate | std::ios_base::binary);   	if (file) 	{ 		int len = 0; 		file.seekg(sub.r_offset); 		bRead = readSubImage(file, &m_pbufferR, len);  		if (sub.channel == 1) 		{ 			//pPixmap->loadFromData((uchar*)m_pbufferR, len); 		} 		else if (sub.channel == 3) 		{ 			std::vector<cv::Mat> vec;  			// R 			std::vector<uchar> data_r(m_pbufferR, m_pbufferR + len);  			cv::Mat dr = cv::imdecode(data_r, cv::IMREAD_UNCHANGED); 			data_r.clear();  			vec.push_back(dr);     			// G 			file.seekg(sub.g_offset); 			bRead = readSubImage(file, &m_pbufferG, len);  			std::vector<uchar> data_g(m_pbufferG, m_pbufferG + len); 			cv::Mat dg = cv::imdecode(data_g, cv::IMREAD_UNCHANGED); 			data_g.clear(); 			vec.push_back(dg);  			// B 			file.seekg(sub.b_offset); 			bRead = readSubImage(file, &m_pbufferB, len);  			std::vector<uchar> data_b(m_pbufferB, m_pbufferB + len); 			cv::Mat db = cv::imdecode(data_b, cv::IMREAD_UNCHANGED); 			data_b.clear(); 			vec.push_back(db);  			cv::merge(vec, errImgMat);   			vec.clear(); 		} 		file.close(); 	} 	return true; }

三通道数据长度不一样？那可能是用的YUV/YCbCr彩色空间，而不是RGB

能给个例子吗？取数据时发现，三通道（m_pbufferR、m_pbufferG、m_pbufferB）的数据长度是不一样的，这样也行？

你自己调整一下就行了 RRR...RRR GGG...GGG BBB...BBB 调整成 RGBRGB...RGB

我就是不会合，三通道数据是别人写在本地的文件，我只是读进来但不会用，单个通道的数据（m_pbufferR、m_pbufferG、m_pbufferB三个中的任一个）使用CImage.Load能生成CImage,三通道数据不会合

引用 2 楼 djmjxm 的回复:没找到相关的函数，三通道的数据是分开的 分开的你自己写段代码给它合并到一个缓冲区里不就结了。

没找到相关的函数，三通道的数据是分开的


Question: 关于结构体数组的问题

你改正后的for循环还是有;

文件里面已经有了一个学号是05A18330的内容，但是后面比较输入05A18330怎么都是该学号不存在

这个问题刚刚自己排出来了。现在这一段是这个。 void SEARCH() { 	PRINT(); 	int t; 	int flag=0; 	char s[30]; 	printf("\n  ==================\n"); 	printf("     1.按学号查询     \n"); 	printf("     2.按姓名查询     \n"); 	printf("    ==================\n"); 	printf("请选择查询方式（输入序号）\n"); 	scanf("%d",&t); 	switch(t) 	{ 	case 1: 		printf("请输入想要查询的学号："); 		scanf("%s",s); 		for(i=0;i<33;i++);       			if(strcmp(stu[i].code,s)==0) 		{ 				flag=1; 			printf("姓名    学号   性别   出生日期\n"); 			printf("%s %s %s %s\n",stu[i].name,stu[i].code,stu[i].sex,stu[i].birth); 		} 		if(flag==0) 			printf("该学号不存在\n");break; 	case 2:printf("请输入想要查询的姓名："); 		scanf("%s",s); 		for(i=0;i<33;i++); 		if(strcmp(stu[i].name,s)==0) 		{ 			flag=1; 			printf("姓名    学号   性别   出生日期\n"); 			printf("%s %s %s %s\n",stu[i].name,stu[i].code,stu[i].sex,stu[i].birth); 		} 		if(flag==0) 			printf("该姓名不存在\n");break; 	case 3:default: 		WRONG();break; 	} }   后面怎么都检测不出来相同的= =

你的 for 循环后边多写了一个 分号  void SEARCH() { READ(); for(i=0;i<33;i++); { printf("%s",stu[i].code); }  改成  for(i=0;i<33;i++) { printf("%s",stu[i].code); }

自顶，顶，顶


#include<stdio.h> int main(void) {     int i = 0, j = 0;     char ch;      printf("Please input a string end by '#':\n");     while (1) {         ch = getchar();         if (ch == '#') break;         if (ch == '.') {             putchar('!');             i++;         } else if (ch == '!') {             putchar('!');             putchar('!');             j++;         } else putchar(ch);     }     printf("\n");     printf("'.' times=%d\n", i);     printf("'!' times=%d\n", j);     return 0; } //输出Please input a string end by '#': //输入abc.!# //输出abc!!! //输出'.' times=1 //输出'!' times=1 //输出

没少，后面的补上了。但我就是出不了结果，应该是编译器问题

while循环中你少了ch=getchar();

很好奇楼主的问题是什么？我跑了一遍感觉没问题啊   引用 5 楼 老犯錯誤 的回复:不是很明白你说的，ch用int类型定义？其他步骤跟你是一样的。难道我下了个盗版的编译器？有人能帮忙运行一下吗 #include<stdio.h>  int main(void) { 	int i = 0, j = 0; 	char ch;  	printf("Please input a string end by '#':\n"); 	while (1) 	{ 		ch = getchar(); 		if (ch != '#') 		{ 			if (ch == '.') 			{ 				putchar('!'); 				i++; 			} 			else if (ch == '!') 			{ 				putchar('!'); 				putchar('!'); 				j++; 			} 			else 				putchar(ch); 		} 		if (ch == '#') 			break; 	} 	printf("\n"); 	printf("'.' times=%d\n", i); 	printf("'!' times=%d\n", j); 	return 0; }

引用 4 楼 自信男孩 的回复:while里面不是有break；吗？   int ch; //定义为int类型。 while (1) {     ch = getchar();     if (ch == '#')         break; }  不是很明白你说的，ch用int类型定义？其他步骤跟你是一样的。难道我下了个盗版的编译器？有人能帮忙运行一下吗 #include<stdio.h>  int main(void) { 	int i = 0, j = 0; 	char ch;  	printf("Please input a string end by '#':\n"); 	while (1) 	{ 		ch = getchar(); 		if (ch != '#') 		{ 			if (ch == '.') 			{ 				putchar('!'); 				i++; 			} 			else if (ch == '!') 			{ 				putchar('!'); 				putchar('!'); 				j++; 			} 			else 				putchar(ch); 		} 		if (ch == '#') 			break; 	} 	printf("\n"); 	printf("'.' times=%d\n", i); 	printf("'!' times=%d\n", j); 	return 0; }

重新放张图

while(1)语句块为啥没有ch赋值的操作。没有赋值就是乱码

不要使用 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 ((ch = getchar()) != '#')       ch == '.' ? putchar('!'), i++ :        ch == '!' ? printf("!!"), j++ : putchar(ch);


Question: 关于打开文本文档时ASCII码转成二进制码不能理解

文本文件是以二进制数值存储的，一个二进制数就是一个字符（只以ASCII码为例），打开文件的软件将每个二进制数对应的ASCII码显示或打印出来。所以这里是将存储的二进制数转换成ASCII码显示或打印出来让我们看明白。所有的存储的文件都是以二进制数值存储的。

引用 1 楼 赵4老师的回复:电脑内存或文件内容或传输内容只是一个一维二进制字节数组及其对应的二进制地址； 人脑才将电脑内存或文件内容或传输内容中的这个一维二进制字节数组及其对应的二进制地址的某些部分看成是整数、有符号数/无符号数、浮点数、复数、英文字母、阿拉伯数字、中文/韩文/法文……字符/字符串、汇编指令、函数、函数参数、堆、栈、数组、指针、数组指针、指针数组、数组的数组、指针的指针、二维数组、字符点阵、字符笔画的坐标、黑白二值图片、灰度图片、彩色图片、录音、视频、指纹信息、身份证信息……  推荐使用WinHex软件查看硬盘或文件或内存中的原始字节内容。 您的意思是他是由二进制比如01000001表示A,就是从前者二进制转成A，而不是我理解的10000那个由ASCII码五字节变成二进制吗四字节吗？

数据在计算机里都是二进制形式存放的，而我们能看懂的ASCII只是数据的存放形式不一样。对于计算机而言，它只 认识二进制数。

存在电脑上的是二进制的数。读的方式像是个转换规则， 将二进制按照这个码表的规则转化显示出来给人， 人能看看得懂。  文本中以ascII 码读出来为10000 的块内存 已经不是数字了 而是 '1''0''0''0''0'五个字符

存放到硬盘上都是二进制，会用UltraEdit  16进制看文件，你再回来讨论这个问题比较好。


Question: 求拜各位大佬，我的strcat哪里错了？

计算机组成原理→DOS命令→汇编语言→C语言（不包括C++）、代码书写规范→数据结构、编译原理、操作系统→计算机网络、数据库原理、正则表达式→其它语言（包括C++）、架构……

C:\Program Files (x86)\Windows Kits\10\Source\10.0.10240.0\ucrt\string\amd64\strcat.asm:         title   strcat - concatenate (append) one string to another ;*** ;strcat.asm - contains strcat() and strcpy() routines ; ;       Copyright (c) Microsoft Corporation. All rights reserved. ; ;Purpose: ;       STRCAT concatenates (appends) a copy of the source string to the ;       end of the destination string, returning the destination string. ; ;******************************************************************************* include ksamd64.inc         subttl  "strcat" ;*** ;char *strcat(dst, src) - concatenate (append) one string to another ; ;Purpose: ;       Concatenates src onto the end of dest.  Assumes enough ;       space in dest. ; ;       Algorithm: ;       char * strcat (char * dst, char * src) ;       { ;           char * cp = dst; ; ;           while( *cp ) ;                   ++cp;           /* Find end of dst */ ;           while( *cp++ = *src++ ) ;                   ;               /* Copy src to end of dst */ ;           return( dst ); ;       } ; ;Entry: ;       char *dst - string to which "src" is to be appended ;       const char *src - string to be appended to the end of "dst" ; ;Exit: ;       The address of "dst" in EAX ; ;Uses: ;       EAX, ECX ; ;Exceptions: ; ;*******************************************************************************  ;*** ;char *strcpy(dst, src) - copy one string over another ; ;Purpose: ;       Copies the string src into the spot specified by ;       dest; assumes enough room. ; ;       Algorithm: ;       char * strcpy (char * dst, char * src) ;       { ;           char * cp = dst; ; ;           while( *cp++ = *src++ ) ;                   ;               /* Copy src over dst */ ;           return( dst ); ;       } ; ;Entry: ;       char * dst - string over which "src" is to be copied ;       const char * src - string to be copied over "dst" ; ;Exit: ;       The address of "dst" in EAX ; ;Uses: ;       EAX, ECX ; ;Exceptions: ;*******************************************************************************  public ___entry_from_strcat_in_strcpy LEAF_ENTRY_ARG2 strcat, _TEXT, dst:ptr byte, src:ptr byte      OPTION PROLOGUE:NONE, EPILOGUE:NONE      mov     r11, rcx     test    cl, 7     jz      strcat_loop_begin  strcat_copy_head_loop_begin:     mov     al, [rcx]     test    al, al     jz      ___entry_from_strcat_in_strcpy     inc     rcx     test    cl, 7     jnz     strcat_copy_head_loop_begin  strcat_loop_begin:     mov     rax, [rcx]     mov     r10, rax     mov     r9, 7efefefefefefeffh     add     r9, r10     xor     r10, -1     xor     r10, r9     add     rcx, 8     mov     r9, 8101010101010100h     test    r10, r9     je      strcat_loop_begin     sub     rcx, 8  strcat_loop_end:     test    al, al     jz      ___entry_from_strcat_in_strcpy     inc     rcx     test    ah, ah     jz      ___entry_from_strcat_in_strcpy     inc     rcx     shr     rax, 16     test    al, al     jz      ___entry_from_strcat_in_strcpy     inc     rcx     test    ah, ah     jz      ___entry_from_strcat_in_strcpy     inc     rcx     shr     rax, 16     test    al, al     jz      ___entry_from_strcat_in_strcpy     inc     rcx     test    ah, ah     jz      ___entry_from_strcat_in_strcpy     inc     rcx     shr     eax, 16     test    al, al     jz      ___entry_from_strcat_in_strcpy     inc     rcx     test    ah, ah     jz      ___entry_from_strcat_in_strcpy     inc     rcx     jmp     strcat_loop_begin  LEAF_END strcat, _TEXT  LEAF_ENTRY_ARG2 strcpy, _TEXT, dst:ptr byte, src:ptr byte      OPTION PROLOGUE:NONE, EPILOGUE:NONE      mov     r11, rcx strcat_copy: ___entry_from_strcat_in_strcpy=strcat_copy  ; align the SOURCE so we never page fault  ; dest pointer alignment not important     sub     rcx, rdx ; combine pointers     test    dl, 7     jz      qword_loop_entrance  copy_head_loop_begin:     mov     al, [rdx]     mov     [rdx+rcx], al     test    al, al     jz      byte_exit     inc     rdx     test    dl, 7     jnz     copy_head_loop_begin     jmp     qword_loop_entrance  byte_exit:     mov     rax, r11     ret  qword_loop_begin:     mov     [rdx+rcx], rax     add     rdx, 8 qword_loop_entrance:     mov     rax, [rdx]     mov     r9, 7efefefefefefeffh     add     r9, rax     mov     r10, rax     xor     r10, -1     xor     r10, r9     mov     r9, 8101010101010100h     test    r10, r9     jz      qword_loop_begin  qword_loop_end:     test    al, al     mov     [rdx+rcx], al     jz      strcat_exit     inc     rdx     test    ah, ah     mov     [rdx+rcx], ah     jz      strcat_exit     inc     rdx     shr     rax, 16     test    al, al     mov     [rdx+rcx], al     jz      strcat_exit     inc     rdx     test    ah, ah     mov     [rdx+rcx], ah     jz      strcat_exit     inc     rdx     shr     rax, 16     test    al, al     mov     [rdx+rcx], al     jz      strcat_exit     inc     rdx     test    ah, ah     mov     [rdx+rcx], ah     jz      strcat_exit     inc     rdx     shr     eax, 16     test    al, al     mov     [rdx+rcx], al     jz      strcat_exit     inc     rdx     test    ah, ah     mov     [rdx+rcx], ah     jz      strcat_exit     inc     rdx     jmp     qword_loop_entrance  strcat_exit:     mov     rax, r11     ret  LEAF_END strcpy, _TEXT      end

D:\Program Files (x86)\Microsoft Visual Studio 10.0\VC\crt\src\intel\strcat.asm:         page    ,132         title   strcat - concatenate (append) one string to another ;*** ;strcat.asm - contains strcat() and strcpy() routines ; ;       Copyright (c) Microsoft Corporation. All rights reserved. ; ;Purpose: ;       STRCAT concatenates (appends) a copy of the source string to the ;       end of the destination string, returning the destination string. ; ;*******************************************************************************          .xlist         include cruntime.inc         .list   page ;*** ;char *strcat(dst, src) - concatenate (append) one string to another ; ;Purpose: ;       Concatenates src onto the end of dest.  Assumes enough ;       space in dest. ; ;       Algorithm: ;       char * strcat (char * dst, char * src) ;       { ;           char * cp = dst; ; ;           while( *cp ) ;                   ++cp;           /* Find end of dst */ ;           while( *cp++ = *src++ ) ;                   ;               /* Copy src to end of dst */ ;           return( dst ); ;       } ; ;Entry: ;       char *dst - string to which "src" is to be appended ;       const char *src - string to be appended to the end of "dst" ; ;Exit: ;       The address of "dst" in EAX ; ;Uses: ;       EAX, ECX ; ;Exceptions: ; ;*******************************************************************************  page ;*** ;char *strcpy(dst, src) - copy one string over another ; ;Purpose: ;       Copies the string src into the spot specified by ;       dest; assumes enough room. ; ;       Algorithm: ;       char * strcpy (char * dst, char * src) ;       { ;           char * cp = dst; ; ;           while( *cp++ = *src++ ) ;                   ;               /* Copy src over dst */ ;           return( dst ); ;       } ; ;Entry: ;       char * dst - string over which "src" is to be copied ;       const char * src - string to be copied over "dst" ; ;Exit: ;       The address of "dst" in EAX ; ;Uses: ;       EAX, ECX ; ;Exceptions: ;*******************************************************************************           CODESEG  %       public  strcat, strcpy      ; make both functions available strcpy  proc \         dst:ptr byte, \         src:ptr byte          OPTION PROLOGUE:NONE, EPILOGUE:NONE          push    edi                 ; preserve edi         mov     edi,[esp+8]         ; edi points to dest string         jmp     short copy_start  strcpy  endp          align   16  strcat  proc \         dst:ptr byte, \         src:ptr byte          OPTION PROLOGUE:NONE, EPILOGUE:NONE          .FPO    ( 0, 2, 0, 0, 0, 0 )          mov     ecx,[esp+4]         ; ecx -> dest string         push    edi                 ; preserve edi         test    ecx,3               ; test if string is aligned on 32 bits         je      short find_end_of_dest_string_loop  dest_misaligned:                    ; simple byte loop until string is aligned         mov     al,byte ptr [ecx]         add     ecx,1         test    al,al         je      short start_byte_3         test    ecx,3         jne     short dest_misaligned          align   4  find_end_of_dest_string_loop:         mov     eax,dword ptr [ecx] ; read 4 bytes         mov     edx,7efefeffh         add     edx,eax         xor     eax,-1         xor     eax,edx         add     ecx,4         test    eax,81010100h         je      short find_end_of_dest_string_loop         ; found zero byte in the loop         mov     eax,[ecx - 4]         test    al,al               ; is it byte 0         je      short start_byte_0         test    ah,ah               ; is it byte 1         je      short start_byte_1         test    eax,00ff0000h       ; is it byte 2         je      short start_byte_2         test    eax,0ff000000h      ; is it byte 3         je      short start_byte_3         jmp     short find_end_of_dest_string_loop                                     ; taken if bits 24-30 are clear and bit                                     ; 31 is set start_byte_3:         lea     edi,[ecx - 1]         jmp     short copy_start start_byte_2:         lea     edi,[ecx - 2]         jmp     short copy_start start_byte_1:         lea     edi,[ecx - 3]         jmp     short copy_start start_byte_0:         lea     edi,[ecx - 4] ;       jmp     short copy_start  ;       edi points to the end of dest string. copy_start::         mov     ecx,[esp+0ch]       ; ecx -> sorc string         test    ecx,3               ; test if string is aligned on 32 bits         je      short main_loop_entrance  src_misaligned:                     ; simple byte loop until string is aligned         mov     dl,byte ptr [ecx]         add     ecx,1         test    dl,dl         je      short byte_0         mov     [edi],dl         add     edi,1         test    ecx,3         jne     short src_misaligned         jmp     short main_loop_entrance  main_loop:                          ; edx contains first dword of sorc string         mov     [edi],edx           ; store one more dword         add     edi,4               ; kick dest pointer main_loop_entrance:         mov     edx,7efefeffh         mov     eax,dword ptr [ecx] ; read 4 bytes          add     edx,eax         xor     eax,-1          xor     eax,edx         mov     edx,[ecx]           ; it's in cache now          add     ecx,4               ; kick dest pointer         test    eax,81010100h          je      short main_loop         ; found zero byte in the loop ; main_loop_end:         test    dl,dl               ; is it byte 0         je      short byte_0         test    dh,dh               ; is it byte 1         je      short byte_1         test    edx,00ff0000h       ; is it byte 2         je      short byte_2         test    edx,0ff000000h      ; is it byte 3         je      short byte_3         jmp     short main_loop     ; taken if bits 24-30 are clear and bit                                     ; 31 is set byte_3:         mov     [edi],edx         mov     eax,[esp+8]         ; return in eax pointer to dest string         pop     edi         ret byte_2:         mov     [edi],dx         mov     eax,[esp+8]         ; return in eax pointer to dest string         mov     byte ptr [edi+2],0         pop     edi         ret byte_1:         mov     [edi],dx         mov     eax,[esp+8]         ; return in eax pointer to dest string         pop     edi         ret byte_0:         mov     [edi],dl         mov     eax,[esp+8]         ; return in eax pointer to dest string         pop     edi         ret  strcat  endp          end

建议不要玩这些操作优先级之类的游戏，把代码写的明白清楚一点，这样不容易出错，别人也能看得明白 char *mystrcat(char*dest，const char* str) {        char * ret=dest；        while(*dest)dest++；        while((*dest=*str))dest++, str++；// 多加一重括号表示里面是一个逻辑表达式        return  ret； }

char *mystrcat(char*dest，const char* str) {        char * ret=dest；        while(*dest++)；         dest--;    //经过循环之后，dest指向了'\0'的下一个字符，所以这条语句就是让他指向'\0'，以便后面的while把'\0'覆盖；        while(*dest++=*str++)；        return  ret； }  加一条语句； dest--;    //经过循环之后，dest指向了'\0'的下一个字符，所以这条语句就是让他指向'\0'，以便后面的while把'\0'覆盖；


Question: paho_mqtt 客户端源码例程部分使用交叉编译工具不通过的问题

嗯，问题解决了，我使用cmake 将编译器换成自己的交叉编译器重新生成了库！

paho这个依赖库找不到，有可能是路径配置问题，也有可能没配置生成好的

你要看-L参数指定的路径啊，跟你找到的目录是不是吻合，虽然是用makefile，但你也要知道gcc参数的含义，最好还是把关键参数都了解一遍

有的，但还是会报错

就是这个“-lpaho_mqtt3cs”,要不就是libpaho_mqtt3cs.a文件，要不就是paho_mqtt3cs.so，在你的所谓output目录里面到底有没有

引用 1 楼 user-1的回复:paho这个依赖库找不到，有可能是路径配置问题，也有可能没配置生成好的 你好，你可以详细讲解一下吗？我把生成的库放在了output文件夹下，然后编译的时候是优先去这个文件夹中寻找，但是就一直会报这个错误，


Question: 学生信息管理，运行输到一半程序就崩了，哪里错了，大佬们帮忙解释一下。

感谢大佬们，辛苦四楼啦，加了  if (len > 30) return;就都解决了

我删了	p = (struct student *)malloc(len * sizeof(struct student *)); 还是会停止工作呀

c是静态语言，一旦数组的大小确定了，就不能更改了，如果想要动态的话，建议使用指针

引用 4 楼 自信男孩 的回复:#include<stdio.h> #include <malloc.h>  struct student {     int age;     char name[100];     //float score[100];     float score; }stu[30];  void input(struct student p[]) {     int len,i=0;     //printf("请输入学生人数：",&len);     printf("请输入学生人数：");     scanf("%d", &len);     //p = (struct student *)malloc(len * sizeof(struct student *));     p = (struct student *)malloc(len * sizeof(struct student));     if (!p)         return;      for(i=0; i<len; i++)     {         printf("请输入第%d个学生的信息：\n",i+1);         printf("age=");         scanf("%d",&p[i].age);         printf("name=");         scanf("%s",p[i].name);          printf("score=");         scanf("%f",&p[i].score);     }     for(i=0; i<len; i++)     {         printf("第%d个学生的信息：\n",i+1);         printf("age=%d\n",p[i].age);         printf("name=%s\n",p[i].name);         printf("score=%f\n",p[i].score);     } } int main() {     input(stu);     return 0; }  供参考～   #include<stdio.h> #include <malloc.h>  struct student {     int age;     char name[100];     //float score[100];     float score; }stu[30];  void input(struct student p[]) {     int len,i=0;     //printf("请输入学生人数：",&len);     printf("请输入学生人数：");     scanf("%d", &len);     //p = (struct student *)malloc(len * sizeof(struct student *));     //p = (struct student *)malloc(len * sizeof(struct student ));    //如果要申请也要把*去掉     if (len > 30)         return;      for(i=0; i<len; i++)     {         printf("请输入第%d个学生的信息：\n",i+1);         printf("age=");         scanf("%d",&p[i].age);         printf("name=");         scanf("%s",p[i].name);          printf("score=");         scanf("%f",&p[i].score);     }     for(i=0; i<len; i++)     {         printf("第%d个学生的信息：\n",i+1);         printf("age=%d\n",p[i].age);         printf("name=%s\n",p[i].name);         printf("score=%f\n",p[i].score);     } } int main() {     input(stu);     return 0; }  用这个版本吧，供参考～

错误1， stu是已经分配了空间，在全局区，所以在input中不需要再分配空间了 错误2， sizeof(struct student)应该是分配student结构体的大小，而不是指针大小

input传入的就是一个数组没有必要再动态分配内存啊，你早已经设定stu大小为30

大佬们帮帮忙


Question: C++ 问题求助

printf里面的%和变量的一一对应关系 scanf里面的%和变量以及变量前加不加&的一一对应关系 是C代码中非常容易出错的地方，而且通常编译还不出错。 所以在编译源代码之前值得专门仔细检查一遍甚至多遍。

#include <stdio.h>  int main() {     //int a[5]={0,0,0,0,0};     int a[5]={0};     long long n,m;     //while(scanf("%d%d",&m,&n)!=EOF && m!=0 && n!=0)     while(scanf("%lld%lld", &m, &n) != EOF && m != 0 && n!=0)     {         if(m<=6 && n>=6) a[0]=6;         if(m<=28 && n>=28) a[1]=28;         if(m<=496 && n>=496) a[2]=496;         if(m<=8128 && n>=8128) a[3]=8128;         if(m<=33550336 && n>=33550336) a[4]=33550336;         int d=0;         for(int i=0;i<5;i++)         {             if(a[i]!=0)             {                 printf("%d", a[i]);                 d=1;                 int c=0;                 for(int j=i+1;j<5;j++)                 {                     if(a[j]!=0)                     {                         printf(" ");                         c=1;                         break;                     }                 }                 if(c==0)                     printf("\n");             }         }         if(d==0) printf("No\n");     } }  供参考～

long long是%lld while(scanf("%lld%lld",&m,&n)!=EOF && m!=0 && n!=0)


Question: 关于算术溢出的问题

换个编译器就没问题。推荐 codeblocks

没碰到过类似的情况，不过建议楼主用debug win32模式。

printf("%f",(float)(b-a));

目前我认为可以忽略这种提示。VS2019目前还不能算是一个成熟的成品。 https://docs.microsoft.com/zh-cn/visualstudio/code-quality/c26451?view=vs-2019

应该是跟你选择x64配置项有关


Question: 菜品管理系统

此类代码，请使用C#或者JAVA完成。C++太繁琐。


Question: 中缀转后缀时，用栈处理运算符，处理方法步骤，以及运算符优先级

引用 1 楼 user-1 的回复：楼主到底想说什么？如果是想说算法，百度一下一大堆，如果是想说控件，不论C#还是JAVA都有现成的。我在给我写日志自己以后好看


Question: 疑难问题

那就是保存的地方有问题呗，你是存到堆上了，还是存到栈上了 如果不懂堆栈，那么就问你保存到全局了还是保存在局部作用域了？ 如果保存到数据库那么就得指定数据库语句是否正确执行了。 得确定两件事情 1，是否正确保存 2，拿到的保存信息是否正确

请帖代码。靠猜是不可能猜到的

请判断每个函数调用的返回值。

这样提问，真的世界级难题，没有人能答上


Question: c语言疑惑

调用函数是参数的传递，实际是把实参拷贝了一份传递给函数。所以函数里面再怎么改也只是改的函数中的a,b。跟主函数中的ab没关系。 如果要改主函数中的值，就传地址。通过指针来改。

主函数中改成 swap(&a,&b);  swap函数整个修改： void swap(int *a,int *b){     int t = *a;     *a = *b;     *b = t; }

准确地说，C语言中都是传值的，不能返回结果。哪怕是传指针，指针本身也不能返回，但是可以通过指针改变所指向的变量的值

在main函数里，a和b是实参，在swap函数里，a和b是形参，参数传递只能从实参传到形参，不能从形参传到实参

因为swap中的a,b是局部变量，swap的a, b交换只是改变了swap中的a, b值并没有改变main函数里的a, b值； 参数传递其实是值传递，传给swap的值，即swap局部变量a, b接收了这两个值。


Question: LeetCode 506 输出乱码问题

栈中的变量通常包括函数参数和函数里声明的临时变量。 栈中的基本变量退出其作用域时，没有谁执行一段代码去释放/销毁/析构它所占用的内存，仅仅是没人再去理会的留在当前栈顶上方的若干遗留下来可被后续压栈操作覆盖的无用数据而已。 而栈中的类变量退出其作用域时，会自动执行其析构函数，……

/**  * Note: The returned array must be malloced, assume caller calls free().  */ char ** findRelativeRanks(int* nums, int numsSize, int* returnSize){     static char first[11] = "Gold Medal";     static char second[13] = "Silver Medal";     static char third[13] = "Bronze Medal";     static char mingci[10+5];      char ** ret = (char **)malloc(sizeof(char *)*numsSize);     //建立标记数组，表示该名词有没有被标记过     //1-标记过，0-没有被标记过     int * ptr = (int *)malloc(sizeof(int)*numsSize);     memset(ptr,0,sizeof(int)*numsSize);     //找出前三名的下标，在ret数组里授予相应的奖牌     for(int i = 0;i<3;i++){         int max_index = -1;         int max = INT_MIN;         int index = -1;         for(int j =0;j<numsSize;j++){             if(nums[j] >= max && ptr[j] == 0){                 index = j;                 max = nums[j];             }         }         ptr[index] = 1;         printf("第%d次搜索，最高名次的下标是%d\n",i,index);          if(i ==  0 )             ret[index] = first;         if( i == 1 )             ret[index] = second;         if(i ==  2)             ret[index] = third;         printf("ret[%d] = %s\n",index,ret[index]);         // printf("index = %d,ret = %s\n",index,ret[index]);      }     printf("***");     //对4~剩下的进行排名     char *p=(char *)&mingci[0];     int L;     for(int i = 0;i<numsSize-3;i++){         int max_index = -1;         int max = INT_MIN;         int index = -1;         for(int j =0;j<numsSize;j++){             if(nums[j] >= max && ptr[j] == 0){                 index = j;                 max = nums[j];             }         }         ptr[index] = 1;         printf("第%d次搜索，最高名次的下标是%d\n",i,index);          char mingci[2] ="";         L=sprintf(p,"%d",4+i);         ret[index] = p;         p+=L+1;         if (p-(char *)&mingci[0]>10) {             printf("Too many times!\n");             exit(1);         }         printf("ret[%d] = %s\n",index,ret[index]);         // printf("%c\n",'4'+i);         // printf("index = %d,ret = %s\n",index,ret[index]);     }     // printf("numsSize = %d\n",numsSize);      *returnSize = numsSize;     return ret; }

引用 3 楼 轻箬笠 的回复:楼主的资源这么紧张吗？ char first[11] = "Gold Medal";     char second[13] = "Silver Medal";     char third[13] = "Bronze Medal"; 改成 char first[32] = "Gold Medal";     char second[32] = "Silver Medal";     char third[32] = "Bronze Medal";  因为想空间最小呀，这里改不改问题都不大吧，而且改了之后也是一样的问题，输出还是乱码

引用 1 楼 自信男孩 的回复:出现乱码很可能是字符串没有以'\0'结束，建议查一下你的字符串是否都用'\0'结束了。  请看代码，前三名的字符串是直接赋值的，后面的都在第54行给了'\0'


Question: xp，c

VC6EN https://pan.baidu.com/s/1_t4HPLJZCdiIaJKecguK_A

引用 2 楼 Fick dich 的回复:引用 1 楼 zjq9931 的回复：很多啊，不知你遇到了什么问题？我想下一个 VC6,VS2003 -vs2008 其实是主要是库，对xp的兼容，还有函数，确认函数是否能在xp上使用。只要看MSDN，就好了。

vs就兼容xp啊，不过需要安装xp兼容组件

引用 1 楼 zjq9931 的回复：很多啊，不知你遇到了什么问题？我想下一个


Question: token "." is not valid in preprocessor expressions

理解和讨论之前请先学会如何观察！  VC编译选项加/EP /P（项目、属性、配置属性、C/C++、预处理器、预处理到文件：是，预处理取消显示行号：是），重新编译，查看宏展开后对应的.i文件。gcc加-E http://bbs.csdn.net/topics/391003898

宏定义就是等价替换，你把这个宏定义等价替换到使用的地方看看。


Question: C语言数组学习的困惑，望各位大神解答

#include<stdio.h> int main(void) {     int digit_seen[10] = { 0 };//, repeated_digit[10] = { 0 };     int digit,i=0, flag = 0;//j=0;     long n;     printf("Enter a number: ");     //scanf_s("%ld", &n);     scanf("%ld", &n);     while (n > 0) {         digit_seen[n % 10]++;         n /= 10;         /*         digit = n % 10;         digit_seen[digit] = digit;         if (digit_seen[digit] == digit)         {             repeated_digit[j] = digit;             j++ ;         }         n /=10;         */     }      for (i = 0; i < 10; i++)         if (digit_seen[i] > 1) {             if (flag == 0)                 printf("Repeated digit\n");             printf("%d ", i);             flag = 1;         }     if (flag == 0)         printf("No repeated digit\n");     else         putchar(10);  /*     if (j > 0)     {         printf("Repeated digit\n");         for (i = 0; i <= j; i++)         {             printf(" %d", repeated_digit[j]);         }     }     else         printf("No repeated digit\n"); */     return 0; } 供参考 一个数组就可以完成了！

1. 你的算法不对，if循环永远成立 2. 最后输出的时候应该是printf(" %d", repeated_digit[i]);


Question: visual stdio的用法求助！

我就只用一个控制台项目test，项目中配置源代码为test.cpp,生成test.exe 以后每次都照以下步骤操作：  copy /y xxx.cpp test.cpp 编译链接调试test.exe copy /y test.exe xxx.exe

引用 3 楼 Italink 的回复:[quote=引用 2 楼 老犯錯誤 的回复:] 那每次编写一个新程序倒要重新建立一个win32控制台吗（也不知道是不是这样表述） 是这样的，难道你不觉得所有代码放在一个项目中很乱吗？[/quote] 一般是新建-项目-空项目（c++）

引用 2 楼 老犯錯誤 的回复:那每次编写一个新程序倒要重新建立一个win32控制台吗（也不知道是不是这样表述） 差不多就是你想的那样。每次写新程序，都要新建项目。楼主可以在同一个解决方案下面建多个项目

引用 2 楼 老犯錯誤 的回复:那每次编写一个新程序倒要重新建立一个win32控制台吗（也不知道是不是这样表述） 是这样的，难道你不觉得所有代码放在一个项目中很乱吗？

vc中有一个项目或解决方案的概念，具体来说你这里项目有四个cpp文件，其他CPP文件中也有main函数，就是这个原因。解决：从项目中移除其他cpp

引用 2 楼 老犯錯誤 的回复:那每次编写一个新程序倒要重新建立一个win32控制台吗（也不知道是不是这样表述） 每次把新的CPP加入项目并把不要的CPP移出项目就可以了


Question: devc++循环体内a[k++]调试是k变量的值乱变问题

引用 1 楼 自信男孩的回复:建议贴源码，贴图片看不全代码～ 服了，贴了三张图，全乱掉了

建议贴源码，贴图片看不全代码～


Question: c primer plus 294页

引用 3 楼 user-1 的回复：又看到楼主的帖子，还没搞明白呀？  结合性指的是，在一个表达式里面的优先结合次序，就像楼主所说的，*和++的 优先级是一样的，那么这时候就需要结合性了判断一个表达式是如何进行运算的。 楼主所说的*start++这个表达式，它到底指的是*(start++)还是(*start)++，这就是由结合性来决定的，因为++这个操作符是从右至左的，那么它就是表示*(start++)。但因为start++这个表达式的值是start，所以这个表达式的取值就是*start，从而total+=*start++，就相当于是total+=*start之后start++。结合性指的是操作符的结合次序，并不是运算的次序，就是说，total+=*start++不是start++之后再total+=*start 同样的，因为++start表达式的值是start+1，所以total+=*++start就相当于total+=*(start+1)之后再start++  不知道我说的你明白了吗?明白了，谢谢你

有人回答吗？