Question: 请教如何把结构体数组里的内容用fwrite写到文本文件？谢谢

引用 12 楼 startstop2015 的回复:[quote=引用 9 楼 zhao4zhong1 的回复:] 电脑内存或文件内容只是一个一维二进制字节数组及其对应的二进制地址； 人脑才将电脑内存或文件内容中的这个一维二进制字节数组及其对应的二进制地址的某些部分看成是整数、有符号数/无符号数、浮点数、复数、英文字母、阿拉伯数字、中文/韩文/法文……字符/字符串、汇编指令、函数、函数参数、堆、栈、数组、指针、数组指针、指针数组、数组的数组、指针的指针、二维数组、字符点阵、字符笔画的坐标、黑白二值图片、灰度图片、彩色图片、录音、视频、指纹信息、身份证信息……  推荐使用WinHex软件查看硬盘或文件或内存中的原始字节内容。  不要把 fopen("...","...");fscanf,fprintf,fgets,fgetc,fclose //读时把\r\n替换成\n，写时把\n替换成\r\n;读到\x1a就设置EOF;读写的内容当字符看待 和 fopen("...","...b");fseek,ftell,fread,fwrite,fgetc,fclose //不作以上替换，遇到\x1a仍继续读;读写的内容当字节看待 弄混了 谢谢，我看不懂，请教如何用winhex查看结构体数组里保存的内容？[/quote] 参考WinHex联机帮助和网上相关博客文章。 https://www.baidu.com/s?wd=WinHex&rsv_spt=1&issp=1&f=8&rsv_bp=1&rsv_idx=2&ie=utf-8&tn=baiduhome_pg&rsv_enter=0&oq=WinHex&rsv_t=b89bhqvghZ9KJ39cyIMmBG7JlkSxv8bcp7lbRrPMKO99GWwYA%2BINke%2BJRuaVThZ%2FebB%2F&rsv_pq=f2d7376a000834ec

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

去问微软。

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

如何结构体  引用 7 楼 zhao4zhong1 的回复:[/code] 谢谢 struct stru_salary {   double  salary[100][15];   char    name[100][15]; };  struct stru_salary *array_sal; array_sal=(struct stru_salary *)malloc(sizeof(struct stru_salary));  此时，我发现不能直接fwrite这个结构体数组，格式是乱的  假设array_sal有100条记录，如何把这100条记录memcpy到其它内存区域， 假设其它内存区域名字是A,然后把A一次性用fwrite写到文本？

仅供参考：#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("\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("\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("\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("\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("\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("\n");     return 0; } //AD.a 0 //AD.b 4 //AD.c 24 // //A1.a 0 //A1.b 4 //A1.c 17 // //A2.a 0 //A2.b 4 //A2.c 18 // //A4.a 0 //A4.b 4 //A4.c 20 // //A8.a 0 //A8.b 4 //A8.c 24 // //A16.a 0 //A16.b 4 //A16.c 24 // //

一般工作中数据保存, 建议是保存二进制数据, 这时所有数据都是二进制保存在文件中, 查看数据需要UtralEdit这样的二进制数据查看工具.  当然, 如果只为学习, 为了所有数据都以字符串方式展现, 那就格式化成字符串, 然后保存, 读取的时候把字符串再转换回来

格式化输入比较好，读起来也容易

如果要写入文本的话，不能用fwrite了，得用fprintf格式化输出文本。写一个函数，专门负责结体的输出

这跟写入一般变量是一样的，参考例子：  struct A { 	int data; };  int main() {    	A a; 	a.data = 1; 	FILE* pfile; 	pfile = fopen("test.txt", "w"); 	fwrite(&a, sizeof(a), 1, pfile); 	fclose(pfile);     return 0;    }

引用 1 楼 user-6 的回复:二进制打开写入 谢谢，是写入文本文件啊，具体该怎么实现？

二进制打开写入


Question: 指针指向字符串

注意 char *s="123"; 和char s[]="123";的区别。 后者等同于char s[]={'1', '2', '3', '\0'};

你的字符指针指向的是一个常量字符串，你修改肯定出错  char string[]="123456";就可以了

char *string="123456"; 中的 "123456"是存在程序的“常量区”，而常量区的内容默认是不允许修改的，因此string[2]='a';修改了常量区的内容，会报错。 解决办法是不要定义在常量区，而是定义在堆或者栈区： char string[] = "123456";

实际是char const *string = "123456"; 字符串的内存在常量区，不能变


Question: C语言字符串查找问题

这样可好：  #include <stdio.h> #include <math.h> char s[] = "qwertyuiop"; int pos[256]; int i, j, k, L, dis; char buf[256]; int main(void) { 	dis = 0; 	scanf("%s", buf); 	L = strlen(s); 	for (i = 0; i < L; i++) 		pos[s[i]] = i; 	L = strlen(buf); 	for (i = 0; i < L - 1; i++) 	{ 		dis += abs(pos[buf[i]] - pos[buf[i + 1]]); 	} 	printf("dis=%d\n", dis); 	return 0; }

写成函数形式呢int minDistance(char* szKeyBoard,char* szWord)？


Question: 如何正确用realloc函数

引用 2 楼 CharlesSimonyi的回复:p=(char*)realloc(q,16); p=(char*)realloc(q,16);[/quote] 已经成功了，非常感谢！

仅供参考：//文件1中的内容排序并去重,结果保存到文件2中 #include <stdio.h> #include <stdlib.h> #include <string.h> #define MAXCHARS 128      //能处理的最大行宽,包括行尾的\n和字符串尾的\0 int MAXLINES=10000,MAXLINES2; char *buf,*buf2; int c,n,hh,i,L; FILE *f; char ln[MAXCHARS]; int ignore_case=0; int icompare(const void *arg1,const void *arg2) {    return stricmp((char *)arg1,(char *)arg2); } int compare(const void *arg1,const void *arg2) {    return strcmp((char *)arg1,(char *)arg2); } int main(int argc,char **argv) {     if (argc<3) {         printf("Unique line. Designed by zhao4zhong1@163.com. 2012-08-20\n");         printf("Usage: %s src.txt uniqued.txt [-i]\n",argv[0]);         return 1;     }     if (argc>3) ignore_case=1;//若存在命令行参数3，忽略大小写     f=fopen(argv[1],"r");     if (NULL==f) {         printf("Can not find file %s!\n",argv[1]);         return 1;     }     buf=(char *)malloc(MAXLINES*MAXCHARS);     if (NULL==buf) {         fclose(f);         printf("Can not malloc(%d LINES*%d CHARS)!\n",MAXLINES,MAXCHARS);         return 2;     }     n=0;     hh=0;     i=0;     while (1) {         if (NULL==fgets(ln,MAXCHARS,f)) break;//         hh++;         L=strlen(ln)-1;         if ('\n'!=ln[L]) {//超长行忽略后面内容             printf("%s Line %d too long(>%d),spilth ignored.\n",argv[1],hh,MAXCHARS);             while (1) {                 c=fgetc(f);                 if ('\n'==c || EOF==c) break;//             }         }         while (1) {//去掉行尾的'\n'和空格             if ('\n'==ln[L] || ' '==ln[L]) {                 ln[L]=0;                 L--;                 if (L<0) break;//             } else break;//         }         if (L>=0) {             strcpy(buf+i,ln);i+=MAXCHARS;             n++;             if (n>=MAXLINES) {                 MAXLINES2=MAXLINES*2;                 if (MAXLINES2==1280000) MAXLINES2=2500000;                 buf2=(char *)realloc(buf,MAXLINES2*MAXCHARS);                 if (NULL==buf2) {                     printf("Can not malloc(%d LINES*%d CHARS)!\n",MAXLINES2,MAXCHARS);                     printf("WARNING: Lines >%d ignored.\n",MAXLINES);                     break;//                 }                 buf=buf2;                 MAXLINES=MAXLINES2;             }         }     }     fclose(f);     if (n>1) {         if (ignore_case) qsort(buf,n,MAXCHARS,icompare);         else qsort(buf,n,MAXCHARS,compare);     }     f=fopen(argv[2],"w");     if (NULL==f) {         free(buf);         printf("Can not create file %s!\n",argv[2]);         return 2;     }     fprintf(f,"%s\n",buf);     if (n>1) {         if (ignore_case) {             hh=0;             L=MAXCHARS;             for (i=1;i<n;i++) {                 if (stricmp((const char *)buf+hh,(const char *)buf+L)) {                     fprintf(f,"%s\n",buf+L);                 }                 hh=L;                 L+=MAXCHARS;             }         } else {             hh=0;             L=MAXCHARS;             for (i=1;i<n;i++) {                 if ( strcmp((const char *)buf+hh,(const char *)buf+L)) {                     fprintf(f,"%s\n",buf+L);                 }                 hh=L;                 L+=MAXCHARS;             }         }     }     fclose(f);     free(buf);     return 0; }


Question: uefi下的hwmonitor

哎哟  不错哦

这方面的开源项目参考一下。

不会不会不会不会


Question: C语言用scanf清理输入缓存的一个程序,程序运行结果不理解

理解和讨论之前请先学会如何观察！  计算机组成原理→DOS命令→汇编语言→C语言（不包括C++）、代码书写规范→数据结构、编译原理、操作系统→计算机网络、数据库原理、正则表达式→其它语言（包括C++）、架构……  对学习编程者的忠告： 多用小脑和手，少用大脑、眼睛和嘴，会更快地学会编程！ 眼过千遍不如手过一遍！ 书看千行不如手敲一行！ 手敲千行不如单步一行！ 单步源代码千行不如单步Debug版对应汇编一行！ 单步Debug版对应汇编千行不如单步Release版对应汇编一行！  VC调试时按Alt+8、Alt+7、Alt+6和Alt+5,打开汇编窗口、堆栈窗口、内存窗口和寄存器窗口看每句C对应的汇编、单步执行并观察相应堆栈、内存和寄存器变化，这样过一遍不就啥都明白了吗。 对VC来说，所谓‘调试时’就是编译连接通过以后，按F10或F11键单步执行一步以后的时候，或者在某行按F9设了断点后按F5执行停在该断点处的时候。 （Turbo C或Borland C用Turbo Debugger调试,Linux或Unix下用GDB调试时,看每句C对应的汇编并单步执行观察相应内存和寄存器变化。）  提醒：scanf是开源的。你可以单步到scanf的实现中一探究竟。  先 http://www.microsoft.com/visualstudio/chs/downloads#d-2010-express 点开Visual C++ 2010 Express下面的语言选‘简体中文’，再点立即安装  再参考： C:\Program Files\Microsoft Visual Studio 10.0\VC\crt\src\input.c

引用 1 楼 zhao4zhong1 的回复:在每个最后不带\n的printf后面加fflush(stdout); 在每个不想受接收缓冲区旧内容影响的scanf前面加rewind(stdin); 另外请检查scanf的返回值。 //请今后要用 int c; scanf("%c",&c); //时，都改为 char s[2]; int c; scanf("%1s",s); c=s[0];  scanf("%*[^\n]"); scanf("%*e");这两句上面一个是去掉\n前的所有字符,后面是去掉\n,你是否运行过我那段程序?结果也是那么怪吗?能解释为什么结果那么怪吗?


Question: 结构体数组指针如何引用？

我觉得lz应该再看看书或者教程 struct STU {     int a;     int b; };  void input(STU* p) {     p->a = 0; }  int main(void) {     STU stu[50];     STU *pstu = stu;     input(pstu);     return 0; }


Question: 求大神帮忙，最高悬赏！！

引用 10 楼 赵4老师的回复:倒推法？ 嗯，是的，不过手机党真的无力，帮忙把代码补全吧，反正程序简单直接goto省事，

第一眼也想到从后往前推。应该可以用递推，让我看看楼上的大神们

倒推法？

能不能直接实现一下，把代码写出来？

long last,sum; last=0; loop: last++; sum=last*m+1; for(int i=1;i<m;i++) { if(sum%(m-1)) goto loop;  sum=sum/(m-1)*m+1; }  最后剩下的桃子数为last*m+1; 猴子数为m 总桃子数为sum 我是用手机答的，所以比较麻烦，就直接使用goto语句了，正常情况你可以用变量来控制

首先，只把它看成是一个数学题。貌似，这题小学生估计也能解吧？  然后，将数学题得到的式子，用计算机表达出来。

引用 7 楼 adusuccessfully 的回复:[quote=引用 6 楼 u014444402 的回复:] 抛砖引玉，出个暴力算法。  #include <stdio.h>  int GetPeachNum( int monkey ); int GetLastNum( int m, int n ); int main() { 	int i; 	for ( i=3; i<=9; i++ ) 	{ 		printf( "%d ", GetPeachNum(i) ); 	}  	printf( "\r\n" ); 	getchar(); 	return 0; }  int GetPeachNum( int monkey ) { 	int i, j; 	int temp;  	for ( i=1;; i++ )//这里可以设置超时，以防找不到死循环 	{ 		temp = i; 		for ( j=1; j<monkey; j++ ) 		{ 			temp = GetLastNum( monkey, temp );  			if ( temp < 0 ) break; 		}  		if ( temp > 0 ) return temp * monkey + 1;   	} }  //获取上个猴子的桃数，如果不满足条件那返回-1 //m猴子数，n当前这个猴子拿到的桃数 int GetLastNum( int m, int n ) { 	int total; 	 	total = m * n + 1; 	 	if (total % (m - 1) != 0) return -1;  	return total / (m - 1); }   请教楼上，猴子每次分分到的桃子数，为啥那样计算？？？我没想明白……[/quote] 假设有m只猴子，当前猴子分到的桃子数是n, 1 那当前猴子没拿前总数就是m*n+1 2 在1的基础上我们得出 上个猴子拿的数量是 (m*n+1) / (m-1) 3 根据1，2点我们只要保证   (m*n+1) / (m-1) 结果是个整数就OK了。 4 因为至少所以n我认为从1开始。

引用 6 楼 u014444402 的回复:抛砖引玉，出个暴力算法。  #include <stdio.h>  int GetPeachNum( int monkey ); int GetLastNum( int m, int n ); int main() { 	int i; 	for ( i=3; i<=9; i++ ) 	{ 		printf( "%d ", GetPeachNum(i) ); 	}  	printf( "\r\n" ); 	getchar(); 	return 0; }  int GetPeachNum( int monkey ) { 	int i, j; 	int temp;  	for ( i=1;; i++ )//这里可以设置超时，以防找不到死循环 	{ 		temp = i; 		for ( j=1; j<monkey; j++ ) 		{ 			temp = GetLastNum( monkey, temp );  			if ( temp < 0 ) break; 		}  		if ( temp > 0 ) return temp * monkey + 1;   	} }  //获取上个猴子的桃数，如果不满足条件那返回-1 //m猴子数，n当前这个猴子拿到的桃数 int GetLastNum( int m, int n ) { 	int total; 	 	total = m * n + 1; 	 	if (total % (m - 1) != 0) return -1;  	return total / (m - 1); }   请教楼上，猴子每次分分到的桃子数，为啥那样计算？？？我没想明白……

引用 3 楼 均陵鼠侠的回复:朕能解这道题，但你要保证把100分全给朕。 皇上，你得先解题，再要分。

可以用递归实现你要说的函数功能

朕能解这道题，但你要保证把100分全给朕。


Question: 急急急！！

这次用真身。  引用 4 楼 adusuccessfully 的回复:[quote=引用 3 楼 walkiz 的回复:] 什么小号？  [quote=引用 2 楼 adusuccessfully 的回复:] [quote=引用 1 楼 walkiz 的回复:]  #include <ctype.h> #include <stdio.h>  void fliter(const char* src, char* dst) {     char* p = (char*)src;     char* q = dst;      while(*p){         if(isalpha(*p)){             *q++ = *p;         }         p++;     }     *q = '\0'; }  int main(int argc, char* argv[]) {     char src[51];     char dst[51];      for(;;){         scanf("%s", src);         fliter(src, dst);         printf("%s\n", dst);     }      return 0; }  楼上的大牛用的是个小号吧 [/quote][/quote]  有个“图灵狗”的账号跟你的头像是一样的……[/quote]

引用 3 楼 walkiz 的回复:什么小号？  [quote=引用 2 楼 adusuccessfully 的回复:] [quote=引用 1 楼 walkiz 的回复:]  #include <ctype.h> #include <stdio.h>  void fliter(const char* src, char* dst) {     char* p = (char*)src;     char* q = dst;      while(*p){         if(isalpha(*p)){             *q++ = *p;         }         p++;     }     *q = '\0'; }  int main(int argc, char* argv[]) {     char src[51];     char dst[51];      for(;;){         scanf("%s", src);         fliter(src, dst);         printf("%s\n", dst);     }      return 0; }  楼上的大牛用的是个小号吧 [/quote][/quote]  有个“图灵狗”的账号跟你的头像是一样的……

什么小号？  引用 2 楼 adusuccessfully 的回复:[quote=引用 1 楼 walkiz 的回复:]  #include <ctype.h> #include <stdio.h>  void fliter(const char* src, char* dst) {     char* p = (char*)src;     char* q = dst;      while(*p){         if(isalpha(*p)){             *q++ = *p;         }         p++;     }     *q = '\0'; }  int main(int argc, char* argv[]) {     char src[51];     char dst[51];      for(;;){         scanf("%s", src);         fliter(src, dst);         printf("%s\n", dst);     }      return 0; }  楼上的大牛用的是个小号吧 [/quote]

引用 1 楼 walkiz 的回复: #include <ctype.h> #include <stdio.h>  void fliter(const char* src, char* dst) {     char* p = (char*)src;     char* q = dst;      while(*p){         if(isalpha(*p)){             *q++ = *p;         }         p++;     }     *q = '\0'; }  int main(int argc, char* argv[]) {     char src[51];     char dst[51];      for(;;){         scanf("%s", src);         fliter(src, dst);         printf("%s\n", dst);     }      return 0; }  楼上的大牛用的是个小号吧


Question: C语言用三级指针接受二级指针问题

引用 1 楼 ant2012 的回复:这个是符号优先级的问题 []的优先级比*高，所以*p[i]，实际上是先p[i]，再* 这样p[1]已经越界了  解决办法：将*p[i]全部改成 (*p)[i]  如果换成这二种，就可以避免这个问题 非常感谢，实现了。


Question: 学习中遇到一道题

#include<stdio.h> #include<string.h> int main() {     int c;     while((c=getchar())!='\n') 		if(isalpha(c)) 			putchar(c);     putchar('\n');     return 0; }

输入：dssd212 输出：dssd1 没有完全去掉啊

对于1sec的限制，用最笨的方法就行了。  /* 字符串过滤 描述: 输入一个字符串，对字符串中非字母类型的字符(字母类型例如a、B、C等，非字母类型例如#、&、1等),  全部移除掉。输入的字符串中最少包含一个字母类型的字符。字符长度不超过50. 运行时间限制:	1 Sec */ #include<stdio.h> #include<string.h> #define MAXLEN 51 char buf[MAXLEN]; int i, L; int main(void) { 	scanf("%51s", buf); 	L = strlen(buf); 	for (i = 0; i < L; i++) 	{ 		if (!((buf[i] >= 'A' && buf[i] <= 'Z') || (buf[i] >= 'a' && buf[i] <= 'z')))//非字母类型 		{ 			memmove(buf + i, buf + i + 1, L - i + 1); 			L = strlen(buf); 		} 	} 	printf("%s\n", buf); 	return 0; } //abc1def2ghi3 //abcdefghi

引用 5 楼 u010284226 的回复: #include <stdio.h> #include <time.h> int main(void){ 	char str[51]; 	int i=0,j=0; 	printf("输入字符：\n"); 	gets(str); 	while((str[i]=str[j++])!='\0'){ 		if((str[i]>='a' && str[i] <='z')|| (str[i]>='A' && str[i]<='Z')){ 			i++; 		} 	} 	printf("%s",str); 	return 0; }   使用i,j同时指向字符串，j负责不断符读取字符，i保存字符， 是个好方法！

可以参考这个帖子中牛人的回复：http://bbs.csdn.net/topics/391828543  #include <ctype.h> #include <stdio.h>   void fliter(const char* src, char* dst) {     char* p = (char*)src;     char* q = dst;       while(*p){         if(isalpha(*p)){             *q++ = *p;         }         p++;     }     *q = '\0'; }   int main(int argc, char* argv[]) {     char src[51];     char dst[51];       for(;;){         scanf("%s", src);         fliter(src, dst);         printf("%s\n", dst);     }       return 0; }

引用 2 楼 wwwssshhh2014 的回复:输入：dssd212 输出：dssd1 没有完全去掉啊 有bug，多添一行 改为  if (!((buf[i] >= 'A' && buf[i] <= 'Z') || (buf[i] >= 'a' && buf[i] <= 'z')))//非字母类型 { 	memmove(buf + i, buf + i + 1, L - i + 1); 	i--;   //添一行 	L = strlen(buf); }


Question: 没见过的错误，请帮忙解决，谢谢！

引用 1 楼 adlay 的回复:menu 里面的 return 0 改成 return; input 函数放到 menu 函数的前面去 解决了，谢谢


Question: 请问要把168.7转换为168.0要怎么做？C语言。

x = (float)(int)x


Question: 初学C语言基础

基础至关重要，建议从《C Prime Plus》学起。

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

我推荐这本书 [C语言程序设计_现代方法(第2版)].（美）King


Question: 简单C语言问题，子函数到另一个子函数？

{         if (key == 6)             return;         if (key == 1 || key == 2 || key == 3 || key == 4 || key == 5)             break;         else             printf("输入错误，请重新输入!\n");     }     switch (key)     {         case 1:input(stu);          /*case 2:show(stu,num);         case 3:sort(); break;         case 4:change(); break;         case 5:del(); break;*/     } 变成了 {         if (key == 6)             return 0;         if (key == 1 || key == 2 || key == 3 || key == 4 || key == 5)         {             switch (key)             {                 case 1:input(stu);                 /*case 2:show(stu,num);                 case 3:sort(); break;                 case 4:change(); break;                 case 5:del(); break;*/             }         }         else             printf("输入错误，请重新输入!\n");     } 仔细看一下。。。

本来就进不到menu，程序在信息录入之后会return，就代表程序结束了

引用 1 楼 Destiny0321 的回复:#define  _CRT_SECURE_NO_WARNINGS #include <stdio.h> #include <windows.h>  typedef struct {     char name[10];     int id;     int eng;     int math;     int chi;     int sum; }Stu;  void menu()//主菜单 {     int key = 0;     printf("\t\t\t\t学生成绩管理系统\n");     printf("\t\t\t\t**1.录入信息**\n");     printf("\t\t\t\t**2.显示信息**\n");     printf("\t\t\t\t**3.成绩排序**\n");     printf("\t\t\t\t**4.成绩修改**\n");     printf("\t\t\t\t**5.成绩删除**\n");     printf("\t\t\t\t**6.退出**\n"); } void input(Stu stu[])//录入信息 {     int num,i;     printf("请输入学生人数:");     scanf("%d", &num);     for (i = 0; i < num; i++)     {         getchar();         printf("请输入姓名:");         gets(stu[i].name);         printf("请输入学号:");         scanf("%d", &stu[i].id);         printf("英语成绩:");         scanf("%d", &stu[i].eng);         printf("数学成绩:");         scanf("%d", &stu[i].math);         printf("语文成绩:");         scanf("%d", &stu[i].chi);         stu[i].sum = stu[i].eng + stu[i].math + stu[i].chi;     }     printf("\n录入成功！\n");     system("cls");     menu(); }  int main(void) {     Stu stu[50];     int key,num = 0;     menu();     printf("\t\t\t\t请选择:");     while (scanf("%d", &key))     {         if (key == 6)             return 0;         if (key == 1 || key == 2 || key == 3 || key == 4 || key == 5) 		{             switch (key) 			{ 				case 1:input(stu); 				/*case 2:show(stu,num); 				case 3:sort(); break; 				case 4:change(); break; 				case 5:del(); break;*/ 			} 		}         else             printf("输入错误，请重新输入!\n");     }     return 0; } 这个没变化啊


Question: C语言，请问为什么扩展分配内存后，再释放指针程序就无法退出了？

引用 7 楼 u014626834 的回复:可是我输入了11个数据，还是正常显示了呢？ 1）C内存分配策略，是分配足够的内存，而不是恰到好处的内存。 2）内存越界的结果，可能是破坏为管理内存，而设定的数据结构，未必一定会抛出异常。 3）编译期间，和程序运行期间不报错，不代表程序没有错误。

其实电脑开机后物理内存的每个字节都是可读写的，从来不会因为所谓的new、delete或malloc、free而被创建、销毁。区别仅在于操作系统内存管理模块在你读写时是否能发现并是否采取相应动作而已。操作系统管理内存的粒度不是字节而是页，一页通常为4KB。  崩溃的时候在弹出的对话框按相应按钮进入调试，按Alt+7键查看Call Stack即“调用堆栈”里面从上到下列出的对应从里层到外层的函数调用历史。双击某一行可将光标定位到此次调用的源代码或汇编指令处，看不懂时双击下一行，直到能看懂为止。

内存访问越界的后果是行为未定义的，程序可能产生这种异常，也可能产生那种异常，也可能没有异常

可是我输入了11个数据，还是正常显示了呢？

realloc 的参数不是增加多少内存，而是增加到多少 你永远只分配 10 个 int，当数据超过 10 个就出现内存访问越界了

请帮我看看，谢谢！

#include <stdio.h> #include <malloc.h>  int main(void) { 	int *p = (int*)calloc(10, sizeof(int)); 	if (!p) 	{ 		printf("内存分配错误!\n"); 		return 0; 	}  	int *ptemp = { NULL };  	int i = 0; 	int j = 0;  	printf("请输入:\n");  	for (i = 0;;) 	{ 		scanf_s("%d", (p + i)); 		getchar();  		++j;  		if (i % 9 == 0) 		{ 			ptemp = (int*)realloc(p, 10 * sizeof(int)); 			if (!ptemp) 			{ 				printf("上限内存分配错误!\n"); 				free(p); 				p = NULL; 				return 0; 			} 			p = ptemp; 		}  		if (*(p + i) == 9999) 		{ 			break; 		}  		++i;  	}  	printf("\n\n下面进行输出:\n\n");  	for (i = 0; i < j; ++i) 	{ 		printf("%d ", *(p + i));  	}  	free(p); 	p = NULL;  	return 0; }

说明内存分配和指针应用上出问题了。

show me the code

因为程序中有 BUG


Question: 新人菜鸟用VS2015做C语言出现问题，求各位大神解答！！！1

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

引用 3 楼 user-2的回复:fp是空指针么, fopen你不检查返回值么 明白了些，感谢大神的解答！！

fp是空指针么, fopen你不检查返回值么

引用 1 楼 user-2 的回复:lz没用过断言么, 断言失败, 空指针截断, 点击重试，再点击中断，顺着调用栈找空指针   以前一直用VC++6.0的，这个真的不知道。。。 提示好像是这个出了问题，但是我还是不知道怎么改。。		n = fread(txl, sizeof(tongxunlu), 200, fp);


Question: 程序在linux环境中会出错，在win7下正常

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

引用 5 楼 fly_dragon_fly 的回复:[quote=引用 4 楼 ly0303521 的回复:] [quote=引用 2 楼 fly_dragon_fly 的回复:] 这是判断[i,j]之间是否回文, 但有 temp += 2; p ++;  用递归吧, 回文天生就是为递归准备的 我将之前的程序改成用递归的方法，还是会出现这样的问题，测试用的字符串：abbacabbaab[/quote]  while (*p == *q)  /* ==> 换成 */ for (p=&str[i];*p == *q;) [/quote] 这样该，不行吧

引用 4 楼 ly0303521 的回复:[quote=引用 2 楼 fly_dragon_fly 的回复:] 这是判断[i,j]之间是否回文, 但有 temp += 2; p ++;  用递归吧, 回文天生就是为递归准备的 我将之前的程序改成用递归的方法，还是会出现这样的问题，测试用的字符串：abbacabbaab[/quote] 这样改，不行吧

引用 4 楼 ly0303521 的回复:[quote=引用 2 楼 fly_dragon_fly 的回复:] 这是判断[i,j]之间是否回文, 但有 temp += 2; p ++;  用递归吧, 回文天生就是为递归准备的 我将之前的程序改成用递归的方法，还是会出现这样的问题，测试用的字符串：abbacabbaab[/quote]  while (*p == *q)  /* ==> 换成 */ for (p=&str[i];*p == *q;)

引用 2 楼 fly_dragon_fly 的回复:这是判断[i,j]之间是否回文, 但有 temp += 2; p ++;  用递归吧, 回文天生就是为递归准备的 我将之前的程序改成用递归的方法，还是会出现这样的问题，测试用的字符串：abbacabbaab

引用 1 楼 user-3 的回复:你确定在win7下正常    for (j = len_str -1; j >= i; j--) { ------》这个每次循环，指针p要重新赋值的 不然就是从上次错误的地方开始比较 我使用的测试例子：abbacabbaab 。在WIN7 32位 VC ，显示长度为9，是正确的，在linux下就不对


Question: 关于枚举类型的应用

#include <stdio.h>  typedef enum {     MON,     TUE,     WED,     THU,     FRI,     SAT,     SUN, }week_t;  static const char* names[] = {     "MON",     "TUE",     "WED",     "THU",     "FRI",     "SAT",     "SUN", };  int main(int argc, char* argv[]) {     week_t week;      printf("Please input a day number: ");     scanf("%d", (int*)&week);     printf("The day is %s\n", names[week % 7]);      return 0; }

#include <stdio.h>    //定义一个枚举类型  enum Weekday{MON,TUE,THU,FRI,SAT,SUN}Weekday;  int main(int argc, char* argv[]) {	 	enum Weekday week; 	printf("输入数字：\n"); 	scanf("\n%d",&week); 	while(week>7){ 		printf("输入不正确：\n"); 		scanf("\n%d",&week); 	} 	switch(week){ 		case 0:printf("MON");break; 		case 1:printf("TUE");break; 		case 2:printf("WED");break; 		case 3:printf("THU");break; 		case 4:printf("FRI");break; 		case 5:printf("SAT");break; 		case 6:printf("SUN");break; 	}     return 0; }

#include<iostream.h> int main() { 	enum Week{MON, TUE, WED, THU, FRI, SAT, SUN}; 	int day; 	cout<<"请输入一个0-6的整数："; 	cin>>day; 	switch((Week)day) 	{ 	case 0: cout<<"MON"<<endl;	break; 	case 1: cout<<"TUE"<<endl;	break; 	case 2: cout<<"WED"<<endl;  break; 	case 3: cout<<"THU"<<endl;	break; 	case 4: cout<<"FRI"<<endl;	break; 	case 5: cout<<"SAT"<<endl;	break; 	case 6: cout<<"SUN"<<endl;	break; 	default: 		cout<<"输入有误！"<<endl; 	 	} 	return 0; 	 }    这样对吗

开学了, 教得挺快的, 都教到枚举了?


Question: 如何真正解决VS c++6.0在win7(32位）中流畅运行

有免安装版的，不过只能打开工作空间，不能新建别的东西，要不直接崩溃

不要光盘版的，下载VC6 sp6的。

FileTool.exe 替换打开和添加到项目中 Visual C++ 的新功能 http://support.microsoft.com/kb/241396/zh-cn  "我就要走在老路上，我就要回到老地方。"

真正解决问题的办法是换XP或 win98

引用 3 楼 relaxisland 的回复:计算机等级考试还用vs6.0？ 这不知道 不都是TC么?啥时候改的VC6啊

加个内存条，装个虚拟机。

安装虚拟机，在xp中使用vc6.0是比较可行的方法

如果只是为了计算机等级考试而用VC6.0的话，还是装虚拟机，装XP，在虚拟机中使用VC6.0吧

引用 10 楼 u010165006 的回复:不要光盘版的，下载VC6 sp6的。  VC6有个地方很讨厌，比如：  for(int i=0;...) 	for(int j=0;...) 。。。  for(int i=0;...) 	for(int j=0;...) 。。。 编译会出错。

会用后续版本的vs，也是一样的。

计算机等级考试还用vs6.0？ 这不知道


Question: VS C++调试的时候不会出现哪里错误

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

好好贴代码：  #include<stdio.h> int main() { 	int a = 1, b = 2; 	for(; a < 8; a++) 	{ 		b+=a;  		a+=2; 	} 	printf("a=%d,b=%d\n", a, b); 	return 0; } //a=10,b=14

全部都是全角字符，能够编译通过才怪了。

代码全 是全角字符


Question: C语言：int a2[10]="123"; 这种定义是非法的吗？为什么？

类型不一致

数组的初始化列表是 ｛｝; 串的字面值，只能初始化  字符指针和字符数组  如果用它初始化整型数据，你认为哪种好啊  int  a[20] ="abcdefgh" 初始化为 ｛'abcd','efgh','ijkl',0｝;还是 ｛'a’，‘b’，‘c，’‘d','e’，‘f’’，g‘，‘h'｝

int a1[10]={'1','2','3'};   //为什么这样定义可以----->这样是给int类型的数组的每个成员赋字符'1','2','3'； int a2[10]="123";           //为什么这样定义就不行了？----->这句表示把字符串"123" 的地址赋给int指针地址a2，                                           //指针要区分类型，所以不可以这样赋值； char d[10]={1,2,3};     //为什么这样可以？----->这句是给字符串数组每个成员赋整数值1,2,3；

char a1[10] = "123";                    // 初始化字符串为 "123" char a2[10] = { "123" };                // 初始化字符串为 "123" char a3[10] = { 1, 2, 3, 0 }; char a4[10] = { '1', '2', '3', '\0' };  // 初始化字符串为 "123"  int b1[10] = { 1, 2, 3, 0 }; int b2[10] = { '1', '2', '3', '\0' };

引用 楼主 weishen2011 的回复:#include <stdio.h> #include <stdlib.h>  int main() {     int b='A';     char c=65;     printf("%d %c %d %c\n",b,b+48,c,c);          //以上条语句，说明char变量和int是可以通用的      int a1[10]={'1','2','3'};   //为什么这样定义可以     printf("%d %d %d\n",a1[0],a1[1],a1[2]);     int a2[10]="123";           //为什么这样定义就不行了？  char d[10]={1,2,3};     //为什么这样可以？     printf("%c %c %c\n",d[0],d[1],d[2]);      return 0; }  我们知道，C语言中，char变量和int变量是通用的 单个字符和单个整数怎么定义都行，这个应该是没问题的 那么问题来了： 对于字符串（数组）和整型数组：     int a1[10]={'1','2','3'};   //为什么这样定义可以     int a2[10]="123";           //为什么这样定义就不行了？     char d[10]={1,2,3};     //为什么这样可以？ 能一一解释一下吗？亿分感谢！！ int a2[10]="123";           //为什么这样定义就不行了？  报错是：array of inappropriate type initialized from string constant 大意是：初始化时给字符串常量定义数组类型不恰当 貌似这里只能用char去修饰…… 不知道怎么解释好？  语法中有一个特例 char a[10]="123"是可以的，这是将字符数组用字符串初始化，最后追加一个结束符，也就是初始化字符串的意思，但是这只是语法上的一个标准规定许可的特例，如果你不是字符数组当然不行(无法执行隐式转换)，但是，你可以加上大括号变成 int a[10]={'1','2','3'}

看语法    An array of character type may be initialized by a character string literal, optionally enclosed in braces.  Successive characters of the character string literal (including the terminating null character if there is room or if the array is of unknown size) initialize the members of the array.  3.5.7 Initialization  Syntax            initializer:                   assignment-expression                   {  initializer-list }                    {  initializer-list , }            initializer-list:                   initializer                   initializer-list ,  initializer

变量类型都不一样，当然会报错了

引用 6 楼 weishen2011 的回复:[quote=引用 5 楼 q3733353520 的回复:] [quote=引用 3 楼 weishen2011 的回复:] [quote=引用 2 楼 q3733353520 的回复:]  char a[10] = {"123"};//这样是可以的，数组在定义的时候初始化可能要括起来，我猜测 //数据类型之间是可以强制转化的   没有啊，char 定义字符数组的时候可以需要花括号的 现在就是为啥int a[100]="123这种定义，为什么不行 没有一个太好的解释[/quote] 其实你那些编译得过的说明是可以隐式转化的，而 int a[100]="123";是因为这个表达式的赋值对象其实是数组a的成员(如a[0],a[1])而"123"它其实是表示"123"的首地址，是个指针值，char *指针类型是不能够cast成int类型的 所以报错  cast from pointer to integer of different size [-Wpointer-to-int-cast]    [/quote] 没看懂你说的意思…… 怎么变成char指针了[/quote]  "123"这个表达式的值就是个char类型的指针

问题1： int a1[10]={'1','2','3'};   //为什么这样定义可以    问题2：  int a2[10]="123";           //为什么这样定义就不行了？    问题3：  char d[10]={1,2,3};     //为什么这样可以？  C语言中，char变量和int变量是通用的,即ASCII编码与十进制之间的转换。问题3和问题1应该原理相似。 问题1: 等价于 int ch1='1',ch2='2',ch3='3';即原数组各个元素赋值。  问题2: 数组的首地址指向字符串常量"123" 。

int arr[10] = "123"; //"123" 是字符串啊！ int arr[10] = {'1', '2', '3'}; //相当于 int arr[10] = {49, 50, 51} ; 因为char 和 int 可以转换

array of inappropriate type initialized from string constant 的意思就是 不恰当类型的数组从字符串常量初始化   int a[10]="123"; “123”赋给a[10]的是地址，

引用 1 楼 FXM720505 的回复:数组定义  赋值时需要用大括号包起来 字符数组可以不要花括号的

引用 2 楼 q3733353520 的回复: char a[10] = {"123"};//这样是可以的，数组在定义的时候初始化可能要括起来，我猜测 //数据类型之间是可以强制转化的   没有啊，char 定义字符数组的时候可以需要花括号的 现在就是为啥int a[100]="123这种定义，为什么不行 没有一个太好的解释

数组定义  赋值时需要用大括号包起来

1. 自动类型转换 char -> int 2. 指针是带类型的

引用 5 楼 q3733353520 的回复:[quote=引用 3 楼 weishen2011 的回复:] [quote=引用 2 楼 q3733353520 的回复:]  char a[10] = {"123"};//这样是可以的，数组在定义的时候初始化可能要括起来，我猜测 //数据类型之间是可以强制转化的   没有啊，char 定义字符数组的时候可以需要花括号的 现在就是为啥int a[100]="123这种定义，为什么不行 没有一个太好的解释[/quote] 其实你那些编译得过的说明是可以隐式转化的，而 int a[100]="123";是因为这个表达式的赋值对象其实是数组a的成员(如a[0],a[1])而"123"它其实是表示"123"的首地址，是个指针值，char *指针类型是不能够cast成int类型的 所以报错  cast from pointer to integer of different size [-Wpointer-to-int-cast]    [/quote] 没看懂你说的意思…… 怎么变成char指针了

引用 3 楼 weishen2011 的回复:[quote=引用 2 楼 q3733353520 的回复:]  char a[10] = {"123"};//这样是可以的，数组在定义的时候初始化可能要括起来，我猜测 //数据类型之间是可以强制转化的   没有啊，char 定义字符数组的时候可以需要花括号的 现在就是为啥int a[100]="123这种定义，为什么不行 没有一个太好的解释[/quote] 其实你那些编译得过的说明是可以隐式转化的，而 int a[100]="123";是因为这个表达式的赋值对象其实是数组a的成员(如a[0],a[1])而"123"它其实是表示"123"的首地址，是个指针值，char *指针类型是不能够cast成int类型的 所以报错  cast from pointer to integer of different size [-Wpointer-to-int-cast]


Question: C语言，关于printf()输出字符串（数组）出现乱码的解释，求给个比较专业、略微详细的解释？

其实电脑开机后物理内存的每个字节都是可读写的，从来不会因为所谓的new、delete或malloc、free而被创建、销毁。区别仅在于操作系统内存管理模块在你读写时是否能发现并是否采取相应动作而已。操作系统管理内存的粒度不是字节而是页，一页通常为4KB。

引用 4 楼 weishen2011 的回复:[quote=引用 2 楼 q3733353520 的回复:] 方式一：在数组str[7]后的内存区域中也是有值的，虽然你没有赋值，那些你打印的乱码就是那些区域里的值，直到遇到'\0' 方式二：同方式一 方式三; 也一样 也就是说跟定义时分配的空间大小毫无关系了？ 不管空间小于字符串长度，还是大于字符串长度，总之只要最后printf()和puts()没有获取到‘\0’ 这两个函数就会继续读取给定空间之外的变量，因为这个变量是随机的，不可预知的，所以很多时候就会是乱码？ 是这个意思么？[/quote] 是的

1. 都是一直往后遍历，直到遇到内存中第一个 0 为止，在之前输出的就都是乱码。 2. 和上面一样。

建议，下断点，查看内存

引用 2 楼 q3733353520 的回复:方式一：在数组str[7]后的内存区域中也是有值的，虽然你没有赋值，那些你打印的乱码就是那些区域里的值，直到遇到'\0' 方式二：同方式一 方式三; 也一样 也就是说跟定义时分配的空间大小毫无关系了？ 不管空间小于字符串长度，还是大于字符串长度，总之只要最后printf()和puts()没有获取到‘\0’ 这两个函数就会继续读取给定空间之外的变量，因为这个变量是随机的，不可预知的，所以很多时候就会是乱码？ 是这个意思么？

声明时初始化，输出时限定输出长度，可以有效的减少输出溢出问题。


Question: str1=""条件下strcmp(str1,str2)不会core,而int n=str(str1,str2)会core?

char *str1=NULL; 这样试下。

兄弟，你这代码真的会dump么？我跑了好几次都没复现bug啊

首先，很感谢各位的回复。 很想说下，这里只是讨论问题，不涉及水平问题。对于#4 很明显这是手误，是#include<string.h>，有必要刷帖吗。  再回复下其他回复问题的人，不要套理论回复别人的问题，你怎么知道别人就是小白呢。针对问题请给出针对性的回答，套话就别刷了吧。  程序中写成strcmp(str1,str2); 这种形式，程序压根就不会执行这一行代码，这才是问题的所在！

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

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

#incude<stdio.h> #incude<string.h>//incude是什么鬼

不同编译器对这个函数返回值不同，你可以看看strcmp这个函数的源码是什么，看看返回值是什么类型什么值，有可能bug就是这了

请大家帮助看下为什么init n=strcmp...为什么会产生coredump,多谢了。

从代码看来，没问题。


Question: 请教一个形参类型的warning

把uint8_t 改为char。

#include <stdio.h> typedef unsigned char   uint8_t;   uint8_t 和char 是不兼容的

uint8_t 一般来说就是unsigned char，与char自然是不兼容的, 需要    强制转换, 一般来说uint8_t*用来存储二进制数据, lz这里声明字符串为什么要用uint8_t

const char*与const unsigned char*不兼容的警告。不要用uint8_t，直接用char


Question: 一个课本上的题目请大家帮忙，谢谢

加  delete pN;

得在加一行：  void main() { 	int *pN = new int; 	cin >> *pN; 	int *arr = new int[*pN]; 	for (int i = 0; i < *pN; i++) 	{ 		arr[i] = i + 1; 	} 	for (i = 0; i < *pN; i++) 	{ 		cout << arr[i] << endl; 	} 	delete[] arr; 	delete pN; }

引用 1 楼 ant2012 的回复:void main() {     int *pN;     cin>> *pN;   //pN没有开辟空间，就对其赋值，很危险     int *arr = new int[*pN];     for(int i=0;i<*pN;i++)     {         arr[i] = i+1;     }     for(i=0;i<*pN;i++)     {         cout<<arr[i]<<endl;     }     delete arr;       //释放空间方式不对，这种方式只能释放一个元素 }  正确代码  void main() {     int *pN = new int;     cin>> *pN;     int *arr = new int[*pN];     for(int i=0;i<*pN;i++)     {         arr[i] = i+1;     }     for(i=0;i<*pN;i++)     {         cout<<arr[i]<<endl;     }     delete[] arr; }谢谢


Question: 求大神用C语言设计一个简单的计算器进行加减乘除，可带括号，不限定运算式的输入长度，多加些注释，简单就可以了

仅供参考：/*--------------------------------------- 函数型计算器(VC++6.0,Win32 Console)程序由 yu_hua 于2007-07-27设计完成 功能： 目前提供了10多个常用数学函数:     ⑴正弦sin     ⑵余弦cos     ⑶正切tan     ⑷开平方sqrt     ⑸反正弦arcsin     ⑹反余弦arccos     ⑺反正切arctan     ⑻常用对数lg     ⑼自然对数ln     ⑽ｅ指数exp     ⑾乘幂函数∧ 用法： 如果要求2的32次幂，可以打入2^32<回车> 如果要求30度角的正切可键入tan(Pi/6)<回车> 注意不能打入：tan(30)<Enter> 如果要求1.23弧度的正弦，有几种方法都有效： sin(1.23)<Enter> sin 1.23 <Enter> sin1.23  <Enter> 如果验证正余弦的平方和公式,可打入sin(1.23)^2+cos(1.23)^2 <Enter>或sin1.23^2+cos1.23^2 <Enter> 此外两函数表达式连在一起,自动理解为相乘如：sin1.23cos0.77+cos1.23sin0.77就等价于sin(1.23)*cos(0.77)+cos(1.23)*sin(0.77) 当然你还可以依据三角变换，再用sin(1.23+0.77)也即sin2验证一下。 本计算器充分考虑了运算符的优先级因此诸如：2+3*4^2 实际上相当于：2+(3*(4*4)) 另外函数名前面如果是数字,那么自动认为二者相乘. 同理，如果某数的右侧是左括号，则自动认为该数与括弧项之间隐含一乘号。 如：3sin1.2^2+5cos2.1^2 相当于3*sin2(1.2)+5*cos2(2.1) 又如：4(3-2(sqrt5-1)+ln2)+lg5 相当于4*(3-2*(√5 -1)+loge(2))+log10(5) 此外，本计算器提供了圆周率 Pi键入字母时不区分大小写,以方便使用。 ----------------------------------------*/ #include <iostream> #include <iomanip> #include <cstdlib> #include <cstring> #include <cctype> #include <cmath> #include <stdio.h> #include <string.h> #include <windows.h> using namespace std; const char Tab=0x9; const int  DIGIT=1; const int MAXLEN=16384; char s[MAXLEN],*endss; int pcs=15; double fun(double x,char op[],int *iop) {     while (op[*iop-1]<32) //本行使得函数嵌套调用时不必加括号,如 arc sin(sin(1.234)) 只需键入arc sin sin 1.234<Enter>         switch (op[*iop-1]) {         case  7: x=sin(x);  (*iop)--;break;         case  8: x=cos(x);  (*iop)--;break;         case  9: x=tan(x);  (*iop)--;break;         case 10: x=sqrt(x); (*iop)--;break;         case 11: x=asin(x); (*iop)--;break;         case 12: x=acos(x); (*iop)--;break;         case 13: x=atan(x); (*iop)--;break;         case 14: x=log10(x);(*iop)--;break;         case 15: x=log(x);  (*iop)--;break;         case 16: x=exp(x);  (*iop)--;break;         }     return x; } double calc(char *expr,char **addr) {     static int deep; //递归深度     static char *fname[]={ "sin","cos","tan","sqrt","arcsin","arccos","arctan","lg","ln","exp",NULL};     double ST[10]={0.0}; //数字栈     char op[10]={'+'}; //运算符栈     char c,*rexp,*pp,*pf;     int ist=1,iop=1,last,i;      if (!deep) {         pp=pf=expr;         do {             c = *pp++;             if (c!=' '&& c!=Tab)                 *pf++ = c;         } while (c!='\0');     }     pp=expr;     if ((c=*pp)=='-'||c=='+') {         op[0] = c;         pp++;     }     last = !DIGIT;     while ((c=*pp)!='\0') {         if (c=='(') {//左圆括弧             deep++;             ST[ist++]=calc(++pp,addr);             deep--;             ST[ist-1]=fun(ST[ist-1],op,&iop);             pp = *addr;             last = DIGIT;             if (*pp == '('||isalpha(*pp) && strnicmp(pp,"Pi",2)) {//目的是：当右圆括弧的右恻为左圆括弧或函数名字时，默认其为乘法                 op[iop++]='*';                 last = !DIGIT;                 c = op[--iop];                 goto operate ;             }         }         else if (c==')') {//右圆括弧             pp++;             break;         } else if (isalpha(c)) {             if (!strnicmp(pp,"Pi",2)) {                 if (last==DIGIT) {                     cout<< "π左侧遇）" <<endl;exit(1);                 }                 ST[ist++]=3.14159265358979323846264338328;                 ST[ist-1]=fun(ST[ist-1],op,&iop);                 pp += 2;                 last = DIGIT;                 if (!strnicmp(pp,"Pi",2)) {                     cout<< "两个π相连" <<endl;exit(2);                 }                 if (*pp=='(') {                     cout<< "π右侧遇（" <<endl;exit(3);                 }             } else {                 for (i=0; (pf=fname[i])!=NULL; i++)                     if (!strnicmp(pp,pf,strlen(pf))) break;                 if (pf!=NULL) {                     op[iop++] = 07+i;                     pp += strlen(pf);                 } else {                     cout<< "陌生函数名" <<endl;exit(4);                 }             }         } else if (c=='+'||c=='-'||c=='*'||c=='/'||c=='%'||c=='^') {             char cc;             if (last != DIGIT) {                 cout<< "运算符粘连" <<endl;exit(5);             }             pp++;             if (c=='+'||c=='-') {                 do {                     cc = op[--iop];                     --ist;                     switch (cc) {                     case '+':  ST[ist-1] += ST[ist];break;                     case '-':  ST[ist-1] -= ST[ist];break;                     case '*':  ST[ist-1] *= ST[ist];break;                     case '/':  ST[ist-1] /= ST[ist];break;                     case '%':  ST[ist-1] = fmod(ST[ist-1],ST[ist]);break;                     case '^':  ST[ist-1] = pow(ST[ist-1],ST[ist]);break;                     }                 } while (iop);                 op[iop++] = c;             } else if (c=='*'||c=='/'||c=='%') { operate:        cc = op[iop-1];                 if (cc=='+'||cc=='-') {                     op[iop++] = c;                 } else {                     --ist;                     op[iop-1] = c;                     switch (cc) {                     case '*':  ST[ist-1] *= ST[ist];break;                     case '/':  ST[ist-1] /= ST[ist];break;                     case '%':  ST[ist-1] = fmod(ST[ist-1],ST[ist]);break;                     case '^':  ST[ist-1] = pow(ST[ist-1],ST[ist]);break;                     }                 }             } else {                 cc = op[iop-1];                 if (cc=='^') {                     cout<< "乘幂符连用" <<endl;exit(6);                 }                 op[iop++] = c;             }             last = !DIGIT;         } else {             if (last == DIGIT) {                 cout<< "两数字粘连" <<endl;exit(7);             }             ST[ist++]=strtod(pp,&rexp);             ST[ist-1]=fun(ST[ist-1],op,&iop);             if (pp == rexp) {                 cout<< "非法字符" <<endl;exit(8);             }             pp = rexp;             last = DIGIT;             if (*pp == '('||isalpha(*pp)) {                 op[iop++]='*';                 last = !DIGIT;                 c = op[--iop];                 goto operate ;             }         }     }     *addr=pp;     if (iop>=ist) {         cout<< "表达式有误" <<endl;exit(9);     }     while (iop) {         --ist;         switch (op[--iop]) {         case '+':  ST[ist-1] += ST[ist];break;         case '-':  ST[ist-1] -= ST[ist];break;         case '*':  ST[ist-1] *= ST[ist];break;         case '/':  ST[ist-1] /= ST[ist];break;         case '%':  ST[ist-1] = fmod(ST[ist-1],ST[ist]);break;         case '^':  ST[ist-1] = pow(ST[ist-1],ST[ist]);break;         }     }     return ST[0]; } int main(int argc,char **argv) {     int a;      if (argc<2) {         if (GetConsoleOutputCP()!=936) system("chcp 936>NUL");//中文代码页         cout << "计算函数表达式的值。"<<endl<<"支持(),+,-,*,/,%,^,Pi,sin,cos,tan,sqrt,arcsin,arccos,arctan,lg,ln,exp"<<endl;         while (1) {             cout << "请输入表达式：";             gets(s);             if (s[0]==0) break;//             cout << s <<"=";             cout << setprecision(15) << calc(s,&endss) << endl;         }     } else if (argc==2 && 0==strcmp(argv[1],"/?")) {         if (GetConsoleOutputCP()!=936) system("chcp 936>NUL");//中文代码页         cout << "计算由≥1个命令行参数给出的函数表达式的值。最后一个参数是.0～.15表示将计算结果保留小数0～15位"<<endl<<"支持(),+,-,*,/,%,^^,Pi,sin,cos,tan,sqrt,arcsin,arccos,arctan,lg,ln,exp"<<endl;     } else {         strncpy(s,argv[1],MAXLEN-1);s[MAXLEN-1]=0;         if (argc>2) {             for (a=2;a<argc-1;a++) strncat(s,argv[a],MAXLEN-1);//将空格间隔的各参数连接到s             if (1==sscanf(argv[a],".%d",&pcs) && 0<=pcs && pcs<=15) {//最后一个参数是.0～.15表示将计算结果保留小数0～15位                 printf("%.*lf\n",pcs,calc(s,&endss));             } else {                 strncat(s,argv[a],MAXLEN-1);                 printf("%.15lg\n",calc(s,&endss));             }         } else {             printf("%.15lg\n",calc(s,&endss));         }     }     return 0; }

具体要求呢？


Question: 文件加密的问题

你如何加密以及解密？


Question: c语言问题

参考C语言书上，代码如下：  #include "stdio.h" int hcf(int m,int n) { 	int t,r; 	if(n>m) 	{ 		t=m; 		m=n; 		n=t; 	} 	while((r=m%n)!=0) 	{ 		m=n; 		n=r; 	} 	return n; } int lcd(int m,int n,int h) { 	return m*n/h; } void main() { 	int m,n,h,l; 	printf("请输入m,n:\n"); 	scanf("%d,%d",&m,&n); 	h=hcf(m,n); 	l=lcd(m,n,h); 	printf("最大公约数是:%d\n最小公倍数是:%d\n",h,l); }

搜＂最大公约数＂代码

有谁能给个能用的算法吗？我对比看看错在哪

for (i = x; i < 1; i--) 改为： for (i = x; i > 1; i--)

况且你找最大公约数的方法，大概看了一下，问题挺多的，希望再认真斟酌

i你已经定义为整数，for循环那又给了i＜1的限制，i--肯定要出问题啊

粗略一看，for循环的条件是否有问题


Question: C语言函数作用域问题？

楼主说的是对着，自己也可以验证下：  #include <stdio.h> #include <iostream> using namespace std; void sum(int a, int b) { 	int i = 15; 	int j = 20; 	a = i; 	b = j; 	printf("%x\n",&a); 	printf("%x\n",&b); 	printf("\n*********************\n"); 	cout<<&a<<endl; 	cout<<&a<<endl;  	printf("sum函数的地址：%x\n",sum); 	cout<<sum<<endl; 	return; } int main(void) { 	int a = 5; 	int b = 10; 	printf("%x\n",&a); 	printf("%x\n",&b); 	printf("\n*********************\n"); 	cout<<&a<<endl; 	cout<<&b<<endl; 	sum(a, b); 	printf("\n*********************\n"); 	cout<<sum<<endl; 	return 0; }

单步跟踪加深理解函数调用栈的原理

你的理解是正确的。

第一，肯定不一样！函数中的变量作用域都只到函数结束，调用时开辟空间，调用完释放！还有你这个函数是没有意义的，采用值传递时，实参只是传递了一个副本给形参，对实参ab没有任何影响！！除非采用指针地址传值或者引用传值（c++）

主函数和sum函数中的变量a和变量b，他们的地址不一样 在函数定义的非静态变量是存在栈区的，函数结束这部分内存被free， 这些变量的作用域是在函数内


Question: C语言指针问题？

引用 5 楼 ruying1389279 的回复:[quote=引用 1 楼 q3733353520 的回复:]  int *q;//定义的时候没有初始化，指向的区域（指针本身的值）是未知的 i=5 *q= i//把5存储(赋值)到q指向的内存 printf("%d",*q);打印q指向的内存中存储的值  这样不是业指针吗？好奇的是编译器能通过编译。[/quote] 野指针是指，指针指向了不该指向的区域，当你定义这个指针值的时候，系统会给你分配一块内存来存储它，如果你不初始化，那么它的值就是系统分配给你时这块内存原本的值，它有可能是野指针，有可能不是

看来是这个IDE的问题

6 楼 是正确 的 我在 gcc 上也测试过

我在VS2010上试了下，楼主那样是不能运行的，指针q没有赋值，是个野指针…… 必须先赋地址值。  #include <stdio.h>  int main(void) { 	int *q; 	int i = 5; 	//*q = i; 	q = &i; 	printf("%d\n",*q); 	return 0; }

引用 1 楼 q3733353520 的回复: int *q;//定义的时候没有初始化，指向的区域（指针本身的值）是未知的 i=5 *q= i//把5存储(赋值)到q指向的内存 printf("%d",*q);打印q指向的内存中存储的值  这样不是业指针吗？好奇的是编译器能通过编译。

哈哈，有些事，做了不一定错，但总是这样做，一定会出错。

目测lz打开了优化, 编译器优化后就没问题了

为啥不可以运行？楼上正解


Question: 关于直接访问内存地址值

rw从给定的地址中读取内存的值，你用的winio库里的哪个函数啊

引用 11 楼 zhao4zhong1 的回复:https://www.baidu.com/s?wd=WinIO.sys%2064%E4%BD%8D&rsv_spt=1&issp=1&f=8&rsv_bp=1&rsv_idx=2&ie=utf-8&tn=baiduhome_pg&rsv_enter=0&rsv_t=1792P3lllds0nXKvBKyge625umfFkufwxZUgnvIfDofMukDFdTJBasHwLC0o5u0vklJp&oq=WinIO.sys%E6%9C%8964%E4%BD%8D%E7%89%88%E7%9A%84%E5%90%97%3F&rsv_pq=f0e5a027000054a2&rsv_sug3=4&inputT=23330&rsv_sug4=23330  PBYTE pbLinAddr; HANDLE PhysicalMemoryHandle; pbLinAddr = MapPhysToLin(0xA0000, 65536, &PhysicalMemoryHandle); 该函数将把物理地址范围为0xA0000 - 0xAFFFF的地址空间映射到与应用程序对应的线性地址空间。 返回值为一个与物理地址0xA0000相关的线性地址。如果出现错误，则返回值为NULL。 为什么上面列子MapPhysToLin第一个参数就报错了啊

感谢各位的回复，winio已经可以成功读取到物理地址的值了，稍后会更新上DEMO

什么系统, 做什么用的

你要读物理地址？

嵌入汇编代码是比较本质的方法吧。

引用 1 楼 zhao4zhong1 的回复:使用WinIO.sys？  谢谢赵老师提供的，我去看看文档先 ：）

使用WinIO.sys？

引用 7 楼 nice_fish 的回复:[quote=引用 5 楼 fly_dragon_fly 的回复:] 什么系统, 做什么用的  是这样的一个需求，比较预设的GPIO的值和实际值是否有出入  而GPIO的值是存在内存中的，所以需要从内存地址中读取相应的值出来然后做后续的比较[/quote]不太明白是什么地址, 那地址看起来是64位的, 如果是物理地址, 算起来有19G的,你内存有那么大吗

WinIo.h：#ifndef WINIO_H #define WINIO_H  #ifdef WINIO_DLL #define WINIO_API _declspec(dllexport) #else #define WINIO_API _declspec(dllimport) #endif  extern "C" {   WINIO_API bool _stdcall InitializeWinIo();   WINIO_API void _stdcall ShutdownWinIo();   WINIO_API PBYTE _stdcall MapPhysToLin(PBYTE pbPhysAddr, DWORD dwPhysSize, HANDLE *pPhysicalMemoryHandle);   WINIO_API bool _stdcall UnmapPhysicalMemory(HANDLE PhysicalMemoryHandle, PBYTE pbLinAddr);   WINIO_API bool _stdcall GetPhysLong(PBYTE pbPhysAddr, PDWORD pdwPhysVal);   WINIO_API bool _stdcall SetPhysLong(PBYTE pbPhysAddr, DWORD dwPhysVal);   WINIO_API bool _stdcall GetPortVal(WORD wPortAddr, PDWORD pdwPortVal, BYTE bSize);   WINIO_API bool _stdcall SetPortVal(WORD wPortAddr, DWORD dwPortVal, BYTE bSize);   WINIO_API bool _stdcall InstallWinIoDriver(PSTR pszWinIoDriverPath, bool IsDemandLoaded = false);   WINIO_API bool _stdcall RemoveWinIoDriver(); }  extern bool IsNT; extern HANDLE hDriver; extern bool IsWinIoInitialized;  bool _stdcall StartWinIoDriver(); bool _stdcall StopWinIoDriver();  #endif

引用 4 楼 adlay 的回复:你要读物理地址？   我用的软件是：RwPortableX64V1.6.7   这个当前显示应该就是物理内存的实际值吧？

引用 5 楼 fly_dragon_fly 的回复:什么系统, 做什么用的  是这样的一个需求，比较预设的GPIO的值和实际值是否有出入  而GPIO的值是存在内存中的，所以需要从内存地址中读取相应的值出来然后做后续的比较

c语言和汇编都可以解决


Question: Ｃ程序运行崩溃，面试题，求大神解释

char类型只能存储一个字符

使用了非法内存，你只有一个字符（1B）是申请的，可以合法使用，而后面你使用了多个空间，因此崩溃！

内存没有分配

只分配一个字节，空间不足，应该这样修改：  #include<stdio.h>  int main() {     char a[10];     char* str = (char*)a;      strcpy(str, "hello");     puts(str);      return 0; }

你的str指向了a，a只有一个字节，.....溢出了，可能出错也可能不出错，

程序 正常运行，就打印一个'\0'；

多看看基础知识

你只申请了一个字节，却想使用这一个字节的位置放5个字节，当然不可以

越界、越界、越界！

另外，这里的main函数也是被其它的函数调用的，至于是什么函数LZ就别管了，这个和操作系统相关。

这是一个典型的栈溢出问题。  C语言运行时内存分为2块，堆内存和栈内存。所有的函数在发生调用关系时，会自动在栈内存上进行展开，就是生成一些数据，我们称之为上下文，展开的地址顺序很奇怪，是由高址向低地址空间展开的。  运行时发生函数调用时，栈上会存放一些数据，这些数据分为2个部分。在这里，你可以认为函数调用就是一个超级版本的goto语句，它跳到被调用函数的首地址，等执行完了，再跳回来。  为了完成整个过程，编译器需要建立上下文，比如，传给被调用函数的参数，最重要的是，被调用函数执行完之后，它返回的地址。这些都是数据，存储在栈上。这是第一部分的数据。另一部分数据，则是被调用函数在执行过程中，自己生成的一些临时变量，比如LZ提供的代码中的变量： char a; char* str；  现在我们再看LZ提供的如下代码语句： strcpy(str,"hello");  显然，地址越界了，现在的a 的值应该是'h',然后呢，‘ello’这四个字节就把一些其它的内存覆盖了，最大的可能性就是覆盖了main函数的返回地址。现在，当程序返回后，发现所在的指令地址在一个莫名其妙的地方，如果你的运气不错，这个地方不是可执行区域，那么操作系统会为你捕获这个异常，引发一个访址异常，程序崩溃。如果你的运气比较糟糕，这仍然是一个可执行区域，那么，恭喜你，You have been hacked!

buffer overflow

溢出了，不出错才有鬼。


Question: 关于枚举成员赋值

Semantics     The identifiers in an enumerator list are declared as constants that have type int and may appear wherever such are permitted./52/ An enumerator with = defines its enumeration constant as the value of the constant expression.  If the first enumerator has no = , the value of its enumeration constant is 0.  Each subsequent enumerator with no = defines its enumeration constant as the value of the constant expression obtained by adding 1 to the value of the previous enumeration constant.  (A combination of both forms of enumerators may produce enumeration constants with values that duplicate other values in the same enumeration.) The enumerators of an enumeration are also known as its members.     Each enumerated type shall be compatible with an integer type; the choice of type is implementation-defined.

没有显式赋值的都是前面的加1，如果都没有赋值，从0开始。

默认后面的是按照第一个的值依次加1的

两种情况下输出结果都是一样的，a=0, b=1, 依次加一，因为如果不设定值，第一个枚举值默认为0。  #include <iostream>  using namespace std;  enum ff{     a = 0,     b,     c,     d,     e = 0x7FFFFFFF };   enum ff2{     a2,     b2,     c2,     d2,     e2 = 0x7FFFFFFF };   int main() {     ff t = a;     cout << t <<endl;     t = b;     cout << t <<endl;     t = c;     cout << t <<endl;       ff2 t2 = a2;     cout << t2 <<endl;     t2 = b2;     cout << t2 <<endl;     t2 = c2;     cout << t2 <<endl;      return 0; }

你得亲自试下……

未初始化的枚举值，顺次增加 1， 第一个枚举值，没有初始化的，初始化为 0 已经初始化的，以初始化为准 枚举值，是常量，不能赋值，只能初始化 枚举变量，才可以赋值

依次加1,第一个值默认是0,赋值了什么就变什么


回复赵4老师：         g_hLogHook调试确实是非法的指针，可是已经给g_hLogHook分配内存了。   HHOOK g_hLogHook = NULL;

请检查每个函数的返回值。

使用GlobalAlloc分配内存。并使用GlobalLock


Question: QT中结构体编译出错。。。

sizeof(struct tag_TrackInfoTRACKINFO)

直接sizeof(*this)


Question: C语言中关于结构体指针使用->调用成员编译器找不到结构体的情况

引用 2 楼 JiangWenjie2014 的回复:假设我有一个函数do_some_thing，需要一个参数，并且这个参数是一个结构体，例如struct SomeType，那么这个函数的声明就是void do_some_thing (struct SomeType t); 当编译器看到这个函数时，必须知道struct SomeType的定义是不是？要不然编译不通过，因为不知道这个参数占用多少内存，要不然函数调用的时候怎么把参数传进去？ 现在换种思路，把参数换成指针，就像这样void do_some_thing (struct SomeType *t);当编译器看到这个函数是，发现函数的参数是一个指针，现在编译器不需要知道struct SomeType的定义了，因为在确定的系统中，指针占用的字节数是确定的，32位系统下是4个字节，64位系统下是8个字节，至于指针的类型struct SomeType，编译器是可以忽略的，至少C是这样。  (*vm)-> 这种写法，显然*vm也是一个指针，vm是一个二级指针，因为只有指针才可以用->操作符。 感觉应该不是一个二级指针，因为那个文章中也说，如果改成c++文件，那么就是vm->这种写法，不过这个说法我也没验证，明天可以试试

取决于JavaVM的定义了 比如重载了operator-> 又比如typedef xxx* JavaVM


Question: 关于C语言读取Unicode文档的问题，求教

非常感谢，我也怀疑文件解析出错

可以1。读的时候忽略这几个字节。 2。下个可以以unicode保存且不带签名的编辑器（我知道用EmEditor可以）

因为windows中txt文件保存为unicode是带签名的，就是在文件开始有几个字节的字符作标记，你用一个二进制查看器看一下就知道了

附图


Question: 蓝桥杯试题求助（1）

引用 2 楼 zhao4zhong1 的回复:仅供参考：#include<stdio.h> #define N 1000    //要计算的N long s[N]={1,1},n=N,t=2,a=1,b=0; int main()//雨中飞燕之作 {     for(;a<=*s||(++t<=n?(b=0,a=1):0);(*s==a++&&b)?(*s)++:0)         s[a]=(b+=s[a]*t)%10000,b/=10000;     for(printf("%d",s[*s]);--*s>0;) printf("%04d",s[*s]);     return 0; } 表示好难懂。。。

高精度乘法运算，用字符数组模拟手工乘法就可以了，用到也就是高精度加法。高精度加法应该还是简单的吧


Question: 关于VS2015写C出现“无法查找或打开 PDB 文件”不断提示的问题

有时候就应该学会视而不见听而不闻，否则自寻烦恼

我的也是这样，不过可以运行一会儿，然后产生中断出错，已经加载了启用源服务器支持和Microsoft符号服务器，还是找不到，全盘搜了没有.pdb文件

楼主在return 0；前面加上system（“pause”）；

我ctrl+f5之后还有，嘛~无所谓了

在不需要调试系统符号的情况下，有没有pdb无所谓。

在return 0前加一行代码，system("pause"); 重新编译运行即可。

http://blog.csdn.net/zhao4zhong1/article/details/53078924 老司机找bug的十年心路历程

引用 15 楼 winc_best 的回复:的确啊我和你的情况一模一样 然后按了ctrl+f5 就行了 但是会多个 按任意键继续。。 但是按照我同学说的加个while（1）；就没有这个东西了 楼主知道为什么吗==   楼主是在哪里加个while（1），我也遇到了一样的问题

我也遇到了这种情况，按楼上的方法还是不能调试，楼主是怎样弄好的呢

忽略这些，通常对你没有影响

引用 11 楼 hydrogencyanide 的回复:这样试试吧，我是这样弄的 1.菜单栏的“调试”-》“选项”→“选项”菜单中的“调试”→“常规”→把“常规”中的“启用源服务器支持”和它的子项勾选； 2.“选项”菜单中的“调试”→“符号”→把“符号”中的“Microsoft符号服务器”勾选； 3.点击“选项”菜单中的“确定”。  我也是这个出错，我是在调用fseek函数是才发生这个错误的。vs提示是∵fseek.cpp第177行出错。用了您的方法还是不行。我用的vs 2015 社区版

已加载“C:\Windows\SysWOW64\ucrtbased.dll”。无法查找或打开 PDB 文件。 输出不了运行结果怎么办？

再补充一点：VS这样做，在多个项目（互有依赖）同时调试的时候，会比较方便。

1.在Windows中，哪怕你只是一个很小的程序，也会对很多的库有依赖，那些你没见过的DLL，就是程序运行时需要依赖的库；  2.Visual Studio在调试的时候，默认会加载你的程序及其依赖项的所有PDB文件，其结果通常是：你自己程序的PDB能找到，但其依赖项的PDB文件一般是找不到的（比如WINDOWS系统内核），于是你就看到了给出的这个提示；  3.如果VS没有说你自己程序的PDB没找到，那么一般情况下你不用理会那些信息。

找到那个文件，删了


Question: chart图标的缩放，怎么设置缩放最值

沉吧。。提错地方就不会有人会吗。。 自己来拣个分。。

还有一个问题 这个只是实验一下 把代码移植到另一个form的TabPage2里面，发现鼠标滚轮缩放不好用了。。。。 想知道为什么和怎么改 我在designer.cs里面加了 this.chart1.MouseWheel += new System.Windows.Forms.MouseEventHandler(chart_MouseWheel); 感觉不执行。。。

这里不是C#版块


Question: 求助make并发编译问题

搜“跟我一起写makefile”？

同问啊！！！！！！！

把make替换为$(MAKE)可以解决


Question: 有个问题请教大牛

抽象层次的不同：一句顶十句

C其实也不能，只是可以大致控制一下 C++如果你当作C用的话，和C的区别不是很大 如果你使用高级特性，那还是不要想太多

楼主的意思是说程序语句对应的汇编代码吗？

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

转成汇编代码后其实机制都是一样的，但c++因为比c抽象层次更多，所以理解起来要更难，所以要学得深，最好搞懂它的内存机制。


Question: memcpy段错误，

看不懂时看下一行对应汇编指令或C/CPP源代码，直到能看懂为止。

引用 12楼赵4老师 的回复:进程意外退出会在当前目录下产生‘core’文件或形如‘core.数字’的文件比如‘core.1234’ 使用命令 gdb 运行程序名 core或core.数字 进入gdb然后使用bt命令 可以查看进程意外退出前函数调用的堆栈，内容为从上到下列出对应从里层到外层的函数调用历史。 如果进程意外退出不产生core文件，参考“ulimit -c core文件最大块大小”命令查看咯core 文件产生的信息，就是在memcpy的时候进程core掉的。上面的图片是gdb调试的时候打出的信息

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

NAME        memcpy - copy memory area  SYNOPSIS        #include <string.h>         void *memcpy(void *dest, const void *src, size_t n);  DESCRIPTION        The  memcpy()  function  copies  n bytes from memory area src to memory        area dest.  The memory areas must not overlap.  Use memmove(3)  if  the        memory areas do overlap.  RETURN VALUE        The memcpy() function returns a pointer to dest.  CONFORMING TO        SVr4, 4.3BSD, C89, C99, POSIX.1-2001.

引用 3楼heroesjun 的回复:再贴一点代码，把sGbsinfo结构体类型贴出来看看。第一张图片里面有打印部分的结构体成员

引用 6楼heroesjun 的回复:引用 5 楼 初見的畫面的回复:[quote=引用 2 楼 qq_26238085 的回复:] [quote=引用 1楼ant2012 的回复:]sMsgCode是什么类型，另外“51”占三个字节，还有最后的'\0'别忘了结构体中都是char 类型的，在使用结构体前，都有使用memset进行初始化。所以拷贝51的时候就没有拷贝结束符 都是char类型你是怎么坐到拷贝字符串进char类型的？[/quote] 是个char数组，看第一张图就知道了。[/quote]是的，这是一个char类型的数组

引用 4楼faith_locus 的回复:复制字符串你使用strcpy更合适，再有段错误应该是你访问非法内存了。以为在第一张图的时候可以看到sMsgCode是一个20位的字符数组，所以应该

引用 5 楼 初見的畫面的回复:引用 2 楼 qq_26238085 的回复:[quote=引用 1楼ant2012 的回复:]sMsgCode是什么类型，另外“51”占三个字节，还有最后的'\0'别忘了结构体中都是char 类型的，在使用结构体前，都有使用memset进行初始化。所以拷贝51的时候就没有拷贝结束符 都是char类型你是怎么坐到拷贝字符串进char类型的？[/quote] 是个char数组，看第一张图就知道了。

引用 2 楼 qq_26238085 的回复:引用 1楼ant2012 的回复:sMsgCode是什么类型，另外“51”占三个字节，还有最后的'\0'别忘了结构体中都是char 类型的，在使用结构体前，都有使用memset进行初始化。所以拷贝51的时候就没有拷贝结束符 都是char类型你是怎么坐到拷贝字符串进char类型的？

复制字符串你使用strcpy更合适，再有段错误应该是你访问非法内存了。

再贴一点代码，把sGbsinfo结构体类型贴出来看看。

sMsgCode是什么类型，另外“51”占三个字节，还有最后的'\0'别忘了


Question: 枚举类型 求指导~

你这里的枚举是从3开始的

感谢各位大神指导~~~

枚举的本质是整型，一个枚举值，可以看成是整数的别名，sun被显式赋值为2，所以后面的mon、tue依此加一，即3和4。day被赋值为2，而且输出的格式是整型格式”%d“，所以打印结果即2。

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

枚举类型只是整数的马甲。

定义的enum weekday中没有等于2的枚举常量，是从3开始的。 printf("%d")只认识二进制，不管是什么类型的，2就是2，不管它是整数还是枚举类型。


Question: C语言编写的虚拟串口通信程序出错，显示Open COM Failed，请问是什么原因？

把分给我吧   串口只能打开一次  必须关掉或者程序被结束后  才能再次打开

GetLastError()看看是什么错误

串口open failed还能发数据？有没有单步调，看看数据怎么发的？


Question: 请教c语言是怎么表示NULL的？

C里面 char有NULL?

引用 27 楼 u014444402 的回复:要插到数据库，得先格式化好不好？ 谢谢，怎么格式化？

要插到数据库，得先格式化好不好？

引用 25 楼 libaoyuan1114 的回复:首先，你定义的结构体对应的字段类型是float/double类型，那么你在c语言中见过这种类型有你所谓的NULL吗，答案是没有，他都是转换成0。所以如果你要非要数据库中完全搬移过去，那我个人认为你最好转换成字符型。希望对你有帮助 谢谢，那C的字符char[10]就有NULL了、CHAR[10]什么情况算NULL呢？

引用 22 楼 q3733353520 的回复:[quote=引用 21 楼 startstop2015 的回复:] [quote=引用 19 楼 q3733353520 的回复:] [quote=引用 17 楼 startstop2015 的回复:] #define NULL 0能说明什么问题码？能解决我的问题码？ NULL无非一个标识符宏，其值=0而已，能解决我的问题码？ 谢谢  你可以去数据库版块问怎么插入null[/quote] SQL 怎么做我知道，这个是PRO*C，涉及到C的结构体，并非纯粹的数据库操作[/quote]    引用 21 楼 startstop2015 的回复:[quote=引用 19 楼 q3733353520 的回复:] [quote=引用 17 楼 startstop2015 的回复:] #define NULL 0能说明什么问题码？能解决我的问题码？ NULL无非一个标识符宏，其值=0而已，能解决我的问题码？ 谢谢  你可以去数据库版块问怎么插入null[/quote] SQL 怎么做我知道，这个是PRO*C，涉及到C的结构体，并非纯粹的数据库操作[/quote]   http://blog.csdn.net/wp_gis/article/details/5452454[/quote] 谢谢，谢谢，我现在的疑问不是使用指示变量 而是C怎么区分0和NULL?

引用 21 楼 startstop2015 的回复:[quote=引用 19 楼 q3733353520 的回复:] [quote=引用 17 楼 startstop2015 的回复:] #define NULL 0能说明什么问题码？能解决我的问题码？ NULL无非一个标识符宏，其值=0而已，能解决我的问题码？ 谢谢  你可以去数据库版块问怎么插入null[/quote] SQL 怎么做我知道，这个是PRO*C，涉及到C的结构体，并非纯粹的数据库操作[/quote]    引用 21 楼 startstop2015 的回复:[quote=引用 19 楼 q3733353520 的回复:] [quote=引用 17 楼 startstop2015 的回复:] #define NULL 0能说明什么问题码？能解决我的问题码？ NULL无非一个标识符宏，其值=0而已，能解决我的问题码？ 谢谢  你可以去数据库版块问怎么插入null[/quote] SQL 怎么做我知道，这个是PRO*C，涉及到C的结构体，并非纯粹的数据库操作[/quote]   http://blog.csdn.net/wp_gis/article/details/5452454

引用 19 楼 q3733353520 的回复:[quote=引用 17 楼 startstop2015 的回复:] #define NULL 0能说明什么问题码？能解决我的问题码？ NULL无非一个标识符宏，其值=0而已，能解决我的问题码？ 谢谢  你可以去数据库版块问怎么插入null[/quote] SQL 怎么做我知道，这个是PRO*C，涉及到C的结构体，并非纯粹的数据库操作

引用 18 楼 zhangxiangDavaid 的回复:[quote=引用 17 楼 startstop2015 的回复:] #define NULL 0能说明什么问题码？能解决我的问题码？ NULL无非一个标识符宏，其值=0而已，能解决我的问题码？ 谢谢 你需要理解宏[/quote] 能否赐教一下?xiexie

引用 17 楼 startstop2015 的回复:#define NULL 0能说明什么问题码？能解决我的问题码？ NULL无非一个标识符宏，其值=0而已，能解决我的问题码？ 谢谢  你可以去数据库版块问怎么插入null

引用 17 楼 startstop2015 的回复:#define NULL 0能说明什么问题码？能解决我的问题码？ NULL无非一个标识符宏，其值=0而已，能解决我的问题码？ 谢谢 你需要理解宏

引用 23 楼 startstop2015 的回复:[quote=引用 22 楼 q3733353520 的回复:] [quote=引用 21 楼 startstop2015 的回复:] [quote=引用 19 楼 q3733353520 的回复:] [quote=引用 17 楼 startstop2015 的回复:] #define NULL 0能说明什么问题码？能解决我的问题码？ NULL无非一个标识符宏，其值=0而已，能解决我的问题码？ 谢谢  你可以去数据库版块问怎么插入null[/quote] SQL 怎么做我知道，这个是PRO*C，涉及到C的结构体，并非纯粹的数据库操作[/quote]    引用 21 楼 startstop2015 的回复:[quote=引用 19 楼 q3733353520 的回复:] [quote=引用 17 楼 startstop2015 的回复:] #define NULL 0能说明什么问题码？能解决我的问题码？ NULL无非一个标识符宏，其值=0而已，能解决我的问题码？ 谢谢  你可以去数据库版块问怎么插入null[/quote] SQL 怎么做我知道，这个是PRO*C，涉及到C的结构体，并非纯粹的数据库操作[/quote]   http://blog.csdn.net/wp_gis/article/details/5452454[/quote] 谢谢，谢谢，我现在的疑问不是使用指示变量 而是C怎么区分0和NULL?[/quote](void *)0

引用 15 楼 zxh707wk 的回复:#define NULL 0 谢谢，这个算什么意思呢？ 我的数据库里的NUMBER数值是NULL,保存到c语言的结构体的DOUBLE成员的时候，变成了0 然后这个结构体插入到数据库表，也是0，这个怎么解决啊？

#define NULL 0

如果说NULL就是0 那么和真正的0怎么区分呢？

引用 12 楼 zhao4zhong1 的回复:Code::Blocks也有类似VS IDE的功能。 谢谢，我不知道这事啥意思，我只想知道为什么数据库里的NULL保存到C语言的结构体里变成了0,然后再插入到表里就是0 我不知道怎么解决

Code::Blocks也有类似VS IDE的功能。

引用 10 楼 user-8 的回复:NULL的ASCii码值不就是0莫。。。。。。 你意思是不是数据库中某字段为空，然后你用PROC把它选出来赋给C结构提成员，最终保存在成员中的值为0？  你在判断null的时候不使用=符号，因为null值比较特殊，需要使用 is null 表达式来判断。 把你存储过程中所有 =null 的内容 都改为 is null 。然后当该字段为NULL时，你给结构体成员特殊值（你想表达的空对应值）试试 首先表A NAME SALARY A    0 B    100 C    NULL    <-salry是NULL，不是'NULL'  SELECT NAME, SALARY INTO C结构体数组 FROM A 然后 INSERT INTO B表(NAME,SALARY) VALUES(:C结构体数组); 此时B表的SALARY是 0，不是 NULL，而且这里我不能这样 INSERT INTO B表(NAME,SALARY) VALUES(:C结构体数组->NAME,(:C结构体数组->SALARY,0,NULL)); 因为也有0值  B表的数据变成了这样 NAME SALARY A    0 B    100 C    0  和你说的IS NULL没有关系，这个我知道的


Question: 拦截导弹

在百度上搜原题。

最长下降/上升子序列


Question: socket  怎样检测TCP连接是否失效？

心跳包是最有效的方案。

tcp协议栈的keepalive是有个陷阱的，比如说 服务端挂了，而你还不停的往这个socket上发数据，因为send是往内核里写数据（缓冲区没满是是不会阻塞的），此时tcp认为该socket还存在数据往来，就认为该连接是有效的。  上次就差点因为这个没把一个关键bug解决，巨坑~~

总结以上所说，检测TCP连接是否有效，最好的方法是进行心跳包检测。检测过程中，网断、服务器断开等情况分别需要检测会出现什么结果。结贴啦

如15楼所说

引用 9 楼 cr945211 的回复:如果网络断开，setsockopt(sock_fd,SOL_SOCKET,SO_SNDTIMEO,(const char*)&timeout,sizeof(timeout))依然为0，但是send函数的执行不会使程序终止；如果服务器断开，setsockopt(sock_fd,SOL_SOCKET,SO_SNDTIMEO,(const char*)&timeout,sizeof(timeout))依然为0，send函数的执行会提示信号错误，导致程序终止。以上是调试过程中出现的结果，如果连续运行，服务器断开后程序不会终止。 我查到的资料都是这样用setsockopt来设定send和recv的超时。但是理论上应该是：若无错误发生，setsockopt()返回0，否则的话，返回SOCKET_ERROR错误。  你的网络断开是指：直接禁用网卡或拔网线或关闭交换机电源？       //这样操作socket还是一个全法状态的socket，所以发送不会有问题 你的服务器断开 是指：服务器正常退出，客户端正常关闭socket吗？//如果是这样，socket处于关闭或time_wait或close_wait或其他状态，发送会出问题

引用 10 楼 lianshaohua 的回复:强烈建议使用心跳机制，一发一回； 强烈不建议使用keep_alive现在没使用keepalive，用的是心跳包，请看一下9楼的问题，能不能帮我解答下？

看来还真是有陷阱啊，我测试测试 。

引用 11 楼 zhllxt 的回复:[quote=引用 5 楼 zhao4zhong1 的回复:] 不要管KeepAlive，使用心跳包。  我想问一下赵老师，我在开源的HPSocket中看到检测连接是否正常的代码就是用的KeepAlive，我测试过，这个KeepAlive非常可靠，我觉得完全没有必要再自己定义心跳包来实现检测了。 赵老师说“不要管KeepAlive，使用心跳包。”是有什么我不知道的陷阱在里面吗？[/quote] 换移动互联网你再测一下。

引用 5 楼 zhao4zhong1 的回复:不要管KeepAlive，使用心跳包。  我想问一下赵老师，我在开源的HPSocket中看到检测连接是否正常的代码就是用的KeepAlive，我测试过，这个KeepAlive非常可靠，我觉得完全没有必要再自己定义心跳包来实现检测了。 赵老师说“不要管KeepAlive，使用心跳包。”是有什么我不知道的陷阱在里面吗？

强烈建议使用心跳机制，一发一回； 强烈不建议使用keep_alive

测试

自定义心跳包或者启用保活定时机制

最简单也是最常用的维持长连接的方法是： 客户端发送心跳包 靠设置socket的keepalive是不够的

自定义心跳包来监测是否连接正常

参考略微成熟一点的相关开源项目中的相关源代码。

上面写错了 send(sock_fd,senfbuf,len1,0); recv(sock_fd,recvbuf,len2,0);

引用 5 楼 zhao4zhong1 的回复:不要管KeepAlive，使用心跳包。 不停给服务器发数据、接收数据来检测是否处于连接状态。如果服务器断开，还是要继续发送数据、接收数据，以下为将发送、接收设置为超时。但是服务器断开后ret1和ret2一直为0，还是会运行send函数，接着会出现错误；recv函数执行时不会出现错误，但是ret1和ret2不应该都是0啊？异常应该是-1吧。请问这是为什么？  int ret1=setsockopt(sock_fd,SOL_SOCKET,SO_SNDTIMEO,(const char*)&timeout,sizeof(timeout)); if(ret1!=-1) {        send(sock,senfbuf,len1,0); }  int ret2=setsockopt(sock_fd,SOL_SOCKET,SO_RCVTIMEO,(const char*)&timeout,sizeof(timeout)); if(ret2!=-1) {        recv(sock,recvbuf,len2,0); }

不要管KeepAlive，使用心跳包。


Question: c语言模拟class遇到个额问题

有钻研精神很佩服，不过我觉得这个技术非主流，不值得浪费太多时间，不如C++。

我想这个就是用C实习面向对象吧，一个结构体，里面有函数指针

C++一个重要特性是析构函数的自动化执行 这个是C所不具备的， 这个特性，对资源的配置与释放，异常安全等方面，很方便 而C差不多要手工处理。 每种语言，编译器，都有它的好处，与不足 用一个语言，去做另一个语言擅长的事情，是很吃力的，当然做得好了，也很有成就感。 喜欢玩，就努力去做吧，不是很喜欢探索的话，还是根据问题不同，选择工具吧

引用 7 楼 Saleayas 的回复:把你的函数指针，定义到其他的结构里面，然后，在这个结构里，使用指针指向他。 定义函数指针的结构就是所谓的虚表。 而这个虚表其实在编译的时候是固定的。 这样，你的构造的时候，虚表的实例指针也是固定的，就可以直接使用 = {} 模式构造了。

面向过程的语言还要封装，为啥不直接用C++，而且结构体并没有private，封装并没有效果，这函数指针谁想用都能用，又有什么意义

何必非要把c弄成c++的样子？

要么用C， 要么用C++， 这不伦不类的算啥。

引用 4 楼 chouxiaoya8100 的回复:[quote=引用 3 楼 JiangWenjie2014 的回复:] 楼主知不知道GLIB除了GQueue之外还有一个GAsyncQueue，这个就是加锁的GQueue。  可以直接使用？ 不需要用任何锁和其配合？  如此说来， GQueue根本就没有必要出现在多线程中， 浪费代码。直接使用CAnsyQueue即可。  我理解的对否？ [/quote] GQueue提供的接口不是线程安全的，GAsyncQueue提供的接口是线程安全的。并不是说多线程代码中就不能用GQueue了，如果一个GQueue对象只在一个线程中维护，那就可以用。你没有GLIB的源码吗，看一下GAsyncQueue类型的定义，它里面就自带锁了。  typedef struct _GAsyncQueue GAsyncQueue;  struct _GAsyncQueue {   GMutex mutex;   GCond cond;   GQueue queue;   GDestroyNotify item_free_func;   guint waiting_threads;   gint ref_count; };  void g_async_queue_push (GAsyncQueue *queue,                     gpointer     data) {   g_return_if_fail (queue);   g_return_if_fail (data);    g_mutex_lock (&queue->mutex);   g_async_queue_push_unlocked (queue, data);   g_mutex_unlock (&queue->mutex); }

引用 3 楼 JiangWenjie2014 的回复:楼主知不知道GLIB除了GQueue之外还有一个GAsyncQueue，这个就是加锁的GQueue。  可以直接使用？ 不需要用任何锁和其配合？  如此说来， GQueue根本就没有必要出现在多线程中， 浪费代码。直接使用CAnsyQueue即可。  我理解的对否？


Question: 对析构函数的盲点

引用 13 楼 heroesjun 的回复:[quote=引用 7 楼 U201212366 的回复:] /////.h///////////////// class test { public: 	test(); 	test(char *); 	bool read(void **); 	char * buffer; }; //////.cpp///////////// #include "stdio.h" #include "studybv.h" #include <string.h>   test::test() { 	buffer = NULL; }  test::test(char *p) { 	buffer = p; }  bool test::read( void ** q ) { 	*q = buffer; 	if (*q == NULL) 	{ 		return false; 	} 	return true; }  void main() { 	void *p = NULL; 	char *x = new char[4]; 	char *a = "abc"; 	if(1) 	{ 		test T(a); 			     		if (T.read(&p)) 		{ 			printf("%s",p); 		} 		strcpy(x, (char *)p); 	} 	printf("%s",p); 	printf("%s",x); 	delete []x; } ////////////////////////////// 这是我做的测试用的小程序，为什么结果是“abcabcabc” 第二个printf("%s",p); 不应该因为出了作用域而失效吗  打印p的时候，已经出了T对象的作用域， 所以它会被析构掉，但T类中的buffer指向的是在T对象外部的字符串常量，即main函数中的a字符串“abc”， 这个字符串在main中一直存在，所以p能打印出来。[/quote] 恍然大悟  谢谢

引用 12 楼 aqiu348503 的回复:[quote=引用 7 楼 U201212366 的回复:] /////.h///////////////// class test { public: 	test(); 	test(char *); 	bool read(void **); 	char * buffer; }; //////.cpp///////////// #include "stdio.h" #include "studybv.h" #include <string.h>   test::test() { 	buffer = NULL; }  test::test(char *p) { 	buffer = p; }  bool test::read( void ** q ) { 	*q = buffer; 	if (*q == NULL) 	{ 		return false; 	} 	return true; }  void main() { 	void *p = NULL; 	char *x = new char[4]; 	char *a = "abc"; 	if(1) 	{ 		test T(a); 			     		if (T.read(&p)) 		{ 			printf("%s",p); 		} 		strcpy(x, (char *)p); 	} 	printf("%s",p); 	printf("%s",x); 	delete []x; } ////////////////////////////// 这是我做的测试用的小程序，为什么结果是“abcabcabc” 第二个printf("%s",p); 不应该因为出了作用域而失效吗 你printf的p和x都没出main作用域啊，出了作用域访问就会编译出错的还怎么打印结果[/quote] 是的 可是我的问题是为什么会有结果

引用 11 楼 zhao4zhong1 的回复:生、死 构造、析构 new、delete malloc、free {、}  你说的我知道一点点，可是我的问题是我没有动态创建，需不需要我手动释放，因为F5调试的时候检测到了内存泄露

pixData和OpenFilePath所指的空间是动态分配的，还是指向外部数据块，如果是动态分配的话，需要用析构delete掉，myfileheader不需要处理，对象析构的时候会自动释放它。另外如果class没有定义析构函数，那么只有在class内带有member object(或是class自己的base class)拥有析构函数的情况下，编译器才会自动合成一个来，否则析构函数会被视为不需要，也就不需要被合成。但还是建议你不管你的类需不需要，你都应该定义一个析构函数，并声明为virtual，因为如果该类的使用者定义一个子类，非virtual的析构函数有可能导致内存泄露。

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

在构造时候用了new，那么析构时候就要delete掉

因为我这是动态链接库的导出类，外面的主进程会给我提供相应的参数，在外面可以动态分配内存，而我只需要使数据放到动态分配的内存空间里就行了，因为我内部主要完成的是对结构体对象成员的赋值和获取目标文件相应数据的指针，对于如何转出，我又迷茫了，因为我采用的是void **的方式

个人意见， 强烈建议区分"堆栈".  不需要析构函数就不写或者用~XXXX() = default; 指针指向成员或者结构体? 那为什么不用new?

引用 7 楼 U201212366 的回复://///.h///////////////// class test { public: 	test(); 	test(char *); 	bool read(void **); 	char * buffer; }; //////.cpp///////////// #include "stdio.h" #include "studybv.h" #include <string.h>   test::test() { 	buffer = NULL; }  test::test(char *p) { 	buffer = p; }  bool test::read( void ** q ) { 	*q = buffer; 	if (*q == NULL) 	{ 		return false; 	} 	return true; }  void main() { 	void *p = NULL; 	char *x = new char[4]; 	char *a = "abc"; 	if(1) 	{ 		test T(a); 			     		if (T.read(&p)) 		{ 			printf("%s",p); 		} 		strcpy(x, (char *)p); 	} 	printf("%s",p); 	printf("%s",x); 	delete []x; } ////////////////////////////// 这是我做的测试用的小程序，为什么结果是“abcabcabc” 第二个printf("%s",p); 不应该因为出了作用域而失效吗  打印p的时候，已经出了T对象的作用域， 所以它会被析构掉，但T类中的buffer指向的是在T对象外部的字符串常量，即main函数中的a字符串“abc”， 这个字符串在main中一直存在，所以p能打印出来。

引用 7 楼 U201212366 的回复://///.h///////////////// class test { public: 	test(); 	test(char *); 	bool read(void **); 	char * buffer; }; //////.cpp///////////// #include "stdio.h" #include "studybv.h" #include <string.h>   test::test() { 	buffer = NULL; }  test::test(char *p) { 	buffer = p; }  bool test::read( void ** q ) { 	*q = buffer; 	if (*q == NULL) 	{ 		return false; 	} 	return true; }  void main() { 	void *p = NULL; 	char *x = new char[4]; 	char *a = "abc"; 	if(1) 	{ 		test T(a); 			     		if (T.read(&p)) 		{ 			printf("%s",p); 		} 		strcpy(x, (char *)p); 	} 	printf("%s",p); 	printf("%s",x); 	delete []x; } ////////////////////////////// 这是我做的测试用的小程序，为什么结果是“abcabcabc” 第二个printf("%s",p); 不应该因为出了作用域而失效吗 你printf的p和x都没出main作用域啊，出了作用域访问就会编译出错的还怎么打印结果

生、死 构造、析构 new、delete malloc、free {、}

我要的就是地址，这个是作为fopen的参数的

在实例对象时成员分配内存空间，如果你不给openfile成员使用new来初始化分配具体的空间大小，那它所占的空间只是一个地址大小而已（除非你用数组形式），所以既然要用new,也就要析构delete

栈区存放该类的对象，但对象本身有指针变量，指针变量指向的空间有可能是在对象存在的生命期中动态分配的，所以析构函数里必须释放这些指针。

因为我之前想的是既然我要用到这个类的对象，那么在栈区已经有了相应空间，我就没必要再去new一个到堆区离了，不知道这种想法是否正确。


Question: 请问数组为什么读取我输入的数据？

引用 10 楼 u010284226 的回复: scanf_s("%c",s[i],sizeof(s[i]))  引用 10 楼 u010284226 的回复: scanf_s("%c",s[i],sizeof(s[i]))  再把 for(i=0;i<20;++i) 改为 for(i=0;i<20;i++)

ANSI C中没有scanf_s(),只有scanf()，scanf()在读取时不检查边界，所以可能会造成内存访问越界，例如分配了5字节的空间但是读入了10字节 char buf[5]={'\0'}; scanf("%s", buf); 如果输入1234567890，后面的部分会被写到别的空间上去。 以上代码如果用scanf_s,第二行应改为scanf_s("%s",buf,5),表示最多读取4个字符，因为buf[4]要放'\0' scanf_s最后一个参数是缓冲区的大小，表示最多读取n-1个字符. vc++2005/2008中提供了scanf_s(),在最新的VS2013中也提供了scanf_s()。在调用时，必须提供一个数字以表明最多读取多少位字符。

int main(void) { 	int i; 	char s[10]; 	for (i = 0; i < 10; i++) 		scanf("%c", s + i); 	for (i = 0;i < 10;i++) 		printf("%c", s[i]); 	printf("\n"); 	return 0; }

#pragma warning(disable:4996)

引用 5 楼 qq_30446977 的回复:scanf_s是scanf的安全形式。后面必须加上最大存储长度，所以括号内必须再加上一个scanf_s（“%c”，&s[i]，1）才行。你能给我个你编译器的下载地址吗，我也是刚自学c的，但是我下载的编译器都不支持c11，包括scanf_s（）。我一直都是用不加_s的函数。我书上好多都是用的_s的函数，说这个的安全。谢谢啊 微软官网

并且你只输入了19位数，应该使用i++，而不是++i

为什么不用scanf

是为什么没有，打错了！


Question: 二维数组在调用函数中的声明问题

第一行什么意思都不知道

typedef int arr[][4]; cout << typeid(arr).name() << endl;  //int[0][4]

前面应该定义了arr3x4类型的：  typedef int arr3x4[][4];  引用 楼主 cant_see 的回复: 这里的第一行是不是有问题，看不懂

楼主得把上下文贴全了，看样子 arr3x4 应该是在前面定义了。

第一种没见过，第二种和第三种等价，因为形参中二维数组的第一维长度是没有意义的


Question: 求教memset报错，谢谢

对不起，我搞错了，你的是二维数组

我认为你的malloc是为了保存100行记录，应该乘上ROWS，否则，你申请的内存大小只能存放一条记录

引用 10 楼 startstop2015 的回复:[quote=引用 9 楼 q3733353520 的回复:] [quote=引用 8 楼 startstop2015 的回复:] [quote=引用 5 楼 u012033027 的回复:] 你用了ROWS*的时候，分配的可视为一个元素为struct_emp的数组，没有ROWS*的时候，分配的是一个元素。 都可以的，看你怎么用了。 你的意思是两种写法都是正确的？[/quote]   array_emp=(struct struct_emp *)malloc(ROWS*sizeof(struct struct_emp));  memset(array_emp,0,ROWS*sizeof(struct struct_emp));//就是不该加&   如果你的malloc用了ROWS*，那么你的memset也要用ROWS* 我看你的结构体里面的成员是个大小100的数组，按你的意思应该是2个都可以不加[/quote] 我只要申请够用的内存即可，也就是保存100行的内存，到底该怎么写啊？[/quote]  引用 10 楼 startstop2015 的回复:[quote=引用 9 楼 q3733353520 的回复:] [quote=引用 8 楼 startstop2015 的回复:] [quote=引用 5 楼 u012033027 的回复:] 你用了ROWS*的时候，分配的可视为一个元素为struct_emp的数组，没有ROWS*的时候，分配的是一个元素。 都可以的，看你怎么用了。 你的意思是两种写法都是正确的？[/quote]   array_emp=(struct struct_emp *)malloc(ROWS*sizeof(struct struct_emp));  memset(array_emp,0,ROWS*sizeof(struct struct_emp));//就是不该加&   如果你的malloc用了ROWS*，那么你的memset也要用ROWS* 我看你的结构体里面的成员是个大小100的数组，按你的意思应该是2个都可以不加[/quote] 我只要申请够用的内存即可，也就是保存100行的内存，到底该怎么写啊？[/quote]    array_emp=(struct struct_emp *)malloc(sizeof(struct struct_emp));  memset(array_emp,0, sizeof(struct struct_emp));//就是不该加&

引用 9 楼 q3733353520 的回复:[quote=引用 8 楼 startstop2015 的回复:] [quote=引用 5 楼 u012033027 的回复:] 你用了ROWS*的时候，分配的可视为一个元素为struct_emp的数组，没有ROWS*的时候，分配的是一个元素。 都可以的，看你怎么用了。 你的意思是两种写法都是正确的？[/quote]   array_emp=(struct struct_emp *)malloc(ROWS*sizeof(struct struct_emp));  memset(array_emp,0,ROWS*sizeof(struct struct_emp));//就是不该加&   如果你的malloc用了ROWS*，那么你的memset也要用ROWS* 我看你的结构体里面的成员是个大小100的数组，按你的意思应该是2个都可以不加[/quote] 我只要申请够用的内存即可，也就是保存100行的内存，到底该怎么写啊？

引用 8 楼 startstop2015 的回复:[quote=引用 5 楼 u012033027 的回复:] 你用了ROWS*的时候，分配的可视为一个元素为struct_emp的数组，没有ROWS*的时候，分配的是一个元素。 都可以的，看你怎么用了。 你的意思是两种写法都是正确的？[/quote]   array_emp=(struct struct_emp *)malloc(ROWS*sizeof(struct struct_emp));  memset(array_emp,0,ROWS*sizeof(struct struct_emp));//就是不该加&   如果你的malloc用了ROWS*，那么你的memset也要用ROWS* 我看你的结构体里面的成员是个大小100的数组，按你的意思应该是2个都可以不加

引用 5 楼 u012033027 的回复:你用了ROWS*的时候，分配的可视为一个元素为struct_emp的数组，没有ROWS*的时候，分配的是一个元素。 都可以的，看你怎么用了。 你的意思是两种写法都是正确的？

费那事！ array_emp=(struct struct_emp *)calloc(1,sizeof(struct struct_emp));

引用 3 楼 u012033027 的回复:malloc是正确的。 memset的第一个参数确实应该是指针，但是array_emp本身就是一个指向了分配空间的指针，直接使用就可以了。如果在使用取地址操作&，反而不对，不是指向刚才malloc所分配的空间的。 谢谢，我这样malloc貌似是错的，而不是你说的是正确的 struct struct_emp {   char  name[ROWS][10];   float salary[ROWS]; };  int main(int argc,char* argv[]) {   struct struct_emp *array_emp;   array_emp=(struct struct_emp *)malloc(ROWS*sizeof(struct struct_emp));   这个地方array_emp=(struct struct_emp *)malloc(ROWS*sizeof(struct struct_emp));  似乎不应该有ROWS*了  memset你说的我不是很懂，心里没底

引用 1 楼 u012033027 的回复:memset(&array_emp,0,ROWS*sizeof(struct struct_emp)); 改为 memset(array_emp,0,ROWS*sizeof(struct struct_emp)); 试试看。 谢谢，为什么这样改？不都是&XX这样写的吗？ 我现在还不确定的malloc是否正确


Question: 为什么会访问冲突？

引用 6 楼 linfengc 的回复:这年头怎么还在搞c啊.  直接c++ primer搞起. stl搞起, boost搞起.  学盖房子也别学怎么烧砖... 不会c的c++程序员，不是好的c++程序员

修改如下：  #include <stdio.h> struct fullname { 	char fname[20]; 	char lname[20]; }; struct bard { 	struct fullname name; 	int born; 	int died; }; struct bard willie; int main(void) { 	scanf("%d", &willie.born); 	scanf("%d", &willie.died); 	scanf("%s", willie.name.fname); 	scanf("%s", willie.name.lname); 	printf("name.fname=%s,name.lname=%s,born=%d,died=%d\n", willie.name.fname, willie.name.lname, willie.born, willie.died); 	return 0; };

话说输入的时候为什么要用换行符呢？ ‘\n’这个东西是干嘛的？

我的编译器能提示这种错误code blocsk.

引用 6 楼 linfengc 的回复:这年头怎么还在搞c啊.  直接c++ primer搞起. stl搞起, boost搞起.  学盖房子也别学怎么烧砖...  c++能用来开发单片机吗？

#include <stdio.h>  struct fullname {     char fname[20];     char lname[20]; };  struct bard {     struct fullname name;     int born;     int died; };  struct bard willie; struct bard *pt = &willie;  int main(void) {     scanf("%d\n", &willie.born);     scanf("%d\n", &pt->born);     scanf("%s\n", willie.name.lname);     scanf("%s\n", pt->name.lname);      printf("%s\n", pt->name.lname);      getchar();     return 0; }

崩溃的时候在弹出的对话框按相应按钮进入调试，按Alt+7键查看Call Stack即“调用堆栈”里面从上到下列出的对应从里层到外层的函数调用历史。双击某一行可将光标定位到此次调用的源代码或汇编指令处，看不懂时双击下一行，直到能看懂为止。  printf里面的%和变量的一一对应关系 scanf里面的%和变量以及变量前加不加&的一一对应关系 是C代码中非常容易出错的地方，而且通常编译还不出错。 所以在编译源代码之前值得专门仔细检查一遍甚至多遍。

所有的scanf把取地址符号都去掉试试

当然冲突了，lname[2]是一个字符，%s输出一个字符串，printf在输出时，会将这个字符的值转成地址，而且遇'\0'结束，所以会崩溃


Question: c语言如何实现局部锁？

上帝为什么不担心有人长生不老呢？

lz与其担心锁未释放，为什么不担心内存未释放? 没有智能指针忘记释放怎么办, 锁未释放, 可能线程死锁, 可能直接就看出来了, 内存不释放很蛋疼.  先写 {     xxx_lock(&locker);     xxx_unlock(&locker); } 再在中间写? 没用过纯C, lz要不要加入C++


Question: 怎么把数字以字母形式输出

使用递归啊  //函数 void rever_array(int number){ 	if(number/10)rever_array(number/10); 	putchar(number%10+'0'); }

其实已经是字符串了，你想存起来的话，改用sprintf即可。  引用 5 楼 dag617712 的回复:[quote=引用 2 楼 walkiz 的回复:]  printf("%ld", 54445352);  我是想把这几个数字以字母形式输出，这样还是以数字形式啊[/quote]

/************************* 将整数以字符形式输出 *************************/ #include <stdio.h>  int main () { 	int num = 12345; 	int arr[100]; 	int i = 0; 	int count = 0; 	do 	{ 		arr[i++] = num % 10;//5  4      3     2    1 		num = num / 10;//1234    123    12    1     0 		count ++;//1  2  3  4  5 	}while(num); //	printf("%d\n",count); 	for(i = count-1; i >= 0; --i) 	{ 		printf("%c",arr[i]); 	} 	printf("\n"); 	return 0; } 不知道你指的是不是这个意思你看下

作为一个C程序员，对  scanf,sscanf,fscanf  printf,sprintf,fprintf 这类函数的用法，还是要做到“拳不离手，曲不离口”的。

你想把ascii以字符的型式输出可以是可以,得手动分开 char a = 54； char b = 44； char c = 53； char d = 52； printf("%c,%c,%c,%c\n",a,b,c,d); 要是让程序自动分割可能很困难 54445352，可以是54，44，53，52 也可能是54，4，4，5，35，2， 除非本来就有分隔符

引用 11 楼 dag617712 的回复:[quote=引用 10 楼 zhangxiangDavaid 的回复:] RSDT是个啥？  R的ASCII是54，以此类推[/quote] R的ASCII是82

引用 10 楼 zhangxiangDavaid 的回复:RSDT是个啥？  R的ASCII是54，以此类推

RSDT是个啥？

引用 8 楼 zhangxiangDavaid 的回复:[quote=引用 7 楼 dag617712 的回复:] [quote=引用 6 楼 dag617712 的回复:] [quote=引用 4 楼 zhangxiangDavaid 的回复:] 你可以：  int main(void) { 	char s[] = "54445352"; 	printf("%s", s); 	return 0; }  运行结果还是不对[/quote][/quote] 你要哪种结果？[/quote] 把54445352以RSDT输出

引用 7 楼 dag617712 的回复:[quote=引用 6 楼 dag617712 的回复:] [quote=引用 4 楼 zhangxiangDavaid 的回复:] 你可以：  int main(void) { 	char s[] = "54445352"; 	printf("%s", s); 	return 0; }  运行结果还是不对[/quote][/quote] 你要哪种结果？

引用 6 楼 dag617712 的回复:[quote=引用 4 楼 zhangxiangDavaid 的回复:] 你可以：  int main(void) { 	char s[] = "54445352"; 	printf("%s", s); 	return 0; }  运行结果还是不对[/quote]

引用 4 楼 zhangxiangDavaid 的回复:你可以：  int main(void) { 	char s[] = "54445352"; 	printf("%s", s); 	return 0; }  运行结果还是不对

引用 2 楼 walkiz 的回复: printf("%ld", 54445352);  我是想把这几个数字以字母形式输出，这样还是以数字形式啊

把它转换成字符串在输出？或者用楼上的办法更直接

printf("%ld", 54445352);

存到数组，或用指针指向它，一个一个打印输出

#include<stdio.h>  int main() {     unsigned int n;     scanf("%x",&n);                              // 输入54445352     for(int i=0;i<sizeof n;++i)         putchar(  ( (const char*)&n )[i]  );     // 输出RSDT     putchar('\n');     return 0; }

没法子，因为 字符有256个，ASCII有0～127，128 个所以必须定义好你的数字的意义，才能按照所谓的字符输出 汉字更多


Question: 求救！！我这个菜鸟看不懂是什么意思

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

printf("%c\n", c);

看效果：  #include <stdio.h> int main() { 	char c; 	for (;(c = getchar()) != '\n';) 		printf("%c\n", c); 	return 0; } //zhangxiang //z //h //a //n //g //x //i //a //n //g

好了，打印后面少个东西，谢谢呵

可打印出来的全是换行啊，什么也不显示

打印你输入的字符，遇到回车结束


Question: 请教，程序异常终止时，malloc分配的堆内存会自动释放吗?xiexie

会

引用 5 楼 startstop2015 的回复:[quote=引用 4 楼 zhangxiangDavaid 的回复:] 程序都终止了，还有什么可以留下 那我们还用担心比如“内存崩溃”“内存泻漏”吗？即使是堆变量，即使没有free，只要程序结束/异常终止了，也自动free了?[/quote]  服务程序是要长期运行的，可能一年365天一直运行着，如果有内存泄露，超过虚拟内存最大限度，程序就会崩溃。

我们程序使用的内存是虚拟内存，使用的时候映射到物理内存上，当程序崩溃以后，系统就收回了映射的部分，所以，不是是自动free掉，而是强制收回了

引用 5 楼 startstop2015 的回复:[quote=引用 4 楼 zhangxiangDavaid 的回复:] 程序都终止了，还有什么可以留下 那我们还用担心比如“内存崩溃”“内存泻漏”吗？即使是堆变量，即使没有free，只要程序结束/异常终止了，也自动free了?[/quote] 很多时候，内存会泄露，直到内存被耗尽，程序才奔溃

引用 5 楼 startstop2015 的回复:[quote=引用 4 楼 zhangxiangDavaid 的回复:] 程序都终止了，还有什么可以留下 那我们还用担心比如“内存崩溃”“内存泻漏”吗？即使是堆变量，即使没有free，只要程序结束/异常终止了，也自动free了?[/quote]  问题是很多程序不能随意退出 靠程序退出来解决内存泄漏是下下策

引用 4 楼 zhangxiangDavaid 的回复:程序都终止了，还有什么可以留下 那我们还用担心比如“内存崩溃”“内存泻漏”吗？即使是堆变量，即使没有free，只要程序结束/异常终止了，也自动free了?

程序都终止了，还有什么可以留下

引用 2 楼 user-6 的回复:不是自动释放, 而是被系统收回. 那有什么区别码？

不是自动释放, 而是被系统收回.

想请教的是栈变量是否会在程序异常终止时，比如出错了，栈变量申请的内存会自动释放吗？


Question: 新手，指针的问题

引用 楼主 cant_see 的回复: 这里非法的第二个和第三个是为什么呢？ 上面的两个地址之所以非法，是因为两个地址的加法可能导致这个指针的地址可能指向了每个进程的内核空间，肯定会非法。 乘法更不用说，随时就超过了整个进程空间的4G内存空间范围

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

引用 10 楼 zhao4zhong1 的回复:在指针参加四则运算到底哪个有意义，哪个没意义这个问题上，你可以把指针类比为排行榜中的名次。 +1 相当于门牌号可以吗？

指针是被说玄乎的，在我看来，它和普通变量并没有什么区别。

《深入理解C指针》这本书不错，当当或者亚马逊都有，值得拥有。

没有指针与指针相加相乘的运算，只有指针与整数相加相减的运算

指针和指针不能相加或者相乘的，那样没什么意义，指针前移一位，+1，后移一位-1，看看谭浩强爷爷的书就知道怎么回事了

指针运算的限定，参看： http://blog.csdn.net/zhangxiangdavaid/article/details/38146449

C语言中， int *指针类型不支持两指针进行+和*操作

1）数组本就是固定的，他包含定义的所有元素，     他的名字有时候，用来表示首地址（有人说这是类型转换），总之是固定不变的      所以，不论从哪个角度看，自加都无意义 2）因为指针存放的是内存地址，也就是内存单元的位置编号，编号相加，意义不明确，所以指针相加无意义 3）指针乘法同样无意义，因为他只是个编号，很难明确的说明，乘了以后，结果有何意义

可能使ptr2指向不该指向的地方


Question: 请教2个结构体数组的问题，谢谢

引用 17 楼 github_27756899 的回复:例一：  struct rec{ 	int salary; //int是4字节   char  name[4]; }  printf("字节数为%d",sizeof(struct rec));  8字节 例二:  struct rec{ 	int salary; //int是4字节   char  name[5]; }  printf("字节数为%d",sizeof(struct rec));  12字节 我理解了，应该是对齐原则，谢谢你这么晚回答我的问题

对齐字节数：2^n=1、2、4、8……

仅供参考：#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("\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("\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("\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("\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("\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("\n");     return 0; } //AD.a 0 //AD.b 4 //AD.c 24 // //A1.a 0 //A1.b 4 //A1.c 17 // //A2.a 0 //A2.b 4 //A2.c 18 // //A4.a 0 //A4.b 4 //A4.c 20 // //A8.a 0 //A8.b 4 //A8.c 24 // //A16.a 0 //A16.b 4 //A16.c 24 // //

name无宽度仅指示字符的地址 我猜8个字节为一个储存位10个超过8字节

引用 14 楼 github_27756899 的回复:大家互助应该的，用你的结构体也行，只是考虑可能数据不好赋值。 谢谢，你的写法，我搞不清楚name的宽度了  另外，问题2：但是，当我这样定义的时候 struct rec {   char  name[10];   float salary; };  printf("%d",sizeof(struct rec)) 居然是16，不是14 为什么是16呢？

大家互助应该的，用你的结构体也行，只是考虑可能数据不好赋值。

问题2可参考:http://blog.sina.com.cn/s/blog_913c070a0100zq3m.html

引用 11 楼 github_27756899 的回复:问题1就是楼主所说代码。 问题2 ... 改进版代码：  #include <stdio.h> #include <stdlib.h>  struct rec {   char  *name[100];   float salary[100]; };  int main(int argc,char* argv[]) {   struct rec *array_emp;   array_emp=(struct rec *)malloc(sizeof(struct rec));    if (NULL==array_emp)   {     printf("Can not malloc!\n");     return 1;   }   //测试数据如下   array_emp->name[0]="张三";	//记录1   array_emp->salary[0]=3000;   array_emp->name[1]="李四";	//记录2   array_emp->salary[1]=5000;   printf("记录1：\n%s收入为%f\n记录2：\n%s收入为%f\n",array_emp->name[0],array_emp->salary[0],array_emp->name[1],array_emp->salary[1]); }   我有点看不懂了，你的 struct rec {    char  *name[100];    float salary[100]; }; 和我的有什么区别吗？我想表示的是一个结构体数组，等价与数据库的表 name字段长度char(10)，总共可以保存100行 struct rec {    char  name[100][10];    float salary[100]; }; 谢谢这么晚了还帮忙解答

引用 8 楼 github_27756899 的回复:你用以下代码测试一下是几个字节  printf("字节数为%d",sizeof(struct rec));   一条记录应该是14字节(姓名是10字节+收入是4字节) 100条记入为1400字节  确实是1400 如果是这样定义呢 struct rec {   char  name[10];   float salary; };  问题1：如果想要100个元素，就要这样了？ array_emp=(struct rec *)malloc(100*sizeof(struct rec));   问题2：但是，当我这样定义的时候 struct rec {   char  name[10];   float salary; };  printf("%d",sizeof(struct rec)) 居然是16，不是14

原帖：（即赵大神）  char name[10]; float salary;  现贴：   char  name[100][10];  float salary[100];

引用 6 楼 github_27756899 的回复:用sizeof(struct rec)；就行了 可是赵4大大神是这样写的 array_emp=(struct rec *)malloc(100*sizeof(struct rec));  看这个帖子赵大神的写法 http://bbs.csdn.net/topics/391823730

用sizeof(struct rec)；就行了

引用 4 楼 github_27756899 的回复:1.  sizeof(struct rec) 是1400字节。 2.  100*sizeof(struct rec)是140000字节。 谢谢，那我这里到底应该申请140000字节还是1400字节呢？ 怎么会有140000字节呢？

引用 1 楼 ant2012 的回复:1. 这个涉及结构体对齐原则。具体机制，可以百度一下。name占10*00个字节，由于能被4（float的大小为4）整除，无需填充字节；salary占4*100个字节,；所以结构体总大小为1400字节 谢谢，此时的sizeof(struct rec) 是14还是1400？ 我这样写是想表示申请100条记录的内存空间，对马？，如下是申请了1400字节吗？ array_emp=(struct rec *)malloc(100*sizeof(struct rec));

2. 由于malloc出来的内存是连续的，所以要想清空一个类型的数组，直接在memset第三个参数设置为类型大小*数组元素个数就行，即程序： memset(&array_emp,0,sizeof(rec) * 100);   MSDN  void *memset( void *dest, int c, size_t count );  dest  Pointer to destination  c  Character to set  count  Number of characters


Question: 在结构体中分配堆，怎么回收？

有几个问题： 1. 函数内部动态分配空间并返回地址，参数需要时双重指针，因为malloc返回的地址是随机的。 2. 主函数的array是静态分配的，不需要free，函数退出自动收回。 #include<stdio.h> #include<stdlib.h> #include<string.h> typedef struct _Teacher { int age; char name[32]; //char* p; }Teacher; int creatArray(Teacher** buf,int num) { Teacher* p = NULL;  p = (Teacher*)malloc(num*sizeof(Teacher)); if(p == NULL) { return -1; } *buf = p;  return 0; } void main() { int i = 0; int num = 3; Teacher* Array ; if(creatArray(&Array,num) != 0) { return; } free(Array); system("pause"); }

Teacher Array[4]  ;这里定义了，直接分配到栈的空间去了。所以不能free

定义的函数里面由malloc，根本没有调用，所以不需要free。 局部变量都是在栈里面的，包括数组和变量，也不需要free。 最后如果想要调用malloc的函数，请专门写一个destroy的函数里面去free，在main函数的最后调用一下就可以了。

两个问题 Array是栈内存而不是堆内存,不用释放 而如果你有一个createArray函数申请了堆内存,你必须提供一个destroyArray来释放,两者配套使用 或者用类

#include<stdio.h> #include<stdlib.h> #include<string.h> typedef struct _Teacher { 	int age; 	char name[32]; 	//char* p; }Teacher; int creatArray(Teacher** buf,int num) { 	Teacher* p = NULL;  	p = (Teacher*)malloc(num*sizeof(Teacher)); 	*buf = p; 	if(buf == NULL) 	{ 		return -1; 	} 	return 0; } void main() { 	int i = 0; 	int num = 3; 	Teacher* Array ; 	if(creatArray(&Array,num) != 0) 	{ 		return; 	} 	free(Array); 	system("pause"); }

Teacher Array[4] ;是在栈中分配内存，main退出会自动释放 你定义了creatArray但在main中没有调用。 应该 void main() { int i = 0; int num = 3; Teacher* Array ; if(creatArray(Array,num) != 0) { return; } free(Array); system("pause"); }


Question: 一个关于指针的问题

int * func(int var){ 	int static result,*p; 	result=var+1500; 	p=&result; 	return p; }  把函数改成这样 result是局部变量，函数结束的时候，虽然你是返回了reslut的地址，但是reslut已经不存在了， 再指向他就没有意义了，可以让result改成静态的  指针.c:17:2: warning: function returns address of local variable [enabled by default]  不能用return &result不能返回局部变量的地址

为何要执着于返回局部变量的地址？

#include <stdio.h>  void fun1(int val, int *result) { 	*result = val + 1500; }   void fun2(int val, int *result) { 	*result = val - 1500; }  int main() { 	int result1, result2; 	int val = 1000;  	fun1(val, &result1); 	fprintf(stderr, "result1 = %d\n", result1);  	fun2(val, &result2); 	fprintf(stderr, "result2 = %d\n", result2); 	fprintf(stderr, "result1 = %d\n", result1); }

msvc 引用warning C4172: 返回局部变量或临时变量的地址 clang 引用warning: address of stack memory associated with local variable 'result' returned 不要忽略警告，以为过了编译就万事大吉了

返回局部变量指针的结果不确定性问题。

局部自动变量的值，只在局部可控 其地址也只在局部可用

使用数据改变断点。参考下面： #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: C语言遇到的3个问题，一起问了

int main(void) { 	int n1, n2; 	while(2 == scanf("%10d%10d", &n1, &n2)) 		printf("n1=%d,n2=%d\n", n1, n2); 	return 0; } //123 456 //n1=123,n2=456 //1234567890123 456 //n1=1234567890,n2=123

排除一切干扰（非数字、任意间隔字符、超长超大输入、……），输入两个整数。

引用#include <stdio.h> int main() {     int a,b,n,v,r,k;     char buf[80];     char *p;      k=0;     r=EOF;     while (1) {         if (EOF==r) {             fgets(buf,80,stdin);             p=buf;         }         while (1) {             r=sscanf(p,"%d%n",&v,&n);             if (1==r) {k++;break;}             if (EOF==r) break;             p++;         }         if (EOF==r) continue;         p+=n;         if (1==k) a=v;         if (2==k) {             b=v;             break;         }     }     printf("%d,%d\n",a,b);     return 0; }  这段代码是干嘛用的啊， 大哥解释一下呗

do 	{ 	  testOne = scanf("%f",&nu); 	  fflush(stdin); 	  testTwo = scanf("%f",&nj); 	  fflush(stdin); 	}while(testOne == 1 & testTwo ==1); 		  这是一个关于缓冲区 的问题，刷新输入流

引用 1 楼 adlay 的回复:1. 你用 %f 来输入 int ？      出错的时候输入流会处于一种错误的状态，只有把这种状态清除后才能继续输入。  2. 用 set 命令可以改变变量的值 3. %f 本来就是用于输入 float 的，float 和 double 大小都不一样，用 double 会得到错误的结果的，能提供警告说明编译器做得好。  3 我看错了，以为是 scanf  在输入

1. %处理不了字母, 处理不了就自然跳过了 2. set var kk=0 3. 什么warning

2楼正解！ 顶2楼的

引用 9 楼 user-7 的回复:1.循环条件改为true，每个输入后面跟一个判断，如果是字母就break； 2.%c是输入单个字符的时候使用的，而names是个数组，你这样输入只是给names[0]进行赋值了，而后面的值由于没有初始化，strlen无法找到结束符\0，当然无法正确获取该字符串长度了。你可以试试%c换成%s。另外记得申请数组的时候初始化，如char names = { 0 };char names[20]= { 0 };个数忘写了，不好意思

引用 5 楼 kog2333 的回复:[quote=引用 1 楼 adlay 的回复:] 1. 你用 %f 来输入 int ？      出错的时候输入流会处于一种错误的状态，只有把这种状态清除后才能继续输入。  2. 用 set 命令可以改变变量的值 3. %f 本来就是用于输入 float 的，float 和 double 大小都不一样，用 double 会得到错误的结果的，能提供警告说明编译器做得好。 额，第三个问题我没仔细看书。。。。  第一个问题是个什么情况，以前写c++代码的时候类似情况会给第二次输入的机会，所以我以为C也一样，但实际结果却是不给第二次出入的机会[/quote]  printf 的 "%f" 确实是对应 double 的 scanf 的 "%f" 才是对应 float   C++ 中的输入流也有错误状态的吧，这方面应该是相同的哦

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

仅供参考：#include <stdio.h> int main() {     int a,b,n,v,r,k;     char buf[80];     char *p;      k=0;     r=EOF;     while (1) {         if (EOF==r) {             fgets(buf,80,stdin);             p=buf;         }         while (1) {             r=sscanf(p,"%d%n",&v,&n);             if (1==r) {k++;break;}             if (EOF==r) break;             p++;         }         if (EOF==r) continue;         p+=n;         if (1==k) a=v;         if (2==k) {             b=v;             break;         }     }     printf("%d,%d\n",a,b);     return 0; }

引用 1 楼 adlay 的回复:1. 你用 %f 来输入 int ？      出错的时候输入流会处于一种错误的状态，只有把这种状态清除后才能继续输入。  2. 用 set 命令可以改变变量的值 3. %f 本来就是用于输入 float 的，float 和 double 大小都不一样，用 double 会得到错误的结果的，能提供警告说明编译器做得好。 额，第三个问题我没仔细看书。。。。  第一个问题是个什么情况，以前写c++代码的时候类似情况会给第二次输入的机会，所以我以为C也一样，但实际结果却是不给第二次出入的机会

引用 3 楼 adlay 的回复:[quote=引用 1 楼 adlay 的回复:] 1. 你用 %f 来输入 int ？      出错的时候输入流会处于一种错误的状态，只有把这种状态清除后才能继续输入。  2. 用 set 命令可以改变变量的值 3. %f 本来就是用于输入 float 的，float 和 double 大小都不一样，用 double 会得到错误的结果的，能提供警告说明编译器做得好。  3 我看错了，以为是 scanf  在输入[/quote] 我是用scanf()函数的返回值判断输入是否合格


Question: 神奇的 int unsigned int 大家帮看下 什么原因(十进制转二进制)

请楼主亲自打开include\limits.h文件，并逐行看其内容。

这样啊，这个思路貌似蛮难拐弯的~谢谢啦，对这个还有什么建议的吗

unsigned int m  m 永远大于等于0,for不会退出。


Question: 各位大神帮我看看这程序生什么病了。。

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

我也认为是0的问题。 第一次3%2没法整除，接着循环一次就算3%0

修改如下：  #include<stdio.h> #define N 100 int a[N]; int i, ci, sw; int x; int prime(int x, int a[], int w); int main(void) {  	a[0] = 2; 	x = 3; 	ci = 1; 	while (ci < N) { 		if (prime(x, a, sw)) { 			a[ci++] = x; 			sw++; 		} 		x++; 	} 	for (i = 0; i < N; i++) { 		printf("%d", a[i]); 		if ((i + 1) % 5) { 			printf("\t"); 		} 		else { 			printf("\n"); 		} 	} 	return 0; } int prime(int x, int a[], int w) { 	int ret = 1; 	int i; 	for (i = 0; i < w; i++) { 		if (x % a[i] == 0) { 			ret = 0; 			break; 		} 	} 	return ret; }

这个问题应该是除0问题  int a[sw] = {2};  // 初始化数组，第一个元素值为2，其后元素为0，执行sum里的if(x%a[i]==0)时 被除数为0，程序就会抛出异常

x%a[i]  a[i] 有为 0 的，产生除 0 的错误


Question: 帮分析下这个宏，谢谢

VC编译选项加/EP /P（项目、属性、配置属性、C/C++、预处理器、预处理到文件：是，预处理取消显示行号：是），重新编译，查看宏展开后对应的.i文件。gcc加-E http://bbs.csdn.net/topics/391003898 http://bbs.csdn.net/topics/390150105

随便用两个参数带入进去手动把宏展开一下，写下来就明白了。 还不明白的话，换个参数再来几次，很快就会明白的。


Question: 小弟有个动态内存free的小问题请高手指教

pstu1->name指向的是 一个字节的字符地址。你又在这个字节里面放一个字符串，肯定不行啊

“多一少一”问题占程序员常犯错误的10%以上！ 避免“多一少一”问题的方法之一是将比如<10甚至<5的数代入程序片断，搬手指头心算验证一下程序到底应该写为 x、x-1、x+1中的哪个？ <、<=、==、>、>=中的哪个？

如上，二选一：#define MAX_NAME_LENGTH 32  struct STUDENT {     char *name;     int score; } *pstu1;  int main() {     pstu1 = (struct STUDENT*)malloc(sizeof(struct STUDENT));     pstu1->name = (char*)malloc(sizeof(char) * MAX_NAME_LENGTH);     strncpy(pstu1->name, "Jimmy", MAX_NAME_LENGTH);     pstu1->score = 99;     printf("%s: %d\n", pstu1->name, pstu1->score);     free(pstu1->name);     free(pstu1);     return 0; }#define MAX_NAME_LENGTH 32  struct STUDENT {     char name[MAX_NAME_LENGTH];     int score; } *pstu1;  int main() {     pstu1 = (struct STUDENT*)malloc(sizeof(struct STUDENT));     strncpy(pstu1->name, "Jimmy", MAX_NAME_LENGTH);     pstu1->score = 99;     printf("%s: %d\n", pstu1->name, pstu1->score);     free(pstu1);     return 0; }

开辟的内存太小， 不够赋值。 所以就报错了。 开辟的内存要略大于你所写数据。

分配足够内存即可：  //pstu1->name = (char*)malloc(sizeof(char)); pstu1->name = (char*)malloc(sizeof(char) * 10);

楼主的代码：  #include<stdlib.h> #include <stdio.h> #include<string.h>  struct STUDENT { char *name; int score; }*pstu1; int main() {	 pstu1=(struct STUDENT*)malloc(sizeof(struct STUDENT)); pstu1->name=(char*)malloc(sizeof(char)); strcpy(pstu1->name,"Jimmy"); pstu1->score=99; printf("%s : %d",pstu1->name,pstu1->score); free(pstu1->name); free(pstu1);	 return 0; }  改后的代码  #include<stdlib.h> #include <stdio.h> #include<string.h>  struct STUDENT { char *name; int score; }*pstu1; int main() {	 pstu1=(struct STUDENT*)malloc(sizeof(struct STUDENT)); pstu1->name="Jimmy"; pstu1->score=99; printf("%s : %d",pstu1->name,pstu1->score); free(pstu1);	 return 0; }  楼主的问题： pstu1=(struct STUDENT*)malloc(sizeof(struct STUDENT));  //指针变量pstu1分配了内存。 pstu1->name=(char*)malloc(sizeof(char)); // //指针变量pstu1中的name成员 再 分配内存。可能此不与上步有相同内存部分 free(pstu1->name);是单独释放结构体所占内存的name成员部分。

现在计算机程序运行内存实际上为虚拟内存，你用new申请的内存为一个字节，但是你写入的不只一个字节，在linux系统中（其他系统类似），堆其实是个链表，维护的有上一个内存块的位置，下一个内存块的位置，当前块的大小等信息，你越界放入数据以后，存取的时候没有问题，但是你破坏了维护结构，释放的时候就会出问题

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

引用 6 楼 mutoyc 的回复:[quote=引用 5 楼 xian_wwq 的回复:] [quote=引用 楼主 mutoyc 的回复:] 代码如下： #include<stdlib.h> #include <stdio.h> #include<string.h>  struct STUDENT { 	char *name; 	int score; }*pstu1; int main() {	 	pstu1=(struct STUDENT*)malloc(sizeof(struct STUDENT)); 	pstu1->name=(char*)malloc(sizeof(char));   //分配的空间不够 	strcpy(pstu1->name,"Jimmy"); 	pstu1->score=99; 	printf("%s : %d",pstu1->name,pstu1->score); 	free(pstu1->name); 	free(pstu1);	 	return 0; } 调试中free(pstu1->name);这句总是报错说“堆破坏”，求大神解答 可以把char* 换成定长的char数组[/quote] 请问换成char数组以后，数组内的“Jimmy”字符串储存在那块内存中？是堆中还是常量储存区中？[/quote] 如果是局部的数组,就是栈里面，否则就是堆立面。

引用 5 楼 xian_wwq 的回复:[quote=引用 楼主 mutoyc 的回复:] 代码如下： #include<stdlib.h> #include <stdio.h> #include<string.h>  struct STUDENT { 	char *name; 	int score; }*pstu1; int main() {	 	pstu1=(struct STUDENT*)malloc(sizeof(struct STUDENT)); 	pstu1->name=(char*)malloc(sizeof(char));   //分配的空间不够 	strcpy(pstu1->name,"Jimmy"); 	pstu1->score=99; 	printf("%s : %d",pstu1->name,pstu1->score); 	free(pstu1->name); 	free(pstu1);	 	return 0; } 调试中free(pstu1->name);这句总是报错说“堆破坏”，求大神解答 可以把char* 换成定长的char数组[/quote] 请问换成char数组以后，数组内的“Jimmy”字符串储存在那块内存中？是堆中还是常量储存区中？

引用 楼主 mutoyc 的回复:代码如下： #include<stdlib.h> #include <stdio.h> #include<string.h>  struct STUDENT { 	char *name; 	int score; }*pstu1; int main() {	 	pstu1=(struct STUDENT*)malloc(sizeof(struct STUDENT)); 	pstu1->name=(char*)malloc(sizeof(char));   //分配的空间不够 	strcpy(pstu1->name,"Jimmy"); 	pstu1->score=99; 	printf("%s : %d",pstu1->name,pstu1->score); 	free(pstu1->name); 	free(pstu1);	 	return 0; } 调试中free(pstu1->name);这句总是报错说“堆破坏”，求大神解答 可以把char* 换成定长的char数组

malloc的时候尽量申请的大小大于要写入的长度

引用 1 楼 adlay 的回复:你只分配了一个字节 sizeof(char), 却往里面写入了 "Jimmy" 这么长一串，当然破坏了 就是说内存越界了是吗？


Question: 求懂pascal的帮忙转换下代码成C

声明一个记录（结构体），然后定义一个结构体数组并初始化


Question: WIN32编程关于消息循环的一个问题

引用 2楼user-4 的回复:对话框的回调过程 DialogProc 和窗口的回调过程 WindowProc 是不一样的，对话框的内部有真正的窗口回调过程，这里面再调用对话框的回调过程。  微软的 MSDN 里面明确的说明了，在 DialogProc 中是不能调用 DefWindowProc 的，你非要去调用！ 为什么会卡死只有微软能解释了，估计是这样破坏了鼠标点击这类消息的流动方向，让对话框内部的 WindowProc 没有机会处理消息，也就没法做出响应。  https://msdn.microsoft.com/en-us/library/windows/desktop/ms645469(v=vs.85).aspx  Remarks  You should use the dialog box procedure only if you use the dialog box class for the dialog box. This is the default class and is used when no explicit class is specified in the dialog box template. Although the dialog box procedure is similar to a window procedure, it must not call the DefWindowProc function to process unwanted messages. Unwanted messages are processed internally by the dialog box window procedure.谢谢！

引用 1楼dustpg 的回复:那行str = (char*)malloc(nMaxCount*sizeof(char));也是屌  MessageBox呼出后父窗口肯定会卡住啊你没明白，不是说模态窗口。

查MSDN是Windows程序员必须掌握的技能之一。 http://bbs.csdn.net/topics/390374955

引用 2楼user-4 的回复:对话框的回调过程 DialogProc 和窗口的回调过程 WindowProc 是不一样的，对话框的内部有真正的窗口回调过程，这里面再调用对话框的回调过程。  微软的 MSDN 里面明确的说明了，在 DialogProc 中是不能调用 DefWindowProc 的，你非要去调用！ 为什么会卡死只有微软能解释了，估计是这样破坏了鼠标点击这类消息的流动方向，让对话框内部的 WindowProc 没有机会处理消息，也就没法做出响应。  https://msdn.microsoft.com/en-us/library/windows/desktop/ms645469(v=vs.85).aspx  Remarks  You should use the dialog box procedure only if you use the dialog box class for the dialog box. This is the default class and is used when no explicit class is specified in the dialog box template. Although the dialog box procedure is similar to a window procedure, it must not call the DefWindowProc function to process unwanted messages. Unwanted messages are processed internally by the dialog box window procedure.再次感谢！回去把贴结了

引用 2 楼 adlay 的回复:对话框的回调过程 DialogProc 和窗口的回调过程 WindowProc 是不一样的，对话框的内部有真正的窗口回调过程，这里面再调用对话框的回调过程。  微软的 MSDN 里面明确的说明了，在 DialogProc 中是不能调用 DefWindowProc 的，你非要去调用！ 为什么会卡死只有微软能解释了，估计是这样破坏了鼠标点击这类消息的流动方向，让对话框内部的 WindowProc 没有机会处理消息，也就没法做出响应。  https://msdn.microsoft.com/en-us/library/windows/desktop/ms645469(v=vs.85).aspx  Remarks  You should use the dialog box procedure only if you use the dialog box class for the dialog box. This is the default class and is used when no explicit class is specified in the dialog box template. Although the dialog box procedure is similar to a window procedure, it must not call the DefWindowProc function to process unwanted messages. Unwanted messages are processed internally by the dialog box window procedure. +1 学习了，以前遇到过同样的问题。没有想到看msdn

引用 1楼dustpg 的回复:那行str = (char*)malloc(nMaxCount*sizeof(char));也是屌  MessageBox呼出后父窗口肯定会卡住啊妈的，你为什么不去看看二楼的回复，看懂问题了吗？

引用 9楼dustpg 的回复:[quote=引用 5 楼 dianziyanh 的回复:] [quote=引用 1楼dustpg 的回复:]那行str = (char*)malloc(nMaxCount*sizeof(char));也是屌  MessageBox呼出后父窗口肯定会卡住啊妈的，你为什么不去看看二楼的回复，看懂问题了吗？[/quote]  问题我看错了, 这是我的锅. 我主要是指出malloc那行的毛病, 娘的, 出口成脏吃多了，我也要骂人了[/quote]你不回也罢，玩溜溜球去吧

引用 9楼dustpg 的回复:[quote=引用 5 楼 dianziyanh 的回复:] [quote=引用 1楼dustpg 的回复:]那行str = (char*)malloc(nMaxCount*sizeof(char));也是屌  MessageBox呼出后父窗口肯定会卡住啊妈的，你为什么不去看看二楼的回复，看懂问题了吗？[/quote]  问题我看错了, 这是我的锅. 我主要是指出malloc那行的毛病, 娘的, 出口成脏吃多了，我也要骂人了[/quote]你先把那行有什么问题说出来，再说其他的，可以吗？

引用 5 楼 dianziyanh 的回复:[quote=引用 1楼dustpg 的回复:]那行str = (char*)malloc(nMaxCount*sizeof(char));也是屌  MessageBox呼出后父窗口肯定会卡住啊妈的，你为什么不去看看二楼的回复，看懂问题了吗？[/quote]  问题我看错了, 这是我的锅. 我主要是指出malloc那行的毛病, 娘的, 出口成脏吃多了，我也要骂人了