Question: 【求助】编程找反例：q=p+2^n*(2^m-1)是否成立？

用过筛法可以在线性时间求解，但我算了下4294967291以内无反例

引用 5 楼 lcbex 的回复:回4楼： 可能是我表述不清楚，你对问题3的理解有误。  /* 问题3：q是否一定可以表示成p+2^n*(2^m-1)的形式？ 答案：不确定，在10000000以内没有反例。 */ 正确的理解是： q=p+(2^n)*((2^m)-1) =p+2^(n+m)-2^n =p+2^a-2^b (a>b≥1).  —————————————————————————————————— 问题3的集合描述： /* 集合A={ p+2^a-2^b | p为正的奇素数，a>b≥1。} 集合B={ 2k+3 | k为正整数} 则A=B。 */  另外，对于问题3，我已经验证到2亿，未出现反例。 不是我理解有误，是问题表述不准确 q=p+(2^n)*((2^m)-1) 和 q=p+2^n*((2^m)-1) 不是等价的概念 当然也是因为这里不能编辑公式造成的！ 命题换了，重新来 q - p = t t = 2^n   *   (2^m    -     1) 测定t是不是等号右边这样的 对t每次向右移1位，测定是不是2^m    -     1 x = 2^m -1, 测定公式：x&(x + 1) 其他和原来一样

/*    定义：q是任意一个大于3的奇数，p为正的奇素数，k、m、n为正整数。     问题1：q是否一定可以表示成p+2^k的形式？    答案：否，在10000000以内共有421862个反例，最小的反例为q=127。    备注：有人证明p+2^k形式的数在整数中具有正密度。     问题2：q是否一定可以表示成p+2^n*3^(m-1)的形式？    答案：否，在10000000以内共有18056个反例，最小的反例为q=1719。     问题3：q是否一定可以表示成p+2^n*(2^m-1)的形式？    答案：不确定，在10000000以内没有反例。     求助：将问题3验证到10亿甚至100亿，看是否存在反例。   */  /*    q=p+2^n*(2^m-1)     => q - p = 2^n*(2^m-1)     令x = n*(2^m -1)    	=> q - p = 2^x; 其中x一定是一个正整数 	由2^x > 2 => q > p + 2 	判断一个整数y是不是2^x公式：y&(y-1) == 0是否成立  	当m = 1时，x = n,很显然简化成了问题1 	当m > 1时，才是问题3讨论的意义    ULL=8B=64bits 能表示的最大值>10^19    很明显大于100亿  */  #include <stdio.h> #include <stdlib.h>  #include <malloc.h>  #include <math.h>  #define RIGHT_BOUNDARY 1000000ULL//这里适当放大，否则运行时间很长 #define BITS (sizeof(unsigned long long) * 8)   int is_prime(unsigned long long num) { 	unsigned long i; 	for(i = 2; i < sqrt(num); i++) { 		if(num % i == 0) 			return 0; 	} 	return 1; }  int is_comp(unsigned long long power) { 	int i; 	for(i = 1; i < BITS; ++i) { 		if(power % ((0x2ULL << i) - 1) == 0)//0x2->0x1就蜕变成问题1 			return 1; 	} 	return 0; }  int main(int argc, char *argv[]) { 	unsigned long long *prime_tbl; 	unsigned long long i, tst, tmp; 	unsigned long nr; 	unsigned long top;  	prime_tbl = (unsigned long long *)malloc(sizeof(unsigned long long) * RIGHT_BOUNDARY / 2); 	if(prime_tbl == NULL) { 		perror("fail:"); 		exit(0); 	}  	nr = 0; 	top = 1; 	prime_tbl[0] = 2;  	for(tst = 3; tst < RIGHT_BOUNDARY; tst += 2) { 		for(i = 0; i < top; ++i) { 			tmp = tst - prime_tbl[i]; 			if(tmp > 2 && !(tmp & (tmp - 1)) && is_comp(tmp)) { 				++nr; 				printf("%lld -  %lld = %lld\n", tst, prime_tbl[i], tmp); 			} 		} 		if(is_prime(tst)) { 			prime_tbl[top++] = tst; 		} 	}  	printf("sum : %ld\n", nr); }   这是最直接的思想：边检测，边添加素数表。运算量稍大，大概O(n2),当检测区间很大时，有点不可行。有待优化，仅供参考！

引用 1 楼 zhao4zhong1 的回复:仅供参考：#include <iostream> #include <string> using namespace std; inline int compare(string str1,string str2) {//相等返回0，大于返回1，小于返回-1          if (str1.size()>str2.size()) return 1; //长度长的整数大于长度小的整数     else if (str1.size()<str2.size()) return -1;     else                              return str1.compare(str2); //若长度相等，则头到尾按位比较 } string SUB_INT(string str1,string str2); string ADD_INT(string str1,string str2) {//高精度加法     int sign=1; //sign 为符号位     string str;     if (str1[0]=='-') {         if (str2[0]=='-') {             sign=-1;             str=ADD_INT(str1.erase(0,1),str2.erase(0,1));         } else {             str=SUB_INT(str2,str1.erase(0,1));         }     } else {         if (str2[0]=='-') {             str=SUB_INT(str1,str2.erase(0,1));         } else { //把两个整数对齐，短整数前面加0补齐             string::size_type L1,L2;             int i;             L1=str1.size();             L2=str2.size();             if (L1<L2) {                 for (i=1;i<=L2-L1;i++) str1="0"+str1;             } else {                 for (i=1;i<=L1-L2;i++) str2="0"+str2;             }             int int1=0,int2=0; //int2 记录进位             for (i=str1.size()-1;i>=0;i--) {                 int1=(int(str1[i])-'0'+int(str2[i])-'0'+int2)%10;                 int2=(int(str1[i])-'0'+int(str2[i])-'0'+int2)/10;                 str=char(int1+'0')+str;             }             if (int2!=0) str=char(int2+'0')+str;         }     }     //运算后处理符号位     if ((sign==-1)&&(str[0]!='0')) str="-"+str;     return str; } string SUB_INT(string str1,string str2) {//高精度减法     int sign=1; //sign 为符号位     string str;     int i,j;     if (str2[0]=='-') {         str=ADD_INT(str1,str2.erase(0,1));     } else {         int res=compare(str1,str2);         if (res==0) return "0";         if (res<0) {             sign=-1;             string temp =str1;             str1=str2;             str2=temp;         }         string::size_type tempint;         tempint=str1.size()-str2.size();         for (i=str2.size()-1;i>=0;i--) {             if (str1[i+tempint]<str2[i]) {                 j=1;                 while (1) {//zhao4zhong1添加                     if (str1[i+tempint-j]=='0') {                         str1[i+tempint-j]='9';                         j++;                     } else {                         str1[i+tempint-j]=char(int(str1[i+tempint-j])-1);                         break;                     }                 }                 str=char(str1[i+tempint]-str2[i]+':')+str;             } else {                 str=char(str1[i+tempint]-str2[i]+'0')+str;             }         }         for (i=tempint-1;i>=0;i--) str=str1[i]+str;     }     //去除结果中多余的前导0     str.erase(0,str.find_first_not_of('0'));     if (str.empty()) str="0";     if ((sign==-1) && (str[0]!='0')) str ="-"+str;     return str; } string MUL_INT(string str1,string str2) {//高精度乘法     int sign=1; //sign 为符号位     string str;     if (str1[0]=='-') {         sign*=-1;         str1 =str1.erase(0,1);     }     if (str2[0]=='-') {         sign*=-1;         str2 =str2.erase(0,1);     }     int i,j;     string::size_type L1,L2;     L1=str1.size();     L2=str2.size();     for (i=L2-1;i>=0;i--) { //模拟手工乘法竖式         string tempstr;         int int1=0,int2=0,int3=int(str2[i])-'0';         if (int3!=0) {             for (j=1;j<=(int)(L2-1-i);j++) tempstr="0"+tempstr;             for (j=L1-1;j>=0;j--) {                 int1=(int3*(int(str1[j])-'0')+int2)%10;                 int2=(int3*(int(str1[j])-'0')+int2)/10;                 tempstr=char(int1+'0')+tempstr;             }             if (int2!=0) tempstr=char(int2+'0')+tempstr;         }         str=ADD_INT(str,tempstr);     }     //去除结果中的前导0     str.erase(0,str.find_first_not_of('0'));     if (str.empty()) str="0";     if ((sign==-1) && (str[0]!='0')) str="-"+str;     return str; } string DIVIDE_INT(string str1,string str2,int flag) {//高精度除法。flag==1时,返回商; flag==0时,返回余数     string quotient,residue; //定义商和余数     int sign1=1,sign2=1;     if (str2 == "0") {  //判断除数是否为0         quotient= "ERROR!";         residue = "ERROR!";         if (flag==1) return quotient;         else         return residue ;     }     if (str1=="0") { //判断被除数是否为0         quotient="0";         residue ="0";     }     if (str1[0]=='-') {         str1   = str1.erase(0,1);         sign1 *= -1;         sign2  = -1;     }     if (str2[0]=='-') {         str2   = str2.erase(0,1);         sign1 *= -1;     }     int res=compare(str1,str2);     if (res<0) {         quotient="0";         residue =str1;     } else if (res == 0) {         quotient="1";         residue ="0";     } else {         string::size_type L1,L2;         L1=str1.size();         L2=str2.size();         string tempstr;         tempstr.append(str1,0,L2-1);         for (int i=L2-1;i<L1;i++) { //模拟手工除法竖式             tempstr=tempstr+str1[i];             tempstr.erase(0,tempstr.find_first_not_of('0'));//zhao4zhong1添加             if (tempstr.empty()) tempstr="0";//zhao4zhong1添加             for (char ch='9';ch>='0';ch--) { //试商                 string str;                 str=str+ch;                 if (compare(MUL_INT(str2,str),tempstr)<=0) {                     quotient=quotient+ch;                     tempstr =SUB_INT(tempstr,MUL_INT(str2,str));                     break;                 }             }         }         residue=tempstr;     }     //去除结果中的前导0     quotient.erase(0,quotient.find_first_not_of('0'));     if (quotient.empty()) quotient="0";     if ((sign1==-1)&&(quotient[0]!='0')) quotient="-"+quotient;     if ((sign2==-1)&&(residue [0]!='0')) residue ="-"+residue ;     if (flag==1) return quotient;     else         return residue ; } string DIV_INT(string str1,string str2) {//高精度除法,返回商     return DIVIDE_INT(str1,str2,1); } string MOD_INT(string str1,string str2) {//高精度除法,返回余数     return DIVIDE_INT(str1,str2,0); } int main() {     char ch;     string s1,s2,res;      while (cin>>s1>>ch>>s2) {         switch (ch) {             case '+':res=ADD_INT(s1,s2);break;             case '-':res=SUB_INT(s1,s2);break;             case '*':res=MUL_INT(s1,s2);break;             case '/':res=DIV_INT(s1,s2);break;             case '%':res=MOD_INT(s1,s2);break;             default :                   break;         }         cout<<res<<endl;     }     return(0); }   减法有问题：

一楼犀利，好身手


Question: 为什么pow函数里面放不能放变量，谢谢！

gcc pow.c -lm

虽然结果不对, 但是还是能编译的啊  int改成double试试


Question: C语言链表问题，求大神解答！标题长长长长长长长长长长长长长长长长长长一点！！

引用 4 楼 Falleyes 的回复:#include <stdio.h> #include <stdlib.h>  struct student { 	int score; 	struct student *next; }Node;  struct student *creat(int n) { 	struct student *p1, *p2; 	int i; 	p1 = (struct student*)malloc(sizeof(struct student)); 	struct student *head; 	head = p1; 	for (i = 0; i<n; i++) 	{ 		p1->score = i + 1; 		p2 = (struct student*)malloc(sizeof(struct student)); 		p1->next = p2; 		p1 = p2; 	} 	p1->next = NULL; 	return head; };  void print(struct student *head, int n) { 	struct student *p1; 	p1 = head; 	while (p1->next->next != NULL) 	{ 		printf("%d ", p1->score); 		p1 = p1->next; 	} 	printf("%d\n", p1->score); }  int main() { 	int N; 	struct student *head; 	scanf("%d", &N); 	head = creat(N); 	print(head, N); 	return 0; }是的是的，谢谢啦！！！

N没有初始化。。。。

引用 1 楼 hant1991 的回复:struct student *creat(int n)返回student指针，但是你的head是int型。#include <stdio.h> #include <stdlib.h>  struct student {     int score;     struct student *next; }Node;  struct student *creat(int n) {     struct student *p1,*p2;     int i;     p1=(struct student*)malloc(sizeof(struct student));     struct student *head;     head=p1;     for(i=0;i<n;i++)     {         p1->score=i+1;         p2=(struct student*)malloc(sizeof(struct student));         p1->next=p2;         p1=p2;     }     p1->next=NULL;     return head; };  void print(struct student *head,int n) {     struct student *p1;     p1=head;     while (p1->next->next!=NULL)     {         printf("%d ",p1->score);         p1=p1->next;     }     printf("%d\n",p1->score); }  int main() {     int N;     struct student *head;     head=struct student *creat(N);     scanf("%d",&N);     struct student * creat(N);     print(head,N);     return 0; } ||=== Build: Debug in 约瑟夫问题 (compiler: GNU GCC Compiler) ===| D:\codeblocks --project\约瑟夫问题\main.c||In function 'main':| D:\codeblocks --project\约瑟夫问题\main.c|44|error: expected expression before 'struct'| D:\codeblocks --project\约瑟夫问题\main.c|46|warning: parameter names (without types) in function declaration [enabled by default]| ||=== Build failed: 1 error(s), 1 warning(s) (0 minute(s), 0 second(s)) ===|   改了之后只有1 error 1 warning了，但是还是有个error啊？怎么办啊


Question: Linux下编译.so报找不到main函数

搜“跟我一起写makefile”？


Question: struct {。。。}__PACKED__中的__PACKED__作用是什么？

VS IDE中，在不明白的符号上点鼠标右键，选转到定义。

__PACKED__应该是把所有变量在内存中的存储变得连续起来，不会出现因为自动对齐造成某些字节或者位成为空的

猜想__PACKED__应该是不采用默认对齐

看编译器： 1.如果是编译器的属性，那么就是告诉编译器的参数 2.是个结构体变量。前后下划线说明是“内部”变量，防止和用户定义变量ID冲突。 个人觉得是第2种情况。

楼上的代码可以编译通过的，这个 可以验证。（在linux下）

struct _RTP_FIXED_HEADER {     /**//* byte 0 */     unsigned char csrc_len:4;        /**//* expect 0 */     unsigned char extension:1;        /**//* expect 1, see RTP_OP below */     unsigned char padding:1;        /**//* expect 0 */     unsigned char version:2;        /**//* expect 2 */     /**//* byte 1 */     unsigned char payload:7;        /**//* RTP_PAYLOAD_RTSP */     unsigned char marker:1;        /**//* expect 1 */     /**//* bytes 2, 3 */     unsigned short seq_no;                 /**//* bytes 4-7 */     unsigned  long timestamp;             /**//* bytes 8-11 */     unsigned long ssrc;            /**//* stream number is used here. */ } __PACKED__;  typedef struct _RTP_FIXED_HEADER RTP_FIXED_HEADER;  struct _NALU_HEADER {     //byte 0 	unsigned char TYPE:5;     	unsigned char NRI:2; 	unsigned char F:1;     	 }__PACKED__; /**//* 1 BYTES */  typedef struct _NALU_HEADER NALU_HEADER;

定义了一个结构体叫_RTP_FIXED_HEADER，声明了一个结构体变量叫__PACKED__


Question: 关于位运算

引用 12 楼 sholber 的回复:[quote=引用 10 楼 my_live_123 的回复:] 这是C语言的一个特性，C89时候没有布尔类型，C认为非零即真，0即假。因此算术表达式就可以和逻辑表达式整合在一起了。 if(GPFDAT&(1<<4)) 等价于 if(GPFDAT&(1<<4) ！= 0)  1左移4位和GPFDAT与，则获取GPFDAT的第4位（从1数）上的bit，结果是0或0x8  为0和不为0，与真假无关，C99之前，C里没有这个概念。很多教材为了通俗起见，胡乱引入这个术语。 另外，那两个表达式并不等价。如果执行起来，则， 第一个表达式：如果GPFDAT&(1<<4)的结果不为0，执行语句1，否则执行语句2； 第二个表达式：如果GPFDAT&(1<<4) != 0的结果不为0，执行语句1，否则执行语句2。 显然，第二个表达式虽然好看，但实际上加重了编译器的负担。个人管见。[/quote]  好吧，你总是把我拉进编译的深渊！ 从编译角度讲，编译过程是不同的，前者没有经过equality-expression ！= relational-expression，后者需要这个操作。 殊途同归，到达expression时，第一种情况，它要么为0要么不为0，如果不为0认为逻辑真，为0则逻辑假；第二种情况，在中间代码过程中，编译器可以在equality-expression ！= relational-expression如果逻辑真选择对往上走的值是1，而不是像第1种情传递GPFDAT&(1<<4)的结果值。无论到达exp后的值是1还是其他非零值， 到达exp后，生成的条件调转指令都是以判断0执行的。因此，表现形式不同，结果一致，从这一点上而论，是等价的！你提出的“不等价”只是以形式而论，不符合“等价”含义——比如一个直线方程有多种表达方式，但是都是等价的！ 你觉得这样解释咋样？ 个人觉得对初学者讨论编译问题，对于他们益处不大！  你说的“为0和不为0，与真假无关，C99之前，C里没有这个概念。”，我想瞅瞅你的依据

自动抓换成bool 类型 false 或 true

引用 16 楼 my_live_123 的回复:[quote=引用 12 楼 sholber 的回复:] [quote=引用 10 楼 my_live_123 的回复:] 这是C语言的一个特性，C89时候没有布尔类型，C认为非零即真，0即假。因此算术表达式就可以和逻辑表达式整合在一起了。 if(GPFDAT&(1<<4)) 等价于 if(GPFDAT&(1<<4) ！= 0)  1左移4位和GPFDAT与，则获取GPFDAT的第4位（从1数）上的bit，结果是0或0x8  为0和不为0，与真假无关，C99之前，C里没有这个概念。很多教材为了通俗起见，胡乱引入这个术语。 另外，那两个表达式并不等价。如果执行起来，则， 第一个表达式：如果GPFDAT&(1<<4)的结果不为0，执行语句1，否则执行语句2； 第二个表达式：如果GPFDAT&(1<<4) != 0的结果不为0，执行语句1，否则执行语句2。 显然，第二个表达式虽然好看，但实际上加重了编译器的负担。个人管见。[/quote]  好吧，你总是把我拉进编译的深渊！ 从编译角度讲，编译过程是不同的，前者没有经过equality-expression ！= relational-expression，后者需要这个操作。 殊途同归，到达expression时，第一种情况，它要么为0要么不为0，如果不为0认为逻辑真，为0则逻辑假；第二种情况，在中间代码过程中，编译器可以在equality-expression ！= relational-expression如果逻辑真选择对往上走的值是1，而不是像第1种情传递GPFDAT&(1<<4)的结果值。无论到达exp后的值是1还是其他非零值， 到达exp后，生成的条件调转指令都是以判断0执行的。因此，表现形式不同，结果一致，从这一点上而论，是等价的！你提出的“不等价”只是以形式而论，不符合“等价”含义——比如一个直线方程有多种表达方式，但是都是等价的！ 你觉得这样解释咋样？ 个人觉得对初学者讨论编译问题，对于他们益处不大！  你说的“为0和不为0，与真假无关，C99之前，C里没有这个概念。”，我想瞅瞅你的依据 [/quote] 我认同你的这个解释。 另外，你问的依据嘛，我的依据是标准里的措辞，标准不说为真是怎样，为假时怎样，只是说同0比较是否相等。举例来说，对于if语句： the first substatement is executed if the expression compares unequal to 0 它只是说表达式的值在比较时等于0或者不等于0。 其实最好的证据就是C11才正式地引入了_Bool 和头文件<stdbool.h>

需要的改正下 ，if(GPFDAT&(1<<4)),  是表示GPFDAT寄存器地址里的数据的第五位是否是 1， 而不是第四位， #define GPFDAT  (*((unsigned long *)0x7F0080A4))   if(GPFDAT&(1<<4)),  {         如果GPFDAT的第五位是一，则进入if  （& 是按位与的意思）  ; } 1<<4 ==    0x0000 0000 0000 0000 0000 0000 0001 0000

引用 4 楼 wysdaomei 的回复:[quote=引用 2 楼 user-10 的回复:] 表达式被隐式转换成bool类型了   谢谢，这个表达式是不是就只对第4位进行了判断！[/quote]  居然还谢谢。没证据表明被隐式转换为bool类型。自己想像的吧。

引用 10 楼 my_live_123 的回复:这是C语言的一个特性，C89时候没有布尔类型，C认为非零即真，0即假。因此算术表达式就可以和逻辑表达式整合在一起了。 if(GPFDAT&(1<<4)) 等价于 if(GPFDAT&(1<<4) ！= 0)  1左移4位和GPFDAT与，则获取GPFDAT的第4位（从1数）上的bit，结果是0或0x8  为0和不为0，与真假无关，C99之前，C里没有这个概念。很多教材为了通俗起见，胡乱引入这个术语。 另外，那两个表达式并不等价。如果执行起来，则， 第一个表达式：如果GPFDAT&(1<<4)的结果不为0，执行语句1，否则执行语句2； 第二个表达式：如果GPFDAT&(1<<4) != 0的结果不为0，执行语句1，否则执行语句2。 显然，第二个表达式虽然好看，但实际上加重了编译器的负担。个人管见。

谢谢，之前想的有点混乱

理解和讨论之前请先学会如何观察！  计算机组成原理→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对应的汇编并单步执行观察相应内存和寄存器变化。）

如5楼说说 GPFDAT的第四位没变 --------------------------- 你想想 a= 10;  if(a - 8)  这样a变了吗?

引用 3 楼 wysdaomei 的回复:[quote=引用 1 楼 jiht594 的回复:] GPFDAT&(1<<4) 这叫表达式, 表达式结果是0为假, 非0真  3*2-6是假, 3*2-1是真  这个我知道，只是不明白，对于GPFDAT&（1《4）这个表达式来说，现在只明白GPFDAT的第4位变成了1，按照原来的理解，只要不是0都是真的话，那这边显然为真了，如果是这样的话与GPFDAT&（1《5）比较，这2个不就没区别了么。而实际是对第4位和第5位分别做了判断。[/quote] hi  如果GPFDAT是 0110 1010,  1《4 是0000 1000 那么GPFDAT&（1《4）是非0. (0110 1010 & 0000 1000 = 0000 1000 )  如果GPFDAT是 0111 0111,  1《4 是0000 1000 那么GPFDAT&（1《4）就是0啊 (0110 1010 & 0000 1000 = 0000 0000 )  这就可以判断第四位是不是1了啊. ----------------------------------------------------------------------- 后面对GPFDAT&（1《5）对描述看不明白

引用 3 楼 wysdaomei 的回复:这个我知道，只是不明白，对于GPFDAT&（1《4）这个表达式来说，现在只明白GPFDAT的第4位变成了1，按照原来的理解，只要不是0都是真的话，那这边显然为真了，如果是这样的话与GPFDAT&（1《5）比较，这2个不就没区别了么。而实际是对第4位和第5位分别做了判断。  bit4没有变成1，只是判断bit4是不是1. if(0x51 &(1 <<4))  0101 0001 & 0001 0000 结果是1， if成立

引用 2 楼 user-10 的回复:表达式被隐式转换成bool类型了   谢谢，这个表达式是不是就只对第4位进行了判断！

引用 1 楼 jiht594 的回复:GPFDAT&(1<<4) 这叫表达式, 表达式结果是0为假, 非0真  3*2-6是假, 3*2-1是真  这个我知道，只是不明白，对于GPFDAT&（1《4）这个表达式来说，现在只明白GPFDAT的第4位变成了1，按照原来的理解，只要不是0都是真的话，那这边显然为真了，如果是这样的话与GPFDAT&（1《5）比较，这2个不就没区别了么。而实际是对第4位和第5位分别做了判断。

表达式被隐式转换成bool类型了


Question: c语言问题

d可以理解为一个长度为4的char类型数组，"abcd"则是存储在静态常量区，其实加上结尾的'\0'一个占用了五个字符，但是d只有四个字节的存储空间，所以就没有存储'\0'，你调用strlen函数，会一直在d后面的栈存储空间上寻找'\0'直至找到，可能你d后面的内存在第7个恰好是一个'\0'，所以得到的长度为7.因此操作C风格字符串的时候一定要小心。

引用 7 楼 u012436960 的回复:四个数组在内存中的分布为： abcd abc\0 ab\0? a\0?? 其中?表示任意字符。 因为数组是被压栈进入内存的，所以先定义的数组在后，后定义的在前，因为最后一个字符串实际包含5个字符(包括最后的\0),而定义的数组容量是4，所以最后的\0会被丢弃。strlen是判断以\0结尾的字符串的长度的，它认为d="abcdabc",所以d的长度为7。错误太多了  动不动初始化啊 初始化之后没指定的元素会初始化为 0  根本不存在你所谓的 ? 压栈 和 变量在内存的顺序没有一分钱关系 别张冠李戴 变量在内存中的顺序 编译器不一定按照声明的顺序一一分配  可以是 abcd 可以是cadb 一样是压栈 按照abcd 和 按照 cadb 结果是不一样的  没什么意义

引用 2 楼 fly_dragon_fly 的回复:你的编译器有问题，最后一个d明显越界没有提示吗，换编译器 d 没有越界 这样初始化是 完全没问题的  需要注意的是 初始化得到的d 不是字符串 不能用字符串函数操作

编译器没有提示

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

char d[4] = "abcd"; 这个已经越界了，编译器没提示么？

应该没有越界，只是数组d只有4个字符空间，所以d只包含a、b、c、d四个字符，没有包含字符串结束符\0，而strlen计算字符串长度是以\0为结束符，所以strlen(d)会输出一个大于4的值，输出多少要看strlen计算d的长度时遍历到\0为止。

char d[4] = "abcd";

char d[4] = "abcd";   下标越界了， 字符串的结尾后面自动会加‘\0’， 会用掉一个字符的空间， 这里你有了4个字符， 没空间在加'\0'， strlen（）函数遇到'\0'才认为字符串结束。  程序中应尽量避免这种情况出现。

你的编译器有问题，最后一个d明显越界没有提示吗，换编译器

数组越界了吧


Question: 关于FIFO的设置深度的困惑

引用 1 楼 my_live_123 的回复:FIFO队列的链式实现，不存在覆盖问题 LZ的意思是限制FIFO元素个数？那你设置一个计数器即可，每次入队时对计数器加1，出队时对计数器减1，测试计数器是否超过限制（队空或者队满）  计数很好，满足了，感谢你的支持。

你要实现的是一个 环形 队列吧


Question: 怎么获取某条直线中间的几个点的坐标.

赵老师  您太牛了！！！

引用 8 楼 zhao4zhong1 的回复:(X0,Y0)-(X1,Y1),t=0.2,0.4,0.6,0.8 Xt=X0*t+X1*(1-t) Yt=Y0*t+Y1*(1-t) 正解！

先把二元一次多项式列出来，比较笨的办法就是 for{for()}这样搞就行了。

引用 4 楼 hyz_cs 的回复:[quote=引用 2 楼 q3733353520 的回复:]  //l^2 =   (y2-y1)^2 +  (x2-x1)^2 算出l（两点间的距离） //然后根据中间点数等分 //最后依次求出点的坐标   是这个办法,但是我现在距离求出来了,中间点等分也简单,但是怎么依次求坐标?[/quote]  你没学过几何吗

点的线性插值 如果已知 点A，B， 中间点的公式为 A(1-t)+Bt 其中t为比例

x1=x0+d *cos(a) y1=y0+d*sin(a)

引用 2 楼 q3733353520 的回复: //l^2 =   (y2-y1)^2 +  (x2-x1)^2 算出l（两点间的距离） //然后根据中间点数等分 //最后依次求出点的坐标   是这个办法,但是我现在距离求出来了,中间点等分也简单,但是怎么依次求坐标?

初中时几何老师口口相授：平面之上，两点确定一线。 直线方程： 1：一般式:Ax+By+C=0(A、B不同时为0)【适用于所有直线】 k= - A/B ， b= - C/B A1/A2=B1/B2≠C1/C2←→两直线平行 A1/A2=B1/B2=C1/C2←→两直线重合 横截距a=-C/A 纵截距b=-C/B 2：点斜式:y-y0=k(x-x0) 【适用于不垂直于x轴的直线】 表示斜率为k，且过（x0,y0）的直线 3：截距式:x/a+y/b=1【适用于不过原点或不垂直于x轴、y轴的直线】 表示与x轴、y轴相交，且x轴截距为a，y轴截距为b的直线 4：斜截式:y=kx+b【适用于不垂直于x轴的直线】 表示斜率为k且y轴截距为b的直线 5：两点式:【适用于不垂直于x轴、y轴的直线】 表示过（x1,y1）和(x2,y2)的直线 (y-y1)/(y2-y1)=(x-x1)/(x2-x1) (x1≠x2，y1≠y2) 6：交点式:f1(x,y) *m+f2(x,y)=0 【适用于任何直线】 表示过直线f1(x,y)=0与直线f2(x,y)=0的交点的直线 7：点平式:f(x,y) -f(x0,y0)=0【适用于任何直线】 表示过点（x0,y0）且与直线f（x,y）=0平行的直线 8：法线式：x·cosα+ysinα-p=0【适用于不平行于坐标轴的直线】 过原点向直线做一条的垂线段，该垂线段所在直线的倾斜角为α，p是该线段的长度 9：点向式：(x-x0)/u=(y-y0)/v (u≠0,v≠0)【适用于任何直线】 表示过点(x0,y0)且方向向量为（u,v ）的直线 10：法向式：a（x-x0）+b（y-y0）=0【适用于任何直线】 表示过点（x0，y0）且与向量（a，b）垂直的直线

直线方程啊 y=kx+b


pcap_list是传出参数，不需要先分配内存，原因应该不是你说的那个。这几行代码看不出什么问题，你可以设置断点单步调试看看到底是哪行代码的问题。


Question: 一次面试题目，求解答

3.cpu的使用率一般是看最低优先级的idle任务占用cpu的时间，而cpu100%，说明idle任务一直未被调用。此时需要对当前占有处理器资源的线程，主动睡眠 taskdelay.等。主动睡眠，放弃cpu资源。

关于修改ip地址，我可以简略说一下也不知道对不对，首先你要捕获ip数据包，这个是有相应的库的叫libpcap，Windows有更强大的winpcap。捕获ip数据包后就可以对其做相应的操作了，比如修改ip地址，建议你去看看《网络开发包安全详解》

有难度，不会呀

1.分两种情况！ a.返回接口传入时的指针参数或者引用对象的地址。一般是对传进来的指针指向对象操作后原指针参数返回。如果操作失败返回NULL b.在函数分配对象，返回对象的地址。分配失败，返回NULL。  2.没看懂 3.a.root权限更改进程的优先级！如果不好使，b.系统调用setrlimit，设置进程的RLIMIT_CPU限制,个人觉得a就好使。优先级发生变化，时间片跟着调整 4.既然是非阻塞方式了，返回此标示指示资源未到位，1.轮询。sleep片刻，再试一试2.select或者poll 5.不会！ 6.指定目标文件名，自己就会找了！默认就是在当前目录搜索，你也可以指定搜索目录，设置VPATH= . <-注意这里是个点点

都不会，我是不是太菜了

一份好的笔试题应该是把面试者的真实实力筛选成不同等级的。  面试的时候多个心眼 有的面试官是在刷荣誉感，这种人日后做同事还不如换家公司。  有时候面试官会突然问一两个刁难性问题，可能是考验你的心理素质，尽量扩展性把自己会的以及思路说出来，知之为知之，不知为不知。 这种情况有的面试者严重点会恼羞成怒，八成影响分就扣光了。。

这题目确实出的不清晰，有可能出题的也是个半桶水。或者更多的想考察面试者的应变吧。  1.封装一个接口，返回一个指针，应完成哪些操作。 这题八成想考内存管理。 2.#define MAX 256，定义结构struct  stNode{ unsigned long lu，char LINE[MAX]}，对一个结构数字，快速查找到lu TOP10的结构数据。 用lu做map的key。题目又没说具体有多少数据，有多少空间可以用。 3.CPU独占时有时占用率会达到100%，如何降低CPU使用率。（与时间片有关） 想问抢占式系统还是多线程 4.非阻塞式socket经常返回EAGIAN错误，应该如何解决。 一般不用管，continue，具体看man手册 5.如何自己修改数据包的IP地址。 修改协议栈啊，或者rawsocket，总之就是根据更底层的的API写代码。 6.Makefile中如何查找当前目录下的C文件。 通配。。

好几个都是描述不清楚的 1.封装一个接口，返回一个指针，应完成哪些操作。   问得好像有固定步骤似的 2.看不懂 3.CPU独占时有时占用率会达到100%  我可以回答换一台电脑吗?  456太具体问题了, 没接触过根本不会懂. 如果你面试的是特定方向的可以理解. 要不然可以回答, "百度一下, 我才知道"

1. 返回的指针是从哪里来的，如果是动态申请内存的话，在哪里申请，就在哪里释放；或者申请内存的操作可以从外部定制 2. 题目没看懂 3. 不会 4. IO多路复用 5. 不会（IP地址是在IP层包头部中有源地址和目的地址，但不知道怎么改，从来没做过） 6. SRC := $(wildcard *.c)

谁家的面试题啊，有点难。 第一个应该涉及内存的分配与回收，和指针指向的数据结构。


Question: linux 下要做一个有几十万客户端连接的服务器？？？问一下怎么实现

搜“epoll”

用epoll没有错，达到5w的并发连接已经很强了，差不多达到一台万兆网卡的机器性能极限了。要想达到几十万的并发连接的话，只能加机器来做负载均衡了。 你可以参考haproxy和nginx的实现。 下面的是haproxy的一些介绍： http://freeloda.blog.51cto.com/2033581/1294094


Question: c sprintf字符转换十六进制问题，急！！！

GDB也有很多GUI外壳的。

引用 5 楼 zhao4zhong1 的回复:[quote=引用 4 楼 suxinpingtao51 的回复:] [quote=引用 3 楼 my_live_123 的回复:]  sprintf(szMessage+y*2, "%02x", sziMessage[y] & 0xff);//只取低8位  可以说明下，不取8位为什么会是我提的那种结果吗？[/quote] 理解和讨论之前请先学会如何观察！  计算机组成原理→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对应的汇编并单步执行观察相应内存和寄存器变化。） [/quote] 赵老师教训的是以后注意多观察！有个疑问，在Linux或Unix下大家都是用GDB调试的吗，我总是用的不习惯，感觉GDB调试好慢的赶脚，可能是习惯IDE这种的了

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

引用 3 楼 my_live_123 的回复: sprintf(szMessage+y*2, "%02x", sziMessage[y] & 0xff);//只取低8位  可以说明下，不取8位为什么会是我提的那种结果吗？

引用 1 楼 zhao4zhong1 的回复:sprintf(szMessage+y*2, "%02x", (unsigned char)sziMessage[y]); 为什么可以这样强制转呢，我看sziMessage的第二个的十进制是个 负整数，将有符号的强转成无符号的字符，这在取值范围上都不一样啊，这样转的目的是让字符被强制从低位截取8位输出？


Question: 如何判断一个int型变量是否已赋值或者已初始化

引用 14 楼 ren0065 的回复:IsBadReadPtr() IsBadWritePtr() 涨姿势了！

引用 5 楼 zhangxiangDavaid 的回复:这个没法判断，及时初始化是个好的习惯记忆中好多内存泄露也是4k 4k的泄的

IsBadReadPtr() IsBadWritePtr()

对于一个局部变量来说，给变量分配的存储空间是线程的栈，由于进进出出的人很多，变量的值通常是不确定的。

[quote=引用 10 楼 a138762698828 的回复:]   [quote=引用 6 楼 zhao4zhong1 的回复:] 其实电脑开机后物理内存的每个字节都是可读写的，从来不会因为所谓的new、delete或malloc、free而被创建、销毁。区别仅在于操作系统内存管理模块在你读写时是否能发现并是否采取相应动作而已。操作系统管理内存的粒度不是字节而是页，一页通常为4KB。  页的大小，不一定， 很多都是2k

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

定义的时候自己赋值好了 int a(1234)这样

定义的时候自己赋值好了 int a = {1234}这样

判断不了的，靠你自己判断吧

其实电脑开机后物理内存的每个字节都是可读写的，从来不会因为所谓的new、delete或malloc、free而被创建、销毁。区别仅在于操作系统内存管理模块在你读写时是否能发现并是否采取相应动作而已。操作系统管理内存的粒度不是字节而是页，一页通常为4KB。  仅供参考：windows里常见的内存填充数据含义 * 0xABABABAB : Used by Microsoft's HeapAlloc() to mark "no man's land" guard bytes after allocated heap memory * 0xABADCAFE : A startup to this value to initialize all free memory to catch errant pointers * 0xBAADF00D : Used by Microsoft's LocalAlloc(LMEM_FIXED) to mark uninitialised allocated heap memory * 0xBADCAB1E : Error Code returned to the Microsoft eVC debugger when connection is severed to the debugger * 0xBEEFCACE : Used by Microsoft .NET as a magic number in resource files * 0xCCCCCCCC : Used by Microsoft's C++ debugging runtime library to mark uninitialised stack memory * 0xCDCDCDCD : Used by Microsoft's C++ debugging runtime library to mark uninitialised heap memory * 0xDEADDEAD : A Microsoft Windows STOP Error code used when the user manually initiates the crash * 0xFDFDFDFD : Used by Microsoft's C++ debugging heap to mark "no man's land" guard bytes before and after allocated heap memory * 0xFEEEFEEE : Used by Microsoft's HeapFree() to mark freed heap memory

这个没法判断，及时初始化是个好的习惯

这个只有自己的编程意识了，变量最好都初始化，至于初始化的值，不同的应用场景用不同的值

初始化是什么呢？就是你第一次赋予变量一个值，这个值可以是你想要的值，也可以是预防错误发生的值。 第一种比如int PI=3.14，那么你判断是否为3.14就可以。 第二种比如int* p=NULL; 后面使用该变量的时候，判断指针是否为NULL就可以。  如果你也不清楚初始化应该是多少，那么判断是否初始化过就没有意义了。还不如就在你要判断是否初始化过的地方，直接赋给它一个有意义的值。

未初始化的值是不一定的，所以上面两种方式肯定不行！ 所以于其考虑怎么判断一个值有没有初始化，不好做好每个变量的初始化

只有编译期可以(编译器抛警告) 运行时无法判断


Question: linux的 sed命令 请教

顶起来，有高手不

顶起来，有高手不

引用 1 楼 cjqpker 的回复:shell中斜杠是用作转义了吧，终端中好像不是转义  注意有单引号  不存在你说的问题

shell中斜杠是用作转义了吧，终端中好像不是转义


Question: 如何根据一列数据而整行排序，求大神帮忙，跪谢

弄一个结构体保存读到的数据，再排序不就好咯

仅供参考：//学号 姓名 电话 成绩 //01 XXX 182XXXXXXXX 88 #include <stdio.h> #include <string.h> #define MAXS 10000 struct ST {     int XH;     char XM[11];     char DH[13];     int CJ; } st[MAXS],t; int n,i,j; char ln[80]; FILE *f; int main() {     f=fopen("in.txt","r");     if (NULL==f) {         printf("Can not open file in.txt!\n");         return 1;     }     i=0;     while (1) {         if (NULL==fgets(ln,80,f)) break;         if (4!=sscanf(ln,"%d%10s%12s%d",&st[i].XH,st[i].XM,st[i].DH,&st[i].CJ)) {             st[i].XH=0;             strcpy(st[i].XM,"Unknown");             strcpy(st[i].DH,"Unknown");             st[i].CJ=0;             printf("line %d format error:%s!\n",i+1,ln);         }         i++;         if (i>=MAXS) {             printf(">%d lines Ignored.\n",MAXS);             break;         }     }     fclose(f);     n=i;     for (i=0;i<n-1;i++) {         for (j=i+1;j<n;j++) {             if (st[i].CJ<st[j].CJ) {t=st[i];st[i]=st[j];st[j]=t}         }     }     for (i=0;i<n;i++) {         printf("%5d%10s%12s%4d\n",st[i].XH,st[i].XM,st[i].DH,st[i].CJ);     }     return 0; }

结构体排序你不会吗


Question: 能否将单独的C文件编译为单独的可执行文件

引用 5 楼 adlay 的回复:[quote=引用 3 楼 ForestDB 的回复:] $ cat my.c int my_main() {     return 0; }  $ gcc -nostdlib -emy_main my.c  $ ./a.out Segmentation fault (core dumped)  如上，可以做到，但是这里已经暴露了两个问题， 1、不能用printf这样的库了，因为它是标准库； 2、运行程序会有问题，也是因为缺少了标准库做的一些处理； 上述两个问题可以解决，但是要花更多的功夫。 花不了什么功夫  [adie@adintr ~]$ cat my.c #include <stdio.h> #include <stdlib.h>  int my_main() {    printf("hello world\n");    exit(0);    return 0; } [adie@adintr ~]$ gcc -nostdlib -emy_main -lc my.c [adie@adintr ~]$ ./a.out hello world [adie@adintr ~]$  [/quote]

引用 3 楼 ForestDB 的回复:$ cat my.c int my_main() {     return 0; }  $ gcc -nostdlib -emy_main my.c  $ ./a.out Segmentation fault (core dumped)  如上，可以做到，但是这里已经暴露了两个问题， 1、不能用printf这样的库了，因为它是标准库； 2、运行程序会有问题，也是因为缺少了标准库做的一些处理； 上述两个问题可以解决，但是要花更多的功夫。 花不了什么功夫  [adie@adintr ~]$ cat my.c #include <stdio.h> #include <stdlib.h>  int my_main() {    printf("hello world\n");    exit(0);    return 0; } [adie@adintr ~]$ gcc -nostdlib -emy_main -lc my.c [adie@adintr ~]$ ./a.out hello world [adie@adintr ~]$

没有入口函数的可执行文件没有意义。

可以，但不可运行

可以，但需要指定 入口函数。 还不如写上main


Question: 求助下！ 为什么出现expected ')' before '! ' token这个错误啊！

检查有没有中文标点

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

这样的问题最好自己先定位，同时在这个过程中积累自己的经验从而避免以后再犯此类错误。

这个编译错误自己检查撒

! =不等于中间该没空格吧


Question: 如何把一个本地文件的内容嵌入到代码里

#define myfilelength 你要嵌入的那个文件的字节数 unsigned char myfilecontent[myfilelength]={ //此处插入使用楼上代码对你要嵌入的那个文件转换后的字节序列的文本描述 };//全局变量

仅供参考：#include <stdio.h> #include <string.h> #include <conio.h> FILE *fi,*fo; unsigned int n; int c; //------------------------------------------------------- void main(int argc,char *argv[]) {     if (argc<3) {         cprintf("Bin2Hex srcfile desfile");         return;     }     if ((fi=fopen(argv[1],"rb"))==NULL) {         cprintf("Can not find file %s",argv[1]);         return;     }     if ((fo=fopen(argv[2],"w"))==NULL) {         fclose(fi);         cprintf("Can not create file %s",argv[2]);         return;     }     n=0;     while (1) {         c=fgetc(fi);         if (EOF==c) break;         n++;         if (1==n)        fprintf(fo,  "0x%02X",c);         else {             if (1==n%16) fprintf(fo,"\n0x%02X",c);             else         fprintf(fo, ",0x%02X",c);         }     }     fcloseall();     cprintf("OK to Bin2Hex %u bytes.",n); }

引用 6 楼 u012006886 的回复:之后就是细节问题了，特别要注意动态内存的处理，使用完毕这块内存之后记得及时释放掉  fp，是FILE*类型的，如何得来？？？

PEM_read_RSAPrivateKey这个接口是封装好的读文件接口吧，对应应该有一个写接口啊，动态申请内存要么你用标准库里面的malloc，如果你们自己封装的有申请动态内存的接口，就用封装好的，这些搞定之后，调用写接口，把key写到你申请的内存里就行吧

引用 3 楼 u012006886 的回复:你都已经把文件内容读出来了，之后申请一块动态内存，把你读出来的文件内容写进去就行了吧  嗯，有文件内容。 能否再具体一点？搞定分都给你了~~~

函数倒数第三行FILE是个笔误，请忽略。。。。

顶一个，寻大神帮忙。。。。


Question: 单链表信息分类的问题，求大神帮忙

引用 楼主 USE_R_NAME 的回复:已知L为设有头结点的单链表中第一个结点的指针，每个结点数据域存放一个字符，该字符可能是英文字母字符或数字字符或其他字符。编写程序构造三个以带头结点的单循环链表表示的线性表，使每个表中只含同一类字符，最后输出链表中的信息。 第一行为数字链表中的信息； 第二行为英文字母字符链表中的信息； 第三行为其它字符链表中的信息。 #include<stdio.h> #include<stdlib.h> struct data  { 	char ch; 	struct data *nt; };  int main() { 	int n=0; 	struct data *r,*p,*l,*z,*q,*r1,*l1,*o,*l2,*l3,*j,*k,*r2,*r3,*d,*f; 	l=(struct data *)malloc(sizeof(struct data *)); 	r=l; 	while(n==0||p->ch!='\n') 	{ 		p=(struct data *)malloc(sizeof(struct data *)); 		scanf("%c",&p->ch); 		r->nt=p; 		r=p; 		n++; 	} 	r->nt=NULL; 	l1=(struct data *)malloc(sizeof(struct data *)); 	l2=(struct data *)malloc(sizeof(struct data *)); 	l3=(struct data *)malloc(sizeof(struct data *)); 	q=(struct data *)malloc(sizeof(struct data *)); 	j=(struct data *)malloc(sizeof(struct data *)); 	k=(struct data *)malloc(sizeof(struct data *)); 	l1->nt=q; 	l2->nt=j; 	l3->nt=k; 	z=l->nt; 	while(z!=NULL) 	{ 		if(z->ch>=48&&z->ch<=57) 		{ 			r1=q; 			r1->ch=z->ch; 			q=(struct data *)malloc(sizeof(struct data *)); 			r1->nt=q; 		} 		else if(z->ch>=65&&z->ch<=90||z->ch>=97&&z->ch<=122) 		{ 			r2=j; 			r2->ch=z->ch; 			j=(struct data *)malloc(sizeof(struct data *)); 			r2->nt=j; 		} 		else 		{ 			r3=k; 			r3->ch=z->ch; 			k=(struct data *)malloc(sizeof(struct data *)); 			r3->nt=k; 		} 		z=z->nt; 	} 	r1->nt=NULL; 	r2->nt=NULL; 	r3->nt=NULL; 	o=l1->nt; 	d=l2->nt; 	f=l3->nt; 	while(o!=NULL) 	{ 		printf("%c",o->ch); 		o=o->nt; 	} 	printf("\n"); 	while(d!=NULL) 	{ 		printf("%c",d->ch); 		d=d->nt; 	} 	printf("\n"); 	while(f!=NULL) 	{ 		printf("%c",f->ch); 		f=f->nt; 	} 	return 0; } 提交上去一直是Time Limit Exceeded  在我电脑上可以成功，应该怎么简化一下呢！就是您能不能帮我看看我这个要怎么简化一下..我那个上去一直超时。。您的这些上完课回来好好看看！谢谢啦

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


古董级的工具还是有不少人怀念呀

引用 12 楼 akirya 的回复:[quote=引用 11 楼 sugar13 的回复:] 关键是TC是16位软件,没法在64位win系统下跑. Win-TC的话,当年在学校的机房里面XP下倒是很正常的跑,自己电脑的XP系统下却总是在编译的时候,肉眼能够找到的函数,它却找不到.. TC2 得和 DOS6.22搭配着使用，实在不行也可以上Win98。XP就有点不搭了。[/quote] TC2和BC31应该在DoxBox里面也能跑得不错。

引用 11 楼 sugar13 的回复:关键是TC是16位软件,没法在64位win系统下跑. Win-TC的话,当年在学校的机房里面XP下倒是很正常的跑,自己电脑的XP系统下却总是在编译的时候,肉眼能够找到的函数,它却找不到.. TC2 得和 DOS6.22搭配着使用，实在不行也可以上Win98。XP就有点不搭了。

引用 15 楼 sugar13 的回复:[quote=引用 12 楼 akirya 的回复:] [quote=引用 11 楼 sugar13 的回复:] 关键是TC是16位软件,没法在64位win系统下跑. Win-TC的话,当年在学校的机房里面XP下倒是很正常的跑,自己电脑的XP系统下却总是在编译的时候,肉眼能够找到的函数,它却找不到.. TC2 得和 DOS6.22搭配着使用，实在不行也可以上Win98。XP就有点不搭了。[/quote]  请问我从itellyou上下载的dos6.22的exe文件，该如何安装到vmware中呢 文件名 SC_MSDOS622sc.exe SHA1 DD3C5CAD0FF837C38D5EB14B0D59E9A670792DCC[/quote] 不清楚是啥版本的，应该是几个软盘镜像才对

引用 15 楼 sugar13 的回复:[quote=引用 12 楼 akirya 的回复:] [quote=引用 11 楼 sugar13 的回复:] 关键是TC是16位软件,没法在64位win系统下跑. Win-TC的话,当年在学校的机房里面XP下倒是很正常的跑,自己电脑的XP系统下却总是在编译的时候,肉眼能够找到的函数,它却找不到.. TC2 得和 DOS6.22搭配着使用，实在不行也可以上Win98。XP就有点不搭了。[/quote]  请问我从itellyou上下载的dos6.22的exe文件，该如何安装到vmware中呢 文件名 SC_MSDOS622sc.exe SHA1 DD3C5CAD0FF837C38D5EB14B0D59E9A670792DCC[/quote] 别费那劲了，为什么不使用DosBox呢？

引用 12 楼 akirya 的回复:[quote=引用 11 楼 sugar13 的回复:] 关键是TC是16位软件,没法在64位win系统下跑. Win-TC的话,当年在学校的机房里面XP下倒是很正常的跑,自己电脑的XP系统下却总是在编译的时候,肉眼能够找到的函数,它却找不到.. TC2 得和 DOS6.22搭配着使用，实在不行也可以上Win98。XP就有点不搭了。[/quote]  请问我从itellyou上下载的dos6.22的exe文件，该如何安装到vmware中呢 文件名 SC_MSDOS622sc.exe SHA1 DD3C5CAD0FF837C38D5EB14B0D59E9A670792DCC

编译工具不是重点，vc++6.0就行

编译的话Dev-cpp用的不错，还有就是楼上说的VC了，本人觉得这两种都不错

引用 5 楼 sholber 的回复:在学习C语言的路上，你第一步就走错了，更遑论学好C语言。这年月哪有用TC学C语言的。 赵老湿名义上是帮忙，实际上是落井下石啊。其心可诛，奸侫之师，不可师之！ 那请你找出一个比 Win-TC\tcstudy.chm 更好的中文chm格式的C帮助文件的链接贴上来。

这个阶段用gcc还是tc都是一样的，楼主在看《汇编语言》迈

引用 7 楼 zhao4zhong1 的回复:[quote=引用 5 楼 sholber 的回复:] 在学习C语言的路上，你第一步就走错了，更遑论学好C语言。这年月哪有用TC学C语言的。 赵老湿名义上是帮忙，实际上是落井下石啊。其心可诛，奸侫之师，不可师之！ 那请你找出一个比 Win-TC\tcstudy.chm 更好的中文chm格式的C帮助文件的链接贴上来。[/quote]  大胆胡说，下面冒气  过时软件之过时文档，不要也罢。

bc++3.1 帮助里面对每个函数都有一小段能拷贝出来运行看效果的例子程序。非常适合初学C语言。相比较而言VC带的帮助MSDN就没有。http://download.csdn.net/source/2805028  要想在Windows环境下稳定运行bc.exe 建一个批处理bc.bat,内容为下面两行，放在bc.exe同目录下，再将bc.bat发送到桌面快捷方式： del bc*.swp >NUL start command /c bc.exe 如果想在IDE里面使用鼠标，还应将快捷方式属性中的快速编辑模式关掉。

好怀念这个软件，只能帮顶了

搜索下载“Win-TC”

记得当初学C语言用的就是它，估计现在不好找到了！


Question: 我头一次发现C语言还能这么玩

记得有个只用“喵呜”编程的帖子，找不到了。

1.现在的编译器已经支持中文字符了 2.宏的预处理 3.国际乱码大赛常用技巧

宏定义直接替换

多见不怪

引用 4 楼 euewrqe12 的回复:我奇怪的是为什么能用中文 新一些的编译器都支持 中文变量什么的,早就有了

C语言怪异代码大赛历届作品大全 1984～1996，1998，2000，2001，2004～2006，2011，2012 http://download.csdn.net/detail/zhao4zhong1/5538847

电脑又不知道什么是中文   只要字符不非法就行

我奇怪的是为什么能用中文

你很牛，这都整的出来

这是宏替换，没什么稀奇的！


Question: [求教]c语言数组问题

搜“辗转相除法”

优化你的GCD函数，两个for循环没法避免吧

没看明白，你的GCD()函数怎么写的，超时又是指什么？

引用 1 楼 JiangWenjie2014 的回复:优化你的GCD函数，两个for循环没法避免吧 有没有什么数学方法来解决这个问题啊


Question: 关于C中的浮点数的存储问题

引用 2 楼 sz523921551 的回复:[quote=引用 1 楼 zhao4zhong1 的回复:] http://bbs.csdn.net/topics/390676437  赵老师能否直接说明下，我是哪里出问题了？[/quote] 懒得说，自己运行这个链接里面我的程序，亲自观察一下。  理解和讨论之前请先学会如何观察！  不要迷信书、考题、老师、回帖； 要迷信CPU、编译器、调试器、运行结果。 并请结合“盲人摸太阳”和“驾船出海时一定只带一个指南针。”加以理解。 任何理论、权威、传说、真理、标准、解释、想象、知识……都比不上摆在眼前的事实！  有人说一套做一套，你相信他说的还是相信他做的？ 其实严格来说这个世界上古往今来所有人都是说一套做一套，不是吗？

引用 1 楼 zhao4zhong1 的回复:http://bbs.csdn.net/topics/390676437  赵老师能否直接说明下，我是哪里出问题了？


Question: 一个蛋疼的数字转字符串的问题

既然说到秀：#include <afx.h> #include <stdio.h> CString ChineseCapitalMoney(double Num) {     CString szChMoney,szNum;     int iLen, iNum, iAddZero=0;     TCHAR* hzUnit[18]={_T("分"),_T("角"),_T("元"),_T("拾"),_T("佰"),_T("仟"),_T("万"),_T("拾"),_T("佰"),_T("仟"),_T("亿"),_T("拾"),_T("佰"),_T("仟"),_T("万"),_T("拾"),_T("佰"),_T("仟")};     TCHAR* hzNum[10]={_T("零"),_T("壹"),_T("贰"),_T("叁"),_T("肆"),_T("伍"),_T("陆"),_T("柒"),_T("捌"),_T("玖")};     if (-0.01<Num && Num<0.01) return _T("零元整");     szNum.Format(_T("%18.0f"), Num*100); // 最小到分     szNum.TrimLeft();     iLen=szNum.GetLength();     if(iLen>15 || iLen==0 || Num<0) return _T(""); // 数据错误返回      for(int i=0;i<iLen;i++) {         iNum=_ttoi((LPCTSTR)szNum.Mid(i,1));         if (iNum==0) {             iAddZero++;         } else {             if (iAddZero>0) szChMoney+=_T("零");             szChMoney+=hzNum[iNum];             iAddZero=0;         }         if (iNum!=0 || iLen-i==3 || iLen-i==11 || ((iLen-i+1)%8==0 && iAddZero<4)) szChMoney+=hzUnit[iLen-i-1];     }     if (szNum.Right(2)==_T("00")) szChMoney+=_T("整"); // 没有角和分     return szChMoney; } void main() {     double d;     CString s;      d=-1.0            ;printf("%16.2f %s\n",d,ChineseCapitalMoney(d));     d=0.0             ;printf("%16.2f %s\n",d,ChineseCapitalMoney(d));     d=1234501234567.89;printf("%16.2f %s\n",d,ChineseCapitalMoney(d));     d=1000000000000.01;printf("%16.2f %s\n",d,ChineseCapitalMoney(d));     d=1000000000001.00;printf("%16.2f %s\n",d,ChineseCapitalMoney(d));     d= 130040600090.01;printf("%16.2f %s\n",d,ChineseCapitalMoney(d)); } //           -1.00 //            0.00 零元整 //1234501234567.89 壹万贰仟叁佰肆拾伍亿零壹佰贰拾叁万肆仟伍佰陆拾柒元捌角玖分 //1000000000000.01 壹万亿元零壹分 //1000000000001.00 壹万亿零壹元整 // 130040600090.01 壹仟叁佰亿零肆仟零陆拾万零玖拾元零壹分  #include <stdio.h> #include <string.h> char hznum[100]; char hzunit[15][3]={"","十","百","千","万","十","百","千","亿","十","百","千","万","十","百"}; char hzdigit[10][3]={"零","一","二","三","四","五","六","七","八","九"}; char numstr[20]; char *ReadNumByHZ(double v) {     char *p,*d;     int u,i;      sprintf(numstr,"%.15lg",v);     printf("%s\n",numstr);     if ('-'==numstr[0]) {         sprintf(hznum,"不支持读负数");         return hznum;     }     p=strchr(numstr,'e');     if (NULL!=p) {         sprintf(hznum,"不支持读太大或太小的数");         return hznum;     }     d=NULL;     p=strchr(numstr,'.');     if (NULL!=p) {         p[0]=0;         d=p+1;     }     u=strlen(numstr);     hznum[0]=0;     for (i=0;i<u;i++) {         if ('0'==numstr[i] && 0!=((u-1-i)%4)) {             sprintf(hznum,"%s%s",hznum,hzdigit[numstr[i]-'0']);         } else {             sprintf(hznum,"%s%s%s",hznum,hzdigit[numstr[i]-'0'],hzunit[u-1-i]);         }     }     printf("%s\n",hznum);     u=strlen(hznum);     for (i=0;i<u;i+=2) {         if (0==strncmp(hznum+i,"零零",4)) {//多个连续的“零”改成一个“零”             memmove(hznum+i,hznum+i+2,u-i-2+1);             i-=2;             u-=2;         }     }     printf("%s\n",hznum);     if (0==strcmp(hznum+u-2,"零")) {//末尾“零”去掉         hznum[u-2]=0;         u-=2;     }     printf("%s\n",hznum);     for (i=0;i<u;i+=2) {         if (0==strncmp(hznum+i,"零万",4) || 0==strncmp(hznum+i,"零亿",4)) {//“万”“亿”前是“零”去掉             memmove(hznum+i,hznum+i+2,u-i-2+1);             u-=2;         }     }     printf("%s\n",hznum);     if (NULL!=d) {         sprintf(hznum,"%s点",hznum);         i=0;         while (1) {             if (0==d[i]) break;             sprintf(hznum,"%s%s",hznum,hzdigit[d[i]-'0']);             i++;         }     }     printf("%s\n",hznum);     return hznum; } void main() {     printf("\n%s\n",ReadNumByHZ(130040600090.012)); } //130040600090.012 //一千三百零零亿四千零六十零万零零九十零 //一千三百零亿四千零六十零万零九十零 //一千三百零亿四千零六十零万零九十 //一千三百亿四千零六十万零九十 //一千三百亿四千零六十万零九十点零一二 // //一千三百亿四千零六十万零九十点零一二  那就一秀到底裤吧

6楼代码略优化： 删除第3行#include <string.h> 原第69行if (p[strlen(p)-1]==' ') p[strlen(p)-1]=0;改为if (p[-1]==' ') p[-1]=0;

char s_n[20] = { "", "One",...,"Nineteen"}; char s_n1[10]= { "", "", "twenty",...,"ninety"};  void thousandToStr( UINT u, char *pStr ) { 	UINT u1 = u/100; 	if( u1 > 0 ) 	{ 		strcat( pStr, s_n[u1] ); 		strcat( pStr, " hundred " ); 	} 	u = u%100; 	u1= u/10; 	if( u1 > 1 ) 	{ 		strcat( pStr, s_n1 ); 		strcat( pStr, " " ); 	} 	u1 = u%20; 	strcat( pStr, s_n ); } void MillionToStr( UINT u, char *pStr ) { 	UINT u1 = u/1000000; 	if( u1 > 0 ) 	{ 		MillionToStr( u1, pStr ); 		strcat( pStr, " Million ") 	} 	u1 = u/1000; 	if( u1 > 0 ) 	{ 		thousandToStr( u1, pStr ); 		strcat( pStr, " thousand" ); 	} 	strcat( pStr, " " ); 	thousandToStr( u1, pStr ); }  void UintToStr( UINT u, char* pStr ) { 	MillionToStr( u, pStr ); }

#include <stdio.h> #include <string.h> #include <memory.h>  #pragma warning (disable : 4996)  void written_amount(unsigned long long amount, char * buffer); char* head(unsigned long long num, char* buf);  char* _1[]  = {"", " thousand", " million", " billion"}; char* _2[]  = {"", " ten"," twenty"," thirty"," forty"," fifty"," sixty"," seventy"," eighty"," ninety"}; char* _3[]  = {"", " one"," two"," three"," four"," five"," six"," seven"," eight"," nine", " ten", " eleven"," twelve"," thirteen"," fourteen"," fifteen"," sixteen"," seventeen"," eighteen"," nineteen"};  int main(void) {     unsigned long long n;     char str[255];     memset(str, '\0', 254);      printf("Please enter the value.\n");     scanf("%I64d", &n);      if (n > 999999999999)     {         printf("Hard to describe a number larger than 999 billion \n");         return -1;     }      written_amount(n, str);     puts(str);      return 0; }   void written_amount(unsigned long long amount, char * buffer) {     long long i = 0;     long long temp = amount;     long long bu = amount;      for (i = 3; i >= 0; i--)     {         unsigned long long temp = amount;         char stemp[128] = {0};          for (long long j = 0; j < i; j++)         {             temp /= 1000;         }         temp %= 1000;         if (temp > 0)         {             strcat(buffer, head(temp, stemp));             strcat(buffer, _1[i]);         }     } }  char* head(unsigned long long num, char* buf) {     char stemp[128] = {0};     unsigned long long temp;          //hundred     temp = num / 100;     if (temp > 0)     {         strcat(buf, _3[temp]);         strcat(buf, " hundred ");     }      //less than hundred     temp = num % 100;     if (temp > 0)     {         strcat(buf, num / 100 > 0 ? " and " : "");         if (temp > 0 && temp < 20 )     // 0-19         {             strcat(buf, _3[temp]);         }         else                            // >19         {             strcat(buf, _2[temp / 10]);             //less than 10             temp = temp % 10;             if (temp > 0)             {                 strcat(buf, _3[temp]);             }         }     }          return buf; }

仅供参考：///////////////////////////////////////////////////////////// // FREE code from CODECENTRIX // http://www.codecentrix.com/ // http://codecentrix.blogspot.com/ ///////////////////////////////////////////////////////////// #include "stdafx.h"  const TCHAR* const NUMBERS_UP_TO_20[] = {     _T("zero"),     _T("one"),     _T("two"),      _T("three"),    _T("four"),     _T("five"),     _T("six"),     _T("seven"),    _T("eight"),    _T("nine"),     _T("ten"),      _T("eleven"),  _T("twelve"),   _T("thirteen"), _T("fourteen"),     _T("fifteen"),  _T("sixteen"), _T("sventeen"), _T("eighteen"), _T("nineteen") };  const TCHAR* const NUMBERS_MULTIPLE_OF_10[] = {     _T("twenty"), _T("thirty"),  _T("fourty"), _T("fifty"),     _T("sixty"),  _T("seventy"), _T("eighty"), _T("ninety") };   tstring NumberToStringEN(INT64 nNumber) {     if (nNumber < 0)     {         return _T("");     }      if (nNumber < 20)     {         return NUMBERS_UP_TO_20[nNumber];     }      tstring sResult;     INT64   nCrntNumber = nNumber / 1000000000;      if (nCrntNumber > 0)     {         sResult = NumberToStringEN(nCrntNumber);         sResult += _T(" billion");         nNumber %= 1000000000;     }      nCrntNumber = nNumber / 1000000;     if (nCrntNumber > 0)     {         sResult = NumberToStringEN(nCrntNumber);         sResult += _T(" million");         nNumber %= 1000000;     }      nCrntNumber = nNumber / 1000;     if (nCrntNumber > 0)     {         sResult = NumberToStringEN(nCrntNumber);         sResult += _T(" thousand");         nNumber %= 1000;     }  	nCrntNumber = nNumber / 100; 	if (nCrntNumber > 0) 	{ 		sResult = NumberToStringEN(nCrntNumber); 		sResult += _T(" hundred"); 		nNumber %= 100; 	}  	if ((0 < nNumber) && (nNumber < 20)) 	{ 		sResult += _T(" "); 		sResult += NumberToStringEN(nNumber); 	} 	else 	{ 		nCrntNumber = nNumber / 10; 		if (nCrntNumber > 0) 		{ 			sResult += _T(" "); 			sResult += NUMBERS_MULTIPLE_OF_10[nCrntNumber - 2]; 			nNumber %= 10; 		}  		nCrntNumber = nNumber; 		if (nCrntNumber > 0) 		{ 			sResult += _T(" "); 			sResult += NumberToStringEN(nCrntNumber); 		} 	}  	if (sResult[sResult.length() - 1] == _T(' ')) 	{ 		// Erase last space. 		sResult.erase(sResult.length() - 1, 1); 	}  	return sResult; }

如果能利用库函数的话先把16312 转为16312转为字符串 “16312”(利用 sprintf)，再一个一个字符转就可以

我觉得应该有改善的空间，因为除了 billion、million、thousand、hundred，就剩下1-9了，应该不用写那么多次分支，待我写写试试

看各位秀代码中

为什么不用1000作为模？

西方计数的特点是3位一段，中国是4位一段。 所以3位一个处理就ok了。 10万用西方的话说就是100个一千。

引用 6 楼 zhao4zhong1 的回复:Ready——Go！ DUANG！ Perfect！ #pragma warning(disable:4996) #include <stdio.h> #include <string.h> char *NUMBERS_UP_TO_20[] ={     "zero"   ,"one"    ,"two"     ,"three"   ,"four"    ,     "five"   ,"six"    ,"seven"   ,"eight"   ,"nine"    ,     "ten"    ,"eleven" ,"twelve"  ,"thirteen","fourteen",     "fifteen","sixteen","sventeen","eighteen","nineteen", }; char *NUMBERS_MULTIPLE_OF_10[] ={     "twenty", "thirty" , "fourty", "fifty" ,     "sixty" , "seventy", "eighty", "ninety", }; char *NumberToString(long long int nNum,char *p) {     char *q;     int n;     long long int nCrntNumber;      q=p;     if (nNum<0) return "";     if (nNum<20) return NUMBERS_UP_TO_20[nNum];      nCrntNumber=nNum/1000000000;     if (nCrntNumber>0) {         n=sprintf(p,"%s billion ",NumberToString(nCrntNumber,p));         p+=n;         nNum%=1000000000;     }      nCrntNumber=nNum/1000000;     if (nCrntNumber>0) {         n=sprintf(p,"%s million ",NumberToString(nCrntNumber,p));         p+=n;         nNum%=1000000;     }      nCrntNumber=nNum/1000;     if (nCrntNumber>0) {         n=sprintf(p,"%s thousand ",NumberToString(nCrntNumber,p));         p+=n;         nNum%=1000;     }      nCrntNumber=nNum/100;     if (nCrntNumber>0) {         n=sprintf(p,"%s hundred ",NumberToString(nCrntNumber,p));         p+=n;         nNum%=100;     }      if (0<nNum && nNum<20) {         n=sprintf(p,"%s ",NumberToString(nNum,p));         p+=n;     } else {         nCrntNumber=nNum/10;         if (nCrntNumber>0) {             n=sprintf(p,"%s ",NUMBERS_MULTIPLE_OF_10[nCrntNumber-2]);             p+=n;             nNum%=10;         }          nCrntNumber=nNum;         if (nCrntNumber>0) {             n=sprintf(p,"%s ",NumberToString(nCrntNumber,p));             p+=n;         }     }      if (p[strlen(p)-1]==' ') p[strlen(p)-1]=0;      return q; } int main() {     char sRes[256];     long long int d;      d=                  0  ;printf("%19lld is [%s]\n",d,NumberToString(d,sRes));     d=                  1  ;printf("%19lld is [%s]\n",d,NumberToString(d,sRes));     d=                  9  ;printf("%19lld is [%s]\n",d,NumberToString(d,sRes));     d=                 19  ;printf("%19lld is [%s]\n",d,NumberToString(d,sRes));     d=                 20  ;printf("%19lld is [%s]\n",d,NumberToString(d,sRes));     d=                 21  ;printf("%19lld is [%s]\n",d,NumberToString(d,sRes));     d=                 90  ;printf("%19lld is [%s]\n",d,NumberToString(d,sRes));     d=                100  ;printf("%19lld is [%s]\n",d,NumberToString(d,sRes));     d=               2000  ;printf("%19lld is [%s]\n",d,NumberToString(d,sRes));     d=            3000000  ;printf("%19lld is [%s]\n",d,NumberToString(d,sRes));     d=         4000000000ll;printf("%19lld is [%s]\n",d,NumberToString(d,sRes));     d=1000000000000000002ll;printf("%19lld is [%s]\n",d,NumberToString(d,sRes));     d=1234567890123456789ll;printf("%19lld is [%s]\n",d,NumberToString(d,sRes));     d=9223372036854775807ll;printf("%19lld is [%s]\n",d,NumberToString(d,sRes));//2^63-1     return 0; } //                  0 is [zero] //                  1 is [one] //                  9 is [nine] //                 19 is [nineteen] //                 20 is [twenty] //                 21 is [twenty one] //                 90 is [ninety] //                100 is [one hundred] //               2000 is [two thousand] //            3000000 is [three million] //         4000000000 is [four billion] //1000000000000000002 is [one billion billion two] //1234567890123456789 is [one billion two hundred thirty four million five hundred sixty seven thousand eight hundred ninety billion one hundred twenty three million four hundred fifty six thousand seven hundred eighty nine] //9223372036854775807 is [nine billion two hundred twenty three million three hundred seventy two thousand thirty six billion eight hundred fifty four million seven hundred seventy five thousand eight hundred seven] //


Question: 新手求助！如何在一个函数中调用另一个函数来达到search的目的

从第一个文件的内容（head指针指向的内容）中逐行搜索并找到包含第二个文件中指定字符串的文本行（strFp读出的内容，第二个文件中的每一行就是一个待搜索的字符串，所以针对每个字符串要在要第一个文件的内容中搜索一次），然后直接在控制台上打印出来，while(fgets(buf, LINE, strFp))要实现的就是上述过程

该怎么调用，就怎么调用

search(strFile, buf[LINE])；  函数的调用基本就是这样喽，调用的时候 省掉前面的返回值类型，两个参数换下就ok


Question: 一元二次方程 数据类型用float正确 用double错误 求解

引用 1 楼 zhangxiangDavaid 的回复:double类型使用lf读入 scanf("%f %f %f",&a,&b,&c);=>scanf("%lf %lf %lf",&a,&b,&c);     谢谢！

引用 2 楼 s_a_n_ 的回复:改成double后使用scanf读入数据时要把相应的%f改成%lf，就可以了 scanf("%lf %lf %lf",&a,&b,&c);     谢谢！


Question: 向大神请教一个读取数字字母串的程序，不知道错在哪里，谢谢了

仅供参考：#include <stdio.h> char s[]="123 ab 4"; char *p; int v,n,k; void main() {     p=s;     while (1) {         k=sscanf(p,"%d%n",&v,&n);         printf("k,v,n=%d,%d,%d\n",k,v,n);         if (1==k) {             p+=n;         } else if (0==k) {             printf("skip char[%c]\n",p[0]);             p++;         } else {//EOF==k             break;         }     }     printf("End.\n"); } //k,v,n=1,123,3 //k,v,n=0,123,3 //skip char[ ] //k,v,n=0,123,3 //skip char[a] //k,v,n=0,123,3 //skip char[b] //k,v,n=1,4,2 //k,v,n=-1,4,2 //End.

1.txt是这样的：只有两行 +123 00 ab -123 -- abc ++ +abc -abc

大道至简 仅供参考：  #include <stdio.h> #include <stdlib.h> #include <ctype.h> #define LINE 80 int n1, n2; char str[10][20]; int num[10]; void evaluate(char *line, int n) { 	char buf[80]; 	int i = 0, j = 0, flag; 	while (1) 	{ 		j = 0; 		//跳过空白字符 		while (line[i] && (line[i] == '\t' || line[i] == ' ')) i++; 		if (line[i] == 0) break; 		while (line[i] && line[i] != '\t' && line[i] != ' ') 		{ 			if (line[i] == '+' || line[i] == '-') 			{ 				if (isdigit(line[i + 1]))  //下一个字符是数字，处理形如 "+123"  "-123" 的数字 					flag = 1; 				else 					flag = 0; 			} 			else if (isdigit(line[i])) 				flag = 1; 			else 				flag = 0;  			while (line[i] && line[i] != '\t' && line[i] != ' ') 			{ 				buf[j++] = line[i++]; 			} 			buf[j] = 0;  			if (flag)   //处理数字 			{ 				sscanf(buf, "%d", num + n1); 				n1++; 			} 			else   //处理字符串 			{ 				sscanf(buf, "%s", str + n2); 				n2++; 			} 		} 	} } int main()  //118 { 	FILE *fp; 	char line[LINE], inFile[20]; 	printf("请输入文件名: "); 	scanf("%s", inFile); 	if ((fp = fopen(inFile, "r")) == NULL) 	{ 		printf("无法打开文件\n", inFile); 		system("pause"); 		exit(0); 	} 	int i = 0; 	while (fgets(line, LINE, fp)) 	{ 		n1 = n2 = 0; 		printf("获取文本: %s\n", line); 		evaluate(line, strlen(line)); 		for (i = 0; i < n1; i++) 			printf("第%d个整数是%d\n", i, num[i]); 		for (i = 0; i < n2; i++) 			printf("第%d个字符串是%s\n", i, str[i]); 	} 	return  0; } //请输入文件名: 1.txt //获取文本 : +123 00 ab - 123 -- //第0个整数是123 //第1个整数是0 //第2个整数是 - 123 //第0个字符串是ab //第1个字符串是-- //获取文本 : abc++ + abc - abc //第0个字符串是abc //第1个字符串是++ //第2个字符串是 + abc //第3个字符串是 - abc

引用 3 楼 zhangxiangDavaid 的回复:有些特殊输入没有处理 如 ajsdkk   -  asdkjl  134 +  alsdk 正负号后面跟的不是数字，你怎么办？  如果先不管这个问题的话，像2楼所说的getNum和getStr没有输出这个应该怎么改啊？我的意思是怎么输出……

#include <stdio.h> #include <stdlib.h> #include <ctype.h> #define LINE 80  void getNum(char *buf, int *k, int *num) { 	int sign=1; 	/* 以下程序用来获取整型数*/ 	if(buf[*k]=='-') 	{ 		sign=-1;(*k)++; 	} 	*num=0; 	while(isdigit(buf[*k])) 	{ 		*num=*num*10+buf[*k]-'\0'; 		(*k)++;/*差个括号*/ 	} 	*num*=sign; }  void getStr(char *buf, int *k, char *str) { 	int i=0; 	/* 以下程序用来获取字符串*/ 	while(isalpha(buf[*k])) 	{ 		str[i]=buf[*k]; 		(*k)++; 		i++; 	} 	str[i]='\0'; }  void getData(char *buf, int *nNum, int num[], int *nStr, char str[][20]) { 	int k; 	k=0; 	while(buf[k]) 	{ 		while(buf[k] == ' ' || buf[k] == '\t') 			k++; 		if(isdigit(buf[k]) || buf[k] == '-') 			/* 调用getNum函数，获取整型数*/ 			getNum(buf,&k,num); 		else if(isalpha(buf[k])) 			/* 调用getStr函数，获取字符串*/ 			getStr(buf,&k,*str); 		while(buf[k] != ' ' && buf[k] != '\t' && buf[k] != '\0') 			k++; 	} }  void main() { 	FILE *fp; 	char buf[LINE], inFile[20]; 	int  i, nNum, num[10], nStr; 	char str[10][20]; 	printf("请输入文件名: "); 	scanf("%s", inFile); 	if((fp = fopen(inFile, "r")) == NULL) 	{ 		printf("无法打开文件\n", inFile); 		system("pause"); 		exit(0); 	} 	while( fgets(buf, LINE, fp) ) 	{ 		printf("获取文本: %s", buf); 		nNum = nStr = -1; 		getData(buf, &nNum, num, &nStr, str); 		for(i=0; i<=nNum; ) 			printf("整型数 %d: %d\n", ++i, num[i]); 		for(i=0; i<=nStr; ) 			printf("字符串 %d: %s\n", ++i, str[i]); 	} } /* 请输入文件名: exe2-3File.txt 获取文本:   -2 abc 8    string 整型数 1: -2 整型数 2: 8 字符串 1: abc 字符串 2: string 获取文本: 获取文本: 8     china  6  9  printf(" 整型数 1: 8 整型数 2: 6 整型数 3: 9 字符串 1: china 字符串 2: printf 获取文本:    4    6 fudan6 3  stracosed 整型数 1: 4 整型数 2: 6 整型数 3: 3 字符串 1: fudan 字符串 2: stracosed */   另外需要加上输出语句，不然你的getNum两个函数没有输出

#include<stdio.h> int main() {     const char *p = "sdfdsf345fdgfdg678";     const char *q = "123wer";     char a[100] = { 0 };     int i = 0;     if (sscanf(p,"%d", &i) > 0)     {         printf("p: i = %d\n", i);     }     else     {         sscanf(p,"%s", a);//a:"sdfdsf345fdgfdg678"         printf("p: a = %s\n", a);         sscanf(q,"%d", &i);         printf("q: i = %d\n", i);     } //    p: a = sdfdsf345fdgfdg678 //    q: i = 123     return  0; }


Question: 请教一个预编译命令的问题

展开果然是条空语句，给我留的填空题？

引用 3 楼 ytfhwfnh 的回复:[quote=引用 1 楼 user-2 的回复:] 编译器可以展开宏  可以搜"vc 宏展开" 或者"gcc 宏展开" source insight也可以展开么？[/quote] 哦，gcc -E -P xxx 我试试

引用 1 楼 user-2 的回复:编译器可以展开宏  可以搜"vc 宏展开" 或者"gcc 宏展开" source insight也可以展开么？

这样定义什么都没有

编译器可以展开宏  可以搜"vc 宏展开" 或者"gcc 宏展开"


Question: C语言printf参数修饰符对%%是否有效？

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

去gnu下载glibc源码看看printf的实现即可

如果真想搞清楚到底是几个，还是翻编译器源代码吧，最直接

经多个编译器测试，确实不行，但不必纠结此事，了解即可。


Question: 快速排序划分先处理较短的那部分 能提高效率吗？

楼主我估计在你之前至少有上几十万人次企图优化快速排序算法而不得！

没区别的，都是要算，谁先谁后一样 你这个优化思路的正解是分治后并行计算。但一般没这个必要  我面试别人的时候问快排如果问别人如何优化，基本答出随机化主元以及为什么要这么做就行了。

根较短的没关系吧。跟划分的关键字有关

递归深度用于stack 跟效率关系不大

你可以自己模拟一下啊


Question: c语言如何求得结构体内某个元素的长度

LZ 的给分。。。，感觉你依旧不懂你的问题。

糊涂了，直接用空指针就可以了啊  sizeof(((struct card *)0)->b);

在不考虑对齐的情况下，可以使用offsetof  #include <stdio.h> #include <stddef.h>   struct card  {        char a;        char  b[4];        char   c; };  int main(int argc, char *argv[]) {         size_t size;          size = offsetof(struct card, c) - offsetof(struct card, b);         printf("size=%d\n", size);          return 0; }

这让我想起Kernel的container_of关键技术了  #define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER)  #define container_of(ptr, type, member) ({                      \          const typeof( ((type *)0)->member ) *__mptr = (ptr);    \          (type *)( (char *)__mptr - offsetof(type,member) );})

同意 7楼， 对齐就有偏差了  通常的严谨的结构定义都是需要pack（1），即使对齐也要在结构中添加 reserve来主动对齐。

在确保结构体内部字节对齐的前提下(无无效字节)，可以如楼上的楼上所说。  (int)(&(((struct card *)0)->c)) -(int)( &(((struct card *)0)->b)),若c为int的话，就不可用了。

[code = c] struct card { 	char a; 	char  b[4]; 	char   c; }; int main(void) { 	printf("%d\n", sizeof(card::a));  //1 	printf("%d\n", sizeof(card::b));  //4 	printf("%d\n", sizeof(card::c));  //1 	return 0; } [/ code]  查看偏移量 [code = c] struct card { 	char a; 	char  b[4]; 	char   c; }; int main(void) { 	printf("%d\n", offsetof(struct card, a));   //0 	printf("%d\n", offsetof(struct card, b));   //1 	printf("%d\n", offsetof(struct card, c));   //5 	printf("%d\n", sizeof(struct card));        //6 	system("pause"); 	return 0; } [/ code]

(int)(&(((struct card *)0)->b)) 获得b开始地址，(int)(&(((struct card *)0)->c)) 获得c开始地址  答案就是：(int)(&(((struct card *)0)->c))  - (int)(&(((struct card *)0)->b))

(int)(&(((struct card *)0)->b))

试试这个呢？ sizeof(card::b); c++里新增了，不知道c语言里怎么样

必须声明一个具体的结构体吗,就像我自己试过的那样？

必须声明结构体，才可以


Question: leetcode OJ的longest Common Prefix这一题，我用C写的，提交之后有bug（OJ说两个“a”的时候不符合），可是我自己测试却可以。

仅供参考，简化：  #include <stdio.h> char *longestCommonPrefix(char **strs, int n) { 	int i, j; 	static char prefix[100]; 	strcpy(prefix, strs[0]); 	for (i = 1; i < n; i++) 	{ 		j = 0; 		while (prefix[j] && prefix[j] == strs[i][j]) j++; 		prefix[j] = '\0'; 	} 	return prefix; } int main(void) { 	//char *strs[] = { "abcdabc", "abcdxxxx", "abcyyyyy" }; 	char *strs[] = { "a", "a" }; 	printf("%s\n", longestCommonPrefix(strs, sizeof(strs)/sizeof(*strs))); 	return 0; }


Question: 【新手求解答】 结构体 在函数中赋值的问题！

# include <stdio.h> # include <malloc.h>  struct xues { int age; int fens; char sex; };  void f (struct xues ** A, int t) { int i = 0;  printf("请输入学生的具体资料："); printf("\n"); for(i = 0; i < t; i++) { //	 printf("第%d个学生的信息："，i + 1 );   //19行   printf("age = "); scanf("%d", &((*A[i]).age));  printf("fens = "); scanf("%d", &(*A[i]).fens);  printf("sex = "); scanf("% c", &(*A[i]).sex);  } }  int main (void) { int len; struct xues * p; int t; printf("请输入学生的个数："); scanf("%d", &len);  p = (struct xues *)malloc(len * sizeof(struct xues)); printf("\n");  f(&p, len);  printf("---------------------------------------------------------\n");  for(t = 0; t < len; t++) { printf("第%d个学生的信息是：\n", t); printf("age = %d, fens = %d, sex = %c\n", p[t].age, p[t].fens, p[t].sex); } return 0; } 你说的问题没有了！但是又有新的问题！你自己看看吧！

修改如下：  #include <stdio.h> #include <malloc.h> struct xues { 	int age; 	int fens; 	//int sex; 	char sex; };  void f(struct xues *A, int t)  //直接使用一级指针即可 { 	int i = 0;  	printf("请输入学生的具体资料："); 	printf("\n"); 	for (i = 0; i < t; ++i) 	{ 		//printf("第%d个学生的信息："，i + 1 );   //19行  error:需要英文',' 		printf("第%d个学生的信息：", i + 1); 		printf("age = "); 		scanf("%d", &(A[i].age));  		printf("fens = "); 		scanf("%d", &(A[i].fens));  		getchar();    //读入回车，必须的 		printf("sex = "); 		//scanf("%d", &(*A[t]).sex); 		scanf("%c", &(A[i].sex)); 	} }  int main(void) { 	int len; 	struct xues * p; 	int t; 	printf("请输入学生的个数："); 	scanf("%d", &len);  	p = (struct xues *)malloc(len * sizeof(struct xues)); 	printf("\n");  	f(p, len);  	printf("华丽的分割线\n");  	for (t = 0; t < len; ++t) 	{ 		printf("第%d个学生的信息是：\n", t + 1); 		//printf("age = %d, fens = %d, sex = %d\n", p[t].age, p[t].age, p[t].sex); 		printf("age = %d, fens = %d, sex = %c\n", p[t].age, p[t].fens, p[t].sex); 	} 	//释放内存 	free(p); 	system("pause"); 	return 0; } //f->female, m->male //请输入学生的个数：3 //请输入学生的具体资料： //第1个学生的信息：age = 12 //fens = 89 //sex = f //第2个学生的信息：age = 13 //fens = 92 //sex = m //第3个学生的信息：age = 13 //fens = 88 //sex = f //华丽的分割线 //第1个学生的信息是： //age = 12, fens = 89, sex = f //第2个学生的信息是： //age = 13, fens = 92, sex = m //第3个学生的信息是： //age = 13, fens = 88, sex = f

十九行逗号是中文的, 改成,就好了 后面的(*A)[i]形成(*A)[t]了, *A外面加个括号 		scanf("%d", &((*A)[i].age));  		printf("fens = "); 		scanf("%d", &((*A)[i].fens));  		printf("sex = "); 		scanf("%d", &((*A)[i].sex));


Question: 递归逆序输出带有头结点链表问题，求解决

你这是不带头结点啊，那么带头结点呢

int inverseListWithoutHead(LinkList L) {         return inverseList(L-next); }  main函数直接inverseListWithoutHead（L）


Question: 利用指针交换两者数据，这样为什么运行就显示11db?

#define SWAP(a,b)  ((&(a))!=(&(b)))?((a)^=(b)^=(a)^=(b)):(1);

void exchange(float *num1 ,float *num2) {        float *temp = new float  ; \\要分配空间      *temp= *num1;           *num1 = *num2;           *num2 = *temp;      delete c;     }

更改如下：  #include <stdio.h> void exchange(float *num1, float *num2); int main(int argc, const char * argv[]) {  	float a = 10.5; 	float b = 18.8; 	exchange(&a, &b); 	printf("a=%.1f,b=%.1f\n", a, b); 	system("pause"); 	return 0; } void exchange(float *num1, float *num2) { 	//float *temp;   //指针都没有指向，后面如何使用 	float temp;      //这里只需使用简单类型即可 	temp = *num1; 	*num1 = *num2; 	*num2 = temp; } //a=18.8,b=10.5

#include <stdio.h>  void exchange(float *num1, float *num2);   int main(int argc, const char * argv[]) {  	float a = 10.5f;  	float b = 18.8f;  	exchange(&a, &b);  	printf("a=%.1f,b=%.1f\n", a, b);  	getchar();  	return 0; }  void exchange(float *num1, float *num2) {  	float temp;  	temp = *num1;  	*num1 = *num2;  	*num2 = temp;  }

仅供参考：#include <stdio.h> #define SWAP(a,b) do ((&(a))!=(&(b)))?((a)^=(b)^=(a)^=(b)):((a)=(a)); while (0) char   *p1="1" ,*p2="2" ; char    c1=1   , c2=2   ; short   s1=1   , s2=2   ; int     i1=1   , i2=2   ; __int64 I1=1i64, I2=2i64; float   f1=1.0f, f2=2.0f; double  d1=1.0 , d2=2.0 ; void main() {     SWAP((int)p1,(int)p2);                printf("char *     %5s,   %5s\n",p1,p2);     SWAP(c1,c2);                          printf("char       %5d,   %5d\n",c1,c2);     SWAP(s1,s2);                          printf("short      %5d,   %5d\n",s1,s2);     SWAP(i1,i2);                          printf("int        %5d,   %5d\n",i1,i2);     SWAP(I1,I2);                          printf("__int64 %5I64d,%5I64d\n",I1,I2);     SWAP(*(int     *)&f1,*(int     *)&f2);printf("float      %5g,   %5g\n",f1,f2);     SWAP(*(__int64 *)&d1,*(__int64 *)&d2);printf("double    %5lg,  %5lg\n",d1,d2);      SWAP(c1,c1);     printf("%d\n",c1); } //char *         2,       1 //char           2,       1 //short          2,       1 //int            2,       1 //__int64     2,    1 //float          2,       1 //double        2,      1 //2


Question: 为什么1取反获得的是-2

取反用无符号类型

楼主想要的功能应该是非运算符吧，要写成： !x   而不是：~x  ~是按位的，就是在你的数对应的二进制上，如果是0变成1，如果是1变成0  而非则是你想要的效果

我俩终于达成一致了！

引用 33 楼 zhao4zhong1 的回复:[quote=引用 32 楼 sholber 的回复:] [quote=引用 31 楼 zhao4zhong1 的回复:] 不得不承认：  有那么些人喜欢或者适合用“先具体再抽象”的方法学习和理解复杂事物；  而另一些人喜欢或者适合用“先抽象再具体”的方法学习和理解复杂事物。 zhao4zhong1属前者； sholber属后者。  这么说来，zhao4zhong1在诞生之初，在见到万物之前，就已经在脑海里抽象出了万物。Really ?[/quote] 佛教的轮回转世学说就是这么诞生的。[/quote]  那是因为你没喝孟婆汤。

引用 34 楼 zhao4zhong1 的回复:电脑内存或文件内容只是一个一维二进制字节数组及其对应的二进制地址； 人脑才将电脑内存或文件内容中的这个一维二进制字节数组及其对应的二进制地址的某些部分看成是整数、有符号数/无符号数、浮点数、复数、英文字母、阿拉伯数字、中文/韩文/法文……字符/字符串、汇编指令、函数、函数参数、堆、栈、数组、指针、数组指针、指针数组、数组的数组、指针的指针、二维数组、字符点阵、字符笔画的坐标、黑白二值图片、灰度图片、彩色图片、录音、视频、指纹信息、身份证信息……  推荐使用WinHex软件查看硬盘或文件或内存中的原始字节内容。  相由心生  还有人说电脑里面没有字节、地址、……；只有PN结、电场、电流、…… 还有人说电脑里面没有PN结、电场、电流、……；只有质子、中子、电子、夸克、…… 还有人说电脑里面没有质子、中子、电子、夸克、……；只有…… ……  对了，最后一句我来补：只有弦。

引用 32 楼 sholber 的回复:[quote=引用 31 楼 zhao4zhong1 的回复:] 不得不承认：  有那么些人喜欢或者适合用“先具体再抽象”的方法学习和理解复杂事物；  而另一些人喜欢或者适合用“先抽象再具体”的方法学习和理解复杂事物。 zhao4zhong1属前者； sholber属后者。  这么说来，zhao4zhong1在诞生之初，在见到万物之前，就已经在脑海里抽象出了万物。Really ?[/quote] 佛教的轮回转世学说就是这么诞生的。

引用 31 楼 zhao4zhong1 的回复:不得不承认：  有那么些人喜欢或者适合用“先具体再抽象”的方法学习和理解复杂事物；  而另一些人喜欢或者适合用“先抽象再具体”的方法学习和理解复杂事物。 zhao4zhong1属前者； sholber属后者。  这么说来，zhao4zhong1在诞生之初，在见到万物之前，就已经在脑海里抽象出了万物。Really ?

引用 29 楼 zhao4zhong1 的回复:[quote=引用 28 楼 sholber 的回复:] [quote=引用 27 楼 zhao4zhong1 的回复:] 好象、好象、…… https://www.baidu.com/link?url=XEX9wA0ujvWr6y8c9ErJ6EN6awTECiUJ93_lWXkrrKQviRxgGntedeJQ2K0ZBfNvVBSWxrjYwnnzG7Y0dT5ivq&wd=%E7%B2%BE%E7%A1%AE%20%E2%80%9C%E5%88%BB%E4%B8%80%E4%B8%AA%E7%82%B9%E2%80%9D%20%E8%A1%A8%E7%A4%BA%20%E5%A4%A7%E8%8B%B1%E7%99%BE%E7%A7%91%E5%85%A8%E4%B9%A6&issp=1&f=8&ie=utf-8&tn=baiduhome_pg&inputT=10230  我认为赵老湿永远画不出这个点——即使是在理论上。原因很简单： 在你决定画这个点之前，并计算好这个点的位置时，宇宙的信息就已经增加了：你的思想活动，以及画这个点的过程，如此等等，都影响了你要画的点的位置。每当你再次修正这个点的位置时，这个修正的过程将再次影响到点的位置。 不管怎么说，WinXP32是客观存在的，但赵老湿有生之年决画不出这个点来——即使是在理论上。 所以，赵老湿该反思一下自己的治学思想了。[/quote] 根据你的治学思想，兔子永远追不上乌龟，因为每当兔子到达乌龟刚才的位置时，乌龟已经往前爬了那么一丢丢！[/quote] 正是如此。你的画点容纳世界，不正是这种思想吗！ 反正谁也画不出这个点，在思想的世界里说东说西，谁不会啊。

引用 28 楼 sholber 的回复:[quote=引用 27 楼 zhao4zhong1 的回复:] 好象、好象、…… https://www.baidu.com/link?url=XEX9wA0ujvWr6y8c9ErJ6EN6awTECiUJ93_lWXkrrKQviRxgGntedeJQ2K0ZBfNvVBSWxrjYwnnzG7Y0dT5ivq&wd=%E7%B2%BE%E7%A1%AE%20%E2%80%9C%E5%88%BB%E4%B8%80%E4%B8%AA%E7%82%B9%E2%80%9D%20%E8%A1%A8%E7%A4%BA%20%E5%A4%A7%E8%8B%B1%E7%99%BE%E7%A7%91%E5%85%A8%E4%B9%A6&issp=1&f=8&ie=utf-8&tn=baiduhome_pg&inputT=10230  我认为赵老湿永远画不出这个点——即使是在理论上。原因很简单： 在你决定画这个点之前，并计算好这个点的位置时，宇宙的信息就已经增加了：你的思想活动，以及画这个点的过程，如此等等，都影响了你要画的点的位置。每当你再次修正这个点的位置时，这个修正的过程将再次影响到点的位置。 不管怎么说，WinXP32是客观存在的，但赵老湿有生之年决画不出这个点来——即使是在理论上。 所以，赵老湿该反思一下自己的治学思想了。[/quote] 根据你的治学思想，兔子永远追不上乌龟，因为每当兔子到达乌龟刚才的位置时，乌龟已经往前爬了那么一丢丢！

引用 27 楼 zhao4zhong1 的回复:好象、好象、…… https://www.baidu.com/link?url=XEX9wA0ujvWr6y8c9ErJ6EN6awTECiUJ93_lWXkrrKQviRxgGntedeJQ2K0ZBfNvVBSWxrjYwnnzG7Y0dT5ivq&wd=%E7%B2%BE%E7%A1%AE%20%E2%80%9C%E5%88%BB%E4%B8%80%E4%B8%AA%E7%82%B9%E2%80%9D%20%E8%A1%A8%E7%A4%BA%20%E5%A4%A7%E8%8B%B1%E7%99%BE%E7%A7%91%E5%85%A8%E4%B9%A6&issp=1&f=8&ie=utf-8&tn=baiduhome_pg&inputT=10230  我认为赵老湿永远画不出这个点——即使是在理论上。原因很简单： 在你决定画这个点之前，并计算好这个点的位置时，宇宙的信息就已经增加了：你的思想活动，以及画这个点的过程，如此等等，都影响了你要画的点的位置。每当你再次修正这个点的位置时，这个修正的过程将再次影响到点的位置。 不管怎么说，WinXP32是客观存在的，但赵老湿有生之年决画不出这个点来——即使是在理论上。 所以，赵老湿该反思一下自己的治学思想了。

引用 15 楼 zhao4zhong1 的回复:[quote=引用 13 楼 sholber 的回复:] [quote=引用 12 楼 zhao4zhong1 的回复:] [quote=引用 10 楼 sholber 的回复:] [quote=引用 9 楼 zhao4zhong1 的回复:] [quote=引用 7 楼 sholber 的回复:] [quote=引用 1 楼 zhao4zhong1 的回复:] 0x00000001 0xFFFFFFFE  这是比较狡猾的回答，但仍然有一个问题，你怎么知道它一定是0xFFFFFFFE，而不是0xFFFE？[/quote] 因为我只用WinXP 32位[/quote] 因为你在井里，你就说天只有井口那么大，这像话吗！唵！左右与我拿下赵老湿这厮[/quote] 因为你在一个超级WinXP32位系统下虚拟机里面运行的Matrix系统所控制的宇宙中，我可以说你以及你的思想都是32位的。  搜 “《黑客帝国》完全解析” “《黑客帝国》里的锡安是不是虚拟世界”[/quote]  胡说！下面冒气！ 诚如此，我们怎么会想像还有一个多层宇宙！可见我们的思想不受限于环境和时空。 [/quote] 凭什么说一个超级WinXP32位系统中装不下整个宇宙中的信息流？[/quote] 那是你说的，我可没说。不过我确定觉得它装不下。要反驳我，你需要首先告诉我宇宙里的信息有多少。

引用 13 楼 sholber 的回复:[quote=引用 12 楼 zhao4zhong1 的回复:] [quote=引用 10 楼 sholber 的回复:] [quote=引用 9 楼 zhao4zhong1 的回复:] [quote=引用 7 楼 sholber 的回复:] [quote=引用 1 楼 zhao4zhong1 的回复:] 0x00000001 0xFFFFFFFE  这是比较狡猾的回答，但仍然有一个问题，你怎么知道它一定是0xFFFFFFFE，而不是0xFFFE？[/quote] 因为我只用WinXP 32位[/quote] 因为你在井里，你就说天只有井口那么大，这像话吗！唵！左右与我拿下赵老湿这厮[/quote] 因为你在一个超级WinXP32位系统下虚拟机里面运行的Matrix系统所控制的宇宙中，我可以说你以及你的思想都是32位的。  搜 “《黑客帝国》完全解析” “《黑客帝国》里的锡安是不是虚拟世界”[/quote]  胡说！下面冒气！ 诚如此，我们怎么会想像还有一个多层宇宙！可见我们的思想不受限于环境和时空。 [/quote] 凭什么说一个超级WinXP32位系统中装不下整个宇宙中的信息流？

引用 19 楼 zhao4zhong1 的回复:[quote=引用 16 楼 sholber 的回复:] [quote=引用 15 楼 zhao4zhong1 的回复:] [quote=引用 13 楼 sholber 的回复:] [quote=引用 12 楼 zhao4zhong1 的回复:] [quote=引用 10 楼 sholber 的回复:] [quote=引用 9 楼 zhao4zhong1 的回复:] [quote=引用 7 楼 sholber 的回复:] [quote=引用 1 楼 zhao4zhong1 的回复:] 0x00000001 0xFFFFFFFE  这是比较狡猾的回答，但仍然有一个问题，你怎么知道它一定是0xFFFFFFFE，而不是0xFFFE？[/quote] 因为我只用WinXP 32位[/quote] 因为你在井里，你就说天只有井口那么大，这像话吗！唵！左右与我拿下赵老湿这厮[/quote] 因为你在一个超级WinXP32位系统下虚拟机里面运行的Matrix系统所控制的宇宙中，我可以说你以及你的思想都是32位的。  搜 “《黑客帝国》完全解析” “《黑客帝国》里的锡安是不是虚拟世界”[/quote]  胡说！下面冒气！ 诚如此，我们怎么会想像还有一个多层宇宙！可见我们的思想不受限于环境和时空。 [/quote] 凭什么说一个超级WinXP32位系统中装不下整个宇宙中的信息流？[/quote] 那是你说的，我可没说。不过我确定觉得它装不下。要反驳我，你需要首先告诉我宇宙里的信息有多少。[/quote] 我可以告诉你不用超级WinXP32位系统，只要一个普通WinXP32位系统，里面就可以运行GMP库了。[/quote]  如果需要，赵老湿随时可以切换概念和内涵和外延，其娴熟程度不亚于WinXP32位系统的进程切换。

引用 23 楼 my_live_123 的回复:[quote=引用 20 楼 zhao4zhong1 的回复:] [quote=引用 16 楼 sholber 的回复:] [quote=引用 15 楼 zhao4zhong1 的回复:] [quote=引用 13 楼 sholber 的回复:] [quote=引用 12 楼 zhao4zhong1 的回复:] [quote=引用 10 楼 sholber 的回复:] [quote=引用 9 楼 zhao4zhong1 的回复:] [quote=引用 7 楼 sholber 的回复:] [quote=引用 1 楼 zhao4zhong1 的回复:] 0x00000001 0xFFFFFFFE  这是比较狡猾的回答，但仍然有一个问题，你怎么知道它一定是0xFFFFFFFE，而不是0xFFFE？[/quote] 因为我只用WinXP 32位[/quote] 因为你在井里，你就说天只有井口那么大，这像话吗！唵！左右与我拿下赵老湿这厮[/quote] 因为你在一个超级WinXP32位系统下虚拟机里面运行的Matrix系统所控制的宇宙中，我可以说你以及你的思想都是32位的。  搜 “《黑客帝国》完全解析” “《黑客帝国》里的锡安是不是虚拟世界”[/quote]  胡说！下面冒气！ 诚如此，我们怎么会想像还有一个多层宇宙！可见我们的思想不受限于环境和时空。 [/quote] 凭什么说一个超级WinXP32位系统中装不下整个宇宙中的信息流？[/quote] 那是你说的，我可没说。不过我确定觉得它装不下。要反驳我，你需要首先告诉我宇宙里的信息有多少。[/quote] 再看看好象是《从一到无穷大》手中说的：“在一根棍上足够精确地刻一个点，就可以表示正本大英百科全书的信息了。”[/quote]  无穷大是一个概念但不是一个特指概念！不是一个客观实体，也不是一个数！是数学分支中的东东！牵涉到极限等等！ LZ引用的这句话是作者对抽象无穷大的一种牵强的“示例”，帮助“理解”作用，不能从字面上理解！示例的作用只是想描述一个“量”十分大的概念，然后“解释”无穷大怎么理解！其实这样做反而偏离了概念的本质！至于它的正确性，如何精确刻点，一个客体的信息量如何度量，有待考证！其实无穷大还是要从实数论上来理解最为合适。  记得在学校的时候老师就曾告诫我们学<实变函数>不要往世界中“看到”的东西拿来理解书中的理论。因为任何"具化"工作在这里都是对抽象理论的“误解”！我们都是从欧几里德空间开始我们的人生学习生涯的，这个空间和我们生活的世界是保持一致的，类比也是我们学习的主要方式！比如球体和乒乓球，长方体和积木等等，这就是抽象到具体，帮助我们理解世界的一个很好的方式！但是，随着数学深入，会发现太多的抽象概念是没法具化的！其中就包括“无穷大”以及“正无穷大”和“负无穷大”！  声明：就事论事，阐述个人观点而已！不中，权当没说！[/quote]  这也正是我想说的。嘎嘎~~ 赵老湿一贯如此。这是他的治学特色。  PS：如果我没说错的话，《从一到无穷大》里没有这句话。那不是伽莫夫所说的。

引用 20 楼 zhao4zhong1 的回复:[quote=引用 16 楼 sholber 的回复:] [quote=引用 15 楼 zhao4zhong1 的回复:] [quote=引用 13 楼 sholber 的回复:] [quote=引用 12 楼 zhao4zhong1 的回复:] [quote=引用 10 楼 sholber 的回复:] [quote=引用 9 楼 zhao4zhong1 的回复:] [quote=引用 7 楼 sholber 的回复:] [quote=引用 1 楼 zhao4zhong1 的回复:] 0x00000001 0xFFFFFFFE  这是比较狡猾的回答，但仍然有一个问题，你怎么知道它一定是0xFFFFFFFE，而不是0xFFFE？[/quote] 因为我只用WinXP 32位[/quote] 因为你在井里，你就说天只有井口那么大，这像话吗！唵！左右与我拿下赵老湿这厮[/quote] 因为你在一个超级WinXP32位系统下虚拟机里面运行的Matrix系统所控制的宇宙中，我可以说你以及你的思想都是32位的。  搜 “《黑客帝国》完全解析” “《黑客帝国》里的锡安是不是虚拟世界”[/quote]  胡说！下面冒气！ 诚如此，我们怎么会想像还有一个多层宇宙！可见我们的思想不受限于环境和时空。 [/quote] 凭什么说一个超级WinXP32位系统中装不下整个宇宙中的信息流？[/quote] 那是你说的，我可没说。不过我确定觉得它装不下。要反驳我，你需要首先告诉我宇宙里的信息有多少。[/quote] 再看看好象是《从一到无穷大》手中说的：“在一根棍上足够精确地刻一个点，就可以表示正本大英百科全书的信息了。”[/quote]  无穷大是一个概念但不是一个特指概念！不是一个客观实体，也不是一个数！是数学分支中的东东！牵涉到极限等等！ LZ引用的这句话是作者对抽象无穷大的一种牵强的“示例”，帮助“理解”作用，不能从字面上理解！示例的作用只是想描述一个“量”十分大的概念，然后“解释”无穷大怎么理解！其实这样做反而偏离了概念的本质！至于它的正确性，如何精确刻点，一个客体的信息量如何度量，有待考证！其实无穷大还是要从实数论上来理解最为合适。  记得在学校的时候老师就曾告诫我们学<实变函数>不要往世界中“看到”的东西拿来理解书中的理论。因为任何"具化"工作在这里都是对抽象理论的“误解”！我们都是从欧几里德空间开始我们的人生学习生涯的，这个空间和我们生活的世界是保持一致的，类比也是我们学习的主要方式！比如球体和乒乓球，长方体和积木等等，这就是抽象到具体，帮助我们理解世界的一个很好的方式！但是，随着数学深入，会发现太多的抽象概念是没法具化的！其中就包括“无穷大”以及“正无穷大”和“负无穷大”！  声明：就事论事，阐述个人观点而已！不中，权当没说！

2楼正解  引用 2 楼 zhangxiangDavaid 的回复: 32位 0000 0000 0000 0000 0000 0000 0000 0001(1的补码) 取反 1111 1111 1111 1111 1111 1111 1111 1110 为了知道上述二进制代表的真实大小 减一得反码 1111 1111 1111 1111 1111 1111 1111 1101 取反(符号为不变)得原码 1000 0000 0000 0000 0000 0000 0000 0010 这即是-2的原码


Question: scrollwindow问题

这种试一下就知道了

谁的hwbd谁滚吧


Question: 菜鸟关于文件读写的三个问题

a+ 打开文件不会把原来的文件内容清楚，所以你运行一次，文件的内容都会增加。 just so

1. 统计有多少行 2. 只是输出显示,对于溢出..其有依赖于 中间的那行输入 while (gets(words) != NULL  && words[0] != '\0')  对于溢出处理,不管输入/输出都要作长度限制.这是比较有效的处理方法 //////-------------------------------------------------------- 对于 fp = fopen("wordy", "a+"); ....这里的 "a+" ,这是一个以添加读写式打开/创建一个文件. 其内部文件读指针与文件写指针是不同步的 文件读指针: 开始指向 位置 0 (有些环境会指出文件结尾 - -!!!) , 对于 fseek 等操作有效 文件写指针: 始终指向文件结尾,  不受 fseek等操影响  //------------------------------ 所以最后的输出之前需要rewind()

fgets(words,39,fp) != NULL;改为fgets(words,40,fp) != NULL;最多读入40-1=39个字节，其它的1楼正解

#include <stdio.h> #include <stdlib.h> int main(void)  { 	FILE *fp; 	char words[40]; 	int count = 0; 	fp = fopen("wordy", "a+"); 	while ( fgets(words,39,fp) != NULL)   //读文件内容 存到words 	{ 		count++; 		printf("words = [%s]\n", words); 	} 	while (gets(words) != NULL  && words[0] != '\0')//读标准输入 	{ 		fprintf(fp, "%d:%s\n", count++, words); //写入文件 	} 	rewind(fp);                                       //回到文件开头 	while (fscanf(fp,"%s",words) == 1)                //读文件内容到 words  每次读一个字符串,当输入字符串的长度超过40时发生错误 		puts(words);         	fclose(fp); 	return 0; }


Question: 新手写日历，发现越调试错误越多

1 #include<stdio.h>   2 #include<string.h>   3 #include<time.h>   4 #include<math.h>   5    6 int nmonth[13] = {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};   7    8 long since(int year, int month, int day);   9   10   11 int main()  12 {  13         long    sum_day_1;  14         long    sum_day_2;  15         int     gap;  16         int     e_year, e_month, e_day, e_wday;  17         struct  tm *tp;  18         long    t0;  19         int     e_date;  20         int     remainder;  21         int     i, j;  22         int     m;  23         int     first_wday;  24   25         remainder                       = 0;  26         first_wday                      = 0;  27         e_year, e_month, e_day, e_wday  = 0;  28         sum_day_1 = sum_day_2           = 0;  29   30         printf("Please enter the year month day before today:(seperate wi    th blank)\n");  31   32         e_date  =scanf("%d%d%d", &e_year, &e_month, &e_day);  33   34         //Get current time  35         t0      = time(NULL);  36   37         //Get current struct time 38         tp      = localtime(&t0);  39   40         //Calculate the day from beginning by using function since  41         sum_day_1       = since(tp->tm_year+1900, tp->tm_mon+1, tp->tm_md    ay);  42         sum_day_2       = since(e_year, e_month, e_day);  43   44         //Calculate the gap between 2 days  45         gap             = sum_day_1 - sum_day_2;  46   47         //Calculate the remainder of the gap  48         remainder       = gap % 7;  49   50         //Calculate the weekday of the enter day  51         if(tp->tm_wday  == 0){  52                 if(remainder    ==0)  53                         e_wday  = 0;  54                 else  55                         e_wday  = 7 - remainder;  56         }  57         else if (tp->tm_wday >= remainder)  58                 e_wday  = tp->tm_wday - remainder;  59         else if (0 < tp->tm_wday < remainder)  60                 e_wday  = 7 - (remainder - tp->tm_wday) ;  61   62         if(e_wday == 7)  63                 e_wday == 0;  64   65         //Printf the title of the week  66         printf("Mon Tue Wed Thu Fri Sat Sun\n");  67   68         //Calculate the weekday of the first day in the month  69         if(e_wday != 0){  70                 if(e_day < e_wday)  71                         first_wday = e_wday - e_day + 1;  72                 else  73                         first_wday = 8 - (abs(e_day - e_wday) % 7); 74         }  75         else  76                 first_wday = 8 - (e_day % 7);  77   78         if (first_wday == 7)  79                 first_wday = 0;  80         if (first_wday == 8)  81                 first_wday = 1;  82   83         //Calculate the empty date of the month in calender  84         if(first_wday   != 0){  85                 for(i = 1; i < first_wday; ++i)  86                         printf("    ");  87         }  88         else  89                 for(i = 1; i <= 6; ++i)  90                         printf("    ");  91   92         i = i -1 ;//Easy for next step to do  93   94         //Enter thr current calender  95         for(m =1; m <= nmonth[e_month]; ++m){  96                 if(i % 7 == 0 )  97                         printf("\n");  98                 ++i;  99                 { 100                 if(m    == e_day) 101                         printf("[%2d]", e_day); 102                 else 103                         printf(" %2d ", m); 104                 } 105         } 106         //When leep year plus 29 to January 107         if((e_year % 4 == 0 && e_year % 100 != 0 || e_year % 400 == 0) &&     e_month ==2) 108                  printf(" %2d ", 29); 109          printf("\n"); 110  111          return 0; 112  113 } 114  115 //Calculate the day since biginning 116 long since(int year, int month, int day) 117 { 118         long    sum; 119         int     i, j; 120         sum     =0; 121  122         for(i = 0; i < year; ++i){ 123                 if(i % 4 == 0 && i % 100 != 0 || i % 400 == 0) 124                 sum += 366; 125                 else 126                 sum += 365; 127         } 128  129         if(year % 4 == 0 && year % 100 != 0 || year % 400 == 0){ 130                 for(j = 1; j < month; ++j) 131                         sum += nmonth[j]; 132                 if(month > 2) 133                         sum += 1; 134         } 135         else 136                 for(j = 1; j < month; ++j) 137                         sum += nmonth[j]; 138  139         sum     = sum + day; 140  141         return  sum; 142  143 } 144     非常感谢你的代码。 我睡觉前会仔细研究一下的。 不过我自己通过gdb已经发现了自己代码中存在的问题  并且也重新整理了格式， 只是这个算法是我自己想得太水乐。 目前只能实现在今天之前的日历打印。 不过我还是很开心。  好拉， 关电脑， 研究您的代码了~

#include<stdio.h> #include<time.h> #include<string.h> #include<math.h> #include <stdlib.h>  long since(int year, int month, int day); int empty(int year);  int nmonth[13] = { 0,31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };  int main() {     long    sum_day_1;     long    sum_day_2;     int     gap;     int     e_year, e_month, e_day, e_wday;     struct  tm *tp;     time_t    t0;     int     e_date;     int     remainder;     int i, j;     int m;     int first_wday;     remainder = 0;     first_wday = 0;     e_year = 0;     e_month = 0;     e_day = 0;     e_wday = 0;      printf("Please inter year month day:(seperate with blank)\n");     e_date = scanf("%d%d%d", &e_year, &e_month, &e_day);      sum_day_1 = sum_day_2 = gap = 0;      //Get current time     t0 = time(NULL);      //Get current struct time     tp = localtime(&t0);      printf("mday = %d\n", tp->tm_mday);      //Because of my US time have to plus 4 to tm_day     sum_day_1 = since(tp->tm_year + 1900, tp->tm_mon + 1, tp->tm_mday);     sum_day_2 = since(e_year, e_month, e_day);      gap = abs(sum_day_1 - sum_day_2);      printf("mwday = %d\n", tp->tm_wday);     printf("gap = %d\n", gap);      //Calulate the remainder of the gap % 7     remainder = gap % 7;      if (tp->tm_wday == 0)         e_wday = remainder;     else if (tp->tm_wday > remainder)         e_wday = tp->tm_wday - remainder;     else if (0 < tp->tm_wday && tp->tm_wday < remainder)         e_wday = 7 - abs((tp->tm_wday - remainder));      if (e_wday == 7)         e_wday = 0;      printf("remainder = %d\n", remainder);     printf("e_wday = %d\n", e_wday);      printf("Mon Tue Wed Thu Fri Sat Sun \n");       //int empty(int tm.tm_wday, int remainder);      //Calculate the weekday of the first day in the month     if (e_wday != 0) {         if (e_day < e_wday)             first_wday = e_wday - e_day;         else             first_wday = 8 - (abs(e_day - e_wday) % 7);     }     else         first_wday = 8 - (e_day % 7);      printf("first_wday = %d\n", first_wday);      if (first_wday == 7)         first_wday = 0;     //      if (first_wday == 8)     //              first_wday = 1;      //Calculate the empty date of the month in calendar     if (first_wday != 0) {         for (i = 1; i < first_wday; ++i)             printf("    ");     }     else         for (i = 1; i <= 6; ++i)             printf("    ");      i = i - 1;     //      printf("remainder = %d\n",remainder);      //enter thr current calender     for (m = 1; m <= nmonth[e_month]; ++m) {         //      for(i = i-1; i <= nmonth[e_month]; ++i)         if (i % 7 == 0)             printf("\n");         ++i;         {             if (m == e_day)                 printf("[%2d]", e_day);             else                 printf(" %2d ", m);         }     }       if ((e_year % 4 == 0 && e_year % 100 != 0 || e_year % 400 == 0) && e_month == 2)         printf(" %2d ", 29);      printf("\n");     fflush(stdin);     getchar();     return  0; }  //calculate the days since the biginning day to the specific day long since(int year, int month, int day) {      long sum;     int  i, j;     sum = 0;     for (i = 1; i < year; ++i) {         if (i % 4 == 0 && i % 100 != 0 || i % 400 == 0)             sum += 366;// leap year         else             sum += 365;// not leap year     }      if (year % 4 == 0 && year % 100 != 0 || year % 400 == 0) {         // leap year         for (j = 1; j < month; ++j)             sum += nmonth[j];         sum += 1;     }     else         for (j = 1; j < month; ++j)             sum += nmonth[j];     sum += 365;// not leap year     sum = sum + day;      return sum; }

引用 2 楼 user-1 的回复:// console.cpp : Defines the entry point for the console application. //  #include "stdafx.h" #include<stdio.h> #include<time.h> #include<string.h> #include<math.h>   long since(int year, int month, int day); int empty(int year);  int nmonth[13] = { 0,31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };  int main() { 	long    sum_day_1; 	long    sum_day_2; 	int     gap; 	int     e_year, e_month, e_day, e_wday; 	struct  tm tm; 	time_t    t0; 	int     e_date; 	int     remainder; 	int i, j; 	int m; 	int first_wday; 	remainder = 0; 	first_wday = 0; 	e_year, e_month, e_day, e_wday = 0;  	printf("Please inter year month day:(seperate with blank)\n"); 	e_date = scanf_s("%d%d%d", &e_year, &e_month, &e_day);  	sum_day_1 = sum_day_2 = gap = 0;  	//Get current time 	t0 = time(NULL);  	//Get current struct time 	 localtime_s(&tm, &t0);  	printf("mday = %d\n", tm.tm_mday);  	//Because of my US time have to plus 4 to tm_day 	sum_day_1 = since(tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday); 	sum_day_2 = since(e_year, e_month, e_day);  	gap = abs(sum_day_1 - sum_day_2);  	printf("mwday = %d\n", tm.tm_wday); 	printf("gap = %d\n", gap);  	//Calulate the remainder of the gap % 7 	remainder = gap % 7;  	if (tm.tm_wday == 0) 		e_wday = remainder; 	else if (tm.tm_wday > remainder) 		e_wday = tm.tm_wday - remainder; 	else if (0 < tm.tm_wday && tm.tm_wday < remainder) 		e_wday = 7 - abs((tm.tm_wday - remainder));  	if (e_wday = 7) 		e_wday = 0;  	printf("remainder = %d\n", remainder); 	printf("e_wday = %d\n", e_wday);  	printf("Sun Mon Tue Wed Thu Fri Sat\n");   	//int empty(int tm.tm_wday, int remainder);  	//Calculate the weekday of the first day in the month 	if (e_wday != 0) { 		if (e_day < e_wday) 			first_wday = e_wday - e_day; 		else 			first_wday = 8 - (abs(e_day - e_wday) % 7); 	} 	else 		first_wday = 8 - (e_day % 7);  	printf("first_wday = %d\n", first_wday);  	if (first_wday == 7) 		first_wday = 0; 	//      if (first_wday == 8) 	//              first_wday = 1;  	//Calculate the empty date of the month in calendar 	if (first_wday != 0) { 		for (i = 1; i < first_wday; ++i) 			printf("    "); 	} 	else 		for (i = 1; i <= 6; ++i) 			printf("    ");  	i = i - 1; 	//      printf("remainder = %d\n",remainder);  	//enter thr current calender 	for (m = 1; m <= nmonth[e_month]; ++m) { 		//      for(i = i-1; i <= nmonth[e_month]; ++i) 		if (i % 7 == 0) 			printf("\n"); 		++i; 		{ 			if (m == e_day) 				printf("[%2d]", e_day); 			else 				printf(" %2d ", m); 		} 	}   	if ((e_year % 4 == 0 && e_year % 100 != 0 || e_year % 400 == 0) && e_month == 2) 		printf(" %2d ", 29);  	printf("\n"); 	fflush(stdin); 	getchar(); 	return  0; }  //calculate the days since the biginning day to the specific day long since(int year, int month, int day) {  	long sum; 	int  i, j; 	sum = 0; 	for (i = 1; i < year; ++i) { 		if (i % 4 == 0 && i % 100 != 0 || i % 400 == 0) 			sum += 366;// leap year 		else 			sum += 365;// not leap year 	}  	if (year % 4 == 0 && year % 100 != 0 || year % 400 == 0) { 		// leap year 		for (j = 1; j < month; ++j) 			sum += nmonth[j]; 		sum += 1; 	} 	else 		for (j = 1; j < month; ++j) 			sum += nmonth[j]; 	sum += 365;// not leap year 	sum = sum + day;  	return sum; }   linux 中GCC 编译 报错呀。

1 #include<stdio.h>   2 #include<time.h>   3 #include<string.h>   4 #include<math.h>   5    6 long since(int year, int month, int day);   7 int empty(int year);   8    9 int nmonth[13] = {0,31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};  10   11 int main()  12 {  13         long    sum_day_1;  14         long    sum_day_2;  15         int     gap;  16         int     e_year, e_month, e_day, e_wday;  17         struct  tm *tp;  18         long    t0;  19         int     e_date;  20         int     remainder;  21         int i, j;  22         int m;  23         int first_wday;  24         remainder       =0;  25         first_wday      =0;  26         e_year, e_month, e_day, e_wday  = 0;  27   28         printf("Please inter year month day:(seperate with blank)\n");  29         e_date  =scanf("%d%d%d", &e_year, &e_month, &e_day);  30   31         sum_day_1 = sum_day_2 = gap = 0;  32   33         //Get current time  34         t0      = time(NULL);  35   36         //Get current struct time  37         tp      = localtime(&t0);  38   39         printf("mday = %d\n", tp->tm_mday);  40   41         //Because of my US time have to plus 4 to tm_day  42         sum_day_1 = since(tp->tm_year+1900, tp->tm_mon+1, tp->tm_mday);  43         sum_day_2 = since(e_year, e_month, e_day);  44   45         gap = abs(sum_day_1 - sum_day_2); 46   47         printf("mwday = %d\n",tp->tm_wday);  48         printf("gap = %d\n",gap);  49   50         //Calulate the remainder of the gap % 7  51         remainder       = gap % 7;  52   53         if(tp->tm_wday == 0)  54         e_wday  = remainder;  55         else if (tp->tm_wday > remainder)  56         e_wday  = tp->tm_wday - remainder;  57         else if (0 < tp->tm_wday < remainder)  58         e_wday  = 7 - abs((tp->tm_wday - remainder)) ;  59   60         if(e_wday = 7)  61                 e_wday == 0;  62   63         printf("remainder = %d\n",remainder);  64         printf("e_wday = %d\n", e_wday);  65   66         printf("Mon Tue Wed Thu Fri Sat Sun\n");  67   68   69                      //int empty(int tp->tm_wday, int remainder);  70   71         //Calculate the weekday of the first day in the month  72         if(e_wday != 0){  73                 if(e_day < e_wday)  74                         first_wday = e_wday - e_day;  75                 else  76                 first_wday = 8 - (abs(e_day - e_wday) % 7);  77         }  78         else  79                 first_wday = 8 - (e_day % 7);  80   81         printf("first_wday = %d\n", first_wday);  82   83         if (first_wday == 7)  84                 first_wday = 0;  85 //      if (first_wday == 8)  86 //              first_wday = 1;  87   88         //Calculate the empty date of the month in calendar 89         if(first_wday   != 0){  90                 for(i = 1; i < first_wday; ++i)  91                         printf("    ");  92                 }  93         else  94                 for(i = 1; i <= 6; ++i)  95                         printf("    ");  96   97         i = i -1 ;  98 //      printf("remainder = %d\n",remainder);  99  100         //enter thr current calender 101         for(m =1; m <= nmonth[e_month]; ++m){ 102         //      for(i = i-1; i <= nmonth[e_month]; ++i) 103                 if(i % 7 == 0 ) 104                         printf("\n"); 105                 ++i; 106                 { 107                 if(m    == e_day) 108                         printf("[%2d]", e_day); 109                 else 110                         printf(" %2d ", m); 111                 } 112         } 113  114  115         if((e_year % 4 == 0 && e_year % 100 != 0 || e_year % 400 == 0) && e__     month ==2) 116                 printf(" %2d ", 29); 117  118         printf("\n"); 119  120         return  0; 121 } 122  123 //calculate the days since the biginning day to the specific day 124 long since(int year, int month, int day) 125 { 126  127         long sum; 128         int  i, j; 129         sum     = 0; 130         for(i = 1; i < year; ++i){ 131                 if(i % 4 == 0 && i % 100 != 0 || i % 400 == 0) 132                         sum += 366;// leap year 133                 else 134                         sum += 365;// not leap year 135         } 136  137         if(year % 4 == 0 && year % 100 != 0 || year % 400 == 0){ 138                 // leap year 139                 for(j = 1; j < month; ++j) 140                         sum += nmonth[j]; 141                 sum += 1; 142         } 143         else 144                 for(j = 1; j < month; ++j) 145                         sum += nmonth[j]; 146                 sum += 365;// not leap year 147         sum = sum + day; 148  149                 return sum; 150 }


Question: 威慑么

(-1) ^ (i + 1)     // 这里的^表示的是异或运算，并不乘幂 仅供参考：  #include<stdio.h> double sum(int n) { 	int i, flag; 	double a, s; 	i = flag = 1; 	a = 1; 	s = 0; 	while (i <= n) 	{ 		s += flag / a; 		a++; 		flag = -flag; 		i++; 	} 	return s; } int main(void) { 	int n; 	scanf("%d", &n); 	double s; 	s = sum(n); 	printf("s=%.1f\n", s);  //保留一位小数输出 	return 0; } //2 //s=0.5 //3 //s=0.8 //4 //s=0.6


Question: 【新手求助】 关于指针 数组 函数之间的一个问题

引用 4 楼 ViviaN_0214 的回复:[quote=引用 2 楼 relaxisland 的回复:] p[d]  等价于 *(p+d) 因此     *i[2] = 3;  的正确写法是  （*i）[2] = 3;    谢谢大牛~ 能问问具体的原因么？ *i等价于p   *i[2] 等价于 p[2]  这里的* i 要用括号 括起来的原因是什么 能给详细说说么 感激不尽！[/quote] 1+2=3 所以1+2 * 2 = 3*2 = 6吗

引用 2 楼 relaxisland 的回复:p[d]  等价于 *(p+d) 因此     *i[2] = 3;  的正确写法是  （*i）[2] = 3;    谢谢大牛~ 能问问具体的原因么？ *i等价于p   *i[2] 等价于 p[2]  这里的* i 要用括号 括起来的原因是什么 能给详细说说么 感激不尽！

p[d] 不等价于 *p+d

引用 5 楼 jiht594 的回复:[quote=引用 4 楼 ViviaN_0214 的回复:] [quote=引用 2 楼 relaxisland 的回复:] p[d]  等价于 *(p+d) 因此  *i[2] = 3;  的正确写法是  （*i）[2] = 3;   谢谢大牛~ 能问问具体的原因么？ *i等价于p   *i[2] 等价于 p[2]  这里的* i 要用括号 括起来的原因是什么 能给详细说说么 感激不尽！[/quote] 1+2=3 所以1+2 * 2 = 3*2 = 6吗 [/quote]  大牛今天又遇到这个类似的问题了 求帮助     昨天内个搞懂了 自己书写格式错误 缺少括号   今天这个 也是一样的书写格式错误么？  但是在main 里面 *（p+2->.b也一样不可以赋值 如果他是指向地址的话 等价于他的 另一种书写方式 咋就可以赋值了

引用 4 楼 ViviaN_0214 的回复:[quote=引用 2 楼 relaxisland 的回复:] p[d]  等价于 *(p+d) 因此     *i[2] = 3;  的正确写法是  （*i）[2] = 3;    谢谢大牛~ 能问问具体的原因么？ *i等价于p   *i[2] 等价于 p[2]  这里的* i 要用括号 括起来的原因是什么 能给详细说说么 感激不尽！[/quote] 优先级的问题，参考 C语言操作符优先级 *(解引用)优先级2比+加法优先级4高，所以*先运算

B是不是少了一个括号


Question: 八皇后问题请教

仅供参考：#include <stdio.h> int d[8][8]; int n; void queen8(int L) {     int x,y;      if (8==L) {         n++;         printf("%d\n",n);         for (y=0;y<8;y++) {             for (x=0;x<8;x++) { //              printf("%d",d[y][x]);                 if (d[y][x]) printf("■");                 else         printf("□");             }             printf("\n");         }         return;     }     for (x=0;x<8;x++) {         for (y=0;y<L;y++) {             if  (              d[y][x      ]              || (x-(L-y)>=0 && d[y][x-(L-y)])              || (x+(L-y)< 8 && d[y][x+(L-y)]))                 break;         }         if (y>=L) {             d[L][x]=1;             queen8(L+1);             d[L][x]=0;         }     } } int main() {     int y,x;     for (y=0;y<8;y++) {         for (x=0;x<8;x++) {             d[y][x]=0;         }     }     queen8(0);     return 0; }  “给定一个小点的输入，完整单步跟踪(同时按Alt+7键查看Call Stack里面从上到下列出的对应从里层到外层的函数调用历史)一遍。”是理解递归函数工作原理的不二法门！ 递归函数关注以下几个因素 ·退出条件 ·参数有哪些 ·返回值是什么 ·局部变量有哪些 ·全局变量有哪些 ·何时输出 ·会不会导致堆栈溢出

编辑下，，看书上说递归调用好像想完全弄清楚每一步很困难，只要搞清楚释放递归的条件和大致的原因即可，是这样吗。我感觉我现在对于这个问题的理解就处于这种程度上，不是完全理解每一步，但是对于这个递归这样的写法和原因算是大致的掌握了。

如果让你放，你怎么放？

这问题最好就是自己设置较少的量，单步调试几遍就会有了自己深入的理解。其他人说多了更糊涂

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

引用 2 楼 fly_dragon_fly 的回复:八皇后问题不需要象chess这样的二维数组，每行只能放一个，其实用一个a[8]保存每个列的坐标就行了。位置判断也相应简化了一点，只需要不同列，不同对角线判断 int sum,a[8]; bool isput(int r,int c) {     for(int k=0;k<r;k++)         if(a[k]==c || abs(r-k)==abs(a[k]-c))             return false;     return true; }  void queen(int r) {     for(int c=0;c<8;c++) if(isput(r,c)) {         a[r] =c;         if(r==7) { sum++;}         else queen(r+1);     } } 引用 2 楼 fly_dragon_fly 的回复:八皇后问题不需要象chess这样的二维数组，每行只能放一个，其实用一个a[8]保存每个列的坐标就行了。位置判断也相应简化了一点，只需要不同列，不同对角线判断 int sum,a[8]; bool isput(int r,int c) {     for(int k=0;k<r;k++)         if(a[k]==c || abs(r-k)==abs(a[k]-c))             return false;     return true; }  void queen(int r) {     for(int c=0;c<8;c++) if(isput(r,c)) {         a[r] =c;         if(r==7) { sum++;}         else queen(r+1);     } }  我不理解的地方就是对角线的判断，，希望能仔细的解释下，，谢谢。。