Question: 急急急！ 老师布置的用C写一个能将TXT XYH文件转化成CASS格式的dat文件

还是显示无法找到文件  是因为我放的位置有问题  还是文件有问题啊 老师您 测试有问题吗？

#pragma warning(disable:4996) #include <stdio.h> #include <direct.h> int main() {     FILE *fi,*fo;     int c;     char ln[256];     char fin[256];     char fon[256];     double X,Y,H;     int N;     char buffer[512];      while (1) {         printf("（1）XYH文件转带编号CASS格式文件\n（2）YXH文件转带编号CASS格式文件\n（0）退出\n");         scanf("%d",&c);         if (c==0) break;         if (c==1) {             printf("请输入XYH文件的文件名和扩展名：");fflush(stdout);             rewind(stdin);             gets(fin);             printf("请输入CASS文件的文件名和扩展名：");fflush(stdout);             rewind(stdin);             gets(fon);             fi=fopen(fin,"r");             if (NULL==fi) {                 printf("找不到文件%s\\%s\n",_getcwd(buffer,512),fin);             } else {                 fo=fopen(fon,"w");                 N=1;                 while (1) {                     if (NULL==fgets(ln,256,fi)) break;                     if (3==sscanf(ln,"%lf,%lf,%lf",&X,&Y,&H)) {                         fprintf(fo,"%d,,%lg,%lg,%lg\n",N,Y,X,H);                     }                 }                 fclose(fo);                 fclose(fi);             }         }         if (c==2) {             printf("请输入YXH文件的文件名和扩展名：");fflush(stdout);             rewind(stdin);             gets(fin);             printf("请输入CASS文件的文件名和扩展名：");fflush(stdout);             rewind(stdin);             gets(fon);             fi=fopen(fin,"r");             if (NULL==fi) {                 printf("找不到文件%s\\%s\n",_getcwd(buffer,512),fin);             } else {                 fo=fopen(fon,"w");                 N=1;                 while (1) {                     if (NULL==fgets(ln,256,fi)) break;                     if (3==sscanf(ln,"%lf,%lf,%lf",&Y,&X,&H)) {                         fprintf(fo,"%d,,%lg,%lg,%lg\n",N,Y,X,H);                     }                 }                 fclose(fo);                 fclose(fi);             }         }     }     return 0; } //（1）XYH文件转带编号CASS格式文件 //（2）YXH文件转带编号CASS格式文件 //（0）退出 //1 //请输入XYH文件的文件名和扩展名：abc.txt //请输入CASS文件的文件名和扩展名：cass.dat //找不到文件C:\tmp\tmp\abc.txt //（1）XYH文件转带编号CASS格式文件 //（2）YXH文件转带编号CASS格式文件 //（0）退出 //0 //

现在的码农竟然99%都不会在cmd窗口中输入cd命令设置当前目录为程序所在目录，输入程序名运行程序了！  开始、运行、cmd、确定。 cd /d C:\Users\Administrator\Documents\Visual Studio 2012\Projects\Win32Project1\Project3\Debug Project3.exe  程序员的常识之一：不要将程序源代码或项目或exe放在桌面这种复杂（多半带空格和汉字且在防火墙或杀毒软件严密控制的C盘上）的目录下。

#pragma warning(disable:4996) #include <stdio.h> int main() {     FILE *fi,*fo;     int c;     char ln[256];     char fin[256];     char fon[256];     double X,Y,H;     int N;      while (1) {         printf("（1）XYH文件转带编号CASS格式文件\n（2）YXH文件转带编号CASS格式文件\n（0）退出\n");         scanf("%d",&c);         if (c==0) break;         if (c==1) {             printf("请输入XYH文件的文件名和扩展名：");fflush(stdout);             rewind(stdin);             gets(fin);             printf("请输入CASS文件的文件名和扩展名：");fflush(stdout);             rewind(stdin);             gets(fon);             fi=fopen(fin,"r");             if (NULL==fi) {                 printf("找不到文件%s\n",fin);             } else {                 fo=fopen(fon,"w");                 N=1;                 while (1) {                     if (NULL==fgets(ln,256,fi)) break;                     if (3==sscanf(ln,"%lf,%lf,%lf",&X,&Y,&H)) {                         fprintf(fo,"%d,,%lg,%lg,%lg\n",N,Y,X,H);                     }                 }                 fclose(fo);                 fclose(fi);             }         }         if (c==2) {             printf("请输入YXH文件的文件名和扩展名：");fflush(stdout);             rewind(stdin);             gets(fin);             printf("请输入CASS文件的文件名和扩展名：");fflush(stdout);             rewind(stdin);             gets(fon);             fi=fopen(fin,"r");             if (NULL==fi) {                 printf("找不到文件%s\n",fin);             } else {                 fo=fopen(fon,"w");                 N=1;                 while (1) {                     if (NULL==fgets(ln,256,fi)) break;                     if (3==sscanf(ln,"%lf,%lf,%lf",&Y,&X,&H)) {                         fprintf(fo,"%d,,%lg,%lg,%lg\n",N,Y,X,H);                     }                 }                 fclose(fo);                 fclose(fi);             }         }     }     return 0; }

总是显示找不到文件啊~~

你好老师 请问是放在这个位置吗？dat文件我是新建了一个空的dat文件。

引用 4 楼 qq_35581867 的回复:这只是做出了3个按钮 但是无法实现转化啊.总是显示找不到文件 我输入文件名和扩展名。 把要处理的文件拷贝到和exe相同文件夹下。

加这行到我代码最前面： #pragma warning(disable:4996)

我用我的版本复制这些代码显示了很多警告 	warning C4996: 'sscanf': This function or variable may be unsafe. Consider using sscanf_s instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. See online help for details.	c:\users\administrator\documents\visual studio 2012\projects\win32project1\project3\project3\源.cpp	28	1	Project3 这个不影响吧

仅供参考：  /* 测试文件: test1.XYH 3175915.493,596570.218,92.128 1,2,3 测试文件: test2.YXH 596570.218,3175915.493,92.128 2,1,3 用法: a.exe test1.XYH 或 a.exe test2.XYH 输出文件: cass.data 0,,3175915.493,596570.218,92.128 1,,1,2,3 */ #include <iostream> //#include <cassert> #include <fstream> #include <string> using namespace std;  typedef unsigned long DWORD; typedef long LONG;  int main(int argc, char* argv[]) { 	if(argc < 2) 	{ 		cout << "usage" << endl; 		return 0; 	} 	string fname = argv[1]; 	ifstream file; 	file.open(fname.c_str()); 	if(!file.good()) 	{ 		cerr << "open file " << fname << " error !" << endl; 		return 0; 	} 	int type = 0; 	if(fname.find(".XYH") != string::npos) 	{ 		type = 1; 	} 	else if(fname.find(".YXH") != string::npos) 	{ 		type = 2; 	} 	if(type == 0) 	{ 		cout << "unknown file type!" << endl; 		return 0; 	} 	string line; 	string x,y,h; 	int index = 0; 	string::size_type first,second; 	ofstream ofile; 	ofile.open("cass.data"); 	if(!ofile.good()) 	{ 		cout << "create file failed" << endl; 		return 0; 	} 	while(getline(file,line)) 	{ 		x.clear(); x.clear(); h.clear(); 		first = line.find_first_of(','); 		second = line.find_first_of(',',first+1); 		if(first==string::npos || second==string::npos) 			continue; 		if(type==1) 		{ 			x = line.substr(0,first); 			y = line.substr(first+1,second-first-1); 			h = line.substr(second+1); 		} 		else if(type==2) 		{ 			y = line.substr(0,first); 			x = line.substr(first+1,second-first-1); 			h = line.substr(second+1); 		} 		else 			continue; 		//cout << index << ",," << x << "," << y << "," << h << endl; 		ofile << index << ",," << x << "," << y << "," << h << endl; 		index++; 	} 	return 0; }

#include <stdio.h> int main() {     FILE *fi,*fo;     int c;     char ln[256];     char fin[256];     char fon[256];     double X,Y,H;     int N;      while (1) {         printf("（1）XYH文件转带编号CASS格式文件\n（2）YXH文件转带编号CASS格式文件\n（0）退出\n");         scanf("%d",&c);         if (c==0) break;         if (c==1) {             printf("请输入XYH文件的文件名和扩展名：");fflush(stdout);             gets(fin);             printf("请输入CASS文件的文件名和扩展名：");fflush(stdout);             gets(fon);             fi=fopen(fin,"r");             if (NULL==fi) {                 printf("找不到文件%s\n",fin);             } else {                 fo=fopen(fon,"w");                 N=1;                 while (1) {                     if (NULL==fgets(ln,256,fi)) break;                     if (3==sscanf(ln,"%lf,%lf,%lf",&X,&Y,&H)) {                         fprintf(fo,"%d,,%lg,%lg,%lg\n",N,Y,X,H);                     }                 }                 fclose(fo);                 fclose(fi);             }         }         if (c==2) {             printf("请输入YXH文件的文件名和扩展名：");fflush(stdout);             gets(fin);             printf("请输入CASS文件的文件名和扩展名：");fflush(stdout);             gets(fon);             fi=fopen(fin,"r");             if (NULL==fi) {                 printf("找不到文件%s\n",fin);             } else {                 fo=fopen(fon,"w");                 N=1;                 while (1) {                     if (NULL==fgets(ln,256,fi)) break;                     if (3==sscanf(ln,"%lf,%lf,%lf",&Y,&X,&H)) {                         fprintf(fo,"%d,,%lg,%lg,%lg\n",N,Y,X,H);                     }                 }                 fclose(fo);                 fclose(fi);             }         }     }     return 0; }


Question: 请教wscanf 格式化中文字符乱码怎么解决?

完全理解得费些功夫，涉及到字符集、编码方式、unicode等等概念。 setlocale函数的链接如下： https://msdn.microsoft.com/en-us/library/x99tb11d.aspx

引用感谢楼下继续帮我解决这个问题 先给出解决方案，在main函数的第一行：  #include <locale.h>  //头文件 setlocale (LC_ALL,""); //添加到main函数的第一行  原因是因为执行字符集和控制台字符集必须保持一致(GBK)。 代码中setlocale (LC_ALL,"");的作用是将执行字符集与操作系统的字符集设置成一样。  更详细的原因请查询相关资料，可以从setlocale函数入手：

http://www.cnblogs.com/dejavu/archive/2012/09/16/2687586.html 这个可以作为到此一游的纪念了!结贴!!

ok,问题终于解决了,感谢fight_in_dl的解决方法,我只知道是编码问题,没方法解决.刚才有在csdn上找到了一个例子,再次感谢所有围观的各位!!

对电脑而言没有乱码，只有二进制字节；对人脑才有乱码。啊 GBK:0xB0 0xA1,Unicode-16 LE:0x4A 0x55,Unicode-16 BE:0x55 0x4A,UTF-8:0xE5 0x95 0x8A

百度了一通,好像跟代码页没什么关系! 2楼请注意,pe32得到的文件名是正常的,控制台输入的得到不正常,所以比较的时候就出问题了? 继续求解!感谢楼下继续帮我解决这个问题.

是Unicode的编码，所以是乱码

1，控制台的字符格式默认不是utf-8的，所以wscanf读入的中文是乱码 2，wprintf没有问题，比如控制台的字符格式是A，wscanf是按照A格式读入的，wprintf也是按照A格式输出的，所以其没问题 chcp可以修改控制台字符格式，详情请自行搜索

main换成wmain


Question: 请教哪里有问题

字符串中的字符和十六进制数据值是不能意义对应的。 建议使用sscanf和sprintf对字符串和16进制数据进行转换

每次赋值与上0xff.    ch2[i] = ch[i]&0xff.

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

引用就会异常 没看到代码，不好说具体原因。  有几个地方提醒楼主注意： 1  char 有signed char 和 unsigned char。     不能保证这些十六进制数能对应期望的值。 2  %x打印的是数组第一个元素的地址，如果想打印某个元素的值，以下是范例：          unsigned char arr[8];     printf("0x%x", arr[5]);  //打印第6个元素


Question: inRec.EventType == MOUSE_EVENT 总是不成立

谢谢大神指点，困扰几天的问题得到解决啦

引用求解答  请参考：  http://ask.csdn.net/questions/381133  这是我之前的一个回答，应该和这个问题相似。

关闭快速编辑模式。

引用困扰几天的问题得到解决啦  不客气，共同进步。 能结题散分吗，论坛有采纳率的指标，谢谢！


Question: 各位大大能给小弟看看吗？

是不是malloc的空间太小了，malloc(10*n*sizeof(int))

引用 1 楼 T20091 的回复:int *buf=(int *)malloc(10*n); int *buf1=(int *)malloc(n);   一个int占四个字节，分配的空间有问题，你这代码准确来说是会crash的。 int *buf=(int *)malloc(10*n*sizeof(int)); int *buf1=(int *)malloc(n*sizeof(int)); 恍然大悟，谢谢！！


Question: zzuliOj 1178

#include <stdio.h> #include <stdlib.h> #include <string.h>   typedef struct word {     char str[32]; } W;   typedef struct words {     char word[32];     int cnt; }WORD;  int get_words(W *word_list, int max_num, char *sentence);  static W p[1001]; static int gword_num;  int main() {     char str1[32];     int count = 0;      memset(p,'\0',sizeof(p));     while(strcmp((gets(str1)), "#") != 0)     {         count = get_words(p, 1001, str1);         /*            i=0;            count=0;            k=0;            while(str1[i]!='\0')            {            j=0;            while(str1[i] == ' ')            i++;            for( ; str1[i] != ' ' && str1[i] !='\0'; i++)            {            p[k].str[j++]=str1[i];            }            for(j=0; j<k; j++)            {            if(strcmp( p[k].str, p[j].str)==0)            {            count--;            break;             }            }            count++;            k++;            while(str1[i]==' ')            i++;             }            */          printf("%d\n",count);     }     printf("%d\n",count);      return 0; }   int get_words(W *word_list, int max_num, char *sentence) {     int i = 0, j = 0, k;     int flag = 0;     char tmp[32];      while (sentence[i] == ' ')         i++;      for ( ; sentence[i] && sentence[i] != '\n'; i++) {         if (sentence[i] != ' ' && sentence[i] != ','                 && sentence[i] != '!' && sentence[i] != '.') {             tmp[j++] = sentence[i];         } else if (j >= 1) {             tmp[j] = 0;             for (k = 0; k < max_num && strlen(word_list[k].str) > 0; k++) {                 if (strcmp(word_list[k].str, tmp) == 0) {                     flag = 1;                     break;                 }             }             if (flag == 0) {                 strcpy(word_list[k].str, tmp);                 gword_num++;             }             j = 0;             flag = 0;         }     }     if (j >= 1) {         tmp[j] = 0;     }     for (k = 0; k < max_num && strlen(word_list[k].str) > 0; k++) {         if (strcmp(word_list[k].str, tmp) == 0) {             flag = 1;             break;         }     }     if (flag == 0) {         strcpy(word_list[k].str, tmp);         gword_num++;     }      return gword_num; } 做了一个参考吧

引用 2 楼 zhao4zhong1 的回复:static W p[1001]; 在占用内存空间较大的局部数组声明的前面加static将其从堆栈数据段挪到全局数据段即可避开因局部数组大小超过默认堆栈大小1MB造成程序不能正常运行的问题。 为啥不加个标点符号呢，但我能大概看懂了

发现问题了，谢谢你们，内存申请的不够

帮帮忙吧，实在看不出来才求助的


Question: 关于数组下标问题

其实电脑开机后物理内存的每个字节中都有值且都是可读写的，从来不会因为所谓的new、delete或malloc、free而被创建、销毁。区别仅在于操作系统内存管理模块在你读写时是否能发现并是否采取相应动作而已。操作系统管理内存的粒度不是字节而是页，一页通常为4KB。  “多一少一”问题占程序员常犯错误的10%以上！ 避免“多一少一”问题的方法之一是将比如<10甚至<5的数代入程序片断，掰手指头心算验证一下程序到底应该写为 x、x-1、x+1中的哪个？ <、<=、==、>、>=中的哪个？

下标都是从0开始的，如果你确实想从1开始，即下标为0的元素不使用，也是可以，那就是定义a[11]，下标从1～10的都可以使用。

你可以定义一个宏来实现不建议.

不能，规定就是从0开始。越界的话，轻者数据访问错误，重者应用崩溃，不能越界访问

不能

引用后果是什么  推荐参考这篇博客，阐述了这么做的一些弊端。 引用http://c.biancheng.net/cpp/html/1600.html  再补充我个人的一些理解: 下标表示的是该元素对首元素的偏移，第一个元素没有偏移，所以下标为0  c/c++中数组运算本质上是指针运算。 当下标从0开始，*(a+n)就可引用到a[n] 当下标从1开始，则*(a+n-1)才能引用到a[n] 前者更好。  随着编程学习的深入，会逐渐体会到下标从0开始更合理。


百度搜相关关键字。


Question: C语言疑惑的地方

5是一个常量，所以返回的是5这个常量的指针，常量指针不会变，所以可以输出5

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

引用 楼主 qq_39545013 的回复:int *name() {  int  *s=5;     //这步会出错，将int型赋给int* 类型，要强转，不然编译不通过  return s; } main() {  int *a=name();  printf("%d\n",s); } 为什么输出还是5，*s不应该是在栈区的吗，函数结束后，内存就没了呀。  其它没毛病

虽然是在堆栈中，堆栈是没有了，但是指针绝对在（也就是内存地址是不会跟着堆栈消失的），里面的数据你没有清空，内存中就会一直保存。 如果你的s是一个基本变量，这样就行不通了。

先不辨别楼主的问题，首先，你的程序肯定是有问题的，编译都通不过吧。怎么会有正确值呢。 修改如下： int *name() {  int  *s=5;  return s; } main() {  int *a=name();  printf("%d\n", a); } 然后，讨论这个问题； name函数中，s是指针，将5赋值给s就是，s指针变量里存放的值是5，即s指针指向内存单元中地址为5单元（可能是虚拟地址）。然后将s返回（返回的是s内存单元里的值5）。main函数中将该值又赋值给变量a，然后输出变量a的值。这样没什么问题。跟栈有关系的就是变量s, a但是return返回的是值。

引用内存就没了 int *name() {  int  *s=5; //这行会报错，等式左右两边类型不符  return s; } main() {  int *a=name();  printf("%d\n",s); //这行会报错,s在main函数中没有定义。 }  代码是有问题的，不知道是不是粘贴错了，请再检查一下。

如果真确，也是偶然

这个代码好奇怪哦，能通过编译吗？

main函数里哪来的s,直接就报错不运行的......

直接就在 int * s =5 就报错了

int *name() {  int  *s=5;/////////// 编译能过吗  return s; } main() {  int *a=name();  printf("%d\n",s); /////////////  s哪来的 }   这样的代码还能运行，深表怀疑，能编译成功吗

这种方式是很危险的，int  *s=5; 准确来说这个会crash的。 刚好返回的这个指针指向内存能访问，所以某次是没有问题。 还有你确定main里面的printf是没打错？

你是直接向指针赋值一个整数，然后指针又向指针赋值，所以指针a的值当然就是5啦

兄弟们解释一下


Question: 如代码所示，连续运行‘b’，‘c’程序出现崩溃，但是单步执行程序却不出现崩溃现象

是排序有问题，但是我单步调试发现没问题，也不知道错在哪，而且单步调试可以运行但是一运行就崩溃

重点看一下你的排序，排序有问题。

不太懂，，可以说详细点吗?小白一枚，。。。

判断是否越界访问，可以在数组的最后一个元素之后对应的地址处设置数据读写断点。如果该地址对应其它变量干扰判断，可将数组多声明一个元素，并设置数据读写断点在该多出元素对应的地址上。 #include <time.h> #include <stdlib.h> #include <windows.h> int main() {     int a,b[11];//本来是b[10]，为判断哪句越界，故意声明为b[11]      srand((unsigned int)time(NULL));//按两次F11，等黄色右箭头指向本行时，调试、新建断点、新建数据断点，地址：&b[10]，字节计数：4，确定。     while (1) {//按F5，会停在下面某句，此时a的值为10，b[10]已经被修改为对应0..4之一。         b[(a=rand()%11)]=0;         Sleep(100);         b[(a=rand()%11)]=1;         Sleep(100);         b[(a=rand()%11)]=2;         Sleep(100);         b[(a=rand()%11)]=3;         Sleep(100);         b[(a=rand()%11)]=4;         Sleep(100);     }     return 0; }


Question: 关于return 0返回成对的值还是任意值

看你程序本身是如何设计的 返回0表示成功一般的情况是，有多种类型错误，比如1，2，3……（-1，-2，-3……）分别代表某种类型错误 当程序只要求判断成功那么使用 ！取反操作符即可  你认为的仅仅只是成功和失败（不细分）两种情况就返回0，1，这样子也是没有问题的 C++的话更清晰明了的做法是直接返回bool类型 C可以选择TRUE宏和FALSE宏替代（很多程序通常的做法）  以此开始延伸，当你返回int的时候用某个具体值代表失败，考虑如下代码： if(func() == 1) //此处用1来代表失败     return; 假如某天你扩展了你的func函数，你想更细分你的错误类型，诸如加入2，3等 那么你此处的代码必须进行更新  得出结论：判断不成功最好的方式就是 if(!func())  而要判断具体错误，那就使用具体代码（也可以用定义好的宏来比较）  这是一个设计观念的差异而已 Win32接口绝大多数函数返回值就是使用此设计方式。

如果只是针对return返回值，那么返回什么数据，什么类型跟函数定义的返回类型有关。 对于是返回0标识成功，还是返回1，这个没有严格的标准，再说C/C++语言也不会限制这么死。

引用return 0返回的值是确定的一对整数  return 关键字的作用是从函数中返回一个值，这个值紧跟在 return 后面。 return 0； 如果放在一般函数里，就是指返回0。  需要特别注意的是 return 0；在main函数中的情况。 main函数 必须 返回0 (EXIT_SUCCESS宏) 来表明程序运行正常，返回 EXIT_FAILURE宏来表明程序运行异常。 与EXIT_SUCCESS宏 一定是0不同，C标准并没有明确EXIT_FAILURE宏应该定义成多少，而是交给编译器厂商自行实现。 通常 是 1，注意只是通常为1 ，不是一定为1 。  大多数情况下，比如平时编译学习时，我们并不用关心这个EXIT_FAILURE到底是1还是多少。 main函数的返回值是给调用它的进程(shell)使用，如果你想感性的知道这个值的大小，方法如下：  //你可以设计错误和正确的情况来对比体会 @echo off YOUR.EXE  //调用你的程序 SET /a retVar=%errorlevel%  ECHO %retVar%   还有一个可能，你需要在main函数中自己区分返回错误的类型，这种情况下，你自己定义返回值和类型的对应关系即可。 但记住仍然不要破坏 0 代表成功执行main函数。


Question: 请教char类型数组循环赋值？

#include <stdio.h>  int main() { 	char buffer[512] = { 0 };     //控制台的输入缓冲区 	char *dest[512] = { 0 };		//分割出来的字符串存放的位置  	char seps[] = " ,\t\n";			//分割符数组 	char *token = NULL;					//看msdn 	 	int i = 0;  	scanf("%[^\n]", buffer);        //看msdn  谁说输入看到空格就切断了??  	//printf("输入的字符串为:%s\n", buffer);   //你可以测试一下看看,是不是空格后面的不接受了  	//以下是从mdsn  strtok 函数的实例拷贝过来的, 	//只是加了一个分割出来的字符串存入desk指针数组中, 	//稍加改进还可以循环scanf  	token = (char*)strtok(buffer, seps);  	while (NULL != token) 	{ 		dest[i] = token; 		printf(" %s\n", dest[i]); 		i++; 		token = strtok(NULL, seps); 	} 	system("pause");  	return 0; }     花了一点时间调试了一下 ,应该可以满足你的要求.

引用 2 楼 jianwen0529 的回复:试试如下代码（手打，未经过测试）：  char ch; int index = 0; while(scanf("%c, ch))     if(ch != ' ' && ch != '\n' && ch != '\0')          str[index++] = ch;  修正 while(scanf("%c, &ch))

如果你是控制台输入的话,可以试一下scanf函数

引用 3 楼 jianwen0529 的回复:[quote=引用 2 楼 jianwen0529 的回复:] 试试如下代码（手打，未经过测试）：  char ch; int index = 0; while(scanf("%c, ch))     if(ch != ' ' && ch != '\n' && ch != '\0')          str[index++] = ch;  修正 while(scanf("%c, &ch))[/quote] 还需再修正一下才能去掉语法错误。  楼主，以下是个人的方法：  #include <stdio.h> #include <ctype.h>  int main(void) {     int ch, i = 0;     char str[32];      while ((ch = getchar()) != '\n')         if (isalpha(ch))             str[i++] = ch;      str[i] = 0;      puts(str);      return 0; }

引用对一个字符数组进行循环赋值  int main() { 	char str[6] = { 0 }; //定义字符数组大小为6 	char ch; 	int i = 0; 	while (true) 	{ 		ch = getchar(); 		if (ch!=' ') 		{ 			str[i] = ch; 			i = i + 1; 		} 		if (i>5 || ch=='\n') //保证只接收6个字符 		{ 			break; 		} 	} 	for (int j = 0; j < 6;j++) //测试结果 	{ 		printf("%c\n",str[j]); 	} 	return 0; }


Question: C语言调用系统WMI 的API在dll中怎么找不到

照我说的做了以后自有体会，

引用程序调用WMI  要调用WMI中的函数，从大的方面来说分为两步： 1. 获得iwbemservices服务接口 2. 调用接口提供的ExecQuery 和常规调用动态链接库中的函数相比，写法差别比较大，可以参考 https://msdn.microsoft.com/en-us/library/aa390423(v=vs.85).aspx  文档提供了完整例子，虽然是英文，但有详细的步骤，希望对您有帮助。  补充：在很多问题中看到赵四老师这样回答问题，这种泛泛的回答省时省力，还能经常混到分。            但对问题的实质性解决能有多少推动呢？

学会使用 OleView.exe 和 WinAPIOverride http://jacquelin.potier.free.fr/winapioverride32/

引用 1 楼 wyyy2088511 的回复:看看<Windows核心编程>中LoadLibrary。 你会拿那个地址吗？

引用 2 楼 DelphiGuy 的回复:因为导出的是COM接口对象，不是函数API。  那我想拿这个地址还有可能吗？具体该怎么拿呢？多谢啦

因为导出的是COM接口对象，不是函数API。

看看<Windows核心编程>中LoadLibrary。


Question: 关于监视窗口的问题

引用 2 楼 cfjtaishan 的回复:描述一下a这个奇怪的值是什么？随机值？ 定义一个局部变量时，若定义时不赋值，则会a变量的内存空间里是一个随机值；你好，谢谢您，通过调试我发现 所监视的只是 当前帧所在模块的某个 名字，而不是我所要监视的变量

引用 2 楼 cfjtaishan 的回复:描述一下a这个奇怪的值是什么？随机值？ 定义一个局部变量时，若定义时不赋值，则会a变量的内存空间里是一个随机值； 引用 1 楼 fight_in_dl 的回复:引用在监视什么？   用{}包含的代码称为代码块，在代码块中定义的变量是块的局部变量，其生存周期从定义开始一直到退出块。 这里注意，当进入里层代码块后，a会变成5，隐藏了外部块同名的a变量。  说了这么多，还是实际上机测试一下体会更深，修改代码如下：  int main() { 	{ 		int a; 		a = 6; //刚开始把断点设到这行，然后分步调试，在监视窗口中就能观察到a的变化 		printf("first a is %d\n", a); 		{ 			int a; 			a = 5; 			printf("second a is %d\n", a); 		} 	} 	return 0; } 同时可以在控制台窗口看一下程序运行结果。  你好，很感谢，很久才看到回复，我自己测试知道监视窗口只是监视当前帧所在语句块的 所要监视的“变量名字"的值，而不是我想要监视的变量。当时不明白这个原理，

不要依赖调试器输出复杂数据结构！而要将复杂数据结构的整个内容在处理它的每一步使用一小段代码按自己很容易理解的格式输出，非常有助于调试！或者可以说是“基础设施”

看不懂，这难道不会重定义


Question: 一直在纠结if((mikfifo(FIFO_SERVER,O_CREAT|O_EXCL|O+RDWR)<0&&(errno!=EEXIST))的作用，求大神解惑

&&是 逻辑与 运算符。 只有当&&左右两侧的逻辑表达式结果都为真时，整个逻辑表达式的结果才为真。  题目中：  //mikfifo应该是一个函数，当函数的返回值小于0，下面这个表达式的结果为真 mikfifo(FIFO_SERVER,O_CREAT|O_EXCL|O+RDWR)<0  如果同时再满足 errno!=EEXIST，那么if判断条件就为真，可以执行这个if分支中的语句。


Question: 删除字符数组中的重复字符

#include<stdio.h> #include<string.h>  int main() {     int i, j, k, len;     char str[50];     int ch;      printf("Please input string:");     scanf("%[^\n]",str);     char *p = str;     len = strlen(str);      for (i = 0; i < len; i++) {         ch = p[i];         for (j = i+1; j < len; j++)             if (ch == p[j]) {                 for (k = j; k < len; k++)                     p[k] = p[k+1];             }     }      puts(p);     printf("%s\n",str);     #if 0       for(i = 0;i < k;i++)     {         for(j = i + 1;j < k;j++)         {             if(*(p+i) == *(p+j))             {                 *(p+j) = *(p + j + 1);                 k--;                 j--;                 i--;             }         }     }     str[k] = '\0';     printf("%s\n",str); #endif     return 0; } i, j , k一般用于循环变量；一般被定义为int类型

可以把不重复的字符另外放到一个数组中。

如果只是ascii字符，可以试一下下面的代码。  #include<stdio.h> #include<string.h> int main() { char str[50]="f4gg2gjkll2k*))kg  7i7nhjt"; char strOut[50]; int flg[8],i,r,c,k; memset(flg,0,32); k=0; for(i=0;str[i]!='\0';++i) {    r=str[i]/32;    c=str[i]%32;    if((flg[r] & (1<<c))==0)    {        flg[r] |= (1<<c);        strOut[k]=str[i];       ++k;    } }  strOut[k]='\0'; printf("%s\n%s\n",str,strOut);   return 0; }

挑剔的说这个题目出的有问题 比如 abdefa 去除重复后 到底是 abdef 还是 bdefa

引用求解答  代码基本上不用变动，就是里层循环的写法有变化，如下： 不算复杂，就不加注释了，希望有帮助。  int main() { 	char str[50]; 	int i, j, k, n; 	printf("Please input string:"); 	scanf("%[^\n]", str); 	char *p = str; 	k = strlen(str); 	for (i = 0; i < k; i++) 	{ 		for (j = i + 1; j < k; ) 		{ 			if (*(p + j) == *(p + i)) 			{ 				for (n = j; n < k; n++) 				{ 					str[n] = str[n + 1]; 				} 				k--; 			} 			else { 				j++; 			} 		} 	} 	str[k] = '\0'; 	printf("%s\n", str); 	return 0; }


Question: 关于C/C++缓冲区的问题

引用 1 楼 jianwen0529 的回复:char str[32] = "hello world!";  呃呃，我原本的程序是for循环printf  引用 3 楼 wyyy2088511 的回复:调用完setvbuf，不调用fflush  非常感谢！

调用完setvbuf，不调用fflush

setvbuf

char str[32] = "hello world!";


Question: 求大神指点迷津，敢问小弟的程序错哪儿了

当然可以，数组只不过是相同类型的分配空间，而指针可以是任意空间，可以把数组比作是一个特殊的指针。

谢谢，各位大神的指点，这个题，用数组做我已经做出来了，但是我想知道一下，用指针应该怎样做，所以才提出了以上疑问，请问，我的程序用指针的方法能完成吗？

#include<stdio.h> #include<string.h>  #define M 150  void Sortstring(char *p[], int n);  int main() {     int n, i;     char pl[M][M] = {};     char *pstr[M] = { NULL };     printf("How many countries?");     scanf("%d", &n);     getchar();     printf("Input there numbers:\n");     for (i = 0; i < n; i++)     {         gets(pl[i]);         pstr[i] = pl[i];     }      Sortstring(pstr, n);     printf("Sorted results:\n");     for (i = 0; i < n; i++)     {         puts(pl[i]);     }     return 0; } void Sortstring(char *p[], int n) {     int i, j;     char temp[M];     for (i = 0; i < n - 1; i++)     {         for (j = 0; j < n - i - 1; j++)         {             if (strcmp(p[j], p[j+1]) < 0)             {                 strcpy(temp, p[j]);                 strcpy(p[j], p[j+1]);                 strcpy(p[j+1], temp);             }         }     } } 排序是有问题的，并且参数类型也不匹配。 以上是修改后的代码～

#include<stdio.h> #include<string.h> #define M 150 void Sortstring(char p[M][M],int n); int main() {     int n, i;     char pl[M][M];     printf("How many countries?");     scanf("%d", &n);     getchar();     printf("Input there numbers:\n");     for (i = 0; i < n; i++)     {         gets(pl[i]);     }     Sortstring(pl,n);     printf("Sorted results:\n");     for (i = 0; i < n; i++)     {         puts(pl[i]);     }     return 0; } void Sortstring(char p[M][M],int n) {     int i, j;     char temp[M];     for (i = 0; i < n - 1; i++)     {         for (j = i; j < n; j++)         {             if (strcmp(p[j], p[i]) < 0)             {                 strncpy(temp,p[i],M);                 strncpy(p[i],p[j],M);                 strncpy(p[j],temp,M);             }         }     } }

数组作为函数参数会自动转换为指针，我试了传参时候直接强制转换，程序会崩溃。

是指针的问题吗？大神们


Question: 为什么这个算法计算范围这么小？

哦哦，可以了，，，那当时应该不是程序的问题。

不对呀，为什么我的编译器1.5根本给不出答案。

引用输入1.5的时候就出错了   测试是正确的，注意1.5的单位是弧度，不是度。

输入1.5的时候就出错了

浮点数格式 http://bbs.csdn.net/topics/390676437

楼主想表达什么意思，这应该是计算sin的程序吧？输入的是角度，以rad为单位的角度。输入3.14，sinpi接近0，输入1.57,结果接近1，并没有错误啊？


Question: C语言控制台鼠标事件

console屏幕处理例子程序。终端窗口屏幕处理相关API使用例子。来自MSVC20\SAMPLES\win32\console\ http://download.csdn.net/detail/zhao4zhong1/3461309  将快捷方式属性中的快速编辑模式关掉再试试。

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


Question: C语言删除一个长字符串中出现的短字符串问题

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

看我的博客：实现你需要的功能：http://blog.csdn.net/sinat_26448309/article/details/76084620

仅供参考：#include <stdio.h> #include <string.h> char s[256]; char *p; int r,n,i; int main() {     while (1) {         printf("请输入一行文字(空行结束),\"%%20\"将替换为\" \",\"你懂得\"将替换为\"XXXXXX\":\n");         fgets(s,256,stdin);         if ('\n'==s[0]) break;         p=s;         while (1) {             p=strstr(p,"%20");             if (p) {                 memmove(p+1,p+3,strlen(p)-3+1);                 p[0]=' ';             } else break;         }         p=s;         while (1) {             p=strstr(p,"你懂得");             if (p) {                 memmove(p+6,p+6,strlen(p)-6+1);                 for (i=0;i<6;i++) p[i]='X';             } else break;         }         printf("%s",s);     }     return 0; } //请输入一行文字(空行结束),"%20"将替换为" ","你懂得"将替换为"XXXXXX": //abcdefg%20helloworld%20something.pdf //abcdefg helloworld something.pdf //请输入一行文字(空行结束),"%20"将替换为" ","你懂得"将替换为"XXXXXX": //这是测试文字你懂得，在这个你懂的地方，就得做你懂得的事 //这是测试文字XXXXX，在这个你懂的地方，就得做XXXXX的事 //请输入一行文字(空行结束),"%20"将替换为" ","你懂得"将替换为"XXXXXX": //

上面我的代码有问题

上面代码有问题。

#include <stdio.h> #include <string.h> #include <math.h>  int del_substr(char *str, const char *substr) {      int len = strlen(str), len_sub = strlen(substr);     int i, j, k, ok;      ok = 0;     if(len >= len_sub) {         for(i = 0; i < len && ok != 1;) {             j = 0;             if(str[i] == substr[0]) {                 for(; j < len_sub; ++j)                     if(str[i+j] != substr[j])                         break;             }             if (j >= len_sub)                 ok = 1;             if(ok) {                 j = i;                 for(k = i + len_sub; k < len; ++k)                     str[j++] = str[k];                 str[j] = 0;                 printf("%s\n", str);                 ok = 0;             } else {                 i++;             }         }     }      return ok; }  int main(void) {      char str[100] = "asdfsdgsdhsdg";     char substr[100] = "sdg";     //char str[100] = "worldhelloworldhelloworld";     //char substr[100] = "world";     printf("%d\n", del_substr(str, substr));     return 0;  } 以上是我修改后的代码； 逻辑有点问题，从你的逻辑上看只删除了第一次遇到字串而没有将后面所有字串删除。

#include <stdio.h> #include <string.h> #include <math.h> #include <stdlib.h> char *del_substr(char *str, const char *substr) { 	int len = strlen(str), len_sub = strlen(substr), i, j,k,m;     if(len >= len_sub) 	{  		for(i=0,j=0;i<len;) 		{ 			if(str[i]==substr[0]) 			{ 				for(k=i,m=0;str[k]==substr[m];k++,m++); 				if(!substr[m]) i+=len_sub; 			} 			str[j++]=str[i++]; 		} 	} 	if(i==len) 		str[j]='\0';     return str;  }     int main()  {     char str[100] = "asdfsdgsdhsdg";     char substr[100] = "sdg";     printf("%s\n", del_substr(str, substr)); 	system("pause");     return 0;  }  //你的代码功能是去除一次


Question: 请问怎样实现这个功能？

这只是显示效果而已，需要与界面库相关，这样才能更好的思想数据与界面的联系

引用 2 楼 ccssddnn218 的回复:1. 定义一个链表(list)表示一篇文章，链表中的元素表示一个文字或字符。 2. “按一下退格键”后，删除对应的文字元素。 3. 遍历链表中的所有元素，得到最新的文章。  创建一个双向链表，在1.2中间加一步    如果按下方向键链表的指针移动一格 按下退格键将链表的内存单元删除，我觉得应该是  这样的

楼主不是说要删除中间的字符吗，我觉得可以在加上一段……、、 如果按下左右方向键，链表指针移动一个


Question: 求助！！！如何用c语言将点阵化为方格阵

你的意思是不是由点来确定区域？？

引用 6 楼 hdt 的回复:最大的x,y坐标为4，最小的为0 所以应该是一个5X5矩阵吧？ 还是我没明白你的意思 请把题目讲清楚 不是的，x,y是从0到4一共五个坐标点，但是每个方格的上下、左右各需要两个点来确定，所以是个4X4的。 问题就是我说的那样啊，给了一个邻边全都相互垂直的多边形的各顶点坐标，然后把它化成一个方格阵啊

判断每个正方形中心点，是否在你的区域内 可以使用射线法

引用 8 楼 qq_36409192 的回复:你的意思是不是由点来确定区域？？ 是

有人吗？？求助 ，万分感谢！！

引用 4 楼 wyyy2088511 的回复:#include <stdio.h> #include <stdlib.h> #include <time.h>  int main () { 	int data[4][4] = 	{{0,0,1,0}, 	{0,0,1,1}, 	{1,1,1,1}, 	{1,1,1,1}}; 	for(int i=0; i<4; i++) 	{ 		for(int j=0; j<4; j++) 		{ 			if(data[i][j]) 			{ 				printf("口"); 			} 			else 			{ 				printf("  "); 			} 		} 		printf("\n"); 	} 	system("pause"); 	return(0); }   不是吧  你好像没明白我的意思

图片倒过来了。。。发一张正的


Question: c语言读写文件问题

凡字符处理就要考虑字符集 写入和读取的字符集要一致， 比如写入用Unicode，读取也得Unicode， 否则就是乱码

不要迷信书、考题、老师、回帖； 要迷信CPU、编译器、调试器、运行结果。 并请结合“盲人摸太阳”和“驾船出海时一定只带一个指南针。”加以理解。 任何理论、权威、传说、真理、标准、解释、想象、知识……都比不上摆在眼前的事实！  对电脑而言没有乱码，只有二进制字节；对人脑才有乱码。啊 GBK:0xB0 0xA1,Unicode-16 LE:0x4A 0x55,Unicode-16 BE:0x55 0x4A,UTF-8:0xE5 0x95 0x8A

fscanf/fprintf是格式化读写文件，所以跟你的写入的是格式化的，所以建议读取时使用fscanf 不一定使用C写的文件，必须用C来读；这个不是必须的。

那我怎么读取的都是乱码，我是要读取到结构体的。我用fpintf写入才不会错。

不是编译器，是编辑器，打错一个字~

读和写是独立的两个过程。  对于读文件这个操作来说，它并不关心文件是怎么生成的，由C语言写入也好，fprint写入也好，在编译器中人工输入然后保存也好。 最终的结果都是硬盘上的一个文件，更具体说就是一些二进制序列。


Question: windbg如何调试会读取文件的程序？

ctrl + E 打开可执行文件时修改start directory即可

可是test.txt是跟代码放在同一目录下

根据代码的路径，你的test.txt应该放在和可执行文件在同一路径下~~


Question: C语言double 型数组转short

已经解决了，举的这个例子有点问题，哈哈，不过还是谢谢你

#include "stdio.h" #include "stdlib.h"  int main() {     int i,j;     short *T;     double **X;     X = (double **)malloc( sizeof(double*) * 10000);      for(i=0;i<10000;i++)     {         X[i] = (double *)malloc(sizeof(double) * 2);    /*申请第二维的空间*/         for(j=0;j<2;j++)         {             X[i][j] = -0.003+0.2*(j+1);         }     }     T = (short *)malloc( sizeof(short) * 10000);      for(i=0;i<10000;i++)     {         T[i] = (short)(X[i][0]*3000);     }      for(i=0;i<10000;i++)     {         printf("%d", T[i]);         printf("\n");     }      for(i=0;i<10000;i++)    /*释放注意循环释放，因为是循环申请的*/         free(X[i]);     free(X);     X = NULL;     free(T);     T = NULL;      return 0; } 详见上面的代码


Question: 这段代码对于a数组的输出已经溢出，只能输出8个a但为何输出可以超出了8个。

赋写了其他内存而已，很危险的事情。编译器不坚持数组越界，这需要程序员自己来保证

越界了，但是后面的内存是可以使用的，但是不是每次都能这么幸运。所以，这样的代码是带着潜在bug的。


Question: 问个char*[]的问题？！

现在的问题就是怎么传一个char*[]的参数，在函数里给它赋值，在函数外可以使用

是传参不对吗 std::string s = XX[index]; //XX是在哪里定义的? 问题描述不太清楚，只能靠猜。 如果是想将string转化为char*，可以参考如下代码：  std::string str = "string"; char *cstr = new char[str.length() + 1]; strcpy(cstr, str.c_str()); //其它代码 delete [] cstr; //记得释放动态申请的内存

list[index] = (char*)s.c_str(); s是局部变量，语句块结束会释放内存。而且你的list[index]并没有分配内存  list是数组指针，请使用类似用法： char* list[30]; for(int i = 0; i < 30; i++)     list[i] = new char[32]; strcpy(list[0], "a"); strcpy(list[1], "b"); strcpy(list[2], "cd");

你这代码贴的相当乱啊。  for( int index;index<size;index++ )   // index未初始化，而且仅在for循环中有效，你确定for后边那个 list[index] = `\0`;可以编译通过？

XX是局部变量吗？建议你将完整代码贴出来


Question: 初学者 求大神帮忙看下哪里有问题  编译是没错 运行时候提示有错误

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

注意其他问题，详见下面的代码，对比一下吧，指针的基础还待加强！ #include<stdio.h>      void jiao(int *);     void shuchu(int *);  int main() {     int a[10],i,*p;     for (i=0;i<10;i++)         scanf("%d", &a[i]);     p=a;     shuchu(p);     jiao(p);     shuchu(p);     return(0); }  void jiao(int *o) {     int *z,*m,s,d;     z = o, m = o;     int i = 0;     printf("%p ", o);     printf("%p ", o+9);     printf("%p ", ++o);     for(;o <= z + 9; o++)     {         printf("i = %d\n", i);         if(*z > *o)         {             s=*z;             *z=*o;             *o=s;         }         if(*m < *o)         {             d=*m;             *m=*o;             *o=d;         }         i++;     } } void shuchu(int *n) {     int t;     for(t=0;t<10;t++)     {         printf("%d ",*n);         n = n+1;     }     putchar(10); }

#include<stdio.h>      void jiao(int *);     void shuchu(int *);  int main() {     int a[10],i,*p;     for (i=0;i<10;i++)         scanf("%d", &a[i]);     p=a;     shuchu(p);     jiao(p);     shuchu(p);     return(0); }  void jiao(int *o) {     int *z,*m,s,d;     z = o, m = o;     int i = 0;     printf("%p ", o);     printf("%p ", o+9);     printf("%p ", ++o);     for(;o <= z + 9; o++)     {         printf("i = %d\n", i);         if(*z > *o)         {             s=*z;             *z=*o;             *o=s;         }         if(*m < *o)         {             d=*m;             *m=*o;             *o=d;         }         i++;     } } void shuchu(int *n) {     int t;     for(t=0;t<10;t++)     {         printf("%d ",*n);         n = n+1;     }     putchar(10); } jiao函数里，o是变化的，那么o <= o + 9;是也是跟着变化的。这样就是一个死循环，直到栈越界。

scanf("%d",&b); a[i]=b; 绕路  scanf("%d",&a[i]);  调试程序有三个阶段，编译，链接。运行。你的错误信息是链接错误，发生在程序链接时，此时程序还没有被指行。

jiao(*p);，定义的是void jiao(int *o)，把a【0】的值赋值给jiao的指针，所以错误直接jiao（p）。

void jiao(int);--------void jiao(int *o) void shuchu(int);----------void shuchu(int *n) 参数应一致，不然，编译器认为是两个函数，这样，一个函数未定义，一个函数未声明。 另外，你应该把代码实现什么目的写出来，如此，你提问的水平就达到了正常的水平了

#include<stdio.h> main() { 	void jiao(int); 	int shuchu(int); 	int a[10],i,*p,b; 		for (i=0;i<10;i++) 		{ 			scanf("%d",&b); 			a[i]=b; 		}  		p=a; 		jiao(*p); 		shuchu(*p); 		return(0); } void jiao(int *o) { 	int *z,*m,s,d; 	z=o,m=o; 	for(;o<=&o[9];o++) 	{ 		if(*z>*o) 		{ 			s=*z; 			*z=*o; 			*o=s; 		} 		if(*m<*o) 		{ 			d=*m; 			*m=*o; 			*o=d; 		} 	} } int shuchu(int *n) { 	int t; 	for(t=0;t<10;t++) 	{ 		printf("%d",*n); 		n+=1; 	} 	return(0); } 改成这样的了 还是编译是没错运行时出错

Linking... 1.obj : error LNK2001: unresolved external symbol "void __cdecl shuchu(int)" (?shuchu@@YAXH@Z) 1.obj : error LNK2001: unresolved external symbol "void __cdecl jiao(int)" (?jiao@@YAXH@Z) Debug/3.exe : fatal error LNK1120: 2 unresolved externals 执行 link.exe 时出错.

你得把报错贴出来，才方便大家帮你看

scanf("%d",a[i]);/////  x


Question: 为什么scanf输入的小数打印后却是0？

double arr[ ]={0};改成float arr[ ]={0};就好了

定义数组要明确元素个数， double arr[10 ]={0}; double arr[10 ]; 明确确定。 double arr[ ]={0,2.3,5.4,560.32}; 隐含确定，编译器为你数个数。

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

请检查scanf函数的返回值。

引用 6 楼 jianyuezhimei 的回复:double arr[ ]={0};   ????????????????????????  嗯，这个改了就没有报警了！，可是不是可以这样初始化数组的吗?

那么我把全部改为%lf可以吗？

%f和%lf在内存里表示的大小不一样，一个是4字节，一个8字节。自然对于同一个数据比如1.23，在内存里浮点数也是不一样的。

#define _CRT_SECURE_NO_DEPRECATE  #define _CRT_SECURE_CPP_OVERLOAD_STANDARD_NAMES 1  #include <stdio.h>  int main( ) {          double arr[ ]={0};  	int n;  	scanf("%lf",&arr[0]);  	scanf("%lf",&arr[1]);  	scanf("%lf",&arr[2]);  	printf("Input mumber 1 is %f\n",arr[0]);   	 	printf("Input mumber 2 is %f\n",arr[1]);   	 	printf("Input mumber 3 is %f\n",arr[2]);    	printf("Now we have the numbers : %f,%f,%f\n",arr[0],arr[1],arr[2]);        return 0; }

为什么运行后出现这个?

嗯，是这样的，之前怎么没发现！

引用为什么scanf输入的小数，打印后却是0？   double类型的输入输出应该用　%lf  scanf("%lf",&arr[n]);  //是字母l，可别打成数字1 printf("%lf\n",arr[n]);  //同上


Question: 刚才问题没说清楚。求大神帮忙看下小弟这个程序哪里出了问题 感激ing~

不要使用 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> #define MAXLINE 1000  int getline_r(char line[], int maxline); void copy(char to[], char from[]);  int main(void) {     int len;     int max;     char line[MAXLINE];     char longest[MAXLINE];      max = 0;      printf("please enter some strings!\n");      while((len = getline_r(line, MAXLINE)) > 0)         if (len > max) {             max = len;             copy(longest, line);         }      if (max > 0)         printf("%s", longest);      getchar();      return 0;  }  int getline_r(char s[], int lim)   //返回行的长度 {     int c, i;      for (i = 0; i < lim - 1 && (c = getchar()) != EOF && c != '\n'; ++i)         s[i] = c;     if (c == '\n') {         s[i] = c;         i++;     }     s[i] = '\0';      printf("i = %d\n", i);     return i; } void copy(char to[], char from[])  //复制字符串 {     int i;     i = 0;     while ((to[i] = from[i]) != '\0')         ++i;  } 去掉if后面的括号，那么输入EOF后，i也会自增1，那么循环（main里的循环）就不会停止，因为getline的返回值返回1。 如果加上括号，输入EOF后，i的值就是0，while循环判断为0，退出循环。 另外，建议将getline改一下名字，防止与系统函数名字冲突～


Question: 该代码循环中为何赋完a就结束循环了?对于s1的输出结果是否以空字符结束？

for (A;B;C) D; //等价于 {  A;  while (1) {   if (!(B)) break;   D;   C;  } }

问题修改一下，两者为何有这差别?这段语句的输出结果为“abc” #include <stdio.h> #include"stdlib.h" main() { char y[9]; char qw[5]; char *s1="iya"; char *s2="abc"; int i=0; for(;*s1;s1++,s2++,i++){ y[i]=*s2; }  s1=&y[0]; printf("%s",s1);  system("pause"); } 收起 这段语句输出结果为"a" #include <stdio.h> #include"stdlib.h" main() { char y[9]; char qw[5]; char *s1="iya"; char *s2="abc"; int i=0; for(;*s1;s1++,s2++,i++){ y[i]=*s2; s1=&y[i]; }  s1=&y[0]; printf("%s",s1);  system("pause"); }

具体循环了几次，可以通过在循环外打印i的值便可以知道。 理论上讲，s1指向字符串结束标记'\0'才会结束循环，那么至少循环3次才可以。循环3次也不能对y后面加上'\0',所以从逻辑上考虑，需要在循环外将字符串'\0'加到y有效字符的后面； #include <stdio.h> #include"stdlib.h" int main() {     char y[9];     char qw[5];     char *s1="iya";     char *s2="abc";     int i=0;     for(;*s1;s1++,s2++,i++){         y[i]=*s2;     }     printf("i = %d\n", i);     y[i] = 0;     s1=&y[0];     printf("%s\n",s1);     system("pause"); }

引用为何有这差别  第二种写法是有问题的。 //这个循环并不能如预想的那样结束	 for (; *s1; s1++, s2++, i++) { //执行完循环后，会执行s1++,s2++,i++,然后再判断循环条件 		y[i] = *s2; 		s1 = &y[i];  //s1读到'\0'后，在进行下一次判断之前，会先执行s1++，之后*s1又不会等于0，继续循环下去。 	} 最终的结果是发生运行时错误。你可以分步调试就能清楚的看到这个过程。


Question: 请教大神，我的22被吃掉了，新生成的文件只有沈潇潇

谢谢大神，我明白了

这是因为fwrite写入后，文件中存放的是22的二进制形式。 查一下ascii表： http://blog.csdn.net/xiaojianpitt/article/details/6925849 从表中可知，十进制为22的字符是一个不可见字符，因此导致题目中描述的现象。 您可以把22换成65(查ascii表可知其为大写字母'A')，再运行一次看看结果。  解决方法： 如果确实是想将22这个数字写入文件，应该换用fprintf函数，具体用法可以百度。


Question: 求助 c语言程序设计里面的一段代码

加括号，新串第一个字符就输入EOF时，返回值i就是0， 不加括号，第一个字符输入EOF时，i的值就是1，返回就是1。

引用 1 楼 fight_in_dl 的回复:引用求解 if (c == '\n') { 	s[i] = c; 	i++;  //当if条件满足时，才执行这行。 } if (c == '\n') { 	s[i] = c; } i++;  //不管if条件是否满足，都会执行这行  两种情况下i值的变化规律不一样，程序的运行逻辑也会不一样。 引用 1 楼 fight_in_dl 的回复:引用求解 if (c == '\n') { 	s[i] = c; 	i++;  //当if条件满足时，才执行这行。 } if (c == '\n') { 	s[i] = c; } i++;  //不管if条件是否满足，都会执行这行  两种情况下i值的变化规律不一样，程序的运行逻辑也会不一样。 c = getchar() 假如我输入abcdef 我上面2种形式不都是变成s[] = abcdef\n\0 这样么。。。


Question: 无法解析的外部符号

注意下是不是函数名不对呢，OpenSrve和OpenSrv的区别。

无法解析是因为没有定义或者张冠李戴了

引用编译的时候报错  提问时最好能附上具体的错误信息，更利于定位。  void OpenSrve(void);  //和后来的函数名不一致，多了一个e  不确定是不是粘贴失误，如果这是最终版本，那肯定是要报错的。


Question: 请问我这个函数有什么问题？找不到原因

引用 3 楼 ipqtjmqj 的回复:改用strcpy或memcpy 谢谢你，可以了。

引用 2 楼 fight_in_dl 的回复:引用不能修改的左值  c++表达式的左值必须可以修改。 没有结构体的定义，不清楚name和wage的类型。 如果是数组类型， 数组名是常量 ，不可以修改。  可以用strcpy函数为字符数组赋值，具体用法可以百度。 谢谢，，忘了，前面都写了<string.h> 结构到复制名字的时候怎么都没想起来， 哈哈， 真的太感谢了。

改用strcpy或memcpy

谁能帮助我一下啊，谢谢了


Question: 大哥帮解释一下

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

引用p2=p1;              //为什么这"p2=p2->node"就段错误，这两个不是一样的吗。 p1=p2->node; //注意这行是在if分支中，有可能执行，也有可能不执行，取决于是否满足判断条件  //所以这两个并不一样  p2 = p1;  //因为不能百分百保证 p1 = p2->node会执行 p2 = p2->node;

这有什么好解释的？


Question: C语言两个byte 赋给一个变量的问题

位移➕与运算，楼主用的是位移和➕运算，算法本身就错误，结果自然不正确

5楼正解！

int byte1 = 0x3f; int byte2 = 0xf0; int data = byte2 + (byte1 << 8); cout << data << endl;

unsigned char b1=0x3Fu; unsigned char b2=0xF0u; unsigned short int data; data=((unsigned short int)b1<<8)|((unsigned short int)b2;

data = ((unsigned int)byte1 << 8) + byte2; 另外注意下byte1和byte2的类型

算加法也可以,不过 需要注意 << 运算符的优先级 低于 +    data = (byte1 << 8) + byte2;

引用希望的结果是 data= 0x3FF0    不应该用+，应该用位或运算符  ｜ data = (byte1 << 8) | byte2;

查阅优先级表格 下一题


Question: 急急急!!!!!!!源目的IP 源目的port 计算哈希值 不冲突

A:B:C:D:port 8+8+8+8+16=48bit 直接用≥48位比如64位整数保存所有信息？

引用 1 楼 fight_in_dl 的回复:引用有什么好哈希算法吗  哈希冲突是必然的，推荐 http://www.cnblogs.com/xiekeli/archive/2012/01/13/2321207.html 系列文章共三篇。  文中提到的暴雪hash代码下载地址 http://download.csdn.net/detail/yjsyjs1189/2844737谢谢 我只想知道四元组算哈希值 有什么好办法，别整一堆帖子给我。


Question: 实现两个字符串的比较，但在编译器中比较的结果却不正确，比如输入"ihq"时却也显示字符串相同。什么原因？

引用还有这段代码，编译器为何提示这个错误？ 左值这个问题： c++表达式的左值必须可以修改， 数组名是常量 ，不可以修改。 可以用strcpy函数为字符数组赋值，具体用法可以百度。     for (; *s1 && *s2 && *s1==*s2; ++s1,++s2)        NULL;   //当比较的两个字符串没有到末尾，或者对应字符相等，就一直循环 return *s1==*s2 ? 0 : *s1>*s2 ? 1 : -1;     假如s1 = "abc"，s2 = “abe" 这两行代码结果为 -1 。 循环比较对应字符，'a' == 'a'  'b' == 'b'  'c' < 'e'         你再自己输入几个样例，走一遍循环就理解了。

还有这段代码，编译器为何提示这个错误？ #include <stdio.h>  main() {     int y;     char s1[]="iya";     char s2[]="abc";     for(;*s1!='\0';s1++,s2++) {      y=(*s1>*s2)? 1 : -1;      printf("%d ",y);      } }

请再看下这个， #include <stdio.h>  int _strcmp(char *s1, char *s2) {     for (; *s1 && *s2 && *s1==*s2; ++s1,++s2) NULL;   //对于这两行语句我不明白它的含义；麻烦解释一下。     return *s1==*s2 ? 0 : *s1>*s2 ? 1 : -1;                         //对于这两行语句我不明白它的含义；麻烦解释一下。 }  main() {     char m[5];     char a[]="abc";     gets(m);     if (_strcmp(m, a) == 0)         printf("a\n");     else         printf("b\n"); }

引用比较的结果却不正确 原有的写法中当 *a==*b 时循环才执行，当*a !=*b 时不执行循环。 这样  x=1; 没有机会得到执行。 修改后的代码如下：  int function(char *a, char *b) { 	int x;        //当被比较的字符串（ihy）到未尾才结束循环，这样不管输入的字符串长度如何，都能对其比较完全        //输入ih，结果应为不相等，输入ihq，结果应为不相等，只有输入ihy，结果才相等 	for (; *b != '\0'; a++, b++) {  		if (*a == *b) 			x = 0; 		else 			x = 1; 	} 	return(x); } int main() { 	char *c = "ihy"; 	char d[100]; //题目中d定义为指向常量字符串的指针变量，运行时会报错。  	scanf("%s", d); 	if (function(d, c) == 0) 		printf("字符串相同\n"); 	else 		printf("字符串不相同\n"); 	system("pause"); 	return 0; }

[quote=引用 5 楼 fight_in_dl 的回复:] for (; *s1 && *s2 && *s1==*s2; ++s1,++s2)        NULL;   //当比较的两个字符串没有到末尾， 比如这个，导致循环结束，是因为赋完一个值a给*s1后*s1就到末尾了吗？为何没有完整的赋完abc? #include <stdio.h>  main() {     char y[9];     char *s1="iya";     char *s2="abc";     int i=0;     for(;*s1;s1++,s2++,i++){       y[i]=*s2;       s1=&y[i];     }      s1=&y[0];      printf("%s",s1); }

首先你没有判断字符串是否结束，要是两个字符串真的相等，就没法停下来，a和b会移到字符串外面去。 其次，你的循环里面，else x = 1永远都不会被执行到。因为只要能进入循环必然a、b相等。要是不等，就根本进不去循环。  基于你的思路改一下：  int function(char *a,char *b){   for(;*a==*b;a++,b++){     // 一直看到字符串尾才返回0     // *a=='\0'那么也必然*b=='\0'，就不用写了     if ( *a=='\0' )       return 0;   }   // 循环提前结束，说明二者有所不同   return 1; }


Question: c语言调用dos命令

多谢各位啦

char command[200]; sprint(command,"netsh wlan set hostednetwork mode=allow ssid=%s key=%s",name.c_str(),key.c_str()); system(command);

要#include <sstream> stringstream用起来就跟iostream一样。   std::stringstream ss; string name = "test.jpg"; ss << "del " << name; system(ss.str());

sprintf 字符串格式化函数


Question: 求改正~调用2个子函数，先对输入的10个值进行排序，然后去掉最大最小6个值，剩下中间4个值求平均值

sort函数最后少了个大括号


Question: 数据结构对单链表进行数据排序

学到了学到了

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

C双链表的逆序操作：http://bbs.csdn.net/topics/392264935

学习学习 长知识 了。

学习学习了乐乐乐乐

引用 33 楼 weixin_37174592 的回复:长见识了，原来还可以这操作！  呵呵！

长见识了，原来还可以这操作！

就是第一次r->data<cp->data比较的时候我就有点不明白

长见识了，以前学习的时候也是模糊。

怎么获得下载积分啊？？？？？？

好的 谢谢老师！

引用 26 楼 zhezhe_9860 的回复:请教下 赵老师 这几个图用什么软件画出 来的？？visio

长见识了.谢谢楼主.

引用 20 楼 user-15 的回复:[quote=引用 16 楼 zhao4zhong1 的回复:] Orz 跪求版主加精！  已推荐，难得赵老师这么有耐心了[/quote] 谢谢推荐！ 关键是这个图应该够“旷古烁今”了。

没必要吧，这个是很经典的插入排序算法，

引用 16 楼 zhao4zhong1 的回复:Orz 跪求版主加精！  已推荐，难得赵老师这么有耐心了


Question: OpenGL绘制界面，接收udp发送的数据并改变界面

代码太多了，放不下

百度搜相关关键字。


Question: 新手求解大神一道简单编程题！

规则为如果x楼和y楼已经有归属人，则i=x+y或i=x-y均可占领  这句话不知道是什么意思。

我觉得你题目是不是有问题,或许可能是我理解错了,我是这样理解的,N,一开始不就代表宿舍楼的总数了吗,为什么还要计算可到达的宿舍楼,一人占一次,就是判断奇偶性？你是怎么理解的呢


Question: 求解

如果不考虑先算乘除后算加减的话,答案应该是 5 + 8 - 9 = 4 +     -    - 7 -  6 * 4 = 4 /      *     - 3 + 2 - 1 = 4 =    =    = 4    4    4 考虑到先乘除后加减的情况下 2 + 11 - 9 = 4 +     -    - 4 -  1 * 0 = 4 /      *     - 2 + 7 - 5 = 4 =    =    = 4    4    4


Question: 如何用链表存储socket投递的io请求？

首先，非常感谢您的回复！  小猪用动态数组存储新创建的IO请求，请问这些IO请求是谁创建的？又是谁投递的？小猪用动态数组管理这些IO请求，却没用动态数组中的泛型进行查找，他那段查找代码效率有些低，所以我想用链表实现该功能。

个人感觉不需要链表存储， 因为投递后，不管是成功还是失败， 在GetQueuedCompletionStatus中都会返回 如果是学习，网搜 iocp piggy， 有很完整的入门代码


Question: 如何设置Include根目录相对文件？

引用 1 楼 zhao4zhong1 的回复:在include path最后加 ;d:/code/ruby/ruby/blob/trunk  对，这样解决了，在CMakeLists.txt增加： include_directories(.)


Question: 请大神帮忙看看，我写了个文件复制的简单程序，但是p1指针不知道为什么变为空指针了

打扰了大家了，在编辑器中大写的W和小写的w真的不好分辨，一贴出来就马上发现问题了，闹笑话了


Question: 关于结构体

引用已经改正了 不客气，共同进步。 可以的话结题散分好吗^_^，论坛有结题率和采纳率的指标~~

引用 2 楼 fight_in_dl 的回复:引用出错 问题的根源是里层GROUP_INFO是 类型 的名字，而不是 变量 的名字。 之前的写法类似 变量->类型.成员 = .... 应该修改为 变量->变量.成员 = ....  具体修改方法为将里层结构体定义中的typedef关键字去掉  typedef    struct   _GROUP_INFO //去掉typedef      然后应该这么使用：  pstFrameInfo->GROUP_INFO.iGroupRank = 9;   //=右侧不能是iGroupRank，编译器不知道等号右侧iGroupRank是什么。 //9是我随意取的数，根据需要自己赋值  我后来也发现是这个问题,已经改正了,还是非常感谢你,你的回答很有用

引用 3 楼 fight_in_dl 的回复:引用pstFrameInfo->iGroupRank=iGroupRank;  赵四老师，请注意回答质量，你每天要答几百道题吧? 别累坏了。

pstFrameInfo->iGroupRank=iGroupRank;


Question: 关于内存对齐

一楼是正解，终于明白了。谢谢大家！

引用 楼主 vinnyjia 的回复:因为内存中的所有变量的首地址都是从偶地址开始的 不是。

《C语言结构struct的内存对齐》 http://blog.csdn.net/hou09tian/article/details/74359172 还请多指教

http://blog.csdn.net/hou09tian/article/details/74359172 《C语言结构struct的内存对齐》 还请多指教

struct HH {     char str[3];     char ch; };  这样子试试？

仅供参考：#include <stdio.h> #define field_offset(s,f) (int)(&(((struct s *)(0))->f)) struct AD  { int a; char b[13]; double c;}; #pragma pack(push) #pragma pack(1) struct A1  { int a; char b[13]; double c;}; #pragma pack(2) struct A2  { int a; char b[13]; double c;}; #pragma pack(4) struct A4  { int a; char b[13]; double c;}; #pragma pack(8) struct A8  { int a; char b[13]; double c;}; #pragma pack(16) struct A16 { int a; char b[13]; double c;}; #pragma pack(pop) int main() {     printf("AD.a %d\n",field_offset(AD,a));     printf("AD.b %d\n",field_offset(AD,b));     printf("AD.c %d\n",field_offset(AD,c));     printf("AD sizeof %d\n", sizeof(AD));     printf("\n");     printf("A1.a %d\n",field_offset(A1,a));     printf("A1.b %d\n",field_offset(A1,b));     printf("A1.c %d\n",field_offset(A1,c));     printf("A1 sizeof %d\n", sizeof(A1));     printf("\n");     printf("A2.a %d\n",field_offset(A2,a));     printf("A2.b %d\n",field_offset(A2,b));     printf("A2.c %d\n",field_offset(A2,c));     printf("A2 sizeof %d\n", sizeof(A2));     printf("\n");     printf("A4.a %d\n",field_offset(A4,a));     printf("A4.b %d\n",field_offset(A4,b));     printf("A4.c %d\n",field_offset(A4,c));     printf("A4 sizeof %d\n", sizeof(A4));     printf("\n");     printf("A8.a %d\n",field_offset(A8,a));     printf("A8.b %d\n",field_offset(A8,b));     printf("A8.c %d\n",field_offset(A8,c));     printf("A8 sizeof %d\n", sizeof(A8));     printf("\n");     printf("A16.a %d\n",field_offset(A16,a));     printf("A16.b %d\n",field_offset(A16,b));     printf("A16.c %d\n",field_offset(A16,c));     printf("A16 sizeof %d\n", sizeof(A16));     printf("\n");     return 0; } //AD.a 0 //AD.b 4 //AD.c 24 //AD sizeof 32 // //A1.a 0 //A1.b 4 //A1.c 17 //A1 sizeof 25 // //A2.a 0 //A2.b 4 //A2.c 18 //A2 sizeof 26 // //A4.a 0 //A4.b 4 //A4.c 20 //A4 sizeof 28 // //A8.a 0 //A8.b 4 //A8.c 24 //A8 sizeof 32 // //A16.a 0 //A16.b 4 //A16.c 24 //A16 sizeof 32 // //

字节对齐只看基本数据类型的大小，包括嵌套的结构体、共用体等。数组无非就是N个相同连续变量而已。 默认是按成员最大的基本类型字节数对齐，目前最大也就是8字节的double和64位的long、pointer或者32位的long long之类的。  默认情况下，成员对齐要求成员首地址是自身类型大小的倍数，不一定是偶地址，奇地址主要是单字节的char。char不管奇偶都可以放，因为任何地址都是1的倍数。 你举的例实际上就是连续的4个char，它们是挨着存储的，所以是4字节。  struct A{ char a; short b; int c; } 4字节对齐，b地址等于a地址+2，c地址等于a地址+4，共8字节。  struct A{ char a; int c; short b; } 4字节对齐，c地址等于a地址+4，b地址等于a地址+8，，共12字节。


Question: windows系统中codeblocks中GCC的搭建问题

引用 3楼战在春秋 的回复:引用哪里的路径不对  检查linker settings和search directories的设置是否正确谢谢 是的 问题点找到了

帮结帖＋蹭分

问题已经解决


Question: C/C++关于i++,i--的问题

个人建议对于这类问题，可以作为研究用，平时写代码时不建议写。i++,++i这类表达式是有副作用的，用不好会出现问题。

谁这样写产品中的代码就等着被喷吧。

这种问题变成了论坛的日经了吗? 日日讲月月讲 +1

关于C,C++表达式求值顺序 http://blog.csdn.net/fefe82/article/details/37833767，http://bbs.csdn.net/topics/370153775

这种问题变成了论坛的日经了吗? 日日讲月月讲

引用 1 楼 fight_in_dl 的回复:1 参数从右向左顺序计算。 2 对于后缀形式的自增（自减）表达式，先取变量的值作为表达式的值，然后该变量再加1（减1）。  int i = 0;  此时i=0 先算i--表达式的值为0，然后i = i -1 = -1 再算右边第一个i++表达式的值为-1，然后i = i + 1 = 0 再算右边第二个i++表达式的值为0， 然后i = i + 1 = 1 再算i的值等于 1 printf("%d %d %d %d\n", i, i++, i++,i--); //输出 1 0  -1 0  此时i = 1，开始执行下一句。 先算i--表达式的值为1，然后i = 1 -1 =  0 再算右边第一个i++表达式的值为0，然后i = 0 + 1 = 1 再算右边第二个i++表达式的值为1， 然后i = 1+ 1 = 2 再算i的值等于 2 cout << i << " " << i++ << " " << i++ << " " << i-- << endl; //输出 2 1 0 1说错了  不是从右向左  也不一定是输出1 0 -1 0

同一表达式中多个子表达式，标准对于其求值顺序未进行强制规定 这个程序放在不同编译器下可能结果就不一样了  求值顺序和参数的压栈顺序，操作数的结合律，操作符运算优先级是不一样的概念


Question: 文件读取乱码

引用另外请检查scanf的返回值  怎么又来复制粘贴抢分~~，赵老师，手下留情。

c  读写文件注意事项比较多，二进制方式，流式，字符串识别等。

这fscanf(fp,"%d %s %d %d %d %f"我改了以后，  p2=p2->node; 可以了，可还是乱码。

引用就这2个  不能试图在输入时指定浮点数的精度，否则不能正确接收。 fscanf(fp,"%d %s %d %d %d %6.2f"  应为：  fscanf(fp,"%d %s %d %d %d %f"  使用scanf时也要注意这点。

printf里面的%和变量的一一对应关系 scanf里面的%和变量以及变量前加不加&的一一对应关系 是C代码中非常容易出错的地方，而且通常编译还不出错。 所以在编译源代码之前值得专门仔细检查一遍甚至多遍。  在每个最后不带\n的printf后面加fflush(stdout); 在每个不想受接收缓冲区旧内容影响的scanf前面加rewind(stdin); 另外请检查scanf的返回值。 //请今后要用 char c; scanf("%c",&c); //时，都改为 char s[2]; char c; scanf("%1s",s); c=s[0]; //自动跳过一个或多个空格或Tab字符或回车换行，读取下一个字符。


Question: 求解

引用用的控件是DataGridView DataGridView属于.net控件，建议楼主在C#论坛问一下，应该更快得到答复。  http://bbs.csdn.net/forums/CSharp


Question: 宏定义的意义

#与##在宏定义中的--宏展开 #include <stdio.h> #define f(a,b) a##b #define g(a)   #a #define h(a) g(a) int main() {         printf("%s\n", h(f(1,2)));   // 12         printf("%s\n", g(f(1,2))); // f(1,2)         return 0; } 宏展开时： 如果宏定义以#开头，不展开参数，直接替换。 故g(f(1,2))--->#f(1,2)--->"f(1,2)"； 如果宏定义不以#开头，展开参数，直接替换，由外层向里层，如果碰到的是#开头的宏，不继续往里层展开，往外层展开。 由外层向里层，如果碰到的是以非#开头的宏，继续往里层走，直至最里层，开始一层层往外层展开。 故h(f(1,2))--->h(12)--->g(12)---->#12----->"12"。 PS： ##在宏中定义，是字符连接符 如a##b##c 等同于 "abc" #在宏开头出现，是表示宏展开的方式不同 #a 等同于"a" #abc 等同于 "abc" 复杂的: #include <stdio.h> #define f(a,b) a##b #define g(a)   #a #define h(a) g(a) int main() {         char a = 'a';         cout<<g(a)<<endl; // a         cout<<g(g(a))<<endl; // a         printf("%s\n", h(f(1,2)));   // 12         printf("%s\n", g(f(1,2))); // f(1,2)         printf("%s\n", g(h(f(1,2)))); // h(f(1,2))         printf("%s\n", h(g(f(1,2)))); // "f(1,2)"         printf("%s\n", h(h(f(1,2)))); // "12"         system("pause");         return 0; } 预处理后的：（在编译选项中添加/EP /P后编译生成的.i文件。gcc加-E） int main() {         char a = 'a';         cout<<"a"<<endl;         cout<<"g(a)"<<endl;         printf("%s\n", "12");         printf("%s\n", "f(1,2)");         printf("%s\n", "h(f(1,2))");         printf("%s\n", "\"f(1,2)\"");         printf("%s\n", "\"12\"");         system("pause");         return 0; } --------------------------------------------------- 宏解析 1.       ##操作符 ##操作符它的作用是在替代表中将其前后的参数连接成为一个预处理符号，它不能出现于宏替代表的开端和末尾。 例： #define concat(s,t) s##t #define AAA ABC concat(A, AA) 将被替换成 ABC 2.       重新扫描和替换 在替换列表中的所有参数替换过之后，预处理器将对结果token序列重新扫描以便对其中的宏再次替换。 当正在替换的宏在其替换列表中发现自身时，就不再对其进行替换。在任何正在嵌套替换的宏的替换过程中遇到正被替换的宏就对其不再进行替换（防止递归）。 例： #define ROOT AAA CCC #define AAA ROOT ROOT 将被替换成 ROOT CCC

看起来像是计算所使用的内存总数 table_mem，pair_mem这两个的类型是初始化为0的整形数？

引用两个宏定义 宏分为无参宏和带参宏，题目中属于无参宏。 在预处理时，会将宏替换为字符串。 #define t   (table_mem)=(table_mem)+(sizeof(table)) //预处理时会将宏t替换为(table_mem)=(table_mem)+(sizeof(table))  t; //相当于(table_mem)=(table_mem)+(sizeof(table)); 后面有分号，是一行执行语句 (table_mem)=(table_mem)+(sizeof(table)); //这行具体什么功能要看table_mem和table怎么定义的，在其它代码中找找定义


Question: 非常神奇的一个c问题，全局和局部变量的问题，求大神！

理解和讨论之前请先学会如何观察！  计算机组成原理→DOS命令→汇编语言→C语言（不包括C++）、代码书写规范→数据结构、编译原理、操作系统→计算机网络、数据库原理、正则表达式→其它语言（包括C++）、架构……  对学习编程者的忠告： 多用小脑和手，少用大脑、眼睛和嘴，会更快地学会编程！ 眼过千遍不如手过一遍！ 书看千行不如手敲一行！ 手敲千行不如单步一行！ 单步源代码千行不如单步Debug版对应汇编一行！ 单步Debug版对应汇编千行不如单步Release版对应汇编一行！ 不会单步Release版对应汇编？在你想单步Release版C/C++代码片断的前面临时加一句DebugBreak();重建所有，然后在IDE中运行。（一般人我不告诉他！）  VC调试时按Alt+8、Alt+7、Alt+6和Alt+5,打开汇编窗口、堆栈窗口、内存窗口和寄存器窗口看每句C对应的汇编、单步执行并观察相应堆栈、内存和寄存器变化，这样过一遍不就啥都明白了吗。 对VC来说，所谓‘调试时’就是编译连接通过以后，按F10或F11键单步执行一步以后的时候，或者在某行按F9设了断点后按F5执行停在该断点处的时候。  电脑内存或文件内容或传输内容只是一个一维二进制字节数组及其对应的二进制地址； 人脑才将电脑内存或文件内容或传输内容中的这个一维二进制字节数组及其对应的二进制地址的某些部分看成是整数、有符号数/无符号数、浮点数、复数、英文字母、阿拉伯数字、中文/韩文/法文……字符/字符串、汇编指令、函数、函数参数、堆、栈、数组、指针、数组指针、指针数组、数组的数组、指针的指针、二维数组、字符点阵、字符笔画的坐标、黑白二值图片、灰度图片、彩色图片、录音、视频、指纹信息、身份证信息……  不要迷信书、考题、老师、回帖； 要迷信CPU、编译器、调试器、运行结果。 并请结合“盲人摸太阳”和“驾船出海时一定只带一个指南针。”加以理解。 任何理论、权威、传说、真理、标准、解释、想象、知识……都比不上摆在眼前的事实！

我猜测 因为输入的是 %d 是有符号整形的 应该是 0000 0002 但是我的变量是 16位的 所以 第一个变量存的是 0000 第二个存的是0002 然后因为存的地址是连续的 第二个输入的时候 覆盖了第一个 一样的是0000 0002   然后vs可能是16位编译器 int 和 %d 是十六位的 所以就对上了 gcc是32位编译器，在局部变量时有优化 存的是16位的 全局没有优化 还是32位的 所以就没对上  纯粹猜测

%d是指针int类型的，四字节，不管你传入什么地址给它比如void* p，它都会强制转换为int *pp = (int*)p; 再对*pp赋值。 明显你的row,col是int16_t两字节的，会发生字节覆盖。 分别把row和col的地址打印出来就知道了。全局区和栈区地址顺序是反的。

输入时候不要换行

编译器用 gcc才有问题 用 vs没问题

编译器用的gcc IDE是 codeblocks


Question: c语言问题 给出完整代码

仅供参考：//有一个6x6的矿区，分布有4处铁矿和4处煤矿，中心2x2已预先分配给4家公司经营。 //要求给出所有可能，将整个矿区划分为形状相同，内部连通，且恰好包含铁矿煤矿各一处的4块 //给这4家公司。 // 012345  012345  012345 //0...... 0.....M 0CCAAAA //1...... 1....I. 1CCABAA //2..AB.. 2...M.. 2CAABBB //3..CD.. 3..MMI. 3CCCDDB //4...... 4..I... 4DDCDBB //5...... 5....I. 5DDDDBB #include <stdio.h> #include <time.h> #include <stdlib.h> #include <string.h> char W[6][6]; char M[6][6]; int Y[9],X[9]; char S[1000][37]; char s[37]; int N=0; void divide(int y,int x,int L) {     int m,y1,x1;     int b,y2,x2;      Y[L]=y;X[L]=x;     W[  y][  x]='A';     W[  x][5-y]='B';     W[5-x][  y]='C';     W[5-y][5-x]='D';     if (L>=8) {         for (y1=0;y1<6;y1++) {             for (x1=0;x1<6;x1++) {                 s[y1*6+x1]=W[y1][x1];             }         }         s[36]=0;         for (m=0;m<N;m++) if (0==strcmp(s,S[m])) break;         if (m>=N) {             strcpy(S[N],s);             N++; //          printf("N%d:\n",N); //          for (m=0;m<6;m++) printf("%.6s\n",s+m*6); //          printf("\n"); //          getchar();             if (N>=1000) {                 printf("N>=1000!\n");                 exit(1);             }         }         W[  y][  x]='.';         W[  x][5-y]='.';         W[5-x][  y]='.';         W[5-y][5-x]='.';         return;     }     for (b=L;b>=0;b--) {         y2=Y[b];x2=X[b];         if ((y2>0 && W[y2-1][x2  ]=='.')          || (x2>0 && W[y2  ][x2-1]=='.')          || (y2<5 && W[y2+1][x2  ]=='.')          || (x2<5 && W[y2  ][x2+1]=='.')) {             for (m=0;m<4;m++) {                 switch (m) {                 case 0://上                     y1=y2-1;x1=x2;                     if (y1<0) continue;                 break;                 case 2://左                     y1=y2;x1=x2-1;                     if (x1<0) continue;                 break;                 case 1://下                     y1=y2+1;x1=x2;                     if (y1>5) continue;                 break;                 case 3://右                     y1=y2;x1=x2+1;                     if (x1>5) continue;                 break;                 }                 if (W[  y1][  x1]=='.'                  && W[  x1][5-y1]=='.'                  && W[5-x1][  y1]=='.'                  && W[5-y1][5-x1]=='.') {                     divide(y1,x1,L+1);                     W[  y1][  x1]='.';                     W[  x1][5-y1]='.';                     W[5-x1][  y1]='.';                     W[5-y1][5-x1]='.';                 }             }         }     } } int main() {     int i,n,a,b,t;     int d[36];     int y,x;     int Ic[4],Mc[4];      srand(time(NULL));     n=36;     for (i=0;i<n;i++) d[i]=i;/* 填写0～n-1 */     for (i=n;i>0;i--) {/* 打乱0～n-1 */         a=i-1;b=rand()%i;         if (a!=b) {t=d[a];d[a]=d[b];d[b]=t;}     }     for (y=0;y<6;y++) for (x=0;x<6;x++) {         W[y][x]='.';M[y][x]='.';     }     for (i=0;i<4;i++) M[d[i]/6][d[i]%6]='I';//铁     for (i=4;i<8;i++) M[d[i]/6][d[i]%6]='M';//煤     for (y=0;y<6;y++) {         for (x=0;x<6;x++) {             printf("%c",M[y][x]);         }         printf("\n");     }     printf("\n");     divide(2,2,0);     n=0;     for (i=0;i<N;i++) {         for (t=0;t<4;t++) {Ic[t]=0;Mc[t]=0;}         for (y=0;y<6;y++) {             for (x=0;x<6;x++) {                 if (M[y][x]=='I') Ic[S[i][y*6+x]-'A']++;                 if (M[y][x]=='M') Mc[S[i][y*6+x]-'A']++;             }         }         if (Ic[0]==1 && Ic[1]==1 && Ic[2]==1 && Ic[3]==1          && Mc[0]==1 && Mc[1]==1 && Mc[2]==1 && Mc[3]==1) {             n++;             printf("%d:\n",n);             for (t=0;t<6;t++) printf("%.6s\n",S[i]+t*6);             printf("\n");         }     }     if (n==0) printf("Impossible.\n");     return 0; } //..M... //I.M..I //...... //...M.M //...I.. //....I. // //1: //CCCAAA //CAAABA //CCABBA //DCCDBB //DCDDDB //DDDBBB // //2: //CCCAAA //CCAAAA //CCABBA //DCCDBB //DDDDBB //DDDBBB // //

引用积木 此类问题不一定能直接搜索到。 可以先将问题归纳，转化为对应的经典算法，然后搜索相关经典算法的求解。 在这基础上结合问题设计算法。

百度搜相关关键字。


Question: c语言问题 给出完整代码

#include<stdio.h> #define N 20 int Judge(int b[][N],int c[][N]); int main() {     int s[N][N],a[N][N];     int num,i,j,k,l,m,o;     scanf("%d",&num);     for(i = 0;i < num;i++)     {         for(j = 0;j < 3;j++)         {             for(k = 0;k < 3;k++)             {                 a[j][k] = 0;             }         }         for(j = 0;j < 3;j++)         {             for(k = 0;k < 3;k++)             {                 s[j][k] = 1;                 if(s[1][1]==1)                 {                     s[1][1]=0;                 }             }         }         for(l = 0;l < 8;l++)         {             scanf(" %d,%d",&m,&o);                 a[m][o] = 1;         }         if(Judge(s,a))         {             printf("YES\n");         }         else             printf("NO\n");     }     return 0; } int Judge(int b[][N],int c[][N]) {     int i,j;     for(i = 0;i < 3;i++)     {         for(j = 0;j < 3;j++)         {             if(i==1&&j==1)             {                 continue;             }             if(b[i][j]!=c[i][j])             {                 return 0;             }         }     }     return 1; }

引用数据范围 坐等大神出现


Question: c语言问题

引用拆除这个玩具的最短时间是多少  是无向图的最短路径问题，可以参考 http://bbs.csdn.net/topics/70392756


Question: qsort 对结构体排序，编译不过，在线等！！！求指点！！！

看看这样好不好：  typedef struct _In { ..... } In;   然后就可以用 In了

编译不过 int main() { 	int n = 8; 	qsort(cow_x + 1, n, sizeof(cow_x), cmp); //除了全局变量的定义，其它执行语句必须放在函数体内，调用qsort这句要放到main函数体中 	return 0; }


Question: malloc动态分配内存问题

#define里不要加分号; 宏定义是等价替换，如果将等价替换到表达式里你就可以明白为什么不能加分号了

谢谢细心的四楼，当然还有五楼~~贴吧还是大神多。

晕，晚一步~

引用就出错  找到原因了  #define LIST_INIT_SIZE 10; #define INCREASE_SIZE 2; 应修改为：  #define LIST_INIT_SIZE 10 #define INCREASE_SIZE 2

#define LIST_INIT_SIZE 10; #define INCREASE_SIZE 2; 多了分号导致替代的时候语法错误

一楼：是的我手动敲错了c2-1.h，这个无关紧要 二楼：这个放在这应该没什么问题吧，定义的常量LIST_INIT_SIZE在c2-1文件之前就编译了，应该是能用的， L.listsize = LIST_INIT_SIZE;  这句用了就没错，只是在malloc中用就出错。

把头文件bo2-1.h中的东西挪到.c中

引用为什么 #include"C1.h" typedef int ElemType; #include "c2-1.h"  //找半天没找到c2-1.h这个文件，是否应该为c1-1.h #include "bo2-1.h" void main() {     SqList L;     InitList(L);     printf("List列表的内存大小为%d", L.listsize); }


Question: 各位大神帮忙解释下这个问题

Typedef Declarations A typedef declaration is a declaration with typedef as the storage class. The declarator becomes a new type. You can use typedef declarations to construct shorter or more meaningful names for types already defined by C or for types that you have declared. Typedef names allow you to encapsulate implementation details that may change.   A typedef declaration is interpreted in the same way as a variable or function declaration, but the identifier, instead of assuming the type specified by the declaration, becomes a synonym for the type.   Syntax  declaration :  declaration-specifiers init-declarator-list opt ;  declaration-specifiers :  storage-class-specifier declaration-specifiers opt type-specifier declaration-specifiers opt type-qualifier declaration-specifiers opt   storage-class-specifier :  typedef  type-specifier :  void char short int long float double signed unsigned struct-or-union-specifier enum-specifier typedef-name  typedef-name :  identifier  Note that a typedef declaration does not create types. It creates synonyms for existing types, or names for types that could be specified in other ways. When a typedef name is used as a type specifier, it can be combined with certain type specifiers, but not others. Acceptable modifiers include const and volatile.   Typedef names share the name space with ordinary identifiers (see Name Spaces in Chapter 2 for more information). Therefore, a program can have a typedef name and a local-scope identifier by the same name. For example:   typedef char FlagType;  int main() { }  int myproc( int ) {     int FlagType; }  When declaring a local-scope identifier by the same name as a typedef, or when declaring a member of a structure or union in the same scope or in an inner scope, the type specifier must be specified. This example illustrates this constraint:  typedef char FlagType; const FlagType x;  To reuse the FlagType name for an identifier, a structure member, or a union member, the type must be provided:  const int FlagType;  /* Type specifier required */  It is not sufficient to say  const FlagType;      /* Incomplete specification */  because the FlagType is taken to be part of the type, not an identifier that is being redeclared. This declaration is taken to be an illegal declaration like  int;  /* Illegal declaration */  You can declare any type with typedef, including pointer, function, and array types. You can declare a typedef name for a pointer to a structure or union type before you define the structure or union type, as long as the definition has the same visibility as the declaration.   Typedef names can be used to improve code readability. All three of the following declarations of signal specify exactly the same type, the first without making use of any typedef names.   typedef void fv( int ), (*pfv)( int );  /* typedef declarations */  void ( *signal( int, void (*) (int)) ) ( int ); fv *signal( int, fv * );   /* Uses typedef type */ pfv signal( int, pfv );    /* Uses typedef type */  Examples  The following examples illustrate typedef declarations:  typedef int WHOLE; /* Declares WHOLE to be a synonym for int */  Note that WHOLE could now be used in a variable declaration such as WHOLE i; or const WHOLE i;. However, the declaration long WHOLE i; would be illegal.  typedef struct club  {     char name[30];     int size, year; } GROUP;  This statement declares GROUP as a structure type with three members. Since a structure tag, club, is also specified, either the typedef name (GROUP) or the structure tag can be used in declarations. You must use the struct keyword with the tag, and you cannot use the struct keyword with the typedef name.   typedef GROUP *PG; /* Uses the previous typedef name                        to declare a pointer            */  The type PG is declared as a pointer to the GROUP type, which in turn is defined as a structure type.  typedef void DRAWF( int, int );  This example provides the type DRAWF for a function returning no value and taking two int arguments. This means, for example, that the declaration  DRAWF box;   is equivalent to the declaration   void box( int, int );

PASSWORD 是 结构体 pass 的别名，作用同pass PPASSWORD 是  结构体 pass 的指针 的别名 , 作用同pass *

引用是结构体指针吗 typedef struct pass {    int i; }PASSWORD,*PPASSWORD 定义了两个别名: PASSWORD 是 struct pass 的别名   PPASSWORD 是 *struct pass 的别名   之后可以用这两个别名定义变量： PASSWORD var1; PPASSWORD var2;  区别在于引用成员时，要使用不同的运算符 var1.i  //使用点号 var2->i //使用->

请问下二楼的大佬，PPASSWORD是一个什么类型，是结构体指针吗？struct pass*是结构体指针吗  问下三楼的大佬，那意思就是，a，b都是等价于struct node吗？

int n,m; 声明两个int变量 typedef int n, m; n, m作为int类型的别名  struct node { //成员列表 }a, b; 声明两个结构体变量 typedef struct node { //成员列表 }a, b; a, b作为结构体类型的别名  你可以把  struct node { //成员列表 } 这一段 看成 int 这是一个类型

typedef 把PASSWORD定义为struct pass的别名，把PPASSWORD定义为struct pass* 的别名。 为什么用逗号？语法规定如此，反正就是typedef同时定义了两个别名。


Question: 求帮忙改错啊

引用 1 楼 fight_in_dl 的回复:引用谢谢啦 修改后的代码： #include <stdio.h> #include <stdlib.h> #define A 18 struct node {     char book[18];     int number;     char publish;     char writer;     char time;     double p[18]; }stud[A];  int main() {     int i,j;     double t;     FILE*fp;     if ((fp = fopen("123.txt", "r+")) == NULL)     {         printf("cannot open file\n");         exit(0);     }     for (j=0;j<17;j++)         for (i=0;i<17-j;i++)             if (stud[i].p[i]>stud[i].p[i+1])             {                 t=stud[i].p[i];stud[i].p[i]=stud[i+1].p[i+1];stud[i+1].p[i+1]=t;             }     {         fread(&stud[i], sizeof(struct node),1,fp);         printf("%s %d %s %s %s %lf\n", stud[i].book,stud[i].number,stud[i].publish,stud[i].writer,stud[i].time,stud[i].p);     }     fclose(fp); return 0; }  说明： 1 原代码有的符号是中文输入状态下输入的，比如main后面的括号，不确定是粘贴排版的原因还是本来就输错了，总之小心些 2 修改后的代码编译通过，可以在这基础上调试修改，直到满足程序要求结果 运行出现错误 导致程序停止，，实在找不出错误

运行的时候  出现了一个错误，导致程序停止， 实在找不出来

引用谢谢啦 修改后的代码： #include <stdio.h> #include <stdlib.h> #define A 18 struct node { 	char book[18]; 	int number; 	char publish; 	char writer; 	char time; 	double p[18]; }stud[A];  int main() { 	int i,j; 	double t; 	FILE*fp; 	if ((fp = fopen("123.txt", "r+")) == NULL) 	{ 		printf("cannot open file\n"); 		exit(0); 	} 	for (i = 0; i < 17; i++) 		for (j = i + 1; j<18; j++) 			if (stud[i].p[i]>stud[i].p[j]) 			{ 				t = stud[i].p[i]; stud[i].p[i] = stud[i].p[j]; stud[i].p[j] = t; 			} 	{ 		fread(&stud[i], sizeof(struct node),1,fp); 		printf("%s %d %s %s %s %lf\n", stud[i].book, stud[i].number, stud[i].publish, stud[i].writer, stud[i].time, stud[i].p); 	} 	fclose(fp); return 0; } 说明： 1 原代码有的符号是中文输入状态下输入的，比如main后面的括号，不确定是粘贴排版的原因还是本来就输错了，总之小心些 2 修改后的代码编译通过，可以在这基础上调试修改，直到满足程序要求结果


Question: 从第十行就完全看不懂，感觉像没交换一样（c语言排列）

不过谢谢你们

其实我是被这里的i给搞晕了我以为i都是一样的。函数嵌套生成的i是不一样的吧

在纸上自己模拟一下这个过程，就清楚了

引用void swap(int * o, int i, int j) 如果是编译错误，请发一下错误说明。 如果编译是正确的，这个函数代码没有问题。  swap函数第一个参数接收的是数组首地址，属于传址调用，函数对形参数组的交换会影响实参数组。

引用i是不一样的 每次调用perm函数s是不一样的。 for(i = s; i <= e; i++）//10  // i = s，s不一样，i也就不一样         {                           swap(list, s, i);                           perm(list, s + 1, e, cbk);  //再次调用perm函数时，s的值是原来的值+1                         swap(list, s, i);                  }


Question: 如何限制FILE *fp所创建的文件的大小，并追加文件？

我的例子代码已经解决了楼主的问题。

引用 15 楼 zhao4zhong1 的回复:仅供参考：#include <stdio.h> #include <stdlib.h> #include <string.h> #ifdef _MSC_VER     #pragma warning(disable:4996)     #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 _MSC_VER 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 _MSC_VER     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 _MSC_VER     DeleteCriticalSection(&cs_log); #else     pthread_mutex_destroy(&cs_log); #endif     return 0; } //1-79行添加到你带main的.c或.cpp的那个文件的最前面 //81-86行添加到你的main函数开头 //90-94行添加到你的main函数结束前 //在要写LOG的地方仿照第88行的写法写LOG到文件MyLog1.log中  这个里面运用了很多的结构类什么的，表示这些不是很明白，不过感谢大神的指教，对于之前的问题，我采用了一个折中的方法，就是存到一定的大小，将文件关闭改名，然后重新建立一个原来命名的日志文件进行追加。

引用 9 楼 xy_kok 的回复:引用#8 通过第二条可以达到一定的预期目的，但是却是把原来的所有数据清空后重新写入的，如果我需要的是只清掉最早的，继续追加写入该如何弄了，就是假设有1000行，需要重新存入新的一行，但是大小已经达到了，这个时候就删除最早的一行，然后就可以写入一行了，这样的要如何操作了？  这个涉及到整体的文件内容迁移，暂时没想到好办法，如果不觉得麻烦的话，可以参考下面这种： 1.当文件未满是按原思路做； 2.当文件满时，创建一个临时文件，将除最早记录之外的文件内容复制到临时文件中，再清空原文件，之后将临时文件中的内容和新的内容写入到原文件中（临时文件只是为了保证原文件内容的完整性，但会损失一些效率）； 2-1. 要考虑到一点，可能会频繁的写入已经满的文件，此时，如果对写入内容没有过高的要求的话，可以将需要写入的内容存储到一个buffer中，当满足一定条件时，将buffer中的数据写入到文件，如此可避免过多的文件操作。 以上请参考。  这中方法确实是比较的麻烦，这估计会占用过多的内存吧。

引用 10 楼 SXJIAKE 的回复:[quote=引用 7 楼 a1317296227 的回复:]是没有复制完全还是什么的，复制到我这边编译一大堆问题。且不知道各个的作用。 手打的，其中有一处错误，应为：sprintf(file2, "%s.%d", file, index++);我没有编译运行，因为有些变量没有声明，就比如 fwrite 这一行。如果你这个都看不明白的话，那我也没办法。我这个只是给个思路，即文件超出指定大小，则将文件关闭，改名，然后重新创建一个同名文件。举个例子，日志叫 debug.log，首次打开的时候，获取到末尾偏移，也就是大小了，然后每写入一行都会加上写入的字节数，如果超出一定大小，比如 4MB，则关闭该文件，循环查找 debug.log.0、debug.log.1、debug.log.2... 直到某个文件不存在，则将 debug.log 改名为这个名字，然后重新打开 debug.log 以这个名字继续写日志。即 debug.log 永远都是最新的内容。当然，你也可以以年月日时分秒作为后缀作为备份文件名，这样的话就更直观看到哪些是旧文件的了。这个思路其实是从 log4j 中学来的。[/quote]   // 限制大小 4MB int limit = 4 * 1024 * 1024; FILE *fp = fopen(file, "w+"); if (fp != NULL) {     fseek(fp, 0, SEEK_END);     int pos = ftell(fp);     while (...) {         // 循环写入数据         pos += fwrite(p, s, 1, fp);         // 如果文件大于指定字节数则关闭改名         // 重新以原始名称打开该文件         if (pos > limit) {             int index = 0;             while (1) {                 char file2[256];                 sprintf(file2, "%s.%d", index++);                 FILE *fp2 = fopen(file2, "r");                 if (fp2 != NULL) {                     fclose(fp2);                 } else {                     fflush(fp);                     fclose(fp);                     rename(file, file2);                     fp = fopen(file, "w+");                     pos = 0;                     break;                 }             }         }     }     fflush(fp);     fclose(fp); }   对于你的这一段函数中，pos += fwrite(p, s, 1, fp);这个的p,s不清楚； sprintf(file2, "%s.%d", file, index++);这个为什么这么写不清楚，为什么第一个是file2,第三个是file； 最后的                     pos = 0;                     break; 这两句不理解。  求大神指教，另外如果说是添加时间又是如何弄的了？

引用引用 12楼 a1317296227的回复 ： 这中方法确实是比较的麻烦，这估计会占用过多的内存吧。  这种方法是比较麻烦，我暂时没有其他更好的办法。不过相比于频繁的操作文件（耗时，在加上flush操作就更麻烦了），占用些内存也无伤大雅。而且缓冲用的buffer不需要太大，可以根据流量设计一个合理的不大不小的值。

引用这中方法  我答案里的方法比较简单，在1楼。

引用 7 楼 a1317296227 的回复:是没有复制完全还是什么的，复制到我这边编译一大堆问题。且不知道各个的作用。 手打的，其中有一处错误，应为：sprintf(file2, "%s.%d", file, index++);我没有编译运行，因为有些变量没有声明，就比如 fwrite 这一行。如果你这个都看不明白的话，那我也没办法。我这个只是给个思路，即文件超出指定大小，则将文件关闭，改名，然后重新创建一个同名文件。举个例子，日志叫 debug.log，首次打开的时候，获取到末尾偏移，也就是大小了，然后每写入一行都会加上写入的字节数，如果超出一定大小，比如 4MB，则关闭该文件，循环查找 debug.log.0、debug.log.1、debug.log.2... 直到某个文件不存在，则将 debug.log 改名为这个名字，然后重新打开 debug.log 以这个名字继续写日志。即 debug.log 永远都是最新的内容。当然，你也可以以年月日时分秒作为后缀作为备份文件名，这样的话就更直观看到哪些是旧文件的了。这个思路其实是从 log4j 中学来的。

fseek(fp_r,0L,SEEK_END); ulFileSize = ftell(fp_r);//文件总的字节数 if( ulFileSize>MAXBUFFER ) {     //Do something.... }

只需要在循环最后检测如果文件大小写满了D关闭文件再用w的方式打开再关闭再用a+方式打开即可继续写入文件。

引用 5 楼 xy_kok 的回复:想来想去没找到限制文件大小的函数原型，估摸着只能自己实现逻辑了。 简单点说：自己添加一个值作为文件的额定大小，操作文件时写入量切勿超过自己设定的额定值；其次fopen中w为清空写，a+为追加写，分情况选择打开文件方式；  #define FILESIZE 12312   // 定义文件大小  1. 获取文件大小(fseek, ftell配合使用) 2.检测当前文件大小与额定值的大小关系 if(filesize < FILESIZE) // 小于额定值 { fopen("xxx.txt", "a+") } else { fopen("xxx.txt", "w"); }  3. 写文件 left = FILESIZE - filesize； // 获取文件剩余量 res = fwrite(....); left -= res； 检测left的值，切勿使其值<=0  这是一个大概的逻辑，有两点需要注意： （1）. 当前逻辑适用于文件多次被打开关闭，如果只打开一次，3的逻辑还要更严谨一些，还要涉及到文件清空的问题； （2）. 文件未满，但需要的写入的量大于剩余量时，如何处理，这需要楼主根据业务要求自行定夺。  通过第二条可以达到一定的预期目的，但是却是把原来的所有数据清空后重新写入的，如果我需要的是只清掉最早的，继续追加写入该如何弄了，就是假设有1000行，需要重新存入新的一行，但是大小已经达到了，这个时候就删除最早的一行，然后就可以写入一行了，这样的要如何操作了？

引用 4 楼 SXJIAKE 的回复:// 限制大小 4MB int limit = 4 * 1024 * 1024; FILE *fp = fopen(file, "w+"); if (fp != NULL) { 	fseek(fp, 0, SEEK_END);     int pos = ftell(fp); 	while (...) { 		// 循环写入数据 		pos += fwrite(p, s, 1, fp); 		// 如果文件大于指定字节数则关闭改名 		// 重新以原始名称打开该文件 		if (pos > limit) { 			int index = 0; 			while (1) { 				char file2[256]; 				sprintf(file2, "%s.%d", index++); 				FILE *fp2 = fopen(file2, "r"); 				if (fp2 != NULL) { 					fclose(fp2); 				} else { 					fflush(fp); 					fclose(fp); 					rename(file, file2); 					fp = fopen(file, "w+"); 					pos = 0; 					break; 				} 			} 		} 	} 	fflush(fp); 	fclose(fp); }   是没有复制完全还是什么的，复制到我这边编译一大堆问题。且不知道各个的作用。

引用 1 楼 fight_in_dl 的回复:引用不知道如何处理 这个问题的关键是限定创建文件的大小，提供一个方法： #include <stdio.h> int main(void) {         int X = 1024 * 1024 - 1;         FILE *fp = fopen("myfile", "w");         fseek(fp, X , SEEK_SET);         fputc('\0', fp);          fclose(fp); } 如何删除文件内容？ fclose(fopen("file.txt", "w")); //w方式打开就会清空文件，之后再用添加模式打开文件即可  完整的程序您可以根据需求编写调试。 看不懂啊，没有注释，和我那个不知道如何结合起来好


Question: 【C语言】如何实现将windows平台下的目录复制到另一个目录下

搜robocopy

引用 6 楼 sunrier 的回复:[quote=引用 5 楼 SXJIAKE 的回复:] /E     Copies directories and subdirectories, including empty ones.        Same as /S /E. May be used to modify /T. Hi，实践你的方法，不行哦，你可以自己试试哦，看来还没有更好的方法了。我现在的实现方法是可以的。就是感觉不简化。[/quote]测试了一下发现，原来 Windows 除了 move 之外，copy 和 xcopy 都不能把原目录自身拷贝到目标目录，只能从把原目录中的文件进行拷贝。这点和 Linux 的 cp、mv 略不同。Windows 的 copy 或 xcopy 来源写成 dir、dir\、dir\* 是一样的意义。而 Linux 系统的 cp 命令，如果来源只写目录名字 dir、dir/，就是连带目录一起拷贝。如果是 dir/* 则拷贝其中的文件，不拷贝来源目录本身。

引用 5 楼 SXJIAKE 的回复:/E     Copies directories and subdirectories, including empty ones.        Same as /S /E. May be used to modify /T. Hi，实践你的方法，不行哦，你可以自己试试哦，看来还没有更好的方法了。我现在的实现方法是可以的。就是感觉不简化。

引用 3 楼 SXJIAKE 的回复:set BASE=E:\Project1 xcopy "%BASE%\dir1" "%BASE%\dir3" /E /C /F /G /R /Y xcopy "%BASE%\dir2" "%BASE%\dir3" /E /C /F /G /R /Y copy "%BASE%\hello.c" "%BASE%\dir3" /Y Hi, 比如目录dir1,dir2下面没有文件，那么也需要把目录dir1,dir2拷贝到dir3下，不单单是dir1或dir2下面的文件。

打错一个字，不是复用资源浏览器， 是使用资源浏览器

引用如果有批处理的方法 批处理相当于小程序，一般使用程序的原因是手工比较繁琐费时。 或者想实现可复用，比如换一个参数就能实现将目录1、目录3 、hello.c复制到目录2。  回到题目，第一个原因不存在，也就是点几个鼠标或者快捷键，并不麻烦。 如果是第二个原因，那怎么设计这个小程序呢，需要再给出更明确的需求说明。 输入参数设定成什么，能让程序知道是将目录1、目录3 、hello.c复制到目录2。 还是将目录1、目录2 、hello.c复制到目录3。 您仔细想想，其实设计这个小程序并不简单，当然，如果你能给出明确的规律，就容易了。  总结：单就这个题目而言，复用资源浏览器，选定、复制即可。           暂时没看出有写批处理(小程序)的必要。


Question: 小白求助，调试时 写入位置冲突。

谢谢谢谢，问题是出在了scanf_s 这块儿 这里后面需要给出一个参数，以表示最多读取多少位字符。 正确格式应该是这样的： scanf_s("%s", name,40); 用逗号隔开.......

scanf_s("%s", name[39]); 如果想获取一个字符串，那么应该传入的是name  size = sizeof name; 这一句不应该是这样吗？  size = sizeof( name );

scanf_s("%s", name);

清晨一顶~清晨一顶~

顶顶顶顶顶顶顶顶顶顶顶顶~


Question: 杭电acm2023求解,运行没问题就是提交不上去

建议你提供一下测试用例

边界条件 输入输出格式 ……


Question: visual studio 2015修改"stdafx.h"头文件

百度搜“stdafx.h”

多谢指导，当时急晕了头，很多东西描述不好，删改后没能看出问题

项目属性----- C/C++  ---------- 预处理器 ---------- 生成与处理文件  --- 否

引用具体 想做什么事情，是怎么做的，期望结果是什么，实际结果是什么 这样描述问题感觉更清晰，也能帮助回答者迅速定位问题。  从图中看，文件名是s.h，没看到stdafx.h。 请检查一下是否因为这个原因导致


Question: VS里怎么设置属性管理器并保存？

谢谢两位的回答

引用没有保存下来  设置好属性表后，需要将其保存。 下面这篇博客有详细的操作步骤 http://www.cnblogs.com/douzi2/p/4229285.html

视图、属性管理器 当前项目、Debug | Win32、Microsoft.Cpp.Win32.user、点鼠标右键、属性、…… 当前项目、Release | Win32、Microsoft.Cpp.Win32.user、点鼠标右键、属性、…… ？


Question: 求助，读取文本中的十进制整数和浮点数，并进行排序。

浮点数格式 http://bbs.csdn.net/topics/390676437


Question: 八皇后

仅供参考：#include <stdio.h> int d[8][8]; int n; void queen8(int L) {     int x,y;      if (8==L) {         n++;         printf("%d\n",n);         for (y=0;y<8;y++) {             for (x=0;x<8;x++) { //              printf("%d",d[y][x]);                 if (d[y][x]) printf("■");                 else         printf("□");             }             printf("\n");         }         return;     }     for (x=0;x<8;x++) {         for (y=0;y<L;y++) {             if  (              d[y][x      ]              || (x-(L-y)>=0 && d[y][x-(L-y)])              || (x+(L-y)< 8 && d[y][x+(L-y)]))                 break;         }         if (y>=L) {             d[L][x]=1;             queen8(L+1);             d[L][x]=0;         }     } } int main() {     int y,x;     for (y=0;y<8;y++) {         for (x=0;x<8;x++) {             d[y][x]=0;         }     }     queen8(0);     return 0; }


Question: 简单文件加解密，但是读不到文件，咋办？

代码没有问题，应该是输入的文件名不存在导致的，确认一下输入文件即可，或者使用perror/strerror检测一下具体错误。  另外提一点，如果加密用的文件比较小，这个程序可能没有问题，但如果加密文件很大的话，那么尝试一次性读取所有文件内容肯定就要出问题了，请注意。

同意楼上的观点 Windows10+VS2015测试没有问题，应该是输入的要加密的源文件不存在导致的 可以把对源文件的操作提前，这样就可以在输入源文件的路径后，就马上能够判断源文件是否存在， 	printf("请输入输入文件名：\n"); 	scanf_s("%s", src_filename,sizeof(src_filename)); 	FILE* fp = NULL; 	fopen_s(&fp, src_filename, "rb"); 	if (NULL == fp) 	{ 		printf("NO!"); 		return 0; 	} 	printf("请输入秘钥：\n"); 	scanf_s("%d", &key); 	printf("请输入输出文件名：\n"); 	scanf_s("%s", dst_filename,sizeof(dst_filename)); 	printf("请输入你需要的操作模式\n1.加密；\n2.解密；\n3.退出\n"); 	scanf_s("%d", &operate_flag);

引用读不到文件 我上机测试代码没有问题。 注意src_filename应该接收正确的文件路径名，且该文件确实已经存在。 如下图，我电脑上之前就有d:\test.txt这个文件。   您可以对照检查一下。

文件加密应该是对已存在的文件进行加密，malloc申请觉得没什么必要，这些申请是在内存上面申请空间，文件属于磁盘内容了。  ...................我也是菜鸟！自学中。。参考下下吧

fp=fopen(src_filename,"rb");制读二进制文件，所以要保证你的路径下有这个文件。


Question: 关于句柄

引用pHandle是句柄 关于句柄的含义，推荐阅读 http://www.cnblogs.com/yellowyu/archive/2009/06/07/1497910.html  从语法角度来讲，句柄类似指针。 至于题目中pHandle怎么用，取决于这两个函数要实现什么功能，要对什么资源进行操作。

_findfirst, _findfirsti64, _wfindfirst, _wfindfirsti64 Provides information about the first instance of a filename that matches the file specified in the filespec argument.  long _findfirst( char *filespec, struct _finddata_t *fileinfo );  __int64 _findfirsti64( char *filespec, struct _finddata_t *fileinfo );  long _wfindfirst( wchar_t *filespec, struct _wfinddata_t *fileinfo );  __int64 _wfindfirsti64( wchar_t *filespec, struct _wfinddata_t *fileinfo );  Function Required Header Compatibility  _findfirst <io.h> Win 95, Win NT  _findfirsti64 <io.h> Win 95, Win NT  _wfindfirst <io.h> or <wchar.h> Win NT  _wfindfirsti64 <io.h> or <wchar.h> Win NT    For additional compatibility information, see Compatibility in the Introduction.  Libraries  LIBC.LIB Single thread static library, retail version  LIBCMT.LIB Multithread static library, retail version  MSVCRT.LIB Import library for MSVCRT.DLL, retail version    Return Value  If successful, _findfirst and _wfindfirst return a unique search handle identifying the file or group of files matching the filespec specification, which can be used in a subsequent call to _findnext or _wfindnext, respectively, or to _findclose. Otherwise, _findfirst and _wfindfirst return –1 and set errno to one of the following values:  ENOENT  File specification that could not be matched  EINVAL  Invalid filename specification  Parameters  filespec  Target file specification (may include wildcards)  fileinfo  File information buffer  Generic-Text Routine Mappings  TCHAR.H Routine  _UNICODE & _MBCS Not Defined _MBCS Defined _UNICODE Defined  _tfindfirst _findfirst _findfirst _wfindfirst  _tfindfirsti64 _findfirsti64 _findfirsti64 _wfindfirsti64    System Calls Routines |  _find, _wfind Function Overview

资料有限，没法去猜测，还是问规定的人吧？问清楚为什么要这么设计，每个参数代表什么，函数功能是怎么样的？

这个你最好问你的老师

引用 1 楼 jianwen0529 的回复:这不是你自己定义的函数吗？  是的,这是老师给我写的,它说这是句柄,让我这样定义函数,但是我不知道它应该怎么用

这不是你自己定义的函数吗？


Question: 为什么这里要有个（ret！=1）能解释下result的公式的思维

好的谢谢你的帮助

ret = scanf("%d", &man); ret是接受scanf返回值，表示成功读入多少个值，这里仅仅读取一个值 ret != 1则说明读取失败（比如流发生错误，又如要接收一个int值，却给出了字符/字符串等）  公式那得看你程序是想做什么的


Question: C语言如何在栈返回前插入代码

不要企图优雅的结束（因为这是不可能办到的） 而要在烂的不能再烂的摊子上也能重整河山！  http://bbs.csdn.net/topics/390787357


Question: C语言输出表格的问题

仅供参考：#include <stdio.h> #include <time.h> #include <stdlib.h> #define MAXX 10 #define MAXY 10 void main() {     char MAP[MAXX][MAXY];     char str;     int x,y,z,f,n;      for (x=0;x<MAXX;x++) {         for (y=0;y<MAXY;y++) {             MAP[x][y]='.';         }     }      for (x=0;x<MAXX;x++) {         printf("\n");         for (y=0;y<MAXY;y++) {             printf("%c",MAP[x][y]);         }     }     printf("\n");      srand((unsigned) time(NULL)); RETRY:     x=0;y=0;str='A';MAP[x][y]=str;      for (str='B';str<='Z';str++) {         n=0;         f=1;         while (1) {             n++;             z=rand()%4;             switch (z) {                 case 0: if (y+1<MAXY && MAP[x  ][y+1]=='.') {y++;MAP[x][y]=str;f=0;} break;                 case 1: if (x+1<MAXX && MAP[x+1][y  ]=='.') {x++;MAP[x][y]=str;f=0;} break;                 case 2: if (y-1>0    && MAP[x  ][y-1]=='.') {y--;MAP[x][y]=str;f=0;} break;                 case 3: if (x-1>0    && MAP[x-1][y  ]=='.') {x--;MAP[x][y]=str;f=0;} break;             }             if (f==0) break;             if (n>200) {//钻入死胡同                 for (x=0;x<MAXX;x++) {                     for (y=0;y<MAXY;y++) {                         MAP[x][y]='.';                     }                 }                 goto RETRY;             }         }//while         if (x==MAXX-1 || y==MAXY-1) break;     }//for      for (x=0;x<MAXX;x++) {         printf("\n");         for (y=0;y<MAXY;y++) {             printf("%c",MAP[x][y]);         }     }     printf("\n"); }

不能，自己先把格式组织起来（存储在另外的结构中，如果数据同时已知的可以按照你的方式交叉写入）


Question: const int全局变量数组初始化

引用 23 楼 lin5161678 的回复:int i = 0; i += ++i + ++i;  i 是多少?  这种问题, 写代码跑一下就知道了. 没必要解释. 如果在工作中写这种代码, 保证被吐槽到死

引用 22 楼 xiaohuh421 的回复:[quote=引用 21 楼 lin5161678 的回复:] [quote=引用 20 楼 xiaohuh421 的回复:] [quote=引用 18 楼 lin5161678 的回复:] [quote=引用 17 楼 xiaohuh421 的回复:] const int SIZE = 3;   *(int*)&SIZE = 100; 这是错的 企图修改一个const限定的变量是不可取的[/quote]  这就是C/C++的特点, 虽然法律规定了不能杀人, 杀人不好, 但实际上还是可以杀的, 只是后果自负. [/quote]不想和你谈论乱扯的比喻 你就告诉我 你这样做了之后 SIZE的值是多少了[/quote] 依赖于编译器实现吧,  在VS中, 如果你是直接使用的SIZE, 那么它会参编译时就确定(常量替换).  如果使用指针访问它, 那么会变成修改后的值.[/quote] int i = 0; i += ++i + ++i;  i 是多少?

引用 21 楼 lin5161678 的回复:[quote=引用 20 楼 xiaohuh421 的回复:] [quote=引用 18 楼 lin5161678 的回复:] [quote=引用 17 楼 xiaohuh421 的回复:] const int SIZE = 3;   *(int*)&SIZE = 100; 这是错的 企图修改一个const限定的变量是不可取的[/quote]  这就是C/C++的特点, 虽然法律规定了不能杀人, 杀人不好, 但实际上还是可以杀的, 只是后果自负. [/quote]不想和你谈论乱扯的比喻 你就告诉我 你这样做了之后 SIZE的值是多少了[/quote] 依赖于编译器实现吧,  在VS中, 如果你是直接使用的SIZE, 那么它会参编译时就确定(常量替换).  如果使用指针访问它, 那么会变成修改后的值.

引用 20 楼 xiaohuh421 的回复:[quote=引用 18 楼 lin5161678 的回复:] [quote=引用 17 楼 xiaohuh421 的回复:] const int SIZE = 3;   *(int*)&SIZE = 100; 这是错的 企图修改一个const限定的变量是不可取的[/quote]  这就是C/C++的特点, 虽然法律规定了不能杀人, 杀人不好, 但实际上还是可以杀的, 只是后果自负. [/quote]不想和你谈论乱扯的比喻 你就告诉我 你这样做了之后 SIZE的值是多少了

引用 18 楼 lin5161678 的回复:[quote=引用 17 楼 xiaohuh421 的回复:] const int SIZE = 3;   *(int*)&SIZE = 100; 这是错的 企图修改一个const限定的变量是不可取的[/quote]  这就是C/C++的特点, 虽然法律规定了不能杀人, 杀人不好, 但实际上还是可以杀的, 只是后果自负.

不要纠结各种常量了，这个世界上唯一不变的就是变化。用API WriteProcessMemory还能修改正运行的其它进程的内存里面的所谓常量呢！

引用 17 楼 xiaohuh421 的回复:const int SIZE = 3;   *(int*)&SIZE = 100; 这是错的 企图修改一个const限定的变量是不可取的

const int全局变量数组如何使用函数初始化，我的这个数组比较长，所以想要用函数初始化？  按语法,定义成const 的变量, 只能在定义的时候初始化, 比如  const int SIZE = 3;   然后调用  SIZE = 5; 这样是不允许的.  但是呢, C++的一个特点是指针.   你可以这样来修改它. *(int*)&SIZE = 100;  又但是 如果你代码中有如下的语句. const int SIZE = 3;   *(int*)&SIZE = 100; string strs[SIZE];  //  这里应该仍然会是3, 而不是你想的100.  所以, 虽然你可以修改const变量, 但是可能达不到你想要的目的.  怎么让函数返回数组，然后整体初始化呢.  函数返回数组肯定是可以的. 可能通过参数返回, 也可能通过函数返回值返回. 其中通过参数返回时, 可以函数外部申请好数组空间, 函数内部填充数据, 也可能通过指针,直接返回内部动态申请的数组.  数组整体初始化, 如果是初始化成同一个变量, 可以使用memset, 否则就只能按需赋值了.   全局变量初始化应该在主函数之前的吧。 全局变量初始化肯定是在main函数前的, 它在main之前就会分配好内存空间了.

引用 13 楼 zhao4zhong1 的回复:[quote=引用 10 楼 u011609112 的回复:] LZ的核心是定义变量时输入{}内数据太多麻烦，  如果数据不是海量，可以简单写个函数，将你要初始化时的数据写txr文件保存格式如   1,2,3,4,.......，然后拷贝到   const int a[xxxx]={}   的大括号内 了解一下代码生成技术。[/quote]  我理解LZ的需求就是我说的那样，应该涉及不到那么复杂吧？

全局变量定义之后若未显示初始化，则也会隐式初始化；默认const int定义的初始化都为0；

const  变量定义之后不可修改

引用 10 楼 u011609112 的回复:LZ的核心是定义变量时输入{}内数据太多麻烦，  如果数据不是海量，可以简单写个函数，将你要初始化时的数据写txr文件保存格式如   1,2,3,4,.......，然后拷贝到   const int a[xxxx]={}   的大括号内 了解一下代码生成技术。

还是不要设为const比较好

严格意义上说，定义时赋值才叫初始化，否则都只能叫再赋值。 const 的全局变量只能在定义时就初始化，const的全局数组只能用{ }初始化，不排除可能有编译器支持用指针强转在在main函数开头赋值。  c语言可没有返回数组的说法，返回数组指针或者返回包装有数组的结构体到是有可能，但是数组也不能有除了 = { }之外的其它初始化方法。  为什么要定义为const？？？这才是问题所在。

这招，我以前经常用

引用 5 楼 lin5161678 的回复:可以考虑  const int arr[] =  { 	#include "arr.date" } arr.data 就自己写代码生成一个  咦，这样写， 似乎可以有

contst 不 是限制修改了吗？

static int arr[1024]; static int isInit;  void InitArr() { 	isInit = 1; 	//初始化arr  } const int *GetArr() { 	if(isInit) 		InitArr(); 	return const_cast<const int *>(arr); } 忘记 const 了  尴尬


Question: 关于文件输入输出的问题，出现缓冲器溢出，希望大家帮我解答一下！

a的下标越界，要对下标做判断

解答一下 数组越界访问，a数组大小为23，C语言中数组索引从0开始，这样最多到a[22] 		while ((fgets(s, 100, fp)) != NULL) { 			lines++;  //增加索引 			a[lines] = atoi(s); // 会执行a[23] = atoi(s)，超过a[22]，越界。 			if (lines == 23) { //当等于23时，才退出循环，不完全清楚你代码的逻辑，改成 == 22 试试? 				break; 			} 		}

代码如上，发生错误缓冲区溢出。。。希望大家能帮我解答一下，最好是能帮我改一下！感激不尽！


Question: if条件不满足，但是进入分支执行

引用找到原因了  学习了，谢谢~

请教了一下前辈。找到原因了。原因是在未按下按键时，我在按键扫描程序里没有把键值清零。虽然key_flag_1按键标志清零了，下次按键已经附新键值，以为不会发生错误。但是没有考虑到可能在判断完(key_number == 4)满足后突然进入中断，之后key_flag_1在中断中被执1，此时不会再判断第一个条件。 解决办法 可以在按键程序里，没按键时键值清零； 可以在每个按键分支中清零； 可以把按键判断也放在中断中键值判断后执行。  印象中觉得这种情况不容易发生，结果概率挺高的样子。 而且感觉除了这个也没别的理由了。如果不是这个原因再补充。

引用 2 楼 fight_in_dl 的回复:引用进入键值为1的分支 从物理角度讲，按键的按下和释放有耗时， 应该合理的设定时间间隔，以判断究竟是两次按键还是一次按键。目前测试发现，按第一个按键，间隔一段时间按第二个也会发生这个情况。而且按键程序在别的地方也正常使用。应该不是按键程序问题。

可能是中断执行时间过长导致的吗？发生频率挺高，不过有时候也不会发生。

其它地方被改写了？


Question: 字符串的输入

指向一个可用的空间，指针变量只能存放地址，你想要存放字符串，用什么空间来存放呢？

为什么要关联，关联的作用是什么，是要获得分配的空间的吗

#include <stdio.h> int main() {     char *buf=NULL;//定义初始化     char a[100]={0};     buf=a;//关联，绑定变量     scanf("%s",buf);//使用     printf("%s\n",buf);//使用     return 0; }   这样就可以了

你的意思是这样吗 char name[10]; scanf("%s",name); char *s=name;

3步：定义，关联，使用，你这没有关联吧

char name[32]; scanf("%s",name);

引用这为什么不行 C/C++语言中，NULL宏定义如下：  #define NULL 0 地址为0的内存空间，用户没有权限访问。  正确的使用方式有两种: 1  	char ab[10]; //数组名ab为字符数组的首地址 	char *name = ab; //初始化name指针，name与ab指向同一个合法地址 	scanf("%s", name); 2 	char *name = (char*)malloc(10); //动态申请内存空间 	scanf("%s", name);


Question: C语言读取文件某些特定字符串的问题

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

用c语言这样做已经很不错了，更好的办法是不用c语言，比如awk(当然只有linux下才有用)


Question: 小白请教编程大牛

百度一下，就有代码

引用并记录所经过的节点  可以参考： http://download.csdn.net/detail/dcmengqiuyang/6838167 输入输出格式这部分可能和你的需求有差异，但关键逻辑代码应该能用上。


Question: 读取txt中浮点数问题

Format Specification Fields: scanf and wscanf Functions A format specification has the following form:  % [width] [{h | l | I64 | L}]type  The format argument specifies the interpretation of the input and can contain one or more of the following:   White-space characters: blank (' '); tab ('\t'); or newline ('\n'). A white-space character causes scanf to read, but not store, all consecutive white-space characters in the input up to the next non–white-space character. One white-space character in the format matches any number (including 0) and combination of white-space characters in the input.   Non–white-space characters, except for the percent sign (%). A non–white-space character causes scanf to read, but not store, a matching non–white-space character. If the next character in stdin does not match, scanf terminates.   Format specifications, introduced by the percent sign (%). A format specification causes scanf to read and convert characters in the input into values of a specified type. The value is assigned to an argument in the argument list.  The format is read from left to right. Characters outside format specifications are expected to match the sequence of characters in stdin; the matching characters in stdin are scanned but not stored. If a character in stdin conflicts with the format specification, scanf terminates, and the character is left in stdin as if it had not been read.  When the first format specification is encountered, the value of the first input field is converted according to this specification and stored in the location that is specified by the first argument. The second format specification causes the second input field to be converted and stored in the second argument, and so on through the end of the format string.  An input field is defined as all characters up to the first white-space character (space, tab, or newline), or up to the first character that cannot be converted according to the format specification, or until the field width (if specified) is reached. If there are too many arguments for the given specifications, the extra arguments are evaluated but ignored. The results are unpredictable if there are not enough arguments for the format specification.  Each field of the format specification is a single character or a number signifying a particular format option. The type character, which appears after the last optional format field, determines whether the input field is interpreted as a character, a string, or a number.   The simplest format specification contains only the percent sign and a type character (for example, %s). If a percent sign (%) is followed by a character that has no meaning as a format-control character, that character and the following characters (up to the next percent sign) are treated as an ordinary sequence of characters, that is, a sequence of characters that must match the input. For example, to specify that a percent-sign character is to be input, use %%.  An asterisk (*) following the percent sign suppresses assignment of the next input field, which is interpreted as a field of the specified type. The field is scanned but not stored.

等宽位数，读取的时候设定宽度读取到字符串然后转换atof

引用 3 楼 qq_35359073 的回复:[quote=引用 2 楼 sdghchj 的回复:]      double a[100];     int n = 0;     FILE* f = fopen("a.txt","r");      while(EOF != fscanf(f,"%5lf",a + n)){         printf("%lf ",a[n]);         ++ n;     }      fclose(f);  是不是 fscanf函数读取的过程中，遇到空格制表符或者其他的非读取格式字符，无论是否读取完制定长度，都会停止读取呢？[/quote] 是。

引用 2 楼 sdghchj 的回复:     double a[100];     int n = 0;     FILE* f = fopen("a.txt","r");      while(EOF != fscanf(f,"%5lf",a + n)){         printf("%lf ",a[n]);         ++ n;     }      fclose(f);  是不是 fscanf函数读取的过程中，遇到空格制表符或者其他的非读取格式字符，无论是否读取完制定长度，都会停止读取呢？


Question: 求助，编写文本挖掘的编程用于毕业论文，付费！搜索词语在一篇word文档中是否出现，出现为1，没出现为0，最后结果显示在excel里。

举例说明：A公司只提供循环泵    B公司只提供启动器。  如果搜索A公司，是有的，搜索启动器也是有的，那么  A公司 启动器  【都可以搜到】应该显示1. 同理：B公司 和循环泵也是应该出现的。  综上，需求非常不明确，无法编程实现。除非能将需求进一步细化【如：从同一行数据里面提取】

引用 2 楼 qq_39543148 的回复:我没学过编程，如果可以的话，能不能麻烦帮我编写。谢谢了 有偿提供帮助。QQ见我的个人资料。

C# 一天即可，你可以网上搜索相关的操作

我没学过编程，如果可以的话，能不能麻烦帮我编写。谢谢了


Question: 求助 c程序设计语言上一个关于空间分配的函数不懂，求老司机带带

你猜得对。它记录数组首地址，以后内存分配时，就返回该该地址，然后将该指针往后移动标志未使用内存的首地址。释放内存的时候该指针往前移。


Question: 用线性链表对一个文档中的数据进行提取，跑程序的时候发现有个大问题...求高人指点！

引用 3 楼 user-1 的回复:[quote=引用 2 楼 github_39501974 的回复:] [quote=引用 1 楼 user-1 的回复:] 得到行数后，rewind一下，再fscanf 刚试了 的确OK了！ 我再多请教一个问题：我如果要对链表里的数据进行升序排序并只输出前10个 这个该怎么做呢？[/quote] 链表排序网上搜，一大堆方法。只输出前10个应该好办，遍历时计一下数就行。 [/quote]  已解决 感谢！

引用 2 楼 github_39501974 的回复:[quote=引用 1 楼 user-1 的回复:] 得到行数后，rewind一下，再fscanf 刚试了 的确OK了！ 我再多请教一个问题：我如果要对链表里的数据进行升序排序并只输出前10个 这个该怎么做呢？[/quote] 链表排序网上搜，一大堆方法。只输出前10个应该好办，遍历时计一下数就行。

引用 1 楼 user-1 的回复:得到行数后，rewind一下，再fscanf 刚试了 的确OK了！ 我再多请教一个问题：我如果要对链表里的数据进行升序排序并只输出前10个 这个该怎么做呢？

得到行数后，rewind一下，再fscanf


Question: 关于参数的入栈和自增

引用 7 楼 yirol_ 的回复:[quote=引用 1 楼 lin5161678 的回复:] 代码错了 这是未定义行为  编译器处理方式无法确定 有多种不同输出 没有意义    这个应该是和编译器有关系。我用的是gcc[/quote]  这个跟ABI有关，编译器是按照ABI来实现，如果ABI未定义或者定义不清晰，不同编译器会有不同处理方式。但是像函数入栈顺序，这个肯定ABI定义的很清楚

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

引用 6 楼 wang0635 的回复:谁说“参数是从右向左入栈的”？你的意思是从左向右？

这个跟编译器有关，能看反汇编的话去看看，反正VC6存的都是0

这样的问题不值得研究，这样的代码没有实用价值，工作中不能用，如果你常写出这样的代码，或许你离下岗只有半步之遥了。

这个跟printf进栈出栈的顺序有关

因为你直接调用库输里面的标准出函数printf(),你根本不知道在库函数printf()里面他是按什么顺序处理这些运算的，所以出来的结果是无法预知的。如果你要实现显示自增的数值，建议规范代码的书写格式，例如： int main() {   int a = 0;   int b,c,d;   b = a++;   c = a++;   d = ++a;   printf("%d,%d,%d",b,c,d);   / /出来的结果就是0,1,3  }

关于C,C++表达式求值顺序 http://blog.csdn.net/fefe82/article/details/37833767，http://bbs.csdn.net/topics/370153775

引用 7 楼 yirol_ 的回复:这个应该是和编译器有关系。我用的是gcc代码错了 你用什么编译器都一样  gcc 一样有不同的运行结果  你开优化看看

引用 8 楼 yirol_ 的回复:[quote=引用 5 楼 baidu_37097818 的回复:] 旁边如果真有人这么写就会被我打一顿  一般情况下肯定不能这么写，我只是想知道这里是怎么样的？[/quote] 怎么样都可能。

未定义行为，后期还有优化行为，全是0 0 0 0 0 ，或者全部 5 5 5 5 都可能

引用 5 楼 baidu_37097818 的回复:旁边如果真有人这么写就会被我打一顿  一般情况下肯定不能这么写，我只是想知道这里是怎么样的？

引用 1 楼 lin5161678 的回复:代码错了 这是未定义行为  编译器处理方式无法确定 有多种不同输出 没有意义    这个应该是和编译器有关系。我用的是gcc

谁说“参数是从右向左入栈的”？

旁边如果真有人这么写就会被我打一顿

这个练不出水平，感觉

还是要尽量规范的写

代码错了 这是未定义行为  编译器处理方式无法确定 有多种不同输出 没有意义


Question: C语言可以像fortran一样读取数据直接到数组么？

不可以，需要自己实现类似的函数


Question: C语言如何定位并抓取文件中的特定字符串

引用 3 楼 lonmecy 的回复:[quote=引用 2 楼 战在春秋的回复:]引用该如何抓取inname后的字符串呢？ 读第一个文件的代码如下：(测试通过) #include<stdio.h> #include<stdlib.h> #include <string.h>  int main() { 	FILE *file; 	char line[64]; //接收文件每行 	char result[32][64]; //二维数组，存放结果字符串 	int i = 0; 		 	file = fopen("d:\\test.txt", "r"); 	if (file == NULL) 		exit(EXIT_FAILURE);  	while (fgets(line, sizeof(line), file)) {  //用fgets函数逐行读取到line 		char *pLast = strrchr(line, '=');  //用strrchr查找'='字符最后出现的位置, 		if (NULL != pLast)        		{ 			strcpy(result[i], pLast + 1);  //将每行最后一个"="之后的字符赋给result 		} 		i++;  //以题目第一个文件为例子，最后i值为4。result[0]到result[4]即为所需要的结果 	} 	fclose(file); 	exit(EXIT_SUCCESS); } 说明： 1 题目中有C语言这几个字，我理解就只能用C的东西，不考虑C++的函数。 2 第二个文件的处理方法类似，查找'='字符或者空格字符出现的位置，再进行处理。 十分感谢！这个二位数组是不是一个存放字符串的一维数组？[/quote] 一个二位数组，char resutl[32][64] ,代表这个二维数组能存放32条信息，每条信息不超过64个字节

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

比如： char str[n][m]; 二维数组str由n个一维数组组成，每个一维数组可存放一个字符串(长度不超过m)。

引用这个二位数组是不是一个存放字符串的一维数组 是的，二维字符数组的每一行就是一个字符串。

这个基础，参考楼上

引用 2 楼 战在春秋的回复:引用该如何抓取inname后的字符串呢？ 读第一个文件的代码如下：(测试通过) #include<stdio.h> #include<stdlib.h> #include <string.h>  int main() { 	FILE *file; 	char line[64]; //接收文件每行 	char result[32][64]; //二维数组，存放结果字符串 	int i = 0; 		 	file = fopen("d:\\test.txt", "r"); 	if (file == NULL) 		exit(EXIT_FAILURE);  	while (fgets(line, sizeof(line), file)) {  //用fgets函数逐行读取到line 		char *pLast = strrchr(line, '=');  //用strrchr查找'='字符最后出现的位置, 		if (NULL != pLast)        		{ 			strcpy(result[i], pLast + 1);  //将每行最后一个"="之后的字符赋给result 		} 		i++;  //以题目第一个文件为例子，最后i值为4。result[0]到result[4]即为所需要的结果 	} 	fclose(file); 	exit(EXIT_SUCCESS); } 说明： 1 题目中有C语言这几个字，我理解就只能用C的东西，不考虑C++的函数。 2 第二个文件的处理方法类似，查找'='字符或者空格字符出现的位置，再进行处理。 十分感谢！这个二位数组是不是一个存放字符串的一维数组？

1： scanf 正则表达式 fscanf正则表达式  2： getline获取流中的一行字符串 strstr  查找特定字符串


Question: 新手求助，有关同步读取和异步读取的问题

引用 1 楼 lian34jian 的回复:刚刚试了一次，明白了，用同步的话read会一直拿着HANDLE 造成死锁？不知道这叫不叫死锁，反正就是read一直在等待，然后write拿不到HANDLE也完成不了  是死锁

同步 可能 阻塞 ， 异步不会阻塞。直接返回。

楼主可以继续看看关于自旋锁、信号量等相关内容。