Question: C语言怎么取出一张256色位的bmp图像的某个像素的颜色

怎么实现图片的平移啊

////////////////////////////////////////////////////////////////////////// // Bitmap 文件(压缩)格式 typedef enum tag_bmp_encode { 	bmp_encode_none = 0, // 未压缩 	bmp_encode_rle8, // rle8压缩 	bmp_encode_rle4, // rle4压缩 	bmp_encode_mask, // 由掩码(color_mask_abgr_t)决定  	// os2 压缩方式 	bmp_encode_os2_index4, // OS/2 的 4 位编码 	bmp_encode_os2_index8, // OS/2 的 8 位编码 	bmp_encode_os2_24, // OS/2 的 24 位编码 }bmp_encode_e;  #pragma pack(push, 1) ////////////////////////////////////////////////////////////////////////// // 简单的 Bitmap 文件头，用于识别 Bitmap 文件类型。 struct bmp_simple_header_t { 	uint_16 type; 	uint_32 file_size; 	uint_32 reserved; 	uint_32 data_offset; 	uint_32 info_size; };  ////////////////////////////////////////////////////////////////////////// // Windows Bitmap 文件头 struct bmp_info_windows_t { 	uint_32 size; 	int_32 width; 	int_32 height; 	uint_16 plane_count; 	uint_16 bit_count; 	bmp_encode_e encode; 	uint_32 image_size; 	int_32 ppm_x; // pels per meter 	int_32 ppm_y; 	uint_32 color_used; 	uint_32 color_important; };  struct bmp_header_windows_t { 	uint_16 type; 	uint_32 file_size; 	uint_32 reserved; 	uint_32  data_offset; };  bmp_simple_header_t + bmp_header_windows_t + bmp_info_windows_t 这是标准的 windows bitmap 的文件头结构。  下面是确认出 bitmap 文件的格式，  	const uint_16 BMP_HEADER_ID = 0x4D42; // 'BM',header.type 	bmp_simple_header_t * header = (bmp_simple_header_t *)buffer; 	if(header->type != BMP_HEADER_ID) 		return 1;  	int_x width = 0; 	int_x height = 0; 	color_mode_e src_mode = color_mode_invalid; 	byte_t * conv_palette = nullptr; 	byte_t * conv_buffer = nullptr; 	int_x flags = 0; 	bmp_header_windows_t * header = (bmp_header_windows_t *)buffer; 	buffer += sizeof(bmp_header_windows_t); 	if(header->type != BMP_HEADER_ID) 		return false;  	bmp_info_windows_t * info = (bmp_info_windows_t *)buffer; 	buffer += sizeof(bmp_info_windows_t);  	if(info->size != sizeof(bmp_info_windows_t) && info->size != sizeof(bmp_info_windows_t)+sizeof(color_mask_abgr_t)) 		return false;  	width = (int_x)info->width; 	height = (int_x)info->height; 	// 翻转行序 	if(height < 0) 		height = -height; 	else 		flags |= IMAGE_CONVERT_FLIP_Y;  	// 调色板、颜色掩码等额外信息 	int_x extern_size = header->data_offset - sizeof(bmp_info_windows_t)-sizeof(bmp_header_windows_t);  	conv_palette = nullptr; 	conv_buffer = buffer; 	// 颜色掩码确定颜色类型 	if(info->encode == bmp_encode_mask) 	{ 		IMAGE_ASSERT(extern_size == sizeof(color_mask_abgr_t)); 		color_mask_abgr_t * mask = (color_mask_abgr_t *)buffer; 		src_mode = color_mode_from_mask_abgr(mask, info->bit_count); 		conv_buffer = buffer + extern_size; 		conv_palette = nullptr; 	} 	// rle8 编码 	else if(info->encode == bmp_encode_rle8) 	{ 		src_mode = color_mode_index8_rle2_x8r8g8b8; 		conv_buffer = buffer + extern_size; 		conv_palette = buffer; 	} 	// rle4 编码 	else if(info->encode == bmp_encode_rle4) 	{ 		src_mode = color_mode_index4_rle2_x8r8g8b8; 		conv_buffer = buffer + extern_size; 		conv_palette = buffer; 	} 	// 有调色板 	else if(extern_size) 	{ 		src_mode = color_mode_invalid; 		switch(info->bit_count) 		{ 		case 1: 			src_mode = color_mode_index1_x8r8g8b8; 			break; 		case 2: 			src_mode = color_mode_index2_x8r8g8b8; 			break; 		case 4: 			src_mode = color_mode_index4_x8r8g8b8; 			break; 		case 8: 			src_mode = color_mode_index8_x8r8g8b8; 			break; 		default: 			break; 		} 		conv_buffer = buffer + extern_size; 		conv_palette = buffer; 	} 	else // 没有调色板 	{ 		src_mode = color_mode_invalid; 		switch(info->bit_count) 		{ 		case 2: 			src_mode = color_mode_gray2; 			break; 		case 4: 			src_mode = color_mode_gray4; 			break; 		case 8: 			src_mode = color_mode_gray8; 			break; 		case 16: 			src_mode = color_mode_x1r5g5b5; 			break; 		case 24: 			src_mode = color_mode_r8g8b8; 			break; 		case 32: 			src_mode = color_mode_a8r8g8b8; 			break; 		default: 			break; 		} 		conv_buffer = buffer; 		conv_palette = nullptr; 		}  其中，  		case 8: 			src_mode = color_mode_index8_x8r8g8b8; 			break;  应该就是楼主的 8-bit 格式了，当然了读取就比较简单了 conv_palette 指向的是调色板， conv_buffer 指向的是索引数据。 而将索引数据映射到调色板里就不用我说了吧，楼主自己会做了。 需要注意的是，调色板里的颜色格式是 x8r8g8b8。 跨度 pitch = align_to_4(width)，需要 4 字节对齐。

我参考了很多资料，想了三四天了，还是写不出来，各位大神能否帮忙写一点代码

这个很多教材都有示例嘛

恩，我知道了，谢谢！

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

我这样写的代码，实现的效果有一点错误，但是我看不出到底是哪里不对，求大神帮忙看看 #include <stdio.h> #include <stdlib.h> #include <windows.h> int main() { 	BITMAPFILEHEADER fileHeader; 	BITMAPINFOHEADER infoHeader; 	FILE *pfin = fopen("F:\\1.bmp","rb"); 	FILE *pfout = fopen("F:\\2.bmp","wb"); 	fread(&fileHeader,sizeof(BITMAPFILEHEADER),1,pfin); 	fread(&infoHeader,sizeof(BITMAPINFOHEADER),1,pfin); 	int bfsize = fileHeader.bfSize;//图片的大小  	int size = infoHeader.biWidth*infoHeader.biHeight; 	int shuju = fileHeader.bfOffBits;//位图数据区的起始字节  	int height = infoHeader.biHeight; 	int width = infoHeader.biWidth; 	int i,j; 	unsigned char *color[256][4]; 	fseek(pfin,54L,SEEK_SET); 	fread(color,sizeof(unsigned char *),256,pfin); 	unsigned char *img[512][512]; 	fseek(pfin,shuju,SEEK_SET); 	int left = 0, right = 0, up = 0, down = 0; 	fread(img,1,bfsize-shuju,pfin); 	printf("w:up\n"); 	printf("s:down\n"); 	printf("a:left\n"); 	printf("d:right\n"); 	printf("请输入：\n"); 	char f; 	scanf("%c",&f); 	if(f=='w') 	{ 		printf("请输入向上移动多少？\n"); 		scanf("%d",&up); 	} 	if(f=='s') 	{ 		printf("请输入向下移动多少？\n"); 		scanf("%d",&down); 	} 	if(f=='a') 	{ 		printf("请输入向左移动多少？\n"); 		scanf("%d",&left); 	} 	if(f=='d') 	{ 		printf("请输入向右移动多少？\n"); 		scanf("%d",&right); 	} 	if(infoHeader.biBitCount == 8) 	{ 		for(i=511;i>0+up;i--)//上  		{ 			for(j=0;j<512;j++) 			{ 				img[i][j]=img[i-up][j]; 			} 		}  		for(i=0;i<512-down;i++)//下  		{ 			for(j=0;j<512;j++) 			{ 				//*img[i][j]>>512; 				img[i][j]=img[i+down][j]; 			} 		} 		for(i=0;i<512;i++)//左  		{ 			for(j=0;j<512-left;j++) 			{ 				img[i][j]=img[i][j+left]; 				 			} 		} 		for(i=0;i<512;i++)//右  		{ 			for(j=511;j>0+right;j--) 			{ 				img[i][j]=img[i][j-right]; 			} 		} 	} 	 	fwrite(&fileHeader,sizeof(fileHeader),1,pfout); 	fwrite(&infoHeader,sizeof(infoHeader),1,pfout); 	fwrite(color,sizeof(unsigned char *),256,pfout); 	fwrite(img,sizeof(unsigned char *),(bfsize-shuju)/4,pfout); 	 }

8位读文件需跳过调色板，紧接就是索引值，生成8位前面部父基本一致，只需改宽高大小

比如表示某个像素的值为0x12,找调色板中从0x00到0xff的第0x12项对应的RGB值。

我该怎么获取像素的颜色值？ #include <stdio.h> #include <windows.h> int main() { 	BITMAPFILEHEADER fileHeader; 	BITMAPINFOHEADER infoHeader; 	FILE *pfin = fopen("F:\\1.bmp","rb"); 	FILE *pfout = fopen("F:\\2.bmp","wb"); 	fread(&fileHeader,sizeof(BITMAPFILEHEADER),1,pfin); 	fread(&infoHeader,sizeof(BITMAPINFOHEADER),1,pfin); 	int size = infoHeader.biWidth*infoHeader.biHeight; 	int i,n; 	RGBQUAD RGB; 	unsigned char *img[512][512]; 	fread(img,sizeof(unsigned char *),size,pfin);  	if(infoHeader.biBitCount == 8) 	{ 		for(n=0;n<256;n++) 		{ 			 		} 	} 	fwrite(&fileHeader,sizeof(fileHeader),1,pfout); 	fwrite(&infoHeader,sizeof(infoHeader),1,pfout); 	fwrite(img,sizeof(unsigned char*),size,pfout); }

格式化读取文件就能完成

bmp每行像素数据的字节数必须是4的倍数。不够需要补1或2或3个字节。 256索引色的每个像素是用一个字节表示的（用0～255表示其颜色索引）。


Question: 福利：C语言面试必读书籍 pdf赠送

大爱楼主～～

分   书

分也要，书也要

很多书我都有，我只是想接分，行吗？

求共享啊

这些相比都不重要，最重要的一个你却拉掉了，那就是《K&R》

到网上找pdf版去。。。

C和指针 资源不存在啊  楼主给个分享链接吧

谢谢楼主的分享！！ 我想看《C++ primer》第五版中文版

还有Linux、嵌入式、网络、等等pdf书籍，需要的请在我的博客 http://blog.csdn.net/windeal3203/article/details/39205611 http://blog.csdn.net/windeal3203  留下书名和邮箱


Question: 两个线程的问题，我不知道结果为什么是这样的。。。。。。

你的i又没有加锁，可能存在这样的情况： i++可以分为这三个步骤 1.将i加载到寄存器 2. i+1写到寄存器 3. 写回内存  线程1线程2同时加载i到内存，再写回内存，都是一样的对吧，所以不加锁操作同一个数据肯定有问题

Synchronization Functions The following functions are used in synchronization.        CancelWaitableTimer   CreateEvent   CreateMutex   CreateSemaphore   CreateWaitableTimer   DeleteCriticalSection   EnterCriticalSection   GetOverlappedResult   InitializeCriticalSection   InitializeCriticalSectionAndSpinCount   InterlockedCompareExchange   InterlockedDecrement   InterlockedExchange   InterlockedExchangeAdd   InterlockedIncrement   LeaveCriticalSection   MsgWaitForMultipleObjects   MsgWaitForMultipleObjectsEx   OpenEvent   OpenMutex   OpenSemaphore   OpenWaitableTimer   PulseEvent   QueueUserAPC   ReleaseMutex   ReleaseSemaphore   ResetEvent   SetCriticalSectionSpinCount   SetEvent   SetWaitableTimer   SignalObjectAndWait   TimerAPCProc   TryEnterCriticalSection   WaitForMultipleObjects   WaitForMultipleObjectsEx   WaitForSingleObject   WaitForSingleObjectEx


Question: 如何用十字链表进行稀疏矩阵的求逆运算呢?

仅供参考： 十字链表交换任意两个节点C源代码（C指针应用终极挑战）http://download.csdn.net/detail/zhao4zhong1/5532495


Question: 一个链表程序

仅供参考//带表头结点的单向链表 #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-> //

printf("指针地址:%p\n",crrent->next);  // 即使这里输出的crrent->next是正确的值，         crrent = crrent->next; // 也不能保证这里的crrent->next仍然是正确的。 crrent被free之后，它指向的内存有可能被别人申请了之后覆盖。如果这个覆盖刚好发生在上述两行之间，crrent->next就可能有变化。

free(crrent);         printf("***%d***\n",__LINE__);         printf("指针地址:%p\n",crrent->next);         crrent = crrent->next; crrent先被free了，之后不应该再使用crrent->next 正确做法：         tmp = crrent->next;         free(crrent);         crrent = tmp;


Question: Linux下fork()函数使用

引用 15 楼 zhao4zhong1 的回复:[quote=引用 11 楼 Falleyes 的回复:] [quote=引用 9 楼 zhao4zhong1 的回复:] 保大人还是保孩子！ 孩子还可以再生嘛~~~ [/quote] 有时候大人死后生下了孩子， 有时候大人生下了孩子后大人死了，孩子活了， 有时候大人生下了孩子后孩子死了，大人没事， 有时候胎死腹中， …… 残酷的现实啊！ [/quote] 是有多无聊

引用 11 楼 Falleyes 的回复:[quote=引用 9 楼 zhao4zhong1 的回复:] 保大人还是保孩子！ 孩子还可以再生嘛~~~ [/quote] 有时候大人死后生下了孩子， 有时候大人生下了孩子后大人死了，孩子活了， 有时候大人生下了孩子后孩子死了，大人没事， 有时候胎死腹中， …… 残酷的现实啊！

哎呀，这两天都忙得忘结贴了。 这个帖子描述的问题已经解决，因为这个顺序发生变化的概率太小了，我试了很久很久很久才出现一次。。。

保大人还是保孩子！

引用 9 楼 zhao4zhong1 的回复:保大人还是保孩子！ 孩子还可以再生嘛~~~

引用 8 楼 pengzhixi 的回复:先说结论吧：不应对fork之后，父进程还是子进程哪个先调用做任何假设，如果要保证按照特定顺序执行得做同步。 实际上子进程或者父进程先调用都有各自的理由。 子进程先调用的理由是：当fork之后，如果父进程先调用，那么根据写时拷贝的策略，父进程必须对即将修改的数据或者栈所在的内存页进行复制，这样才不至于影响到子进程，但是很多时候我们子进程可能在fork之后就调用exec函数执行新的程序，这就意味着父进程复制的那些内存页完全没必要，所以从这里来看子进程应该先调用，可以避免不必要的内存拷贝。 父进程先调用的理由：fork之后父进程正好占用cpu，那么很多父进程的很多数据可能处于cpu缓存以及寄存器当中，继续执行父进程就不需要切换进程，这样可以提高效率。 内核版本的历史上都根据这些权衡有时候让子进程先执行，有时候让父进程执行。所以结论就是开头的。这些理论也可以用于两个子进程？也就是说，因为某些类似的原因，会让同一父进程下的一个子进程总是优于另一个子进程先执行？

引用 2 楼 luciferisnotsatan 的回复:看着没什么，你试个10万次的话，应该就会看到不一样了 10w次，这么大规模 引用 6 楼 luciferisnotsatan 的回复:这和操作系统的调度算法实现有关。而且lz的程序太简单，结果可能就导致输出都是一个顺序的了。 那应该怎么写，有没有示例代码给个

fork并不保证父子进程的运行顺序。fork只是让内核创建一个进程，创建完就返回了，进程怎么调度运行就跟内核的调度算法有关。 如果要保证运行顺序，可以试试vfork。

总要有个先后， 想控制 用sleep

看着没什么，你试个10万次的话，应该就会看到不一样了

如果将pid1和pid2的赋值顺序调换，则出现和刚才相反的结果，son一直先于daughter。


Question: 难倒了众多牛人的题目，让我这个大一学生如何是好，求帮忙，感激不尽！！

动态规划（DP），一楼说的对，你百度搜"最长递增子序列"。

一：先从第一个数开始跟后面的所有的数比较，计算第一个数符合条件的人数，并保存需要剔除的数据        然后以剔除的数据作为新的数组计算第一个开始跟后面的所有的数比较，计算第一个数符合条件的人数，并保存需要剔除的数据到新的数组中         继续上面的流程直到没有数据或只有一个数据 二：从一计算的人数值选择最大的一个就是M，然后需要剔除的数据就是第二排开始计算的数组数据，可以重复一的步骤        一的步骤执行了几次就是Low的值，这个应该可以使用递归处理

穷举法

就是那个第一排人尽可能多不会啊

求最长非递增子序列。


Question: 结构体指针转换成int报错

typedef struct META {     char* name;        // the name of member     uint16_t type;    // member type     uint16_t offset; // offset of member from the type head     union {         struct META* meta; // support the child struct type         int count;    // indicate the count of member when the member is a array type     } M;     #define count M.count;     #define meta  M.meta;     char* alias; // alias for the parameter, use the "name" if this is NULL } META;  语句改为 count =meta->count   只是权宜之计，最好还是不要这宏，直接写 meta->M.count

union {         struct META* meta; // support the child struct type         int count;    // indicate the count of member when the member is a array type     }; 这是个联合体  如果你想取里面count的值 要改成meta->count               count = (int)meta->meta;把结构体指针强转成int型肯定会出错


Question: 关于 fegts() 丢每行 首个字符的问题

不要使用 while (条件) 更不要使用 while (组合条件) 要使用 while (1) {  if (条件1) break;  //...  if (条件2) continue;  //...  if (条件3) return;  //... } 因为前两种写法在语言表达意思的层面上有二义性，只有第三种才忠实反映了程序流的实际情况。 典型如： 下面两段的语义都是当文件未结束时读字符 while (!feof(f)) {  a=fgetc(f);  //...  b=fgetc(f);//可能此时已经feof了！  //... } 而这样写就没有问题： while (1) {  a=fgetc(f);  if (feof(f)) break;  //...  b=fgetc(f);  if (feof(f)) break;  //... } 类似的例子还可以举很多。

仅供参考：#include <stdio.h> #include <string.h> #define MAXLEN 1000 char ln[MAXLEN]; FILE *f; int i,z; int b,n,L; int main(int argc,char **argv) {     if (argc<2) {         printf("Usage:%s fullpathfilename.ext\nget total blank/non-blank/total linenumbers.\n",argv[0]);         return 1;     }     f=fopen(argv[1],"r");     if (NULL==f) {         printf("Can not open file [%s]!\n",argv[1]);         return 2;     }     z=0;     b=0;     n=0;     L=0;     while (1) {         if (NULL==fgets(ln,MAXLEN,f)) break;         L=strlen(ln);         if ('\n'==ln[L-1]) {             if (0==z) {                 for (i=0;i<L-1;i++) {                     if (!(' '==ln[i] || '\t'==ln[i])) break;                 }                 if (i<L-1) z=1;//当前行不是空行             }             if (0==z) b++; else n++;             z=0;         } else {             if (0==z) {                 for (i=0;i<L;i++) {                     if (!(' '==ln[i] || '\t'==ln[i])) break;                 }                 if (i<L) z=1;//当前行不是空行             }         }     }     fclose(f);     if (L>0 && '\n'!=ln[L-1]) {         if (0==z) b++; else n++;//最后一行末尾无'\n'也计算     }     printf("File:[%s] total blank/non-blank/total linenumbers is %d/%d/%d\n",argv[1],b,n,b+n);     return 0; }

fgetc取走的字符你啥时候保存到buffer中呢？

引用 7 楼 mymtom 的回复:这不科学啊，楼主上代码  while( fgetc( tempFp ) != EOF ) { fgetpos( tempFp, &pos_here);  fgets( buffer, 256, tempFp );  robot_string = buffer;  memset( buffer, 0, 256 );  if( robot_string.find( "moveRobot" ) == robot_string.npos || robot_string.find( "void" ) != robot_string.npos )  { fprintf( file->FP_fp, "%s\n", robot_string.c_str() ); }  else { break; } }

引用 6 楼 zhao4zhong1 的回复:将对fgetc的调用删掉！while (1) {     fgetpos( tempFp, &pos_here);      if (NULL==fgets( buffer, 256, tempFp )) break;      robot_string = buffer;      memset( buffer, 0, 256 );      if ( robot_string.find( "moveRobot" ) == robot_string.npos      ||  robot_string.find( "void" )      != robot_string.npos ) {         fprintf( file->FP_fp, "%s\n", robot_string.c_str() );     } else {         break;     } }     为什么 不直接调用呢，能简单解释下原因吗？ 谢谢

这不科学啊，楼主上代码

引用 3 楼 turingo 的回复:fgets函数从文件结构体指针stream中读取数据，每次读取一行。读取的数据保存在buf指向的字符数组中，每次最多读取bufsize-1个字符（第bufsize个字符赋'\0'），如果文件中的该行，不足bufsize个字符，则读完该行就结束。如若该行（包括最后一个换行符）的字符数超过bufsize-1，则fgets只返回一个不完整的行，但是，缓冲区总是以NULL字符结尾，对fgets的下一次调用会继续读该行。函数成功将返回buf，失败或读到文件结尾返回NULL。因此我们不能直接通过fgets的返回值来判断函数是否是出错而终止的，应该借助feof函数或者ferror函数来判断。  仔细阅读上面内容，看看问题在哪，另外也可以看看ferror的情况。  嗯，设置断点看到读到 buffer[256] 里面的就是 丢失之后的，我试试看 ferror的情况

引用 2 楼 q3733353520 的回复:请贴代码  while( fgetc( tempFp ) != EOF ) 		{ 			fgetpos( tempFp, &pos_here);  			fgets( buffer, 256, tempFp );  			robot_string = buffer;  			memset( buffer, 0, 256 );  			if( robot_string.find( "moveRobot" ) == robot_string.npos || 				robot_string.find( "void" ) != robot_string.npos )  			{ 				fprintf( file->FP_fp, "%s\n", robot_string.c_str() ); 			}  			else 			{ 				break; 			} 		}

请贴代码

不是所有行的 首个字符丢失，只是某些行的

引用 6 楼 zhao4zhong1 的回复:将对fgetc的调用删掉！while (1) {     fgetpos( tempFp, &pos_here);      if (NULL==fgets( buffer, 256, tempFp )) break;      robot_string = buffer;      memset( buffer, 0, 256 );      if ( robot_string.find( "moveRobot" ) == robot_string.npos      ||  robot_string.find( "void" )      != robot_string.npos ) {         fprintf( file->FP_fp, "%s\n", robot_string.c_str() );     } else {         break;     } }    谢谢解答，很详细，已经解决了

引用 15 楼 mymtom 的回复: while (fgets(buffer, 256, tempFp) != NULL) {     // 这句有什么用？ fgetpos(tempFp, &pos_here);        // fgets(buffer, 256, tempFp);      robot_string = buffer;      // 这句有什么用？memset(buffer, 0, 256);        if (robot_string.find("moveRobot") == robot_string.npos ||         robot_string.find("void") != robot_string.npos)     {         fprintf(file->FP_fp, "%s\n", robot_string.c_str());     }      else {         break;     } }   fgetpos 这句 是个 后面 再 读取用到的。 这个清空多余吗


Question: C语言实现文件内容拷贝并修改，为何这样实现不了

oxfc为不可显示内容

引用 5 楼 adusuccessfully 的回复:0xfc的十进制数是252，字符转换成十进制后的取值范围是0~127，所以字符不可能等于0xfc。LZ明白了吧~谢谢，我已经明白了。

if 语句是没错的，  我想你应该关注ch

在线急等呐。。。为何不能回写。

引用 1 楼 u013163178 的回复:楼主:请问0xfc是什么,unicode吗0xfc就只是文件里面数据的16进制形式，我是一个字节一个字节从文件里取出来的

0xfc就只是文件里面数据的16进制形式，我是一个字节一个字节从文件里取出来的


Question: 关于c语言线程控制主函数内函数跳转，请前辈们指导一下

如果嫌一层一层退出函数麻烦，你还可以使用longjmp技术，参考下面： #include <stdio.h> #include <setjmp.h> jmp_buf mark; int i=0; void c() {     printf( "c in\n");     if (1==i%2) longjmp( mark, i );     printf( "c out\n"); } void b() {     printf( "b in\n");     c();     printf( "b out\n"); } void a() {     printf( "a in\n");     b();     printf( "a out\n"); } void main( void ) {    int jmpret;    jmpret = setjmp( mark );    printf( "Start %d\n",jmpret);    if( jmpret == 0 ) {        printf( "First\n");        a();        i++;        a();    } else {        printf( "Second\n");    } } //Start 0 //First //a in //b in //c in //c out //b out //a out //a in //b in //c in //Start 1 //Second //

“A线程控制B线程的执行流程”本身就是一个伪命题（当然如果你要动用WriteProcessMemory修改B线程的堆栈段或代码段字节内容以达到控制B线程的执行流程的目的的话，另说，参考这个帖子：http://bbs.csdn.net/topics/390627329）。 最简单的办法就是不用线程，只需在你主程序流程中等待用户输入的地方或长时间循环的地方抽空判断一下用户是否在此阶段不久之前是否按了比如Esc键，如果按了，提前返回本函数，必要的话，返回一个特殊值表示用户刚按了Esc，外层函数判断返回为此特殊值，也立即返回，……，直到返回主函数。此时主函数再决定是退出程序呢还是重新开始主循环。


Question: scanf 参数 中，数组类型的参数前面的&符号问题

引用 5 楼 Baoge_leopard 的回复:&str代表的不是取str这个变量的地址，而是取数组元素的地址。虽然&str和str得内存地址相同，但它们的意义不相同，它是代表整个数组的，它的进阶单位是整个数组的字节长度 谭浩强书里对二维数组的取址和指针有详细的介绍，建议看看

引用 16 楼 sivolin 的回复:[quote=引用 14 楼 vkkeva 的回复:] [quote=引用 11 楼 lm_whales 的回复:] [quote=引用 10 楼 vkkeva 的回复:] [quote=引用 9 楼 lm_whales 的回复:] scanf("%s", str);//这个才是真正的正确的格式 scanf("%s", &str);//这个原则上是错误的，只是scanf并不识别&str与%s是否匹配，才能编译并正确输出的 为什么我数组赋值的时候，不用&，然后调试就报错？[/quote] 数组赋值？不能啊？ 至少C不能给数组赋值  C只能初始化数组 把数组赋值的代码，拿来看看[/quote] 奇怪了，之前我调试老是报debug错误，现在再运行又没了。 #include<stdio.h> 这个 & 取得是 数组元素的地址，效果和  int main() { 	double array5[5]={0.0}; 	double fraction[5]={0.0}; 	 	printf ("input 5 double numbers to array.\n"); 	for (int i=0;i<5;i++) 	{ 			printf ("%2d>",i+1); 		scanf  ("%lf",&array5[i]); 	}  	for (int i=0;i<5;i++) 		fraction[i]=1.0/array5[i]; 	 	for (int i=0;i<5;i++) 	{ 		printf ("%d> %f ",i+1,fraction[i]); 		if ((i+1)%2==0) 			printf("\n"); 	}  return 0; }[/quote]没什么问题啊，只要编译时使用c99标准就好，不过用clang 好像默认的就是c99标准，直接就能编译通过[/quote]  这个程序，写成这样，已经和标准的版本没关系了 &array5[i] 和 &array5 是不同的 &array5[i] 相当于 & （array5[i] ），而不是 (&array5)[i] 这是数组array5的第 i 元素的地址。  这里有个优先级的问题 ，[] 运算符的优先级, 比& 要高所以array5先和[i]， 结合成 array5[i]。 然后在对 (array5[i])取地址。 这是取数组array5的第 5个元素的地址 。  你换成 &array5 +i 输入位置就错了 而写成 array5+i 和 &array5[i] 效果是一致的。  所以 尽量不要用 &array5 这种方式处理数据， 因为数组名 array5 本身, 就是数组自己， 在表达式中,也可以表示数组首地址 array5 + i 就可以表示,第i元素的地址  &array5 是定长数组 的地址，需要用到的地方不多 而数组首元素地址，可以取到其他任何元素的值，非常方便，灵活 一个和数组相关的操作，定义成函数  如果用定长数组地址作为实参， 用定长数组指针作为形参  似乎很方便，一个参数，就可以表示数组和他的大小  但是这种方式很不灵活 能处理 10个元素的，不能处理11个元素的数组 一个同样的算法，这要写多少函数啊。   比较一下，数组填充 //这个函数通用型要好得多  void fill(int val,int *a,int n) {      for(int i=0;i<n;i++)      {              a[i] =val;      } }  void fill10(int (*val)[10]) {      for(int i=0;i<10;i++)      {              a[i] =val;      } } void fill11(int (*val)[11]) {      for(int i=0;i<11;i++)      {              a[i] =val;      } }  int main(){ int a[10],b[11]; /////////////////////////////////////////// //1)一个函数名，就可以了 fill(5,a,10); filll(6,b,11); //2)要写两个函数名 //如果有100中 数组元素格式的不同整型数组， //要写100个不同名字的filln 函数 fill10(5,&a), fill11(6,&b); return 0; }

引用 7 楼 lm_whales 的回复:scanf如何区分传给它的参数是一个指针，还是指针的指针呢？  scanf 这种函数的使用，是有一个约定的 由第一个参数，提供其他参数的类型（以及参数个数） scanf 内部，直接取出相关参数，默认为 对应格式，指定的类型，然后输入 scanf ，只是按照，格式指定的类型的长度，取出参数而已 原来如此，明白了

引用 14 楼 vkkeva 的回复:[quote=引用 11 楼 lm_whales 的回复:] [quote=引用 10 楼 vkkeva 的回复:] [quote=引用 9 楼 lm_whales 的回复:] scanf("%s", str);//这个才是真正的正确的格式 scanf("%s", &str);//这个原则上是错误的，只是scanf并不识别&str与%s是否匹配，才能编译并正确输出的 为什么我数组赋值的时候，不用&，然后调试就报错？[/quote] 数组赋值？不能啊？ 至少C不能给数组赋值  C只能初始化数组 把数组赋值的代码，拿来看看[/quote] 奇怪了，之前我调试老是报debug错误，现在再运行又没了。 #include<stdio.h>  int main() { 	double array5[5]={0.0}; 	double fraction[5]={0.0}; 	 	printf ("input 5 double numbers to array.\n"); 	for (int i=0;i<5;i++) 	{ 			printf ("%2d>",i+1); 		scanf  ("%lf",&array5[i]); 	}  	for (int i=0;i<5;i++) 		fraction[i]=1.0/array5[i]; 	 	for (int i=0;i<5;i++) 	{ 		printf ("%d> %f ",i+1,fraction[i]); 		if ((i+1)%2==0) 			printf("\n"); 	}  return 0; }[/quote]没什么问题啊，只要编译时使用c99标准就好，不过用clang 好像默认的就是c99标准，直接就能编译通过

指针和地址 1）指针，是数据值为地址的数据 2）指针，是有类型的 ， 地址是个纯数据。 & 取到的并不是纯数据，而是一个指针  从这个意义上说，指针并不是地址值， 但指针的值，确实是个地址数据值， 只是C，C++中，指针还有个类型，表示指向的数据的类型

引用 9 楼 lm_whales 的回复:scanf("%s", str);//这个才是真正的正确的格式 scanf("%s", &str);//这个原则上是错误的，只是scanf并不识别&str与%s是否匹配，才能编译并正确输出的 ，只是scanf并不识别&str与%s是否匹配，才能编译并正确输入的

引用 10 楼 vkkeva 的回复:[quote=引用 9 楼 lm_whales 的回复:] scanf("%s", str);//这个才是真正的正确的格式 scanf("%s", &str);//这个原则上是错误的，只是scanf并不识别&str与%s是否匹配，才能编译并正确输出的 为什么我数组赋值的时候，不用&，然后调试就报错？[/quote] 数组赋值？不能啊？ 至少C不能给数组赋值  C只能初始化数组 把数组赋值的代码，拿来看看

引用 9 楼 lm_whales 的回复:scanf("%s", str);//这个才是真正的正确的格式 scanf("%s", &str);//这个原则上是错误的，只是scanf并不识别&str与%s是否匹配，才能编译并正确输出的 为什么我数组赋值的时候，不用&，然后调试就报错？

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

数组地址和数组首地址是指向同一个地址的，所以一样 而其他类型必须加取地址符才是值地址

这个问题解释在C99标准的一个脚注里： 78)...A parameter declared to have array or function type is converted to a parameter with a pointer type as described in 6.9.1.

引用 11 楼 lm_whales 的回复:[quote=引用 10 楼 vkkeva 的回复:] [quote=引用 9 楼 lm_whales 的回复:] scanf("%s", str);//这个才是真正的正确的格式 scanf("%s", &str);//这个原则上是错误的，只是scanf并不识别&str与%s是否匹配，才能编译并正确输出的 为什么我数组赋值的时候，不用&，然后调试就报错？[/quote] 数组赋值？不能啊？ 至少C不能给数组赋值  C只能初始化数组 把数组赋值的代码，拿来看看[/quote] 奇怪了，之前我调试老是报debug错误，现在再运行又没了。 #include<stdio.h>  int main() { 	double array5[5]={0.0}; 	double fraction[5]={0.0}; 	 	printf ("input 5 double numbers to array.\n"); 	for (int i=0;i<5;i++) 	{ 			printf ("%2d>",i+1); 		scanf  ("%lf",&array5[i]); 	}  	for (int i=0;i<5;i++) 		fraction[i]=1.0/array5[i]; 	 	for (int i=0;i<5;i++) 	{ 		printf ("%d> %f ",i+1,fraction[i]); 		if ((i+1)%2==0) 			printf("\n"); 	}  return 0; }

个人理解:都是对的,只是语法问题而已,我认为地址没有类型,只有指针才有类型.数据类型是给人看的,机器不看类型.

举个栗子，快捷方式的快捷方式不还是快捷方式吗

引用 1 楼 user-10 的回复:个人的理解：  &str可以看作是pointer to array of 100 ints类型的 所以&a是数组的首地址 str是array of 100 ints类型的，但是str的值是什么呢？str的值其实是一个 pointer to int，即a[0]的地址  两个的地址是指向同一个位置的。  更详细的说明楼主可以参考：http://bbs.chinaunix.net/forum.php?mod=viewthread&tid=960717  两个指针确实指向同个地方，但是这两个指针的含义是不同的啊，如果对他们做偏移运算得到的结果也是不同的啊，比如下面的程序  #include <stdio.h> int main() {   int a[5];   printf("%p\n%p\n%p\n", a, &a, (&a)[1]);   return 0; } 针对 a和&a, 对他们同时取偏移值1：  a[1] 是字符，而(&a)[1] 则是第二个 array of 5 ints的首地址，这种区别在scanf内部是如何处理呢？ 能想到的一个办法是 对于传入的指针，先强制转换成(char *),然后在进行解析。 不晓得具体是怎么做的，而且这样设计感觉不严谨啊


Question: 【STM32】串口中断问题，求大神赐教！！！

引用 7 楼 zhao4zhong1 的回复:[quote=引用 5 楼 u011113596 的回复:] [quote=引用 4 楼 zhao4zhong1 的回复:] 《Windows核心编程》 这个不是windows吧[/quote] 看走眼了。[/quote]

引用 5 楼 u011113596 的回复:[quote=引用 4 楼 zhao4zhong1 的回复:] 《Windows核心编程》 这个不是windows吧[/quote] 看走眼了。

引用 2 楼 turingo 的回复:1、开辟一个ringbuffer； 2、 gps_receive_process_event中只是简单把字符写入ringbuffer； 3、协议层才负责从ringbuffer中取出数据进行解析。 我在考虑用中断控制

引用 4 楼 zhao4zhong1 的回复:《Windows核心编程》 这个不是windows吧

《Windows核心编程》

引用 1 楼 user-4 的回复:你的延时在干什么?等指令吗?         如果不是,那么延时延后处理.         如果是,也可以先处理指令,再延时等待下一条指令. 或者暂存指令到缓冲区,用空闲时间来处理指令. 主要是有定期执行的事件在里面，延时就是时间间隔，而我发指令的时候基本上程序都在执行延时函数，所以实时性就影响了。


参考 http://www.eeesai.com/down_233804.html


Question: 谁能说说hook怎么实现按键跳转回程序某一个界面，还有dll入口函数是必要的吗？ c语言

我没查到怎么通过感触到按键的信息去回主函数窗口界面，win  32控制台程序

网上有很多全局钩子记录键盘信息例子。楼主可以百度！  DLLMain只是windows的动态库。c++的动态库的话是没有的。 windows中为了更好处理线程、进程对动态库的调用，用DLLMain来做初始化、清理操作（当然如果你愿意，如界面的动态库）。 但c++动态库（通信等和系统无关库）他们更愿意封装c接口，或者用_stacall等c++操作符来让调用者做析构。

入口函数不是必须的：http://bbs.csdn.net/topics/10107940  我觉得hook用全局钩子监听消息后，通过消息完全可以启动其他程序。

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

MSDN98\SAMPLES\VC98\MFC\TUTORIAL\SCRIBBLE\STEP1～7\*.*

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


Question: FFMPEG+SDL解码出现声音视频都是一卡一卡的

博主的问题找到了吗，想请教一下，遇到了同样的问题，雷霄华的MFC sample好像也是存在这样的问题，但是播放h.264的文件似乎就不存在这个问题，没有SDL_Delay，视频倒是可以正常快速的播放，实在是找不到原因

我还是找出原因了，把视频显示线程中的SDL_Delay（）注释掉就可以正常播放了，这里还是要感谢一下博主的代码

我去。。不小心发错版块了。版主帮我调整下谢谢。。


Question: 菜鸟求指导！

引用 5 楼 linxin3333520 的回复:[quote=引用 4 楼 aime999 的回复:] [quote=引用 3 楼 linxin3333520 的回复:] 抱歉，复制错误，前面的解释不对口。 注意：当一个共用体被声明时, 编译程序自动地产生一个变量, 其长度为联合中元类型（如数组，取其类型的数据长度）最大的变量长度的整数倍，且要大于等于其最大成员所占的存储空间。union中类型最大的变量为long b;取其整数倍，那只能是２４或３２，所以前两个数为３２，u中间的a[6]时为２４；后面看a[]大小  ——这个回答有问题的，long在32位机上是4个字节，“union中类型最大的变量为long b”这个就是错误的说法，最大的还是int a[7]; 这里面应该是涉及到字节对其的问题，如果定义了8字节对其的话，那么一个数据结构会根据内部数据的字节数动态的补0的，int a[7]就是4*7=28字节，在8字节对其的时候后面还会继续补齐4个字节的0，这样达到8字节对齐的，所以确认一下是不是8字节对齐，如果是4字节对齐的话，应该都是28的[/quote] 我之前一直认为long是8字节。若都是4字节，那结果应该是sizeof(u)与sizeof(u.a)一样吧？[/quote] 抱歉问一下，这跟逆序有什么关系？

引用 3 楼 linxin3333520 的回复:抱歉，复制错误，前面的解释不对口。 注意：当一个共用体被声明时, 编译程序自动地产生一个变量, 其长度为联合中元类型（如数组，取其类型的数据长度）最大的变量长度的整数倍，且要大于等于其最大成员所占的存储空间。union中类型最大的变量为long b;取其整数倍，那只能是２４或３２，所以前两个数为３２，u中间的a[6]时为２４；后面看a[]大小  ——这个回答有问题的，long在32位机上是4个字节，“union中类型最大的变量为long b”这个就是错误的说法，最大的还是int a[7]; 这里面应该是涉及到字节对其的问题，如果定义了8字节对其的话，那么一个数据结构会根据内部数据的字节数动态的补0的，int a[7]就是4*7=28字节，在8字节对其的时候后面还会继续补齐4个字节的0，这样达到8字节对齐的，所以确认一下是不是8字节对齐，如果是4字节对齐的话，应该都是28的

在内存中，数据是按4字节逆序存储的，所有两次输出，前面都为３２；后面看a[]的数据大小，一个为７*４＝２８，另一个为８*４＝３２

机器码数据是按4字节逆序存储的，所有两次输出，前面都为３２；后面看a[]的数据大小，一个为７*４＝２８，另一个为８*４＝３２ 那结果应该是sizeof(u)与sizeof(u.a)不一样。

引用 4 楼 aime999 的回复:[quote=引用 3 楼 linxin3333520 的回复:] 抱歉，复制错误，前面的解释不对口。 注意：当一个共用体被声明时, 编译程序自动地产生一个变量, 其长度为联合中元类型（如数组，取其类型的数据长度）最大的变量长度的整数倍，且要大于等于其最大成员所占的存储空间。union中类型最大的变量为long b;取其整数倍，那只能是２４或３２，所以前两个数为３２，u中间的a[6]时为２４；后面看a[]大小  ——这个回答有问题的，long在32位机上是4个字节，“union中类型最大的变量为long b”这个就是错误的说法，最大的还是int a[7]; 这里面应该是涉及到字节对其的问题，如果定义了8字节对其的话，那么一个数据结构会根据内部数据的字节数动态的补0的，int a[7]就是4*7=28字节，在8字节对其的时候后面还会继续补齐4个字节的0，这样达到8字节对齐的，所以确认一下是不是8字节对齐，如果是4字节对齐的话，应该都是28的[/quote] 我之前一直认为long是8字节。若都是4字节，那结果应该是sizeof(u)与sizeof(u.a)一样吧？

union的大小由其中最大的元素决定，a[]最大，所以按a[]的来


Question: 循环使用realloc十次左右及以上 VS2008报错

越界了

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

sizeof(a)永远等于4，也就是你操作个几次以后就一直是越界了，不挂才挂

已修正错误，使用一个int来记录长度，谢谢指教。

a=(char *)realloc(b+1,sizeof(char));


Question: 求助大神，这个程序输出结果1的前面为什么没有空格字符的。。。。请告诉我详细的原因，按道理4次循环应该有4个空格才对吧？？？

因为循环处理的最后一个是 i=1，没有处理 x[0];


Question: 关于C语言中的多线程问题——银行转账

引用 5 楼 zhao4zhong1 的回复:Synchronization Functions The following functions are used in synchronization.        CancelWaitableTimer   CreateEvent   CreateMutex   CreateSemaphore   CreateWaitableTimer   DeleteCriticalSection   EnterCriticalSection   GetOverlappedResult   InitializeCriticalSection   InitializeCriticalSectionAndSpinCount   InterlockedCompareExchange   InterlockedDecrement   InterlockedExchange   InterlockedExchangeAdd   InterlockedIncrement   LeaveCriticalSection   MsgWaitForMultipleObjects   MsgWaitForMultipleObjectsEx   OpenEvent   OpenMutex   OpenSemaphore   OpenWaitableTimer   PulseEvent   QueueUserAPC   ReleaseMutex   ReleaseSemaphore   ResetEvent   SetCriticalSectionSpinCount   SetEvent   SetWaitableTimer   SignalObjectAndWait   TimerAPCProc   TryEnterCriticalSection   WaitForMultipleObjects   WaitForMultipleObjectsEx   WaitForSingleObject   WaitForSingleObjectEx 谢谢您的耐心回答，但这些东西对于我来说太复杂了看不懂，但还是把分给你分一半～

《Windows核心编程》 仅供参考//循环向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; }

for(i=1; i<=100;i++)     {         if(pthread_create(&account_thr,NULL,transfer,NULL))         {             printf("ERROR CREATING THREAD");             abort();         }else if(pthread_join(account_thr, NULL)){}     } join判断后不执行任何东西都可以，但如果不加join的话，即使有while也会只出来两三个结果。度娘说join有阻塞线程（？）的作用，，我不太明白，为什么阻塞可以影响线程的执行，跪求大神解答。

已经解决了，在main函数里加一个判断pthread_join(accpunt_thr,NULL),之后在transfer里加while（1）循环，虽然感觉很矛盾，理解不了，但是结果是满足我需要的条件的。 加了join之后，sleep起作用了，加了while之后能无限永久地输出，但缺少任何一个都不能满足要求。 for(i=1; i<=100;i++)     {         printf("%d\n",i);         if(pthread_create(&account_thr,NULL,transfer,NULL))         {             printf("ERROR CREATING THREAD");             abort();         }else if(pthread_join(account_thr, NULL))             i--;     } void *transfer(void *arg) {     //srand( (unsigned)time( NULL ) );      while(1){     int i=rand()%100;     int j=rand()%100;     int amount=rand()%1000+1;       pthread_mutex_lock(&mymutex);     if(account[i]>=amount)     {         account[i]=account[i]-amount;         account[j]=account[j]+amount;         printf("#%d transfers %d, %d left now.\n",i,amount,account[i]);         printf("#%d receives %d, %d left now.\n",j,amount,account[j]);     }else         printf("#%d has not enough money.\n",i);     printf("Current total money in bank is %d.\n",TotalMoney());     pthread_mutex_unlock(&mymutex);     //usleep((rand()%10+1)*1000); sleep(1);     }     return NULL; }


Question: 俄罗斯方块，想问下，红色部分为什么不成功，我利用的是坐标求解

同为自学者，向楼主问好。 2楼网友排版的意思是这样： #include<stdio.h> #include<conio.h> #include<windows.h> #include<stdlib.h> #include<time.h> #define M 27 #define N 20 int a = 0, b = 5; int id; int score = 0, next, map[M][N] = { 0 }, gamespeed = 300; int shape[28][6] = { { 0, -1, 0, -2, 1, 0 }, { 0, 1, 1, 0, 2, 0 }, { -1, 0, 0, 1, 0, 2 }, { 0, -1, -1, 0, -2, 0 }, { 0, -1, 0, 1, -1, 0 }, { 0, 1, 1, 0, -1, 0 }, { 1, 0, 0, -1, 0, 1 }, { 1, 0, -1, 0, 0, -1 }, { -1, 1, 0, 1, 1, 0 }, { 0, -1, 1, 0, 1, 1 }, { -1, 0, 0, -1, 1, -1 }, { -1, -1, -1, 0, 0, 1 }, { -1, 0, 0, 1, 1, 1 }, { 0, 1, 1, -1, 1, 0 }, { -1, 0, 0, 1, 1, 1 }, { 0, 1, 1, -1, 1, 0 }, { -1, 0, 0, -1, 0, -2 }, { -1, 0, -2, 0, 0, 1 }, { 0, 1, 0, 2, 1, 0 }, { 0, -1, 1, 0, 2, 0 }, { 0, 1, 1, 0, 1, 1 }, { 0, -1, 1, 0, 1, -1 }, { -1, 0, 0, -1, -1, -1 }, { -1, 0, -1, 1, 0, 1 }, { 0, 1, 0, 2, 0, 3 }, { 1, 0, 2, 0, 3, 0 }, { 0, -1, 0, -2, 0, -3 }, { -1, 0, -2, 0, -3, 0 } }; void gotoxy(int x, int y) {     COORD c;     c.X = x - 1;     c.Y = y - 1;     SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), c); } void gameover(int h[M][N]) {     int i, j, flag = 0;     for (j = 1; j < 17; j++)     if (h[1][j] != 0)     {         flag = 0;         break;     }     if (flag == 1)     {         for (i = 1; i < 17; i++)         {             gotoxy(2, i + 1);             for (j = 1; j < 11; j++)                 printf("空心方块");             gotoxy(7, 9);             printf("game over!");             gotoxy(1, 19);             exit(0);         }     } } void block(int x, int y, int h[M][N]) {     int i;     h[x][y] = 3;     for (i = 0; i < 6; i += 2)         h[x + shape[id][i]][y + shape[id][i + 1]] = 3; } void clsc(int x, int y, int h[M][N]) {     int i;     h[x][y] = 0;     for (i = 0; i < 6; i += 2)         h[x + shape[id][i]][y + shape[id][i + 1]] = 0; } int judge(int x, int y, int h[M][N]) {     int i;     if (h[x][y] != 0)         return 0;     for (i = 0; i < 6; i += 2)     if (h[x + shape[id][i]][y + shape[id][i + 1]] != 0)         return 0;     return 1; } void print(int h[M][N]) {     int i, j;     for (i = 0; i < 19; i++)     {         for (j = 0; j < 12; j++)         {             if (i == 18) h[i][j] = 2;             if (j == 0 || j == 11)h[i][j] = 1;                   if (h[i][j] == 0)                 printf("  ");             if (h[i][j] == 1)                 printf("|");             if (h[i][j] == 2)                 printf("--");             if (h[i][j] == 3)                 printf("实心方块");             if (i == 1 && j == 11)printf("next:");             if (i == 11 && j == 11)printf("score:%d", score);             if (i == 14 && j == 11)printf("speed:%d", score / 100 + 1);         }         printf("\n");     } }   void ne(int h[M][N])        {     int i, j;     for (i = 0; i < 6; i += 2)         h[6 + shape[id][i]][16 + shape[id][i + 1]] = 0;     h[6][16] = 3;     for (j = 0; j < 6; j += 2)         h[6 + shape[next][j]][16 + shape[next][j + 1]] = 3; } void main() {     int i, j, id;     int flag = 0;     srand(time(NULL));     id = rand() % 27;     print(map);     while (1)     {         next = rand() % 27;         id = next;         ne(map);         while (!_kbhit())         {             if (judge(a + 1, b, map) == 1)             {                 clsc(a, b, map);                 block(a++, b, map);             }             else             {                 for (i = 1; i < 17; i++)                 for (j = 1; j < 11; j++)                 if (map[i][j] != 3)                 {                     flag = 1;                     break;                 }                 if (flag == 0)                     map[i][j] = map[i - 1][j];                 print(map);                 a = 0;                 b = 5;                 score += 10;                 if (score % 100 == 0) gamespeed -= 50;                 Sleep(gamespeed);             }         }         switch (_getch())         {         case'a':case'A':if (judge(a, b - 1, map) == 1)clsc(a, b, map), block(a, --b, map); break;         case'd':case'D':if (judge(a, b + 1, map) == 1)clsc(a, b, map), block(a, ++b, map); break;         case's':case'S':if (judge(a + 1, b, map) == 1)clsc(a, b, map), block(a++, b, map); break;         case'w':case'W':if (id % 4 == 0 && id != 0)id -= 4, block(a, b, map); break;         }     } }

我是新手，我自学的，排版的问题我暂时还不知道应该怎么做，我知道你说的自己调，我是单步调试调试了几天我才问的，所以有些东西谁都知道自己会才最好，但是真的没有办法才求助的

楼主你先排版一下吧，这么乱怎么看啊

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


Question: 为什么文本框没显示内容?坐等!

没人回会吗?

明显的是属于C#的代码吧？

.cs? C#代码？

.cs? 这里是c++论坛吧，难道我来错了？  获取button的名字 应该是button.Name 吧，你试试。

大图


Question: 使用vc6调试程序，输出框行数有限制，运行输出，数据丢失

#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中

数据没有丢失，只是dos框显示的限制

那是因为控制台的显示数目有限，你可以把结果写到文件中，这样就都会出来的


Question: 求高人解答 算法问题

算出平均距离，确认石头位置。

DP问题！！


Question: 求助大神，帮帮小弟

Windows控制台程序课程

MFC控件程序？还是Windows控制台程序呀？

老师都说了，雷同作业全部零分。自己好好写吧。


Question: 画实心圆

r*sqrt(2.0)/2.0≈r*1.414/2.0=r*0.707=r*707/1000

复习高中数学圆锥曲线。

恩，谢谢啊，可是还想问下，它这是根据什么算法来实现的？怎么就知道要这样写的

引用 1 楼 user-2 的回复:.sqrt(2)/2 恩，还是想问问这是根据什么来实现的，为什么是这样啊？


Question: 求一位C语言大神,帮我加个程序

这个没有要求，只要在这个程序中能够再加上个矩阵对角化就行，能符合上面的程序运行出来

个人觉得你应该把矩阵对角化表述清楚。什么需求、什么结果说明白了，就算没学过矩阵对角化的，也能帮你把程序写出来

#include<stdio.h> #include<math.h>   /*--------------------全局变量定义-------------------------*/ int n, c = 0; int a[100][100], b[100][100]; int fc[100][100];   /*--------------------函数声明-----------------------------*/ void print(); void print_sub(); void input_marry(); void add_marry(); void sub_marry(); void mut_marry();  /*------------------主函数-----------------*/ void main() { 	print();   	scanf("%d",&c); 	while(c!=0) 	{     		if(c==1) {input_marry();}	 		if(c==2) {add_marry();}	 		if(c==3) {sub_marry();}	 		if(c==4) {mut_marry();}	 		printf("请选择运算：\n\n"); 		scanf("%d",&c);	  	}	 }  /*----------------打印函数------------------*/ void print() { 	printf("          矩阵运算管理系统          \n"); 	printf("------------------------------------\n"); 	printf("1 输入矩阵\n"); 	printf("2 矩阵相加\n"); 	printf("3 矩阵相减\n"); 	printf("4 矩阵相乘\n"); 	printf("0 退出系统\n"); 	printf("------------------------------------\n"); 	printf("请选择:\n\n"); }   /*---------------矩阵输入-----------------------*/ void input_marry() { 	int i, j; 	printf("请输入矩阵的维数\n\n"); 	scanf("%d",&n); 	/*---------------第一个矩阵输入-----------------*/ 	printf("请输入第一个矩阵a（共有%4d个元素）:\n\n",n*n); 	for(i=0;i<n;i++) 		for(j=0;j<n;j++) 		{ 			scanf("%d",&a[i][j]); 		} 	 	/*----------------打印第一个矩阵---------------*/ 	printf("您输入的矩阵a=\n\n"); 	for(i=0;i<n;i++) 	{ 		for(j=0;j<n;j++) 		{  			printf("%10d",a[i][j]);			 		} 		printf("\n"); 	}  	/*---------------第二个矩阵输入-----------------*/		 		printf("请输入第二个矩阵b（共有%d个元素）:\n\n",n*n); 		for(i=0;i<n;i++) 		{ 			for(j=0;j<n;j++) 			{ 				scanf("%d",&b[i][j]); 			} 		} 		/*----------------打印第二个矩阵---------------*/ 		printf("您输入的矩阵b=\n\n"); 		for(i=0;i<n;i++) 		{ 			for(j=0;j<n;j++) 			{  				printf("%10d",b[i][j]); 			} 			printf("\n"); 		} 		print_sub();  }   /*----------------矩阵加法运算-----------------*/ void add_marry() { 	int i,j; 	for(i=0;i<n;i++) 		for(j=0;j<n;j++) 		{ 			fc[i][j] = a[i][j] + b[i][j];		 		}  	printf("矩阵和为：\n\n"); 	for(i=0;i<n;i++) 	{ 		for(j=0;j<n;j++) 		{  			printf("%10d",fc[i][j]); 		} 		printf("\n"); 	} 	print_sub();  }  /*----------------矩阵减法运算-----------------*/ void sub_marry() { 	int i,j; 	for(i=0;i<n;i++) 		for(j=0;j<n;j++) 		{ 			fc[i][j] = a[i][j] - b[i][j]; 		}  	printf("矩阵差为：\n\n"); 	for(i=0;i<n;i++) 	{ 		for(j=0;j<n;j++) 		{  			printf("%10d",fc[i][j]); 		} 		printf("\n"); 	} 	print_sub();  } /*----------------矩阵乘法运算-----------------*/ void mut_marry() { 	int k,i,j; 	for (i=0;i<n;i++) 		for (j=0;j<n;j++) 		{ 			fc[i][j] = 0; 			for (k=0; k<n; k++) 				fc[i][j] += a[i][k] * b[k][j]; 		} 		 	printf("矩阵积为：\n\n"); 	for(i=0;i<n;i++) 	{ 		for(j=0;j<n;j++) 		{  			printf("%10d",fc[i][j]); 		} 		printf("\n"); 	} 	print_sub(); 	            }  /*-------------------子打印函数-----------------*/ void print_sub() { 	printf("\n----------------------------------------------\n");     printf("\n2 矩阵相加；3 矩阵相减；4 矩阵相乘；0 退出系统\n"); 	printf("\n----------------------------------------------\n");	 }

有会的吗?我比较急，大神告诉一下

是啊，我也是这块弄不出来了，所以找个大神看看能不能帮我一下

这个问题比较棘手啊！


Question: 数据结构课程设计

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

好熟悉的题目。。。


Question: c语言入门基础题一道，求教

发表于： 2014-12-23 18:37:30 竟然显示的前面

生命不息，挖坟不止。

float a[5][6]={};  没这么做过 好像是没有赋值，但又做了赋值的操作，浪费时间

[quote=引用 6 楼 zhao4zhong1 的回复:] 计算机组成原理→DOS命令→汇编语言→C语言（不包括C++）、代码书写规范→数据结构、编译原理、操作系统→计算机网络、数据库原理、正则表达式→其它语言（包括C++）、架构…… 说得很好，要是再附上一些推荐的相关书籍就更好了

可以啊 没初值而已

理解和讨论之前请先学会如何观察！

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

实践是检验真理的唯一标准

为什么不自己运行一下呢

可以这样赋值~~~

不做吗？只是没初始值而已

gcc 4.8编译通过,运行无异常 /*************************************************************************     > File Name: test1.c     > Author: jukay     > Mail: hellojukay@163.com      > Created Time: 2014年12月23日 星期二 19时47分48秒  ************************************************************************/  #include<stdio.h> int main() { 	float a[5][6] = {}; 	for(int i = 0; i < sizeof(a) / sizeof(float);++i) 		printf("%a\t",a[i]); 	return 0; }


Question: 字符拼接

参考代码 http://tieba.baidu.com/p/3255025351

已经解决  跟帖回复   三分


Question: 有一个这样的课设作业....

其实我不会用C++...

引用 7 楼 yangyunzhao 的回复:[quote=引用 5 楼 L5_DP 的回复:] [quote=引用 3 楼 yangyunzhao 的回复:] 晕，声音文件不就是一串二进制数据吗？不就是01010的混合体吗？不就是const char *吗？用std::string也可以，只是不好理解，但是好用。  但是！一般不会把声音、图形读入到内存里面，因为比较占内存。建议做一个汉字到声音文件（即文件存储路径文件名）的映射。 那么请问这个映射怎么做。。。原谅我实在是菜....[/quote]  std::map<std::string, std::string>  第一个string表示汉字，第二个string表示存储路径[/quote]  我在dev里面编译 这有一个纯输出声音的语句 #include<stdio.h> #include <windows.h> #include <mmsystem.h> // 加上，不然PlaySound函数无法使用 #pragma comment(lib, "WINMM.LIB") // 加上，不然PlaySound函数无法使用 int main(){ 	PlaySound("d:\\read\\down.wav",NULL,SND_ASYNC|SND_FILENAME); 	return 0; } 但是却报错了 C:\Users\dell\AppData\Local\Temp\cco5GYmK.o	ks.cpp:(.text+0x22): undefined reference to `__imp_PlaySoundA' E:\Program\collect2.exe	[Error] ld returned 1 exit status  大哥知道是怎么回事么

引用 5 楼 L5_DP 的回复:[quote=引用 3 楼 yangyunzhao 的回复:] 晕，声音文件不就是一串二进制数据吗？不就是01010的混合体吗？不就是const char *吗？用std::string也可以，只是不好理解，但是好用。  但是！一般不会把声音、图形读入到内存里面，因为比较占内存。建议做一个汉字到声音文件（即文件存储路径文件名）的映射。 那么请问这个映射怎么做。。。原谅我实在是菜....[/quote]  std::map<std::string, std::string>  第一个string表示汉字，第二个string表示存储路径

引用 4 楼 zxhuser-2 的回复:百度 语音识别 不是做语音识别，我百度了好久 从文本到语音，但是都不是我想要的。。。

引用 3 楼 yangyunzhao 的回复:晕，声音文件不就是一串二进制数据吗？不就是01010的混合体吗？不就是const char *吗？用std::string也可以，只是不好理解，但是好用。  但是！一般不会把声音、图形读入到内存里面，因为比较占内存。建议做一个汉字到声音文件（即文件存储路径文件名）的映射。 那么请问这个映射怎么做。。。原谅我实在是菜....

百度 语音识别

人工置顶

为什么没人


Question: c语言如何创建线程

引用 12 楼 zhao4zhong1 的回复:连main都拼写错误的人能编好程序吗？ 仅供参考#include <stdio.h> #include <stdlib.h> #include <string.h> #ifdef WIN32     #include <windows.h>     #include <io.h>     #include <process.h>     #define  MYVOID             void #else     #include <unistd.h>     #include <sys/time.h>     #include <pthread.h>     #define  CRITICAL_SECTION   pthread_mutex_t     #define  _vsnprintf         vsnprintf     #define  MYVOID             void * #endif //Log{ #define MAXLOGSIZE 20000000 #define ARRSIZE(x) (sizeof(x)/sizeof(x[0])) #include <time.h> #include <sys/timeb.h> #include <stdarg.h> char logfilename1[]="MyLog1.log"; char logfilename2[]="MyLog2.log"; char logstr[16000]; 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;     if (-1==_vsnprintf(logstr,ARRSIZE(logstr),pszFmt,argp)) logstr[ARRSIZE(logstr)-1]=0;     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);             }             flog=fopen(logfilename1,"a");             if (NULL==flog) return;         }         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 No_Loop=0; MYVOID testThread(void *pcn) {     int n,i;      n=(int)pcn;     i=0;     while (1) {         sleep_ms(1000);         Log("in testThread %d:i==%ds\n",n,++i);         if (i>=5) No_Loop=1;     } } int main(int argc,char * argv[]) {     int i; #ifdef WIN32     InitializeCriticalSection(&cs_log); #else     pthread_mutex_init(&cs_log,NULL);     pthread_t threads[1];     int threadsN;     int rc; #endif     Log("=========BEGIN==================\n"); #ifdef WIN32     _beginthread((void(__cdecl *)(void *))testThread,0,(void *)1); #else     threadsN=0;     rc=pthread_create(&(threads[threadsN++]),NULL,testThread,(void *)1);if (rc) Log("%d=pthread_create %d error!\n",rc,threadsN-1); #endif     i=0;     while (1) {         sleep_ms(100);         Log("in main:i==%d\n",++i);         if (No_Loop==1) break;//     }     Log("=========END====================\n"); #ifdef WIN32     DeleteCriticalSection(&cs_log); #else     pthread_mutex_destroy(&cs_log); #endif     return 0; } //2012-06-14 16:27:21.500 =========BEGIN================== //2012-06-14 16:27:21.609 in main:i==1 //2012-06-14 16:27:21.718 in main:i==2 //2012-06-14 16:27:21.828 in main:i==3 //2012-06-14 16:27:21.937 in main:i==4 //2012-06-14 16:27:22.046 in main:i==5 //2012-06-14 16:27:22.156 in main:i==6 //2012-06-14 16:27:22.265 in main:i==7 //2012-06-14 16:27:22.375 in main:i==8 //2012-06-14 16:27:22.484 in main:i==9 //2012-06-14 16:27:22.500 in testThread 1:i==1s //2012-06-14 16:27:22.593 in main:i==10 //2012-06-14 16:27:22.703 in main:i==11 //2012-06-14 16:27:22.812 in main:i==12 //2012-06-14 16:27:22.921 in main:i==13 //2012-06-14 16:27:23.031 in main:i==14 //2012-06-14 16:27:23.140 in main:i==15 //2012-06-14 16:27:23.250 in main:i==16 //2012-06-14 16:27:23.359 in main:i==17 //2012-06-14 16:27:23.468 in main:i==18 //2012-06-14 16:27:23.500 in testThread 1:i==2s //2012-06-14 16:27:23.578 in main:i==19 //2012-06-14 16:27:23.687 in main:i==20 //2012-06-14 16:27:23.796 in main:i==21 //2012-06-14 16:27:23.906 in main:i==22 //2012-06-14 16:27:24.015 in main:i==23 //2012-06-14 16:27:24.125 in main:i==24 //2012-06-14 16:27:24.234 in main:i==25 //2012-06-14 16:27:24.343 in main:i==26 //2012-06-14 16:27:24.453 in main:i==27 //2012-06-14 16:27:24.500 in testThread 1:i==3s //2012-06-14 16:27:24.562 in main:i==28 //2012-06-14 16:27:24.671 in main:i==29 //2012-06-14 16:27:24.781 in main:i==30 //2012-06-14 16:27:24.890 in main:i==31 //2012-06-14 16:27:25.000 in main:i==32 //2012-06-14 16:27:25.109 in main:i==33 //2012-06-14 16:27:25.218 in main:i==34 //2012-06-14 16:27:25.328 in main:i==35 //2012-06-14 16:27:25.437 in main:i==36 //2012-06-14 16:27:25.500 in testThread 1:i==4s //2012-06-14 16:27:25.546 in main:i==37 //2012-06-14 16:27:25.656 in main:i==38 //2012-06-14 16:27:25.765 in main:i==39 //2012-06-14 16:27:25.875 in main:i==40 //2012-06-14 16:27:25.984 in main:i==41 //2012-06-14 16:27:26.093 in main:i==42 //2012-06-14 16:27:26.203 in main:i==43 //2012-06-14 16:27:26.312 in main:i==44 //2012-06-14 16:27:26.421 in main:i==45 //2012-06-14 16:27:26.500 in testThread 1:i==5s //2012-06-14 16:27:26.531 in main:i==46 //2012-06-14 16:27:26.531 =========END====================  我用手机写的

引用 10 楼 fuqingyun 的回复:[quote=引用 9 楼 fly_dragon_fly 的回复:] 硬中断只做简单的事，如果i++和printf相比，那么就应该让中断做i++，windows显示时间并不实时，它仅是一个0.5秒的定时器。也就是线程的消息队列机制， 如果你仅是为了显示变量，内部可以自己实行一个简单的队列来处理，用线程并不能提高什么。 我要的就是定时显示，开始描述不恰当，后面纠正了，定时显示每个一秒一次 [/quote] 线程 是和操作系统相关的，c语言并不存在一个标准的线程操作函数。 如果你的系统是在单片机上面实现的，你应该考虑单片机提供的计时寄存器。 如果你是在windows和linux上面实现的，这个可以用系统提供的线程来实现计时。

引用 9 楼 fly_dragon_fly 的回复:硬中断只做简单的事，如果i++和printf相比，那么就应该让中断做i++，windows显示时间并不实时，它仅是一个0.5秒的定时器。也就是线程的消息队列机制， 如果你仅是为了显示变量，内部可以自己实行一个简单的队列来处理，用线程并不能提高什么。 我要的就是定时显示，开始描述不恰当，后面纠正了，定时显示每个一秒一次

好吧，再罗嗦一次，i做自增运算，不需要每次自增都显示，也不用传递i值给系统函数，只有当一秒结束的时候，硬件发出int中断指令（汇编可以实现吧），然后转到中段程序，显示i，回复现场，继续运行主程序，直到下一秒结束

中段是指令是时钟发出的，如果不用汇编，有没有现成的可以调用？我好像罗嗦了

man pthread_create

从底层考虑，我要求有一个时钟中断程序，隔一秒中断一次，显示参数，假设显示的时间是1/100秒，中断和现场回复的时间几乎可以忽略，那我的程序速度，仅仅降低了1/100而已，但是c能操作中段这么底层的东西吗？如果不能，要实现这样的效果，最好的办法是什么？  再强调:我并不要求每次i++都显示，只是要求每隔一秒显示一次，就显示“当下”的i，而其他时间，程序都在正常运行，

在process.h头文件里  有一个_beginthread函数可以创建线程

可以用线程做，网上搜一下，很多资料的

for reference only/*************************************************************************     > File Name: test1.c     > Author: jukay     > Mail: hellojukay@163.com      > Created Time: 2014年12月23日 星期二 20时39分21秒  ************************************************************************/  #include<pthread.h> #include<stdio.h> #include<stdlib.h>  void thread(void) { 	int i; 	for(i = 0; i < 3; i++) 	{ 		printf("This is a pthread!\n"); 	} } int main(void) { 	pthread_t id; 	int i,ret; 	ret = pthread_create(&id,NULL,(void*)thread,NULL); 	if(ret != 0) 	{ 		fprintf(stderr,"create pthread error!\n"); 		exit(EXIT_FAILURE); 	} 	for(i = 0; i < 3; ++i) 		printf("This is a the main process\n");  	pthread_join(id,NULL);  	exit(EXIT_SUCCESS); }

看你线程创建成功否。而且就算是多线程，CPU其实也是按调度方式分别执行，不是真正的并行运行啦，你可以在线程里面输出试试。  CreateThread(NULL,0,ThreadProc,NULL,NULL,NULL);  第一个参数是指向安全属性的指针，NULL就行 第二个参数是初始线程堆栈大小，0就可以，WINDOWS会自动分配 第三个参数指向线程函数，必须是这样DWORD WINAPI ThreadProc (LPVOID pParam)  第四个参数是传给线程函数的参数，有就传，没有就NULL 第五个参数是线程启动方式，可以是挂起CREATE_SUSPENDED，或者马上启动NULL 最后一个参数是创建的线程ID。  成功的话，返回线程句柄。

或者我把问题改一改，我想即时显示程序的某个变量，程序实现或者交给系统去代办都行，就像windows显示时间那样


Question: 一个简单的问题，求教

vs里面是2 这是正确的  因为printf的时候i已经是2了

自己写代码搞不清楚算符优先级请多加括号。 看别人代码搞不清楚算符优先级能调试的话请单步调试对应汇编。 看别人代码搞不清楚算符优先级不能调试的话想办法照写一小段孤立的可调试的代码然后单步调试对应汇编。 看别人代码搞不清楚算符优先级不能调试的话且没有办法照写一小段孤立的可调试的代码然后单步调试对应汇编的话只能参考算符优先级表猜了（提醒：并不能100%猜对）。 //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 | //+------------------+-----------------------------------------+---------------+

自行详阅置顶帖！

不同的系统和程序下，编译肯定有差异啊。

引用 5 楼 q3733353520 的回复:gcc   	.file	"14.c" 	.section	.rodata .LC0: 	.string	"%d\n" 	.text 	.globl	main 	.type	main, @function main: .LFB0: 	.cfi_startproc 	pushq	%rbp 	.cfi_def_cfa_offset 16 	.cfi_offset 6, -16 	movq	%rsp, %rbp 	.cfi_def_cfa_register 6 	subq	$16, %rsp 	movl	$1, -4(%rbp) 	movl	-4(%rbp), %eax 	leal	1(%rax), %edx 	movl	%edx, -4(%rbp) 	movl	%eax, -4(%rbp) 	movl	-4(%rbp), %eax 	movl	%eax, %esi 	movl	$.LC0, %edi 	movl	$0, %eax 	call	printf 	movl	$1, %eax 	leave 	.cfi_def_cfa 7, 8 	ret 	.cfi_endproc .LFE0: 	.size	main, .-main 	.ident	"GCC: (Ubuntu 4.8.2-19ubuntu1) 4.8.2" 	.section	.note.GNU-stack,"",@progbits             我觉的救你的回答靠谱一些。。。我已经知道了，两个汇编代码看看就知道了。。。

计算机组成原理→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对应的汇编并单步执行观察相应内存和寄存器变化。）

i=1;i=i+1;输出i=2； 是不是这样子

引用 1 楼 zhao4zhong1 的回复:不要迷信书、考题、老师、回帖； 要迷信CPU、编译器、调试器、运行结果。 并请结合“盲人摸太阳”和“驾船出海时一定只带一个指南针。”加以理解。 任何理论、权威、传说、真理、标准、解释、想象、知识……都比不上摆在眼前的事实！  有人说一套做一套，你相信他说的还是相信他做的？ 其实严格来说这个世界上古往今来所有人都是说一套做一套，不是吗？  不要写连自己也预测不了结果的代码！  赵四老师能不能解答一下这个具体问题？？  LZ说gcc下是可以理解的1，是怎么理解呢？？

引用 1 楼 zhao4zhong1 的回复:不要迷信书、考题、老师、回帖； 要迷信CPU、编译器、调试器、运行结果。 并请结合“盲人摸太阳”和“驾船出海时一定只带一个指南针。”加以理解。 任何理论、权威、传说、真理、标准、解释、想象、知识……都比不上摆在眼前的事实！  有人说一套做一套，你相信他说的还是相信他做的？ 其实严格来说这个世界上古往今来所有人都是说一套做一套，不是吗？  不要写连自己也预测不了结果的代码！ 囧了，你又开始复制粘贴了。。。严肃的讨论问题哈


Question: 错就错在自己也不知道哪里错了

楼主没看出来我5楼和6楼的代码都是交换指针吗？

引用 5 楼 zhao4zhong1 的回复://不带表头结点的单向链表 #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-> //

void sortlist(INDEX head,int i) {	 	int j=0; 	INDEX temp=NULL; 	printf("start sort,"); 	INDEX p1=NULL,p2=NULL; 	for(p1=head->next; p1!=head->prev; p1=p1->next) 	{ 		for(p2=p1->next; p2!=head; p2=p2->next) 		{ 			if(p1->data[i]<p2->data[i]) 			{ 				//printf("%d,", j++); 				//exchangenode(p1,p2); 				memcpy(temp,p1->data,sizeof(s)); 				memcpy(p1->data,p2->data,sizeof(s)); 				memcpy(p2->data,temp,sizeof(s));//改成这个样排序正确，                                                                                //但是data太长，我不想交换数据，想换指针                                                                                //谁给看看要怎么改 			} 		} 	} }

这玩意自己能调试出来的！~

是不是sort和exchange“打架”了？exchang交换是指针不是数据……


Question: 非递归算法的遍历问题

引用 6 楼 zhao4zhong1 的回复:你的代码思想混乱。对照我的自我检讨一下。

你的代码思想混乱。对照我的自我检讨一下。

引用 4 楼 zhao4zhong1 的回复:代码功能归根结底不是别人帮自己看或讲解或注释出来的；而是被自己静下心来花足够长的时间和精力亲自动手单步或设断点或对执行到某步获得的中间结果显示或写到日志文件中一步一步分析出来的。 提醒：再牛×的老师也无法代替学生自己领悟和上厕所！ 单步调试和设断点调试（VS IDE中编译连接通过以后，按F10或F11键单步执行，按Shift+F11退出当前函数；在某行按F9设断点后按F5执行停在该断点处。）是程序员必须掌握的技能之一。  /*  *build a Immoblization bottom stack  *Push order is from bottom to top  */ #define MAXSTACKSIZE 1000 typedef struct {     int top;     tree *buf[MAXSTACKSIZE]; }stack,*stack_point; void init_stack(stack_point stp) {     stp->top=0; }  void push(stack_point stp,Bit_tree bittree) {     if (stp->top>=MAXSTACKSIZE) {         printf("stack overflow!\n");         exit(1);     }     stp->buf[stp->top] = bittree;     stp->top++; }  Bit_tree *pop(stack_point stp) {     if (stp->top<=0) return NULL;     stp->top--;     return stp->buf[stp->top]; }  int stack_status(stack_point stp) {     if(stp->top <= 0)     {         printf("stack is null!\n");         return 1;     }     return 0; }  Bit_tree stack_top(stack_point stp) {     if (stp->top<=0) return NULL;     return stp->buf[stp->top-1]; }  谢谢你，问题解决了！其实我还是比较想知道为什么，我的代码单纯用指针的时候不好使，我发问题代码的那种

哪位大神出来给点指导，很想知道错在那，都改了好几天了，怎么都不对。。。。

引用 1 楼 zhao4zhong1 的回复:http://www.codeproject.com/Articles/418776/How-to-replace-recursive-functions-using-stack-and 仅供参考#include <stdio.h> #include <stdlib.h> #include <conio.h> #include <graphics.h> int xs[10000]; int ys[10000]; int i=0,xx,yy; int fc,bc; void push(int x,int y) {     xs[i]=x;     ys[i]=y;     if (i<10000-1) {         i=i+1;     } else {         printf("stack overflow!\n");         exit(1);     } } void pop(void) {     i=i-1;     xx=xs[i];     yy=ys[i]; } int check(int x,int y) {     int c;      c=getpixel(x,y); /* 获取当前点的颜色 */     return ((c!=bc)&&(c!=fc));/* 如果颜色为边界色或填充色则不填充 */ } void seedfilling(int x,int y,int fill_color,int boundary_color) {     fc=fill_color;     bc=boundary_color;     push(x,y);     while (1) {         if (i<=0) return;         pop();         if (check(xx,yy)) {             putpixel(xx, yy, 14);getch();  /* 加上这行显示当前填充状态 */              putpixel(xx, yy, fill_color); /* 画点 */              if (check(xx-1,yy  )) push(xx-1,yy  );             if (check(xx  ,yy+1)) push(xx  ,yy+1);             if (check(xx  ,yy-1)) push(xx  ,yy-1);             if (check(xx+1,yy  )) push(xx+1,yy  );             /* 去掉下面四句就是四连通 */             if (check(xx-1,yy-1)) push(xx-1,yy-1);             if (check(xx-1,yy+1)) push(xx-1,yy+1);             if (check(xx+1,yy-1)) push(xx+1,yy-1);             if (check(xx+1,yy+1)) push(xx+1,yy+1);         }     } } void main() {     int a,b,color;     int gdriver = DETECT, gmode, errorcode;     int poly[10];      initgraph(&gdriver, &gmode, "d:\\bc\\bgi");     a=150;     b=140;     color=4;     poly[0]=110;/* 第一个点的x坐标以及y坐标 */     poly[1]=110;     poly[2]=200;/* 第二点 */     poly[3]=105;     poly[4]=170;/* 第三点 */     poly[5]=120;     poly[6]=150;/* 第四点 */     poly[7]=170;     poly[8]=110;/* 多边形的起点与终点一样 */     poly[9]=110;     drawpoly(5,poly);/* 显示各点连接起来的多边形 */      /* 保证边界对八连通是封闭的 */     setviewport(0,1,600,300,0);     drawpoly(5,poly);/* 显示各点连接起来的多边形 */     setviewport(1,0,600,300,0);     drawpoly(5,poly);/* 显示各点连接起来的多边形 */     setviewport(1,1,600,300,0);     drawpoly(5,poly);/* 显示各点连接起来的多边形 */      /* 恢复默认viewport */     setviewport(0,0,600,300,0);      seedfilling(a,b,color,15);  /* 种子填充多边形 */      getch();     closegraph(); }  这个文章我看过了，我以前写过别的非递归程序，没出问题，但是这次我写树的时候就出问题了，不知道为什么堆栈老是出问题，似乎是++后不是连续的，好像跳了一格！


Question: 求大神解释一段代码的功能。

代码功能归根结底不是别人帮自己看或讲解或注释出来的；而是被自己静下心来花足够长的时间和精力亲自动手单步或设断点或对执行到某步获得的中间结果显示或写到日志文件中一步一步分析出来的。 提醒：再牛×的老师也无法代替学生自己领悟和上厕所！ 单步调试和设断点调试（VS IDE中编译连接通过以后，按F10或F11键单步执行，按Shift+F11退出当前函数；在某行按F9设断点后按F5执行停在该断点处。）是程序员必须掌握的技能之一。  “给定一个小点的输入，完整单步跟踪(同时按Alt+7键查看Call Stack里面从上到下列出的对应从里层到外层的函数调用历史)一遍。”是理解递归函数工作原理的不二法门！ 递归函数关注以下几个因素 ·退出条件 ·参数有哪些 ·返回值是什么 ·局部变量有哪些 ·全局变量有哪些 ·何时输出 ·会不会导致堆栈溢出

看上去象是最小公倍数，不过静态变量有问题。


Question: 谁能帮我找一个代码例子或者写一个可以按ESC键随时退出主程序的键盘钩子？C语言

#include <stdio.h> #include <conio.h> #include <windows.h> #include <process.h>  void max(a,b) {     if(a<b)     printf("%d",b);     else     printf("%d",a);  }   void thread_proc(void* arg) {         Sleep(100);         int k;         if(kbhit()) 	{ 		k=getch(); 		if(27==k)  		 	}               //_endthread();         //_endthreadex();      }  void main(void) {     int a,b;     max(a,b); //static unsigned pid; //  _beginthreadex(NULL,0,(unsigned (__stdcall*)(void*))thread_proc,0,0,0);     _beginthread(thread_proc,0,0);      getch();     } 前辈，我如果想把这个程序实现用那个线程控制主函数内各跳转函数返回主界面应该怎么改一下？这是我找的代码，然后自己研究改一下

引用 5 楼 jacksonfan 的回复:[quote=引用 3 楼 baijiaheizhiganmao 的回复:]  求科普什么叫键盘钩子，难道就是监听用户按键的程序吗？  钩子的核心不是回调函数？[/quote] 不知道诶，大概“钩子”这个词有二义性吧。在一般的文献中叫什么？

本来按Ctrl+Break就可以随时退出Console程序。

引用 3 楼 baijiaheizhiganmao 的回复:求科普什么叫键盘钩子，难道就是监听用户按键的程序吗？  钩子的核心不是回调函数？

#include <conio.h> #include <windows.h> int main() {     int k;      while (1) {         if (kbhit()) {             k=getch();             if (0==k || 0xE0==k) k=k<<8|getch();             if (27==k) break;//按Esc键退出             cprintf("\r\n%04X\r\n",k);         }         Sleep(200);         cprintf(".");     }     return 0; }

GenerateConsoleCtrlEvent(CTRL_BREAK_EVENT,0); GenerateConsoleCtrlEvent The GenerateConsoleCtrlEvent function sends a specified signal to a console process group that shares the console associated with the calling process.   BOOL GenerateConsoleCtrlEvent(   DWORD dwCtrlEvent,       // signal to generate   DWORD dwProcessGroupId   // process group to get signal );   Parameters dwCtrlEvent  Specifies the type of signal to generate. One of the following values is specified: Value Meaning  CTRL_C_EVENT Generates a ctrl+c signal.  CTRL_BREAK_EVENT Generates a ctrl+break signal.    dwProcessGroupId  Specifies the identifier of the process group that receives the signal. A process group is created when the CREATE_NEW_PROCESS_GROUP flag is specified in a call to the CreateProcess function. The process identifier of the new process is also the process group identifier of a new process group. The process group includes all processes that are descendants of the root process. Only those processes in the group that share the same console as the calling process receive the signal. In other words, if a process in the group creates a new console, that process does not receive the signal, nor do its descendants.  If this parameter is zero, the signal is generated in all processes that share the console of the calling process.   Return Values If the function succeeds, the return value is nonzero.  If the function fails, the return value is zero. To get extended error information, call GetLastError.   Remarks GenerateConsoleCtrlEvent causes the control handler functions of processes in the target group to be called. All console processes have a default handler function that calls the ExitProcess function. A console process can use the SetConsoleCtrlHandler function to install or remove other handler functions.   SetConsoleCtrlHandler can also enable an inheritable attribute that causes the calling process to ignore ctrl+c signals. If GenerateConsoleCtrlEvent sends a ctrl+c signal to a process for which this attribute is enabled, the handler functions for that process are not called. ctrl+break signals always cause the handler functions to be called.   QuickInfo   Windows NT: Requires version 3.1 or later.   Windows: Requires Windows 95 or later.   Windows CE: Unsupported.   Header: Declared in wincon.h.   Import Library: Use kernel32.lib.  See Also Consoles and Character-Mode Support Overview, Console Functions, CreateProcess, ExitProcess, SetConsoleCtrlHandler

代码我尝试了好多，查的网上的资料也好杂，所以我想在这里求前辈们给个例子什么的

引用 1 楼 jacksonfan 的回复: LRESULT CALLBACK KeyboardProc(   int code,       // hook code   WPARAM wParam,  // virtual-key code   LPARAM lParam   // keystroke-message information ) { 	//if(VK_SPACE==wParam || VK_RETURN==wParam) 	/*if(VK_F4==wParam && (1==(lParam>>29 & 1))) 		return 1; 	else 		return CallNextHookEx(g_hKeyboard,code,wParam,lParam);*/ 	if(VK_F2==wParam) 	{ 		::SendMessage(g_hWnd,WM_CLOSE,0,0); 		UnhookWindowsHookEx(g_hKeyboard); 	} 	return 1; }  求科普什么叫键盘钩子，难道就是监听用户按键的程序吗？

监听键盘事件，然后根据按下键做相应的处理（如你说的退出程序）


Question: 求大神解决关于同一语句不同程序中结果不同的问题

在每个最后不带\n的printf后面加fflush(stdout); 在每个不想受接收缓冲区旧内容影响的scanf前面加rewind(stdin); 另外请检查scanf的返回值。

fflush(stdin) fflush(stdout) 试一下

自己调试跟踪就明白了 注意getchar()的值

字符缓冲区的问题。

应该是你getchar（）了一下


Question: C语言怎么打开文件并输入文本中的字符啊？

看代码 /*************************************************************************     > File Name: main1.c     > Author: jukay     > Mail: hellojukay@163.com      > Created Time: 2014年12月24日 星期三 20时52分05秒  ************************************************************************/  #include<stdio.h> #include<stdlib.h> int main() { 	int ch; 	FILE *fp; 	fp = fopen("test.txt","w"); 	if(fp == NULL) 	{ 		fprintf(stdout,"can`t open file test.txt\n"); 		exit(EXIT_FAILURE); 	} 	while((ch = getchar()) != EOF) 	{ 		fputc(ch,fp); 	} 	fclose(fp);  	exit(EXIT_SUCCESS); }

fopen, getline（）

引用 4 楼 u012309996 的回复:还是不行。 是输入的时候 exam.txt就行吗？ txt的内容有什么要求？  如果文件在程序目录下就可以你那样输入 如果不是就要输入全路径

引用 3 楼 jacksonfan 的回复:[quote=引用 2 楼 u012309996 的回复:]  显示文件内容 [code=c ]#include<stdio.h> #include<stdlib.h> #define max 1000 int main(void) { 	int count = 0; 	FILE * fp; 	char ch; 	char fname[max]; 	printf("Enter your file name:\n"); 	gets(fname); 	if ((fp = fopen(fname, "r")) == NULL) 	{ 		printf("You can not open file\n"); 		exit(1); 	} 	else 	{ 		while ((ch = getc(fp)) != EOF) 		{ 			printf("%c",ch); 		} 	} 	fclose(fp); 	exit(0); } [/code][/quote] 还是不行。 是输入的时候 exam.txt就行吗？ txt的内容有什么要求？

引用 2 楼 u012309996 的回复:显示文件内容 [code=c ]#include<stdio.h> #include<stdlib.h> #define max 1000 int main(void) { 	int count = 0; 	FILE * fp; 	char ch; 	char fname[max]; 	printf("Enter your file name:\n"); 	gets(fname); 	if ((fp = fopen(fname, "r")) == NULL) 	{ 		printf("You can not open file\n"); 		exit(1); 	} 	else 	{ 		while ((ch = getc(fp)) != EOF) 		{ 			printf("%c",ch); 		} 	} 	fclose(fp); 	exit(0); } [/code]

引用 1 楼 jacksonfan 的回复:是要向文件中输入数据还是显示文件内容  显示文件内容

是要向文件中输入数据还是显示文件内容