Question: 求助一个结构体长度问题

引用 6 楼 zhao4zhong1 的回复:仅供参考：#include <stdio.h> #define field_offset(s,f) (int)(&(((struct s *)(0))->f)) struct AD  { int a; char b[13]; double c;}; #pragma pack(push) #pragma pack(1) struct A1  { int a; char b[13]; double c;}; #pragma pack(2) struct A2  { int a; char b[13]; double c;}; #pragma pack(4) struct A4  { int a; char b[13]; double c;}; #pragma pack(8) struct A8  { int a; char b[13]; double c;}; #pragma pack(16) struct A16 { int a; char b[13]; double c;}; #pragma pack(pop) int main() {     printf("AD.a %d\n",field_offset(AD,a));     printf("AD.b %d\n",field_offset(AD,b));     printf("AD.c %d\n",field_offset(AD,c));     printf("AD sizeof %d\n", sizeof(AD));     printf("\n");     printf("A1.a %d\n",field_offset(A1,a));     printf("A1.b %d\n",field_offset(A1,b));     printf("A1.c %d\n",field_offset(A1,c));     printf("A1 sizeof %d\n", sizeof(A1));     printf("\n");     printf("A2.a %d\n",field_offset(A2,a));     printf("A2.b %d\n",field_offset(A2,b));     printf("A2.c %d\n",field_offset(A2,c));     printf("A2 sizeof %d\n", sizeof(A2));     printf("\n");     printf("A4.a %d\n",field_offset(A4,a));     printf("A4.b %d\n",field_offset(A4,b));     printf("A4.c %d\n",field_offset(A4,c));     printf("A4 sizeof %d\n", sizeof(A4));     printf("\n");     printf("A8.a %d\n",field_offset(A8,a));     printf("A8.b %d\n",field_offset(A8,b));     printf("A8.c %d\n",field_offset(A8,c));     printf("A8 sizeof %d\n", sizeof(A8));     printf("\n");     printf("A16.a %d\n",field_offset(A16,a));     printf("A16.b %d\n",field_offset(A16,b));     printf("A16.c %d\n",field_offset(A16,c));     printf("A16 sizeof %d\n", sizeof(A16));     printf("\n");     return 0; } //AD.a 0 //AD.b 4 //AD.c 24 //AD sizeof 32 // //A1.a 0 //A1.b 4 //A1.c 17 //A1 sizeof 25 // //A2.a 0 //A2.b 4 //A2.c 18 //A2 sizeof 26 // //A4.a 0 //A4.b 4 //A4.c 20 //A4 sizeof 28 // //A8.a 0 //A8.b 4 //A8.c 24 //A8 sizeof 32 // //A16.a 0 //A16.b 4 //A16.c 24 //A16 sizeof 32 // //   结构体默认的字节对齐准则： 1.           结构体变量的首地址能够被其最宽基本类型成员的大小所整除； 2.           结构体每个成员相对于结构体首地址的偏移量（offset）都是成员大小的整数倍，如有需要编译器会在成员之间加上填充字符； 3.           结构体的总大小为结构体最宽基本类型成员大小和编译器缺省対界条件大小中比较小得那个值的整数倍，如有需要编译器会在最后一个成员之后加上填充字节；  之前一直不太理解 ， 后来发现有个offsetof()函数。 然后结合起来，大概白话意思就是：  struct _test{    int a;    char b[10]; } A偏移0 A长度4 B便宜4 B长度 1*10 = 10 第一和第二规则算：长度为 4+10=14 第三规则来算：总长度要是最宽成员长度的整数倍，也就是说必须是4的整数倍， 所以加上2对齐 14+2 = 16

对齐的时候，数组看成是多个单体排列成的

这是结构体对齐的原因；4字节对齐，所以在结构体最后补了2个字节。sizeof(struct _parent)长度是4+12(2个补齐）+4，所以是20. sizeof(struct _son)是4+10+2(补齐）= 16

要能够被最宽基本类型的变量长度所整除。

内存对齐的原因：32位系统最高按照4字节对齐，指针在32位系统中4个字节

sizeof(struct _parentt)吧！！！

楼楼你的10+10是什么想的啊


Question: PAT甲级    1002. A+B for Polynomials (25)

#include<stdio.h> #include<stdlib.h>  typedef struct Node{     double exp,coef;     struct Node *next; }*LinkList,Node;  LinkList createList(void) {     LinkList L;     L = (Node *)malloc(sizeof(Node));     L->next = NULL;     return L; } void insert(LinkList L,double exp,double coef) {     Node *p,*pre,*s;     p = L->next;     pre = L;     while(p && p->exp > exp){         pre = p;         p = p->next;     }     s = (Node*)malloc(sizeof(Node));     s->coef = coef;     s->exp = exp;     s->next = pre->next;     pre->next = s; } void plus(LinkList LA, LinkList LB) {     Node *p1,*p2,*pre,*temp;     pre = LA;     p1 = LA->next;     p2 = LB->next;     LA->next = NULL;     while(p1 && p2){         if(p1->exp > p2->exp){             pre->next = p1;             pre = p1;             p1 = p1->next;         }         else if(p1->exp < p2->exp){             pre->next = p2;             pre = p2;             p2 = p2->next;         }         else if(p1->exp == p2->exp){             p1->coef = p1->coef + p2->coef;             if(p1->coef != 0){                 pre->next = p1;                 pre = p1;                 p1 = p1->next;                 temp = p2;                 p2 = p2->next;                 free(temp);   /* free temp not p2*/                 //free(p2);             } else if(p1->coef == 0){                 temp = p1;                 p1 = p1->next;                 free(temp);                 temp = p2;                 p2 = p2->next;                 free(temp);             }         }     }     if(p1){         pre->next = p1;     }     else if(p2){         pre->next=p2;     }     free(LB);  } int Listlength(LinkList L) {     int k=0;     Node *p;      p = L->next;     while(p){         k++;         p = p->next;     }      return k; } void output(LinkList L) {     Node *p;     p = L->next;     while(p){         printf(" %.0lf %.1lf ",p->exp,p->coef);         p = p->next;     }     printf("\n"); } int main(void) {     int a,b,sum;     double exp,coef;     LinkList LA;     LinkList LB;      LB = createList();     LA = createList();     scanf("%d", &a);     while(a != 0){         scanf("%lf %lf", &exp, &coef);         insert(LA, exp, coef);         a--;     }     scanf("%d", &b);     while(b != 0){         scanf("%lf %lf",&exp, &coef);         insert(LB,exp,coef);         b--;     }     plus(LA,LB);     sum = Listlength(LA);     printf("%d\n", sum);     output(LA);     return 0; }  代码写的不错，有一个小问题，应该free(temp)，但是你释放的是p2，详见上面的代码；  其他地方也做了修改，但不是逻辑问题，而是个人习惯。比如 while(p1 && p2){ 你的判断是这样的： while(p1!=NULL&&p2!=NULL){ 这个地方需要理解的地方是，当p1 == NULL或p2 == NULL 时，则为假


Question: 怎么从一个不连通的图中找到连通的子图

这个是根据路径得到节点关系吧 每拿到一张卡片，就对这两个节点标记连通，用同一个网络号来标记，如果这两个节点有一个已经有了网络号， 则另一个节点也赋予同样的网络号，如果两个都没有网络号，给一个新的网络号，如果两个都有了网络号 把两个网络合并（用一个网络号替换另一个网络号）。 最后按照网络号码累加力量值得到结果

你的思想我也想过，但是用c语言实现起来还是比较困难的。看看还有没有别的方法？？

并查集 为每个根节点额外保存一个值代表该组实力，合并时将根节点的实力值相加即可。


Question: 小白。。怎么把下面那个函数写到程序里？？C语言：一个二叉树构造问题 麻烦直接给个代码！！！懂的大神顺便解释下原理，谢谢了

仅供参考：#include <iostream> #include <stack> #include <queue> #include <locale.h> using namespace std; typedef struct BiTNode {//二叉树结点     char data;                      //数据     struct BiTNode *lchild,*rchild; //左右孩子指针 } BiTNode,*BiTree; int CreateBiTree(BiTree &T) {//按先序序列创建二叉树     char data;     scanf("%c",&data);//按先序次序输入二叉树中结点的值（一个字符），‘#’表示空树     if (data == '#') {         T = NULL;     } else {         T = (BiTree)malloc(sizeof(BiTNode));         T->data = data;         //生成根结点         CreateBiTree(T->lchild);//构造左子树         CreateBiTree(T->rchild);//构造右子树     }     return 0; } void Visit(BiTree T) {//输出     if (T->data != '#') {         printf("%c ",T->data);     } } void PreOrder(BiTree T) {//先序遍历     if (T != NULL) {         Visit(T);               //访问根节点         PreOrder(T->lchild);    //访问左子结点         PreOrder(T->rchild);    //访问右子结点     } } void InOrder(BiTree T) {//中序遍历     if (T != NULL) {         InOrder(T->lchild);     //访问左子结点         Visit(T);               //访问根节点         InOrder(T->rchild);     //访问右子结点     } } void PostOrder(BiTree T) {//后序遍历     if (T != NULL) {         PostOrder(T->lchild);   //访问左子结点         PostOrder(T->rchild);   //访问右子结点         Visit(T);               //访问根节点     } } void PreOrder2(BiTree T) {//先序遍历(非递归) //访问T->data后，将T入栈，遍历左子树；遍历完左子树返回时，栈顶元素应为T，出栈，再先序遍历T的右子树。     stack<BiTree> stack;     BiTree p = T;//p是遍历指针     while (p || !stack.empty()) {   //栈不空或者p不空时循环         if (p != NULL) {             stack.push(p);          //存入栈中             printf("%c ",p->data);  //访问根节点             p = p->lchild;          //遍历左子树         } else {             p = stack.top();        //退栈             stack.pop();             p = p->rchild;          //访问右子树         }     } } void InOrder2(BiTree T) {//中序遍历(非递归) //T是要遍历树的根指针，中序遍历要求在遍历完左子树后，访问根，再遍历右子树。 //先将T入栈，遍历左子树；遍历完左子树返回时，栈顶元素应为T，出栈，访问T->data，再中序遍历T的右子树。     stack<BiTree> stack;     BiTree p = T;//p是遍历指针     while (p || !stack.empty()) {   //栈不空或者p不空时循环         if (p != NULL) {             stack.push(p);          //存入栈中             p = p->lchild;          //遍历左子树         } else {             p = stack.top();        //退栈，访问根节点             printf("%c ",p->data);             stack.pop();             p = p->rchild;          //访问右子树         }     } }  typedef struct BiTNodePost{     BiTree biTree;     char tag; } BiTNodePost,*BiTreePost; void PostOrder2(BiTree T) {//后序遍历(非递归)     stack<BiTreePost> stack;     BiTree p = T;//p是遍历指针     BiTreePost BT;     while (p != NULL || !stack.empty()) {//栈不空或者p不空时循环         while (p != NULL) {//遍历左子树             BT = (BiTreePost)malloc(sizeof(BiTNodePost));             BT->biTree = p;             BT->tag = 'L';//访问过左子树             stack.push(BT);             p = p->lchild;         }         while (!stack.empty() && (stack.top())->tag == 'R') {//左右子树访问完毕访问根节点             BT = stack.top();             stack.pop();//退栈             printf("%c ",BT->biTree->data);         }         if (!stack.empty()) {//遍历右子树             BT = stack.top();             BT->tag = 'R';//访问过右子树             p = BT->biTree;             p = p->rchild;         }     } }  void LevelOrder(BiTree T) {//层次遍历     if (T == NULL) return;     BiTree p = T;     queue<BiTree> queue;//队列     queue.push(p);//根节点入队     while (!queue.empty()) {    //队列不空循环         p = queue.front();      //对头元素出队         printf("%c ",p->data);  //访问p指向的结点         queue.pop();            //退出队列         if (p->lchild != NULL) {//左子树不空，将左子树入队             queue.push(p->lchild);         }         if (p->rchild != NULL) {//右子树不空，将右子树入队             queue.push(p->rchild);         }     } } int main() {     BiTree T;      setlocale(LC_ALL,"chs");     CreateBiTree(T);      printf("先序遍历        ：");PreOrder  (T);printf("\n");     printf("先序遍历(非递归)：");PreOrder2 (T);printf("\n");                                                printf("\n");     printf("中序遍历        ：");InOrder   (T);printf("\n");     printf("中序遍历(非递归)：");InOrder2  (T);printf("\n");                                                printf("\n");     printf("后序遍历        ：");PostOrder (T);printf("\n");     printf("后序遍历(非递归)：");PostOrder2(T);printf("\n");                                                printf("\n");     printf("层次遍历        ：");LevelOrder(T);printf("\n");      return 0; } //ABC##DE#G##F### //先序遍历        ：A B C D E G F //先序遍历(非递归)：A B C D E G F // //中序遍历        ：C B E G D F A //中序遍历(非递归)：C B E G D F A // //后序遍历        ：C G E F D B A //后序遍历(非递归)：C G E F D B A // //层次遍历        ：A B C D E F G //  ///       A ///      / ///     B ///    / \ ///   C   D ///      / \ ///     E   F ///      \ ///       G

在线等！！急急急


Question: 学习c语言中碰到的问题，请大神们帮忙解决，谢谢！

调试的时候闪过Hello World的黑幕，接着有出现上面的一幕了

非常感谢各位的答复。我现在去弄一下先，希望各位多多指教!

项目选的对不对哦？

怎么没有.h文件？光一个c文件怎么编译过去

查一下是不是有中文字符了，比如printf后面的分号；要么就是查一下printf中的双引号是不是中文的，若是改成英文的。另外，注意输入法的设置，应设置为英文和半月牙

哇，好开心，终于可以给小白解答问题了。 你这个问题一般都是由于输入法没设置好造成的吧。检查一下喽，要不就用notepad++查下看看。

引用 5 楼 l18277221302 的回复:调试的时候闪过Hello World的黑幕，接着有出现上面的一幕了 那应该是你的编译环境问题了吧，查一下看看是否需要配置一下。


Question: 0-1背包问题的代码，这段代码的Max_Value函数表示从前k个物品中选择，总体积不超过参数Weight,并且总价值最大的最优解，但是运行不出来，求指教

int Max_Value(int Weight,int a[],int b[],int k) {     //如果剩余容量为0，装不了了，价值为0；     //如果没有物品可装，价值也为0     if(Weight == 0 || k == 0){         return 0;     }      //剩余容量容不下第k个(索引k-1)物品，则递归求第k-1个物品     if(Weight < a[k-1])         return Max_Value(Weight,a,b,k-1);      //容量足够装第k个物品，装或者不装，取较大值     return max(Max_Value(Weight-a[k-1],a,b,k-1)+b[k-1],Max_Value(Weight,a,b,k-1)); }

下面函数无返回值 int max_value return后面参数传递错误 传递参数不要用a[] b[]直接a b


Question: TCP接收端如何判断文件接收结束

引用 9 楼 wangying_great的回复:[quote=引用 8 楼 mengsofts 的回复:] 因为TCP是以数据流的方式发送数据的，没有边界。所以在发送和接受这里你要进行额外的设计，可以在第一次通信的时候把文件的长度传给客户端，在在客户端收到这么长数据的时候退出即可。  对对对，昨天看了一晚上，终于知道发送端这边的基本思路了。就是在发送文件内容之前，定义一个结构体，将文件数据，以及文件数据的长度，还有一些你自己想要的一些信息放在结构体中，一并发送给客户端。[/quote] 聪明，结构体至少应该包括文件名、文件大小和文件md5(用来检验)。

聪明，结构体至少应该包括文件名、文件大小和文件md5(用来检验)。

引用 8 楼 mengsofts 的回复:因为TCP是以数据流的方式发送数据的，没有边界。所以在发送和接受这里你要进行额外的设计，可以在第一次通信的时候把文件的长度传给客户端，在在客户端收到这么长数据的时候退出即可。  对对对，昨天看了一晚上，终于知道发送端这边的基本思路了。就是在发送文件内容之前，定义一个结构体，将文件数据，以及文件数据的长度，还有一些你自己想要的一些信息放在结构体中，一并发送给客户端。

引用 6 楼 zhao4zhong1 的回复:不知道有多少前人掉在TCP Socket send(人多)send(病少)send(财富) recv(人多病)recv(少财富) 陷阱里面啊！ http://bbs.csdn.net/topics/380167545  谢谢啦，虽然看的一知半解。哈哈

引用 4 楼 adlay 的回复:客户端再请求文件可以再 connect 重新建立一条链接来呀 把传控制协议的通道和传数据的通道分开是最好的.  其实我也是这么做的，建立两条通道，一个请求文件，一个接收文件。但是整个大程序是在一个epoll的监听集合里(不是使用fork创建子进程的方式)，如果两条连接的话，就必须给这两条连接建立关联，而且连接变多的话，整个epoll程序会变复杂很多。所以我觉得可能只用一条连接，不用通过断开连接就能结束接收的话程序会变简单很多。

这条连接不能关闭，因为在这个文件发送结束后，客户端可能还要继续请求文件，如果这条连接关闭了，客户端就不能继续请求文件了。

一种办法是服务器发送结束就直接断开连接，但是如果还有其他业务需要通信这种办法不太靠谱； 另一种办法是，服务器先给客户端发送文件的大小，然后客户端通过这个大小自己决定何时结束；

发送文件的一端发送完成后把 socket close 掉接收端的 recv 就会返回 0 了


Question: 请教一个关于strlen函数的问题

使用前初始初始化一下  char xing[10] = {0}; char ming[20] = {0};  否则a，b可能是任意的值

没有初始化就调用strlen导致的。

xing和ming未初始化，在大多数的平台上他们的值是随机的，所以什么长度都有可能，亦可超出定义的字符数组长度。少数平台下会自动初始化为全0，这时对初始值取长度会是0。 为了忽略平台的差别，通常我们都会在定义时先做初始化，比如char xing[10] = { 0 }。

请问楼主是想让用户输入一个正常的姓氏吗？ 这个代码可以让用户必须输入像人名的名字 希望能帮到你 你试一下就知道了 # include <stdio.h> # define N 8 # define At(t)  (t<'a'||t>'z')&&(t<'A'||t>'Z')&&t!='-' int Getchar(char *A,int min,int max);//长度在[min,max]  <闭区间>  之间时 函数结束 返回字符串A的长度  int BF(char a[],char b[]); int check(char S[]); int ISxing(char A[],int B);//如果姓氏查到返回 1  char name[]={"赵 钱 孙 李 周 吴 郑 王 冯 陈 楮 卫 蒋 沈 韩 杨 朱 秦 尤 许 何 吕 施 张 孔 曹 严 华 金 魏 陶 姜 戚 谢 邹 喻 柏 水 窦 章 云 苏 潘 葛 奚 范 彭 郎 鲁 韦 昌 马 苗 凤 花 方 俞 任 袁 柳 酆 鲍 史 唐 费 廉 岑 薛 雷 贺 倪 汤 滕 殷 罗 毕 郝 邬 安 常 乐 于 时 傅 皮 卞 齐 康 伍 余 元 卜 顾 孟 平 黄 和 穆 萧 尹 姚 邵 湛 汪 祁 毛 禹 狄 米 贝 明 臧 计 伏 成 戴 谈 宋 茅 庞 熊 纪 舒 屈 项 祝 董 梁 杜 阮 蓝 闽 席 季 麻 强 贾 路 娄 危 江 童 颜 郭 梅 盛 林 刁 锺 徐 丘 骆 高 夏 蔡 田 樊 胡 凌 霍 虞 万 支 柯 昝 管 卢 莫 经 房 裘 缪 干 解 应 宗 丁 宣 贲 邓 郁 单 杭 洪 包 诸 左 石 崔 吉 钮 龚 程 嵇 邢 滑 裴 陆 荣 翁 荀 羊 於 惠 甄 麹 家 封 芮 羿 储 靳 汲 邴 糜 松 井 段 富 巫 乌 焦 巴 弓 牧 隗 山 谷 车 侯 宓 蓬 全 郗 班 仰 秋 仲 伊 宫 宁 仇 栾 暴 甘 斜 厉 戎 祖 武 符 刘 景 詹 束 龙 叶 幸 司 韶 郜 黎 蓟 薄 印 宿 白 怀 蒲 邰 从 鄂 索 咸 籍 赖 卓 蔺 屠 蒙 池 乔 阴 郁 胥 能 苍 双 闻 莘 党 翟 谭 贡 劳 逄 姬 申 扶 堵 冉 宰 郦 雍 郤 璩 桑 桂 濮 牛 寿 通 边 扈 燕 冀 郏 浦 尚 农 温 别 庄 晏 柴 瞿 阎 充 慕 连 茹 习 宦 艾 鱼 容 向 古 易 慎 戈 廖 庾 终 暨 居 衡 步 都 耿 满 弘 匡 国 文 寇 广 禄 阙 东 欧 殳 沃 利 蔚 越 夔 隆 师 巩 厍 聂 晁 勾 敖 融 冷 訾 辛 阚 那 简 饶 空 曾 毋 沙 乜 养 鞠 须 丰 巢 关 蒯 相 查 后 荆 红 游 竺 权 逑 盖 益 桓 公 万俟 司马 上官 欧阳 夏侯 诸葛 闻人 东方 赫连 皇甫 尉迟 公羊 澹台 公冶 宗政 濮阳 淳于 单于 太叔 申屠 公孙 仲孙 轩辕 令狐 锺离 宇文 长孙 慕容 鲜于 闾丘 司徒 司空 丌官 司寇 仉 督 子车 颛孙 端木 巫马 公西 漆雕 乐正 壤驷 公良 拓拔 夹谷 宰父 谷梁 晋 楚 阎 法 汝 鄢 涂 钦 段干 百里 东郭 南门 呼延 归 海 羊舌 微生 岳 帅 缑 亢 况 后 有 琴 梁丘 左丘 东门 西门 商 牟 佘 佴 伯 赏 南宫 墨 哈 谯 笪 年 爱 阳 佟 第五 言 福 "}; char key[21][3]={"！","。","？","《","》","，","｛","｝","（","）","￥","‘","’","：","；","—","”","“","、","·","~"};  int main(){ 	char XM[N+1]; 	int F;  	while(1){ 	  do{ 		printf("输入姓名:"); 		Getchar(XM,4,N); 	   }while(check(XM));        F=ISxing(XM,2)+ISxing(XM,4);        if(!F)           printf("姓氏有误！请重新");        else printf("姓名:%s\n",XM);    } 	return 0; } int ISxing(char A[],int B)//如果姓氏查到返回 1  { 	char X=A[B],F=0; 	A[B]=0; 	if(BF(name,A)) 	   F=1; 	A[B]=X; 	return F; } int check(char S[]) { 	int i=-1,j=0; 	while(S[++i]) 	  if(S[i]>0) 	     return printf("输入的不是中文字符！请重新");      while(j<21)         if(BF(S,key[j++]))            return printf("输入的不是汉字！请重新");     return 0;  } int Getchar(char *A,int min,int max)//长度在[min,max]  <闭区间>  之间时 函数结束 返回字符串A的长度           {               int B,C;          do{                   A[max]=B=C=0;               while((A[B++]=getchar())!='\n'&&B<max);               if(A[B-1]!='\n')while(getchar()!='\n'&&++C);                   else A[--B]=0;            if(C||B&&B<min)              printf("您录入的字符串长度:%d字节\n只录入(%d--%d)个字节!\n",B+C,min,max);               }while(C||B<min);               return B;         }   int BF(char a[],char b[])//检查B在A里是否完整  {//匹配 a中b单词完整的个数      int i=0,j=0,k=0;       do{           if (b[j]&&(a[i++]==b[j]))++j;//若a[i]与b[j]相等或是大小写关系 继续比较           else{              if(!b[j])              {//如果b字符串到头了 此时需要检查 b在a字符串是否为完整的单词               if((i!=j)&&At(a[i-j-1])||(i==j))//i==j时 b在a字符串的串首  如果不在串首，则i!=j 此时应检查a[i-j-1]               if(!a[i]||a[i]&&At(a[i]))//如果b在a字符串的串尾 则a[i]==0  如果不在末尾 则检验 a[i]                 return 1;//存储当前匹配的单词位置              }              else i-=j;               j=0;           }       }while(a[i-1]);          return 0;   }

其实电脑开机后物理内存的每个字节中都有值且都是可读写的，从来不会因为所谓的new、delete或malloc、free而被创建、销毁。区别仅在于操作系统内存管理模块在你读写时是否能发现并是否采取相应动作而已。操作系统管理内存的粒度不是字节而是页，一页通常为4KB。

strlen是求字符串的长度，它是以遇到'\0'作为结束计数的，但是xing和ming数组没有初始化，所以这两个数组里存放的是随机值，你这儿得到的是1，其实得到几都是有可能的。这个要看计算这两个数组何时遇到'\0' 建议在计算两个数组长度之前，先对其初始化：  #include <stdio.h> #include <string.h>  int main(void) {     char xing[10] = {0};     char ming[20] = {0};     int a,b;     a = strlen(xing);     b = strlen(ming);      printf("请输入你的姓氏:\n");     scanf("%s",xing);     printf("请输入你的名字:\n");     scanf("%s",ming);      printf("%s %s\n",xing,ming);     printf("%-*d %-*d\n",strlen(xing),strlen(xing),strlen(ming),strlen(ming));     printf("%d %d\n",a,b);      return(0); }

数组内存没有初始化，可能就是随机值，而且，代码顺序有误

栈上的内存你没有初始化的话，里面有垃圾数据什么内容都可能，估计叫伪随机数据吧，strlen结果是多少也都有可能，看当时的内存环境，结果没有意义。


Question: 关于redis的dict模块内存分配的一些问题

顶起~~~~


Question: C语言新手求助，输出的数字非常大

这个很正常，因为在内存中，double类型和int类型数据存储方式是不一样的。存放double类型的数据，以整型形式输出，这个值要看double数据在内存的二进制形式，然后用int类型解析。  既然定义的是double类型，还是用%lf输出吧

输出语句错了，%d是输出整数，double应该用%lf输出

最后一行printf %d 换成%f或%e


Question: GetVersion返回的一串数字应该如何解读？

Platform SDK: Windows System Information  GetVersion The GetVersion function returns the current version number of the operating system.   Note  This function has been superseded by GetVersionEx. New applications should use GetVersionEx or VerifyVersionInfo.   DWORD GetVersion(VOID); Parameters This function has no parameters.   Return Values If the function succeeds, the return value is a DWORD value that contains the major and minor version numbers of the operating system in the low order word, and information about the operating system platform in the high order word.   For all platforms, the low order word contains the version number of the operating system. The low-order byte of this word specifies the major version number, in hexadecimal notation. The high-order byte specifies the minor version (revision) number, in hexadecimal notation.   To distinguish between operating system platforms, use the high order bit and the low order byte, as shown in the following table:  Platform High-order bit Next 7 bits Low-order byte  Windows NT 3.51 0 Build number 3  Windows NT 4.0 0 Build number 4  Windows 2000 or Windows XP 0 Build number 5  Windows 95, Windows 98, or Windows Me 1  Reserved 4  Win32s with Windows 3.1 1 Build number 3    Remarks The GetVersionEx function was developed because many existing applications err when examining the packed DWORD value returned by GetVersion, transposing the major and minor version numbers. GetVersionEx forces applications to explicitly examine each element of version information. VerifyVersionInfo eliminates further potential for error by comparing the required system version with the current system version for you.   The following code fragment illustrates how to extract information from the GetVersion return value:  dwVersion = GetVersion();   // Get the Windows version.  dwWindowsMajorVersion =  (DWORD)(LOBYTE(LOWORD(dwVersion))); dwWindowsMinorVersion =  (DWORD)(HIBYTE(LOWORD(dwVersion)));  // Get the build number.  if (dwVersion < 0x80000000)              // Windows NT/2000/XP     dwBuild = (DWORD)(HIWORD(dwVersion)); else if (dwWindowsMajorVersion < 4)      // Win32s     dwBuild = (DWORD)(HIWORD(dwVersion) & ~0x8000); else                                     // Windows 95/98/Me     dwBuild =  0; Requirements    Windows NT/2000/XP: Included in Windows NT 3.1 and later.   Windows 95/98/Me: Included in Windows 95 and later.   Header: Declared in Winbase.h; include Windows.h.   Library: Use Kernel32.lib.   Unicode: Implemented as Unicode and ANSI versions on Windows NT/2000/XP.  See Also System Information Overview, System Information Functions, GetVersionEx, VerifyVersionInfo   Platform SDK Release: August 2001  What did you think of this topic? Let us know.  Order a Platform SDK CD Online (U.S/Canada)   (International)      Requirements    Windows NT/2000/XP: Included in Windows NT 3.1 and later.   Windows 95/98/Me: Included in Windows 95 and later.   Header: Declared in Winbase.h; include Windows.h.   Library: Use Kernel32.lib.   Unicode: Implemented as Unicode and ANSI versions on Windows NT/2000/XP. See Also System Information Overview, System Information Functions, GetVersionEx, VerifyVersionInfo

他的返回值包含了主次版本等信息：  https://msdn.microsoft.com/en-us/library/windows/desktop/ms724439(v=vs.85).aspx  If the function succeeds, the return value includes the major and minor version numbers of the operating system in the low-order word, and information about the operating system platform in the high-order word.  可以参看上面的例子

分开高16字节和低16字节； 返回值的低字部分（低16位）是操作系统的主次版本号，高字部分（高16位）保存着操作系统平台的信息。


Question: 新人求助程序无法构建

推荐你用 vs2010

这个要怎么查看啊

代码没问题，应该是编译环境有问题。查一下你的编译器


Question: c小白  求帮帮忙

struct Student {     int age;     float score;     char name[100]; };    /*少一个分号*/  代码没问题，编译的时候会提示一个错误，就是结构体声明的时候少一个分号；  #include <stdio.h> #include <malloc.h>  struct Student {     int age;     float score;     char name[100]; };  int main (void) {      int len;     struct Student * pArr;     int i;       //动态的构造一维数组     printf ("请输入学生的个数:\n");     printf ("len = ");     scanf ("%d", &len);      pArr = (struct Student *)malloc(len * sizeof(struct Student));      for (i=0; i<len; ++i)     {         printf ("请输入第%d个学生的信息：",i+1);         printf ("age = ");         scanf ("%d", &pArr[i].age);         printf ("name = ");         scanf ("%s", pArr[i].name);         printf ("score = ");         scanf ("%f", &pArr[i].score);     }     //输出     for (i = 0; i<len; ++i)     {         printf ("第%d个学生的信息:\n",i+1);         printf ("age = %d\n ", pArr[i].age);         printf ("name = %s\n", pArr[i].name);         printf ("score = %f\n", pArr[i].score);         printf ("\n");     }      return 0; }

VS2015+Windows10 64位 把scanf()改为scanf_s() scanf_s("%d", &pArr[i].age); scanf_s("%s", pArr[i].name, 100); scanf_s("%f", &pArr[i].score); 以下是输出结果

谢谢帮助！！！


Question: Linux c画圆角矩形和填充圆角矩形的问题

应该是浮点数的误差造成的吧

如果代码没有问题 ，换一个电脑试试，之前画斜线的时候就遇到过，线不平滑，填充倒是没有遇到过； 而且有可能是你的填充空间不完全闭合，也可能有这种问题

引用 1 楼 zhao4zhong1 的回复:偶遇到类似问题都是用 “每次用/*...*/注释掉不同部分再重新编译，直到定位到具体出错的位置。” 的方法解决的。 填充时有漏点的问题，是什么原因导致的呢？


Question: 关于c语言图形界面程序中bmp图片的显示问题

引用 3 楼 zhao4zhong1 的回复:仅供参考：#pragma comment(lib,"user32") #pragma comment(lib,"gdi32") #include <stdlib.h> #include <conio.h> #include <windows.h> HWND WINAPI GetConsoleWindow(); void HideTheCursor() {     CONSOLE_CURSOR_INFO cciCursor;     HANDLE hStdOut = GetStdHandle(STD_OUTPUT_HANDLE);     if (GetConsoleCursorInfo(hStdOut, &cciCursor)) {         cciCursor.bVisible = FALSE;         SetConsoleCursorInfo(hStdOut, &cciCursor);     } } void ShowTheCursor() {     CONSOLE_CURSOR_INFO cciCursor;     HANDLE hStdOut = GetStdHandle(STD_OUTPUT_HANDLE);     if (GetConsoleCursorInfo(hStdOut, &cciCursor)) {         cciCursor.bVisible = TRUE;         SetConsoleCursorInfo(hStdOut, &cciCursor);     } } int main() {     HWND  hwnd;     HDC   hdc;     HFONT hfont;     HBITMAP hbm;     HDC hdcBits;     BITMAP bm;      system("color F0");     system("cls");     HideTheCursor();     hwnd  = GetConsoleWindow();     hdc   = GetDC(hwnd);     hbm=LoadImage(0,"C:\\Windows\\Soap Bubbles.bmp",IMAGE_BITMAP,0,0,LR_DEFAULTSIZE|LR_LOADFROMFILE);     if (hbm) {         hdcBits = CreateCompatibleDC(hdc);         GetObject (hbm, sizeof(BITMAP), &bm);         SelectObject(hdcBits,hbm);         BitBlt(hdc,200,10,bm.bmWidth, bm.bmHeight,hdcBits,0,0,SRCCOPY);         DeleteDC(hdcBits);         DeleteObject(hbm);     }     hfont = CreateFont(24, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "华文楷体");     SelectObject(hdc,hfont);     SetTextColor(hdc,RGB(255,255,255));     SetBkMode(hdc,TRANSPARENT);     TextOut(hdc,210,30,"这个背景是泡泡",14);     DeleteObject(hfont);     ReleaseDC(hwnd,hdc);     getch();     system("color 07");     system("cls");     ShowTheCursor();     return 0; }  这个问题我解决了，但是如果我要调用的是资源里引入的bmp图片的话又该怎么办呢？

引用 3 楼 zhao4zhong1 的回复:仅供参考：#pragma comment(lib,"user32") #pragma comment(lib,"gdi32") #include <stdlib.h> #include <conio.h> #include <windows.h> HWND WINAPI GetConsoleWindow(); void HideTheCursor() {     CONSOLE_CURSOR_INFO cciCursor;     HANDLE hStdOut = GetStdHandle(STD_OUTPUT_HANDLE);     if (GetConsoleCursorInfo(hStdOut, &cciCursor)) {         cciCursor.bVisible = FALSE;         SetConsoleCursorInfo(hStdOut, &cciCursor);     } } void ShowTheCursor() {     CONSOLE_CURSOR_INFO cciCursor;     HANDLE hStdOut = GetStdHandle(STD_OUTPUT_HANDLE);     if (GetConsoleCursorInfo(hStdOut, &cciCursor)) {         cciCursor.bVisible = TRUE;         SetConsoleCursorInfo(hStdOut, &cciCursor);     } } int main() {     HWND  hwnd;     HDC   hdc;     HFONT hfont;     HBITMAP hbm;     HDC hdcBits;     BITMAP bm;      system("color F0");     system("cls");     HideTheCursor();     hwnd  = GetConsoleWindow();     hdc   = GetDC(hwnd);     hbm=LoadImage(0,"C:\\Windows\\Soap Bubbles.bmp",IMAGE_BITMAP,0,0,LR_DEFAULTSIZE|LR_LOADFROMFILE);     if (hbm) {         hdcBits = CreateCompatibleDC(hdc);         GetObject (hbm, sizeof(BITMAP), &bm);         SelectObject(hdcBits,hbm);         BitBlt(hdc,200,10,bm.bmWidth, bm.bmHeight,hdcBits,0,0,SRCCOPY);         DeleteDC(hdcBits);         DeleteObject(hbm);     }     hfont = CreateFont(24, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "华文楷体");     SelectObject(hdc,hfont);     SetTextColor(hdc,RGB(255,255,255));     SetBkMode(hdc,TRANSPARENT);     TextOut(hdc,210,30,"这个背景是泡泡",14);     DeleteObject(hfont);     ReleaseDC(hwnd,hdc);     getch();     system("color 07");     system("cls");     ShowTheCursor();     return 0; }  老师还在么？

百度搜相关关键字。

引用 1 楼 tk2003 的回复:"打开程序后程序就直接一直未响应状态了" ---主程序卡住，陷入死循环了  这方面代码荒芜依旧，只能提这么点建议了 额，我的意思是我这个程序运行到bmp图形那一块才出现的问题，其余部分正常，因为我是刚加进去的这部分代码，加进去之前程序是能正常运作的

引用 4 楼 hzy_76 的回复:不懂，仅凭猜测，你调用了BeginPaint，却没有EndPaint，这是要出事的。 额，EndPaint在下面，我没写出来

引用 3 楼 zhao4zhong1 的回复:仅供参考：#pragma comment(lib,"user32") #pragma comment(lib,"gdi32") #include <stdlib.h> #include <conio.h> #include <windows.h> HWND WINAPI GetConsoleWindow(); void HideTheCursor() {     CONSOLE_CURSOR_INFO cciCursor;     HANDLE hStdOut = GetStdHandle(STD_OUTPUT_HANDLE);     if (GetConsoleCursorInfo(hStdOut, &cciCursor)) {         cciCursor.bVisible = FALSE;         SetConsoleCursorInfo(hStdOut, &cciCursor);     } } void ShowTheCursor() {     CONSOLE_CURSOR_INFO cciCursor;     HANDLE hStdOut = GetStdHandle(STD_OUTPUT_HANDLE);     if (GetConsoleCursorInfo(hStdOut, &cciCursor)) {         cciCursor.bVisible = TRUE;         SetConsoleCursorInfo(hStdOut, &cciCursor);     } } int main() {     HWND  hwnd;     HDC   hdc;     HFONT hfont;     HBITMAP hbm;     HDC hdcBits;     BITMAP bm;      system("color F0");     system("cls");     HideTheCursor();     hwnd  = GetConsoleWindow();     hdc   = GetDC(hwnd);     hbm=LoadImage(0,"C:\\Windows\\Soap Bubbles.bmp",IMAGE_BITMAP,0,0,LR_DEFAULTSIZE|LR_LOADFROMFILE);     if (hbm) {         hdcBits = CreateCompatibleDC(hdc);         GetObject (hbm, sizeof(BITMAP), &bm);         SelectObject(hdcBits,hbm);         BitBlt(hdc,200,10,bm.bmWidth, bm.bmHeight,hdcBits,0,0,SRCCOPY);         DeleteDC(hdcBits);         DeleteObject(hbm);     }     hfont = CreateFont(24, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "华文楷体");     SelectObject(hdc,hfont);     SetTextColor(hdc,RGB(255,255,255));     SetBkMode(hdc,TRANSPARENT);     TextOut(hdc,210,30,"这个背景是泡泡",14);     DeleteObject(hfont);     ReleaseDC(hwnd,hdc);     getch();     system("color 07");     system("cls");     ShowTheCursor();     return 0; }  这个报错呀，error C2440: '=' : cannot convert from 'void *' to 'struct HBITMAP__ *'


Question: c小白，在线等！！！！！

可以使用sleep()函数，通过设置该函数的参数来控制输出时间间隔。sleep()函数的参数是间隔的时间，需要注意的是该参数的单位是毫秒，即sleep(500)相当于等待半秒钟。

sleep函数中的参数是秒，所以你500就会等很久，你是不是一开始想用usleep，它的参数是微秒

你不是动用sleep函数了吗？你也可以采用时间函数进行控制

时间间隔? 延时? sleep不可以么?


Question: if else语句，为什么就一直进不去else呢

sizeof(数组)  给出的是数组所占的字节数    循环判断条件改成sizeof(headsize) / sizeof(int) .

#include<stdio.h> #include<stdbool.h> int main(void) { char size[3][13] = { { '6','6','6','6','7','7','7','7','7','7','7','7' }, { '1','5','3','7',' ','1','1','3','1','5','3','7' }, { '2','8','4','8',' ','8','4','8','2','8','4','8' } }; int headsize[12] = {164,166,169,172,175,178,181,184,188,191,194,197}; float cranium = 0.0; int your_head = 0; bool hat_found = false; printf("请输入头的尺寸:"); scanf("%f", &cranium); your_head = (int)(8 * cranium); size_t i = 0; if (your_head == headsize[i]) hat_found = true; else { for (i = 1; i <12; i++) { if (your_head > headsize[i - 1] && your_head <= headsize[i]) { hat_found = true; break; } }  } if (hat_found) printf("your_head=%d,帽子尺寸是%c %c%c%c\n", your_head, size[0][i], size[1][i], (size[1][i] == ' ') ? ' ' : '/', size[2][i]); else { if (your_head < 164) printf("你输入的尺寸太小，没有适合你的帽子！\n"); else printf("你输入的尺寸太大，没有适合你的帽子！\n");  } return 0;  } 有问题吗?

首先 size[3][12]中的12改成13


Question: c语言中，系统申请的内存空间不自动释放会出问题吗？

其实电脑开机后物理内存的每个字节中都有值且都是可读写的，从来不会因为所谓的new、delete或malloc、free而被创建、销毁。区别仅在于操作系统内存管理模块在你读写时是否能发现并是否采取相应动作而已。操作系统管理内存的粒度不是字节而是页，一页通常为4KB。  栈中的变量通常包括函数参数和函数里声明的临时变量。 栈中的基本变量退出其作用域时，没有谁执行一段代码去释放/销毁/析构它所占用的内存，仅仅是没人再去理会的留在当前栈顶上方的若干遗留下来可被后续压栈操作覆盖的无用数据而已。 而栈中的类变量退出其作用域时，会自动执行其析构函数，……

2楼说的对，释放和清空是两种概念。 函数返回时，i的内容并没有改变，即i所指的地址没变。 传回去之后 pointer_i所指的地址与原i所指的地址没变。 因为本程序很简单，所以 pointer_i所指地址内的内容应该也没有改变。不过编译系统 会不会重新布置内存空间就不一定了。如果程序复杂 一点就不好说了。反正这是一个明显的“野指针”，这片内存区已经不属于你可控的了，编译器很可能下一次把这片内存区覆盖掉，自己编程是要杜绝此类情况的发生。

这些是常量字符串是存在常量区，不在堆上，不需要清除，生成的EXE文件中本身就包含了这些常量，程序运行后将会加载到内存，整个程序运行过程中都会存在

内存释放和清空不是同一个概念，实际上释放并不需要清空，只需要把这一块内存挂到空闲内存块链表中，就完成释放了，但这块内存中的值并没有变化，直到重新被分配并赋值。  如果你在函数结束时把一个局部变量的地址返回，很可能可以得到一个正确的结果，但也不一定，如果这块内存被其他函数使用了，它的值就会变化。我们让函数返回一个值，一般都是在调用处马上把返回值赋给另一个变量，语句执行完对该局部变量的引用也结束了，我们再引用该返回值，实际上是调用处的那块内存，所以是没有问题的。

"abc"和"efg"都是只读数据，在只读数据区存放。指针变量c是一个变量，它存放的是这两个字符串中一个的地址（同一时间只能存放一个字符串的地址）。这两个字符串在只读数据段的不同位置，所以当变量c指向"efg"时，并不是"efg"覆盖了"abc"，所以c存放的地址值也是不一样的。

其实不是这样的，字符串和其他常数都是代码段，连全局变量都不是，没有开辟过内存，是直接跟着代码按照导入规则从文件复制过去的，所有常数都这样。。 给你举个例子，甚至会出现类似的代码 0001  ADD XXX,XXX 0003  J  0004 0002  abc 0004 MOV  R1,002H a这就是常数，他的地址就在代码里了，这东西本身就是程序代码，程序代码有没有内存，当然有，但是你从来没申请过他，在你导入进程时就存在。


Question: C++文件中用了fopen，fwrite，fclose但是程序运行完以后文件内容仍未改变

引用 4 楼 cfjtaishan 的回复:因为rb是只读二进制形式打开文件，所以不能写成功；建议使用rb+形式打开文件，这样文件就可以读也可以写了。确实应该以rb+打开，不过还有一个莫名其妙的毛病就是，文件内部的指针会莫名奇妙跑偏，ftell获取到的位置明明是对的，可是读和写的时候就不知道指到哪里去了，后来发现用ftell的返回值，fseek(fp, ftell(fp), SEEK_CUR)一下，再读或写就是对的了，这又是什么毛病

你是以二进制的方式写入的,  所以人无法识别其中的内容, 如果人要查看其中的内容, 请不要使用二进制方式打开文件

我也顶4楼，

引用 4 楼 cfjtaishan 的回复:因为rb是只读二进制形式打开文件，所以不能写成功；建议使用rb+形式打开文件，这样文件就可以读也可以写了。顶一个

顶楼上

打开的时候模式对不？

引用 1 楼 ckc 的回复:搞错了文件名不大可能吧，文件名错了连文件都打不开，我这里文件是打开成功的，也能在调试的时候从文件指针那里看到里面内容的改变，就是程序运行完后再打开文件看内容没有变

搞错了文件名

骗个分 r 打开只读文件，该文件必须存在。  r+ 打开可读写的文件，该文件必须存在。  w 打开只写文件，若文件存在则文件长度清为0，即该文件内容会消失。若文件不存在则建立该文件。  w+ 打开可读写文件，若文件存在则文件长度清为零，即该文件内容会消失。若文件不存在则建立该文件。  a 以附加的方式打开只写文件。若文件不存在，则会建立该文件，如果文件存在，写入的数据会被加到文件尾，即文件原先的内容会被保留。  a+ 以附加方式打开可读写的文件。若文件不存在，则会建立该文件，如果文件存在，写入的数据会被加到文件尾后，即文件原先的内容会被保留。  上述的形态字符串都可以再加一个b字符，如rb、w+b或ab＋等组合，加入b 字符用来告诉函数库打开的文件为二进制文件，而非纯文字文件。 所以楼主应该以r+b模式打开文件。


Question: 请问我这个密码输入3次错误有什么问题，为什么一调试就停止工作

引用 3 楼 zhun12078 的回复:好的，我把scanf改成gets就可以了，谢谢了 使用gets不安全，建议使用fgets，同时注意检查'\n'输入到缓存里。

好的，我把scanf改成gets就可以了，谢谢了

引用 楼主 zhun12078 的回复:#include<stdio.h> #include<string.h> int main() { 	char mima[10] = "zyqzyq"; 	char input[10] = {0}; 	int i = 0; 	printf("欢迎使用本系统，请输入密码："); 	for (i = 0;i < 3;i++) 	{ 		scanf_s("%s", input); 		if (strcmp(mima, input) == 0) 		{ 			break; 		} 		else 		{ 			printf("密码错误，请重新输入!"); 		} 	} 	if (i == 3) 		printf("退出系统\n"); 	else 		printf("登陆成功\n"); 	return 0; }scanf_s用法有问题，看看msdn吧 Unlike scanf and wscanf, scanf_s and wscanf_s require the buffer size to be specified for all input parameters of type c, C, s, S, or string control sets that are enclosed in []. The buffer size in characters is passed as an additional parameter immediately following the pointer to the buffer or variable. For example, if you are reading a string, the buffer size for that string is passed as follows:  char s[10];  scanf_s("%9s", s, _countof(s)); // buffer size is 10, width specification is 9  The buffer size includes the terminating null. You can use a width specification field to ensure that the token that's read in will fit into the buffer. If no width specification field is used, and the token read in is too big to fit in the buffer, nothing is written to that buffer.

scanf_s 换成std::cin


Question: 关于c语言图形界面的光条式菜单问题

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

引用 11 楼 zhao4zhong1 的回复:自动关闭也是崩溃的一种。 好了，问题我自己解决了，case WM_COMMAND:{...}后面我忘记加break;了，导致程序执行完按键的命令胡自动执行了后面的case WM_DESTROY:\         PostQuitMessage(0);         return 0;

自动关闭也是崩溃的一种。

用游戏引擎应该比较简单。

单纯用C，应该也可以，就是略麻烦。 具体请百度搜“用API显示PNG 透明”

引用 1 楼 zhao4zhong1 的回复:使用GDIplus 单纯用c，能够做到么？ 课程设计想试着弄进去，如果实在不行的话要怎么样才能制作出图中那种列状菜单呢？

使用GDIplus

引用 9 楼 zhao4zhong1 的回复:崩溃的时候在弹出的对话框按相应按钮进入调试，按Alt+7键查看Call Stack即“调用堆栈”里面从上到下列出的对应从里层到外层的函数调用历史。双击某一行可将光标定位到此次调用的源代码或汇编指令处，看不懂时双击下一行，直到能看懂为止。 我刚才仔细调试了一下，发现问题没出在菜单那里，而似乎是信息的回调问题，不知道为什么处理完菜单的选项之后程序就直接自动关闭了，实在是没弄明白，帮忙看看好么，谢了！ #include <windows.h> #include <stdlib.h> #include "resource.h" #include "resrc1.h" #include <stdio.h> HDC hDC; HFONT hfont,ohfont; PAINTSTRUCT paint; RECT rect; COLORREF oc; HMENU	hMenuShort;  int PopupShortcutMenu(HWND hWnd) { 	POINT point; 	GetCursorPos(&point); 	 	TrackPopupMenu(GetSubMenu(hMenuShort,0),TPM_CENTERALIGN,point.x,point.y,0,(HWND)hWnd,NULL ); 	return 1; }   LRESULT WINAPI WinProc(HWND hWnd,UINT Msg,WPARAM wParam,LPARAM lParam) {     	switch(Msg)     { 	case WM_RBUTTONUP: 	    PopupShortcutMenu(hWnd); 		break;     case WM_PAINT:         BeginPaint(hWnd, &paint);         hDC = paint.hdc; // the device context to draw in         GetClientRect(hWnd, &rect); // 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,rect.left+rect.right/2-600, rect.top+rect.bottom/2-100,"最短画图程序",12);         SelectObject(hDC,ohfont);         SetTextColor(hDC,oc);         DeleteObject(hfont);         EndPaint(hWnd, &paint);         break; 	case WM_COMMAND: 		switch(0x0000ffff&wParam) 		{case 40001: 			MessageBox(NULL,"4001","WinMain",MB_OK); 			break; 		case 40002: 			MessageBox(NULL,"4002","WinMain",MB_OK); 			break; 		case 40003:                         MessageBox(NULL,"4003","WinMain",MB_OK);                         break; 		}     case WM_DESTROY:\         PostQuitMessage(0);         return 0; 	}		     return DefWindowProc(hWnd,Msg,wParam,lParam); }   int WINAPI WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,LPSTR lpCmdLine,int nShowCmd) {     char *cName = "myWindow";     WNDCLASSEX wc;     HWND hWnd;     MSG Msg;     wc.cbClsExtra = 0;     wc.cbWndExtra = 0;     wc.cbSize = sizeof(WNDCLASSEX);     wc.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);     wc.hCursor = LoadCursor(hInstance,MAKEINTRESOURCE(IDC_1));     wc.hIcon = LoadIcon(hInstance,MAKEINTRESOURCE(IDI_ICON1));     wc.hIconSm = NULL;     wc.hInstance = hInstance;     wc.lpfnWndProc = WinProc;     wc.lpszClassName =(LPSTR)cName;     wc.lpszMenuName = NULL;//     wc.style = CS_HREDRAW | CS_VREDRAW;       RegisterClassEx(&wc);//     hMenuShort = LoadMenu(hInstance,MAKEINTRESOURCE(IDM_SHORTCUT));     hWnd = CreateWindowEx(WS_EX_CLIENTEDGE,cName,"贪吃蛇",WS_POPUP|WS_VISIBLE,         0,0,GetSystemMetrics(SM_CXSCREEN),GetSystemMetrics(SM_CYSCREEN),NULL,NULL,hInstance,NULL);     if(hWnd == NULL)     {//容错处理         MessageBox(NULL,"There's an Error","Error Title",MB_ICONEXCLAMATION|MB_OK);         return 0;     }     ShowWindow(hWnd,nShowCmd);//显示窗口     UpdateWindow(hWnd);        while(GetMessage(&Msg,NULL,0,0))     {         TranslateMessage(&Msg);//翻译消息         DispatchMessage(&Msg);//分派消息     }     return Msg.message; }

引用 7 楼 zhao4zhong1 的回复:  就是用PhotoShop做好楼主提供的图和这两张图，交替显示。 哦哦，谢谢，不知道最后能不能帮我看看我这程序是什么情况，不知为什么一点弹出菜单的子项目就直接闪退（选项的功能是谁便写的）  #include <windows.h> #include <stdlib.h> #include "resource.h" HDC hDC; HFONT hfont,ohfont; PAINTSTRUCT paint; RECT rect;//RECT用来存储窗口信息的结构，只要是窗口的坐标、宽度和高度。 COLORREF oc; HMENU	hMenuShort;//同上 //定义弹出快捷菜单函数 int PopupShortcutMenu(HWND hWnd) { 	POINT point; 	GetCursorPos(&point);//获取鼠标的位置 	//弹出菜单 	TrackPopupMenu(GetSubMenu(hMenuShort,0),TPM_CENTERALIGN,point.x,point.y,0,(HWND)hWnd,NULL ); 	return 1; }  //回调函数 LRESULT WINAPI WinProc(HWND hWnd,UINT Msg,WPARAM wParam,LPARAM lParam) {     	switch(Msg)//处理消息过程，什么是消息，下节再讲     {     case WM_LBUTTONUP://鼠标左键松开时 		              //清除文字，出现菜单 		break; 	case WM_RBUTTONUP://鼠标右键松开时 	    PopupShortcutMenu(hWnd); 		break;     case WM_PAINT:         BeginPaint(hWnd, &paint);         hDC = paint.hdc; // the device context to draw in         GetClientRect(hWnd, &rect); // 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,rect.left+rect.right/2-600, rect.top+rect.bottom/2-100,"最短画图程序",12);         SelectObject(hDC,ohfont);         SetTextColor(hDC,oc);         DeleteObject(hfont);         EndPaint(hWnd, &paint);         break; 	case WM_COMMAND: 		switch(0x0000ffff&wParam) 		{case IDR_HELP: 			//添加新菜单项 			AppendMenu(GetSubMenu(hMenuShort,0),MF_CHECKED,0X4403,"新添加的菜单项"); 			break; 		case IDR_RANK: 			//删除菜单项 			DeleteMenu(GetSubMenu(hMenuShort,0),0x4403,MF_BYCOMMAND); 			break; 		case IDR_EXIT: 			exit(1); 		}     case WM_DESTROY://响应鼠标单击关闭按钮事件         PostQuitMessage(0);//退出消息队列，至于什么是消息队列，下节说         return 0;//退出函数 	}		     return DefWindowProc(hWnd,Msg,wParam,lParam); }  //主函数 int WINAPI WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,LPSTR lpCmdLine,int nShowCmd) {     char *cName = "myWindow";     WNDCLASSEX wc;     HWND hWnd;     MSG Msg;     wc.cbClsExtra = 0;     wc.cbWndExtra = 0;     wc.cbSize = sizeof(WNDCLASSEX);     wc.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);//通过函数来设置一个白色的背景     wc.hCursor = LoadCursor(hInstance,MAKEINTRESOURCE(IDC_1));//载入光标资源     wc.hIcon = LoadIcon(hInstance,MAKEINTRESOURCE(IDI_ICON1));     wc.hIconSm = NULL;//不设置     wc.hInstance = hInstance;//当前程序的句柄，hInstance是有系统给传递的     wc.lpfnWndProc = WinProc;//窗口处理过程的回调函数。     wc.lpszClassName =(LPSTR)cName;//窗口类的名字。     wc.lpszMenuName = NULL;//目录名，不设置     wc.style = CS_HREDRAW | CS_VREDRAW;       RegisterClassEx(&wc);//在系统中注册     hMenuShort = LoadMenu(hInstance,MAKEINTRESOURCE(IDM_SHORTCUT));     hWnd = CreateWindowEx(WS_EX_CLIENTEDGE,cName,"贪吃蛇",WS_POPUP|WS_VISIBLE,         0,0,GetSystemMetrics(SM_CXSCREEN),GetSystemMetrics(SM_CYSCREEN),NULL,NULL,hInstance,NULL);//创建窗口，窗口标题为"我的窗口我喜欢"     if(hWnd == NULL)     {//容错处理         MessageBox(NULL,"There's an Error","Error Title",MB_ICONEXCLAMATION|MB_OK);         return 0;     }     ShowWindow(hWnd,nShowCmd);//显示窗口     UpdateWindow(hWnd);      //下面是对消息的循环处理，大家先不必管这些，下节课我会细说的 	while(GetMessage(&Msg,NULL,0,0))     {         TranslateMessage(&Msg);//翻译消息         DispatchMessage(&Msg);//分派消息     }     return Msg.message; }

就是用PhotoShop做好楼主提供的图和这两张图，交替显示。

引用 4 楼 zhao4zhong1 的回复:或者事先用比如PhotoShop做好要显示的多张位图，编程用GDI显示对应位图即可。 这个要怎样做呢？我刚才搜了一会儿看到很多人推荐用GdipDrawImageRect(I)，这个函数是什么情况呀？大神能不能给我弄个实例呀？搜了好一会儿也没找到


Question: c小白，求大神指教，在线等！！！

或 只需要满足一个条件 与 需要满足所有条件

为什么不是”或“

if(i!='m' && i!='M' && i!='F' &&　i!='f')


Question: 大佬们，帮我看看这个程序为什么会出现段错误

引用 2 楼 user-1 的回复:pfile = (FILE*)filename; if (!fopen(pfile, "w"))  改成：  pfile = fopen(filename, "w") if (!pfile) 不好意思，点错了。 我明白了，谢谢


Question: 请对我写的这两个gainint和Getchar函数提出建设性的改进意见 谢谢

可以用动态数组 程序限制有点多 必须先小后大 可以直接输入两个数字判断 变量l可以删掉 主程序一直循环 给个跳出条件比较好 楼上讲到的 intint 和下面的returnreturn 以上是一些不成熟的意见 最后说一句 看了楼主的博客感觉楼主算法搞的不错哟

就是对输入的检验 这个intint charchar我也不清楚是怎么回事 但是在我原来的代码里是int 和 char

我是让你们看函数 不是看我的主函数 不要偏离主题

我的这个输入字母也没问题啊。。。

这样实现还不够完善，起码缺少对scanf的返回值判断和校验。你不能保证每个使用你的程序的人都按照你的想法或者要求去输入数据。比如你要输入int类型，但是若输入字母怎么办？所以为了严谨起见，建议加上返回值的判断。

其实我没看懂你是想做啥

int gainint(intint *p,int a,int b);


Question: 求教求教！！请问我自己用C设置的SVGA 0X105模式 可不知道颜色对应的数字

一图胜过千言！ 自赞一下！

谢谢谢谢啦

SVGA256色模式，所使用的是索引颜色表（即一个数字对应一种颜色），值是从0x00到0xFF，你可以写一个绘制矩形的函数，然后设置不同的颜色，绘制出256不同颜色的矩形(小的矩形，同屏幕上一起显示即可)，之后根据颜色，再给每个整数取一个颜色名称，以方便使用。


纯粹的宏操作是不行的了，得自己写函数，然后用宏封装函数。

引用 21 楼 ForestDB 的回复: $ cat main.c  int main() {     puts(__FUNCTION__);     puts(__func__);     puts(__FILE__); }  $ cpp main.c  # 1 "main.c" # 1 "<built-in>" # 1 "<command-line>" # 1 "/usr/include/stdc-predef.h" 1 3 4 # 1 "<command-line>" 2 # 1 "main.c" int main() {     puts(__FUNCTION__);     puts(__func__);     puts("main.c"); }  $ gcc -S main.c  main.c: In function ‘main’: main.c:3:5: warning: implicit declaration of function ‘puts’ [-Wimplicit-function-declaration]      puts(__FUNCTION__);      ^ $ cat main.s 	.file	"main.c" 	.section	.rodata .LC0: 	.string	"main.c" 	.text 	.globl	main 	.type	main, @function main: .LFB0: 	.cfi_startproc 	pushq	%rbp 	.cfi_def_cfa_offset 16 	.cfi_offset 6, -16 	movq	%rsp, %rbp 	.cfi_def_cfa_register 6 	movl	$__FUNCTION__.1832, %edi 	call	puts 	movl	$__func__.1833, %edi 	call	puts 	movl	$.LC0, %edi 	call	puts 	movl	$0, %eax 	popq	%rbp 	.cfi_def_cfa 7, 8 	ret 	.cfi_endproc .LFE0: 	.size	main, .-main 	.section	.rodata 	.type	__FUNCTION__.1832, @object 	.size	__FUNCTION__.1832, 5 __FUNCTION__.1832: 	.string	"main" 	.type	__func__.1833, @object 	.size	__func__.1833, 5 __func__.1833: 	.string	"main" 	.ident	"GCC: (Ubuntu 5.4.0-6ubuntu1~16.04.4) 5.4.0 20160609" 	.section	.note.GNU-stack,"",@progbits  看到了么？准确的说__FILE__和__LINE__才是预定义宏，且是标准定义的；而__FUNCTION__和__func__是编译器预定义符号，是个变量，且从某种意义上来说并不是标准（__func__已经是C99的标准了）。  详见 https://gcc.gnu.org/onlinedocs/gcc-7.2.0/cpp/Standard-Predefined-Macros.html#Standard-Predefined-Macros https://gcc.gnu.org/onlinedocs/gcc-7.2.0/gcc/Function-Names.html#Function-Names  These identifiers are variables, not preprocessor macros, and may not be used to initialize char arrays or be concatenated with string literals. 非常感谢你的的回答。那是不是说，不能将__FUNCTION__当成宏的参数传到那个宏con中去？看了你的回答，我估计确实不行。那我只能换个思路修改那个宏的写法了。

引用 22 楼 paschen 的回复:#define con(x,y） x#y 右括号你用成中文的了，改成英文的则没问题了 这是个笔误，改了以后还是不行。

引用 25 楼 ForestDB 的回复:纯粹的宏操作是不行的了，得自己写函数，然后用宏封装函数。 谢谢回答，我已经修改了。揭帖给分

建议楼主深入理解编译的若干步骤 及 各步骤都干了些什么 以及 编译期和运行期的区别与联系。

代码生成技术是业界很成熟的技术。

引用 13 楼 zhao4zhong1 的回复:实在不行，楼主只能使用代码生成技术了。 代码生成技术参考下面： //codegen.c // 输入一组字符串，比如 // aa ss ddd dd 33 dd // 然后自动生成一个函数 int A(const char*); // 实现A("aa")返回0  A("ss")返回1 依次类推 #include <stdio.h> int main(int argc,char **argv) {     int i;     if (argc<2) {         printf("%s p1 [p2 ...] [>result.c]\nGenerate code int A(const char *a); 0==A(\"p1\") 1==A(\"p2\") ...",argv[0]);         return 1;     }     //printf("#include <string.h>\n");     printf("int A(const char *a) {\n");     for (i=0;i<argc-1;i++) {         printf("    if (0==strcmp(a,\"%s\")) return %d;\n",argv[i+1],i);     }     printf("    return -1;\n");     printf("}\n");     return 0; } //C:\test\Debug>codegen.exe //codegen.exe p1 [p2 ...] [>result.c] //Generate code int A(const char *a); 0==A("p1") 1==A("p2") ... //C:\test\Debug>codegen.exe aa ss ddd dd 33 dd //int A(const char *a) { //    if (0==strcmp(a,"aa")) return 0; //    if (0==strcmp(a,"ss")) return 1; //    if (0==strcmp(a,"ddd")) return 2; //    if (0==strcmp(a,"dd")) return 3; //    if (0==strcmp(a,"33")) return 4; //    if (0==strcmp(a,"dd")) return 5; //    return -1; //} // //c:\test\Debug>codegen.exe aa ss ddd dd 33 dd >result.c // //c:\test\Debug>type result.c //int A(const char *a) { //    if (0==strcmp(a,"aa")) return 0; //    if (0==strcmp(a,"ss")) return 1; //    if (0==strcmp(a,"ddd")) return 2; //    if (0==strcmp(a,"dd")) return 3; //    if (0==strcmp(a,"33")) return 4; //    if (0==strcmp(a,"dd")) return 5; //    return -1; //} //  谢谢回答！请问有简单的做法吗，因为是老代码 ，我不想改的太多。

引用 11 楼 cfjtaishan 的回复:楼主说的宏是不是__func__呢？ 我用__func__好像也不行。

楼主说的宏是不是__func__呢？

引用 19 楼 cutmelon 的回复:[quote=引用 楼主 maoaq 的回复:] 我写了一个宏 #define con(x,y） x#y  然后在main函数中写了下面的代码： char * ss = con(__FUNCTIION__,2);  用gcc编译出错。  但char * ss = con(“1”，“2”);是正确的。  请问这个宏应该怎么写才对？  我用gcc的-i选项编译，发现这个__FUNCTION__没有展开，所以编译错误，请问这个__FUNCTION__是在什么时候展开的？ 不知道你的代码文件里怎么写的，看上面红色部分，括号是全角，FUNCTION多了个I，这应该编译不过去吧 我怎么写是能跑的：#include <stdio.h>  #define con(x,y) x#y  void main() { 	char* ss=con(__FUNCTION__,2); 	printf(ss); } [/quote] 那个是笔误。 我的代码如下： #include <stdio.h>  #define con(x,y) x#y  int main(int argc, char** argv){	 	char * ss = con(__FUNCTION__,2); 	printf("ss = %s\n",ss); 	return 0; } 但是编译不过。你是用的什么编译器？我的是gcc4.4.7. 而且把__FUNCTION__换成__FILE__就可以，换成__func__也不对。

引用 楼主 maoaq 的回复:我写了一个宏 #define con(x,y） x#y  然后在main函数中写了下面的代码： char * ss = con(__FUNCTIION__,2);  用gcc编译出错。  但char * ss = con(“1”，“2”);是正确的。  请问这个宏应该怎么写才对？  我用gcc的-i选项编译，发现这个__FUNCTION__没有展开，所以编译错误，请问这个__FUNCTION__是在什么时候展开的？ 不知道你的代码文件里怎么写的，看上面红色部分，括号是全角，FUNCTION多了个I，这应该编译不过去吧 我怎么写是能跑的：#include <stdio.h>  #define con(x,y) x#y  void main() { 	char* ss=con(__FUNCTION__,2); 	printf(ss); }

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

引用 7 楼 maoaq 的回复:[quote=引用 5 楼 zhao4zhong1 的回复:] 仅供参考：#include <stdio.h> #define DEBUG2(x,y) "Line " #y " of File " x #define DEBUG1(x,y) DEBUG2(x,y) #define LINE_FILE DEBUG1( __FILE__ , __LINE__ )      const char *str = LINE_FILE; void main() {     printf("%s\n",str); } //Line 10 of File c:\tmp\tmp\foo.c  这个肯定知道，为什么放到我写的那个宏里就不对了呢？[/quote] 不好意思，看错了，我试试这个，谢谢！  引用 7 楼 maoaq 的回复:[quote=引用 5 楼 zhao4zhong1 的回复:] 仅供参考：#include <stdio.h> #define DEBUG2(x,y) "Line " #y " of File " x #define DEBUG1(x,y) DEBUG2(x,y) #define LINE_FILE DEBUG1( __FILE__ , __LINE__ )      const char *str = LINE_FILE; void main() {     printf("%s\n",str); } //Line 10 of File c:\tmp\tmp\foo.c  这个肯定知道，为什么放到我写的那个宏里就不对了呢？[/quote] 不好意思，看错了。我试验了你的代码，结果没有问题，但是我有以下的问题想请教一下： 1 为什么用 __FUNCTIION__修改你的代码，编译不过，与我遇到的现象一样？ 2 我现在必须要用__FUNCTIION__来作为参数调用宏，请问这样应该怎么写宏？我直接调用那个DEBUG1，编译不过。 非常感谢回答。

请再研究研究

引用 4 楼 wyyy2088511 的回复:http://blog.csdn.net/wyyy2088511/article/details/77162949   #是字符串，##是连接符 可是我的那个宏为什么不对呢？

引用 5 楼 zhao4zhong1 的回复:仅供参考：#include <stdio.h> #define DEBUG2(x,y) "Line " #y " of File " x #define DEBUG1(x,y) DEBUG2(x,y) #define LINE_FILE DEBUG1( __FILE__ , __LINE__ )      const char *str = LINE_FILE; void main() {     printf("%s\n",str); } //Line 10 of File c:\tmp\tmp\foo.c  这个肯定知道，为什么放到我写的那个宏里就不对了呢？


Question: 字体颜色一加就提示错误

支持VC++6.0，我一直都用它！

少了个头文件  #include <stdlib.h>

什么问题? 我的编译器一切正常vs 2008

#include <stdlib.h>

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

提示什么错误？

system 是在stdlib.h这个头文件里的，加上stdlib.h就好了。 #include <stdio.h> #include <malloc.h> #include<stdlib.h> int main() { system("color F5");  printf("nihao"); getchar(); return 0; }


Question: 怎么样在c语言界面程序中改变光标的图标呀？

没试过全屏化，用无边框窗体并设置最大化，是不是可行？

仅供参考：#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 (0==RegisterClass(&wc)) return 1;      if (NULL==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; }

引用 7 楼 hzy_76 的回复:我家里是新版本的，不知道是否一致，回家了有空帮你看看。 哈哈，我找到方法了，成功替换了，对了，不知道有没有办法让我用vc++写的界面化c程序全屏化呀？

我家里是新版本的，不知道是否一致，回家了有空帮你看看。

wc.hCursor = LoadCursor(hInstance,MAKEINTRESOURCE(CUR));把里面的CUR改成你想要的光标的ID不就好了嘛。系统里面自带的有IDC_CROSS, IDC_ARROW. IDC_WAIT等等。也可以LoadIcon图片来作为光标，具体的可以到网上搜相关呀。

引用 4 楼 hzy_76 的回复:你说的好复杂，还要学习如何分解编译步骤吗？这个还真没搞过，一般改完工程，菜单里点一下build就完成了。 其实我就是不明白那个教程那里最后是怎么把生成的res资源文件和obj文件连接生成exe执行程序的，没事，大神你就帮我看看怎么用VC++6.0改变光标的图标就好~~~

引用 1 楼 hzy_76 的回复:Visual C++还是古老的纯C？前者可以在工程中更改，后者应该是不太可行。 现在手上没有Visual C++，如果你需要具体方式，晚上回家可以帮你找一下。 这是教程里说的，我弄到连接obj和res那就弄不下去了，显示'linke' 不是内部或外部命令，也不是可运行的程序 或批处理文件。 今天我们只是修改鼠标的指针，所以用到的资源，只有鼠标的光标资源而已。资源的源文件是以rc为扩展名的脚本文件（仍然是C语言格式的，很简单），有资源编译器Rc.exe编译成以res为扩展名的二进制资源文件，最后用连接器，把res文件和obj文件连接到一起就成了我们的程序exe文件了，现在知道了程序编译后要连接了吧。光标的图片格式有两中cur和ani的。这个文件我在魔域的图片库里面找到了就复制到，当前项目目录下。下面来定义下资源文件myOwnCursor.rc //myOwnCursor.rc written by xhk 2009.3.1 #include	<resource.h>  //资源文件要用到的图文件 #define	CUR	0x1000		//定义资源的ID，为整型id CUR	CURSOR 	"myOwnCursor.ani"	//用到的光标图案 写完后，在命令提示符下进入目录，然后用rc.exe编译，输入rc myOwnCursor.rc命令，回车   我们查看下项目目录下多了个myOwnCursor.RES的文件，就是编译生成的二进制资源件。   接下来就该编写代码了，来应用这个资源文件，建立myOwnCursor.c文件，其实代码和上节所写代码很相似的，只是稍微加以修改而已。 #include <windows.h> #define CUR 0x1000	//预定义光标的id //回调函数 LRESULT WINAPI WinProc(HWND hWnd,UINT Msg,WPARAM wParam,LPARAM lParam) {     switch(Msg)//处理消息过程，什么是消息，下节再讲     {     case WM_DESTROY://响应鼠标单击关闭按钮事件         PostQuitMessage(0);//退出消息队列，至于什么是消息队列，下节说         return 0;//退出函数     }     return DefWindowProc(hWnd,Msg,wParam,lParam); }  //主函数 int WINAPI WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,LPSTR lpCmdLine,int nShowCmd) {     char *cName = "myWindow";     WNDCLASSEX wc;     HWND hWnd;     MSG Msg;      wc.cbClsExtra = 0;     wc.cbWndExtra = 0;     wc.cbSize = sizeof(WNDCLASSEX);     wc.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);//通过函数来设置一个白色的背景，这里大家设置为NULL看看，会很有趣的     wc.hCursor = LoadCursor(hInstance,MAKEINTRESOURCE(CUR));//这里改了，来载入光标资源     wc.hIcon = NULL;//不设置     wc.hIconSm = NULL;//不设置     wc.hInstance = hInstance;//当前程序的句柄，hInstance是有系统给传递的     wc.lpfnWndProc = WinProc;//窗口处理过程的回调函数。     wc.lpszClassName =(LPSTR)cName;//窗口类的名字。     wc.lpszMenuName = NULL;//目录名，不设置     wc.style = CS_HREDRAW | CS_VREDRAW;       RegisterClassEx(&wc);//在系统中注册      hWnd = CreateWindowEx(WS_EX_CLIENTEDGE,cName,"我的窗口我喜欢",WS_OVERLAPPEDWINDOW,         200,100,600,400,NULL,NULL,hInstance,NULL);//创建窗口，窗口标题为"我的窗口我喜欢"     if(hWnd == NULL)     {//容错处理         MessageBox(NULL,"There's an Error","Error Title",MB_ICONEXCLAMATION|MB_OK);         return 0;     }     ShowWindow(hWnd,nShowCmd);//显示窗口     UpdateWindow(hWnd);      //下面是对消息的循环处理，大家先不必管这些，下节课我会细说的 	while(GetMessage(&Msg,NULL,0,0))     {         TranslateMessage(&Msg);//翻译消息         DispatchMessage(&Msg);//分派消息     }     return Msg.message; } 用vc编译生成myOwnCursor.obj,把myOwnCursor.obj和myOwnCursor.res放到同一个文件夹下，然后在命令行下进入它们所在的目录 ，输入命令：linke kernel32.lib user32.lib gdi32.lib /subsystem:windows myOwnCursor.obj myOwnCursor.res把两个文件连接成myOwnCursor.exe.

引用 1 楼 hzy_76 的回复:Visual C++还是古老的纯C？前者可以在工程中更改，后者应该是不太可行。 现在手上没有Visual C++，如果你需要具体方式，晚上回家可以帮你找一下。 嗯嗯，是VC++6.0,谢谢啦，课程设计需要，网上查了愣是没弄懂，大神帮我看看吧~~~


Question: 随机生成多个数独的程序问题

引用 3 楼 user-1 的回复:把srand放在main开头啊哈哈，我刚才也是这么做的，成功了，过来一看确实是这样，谢谢拉

引用 2 楼 Love_Irelia97 的回复:[quote=引用 1 楼 user-1 的回复:] srand在哪里？  不能放在循环体内以及循环体内的函数内，因为代码执行速度很快，即便你是在循环体内执行srand(time(0))时间种子基本不会改变导致伪随机数是一样的。 void sudoku_algorithm(int a[10][10]) { 	srand((unsigned)time(NULL)); 	//sudoku_print(a); 			 	for (int row = 1; row <= 9; row++) 	{ 		int fail_times = 0;					//	寻找当前行的解的次数 		for (int col = 1; col <= 9; ) 		{ 			if(fail_times > 1000)			//	寻找次数超过1000次，重置本行和上一行的元素为0 			{ 				for (int i = 1; i <= 9; i++) 				{ 					a[row][i] = 0; 					a[row-1][i] = 0; 				} 				row -= 2;		//	因为循环开头会+1，故此处先-2 				break;			//	重新寻找上一行的解 			} 			 			bool flag = sudoku_test(a, row, col);	//	判断a[row][col]是否能填数 			if(!flag) 			{ 				col = 1; 				fail_times++; 				continue; 			} 								 			int  rand_num = rand() % 9 + 1;	//	随机数1 ~ 9  			bool flag1 = sudoku_row(a, row, col, rand_num);	//	判断行约束 			if (!flag1) 				continue;  			bool flag2 = sudoku_col(a, row, col, rand_num);	//	判断列约束 			if (!flag2) 				continue;  			bool flag3 = sudoku_mod(a, row, col, rand_num);	//	判断模块（宫）约束 			if (!flag3) 				continue;  			a[row][col++] = rand_num; 		} 		//	For Debug	//  		/* 		for (int i = 1; i <= 9; i++) 			printf("%d ", a[row][i]); 		printf("\n"); 		*/ 	} }  放在这里，那么有没有什么解决方法呢[/quote]  把srand放在main开头啊

引用 1 楼 user-1 的回复:srand在哪里？  不能放在循环体内以及循环体内的函数内，因为代码执行速度很快，即便你是在循环体内执行srand(time(0))时间种子基本不会改变导致伪随机数是一样的。 void sudoku_algorithm(int a[10][10]) { 	srand((unsigned)time(NULL)); 	//sudoku_print(a); 			 	for (int row = 1; row <= 9; row++) 	{ 		int fail_times = 0;					//	寻找当前行的解的次数 		for (int col = 1; col <= 9; ) 		{ 			if(fail_times > 1000)			//	寻找次数超过1000次，重置本行和上一行的元素为0 			{ 				for (int i = 1; i <= 9; i++) 				{ 					a[row][i] = 0; 					a[row-1][i] = 0; 				} 				row -= 2;		//	因为循环开头会+1，故此处先-2 				break;			//	重新寻找上一行的解 			} 			 			bool flag = sudoku_test(a, row, col);	//	判断a[row][col]是否能填数 			if(!flag) 			{ 				col = 1; 				fail_times++; 				continue; 			} 								 			int  rand_num = rand() % 9 + 1;	//	随机数1 ~ 9  			bool flag1 = sudoku_row(a, row, col, rand_num);	//	判断行约束 			if (!flag1) 				continue;  			bool flag2 = sudoku_col(a, row, col, rand_num);	//	判断列约束 			if (!flag2) 				continue;  			bool flag3 = sudoku_mod(a, row, col, rand_num);	//	判断模块（宫）约束 			if (!flag3) 				continue;  			a[row][col++] = rand_num; 		} 		//	For Debug	//  		/* 		for (int i = 1; i <= 9; i++) 			printf("%d ", a[row][i]); 		printf("\n"); 		*/ 	} }  放在这里，那么有没有什么解决方法呢


Question: 关于c语言的声音识别问题。

语音识别出来贪吃蛇早撞墙了（意思控制不灵敏），不现实。

额，我是说在贪吃蛇已经弄出来的情况下，重点是语音的识别问题

想法很完美，现实很骨感，可以先做的键盘控制贪吃蛇，然后通过识别语言，识别语言后转换成键盘，一步步来。

这个用C语言来实现，恐怕不好弄吧；想法很好，实现起来不是很简单。  做好一个贪吃蛇这是一个问题（大问题），语音识别这是一个大问题，语音输入，语音辨别，控制贪吃蛇的方向。 可以从这几块去查找资料，也可以继续细化一下模块。

对接百度语音识别吧。ai.baidu.com

"上右下左上右下左上右下左......"


Question: c语言负数输出问题

整数，浮点数在计算机中以补码形式存储，printf()函数是以原码输出吗？ 列： #include <stdio.h> void main() { 	short x; 	x=54278; 	printf("%d\n",x); } 输出为-11258

引用 6 楼 qq_30573461 的回复:[quote=引用 1 楼 kaijkl 的回复:] 参照http://blog.sina.com.cn/s/blog_8b745a5f01016uma.html没有用，看了一眼若要输出负数得用%hhd  引用 4 楼 cfjtaishan 的回复:输出的值是负值还是正值跟你的输出格式有关，想输出-7，但是输出的是一个大的正值，需要看一下你是以什么格式输出的问题解决了，但是出现一个新的问题，负数的浮点该怎么计算，例-7*1.000/1000，是-0.007还是别的数。[/quote] 浮点数跟精度有关系，理论值和实际计算机计算出来的值可能有差距，尤其是小数点第7位

引用 1 楼 kaijkl 的回复:参照http://blog.sina.com.cn/s/blog_8b745a5f01016uma.html没有用，看了一眼若要输出负数得用%hhd  引用 4 楼 cfjtaishan 的回复:输出的值是负值还是正值跟你的输出格式有关，想输出-7，但是输出的是一个大的正值，需要看一下你是以什么格式输出的问题解决了，但是出现一个新的问题，负数的浮点该怎么计算，例-7*1.000/1000，是-0.007还是别的数。

贴代码…………

keil没用过。在C语言中，输出不同格式的数字可以用printf函数实现。


Question: 调试在输入学号后中段，运行必须输入两个学号才能继续执行？

int gainint(int *p,int a,int b)//输入int *p直至满足(a,b)输入结束，并返回*p的位数           {                do{                   *p=a-1;    //此处是为了减少意外情况的发生 虽然那种意外情况不常见             scanf("%d",p);                   while(getchar()!='\n');                   if(*p>b||*p<a)                       printf("输入有误,请重新输入[%d--%d]:",a,b);               }while(*p>b||*p<a);               return *p;           }   int Getchar(char *A,int min,int max)//长度在[min,max]  <闭区间>  之间时 函数结束 返回字符串A的长度         {             int B,C;        do{                 A[max]=B=C=0;             while((A[B++]=getchar())!='\n'&&B<max);             if(A[B-1]!='\n')while(getchar()!='\n'&&++C);                 else A[--B]=0;          if(C||B&&B<min)            printf("您录入的字符串长度:%d字节\n只录入(%d--%d)个字节!\n",B+C,min,max);             }while(C||B<min);             return B;       }  给你两个函数 提高程序的健壮性

scanf("%s\n", p->num);  改成：  scanf("%s", p->num);  \n属于空白符，最后输入的那个非（空格、制表符、回车）的东西是不会被这个scanf读进来的，要等再接收到一个非（空格、制表符、回车）的输入scanf语句才结束

把scanf里的\n去掉


Question: 一个很懵的情况，关于system()函数

引用 6 楼 wwww200808008 的回复:[quote=引用 2 楼 lq951114 的回复:] [quote=引用 1 楼 wwww200808008 的回复:] 有可能是权限问题。你用管理者权限运行试试。 管理员运行也还是一样的情况[/quote]  帮你在我电脑试了一下，debug调试没有问题。自己点exe启动也没有问题。 int _tmain(int argc, _TCHAR* argv[]) { 	system("shutdown -s -t 1200"); 	exit(0); 	return 0; } [/quote]  刚刚在试着把程序名字改成shutdown.exe 发现不会自动退出。所以可能是你的程序名和系统的shutdown.exe冲突导致。

引用 2 楼 lq951114 的回复:[quote=引用 1 楼 wwww200808008 的回复:] 有可能是权限问题。你用管理者权限运行试试。 管理员运行也还是一样的情况[/quote]  帮你在我电脑试了一下，debug调试没有问题。自己点exe启动也没有问题。 int _tmain(int argc, _TCHAR* argv[]) { 	system("shutdown -s -t 1200"); 	exit(0); 	return 0; }

引用 7 楼 wwww200808008 的回复:[quote=引用 6 楼 wwww200808008 的回复:] [quote=引用 2 楼 lq951114 的回复:] [quote=引用 1 楼 wwww200808008 的回复:] 有可能是权限问题。你用管理者权限运行试试。 管理员运行也还是一样的情况[/quote]  帮你在我电脑试了一下，debug调试没有问题。自己点exe启动也没有问题。 int _tmain(int argc, _TCHAR* argv[]) { 	system("shutdown -s -t 1200"); 	exit(0); 	return 0; } [/quote]  刚刚在试着把程序名字改成shutdown.exe 发现不会自动退出。所以可能是你的程序名和系统的shutdown.exe冲突导致。[/quote]  多谢了，还真是和系统的shutdown冲突了，太感谢了

在vs，windows系统没有问题。

shutdown -s -t 1200：这条命令是延迟20分钟关闭计算机。这条命令执行需要20分钟后，才会启动关闭计算机，所以不会立马执行

不要用 void main  main里没有这个用法

引用 1 楼 wwww200808008 的回复:有可能是权限问题。你用管理者权限运行试试。 管理员运行也还是一样的情况

有可能是权限问题。你用管理者权限运行试试。


Question: c类型的结构体转成c#的结构体，请大神指导。。。

不要做A语言代码修改为B语言代码的无用功。 也不要做用A语言代码直接调用B语言代码库这样复杂、这样容易出错的傻事。 只需让A、B语言代码的输入输出重定向到文本文件，或修改A、B语言代码让其通过文本文件输入输出。 即可很方便地让A、B两种语言之间协调工作。 比如： A将请求数据写到文件a.txt，写完后改名为aa.txt B发现aa.txt存在时，读取其内容，调用相应功能，将结果写到文件b.txt，写完后删除aa.txt，再将b.txt改名为bb.txt A发现bb.txt存在时，读取其内容，读完后删除bb.txt 以上A可以替换为任何一种开发语言或开发环境，B可以替换为任何一种与A不同的开发语言或开发环境。 除非A或B不支持判断文件是否存在、文件读写和文件更名。 但是谁又能举出不支持判断文件是否存在、文件读写和文件更名的开发语言或开发环境呢？ 可以将临时文件放在RamDisk上提高效率减少磨损磁盘。 数据的结构很复杂的话，文本文件的格式问题可参考json或xml  共享临时文本文件这种进程之间的通讯方法相比其它方法的优点有很多，下面仅列出我现在能想到的： ·进程之间松耦合 ·进程可在同一台机器上，也可跨机，跨操作系统，跨硬件平台，甚至跨国。 ·方便调试和监视，只需让第三方或人工查看该临时文本文件即可。 ·方便在线开关服务，只需删除或创建该临时文本文件即可。 ·方便实现分布式和负载均衡。 ·方便队列化提供服务，而且几乎不可能发生队列满的情况（除非硬盘空间满） ·……  “跨语言、跨机，跨操作系统，跨硬件平台，跨国，跨*.*的”苦海无边， 回头是“使用共享纯文本文件进行信息交流”的岸！


Question: c语言明明是负数的运算，他按无符号进行计算

仅供参考：#include <stdio.h> unsigned short int ui;   signed short int si; int main() { 	ui=(unsigned short int)0x8000u; 	si=(  signed short int)0x8000; 	printf("ui=%u\n",ui); 	printf("si=%d\n",si); 	ui=ui>>1; 	si=si>>1; 	printf("ui=%u\n",ui); 	printf("si=%d\n",si);  	printf("--------------\n"); 	ui=(unsigned short int)0x8000u; 	si=(  signed short int)0x8000; 	printf("ui=%u\n",ui); 	printf("si=%d\n",si); 	ui=((  signed short	int)ui)>>1; 	si=((unsigned short	int)si)>>1; 	printf("ui=%u\n",ui); 	printf("si=%d\n",si);  	return 0; } //ui=32768 //si=-32768 //ui=16384 //si=-16384 //-------------- //ui=32768 //si=-32768 //ui=49152 //si=16384

第四行靠运气了哈哈哈

水点积分下载东西，楼主莫怪

http://edu.csdn.net/course/detail/2344 C语言指针与汇编内存地址-一.代码要素

int v;  v没有初台化, 你的平台估计自动初台化为0了, 你运气好.  如果给你初始化个随机数, 你看起会更诡异.  然后因为int是4字节, 你只设置了低字节, 并且成了正数, 那么说明, 你这个是小端的.   类似于变成 0x0000fff9   对于int, 他就是一个正数啊. 并不是你想的 -7.

第四行，这样赋值可以编译通过吗

什么问题? 我的编译器一切正常vs 2008

wugonggonglv = (char*)&v; wugonggonglv[0] = k_buf[1]; 这里之后，v应该变为 k_buf[1]的负数值了。 比如 k_buf[1] = 0x01,那么v = -255. 这样的话，后面的运算自然不对了。


Question: C语言菜鸟求助，大神预编译头怎么用？［图］

什么问题? 我的编译器一切正常vs 2008

#include<stdio.h>

#include <stdio.h>，不是这样吗？


Question: 新手求问再C语言中怎样输出汉字

#include<stdio.h> main(void) { char a[10]; scanf("%s",a); printf("你好"); }

引用 1 楼 user-2 的回复:#include<stdio.h> int main(void) { 	char a[7]="你好"; 	scanf("%*s",a); 	printf("%s\n",a); 	return 0; }真的可以，多谢！


Question: lnl-genl-3动态库不兼容   skipping incompatible .../usr/lib/libnl-genl-3.so

什么问题? 我的编译器一切正常vs 2008


Question: 求大神教TLV格式 C语言

不知道有多少前人掉在TCP Socket send(人多)send(病少)send(财富) recv(人多病)recv(少财富) 陷阱里面啊！ http://bbs.csdn.net/topics/380167545

希望可以有一个用TLV格式写的C语言代码模板可以参考。

什么问题? 我的编译器一切正常vs 2008


Question: 获得线性表元素的操作小问题

形参e也叫传出参数，即它要从该函数里的得到值，所以它是接收一个地址值，这个地址可能是调用函数里定义的普通变量。调用函数后，就能通过这个参数得到一个值。

这两个是不一样的，这儿是想获取第i个值，而不是获取它的地址。再说你传递给这个函数的实参（给e）也不是一个指针，而是一个变量的地址。

调用此函数时，把一个变量的地址传进来，此时，形参e 也指向这个地址，函数里，通过间接访问，修改这个地址里存放的内容，因为形参和指向的是变量的地址，所以，会影响变量的值，但是，如果修改了形参e的指向，仅仅是在调用函数时改变了形参的指向。并没有影响到变量的值

引用 1 楼 jianwen0529 的回复:e是指针值，在传入函数时候，函数中会拷贝它的一个临时副本，假设为 _e，在函数中使用的e实际上是 _e这个副本。 所以为什么说传值引用（此处更正为值传递）不会影响到实参了，因为所有的修改都是建立在这个临时的副本身上的。

e是一个指针，*用在指针的左边，是一个解引用操作符，效果是取该指针所执行的对象（值） 之后赋值给该对象，即重写e指向的内存  e=&L.data[i-1]是赋值给e，让e指向了L.data[i-1]的内存 但是这种做法会发生逻辑错误，此处解释下。  e是指针值，在传入函数时候，函数中会拷贝它的一个临时副本，假设为 _e，在函数中使用的e实际上是 _e这个副本。 所以为什么说传值引用不会影响到实参了，因为所有的修改都是建立在这个临时的副本身上的。  而这个函数是直接修改e（这个也是临时副本）所指向的内存，但是因为e和临时副本的指针值是一致的，所以找到的内存也是同一块地方，间接地影响了e（严格来说是e所指向的内存），就可以当作返回值使用。   //经过编译器处理后的代码类似如下 status GetElem(SqList L,int i,ElemType *e)//获得元素的操作线性表L第i个数据的值，并用e返回 {     SqList __GetElem_L = L;     int __GetElem_i = i;     ElemType *__GetElem_e = e;      if(__GetElem_L.length==0||__GetElem_i<1||__GetElem_L.length)         return ERROR;     *__GetElem_e=__GetElem_L.data[__GetElem_i -1];//这句不太理解不应该是 e=&L.data[i-1]吗         return OK; }


Question: 关于链表输入集合问题，代码可以输入但是不能输出？？

在create函数 while(1)上面加个p1->next=NULL;

#include<stdio.h>  #include<stdlib.h>  #include<time.h>  typedef int ElemType;  typedef struct LNode  {      ElemType data;      struct LNode *next;  } LNode,*LinkList;  void InitList(LinkList *L)  {      *L=(LinkList)malloc(sizeof(LNode));      (*L)->next=NULL;  }   /*LinkList CreateFromTail(LinkList L, int n, int N[])//尾插法建表  {      LinkList p,q;      int i;      p=(LNode*)malloc(sizeof(LNode));      L->next=NULL;      if(n!=0)      {          for(i=0; i<n; i++)          {              q=(LNode*)malloc(sizeof(LNode));              q->data=N[i];              p->next=q;              p=q;          }      }      p->next=NULL;      return L;  }*/  LinkList Creat(char n)  //输入集合  {      LinkList head=NULL,p1,p2; 	 ElemType num;      printf("请输入%c单链表集合（以0为结束符）：\n",n);      scanf("%d",&num);      if(num==0) 		return head;  	 head=p1=(LinkList)malloc(sizeof(LNode)); 	 p1->data=num;      while(1)      {          scanf("%d",&num);          if(num==0)              return head; 		 p2=(LinkList)malloc(sizeof(LNode)); 		 p2->data=num; 		 p2->next=NULL;          p1->next=p2;          p1=p2;      }  }  LinkList Sort(LinkList SL)/*递增排序函数*/  {      LinkList p1,p2;      int temp; 	 for(p1=SL->next; p1!=NULL; p1=p1->next)      {          for(p2=p1->next; p2!=NULL; p2=p2->next)          {              if(p1->data>p2->data)              {                  temp=p2->data;                  p2->data=p1->data;                  p1->data=temp;              }          }      }      return SL;  }  void Print(LinkList L) //  输出集合  {      LinkList p;      p=L->next;;      while(p)      {          printf("%d\t",p->data);          p=p->next;      }      printf("\n");  }  void AddList(LinkList La,LinkList Lb)     //求并集并输出  {      LinkList Lc;      LinkList cur,la,lb,ln;       Lc=cur=(LinkList)malloc(sizeof(LNode));      la=La->next;      lb=Lb->next;       while(la && lb)      {          if(la->data<lb->data)          {              ln=(LinkList)malloc(sizeof(LNode));              ln->data=la->data;              cur->next=ln;              cur=ln;              la=la->next;          }          else if(la->data==lb->data)          {              ln=(LinkList)malloc(sizeof(LNode));              ln->data=la->data;              cur->next=ln;              cur=ln;              la=la->next;              lb=lb->next;          }          else          {              ln=(LinkList)malloc(sizeof(LNode));              ln->data=lb->data;              cur->next=ln;              cur=ln;              lb=lb->next;          }      }      while(la)      {          ln=(LinkList)malloc(sizeof(LNode));          ln->data=la->data;          cur->next=ln;          cur=ln;          la=la->next;      }      while(lb)      {          ln=(LinkList)malloc(sizeof(LNode));          ln->data=lb->data;          cur->next=ln;          cur=ln;          lb=lb->next;      }      cur->next=NULL;       Print(Lc);  }  void JiaoList(LinkList La,LinkList Lb)  {      LinkList Lc,la,lb,ln,cur;       Lc=cur=(LinkList)malloc(sizeof(LNode));      la=La->next;      lb=Lb->next;      while(la && lb)      {          if(la->data<lb->data)              la=la->next;          else if(la->data==lb->data)          {              ln=(LinkList)malloc(sizeof(LNode));              ln->data=la->data;              cur->next=ln;              cur=ln;              la=la->next;              lb=lb->next;          }          else              lb=lb->next;      }      cur->next=NULL;      Print(Lc);  }  void ChaList(LinkList La,LinkList Lb)  {      LinkList Lc,la,lb,cur,ln;       Lc=cur=(LinkList)malloc(sizeof(LNode));      la=La->next;      lb=Lb->next;       while(la && lb)      {          if(la->data<lb->data)          {              ln=(LinkList)malloc(sizeof(LNode));              ln->data=la->data;              cur->next=ln;              cur=ln;              la=la->next;          }          else if(la->data==lb->data)          {              la=la->next;              lb=lb->next;          }          else              lb=lb->next;      }      while(la)      {          ln=(LinkList)malloc(sizeof(LNode));          ln->data=la->data;          cur->next=ln;          cur=ln;          la=la->next;      }      cur->next=NULL;      Print(Lc);  }  int main()  {      LinkList La, Lb;      //LinkList head,p1,p2;      //int na,nb;      InitList(&La);      InitList(&Lb);      La->next=Creat('A') ;      Lb->next=Creat('B') ;      Sort(La);      Sort(Lb);      Print(La);      Print(Lb);      printf("并集为：\n");      AddList(La,Lb);      printf("交集为：\n");      JiaoList(La,Lb);      printf("差集为：\n");      ChaList(La,Lb); 	 system("pause");      return 0;  }


Question: 已自定义SIGINT处理函数，为什么ctrl+c 仍不能终止程序执行？

@laoqiang0910 , 就是按ctrl+c 预期是进程终止，实际终止不掉。 你说的没问题是指什么？

什么问题? 我的编译器一切正常vs 2008

在不知道谁调用的语句处设置断点，中断在断点处时，按Alt+7键查看Call Stack即“调用堆栈”里面从上到下列出的对应从里层到外层的函数调用历史。双击某一行可将光标定位到此次调用的源代码或汇编指令处，看不懂时双击下一行，直到能看懂为止。

是不是可以这样理解：    进程收到SIGINT 信号， --> 调用sig_cancel函数处理，而该函数通过调用kill 对该进程再次发送SIGINT信号， -->   进程收到SIGINT 信号， --> 调用sig_cancel函数处理，而该函数通过调用kill 对该进程再次发送SIGINT信号， -->  .....      这样死循环了， 对吧？


Question: 高手大佬帮忙，求有向图中所有最小的简单环

引用 6 楼 zhao4zhong1 的回复:《算法精解（C语言描述）》  给本书是什么意思呢？让去看书吗。

引用 8 楼 laoqiang0910 的回复:什么问题? 我的编译器一切正常vs 2008   你说的和我的是一个问题吗？

什么问题? 我的编译器一切正常vs 2008

发本书您是什么意思？

《算法精解（C语言描述）》

数据结构中有向图问题。

其实要求的环应该满足：环自身的顶点集合的子集不能在构成其他的环

对，是数据结构里面图论的东西

但我的需求就是如题啊，要找所有简单环并且这些简单环的节点集合是最小的，包含任一这些节点集合的大的节点集合构成的环，都要剔除

本来就指数级的规模，我100个点都能把你撑爆： 1->2->3 1->3 这样的一个有向三角形拿50个头尾相连构成一个圈。总共2^50个圈而且互不包含。  这种时候必须是改需求啊


Question: 输出出问题了

对于浮点型数据的定义： long double s=1.0； 其他没什么问题，vc6.0 完美通过 还有就是，如果你要进行的是阶乘的运算的话，不必要定义浮点型，整型就ok了！ 阶乘代码：  #include<stdio.h> #include<stdlib.h> int main() {     int n,num=1,i; 	if(scanf("%d",&n)!='EOF') 	{ 		for(i=1;i<=n;i++) 		{ 			num*=i; 		} 	} 	printf("%d",num); 	return 0; }

VS2015+Windows10 64位 把scanf()该为scanf_s()后，没有问题，以下是输出

Format Specification Fields: printf and wprintf Functions     This topic describes the syntax for format specifications fields, used in printf, wprintf and related functions. More secured versions of these functions are available, see printf_s, _printf_s_l, wprintf_s, _wprintf_s_l. For details on the individual functions, see the documentation for those specific functions. For a complete listing of these functions, see Stream I/O.  A format specification, which consists of optional and required fields, has the following form:  %[flags] [width] [.precision] [{h | l | ll | I | I32 | I64}]type  Each field of the format specification is a single character or a number signifying a particular format option. 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 field, the character is copied to stdout. For example, to print a percent-sign character, use %%.  The optional fields, which appear before the type character, control other aspects of the formatting, as follows:  type Required character that determines whether the associated argument is interpreted as a character, a string, or a number (see the "printf Type Field Characters" table in printf Type Field Characters).  flags Optional character or characters that control justification of output and printing of signs, blanks, decimal points, and octal and hexadecimal prefixes (see the "Flag Characters" table in Flag Directives). More than one flag can appear in a format specification.  width Optional number that specifies the minimum number of characters output (see printf Width Specification).   precision Optional number that specifies the maximum number of characters printed for all or part of the output field, or the minimum number of digits printed for integer values (see the "How Precision Values Affect Type" table in Precision Specification).  h| l| ll| I| I32| I64 Optional prefixes to type-that specify the size of argument (see the "Size Prefixes" table in Size and Distance Specification).  Security Note:  Ensure that format specification strings are not user-defined. For example, consider a program that prompts the user to enter his name and stores the input in a string variable called name. To print name, do not do this:     Copy Code  printf( name ); // Danger!  If name contains "%s", program will crash   Note:  Instead, do this:     Copy Code  printf( "%s", name );

顶楼上，无问题

printf（“%d”,a）;

什么问题? 我的编译器一切正常vs 2008

long double输出需要用%llf 因为lf只是double的输出格式，long double是llf输出格式了。

%Lf 这个格式输出试试


Question: 大神帮忙看看我这代码，输入回车没反应

printf("even is %d,average is %d,odd is %d,ave is %d", even, aven / even, odd, avodd / odd);。。aven / even, odd, avodd / odd这俩货除数可能为0 。而且一般用到除法可能会出现小数，前面%d最好用%f

0是退出条件，输出结果有可以被零除。

printf语句可能存在0/0非法。。。。


Question: 新人求助：字符指针读取字符串问题出现第一机会异常问题。

问题楼上都说了，首先指向字符串最后一个字符，减1即可，其次用来交换的应该是字符而不是字符指针，第三点，输入参数是字符串常量，无法被改变。

#include "stdafx.h" #include <stdio.h> #include <string.h> #include<stdlib.h>  void reverse(char* str) {     char temp, *p, *q; int i;    /*temp定义成字符类型即可。*/     p = str;     q = p + strlen(str) - 1;   /*减1就好，因为最后只有一个'\0'，下表是从0开始。*/     for (i = 0; i< strlen(str) / 2; i++){         temp = *p;         *p = *q;         *q = temp;         p++; q--;     } }   int _tmain(int argc, _TCHAR* argv[]) {     char str[] = "hello";   /*需要定义成数组，否则是字符串常量是不能修改的，所以调用reverse会导致段错误*/     printf("%s\n",str);      reverse(str);     printf("%s\n", str);     //system("pause");      return 0; } 三处问题，详见以上代码

O(∩_∩)O谢谢楼上问题已经解决了，我回去也改了两个地方，就是把它做成常量了，谢谢

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

temp指向NULL,所以错误，可以用malloc申请空间，还有，那个应该是-1才对

1,、将char *temp修改为char temp，后边*temp都为temp； 2、将char*str="hello"修改为char str[6] = "hello"


Question: 拼长度问题，求高手老师给予帮助！谢谢!

谢谢，各位老师的认真详细的解释！@jianwen0529 @user-4 @zhao4zhong1  非常感谢！ 我是门外汉，不懂怎么编程，是C/C++语法是吧，谢谢~

穷举法  “给定一个小点的输入，完整单步跟踪(同时按Alt+7键查看Call Stack里面从上到下列出的对应从里层到外层的函数调用历史)一遍。”是理解递归函数工作原理的不二法门！ 递归函数关注以下几个因素 ·退出条件 ·参数有哪些 ·返回值是什么 ·局部变量有哪些 ·全局变量有哪些 ·何时输出 ·会不会导致堆栈溢出

引用 4 楼 jianwen0529 的回复:[quote=引用 3 楼 kuangbao9 的回复:] [quote=引用 2 楼 jianwen0529 的回复:] 你这个数据量很少，遍历所有情况，选择剩余少的那种情况就可以了，很小的一个算法。  现在只有28米=2支 ，49米=3支 ，55米=4支这三种，那要是每次种类都不一样呢？这个该怎么去写一个函数遍历呢？[/quote] 一楼已经给出代码了 28米=2支 ，49米=3支 ，55米=4支 分别有3 4 5种选择（不选也是一种选择）（例如28m线，不取，取一根，取两根） 设x为记录剩余的长度，可以初始化为55或者更大（因为最佳情况不可能剩余超过或等于55m，用于后续的比较） 组合所有情况，当不满足115m需求则舍弃该种组合。当满足时，记录此种选择并跟之前比较是不是剩余更少。 最后，剩余最少的就是最佳组合了。[/quote]  我的意思是28米=2支 ，49米=3支 ，55米=4支， 66米 = 2, 56米 = 5,..............后面不知道有多少个，这个怎么设计函数

ComputeMaxNumNeeded这个函数可有可无，是之前设计思路写的。  不过如今那个递归求解的函数已经间接做了ComputeMaxNumNeeded这个事情，虽然也是多了一些计算，但是影响不大

#include <stdio.h> #include <stdlib.h> #include <limits.h>  #define  MAX_COUNT 100  //0记录材料规格长度，1记录总数，2记录最多需要的数量 int _material[MAX_COUNT][3] = { 0 }; int _num_material = 0;  void ComputeMaxNumNeeded(int needLength) {     int i, maxNum;     for (i = 0, maxNum = 1; i < _num_material; ++i)     {         while (_material[i][0] * maxNum < needLength && maxNum < _material[i][1])             ++maxNum;         _material[i][2] = maxNum;     } }  int MinSurplus(int(*material)[3], int num, int needLength, int *result) {     int i, j;     int len, totalLen = 0;     int minSurplus = INT_MAX;      // 递归结束条件     if (num == 0)         return 0;          *result = 0; //首先设置此索引默认值     for (i = 0; i <= (*material)[2]; ++i)     {         // 重置之后的索引记录项，防止之前计算45设置了但是此次却没有递归导致索引错误         for (j = 1; j < num; ++j)             *(result + j) = 0;          len = (*material)[0] * i;         // 如果还未够长度，则递归         if (len < needLength)             len += MinSurplus(material + 1, num - 1, needLength - len, result + 1);          // 判断此种情况是否为最优结果，是则记录所需信息         if (len > needLength && len - needLength < minSurplus)         {             *result = i;             totalLen = len;             minSurplus = len - needLength;         }     }      return totalLen; }  int main() {     int *result = 0;     int length = 0;     int i;      _material[0][0] = 28;     _material[0][1] = 2;     _material[1][0] = 49;     _material[1][1] = 3;     _material[2][0] = 55;     _material[2][1] = 4;      _num_material = 3;      ComputeMaxNumNeeded(115);      result = (int *)malloc(sizeof(int)*_num_material);     length = MinSurplus(_material, _num_material, 115, result);      printf("%d\n", length);     for (i = 0; i < _num_material; ++i)         printf("%d ", result[i]);     printf("\n");      free(result);      return 0; }

引用 3 楼 kuangbao9 的回复:[quote=引用 2 楼 jianwen0529 的回复:] 你这个数据量很少，遍历所有情况，选择剩余少的那种情况就可以了，很小的一个算法。  现在只有28米=2支 ，49米=3支 ，55米=4支这三种，那要是每次种类都不一样呢？这个该怎么去写一个函数遍历呢？[/quote] 一楼已经给出代码了 28米=2支 ，49米=3支 ，55米=4支 分别有3 4 5种选择（不选也是一种选择）（例如28m线，不取，取一根，取两根） 设x为记录剩余的长度，可以初始化为55或者更大（因为最佳情况不可能剩余超过或等于55m，用于后续的比较） 组合所有情况，当不满足115m需求则舍弃该种组合。当满足时，记录此种选择并跟之前比较是不是剩余更少。 最后，剩余最少的就是最佳组合了。

#include <stdio.h> int main() { 	//28米=2支 ，49米=3支 ，55米=4支 //。实际用的整条线为115 	int i,j,k,min=115,p; 	int x,y,z; 	for(i=0;i<=2;i++) 	    for(j=0;j<=3;j++) 	         for(k=0;k<=4;k++) 	         { 	              p=28*i+49*j+55*k-115; 	              if(p>=0&&p<min) 	              { 	                  min=p; 	                  x=i;y=j;z=k; 	              }   	         } 	     printf("%d %d %d min=%d\n",x,y,z,min);         	     return 0;    }

引用 2 楼 jianwen0529 的回复:你这个数据量很少，遍历所有情况，选择剩余少的那种情况就可以了，很小的一个算法。  现在只有28米=2支 ，49米=3支 ，55米=4支这三种，那要是每次种类都不一样呢？这个该怎么去写一个函数遍历呢？

你这个数据量很少，遍历所有情况，选择剩余少的那种情况就可以了，很小的一个算法。


Question: c语言新手求助大佬

引用 3 楼 qq_40088982 的回复:大神们太厉害了，问一下int long和int short分别怎么用 建议查一下这个楼主的博客； http://blog.csdn.net/u012223913/article/details/51181761

大神们太厉害了，问一下int long和int short分别怎么用

//删除学生信息 void DeleteStuDate(PNODE pNode); //修改学生信息 void ReviseStuDate(PNODE pTemp); 函数声明需要添加参数，至少参数的类型需要加。  void ReadStuDate() {     char stubuf[30] = { 0 };     char stunum[10] = { 0 };     char stuname[10] = { 0 };     char stuscore[10] = { 0 };     FILE* pFile = fopen("StuDate.txt", "rb+");     int nCount = 0;     int j = 0;      if (NULL == pFile)     {         printf("文件打开失败\n");         return;     }     else     {         printf("读取成功\n");    /*这儿还没开始读呢*/     }     //操作文件指针     while ( NULL!=fgets(stubuf, 30, pFile))    /*这儿应该去掉分号*/     {         int i = 0;         nCount = 0;         j = 0;         for (i = 0; stubuf[i] != '\n'; i++)   /*此处应该是'\n'，而不应该是'\r'*/         {             //没到点             if (0 == nCount)             {                 stunum[i] = stubuf[i];                 if ('.' == stubuf[i])                 {                     stunum[i] = '\0';                     nCount++;                 }             }             //第一个点             else if (1 == nCount)             {                 stuname[j] = stubuf[i];                 j++;                 if ('.' == stubuf[i])                 {                     stuname[j] = '\0';                     nCount++;                     j = 0;                 }             }             else             {                 stuscore[j] = stubuf[i];                 j++;             }         }         //插入到链表         AddStuMsg(stuname, stunum, atoi(stuscore));     }     fclose(pFile); } 回车符应该是'\n'

while ( NULL!=fgets(stubuf, 30, pFile));  加了分号，就等着读到最后一行后，再执行下面的语句吧。


Question: 求大神帮我看下下面这个递归和迭代那个快啊

迭代效率高，计算机就是喜欢做重复性的工作

无profiler不要谈效率！！尤其在这个云计算、虚拟机、模拟器、CUDA、多核 、多级cache、指令流水线、多种存储介质、……满天飞的时代！

通常迭代比较快，递归每次调用函数需要压栈出栈等有开销

迭代快一点       参数不大的话差不多

用性能检查工具看 一般来说一点差距没有任何意义，只有算法的改进和掉用量巨大的方法才有价值 pow的话用矩阵可以把复杂度降为logn


Question: 架构师怎么学

架构师更多是实际的项目经验，现在只有理论知识的架构师不存在吧。 所以，不断提高自己的项目经验，解决问题的经验，才能一步步向架构师靠拢

先是学基础.   各种语法, 算法,开源库, 开源框架    然后是总结 然后在工作中实践 积累.

这不仅仅是学的结果，还是项目经验积累的结果。因为几乎没有一个大项目是仅仅只用一门技术去实现的。  架构师对很多技术都应该是熟悉的，精通其中某个或多个领域。 在架构程序的时候选择什么样的架构，什么算法，什么技术。 对性能有一定的把控，对未来的扩展有一定程度的支持。  我只能说出我自己理解的架构师。

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


Question: 内存泄漏

引用 3 楼 cfennudezhanche的回复:意思是free(tmp),,,,,就可以释放掉p所申请的内存空间吗? 理论上可以 都指向那片空间 释放谁都可以

引用 3 楼 cfennudezhanche 的回复:意思是free(tmp),,,,,就可以释放掉p所申请的内存空间吗? 可以，因为tmp也指向了funcA所申请的内存； 也可以在funcA函数内直接释放（前提是不再使用该内存空间） 在funA中，直接free(p);  另外，你的memcpy函数缺少参数，需要3个参数，而调用的时候只提供了2个

意思是free(tmp),,,,,就可以释放掉p所申请的内存空间吗?

释放接受改参数的变量

malloc 对应 free  只需在需要释放的地方调用free即可.


Question: C语言位字段问题

Struct定义不够整字节，整字节对齐

C语言结构struct的内存对齐 http://blog.csdn.net/hou09tian/article/details/74359172 希望能帮助到你

什么问题? 我的编译器一切正常vs 2008

pack #pragma pack( [ n] )  Specifies packing alignment for structure and union members. Whereas the packing alignment of structures and unions is set for an entire translation unit by the /Zp option, the packing alignment is set at the data-declaration level by the pack pragma. The pragma takes effect at the first structure or union declaration after the pragma is seen; the pragma has no effect on definitions.  When you use #pragma pack(n), where n is 1, 2, 4, 8, or 16, each structure member after the first is stored on the smaller member type or n-byte boundaries. If you use #pragma pack without an argument, structure members are packed to the value specified by /Zp. The default /Zp packing size is /Zp8.  The compiler also supports the following enhanced syntax:  #pragma pack( [ [ { push | pop}, ] [  identifier, ] ] [ n ] )  This syntax allows you to combine program components into a single translation unit if the different components use pack pragmas to specify different packing alignments.   Each occurrence of a pack pragma with a push argument stores the current packing alignment on an internal compiler stack. The pragma’s argument list is read from left to right. If you use push, the current packing value is stored. If you provide a value for n, that value becomes the new packing value. If you specify an identifier, a name of your choosing, the identifier is associated with the new packing value.  Each occurrence of a pack pragma with a pop argument retrieves the value at the top of an internal compiler stack and makes that value the new packing alignment. If you use pop and the internal compiler stack is empty, the alignment value is that set from the command-line and a warning is issued. If you use pop and specify a value for n, that value becomes the new packing value. If you use pop and specify an identifier, all values stored on the stack are removed from the stack until a matching identifier is found. The packing value associated with the identifier is also removed from the stack and the packing value that existed just before the identifier was pushed becomes the new packing value. If no matching identifier is found, the packing value set from the command line is used and a level-one warning is issued. The default packing alignment is 8.  The new, enhanced functionality of the pack pragma allows you to write header files that ensure that packing values are the same before and after the header file is encountered:  /* File name: include1.h */ #pragma pack( push, enter_include1 ) /* Your include-file code ... */ #pragma pack( pop, enter_include1 ) /* End of include1.h */  In the previous example, the current pack value is associated with the identifier enter_include1 and pushed, remembered, on entry to the header file. The pack pragma at the end of the header file removes all intervening pack values that may have occurred in the header file and removes the pack value associated with enter_include1. The header file thus ensures that the pack value is the same before and after the header file.  The new functionality also allows you to use code, such as header files, that uses pack pragmas to set packing alignments that differ from the packing value set in your code:  #pragma pack( push, before_include1 ) #include "include1.h" #pragma pack( pop, before_include1 )  In the previous example, your code is protected from any changes to the packing value that might occur in include.h.

http://blog.csdn.net/crazywdy/article/details/33730775 设定结构体对齐和取消结构体对齐；

引用 1 楼 赵4老师的回复:仅供参考：#include <stdio.h> #pragma pack(push,1) union U {     unsigned char byte;     struct BF {         unsigned int b0:1;//a         unsigned int b1:1;//b         unsigned int b2:1;//c     } bf; } u; #pragma pack(pop) unsigned char bt; int a,b,c; int main() {     for (bt=0;bt<8;bt++) {         u.byte=(unsigned char)bt;         a=u.bf.b0;         b=u.bf.b1;         c=u.bf.b2;         printf("byte 0x%02x -- c:%d b:%d a:%d\n",bt,c,b,a);     }     for (c=0;c<2;c++)     for (b=0;b<2;b++)     for (a=0;a<2;a++) {         u.bf.b0=a;         u.bf.b1=b;         u.bf.b2=c;         bt=u.byte;         printf("c:%d b:%d a:%d -- byte 0x%02x\n",c,b,a,bt);     }     return 0; } //byte 0x00 -- c:0 b:0 a:0 //byte 0x01 -- c:0 b:0 a:1 //byte 0x02 -- c:0 b:1 a:0 //byte 0x03 -- c:0 b:1 a:1 //byte 0x04 -- c:1 b:0 a:0 //byte 0x05 -- c:1 b:0 a:1 //byte 0x06 -- c:1 b:1 a:0 //byte 0x07 -- c:1 b:1 a:1 //c:0 b:0 a:0 -- byte 0x00 //c:0 b:0 a:1 -- byte 0x01 //c:0 b:1 a:0 -- byte 0x02 //c:0 b:1 a:1 -- byte 0x03 //c:1 b:0 a:0 -- byte 0x04 //c:1 b:0 a:1 -- byte 0x05 //c:1 b:1 a:0 -- byte 0x06 //c:1 b:1 a:1 -- byte 0x07   这#pragma什么意思？，pack()？有关预处理还不太懂

？，什么头，求指点。。。。。

哎，头拧不过去呀


Question: 关于数据查找的问题，求指教

注意，110D这个不是十进制也不是16进制。因此，要么定义成16进制，但是需要加0x，要么去掉D，作为一个10进制。

#include<stdio.h> #include<string.h>  typedef unsigned short int16u;  typedef struct {     char *company;     int16u code;  }Manufacturer_Code_t;  int searchCompany(Manufacturer_Code_t *parr, int16u len, int16u code0);  int main(void) {     Manufacturer_Code_t Manufacturer_Code[]={{"2_Save_Energy_Ltd", 110}};     int16u idx, len, code;      len = sizeof(Manufacturer_Code) / sizeof(Manufacturer_Code[0]);     printf("size = %d, %d, %d\n", len, sizeof(Manufacturer_Code), sizeof(Manufacturer_Code[0]));     //scanf("%d", &code);     scanf("%hu", &code);     idx = searchCompany(Manufacturer_Code, len, code);     if (idx < len) {         printf("%s\n", Manufacturer_Code[idx].company);     } else {         printf("Can't find it!\n");     }     if (idx )     return 0; }   int searchCompany(Manufacturer_Code_t *parr, int16u len, int16u code0) {     int i;      for (i = 0; i < len; i++) {         if (parr[i].code == code0)             return i;     }      return i; }

仅供参考：#include<stdio.h> #include<string.h>    typedef struct  {  	char *company;  	int16u code;  }Manufacturer_Code_t;  char* searchCompany(int16u code0)  char* searchCompany(Manufacturer_Code_t mmc, int16u code0) { 	if(mmc[0].code == code0){ 		return Manufacturer_Code[0].company; 	} 	return null; }  int main() { 	Manufacturer_Code_t Manufacturer_Code[]={{"2_Save_Energy_Ltd", 110D}};  	char* company = searchCompany(Manufacturer_Code, 110D); 	printf("%s\n", company); 	return 0; }


Question: 从文件中读取数据求平均值和最大最小值，真的搞不懂了，可以单独弄一个模块查看吗

引用 3 楼 qq_40034595 的回复:大神！！求的是图书价格的平均值和最大最小值 可以仿照上面的demo写一个函数。

大神！！求的是图书价格的平均值和最大最小值

引用 1 楼 qq_40034595 的回复:真的弄不了了 代码是图书管理系统，你的要求是求平均值和最大最小值，好像不搭。 你要读取的数据格式，说一下。求平均值应该不难，最大值和最小值，遍历求解。 以下是一个demo程序，求最大值，最小值和平均值： #include <stdio.h>  int get_avr_value(int *arr, int len, int *pmax, int *pmin);  int main(void) {     int arr[] = { 10, 45, 67, 80, 38};     int size = sizeof(arr)/sizeof(arr[0]);     int max, min, avr;      avr = get_avr_value(arr, size, &max, &min);     printf("avr = %d, max = %d, min = %d\n", avr, max, min);     return 0; }   int get_avr_value(int *arr, int len, int *pmax, int *pmin) {     int avr, sum;     int i;      *pmax = *pmin = arr[0];     sum = arr[0];     for (i = 1; i < len; i++) {         if (*pmax < arr[i])             *pmax = arr[i];         if (*pmin > arr[i])             *pmin = arr[i];         sum += arr[i];     }     avr = sum / len;     return avr; }

真的弄不了了


Question: 在用枚举法求解八皇后问题时遇到了问题

今早打开继续解决问题，发现judge写成jungle,就将错就错吧

“给定一个小点的输入，完整单步跟踪(同时按Alt+7键查看Call Stack里面从上到下列出的对应从里层到外层的函数调用历史)一遍。”是理解递归函数工作原理的不二法门！ 递归函数关注以下几个因素 ·退出条件 ·参数有哪些 ·返回值是什么 ·局部变量有哪些 ·全局变量有哪些 ·何时输出 ·会不会导致堆栈溢出

引用 2 楼 zhao4zhong1 的回复:仅供参考：#include <stdio.h> int d[8][8]; int n; void queen8(int L) {     int x,y;      if (8==L) {         n++;         printf("%d\n",n);         for (y=0;y<8;y++) {             for (x=0;x<8;x++) { //              printf("%d",d[y][x]);                 if (d[y][x]) printf("■");                 else         printf("□");             }             printf("\n");         }         return;     }     for (x=0;x<8;x++) {         for (y=0;y<L;y++) {             if  (              d[y][x      ]              || (x-(L-y)>=0 && d[y][x-(L-y)])              || (x+(L-y)< 8 && d[y][x+(L-y)]))                 break;         }         if (y>=L) {             d[L][x]=1;             queen8(L+1);             d[L][x]=0;         }     } } int main() {     int y,x;     for (y=0;y<8;y++) {         for (x=0;x<8;x++) {             d[y][x]=0;         }     }     queen8(0);     return 0; }  老师，你的代码简洁可行，但是queen8把0给传进去，那这个if（8 == L） 不是永远没办法是true吗，还有我特想知道我的代码逻辑错误出在哪儿了，第一次写程序。


Question: 链表的插入排序

我会了    谢谢各位

r用以保存上次满足条件指针，不满足了，就插入r后

建议单步跟踪程序运行，观察变量变化情况，比你空想容易懂&& 运算符当左边操作数为假的时候不会执行右边所以q!=NULL&&q->data<=p->data这句中，q为NULL时不会再比较后面的了

刚打完草稿发现还是不会才过来问的 我都想了一整天，就这一小段代码，看见就想吐   最后一行  p=u  是什么操作

进入第一层while循环后，第一次不会立马执行第二层的循环，因为q不满足条件，所以会跳过第二层循环，执行后面的，然后第二次就会执行到第二次while循环了。 建议在草稿纸上画画这个排序的过程

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


Question: popen阻塞问题

再供参考：#include <stdio.h> #include <sys/types.h> #include <sys/wait.h> #include <unistd.h> pid_t rw_popen(char* cmd, FILE **rfile, FILE **wfile) {     int pipefd[2],pipefd2[2]; //管道描述符     pid_t pid; //进程描述符      if (pipe(pipefd) < 0) //建立管道     {         printf("rw_popen() pipe create error/n");         return 0;     }     if (pipe(pipefd2) < 0) //建立管道     {         printf("rw_popen() pipe create error/n");         return 0;     }      pid = fork(); //建立子进程      if (pid < 0)     return 0;      if (0 == pid) //子进程中     {         close(pipefd[0]);         dup2(pipefd[1], 1);         close(pipefd[1]);         dup2(pipefd2[0], 0);         close(pipefd2[0]);         close(pipefd[1]);         char *argv[] = { "/bin/sh", "-c", cmd, NULL };         if (execvp("/bin/sh", argv) < 0) //用exec族函数执行命令         exit(1);     }      close(pipefd[1]);     *rfile = fdopen(pipefd[0], "r");     close(pipefd2[0]);     *wfile = fdopen(pipefd2[1], "w");     return pid; } void rw_pclose(pid_t pid, FILE *rfile, FILE *wfile) {     int status;     waitpid(pid, &status, 0);     fclose(rfile);     fclose(wfile); } int main() {     char buf1[1024];     FILE *file1, *file2;     pid_t pid;     pid = rw_popen("sh", &file1, &file2);     if (pid) {         fputs("pwd;exit;\n",file2);         fflush(file2);         if (fgets(buf1, 1400, file1)) {             puts(buf1);         }         rw_pclose(pid, file1, file2);     }     return 1; }

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


Question: 关于C语言IO输出txt的效率问题

7楼已经给了你方法。

引用 1 楼 zhao4zhong1 的回复:无profiler不要谈效率！！尤其在这个云计算、虚拟机、模拟器、CUDA、多核 、多级cache、指令流水线、多种存储介质、……满天飞的时代！  不要低估操作系统读写文件使用内存缓冲区优化速度时的智商。 赵四老师请教一个问题，现在公司有个项目要做多线程读写的功能，就是从多个存储设备读取数据写入到单个磁盘中，要求数据读取要多线程同步进行，但是考虑到磁盘实际是异步写入，如果多线程会不会导致磁盘频繁跳针，对磁盘损耗过大？有没有什么缓解的方法？

学会使用profiler才是王道。

建议换Intel的编译器再试试。

引用 12 楼 qq_35359073 的回复:[quote=引用 11 楼 zhao4zhong1 的回复:] 没准只是因为fortran写的文件碎片少；而C写的文件碎片多罢了。 这是我写的fortran和C的代码对比，可能是我小白，C写的代码很垃圾； 都是windows764位的I5-6200的cpu环境下，假设3年，每年365天，有300个单元，每个单元（行）输出1个字符串+80个双精度浮点数； 这是C的，运行时间为20秒左右大约生成了200M的文件，VC编译后运行20秒左右，GCC编译后运行时间也是20秒左右 #include <stdio.h> #include <stdlib.h> #include <time.h>  int main(){ 	FILE *fp = NULL; 	char hruname[14] = {"test"}; 	int year = 0, day = 0, h = 0, i = 0; 	int start_time = 0, end_time = 0; 	double /*array[1000000] = {0.0},*/ run_time = 0.0; 	double *array = (double*)calloc(80, sizeof(double)); 	for (i = 0; i < 80; ++i) { 		array[i] = 5.0/* * random()*/; 	} 	start_time = clock(); 	fp = fopen("TEST.txt", "w");  	for (year = 0; year < 3; year++) 	{ 		for (day = 0; day < 365; day++) 		{ 			for (h = 0; h < 300; h++) 			{ 				fprintf(fp,"%8s", hruname);  				for(i = 0; i < 80; ++i) 				{ 					fprintf(fp,"%8.4lf", array[i]); 				} 			} 			fprintf(fp,"\n"); 		} 		printf("第%d年完毕\n", year); 	}  	fclose(fp); 	end_time = clock(); 	run_time = ((double)end_time - (double)start_time) / 1000.0; 	printf("%lf", run_time); 	getchar(); 	return 0; }   这是fortran的代码，使用visual studio2012平台和intel fortran2013编译器编译，运行时间为5.5秒左右！ program main     !初始化数据     real, dimension (:), allocatable :: array     real :: t, start_time, end_time     character (len=14) :: hruname     integer :: i, year, day , h     allocate (array(80))     array = 5.0     i = 0     year = 0     day = 0     h = 0     hruname = "test"     !生成随机数     !call random_seed()     !do i = 1, 100000     !    array(i) = 5.;     !end do     call CPU_TIME(start_time)     open (1,file="TEST.txt")     do year = 1, 3         do day = 1, 365             do h = 1, 300                 write(1,1001) hruname, (array(i), i = 1, 80)                               end do         end do         write(*,*) "年结束"     end do     close(1)     call CPU_TIME(end_time)     write(*,*) end_time - start_time     pause 1001 format(a8, 80f8.4)       stop end   我承认我很菜，但是请问在IO输出上，C和fortran的差距有这么大么？[/quote]  我又试了一下，fortran之所以能够快这么多，就是fortran的矩阵计算十分变态，如果write(1,1001) hruname (array(i), i = 1, 80)  这里不用隐式循环而改成                 do i = 1 , 80                     write(1,1003) array(i)                 end do 也是巨慢无比，要比C语言还慢好几倍，与隐式循环差了10倍！真希望C语言也能有这么强的数组运算能力！

引用 11 楼 zhao4zhong1 的回复:没准只是因为fortran写的文件碎片少；而C写的文件碎片多罢了。 这是我写的fortran和C的代码对比，可能是我小白，C写的代码很垃圾； 都是windows764位的I5-6200的cpu环境下，假设3年，每年365天，有300个单元，每个单元（行）输出1个字符串+80个双精度浮点数； 这是C的，运行时间为20秒左右大约生成了200M的文件，VC编译后运行20秒左右，GCC编译后运行时间也是20秒左右 #include <stdio.h> #include <stdlib.h> #include <time.h>  int main(){ 	FILE *fp = NULL; 	char hruname[14] = {"test"}; 	int year = 0, day = 0, h = 0, i = 0; 	int start_time = 0, end_time = 0; 	double /*array[1000000] = {0.0},*/ run_time = 0.0; 	double *array = (double*)calloc(80, sizeof(double)); 	for (i = 0; i < 80; ++i) { 		array[i] = 5.0/* * random()*/; 	} 	start_time = clock(); 	fp = fopen("TEST.txt", "w");  	for (year = 0; year < 3; year++) 	{ 		for (day = 0; day < 365; day++) 		{ 			for (h = 0; h < 300; h++) 			{ 				fprintf(fp,"%8s", hruname);  				for(i = 0; i < 80; ++i) 				{ 					fprintf(fp,"%8.4lf", array[i]); 				} 			} 			fprintf(fp,"\n"); 		} 		printf("第%d年完毕\n", year); 	}  	fclose(fp); 	end_time = clock(); 	run_time = ((double)end_time - (double)start_time) / 1000.0; 	printf("%lf", run_time); 	getchar(); 	return 0; }   这是fortran的代码，使用visual studio2012平台和intel fortran2013编译器编译，运行时间为5.5秒左右！ program main     !初始化数据     real, dimension (:), allocatable :: array     real :: t, start_time, end_time     character (len=14) :: hruname     integer :: i, year, day , h     allocate (array(80))     array = 5.0     i = 0     year = 0     day = 0     h = 0     hruname = "test"     !生成随机数     !call random_seed()     !do i = 1, 100000     !    array(i) = 5.;     !end do     call CPU_TIME(start_time)     open (1,file="TEST.txt")     do year = 1, 3         do day = 1, 365             do h = 1, 300                 write(1,1001) hruname, (array(i), i = 1, 80)                               end do         end do         write(*,*) "年结束"     end do     close(1)     call CPU_TIME(end_time)     write(*,*) end_time - start_time     pause 1001 format(a8, 80f8.4)       stop end   我承认我很菜，但是请问在IO输出上，C和fortran的差距有这么大么？

没准只是因为fortran写的文件碎片少；而C写的文件碎片多罢了。

引用 4 楼 qq_35359073 的回复:[quote=引用 2 楼 cfjtaishan 的回复:] 建议楼主试一下，不会你想像的那么慢。 再说你的要求只是100000次。 与其纸上谈兵，不如实际操作一下； IO是有缓存的，并且也不是你说的调一下fprintf就往文件里写一下，往磁盘写数据先放到缓存里，然后到一定数量了（达到一定字节数）才会真正的刷到文件里。你好，我试了一下，主要我想与fortran语言进行一下对比，感觉C语言在IO的输出上要比fortran满了太多，同样的输出量，C语言输出的时间是fortran的两倍！[/quote] 你用两种语言算一下用时，看那个用时时间长一些。把它们的分别用时打出来。

引用 8 楼 qq_35359073 的回复:引用 5 楼 jianwen0529 的回复:请查看release版本的用时。release版本，同样写2G的数据（格式一样，fortran写的还稍微多一些）多次测试是fortran的用时为：90秒左右，C的用时是178秒左右 格式化（fprintf）写还是非格式化（write）写？是否每次写都有刷新输出流缓冲区的动作？

您是否希望迅速对您频繁使用的文件进行碎片整理？使用 Contig 优化单个的文件，或者创建连续的新文件。http://technet.microsoft.com/zh-cn/sysinternals/bb897428

你 再试一次 换台电脑 重启电脑 …… 没准就不是所谓的两倍了。  在文件大小相同的前提下：  读刚读过的文件比头次读没读过的文件快  读转速快的硬盘上的文件比读转速慢的硬盘上的文件快  读没有磁盘碎片的文件比读有磁盘碎片的文件快  读文件不处理比边读边处理快  单线程从头到尾一次读文件比多线程分别读文件各部分快（非固态硬盘上）  读固态硬盘上的文件比读普通硬盘上的文件快 写类似。

请查看release版本的用时。

引用 2 楼 cfjtaishan 的回复:建议楼主试一下，不会你想像的那么慢。 再说你的要求只是100000次。 与其纸上谈兵，不如实际操作一下； IO是有缓存的，并且也不是你说的调一下fprintf就往文件里写一下，往磁盘写数据先放到缓存里，然后到一定数量了（达到一定字节数）才会真正的刷到文件里。你好，我试了一下，主要我想与fortran语言进行一下对比，感觉C语言在IO的输出上要比fortran满了太多，同样的输出量，C语言输出的时间是fortran的两倍！

引用 1 楼 zhao4zhong1 的回复:无profiler不要谈效率！！尤其在这个云计算、虚拟机、模拟器、CUDA、多核 、多级cache、指令流水线、多种存储介质、……满天飞的时代！  不要低估操作系统读写文件使用内存缓冲区优化速度时的智商。你好，我试了一下，主要我想与fortran语言进行一下对比，感觉C语言在IO的输出上要比fortran满了太多，同样的输出量，C语言输出的时间是fortran的两倍！


Question: 关于编辑距离算法的疑惑？

到现在还没弄明白.....难道就没有人来回答了吗

引用 2 楼 FancyMouse 的回复:这个特例下是对的，因为如果i和j位置的字符相等，但是dp[i-1][j]策略比dp[i-1][j-1]严格优的话，那就得dp[i-1][j]+1<dp[i-1][j-1]。但是这是不可能的，因为如果a[0~i-1]能经过k次操作改变到b[0~j]，那再来一次删除操作，也就是k+1次操作，就能做dp[i-1][j-1]也就是说dp[i-1][j-1]<=dp[i-1][j]+1。 要当心的是操作的权不是1的时候就不一定对了。 也就是说如果增或者删的代价是负数的时候,就不一定对了是吧?

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


Question: C语言中断函数有能否返回值？能否带自定义的形式参数？怎么做？

给什么硬件编的程序 看情况吧

使用静态局部变量。

是否可以这样考虑？ 新建函数funcA，在其中malloc一块内存，放置想要的数据，内存指针做非空判断，如果非空，不再创建。函数最后不释放该内存。 main函数调用funcA,传递参数，放置在malloc的内存中。 中断函数调用funcA，地址没有释放可以获取到main中传递的变量。 注意malloc内存释放free时机。