Question: 在32位机中为什么1KB是10位？

虽然没有按位寻址，但是既然楼主问了，那我们就假设有吧。  最小寻址单位为字节（Byte）时，寻址1KB=1024B=2^10B，所以要10位来寻址，要10根。 寻址1B=2^0B，所以要0位来寻址，即不需要地址总线。（你就这么一个地方可以放数据，还要我告诉你我要去哪儿找吗？？）  最小寻址单位为位（bit）时， 寻址1KB=1024B=2^10B=2^13bit， 所以要13根。 寻址1B=2^3bit，所以需要3根。因为根本不存在按位寻址，所以也没有楼主所说的“其实是8根”。  综上，其实寻址所需的位数（根数？）跟最小寻址单位没关系，主要是看要从多少个最小单位中找到特定的一个。 如果最小寻址单位是KB，那么一根线就可以寻址2KB的空间。  不知道这样楼主理解了没。。。

1024*8的意思是存1024个数 每个8位  10是地址总线的个数  2^10 =1024  可以寻址范围是1-1024 寻到的是8位的RAM 你可以这么理解 一个8位的RAM由一个3-8译码器 一个8-1的选择器和一个8位的锁存器构成吧 如果两个8位的RAM拼成16位的RAM的话 就需要一根地址总线来从这两个8为的RAM里面选择一个 这个即使1-2选择器 1024的话 就是10跟地址总线 不知道你懂了没有 有兴趣的话可以看看 编码的奥秘

引用 31 楼 xhw88398569 的回复:引用 19 楼 zhao4zhong1 的回复:据我所知：CPU都是按字节寻址，没有按位寻址的。是按照机器字长寻址，然后再偏移吗？ 《计算机组成原理》 地址总线、数据总线、RAM电路、……

楼主在题目中已经确认 1B是8位，这是前提，怎么又成了问题了。

char 就是一个字节 1024个字节就是1KB 一字节8位 1024个字节   1024*8

引用 33 楼 zhao4zhong1 的回复:引用 31 楼 xhw88398569 的回复:[quote=引用 19 楼 zhao4zhong1 的回复:] 据我所知：CPU都是按字节寻址，没有按位寻址的。是按照机器字长寻址，然后再偏移吗？ 《计算机组成原理》 地址总线、数据总线、RAM电路、……[/quote]要学的太多了，刚学python，又要学C++，Web。。。还想学服务器。刚毕业，大学都学的硬件和c

因为1字节即1Bytes = 8bit  即8位, 只能表示  0-255的数字即   0 - 0xFF    9bit能表示0-511    即 0x0  -  0x1FF 10bit能表示0-1023        即 0x0 -  0x3FF  所以10bit就能表示1KB了.

引用 28 楼 bbs2241 的回复:你没搞清楚大B，小b。一般说的大B是指byte，小b是bit  1Byte = 8bit 1KB = 1024B = 1024*8 bit

1K是指的1024个bit 是一个存储空间的大小 因为1024 = 2^10 所以占10个位  和电脑是32位 64位没有任何关系

#include <stdio.h> char *human(__int64 v) {     __int64 g;     int i,j;     char N[8]=" KMGTPE";     static char s[20];      g=512i64;     for (i=0;i<6;i++) {         if (v<g) break;//         g=g<<10;     }     j=(i-1)*10;     if (j<0) j=0;     if (j==0) {         if (i==0) {             sprintf(s,"%I64d B",v);         } else {//i==1             sprintf(s,"%.4lg KB",(double)v/1024.0);         }     } else {//j>0         v=v>>j;         sprintf(s,"%.4lg %cB",(double)v/1024.0,N[i]);     }     return s; } int main() {     __int64 d,t;     while (1) {         printf("Input a number(0..%I64d):",0x7FFFFFFFFFFFFFFFi64);         fflush(stdout);         rewind(stdin);         if (1==scanf("%I64i",&d)) {             if (d>=0i64) break;//         }     }     printf("%I64d is %s\n",d,human(d));      printf("\n");     d=0i64;t=512i64;     while (1) {         printf("0x%016I64x is %s\n",d,human(d));         d+=t>>2;         if (d>=t) {             d=t-1i64;             printf("0x%016I64x is %s\n",d,human(d));             d=t;             printf("0x%016I64x is %s\n",d,human(d));             if (d>=0x2000000000000000i64) {                 d=0x7FFFFFFFFFFFFFFFi64;                 printf("0x%016I64x is %s\n",d,human(d));                 break;//             }             if (d<0x0800000000000000i64) {                 d=d<<8;                 t=t<<10;             } else {                 t=d<<1;                 d+=t>>2;             }         }     }      return 0; } //Input a number(0..9223372036854775807):0x33333333333 //3518437208883 is 3.199 TB // //0x0000000000000000 is 0 B //0x0000000000000080 is 128 B //0x0000000000000100 is 256 B //0x0000000000000180 is 384 B //0x00000000000001ff is 511 B //0x0000000000000200 is 0.5 KB //0x0000000000020000 is 128 KB //0x0000000000040000 is 256 KB //0x0000000000060000 is 384 KB //0x000000000007ffff is 512 KB //0x0000000000080000 is 0.5 MB //0x0000000008000000 is 128 MB //0x0000000010000000 is 256 MB //0x0000000018000000 is 384 MB //0x000000001fffffff is 512 MB //0x0000000020000000 is 0.5 GB //0x0000002000000000 is 128 GB //0x0000004000000000 is 256 GB //0x0000006000000000 is 384 GB //0x0000007fffffffff is 512 GB //0x0000008000000000 is 0.5 TB //0x0000800000000000 is 128 TB //0x0001000000000000 is 256 TB //0x0001800000000000 is 384 TB //0x0001ffffffffffff is 512 TB //0x0002000000000000 is 0.5 PB //0x0200000000000000 is 128 PB //0x0400000000000000 is 256 PB //0x0600000000000000 is 384 PB //0x07ffffffffffffff is 512 PB //0x0800000000000000 is 0.5 EB //0x0c00000000000000 is 0.75 EB //0x0fffffffffffffff is 0.999 EB //0x1000000000000000 is 1 EB //0x1800000000000000 is 1.5 EB //0x1fffffffffffffff is 1.999 EB //0x2000000000000000 is 2 EB //0x7fffffffffffffff is 7.999 EB

据我所知：CPU都是按字节寻址，没有按位寻址的。

引用 17 楼 layershow 的回复:[quote=引用 14 楼 u010412073 的回复:] [quote=引用 10 楼 ForestDB 的回复:] 内存寻址时，是8个bit一起一次读出来的。另外1KB＝1024B＝2的10次B，按字节寻址是10根？ 那么同理1B＝8bit＝2的3次bit，如果按位寻址（不按字节），那么应该是3根就可以？但其实是8根吧？ [/quote] 1KB＝1024B＝2的10次B 1B＝8bit＝2的3次bit  这两个不同理，1KB = 1024B 与 1B = 1B 才是同理 按什么寻址是指编号单位，不是让你来换算位的 例如按照 4GB寻址  0 就是第一个 4GB，1就是第二个 4GB，用 1 根线就能表示这两个地址（状态 0 和 1） 这种方式的地址空间 1 根线映射了 8GB 的空间，但是，你注意这 4GB 你传不回来，不可能用这 1 根线传 4GB 数据 所以你不要想小于 8 根线能取回一个字节 你对这些概念都混淆了 [/quote] 这两个关系也不对应么？ KB＝1024B＝1024x8bit＝2的13次bit，需要13根？（按位寻址计算） 1B＝8bit＝2的3次bit，如果按位寻址（不按字节），那么应该是3根就可以？但其实是8根吧？ 另确认下在按字节寻址和按bit寻址时1KB和1B分别需要相应地址线几根？（4种情况）

引用 14 楼 u010412073 的回复:[quote=引用 10 楼 ForestDB 的回复:] 内存寻址时，是8个bit一起一次读出来的。另外1KB＝1024B＝2的10次B，按字节寻址是10根？ 那么同理1B＝8bit＝2的3次bit，如果按位寻址（不按字节），那么应该是3根就可以？但其实是8根吧？ [/quote] 1KB＝1024B＝2的10次B 1B＝8bit＝2的3次bit  这两个不同理，1KB = 1024B 与 1B = 1B 才是同理 按什么寻址是指编号单位，不是让你来换算位的 例如按照 4GB寻址  0 就是第一个 4GB，1就是第二个 4GB，用 1 根线就能表示这两个地址（状态 0 和 1） 这种方式的地址空间 1 根线映射了 8GB 的空间，但是，你注意这 4GB 你传不回来，不可能用这 1 根线传 4GB 数据 所以你不要想小于 8 根线能取回一个字节 你对这些概念都混淆了

引用 13 楼 zhao4zhong1 的回复:B － Byte b - bit K - 1024求大神对上面的问题解释下？

引用 13 楼 zhao4zhong1 的回复:B － Byte b - bit K - 1024 1KB＝1024B＝2的10次B，按字节寻址是10根？ KB＝1024B＝1024x8bit＝2的13次bit，需要13根？（按位寻址计算） 1B＝8bit＝2的3次bit，如果按位寻址（不按字节），那么应该是3根就可以？但其实是8根吧？ 为什么这种关系不对应？前面的＝号理解为有多少种情况？后面的理解为需要几根？ 另确认下在按字节寻址和按bit寻址时1KB和1B分别需要相应地址线几根？（4种情况）

引用 10 楼 ForestDB 的回复:内存寻址时，是8个bit一起一次读出来的。另外1KB＝1024B＝2的10次B，按字节寻址是10根？ 那么同理1B＝8bit＝2的3次bit，如果按位寻址（不按字节），那么应该是3根就可以？但其实是8根吧？

B － Byte b - bit K - 1024

你没搞清楚大B，小b。一般说的大B是指byte，小b是bit

引用 10 楼 ForestDB 的回复:内存寻址时，是8个bit一起一次读出来的。是不是32根线的任一一种状态就是1B？。只有 一根线的话可以确定2B？


Question: VC++2010使用openssl的des算法，出现：无法解析的外部符号 DES_ecb3_encrypt

7楼完美地解决了问题！

引用 6 楼 MZONE2020 的回复:[quote=引用 5 楼 mymtom 的回复:] 楼主确定一下工程是32位还是64位的，不知道是不是这个问题 电脑是 win7 64位系统 工程生成32位dll可以通过，但是生成64位时就会报这个错误[/quote] 那就是这个问题嘛，说好的32位，搞64位不出错才怪了。  #pragma comment(lib,"libeay32.lib") #pragma comment(lib,"ssleay32.lib")  解释：32位和64位不能混用的！

楼主确定一下工程是32位还是64位的，不知道是不是这个问题

引用 5 楼 mymtom 的回复:楼主确定一下工程是32位还是64位的，不知道是不是这个问题 电脑是 win7 64位系统 工程生成32位dll可以通过，但是生成64位时就会报这个错误

引用 1 楼 zhao4zhong1 的回复:将错误信息中出现的标识符放在google里面搜一下，看其在哪个.lib中，然后在本地硬盘上搜索该.lib,如果没有，在网上搜索相关库或模块下载安装，然后将其所在目录填写到“附加依赖库所在目录”中，将其名字添加到“附加依赖库”中，重新连接。 VC6： 工程、设置、C/C++、分类：Preprocessor、附加包含路径：填写附加头文件所在目录 逗号间隔多项 工程、设置、Link、分类：Input、附加库路径：填写附加依赖库所在目录 分号间隔多项 工程、设置、Link、分类：Input、对象/库模块：填写附加依赖库的名字.lib 空格间隔多项 VS20xx： 项目、属性、C/C++、附加包含目录：填写附加头文件所在目录 分号间隔多项 项目、属性、链接器、常规、附加库目录：填写附加依赖库所在目录 分号间隔多项 项目、属性、链接器、输入、附加依赖项：填写附加依赖库的名字.lib 空格或分号间隔多项 有搜过相关的解决方案了，他们的解决方法跟你的差不多，但都不能解决问题，还有其他可能的方案吗

引用 2 楼 mymtom 的回复:有没有包含头文件啊？ #include <openssl/des.h> 这个肯定有呀，用在IDE下看不到有错误的地方，只有在执行生成dll的时候，出现了错误

有没有包含头文件啊？ #include <openssl/des.h>


Question: 有将basic语言称作B语言的讲法？

那种讲法，那个人该拉出去打屁股了

见http://en.wikipedia.org/wiki/C_%28programming_language%29中history一节。

編輯： C#=B#1 JAVA=B#2

B=B C=B+ C++=B++ C#=B# JAVA=BJ


Question: 二叉平衡排序树主函数该怎样写？

void _tmain() { 	BiTNode b1;     BiTNode* pb1 = &b1; 	InsertBST(&pb1, 1);  	BiTNode b2;     BiTNode* pb2 = &b2; 	InsertBST(&pb2, 2);                printf("Hello world!\n");     return; }


Question: 窗口程序   edit

我把边框改粗，还是看不出来，说明边框要么是背景色，要么是填充色

根本看不清边框的颜色，既有背景色又有填充色

看书慢慢看,  看明白了多练习   和 速度快了没关系

else         {             cur_x++;         }         hdc=GetDC(hwnd);         SelectObject(hdc,CreateFont(0,0,0,0,0,0,0,0,0,0,0,0,/*12个0*/             FIXED_PITCH,NULL));         TextOut(hdc,r.left+cur_x*word_width,r.top+cur_y*word_height,             &p[cur_x+cur_y*20],1);         ReleaseDC(hwnd,hdc);

windows程序设计你看了多久看完的啊？

唉，兄弟，从前几天开始学习api函数以来老是出现这种逻辑错误，我也不知道该如何是好

SelectObject(hdc,GetStockObject(NULL_BRUSH));//设置背景空 			SetROP2(hdc,R2_NOT);//设置绘图方式：与背景色相反（忽略背景，因为背景为空） 			SelectObject(hdc,CreatePen(PS_DOT,2,RGB(0,0,255))); 			Rectangle(hdc,start.x,start.y,end.x,end.y); 麻烦再帮我看看，这里我想用蓝色画笔，但是画出的矩形边框是黑的，是因为setrop2的关系吗？ 我订的书还没到，我知道这个书上肯定有吧

兄弟，能不能仔细看一下你的逻辑？你的x都++了，移到没有值的数据后才textout，肯定输出错误


Question: storyboard下 UICollectionView and UIPageControl组合使用

是C的超类，应该算吧，我在分类里面没看到objective-c，就进来了

这东西是c语言范围吗?


Question: *(int *)a等于*((int *)a)吗？

完全可以自己敲代码解决的问题

如果你自己用编译器试一试或者找谷哥+度娘 解决问题前后不超过 2分钟 甚至更快。  如果你到论坛从发帖直到找到满意的帖子解决问题前后至少要10分钟 甚至更长。

根据运算符的优先级和结合性判断应该可以

引用 楼主 screen12 的回复:*(int *)a等于*((int *)a)吗？也就是说，后一个表达式中外面的括号可以去掉，是吗？ 可以。


Question: 文件读写失败

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

if (Source == NULL)           ;  //这个分号说明了，if 指针为空，那么让电脑啥 都不干，然后执行下面的句子  //这种错误很常见，而且很难找

引用 4 楼 yangyangsnr 的回复: if (Source == NULL);  {      printf("Source File is not exist!");      return 0;  }  因为你if后面有个分号... 所以下面大括号里的语句就不是if控制的了。 真相帝。

引用 4 楼 yangyangsnr 的回复: if (Source == NULL);  {      printf("Source File is not exist!");      return 0;  }  因为你if后面有个分号... 所以下面大括号里的语句就不是if控制的了。  我想给你结贴加分。但是你加分的那个文本框看不到。

引用 2 楼 piaobotudou 的回复:使用绝对路径 例如e:\\source.txt  绝对路径也获取指针失败。

使用绝对路径 例如e:\\source.txt


Question: 来个明白人给解释一下对齐(pragma pack)吧

我都拿颜色标记出来了...难道不明显吗

是的  引用 16 楼 sdu_hanson 的回复:[quote=引用 15 楼 Cnwanglin 的回复:] 1000 0000 1000 0000 1000 0000 0100 0000 tempBuf[0] =1000 0000; tempBuf[1] =1000 0000; tempBuf[2] =1000 0000; tempBuf[3] =0100 0000;  从上到下开始数 struct { unsigned	Info:10;       unsigned	Func:8;       unsigned	SA:4;	 unsigned	DA:4;	 unsigned	RES:2;	    unsigned	p:1;                      }ID;  info 10位 1000 0000 10  输出的时候颠倒位置 01 0000 0001 = 257 func 8 位  0000 0010 输出0100 0000 = 64 依次类推 恩，比如1，在内存中存储顺序是 1 0 0 0 0 0 0 0 而不是 0 0 0 0 0 0 0 1  是这样吗？[/quote]

引用 15 楼 Cnwanglin 的回复:1000 0000 1000 0000 1000 0000 0100 0000 tempBuf[0] =1000 0000; tempBuf[1] =1000 0000; tempBuf[2] =1000 0000; tempBuf[3] =0100 0000;  从上到下开始数 struct { unsigned	Info:10;       unsigned	Func:8;       unsigned	SA:4;	 unsigned	DA:4;	 unsigned	RES:2;	    unsigned	p:1;                      }ID;  info 10位 1000 0000 10  输出的时候颠倒位置 01 0000 0001 = 257 func 8 位  0000 0010 输出0100 0000 = 64 依次类推 恩，比如1，在内存中存储顺序是 1 0 0 0 0 0 0 0 而不是 0 0 0 0 0 0 0 1  是这样吗？

引用 9 楼 nice_cxf 的回复:按一字节对齐，跟字节对齐无关 Info：10,对应tempBuf[0]的8字节的01和tempBuf[1]的01字节01，二进制为0100000001：257 Func:8，对应tempBuf[1]的高6字节0和tempBuf[2]的低两个字节01，二进制为0100000，10进制为64 SA:4，对应tempBuf[2]的2-5字节，二进制为0000	 DA:4，	对应tempBuf[2]的67字节和tempBuf[3]的第01字节，为1000，结果为4 RES:2，	对应tempBuf[3]第23字节，为00    p:1; 对应tempBuf[3]第4字节，为00 你好  1 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0  你的意思是info是10个二进制位，都是从下往上取是吧？

引用 9 楼 nice_cxf 的回复:按一字节对齐，跟字节对齐无关 Info：10,对应tempBuf[0]的8字节的01和tempBuf[1]的01字节01，二进制为0100000001：257 Func:8，对应tempBuf[1]的高6字节0和tempBuf[2]的低两个字节01，二进制为0100000，10进制为64 SA:4，对应tempBuf[2]的2-5字节，二进制为0000	 DA:4，	对应tempBuf[2]的67字节和tempBuf[3]的第01字节，为1000，结果为4 RES:2，	对应tempBuf[3]第23字节，为00    p:1; 对应tempBuf[3]第4字节，为00 你好，还是不大明白 Info：10,对应tempBuf[0]的8字节的01和tempBuf[1]的01字节01，二进制为0100000001：257 为什么会是对应tempbuf【1】的01两位呢？ 00000001000000010000000100000010 我感觉应该是前十个二进制位0000000100才对啊？

c++ primer plus中有详细解释：位域的问题

差不多搞明白了，谢谢大家

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

引用 2 楼 Cnwanglin 的回复:在C语言中，结构是一种复合数据类型，其构成元素既可以是基本数据类型（如int、long、float等）的变量，也可以是一些复合数据类型（如数组、结构、联合等）的数据单元。在结构中，编译器为结构的每个成员按其自然对界（alignment）条件分配空间。(所谓自然对界条件是指有些CPU要求数据存放的时候要对齐，就是起始地址必须是所占字节数的整数倍。RISC   CPU就有这种要求。如果在PowerPC的系统上用这样一个结构：    struct s {  Char a;  long b;  };     在内存里就会看到：（字母表示这个字节属于谁） a   0   0   0    b   b   b   b    由于b需要对齐，所以a和b之间就有了一个3字节的pad。要是取sizeof(struct   s)，就会看到是8。这种对齐在RISC   CPU上是必须的，否则会出错.     在x86上面则没有这种必须对齐的要求，a和b之间可以不需要pad。但是你并不能确定他们之间到底有没有这个pad，这个和编译器有关系。因为数据对齐的时候访问效率最高，所以有的编译器进行了优化，就是在x86上数据照样也是对齐的。比如gcc，用gcc得到的sizeof(struct   s)就是8，但是如果用Turbo   C，就会看到是5。 “自然对界条件”对齐条件，不是说变量的起始地址必须是其所占字节数的整数倍   ！    注意这里的起始地址   是相对地址   ！   从   0   开始计算的   ～) 各个成员按照它们被声明的顺序在内存中顺序存储，第一个成员的地址和整个结构的地址相同。 例如，下面的结构各成员空间分配情况： struct test  {      char x1;      short x2;      float x3;      char x4; }; 结构的第一个成员x1，其偏移地址为0，占据了第1个字节。第二个成员x2为short类型，其起始地址必须2字节对界，因此，编译器在x2和x1之间填充了一个空字节。结构的第三个成员x3和第四个成员x4恰好落在其自然对界地址上，在它们前面不需要额外的填充字节。在test结构中，成员x3要求4字节对界，是该结构所有成员中要求的最大对界单元，因而test结构的自然对界条件为4字节，编译器在成员x4后面填充了3个空字节。整个结构所占据空间为12字节。+1

笔误，DA:4，结果1000，值为8 p:1; 对应tempBuf[3]第4字节，为0

引用 7 楼 aqtata 的回复:struct  {  unsigned Info:10;        unsigned Func:8;        unsigned SA:4;   unsigned DA:4;   unsigned RES:2;     unsigned p:1;                       }ID;  29位也能编译通过吗？  能啊

引用 5 楼 zhao4zhong1 的回复:位域 谢谢，我去看看~~~~~

位域

引用 2 楼 Cnwanglin 的回复:在C语言中，结构是一种复合数据类型，其构成元素既可以是基本数据类型（如int、long、float等）的变量，也可以是一些复合数据类型（如数组、结构、联合等）的数据单元。在结构中，编译器为结构的每个成员按其自然对界（alignment）条件分配空间。(所谓自然对界条件是指有些CPU要求数据存放的时候要对齐，就是起始地址必须是所占字节数的整数倍。RISC   CPU就有这种要求。如果在PowerPC的系统上用这样一个结构：    struct s {  Char a;  long b;  };     在内存里就会看到：（字母表示这个字节属于谁） a   0   0   0    b   b   b   b    由于b需要对齐，所以a和b之间就有了一个3字节的pad。要是取sizeof(struct   s)，就会看到是8。这种对齐在RISC   CPU上是必须的，否则会出错.     在x86上面则没有这种必须对齐的要求，a和b之间可以不需要pad。但是你并不能确定他们之间到底有没有这个pad，这个和编译器有关系。因为数据对齐的时候访问效率最高，所以有的编译器进行了优化，就是在x86上数据照样也是对齐的。比如gcc，用gcc得到的sizeof(struct   s)就是8，但是如果用Turbo   C，就会看到是5。 “自然对界条件”对齐条件，不是说变量的起始地址必须是其所占字节数的整数倍   ！    注意这里的起始地址   是相对地址   ！   从   0   开始计算的   ～) 各个成员按照它们被声明的顺序在内存中顺序存储，第一个成员的地址和整个结构的地址相同。 例如，下面的结构各成员空间分配情况： struct test  {      char x1;      short x2;      float x3;      char x4; }; 结构的第一个成员x1，其偏移地址为0，占据了第1个字节。第二个成员x2为short类型，其起始地址必须2字节对界，因此，编译器在x2和x1之间填充了一个空字节。结构的第三个成员x3和第四个成员x4恰好落在其自然对界地址上，在它们前面不需要额外的填充字节。在test结构中，成员x3要求4字节对界，是该结构所有成员中要求的最大对界单元，因而test结构的自然对界条件为4字节，编译器在成员x4后面填充了3个空字节。整个结构所占据空间为12字节。 你这不说的废话么，人家明明写了按1字节对齐

引用 2 楼 Cnwanglin 的回复:在C语言中，结构是一种复合数据类型，其构成元素既可以是基本数据类型（如int、long、float等）的变量，也可以是一些复合数据类型（如数组、结构、联合等）的数据单元。在结构中，编译器为结构的每个成员按其自然对界（alignment）条件分配空间。(所谓自然对界条件是指有些CPU要求数据存放的时候要对齐，就是起始地址必须是所占字节数的整数倍。RISC   CPU就有这种要求。如果在PowerPC的系统上用这样一个结构：    struct s {  Char a;  long b;  };     在内存里就会看到：（字母表示这个字节属于谁） a   0   0   0    b   b   b   b    由于b需要对齐，所以a和b之间就有了一个3字节的pad。要是取sizeof(struct   s)，就会看到是8。这种对齐在RISC   CPU上是必须的，否则会出错.     在x86上面则没有这种必须对齐的要求，a和b之间可以不需要pad。但是你并不能确定他们之间到底有没有这个pad，这个和编译器有关系。因为数据对齐的时候访问效率最高，所以有的编译器进行了优化，就是在x86上数据照样也是对齐的。比如gcc，用gcc得到的sizeof(struct   s)就是8，但是如果用Turbo   C，就会看到是5。 “自然对界条件”对齐条件，不是说变量的起始地址必须是其所占字节数的整数倍   ！    注意这里的起始地址   是相对地址   ！   从   0   开始计算的   ～) 各个成员按照它们被声明的顺序在内存中顺序存储，第一个成员的地址和整个结构的地址相同。 例如，下面的结构各成员空间分配情况： struct test  {      char x1;      short x2;      float x3;      char x4; }; 结构的第一个成员x1，其偏移地址为0，占据了第1个字节。第二个成员x2为short类型，其起始地址必须2字节对界，因此，编译器在x2和x1之间填充了一个空字节。结构的第三个成员x3和第四个成员x4恰好落在其自然对界地址上，在它们前面不需要额外的填充字节。在test结构中，成员x3要求4字节对界，是该结构所有成员中要求的最大对界单元，因而test结构的自然对界条件为4字节，编译器在成员x4后面填充了3个空字节。整个结构所占据空间为12字节。 这个我能看懂，但是套不上啊

位域。 仅供参考#include <stdio.h> #include <stdlib.h> char buf[17]; union U {   unsigned short int aa;   struct S {     unsigned int bb:7;//(bit 0-6)     unsigned int cc:6;//(bit 7-12)     unsigned int dd:3;//(bit 13-15)   } s; } u; void main() {                 //bbbbbbbbbbbbbbbb                 //iiiiiiiiiiiiiiii                 //tttttttttttttttt                 //111111                 //5432109876543210                 //::::::::::::::::     u.aa=0xE07F;//1110000001111111     printf("bb==%d,cc==%d,dd==%d\n",u.s.bb,u.s.cc,u.s.dd);     u.s.bb=0x41;     u.s.cc=0x21;//dddccccccbbbbbbb     u.s.dd=5;   //1011000011000001     printf("aa==0x%04X==%016s(2)\n",u.aa,itoa(u.aa,buf,2)); } //bb==127,cc==0,dd==7 //aa==0xB0C1==1011000011000001(2)


Question: 问个C语言的基础知识

d=f=20/3;的处理顺序是这样的。 先按照int处理20/3,得到整数6，然后6被赋值给浮点数d，f，得到6.0 如果想得到6.7的话， 可以考虑20.0/3

我还想问一下， double d;float f; d=f=20/3; printf("%f%f\n",d,f); 为什么输出是6.0 6.0，不是6.7 6.7   ？

引用 7 楼 zhao4zhong1 的回复://C++ Operators //  Operators specify an evaluation to be performed on one of the following: //    One operand (unary operator) //    Two operands (binary operator) //    Three operands (ternary operator) //  The C++ language includes all C operators and adds several new operators. //  Table 1.1 lists the operators available in Microsoft C++. //  Operators follow a strict precedence which defines the evaluation order of //expressions containing these operators.  Operators associate with either the //expression on their left or the expression on their right;    this is called //“associativity.” Operators in the same group have equal precedence and are //evaluated left to right in an expression unless explicitly forced by a pair of //parentheses, ( ). //  Table 1.1 shows the precedence and associativity of C++ operators //  (from highest to lowest precedence). // //Table 1.1   C++ Operator Precedence and Associativity // The highest precedence level is at the top of the table. //+------------------+-----------------------------------------+---------------+ //| Operator         | Name or Meaning                         | Associativity | //+------------------+-----------------------------------------+---------------+ //| ::               | Scope resolution                        | None          | //| ::               | Global                                  | None          | //| [ ]              | Array subscript                         | Left to right | //| ( )              | Function call                           | Left to right | //| ( )              | Conversion                              | None          | //| .                | Member selection (object)               | Left to right | //| ->               | Member selection (pointer)              | Left to right | //| ++               | Postfix increment                       | None          | //| --               | Postfix decrement                       | None          | //| new              | Allocate object                         | None          | //| delete           | Deallocate object                       | None          | //| delete[ ]        | Deallocate object                       | None          | //| ++               | Prefix increment                        | None          | //| --               | Prefix decrement                        | None          | //| *                | Dereference                             | None          | //| &                | Address-of                              | None          | //| +                | Unary plus                              | None          | //| -                | Arithmetic negation (unary)             | None          | //| !                | Logical NOT                             | None          | //| ~                | Bitwise complement                      | None          | //| sizeof           | Size of object                          | None          | //| sizeof ( )       | Size of type                            | None          | //| typeid( )        | type name                               | None          | //| (type)           | Type cast (conversion)                  | Right to left | //| const_cast       | Type cast (conversion)                  | None          | //| dynamic_cast     | Type cast (conversion)                  | None          | //| reinterpret_cast | Type cast (conversion)                  | None          | //| static_cast      | Type cast (conversion)                  | None          | //| .*               | Apply pointer to class member (objects) | Left to right | //| ->*              | Dereference pointer to class member     | Left to right | //| *                | Multiplication                          | Left to right | //| /                | Division                                | Left to right | //| %                | Remainder (modulus)                     | Left to right | //| +                | Addition                                | Left to right | //| -                | Subtraction                             | Left to right | //| <<               | Left shift                              | Left to right | //| >>               | Right shift                             | Left to right | //| <                | Less than                               | Left to right | //| >                | Greater than                            | Left to right | //| <=               | Less than or equal to                   | Left to right | //| >=               | Greater than or equal to                | Left to right | //| ==               | Equality                                | Left to right | //| !=               | Inequality                              | Left to right | //| &                | Bitwise AND                             | Left to right | //| ^                | Bitwise exclusive OR                    | Left to right | //| |                | Bitwise OR                              | Left to right | //| &&               | Logical AND                             | Left to right | //| ||               | Logical OR                              | Left to right | //| e1?e2:e3         | Conditional                             | Right to left | //| =                | Assignment                              | Right to left | //| *=               | Multiplication assignment               | Right to left | //| /=               | Division assignment                     | Right to left | //| %=               | Modulus assignment                      | Right to left | //| +=               | Addition assignment                     | Right to left | //| -=               | Subtraction assignment                  | Right to left | //| <<=              | Left-shift assignment                   | Right to left | //| >>=              | Right-shift assignment                  | Right to left | //| &=               | Bitwise AND assignment                  | Right to left | //| |=               | Bitwise inclusive OR assignment         | Right to left | //| ^=               | Bitwise exclusive OR assignment         | Right to left | //| ,                | Comma                                   | Left to right | //+------------------+-----------------------------------------+---------------+ 这什么东西？

printf("%d,%d,%d\n",(x,y),z+2); 首先这个表达式应该写成printf("%d,%d\n",(x,y),z+2); 其次(x,y)是逗号表达式，只会显示后面的结果（即y） 所以结果应该是 3,3

x 是int 所以x=1.2 -->x=1 y = (1 + 3.8)/5.0 -->y = 4/5 = 0 试试把x，y改为float或者double，看看结果是否不一样了

#include "stdio.h" main() { double d=3.2;int x,y; x=1.2;y=(x+3.8)/5.0; printf("%d\n",d*y); } 请问为什么输出是0啊？

%2d\n, a  2 表示输出的位数 d 表示按照十进制输出  \n 表示换行  a 表示变量名称

那（“%2d\n”，a）什么意思?

请查看逗号运算符


Question: 求助，读redis源码遇到问题，求大牛帮忙看看，谢谢

s 是指针的地址, 地址有增加,减少的方向  减去这个结构体的大小,正好是获得这个结构体指针的首地址


Question: C语言关于文件分割、修改、保存的，有大神来处理一下

仅供参考//NAME: essaie bla bla //DIMENSION: 8 //DATA //1  14  15 //2  11  10 //3  6   4 //4  7   13 //5  9   21 //6  19  3 //7  1   5 //8  8   8 //EOF // // 文本文件中可能还含有其他内容，但是需要用到的内容即以上  //比如data.txt: //NAME: essaie bla bla //其它内容 //DIMENSION: 8 //其它内容 //DATA //其它内容 //1  14  15 //其它内容 //2  11  10 //其它内容 //3  6   4 //其它内容 //4  7   13 //其它内容 //5  9   21 //其它内容 //6  19  3 //其它内容 //7  1   5 //其它内容 //8  8   8 //其它内容 //EOF  // 目标是要获取NAME后字串，DIMENSION后数值，以及DATA以下的数值 // 其中NAME就是随便个字句，DIMENSION是城市数量，DATA以下是城市编号，X坐标，Y坐标 // 所有的这些将赋值给一个事先定义好的结构 #include <stdio.h> #include <string.h> #define MAXCPL   80   //每行最大字符数 #define MAXCITY  100  //每组数据中DATA最多项数，DIMENSION的最大值 #define MAXNAMEL 32   //NAME最大长度 struct S {     char NAME[MAXNAMEL+1];     int  DIMENSION;     struct D {         int NO;         int X;         int Y;     } DATA[MAXCITY]; } s; FILE *f; int st,n,i; char ln[MAXCPL]; int main() {     f=fopen("data.txt","r");     if (NULL==f) {         printf("Can not open file data.txt!\n");         return 1;     }     st=0;     n=0;     while (1) {         if (NULL==fgets(ln,MAXCPL,f)) break;         if (st==0) {             if (1==sscanf(ln,"NAME: %32[^\n]",s.NAME)) st=1;         } else if (st==1) {             if (1==sscanf(ln,"DIMENSION: %d",&s.DIMENSION)) st=2;         } else if (st==2) {             if (0==strcmp(ln,"DATA\n")) st=3;         } else if (st==3) {             if (3==sscanf(ln,"%d%d%d",&s.DATA[n].NO,&s.DATA[n].X,&s.DATA[n].Y)) {                 n++;                 if (n>=MAXCITY || n>=s.DIMENSION) break;             }         }     }     fclose(f);     printf("s.NAME=[%s]\n",s.NAME);     printf("s.DIMENSION=%d\n",s.DIMENSION);     for (i=0;i<n;i++) {         printf("s.DATA[%d].NO,X,Y=%d,%d,%d\n",i,s.DATA[i].NO,s.DATA[i].X,s.DATA[i].Y);     }     return 0; } //s.NAME=[essaie bla bla] //s.DIMENSION=8 //s.DATA[0].NO,X,Y=1,14,15 //s.DATA[1].NO,X,Y=2,11,10 //s.DATA[2].NO,X,Y=3,6,4 //s.DATA[3].NO,X,Y=4,7,13 //s.DATA[4].NO,X,Y=5,9,21 //s.DATA[5].NO,X,Y=6,19,3 //s.DATA[6].NO,X,Y=7,1,5 //s.DATA[7].NO,X,Y=8,8,8

我看了  好像不是太一样，可能是我没说明白  这样的 问题是MATLAB只能跟C混编    没看懂 ？如下：  这部分数据  NODE   VOLTAGE     NODE   VOLTAGE     NODE   VOLTAGE     NODE   VOLTAGE  (N00117)     .0971 (N00127)    3.4979 (N00140)     .0971 (N00149)    3.4979       (N00167)     .0900 ($G_DGND)    0.0000                   ($G_DPWR)    5.0000     还有这部分（我发的帖子里可能没有，但是实际是有的，可以不管）  DGTL NODE : STATE  DGTL NODE : STATE  DGTL NODE : STATE  DGTL NODE : STATE  (N00149$DtoA) : 1  (N00127$DtoA) : 1  (N00149$AtoD) : 1  (   $D_HI) : 1           (N00127$AtoD) : 1  (N00167$DtoA) : 0  (N00117$DtoA) : 0  (   $D_LO) : 0           (N00140$DtoA) : 0  (N00117$AtoD) : 0  (N00140$AtoD) : 0   从原文件之中分出来，并生成一个文件1.txt，其中内容是这样的 1     .0971   2    3.4979   3     .0971       4    3.4979   5     .0900     就是第一部分数据 变成的这样，只是把N00117这些编号换成了12345


Question: 算法~~

引用 2 楼 xmh1954 的回复:这个字体好洋气，看得人眼花缭乱~ 赵老师果断换版本了~ 没换。

这个字体好洋气，看得人眼花缭乱~ 赵老师果断换版本了~

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

谢谢老师~~~


Question: WinpCap接收数据出问题

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

问题描述的不清晰  wireshark 能都抓到,表示包确实都发出来了  上位机为什么会丢包,用的什么协议?


Question: C语言的贪吃蛇，别人的程序，有个bug，

/*俄罗斯方块（C代码）*/ /*    —— 晓帝*/   #include <stdio.h> #include <dos.h> #include <conio.h> #include <graphics.h> #include <stdlib.h>  #ifdef __cplusplus  #define __CPPARGS ... #else #define __CPPARGS #endif #define MINBOXSIZE 15 /* 最小方块的尺寸 */ #define BGCOLOR 7 /* 背景着色 */ #define GX 200 #define GY 10 #define SJNUM 10000 /* 每当玩家打到一万分等级加一级*/  /* 按键码*/ #define VK_LEFT 0x4b00 #define VK_RIGHT 0x4d00 #define VK_DOWN 0x5000 #define VK_UP 0x4800 #define VK_HOME 0x4700 #define VK_END 0x4f00 #define VK_SPACE 0x3920 #define VK_ESC 0x011b #define VK_ENTER 0x1c0d  /* 定义俄罗斯方块的方向（我定义他为4种）*/ #define F_DONG 0 #define F_NAN 1 #define F_XI 2 #define F_BEI 3  #define NEXTCOL 20 /* 要出的下一个方块的纵坐标*/ #define NEXTROW 12 /* 要出的下一个方块的横从标*/ #define MAXROW 14 /* 游戏屏幕大小*/ #define MAXCOL 20 #define SCCOL 100 /*游戏屏幕大显示器上的相对位置*/ #define SCROW 60   int gril[22][16]; /* 游戏屏幕坐标*/ int col=1,row=7; /* 当前方块的横纵坐标*/ int boxfx=0,boxgs=0; /* 当前寺块的形壮和方向*/ int nextboxfx=0,nextboxgs=0,maxcol=22;/*下一个方块的形壮和方向*/ int minboxcolor=6,nextminboxcolor=6; int num=0; /*游戏分*/ int dj=0,gamedj[10]={18,16,14,12,10,8,6,4,2,1};/* 游戏等级*/ /* 以下我用了一个3维数组来纪录方块的最初形状和方向*/ int boxstr[7][4][16]={{ {1,1,0,0,0,1,1,0,0,0,0,0,0,0,0,0}, {0,1,0,0,1,1,0,0,1,0,0,0,0,0,0,0}, {1,1,0,0,0,1,1,0,0,0,0,0,0,0,0,0}, {0,1,0,0,1,1,0,0,1,0,0,0,0,0,0,0}}, { {0,1,1,0,1,1,0,0,0,0,0,0,0,0,0,0}, {1,0,0,0,1,1,0,0,0,1,0,0,0,0,0,0}, {0,1,1,0,1,1,0,0,0,0,0,0,0,0,0,0}, {1,0,0,0,1,1,0,0,0,1,0,0,0,0,0,0}}, { {1,1,0,0,0,1,0,0,0,1,0,0,0,0,0,0}, {1,1,1,0,1,0,0,0,0,0,0,0,0,0,0,0}, {1,0,0,0,1,0,0,0,1,1,0,0,0,0,0,0}, {0,0,1,0,1,1,1,0,0,0,0,0,0,0,0,0}}, { {1,1,0,0,1,0,0,0,1,0,0,0,0,0,0,0}, {1,0,0,0,1,1,1,0,0,0,0,0,0,0,0,0}, {0,1,0,0,0,1,0,0,1,1,0,0,0,0,0,0}, {1,1,1,0,0,0,1,0,0,0,0,0,0,0,0,0}}, { {0,1,0,0,0,1,0,0,0,1,0,0,0,1,0,0}, {0,0,0,0,1,1,1,1,0,0,0,0,0,0,0,0}, {0,1,0,0,0,1,0,0,0,1,0,0,0,1,0,0}, {0,0,0,0,1,1,1,1,0,0,0,0,0,0,0,0}}, { {1,1,0,0,1,1,0,0,0,0,0,0.0,0,0,0}, {1,1,0,0,1,1,0,0,0,0,0,0.0,0,0,0}, {1,1,0,0,1,1,0,0,0,0,0,0.0,0,0,0}, {1,1,0,0,1,1,0,0,0,0,0,0.0,0,0,0}}, { {0,0,0,0,1,1,1,0,0,1,0,0,0,0,0,0}, {1,0,0,0,1,1,0,0,1,0,0,0,0,0,0,0}, {0,1,0,0,1,1,1,0,0,0,0,0.0,0,0,0}, {0,1,0,0,1,1,0,0,0,1,0,0,0,0,0,0}}  };  /* 随机得到当前方块和下一个方块的形状和方向*/ void boxrad(){ minboxcolor=nextminboxcolor; boxgs=nextboxgs; boxfx=nextboxfx; nextminboxcolor=random(14)+1; if(nextminboxcolor==4||nextminboxcolor==7||nextminboxcolor==8) nextminboxcolor=9; nextboxfx=F_DONG; nextboxgs=random(7); } /*初始化图形模试*/ void init(int gdrive,int gmode){ int errorcode; initgraph(&gdrive,&gmode,"D:\\tc\\"); errorcode=graphresult(); if(errorcode!=grOk){ printf("error of: %s",grapherrormsg(errorcode)); exit(1); } }  /* 在图形模式下的清屏 */ void cls() { setfillstyle(SOLID_FILL,0); setcolor(0); bar(0,0,640,480); } /*在图形模式下的高级清屏*/ void clscr(int a,int b,int c,int d,int color){ setfillstyle(SOLID_FILL,color); setcolor(color); bar(a,b,c,d); } /*最小方块的绘制*/ void minbox(int asc,int bsc,int color,int bdcolor){ int a=0,b=0; a=SCCOL+asc; b=SCROW+bsc; clscr(a+1,b+1,a-1+MINBOXSIZE,b-1+MINBOXSIZE,color); if(color!=BGCOLOR){ setcolor(bdcolor); line(a+1,b+1,a-1+MINBOXSIZE,b+1); line(a+1,b+1,a+1,b-1+MINBOXSIZE); line(a-1+MINBOXSIZE,b+1,a-1+MINBOXSIZE,b-1+MINBOXSIZE); line(a+1,b-1+MINBOXSIZE,a-1+MINBOXSIZE,b-1+MINBOXSIZE); } }  /*游戏中出现的文字*/ void txt(int a,int b,char *txt,int font,int color){ setcolor(color); settextstyle(0,0,font); outtextxy(a,b,txt); } /*windows 绘制*/ void win(int a,int b,int c,int d,int bgcolor,int bordercolor){ clscr(a,b,c,d,bgcolor); setcolor(bordercolor); line(a,b,c,b); line(a,b,a,d); line(a,d,c,d); line(c,b,c,d);  }  /* 当前方块的绘制*/ void funbox(int a,int b,int color,int bdcolor){ int i,j; int boxz[4][4]; for(i=0;i<16;i++) boxz[i/4][i%4]=boxstr[boxgs][boxfx][i]; for(i=0;i<4;i++) for(j=0;j<4;j++) if(boxz[i][j]==1) minbox((j+row+a)*MINBOXSIZE,(i+col+b)*MINBOXSIZE,color,bdcolor); } /*下一个方块的绘制*/ void nextfunbox(int a,int b,int color,int bdcolor){ int i,j; int boxz[4][4]; for(i=0;i<16;i++) boxz[i/4][i%4]=boxstr[nextboxgs][nextboxfx][i]; for(i=0;i<4;i++) for(j=0;j<4;j++) if(boxz[i][j]==1) minbox((j+a)*MINBOXSIZE,(i+b)*MINBOXSIZE,color,bdcolor); } /*时间中断定义*/ #define TIMER 0x1c int TimerCounter=0; void interrupt ( *oldhandler)(__CPPARGS); void interrupt newhandler(__CPPARGS){ TimerCounter++; oldhandler(); } void SetTimer(void interrupt (*IntProc)(__CPPARGS)){ oldhandler=getvect(TIMER); disable(); setvect(TIMER,IntProc); enable(); } /*由于游戏的规则，消掉都有最小方块的一行*/ void delcol(int a){ int i,j; for(i=a;i>1;i--) for(j=1;j<15;j++){ minbox(j*MINBOXSIZE,i*MINBOXSIZE,BGCOLOR,BGCOLOR); gril[i][j]=gril[i-1][j]; if(gril[i][j]==1) minbox(j*MINBOXSIZE,i*MINBOXSIZE,minboxcolor,0); } }  /*消掉所有都有最小方块的行*/ void delete(){ int i,j,zero,delgx=0; char *nm="00000"; for(i=1;i<21;i++){ zero=0; for(j=1;j<15;j++) if(gril[i][j]==0) zero=1; if(zero==0){ delcol(i); delgx++; } } num=num+delgx*delgx*10; dj=num/10000;  sprintf(nm,"%d",num); clscr(456,173,500,200,4); txt(456,173,"Number:",1,15); txt(456,193,nm,1,15); } /*时间中断结束*/ void KillTimer(){ disable(); setvect(TIMER,oldhandler); enable(); } /* 测试当前方块是否可以向下落*/ int downok(){ int i,j,k=1,a[4][4]; for(i=0;i<16;i++) a[i/4][i%4]=boxstr[boxgs][boxfx][i]; for(i=0;i<4;i++) for(j=0;j<4;j++) if(a[i][j] && gril[col+i+1][row+j]) k=0; return(k); } /* 测试当前方块是否可以向左行*/ int leftok(){ int i,j,k=1,a[4][4]; for(i=0;i<16;i++) a[i/4][i%4]=boxstr[boxgs][boxfx][i]; for(i=0;i<4;i++) for(j=0;j<4;j++) if(a[i][j] && gril[col+i][row+j-1]) k=0; return(k); } /* 测试当前方块是否可以向右行*/ int rightok(){ int i,j,k=1,a[4][4]; for(i=0;i<16;i++) a[i/4][i%4]=boxstr[boxgs][boxfx][i]; for(i=0;i<4;i++) for(j=0;j<4;j++) if(a[i][j] && gril[col+i][row+j+1]) k=0; return(k); } /* 测试当前方块是否可以变形*/ int upok(){ int i,j,k=1,a[4][4]; for(i=0;i<4;i++) for(i=0;i<16;i++) a[i/4][i%4]=boxstr[boxgs][boxfx+1][i]; for(i=3;i>=0;i--) for(j=3;j>=0;j--) if(a[i][j] && gril[col+i][row+j]) k=0; return(k); } /*当前方块落下之后，给屏幕坐标作标记*/ void setgril(){ int i,j,a[4][4]; funbox(0,0,minboxcolor,0); for(i=0;i<16;i++) a[i/4][i%4]=boxstr[boxgs][boxfx][i]; for(i=0;i<4;i++) for(j=0;j<4;j++) if(a[i][j]) gril[col+i][row+j]=1; col=1;row=7; } /*游戏结束*/ void gameover(){ int i,j;  for(i=20;i>0;i--) for(j=1;j<15;j++) minbox(j*MINBOXSIZE,i*MINBOXSIZE,2,0); txt(103,203,"Game Over",3,10); } /*按键的设置*/ void call_key(int keyx){ switch(keyx){ case VK_DOWN: { /*下方向键，横坐标加一。*/ if(downok()){ col++; funbox(0,0,minboxcolor,0);} else{ funbox(0,0,minboxcolor,0); setgril(); nextfunbox(NEXTCOL,NEXTROW,4,4); boxrad(); nextfunbox(NEXTCOL,NEXTROW,nextminboxcolor,0); delete(); } break; } case VK_UP: { /*上方向键，方向形状旋转90度*/ if(upok()) boxfx++; if(boxfx>3) boxfx=0; funbox(0,0,minboxcolor,0); break; } case VK_LEFT:{ /*左方向键，纵坐标减一*/ if(leftok()) row--; funbox(0,0,minboxcolor,0); break; } case VK_RIGHT:{ /*右方向键，纵坐标加一*/ if(rightok()) row++; funbox(0,0,minboxcolor,0); break; } case VK_SPACE: /*空格键，直接落到最后可以落到的们置*/ while(downok()) col++; funbox(0,0,minboxcolor,0); setgril(); nextfunbox(NEXTCOL,NEXTROW,4,4); boxrad(); nextfunbox(NEXTCOL,NEXTROW,nextminboxcolor,0); delete(); break; default: { txt(423,53,"worng key!",1,4); txt(428,80,"Plese Enter Anly Key AG!",1,4); getch(); clscr(420,50,622,97,BGCOLOR); } } }  /*时间中断开始*/ void timezd(void){ int key; SetTimer(newhandler); boxrad(); nextfunbox(NEXTCOL,NEXTROW,nextminboxcolor,0); for(;;){ if(bioskey(1)){ key=bioskey(0); funbox(0,0,BGCOLOR,BGCOLOR); if(key==VK_ESC) break; call_key(key); } if(TimerCounter>gamedj[dj]){ TimerCounter=0; if(downok()){ funbox(0,0,BGCOLOR,BGCOLOR); col++; funbox(0,0,minboxcolor,0); } else { if(col==1){ gameover(); getch(); break; } setgril(); delete(); funbox(0,0,minboxcolor,0); col=1;row=7; funbox(0,0,BGCOLOR,BGCOLOR); nextfunbox(NEXTCOL,NEXTROW,4,4); boxrad(); nextfunbox(NEXTCOL,NEXTROW,nextminboxcolor,0); } } } }  /*主程序开始*/ void main(void){ int i,j; char *nm="00000"; init(VGA,VGAHI); cls(); /*屏幕坐标初始化*/ for(i=0;i<=MAXCOL+1;i++) for(j=0;j<=MAXROW+1;j++) gril[i][j]=0; for(i=0;i<=MAXCOL+1;i++) { gril[i][0]=1; gril[i][15]=1; } for(j=1;j<=MAXROW;j++){ gril[0][j]=1; gril[21][j]=1; } clscr(0,0,640,480,15); win(1,1,639,479,4,15); win(SCCOL+MINBOXSIZE-2,SCROW+MINBOXSIZE-2,SCCOL+15*MINBOXSIZE+2,SCROW+21*MINBOXSIZE+2,BGCOLOR,0); nextboxgs=random(8); nextboxfx=random(4); sprintf(nm,"%d",num); txt(456,173,"Number:",1,15); txt(456,193,nm,1,15); txt(456,243,"Next Box:",1,15); timezd(); KillTimer(); closegraph(); }

这个画面也太差劲了

自己重新编一个

引用 楼主 sinat_17506531 的回复:就是刚开始运行的时候，蛇头部分清除不了，想了好久，能力有限，希望大家帮我分析一下 [/code] 原因是：第一个蛇头增加1的时候没有备份。 改后的代码如下：  #include<stdio.h> #include<windows.h> #include<stdlib.h> #include<time.h> #include"conio.h" struct Snake { 	int x; 	int y; }snake[150];  struct Smile { 	int x; 	int y; }smile[3];  struct Cross { 	int x; 	int y; }cross[5]; void screen() { 	int i,j; 	HANDLE hout; 	COORD coord; 	for(i=57;i<=58;i++) 	{ 		for(j=0;j<=24;j++) 		{ 			coord.X=i; 			coord.Y=j; 			hout=GetStdHandle(STD_OUTPUT_HANDLE); 			SetConsoleCursorPosition(hout,coord); 			printf("#"); 		} 	} 	for(j=23;j<=24;j++) 	{ 		for(i=0;i<=56;i++) 		{ 			coord.X=i; 			coord.Y=j; 			hout=GetStdHandle(STD_OUTPUT_HANDLE); 			SetConsoleCursorPosition(hout,coord); 			printf("#"); 		} 	} } static int length=3; static int direction=2; static int temp; void rubber() { 	HANDLE hout; 	COORD coord; 	coord.X=snake[length].x; 	coord.Y=snake[length].y; 	hout=GetStdHandle(STD_OUTPUT_HANDLE); 	SetConsoleCursorPosition(hout,coord); 	printf(" "); }  void clescr() { 	system("cls"); }  void ifcollide() { 	int i; 	for(i=3;i<=length;i++) 	{ 		if((snake[0].x==snake[i].x)&&(snake[0].y==snake[i].y)) exit(0); 	} }  void over() { 	if(((snake[0].x>=57)||(snake[0].x<0))||((snake[0].y>=23)||(snake[0].y<0))) 		exit(0); }  void moveon() { 	int i; 	for(i=length;i>0;i--) 	{ 		snake[i].x=snake[i-1].x; 		snake[i].y=snake[i-1].y; 	} }  void keybd() { 	Sleep(temp-300);//这个函数也来自于windows.h头文件，作用是程序暂停一段时间，这里的作用很明显，那就是一个简单的计时功能，如果没有它，整个蛇就会处在不断前进前进前进的疯癫状 	if(kbhit())//一开始有提到过的判断键盘是否输入的函数，即如果有输入，执行： 	{ 		switch (getch())//getch（）就是键盘信息，72,80,75,77分别对应上下左右方向键，在百度搜索keybdevent()，有详细的各种键盘值对应，当然这里只需要这四个 		{ 		case 72: 			direction=1; 			break;//direction 就是一开始开辟的静态变量，纪录方向 		case 80: 			direction=2; 			break; 		case 75: 			direction=3; 			break; 		case 77: 			direction=4; 			break; 		default: 			break; 		} 	} 	switch(direction)//根据方向判定，如果有键盘输入，在上面的时候已经改变过一次direction的值，如果没有，direction就衍用上次的值，这也是好处之一 	{ 	case 1: 		snake[0].y-=1;break;//snake〔0〕就是蛇头坐标结构体 	case 2: 		snake[0].y+=1;break; 	case 3: 		snake[0].x-=1;break; 	case 4: 		snake[0].x+=1;break; 	default: 		exit(0); 	} }  void ifcolobs() {     int i;     for(i=0;i<=4;i++) 	{ 		if((snake[0].x==cross[i].x)&&(snake[0].y==cross[i].y)) //判断是不是有撞倒障碍 		{ 			printf("Fail!"); 			getch(); 			exit(0); 		} 	} } int main(void) { 	char ch; 	int j=0,k; 	printf("碰到%c蛇会死亡,吃到%c蛇的长度增加一节!注意了,有时候%c会被%c所替代!\n尽管如此,你还是不能吃掉它,所以如果你运气太差,会因此而死亡\n",29,2,29,2); 	printf("请输入游戏难度:\n"); 	printf("A.easy\n"); 	printf("B.medium\n"); 	printf("C.difficult\n"); 	printf("D.death challenge\n"); 	scanf("%c",&ch); 	switch(ch) 	{ 	case'A': 	case'a':     		temp=800; 		break; 	case'B': 	case'b':     		temp=700; 		break; 	case'C': 	case'c':     		temp=500; 		break; 	case'D': 	case'd':     		temp=400; 		break; 	default: 		printf("you are kidding..."); 		exit(0); 	} 	printf("游戏初始化中...");//到此为止，主函数第一步完成，一个简单的选择界面就出来了。。 	for(k=0;k<3;k++) 	{ 		snake[k].x=j; 		snake[k].y=2-k; 	} 	srand((unsigned)time(NULL)); 	for(k=0;k<=4;k++) 	{ 		cross[k].x=rand()%50+5; 		cross[k].y=rand()%20+1; 	} 	for(j=0;j<=2;j++) 	{ 		smile[j].x=rand()%54+1; 		smile[j].y=rand()%15+8; 	} 	clescr(); 	screen(); 	 	 	for(j=0;j<3;j++) 	{ 		HANDLE hout; 		COORD coord; 		coord.X=snake[j].x; 		coord.Y=snake[j].y; 		hout=GetStdHandle(STD_OUTPUT_HANDLE); 		SetConsoleCursorPosition(hout,coord); 		printf("%c",4); 	}//不再赘述，主要就是清屏，画边界，画一开始的蛇 	for(j=0;j<=4;j++) 	{ 		HANDLE hout; 		COORD coord; 		coord.X=cross[j].x; 		coord.Y=cross[j].y; 		hout=GetStdHandle(STD_OUTPUT_HANDLE); 		SetConsoleCursorPosition(hout,coord); 		printf("%c",29); 	} 	for(j=0;j<3;j++) 	{ 		HANDLE hout; 		COORD coord; 		coord.X=smile[j].x; 		coord.Y=smile[j].y; 		hout=GetStdHandle(STD_OUTPUT_HANDLE); 		SetConsoleCursorPosition(hout,coord); 		printf("%c",2); 	} 	while(1) 	{ 		moveon(); 		keybd(); 		int i; 		HANDLE hout; 		COORD coord; 		coord.X=snake[0].x; 		coord.Y=snake[0].y; 		hout=GetStdHandle(STD_OUTPUT_HANDLE); 		SetConsoleCursorPosition(hout,coord); 		printf("%c",4);//正如思路里面所述，获取方向键信息之后画蛇头 		over(); 		ifcollide(); 		ifcolobs(); 		 		for(i=0;i<=2;i++) 		{ 			int a=0; 			if((snake[0].x==smile[i].x)&&(snake[0].y==smile[i].y)) 				a=1;//判断是不是有吃到笑脸 			if(a==1) 			{  				int b=0;//如果有吃到，长度加一，对于被吃到的笑脸，把那个结构体的坐标重新随机一遍，再画出来，当然随机完需要判断一下是不是有和谁重叠 				length++; 				while(b==0) 				{ 					int c; 					srand((unsigned)time(NULL)); 					smile[i].x=rand()%56+1; 					smile[i].y=rand()%16+1; 					for(c=0;c<=length;c++) 					{ 						if((snake[c].x==smile[i].x)&&(snake[c].y==smile[i].y)) 						{ 							c=length+1; 							b--; 						} 					} 					b++; 				} 				HANDLE hout; 				COORD coord; 				coord.X=smile[i].x; 				coord.Y=smile[i].y; 				hout=GetStdHandle(STD_OUTPUT_HANDLE); 				SetConsoleCursorPosition(hout,coord); 				printf("%c",2); 			} 			rubber(); 		} 		rubber(); 		//moveon(); 	} 	return 0; }

控制台版的贪吃蛇


Question: c语言

灰常感谢哒~~~

这样的问题，再往上不难找到，像这个——http://zhidao.baidu.com/link?url=PIbId2SQVgDzdIeomPv6QzjC-zYOSncLUeHn30nISNP3wnMjnWC3bPRJPks0wqCFwfemD0oKOaIfyrEnXoWiJK

引用 1 楼 user-3 的回复:#include <stdio.h>  int main(void) {    puts("\\n");     return 0; } +1


Question: 一个删除字符串中空格的函数

1.我不赞同1楼的第1点 2.我觉得楼上的代码可以有效实现楼主要求 下面我是按楼主的代码改的 测试过 没有毛病  #include<stdio.h> #define SIZE 81 void skong(char *); int main(void) { 	char ar[SIZE]; 	puts("请输入字符串,输入空行结束"); 	while (fgets(ar, SIZE, stdin) != NULL && *ar != '\n')//改1 	{ 		puts("删除空行之前"); 		fputs(ar, stdout); 		skong(ar); 		puts("删除空行之后"); 		fputs(ar, stdout); 		fflush(stdin);//改2 这个纯个人习惯 		puts("请输入字符串，输入空行结束"); 	} 	return 0; } #include<string.h> void skong(char *str) { 	while (*str) 	{ 		if (*str == ' ') 		{ 			strcpy(str, str + 1); 			continue; 		} 		str++; 	} }  编译器：VS2013

1. 使用strcpy的时候要求源串和目的串不能有重叠，你这个明显有重叠，结果就看人品了。 2. strcpy这个函数不安全，因为它没有任何边界检查，很容易造成目的串溢出。可以用strncpy或其它一些安全的函数替代。 3. strcpy的思路，每次删一个空格就要把后面的所有字符复制一次，效率太低。 void RemoveSpaces(char str[]) {   char *p_src, *p_dst;    if (str == NULL) {     return;   }   for (p_src = p_dst = str; *p_src != '\0'; p_src++) {     if (*p_src != ' ') {       *p_dst++ = *p_src;     }   }   *p_dst = '\0'; }


Question: unsigned char型的变量，值为0， 减去1成为多少？

a - 1的话是int类型，-操作符左边是unsigned char，右边是int（1），然后a被提升至int做减法，结果是int类型的-1。

#include "stdafx.h" #include <iostream>  int _tmain(int argc, _TCHAR* argv[]) { 	unsigned char a = 0; 	std::cout << (a-1) << std::endl; 	while(1){}; 	return 0; }  VS2012编译出来是-1 char - int  ，char会被强转成int  还是说unsigned char 本身可能就是int型的？

C标准  unsigned  char  ，unsigned short 和int  运算     不会转化为unsigned int   采用的值保留的策略         早期的C    全部转换   但是现在的C标准不转换    （unsigned char）0 - 1 就为  -1             没写代码验证

哦？！有替身先上了。

int _tmain(int argc, _TCHAR* argv[]) { 003A1370  push        ebp   003A1371  mov         ebp,esp  003A1373  sub         esp,0CCh  003A1379  push        ebx   003A137A  push        esi   003A137B  push        edi   003A137C  lea         edi,[ebp-0CCh]  003A1382  mov         ecx,33h  003A1387  mov         eax,0CCCCCCCCh  003A138C  rep stos    dword ptr es:[edi]  	unsigned char a = 0; 003A138E  mov         byte ptr [a],0  	a - 1; 	return 0; 003A1392  xor         eax,eax  }

你没有考虑减数1的感受，你以为别人这么随便就让你减吗？别人也是有类型的好不。

引用 5 楼 screen12 的回复:[quote=引用 4 楼 yangyunzhao 的回复:] [quote=引用 2 楼 screen12 的回复:] 我刚才看了一下书，书上说：出现在表达式中的变量，不管是char 还是 short，都会被转换成int型。  这样一来，a被转换成int型，变成了有符号数，然后减1，等于-1。就不等于255了。  我希望它等于255 ，是不是这样转换一下呢？  (unsigned char)(a - 1),这样的话，a就等于255了是吗？  哪本书？可以扔了[/quote] C primer plus[/quote]  看到书名，吓得我一身冷汗，赶紧写代码验证了一下。  我觉得lz的问题本身就不是很明确，然后引用书里的内容又有些断章取义了。  以下是我写源码  	unsigned char a = 0; 	int i = a - 1;  	a = 0; 	unsigned int ii = a -1;  	a = 0; 	unsigned char b = a - 1;   这个是汇编代码，VC2008SP1  	unsigned char a = 0; 0122138E  mov         byte ptr [a],0  	int i = a - 1; 01221392  movzx       eax,byte ptr [a]  01221396  sub         eax,1  01221399  mov         dword ptr [i],eax   	a = 0; 0122139C  mov         byte ptr [a],0  	unsigned int ii = a -1; 012213A0  movzx       eax,byte ptr [a]  012213A4  sub         eax,1  012213A7  mov         dword ptr [ii],eax   	a = 0; 012213AA  mov         byte ptr [a],0  	unsigned char b = a - 1; 012213AE  movzx       eax,byte ptr [a]  012213B2  sub         eax,1  012213B5  mov         byte ptr [b],al

引用 14 楼 u013470052 的回复:[quote=引用 13 楼 mujiok2003 的回复:] [quote=引用 12 楼 u013470052 的回复:] unsigned  char会被转化成unsigned int  而不是int  这里只有类型提升(integer promotions)， 没有转换(conversions),不要误导别人。 [/quote] 好吧 是提升  说错了  [/quote]  a-1的类型是int. 这个是结论。

引用 13 楼 mujiok2003 的回复:[quote=引用 12 楼 u013470052 的回复:] unsigned  char会被转化成unsigned int  而不是int  这里只有类型提升(integer promotions)， 没有转换(conversions),不要误导别人。 [/quote] 好吧 是提升  说错了

引用 12 楼 u013470052 的回复:unsigned  char会被转化成unsigned int  而不是int  这里只有类型提升(integer promotions)， 没有转换(conversions),不要误导别人。

unsigned  char会被转化成unsigned int  而不是int

引用 9 楼 mujiok2003 的回复:对a 类型提升: unsigned char-> int, 变成int - int, 所以类型是a -1的类型是int。 值的话， 0-1当然是-1喽 写了个C++程序证明

编译器去哪儿了？

-1 不管只要是整形数据类型, 不管是哪种都应该是多个0xFF组成.  如果是char 或者 unsigned char  都是0xFF short或者unsigned short 都是0xFFFF int或者unsigned int都是0xFFFFFFFF

a-1需要赋值给一个左值，比如说b=a-1 这样的话就根据b的不同值就不同，但是二进制位是一样的。 如果b是int类型。printf("ia=%u=%d\n",a-1, a-1);输出ia=4294967295=-1

计算机组成原理→DOS命令→汇编语言→C语言（不包括C++）、代码书写规范→数据结构、编译原理、操作系统→计算机网络、数据库原理、正则表达式→其它语言（包括C++）、架构……  对学习编程者的忠告： 眼过千遍不如手过一遍！ 书看千行不如手敲一行！ 手敲千行不如单步一行！ 单步源代码千行不如单步对应汇编一行！  VC调试时按Alt+8、Alt+7、Alt+6和Alt+5,打开汇编窗口、堆栈窗口、内存窗口和寄存器窗口看每句C对应的汇编、单步执行并观察相应堆栈、内存和寄存器变化，这样过一遍不就啥都明白了吗。 对VC来说，所谓‘调试时’就是编译连接通过以后，按F10或F11键单步执行一步以后的时候，或者在某行按F9设了断点后按F5执行停在该断点处的时候。 （Turbo C或Borland C用Turbo Debugger调试,Linux或Unix下用GDB调试时,看每句C对应的汇编并单步执行观察相应内存和寄存器变化。）  想要从本质上理解C指针，必须学习汇编以及C和汇编的对应关系。 从汇编的角度理解和学习C语言的指针，原本看似复杂的东西就会变得非常简单！ 指针即地址。“地址又是啥？”“只能从汇编语言和计算机组成原理的角度去解释了。” 但我又不得不承认：  有那么些人喜欢或者适合用“先具体再抽象”的方法学习和理解复杂事物；  而另一些人喜欢或者适合用“先抽象再具体”的方法学习和理解复杂事物。 而我本人属前者。  不要企图依赖输出指针相关表达式的值【比如printf("%p\n",...)】来理解指针的本质， 而要依赖调试时的反汇编窗口中的C/C++代码【比如void *p=...】及其对应汇编指令以及内存窗口中的内存地址和内存值来理解指针的本质。  这辈子不看内存地址和内存值；只画链表、指针示意图，画堆栈示意图，画各种示意图，甚至自己没画过而只看过书上的图……能从本质上理解指针、理解函数参数传递吗？本人深表怀疑！ 这辈子不种麦不收麦不将麦粒拿去磨面；只吃馒头、吃面条、吃面包、……甚至从没看过别人怎么蒸馒头，压面条，烤面包，……能从本质上理解面粉、理解面食吗？本人深表怀疑！！  提醒： “学习用汇编语言写程序” 和 “VC调试(TC或BC用TD调计算机组成原理→DOS命令→汇编语言→C语言（不包括C++）、代码书写规范→数据结构、编译原理、操作系统→计算机网络、数据库原理、正则表达式→其它语言（包括C++）、架构……  对学习编程者的忠告： 眼过千遍不如手过一遍！ 书看千行不如手敲一行！ 手敲千行不如单步一行！ 单步源代码千行不如单步对应汇编一行！  VC调试时按Alt+8、Alt+7、Alt+6和Alt+5,打开汇编窗口、堆栈窗口、内存窗口和寄存器窗口看每句C对应的汇编、单步执行并观察相应堆栈、内存和寄存器变化，这样过一遍不就啥都明白了吗。 对VC来说，所谓‘调试时’就是编译连接通过以后，按F10或F11键单步执行一步以后的时候，或者在某行按F9设了断点后按F5执行停在该断点处的时候。 （Turbo C或Borland C用Turbo Debugger调试,Linux或Unix下用GDB调试时,看每句C对应的汇编并单步执行观察相应内存和寄存器变化。）  想要从本质上理解C指针，必须学习汇编以及C和汇编的对应关系。 从汇编的角度理解和学习C语言的指针，原本看似复杂的东西就会变得非常简单！ 指针即地址。“地址又是啥？”“只能从汇编语言和计算机组成原理的角度去解释了。” 但我又不得不承认：  有那么些人喜欢或者适合用“先具体再抽象”的方法学习和理解复杂事物；  而另一些人喜欢或者适合用“先抽象再具体”的方法学习和理解复杂事物。 而我本人属前者。  不要企图依赖输出指针相关表达式的值【比如printf("%p\n",...)】来理解指针的本质， 而要依赖调试时的反汇编窗口中的C/C++代码【比如void *p=...】及其对应汇编指令以及内存窗口中的内存地址和内存值来理解指针的本质。  这辈子不看内存地址和内存值；只画链表、指针示意图，画堆栈示意图，画各种示意图，甚至自己没画过而只看过书上的图……能从本质上理解指针、理解函数参数传递吗？本人深表怀疑！ 这辈子不种麦不收麦不将麦粒拿去磨面；只吃馒头、吃面条、吃面包、……甚至从没看过别人怎么蒸馒头，压面条，烤面包，……能从本质上理解面粉、理解面食吗？本人深表怀疑！！  提醒： “学习用汇编语言写程序” 和 “VC调试(TC或BC用TD调试)时按Alt+8、Alt+7、Alt+6和Alt+5,打开汇编窗口、堆栈窗口、内存窗口和寄存器窗口看每句C对应的汇编、单步执行并观察相应堆栈、内存和寄存器变化，这样过一遍不就啥都明白了吗。 （Linux或Unix下可以在用GDB调试时,看每句C对应的汇编并单步执行观察相应内存和寄存器变化。） 想要从本质上理解C指针，必须学习C和汇编的对应关系。” 不是一回事！  不要迷信书、考题、老师、回帖； 要迷信CPU、编译器、调试器、运行结果。 并请结合“盲人摸太阳”和“驾船出海时一定只带一个指南针。”加以理解。 任何理论、权威、传说、真理、标准、解释、想象、知识……都比不上摆在眼前的事实！  有人说一套做一套，你相信他说的还是相信他做的？ 其实严格来说这个世界上古往今来所有人都是说一套做一套，不是吗？  不要写连自己也预测不了结果的代码！  电脑内存或文件内容只是一个一维二进制字节数组及其对应的二进制地址； 人脑才将电脑内存或文件内容中的这个一维二进制字节数组及其对应的二进制地址的某些部分看成是整数、有符号数/无符号数、浮点数、复数、英文字母、阿拉伯数字、中文/韩文/法文……字符/字符串、汇编指令、函数、函数参数、堆、栈、数组、指针、数组指针、指针数组、数组的数组、指针的指针、二维数组、字符点阵、字符笔画的坐标、黑白二值图片、灰度图片、彩色图片、录音、视频、指纹信息、身份证信息……  十字链表交换任意两个节点C源代码（C指针应用终极挑战）http://download.csdn.net/detail/zhao4zhong1/5532495  英语也是一门计算机语言的说。  关于自己是否适合编程的很简单的测试： 在报纸或杂志上随便找一段约1000字的文章，在Word中输入一遍。输完后再参考下面答案：  A里面有10处以上文字或标点错误 B里面没有文字或标点错误并敢为此跟人打赌 C里面没有文字或标点错误并且字体和排版完全与原稿一致 D打印在半透明的纸上和原稿重叠在一起检查一模一样，且自我感觉很有成就感  A不适合编程（理由：打字准确度偏低、粗心大意） B初级程序员（理由：打字准确度很高、认真细致、自信、理解全角半角概念） C高级程序员（理由：在B的基础上理解字体和排版也是电脑打印的重要因素、但相比D还不够偏执、精益求精、结果可验证） D软件项目经理（理由：能针对项目给出令人信服的细致到极点的需求说明和典型测试用例。用户几乎挑不出毛病。专业！）  如果想从A变成B的话，到我的资源http://download.csdn.net/detail/zhao4zhong1/4084259里面下载“适合程序员的键盘练习”试)时按Alt+8、Alt+7、Alt+6和Alt+5,打开汇编窗口、堆栈窗口、内存窗口和寄存器窗口看每句C对应的汇编、单步执行并观察相应堆栈、内存和寄存器变化，这样过一遍不就啥都明白了吗。 （Linux或Unix下可以在用GDB调试时,看每句C对应的汇编并单步执行观察相应内存和寄存器变化。） 想要从本质上理解C指针，必须学习C和汇编的对应关系。” 不是一回事！  不要迷信书、考题、老师、回帖； 要迷信CPU、编译器、调试器、运行结果。 并请结合“盲人摸太阳”和“驾船出海时一定只带一个指南针。”加以理解。 任何理论、权威、传说、真理、标准、解释、想象、知识……都比不上摆在眼前的事实！  有人说一套做一套，你相信他说的还是相信他做的？ 其实严格来说这个世界上古往今来所有人都是说一套做一套，不是吗？  不要写连自己也预测不了结果的代码！  电脑内存或文件内容只是一个一维二进制字节数组及其对应的二进制地址； 人脑才将电脑内存或文件内容中的这个一维二进制字节数组及其对应的二进制地址的某些部分看成是整数、有符号数/无符号数、浮点数、复数、英文字母、阿拉伯数字、中文/韩文/法文……字符/字符串、汇编指令、函数、函数参数、堆、栈、数组、指针、数组指针、指针数组、数组的数组、指针的指针、二维数组、字符点阵、字符笔画的坐标、黑白二值图片、灰度图片、彩色图片、录音、视频、指纹信息、身份证信息……  十字链表交换任意两个节点C源代码（C指针应用终极挑战）http://download.csdn.net/detail/zhao4zhong1/5532495  英语也是一门计算机语言的说。  关于自己是否适合编程的很简单的测试： 在报纸或杂志上随便找一段约1000字的文章，在Word中输入一遍。输完后再参考下面答案：  A里面有10处以上文字或标点错误 B里面没有文字或标点错误并敢为此跟人打赌 C里面没有文字或标点错误并且字体和排版完全与原稿一致 D打印在半透明的纸上和原稿重叠在一起检查一模一样，且自我感觉很有成就感  A不适合编程（理由：打字准确度偏低、粗心大意） B初级程序员（理由：打字准确度很高、认真细致、自信、理解全角半角概念） C高级程序员（理由：在B的基础上理解字体和排版也是电脑打印的重要因素、但相比D还不够偏执、精益求精、结果可验证） D软件项目经理（理由：能针对项目给出令人信服的细致到极点的需求说明和典型测试用例。用户几乎挑不出毛病。专业！）  如果想从A变成B的话，到赵老师的资源http://download.csdn.net/detail/zhao4zhong1/4084259里面下载“适合程序员的键盘练习”

引用 4 楼 yangyunzhao 的回复:[quote=引用 2 楼 screen12 的回复:] 我刚才看了一下书，书上说：出现在表达式中的变量，不管是char 还是 short，都会被转换成int型。  这样一来，a被转换成int型，变成了有符号数，然后减1，等于-1。就不等于255了。  我希望它等于255 ，是不是这样转换一下呢？  (unsigned char)(a - 1),这样的话，a就等于255了是吗？  哪本书？可以扔了[/quote] C primer plus

引用 2 楼 screen12 的回复:我刚才看了一下书，书上说：出现在表达式中的变量，不管是char 还是 short，都会被转换成int型。  这样一来，a被转换成int型，变成了有符号数，然后减1，等于-1。就不等于255了。  我希望它等于255 ，是不是这样转换一下呢？  (unsigned char)(a - 1),这样的话，a就等于255了是吗？  哪本书？可以扔了

手头没有编译器吗？试试看呗


Question: 求大神

随便输入一个数字后回车

引用 1 楼 FightForProgrammer 的回复:printf("个位数是:%d",z); printf("十位数是:%d",y); printf("百位数是:%d",x) 少了%d  你的输入格式不对。scanf("%d",&a);

#include <stdio.h> int a; int x,y,z; int main() { printf("请输入一个三位整数:"); scanf("%d",&a); x=a/100;     y=a/10%10; z=a%10; printf("个位数是:%d",z); printf("十位数是:%d",y); printf("百位数是:%d",x); return 0; }

你这个scanf的语句里面不要加\n  然后还有输出语句少了%d

见二楼！！！！！！！！！！！！！！！

我试过了没用    下面就显示不出来了


Question: 关于LINUX下的SOCKET编程问题

太失败了。 问了这种菜鸟问题。 已经知道了操作。 结贴！

直接把你编译好的二进制文件拖到终端运行


Question: 关于&&与||的问题。不懂呀

这是短路与和短路或，短路与只要第一个式子为假就不用执行后面的式子了，整个式子都为假；短路或如果第一个式子为真，则整个式子为真，不用执行后面的式子。所以第2,4,5个式子都不用执行后面的printf语句。而第一和第三句因为&&（||）左边的并不能判断整个式子的真假，所以要执行后面的语句。 求给分~~~~


Question: 指针错误，求指教。

p指向的是字符串常量，不能修改，记得以前看过一个帖子问过这个问题、、、 找了老半天找到了。。。 http://bbs.csdn.net/topics/340104640


Question: 请问这个相对健壮的'插入'链表中,设计到多线程?

以上 都是线程安全的

这是一个单链表 这是一个双联表

引用 6 楼 zhao4zhong1 的回复:多线程没日志、没锁也敢叫健壮？  我的C相当于刚入门,还没接触那些. 教材上说的,就是觉得这种算法一般寿命比较长罢了. 开始我是不知道为什么在第 13 行需要 检测同时检测两个条件.

引用 10 楼 yangyunzhao 的回复:[quote=引用 8 楼 zilaishuichina 的回复:] 这是一个单链表 这是一个双联表  ContainerFlag ？？？ m_dwLock ？？？  如果是学习性质无所谓。但如果是工作中，我觉得还是使用标准库比较好，除非能够证明自己效率确实比较高。[/quote]  欢迎来测

我觉得规范点写开头应该先判断head == null ?和pos < 0 ?，后面只需要判断当前位置是否为空。这样代码不是一目了然？

引用 8 楼 zilaishuichina 的回复:这是一个单链表 这是一个双联表  ContainerFlag ？？？ m_dwLock ？？？  如果是学习性质无所谓。但如果是工作中，我觉得还是使用标准库比较好，除非能够证明自己效率确实比较高。

引用 3 楼 zhao4zhong1 的回复:仅供参考 //循环向a函数每次发送200个字节长度（这个是固定的）的buffer, //a函数中需要将循环传进来的buffer，组成240字节（也是固定的）的新buffer进行处理， //在处理的时候每次从新buffer中取两个字节打印 #ifdef WIN32     #pragma warning(disable:4996) #endif #include <stdio.h> #include <stdlib.h> #include <string.h> #ifdef WIN32     #include <windows.h>     #include <process.h>     #include <io.h>     #define  MYVOID             void     #define  vsnprintf          _vsnprintf #else     #include <unistd.h>     #include <sys/time.h>     #include <pthread.h>     #define  CRITICAL_SECTION   pthread_mutex_t     #define  MYVOID             void * #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); } void sleep_ms(int ms) {     Sleep(ms); } #else void Lock(CRITICAL_SECTION *l) {     pthread_mutex_lock(l); } void Unlock(CRITICAL_SECTION *l) {     pthread_mutex_unlock(l); } void sleep_ms(int ms) {     usleep(ms*1000); } #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} #define ASIZE    200 #define BSIZE    240 #define CSIZE      2 char Abuf[ASIZE]; char Cbuf[CSIZE]; CRITICAL_SECTION cs_HEX ; CRITICAL_SECTION cs_BBB ; struct FIFO_BUFFER {     int  head;     int  tail;     int  size;     char data[BSIZE]; } BBB; int No_Loop=0; void HexDump(int cn,char *buf,int len) {     int i,j,k;     char binstr[80];      Lock(&cs_HEX);     for (i=0;i<len;i++) {         if (0==(i%16)) {             sprintf(binstr,"%03d %04x -",cn,i);             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]:'.');             }             Log("%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]:'.');         }         Log("%s\n",binstr);     }     Unlock(&cs_HEX); } int GetFromRBuf(int cn,CRITICAL_SECTION *cs,FIFO_BUFFER *fbuf,char *buf,int len) {     int lent,len1,len2;      lent=0;     Lock(cs);     if (fbuf->size>=len) {         lent=len;         if (fbuf->head+lent>BSIZE) {             len1=BSIZE-fbuf->head;             memcpy(buf     ,fbuf->data+fbuf->head,len1);             len2=lent-len1;             memcpy(buf+len1,fbuf->data           ,len2);             fbuf->head=len2;         } else {             memcpy(buf     ,fbuf->data+fbuf->head,lent);             fbuf->head+=lent;         }         fbuf->size-=lent;     }     Unlock(cs);     return lent; } MYVOID thdB(void *pcn) {     char        *recv_buf;     int          recv_nbytes;     int          cn;     int          wc;     int          pb;      cn=(int)pcn;     Log("%03d thdB              thread begin...\n",cn);     while (1) {         sleep_ms(10);         recv_buf=(char *)Cbuf;         recv_nbytes=CSIZE;         wc=0;         while (1) {             pb=GetFromRBuf(cn,&cs_BBB,&BBB,recv_buf,recv_nbytes);             if (pb) {                 Log("%03d recv %d bytes\n",cn,pb);                 HexDump(cn,recv_buf,pb);                 sleep_ms(1);             } else {                 sleep_ms(1000);             }             if (No_Loop) break;//             wc++;             if (wc>3600) Log("%03d %d==wc>3600!\n",cn,wc);         }         if (No_Loop) break;//     } #ifndef WIN32     pthread_exit(NULL); #endif } int PutToRBuf(int cn,CRITICAL_SECTION *cs,FIFO_BUFFER *fbuf,char *buf,int len) {     int lent,len1,len2;      Lock(cs);     lent=len;     if (fbuf->size+lent>BSIZE) {         lent=BSIZE-fbuf->size;     }     if (fbuf->tail+lent>BSIZE) {         len1=BSIZE-fbuf->tail;         memcpy(fbuf->data+fbuf->tail,buf     ,len1);         len2=lent-len1;         memcpy(fbuf->data           ,buf+len1,len2);         fbuf->tail=len2;     } else {         memcpy(fbuf->data+fbuf->tail,buf     ,lent);         fbuf->tail+=lent;     }     fbuf->size+=lent;     Unlock(cs);     return lent; } MYVOID thdA(void *pcn) {     char        *send_buf;     int          send_nbytes;     int          cn;     int          wc;     int           a;     int          pa;      cn=(int)pcn;     Log("%03d thdA              thread begin...\n",cn);     a=0;     while (1) {         sleep_ms(100);         memset(Abuf,a,ASIZE);         a=(a+1)%256;         if (16==a) {No_Loop=1;break;}//去掉这句可以让程序一直循环直到按Ctrl+C或Ctrl+Break或当前目录下存在文件No_Loop         send_buf=(char *)Abuf;         send_nbytes=ASIZE;         Log("%03d sending %d bytes\n",cn,send_nbytes);         HexDump(cn,send_buf,send_nbytes);         wc=0;         while (1) {             pa=PutToRBuf(cn,&cs_BBB,&BBB,send_buf,send_nbytes);             Log("%03d sent %d bytes\n",cn,pa);             HexDump(cn,send_buf,pa);             send_buf+=pa;             send_nbytes-=pa;             if (send_nbytes<=0) break;//             sleep_ms(1000);             if (No_Loop) break;//             wc++;             if (wc>3600) Log("%03d %d==wc>3600!\n",cn,wc);         }         if (No_Loop) break;//     } #ifndef WIN32     pthread_exit(NULL); #endif } int main() { #ifdef WIN32     InitializeCriticalSection(&cs_log);     InitializeCriticalSection(&cs_HEX );     InitializeCriticalSection(&cs_BBB ); #else     pthread_t threads[2];     int threadsN;     int rc;     pthread_mutex_init(&cs_log,NULL);     pthread_mutex_init(&cs_HEX,NULL);     pthread_mutex_init(&cs_BBB,NULL); #endif     Log("Start===========================================================\n");      BBB.head=0;     BBB.tail=0;     BBB.size=0;  #ifdef WIN32     _beginthread((void(__cdecl *)(void *))thdA,0,(void *)1);     _beginthread((void(__cdecl *)(void *))thdB,0,(void *)2); #else     threadsN=0;     rc=pthread_create(&(threads[threadsN++]),NULL,thdA,(void *)1);if (rc) Log("%d=pthread_create %d error!\n",rc,threadsN-1);     rc=pthread_create(&(threads[threadsN++]),NULL,thdB,(void *)2);if (rc) Log("%d=pthread_create %d error!\n",rc,threadsN-1); #endif      if (!access("No_Loop",0)) {         remove("No_Loop");         if (!access("No_Loop",0)) {             No_Loop=1;         }     }     while (1) {         sleep_ms(1000);         if (No_Loop) break;//         if (!access("No_Loop",0)) {             No_Loop=1;         }     }     sleep_ms(3000);     Log("End=============================================================\n"); #ifdef WIN32     DeleteCriticalSection(&cs_BBB );     DeleteCriticalSection(&cs_HEX );     DeleteCriticalSection(&cs_log); #else     pthread_mutex_destroy(&cs_BBB);     pthread_mutex_destroy(&cs_HEX);     pthread_mutex_destroy(&cs_log); #endif     return 0; }   兄弟，这个貌似和我的问题好像没有多少关系哦？

多线程没日志、没锁也敢叫健壮？

引用 1 楼 truexf 的回复:如果传入的pos是负数呢？ 貌似也就这样而已了，pos和 i 判断为负，p和 null判断的是可能为空链表。

如果传入的pos是负数呢？

i应该是节点数，如果多线程的话。。。是不是判断当前链表是否正在被某一线程进行插入？


Question: 关于计算机c语言计算问题

能说详细点吗？

因为有溢出 假如运算范围是1位十进制，那么3+8=11溢出，结果就是3+8=1 而有符号的-2转换成无符号就是8，3+(-2)=3+8=1


Question: vc6.0在wind8.1系统上经常出现工作已停止

FileTool.exe 替换打开和添加到项目中 Visual C++ 的新功能 http://support.microsoft.com/kb/241396/zh-cn

别用v开头的东西

换最新的VS  装虚拟机，装xp，装vc6

摒弃Win8 使用VC6

都win 8了， 还 vc 6.0，唉

换个新点的行不行，VC6招谁惹谁了，都这么老了，还揪着人家不放

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

不清楚，我win8虽然装着VC6，但一般不用，同楼上各位，建议楼主还是换个编译器吧

lz换编译器吧，要不然用兼容模式运行

除非公司有些老项目，要求必须用vc6，否则还是换新的吧。

引用 1 楼 user-13 的回复:珍惜生命，远离VC6. 学编程，又不是学考古。 换个新点的编译器吧。 改用vs2010吗

不要说win8 ，我在xp和win7 上经常这样，我也问过，很多人也发现， VCbug太多了，换 VS吧，或其他。

好像不应该啊，说不定很多WIN8组件都是VC6写的呢

珍惜生命，远离VC6. 学编程，又不是学考古。 换个新点的编译器吧。


Question: fscanf(stdin, "%79[^\n]\n",line) 这里两个\n什么意思

读取“除了\n以外的字符”，最多读79个； 完了之后输入流中还得有个\n，

引用 11 楼 gy_1518 的回复:9、10楼全英文，亚历山大。。。 英语也是一门计算机语言的说。

引用 13 楼 lin5161678 的回复:你输入 123 然后按下回车 表示完成输入  这时候 缓冲区里面存储的数据实际是  123\n 4个字符  而你的 %[^\n] 表示 读取除了\n以为的全部字符  那么缓冲区里面的 123 就会被读走   最后缓冲区里面就只剩下数据 \n 现在你知道代码里面 最后一个\n是做什么的嘛 ?额， 再明白点是？？截取？那是第一个吧，第二个就是输入？可是如果有字数限制，小于字数输入要输入两个回车才显示结果

9、10楼全英文，亚历山大。。。

C++ Character Constants Character constants are one or more members of the “source character set,” the character set in which a program is written, surrounded by single quotation marks ('). They are used to represent characters in the “execution character set,” the character set on the machine where the program executes.  Microsoft Specific   For Microsoft C++, the source and execution character sets are both ASCII.  END Microsoft Specific  There are three kinds of character constants:   Normal character constants   Multicharacter constants   Wide-character constants  Note   Use wide-character constants in place of multicharacter constants to ensure portability.  Character constants are specified as one or more characters enclosed in single quotation marks. For example:  char ch = 'x';          // Specify normal character constant. int mbch = 'ab';        // Specify system-dependent                         //  multicharacter constant. wchar_t wcch = L'ab';   // Specify wide-character constant.  Note that mbch is of type int. If it were declared as type char, the second byte would not be retained. A multicharacter constant has four meaningful characters; specifying more than four generates an error message.  Syntax  character-constant :  'c-char-sequence' L'c-char-sequence'  c-char-sequence :  c-char c-char-sequence c-char  c-char :  any member of the source character set except the single quotation mark ('), backslash (\), or newline character escape-sequence  escape-sequence :  simple-escape-sequence octal-escape-sequence hexadecimal-escape-sequence  simple-escape-sequence : one of  \' \" \? \\ \a \b \f \n \r \t \v  octal-escape-sequence :  \octal-digit \octal-digit octal-digit \octal-digit octal-digit octal-digit  hexadecimal-escape-sequence :  \xhexadecimal-digit hexadecimal-escape-sequence hexadecimal-digit  Microsoft C++ supports normal, multicharacter, and wide-character constants. Use wide-character constants to specify members of the extended execution character set (for example, to support an international application). Normal character constants have type char, multicharacter constants have type int, and wide-character constants have type wchar_t. (The type wchar_t is defined in the standard include files STDDEF.H, STDLIB.H, and STRING.H. The wide-character functions, however, are prototyped only in STDLIB.H.)  The only difference in specification between normal and wide-character constants is that wide-character constants are preceded by the letter L. For example:  char schar = 'x';               // Normal character constant wchar_t wchar = L'\x81\x19';    // Wide-character constant  Table 1.2 shows reserved or nongraphic characters that are system dependent or not allowed within character constants. These characters should be represented with escape sequences.  Table 1.2   C++ Reserved or Nongraphic Characters  Character ASCII  Representation ASCII  Value Escape Sequence  Newline NL (LF) 10 or 0x0a \n  Horizontal tab HT 9 \t  Vertical tab VT 11 or 0x0b \v  Backspace BS 8 \b  Carriage return CR 13 or 0x0d \r  Formfeed FF 12 or 0x0c \f  Alert BEL 7 \a  Backslash \ 92 or 0x5c \\  Question mark ? 63 or 0x3f \?  Single quotation mark ' 39 or 0x27 \'  Double quotation mark " 34 or 0x22 \"  Octal number ooo — \ooo  Hexadecimal number hhh — \xhhh  Null character NUL 0 \0    If the character following the backslash does not specify a legal escape sequence, the result is implementation defined. In Microsoft C++, the character following the backslash is taken literally, as though the escape were not present, and a level 1 warning (“unrecognized character escape sequence”) is issued.  Octal escape sequences, specified in the form \ooo, consist of a backslash and one, two, or three octal characters. Hexadecimal escape sequences, specified in the form \xhhh, consist of the characters \x followed by a sequence of hexadecimal digits. Unlike octal escape constants, there is no limit on the number of hexadecimal digits in an escape sequence.  Octal escape sequences are terminated by the first character that is not an octal digit, or when three characters are seen. For example:  wchar_t och = L'\076a';  // Sequence terminates at a char    ch = '\233';     // Sequence terminates after 3 characters  Similarly, hexadecimal escape sequences terminate at the first character that is not a hexadecimal digit. Because hexadecimal digits include the letters a through f (and A through F), make sure the escape sequence terminates at the intended digit.  Because the single quotation mark (') encloses character constants, use the escape sequence \' to represent enclosed single quotation marks. The double quotation mark (") can be represented without an escape sequence. The backslash character (\) is a line-continuation character when placed at the end of a line. If you want a backslash character to appear within a character constant, you must type two backslashes in a row (\\). (SeePhases of Translation in the Preprocessor Reference for more information about line continuation.)

scanf Width Specification width is a positive decimal integer controlling the maximum number of characters to be read from stdin. No more than width characters are converted and stored at the corresponding argument. Fewer than width characters may be read if a white-space character (space, tab, or newline) or a character that cannot be converted according to the given format occurs before width is reached.  The optional prefixes h, l, I64, and L indicate the “size” of the argument (long or short, single-byte character or wide character, depending upon the type character that they modify). These format-specification characters are used with type characters in scanf or wscanf functions to specify interpretation of arguments as shown in the Table R.7. The type prefixes h, l, I64, and L are Microsoft extensions and are not ANSI-compatible. The type characters and their meanings are described in Table R.8.  Table R.7   Size Prefixes for scanf and wscanf Format-Type Specifiers  To Specify Use Prefix With Type Specifier  double l e, E, f, g, or G  long int l d, i, o, x, or X  long unsigned int l u  short int h d, i, o, x, or X  short unsigned int h u  __int64 I64 d, i, o, u, x, or X  Single-byte character with scanf h c or C  Single-byte character with wscanf h c or C  Wide character with scanf l c or C  Wide character with wscanf l c, or C  Single-byte – character string with scanf h s or S  Single-byte – character string with wscanf h s or S  Wide-character string with scanf l s or S  Wide-character string with wscanf l s or S    Following are examples of the use of h and l with scanffunctions and wscanf functions:  scanf( "%ls", &x );    // Read a wide-character string wscanf( "%lC", &x );    // Read a single-byte character  To read strings not delimited by space characters, a set of characters in brackets ([ ]) can be substituted for the s (string) type character. The corresponding input field is read up to the first character that does not appear in the bracketed character set. If the first character in the set is a caret (^), the effect is reversed: The input field is read up to the first character that does appear in the rest of the character set.  Note that %[a-z] and %[z-a] are interpreted as equivalent to %[abcde...z]. This is a common scanf function extension, but note that the ANSI standard does not require it.  To store a string without storing a terminating null character ('\0'), use the specification %nc where n is a decimal integer. In this case, the c type character indicates that the argument is a pointer to a character array. The next n characters are read from the input stream into the specified location, and no null character ('\0') is appended. If n is not specified, its default value is 1.  The scanf function scans each input field, character by character. It may stop reading a particular input field before it reaches a space character for a variety of reasons:   The specified width has been reached.   The next character cannot be converted as specified.   The next character conflicts with a character in the control string that it is supposed to match.    The next character fails to appear in a given character set.  For whatever reason, when the scanf function stops reading an input field, the next input field is considered to begin at the first unread character. The conflicting character, if there is one, is considered unread and is the first character of the next input field or the first character in subsequent read operations on stdin.

任何一个C库函数手册都可以查到你要的答案的。 自己勤快点，去认真翻吧。

引用 1 楼 garbageam 的回复:你这是devc++的皮肤吗?叫什么plastic code来者的?你还人格分裂了？？？？

引用 4 楼 u013491662 的回复:请问那个[^\n]是正则表达式吗？是的

这东西还真不知道

请问那个[^\n]是正则表达式吗？

这和scanf("%d,%d");当中需要你手动输入逗号才能将输入匹配到第二个%d道理一样的

第二个\n就是读取回车符 当你按下回车符之后,回车符"\n"会和%20[^\n]\n中的第二个\n匹配,如果你需要得到结果,再按一下回车就行.当然,%20[^\n]\n规定的最大字符数是20个,超过这个就会将缓冲区刷新,显示到屏幕上了

你这是devc++的皮肤吗?叫什么plastic code来者的?


Question: 缓冲输入问题

buf分配的是一个栈空间，函数结束的时栈被释放，你需要使用的buf就没有了（一种未定义行为）     缓冲区不应该是局部的             他提供了很多改进策略可以了解

多看msdn，少看书。

c++ primer plus 6

引用 1 楼 user-4 的回复:你知道陷阱与缺陷写在哪一年么？ 这书现在已经几乎没有参考价值了，换本有用点的书啃啃吧。 刚入门，求推荐


Question: 新手上路，C语言结构体中void型指针问题，求高手解答！！

set->elem=elem没错 set->elem[0]=elem还能对吗？ 完全乱套

未确定的类型付给确定类型

set->elem[set->card]=elem;    // 这行报错！为什么？? 首先，elem[set->card]表示的是内容啊！。。表示的是得到elem指针的起始地址偏移set->card后的内容; set->elem[set->card]=elem;红色标记的表示的是一个指针，也就是一个指向一个地址； 不知你是故意这么做的呢？还是什么意思呢？这样写就相当表示你将一个指针的地址保存在另一个指针的地址所指的内容； 这样写一般来说不规范化，出错可能性很大

存void *的时候将其转成int存。

addElem 函数内部需要知道elem的具体类型，然后强转为这种类型。 很多c的接口都是这样的，不过不太安全而已

引用 2 楼 user-6 的回复:set->elem[set->card]=elem; 由于elem是void*指针，不知道它指向什么类型，编译器不知道如何对它指向的东西赋值 由于elem是void*指针，不知道它指向的类型占用内存大小，编译器无法计算第set->card个该类型的具体地址  如果通过判断语句知道了elem会是 char* 或者 int* 之类的指针， 是不是可以先怎样转换来实现功能...高手赐教！

小弟苦逼学生党...限制了必须使用void*...求问下怎样实现void addElem(void *elem, uset *set) 这个函数的功能，即来一个新元素就加在后面

void*类型只有地址信息没有类型信息，所以不能计算偏移，也不能对其指向的地址赋值 楼主可能觉得void*不保存类型信息所以适用于任何类型功能更强大，恰恰相反，void*不保存类型信息所以不能用于操作任何类型，功能更受限制


Question: 字符串反转

引用 2 楼 bbs2241 的回复:[quote=引用 1 楼 Idle_ 的回复:] int main(){     char *string = "abcdefg";  <-- string指向常量字符串， 只读内存， 所以程序必报错  改成char []string = "abcdefg";[/quote]   对头。char *str="abcdefg"; 中 字符串是在字符串字面量池中，不可更改。而 char str[]="abcdefg"，字符串是在栈中，可以更改

可以采用堆栈处理，从栈底打印与栈顶打印就可以了。。

以前还没注意过这个细节，学习了

char *string = "abcdefg";  程序执行这句话的时候，干了两件事情 1、在常量区域把字符串 "abcdefg"写到内存 2、把这个字符串的首地址赋值给string   你在函数里面试图修改常量区域的内存数据，那是违背c语言的设计体系的

引用 2 楼 bbs2241 的回复:[quote=引用 1 楼 Idle_ 的回复:] int main(){     char *string = "abcdefg";  <-- string指向常量字符串， 只读内存， 所以程序必报错  改成char []string = "abcdefg";[/quote]+1

*string++ = *p; string指向常量字符串，不能修改。

引用 1 楼 Idle_ 的回复:int main(){     char *string = "abcdefg";  <-- string指向常量字符串， 只读内存， 所以程序必报错  改成char []string = "abcdefg";


Question: 求大神帮帮忙

引用 3 楼 hsmhyy0615 的回复:那个下载要分的，，，我木有 这方面了解不多，在CSDN里面搜索了一下，发现不少，不知道哪个适合你，右上角，搜索。

那个下载要分的，，，我木有

这里似乎有你要的这个。 http://www.pudn.com/downloads334/sourcecode/app/detail1467126.html


Question: 数组指针

类型都不一样，意义也不同， m是二维数组。

m和*m的值一样，以为都是数组的起始地址。但是它们的类型不一样。 m的类型是char (*)[6]，而*m的类型是char*。因此你写成m应该不能编译通过。它们是两个不同的指针类型，地址相同不能代表就能相互比较。记住变量的地址和变量的类型是两码事

*m+1表示的是地址增加一个char类型长度，m+1表示的是地址增加6个char类型长度

*m等价于m[]!


Question: 简单C语言程序求解释

工作中几乎没见过这么写的，很别扭。

逗号，我一般是从最后一个表达式开始看，不过，还真的很少遇到

引用 14 楼 zhao4zhong1 的回复:计算机组成原理→DOS命令→汇编语言→C语言（不包括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对应的汇编并单步执行观察相应内存和寄存器变化。）  不要迷信书、考题、老师、回帖； 要迷信CPU、编译器、调试器、运行结果。 并请结合“盲人摸太阳”和“驾船出海时一定只带一个指南针。”加以理解。 任何理论、权威、传说、真理、标准、解释、想象、知识……都比不上摆在眼前的事实！  有人说一套做一套，你相信他说的还是相信他做的？ 其实严格来说这个世界上古往今来所有人都是说一套做一套，不是吗？  不要写连自己也预测不了结果的代码！赵老师威武

引用 10 楼 u012421456 的回复:逗号表达式当初虽然学过，但至今没见哪里用过（除了习题、考试题）+1

逗号表达式当初虽然学过，但至今没见哪里用过（除了习题、考试题）

哎~是一本书的习题。。。。我也很无奈

遇到过工程中有人这么写的， 很明显处于一种炫技的心理 ---- 一个奇烂无比的工程

一般会这样写吗？

为什么要用这种迷惑人的写法？ 一行一行写不行吗？ 还是考题？ 这种写法在不同编译器上的运行结果可能是不一样的。

a=3就不用多说了。。。c一开始是等于b，b初始值为20，b最后的值是a*c，所以为60。。。c最终值为a+b+c（第一个c值）=83

不似作弊啦，，，别想多了，我是好人~~~~

引用 1 楼 u012421456 的回复:放编译器例运行一下就知道了 a = 3, b = 60, c = 83  楼主可以去看看逗号表达式方面的知识  楼上有帮人作弊了。。。。。

我也想运行的，纸质考试没软件啊。。。。 c=(a=5,b=a*4) 这里a=5，b=20，c是等于什么？


Question: 求帮忙做一道程序题

补充：数据不大，M，N都小于10


Question: 急求c语言学生成绩管理系统~~~~

刚整理文档的时候删了。。。额。。

引用 楼主 u012923203 的回复:参考下面的数据，用C/C++设计一个简单的学生成绩管理软件，实现基本的功能。学生信息文件（A.TXT）及其内容（示意）：学号                   姓名  性别    班级201200800999    张三   男    电子01    ……课程信息（B.TXT）及其内容（示意）：课程编号课程名称    学分C01    大学英语        4 C02    C语言程序设计  3 ……学生成绩信息文件（C.TXT）及其内容（示意，成绩保存使用浮点数）：学号                    课程  成绩201200800999       C01   89201200800999    C02   68.5……功能要求：（1）       数据录入：通过软件运行界面录入（至少有1个文件可以通过界面录入方式建立）或直接编辑形成上述A.TXT  B.TXT  C.TXT，录入时，需要校验学号、课程是否已经在A、B文件中存在。（2）       显示功能：可分别显示学生、课程和学生成绩。学生成绩显示的时候，应将课程号输出为课程名称（可以自行设计更为详尽、用户友好的输出形式）。（3）       查询功能：输入一个学号时，查询出此生的所有课程情况，格式如下（注意：成绩不及格时实得学分为0）：学号：xxxxxxxxxxx       姓名：xxxxxxx课程号：xxx      课程名称：xxxxx    成绩：xx   实得学分: xx课程号：xxx      课程名称：xxxxx    成绩：xx   实得学分: xx…共修：xx科，实得总学分为：xxx（4）       数据删除、整理功能：当在A.TXT、B.TXT中删除学生或课程信息时，能分析并删除C.TXT相关信息（即删除C.TXT中的无用信息）。（5）       排序功能（选做，加分项）：对指定的科目，能够按照成绩降序或升序排序显示数据。（6）       其他自己在软件编写过程中增加的便于应用的分析、统计功能（加分项，考查自主软件改进能力）性能及其他要求：（7）       具备一定的防错能力，能够识别文件的错误，能够对文件中的数据类型错误做出有针对性的处理。（8）       验收时，自带的数据文件中学生信息条目不得少于六条，课程信息不得少于6条，成绩信息不得少于10条。  谢谢！   我有个图书信息管理系统，你先看看，改改应能用 2、C语言链表实现图书信息管理系统(回头太难[qq:85134211]友情提供) http://vs2003.net/jt.asp?id=4

你看到了吧，这样问，没人会直接回答你的，以前没好好学，现在不会做，个人建议，从网上搜，把搜到的看懂，这样也能多少学点儿知识

自己上课不认真。。。

别浪费青春了

别浪费青春了,退学去搬砖来得实在

大学整天不学期，到期末就来发帖求助。将来你想去干嘛？？？？？？？？？

老兄你来做地方了  你去http://www.taobao.com/ 直接花点钱买啊


Question: 求助MemoryModule.c里pVirtualFree(module->codeBase, 0, MEM_RELEASE);怎么修改

不好意思 图发错了


Question: 江湖告急！Error spawning 'vcspawn.exe'.求教大虾！

楼主大大，最后问题怎么解决的？？可否教一下，这两天我也被这个搞到头疼

引用 46 楼 zhao4zhong1 的回复:FileTool.exe 替换打开和添加到项目中 Visual C++ 的新功能 http://support.microsoft.com/kb/241396/zh-cn 引用 45 楼 zhao4zhong1 的回复:[quote=引用 44 楼 call_from_dream 的回复:] [quote=引用 39 楼 zhao4zhong1 的回复:] 也许是你的.dsp文件坏了。 试试重新建立一个新项目，再将原来的.h、.cpp等手动添加进来……弱弱的问一句，我该怎么添加呀？[/quote] 在左边FileView的项目树的Source Files上点鼠标右键，Add Files to Folder...[/quote]It does not work! But, thank U all the same!

建议楼主沐浴更衣焚香祷告忏悔……

引用 44 楼 call_from_dream 的回复:[quote=引用 39 楼 zhao4zhong1 的回复:] 也许是你的.dsp文件坏了。 试试重新建立一个新项目，再将原来的.h、.cpp等手动添加进来……弱弱的问一句，我该怎么添加呀？[/quote] 在左边FileView的项目树的Source Files上点鼠标右键，Add Files to Folder...

引用 39 楼 zhao4zhong1 的回复:也许是你的.dsp文件坏了。 试试重新建立一个新项目，再将原来的.h、.cpp等手动添加进来……弱弱的问一句，我该怎么添加呀？

引用 41 楼 ForestDB 的回复:不行装个虚拟机？老机子了，装VM后估计非卡死不可。

引用 40 楼 user-4 的回复:珍惜生命，远离VC6.你就让VC6退休吧，换个新点的编译器吧单位的电脑，年代久远，但里面有很多重要数据和配置文件。换VS，硬件条件太差，用起来会很卡。再说，装VS2005或VS2008，他们都是Microsoft的产品，VC6.0卸了重装N次都不行，装VS2005/2008,估计更够呛！

不行装个虚拟机？

珍惜生命，远离VC6.你就让VC6退休吧，换个新点的编译器吧

引用 37 楼 call_from_dream 的回复:[quote=引用 35 楼 zhao4zhong1 的回复:] 无XP兼容就选Windows 2000 “以管理员身份运行”在“常规”选项卡中，如果还没有，你用的不是Win7及以上操作系统，可不去理它。 email已发。用得是XP的系统，没有。其他的试了，问题还是老样子。。唉！[/quote] 试试用命令行方式生成行不行： msdev 项目名称.dsw /MAKE "项目名称 - Win32 Debug" /REBUILD 或 msdev 项目名称.dsw /MAKE "项目名称 - Win32 Release" /REBUILD   Building a Project from the Command Line You can build a Visual C++ project from the command line without first exporting a makefile (MAKEFILE, or filename.mak) and using the NMAKE utility.   The basic command syntax is  msdev FileName [/MAKE "ProjectName – ConfigName | ALL"] [/REBUILD /CLEAN /NORECURSE /OUT LogFile /USEENV]  where FileName is the name of your project (.dsp) or workspace (.dsw) file.   For example, the following syntax deletes all intermediate files and then builds a project called MyProject:  msdev MyProject.dsp /MAKE "MyProject – Win32 Debug" /REBUILD  The following syntax builds a workspace that contains (at least) two projects, building the release configuration of MyProject1 and all configurations of MyProject2, and directing the build output to a file called MyWorkspace.log:  msdev MyWorkspace.dsw /MAKE "MyProject1 – Win32 Release" "MyProject2 – ALL" /OUT MyWorkspace.log  Note   Projects created in Visual C++ versions earlier than 5.0 must first be converted before you can build them from the command line. To convert a project, open it inside the development environment.  You can also build all configurations of a certain type within a single project, for example, if you have defined multiple types of Debug configurations. For more information, see "Building by Type of Configuration."  Tip   Type msdev /? /OUT FileName to pipe the command syntax to a file.   The /MAKE Option The /REBUILD, /CLEAN and /NORECURSE options all modify the /MAKE option, and are meaningless without it. Also, unless you specify a FileName after msdev, any /MAKE options will be ignored. /MAKE requires at least one configuration.  Parameters Parameter Description  FileName A valid workspace or project filename. Must have an extension of .dsp or .dsw.  ProjectName The project that contains the configurations you want to build. If Filename is a workspace file, ProjectName must be a part of that workspace.  ConfigName Any valid project configuration, or all configurations for a particular project. To build all configurations, simply type "ALL" for the configuration value (must be uppercase). Corresponds to the choices available from the Settings For drop-down list in the Project Settings dialog box.   LogFile Name of an optional file used to store the build output information (valid only with the /OUT option).     Options Option Operation  /MAKE "projectname1 – configuration1 | projectname1 – configuration2 | projectname2 – configuration1 | ALL" Builds the specified configurations. The /CLEAN option modifies /MAKE so that the specified configurations are cleaned rather than built.   /? Displays usage information for the msdev command.  /CLEAN Deletes intermediate files created during the build process for the specified configuration(s); does not build the project configuration(s).   /REBUILD Cleans and builds the specified configuration(s), including all dependent projects. Takes precedence if both /CLEAN and /REBUILD are specified.  /NORECURSE Builds the specified project configuration(s) without building any dependent projects.  /OUT logfile Creates a log file for the build output, which includes such information as syntax errors and warnings. If you don't specify a filename, the build output information is displayed at the command prompt and is not saved to a file.   /USEENV Directs the build system to use environment variables for the current build session, rather than the directory settings specified on the Directories tab (Tools menu, Options command). The PATH, INCLUDE and LIB paths must be set correctly for the build to succeed when /USEENV is specified.  /EX MacroName Invokes the named macro (if the associated .dsm file is not loaded, this command will fail).    Tip   Type msdev /USEENV at the command line to launch Visual C++ and use the environment variables for the duration of that IDE session.  Building by Type of Configuration For any single project, you can build all configurations of a certain type. The build system uses limited pattern matching to recognize the name of the configuration you specify.   For example, if your project contains Debug and Release configurations for both regular and UNICODE applications, you can build both configurations for only the UNICODE application by issuing the following command:  msdev MyProject.dsp /MAKE "MyProject – UNICODE"   Or, if your project contains several types of Debug and Release configurations, you can build all of the Debug configurations:  msdev MyProject.dsp /MAKE "MyProject – DEBUG"   This pattern matching gives you even more flexibility when customizing your batch builds.

引用 35 楼 zhao4zhong1 的回复:无XP兼容就选Windows 2000 “以管理员身份运行”在“常规”选项卡中，如果还没有，你用的不是Win7及以上操作系统，可不去理它。 email已发。用得是XP的系统，没有。其他的试了，问题还是老样子。。唉！

曾经有一套好用的编译链接调试环境，我没有珍惜，直到失去她时，我才追悔莫及，如果……一万年！

引用 32 楼 zhao4zhong1 的回复:要不要我email给你发一个我这边的C:\Program Files\Microsoft Visual Studio\Common\MSDev98\Bin\VCSPAWN.EXE试试？bef2010@qq.com  发过来试试吧。谢谢了！  开始、程序、Microsoft Visual Studio 6.0、Microsoft Visual C++ 6.0上点鼠标右键，属性：  快捷方式：  目标："C:\Program Files\Microsoft Visual Studio\Common\MSDev98\Bin\MSDEV.EXE"  起始位置："C:\Program Files\Microsoft Visual Studio\Common\MSDev98\Bin"  兼容性：无XP兼容模式   以管理员身份运行这个程序  也不知道怎么运，有种老天爷存心玩我的感觉！

开始、程序、Microsoft Visual Studio 6.0、Microsoft Visual C++ 6.0上点鼠标右键，属性：  快捷方式：  目标："C:\Program Files\Microsoft Visual Studio\Common\MSDev98\Bin\MSDEV.EXE"  起始位置："C:\Program Files\Microsoft Visual Studio\Common\MSDev98\Bin"  兼容性：  以XP兼容模式运行这个程序  以管理员身份运行这个程序  确定。  试试看？

引用 30 楼 zhao4zhong1 的回复:还可以试试对 C:\Program Files\Microsoft Visual Studio\Common\MSDev98\Bin\VCSPAWN.EXE 使用depends.exe查看其依赖的dll，我这里是 C:\Program Files\Microsoft Visual Studio\Common\MSDev98\Bin>depends.exe /v /t /p VCSPAWN.EXE ntdll.dll     11/23/2011 00:28:30  (C:\WINDOWS\system32\ntdll.dll)   CompanyName Microsoft Corporation   FileDescription NT Layer DLL   FileVersion 5.2.3790.4937 (srv03_sp2_gdr.111121-0236)   InternalName ntdll.dll   LegalCopyright (C) Microsoft Corporation. All rights reserved.   OriginalFilename ntdll.dll   ProductName Microsoft(R) Windows(R) Operating System   ProductVersion 5.2.3790.4937 KERNEL32.dll  10/03/2012 15:26:24  (C:\WINDOWS\system32\KERNEL32.dll)   CompanyName Microsoft Corporation   FileDescription Windows NT BASE API Client DLL   FileVersion 5.2.3790.5069 (srv03_sp2_gdr.120928-0333)   InternalName kernel32   LegalCopyright (C) Microsoft Corporation. All rights reserved.   OriginalFilename kernel32   ProductName Microsoft(R) Windows(R) Operating System   ProductVersion 5.2.3790.5069 MSVCRT.dll    03/07/2007 20:00:00  (C:\WINDOWS\system32\MSVCRT.dll) VCSPAWN.EXE   06/17/1998 00:00:00  (VCSPAWN.EXE)如果死能解决问题，我想，我早就做了。赵老师，谢谢你了！虽然问题没有解决，不过你的热心已经让我感动+激动很久了！再过一天，如果还没好的方法，我就结贴了。


Question: acm hdu  1325 RE 非常不解

大神收了我吧~好不好，刚把结束条件改了，速度AC,   谢谢了~~~~~

看看discuss，首先把结束条件修改一下再说。


Question: 字符串搜索问题

对待查找的字符串设置一个哈希函数     每次检索被查找函数  如果等于存在标志就返回  不等于就继续查找 int  hash[128] = {0}; while (*chars) {           hash[*chars] = 1;           chars++; } while (*source) {          if (hash[*source])          {                  return source;          }          source++; } return NULL;

仅供参考#include <stdio.h> #include <string.h> char string[80]; char seps1[3]; char seps2[3]; char *token; char *zzstrtok (     char *string,     const char *control1,//连续出现时视为中间夹空token     const char *control2 //连续出现时视为中间无空token     ) {     unsigned char *str;     const unsigned char *ctrl1 = control1;     const unsigned char *ctrl2 = control2;     unsigned char map1[32],map2[32];     static char *nextoken;     static char flag=0;     unsigned char c;     int L;      memset(map1,0,32);     memset(map2,0,32);     do {         map1[*ctrl1 >> 3] |= (1 << (*ctrl1 & 7));     } while (*ctrl1++);     do {         map2[*ctrl2 >> 3] |= (1 << (*ctrl2 & 7));     } while (*ctrl2++);      if (string) {         if (control2[0]) {             L=strlen(string);             while (1) {                 c=string[L-1];                 if (map2[c >> 3] & (1 << (c & 7))) {                     L--;                     string[L]=0;                 } else break;             }         }         if (control1[0]) {             L=strlen(string);             c=string[L-1];             if (map1[c >> 3] & (1 << (c & 7))) {                 string[L]=control1[0];                 string[L+1]=0;             }         }         str=string;     }     else        str=nextoken;      string=str;     while (1) {         if (0==flag) {             if (!*str) break;             if (map1[*str >> 3] & (1 << (*str & 7))) {                 *str=0;                 str++;                 break;             } else if (map2[*str >> 3] & (1 << (*str & 7))) {                 string++;                 str++;             } else {                 flag=1;                 str++;             }         } else if (1==flag) {             if (!*str) break;             if (map1[*str >> 3] & (1 << (*str & 7))) {                 *str=0;                 str++;                 flag=0;                 break;             } else if (map2[*str >> 3] & (1 << (*str & 7))) {                 *str=0;                 str++;                 flag=2;                 break;             } else str++;         } else {//2==flag             if (!*str) return NULL;             if (map1[*str >> 3] & (1 << (*str & 7))) {                 str++;                 string=str;                 flag=0;             } else if (map2[*str >> 3] & (1 << (*str & 7))) {                 str++;                 string=str;             } else {                 string=str;                 str++;                 flag=1;             }         }     }     nextoken=str;      if (string==str) return NULL;     else             return string; } void main() {    strcpy(string,"A \tstring\t\tof ,,tokens\n\nand some  more tokens, ");    strcpy(seps1,",\n");strcpy(seps2," \t");    printf("\n[%s]\nTokens:\n",string);    token=zzstrtok(string,seps1,seps2);    while (token!=NULL) {       printf(" <%s>",token);       token=zzstrtok(NULL,seps1,seps2);    }     strcpy(string,"1234| LIYI|China | 010 |201110260000|OK");    strcpy(seps1,"|");strcpy(seps2," ");    printf("\n[%s]\nTokens:\n",string);    token=zzstrtok(string,seps1,seps2);    while (token!=NULL) {       printf(" <%s>",token);       token=zzstrtok(NULL,seps1,seps2);    }     strcpy(string,"1234|LIYI||010|201110260000|OK");    strcpy(seps1,"");strcpy(seps2,"|");    printf("\n[%s]\nTokens:\n",string);    token=zzstrtok(string,seps1,seps2);    while (token!=NULL) {       printf(" <%s>",token);       token=zzstrtok(NULL,seps1,seps2);    }     strcpy(string,"1234|LIYI||010|201110260000|OK");    strcpy(seps1,"|");strcpy(seps2,"");    printf("\n[%s]\nTokens:\n",string);    token=zzstrtok(string,seps1,seps2);    while (token!=NULL) {       printf(" <%s>",token);       token=zzstrtok(NULL,seps1,seps2);    }     strcpy(string,"a");    strcpy(seps1,",");strcpy(seps2,"");    printf("\n[%s]\nTokens:\n",string);    token=zzstrtok(string,seps1,seps2);    while (token!=NULL) {       printf(" <%s>",token);       token=zzstrtok(NULL,seps1,seps2);    }     strcpy(string,"a,b");    strcpy(seps1,",");strcpy(seps2,"");    printf("\n[%s]\nTokens:\n",string);    token=zzstrtok(string,seps1,seps2);    while (token!=NULL) {       printf(" <%s>",token);       token=zzstrtok(NULL,seps1,seps2);    }     strcpy(string,"a,,b");    strcpy(seps1,",");strcpy(seps2,"");    printf("\n[%s]\nTokens:\n",string);    token=zzstrtok(string,seps1,seps2);    while (token!=NULL) {       printf(" <%s>",token);       token=zzstrtok(NULL,seps1,seps2);    }     strcpy(string,",a");    strcpy(seps1,",");strcpy(seps2,"");    printf("\n[%s]\nTokens:\n",string);    token=zzstrtok(string,seps1,seps2);    while (token!=NULL) {       printf(" <%s>",token);       token=zzstrtok(NULL,seps1,seps2);    }     strcpy(string,"a,");    strcpy(seps1,",");strcpy(seps2,"");    printf("\n[%s]\nTokens:\n",string);    token=zzstrtok(string,seps1,seps2);    while (token!=NULL) {       printf(" <%s>",token);       token=zzstrtok(NULL,seps1,seps2);    }     strcpy(string,",a,,b");    strcpy(seps1,",");strcpy(seps2,"");    printf("\n[%s]\nTokens:\n",string);    token=zzstrtok(string,seps1,seps2);    while (token!=NULL) {       printf(" <%s>",token);       token=zzstrtok(NULL,seps1,seps2);    }     strcpy(string,",,a,,b,,");    strcpy(seps1,",");strcpy(seps2,"");    printf("\n[%s]\nTokens:\n",string);    token=zzstrtok(string,seps1,seps2);    while (token!=NULL) {       printf(" <%s>",token);       token=zzstrtok(NULL,seps1,seps2);    }     strcpy(string,",");    strcpy(seps1,",");strcpy(seps2,"");    printf("\n[%s]\nTokens:\n",string);    token=zzstrtok(string,seps1,seps2);    while (token!=NULL) {       printf(" <%s>",token);       token=zzstrtok(NULL,seps1,seps2);    }     strcpy(string,",,");    strcpy(seps1,",");strcpy(seps2,"");    printf("\n[%s]\nTokens:\n",string);    token=zzstrtok(string,seps1,seps2);    while (token!=NULL) {       printf(" <%s>",token);       token=zzstrtok(NULL,seps1,seps2);    }     strcpy(string,",,,");    strcpy(seps1,",");strcpy(seps2," ");    printf("\n[%s]\nTokens:\n",string);    token=zzstrtok(string,seps1,seps2);    while (token!=NULL) {       printf(" <%s>",token);       token=zzstrtok(NULL,seps1,seps2);    } } // //[A      string          of ,,tokens // //and some  more tokens,] //Tokens: // <A>, <string>, <of>, <>, <tokens>, <>, <and>, <some>, <more>, <tokens>, <>, //[1234| LIYI|China | 010 |201110260000|OK] //Tokens: // <1234>, <LIYI>, <China>, <010>, <201110260000>, <OK>, //[1234|LIYI||010|201110260000|OK] //Tokens: // <1234>, <LIYI>, <010>, <201110260000>, <OK>, //[1234|LIYI||010|201110260000|OK] //Tokens: // <1234>, <LIYI>, <>, <010>, <201110260000>, <OK>, //[a] //Tokens: // <a>, //[a,b] //Tokens: // <a>, <b>, //[a,,b] //Tokens: // <a>, <>, <b>, //[,a] //Tokens: // <>, <a>, //[a,] //Tokens: // <a>, <>, //[,a,,b] //Tokens: // <>, <a>, <>, <b>, //[,,a,,b,,] //Tokens: // <>, <>, <a>, <>, <b>, <>, <>, //[,] //Tokens: // <>, <>, //[,,] //Tokens: // <>, <>, <>, //[,,,] //Tokens: // <>, <>, <>, <>,

%s 格式符打印字符串，就不要是*p了，直接p就可以

只是printf那多了一个* #include <stdio.h> char *find_char(char  *source,char  *chars){     char *cp;       if (source != NULL && chars !=NULL)     {         for (;*source != '\0';source++)         {             for ( cp = chars; *cp != '\0';cp++ )             {                 if (*cp == *source)                 {                     return source;                 }             }         }     }     return NULL;         } int main(){           char  *source = "abcdef";      char  *chars = "xrcqef";     char  *p= find_char(source,chars);     if (p!=NULL)     {         printf("%s\n",p);     }     return 0; }

单步调试，看看是执行到哪一行挂掉的，然后再分析为什么会在这挂掉。

引用 楼主 laopufua 的回复: 程序直接挂掉，不知为何？ F9设置断点，F5单步调试。先跟踪调试完成再问。

- -  汗 ，楼主我看你说的我还以为问题在find_char里面，找了老半天，各种调试找不到原因、、、后来才发现、 printf("%s\n",*p); 你这句什么意思？？？？将一个字符变量以字符串类型输出。。。 printf("%c\n",*p);


Question: 请教如下code的bug

int pt[2000][2000]; 默认的栈大小是1M吧，所以溢出了。

第一，不要随便省略代码，因为你自己不知道错误在哪里所以才向别人求助，如果你求助的时候还按照自己的错误想法省略信息，那谁也帮不了你 第二，进入函数时所有局部变量一起入栈

我找到错误了，但是不知道错误的原因： 错误如下： 在Detec函数中，我在靠后面的地方，定义了一个很大的数组，导致stack overflow。我将这个数组改为： int **pt = (int **)malloc(2000*2000*sizeof(int)); 后，就没有溢出了，但是出了其他的问题（这是后话，这里不讨论）。  我现在的疑问是：我定义的这个二维数组，还没有执行到，也谈不上入栈，怎么会导致栈溢出呢？？   void Detect( IplImage * img ) {     int a,b,c;     a=1;b=2;     c=a+b;    int pt[2000][2000]; }

这段code的bug实在太奇怪了： 按F11，进入Detect函数，然后，按一下F10，就提示stack overflow。好像我什么都没做，就提示栈溢出了。

不好意思，code的大意是这样的。因为整个code比较复杂，我就贴了最主要的一段，所以忘记了一些东西，现在改正如下：   void Detect( IplImage * img ) {     int a,b,c;     a=1;b=2;     c=a+b; }  main() {     IplImage* img = cvLoadImage("E:\\TestPic\\facedec\\face_001.jpg");     cvNamedWindow("source",CV_WINDOW_AUTOSIZE);     cvShowImage("source",img);     cvWaitKey(0);     IplImage* gimg=cvCreateImage(cvGetSize(img), IPL_DEPTH_8U, 1);     cvCvtColor(img,gimg,CV_BGR2GRAY);     cvReleaseImage( &img );     Detect( gimg );   }

你这个代码不完整吧  Detect() { } 这个是个函数么？ 没有返回值？ 没有参数？ 是Detect( gimg );使用的函数么？


Question: 求教2个有序链表合并的时间空间复杂度。

链表1：一千个，100~1100 链表2：一百个，1~99，  最后一个是1101

嗯 不对 ，最坏情况是 m+n  例子应该是  链表1：一千个，100~1000 链表2：一百个，1~99，  最后一个是1001  if (a <= b) 执行99次， if (a > b)执行1000次， if (a <= b) 执行1次

两个有序链表合并，应该是两个链表同时从头开始遍历，谁先遍历完，另一个还没有遍历完的链表是直接接在最后  所以时间复杂度应该是：最好情况下，时间复杂度是(m、n中的最小值)，最坏情况下，时间复杂度是(m、n中的最大值)  a = 链表1[0] b = 链表2[0] while (a != NULL && b != NULL) {     if (a > b) b插入a前; b后移一位;     if (a <= b) b插入a后; b后移一位;a后移一位; } if(a != NULL)     不需要处理 if(b != NULL)     b插入a最后，此处b剩余的不需要再遍历  以 引用 2 楼 brookmill 的回复:刚才那个例子不妥，换一个： 链表1：一千个，1~999，最后一个是10000 链表2：一百个，1~99，  最后一个是10001 为例  if (a <= b) 执行99次， if (a > b)执行900次， if (a <= b) 执行1次

引用 6 楼 brookmill 的回复:空间复杂度是O(1)，这个应该没问题。 引用 5 楼 brookmill 的回复:[quote=引用 3 楼 bx__8840668 的回复:] [quote=引用 1 楼 brookmill 的回复:] 最坏情况是O(m+n) 举例：链表1有10000个元素，链表2有10个，但是链表2的10个数据比链表1的都大，那就得把链表1的10000个全都过一遍  你的例子的复杂度应该是O(n)或者O(m)吧，只要把链表1的10000个遍历一遍就可以了啊，不需要O(m+n)啊[/quote] 1楼的例子还不是最坏情况，见2楼[/quote]  这个例子有点明白了，谢谢了啊

空间复杂度是O(1)，这个应该没问题。

引用 3 楼 bx__8840668 的回复:[quote=引用 1 楼 brookmill 的回复:] 最坏情况是O(m+n) 举例：链表1有10000个元素，链表2有10个，但是链表2的10个数据比链表1的都大，那就得把链表1的10000个全都过一遍  你的例子的复杂度应该是O(n)或者O(m)吧，只要把链表1的10000个遍历一遍就可以了啊，不需要O(m+n)啊[/quote] 1楼的例子还不是最坏情况，见2楼

最好的情况是O(m、n中的最小值) 最坏的情况是O(m+n)

引用 1 楼 brookmill 的回复:最坏情况是O(m+n) 举例：链表1有10000个元素，链表2有10个，但是链表2的10个数据比链表1的都大，那就得把链表1的10000个全都过一遍  你的例子的复杂度应该是O(n)或者O(m)吧，只要把链表1的10000个遍历一遍就可以了啊，不需要O(m+n)啊