Question: float型和double型的问题

引用 13 楼 xiaohuh421 的回复:参数  有道词典结果 n. 论证；论据；争吵；内容提要 查看详细结果» 哦，是有啊，这微软真是的，好好说话不行吗，老用生僻字，头疼！

参数  有道词典结果 n. 论证；论据；争吵；内容提要 查看详细结果»

引用 2 楼 xiaohuh421 的回复:The type character is the only required format field; it appears after optional format fields.   The type character determines whether the associated argument is interpreted as a character, string, or number.   The types C and S, and the behavior of c and s with printf functions, are Microsoft extensions and are not ANSI-compatible.   printf Type Field Characters  Character Type Output Format  c int or wint_t When used with printf functions, specifies a single-byte character.  C int or wint_t When used with printf functions, specifies a wide character.  d int Signed decimal integer.  i int  Signed decimal integer.  o int  Unsigned octal integer.  u int  Unsigned decimal integer.  x int Unsigned hexadecimal integer, using "abcdef."  X int Unsigned hexadecimal integer, using "ABCDEF."  e  double Signed value having the form [ – ]d.dddd e [sign]ddd where d is a single decimal digit, dddd is one or more decimal digits, ddd is exactly three decimal digits, and sign is + or –.  E double Identical to the e format except that E rather than e introduces the exponent.  f double Signed value having the form [ – ]dddd.dddd, where dddd is one or more decimal digits.  The number of digits before the decimal point depends on the magnitude of the number, and the number of digits after the decimal point depends on the requested precision.   g double Signed value printed in f or e format, whichever is more compact for the given value and precision.  The e format is used only when the exponent of the value is less than –4 or greater than or equal to the precision argument.   Trailing zeros are truncated, and the decimal point appears only if one or more digits follow it.   G double Identical to the g format, except that E, rather than e, introduces the exponent (where appropriate).  n  Pointer to integer  Number of characters successfully written so far to the stream or buffer; this value is stored in the integer whose address is given as the argument.  p Pointer to void Prints the address of the argument in hexadecimal digits.  s String  When used with printf functions, specifies a single-byte–character string.  Characters are printed up to the first null character or until the precision value is reached.   S String When used with printf functions, specifies a wide-character string.  Characters are printed up to the first null character or until the precision value is reached. “argument”在这里是如何翻译的，我查了下只有争论一类的意思呀？

printf("Sex=%c\nScore=%d\n\n", pstu->sex, pstu->score); 改成 printf("Sex=%c\nScore=%lf\n\n", pstu->sex, pstu->score);

引用 7 楼 zhao4zhong1 的回复:printf里面的%和变量的一一对应关系 scanf里面的%和变量以及变量前加不加&的一一对应关系 是C代码中非常容易出错的地方，而且通常编译还不出错。 所以在编译源代码之前值得专门仔细检查一遍甚至多遍。 这个以后是得注意点，看来还是c++在输出上简单些，都不用这些格式控制符！

引用 6 楼 starytx 的回复:格式化输出要和对应的数据类型匹配，整型用%d,浮点型用%f,double用%lf 谢谢，这才明白，看书马虎了

引用 5 楼 mujiok2003 的回复:输出浮点数（double或float)，可以使用%f , %F, %e, %E, %g, %G ,%a , %A 输出长浮点数(long double),使用%Lf , %LF, %Le, %LE, %Lg, %LG ,%La , %LA  不要使用%d.谢谢，我查了下是有这么多的格式呀，我原来吧%d当作是输出双精度型了，马虎呀

double是双精度浮点数，它的输出应该是%f或者%lf 而你的输出用的是%d，只能输出整数部分。  至于输出为0的话，则有可能是因为字节对齐的原因。 有可能双精度浮点数用8字节表示，%d取整数的时候取到了为0的高位。

Score在输入的时候应该用%lf

Score=%d   这里全部换成%f     %d是整数.

引用 10 楼 u014496787 的回复:[quote=引用 7 楼 zhao4zhong1 的回复:] printf里面的%和变量的一一对应关系 scanf里面的%和变量以及变量前加不加&的一一对应关系 是C代码中非常容易出错的地方，而且通常编译还不出错。 所以在编译源代码之前值得专门仔细检查一遍甚至多遍。 这个以后是得注意点，看来还是c++在输出上简单些，都不用这些格式控制符！[/quote] 不用格式控制符,输出恰好是你期望的时候好说；等到输出不是你期望的时候，你会觉得还是用格式控制符更方便、更靠谱。  摒弃cin、cout 使用scanf,printf


Question: 函数多次调  声明部分是否再次执行

因为他是static变量，只初始化一次，存储区域和普通的局部变量不同

static int c=3; static就是干这个效果用的

在函数里打个断点，然后F11单步执行，可以看到static int c = 3会被跳过

因为c是静态变量。

static 不在函数栈分配内存， 首次调用时初始化。

静态变量，局部变量，全局变量的区别而已。 静态变量只有第一次调用的时候初始化。 局部非静态变量每次都要初始化

静态变量声明的问题

google C static！

static局部变量在所处模块在初次运行时进行初始化工作, 且只操作一次

因为c是static变量，static变量只初始化一次。


Question: c语言写了个线性链表算法，求助怎么再加个排序功能，不会写排序==

用stl就好了 std::list   sort

仅供参考： //假设带表头结点的单向链表头指针为head，试编写一个算法将值为5的结点插入到连接表的第k个结点前，删除第k个节点，并对该链表进行排序。 #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-> //

链表的排序，难点在于元素的交换，以及末尾位置的判断。 可设两个指针pWork，pNext 伪代码如下 pNext=pWork->next; pWork=myList; while(pWork->next!=NULL) { pNext=pWork->next; if(pWork->value>pNext->value)//比较关键值,升序 { temp=pWork->value; pWork->value=pNext->value; pNext->value=temp; } pWork=pNext; }

如果你的链表已经写好了，要排序的话，如果是冒泡排序，就从头结点开始逐个与以后的节点比较，如果符合条件就交换，然后是第二个节点、第三个节点类似的处理。

严蔚敏写的数据结构，里面有常用的几种排序的介绍，好好看看吧。


Question: 哪位大哥用过linux下的工具curl啊？

linux 下man curl不就是手册嘛

引用 1 楼 user-2 的回复:很明显校验了你的cookie或者referer 查了一下说是需要在搭建的nginx，在编译./configure时要加入 --with-http_sub_module 这个模块。。。。在nginx.conf中配置加入PUT, GET POST方法。 我们头让我实现的功能是用curl这个工具向https服务器发送一个json格式的字符串，但是查了半天只发现了能传送文件的方法。大哥有没有办法啊？？？急求啊。。。

很明显校验了你的cookie或者referer


Question: 数据结构原理与分析跟C语言没关系么？

为什么要有数据结构这个东东？ 因为要将现实世界或者抽象理论中的各种数据保存在计算机外存（光盘、硬盘、U盘……）或内存（ROM、RAM、SRAM……）里面的二进制字节数组中。 然后让CPU这个只会执行预先保存好的加减乘除移位条件转移……等机器指令的家伙按照人的意志去处理这些数据。至于具体如何处理就是所谓算法。

数据结构和算法只是用计算机解决问题时的数据化形式和实现的方法，和语言基本没有特定关系

自考数据结构原理与分析还有算法设计与分析看哪本书好呢？？？

没有关系啊，只是你可以用C语言或者c++来数据结构或者算法。如果你觉得有关系，那是什么关系呢

数据结构，算法这些和语言都没什么关系，


Question: C调用ldap api进行简单认证，无法认证成功

没有人搞过吗？

不要沉啊，


Question: 如何将jobject转换成float呢？其中jobject对应的是Float对象类型

FindClass  jfieldID fieldId   = (*env)->GetFieldID(env, objectClass, "value", "F");   jobject myobject   = score;          jmethodID methodID = (*env)->GetMethodID(env,objectClass,"floatValue","()F");   SetFloatField  大概这样

引用 1 楼 user-2 的回复:[quote=引用 楼主 lgmsyy 的回复:] JAVA ： Float x = new Float(x);  C： JNIEXPORT jint JNICALL Java_com_test(JNIEnv * env, jobject obj, ...,jobject score){ // jobject对应的是JAVA的 Float对象 请问如何将jobject的值赋值给C语言的float float fs = score;//这个地方应该如何转换呢  } jobject fScore  JNI 找到对应class，取值，再赋值，JNI API接口有对应函数。[/quote]  主要是取值，赋值那个地方如何做？

引用 1 楼 user-2 的回复:[quote=引用 楼主 lgmsyy 的回复:] JAVA ： Float x = new Float(x);  C： JNIEXPORT jint JNICALL Java_com_test(JNIEnv * env, jobject obj, ...,jobject score){ // jobject对应的是JAVA的 Float对象 请问如何将jobject的值赋值给C语言的float float fs = score;//这个地方应该如何转换呢  } jobject fScore  JNI 找到对应class，取值，再赋值，JNI API接口有对应函数。[/quote]  具体的怎么编写呢

引用 楼主 lgmsyy 的回复:JAVA ： Float x = new Float(x);  C： JNIEXPORT jint JNICALL Java_com_test(JNIEnv * env, jobject obj, ...,jobject score){ // jobject对应的是JAVA的 Float对象 请问如何将jobject的值赋值给C语言的float float fs = score;//这个地方应该如何转换呢  } jobject fScore  JNI 找到对应class，取值，再赋值，JNI API接口有对应函数。


Question: 为何需要自己管理内存

减少向系统申请和释放内存的次数。

引用 1 楼 zhao4zhong1 的回复:搜“内存池” 先谢谢啦，我去看看。csdn到处都有你的身影，大神~~

搜“内存池”


Question: 自定义函数问题，求解释

引用 楼主 u014687239 的回复: #define _STDC_WANT_LIB_EXT1_1 #include <stdio.h> #include <stdlib.h> #define MAX_COUNT 50  double Sum (double x[],size_t n) { 	double dsum=0; 	for(size_t i=0;i<n;i++) 	{ 		dsum=dsum+x[i]; 	} 	return dsum; } double average (double x[],size_t n) { 	return Sum(&x[0],n)/n; } size_t Getdata(double *data,size_t max_count) { 	size_t nvalues=0; 	printf("How many values do you want to enter(Maximum 50)?"); 	scanf("%d",&nvalues); 	if(nvalues>max_count) 	{ 		printf("maximum count exceeded . %zd items will be read.",max_count); 		nvalues=max_count; 	} 	for(size_t i=0;i<nvalues;i++) 	{ 		scanf("%d",&data[i]);//这步改为 scanf("%lf",&data[i])即可 	} 	return nvalues; }  int main () { 	double samples[MAX_COUNT]={0.0}; 	size_t samplecount=Getdata(samples,50); 	double aaverage =average(samples,samplecount); 	printf("%f",aaverage); 	system("pause"); 	return 0; }   运行结果总是0.000000，这是为什么，求解释。 看代码注释，你用double型数据来保存输入的数据，因为用%d来接收是不行的！将scanf("%d",&data[i])改为scanf("%lf",&data[i])即可

跟踪看下是哪步有问题啊，估计是求和那有问题


Question: C语言小端法排序的问题

引用 5 楼 lm_whales 的回复:87654321  本来就存储错数据了。  应该存储，0x12345678,或者0x78563412; //16  进制常量，每两个数字字符，表示一个自己的二进制 这两个是，不同字节顺序存储同一个数的结果。 不过编译器会自动调整的，只有在不同字节顺序的系统上才能看出字节顺序的区别，其实存入文件的数据最容易辨别了 一个整型存储 0x12345678在文件里，按照字符顺序读出来，在不同系统上显示，顺序是不同的。 如果真的想存储字符，这么存储。 unsigned char a[]="0x12345678"; 我明白了。 87654321  倒过来可不是就取出字节 可不就是21 2143

1.首先intel架构采用的小端存储法，故(21排在最前)低字节位排前 2.理解字节存储，21为一个字节，1存低四位，2存高四位。 不知这样能解释的通不

引用 2 楼 u012586257 的回复:你那书是错的 单字节不存在大小端，数据是21，内存里也是21，打出来还是21 我存进去的是87654321  为什么到内存里就变成这样了

你那书是错的 单字节不存在大小端，数据是21，内存里也是21，打出来还是21

我是64位的  WIN7系统


Question: 才学指针，想用指针实现一个字符串复制的函数

字符串指针不能拆开，在自定义函数中，写入s=t就行了.

移步 http://stackoverflow.com/questions/8716714/bus-error-10-error?answertab=votes#tab-top

char *s = "123456"; char *t = "111111";  这个时候，指针指向的是常量，数组的时候是变量。 常量是不能修改的。如果修改常量的值，就会有问题。

char *s =new char [10]; strcpy(s,"123456"); delete [] s;


Question: 关于指针的问题，*p和**p，实在没有理解，求教！

引用 3 楼 mcmay 的回复:[quote=引用 楼主 u014496787 的回复:] 有两段代码，都是正确的，如下： NO.1  main(){ int x,*p,**pp; x=10; p=&x; pp=&p; printf("x=%d\n",**pp); }  NO.2  main(){ static char *ps[]={ "BASIC","DBASE","C","FORTRAN", "PASCAL"}; char **pps; int i; for(i=0;i<5;i++){ pps=ps+i; printf("%s\n",*pps); } } l两段代码中最后一句分别用了**pp和*pps，明显意义不同，为何输出却又是正确的，我自己在分别修改**pp为*pp和*pps为**pps之后没有得到合理结果，求知道的解释下，万分感激！ NO1 pp = &p; p = & x; int x = 10;  ** pp = **(&p) = *p = *&x = x 而将 **pp 改为 *p后 *pp = *(&p) = p = &x != x  NO 2 char **pps pps =  ps + i *pps = *(ps + i) = ps[i]，即字符串二维数组当中的每个字符串的首地址，用%s输出，则是相应的字符串 **pps = **(ps + i) = *(ps[i]) 而ps[i] = &ps[i][0] 所以*(ps[i]) = *(&ps[i][0]) = ps[i][0] ps[i][0]是个字母，后面没跟'\0'，但用%s输出，因此结果不可预测。[/quote] 原来指针是用这样的方法分析的呀，受教了，谢谢！

引用 1 楼 bbs2241 的回复:1 我自己在分别修改**pp为*pp  *pp是什么，这是个指针，printf("x=%d\n",*pp);  %d将指针的内容打印出来了，这个指针的内容是指向x的地址的  2 和*pps为**pps之后没有得到合理结果，求知道的解释下，万分感激！  **pps是什么，是字符，printf("%s\n",**pps); %s是将字符串打印出来，而你传给print的是字符，结果是什么，oh no......... access violation有个问题，想要打印一个地址的类容使用%p,而不是%d

引用 2 楼 u014496787 的回复:[quote=引用 1 楼 bbs2241 的回复:] 1 我自己在分别修改**pp为*pp  *pp是什么，这是个指针，printf("x=%d\n",*pp);  %d将指针的内容打印出来了，这个指针的内容是指向x的地址的  2 和*pps为**pps之后没有得到合理结果，求知道的解释下，万分感激！  **pps是什么，是字符，printf("%s\n",**pps); %s是将字符串打印出来，而你传给print的是字符，结果是什么，oh no......... access violation 谢谢热心帮助，按照你的解释我理解了这样的修改是不对的，另外我也知道第一种情形是要以指针变量的方式输出数据，但是对第二种还不甚理解，*pps不是char型没错，可是难道是指针变量吗？[/quote] 刚发出去，我再看了下代码，大神帮我看下是不是这样的：“ps返回指针，ps+i返回i行即第i+1个字符串的首地址，即pps返回第i+1个字符串的地址，*pps成为指针变量型，返回地i+1个字符串。”

引用 楼主 u014496787 的回复:有两段代码，都是正确的，如下： NO.1  main(){ int x,*p,**pp; x=10; p=&x; pp=&p; printf("x=%d\n",**pp); }  NO.2  main(){ static char *ps[]={ "BASIC","DBASE","C","FORTRAN", "PASCAL"}; char **pps; int i; for(i=0;i<5;i++){ pps=ps+i; printf("%s\n",*pps); } } l两段代码中最后一句分别用了**pp和*pps，明显意义不同，为何输出却又是正确的，我自己在分别修改**pp为*pp和*pps为**pps之后没有得到合理结果，求知道的解释下，万分感激！ NO1 pp = &p; p = & x; int x = 10;  ** pp = **(&p) = *p = *&x = x 而将 **pp 改为 *p后 *pp = *(&p) = p = &x != x  NO 2 char **pps pps =  ps + i *pps = *(ps + i) = ps[i]，即字符串二维数组当中的每个字符串的首地址，用%s输出，则是相应的字符串 **pps = **(ps + i) = *(ps[i]) 而ps[i] = &ps[i][0] 所以*(ps[i]) = *(&ps[i][0]) = ps[i][0] ps[i][0]是个字母，后面没跟'\0'，但用%s输出，因此结果不可预测。

引用 1 楼 bbs2241 的回复:1 我自己在分别修改**pp为*pp  *pp是什么，这是个指针，printf("x=%d\n",*pp);  %d将指针的内容打印出来了，这个指针的内容是指向x的地址的  2 和*pps为**pps之后没有得到合理结果，求知道的解释下，万分感激！  **pps是什么，是字符，printf("%s\n",**pps); %s是将字符串打印出来，而你传给print的是字符，结果是什么，oh no......... access violation 谢谢热心帮助，按照你的解释我理解了这样的修改是不对的，另外我也知道第一种情形是要以指针变量的方式输出数据，但是对第二种还不甚理解，*pps不是char型没错，可是难道是指针变量吗？


Question: 关于getch和getchar用法求助

引用 2 楼 user-1 的回复:for( ; i <= 20; i++) i == 20 时，数组ch[i] 下标越界，*(ch + i)指向了*(ch + i)（当i == 19）时的下一个地址，而这个地址是不确定的，因此*(ch + i) (i == 20时）所指向的内存单元的内容也就不确定了，方括号内的字符就是不确定的。 至于i为什么会等于53（或者再一次运行程序，这个值还会发生变化），这是因为*(ch + i)（i == 20时）所指向的地址，例如在我的电脑上编译运行时ch + i 是 0x0022ff09，它与ch（例如在我的电脑上：ch是 0x0022fed8）所指向的地址（即数组的地址）之差，即 *(ch + i)（请当成一个整体地址看待）- ch = 两个地址之间的距离，即*(ch + i)之中的i（此i非for循环当中的那个i（这个i是int变量））。例如；当ch = 0x0022fed8，而(ch + i) = 0x0022ff09时，0x0022ff09 - 0x0022fed8 = 0x31（等于10进制的49）。  ch = 0022fed8 0       0 = [1] 0022fed8 1       1 = [1] 0022fed9 2       2 = [1] 0022feda 3       3 = [1] 0022fedb 4       4 = [1] 0022fedc 5       5 = [1] 0022fedd 6       6 = [1] 0022fede 7       7 = [1] 0022fedf 8       8 = [1] 0022fee0 9       9 = [1] 0022fee1 10      10 = [1]        0022fee2 11      11 = [1]        0022fee3 12      12 = [1]        0022fee4 13      13 = [1]        0022fee5 14      14 = [1]        0022fee6 15      15 = [1]        0022fee7 16      16 = [1]        0022fee8 17      17 = [1]        0022fee9 18      18 = [1]        0022feea 19      19 = [1]        0022feeb 20      49 = [_]        0022ff09  Process returned 0 (0x0)   execution time : 7.763 s Press any key to continue. 谢谢哈，我发现越界了但是还是不懂为什么是53，，原来是因为地址的不确定


Question: 小问题

楼上说的对

引用 楼主 huang514469 的回复:#include<stdio.h> void main() { 	char c; 	if((c=getchar())=EOF) 	{ 		printf("13"); 	} 	 } 本人测试代码如上，但我在控制台输入完字符按enter键时输出13，但是输完字符按ctrl+z时显示^z并不是文件结束标志，求解释！！！  1. if((c=getchar())=EOF), 这编译都过不了，应该是== 2. 按ctrl+c, linux按ctrl+d

请养成在if语句中将常量写在==左边的好习惯！

引用 1 楼 user-6 的回复:if((c=getchar())=EOF) 改成 if((c=getchar())==EOF)

注意=与==的区别，前者是赋值符号，后者是判断符号


Question: char a[4] = "12345"; //为什么报错

请自行百度字符串和字符串数组的区别

原因是越界了，所以报错还是正常的。

引用 39 楼 luoxuechengbing 的回复:[quote=引用 36 楼 oYinGui1 的回复:] [quote=引用 10 楼 luoxuechengbing 的回复:]   其实，我就想知道   ....char [5]={"12345"}；   不会出错？ 必须出错啊 不会出错，列表初始化去初始化数组，如果列表内元素超过数组长，它会取前面的刚好够数组长的数目的元素来初始化的。[/quote]  我用VS2010记得会出错的，你用VS2010试试；；   不知道你用的哪个 嘿嘿。[/quote] 确实。。记错了，记成char p[5] = { '1', '2', '3', '4', '5' };这种了。。

引用 36 楼 oYinGui1 的回复:[quote=引用 10 楼 luoxuechengbing 的回复:]   其实，我就想知道   ....char [5]={"12345"}；   不会出错？ 必须出错啊 不会出错，列表初始化去初始化数组，如果列表内元素超过数组长，它会取前面的刚好够数组长的数目的元素来初始化的。[/quote]  我用VS2010记得会出错的，你用VS2010试试；；   不知道你用的哪个 嘿嘿。

是少了{}，应加入。

"12345"作为字符串的时候自动在后面填充'\0' #include <stdio.h> #include <string.h>  int main() {     char a[5]="12345";     printf("%d\n",sizeof("12345"));//6     printf("%d\n",sizeof(a));//5     printf("%d\n",strlen("12345"));//5     return 0; }

为什么要报错

引用 18 楼 k91191 的回复:#include <stdio.h> #include <string.h> int main() { 	char n[4]="12345"; 	printf ("%d\n",strlen (n)); 	printf ("%d\n",sizeof (n));     printf("Hello World!\n");     return 0; }  为什么我的结果却是 n是一个字符数组，不是一个字符串，不能使用strlen(n)

引用 14 楼 panda1993 的回复:的确是6，'\0‘作为结束符由编译器自动填入，char a[5]="12345",虽然没有错，但是却不能与null-terminated 的字符串混用，否则会有意想不到的错误 楼上正解，若使用strlen获取字符串长度，则返回的是字符串实际值，是5，sizeof返回的是该变量内存实际占用空间大小

引用 37 楼 oYinGui1 的回复:[quote=引用 34 楼 u013163178 的回复:] #include <stdio.h> #include <string.h>  int main() {     char a[5]="12345";     char *p="12345";//"12345\0"     //printf("%d\n",sizeof("12345"));//6     //printf("%d\n",sizeof(a));//5    // printf("%d\n",strlen("12345"));//5     printf("%s\n",a); //找不到'\0'     printf("%s",p);     return 0; }  char *p = "12345";         //这种就不要再写了，"12345"是个字面值啊，你定义一个char *类型来接收它的地址                                           //是不是说可以用p来改变一个字面值呢？应该定义为const char *啊！[/quote] 不不，我的重点是：不能把字符数组当作字符串来输出

引用 34 楼 u013163178 的回复:#include <stdio.h> #include <string.h>  int main() {     char a[5]="12345";     char *p="12345";//"12345\0"     //printf("%d\n",sizeof("12345"));//6     //printf("%d\n",sizeof(a));//5    // printf("%d\n",strlen("12345"));//5     printf("%s\n",a); //找不到'\0'     printf("%s",p);     return 0; }  char *p = "12345";         //这种就不要再写了，"12345"是个字面值啊，你定义一个char *类型来接收它的地址                                           //是不是说可以用p来改变一个字面值呢？应该定义为const char *啊！

引用 10 楼 luoxuechengbing 的回复:  其实，我就想知道   ....char [5]={"12345"}；   不会出错？ 必须出错啊 不会出错，列表初始化去初始化数组，如果列表内元素超过数组长，它会取前面的刚好够数组长的数目的元素来初始化的。

"12345"的真实存储是12345\0 所以sizeof("12345")是6. 看下这篇文章你就明白了。 http://www.ilanever.com/article/sitedetail.html?id=232

后面会有一个\0哒~亲~

犯罪必然被抓吗？

引用 4 楼 liuhengxiao 的回复:你写的是字符串啊，字符串尾部会填充\0的，它也要占一个字节啊！ 引用 5 楼 yiyefangzhou24 的回复:a 这个数组里其实是1,2,3,4,5,\0 引用 3 楼 ffsdp 的回复:原来真是6。。 引用 6 楼 angel_su 的回复:c警告，c++报错...  你们在看看题目。。。。。。请在看看题目。


Question: C语言文件操作~~~求大牛指导

在文件起始的地方指明多少个学生多少个老师，然后依次读取

2进制肯定是 fwrite/fread 字符 fprintf/fscanf

引用 12 楼 ly621000 的回复:[quote=引用 11 楼 zjq9931 的回复:] [quote=引用 10 楼 ly621000 的回复:] [quote=引用 9 楼 zjq9931 的回复:] [quote=引用 7 楼 ly621000 的回复:] 哦，我的想法是将文件中信息读取到链表中，再对链表进行具体的操作，比如增加或者删除，然后再写回文件，将原来的文件中信息覆盖。但是，我的意思是比如原来，a.bin这个文件既有老师的信息，又有学生的信息，现在我只是想删除某个学生的信息，我就想把文件中所有学生的信息，读取到链表中来。由于，刚刚已经说到，文件里有老师和学生两种结构体的信息，我怎么只把学生的信息提取到链表中呢？直接用fread()，好像不行吧~~~ 首先，要都读出来。修改后再都写回去。 1.你读的时候能否区分出来老是的信息，学生的信息？ 2.如果不能，你要解决这个，可以在文件里面增加索引，或者在链表结构里面增加类型，用于区分。 2.如果能，那就都读出来，修改后再写回去。[/quote] 文件里增加索引？ 链表结构增加类型？不好意思~~我是一个新手~~~请问能不能说详细一点呢~~~谢谢了·[/quote] 索引呢，就是增加一个链表以外的内容，写到文件里面，告诉程序，学生的数据是从多少个字节开始，到多少个字节结束（或者个数），老师的数据从多少个字节开始到多少个字节结束（或者个数）。  就像这样： 学生数据的起始地址：100 学生数据的个数：100个（或者10000个字节） 老师数据的起始地址：10000 老师数据的个数：10个（或者1000个字节） [/quote]   如果，增加老师和学生信息由管理员来实现。管理员增加一个学生信息，随后又增加一个老师的信息。管理员增加角色（老师或者学生）信息是随意的。然后写到文件里，老师和学生的信息不是混在一起了嘛？并不是学生信息只存在某一片，老师信息存在某一片呢？[/quote] 1.老师的结构体大小和学生的结构体大小是否一样？ 2.如果一样大，那就在结构体中增加类型用来区分就可以了。 3.如果不一样大     （1）最好分开放（分文件，也可同一个文件里面两个块），这样便于维护，就像数据库一样，学生一个表，老师一个表。     （2）如果不分开放，那就在文件里面一链表的形式存放，制定下一个同类型的数据的地址。但是不同类型的数据的第一个数据的起始地址也要在文件里面给出，即，要给一个索引。和一个文件里面两块差不多。但是这样的好处是，修改文件时不用全部重写。

引用 18 楼 ly621000 的回复:[quote=引用 16 楼 bigwatercar 的回复:] lz用数据库吧  我也想啊··但是，现在老师明确这么要求的 [/quote] 那就要自己定义文件数据格式了。 内存中保存的链表，内部包含的节点指针只在本次运行中有效，等你写到硬盘，在都会来，那些指针就没用了。 所以主要就是要处理好这种关联关系，比如每个节点增加一个ID，在写入硬盘的时候用这个ID代替指针， 等下次读回来，再根据ID重新建立节点。

引用 16 楼 bigwatercar 的回复:lz用数据库吧  我也想啊··但是，现在老师明确这么要求的

lz用数据库吧

引用 13 楼 zjq9931 的回复:[quote=引用 12 楼 ly621000 的回复:] [quote=引用 11 楼 zjq9931 的回复:] [quote=引用 10 楼 ly621000 的回复:] [quote=引用 9 楼 zjq9931 的回复:] [quote=引用 7 楼 ly621000 的回复:] 哦，我的想法是将文件中信息读取到链表中，再对链表进行具体的操作，比如增加或者删除，然后再写回文件，将原来的文件中信息覆盖。但是，我的意思是比如原来，a.bin这个文件既有老师的信息，又有学生的信息，现在我只是想删除某个学生的信息，我就想把文件中所有学生的信息，读取到链表中来。由于，刚刚已经说到，文件里有老师和学生两种结构体的信息，我怎么只把学生的信息提取到链表中呢？直接用fread()，好像不行吧~~~ 首先，要都读出来。修改后再都写回去。 1.你读的时候能否区分出来老是的信息，学生的信息？ 2.如果不能，你要解决这个，可以在文件里面增加索引，或者在链表结构里面增加类型，用于区分。 2.如果能，那就都读出来，修改后再写回去。[/quote] 文件里增加索引？ 链表结构增加类型？不好意思~~我是一个新手~~~请问能不能说详细一点呢~~~谢谢了·[/quote] 索引呢，就是增加一个链表以外的内容，写到文件里面，告诉程序，学生的数据是从多少个字节开始，到多少个字节结束（或者个数），老师的数据从多少个字节开始到多少个字节结束（或者个数）。  就像这样： 学生数据的起始地址：100 学生数据的个数：100个（或者10000个字节） 老师数据的起始地址：10000 老师数据的个数：10个（或者1000个字节） [/quote]   如果，增加老师和学生信息由管理员来实现。管理员增加一个学生信息，随后又增加一个老师的信息。管理员增加角色（老师或者学生）信息是随意的。然后写到文件里，老师和学生的信息不是混在一起了嘛？并不是学生信息只存在某一片，老师信息存在某一片呢？[/quote] 1.老师的结构体大小和学生的结构体大小是否一样？ 2.如果一样大，那就在结构体中增加类型用来区分就可以了。 3.如果不一样大     （1）最好分开放（分文件，也可同一个文件里面两个块），这样便于维护，就像数据库一样，学生一个表，老师一个表。     （2）如果不分开放，那就在文件里面一链表的形式存放，制定下一个同类型的数据的地址。但是不同类型的数据的第一个数据的起始地址也要在文件里面给出，即，要给一个索引。和一个文件里面两块差不多。但是这样的好处是，修改文件时不用全部重写。  [/quote]  老师和学生的结构就是不一样大~~~~因为，我们老师要求文件个数不能超过两个~~老师和学生分文件存，那还是比较方便的~~主要是我们题目还有一个要求，就是选了角色以后（老师、学生、管理员），会需要相应角色输入密码，才能进入相应的功能选择菜单。那这个各自角色的密码，我不是又要创建一个二进制文件？那文件个数就超过2个呢？ 谢谢你耐心的解答~~主要才开始接触C语言~~所以，只有多问问你们这些大牛~~~

还是用XML格式保存结构体信息比较靠谱。

引用 11 楼 zjq9931 的回复:[quote=引用 10 楼 ly621000 的回复:] [quote=引用 9 楼 zjq9931 的回复:] [quote=引用 7 楼 ly621000 的回复:] 哦，我的想法是将文件中信息读取到链表中，再对链表进行具体的操作，比如增加或者删除，然后再写回文件，将原来的文件中信息覆盖。但是，我的意思是比如原来，a.bin这个文件既有老师的信息，又有学生的信息，现在我只是想删除某个学生的信息，我就想把文件中所有学生的信息，读取到链表中来。由于，刚刚已经说到，文件里有老师和学生两种结构体的信息，我怎么只把学生的信息提取到链表中呢？直接用fread()，好像不行吧~~~ 首先，要都读出来。修改后再都写回去。 1.你读的时候能否区分出来老是的信息，学生的信息？ 2.如果不能，你要解决这个，可以在文件里面增加索引，或者在链表结构里面增加类型，用于区分。 2.如果能，那就都读出来，修改后再写回去。[/quote] 文件里增加索引？ 链表结构增加类型？不好意思~~我是一个新手~~~请问能不能说详细一点呢~~~谢谢了·[/quote] 索引呢，就是增加一个链表以外的内容，写到文件里面，告诉程序，学生的数据是从多少个字节开始，到多少个字节结束（或者个数），老师的数据从多少个字节开始到多少个字节结束（或者个数）。  就像这样： 学生数据的起始地址：100 学生数据的个数：100个（或者10000个字节） 老师数据的起始地址：10000 老师数据的个数：10个（或者1000个字节） [/quote]   如果，增加老师和学生信息由管理员来实现。管理员增加一个学生信息，随后又增加一个老师的信息。管理员增加角色（老师或者学生）信息是随意的。然后写到文件里，老师和学生的信息不是混在一起了嘛？并不是学生信息只存在某一片，老师信息存在某一片呢？

fwrite，可以直接写到文件里面。 但注意：链表，里面的下一个，上一个是内存的地址，并不是文件里面的地址。 另外，什么地方存老师的，什么地方存学生的，这个需要有个索引。 等等，制定文件结构吧。

用文件IO流就可以实现吧

引用 10 楼 ly621000 的回复:[quote=引用 9 楼 zjq9931 的回复:] [quote=引用 7 楼 ly621000 的回复:] 哦，我的想法是将文件中信息读取到链表中，再对链表进行具体的操作，比如增加或者删除，然后再写回文件，将原来的文件中信息覆盖。但是，我的意思是比如原来，a.bin这个文件既有老师的信息，又有学生的信息，现在我只是想删除某个学生的信息，我就想把文件中所有学生的信息，读取到链表中来。由于，刚刚已经说到，文件里有老师和学生两种结构体的信息，我怎么只把学生的信息提取到链表中呢？直接用fread()，好像不行吧~~~ 首先，要都读出来。修改后再都写回去。 1.你读的时候能否区分出来老是的信息，学生的信息？ 2.如果不能，你要解决这个，可以在文件里面增加索引，或者在链表结构里面增加类型，用于区分。 2.如果能，那就都读出来，修改后再写回去。[/quote] 文件里增加索引？ 链表结构增加类型？不好意思~~我是一个新手~~~请问能不能说详细一点呢~~~谢谢了·[/quote] 索引呢，就是增加一个链表以外的内容，写到文件里面，告诉程序，学生的数据是从多少个字节开始，到多少个字节结束（或者个数），老师的数据从多少个字节开始到多少个字节结束（或者个数）。  就像这样： 学生数据的起始地址：100 学生数据的个数：100个（或者10000个字节） 老师数据的起始地址：10000 老师数据的个数：10个（或者1000个字节）

引用 9 楼 zjq9931 的回复:[quote=引用 7 楼 ly621000 的回复:] 哦，我的想法是将文件中信息读取到链表中，再对链表进行具体的操作，比如增加或者删除，然后再写回文件，将原来的文件中信息覆盖。但是，我的意思是比如原来，a.bin这个文件既有老师的信息，又有学生的信息，现在我只是想删除某个学生的信息，我就想把文件中所有学生的信息，读取到链表中来。由于，刚刚已经说到，文件里有老师和学生两种结构体的信息，我怎么只把学生的信息提取到链表中呢？直接用fread()，好像不行吧~~~ 首先，要都读出来。修改后再都写回去。 1.你读的时候能否区分出来老是的信息，学生的信息？ 2.如果不能，你要解决这个，可以在文件里面增加索引，或者在链表结构里面增加类型，用于区分。 2.如果能，那就都读出来，修改后再写回去。[/quote]    文件里增加索引？ 链表结构增加类型？不好意思~~我是一个新手~~~请问能不能说详细一点呢~~~谢谢了·

引用 7 楼 ly621000 的回复:哦，我的想法是将文件中信息读取到链表中，再对链表进行具体的操作，比如增加或者删除，然后再写回文件，将原来的文件中信息覆盖。但是，我的意思是比如原来，a.bin这个文件既有老师的信息，又有学生的信息，现在我只是想删除某个学生的信息，我就想把文件中所有学生的信息，读取到链表中来。由于，刚刚已经说到，文件里有老师和学生两种结构体的信息，我怎么只把学生的信息提取到链表中呢？直接用fread()，好像不行吧~~~ 首先，要都读出来。修改后再都写回去。 1.你读的时候能否区分出来老是的信息，学生的信息？ 2.如果不能，你要解决这个，可以在文件里面增加索引，或者在链表结构里面增加类型，用于区分。 2.如果能，那就都读出来，修改后再写回去。

学习了，，，

Archive

所谓修改删除文件a某位置的内容，其实是读打开文件a，再将‘a中修改删除位置之前的内容＋修改删除的内容＋a中修改删除位置之后的内容’保存到文件b，关闭文件a，删除文件a，将文件b改名为与之前文件a相同的名字，仅此而已。  f=fopen(..."wb"); fwrite(&student1,sizeof(struct STUDENT),1,f); fwrite(&student2,sizeof(struct STUDENT),1,f); fwrite(&teacher1,sizeof(struct TEACHER),1,f); fwrite(&teacher2,sizeof(struct TEACHER),1,f); fclose(f); f=fopen(..."rb"); fread(&student1,sizeof(struct STUDENT),1,f); fread(&student2,sizeof(struct STUDENT),1,f); fread(&teacher1,sizeof(struct TEACHER),1,f); fread(&teacher2,sizeof(struct TEACHER),1,f); fclose(f);


Question: 我写了一个用链表实现的队列，第一次入队出队列都没问题，但是之后就出问题了，无法入队列，于是我设定，如果队列为空，再初始化队列，请问我这方法会不会很烂

type struct queue_header {...} queueheader～～

楼主的队列的len的算法或许可以有些改进： type struct queue_header {        int qlen；        struct queue *header;        struct queue *last； } header 记录头，last记录尾部，qlen记录长度 个人感觉数组实现方便些。

引用 6 楼 liuhengxiao 的回复:看完代码我惊呆了，楼主你对指针和内存这块真的是什么都不知道啊。。。。每次调用函数你都给temp申请空间。。。  你只需要在添加节点的时候为temp申请空间，删除，计算长度都不需要再申请个空间。。。。 受教了，谢谢你的指点

大致改了几个地方： 全局变量que放到main() temp问题 enqueue(),在que== NULL时没有free掉，但在此函数中free会造成que无法避免地成为野指针，以致在调用print()时出错，只好在main()的最后free，求高人解决一下。 #include<stdio.h> #include<stdlib.h>  struct node { 	int data; 	struct node *next; } ;  struct queue { 	struct node *front; 	struct node *rear; } ;  // enter a node to queue struct queue *initQueue() { 	struct queue *que; 	que = (struct queue*)malloc(sizeof(struct queue)); 	que->front = que->rear = NULL; 	return que; }  void enqueue(struct queue *que, int num) { 	struct node* temp = (struct node*)malloc(sizeof(struct node)); 	temp->data = num; 	temp->next= NULL; 	//-------------------------------------------------------------------------------------------- 	//    because front and rear are NULL when being initialized,so i have to distinguish this two 	//    this is the point 	//-------------------------------------------------------------------------------------------- 	if (NULL == que->rear) 		que->front = que->rear = temp; 	else 	{ 		que->rear->next = temp; 		que->rear = temp; 	} }  // destroy one node void dequeue(struct queue *que) { 	struct node *temp = que->front; 	if (temp != NULL) 	{ 		que->front = que->front->next; 		free(temp); 		temp = NULL;  		if (que->front == NULL) 		{ 			que->rear = NULL; 			//free(que); 		} 	} }  //return length of queue int length(struct queue *que) { 	struct node* temp = que->front; 	int n = 0; 	while (temp != NULL) 	{ 		++n; 		temp = temp->next; 	} 	temp = NULL; 	return n; }  //print the queue void print(struct queue *que) { 	struct node* temp = que->front; 	if (que->front == NULL) 	{ 		printf("Empty Queue!\n"); 		return; 	}  	while (temp != NULL) 	{ 		printf("%d->", temp->data); 		temp = temp->next; 	} 	printf("\n");	 	temp=NULL; }   void menu() { 	printf("---------------------------------------------------------------------------------\n"); 	printf("-------------------------------first in first out example------------------------\n"); 	printf("---------------------------------------------------------------------------------\n"); 	printf("                                 1:enter queue\n"); 	printf("                                 2:destroy queue\n"); 	printf("                                 3:print queue\n"); 	printf("                                 4:length\n"); 	printf("                                 5:clear screen\n"); 	printf("                                 0:exit\n"); 	printf("---------------------------------------------------------------------------------\n"); 	printf("---------------------------------------------------------------------------------\n"); }  int main() { 	struct queue *que; 	int choice, num; 	que = initQueue(); 	menu(); 	while(1) 	{ 		printf("please enter your choice: "); 		scanf("%d", &choice); 		switch(choice) 		{ 		case 1: 			printf("please enter a number: "); 			scanf("%d",&num); 			enqueue(que,num); 			print(que); 			break; 		case 2: 			dequeue(que); 			print(que); 			break; 		case 3: 			print(que); 			break; 		case 4: 			printf("queue's length is :%d\n",length(que)); 			break; 		case 5: 			system("clear"); 			menu(); 			break; 		case 0: 			exit(1); 		default:printf("wrong input\n"); 			break; 		} 	} 	free(que); 	return 0; }

void dequeue(struct queue *queue){     struct node* temp=(struct node*)malloc(sizeof(struct node));//这里是删除节点，不用再给temp申请空间，直接把temp指向 要删除的节点，然后free掉就可以了     if(queue->front!=NULL){         temp=queue->front;         queue->front=queue->front->next;         free(temp);         temp=NULL;     }     else printf("queue is empty\n"); }

void enqueue(struct queue *queue,int num){     struct node* temp=(struct node*)malloc(sizeof(struct node));     temp->data=num;     temp->next=NULL;     //--------------------------------------------------------------------------------------------     //    because front and rear are NULL when being initialized,so i have to distinguish this two     //    this is the point     //--------------------------------------------------------------------------------------------     if(queue->rear==NULL)         queue->front=queue->rear=temp;     else         queue->rear=queue->rear->next=temp;//notice the sequence      //    queue->rear->next=temp;     //    queue->rear=temp;     temp=NULL; //这里的temp已经加入到队列中了，你把temp又指向NULL是什么意思？本来是一个已经分配的内存空间指针，现在又找不到了，当第二个插入的时候NULL 是没有next指针的，肯定会出错的 }

看出个错误，除了enqueue，dequeue，length，print 都不需要分配内存的


Question: 贪吃蛇一吃到食物就不行了，求教大神哪里错了

呵呵，断点调试后解决问题了，多谢了

引用 2 楼 u012852836 的回复:我写的哪个错在哪了，为什么不行啊？ 错在逻辑复杂，难以看明白。 for()中i一直增加，没有上限，一看就有问题。 你为何不断点调一下呢？

我写的哪个错在哪了，为什么不行啊？

#include <windows.h> #include <stdlib.h> #include <stdio.h> #include <conio.h> #include <time.h> #define S 200 #define HEIGHT 20 #define WIDTH 80 int m,n; void gotoxy(int x ,int y) { 	COORD pos={x,y}; 	HANDLE hOut=GetStdHandle(STD_OUTPUT_HANDLE);     SetConsoleCursorPosition(hOut,pos); 	 }  void block() { 	int i=0,j=0; 	gotoxy(i,j); 	while (i<WIDTH) 	{ 		printf("@"); 		i++; 	} 	i=0;j=1; 	while (j<HEIGHT-1) 	{ 		gotoxy(i,j); 		printf("@"); 		gotoxy(i+WIDTH-1,j); 		printf("@"); 		j++; 	} 	while (i<WIDTH) 	{         gotoxy(i,j); 		printf("@"); 		i++; 	} }  food() { 	int x=(int)(rand()%79)+1; 	int y=(int)(rand()%19)+1; 	if (x == 0 || x == 79 || y == 0 || y == 19) 	{ 		food(); 	} 	else 	{ 		m=x;n=y; 		gotoxy(x,y); 		printf("*"); 	} }  void start() { 	int nSleep = S; 	food();  	struct Corner 	{ 		int nX; 		int nY; 		int nDirection; 		struct Corner *pNext; 	};  	Corner Head; 	Corner *pTail; 	pTail = NULL; 	Head.pNext = NULL; #define UP_DIRECTION	0 #define RIGHT_DIRECTION	1 #define DOWN_DIRECTION	2 #define LEFT_DIRECTION	3 	int nTailDirection = RIGHT_DIRECTION; 	int nHeadDirection = RIGHT_DIRECTION;  	int nTailX = 5; 	int nTailY = 5; 	int nHeadX = 7; 	int nHeadY = 5;  	for (int i = nTailX; i <= nHeadX - 1; i++) 	{ 		gotoxy(i, nTailY); 		printf("*"); 	} 	gotoxy(nHeadX, nHeadY); 	printf("#");  	char ch = 0; 	while(TRUE) 	{ 		if (kbhit()) 		{ 			int nOldHeadDirection = nHeadDirection; 			ch=getch(); 			switch(ch) 			{ 			case 'w': 			case 'W': 				if (nHeadDirection != DOWN_DIRECTION) 				{ 					if (nHeadDirection == UP_DIRECTION) 					{ 						nSleep = 1; 					} 					nHeadDirection = UP_DIRECTION; 				} 				break; 			case 'd': 			case 'D': 				if (nHeadDirection != LEFT_DIRECTION) 				{ 					if (nHeadDirection == RIGHT_DIRECTION) 					{ 						nSleep = 1; 					} 					nHeadDirection = RIGHT_DIRECTION; 				} 				break; 			case 's': 			case 'S': 				if (nHeadDirection != UP_DIRECTION) 				{ 					if (nHeadDirection == DOWN_DIRECTION) 					{ 						nSleep = 1; 					} 					nHeadDirection = DOWN_DIRECTION; 				} 				break; 			case 'a': 			case 'A': 				if (nHeadDirection != RIGHT_DIRECTION) 				{ 					if (nHeadDirection == LEFT_DIRECTION) 					{ 						nSleep = 1; 					} 					nHeadDirection = LEFT_DIRECTION; 				} 				break; 			default: 				break; 			} 			if (nOldHeadDirection != nHeadDirection) 			{ 				Corner *pCorner = new Corner(); 				pCorner->nX = nHeadX; 				pCorner->nY = nHeadY; 				pCorner->nDirection = nHeadDirection; 				pCorner->pNext = NULL; 				if (pTail) 				{ 					pTail->pNext = pCorner; 				} 				else 				{ 					Head.pNext = pCorner; 				} 				pTail = pCorner; 			} 		} 	 		switch(nHeadDirection) 		{ 		case UP_DIRECTION: 			gotoxy(nHeadX, nHeadY); 			printf("*"); 			nHeadY -= 1; 			break; 		case RIGHT_DIRECTION: 			gotoxy(nHeadX, nHeadY); 			printf("*"); 			nHeadX += 1; 			break; 		case DOWN_DIRECTION: 			gotoxy(nHeadX, nHeadY); 			printf("*"); 			nHeadY += 1; 			break; 		case LEFT_DIRECTION: 			gotoxy(nHeadX, nHeadY); 			printf("*"); 			nHeadX -= 1; 			break; 		default: 			break; 		}  		gotoxy(nHeadX, nHeadY); 		printf("#");  		if (nHeadX == m && nHeadY == n) 		{  			food(); 		} 		else 		{ 			gotoxy(nTailX, nTailY); 			printf(" ");  			Corner *pHeadNext = Head.pNext; 			if (pHeadNext) 			{ 				if (pHeadNext->nX == nTailX && pHeadNext->nY == nTailY) 				{ 					nTailDirection = pHeadNext->nDirection; 					Head.pNext = pHeadNext->pNext; 					if (!Head.pNext) 					{ 						pTail = NULL; 					} 					delete pHeadNext; 				} 			}  			switch(nTailDirection) 			{ 			case UP_DIRECTION: 				nTailY -= 1; 				break; 			case RIGHT_DIRECTION: 				nTailX += 1; 				break; 			case DOWN_DIRECTION: 				nTailY += 1; 				break; 			case LEFT_DIRECTION: 				nTailX -= 1; 				break; 			default: 				break; 			} 		}  		if (nHeadX == 0 || nHeadX == 79 || nHeadY == 0 || nHeadY == 19) 		{ 			gotoxy(0, 20); 			printf("Dead!"); 			getch(); 			exit(EXIT_FAILURE); 		}  		if (nSleep != 1) 		{ 			Sleep(nSleep); 		} 		nSleep = S; 	} }  int main() { 	srand((unsigned)time(NULL)); 	block(); 	start(); 	 }


Question: 对于int a，要使((1<<2>>1)|a)==a，则a可以是？

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

ALL.......

都可以的吧，我试了试 1 << 2 >> 1  // == 2啊

<<和>>的优先级是一样的，所以先算左边的，所以1<<2>>1的结果为2，所以三个都可以。

和平台没有关系。 1，<<和>>运算符是左结合的，因此，1<<2>>1可以解析为(1<<2)>>1。 2，若>>运算符的左操作数为负，则结果是实现定义的。但显然这里不存在这种情况。

目测都可以。。。

2|a == a  2|2=2 2|6=6 2|10=10  abc都可以

我咋感觉会是10呢。。。

这题目出的不错。a只要第1位上有1，按位或以后结果就会保持不变。所以ABC都可以。


Question: 底层数据的写入

假设你使用的是SATA的硬盘，要实现这个目的需要用到ATA协议中的指令，去看看ATA的协议标准文档。但另一方面，在windows系统中，处在用户层是没有办法对硬盘实现这种底层操作的。你可以从这两方面着手。


Question: 这段伸展树代码，我用错了吗？

compare(struct my_entry *a, struct my_entry *b) {         return (a->key<b->key); }  改成  compare(struct my_entry *a, struct my_entry *b) {         return (a->key-b->key); }

引用 1 楼 user-2 的回复:找了一段？不如自己写啊。 +1，看过不如做过，做过不如错过。

找了一段？不如自己写啊。


Question: 菜鸟求问。C语言字符指针问题

字符串常量是放在只读数据段中的。不具有写的能力，不能修改！

引用 1 楼 a156435646 的回复:UPUPUPUPUPUP  char s[] ="xxx";  char *s = "xxx"; //指向静态区，可读不可改

5楼的方法是正解  你用char * 是把s指向一个常量字符串，对常量字符串的内容是不能修改的， 在定义时char s[]，是一个字符数组，数组的内容是可以修改的。

引用 4 楼 HiSoldier__ 的回复:char *S = abcdef"; 是常量，不能S[2] = '\0'这样操作 你也可以这样理解（不太正规） char *S = abcdef";这一语句中的S只是一个字符型指针而非字符型数组，所以S是有值的，它的值是字符串的首地址，又应为S并非是常指针，所以S的值是可以变的，即可以进行S++，s+1·····这一类的改变地址的操作。

#include<stdio.h> int main() { 	char s[]="abcdef"; 	// u see 	printf("%s\n",s);     s[1] = '\0'; 	//u see again 	printf("%s\n",s); 	return 0; }

S=(char*)malloc(6); strcpy(S, "abcdef\0"); S[2] = '\0';

char *S="abcdef"; //1 这个语句里的字符串“abcdef“是字符串常量，存放在静态区，不能被 S[2]='\0'; 这样的语句修改其中的值。*S只是个指针而已，并不分配内存空间，对它所指向的字符串常量无法加以修改。

UPUPUPUPUPUP


Question: 求解释，在vc6.0上运行是a=3，b=17。但我算的是b=19啊。求大神指点一下

C,C++表达式求值顺序 裘老的解释。

没必要考虑这种情况，这种情况下c标准本来就没有规范的结果是未定义的，具体结果看各个编译器厂家自己的实现，你可能在cfree中运行又不一样了

为什么要纠结这个呢，这样的结果是未定义的。一个编译器一个结果。


Question: C怎么判断或者限制输入的字符串的类型？

asc码呗。

scanf的能力有限，你自己把输入的字符检测一下就ok http://www.cplusplus.com/reference/cctype/ type.h库里面常用的字符判断函数，可查阅

scanf()的返回值是输入成功的次数，输入的时候会检测类型，如果类型不匹配，就会把字符留在缓冲区里面啊

#include <stdio.h> #include <conio.h> int i = 0; char c; void main() {     while (1) {         printf("\nPlease input a number:");         fflush(stdout);         rewind(stdin);         if (2==scanf("%d%c",&i,&c)) {             if ('\n'==c) {                 printf("\nThe number is %d.\n", i);                 break;             }         }     }     printf("Press any key to end ...");     getch(); } // //Please input a number:12a // //Please input a number:a // //Please input a number:12 // //The number is 12. //Press any key to end ...

判断输入的字符对应的ascii值是否在48-57之间

这和你贴出来的代码有什么关系？


Question: double数组的赋值问题，0.2和int相乘赋值到double数值出问题

引用 2 楼 mcmay 的回复:#include"stdio.h" void main() { int i; double x[21]; for (i = 0; i <= 20;i++) { x[i] = i*0.2; } for (i = 0;i<=20;i++) printf("%d ", x[i]); // 这里要用%f或%g，而不是%d，x[i]是double型的  } 厉害，大神谢谢你！！！！膜拜

应该是 0  0.2  0.4  0.6 0.8 1.0 依次类推 不知道楼主是否是这样的值


Question: c语言实现的库，树型结构存储数据，写到文件中也是分层的，和xml类似，但不是libxml，求名字

贴一段数据上来好不，啥都没有怎么判断？猜？


Question: 【视频资源】c语言全套高清视频打包下载，希望对正在学习c语言的朋友有帮助

这么多视频没用，随便找个视频入个门，之后就是多看书，多写代码了

c语言还是多编程多联系吧


Question: 关于在VC中直接写内存的问题？？？？

引用 9 楼 anewbies 的回复:[quote=引用 8 楼 zhao4zhong1 的回复:] MSDN98中的例子walker又名pwalk。完整列出指定进程的内存使用情况，显示进程地址空间内容，装载哪些DLL，代码、数据、堆栈段分配在何处，可以用来检测内存泄漏，监测内存使用。  http://download.csdn.net/detail/zhao4zhong1/3667896 大神，我做任务，绑手机终于弄够8个积份下下来了个这工具，这个工具确实好，但是打开资源管理器，有那么多进程，还有那么多系统进程，我没法一个一个查看倒底占了那些内存啊？ 我现在的问题是：1、在我写一个地址时是不是先要告诉内存管理机制我要改内存，用你提供的API获得相应的权限后才能写内存？2、在没有内存管理机制或者没有虚拟内存机制的情况下，例如一些没有操作系统的嵌入式系统中，我写的语句应该是能执行的？是这样的吗?[/quote] 完全正确。  推荐使用WinHex软件查看或修改硬盘或文件或内存中的原始字节内容，但后果自负。  VMMap 是进程虚拟和物理内存分析实用工具。http://technet.microsoft.com/zh-cn/sysinternals/dd535533

引用 8 楼 zhao4zhong1 的回复:MSDN98中的例子walker又名pwalk。完整列出指定进程的内存使用情况，显示进程地址空间内容，装载哪些DLL，代码、数据、堆栈段分配在何处，可以用来检测内存泄漏，监测内存使用。  http://download.csdn.net/detail/zhao4zhong1/3667896 大神，我做任务，绑手机终于弄够8个积份下下来了个这工具，这个工具确实好，但是打开资源管理器，有那么多进程，还有那么多系统进程，我没法一个一个查看倒底占了那些内存啊？ 我现在的问题是：1、在我写一个地址时是不是先要告诉内存管理机制我要改内存，用你提供的API获得相应的权限后才能写内存？2、在没有内存管理机制或者没有虚拟内存机制的情况下，例如一些没有操作系统的嵌入式系统中，我写的语句应该是能执行的？是这样的吗?

在没有内存管理机制或者没有虚拟内存机制的情况下，我写的语句是不是不会报错的啊？

引用 4 楼 zhao4zhong1 的回复:其实电脑开机后物理内存的每个字节都是可读写的，区别仅在于操作系统内存管理模块在你读写时是否能发现并是否采取相应动作而已。操作系统管理内存的粒度不是字节而是页，一页通常为4KB。  OpenProcessToken LookupPrivilegeValue AdjustTokenPrivileges VirtualQueryEx VirtualProtectEx WriteProcessMemory 是不是先要告诉内存管理机制要改内存，获得相应的权限后才能写内存？

引用 2 楼 majia2011 的回复:那是系统留给自己用的，不是给你的内存，不会让你访问的 那那那一段是可以给用户用用的呢？

引用 1 楼 u013410838 的回复:addr所指向的那块内存不能访问，不能写数据 可是我查看内存了，那个地址是空的啊，计算机内哪些内存可以改值啊？我试了好几个都不行啊

那是系统留给自己用的，不是给你的内存，不会让你访问的

addr所指向的那块内存不能访问，不能写数据


Question: 二叉搜索树 奇葩错误

非常感谢,I see it

if(p->Left ==NULL&&p->Right ==NULL)    {             if(p->parent ==NULL){           free(p);           (*root) =NULL;     }  这里造成的结果就是整棵树都不再可以访问。 但是紧接着你后面就通过p访问（P已经被free掉了） 如果你加了else，那么这两部分的代码就不会同时执行，出错的可能就会降低。 不加else，就一定会出错，因为你使用了一个野指针

你整个程序中对一个节点的parent域赋值的地方只有一个就是p->Left=p->parent=p->Right=NULL;  我可以理解你的所有节点的parent域全部都赋值是NULL  所以你代码里面这句 if(p->parent->Left == p) 相当于你访问一个空指针的left，即NULL->left，当然会出问题

因此在else后面的第一个if那里设置断点，然后调试哈！

F9-> F5-> F10 == 答案  加了else不出现非法访问是因为 加上else之后后面的代码就不执行了， 所以不会出现错误，不加的话后面的if语句就会执行以下， 也许就是执行if语句的时候出现了非法访问， 因为在else后面的第一个if那里设置断点，然后调试哈！


Question: 编二叉搜索树 遇到个非凡的错误

void deleteNode(Pnode *root,KeyType key){       Pnode p =NULL,q = NULL;    p = (struct Node*)malloc(sizeof(struct Node));   p = search(*root,key);   if( p == NULL){        printf("不存在该结点 sorry!");   }         if(p->Left ==NULL&&p->Right ==NULL)//估计错误在这   {    //加            if(p->parent->Left == p){    p->parent->Left=NULL;   free(p);   }  else{            p->parent->Right=NULL;    free(p);   }   } }   删除节点的时候为什么还要malloc一个出来呢？

代码错误是什么啊？贴出来看下


Question: 这个函数调用没有用到参数，那还传参数干什么？

写代码的人初衷和结果不一致的表现！或者写成带参数接口，在不使用全局变量的情况下也能用一用

谢谢楼上各位大侠的提点，看来学一门语言还会牵涉到语言之外的很多其他知识。学习的过程也就是个不断扩展的过程。

引用 4 楼 supermegaboy 的回复:[quote=引用 3 楼 lm_whales 的回复:] [quote=引用 2 楼 supermegaboy 的回复:] bool ListIsFull(const List * plist) 应该是设计之初的想法，后来实现的时候没有使用，却忘了删掉。但这段代码废话很多，不够简洁，例如这个LitisFull，这样写就行了：   bool ListIsFull(const List * plist)  {     Node * pt = ( Node * )malloc( sizeof( Node ) );     free( pt );     return !pt; }  ++  LitisFull就是检查一下，还有没有内存可以分配，有的话就永远不会满，内存用完了就满了。 这个情况，几乎不会遇到满的情况，满了以后，估计程序啥也干不了了。  满了以后，任何其他分配内存的操作，都几乎不能执行，这样这个程序基本上也就跑不下去了。 对于链表，一般不用判满，除非限制节点数量。 [/quote]  这个ListisFull提不提供均可以，提供的话，遇到无内存可分配时，可通过自定义资源管理模块（C）或new_handler（C++）释放内存。[/quote] 哦，原来还可以这样处理，谢谢

引用 3 楼 lm_whales 的回复:[quote=引用 2 楼 supermegaboy 的回复:] bool ListIsFull(const List * plist) 应该是设计之初的想法，后来实现的时候没有使用，却忘了删掉。但这段代码废话很多，不够简洁，例如这个LitisFull，这样写就行了：   bool ListIsFull(const List * plist)  {     Node * pt = ( Node * )malloc( sizeof( Node ) );     free( pt );     return !pt; }  ++  LitisFull就是检查一下，还有没有内存可以分配，有的话就永远不会满，内存用完了就满了。 这个情况，几乎不会遇到满的情况，满了以后，估计程序啥也干不了了。  满了以后，任何其他分配内存的操作，都几乎不能执行，这样这个程序基本上也就跑不下去了。 对于链表，一般不用判满，除非限制节点数量。 [/quote]  这个ListisFull提不提供均可以，提供的话，遇到无内存可分配时，可通过自定义资源管理模块（C）或new_handler（C++）释放内存。

引用 2 楼 supermegaboy 的回复:bool ListIsFull(const List * plist) 应该是设计之初的想法，后来实现的时候没有使用，却忘了删掉。但这段代码废话很多，不够简洁，例如这个LitisFull，这样写就行了：   bool ListIsFull(const List * plist)  {     Node * pt = ( Node * )malloc( sizeof( Node ) );     free( pt );     return !pt; }  ++  LitisFull就是检查一下，还有没有内存可以分配，有的话就永远不会满，内存用完了就满了。 这个情况，几乎不会遇到满的情况，满了以后，估计程序啥也干不了了。  满了以后，任何其他分配内存的操作，都几乎不能执行，这样这个程序基本上也就跑不下去了。 对于链表，一般不用判满，除非限制节点数量。

写代码的人不知道怎么传参，我猜。


Question: PE文件头编程的一个错误，求解

《Windows PE权威指南》

那是相对偏移，不是地址，直接访问，必然会错的

文件能打开，但是加上printf()那句就出错，buffer数组我看过了就是PE文件头


Question: 从fopen获得的写入句柄总是NULL

FILE * fin = fopen("gift1.in","r+");     FILE * fout = fopen("gift1.out","w+");

_chdir _getcwd

检查下你的文件存放的路径对不对吧！！！！

method2: SetCurrentDirectory(...)

相对路径问题，windows用GetModuleFileName经过字符串操作，获取文件绝对路径，传入fopen

"r"  Opens for reading. If the file does not exist or cannot be found, the fopen call fails.  "w"  Opens an empty file for writing. If the file exists, its contents are destroyed.  "a"  Opens for writing at the end of the file (appending) without removing the EOF marker before writing new data to the file; creates the file first if it doesn't exist.  "r+"  Opens for both reading and writing. (The file must exist.)  "w+"  Opens an empty file for both reading and writing. If the file exists, its contents are destroyed.  "a+"  Opens for reading and appending; the appending operation includes the removal of the EOF marker before data is written to the file and the EOF marker is restored after writing is complete; creates the file first if it doesn't exist.  When a file is opened with the "a" or "a+" access type, all write operations occur at the end of the file.   The file pointer can be repositioned using fseek, but is always moved back to the end of the file before a write operation is carried out. Thus, existing data cannot be overwritten.   The "a" mode does not remove the EOF marker before appending to the file. After appending occurs, the MS-DOS TYPE command only shows data up to the original EOF marker and not any data appended to the file.   The "a+" mode removes the EOF marker before appending to the file. After appending, the MS-DOS TYPE command shows all data in the file.   The "a+" mode is required for appending to a stream file that is terminated with the CTRL+Z EOF marker.   When the "r+", "w+", or "a+" access type is specified, both reading and writing are allowed (the file is said to be open for "update"). However, when you switch between reading and writing, there must be an intervening fflush, fsetpos, or fseek operation.   The current position can be specified for the fsetpos or fseek operation.   In addition to the above values, the following characters can be included in mode to specify the translation mode for newline characters:   t  Open in text (translated) mode.  In this mode, CTRL+Z is interpreted as an end-of-file character on input.   In files opened for reading/writing with "a+", fopen checks for a CTRL+Z at the end of the file and removes it, if possible.   This is done because using fseek and ftell to move within a file that ends with a CTRL+Z can cause fseek to behave improperly near the end of the file.   Also, in text mode, carriage return–linefeed combinations are translated into single linefeeds on input, and linefeed characters are translated to carriage return–linefeed combinations on output.   When a Unicode stream-I/O function operates in text mode (the default), the source or destination stream is assumed to be a sequence of multibyte characters. Therefore, the Unicode stream-input functions convert multibyte characters to wide characters.   For the same reason, the Unicode stream-output functions convert wide characters to multibyte characters.   b  Open in binary (untranslated) mode; translations involving carriage-return and linefeed characters are suppressed.  If t or b is not given in mode, the default translation mode is defined by the global variable _fmode.   If t or b is prefixed to the argument, the function fails and returns NULL.   c  Enable the commit flag for the associated filename so that the contents of the file buffer are written directly to disk if fflush or _flushall is called.  n  Reset the commit flag for the associated filename to "no-commit." This is the default.    你的文件是否存在？目录对不对？

为什么在简单的代码中，  FILE * fin = fopen("gift1.in","r");  就可以得到正确结果呢？

发觉在调试时，fin就会变成空句柄，但正常运行时就一切正常。。。 不知道这是为什么


Question: 请教大家一个关于gets函数的问题

你要再回车一下啊，不然编译器怎么知道你输入结束了

请各位大侠指导一下啊


Question: 如何理解typedef Node * List

引用 6 楼 mcmay 的回复:谢谢楼上各位的解析。这就是说根据 typedef Node * List 这个定义， List实际上就是个 Node结构体的指针了是吗？但是我在后面的代码中又看到了这样的变量声明和函数参数传递。 List movies;  InitializeList(&movies); 既然根据前面的typedef定义List本来就是一个指针了，也就是说变量movies本身就是个Node结构体指针。那么，为何把它当做函数参数传递时还要用&movies的形式呢？谢谢！ 这种东西通常这么设计，glib里面用来代替throw catch机制：  return_type some_operation_that_may_cause_error(......, error_type** err);  // 调用时 error_type* err = 0; some_operation_that_may_cause_error(...， &err); if (err) {     fprintf(stderr, "error: %s\n", err->message);     exit(1); }

引用 6 楼 mcmay 的回复:谢谢楼上各位的解析。这就是说根据 typedef Node * List 这个定义， List实际上就是个 Node结构体的指针了是吗？但是我在后面的代码中又看到了这样的变量声明和函数参数传递。 List movies;  InitializeList(&movies); 既然根据前面的typedef定义List本来就是一个指针了，也就是说变量movies本身就是个Node结构体指针。那么，为何把它当做函数参数传递时还要用&movies的形式呢？谢谢！ 在初始化函数里传递指针变量的地址，可以设计成这样：如果失败，指针赋0。 当然，这里我看不到设计成这样的必要性，因为返回值也可以。

typedef Node * List; //List 定义为指向结构体的指针

别名，便于修改，移植性好！

类型重定义。有什么不好理解的？

相当于别名

就是 当你定义一个List时， 其实它实际是Node*类型的！ 图个方便

这是定义Node* 为一个新的类型 List


Question: 函数返回值

int result(int a,int b) {      if(a==b)          return 1;      else          return 0; }

引用 楼主 u012908190 的回复:#include<stdio.h> int result(int a,int b) {      if(a==b)          return 1; } int main(void) {     int a=1,b=2;     int re=result(a,b);     printf("%d\n",re);     return 0; } 这个程序为什么结果是1？ 貌似返回的是程序里面if语句里面做判断的第一个变量的值 至于为什么

你这个程序编译的时候应该会报一个warning，因为a!=b时你没给出return语句，因此返回值应该是一个随机整形数。你可以尝试把a值改为5，应该输出就会是5了。

引用 7 楼 zgangz 的回复:if的另一个分支你没有指定返回值，此时的返回值行为是无定义的。我们可以通过反汇编来看看函数是怎么处理的，函数的返回值是通过EAX和EDX保存的，其中EAX存低位 result函数的反汇编： 0041BBF0  push        ebp   0041BBF1  mov         ebp,esp  0041BBF3  sub         esp,0C0h   0041BBF9  push        ebx   0041BBFA  push        esi   0041BBFB  push        edi   0041BBFC  lea         edi,[ebp-0C0h]  0041BC02  mov         ecx,30h  0041BC07  mov         eax,0CCCCCCCCh  0041BC0C  rep stos    dword ptr [edi]  0041BC0E  mov         eax,dword ptr [a]       //将变量a的值存入寄存器eax，a的值是1，所以eax的值是1 0041BC11  cmp         eax,dword ptr [b]       //将b和eax比较 0041BC14  jne         result+2Bh (41BC1Bh)  //如果b和eax不相等则跳到41BC1Bh,即往下的第二条指定pop edi 0041BC16  mov         eax,1                               //如果相等将eax的值赋为1,这里即是你指定的return 1 0041BC1B  pop         edi   通过反汇编可以看到，如果a和b不相等，eax并没有被赋值，它的值仍是在进行比较操作时变量a的值，即1，你可以改变变量a的值，会发现只要a和b不相等，函数的返回值总是等于a  上面是vs编译器debug版的结果，如果换成release，情况会不一样，因为编译器进行了优化 gcc编译器在不进行优化的情况下，结果和上述类似  为了代码的健壮性，所以要考虑到每个分支，每个分支都需要有返回值      if(a==b)          return 1;      else          return 0; 学习了！！！

引用 4 楼 tangfengray 的回复: if (a == b) return 1; else return 0;  一个分支不给返回值...会被骂的 我的手下任何if没有对应的else，都会被我骂。


Question: 关于c语言程序的问题，求好心人帮助

LZ我看不懂   p = DATA + (p-DATA+1)%2; 是什么意思

谢谢，原来是输入和输出缓冲区的问题

在每个最后不带\n的printf后面加fflush(stdout); 在每个不想受接收缓冲区旧内容影响的scanf前面加rewind(stdin); 另外请检查scanf的返回值。  代码功能归根结底不是别人帮自己看或讲解或注释出来的；而是被自己静下心来花足够长的时间和精力亲自动手单步或设断点或对执行到某步获得的中间结果显示或写到日志文件中一步一步分析出来的。 提醒：再牛×的老师也无法代替学生自己领悟和上厕所！ 单步调试和设断点调试是程序员必须掌握的技能之一。

还有LZ不要调用本代码中不需要的头文件，去掉#include <stdlib.h> #include <malloc.h> ，这样将加快代码编译速度和减少生成文件的大小

LZ是否应该把_INDUSTRIAL_INFO_ DATA[5]={0}; 改为_INDUSTRIAL_INFO_ DATA[2]={0}; 这样将节省3个_INDUSTRIAL_INFO_空间

引用 6 楼 u014724273 的回复:[quote=引用 1 楼 zhao4zhong1 的回复:] 在每个最后不带\n的printf后面加fflush(stdout); 为什么是不带\n[/quote] 带\nprintf底层会自动fflush(stdout);

引用 1 楼 zhao4zhong1 的回复:在每个最后不带\n的printf后面加fflush(stdout); 为什么是不带\n

指针对应的是一个数组，指向数组下一个元素，当指针在在数组末尾时，指向数组第一个元素； 因为是2个元素的数组，所以%2；


Question: 如何将很多文件封装成一个文件，扩展名任意，封装后的文件可供程序调用其中的资源，也就是原来文件夹内的文件是可用的。

提醒：指针在内存中是内存地址，在文件中是相对文件开头的偏移量。 fopen(...,"wb"),fwrite,fclose;fopen(...,"rb"),fseek,fread,fclose; _open,_lseeki64,_write,_read,_close;

7z源代码中难道不提供目录相关功能？

引用 1 楼 zhao4zhong1 的回复:为什么不WinExec("c:\\program files\winrar\rar.exe a -r d:\\mypack.mpk d:\\mydir\\*.*",SW_HIDE);呢我是用mfc中的7z源代码压缩的，但现在要写文件头+数据头+数据，然后再把两者合并起来。就是上面的。能不能这样做给个思路？


Question: c语言，求大神解答

嗯！！！！！！！

首地址就比如int a[][50],就可以吗？

嗯嗯，这个知道，谢谢

还有自定义的函数名不能用main哦，main 是系统识别的。

就算这样写main(int a[][50])，函数传入的也并不是一个数组而是一个指针等价于 main(int (*a)[50])==main( int **a); 所以你可以传递数组的首地址 就可以访问该数组的成员。

还应该怎么改？谢谢。比如自定义函数判断是不是素数，然后主函数输入数组数据?

不能！！！！！！！！！！！！！！！！！


Question: 关于Labwiondows/cvi

labwiondows cvi可能用不了depends.exe 你先确认你的cvi及相关扩展库安装全了。

用的软件是labwiondows cvi也可以吗，没有找到depends.exe啊

少The analysis library DLL啊。 用depends.exe查看exe依赖的dll。


Question: acm 小题

我也不会，没看懂那题目。 顺手试了试地址，好像不能注入。


Question: 结构体指针的释放问题！

没有malloc/alloc的时候调用free出错是可以预见的错误

函数内部声明的变量都是在栈上的，不是在堆上，因此不用free，free是用来释放她丈夫malloc干出来的“孩子（动态分配的内存）”的！malloc，free是一夫一妻制！

不要单独使用malloc和free

引用 2 楼 xiaohuh421 的回复:首先, 在结构体struct B生成具体数据的时候, 需要初始化buf为NULL. 再有, 必需是要malloc申请, 才能使用free.  没看到你的initfunction是怎么写的,   如果有代码, 应该就能看到是什么问题了.   二楼正解！楼主的问题已经可以解决

使用free的同时要用用malloc库函数创建的内存，不然会报错的


Question: 请问在c语言里面怎么计算递归的次数？

“给定一个小点的输入，完整单步跟踪(同时按Alt+7键查看Call Stack里面从上到下列出的对应从里层到外层的函数调用历史)一遍。”是理解递归函数工作原理的不二法门！ 递归函数关注以下几个因素 ·退出条件 ·参数有哪些 ·返回值是什么 ·局部变量有哪些 ·全局变量有哪些 ·何时输出 ·会不会导致堆栈溢出

定义一个全局变量，在递归的每一层加一不就行了！

例如一个矩阵是 0 0 1 1 1 1 1 1 1 0 0 0 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 那最大的size应该是6，但是我这个程序出来的是7，而单行的情况应该要排除的

用全局变量或静态变量。初值0，进入函数++


Question: 新人发帖，自己编写的同学信息管理程序，读取信息与查找的时候一直出错。

我也是新手，最近刚好也编过学生信息管理程序，方式有点不一样。胡乱说点意见，不知道是不是你在保存信息的时候，（因为你用的是字符串形式输入的），系统后面自动加了‘\0’的缘故。所以你在查找的时候就对不上了。（我也没试过，不知道是不是这个原因）

推荐使用WinHex软件查看硬盘或文件或内存中的原始字节内容。

可能是字节对齐的问题。可以参考这个看看http://blog.csdn.net/chenglibin1988/article/details/8882852

引用 2 楼 user-3 的回复:这个要一步步调试，先确保输入的信息保存好了，然后查找的数据地址是对的。  我之前自己也调试了很多次，做了很多修改，发现了一些问题。  首先数据的写入都没有报错。 问题在后面，如果我写入了一个数据，然后读取的时候，首先读取一次，将文件中的数据放入stu[0]中，这个也没有报错，然后读取第二个数据放入stu[1]中报错了（这个当然会报错，因为只写入了一个数据），问题是我循环输出stu[]时，第一次循环，输出stu[0]，输出的是空格，第二次输出stu[1]就是之前写入的数据。  如果我写入两个数据，写入也是没有错，关键在循环读取的时候，循环两次没报错，但是在输出的时候，stu[0]输出的是空格，stu[1]输出的是写入的第二个数据。

这个要一步步调试，先确保输入的信息保存好了，然后查找的数据地址是对的。

求助各位大神。。。。


Question: C语言 用单链表实现栈的功能 请教pop怎么实现 我这错在哪里

最终代码献上，谢谢各位的指点。  #include<stdio.h> #include<stdlib.h>  struct node{ 	int data; 	struct node *next; }; struct node *head,*temp,*current;  int length(){ 	int length=0; 	current=head; 	while(current->next!=NULL){ 		length++; 		current=current->next; 	} 	return length; }  void push(int num){ 	struct node *pnode=(struct node*)malloc(sizeof(struct node)); 	pnode->data=num; 	pnode->next=head; 	head=pnode; }  void pop(){ 	if(head->next==NULL) 		return; 	else{ 		temp=head; 		head=head->next; 		free(temp); 		temp=NULL;//避免野指针 		printf("pop successfully!\n"); 	} }  void print(){ 	current=head; 	while(current->next!=NULL){ 		printf("<<---%d",current->data); 		current=current->next; 	} 	printf("\n"); }  void main(){ 	head=(struct node *)malloc(sizeof(struct node)); 	head->next=NULL; 	printf("                  1:length\n"); 	printf("                  2:push\n"); 	printf("                  3:pop\n"); 	printf("                  4:print\n"); 	printf("                  0:exit\n"); 	int choice; 	int number; 	while(1){ 		printf("please enter your choice:"); 		scanf("%d",&choice); 		switch(choice){ 			case 1: 				printf("stack size is:%d\n",length(head));	 				break; 			case 2: 				printf("please enter a number:"); 				scanf("%d",&number); 				push(number); 				print(); 				break; 			case 3: 				pop(); 				print(); 				break; 			case 4: 				print(); 				break; 			case 0:exit(0); 			default: 				printf("wrong choice!\n"); 				break; 		} 	} }

引用 14 楼 neolyao 的回复:这些基本的数据结构 教材上应该有的吧！ 是的，但是我总感觉自己的想法和书上不一样，额，是作死的节奏么。

这些基本的数据结构 教材上应该有的吧！

引用 10 楼 liuhengxiao 的回复:如果你还是想用链表实现栈，而且用尾插的话，你可以用双向循环链表，道理和单链表的头插差不多是一个意思 头插法让我感觉像FIFO而不是LIFO

引用 7 楼 xiaohuh421 的回复:pop是出栈, 你又new一个出来, 明显是不对的.  void pop(){     if(head == NULL)     {           printf("stack is empty!\n");//这里可以打印点东西          return;  //如果头节点也是空, 则还没有任何数据, 直接返回.     }     temp=head; //保存当前的head     head = head->next; //head指向栈中的下一个元素(也就相当于出栈了).     free(temp);  //释放原来的头节点     temp = NULL;  //防止野指针    }  看来我错了，我是应该用头插法和删除首节点，我本来是想实现尾插尾删除的，现在想想，这种方法时间复杂度更大。

引用 9 楼 liuhengxiao 的回复:int main(){     head=(struct node *)malloc(sizeof(struct node));     head=NULL;  应该是head->next=NULL；额，head=NULL是初始栈为空

栈内也是节点存在，节点与节点之间的联系和链表有什么不同？  实际上栈就等同于链表的头插和首节点删除  看你用个尾插的链表思路去实现栈，这是有什么特殊需求么？

LIFO，所以改用头插法吧，pop/push不需要去遍历整个链表...

抱歉，代码最后的0是return 0; }  , 复制时出了点小问题

引用 1 楼 u012033027 的回复:while(current->next!=NULL){             current=current->next;         }         temp=current->next;         current->next=temp->next;  wihle之后，current->next == NULL，也就是temp = NULL; 那么，temp->next 就是非法的。 请问我该如何修改呢

对啊，是LIFO，因我我实现的是栈的功能，请指点，我该如何写呢

pop是指第一个LIFO吗？ 想想还挺绕的


Question: c语言位运算的一个问题。

学习到了，汇编好强大啊。可我不怎么看的很清楚，呜呜呜。。。。

引用 17 楼 halfword1982 的回复:针对32位系统，当算术左移位数大于31时，C标准中对该移位操作是未定义的。  unsigned in i = 1; int n = 32; i <<= n;   上述C代码在Intel x86、PowerPC、ARM架构CPU下对应的汇编指令和移位执行说明如下：  ;;Intel ;;将寄存器eax中的值左移，移动位数为寄存器cl中的值，结果存在eax中 ;;仅取寄存器cl最低5 bits的值作为移位数 ;;当cl寄存器中的值为32时，该操作等价于shl    eax, 0，即移位操作无效 shl    eax,cl   ;;PowerPC ;;将寄存器RS中的值左移，移动位数为寄存器RB中的值，结果存在RA中 ;;仅取寄存器RB的高6 bits作为移位数，当移位数为32-63时，移位结果为0 slw  RA,RS,RB   ;;ARM ;;将寄存器Rm中的值左移，移动位数为寄存器Rm中的值，结果存在Rd中 ;;仅取Rs的最低8 bits作为移位数，当移位数大于31时，移位结果为0 LSL  Rd, Rm, Rs   可以看到，对于C标准中未定义的操作，不同架构CPU有不同的实现和限制，导致计算结果不同。  C标准中哪里来的“算术左移”？

引用 16 楼 sholber 的回复:[quote=引用 9 楼 halfword1982 的回复:] 这个问题的关键在于n的值为32，对于32位系统，算术左移位数的合法值为0-31，超过该范围时，移位操作的结果在C标准中是未定义的，完全取决于芯片厂家的实现。  Intel对于算术左移指令有如下的规定：  SAL/SAR/SHL/SHR—Shift  The count is masked to 5 bits (or 6 bits if in 64-bit mode and REX.W is used). The count range is limited to 0 to 31 (or 63 if 64-bit mode and REX.W is used).  借用楼上的代码，地址0040104F处的shl指令即对应(~0U << n)的计算，寄存器cl中的值为n=32，取最低5 bits的值为0，所以该指令执行后，eax中的值依然为0xffffffff  20:       r = (~(~0U << n) << ( p + 1 - n)); 00401049   or          eax,0FFh 0040104C   mov         ecx,dword ptr [ebp+10h] 0040104F   shl         eax,cl 00401051   not         eax 00401053   mov         ecx,dword ptr [ebp+0Ch] 00401056   add         ecx,1 00401059   sub         ecx,dword ptr [ebp+10h] 0040105C   shl         eax,cl 0040105E   mov         dword ptr [ebp-4],eax   完全取决于芯片厂家是什么意思？[/quote] 其实这应该是undefined behavior而不是implementation-defined。标准规定这是UB是考虑到编译器可以对于这类操作做constant folding，这个fold的结果可以和目标cpu的指令效果不同。

引用 9 楼 halfword1982 的回复:这个问题的关键在于n的值为32，对于32位系统，算术左移位数的合法值为0-31，超过该范围时，移位操作的结果在C标准中是未定义的，完全取决于芯片厂家的实现。  Intel对于算术左移指令有如下的规定：  SAL/SAR/SHL/SHR—Shift  The count is masked to 5 bits (or 6 bits if in 64-bit mode and REX.W is used). The count range is limited to 0 to 31 (or 63 if 64-bit mode and REX.W is used).  借用楼上的代码，地址0040104F处的shl指令即对应(~0U << n)的计算，寄存器cl中的值为n=32，取最低5 bits的值为0，所以该指令执行后，eax中的值依然为0xffffffff  20:       r = (~(~0U << n) << ( p + 1 - n)); 00401049   or          eax,0FFh 0040104C   mov         ecx,dword ptr [ebp+10h] 0040104F   shl         eax,cl 00401051   not         eax 00401053   mov         ecx,dword ptr [ebp+0Ch] 00401056   add         ecx,1 00401059   sub         ecx,dword ptr [ebp+10h] 0040105C   shl         eax,cl 0040105E   mov         dword ptr [ebp-4],eax   完全取决于芯片厂家是什么意思？

引用 9 楼 halfword1982 的回复:这个问题的关键在于n的值为32，对于32位系统，算术左移位数的合法值为0-31，超过该范围时，移位操作的结果在C标准中是未定义的，完全取决于芯片厂家的实现。  Intel对于算术左移指令有如下的规定：  SAL/SAR/SHL/SHR—Shift  The count is masked to 5 bits (or 6 bits if in 64-bit mode and REX.W is used). The count range is limited to 0 to 31 (or 63 if 64-bit mode and REX.W is used).  借用楼上的代码，地址0040104F处的shl指令即对应(~0U << n)的计算，寄存器cl中的值为n=32，取最低5 bits的值为0，所以该指令执行后，eax中的值依然为0xffffffff  20:       r = (~(~0U << n) << ( p + 1 - n)); 00401049   or          eax,0FFh 0040104C   mov         ecx,dword ptr [ebp+10h] 0040104F   shl         eax,cl 00401051   not         eax 00401053   mov         ecx,dword ptr [ebp+0Ch] 00401056   add         ecx,1 00401059   sub         ecx,dword ptr [ebp+10h] 0040105C   shl         eax,cl 0040105E   mov         dword ptr [ebp-4],eax  不够严谨。 你能告诉我 char c = 1; int i = sizeof (int) * CHAR_BIT - 1; c = c << i;是未定义的吗？为什么？

电脑内存或文件内容只是一个一维二进制字节数组及其对应的二进制地址； 人脑才将电脑内存或文件内容中的这个一维二进制字节数组及其对应的二进制地址的某些部分看成是整数、有符号数/无符号数、浮点数、复数、英文字母、阿拉伯数字、中文/韩文/法文……字符/字符串、汇编指令、函数、函数参数、堆、栈、数组、指针、数组指针、指针数组、数组的数组、指针的指针、二维数组、字符点阵、字符笔画的坐标、黑白二值图片、灰度图片、彩色图片、录音、视频、指纹信息、身份证信息……

引用 5 楼 zhao4zhong1 的回复:[quote=引用 4 楼 luanxia77 的回复:] 楼上，你这个算什么。。。。？ 人间正道是沧桑， 编程正道是汇编。[/quote] 学C要靠汇编，那你说(char)1<<1LL的结果是啥类型，并用汇编证明。

引用 13 楼 sholber 的回复:不够严谨。 你能告诉我 char c = 1; int i = sizeof (int) * CHAR_BIT - 1; c = c << i;是未定义的吗？为什么？  上述移位操作是否为未定义取决于char类型的符号定义。如果char为signed char，移位计算前，其类型提升为signed int，移位操作的结果（数值结果，正值）超过了signed int的范围，该操作为未定义的；如果char为unsigned char，则该操作的定义是确定的。

//32bits反转： x = (x & 0x55555555) << 1 | (x & 0xAAAAAAAA) >> 1; x = (x & 0x33333333) << 2 | (x & 0xCCCCCCCC) >> 2; x = (x & 0x0F0F0F0F) << 4 | (x & 0xF0F0F0F0) >> 4; x = (x & 0x00FF00FF) << 8 | (x & 0xFF00FF00) >> 8; x = (x & 0x0000FFFF) << 16 | (x & 0xFFFF0000) >> 16;  /*circle left shift :y = (x << n) | (x >> (32 - n)); circle right shift:y = (x >> n) | (x << (32 - n)); 由循环移位，第4,5句优化为：*/ x = (x << 24) | ((x & 0xFF00) << 8) |  	((x >> 8) & 0xFF00) | (x >> 24);  //32b，4字节反转： y = x & 0x00FF00FF; (y >> 8) | (y << 24) | (((x << 8) | (x >> 24)) & 0x00FF00FF);

引用 9 楼 halfword1982 的回复:这个问题的关键在于n的值为32，对于32位系统，算术左移位数的合法值为0-31，超过该范围时，移位操作的结果在C标准中是未定义的，完全取决于芯片厂家的实现。  Intel对于算术左移指令有如下的规定：  SAL/SAR/SHL/SHR—Shift  The count is masked to 5 bits (or 6 bits if in 64-bit mode and REX.W is used). The count range is limited to 0 to 31 (or 63 if 64-bit mode and REX.W is used).   借用楼上的代码，地址0040104F处的shl指令即对应(~0U << n)的计算，寄存器cl中的值为n=32，取最低5 bits的值为0，所以该指令执行后，eax中的值依然为0xffffffff  20:       r = (~(~0U << n) << ( p + 1 - n)); 00401049   or          eax,0FFh 0040104C   mov         ecx,dword ptr [ebp+10h] 0040104F   shl         eax,cl 00401051   not         eax 00401053   mov         ecx,dword ptr [ebp+0Ch] 00401056   add         ecx,1 00401059   sub         ecx,dword ptr [ebp+10h] 0040105C   shl         eax,cl 0040105E   mov         dword ptr [ebp-4],eax  真的很感谢。

引用 6 楼 zhao4zhong1 的回复:16: 17:   unsigned int invert( unsigned int x , int p , int n) 18:   { 00401040   push        ebp 00401041   mov         ebp,esp 00401043   sub         esp,48h 00401046   push        ebx 00401047   push        esi 00401048   push        edi 19:       unsigned int r; 20:       r = (~(~0U << n) << ( p + 1 - n)); 00401049   or          eax,0FFh 0040104C   mov         ecx,dword ptr [ebp+10h] 0040104F   shl         eax,cl 00401051   not         eax 00401053   mov         ecx,dword ptr [ebp+0Ch] 00401056   add         ecx,1 00401059   sub         ecx,dword ptr [ebp+10h] 0040105C   shl         eax,cl 0040105E   mov         dword ptr [ebp-4],eax 21: 22:       //printf("r = %x\n",r); 23: 24: 25:       unsigned s = r & x; 00401061   mov         ecx,dword ptr [ebp-4] 00401064   and         ecx,dword ptr [ebp+8] 00401067   mov         dword ptr [ebp-8],ecx 26:       //printf("s = %x \n",s); 27: 28:       x = x | r; 0040106A   mov         edx,dword ptr [ebp+8] 0040106D   or          edx,dword ptr [ebp-4] 00401070   mov         dword ptr [ebp+8],edx 29: 30:       x = x & (~s); 00401073   mov         eax,dword ptr [ebp-8] 00401076   not         eax 00401078   mov         ecx,dword ptr [ebp+8] 0040107B   and         ecx,eax 0040107D   mov         dword ptr [ebp+8],ecx 31: 32:       return x ; 00401080   mov         eax,dword ptr [ebp+8] 33: 34:   } 00401083   pop         edi 00401084   pop         esi 00401085   pop         ebx 00401086   mov         esp,ebp 00401088   pop         ebp 00401089   ret  16: 17:   unsigned int invert( unsigned int x , int p , int n) 18:   { 00401040   push        ebp 00401041   mov         ebp,esp 00401043   sub         esp,48h 00401046   push        ebx 00401047   push        esi 00401048   push        edi 19:       unsigned int r; 20:       r = (~(~0U << n) << ( p + 1 - n)); 00401049   or          eax,0FFh 0040104C   mov         ecx,dword ptr [ebp+10h] 0040104F   shl         eax,cl 00401051   not         eax 00401053   mov         ecx,dword ptr [ebp+0Ch] 00401056   add         ecx,1 00401059   sub         ecx,dword ptr [ebp+10h] 0040105C   shl         eax,cl 0040105E   mov         dword ptr [ebp-4],eax 21: 22:       //printf("r = %x\n",r); 23: 24: 25:       unsigned s = r & x; 00401061   mov         ecx,dword ptr [ebp-4] 00401064   and         ecx,dword ptr [ebp+8] 00401067   mov         dword ptr [ebp-8],ecx 26:       //printf("s = %x \n",s); 27: 28:       x = x | r; 0040106A   mov         edx,dword ptr [ebp+8] 0040106D   or          edx,dword ptr [ebp-4] 00401070   mov         dword ptr [ebp+8],edx 29: 30:       x = x & (~s); 00401073   mov         eax,dword ptr [ebp-8] 00401076   not         eax 00401078   mov         ecx,dword ptr [ebp+8] 0040107B   and         ecx,eax 0040107D   mov         dword ptr [ebp+8],ecx 31: 32:       return x ; 00401080   mov         eax,dword ptr [ebp+8] 33: 34:   } 00401083   pop         edi 00401084   pop         esi 00401085   pop         ebx 00401086   mov         esp,ebp 00401088   pop         ebp 00401089   ret  我刚刚对着汇编代码一行一行的运行了一下， 就在这一行 dword ptr [ebp-4],eax的时候，eax是0xffffffff，但是我看r的内存地址的时候，赋值并没有成功，但是我在watch整个表达式之后又再，再watch变量r，r的内存就是fffffff了。感觉不知道为什么？

引用 6 楼 zhao4zhong1 的回复:16: 17:   unsigned int invert( unsigned int x , int p , int n) 18:   { 00401040   push        ebp 00401041   mov         ebp,esp 00401043   sub         esp,48h 00401046   push        ebx 00401047   push        esi 00401048   push        edi 19:       unsigned int r; 20:       r = (~(~0U << n) << ( p + 1 - n)); 00401049   or          eax,0FFh 0040104C   mov         ecx,dword ptr [ebp+10h] 0040104F   shl         eax,cl 00401051   not         eax 00401053   mov         ecx,dword ptr [ebp+0Ch] 00401056   add         ecx,1 00401059   sub         ecx,dword ptr [ebp+10h] 0040105C   shl         eax,cl 0040105E   mov         dword ptr [ebp-4],eax 21: 22:       //printf("r = %x\n",r); 23: 24: 25:       unsigned s = r & x; 00401061   mov         ecx,dword ptr [ebp-4] 00401064   and         ecx,dword ptr [ebp+8] 00401067   mov         dword ptr [ebp-8],ecx 26:       //printf("s = %x \n",s); 27: 28:       x = x | r; 0040106A   mov         edx,dword ptr [ebp+8] 0040106D   or          edx,dword ptr [ebp-4] 00401070   mov         dword ptr [ebp+8],edx 29: 30:       x = x & (~s); 00401073   mov         eax,dword ptr [ebp-8] 00401076   not         eax 00401078   mov         ecx,dword ptr [ebp+8] 0040107B   and         ecx,eax 0040107D   mov         dword ptr [ebp+8],ecx 31: 32:       return x ; 00401080   mov         eax,dword ptr [ebp+8] 33: 34:   } 00401083   pop         edi 00401084   pop         esi 00401085   pop         ebx 00401086   mov         esp,ebp 00401088   pop         ebp 00401089   ret  16: 17:   unsigned int invert( unsigned int x , int p , int n) 18:   { 00401040   push        ebp 00401041   mov         ebp,esp 00401043   sub         esp,48h 00401046   push        ebx 00401047   push        esi 00401048   push        edi 19:       unsigned int r; 20:       r = (~(~0U << n) << ( p + 1 - n)); 00401049   or          eax,0FFh 0040104C   mov         ecx,dword ptr [ebp+10h] 0040104F   shl         eax,cl 00401051   not         eax 00401053   mov         ecx,dword ptr [ebp+0Ch] 00401056   add         ecx,1 00401059   sub         ecx,dword ptr [ebp+10h] 0040105C   shl         eax,cl 0040105E   mov         dword ptr [ebp-4],eax 21: 22:       //printf("r = %x\n",r); 23: 24: 25:       unsigned s = r & x; 00401061   mov         ecx,dword ptr [ebp-4] 00401064   and         ecx,dword ptr [ebp+8] 00401067   mov         dword ptr [ebp-8],ecx 26:       //printf("s = %x \n",s); 27: 28:       x = x | r; 0040106A   mov         edx,dword ptr [ebp+8] 0040106D   or          edx,dword ptr [ebp-4] 00401070   mov         dword ptr [ebp+8],edx 29: 30:       x = x & (~s); 00401073   mov         eax,dword ptr [ebp-8] 00401076   not         eax 00401078   mov         ecx,dword ptr [ebp+8] 0040107B   and         ecx,eax 0040107D   mov         dword ptr [ebp+8],ecx 31: 32:       return x ; 00401080   mov         eax,dword ptr [ebp+8] 33: 34:   } 00401083   pop         edi 00401084   pop         esi 00401085   pop         ebx 00401086   mov         esp,ebp 00401088   pop         ebp 00401089   ret  谢谢。。。。 我先去看一下win32的基本汇编指令。。。

引用 4 楼 luanxia77 的回复:楼上，你这个算什么。。。。？ 人间正道是沧桑， 编程正道是汇编。

楼上，你这个算什么。。。。？

bc++3.1 帮助里面对每个函数都有一小段能拷贝出来运行看效果的例子程序。非常适合初学C语言。相比较而言VC带的帮助MSDN就没有。http://download.csdn.net/source/2805028 计算机组成原理→DOS命令→汇编语言→C语言（不包括C++）、代码书写规范→数据结构、编译原理、操作系统→计算机网络、数据库原理、正则表达式→其它语言（包括C++）、架构……  对学习编程者的忠告： 眼过千遍不如手过一遍！ 书看千行不如手敲一行！ 手敲千行不如单步一行！ 单步源代码千行不如单步对应汇编一行！  VC调试时按Alt+8、Alt+7、Alt+6和Alt+5,打开汇编窗口、堆栈窗口、内存窗口和寄存器窗口看每句C对应的汇编、单步执行并观察相应堆栈、内存和寄存器变化，这样过一遍不就啥都明白了吗。 对VC来说，所谓‘调试时’就是编译连接通过以后，按F10或F11键单步执行一步以后的时候，或者在某行按F9设了断点后按F5执行停在该断点处的时候。 （Turbo C或Borland C用Turbo Debugger调试,Linux或Unix下用GDB调试时,看每句C对应的汇编并单步执行观察相应内存和寄存器变化。）

刚刚到ubuntu下测试了一下也是这样的。

刚刚用windows测试了一下也是这样的情况。现在换linux试试看。


Question: 才学指针与数组的关系，有个问题不明白

你的数组没有初始化  所以得到的结果也是不确定的

之申明，未定义的变量出现的数字都是随机数。

引用 3 楼 Gonefar 的回复:这是由于没有初始化a数组的问题。a由于没有初始化，所以刚好a[7]的ascii值为0，而a[7]以前都不为0。所以会出现你的结果，你可以把a[9]每个元素的ascii值打印出来。我运行的结果是这样的  -64 5 64 0 0 0 0 0 0  123 上面一行为a[9]的各元素的ascii值。下面一行为输出结果。 请问下像这种没初始化的数组，它里面的每个元素的值是怎么弄出来的了，我试了试，的确a[7]的值为0，但前面的值各异

引用 1 楼 neolyao 的回复: int n = 1; //这里改一下 ‘1’是字符不是int  ，转换为int 实际值是49  引用 1 楼 neolyao 的回复: int n = 1; //这里改一下 ‘1’是字符不是int  ，转换为int 实际值是49   看错提了不好意思 ，因为a[7]里面是'\0'啊，所一到7就停止循环了


Question: c代码实现单链表，可惜反转链表没写出来啊

写成双向链表，就不用反转喽 如果非要单链表翻转，把现有的链表从头挨个取下，以头插入办法重新建表，就翻转成功！ 或者，对现有链表，从第二个结点开始（需要头结点），挨个调换next指针，使其指向前一个结点，不懂看下面示例  已有链表：H->A->B->C->D-H; 调整： r=H; p=B; q=A; q->next = r;  r=p; q=B; p=B->next; q->next = r; 。。。 H<-A<-B<-C<-D 最后调整H，H->D 实际上本质和头插入法重新建表一致的

翻转的话，需要   前一个节点，后一个节点  以及当前节点 一个一个来！

反转链表：   把链表的首节点取出，入栈，直到链表为空，然后出栈的节点尾插到链表，直到栈空

#include <stdio.h> #include <stdlib.h> #include <Windows.h> //头插入法创建链表 int main() {  typedef struct NODE  {   char date;   struct NODE * next;  }node;  node  *s, *p;  char  ch;  s =NULL;p=NULL;  while ((ch =getchar()) != '\n')  {   s = p;   p =(node *)malloc(sizeof(node));   p ->date =ch;   p ->next =s;  }  while (p !=NULL)  {   printf("%c",p ->date);   p =p ->next;  }  printf("\n");  Sleep(10000);  return 0; }


Question: C语言中字符串与十进制的互相转换

#include <stdio.h> #include <stdlib.h> #include <string.h> #include <locale.h> int main() {     int i,v;     char bs[33];     char b[33];     char hs[9];     char h[9];     char s[4];     char *e;  // 十进制整数转二进制串；     i=1024;     ltoa(i,b,2);     sprintf(bs,"%032s",b);     printf("i=%d,bs=%s\n",i,bs); // 十进制整数转十六进制串；     i=1024;     ltoa(i,h,16);     sprintf(hs,"%08s",h);     printf("i=%d,hs=%s\n",i,hs); // 十六进制字符串转成十进制数     strcpy(hs,"00000400");     sscanf(hs,"%x",&i);     printf("hs=%s,i=%d\n",hs,i); // 二进制字符串转化为十六进制字符串；     strcpy(bs,"00000000000000000000010000000000");     i=strtol(bs,&e,2);     ltoa(i,h,16);     sprintf(hs,"%08s",h);     printf("bs=%s,hs=%s\n",bs,hs); // 二进制字符串转化为十进制数；     strcpy(bs,"00000000000000000000010000000000");     i=strtol(bs,&e,2);     printf("bs=%s,i=%d\n",bs,i); // 十六进制字符串转成二进制串     strcpy(hs,"00000400");     sscanf(hs,"%x",&i);     ltoa(i,b,2);     sprintf(bs,"%032s",b);     printf("hs=%s,bs=%s\n",hs,bs); // ASC\GBK字符串转十六进制串     strcpy(s,"a汉");     i=0;     while (1) {         if (0==s[i]) break;         sprintf(hs+i*2,"%02X",(unsigned char)s[i]);         i++;     }     setlocale(LC_ALL,"chs");     printf("s=%s,hs=%s\n",s,hs); // 十六进制字符串转成汉字（GBK）及字符(ASC)     strcpy(hs,"61BABA");     i=0;     while (1) {         if (1!=sscanf(hs+i*2,"%2x",&v)) break;         s[i]=(char)v;         i++;     }     s[i]=0;     printf("hs=%s,s=%s\n",hs,s);      return 0;  } //i=1024,bs=00000000000000000000010000000000 //i=1024,hs=00000400 //hs=00000400,i=1024 //bs=00000000000000000000010000000000,hs=00000400 //bs=00000000000000000000010000000000,i=1024 //hs=00000400,bs=00000000000000000000010000000000 //s=a汉,hs=61BABA //hs=61BABA,s=a汉

上面搞错了， itoa 能够转换成16进制字符串表，从 2～36进制都没问题 不过atoi不能把16进制字符串，转换成二进制（内部表示）

引用 3 楼 conanson 的回复:[quote=引用 1 楼 lovehuan54 的回复:] 两个字节？ 这个是要求？  如果没有字节限制可以直接用sprintf 是的，协议里要求两个字节，对于unsigned short十进制转字符串，我一个想法是先转成二进制，然后高八位一个字节，低八位一个字节。[/quote] unsigned short 内部表示就是两个字节， 但是不是字符串，要定长，就转换为16进制字符串4个字节。 否则直接转换为10进制大概5个字节以内不定长。 直接库函数的话，sprintf,sscanf 就可以满足要求了，如果需要更快一点 atoi 和itoa，不过itoa 不能转换成16进制字符串表示。

引用 1 楼 lovehuan54 的回复:两个字节？ 这个是要求？  如果没有字节限制可以直接用sprintf 是的，协议里要求两个字节，对于unsigned short十进制转字符串，我一个想法是先转成二进制，然后高八位一个字节，低八位一个字节。

调用atoi就行了，实现也很简单。< c programing language> 书上就有

两个字节？ 这个是要求？  如果没有字节限制可以直接用sprintf #include "stdio.h"  int main(void) { 	int test = 6325; 	char result[5] = {0};  	sprintf(result, "%d", test);  	printf("result is %s\n", result); }


Question: 海康威视面试题（老早的08年的），不过没看懂这个结构是干嘛的，即使穿是串结构，但是这data类型搞不懂

数据结构中有一章节讲的就是串结构

引用 10 楼 xihu1364 的回复:用啥结构体 直接2个数组  for循环 就搞定  多此一举面试题要求用接结构体

用啥结构体 直接2个数组  for循环 就搞定  多此一举

遍历一次，加辅助空间，逆向链表

是不是先遍历取出数据，再次遍历逆序替换值？代价是2次遍历加部分辅助内存

struct Node {                int   data;                Node* next; }  void reverse(Node* pInHead , Node* pOutHead) {   ...  链表倒序输出  }  递归，或者 链表反向

难道是想要用递归逆序打印实现？？

引用 2 楼 xiaomi163 的回复:[quote=引用 1 楼 My_ID_is_NULL 的回复:] 难道要用链表来表示字符串？这个也太不走寻常路了 应该是的，但是这已给的结构怎么表示，搞不清楚。[/quote] 如果是这样的话，应该是想用int型的data来表示char，感觉出这题目的人脑子进水了

用ascii码来表示一个字符? 用结构体太不划算了

引用 1 楼 My_ID_is_NULL 的回复:难道要用链表来表示字符串？这个也太不走寻常路了 应该是的，但是这已给的结构怎么表示，搞不清楚。

难道要用链表来表示字符串？这个也太不走寻常路了


Question: windows驱动创建设备失败问题

去其他地方问问吧


Question: 求教一个从一段内存区域读取数据的问题

引用 5 楼 xihu1364 的回复:[quote=引用 4 楼 xihu1364 的回复:] BYTE* buff = buffer; int  _nData = *(int*)(buff + 4);//应该是4个字节  32个位 _nData = _nData <<4  //这里是不是应该想左移？   不能确定 一起学习  BYTE* buff = buffer; int  _nData = *(int*)(buff + 4);//应该是4个字节  32个位 _nData = _nData >>4  是这样了上面说错了  [/quote] 昨天去问老板了，他说的是补够32位再转换成int类型，即：先判断出第28位是0还是1，然后补的4位就是0或者1。再转换成int类型就行了

以上所有回复，如何考虑符号位呢？

引用 楼主 iloveiverson 的回复:有一段buffer共0-100位，其中从32位到59位共28位中存放着一个整数类型的数据，区分正负号。 请问我怎么把这个数据读取出来？  100bit ，12.5个字节，实际分配应该是>=13B，只需确定目标位在第几个字节，然后位运算。

如果真是位的话，参考下面： //有一个二进制文件，要求每隔50bits，删除后面的12bits。 #include <stdio.h> #include <stdlib.h> #include <string.h> FILE *fi,*fo; char buf[31]; char obf[31]; int bn,n; void filter() {//对buf中前n个字节中的位，每隔50bits，忽略12bits，结果放在obf中,且将bn设置为obf中的字节数。     char bit[249];     char obt[249];     char b8[33];     char b88[33];     int i,j;     char *e;      for (i=0;i<n;i++) {         _itoa(buf[i],b8,2);         sprintf(b88,"%032s",b8);         sprintf(bit+i*8,"%s",b88+24);     }      j=0;     for (i=0;i<n*8;i++) {         if (i%62<50) {             obt[j]=bit[i];             j++;         }     }     if (j%8) {         bn=(j/8+1)*8;     } else {         bn=j;     }     for (i=j;i<bn;i++) obt[i]='0';     obt[bn]=0;     bn=bn/8;     for (i=0;i<bn;i++) {         strncpy(b8,obt+i*8,8);b8[8]=0;         obf[i]=(char)strtol(b8,&e,2);     } } int main() {     fi=fopen("in.bin","rb");     if (NULL==fi) {         printf("Can not open file in.bin!\n");         return 1;     }     fo=fopen("out.bin","wb");     if (NULL==fo) {         fclose(fi);         printf("Can not open file out.bin!\n");         return 2;     }     while (1) {         n=fread(buf,1,31,fi);         if (0==n) break;         filter();         fwrite(obf,1,bn,fo);     }     fclose(fo);     fclose(fi);     return 0; }

buffer是以字节为单位的吧！

引用 4 楼 xihu1364 的回复:BYTE* buff = buffer; int  _nData = *(int*)(buff + 4);//应该是4个字节  32个位 _nData = _nData <<4  //这里是不是应该想左移？   不能确定 一起学习  BYTE* buff = buffer; int  _nData = *(int*)(buff + 4);//应该是4个字节  32个位 _nData = _nData >>4  是这样了上面说错了

引用 2 楼 xihu1364 的回复:楼主说的位，是指位还是字节？  如果是字节的话，pBuffer指针指向buffer，  char szNum[29] = {0};  memcpy(szNum,pBuffer + 32,28); //这样第32-59字节全部拷贝到szNum中  你所说的取出来是转换正整形吗？还是字符串？........ 100个bit，用第32个bit到第59个bit共28个bit存放一个有符号整数

我是这样做的不知道有问题没 BYTE* buff = buffer; int  _nData = *(int*)(buffer + 7); _nData = _nData >>4


Question: makefile对头文件的依赖关系

你的 Makefile 没有做更新 .d 文件的目标啊. 怎么也得弄一个 dep : $(DEPS) 啥的. 编译 .c 的时候可以自动更新对应的 .d 的, 这样就不用专门为 .d 弄个目标 比如 gcc -MMD -MT dep/1.d  1.c  啥的 ..

大家的做法是不是头文件有改动 就需要make clean了？？？？？？

makefile最好还是别用啥模版，按照自己的风格来，出错了也好修改

确保电脑时间没乱。

make clean;make  修改了头文件重新clean！

搜“跟我一起写makefile”


Question: 程序无法运行，调试显示program received signal SIGFPE

在if语句中，请养成将常量写在==左侧的好习惯。

if(r==0) break;


Question: [SWU]linux中的ls目录如何实现？

opendir/readdir/closedir用于目录树的遍历 lstat用于查看文件属性 readlink用于查看符号链接的内容 都是Linux的库函数

《unix环境高级编程》这本书可能对你有用

Linux不是号称开放源代码的吗？看ls命令相关源代码片断啊。

man opendir man readdir 要更详细的请参阅Unix系统编程


Question: 快速排序，请问这个程序有什么问题？

主要是，函数使用的时候不用加上函数的返回值类型。

改好了。  #include<stdio.h> void quick(int *a,int n,int m) { 	int temp,i,j; 	i=n; 	j=m-1; 	temp=a[i];     do 	{ 		for( ; a[j]>=temp && j>i; j--) 			; 		a[i]=a[j]; 		for( ; a[i]<temp && j>i; i++) 			; 		a[j]=a[i]; 	} 	while(j>i); 	a[i]=temp; 	if(n<i) 		quick(a, 0, i); 	if(m>i)   		quick(a, i+1, m);   } void main() {     int b[6]={5,9,1,3,2,4},t;     quick (b, 0, 6); 	for(t=0; t<6; t++) 		printf("%d\t",b[t]); }


Question: 关于字符串的输入问题

scanf函数遇到'\n'就结束，并且把'\n'留在缓冲区里面啊

引用 3 楼 zhao4zhong1 的回复:在每个最后不带\n的printf后面加fflush(stdout); 在每个不想受接收缓冲区旧内容影响的scanf前面加rewind(stdin); 另外请检查scanf的返回值。 楼上有人提到的fflush(stdin)与fflush(stdout怎么区别 另外清除printf的缓存和不清除得到的输出结果都相同，清除缓存似乎没什么用处啊，新手表示不解

引用 6 楼 zhenzhen_10 的回复:scanf输入与getchar输入的区别是是否识别enter键，即空格键。。。。上诉代码改成getchar就对了 可是要怎么改呢？用for循环？

我无法理解scanf会把回车键赋给字符变量，scanf不可能会用回车啊

建议你用单步调试，查看b的ASC码

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

回车也是一个字符，被变量b接收了

因为你没有清空缓冲区。  #define _CRT_SECURE_NO_WARNINGS #include<stdio.h> #include <cmath> #include <stdlib.h> int main() { 	char a[10]; 	scanf("%s", a); 	char b; 	fflush(stdin);// 或者getchar() 把缓冲区里面的‘\n’回收 	scanf("%c", &b); 	printf("%c\n", b);     printf("%s\n", a);     return 0; }


Question: 下面这个问题应该有点难度，我想知道为什么，不是要找解决办法的

引用 8 楼 angel_su 的回复:不用原型那就是4楼说的按隐式转换，调用方第一个参数会用double入栈，你得把函数首参改成double估计就匹配了... 恩    和4L说的差不多。

引用 7 楼 Gonefar 的回复:把程序都贴出来看看。  程序就在题目中。

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

把程序都贴出来看看。

这是C专家编程第177页的一个编程挑战，我把形参float提前了。 我问过我们老师，他从事嵌入式开发十多年，他并没有告知我这是为什么。

引用 4 楼 truelance 的回复:因为你没有使用函数原型, 所以编译器不知道函数参数的类型, 只能使用缺省类型, 缺省情况下3.3会被当成double类型, 往栈里写了8个字节. 被调函数c读了前4个字节, b读2个字节(参数存放会按4字节对齐), 这样就把(double)3.3的内容读完. c读的就是之后放入栈的69 你打印形参地址看看，你再打印实参地址看看，  不管它们在主函数用怎样的顺序定义，最后输出值不变。 形参地址值告知了它们不存在覆盖的问题，实参的地址告知了同样的道理。

引用 1 楼 zhao4zhong1 的回复:void banana_peel(float c,short b,char a) {         printf("float=%f,short=%hd,char=%d\n",c,b,a); }  printf里面的%和变量的一一对应关系 scanf里面的%和变量以及变量前加不加&的一一对应关系 是C代码中非常容易出错的地方，而且通常编译还不出错。 所以在编译源代码之前值得专门仔细检查一遍甚至多遍。 不是对应关系的问题。对应关系的问题造成指令取值变化的问题我知道。


Question: 为什么1 << 31结果是负的，而（1<<31）-1结果却是正的呢?

一般按补码解释，最左边一位是1就是负数，是0就是非负数

计算机组成原理→DOS命令→汇编语言→C语言（不包括C++）、代码书写规范→数据结构、编译原理、操作系统→计算机网络、数据库原理、正则表达式→其它语言（包括C++）、架构……  对学习编程者的忠告： 眼过千遍不如手过一遍！ 书看千行不如手敲一行！ 手敲千行不如单步一行！ 单步源代码千行不如单步对应汇编一行！  VC调试时按Alt+8、Alt+7、Alt+6和Alt+5,打开汇编窗口、堆栈窗口、内存窗口和寄存器窗口看每句C对应的汇编、单步执行并观察相应堆栈、内存和寄存器变化，这样过一遍不就啥都明白了吗。 对VC来说，所谓‘调试时’就是编译连接通过以后，按F10或F11键单步执行一步以后的时候，或者在某行按F9设了断点后按F5执行停在该断点处的时候。 （Turbo C或Borland C用Turbo Debugger调试,Linux或Unix下用GDB调试时,看每句C对应的汇编并单步执行观察相应内存和寄存器变化。）

在32位的机器中，1<<31=0x80000000，作为有符号整数，其最高位为1表示负数，其值正好为32位有符号整数的最小值- 2,147,483,648。  (1<<31)-1在机器中计算时转换为2个数相加，即(1<<31)+(-1)，其数学上的计算过程如下所示：     1000 0000 0000 0000 0000 0000 0000 0000 +  1111 1111 1111 1111 1111 1111 1111 1111 ------------------------------------------------------------  1 0111 1111 1111 1111 1111 1111 1111 1111  显然计算结果超过了32位，最高位的1溢出被舍弃，最终机器中的结果为0x7fffffff，即32为有符号整数的最大值2,147,483,647


Question: 如何使用lib文件？

FILE *f; long offset; f=fopen("xxx.lib","rb"); fseek(f,offset,SEEK_SET); fread(…… fclose(f);

引用 2 楼 u014691814 的回复:[quote=引用 1 楼 fengxuxing 的回复:] (1)头文件和库文件都放到vcproject同目录下 (2)引用 #include "xxx.h"   引入头文件 #pragma comment(lib, "xxx.lib") 引入库文件 然后你就可以开始编程了 那怎么用这个库文件呢？现在这个.lib里面全是解释。我可以通过.idx知道某个单词的解释在.lib中的位置。怎么调出来这部分解释呢？[/quote] lib是2进制文件，貌似是无查看其内容的

引用 1 楼 fengxuxing 的回复:(1)头文件和库文件都放到vcproject同目录下 (2)引用 #include "xxx.h"   引入头文件 #pragma comment(lib, "xxx.lib") 引入库文件 然后你就可以开始编程了 那怎么用这个库文件呢？现在这个.lib里面全是解释。我可以通过.idx知道某个单词的解释在.lib中的位置。怎么调出来这部分解释呢？


Question: 急求一道C语言

具体问题是什么？ main()函数要放在最后面。

至少自己先要把格式调工整吧

#include <stdio.h> int InputData(unsigned __int64 *x); int InputYear(); int xxx(unsigned __int64 x,__int64 n); unsigned __int64 xxxx(unsigned __int64 x,__int64 n,__int64 z); int main() { unsigned __int64 x;   int n,i,j,y;   n=InputData(&x);   y=InputYear();   printf("\nOriginal Configuration: "); printf("%lld\n",x);   for ( j=0;j<y;j++ )   { for ( i=0;i<n-1;i++ ) if ( xxx(x,n-i-1)==1 && xxx(x,n-i-2)==2 ) x=xxxx(x,n-i-1,2);     for ( i=n-1;i>=0;i-- ) if ( xxx(x,n-i-1)==1 && xxx(x,n-i)==2 ) x=xxxx(x,n-i-1,2);     printf("Year:%3d Configuration: ",j+1); printf("%lld\n",x);   }   return(0); } int InputData(unsigned __int64 *x) { int b=1,n,y;   unsigned __int64 xx;   while ( b )   { n=b=0;     printf("Enter field configuration: "); scanf("%lld",x); xx=*x;     while ( xx ) { n++; y=xx%10; xx/=10; if ( y!=1 && y!=2 ) { b=1; break; }   }     if ( b ) printf("\nError!  Interger can contain 1 and 2 digits only!!\n");   }   return n; } int InputYear() { int y=-1;    while ( y<0 ) { printf("Enter desired number of years:"); scanf("%d",&y);   if ( y<0 ) printf("\nError! Non-negative years only!!\n"); }   return y;  } int xxx(unsigned __int64 x,__int64 n) { int i,y; for ( i=0;i<n;i++ ) x/=10; y=x%10; return y; } unsigned __int64 xxxx(unsigned __int64 x,__int64 n,__int64 z) { unsigned __int64 xx=0,yy=1;    int i;    for ( i=0;i<n+1;i++ ) yy*=10; xx=x/yy*10+z; yy/=10; xx*=yy; xx+=x%yy; return xx;  }  求高手指导改错


Question: 求大神   基于51单片机的温湿度检测与报警的编程

你准备用何种温湿度检测器件？就先了解下它，51你要不会的话就得学一阵子了，这玩意不难。慢慢学吧 。也可以加我的q 到时候群里说也行 我之前做过一个DHT11的温湿度检测程序没什么特别感觉

买个开发板 学学几个基本例子  很容易的。。。这个系统很容易就可以搞定了，只是涉及到一个传感器和一个驱动器  只是简单io 的操作。。。

先看看51的书，不是特别难，但是要下功夫，能把51啃的精通了，也不容易。多看书吧

自己慢慢来吧

具体的应用，单片机的控制，程序的状态运转没有定式，要烤自己的。LZ既然要做，还是多学学吧。


Question: ADS在make时出错，编译时没问题，帮忙看一下

汇编跟硬件有关系吧


Question: 关于gets的返回值问题

引用 3 楼 zhao4zhong1 的回复:[quote=引用 1 楼 zjq9931 的回复:] char a[100]; 取超过100个，是溢出了，在vc6.0和vs2010没有报错，但程序大了之后就不好说了，指不定出什么烂七八糟的问题呢。。。 这种情况很危险。。。 所以可以用：fgets(a, 99, stdin);// 这个来代替。只读取99个，末尾留上结束位。 纠错： char a[100]; 取超过100个，是溢出了，在vc6.0和vs2010没有报错，但程序大了之后就不好说了，指不定出什么烂七八糟的问题呢。。。 这种情况很危险。。。 所以可以用：fgets(a, 100, stdin);// 这个来代替。只读取99个，末尾留上结束位。 [/quote]好细心，呵呵。

gets, _getws Get a line from the stdin stream.  char *gets( char *buffer );  wchar_t *_getws( wchar_t *buffer );  Routine Required Header Compatibility  gets <stdio.h> ANSI, Win 95, Win NT  _getws <stdio.h> or <wchar.h> ANSI, Win 95, Win NT    For additional compatibility information, see Compatibility in the Introduction.  Libraries  LIBC.LIB Single thread static library, retail version  LIBCMT.LIB Multithread static library, retail version  MSVCRT.LIB Import library for MSVCRT.DLL, retail version    Return Value  Each of these functions returns its argument if successful. A NULL pointer indicates an error or end-of-file condition. Use ferror or feof to determine which one has occurred.  Parameter  buffer  Storage location for input string  Remarks  The gets function reads a line from the standard input stream stdin and stores it in buffer. The line consists of all characters up to and including the first newline character ('\n'). gets then replaces the newline character with a null character ('\0') before returning the line. In contrast, the fgets function retains the newline character. _getws is a wide-character version of gets; its argument and return value are wide-character strings.  Generic-Text Routine Mappings  TCHAR.H Routine  _UNICODE & _MBCS Not Defined _MBCS Defined _UNICODE Defined  _getts gets gets _getws    Example  /* GETS.C */  #include <stdio.h>  void main( void ) {    char line[81];     printf( "Input a string: " );    gets( line );    printf( "The line entered was: %s\n", line ); }   Output  Input a string: Hello! The line entered was: Hello!   Stream I/O Routines  See Also   fgets, fputs, puts

引用 1 楼 zjq9931 的回复:char a[100]; 取超过100个，是溢出了，在vc6.0和vs2010没有报错，但程序大了之后就不好说了，指不定出什么烂七八糟的问题呢。。。 这种情况很危险。。。 所以可以用：fgets(a, 99, stdin);// 这个来代替。只读取99个，末尾留上结束位。 纠错： char a[100]; 取超过100个，是溢出了，在vc6.0和vs2010没有报错，但程序大了之后就不好说了，指不定出什么烂七八糟的问题呢。。。 这种情况很危险。。。 所以可以用：fgets(a, 100, stdin);// 这个来代替。只读取99个，末尾留上结束位。

啊 这个问题没想过，学习了。