Question: C语言关于指向字符串的指针数组的问题求助，求高手！

不过前提是指针数组应该有所指向，如char str[9][100]; char *str_add[9]; for(i=0;i<10;++i){str_add[i]=str[i];}

引用 2楼我是你的主体 的回复:我试了下把void add的都写到main里面，还是出现同样的问题……  引用 1 楼 weixin_30460121 的回复:因为add是局部变量，当执行add()函数时，将add的地址赋给str_add，函数执行完毕后，该地址所指向的内存即背释放，所以第二次printf的时候，前面的指针指向的内容已发生变化你把void add()里面的内容全写在main()里面的话，虽然char add[100]才被调用后其内存不会释放，但你每次执行str_add[sum_add]=add时，其实是每次都只是把add的地址赋给指针str_add了，这样一来，相当于指针数组里面所有的指针都指向同一个地址add，所以printf出来的都是最后一次输入的值，你可以把str_add[sum_add]=add改成 strcpy(str_add[sum_add],add)

#include <stdio.h> void add(int sum_add, char* str_add) {     printf("\ntext?");fflush(stdout);     scanf(" %99s", str_add); }  int main(int argc, char* argv[]) {     char str[9][100];     int sum = 0;     while (1)     {         add(sum, str[sum]);         sum++;         for (int i = 0; i < sum; ++i)         {             printf("%s\n", str[i]);         }         if (sum>=9) break;     }     getchar();     return 0; } // //text?1 //1 // //text?22 //1 //22 // //text?333 //1 //22 //333 // //text?4444 //1 //22 //333 //4444 // //text?55555 //1 //22 //333 //4444 //55555 // //text?666666 //1 //22 //333 //4444 //55555 //666666 // //text?7777777 //1 //22 //333 //4444 //55555 //666666 //7777777 // //text?88888888 //1 //22 //333 //4444 //55555 //666666 //7777777 //88888888 // //text?999999999 //1 //22 //333 //4444 //55555 //666666 //7777777 //88888888 //999999999 //

char add[100]，这个add数组是个局部变量，每次函数调用完毕之后，都会被销毁。即使你保存了地址，其实该地址所指向的内容已经被释放了。其实你保存的只是一个野指针，很危险。之所以你说覆盖了之前的内容，其实是你调用add函数时，分配给add数组的地址是相同的。所以你str指针数组中保存的内容其实都是同一个地址，而这个地址中的内容又被你每次更新了。你在char add[100];后面加一句printf（“%d”,(unsigned int)add);看一下 什么都清楚了。我表达能力有限。

引用 2 楼 u012395902 的回复:我试了下把void add的都写到main里面，还是出现同样的问题……  引用 1 楼 weixin_30460121 的回复:因为add是局部变量，当执行add()函数时，将add的地址赋给str_add，函数执行完毕后，该地址所指向的内存即背释放，所以第二次printf的时候，前面的指针指向的内容已发生变化  add = malloc(100);


Question: ssl协议是如何解决这 用户发的报文签名的？

看不到 CA 是用来确认服务器身份的, 跟 密钥交换没关系么,  参与密钥交换的不管在啥时候都是服务器证书, 跟 CA 没关系 ...  那个提示是告诉你服务器是不可靠的.

引用 12 楼 mLee79 的回复:IE6 缺省使用 SSL2 SSL3 , 现在一些服务器配置成了只支持 TLS 了,  IE6 当然就登不上.  你在 IE6里设置成使用 TLS应该就能连接了, 不过IE6应该只支持 TLS1.0, 不过你改抓包确认...  CA 是用来确认服务器身份的, 跟 密钥交换没关系,  按照规矩, CA证书不应该在互联网上传播.  你跟服务器的通讯仍然是 https 加密的, 但是服务器是不能信任的...    当我用其他浏览器访问邮箱，勾选了ssl项目，这个时候，又是什么协议？ http ? https ?   如果是后者， 由于公司自己做了个ca，自己搞证书，我的浏览器必须告警，似乎也没有提示我安装根证书。 按照大神的说话，它把网站的证书发到我计算机里，浏览器缓存了。 由于浏览器告警，”当我依然一意孤行“继续访问，这个时候，浏览器是什么行文？ 它如何获取到网站的公钥？   按照ssl的握手，它需要用网站公钥来加密”前主密钥“，然后发送给网站。  由于证书不信赖，我也没有安装不信赖的根证书，至少我没有点击根证书的操作。 没有安装根证书，那么如何完成这个ssl握手呢？

分析通信必须要抓包。

引用 7 楼 mLee79 的回复:私钥应该永远不在互联网上传播,    正常的个人证书应该是    个人自己生产私钥 PKEY,  根据私钥填写信息后生成证书签名请求 CSR, 然后你把证书提交给 CA 签名生成证书,  得到证书后才是你自己用 私钥和证书打包成 PKCS#12 的个人  非常感谢兄台和楼下楼上的几个兄弟不厌其烦的回答。   昨晚又看了ssl的握手和通信。当然看归看，理论毕竟是理论。我喜欢试验性思考一些小问题。 希望大家别觉得我烦。   试验：   用古来的系统xp, 这机器很少装软件，登录某个公司邮箱，（某公司自己搞的邮箱,邮箱主页上出现coremail这个字），登录之前，我需要输入用户名和密码，密码这个编辑框下有个选项："ssl登录“。 我勾选了该选项，结果无法接入该邮箱。只好把该选项去掉。结果我们的古老的ie浏览器就进入了。 由于ie版本非常古老，不像现在的浏览器 会在网址输入框的左侧提示红色或者绿色。（注：红色是说明 该邮箱的证书不可靠）， 绿色（可靠）。  1. 证书是该公司自己做的，没有经过任何ca认证。那么为什么使用ie的时候，必须 去掉那个”ssl登录“选项才能进入系统。否则无法进入？  这个背后隐藏了什么知识？  你也许会问，因为ie强大。当ie 认为这个证书不可靠，所以无法使用ssl协议。 所以你登录不了，不奇怪。  2.  那么我换个浏览器试试， 这个浏览器从网上下载，新浏览器名字暂时不透漏， 我开始登录邮箱（默认勾选邮箱首页上的"ssl登录”）。 新浏览器登录进去了，网页左上角 出现红色告警（说明该证书不可靠,因为是公司自己给自己搞的一个证书）。  虽然提示不可靠，但我依然用ssl登录了进去了。 那么新浏览器，为什么可以登录呢？  3. 新浏览器访问邮箱的时候，按照ssl的理论， 会去下载服务器的数字证书，然后安装（因为没有根证书嘛）， 这一切是在后台进行，用户不知道。  那么我用certmsg.msc打开windows的证书表看看，到底有没有安装该证书。  打开后，没有发现有该证书的关键字。既然没有安装，那么浏览器无法获取该邮箱的公钥， 自然无法用ssl协议和服务器握手，获取到通信用的对称密钥。  请问： 新浏览器进入邮箱，是伪https?   3个问题，希望有高手指教一下。

几个基本的东西要先弄清楚：  非对称加密，A/B为一对密钥，A加密，B解密，或者反过来。 如果把A/B密钥对给予公／私之分，那么私钥加密，公钥解密，这是签名（验证）；公钥加密，私钥解密，这是加密（安全传输）。 对于密钥，加上一些其它元信息，是以为证书；再加上证书链，是以为整个证书体系。  对称加密，双方持相同密钥，你加密我解密，反之亦然。  对于SSL/TLS，它其实分两个阶段： 协商阶段： 1、浏览器（客户端）验证服务器，要求严格的场景（比如网银），服务器也要验证客户端（所谓的双向认证）。 这里的验证，抛开证书的细节不谈，其实就是用的非对称加密中的“私钥加密，公钥解密” 2、通信双方协商出一个对称密钥，这里用到了“公钥加密，私钥解密” 通信阶段： 到此为止，双方应该相互信任（通过了认证），然后使用协商出来的对称密钥，对通信过程进行加密。

私钥应该永远不在互联网上传播,    正常的个人证书应该是    个人自己生产私钥 PKEY,  根据私钥填写信息后生成证书签名请求 CSR, 然后你把证书提交给 CA 签名生成证书,  得到证书后才是你自己用 私钥和证书打包成 PKCS#12 的个人证书..  支付宝好像信不过大家的水平,   直接帮你生成私钥了..

支付宝的证书是 pkcs#12 的证书, 包含私钥和公钥, 并且私钥被标记为禁止导出.. 这个被服务器用来识别你的身份, 不用来做密钥交换 ...  ssl 的握手过程:       Client                                               Server        ClientHello                  -------->                                                       ServerHello                                                      Certificate*                                                ServerKeyExchange*                                               CertificateRequest*                                    <--------      ServerHelloDone       Certificate*       ClientKeyExchange       CertificateVerify*       [ChangeCipherSpec]       Finished                     -------->                                                [ChangeCipherSpec]                                    <--------             Finished       Application Data             <------->     Application Data  Server Certificate  包中包含服务器的证书, 在一些安全性要求不高的场合,  服务器证书都没有, 服务器公钥直接在 ServerKeyExchange 里发送,  ClientKeyExchange 包含用服务器公钥加密的前主密文...  如果安装了客户端证书, 客户端证书在 Client Certificate 中发送,  CertificateVerify 包含对之前的握手消息的签名...

引用 4 楼 mLee79 的回复:ssl 服务器证书是用来做密钥交换的,  没有每个包做签名... 密钥交换的过程是 客户端 选择  前主密文 , 用 服务器证书公钥加密, 发送给服务器, 服务器用私钥解码得到这个 前主密文,  然后按一定的算法获得所有的加密参数 ...   包的完整性是用 HMAC 来保证的...  ssl 可以选择要求客户端证书, 这时候客户端用私钥对前面的握手消息签名, 这一般会在要求比较高的场合下使用, 比如网银啊, VPN 啥的时候... 这个证书也只是在握手的时候用...  你好，我昨天看了密码学书籍， 书上确实说数字证书是存放 发送端的 公钥。  你的意思是： ssl中用的证书， 和书上的有差异？  ssl存放的有发送端的公钥和客户端用的私钥 ？  是这个意思吗

引用 2 楼 caddor9100 的回复:1.  证书里私钥？   公钥是什么？公开的， 私钥自然不是公开的， 服务器把证书给了用户，证书里多了一个私钥，用户用它来加密报文。  当然，服务器也用它来解密。  这个恐怕有问题， 你上csdn， 登录的时候，网站然给你进入https(这个里有证书，只是你不知道自己已经安装了）。  我和你下载的证书都一样， 我们都知道该网站加密的私钥。 这太恐怖了。  另外：   最为对称加密的私钥，不应该是每次都通信后，就废弃它吗？   2.  我做个试验：  用一台古老的，干净的xp 去访问csdn，看会不会要求我安装证书。  试验的结果，似乎证书的安装时背后安装。  额，你说的证书是那种公开的证书哦  我说的是像支付宝这类证书，是要你登录后网站验证了你的身份后才让你下载的。而且也说明了里面的私匙和公匙并不是一对。整个过程中时两对秘钥，服务器用私匙 A 加密的数据客户端用公匙 A 解密，客户端用私匙 B 加密的数据服务器端用 公匙 B 来解密。 客户端的证书里面包含的是 公匙 A 和 私匙 B，是不成对的。  另外，你说的那种公开的证书，只是用来让客户端验证服务器的身份的，客户端并不用它来加密数据。客户端生成一个随机数，发给服务器，服务器用私匙加密后返回给客户端，客户端用证书里的公匙解密，看和加密的那个随机数是否相同，以此来验证服务器的身份。

引用 1 楼 adlay 的回复:[quote=引用 楼主 caddor9100 的回复:]  1. 按照密码学教材的理论，数字证书存放的服务器签名用的公钥，  浏览器下载数字证书后，获取到公钥，有了这个公钥。 由于服务器发送的每个报文都签名了，  用公钥解“加密过的报文摘要”，然后验证报文是否被篡改。  这样似乎很安全了，有什么问题？   要说有问题， 浏览器发送报文给服务器（这个时候，浏览器成了发送方） ，它的报文谁签名？   它自己签名？ 它如果签名，那么它的公钥如何让服务器知道？  有人说了，它也可以搞一个证书给服务器啊，事实上，我们上网，我们没有自己的证书啊。    2.     ssl协议为什么能够解决我的问题1.  首先，ssh 并不会把所有数据都用这种不对称算法来加密，因为这样效率太低了。而是先和服务器协商一个对称加密的密匙，之后的数据用这个密匙来加密，而协商密匙的过程才使用公匙私匙这种非对称的加密方法。  然后，你下载的证书除了包含一个解密服务器数据的公匙外，还包括一个加密数据的私匙，当然它们并不是一对的，每一个都需要和服务器上的那组才能形成一对。 这个你可以打开一个 .pem 证书文件来查看，里面都是文本形式的。 如果你从 IE 里面导出一个证书的时候也会提示你是否导出私匙， 由此可见证书里面除了公匙是还包含私匙的[/quote]   1.  证书里私钥？   公钥是什么？公开的， 私钥自然不是公开的， 服务器把证书给了用户，证书里多了一个私钥，用户用它来加密报文。  当然，服务器也用它来解密。  这个恐怕有问题， 你上csdn， 登录的时候，网站然给你进入https(这个里有证书，只是你不知道自己已经安装了）。  我和你下载的证书都一样， 我们都知道该网站加密的私钥。 这太恐怖了。  另外：   最为对称加密的私钥，不应该是每次都通信后，就废弃它吗？   2.  我做个试验：  用一台古老的，干净的xp 去访问csdn，看会不会要求我安装证书。  试验的结果，似乎证书的安装时背后安装。

引用 楼主 caddor9100 的回复:1. 按照密码学教材的理论，数字证书存放的服务器签名用的公钥，  浏览器下载数字证书后，获取到公钥，有了这个公钥。 由于服务器发送的每个报文都签名了，  用公钥解“加密过的报文摘要”，然后验证报文是否被篡改。  这样似乎很安全了，有什么问题？   要说有问题， 浏览器发送报文给服务器（这个时候，浏览器成了发送方） ，它的报文谁签名？   它自己签名？ 它如果签名，那么它的公钥如何让服务器知道？  有人说了，它也可以搞一个证书给服务器啊，事实上，我们上网，我们没有自己的证书啊。    2.     ssl协议为什么能够解决我的问题1.  首先，ssh 并不会把所有数据都用这种不对称算法来加密，因为这样效率太低了。而是先和服务器协商一个对称加密的密匙，之后的数据用这个密匙来加密，而协商密匙的过程才使用公匙私匙这种非对称的加密方法。  然后，你下载的证书除了包含一个解密服务器数据的公匙外，还包括一个加密数据的私匙，当然它们并不是一对的，每一个都需要和服务器上的那组才能形成一对。 这个你可以打开一个 .pem 证书文件来查看，里面都是文本形式的。 如果你从 IE 里面导出一个证书的时候也会提示你是否导出私匙， 由此可见证书里面除了公匙是还包含私匙的


Question: 指针的引用传参错误，大神帮忙看看

...傻了，谢谢，我这是不懂脑子的结果

#include <stdio.h> void test(int **p2) {     static int a =1;     *p2 = &a;     printf("*p2=%p\n",*p2); } int main() {     int * p1 = NULL;      test(&p1);     printf("p1=%p,*p1=%d\n",p1,*p1);     return 0; }

C++ 语言里面才有引用，C 语言没有


Question: 如何把采集到的声音保存为wav？编的程序不能实现实时，求指导

传到上位机保存呗

引用 4 楼 paschen 的回复:参看：http://www.oschina.net/code/snippet_6981_5361看了以后觉得挺底层的，有点不懂

引用 3 楼 zhao4zhong1 的回复:其实我也不熟悉。只知道这个库处理音频很厉害。不然Record Anything软件也不会用它了。这个我看过后不是很理解，我再看看，感觉不太适用于lab windows

本来是用cvi实现这样的功能的，自动对采集到的时域数据进行处理并调用计算机声卡进行播放，但一直没思路，只好先保存，再播放。这个可以用bass库吗，不太熟悉这个库  引用 1 楼 zhao4zhong1 的回复:使用BASS库？ https://www.baidu.com/s?wd=bass%E5%BA%93&rsv_spt=1&rsv_iqid=0xf93197f600011445&issp=1&f=8&rsv_bp=1&rsv_idx=2&ie=utf-8&tn=baiduhome_pg&rsv_enter=0&oq=bass&rsv_t=c40ewHsRMdRTjlYkJ6QqmdRqWIThwPNirbRq4A1SoS6e5%2FaEwicCk92hyHzj9xmHFU3l&rsv_pq=f5ff69d9000102ab&rsv_sug3=11&rsv_sug1=7&inputT=22757&rsv_sug4=22757   本来是用cvi实现这样的功能的，自动对采集到的时域数据进行处理并调用计算机声卡进行播放，但一直没思路，只好先保存，再播放。这个可以用bass库吗，不太熟悉这个库


Question: 关于c库的一些疑问

1. 标准里只有一章 Library 介绍所有的库函数，并没有给这个库起名字。C库应该是来源与"C 语言的库"。 2. C 标准里 Library 一章介绍的 C 语言中应该包含的头文件，头文件中应该定义的函数、宏、常量、变量等，并详细说明了所有这些符号的含义和功能。这可能就是所谓的 C 库吧。 3. C 库既然是 C 语言的库，那个就只有 C 语言才会需要。鉴于系统里很多程序是用 C 语言写的，所以在系统中可能也可以找到。    对一个已经编译好的 C 程序来说，它可以将（它所用到的） C 库完全包含在自己的可执行文件中，这是你是看不到独立的 C 库的。当然它也可以动态链接库的形式依赖一个 C 库的 dll 。这个 dll 可能在系统目录，也可能在其它目录，只要程序运行时可以找到（如何找需要参阅 Windows 的文档）。由于不同的程序可能去不同的地方找，从而系统中也可能存在多个（可能相同也可能不同的）C 库。   至于 lib ，那是 C 语言编译需要的。lib 里存放的是已编译好 C 库，在 C 编译器遇到 C 库中的内容的时候，可以直接引用。 4. 靠名字。   上面说了，lib 里有已经编译好的 C 库。当你调用一个库函数的时候，编译器会去 lib 通过名字查找这个函数（这一步称作链接）。当你的程序包含几个源文件的时候，不同源文件中的函数调用也是这样通过名字查找的。 5. 老的 C 标准（C89）不要求在调用函数之前事先声明。新标准（C99）要求声明。但是并不是所有的C编译器都会按照新标准强制要求声明。所以现在你可能依然可以不经声明调用一个函数（比如不包含 stdio.h ，调用 stdio.h 中的函数）。 6. 这个，可能包括库的位置，你要链接那些库，等等。这里的库不一定只包含 C 库，还可以有其它库。只有 C 库的话，通常不用，编译器就搞定了。具体的要查询编译器文档。

1. c库指c语言可以用的库 2. c库里面没有函数定义, 而是已经翻译好的电脑能看懂的语言. 3. c库保存的位置与编译器有关, 是lib还是dll也与编译器有关. 4. 没错只有声明, 声明是给编译器看的, 编译后还有链接过程, 链接时, 就必须确保有定义了. 5. 因为stdio中的只是声明, 可以手工写出来, 6. 某个阶段就是链接阶段, 有些库是默认链接的, 所以不用显式地指定. 而有些需要显式指定.

C标准中定义的一些函数，比如printf，fopen这些库函数，写代码时直接调用就可以了，但是它们的实现是由各个编译器作者们提供的。比如在Windows，你用vs写C代码，最终代码在链接阶段需要把msvcrt（msvcrt.dll）引用到生成的可执行文件中，程序在执行的时候遇到printf就自动进入msvcrt.dll中完成相应功能，这个msvcrt.dll就是Microsoft提供的。Linux系统中的实现是glibc，编程过程中需要libc.so。


Question: 新手请教关于汉诺塔的问题。

scanf("%d", &n);


Question: 新人提两个问题！！非常急！！！

如果“单步printf对应的汇编指令几步后，你就会来到printf的源代码处。”不灵，请换VS20XX。

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

这是一种可能的解释：往屏幕上输出的字符最后是要写到显存中的。如果是可打印字符，如'a'、'b'、'c'之类，需要将他们写进去；如果是'\b'、'\n'、'\t'之类，调整显存中下一个字符的位置；等等。'\0'呢，不属于前面任何一种，就简单地向后移动一个位置得了，原来显存中可能有其他的东西，比如'a'，于是显示的就是上次遗留的符号了

没人来拯救我吗

引用 6 楼 zhao4zhong1 的回复:将printf("%c ",a[i]);改为printf("%02x ",(unsigned char)a[i]);  引用 4 楼 wang0635 的回复:1、那个a实际上是输出 '\0' 的效果 2、有的C系统中，对一些常用的函数可以不加头文件说明  引用 2 楼 q3733353520 的回复:是scanf的原因， "1112223333\0"，这才是你输入的字符串  你们看看我再最后一句输出a【9】的ascll码（’a‘）为0，然后在输出’\0‘的ascll码为0这是为什么我很苦恼。

void HexDump(char *buf,int len,int addr) {     int i,j,k;     char binstr[80];      for (i=0;i<len;i++) {         if (0==(i%16)) {             sprintf(binstr,"%08x -",i+addr);             sprintf(binstr,"%s %02x",binstr,(unsigned char)buf[i]);         } else if (15==(i%16)) {             sprintf(binstr,"%s %02x",binstr,(unsigned char)buf[i]);             sprintf(binstr,"%s  ",binstr);             for (j=i-15;j<=i;j++) {                 sprintf(binstr,"%s%c",binstr,('!'<buf[j]&&buf[j]<='~')?buf[j]:'.');             }             printf("%s\n",binstr);         } else {             sprintf(binstr,"%s %02x",binstr,(unsigned char)buf[i]);         }     }     if (0!=(i%16)) {         k=16-(i%16);         for (j=0;j<k;j++) {             sprintf(binstr,"%s   ",binstr);         }         sprintf(binstr,"%s  ",binstr);         k=16-k;         for (j=i-k;j<i;j++) {             sprintf(binstr,"%s%c",binstr,('!'<buf[j]&&buf[j]<='~')?buf[j]:'.');         }         printf("%s\n",binstr);     } }

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

请问为什么我的‘a'的ascll码是零？  引用 3 楼 shen_wei 的回复:0x0A 这个是换行符。。。。

关于2，猜测一下： C 语言使用函数是不需要声明的，但是如果不声明的话对函数的参数类型会有限制（不满足限制的函数就必须先声明在使用了，否则程序会出错）。你对 sqrt 函数的使用可能正好满足这个限制。  % 是不需要引用任何头的。

0x0A 这个是换行符。。。。

是scanf的原因， "1112223333\0"，这才是你输入的字符串

诚心求教！！！


Question: 关于汇总数据的实现代码

引用 2 楼 wang0635 的回复:代码没有问题。但是这个if是多余的，因为 iData_Counter < MAX_DATA_BUFF 的条件始终成立 是的，谢谢提醒。 开始的时候是没有加if的，后来在调试的时候逐步逼近，就有了这个if没有删除。  两段代码应该是相同功能，不知道为什么在Keil C51里面编译没有问题，运行起来就会有问题  今天调试的结果是在数据量MAX_DATA_BUFF很少，比如小于20的话，都没有问题，但是在大于200时运行就出状况，头疼

引用 3 楼 super_admi 的回复:给你一个类似的问题作为参考：http://blog.csdn.net/super_admi/article/details/46006789 谢谢！

引用 1 楼 hnwyllmm 的回复:第一个if少了一个右大括号没看到哪里缺少，这两端代码编译都可以通过的

第一个if少了一个右大括号


Question: 字符串的内存分布疑惑

优化~~~~~~~~

优化~~~~~~~~

相同的字符串常量是可以共享内存的。这样可以节省资源。


Question: 矩阵操作

已解决！我还是通过编程实现上面的梯度值的。不过楼上提供的A*算法比较经典！

引用 1 楼 zhao4zhong1 的回复:搜A*寻路算法. 好像不太一样啊？看得不太明白。我这个能实现吗！

引用 2 楼 user-2 的回复:不太明白,这些值怎么来的 上面一个矩阵中数值为1的位置，他在该位置就需要一个梯度值，这个梯度值赋值到下一个矩阵中。看懂了没？

不太明白,这些值怎么来的

搜A*寻路算法.


Question: 指针数组与数组指针

//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]

楼上的解释的挺好，我在VS上试了下。  学习了，谢谢！

指针是有类型的，你不能把一个指向 int 的指针 (int *) 赋值给一个指向字符的指针(char *)。 同样，你也不能把一个指向数组的指针（ int (*)[3]， &laxy[0] ) ，赋值个一个指向 int 的指针 (int *， p[0] ）


我是在VS中编译libxml2出现的这样的错误，解决如下，在 工程属性 -> 配置属性 -> 链接器 -> 输入 -> 附加依赖项 添加libiconv.lib库文件

引用 7 楼 xiaoshang_program 的回复:标准的链接错误  缺少iconv 这个函数库  iconv 函数库 是linux 版本 有win  你可以看看 我记得我原来编译过 可以的 iconv函数库我已经用include=F:\sohu_code\p2plive\third\libiconv-1.9.2-1-lib\include lib=F:\sohu_code\p2plive\third\libiconv-1.9.2-1-lib\lib命令include进来了

引用 6 楼 zhao4zhong1 的回复:[quote=引用 5 楼 u012115420 的回复:] [quote=引用 4 楼 zhao4zhong1 的回复:] 项目、属性、C/C++、附加包含目录：填写附加头文件所在目录 分号间隔多项 项目、属性、链接器、常规、附加库目录：填写附加依赖库所在目录 分号间隔多项 项目、属性、链接器、输入、附加依赖项：填写附加依赖库的名字.lib 空格或分号间隔多项我用的是dev C++跟keil，没这些设置的[/quote] 肯定有类似这些设置的地方，找找看。[/quote] 恩

引用 5 楼 u012115420 的回复:[quote=引用 4 楼 zhao4zhong1 的回复:] 项目、属性、C/C++、附加包含目录：填写附加头文件所在目录 分号间隔多项 项目、属性、链接器、常规、附加库目录：填写附加依赖库所在目录 分号间隔多项 项目、属性、链接器、输入、附加依赖项：填写附加依赖库的名字.lib 空格或分号间隔多项我用的是dev C++跟keil，没这些设置的[/quote] 肯定有类似这些设置的地方，找找看。

引用 4 楼 zhao4zhong1 的回复:项目、属性、C/C++、附加包含目录：填写附加头文件所在目录 分号间隔多项 项目、属性、链接器、常规、附加库目录：填写附加依赖库所在目录 分号间隔多项 项目、属性、链接器、输入、附加依赖项：填写附加依赖库的名字.lib 空格或分号间隔多项我用的是dev C++跟keil，没这些设置的

引用 2 楼 zhao4zhong1 的回复:重建所有试试看。重建过了，没有用，现在改mini xml了，不过mini XML可以#include <mxml.h>，使用mxml_node_t*xml;也没问题，但是调用mxmlNewXML("1.0")这几个函数就报错，请问你知道什么原因吗？

重建所有试试看。

求大神解答·····


Question: 将两个文件的同一行内容打印为一行

这是把两个文件的同一行内容打印到一行的程序。  我想问问这两行代码有必要吗？有什么用处啊？    if (str2 == EOF) //如果到文件尾最后，则输出换行，否则输出 空格分隔  	putchar('\n');  else  	putchar(' ');

引用 5 楼 zhao4zhong1 的回复:自己写日志。  有时不将“调用函数名字＋各参数值，进入函数后各参数值，中间变量值，退出函数前准备返回的值，返回函数到调用处后函数名字＋各参数值＋返回值”这些信息写日志到文件中是无论如何也发现不了问题在哪里的，包括捕获各种异常、写日志到屏幕、单步或设断点或生成core文件、……这些方法都不行！ 写日志到文件参考下面： #include <stdio.h> #include <stdlib.h> #include <string.h> #ifdef WIN32     #include <windows.h>     #include <io.h> #else     #include <unistd.h>     #include <sys/time.h>     #include <pthread.h>     #define  CRITICAL_SECTION   pthread_mutex_t     #define  _vsnprintf         vsnprintf #endif //Log{ #define MAXLOGSIZE 20000000 #define MAXLINSIZE 16000 #include <time.h> #include <sys/timeb.h> #include <stdarg.h> char logfilename1[]="MyLog1.log"; char logfilename2[]="MyLog2.log"; static char logstr[MAXLINSIZE+1]; char datestr[16]; char timestr[16]; char mss[4]; CRITICAL_SECTION cs_log; FILE *flog; #ifdef WIN32 void Lock(CRITICAL_SECTION *l) {     EnterCriticalSection(l); } void Unlock(CRITICAL_SECTION *l) {     LeaveCriticalSection(l); } #else void Lock(CRITICAL_SECTION *l) {     pthread_mutex_lock(l); } void Unlock(CRITICAL_SECTION *l) {     pthread_mutex_unlock(l); } #endif void LogV(const char *pszFmt,va_list argp) {     struct tm *now;     struct timeb tb;      if (NULL==pszFmt||0==pszFmt[0]) return;     _vsnprintf(logstr,MAXLINSIZE,pszFmt,argp);     ftime(&tb);     now=localtime(&tb.time);     sprintf(datestr,"%04d-%02d-%02d",now->tm_year+1900,now->tm_mon+1,now->tm_mday);     sprintf(timestr,"%02d:%02d:%02d",now->tm_hour     ,now->tm_min  ,now->tm_sec );     sprintf(mss,"%03d",tb.millitm);     printf("%s %s.%s %s",datestr,timestr,mss,logstr);     flog=fopen(logfilename1,"a");     if (NULL!=flog) {         fprintf(flog,"%s %s.%s %s",datestr,timestr,mss,logstr);         if (ftell(flog)>MAXLOGSIZE) {             fclose(flog);             if (rename(logfilename1,logfilename2)) {                 remove(logfilename2);                 rename(logfilename1,logfilename2);             }         } else {             fclose(flog);         }     } } void Log(const char *pszFmt,...) {     va_list argp;      Lock(&cs_log);     va_start(argp,pszFmt);     LogV(pszFmt,argp);     va_end(argp);     Unlock(&cs_log); } //Log} int main(int argc,char * argv[]) {     int i; #ifdef WIN32     InitializeCriticalSection(&cs_log); #else     pthread_mutex_init(&cs_log,NULL); #endif     for (i=0;i<10000;i++) {         Log("This is a Log %04d from FILE:%s LINE:%d\n",i, __FILE__, __LINE__);     } #ifdef WIN32     DeleteCriticalSection(&cs_log); #else     pthread_mutex_destroy(&cs_log); #endif     return 0; } //1-78行添加到你带main的.c或.cpp的那个文件的最前面 //81-85行添加到你的main函数开头 //89-93行添加到你的main函数结束前 //在要写LOG的地方仿照第87行的写法写LOG到文件MyLog1.log中             谢谢赵老师！！

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

找两个文件都有分别有两行文本与一行文本，再比较去代码与没去代码的区别。较直观。 考虑问题是从编程角度还是解决实际问题会遇到的情况？？？  如上讲的情况，当两个文件的第一行都读完，应该输出？。接下去第一个文件还有一行，第二个文件已经没有行了，应该输出？。


Question: 对一个数组赋值，为什么会改变另一个数组的值。

引用 3 楼 lm_whales 的回复:[quote=引用 1 楼 user-4 的回复:] j为29时j+1是30越界了  引用 1 楼 user-4 的回复:j为29时j+1是30越界了  引用 1 楼 user-4 的回复:j为29时j+1是30越界了++ [/quote]  引用 3 楼 lm_whales 的回复:[quote=引用 1 楼 user-4 的回复:] j为29时j+1是30越界了  引用 1 楼 user-4 的回复:j为29时j+1是30越界了  引用 1 楼 user-4 的回复:j为29时j+1是30越界了++ [/quote]  引用 3 楼 lm_whales 的回复:[quote=引用 1 楼 user-4 的回复:] j为29时j+1是30越界了  引用 1 楼 user-4 的回复:j为29时j+1是30越界了  引用 1 楼 user-4 的回复:j为29时j+1是30越界了++ [/quote]  引用 3 楼 lm_whales 的回复:[quote=引用 1 楼 user-4 的回复:] j为29时j+1是30越界了  引用 1 楼 user-4 的回复:j为29时j+1是30越界了  引用 1 楼 user-4 的回复:j为29时j+1是30越界了++ [/quote]  引用 3 楼 lm_whales 的回复:[quote=引用 1 楼 user-4 的回复:] j为29时j+1是30越界了  引用 1 楼 user-4 的回复:j为29时j+1是30越界了  引用 1 楼 user-4 的回复:j为29时j+1是30越界了++ [/quote]  引用 3 楼 lm_whales 的回复:[quote=引用 1 楼 user-4 的回复:] j为29时j+1是30越界了  引用 1 楼 user-4 的回复:j为29时j+1是30越界了  引用 1 楼 user-4 的回复:j为29时j+1是30越界了++ [/quote]  引用 3 楼 lm_whales 的回复:[quote=引用 1 楼 user-4 的回复:] j为29时j+1是30越界了  引用 1 楼 user-4 的回复:j为29时j+1是30越界了  引用 1 楼 user-4 的回复:j为29时j+1是30越界了++ [/quote]谢谢

引用 1 楼 user-4 的回复:j为29时j+1是30越界了  谢谢

编译器缺少越位 吹哨！！！

for(j=29;j>=0;j--) { OUT_ARI_TEM_AM[j+1]=OUT_ARI_TEM_AM[j]; }  j=29的时候 j+1就是30 OUT_ARI_TEM_AM[30] 已经越界。对其操作其结果是不可预料的。  至于对30下标赋值改变了另外一个数组。只不是是刚好另外一个数组的内存在30这里。  不知道你知道for执行的顺序不。明明+1了。  for（1；2；4） {       3 }  执行顺序 1 2 3 4.这么循环下去，直到退出

引用 1 楼 user-4 的回复:j为29时j+1是30越界了  引用 1 楼 user-4 的回复:j为29时j+1是30越界了  引用 1 楼 user-4 的回复:j为29时j+1是30越界了++

引用 1 楼 user-4 的回复:j为29时j+1是30越界了  引用 1 楼 user-4 的回复:j为29时j+1是30越界了  不好意思，我并没有+1


Question: 有三个问题请教，非常感谢

scanf那句改：scanf("%d", &score[index]);  你多了一个换行符，scanf会跳过其去读下一个字符，所以你必须再输入一个数

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

如果第一次输入11个数而不是10个数，下面可以显示10个数。输入10个数只显示九个数，再输入1个才会显示第10个输入的数，这是为什么？


Question: 求缩放比例算法

推荐看一下windows编程的，映射模式章节，那块看懂了，计算公式就有了，这种缩放就是一个计算公式。

感谢这么晚了还回复我的贴子  不好意思，估计是我没有表达清楚应用，还是没思路   广告牌子大小1800CM*600CM 有可能变化，但变化不会很大。  要实现这样的结果是  10米的时候完全能看得清楚广告牌上所有的字及图像，  这时假定就把广告牌缩小到屏幕最大宽度1440像素 (当前为1440*900)  还有一个限制条件 当输入5000米的时候电脑上的图像应缩小至1像素宽，  就有点像我们人眼看5公里以外的东西是一个小黑点。  求之间的换算公式，  即输入10的时候图像宽1440像素    输入5000的时候图像宽度1像素  其中输入10-5000之间的任何值，怎么求出应该是多少像素  其实可以不用管成像的其它因素，就是看算示那个比例，  纯数值计算公式，至于是不是那么大，也没有要求那么严格。  到底是不是10内能看清楚广告牌上的内容，这个不用考虑，或者是100米都可以自由设定  因为看的物体有可能很大，100米有可能都很清楚  所以，我们也可以假定100米完全能看清楚的时候，就视为在电脑上显示1440像素  也有可能10公里以看也看得到，那么这个时候输入10000的时候  就在电脑上显示1像素  意思是这个值可以自由设定但，  有两个事是限制了的，如10米或100米，对应的1440    和 5KM 或10KM 应用1像素这个是区域限制。  我想公式应该是一样的，只是多远能看清楚和模糊可以自己设置，但在屏幕上的1440和1像素是固定的。  即有可能 10对应该 1440 5000对应  1 或 100对应 1440 8000对应 1

引用 9 楼 cnslong 的回复:模拟一下上面的字体大小多远能看得清楚,以便调整广告的字体及重点表达的元素。  输入 5000米 3000米 100米，50米 看到的缩小版  字体大小，和远近成反比例 除了需要求出10 米的可见范围之外，其他都直接按照比例关系就可以了 这样算出的是大概的，然后根据实际感觉调整以下，不会有太大误差 所谓视角，就是物体两端都能看见（看得清晰）的这个角度  把 眼睛（晶状体）看成 一个透镜  穿过透镜中心的两条直线线（光线）正好经过物体两端，这两条线的夹角， 就是视角 物体和两条直线，构成等腰三角形 正切函数，求出 10米可视物体的大小 即可  如果你说的物体，就是广告牌，那么不需要再求出物体大小了 直接就是广告牌的大小 按比例缩放就是了，近大远小  几尺以内的图像，眼睛可以直接调节到清晰为止。 再远，例如10米。就不必调节了。图像基本直接可见了 这样，10～5000米 眼睛无须做多少调节  这个比例就是 10/X 越远字越小 X =10,20,50,,,,5000米  其余的不必说了吧

设x坐标表示距离（米），y坐标表示图像大小（像素），于是得到两个点分别为（10,1440）和（5000,1），根据直线方程的两点式： (x-x1)/(x2-x1)=(y-y1)/(y2-y1) 将已知的两点坐标代入上式，求出此直线的函数表达式，然后对于任何的x值，只要代入公式计算即可。  根据题目要求，在实际计算中，应该把x值限制在10到5000的范围，y值限制在1到1440的范围。

不知道对不对，测试误差不大，   		//计算实物到缩小的缩放比 实物大小/屏幕大小 CM 根据宽 		double fScaling=m_fWidth/m_fScreenWidth; 		m_nScaling=fScaling;   		//计算出宽度缩小后的尺寸 物体原始高度CM/缩放比例 		double fScalingHeightCM=m_fHeight/fScaling;    		//计算出1CM是多少个像素点 屏蔽像素点/屏幕大小CM 目的是求出缩放后的高度 作为当图片最大时的高度 		double fPerPx=m_fScreenWidthpx/m_fScreenWidth;   		//计算出缩放后的图像的原始高度像素点 缩放后的1CM代表的像素点 图片最大时的高度 		double fShowHeightOriginal;//缩放后最大高度 		fShowHeightOriginal=fPerPx*fScalingHeightCM;   		//计算出距离与屏幕像素点的关系,走近一米屏幕上缩小多少像素 从最大（屏蔽的像素点）到最小1个像素点 		double fPerDistancePx=m_fScreenWidthpx/(m_fMaxDistance-m_fMinDistance);   		//根据距离算出应缩小多少像素 向前移动的距离*移动1米缩小的像素点 		double fScalingPositivePx=(m_fDistance-m_fMinDistance)*fPerDistancePx;   	    //根据距离移动后的宽度为 图片最大的像素-应该缩小的像素 		m_nShowWidth=m_fScreenWidthpx-fScalingPositivePx;    	    //根据移到后的宽度计算出缩小倍数                 double fCalingHeight; 		fCalingHeight=m_fScreenWidthpx/m_nShowWidth;  		//根据倍数计算出缩小后的高度 		m_nShowHeight=fShowHeightOriginal/fCalingHeight;     		if(m_nShowWidth<1)//防止误差 		{			 			m_nShowWidth=1; 			MessageBox(_T("已经消失在视线中啦！"),_T("提示信息"),MB_OK|MB_ICONASTERISK); 		} 		if(m_nShowHeight<1)//防止误差 		{ 			m_nShowHeight=1; 			MessageBox(_T("已经消失在视线中啦！"),_T("提示信息"),MB_OK|MB_ICONASTERISK); 		}

引用 15 楼 cnslong 的回复:不是知道是不是这们的， 10应该的是1440 5000对应的是1  相当于5000-10=4990 表示1440像素 那么1米应该是多少像素呢？ 1440/4990=0.2885个像素点  那么当100的时候是多少像素呢？  起始点10 到100为90米  1440-90*0.2885=1351 即当输入100米的时候应该把电脑上的图像宽设置为1351像素  同  如果是2145米 公式应该是 1440-(1440/(5000-10))*(2145-10)=824(像素大约)  应该这样计算吧， 如果是50000 1440-(1440/(5000-10))*(50000-10)=0 引用 15 楼 cnslong 的回复:不是知道是不是这们的， 10应该的是1440 5000对应的是1  相当于5000-10=4990 表示1440像素 那么1米应该是多少像素呢？ 1440/4990=0.2885个像素点  那么当100的时候是多少像素呢？  起始点10 到100为90米  1440-90*0.2885=1351 即当输入100米的时候应该把电脑上的图像宽设置为1351像素  同  如果是2145米 公式应该是 1440-(1440/(5000-10))*(2145-10)=824(像素大约)  应该这样计算吧， 如果是50000 1440-(1440/(5000-10))*(50000-10)=0  比例是(1440-1)/(5000-10),看14楼才是正解

你这样算是可以的，稍微修改一下就行了。 假设距离为x，10<=x<=5000，需要浮点运算，则结果为：(int)(1440 - (((x + 0.001) - 10) / 4990 * 1440)) + 1;

完全可以这么来理解,这是个纯数字题，不用管成像问题。  10 对应该 1440   ---已知 20 对应多少 ? 50 对应多少 ? 。 。 。 。 5000对应 1   --已知  求当20,23,74,400,456......的时候怎么计算的。

假定5公里是一个黑点，电脑上是1像素大小  走近1公里 像素点是多少？  最终走近到离广告牌10米的时候，像素大小不能超过1440像素  这个比例应该受到1-1440的限制，

主要用于，模拟户外广告牌由远到近看到的效果，在电脑上显示出来。

引用 6 楼 lm_whales 的回复:20，5000  按照10米看到的范围，求出像素量即可  哈哈，大神，要不帮我写一下感觉还是有点晕

20，5000  按照10米看到的范围，求出像素量即可

如果，再考虑多一点，还有人的身高大概在160cm ～200cm ; 200以上的高个，160以下的矮个不算 另外，不考虑高山河流，只考虑平地，人眼平视，向上10度，向下身高是垂直可见范围。

人眼的视角极限大约为垂直方向150度，水平方向230度，如果在这个视角范围内都是屏幕，那么就会给我们一种身临其境的感觉。但这个角度太大，通常只有环幕电影才能达到这种效果。实际上，人视觉在10度是敏感区，10 ～20度可以正确识别信息，20～30度对动态东西比较敏感，当图像的垂直方向视角为20度，水平方向的视角为36度时，就会有非常好的视觉临场感，而且 也不因为频繁转动眼球造成疲倦  按照20度算  10米看到的范围是多少米（铅垂面的矩形或者正方形），按照20 度算求出来，或者水平36 垂直20 算， 这个 面中可视矩形（正方形），对应与屏幕的1440*900 这个比例就求出来了， 20，5000 同样求出来，就可以了

即 10---1440  已知 20--------? 2512----? 5000----1  已知

引用 1 楼 lm_whales 的回复:这和视角有关系 大约是 成比例的吧  就是大约这个比例值是多大，一般人能看到5公里以内的另一个人  比如10米的时候就是屏幕的宽度(1440*900),离得越远就越小，如果输入的是5000米，那么就在屏幕中显示1*1的像素点，  当然也可以设置5米为屏幕的最宽1000就显示成1*1的一个像素点这么小，  需要知道的这个比例怎么计算，  10米的时候对应的电脑像素点是多大。  500米的时候对应的电脑像素点是多大。  已知假设的条例是 10米 对应1440像素  5000米应用的是1像素

这和视角有关系 大约是 成比例的吧


Question: 关于linux c 文件读写

两个文件都没有 close

我直接到文件夹，直接打开，但是开不了

用什么打不开？ 你的文本编辑器吗？ 用 more 可以说明文件本身是没问题的撒


Question: 这个获取文件信息的意思应该怎么理解呢？

引用 2 楼 cl781121 的回复:[quote=引用 1 楼 adlay 的回复:] myfile 除了是一个结构，应该还有一个函数也叫这个名字才对  E:\share\examples/.prefs  Windows 的路径分隔符为 \ , UNIX 的路径分割符为 /  。 某些函数可能都接受，都是路径分隔符 .prefs 只是一个文件，并不是代表所有文件。 在 UNIX 系统下， 以 . 开头的文件作为隐藏文件  但是prefs前面还有个“.”，正常的文件是文件名+逗号+后缀名，这里只有逗号+后缀名 应该怎么解释呢[/quote]  windows 一般情况下文件名不能为空，但是通过一些手段也可以建立只有 .后缀的文件（文件名为空）。  Linux 下 . 在文件名里没有特殊含义（只含有 . 的文件名是有特殊含义的，表示当前目录），文件命名也没有所谓“文件名+.+后缀"的约束， .prefs 是一个很普通的文件名。（Linux 下 . 开始文件默认是隐藏的）  这个程序估计是 Linux 的直接拿到 windows 下来用了。

引用 1 楼 adlay 的回复:myfile 除了是一个结构，应该还有一个函数也叫这个名字才对  E:\share\examples/.prefs  Windows 的路径分隔符为 \ , UNIX 的路径分割符为 /  。 某些函数可能都接受，都是路径分隔符 .prefs 只是一个文件，并不是代表所有文件。 在 UNIX 系统下， 以 . 开头的文件作为隐藏文件  但是prefs前面还有个“.”，正常的文件是文件名+逗号+后缀名，这里只有逗号+后缀名 应该怎么解释呢

原来如此，多谢两位 彻底明白了


Question: linux c语言写个telnet自动输入密码？（关于pipe、重定向疑问）

你的是怎么解决的？我怎么在telnet链接上了之后执行的指令输出打印不出来。手动链接时回出现的账号密码提示行也打印不出来，退出提示倒是能打印。

向12楼学习！

代码就是12楼这样。。。显示不了我认为是因为重定向改变了输出位置，所以没输出到屏幕。

lz可以共享下你代码，在写个c的telnet自动登录

引用 10 楼 sand6174 的回复:有一段shell 脚本 ssh 自动输入密码的   echo "$0" function Help() {         echo "ip;password;cmd..."         exit 1 }  if [ $# -lt 3 ]; then        Help fi echo "ip: $1" echo "password: $2"  cmd="" i=0 for arg in "$@" do         let i++         if [ $i -le 2 ]; then                 continue         fi         cmd+="$arg " done  echo "cmd: $cmd "  expect -c "set timeout -1;         spawn ssh -l root $1 \"$cmd\";         expect {                 yes/no { send \"yes\r\"; exp_continue }                 *password* { send \"$2\r\"; interact}         };         expect eof;         " telnet 改改也能用

自定义函数rw_popen来打开一个支持读写的进程，用rw_pclose关闭，附带测试代码，已通过测试  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; }

我的代码是Windows上用的。 Linux下没搞过pipe，坐等楼下大神现身。

谢谢各位帮忙。。。已经解决。利用抓包软件看到现象。（代码和思路都是对的）因为无法看到输出。可以fgets来读取后输出

急阿，有人知道怎么处理吗

谢谢楼上的大神，新手表示看不懂。好像不是我想要的

仅供参考：#pragma comment(lib,"user32") #include <stdio.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, "dir *.txt /b\nexit\n");     WriteFile(           hPipeInputWrite,      // handle of the write end of our pipe           &szMsg,               // address of buffer that send data           18,                   // 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());           MessageBox(NULL, szMsg, "WinPipe", MB_OK);           break;       }        // do something with data.       szBuffer[dwNumberOfBytesRead] = 0;  // null terminate       MessageBox(NULL, szBuffer, "WinPipe", MB_OK);     }      // Wait for CONSPAWN to finish.     WaitForSingleObject (pi.hProcess, INFINITE);      // Close all remaining handles     CloseHandle (pi.hProcess);     CloseHandle (hPipeOutputRead);     CloseHandle (hPipeInputWrite);      return 0; }

@killer1978 大神，搜到11年您发的帖子。。。写过用无阻塞2个piple结合fock实现了进程间双向管道调用telnet,再自动输入用户名，密码的代码。 请问我遇到的问题您怎么解决的？能否给份源码？

我知道python比较好弄 不是一定用c的话, 可以试试

急急急！


Question: c语言     函数参数和隐式转换问题

1. C 允许不声明函数直接使用，或者声明函数但是不指明参数表。这两种情况下函数都可以接受任意参数。     但是，此时某些参数会有类型提升，如 char 会提升成 int ，float 会提升成 double 。  2. 对于在调用时函数已经声明了参数表的，调用的参数个数与类型需要与参数表匹配。每个参数都会转换为声明中对应参数的类型。  3. 如果函数调用时的参数数量、类型与定义时的不一致，结果是不可预知的。     C 对这中情况不能给出错误或警告，所以只能依赖程序员自己控制了。

引用 4 楼 u010424970 的回复:第二个，如果说编译器足够聪明，如果是我给的提示多还好，如果是这二个问题一起的话： 对于库 函数，int func2(float,float,float)是它实际的定义时的，结果我头文件声明却是int  func2(int,int,int),调用是func(2,2,2);那编译器的聪明也会少条件数据，提前先做相应的转换。 如果是这样，程序员只能去查看反汇编了去确定问题了吗？ 制作库的人如果给出一个错误声明的头文件，自然要对此负责， 库里面代码所使用的参数个数，类型，函数调用约定如果和头文件中的不一致，崩溃是很正常的。

引用 1 楼 stupid_boy2007 的回复:"对于c，函数的声明和调用参数个数和参数类型都可以不同，那在预处理、编译、汇编、链接中的编译过程中，对函数调用的参数个数和类型在声明或定义做了什么？" 应该只是在语义解析时，表明了是函数名而非其它。  “那这种隐式转换是出现在什么地方？” 编绎器足够聪明，在调用位置，先把参数隐式转换。  语义解析，我想到的是生成重定位目标文件时，编译器只是在ELF文件中的.symtab中确认一个func符号且为函数类型。  第二个，如果说编译器足够聪明，如果是我给的提示多还好，如果是这二个问题一起的话： 对于库 函数，int func2(float,float,float)是它实际的定义时的，结果我头文件声明却是int  func2(int,int,int),调用是func(2,2,2);那编译器的聪明也会少条件数据，提前先做相应的转换。 如果是这样，程序员只能去查看反汇编了去确定问题了吗？

1. 函数如果声明了参数，调用的时候就要求相同。如果没有参数，就写成 int func1(void)。 int func1() 这种形式在 C 里面是表示它接受任意参数了。      函数声明只是用来加查后面的函数调用是否正确，只在语法检查的时候起作用。     函数定义编译后会产生函数的代码，并给这个代码的首地址一个符号，链接的时候其他 obj 引用这个符号就替换成对应的地址。  2. 在 main 函数中。

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


Question: C语言socket programming第一次运行function成功，第二次调用报segmentation fault

问题是GDB查不出来，因为第一次call function时没问题，第二次call才出错。。

gdb是调试段错误的神器

进程意外退出会在当前目录下产生‘core’文件或形如‘core.数字’的文件比如‘core.1234’ 使用命令 gdb 运行程序名 core或core.数字 进入gdb然后使用bt命令 可以查看进程意外退出前函数调用的堆栈，内容为从上到下列出对应从里层到外层的函数调用历史。 如果进程意外退出不产生core文件，参考“ulimit -c core文件最大块大小”命令

代码太长了也看不了，我大概知道问题的原因就是socket，大侠请ctr＋f找 else if(!strcmp(packet.option, "send")) { 和 else if(!strcmp(packet.option, "help")) { 看一下这两个功能的socket写法有什么问题，前者是用来接发送两个client之间的信息，完全没问题， 但是第二个help只能成功调用一次，第二次调用就会segmentation fault，其他例如第一次调用chat后再调用help、quit之类的也会立刻挂掉，问题出现在我的socket写法上，希望大神能指点下

else if(!strcmp(packet.option, "allup")){                     fclose(tfp);                     bzero(buffer, BUFFSIZE);                 }             }             // Send to partner             j = (threadinfo.sockfd == channelmap[chptr][0])?1:0;             memset(&spacket, 0, sizeof(struct PACKET));             strcpy(spacket.option, "fileout");             strcpy(spacket.buff, file_name);             // Send download request             sent = send(channelmap[chptr][j], (void *)&spacket, sizeof(struct PACKET), 0);             channelmap[chptr][2]+=sent;             if((len = recv(channelmap[chptr][j],  (void *)&spacket, sizeof(struct PACKET), 0))>0){                 if(!strcmp(packet.option, "download")){                     if((tfp=fopen(file_name, "rb"))==NULL){                         error("ERROR cannot open file for read.");                         break;                     }                     while(!feof(tfp)){                         bzero(buffer, sizeof(buffer));                         readlen = fread(buffer, sizeof(char), BUFFSIZE, tfp);                         if(readlen > 0){                             strcpy(spacket.buff, buffer);                             sent = send(channelmap[chptr][j], (void *)&spacket, sizeof(struct PACKET), 0);                             channelmap[chptr][2]+=sent;                         }                     }                     fclose(tfp);                 }             }             memset(&spacket, 0, sizeof(struct PACKET));             strcpy(spacket.option, "alldown");             sent = send(channelmap[chptr][j], (void *)&spacket, sizeof(struct PACKET), 0);             channelmap[chptr][2]+=sent;               pthread_mutex_unlock(&clientlist_mutex);         }         else if(!strcmp(packet.option, "flag")) {         	pthread_mutex_lock(&clientlist_mutex);             oid = packet.oid;             int i,j;             struct PACKET spacket;             memset(&spacket, 0, sizeof(struct PACKET));             strcpy(spacket.option, "terminate");             strcpy(spacket.buff, "Either you or your partner is blocked.\n");             for(curr = client_list.head; curr != NULL; curr = curr->next) {                 if(oid == curr->threadinfo.uid) {                     curr->threadinfo.chatflag = 0;                       }             }             threadinfo.chatflag = 0;             for(j=0;j<2;j++){                 sent = send(channelmap[chanptr][j], (void *)&spacket, sizeof(struct PACKET), 0);                 channelmap[chanptr][2] += sent;             }             channelmap[chanptr][3] = 0;             blockId(oid); 			pthread_mutex_unlock(&clientlist_mutex);         }         else if(!strcmp(packet.option, "send")) {             int i, j;             char target[ALIASLEN];             //for(i = 0; packet.buff[i] != ' '; i++); packet.buff[i++] = 0;             oid = packet.oid;         	chanptr = threadinfo.channel;             strcpy(target, packet.buff);             struct PACKET spacket;             memset(&spacket, 0, sizeof(struct PACKET));              pthread_mutex_lock(&clientlist_mutex);             j = (threadinfo.sockfd == channelmap[chanptr][0])?1:0;             strcpy(spacket.option, "msg");             strcpy(spacket.alias, packet.alias);             strcpy(spacket.buff, packet.buff);             sent = send(channelmap[chanptr][j], (void *)&spacket, sizeof(struct PACKET), 0);             channelmap[chanptr][2] += sent;             pthread_mutex_unlock(&clientlist_mutex);         }         else if(!strcmp(packet.option, "quit")) {             printf("[%d] %d %s quit chatting...\n", threadinfo.sockfd, threadinfo.uid, threadinfo.alias);             int i,j;             struct PACKET spacket;             memset(&spacket, 0, sizeof(struct PACKET));             strcpy(spacket.option, "terminate");              pthread_mutex_lock(&clientlist_mutex);             for(curr = client_list.head; curr != NULL; curr = curr->next) {             	if(oid == curr->threadinfo.uid) {             		curr->threadinfo.chatflag = 0;		             	}             }             threadinfo.chatflag = 0;             for(j=0;j<2;j++){             	sent = send(channelmap[chanptr][j], (void *)&spacket, sizeof(struct PACKET), 0);             	channelmap[chanptr][2] += sent;             }             channelmap[chanptr][3] = 0;             pthread_mutex_unlock(&clientlist_mutex);         }         else if(!strcmp(packet.option, "exit")) {             printf("[%d] %d %s has disconnected...\n", threadinfo.sockfd, threadinfo.uid, threadinfo.alias);             int j;             pthread_mutex_lock(&clientlist_mutex);             struct PACKET spacket;             memset(&spacket, 0, sizeof(struct PACKET));             strcpy(spacket.option, "terminate");              for(curr = client_list.head; curr != NULL; curr = curr->next) {             	if(oid == curr->threadinfo.uid) {             		curr->threadinfo.chatflag = 0;		             	}             }             threadinfo.chatflag = 0;             for(j=0;j<2;j++){             	sent = send(channelmap[chanptr][j], (void *)&spacket, sizeof(struct PACKET), 0);             	channelmap[chanptr][2] += sent;             }             channelmap[chanptr][3] = 0;             list_delete(&client_list, &threadinfo);             pthread_mutex_unlock(&clientlist_mutex);             break;         }         else {             fprintf(stderr, "Garbage data from [%d] %d %s...\n", threadinfo.sockfd, threadinfo.uid, threadinfo.alias);         }     }      // clean up     close(threadinfo.sockfd);      return NULL; }

//strcpy(threadinfo.alias, packet.alias);              pthread_mutex_lock(&clientlist_mutex);             list_insert(&client_list, &threadinfo);             pthread_mutex_unlock(&clientlist_mutex);             pthread_create(&threadinfo.thread_ID, NULL, client_handler, (void *)&threadinfo);         }     }       return 0; }   void *admin_handler(void *param) {     char option[OPTLEN];     int i;     while(scanf("%s", option)==1) {         if(!strcmp(option, "end")) {             // clean up              printf("Terminating server...\n");             shutdown_sockets(&client_list);             pthread_mutex_destroy(&clientlist_mutex);             close(sockfd);             exit(0);         }         else if(!strcmp(option, "stats")) {             pthread_mutex_lock(&clientlist_mutex);             showstat();             pthread_mutex_unlock(&clientlist_mutex);         }         else if(!strcmp(option, "throw")){             pthread_mutex_lock(&clientlist_mutex);         	printf("Specify the client uid:");         	scanf("%d", &i);         	if(!throwId(i, &client_list, 0)){         		fprintf(stderr, "ERROR throwing uid:%d", i);         	}             pthread_mutex_unlock(&clientlist_mutex);         }         else if(!strcmp(option, "block")){             pthread_mutex_lock(&clientlist_mutex);         	printf("Specify the client uid:");         	scanf("%d", &i);         	if(!blockId(i)){         		fprintf(stderr, "ERROR blocking uid:%d", i);         	}             pthread_mutex_unlock(&clientlist_mutex);         }         else if(!strcmp(option, "unblock")){             pthread_mutex_lock(&clientlist_mutex);         	printf("Specify the client uid:");         	scanf("%d", &i);         	if(!unblockId(i)){         		fprintf(stderr, "ERROR unblocking uid:%d", i);         	}             pthread_mutex_unlock(&clientlist_mutex);         }         else if(!strcmp(option, "blocklist")){         	printf("----- BLOCK LIST ------\n");             pthread_mutex_lock(&clientlist_mutex);         	for(i=0;i<BLOCKLIST;i++){         		if(getnamebyuid(blockList[i], &client_list)!=NULL){         			printf("Uid : [%d] %s\n", blockList[i], getnamebyuid(blockList[i], &client_list));	         		}         	}             pthread_mutex_unlock(&clientlist_mutex);         }         else if(!strcmp(option, "start")){         	// Listen         	if(serverOn == 0){         		if(listen(listenfd, 10) < 0){ 					fprintf(stderr, "ERROR on listen"); 				}         	}         }         else {             fprintf(stderr, "Unknown command: %s...\n", option);         }     }     return NULL; }   void *client_handler(void *fd) {     struct THREADINFO threadinfo = *(struct THREADINFO *)fd;     struct PACKET packet;     struct LLNODE *curr;     int bytes, sent;     int uid, oid, chanptr;     uid = threadinfo.uid;     oid = 0;     while(1) {         bytes = recv(threadinfo.sockfd, (void *)&packet, sizeof(struct PACKET), 0);         if(!bytes) {             fprintf(stderr, "Connection lost from [%d] %s...\n", threadinfo.sockfd, threadinfo.alias);             pthread_mutex_lock(&clientlist_mutex);             list_delete(&client_list, &threadinfo);             pthread_mutex_unlock(&clientlist_mutex);             break;         }         chanptr = threadinfo.channel;         printf("[%d] %s %d %s %s\n", threadinfo.sockfd, packet.uid, packet.option, packet.alias, packet.buff);         if(!strcmp(packet.option, "connect")) {             //printf("[%d]Set alias to %s\n", packet.uid, packet.alias);             pthread_mutex_lock(&clientlist_mutex);             for(curr = client_list.head; curr != NULL; curr = curr->next) {                 if(compare(&curr->threadinfo, &threadinfo) == 0) {                     strcpy(curr->threadinfo.alias, packet.alias);                     strcpy(threadinfo.alias, packet.alias);                     break;                 }             }             struct PACKET spacket;             memset(&spacket, 0, sizeof(struct PACKET));             strcpy(spacket.option, "ackn");             strcpy(spacket.alias, packet.alias);             spacket.uid = uid;             spacket.oid = 0;             threadinfo.chatflag = 0;             sent = send(threadinfo.sockfd, (void *)&spacket, sizeof(struct PACKET), 0);             totalCount++;             pthread_mutex_unlock(&clientlist_mutex);         }         else if(!strcmp(packet.option, "help")) {         	pthread_mutex_lock(&clientlist_mutex);             struct PACKET spacket;             memset(&spacket, 0, sizeof(struct PACKET));             strcpy(spacket.option, "help");             spacket.uid = uid;             spacket.oid = oid;             strcpy(spacket.buff, "connect(to server)\nchat(find some one)\ntransfer(a file)\nflag(report misbehavior)\nsend(messages)\nexit(leave chat and disconnect)\n");             sent = send(threadinfo.sockfd, (void *)&spacket, sizeof(struct PACKET), 0);             pthread_mutex_unlock(&clientlist_mutex);         }            else if(!strcmp(packet.option, "send")) {             int i, j;             char target[ALIASLEN];             //for(i = 0; packet.buff[i] != ' '; i++); packet.buff[i++] = 0;             oid = packet.oid;             chanptr = threadinfo.channel;             strcpy(target, packet.buff);             struct PACKET spacket;             memset(&spacket, 0, sizeof(struct PACKET));                          pthread_mutex_lock(&clientlist_mutex);             j = (threadinfo.sockfd == channelmap[chanptr][0])?1:0;             strcpy(spacket.option, "msg");             strcpy(spacket.alias, packet.alias);             strcpy(spacket.buff, packet.buff);             sent = send(channelmap[chanptr][j], (void *)&spacket, sizeof(struct PACKET), 0);             channelmap[chanptr][2] += sent;             pthread_mutex_unlock(&clientlist_mutex);         else if(!strcmp(packet.option, "chat")) {         	int i, tgt;             char target[ALIASLEN];         	pthread_mutex_lock(&clientlist_mutex);         	struct PACKET spacket;             memset(&spacket, 0, sizeof(struct PACKET));             spacket.uid = uid;         	if(threadinfo.chatflag != 0){         		strcpy(spacket.option, "in_session");         		strcpy(spacket.buff, "You are already in a session.\n");         	}else if(ifblock(uid)){         		strcpy(spacket.option, "blocked");         		strcpy(spacket.buff, "You are blocked from chatting.\n");         	}else{         		if((oid = randPick(&chat_queue))==0){         			strcpy(spacket.option, "in_queue");                     strcpy(spacket.buff, "You are currently in the queue.\n");                     list_insert(&chat_queue, &threadinfo);         		}else{                     for(curr = client_list.head; curr != NULL; curr = curr->next) {                         if(oid == curr->threadinfo.uid) {                             sprintf(spacket.buff, "You are chatting with [%d] %s \n", oid, curr->threadinfo.alias);                             curr->threadinfo.channel = chptr;                             channelmap[chptr][0] = threadinfo.sockfd;                             channelmap[chptr][1] = curr->threadinfo.sockfd;                             inChat+=2;                             threadinfo.channel = chptr;                             break;                         }                     }                     strcpy(spacket.option, "in_session");                     threadinfo.chatflag = 1;                     chptr++;                 }         	}         	spacket.oid = oid; 			sent = send(threadinfo.sockfd, (void *)&spacket, sizeof(struct PACKET), 0); 			pthread_mutex_unlock(&clientlist_mutex);         }         else if(!strcmp(packet.option, "transfer")) {// transfer signal             struct PACKET spacket;             oid = packet.oid;             int chptr = threadinfo.channel;             int i,j;             char buffer[BUFFSIZE];             int readlen, writelen;             bzero(buffer, sizeof(buffer));             memset(&spacket, 0, sizeof(struct PACKET));             strcpy(spacket.option, "filein");             strcpy(spacket.buff, "Upload start\n");                          pthread_mutex_lock(&clientlist_mutex);             strcpy(file_name, packet.buff);             // Respond  to transfer request             sent = send(threadinfo.sockfd, (void *)&spacket, sizeof(struct PACKET), 0);             if((tfp = fopen(file_name, "wb")) == NULL){                 error("ERROR Can not open to write.");                 break;             }             int len = 0;             while(len = recv(threadinfo.sockfd, (void *)&packet, sizeof(struct PACKET), 0)){                 if(!strcmp(packet.option, "upload")){                     writelen = fwrite(buffer, sizeof(char), sizeof(packet.buff), tfp);                     if(writelen < sizeof(packet.buff)){                         error("ERROR File wirte error");                         break;                     }                     channelmap[chptr][2]+=len;                     bzero(buffer, BUFFSIZE);                 }


Question: 关于printf输出的数据类型

#include <stdio.h>  int main(int argc, char *argv[]) {     int a = 0x12345678;      printf("%x %llx\n", a, a);     printf("%x %llx\n", a, (long long)a);     return 0; }

%lld会从栈里取8个字节，a 是int型，压栈的时候只压了4个字，改成(long long)a就可以了

引用 4 楼 qq_31361473 的回复:[quote=引用 3 楼 赵4老师的回复:]将int a的值在内存中保存的起始地址处的8个字节按照long long int的格式输出。a实际占了前4个字节，后面的4个字节没人保证它全是00 为什么说是后面四个？不是前面四个？[/quote] 自己在调试器中打开内存窗口输入&a，查看内存中的字节值。  理解和讨论之前请先学会如何观察！  计算机组成原理→DOS命令→汇编语言→C语言（不包括C++）、代码书写规范→数据结构、编译原理、操作系统→计算机网络、数据库原理、正则表达式→其它语言（包括C++）、架构……  对学习编程者的忠告： 多用小脑和手，少用大脑、眼睛和嘴，会更快地学会编程！ 眼过千遍不如手过一遍！ 书看千行不如手敲一行！ 手敲千行不如单步一行！ 单步源代码千行不如单步Debug版对应汇编一行！ 单步Debug版对应汇编千行不如单步Release版对应汇编一行！  VC调试时按Alt+8、Alt+7、Alt+6和Alt+5,打开汇编窗口、堆栈窗口、内存窗口和寄存器窗口看每句C对应的汇编、单步执行并观察相应堆栈、内存和寄存器变化，这样过一遍不就啥都明白了吗。 对VC来说，所谓‘调试时’就是编译连接通过以后，按F10或F11键单步执行一步以后的时候，或者在某行按F9设了断点后按F5执行停在该断点处的时候。 （Turbo C或Borland C用Turbo Debugger调试,Linux或Unix下用GDB调试时,看每句C对应的汇编并单步执行观察相应内存和寄存器变化。）

引用 3 楼 赵4老师的回复:将int a的值在内存中保存的起始地址处的8个字节按照long long int的格式输出。a实际占了前4个字节，后面的4个字节没人保证它全是00 为什么说是后面四个？不是前面四个？

你给的格式符与实际变量的类型不符，那结果肯定很难是正确的了。

错误的代码产生错误的结果，你看编译器都警告了  [root@localhost jwj]# cat main.c  #include <stdio.h>  int main () {   int a = 1;    printf ("%d,%lld\n", a, a);    return 0; } [root@localhost jwj]# gcc -g -Wall main.c  main.c: In function ‘main’: main.c:7: warning: format ‘%lld’ expects type ‘long long int’, but argument 3 has type ‘int’ [root@localhost jwj]# ./a.out  1,577731895119314945  如果你非要纠结的话，那下面这个你怎么解释？  [root@localhost jwj]# cat main.c  #include <stdio.h>  int main () {   int a = 1;    printf ("%d,%lld\n", a, a, 0);    return 0; } [root@localhost jwj]# gcc -g -Wall main.c  main.c: In function ‘main’: main.c:7: warning: format ‘%lld’ expects type ‘long long int’, but argument 3 has type ‘int’ main.c:7: warning: too many arguments for format [root@localhost jwj]# ./a.out  1,1


Question: 一个数如果等于其每一位数字的立方之和，则称此数为水仙花数，如153就是一个水仙花数，因为153=13+53+33。使用for语句编程求出100到999之间所有的

153=13+53+33?哈哈这叫水仙花？153 =1 +125+27

看错了  不要在意

个十百位的数字求错了吧

if(i=ge*ge*ge+shi*shi*shi+bai*bai*bai)  {  printf("%d ",i);  } 改成== 不然会把100到999的数字都打出来

比较是二个等号,==, 把编译开关全打开,应该有提示的

if(i=ge*ge*ge+shi*shi*shi+bai*bai*bai)  //里面是关系表达式，不是赋值表达式 还有主函数定义为空，就不要有返回值了。


Question: 程序运行都没什么问题，就是记事本里的数字要么是问号，要么是方框，其中数字为 19 2000 1001 20.

fwrite、fread是按二进制的，当打开记事本查看时都是乱码。fprintf()、fscanf()是以文本写入读出的，打开记事本查看时才不会是乱码

电脑内存或文件内容只是一个一维二进制字节数组及其对应的二进制地址； 人脑才将电脑内存或文件内容中的这个一维二进制字节数组及其对应的二进制地址的某些部分看成是整数、有符号数/无符号数、浮点数、复数、英文字母、阿拉伯数字、中文/韩文/法文……字符/字符串、汇编指令、函数、函数参数、堆、栈、数组、指针、数组指针、指针数组、数组的数组、指针的指针、二维数组、字符点阵、字符笔画的坐标、黑白二值图片、灰度图片、彩色图片、录音、视频、指纹信息、身份证信息……  推荐使用WinHex软件查看硬盘或文件或内存中的原始字节内容。  不要把 fopen("...","...");fscanf,fprintf,fgets,fgetc,fclose //读时把\r\n替换成\n，写时把\n替换成\r\n;读到\x1a就设置EOF;读写的内容当字符看待 和 fopen("...","...b");fseek,ftell,fread,fwrite,fgetc,fclose //不作以上替换，遇到\x1a仍继续读;读写的内容当字节看待 弄混了

fwrite、fread是按二进制的 想能在记事本中看，需要按文本方式


Question: 利用分治算法求中位数的算法设计

1.若midA=midB，返回midA； 2.若midA<midB，舍弃A中较小的一半，舍弃B中较大的一半； 3.若midA>midB，舍弃A中较大的一半，舍弃B中较小的一半；

求两有序数组x和y的第k个数，思路如下： 若k为1，则返回两数组的最小值 取x的第i个数x0，取y的第(k-i)个数y0 若x0=y0，则x0即为所求 若x0<y0，则丢弃x的前i个数，k=k-i，递归 若x0>y0，则丢弃y的前(k-i)个数，k=i，递归  i取值尽可能地为k/2，每次丢弃k/2个数，O(log k) 取中位数时，k=(m+n)/2，O(log (m+n)) 当m=n时，k=n，O(log n)  public class Solution {     public double findMedianSortedArrays(int[] nums1, int[] nums2) {         if ((null == nums1) || (null == nums2)) {             return 0;         }          int total = nums1.length + nums2.length;         int middle = total >> 1;         if (0 == (total & 0x01)) {             int val1 = findKthSortedArrays(nums1, 0, nums1.length, nums2, 0,                     nums2.length, middle);             int val2 = findKthSortedArrays(nums1, 0, nums1.length, nums2, 0,                     nums2.length, middle + 1);             return (val1 + val2) / 2.0;         } else {             return findKthSortedArrays(nums1, 0, nums1.length, nums2, 0,                     nums2.length, middle + 1);         }     }      private int findKthSortedArrays(int[] nums1, int b1, int e1, int[] nums2,             int b2, int e2, int k) {         if (e1 - b1 > e2 - b2) {             return findKthSortedArrays(nums2, b2, e2, nums1, b1, e1, k);         }          if (b1 == e1) {             return nums2[b2 + k - 1];         } else if (1 == k) {             return Math.min(nums1[b1], nums2[b2]);         }          int i = Math.min(k / 2, e1 - b1);         int j = k - i;         int val1 = nums1[b1 + i - 1];         int val2 = nums2[b2 + j - 1];         if (val1 == val2) {             return val1;         } else if (val1 < val2) {             return findKthSortedArrays(nums1, b1 + i, e1, nums2, b2, e2, k - i);         } else {             return findKthSortedArrays(nums1, b1, e1, nums2, b2 + j, e2, k - j);         }     } }

分别求x,y数组的中位数，mid_x, mid_y，如果mid_x<mid_y，则将x的前一半舍弃，y的后一半舍弃;如果mid_x>mid_y，则反之;如果两个相等，则找到中位数。 第二步，接着找被折半的x,y的中位数


Question: 打印'\0'与“\0”与实际不相符

添加如下代码： char c[2]={'\0'}; 	printf("|%c|",c[0]);

所有字符，如果你一定要输出的话总会用一个样子的，具体样子是啥与操作系统(win, linux ...)，区域/语言设置(中文、英文、法文...)，终端程序(cmd, powshell, bash, ...)，字体设置等等都有关。  大概只有 ASCII 可显示字符区的显示起来一致性比较高，其它的（包括'\0'），显示成啥就只能自求多福了。

%s是输出\0之前的字符, 不包过\0 printf("|%c|\n",a[0]); %c是输出字符

输出字符，不管这个字符能不能正确输出，都会占一个字符格位，不光是'\0'，楼主，你可以试试别的不能显示的字符，都是如此

为什么不参考printf对应的源代码呢？


Question: 关于Linux C 与window C 的网络编程

恩，我在visual studio 上跑起来了，不过用文件的扩展名用的   。cpp   ，我没学过，C++ ,   和C语言有严格的区分吗

引用 12 楼 a962443153 的回复:SXJIAKE  谢谢了，大神， 好几天没上一直没有回复  这。。。。。。VC6 太老，c 代码不支持 C99/C11 随用随声明。可以稍微改改，把所有声明提前到该语句块的顶部。另外，我还忘了一个重要的事，winsock 之类的头文件需要放在 windows.h 之前，否则可能导致各种声明冲突错误。 #include <stdio.h> #include <stdlib.h>    #define WIN32_LEAN_AND_MEAN #define WINVER 0x0501  #include <winsock2.h>   #include <windows.h> #pragma comment(lib, "ws2_32.lib")   int main(int argc, char *argv[]) {     SOCKET sockfd = 0;     WSADATA wsaData = { 0 };      int ret = WSAStartup(MAKEWORD(1, 1), &wsaData);     if (ret != 0) {         return (-1);     }       sockfd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);     if (sockfd != INVALID_SOCKET) {         char data[32] = { 0 };         char buf[32] = { 0 };         struct sockaddr_in addr = { 0 };          // 主机         struct hostent *host = gethostbyname("bbs.csdn.net");         addr.sin_family = AF_INET;         // 端口         addr.sin_port = htons(80);         addr.sin_addr.s_addr = *((unsigned long*)*host->h_addr_list);         // connect         connect(sockfd, (SOCKADDR*)&addr, sizeof(addr));         // send         send(sockfd, data, sizeof(data), 0);         // recv         recv(sockfd, buf, sizeof(buf), 0);          closesocket(sockfd);     }      WSACleanup();       return 0; }这个代码只是例子，具体的还得你自己添加内容。

SXJIAKE  谢谢了，大神， 好几天没上一直没有回复  这。。。。。。

初学者，还是别乱用 你看看boost asio  那个对于你的思想很重要  然后自己就可以写一个了

#include <stdio.h> #include <stdlib.h>   #define WIN32_LEAN_AND_MEAN #define WINVER 0x0501   #include <windows.h> #include <winsock2.h> #pragma comment(lib, "ws2_32.lib")  int main(int argc, char *argv[]) {     WSADATA wsaData = { 0 };     int ret = WSAStartup(MAKEWORD(1, 1), &wsaData);     if (ret != 0) {         return (-1);     }      SOCKET sockfd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);     if (sockfd != INVALID_SOCKET) {         struct hostent *host = gethostbyname("bbs.csdn.net");         struct sockaddr_in addr = { 0 };         addr.sin_family = AF_INET;         addr.sin_port = htons(80);         addr.sin_addr.s_addr = *((unsigned long*)*host->h_addr_list);         // connect         connect(sockfd, (SOCKADDR*)&addr, sizeof(addr));         // send         char data[32] = { 0 };         send(sockfd, data, sizeof(data), 0);         // recv         char buf[32] = { 0 };         recv(sockfd, buf, sizeof(buf), 0);          closesocket(sockfd);     }      WSACleanup();      return 0; }

引用 8 楼 a962443153 的回复:其实网络编程的流程 我知道 ，socket ——  bind —— listen —— accept—— send / recv  就是不知道这几个函数在windows下还能不能用 ？ 都需要什么头文件 ？ VC++的库里都有吗　？　　都能用的，例子：#include <stdio.h> #include <stdlib.h>   #define WIN32_LEAN_AND_MEAN #define WINVER 0x0501   #include <windows.h> #include <winsock2.h> #pragma comment(lib, "ws2_32.lib")  int main(int argc, char *argv[]) {     WSADATA wsaData = { 0 };     int ret = WSAStartup(MAKEWORD(1, 1), &wsaData);     if (ret != 0) {         return (-1);     }      SOCKET sockfd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);     if (sockfd != INVALID_SOCKET) {             struct hostent *host = gethostbyname("bbs.csdn.net");             struct sockaddr_in addr = { 0 };             addr.sin_family = AF_INET;             addr.sin_port = htons(80);             addr.sin_addr.s_addr = *((unsigned long*)*host->h_addr_list);             // connect             connect(sockfd, (SOCKADDR*)&addr, sizeof(addr));             // send             char data[32] = { 0 };             send(sockfd, data, sizeof(data), 0);             // recv             char buf[32] = { 0 };             recv(sockfd, buf, sizeof(buf), 0);         }         closesocket(sockfd);     }      WSACleanup();      return 0; }

说“跨平台一定比不跨平台好”就和说“双性恋一定比异性恋好”一样！

Windows 的 API 绝大多数都是单词首字母大写命名，如：GetWindowText、CreateWindowEx 等。但对于网络编程这部分，据说早期也是抄袭 UNIX 的，因此包括名称和参数绝大多数是一样的，即全小写的命名风格。但还是有细微差别，如：close、ioctl 在 Windows 下用 closesocket、ioctlsocket 代替。现在开发 Windows Socket 程序需调用 WSAStartup 启动 Socket 库，WSACleanup 来关闭。Windows 程序员都知道，Windows API 只要是涉及到字符串参数的，大都分为两个版本，如 GetWindowTextA、GetWindowTextW，可能微软为了保持统一，在新版的系统中又推出了新的 Socket API，最初的一批是推出 Unicode 版本，如 GetHostNameW、GetNameInfoW，然而 ANSI 版还是 gethostname、getnameinfo，不过后来又推出新的一套 WSA 前缀的，比如 WSAConnet、WSAAccept，不过每个系列 API 也不完全涵盖。觉得微软这样越想统一越是乱套。既然你是 Linux 下编程的，那大多用的是纯 C 代码，如果你下载的是 C++ 封装的那几乎是不能用的。可以下载飞鸽的源代码学习一下，点击这里下载，这个也是 C++ 的进行了简单封装。

windows的跟linux的区别其实并不大，思想都是一样的，只 不过windows下的socket编程，在最前面会有一个初始化的操作，剩下的都一样 服务端                         客户端 1 创建socket            1 创建socket 2 绑定                        2 连接 3 监听 4 接受 发送接受消息，关闭连接

我也推荐用boost asio，简单强大，用ace太复杂了

应该用框架或组件，一套统一API，屏蔽各平台差异。 如Boost.Asio.

可以参考这个 http://blog.csdn.net/tpriwwq/article/details/17682141

函数几乎一样，逻辑完全一样，不应该有困难


Question: 使用for语句编程求以下表达式的值

先找规律。然后分成几个模块。接着全部连在一起。最后就是用语言实现。

这样：  int main(void) { 	int i, fenmu; 	double sum = 0; 	fenmu = 0; 	for (i = 1; i <= 10; i++) { 		fenmu += i; 		sum += 1.0 / fenmu; 	} 	printf("%f\n", sum); 	return 0; }

你得循序渐进了  先写个程序输出 1 1+2 1+2+3 ... 1+2+...+10 的结果吧。  然后在写一个（或者修改一下）求 1/1 1/(1+2) ... 1/(1+2+...+10) 的结果。  都调对了再做累加。

在C语言中，整数之间做除法：/，其结果仍是整数


Question: 有n个人围成一圈,顺序排号.从第1个人开始报数(从1到3报数),凡报到3的人退出圈子,问最后留下的是原来的第几号的那位。

约瑟夫环 用循环链表易于理解，易于找错

楼主，且不说你的问题出在哪里，就看您提问的方式。 1.直接上代码，问出什么问题，起码要有自己的一些分析过程，出问题的点在哪里。。等。 2.代码乱七八糟，连个缩进格式都没有。这样大家都没心情帮你调试了。 你看看回复你的两位高手的代码格式。

N年前面试时遇到过这个题，当时答错了，面试官跟我说用循环链表比较好做。

使用循环列表，这个问题就比较简单了

其实这道题最好的是用循环链表，这个时候考虑数据的组织比较好

引用 1 楼 zhao4zhong1 的回复:仅供参考：//假设有n个人团团围做，从第1个人开始数数，数到第m个人时候，第m个人出列， //然后继续从1开始数数，数到第m个人退出 #include <stdio.h> #include <conio.h> int i,k,t; int n,m; static char f[1001];//0该座位未出圈,1该座位已出圈 void main() {     while (1) {         printf("Input n m(1000>=n>=m>=1):");         fflush(stdout);         rewind(stdin);         if (2==scanf("%d%d",&n,&m)) {             if (1000>=n && n>=m && m>=1) break;         }     }     t=0;//已出圈总人数     i=1;//座位编号     k=1;//当前要数的数     while (1) {         if (0==f[i]) {             if (m==k) {                 t++;                 f[i]=1;                 printf("%3d ",i);                 if (0==t%10) printf("\n");                 if (t>=n) break;             }             k++;if (k>m) k=1;         }         i++;if (i>n) i=1;     }     cprintf("Press any key ...");     getch(); }    我已经有答案了，但是我不知道我写的错在哪里了，您能帮我看一下吗？谢谢！


Question: 求算法   将2的14次方个的二进制数字，打印输出第3位和第11位的数字相同的所有数!!!!!!!!!!!!

仅供参考：#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汉

#define BIT3(x) ((x)&4)     for(int i=0;i<(1<<14);i++)     {         if(BIT3(i>>8)==BIT3(i))             printf("%d\n",i);     }

int IsBit3SameBit11(int n) { 	return !((n >> 8 ^ n) >> 3 & 1); }


Question: C语言指针问题

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

请在debug时，查看内存信息即可。。

楼主真想弄明白的话，建议查一下什么是大端，什么是小端

引用 1 楼 adlay 的回复:i 在内存里面的内容是 0x78, 0x56, 0x34, 0x12 p++ 后指向第二个，自然就是 56 了  i 在内存里面的内容是 0x78, 0x56, 0x34, 0x12  //不是很明能解释清楚点吗？谢谢！

引用 1 楼 adlay 的回复:i 在内存里面的内容是 0x78, 0x56, 0x34, 0x12 p++ 后指向第二个，自然就是 56 了 同意一楼的说法

楼主的程序编译不过吧，无法从”int *“转换为"char *"

这个已经设计到编译器的具体实现与系统结构了。  不同的系统结构下可能会得到不同的结果。如果只是在学 C 的话，还是应该先不要管这种问题为好。


Question: 请问这里为什么老是Segmentation fault

printf(fmt,*args); fprintf(debug_stream,fmt, *aq);    应为 vprintf(fmt,args); vfprintf(debug_stream,fmt, aq);


Question: 求解决方案：我用socket模拟http请求，访问天气预报公共websever服务器接口，结果运行返回“http/1.1 400 bad request”

楼主这个可以获取到天气信息吗？？？

逐字节对比你的代码和可用的例子程序的包内容有何不同之处。

引用 6 楼 zhao4zhong1 的回复:楼主学习使用抓包软件比如wireshark正当时！  那怎么用抓包软件检查它的错误的地方呢

楼主学习使用抓包软件比如wireshark正当时！

引用 2 楼 user-3 的回复: 大半夜的爬起来开电脑看了看，看图吧，睡觉去咯。。。 还有我这是用GET方式访问的，要是换成POST方式呢，这个问题解决了马上给分

引用 3 楼 user-3 的回复:记得给分   太厉害了，问题解决了，可是为什么加几个换行符就行了呢？？

引用 11楼我是你的主体 的回复:[quote=引用 10 楼 user-3 的回复:] [quote=引用 5楼我是你的主体 的回复:][quote=引用 2 楼 user-3 的回复:]  大半夜的爬起来开电脑看了看，看图吧，睡觉去咯。。。 还有我这是用GET方式访问的，要是换成POST方式呢，这个问题解决了马上给分  [/quote]Post请求的协议头比Get多了个，提交数据的大小。 如图所示，将lenght替换为"theC..."提交数据的长度。  然后协议头 + 空行 + 提交数据，这样应该就可以了。   HttpWatch会使？ 方法已经说了，就看楼主你的了[/quote] 真乃大神也！！按照http请求的格式有条理的顺了一遍，加上换行符后果然就好了，多谢啦！！[/quote]大神不敢当，不敢当

引用 10 楼 user-3 的回复:[quote=引用 5楼我是你的主体 的回复:][quote=引用 2 楼 user-3 的回复:]  大半夜的爬起来开电脑看了看，看图吧，睡觉去咯。。。 还有我这是用GET方式访问的，要是换成POST方式呢，这个问题解决了马上给分  [/quote]Post请求的协议头比Get多了个，提交数据的大小。 如图所示，将lenght替换为"theC..."提交数据的长度。  然后协议头 + 空行 + 提交数据，这样应该就可以了。   HttpWatch会使？ 方法已经说了，就看楼主你的了[/quote] 真乃大神也！！按照http请求的格式有条理的顺了一遍，加上换行符后果然就好了，多谢啦！！

引用 5楼我是你的主体 的回复:[quote=引用 2 楼 user-3 的回复:]  大半夜的爬起来开电脑看了看，看图吧，睡觉去咯。。。 还有我这是用GET方式访问的，要是换成POST方式呢，这个问题解决了马上给分  [/quote]Post请求的协议头比Get多了个，提交数据的大小。 如图所示，将lenght替换为"theC..."提交数据的长度。  然后协议头 + 空行 + 提交数据，这样应该就可以了。   HttpWatch会使？ 方法已经说了，就看楼主你的了

记得给分

大半夜的爬起来开电脑看了看，看图吧，睡觉去咯。。。

引用 4楼我是你的主体 的回复:[quote=引用 3 楼 user-3 的回复:] 记得给分   太厉害了，问题解决了，可是为什么加几个换行符就行了呢？？[/quote]换行符多了，协议头错了。这是简单的错误。  HTTP请求的协议头，每行都应该有一个换行符。 然后协议头之后，一行空行，然后是提交的数据。Get可以没有数据，但是协议头后面与数据之间的空行一定要有。  你可以试一试，如果之间没有空行，程序会怎么样

完整的程序代码如下： #include "stdio.h" #include "stdlib.h" #include "winsock2.h" #pragma comment(lib,"ws2_32.lib") int main(int argc, char* argv[]) {    SOCKET hsocket;   SOCKADDR_IN saServer;   WSADATA     wsadata;   LPHOSTENT lphostent;   int     nRet;     char   Dest[3000];  char* host_name="www.webxml.com.cn"; char* req="GET /WebServices/WeatherWebService.asmx/getWeatherbyCityName?theCityName=57494 HTTP/1.1\r\n\r\n"//此为要发送的数据包  "Accept: image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, */*\r\n"  "Accept-Language: zh-cn\r\n" "Connection: Keep-Alive\r\n" "Host: Host: www.webxml.com.cn\r\n" "User-Agent: Mozilla/4.0 (compatible; MSIE 5.5; Windows 98)"; // 初始化套接字      if(WSAStartup(MAKEWORD(2,2),&wsadata))         printf("初始化SOCKET出错！");     lphostent=gethostbyname(host_name);          if(lphostent==NULL)              printf("lphostent为空！");       hsocket   =   socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);          saServer.sin_family = AF_INET;          saServer.sin_port = htons(80);          saServer.sin_addr =*((LPIN_ADDR)*lphostent->h_addr_list);       // 利用SOCKET连接       nRet = connect(hsocket,(LPSOCKADDR)&saServer,sizeof(SOCKADDR_IN));          if(nRet == SOCKET_ERROR)          {         printf("建立连接时出错！");              closesocket(hsocket);         return 0;     }     // 利用SOCKET发送        nRet = send(hsocket,req,strlen(req),0);       if(nRet==SOCKET_ERROR)       {           printf("发送数据包时出错！");           closesocket(hsocket);       }           nRet=1;          while(nRet>0)          {           // 接收返回数据包           nRet=recv(hsocket,(LPSTR)Dest,sizeof(Dest),0);              if(nRet>0)             Dest[nRet]=0;         else                  Dest[0]=0;           // 显示返回数据包的大小、内容          printf("\nReceived   bytes:%d\n",nRet);              printf("Result:\n%s",Dest);          } }


Question: C语言  数据结构    链表首节点的建立

楼主我强烈建议你学习下语法 typedef  typedef struct Student * List;  后边凡是含有struct Student * 都可以替换成 List 极大提高易读性

参考代码: https://github.com/707wk/Senior-middle-school/blob/master/Filling%20in%20the%20gaps.c

楼主，自己在纸上画画图就知道了。 如果没用if里的语句，只用else里的语句，在执行到pEnd->pNext=pNew;时，pEnd为NULL，如果执行pEnd->pNext，程序就会崩溃 如果不想每次创建一个节点都判断是否为第一个节点（执行效率来说，的确有点不妥），就在前面创建一个根节点，这个根节点不存放数据，只为了标记链表的入口

再供参考：//不带表头结点的单向链表 #include <stdio.h> #include <stdlib.h> #include <malloc.h> #include <time.h> #include <locale.h> struct NODE {     int          data;     struct NODE *next; } *head,*p,*q,*s,*p1,*p2,*q1,**ta; int i,k,n,t,m,v,N=10; int main() {     setlocale(LC_ALL,"chs");     srand(time(NULL));      head=NULL;      printf("创建%d个节点的单链表:",N);//创建N个节点的单链表     p=head;     for (i=0;i<N;i++) {         q=(struct NODE *)malloc(sizeof(struct NODE));         if (NULL==q) exit(1);         q->data=rand()%100;//填写0..99的随机值         q->next=NULL;         if (NULL==p) {             head=q;             p=head;         } else {             p->next=q;             p=q;         }     }      //输出整个单链表     s=head;     while (1) {         if (NULL==s) {             printf("\n");             break;         }         printf("%02d->",s->data);         s=s->next;     }      k=3;     v=5;     printf("将值为%d的结点插入到单链表的第%d个结点前:",v,k);//将值为v的结点插入到单链表的第k个结点前     n=0;     p=head;     while (1) {         if (NULL==p) {             break;         }         n++;         if (k==1) {             q=(struct NODE *)malloc(sizeof(struct NODE));             if (NULL==q) exit(1);             q->data=5;             q->next=head;             head=q;             break;         } else {             if (k-1==n) {                 q=(struct NODE *)malloc(sizeof(struct NODE));                 if (NULL==q) exit(1);                 q->data=5;                 q->next=p->next;                 p->next=q;                 break;             }         }         p=p->next;     }      //输出整个单链表     s=head;     while (1) {         if (NULL==s) {             printf("\n");             break;         }         printf("%02d->",s->data);         s=s->next;     }      k=5;     printf("删除第%d个节点:",k);//删除第k个节点     n=0;     p=head;     while (1) {         if (NULL==p) {             break;         }         n++;         if (k==1) {             q=head;             head=head->next;             free(q);             break;         } else {             if (k-1==n) {                 q=p->next;                 if (q) {                     p->next=q->next;                     free(q);                 }                 break;             }         }         p=p->next;     }      //输出整个单链表     s=head;     while (1) {         if (NULL==s) {             printf("\n");             break;         }         printf("%02d->",s->data);         s=s->next;     }      printf("从小到大排序:");//从小到大排序     for (p=head,p1=NULL;p!=NULL;p1=p,p=p->next) {         for (q=p->next,q1=p;q!=NULL;q1=q,q=q->next) {             if (p->data > q->data) {                  //交换data //              printf("swap %02d %02d\n",p->data,q->data); //              t=p->data;p->data=q->data;q->data=t;                  //或者                  //交换next //              printf("swap %02d %02d\n",p->data,q->data);                 if (p==head) {//p是头                     if (p->next==q) {//pq挨着                         head=q;                         p->next=q->next;                         q->next=p;                         q=p;                         p=head;                     } else {//pq不挨着                         head=q;                         p2=p->next;                         p->next=q->next;                         q->next=p2;                         q1->next=p;                         q=p;                         p=head;                     }                 } else {//p不是头                     if (p->next==q) {//pq挨着                         p1->next=q;                         p->next=q->next;                         q->next=p;                         q=p;                         p=p1->next;                     } else {//pq不挨着                         p1->next=q;                         p2=p->next;                         p->next=q->next;                         q->next=p2;                         q1->next=p;                         q=p;                         p=p1->next;                     }                 }                  //输出整个单链表 //              s=head; //              while (1) { //                  if (NULL==s) { //                      printf("\n"); //                      break; //                  } //                  printf("%02d->",s->data); //                  s=s->next; //              } //              getchar();             }         }     }      //输出整个单链表并计算链表长度n     n=0;     s=head;     while (1) {         if (NULL==s) {             printf("\n");             break;         }         printf("%02d->",s->data);         n++;         s=s->next;     }      printf("将整个链表逆序:");//将整个链表逆序     if (n>=2) {         ta=(struct NODE **)malloc(n*sizeof(struct NODE *));         if (NULL==ta) exit(1);         s=head;         for (i=0;i<n;i++) {             ta[i]=s;             s=s->next;         }         head=ta[n-1];         for (i=n-1;i>0;i--) {             ta[i]->next=ta[i-1];         }         ta[0]->next=NULL;         free(ta);     }      //输出整个单链表     s=head;     while (1) {         if (NULL==s) {             printf("\n");             break;         }         printf("%02d->",s->data);         s=s->next;     }      m=4;     n=6;     printf("将单链表中前%d个结点和后%d个结点进行互换:",m,n);//将单链表中前m个结点和后n个结点进行互换,m+n为链表总长     k=0;     p=head;     while (1) {         if (NULL==p) {             break;         }         k++;         if (m==k) {             q=p;         }         s=p;         p=p->next;     }     q1=head;     head=q->next;     s->next=q1;     q->next=NULL;      //输出整个单链表     s=head;     while (1) {         if (NULL==s) {             printf("\n");             break;         }         printf("%02d->",s->data);         s=s->next;     }      //释放所有节点     p=head;     while (1) {         if (NULL==p) {             break;         }         q=p->next;         free(p);         p=q;     }      return 0; } //创建10个节点的单链表:08->74->07->23->03->99->31->56->88->16-> //将值为5的结点插入到单链表的第3个结点前:08->74->05->07->23->03->99->31->56->88->16-> //删除第5个节点:08->74->05->07->03->99->31->56->88->16-> //从小到大排序:03->05->07->08->16->31->56->74->88->99-> //将整个链表逆序:99->88->74->56->31->16->08->07->05->03-> //将单链表中前4个结点和后6个结点进行互换:31->16->08->07->05->03->99->88->74->56-> //

仅供参考：//带表头结点的单向链表 #include <stdio.h> #include <stdlib.h> #include <malloc.h> #include <time.h> struct NODE {     int          data;     struct NODE *next; } H,*head,*p,*q,*s1,*s2,*s3,*s4,*s; int i,j,k,n,t,m; int main() {     srand(time(NULL));      //填写头节点数据     H.data=-1;     H.next=NULL;     head=&H;      //创建10个节点的单链表     p=head;     for (i=0;i<10;i++) {         q=(struct NODE *)malloc(sizeof(struct NODE));         if (NULL==q) return 1;         q->data=rand()%100;//填写0..99的随机值         q->next=NULL;         p->next=q;         p=q;     }      //输出整个单链表     s=head->next;     while (1) {         if (NULL==s) {             printf("\n");             break;         }         printf("%02d->",s->data);         s=s->next;     }      //将值为5的结点插入到单链表的第k个结点前     k=3;     n=0;     p=head;     while (1) {         if (NULL==p) {             break;         }         n++;         if (k==n) {             q=(struct NODE *)malloc(sizeof(struct NODE));             if (NULL==q) return 1;             q->data=5;             q->next=p->next;             p->next=q;             break;         }         p=p->next;     }      //输出整个单链表     s=head->next;     while (1) {         if (NULL==s) {             printf("\n");             break;         }         printf("%02d->",s->data);         s=s->next;     }      //删除第k个节点     k=5;     n=0;     p=head;     while (1) {         if (NULL==p) {             break;         }         n++;         if (k==n) {             q=p->next;             if (q) {                 p->next=q->next;                 free(q);             }             break;         }         p=p->next;     }      //输出整个单链表     s=head->next;     while (1) {         if (NULL==s) {             printf("\n");             break;         }         printf("%02d->",s->data);         s=s->next;     }      //从小到大排序     for (p=head;p!=NULL && p->next!=NULL;p=p->next) {         for (q=p->next;q!=NULL && q->next!=NULL;q=q->next) {             if (p->next->data > q->next->data) {                  //交换data //              printf("swap %02d %02d\n",p->next->data,q->next->data); //              t=p->next->data;p->next->data=q->next->data;q->next->data=t;                  //或者                  //交换next //              printf("swap %02d %02d\n",p->next->data,q->next->data);                 s1=p->next;                 s2=p->next->next;                 s3=q->next;                 s4=q->next->next;                  if (s2!=s3) {                      p->next=s3;                     s3->next=s2;                      q->next=s1;                     s1->next=s4;                 } else {                      p->next=s3;                     s3->next=s1;                            q=s3;                     s1->next=s4;                 }                  //输出整个单链表 //              s=head->next; //              while (1) { //                  if (NULL==s) { //                      printf("\n"); //                      break; //                  } //                  printf("%02d->",s->data); //                  s=s->next; //              } //              getchar();             }         }     }      //输出整个单链表     s=head->next;     while (1) {         if (NULL==s) {             printf("\n");             break;         }         printf("%02d->",s->data);         s=s->next;     }      //将单链表中前 m 个结点和后 n 个结点进行互换,m+n为链表总长10     m=4;     n=6;     k=0;     p=head;     while (1) {         if (NULL==p) {             break;         }         k++;         if (m+1==k) {             q=p;         }         s=p;         p=p->next;     }     s1=head->next;     head->next=q->next;     s->next=s1;     q->next=NULL;      //输出整个单链表     s=head->next;     while (1) {         if (NULL==s) {             printf("\n");             break;         }         printf("%02d->",s->data);         s=s->next;     }      //释放所有节点     p=head->next;     while (1) {         if (NULL==p) {             break;         }         q=p->next;         free(p);         p=q;     }      return 0; } //18->94->58->17->27->20->43->57->75->78-> //18->94->05->58->17->27->20->43->57->75->78-> //18->94->05->58->27->20->43->57->75->78-> //05->18->20->27->43->57->58->75->78->94-> //43->57->58->75->78->94->05->18->20->27-> //


Question: 新手练习，一元二次方程求解报错，求大神帮忙。error C2143: syntax error : missing ';' before '{'

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

else (delta < 0)   ==>  else if (delta < 0)


Question: 请问什么是流，流的定义是什么？

以我个人的理解，流就是纯粹的二进制，也就是字节流。对于二进制而言，就没有什么字符串，数字，文字或乱码，长度等概念。

Ｃ流操作有，scanf,printf 系列函数，fread,fwrite ，getc,fgetc,gets,fgets　fopen,fclose,fflush,fseek,rewind等 ｃ 有　stdin,stdout,stderr　等流指针 c++ 有 cin,cout,cerr 等标准流对象 <<,>>　是输入输出，基本流操作，也有一些流类的方法　用于访问流。、

流的概念就是水流，气流，连绵不断的那种。 计算机里，指的是　连绵不断的字节，数据块等　带缓冲的数据流。  C,C++流，分别对应与 FILE* 和stream　类模板 （istream.ostream,iostream,等） 分为字节符流（文本文件），二进制流（二进制文件）等等， 其实就是文件（带缓冲的文件的数据结构）　包括设备文件，和磁盘文件。  这些流　代表　屏幕，串口，（网络），打印机　等设备　和磁盘文件。  有时候，字符串，也被看成是流。

7.21.2 Streams 1 Input and output, whether to or from physical devices such as terminals and tape drives, or whether to or from files supported on structured storage devices, are mapped into logical data streams, whose properties are more uniform than their various inputs and outputs. Two forms of mapping are supported, for text streams and for binary streams.266)


Question: BIOS-ID如何获取

谢谢2楼 已经获取到了

SMBIOS 这个关键字。。。

搜“devcon”？


Question: 函数递归调用

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

#include <stdio.h> #include <string.h>  void DisplayNames(char **cNameArray);  char*cNames[]= {     "Aaron",     "Jim",     "Charles",     "Sam",     "Ken",     "end" };  int main() {     DisplayNames(cNames);     return 0; }  void DisplayNames(char** cNameArray) {     if(!strcmp(*cNameArray, "end"))     {         return;     }     else     {         DisplayNames(cNameArray + 1);         printf("%s\n", *cNameArray);     } }


Question: 字符串替换功能，会随机出错。望指教。

好讨厌这种一行注释都不写的程序员

终于正常了. #include "stdio.h" #include "stdlib.h" #include "string.h"  char *strrpl(const char *src, const char *search, const char *replace){  	char *dst = NULL; 	char *FindedPos = NULL; 	const char *SrcCurPos = src; 	int lensw = strlen(search); 	int lenrw = strlen(replace);     int lendst = 0; 	int count = 0; 	while( (FindedPos = strstr(SrcCurPos,search)) != NULL ){ 		 		char *y = (char *)malloc((FindedPos - SrcCurPos + lenrw + 1)*sizeof(char));  		*(y + (FindedPos - SrcCurPos) ) = '\0'; 		if( count == 0 ){ 			dst = (char *)calloc((FindedPos - SrcCurPos + lenrw + 1),sizeof(char));  		} 		else{             lendst = strlen(dst); 			dst = (char *)realloc(dst, (FindedPos - SrcCurPos + lenrw + lendst + 1)*sizeof(char)); 			*(dst + lendst) = '\0'; 		}  		int len = FindedPos - SrcCurPos; 		memmove(y, SrcCurPos, len); 		strcat(y, replace); 		strcat(dst, y); 		SrcCurPos = FindedPos + lensw; 		free(y); 		y = NULL; 		count++;  	}  	int lenSrcCurPos = strlen(SrcCurPos); 	lendst = strlen(dst); 	dst = (char *)realloc(dst, (lendst + lenSrcCurPos + 1)*sizeof(char)); 	strcat(dst, SrcCurPos);  	FindedPos = NULL; 	SrcCurPos = NULL; 	return dst;  }   int main(int argc, char *argv[]){  	char *testsrc = "asd234mn3;4j;bef2344jr23455"; 	char *findword = "23"; 	char *replaceword ="|*-"; 	char *resultdst = strrpl(testsrc,findword,replaceword); 	printf("%s\n",resultdst); 	return 0; }

谢谢各位, 是 字符串长度 + 1就OK

字符串长度 + 1 试试！！

你好像开辟空间的时候都没有给最后的 '\0' 留地方啊。 把所有的 malloc realloc calloc 啥的开辟的长度都加个 1 吧


Question: 读取输入行里的第一个单词到数组，丢掉该行的其他字符，下列程序有什么错误？为什么每次运行输入稍长的字符串时，都会在单词后面加个奇怪的字符？

ct 自增在a[ct]赋值之后，即a[ct]总是为未赋值状态，添加'\0'的时候直接赋给a[ct]即可


Question: 1589 - Xiangqi修改了好多次老是错

有检测黑王吃掉车就活的情况吗

我好像检查了所有可能再下一步被吃掉的棋子


Question: c语言结构体地址的问题

//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]

可以得出结论： abc.a == 0x0028FF68 abc.b == 0x00401CBE

abc abc.a 都不是地址，不能用 %p 输出。

为什么啊，求解释！

懂了就好，自己搞懂忘不了

恭喜恭喜

我已经懂了！


Question: 深夜求教一个算法问题，求大神们来看看

仅供参考：#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); }  #include <stdio.h> #include <stdlib.h> void print(int res[], int num) {     static int L=0;     L++;     printf("%8d:",L);     for (int i=0;i<num;++i) {         printf(" %d", res[i]);     }     printf("\n"); } void split(int n, int m) {// n表示总数，m表示最大因子     static int res[100];// 保存结果     static int num=-1;// 当前因子下标      if (n<m || n<0 || m<1) return;     num++;     if (0==n) {// 递归终止条件，为0不可再分，直接输出         print(res,num+1);         num--;         return;     } else {         if (n==m) {// 不拆，直接输出             res[num]=m;             print(res,num+1);             num--;         } else {             // 拆分出第一个             res[num]=m;             n=n-m;              if (m>n) m = n; // 最大因子不可能大于总数              for (int i=m;i>=1;--i) {// 循环，第二个因子可以继续拆分，而且按照最大因子不同可以拆分成多个                 split(n,i);             }             num--;         }     } } void Split(int n) {     if (n<=0) return;     if (100<n) {         printf("Up to 100\n");         return;     }     for (int i=n;i>=1;--i) {         split(n, i);     } } void main(int argc,char **argv) {          if (argc<=1) Split(5);     else if (argc>=3) split(atoi(argv[1]),atoi(argv[2]));     else              Split(atoi(argv[1])); }

穷举法. 1. 网上搜一个排列的函数 2. 写一个检测排列中有没有冲突的函数 3. 对于分2个集合,就有<1,11>, <2,10>, <3,9>,  <4,8>, <5,7>, <6,6> 六大种分种, 每一种分别是C(12, 1) = 12, C(12, 2) = 66, ... C(12, 6) = 924种, 对每一种, 都检测一下有没有冲突, 然后统计之.

用一个表表示能不能共存 这个似乎是图算法


Question: 请问一下，这是哪里出了问题，一编译就出现错误

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

一楼正解

 	由中美日韩四国团队联手打造的东方校园魔幻恐怖巨制《笔仙魔咒》将于10月16日在全球同步公映。该片由《午夜凶铃》《暮光之城》《女高怪谈》主力团队联合国内《笔仙惊魂》主创团队，共同打造2.0升级版华语恐怖大片，该片力图制作水准向好莱坞看齐，为华语恐怖片打造一张全新的名片。

 	制作工艺向好莱坞看齐  即将被翻拍成日语版

 	《笔仙魔咒》融合了中美日韩四国团队的制作班底，旨在突破观众对过往国内低成本恐怖片的常规认知，从电影工艺上重新定义华语恐怖电影。为了保证影片的品质，美方监制丹尼尔·莫坚持要斥资两千万搭建一个主场景，美术部门租用全亚洲最大的摄影棚，按1:1比例搭建了一座医学院废弃实验楼，仅仅只为了十几分钟内容的拍摄。根据故事情节的需要，宋朵朵需要在一个树洞中躲避同学的追踪，为了更好地营造氛围，剧组又搭建了一棵占地面积600平方米、带有树洞的巨大古树，这种为了追求极致画面效果而不惜血本的做法在国内极为罕见。对于丹尼尔·莫超乎常人想象的大胆举措，本片的日方监制菅野一郎却表示赞赏。菅野一郎表示，他作为丹尼尔·莫多年的合作伙伴，他认为丹尼尔·莫在电影领域极富创造天分，他特别欣赏丹尼尔·莫突破常规的逆向思维，因为事后都证明丹尼尔·莫的新奇想法总能为电影的高品质加分不少。

 	来自韩方的金牌监制金宇正也对丹尼尔·莫的举措非常认可，他表示，惊悚巨制《笔仙魔咒》一开始就奔着国际化路线而去，是准备跟好莱坞制作一起PK的，所以每个细节都很重要，每个亮点都应该以尽善尽美的方式呈现出来，而不是为了省钱随便以次充好敷衍过去，毕竟大多数观众都是很聪明的，绝不能辜负了影迷的期待，虽然多花了不少钱，但一定可以为我们赢回良好的口碑。菅野一郎最近还在接受访谈中兴奋地告诉媒体，日本已经有公司对《笔仙魔咒》的故事创意相当感兴趣，准备购买本片的故事版权翻拍成日语版。

 	国际团队孵化超级恐怖IP  打造华语恐怖电影新名片

 	《笔仙魔咒》中国片方为了一切制作均朝好莱坞的惊悚电影标准看齐，不惜花重金力邀丹尼尔·莫、菅野一郎及金宇正这三位金牌监制加盟，这无疑是中国惊悚片影迷最大的福音。四国团队将各国电影中的经典恐怖桥段创造性地融合在这部电影中。《午夜凶铃》中贞子的造型，电话与铅笔这种日常生活所见事物的恐怖感营造；《女高怪谈》中女生之间的互相猜忌与怨恨；美式恐怖中的举叉怪人，假面魔鬼等等。这些经典意象与画面都被再次整合，将东方恐怖的“笔仙故事”讲得更加精彩绝伦，四国团队精诚合作终于打造出了一部可作为华语惊悚片最亮丽名片的好作品。为了给观影者极致的听觉体验，制片方还不惜重金邀请国际作曲大师井上存一为本片打造玄幻音乐。尼尔·莫庆幸地表示，《笔仙魔咒》是自己历年参与过最棒的亚洲惊悚电影，剧情恐怖悬疑烧脑的同时，还深蕴超越国界的文化内涵与艺术价值，能跨越不同的文化、种族和肤色，在全球引起普世共鸣，所以这部影片无论放在亚洲或是北美上映，都会有相当庞大的影迷追捧。

 	据悉，由知名惊悚片导演关尔操刀、资深媒体人兼影视编剧徐高栋等策划的《笔仙魔咒》系列的第二部已经关机，将全部在美国完成后期制作，该系列将被打造成一艘超级IP航母，计划连续投拍十二部构成一个超越《电锯惊魂》和《暮光之城》的系列大银幕电影。

 	10月16日，《笔仙魔咒》将携带惊悚魔幻的飓风席卷全球！

有一个中文逗号

惊现中文的逗号 if((fp=fopen("C:\\che"，"wb+"))==NULL)


Question: K阶斐波那契数列，为什么我编的运行不了？

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

void initqueue(SeQueue *q,int size) { 	//q=(SeQueue*)malloc(sizeof(SeQueue)); 	q->front=q->rear=0; 	q->size=size+1; }

楼主，自己先插断点跟踪一下，看看是哪出的问题


Question: C 问题分析!求大家分析过程...高分

整型的每一种都有无符号（unsigned）和有符号（signed）两种类型， （基本数据类型其实只有整型和浮点型  char  int  long  都是整型） 无符号版本和有符号版本的区别就是无符号类型能保存2倍于有符号类型的正整数数据。 由于在计算机中,整数是以补码形式存放的。根据最高位的不同，如果是1,有符号数的话就是负数；如果是无符号数,则都解释为正数。 所以声明为unsigned 的数据类型 编译器最后处理的时候 都表示正数。 所以最高位1的时候不做符号处理 而是做数值处理。 for(i = 2 ; i >= 0 ; i--) {  }  i 的值永远是0到2^sizeof（long）   i >= 0永远满足。 for会一直循环下去，或者崩溃

学习了！

效果不错

就是死循环呗，因为 unsigned 类型无法表示负值，向下越界了之后会循环回去变成很大的正值。

unsigned long i; 无论你怎么加还是减都不会小于零啊

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

目测是作业题

学习了

我最大的问题是这题值100份？

while（1） ｛  ｝

程序没错，只是是个死循环，或许不是程序员的本意。。当i=0时，i--后，i将变成long能取到的最大整数（正数），而不是-1，所以循环一直会继续

i是无符号长整型，for循环的判断语句永远都满足，永远处于循环中。

i是无符号long，没有负数，当i=0之后执行i--得到的值将是一个极大值也就是说这个程序将要陷入死循环

对于 unsigned long i 来说， i >= 0 永远是 true


Question: 请大家帮我看看哪写错了，不应该是还有相同的一行吗

引用 1 楼 user-2的回复:读写都有的话要用 "w+" 方式打开 就只有这个地方有错误吗，感觉还是不行哎

"r"  Opens for reading. If the file does not exist or cannot be found, the fopen call fails.  "w"  Opens an empty file for writing. If the file exists, its contents are destroyed.  "a"  Opens for writing at the end of the file (appending) without removing the EOF marker before writing new data to the file; creates the file first if it doesn't exist.  "r+"  Opens for both reading and writing. (The file must exist.)  "w+"  Opens an empty file for both reading and writing. If the file exists, its contents are destroyed.  "a+"  Opens for reading and appending; the appending operation includes the removal of the EOF marker before data is written to the file and the EOF marker is restored after writing is complete; creates the file first if it doesn't exist.  When a file is opened with the "a" or "a+" access type, all write operations occur at the end of the file.   The file pointer can be repositioned using fseek, but is always moved back to the end of the file before a write operation is carried out. Thus, existing data cannot be overwritten.   The "a" mode does not remove the EOF marker before appending to the file. After appending occurs, the MS-DOS TYPE command only shows data up to the original EOF marker and not any data appended to the file.   The "a+" mode removes the EOF marker before appending to the file. After appending, the MS-DOS TYPE command shows all data in the file.   The "a+" mode is required for appending to a stream file that is terminated with the CTRL+Z EOF marker.   When the "r+", "w+", or "a+" access type is specified, both reading and writing are allowed (the file is said to be open for "update"). However, when you switch between reading and writing, there must be an intervening fflush, fsetpos, or fseek operation.   The current position can be specified for the fsetpos or fseek operation.   In addition to the above values, the following characters can be included in mode to specify the translation mode for newline characters:   t  Open in text (translated) mode.  In this mode, CTRL+Z is interpreted as an end-of-file character on input.   In files opened for reading/writing with "a+", fopen checks for a CTRL+Z at the end of the file and removes it, if possible.   This is done because using fseek and ftell to move within a file that ends with a CTRL+Z can cause fseek to behave improperly near the end of the file.   Also, in text mode, carriage return–linefeed combinations are translated into single linefeeds on input, and linefeed characters are translated to carriage return–linefeed combinations on output.   When a Unicode stream-I/O function operates in text mode (the default), the source or destination stream is assumed to be a sequence of multibyte characters. Therefore, the Unicode stream-input functions convert multibyte characters to wide characters.   For the same reason, the Unicode stream-output functions convert wide characters to multibyte characters.   b  Open in binary (untranslated) mode; translations involving carriage-return and linefeed characters are suppressed.  If t or b is not given in mode, the default translation mode is defined by the global variable _fmode.   If t or b is prefixed to the argument, the function fails and returns NULL.   c  Enable the commit flag for the associated filename so that the contents of the file buffer are written directly to disk if fflush or _flushall is called.  n  Reset the commit flag for the associated filename to "no-commit." This is the default.

读写都有的话要用 "w+" 方式打开


Question: 关于CLIPS的一些问题

晕  没人啊


Question: 怎么去掉注册表的父项继承的权限呢？附上代码

我的这里真没用。。不知道你那里是如何显示的！！！

引用 3 楼 shen_wei 的回复:MACHINE\\SYSTEM\\CurrentControlSet\\Control\\TabletPC  按照楼主的描述。。我的注册表里面是空的。。不知道你要修改成什么的项？？ 只是是  win7 以后的 桌面用户系统 都有此注册表项啊     因为从vista之后  应该都支持平板了把

用 Process Monitor 实时监视文件系统、注册表、进程、线程和 DLL 活动。 http://www.microsoft.com/china/technet/sysinternals/utilities/processmonitor.mspx 或 WinAPIOverridehttp://jacquelin.potier.free.fr/winapioverride32/ 监视Explorer的行为。

都看不到我发的帖子？。