Question: 内存问题请教

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

引用 2 楼 u013431701 的回复:这个是什么原理呢？  编译器会加入调试信息

上全部代码！

可能是字节对齐。 你怎么打印的？

我会告诉你是编译器的问题吗？

这个是什么原理呢？

在debug模式下就是这样，如果换成release就不会了。


Question: NuSMV最后make报错，求大牛帮忙

那个在 $$ ./configure  的时候不装会报错，我试试Ubunut 12.04 吧 Thanks 引用 4 楼 turingo 的回复:我在Ubuntu12.04上测试没有问题，会不会是你的flex和bison没有安装。  [quote=引用 楼主 dengnanyi 的回复:] NuSMV是一个基于linux的模型检测工具，小弟安装它出现了问题，求大牛帮帮忙。  这是在Ubuntu Server上安装的，我在此系统上安装成功过NuSMV。  系统里直接apt-get的g++包。  $$ ./configure  命令执行成功 截图如下：   $$ make 命令后报错如下：   求大牛帮帮忙，看看怎么弄这个[/quote]

我在Ubuntu12.04上测试没有问题，会不会是你的flex和bison没有安装。  引用 楼主 dengnanyi 的回复:NuSMV是一个基于linux的模型检测工具，小弟安装它出现了问题，求大牛帮帮忙。  这是在Ubuntu Server上安装的，我在此系统上安装成功过NuSMV。  系统里直接apt-get的g++包。  $$ ./configure  命令执行成功 截图如下：   $$ make 命令后报错如下：   求大牛帮帮忙，看看怎么弄这个

引用 1 楼 wangyaninglm 的回复:这个错误，应该是由配置不正确引起的。。。  求解释啊

我猜的 ，看看楼下大牛的说法

这个错误，应该是由配置不正确引起的。。。

换成Ubuntu12.10 后编译成功


Question: 点子扎手，请求支援这个程序过程似乎有问题

多累，已经知道是3位数，百位和个位相等的数就是回文数   int count=0; for(int i=100; i<1000; ++i)     if(i/100==i%10)         ++count; printf("三位回文数个数为:%d\n",n);

1.在do前面漏了赋值 j = m; 2.里面的那个m==0应该是j==0

用排列组合，首位和个位相等，首位不为0，共9种可能。 中间位有10中可能。 共：9＊10=90 三位回文数个数为：90


Question: 怎么进入死循环了？

弄明白没？以下是我的一些看法： #include<stdio.h> main() { 		int m,s=0,i,n=0; 		int m1; 		for(m=100;m<1000;m++) 		{ 				m1 = m;//用于保存m值 				s=0;//这里很重要，因为你不清零的话 ，下次进入循环，史上一次保存的值； 				do{ 						i=m1%10; 						m1/=10; 						s=s*10+i; 				}while(m1>0);//这里我不明白你为什么事m==0？ 			 				if (s == m) n++; 		} 		printf("三位使得回文数个数为:%d\n",n); }

m/10也能在循环内部？

#include<stdio.h> main() { int m,s=0,i,n=0; for(m=100;m<1000;m++) { int m2 = m;do { i=m2%10; m2/=10; s=s*10+i; }while (m2 == 0); if (s == m) n++; } printf("三位使得回文数个数为:%d\n",n); }

m/=10会使得m>=1000的条件永远不满足，所以退不出for循环。  引用 楼主 u013389843 的回复:#include<stdio.h> main() { int m,s=0,i,n=0; for(m=100;m<1000;m++) { do { 	i=m%10; 	m/=10; 	s=s*10+i; 	}while (m == 0); 	if (s == m) n++; } 	printf("三位使得回文数个数为:%d\n",n); }

代码功能归根结底不是别人帮自己看或讲解或注释出来的；而是被自己静下心来花足够长的时间和精力亲自动手单步或设断点或对执行到某步获得的中间结果显示或写到日志文件中一步一步分析出来的。 提醒：再牛×的老师也无法代替学生自己领悟和上厕所！ 单步调试和设断点调试是程序员必须掌握的技能之一。

what an algorithm!!

m/=10;这一句，m=m/10；这样m的值一直偏小，无法达到上面跳出循环的条件，所以死了吧

for或者while中一般都是线性增加或者减少控制的值，你这样搞肯定容易死循环


Question: C语言疑问

引用 2 楼 baoyuan24 的回复:point是char*变量，我打错了。 两个指针都是指向一块动态内存，free(point)和free(p)不是一样吗？ 第二个程序有什么好的替代方法吗？因为有时候的确有这样的逻辑  [quote=引用 1 楼 turingo 的回复:] 1、第一种没有问题； 2、第二种不行，point只是一个char变量而已，即便point是char*指针，也会有隐患，因为会导致p成为野指针。  [quote=引用 楼主 baoyuan24 的回复:] 程序1： #include <stdio.h> #include <stdlib.h> #include <string.h> void fun(char**point) {     *point = malloc(5);     ASSERT(*point != NULL); } int main() {     char* p;     fun(&p);     free(p);     return 0; } 程序2： #include <stdio.h> #include <stdlib.h> #include <string.h> int main() {     char* p, point;     p = malloc(5);     ASSERT(p != NULL);     point = p;     free(point);     return 0; } 问题： 程序1中从被调函数中分配的内存，在主调函数中释放； 程序2中两个指针指向同一内存，释放point而不是p，上述两种做法会不会有什么不妥？怎样修改？恳请指点。[/quote][/quote]  那就完成没有什么问题了！释放后置NULL比较好一点吧！是一个好的编程习惯 另外p和point指向同一块内存，释放的时候只有一个释放就好！所以释放前判断不为NULL再释放比较好一点！

从技术层面和正确性方面，是没有问题的，但从软件工程角度，问题就比较大，说得直白一点，这种代码难于维护。  一般来说，除非非常有必要，否则是不会讲malloc()和free()脱离函数上下文，即便放在不同的函数，也一般用  明显的函数包装，比如resInit() resDelete()。  另外，搞不懂什么场景下需要pointer=p;这种操作。调用一个函数就可以在函数中定义形参了，为什么还要维护一个指针的多个副本？

free之后把point和p都置为NULL。  引用 2 楼 baoyuan24 的回复:point是char*变量，我打错了。 两个指针都是指向一块动态内存，free(point)和free(p)不是一样吗？ 第二个程序有什么好的替代方法吗？因为有时候的确有这样的逻辑  [quote=引用 1 楼 turingo 的回复:] 1、第一种没有问题； 2、第二种不行，point只是一个char变量而已，即便point是char*指针，也会有隐患，因为会导致p成为野指针。  [quote=引用 楼主 baoyuan24 的回复:] 程序1： #include <stdio.h> #include <stdlib.h> #include <string.h> void fun(char**point) {     *point = malloc(5);     ASSERT(*point != NULL); } int main() {     char* p;     fun(&p);     free(p);     return 0; } 程序2： #include <stdio.h> #include <stdlib.h> #include <string.h> int main() {     char* p, point;     p = malloc(5);     ASSERT(p != NULL);     point = p;     free(point);     return 0; } 问题： 程序1中从被调函数中分配的内存，在主调函数中释放； 程序2中两个指针指向同一内存，释放point而不是p，上述两种做法会不会有什么不妥？怎样修改？恳请指点。[/quote][/quote]

point是char*变量，我打错了。 两个指针都是指向一块动态内存，free(point)和free(p)不是一样吗？ 第二个程序有什么好的替代方法吗？因为有时候的确有这样的逻辑 引用 1 楼 turingo 的回复:1、第一种没有问题； 2、第二种不行，point只是一个char变量而已，即便point是char*指针，也会有隐患，因为会导致p成为野指针。  [quote=引用 楼主 baoyuan24 的回复:] 程序1： #include <stdio.h> #include <stdlib.h> #include <string.h> void fun(char**point) {     *point = malloc(5);     ASSERT(*point != NULL); } int main() {     char* p;     fun(&p);     free(p);     return 0; } 程序2： #include <stdio.h> #include <stdlib.h> #include <string.h> int main() {     char* p, point;     p = malloc(5);     ASSERT(p != NULL);     point = p;     free(point);     return 0; } 问题： 程序1中从被调函数中分配的内存，在主调函数中释放； 程序2中两个指针指向同一内存，释放point而不是p，上述两种做法会不会有什么不妥？怎样修改？恳请指点。[/quote]

1、第一种没有问题； 2、第二种不行，point只是一个char变量而已，即便point是char*指针，也会有隐患，因为会导致p成为野指针。  引用 楼主 baoyuan24 的回复:程序1： #include <stdio.h> #include <stdlib.h> #include <string.h> void fun(char**point) {     *point = malloc(5);     ASSERT(*point != NULL); } int main() {     char* p;     fun(&p);     free(p);     return 0; } 程序2： #include <stdio.h> #include <stdlib.h> #include <string.h> int main() {     char* p, point;     p = malloc(5);     ASSERT(p != NULL);     point = p;     free(point);     return 0; } 问题： 程序1中从被调函数中分配的内存，在主调函数中释放； 程序2中两个指针指向同一内存，释放point而不是p，上述两种做法会不会有什么不妥？怎样修改？恳请指点。

no problem

用c就是要养成好习惯也严谨的编码态度，遵循一定的编码和设计规范。 如果是c++，可以用shared_ptr来代替。减少不必要的人为失误

char* p, point;  --〉 char *p; char *point;  两个代码都行的通。第一个这么会好些： void fun(char**point) {     ASSERT(*point != NULL); } int main() {     char* p;     *p = malloc(5); //这样比较好， 与下面的free对应上     fun(&p);     free(p);        //     return 0; }


Question: C语言 内存详细的分配过程问题

和堆栈无关！

//scanf("%d",&c); scanf("%c",&c);    不要写未定义行为的代码。

计算机组成原理→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

引用 17 楼 u010800064 的回复:[quote=引用 13 楼 user-8 的回复:] [quote=引用 6 楼 lm_whales 的回复:] 开什么玩笑，这个scanf 越界了 内存分配和数据类型对齐方式，等都有关系。  自动变量，只是需要分配一个空间，够他用就行了； 变量在内存的位置，看编译器如何安排。  有的按照顺序分配，有的不按照顺序； 有的可能，这里是顺序的，那里不是。 PS： 一般来说，编译器只是根据需要； 一次或者多次，安排够，所有变量，用的空间，而已。 这个才是正解，%d对于int，你这里是char，要用%c，或者%hhd sizeof(int) == 4(目前大部分编译器都是这个值，当然也有2或者其他的) sizeof(char) == 1 所以char放不下int的数据，导致溢出[/quote] ++++++++++++++++++++++++++++++++++++++++++++1[/quote] +++++++++++++++++

引用 13 楼 user-8 的回复:[quote=引用 6 楼 lm_whales 的回复:] 开什么玩笑，这个scanf 越界了 内存分配和数据类型对齐方式，等都有关系。  自动变量，只是需要分配一个空间，够他用就行了； 变量在内存的位置，看编译器如何安排。  有的按照顺序分配，有的不按照顺序； 有的可能，这里是顺序的，那里不是。 PS： 一般来说，编译器只是根据需要； 一次或者多次，安排够，所有变量，用的空间，而已。 这个才是正解，%d对于int，你这里是char，要用%c，或者%hhd sizeof(int) == 4(目前大部分编译器都是这个值，当然也有2或者其他的) sizeof(char) == 1 所以char放不下int的数据，导致溢出[/quote] ++++++++++++++++++++++++++++++++++++++++++++1

这才是我们想要的答案。 引用 19 楼 zhao4zhong1 的回复:printf里面的%和变量的一一对应关系 scanf里面的%和变量以及变量前加不加&的一一对应关系 是C代码中非常容易出错的地方，而且通常编译还不出错。 所以在编译源代码之前值得专门仔细检查一遍甚至多遍。  在每个最后不带\n的printf后面加fflush(stdout); 在每个不想受接收缓冲区旧内容影响的scanf前面加rewind(stdin); 另外请检查scanf的返回值。

引用 10 楼 yuheni 的回复:问个简单问题，变量声明了，没有给初始化，分配空间吗？ 这个问题其实很复杂 1）extern int n; 2) extern int a[]; //这种不会 3) int b[10];//这种会  C++     class A{ static int a;//这个不会 };   //int A::a;这个会的吧 int A::a = 0;//这个一定会  其他类型静态变量研究不多，暂时不知道。  void fun(){     int a;//这个会的，不过要在函数fun()调用以后，才会分配内存，函数结束则自动丢弃，销毁。 }

http://www.cplusplus.com/reference/cstdio/scanf/ LZ看看上面这个链接里specifiers和length的对应关系吧

引用 6 楼 lm_whales 的回复:开什么玩笑，这个scanf 越界了 内存分配和数据类型对齐方式，等都有关系。  自动变量，只是需要分配一个空间，够他用就行了； 变量在内存的位置，看编译器如何安排。  有的按照顺序分配，有的不按照顺序； 有的可能，这里是顺序的，那里不是。 PS： 一般来说，编译器只是根据需要； 一次或者多次，安排够，所有变量，用的空间，而已。 这个才是正解，%d对于int，你这里是char，要用%c，或者%hhd sizeof(int) == 4(目前大部分编译器都是这个值，当然也有2或者其他的) sizeof(char) == 1 所以char放不下int的数据，导致溢出

引用 9 楼 yuheni 的回复:引用 8 楼 KenZhang1031 的回复:[quote=引用 7 楼 yuheni 的回复:] [quote=引用 5 楼 KenZhang1031 的回复:] [quote=引用 3 楼 yuheni 的回复:] [quote=引用 1 楼 KenZhang1031 的回复:] 这个和栈分配没关系，你输入时怎么输入的？截个图来看看。 我明白你的意思了，你的程序不可能跑成这样的，因为你才循环5次。应该是你输入0，回车键，然后输出0， 输入1，回车，输出1，一直到4，然后就结束了。你确认你跑的是你源代码编译出来的的程序？[/quote]  是的，就是上变得程序，你可以试试，我发现结果不是0，0，0，0，1，2，3，4而是一直死循环，貌似一直是0[/quote]我试到很正常。[/quote] 我用vs试了一下，和你的确实是正常的，刚才那个编译器就不好可以，可能就如6楼说的吧，可是我现在还是不明白那个编译器一直为0怎么解释[/quote]我也不明白，或者你把char c，改成int c试试，不知道是不是这个编译器一定把输入当成是32位的，然后存到你的char中了。

引用 10 楼 yuheni 的回复:问个简单问题，变量声明了，没有给初始化，分配空间吗？分配的。

问个简单问题，变量声明了，没有给初始化，分配空间吗？

引用 8 楼 KenZhang1031 的回复:引用 7 楼 yuheni 的回复:[quote=引用 5 楼 KenZhang1031 的回复:] [quote=引用 3 楼 yuheni 的回复:] [quote=引用 1 楼 KenZhang1031 的回复:] 这个和栈分配没关系，你输入时怎么输入的？截个图来看看。 我明白你的意思了，你的程序不可能跑成这样的，因为你才循环5次。应该是你输入0，回车键，然后输出0， 输入1，回车，输出1，一直到4，然后就结束了。你确认你跑的是你源代码编译出来的的程序？[/quote]  是的，就是上变得程序，你可以试试，我发现结果不是0，0，0，0，1，2，3，4而是一直死循环，貌似一直是0[/quote]我试到很正常。[/quote] 我用vs试了一下，和你的确实是正常的，刚才那个编译器就不好可以，可能就如6楼说的吧，可是我现在还是不明白那个编译器一直为0怎么解释

引用 7 楼 yuheni 的回复:引用 5 楼 KenZhang1031 的回复:[quote=引用 3 楼 yuheni 的回复:] [quote=引用 1 楼 KenZhang1031 的回复:] 这个和栈分配没关系，你输入时怎么输入的？截个图来看看。 我明白你的意思了，你的程序不可能跑成这样的，因为你才循环5次。应该是你输入0，回车键，然后输出0， 输入1，回车，输出1，一直到4，然后就结束了。你确认你跑的是你源代码编译出来的的程序？[/quote]  是的，就是上变得程序，你可以试试，我发现结果不是0，0，0，0，1，2，3，4而是一直死循环，貌似一直是0[/quote]我试到很正常。

引用 5 楼 KenZhang1031 的回复:引用 3 楼 yuheni 的回复:[quote=引用 1 楼 KenZhang1031 的回复:] 这个和栈分配没关系，你输入时怎么输入的？截个图来看看。 我明白你的意思了，你的程序不可能跑成这样的，因为你才循环5次。应该是你输入0，回车键，然后输出0， 输入1，回车，输出1，一直到4，然后就结束了。你确认你跑的是你源代码编译出来的的程序？[/quote]  是的，就是上变得程序，你可以试试，我发现结果不是0，0，0，0，1，2，3，4而是一直死循环，貌似一直是0

引用 3 楼 yuheni 的回复:引用 1 楼 KenZhang1031 的回复:这个和栈分配没关系，你输入时怎么输入的？截个图来看看。 我明白你的意思了，你的程序不可能跑成这样的，因为你才循环5次。应该是你输入0，回车键，然后输出0， 输入1，回车，输出1，一直到4，然后就结束了。你确认你跑的是你源代码编译出来的的程序？

引用 2 楼 yuheni 的回复:#include <stdio.h>  #include <stdlib.h>   int main(int argc, char **argv)  {  char c;          int i;  for(i=0;i<5;i++)  {  scanf("%d",&c);  printf("%d\t",i);  }      return 0;  }  当输入0，1，2，3，4结果为0，0，0，0，0，1，2，3，4为什么呢？i在栈上具体怎么分配的 ，刚才打错了，是变量i怎么解？变量i怎么解是什么意思？i就是0,1,2,3,4的循环啊。


Question: C语言模拟栈是出错。

听到模拟栈，我第一个想到LZ是大神，要自建虚拟机，结果原来是小白，在练习数据结构~  void push(Stack * pS,int val){ //你这个push写的狗屁不通，不作评论~ //PNode p=(PNode)malloc(sizeof(PNode)); PNode p=(PNode)malloc(sizeof(Node)); p->date=val; //p->next=pS->pHead; p->next = NULL; //pS->pHead=p; pS->pTail->next = p; pS->pTail = p; }  void travel(Stack * pS){ //PNode p=pS->pHead; PNode p=pS->pHead->next; //你既然带了头节点，那么这个头节点是没有数据的，遍历时自然要跳过 while(p!=NULL){  printf("%d ",p->date);  p=p->next; } }  还有题外话，data才是数据的英文，你那个date是日期。还有你没写内存释放的函数，会有内存泄漏

init函数你写了没有调用

c language debug


Question: 做定制好还是做基线好

定制组可以接触到市场，需要和他人交流，而且你过去会作为老人，提升空间也比较大。

关键看你自己的兴趣。定制会有各种客户、市场上的压力，客户都希望用有限的价钱买到十全十美的东西，甚至有些功能他一辈子也用不到，他也要求要完美的具有，尤其是小公司，随着产品越来越多，客户越来越多，就会越来越烦，又不敢得罪客户，光应付这些就够了，肯本没有时间去沉下心来做技术，而且如果你对基线的技术不熟的话，未必能满足客户的定制要求，要得去找做基线的帮忙，如果做基线的专注于他自己的事情，不帮你，到时客户找的是你，解决问题还得求人，夹在中间很麻烦。如果你喜欢做技术，觉得研究技术不是压力，而是兴趣，建议还是做基线的好，如果相反，那就做定制。

具体是做什么。

基线项目对能力要求高. 如果你要考虑如何让各种定制更简单的话.

it depends


Question: 相同思路编程~~多个文件编程和单个文件编程结果不同~~求指教~~

引用 10 楼 vipcxj 的回复:[quote=引用 9 楼 pokerLee 的回复:] [quote=引用 7 楼 vipcxj 的回复:]  printf("The second of your age is %e", age_sec(age));  你那多个文件的例子中相关代码请改成这样，至于原因，LZ还是先看书去吧，因为根据LZ犯的错误，我就知道LZ还在婴儿学语阶段，就算告诉你为什么，你也看不懂~应该看哪本书~~求指教~~[/quote] 只要是教C/C++基础的就行，关于你的错误，看函数这章就行了[/quote]谢谢

引用 9 楼 pokerLee 的回复:[quote=引用 7 楼 vipcxj 的回复:]  printf("The second of your age is %e", age_sec(age));  你那多个文件的例子中相关代码请改成这样，至于原因，LZ还是先看书去吧，因为根据LZ犯的错误，我就知道LZ还在婴儿学语阶段，就算告诉你为什么，你也看不懂~应该看哪本书~~求指教~~[/quote] 只要是教C/C++基础的就行，关于你的错误，看函数这章就行了

引用 7 楼 vipcxj 的回复: printf("The second of your age is %e", age_sec(age));  你那多个文件的例子中相关代码请改成这样，至于原因，LZ还是先看书去吧，因为根据LZ犯的错误，我就知道LZ还在婴儿学语阶段，就算告诉你为什么，你也看不懂~应该看哪本书~~求指教~~

引用 3 楼 angel_su 的回复:晕，多文件那个代码错有误，%e格式对应参数是函数名，呢怎会正确。h文件做函数声明即可，不要在里面写实现的代码，另外再开个.c文件往里面写...我把函数返回值赋给了一个变量，然后让变量显示就正常了~~这是为什么？求指教~~ 程序显示变量后可正常运行了~~

引用 3 楼 angel_su 的回复:晕，多文件那个代码错有误，%e格式对应参数是函数名，呢怎会正确。h文件做函数声明即可，不要在里面写实现的代码，另外再开个.c文件往里面写...声明不是函数么~~头文件不应该包含么~~再有格式控制符%e对应的函数不可以看成是返回值么？求指教~~

引用 2 楼 wangyaninglm 的回复:第一个程序写的不太对啊，函数运行完后，那个值就释放掉了啊。 第二个程序对着呢。如何处理求指教~~

引用 1 楼 turingo 的回复:多文件的时候，main.c是如何写的？  [quote=引用 楼主 pokerLee 的回复:] 思路、变量都相同，单个文件是按照多个文件为模板编写。但是输出结果差异很大，多个文件编程效果图如下   得出结果如下图  单个文件编程效果图如下  得出结果如下图  求指点~~是不是没设置指针的原因？[/quote]第一张图不是main.c么？

第一个程序写的不太对啊，函数运行完后，那个值就释放掉了啊。 第二个程序对着呢。

多文件的时候，main.c是如何写的？  引用 楼主 pokerLee 的回复:思路、变量都相同，单个文件是按照多个文件为模板编写。但是输出结果差异很大，多个文件编程效果图如下   得出结果如下图  单个文件编程效果图如下  得出结果如下图  求指点~~是不是没设置指针的原因？


Question: 怎样把大型的c语言程序写好？比如更层次化，接口与实现的分离等等？

看看FILE流是如何设计的。

用比如Source Insight软件查看、修改代码 ？

引用 4 楼 fengyunjh6 的回复:知道该这么做，但是不知道具体怎么分。  有没有比较详细的介绍这方面的资料。   引用 1 楼 KenZhang1031 的回复:自己规划啊。把自己要实现的功能规划好，细分，先做到规划，要有那些模块，要提供哪些接口？分别有哪些文件？工程目录层次也规划好，规划的同时必须要考虑可移植、可维护性和可扩展性，要建立模块是独立的这样的思想，模块写好了可以用于不同的工程，规划好了再写程序，层次要分明。不要上来就写，更不要一个函数、一个文件写到底，写到哪算哪，出问题由推翻重写，切不要这样做。我没见过，或者说没看过，这些是属于软件工程方面的范畴吧？或者下别人的工程看看别人的架构是怎样的，这样也能学到一些。

学习一下面向对象的设计，以及设计模式 比如有些开源代码里面用结构体包裹指针函数就是C在用类似于C++成员函数的概念

改用C++~~~


Question: ./a.out 0 < /dev/tty 如何理解？

是在看UNIX环境高级编程吧，哈哈，我也刚刚开始看。 ./a.out 2 2>>temp.foo 就是先执行./a.out 2，并将错误信息追加输入到temp.foo ./a.out 5 5<>temp.foo 这句书上有解释的啊，先执行./a.out 5，同时在文件描述符5上打开temp.foo文件，并以这个文件为程序执行的输入和输出

直接从鸟哥私房菜里复制的 这里我们来说明命令重定向里几个常用的符号与设备： · < ：由 < 的右边读入参数文件； · > ：将原本由屏幕输出的正确数据输出到 > 右边的file（文件名称）或device（设 备，如printer）； · >> ：将原本由屏幕输出的正确数据输出到 >> 右边，与 > 不同的是，该文件将 不会被覆盖，而新的数据将以累加方式添加到文件的最后面； · 2> ：将原本应该由屏幕输出的错误数据输出到2>的右边； · /dev/null ：可以视为垃圾设备。

引用 4 楼 xwhbwas2008 的回复:[quote=引用 2 楼 YTerrenceLau 的回复:] 用tty设备，取代文件0（stdin），来运行a.out。  就是说a.out的所有需要输入的信息，都是通过tty设备获得的，而不是用户终端（有可能用户终端也是tty）。 你好，那再问下 ./a.out 5 5<>temp.foo 如何理解阿 ？ 是不是多写了一个5 ？[/quote] 还有一个 ./a.out 2 2>>temp.foo 麻烦Lau了。thanks

引用 2 楼 YTerrenceLau 的回复:用tty设备，取代文件0（stdin），来运行a.out。  就是说a.out的所有需要输入的信息，都是通过tty设备获得的，而不是用户终端（有可能用户终端也是tty）。 你好，那再问下 ./a.out 5 5<>temp.foo 如何理解阿 ？ 是不是多写了一个5 ？

标准输入重定向

执行./a.out文件, 命令行参数是0, 程序里scanf()输入的地方从/dev/tty文件里读


Question: 几个简单的c

相当于SENSOR_BLUE|SENSOR_YELLOW|SENSOR_NEGATIVE|SENSOR_CANVAS  引用 3 楼 u013410394 的回复:[quote=引用 1 楼 turingo 的回复:] 先看一遍《C Prime Plus》，再买开发板学习，随时回帖。  [quote=引用 楼主 u013410394 的回复:] typedef struct L_code_tag{ 	unsigned int datatype; 	int a; }L_Code;          //这里我定义这个结构体，是不是以后用这个结构体初始化                   //变量只需要使用别名L_Code A;就可以？？那这里定义了结构体                   //A有什么具体的用处？ 	   L_Code * rd = rd_prep；//这样定义了一个结构体指针？有什么具体的用处吗，希望多讲讲。      想要学习单片机，现在打算买开发板，请问买开发板前需要做什么吗？只买开发板可以学习单片机了吗？  同时问大家，csdn这个类似财富值的可用分，是怎么赚的？只能回答题目吗？别的途径可以吗？[/quote]          SENSOR_BLUE|\         SENSOR_YELLOW|\         SENSOR_NEGATIVE|\         SENSOR_CANVAS, 我刚看到有这个的，那这里|\是啥呢？[/quote]

|是按位或 \是续行符

引用 1 楼 turingo 的回复:先看一遍《C Prime Plus》，再买开发板学习，随时回帖。  [quote=引用 楼主 u013410394 的回复:] typedef struct L_code_tag{ 	unsigned int datatype; 	int a; }L_Code;          //这里我定义这个结构体，是不是以后用这个结构体初始化                   //变量只需要使用别名L_Code A;就可以？？那这里定义了结构体                   //A有什么具体的用处？ 	   L_Code * rd = rd_prep；//这样定义了一个结构体指针？有什么具体的用处吗，希望多讲讲。    想要学习单片机，现在打算买开发板，请问买开发板前需要做什么吗？只买开发板可以学习单片机了吗？  同时问大家，csdn这个类似财富值的可用分，是怎么赚的？只能回答题目吗？别的途径可以吗？[/quote]          SENSOR_BLUE|\         SENSOR_YELLOW|\         SENSOR_NEGATIVE|\         SENSOR_CANVAS, 我刚看到有这个的，那这里|\是啥呢？

你可以看看自引用的结构指针，自引用的在链表中是很有用的。买开发板之前需要了解熟悉具体一款单片机的片上资源，可以看看相关的书，用到具体的单片机时随时翻看芯片的数据手册。好好学吧

先看一遍《C Prime Plus》，再买开发板学习，随时回帖。  引用 楼主 u013410394 的回复:typedef struct L_code_tag{ 	unsigned int datatype; 	int a; }L_Code;          //这里我定义这个结构体，是不是以后用这个结构体初始化                   //变量只需要使用别名L_Code A;就可以？？那这里定义了结构体                   //A有什么具体的用处？ 	   L_Code * rd = rd_prep；//这样定义了一个结构体指针？有什么具体的用处吗，希望多讲讲。    想要学习单片机，现在打算买开发板，请问买开发板前需要做什么吗？只买开发板可以学习单片机了吗？  同时问大家，csdn这个类似财富值的可用分，是怎么赚的？只能回答题目吗？别的途径可以吗？


Question: 关于【作业】统计空格，制表符，换行符的个数的程序。

引用 5 楼 buyong 的回复:编程语言和自然语言的本质区别是： 编程语言是给编译器用的，格式比较严格。 自然语言是人看的，能看懂就行。 所以不能用自然语言的方法改编程语言代码。  对于才初学者来说，这段话就是明灯！

[quote=引用 6 楼 jiandingzhe 的回复:] if(a == ' ',b == '%d',c == '\n') 你这是什么意思？[/quote  就是分别代表 空格，制表符，换行符啊

引用 1 楼 user-7 的回复:if(a == ' ',b == '%d',c == '\n')    谁告诉你if里用逗号的？ ++kg,++zb,++hh;  每次符合条件后，3个变量都加1，那能不一样么？ 不好意思，IF确实不能用逗号，基本的都不知道，小白都不如啊T T  ++ 得 分开来 谢谢大哥 指教。

你这小程序问题大大的多啊  按4楼改把

可以读一个字符处理然后判断它是什么类型就可以  #include<stdio.h> int main(){  	int ch; 	int word; 	int space=0; 	int tab=0; 	int cr=0;  	while((ch=getchar())!=EOF) 	{ 		if(ch==' ') 			space++;//空格 		else if(ch=='\t') 			tab++;//制表 		else if(ch=='\n') 			cr++;//回车 		else 			word++; 	} 	 printf("%d\n%d\n%d\n",space,tab,cr);  	 return 0; }

你这程序写的问题比较多啊

逗号表达式


Question: 我这码风如何？

大哥您不缩进？！

一坨一坨的代码，看着很不爽。 goto应该用在onexit这样的地方，而且尽量少用。

任何傻瓜都能写出机器看的懂的程序，能写出人类看的懂的程序的，才是优秀的程序员

马马虎虎，main太长了。

感觉看着很痛苦……看来是自己耐心不足啊

这马疯是要被揍的节奏。。。

套用今年的流行语说：马上疯了。。。

在短的句子，一句一行 还是好些吧

已瞎！

项目不够大，代码不够长，看不出来。

后面的还好！ 加的缩进吧，一个语句一行或许比较好一点哦！

说实话，看着有点累，没有想阅读的感觉，函数和函数之间没有隔开，功能块之间也没有隔开。

代码不错！

引用 8 楼 FrankHB1989 的回复:多年前我在文曲星上也是这么撸的，因为分辨率只有160*80……  苦了你了，这是无码胜有码的节奏啊。。。

确实有够疯的。  引用 楼主 u010211892 的回复:/*************************************  //  Powered by c //  Written by chen*** //  Date:2014.1.4 //  Run :Linux  */    #include <stdlib.h>    #include <sys/types.h>    #include<time.h>  #include<openssl/md5.h>  #include <stdio.h>    #include <sys/socket.h>    #include <linux/in.h>    #include <string.h>    #define IP "58.192.142.134"  #define PORT 7777          #define ID "********"  #define PASSWD "********"          #define TEN 1.0  char info[1115]="";  char md5[35]="\0";  void gotoxy(int x,int y)   //Fantasy  {     printf("%c[%d;%df",0x1B,y,x);  }  int post(char *sendbuf)    {    int cfd;      int recbytes;    int sin_size;    struct sockaddr_in s_add,c_add;   unsigned short portnum=PORT;  cfd = socket(AF_INET, SOCK_STREAM, 0);    if(-1 == cfd)    {        printf("socket fail ! \r\n");        return -1;    }    bzero(&s_add,sizeof(struct sockaddr_in));    s_add.sin_family=AF_INET;    s_add.sin_addr.s_addr= inet_addr(IP);   s_add.sin_port=htons(portnum);   if(-1 == connect(cfd,(struct sockaddr *)(&s_add), sizeof(struct sockaddr)))    {        printf("connect fail !\r\n");        return -1;    }    if(-1 == (recbytes =send(cfd,sendbuf,strlen(sendbuf),0)))   {        printf("read data fail !\r\n");        return -1;    }    strcpy(info,"");  recv(cfd, info,1024,0);  info[recbytes]='\0';    close(cfd);   return 0;    }    int paus(float time)  {  long zt1=clock();  long zt2;  while(1)  {  zt2=clock();  if(((float)(zt2-zt1)/CLOCKS_PER_SEC)>time)  return 0;  else  {  gotoxy(23,2);  printf("%-9.2f",((float)(zt2-zt1)/CLOCKS_PER_SEC));}  }  }  void information()//Line 3 to 11  {  gotoxy(1,3);printf("This is used in a special election for course selection");  gotoxy(1,4);printf("Running under Linux,compiled by gcc");  gotoxy(1,5);printf("Yangzhou University");  gotoxy(1,6);printf("Ten minutes after logging in,try every time interval,a total of three times");  gotoxy(1,7);printf("Log back in thirty minutes");  gotoxy(1,8);printf("Run without a screen in card PC");  gotoxy(1,9);printf("Wake up,the course is completed,the final number is mine");  gotoxy(1,10);printf("This proof,C language can do anything");  gotoxy(1,11);printf("I wish the electromagnetic field will not fail");  }  int main()  {      int loop;      char acc[20];      MD5_CTX ctx;      unsigned char *data=PASSWD;      unsigned char md[16];      char tmp[3]={'\0'};      int i,j;  char *pg0;  float tpause;  printf("Input time(seconds):");  scanf("%f",&tpause);  puts("Waiting...,Now passed            seconds");  paus(tpause);  information();  gotoxy(1,12);  printf("RunTime is                               seconds\n");  long zt1=clock();  long zt2;      MD5_Init(&ctx);         MD5_Update(&ctx,data,strlen(data));        MD5_Final(md,&ctx);       for( i=0; i<16; i++ ){          sprintf(tmp,"%02X",md[i]);          strcat(md5,tmp);      }      again:      pg0=(char *)malloc(1025);  sprintf(pg0,"GET /pls/wwwbks/bks_login2.uniteLogin?stuid=%s&pwd=%s HTTP/1.1\r\n"  "Host:\r\n"  "Proxy-Connection: keep-alive\r\n"  "Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8\r\n"  "User-Agent: \r\n"  "Referer:\r\n"  "Accept-Encoding: deflate\r\n"  "Accept-Language: zh-CN,zh;q=0.8\r\n"  "Accept-Charset: gb2312;q=0.7,*;q=0.3\r\n"  "Cookie: \r\n\r\n",ID,md5);  post(pg0);  free(pg0);  i=j=0;  while(1){  while(info[i]!='C')i++;  if(info[i+3]==info[i+6])break;  else i++;  }  if(info[i+16]!='1'){printf("Wrong and wrong");}  else  {  while(1){  while(info[i]!='S')i++;  if(info[i+4]=='C')break;  else i++;  }  j=i;  while(info[j]!=';')j++;  info[j]=0;  strcpy(acc,info+20+i);  }  pg0=(char *)malloc(1025);  for(loop=0;loop<3;loop++)  {  sprintf(pg0,"POST /pls/wwwbks/xk.CourseInput HTTP/1.1\r\n"  "Host: \r\n"  "Proxy-Connection: keep-alive\r\n"  "Content-Length: 29\r\n"  "Cache-Control: \r\n"  "Origin: \r\n"  "User-Agent: \r\n"  "Content-Type: \r\n"  "Accept: \r\n"  "Referer: \r\n"  "Accept-Encoding: \r\n"  "Accept-Language: \r\n"  "Accept-Charset: \r\n"  "Cookie: ACCOUNT=%s;\r\n\r\n"  "p_qxrxk=0329016&p_qxrxk_kxh=6",acc);  post(pg0);  sprintf(pg0,"POST /pls/wwwbks/xk.CourseInput HTTP/1.1\r\n"  "Host: \r\n"  "Proxy-Connection: keep-alive\r\n"  "Content-Length: 29\r\n"  "Cache-Control: \r\n"  "Origin: \r\n"  "User-Agent: \r\n"  "Content-Type: \r\n"  "Accept: \r\n"  "Referer: \r\n"  "Accept-Encoding: \r\n"  "Accept-Language: \r\n"  "Accept-Charset: \r\n"  "Cookie: ACCOUNT=%s;\r\n\r\n"  "p_qxrxk=1029012&p_qxrxk_kxh=0",acc);  post(pg0);  sprintf(pg0,"POST /pls/wwwbks/xk.CourseInput HTTP/1.1\r\n"  "Host: \r\n"  "Proxy-Connection: keep-alive\r\n"  "Content-Length: 29\r\n"  "Cache-Control: \r\n"  "Origin: \r\n"  "User-Agent: \r\n"  "Content-Type: \r\n"  "Accept: \r\n"  "Referer: \r\n"  "Accept-Encoding: \r\n"  "Accept-Language: \r\n"  "Accept-Charset: \r\n"  "Cookie: ACCOUNT=%s;\r\n\r\n"  "p_qxrxk=1029013&p_qxrxk_kxh=0",acc);  post(pg0);  zt2=clock();  gotoxy(12,12);  printf("%9.2f",((float)(zt2-zt1)/CLOCKS_PER_SEC));  paus(TEN);  }  free(pg0);  goto again;  return 0;  }

果然是马蜂..密密麻麻的!

马蜂吗 有什么马蜂

麻风不错


Question: 求解STM32驱动0V7670摄像头的手势识别

或者说，不要平台，手势识别这个功能是不是就实现不了。。

就是如何用纯c语言去吧图像识别的那些肤色检测啊，边缘提取啊，以及模式匹配那些算法实现，，而不是c++。

what is your problem


Question: 优化矩阵乘法程序求bug解决方法

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

请判断malloc的返回值。

谢谢指正 但还是不行 program start  thread start  Segmentation fault (core dumped)

a = (double**)malloc(sizeof(double*)*N);


Question: 百元百鸡问题

引用 3 楼 user-2 的回复:三层for循环，暴力破解不就搞定啦？ 恩 是的 谢谢了

引用 2 楼 u011075056 的回复:三个未知数只有两个条件  鸡一百只 钱一百块  如果有三个条件 就是唯一解了

三层for循环，暴力破解不就搞定啦？

三个未知数只有两个条件  鸡一百只 钱一百块

这不是解方程组嘛


Question: 讨论：C语言学习中位运算重要吗？

位运算很重要啊，你看微软的编程之美里面就可以知道了，这玩意可以提高速度，非常有效。 书到用时方恨少，这是真的。

用得多 不过需要学的没多少  一天了解 一星期专项训练  基本就能掌握了

受教了，我以前学c语言的时候也对位运算不是很重视……

如果做底层开发，位运算就是很重要里的了。而且平时好多加密算法都用的是位运算 。。

位运算用得较多，可以用最少的空间表示状态，也就是状态位的意思。结合宏定义，使用位运算很简单的。位运算是基础得不能再基础的事情了，一定要学好。

一次性搞定还是好些。不懂在翻番看。

如果你做底層一點的東西就會經常用到，比如一些寄存器的設置，你隨便找一個關於ARM的代碼，裏面基本會有，不過就位運算本身來說，也不是很難

书到用时方恨少， 位运算到用时再补课恐怕比老板炒你鱿鱼的速度慢。

位运算用的地方还是很多的，linux内核以及一些库的实现都经常用到.

位运算速度快 VC里面好多这个

非常重要，位运算实际工程中也是经常用到的。

这是C语言基础语法哈，掌握并且了解一些常见的用法是很有必要的，enum基于位做一些flag是很常见的。

重要啊，经常用到的。

除了运算中的奇葩优化，位运算可以用于表示状态。 比如Glib的如下代码：  typedef enum {   G_OPTION_FLAG_HIDDEN		= 1 << 0,   G_OPTION_FLAG_IN_MAIN		= 1 << 1,   G_OPTION_FLAG_REVERSE		= 1 << 2,   G_OPTION_FLAG_NO_ARG		= 1 << 3,   G_OPTION_FLAG_FILENAME = 1 << 4,   G_OPTION_FLAG_OPTIONAL_ARG    = 1 << 5,   G_OPTION_FLAG_NOALIAS	        = 1 << 6 } GOptionFlags;  你就可以用|算符把这些东西组合成属性集合。

九九乘法表无比重要，谁会花一年去学它？ 讲的简洁是因为没啥好讲的，就那么几句话总不成重复一万遍占篇幅吧？

位运算就是逻辑运算,在学数电的时候了解过了，在这里学也是很容易明白的吧

这东西相对接近底层  所以包含的知识点不多


Question: 无符号算术运算 没有所谓的“溢出”-说  怎么理解阿 ？

引用 16 楼 FrankHB1989 的回复:这个只是考虑大部分实现的说法，看来也不是每个实现都有这个保证。 大概是因为有符号数的情况可能更复杂（不同体系结构处理的花样更多），语言的抽象对有符号数和无符号数区别对待：只有无符号数无溢出，有符号数可以溢出UB。 ++ 嗯，应该是这样

无符号运算 ，取2^n的模，可以保证低n位值正确~

数的域是数学上群论的概念。

引用 9 楼 lm_whales 的回复:引用 8 楼 xwhbwas2008 的回复:[quote=引用 7 楼 skyliuxu 的回复:] 从哪看的“无符号算术运算 没有所谓的“溢出”-说 ：所有的无符号运算都是以2的n次方为模，这里的n是结果中的位数”？C traps and pitfalls 这其实有两种数的概念在里面 1）是我们平时使用的，数学上的无限域的数的概念，这样其实无符号数就是自然数。 2）计算机上，各种编程语言实现的，模2域中的无符号数；    这个数域中的数+，-，* ，结果总是在模2域中；    这样，也就没有溢出的说法了。 3）模2域中的计算结果，用作现实的自然数，整数    当自然数的+，-，* 结果过大，超出模2域的表示范围；    再用模2域表示，就会有数据丢失现象，这就是溢出。    另外，自然数相减，结果未必是自然数（成了负数，这应该在整数域计算），    结果，用模2域的无符号数表示，结果也是错误的，这也应该是一种溢出。 PS： 溢出，是相对，无限域的整数，来说的。  对于模2域中的无符号数，+，-，* 三种运算； 结果是封闭的，结果是在模2域中。  这样相对于 nBits 的模2域，无符号数+，-，* 三种运算，确实没有溢出的问题。 至于除法，也只有除数为0，这一点有问题。 [/quote] 这个只是考虑大部分实现的说法，看来也不是每个实现都有这个保证。 大概是因为有符号数的情况可能更复杂（不同体系结构处理的花样更多），语言的抽象对有符号数和无符号数区别对待：只有无符号数无溢出，有符号数可以溢出UB。

无符号数所谓的算术运算严格意义上不是一般的整数算术，是以2^n回绕的模算术，所有计算结果都在预期范围内，当然不存在溢出的情况。

引用 9 楼 lm_whales 的回复:引用 8 楼 xwhbwas2008 的回复:[quote=引用 7 楼 skyliuxu 的回复:] 从哪看的“无符号算术运算 没有所谓的“溢出”-说 ：所有的无符号运算都是以2的n次方为模，这里的n是结果中的位数”？C traps and pitfalls 这其实有两种数的概念在里面 1）是我们平时使用的，数学上的无限域的数的概念，这样其实无符号数就是自然数。 2）计算机上，各种编程语言实现的，模2域中的无符号数；    这个数域中的数+，-，* ，结果总是在模2域中；    这样，也就没有溢出的说法了。 3）模2域中的计算结果，用作现实的自然数，整数    当自然数的+，-，* 结果过大，超出模2域的表示范围；    再用模2域表示，就会有数据丢失现象，这就是溢出。    另外，自然数相减，结果未必是自然数（成了负数，这应该在整数域计算），    结果，用模2域的无符号数表示，结果也是错误的，这也应该是一种溢出。 PS： 溢出，是相对，无限域的整数，来说的。  对于模2域中的无符号数，+，-，* 三种运算； 结果是封闭的，结果是在模2域中。  这样相对于 nBits 的模2域，无符号数+，-，* 三种运算，确实没有溢出的问题。 至于除法，也只有除数为0，这一点有问题。 [/quote] 取模就等于是溢出处理，有必要纠结于文字游戏？C traps and pitfalls哪一章哪一节这么说的？ ps:不要太相信翻译的书，要看原版求证

11点加2个小时就是1点 这就是“溢出”也是“取模”

文字游戏 对2的n次方取模本身就是溢出

引用 8 楼 xwhbwas2008 的回复:引用 7 楼 skyliuxu 的回复:从哪看的“无符号算术运算 没有所谓的“溢出”-说 ：所有的无符号运算都是以2的n次方为模，这里的n是结果中的位数”？C traps and pitfalls 这其实有两种数的概念在里面 1）是我们平时使用的，数学上的无限域的数的概念，这样其实无符号数就是自然数。 2）计算机上，各种编程语言实现的，模2域中的无符号数；    这个数域中的数+，-，* ，结果总是在模2域中；    这样，也就没有溢出的说法了。 3）模2域中的计算结果，用作现实的自然数，整数    当自然数的+，-，* 结果过大，超出模2域的表示范围；    再用模2域表示，就会有数据丢失现象，这就是溢出。    另外，自然数相减，结果未必是自然数（成了负数，这应该在整数域计算），    结果，用模2域的无符号数表示，结果也是错误的，这也应该是一种溢出。 PS： 溢出，是相对，无限域的整数，来说的。  对于模2域中的无符号数，+，-，* 三种运算； 结果是封闭的，结果是在模2域中。  这样相对于 nBits 的模2域，无符号数+，-，* 三种运算，确实没有溢出的问题。 至于除法，也只有除数为0，这一点有问题。

。。。感觉已经很好理解了  好比4位的无符号数 0到15 那么8+8=0

1）计算机上，某个编程语言实现的运算，都是有限域的运算。  1.1）通常就是就是模2域的运算 1.2）模2域有两种类型的运算 1.2.1）第1种就是，计算机上的，普通算术运算。 1.2.2）第2种，是模2域的多项式运算，这种运算用于加密，解密，编码，解码，CRC等。 2）而数学上的，日常应用的，算术运算，都是无限域的算术运算。 3）因为数学上的，日常应用的数，是没有范围限制的，是无限的，    计算机表示的某种类型的数是有限的。    计算机的运算结果，如果超出所能表示范围，结果就不正确了；    这样计算机的运算结果，就出错了；    这种错误，就称为数据溢出错误，简称溢出。

仅供参考： //有符号整形a和b,如何判断a+b是否溢出 #include <stdio.h> int ifo_add(int a,int b) {     __asm {         mov eax,a         add eax,b         jo  overflowed         xor eax,eax         jmp no_overflowed overflowed:         mov eax,1 no_overflowed:     } } int main() {     int a,b;      a=          1;b= 2;printf("%11d+(%2d) %d\n",a,b,ifo_add(a,b));     a=         -1;b=-2;printf("%11d+(%2d) %d\n",a,b,ifo_add(a,b));     a= 2147483647;b= 1;printf("%11d+(%2d) %d\n",a,b,ifo_add(a,b));     a=-2147483647;b=-1;printf("%11d+(%2d) %d\n",a,b,ifo_add(a,b));     a=-2147483647;b=-2;printf("%11d+(%2d) %d\n",a,b,ifo_add(a,b)); } //          1+( 2) 0 //         -1+(-2) 0 // 2147483647+( 1) 1 //-2147483647+(-1) 0 //-2147483647+(-2) 1  //无符号整形a和b,如何判断a+b是否溢出 #pragma warning(disable:4035) #include <stdio.h> int ifo_addu(unsigned int a,unsigned int b) {     __asm {         mov eax,a         add eax,b         jo  overflowed         xor eax,eax         jmp no_overflowed overflowed:         mov eax,1 no_overflowed:     } } int ifc_addu(unsigned int a,unsigned int b) {     __asm {         mov eax,a         add eax,b         jc  carried         xor eax,eax         jmp no_carried carried:         mov eax,1 no_carried:     } } int main() {     unsigned int a,b;      a=          1u;b= 2u;printf("%11u+(%2u) %d\n",a,b,ifo_addu(a,b));     a= 4294967295u;b= 1u;printf("%11u+(%2u) %d\n",a,b,ifo_addu(a,b));     a=          1u;b= 2u;printf("%11u+(%2u) %d\n",a,b,ifc_addu(a,b));     a= 4294967295u;b= 1u;printf("%11u+(%2u) %d\n",a,b,ifc_addu(a,b));      return 0; } //          1+( 2) 0 // 4294967295+( 1) 0 //          1+( 2) 0 // 4294967295+( 1) 1 //

有溢出，不过如果限定，只能得到可表示数据，那也可以看作没有溢出。  事实上，CPU 做无符号加法运算，溢出后，进位位 c,会置位为1. 但是如果把无符号数，看作模2域中的数，自然就没有溢出一说了。  从模2域的加法的定义看，这个溢出部分,被模2^n 的求余算法，消除了。 而实际计算，CPU只需要，做个简单的加法，就实现了模2^n的加法。（n=8,16,32,64,etc) 其他运算也是类似。

俺也不明白，求高手指教

说的很明白啊，2的n次方的模，nn是结果中的位数。。这还不懂么？


Question: 2014年计算机图书伪劣作者打假第一案！踢爆伪C大师garbageMan（薛非）的真实嘴脸。这一切的背后，到底是利益的驱动还是智商的无奈！

说的不错  ！！！

如果可以，请博友转载本文或发帖，以便让更多博友看到此人的真实面目。让这样没有廉耻的人待在博客园，是对每个人的侮辱。鲁迅有篇文章，叫“痛打落水狗”，对卑劣之人，一旦让其起性，只会更加疯狂，唯有痛打、打疼、打怕，或许才能让其明白一个简单的道理——一个人的生存，是由于他的正直，而卑劣之人暂时能够存在，只是因为其侥幸逃脱了灾祸。

不错，可以起到振兴C语言的作用。

推荐加精！谁有权限？

这个。。。建议置顶。

为人师表者，不误人子弟！希望垃圾书能尽快被历史淘汰掉！

看了点目录，貌似还花一了一章介绍了vs的环境的安装吧

看作者名字,就不会买的

都是踢来踢去的

到底是利益的驱使还是智商的无耐，呵呵。

这么吊，我都不知道。

爱的反面不是恨；而是漠然。

引用楼主做不到从技术上反驳薛非，光骂人没用，相反薛非从技术上指出了对方的谬误，而楼主没法接招的话，骂得越多，越会让旁人觉得你虚伪，呵呵。 不能这么说，我觉得老谭也没反驳他，不等于说老谭默认他对，有时候反驳他着了他的道，不用反驳，直接NG。

存在即合理。

求细8。还有更多细节么？

这得多大仇啊，删前留名。

打倒×××！再踏上一只脚！！让他永世不得翻身！！！


Question: 求大神帮忙啊

都不会....

你是不会生成迷宫, 还是不会找到路径? 话说这个题目是我当年高一时参加计算机竞赛培训时的练习题.

自己看下求迷宫全部路径 http://download.csdn.net/detail/xx_123_1_rj/6361839


Question: 进程退出后，泄漏在其中的内存会被os回收，我的观点是不是准确的 ？

引用 9 楼 lm_whales 的回复:进程exit，进程的所有自有内存，都会释放掉，包括heap区。  现在的操作系统而言

进程exit，进程的所有自有内存，都会释放掉，包括heap区。

《深入解析Windows操作系统-Windows Internals》进程管理、内存管理。

引用 6 楼 xwhbwas2008 的回复:[quote=引用 1 楼 hnwyllmm 的回复:] 每个进程起来用的内存都是虚的，不是有整个操作系统统一分配的，所以你的进程即使异常退出了，也不会影响整个OS的运行。其实也不存在进程的Heap区还给OS，因为他的Heap是专属进程的，进程结束了，也就没了，而且这个Heap不是从OS中的某部分内存分出来的 问下你这里的 不是有整个操作系统统一分配的 是不是“由”？   再就是能详细解释下这句话不 ？[/quote] 是由，打错了不好意思。 我的意思是，每个进程都有自己专属的内存空间。当操作系统创建一个新的进程出来，就为他分配了一定的内存（不是所有进程共用同一个内存），但是这个内存不占用操作系统本身内存，也不受物理内存的限制，只有当进程运行时访问到某些内存没有对应物理内存时，操作系统才将信息加载到物理内存中。我的表达能力有限，可能会带有误导性，给个关键字：虚拟内存，搜索下。

引用 1 楼 hnwyllmm 的回复:每个进程起来用的内存都是虚的，不是有整个操作系统统一分配的，所以你的进程即使异常退出了，也不会影响整个OS的运行。其实也不存在进程的Heap区还给OS，因为他的Heap是专属进程的，进程结束了，也就没了，而且这个Heap不是从OS中的某部分内存分出来的 问下你这里的 不是有整个操作系统统一分配的 是不是“由”？   再就是能详细解释下这句话不 ？

引用 1 楼 hnwyllmm 的回复:每个进程起来用的内存都是虚的，不是有整个操作系统统一分配的，所以你的进程即使异常退出了，也不会影响整个OS的运行。其实也不存在进程的Heap区还给OS，因为他的Heap是专属进程的，进程结束了，也就没了，而且这个Heap不是从OS中的某部分内存分出来的长知识了 big thanks

怕的就是你的进程不结束

对于现在的操作系统而言是这样的； 不过比较老的就不是这样，所以当时内存泄露，是个很大的问题。

应该是对的。内存泄露只发生在在进程运行过程中

引用 11 楼 xwhbwas2008 的回复:[quote=引用 7 楼 hnwyllmm 的回复:] [quote=引用 6 楼 xwhbwas2008 的回复:] [quote=引用 1 楼 hnwyllmm 的回复:] 每个进程起来用的内存都是虚的，不是有整个操作系统统一分配的，所以你的进程即使异常退出了，也不会影响整个OS的运行。其实也不存在进程的Heap区还给OS，因为他的Heap是专属进程的，进程结束了，也就没了，而且这个Heap不是从OS中的某部分内存分出来的 问下你这里的 不是有整个操作系统统一分配的 是不是“由”？   再就是能详细解释下这句话不 ？[/quote] 是由，打错了不好意思。 我的意思是，每个进程都有自己专属的内存空间。当操作系统创建一个新的进程出来，就为他分配了一定的内存（不是所有进程共用同一个内存），但是这个内存不占用操作系统本身内存，也不受物理内存的限制，只有当进程运行时访问到某些内存没有对应物理内存时，操作系统才将信息加载到物理内存中。我的表达能力有限，可能会带有误导性，给个关键字：虚拟内存，搜索下。[/quote] 受教了。再请问下你这些知识是从哪里获取的？推荐本书或者资料 ？ [/quote] 基本上每本操作系统的书都会介绍的，如果你是计算机专业或者相关专业，这门课也会开的

引用 7 楼 hnwyllmm 的回复:[quote=引用 6 楼 xwhbwas2008 的回复:] [quote=引用 1 楼 hnwyllmm 的回复:] 每个进程起来用的内存都是虚的，不是有整个操作系统统一分配的，所以你的进程即使异常退出了，也不会影响整个OS的运行。其实也不存在进程的Heap区还给OS，因为他的Heap是专属进程的，进程结束了，也就没了，而且这个Heap不是从OS中的某部分内存分出来的 问下你这里的 不是有整个操作系统统一分配的 是不是“由”？   再就是能详细解释下这句话不 ？[/quote] 是由，打错了不好意思。 我的意思是，每个进程都有自己专属的内存空间。当操作系统创建一个新的进程出来，就为他分配了一定的内存（不是所有进程共用同一个内存），但是这个内存不占用操作系统本身内存，也不受物理内存的限制，只有当进程运行时访问到某些内存没有对应物理内存时，操作系统才将信息加载到物理内存中。我的表达能力有限，可能会带有误导性，给个关键字：虚拟内存，搜索下。[/quote] 受教了。再请问下你这些知识是从哪里获取的？推荐本书或者资料 ？


Question: 本人想报班学习下嵌入式开发，请问学习嵌入式的时候，是否需要先学习别的诸如单片机的东西？

Andriod  引用 8 楼 blueyiniu 的回复:引用 6 楼 turingo 的回复:那就不要往嵌入式方向走。  [quote=引用 4 楼 blueyiniu 的回复:] [quote=引用 1 楼 turingo 的回复:] 必须对硬件比较了解。  [quote=引用 楼主 u013410394 的回复:] 本人想报班学习下嵌入式开发，请问学习嵌入式的时候，是否需要先学习别的诸如单片机的东西？还有哪些基础必须要懂？  请问那如果只是能软件部分比较感兴趣呢？[/quote][/quote]   高人指点下，有没有其他合适的方向，本科专业是电气自动化，数、模、电都是专业课，但对软件编程及智能控制很感兴趣，不过对硬件电路设计无爱啊[/quote]

不过也看你想做那个系统。wince,linux,vxworks、、多了

引用 楼主 u013410394 的回复:本人想报班学习下嵌入式开发，请问学习嵌入式的时候，是否需要先学习别的诸如单片机的东西？还有哪些基础必须要懂？想学喜欢软件的话，可以向嵌入式应用软件发展，可以基本不用懂硬件，需要学：linux，C语言，数据结构，QT，make file。

做嵌入式开发，不懂硬件的话怎么调试啊。不需要你会设计电路，但至少要能看得懂电路图，清楚整个系统的工作方式。

如果只是软件、学习c语言！学精通

引用 6 楼 turingo 的回复:那就不要往嵌入式方向走。  引用 4 楼 blueyiniu 的回复:[quote=引用 1 楼 turingo 的回复:] 必须对硬件比较了解。  [quote=引用 楼主 u013410394 的回复:] 本人想报班学习下嵌入式开发，请问学习嵌入式的时候，是否需要先学习别的诸如单片机的东西？还有哪些基础必须要懂？  请问那如果只是能软件部分比较感兴趣呢？[/quote][/quote]   高人指点下，有没有其他合适的方向，本科专业是电气自动化，数、模、电都是专业课，但对软件编程及智能控制很感兴趣，不过对硬件电路设计无爱啊

不单单是单片机，数字电路和模拟电路都应该了解。  引用 2 楼 u013410394 的回复:引用 1 楼 turingo 的回复:必须对硬件比较了解。  [quote=引用 楼主 u013410394 的回复:] 本人想报班学习下嵌入式开发，请问学习嵌入式的时候，是否需要先学习别的诸如单片机的东西？还有哪些基础必须要懂？ 您是指单片机吗？您的意思是学习嵌入式之前需要把单片机学习下？？[/quote]

那就不要往嵌入式方向走。  引用 4 楼 blueyiniu 的回复:引用 1 楼 turingo 的回复:必须对硬件比较了解。  [quote=引用 楼主 u013410394 的回复:] 本人想报班学习下嵌入式开发，请问学习嵌入式的时候，是否需要先学习别的诸如单片机的东西？还有哪些基础必须要懂？  请问那如果只是能软件部分比较感兴趣呢？[/quote]

引用 2 楼 u013410394 的回复:引用 1 楼 turingo 的回复:必须对硬件比较了解。  [quote=引用 楼主 u013410394 的回复:] 本人想报班学习下嵌入式开发，请问学习嵌入式的时候，是否需要先学习别的诸如单片机的东西？还有哪些基础必须要懂？ 您是指单片机吗？您的意思是学习嵌入式之前需要把单片机学习下？？[/quote]   感觉单片机太简单了点，学不学对嵌入式学习影响应该不大，无非就那几个口和2个E2PROM吧

引用 1 楼 turingo 的回复:必须对硬件比较了解。  引用 楼主 u013410394 的回复:本人想报班学习下嵌入式开发，请问学习嵌入式的时候，是否需要先学习别的诸如单片机的东西？还有哪些基础必须要懂？  请问那如果只是能软件部分比较感兴趣呢？

如果自己有学习能力 为什么要报班

引用 1 楼 turingo 的回复:必须对硬件比较了解。  引用 楼主 u013410394 的回复:本人想报班学习下嵌入式开发，请问学习嵌入式的时候，是否需要先学习别的诸如单片机的东西？还有哪些基础必须要懂？ 您是指单片机吗？您的意思是学习嵌入式之前需要把单片机学习下？？


Question: 用C语言如何实现访问网站啊，求解

可以用socket发HTTP请求。

ShellExecute(NULL,"open","http://www.baidu.com",NULL,NULL,SW_SHOW);  要包含头文件windows.h


Question: #define LCD_PRINT(...)这样的一个简单定义是干嘛的？有啥作用

引用 4 楼 KenZhang1031 的回复:引用你是指 LCD_PRINT(a);调用的是func（a） 这个函数吗？可是它里面是...啊，怎么传递参数的 在我举例代码中，你明白那段代码的意思吗？如果DEBUG定义了，那么有效的就是#define LCD_PRINT(...)    func(a)，所以LCD_PRINTF就会执行func(a)，如果没有定义DEBUG，那么有效的就是#define LCD_PRINT(...)。什么都不做。 谢谢你，分数不多，都给你了，笑纳

省略号表示函数参数个数可变，比如常用的printf函数，原型是int printf( const char* format, ...); 后面的...表示参数个数可变，所以才能打印多个参数啊。

引用 1 楼 KenZhang1031 的回复:这个宏定义表示什么都不做。通常用于如下的用法：  #include <stdio.h>  #ifdef DEBUG #define LCD_PRINT(...)	func(a) #else #define LCD_PRINT(...) #endif  void func(int a) { 	printf("Call func, param = %d\r\n", a); }  void main(void) { 	unsigned int a = 123;  	LCD_PRINT(a);  } 比如调式版本的软件中定义了DEBUG，那么这个时候LCD_PRINT函数就会调用func(a)来打印调式的信息；一旦程序调式通过，要发行了，就不需要DEBUG的定义了，这个时候LCD_PRINT就会什么都不执行。  你是指 LCD_PRINT(a);调用的是func（a） 这个函数吗？可是它里面是...啊，怎么传递参数的


Question: C基础

引用 7 楼 crabisacoolboy 的回复:[quote=引用 6 楼 crabisacoolboy 的回复:] [quote=引用 4 楼 derekrose 的回复:] [quote=引用 2 楼 crabisacoolboy 的回复:] [quote=引用 1 楼 derekrose 的回复:] 相当于 gcc -c main.c -o main.o gcc -c a.c -o a.o gcc main.o a.o -o main  还是不明白main()方法怎么把foo()方法引用到的？是编译完了直接就会把foo()方法跟main()方法关联吗？ 能够解释下吗？[/quote]  理解link动作是做什么[/quote]  不明白，我先google下，然后再回来看看[/quote] 在问个问题啊，比如我的main.c 里面也也有个foo()方法，这样程序就会报错，想问下c语言不支持在不同的文件里面定义相同名字的函数吗？[/quote]  貌似都是比C高级的编程语言（如C＋＋ JAVA）才有命名空间来解决这个问题的吧

引用 8 楼 baichi4141 的回复:首先，c和java是两门不同的语言，所以“main.c的main()方法里面没有引入a.c的foo()方法应该编译都通不过”这种想法以后不要再有了，没有什么应该不应该，只有语言标准 然后，c语言的不同文件在编译时分别编译为不同模块，所有模块最终链接为可执行文件，如果没有特别声明，所有全局变量和函数都可以在模块外通过名字直接访问，所以不同模块中不能有同名的全局变量和函数。如果想要使用同名的全局变量和函数，就用关键字static声明为内部，这样这个变量和函数对模块外来说就是不可见的，自然也就不会报冲突错误   谢谢，刚刚学习所以才会有这些疑问。分少，就把分平均给几位吧。

引用 6 楼 crabisacoolboy 的回复:[quote=引用 4 楼 derekrose 的回复:] [quote=引用 2 楼 crabisacoolboy 的回复:] [quote=引用 1 楼 derekrose 的回复:] 相当于 gcc -c main.c -o main.o gcc -c a.c -o a.o gcc main.o a.o -o main  还是不明白main()方法怎么把foo()方法引用到的？是编译完了直接就会把foo()方法跟main()方法关联吗？ 能够解释下吗？[/quote]  理解link动作是做什么[/quote]  不明白，我先google下，然后再回来看看[/quote] 在问个问题啊，比如我的main.c 里面也也有个foo()方法，这样程序就会报错，想问下c语言不支持在不同的文件里面定义相同名字的函数吗？

引用 4 楼 derekrose 的回复:[quote=引用 2 楼 crabisacoolboy 的回复:] [quote=引用 1 楼 derekrose 的回复:] 相当于 gcc -c main.c -o main.o gcc -c a.c -o a.o gcc main.o a.o -o main  还是不明白main()方法怎么把foo()方法引用到的？是编译完了直接就会把foo()方法跟main()方法关联吗？ 能够解释下吗？[/quote]  理解link动作是做什么[/quote]  不明白，我先google下，然后再回来看看

引用 3 楼 KenZhang1031 的回复:你的gcc明明写了两个.c文件，两个.c文件都编译成了main文件，怎么会报错？ gcc f1.c f2.c -o out 会把f1.c和f2.c都编译并且连接成out文件。你的main函数以及main调用的函数在这两个文件里都能找到，为什么要报错？ 恩。我是学java的，就是觉得main.c的main()方法里面没有引入a.c的foo()方法应该编译都通不过,但是c可以，所以不明白。

引用 2 楼 crabisacoolboy 的回复:[quote=引用 1 楼 derekrose 的回复:] 相当于 gcc -c main.c -o main.o gcc -c a.c -o a.o gcc main.o a.o -o main  还是不明白main()方法怎么把foo()方法引用到的？是编译完了直接就会把foo()方法跟main()方法关联吗？ 能够解释下吗？[/quote]  理解link动作是做什么

引用 1 楼 derekrose 的回复:相当于 gcc -c main.c -o main.o gcc -c a.c -o a.o gcc main.o a.o -o main  还是不明白main()方法怎么把foo()方法引用到的？是编译完了直接就会把foo()方法跟main()方法关联吗？ 能够解释下吗？


Question: typedef void (*spi_t)(uint32_t *data);

这个相当于定义了一个指向函数的指针spi_t类型，指向的函数原型是 void 函数名(unit32_t *data) 用法，比如下面的程序：   #include <stdio.h>  typedef void (*spi_t)(unsigned int *data);  void func(unsigned int * pParam) { 	printf("Call func, param = %d\r\n", *pParam); }   void main(void) { 	unsigned int a = 123; 	spi_t f = func;      if(f) 	{ 		f(&a); 	} }

typedef void (*spi_t)(uint32_t *data); //定义的是一个返回值为void, 参数为uint32_t *的函数指针  void spi_tFunc(uint32_t *data) { 	printf("%d\n", *data); } int main() { 	spi_t F1 = NULL; 	F1 = spi_tFunc; 	uint32_t l1 = 6; 	F1(&l1); 	  	return 0; }


Question: 如何判断 -1.#IND000000000000

引用 8 楼 mujiok2003 的回复:#include <cmath> if(i == NAN){ //... }  if(isnan(i)){  }

#include <cmath> if(i == NAN){ //... }

引用 5 楼 daxiaoyuyu 的回复:[quote=引用 4 楼 derekrose 的回复:] 你想把i去掉？ 从符号表去掉么  我想判断出 i == -1.#IND000000000000; 这样的情况。不知道怎么弄。[/quote] i == i 你试试

我的理解是在C语言中对参数做判断，比如： if(a != 0) // a才可以做除数 if(a >= 0) // 才可以sqrt(a)

引用 4 楼 derekrose 的回复:你想把i去掉？ 从符号表去掉么  我想判断出 i == -1.#IND000000000000; 这样的情况。不知道怎么弄。

你想把i去掉？ 从符号表去掉么

引用 2 楼 KenZhang1031 的回复:那是你用了超范围的操作引起的，比如：除数为0，平方根参数用负数，对负数取对数，对无穷大的数执行加减乘除，反正弦和反余弦函数的参数大于1等等这些超范围的操作，具体看你程序中做了什么，对参数要做一下判断。 引用 1 楼 user-4 的回复:几个意思？出现这样的数值说明你的程序有bug，这个判断是干什么用？  因为我的程序的一些数据需要重外部导入。matlab中有NaN的导入到C语言的double类型就成了-1.#IND000000000000，我是为了不要处理原来matlab中有NaN的数据。

几个意思？出现这样的数值说明你的程序有bug，这个判断是干什么用？


Question: epoll的端口数量限制

引用 2 楼 gpshq 的回复:一个TCP连接的表示[源IP, 源port, 目的ip, 目的port]  弄蒙了，一直以为accept后的一个描述符对应一条链接，基本概念都没搞懂，2了....

一个TCP连接的表示[源IP, 源port, 目的ip, 目的port]

参考这个帖子 http://bbs.csdn.net/topics/390429343


Question: 寄存器写值

谢谢楼上两位大师，原来还有这样的规定

缺省是32位的, 左移7位不会越界的

你要分是8位的还是16位的还是32位的，16位和32位的话1792没错，14*(2的7次方)，8位的话，会丢弃高位，结果为0。

这是我用百度搜索出来的答案，也不知道对不对，求大神们指教下，谢谢


Question: 有点莫名其妙。。。

引用 1 楼 user-1 的回复:第18行下边加上这句 	long M = N; 24行的N改为M. ps:打印结果后边加上\n 忘了去单步调试，急躁了，哎，麻烦版主了。。下次得改

引用 1 楼 user-1 的回复:第18行下边加上这句 	long M = N; 24行的N改为M. ps:打印结果后边加上\n 捉急了，谢谢啦


Question: C语言结构体变量和结构体指针变量的疑问

习惯性问题吧  一般纯成员变量的话 大家都喜欢用struct

不管是不是结构体，指针都是C语言中的特点之一，如果不用指针，就发挥不了C语言相比于其它高级语言的优点，指针，自由而强大，同时也是一把双刃剑，用的不好，程序随时崩溃。

用指针省空间，不用传递给函数一个数据的副本，这个数据可能是庞大的。 那内存泄露对吧。。。嗯，你懂的。。。别的高级语言可能好点

跟结构体没啥关系，关键在于指针 至于为啥用指针——嗯，一幅宽度不确定高度不确定的图片，你不用指针保存一下试试看？再把它等大小切成四份八份三十二份不确定份数，你不用指针保存一下试试看？

函数传参一般用指针而不用指针指向的数据（包括结构体）。

赞同二楼，要不然谁愿意冒内存泄露的风险使用指针呢

指针和对象的区别，和结构体没啥关系。指针的作用搜一下一大把，再加上多实践就明白为啥要用指针了

引用 1 楼 user-9 的回复:因为指针效率比较高  不然谁特么用它啊 回答的真霸气····

因为指针效率比较高  不然谁特么用它啊


Question: DEV C++支持动态数组吗？

楼主是大几？？  建议先看一看变量在内存中的分配位置  不然你是搞不定动态数组的

引用 6 楼 mujiok2003 的回复:In C++ and pre-C99 versions of C, an array's size must be a constant integral expression so that it can be calculated at compile-time. In C99, this restriction was relaxed. An array's size must be an integral expression, not necessarily a constant one. This allows you to declare a variable-length array or an array whose size is determined at runtime. For example:  void func(int sz)  {  int arr[sz]; // sz ins't const; allowed only in C99 } The size of arr may be different for every func() call. For example:  int main() {  int size;  printf("enter array's size : ");  scanf("%d", &size);  func(size); }这位朋友才提到问题的点子上，不像某些人只知道装！

引用 10 楼 taodm 的回复:好吧，坚决地佩服你一下。传说中，C语言这把枪，很容易打到自己的脚。你中枪了。 补课C99以及数组越界吧。 [quote=引用 9 楼 lulutong_ 的回复:] [quote=引用 4 楼 movsd 的回复:] 这个不算动态数组，因为a的值已经定了，你试试  void fun(int a) { 	int b[a]; 	... }  int main() { 	fun(10); 	fun(20); }  int a = 10; int b[a]; a = 20; b[13]引用合法，说明b的范围变宽了，即动态加长了。[/quote][/quote]这段代码在DEV中编译通过并且成功运行。你可以先给a赋值，在0~a-1之间即为合法调用，怎么能说越界呢？a= 20,b[13]是合法的。动态数组即可以在运行过程中改变其长度的数组，这是我的理解。我知道一般都是用内存分配函数进行动态分配，但问题是在DEV中可以通过改变变量a的形式实现，这个不正是刚学C语言时候提到过的问题吗？ #include <stdio.h> #include <stdlib.h>  int main(int argc, char *argv[]) {     int a;     int b[a];      printf("a = ");     scanf("%d",&a);     printf("\nb[%d -1] = ",a);     scanf("%d",&b[a - 1]);     printf("\nb[%d - 1] = %d\n",a,b[a - 1]);       printf("a = ");     scanf("%d",&a);     printf("\nb[%d -1] = ",a);     scanf("%d",&b[a - 1]);     printf("\nb[%d - 1] = %d\n",a,b[a - 1]);    system("PAUSE");	   return 0; }

引用 9 楼 lulutong_ 的回复:[quote=引用 4 楼 movsd 的回复:] 这个不算动态数组，因为a的值已经定了，你试试  void fun(int a) { 	int b[a]; 	... }  int main() { 	fun(10); 	fun(20); }  int a = 10; int b[a]; a = 20; b[13]引用合法，说明b的范围变宽了，即动态加长了。[/quote]#include <stdio.h> #include <stdlib.h>  int main(int argc, char *argv[]) {     int a;     int b[a];      printf("a = ");     scanf("%d",&a);     printf("\nb[%d -1] = ",a);     scanf("%d",&b[a - 1]);     printf("\nb[%d - 1] = %d\n",a,b[a - 1]);       printf("a = ");     scanf("%d",&a);     printf("\nb[%d -1] = ",a);     scanf("%d",&b[a - 1]);     printf("\nb[%d - 1] = %d\n",a,b[a - 1]);    system("PAUSE");	   return 0; }

好吧，坚决地佩服你一下。传说中，C语言这把枪，很容易打到自己的脚。你中枪了。 补课C99以及数组越界吧。 引用 9 楼 lulutong_ 的回复:[quote=引用 4 楼 movsd 的回复:] 这个不算动态数组，因为a的值已经定了，你试试  void fun(int a) { 	int b[a]; 	... }  int main() { 	fun(10); 	fun(20); }  int a = 10; int b[a]; a = 20; b[13]引用合法，说明b的范围变宽了，即动态加长了。[/quote]

引用 4 楼 movsd 的回复:这个不算动态数组，因为a的值已经定了，你试试  void fun(int a) { 	int b[a]; 	... }  int main() { 	fun(10); 	fun(20); }  int a = 10; int b[a]; a = 20; b[13]引用合法，说明b的范围变宽了，即动态加长了。

引用 5 楼 derekrose 的回复:楼主 你认为什么叫动态数组   你这是动态的吗！！int b[a]，a是变量，用变量进行了数组界限的定义，变量的数值可以运行时改变，怎么不是动态数组？！事实，当取a=20是，对b[13]赋值也是合法的，并且可以正确输出，这难道不是典型的动态数组吗？

楼主 你认为什么叫动态数组   你这是动态的吗！！

http://www.microsoft.com/visualstudio/chs/downloads#d-2010-express 点开Visual C++ 2010 Express下面的语言选‘简体中文’，再点立即安装

引用 1 楼 zhao4zhong1 的回复:计算机组成原理→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对应的汇编并单步执行观察相应内存和寄存器变化。）  本人严重鄙视象DEV C++这种不能查看C/C++源代码对应汇编指令的IDE！VC倒是用了好几年，不过在win7系统上使用起来比较麻烦，VS又找不到破解版的，所以就选了这个DEV，这东东倒是蛮小巧的，17M，小巧程度跟TC有的拼。


Question: c中的疑惑

#define LCM(len) ((1 << LCM_TAG_SHI)| len) #include <stdio.h> int LCM_TAG_SHI; int L; int main() {     for (LCM_TAG_SHI=0;LCM_TAG_SHI<32;LCM_TAG_SHI+=2) {         printf("LCM_TAG_SHI==%d:\n",LCM_TAG_SHI);         for (L=0;L<0x1000;L+=0x100) {             printf("LCM(0x%08x)==0x%08x\n",L,LCM(L));         }         printf("\n");     }     return 0; } //LCM_TAG_SHI==0: //LCM(0x00000000)==0x00000001 //LCM(0x00000100)==0x00000101 //LCM(0x00000200)==0x00000201 //LCM(0x00000300)==0x00000301 //LCM(0x00000400)==0x00000401 //LCM(0x00000500)==0x00000501 //LCM(0x00000600)==0x00000601 //LCM(0x00000700)==0x00000701 //LCM(0x00000800)==0x00000801 //LCM(0x00000900)==0x00000901 //LCM(0x00000a00)==0x00000a01 //LCM(0x00000b00)==0x00000b01 //LCM(0x00000c00)==0x00000c01 //LCM(0x00000d00)==0x00000d01 //LCM(0x00000e00)==0x00000e01 //LCM(0x00000f00)==0x00000f01 // //LCM_TAG_SHI==2: //LCM(0x00000000)==0x00000004 //LCM(0x00000100)==0x00000104 //LCM(0x00000200)==0x00000204 //LCM(0x00000300)==0x00000304 //LCM(0x00000400)==0x00000404 //LCM(0x00000500)==0x00000504 //LCM(0x00000600)==0x00000604 //LCM(0x00000700)==0x00000704 //LCM(0x00000800)==0x00000804 //LCM(0x00000900)==0x00000904 //LCM(0x00000a00)==0x00000a04 //LCM(0x00000b00)==0x00000b04 //LCM(0x00000c00)==0x00000c04 //LCM(0x00000d00)==0x00000d04 //LCM(0x00000e00)==0x00000e04 //LCM(0x00000f00)==0x00000f04 // //LCM_TAG_SHI==4: //LCM(0x00000000)==0x00000010 //LCM(0x00000100)==0x00000110 //LCM(0x00000200)==0x00000210 //LCM(0x00000300)==0x00000310 //LCM(0x00000400)==0x00000410 //LCM(0x00000500)==0x00000510 //LCM(0x00000600)==0x00000610 //LCM(0x00000700)==0x00000710 //LCM(0x00000800)==0x00000810 //LCM(0x00000900)==0x00000910 //LCM(0x00000a00)==0x00000a10 //LCM(0x00000b00)==0x00000b10 //LCM(0x00000c00)==0x00000c10 //LCM(0x00000d00)==0x00000d10 //LCM(0x00000e00)==0x00000e10 //LCM(0x00000f00)==0x00000f10 // //LCM_TAG_SHI==6: //LCM(0x00000000)==0x00000040 //LCM(0x00000100)==0x00000140 //LCM(0x00000200)==0x00000240 //LCM(0x00000300)==0x00000340 //LCM(0x00000400)==0x00000440 //LCM(0x00000500)==0x00000540 //LCM(0x00000600)==0x00000640 //LCM(0x00000700)==0x00000740 //LCM(0x00000800)==0x00000840 //LCM(0x00000900)==0x00000940 //LCM(0x00000a00)==0x00000a40 //LCM(0x00000b00)==0x00000b40 //LCM(0x00000c00)==0x00000c40 //LCM(0x00000d00)==0x00000d40 //LCM(0x00000e00)==0x00000e40 //LCM(0x00000f00)==0x00000f40 // //LCM_TAG_SHI==8: //LCM(0x00000000)==0x00000100 //LCM(0x00000100)==0x00000100 //LCM(0x00000200)==0x00000300 //LCM(0x00000300)==0x00000300 //LCM(0x00000400)==0x00000500 //LCM(0x00000500)==0x00000500 //LCM(0x00000600)==0x00000700 //LCM(0x00000700)==0x00000700 //LCM(0x00000800)==0x00000900 //LCM(0x00000900)==0x00000900 //LCM(0x00000a00)==0x00000b00 //LCM(0x00000b00)==0x00000b00 //LCM(0x00000c00)==0x00000d00 //LCM(0x00000d00)==0x00000d00 //LCM(0x00000e00)==0x00000f00 //LCM(0x00000f00)==0x00000f00 // //LCM_TAG_SHI==10: //LCM(0x00000000)==0x00000400 //LCM(0x00000100)==0x00000500 //LCM(0x00000200)==0x00000600 //LCM(0x00000300)==0x00000700 //LCM(0x00000400)==0x00000400 //LCM(0x00000500)==0x00000500 //LCM(0x00000600)==0x00000600 //LCM(0x00000700)==0x00000700 //LCM(0x00000800)==0x00000c00 //LCM(0x00000900)==0x00000d00 //LCM(0x00000a00)==0x00000e00 //LCM(0x00000b00)==0x00000f00 //LCM(0x00000c00)==0x00000c00 //LCM(0x00000d00)==0x00000d00 //LCM(0x00000e00)==0x00000e00 //LCM(0x00000f00)==0x00000f00 // //LCM_TAG_SHI==12: //LCM(0x00000000)==0x00001000 //LCM(0x00000100)==0x00001100 //LCM(0x00000200)==0x00001200 //LCM(0x00000300)==0x00001300 //LCM(0x00000400)==0x00001400 //LCM(0x00000500)==0x00001500 //LCM(0x00000600)==0x00001600 //LCM(0x00000700)==0x00001700 //LCM(0x00000800)==0x00001800 //LCM(0x00000900)==0x00001900 //LCM(0x00000a00)==0x00001a00 //LCM(0x00000b00)==0x00001b00 //LCM(0x00000c00)==0x00001c00 //LCM(0x00000d00)==0x00001d00 //LCM(0x00000e00)==0x00001e00 //LCM(0x00000f00)==0x00001f00 // //LCM_TAG_SHI==14: //LCM(0x00000000)==0x00004000 //LCM(0x00000100)==0x00004100 //LCM(0x00000200)==0x00004200 //LCM(0x00000300)==0x00004300 //LCM(0x00000400)==0x00004400 //LCM(0x00000500)==0x00004500 //LCM(0x00000600)==0x00004600 //LCM(0x00000700)==0x00004700 //LCM(0x00000800)==0x00004800 //LCM(0x00000900)==0x00004900 //LCM(0x00000a00)==0x00004a00 //LCM(0x00000b00)==0x00004b00 //LCM(0x00000c00)==0x00004c00 //LCM(0x00000d00)==0x00004d00 //LCM(0x00000e00)==0x00004e00 //LCM(0x00000f00)==0x00004f00 // //LCM_TAG_SHI==16: //LCM(0x00000000)==0x00010000 //LCM(0x00000100)==0x00010100 //LCM(0x00000200)==0x00010200 //LCM(0x00000300)==0x00010300 //LCM(0x00000400)==0x00010400 //LCM(0x00000500)==0x00010500 //LCM(0x00000600)==0x00010600 //LCM(0x00000700)==0x00010700 //LCM(0x00000800)==0x00010800 //LCM(0x00000900)==0x00010900 //LCM(0x00000a00)==0x00010a00 //LCM(0x00000b00)==0x00010b00 //LCM(0x00000c00)==0x00010c00 //LCM(0x00000d00)==0x00010d00 //LCM(0x00000e00)==0x00010e00 //LCM(0x00000f00)==0x00010f00 // //LCM_TAG_SHI==18: //LCM(0x00000000)==0x00040000 //LCM(0x00000100)==0x00040100 //LCM(0x00000200)==0x00040200 //LCM(0x00000300)==0x00040300 //LCM(0x00000400)==0x00040400 //LCM(0x00000500)==0x00040500 //LCM(0x00000600)==0x00040600 //LCM(0x00000700)==0x00040700 //LCM(0x00000800)==0x00040800 //LCM(0x00000900)==0x00040900 //LCM(0x00000a00)==0x00040a00 //LCM(0x00000b00)==0x00040b00 //LCM(0x00000c00)==0x00040c00 //LCM(0x00000d00)==0x00040d00 //LCM(0x00000e00)==0x00040e00 //LCM(0x00000f00)==0x00040f00 // //LCM_TAG_SHI==20: //LCM(0x00000000)==0x00100000 //LCM(0x00000100)==0x00100100 //LCM(0x00000200)==0x00100200 //LCM(0x00000300)==0x00100300 //LCM(0x00000400)==0x00100400 //LCM(0x00000500)==0x00100500 //LCM(0x00000600)==0x00100600 //LCM(0x00000700)==0x00100700 //LCM(0x00000800)==0x00100800 //LCM(0x00000900)==0x00100900 //LCM(0x00000a00)==0x00100a00 //LCM(0x00000b00)==0x00100b00 //LCM(0x00000c00)==0x00100c00 //LCM(0x00000d00)==0x00100d00 //LCM(0x00000e00)==0x00100e00 //LCM(0x00000f00)==0x00100f00 // //LCM_TAG_SHI==22: //LCM(0x00000000)==0x00400000 //LCM(0x00000100)==0x00400100 //LCM(0x00000200)==0x00400200 //LCM(0x00000300)==0x00400300 //LCM(0x00000400)==0x00400400 //LCM(0x00000500)==0x00400500 //LCM(0x00000600)==0x00400600 //LCM(0x00000700)==0x00400700 //LCM(0x00000800)==0x00400800 //LCM(0x00000900)==0x00400900 //LCM(0x00000a00)==0x00400a00 //LCM(0x00000b00)==0x00400b00 //LCM(0x00000c00)==0x00400c00 //LCM(0x00000d00)==0x00400d00 //LCM(0x00000e00)==0x00400e00 //LCM(0x00000f00)==0x00400f00 // //LCM_TAG_SHI==24: //LCM(0x00000000)==0x01000000 //LCM(0x00000100)==0x01000100 //LCM(0x00000200)==0x01000200 //LCM(0x00000300)==0x01000300 //LCM(0x00000400)==0x01000400 //LCM(0x00000500)==0x01000500 //LCM(0x00000600)==0x01000600 //LCM(0x00000700)==0x01000700 //LCM(0x00000800)==0x01000800 //LCM(0x00000900)==0x01000900 //LCM(0x00000a00)==0x01000a00 //LCM(0x00000b00)==0x01000b00 //LCM(0x00000c00)==0x01000c00 //LCM(0x00000d00)==0x01000d00 //LCM(0x00000e00)==0x01000e00 //LCM(0x00000f00)==0x01000f00 // //LCM_TAG_SHI==26: //LCM(0x00000000)==0x04000000 //LCM(0x00000100)==0x04000100 //LCM(0x00000200)==0x04000200 //LCM(0x00000300)==0x04000300 //LCM(0x00000400)==0x04000400 //LCM(0x00000500)==0x04000500 //LCM(0x00000600)==0x04000600 //LCM(0x00000700)==0x04000700 //LCM(0x00000800)==0x04000800 //LCM(0x00000900)==0x04000900 //LCM(0x00000a00)==0x04000a00 //LCM(0x00000b00)==0x04000b00 //LCM(0x00000c00)==0x04000c00 //LCM(0x00000d00)==0x04000d00 //LCM(0x00000e00)==0x04000e00 //LCM(0x00000f00)==0x04000f00 // //LCM_TAG_SHI==28: //LCM(0x00000000)==0x10000000 //LCM(0x00000100)==0x10000100 //LCM(0x00000200)==0x10000200 //LCM(0x00000300)==0x10000300 //LCM(0x00000400)==0x10000400 //LCM(0x00000500)==0x10000500 //LCM(0x00000600)==0x10000600 //LCM(0x00000700)==0x10000700 //LCM(0x00000800)==0x10000800 //LCM(0x00000900)==0x10000900 //LCM(0x00000a00)==0x10000a00 //LCM(0x00000b00)==0x10000b00 //LCM(0x00000c00)==0x10000c00 //LCM(0x00000d00)==0x10000d00 //LCM(0x00000e00)==0x10000e00 //LCM(0x00000f00)==0x10000f00 // //LCM_TAG_SHI==30: //LCM(0x00000000)==0x40000000 //LCM(0x00000100)==0x40000100 //LCM(0x00000200)==0x40000200 //LCM(0x00000300)==0x40000300 //LCM(0x00000400)==0x40000400 //LCM(0x00000500)==0x40000500 //LCM(0x00000600)==0x40000600 //LCM(0x00000700)==0x40000700 //LCM(0x00000800)==0x40000800 //LCM(0x00000900)==0x40000900 //LCM(0x00000a00)==0x40000a00 //LCM(0x00000b00)==0x40000b00 //LCM(0x00000c00)==0x40000c00 //LCM(0x00000d00)==0x40000d00 //LCM(0x00000e00)==0x40000e00 //LCM(0x00000f00)==0x40000f00 //

引用 1 楼 zhao4zhong1 的回复://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 | //+------------------+-----------------------------------------+---------------+   |                | Bitwise OR                              | Left to right 您是指我的那个属于这个？那我的完整的意思是什么呢，能麻烦您告知吗


Question: 仿QQ 截图

真不错！希望自己以后也能做一个！


Question: printf("\nCC\toptions\tfile.[cC]\n");打印结果是什么

引用 3 楼 chinmusam 的回复:调试的结果显示：CC       options file.[cC] 从结果上看，明显第一个\t处跳转位置正确，而后面的\t应该是接着前面的options显示后，再跳一个制表位(即7个空字符)才显示后面的file这个单词才正确呀？可结果显示，第二个\t只后跳了一个空字符。求解释。 did you read what 1# and 2# text?

学习到了  吼吼 好幸福啊  又懂了一点点

引用 3 楼 chinmusam 的回复:调试的结果显示：CC       options file.[cC] 从结果上看，明显第一个\t处跳转位置正确，而后面的\t应该是接着前面的options显示后，再跳一个制表位(即7个空字符)才显示后面的file这个单词才正确呀？可结果显示，第二个\t只后跳了一个空字符。求解释。 可以理解成为\t显示的长度是[1,8],至少是一个空位(前面有7个字符时),至多8个空位(前面已经对齐到8的整数倍) 具体是1还是8.显示完\t后一行的长度为8的整数倍为准. options 7个字符,加一个\t, 这是只要一个空格的位置,就可以对齐到8的整数倍位置,即'f'显示在第8列上(base on 0). 试试 $ echo -e "\nCC\toptions\tfile.[cC]\n"  CC      options file.[cC]  $ echo -e "\nCC\toptions1\tfile.[cC]\n"  CC      options1        file.[cC]  (代码显示有问题,使用了空格代替制表符)

不就是cC吗？

同求解释•••••••

\t是一个制表符位, 默认8个空格长度, 它会跳到下一个8的倍数的整数列上 options已经占了7位，/t只是向后移动一位

\t是一个制表符位, 默认8个空格长度, 它会跳到下一个8的倍数的整数列上（从第0列开始数）  options已经占了7位，/t只是向后移动一位


Question: 急求！希望这题做了能给明天考试一些帮助 （C语言写）

代码功能归根结底不是别人帮自己看或讲解或注释出来的；而是被自己静下心来花足够长的时间和精力亲自动手单步或设断点或对执行到某步获得的中间结果显示或写到日志文件中一步一步分析出来的。 提醒：再牛×的老师也无法代替学生自己领悟和上厕所！ 单步调试和设断点调试是程序员必须掌握的技能之一。 查MSDN是Windows程序员必须掌握的技能之一。

说的是  感谢！

while循环用fgets 读入一行line sscanf(line,"%[^,],%[^,],%s",name,number,tmp); //tmp没用，防止坏数据溢出 然后数据就出来了，放到数组里处理输出就好了

用fscanf的话怎么把数据分开啊   例如分开aaa和77  新手呀 能给一些代码吗 我好好体会一下 下午就要考了 谢谢！

读文件用fscanf就可以了. 数据可以用链表, 也可以简单一点用数组(事先假定一个最大的学生数目)

读文件是个问题   要用哪个一个函数读  fscanf？  然后这些数据存在哪里  要建立链表吗

1. 读文件 2. 以姓名为key作查找和计算 3. 排序 4. 写文件  你是哪部分不会呢?

十分感谢六楼以及其他回帖的人 ~~~  但能不能给点注释啊@#6

//读入一系列两元组数据<姓名，成绩>，生成一个排序的五元组<姓名，总分，平均分，最低分，最高分>，并将排序结果按照姓名的降序生成到文件。 // //文件举例： //Input files: In_3.txt //<aaa,77> //<bbb,82> //<ccc,72> //<aaa,83> //<bbb,95> // //Output files: [Your Student No.]_3_out.txt //<ccc,72,72,72,72> //<bbb,177,88.5,82,95> //<aaa,160,80,77,83> #include <stdio.h> #include <string.h> #define MYNO "0001" #define MAXL 1000 static struct S {     char nam[20];     double tsc;     double asc;     double lsc;     double hsc;     int num; } s[MAXL],t; char ln[80]; char nam[20]; double sco; FILE *f; int n,i,h,j; char c; int main() {     f=fopen("In_3.txt","r");     if (f==NULL) {         printf("Can not open file In_3.txt\n");         return 1;     }     n=0;     h=0;     while (1) {         if (NULL==fgets(ln,80,f)) break;         h++;         if (3==sscanf(ln,"<%19[^,],%lf%c",nam,&sco,&c)) {             if (c!='>') printf("line %d formar error:%s",h,ln);             else {                 for (i=0;i<n;i++) {                     if (0==strcmp(nam,s[i].nam)) break;                 }                 if (i<n) {                     s[i].tsc+=sco;                     if (s[i].lsc>sco) s[i].lsc=sco;                     if (s[i].hsc<sco) s[i].hsc=sco;                     s[i].num++;                 } else {                     strcpy(s[n].nam,nam);                     s[n].tsc=sco;                     s[n].lsc=sco;                     s[n].hsc=sco;                     s[n].num=1;                     n++;                     if (n>=MAXL) {                         printf("Too many students(>%d)!\n",MAXL);                         fclose(f);                         return 2;                     }                 }             }         } else {             printf("line %d formar error:%s",h,ln);         }     }     fclose(f);     for (i=0;i<n;i++) {         s[i].asc=s[i].tsc/s[i].num;     }     for (i=0;i<n-1;i++) {         for (j=i+1;j<n;j++) {             if (strcmp(s[i].nam,s[j].nam)<0) {                 t=s[i];s[i]=s[j];s[j]=t;             }         }     }     f=fopen("["MYNO"]_3_out.txt","w");     for (i=0;i<n;i++) {         fprintf(f,"<%s,%lg,%lg,%lg,%lg>\n",s[i].nam,s[i].tsc,s[i].asc,s[i].lsc,s[i].hsc);     }     fclose(f);     return 0; } //type [0001]_3_out.txt //<ccc,72,72,72,72> //<bbb,177,88.5,82,95> //<aaa,160,80,77,83> //


Question: 一个vs的链接问题。

问题是代码的作者能编译出来。而且就算写汇编也可能有这种问题，因为是链接而不是编译的问题。

写.asm

直接插入汇编吧

顶起，求解..


Question: c语言删除字符串多余空格问题

string指向字符串常量，不能对字符串常量做修改

引用 5 楼 darktempl123 的回复:[quote=引用 2 楼 a345485527 的回复:]  int main() { 	char str[]="abc   d"; 	deblank(str); }  多说一句，deblank函数达不到Lz的需求 能给解释一下为什么这样就没有那个内存错误了吗？我那种写法传递的是字符串常量？[/quote] 是的 先前传递的"abcd"是存放在文字常量区的，顾名思义，试图修改是不允许的 而用一个数组 str[]则是在栈内存放的，允许修改 同理 char *str="abc"是一个执行常量的指针，故同样不能修改str指向内存的内容

#pragma comment(linker,"/SECTION:.rdata,RW") //加这句可以让常量区可写，后果自负！

引用 2 楼 a345485527 的回复: int main() { 	char str[]="abc   d"; 	deblank(str); }  多说一句，deblank函数达不到Lz的需求 能给解释一下为什么这样就没有那个内存错误了吗？我那种写法传递的是字符串常量？

#include <stdio.h> #include <string.h>  void deblank(char string[]) {          int j=1;     for(int i=0;i<=strlen(string)-2;i++,j=i+1)     {         if(string[i]==' '&&string[j]==' ')         {             string[j]=string[++j];         }     }     puts(string); }   int main() {     char str[] = "abc  d";     deblank(str);     return 0; }  引用 楼主 darktempl123 的回复:初学c语言，想实现这么个功能：如果字符串有一个地方由一个或多个连续空格组成，就把它们改成单个空格字符。比如abc  d输出成abc d。  #include <stdio.h> #include <string.h> void deblank(char string[]) { 	 	int j=1; 	for(int i=0;i<=strlen(string)-2;i++,j=i+1) 	{ 		if(string[i]==' '&&string[j]==' ') 		{ 			string[j]=string[++j]; 		} 	} 	puts(string); }  int main() { 	deblank("abc  d"); } 但是这段代码总是报错，好像和内存地址冲突有关，求点拨，怎么才能用数组实现这个功能呢？


Question: Makefile疑问

静态库的话，不需要的，直接运行就好！

搜“跟我一起写makefile”

引用 2 楼 max_min_ 的回复:静态库的话，不需要的，直接运行就好！ 怎么判断是静态库还是动态库？Makefile中看不出来么

首先分清运行时和编译时分别是什么东西

引用 3 楼 turingo 的回复:是编译的时候去链接ovi库，运行的时候是不需要的。  [quote=引用 楼主 hanzhaoshuai 的回复:]  上面是makefile中的一段，我的疑惑，md_func1.fcgi运行时是不是要到/home/ovi_lib目录下找 ovi这个库？ 如果找不到怎么办？不明白，求指点。。。[/quote]  不是有动态库 .so 和静态库 .a 的区别么，怎么判断是静态库还是动态库？

是编译的时候去链接ovi库，运行的时候是不需要的。  引用 楼主 hanzhaoshuai 的回复: 上面是makefile中的一段，我的疑惑，md_func1.fcgi运行时是不是要到/home/ovi_lib目录下找 ovi这个库？ 如果找不到怎么办？不明白，求指点。。。


Question: linux下套接字问题

int loopWriteV(int _isockfd, struct iovec *_iov, int _iovcnt) { int iret = 0;  int i = 0; int itmplen0 = 0; int itmplen1 = 0; int itmplen2 = 0;  for(i = 0; i < _iovcnt; i++) { itmplen0 += _iov[i].iov_len; }   int w;  i = 0;//归零 while(itmplen0 > 0) {  itmplen1 = writev(_isockfd, _iov + i, _iovcnt - i); if(itmplen1 == itmplen0) { break; } else if(itmplen1 <= 0) { if((errno == EINTR) ||(errno == EAGAIN)) { continue; } else { perror("what the fucking what"); iret = -1; goto leave; } } else// if(itmplen1 < itmplen0) {  itmplen0 -= itmplen1; itmplen2 = 0;  for(; i < _iovcnt; i++) { itmplen2 += _iov[i].iov_len;  if(itmplen2 > itmplen1) { //此处指针偏移错误 //_iov[i].iov_base +=  (itmplen2 - itmplen1); //_iov[i].iov_len -= (itmplen2 - itmplen1);  break; } else if(itmplen2 == itmplen1) { i++; break; } } } } leave:  return iret; }   我找到原因了，还是要感谢各位的回答。

1， No such file or directory : 没有文件路径  可能是socket的参数是不是正确；文件（资源）路径是否正确；指定的文件（资源）是否有读写权限 2， 不让变成阻塞 可能是怕程序卡死吧  3， 其他的就不知道了

我是根据writev返回值，然后while里发送，代码如下, 可有不合理的地方？？？ int loopWriteV(int _isockfd, struct iovec *_iov, int _iovcnt) { 	int iret = 0;	 	int i = 0; 	int itmplen0 = 0; 	int itmplen1 = 0; 	int itmplen2 = 0; 	 	for(i = 0; i < _iovcnt; i++) 	{ 		itmplen0 += _iov[i].iov_len; 	}   	int w; 	 	i = 0;//归零 	while(itmplen0 > 0) 	{  		itmplen1 = writev(_isockfd, _iov + i, _iovcnt - i); 		if(itmplen1 == itmplen0) 		{ 			break; 		} 		else if(itmplen1 <= 0) 		{ 			if((errno == EINTR) ||(errno == EAGAIN)) 			{ 				continue; 			} 			else 			{ 				perror("what the fucking what"); 				iret = -1; 				goto leave; 			} 		} 		else// if(itmplen1 < itmplen0) 		{ 			 			itmplen0 -= itmplen1; 			itmplen2 = 0; 			 			for(; i < _iovcnt; i++) 			{ 				itmplen2 += _iov[i].iov_len; 					 				if(itmplen2 > itmplen1) 				{ 					_iov[i].iov_base +=  (itmplen2 - itmplen1); 					_iov[i].iov_len -= (itmplen2 - itmplen1);  					break; 				} 				else if(itmplen2 == itmplen1) 				{ 					i++; 					break; 				} 			} 		} 	} leave:	 	return iret; }

writev：成功返回write字节数，失败返回-1，用 error()获取错误码，

引用 3 楼 user-3 的回复:检查下你发送的时候 socket套接字是否有效！  版主老大 ，这个怎么检查呀？不应该根据writev的返回值检查吗？返回值是-1，我这面没有关闭socket，如果对端关闭的话不应该是reset by peer吗？

检查下你发送的时候 socket套接字是否有效！


Question: extern char hello[]；是嘛意思阿 ？

就是在另外一个文件里定义了char hello[xxxx]; 定义那里必须明确数组的大小. 这里只是声明, 说明hello是一个char类型的数组, 声明时不必说明大小.

表示hello是个外部符号，他的定义在其他的编译单元中 可以有，但没有意义。

可以不可以 试试就知道了

工程搜索下char hello[ ，这个应该是在其它cpp定义的。此处只是一个外部引用声明


Question: 【大家来找茬】不知道到这发个这样的帖子合不合适呀。。。各位C/C++大牛们快来呀~~~~~~~~~

引用 10 楼 vipcxj 的回复:我之所以说LZ分多得没处花是因为既然这代码是LZ自己用来练手的，那么遇到问题就应该自己常识解决，这样水平才能提高，一味依靠别人，那就是在浪费时间   http://bbs.csdn.net/topics/390688307  分已散，请去接分吧

引用 14 楼 vipcxj 的回复:[quote=引用 13 楼 benma378 的回复:] [quote=引用 9 楼 vipcxj 的回复:] 又是一段明显初学者写的代码~  int strcompare(char *s, char *t)   {           if(!s && !t){          return 0;     }     if(s && !t){         return 1;     }     if(!s && t){         return -1;     }     while(*s || *t){ //这个条件是错误滴，*s && *t         if(*s > *t){             return 1;         }else if(*s < *t){             return -1;         }         s++;         t++;     }      //可不能直接返回0     if (*s)        return 1;     else if (*t)        return -1;     else        return 0; }   关于这个条件，我觉得是或关系，因为子串肯定短一些，必须完全遍历一遍父串吧。其实子串可以不要，放在循环里判断更好一些[/quote]  你这种逻辑就是非常有问题的，如果是或关系，就有可能有一个超出字符串范围，一个还在范围内，但出不了循环，仍旧继续在迭代，导致的结果是必然会访问到字符串上无效的位置。其实你只要考虑到循环访问一个字符串，绝对要保证访问的都是有效位置就不会出这种问题了。我估计你的思路是妄图走捷径，希望在循环内一次解决，其实编程最好不要有捷径的想法，情愿事后优化也不要在编写的时候想着直接写出最好最简洁的方法，往往这样花的时间更长，错误率更高。[/quote]  你应该是一个比较有经验的程序员了。。。确实是这样的哈，刚刚想删回复也删不了，想编辑也编辑不了了。确实没有思考清楚就回复了。 嗯，昨晚写的程序，发现时间越晚可能错误率也高。现在我来看着代码，感觉确实思路不清晰，这是一个修炼的过程。我还有很长的路要走！谢谢！我会把可用分散在灌水区里，希望你来拿。。呵呵，兑现我的承诺。好像不能直接转的吧

引用 13 楼 benma378 的回复:[quote=引用 9 楼 vipcxj 的回复:] 又是一段明显初学者写的代码~  int strcompare(char *s, char *t)   {           if(!s && !t){          return 0;     }     if(s && !t){         return 1;     }     if(!s && t){         return -1;     }     while(*s || *t){ //这个条件是错误滴，*s && *t         if(*s > *t){             return 1;         }else if(*s < *t){             return -1;         }         s++;         t++;     }      //可不能直接返回0     if (*s)        return 1;     else if (*t)        return -1;     else        return 0; }   关于这个条件，我觉得是或关系，因为子串肯定短一些，必须完全遍历一遍父串吧。其实子串可以不要，放在循环里判断更好一些[/quote]  你这种逻辑就是非常有问题的，如果是或关系，就有可能有一个超出字符串范围，一个还在范围内，但出不了循环，仍旧继续在迭代，导致的结果是必然会访问到字符串上无效的位置。其实你只要考虑到循环访问一个字符串，绝对要保证访问的都是有效位置就不会出这种问题了。我估计你的思路是妄图走捷径，希望在循环内一次解决，其实编程最好不要有捷径的想法，情愿事后优化也不要在编写的时候想着直接写出最好最简洁的方法，往往这样花的时间更长，错误率更高。

引用 9 楼 vipcxj 的回复:又是一段明显初学者写的代码~  int strcompare(char *s, char *t)   {           if(!s && !t){          return 0;     }     if(s && !t){         return 1;     }     if(!s && t){         return -1;     }     while(*s || *t){ //这个条件是错误滴，*s && *t         if(*s > *t){             return 1;         }else if(*s < *t){             return -1;         }         s++;         t++;     }      //可不能直接返回0     if (*s)        return 1;     else if (*t)        return -1;     else        return 0; }   关于这个条件，我觉得是或关系，因为子串肯定短一些，必须完全遍历一遍父串吧。其实子串可以不要，放在循环里判断更好一些

引用 2 楼 vipcxj 的回复: void strcopy(char **target, char *source)  {     if(!source){         return;     }     unsigned length = strlenth(source);     *target = (char*)malloc(length + 1); //这里要改     if(*target){         return;     }     unsigned int i = 0;       for(; i<length; ++i){         (*target)[i] = source[i];     }     (*target)[i] = '\0'; }   先修正一个在看下面的  length+1确实是的，但是你说在哪种情况下回导致死循环呢还是越界访问？为啥一定要把while改成for呢？while不是更加简洁吗？

引用 10 楼 vipcxj 的回复:我之所以说LZ分多得没处花是因为既然这代码是LZ自己用来练手的，那么遇到问题就应该自己常识解决，这样水平才能提高，一味依靠别人，那就是在浪费时间这话在理，遇到问题应该先自己思考，google之，再思考之。。。  说实话，Java和C、C++差别还是蛮大的。很多繁琐的细节问题Java都不需要去反复考虑，而C、C++就不一样，存在这复杂的指针、内存问题。  当然，从算法的严谨度来说，这样的代码确实太嫩了。但这岂是一朝一夕的事情？  这是一道OJ上的题，由于两年多没接触过C、C++，只有靠大一那点底子了。（当然，你会说这是我不主动学习的借口）当时我提交的时候，自己的用例都通过了，就是不知道为啥OJ上跑就超时了，知道肯定是自己代码问题，但一时找不到自己漏洞到底在哪？对C、C++细节确实不是熟悉，一个从没系统学习过的能熟悉到哪去呢？  当然，如果是要我学习的话，我不会这样学的，应该是从最基础的开始，一步一步来。总之，你猜对了

引用 6 楼 vipcxj 的回复:老实说看着这些代码的水平，我估计这根本就是LZ自己写来练手的吧，但又不好意思不耻下问，就出此下策了，不过看在LZ的分多得没处花的份上，我还是来帮帮LZ吧 好吧，我确实没啥水平，因为代码总量不超过10w行。。学生党嘛。。。  请友情提示一下代码问题在哪？比如代码风格啊，思路啊，清晰度，可靠性等等这些问题。  当然C/C++用法方面的就算了，我这两年来一直写Java，最近才接触这些东西。主要是算法评价和思路

引用 5 楼 benma378 的回复:[quote=引用 2 楼 vipcxj 的回复:]  void strcopy(char **target, char *source)  {     if(!source){         return;     }     unsigned length = strlenth(source);     *target = (char*)malloc(length + 1); //这里要改     if(*target){         return;     }     unsigned int i = 0;       for(; i<length; ++i){         (*target)[i] = source[i];     }     (*target)[i] = '\0'; }   先修正一个在看下面的 引用 4 楼 benma378 的回复:额，忘了说了，每找出一个，必须说出理由和可行的测试用例。。每一个奖励可用分100分请说出理由[/quote] 你比对一下不就能看出问题了，第一个问题，你为字符串申请内存要length+1，这是常识吧，第二个问题，你后面空指针的判断，其实这应该第一步判断吧，你后判断也是依赖于你strlength里面判断过，不然就死定了。后面的循环，你既然已经搞到了length，为啥还要用while，直接for不就得了。

引用 2 楼 vipcxj 的回复: void strcopy(char **target, char *source)  {     if(!source){         return;     }     unsigned length = strlenth(source);     *target = (char*)malloc(length + 1); //这里要改     if(*target){         return;     }     unsigned int i = 0;       for(; i<length; ++i){         (*target)[i] = source[i];     }     (*target)[i] = '\0'; }   先修正一个在看下面的 引用 4 楼 benma378 的回复:额，忘了说了，每找出一个，必须说出理由和可行的测试用例。。每一个奖励可用分100分请说出理由

引用 1 楼 user-2 的回复:人艰不拆

人艰不拆


通过了 1>------ 已启动生成: 项目: Test, 配置: Debug Win32 ------ 1>生成启动时间为 2014/1/7 21:49:24。 1>ClCompile: 1>  test.c 1>d:\source code\test\test\test.c(7): warning C4244: “=”: 从“double”转换到“float”，可能丢失数据 1> 1>生成成功。 1> 1>已用时间 00:00:00.11 ========== 生成: 成功 1 个，失败 0 个，最新 0 个，跳过 0 个 ==========

1、sqrt要求参数为非负浮点数，如果为负数，返回值不定。 2、http://msdn.microsoft.com/zh-cn/library/f1xa99e6.aspx

第一个。。。 怎么会通过编译呢


Question: 三个关于c语法的问题，谢谢

学然后知不足。

还有大家能告诉我下 void * p.........和（void *）p..........的区别吗

1.2.4）补充一下,函数指针变量的声明。    typedef int32_t (*a)(void);//定义 a ，a 这个名字，就是函数指针 int32_t (*)(void) 这种类型。    int32_t (*pa)(void); //直接声明函数指针变量。    a pa;                //用定义的类型名 a ,声明函数指针变量。

1）要结合 typedef 关键字，和函数指针的概念看 1.1）typedef 用于给现有的类型，定义一个新名字。  typedef int32_t (*a)(void); //给函数指针类型，int32_t (*)(void)定义一个名字 a; 1.2)函数是有类型的     1.2.1) 函数大都有一个返回值，这个返回值（如果有的话），是有类型的     1.2.2) 函数大都有一些参数，每个参数也是有类型的。     1.2.3）函数的类型，            a) 包涵了它的返回值类型(0～1个返回值类型);               无返回值视作返回void 类型            b) 参数个数(0~n个参数);               无参数参数表,可能会写上 void,表示无参数.            c) 每个参数的类型(如果有参数)。            这些全都相同的，视为一个类型的函数。      1.2.4）指向某一类型函数的指针，就是该类型的函数指针。      函数有一个地址，所以，可以用，表示地址类型的，数据（指针），表示函数地址。      这个，表示函数地址的，数据类型，就是函数指针类型。       函数指针类型的数据定义,声明，赋值,调用函数      如下       a) int32_t (*pa)(void); //声明pa 是一个函数指针，类型为 int32_t (*)(void)           //该类型的指针，指向一个，返回值类型为int32_t，无参数的函数。      b)      int32_t fun(){return 0;}; //定义一个函数fun,返回值类型为int32_t，无参数.         int32_t (*pa)(void) = fun; //定义pa 是一个函数指针，类型为 int32_t (*)(void),用fun初始化         int32_t v;         pa = fun  ;//用函数(地址),给函数指针赋值         pa = &fun  ;//用函数地址,给函数指针赋值,有人认为这样更明确。         fun(); //函数调用，忽略返回值。                  pa();  //函数调用，通过函数指针，调用函数，忽略返回值。         (*pa)(); //函数调用，通过函数指针，调用函数，忽略返回值。有人认为这样更明确。         v = fun(); //函数调用，用返回值，给变量v赋值。这是包含，函数调用表达式的，赋值表达式。         v = pa(); //函数调用，通过函数指针，调用函数,                   // 用返回值，给变量v赋值。这是包含，函数调用表达式的，赋值表达式。                   // 函数用函数指针表示。                   v = (*pa)(); //函数调用，通过函数指针，调用函数,                   // 用返回值，给变量v赋值。这是包含，函数调用表达式的，赋值表达式。                   // 函数，用函数指针的，解引用，表示。                    // 有人认为这样更明确。          1.3） 给函数指针定义一个名字，并使用      typedef int32_t (*a)(void); //给函数指针类型，int32_t (*)(void)，定义一个名字 a;     int32_t fun(){return 0;}; //定义一个函数fun,返回值类型为int32_t，无参数.     a pa =fun; //定义一个a 类型变量，初始化为fun                //a类型就是 int32_t (*)(void)这是一个,                //返回值类型为int32_t，无参数的，函数指针类型。     pa();//     printf("%d\n",pa()); 通过a类型指针pa， 调用函数fun，并输出返回值。  2）a->b->c 这个只是指向运算符（->） 的连续使用，准确的说不是一种调用。 这个可以看成这样 (a->b)->c; 可以理解成这样： (* ((*a).b) ).c

引用 3 楼 jerry_dqh 的回复:3也不能算偏！基础没有看啊 3）应该有点偏的。 理由如下： a) 很多入门书（可能很垃圾）不会讲续行符的，毕竟这不是一种运算符，也不是普通的分隔符。    多半都是用在宏定义的地方。 b)虽然，续行符,可以用在任何其他地方，基本上，别的地方都不会用续行符。 因为通常来说，不用续行符，和使用续行符，没有多大区别，除非用于宏定义。  c)相信，没有几个人，在非宏定义中，使用续行符。   所以，有些入门书不讲续行符，也是有谅可原的。

我把c语言的基础学习篇都看了好几遍了，是不是得看看一些提高的书？大神们能方便推荐下不，我现在看的c语言大全目前还没有看到上面的答案

引用 4 楼 u013410394 的回复:谢谢大神，你已经讲得很详细了，可是我还得细细想想，第一个和第二个还不是特别懂，第二个的a->b->c这样死连续调用吗 是的,a->b的返回值在调用c

3也不能算偏！基础没有看啊

1）定义函数指针类型 a，即给函数指针类型 int32_t (*)(void) 类型起个名字，叫做 a;    这个看任何一本C语言的书，就知道了。    typedef int32_t (*a)(void);      int32_t fun(){return 0;};    int main(){    a *pfun = fun; //这是初始化a 类型指针    printf("pfun() = %d",           pfun()//这是通过函数指针调用函数。           );     return 0;         } 2）这是指向运算符-> ; c->a 相当于 (*c).a ，这个看任何一本C语言的书，就知道了，前者是后者的简化写法，后来就固定为一个运算符了。   3)  \ 是续行符 ，表示这行代码没结束，下一行的和这一行，实际是同一行代码。 PS： 只有3）比较偏僻，1）2）只要看书能够知道。

大神们求教，分虽然不多，但是心意诚啊，谢谢大家


Question: 求指导C语言中可变参数宏的知识

#define va_arg(ap,t)    ( *(t *)((ap += _INTSIZEOF(t)) - _INTSIZEOF(t)) ) 这句前面*(t *)有什么意义？先强制转成二级指针再转为一级指针的作用是什么？  这么没有那么多道道。  1)va_list 就是char * typedef char *  va_list; 所以ap 是个 char 类型的指针 2）char 类型的指针，加上_INTSIZEOF(t)后，就指向下一个参数了。    注意这里是 +=，所以ap变了   ap += _INTSIZEOF(t)    //让 ap跳过当前参数，指向下一个参数。     3）再减去_INTSIZEOF(t)，回到当前参数的位置，不过ap现在，指向下一个参数。   注意这里是 -   所以ap不变。   (t *)((ap += _INTSIZEOF(t)) - _INTSIZEOF(t)) //跳过当前参数后，            //表达式(ap += _INTSIZEOF(t)) - _INTSIZEOF(t)的值，为ap - _INTSIZEOF(t)           // ap-_INTSIZEOF(t) 是当前参数的地址，类型为 char * (t *)(ap-_INTSIZEOF(t)) char * 强制转换为 t *    4）指针的强制类型转换，和指针解引用   *(t *)((ap += _INTSIZEOF(t)) - _INTSIZEOF(t))    强制类型转换后的得到的 一个t* (t 类型的指针)，  指向的数据类型为 t ，解引用得到一个t类型的参数，是个左值。  5）总结，这里分几个步骤 5.1） 步骤1，前进到下一个参数，ap指向下一个参数。    ap += _INTSIZEOF(t) //让ap，加上认定的参数长度(t 类型的参数，在传递时候的长度)，  5.2）步骤2，返回到当前参数 ，ap 不变，依然指向下一个参数。    (t*)(ap-_INTSIZEOF(t)) //这就是当前参数地址，这里看作t类型的参数地址， 5.3)步骤3，强制类型转换，并解引用，最外面的括号，是为了防止宏扩展错误。    (*(t *)((ap += _INTSIZEOF(t)) - _INTSIZEOF(t)))  PS：      C 式的，带有不定类型和个数参数的，      函数的参数表中的，      省略号表示的，不确定参数表部分，          参数类型信息，无法直接传递，      只能，从已经确定的参数里，获取类型信息，      比如 scanf,printf 这两个函数，从第一个参数里，提取其他参数的类型信息。      或者，直接认定，是某种类型的参数。      比如，你做一个累加和的函数，第一个参数为整型，是参数个数      默认，其他所有参数的类型，都是整型，或者浮点类型。

引用 楼主 sozenvN 的回复:va_start(ap, c);//此时ap应该指向c后面的第一个可变参数,为什么我用printf("%s", ap);输出不了,ap不是已经指向那个可变参数了吗？ 不是的， va_start 之后， ap 是指向第一个可变参数的地址，而不是第一个可变参数！ 它需要解引用一次后才是参数的值。所以， printf("%s", *(char**)ap) 才对，即使 printf("%s", *(int*)ap) 也行，总之需要解引用一次。  引用 楼主 sozenvN 的回复:&v对这个函数而言不就是二级指针吗？为什么用到二级指针,直接去v的地址加上v的内存大小不照样得到v后面一个参数的地址吗？而用二级指针的话我调试了还不是那个地址，疑惑！ 之所以会是二级指针只是因为你的参数本身是个指针而已，这几个宏是通用的宏，当你的参数不是指针时，它就只是个指针，不是二级指针了。  这里所做的事情正是 “去v的地址加上v的内存大小不照样得到v后面一个参数的地址”，v 本身是个指针，取它的地址就是二级指针。  引用 楼主 sozenvN 的回复:这句前面*(t *)有什么意义？先强制转成二级指针再转为一级指针的作用是什么？ 这其实就是进行一次解引用，并转换成 t 的类型， 不要再纠结几级指针了，先把 t 写成 int 类型来推导一下过程吧。

[quote=引用 10 楼 zhao4zhong1 的回复:] 谢谢老师的回复，这段源码确实有很多疑惑。

计算机组成原理→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

编译选项加/EP /P，重新编译，查看宏展开后对应的.i文件。gcc加-E

引用 4 楼 adlay 的回复:[quote=引用 楼主 sozenvN 的回复:] va_start(ap, c);//此时ap应该指向c后面的第一个可变参数,为什么我用printf("%s", ap);输出不了,ap不是已经指向那个可变参数了吗？ 不是的， va_start 之后， ap 是指向第一个可变参数的地址，而不是第一个可变参数！ 它需要解引用一次后才是参数的值。所以， printf("%s", *(char**)ap) 才对，即使 printf("%s", *(int*)ap) 也行，总之需要解引用一次。  引用 楼主 sozenvN 的回复:&v对这个函数而言不就是二级指针吗？为什么用到二级指针,直接去v的地址加上v的内存大小不照样得到v后面一个参数的地址吗？而用二级指针的话我调试了还不是那个地址，疑惑！ 之所以会是二级指针只是因为你的参数本身是个指针而已，这几个宏是通用的宏，当你的参数不是指针时，它就只是个指针，不是二级指针了。  这里所做的事情正是 “去v的地址加上v的内存大小不照样得到v后面一个参数的地址”，v 本身是个指针，取它的地址就是二级指针。  引用 楼主 sozenvN 的回复:这句前面*(t *)有什么意义？先强制转成二级指针再转为一级指针的作用是什么？ 这其实就是进行一次解引用，并转换成 t 的类型， 不要再纠结几级指针了，先把 t 写成 int 类型来推导一下过程吧。[/quote] #define va_start(ap, v) (ap = (va_list)&(v) + _INTSIZEOF(v)) 如果按这个例子 void va_test(char* a, char* b, char* c, …) va_start(ap, c)宏展开  ap = (va_list)&c + _INTSIZEOF(c)  这句怎么理解？ 此时c是char* 类型,&c是指向char*类型的二级指针,(va_list)强制转换为char*类型指针，然后加上c指针的大小， 我的疑惑是，如果不强制转换的话 &(c) 和 (va_list)&(c) 加上_INISIZEOF(c)后指向的结果有什么不同？

va_arg, va_end, va_start Access variable-argument lists.  type va_arg( va_list arg_ptr, type );  void va_end( va_list arg_ptr );  void va_start( va_list arg_ptr );   (UNIX version)  void va_start( va_list arg_ptr, prev_param );   (ANSI version)  Routine Required Header Optional Headers Compatibility  va_arg <stdio.h> and <stdarg.h> <varargs.h>1 ANSI, Win 95, Win NT  va_end <stdio.h> and <stdarg.h> <varargs.h>1 ANSI, Win 95, Win NT  va_start <stdio.h> and <stdarg.h> <varargs.h>1 ANSI, Win 95, Win NT    1 Required for UNIX V compatibility.  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  va_arg returns the current argument; va_start and va_end do not return values.  Parameters  type  Type of argument to be retrieved  arg_ptr  Pointer to list of arguments  prev_param  Parameter preceding first optional argument (ANSI only)  Remarks  The va_arg, va_end, and va_start macros provide a portable way to access the arguments to a function when the function takes a variable number of arguments. Two versions of the macros are available: The macros defined in STDARG.H conform to the ANSI C standard, and the macros defined in VARARGS.H are compatible with the UNIX System V definition. The macros are:  va_alist  Name of parameter to called function (UNIX version only)  va_arg  Macro to retrieve current argument  va_dcl  Declaration of va_alist (UNIX version only)  va_end  Macro to reset arg_ptr  va_list  typedef for pointer to list of arguments defined in STDIO.H  va_start  Macro to set arg_ptr to beginning of list of optional arguments (UNIX version only)  Both versions of the macros assume that the function takes a fixed number of required arguments, followed by a variable number of optional arguments. The required arguments are declared as ordinary parameters to the function and can be accessed through the parameter names. The optional arguments are accessed through the macros in STDARG.H or VARARGS.H, which set a pointer to the first optional argument in the argument list, retrieve arguments from the list, and reset the pointer when argument processing is completed.  The ANSI C standard macros, defined in STDARG.H, are used as follows:   All required arguments to the function are declared as parameters in the usual way. va_dcl is not used with the STDARG.H macros.   va_start sets arg_ptr to the first optional argument in the list of arguments passed to the function. The argument arg_ptr must have va_list type. The argument prev_param is the name of the required parameter immediately preceding the first optional argument in the argument list. If prev_param is declared with the register storage class, the macro’s behavior is undefined. va_start must be used before va_arg is used for the first time.   va_arg retrieves a value of type from the location given by arg_ptr and increments arg_ptr to point to the next argument in the list, using the size of type to determine where the next argument starts. va_arg can be used any number of times within the function to retrieve arguments from the list.   After all arguments have been retrieved, va_end resets the pointer to NULL.  The UNIX System V macros, defined in VARARGS.H, operate somewhat differently:   Any required arguments to the function can be declared as parameters in the usual way.   The last (or only) parameter to the function represents the list of optional arguments. This parameter must be named va_alist (not to be confused with va_list, which is defined as the type of va_alist).   va_dcl appears after the function definition and before the opening left brace of the function. This macro is defined as a complete declaration of the va_alist parameter, including the terminating semicolon; therefore, no semicolon should follow va_dcl.   Within the function, va_start sets arg_ptr to the beginning of the list of optional arguments passed to the function. va_start must be used before va_arg is used for the first time. The argument arg_ptr must have va_list type.   va_arg retrieves a value of type from the location given by arg_ptr and increments arg_ptr to point to the next argument in the list, using the size of type to determine where the next argument starts. va_arg can be used any number of times within the function to retrieve the arguments from the list.   After all arguments have been retrieved, va_end resets the pointer to NULL.  Example  /* VA.C: The program below illustrates passing a variable  * number of arguments using the following macros:  *      va_start            va_arg              va_end  *      va_list             va_dcl (UNIX only)  */  #include <stdio.h> #define ANSI            /* Comment out for UNIX version     */ #ifdef ANSI             /* ANSI compatible version          */ #include <stdarg.h> int average( int first, ... ); #else                   /* UNIX compatible version          */ #include <varargs.h> int average( va_list ); #endif  void main( void ) {    /* Call with 3 integers (-1 is used as terminator). */    printf( "Average is: %d\n", average( 2, 3, 4, -1 ) );     /* Call with 4 integers. */    printf( "Average is: %d\n", average( 5, 7, 9, 11, -1 ) );     /* Call with just -1 terminator. */    printf( "Average is: %d\n", average( -1 ) ); }  /* Returns the average of a variable list of integers. */ #ifdef ANSI             /* ANSI compatible version    */ int average( int first, ... ) {    int count = 0, sum = 0, i = first;    va_list marker;     va_start( marker, first );     /* Initialize variable arguments. */    while( i != -1 )    {       sum += i;       count++;       i = va_arg( marker, int);    }    va_end( marker );              /* Reset variable arguments.      */    return( sum ? (sum / count) : 0 ); } #else       /* UNIX compatible version must use old-style definition.  */ int average( va_alist ) va_dcl {    int i, count, sum;    va_list marker;     va_start( marker );            /* Initialize variable arguments. */    for( sum = count = 0; (i = va_arg( marker, int)) != -1; count++ )       sum += i;    va_end( marker );              /* Reset variable arguments.      */    return( sum ? (sum / count) : 0 ); } #endif   Output  Average is: 3 Average is: 8 Average is: 0   Argument Access Routines  See Also   vfprintf

更正以下 //2)初始化va_list指针，（不定参数指针，让他指向最后一个确定参数的下一个参数）   va_start(vlist,c);其实就是让 vlist指向堆栈中，c后面一个参数。

void va_test(char* a, char* b, char* c, …){ //1) //定义va_list指针（不定参数列表指针） va_list vlist; //2)//初始化va_list指针，（不定参数指针，让他指向最后一个确定参数）  va_start(vlist,c); //3)//读取后面的各个函数参数，格式为，type x =  va_arg(vlist,type) ; 例如： int x =        va_arg(vlist，int);  //4) 结束使用不定参数函数参数      va_end(vlist); } PS： 这4个步骤，缺一不可。。。。哦，va_end();也许作用不大。


Question: c语言求解

LZ是在考试吗？

我刚学C的时候貌似写过类似的作页

貌似这C语言上过几节课的都可以写了，LZ还是用心写写试试吧

LZ的语气不对，学习的态度也不对

这个是最基本的了，还用来问？自己不去动动脑子？

#include <stdio.h> #include <stdlib.h> #include <malloc.h> #include <string.h>  typedef struct message{     int number;     char name[100];     int ordinary;     int midterm;     int endterm; }Message;  typedef struct link{     Message *stu;     struct Link *next; }Link;  int main() {     Link *head = (Link*)malloc(sizeof(Link)), *tail = head;     head->stu = NULL;     head->next = NULL;     Message *tmp;     int n = 0;     printf("input students' number:");     scanf("%d", & n);     int m = n;     printf("circle input %d students message\n", n);     while(n--){         tmp = (Message*)malloc(sizeof(Message));         printf("input student's message\n");         scanf("%d %s %d %d %d", &(tmp->number), tmp->name, &(tmp->ordinary), &(tmp->midterm), &(tmp->endterm));         tail->next = (Link*)malloc(sizeof(Link));         tail = tail->next;         tail->stu = tmp;     }      int total[10] = {0};     tail = head;     while(tail->next != NULL){         tail = tail->next;         int score = tail->stu->ordinary * 0.2 + tail->stu->midterm * 0.3 + tail->stu->endterm * 0.5;         printf("ID:%d NAME:%s SCORE:%d\n", tail->stu->number, tail->stu->name, score);         total[score / 10 - 1]++;     } 	int i = 0;     for(i = 0; i < 10 ; i++){     	if(total[i] == 0) continue;       printf("%2d-%3d: %d/%d\n", i * 10, (i + 1) * 10, total[i], m); 	}     return 0; }   不好意思， 这个才是

#include <stdio.h> #include <stdlib.h> #include <malloc.h> #include <string.h>  struct Message{     int number;     char name[100];     int ordinary;     int midterm;     int endterm; };  struct link{     Message *stu;     link *next; };  int main() {     link *head = (link*)malloc(sizeof(link)), *tail = head;     head->stu = NULL;     head->next = NULL;     Message *tmp;     int n = 0;     printf("input students' number:");     scanf("%d", & n);     int m = n;     printf("circle input %d students message\n", n);     while(n--){         tmp = (Message*)malloc(sizeof(Message));         printf("input student's message\n");         scanf("%d %s %d %d %d", &(tmp->number), tmp->name, &(tmp->ordinary), &(tmp->midterm), &(tmp->endterm));         tail->next = (link*)malloc(sizeof(link));         tail = tail->next;         tail->stu = tmp;     }      int total[10] = 0;     tail = head;     while(tail->next != NULL){         tail = tail->next;         int score = tmp->ordinary * 0.2 + tmp->midterm * 0.3 + tmp->endterm * 0.5;         printf("ID:%d NAME:%s SCORE:%d\n", tail->number, tail->name, score);         total[score / 10 - 1]++;     }      for(int i = 0; i < 10 ; i++){         printf("%d-%d: %f\n", i * 10, (i + 1) * 10, total[i] / m);     }     return 0; }


Question: SyncWait函数

参考下面：用double类型是因为32位int类型不够表示时间跨度从1970.1.1到比如2050.1.1经过的秒数。 difftime Finds the difference between two times.  double difftime( time_t timer1, time_t timer0 );  Routine Required Header Compatibility  difftime <time.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  difftime returns the elapsed time in seconds, from timer0 to timer1. The value returned is a double-precision floating-point number.  Parameters  timer1  Ending time  timer0  Beginning time  Remarks  The difftime function computes the difference between the two supplied time values timer0 and timer1.  Example   /* DIFFTIME.C: This program calculates the amount of time  * needed to do a floating-point multiply 10 million times.  */  #include <stdio.h> #include <stdlib.h> #include <time.h>  void main( void ) {    time_t   start, finish;    long loop;    double   result, elapsed_time;     printf( "Multiplying 2 floating point numbers 10 million times...\n" );        time( &start );    for( loop = 0; loop < 10000000; loop++ )       result = 3.63 * 5.27;     time( &finish );     elapsed_time = difftime( finish, start );    printf( "\nProgram takes %6.0f seconds.\n", elapsed_time ); }   Output  Multiplying 2 floats 10 million times...  Program takes      2 seconds.   Floating-Point Support Routines |  Time Management Routines  See Also   time


Question: 数据结构字符串操作，求指导一下

你的第一个问题  我测试了一下  你的 SString S1,S2;中的S1，S2中的ch没有初始化，应该先memset(S->ch,0,MAX);或者bzero(S->ch,MAX);程序逻辑基本没错误； 第二个问题 我随便写了写 你自己看看 需要改进的地方 ，自己改改； #include<stdio.h> #include<string.h> int search(char *str1,char *str2,int m) { 		int i,j; 		int len1 = strlen(str1); 		int len2 = strlen(str2); 		char *p1,*p2; 		p1 = str1; 		p2 = str2; 		if(len1<len2) { 				strcat(str2,p1+m); 				for(i=0;str2[i]!='\0';i++)  						str1[i+m] = str2[i]; 				str1[i+m] = '\0'; 		} 		for(i = 0;i < (len1-len2);i++) { 				if(strncmp(p2,p1+i,len2)==0){ 						//	puts(p1+i); 						return i; 				} 		} 		strcat(str2,p1+m); 		for(i=0;str2[i]!='\0';i++)  				str1[i+m] = str2[i]; 		str1[i+m] = '\0'; 		return -1; }  int main() { 		char a[128] = {}; 		char b[128] = {}; 		int n=-1;  		scanf("%s",a); 		getchar(); 		puts(a); 		scanf("%s",b); 		getchar(); 		puts(b); 		n =	search(a,b,5); 		printf("n = %d",n); 		puts(a); 		return 0; }


Question: 二级void指针呢怎么消除编译警告和返回正确值呢？

#include <stdio.h> int p2(void **j) {    return **(int **)j; } int main() {     int *i, **j;     int n = 99;     i = &n;     j = &i;     printf("====== %d =====\n", p2((void **)j));     return 0; } //====== 99 ===== //

printf("====== %d =====\n", p2((void**)（void*）j)); 这样做试试

怎么修改才能避免警告呢？

强制转换，出错自己负责； 编译器已经尽职尽责了，是你抛开了编译器的检查，自己要处理的。 有了问题，不要再找编译器的麻烦了。


Question: 如何消除void *这样的警告和返回预期值

return *((int *)i);  引用 楼主 u013354393 的回复:#include <stdio.h>  int p(void *i) {   return (int *)i; }  int main() {   int *i;   int n = 99;   i = &n;   printf("====== %d =====\n", p(i)); }  test2.c: In function ‘p’: test2.c:5: warning: return makes integer from pointer without a cast


Question: 屏幕画笔的实现原理

在屏幕上进行缩放和绘图的演示实用工具。 http://technet.microsoft.com/zh-cn/sysinternals/bb897434


Question: C语言图书馆管理系统

这是要输出一个正方形的界面。

好长啊，不过感觉这些东西 printf("   ※※※※※※※※※※※※※※※※※※\n  ");     printf("   ※                                ※\n  "); printf("   ※                                ※\n  "); printf("   ※         添加读者(1)            ※\n  "); printf("   ※         查询读者(2)            ※\n  ");	 printf("   ※         修改读者(3)            ※\n  "); printf("   ※         删除读者(4)            ※\n  ");	 printf("   ※         返回上一级(5)          ※\n  "); printf("   ※                                ※\n  "); printf("   ※※※※※※※※※※※※※※※※※※\n  "); 放在一个函数里就可以了，不用写那么多遍吧


Question: 新手求助o(︶︿︶)o

仅供参考#include <stdio.h> #include <string.h> char *a="abcde"; int L,i,j,k; void main() {     L=strlen(a);     for (i=1;i<=L;i++) {         for (j=0;j<=L-i;j++) {             for (k=j;k<j+i;k++) {                 printf("%c",a[k]);             }             printf("\n");         }     } }

好吧。。大牛们能不能先给个代码研究一下。。还要交作业。。

引用 4 楼 KillerGod 的回复:读文件，然后比较，合条件的就输出。 然后比较这个地方能说个详细点的算法或者步骤嘛？ 我是渣。。。。

读文件，然后比较，合条件的就输出。

能说的具体点嘛~ 我是菜鸟。。  谢谢啦。

穷举不行吗,我觉的这个问题还是比较简单的啊

忘了说了，是C语言的。。 真心求解答啊。。。想不出来了。。


Question: 【大小数相加问题】【字符数组】【求帮助哪里有错误】

仅供参考#include <stdio.h> #include <string.h> #define MAXLEN 1000 char a1[MAXLEN]; char a2[MAXLEN]; static int v1[MAXLEN]; static int v2[MAXLEN]; static int v3[MAXLEN]; int i,j,n,L,z; void main(void) {     scanf("%d",&n);     for (j=0;j<n;j++) {         scanf("%s%s",a1,a2);          L=strlen(a1);         for (i=0;i<L;i++) v1[i]=a1[L-1-i]-'0';          L=strlen(a2);         for (i=0;i<L;i++) v2[i]=a2[L-1-i]-'0';          for (i=0;i<MAXLEN;i++) v3[i]=v1[i]+v2[i];          for (i=0;i<MAXLEN;i++) {             if (v3[i]>=10) {                 v3[i+1]+=v3[i]/10;                 v3[i]=v3[i]%10;             }         }          printf("Case %d:\n", j+1);         printf("%s + %s = ", a1, a2);          z=0;         for (i=MAXLEN-1;i>=0;i--) {             if (z==0) {                 if (v3[i]!=0) {                     printf("%d",v3[i]);                     z=1;                 }             } else {                 printf("%d",v3[i]);             }         }         if (z==0) printf("0");          printf("\n");     } } //Sample Input //3 //0 0 //1 2 //112233445566778899 998877665544332211 // //Sample Output //Case 1: //0 + 0 = 0 //Case 2: //1 + 2 = 3 //Case 3: //112233445566778899 + 998877665544332211 = 1111111111111111110

经过本大师的判断，你的代码的第一行到最后一行之间的某一行或某几行必定有不可告人的错误。


Question: 动态给字符串数组赋值

比较j值，原表中是否有值？

引用 1 楼 ouyh12345 的回复:设断点，调试，看取出来的是什么我把取出来的值打印出来了，是空值哦，亲

引用 4 楼 xiaolanghh 的回复:[quote=引用 3 楼 zhuobattle 的回复:] static char CellString[10][10]; 这个每个字串才10个字符是不是太短了？  GetTableCellVal (panelHandle, PANEL_TABLE, MakePoint(j,i), &CellString[j]） //建议可以这样调用: char pStr[256] = {0}; GetTableCellVal (panelHandle, PANEL_TABLE, MakePoint(j,i), pStr）; //这里最后一个只是一个指针吧？你这样获取试试。  最后一个是个字符串数组，应该定义一个二维数组存放吧，CellString[j]表示的是第j行的一个字符串吧[/quote] 一个字符串，那么char pStr[256]就可以获取了啊，你获取的仅仅是第j行的字符串，又不是所有行的字符串

引用 2 楼 truelance 的回复:是LabWindows么? The value that this function returns depends on the cell type of the specified cell.  If the cell type is VAL_CELL_PICTURE, the function returns the bitmap stored in the cell, or zero if there is no bitmap. When you no longer need the bitmap, free it using DiscardBitmap.  If the cell type is VAL_CELL_STRING, VAL_CELL_RING, VAL_CELL_COMBO_BOX, or VAL_CELL_BUTTON, the function expects you to pass a buffer large enough to hold the corresponding string, plus the terminating NUL. Use GetTableCellValLength to obtain the length of the string.  If the cell type is VAL_CELL_NUMERIC, the function expects the data type of value to match the data type of the cell.恩，是Labwindows CVI 里的一个函数，我看了这个帮助文档，但是没弄明白为什么我定义的二维数组不能获取到table控件里的字符串值，我打印出来CellString里的值都为空值。

引用 3 楼 zhuobattle 的回复:static char CellString[10][10]; 这个每个字串才10个字符是不是太短了？  GetTableCellVal (panelHandle, PANEL_TABLE, MakePoint(j,i), &CellString[j]） //建议可以这样调用: char pStr[256] = {0}; GetTableCellVal (panelHandle, PANEL_TABLE, MakePoint(j,i), pStr）; //这里最后一个只是一个指针吧？你这样获取试试。  最后一个是个字符串数组，应该定义一个二维数组存放吧，CellString[j]表示的是第j行的一个字符串吧

设断点，调试，看取出来的是什么

引用 6 楼 zhuobattle 的回复:[quote=引用 4 楼 xiaolanghh 的回复:] [quote=引用 3 楼 zhuobattle 的回复:] static char CellString[10][10]; 这个每个字串才10个字符是不是太短了？  GetTableCellVal (panelHandle, PANEL_TABLE, MakePoint(j,i), &CellString[j]） //建议可以这样调用: char pStr[256] = {0}; GetTableCellVal (panelHandle, PANEL_TABLE, MakePoint(j,i), pStr）; //这里最后一个只是一个指针吧？你这样获取试试。  最后一个是个字符串数组，应该定义一个二维数组存放吧，CellString[j]表示的是第j行的一个字符串吧[/quote] 一个字符串，那么char pStr[256]就可以获取了啊，你获取的仅仅是第j行的字符串，又不是所有行的字符串[/quote]谢谢 问题解决了，用一个字符串重复获取能获取到值！再多问一句，如果是取所有行的字符串保存在一个二维数组中，该如何获取呢？

这个GetTableCellVal的内部实现可以看到吗？第四个参数类型是什么？


Question: 求助帖

引用 6 楼 jimmywang123 的回复:[quote=引用 5 楼 user-2 的回复:] [quote=引用 4 楼 jimmywang123 的回复:] [quote=引用 2 楼 user-2 的回复:] 调试过了吗？ 调试没错误，用的VS2013，就是出现了那个中断，不知道怎么去处理了[/quote]  调试到哪的时候出错了  指出来[/quote] [/quote]  引用 6 楼 jimmywang123 的回复:[quote=引用 5 楼 user-2 的回复:] [quote=引用 4 楼 jimmywang123 的回复:] [quote=引用 2 楼 user-2 的回复:] 调试过了吗？ 调试没错误，用的VS2013，就是出现了那个中断，不知道怎么去处理了[/quote]  调试到哪的时候出错了  指出来[/quote] [/quote] 已经解决，总之谢谢啦。

崩溃的时候在弹出的对话框按相应按钮进入调试，按Alt+7键查看Call Stack里面从上到下列出的对应从里层到外层的函数调用历史。双击某一行可将光标定位到此次调用的源代码或汇编指令处。  在每个最后不带\n的printf后面加fflush(stdout); 在每个不想受接收缓冲区旧内容影响的scanf前面加rewind(stdin); 另外请检查scanf的返回值。

引用 5 楼 user-2 的回复:[quote=引用 4 楼 jimmywang123 的回复:] [quote=引用 2 楼 user-2 的回复:] 调试过了吗？ 调试没错误，用的VS2013，就是出现了那个中断，不知道怎么去处理了[/quote]  调试到哪的时候出错了  指出来[/quote]

引用 4 楼 jimmywang123 的回复:[quote=引用 2 楼 user-2 的回复:] 调试过了吗？ 调试没错误，用的VS2013，就是出现了那个中断，不知道怎么去处理了[/quote]  调试到哪的时候出错了  指出来

引用 2 楼 user-2 的回复:调试过了吗？ 调试没错误，用的VS2013，就是出现了那个中断，不知道怎么去处理了

调试没错误，用的VS2013，就是出现了那个中断，不知道怎么去处理了

调试过了吗？

大神帮忙看看，为什么输入第一组数据之后就出现中断啊