Question: 字符变量和字符常量所占内存大小？(C语言)

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

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

谢了，，我已知道了、

sizeof('a')的结果是多少？这个要看是在C中还是C++中了。根据C99标准的规定，'a'叫做整型字符常量（integer character constant），为int型，故结果是4（对于32位机器）；而ISO C++规定，'a'叫做字符字面量（character literal），为char型，故结果是1。C强调了'a'的“数”属性，而C++强调了'a'的“字符”属性。 字符常量在C中长度是4，在C++中是1，VC中默认如果源文件为.c则按c编译，如果是.cpp则按C++编译 PS:在C程序里可以试试sizeof((char)'A')

C99标准的规定，'a'叫做整型字符常量(integer character constant)，被看成是int型，所以在32位机器上占4字节。  ISO C++标准规定，'a'叫做字符字面量(character literal)，被看成是char型，所以占1字节。  C99: An integer character constant is a sequence of one or more multibyte characters enclosed in single-quotes, as in 'x'. An integer character constant has type int.  C++2003: A character literal is one or more characters enclosed in single quotes, as in ’x’, optionally preceded by the letter L, as in L’x’.A character literal that does not begin with L is an ordinary character literal, also referred to as a narrow-character literal. An ordinary character literal that contains a single c-char has type char, with value equal to the numerical value of the encoding of the c-char in the execution character set. An ordinary character literal that contains more than one c-char is a multicharacter literal. A multicharacter literal has type int and implementation-defined value.   文章来自于： http://blog.csdn.net/rangf/article/details/8199241

这个现象   有个什么合理的解释呢？


Question: queue函式的问题

很明显，这里的Q1、Q2中的Q是queue的意思，代表队列，x就是入队/出队的元素。


Question: c语言   宏定义

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

假定有三个不同的宏，来包装多条表达式：#define statement1() x; y #define statement2() { x; y; } #define statement3() do { x; y; } while (0)1. 如果程序员这样写代码： if (a)     statement1(); else     statement0();由于分号的作用，if (a) 只对 “x;” 有效。 如果没有 else，逻辑可能达不到书写的目的，如果有 else 分支，则无法编译通过。 2. 如果程序员这样写代码：if (a)     statement2(); else     statement0();由于分号的作用，if (a) 只对 “{ x; y; }” 有效。 如果没有 else，一切都很正常。如果有 else 分支，则无法编译通过。  以上两种情况都需要在任何情况下强制使用大括号才能消除问题。 如果使用 statement3() 这个宏，则不管有没有大括号，有没有 else 都不会影响到代码逻辑。

引用 楼主 qq_28325599 的回复: 这里的_align怎么理解？？  这里出现的"_align"只是一个普通的变量（应该是一个整数），用4个二进制位（bits）来表示ALIGN的模式。 其中，_align的bit0和bit1对应HALIGN的4种取值，bit2和bit3对应VALIGN的4种取值。

使用 {} 把复合语句变成一个块。 加上 do while(0) 使得这个块变成一个语句。而且 while(0) 保证仅仅执行一次。 这样在使用的时候，就好像使用一个语句一样。  ALIGN 的宏定义表示 参数 _align 包含了HV 对齐的两个参数，而这两个参数放在一个 UINT8 中。

do{...}while(0); 说明只执行一次do ...while里面的代码即刻停止

__align 关键字指示编译器在 n 字节边界上对齐变量。 参考：http://blog.csdn.net/bruce0532/article/details/4719540


Question: 为啥输出差距那么大？

建议楼主看一下浮点数在内存中的存储，就明白了  union{ 		float input; 		char output[4]; 	}data; 	data.input = 3.14; 	printf("%d %d %d %d\n", data.output[0], data.output[1], data.output[2], data.output[3]);

引用 1 楼 qq423399099 的回复:输出差距那么大，是因为浮点数在内存中的存储造成的 可以借助联合体输出一个浮点数在内存中的存储  #include<iostream> #include <bitset> using namespace std;   void main() {        union {         float input;         int output;     } data;       data.input = 3.14;     std::bitset<sizeof(float) * 8>bits(data.output);     std::cout << bits << std::endl; }  也可以参考：http://bbs.csdn.net/topics/390676437 你这个是c++的，也适用于C么？


Question: 一个应该是主函数上的错误

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

#include <stdio.h> #include <malloc.h> #include <stdlib.h> #define NO 0 #define OK 1 #define TRUE 1 #define FALSE 0 #define max 100 typedef int ElemType; struct          \\struct结构变量的声明不用前面的typedef吧  { int top; ElemType *base; int stacksize; }table;   struct {  int *base; int front; int rear; }man;  void initstack(table *S);  int push(table *S,ElemType x); int pop(table *S,ElemType *e); int InitQueue(man *Q); int DeQueue(man *Q,ElemType e); int EnQueue(man *Q,ElemType e); int QueueEmpty(man *Q); void list(man *Q);  void initstack(table *S) { S=&table;                                          \\必须初始化结构指针，跟数组不一样 S->base=(ElemType*)malloc(max*sizeof(ElemType)); S->top=0; S->stacksize=max; }/*创建空栈*/  int push(table *S,ElemType x) { { S=&table;                                          \\必须初始化结构指针，跟数组不一样 if(S->top>=S->stacksize) { S->base=(ElemType *)realloc(S->base,(S->stacksize+1)*sizeof(ElemType)); if(!S->base) return NO; S->stacksize++; } S->base[S->top++]=x; return OK; }/*压栈*/  int pop(table *S,ElemType *e) { if(S->top==0) return NO; *e=S->base[--S->top]; return OK; } /*弹栈*/   int InitQueue(man *Q) {  Q->base=(ElemType *)malloc(max*sizeof(ElemType));     if(!Q->base) /* 存储分配失败 */       return NO;     Q->front=Q->rear=0;     return OK; }/* 构造一个空队列Q */  int DeQueue(man *Q,ElemType e) { if(Q->front==Q->rear) /* 队列空 */       return NO;     e=Q->base[Q->front];     Q->front=(Q->front+1)%max;     return OK;  }/* 若队列不空,则删除Q的队头元素,用e返回其值,并返回OK;否则返回ERROR */  int EnQueue(man *Q,ElemType e) {  if((Q->rear+1)%max==Q->front) /* 队列满 */       return NO;     Q->base[Q->rear]=e;     Q->rear=(Q->rear+1)%max;     return OK; }/* 插入元素e为Q的新的队尾元素 */  int QueueEmpty(man *Q) {  if(Q->front==Q->rear) /* 队列空的标志 */       return TRUE;     else       return FALSE; }/* 若队列Q为空队列,则返回TRUE,否则返回FALSE */  void list(man *Q) { int i; i=Q->front; while(i!=Q->rear) { printf("%4d",Q->base[i]); i=(i+1)%max; } }   int main() {  int j,k,n,i,e; man A; man B; table a; InitQueue(&A); InitQueue(&B); initstack(&a); printf("一人几张\n"); scanf("%d",&n); for(i=0;i<n;i++) { printf("\nA的第%d个数:",i+1); scanf("%d",&j); EnQueue(&A,j);  } list(&A); for(i=0;i<n;i++) { printf("\nB的第%d个数:",i+1); scanf("%d",&j); EnQueue(&B,j); } list(&B); for(k=0;k<max;k++) { for(i=max;i>=0;i--)//扫描是否有以入栈的元素与之前元素相同         { if(a.base[i]==j)              break;         }         if(a.base[i]==j)//如果当前栈中有与输入元素相同的值，出栈          for(n=max;n>=i;n--)          { pop(&a,&e); EnQueue(&A,e); }         else if(QueueEmpty(&A)==TRUE) { printf("\nB胜"); break; } else//否则入栈         {  DeQueue(&A,j); push(&a,j);         } for(i=max;i>=0;i--)//扫描是否有以入栈的元素与之前元素相同         { if(a.base[i]==j)              break;         }         if(a.base[i]==j)//如果当前栈中有与输入元素相同的值，出栈          for(n=max;n>=i;n--)          { pop(&a,&e); EnQueue(&B,e); }         else if(QueueEmpty(&B)==TRUE) { printf("\nA胜"); break;   } else//否则入栈         {  DeQueue(&B,j); push(&a,j);         } } return OK; }   看不下去了，我发现现在的CSDN真的是学不到东西，经典的代码看不到，全是一些新手在误导新手

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

typedef struct结构变量的声明不用前面的typedef吧

这个是做一个金钩钓鱼，不用洗牌，不用发牌，无视大小王，只是10以内。http://jingyan.baidu.com/article/d169e1869e9b1c436611d8ef.html大概玩法应该是在for(k=0;k<max;k++)这句之后错了，但我还是不会改


Question: UVA227 总是无法ac 写了两遍调了一天  求找bug

一般来说，测试用例要涵盖以下情况： 小规模、可以手算的数据。用于快速检验程序的正确性。要注意规模不能太小以至于过分简化问题，比如对于图论题，只有2、3个点的图就太小，一般要取5、6个点。 大规模，但仍有规律、可以手算的数据。也是用于检验程序的正确性。如果程序算出来的结果跟手算的不同，不要急着debug，还需要考虑一下是不是手算错了哦~ 边界和极端情况。一方面检验程序的正确性，另一方面保证复杂度不超过限制。比如二叉树退化成一条链的情况。 大规模随机数据。用于保证程序不会崩溃，以及复杂度不超过限制。 输入格式不正确的情况，在OJ上一般可以忽略，虽然在实际应用中必须考虑。

边界条件 逐字扣题意和输入输出格式


Question: C++小白遇到环境配置问题，程序有点多，求大神帮忙解决问题，必有重谢啊！

引用 6 楼 lgbxyz 的回复:可以运行-我编译的是最新版本下面的那个ProcessBusTool文件夹，其他的没试过 xp3 - 虚拟机 vc6.0++ 企业版（完整版），不要下载网上的精简版   依然不行，请问能不能把你工程-设置-连接里的的库文件粘贴下给我看一下呢？不知道会不会是这个问题，不行我就重装系统了

引用 10 楼 lgbxyz 的回复:socket库 是 Ws2_32.lib 谢谢，ProcessBusToolDSW文件确实可以运行了，分给你，方便加个Q吗 249225749

socket库 是 Ws2_32.lib

引用 8 楼 lgbxyz 的回复:你搞一个winxp虚拟机安装一个VC6.0++，再下载winpcap就行了， 别告诉我你在win7、win8上搞。。。  设置我没动过，肯定和原来的一样，我记得是3个 wpcap、socket、netapi， 在家里电脑中搞得现在在公司，看不到了 我没有socket的库文件，我找找看

引用 4 楼 lgbxyz 的回复:缺少winpcap库，安装了就能编译过了. 下载一个winpcap http://120.52.72.59/www.winpcap.org/c3pr90ntcsf0/archive/4.0-WpdPack.zip 解压后把 WpdPack\Lib 下的文件 拷贝到 Microsoft Visual Studio\VC98\Lib 下， WpdPack\Include下的文件 拷贝到 Microsoft Visual Studio\VC98\Include下，  1.打开ProcessBusTool.dsw 2.编译->重建全部 3.运行(Ctrl+F5)  PS* winxp-sp3, VC6.0++企业版  谢谢啊！·只是我之前也装过WINPCAP了，也设置了库文件，我按你的步骤还是有错误啊，错误如下 ProcessBusTool.obj : error LNK2001: unresolved external symbol "public: static struct CRuntimeClass const CProcessBusToolDoc::classCProcessBusToolDoc" (?classCProcessBusToolDoc@CProcessBusToolDoc@@2UCRuntimeClass@@B) ProcessBusTool.obj : error LNK2001: unresolved external symbol "public: static struct CRuntimeClass const CMainFrame::classCMainFrame" (?classCMainFrame@CMainFrame@@2UCRuntimeClass@@B) ProcessBusTool.obj : error LNK2001: unresolved external symbol "public: static struct CRuntimeClass const CProcessBusToolView::classCProcessBusToolView" (?classCProcessBusToolView@CProcessBusToolView@@2UCRuntimeClass@@B) Debug/ProcessBusTool.exe : fatal error LNK1120: 3 unresolved externals Error executing link.exe.  ProcessBusTool.exe - 4 error(s), 0 warning(s)  好象也是些配置错误，请问在你电脑上是可以运行的么？

引用 1 楼 lgbxyz 的回复:首先这是个VC6.0的MFC程序， 你VC6.0下也无法运行?   是的呀，这个程序有个界面，应用程序已经是可以运行的了，我现在是需要对其源程序做一些修改，完成自己要的功能，然而第一步在VC++6里运行源程序就很多错误，没法解决

重建所有 ？

首先这是个VC6.0的MFC程序， 你VC6.0下也无法运行?


Question: 关于结构体函数调用的问题 急急急

xavs_image_t  * nn1; 这里应该是xavs_image_t类型指针吧

完美！大神你说得对，把out4在外部只打开一次，现在问题就解决了！

按照你给的内容，可能出现问题的地方是out4文件打开的方式是追加， 不会多次执行吗？

为什么只是简单调用一下，图像就不一样了呢？求大神解答！ 上图是一开始很正确的，下方是进了encode_frame里输出的问题图像


Question: 请问听说Android基于Linux内核,Ios基于Unix,为什么他们不编写全新的内核呢?难道Unix、Linux在新系统上不会有多余的代码吗？

引用 3 楼 user-3的回复:Linux内核是可以裁剪的，可以对不同的目标平台（如PC、嵌入式设备。。）做不同的裁剪。 很早以前我自己也编译过Linux内核，编译之前有一个工具可以定制内核需要哪些模块、排除哪些模块，这些模块一般都是支持某些特性或者某些驱动支持，可选择的项目有几十上百项（那时候），然后我那台老奔腾MMX编译了半个多小时产生内核二进制文件。 有实力的厂家一般还可以直接修改内核源代码，做不同的定制或者裁剪。比如以前国产麒麟系统修改了FreeBSD（一种Unix）内核以便符合自主安全，成为一个事件。 学过《操作系统》这门课就会知道系统内核技术上是很复杂的。Linux内核由0.01版本的1万行代码发展到1996年2.0版本时就有40多万行代码，可见没有一定实力不是想编写就编写的。 原来是这样，学习了！！

建议楼主先搞搞清楚啥叫“内核”。 《30天自制操作系统》

android系统运行在虚拟机上的，ios之间和硬件打交道

引用 1 楼 zhao4zhong1 的回复:建议楼主先搞搞清楚啥叫“内核”。 《30天自制操作系统》  谢谢指点!


Question: 关于换行符

toprint[strlen(toprint)] = '\n'; 你把之前的\0改成了\n以后，还需要在后面加一个\0，否则这个字符串没有结束

VC 会把未初始化的栈内存全部填成 0xcc，当字符串看就是 烫烫烫烫……  会把未初始化的堆内存全部填成 0xcd，当字符串看就是 屯屯屯屯……

你的char数组都清零

//toprint[strlen(toprint)] = '\n'; //改为: toprint[strlen(toprint)] = '\n'; toprint[strlen(toprint)+1] = '\0';  //或者 //char toprint[1000]; //改为: char toprint[1000]={'\0'};


Question: 新手问题

只要输入的不是\n（即你没按回车），就一直循环（不退出），循环语句是空（最后分号）

getchar()每次从stdin输入流中获取单个字符。当按键是回车的时候不进入while循环，相当于某种意义上的清除回车

两个while用来判断是否为空格和换行符，如果不是这两个，就将读到的字节值返回

引用 3楼renwotao2009 的回复:get_first只取输入字符串中非空格，tab，\0的第一个字符说错了不是\o是换行符

不是换行符就循环，遇见换行符跳出循环

就是当输入的字符不是换行符的时候执行


Question: 如何将浮点数的二进制形式输出？

也可以用联合体  #include<iostream> #include <bitset> using namespace std;  void main() {	 	union { 		float input; 		int output; 	} data;  	data.input = 3.14; 	std::bitset<sizeof(float) * 8>bits(data.output); 	std::cout << bits << std::endl; }

浮点数格式 http://bbs.csdn.net/topics/390676437 ↑此为唯一正解！

unsigned char* b = (unsigned char*)&a; 	printf("%02X %02X %02X %02X", b[0], b[1], b[2], b[3]);


Question: 求最少等待时间。出现错误代码，求解错误

printf("%d",mintime(a,n)); 就好了

没有给add负值,当然是脏值了

mintime的声明和实现的格式不一致  声明是：  int mintime(int a[]);  实现是：  int mintime(int a[],int n)

上面的声明在刚刚复制时不小心复制了之前的，应该是 int mintime(int a[]，int n);

函数实现和声明都不一致，楼主居然可以过编译。。。。 输出-858993460是因为那个值根本没有被赋值也没有被初始化过 当一个未初始化赋值的时候(至少是vc 下未初始化的内存)默认是0xCCCCCCCC;，他在内存就默认保存为-858993460


Question: 伫列问题

这是伪代码。 凡是不能单步调试对应汇编指令的代码都可以认为不是代码。


Question: 关于归并排序中内存释放的问题

通常是你访问申请到的内存越界了而导致堆破坏，在释放时就会出错

是你malloc的地方有问题，应该是： int *L = (int*)malloc(sizeof(int)*lenl); int *R = (int*)malloc(sizeof(int)*lenr);  #include <stdio.h> #include <stdlib.h>   void Merge(int a[], int p, int q, int r) {     int lenl = q - p+1;     int lenr = r - q;           int i, j,k;     int *L = (int*)malloc(sizeof(int)*lenl);     int *R = (int*)malloc(sizeof(int)*lenr);           for (i = 0; i < lenl; i++) {         L[i] = a[p + i];     }           for (j = 0; j < lenr; j++) {         R[j] = a[q + 1 + j];     }           i = j = k = 0;     while (i < lenl && j < lenr) {         if (L[i]<R[j]) {             a[p + k++] = L[i++];         }         else {             a[p + k++] = R[j++];         }     }     while (i < lenl) {         a[p + k++] = L[i++];     }     while (j < lenr) {         a[p + k++] = R[j++];     }           free(L);     free(R); }   void MergeSort(int a[], int p, int r) {     if (p == r) {         return;     }     int mid = (p + r) / 2;     MergeSort(a, p, mid);     MergeSort(a, mid + 1, r);     Merge(a, p, mid, r); }   int main(void) {     int i;     int a[] = { 76,5,34,3,13,4,6,75 };     int last_index = sizeof(a) / sizeof(int) - 1;     MergeSort(a, 0, last_index);     for (i = 0; i <= last_index;i++) {         printf("%d\n", a[i]);     }     return 0; }


Question: 杭电hdu 2054 比较大小问题

引用 1 楼 qq423399099 的回复:楼主注意这个是for循环，只要一次不满足s[i] == '0'就会结束for循环 不是把小数点后的都变成0了，而是把小数最后多余的0给去掉了 主要有两种转换： 1.类似5.转换成5 2.类似4.50400转换成4.504 (如果是4.51这种是不会转换的)   233333   突然明白了  谢谢你！

233333   突然明白了  谢谢你！


Question: 一对兔子，从出生后第3个月起每个月都生一对兔子。小兔子长到第3个月后每个月又生一对兔子。假如兔子都不死...我写的程序,运行会有问题,求大神看看错在哪..

引用 14 楼 yyxgs 的回复:[quote=引用 13 楼 whiteduna 的回复:] 太复杂了，其实把问题简单化，就是当前这个月新生的兔子 = 前两个月的兔子总数（生产周期决定），再加上上个月的兔子总数就好了，做一个递归，现在算出来的单位是对，按只*2 public static int totalRabbits(int month) 	{ 		if (month < 3) return 1; 		return totalRabbits(month - 1) + totalRabbits(month - 2); 	}   高手![/quote] 递归求解果然简单

引用 9 楼 m2200 的回复:我是来看赵4老师的解答的。 赵4老师正在赶来的路上

引用 13 楼 whiteduna 的回复:太复杂了，其实把问题简单化，就是当前这个月新生的兔子 = 前两个月的兔子总数（生产周期决定），再加上上个月的兔子总数就好了，做一个递归，现在算出来的单位是对，按只*2 public static int totalRabbits(int month) 	{ 		if (month < 3) return 1; 		return totalRabbits(month - 1) + totalRabbits(month - 2); 	}   高手!

引用 4 楼 fornetuse123 的回复:#define _CRT_SECURE_NO_WARNINGS   #include <stdio.h> #include <malloc.h>   /*生兔子*/ void giveBirth_rabbit(int **rabbit, int beforeNumber, int currentNumber) {     int i = 0;       *rabbit = (int*)realloc(*rabbit, currentNumber * sizeof(int));     if (!(*rabbit)) {         printf("兔子增加失败!\n");     }       /*将刚出生的兔子,时间改为1个月*/     for (i = beforeNumber;i < currentNumber;i++) {         *(*rabbit + i) = 1;     } }   /*判断有没有兔子符合生育条件*/ void judgment_rabbit_giveBirth(int* *rabbit, int **rabbitNumber) {     int i = 0;       /*储存出生兔子之前的兔子只数*/     int beforeNumber = **rabbitNumber;       for (i = 0;i < beforeNumber;i++) {           /*符合生兔子的条件*/         if (*(rabbit + i) >= 3) {             ++(**rabbitNumber);               /*增加兔子*/             giveBirth_rabbit(**rabbit, beforeNumber, **rabbitNumber);         }           /*增加出生时间*/         ++(**(rabbit + i));     } }   int main(int argc, char *argv[]) {     int i = 0;       int *rabbit = NULL;     int *rabbitNumber = NULL;       /*分配内存储存兔子和兔子个数*/     rabbit = (int*)calloc(1, sizeof(int));     if (!rabbit) {         printf("兔子创建失败!\n");     }       rabbitNumber = (int*)calloc(1, sizeof(int));     if (!rabbitNumber) {         printf("兔子只数创建失败!\n");     }       /*兔子个数为1对*/    * *rabbitNumber = 1;       for (i = 0;i<100;i++) {           /*判断兔子是否符合出生条件*/         judgment_rabbit_giveBirth(rabbit, rabbitNumber);           printf("第 %d 个月: %d 只兔子!\n", i, **rabbitNumber * 2);     }       return 0; }   红字是更改的地方吗?

引用 3 楼 chehw_1 的回复:你的实现方式太复杂了。   #include <stdio.h> #include <stdint.h> #include <inttypes.h>  #define N (100)   int main(int argc, char **argv) { 	int i; 	uint64_t rabbits[N + 1] = {0}; // 为简化代码，直接在栈上初始化一个数组。根据需要，也可以用malloc来分配空间 	rabbits[0] = rabbits[1] = rabbits[2] = 2; //前三个月的兔子数均为2只 	 	for(i = 3; i <= N; ++i) 	{ 		rabbits[i] = rabbits[i - 1] + rabbits[i - 3]; // 【当月的兔子数】 = 【上月的兔子数】 + 【3个月以前的兔子数】 		printf("%3d: \t count = %"PRIu64"\n", i, rabbits[i]); 	} 		 	return 0; }    高手!

引用 3 楼 chehw_1 的回复:你的实现方式太复杂了。   #include <stdio.h> #include <stdint.h> #include <inttypes.h>  #define N (100)   int main(int argc, char **argv) { 	int i; 	uint64_t rabbits[N + 1] = {0}; // 为简化代码，直接在栈上初始化一个数组。根据需要，也可以用malloc来分配空间 	rabbits[0] = rabbits[1] = rabbits[2] = 2; //前三个月的兔子数均为2只 	 	for(i = 3; i <= N; ++i) 	{ 		rabbits[i] = rabbits[i - 1] + rabbits[i - 3]; // 【当月的兔子数】 = 【上月的兔子数】 + 【3个月以前的兔子数】 		printf("%3d: \t count = %"PRIu64"\n", i, rabbits[i]); 	} 		 	return 0; }   高，实在是高

引用 9 楼 m2200 的回复:我是来看赵4老师的解答的。   赵老师没来...

引用 8 楼 jack960330 的回复:我总觉得楼主的实现方式过于复杂   嗯的，我把简单的事情复杂化了...

我是来看赵4老师的解答的。

我总觉得楼主的实现方式过于复杂

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


Question: 循环无法结束

楼上已经解决了，我再给个方案  scanf("%s", buff); len = strlen(buff); int i,j; j = i = len - 1; for(; i >= 0; --i) {      if(buff[i] == ' ' || i == 0) {             int k = i;             while(k != j)                      printf("%c", buff[k++]);            printf(" ");            j =  --i;      } }  如果有第三方库包含substr接口，那么上文中的while循环可以直接使用substr替换 此外，还有一种解决方案使用strtok函数，不过这个需要栈和内存分配结合使用

首先要理解你自己的代码的含义. for(i=0;;i++)//这里有BUG，要是超过20个单词怎么办？   {        for(j=0;;j++)//同样的，超过14个字符也有问题      {          getchar(a[i][j]);          if(a[i][j]==' '||a[i][j]=='\0')              break;     }     if(a[i][j]=='\0')//主要是这里，什么时候发生这个条件？发生不了，因为在内层循环里面也有个if(a[i][j]==' '||a[i][j]=='\0')                       这是死循环的症结所在。          break;   }

getchar(a[i][j]);这是什么用法。。。。  #include<stdio.h> #include<string.h>   void a(char *p) {     char temp[100];     int b    = strlen(p);     int k    = 0;     char temp1[100];     int    i    = 0;     for(i=0;i<b;i++)     {         temp[i]=p[b-i-1];     }     temp[b]='\0';     //puts(temp);     int j    = 0;     //要循环结束条件为: j <= b     for(j=0;j<=b;j++)     {         //此处应为判断,用 '=='，还要考虑句尾的情况，要不最后一个单词打印不出来         if(temp[j]==' ' || temp[j] == '\0')         {             int l    = 0;             for(;k<j;k++)             {                 temp1[k]=temp[j-l-1];                 l++;             }                 //在单词之间添加空格             temp1[j]    = ' ';                         k++;         }     }     temp1[b]='\0';     puts(temp1); }   int main() {     char ch[100];     gets(ch);     a(ch);     return 0; }

为啥不用指针，当指到空格跳出，储存


Question: 用C语言在黑框里画一个爱心，为什么就是不行

引用 9 楼 Cerman 的回复:楼主用的什么app啊，求推荐  我用过C4droid ……不过你会发现很不方便。还是用电脑吧。

楼主用的什么app啊，求推荐

system("chcp 437");printf("%c",3);

引用 1 楼 qq423399099 的回复: #include<stdio.h>  # define U 0.06 # define V 0.025  # define M 1.1 # define N 1.2 int main(void) { 	float x, y; 	float m, n;  	for ( y=2; y>=-2; y-=U ) 	{  		for ( x=-1.2; x<=1.2; x+=V) 		{ 			if ( ( ( (x*x + y*y - 1)*(x*x + y*y - 1)*(x*x + y*y - 1) - x*x*y*y*y ) <= 0 ) ) 				printf("*"); 			else 				printf(" "); 		} 		printf("\n"); 	} 	getchar(); 	return 0; }    心不错，有人还有一箭双心的

那些 2n、4n、2a 什么的，改成2*n、4*n、2*a C语言中乘号是不能省略的，必须要有*号

引用 3 楼 u010643841 的回复:[quote=引用 1楼小灸舞 的回复:] #include<stdio.h>  # define U 0.06 # define V 0.025  # define M 1.1 # define N 1.2 int main(void) { 	float x, y; 	float m, n;  	for ( y=2; y>=-2; y-=U ) 	{  		for ( x=-1.2; x<=1.2; x+=V) 		{ 			if ( ( ( (x*x + y*y - 1)*(x*x + y*y - 1)*(x*x + y*y - 1) - x*x*y*y*y ) <= 0 ) ) 				printf("*"); 			else 				printf(" "); 		} 		printf("\n"); 	} 	getchar(); 	return 0; }  这个，我现在还看不懂呀，现阶段，我思考的到底有错没，我就想知道我那思路和代码有问题吗[/quote] 楼主代码直接拷贝上来吧，不要截图。。。

引用 2楼ooolinux 的回复:用手机来写程序这么先进平常上班就用手机搞

引用 1楼小灸舞 的回复: #include<stdio.h>  # define U 0.06 # define V 0.025  # define M 1.1 # define N 1.2 int main(void) { 	float x, y; 	float m, n;  	for ( y=2; y>=-2; y-=U ) 	{  		for ( x=-1.2; x<=1.2; x+=V) 		{ 			if ( ( ( (x*x + y*y - 1)*(x*x + y*y - 1)*(x*x + y*y - 1) - x*x*y*y*y ) <= 0 ) ) 				printf("*"); 			else 				printf(" "); 		} 		printf("\n"); 	} 	getchar(); 	return 0; }  这个，我现在还看不懂呀，现阶段，我思考的到底有错没，我就想知道我那思路和代码有问题吗

用手机来写程序这么先进


Question: 文件尾和文件结束标识

feof是测试stream是否设置end-of-file标志，而ftell/seek函数不会设置end-of-file标志符。 你看下面的例子，如果你个文件有5个字节长，那么你从读完5个字节后，feof仍然返回0， 说明文件流没有被end-of-file标志，如果你再多读取一个1个字符，feof就返回非0值了。 那么道理就明白了吧，fseek设置文件指针到文件末尾，末尾也是在文件范围内，只有出 了这个范围才是end-of-file   #include <stdio.h>  int main(void) { 	FILE* fp = NULL; 	long offset = 0; 	int ret = 0; 	char buf[4096]; 	 	fp = fopen("words", "rb"); 	if (NULL == fp) { 		return -1; 	} 	 	fseek(fp, 0, SEEK_END); 	offset = ftell(fp);     printf("offset=%ld\n", offset);          //reset 	fseek(fp, 0, SEEK_SET); 	fread(buf, 1, offset, fp);  	ret = feof(fp); 	printf("feof return %d\n", ret); 	if (ret) { 		printf("the end of file \n"); 	} 	fclose(fp); 	return 0; }

参考楼上的文章， 1、你可能没有在程序开头 #include <stdio.h>  #include <stdlib.h> 2、feof函数在文件结尾会返回一个非0值，这个值跟ftell函数在文件尾读到的offset不知是否一样？你可以采用楼上的count计数方法获得offset

feof Tests for end-of-file on a stream.  int feof( FILE *stream );  Function Required Header Compatibility  feof <stdio.h> ANSI, Win 95, Win NT    For additional compatibility information, see Compatibility in the Introduction.  Libraries  LIBC.LIB Single thread static library, retail version  LIBCMT.LIB Multithread static library, retail version  MSVCRT.LIB Import library for MSVCRT.DLL, retail version    Return Value  The feof function returns a nonzero value after the first read operation that attempts to read past the end of the file. It returns 0 if the current position is not end of file. There is no error return.  Parameter  stream  Pointer to FILE structure  Remarks  The feof routine (implemented both as a function and as a macro) determines whether the end of stream has been reached. When end of file is reached, read operations return an end-of-file indicator until the stream is closed or until rewind, fsetpos, fseek, or clearerr is called against it.  Example  /* FEOF.C: This program uses feof to indicate when  * it reaches the end of the file FEOF.C. It also  * checks for errors with ferror.  */  #include <stdio.h> #include <stdlib.h>  void main( void ) {    int  count, total = 0;    char buffer[100];    FILE *stream;     if( (stream = fopen( "feof.c", "r" )) == NULL )       exit( 1 );     /* Cycle until end of file reached: */    while( !feof( stream ) )    {       /* Attempt to read in 10 bytes: */       count = fread( buffer, sizeof( char ), 100, stream );       if( ferror( stream ) )      {          perror( "Read error" );          break;       }        /* Total up actual bytes read */       total += count;    }    printf( "Number of bytes read = %d\n", total );    fclose( stream ); }   Output  Number of bytes read = 745   Error Handling Routines |  Stream I/O Routines  See Also   clearerr, _eof, ferror, perror


Question: 请问在函数中给指针重新分配内存这样对吗?在这里报错了，求指教!

引用 8 楼 yyxgs 的回复:[quote=引用 5 楼 qq423399099 的回复:] 要修改指针的指向必须传二级指针，或者传一级指针的引用  请问是这样吗? void giveBirth_rabbit(int **rabbit, int rabbitNumber) {  	*rabbit = (int*)realloc(*rabbit, rabbitNumber * sizeof(int)); 	if (!rabbit) { 		printf("兔子增加失败!\n"); 	} }[/quote] 对的

引用 4 楼 akirya 的回复:[quote=引用 3 楼 yyxgs 的回复:] [quote=引用 1 楼 akirya 的回复:] 代码呢???  发了，不好意思...[/quote] 要修改指针参数,那么必须使用指针的指针 int**rabbit [/quote]  请问是这样吗? void giveBirth_rabbit(int **rabbit, int rabbitNumber) {  	*rabbit = (int*)realloc(*rabbit, rabbitNumber * sizeof(int)); 	if (!rabbit) { 		printf("兔子增加失败!\n"); 	} }

引用 6 楼 butters10 的回复:void giveBirth_rabbit(int * &rabbit, int rabbitNumber) ;   请问是这样吗? void giveBirth_rabbit(int **rabbit, int rabbitNumber) {  	*rabbit = (int*)realloc(*rabbit, rabbitNumber * sizeof(int)); 	if (!rabbit) { 		printf("兔子增加失败!\n"); 	} }

引用 5 楼 qq423399099 的回复:要修改指针的指向必须传二级指针，或者传一级指针的引用  请问是这样吗? void giveBirth_rabbit(int **rabbit, int rabbitNumber) {  	*rabbit = (int*)realloc(*rabbit, rabbitNumber * sizeof(int)); 	if (!rabbit) { 		printf("兔子增加失败!\n"); 	} }

要修改指针的指向必须传二级指针，或者传一级指针的引用

void giveBirth_rabbit(int *rabbit, int rabbitNumber) {  	rabbit = (int*)realloc(rabbit, rabbitNumber * sizeof(int)); 	if (!rabbit) { 		printf("兔子增加失败!\n"); 	} }

引用 3 楼 yyxgs 的回复:[quote=引用 1 楼 akirya 的回复:] 代码呢???  发了，不好意思...[/quote] 要修改指针参数,那么必须使用指针的指针 int**rabbit

引用 1 楼 akirya 的回复:代码呢???  发了，不好意思...

代码呢???


Question: c程序界面问题

仅供参考： 从C语言的菜单界面管理系统到C++ Builder的图形用户界面，一个简单的电话簿Demo例子  http://blog.163.com/tab_98/blog/static/1192409720158673337998/

仅供参考：#pragma comment(lib,"user32") #pragma comment(lib,"gdi32") #include <windows.h> LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) {     PAINTSTRUCT ps;     HDC hdc;     HFONT hfont,ohfont;     RECT r;     COLORREF oc;      switch(message) {     case WM_CLOSE://按Alt+F4退出         PostQuitMessage(0);         break;     case WM_PAINT:         BeginPaint(hWnd, &ps);         hdc = ps.hdc; // the device context to draw in         GetClientRect(hWnd, &r); // Obtain the window's client rectangle         hfont = CreateFont(200, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "宋体");         ohfont=(HFONT)SelectObject(hdc,hfont);         oc=SetTextColor(hdc,0x00C080FF);         SetBkMode(hdc, TRANSPARENT);         TextOut(hdc,r.left+r.right/2-600, r.top+r.bottom/2-100,"最短画图程序",12);         SelectObject(hdc,ohfont);         SetTextColor(hdc,oc);         DeleteObject(hfont);         EndPaint(hWnd, &ps);         break;     default:         return DefWindowProc(hWnd, message, wParam, lParam);     }     return 0; } int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) {     MSG msg             = {0};     WNDCLASS wc         = {0};     HBRUSH hbrh;     hbrh=CreateSolidBrush(0x00000000);     wc.lpfnWndProc      = WndProc;     wc.hInstance        = hInstance;     wc.hbrBackground    = hbrh;     wc.lpszClassName    = "minwindowsapp";     wc.hCursor          = LoadCursor(NULL,IDC_ARROW);     if( FAILED(RegisterClass(&wc)) ) return 1;      if(FAILED(CreateWindow(wc.lpszClassName,                         "Minimal Windows Application",                         WS_POPUP|WS_VISIBLE,                         0,                         0,                         GetSystemMetrics(SM_CXSCREEN),                         GetSystemMetrics(SM_CYSCREEN),                         0,                         0,                         hInstance,                         NULL)))         return 2;      while( GetMessage( &msg, NULL, 0, 0 ) > 0 ) {         DispatchMessage( &msg );     }     DeleteObject(hbrh);     return 0; }

1 QT 2 MFC 3 WPF 4 WINFORM 5 GTK


Question: Linux C下使用openssl实现SSL双向认证服务端代码实现

在握手之前需要使用SSL_CTX_set_verify(SSL_CTX* ctx,int mode,int (*verify_callback)(int,X509_STORE_CTX*)); 接口来配置对应ssl类是否认证对方证书。

问下 你这个问题解决了吗， 我这边遇到个类似的问题; 方便的话，还想请教下；

// 初始化CTX SSL_library_init(); OpenSSL_add_all_algorithms(); SSL_load_error_strings(); SSL_CTX_new( TLSv1_client_method());  // 请求获取服务端证书 SSL_CTX_set_verify( ctx, SSL_VERIFY_PEER, verify_cb)  //加载客户端证书 SSL_CTX_load_verify_locations(); SSL_CTX_set_default_passwd_cb_userdata(); SSL_CTX_use_certificate_file() SSL_CTX_use_PrivateKey_file(); SSL_CTX_check_private_key();  //创建socket，略 connect()  // 加入SSL SSL_new(); SSL_set_fd(); SSL_connect();  这个是我的双向认证客户端模型，连接别人的服务端没有问题，但是连我自己的服务端就是连不上，SSL_connect()失败。

别人是java写的服务端，客户端证书是别人提供的，连接没有问题。

引用 2 楼 zhuzhisen 的回复:[quote=引用 1 楼 pengzhixi 的回复:] 一般是单向认证即客户端验证服务端证书，握手的时候服务端需要发送证书给客户端，以及公钥，选择的加密套件等  你这种是单向认证的情况，调用SSL_accept()就自动完成了，我的问题就是双向认证该怎么实现，如何从代码里面体现出来？[/quote]SSL_CTX_set_verify你这里不是要求了要进行客户端验证的么

建立socket连接之前 设置要求验证对端参数，只要是下面几个函数 SSL_CTX_set_verify,  SSL_set_verify,  SSL_CTX_set_verify_depth, SSL_set_verify_depth

引用 1 楼 pengzhixi 的回复:一般是单向认证即客户端验证服务端证书，握手的时候服务端需要发送证书给客户端，以及公钥，选择的加密套件等  你这种是单向认证的情况，调用SSL_accept()就自动完成了，我的问题就是双向认证该怎么实现，如何从代码里面体现出来？


Question: C语言，不要c++版本的怎么写？

对于20%的数据，N<=1000  对于100%的数据，N<=10000000  这什么意思

http://blog.csdn.net/iwm_next/article/details/7450424 参考编程之美


Question: 求大神帮忙看看，if语句总是执行第一条

比较用的是==,不是=，前者是比较，后者是赋值

引用 2 楼 qq423399099 的回复:楼上正解 附上易犯错误:http://m.blog.csdn.net/article/details?id=18666263 谢谢！！！

引用 1 楼 user-2 的回复:比较用的是==,不是=，前者是比较，后者是赋值 试过，真的解决了！谢谢！！！


Question: 求助：分块矩阵乘法，分块后各个子块之间相乘时候，如何控制元素下标？

上 VLA ，  楼主可以看 6.7.6.3, 或者上一页也行。 这样写：  void func(int , int , float[*][*]); //prototype void func(int m, int n, float A[m][n]){}  然后函数里就可以直接用 A[i][j]

那就struct封装成员数据和函数指针吧，又不用继承等性质

引用 4 楼 ArthurJava 的回复:自己写个matrix类 亲这个程序目前需要使用C语言来实现，不好使用类。

自己写个matrix类

这个是我的意思，第一个代码太复杂了，意思是上述图片中的意思。请高手帮忙！  #include <stdio.h> #include <stdlib.h> typedef float data_type; //定义为32位浮点数   //暴力矩阵乘法 void R_Mult_tst(data_type *A[], data_type *B[], data_type *C[],int m,int n,int p) { 	int i=0, j=0, k=0; 	for (i = 0; i < m; i++) { //m行号 		for (j = 0; j < n; j++) { //列号 			for (k = 0; k < p; k++) {//并行 				//C[i][k] += A[i][j] * B[j][ k]; 			} 			printf("\n"); 		} 	} }  int main(void) {     int i=0,j=0;     data_type A[4][4] = {1.0,2.0,3.0,4.0,1.0,2.0,3.0,4.0,1.0,2.0,3.0,4.0,1.0,2.0,3.0,4.0};     data_type B[4][4] = {1.0,2.0,3.0,4.0,1.0,2.0,3.0,4.0,1.0,2.0,3.0,4.0,1.0,2.0,3.0,4.0};     data_type C[4][4]={0.0}; //将数组元素初始化为全0,防止出现莫名其妙的运算结果。     //这里如何采用二维数组的方式来传递参数，以便控制元素的下标？     R_Mult_tst(A[0],B[0],C[0],4,4,4); //调用暴力矩阵乘法      return 0; }

hehe ,如果用二位数组当作参数，用： 1. void R_Mult_tst(data_type A[][4], data_type B[][4], data_type C[][4],int m,int n,int p); 含义是必须指定列的大小！ 2.用二重指针void R_Mult_tst(data_type **A, data_type **B, data_type **C,int m,int n,int p);


Question: 请问用socket发送邮件的设计思路是什么？（C语言）

邮件先上传到服务器，接收者再从服务器下载吧

需要具备的知识： 1.TCP/IP协议会socket编程 2.POP3和SMTP协议  这些都会了，就不需要设计什么了。


Question: 问一下二叉搜索树的一个遍历问题？

所有不带else的if都给未来埋下了逻辑隐患。

楼上正解，主要确保返回的不是一个NULL指针

如果左右子树不为空，则返回该子树指针

给定一颗二叉搜索树，请找出其中的第k大的结点。例如， 5 / \ 3 7 /\ /\ 2 4 6 8 中，按结点数值大小顺序第三个结点的值为4。

TreeNode* KthNode(TreeNode* pRoot, unsigned int k)     {         if(pRoot){                  TreeNode *ret = KthNode(pRoot->left, k);                 if(ret) return ret;                 if(++count == k) return pRoot;                 ret = KthNode(pRoot->right,k);                 if(ret) return ret;         }         return nullptr;     }


Question: c语言两大难兄难弟之副作用！谁有最详细的官方资料

理解和讨论之前请先学会如何观察！  计算机组成原理→DOS命令→汇编语言→C语言（不包括C++）、代码书写规范→数据结构、编译原理、操作系统→计算机网络、数据库原理、正则表达式→其它语言（包括C++）、架构……  对学习编程者的忠告： 多用小脑和手，少用大脑、眼睛和嘴，会更快地学会编程！ 眼过千遍不如手过一遍！ 书看千行不如手敲一行！ 手敲千行不如单步一行！ 单步源代码千行不如单步Debug版对应汇编一行！ 单步Debug版对应汇编千行不如单步Release版对应汇编一行！ 不会单步Release版对应汇编？在你想单步Release版C/C++代码片断的前面临时加一句DebugBreak();重建所有，然后在IDE中运行。（一般人我不告诉他！）

[1]. C++ Reference Guide [2]. Stack Overflow: What exactly is a 'side-effect' in C++? [3].side effect in c

Accessing a volatile object, modifying an object, modifying a file, or calling a function that does any of those operations are all side effects, 11) which are changes in the state of the execution environment

引用 1 楼 yuelengdihai 的回复:c语言解决问题思路是面向过程的 使用指针，分配和释放内存要自己手动操作  ?什么意思呀，我说的是有没有side effect的官方解释资料

c语言解决问题思路是面向过程的 使用指针，分配和释放内存要自己手动操作


Question: 用C做一个六边形怎么做啊？(c语言)

引用 7楼一根烂笔头 的回复:寻找相应的图形开发库，不建议自己在终端里画好的

寻找相应的图形开发库，不建议自己在终端里画

引用 5楼赵4老师 的回复:百度找不到在MSDN里面找。 原理参考《高中数学》三角函数。好的

百度找不到在MSDN里面找。 原理参考《高中数学》三角函数。

用三角函数吧

引用 2 楼 zhao4zhong1 的回复:#pragma comment(lib,"user32") #pragma comment(lib,"gdi32") #include <stdio.h> #include <stdlib.h> #include <math.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;     int x[6],y[6];     int i;      for (i=0;i<6;i++) {         x[i]=150+(int)(100.0*cos(i*60.0/180.0*3.1416));         y[i]=150+(int)(100.0*sin(i*60.0/180.0*3.1416));     }     system("color F0");     system("cls");     HideTheCursor();     hwnd  = GetConsoleWindow();     hdc   = GetDC(hwnd);     MoveToEx(hdc,x[0],y[0],NULL);     LineTo(hdc,x[1],y[1]);     LineTo(hdc,x[2],y[2]);     LineTo(hdc,x[3],y[3]);     LineTo(hdc,x[4],y[4]);     LineTo(hdc,x[5],y[5]);     LineTo(hdc,x[0],y[0]);     ReleaseDC(hwnd,hdc);     getchar();     system("color 07");     system("cls");     ShowTheCursor();     return 0; }  想问问原理是什么？需要用到哪些函数？有的百度找不到啊

想问问原理是什么，用到了什么函数？


Question: 关于C语音指针的问题

引用 9 楼 Rewen 的回复:嗯，要实现楼主的void Init_SeqQueue(SeqQueue Sq_pointer) ” “Init_SeqQueue(ListQueue); 做法的话，需要在SeqQueue 中实现拷贝构造函数。 又一个用C++回答C问题的人

理解和讨论之前请先学会如何观察！  计算机组成原理→DOS命令→汇编语言→C语言（不包括C++）、代码书写规范→数据结构、编译原理、操作系统→计算机网络、数据库原理、正则表达式→其它语言（包括C++）、架构……  对学习编程者的忠告： 多用小脑和手，少用大脑、眼睛和嘴，会更快地学会编程！ 眼过千遍不如手过一遍！ 书看千行不如手敲一行！ 手敲千行不如单步一行！ 单步源代码千行不如单步Debug版对应汇编一行！ 单步Debug版对应汇编千行不如单步Release版对应汇编一行！ 不会单步Release版对应汇编？在你想单步Release版C/C++代码片断的前面临时加一句DebugBreak();重建所有，然后在IDE中运行。（一般人我不告诉他！）  单步类的实例“构造”或“复制”或“作为函数参数”或“作为函数返回值返回”或“参加各种运算”或“退出作用域”的语句对应的汇编代码几步后，就会来到该类的“构造函数”或“复制构造函数”或“运算符重载”或“析构函数”对应的C/C++源代码处。  VC调试时按Alt+8、Alt+7、Alt+6和Alt+5,打开汇编窗口、堆栈窗口、内存窗口和寄存器窗口看每句C对应的汇编、单步执行并观察相应堆栈、内存和寄存器变化，这样过一遍不就啥都明白了吗。 对VC来说，所谓‘调试时’就是编译连接通过以后，按F10或F11键单步执行一步以后的时候，或者在某行按F9设了断点后按F5执行停在该断点处的时候。 （Turbo C或Borland C用Turbo Debugger调试,Linux或Unix下用GDB调试时,看每句C对应的汇编并单步执行观察相应内存和寄存器变化。）  想要从本质上理解C指针，必须学习汇编以及C和汇编的对应关系。 从汇编的角度理解和学习C语言的指针，原本看似复杂的东西就会变得非常简单！ 指针即地址。“地址又是啥？”“只能从汇编语言和计算机组成原理的角度去解释了。” 但我又不得不承认：  有那么些人喜欢或者适合用“先具体再抽象”的方法学习和理解复杂事物；  而另一些人喜欢或者适合用“先抽象再具体”的方法学习和理解复杂事物。 而我本人属前者。  不要企图依赖输出指针相关表达式...的值【比如printf("%p\n",...);或者cout<<...】来理解指针的本质， 而要依赖调试时的反汇编窗口中的C/C++代码【比如void *p=(void *)(...);】及其对应汇编指令以及内存窗口中的内存地址和内存值来理解指针的本质。  这辈子不看内存地址和内存值；只画链表、指针示意图，画堆栈示意图，画各种示意图，甚至自己没画过而只看过书上的图……能从本质上理解指针、理解函数参数传递吗？本人深表怀疑！ 这辈子不种麦不收麦不将麦粒拿去磨面；只吃馒头、吃面条、吃面包、……甚至从没看过别人怎么蒸馒头，压面条，烤面包，……能从本质上理解面粉、理解面食吗？本人深表怀疑！！  提醒： “学习用汇编语言写程序” 和 “VC调试(TC或BC用TD调试)时按Alt+8、Alt+7、Alt+6和Alt+5,打开汇编窗口、堆栈窗口、内存窗口和寄存器窗口看每句C对应的汇编、单步执行并观察相应堆栈、内存和寄存器变化，这样过一遍不就啥都明白了吗。 （Linux或Unix下可以在用GDB调试时,看每句C对应的汇编并单步执行观察相应内存和寄存器变化。） 想要从本质上理解C指针，必须学习C和汇编的对应关系。” 不是一回事！  不要迷信书、考题、老师、回帖； 要迷信CPU、编译器、调试器、运行结果。 并请结合“盲人摸太阳”和“驾船出海时一定只带一个指南针。”加以理解。 任何理论、权威、传说、真理、标准、解释、想象、知识……都比不上摆在眼前的事实！  有人说一套做一套，你相信他说的还是相信他做的？ 其实严格来说这个世界上古往今来所有人都是说一套做一套，不是吗？  不要写连自己也预测不了结果的代码！  电脑内存或文件内容只是一个一维二进制字节数组及其对应的二进制地址； 人脑才将电脑内存或文件内容中的这个一维二进制字节数组及其对应的二进制地址的某些部分看成是整数、有符号数/无符号数、浮点数、复数、英文字母、阿拉伯数字、中文/韩文/法文……字符/字符串、汇编指令、函数、函数参数、堆、栈、数组、指针、数组指针、指针数组、数组的数组、指针的指针、二维数组、字符点阵、字符笔画的坐标、黑白二值图片、灰度图片、彩色图片、录音、视频、指纹信息、身份证信息……  十字链表交换任意两个节点C源代码（C指针应用终极挑战）http://download.csdn.net/detail/zhao4zhong1/5532495

楼主需要知道值传递与地址传递的区别。 楼主的当前程序是地址传递的，在初始化函数内部可以通过形参指针（地址）来修改它所指向的实体，实体就是你要修改的队列。 但是如果像楼主想的那样，改成值传递的话，函数的形参是实体（队列）的一个副本，它与实体的内容一开始是相同的，但是它与实体两个是互相独立的，你在初始化函数内部只是修改了那个副本，而没有修改那个实体。 我想这就是你所要知道的“为什么”。

1.你当然可以在函数Init_SeqQueue(SeqQueue *Sq_pointer) 中将参数Sq_pointer设置为SeqQueue Sq，这时Sq是实参的一个副本，也就是说在Init_SeqQueue函数中要建立一个SeqQueue类型的变量Sq，保存ListQueue的所有值，那么Sq_pointer->Front =-1; Sq_pointer->Rear=-1;完成的是对Sq的初始化，而不是希望的对ListQueue初始化。 2.采用Init_SeqQueue(SeqQueue *Sq_pointer) 形式，此处的Sq_pointer就指向了实参ListQueue，Sq_pointer->Front =-1; Sq_pointer->Rear=-1;就是对ListQueue的Front ，Rear的赋值 因此Init_SeqQueue(SeqQueue *Sq_pointer)这个函数的参数一般必须是指针

指针就是为带入函数修改产量而生的。

void sw(int* a, int* b) { int temp; temp=*a; *a=*b; *b=temp; }  int main(void) { int m=3, n=4; printf("b:%d,%d\n", m, n); sw(&m, &n); printf("a:%d,%d\n", m, n); return 0; }你这个同上面这个应该是一个意思，你把指针去掉传值调用就没有用

不使用指针的话，那么Init_SeqQueue函数内的Sq_pointer只是main函数里的ListQueue变量的一个拷贝 你修改Init_SeqQueue函数内的Sq_pointer根本就影响不到main函数里的ListQueue

当然可以的，同时Sq_pointer->Front =-1; 不能用->，只能用.  当然，这个只是语法上的允许而已，这样的程序达不到修改结点的目的了。就是函数按值传递和按引用传递的区别。  百度一下按值传递就知道了。

你这个程序的目的是初始化队列，你如果不使用指针直接传变量的话，初始化后的形参作为局部变量就无法返回，就达不到初始化的目的。


Question: 请高手指导代码bug

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

#include<stdio.h> #include<malloc.h> typedef int score; typedef int number; typedef  char sex; typedef char name; //extern  int N; int N; struct student { 	name nam[100]; 	sex s; 	number num; 	score sc; }; void seq_student(struct student *p)  //插入函数// { 	int m,j; 	struct student *q; 	printf("请检查你输入的信息是否有遗漏。若有遗漏请输入数字'1':"); 	scanf("%d",&j);	 	if(j==1)  { 		printf("输入遗漏的位置\n:"); 		scanf("%d",&m); 		p=p+m-1; 		q=p; 		printf("输入遗漏的学生信息\n:"); 		scanf("%s%c%d%d",&p->nam[100],&p->s,&p->num,&p->sc); 		while(m<N) 		{ 			++m; 			p=q; 		} 	} } void serach_for_student(struct student *p)    //查找学生信息// { 	int nu,i; 	printf("输入学生的学号:"); 	scanf("%d",&nu); 	for(i=0;i<=N;i++) 	{ 		if(nu==p->num) 			printf("%s%c%d%d",p->nam[100],p->s,p->num,p->sc); 		else printf("该学生不存在"); 	} } void main() { 	int i; 	struct student *stu=NULL; 	printf("请输入学生的个数\n:"); 	scanf("%d",&N);  	stu=(struct student*)malloc(sizeof(struct student)*N); 	printf("请输入学生的姓名、性别、学号及该学科成绩\n:"); for(i=0;i<N;i++) scanf("%s%c%d%d",&stu[i].nam[100],&stu[i].s,&stu[i].num,&stu[i].sc); 	//seq_student(struct student stu); 	seq_student(stu); 	//serach_for_student(struct student stu); 	serach_for_student(stu); }

另外，多注意类型；地址和值的关系；scanf要求变量的地址；

#include<stdio.h> #include<malloc.h>   typedef int score; typedef int number; typedef char sex; typedef char name;  int N;  struct student {   name nam[100];   sex s[16];   number num;   score sc; }; void seq_student (struct student *p)	//插入函数// {   int m, j;   struct student *q;   printf("请检查你输入的信息是否有遗漏。若有遗漏请输入数字'1':");   scanf ("%d", &j);   if (j == 1){        printf ("输入遗漏的位置\n:");       scanf ("%d", &m);       p = p + m - 1;       q = p;       printf ("输入遗漏的学生信息\n:");       scanf ("%s%s%d%d", p->nam, p->s, &p->num, &p->sc);     while (m < N) 	{ 	  ++m; 	  p = q; 	}   } }  void serach_for_student (struct student *p)	//查找学生信息// {   int nu, i;   printf ("输入学生的学号:");   scanf ("%d", &nu);   for (i = 0; i <= N; i++)     {       if (nu == p->num) 	    printf ("%s%s%d%d", p->nam, p->s, p->num, p->sc);       else 	printf ("该学生不存在");     } }  int main (void) {   int i;   struct student *stu = NULL;   printf ("请输入学生的个数\n:");   scanf ("%d", &N);   stu = (struct student *) malloc (sizeof (struct student) * N);   if (NULL == stu) {     printf("Malloc error!\n");     return -1;   }   printf ("请输入学生的姓名、性别、学号及该学科成绩\n:");   for (i = 0; i < N; i++)     scanf ("%s%s%d%d", stu[i].nam, stu[i].s, &(stu[i].num), &(stu[i].sc));   seq_student (stu);   serach_for_student (stu);   return 0; }   注意的地方：scanf输入时对于%c的输入尤为小心；因为它是接收一个字符，空格，回车很可能会被其接收；那么你输入学生信息时注意；要么把它和其他信息输入分开，要么可以考虑用其他类型表述这个信息；我上面用了字符串；（性别：male, female）；否则通过测试你会发现，你正常输入的会充斥到seq_student()函数中；导致改函数中的输入被上次的输入充斥；

Main 函数里面， N没有声明。

哦， 在这里定义了。 extern  int N;

最后两句 seq_student(struct student stu); serach_for_student(struct student stu); 改为 seq_student(stu); serach_for_student(stu);

seq_student(struct student stu);改为seq_student(stu); serach_for_student(struct student stu);改为serach_for_student(stu); 传参不需要加上结构体类型名  #include<stdio.h> #include<malloc.h> typedef int score; typedef int number; typedef  char sex; typedef char name; extern  int N; struct student { 	name nam[100]; 	sex s; 	number num; 	score sc; }; void seq_student(struct student *p)  //插入函数// { 	int m,j; 	struct student *q; 	printf("请检查你输入的信息是否有遗漏。若有遗漏请输入数字'1':"); 	scanf("%d",&j);	 	if(j==1)  	{ 		printf("输入遗漏的位置\n:"); 		scanf("%d",&m); 		p=p+m-1; 		q=p; 		printf("输入遗漏的学生信息\n:"); 		scanf("%s%c%d%d",&p->nam[100],&p->s,&p->num,&p->sc); 		while(m<N) 		{ 			++m; 			p=q; 		} 	} } void serach_for_student(struct student *p)    //查找学生信息// { 	int nu,i; 	printf("输入学生的学号:"); 	scanf("%d",&nu); 	for(i=0;i<=N;i++) 	{ 		if(nu==p->num) 			printf("%s%c%d%d",p->nam[100],p->s,p->num,p->sc); 		else printf("该学生不存在"); 	} } void main() { 	int i; 	struct student *stu=NULL; 	printf("请输入学生的个数\n:"); 	scanf("%d",&N);  	stu=(struct student*)malloc(sizeof(struct student)*N); 	printf("请输入学生的姓名、性别、学号及该学科成绩\n:"); 	for(i=0;i<N;i++) scanf("%s%c%d%d",&stu[i].nam[100],&stu[i].s,&stu[i].num,&stu[i].sc); 	seq_student(stu); 	serach_for_student(stu); }


Question: 就是用数据结构做一个金钩钓鱼.c

引用 7 楼 lgbxyz 的回复:写了个简单的demo，没怎么测试，大小王也没做处理，仅供参考   #include <time.h> #include <stdio.h> #include <string.h> #include <stdlib.h>   #define MAX_PLAYER (3)  typedef enum _card_type { 	Spade = 0, 	//黑桃 	Heart,		//红桃 	Diamond,	//方块 	Club, 		//梅花 	Joker, 		//大王/小王 }card_type_t;  const static char* card_type_str[] = { 	"黑桃", 	//黑桃 	"红桃",	//红桃 	"方块",	//方块 	"梅花", 	//梅花 	"王", 	//大王/小王 };  typedef enum _card_value { 	CV_A = 1,  	CV_2, CV_3, CV_4, CV_5,  	CV_6, CV_7, CV_8, CV_9,  	CV_10, CV_J, CV_Q, CV_K,  	CV_RJ, //RedJokeker 	CV_BJ //BlackJoker }card_value_t;  const static char* card_value_str[] = { 	NULL, //dummy data for 0 	"A", "2", "3", "4", "5", 	"6", "7", "8", "9", "10", 	"J", "Q", "K", "大王", 	"小王" };  typedef struct _card_element { 	int card_index; // 1 - 54 	card_type_t  card_type; 	card_value_t card_value; }card_element_t;  typedef struct _card_list { 	card_element_t* elm; 	struct _card_list* next; }card_list_t;   //card num to element #define CRD_NUM_TO_ELM(num, elm)  { 	\ 	int val1 = num % CV_K;				\ 	int val2 = num / CV_K;				\ 	(elm)->card_index = num;			\ 	if (0 == val1) {					\ 		(elm)->card_type = 				\ 		((val2 == 0) ? 0 : (val2-1));	\ 		(elm)->card_value = CV_K;		\ 	} else {							\ 		(elm)->card_type = val2;		\ 		(elm)->card_value = val1;		\ 	}									\ } 						 //card element to str #define CRD_ELM_TO_STR(elm, str) { 							\ 	if ((elm)->card_type != Joker) {						\ 		strcpy(str, card_type_str[(elm)->card_type]);		\ 		strcat(str, card_value_str[(elm)->card_value]);		\ 	}else {													\ 		strcpy(str, card_value_str[(elm)->card_value+13]);	\ 	}														\ }  //card element to str #define CRD_NUM_TO_STR(num, str) { 							\ 	card_element_t elm;										\ 	CRD_NUM_TO_ELM(num, &elm);								\ 	CRD_ELM_TO_STR(&elm, str);								\ }   typedef struct _card_sequence { 	card_element_t elm[54]; 	card_element_t first_hand; //先手牌  }card_sequence_t;  typedef struct _card_player { 	char name[64]; //player name 	int card_num; 	card_list_t* head; //for pop 	card_list_t* tail; // for append }card_player_t;   char* get_card_str(card_element_t* elm) { 	static char str[64]; 	CRD_ELM_TO_STR(elm, str); 	return str; }  //洗牌  void poker_shuffle(card_sequence_t* sequence) {//FisherYates shuffle 	int arr[54] = {0};     int i, j;     char temp;          for (i = 1; i < 55; i++)     {     	arr[i-1] = i; 	}       if (i == 0) return; 	     srand(time(NULL)); 	     i = 54;     while (--i) {         j = rand() % (i+1);         temp = arr[i];         arr[i] = arr[j];         arr[j] = temp;     } 	 	for (i = 0; i < 54; i++) 	{ 		CRD_NUM_TO_ELM(arr[i], &sequence->elm[i]); 	} 	i = rand() % 53 + 1; 	CRD_NUM_TO_ELM(i, &sequence->first_hand); }  //抓牌 void poker_dispatch(card_sequence_t* sequence, card_player_t player[MAX_PLAYER]) { 	int i = 0, j = 0, k = 0; 	card_list_t *list = NULL; 	  	k = 54 / MAX_PLAYER; 	while (k--) { 		for (i = 0; i < MAX_PLAYER; i++) { 			list = (card_list_t *)calloc(sizeof(card_list_t), 1); 			list->elm = &(sequence->elm[j++]); 			list->next = NULL; 			if (NULL == player[i].tail) { 				player[i].head = list; 				player[i].tail = list; 			} else { 				player[i].tail->next = list; 				player[i].tail = list; 			} 			player[i].card_num++; 		} 	} }  //出牌 int poker_push_card(card_player_t *player) { 	int i, j, k = 0; 	static card_element_t* cards[54]; 	static int idx; 	static int losers = 0; 	card_list_t* list = NULL; 	card_list_t* temp = NULL;  	if (player->card_num <= 0) { 		return 0; 	} START: 	list = player->head; 	player->head = list->next; 	player->card_num--; 	cards[idx++] = list->elm; 	printf("%s[还有%2d张牌]%s出牌:%s ", player->name, player->card_num, \ 		((k == 0)?"":"继续"), get_card_str(list->elm));   	for (i = idx - 2; i >= 0 ; i--) { 		if (Joker == list->elm->card_type) { 			break; 		} 		else if (list->elm->card_value == CV_J) { 			k++; 			printf("赢得所有牌(%d张牌):", idx); 			for (j = idx - 1; j >= 0; j--) { 				temp = (card_list_t *)calloc(sizeof(card_list_t), 1); 				temp->elm = cards[j]; 				temp->next = NULL; 				player->tail->next = temp; 				if (NULL == player->head) { 					player->head = temp; 				} 				player->tail = temp; 				player->card_num++; 				idx--; 				printf("%s ", get_card_str(cards[j])); 			} 			free(list); 			list = NULL; 			printf("\n"); 			goto START; 		} 		else if (list->elm->card_value == cards[i]->card_value) { 			k++; 			printf("赢得%d张牌:", idx-i); 			for (j = idx - 1; j >= i; j--) { 				temp = (card_list_t *)calloc(sizeof(card_list_t), 1); 				temp->elm = cards[j]; 				temp->next = NULL; 				player->tail->next = temp; 				player->tail = temp; 				if (NULL == player->head) { 					player->head = temp; 				} 				player->card_num++; 				idx--; 				printf("%s ", card_value_str[cards[j]->card_value]); 			} 			free(list); 			list = NULL; 			printf("\n"); 			goto START; 		} 	}  	if (list) { 		free(list); 	} 	printf("\n");  	if (player->card_num <= 0) { 		losers++; 		printf("[%s]出局!\n", player->name); 		if (losers == (MAX_PLAYER - 1)) { 			return 1; 		} 	} 	return 0; }  //游戏 void poker_run_fish(card_player_t player[MAX_PLAYER]) { 	int i = 0; 	 	while (1) { 		i = 0; 		for (i = 0; i < MAX_PLAYER; i++) { 			if (1 == poker_push_card(&player[i])) { 				return; 			} 		} 	} }  void free_player_info(card_player_t player[MAX_PLAYER]) { 	int i = 0; 	card_list_t* list = NULL; 	 	for (i = 0; i < MAX_PLAYER; i++) { 		list = player[i].head; 		while (list != NULL) { 			player[i].head = list->next; 			free(list); 			list = player[i].head; 		} 	} }   int main(void) { 	int i = 0; 	card_sequence_t seq; 	card_player_t player[MAX_PLAYER]; 	 	poker_shuffle(&seq); 	 	memset(player, 0x00, sizeof(player)); 	 	//name the player 	for (i = 0; i < MAX_PLAYER; i++) 	{ 		sprintf(player[i].name, "player_%d", i + 1); 	} 	 	poker_dispatch(&seq, player); 	 	poker_run_fish(player); 	 	for (i = 0; i < MAX_PLAYER; i++) { 		if (player[i].card_num > 0) { 			printf("%s 获胜(%2d)!!!!!!!!!\n", player[i].name, player[i].card_num); 			break; 		} 	}  	free_player_info(player); 	 	return 0; }    没事的，不用管大小王。我们的要求其实只是数字就可以了。不用想太多

引用 3 楼 zhao4zhong1 的回复:全部用数组即可。这个有特殊要求

全部用数组即可。

我们叫“弥竹竿”

原来是叫这个名字啊，小时候玩过

引用 4 楼 zhao4zhong1 的回复:洗牌参考：#include <stdio.h> #include <stdlib.h> #include <time.h> int d[6]; int i,n,a,b,t; int c,j; void main() {     srand(time(NULL));     printf("shuffle 0..n-1 demo\n");     for (n=1;n<=5;n++) {/* 测试1～5个元素 */         printf("_____n=%d_____\n",n);         j=1;         for (c=1;c<=n;c++) j=j*c;/* j为n! */         j*=n*2;         for (c=1;c<=j;c++) {/* 测试n*2*n!次 */             for (i=0;i<n;i++) d[i]=i;/* 填写0～n-1 */             for (i=n;i>0;i--) {/* 打乱0～n-1 */                 a=i-1;b=rand()%i;                 if (a!=b) {t=d[a];d[a]=d[b];d[b]=t;}             }             printf("%04d:",c);             for (i=0;i<n;i++) printf("%d",d[i]);             printf("\n");         }     }     printf("shuffle 1..n demo\n");     for (n=1;n<=5;n++) {/* 测试1～5个元素 */         printf("_____n=%d_____\n",n);         j=1;         for (c=1;c<=n;c++) j=j*c;/* j为n! */         j*=n*2;         for (c=1;c<=j;c++) {/* 测试n*2*n!次 */             for (i=1;i<=n;i++) d[i]=i;/* 填写1～n */             for (i=n;i>1;i--) {/* 打乱1～n */                 a=i;b=rand()%i+1;                 if (a!=b) {t=d[a];d[a]=d[b];d[b]=t;}             }             printf("%04d:",c);             for (i=1;i<=n;i++) printf("%d",d[i]);             printf("\n");         }     } } 这个不需要洗牌，但还是感谢这位大哥


Question: 请问：以下程序功能是求一个什么数

rg是2~31 i%rg[j]!=0：rg[j]不是i的约数， hit==2：rg中不是i约数的数有2个 hit1+1==hit2：这2个 不是i约数的数 是相邻的 这里把  不是i约数的2个数 称为 非约数对，那么有以下定理： 定理1:2~31中除去 非约数对 以外的数都是i的约数。这里把 2~31中除去 非约数对 以外的数 称为 准约数。 定理2:i的最小正值为 所有准约数 的最小公倍数，设此值为T。  首先，非约数对不可能包含2~15的数，因为如果 非约数对 包含2~15的数（设为k），那么2k<31,由定理1，2k是i的约数，那么k肯定也是i的约数，与前提矛盾。所以，非约数对不可能包含2~15的数。 那么，16~31中,非约数对可以包含质数（准约数中不包含此质数，那么，此质数就不是T的约数），也可以包含 质数^n 形式的数（设这种数为x=p^n，那么2~31中，设除x以外的数的最小公倍数为y，对y分解质因数，p的指数必然是n-1）。所以，非约数对 可以包含：16，17，19，23，25，27，29，31。其中，相邻的只有16,17。所以，所求 非约数对 为 16,17。  那么，i的最小正值T就是2~15,18~31的最小公倍数：2123581660200。i的通项为：2123581660200*k(其中k为奇数，且k不是17的倍数)。  但是，INT_MAX：2147483647，2123581660200>2147483647，所以原程序不会输出任何数。

求I 并且最后会显示1

这个程序根本求不出数吧 rg先初始化成2,3,4......30,31 然后是i从1循环到INT_MAX，每次循环开始hit=0;hit1=hit2=-1; 然后是内层j循环，如果满足if(i%rg[j]!=0)那么进入分支  代码功能归根结底不是别人帮自己看或讲解或注释出来的；而是被自己静下心来花足够长的时间和精力亲自动手单步或设断点或对执行到某步获得的中间结果显示或写到日志文件中一步一步分析出来的。 提醒：再牛×的老师也无法代替学生自己领悟和上厕所！ 单步调试和设断点调试（VS IDE中编译连接通过以后，按F10或F11键单步执行，按Shift+F11退出当前函数；在某行按F9设断点后按F5执行停在该断点处。）是程序员必须掌握的技能之一。

执行到最后没有满足if(hit==2 && hit1+1==hit2)，所以也没printf("%ld\n",i);


Question: vs2012 嵌入汇编大小写转换

结果大写字母并没有转成小写 求原因


Question: 为什么结构不可以用名字来传递地址？而且可以赋值给同类型的结构？

因为同一类型的不同元素个数的数组，是两种数据类型 而C为了方便，在表达式中刻意不去区分两种元素个数不同的数组。 因此，数组赋值的时候，没有办法知道数组的元素个数。 此外，也因此没法统一，对不同元素个数的数组赋值. int a[1], int b[2]; a=b ;这个式子中，解析的时候，并不考虑a,b 都有几个元素。 假设允许赋值， 按照现有规则 a,b都只会解析为数组首元素的地址。 这两个地址值a,b都是不可写的，因此不能赋值。  如果扩充一下，允许赋值。 这里又存在二义性了，到底应该给a的几个元素赋值？ 这个赋值表达什么意思，也就是不确定的了 因此，C没法对数组赋值。  如果，仅仅允许相同元素个数的数组赋值，还不如干脆不允许更好些。 C++继承了C的这个做法，因此也就没法赋值了。

引用 1 楼 user-2 的回复:结构是类型，而数组是变量。 当你看到类型是结构的数组就知道了。  结构既然是类型，其实就是定义了一个内存布局。  那不是也有用结构类型定义的结构变量？

引用 2 楼 lm_whales 的回复:结构可以整体赋值，也可以整体初始化 数组只能初始化 早期数组和结构都不可以整体赋值，都只能初始化。 结构是不同类型（也可以全同，还可以有位段）的组合。结构的每个成员如何存放，跟对齐模式有关， 成员之间可能有对齐间隙。 数组是同一类型数组的聚合。每个数据之间不存在间隙。  结构的成员按名存取。 数组成员按位置存取。  虽然同是聚合类型，但内部结构是不同的。 编译器处理方式也是不同的。  结构，编译器要知道每个成员的名字，和结构对象本身的名字。 数组，编译器只要知道第一个元素的位置，（以及数组元素个数）， 和整个数组的名字就可以了。 既然数组元素之间不存在内存缝隙，那不是对数组进行相同元素类型的数组赋值更好操作，既然复杂的结构都能赋值，为什么数组不能赋值？


Question: 一个批量改名程序  求教

啊，试了下果然是这样，恍然大悟。 谢谢了^_^

rename 函数执行失败了，因为2个表示路径参数中有'\n'符， fgets后把字符串的‘\n’变成‘\n’


Question: C语言，变量的值没有被改变再次输出的时候出现莫名的值

win7+vc++2010 express 结果(未修改代码)

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

Linux下没有这个问题，windows下没有调试环境也不愿意看代码

刚开始学表示不懂，帮顶期待高手

打断点，单步调试


Question: [C语言]检测socket连接状态

引用 3 楼 赵4老师的回复:为什么不 WinExec("cmd /c netstat -na >netstat.txt",SW_HIDE); //然后读文件netstat.txt的内容 呢？ 你跑题了吧，我问的是socket

引用 1 楼 小灸舞的回复:对端正常close socket，或者进程退出（正常退出或崩溃），对端系统正常关闭 这种情况下，协议栈会走正常的关闭状态转移，使用epoll的话，一般要判断如下几个情况 处理可读事件时，在循环read后，返回结果为0 处理可写事件时，write返回-1，errno为EPIPE EPOLLERR或EPOLLHUP或事件  对端非正常断开，比如服务器断电，网线被拔掉 这种情况下，协议栈无法感知，SO_KEEPALIVE这个选项的超时事件太长并不实用，一般还是以应用层的heartbeat来及时发现 那样太费时间了吧，有没有更直接简单的，比如tcp_info结构


Question: 晕！！！UTF8、ANSI不能互相转换吗

转换是没有问题的,主要是VS不能直接显示UTF-8编码的汉字,所以要写入记事本来检验是不是正常转换了  	char* szAnsi = "卡"; 	char szUtf8[64] = { 0 };  	Convert(szAnsi, szUtf8); 	FILE* fp; 	fopen_s(&fp, "D:\\UTF8.TXT", "wb"); 	fwrite("\xEF\xBB\xBF ", 3, 1, fp); 	fwrite(szUtf8, 4, 1, fp); 	fclose(fp);

对电脑而言没有乱码，只有二进制字节；对人脑才有乱码。啊 GBK:0xB0 0xA1,Unicode-16 LE:0x4A 0x55,Unicode-16 BE:0x55 0x4A,UTF-8:0xE5 0x95 0x8A  void HexDump(char *buf,int len,int addr) {     int i,j,k;     char binstr[80];      for (i=0;i<len;i++) {         if (0==(i%16)) {             sprintf(binstr,"%08x -",i+addr);             sprintf(binstr,"%s %02x",binstr,(unsigned char)buf[i]);         } else if (15==(i%16)) {             sprintf(binstr,"%s %02x",binstr,(unsigned char)buf[i]);             sprintf(binstr,"%s  ",binstr);             for (j=i-15;j<=i;j++) {                 sprintf(binstr,"%s%c",binstr,('!'<buf[j]&&buf[j]<='~')?buf[j]:'.');             }             printf("%s\n",binstr);         } else {             sprintf(binstr,"%s %02x",binstr,(unsigned char)buf[i]);         }     }     if (0!=(i%16)) {         k=16-(i%16);         for (j=0;j<k;j++) {             sprintf(binstr,"%s   ",binstr);         }         sprintf(binstr,"%s  ",binstr);         k=16-k;         for (j=i-k;j<i;j++) {             sprintf(binstr,"%s%c",binstr,('!'<buf[j]&&buf[j]<='~')?buf[j]:'.');         }         printf("%s\n",binstr);     } }

转成UTF8是没问题的 问题是你还是把utf8编码的字符串用GBK来显示，自然就是错误的。

UTF8 是UNICODE 的二次编码，不是UNICODE UTF8 可以视为 ANSI（ASCII） 只是还可以编码 UNICODE

LPTSTR CString::GetBuffer(int nMinBufLength) { 	ASSERT(nMinBufLength >= 0);  	if (GetData()->nRefs > 1 || nMinBufLength > GetData()->nAllocLength) 	{ 。。。。。   GetBuffer参数必须>=0啊

另外  GetBuffer(0) 是不对的，改为 -1  CString szTemp("卡("); CString szTemp1(""); Convert(szTemp1,szTemp.GetBuffer(-1),CP_ACP,CP_UTF8);//变成"鍗?" Convert(szTemp,szTemp1.GetBuffer(-1),CP_UTF8,CP_ACP);//变成"?".  正数和0 得到的是参数个字符 -1得到所有字符  GetBuffer 后，必须释放缓冲，不然可能有泄露

utf-8编码是无法在VS里显示的,可以用UTF8编码写入记事本来查看  void Convert(const char *strIn, char *strOut, int sourceCodepage=CP_ACP, int targetCodepage=CP_UTF8) { 	int len = lstrlenA(strIn); 	int unicodeLen = MultiByteToWideChar(sourceCodepage, 0, strIn, -1, NULL, 0);  	wchar_t* pUnicode; 	pUnicode = new wchar_t[unicodeLen + 1]; 	memset(pUnicode, 0, (unicodeLen + 1)*sizeof(wchar_t)); 	MultiByteToWideChar(sourceCodepage, 0, strIn, -1, (LPWSTR)pUnicode, unicodeLen);  	BYTE * pTargetData = NULL; 	int targetLen = WideCharToMultiByte(targetCodepage, 0, (LPWSTR)pUnicode, -1,/*(char *)pTargetData*/NULL, 0, NULL, NULL); 	pTargetData = new BYTE[targetLen + 1]; 	memset(pTargetData, 0, sizeof(char)*(targetLen + 1)); 	WideCharToMultiByte(targetCodepage, 0, (LPWSTR)pUnicode, -1, (char *)pTargetData, targetLen, NULL, NULL);  	//lstrcpy(strOut, (char*)pTargetData); 	lstrcpynA(strOut, (char*)pTargetData, targetLen+1); 	delete pUnicode; 	delete pTargetData; }

这不是bug吧

ANSI（ASCII）不能表示汉字，如果有汉字，不宜转换为ANSI（ASCII）

CString szTemp("卡("); CString szTemp1(""); Convert(szTemp1,szTemp.GetBuffer(0),CP_ACP,CP_UTF8);//变成"鍗?" Convert(szTemp,szTemp1.GetBuffer(0),CP_UTF8,CP_ACP);//变成"?" 怎么能变正常啊

ASCII码不能表示汉字，只能表示英文及英文符号， 正是因为ASCII只能表示256个字符。不能够表示中文所有字符， 所以才有的unicode， UTF8就是unicode的一种实现。


Question: c语言数组 与结构体类型

GCC的扩展属性, 是GCC独有的，是用来优化编译器的。

Avr-gcc 中汇编器生成的目标文件（object-file）至少包含四个段，分别为: .text 段、.data段 、 .bss 段和.EEPROM 段，它们包括了程序存储器（FLASH）代码，内部RAM 数据，和EEPROM 存储器内的数据。这些段的大小决定了程序存储器（FLASH）、数据存储器（RAM）、EEPROM 存储器的使用量，关系如下： 程序存储器（FLASH）使用量 = .text + .data   数据存储器（RAM）使用量 = .data + .bss [+ .noinit] + stack [+ heap]  EEPROM 存储器使用量 = .EEPROM  参考http://gcc.gnu.org/onlinedocs/gcc-4.8.1/gcc/Attribute-Syntax.html#Attribute-Syntax

这是GCC的扩展属性，问题这里是告诉编译器将数据存储到指定的“段“中，((aligned(2), packed))是以2字节对齐存放


Question: C语言符号运算符

没事，我解决了，谢谢

这里的运算符优先级一般认为和程序C语言的运算符优先级无关，这里可以自己规定算术运算的优先级。为什么不能实现呢？

求大神帮忙呀


Question: c文件操作

刚想说需要fseek 我觉得应当是都在缓冲区的，除非手动刷新或者fclose了才行 用fp指针读的时候也是从缓冲区里面读的，所以能够读到

楼主你已经明白了，当时第一次文件读写的时候跟你一样，哎 但我有个疑问，到底那些数据是在缓冲区还是在文件里？？ 如果在缓冲区，你前移几个字符是不管用的。 所以如果让前移几个字符奏效的话：用setbuf(fp,NULL);关闭缓冲区。

引用 7 楼 user-3 的回复:fgets(cch,49,stdin);  你这里不是读了49个字符，然后默认一个结束字符？谢谢你啊，我搞清楚了，不是这里的问题，是我读写只打开了一次文件，文件指针在我写入后已经指向最后一个字符了，所以要想读出来，应该前移写入的几个字符，或者应该重新关闭再打开一次，好多知识都搞混了，谢谢你啊

引用 5 楼 TsingSoftware2014 的回复:引用 4 楼 user-3 的回复:[quote=引用 3 楼 TsingSoftware2014 的回复:] [quote=引用 2 楼 user-3 的回复:] fwrite(cch,49,1,fp);你好，谢谢 你的回复，我知道fwrite可以读出来，但是就想看对于字符串的时候，为什么这样就打印不出来 你的fwrite函数参数是错的 fwrite（）函数原型：size_t fwrite（const viod * restrict ptr, size_t size, size_t nmeb, FILE * restrict fp）;  size_t类型是sizeof运算符返回的类型，通常是unsigned int 类型。指针ptr是要将要写入的数据块的地址，size表示要写入的数据块的大小（以字节为单位）。nmemb表示数据块的数目。fp指定要写入的文件。  char buffer[256];   fwrite（buffer, 256, 1, fp）;将256字节大小的数据从buffer指向的内存缓冲区写入fp指向的文件。[/quote]你好，就算改成fwrite(cch,50,1,fp);跟你的保持一致也是报一样的问题的。[/quote]  fwrite(cch,49,1,fp);

引用 4 楼 user-3 的回复:引用 3 楼 TsingSoftware2014 的回复:[quote=引用 2 楼 user-3 的回复:] fwrite(cch,49,1,fp);你好，谢谢 你的回复，我知道fwrite可以读出来，但是就想看对于字符串的时候，为什么这样就打印不出来 你的fwrite函数参数是错的 fwrite（）函数原型：size_t fwrite（const viod * restrict ptr, size_t size, size_t nmeb, FILE * restrict fp）;  size_t类型是sizeof运算符返回的类型，通常是unsigned int 类型。指针ptr是要将要写入的数据块的地址，size表示要写入的数据块的大小（以字节为单位）。nmemb表示数据块的数目。fp指定要写入的文件。  char buffer[256];   fwrite（buffer, 256, 1, fp）;将256字节大小的数据从buffer指向的内存缓冲区写入fp指向的文件。[/quote]你好，就算改成fwrite(cch,50,1,fp);跟你的保持一致也是报一样的问题的。

引用 3 楼 TsingSoftware2014 的回复:引用 2 楼 user-3 的回复:fwrite(cch,49,1,fp);你好，谢谢 你的回复，我知道fwrite可以读出来，但是就想看对于字符串的时候，为什么这样就打印不出来 你的fwrite函数参数是错的 fwrite（）函数原型：size_t fwrite（const viod * restrict ptr, size_t size, size_t nmeb, FILE * restrict fp）;  size_t类型是sizeof运算符返回的类型，通常是unsigned int 类型。指针ptr是要将要写入的数据块的地址，size表示要写入的数据块的大小（以字节为单位）。nmemb表示数据块的数目。fp指定要写入的文件。  char buffer[256];   fwrite（buffer, 256, 1, fp）;将256字节大小的数据从buffer指向的内存缓冲区写入fp指向的文件。

顶自己一下，打印出来一堆的a


Question: 关于windows 键盘钩子的问题

能不能 在处理函数前 就调用 CallNextHookEx(g_Hook, nCode, wParam, lParam); 将消息传下去  再对键码进行分析？ 这样就不会卡到了  可行吗

引用 1 楼 LubinLew的回复:楼主动机不纯啊。。。 已经记录文件了，应该在空闲的时候向server发送文件， TCP不行用UDP不就OK了 udp 不是容易丢包吗

钩子都是b  引用 2 楼 Unixb 的回复:[quote=引用 1 楼 LubinLew的回复:]楼主动机不纯啊。。。 已经记录文件了，应该在空闲的时候向server发送文件， TCP不行用UDP不就OK了 udp 不是容易丢包吗[/quote] 那只是相对于TCP而言， 如果动不动就丢包，你觉得这个协议有存在的必要吗？ 当然如果网络环境特别差，丢包现象还是容易发生的

引用 4 楼 追梦青年的回复:创建一个线程去处理数据发送。另外把发送数据的socket设置为非阻塞模式，我知道socket读或写可以设置超时，不清楚连接是不是也可以如此设置。 创建线程也一样阿  如果没处理完就传递   下一个键盘消息便会丢失


Question: 关于指针作为函数参数的问题

理解和讨论之前请先学会如何观察！  计算机组成原理→DOS命令→汇编语言→C语言（不包括C++）、代码书写规范→数据结构、编译原理、操作系统→计算机网络、数据库原理、正则表达式→其它语言（包括C++）、架构……  对学习编程者的忠告： 多用小脑和手，少用大脑、眼睛和嘴，会更快地学会编程！ 眼过千遍不如手过一遍！ 书看千行不如手敲一行！ 手敲千行不如单步一行！ 单步源代码千行不如单步Debug版对应汇编一行！ 单步Debug版对应汇编千行不如单步Release版对应汇编一行！ 不会单步Release版对应汇编？在你想单步Release版C/C++代码片断的前面临时加一句DebugBreak();重建所有，然后在IDE中运行。（一般人我不告诉他！）  VC调试时按Alt+8、Alt+7、Alt+6和Alt+5,打开汇编窗口、堆栈窗口、内存窗口和寄存器窗口看每句C对应的汇编、单步执行并观察相应堆栈、内存和寄存器变化，这样过一遍不就啥都明白了吗。 对VC来说，所谓‘调试时’就是编译连接通过以后，按F10或F11键单步执行一步以后的时候，或者在某行按F9设了断点后按F5执行停在该断点处的时候。 （Turbo C或Borland C用Turbo Debugger调试,Linux或Unix下用GDB调试时,看每句C对应的汇编并单步执行观察相应内存和寄存器变化。）  想要从本质上理解C指针，必须学习汇编以及C和汇编的对应关系。 从汇编的角度理解和学习C语言的指针，原本看似复杂的东西就会变得非常简单！ 指针即地址。“地址又是啥？”“只能从汇编语言和计算机组成原理的角度去解释了。” 但我又不得不承认：  有那么些人喜欢或者适合用“先具体再抽象”的方法学习和理解复杂事物；  而另一些人喜欢或者适合用“先抽象再具体”的方法学习和理解复杂事物。 而我本人属前者。  不要企图依赖输出指针相关表达式...的值【比如printf("%p\n",...);或者cout<<...】来理解指针的本质， 而要依赖调试时的反汇编窗口中的C/C++代码【比如void *p=(void *)(...);】及其对应汇编指令以及内存窗口中的内存地址和内存值来理解指针的本质。  这辈子不看内存地址和内存值；只画链表、指针示意图，画堆栈示意图，画各种示意图，甚至自己没画过而只看过书上的图……能从本质上理解指针、理解函数参数传递吗？本人深表怀疑！ 这辈子不种麦不收麦不将麦粒拿去磨面；只吃馒头、吃面条、吃面包、……甚至从没看过别人怎么蒸馒头，压面条，烤面包，……能从本质上理解面粉、理解面食吗？本人深表怀疑！！  提醒： “学习用汇编语言写程序” 和 “VC调试(TC或BC用TD调试)时按Alt+8、Alt+7、Alt+6和Alt+5,打开汇编窗口、堆栈窗口、内存窗口和寄存器窗口看每句C对应的汇编、单步执行并观察相应堆栈、内存和寄存器变化，这样过一遍不就啥都明白了吗。 （Linux或Unix下可以在用GDB调试时,看每句C对应的汇编并单步执行观察相应内存和寄存器变化。） 想要从本质上理解C指针，必须学习C和汇编的对应关系。” 不是一回事！  不要迷信书、考题、老师、回帖； 要迷信CPU、编译器、调试器、运行结果。 并请结合“盲人摸太阳”和“驾船出海时一定只带一个指南针。”加以理解。 任何理论、权威、传说、真理、标准、解释、想象、知识……都比不上摆在眼前的事实！  有人说一套做一套，你相信他说的还是相信他做的？ 其实严格来说这个世界上古往今来所有人都是说一套做一套，不是吗？  不要写连自己也预测不了结果的代码！  电脑内存或文件内容只是一个一维二进制字节数组及其对应的二进制地址； 人脑才将电脑内存或文件内容中的这个一维二进制字节数组及其对应的二进制地址的某些部分看成是整数、有符号数/无符号数、浮点数、复数、英文字母、阿拉伯数字、中文/韩文/法文……字符/字符串、汇编指令、函数、函数参数、堆、栈、数组、指针、数组指针、指针数组、数组的数组、指针的指针、二维数组、字符点阵、字符笔画的坐标、黑白二值图片、灰度图片、彩色图片、录音、视频、指纹信息、身份证信息……  十字链表交换任意两个节点C源代码（C指针应用终极挑战）http://download.csdn.net/detail/zhao4zhong1/5532495

第2个函数中的形参p是局部变量，和main中的p毫无关系，因此在change中改变p的值，使其指向bb,但main中的p仍然指向bb，所以仍然显示20.8

先理解调用函数时发生的操作： 推荐去百度：函数调用过程。  #include <stdio.h> #include <stdlib.h> double aa=10.8; double bb=20.8; void change(double *p)//把aa的地址传过来 { *p=99;//把aa的值改成99 } void main() { double *p=&aa; change(p); printf("%f",*p);//这里p还是指向aa的地址，因此显示99 system("pause"); }  #include <stdio.h> #include <stdlib.h> double aa=10.8; double bb=20.8; void change(double *p)//把aa的地址传过来，传到形参p的存储空间，此空间会在函数结束调用后释放掉 { p=&bb;//把形参p的值改成bb的地址 }//调用结束，形参p的空间被释放 void main() { double *p=&aa; change(p); printf("%f",*p);//实参p的值还是aa的地址，因此显示10.8 system("pause"); }  综上所述，你的change(),第一次改变aa的值，第二次相当于什么都没做。

第二个的change函数，p=&bb一点用都没，函数内的p指针和main函数的p刚进函数的时候都指向了aa所在的地址 然后你让函数内的p指针指向了bb，对main函数内的p指针毫无影响 PS:如果要改变指针所指向区域的值，那么传一级指针就可以了 如果要改变指针本身的值（换句话来说就是改变指针的指向，让它指向另一个变量）那么需要传二级指针或者引用

其实你的change函数屁用都没有

void change(double *p) { *p=&bb; }  这样就能变成20.8了

第一个将aa改写为99了，而第二个则将p改写为bb的地址了  p是普通变量，跟*p一点关系都没有


Question: 这段代码改成指针怎么写？

引用 2 楼 renwotao2009 的回复:a b是char指针，不是char没有存储char的空间你的scanf读入数据放到哪哦，明白了

引用 1 楼 qq_28098403 的回复:运行可以通过？输出结果是啥？我觉得应该是历遍的时候没有第一个字符没有调用那个函数没明白？运行时直接崩溃了

你的a 、b 是个指针，你都没分配内存，就开始放入字符串

char *a,*b;你的a,b指针在未初始化之前都指向了一个未知的区域 你通过scanf试图向那个未知的区域写入数据，运行的时候肯定会提示异常的

malloc


Question: 新手自学C语言，关于浮点数的输出

printf 中%f 类型是float, %lf是double, 不过不定参数中, float类型做为参数传递时候会提升至double(标准规定的), 而scanf中, %f类型对应是float*, %lf则是double*,

scanf("%lf",&nu);

printf的%f说明符的确既可以输出float型又可以输出double型。 根据"默认参数提升"规则（在printf这样的函数的可变参数列表中 ，不论作用域内有没有原型，都适用这一规则）float型会被提升为double型。因此printf()只会看到双精度数。 对于scanf，情况就完全不同了，它接受指针，这里没有类似的类型提升。（通过指针）向float存储和向double存储大不一样，因此，scanf区别%f和%lf。

改成float测试没问题啊


Question: 关于跳舞配对的问题

仅供参考：//舞会上，男士们（m人）和女士们（n人, n<m）进入舞厅时，各自排成一队。跳舞开始时，依次从男队和女队的队头上各出一人配成舞伴。 //男队中未配对者等待下一轮舞曲。现要求写一算法模拟上述舞伴配对问题。在第t首曲子时，第x个女生和第几个男生配对跳舞？ #include <stdio.h> #include <string.h> #define MAX 26 int m,n,t,x,y,i,j,k; char md[MAX]; char nd[MAX]; char c; void main() {     while (1) {         printf("Input n m(1<=n<m<=%d):",MAX);         fflush(stdout);         rewind(stdin);         if (2==scanf("%d%d",&n,&m)) {             if (1<=n && n<m && m<=MAX) break;         }     }     while (1) {         printf("Input t x(1<=t<=%d 1<=x<=%d):",MAX,n);         fflush(stdout);         rewind(stdin);         if (2==scanf("%d%d",&t,&x)) {             if (1<=t && t<=MAX && 1<=x && x<=n) break;         }     }     for (i=0;i<m;i++) md[i]='A'+i;     for (i=0;i<n;i++) nd[i]='a'+i;     k=0;     for (i=0;i<t;i++) {         printf("%2d: ",i+1);         for (j=0;j<n;j++) {             c=' ';             if (i==t-1 && j==x-1) {c='*';y=k+1;}             printf("%c%c%c",md[k],nd[j],c);             k=(k+1)%m;         }         printf("\n");     }     printf("%d\n",y);  }


Question: C++新手，请问大神如何使用C++第三方库

引用 1 楼 qq423399099 的回复:库文件应该都在bin目录下吧，头文件在include目录下 在工程属性里配置下库目录，附加依赖项，代码里include头文件然后试试 谢谢，不过还是版主的详细

引用 2 楼 CharlesSimonyi 的回复:主要使用include中的头文件和native中的snappy32.dll和snappy32.lib库文件 解压出来后，在VisualStudio中进行设置：“ 项目属性” - “VC++目录“ 包含目录添加解压出来的include文件夹路径 库目录添加解压出来的native文件夹路径 然后在代码中写： #include <snappy.h> #pragma comment(lib,"snappy32.lib") 编译成功后要运行时，需要把native文件夹下的snappy32.dll和你的exe放在一起  也可以不设置“ 项目属性” - “VC++目录“ 而是直接把解压出来的include文件夹下的所有头文件拷贝到你的工程目录中，native文件夹下的snappy32.lib也拷贝到你的工程目录中。 然后在代码中写： #include "snappy.h" #pragma comment(lib,"snappy32.lib") 编译成功后要运行时，需要把native文件夹下的snappy32.dll和你的exe放在一起 太感谢版主了


Question: 这样声明正确么

是不是编译器分不清               double  * malloc(30*sizeof(double))                                        究竟是double  （*malloc(30*sizeof(double))）                                          还是（double  *）malloc(30*sizeof(double))

引用 7 楼 fornetuse123 的回复:或者强制类型转换这样ptd=double  *malloc(30*sizeof(double))这样写，不是才更简洁，那个(double *)代表什么含义   [quote=引用 6 楼 qq423399099 的回复:] [quote=引用 5 楼 fornetuse123 的回复:] 或者强制类型转换这样ptd=double  *malloc(30*sizeof(double))这样写，不是才更简洁，那个(double *)代表什么含义 你malloc(30*sizeof(double))返回的是一个void * 也就是说给你返回的是一个长度是30*8个字节的在堆上开辟的一块存储空间的首地址 这个首地址通过给你返回一个void *来使用 double（ *malloc(30*sizeof(double))）是啥？先取*变成void类型，然后再用double强转？ 表达式必须是指向完整类型的指针 [/quote]  *malloc(30*sizeof(double))不是对malloc开辟内存首地址的解引用么，那不就是将首地址中的内容转换为double类型？嗯 明白为什么要对指针进行类型强转换，而不是对首地址内存内容进行转换了。  现在就剩下为什么要用(double *)将double括起来呢？这个不懂，为什么编译器没法识别double *[/quote] 因为*会先和后面的部分先结合，而不是先和double结合形成double * 加上括号既可以增加可读性也防止这个情况发生

引用 楼主 fornetuse123 的回复:可是(double *)，这里为什么要用圆括号，  这样不正好是将malloc分配的内存块的首地址给了ptd么？  类开转换，malloc返回的void*   引用 楼主 fornetuse123 的回复:sizeof(double)这里为什么不是sizeof(ptd)  这样不正好是将malloc分配的内存块的首地址给了ptd么？  ptd类型是double*，而不是double，sizeof(ptd)结果是4（32位时）

或者强制类型转换这样ptd=double  *malloc(30*sizeof(double))这样写，不是才更简洁，那个(double *)代表什么含义   引用 6 楼 qq423399099 的回复:[quote=引用 5 楼 fornetuse123 的回复:] 或者强制类型转换这样ptd=double  *malloc(30*sizeof(double))这样写，不是才更简洁，那个(double *)代表什么含义 你malloc(30*sizeof(double))返回的是一个void * 也就是说给你返回的是一个长度是30*8个字节的在堆上开辟的一块存储空间的首地址 这个首地址通过给你返回一个void *来使用 double（ *malloc(30*sizeof(double))）是啥？先取*变成void类型，然后再用double强转？ 表达式必须是指向完整类型的指针 [/quote]  *malloc(30*sizeof(double))不是对malloc开辟内存首地址的解引用么，那不就是将首地址中的内容转换为double类型？嗯 明白为什么要对指针进行类型强转换，而不是对首地址内存内容进行转换了。  现在就剩下为什么要用(double *)将double括起来呢？这个不懂，为什么编译器没法识别double *

引用 5 楼 fornetuse123 的回复:或者强制类型转换这样ptd=double  *malloc(30*sizeof(double))这样写，不是才更简洁，那个(double *)代表什么含义 你malloc(30*sizeof(double))返回的是一个void * 也就是说给你返回的是一个长度是30*8个字节的在堆上开辟的一块存储空间的首地址 这个首地址通过给你返回一个void *来使用 double（ *malloc(30*sizeof(double))）是啥？先取*变成void类型，然后再用double强转？ 表达式必须是指向完整类型的指针

引用 3 楼 qq423399099 的回复:malloc的原型：void *malloc(unsigned int num_bytes); 返回值是void *所以我们一般使用的时候需要将其强制转换为我们需要的类型，所以前面会加一个(double *) 如果不加括号，楼主觉得编译器能识别的了这是在转换一个指针的类型吗？ sizeof(ptd)也是不行的，因为ptd是一个指针，对一个指针sizeof永远都是4  恩 sizeof 明白了，可是强制类型转换这样ptd=double（ *malloc(30*sizeof(double))）这样写，不是才正确，那个(double *)代表什么含义

引用 1 楼 Rewen 的回复:习惯用法是sizeof(double)，理解起来也方便的啊。 ptd 指向的是30个double大小的内存区域。 如果sizeof(ptd)的话，首先ptd没有指向任何东西，sizeof(ptd)就识别不出来是什么啊 ptd不是已经由double *ptd;声明为double类型了么


Question: 【数据结构】OJ显示Segmentation fault:段错误，检查是否有数组越界，指针异常，访问到不应该访问的内存区域

更正一下： 4.AddPoyln 函数略长，刚看第一个if就觉得有点奇怪，如果链表a的第一项的指数大于链表b的第一项指数，就让pb1和p1往后移了一个节点（如果链表a=3x^2+4x^3,链表b=x+2x^2）,那第一个if过后，p1就已经指向了4x^3,根本没有机会和链表b的2x^2合并啊？

看了一下其他几个函数： 1.CreatPoyln有内存泄露，应该在循环结束完free(p) 2.PrintfPoyln函数，如果遇到空链表，那么会段错误产生异常（OJ里应该会测试这种情况） 3.DestroyPoyln函数，好像没有free头结点啊？ 4.AddPoyln 函数略长，刚看第一个if就觉得有点奇怪，如果链表a的第一项的系数大于链表b的第一项系数，就让pb1和p1往后移了一个节点（如果链表a=3x^2+4x^3,链表b=x+2x^2）,那第一个if过后，p1就已经指向了4x^3,根本没有机会和链表b的2x^2合并啊？ PS：由此没有往下看，试了一组测试用例，结果崩了


Question: C语言动态数组使用的问题

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

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

猜测楼主 if (jag = NULL) 想要表达的是： if (jag == NULL) 吧

判相等 == if (jag = NULL) return 1;


Question: 关于scanf函数用法 求解惑

好像叫忽略输入符

* 是scanf函数中的一种修饰符           表示输入项输入后不转送给任何向量             %s     是格式  控制符        %s用在输入函数中表示输入一个字符串  遇到空格回车  结束  两者一起用              表示将 当前的一个字符串输入后不送给任何变量  执行后光标到了这个字符串后面          也就相当于跳到了下一个字符串前面             一般字符串之间都是用空格  隔离的  所以 是跳到了下一个空白字符处

%*(TYPE) 的作用是按（TYPE）的类型读取数据，但不将其储存至任何变量中，而是直接丢弃。  scanf("%*s"); 的作用就是将stdin缓冲区中后续的内容按字符串的方式处理，并丢弃掉。  比如：如果stdin中的用户输入为：  1  text (\n) 调用scanf("%d", &a); 后，a 的值为1，但stdin的缓冲区中还残留有“text"这一字符串。如果不丢弃掉，那么下一次再执行 rc = scanf("%d”, &a); 时会失败（rc == 0)。


Question: 每次执行程序就会停止工作

DEBUG 调试 进入堆栈 可以看出程序异常的位置 查看变量值~~~

引用 5 楼 zhao4zhong1 的回复:  这一个表情代表的意思是：眼过千遍不如手过一遍！书看千行不如手敲一行！…………以下省略300字

你的country只是一个包含6个char*的数组，这6个char*的指针并没有分配内存

崩溃的时候在弹出的对话框按相应按钮进入调试，按Alt+7键查看Call Stack即“调用堆栈”里面从上到下列出的对应从里层到外层的函数调用历史。双击某一行可将光标定位到此次调用的源代码或汇编指令处，看不懂时双击下一行，直到能看懂为止。  代码功能归根结底不是别人帮自己看或讲解或注释出来的；而是被自己静下心来花足够长的时间和精力亲自动手单步或设断点或对执行到某步获得的中间结果显示或写到日志文件中一步一步分析出来的。 提醒：再牛×的老师也无法代替学生自己领悟和上厕所！ 单步调试和设断点调试（VS IDE中编译连接通过以后，按F10或F11键单步执行，按Shift+F11退出当前函数；在某行按F9设断点后按F5执行停在该断点处。）是程序员必须掌握的技能之一。

代码崩溃是因为你没有给指针分配空间，它指向的是一块未知的内存区域，你直接用scanf写入自然崩溃 我这里用malloc为每个字符串开辟空间，同时楼主的change函数也有问题，楼主那样直接交换  #include <stdio.h> #include <string.h> #include <stdlib.h> void main (void) { 	void change(char*p1,char*p2);  	char*country[6]; 	int i,j,n=6; 	printf("请输入5个国家名字：\n"); 	for(i=1;i<n;i++) 	{ 		char buff[64] = {0}; 		scanf("%s", buff); 		country[i] = (char *)malloc(strlen(buff) + 1); 		strcpy(country[i], buff); 	} 		 	printf("名字排序如下:\n"); 	for(i=1;i<n;i++) 		for(j=1;j<n-i;j++) 			change(country[j+1],country[j]); 	for(i=1;i<n;i++)  		printf("%s\n",country[i]); } void change(char*p1,char*p2) { 	char temp[64] = {0}; 	if(strcmp(p1,p2)<0) 	{ 		strcpy(temp, p1); 		strcpy(p1, p2); 		strcpy(p2, temp); 	}  }

打印日志，就知道哪几行代码有崩溃


Question: 哪错了求大神看下

去掉红色那个括号  struct yyy nn={{"string constant"},{{"text"},{7,8},{12.3}},{"address"}},{"a","b","c"}};

楼主是不仔细造成的，有两个地方： 1.struct yyy nn={{"string constant"},{{"text"},{7,8},{12.3}},{"address"}},{"a","b","c"}};这里的address后面多了一个} 2.printf("%s%s %d %d %1f\n%s%s%s%s\n",rr.dd,rr.mm.aa,rr.mm.bb[0],rr.mm.bb[1],rr.mm,rr.ee,rr.ff[0],rr.ff[2]);这句 rr.mm.cc写成了,rr.mm 少传一个参数,rr.ff[1]  #include <stdio.h> #include <string.h> struct xxx { 	char aa[30]; 	int bb[2]; 	double cc; }; struct yyy { 	char dd[50]; 	struct xxx mm; 	char *ee; 	char *ff[3]; }; void main (void) { 	struct xxx qq={{"sample"},{0,1},{5.4}}; 	struct yyy nn={{"string constant"},{{"text"},{7,8},{12.3}},{"address"},{"a","b","c"}}; 	struct yyy pp,rr; 	strcpy(pp.mm.aa, "in structure"); 	strcpy(pp.dd,"structure");  	pp.mm.bb[0]=10; 	pp.mm.bb[1]=12; 	pp.mm.cc=57.8; 	pp.ee="pointer and"; 	pp.ff[0]="array"; 	pp.ff[1]="of"; 	pp.ff[2]="ponter."; 	rr=pp;  	printf("%s%s %d %d %1f\n%s%s%s%s\n",rr.dd,rr.mm.aa,rr.mm.bb[0],rr.mm.bb[1],rr.mm.cc,rr.ee,rr.ff[0],rr.ff[1],rr.ff[2]); }


Question: 【数据结构新手】一元多项式相加问题

引用 4 楼 qq423399099 的回复:楼主是不是又调试了别的函数？ 就main函数里InitPoyln，CreatPoyln，PrintfPoyln函数应该是没问题的    恩恩，谢谢啦

加上去了，还是不行

引用 1 楼 qq423399099 的回复:问题出在你没有将链表的最后一个节点的next指针置为NULL 这样就导致了调用PrintfPoyln打印节点的时候越界访问导致异常 PS：同时在CreatPoyln函数里还需要free(p),否则这个地方有内存泄露  Status CreatPoyln(LinkList *l) {     //【2】尾插法建立链表     LinkList p,r;     r = (*l);     while (1)     {         p = (LinkList)malloc(sizeof(Node)); //        printf("请输入多项式的系数和指数：");         scanf("%d %d",&p->data.coef,&p->data.index);         if(p->data.coef == -1&&p->data.index == -1)             break;         r->next = p;         r = p;     } 	free(p); //需要释放掉p 	r->next = NULL; //最后一个节点的next要置为NULL     return OK; }  加上去了，还是不行


Question: 做一个测量温度的产品

成本基本取决于温度测量精度和数据传送方式，最低端的是ds18b20加串口通信，整体算下来200以下； 但是场合要求高或者处理数据方法复杂的话就不好说了。。。


Question: C语言静态链表改为动态链表问题

#include<stdio.h> #include<malloc.h> #define NULL 0 struct name { 	int num; 	struct name *next; }; int search(struct name *head,int x); void insert(struct name *head);  void main() { 	int n,res,x; 	struct name a,b,c; 	struct name *p,*p1,*head; 	head = (struct name*)malloc(sizeof(struct name)); 	head->next = NULL; 	insert(head);  	printf("请输入要查找的元素:"); 	scanf("%d",&x);  	res=search(head,x); 	if(res==0) 		printf("没有找到元素!\n"); 	else 		printf("节点序号为:%d\n",res); }  void insert(struct name *head) { 	int x; 	struct name *p,*p1; 	p = head; 	printf("请输入链表元素:"); 	 	scanf("%d",&x); 	while(x!=0) 	{ 		p1 = (struct name*)malloc(sizeof(struct name)); //创建新节点 		p1->num = x;    //给新的结点赋值 		p->next = p1;   //让当前结点的next指针指向新创建的结点 		p = p1;    //让p指向当前最后的结点 		scanf("%d",&x); 	} 	p->next=NULL;//将最后一个结点的next置为NULL }  int search(struct name *head,int x) { 	int i=1; 	struct name *p=head->next; 	while(p!=NULL) 	{ 		if(p->num==x) 			break; 		p=p->next; 		i++; 	} 	if(p==NULL) 		return 0; 	else return i; }

return(head);//这句干吗的？ int search(struct name *head,int x)先声明下再使用


Question: 双三次插值算法  放大图片  图片直接花了 求解

在矩形  -sx/2+x,-sy/2+y  sx/2+x,sy/2+y   范围内的点是有贡献的点

那就采用效率低，但是效果好的方法吧  假设 sx,sy 分别是 x,y 方向的缩放比 求出，dst 的每个像素在 src 的位置 对 dst每个像素 点（x,y） 有贡献的点在     -sx/2+x, x,sx/3+x，-sy/2+y,sy/2+y 之间的所有像素点 在这个范围的所有点求出加权平均值，可以用 立方插值相同的方法

插值的时候，注意不要溢出

图像缩放，应该求出目标图像在原图像的位置，用这个位置做参数 进行缩放 在该位置周围找若干图像点，进行插值 如果缩放比例太大，图像细腻，走样在所难免  如果要求清晰，就不能采用简单的插值了 而应该对每个对目标图像有贡献的点， 做加权平均值，方法可以和Cube 插值相同，但是计算量不是一般的大

建议楼主使用PS创建一个尺寸尽量小比如4像素x3像素的图片辅助单步调试你的代码。

我就是这么做的啊  不知道哪里出了问题


Question: 数组指针的问题：数组的大小和地址赋值

int (*p)[2]和int (*p)[3]是不同类型的指针， (*p)[3]是指向每行有3个元素的一维，因此不能指向其他数组

int (*p)[2];  这里的2是指列数，而不是行数

我试了下，这里p的类型不是int*的，而是int[][2],就是行指针的意思，因为你定义的a每行有两个元素，所以你下面定义p的时候也应该是2，如果你定义为a[][5]=...下面你得定义(*p)[5]才行。

这是一个数组指针，p是一个指向含2个元素的数组的指针 p=a;使得p是指向了a, 如果是p+1那么，其实跳过的是2个int的长度（跳过一个数组，这个数组长度是2），由声明的时候int (*p)[2]决定的 p+1指向的是第三个元素（即3），p+2指向的是第五个元素（即5） (*p)[0]是1，(*p)[1]是2..............

那个2是不能改成3的，2告诉指针，指针的步长是2，p+1跳的是2个整形的内存块，若改为3，则跳的是3个整形的内存块，a的类型指定了a的步长是2，是3的话相当于类型不一样了

理解和讨论之前请先学会如何观察！  仅供参考：//char (*(*x[3])())[5];//x是什么类型的变量? // //分析C语言声明，关键是搞清楚这个变量是个什么东西（函数、指针、数组）， //是函数那么剩下的就是他的参数和返回值， //是指针那剩下部分是说明他指向什么， //是数组剩下的部分就是说明数组的成员是什么类型。 //解析C语言声明规则： //从左侧第一个标识符开始，按照优先级进行结合。*表示是..的指针，const表示只读的，volatile表示可变的，[]表示是数组，()表示是函数。 // //x和[3]结合说明是一个大小为3的数组，该数组的每个元素为一类指针，该类指针指向一类函数，该类函数无参数，返回一类指针，该类指针指向一个大小为5的char型数组 #include <stdio.h> #include <typeinfo.h> char num[5]; char (*x00())[5] {     return # } int main() {     char (*(*x[3])())[5];//是个数组，大小为3     char (*(*x0  )())[5];//数组的元素，是个函数指针     char (*( x00 )())[5];//函数原型，参数为空，返回值为指针     char (*  x000   )[5];//返回值      x0 = x00;     x[0] = x0;     x[1] = x0;     x[2] = x0;     printf("typeid(x).name() is %s\n",typeid(x).name());     return 0; } //typeid(x).name() is char (* (__cdecl**)(void))[5]

看了#2和#3，基本明白了。


Question: 用getchar不用scanf的原因

scanf 的 %f 对应 float*, 请用%lf

scanf("%lf", &a)

楼主原来的a = getchar();也不对的吧？ getchar只能读入一个字符给a, 同时scanf("%f", &a)也是不行的，类型需要严格匹配 printf的%f说明符的确既可以输出float型又可以输出double型。 根据"默认参数提升"规则（在printf这样的函数的可变参数列表中 ，不论作用域内有没有原型，都适用这一规则）float型会被提升为double型。因此printf()只会看到双精度数。 对于scanf，情况就完全不同了，它接受指针，这里没有类似的类型提升。（通过指针）向float存储和向double存储大不一样，因此，scanf区别%f和%lf。


Question: 问一个试题的回答规范

很明显题目问的是整个表达式的值

http://baike.baidu.com/link?url=JH9DKpiLMUjKQQjjqGYfiOgki-2pGiSGAwZbKtitxq_BBZAk8bwz30DRBO_W_Ko2AuJDjkTr8vRYPVtBhL0eqq int a1,a2,b=2,c=7,d=5; a1=(++b,c--,d+3); a2=++b,c--,d+3; 对于给a1赋值的代码，有三个表达式，用逗号分开，所以最终的值应该是最后一个表达式的值，也就是(d+3)的值，为8，所以a1的值为8。 对于给a2赋值的代码，也是有三个表达式，这时的三个表达式为a2=++b、c--、d+3,(这是因为赋值运算符比逗号运算符优先级高)所以最终表达式的值虽然也为8，但a2=4（第2行代码运算完时，b=3，即第3行代码运行时，b的值为4）。

逗号表达式，结果为3

关于C,C++表达式求值顺序 http://blog.csdn.net/fefe82/article/details/37833767，http://bbs.csdn.net/topics/370153775

逆波兰式分析一下就知道了...............

3，分号结果是最后一个表达式

没意思....

根据优先级（=高于,），应该是：  (a=1),(a+=1),(a+1),(a++) 的结果  而不是  a=(1,a+=1,a+1,a++)

表达式 a=1,a+=1,a+1,a++ 的值是____________。

等于2？…………………………

指的应该是前面整个逗号表达式的值


#include <stdio.h>  int main(void) {     int n,i,sum,flag;     flag = 0;     while(scanf("%d",&n) != EOF)     {         sum = 0;         for(i = 1; i <= n; i++)             sum += i;         if(flag)             printf("\n");         printf("%d\n",sum);         flag = 1;     } 	return 0; }

引用 14 楼 Cerman 的回复:[quote=引用 12 楼 sinat_34674745 的回复:] [quote=引用 11 楼 Cerman 的回复:] 或者这么做： # include <stdio.h> #define count 10  int main() {     int n, i,j=0; 	int sum[count]; 	for(i=0;i<count;i++) 		sum[i]=0; 	     while(scanf("%d", &n)!=EOF&&j<count) {         for(i=1; i<=n; ++i)             sum[j]= sum[j] + i; 		j++;             } 	for(i=0;i<j;i++) 	printf("%d\n\n", sum[i]);     return 0;  } 运行结果： 在杭电OJ上编译提示Wrong Answer。[/quote] 我用的VC6.0，按理说没有问题的[/quote]题目要求的是‘‘’换行符’’输出结果？那如何实现输入完几行整数，判断后面一行没有整数，然后输出结果？

引用 12 楼 sinat_34674745 的回复:[quote=引用 11 楼 Cerman 的回复:] 或者这么做： # include <stdio.h> #define count 10  int main() {     int n, i,j=0; 	int sum[count]; 	for(i=0;i<count;i++) 		sum[i]=0; 	     while(scanf("%d", &n)!=EOF&&j<count) {         for(i=1; i<=n; ++i)             sum[j]= sum[j] + i; 		j++;             } 	for(i=0;i<j;i++) 	printf("%d\n\n", sum[i]);     return 0;  } 运行结果： 在杭电OJ上编译提示Wrong Answer。[/quote] 我用的VC6.0，按理说没有问题的

引用 15 楼 sinat_34674745 的回复:[quote=引用 14 楼 Cerman 的回复:] [quote=引用 12 楼 sinat_34674745 的回复:] [quote=引用 11 楼 Cerman 的回复:] 或者这么做： # include <stdio.h> #define count 10  int main() {     int n, i,j=0; 	int sum[count]; 	for(i=0;i<count;i++) 		sum[i]=0; 	     while(scanf("%d", &n)!=EOF&&j<count) {         for(i=1; i<=n; ++i)             sum[j]= sum[j] + i; 		j++;             } 	for(i=0;i<j;i++) 	printf("%d\n\n", sum[i]);     return 0;  } 运行结果： 在杭电OJ上编译提示Wrong Answer。[/quote] 我用的VC6.0，按理说没有问题的[/quote]题目要求的是‘‘’换行符’’输出结果？那如何实现输入完几行整数，判断后面一行没有整数，然后输出结果？[/quote] 把输入的数写到txt里面，才会检测到结束标志eof

引用 15 楼 sinat_34674745 的回复:[quote=引用 14 楼 Cerman 的回复:] [quote=引用 12 楼 sinat_34674745 的回复:] [quote=引用 11 楼 Cerman 的回复:] 或者这么做： # include <stdio.h> #define count 10  int main() {     int n, i,j=0; 	int sum[count]; 	for(i=0;i<count;i++) 		sum[i]=0; 	     while(scanf("%d", &n)!=EOF&&j<count) {         for(i=1; i<=n; ++i)             sum[j]= sum[j] + i; 		j++;             } 	for(i=0;i<j;i++) 	printf("%d\n\n", sum[i]);     return 0;  } 运行结果： 在杭电OJ上编译提示Wrong Answer。[/quote] 我用的VC6.0，按理说没有问题的[/quote]题目要求的是‘‘’换行符’’输出结果？那如何实现输入完几行整数，判断后面一行没有整数，然后输出结果？[/quote] 你的意思是键入两个换行之后显示结果吗？

引用 6 楼 sinat_34674745 的回复:引用 3 楼 butters10 的回复:lz如果开始一直输入，然后用一个'\n'触发计算能不能提交通过？可以，比如输入1 100然后回车，输出结果和样例输出相同。不可以，我理解错你的意思了。如果while ！='\n'，肯定是不行的

引用 11 楼 Cerman 的回复:或者这么做： # include <stdio.h> #define count 10  int main() {     int n, i,j=0; 	int sum[count]; 	for(i=0;i<count;i++) 		sum[i]=0; 	     while(scanf("%d", &n)!=EOF&&j<count) {         for(i=1; i<=n; ++i)             sum[j]= sum[j] + i; 		j++;             } 	for(i=0;i<j;i++) 	printf("%d\n\n", sum[i]);     return 0;  } 运行结果： 在杭电OJ上编译提示Wrong Answer。

引用 8 楼 Cerman 的回复:用动态内存分配给数组sum。等到键入eof时停止输入，输出每个运算结果。能写个代码吗，谢谢

引用 4 楼 qq423399099 的回复:输入一个空行的时候说明输入完了？ 之前每行输入的数先保存下来，之后再一起输出结果？不是的，EOF触发的条件并不是遇到EOF，还包括遇到"\n",遇到换行符直接输出结果了。如下图。

用动态内存分配给数组sum。等到键入eof时停止输入，输出每个运算结果。

引用 5 楼 Cerman 的回复:我知道这是EOF，但是我现在纠结的是，不能像sample input那样输入，也就是说，我输入1然后换行，直接输出结果了。但是如果输入1空格100换行，输出结果和SAMPLE OUTPUT一样。

lz如果开始一直输入，然后用一个'\n'触发计算能不能提交通过？

引用 1 楼 qq423399099 的回复:EOF遇换行符跳出？ 楼主这个程序应该没问题，windows下用ctrl+z可以结束输入Input 举例是1然后换行100，但是我在终端输入1换行，直接就输出结果了


Question: 【一个简单的连通问题】为什么输出总会晚一步

scanf 里面去掉\n  否则会去多匹配一个空白符

scanf("%d %d\n", &p, &q)改成scanf("%d %d", &p, &q) 多了\n,scanf里不需要用\n

大家好厉害，赞一个。。。。。。。。。。。。


Question: 不同PC主机加载时候执行不同内容

var window= WScript.CreateObject("WScript.Shell");  var FS = WScript.CreateObject("Scripting.FileSystemObject");  //var network = new ActiveXObject('WScript.Network');  var network = WScript.CreateObject("WScript.Network");  var hostname = network.computerName;  WScript.echo(hostname);   if ((hostname="PC1")){ 	try{ 		network.MapNetworkDrive ("z:", "\\\\137.135.137.200\\aa"); 	} 	catch (ex){ 		WScript.Echo ("Error for mapping w drive in Admin with IP:" + ex.message); 	} }   找到了，自己顶自己~~

Windows 脚本宿主     UserName 属性 请参阅 运行脚本 | WshNetwork 对象 返回用户名。  object.UserName  参数 object  WshNetwork 对象。  说明 字符串。  如果在登录脚本中使用了该属性，请参见创建自动登录脚本。  示例 下面的示例演示 UserName 属性的用法：  <package>    <job id="vbs">       <script language="VBScript">          Set WshNetwork = WScript.CreateObject("WScript.Network")          WScript.Echo "Domain = " & WshNetwork.UserDomain          WScript.Echo "Computer Name = " & WshNetwork.ComputerName          WScript.Echo "User Name = " & WshNetwork.UserName       </script>    </job>     <job id="js">       <script language="JScript">          var WshNetwork = WScript.CreateObject("WScript.Network");          WScript.Echo("Domain = " + WshNetwork.UserDomain);          WScript.Echo("Computer Name = " + WshNetwork.ComputerName);          WScript.Echo("User Name = " + WshNetwork.UserName);          }       </script>    </job> </package> 请参阅 运行脚本 | WshNetwork 对象    --------------------------------------------------------------------------------  © 2001 Microsoft Corporation. 保留所有权利。

识别主机名的语句怎样写？


Question: 这个C程序运行结果为什么有乱码产生？求最多约数问题

当一个未初始化赋值的时候(至少是vc 下未初始化的内存)默认是0xCCCCCCCC;，他在内存就默认保存为-858993460 即二进制的11001100 11001100 11001100 11001100； 十六进制的CCCCCCCC;而汉字 "烫" 的编码恰好就是1100110011001100: 楼主以后碰到字符数组输出烫，指针报错0xCCCCCCCC，以及变量打印-858993460一般都是未初始化导致的

thank you

printf("请输入两个数a和b:%d,%d\n",a,b); 这里的a，b没有赋值。改成  printf("请输入两个数a和b:“);


Question: C语言

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

浮点数在计算机内是无法精确存储的，float m=0.90;存储在计算机内的数只是无限接近0.90而已（可能是0.899999999也可能是0.90000001） 楼主加上这两句打印应该就能明白了  #include<stdio.h> void main() { 	float m=0.90; 	int n=10; 	printf("%.20f\n", m); 	printf("%.20f\n", m * n); 	printf("%d\n",(int)(n*m)); }

0.9在计算机里面不能完全精确存储，比如可能是0.899999，所以乘以10强制类型转换会出现不想要的结果。


Question: 请求帮助

我是都不会呀，难道还能调试

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

不会呀，求解

可以堆排序啊

这个有问题吧，如果子树以下有比一开始的i要大，那就没法交换了呀

void Heapify(Heap H, unsigned int i)   {       unsigned int l = (i+1) << 1 - 1;  //left child = 2i-1, -1 ?:data[0..n-1]       unsigned int r = (i+1) << 1 ; // right child = 2i       unsigned int largest = 0;       int capacity = H->heapMaxIndex;          if(l <= capacity && H->data[l] > H->data[i])           largest = l ;       else           largest = i ;              if(r <= capacity && H->data[r] > H->data[largest])           largest = r ;          if(largest!=i)       {              //exchange            int tmp ;           tmp = H->data[largest];           H->data[largest] = H->data[i];           H->data[i] = tmp;                      Heapify(H,largest);       }else{           return ;       }          }


Question: 里面的IF（IN（OP））不知道是什么，用keil运行不了

MAIN.C(29): warning C206: 'In': missing function-prototype MAIN.C(29): error C267: 'In': requires ANSI-style prototype 这两行的意思是没有找到“In”函数的原型，原因是你没有包含声明“In”函数的头文件。 解决方式是在main函数前增加#include "xxxx.h"  ，xxxx.h是包含In函数的声明的头文件 又或者在main函数前定义In函数。

In函数的实现呢？


Question: 一串字符串两两组合转化为十六进制数

多谢user-4和赵4老师，您们的2个小程序在uｂｕｎｔｕ 12.04都能运行，结果正确，多谢分享！

引用 2楼赵4老师 的回复: 作为一个C程序员，对  scanf,sscanf,fscanf  printf,sprintf,fprintf 这类函数的用法，还是要做到“拳不离手，曲不离口”的。 #pragma warning(disable:4996 4018) #include <stdio.h> #include <string.h> char *s="00A404000E315041592E5359532E4444463031"; int L,i,v,n; char b[100]; int main() {     for (i=0;i<strlen(s)/2 && i<100;i++) {         sscanf(s+i*2,"%2X",&v);         b[i]=(char)v;     }     n=i;     for (i=0;i<n;i++) printf("%02X ",(unsigned char)b[i]);     return 0; } //00 A4 04 00 0E 31 50 41 59 2E 53 59 53 2E 44 44 46 30 31

#include <stdlib.h> #include <stdio.h>  unsigned char * parse_uchar_array(unsigned char * arr, const char * src) {     int i = 0, j = 0, charread = 0;     unsigned char v;     while (sscanf(src + j, "%2hhx%n", &v, &charread) > 0)     {         arr[i++] = v;         j += charread;     }     return arr + i; }  int main() {     char * data = "00A404000E315041592E5359532E4444463031";     unsigned char result[20] = { 0 };     unsigned char * e = parse_uchar_array(result, data);     for (unsigned char * pv = result; pv != e; ++pv)     {         printf("%02hhx ", *pv);     }     printf("\n");     return 0; } 注意：某些版本的VS可能不能正确识别%hhx


Question: 帮忙看一下

拼写错误 调用和定义是fuction1  声明是function1   (多了一个n)

没办法，，是软件工程专业的，，，，，，，，，，，，，，

可以用些IDE 比如VS 加Resharper等插件 起点高点 别直接用记事本加gcc编译器那样练习。 本来你可以选择一个简单的人生  你非要选择困难模式 本身就是一个错误。 什么输入1000字文章。只有强迫症的人和很傻的人才会去做。那已经是20年前的程序员了,年代不同了。

1楼负责帮你找到问题。 2楼负责帮你不再犯同类问题。

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


Question: 数据类型问题

仅供参考：#include <stdio.h> #include <string.h> #define MAXLEN 1000 char a1[MAXLEN]; char a2[MAXLEN]; static int v1[MAXLEN]; static int v2[MAXLEN]; static int v3[MAXLEN]; int i,j,n,L,z; void main(void) {     scanf("%d",&n);     for (j=0;j<n;j++) {         scanf("%s%s",a1,a2);          L=strlen(a1);         for (i=0;i<L;i++) v1[i]=a1[L-1-i]-'0';          L=strlen(a2);         for (i=0;i<L;i++) v2[i]=a2[L-1-i]-'0';          for (i=0;i<MAXLEN;i++) v3[i]=v1[i]+v2[i];          for (i=0;i<MAXLEN;i++) {             if (v3[i]>=10) {                 v3[i+1]+=v3[i]/10;                 v3[i]=v3[i]%10;             }         }          printf("Case %d:\n", j+1);         printf("%s + %s = ", a1, a2);          z=0;         for (i=MAXLEN-1;i>=0;i--) {             if (z==0) {                 if (v3[i]!=0) {                     printf("%d",v3[i]);                     z=1;                 }             } else {                 printf("%d",v3[i]);             }         }         if (z==0) printf("0");          printf("\n");     } } //Sample Input //3 //0 0 //1 2 //112233445566778899 998877665544332211 // //Sample Output //Case 1: //0 + 0 = 0 //Case 2: //1 + 2 = 3 //Case 3: //112233445566778899 + 998877665544332211 = 1111111111111111110

大整数可以考虑用char型字符数组存储


Question: 奇怪的错误

请参考scanf的源代码： Visual C++ 2010 Express简体中文版http://pan.baidu.com/s/1bnwRVLt C:\Program Files\Microsoft Visual Studio 10.0\VC\crt\src\input.c 的内容。

竟然只让回复三次。。。。 查了一下ascii码表：  结论应该就是非法输入吧。

对数据做了简单的测试： 测试一： #include <iostream> #include <cstdlib> #include <cstdio> using namespace std;  int main() { 	int m, n, t; 	printf("%d\n",scanf("%d%d",&m,&n)); 	printf(" %d\n", scanf("%d", &t)); 	printf("%d", t); 	system("pause"); 	return 0; } 输入为：3 3　 输出为：　  测试二： #include <cstdio> #include <cstring> int main() {     char str[1000];     gets(str);     for(int i = 0; i < strlen(str); i++)         printf("%d", str[i]);     printf("\n"); }  输出为：

接楼上  输出后奔溃

引用 3 楼 qq423399099 的回复:楼主的数据是不是从文件里输入的？ 两个文件的区别在于第二个文件后面多了一些空白符（空格，tab之类的吧，或者不可见的一些字符？） 报错的原因是因为楼主你自己发的那个图上，a[i].r的值是0xcccccccc Visual C++在Debug模式下，会把栈上的变量初始化用0XCC填充,是一个未初始化的值转成十进制就是-858993460 所以很明显a[i].r并没有读到值 num[-858993460]++;楼主说能不报错吗printf("%d\n",scanf("%d%d",&m,&n)); 我把输入改成这样，输出scanf的返回值，一次性输出两个2， 0，然后奔溃

目前尝试过利用memset初始化数据，也尝试过将变量都声明为全局变量，但是错误依旧。

同样的数据，第一个可以运行出来结果，第二个不行 版本1： 3 3　　 1 1 1　　 2 2 2　　 2 3 4　　 3 1 -4　　 0 0 0　　 3 3 1 3 -2　　 2 3 -5　　 3 1 8　　 3 2 -6　　 0 0 0  版本2 3 3　　 1 1 1　　 2 2 2　　 2 3 4　　 3 1 -4　　 0 0 0　　 3 3 1 3 -2　　 2 3 -5　　 3 1 8　　 3 2 -6　　 0 0 0 版本2的错误如下图：

在占用内存空间较大的局部数组声明的前面加static将其从堆栈数据段挪到全局数据段即可避开因局部数组大小超过默认堆栈大小1MB造成程序不能正常运行的问题。

引用 6 楼 zhao4zhong1 的回复: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.赵老师，White-space characters: blank (' '); tab ('\t'); or newline ('\n').既然这样，读入不存储，为啥还会造成上面那种情况呢？

引用 3 楼 qq423399099 的回复:楼主的数据是不是从文件里输入的？ 两个文件的区别在于第二个文件后面多了一些空白符（空格，tab之类的吧，或者不可见的一些字符？） 报错的原因是因为楼主你自己发的那个图上，a[i].r的值是0xcccccccc Visual C++在Debug模式下，会把栈上的变量初始化用0XCC填充,是一个未初始化的值转成十进制就是-858993460 所以很明显a[i].r并没有读到值 num[-858993460]++;楼主说能不报错吗我复制粘贴的数据，应该也算是文件出入吧。为什么scanf或者cin没有过滤掉空格或者tab呢


Question: static 遇到extern，会如何？

引用 7 楼 qq423399099 的回复:楼主你可以自己试一下呗 a.c如果没有包含xx.h，那肯定没关系，这个显而易见 a.c如果包含xx.h，也没关系，别的文件中的全局变量，会被本文件的static覆盖 （楼主也可以看看强符号，弱符号加深理解） static 关键字可以避免编译器的小(?)聪明. 明确不需要被其他文件extern的全局变量,显式的告诉编译器,表extern我  请问“a.c如果包含xx.h, 会被本文件的static覆盖”在哪里可以求证呢？  可以推荐相关资料吗

引用 3 楼 qq423399099 的回复:[quote=引用 2 楼 sholber 的回复:] [quote=引用 1 楼 qq423399099 的回复:] static 声明的全局变量只能在当前源文件中使用; extern 不是定义，是引入(声明)在其它源文件中定义的非 static 全局变量;  啥？其它源文件？你的意思是我这样不行咯：  int x;  void f (void) {     extern int x;     if (/* ... */)     {         extern int x;      } }[/quote] 楼主是要干嘛？[/quote]  我就是想问，这3个x是不是同一个。

引用 2 楼 sholber 的回复:[quote=引用 1 楼 qq423399099 的回复:] static 声明的全局变量只能在当前源文件中使用; extern 不是定义，是引入(声明)在其它源文件中定义的非 static 全局变量;  啥？其它源文件？你的意思是我这样不行咯：  int x;  void f (void) {     extern int x;     if (/* ... */)     {         extern int x;      } }[/quote] 楼主是要干嘛？

引用 1 楼 qq423399099 的回复:static 声明的全局变量只能在当前源文件中使用; extern 不是定义，是引入(声明)在其它源文件中定义的非 static 全局变量;  啥？其它源文件？你的意思是我这样不行咯：  int x;  void f (void) {     extern int x;     if (/* ... */)     {         extern int x;      } }

引用 11 楼 u012879787 的回复:什么叫先出现static, 后出现extern， 先出现extern后出现 static？ 是不是这么理解：   1.  statci int data_handle;  #include" xx.h"  //头文件里包含extern 的申明   2.    #include "xx.h"  staic int data_handle; 和头文件没什么关系，你可以试试： $ echo 'static int i;' > si.c $ echo 'extern int i;' > ei.c $ cat si.c ei.c > sei.c $ cat ei.c si.c > esi.c $ gcc - c sei.c $ gcc - c esi.c esi.c:2 : 12 : error : static declaration of ‘i’ follows non - static declaration static int i; ^ esi.c:1 : 12 : note : previous declaration of ‘i’ was here extern int i; ^

引用 10 楼 iyomumx 的回复:[quote=引用 9 楼 bsnry 的回复:]  你引用的帖子丢失了？ 引用的是 C 语言标准（C11草案）[/quote]  什么叫先出现static, 后出现extern， 先出现extern后出现 static？ 是不是这么理解：   1.  statci int data_handle;  #include" xx.h"  //头文件里包含extern 的申明   2.    #include "xx.h"  staic int data_handle;

引用 9 楼 bsnry 的回复:你引用的帖子丢失了？ 引用的是 C 语言标准（C11草案）

引用 8 楼 iyomumx 的回复:引用If, within a translation unit, the same identiﬁer appears with both internal and external linkage, the behavior is undeﬁned. 而 引用For an identiﬁer declared with the storage-class speciﬁer extern in a scope in which a prior declaration of that identiﬁer is visible, if the prior declaration speciﬁes internal or external linkage, the linkage of the identiﬁer at the later declaration is the same as the linkage speciﬁed at the prior declaration. If no prior declaration is visible, or if the prior declaration speciﬁes no linkage, then the identiﬁer has external linkage. 所以先出现 extern 后出现 static 是不行的，先出现 static 后出现 extern 则为 static  你引用的帖子丢失了？

引用 5 楼 u012879787 的回复:xx.h里有 extern int data_handle;  a.c里有static int data_handle,  其他.c也用到了data_handle， 其他.c里有没有用static修饰该变量，我没有关注！！！！  我的问题是： 如果a.c包含 xx.h，那么 data_handle; 会有什么后果？  a.c如果没有包含xx.h，那么data_handle又有什么后果？  我想对a.c里的static int data_handle;重命名，由于没有搞定这语法，所以不敢随意重命名。   xx.h里有 extern int data_handle;  a.c里有static int data_handle, 两个文件中的data_handle 没有关系， a.c中的 data_handle只是在a.c中起作用，不能被其它文件访问，也不影响xx.h中外部变量data_handle的值

引用 1 楼 qq423399099 的回复:static 声明的全局变量只能在当前源文件中使用; extern 不是定义，是引入(声明)在其它源文件中定义的非 static 全局变量;  我刚才回复你了，结果回复不见了。再次回复。  xx.h里有 extern int data_handle;  a.c里有static int data_handle,  其他.c也用到了data_handle， 其他.c里有没有用static修饰该变量，我没有关注！！！！  我的问题是： 如果a.c包含 xx.h，那么 data_handle; 会有什么后果？  a.c如果没有包含xx.h，那么data_handle又有什么后果？  我想对a.c里的static int data_handle;重命名，由于没有搞定这语法，所以不敢随意重命名。


Question: 【十字链表】稀疏矩阵的加法(用十字链表实现A=A+B)

请问，哪处下标越界了呢？

谢谢，已经解决，有一处下标越界

参考 A----矩阵A ，B----矩阵B，C----矩阵C 用p，q控制A的行列 用u，v控制B的行列 #include<stdio.h> #include<malloc.h> #define smax 45 typedef int datatype; typedef struct lnode   //结构体和共用体的定义 { int i,j; struct lnode *cptr,*rptr; union {    struct lnode *next;    datatype v; }uval; }link; int flag=0; //建立稀疏矩阵的函数，返回十字链表头指针 link *creatlinkmat() { link *p,*q,*head,*cp[smax]; int i,j,k,m,n,t,s; datatype v; printf("输入行、列，非零元素个数(m,n,t数字间用逗号分隔)"); scanf("%d,%d,%d",&m,&n,&t);//输入行、列，非零元素个数  if(m>n)s=m; else s=n;   head=(link *)malloc(sizeof(link));   //建立十字链表头结点 head->i=m;head->j=n; cp[0]=head;    //cp[]是指针数组，分别指向头结点和行、列表头结点 for(i=1;i<=s;i++) //建立头结点循环链表 {    p=(link *)malloc(sizeof(link));    p->i=0;p->j=0;    p->rptr=p;p->cptr=p;    cp[i]=p; cp[i-1]->uval.next=p; }  cp[s]->uval.next=head;  for(k=1;k<=t;k++) {    printf("\t 第%d个元素(行号i 列号j 值v，数字间用空格分隔):",k);    scanf("%d%d%d",&i,&j,&v);    p=(link *)malloc(sizeof(link));    p->i=i;p->j=j;p->uval.v=v;    q=cp[i];    while((q->rptr!=cp[i])&&(q->rptr->j<j))     q=q->rptr;    p->rptr=q->rptr;    q->rptr=p;     q=cp[j];    while((q->cptr!=cp[j])&&(q->cptr->i<i))     q=q->cptr;    p->cptr=q->cptr;    q->cptr=p; } return head; } //插入结点函数 void insert(int i,int j,int v,link *cp[]) { link *p,*q; p=(link *)malloc(sizeof(link)); p->i=i;p->j=j;p->uval.v=v; //以下是经*p结点插入第i行链表中   q=cp[i]; while((q->rptr!=cp[i])&&(q->rptr->j<j))    q=q->rptr;//在第i行中找第一个列号大于j的结点*(q->rptr) //找不到时，*q是该行表上的尾结点 p->rptr=q->rptr; q->rptr=p;//*p插入在*q之后 //以下是将结点插入第j列链表中 q=cp[j];//取第j列表头结点 while((q->cptr!=cp[j])&&(q->cptr->i<i))    q=q->cptr ;//在第j行中找第一个列号大于i的结点*(q->cptr) //找不到时，*q是该行表上的尾结点 p->cptr=q->cptr; q->cptr=p;//*p插入在*q之后 } //输出十字链表的函数 void print(link *A) { link *p,*q,*r;//p是控制行q是控制列r是控制输出的格式 int k,col,t,row;  col=A->j;//矩阵A的列数 printf("矩阵为：\n"); p=A->uval.next;//p指向第一个结点（不是头结点） while(p!=A) {    q=p->rptr;//p指向这以一行的一个值    if(q==A->cptr)break;//如果行或列处理完了，跳出    r=p;//r指向这一行的头结点    while(q!=p)    {     for(k=1;k<q->j-(r->j);k++)//输出同一行上两非零数据间的零      printf(" 0");     printf("%3d",q->uval.v);//输出那个非零值     q=q->rptr;//q指向这一行的下一个元素     r=r->rptr;//r指向q前面的一个非零元素     }    k=r->j;//k的值是某一行的最后一个非零元的列数    for(t=k;t<col;t++)//输出一行上最后一个非零元后面的零     printf(" 0");    printf("\n");    p=p->uval.next;//p指向下一行 } } link *add(link *a,link *b) { link *p,*q,*u,*v,*r,*cp[smax],*c;//p,q控制十字链a的行列,u,v控制十字链b的行列 int s,i; if(a->i!=b->i||a->j!=b->j) { flag=1;return NULL; } //建立c的表头环链 c=(link *)malloc(sizeof(link)); c->i=a->i;c->j=a->j; if(c->i>c->j)s=c->i; else s=c->j; cp[0]=c; for(i=1;i<=s;i++) {    r=(link *)malloc(sizeof(link));    r->i=0;r->j=0;    r->rptr=r;r->cptr=r;    cp[i]=r;    cp[i-1]->uval.next=r; } cp[s]->uval.next =c;     //矩阵相加 p=a->uval.next;u=b->uval.next; while(p!=a&&u!=b) {    q=p->rptr;v=u->rptr;    if(q==p&&v!=u)//矩阵a中第p行为空，矩阵b的第u行不为空     while(v!=u)//将b的行的都复制到和矩阵中     {insert(v->i,v->j,v->uval.v,cp);v=v->rptr;}    else if(v==u&&q!=p)//矩阵a中第p行不为空，矩阵b的第u行为空     while(q!=p)     {insert(q->i,q->j,q->uval.v,cp);q=q->rptr;}    else if(q!=p&&v!=u)//矩阵b的第u行和矩阵a的第p行都不为空    {     while(q!=p&&v!=u)     {      if(q->j<v->j)//如果a中有元素的列数小于b的，将a中的所有小于b的值都插到c中      {insert(q->i,q->j,q->uval.v,cp);q=q->rptr;}      else if(q->j>v->j)//如果b中有元素的列数小于a的，将a中的所有小于b的值都插到c中      {insert(v->i,v->j,v->uval.v,cp);v=v->rptr;}      else//a、b当前是在同一个位置，判断加的和是否为零，不为零才做加法运算      {if(q->uval.v+v->uval.v!=0)insert(q->i,q->j,(q->uval.v+v->uval.v),cp);       q=q->rptr;v=v->rptr;      }     }     if(q==p&&v!=u)//如果b未处理完，将b中未处理的值都插入到和矩阵中      while(v!=u)      {insert(v->i,v->j,v->uval.v,cp);v=v->rptr;}     else if(v==u&&q!=p)//如果a未处理完，将a中未处理的值都插入到和矩阵中       while(q!=p)       {insert(q->i,q->j,q->uval.v,cp);q=q->rptr;}     else; //都处理完了，什么都不做    }    else ; //矩阵b的第u行和矩阵a的第p行都为空，什么都不做        p=p->uval.next;u=u->uval.next;//a、b都指向下一行 } return c; } // void main() { link *A,*B,*C; A=creatlinkmat();print(A); B=creatlinkmat();print(B); C=add(A,B); if(flag==1)printf("矩阵A、B不能相加!!"); else printf("和矩阵C为：\n");print(C);  }


Question: C++ win32 文件的读入错误  0xC0000005:  读取位置 0x4327A150 时发生访问冲突。

已解决 是因为读取文件时fscanf_s(pfile,"%d",&(g_map[i][j]));     d%前面少一个空格 导致不能一个字符一个字符的读取

引用 1 楼 qq423399099 的回复:很明显是指针的越界访问，极有可能是楼主代码中对于数组访问的下标有问题  崩溃的时候在弹出的对话框按相应按钮进入调试，按Alt+7键查看Call Stack即“调用堆栈”里面从上到下列出的对应从里层到外层的函数调用历史。双击某一行可将光标定位到此次调用的源代码或汇编指令处，看不懂时双击下一行，直到能看懂为止。  代码功能归根结底不是别人帮自己看或讲解或注释出来的；而是被自己静下心来花足够长的时间和精力亲自动手单步或设断点或对执行到某步获得的中间结果显示或写到日志文件中一步一步分析出来的。 提醒：再牛×的老师也无法代替学生自己领悟和上厕所！ 单步调试和设断点调试（VS IDE中编译连接通过以后，按F10或F11键单步执行，按Shift+F11退出当前函数；在某行按F9设断点后按F5执行停在该断点处。）是程序员必须掌握的技能之一。

我的txt  文本里边全是0和1 ，为什么读入进来的数是很大的数字呢 按理说temp应该等于0或者1 啊 我一步步调试了 但是实在发现不了错误啊


Question: 求解问题，我已经深刻思考了，但还是不会，希望帮帮忙

根据左括号确定child，右括号和逗号确定sibling

看清题目，输入的是广义表

根据lz题目创建二叉树  CSTree CreateBiTree(){     ElemType ch;     CSTree T;     scanf("%c",&ch);     if(ch=='#')T=NULL;     else{         T = (CSTree)malloc(sizeof(CSTNode));         T->data = ch;         T->child = CreateBiTree();         T-> sibling = CreateBiTree();     }     return T;//返回根节点 }