Question: 各位父老乡亲，请教一个C语言问题

仅供参考：#pragma comment(lib,"user32") #include <stdio.h> #include <string.h> #include <windows.h> int main() {     SECURITY_ATTRIBUTES sa          = {0};     STARTUPINFO         si          = {0};     PROCESS_INFORMATION pi          = {0};     HANDLE              hPipeOutputRead  = NULL;     HANDLE              hPipeOutputWrite = NULL;     HANDLE              hPipeInputRead   = NULL;     HANDLE              hPipeInputWrite  = NULL;     BOOL                bTest = 0;     DWORD               dwNumberOfBytesRead = 0;     DWORD               dwNumberOfBytesWrite = 0;     CHAR                szMsg[100];     CHAR                szBuffer[256];      sa.nLength = sizeof(sa);     sa.bInheritHandle = TRUE;     sa.lpSecurityDescriptor = NULL;      // Create pipe for standard output redirection.     CreatePipe(&hPipeOutputRead,  // read handle             &hPipeOutputWrite, // write handle             &sa,      // security attributes             0      // number of bytes reserved for pipe - 0 default             );      // Create pipe for standard input redirection.     CreatePipe(&hPipeInputRead,  // read handle             &hPipeInputWrite, // write handle             &sa,      // security attributes             0      // number of bytes reserved for pipe - 0 default             );      // Make child process use hPipeOutputWrite as standard out,     // and make sure it does not show on screen.     si.cb = sizeof(si);     si.dwFlags     = STARTF_USESHOWWINDOW | STARTF_USESTDHANDLES;     si.wShowWindow = SW_HIDE;     si.hStdInput   = hPipeInputRead;     si.hStdOutput  = hPipeOutputWrite;     si.hStdError   = hPipeOutputWrite;      CreateProcess (           NULL, "cmd.exe",           NULL, NULL,           TRUE, 0,           NULL, NULL,           &si, &pi);      // Now that handles have been inherited, close it to be safe.     // You don't want to read or write to them accidentally.     CloseHandle(hPipeOutputWrite);     CloseHandle(hPipeInputRead);      // Now test to capture DOS application output by reading     // hPipeOutputRead.  Could also write to DOS application     // standard input by writing to hPipeInputWrite.     sprintf(szMsg, "ver\n");     WriteFile(           hPipeInputWrite,      // handle of the write end of our pipe           &szMsg,               // address of buffer that send data           strlen(szMsg),        // number of bytes to write           &dwNumberOfBytesWrite,// address of number of bytes read           NULL                  // non-overlapped.           );      while(TRUE)     {        bTest=ReadFile(           hPipeOutputRead,      // handle of the read end of our pipe           &szBuffer,            // address of buffer that receives data           256,                  // number of bytes to read           &dwNumberOfBytesRead, // address of number of bytes read           NULL                  // non-overlapped.           );        if (!bTest){           sprintf(szMsg, "Error #%d reading pipe.",GetLastError());           printf("%s",szMsg);           break;       }        // do something with data.       szBuffer[dwNumberOfBytesRead] = 0;  // null terminate       printf("%s",szBuffer);       if ('>'==szBuffer[dwNumberOfBytesRead-1]) break;     }      sprintf(szMsg, "chcp\nexit\n");     WriteFile(           hPipeInputWrite,      // handle of the write end of our pipe           &szMsg,               // address of buffer that send data           strlen(szMsg),        // number of bytes to write           &dwNumberOfBytesWrite,// address of number of bytes read           NULL                  // non-overlapped.           );      while(TRUE)     {        bTest=ReadFile(           hPipeOutputRead,      // handle of the read end of our pipe           &szBuffer,            // address of buffer that receives data           256,                  // number of bytes to read           &dwNumberOfBytesRead, // address of number of bytes read           NULL                  // non-overlapped.           );        if (!bTest){           sprintf(szMsg, "Error #%d reading pipe.",GetLastError());           printf("%s",szMsg);           break;       }        // do something with data.       szBuffer[dwNumberOfBytesRead] = 0;  // null terminate       printf("%s",szBuffer);     }      // Wait for CONSPAWN to finish.     WaitForSingleObject (pi.hProcess, INFINITE);      // Close all remaining handles     CloseHandle (pi.hProcess);     CloseHandle (hPipeOutputRead);     CloseHandle (hPipeInputWrite);      return 0; } //C:\test>test //Microsoft Windows [版本 5.2.3790] //(C) 版权所有 1985-2003 Microsoft Corp. // //C:\test>ver // //Microsoft Windows [版本 5.2.3790] // //C:\test>chcp //活动的代码页: 936 // //C:\test>exit //Error #109 reading pipe. //C:\test>

system或exec函数

引用 3 楼   L.T 的回复:[quote=引用 2 楼 stherix的回复:]Fortran的exe那么输入输出都肯定是字符终端了 直接运行进程,把输入输出管道重定向到自己的函数就行了 那么怎么弄呢，用什么函数？[/quote]  参考一下 https://blog.csdn.net/guyue35/article/details/47186797

引用 1 楼 user-4的回复:键盘模拟或注入控制，得看exe的工作方式了 Fortran的字符控制

引用 2 楼 stherix的回复:Fortran的exe那么输入输出都肯定是字符终端了 直接运行进程,把输入输出管道重定向到自己的函数就行了 那么怎么弄呢，用什么函数？

键盘模拟或注入控制，得看exe的工作方式了


Question: 初学C语言单片机 求大佬指点一下

引用 1 楼 weixin_45631157的回复:这是完整的程序 #include <reg52.h> typedef unsigned int u16; typedef unsigned char u8; sbit right1 = P0^0; sbit right2 = P0^1; sbit left1 = P0^2; sbit left2 = P0^3; void delay(u16 i) 	{ 		while(i--); 	} 	void left() 		{ 			right1 = 0; 			right2 = 1; 			left1 = 0; 			left2 = 0; 		} void left_back() 	{ 		right1 = 1; 		right2 = 0; 		left1 = 0; 		left2 = 0; } void right() 	{ 		right1 = 0; 		right2 = 0; 		left1 = 1; 		left2 = 0; 	} void right_back() 	{ 		right1 = 0; 		right2 = 0; 		left1 = 0; 		left2 = 1; 	} void run() 	{	 		right1 = 0; 		right2 = 1; 		left1 = 1; 		left2 = 0; 	} void dig_left() 	{  		right1 = 1; 		right2 = 0; 		left1 = 1; 		left2 = 0; 	} void dig_right() 	{ 		right1 = 0; 		right2 = 1; 		left1 = 0; 		left2 = 1; 	} void run_back() 	{ 		right1 = 1; 		right2 = 0; 		left1 = 0; 		left2 = 1;	 	} void stop() 	{ 		right1 = 0; 		right2 = 0; 		left1 = 0; 		left2 = 0; 	} void main() 	{ 		while(1) 		{ 			run(); 			delay(10000000); 			dig_left(); 			delay(10000000); 			dig_right(); 			delay(10000000); 			run_back(); 			delay(10000000); 			stop(); 			delay(10000000); 		} 	} 看你u16是int型，不清楚你的系统情况，u16指的是16位吗？

引用 1 楼 weixin_45631157的回复:这是完整的程序 #include <reg52.h> typedef unsigned int u16; typedef unsigned char u8; sbit right1 = P0^0; sbit right2 = P0^1; sbit left1 = P0^2; sbit left2 = P0^3; void delay(u16 i) 	{ 		while(i--); 	} 	void left() 		{ 			right1 = 0; 			right2 = 1; 			left1 = 0; 			left2 = 0; 		} void left_back() 	{ 		right1 = 1; 		right2 = 0; 		left1 = 0; 		left2 = 0; } void right() 	{ 		right1 = 0; 		right2 = 0; 		left1 = 1; 		left2 = 0; 	} void right_back() 	{ 		right1 = 0; 		right2 = 0; 		left1 = 0; 		left2 = 1; 	} void run() 	{	 		right1 = 0; 		right2 = 1; 		left1 = 1; 		left2 = 0; 	} void dig_left() 	{  		right1 = 1; 		right2 = 0; 		left1 = 1; 		left2 = 0; 	} void dig_right() 	{ 		right1 = 0; 		right2 = 1; 		left1 = 0; 		left2 = 1; 	} void run_back() 	{ 		right1 = 1; 		right2 = 0; 		left1 = 0; 		left2 = 1;	 	} void stop() 	{ 		right1 = 0; 		right2 = 0; 		left1 = 0; 		left2 = 0; 	} void main() 	{ 		while(1) 		{ 			run(); 			delay(10000000); 			dig_left(); 			delay(10000000); 			dig_right(); 			delay(10000000); 			run_back(); 			delay(10000000); 			stop(); 			delay(10000000); 		} 	} u16的最大值是65536，你给delay传递的值太大了

错误在那里，贴错误出来看看


Question: 关于for循环中的指针控制

字符串最后以'\0'结尾，系统会默认补充，题主在给声明赋值时结尾加； 循环条件怎么控制看题主具体需求，看题主意图应该是想索引整个字符串，那判断条件就是 *s != '\0'

《C++Primer第五版中文版》中提到 操作符*叫做解引用符，如果指针指向了一个对象，则允许使用解引用符来访问该对象。对指针解引用会得出所指向的对象。 在你的代码中，s是指针，*s就是对s进行解引用，得到s所指向的内容，即字符串“ this is a number”中的字符，而s++是对指针进行移位操作，将指针移动到字符串的下一个字符中。所以，for语句的作用是遍历字符串“ this is a number”中的字符，直到*s的内容是空为之，退出for循环。

字符串最后一个'\0',你的判断条件*s!='\0'就行

引用 2 楼 user-5 的回复:[quote=引用 1 楼 自信男孩的回复:]s++是向后移动位置（地址），*s是去对应地址里的数值。 举个例子，第一次判断*s即't' == 0？，为真执行循环体，s++，此时s指向了'h'，判断*s，即'h' == 0？ 继续执行，以此类推～ 为假，才执行循环体吧[/quote] 哦，应该是*s != 0

引用 1 楼 自信男孩的回复:s++是向后移动位置（地址），*s是去对应地址里的数值。 举个例子，第一次判断*s即't' == 0？，为真执行循环体，s++，此时s指向了'h'，判断*s，即'h' == 0？ 继续执行，以此类推～ 为假，才执行循环体吧


Question: getchar

int getchar(void);从函数名去理解它的功能:获取字符（一个）  至于怎么用，可以搜一下～

百度是个好东西


Question: C语言程序设计

这么简单的就自己实现啦。 把文件读进一个buf[]里 然后对每个buf进行移位判断，例如: for(int j=0; j<8; ++j) { if(buf[i] & 0x01) //输出1 else //输出0 buf[i] >>= 1; }  另外一个程序，把8个1、0进行移位，得到一个byte


Question: C语言数组问题

如果是int a[4]，那就是四个int值，如果是struct tt a[4]，那就是四个tt，每个a[]是一个tt，每个tt里有两个参数(x和y)，所以给a初始化赋值的时候就有八个值，两个一组对应a[0] a[1] a[2] a[3]。至于给a[]的y赋值时的a+n,代表的是一个地址值，a就是a[0]的地址，a+1是a[1]的地址。。当调用->y的时候，其实求是让前者指向后者，整个程序类似写了个循环链表

a是结构体数组，结构体有两个元素一个是x，一个是指针y，所以20是对应x，a+1是对应y； 即y = a+1;即a[0].y = a+1;即y指向a[1]

struct tt a;a[4]是一个结构数组，结构中每个有两个元素x,*y,大括号中初始化，按顺序就需要有8个初始化的内容分对应a[0]={20,a+1},a[1]={15,a+2}..... a值是结构数组的头地址，也就是指向a[0],a+1相当于(&a[0]+sizeof(tt)*1)指向a[1]的指针.

这是结构体数组的初始化,每个结构体有2个数据,每2个数据对应一个结构体元素的初始化. a+1,a+2是指针+1,,a+1指向a[1]这个数据


Question: C语言

自己先写写，看着不难吧

引用 1 楼 user-2 的回复：


Question: Win10使用vim编译一个存在问题的c程序时出现乱码，该如何解决？

文件编码不对。转换一下文件编码试试。


Question: 小学生50以内数学计算基于c语言

谢谢指导，我去尝试一下

do{ a=rand()%51; b=rand()%51; d=rand()%2; if(d==0) c=a+b;     else c=a-b;     }while(c<0||c>50); 这一段通过不停试错得到结果 虽然可行 但可以考虑优化 最大是50 那么 a确定的情况下  b直接缩小选择随机数的范围即可 a = rand() % 51; b = rand() % (51 - a);//默认按照加法处理 c = a+b; d=rand()%2; if(d == 1)//减法做特殊处理  { c = b; b += a;  }一次到位不用循环

引用 3 楼 棉猴的回复:代码写的不错，值得学习！ k = 0;//将k复位 	      printf("错误，正确答案:%d\n", c); 如果不添加这一行，在经过第一次提示正确答案后，以后每次只答错一次就要提示正确答案，而不是三次。 因为是题目要求答题者回答三次才能显示正确答案，所以才弄了答三次才能显示正确答案

是的你这种更简单，我那种复杂化了

//int num=0, add=0; int num, add; int score[3]={10,7,5}; //char str[20],str1[10][20]; //int a=0,b=0,c=0,d,k=0,i=0,j=1,result; int a, b, c, d, k, i, j, result; char sf[2]={'+','-'}; 这些全局变量可以这么定义和声明；  对于i, j, k这些下表，建议定义为局部变量。  这个地方有关问题，如果使用者连续3次以上回答错误，那么在跳出循环之前， 是否现将k赋值为0呢，否则k的值会继续增加，回答下一道题时，执行这条语句时：add+=score[k-1]; 会导致score数组溢出。 修改如下：  else                 {                     printf("错误，正确答案:%d\n",c);                     k = 0;                     break;                 }


Question: 学生信息管理系统基于c语言，输入添加输出查询删除信息。

好的，谢谢指导，希望以后多多交流

建议增加对学号相同的判断，对于学生信息，姓名可能相同，学号不应该相同； 另外，程序中未对姓名相同做判断，若输入两个姓名一样的信息，删除时只会删除一个～  一些细节可以在考虑一下。  另外，gets建议用更安全的方式，比如fgets。gets不能保证输入的内容较多，导致缓存溢出～


Question: 求解！！！关于C语言的一些知识

引用 3 楼 zarelaky 的回复:[quote=引用 2 楼 zarelaky 的回复:] 桩代码，一般来说是在已有实现程序逻辑里面插入一个函数调用，提供一个默认实现，在有需要的时候添加一些功能实现，具体功能需要看GUI_OBJECT_NO_POST_ACTION代表的什么意思 一般不需要理解GUI_OBJECT_NO_POST_ACTION这个符号名称的值具体是什么，只要关注它代表的功能。 在生成执行程序时GUI_OBJECT_NO_POST_ACTION会由编译器进行宏展开，展开后的值就是(1<<9)，开启编译器优化后，会转换为常数0x100[/quote]  好的 多谢大佬！

引用 1 楼 自信男孩 的回复:是return (1<<9);因为宏定义就是等价替换；函数的真正作用可能是注释掉的部分。     哦哦 谢谢大佬了！

引用 2 楼 zarelaky 的回复:桩代码，一般来说是在已有实现程序逻辑里面插入一个函数调用，提供一个默认实现，在有需要的时候添加一些功能实现，具体功能需要看GUI_OBJECT_NO_POST_ACTION代表的什么意思 一般不需要理解GUI_OBJECT_NO_POST_ACTION这个符号名称的值具体是什么，只要关注它代表的功能。 在生成执行程序时GUI_OBJECT_NO_POST_ACTION会由编译器进行宏展开，展开后的值就是(1<<9)，开启编译器优化后，会转换为常数0x100


Question: 求解C语言制表符问题

下面的数据两个\t是为了与上面的汉子对齐。上面也给两个的话，上面的字会分的更开

既然表数据各列%d之间有两个\t 为什么表头各列之间不是两个\t而是一个\t ?

引用 7 楼 qq_44857348 的回复:[quote=引用 4 楼 轻箬笠的回复:]尽量用%10d，%12.2lf之类的。制表符的宽度不好确定，不同的环境结果可能不一样。而空格占用的位置大小基本固定 题目要求用制表符，，，，[/quote] 如果必须用制表符，那把printf改成wprintf试试。我觉得问题应该出在中文上面。

没看懂什么问题

引用 4 楼 轻箬笠的回复:尽量用%10d，%12.2lf之类的。制表符的宽度不好确定，不同的环境结果可能不一样。而空格占用的位置大小基本固定 题目要求用制表符，，，，

应该是你手机环境的问题，你可以试试%10d这样来调整宽度

printf函数采用标记（-   +  #等）和修饰符（数字  .数字  l  ll  h  hh 等等）可以控制输出的格式

引用 2 楼 qq_44857348 的回复:“平方”，“立方”没有和“整数”一样，靠在一起。你可以用 %10d 试试。制表符用的太少了。

引用 1 楼 weixin_43925756的回复:没看懂什么问题 “平方”，“立方”没有和“整数”一样，靠在一起。


Question: 麻将拿好牌算法

两个色子可能的拿牌顺序有6+5+4+3+2+1=21种 34和25加起来都是7 但拿牌的位置是不一样的

1.随机洗牌。如果洗牌不是随机的，你这个作弊暴露的可能性太大了；  2.真正打色子之前，做一个模拟运算，测算出每个数字庄家对应的牌，通过估值函数评分，最后得到一个庄家得分最高的一个色子数字。将此数字作为最终打色子的数字。  3.做一个外部遥控器，分东南西北，按哪个，则按哪个方位评分最高来打色子。

作弊机的关键是胡牌时候出假牌、诈胡什么的。开牌，什么价有什么牌，价小才会出天胡；这种牌，胡到头也不值钱，没必要理它。开牌又叫洗牌，打麻将关键就是开牌能否开出价来。至于麻将机作弊给某人发好牌，其实是逗不懂行的玩儿的，我同学打牌经常是一对三照赢，把对手逼到桌下传牌，然后就开始打架了。

谢谢大家，结贴了！

自动麻将机作弊还是有很高技术含量的，楼主的应该还是麻将软件

让某人拿好牌很简单的，好比让一部分人先富起来，只是你需要转换思路，胆子再大一点，步子再快一点~~~ 人生中能不能拿到好牌主要取决于你生活在什么圈子里，游戏里也一样，一个好牌队列，一个普通牌队列，你想照顾的某人拿到的牌来自于好牌队列，其他人的则来自于普通牌队列，所以你想让他拿到什么牌就有什么牌，起手一副大四喜不也很简单么

首先一个色子就6种点数 2个色子就12种点数  只要将这12种可能的牌列出来  按照你认为是好牌的算法过一遍 取最大值就可以了 关键点  什么样的算是好牌 这个需要你自己去定义 是对子多 还是其他的什么

引用 2 楼 user-10 的回复:没那么简单，杠或者碰都会打乱排序，比较简单的一个方法的就是上手的牌计算分数，分数高的发给庄家 比如同一色大于多少张是多少分，每有一对是多少分等等 请问下这位兄弟，按照你说的方法确实不错，就是根据一些牌型来算分，取最高的分，我想请教下，如何判断手里牌是怎样的，假设一手牌里我有8张万字（已按升序排好），我如何知道有几句话、几对、几个3张的、几个4张的，这似乎是个很复杂的事情，之前没有遇到过类似算法，麻烦可否提供个思路，谢谢！

起手抓牌胡就完事了

换个角度吧，可以把好牌当成数据，事先做好数据就是了。以前玩过一个dos下的麻将就是这样的

引用 9 楼 名人堂再聚首 的回复:谢谢众大神，我的想法是这样的：通过不同的色子组合从不同的位置拿牌（色子的组合方式可以算出来应该是21种），当我拿到一手牌，我用计分的方式来定义是否好牌，例如：两张牌相邻记1分，有一个对子计2分，一句话记3分，三个相同牌记5分，四个相同牌记8分，3连对记10分等等，比如我有一手牌包含8个万字，3个筒字，1个条子，剩余2个风，请问下如何分析这些牌并记分，例如如何分析8个万字中是否有对，多少对，是否有一句话存在，有几句话，有没有连对等等，麻烦各位给个思路，非常感谢！ 楼主可以考虑用multimap，并对其排序。multimap使用和排序 遍历所有的key就可以很简单的得到对子，和三对，四对。 不过三连之类的，还是需要一个个前后比较。 另外，我觉得楼主做的时候不要拘泥于万字，筒子和条子。可以把万字当成1-9，筒子当成11-19，条子当成21-29，字当成31-37。这样排序比较会比较方便点。 如果有花，桌得之类的要另外处理。

引用 3 楼 名人堂再聚首 的回复:楼上几位大神都说得很有道理，目前只管拿到好牌，后面的碰或杠现在都不用管，因为有的牌人家不碰也有可能，目前主要是根据牌的分布情况，尽量选最优的牌，后面怎么打就不管了，其实有时拿到好牌也不一定就能和牌，当然赢的概率会高些，关键还是要手气好。 能抓到好牌己经处理不败之地了，把把天和，还有人玩吗，按几种打点规则，能抓牌的起点位置没有多少种，算一次，取个最优的组合和必胜没什么区别了

引用 楼主 名人堂再聚首 的回复:各位大神，有个问题要向大家请教下： 是这样的，我现在要负责一个单片机测试程序，主要用C语言，设计一个麻将的玩法，就是怎么样让庄家能拿到好牌，是136张的那种，传统的“万条点”加上“东南西北中发白”总共136张，假设是4个人玩，当牌洗好后，每方34张牌分两层摆放，并且我也知道每张牌的分布情况，我现在要设计一个算法：通过分析牌的分布情况，控制打色子的点数来拿到好牌，现在就说一般的胡牌，不说其他什么清一色、对对碰、七对等等，请教下大概的思路，万分感谢！ 这种东西做来害人啊，洗牌是随机的话，那就把所有打出的点数组合算一次，那个点拿到的牌最好就打多少点了

我觉得给麻将算分就行。比如系统规定，一对红中是10分，一对9筒是5分，三四五连在一起的算6分。算出四家牌的总分，把总分高的给自己就好了。当然这样不一定每局都赢。至少每局都是最好的牌。


Question: error: expected ')' before numeric constant

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

主要原因是函数调用和函数声明的区别。这应该是课本上的基本内容呢。  main函数里的函数调用都去掉函数返回值类型

引用 5 楼 阿大古 古古古的回复:[quote=引用 4 楼 Spicy__Chicken 的回复:] [quote=引用 3 楼 阿大古 古古古 的回复：][quote=引用 2 楼 通信小卒 的回复:] main函数调用函数不需要加viod类型，另外把main里面调用的函数放在main函数的前面。 楼主改个名试过吗？调用函数在上面声明就可以了[/quote]换了几次名称还是不管用啊[/quote] main函数中 函数调用前的void去掉了？[/quote] 肯定要去掉，我没见过调用的时候还加返回类型的。另外再main函数里面调用的函数传递参数也不需要加数据类型。我有点疑惑楼主这是要做什么？在main函数里面是要执行函数，不是来声明函数的。

新建一个源码文件，然后一行一行贴进去编译，看看在哪一行出现的问题

引用 4 楼 Spicy__Chicken 的回复:[quote=引用 3 楼 阿大古 古古古 的回复：][quote=引用 2 楼 通信小卒 的回复:] main函数调用函数不需要加viod类型，另外把main里面调用的函数放在main函数的前面。 楼主改个名试过吗？调用函数在上面声明就可以了[/quote]换了几次名称还是不管用啊[/quote] main函数中 函数调用前的void去掉了？

引用 3 楼 阿大古 古古古 的回复：[quote=引用 2 楼 通信小卒 的回复:] main函数调用函数不需要加viod类型，另外把main里面调用的函数放在main函数的前面。 楼主改个名试过吗？调用函数在上面声明就可以了[/quote]换了几次名称还是不管用啊

引用 2 楼 通信小卒 的回复:main函数调用函数不需要加viod类型，另外把main里面调用的函数放在main函数的前面。 楼主改个名试过吗？调用函数在上面声明就可以了

该不会是名字有冲突吧？

哦对，犯了个低级错误


Question: 小白备考C语言ing，求大神解答！

引用 5 楼 qq_45607648 的回复:在此统一谢谢各位，我理解能力有限，每条评论都看了好多遍，自己想的话很难想出来这些思路，我决定还是记答案吧 记住答案是最不保险的方法，因为稍微改动一个表达式，结果可能就是不一样的，建议还是弄懂指针的使用，既然 要干这一行，那就弄明白原理；

9题s指向了t，那么*s就是t，*s = &m;即t指向了m。因此，*t就是m的值。**s即也是m的值。

关键点在于9.里面的s=&t语句，在9里面，s本来指向指针p的地址，s=&t之后变成指向指针t的地址了，*s=&m让t指向了m（*t=m=5,**s=t=5）,而指针p还是指向i，所以*p=i=3,**r=i=3； 然而10.里面s指向p的地址，*s=t之后，p重定向到k的地址，所以*p=k=7,**r=k=7；

这种题目我都佩服出题人 我感觉这么说希望对你有帮助，指向i的指针就只有p一个，在第一个练习中，s = &t;*s = &m；执行完后，p任然是指向i的而r也是继续指向p的二级指针（注意形参和实参的问题，传给函数的参数，程序都在栈中做一份拷贝）。而第二个练习中，*s = t，相当于让p从指向i变成指向k了（因为*s就是p，而t指向的就是k），所以再打印*p时已经指向k了，而r依然指向p，p指向k，所以**r也是7


Question: 自闭大学生在线求帮助，急

引用 1 楼 自信男孩 的回复：把%s的输入地方都去掉&，因为数组本身就是地址，无需再添加&取地址。  另外，以后建议直接贴代码，论坛支持直接贴代码并且还会自动缩进和对齐这可样改还是没法正常输出呀，还是只能输出最后输入的那一组数据

引用 2 楼 I＇m Jason. 的回复:[quote=引用 1 楼 自信男孩 的回复：]把%s的输入地方都去掉&，因为数组本身就是地址，无需再添加&取地址。  另外，以后建议直接贴代码，论坛支持直接贴代码并且还会自动缩进和对齐这可样改还是没法正常输出呀，还是只能输出最后输入的那一组数据[/quote] 贴出你的代码，可以帮你调试一下～

你输入是调你的add函数吗，那每调一次上一次的是不是被替换了，贴代码吧程序一个照片显示不完看起来真不舒服


Question: 时长复习两天半的在校大学生前来报道

引用 5 楼 gouyanfen的回复:[quote=引用 2 楼 Azn2luv 的回复:] [quote=引用 1 楼 gouyanfen的回复:]指定课题就不说了，自己找东西做的话，建议找可以发挥C/C++强项的东西，做管理系统随便找个语言比C实现起来简单一百倍，简单高效，你做了一个月，别人三天,或许只要一天就完成了会打击你学C/C++的热情。 哥，我这是c语言的实训呀⊙∀⊙！[/quote] 实训做这个课题，不知道老师没水准还是对学生没信心。你实训你跑来要代码？那还训什么，直接花钱让人帮做就行了。[/quote] 哥，你说的太对了，我错了，我好好学习去了

引用 2 楼 Azn2luv 的回复:[quote=引用 1 楼 gouyanfen的回复:]指定课题就不说了，自己找东西做的话，建议找可以发挥C/C++强项的东西，做管理系统随便找个语言比C实现起来简单一百倍，简单高效，你做了一个月，别人三天,或许只要一天就完成了会打击你学C/C++的热情。 哥，我这是c语言的实训呀⊙∀⊙！[/quote] 实训做这个课题，不知道老师没水准还是对学生没信心。你实训你跑来要代码？那还训什么，直接花钱让人帮做就行了。

引用 3 楼 轻箬笠的回复:直接说给多少钱更实在 哥，你好像有点东西耶，能不能网上帮我找下啊，不用你编，我不太会找。我数组，链表，文件搞不太清楚，要用数组的，找下10r巨款，救救山沟沟里的穷苦孩子吧！😂😂

直接说给多少钱更实在

引用 1 楼 gouyanfen的回复:指定课题就不说了，自己找东西做的话，建议找可以发挥C/C++强项的东西，做管理系统随便找个语言比C实现起来简单一百倍，简单高效，你做了一个月，别人三天,或许只要一天就完成了会打击你学C/C++的热情。 哥，我这是c语言的实训呀⊙∀⊙！

实训还要代码，楼主是打算不吃这行的饭吗

加油，网上代码去仔细看看是能明白点东西的


Question: 比较字符串大小

引用 1 楼 user-5 的回复：所有字符都要比较。比较字符串大小全部都要遍历吗？

字符串比较大小原理是每个字符都进行比较，根据字符偏移，在偏移值相等的情况下比较对应的字符。  *s++ == *t++ 这个表达式就是比较每个字符，而不是之比较第一个。注意++自增号

我个人感觉有个细节在于while语句后面有个；号，意味着第一个字符满足条件的话是不会返回的，而是一直遍历到两个字符中较小的那个的最后

引用 4 楼 浮一大白开水 的回复：不要纠结比较字符串大小全部都要遍历这些，这个题知识点，敲黑板。。。 1、*s, *t, *s++, *t++都表示什么内容。 2、字符串是以结束符结束的。（*s）（*t） 3、*s-*t  是字符的ascii码值的运算。ok

*s和*t在这里不是第一个字符的意思，而是用来判断字符串是不是为空

所有字符都要比较。


Question: 整数反转

反转后无论是否溢出，永远都在-2147483648~2147483648之间，所以条件判断是无意义的 可以转字符串后操作，正数负数分别处理，最后用字符串比较判断是否越界

没什么问题呀


Question: InvalidateRect（h, NULL, 1），第三个参数，除了BeginPaint，还有没有其他方法获取？

参考一下MSDN98中相关例子代码。


Question: 求助大神

你的问题是什么？%%d作为普通字符了。  建议自己输入到电脑编译一下试试，应该是会有警告～

这个解析里面已经说得很清楚了呀

在printf里，“%d”是一个格式控制符，表示输出整数，换言之，printf在遇到%符号后就会把它以及后一个（或多个）符号共同组成一个格式控制符，那么问题来了，如何输出一个%符号？所以，当初设计人员是这么设计的：每两个%表示一个%符号，比如printf（“%%”）就会输出一个%符号，printf（“%%%%”）就会输出%%，即2两个%符号。

我们在输出是，需要用%d这样的东西来告诉程序我们输出什么格式（相当于告诉计算机怎么去“翻译”那一堆二进制），那么问题来了，要是我们需要输出一个%怎么办呢？程序会认为我们没有写后面的修饰符，这时候我们规定若要输出%，则采取%%的写法


Question: 给出一个 32 位的有符号整数，你需要将这个整数中每位上的数字进行反转

C和C++完整教程:https://blog.csdn.net/it_xiangqiang/category_10581430.html C和C++算法完整教程:https://blog.csdn.net/it_xiangqiang/category_10768339.html

abs绝对值函数；  while( temp % 10 == 0 && temp != 0 )         temp /= 10 ; 针对1000,100， 500等这些数据，  但是这样一个程序，1000怎么翻转，翻转为0001，还是1?

初学没太懂，希望能有点注释，感谢博主

有什么问题嘛？


Question: C

引用 楼主 qq_45541848的回复:int*float int+float  结果是什么类型 运算过程中有没有隐式转换为double 书上说所有的浮点数参与运算都转换为double 书上说“浮点数参与运算都转换为double类型，即使仅有单精度类型，也要转换为双精度参与运算” 是不是错了

刚测试了下，应该是int转成float了。 测试方法。 int size = sizeof(1 + 1.0f); size = sizeof(1 * 1.0f); 结果为4  size = sizeof(1 + 1.0); size = sizeof(1 * 1.0); 结果为8


Question: 为什么是41而不是其他数

随机数是用一个数反复计算得到的，你每次运行时，它是用的同一个数，进行相同的运算，因此也就得到了相同的数

请参考《C++中产生随机整数的方法（srand()函数与rand()函数）》 希望能够帮到你

可能楼主想象不到的是这是故意设计成这样的，其原因是为了方便调试，程序真正发布出去时则会加上上面说的随机化、种子，保证不再一样

先生成随机根 srand

// Seed the random-number generator with the current time so that      // the numbers will be different every time we run.      srand( (unsigned)time( NULL ) );

仅供参考：D:\Program Files (x86)\Microsoft Visual Studio 10.0\VC\crt\src\rand.c /*** *rand.c - random number generator * *       Copyright (c) Microsoft Corporation. All rights reserved. * *Purpose: *       defines rand(), srand() - random number generator * *******************************************************************************/  #include <cruntime.h> #include <mtdll.h> #include <stddef.h> #include <stdlib.h>  /*** *void srand(seed) - seed the random number generator * *Purpose: *       Seeds the random number generator with the int given.  Adapted from the *       BASIC random number generator. * *Entry: *       unsigned seed - seed to seed rand # generator with * *Exit: *       None. * *Exceptions: * *******************************************************************************/  void __cdecl srand (         unsigned int seed         ) {         _getptd()->_holdrand = (unsigned long)seed; }   /*** *int rand() - returns a random number * *Purpose: *       returns a pseudo-random number 0 through 32767. * *Entry: *       None. * *Exit: *       Returns a pseudo-random number 0 through 32767. * *Exceptions: * *******************************************************************************/  int __cdecl rand (         void         ) {         _ptiddata ptd = _getptd();          return( ((ptd->_holdrand = ptd->_holdrand * 214013L             + 2531011L) >> 16) & 0x7fff ); }

随机数种子一样导致生成的随机数相同

一般在调用rand之前，先调用srand(time(NULL));

这种问题建议楼主百度一下

(4)因为rand()函数是按指定的顺序来产生整数，因此每次执行上面的语句都打印相同的两个值，所以说C语言的随机并不是真正意义上的随机，有时候也叫伪随机数。 (5)为了使程序在每次执行时都能生成一个新序列的随机值，我们通常通过为随机数生成器提供一粒新的随机种子。函数 srand()(来自stdlib.h)可以为随机数生成器播散种子。只要种子不同rand()函数就会产生不同的随机数序列。srand()称为随机数生成器的初始化器。


Question: c语言小游戏

将图片整合的资源中。

放到资源里面，或者做个服务端，用到的时候从服务端下载个图片（最简单就是http的服务器了，直接http下载即可，http下载可以用curl）


Question: PTA平台错误问题

内存越界，申请了n个float类型的元素，再输入的时候为啥是i < n+1呢？并且i是从0开始的。  sum == *(a+n);这个有两个问题，第一个这个是赋值操作，为啥要用==，第二个是内存越界。

看提示吧，代码有特殊情况没考虑


Question: 关于长流程的处理方法探索

可以考虑用多态。

请牢记：源代码本身的书写是否结构化或面向对象或符合设计模式或敏捷…并不重要，重要的是你是否使用结构化或面向对象或符合设计模式或敏捷…的方法命名标识符、阅读、修改、检查、测试源代码。  意思是你程序结构看上去再合理，再简洁，也不一定比看上去一团乱麻的程序结构在运行或修改时更不易出错，更方便修改，出错了更容易找到哪里出错和具体出错的原因，更容易改正错误。  试对比 图书馆（对图书的分类够结构化了吧） 和 搜索引擎（可看作是扁平化任何结构数据，仅支持全文检索） 哪个处理信息更方便、更高效。  所以 与其费劲去重构代码让其看上去更简洁、更合理 不如费劲学习grep、sed、awk、……这类全文搜索和批处理编辑的工具。  结构越复杂，越难修改，越难除错。 有时（甚至大多数时候），看上去越合理、越简洁的代码，运行起来性能越差，出错时查找原因越难，找到出错原因后改正越费劲。  程序员要做的不是尽力避免错误，而是聚焦在快速发现并改正错误。真正以快速方式轻易解决错误，“快速的失败”远胜过“预防错误”。Fred George  前微软C#编辑器的开发主管Jay Bazuzi列出的一些有助于找到正确方向的问题；他觉得前同事们应该用这些问题来问自己；实际上不管在哪里工作的开发者们都应该经常问问自己这些问题： ◆“要保证这个问题不会再出现，我该怎么做？” ◆“要想少出些Bug，我该怎么做？” ◆“要保证Bug容易被修复，我该怎么做？” ◆“要保持对变化的快速响应，我该怎么做？” ◆“要保证我的软件的运行速度，我该怎么做？” 如果大多数团队都能不时问一下自己，必定会从中得益，因为这些都是真正强而有力的问题。

引用 楼主 a_moon_devin 的回复:平时我写流程的时候，比较常用switch，但随着case越多的时候，稍微中间有什么变动，基本就会影响到case顺序的排布。 现在我的解决方法是，用了好多个switch，相当于把流程分割出来… 有没有类似链表那种方法，无论我中间怎么删除或者添加，都不用去修改那个流程顺序 用链表把函数指针和参数，还有条件值设计成一个链表，不同的条件传入不同的参数调用对应的回调函数。可以动态添加删除。

可以考虑把这个switch流程改成个结果树，可以基于linux内核红黑树实现，key的生成根据业务逻辑做字符串哈希啥的，如果有无break的特殊case情况，可以在树节点内添加一个标志位，1为终止节点，0为非终止节点，查询到且为0的话就便利大子树。除此之外，如果每个case的处理函数格式一样，就整个统一的函数指针，初始化节点的时候挂上，如果不一样，就参照printf封装可变参函数吧，好歹能整进去。核心问题是key的生成算法，业务相关，不好说。


Question: 谭浩强的5版c程序设计中的例题1.3两数比大小 我写的有问题但不知道原因 请大神帮我看看

哦可以这样 受教了 谢谢

引用 3 楼 qq_45275086的回复:果然 少了逗号 打字习惯不加标点了 谢谢你 你习惯了不加标点，你可以把scanf里面的逗号去掉，这样你就不用输入逗号了。

果然 少了逗号 打字习惯不加标点了 谢谢你

可以在输入之后先检查一下ab的值都是多少

应该是要输入1,2吧

明白了 谢谢各位

输入少个逗号，看一下scanf的输入格式。  scanf是格式化输入，因此要根据你的格式来输入

输入scanf里有逗号，应该加逗号的


Question: c语言结构体数组运用

引用 1 楼 自信男孩的回复:#include<stdio.h> #include<string.h>  #define miun 99  struct stdio {     char str_miun[30];     int student; //} x[3] = {'李楠',0,'张强',0,'王东',0}; } x[3] = {"李楠",0, "张强",0, "王东",0};  int main() {     char str_miuns[miun];     int c, s;     for (c = 0; c < 10; c++)     {         //scanf_s("%s", str_miuns[c]);         scanf_s("%s", str_miuns, mium);         for(s=0;s<3;s++)         {             //if (strcmp(str_miuns[c], x[s].str_miun) == 0)             if (strcmp(str_miuns, x[s].str_miun) == 0)             {                 x[s].student++;             }         }     }     printf("投票结束");     int v;     for (v = 0; v < 3; v++)     {         printf("%s:\t%d\n", x[v].str_miun, x[v].student);     }     return 0; }   供参考～  ''和""的区别，字符串和字符的区别，建议重新梳理一下 还是没明白scanf_s

引用 3 楼 轻箬笠的回复:[quote=引用 2 楼 Gnglas 的回复:] 还是没明白scanf_s scanf_s是scanf的安全形式。 比如 char buf[5]={'\0'}; scanf("%s", buf);//这句可以改成scanf_s("%s",buf,5)  ANSI C标准中没有scanf_s，楼主可以用scanf替换。[/quote] 为什么我改成scanf_s那个格式是错的，而且vs2019用不了scanf

引用 2 楼 Gnglas 的回复:还是没明白scanf_s scanf_s是scanf的安全形式。 比如 char buf[5]={'\0'}; scanf("%s", buf);//这句可以改成scanf_s("%s",buf,5)  ANSI C标准中没有scanf_s，楼主可以用scanf替换。


Question: vs2017输出字符为乱码？

控制台属性里改一下默认字符

怎么解决的？大神，没看懂

system("chcp 437");

问题已经解决，控制台默认值设置一下就可以了！


Question: argc和argv可以程序内赋值吗

引用 4 楼 ArdoYe 的回复:不是const参数，可以修改的，只是改了以后就要自己小心维护，不要越界。  The parameters argc and argv and the strings pointed to by the argv array shall be modifiable by the program, and retain their last-stored values between program startup and program termination。  我的意思就是 int main(int argc, char** argv) {     argc = 2;     argv[1] = "aaa"; } 这种写法， 如果我只传一个参数进去，那argv[1] = "aaa" 这样不就出现数组越界了吗，  但是他前面又给argc赋值了2，这样是否确实地扩大了argv数组的空间

只读，不可写~~~~

引用 1 楼 Eleven 的回复:你已经始终把它们认为是只读~  是什么意思呢

你已经始终把它们认为是只读~

引用 14 楼 lin5161678 的回复:[quote=引用 13 楼 jSORoROWy 的回复:] [quote=引用 9 楼 lin5161678 的回复:] 可以修改 注意不要越界就好了  包括argv本身和argv[ i ] 2个维度的不能越界   标准中的main第二个参数不带 const 就算你这个带上const的参数 一样可以修改 argv[i] 和 argv 不能修改的只是 argv[i][j]  也就是说如果我运行时候输入3个参数，我可以改argv[0], argv[1], argv[2], 而argv[3]以及之后若进行赋值肯定是越界  但是IOS/IEC 9899 5.1.2.2.1中有提到 引用http://www.open-std.org/jtc1/sc22/WG14/www/docs/n1256.pdf The parameters argc and argv and the strings pointed to by the argv array shall be modifiable by the program, and retain their last-stored values between program startup and program termination 说argc和argv都应可修改，那么如果argc的修改并不能使得argv的大小改变，那修改该argc的意义是什么[/quote] 假设你输入参数是  程序名 参数1 参数2 你可以修改  argv[0] argv[1] argv[2] argv[3] argv[4]开始包括4 是越界  argc和argv都可修改 argc的修改并不能使得argv的大小改变 修改该argc的意义 就是修改argc [/quote]  好的，感谢！！！

抱歉，上面说错，是输入2个参数

引用 13 楼 jSORoROWy 的回复:[quote=引用 9 楼 lin5161678 的回复:] 可以修改 注意不要越界就好了  包括argv本身和argv[ i ] 2个维度的不能越界   标准中的main第二个参数不带 const 就算你这个带上const的参数 一样可以修改 argv[i] 和 argv 不能修改的只是 argv[i][j]  也就是说如果我运行时候输入3个参数，我可以改argv[0], argv[1], argv[2], 而argv[3]以及之后若进行赋值肯定是越界  但是IOS/IEC 9899 5.1.2.2.1中有提到 引用http://www.open-std.org/jtc1/sc22/WG14/www/docs/n1256.pdf The parameters argc and argv and the strings pointed to by the argv array shall be modifiable by the program, and retain their last-stored values between program startup and program termination 说argc和argv都应可修改，那么如果argc的修改并不能使得argv的大小改变，那修改该argc的意义是什么[/quote] 假设你输入参数是  程序名 参数1 参数2 你可以修改  argv[0] argv[1] argv[2] argv[3] argv[4]开始包括4 是越界  argc和argv都可修改 argc的修改并不能使得argv的大小改变 修改该argc的意义 就是修改argc

引用 9 楼 lin5161678 的回复:可以修改 注意不要越界就好了  包括argv本身和argv[ i ] 2个维度的不能越界   标准中的main第二个参数不带 const 就算你这个带上const的参数 一样可以修改 argv[i] 和 argv 不能修改的只是 argv[i][j]  也就是说如果我运行时候输入3个参数，我可以改argv[0], argv[1], argv[2], 而argv[3]以及之后若进行赋值肯定是越界  但是IOS/IEC 9899 5.1.2.2.1中有提到 引用http://www.open-std.org/jtc1/sc22/WG14/www/docs/n1256.pdf The parameters argc and argv and the strings pointed to by the argv array shall be modifiable by the program, and retain their last-stored values between program startup and program termination 说argc和argv都应可修改，那么如果argc的修改并不能使得argv的大小改变，那修改该argc的意义是什么

这个得关注一下，以前没有想过可以这样用

引用 10 楼 jSORoROWy 的回复:[quote=引用 8 楼 自信男孩 的回复:] 建议理解一下main函数的两个参数的作用，第一个参数是值执行是的参数个数，第二个参数参数的内容。 对于main函数来讲，这两个参数的作用是接收在运行终端上输入的参数，因此不能在main中对他们进行修改；  int main(int argc, const char *argv[]) 这是main函数的两个参数，从第二个参数可知，argv[]是不允许修改的  如果是int main(int argc, char* argv[]) 不就可以修改了吗，实际上修改了也不会有问题（在简单程序中我没有发现修改argv会造成什么影响，甚至数组越界访问也可以（就是我一楼的那种写法））  int main(int argc, char* argv[]) {     argc = 2;     argv[1] = "aaa";     printf("%s", argv[1]);     return 0; }  以上代码编译运行结果： aaa  如果argc的改变底层不会自动使argv扩容，那么argv[1]肯定是越界访问了，关键是c不检查越界，所以我无法知道到底有没有越界[/quote]需要注意2点  1. 你一楼的做法并没有越界  argv末尾有一个NULL 你修改了那个指针而已 并没有越界 2. 没有统一有效的方式说明存在越界行为 不是说能运行就没越界  另外 明确告诉你 修改argc不存在argv扩容 只是简简单单的修改一个变量而已  这种东西没什么神秘的 直接看汇编就是一个mov 完事

引用 8 楼 自信男孩 的回复:建议理解一下main函数的两个参数的作用，第一个参数是值执行是的参数个数，第二个参数参数的内容。 对于main函数来讲，这两个参数的作用是接收在运行终端上输入的参数，因此不能在main中对他们进行修改；  int main(int argc, const char *argv[]) 这是main函数的两个参数，从第二个参数可知，argv[]是不允许修改的  如果是int main(int argc, char* argv[]) 不就可以修改了吗，实际上修改了也不会有问题（在简单程序中我没有发现修改argv会造成什么影响，甚至数组越界访问也可以（就是我一楼的那种写法））  int main(int argc, char* argv[]) {     argc = 2;     argv[1] = "aaa";     printf("%s", argv[1]);     return 0; }  以上代码编译运行结果： aaa  如果argc的改变底层不会自动使argv扩容，那么argv[1]肯定是越界访问了，关键是c不检查越界，所以我无法知道到底有没有越界

引用 8 楼 自信男孩 的回复:建议理解一下main函数的两个参数的作用，第一个参数是值执行是的参数个数，第二个参数参数的内容。 对于main函数来讲，这两个参数的作用是接收在运行终端上输入的参数，因此不能在main中对他们进行修改；  int main(int argc, const char *argv[]) 这是main函数的两个参数，从第二个参数可知，argv[]是不允许修改的可以修改 注意不要越界就好了  包括argv本身和argv[ i ] 2个维度的不能越界   标准中的main第二个参数不带 const 就算你这个带上const的参数 一样可以修改 argv[i] 和 argv 不能修改的只是 argv[i][j]

引用 5 楼 jSORoROWy 的回复:[quote=引用 4 楼 ArdoYe 的回复:] 不是const参数，可以修改的，只是改了以后就要自己小心维护，不要越界。  The parameters argc and argv and the strings pointed to by the argv array shall be modifiable by the program, and retain their last-stored values between program startup and program termination。  我的意思就是 int main(int argc, char** argv) {     argc = 2;     argv[1] = "aaa"; } 这种写法， 如果我只传一个参数进去，那argv[1] = "aaa" 这样不就出现数组越界了吗，  但是他前面又给argc赋值了2，这样是否确实地扩大了argv数组的空间[/quote] 怎么可能因为给argc赋值为2，就扩大数组空间。要扩展数组空间，需要调用realloc。类似 argv = (char **)realloc(argv, argc);  另外，一般来说，我们不会修改argc和argv，因为有类似GetCommandLine的函数，可以获取到参数的。楼主自己加的，还真不确定能不能拿到哦。

自顶一下。。


Question: 大佬来捞我吧

把你定义的线接到模拟信号输入端口啊。

引用 1 楼 user-1的回复:测电压值，那就是模拟信号输入啊，输出电压控制，那就是模拟信号输出啊。 咋测自己定义那四根线

测电压值，那就是模拟信号输入啊，输出电压控制，那就是模拟信号输出啊。


Question: 习题纠错

哦哦哦，是这样，终于解决了，谢谢哈

#include <stdio.h> #include <stdlib.h> #include <string.h> char * s_gets(char * st, int n); #define MAXTITL 40 #define MAXAUTL 40 #define MAXBKS 100  struct book {     char title[MAXTITL];     char author[MAXAUTL];     float value; };  /* 14.2 manybook.c int main() {     struct book library[MAXBKS];     int count = 0;     int index;      printf("Please enter the book title.\n");     printf("Press [enter] at the start of a line to stop.\n");     while(count < MAXBKS && s_gets(library[count].title, MAXTITL) != NULL && library[count].title[0] != '\0')     {         printf("Now enter the author.\n");         s_gets(library[count].author, MAXAUTL);         printf("Now enter the value.\n");         scanf("%f", &library[count++].value);         while (getchar() != '\n')             continue;         if (count < MAXBKS)             printf("Enter the next title.\n");     }      if (count > 0)     {         printf("Here is the list of your books:\n");         for (index = 0; index < count; index++)             printf("%s by %s: $%.2f\n", library[index].value);     }     else         printf("No books? Too bad.\n");      return 0; } */  void show_books_info(struct book **list, int num);  int main() {     struct book library[MAXBKS];     struct book *alphaorder[MAXBKS];     struct book *priceorder[MAXBKS];     int count = 0;     int index;      printf("Please enter the book title.\n");     printf("Press [enter] at the start of a line to stop.\n");     while(count < MAXBKS && s_gets(library[count].title, MAXTITL) != NULL && library[count].title[0] != '\0')     {         printf("Now enter the author.\n");         s_gets(library[count].author, MAXAUTL);         printf("Now enter the value.\n");         scanf("%f", &library[count++].value);         while (getchar() != '\n')             continue;         if (count < MAXBKS)             printf("Enter the next title.\n");     }      struct book * temp;      if (count > 0)     {         printf("Here is the list of your books:\n");         for (index = 0; index < count; index++)             printf("%s by %s: $%.2f\n",library[index].title,library[index].author, library[index].value);          for (int n = 0; n < count; n++)         {             alphaorder[n] = &library[n];             priceorder[n] = &library[n];         }          printf("Here are the books by alpha order:\n");         for (int i = 0; i < count - 1; i++)         {             for (int j = i + 1;j < count; j++)             {                 if(strcmp(alphaorder[i]->title, alphaorder[j]->title) < 0) {   //需要括号                     temp = alphaorder[i];                     alphaorder[i] = alphaorder[j];                     alphaorder[j] = temp;                 }             }             //printf("%s by %s: $%.2f\n",alphaorder[i]->title,alphaorder[i]->author, alphaorder[i]->value);         }         show_books_info(alphaorder, count);         //printf("%s by %s: $%.2f\n",alphaorder[count - 1]->title,alphaorder[count - 1]->author, alphaorder[count - 1]->value);          printf("Here are the books by price order:\n");         for (int k = 0; k < count -1; k++)         {             for (int m = k + 1; m < count; m++)             {                 if(priceorder[k]->value > priceorder[m]->value) {    //需要括号                     temp = priceorder[k];                     priceorder[k] = priceorder[m];                     priceorder[m] = temp;                 }             }             //printf("%s by %s: $%.2f\n",priceorder[k]->title,priceorder[k]->author, priceorder[k]->value);         }         show_books_info(priceorder, count);         //printf("%s by %s: $%.2f\n",priceorder[count - 1]->title,priceorder[count - 1]->author, priceorder[count - 1]->value);     }     else         printf("No books? Too bad.\n");      return 0; }  void show_books_info(struct book **list, int num) {     int i;      printf("After order:\n");     for (i = 0; i < num; i++)             printf("%s by %s: $%.2f\n", list[i]->title, list[i]->author, list[i]->value); }   char * s_gets(char * st, int n) {     char * ret_val;     char * find;      ret_val = fgets(st, n, stdin);     if(ret_val)     {         find = strchr(st, '\n');         if (find)             *find = '\0';         else             while(getchar() != '\n');     }     return ret_val; }  供参考～  该加大括号的没加，输出排序后的，需要用循环，不能在排序的逻辑里输出排序后的内容～


Question: else悬挂 哪个哥哥救救我 我要疯了

{  }与那个对齐就是哪个？建议使用一个IDE编码，最次也可以用dourceinsught，一目了然

你本来是想让ELSE和外层IF匹配，但是你的写没却与内层IF匹配了，一楼是一种解决办法，另外你可以把内层IF包裹在外层IF的一对｛｝中，在这个｛｝外写ELSE语句块就可以了

楼主是啥问题，可否描述的更清晰一些？

#include<stdio.h>  int main()  { char isRani,isFree;  printf("是否有空? (Y/N)");  scanf("%c",&isFree);  getchar();  printf("是否下雨？(Y/N)");  scanf("%c",&isRani); getchar();  if(isFree == 'Y') { if(isRani == 'Y') { printf("记得带伞噢 (*∩_∩*)\n"); }  } else; else { printf("女神没空！\n");   }  return 0; }

建议用个IDE写代码。


Question: 关于选择排序

谢谢了，这个问题之前还真没留意过！

不是，k的第一次被赋值为0。for循环的执行逻辑建议查一下。 初始值i = 0;此时先判断i < 10;是否为真，如果为真，则执行循环体，而不是执行i++; 当循环体执行完后，且再循环体里没有break操作，则执行i++;然后在判断i < 10;是否为真， 依次向下执行～


Question: 求大神解释一下

引用 9 楼 liups 的回复：[quote=引用 8 楼 二马胖 的回复:] [quote=引用 7 楼 liups 的回复：][quote=引用 5 楼 二马胖 的回复:] 数组越界了，应该就是word2的结尾0写到数组word［0］里面了 按4楼输入，是越界了[/quote]越界了所以如果word1是低地址的话，那么输出应该是12345678##，所以word1只能是高地址才能得到这个结果，但是具体原因我也不懂 [/quote] 我前面就说了，你不能因为word1和word2是连续定义的，就认为他们一定在内存中是连续或紧挨着的，因这没有语言的标准中规定要连续！如果你在某种实现比如VC2013中发现是连续的，那也不能说明什么问题[/quote]谢谢，帮我看看下面的一个疑问吧😄

那假如我定义了一个结构体，结构体里面有两个int类型的数据，它们的地址应该是连续的吧，那他们有没有谁高地址谁低地址的规定呢

没规定 没限制 没要求 word1 可以高地址 可以低地址

引用 8 楼 二马胖 的回复:[quote=引用 7 楼 liups 的回复：][quote=引用 5 楼 二马胖 的回复:] 数组越界了，应该就是word2的结尾0写到数组word［0］里面了 按4楼输入，是越界了[/quote]越界了所以如果word1是低地址的话，那么输出应该是12345678##，所以word1只能是高地址才能得到这个结果，但是具体原因我也不懂 [/quote] 我前面就说了，你不能因为word1和word2是连续定义的，就认为他们一定在内存中是连续或紧挨着的，因这没有语言的标准中规定要连续！如果你在某种实现比如VC2013中发现是连续的，那也不能说明什么问题

引用 7 楼 liups 的回复：[quote=引用 5 楼 二马胖 的回复:] 数组越界了，应该就是word2的结尾0写到数组word［0］里面了 按4楼输入，是越界了[/quote]越界了所以如果word1是低地址的话，那么输出应该是12345678##，所以word1只能是高地址才能得到这个结果，但是具体原因我也不懂

引用 5 楼 二马胖 的回复:数组越界了，应该就是word2的结尾0写到数组word［0］里面了 按4楼输入，是越界了

引用 3 楼 肥仔亮 的回复：地址的分配遵从原则： 1：静态变量和全局变量在启动时就分配内存，局部变量在用到时再分配内存，这个大家都知道。 2：内存的分配地址，从低到高，也知道。 3：同时段定义的变量，变量类型占位大的先分配。        如，char c=3； int i=2；那么，i的地址比c低。  楼主，你两个数组，只是声明，没赋值，其实还没真正分配内存的。你试试赋值后再读地址看看。 这问题之前没多想，楼主验证后麻烦把结果告知一下，大家一起进步你看我楼下回复

数组越界了，应该就是word2的结尾0写到数组word［0］里面了

然后我scanf（%s,word） scanf（%s,word2） 输入的都是12345678 然后printf（"%s#％s#",word,word2） 然后输出是#12345678#

Char：不能大写！ 高地址这些是没有规定的，不能凭空认定

高地址是什么?是说分配的栈的地址号的大小吗？


Question: C初学

scanf("d%", &age); 这样的代码应该是会给error或warning

d%改成%d，楼上已经说了。  关于精度的问题，可以参考IEEE 754浮点数标准详解 第一个函数3.156e7是double类型的，第二个函数3.156e7是float类型的

scanf("%d", &age);


Question: 用C怎么把汉字英语混合字符串逆置

还有 L"Unicode字符串" L'Unicode字符'

Unicode编码~ for循环，首尾字符交换~

逆置是倒叙的意思？用libconv转成宽字节，再排序，如有必要，再转码一次


Question: 实数取余命令框错误

%号需要进行转义，否则会把%5当成格式控制符，改为36%%5=%d


在WM_PAINT意外的其它的地方，你可以使用GetDC()/ReleaseDC()绘图

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

The function returns the previous DC_PEN color, even if the stock pen DC_PEN is not selected in the DC; however, this will not be used in drawing operations until the stock DC_PEN is selected in the DC.

引用 11 楼 六道佩恩 的回复:话说你知道SetDCPenColor无效是怎么一回事吗？设置颜色后，画笔颜色没改变，但GetDCPenColor获取颜色的结果却是已改变 case WM_PAINT:       {          // Initializing original object          HGDIOBJ original = NULL;                   hdc = BeginPaint(h, &ps);          Arc(hdc, 100, 100, 300, 200, 0, 0, 0, 0);          // Saving the original object          // and Select DC_PEN so you can change the color of the pen with          // COLORREF SetDCPenColor(HDC hdc, COLORREF color)          original = SelectObject(hdc, GetStockObject(DC_PEN));          // Set the Pen to Blue          SetDCPenColor(hdc, RGB(0, 0, 255));          Arc(hdc, 200, 100, 300, 200, 0, 0, 0, 0);          // Restoring the original object          SelectObject(hdc, original);          EndPaint(h, &ps);       }       return 0;

为什么不行，闲来无事可以参考一下Win2000源代码相关片段。 我说这句话的意思并不是意味着我看过哈。我只是扶上马，送一程。 https://bbs.csdn.net/topics/390374955

引用 8 楼 user-3 的回复:问题在于hdc不能跨消息使用  话说你知道SetDCPenColor无效是怎么一回事吗？设置颜色后，画笔颜色没改变，但GetDCPenColor获取颜色的结果却是已改变

引用 8 楼 user-3 的回复:问题在于hdc不能跨消息使用  #include "windows.h" LRESULT MyProc( HWND h , UINT msg , WPARAM wParam , LPARAM lParam ) { 	static PAINTSTRUCT ps; 	static HDC hdc; 	switch( msg ) 	{ 		case WM_SIZE: 			hdc = BeginPaint( h , &ps ); 			InvalidateRect( h , NULL, 0 ); 			return 0; 			  		case WM_PAINT: 		{	 			SendMessage( h , WM_ERASEBKGND , hdc , 0 ); 			Arc( hdc , 100,100,300,200,0,0,0,0 ); 			ValidateRect( h , NULL );  			return 0; 		} 	 		case WM_LBUTTONDOWN: 			InvalidateRect( h , NULL , 0 ); 			return 0; 	 		case WM_DESTROY: 			PostQuitMessage(0); 			EndPaint( h , &ps ); 			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			=LoadCursor(NULL, IDC_ARROW);		 	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 ) { 	RegMyClass( "MyClass" , MyProc ); 	CreateWindow( "MyClass" , "绘图" ,WS_OVERLAPPEDWINDOW|WS_VISIBLE,  				300,400,500,500,NULL,NULL,NULL,NULL ); 	MSG msg; 	while( GetMessage( &msg , NULL, 0,0 ) ) 	{ 		DispatchMessage( &msg ); 	} 	return 0; }

引用 8 楼 user-3 的回复:问题在于hdc不能跨消息使用 不是吧，你这样说的话，那个main里的绘图怎么解释？GetDC又怎么解释？ 其实我差不多弄懂是怎么回事了，是ps没有更新，WM_CREATE时窗口大小为0，因此ps里记录的就是{0,0,0,0}，而InvalidateRect使窗口无效化后发送WM_PAINT后，WM_PAINT里也没有更新ps里的矩形，所有绘画不出来，解决办法是把WM_CREATE修改为WM_SIZE，这个时候窗口已经创建完毕，ps可以得到正确的矩形，即便窗口大小变化时也可以正确变化，程序结果也出来了

问题在于hdc不能跨消息使用

在WM_PAINT外一样能用BeginPaint绘图，所以我才会对之前的代码产生疑问  #include "stdio.h" #include "string.h" #include "windows.h" int main( void ) { 	char *str = "C语言";			 	HFONT font = CreateFont( 100, 0, 150, 0, 600, 0, 1, 0, 0, 0, 0, 0, 0, "楷体" );	 	HWND h = GetConsoleWindow(); 	Sleep(100);  	PAINTSTRUCT ps; 	InvalidateRect( h , NULL , 1 );					 	HDC hdc = BeginPaint( h , &ps );			 	SelectObject( hdc , font );					 	TextOut( hdc , 130 , 160 , str , strlen(str) );	 	EndPaint( h , &ps );						 	return 0;  }

引用 1 楼 赵4老师 的回复:BeginPaint The BeginPaint function prepares the specified window for painting and fills a PAINTSTRUCT structure with information about the painting.   HDC BeginPaint(   HWND hwnd,  // handle to window   LPPAINTSTRUCT lpPaint               // pointer to structure for paint information );   Parameters hwnd  Handle to the window to be repainted.  lpPaint  Pointer to the PAINTSTRUCT structure that will receive painting information.  Return Values If the function succeeds, the return value is the handle to a display device context for the specified window.   If the function fails, the return value is NULL, indicating that no display device context is available.   Windows NT: To get extended error information, callGetLastError.  Remarks The BeginPaint function automatically sets the clipping region of the device context to exclude any area outside the update region. The update region is set by the InvalidateRect or InvalidateRgn function and by the system after sizing, moving, creating, scrolling, or any other operation that affects the client area. If the update region is marked for erasing, BeginPaint sends a WM_ERASEBKGND message to the window.   An application should not call BeginPaint except in response to a WM_PAINT message. Each call to BeginPaint must have a corresponding call to the EndPaint function.   If the caret is in the area to be painted, BeginPaint automatically hides the caret to prevent it from being erased.   If the window's class has a background brush, BeginPaint uses that brush to erase the background of the update region before returning.   QuickInfo   Windows NT: Requires version 3.1 or later.   Windows: Requires Windows 95 or later.   Windows CE: Requires version 1.0 or later.   Header: Declared in winuser.h.   Import Library: Use user32.lib.  See Also Painting and Drawing Overview, Painting and Drawing Functions, EndPaint, InvalidateRect, InvalidateRgn, PAINTSTRUCT, ValidateRect, ValidateRgn 赵老。。。原文我看过的，我想要知道的是为什么不能，而不是应该怎样，我使用InvalidateRect，窗口客户区已无效化，这个时候使用BeginPaint理应可以完成绘图且能显示才对呀

引用 3 楼 Eleven 的回复:你调用BeginPaint应该在WM_PAINT消息响应函数中，而不应该在其它的消息响应中~ 我知道，我只想探究它不能的原因，不使用窗口过程直接在main里使用BeginPaint一样可以完成绘图，我想探究的是它和GetDC的不同究竟在哪里？如何实现完全等效


Question: 大家好，请教关于位域的一些问题！

仅供参考：#include <stdio.h> #pragma pack(push,1) union U {     unsigned char byte;     struct BF {         unsigned int b0:1;//a         unsigned int b1:1;//b         unsigned int b2:1;//c     } bf; } u; #pragma pack(pop) unsigned char bt; int a,b,c; int main() {     for (bt=0;bt<8;bt++) {         u.byte=(unsigned char)bt;         a=u.bf.b0;         b=u.bf.b1;         c=u.bf.b2;         printf("byte 0x%02x -- c:%d b:%d a:%d\n",bt,c,b,a);     }     for (c=0;c<2;c++)     for (b=0;b<2;b++)     for (a=0;a<2;a++) {         u.bf.b0=a;         u.bf.b1=b;         u.bf.b2=c;         bt=u.byte;         printf("c:%d b:%d a:%d -- byte 0x%02x\n",c,b,a,bt);     }     return 0; } //byte 0x00 -- c:0 b:0 a:0 //byte 0x01 -- c:0 b:0 a:1 //byte 0x02 -- c:0 b:1 a:0 //byte 0x03 -- c:0 b:1 a:1 //byte 0x04 -- c:1 b:0 a:0 //byte 0x05 -- c:1 b:0 a:1 //byte 0x06 -- c:1 b:1 a:0 //byte 0x07 -- c:1 b:1 a:1 //c:0 b:0 a:0 -- byte 0x00 //c:0 b:0 a:1 -- byte 0x01 //c:0 b:1 a:0 -- byte 0x02 //c:0 b:1 a:1 -- byte 0x03 //c:1 b:0 a:0 -- byte 0x04 //c:1 b:0 a:1 -- byte 0x05 //c:1 b:1 a:0 -- byte 0x06 //c:1 b:1 a:1 -- byte 0x07

位域一般在结构体里面实用，结构体需要考虑字节对齐的问题，这个也是填充字节的目的，不清楚你说的失去位域效果指的是什么？

char和short有时候会扩展成4字节 未命名的字节起填充作用，控制后面位域的位置


Question: 求大佬们解答

for语句里面的三个参数 都是选择项，你像第一个参数初始化，你可以放到for语句之前，这个for里的三个参数的第一个你就可以不写。你这里个第三个参数没有，这个可以把他放到for语句体里面。第二个参数循环条件控制，也可以省，但在for语句里一定要做别的处理，不然就成死循环了。

答案是5因为++的优先级在这里面最小，所以最后执行，但是整个语录执行完后。i已经等于5了

3个参数都可以不填，但;不能省略

出现i(4)++<4时结束循环，故最后i为5


Question: 基础运算求解

引用 4 楼 赵4老师的回复:关于C,C++表达式求值顺序 http://blog.csdn.net/fefe82/article/details/37833767，http://bbs.csdn.net/topics/370153775 非常感谢！ ……………………

不要做这种没意义的事了，记得用括号！！！！！！！！！

不要在同一个式子里对同一个变量出现两次++就行了，因为具体怎么算可能因编译器而不同

编译器对后置 ++ 的解释不同，一个是执行完语句才加 1，一个是执行完当前操作加 1。


Question: 请问为什么结果总比正常值少1啊（codeblocks,c语言）


Question: 菜鸟提问

#include "windows.h" LRESULT MyProc( HWND h , UINT msg , WPARAM wParam , LPARAM lParam ) { 	static PAINTSTRUCT ps; 	switch( msg ) 	{ 		case WM_PAINT: 		{	 			HDC hdc = BeginPaint( h , &ps ); 			MoveToEx( hdc , 50 ,50 , NULL ); 			LineTo( hdc , 50, 400 ); 			LineTo( hdc , 400, 400 ); 			Arc ( hdc , 100 , 100 , 300 , 300 , 0 , 0 , 0 , 0 ); 			EndPaint( h , &ps ); 			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			=LoadCursor(NULL, IDC_ARROW);		 	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 ) { 	RegMyClass( "MyClass" , MyProc ); 	CreateWindow( "MyClass" , "绘图" ,WS_OVERLAPPEDWINDOW|WS_VISIBLE,  				300,400,500,500,NULL,NULL,NULL,NULL ); 	MSG msg; 	while( GetMessage( &msg , NULL, 0,0 ) ) 	{ 		DispatchMessage( &msg ); 	} 	return 0; }

稍微复杂点的话，你还需要创建自己的窗口，总不能老用控制台绘图吧。嫌麻烦的话，可以去了解easyx库，他们的绘图函数简单许多，但貌似只有dll版。

你说的坐标系是理论上的还是实际的线条？ 最简单的方法可以这样： #include "windows.h" int main( void ) { 	HWND h = GetConsoleWindow(); 	HDC hdc = GetDC( h );  	MoveToEx( hdc , 50 ,50 , NULL ); 	LineTo( hdc , 50, 400 ); 	LineTo( hdc , 400, 400 ); 	Arc ( hdc , 100 , 100 , 300 , 300 , 0 , 0 , 0 , 0 ); 	ReleaseDC( h , hdc ); 	return 0; }

用turbo c, 有专门绘图的函数。


Question: csp考试 2019年3月的第二题 24点问题 为什么我的程序可以跑起来而且输出结果也正确，但系统老是显示错误

把显示什么错误发出来？

显示运行错误，然后得零分


Question: 哪里错了

单步调试就知道了。

引用 1 楼 你皮你自己 的回复：算法错了，小循环s还没有完成阶乘就加到sum上了，大循环sum在里面不停被更新为零，输出的位置也不对呀小声bb：希望我没说错s一直在累乘其实


Question: hlog 定义带参宏替换hlog_format函数时，VS2015提示未找到用户定义的文本运算符

引用 1 楼 user-1 的回复:这个没用过呢，能不能说清楚是什么环境？ XXXX(fmt, ...)         hlog_format(HLOG_LEVEL_DEBUG, "xxx", "<%d>\t<%s>,"fmt, __LINE__, __FUNCTION__, ##__VA_ARGS__)  就是这样定义的宏 然后一直报错 编译没问题 但是满屏的红点点

引用 4 楼 weixin_36946549 的回复:[quote=引用 3 楼 user-1 的回复:] 能不能完整的截屏一下呢？代码都看不完整 代码中引用这个宏就会有红色波浪线 提示未找到用户定义的文本运算符 [/quote]编译运行是没问题的

引用 3 楼 user-1 的回复:能不能完整的截屏一下呢？代码都看不完整 代码中引用这个宏就会有红色波浪线 提示未找到用户定义的文本运算符

能不能完整的截屏一下呢？代码都看不完整

这个没用过呢，能不能说清楚是什么环境？


Question: 大佬帮我康康

哦哦，忘记了你这是C，不是C++

error C2275错误，是变量的定义位置不对，应该在函数块的最前面（自己解决了，棒棒）

貌似没什么问题的，这就帮不上忙了

引用 3 楼 user-2的回复:&去掉试试？我感觉右边本身就是地址啊。 去掉了也一样报错，数组元素不是地址吧，数组名才是地址

&去掉试试？我感觉右边本身就是地址啊。

这是前面的定义哦，再帮我康康。

查看一下头文件，或者直接查SqList定义，找到data域，这个就是DataType类型数组


Question: 循环嵌套c语言

楼主应该是刚刚上手没多久吧，这种嵌套很基础，也很重要，建议自己研究，有问题贴码找人解决。

楼主，来这里尽量带着代码，最好不要伸手。哪怕你代码写得再不好，纠正了、运行了，就会在这个过程中进步，如果总是别人帮你写好了，那你能得到什么呢？除非你只是想让人帮你做作业，当然也不排除坛子里有某些好心人能有求必应，不过私以为这不是在帮你。


Question: 求帮助

引用 5 楼 sky.？的回复:我这是算一元2次方程，有2个解的 删除一个后面的参数就行，不影响你有两个解吧

求一元二次方程的实数根：https://blog.csdn.net/pfdvnah/article/details/87460351

有-b吗？应该改为-1*b

我这是算一元2次方程，有2个解的

感觉删除哪一个都可以！

删除x1,你上一步不是已经让x2=x1了嘛，

引用 1 楼 三山丶 的回复：你的printf那一栏(27栏)，你只有一个%d，但是你设置了两个参数(x1,x2)那要怎么解决


Question: c语言结构体练习第二个学生信息没办法输入姓名直接跳到性别了

引用 6 楼 自信男孩的回复:scanf_s("%d", &a); 这个是%d格式输入，输入1之后，a是1，而不是'1'，明白了吗？  可以吧case '1'改成case 1试试。  也可以把%d改成%c，但是这种改法比较麻烦，因为在这条scanf_s之前还得加一条getchar(); 建议用上一种方法，case 1 知道了，谢谢，还是到了内存问题，基础没打严实

引用 4 楼 Gnglas的回复:[quote=引用 3 楼 自信男孩的回复:]#include<stdio.h> int main() {     struct Studens     {         char name[60];         char gender[5];         int studen_number;         float grade;     }studen1,studen2;     puts("录入first学生信息：");     puts("");     printf("学生名字:");     fgets(studen1.name, 60, stdin);     puts(" ");     printf("学生性别:");     fgets(studen1.gender, 5, stdin);     puts(" ");     printf("学号：");     scanf_s("%d", &studen1.studen_number);     puts(" ");     printf("输入学生成绩：");     scanf_s("%f", &studen1.grade);     puts("");     puts("录入second学生信息：");     puts("");     getchar();    //for '\n'     printf("学生名字:");     fgets(studen2.name, 60, stdin);     puts(" ");     printf("学生性别:");     fgets(studen2.gender, 5, stdin);     puts(" ");     printf("学号："); scanf_s("%d", &studen2.studen_number);     puts(" ");     printf("输入学生成绩："); scanf_s("%f", &studen2.grade);     printf("是否比较两个学生的成绩：");     printf("是按1\t否按2\n");     int a;     scanf_s("%d", &a);     switch (a)     {         case '1':             if (studen1.grade > studen2.grade)             {                 printf("名字：%s\n性别：%s\n学号：%d\n成绩:%.2f\n", studen1.name, studen1.gender, studen1.studen_number, studen1.grade);              }             if(studen1.grade < studen2.grade)             {                 printf("名字：%s\n性别：%s\n学号：%d\n成绩:%.2f\n", studen2.name, studen2.gender, studen2.studen_number, studen2.grade);              }break;           default:printf("滚吧"); break;     }     return 0; }  加一条语句:getchar();如上代码。  因为fgets是遇到'\n'就会直接返回，由于输入完第一个学生信息时（最后一个学生信息用的是scanf_s）， '\n'还在输入缓存里，因此fgets遇到他直接返回了。  你可能会问，为什么fgets不会呢，因为fgets可能会把'\n'放到输入缓存里，比如输入name时，用的fgets 若输入的字符串小于60，那么会将'\n'存到name里，在'\0'之前，即前一个字符就是'\n'，若输入的字符 串大于等于59时，'\n'就不存在name里。  可以去网上查一下fgets和scanf_s 谢谢大佬，我知道了。。。。。。[/quote] 大佬还有个问题，switch好像也有问题，我输入1的时候直接调到最后输出"滚吧"

引用 3 楼 自信男孩的回复:#include<stdio.h> int main() {     struct Studens     {         char name[60];         char gender[5];         int studen_number;         float grade;     }studen1,studen2;     puts("录入first学生信息：");     puts("");     printf("学生名字:");     fgets(studen1.name, 60, stdin);     puts(" ");     printf("学生性别:");     fgets(studen1.gender, 5, stdin);     puts(" ");     printf("学号：");     scanf_s("%d", &studen1.studen_number);     puts(" ");     printf("输入学生成绩：");     scanf_s("%f", &studen1.grade);     puts("");     puts("录入second学生信息：");     puts("");     getchar();    //for '\n'     printf("学生名字:");     fgets(studen2.name, 60, stdin);     puts(" ");     printf("学生性别:");     fgets(studen2.gender, 5, stdin);     puts(" ");     printf("学号："); scanf_s("%d", &studen2.studen_number);     puts(" ");     printf("输入学生成绩："); scanf_s("%f", &studen2.grade);     printf("是否比较两个学生的成绩：");     printf("是按1\t否按2\n");     int a;     scanf_s("%d", &a);     switch (a)     {         case '1':             if (studen1.grade > studen2.grade)             {                 printf("名字：%s\n性别：%s\n学号：%d\n成绩:%.2f\n", studen1.name, studen1.gender, studen1.studen_number, studen1.grade);              }             if(studen1.grade < studen2.grade)             {                 printf("名字：%s\n性别：%s\n学号：%d\n成绩:%.2f\n", studen2.name, studen2.gender, studen2.studen_number, studen2.grade);              }break;           default:printf("滚吧"); break;     }     return 0; }  加一条语句:getchar();如上代码。  因为fgets是遇到'\n'就会直接返回，由于输入完第一个学生信息时（最后一个学生信息用的是scanf_s）， '\n'还在输入缓存里，因此fgets遇到他直接返回了。  你可能会问，为什么fgets不会呢，因为fgets可能会把'\n'放到输入缓存里，比如输入name时，用的fgets 若输入的字符串小于60，那么会将'\n'存到name里，在'\0'之前，即前一个字符就是'\n'，若输入的字符 串大于等于59时，'\n'就不存在name里。  可以去网上查一下fgets和scanf_s 谢谢大佬，我知道了。。。。。。

删掉puts函数里面的那一个空格，试一下

有没有人帮忙看下，不知道什么情况

我用vs2019按你的刚发改成getcher()报错，然后我根据你的思路把     fgets(studen2.name, 2, stdin);这段代码放到第二个学生信息前面发现也可以通过，而且我只给他分配了两个字节的内存这样也不会内存膨胀

我用vs2019按你的刚发改成getcher()报错，然后我把     fgets(studen2.name, 2, stdin);这段代码放到第二个学生信息前面发现也可以通过，而且我只给他分配了两个字节的内存这样也不会内存膨胀


Question: 文件输入输出的一道习题

原因是：在 || &&等判断过程中，只要条件满足就不会进行下一步的判断。例如： A || B, 若A为真，则B并不会执行； A && B  若A为假，B同样不会执行。 因此，解决方法也就是将两个fget()放入到while循环体中，加入两个标志量进行循环条件判断即可。 将源代码中的while{}循环体替换为如下即可。  int flag1 = 0;     int flag2 = 0;     while(!flag2 || !flag1)     {         if(fgets(line1, 300, fptr1)){             fputs(line1, stdout);         }else{             flag1 = 1;         }          if(fgets(line2, 300, fptr2)){             fputs(line2, stdout);         }else{             flag2 = 1;         }     }


Question: 基础问题

提醒：scanf是开源的。

这个跟int是2字节还是4字节并没有多大关系，因为即便int是2字节，执行scanf("%d%d",&a,&b) ;语句时输入1234567890，变量b也得不到值，同时变量a也得不到1234567890！ 执行scanf("%d%d",&a,&b) ;时，输入a、b的值，只能由空白符分隔开。输入1234567890后，一定是试图将1234567890给变量a，然后再等待输入另一个整型值给b。假设int是2字节（当然只是假设），那其最大值为32767，输入的1234567890远远大于32767，此时变量a也就不可能等于1234567890！也不会是32767。 总之系统不可能因为输入的值大于a所能取的最大值，就只取输入的值的某一段，这是一种臆想。 当然，诚如楼上大家所说，还是在Turbo C的年代，int的值域是-32768至32767。

引用 2 楼 qq_36005572 的回复:但是有符号基本整型的上限是32767吗 是否还停留在int为16bit的时代里。现在的主流编译器都是32bit的吧。

哦，谢谢，跟不时代了

a的上限比它小也会直接全部读取吗？

引用 2 楼 qq_36005572 的回复:但是有符号基本整型的上限是32767吗 那是16位的编译器，现在主流的都是32位的编译器

引用 2 楼 qq_36005572 的回复:但是有符号基本整型的上限是32767吗 int的取值范围为: -2^31——2^31-1,即-2147483648——2147483647

%d是int型  1234567890全部输入到a了，并且要区分给a还是b输入值，必须输入一个后加个空格。

但是有符号基本整型的上限是32767吗

a 会读取全部（连续的数字），b 什么都没读取到，并且程序还会等你继续输入。因为它认为你只输入了一个数。


Question: 各位神看一下

引用 3 楼 覆陇黄 的回复：[quote=引用 2 楼 wowpH 的回复:] 第二个循环里面再套一层循环输出一定数量的空格，然后里层循环外面输出笑脸就可以了。 //such as： for (i=0;i<2;i++) {prinft("%c\n",2); for(j=0;j<9;j++) printf(" ");}  //楼主你的意思是....... 笑脸的ASCII码是2 吗，学到就是赚到[/quote].....这个毛病我得改了

引用 8 楼 狂风乱吼 的回复:大神putchar（）是什么函数，本人菜鸟一枚，怎么用这个不是本题的重点，重点是中间的那个循环。  另外：putchar，从名字就可以看出来，put（输出）char（字符）。它就是一个输出单个字符的函数。你换成 printf("#"); 效果是一样的。

引用 5 楼 wowpH 的回复: 大神putchar（）是什么函数，本人菜鸟一枚，怎么用

引用 6 楼 狂风乱吼 的回复:[quote=引用 3 楼 覆陇黄 的回复:] [quote=引用 2 楼 wowpH 的回复:] 第二个循环里面再套一层循环输出一定数量的空格，然后里层循环外面输出笑脸就可以了。 //such as： for (i=0;i<2;i++) {prinft("%c\n",2); for(j=0;j<9;j++) printf(" ");}  //楼主你的意思是....... 笑脸的ASCII码是2 吗，学到就是赚到[/quote] 对是2，那大神把源码奉上[/quote]  啥？意思

引用 3 楼 覆陇黄 的回复:[quote=引用 2 楼 wowpH 的回复:] 第二个循环里面再套一层循环输出一定数量的空格，然后里层循环外面输出笑脸就可以了。 //such as： for (i=0;i<2;i++) {prinft("%c\n",2); for(j=0;j<9;j++) printf(" ");}  //楼主你的意思是....... 笑脸的ASCII码是2 吗，学到就是赚到[/quote] 对是2，那大神把源码奉上

数组的话，感觉数组麻烦了就。 定义一个数组a，包含首尾俩笑脸，中间一堆空格？然后循环输出吗。 楼主有什么想法，恳请指教，我没了、、

引用 2 楼 wowpH 的回复:第二个循环里面再套一层循环输出一定数量的空格，然后里层循环外面输出笑脸就可以了。 //such as： for (i=0;i<2;i++) {prinft("%c\n",2); for(j=0;j<9;j++) printf(" ");}  //楼主你的意思是....... 笑脸的ASCII码是2 吗，学到就是赚到

第一列的笑脸前面加上适当多的空格不就好了嘛。。。。。。


Question: 在驱动中测试函数？

补充一下, 我记得教材上叫做“驱动模块"和"桩模块“，驱动模块指调用被测函数的模块，桩模块指的是提供被测函数调用的其他模块, 因为还没有开发出来, 可以先写一个简单的假的函数供被测模块调用。

此"驱动程序“非彼“驱动程序”。这里的驱动程序是测试术语，简单地说就是写一个程序调用这个函数，测试各种情况下的输出是否正确。


Question: 一维数组冒泡排序法从小到大排列

试着把项目属性→清单工具→输入输出→嵌入清单该成否试一下

估计项目类型有问题

https://blog.csdn.net/weixin_39447690/article/details/86550162 参考这个，有源代码可以参考

我用#CSDN#这个app发现了有技术含量的博客，小伙伴们求同去《第一（NUM_ONE）:冒泡排序(BubbleSort)》, 一起来围观吧 https://blog.csdn.net/weixin_39447690/article/details/86550162 可以参考这个，并且把原理说了

引用 4 楼 覆陇黄 的回复:这个应该没问题，不知道加加for嵌套时的括号能不能运行成功。 还有它程序最后的两个getchar（）是干啥的，你知道吗抱歉，我弄错了。他的格式太乱了。

引用 2 楼 wowpH 的回复:最里层的 for 循环的循环变量不能用 i 了。因为最外层已经用过了。  这个应该没问题，不知道加加for嵌套时的括号能不能运行成功。 还有它程序最后的两个getchar（）是干啥的，你知道吗

for 括号全部加上试试。

最里层的 for 循环的循环变量不能用 i 了。因为最外层已经用过了。

引用 楼主 jian995229的回复:新手上路，求大神指点，非常感谢 问下为什么运行不了了


Question: c

这个是没有理解指针和内存的关系吧

引用 4 楼 wowpH 的回复:将第10行替换成  p = a;  哎，经常用 Java，C的指针都快忘记了。  楼主（发帖的）的错误是“教科书式”的，一不小心就忘了。 不过以后应该就记牢了

将第10行替换成  p = a;  哎，经常用 Java，C的指针都快忘记了。

引用 2 楼 阿大古 古古古的回复:void main(void) { 	int *p; 	int i , a[10]; 	p = a; 	for (i = 0; i < 10; i++) 	{ 		scanf("%d", &a[i]); 	} 	printf("\n"); 	for (i = 0; i < 10; i++) 	{ 		printf("%d\t", *p++); 	} 	system("pause"); } 你第一个循环违背了他的初衷，他应该是想用指针操作数组，而不是直接输入到a中。

你第一个循环结束后p就指向了11这个下标,越界了.


Question: 统计字符串的长度问题

引用 4 楼 自信男孩 的回复:while (s != '\0') p++; 改成：  while (p++ != '\0') ;  上一个有误： while (*p++ != '\0') ;

已经改好了，谢谢二位

引用 1 楼 真相重于对错 的回复:while (s != '\0') p++; 这段代码s并没有改变所以一直不等于‘\0’,死循环， 另外比较不是s!='\0'是*s!='\0'*p != 0


Question: 这段代码输出结果是什么？每部分代码是什么意思？

a<<2这条代码语句没意义，什么事也没做。

代码已经了解了  谢谢各位的评论

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

（math. pow（2,3））可能是宏定义   (int)是强制转换为整形   (0xff)是十六进制的数   &是位与操作 a<<2是左移两位


Question: 请问这个怎么搞

你没给这俩函数写定义

C中的函必须先定义后使用，由于会存在相互调用，就可采用先声明后定义，声明要放在定义和调用之前，同时声明和定义时要求返回值相同，函数名相同（C是区分大小写的），形参类型和顺序相同

jolly和deny在哪定义的？编译提示已经很明确了。这两个也不是系统函数的

1.main函数中调用jolly时，你使用的是jolly("For he's...."),jolly使用时时有参数的，而你在第二行声明的时候jolly()是没有参数的。 2.deny同上 3.jolly和deny只有声明没有实现 可以修改下：  #include <stdio.h> void jolly(char *pStr) {     return; }  void deny(char *pStr) {     return; }


Question: C语言二级程序设计题

引用 4 楼 覆陇黄 的回复:学到了，我考虑的太少了 请教一下：那个while（*s！=0）可以吗 需不需要写成while（*s！=‘\0’） 效果应该是一样的。 *s!='\0' 更容易理解些。

int func(char *s) {     int num=0;     /* s为空或者字符串长度为0，则单词数为0 */     if (s==null || *s==0) {          return num;     }    while (*s !=0) {  /* 循环直到字符串末尾 */         while (' ' !=*s ) s++ ；/* 找单词,  ；按照约定字符串第一个字母不应该是空格 */         num++;  /*单词数加1 */         while (' '==*s) s++ ; /*跳过空格到下一个单词*/    }    return num; }  题目没有规定遇到小写字母之外的怎么办，就简化处理认为输入只有小写字母和空格。 这是我现写的没有自己运行，不保证没问题。

s++！=‘\0’   时 num++

不会就选C.....（开个玩笑）


Question: 不会用C语言编小游戏

引用 4 楼 自信男孩的回复:由易到难，你这个跨度有点大。还不会走就要跑是不是有点超前？ 我还以为贪吃蛇是比较简单的程序，原来属于“跑”的吗，那我现在该练点啥呀

由易到难，你这个跨度有点大。还不会走就要跑是不是有点超前？

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

首先把那本谭浩强《C语言程序设计》学通，然后再做画面游戏吧。 贪吃蛇可以用贴图方式实现，这个我有贴图框架，只要你编程基础没问题，很容易实现 https://download.csdn.net/download/zsrmouse/4574138

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

基础的语法学好之后，多看代码，多练习，然后你就会了

要怎样才能看懂并且编程，求大佬


Question: C语言

楼主最好在本地找个老师带，效果比较好一点

怎么带？

可以在B站上搜索C语言的教学视频看，比自己看书学得更快些


Question: CreateBitmap所使用的位图数组为什么是WORD型的？

用来存储每行像素数据的字节数 和 每行多少个像素 不是一回事！

引用 2 楼 user-2 的回复:MSND  lpBits A pointer to an array of color data used to set the colors in a rectangle of pixels. Each scan line in the rectangle must be word aligned (scan lines that are not word aligned must be padded with zeros).  说白了就是为了内存对齐，最终目的还是提高效率，如楼上所说 通过多次比对，总算得出结论了，每一行至少要2字节，超出2字节了以2字节自增，所以8x8及以下，每行都至少会空一个字节，9x9则不空，假如是20x20，每一行4字节，空1字节，25x25则不空，33x33，每一行6字节，空1字节。

早期CPU读写显存不降低效率要求的。我猜。

引用 2 楼 user-2 的回复:MSND  lpBits A pointer to an array of color data used to set the colors in a rectangle of pixels. Each scan line in the rectangle must be word aligned (scan lines that are not word aligned must be padded with zeros).  说白了就是为了内存对齐，最终目的还是提高效率，如楼上所说 我发现了一件奇怪的事，用CreateBitmap给CreatePatternBrush提高位图句柄时，如果8x8的图，数组需要是WORD，但我又测试了32x32的图，WORD却错了，用unsigned char反而对了？为什么会这样？


Question: 背景画刷为方格线条时，如何设置方格中为透明？

用GDI不用GDIplus就这么麻烦。 用GDI的好处是速度快。

BLENDFUNCTION  The BLENDFUNCTION structure controls blending by specifying the blending functions for source and destination bitmaps.   typedef struct _BLENDFUNCTION {     BYTE     BlendOp;     BYTE     BlendFlags;     BYTE     SourceConstantAlpha;     BYTE     AlphaFormat; }BLENDFUNCTION, *PBLENDFUNCTION, *LPBLENDFUNCTION;   Members  BlendOp  Specifies the source blend operation. Currently, the only source and destination blend operation that has been defined is AC_SRC_OVER. For details, see the following Remarks section.  BlendFlags  Must be zero.  SourceConstantAlpha  Specifies an alpha transparency value to be used on the entire source bitmap. The SourceConstantAlpha value is combined with any per-pixel alpha values in the source bitmap. If you set SourceConstantAlpha to 0, it is assumed that your image is transparent. Set the SourceConstantAlpha value to 255 (opaque) when you only want to use per-pixel alpha values.  AlphaFormat  This member controls the way the source and destination bitmaps are interpreted. AlphaFormat has the following value: Value Meaning  AC_SRC_ALPHA  This flag is set when the bitmap has an Alpha channel.     Remarks When the AC_SRC_OVER operation is used, the source bitmap is placed over the destination bitmap based on the alpha values of the source pixels.   If the source bitmap has no per-pixel alpha value, the blend is based on a constant source alpha value as shown in the following table.  Dst.Red    = Src.Red  * ConstantAlpha + (1 - ConstantAlpha) * Dst.Red   Dst.Green    = Src.Green    * ConstantAlpha + (1 - ConstantAlpha) * Dst.Green   Dst.Blue    = Src.Blue  * ConstantAlpha + (1 - ConstantAlpha) * Dst.Blue     If the source bitmap has per-pixel alpha, the constant alpha is not used (0xff) as shown in the following table.  Dst.Red  = Src.Red  + (1 - Src.Alpha) * Dst.Red   Dst.Green    = Src.Green    + (1 - Src.Alpha) * Dst.Green   Dst.Blue  = Src.Blue  + (1 - Src.Alpha) * Dst.Blue     If the destination bitmap has an alpha channel, then:   Dest.alpha    = Src.Alpha    + (1 - SrcAlpha) * Dst.Alpha     If the source has pixel per alpha, the constant alpha is not 0xff.  Dst.Red    = Src.Red   - Src.Red = Src.Red * ConstantAlpha;    Dst.Red  = Src.Red   - Src.Green = Src.Green * ConstantAlpha ;   Dst.Red    = Src.Red   - Src.Blue = Src.Blue * ConstantAlpha ;   Dst.Red   =  Src.Red  + (1 - Src.Alpha) * Dst.Red   Dst.Red   =  Src.Green     + (1 - Src.Alpha) * Dst.Green   Dst.Red   =  Src.Blue  + (1 - Src.Alpha) * Dst.Blue     QuickInfo   Windows NT: Requires version 5.0 or later.   Windows: Requires Windows 98 or later.   Windows CE: Unsupported.   Header: Declared in wingdi.h.  See Also Bitmaps Overview, Bitmap Structures

AlphaBlend  The AlphaBlend function displays bitmaps that have transparent or semitransparent pixels.  AlphaBlend(   HDC hdcDest,   int nXOriginDest,   int nYOriginDest,   int nWidthDest,   int hHeightDest,   HDC hdcSrc,   int nXOriginSrc,   int nYOriginSrc,   int nWidthSrc,   int nHeightSrc,   BLENDFUNCTION blendFunction );   Parameter hdcDest  Handle to the destination device context.  nXOriginDest  Specifies the x-coordinate, in logical units, of the upper-left corner of the destination rectangle.  nYOriginDest  Specifies the y-coordinate, in logical units, of the upper-left corner of the destination rectangle.  nWidthDest  Specifies the width, in logical units, of the destination rectangle.  hHeightDset  Handle to the height, in logical units, of the destination rectangle.  hdcSrc  Handle to the source device context.  nXOriginSrc  Specifies the x-coordinate, in logical units, of the upper-left corner of the source rectangle.  nYOriginSrc  Specifies the y-coordinate, in logical units, of the upper-left corner of the source rectangle.  nWidthSrc  Specifies the width, in logical units, of the source rectangle.  nHeightSrc  Specifies the height, in logical units, of the source rectangle.  blendFunction  Specifies the alpha blending function for source and destination bitmaps, a global alpha value to be applied to the entire source bitmap, and format information for the source bitmap. The source and destination blend functions are currently limited to AC_SRC_OVER. See the BLENDFUNCTION and EMRALPHABLEND structures.  Return Values If the function succeeds, the return value is TRUE.  If the function fails, the return value is FALSE.   Windows NT: To get extended error information, callGetLastError.   Remarks If the source rectangle and destination rectangle are not the same size, the source bitmap is stretched to match the destination rectangle. If the SetStretchBltMode function is used, the iStretchMode value is BLACKONWHITE and WHITEONBLACK; the iStretchMode value is automatically converted to COLORONCOLOR for this function.   The destination coordinates are transformed by using the transformation currently specified for the destination device context. The source coordinates are transformed by using the transformation currently specified for the source device context.   An error occurs (and the function returns FALSE) if the source device context identifies an enhanced metafile device context.   If destination and source bitmaps do not have the same color format, AlphaBlend converts the source bitmap to match the destination bitmap.   AlphaBlend does not support mirroring. If either the width or height of the source or destination is negative, this call will fail.   Note: The SourceConstantaAlpha member of BLENDFUNCTION specifies an alpha transparancy value to be used on the entire source bitmap. The SourceConstantAlpha value is combined with any per-pixel alpha values. If you set SourceConstantAlpha to 0, it is assumed that your image is transparent. Set the SourceConstantAlpha value to 255 (indicates that the image is opaque) when you only want to use per-pixel alpha values.   QuickInfo   Windows NT: Requires version 5.0 or later.   Windows: Requires Windows 98 or later.   Windows CE: Unsupported.   Header: Declared in wingdi.h.   Import Library: Included as a resource in msimg32.dll.  See Also Bitmaps Overview, Bitmap Functions

透明应该改用GDIplus，我觉得。

引用 楼主 六道佩恩 的回复:背景画刷为HS_CROSS时，方格中的颜色是背景色，通过SetBkColor设置，但通过SetBkMode设置背景透明却无效？为什么？能否做到这种方格线条中间透明的背景效果吗？ 对透明的理解：在窗体或控件输出的字符串或图形是有背景色的。而窗体或控件也是有背景色的。这两种背景色一般是不同的， 这样输出图形或字符串时，两种背景（窗体或控件的背景色、符串或图形的背景色）重叠在一起了，影响美观，为了不让这两种背景重叠，可以设置背景模式为TRANSPARENT（透明的），即让输出的字符串或图形的背景色不可见。可以这样理解：把输出的字符串或图形的背景色看成是一物体，窗体或控件看成另一物体，字符串或图形在窗体或控件前面挡住窗体或控件了（因为输出 的字符串或图形是画在窗体或控件上的，所以可以这么类比），但是透过字符串或图形能看到窗体或控件。即字符串或图形的背 景色所代表的物体是透明的。  画刷为HS_CROSS时，系统用这个位图去刷背景，你说的透明和SetBkMode的透明是两回事 你的要求我觉得用SetBkMode是无法完成的 楼上说的TransparentBlt，关键在最后一个参数，如何将源像素和背景像素相互作用后显示出来

TransparentBlt [This is preliminary documentation and subject to change.]   The TransparentBlt function performs a bit-block transfer of the color data corresponding to a rectangle of pixels from the specified source device context into a destination device context.  BOOL TransparentBlt(   HDC hdcDest,   int nXOriginDest,   int nYOriginDest,   int nWidthDest,   int hHeightDest,   HDC hdcSrc,   int nXOriginSrc,   int nYOriginSrc,   int nWidthSrc,   int nHeightSrc,   UINT crTransparent );   Parameters hdcDest  Handle to the destination device context.  nXOriginDest  Specifies the x-coordinate, in logical units, of the upper-left corner of the destination rectangle.  nYOriginDest  Specifies the y-coordinate, in logical units, of the upper-left corner of the destination rectangle.  nWidthDest  Specifies the width, in logical units, of the destination rectangle.  hHeightDest  Handle to the height, in logical units, of the destination rectangle.  hdcSrc  Handle to the source device context.  nXOriginSrc  Specifies the x-coordinate, in logical units, of the source rectangle.  nYOriginSrc  Specifies the y-coordinate, in logical units, of the source rectangle.  nWidthSrc  Specifies the width, in logical units, of the source rectangle.  nHeightSrc  Specifies the height, in logical units, of the source rectangle.  crTransparent  The RGB color in the source bitmap to treat as transparent.  Return Values If the function succeeds, the return value is TRUE.  If the function fails, the return value is FALSE.   Windows NT: To get extended error information, callGetLastError.   Remarks The TransparentBlt function is supported for source bitmaps of 4 bits per pixel and 8 bits per pixel. Use AlphaBlend to specify 32-bit per pixel bitmaps with transparency.   If the source and destination rectangles are not the same size, the source bitmap is stretched to match the destination rectangle. When the SetStretchBltMode function is used, the iStretchMode modes of BLACKONWHITE and WHITEONBLACK are converted to COLORONCOLOR for the TransparentBlt function.   The destination device context specifies the transformation type for the destination coordinates. The source device context specifies the transformation type for the source coordinates.   TransparentBlt does not mirror a bitmap if either the width or height, of either the source or destination, is negative.   QuickInfo   Windows NT: Requires version 5.0 or later.   Windows: Requires Windows 98 or later.   Windows CE: Unsupported.   Header: Declared in wingdi.h.   Import Library: Included as a resource in msimg32.dll.  See Also Bitmaps Overview, Bitmap Functions, AlphaBlend, SetStretchBltMode     ?

引用 2 楼 赵4老师 的回复:透明应该改用GDIplus，我觉得。 gdiplus好像都是C++的函数呀？

#include "stdio.h" #include "windows.h" LRESULT MyProc( HWND h , UINT msg , WPARAM wParam , LPARAM lParam ) { 	switch( msg ) 	{		 		case WM_PAINT: 			{ 				HDC hdc = GetDC( h );			 				LineTo( hdc, 100 ,100 ); 				SetBkMode( hdc , 1 ); 				SendMessage( h , WM_ERASEBKGND , (WPARAM)hdc , 0 );	 				ReleaseDC( h , hdc ); 				ValidateRect( h , NULL );  			} 			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			=LoadCursor(NULL, IDC_ARROW);		 	a->hbrBackground	= CreateHatchBrush ( HS_CROSS , RGB(255,0,0) ); 	a->lpszMenuName	=NULL;	 	a->lpszClassName	=ClassName;	 } ATOM  RegMyClass(  const char* name , WNDPROC  proc) { 	WNDCLASS MyClass; 	SetWNDCLASS ( &MyClass, proc, name );	//处理函数为MyProc,类名为"MyClass" 	return RegisterClass( &MyClass ); } int main( void ) { 	RegMyClass( "MyClass" , MyProc ); 	CreateWindow( "MyClass" , "画刷" ,WS_OVERLAPPEDWINDOW|WS_VISIBLE,  				300,400,500,500,NULL,NULL,NULL,NULL ); 	MSG msg; 	while( GetMessage( &msg , NULL, 0,0 ) ) 	{ 		DispatchMessage( &msg ); 	} 	return 0; }  如果设置透明成功的话，应该能显示红色方格覆盖在一条黑色的线条上，但没有，说明没有实现透明


Question: 求助，用c语言写出一个小学生速算训练的程序

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


Question: 一元二次方程的解  求指错

引用 6 楼 菅田的古着与牛奶 的回复:[quote=引用 4 楼 自信男孩的回复:][quote=引用 2 楼 菅田的古着与牛奶 的回复:] [quote=引用 1 楼 自信男孩的回复:]	if(tr=0) 和 	if(c=0) 看出这两个地方的问题了吗？ 这里改了，可是还是提示 expected'}'before 'else '[/quote]  else if(tr<0); 这个问题看出来了吗？  代码格式注意一下[/quote] 这里有什么问题吗     。 [/quote] 没问题吗? 这儿的分号不是问题？

引用 4 楼 自信男孩的回复:[quote=引用 2 楼 菅田的古着与牛奶 的回复:] [quote=引用 1 楼 自信男孩的回复:]	if(tr=0) 和 	if(c=0) 看出这两个地方的问题了吗？ 这里改了，可是还是提示 expected'}'before 'else '[/quote]  else if(tr<0); 这个问题看出来了吗？  代码格式注意一下[/quote] 这里有什么问题吗     。

基本的编译问题如果不熟练解决，基础有点弱，需要加强

引用 2 楼 菅田的古着与牛奶 的回复:[quote=引用 1 楼 自信男孩的回复:]	if(tr=0) 和 	if(c=0) 看出这两个地方的问题了吗？ 这里改了，可是还是提示 expected'}'before 'else '[/quote]  else if(tr<0); 这个问题看出来了吗？  代码格式注意一下

最下面少了个  }  ,        养成习惯 括号缩进对齐不行嘛

引用 1 楼 自信男孩的回复:	if(tr=0) 和 	if(c=0) 看出这两个地方的问题了吗？ 这里改了，可是还是提示 expected'}'before 'else '

if(tr=0) 和 	if(c=0) 看出这两个地方的问题了吗？


Question: 每一个汉字都拥有ascii码吗

了解一下编码格式，ascii码只是其中一种，ascii长度是一个字节，一个字节上限是256个，但ascii只用了一半，128个，还有两个字节的编码、三个、四个字节的都有，中国常用的gbk或者utf-8等，如果你写大的工程的话需要先配置编码格式，如果编写时配置的和使用者打开的两方编码不一致，就会遇到乱码

[quote=引用 15 楼 littleloveyue 的回复:] 对啊，你可以在线转码。 广告都打到这里了，佩服

应该有吧，算是间接的，将汉字编码对应的两个字节转换成ASCII，勉强算是汉字的ASCII码吧

一般英文是单字节的，其他语言都是多字节。如果每个汉字都有Ascall码，那不有上万个，听着就不靠谱

汉字没有，只有数学和英文字母，还有一些符号

引用 8 楼 通信小卒 的回复:[quote=引用 7 楼 赵4老师的回复:][quote=引用 6 楼 通信小卒 的回复:] 每个汉子用两个字符表示，也就是两个ascii，占用两个字节 不见得： #pragma comment(lib,"user32") #pragma comment(lib,"gdi32") #include <conio.h> #include <stdio.h> #include <stdlib.h> #include <windows.h> extern "C" HWND WINAPI GetConsoleWindow(); void HideTheCursor() {     CONSOLE_CURSOR_INFO cciCursor;     HANDLE hStdOut = GetStdHandle(STD_OUTPUT_HANDLE);      if(GetConsoleCursorInfo(hStdOut, &cciCursor)) {         cciCursor.bVisible = FALSE;         SetConsoleCursorInfo(hStdOut, &cciCursor);     } } void ShowTheCursor() {     CONSOLE_CURSOR_INFO cciCursor;     HANDLE hStdOut = GetStdHandle(STD_OUTPUT_HANDLE);      if(GetConsoleCursorInfo(hStdOut, &cciCursor)) {         cciCursor.bVisible = TRUE;         SetConsoleCursorInfo(hStdOut, &cciCursor);     } } int main() {     HWND  hwnd;     HDC   hdc;     HFONT hfont;     wchar_t wc[2];      system("color F0");     system("cls");     HideTheCursor();     hwnd  = GetConsoleWindow();     hdc   = GetDC(hwnd);     hfont = CreateFont(48,0,0,0,0,0,0,0,GB2312_CHARSET ,0,0,0,0,"宋体-方正超大字符集");     SelectObject(hdc,hfont);     wc[0]=0xD854u;     wc[1]=0xDC00u;     TextOutW(hdc,10,10,wc,2);     DeleteObject(hfont);     ReleaseDC(hwnd,hdc);     getch();     system("color 07");     system("cls");     ShowTheCursor();     return 0; } #if 0 代理项或代理项对是一对共同表示单个字符的 16 位 Unicode 编码值。需要记住的关键一点是： 代理项对实际上是 32 位单个字符，不能再假定一个 16 位 Unicode 编码值正好映射到一个字符。  使用代理项对 代理项对的第一个值是高代理项，包含介于 U+D800 到 U+DBFF 范围内的 16 位代码值。 该对的第二个值是低代理项，包含介于 U+DC00 到 U+DFFF 范围内的值。通过使用代理项对， 16 位 Unicode 编码系统可以对已由 Unicode 标准定义的一百多万个其他字符 (220) 进行寻址。  在传递给 XmlTextWriter 方法的任何字符串中都可以使用代理项字符。不过，代理项字符在编写的 XML 中应该有效。例如，万维网联合会 (W3C) 建议不允许在元素或属性的名称中使用代理项字符。 如果字符串包含无效的代理项对，则引发异常。  另外，可以使用 WriteSurrogateCharEntity 写出与代理项对相对应的字符实体。字符实体以十六 进制格式写出，并用以下公式生成：  (highChar -0xD800) * 0x400 + (lowChar -0xDC00) + 0x10000  如果字符串包含无效的代理项对，则引发异常。下面的示例显示将代理项对作为输入的 WriteSurrogateCharEntity 方法。  C#复制  // The following line writes 𐀀. WriteSurrogateCharEntity ('\uDC00', '\uD800'); 下面的示例生成一个代理项对文件，将其加载到 XmlReader 中，并用新的文件名保存文件。 然后，原始文件和新文件被加载回应用程序的 XML 文档对象模型 (DOM) 结构中以进行比较。  C#复制  char lowChar, highChar; char [] charArray = new char[10]; FileStream targetFile = new FileStream("SurrogatePair.xml",       FileMode.Create, FileAccess.ReadWrite, FileShare.ReadWrite);  lowChar = Convert.ToChar(0xDC00); highChar = Convert.ToChar(0xD800); XmlTextWriter tw = new XmlTextWriter(targetFile, null); tw.Formatting = Formatting.Indented; tw.WriteStartElement("root"); tw.WriteStartAttribute("test", null); tw.WriteSurrogateCharEntity(lowChar, highChar); lowChar = Convert.ToChar(0xDC01); highChar = Convert.ToChar(0xD801); tw.WriteSurrogateCharEntity(lowChar, highChar); lowChar = Convert.ToChar(0xDFFF); highChar = Convert.ToChar(0xDBFF); tw.WriteSurrogateCharEntity(lowChar, highChar);  // Add 10 random surrogate pairs. // As Unicode, the high bytes are in lower // memory; for example, word 6A21 as 21 6A. // The high or low is in the logical sense. Random random = new Random(); for (int i = 0; i < 10; ++i) {       lowChar = Convert.ToChar(random.Next(0xDC00, 0xE000));       highChar = Convert.ToChar(random.Next(0xD800, 0xDC00));       charArray[i] = highChar;       charArray[++i] = lowChar; } tw.WriteChars(charArray, 0, charArray.Length);  for (int i = 0; i < 10; ++i) {       lowChar = Convert.ToChar(random.Next(0xDC00, 0xE000));       highChar = Convert.ToChar(random.Next(0xD800, 0xDC00));       tw.WriteSurrogateCharEntity(lowChar, highChar); }  tw.WriteEndAttribute(); tw.WriteEndElement(); tw.Flush(); tw.Close();  XmlTextReader r = new XmlTextReader("SurrogatePair.xml");  r.Read(); r.MoveToFirstAttribute(); targetFile = new FileStream("SurrogatePairFromReader.xml",        FileMode.Create, FileAccess.ReadWrite, FileShare.ReadWrite);  tw = new XmlTextWriter(targetFile, null); tw.Formatting = Formatting.Indented; tw.WriteStartElement("root"); tw.WriteStartAttribute("test", null); tw.WriteString(r.Value); tw.WriteEndAttribute(); tw.WriteEndElement(); tw.Flush(); tw.Close();  // Load both result files into the DOM and compare. XmlDocument doc1 = new XmlDocument(); XmlDocument doc2 = new XmlDocument(); doc1.Load("SurrogatePair.xml"); doc2.Load("SurrogatePairFromReader.xml"); if (doc1.InnerXml != doc2.InnerXml) {       Console.WriteLine("Surrogate Pair test case failed"); } 在使用 WriteChars 方法（一次写出一个缓冲区的数据）写出时，输入中的代理项对可能 会在一个缓冲区内被意外拆分。由于代理项值是定义完善的，如果 WriteChars 遇到来自 较低范围或者较高范围的 Unicode 值，它将该值标识为代理项对的一半。当遇到  WriteChars 将导致从拆分代理项对的缓冲区写入的情况时，将引发异常。使用   IsHighSurrogate 方法检查缓冲区是否以高代理项字符结束。如果缓冲区中的最后一个   字符不是高代理项，可以将该缓冲区传递给 WriteChars 方法。  请参见 概念 使用 XmlTextWriter 创建格式正确的 XML XmlTextWriter 的 XML 输出格式设置 XmlTextWriter 的命名空间功能  #endif [/quote] 代码比较长没看，你的结论是什么？[/quote] 运行一下看结果喽。

ASCII查询其名字就可知不是表示汉字的。另ASCII是7位，扩展的8位，故最多表示256个字符，而汉字少说数千，实际上数万，所以通常至少两个字节（16位）或更多才能表示。所以汉字没有ASCII吗！  实际上ASCII和上面很多出的各种码，都可以统称内码，ASCII一个字节，汉字最少2字节。

默认情况下，是扩展ASCII，第一个字节为负数时（或理解为127以上）是识别，加后一个字节共两个字节。你可以更改字符集，很多字符集都有汉字，比如UNICODE、UTF-8

引用 6 楼 通信小卒 的回复:每个汉子用两个字符表示，也就是两个ascii，占用两个字节 标准的ascii 只用到7位，高位不用，表示128个字符 而汉字编码 比如GB2312-80 ,每个汉字包含2个字节，高位置1 所以，不能说每个汉字由两个ascii组成

汉字的编码不只一种形式，如UNICODE等。不管哪种一种，一个汉字不会是对应一个ASCII码，很明显，ASCII码的值域是不可能表示得了汉字的。到于具体怎么编码或对应，不能的编码形式做法不同。 不管怎么样，在C/C++中，一个汉字不能看成一个字符，即用单引号括起一个汉字肯定有问题。

引用 7 楼 赵4老师的回复:[quote=引用 6 楼 通信小卒 的回复:] 每个汉子用两个字符表示，也就是两个ascii，占用两个字节 不见得： #pragma comment(lib,"user32") #pragma comment(lib,"gdi32") #include <conio.h> #include <stdio.h> #include <stdlib.h> #include <windows.h> extern "C" HWND WINAPI GetConsoleWindow(); void HideTheCursor() {     CONSOLE_CURSOR_INFO cciCursor;     HANDLE hStdOut = GetStdHandle(STD_OUTPUT_HANDLE);      if(GetConsoleCursorInfo(hStdOut, &cciCursor)) {         cciCursor.bVisible = FALSE;         SetConsoleCursorInfo(hStdOut, &cciCursor);     } } void ShowTheCursor() {     CONSOLE_CURSOR_INFO cciCursor;     HANDLE hStdOut = GetStdHandle(STD_OUTPUT_HANDLE);      if(GetConsoleCursorInfo(hStdOut, &cciCursor)) {         cciCursor.bVisible = TRUE;         SetConsoleCursorInfo(hStdOut, &cciCursor);     } } int main() {     HWND  hwnd;     HDC   hdc;     HFONT hfont;     wchar_t wc[2];      system("color F0");     system("cls");     HideTheCursor();     hwnd  = GetConsoleWindow();     hdc   = GetDC(hwnd);     hfont = CreateFont(48,0,0,0,0,0,0,0,GB2312_CHARSET ,0,0,0,0,"宋体-方正超大字符集");     SelectObject(hdc,hfont);     wc[0]=0xD854u;     wc[1]=0xDC00u;     TextOutW(hdc,10,10,wc,2);     DeleteObject(hfont);     ReleaseDC(hwnd,hdc);     getch();     system("color 07");     system("cls");     ShowTheCursor();     return 0; } #if 0 代理项或代理项对是一对共同表示单个字符的 16 位 Unicode 编码值。需要记住的关键一点是： 代理项对实际上是 32 位单个字符，不能再假定一个 16 位 Unicode 编码值正好映射到一个字符。  使用代理项对 代理项对的第一个值是高代理项，包含介于 U+D800 到 U+DBFF 范围内的 16 位代码值。 该对的第二个值是低代理项，包含介于 U+DC00 到 U+DFFF 范围内的值。通过使用代理项对， 16 位 Unicode 编码系统可以对已由 Unicode 标准定义的一百多万个其他字符 (220) 进行寻址。  在传递给 XmlTextWriter 方法的任何字符串中都可以使用代理项字符。不过，代理项字符在编写的 XML 中应该有效。例如，万维网联合会 (W3C) 建议不允许在元素或属性的名称中使用代理项字符。 如果字符串包含无效的代理项对，则引发异常。  另外，可以使用 WriteSurrogateCharEntity 写出与代理项对相对应的字符实体。字符实体以十六 进制格式写出，并用以下公式生成：  (highChar -0xD800) * 0x400 + (lowChar -0xDC00) + 0x10000  如果字符串包含无效的代理项对，则引发异常。下面的示例显示将代理项对作为输入的 WriteSurrogateCharEntity 方法。  C#复制  // The following line writes 𐀀. WriteSurrogateCharEntity ('\uDC00', '\uD800'); 下面的示例生成一个代理项对文件，将其加载到 XmlReader 中，并用新的文件名保存文件。 然后，原始文件和新文件被加载回应用程序的 XML 文档对象模型 (DOM) 结构中以进行比较。  C#复制  char lowChar, highChar; char [] charArray = new char[10]; FileStream targetFile = new FileStream("SurrogatePair.xml",       FileMode.Create, FileAccess.ReadWrite, FileShare.ReadWrite);  lowChar = Convert.ToChar(0xDC00); highChar = Convert.ToChar(0xD800); XmlTextWriter tw = new XmlTextWriter(targetFile, null); tw.Formatting = Formatting.Indented; tw.WriteStartElement("root"); tw.WriteStartAttribute("test", null); tw.WriteSurrogateCharEntity(lowChar, highChar); lowChar = Convert.ToChar(0xDC01); highChar = Convert.ToChar(0xD801); tw.WriteSurrogateCharEntity(lowChar, highChar); lowChar = Convert.ToChar(0xDFFF); highChar = Convert.ToChar(0xDBFF); tw.WriteSurrogateCharEntity(lowChar, highChar);  // Add 10 random surrogate pairs. // As Unicode, the high bytes are in lower // memory; for example, word 6A21 as 21 6A. // The high or low is in the logical sense. Random random = new Random(); for (int i = 0; i < 10; ++i) {       lowChar = Convert.ToChar(random.Next(0xDC00, 0xE000));       highChar = Convert.ToChar(random.Next(0xD800, 0xDC00));       charArray[i] = highChar;       charArray[++i] = lowChar; } tw.WriteChars(charArray, 0, charArray.Length);  for (int i = 0; i < 10; ++i) {       lowChar = Convert.ToChar(random.Next(0xDC00, 0xE000));       highChar = Convert.ToChar(random.Next(0xD800, 0xDC00));       tw.WriteSurrogateCharEntity(lowChar, highChar); }  tw.WriteEndAttribute(); tw.WriteEndElement(); tw.Flush(); tw.Close();  XmlTextReader r = new XmlTextReader("SurrogatePair.xml");  r.Read(); r.MoveToFirstAttribute(); targetFile = new FileStream("SurrogatePairFromReader.xml",        FileMode.Create, FileAccess.ReadWrite, FileShare.ReadWrite);  tw = new XmlTextWriter(targetFile, null); tw.Formatting = Formatting.Indented; tw.WriteStartElement("root"); tw.WriteStartAttribute("test", null); tw.WriteString(r.Value); tw.WriteEndAttribute(); tw.WriteEndElement(); tw.Flush(); tw.Close();  // Load both result files into the DOM and compare. XmlDocument doc1 = new XmlDocument(); XmlDocument doc2 = new XmlDocument(); doc1.Load("SurrogatePair.xml"); doc2.Load("SurrogatePairFromReader.xml"); if (doc1.InnerXml != doc2.InnerXml) {       Console.WriteLine("Surrogate Pair test case failed"); } 在使用 WriteChars 方法（一次写出一个缓冲区的数据）写出时，输入中的代理项对可能 会在一个缓冲区内被意外拆分。由于代理项值是定义完善的，如果 WriteChars 遇到来自 较低范围或者较高范围的 Unicode 值，它将该值标识为代理项对的一半。当遇到  WriteChars 将导致从拆分代理项对的缓冲区写入的情况时，将引发异常。使用   IsHighSurrogate 方法检查缓冲区是否以高代理项字符结束。如果缓冲区中的最后一个   字符不是高代理项，可以将该缓冲区传递给 WriteChars 方法。  请参见 概念 使用 XmlTextWriter 创建格式正确的 XML XmlTextWriter 的 XML 输出格式设置 XmlTextWriter 的命名空间功能  #endif [/quote] 代码比较长没看，你的结论是什么？

引用 6 楼 通信小卒 的回复:每个汉子用两个字符表示，也就是两个ascii，占用两个字节 不见得： #pragma comment(lib,"user32") #pragma comment(lib,"gdi32") #include <conio.h> #include <stdio.h> #include <stdlib.h> #include <windows.h> extern "C" HWND WINAPI GetConsoleWindow(); void HideTheCursor() {     CONSOLE_CURSOR_INFO cciCursor;     HANDLE hStdOut = GetStdHandle(STD_OUTPUT_HANDLE);      if(GetConsoleCursorInfo(hStdOut, &cciCursor)) {         cciCursor.bVisible = FALSE;         SetConsoleCursorInfo(hStdOut, &cciCursor);     } } void ShowTheCursor() {     CONSOLE_CURSOR_INFO cciCursor;     HANDLE hStdOut = GetStdHandle(STD_OUTPUT_HANDLE);      if(GetConsoleCursorInfo(hStdOut, &cciCursor)) {         cciCursor.bVisible = TRUE;         SetConsoleCursorInfo(hStdOut, &cciCursor);     } } int main() {     HWND  hwnd;     HDC   hdc;     HFONT hfont;     wchar_t wc[2];      system("color F0");     system("cls");     HideTheCursor();     hwnd  = GetConsoleWindow();     hdc   = GetDC(hwnd);     hfont = CreateFont(48,0,0,0,0,0,0,0,GB2312_CHARSET ,0,0,0,0,"宋体-方正超大字符集");     SelectObject(hdc,hfont);     wc[0]=0xD854u;     wc[1]=0xDC00u;     TextOutW(hdc,10,10,wc,2);     DeleteObject(hfont);     ReleaseDC(hwnd,hdc);     getch();     system("color 07");     system("cls");     ShowTheCursor();     return 0; } #if 0 代理项或代理项对是一对共同表示单个字符的 16 位 Unicode 编码值。需要记住的关键一点是： 代理项对实际上是 32 位单个字符，不能再假定一个 16 位 Unicode 编码值正好映射到一个字符。  使用代理项对 代理项对的第一个值是高代理项，包含介于 U+D800 到 U+DBFF 范围内的 16 位代码值。 该对的第二个值是低代理项，包含介于 U+DC00 到 U+DFFF 范围内的值。通过使用代理项对， 16 位 Unicode 编码系统可以对已由 Unicode 标准定义的一百多万个其他字符 (220) 进行寻址。  在传递给 XmlTextWriter 方法的任何字符串中都可以使用代理项字符。不过，代理项字符在编写的 XML 中应该有效。例如，万维网联合会 (W3C) 建议不允许在元素或属性的名称中使用代理项字符。 如果字符串包含无效的代理项对，则引发异常。  另外，可以使用 WriteSurrogateCharEntity 写出与代理项对相对应的字符实体。字符实体以十六 进制格式写出，并用以下公式生成：  (highChar -0xD800) * 0x400 + (lowChar -0xDC00) + 0x10000  如果字符串包含无效的代理项对，则引发异常。下面的示例显示将代理项对作为输入的 WriteSurrogateCharEntity 方法。  C#复制  // The following line writes 𐀀. WriteSurrogateCharEntity ('\uDC00', '\uD800'); 下面的示例生成一个代理项对文件，将其加载到 XmlReader 中，并用新的文件名保存文件。 然后，原始文件和新文件被加载回应用程序的 XML 文档对象模型 (DOM) 结构中以进行比较。  C#复制  char lowChar, highChar; char [] charArray = new char[10]; FileStream targetFile = new FileStream("SurrogatePair.xml",       FileMode.Create, FileAccess.ReadWrite, FileShare.ReadWrite);  lowChar = Convert.ToChar(0xDC00); highChar = Convert.ToChar(0xD800); XmlTextWriter tw = new XmlTextWriter(targetFile, null); tw.Formatting = Formatting.Indented; tw.WriteStartElement("root"); tw.WriteStartAttribute("test", null); tw.WriteSurrogateCharEntity(lowChar, highChar); lowChar = Convert.ToChar(0xDC01); highChar = Convert.ToChar(0xD801); tw.WriteSurrogateCharEntity(lowChar, highChar); lowChar = Convert.ToChar(0xDFFF); highChar = Convert.ToChar(0xDBFF); tw.WriteSurrogateCharEntity(lowChar, highChar);  // Add 10 random surrogate pairs. // As Unicode, the high bytes are in lower // memory; for example, word 6A21 as 21 6A. // The high or low is in the logical sense. Random random = new Random(); for (int i = 0; i < 10; ++i) {       lowChar = Convert.ToChar(random.Next(0xDC00, 0xE000));       highChar = Convert.ToChar(random.Next(0xD800, 0xDC00));       charArray[i] = highChar;       charArray[++i] = lowChar; } tw.WriteChars(charArray, 0, charArray.Length);  for (int i = 0; i < 10; ++i) {       lowChar = Convert.ToChar(random.Next(0xDC00, 0xE000));       highChar = Convert.ToChar(random.Next(0xD800, 0xDC00));       tw.WriteSurrogateCharEntity(lowChar, highChar); }  tw.WriteEndAttribute(); tw.WriteEndElement(); tw.Flush(); tw.Close();  XmlTextReader r = new XmlTextReader("SurrogatePair.xml");  r.Read(); r.MoveToFirstAttribute(); targetFile = new FileStream("SurrogatePairFromReader.xml",        FileMode.Create, FileAccess.ReadWrite, FileShare.ReadWrite);  tw = new XmlTextWriter(targetFile, null); tw.Formatting = Formatting.Indented; tw.WriteStartElement("root"); tw.WriteStartAttribute("test", null); tw.WriteString(r.Value); tw.WriteEndAttribute(); tw.WriteEndElement(); tw.Flush(); tw.Close();  // Load both result files into the DOM and compare. XmlDocument doc1 = new XmlDocument(); XmlDocument doc2 = new XmlDocument(); doc1.Load("SurrogatePair.xml"); doc2.Load("SurrogatePairFromReader.xml"); if (doc1.InnerXml != doc2.InnerXml) {       Console.WriteLine("Surrogate Pair test case failed"); } 在使用 WriteChars 方法（一次写出一个缓冲区的数据）写出时，输入中的代理项对可能 会在一个缓冲区内被意外拆分。由于代理项值是定义完善的，如果 WriteChars 遇到来自 较低范围或者较高范围的 Unicode 值，它将该值标识为代理项对的一半。当遇到  WriteChars 将导致从拆分代理项对的缓冲区写入的情况时，将引发异常。使用   IsHighSurrogate 方法检查缓冲区是否以高代理项字符结束。如果缓冲区中的最后一个   字符不是高代理项，可以将该缓冲区传递给 WriteChars 方法。  请参见 概念 使用 XmlTextWriter 创建格式正确的 XML XmlTextWriter 的 XML 输出格式设置 XmlTextWriter 的命名空间功能  #endif

每个汉子用两个字符表示，也就是两个ascii，占用两个字节

引用 4 楼 赵4老师 的回复:http://www.unicode.org/charts/  重点看里面的CJK

每一个汉字 都没有

汉字不是ascii表示的，ascii是一个字符的，一个汉字一般是两个字符表示。

汉字是gbk，unicode之类的编码。ascii码表示不了。


Question: CSP认证20190302二十四点，提交以后一直只有20分，求大佬解答！！！

我的代码能得几分~~~

我也是的，我提交上去只有30分。后来我将自己实现的数组stack结构，改为c++标准模板库STL里的stack，就没有任何问题了，100分。  可能是我们自己用数组实现的栈结构不够完美吧，虽然我到现在都没有发现自己实现的栈结构有什么逻辑问题。。（也有可能是效率问题）  总之听过来人说：要考这变态的CCF，必须改掉一切一切的哪怕稍微一丁点不好的编程习惯，以及方言，以及即便是一个无伤大雅的小瑕疵，也可能让你的100分变成10分或5分或0分。能用标准的，就用标准。能用库的，就用库。能不投机取巧，就坚决不能投机取巧。能用最好的算法，就用最好的算法。

这题之前有人贴过：https://bbs.csdn.net/topics/393536105

引用 3 楼 赵4老师 的回复:[quote=引用 2 楼 VD7407 的回复:] [quote=引用 1 楼 赵4老师 的回复:] https://bbs.csdn.net/topics/380157851  没看懂什么意思，望赵老师解惑[/quote] 这个链接里面的代码难道不是算24点用的？[/quote] 我想问的是我的代码里有什么问题，您的那个帖子是算二十四点的，但答非所问啊

引用 5 楼 user-4 的回复:错了，不需要浮点，那应该是运算的次序问题，必须先乘除后加减 用了一个简易的逆波兰，确实是先乘除后加减的，问题应该不是这个

引用 2 楼 VD7407 的回复:[quote=引用 1 楼 赵4老师 的回复:] https://bbs.csdn.net/topics/380157851  没看懂什么意思，望赵老师解惑[/quote] 这个链接里面的代码难道不是算24点用的？

错了，不需要浮点，那应该是运算的次序问题，必须先乘除后加减

多半是除法的时候没用浮点结果错了，有除法要用浮点，最后算结果是否24的时候 只要结果在23.99-24.01之间就可以了

引用 1 楼 赵4老师 的回复:https://bbs.csdn.net/topics/380157851  没看懂什么意思，望赵老师解惑


Question: 在Linux环境下用C语言编写一个命令行下的局域网p2p聊天程序

我觉得没那么复杂。 楼主已经限定了是局域网模式，也就是不存在nat穿透的问题。 通知其他用户忙碌或者空闲状态，可以通过udp广播的形式，广播使用广播地址255.255.255.255，楼主可以百度下。 至于点对点聊天，应该用tcp就可以了。每个用户端都建一个客户端一个服务端，如果有用户连上来，或者连接到另一个用户，就拒绝其他连接就可以了。 至于聊天记录，楼主可以用sqlite3在本地保存下。

P2P 之 UDP穿透NAT的原理与实现（附源代码） 这个源码就可以p2p了。

能说下具体做这个程序需要哪些知识吗？大佬


Question: 急，递归函数的困惑

好的👌，明白了。但感觉自己用递归写函数好难像，不知道有什么技巧

看一下递归函数里当n为0时还会继续递归吗？  当n为0时，返回ans = 1然后直接从函数里返回，不会继续递归了吧

if (n > 0)     {         printf("n=%d\n", n);         ans = n * rfact(n - 1);         printf("ans=%ld\n", ans);         printf("n=%d\n", n);     }     else         ans = 1;    ===================  else         ans = 1;

后面的打错了，是rfact


Question: 数组名做实参

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

图2也是两个指针，double x[];编译器也是按照double *x处理的。形参x也是地址，数组名本身就是表示数组开始的位置，也是 数组的首地址。


Question: 无法编译运行

应该是文件没了，  如果文件存在的话，尝试移除再添加（小心源文件真的没了）  ---  我记不得了，应该是文件被移除的问题

路径对的，木得错误（我重启就。。bug吗

引用 2 楼 提及 的回复:文件没了 文件没了 路径不对吗？查一下路径是否是对的

文件没了 文件没了

提示什么错误？


Question: 急求：Mifare plus卡 相关的demo

引用 楼主 Awxx 的回复:急求：Mifare plus卡 相关的demo  没money，谈什么急求。。。


Question: C语言程序

就是一个4*4的矩阵，y就是斜线的值。0 0， 1 1 ，2 2， 3 3

1070就是取数组中间的斜线值值（矩阵的什么，其实有个专业术语的，忘了，基础题）

选A 本题关键语句在于：b[i]=a[i][i]； 即b[0]=a[0][0] ｛1，2，3｝中的第一个元素 同理 可得出答案：1070

x是一个4*4的数组  fun函数给数组b赋值  第一次循环x[0][0]  1 第二次循环x[1][1]  0 第三次循环x[2][2]  7 第三次循环x[3][3]  0  最后循环打印数组y 1 0 7 0


Question: 小白求解

C语言教程（附带C语言100例）http://download.csdn.net/detail/zhao4zhong1/8830817 Visual C++ 2010 Express简体中文版http://pan.baidu.com/s/1bnwRVLt

《the C programming language》看书，多练习和多做总结，也做做笔记，另外多看看之前的笔记～

10年磨一C 入门推荐谭浩强教授的C语言系列，有专门的练习书，挨个理解，挨个打，多来论坛逛逛.....等等


Question: c#中如何在vs里以编程的方式获取到Windows窗体内的所有文本框内容

我还就真不信C#没有遍历当前窗体内所有子窗体的函数。


Question: c语言

printf Width Specification The second optional field of the format specification is the width specification. The width argument is a nonnegative decimal integer controlling the minimum number of characters printed. If the number of characters in the output value is less than the specified width, blanks are added to the left or the right of the values — depending on whether the – flag (for left alignment) is specified — until the minimum width is reached. If width is prefixed with 0, zeros are added until the minimum width is reached (not useful for left-aligned numbers).  The width specification never causes a value to be truncated. If the number of characters in the output value is greater than the specified width, or if width is not given, all characters of the value are printed (subject to the precision specification).  If the width specification is an asterisk (*), an int argument from the argument list supplies the value. The width argument must precede the value being formatted in the argument list. A nonexistent or small field width does not cause the truncation of a field; if the result of a conversion is wider than the field width, the field expands to contain the conversion result.

Format Specification Fields: scanf and wscanf Functions A format specification has the following form:  % [width] [{h | l | I64 | L}]type  The format argument specifies the interpretation of the input and can contain one or more of the following:   White-space characters: blank (' '); tab ('\t'); or newline ('\n'). A white-space character causes scanf to read, but not store, all consecutive white-space characters in the input up to the next non–white-space character. One white-space character in the format matches any number (including 0) and combination of white-space characters in the input.   Non–white-space characters, except for the percent sign (%). A non–white-space character causes scanf to read, but not store, a matching non–white-space character. If the next character in stdin does not match, scanf terminates.   Format specifications, introduced by the percent sign (%). A format specification causes scanf to read and convert characters in the input into values of a specified type. The value is assigned to an argument in the argument list.  The format is read from left to right. Characters outside format specifications are expected to match the sequence of characters in stdin; the matching characters in stdin are scanned but not stored. If a character in stdin conflicts with the format specification, scanf terminates, and the character is left in stdin as if it had not been read.  When the first format specification is encountered, the value of the first input field is converted according to this specification and stored in the location that is specified by the first argument. The second format specification causes the second input field to be converted and stored in the second argument, and so on through the end of the format string.  An input field is defined as all characters up to the first white-space character (space, tab, or newline), or up to the first character that cannot be converted according to the format specification, or until the field width (if specified) is reached. If there are too many arguments for the given specifications, the extra arguments are evaluated but ignored. The results are unpredictable if there are not enough arguments for the format specification.  Each field of the format specification is a single character or a number signifying a particular format option. The type character, which appears after the last optional format field, determines whether the input field is interpreted as a character, a string, or a number.   The simplest format specification contains only the percent sign and a type character (for example, %s). If a percent sign (%) is followed by a character that has no meaning as a format-control character, that character and the following characters (up to the next percent sign) are treated as an ordinary sequence of characters, that is, a sequence of characters that must match the input. For example, to specify that a percent-sign character is to be input, use %%.  An asterisk (*) following the percent sign suppresses assignment of the next input field, which is interpreted as a field of the specified type. The field is scanned but not stored.

最好举个例子，或者写个小程序试一下～

不是,最少六个字


Question: txt文档数据提取保存

谢谢

仅供参考：//将当前文件夹下的所有.txt文件的第R行第C列(空格间隔)显示出来 #include <stdio.h> #include <stdlib.h> #include <string.h> char ln[256]; char fpn[256]; char c[256]; char *p; FILE *af; FILE *f; int L,n,R,C,i,j,k; int main(int argc,char **argv) {     if (argc>=3) {         R=atoi(argv[1]);         C=atoi(argv[2]);     } else {         fprintf(stderr,"Input R C:");         fflush(stderr);         scanf("%d%d",&R,&C);     }     system("dir /b /a-d /on *.txt >d:\\allfn.txt");     af=fopen("d:\\allfn.txt","r");     if (NULL==af) {         fprintf(stderr,"Can not open file d:\\allfn.txt!\n");         return 1;     }     while (1) {         if (NULL==fgets(ln,256,af)) break;         L=strlen(ln);         if ('\n'==ln[L-1]) ln[L-1]=0;         fprintf(stderr,"\nread %s\n",ln);         strcpy(fpn,ln);         f=fopen(fpn,"r");         if (NULL==f) {             fprintf(stderr,"Can not open file %s!\n",fpn);             fclose(af);             return 3;         }         for (i=0;i<R;i++) {             if (NULL==fgets(ln,256,f)) break;         }         if (i>=R) {             p=ln;             for (j=0;j<C;j++) {                 k=sscanf(p,"%s%n",c,&n);                 if (1==k) {                     p+=n;                     if (j==C-1) printf("%s ",c);                 } else break;             }         }         fclose(f);     }     fclose(af);     return 0; }

#include<io.h> ... FILE *pf = fopen("data.txt", "wb"); for(int i = 0; i < 1024; i++) {     fprintf(pf, "%f\n",  1.0); } fclose(pf);


Question: 不允许使用不完整的类型？

我知道了，我太蠢了...第五行和第12行不应该有void。太粗心了！刚发出来就意识到了问题

函数调用和声明是不一样的，调用就要去掉void  另外，“main”和“mian”的区别可以仔细的看一下。

函数声明参数列表 写1是什么意思?


Question: c语言的一个小问题

引用 4 楼 weixin_39885009 的回复:[quote=引用 1 楼 自信男孩的回复:]1处：p[j] = s[i];  因为p是用于存放数字，而j是其下标； 2处：k; 因为这个地方是用于将非数字追加到p+j的后面，因此这个循环应该是k； 3处：p;因为调整之后的字符串存放到了p中，所以最后输出的应该是p的地址。  可以前面p[j+k] = 0;可以知道，应该是输出p。  这个程序有一个问题，就是只有malloc没有free. p的释放在main中，因为main还需要用它，当用完之后就应该free掉。 另一个t，应该在fun函数里，return之前free掉。  但又说过来了，程序运行完会系统会把他malloc的内存释放掉，但是还是建议养成malloc/free的习惯 for循环i会从0循环到n-1，也就是说j+k是等于n的,但是p只有n个内存空间，所以p[n-1]是p的结束符，那么p[j+k]不就不存在吗。[/quote] 你思考一下j+k会大于n-1吗？

引用 6 楼 weixin_39885009 的回复:[quote=引用 5 楼 自信男孩的回复:][quote=引用 4 楼 weixin_39885009 的回复:] [quote=引用 1 楼 自信男孩的回复:]1处：p[j] = s[i];  因为p是用于存放数字，而j是其下标； 2处：k; 因为这个地方是用于将非数字追加到p+j的后面，因此这个循环应该是k； 3处：p;因为调整之后的字符串存放到了p中，所以最后输出的应该是p的地址。  可以前面p[j+k] = 0;可以知道，应该是输出p。  这个程序有一个问题，就是只有malloc没有free. p的释放在main中，因为main还需要用它，当用完之后就应该free掉。 另一个t，应该在fun函数里，return之前free掉。  但又说过来了，程序运行完会系统会把他malloc的内存释放掉，但是还是建议养成malloc/free的习惯 for循环i会从0循环到n-1，也就是说j+k是等于n的,但是p只有n个内存空间，所以p[n-1]是p的结束符，那么p[j+k]不就不存在吗。[/quote] 你思考一下j+k会大于n-1吗？[/quote] 你的坚持是对的，你的分析也是对的，最后执行了n次，这个n是在有效长度的基础上加了1，加1没问题， 但是在第一个循环的时候不应该是i < n;而应该是i < n-1;因为最后的'\0'不参与，也不应该放到p, t中。因为最后有一个p[j+k]= 0;来 填充字符串结束标记。你的理解是对的，赞一个。 我想出题的人没有考虑到这一点。  根据你的理解，第二个地方就不能直接传k这么简单了，可以考虑填这个表达式：  (k > n-j-1 ? k-- : k) 我想出题人也不是想要这个答案，但是出题人出题有问题，也没办法，填这个表达式可以补救一下，不然会内存溢出。  加油吧～

引用 5 楼 自信男孩的回复:[quote=引用 4 楼 weixin_39885009 的回复:] [quote=引用 1 楼 自信男孩的回复:]1处：p[j] = s[i];  因为p是用于存放数字，而j是其下标； 2处：k; 因为这个地方是用于将非数字追加到p+j的后面，因此这个循环应该是k； 3处：p;因为调整之后的字符串存放到了p中，所以最后输出的应该是p的地址。  可以前面p[j+k] = 0;可以知道，应该是输出p。  这个程序有一个问题，就是只有malloc没有free. p的释放在main中，因为main还需要用它，当用完之后就应该free掉。 另一个t，应该在fun函数里，return之前free掉。  但又说过来了，程序运行完会系统会把他malloc的内存释放掉，但是还是建议养成malloc/free的习惯 for循环i会从0循环到n-1，也就是说j+k是等于n的,但是p只有n个内存空间，所以p[n-1]是p的结束符，那么p[j+k]不就不存在吗。[/quote] 你思考一下j+k会大于n-1吗？[/quote] 第一个for循环会循环n次，每次j和k会至少有一个＋1，那j+k不是等于n吗

引用 1 楼 自信男孩的回复:1处：p[j] = s[i];  因为p是用于存放数字，而j是其下标； 2处：k; 因为这个地方是用于将非数字追加到p+j的后面，因此这个循环应该是k； 3处：p;因为调整之后的字符串存放到了p中，所以最后输出的应该是p的地址。  可以前面p[j+k] = 0;可以知道，应该是输出p。  这个程序有一个问题，就是只有malloc没有free. p的释放在main中，因为main还需要用它，当用完之后就应该free掉。 另一个t，应该在fun函数里，return之前free掉。  但又说过来了，程序运行完会系统会把他malloc的内存释放掉，但是还是建议养成malloc/free的习惯 for循环i会从0循环到n-1，也就是说j+k是等于n的,但是p只有n个内存空间，所以p[n-1]是p的结束符，那么p[j+k]不就不存在吗。

感觉逻辑是这样的：把你的字符串在函数里分成数字和字母，在分别用不同的char*来指向，分完以后在把指向字母的加到指向数字的后面，j和k分别是数字和字母的个数，那p[j+k]就是结尾啊，因为第一位是0嘛（比如数字一个，字母一个，那就是j=1，k=1，那数组就是[0][1][2],[2]就是结尾，放结束符）


Question: 求解

写一个交换函数就明白了，若是传你说的普通变量，那么在交换的时候交换的是你传入的变量的拷贝，实际上达不到交换的期望，传指针的话，相当于是直接交换内存中那个地址存放的值，这样才起到交换作用。传指针也可以实现参数的传入传出，就是在A在调用的函数中修改变量后，后面继续对该变量操作时，其值已经得到修改。感觉自己说的很乱......

引用 楼主 qq_45370071 的回复:指针、指针变量做形参和普通变量有何异同？ 指针变量给我一种浓浓的谭浩强味道的感觉

引用 楼主 qq_45370071 的回复:指针、指针变量做形参和普通变量有何异同？ 指针、指针变量分别是什么意思？有什么区别？

指针变量里存放的是地址，而是普通变量里存放的一般是具体的值。


Question: 四行代码求圆周率

仅供参考：#include <stdio.h> long a=10000; long b; long c=2800; long d; long e; long f[2801]; long g; int main() {     for(;b-c;) f[b++]=a/5; //  while (1) { //      if (0==b-c) break; //      f[b]=a/5; //      b++; //  }      //f[0 - 2800] = 10000/5     for(;d=0,g=c*2;c-=14,printf("%.4d",e+d/a),e=d%a)           for(b=c;d+=f[b]*a,f[b]=d%--g,d/=g--,--b;d*=b); //  while (1) { //      d=0; //      g=c*2; //      if (0==g) break; //      b=c; //      while (1) { //          d+=f[b]*a; //          f[b]=d%--g; //          d/=g--; //          --b; //          if (0==b) break; //          d*=b; //      } //      c-=14; //      printf("%.4d",e+d/a); //      e=d%a; //  }  	return 0; }


Question: 大神求教，小白求救

楼上的都说了，hour1  minute1  hour2 minute2  这四个值

需要输入四个值，每两个是一组

有啥不对的呢？ 你输入完两个值之后，回车，再输入两个值，再按回车，结果不就出来了吗？

不是要输入4个值吗？

楼上说得对，注意空格和回车，输入格式要和你scanf函数写的格式一样

第一行scanf中有两个待输入的变量hour1 minute1，第二行还有两个待输入的变量hour2，minute2. 所以正确操作方法应该是：     在运行程序后，     输入第一个数（空格）输入第二个数（回车）输入第三个数（空格）输入第四个数（回车）。

需要输入4个值，等待输入


Question: ndk20 编译android 32位的apk 可以通过编译选项来设置字节对齐位数吗

-fpack-struct  但仍然推荐代码里修改


Question: C语言的++运算符是被编译器重载过么，它是如何分辨参数的数据类型的

整型浮点为什么没疑问 你以为整型的++ 和 浮点的++是一回事? 别说整型的++和浮点的++ 就是浮点内部的++ 浮点数的数值不同 ++ 的效果都不一样  编译器当然知道分辨各种类型 这本来就是编译器工作的基本内容啊


Question: 最小生成树课程设计

会的人多了去了#*/


Question: C语音编程(手机编辑器)

引用 2 楼 赵4老师的回复:Enter，Ctrl+Z，Enter 手机编辑没有ctrl+z，也试过^z，都没反应

引用 3 楼 qq_45594029 的回复:[quote=引用 2 楼 赵4老师的回复:]Enter，Ctrl+Z，Enter 手机编辑没有ctrl+z，也试过^z，都没反应[/quote] 由此可见，手机编程本来就是个鸡肋。

Enter，Ctrl+Z，Enter

Ctrl+Z，Enter


Question: 数据结构大神求助

引用 2 楼 阿大古 古古古 的回复：是想把插入位置以前的全部往前移动一位吗？感觉好奇怪。想在什么位置插入，直接修改那个位置的值不就行了吗，为什么还要去腾位置？这个是线性表 如果链表的话可以直接插入 如果直接修改值的话原始值就被覆盖 就不是插入操作了

t是last，本身就是偏移一个数据了，那么t+1是偏移两个数据了吧  把函数调用也贴出来吧。贴代码，不建议发图片