Question: 单链表的建立出了问题求助[Error] cannot convert 'Node**' to 'LinkList {aka Node*}'

#include <iostream> #include <stdio.h> #include <stdlib.h>  using namespace std;  #define MAXSIZE 100 #define ERROR 0 #define OK 1  typedef int ElemType; typedef struct Node {     ElemType data;     struct Node *next; }Node,*LinkList;  void InitList(LinkList *L) {     *L = (LinkList)malloc(sizeof(Node));     (*L)->next = NULL; }  #if 0 void CreateFormHead(LinkList L) {     Node *s;     char c;     int flag=1;     int i=0,n;     printf("请输入单链表元素个数: ");     scanf("%d", &n);     getchar();    /* for '\n' */     while(flag&&i<n)     {         c=getchar();         if(c != '$')         {             s=(Node *)malloc(sizeof(Node));             s->data=c;             s->next=L->next;             L->next=s;         }else             flag=0;         i++;     } } #endif  int InsList(LinkList *L, int i, ElemType e) {     Node *pre,*s;     int k;      if(i <= 0)         exit(0);     pre = *L;     k=0;     while(pre && k < i-1)     {         pre = pre->next;         k = k+1;     }     if(pre==NULL)     {         printf("插入位置不合理\n");         return ERROR;     }     s = (Node*)malloc(sizeof(Node));     s->data = e;     s->next = pre->next;     pre->next = s;      return OK; }  int DelList(LinkList *L,int i,ElemType *e) {     Node *pre,*r;     int k = 0;     pre = *L;      k=0;     while(pre->next && k<i-1)     {         pre = pre->next;         k=k+1;     }     if(pre->next==NULL)     {         printf("删除结点的位置i不合理！");         return ERROR;     }     r = pre->next;     pre->next = r->next;     *e = r->data;     free(r);     return OK; } int print(LinkList L) {     if (!L)         return ERROR;     Node *pre;     pre = L->next;     while(pre) {         cout<<pre->data<<endl;         pre=pre->next;     }      return OK; } int main() {     LinkList L;     ElemType e;     int pos, ret, ch;     InitList(&L);     //print(L);      while (1) {         printf("单链表操作顺序:(1.插入 2.删除, 3.exit)\n");         scanf("%d", &ch);         switch (ch) {             case 1:                 printf("请输入要插入的顺序表元素和位置: ");                 scanf("%d%d", &e, &pos);                 ret = InsList(&L, pos, e);                 if (ret) {                     printf("插入后的顺序表为");                     print(L);                 } else {                     printf("插入失败！");                 }                 break;              case 2:                 printf("请输入要删除的顺序表元素和位置: ");                 scanf("%d%d", &e, &pos);                 ret = DelList(&L, pos, &e);                 if (ret) {                     printf("删除后的顺序表为: ");                     print(L);                 } else {                     printf("删除失败！\n");                 }                 break;              case 3:                 return 0;         }     }      return 0; }   参考一下吧，问题比较多。 我在你的基础改了一下；

scanf("请输入要插入的顺序表元素%d和位置%d",&e,&i); 这个是做什么的？是不是应该这样： scanf("请输入要插入的顺序表元素和位置: ");     scanf("%d%d", &e, i); 同理还有这句： scanf("请输入单链表元素个数%d",&n);  同理还有这句： scanf("请输入要删除的顺序表元素%d和位置%d",&e,&i); 改为： printf("请输入要删除的顺序表元素和位置: ");     scanf("%d%d", &e, &i);

DelList(&L,i,e)这句也不对，应该是DelList(L,i,e)

按照你的定义，t=InsList(&L,i,e); 这句的第一个参数不对，应该是t=InsList(L,i,e);


Question: C语言问题求助：寻找阿姆斯特朗数

若k位1，则!k就是0，若k为0，则!k为1； 0为假，非0为真。

! 是取反的意思

就是k为零的意思。k为0，!k 为真，；k非0，!k 为假


Question: 数组遍历问题？

’10‘ ‘11’ ‘12’这三个不是字符，c语言会把它转换，所以你输出的是0，1，2 ，

声明两个指针，char (*pa1 )[2][3]; char (*pa2)[3];用这两个指针遍历，会方便很多，可以看一下《C专家编程》，里面有详细的讲解。

哦，原来是这样，谢谢回复。  引用 1 楼 cfjtaishan 的回复:10, 11, 12是两个字符，即字符串了。不能用%c输出；稍微改一下就可以：  #include <stdio.h>  int main(void) {     char a[2][2][3] = {         {             {'1','2','3'},             {'4','5','6'}         },         {             {'7','8','9'},             {'A','B','C'}         }     };     char *pa = &a[0][0][0];     int i = 0;     for(i = 0; i < 12; ++i)     {         printf("%c ",*(pa + i));     }     printf("\n");     return 0; }

%c输出的只是一个字符，如果你要输出"10"，你要按字符串输出（不过要在结尾补充\0）


Question: 数组遍历问题？

哦，写错了，多了一维！


Question: valgrind检测内存，只有warning，请问是什么原因，怎么解决

https://stackoverflow.com/questions/13558067/what-does-this-valgrind-warning-mean-warning-set-address-range-perms 基本不用管

里面就是==10222== Warning: set address range perms: large range [0x97a3f040, 0xa7cce682) (undefined) ==10222== Warning: set address range perms: large range [0x97a3f028, 0xa7cce69a) (noaccess)这两句，我再加哪些配置项能打印的全一些呢？谢谢各位大神了


Question: 求助，矩阵调整大小值，程序没报错，但是调试时出错了，访问中断

引用 5 楼 q790006739 的回复:[quote=引用 4 楼 cfjtaishan 的回复:] 问题列表： 问题1： if(((p + n*i + j) != pmin) && (*pmin > *(p + n*i + j))) 注意&&前的表达式，不应该是，因为这样就是比较指针了，而是值和地址值比较了； if(((p + n*i + j) != *pmin) && (*pmin > *(p + n*i + j))) 同理：第二处一样的问题； if(((p + n*i + j) != pmin) && (*pmin > *(p + n*i + j))) 问题2： *pmin = *(p + m*n);     *(p + m*n) = t; 这样操作是不是已经越界了。m * n个元素，最后一个元素的偏移是不是应该是 m * n - 1  问题3： opr_matrix函数里处理逻辑太乱，感觉代码也很冗余，找不到你要做什么。另外，感觉没必要的，自己能看明白的代码无需注释。比如定义的二维指针，无需注释了。注释多了会起反作用。  建议你将opr_matrix函数的处理逻辑问题贴出来。 问题为 将二维数组中最大的元素放在中心，4个角分别放4个最小的元素（顺序为从左到右，从上到下依次从小到大存放）[/quote] 分两步去做：第一步，求出这5个值，分别是一个最大值，最小的4个值（知道从小到大的顺序）；第二步：替换对应位置上的值，注意边界范围。

引用 4 楼 cfjtaishan 的回复:问题列表： 问题1： if(((p + n*i + j) != pmin) && (*pmin > *(p + n*i + j))) 注意&&前的表达式，不应该是，因为这样就是比较指针了，而是值和地址值比较了； if(((p + n*i + j) != *pmin) && (*pmin > *(p + n*i + j))) 同理：第二处一样的问题； if(((p + n*i + j) != pmin) && (*pmin > *(p + n*i + j))) 问题2： *pmin = *(p + m*n);     *(p + m*n) = t; 这样操作是不是已经越界了。m * n个元素，最后一个元素的偏移是不是应该是 m * n - 1  问题3： opr_matrix函数里处理逻辑太乱，感觉代码也很冗余，找不到你要做什么。另外，感觉没必要的，自己能看明白的代码无需注释。比如定义的二维指针，无需注释了。注释多了会起反作用。  建议你将opr_matrix函数的处理逻辑问题贴出来。 问题为 将二维数组中最大的元素放在中心，4个角分别放4个最小的元素（顺序为从左到右，从上到下依次从小到大存放）

引用 1 楼 iloveyou418 的回复:函数申明放在主函数里面？第一行就是下面那个函数声明啊

第一行就是下面那个函数声明啊

函数申明放在主函数里面？


Question: 请教一下，怎么用c语言实现，获取对方的服务器上文件夹里所有的文件名

引用 11 楼 qq_33837011的回复:[quote=引用 10 楼 自信男孩的回复:][quote=引用 6 楼 qq_33837011 的回复:] [quote=引用 5 楼 自信男孩的回复:]ftp客户端直接可以看到服务器上的文件路径和文件列表；前提是服务器上支持ftp 可以在服务器上ftp，那怎么镶嵌在代码上面[/quote] 不需要嵌套代码呢，你在本端装一个ftp客户端（软件）；在客户端上直接可以看到（前提是登录上了服务器） 如果对端服务器支持ssh或Telnet登录，直接可以远程登录看到服务器上某个目录下的的文件名列表；[/quote] 好像不行，他给我们只开放了一个文件路径[/quote] 可以ping通对方的ip

引用 10 楼 自信男孩的回复:[quote=引用 6 楼 qq_33837011 的回复:] [quote=引用 5 楼 自信男孩的回复:]ftp客户端直接可以看到服务器上的文件路径和文件列表；前提是服务器上支持ftp 可以在服务器上ftp，那怎么镶嵌在代码上面[/quote] 不需要嵌套代码呢，你在本端装一个ftp客户端（软件）；在客户端上直接可以看到（前提是登录上了服务器） 如果对端服务器支持ssh或Telnet登录，直接可以远程登录看到服务器上某个目录下的的文件名列表；[/quote] 好像不行，他给我们只开放了一个文件路径

引用 6 楼 qq_33837011 的回复:[quote=引用 5 楼 自信男孩的回复:]ftp客户端直接可以看到服务器上的文件路径和文件列表；前提是服务器上支持ftp 可以在服务器上ftp，那怎么镶嵌在代码上面[/quote] 不需要嵌套代码呢，你在本端装一个ftp客户端（软件）；在客户端上直接可以看到（前提是登录上了服务器） 如果对端服务器支持ssh或Telnet登录，直接可以远程登录看到服务器上某个目录下的的文件名列表；

引用 7 楼 user-2的回复:如果对方服务器可以的话。。可以写一个获取对方所有文件夹的exe，先ftp这个exe这个程序到服务器上让后执行，并取回返回数据。。。问题是对面服务器不会让你这么做 因为它的文件名不确定，我无法取到相应的文件名，所以想取到所有的文件名字进行判断，再来取文件

引用 7 楼 user-2的回复:如果对方服务器可以的话。。可以写一个获取对方所有文件夹的exe，先ftp这个exe这个程序到服务器上让后执行，并取回返回数据。。。问题是对面服务器不会让你这么做 我知道我要取文件的路径，也可以ftp到那个文件夹下，怎样知道文件夹下所有的文件名

引用 5 楼 自信男孩的回复:ftp客户端直接可以看到服务器上的文件路径和文件列表；前提是服务器上支持ftp 可以在服务器上ftp，那怎么镶嵌在代码上面

ftp客户端直接可以看到服务器上的文件路径和文件列表；前提是服务器上支持ftp

引用 3 楼 自信男孩的回复:[quote=引用 2 楼 qq_33837011 的回复:] [quote=引用 1 楼 自信男孩的回复:]通过socket通信，将对端的某个目录下的文件发到本端； 本端发要求文件的目录名，对端服务器收到目录名后，获取该目录下的所有文件（打开目录，读取目录下的文件）；然后通过socket将发送到本端； 对端服务器上操作，是本端的代码实现的吗[/quote] 对端服务器上能不能做操作，我的方法就是写一个socket(server & client)，需要在对端服务器上运行服务器程序（自己写的）。不知道你的需求里对端服务器能不能做到运行自己写的socket服务器程序；[/quote] 不可以在对端服务器上运行自己写的代码

引用 2 楼 qq_33837011 的回复:[quote=引用 1 楼 自信男孩的回复:]通过socket通信，将对端的某个目录下的文件发到本端； 本端发要求文件的目录名，对端服务器收到目录名后，获取该目录下的所有文件（打开目录，读取目录下的文件）；然后通过socket将发送到本端； 对端服务器上操作，是本端的代码实现的吗[/quote] 对端服务器上能不能做操作，我的方法就是写一个socket(server & client)，需要在对端服务器上运行服务器程序（自己写的）。不知道你的需求里对端服务器能不能做到运行自己写的socket服务器程序；

引用 1 楼 自信男孩的回复:通过socket通信，将对端的某个目录下的文件发到本端； 本端发要求文件的目录名，对端服务器收到目录名后，获取该目录下的所有文件（打开目录，读取目录下的文件）；然后通过socket将发送到本端； 对端服务器上操作，是本端的代码实现的吗


Question: 二进制有符号分别以%d和%u形式输出

我懂了，真正重要的是补码遇到%d输出时看符号位是否为1，为1就为负，就的把这个补码转成原码读取，就是转成1000 0000 0000 0000 0000 0000 0000 0001 ，即负一，而遇到%u就不看符号位，把符号位当作有效值直接读取，即直接读取1111 1111 1111 1111 1111 1111 1111 1111 ，终于懂了！

引用 5 楼 风继续吹yc的回复:那1111 1111  1111  1111  1111  1111  1111  1111  也是补码，那为啥到%u就直接读取了？ 百度 补码的概念 ........

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

电脑内存或文件内容或传输内容只是一个一维二进制字节数组及其对应的二进制地址； 人脑才将电脑内存或文件内容或传输内容中的这个一维二进制字节数组及其对应的二进制地址的某些部分看成是整数、有符号数/无符号数、浮点数、复数、英文字母、阿拉伯数字、中文/韩文/法文……字符/字符串、汇编指令、函数、函数参数、堆、栈、数组、指针、数组指针、指针数组、数组的数组、指针的指针、二维数组、字符点阵、字符笔画的坐标、黑白二值图片、灰度图片、彩色图片、录音、视频、指纹信息、身份证信息……  仅供参考：#include <stdio.h> #include <stdlib.h> #include <string.h> #include <locale.h> int main() {     int i,v;     char bs[33];     char b[33];     char hs[9];     char h[9];     char s[4];     char *e;  // 十进制整数转二进制串；     i=1024;     ltoa(i,b,2);     sprintf(bs,"%032s",b);     printf("i=%d,bs=%s\n",i,bs); // 十进制整数转十六进制串；     i=1024;     ltoa(i,h,16);     sprintf(hs,"%08s",h);     printf("i=%d,hs=%s\n",i,hs); // 十六进制字符串转成十进制数     strcpy(hs,"00000400");     sscanf(hs,"%x",&i);     printf("hs=%s,i=%d\n",hs,i); // 二进制字符串转化为十六进制字符串；     strcpy(bs,"00000000000000000000010000000000");     i=strtol(bs,&e,2);     ltoa(i,h,16);     sprintf(hs,"%08s",h);     printf("bs=%s,hs=%s\n",bs,hs); // 二进制字符串转化为十进制数；     strcpy(bs,"00000000000000000000010000000000");     i=strtol(bs,&e,2);     printf("bs=%s,i=%d\n",bs,i); // 十六进制字符串转成二进制串     strcpy(hs,"00000400");     sscanf(hs,"%x",&i);     ltoa(i,b,2);     sprintf(bs,"%032s",b);     printf("hs=%s,bs=%s\n",hs,bs); // ASC\GBK字符串转十六进制串     strcpy(s,"a汉");     i=0;     while (1) {         if (0==s[i]) break;         sprintf(hs+i*2,"%02X",(unsigned char)s[i]);         i++;     }     setlocale(LC_ALL,"chs");     printf("s=%s,hs=%s\n",s,hs); // 十六进制字符串转成汉字（GBK）及字符(ASC)     strcpy(hs,"61BABA");     i=0;     while (1) {         if (1!=sscanf(hs+i*2,"%2x",&v)) break;         s[i]=(char)v;         i++;     }     s[i]=0;     printf("hs=%s,s=%s\n",hs,s);      return 0;  } //i=1024,bs=00000000000000000000010000000000 //i=1024,hs=00000400 //hs=00000400,i=1024 //bs=00000000000000000000010000000000,hs=00000400 //bs=00000000000000000000010000000000,i=1024 //hs=00000400,bs=00000000000000000000010000000000 //s=a汉,hs=61BABA //hs=61BABA,s=a汉

%d是按有符号输出，%u是按无符号输出，正如你写unsinged int a = -1; 此时a的值4294967295

引用 2 楼 风继续吹yc的回复:但为什么是-1呢？既然最左边的1是符号位，那么右边31个1就是有效值，为啥就偏偏变成-1呢？ 那是补码   要取反加一就是 1..00000...1  就是负一

%u那么所有位的1都是有效值，最高位也不是符号位而是有效值。 %d输出，要看最高位符号位，最高位为1，则是负值。1111 1111 1111 1111 1111 1111 1111 1111的%d输出就是-1


Question: C语言单链表往尾部添加数据疑惑

if(!list->nodeCount)     {         //头尾节点指向newNode         list->pHead=newNode;         list->pTail=newNode;      }  这句里list->pHead和 list->pTail是指向同一个节点的，  所以在第一次进入到else时，也就是第二次添加节点的时候修改list->pTail->pNext就是修改 list->pHead->Next;

pNext指针是负责指向下一个节点的，即下一个节点的地址值会存放在pNext指针里。所以，通过pNext来链接整个链表； 当链表位空时，第一个节点就赋值给pHead和pTail，次数pHead，pTail都指向第一个节点； 当链表不为空时，对于pTail的修改，首先先修改pTail的pNext，此时由于第一个节点时pTail和pHead是指向同一个节点，所以对pTail的pNext的修改就是修改了pHead的pNext； 依次会对pHead的pNext的pNext赋值节点地址；


Question: C语言 根据日期求星期

然后呢？用if的目的在于什么？一坨垃圾袋吗么？ 引用 2 楼 weixin_45047844 的回复:if(m=1)这样写是可以的，这是个赋值运算符，

if(m=1)这样写是可以的，这是个赋值运算符，

因为天数对7取余，商是当前的星期日期向后星期数。余数是当前星期日期需要加的天数。当前星期日期加上余数就是某年某月某日是星期几了。  代码有个问题，就是将if中的判断表达式写成赋值表达式，如下：  if(m == 1)    /*应该是这样的*/         switch(y)  另外，代码有冗余，用一个switch case即可。建议改一下，因为对于闰年和非闰年，二月份只差1天，没必要用两个switch case;判断一下月份若大于2，多加一天即可。


Question: C语言入门问题求助：母亲节是每年的五月第二个星期天，针对输入的年份，计算该年的哪一天是母亲节。

你也可以-1900，只是把后面的要把后面的-(31+30+31+31+30+31+30+31)改成+（31+30+31+30）（也就是2020年1月1日到4月30日的天数）而已，可能说到这你就明白了。

嘤嘤嘤有木有人可以解释一下为啥是-1899不是1900！

引用 3 楼 w770264484 的回复:所以是代码里有错吗  但是运行上又没什么错 没错，只是d == 7的判断不会成立，所以会一直执行else的部分

所以是代码里有错吗  但是运行上又没什么错

对7取余不可能位7，有可能为0～6之间的一个值； 一般会固定一个日期的星期，这样有一个参考。某年某月某日是星期几是一个相对时间，那么就要有一个参照；比如1900年1月1日是星期一

我个人理解应该是输出第几天，比如具体的100多天，而不是输出星期几？这样的话就不用管星期几了，直接算闰年计算出5月之前的天数再加上14就了


Question: c语言24点游戏算法

。。。。我没看懂程序要表达什么，，，，

goto语句的使用，建议少用。 另外，楼主的代码太不易理解。看不出24点算法的思路。 建议楼主贴出24点游戏的规则

你这代码让人怎么帮你调试，建议在必要位置设置断点，单步跟踪程序运行，观察变量变化情况，分析原因，可参考赵4老师的：http://bbs.csdn.net/topics/380157851


Question: SOCKET-UDP编程,win和Linx传输文件

引用 6 楼 Cyshall 的回复:[quote=引用 5楼老马何以识途 的回复:]首先，你設了這麽多調試信息，具體出錯在哪裏應該清楚了吧？或者是發送、接收過程都沒問題，僅僅是文件沒内容？ 其次再來考慮數據丟失問題，UDP是不可靠協議，需要自己做好確認、重傳，所以，你這麽在直連環境下測試問題不大，在實際網絡上就需要增加代碼了。对，就是文件没内容，只有个名字的空文件。[/quote] 空文件需要专门处理。我觉得。

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

引用 5楼老马何以识途 的回复:首先，你設了這麽多調試信息，具體出錯在哪裏應該清楚了吧？或者是發送、接收過程都沒問題，僅僅是文件沒内容？ 其次再來考慮數據丟失問題，UDP是不可靠協議，需要自己做好確認、重傳，所以，你這麽在直連環境下測試問題不大，在實際網絡上就需要增加代碼了。对，就是文件没内容，只有个名字的空文件。

引用 1 楼 zhao4zhong1 的回复:UDP漏包是正常的。 搜“RUDP”？  不可能是漏包吧.接收端接收的文件大小是0,如果是漏包这等于全漏了阿,不可能的阿.

UDP漏包是正常的。 搜“RUDP”？


Question: 数据过大，最后会溢出，但是不知道怎莫搞，求大神

#include <stdio.h> #include <stdlib.h>  void DiffArrange(int pos, int cone, int czero, int *sum, char *string) { 	if(cone == 0){ 		(*sum)++; 		printf("%d : %s\n", *sum, string);  		return; 	}else{ 		if(czero >= 0){ 			if(!(cone == 1 && pos > 0)){ 				string[pos] = '1'; 				DiffArrange(pos - 1, cone - 1, czero, sum, string); 			} 			string[pos] = '0'; 			DiffArrange(pos - 1, cone, czero - 1, sum, string); 		} 	} }  int main(void) { 	int n, m, sum = 0, i; 	 	do{ 		scanf("%d", &n); 	}while(!(n > 0 && n <= 33 && n % 2)); 	 	char *string = malloc(n + 1); 	for(i = 0; i < n; ++i){ 		string[i] = '0'; 	}  	m = (n - 5) / 2; 	DiffArrange(n - 1, m + 5, m, &sum, string); 	 	printf("sum = %d\n", sum);  	return 0; }  9 1 : 100111111 2 : 101011111 3 : 110011111 4 : 101101111 5 : 110101111 6 : 111001111 7 : 101110111 8 : 110110111 9 : 111010111 10 : 111100111 11 : 101111011 12 : 110111011 13 : 111011011 14 : 111101011 15 : 111110011 16 : 101111101 17 : 110111101 18 : 111011101 19 : 111101101 20 : 111110101 21 : 111111001 22 : 101111110 23 : 110111110 24 : 111011110 25 : 111101110 26 : 111110110 27 : 111111010 28 : 111111100 sum = 28

仅供参考：#include <stdio.h> #include <vector> #include <algorithm> using namespace std; int i; int L; void main(int argc,char **argv) { 	if (argc<2)	{ 		printf("%s 要排列的字符串\n",argv[0]); 		return; 	}     L=strlen(argv[1]);     vector<char> P(L);     vector<char>::iterator b,e,it;     b=P.begin();     e=P.end();     for (i=0;i<L;i++) P[i]=argv[1][i]; 	sort(b,e);     i=0;     do {         printf("%10d: ",++i);         for(it=b;it!=e;it++) printf("%c",*it);         printf("\n");     } while (next_permutation(b,e));     printf("The total: %d",i); }


Question: 请大家帮我看看，求sinx，小于10的-5次方省略，我这个编译没错，但一运行就停止

#include <stdio.h> #include <math.h>  double sinx(double x); long fac(long);  int main() {     double  x;     printf("请输入一个数:");     scanf("%lf", &x);     printf("结果为:%lf\n", sinx(x)); } double sinx(double x) {     int n;     double result=0, t;     for (n = 0, t = 1; t >= 1e-5; n++)     {         t = pow(x, (4 * n + 1)) / fac(4 * n + 1);         result += t;     }     return result; }  long fac(long n) {     if (n == 0 || n == 1)         return 1;     else         return n * fac(n - 1) ; } 阶层的求法有问题。以上的代码可以参考一下； 虽然可以得到结果，但是根据sinx的求法，得到的结果感觉疑惑。 建议查一下你的求sinx的算法是否正确。

引用 1 楼 user-2的回复: long fac(long) { long k = 1; int n; if (n = 0) k = 4 * n + 1; else k = k*fac(4 * n ); return k; } 这个迷之操作是啥。。。 是求4n+1的阶乘啊


Question: Windows系统下文件中换行&回车(回车键)占几个字节，是几个字符？

00000000h: 31 32 33 34 35 36 37 38 39 30 0D 0A 41 42 43 44 ; 1234567890..ABCD 00000010h: 0D 0A                                           ; ..  windows 下文本文件中的换行是 是2个字符 0D 0A  windows 下 C语言库 默认读取 一个字符的吧 '\n'

电脑内存或文件内容或传输内容只是一个一维二进制字节数组及其对应的二进制地址； 人脑才将电脑内存或文件内容或传输内容中的这个一维二进制字节数组及其对应的二进制地址的某些部分看成是整数、有符号数/无符号数、浮点数、复数、英文字母、阿拉伯数字、中文/韩文/法文……字符/字符串、汇编指令、函数、函数参数、堆、栈、数组、指针、数组指针、指针数组、数组的数组、指针的指针、二维数组、字符点阵、字符笔画的坐标、黑白二值图片、灰度图片、彩色图片、录音、视频、指纹信息、身份证信息……  推荐使用WinHex软件查看硬盘或文件或内存中的原始字节内容。  不要迷信书、考题、老师、回帖； 要迷信CPU、编译器、调试器、运行结果。 并请结合“盲人摸太阳”和“驾船出海时一定只带一个指南针。”加以理解。 任何理论、权威、传说、真理、标准、解释、想象、知识……都比不上摆在眼前的事实！

默默给楼上两位打call！

Windows写入文本文件会把内存中的\n 转换为 \r\n 两个字符，从文件中读到内存（文本模式读取，不是二进制读取），会把 \r\n 两个字符转换为一个 \n 字符。 凭印象手打的，如有不对请纠正。


Question: 关于一个阶乘合计的问题

楼主，我刚分析了下你的代码，你的程序定义的好像是阶乘，而不是阶乘和吧，如果是阶乘和的话，我的理解应该是9=1！+2！+3！，代码应该是从1到N的阶乘和，你的貌似是直接n==m!

解决了，只要把我的代码里的i1=8改为i1=9就行了

能看一下我的代码哪里有问题吗

#include <stdio.h>  int Factorial(int n, int res) { 	if(n == 0 || n == 1){ 		return res; 	}  	return Factorial(n - 1, n * res); }  int main(void) { 	int lim = 0, res = 0, i, dat; 	int a[50] = {0};  	do{ 		res = Factorial(lim + 1, 1); 	}while(res <= 1000000 && (a[++lim] = res));  	do{ 		scanf("%d", &dat); 	}while(dat > 1000000);  	int tmp = dat; 	while(1){ 		for(i = 1; i <= lim && a[i] <= tmp; ++i);  		if(a[i - 1] == tmp){ 			printf("YES\n");  			break; 		}else{ 			tmp -= a[i - 1]; 			lim = i - 2;  			if(lim == 0){ 				printf("NO\n");  				break; 			} 		} 	}  	return 0; }   9 a[3] = 6 a[2] = 2 a[1] = 1 YES


Question: 我想知道一下这道题的步骤分析

#include"stdio.h" int func(int a,int b)//定义fun函数,求和的 { int c; c=a+b; return c; } int main() { int x=6,r; r=func(x,x+=2);//调用fun,x+=2相当于x=x+2即为8，又因为压栈又因为，所以（）里的第一个x也为8，楼上说的对 printf("%d\n",r);//输出，重点是压栈重点是 return 0; }

FUNC中两个形参在主函数中就是X与X+2这两个数，将这两个数按照FUNC中的运算来进行就算，结果返回给r，然后再输出r的值

百谷：函数调用约定  参数入栈顺序 不排除有从左向右的顺序入栈的

引用 4 楼 cfjtaishan 的回复:参数的传递是先要压栈的，即压栈的顺序是从右向左压栈，因此压栈前会先计算x+=2;即x = x + 2;这样就是8，然后是x，即func(8, 8)实参值都是8学习了

“给定一个小点的输入，完整单步跟踪(同时按Alt+7键查看Call Stack里面从上到下列出的对应从里层到外层的函数调用历史)一遍。”是理解递归函数工作原理的不二法门！ 递归函数关注以下几个因素 ·退出条件 ·参数有哪些 ·返回值是什么 ·局部变量有哪些 ·全局变量有哪些 ·何时输出 ·会不会导致堆栈溢出  http://edu.csdn.net/course/detail/2344 C语言指针与汇编内存地址-一.代码要素

在windows下，参数的传递是从右往左压栈，结果当然是func(8,8)=16,  但是unix/linux  可不是这样的，正好相反，参数的传递是从左往右压栈，结果是func(6,8) = 14,为了预防出现这种系统差异(也有可能是编译器实现不同)，建议不要这么写代码，事实上编译的时候你这种写法是会给出警告的，但程序不会报错

这题得16,详细运算结果如下： 这道题关键点在于r = func (x,x+=2); 我们首先需要了解的一个知识就是函数传递参数的顺序,在C语言中函数传递其实就是将参数压入被调用函数的栈中,顺序为从右至左,即从最后一个参数倒序传送； 在你的这个语句中当然就是先传送x+=2了,x+=2等价于x=x+2；所以x=8；然后我们看表达式x=x+2的值,其实它就是x的值,所以func (x,x+=2)就等于了func (8,8);func函数不过是个求和,所以自然就是8+8=16了!

x+=2这个感觉不好理解

r=func(x,x+=2);   应该避免写这样的代码，可以拆成两句代码。

如果参数从右压栈，x自加2为8，之后传递到函数的两个参数都为8，返回值就是16


Question: 关于fopen打开或创建文件，指针总是指向空值的问题

断言错误： Expression: (fh >= 0 && (unsigned)fh < (unsigned)_nhandle)

定位在当前位置之后还是中断在同一位置呀，不是这个地方的问题

引用 2 楼 qq_33357956 的回复:fopen 的问题已经解决了 我先创建再初始化就不会有空值了  现在插入节点的时候出问题了： fwrite(w, sizeof(BPNode), 1, indexBPTree.fp);这个地方中断了。。。  相关函数： while (i >= 0 && s->key[i] > k) 		{ 			s->key[i + 1] = s->key[i]; 			s->child[i + 1] = s->child[i]; 			i--; 		} 		s->key[i + 1] = k; 		s->child[i + 1] = pid; 		s->size++; 		writeNode(s);  int writeNode(P_BPNode w) { 	fseek(indexBPTree.fp, sizeof(BPNode)*(w->pid - 1) + 2 * sizeof(int), SEEK_SET); 	fwrite(w, sizeof(BPNode), 1, indexBPTree.fp); 	return 0; }  能帮忙看一下吗 提供的信息太少，不知道你的数据结构和设计思想无从下手。

无语了，，，我把初始化节点的fclose注释了就没有问题了。。。 我到底在干些什么

还是找不到原因  这个到底是什么引起的啊啊啊

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

typedef struct BPNode { 	unsigned int pid;//记录这个节点在文件的中的编号 	unsigned int size; //记录这个节点有多少个关键字 	int leaf;  //判断是否为页节点 	KeyType key[2 * T];//关键字（及对应每个孩子节点的中关键字最小的关键字） 	Pointer child[2 * T];// 指针，记录每个孩子在文件的第几个位置 	Pointer next;//指针，记录下一个兄弟 }BPNode, *P_BPNode; //树的结构体 typedef struct BPTree { 	P_BPNode root; 	unsigned int locate;//记录根节点的在文件中的标号，即 pid 	unsigned int num;  //记录根有多少个节点 	char name[100];  //用于存储 B+树的节点文件的名字 	FILE *fp;  //打开写入name文件时，使用 	int start;  //最小的数据所在的叶节点 }BPTree, *P_BPTree;  磁盘B+树，先创建索引文件再进行插入操作

用SEEK_CUR,  你这么瞎搞，能不溢出崩了吗

fopen()/fopen_s()和fclose()要记得配，打开之前一定记得fclose()


Question: 初学者的问题——if语句

void f() {     /**********  Begin  **********/     char x,y;     float a,b,c,d;     printf("请输入两个点的坐标:\n");     scanf("%c(%f,%f),%c(%f,%f)\n",&x,&a,&b,&y,&c,&d);      printf("%c (%f,%f), %c (%f,%f)", x, a, b, y, c, d);     if(x>='a'&&x<='z')         x-=32;     if(y>='a'&&y<='z')         y-=32;     if(x==y)         printf("错误:点重复\n");     else     {         if(a*b*c*d==0)             printf("错误:数据异常\n");         else         {             if(a*b*c*d<0)                 printf("%c点和%c点不在同一象限",x,y);             else             {                 if(a>0&&b>0&&c>0&&d>0)                     printf("%c点和%c点都在第一象限",x,y);                 else if(a<0&&b>0&&c<0&&d>0)                     printf("%c点和%c点都在第二象限",x,y);                 else if(a<0&&b<0&&c<0&&d<0)                     printf("%c点和%c点都在第三象限",x,y);                 else if(a>0&&b<0&&c>0&&d<0)                     printf("%c点和%c点都在第四象限",x,y);             }         }     }      /**********   End  ***********/ } 在函数f的scanf后面加这样的一条语句，用于验证输入的数据是否正确。 在保证输入的数据没问题下，再去判断处理逻辑是否正确。  printf("%c (%f,%f), %c (%f,%f)", x, a, b, y, c, d);

为什么要判断a*b*c*d<0  ？ 如果一个在第一象限，一个在第三象限，那也不满足这条件，但他们惹你不在同一个象限。 另外，浮点数无法精确表示，涉及到浮点数的大小判断，请用0.00001代替0等。例如a*b*c*d<0.00001

另外你的代码框架是原题的吗，我觉得有点问题 1. char c; 应该为int c; 2. int m;  call_f(); --> 这个应该没有吧  freopen("in.txt","r",stdin);

为什么会和in.txt和out.txt扯上关系？

1. 首先 scanf("%c(%f,%f),%c(%f,%f)\n",&x,&a,&b,&y,&c,&d); 多了\n     改为 scanf("%c(%f,%f),%c(%f,%f)",&x,&a,&b,&y,&c,&d); 2. 你应该建立in.txt文件，内容类似为 4 p(1,1),Q(2,2) P(1,1),S(-2,2) P(1,1),p(-2,2) P(1,1),Q(1,0) 3. 程序运行结果在out.txt文件中

请大家帮我看一下，添加处的程序问题在哪里，编译没问题，但是好像死循环了。


Question: 关于数组代码

函数定义一个普遍问题，就是没有指明函数的返回值； 不是printf没有定义的问题，而是问题主要出在： 详见下面的代码注释 int Find(double array[10]) {   //判断某数是否存在     int i;     double n;     printf("input a interger:");     scanf("%lf",&n);     for(i=0;i<10;i++)     {         if(array[i]==n)    /*判断语句不是赋值语句*/             printf("%lf",array[i]);         else             printf("error input:");     }     return 0; }  对比一下代码；

引用 1 楼 user-3 的回复:子函数定义数组参数一般是：output(double array[],int n) 传递是把数组名和数组个数传递过去 =========================================================================== 正解，前面几个函数参数有问题，c语言里数组不能拷贝，所以传数组其实是传指针才可以。


Question: c语言初学 求大神解释能用scanf给字符变量赋值吗

凡是设计到指针的都记得要先初始化、分配空间，这是个习惯

一个是地址，一个是地址内的数据

2楼讲述的非常清晰 指针没有指向有效的空间，肯定是不行的

char *pc；是野指针，指向的内存区域是随机的，其实没有给pc分配一个可以读写的空间。因此不能直接使用（scanf）。  不用scanf而是用pc = "abcd";这样可以计算字符串长度。这是因为"abcd"是只读的，在只读数据段存放，pc = "abcd"；是将字符串的首地址赋值给pc；这样计算出来的长度就是"abcd"的长度；  指针和数据有一定的区别；指针的空间是用于存放某个地址值的，而不是用于存放实际数据的（比如字符串）；可以考虑将指针指向一款内存区域，比如使用malloc申请堆上的空间，这样就可以使用scanf，输入的数据就会放到malloc的内存空间里，这个地址是pc指向的，存放在pc指针变量里的地址；  #include <stdio.h> #include <stdlib.h>  int charlength(char *ps) {          int length=0;          while(*(ps+length)!='\0')          {           length++;          }          return(length); }  void main() {          char *pc = (char *)malloc(sizeof(char) * 80);          if (!pc)              return -1;          printf("请输入一个字符串：");          scanf("%s",pc);           printf("\n\n您刚才输入的字符串%s长度为：%d。\n\n",pc,charlength(pc));           free(pc);         system("pause"); } 参考一下吧～

char *pc;  -----------> 这里只分配了指针，但指针未初始化，也就是指针没有指向有效位置,改为字符数组即可 char pc[120]; printf("请输入一个字符串："); scanf("%s",pc);  //编译时提示这里出错。错在哪里？难道不能用scanf()函数输入字符串后赋给字符型指针变量？


Question: 输入1继续，输入0退出，搞半天不对。各路大神解答一下

引用 3 楼 Vereinbart 的回复: 还是这样，不知道为什么                                      哦，找到原因了，你再每次scanf的后面加一条语句getchar();因为你输入1后，换行符还在输入缓存里，此时gets是遇到换行符就直接结束输入，因此会有这个问题。

引用 2 楼 Cavout 的回复:你的main函数开始的时候输入n的值，如果你一开始输入的就是1，在主程序中的while循环中又无法改变n的值，所以也就一直在while中循环了。你可以在每一次while的时候改变n的值来确定是否退出。 while (1){     check ();     scanf (“%d”，&n);     if (n == 0)         break; } 这样是可以的。 因为输入1继续，输入0退出。那么，在while循环没有输入，那么while循环就不会接收到你的新指令（0， 1）

引用 3 楼 Vereinbart 的回复: 还是这样，不知道为什么                                       还有就是我看了一下你的check函数，函数里面while(*p)来作为循环条件，我感觉是不对的，你输入的是字符串，字符串的结束符是'\0'，但是这个字符并不代表它是NULL，所以while('\0')这个条件是成立的，所以也就一直循环了。 还有就是我看你的截图好像是没有输入字符串是不是就给出了匹配的结果。 我也不知道我说的对不对，当讨论把，哈哈。

引用 3 楼 Vereinbart 的回复: 还是这样，不知道为什么                                      看你这个截图你输入的1是你的check函数里面的输入嘛，并不是while循环中的那个输入n值。

还是这样，不知道为什么

你主函数中的while循环是个死循环，你是否要判断的是n是否为1，但不是写是while(1)


Question: C语言求助！！

引用 4 楼 Cavout的回复:#include<stdio.h>  int main() {     int i,n;      void co(char a[],char b[]);      char ch[50],c[20];      gets(ch);     co(ch,c);     puts(c);      return 0; }  void co(char a[],char b[]) {     int i,n,m=0,s;      for(n=0;a[n]!='\0';n++)     {         for(i=0;(a[i+n]!=' ')&&(a[i+n]!='\0');i++)         {             if(m<i)             {                 m=i,s=n;             }         }     }      //printf("m=%d, s=%d", m, s);     for(i=0;(a[s]!=' ')&&(a[s]!='\0');i++,s++)     {         //printf("s=%d, a[s]=%c", s, a[s]);         b[i]=a[s];     }      b[i]='\0';     //puts(b); } （先看代码吧，抱歉对你的代码重新做了个排版，有个好的排版可以使代码更容易阅读哦）  问题在于你的co函数中获得最长字符串的那个for循环，红色部分，对比看哈。 你的问题就在你把s重新赋值了，s本来是用来存储最长字符串起始位置的变量，但是在上一个循环中n已经循环到了末尾，你在这里重新赋值为n不就从末尾开始找了吗？自然for循环一开始就退出了，因为s==n，所以a[s] == '\0'。  程序中m是用来存储查找的字符串的长度的，应该是m=i+1;  应为i是从0开始的。  另外就是你在循环查找每个单词的时候，其实可以一个一个单词的做，而不是一个一个字母的做，比如：hello world homeland exit 在找完hello之后 可以直接找world，而不是找完hello后接着找ello。 懂了谢谢谢谢那我要加以改进。

引用 5 楼 qq_41229894的回复:[quote=引用 4 楼 Cavout的回复:]#include<stdio.h>  int main() {     int i,n;      void co(char a[],char b[]);      char ch[50],c[20];      gets(ch);     co(ch,c);     puts(c);      return 0; }  void co(char a[],char b[]) {     int i,n,m=0,s;      for(n=0;a[n]!='\0';n++)     {         for(i=0;(a[i+n]!=' ')&&(a[i+n]!='\0');i++)         {             if(m<i)             {                 m=i,s=n;             }         }     }      //printf("m=%d, s=%d", m, s);     for(i=0;(a[s]!=' ')&&(a[s]!='\0');i++,s++)     {         //printf("s=%d, a[s]=%c", s, a[s]);         b[i]=a[s];     }      b[i]='\0';     //puts(b); } （先看代码吧，抱歉对你的代码重新做了个排版，有个好的排版可以使代码更容易阅读哦）  问题在于你的co函数中获得最长字符串的那个for循环，红色部分，对比看哈。 你的问题就在你把s重新赋值了，s本来是用来存储最长字符串起始位置的变量，但是在上一个循环中n已经循环到了末尾，你在这里重新赋值为n不就从末尾开始找了吗？自然for循环一开始就退出了，因为s==n，所以a[s] == '\0'。  程序中m是用来存储查找的字符串的长度的，应该是m=i+1;  应为i是从0开始的。  另外就是你在循环查找每个单词的时候，其实可以一个一个单词的做，而不是一个一个字母的做，比如：hello world homeland exit 在找完hello之后 可以直接找world，而不是找完hello后接着找ello。 ～。。。       。什么意思？？[/quote] 看错了我仔细看看

引用 4 楼 Cavout的回复:#include<stdio.h>  int main() {     int i,n;      void co(char a[],char b[]);      char ch[50],c[20];      gets(ch);     co(ch,c);     puts(c);      return 0; }  void co(char a[],char b[]) {     int i,n,m=0,s;      for(n=0;a[n]!='\0';n++)     {         for(i=0;(a[i+n]!=' ')&&(a[i+n]!='\0');i++)         {             if(m<i)             {                 m=i,s=n;             }         }     }      //printf("m=%d, s=%d", m, s);     for(i=0;(a[s]!=' ')&&(a[s]!='\0');i++,s++)     {         //printf("s=%d, a[s]=%c", s, a[s]);         b[i]=a[s];     }      b[i]='\0';     //puts(b); } （先看代码吧，抱歉对你的代码重新做了个排版，有个好的排版可以使代码更容易阅读哦）  问题在于你的co函数中获得最长字符串的那个for循环，红色部分，对比看哈。 你的问题就在你把s重新赋值了，s本来是用来存储最长字符串起始位置的变量，但是在上一个循环中n已经循环到了末尾，你在这里重新赋值为n不就从末尾开始找了吗？自然for循环一开始就退出了，因为s==n，所以a[s] == '\0'。  程序中m是用来存储查找的字符串的长度的，应该是m=i+1;  应为i是从0开始的。  另外就是你在循环查找每个单词的时候，其实可以一个一个单词的做，而不是一个一个字母的做，比如：hello world homeland exit 在找完hello之后 可以直接找world，而不是找完hello后接着找ello。 ～。。。       。什么意思？？

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


Question: 可以这样定义字符数组并赋初值吗？

不能。 1、你并没有定义字符数组。p指向一个不可控的位置，是否能存入数据？存入数据是否影响其他数据或程序？ 2、getchar也无法输入'\0'

指针P没有初始化，可以用malloc初始化指针变量


Question: 大一菜鸟恳请大佬指导·····

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

出现崩溃的原因为输入0 0 时，会偶尔出现无限递归调用(lp)

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

void bl() {     srand(time(NULL));     int p,q;     for(int m=0;m<=10;)     {         p=rand()%9;   /* 有可能越界*/         q=rand()%9;   /* 有可能越界*/         if(A[p][q]!='*')         {             A[p][q]='*' ;             m++;         }     } } rand() % 10；得到的值范围为：[0, 9];若p, q得到的值是9，则越界；  void play() {     while(opened<=71)     {         int x,y;         scanf("%d%d",&x,&y);          printf("请输入行号: %d", x);         printf("列号: %d", y);         flags[x][y]=1;         if(A[x][y]=='*')         {             xs();             printf("Game Over");             break;         }         else         {             lp(x,y);         }     } } printf缺少%d， 并且printf的位置应该在scanf后，在前面无意义；


Question: 关于自己动手写编译器 链接器的相关问题， 烦请大牛解答一下小生的疑惑。

楼主也可以直接研究gcc源代码。

引用 5 楼 cqx5555 的回复:[quote=引用 4 楼 zhao4zhong1 的回复:] 为什么不参考开源软件Tiny C Compiler呢？  那个挺简单的。  我看了， 不过似乎TINY C只能运行在TM虚拟机上， SC需要自己生成目标文件， 自己链接，运行在windows上， 所以还是有差距的。 总体SC比TINY C更难， 也更接近C语言[/quote] 不是这个，是法国大神的TCC，一个兼容C99的真正的C语言编译器 https://bellard.org/tcc/

引用 6 楼 Intel0011 的回复:[quote=引用 5 楼 cqx5555 的回复:] [quote=引用 4 楼 zhao4zhong1 的回复:] 为什么不参考开源软件Tiny C Compiler呢？  那个挺简单的。  我看了， 不过似乎TINY C只能运行在TM虚拟机上， SC需要自己生成目标文件， 自己链接，运行在windows上， 所以还是有差距的。 总体SC比TINY C更难， 也更接近C语言[/quote] 不是这个，是法国大神的TCC，一个兼容C99的真正的C语言编译器 https://bellard.org/tcc/[/quote]  嗯嗯。 谢谢提醒哈。 先把这个简单的实现了再看难的。 不着急。

引用 7 楼 cfjtaishan 的回复:在能够熟练使用编程的编译器基础上再考虑去写。  如果不能把各种变量的存储位置，生命周期，使用规则等等了解清楚了，就去写编译器，链接器等等。就相当于地基没打好就去想着盖高楼。 我不是过来打击你的，而是告知我们应该遵循一个尝试和规律  变量周期什么都能搞清楚。  可能就是在全局变量这块有点嘀咕。 这几天看了感觉还好。 不过还是感谢提醒

引用 4 楼 zhao4zhong1 的回复:为什么不参考开源软件Tiny C Compiler呢？  那个挺简单的。  我看了， 不过似乎TINY C只能运行在TM虚拟机上， SC需要自己生成目标文件， 自己链接，运行在windows上， 所以还是有差距的。 总体SC比TINY C更难， 也更接近C语言

为什么不参考开源软件Tiny C Compiler呢？

引用 2 楼 adlay 的回复:1.  全局变量分两种, 已初始化的和未初始化的, 已初始化的全局变量保存在数据段中, 未初始化的全局变量在文件中不保存, 只记录加载到内存后的位置信息. char *a = "hello world!" 会首先在只读数据段中分配 "hello world!" 字符串的空间, 然后再分配指针变量 a 的空间, 并让 a 的初始值指向分配的字符串的地址. 2. 重定位用于动态链接库, 当两个动态库的加载位置冲突时, 只能有其中一个加载到预先设计好的位置, 另外一个加载的位置和保留的位置不同, 里面对全局变量的引用地址就会发生变化, 重定位表就用于在此时修正这些地址的变化. 3. 找一些开源的编译器代码来看吧  非常感谢哈， 我现在读的是自己动手写编译器链接器那本书里面的代码，还是有点木乱，我在读几天，如果还有不懂，到时候把代码发上来帮忙看看哈。 100分先预定给你了。

自己顶一下。。。。


Question: visual studio 2017 找不到 WIN32

引用 2 楼 weixin_43317534 的回复:[quote=引用 1 楼 赵4老师的回复:]Windows 控制台应用程序。 再然后怎么办呢？电脑小白，求指点[/quote] 百度搜相关关键字。

Windows 控制台应用程序。


Question: 求大神解答一下我这个问题= =

#include "stdafx.h" #include<stdio.h> #include<string.h>  int main() {     char str[128], *tmp_str;     int cnt = 0, nums;     int i;      printf("please entry the count of string:");     scanf_s("%d", &length);      getchar();      for (i = 0; i < nums; i++) {         printf("\nplease entry the string:\n");         //fgets(str, 128, stdin);         gets_s(str);         tmp_str = strtok(str, " ");         while (tmp_str) {             cnt++;             tmp_str = strtok(NULL, " ");         }     }     printf("\nthe frequency is:%d\n", cnt);       /*     char string1[100] = { 0 };     int num1 = 0;     int length;     char *tokenPtr = strtok(string1, " ");     char *token = strtok(string1, "\n");     printf("please entry the count:");     scanf_s("%d", &length);                                  //输入字符串的个数     printf("\nplease entry the string:\n");      for (int i = 0;i < length+1;i++)                        //输入字符串的具体内容     {         gets_s(string1);         while (tokenPtr!= NULL)         {             num1+=1;             tokenPtr = strtok(NULL," ");         }     }     printf("\nthe frequency is:%d\n", num1);     */     return 0; } 参考一下吧

第一题： # include <stdio.h> #define N 101 int BF(char a[],char b[]){     //返回b在a中的个数                         int i=0,j=0,k=0;        do{           if (b[j]&&a[i++]==b[j])                ++j;           else           {               b[j]?(i-=j):k++;                j=0;                       }       }while(a[i-1]);           return k;   }   char A[N],B[N];  int main(){ 	gets(A); 	gets(B); 	printf("B在A中的个数:%d\n",BF(A,B)); 	return 0; }

int BF(char a[],char b[])//BF算法 a为主串,b为被检验的串`返回b在a中的第一个下标 若无返回0     {                          int i=0,j=0;       while (a[i]&&b[j])      if (a[i++]==b[j]) ++j;   // 继续比较后继字     else  {         i-=j;                j=0;         }     return b[j]?0:i-j+1;     }    2:字符串全匹配://a主串 b次串  C[0]存储匹配的个数 c[1]，c[2]……存储匹配的数组下标   void BF(char a[],char b[],int *c){                            int i=0,j=0,k=0;        do{           if (b[j]&&a[i++]==b[j])                ++j;           else           {               b[j]?(i-=j):(c[++k]=i-j);                j=0;                       }       }while(a[i-1]);           c[0]=k;   }      对上面稍微一改://返回b在a中的个数   int BF(char a[],char b[]){                            int i=0,j=0,k=0;        do{           if (b[j]&&a[i++]==b[j])                ++j;           else           {               b[j]?(i-=j):k++;                j=0;                       }       }while(a[i-1]);           return k;   }


Question: 求大神解答一下我这个问题= =

//#include "stdafx.h" #include<stdio.h> #include<string.h> #include<stdlib.h> #include <ctype.h>   int main(void) {     char str[80];     int alpha[26] = { 0 };     int i = 0;      //scanf_s("%s", str, 80);     scanf("%s", str);      while (str[i]) {         if (isalpha(str[i])) {             if (islower(str[i]))                 alpha[str[i]-'a']++;             else                 alpha[str[i]-'A']++;         }         i++;     }      for (i = 0; i < 26; i++)         printf("%c appears %d times!\n", i + 'A', alpha[i]);      return 0; }  #if 0 int main() {     char string1[1000] = { 0 };     char *searchPtr;     char alpha[26];     char  b[2] = { 0 };     char c;     int  length, count = 0, j = 0, tmp = 0;     printf("please entry the count:");     scanf_s("%d", &length);     printf("\nplease entry the string:\n");     for (int i = 0;i < length + 1;i++)                        //输入想要的字符串     {         gets_s(string1);     }     printf("show the result with the table:\n");     for (tmp = 0;tmp <= 25;tmp++)     {          for (char i = 'A';i <= 'A' + tmp;i++)                           //第一层：从A执行到Z。         {             searchPtr == 0;             b[2] == i && b[2] == i + 32;              while ((b[2] == i) && (b[2] == i + 32))                             //第二层              {                 searchPtr = strchr(string1,*b);                  while (searchPtr == NULL)                                //判别条件：没有找到                 {                     alpha[j] = 0;                     break;                 }                  while (searchPtr != NULL)                                //判别条件：已经找到                 {                     do                     {                          searchPtr = strchr(string1 + j - 1, *b);                         j += 1;                         count += 1;                     } while (searchPtr != NULL);                     alpha[j] += count;                     break;                 }                 break;             }          }     }     for (int i = 'A';i <='A'+25;i++)     {         c = i;          printf("the frequency of %c is:%d\t\t",c, alpha[j]);     }     return 0; } #endif  参考一下吧；

这两行语句完全没起作用！！！  searchPtr == 0; b[2] == i && b[2] == i + 32;


cfjtaishan 自信男孩     错误	1	error LNK1104: 无法打开文件“C:\Users\asus\Documents\Visual Studio 2013\Projects\检测\Debug\检测.exe”	C:\Users\asus\Documents\Visual Studio 2013\Projects\检测\检测\LINK	检测

#include<stdio.h>  #define N 2  void convert(int[][N]);  int main() {     int a[N][N];     int i, j;     printf("\n");     for (i = 0; i < N; i++)     {         for (j = 0; j < N; j++) {    /*这个地方应该用大括号括起来，输入之后直接输出输入的数据*/             scanf("%d",&a[i][j]);         printf("%d",a[i][j]);         }     }     convert(a);     printf("A=\n");     for (i = 0; i < N; i++)     {         for (j = 0; j < N; j++)             printf("%d ", a[i][j]);         printf("\n");     }     return 0; } void convert(int a[][N]) {     int i, j, t;     t = 0;    /*这儿减0没意义，我想应该是赋值初始化*/     for (i = 0; i < N; i++)     {         for (j = i + 1; j < N; j++)         {             t = a[i][j];             a[i][j] = a[j][i];             a[j][i] = t;         }     } }  参考一下吧，问题详见代码的注释

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

#include<stdio.h> #define N 4 void convert(int[][N]); int main() { int a[N][N]; int i, j; printf("\n"); for (i = 0; i < N; i++) { for (j = 0; j < N; j++) { scanf("%d",&a[i][j]); printf("%d",a[i][j]); } } convert(a); printf("A=\n"); for (i = 0; i < N; i++) { for (j = 0; j < N; j++) printf("%d ", a[i][j]); printf("\n"); }	 return 0; } void convert(int a[][N]) { int i, j, t; t - 0; for (i = 0; i < N; i++) { for (j = i + 1; j < N; j++) { t = a[i][j]; a[i][j] = a[j][i]; a[j][i] = t; } } }


Question: C语言中关于返回一个指向数组的指针的问题,有谁知道吗

在我看来在testA中testA_A返回的是char*，那么指针加1会向后移动一个字节 testB中testA_A返回的是char (*)[5]，那么指针加1会向后移动5个字节，所以需要先解引用，然后在加1

引用 8 楼 LM165678 的回复:[quote=引用 2 楼 user-3 的回复:] 数组的名字除了在做sizeof的参数之外，其他时候都是指向数组下表为0的元素，例子，a【10】，×a就是a【0】  char (*c)[5];等价于 char c[ ][5];，所以c等价于c[0],*c等价于c[0][0],取第iIndex个的值就是c[0][iIndex]也就是×（c[0][0] + index)也就是*((*c) + iIndex) 你好,你说"char (*c)[5];等价于 char c[ ][5];",但是在char * testA_A()函数中,是static char chArray[5],而不是static char chArray[?][5]数组...[/quote] 还有,char (*c)[5],等价于char (x)[5];x是任意数组名称,比如char (names)[5];可以去掉括号,即char names[5];

引用 2 楼 user-3 的回复:数组的名字除了在做sizeof的参数之外，其他时候都是指向数组下表为0的元素，例子，a【10】，×a就是a【0】  char (*c)[5];等价于 char c[ ][5];，所以c等价于c[0],*c等价于c[0][0],取第iIndex个的值就是c[0][iIndex]也就是×（c[0][0] + index)也就是*((*c) + iIndex) 你好,你说"char (*c)[5];等价于 char c[ ][5];",但是在char * testA_A()函数中,是static char chArray[5],而不是static char chArray[?][5]数组...

引用 6 楼 zhao4zhong1 的回复:http://edu.csdn.net/course/detail/2344 C语言指针与汇编内存地址-一.代码要素 http://edu.csdn.net/course/detail/2516 C语言指针与汇编内存地址-三.数组和二维数组

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

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

《C专家编程》和《C陷阱和缺陷》里面有详细的讲解，可以去看看


Question: 各位大神，我是新手，请教大家个问题

printf("0%d",变量); 你想要10以内前面加0的话，就加个条件控制语句  if(变量<10)   printf("0%d",变量); else   直接输出

占2位，但是你的举例具有歧义性。占2位是存储上的占2位，还是显示的占2个字节； 存储上占2位，是指一个字节占8位，那么占2位即8位中的2位。 显示占2个字节，即%02d输出，不够2个字节的用0补。

Format Specification Fields: printf and wprintf Functions A format specification, which consists of optional and required fields, has the following form:  %[flags] [width] [.precision] [{h | l | I64 | L}]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 Table R.3).  flags  Optional character or characters that control justification of output and printing of signs, blanks, decimal points, and octal and hexadecimal prefixes (see Table R.4). 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 Table R.5).  h | l | I64 | L  Optional prefixes to type-that specify the size of argument (see Table R.6). Flag Directives The first optional field of the format specification is flags. A flag directive is a character that justifies output and prints signs, blanks, decimal points, and octal and hexadecimal prefixes. More than one flag directive may appear in a format specification.   Table R.4   Flag Characters  Flag Meaning Default  – Left align the result within the given field width.  Right align.  + Prefix the output value with a sign (+ or –) if the output value is of a signed type. Sign appears only for negative signed values (–).  0 If width is prefixed with 0, zeros are added until the minimum width is reached. If 0 and – appear, the 0 is ignored. If 0 is specified with an integer format (i, u, x, X, o, d) the 0 is ignored.  No padding.  blank (' ') Prefix the output value with a blank if the output value is signed and positive; the blank is ignored if both the blank and + flags appear. No blank appears.  # When used with the o, x, or X format, the # flag prefixes any nonzero output value with 0, 0x, or 0X, respectively. No blank appears.    When used with the e, E, or f format, the # flag forces the output value to contain a decimal point in all cases.  Decimal point appears only if digits follow it.    When used with the g or G format, the # flag forces the output value to contain a decimal point in all cases and prevents the truncation of trailing zeros.  Ignored when used with c, d, i, u, or s.  Decimal point appears only if digits follow it. Trailing zeros are truncated.   printf Width Specification The second optional field of the format specification is the width specification. The width argument is a nonnegative decimal integer controlling the minimum number of characters printed. If the number of characters in the output value is less than the specified width, blanks are added to the left or the right of the values — depending on whether the – flag (for left alignment) is specified — until the minimum width is reached. If width is prefixed with 0, zeros are added until the minimum width is reached (not useful for left-aligned numbers).  The width specification never causes a value to be truncated. If the number of characters in the output value is greater than the specified width, or if width is not given, all characters of the value are printed (subject to the precision specification).  If the width specification is an asterisk (*), an int argument from the argument list supplies the value. The width argument must precede the value being formatted in the argument list. A nonexistent or small field width does not cause the truncation of a field; if the result of a conversion is wider than the field width, the field expands to contain the conversion result.


Question: 新人求解

c99之后不是可以在main之后再进行函数声明了吗？ 我觉得可能是函数参数的问题，我去试试

数组作为函数参数不能这么写。

main函数放到最下边

没有对自己定义的函数进行声明  建议先看看资料上有关函数声明定义调用的知识

在main前要先对函数进行声明


Question: 本人比较笨，求大佬解答!!!

48是字符'0'的十进制数，取余后，得到的是实际的进制数，加48就是为了用字符表示。比如，求16进制数，取余得到的事8，那么转成'8'，即8+48等价8 + '0' == '8'

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

‘0’   48

将数值转换为数值字符，如3变成'3'

数字0的ASCII是0x30,以此类推。。。

asc码 和 数字之间的转换


Question: 递归调用建立二叉树没有问题，但是放到if语句中调用函数无法返回

仅供参考:#include <locale.h> #include <stdio.h> #include <stdlib.h> #include <malloc.h> typedef struct BiTNode {//二叉树结点     char data;                      //数据     struct BiTNode *lchild,*rchild; //左右孩子指针 } BiTNode,*BiTree; int nn=0; int CreateBiTree(BiTree *T) {//按先序序列创建二叉树     char data;     scanf("%c",&data);//按先序次序输入二叉树中结点的值（一个字符），‘#’表示空树     if (data == '#') {         *T = NULL;     } else {         *T = (BiTree)malloc(sizeof(BiTNode)); nn++;         (*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的右子树。     BiTree *stack=(BiTree *)malloc(nn*sizeof(BiTree));     int sp=0;     BiTree p = T;//p是遍历指针     while (p || sp) {   //栈不空或者p不空时循环         if (p != NULL) {             stack[sp]=p;sp++;       //存入栈中             printf("%c ",p->data);  //访问根节点             p = p->lchild;          //遍历左子树         } else {             sp--;p=stack[sp];       //退栈             p = p->rchild;          //访问右子树         }     }     free(stack); } void InOrder2(BiTree T) {//中序遍历(非递归) //T是要遍历树的根指针，中序遍历要求在遍历完左子树后，访问根，再遍历右子树。 //先将T入栈，遍历左子树；遍历完左子树返回时，栈顶元素应为T，出栈，访问T->data，再中序遍历T的右子树。     BiTree *stack=(BiTree *)malloc(nn*sizeof(BiTree));     int sp=0;     BiTree p = T;//p是遍历指针     while (p || sp) {   //栈不空或者p不空时循环         if (p != NULL) {             stack[sp]=p;sp++;       //存入栈中             p = p->lchild;          //遍历左子树         } else {             sp--;p=stack[sp];       //退栈             printf("%c ",p->data);             p = p->rchild;          //访问右子树         }     }     free(stack); }  typedef struct BiTNodePost{     BiTree biTree;     char tag; } BiTNodePost,*BiTreePost; void PostOrder2(BiTree T) {//后序遍历(非递归)     BiTreePost *stack=(BiTreePost *)malloc(nn*sizeof(BiTreePost));     int sp=0;     BiTree p = T;//p是遍历指针     BiTreePost BT;     while (p != NULL || sp) {//栈不空或者p不空时循环         while (p != NULL) {//遍历左子树             BT = (BiTreePost)malloc(sizeof(BiTNodePost));             BT->biTree = p;             BT->tag = 'L';//访问过左子树             stack[sp]=BT;sp++;       //存入栈中             p = p->lchild;         }         while (sp && (stack[sp-1])->tag == 'R') {//左右子树访问完毕访问根节点             sp--;BT=stack[sp];        //退栈             printf("%c ",BT->biTree->data);             free(BT);         }         if (sp) {//遍历右子树             BT=stack[sp-1];             BT->tag = 'R';//访问过右子树             p = BT->biTree;             p = p->rchild;         }     }     free(stack); } void LevelOrder(BiTree T) {//层次遍历     BiTree p;     BiTree *queue;     int h=0,t=0,n=0;      if (T == NULL) return;     p=T;     queue=(BiTree *)malloc(nn*sizeof(BiTree));     queue[t]=p;t=(t+1)%10;n++;//根节点入队     while (n) {    //队列不空循环         p=queue[h];             //对头元素出队         printf("%c ",p->data);  //访问p指向的结点         h=(h+1)%10;n--;         //退出队列         if (p->lchild != NULL) {//左子树不空，将左子树入队             queue[t]=p->lchild;t=(t+1)%10;n++;         }         if (p->rchild != NULL) {//右子树不空，将右子树入队             queue[t]=p->rchild;t=(t+1)%10;n++;         }     }     free(queue); } 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: 为何visual studio 2017中汉字的UTF-8编码不是三个字节表示？

一般都是两个字节来进行表示的，3字节基本没有，要不就是4个字节的

引用 1 楼 tajon1226 的回复:UTF8英文的是1个字节，中文的大部分是2个字节，中文很小一部分是3个字节。 UTF8英文的是1个字节，中文的大部分是3个字节，中文很小一部分是2个或4字节。  // UTF-8 编码字符理论上可以最多到 6个字节长，但目前全世界的所 // 有文字和符号种类加起来也只要编到 4个字节长就够了。 // 　　UTF-8 是以 8位（即 1个字节）为单元对原始码进行编码（注意一 // 点：这里所讲的原始码都是指Unicode码），并规定：多字节码（2个字 // 节以上才称为多字节）以转换后第1个字节起头的连续“1”的数目（这 // 些连续“1”称为标记位），表示转换成几个字节：“110”连续两个 // “1”，表示转换结果为2个字节，“1110”表示3个字节，而“11110” // 则表示4个字节……跟随在标记位之后的“0”，其作用是分隔标记位和 // 字符码位。第2～第4个字节的起头两个位固定设置为“10”，也作为标 // 记，剩下的6个位才做为字符码位使用。 // 　　这样，2字节UTF-8码剩下11个字符码位，可用以转换0080～07FF的 // 原始字符码，3字节剩下16个字符码位，可用以转换0800～FFFF的原始字 // 符码，由此类推。编码方式的模板如下： // // 原始码（16进制）　UTF－8编码（二进制） // -------------------------------------------- // 0000 - 007F       0xxxxxxx // 0080 - 07FF       110xxxxx 10xxxxxx // 0800 - FFFF       1110xxxx 10xxxxxx 10xxxxxx // …… // -------------------------------------------- // // 　　模板中的“x”表示字符码。 // 　　Ascii码＜007F，编为1个 // 字节的UTF－8码。汉字的 Unicode编码范围为0800－FFFF，所以被编为 // 3个字节的UTF－8码。 // 　　例如“汉”字的Unicode编码是6C49，6C49在0800-FFFF之间，所以 // 要用3个字节的模板：1110wwww 10xxxxyy 10yyzzzz。  //    6    C    4    9 // 0110 1100 0100 1001 // wwww xxxx yyyy zzzz //     wwww   xxxxyy   yyzzzz // 1110wwww 10xxxxyy 10yyzzzz。 // 11100110 10110001 10001001 //    E   6    B   1    8   9 //“汉”字的UTF-8编码是E6 B1 89

vs2017默认就是utf8编码保存中文的

vs2017应该有的吧  没用过 低版本都有 不至于2017就没

VS貌似对字符串字面量用的都是本地ascii码，不管代码文件是UTF8还是ascii。 要想字符串是utf8，C++语言本身已经已经有语法糖了，在字符串前加 u8 就行了。

UTF8英文的是1个字节，中文的大部分是2个字节，中文很小一部分是3个字节。

中文从 2 字节到 4 字节的都有 ...


Question: 递归调用建立二叉树没有问题，但是放到if语句中调用函数无法返回

很不错的资料，学习了

仅供参考：#include <locale.h> #include <stdio.h> #include <stdlib.h> #include <malloc.h> typedef struct BiTNode {//二叉树结点     char data;                      //数据     struct BiTNode *lchild,*rchild; //左右孩子指针 } BiTNode,*BiTree; int nn=0; int CreateBiTree(BiTree *T) {//按先序序列创建二叉树     char data;     scanf("%c",&data);//按先序次序输入二叉树中结点的值（一个字符），‘#’表示空树     if (data == '#') {         *T = NULL;     } else {         *T = (BiTree)malloc(sizeof(BiTNode)); nn++;         (*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的右子树。     BiTree *stack=(BiTree *)malloc(nn*sizeof(BiTree));     int sp=0;     BiTree p = T;//p是遍历指针     while (p || sp) {   //栈不空或者p不空时循环         if (p != NULL) {             stack[sp]=p;sp++;       //存入栈中             printf("%c ",p->data);  //访问根节点             p = p->lchild;          //遍历左子树         } else {             sp--;p=stack[sp];       //退栈             p = p->rchild;          //访问右子树         }     }     free(stack); } void InOrder2(BiTree T) {//中序遍历(非递归) //T是要遍历树的根指针，中序遍历要求在遍历完左子树后，访问根，再遍历右子树。 //先将T入栈，遍历左子树；遍历完左子树返回时，栈顶元素应为T，出栈，访问T->data，再中序遍历T的右子树。     BiTree *stack=(BiTree *)malloc(nn*sizeof(BiTree));     int sp=0;     BiTree p = T;//p是遍历指针     while (p || sp) {   //栈不空或者p不空时循环         if (p != NULL) {             stack[sp]=p;sp++;       //存入栈中             p = p->lchild;          //遍历左子树         } else {             sp--;p=stack[sp];       //退栈             printf("%c ",p->data);             p = p->rchild;          //访问右子树         }     }     free(stack); }  typedef struct BiTNodePost{     BiTree biTree;     char tag; } BiTNodePost,*BiTreePost; void PostOrder2(BiTree T) {//后序遍历(非递归)     BiTreePost *stack=(BiTreePost *)malloc(nn*sizeof(BiTreePost));     int sp=0;     BiTree p = T;//p是遍历指针     BiTreePost BT;     while (p != NULL || sp) {//栈不空或者p不空时循环         while (p != NULL) {//遍历左子树             BT = (BiTreePost)malloc(sizeof(BiTNodePost));             BT->biTree = p;             BT->tag = 'L';//访问过左子树             stack[sp]=BT;sp++;       //存入栈中             p = p->lchild;         }         while (sp && (stack[sp-1])->tag == 'R') {//左右子树访问完毕访问根节点             sp--;BT=stack[sp];        //退栈             printf("%c ",BT->biTree->data);             free(BT);         }         if (sp) {//遍历右子树             BT=stack[sp-1];             BT->tag = 'R';//访问过右子树             p = BT->biTree;             p = p->rchild;         }     }     free(stack); } void LevelOrder(BiTree T) {//层次遍历     BiTree p;     BiTree *queue;     int h=0,t=0,n=0;      if (T == NULL) return;     p=T;     queue=(BiTree *)malloc(nn*sizeof(BiTree));     queue[t]=p;t=(t+1)%10;n++;//根节点入队     while (n) {    //队列不空循环         p=queue[h];             //对头元素出队         printf("%c ",p->data);  //访问p指向的结点         h=(h+1)%10;n--;         //退出队列         if (p->lchild != NULL) {//左子树不空，将左子树入队             queue[t]=p->lchild;t=(t+1)%10;n++;         }         if (p->rchild != NULL) {//右子树不空，将右子树入队             queue[t]=p->rchild;t=(t+1)%10;n++;         }     }     free(queue); } 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语言用递归函数求数组中最小值，新手求解

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

#include <stdio.h> #define MAX 100 typedef int INT;  INT min(INT num[],INT i); INT main() {     INT num[MAX];     INT  a,b,count;     count = 0;     printf("\n请输入到数组中的整数:\n");     do{          scanf("%d",&a);         getchar();         if(a!=-1)             num[count++] = a;         else             break;      }while(count<MAX);      printf("数组中的整数序列为:\n");      for(b=0;b<count;b++){          printf("%d  ",num[b]);     }     printf("\n");     printf("数组中最小的整数为%d ",min(num,count));   } INT min(INT num[],INT i){     int temp,j;     if(i>0){         j = i;         num[0] =num[0] < num[j]?num[0]:num[j];         temp=min(num,j-1);         return temp;     }     else         return num[0]; }

int MIN(int numbers[], int a) { int j; j = a;  numbers[0] = (numbers[0] < numbers[j]) ? numbers[0] : numbers[j];  return MIN(numbers,a - 1); }//鬼知道是用来干什么的函数！ 把最小的元素移动到一个。


Question: C语言写魔王语言

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


Question: 求最小公倍数 答案不对 答案只写了一种情况 如果改正需要怎么加if条件语句

但是这个最小公倍数不适应于两个数都是奇数的情况

#include <stdio.h> int main() {    int p,n,m,temp;     scanf("%d %d",&n,&m);    temp = n > m ? m : n;     for(temp=m;temp>0;temp--){         if(n%temp==0 && m%temp==0){              printf("两个数的最大公约数是：%d\n",temp);              break;         }    }     p = n * m;     printf("两个数的最小公倍数是:%d\n",p/temp);     return 0; }

你的程序将scanf("%d,%d,",&n,&m);中%的和%d间的逗号去掉就可以了，如果不取，在输入时两个数据间用中文的逗号就会正常，一般在scanf（）函数里两个%d%d不用隔开，在输入数据时用空格隔开就好了。

#include <stdio.h>      int  main(void)   {       int x, y, num1, num2, temp;              printf("请输入两个正整数：\n");       scanf("%d %d", &num1, &num2);   	if(num1 < num2)       {           temp = num1;           num1 = num2;           num2 = temp;       }       x = num1;       y = num2;       while(y != 0)       {           temp = x%y;           x = y;           y = temp;       }   	printf("它们的最大公约数为：%d\n", x);       printf("它们的最小公倍数为：%d\n", num1*num2/x);              return 0;   }


Question: 关于二叉链表的非递归先序遍历输出问题，输出的时候出问题了，请大神指点一二！！！

引用 1 楼 zhao4zhong1 的回复:仅供参考：#include <locale.h> #include <stdio.h> #include <stdlib.h> #include <malloc.h> typedef struct BiTNode {//二叉树结点     char data;                      //数据     struct BiTNode *lchild,*rchild; //左右孩子指针 } BiTNode,*BiTree; int nn=0; int CreateBiTree(BiTree *T) {//按先序序列创建二叉树     char data;     scanf("%c",&data);//按先序次序输入二叉树中结点的值（一个字符），‘#’表示空树     if (data == '#') {         *T = NULL;     } else {         *T = (BiTree)malloc(sizeof(BiTNode)); nn++;         (*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的右子树。     BiTree *stack=(BiTree *)malloc(nn*sizeof(BiTree));     int sp=0;     BiTree p = T;//p是遍历指针     while (p || sp) {   //栈不空或者p不空时循环         if (p != NULL) {             stack[sp]=p;sp++;       //存入栈中             printf("%c ",p->data);  //访问根节点             p = p->lchild;          //遍历左子树         } else {             sp--;p=stack[sp];       //退栈             p = p->rchild;          //访问右子树         }     }     free(stack); } void InOrder2(BiTree T) {//中序遍历(非递归) //T是要遍历树的根指针，中序遍历要求在遍历完左子树后，访问根，再遍历右子树。 //先将T入栈，遍历左子树；遍历完左子树返回时，栈顶元素应为T，出栈，访问T->data，再中序遍历T的右子树。     BiTree *stack=(BiTree *)malloc(nn*sizeof(BiTree));     int sp=0;     BiTree p = T;//p是遍历指针     while (p || sp) {   //栈不空或者p不空时循环         if (p != NULL) {             stack[sp]=p;sp++;       //存入栈中             p = p->lchild;          //遍历左子树         } else {             sp--;p=stack[sp];       //退栈             printf("%c ",p->data);             p = p->rchild;          //访问右子树         }     }     free(stack); }  typedef struct BiTNodePost{     BiTree biTree;     char tag; } BiTNodePost,*BiTreePost; void PostOrder2(BiTree T) {//后序遍历(非递归)     BiTreePost *stack=(BiTreePost *)malloc(nn*sizeof(BiTreePost));     int sp=0;     BiTree p = T;//p是遍历指针     BiTreePost BT;     while (p != NULL || sp) {//栈不空或者p不空时循环         while (p != NULL) {//遍历左子树             BT = (BiTreePost)malloc(sizeof(BiTNodePost));             BT->biTree = p;             BT->tag = 'L';//访问过左子树             stack[sp]=BT;sp++;       //存入栈中             p = p->lchild;         }         while (sp && (stack[sp-1])->tag == 'R') {//左右子树访问完毕访问根节点             sp--;BT=stack[sp];        //退栈             printf("%c ",BT->biTree->data);             free(BT);         }         if (sp) {//遍历右子树             BT=stack[sp-1];             BT->tag = 'R';//访问过右子树             p = BT->biTree;             p = p->rchild;         }     }     free(stack); } void LevelOrder(BiTree T) {//层次遍历     BiTree p;     BiTree *queue;     int h=0,t=0,n=0;      if (T == NULL) return;     p=T;     queue=(BiTree *)malloc(nn*sizeof(BiTree));     queue[t]=p;t=(t+1)%10;n++;//根节点入队     while (n) {    //队列不空循环         p=queue[h];             //对头元素出队         printf("%c ",p->data);  //访问p指向的结点         h=(h+1)%10;n--;         //退出队列         if (p->lchild != NULL) {//左子树不空，将左子树入队             queue[t]=p->lchild;t=(t+1)%10;n++;         }         if (p->rchild != NULL) {//右子树不空，将右子树入队             queue[t]=p->rchild;t=(t+1)%10;n++;         }     }     free(queue); } 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   谢谢赵4老师指点


Question: 麻烦各位，帮我看下头文件，看不明白

]  引用 8 楼 paschen 的回复:[quote=引用 7 楼 记得北海有墓碑的回复:][quote=引用 6 楼 paschen 的回复:] 预编译语句，根据是否定义了__GNUC__将NORETURN定义为不同的值 呃呃，是不是只有gcc里面才有宏__GNUC__，所以说接下来的代码最好是在gcc里面编译；#else #define NORETURN 这个是不是只是个空宏，如果用了gcc意外的编译器，是不是 就没有__attribute__((__noretrun__))这个属性了[/quote] 是，__GNUC__ 是gcc编译器编译代码时预定义的一个宏。  https://www.cnblogs.com/whiteyun/archive/2010/09/05/1818491.html[/quote] 谢谢版主！分全给你了

引用 7 楼 记得北海有墓碑的回复:[quote=引用 6 楼 paschen 的回复:] 预编译语句，根据是否定义了__GNUC__将NORETURN定义为不同的值 呃呃，是不是只有gcc里面才有宏__GNUC__，所以说接下来的代码最好是在gcc里面编译；#else #define NORETURN 这个是不是只是个空宏，如果用了gcc意外的编译器，是不是 就没有__attribute__((__noretrun__))这个属性了[/quote] 是，__GNUC__ 是gcc编译器编译代码时预定义的一个宏。  https://www.cnblogs.com/whiteyun/archive/2010/09/05/1818491.html

引用 6 楼 paschen 的回复:预编译语句，根据是否定义了__GNUC__将NORETURN定义为不同的值 呃呃，是不是只有gcc里面才有宏__GNUC__，所以说接下来的代码最好是在gcc里面编译；#else #define NORETURN 这个是不是只是个空宏，如果用了gcc意外的编译器，是不是 就没有__attribute__((__noretrun__))这个属性了

预编译语句，根据是否定义了__GNUC__将NORETURN定义为不同的值

这是预编译语句

引用 3 楼 wodexiaojidan 的回复:引用http://www.gnu.org/software/libc/manual/pdf/libc.pdfglibc学习手册， 呃呃，打不开。能帮我解释下这段预定义吗

引用 2 楼 dh19930415 的回复:预编译语句。#ifdef与#else相配合就相当于if与else。就是#ifdef后面的语句成立的话，执行这句后面的一些定义，如果不成立，就执行#else下面的定义。最后#endif是结束标志 这个我懂。我的意思是，__GNUC__是不是就是表示，接下来的代码是需要在gcc里编译的；还有#else #define NORETURN 这个NORETURN是个空宏吗？还是在其他编译器内表示另外的意思？


Question: 新手刚学栈，做了个左右括号匹配，但结果怎么都不对，求解我该怎么该

if (!StackEmpty(S))         return ERROR;     else         return OK;  这段是不是写反了，改成下面这样。 ↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓     if (!StackEmpty(S))         return OK;     else         return  ERROR;

OKOKOKOK

#include <stdio.h> #include <stdlib.h> #include <malloc.h>  #define OK 1 #define ERROR 0 #define OVERFLOW -2 #define STACK_INIT_SIZE  100 #define STACKINCREMENT 10  typedef int Status; typedef char SElemType;  typedef struct {     SElemType * base;     SElemType * top;     int stacksize; }SqStack;  //栈的存储结构定义 SqStack stack;//定义全局变量  Status InitStack(SqStack *S)     //初始化栈 {     S->base = (SElemType *)         malloc(STACK_INIT_SIZE * sizeof(SElemType));     if (S->base == NULL)         exit(OVERFLOW);     S->top = S->base;     S->stacksize = STACK_INIT_SIZE;     return OK;  }//InitStack  SElemType GetTop(SqStack *S)    //获取栈顶元素 {     int e;     if (S->top == S->base)         return ERROR;     e = *(S->top - 1);     return e;  }// GetTop Status Push(SqStack *S, SElemType e) //元素e入栈 {     if (S->top - S->base >= S->stacksize)     {         S->base = (SElemType *)realloc(S->base, (S->stacksize + STACKINCREMENT) * sizeof(SElemType));         if (!S->base)             exit(OVERFLOW);         S->top = S->base + S->stacksize;         S->stacksize += STACKINCREMENT;     }     *S->top++ = e;     return OK;  }// Push( Status Pop(SqStack *S, SElemType *e) //出栈，元素存进e {     if (S->top == S->base)         return ERROR;     *e = *(--S->top);     return OK; }//Pop Status ClearStack(SqStack *S)   //清空栈 {     S->top = S->base;     return OK;  }// ClearStack Status DestroyStack(SqStack *S)  //销毁栈 {      free(S->base);     S->base = NULL;     S->top = NULL;     S->stacksize = 0;     return OK;  }// DestroyStack Status StackEmpty(SqStack *S) {//判断空栈     if (S->top == S->base)   /*这儿应该是判断表达式不应该是赋值=*/         return OK;     else         return ERROR; }  int Judge(SqStack *S, SElemType  exp[])   //判断表达式括号是否匹配，若匹配，返回OK，不匹配，返回ERROR {      SElemType e;     int i=0;     for (i = 0; exp[i] != '\0'; i++)     {         switch (exp[i])         {              case '(':case '[':case '{':                 Push(S, exp[i]);                 i++;                 break;             case ')':                 if (!StackEmpty(S) && GetTop(S) == '(')                 {                     Pop(S, &e);                     i++;                 }                 else { return ERROR; }                 break;             case ']':                 if (!StackEmpty(S) && GetTop(S) == '[')                 {                     Pop(S, &e); i++;                 }                 else { return ERROR; }                 break;             case '}':                 if (!StackEmpty(S) && GetTop(S) == '{')                 {                     Pop(S, &e); i++;                 }                 else {                     return ERROR;                 }                 break;         }     }     if (!StackEmpty(S))         return ERROR;     else         return OK;     //DestroyStack(S);   /*放着没意义，也不会运行到*/ }// Judge int main() {     int i, flag;     SElemType express[81];     InitStack(&stack);  //初始化栈     do     {         printf("请输入表达式：\n");         gets(express);         ClearStack(&stack);  //清空栈         i = Judge(&stack, express);         if (i == OK)             printf("该表达式的括号匹配！\n");         else             printf("该表达式的括号不匹配！\n");         printf("1：继续判断,0：退出程序\n");         scanf("%d", &flag);         getchar();     } while (flag != 0);     DestroyStack(&stack);// 销毁栈     system("pause");     return 0; } 以上是修改你的代码，测试了暂没发现问题，建议对比看一下； 问题比较多，主要体现在两个方面： 1. 形参和实参，形参应该定义成指针，这样才能将修改的栈信息带回； 2. if表达式应该是判断表达式，而不应该是赋值表达式=

仅供参考：#include<stdio.h> #include<malloc.h> #include<string.h> #define STACK_INIT_SIZE 10 #define STACK_GROW_SIZE 5 #define ELEMTYPE char #define OK 1 #define ERROR 0 typedef struct { /*建立一个栈的首结点*/     ELEMTYPE * base;     ELEMTYPE * top;     int stacksize; } SpStack; int InitStack(SpStack *s) { /*建立空的栈并返回首地址*/     s->base=((ELEMTYPE*)malloc(STACK_INIT_SIZE*sizeof(ELEMTYPE)));     if (!s->base) return ERROR;     s->top=s->base;     s->stacksize=STACK_INIT_SIZE;     return OK; } int StackEmpty(SpStack *s) { /*判断栈是否为空*/     if (s->top==s->base) return OK;     else                 return ERROR; } int Push(SpStack *s,ELEMTYPE e) { /*往栈顶插入元素即进栈*/     if (s->top-s->base>=s->stacksize) { /*判断是否栈满*/         s->base=((ELEMTYPE*)realloc(s->base,(s->stacksize+STACK_GROW_SIZE)*sizeof(ELEMTYPE)));         if (!s->base) return ERROR;         s->stacksize+=STACK_GROW_SIZE;         s->top=s->base+s->stacksize;     }     *s->top++=e;     return OK; } int Pop(SpStack *s,ELEMTYPE *e) { /*让栈顶元素依次输出即出栈*/     if (StackEmpty(s)) return ERROR;     *e=*(--s->top);     return OK; } int Comp(ELEMTYPE a,ELEMTYPE b) {     if ((a=='('&&b!=')')       ||(a=='['&&b!=']')       ||(a=='{'&&b!='}')) {         return ERROR;     } else return OK; } int Count(SpStack *s) {     ELEMTYPE e[STACK_INIT_SIZE*2];     ELEMTYPE e1;     int i;      InitStack(s);     fgets(e,STACK_INIT_SIZE*2,stdin);     if ('\n'==e[strlen(e)-1]) e[strlen(e)-1]=0;     printf("%s\n",e);     for (i=0;e[i]!='\0';i++) {         switch (e[i]) {         case '(':         case '[':         case '{':             Push(s,e[i]);             break;         case ')':         case ']':         case '}':             if (StackEmpty(s)) {                 printf("%*s↖右括号多余\n",i+1,"");                 return(ERROR);             } else Pop(s,&e1);             if (!Comp(e1,e[i])) {                 printf("%*s↖左右匹配出错\n",i+1,"");                 return(ERROR);             }         }     }     if (!StackEmpty(s)) {         printf("%*s↖左括号多余\n",i,"");         return(ERROR);     } else {         printf("匹配正确\n");         return(OK);     } } void main() {     SpStack s;     Count(&s);     free(s.base); }


Question: 二叉树问题，代码完全正确，但最后的循环为什么不能继续？？？

仅供参考：#include <locale.h> #include <stdio.h> #include <stdlib.h> #include <malloc.h> typedef struct BiTNode {//二叉树结点     char data;                      //数据     struct BiTNode *lchild,*rchild; //左右孩子指针 } BiTNode,*BiTree; int nn=0; int CreateBiTree(BiTree *T) {//按先序序列创建二叉树     char data;     scanf("%c",&data);//按先序次序输入二叉树中结点的值（一个字符），‘#’表示空树     if (data == '#') {         *T = NULL;     } else {         *T = (BiTree)malloc(sizeof(BiTNode)); nn++;         (*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的右子树。     BiTree *stack=(BiTree *)malloc(nn*sizeof(BiTree));     int sp=0;     BiTree p = T;//p是遍历指针     while (p || sp) {   //栈不空或者p不空时循环         if (p != NULL) {             stack[sp]=p;sp++;       //存入栈中             printf("%c ",p->data);  //访问根节点             p = p->lchild;          //遍历左子树         } else {             sp--;p=stack[sp];       //退栈             p = p->rchild;          //访问右子树         }     }     free(stack); } void InOrder2(BiTree T) {//中序遍历(非递归) //T是要遍历树的根指针，中序遍历要求在遍历完左子树后，访问根，再遍历右子树。 //先将T入栈，遍历左子树；遍历完左子树返回时，栈顶元素应为T，出栈，访问T->data，再中序遍历T的右子树。     BiTree *stack=(BiTree *)malloc(nn*sizeof(BiTree));     int sp=0;     BiTree p = T;//p是遍历指针     while (p || sp) {   //栈不空或者p不空时循环         if (p != NULL) {             stack[sp]=p;sp++;       //存入栈中             p = p->lchild;          //遍历左子树         } else {             sp--;p=stack[sp];       //退栈             printf("%c ",p->data);             p = p->rchild;          //访问右子树         }     }     free(stack); }  typedef struct BiTNodePost{     BiTree biTree;     char tag; } BiTNodePost,*BiTreePost; void PostOrder2(BiTree T) {//后序遍历(非递归)     BiTreePost *stack=(BiTreePost *)malloc(nn*sizeof(BiTreePost));     int sp=0;     BiTree p = T;//p是遍历指针     BiTreePost BT;     while (p != NULL || sp) {//栈不空或者p不空时循环         while (p != NULL) {//遍历左子树             BT = (BiTreePost)malloc(sizeof(BiTNodePost));             BT->biTree = p;             BT->tag = 'L';//访问过左子树             stack[sp]=BT;sp++;       //存入栈中             p = p->lchild;         }         while (sp && (stack[sp-1])->tag == 'R') {//左右子树访问完毕访问根节点             sp--;BT=stack[sp];        //退栈             printf("%c ",BT->biTree->data);             free(BT);         }         if (sp) {//遍历右子树             BT=stack[sp-1];             BT->tag = 'R';//访问过右子树             p = BT->biTree;             p = p->rchild;         }     }     free(stack); } void LevelOrder(BiTree T) {//层次遍历     BiTree p;     BiTree *queue;     int h=0,t=0,n=0;      if (T == NULL) return;     p=T;     queue=(BiTree *)malloc(nn*sizeof(BiTree));     queue[t]=p;t=(t+1)%10;n++;//根节点入队     while (n) {    //队列不空循环         p=queue[h];             //对头元素出队         printf("%c ",p->data);  //访问p指向的结点         h=(h+1)%10;n--;         //退出队列         if (p->lchild != NULL) {//左子树不空，将左子树入队             queue[t]=p->lchild;t=(t+1)%10;n++;         }         if (p->rchild != NULL) {//右子树不空，将右子树入队             queue[t]=p->rchild;t=(t+1)%10;n++;         }     }     free(queue); } 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

#include <stdio.h> #include <malloc.h> #include <stack> #include <string.h> #include <queue>  #define N 20 #define M 2*N-1 #define INF 65535  using namespace std;  typedef char* HuffmanCode[N+1];  typedef struct Node { 	char data; 	struct Node *LChild; 	struct Node *RChild; }BiTNode,*BiTree;  typedef struct  { 	int weight;//节点的权值 	int parent;//双亲节点下标 	int LChild;//左节点下标 	int RChild;//右节点下标 }HTNode,HuffmanTree[M+1];//0号单元不用  void CreatBiTree(BiTree *root) {//输入AB.DF..G..C.E.H.. 	char ch; 	scanf("%c",&ch); 	if(ch == '.') 	{ 		*root = NULL; 	} 	else 	{ 		*root = (BiTree)malloc(sizeof(BiTNode)); 		(*root)->data = ch; 		CreatBiTree(&((*root)->LChild)); 		CreatBiTree(&((*root)->RChild)); 	} } void PreOrder1(BiTree root) { 	if (root != NULL) 	{ 		printf("%c",root->data); 		PreOrder1(root->LChild); 		PreOrder1(root->RChild); 	} } void InOrder1(BiTree root) { 	if (root != NULL) 	{ 		InOrder1(root->LChild); 		printf("%c",root->data); 		InOrder1(root->RChild); 	} } void PostOrder1(BiTree root) { 	if (root != NULL) 	{ 		PostOrder1(root->LChild); 		PostOrder1(root->RChild); 		printf("%c",root->data); 	} } void PrintPreBiTree(BiTree root) { 	if(root != NULL) 	{ 		printf(" %c ",root->data); 		PrintPreBiTree(root->LChild); 		PrintPreBiTree(root->RChild); 	} } int PostTreeDepth(BiTree root) { 	int hl,hr,max; 	if(root != NULL) 	{ 		hl = PostTreeDepth(root->LChild);//求左子树的深度 		hr = PostTreeDepth(root->RChild);//求右子树的深度 		max = hl>hr?hl:hr;//得到左右子树深度较大者 		return(max+1);//返回树的深度 	} 	else 	{ 		return 0;//空树返回0 	} } void InOrder(BiTree root) { 	stack<BiTree> s; 	BiTNode *p; 	p=root; 	while(p != NULL || !s.empty()) 	{ 		if(p != NULL)//根指针进栈，遍历左子树 		{ 			s.push(p); 			p = p->LChild; 		} 		else 		{//根指针退栈，访问根节点，遍历右子树 			p = s.top(); 			s.pop(); 			printf(" %c ",p->data); 			p = p->RChild; 		} 	} } void PreOrder(BiTree root) { 	stack<BiTree> s;//s栈，类型BiTree 	BiTree p; 	p = root; 	while(p != NULL || !s.empty()) 	{ 		if(p != NULL) 		{//先遍历左子树 			printf(" %c ",p->data); 			s.push(p); 			p = p->LChild; 		} 		else 		{ 			p = s.top(); 			s.pop(); 			p = p->RChild; 		} 	} } void PostOrder(BiTree root) { 	stack<BiTree> s; 	BiTree p,q; 	p = root; 	q = NULL;//上一个节点 	while(p != NULL || !s.empty()) 	{//先遍历左子树 		while(p != NULL) 		{ 			s.push(p); 			p = p->LChild; 		} 		if(!s.empty()) 		{ 			p = s.top(); 			//如果没有右子树，或者右子树刚刚被访问过，则输出根节点 			if( p->RChild == NULL || 				p->RChild == q) 			{ 				printf(" %c ",p->data); 				q = p; 				s.pop(); 				p = NULL; 			} 			else 			{ 				p = p->RChild; 			} 		} 	} } //=======层序遍历====== int  LayerOrder(BiTree bt) {  	queue<BiTree> Q; 	BiTree  p;  	if(bt == NULL) 	{ 		return 0; /* 若二叉树bt为空树，则结束遍历*/ 	} 	Q.push(bt); 	while(!Q.empty())/*若队列非空，则遍历为结束，继续进行*/ 	{  		p = Q.front(); 		Q.pop(); 		printf("%c  ",p->data); 		if(p->LChild ) 		{ 			Q.push(p->LChild);/*若p的左孩子非空，则进队*/ 		} 		if(p->RChild )  		{ 			Q.push(p->RChild);/*若p的右孩子非空，则进队*/ 		} 	}/*while*/ 	return 1; }   int main(void) { 	/*BiTree root; 	int h;  	CreatBiTree(&root); 	PrintPreBiTree(root); 	h = PostTreeDepth(root); 	printf("\n%d\n",h); 	InOrder(root); 	printf("\n"); 	PreOrder(root); 	printf("\n"); 	PostOrder(root); 	printf("\n"); 	LayerOrder(root); 	printf("\n");*/ 	getchar();  	return 0; }  代码不完整 看实现过程


Question: linux下 udp使用万兆单向网卡进行文件传输

请问最后怎么解决的呀，现在遇到了同样的问题

引用 3 楼 cfjtaishan 的回复:丢包的原因，应该是接收端去处理上次发过来的数据，而没有及时去处理当前发过来的数据包。 个人建议使用缓冲机制，即环形缓冲区（大小可以根据网速自己定义）； 这样，接收端现将数据接收了，然后放到环形缓冲区里，这样保证接收端网卡收到的数据不丢；，另一个线程去从环形缓冲区读，读到之后写文件。  建议了解一下环形缓冲区，环形缓冲区有读位置和写位置，接收到到数据后修改写位置，另一个线程从缓冲区里读数据，修改读位置。  谢谢您的回复  对我帮助很大   正在测试程序。

谢谢您的回复  刚才给忽略了  MTU已经改了为6000.

主要是MTU和MMS你要改，缓冲大小用默认的一般应该够了


Question: 无法输出是怎么回事？

#include <stdio.h> #include<stdlib.h>  #define LIST_INIT_SIZE  100 #define LISTINCREMENT   10  typedef int  ElemType; typedef  struct {     ElemType *elem;     int length;     int listsize; }SqList;  void InitList(SqList &L,int arr[], int size)  //构造一个线性表 {     int i = 0;     L.elem = (ElemType*)malloc(LIST_INIT_SIZE*sizeof(ElemType));     L.length = 0;     for (i = 0; i < size; i++)     {         L.elem[i] = arr[i];         L.length++;     }     L.listsize = LIST_INIT_SIZE;//初始储存容量 }  void MoveList(SqList &L) {     int i = 0;     int j = L.length-1;     int temp = 0;      while(i<j)     {         while(i<j && L.elem[i]%2 == 0)             i++;    /*从开头向后，需要i++*/         while(j>i && L.elem[j]%2 == 1)             j--;    /* 从末尾向前，需要j--*/         if (i < j)         {             temp = L.elem[i];             L.elem[i] = L.elem[j];             L.elem[j] = temp;         }     } }  void DisList(SqList L)  //输出 {     int i = 0;     for(i = 0;i<L.length;i++)         printf("%d ", L.elem[i]);     printf("\n");  } int main() {     SqList L;     int arr[] = {1,2,3,4,5,6,7,8};     InitList(L,arr, 8);     MoveList(L);     DisList(L);     return 0; } 参考一下吧 主要问题是首尾增加的错误；详见代码的注释；

建议单步跟踪程序运行，观察变量变化情况，分析原因

问题可能出在InitList上，参数应该是SqList *，而调用处应该是SqList(&L, arr)，这样才能给main函数的L初始化正确的值。


Question: 链队(POP出了些问题)

#include <stdio.h> #include <stdlib.h>  #define OK 1 #define ERROR 0  int n=0;  typedef int ElemType;  typedef struct linknode {     ElemType data;     struct linknode *next; }linknode;  typedef struct Queue {     linknode *front;     linknode *rear; }linkqueue;  int initial(linkqueue *Q) {     linknode *p;     p = (linknode *)malloc(sizeof(linknode));     if(!p)     {         exit(1);         return ERROR;     }     p->next = NULL;     Q->front = Q->rear = p;     return OK; }  int Empty(linkqueue *Q) {     return(Q->front == Q->rear?OK:ERROR); }  int push(linkqueue *Q) {     linknode *p;     p = (linknode *)malloc(sizeof(linknode));     if (!p) {         exit(1);         return ERROR;     }     printf("请输入进队整数：");     scanf("%d",&p->data);     Q->rear->next = p;     Q->rear = p;     n++;     return OK; }  int pop(linkqueue *Q) {     linknode *p;     if(Q->front == Q->rear)         return ERROR;     else     {         p = Q->front->next;         if(Q->front->next == Q->rear)         {             Q->front->next = NULL;             Q->rear = Q->front;         }         else         {             Q->front->next = p->next;         }         free(p);         n--;         return OK;     } }  int gettop(linkqueue *Q) {     linknode *p;     if(Q->front==Q->rear)         return ERROR;     else     {         p = Q->front->next;     }     return p->data; }  void print(linkqueue *Q) {     int i=0;     linknode *p;     if(Empty(Q))         printf("队为空！");     else     {         printf("队内元素为：");         for(p=Q->front->next;i<n; i++,p=p->next)         {             printf("%d ",p->data);         }         printf("\n队内元素个数为%d个",n);      } }     int main(void) {     linkqueue q;     linkqueue *Q;     Q=&q;     int i,e;     printf("1.链队初始化\n2.链队判空\n3.进队\n4.出队\n5.队顶\n6.遍历队\n7.退出\n\n\n");     while(scanf("%d", &i)!=EOF)     {         switch(i)         {             case 1:                 if(initial(Q))                     printf("初始化成功！");                 break;              case 2:                 if(Empty(Q))                     printf("队空！");                 else                     printf("队未空！");                 break;              case 3:                 if(push(Q))                     printf("进队成功！");                 break;              case 4:                 if(pop(Q))                     printf("出队成功！");                 else                     printf("队为空！");                 break;             case 5:                 if(!gettop(Q))                     printf("队为空");                  else                        {                            e=gettop(Q);                            printf("队顶元素为%d",e);                        }                        break;             case 6: print(Q);break;             case 7: exit(0);         }         putchar(10);     } } 问题不大，主要是pop函数内，一个if判断表达式写成赋值表达式了。 注意是pop函数内的这句:  if(Q->front->next == Q->rear)


Question: 关于C语言函数数组的问题求大神帮忙看一下

#include <stdio.h> #include<stdlib.h>  #define COL 10 #define ROW 9  void get(int(*)[COL]); void xzpx(int[][COL]); void out(int[ROW][COL]); void select_sort(int *arr, int size);  void get(int(*a)[COL]) {     int i,j,x;     for(i=0;i<ROW;i++)     {         for(j=0;j<COL;j++)             do             {                 x=rand()%100;                 a[i][j]=x;             } while(x<=50);      } } void out(int a[ROW][COL]) {     int i,j,l=0;     for(i=0;i<ROW;i++)         for(j=0;j<COL;j++)         {             printf("%4d",a[i][j]);             l++;             if(l==10)             {                 printf("\n");                 l=0;             }         } }  /* void xzpx(int a[][COL]) {     int i,j,x,xxb,y;     for(x=0;x<ROW;x++)         for(i=0;i<COL-1;i++)         {             xxb=i;             for(j=i+1;j<COL;j++)             {                 if(a[x][j]<a[x][xxb])                     xxb=j;                 if(i!=xxb)                 {                     y=a[x][i];                     a[x][i]=a[x][xxb];                     a[x][xxb]=y;                 }             }         } } */  void xzpx(int (*a)[COL], int row) {     int i;      for (i = 0; i < row; i++)         select_sort(a[i], COL); }  void select_sort(int *arr, int size) {     int i, j;     int min = 0;      for (i = 0; i < size; i++) {         min = i;         for (j = i; j < size; j++) {             if (arr[min] > arr[j])                 min = j;         }         if (min != i) {             int tmp = arr[min];             arr[min] = arr[i];             arr[i] = tmp;         }     } }  int main() {     int b[ROW][COL],n;     get(b);     out(b);     for(n=0;n<COL;n++)         printf("****");     printf("\n");     xzpx(b, ROW);     out(b); }  参考一下吧；  输入有问题那应该是选择排序的问题。

冒泡算法有问题  void xzpx(int a[][k]) { 	int i, j, x, y; 	for (x = 0; x < h; x++) 		for (i = 0; i < k - 1; i++) 		{ 			for (j = i + 1; j < k; j++) 			{ 				if (a[x][j] < a[x][i]) 				{ 					y = a[x][i]; 					a[x][i] = a[x][j]; 					a[x][j] = y; 				} 			} 		} }


Question: C语言：萌新求助。可以看下我的代码哪里出问题了吗

QAQ再次求助啊

这样啊。那要怎么改。QWQ引用 3 楼 user-2 的回复:printf("数组已满\n");  else  {  printf("输入第%d个数\n",n+1);  scanf("%d",&x); --> scanf("%d",&a[n]);  另外你的break只是跳出来switch，程序显示被接下来的新一轮循环的system("cls");清除了

还没。。。。 引用 4 楼 htltju 的回复:解决了吗请问

解决了吗请问

QAQ还是没有人帮忙吗

没有人吗QWQ QAQ


Question: 数据结构的一个问题

因为参数的传递是值传递， void attach(Type e, Type c, PolyNomial *PtrRear) 该函数里的PtrRear是attach函数内的局部变量。根据参数值传递，那么修改PtrRear接收到的是实参的内容，在attach修改PtrRear，只是修改了局部变量，而没有修改实参的内容。所以，传递二重指针，可以把attach对PtrRear的修改带回到实参。

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

要想改变指针的内容，直接传指针就好了 但是要改变指针的指向，就需要传指针的地址了啊