Question: 内核对象的问题

引用 1 楼 user-4 的回复:hThread2=hThread;     //CloseHandle (hThread);                  ///////////////////////////////           WaitForSingleObject (hThread2, INFINITE);           CloseHandle (hThread2);  这种做法是错误的，关闭的HANDLE ，是不能用于等待的。 因为相关的数据结构，操作系统随时会撤销。 等待是等到那个数据结构处于有信号状态，现在这个数据结构，已经被撤销了，操作系统不再关注他了。 线程退出他也不会有信号。 只会，等到一个错误，然后线程还在运行程序就结束了。 或者一直等下去。  必须等待结束后才可以关闭句柄 hThread2=hThread;  这个赋值操作，操作系统没有记录，所有没有对该句柄相关数据结构的做任何操作。 只是复制了一个相当于野指针的句柄而已。++

CloseHandle 通常在最后使用 也就是你确定你不会再使用了才关闭

++  引用 1 楼 user-4 的回复:hThread2=hThread;     //CloseHandle (hThread);                  ///////////////////////////////           WaitForSingleObject (hThread2, INFINITE);           CloseHandle (hThread2);  这种做法是错误的，关闭的HANDLE ，是不能用于等待的。 因为相关的数据结构，操作系统随时会撤销。 等待是等到那个数据结构处于有信号状态，现在这个数据结构，已经被撤销了，操作系统不再关注他了。 线程退出他也不会有信号。 只会，等到一个错误，然后线程还在运行程序就结束了。 或者一直等下去。  必须等待结束后才可以关闭句柄 hThread2=hThread;  这个赋值操作，操作系统没有记录，所有没有对该句柄相关数据结构的做任何操作。 只是复制了一个相当于野指针的句柄而已。


Question: linux c 如何动态生成数组名

做不到 数组名 最晚也得在预编译阶段 确定  运行期生成数组名 是没可能的

贴上一个简单的实现，感谢各位大牛int main() { 	char b[10] = "bac"; 	char (*a)[10]; 	a = (char (*)[10])malloc(sizeof(char *) * 5); //	strncpy(a[0], b, sizeof(a[0])); 	strncpy(a[1], b, sizeof(a[1])); 	printf("%s\n", a[1]); 	printf("%c\n", a[1][1]);  	return 0; }

引用 12 楼 turingo 的回复:用指针是毫无疑问的，请看我在3楼的回答。太感谢你啦，确实实现了

用指针是毫无疑问的，请看我在3楼的回答。

引用 10 楼 worldy 的回复:[quote=引用 楼主 he_fa 的回复:] 请问声明数组时如何给数组名带入一个变量,达到用循环批量生成数组的目的啊?比如用一个for循环跑10圈,每圈生成一个arrayX 最终是10个数组，尽量不要用二维数组吧，因为我也不知道要生成多少个数组。。。  必须使用指针，数组是在栈中或者全局数据区中分配内存，在编译时候必须确定大小[/quote]我现在都怀疑，指针真的可以实现需求么？

引用 楼主 he_fa 的回复:请问声明数组时如何给数组名带入一个变量,达到用循环批量生成数组的目的啊?比如用一个for循环跑10圈,每圈生成一个arrayX 最终是10个数组，尽量不要用二维数组吧，因为我也不知道要生成多少个数组。。。  必须使用指针，数组是在栈中或者全局数据区中分配内存，在编译时候必须确定大小

可以试试写一个生成代码的程序gen.exe 1. gen.exe -> generated.c 2. gcc generated.c the_rest_of_your_code.c

引用 楼主 he_fa 的回复:每圈生成一个arrayX 最终是10个数组。 数组须在编译时确定大小，不能动态生成。

锯齿数组,比如 double* aa[10];

lz 是要用for 动态生成   int array_1[] int array_2[] int array_3[] ......... int array_n[] 吗？ 空间可以动态生成，名字就等高人！

引用 4 楼 thefirstz 的回复:引用 2 楼 he_fa 的回复:[quote=引用 1 楼 thefirstz 的回复:] 用指针啊，根据传入的参数进行malloc正在尝试，但还没成功。。。 把你代码精简下，发上来，给你看看[/quote] #include <stdio.h> #include <string.h> #include <stdlib.h> int main() { 	char **a; 	a = (char **)malloc(sizeof(char *) * 2); 	a[1] = (char *)malloc(sizeof(char) * 2); 	char *b = "aa"; 	 	return 0; } 想把数组的名字命名成aa，然后就不知道怎么弄了

引用 2 楼 he_fa 的回复:引用 1 楼 thefirstz 的回复:用指针啊，根据传入的参数进行malloc正在尝试，但还没成功。。。 把你代码精简下，发上来，给你看看

用动态二维数组，参考http://blog.csdn.net/zyxlinux888/article/details/8070495  引用 楼主 he_fa 的回复:请问声明数组时如何给数组名带入一个变量,达到用循环批量生成数组的目的啊?比如用一个for循环跑10圈,每圈生成一个arrayX 最终是10个数组，尽量不要用二维数组吧，因为我也不知道要生成多少个数组。。。

用指针啊，根据传入的参数进行malloc


Question: 请教关于c语言变量的声明和定义

p是整形变量，使用前需初始化，而a是整形，无须初始化

这里是定义不是申明，另外int *p那么p指向了哪里？你修改了一个未知地址的值你说可不可能会出问题?

这两个都是定义，也就是说都在内存里占用了位置。  至于a被修改不会有问题而*p修改就会有问题一说，我觉得你说得没道理。  如果a是一个关键变量，你随意改动a的值，我保证程序跑的乱七八糟的。

int a; int *p; 同样都是 a = 10; p = 46875; 一点问题都没有 安全 不同的是  a不能做 一元运算符*的操作数  p可以做 一元运算符*的操作数   如果你  随便改 a的值  然后做 * 操作 一样死  a = 0; *(int*)a;//死了

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

自动变量,和寄存器变量的定义，其实是一种声明， 他们实际在运行时，函数调用过程中定义，------确定地址，初始化。

C语言中： 1) 定义也是声明 2）声明未必是定义。  extern int a;//纯粹的声明  int a; //定义也是声明，外部变量初始化为0；  int b = 10;//声明同时初始化，定义。   int main() {     int a=10;//声明同时初始化，定义，值确定。      int b;//声明没有初始化，也是定义，局部自动变量，一旦声明就会分配内存。      register c=10;//声明同时初始化，定义，值确定。     register d;   //声明没有初始化，定义。值不确定。                      //寄存器变量，一旦声明就会分配寄存器或者内存      return 0; }

变量一段内存空间，其中可以存储某种类型的数据 指针也是变量，但其中存储某种数据类型的地址  引用 1 楼 user-11 的回复:这两个都是定义！！！  extern int a; 这才是声明  变量一段内存空间，其中可以存储某种类型的数据 指针也是变量，但其中存储某种数据类型的地址

引用 楼主 u011144614 的回复:如果我声明变量和指针 int a ; int * p ;  同样是声明没定义，如果修改*p的值就会可能产生严重后果，但是修改a的值却不会，请问这是为什么呢？  没有初始化的*p，没有指向内存中的任何一个地址，对它进行赋初值（如果不是一个变量的地址的话）就会出错。例如，*p = 5;这里5不是某个变量的地址，所以会出现lvalue和rvalue的匹配错误。那么对*p赋的值是个地址，例如，*p = 0x22b40020，这样行吗？这样也不行，0x22b40020固然有可能是内存中存在着的某个地址，但这个地址上的数值是不确定的，也许是其他程序在用的一个值，贸然这样给*p赋这个地址有可能会给*p机会修改这个数值，从而破坏其他程序所要用的数值。 而给a赋值则没问题，例如，a = 5，这是对变量进行初始化。为什么可以这样呢？因为声明了变量a，就意味着在内存中找到了一个地址，例如，0x002c0450，而以这个地址为起始的若干个（多为4个，int一般占用4个字节内存的大小）连续内存单元就用以来存储数值5了。 总之，没有初始化的*p和a的本质区别就是，*p要是想结婚就得发愁，因为单位没有给他分配房子，给他个新娘他都不知让人家住哪里。而a要是想结婚就不用发愁了，因为他刚一进单位，单位已经给他分配房子了，如果有女孩子投怀送抱他就可以随时将人家接入洞房。

因为指针是间接操作，所以很有可能改动别的数据。  引用 楼主 u011144614 的回复:如果我声明变量和指针 int a ; int * p ;  同样是声明没定义，如果修改*p的值就会可能产生严重后果，但是修改a的值却不会，请问这是为什么呢？

这两个都是定义！！！  extern int a; 这才是声明


Question: 今天coolpad笔试 线程间通信函数实现

题目 表达不清。

引用 9 楼 wanghb1989 的回复:[quote=引用 8 楼 zhxianbin 的回复:] [quote=引用 7 楼 wanghb1989 的回复:] [quote=引用 6 楼 zhxianbin 的回复:] 线程间需要通信吗?  逻辑上不能有吗？[/quote] 进程间通信，线程间同步与互斥。线程处于相同的内存空间，变量的访问和作用域有关，无需特殊手段。[/quote] 这题意思是说一个包裹函数，没别的意思 [/quote]那和 list 、queue 又有什么关系呢，这两个也需要加锁啊

没明白题目意思，是要你自己实现吗还是？？？这个跟链表、队列又有什么关系呢？

引用 8 楼 zhxianbin 的回复:[quote=引用 7 楼 wanghb1989 的回复:] [quote=引用 6 楼 zhxianbin 的回复:] 线程间需要通信吗?  逻辑上不能有吗？[/quote] 进程间通信，线程间同步与互斥。线程处于相同的内存空间，变量的访问和作用域有关，无需特殊手段。[/quote] 这题意思是说一个包裹函数，没别的意思

引用 7 楼 wanghb1989 的回复:[quote=引用 6 楼 zhxianbin 的回复:] 线程间需要通信吗?  逻辑上不能有吗？[/quote] 进程间通信，线程间同步与互斥。线程处于相同的内存空间，变量的访问和作用域有关，无需特殊手段。

引用 6 楼 zhxianbin 的回复:线程间需要通信吗?  逻辑上不能有吗？

线程间需要通信吗?

不用queue和list的话就用公共存储区呗， 配合mutex,sem信号量实现多线程对公共 数据的安全读写。 比如说在公共存储区内创建指针数组， 每个元素都是要传递的数据的地址（这些数据都通过malloc/new创建）。

我个人的理解是，要自己去实现一个队列，而不是调用库函数的。只是在队列的操作中注意用锁。

随便揪一个程序员都要掌握这种基础功噢。  关键字：队列，互斥锁，条件变量。

我认为可以用链表


Question: 一道数据结构 栈的问题

S.top=S.base=0; 这个不是清空操作！

{        S.base=new char[100];      S.top=S.base=0;   ///你给一个指针赋0作甚？ 改成  S.top=S.base;就OK了    S.stacksize=100;        }


Question: 请教一个位编码的过程

如果种类不多可以查表，实际上一个byte 不过256中组合

位操作呗，变换呗

用位运算。  引用 楼主 gzzaigcn 的回复:眼下有一个需求，发送的多个Byte需要经过编码，每个bit如0：使用101,1使用110来编码。如何快速的实现呢？而且每次发起的编码序列前面还需要有6bit的数据帧头。


Question: C语言读取jpeg2000类型图片宽和高的问题

依次查找SOC:0xFF4F  SIZ:0xFF51  在SIZ后面的数据中保存着图片的宽和高. openjpeg中的函数:opj_j2k_read_siz 其中width = XSize-XOSize height = YSize-YOSize

用libjpeg试试看。  引用 楼主 hanow 的回复:大家好，  我刚接触图片处理这方面，在认知上还很有限。最近遇到一个棘手的问题。我打算保存jpeg2000类型图片宽和高，该怎么样实现呢。。  一直在找这方面的解释和实例，也做了一些尝试， 就是通过调用openjpeg程序，读取图片的头文件，但是没成功，有点无助。。。现在正在看函数opj_read_header 在(https://code.google.com/p/openjpeg/source/browse/trunk/libopenjpeg/openjpeg.h?r=950)。  请问各位高手朋友，能不能给我个方向或者提示呀? 比如，我应该从哪些文件, 哪些函数着手...  先谢谢大家。

谢谢你的回复，  libjpeg 应该是对应处理jpeg类型的，我问的是openjpeg.


Question: 初学者一个，遇到个很纠结的问题，求指教

引用 8 楼 u012379764 的回复:引用 7 楼 zhao4zhong1 的回复:程序员的常识之一：不要将程序源代码或项目或exe放在桌面这种复杂（多半带空格和汉字且在防火墙或杀毒软件严密控制的C盘上）的目录下。我给单独放一个硬盘里了，保存的时候名称对程序没影响吧，比如我保存一个刚敲好的程序，用汉字保存的用英文，数字试试。

试试改用纯英文数字文件名

引用 5 楼 user-3 的回复:[quote=引用 4 楼 u012379764 的回复:] [quote=引用 1 楼 user-3 的回复:] 代码没有问题的！可以编译运行！ 至于你说的问题，可能是在敲代码过程中，出现的语法错误！ 中英文标点符号这些问题， 根据编译提示错误，修改一下就好了！我把C语言软件关掉重新打开再运行这个程序就能运行，但是我要是在原基础上开另外一个我保存的程序为什么还是不能运行，或者就是还是运行我第一次打开的那个程序，后打开那个没反应，这是什么原因。[/quote]  用的是什么环境？文件名保存的对不对？有没有先保存下[/quote]用的是Microsoft Visual C++,文件名保存是什么意思，不就是直接点Save就保存了么

引用 4 楼 u012379764 的回复:[quote=引用 1 楼 user-3 的回复:] 代码没有问题的！可以编译运行！ 至于你说的问题，可能是在敲代码过程中，出现的语法错误！ 中英文标点符号这些问题， 根据编译提示错误，修改一下就好了！我把C语言软件关掉重新打开再运行这个程序就能运行，但是我要是在原基础上开另外一个我保存的程序为什么还是不能运行，或者就是还是运行我第一次打开的那个程序，后打开那个没反应，这是什么原因。[/quote]  用的是什么环境？文件名保存的对不对？有没有先保存下

引用 1 楼 user-3 的回复:代码没有问题的！可以编译运行！ 至于你说的问题，可能是在敲代码过程中，出现的语法错误！ 中英文标点符号这些问题， 根据编译提示错误，修改一下就好了！我把C语言软件关掉重新打开再运行这个程序就能运行，但是我要是在原基础上开另外一个我保存的程序为什么还是不能运行，或者就是还是运行我第一次打开的那个程序，后打开那个没反应，这是什么原因。

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


Question: opencv里面的一段源码，有点看不懂，求指点！！！

引用 2 楼 williamzero1 的回复:非常感谢楼上提供的链接，但是那个库是用c#写的，我没学过啊。有点像为了啃掉一块骨头，找来另一块更大的骨头啊~~ 哈，你这个比喻不错。 不过关键是算法和公式，不是开发语言吧。

h = (vr & (g - b)) +                 (~vr & ((vg & (b - r + 2 * diff)) + ((~vg) & (r - g + 4 * diff)))); 那您可以稍微为我解释下这段代码吗？这些位操作是要做什么呢？

RGB转化到HSV的算法 max=max(R,G,B): min=min(R,G,B) V=max(R,G,B) S=(max-min)/max: ifR = max,H =(G-B)/(max-min)* 60 ifG = max,H = 120+(B-R)/(max-min)* 60 ifB = max,H = 240 +(R-G)/(max-min)* 60 ifH < 0,H = H+ 360  对照这个，代码基本是按照这个步骤。很好理解。


Question: sql怎么实现三表联合查询，查询三个表中的计算信息！！

表一需要查这些信息， 表2需要查oil_bottom的最大值，以及oil_top的最小值.  表三需要查，gun_kind为1为总和，还有就是这个id所对应的条数，以及gun字段所对应的总长。 恩，是的，显示的时候想要在一个list列表中显示出所查的这些信息

没看懂啊，三张表啊，我贴图的话，您一定能看懂啊。您有qq么

inner join 没看懂你在说什么


Question: 什么情况下需要创建线程？

例如有界面操作和数据操作，如果数据量大，处理很慢就可以用多线程，否则操作界面可能响应很慢。

当某一工作将消耗很长时间 为了不阻塞主线程 会采用线程  运行一个可执行程序就是创建一个进程

加线程防止程序死锁

一个大型程序，才需要多进程。 进程，是程序的一次运行而已，能够编写的是程序 一般程序，多线程做够了。

首先要了解线程,进程的概念。 进程，是一个可执行程序的一次运行。 线程，是一个可执行程序的一条运行路径。 一个进程，可以同时有许多线程运行。   程序可以写一些代码，开一个线程执行。 但是开进程就不是那么简单了。  只能写一个程序，编译后供其他程序调用。  不过Unix ,linux 的进程和线程的界限很模糊。 在这种操作系统中，线程只是一个轻量级的进程。  线程没有独立的内存空间，进程有自己的独立空间。 进程是操作系统分配资源的单位，线程不是，线程只是独立运行的一段代码。  程序员对线程，有更多的控制权； 一个进程里面的所有线程，代码都是程序员编写的； 线程之间如何协调工作，都是程序员可以控制的。  对进程，操作系统可以控制的更多，而程序员能够控制的很少。 进程是线程的容器。  多进程，每一个进程，都需要一份资源，多线程，可以共享这些资源。

线程比进程更容易共享资源， 更容易相互通讯。 进程更容易隔离错误，更容易横向扩展。

比如调用阻塞IO函数未返回前想同时干点其它事情的时候。

等你工作一阵,你就知道这种问题都不叫问题.

需不需要线程是由程序员来决定的，举个例子吧，对于扫描工具，你可以单线程慢慢地一条一条地扫描，只要你喜欢；你也可以使用多线程，一批一批的去扫描，节省时间。


Question: 关于 windows c编程 ，cygwin ，gcc

《Windows PE权威指南》

引用 1 楼 N_sev7 的回复:WinMain函数是Win32程序的入口函数，你说“cygwin下用gcc编译windows_c 程序，gcc怎么也可以识别winmain”那是因为cygwin是Windows模拟unix的一个平台，从事Windows嵌入式开发的一个平台，WinMain函数是Windows的入口函数，所以在cygwin下也能识别WinMain函数  入口函数是规定的，你也可以指定

1、Windows下的控制台程序是从main函数开始的； 2、Windows下的GUI程序必须从WinMain进去，这是操作系统给应用程序的入口； 3、cygwin归根结底也必须遵守Windows的约定。  引用 楼主 ysm804471920 的回复:在windows下编写c程序时，入口方法是winmain，而不是main，谁能详细点介绍些； cygwin下用gcc编译windows_c 程序，gcc怎么也可以识别winmain，然后生成exe程序； 麻烦详细些介绍。

引用 1 楼 N_sev7 的回复:WinMain函数是Win32程序的入口函数，你说“cygwin下用gcc编译windows_c 程序，gcc怎么也可以识别winmain”那是因为cygwin是Windows模拟unix的一个平台，从事Windows嵌入式开发的一个平台，WinMain函数是Windows的入口函数，所以在cygwin下也能识别WinMain函数 同意


Question: C语言函数指针数组的简单实例

引用 1 楼 user-6 的回复:不错不错，很简单的实例，很能说明问题！++

#include <stdio.h> double A[300][100]; double valuex[300]; double valuey[300]; int i; double fun00(double x,double y) {return x  +   y  ;}; double fun01(double x,double y) {return x*x+ 3*y  ;}; double fun02(double x,double y) {return x  + 2*y*x;}; //...  fun03(double x,double y) {return ...+...   ;}; //... //...  fun98(double x,double y) {return ...+...   ;}; double fun99(double x,double y) {return x/2+20*y  ;}; double (*funNN[100])(double,double)={     fun00,     fun01,     fun02, //  fun03, //  ... //  fun98,     fun99, }; int main() {     double x,y;     int f,FN;      for (i=0;i<300;i++) {         valuex[i]=(double)i;         valuey[i]=(double)i;     }     FN=3;     for (i=0;i<300;i++) {          x=valuex[i];          y=valuey[i];          for (f=0;f<FN;f++) A[i][f]=funNN[f](x,y);     }     for (i=0;i<3;i++) {         for (f=0;f<FN;f++) printf("%lg ",A[i][f]);         printf("\n");     }     return 0; } //0 0 0 //2 4 3 //4 10 10

不错 简单易学

不错不错，很简单的实例，很能说明问题！


Question: 动态内存分配算法(最简单实现)

引用 1 楼 max_min_ 的回复:void *realloc(void *ptr, size_t size); //当然这个有可能首地址发生变化的！  malloc的源码也是通过sbrk, brk 这些底层函数来的，你可以借鉴下！  直接调用内核函数不行，目前面对的是嵌入式环境，可以简单理解为 pMemStart 指向的内存内核是操作不了的。 正在学习malloc函数的实现，但最好还是能简单点。

就搞个内存池吧，如果只是分配 同一种对象的话.

动态内存分配最常用就两种基本算法: 边界标识法和伙伴系统  看《数据结构》（C语言版）严蔚敏 第8章 动态存储管理

我觉得我这个应该算是最简单的了  #ifndef __MY_MALLOC__H_ #define __MY_MALLOC__H_  /**/ void   malloc_init(); void * my_malloc(int numbytes); void   my_free(void *firstbyte); void   Printf();  /**/ struct mem_control_block{   int is_available;   int size; };  #endif   #include "my_malloc.h"  /**/ static int has_initialized = 0; static void *managed_memory_start; static void *last_valid_address; void Printf() {    printf("%p\n",last_valid_address); } void malloc_init()  {      last_valid_address = (void *)sbrk(0);     managed_memory_start = last_valid_address;    has_initialized = 1;  }   void my_free(void *firstbyte) {    struct mem_control_block *mcb;    mcb = firstbyte - sizeof(struct mem_control_block);     mcb->is_available = 1;  }  void * my_malloc(int numbytes) {    void *  current_location;    void *  memory_location;    struct  mem_control_block *current_location_mcb;     if ( !has_initialized) malloc_init();     current_location = managed_memory_start;        numbytes += sizeof(struct  mem_control_block);     while( current_location < last_valid_address)    {         current_location_mcb = (  struct  mem_control_block * )current_location;                 if(current_location_mcb->is_available && current_location_mcb->size >=numbytes)          {            current_location_mcb->is_available = 0;            memory_location = current_location + sizeof(struct  mem_control_block);            return memory_location;        }        current_location = current_location + current_location_mcb->size;    }         /**/       sbrk(numbytes);    current_location = last_valid_address;    last_valid_address += numbytes;    current_location_mcb = (  struct  mem_control_block * )current_location;    current_location_mcb->is_available = 0;    current_location_mcb->size = numbytes;    memory_location = current_location + sizeof(struct  mem_control_block);    return memory_location; }

#include <time.h> #include <stdlib.h> #include <stdio.h> typedef struct memory_block_t memory_block;  struct memory_block_t {   memory_block* next; };   memory_block* freeStroe;  void _init_() {    //puts(__FUNCTION__);    char theHeap[128 * 1024 * 1024]; //128M    memory_block* block;    freeStroe = (memory_block*)theHeap;    block = freeStroe;    while((char*)block + 128 < theHeap + 128 * 1024 * 1024)    {        block->next = (memory_block*)((char*)block + 128); //每128字节为一块 	   block = block->next;    }    block->next = 0;    }   //请求大小(0,128] void * _malloc_(unsigned int size) {   //puts(__FUNCTION__);   if(0 < size && size <= 128)   {      if(freeStroe) 	 { 	     void * ret = freeStroe; 		 freeStroe = freeStroe->next; 		 return ret; 	 }   }   return  0; } //p须是_malloc_返回的 void  _free_(void* p) {   //puts(__FUNCTION__);   if(p)   {     ((memory_block*)p)->next = freeStroe; 	freeStroe = ((memory_block*)p);   } }  void* tmp[1024]; int main() {    int i;    srand((unsigned int)time(NULL));    _init_();    for(i = 0; i < 1024; ++i)    {      tmp[i] =  _malloc_(rand() + 1);    }        for(i = 0; i < 1024; ++i)    {      _free_(tmp[i]);    } }   这个应该足够简陋了。

stack allocator算是最简单的了。

参考Linux源代码中malloc和free的源代码。


Question: （求指教）关于类型转换

i=1e10不截断，i=(int)1e10截断呢？  因为类型不同，所以要转换 也不过是取最大可表示整数，和截断取整两种方式而已。  各有各的道理  截断取整，数据没有改变，只是因为，数据长度不够，表示不了，多余的丢失了。  取最大可表示整数，因为数据太大，取最大可表示整数，表示数据比较大，这在有些时候也是很方便的。 至少不会把正整数，变成负整数。  实际如何操作，看编译器，和标准。  i=1e10不截断，i=(int)1e10？？ 你的编译器比较另类吧； 这都是类型转换，应该一致才对。

引用 8 楼 zhao4zhong1 的回复:抛开编译器，对 int i=1e10; 使用以下三种方法： ①给i赋值int类型所能表达的最大整数 ②给i赋值为1e10在内存中对应的字节 ③编译提示错误 我个人认为各有各的道理。 自顶！

整型数据之间的转换，不过是扩展（有符号符号扩展，无符号0扩展），和截断两种方式。 浮点数和整型之间的转换，可能与此截然不同。  PS:  1e10 这是科学计数法； C，C++ 似乎只有浮点数，才这样表示； 整型数据，好像没有，这种常数表示方法。

引用 3 楼 turingo 的回复:超出范围会被截断，相当于0x7fffffff  [quote=引用 楼主 istudy2012 的回复:] 在学《深入理解计算机系统》时遇到的 对于如下代码： #include<stdio.h> main() {      int i=1e10;      printf("%d\n",i); } 结果是TMIN,而把它改为i=(int)1e10时，结果却是1410065408. 请问这是为什么？[/quote]++

引用 6 楼 zhao4zhong1 的回复:可以换至少三家不同公司和两种不同硬件平台下的C编译器试试。 如果没有这样的条件呢，那又该怎么分析

可以换至少三家不同公司和两种不同硬件平台下的C编译器试试。

引用 4 楼 zhao4zhong1 的回复:由具体编译器决定。  不要写连自己也预测不了结果的代码！  为什么是编译器呢？ 1e10 已经超过了int能表示的最大整数啊，从理论上是可以分析的啊。不是循环来的吗？ 2147483648*a+b,a,b均为正整数 整型值在32位的操作系统的范围就是-2147483648~2147483647啊，i是一个通过强制转换来的整型，所以i的值就在这个范围内啊。

由具体编译器决定。  不要写连自己也预测不了结果的代码！

超出范围会被截断，相当于0x7fffffff  引用 楼主 istudy2012 的回复:在学《深入理解计算机系统》时遇到的 对于如下代码： #include<stdio.h> main() {      int i=1e10;      printf("%d\n",i); } 结果是TMIN,而把它改为i=(int)1e10时，结果却是1410065408. 请问这是为什么？

超过int的最大范围了

就是超过一个int型数据能表示的最大范围了，1e10-2147483648*4就这结果了。

1e10 = 0x2540BE400  截断后 = 0x540BE400=1410065408  这个编译器 1e10不超过最长整型数据的表示范围,不过这是double 类型的浮点数。  可精确表示 - 2^54..+2^54 之间的整数 void print_int() {     int ill =(int)(long long )1e10;     printf ("%d\n",ill); //VC6:（long long 用 LONGLONG 替换）1410065408，VC10 1410065408,mingw ：1410065408     int i =(int)1e10;     printf ("%d\n",i);//VC6: 1410065408,VC10 ：1410065408,mingw： 2147483647 }  这种浮点数和整型数之间的转换， 由于可表示范围不同，超过int的表示范围，不同编译器采取了不同的方法。 VC6，VC10采取截断方式，mingw 则取最大整数。  这是和实现相关的，不要写这种依赖编译实现的代码，除非想追随新标准。 PS： 1e10 是浮点常数，不是整型常数。  10000000000，才是整型常数。 而且这个数超出int的表示范围了，需要用 long long int 来表示。


Question: 贪心。。。。

今天有考虑了一下，觉得还是没有必要排序，贪心法也许会用。   #include<stdio.h>  #define N 9 int doaGroup(FILE *fpin,FILE *fpout) //处理一组数据 V,a[1]..a[9] 共两行。 {     int V ;     // V  这是题目给的，似乎也应该这样命名     int a[N+1]; // ai 这也是题目给 a1...a9: Paints count for number i = 1..9     int i,j;      // i 和  ai 对应的 i; Tom heard that Mary doesn’t like zero 所以只有1..9     int minpaints,minpos; //写每个数字需要的paints中 最小paints 。和他的位置     int repeat,val;      //要写的数字和重复次数。     int replaceRepeat, replaceVal,remain; //替换数字的重复次数，替换的数字，没有用完的paints      if(feof(fpin))return 0; //文件结束，不再处理      fscanf(fpin, "%d", &V);      if(feof(fpin))return 0; //文件结束，不再处理      for(i = 1 ; i <= N; i++)     {         fscanf(fpin , "%d" , &a[i]);     }     for(i = 2 , minpos = 1; i<= N ; i++)     {         if(a[ i ] <= a[ minpos ]) //保险起见，用<= 保证选最大的数字         minpos =i;     }     minpaints = a[ minpos ];     val = minpos ;     repeat = V / minpaints;     remain =V % minpaints;       if(repeat < 1){         fprintf(fpout,"-1\n");     }else{         //依次用当前最大的数字替换val         //选最小的时候确保了比val 大的位置i，不会有相等的paints 了         //val         for(j = N ; remain >0 && j > val ; j-- )         {             int diff =   (a [j] - a[val]);//paints差,val的paints 是最小值，所以 diff > 0              replaceVal = j;             replaceRepeat = remain / diff;             remain %= diff;             repeat -= replaceRepeat ;             while(replaceRepeat--)                 fprintf(fpout,"%d",replaceVal);             //if(repeat == 0 )break;         }         while(repeat--)            fprintf(fpout,"%d",val);     }       return 1; }  int main() {     FILE *fpin,*fpout;     char infile[80]="in.txt";     char outfile[80]="out.txt";     if(NULL==(fpin = fopen(infile,"rt"))){         printf("Error !Cannot open %s for read\n",infile);         return -1;     }     if(NULL == ( fpout = fopen(outfile,"wt"))){         printf("Error !Cannot open %s for write\n");         fclose(fpin);         return -2;     }     while( doaGroup(fpin , fpout))         fprintf(fpout,"\n");      fclose(fpout);     fclose(fpin);      return 0; }  测试了一下，3组数据都正确。  int V，      0 ~ 10^6 没问题 int a[N+1];  1 ~  10^5 没问题

难道输出 21 这样的话，排序确实是必要的。 不过  ai 的最大值是10^5 V 的最大值是10^6 h[30000]; 似乎不够呀  假设 需要写 10^6 个数字你H似乎不够。  我觉得 增加一个数组表示每个数重复次数就够了 先取需要paints的 最小值，求重复次数 再取次小值，并且序号比前一大的，求可以替换多少。 序号不大就不替换。  最多替换9次就可以了。 然后，按照重复次数，写数据就可以了。 这确实就是贪心法了。  貌似sort不是稳定排序。 就是说相同的数据可能会颠倒顺序。 你看是否这个原因！

引用 11 楼 lm_whales 的回复: //val = minpos ;  //repeat = val / minpaints;  //应为 val = minpos ;  repeat = V / minpaints;  ///////////////////  //while(doaGroup(fpin,fpout)); //应为  while(doaGroup(fpin,fpout))        printf("\n"); //成功输出换行 //如果最后一批数据，不换行，先测试一下即可；     [quote=引用 10 楼 lm_whales 的回复:]  #include<stdio.h>  #define N 9 int doaGroup(FILE *fpin,FILE *fpout) //处理一组数据 V,a[1]..a[9] 共两行。 { int V ;     // V  这是题目给的，似乎也应该这样命名      int a[N+1]; // ai 这也是题目给 a1...a9: Paints count for number i = 1..9   int i;      // i 和  ai 对应的 i; Tom heard that Mary doesn’t like zero 所以只有1..9 int minpaints,minpos; //写每个数字需要的paints中 最小paints 。和他的位置 int repeat,val;       //要写的数字和重复次数。 if(feof(fp))return 0; fscanf(fpin, "%d", &V); if(feof(fpin))return 0; for(i = 1 ; i <= N; i++) {     fscanf(fpin , "%d" , &a[i]); } for(i = 2 , minpos = 1; i<= N ; i++) {    if(a[ i ]<= a[ minpos ]) //保险起见，用<= 保证选最大的数字         minpos =i; } minpaints = a[ minpos ]; val = minpos ; repeat = V / minpaints; if(repeat < 1 ){printf(fpout,"-1\n");} else{    for(i=0;i<repeat;i++)        printf(fpout,"%d",val);}  return 1; }  int main() { FILE *fpin,*fpout; char infile[80]="in.txt"; char outfile[80]="out.txt"; if(NULL)==(fpin = fopen(infile,"rt"))){ printf("Error !Cannot open %s for read\n",infile);  return -1; } if(NULL)==(fpout = fopen(outfile,"rt"))){ printf("Error !Cannot open %s for write\n"); fclose(fpin); return -2; }  while( doaGroup(fpin , fpout))    printf("\n");  fclose(fpout); fclose(fpin);  return 0; } 我的理解是，Tom 用所拥有的paints 写用同一数字组成的最大的数 这样，就和 这个数字是哪一个无关了，只和重复次数有关了。 3位数总比2位数大，求做小值的时候，又选了paints的最小值中数字最大的数。  如果我的理解是对的，似乎这么处理就行了，不知道你排序做什么？[/quote] 5 2 3 9 9 9 9 9 9 9 这个输出结果你觉得应该是什么。

是否需要在没用到的paints处理一下，把剩下的那些paints处理掉，让他比同一数字重复要大？？？？

//val = minpos ;  //repeat = val / minpaints;  //应为 val = minpos ;  repeat = V / minpaints;  ///////////////////  //while(doaGroup(fpin,fpout)); //应为  while(doaGroup(fpin,fpout))        printf("\n"); //成功输出换行 //如果最后一批数据，不换行，先测试一下即可；  引用 10 楼 lm_whales 的回复: #include<stdio.h>  #define N 9 int doaGroup(FILE *fpin,FILE *fpout) //处理一组数据 V,a[1]..a[9] 共两行。 { int V ;     // V  这是题目给的，似乎也应该这样命名      int a[N+1]; // ai 这也是题目给 a1...a9: Paints count for number i = 1..9   int i;      // i 和  ai 对应的 i; Tom heard that Mary doesn’t like zero 所以只有1..9 int minpaints,minpos; //写每个数字需要的paints中 最小paints 。和他的位置 int repeat,val;       //要写的数字和重复次数。 if(feof(fp))return 0; fscanf(fpin, "%d", &V); if(feof(fpin))return 0; for(i = 1 ; i <= N; i++) {     fscanf(fpin , "%d" , &a[i]); } for(i = 2 , minpos = 1; i<= N ; i++) {    if(a[ i ]<= a[ minpos ]) //保险起见，用<= 保证选最大的数字         minpos =i; } minpaints = a[ minpos ]; val = minpos ; repeat = V / minpaints; if(repeat < 1 ){printf(fpout,"-1\n");} else{    for(i=0;i<repeat;i++)        printf(fpout,"%d",val);}  return 1; }  int main() { FILE *fpin,*fpout; char infile[80]="in.txt"; char outfile[80]="out.txt"; if(NULL)==(fpin = fopen(infile,"rt"))){ printf("Error !Cannot open %s for read\n",infile);  return -1; } if(NULL)==(fpout = fopen(outfile,"rt"))){ printf("Error !Cannot open %s for write\n"); fclose(fpin); return -2; }  while( doaGroup(fpin , fpout))    printf("\n");  fclose(fpout); fclose(fpin);  return 0; } 我的理解是，Tom 用所拥有的paints 写用同一数字组成的最大的数 这样，就和 这个数字是哪一个无关了，只和重复次数有关了。 3位数总比2位数大，求做小值的时候，又选了paints的最小值中数字最大的数。  如果我的理解是对的，似乎这么处理就行了，不知道你排序做什么？

#include<stdio.h>  #define N 9 int doaGroup(FILE *fpin,FILE *fpout){ int V ; int a[N+1]; int i; int minpaints,minpos; int repeat,val; if(feof(fp))return 0; fscanf(fpin, "%d", &V); if(feof(fpin))return 0; for(i = 1 ; i <= N; i++) {     fscanf(fpin , "%d" , &a[i]); } for(i = 2 , minpos = 1; i<= N ; i++) {    if(a[ i ]<a[ minpos ])         minpos =i; } minpaints = a[ minpos ]; val = minpos ; repeat = val / minpaints; if(repeat < 1 ){printf(fpout,"-1\n");} else{    for(i=0;i<repeat;i++)        printf(fpout,"%d",val);}  return 1; }  int main() { FILE *fpin,*fpout; char infile[80]="in.txt"; char outfile[80]="out.txt"; if(NULL)==(fpin = fopen(infile,"rt"))){ printf("Error !Cannot open %s for read\n",infile);  return -1; } if(NULL)==(fpout = fopen(outfile,"rt"))){ printf("Error !Cannot open %s for write\n"); fclose(fpin); return -2; }  while(doaGroup(fpin,fpout));  fclose(fpout); fclose(fpin);  return 0; } 如果我的理解是对的，似乎这么处理就行了，不知道你排序做什么？

引用 8 楼 lm_whales 的回复:这个题目要做的事情似乎如下： 1）找出a[i]的最小值和最小值所在的位置i 2）找出要写的数：      最小值的位置i，就是要写的数 3）找出要写几个数：      n = V/最小值， 就是写的个数  如果个数 n <1 输出-1  原因a[i] 是写某个数需要的Paint 的数目 V是拥有 的 Paint 的数目  这个题目似乎不需要贪心法，也许是我的理解有错误？应该这样、我感觉我的程序思路没错啊。测试数据也没有，就是AC不过。

引用 6 楼 cfjtaishan 的回复:引用 5 楼 lavendermaple 的回复:[quote=引用 4 楼 cfjtaishan 的回复:] 我在linux下编译和测试都没有问题哦！！但是我在那个上面AC不过。。。估计特殊数据有错误。我也找不出来。所以来这问问。 你是在windows下编译的吗，我不确定在windows下编译会是什么结果？！[/quote]我这是ACM ，应该和系统没问题。估计哪里思维搞错了。代码错误。

引用 5 楼 lavendermaple 的回复:引用 4 楼 cfjtaishan 的回复:我在linux下编译和测试都没有问题哦！！但是我在那个上面AC不过。。。估计特殊数据有错误。我也找不出来。所以来这问问。 你是在windows下编译的吗，我不确定在windows下编译会是什么结果？！

我在linux下编译和测试都没有问题哦！！

引用 2 楼 yulitingfeng 的回复:我这编译测试没问题。。。 测试结果： 5 5 4 3 2 1 2 3 4 5 //输入 55555 //输出 2 9 11 1 12 5 8 9 10 6 //输入 33 //输出程序有错误。不知道哪错了。答案错误。；

坐等回答。。。。


Question: 用多长时间能够熟练掌握c语言？

引用 42 楼 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语言高手，是不是打好基础后，开始转到linux平台学C了？

引用 40 楼 u012207185 的回复:[quote=引用 39 楼 u012071720 的回复:] 我只说一下个人经验，刚开始学可以不看那书，毕竟那个太厚了，刚学最起码要掌握最基本的语法，如果你一点语言基础都没有，建议先看谭浩强的C语言书，确实挺好，学校里就用这教材。等基本的语法掌握了再看你的那个。。 那本书写的细，内容也很丰富，我学的很激动。要是我学谭浩强的，我想不会那么激动！[/quote] 因人而宜了，你要是已经有编程语言基础了，反正语言都是相通的，你可以看详细的

能回答CSDN上相应模块一半问题就可以了

引用 19 楼 zhao4zhong1 的回复:先下载Win-TC，然后参考C:\Win-TC\tcstudy.chm和C:\Win-TC\wintchlp.chm 引用 19 楼 zhao4zhong1 的回复:先下载Win-TC，然后参考C:\Win-TC\tcstudy.chm和C:\Win-TC\wintchlp.chm 赵老师，学些书本上的知识，能把c语言练熟吗？

quote=引用 19 楼 zhao4zhong1 的回复:] 先下载Win-TC，然后参考C:\Win-TC\tcstudy.chm和C:\Win-TC\wintchlp.chm [/quote] 我用的是vs2010啊！一定要用Win-TC吗？

引用 16 楼 turingo 的回复:10年以上。  引用 楼主 u012207185 的回复:各位大虾们？我学c语言不久，在看《C primer plus》，请问我花多长时间能够熟练掌握c语言呢？不是说的精通，而是熟练掌握！我没有在公司上班，在自学。还有大家有什么好方法吗？谢了！！！ 10年，呵呵，等我读博士再做到吧！

最少得3年吧！我感觉！

引用 39 楼 u012071720 的回复:我只说一下个人经验，刚开始学可以不看那书，毕竟那个太厚了，刚学最起码要掌握最基本的语法，如果你一点语言基础都没有，建议先看谭浩强的C语言书，确实挺好，学校里就用这教材。等基本的语法掌握了再看你的那个。。 那本书写的细，内容也很丰富，我学的很激动。要是我学谭浩强的，我想不会那么激动！

很长很长。。

语法容易掌握，要想达到你说的熟练的程度，只能多写代码。 然后到网上找那个C语言经典一百题（这个系列中，和绘图有关的可以掠过）， 如果你觉得这个一百题很简单，说明你就初级熟练了。  至于精通，也许你本科4年后也不敢说自己精通。C语言与底层的关系也很大。  不要以为单单掌握了一门语言就很牛x了。你还得学习数据结果和算法。计算机专业的专业课你都得好好学，如果你是学生的话。  最后多嘴一句，想成为C语言高手的话，早日转到linux平台学C。

引用 25 楼 zhao4zhong1 的回复:[quote=引用 21 楼 u012207185 的回复:] quote=引用 19 楼 zhao4zhong1 的回复:] 先下载Win-TC，然后参考C:\Win-TC\tcstudy.chm和C:\Win-TC\wintchlp.chm 我用的是vs2010啊！一定要用Win-TC吗？[/quote] 不是用Win-TC，是看中文版的C:\Win-TC\tcstudy.chm，里面有教程和100例。[/quote] 赵老师，你能说说怎样才能成为c语言高手吗？包括实现的步骤吗和什么阶段看什么书之类！

引用 33 楼 yulitingfeng 的回复:[quote=引用 32 楼 phommy 的回复:] 21天   楼主图错求删哈哈[/quote] 哈哈

光是语法和常用数据结构的话, 大概反复的使用一个月就能比较熟悉了.

引用 12 楼 u012207185 的回复:[quote=引用 9 楼 modyaj 的回复:] [quote=引用 7 楼 u012207185 的回复:] [quote=引用 6 楼 gewei408990643 的回复:] [quote=引用 5 楼 u012207185 的回复:] 有《The C program language》这书吗？英文版的？我怎么没找到？ 有[/quote] 学完那本书，就能熟练掌握c语言了？[/quote] 学完了 并不代表掌握 就像看小说一样 有些人看了倒背如流 有的人看了 就过了 啥都没有 掌握的怎么样  都是自己的情况[/quote] 我是以吃透那本书为原则，态度是绝对认真的。[/quote] 若是这样的话 就这门语言来说 已算是学得比较好的了

10天，如果只是语法。当然,不包含混乱比赛那种BT型的，只是正常人用的语法


Question: 6个变态的c语言hello world程序！！！

风格各不相同

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

比较下来，感觉还是第一个的代码风格比较好。

看着很厉害的样子....................

牛就一个字，

程序是给人看的，如果你非要抢机器的工作

条条大路通罗马


Question: 求解，为什么求1到100的所有质数为什么会打印出9

计算机组成原理→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语言的指针，原本看似复杂的东西就会变得非常简单！ 指针即地址。“地址又是啥？”“只能从汇编语言和计算机组成原理的角度去解释了。” 但我又不得不承认：  有那么些人喜欢或者适合用“先具体再抽象”的方法学习和理解复杂事物；  而另一些人喜欢或者适合用“先抽象再具体”的方法学习和理解复杂事物。 而我本人属前者。  这辈子不看内存地址和内存值；只画链表、指针示意图，画堆栈示意图，画各种示意图，甚至自己没画过而只看过书上的图……能从本质上理解指针、理解函数参数传递吗？本人深表怀疑！ 这辈子不种麦不收麦不将麦粒拿去磨面；只吃馒头、吃面条、吃面包、……甚至从没看过别人怎么蒸馒头，压面条，烤面包，……能从本质上理解面粉、理解面食吗？本人深表怀疑！！  提醒： “学习用汇编语言写程序” 和 “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

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

引用 11 楼 turingo 的回复:我不是已经说的很清楚了吗？如果你的sieve是char类型，而sp是int的话，那么sp每加一次就是4个字节，相当于对sieve的访问跳过了3个元素，就像sieve[0] sieve[4] sieve[8] sieve[12] ... 这样访问了。  [quote=引用 10 楼 stack009 的回复:] [quote=引用 9 楼 turingo 的回复:] 整个操作都在sp，你要改的话，sp也要改过来，否则数组的访问会不正确：      char sieve[SIZE]; /* the sieve */     char *sp; /* point to access sieve */  int是4个字节，而char是一个字节，这样中间会跳过3个元素。  [quote=引用 8 楼 stack009 的回复:] [quote=引用 5 楼 turingo 的回复:] 大师经常灌水不用理会，我在4楼帮你找到问题点了。  [quote=引用 2 楼 stack009 的回复:] [quote=引用 1 楼 zhao4zhong1 的回复:] char的取值范围-128～127  代码功能归根结底不是别人帮自己看或讲解或注释出来的；而是被自己静下心来花足够长的时间和精力亲自动手单步或设断点或对执行到某步获得的中间结果显示或写到日志文件中一步一步分析出来的。 提醒：再牛×的老师也无法代替学生自己领悟和上厕所！ 单步调试和设断点调试是程序员必须掌握的技能之一。 我调试了好久一直没找到原因，所以才论坛找一下解答的，至于CHAR的取值范围我知道比INT小，但是我还是不明白为什么它不能在给定的数组范围内找到和INT一样的质数，而且我觉得这个代码里面用的数组在一个比较小的范围内CHAR和INT应该关系不大，毕竟每一个数组元素只是一个标志位啊，至于这些注释我只是在模仿英文的写法，上面的代码我也不是照着抄写的，而是理解思想之后自己写出来再调试的，只是到最后没弄明白为什么最后还能打印出数字9来，而且我把数组类型换成CHAR之后找到的质数更少了。[/quote][/quote] 而且为什么把筛选数组改为char之后反倒不能找出更多的质数了呢？[/quote][/quote][/quote]谢谢各位的帮忙，但是谁能具体一点的回答我为什么CHAR型数组不能找到更多的质数呢，我感觉在一定的空间里面，CHAR应该比INT能找到更多的质数啊[/quote][/quote] 哇靠，对哦，这都没想出来时为什么，难怪看内存地址的时候怪怪的，看来还是自己实践的太少了啊[/quote][/quote] 理解指针sp++ 移动的意义下！移动多少个字节是和 sp的指针类型有关系的！不是简单的移动一个字节大小的！

错怪了！不好意思！  引用 12 楼 stack009 的回复:我看到了啊，只是感叹一下，不过回复和以前的连在一起了，小生愚钝了，谢谢大侠

我看到了啊，只是感叹一下，不过回复和以前的连在一起了，小生愚钝了，谢谢大侠

我不是已经说的很清楚了吗？如果你的sieve是char类型，而sp是int的话，那么sp每加一次就是4个字节，相当于对sieve的访问跳过了3个元素，就像sieve[0] sieve[4] sieve[8] sieve[12] ... 这样访问了。  引用 10 楼 stack009 的回复:[quote=引用 9 楼 turingo 的回复:] 整个操作都在sp，你要改的话，sp也要改过来，否则数组的访问会不正确：      char sieve[SIZE]; /* the sieve */     char *sp; /* point to access sieve */  int是4个字节，而char是一个字节，这样中间会跳过3个元素。  [quote=引用 8 楼 stack009 的回复:] [quote=引用 5 楼 turingo 的回复:] 大师经常灌水不用理会，我在4楼帮你找到问题点了。  [quote=引用 2 楼 stack009 的回复:] [quote=引用 1 楼 zhao4zhong1 的回复:] char的取值范围-128～127  代码功能归根结底不是别人帮自己看或讲解或注释出来的；而是被自己静下心来花足够长的时间和精力亲自动手单步或设断点或对执行到某步获得的中间结果显示或写到日志文件中一步一步分析出来的。 提醒：再牛×的老师也无法代替学生自己领悟和上厕所！ 单步调试和设断点调试是程序员必须掌握的技能之一。 我调试了好久一直没找到原因，所以才论坛找一下解答的，至于CHAR的取值范围我知道比INT小，但是我还是不明白为什么它不能在给定的数组范围内找到和INT一样的质数，而且我觉得这个代码里面用的数组在一个比较小的范围内CHAR和INT应该关系不大，毕竟每一个数组元素只是一个标志位啊，至于这些注释我只是在模仿英文的写法，上面的代码我也不是照着抄写的，而是理解思想之后自己写出来再调试的，只是到最后没弄明白为什么最后还能打印出数字9来，而且我把数组类型换成CHAR之后找到的质数更少了。[/quote][/quote] 而且为什么把筛选数组改为char之后反倒不能找出更多的质数了呢？[/quote][/quote][/quote]谢谢各位的帮忙，但是谁能具体一点的回答我为什么CHAR型数组不能找到更多的质数呢，我感觉在一定的空间里面，CHAR应该比INT能找到更多的质数啊[/quote][/quote] 哇靠，对哦，这都没想出来时为什么，难怪看内存地址的时候怪怪的，看来还是自己实践的太少了啊[/quote]

引用 9 楼 turingo 的回复:整个操作都在sp，你要改的话，sp也要改过来，否则数组的访问会不正确：      char sieve[SIZE]; /* the sieve */     char *sp; /* point to access sieve */  int是4个字节，而char是一个字节，这样中间会跳过3个元素。  [quote=引用 8 楼 stack009 的回复:] [quote=引用 5 楼 turingo 的回复:] 大师经常灌水不用理会，我在4楼帮你找到问题点了。  [quote=引用 2 楼 stack009 的回复:] [quote=引用 1 楼 zhao4zhong1 的回复:] char的取值范围-128～127  代码功能归根结底不是别人帮自己看或讲解或注释出来的；而是被自己静下心来花足够长的时间和精力亲自动手单步或设断点或对执行到某步获得的中间结果显示或写到日志文件中一步一步分析出来的。 提醒：再牛×的老师也无法代替学生自己领悟和上厕所！ 单步调试和设断点调试是程序员必须掌握的技能之一。 我调试了好久一直没找到原因，所以才论坛找一下解答的，至于CHAR的取值范围我知道比INT小，但是我还是不明白为什么它不能在给定的数组范围内找到和INT一样的质数，而且我觉得这个代码里面用的数组在一个比较小的范围内CHAR和INT应该关系不大，毕竟每一个数组元素只是一个标志位啊，至于这些注释我只是在模仿英文的写法，上面的代码我也不是照着抄写的，而是理解思想之后自己写出来再调试的，只是到最后没弄明白为什么最后还能打印出数字9来，而且我把数组类型换成CHAR之后找到的质数更少了。[/quote][/quote] 而且为什么把筛选数组改为char之后反倒不能找出更多的质数了呢？[/quote][/quote][/quote]谢谢各位的帮忙，但是谁能具体一点的回答我为什么CHAR型数组不能找到更多的质数呢，我感觉在一定的空间里面，CHAR应该比INT能找到更多的质数啊[/quote][/quote] 哇靠，对哦，这都没想出来时为什么，难怪看内存地址的时候怪怪的，看来还是自己实践的太少了啊

整个操作都在sp，你要改的话，sp也要改过来，否则数组的访问会不正确：      char sieve[SIZE]; /* the sieve */     char *sp; /* point to access sieve */  int是4个字节，而char是一个字节，这样中间会跳过3个元素。  引用 8 楼 stack009 的回复:[quote=引用 5 楼 turingo 的回复:] 大师经常灌水不用理会，我在4楼帮你找到问题点了。  [quote=引用 2 楼 stack009 的回复:] [quote=引用 1 楼 zhao4zhong1 的回复:] char的取值范围-128～127  代码功能归根结底不是别人帮自己看或讲解或注释出来的；而是被自己静下心来花足够长的时间和精力亲自动手单步或设断点或对执行到某步获得的中间结果显示或写到日志文件中一步一步分析出来的。 提醒：再牛×的老师也无法代替学生自己领悟和上厕所！ 单步调试和设断点调试是程序员必须掌握的技能之一。 我调试了好久一直没找到原因，所以才论坛找一下解答的，至于CHAR的取值范围我知道比INT小，但是我还是不明白为什么它不能在给定的数组范围内找到和INT一样的质数，而且我觉得这个代码里面用的数组在一个比较小的范围内CHAR和INT应该关系不大，毕竟每一个数组元素只是一个标志位啊，至于这些注释我只是在模仿英文的写法，上面的代码我也不是照着抄写的，而是理解思想之后自己写出来再调试的，只是到最后没弄明白为什么最后还能打印出数字9来，而且我把数组类型换成CHAR之后找到的质数更少了。[/quote][/quote] 而且为什么把筛选数组改为char之后反倒不能找出更多的质数了呢？[/quote][/quote][/quote]谢谢各位的帮忙，但是谁能具体一点的回答我为什么CHAR型数组不能找到更多的质数呢，我感觉在一定的空间里面，CHAR应该比INT能找到更多的质数啊[/quote]

引用 5 楼 turingo 的回复:大师经常灌水不用理会，我在4楼帮你找到问题点了。  [quote=引用 2 楼 stack009 的回复:] [quote=引用 1 楼 zhao4zhong1 的回复:] char的取值范围-128～127  代码功能归根结底不是别人帮自己看或讲解或注释出来的；而是被自己静下心来花足够长的时间和精力亲自动手单步或设断点或对执行到某步获得的中间结果显示或写到日志文件中一步一步分析出来的。 提醒：再牛×的老师也无法代替学生自己领悟和上厕所！ 单步调试和设断点调试是程序员必须掌握的技能之一。 我调试了好久一直没找到原因，所以才论坛找一下解答的，至于CHAR的取值范围我知道比INT小，但是我还是不明白为什么它不能在给定的数组范围内找到和INT一样的质数，而且我觉得这个代码里面用的数组在一个比较小的范围内CHAR和INT应该关系不大，毕竟每一个数组元素只是一个标志位啊，至于这些注释我只是在模仿英文的写法，上面的代码我也不是照着抄写的，而是理解思想之后自己写出来再调试的，只是到最后没弄明白为什么最后还能打印出数字9来，而且我把数组类型换成CHAR之后找到的质数更少了。[/quote][/quote] 而且为什么把筛选数组改为char之后反倒不能找出更多的质数了呢？[/quote][/quote][/quote]谢谢各位的帮忙，但是谁能具体一点的回答我为什么CHAR型数组不能找到更多的质数呢，我感觉在一定的空间里面，CHAR应该比INT能找到更多的质数啊

引用 6 楼 max_min_ 的回复:正解！好快，刚看出来！ [quote=引用 4 楼 turingo 的回复:] for(number = 3; number += 2;)/*the loop is terminated from inside*/ for循环中的分号写错地方了，应该改为 for(number = 3; ; number += 2)/*the loop is terminated from inside*/  [quote=引用 楼主 stack009 的回复:] RT，这是小弟写的代码 #include "mystd.h" #define SIZE 49  int main() {     int sieve[SIZE]; /* the sieve */     int *sp; /* point to access sieve */     int number;/* number we are comupting */     int total = 1;/* count the total number of primes */     /*     ** Set the entire sieve to true     */     for(sp = sieve; sp < &sieve[SIZE];)        *sp++ = TRUE;    /*    ** Process each number from 3 to as many    ** as the sieve holds.     */     for(number = 3; number += 2;)/*the loop is terminated from inside*/     {        /*        ** Set the point to the proper element in the sieve        ** and stop the loop if we've gone too far        */        sp = &sieve[0] + (number - 3) / 2;        if(sp > &sieve[SIZE])              break;        /*        ** Now adwance the point by multiple of the number        ** and set each subsequent entry false        */        while( sp += number,sp < &sieve[SIZE])            *sp = FALSE;     }    /*    ** Now we go through the entire sieve and print the numbers    ** corresponding to the location that remain TRUE    */    printf("2\n");    for(number = 3,sp = &sieve[0]; sp < &sieve[SIZE] ; number += 2,sp++)    {           if(*sp)           {           printf("%d\n",number);           total++;           }    }    printf("the total number of primes is %d\n",total);    system("pause");    return 0; } 而且为什么把筛选数组改为char之后反倒不能找出更多的质数了呢？[/quote][/quote]谢谢各位的帮忙，但是谁能具体一点的回答我为什么CHAR型数组不能找到更多的质数呢，我感觉在一定的空间里面，CHAR应该比INT能找到更多的质数啊

正解！好快，刚看出来！ 引用 4 楼 turingo 的回复:for(number = 3; number += 2;)/*the loop is terminated from inside*/ for循环中的分号写错地方了，应该改为 for(number = 3; ; number += 2)/*the loop is terminated from inside*/  [quote=引用 楼主 stack009 的回复:] RT，这是小弟写的代码 #include "mystd.h" #define SIZE 49  int main() {     int sieve[SIZE]; /* the sieve */     int *sp; /* point to access sieve */     int number;/* number we are comupting */     int total = 1;/* count the total number of primes */     /*     ** Set the entire sieve to true     */     for(sp = sieve; sp < &sieve[SIZE];)        *sp++ = TRUE;    /*    ** Process each number from 3 to as many    ** as the sieve holds.     */     for(number = 3; number += 2;)/*the loop is terminated from inside*/     {        /*        ** Set the point to the proper element in the sieve        ** and stop the loop if we've gone too far        */        sp = &sieve[0] + (number - 3) / 2;        if(sp > &sieve[SIZE])              break;        /*        ** Now adwance the point by multiple of the number        ** and set each subsequent entry false        */        while( sp += number,sp < &sieve[SIZE])            *sp = FALSE;     }    /*    ** Now we go through the entire sieve and print the numbers    ** corresponding to the location that remain TRUE    */    printf("2\n");    for(number = 3,sp = &sieve[0]; sp < &sieve[SIZE] ; number += 2,sp++)    {           if(*sp)           {           printf("%d\n",number);           total++;           }    }    printf("the total number of primes is %d\n",total);    system("pause");    return 0; } 而且为什么把筛选数组改为char之后反倒不能找出更多的质数了呢？[/quote]

大师经常灌水不用理会，我在4楼帮你找到问题点了。  引用 2 楼 stack009 的回复:[quote=引用 1 楼 zhao4zhong1 的回复:] char的取值范围-128～127  代码功能归根结底不是别人帮自己看或讲解或注释出来的；而是被自己静下心来花足够长的时间和精力亲自动手单步或设断点或对执行到某步获得的中间结果显示或写到日志文件中一步一步分析出来的。 提醒：再牛×的老师也无法代替学生自己领悟和上厕所！ 单步调试和设断点调试是程序员必须掌握的技能之一。 我调试了好久一直没找到原因，所以才论坛找一下解答的，至于CHAR的取值范围我知道比INT小，但是我还是不明白为什么它不能在给定的数组范围内找到和INT一样的质数，而且我觉得这个代码里面用的数组在一个比较小的范围内CHAR和INT应该关系不大，毕竟每一个数组元素只是一个标志位啊，至于这些注释我只是在模仿英文的写法，上面的代码我也不是照着抄写的，而是理解思想之后自己写出来再调试的，只是到最后没弄明白为什么最后还能打印出数字9来，而且我把数组类型换成CHAR之后找到的质数更少了。[/quote]

for(number = 3; number += 2;)/*the loop is terminated from inside*/ for循环中的分号写错地方了，应该改为 for(number = 3; ; number += 2)/*the loop is terminated from inside*/  引用 楼主 stack009 的回复:RT，这是小弟写的代码 #include "mystd.h" #define SIZE 49  int main() {     int sieve[SIZE]; /* the sieve */     int *sp; /* point to access sieve */     int number;/* number we are comupting */     int total = 1;/* count the total number of primes */     /*     ** Set the entire sieve to true     */     for(sp = sieve; sp < &sieve[SIZE];)        *sp++ = TRUE;    /*    ** Process each number from 3 to as many    ** as the sieve holds.     */     for(number = 3; number += 2;)/*the loop is terminated from inside*/     {        /*        ** Set the point to the proper element in the sieve        ** and stop the loop if we've gone too far        */        sp = &sieve[0] + (number - 3) / 2;        if(sp > &sieve[SIZE])              break;        /*        ** Now adwance the point by multiple of the number        ** and set each subsequent entry false        */        while( sp += number,sp < &sieve[SIZE])            *sp = FALSE;     }    /*    ** Now we go through the entire sieve and print the numbers    ** corresponding to the location that remain TRUE    */    printf("2\n");    for(number = 3,sp = &sieve[0]; sp < &sieve[SIZE] ; number += 2,sp++)    {           if(*sp)           {           printf("%d\n",number);           total++;           }    }    printf("the total number of primes is %d\n",total);    system("pause");    return 0; } 而且为什么把筛选数组改为char之后反倒不能找出更多的质数了呢？

引用 1 楼 zhao4zhong1 的回复:char的取值范围-128～127  代码功能归根结底不是别人帮自己看或讲解或注释出来的；而是被自己静下心来花足够长的时间和精力亲自动手单步或设断点或对执行到某步获得的中间结果显示或写到日志文件中一步一步分析出来的。 提醒：再牛×的老师也无法代替学生自己领悟和上厕所！ 单步调试和设断点调试是程序员必须掌握的技能之一。 我调试了好久一直没找到原因，所以才论坛找一下解答的，至于CHAR的取值范围我知道比INT小，但是我还是不明白为什么它不能在给定的数组范围内找到和INT一样的质数，而且我觉得这个代码里面用的数组在一个比较小的范围内CHAR和INT应该关系不大，毕竟每一个数组元素只是一个标志位啊，至于这些注释我只是在模仿英文的写法，上面的代码我也不是照着抄写的，而是理解思想之后自己写出来再调试的，只是到最后没弄明白为什么最后还能打印出数字9来，而且我把数组类型换成CHAR之后找到的质数更少了。


Question: 编的第一个小小小程序，为啥不对呢,求教

大括弧下敲代码要用回车另起一行。

#include <stdio.h> int main(void) { int a,b,c,x1,x2; printf (" Please input three int:\n"); scanf ("%d,%d,%d",&a,&b,&c); x1 = a>b?a:b; x2 = x1>c?x1:c;  printf ("%d\n"，x2); return 0; } 路过调整下，输入的代码最好有一个逗号或者空格隔开吧！！！！新手求解这个东西实现的目标

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

第一次竟然不是hello world。。。

printf ("%d\n"，x2);  这个逗号是中文的  换英文输入法输入逗号

学会看COMPILER的提示，学会debug

编程时不要打开中文输入法

printf ("%d\n"，x2);中逗号改为英文的

printf ("%d\n"，x2); 把红色部分的换成英文下的;

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

输入 1空格2空格3回车

调试一下不就知道了？

代码中不要包含中文和全角符号：  #include <stdio.h> int main(void) {int a,b,c,x1,x2; printf(" Please input three int:\n"); scanf("%d%d%d",&a,&b,&c); x1 = a>b?a:b; x2 = x1>c?x1:c;  printf("%d\n",x2); return 0; }  引用 楼主 u012370173 的回复:#include <stdio.h> int main(void) {int a,b,c,x1,x2; printf (" Please input three int:\n"); scanf ("%d%d%d",&a,&b,&c); x1 = a>b?a:b; x2 = x1>c?x1:c;  printf ("%d\n"，x2); return 0; }


Question: windows下怎样用C语言多线程连接MySQL。

引用 2 楼 user-1 的回复:[quote=引用 1 楼 user-1 的回复:] 提前初始化一个MYSQL连接池，说白了就是一个MYSQL*数组哈，记得用锁保护它，是否使用条件变量与你是否提供阻塞接口有关。  创建一个线程池，希望使用一个MYSQL*就加锁从池里取一个。  这就是MYSQL连接池了，so easy哈。  忘了说，用完要归还到MYSQL连接池里哈。[/quote] 嗯，谢谢了，虽说还不知道怎么做，但是知道大概方向了，还是很感谢你。

引用 2 楼 user-1 的回复:[quote=引用 1 楼 user-1 的回复:] 提前初始化一个MYSQL连接池，说白了就是一个MYSQL*数组哈，记得用锁保护它，是否使用条件变量与你是否提供阻塞接口有关。  创建一个线程池，希望使用一个MYSQL*就加锁从池里取一个。  这就是MYSQL连接池了，so easy哈。  忘了说，用完要归还到MYSQL连接池里哈。[/quote] 有没有一个简单的例子，给一个，因为是初学者，有好多地方不太明白，谢谢。

引用 1 楼 user-1 的回复:提前初始化一个MYSQL连接池，说白了就是一个MYSQL*数组哈，记得用锁保护它，是否使用条件变量与你是否提供阻塞接口有关。  创建一个线程池，希望使用一个MYSQL*就加锁从池里取一个。  这就是MYSQL连接池了，so easy哈。  忘了说，用完要归还到MYSQL连接池里哈。


Question: 哪个函数能够获取手柄按键的值？

先查看按下手柄会得到什么？我之前做过是得到一个字符串，用if（gets()==）

Multimedia Joystick Functions An application uses the joystick functions to query a joystick driver and to prepare an application to receive notification messages from a joystick driver.  The following functions are used with multimedia joysticks.       joyGetDevCaps   joyGetNumDevs   joyGetPos   joyGetPosEx   joyGetThreshold   joyReleaseCapture   joySetCapture   joySetThreshold

Direct Input


Question: 如何解决引用不同头文件中相同变量名的问题？

用extern，不过相同名称的变量名都变成一个了，这个可能有时候逻辑就不多了。头文件里面定义变量名就应该用名空间包围的。

怎么会在头文件中定义变量，这么业余？ 命名规范呢？  同意楼上的，这是一个本不该出现的问题。

变量不要定义在头文件中。

其中一个通过动态库，动态加载来引用好了。  同名变量，在不同头文件中重复，本来就不应该出现。  而头文件，是不会定义外部变量的，只会出现引用外部变量的声明。 所以，大概只有C++  namespace, 或者采用比较偏门的手段，才能解决。

引用 7 楼 mujiok2003 的回复:在头文件中定义变量的做法值得商榷。   在头文件中只声明变量

架构师呢，溜号了？禁止重名/近名，这个是架构师的最基本职责啊

不能改名字？ 用extern

变量命名的时候 文件名也作为一部分  就避免了

static

引用 4 楼 chenbin0522 的回复:[quote=引用 3 楼 mujiok2003 的回复:] 加名字空间。 C？也有么？[/quote]  你也可以模拟一下。         typedef struct  {    int a;   } namespaceABC;   extern namespaceABC ABC;   typedef struct  {    int a;   } namespaceEFG;   extern namespaceEFG EFG;   ABC.a = EFG.a;

在头文件中定义变量的做法值得商榷。

用不同的namespace括住？

引用 4 楼 chenbin0522 的回复:[quote=引用 3 楼 mujiok2003 的回复:] 加名字空间。 C？也有么？[/quote] 没有。

引用 3 楼 mujiok2003 的回复:加名字空间。 C？也有么？

加名字空间。

引用 1 楼 adlay 的回复:改名 额。。。没有别的方法么？

改名


Question: lcs如何打印出最长公共字串？

仅供参考//最长公共子序列字符个数 //c[i][j]保存字符串 {xi},{yj},(长度分别为i,j)的最长公共子序列的字符个数 //i=0或者是j=0 时，c[i][j]必定为零, i,j>=0 且 xi=yj, c[i][j]=c[i-1][j-1]+1 //若 i,j>0 但xi!=yj, c[i][j]=max{ c[i-1][j] , c[i][j-1] } #include <stdio.h> #include <string.h> int c[1001][1001]; void lcs(int a, int b, char x[], char y[], int c[][1001]) {     int i,j;     for(i=1;i<a;i++)         c[i][0]=0; //if b==0, set c[i][j]=0;     for(i=1;i<b;i++)         c[0][i]=0; // if a==0; set c[i][j]=0;     for(i=1;i<=a;i++) // if a!=0,b!=0 loop         for(j=1;j<=b;j++) {             if(x[i-1]==y[j-1])                 c[i][j]=c[i-1][j-1]+1;             else if (c[i-1][j]>=c[i][j-1])                 c[i][j]=c[i-1][j];             else                 c[i][j]=c[i][j-1];         } } int main() {     char x[1001],y[1001];     while ( scanf("%s%s",x,y)!=EOF ) {         int a=strlen(x);         int b=strlen(y);         memset(c,0,sizeof(c));         lcs(a,b,x,y,c);         printf("%d\n",c[a][b]);     }     return 0; }

返回所得字符串

程序完整？

在回调里加答应应该是可以的！ 当然你的回调写的有问题！ 你函数本来只有一个返回值0，但是最后else判断却是同时判断返回值的差，所以没有必要的，思路有问题！

我还以为是连续字串呢 结果是不连续的 你就用栈存起来吧 每次遇到相同的字符就压栈 压栈的时候先确定栈中没有这个字符才压入  不过最好还是改成循环来做

话说递归真的不好打印啊！


Question: 完全一样的语句运行结果却不相同，郁闷

另外如果添加一句，结果就和我想的一样了，我不知道为什么，下面程序结果是D 感觉需要对开辟的空间的地址进行一些操作，之后它就变正常了  #include <stdio.h> #include <string.h> #include <stdlib.h>  void TestD(void) { 	 	char *str = (char *) malloc(100); 	strcpy(str, "Test"); 	//添加下面这一句，结果就正常了 	printf("%s",str); 	 free(str); 	if(str != NULL) 	{ 		strcpy(str, "D"); 		printf("%s\n",str); 	} 	  	   	 }  int main(){ 	TestD(); 	return 0; }

野指针，建议楼主常备一份编程规范

引用 2 楼 turingo 的回复:对野指针进行操作结果难以预料，因为指针所指向的数据及有可能被其它代码段改写。  [quote=引用 楼主 QQ594373024 的回复:]  #include <stdio.h> #include <string.h> #include <stdlib.h>  void TestD(void) { 	 	char *str = (char *) malloc(100); 	strcpy(str, "Test"); 	 free(str);  	if(str != NULL) 	{ 		strcpy(str, "D"); 		printf("%s\n",str); 	} 	  	if(str != NULL) 	{ 		strcpy(str, "D"); 		printf("%s\n",str); 	}  	 }  int main(){ 	TestD(); 	return 0; }  第一个输出时乱码，第二个就是正常的D，我不明白其中的原因，整个程序完全出乎我的意料 的 求大牛们详细解释下，谢啦[/quote]   确实存在不确定因素，有时这样有时那样的。

引用 3 楼 coblan 的回复:楼主，你以操作野指针为乐啊？？  恩，知道原因了

引用 4 楼 max_min_ 的回复:释放之后，没有清空之前，打印它的地址看看，其实它是有地址的！ 所以肯定是可以存放字符串的，只不过你不知道它的地址何时有效何时无效而已！ 访问野指针偶尔能获取到数据，但并不能代表就可以这样做，很危险！结果可能都是不可估计的   昨天晚上太累，弄得有点神志不清，早上醒来就知道什么原因了

反汇编一目了然！

楼主，你以操作野指针为乐啊？？

对野指针进行操作结果难以预料，因为指针所指向的数据及有可能被其它代码段改写。  引用 楼主 QQ594373024 的回复: #include <stdio.h> #include <string.h> #include <stdlib.h>  void TestD(void) { 	 	char *str = (char *) malloc(100); 	strcpy(str, "Test"); 	 free(str);  	if(str != NULL) 	{ 		strcpy(str, "D"); 		printf("%s\n",str); 	} 	  	if(str != NULL) 	{ 		strcpy(str, "D"); 		printf("%s\n",str); 	}  	 }  int main(){ 	TestD(); 	return 0; }  第一个输出时乱码，第二个就是正常的D，我不明白其中的原因，整个程序完全出乎我的意料 的 求大牛们详细解释下，谢啦


Question: RC500 读写问题


Question: 能不能这样初始化一个队列？

//    pQueue = NULL;     //这样行不行? pQueue是地址的形参，你可以改变地址指向的内容，但是改变地址本身是不会对外部有影响的 而且，就像你做了如下操作，你觉得给a初始化了吗？  int a; int * pa = &a; pa = NULL;   个人觉得，你调用一下这个函数 void InitializeQueue(Queue *pQueue); 还不如直接写个构造函数呢

pQueue->front = pQueue->tail = NULL;//一般用这种方法。 //    pQueue = NULL;     //这样行不行?这样是不是也意味着pQueue->front = pQueue->tail = NULL 这样显然不行，因为 1.你在内部改的参数值，是不会传到外面的。外面的     Queue one;     InitializeQueue(&one); 后，one的地址不会是NULL 2.你即使改成引用，也是错的，因为one已经是一个对象，你把它地址设为null,是非法的

void InitializeQueue(Queue *pQueue) {    pQueue = NULL;     } 函数内修改指针要么传指针引用，要么传二级指针。

如果用pQueue = NULL; 来初始化，那么pQueue->number是不是没有初始化？

谢谢楼上，我看到书上都是用pQueue->front = pQueue->tail = NULL;pQueue->number = 0;形式初始化队列。

指针初始化为NULL没有问题，但是在用之前一般需要用malloc分配足够的空间。

上面程序中有一处写错了，	struct stack *next; 应为struct node *next;

谢谢各位，我认真体会下。


Question: 这个程序中的问题与C99标准有关系吗？

for(int i = 0; i < a; i++)             a += b;   a以步长5增长， i以步长1增长，初始时i为0，a为4，你认为这能追得上吗？ 追不上就一直到溢出为负数结束for循环。


Question: 这两个指针操作相似为什么有质的不同？

类型上q是一个数组指针，*q相当于数组名，数组名是不可以作为左值的！ p是int *的，*p就是改变p所指向内存的值！

哦，这样呀，谢谢！

*q = ar;*q表示向q指针指向的内存写入数据 但是q指向的内存只能存int类型的 明显 ar是不对的 ar是数组首地址啊  *p = ar[0];ar[0]表示已经取出数值了 而且也符合指针的类型  所以没问题


Question: C程序大赛其中的一个源代码

怎么不发出来看看呀，

漫画版的美少女，呵呵。

这是一张美女脸，是不是。。

引用 13 楼 zealoussnow 的回复:引用 1 楼 my_live_123 的回复:linux 下indent工具格式化一下，就成正规代码格式了。一切就一目了然了这个怕不好弄吧。。。 10l,我已经格式完喽

读入文件，并输出剔除部分数据后输出。

国外写代码那是兴趣，喜欢在上面倒腾，为啥我就没写代码的兴趣呢。

编译成二进制，然后排成棵女的样子... 一样的闲的蛋疼

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

程序写好后专门用脚本处理的吧？ 可以看下淘宝首页的源码。

so chaos it is！

so beautiful the pic

挺那个啥的。。。

这是什么程序，写出来是完成什么事情？

我说看一个akari能学到啥（

linux 下indent工具格式化一下，就成正规代码格式了。一切就一目了然了

看这样的代码有帮助吗？光花费在规整上的时间就占了大半吧。

还是看不懂。

That's all!   #include<stdio.h> int main(int n, char **m) { 	FILE *p, *q; 	int A, k, a, r, i; 	char *d = "P%" "d\n%d\40%d" "\n%d\n\00wb+", b[1024], y[] = 		"yuriyurarararayuruyuri*daijiken**akkari~n**" 		"/y*u*k/riin<ty(uyr)g,aur,arr[a1r2a82*y2*/u*r{uyu}riOcyurhiyua**rrar+*arayra*=" 		"yuruyurwiyuriyurara'rariayuruyuriyuriyu>rarararayuruy9uriyu3riyurar_aBrMaPrOaWy^?" 		"*]/f]`;hvroai<dp/f*i*s/<ii(f)a{tpguat<cahfaurh(+uf)a;f}vivn+tf/g*`*w/jmaa+i`ni(" 		"i+k[>+b+i>++b++>l[rb"; 	int u; 	for (i = 0; i < 101; i++) 		y[i * 2] ^= 			"~hktrvg~dmG*eoa+%squ#l2" 			":(wn\"1l))v?wM353{/Y;lgcGp`vedllwudvOK`cct~[|ju {stkjalor(stwvne\"gt\"yogYURUYURI" 			[i] ^ y[i * 2 + 1] ^ 4; 	p = (n > 1 		 && (m[1][0] - '-' 			 || m[1][1] != '\0')) ? fopen(m[1], y + 298) : stdin; 	q = (n < 3 		 || !(m[2][0] - '-' || m[2][1])) ? stdout : fopen(m[2], d + 14); 	if (!p || !q) 		return +printf("Can " "not\x20open\40%s\40" "" "for\40%sing\n", 					   m[!p ? 1 : 2], !p ? "read" : "writ"); 	for (a = k = u = 0; y[u]; u = 2 + u) { 		y[k++] = y[u]; 	} 	if ((a = fread(b, 1, 1024, p)) > 2 && b[0] == 'P' 		&& 4 == sscanf(b, d, &k, &A, &i, &r) && !(k - 6 && k - 5) 		&& r == 255) { 		u = A; 		if (n > 3) { 			u++; 			i++; 		} 		fprintf(q, d, k, u >> 1, i >> 1, r); 		u = k - 5 ? 8 : 4; 		k = 3; 	} else 		{ 		(u) = +(n + 14 > 17) ? 8 / 4 : 8 * 5 / 4; 		} 	for (r = i = 0;;) { 		u *= 6; 		u += (n > 3 ? 1 : 0); 		if (y[u] & 01) 			fputc(1 * (r), q); 		if (y[u] & 16) 			k = A; 		if (y[u] & 2) 			k--; 		if (i == a) { 			i = a = (u) * 11 & 255; 			if (1 && 0 >= (a = fread(b, 1, 1024, p)) && 				")]i>(w)-;} {/i-f-(-m--M1-0.)<{" 				[8] == 59) 				break; 			i = 0; 		} 		r = b[i++]; 		u += (+8 & *(y + u)) ? (10 - 								r ? 4 : 2) : (y[u] & 4) ? (k ? 2 : 4) : 2; 		u = y[u] - (int) '`'; 	} fclose(p); 	k = +fclose(q); 	return k - -1 + (-0x01); 	{; 		{ 		} 	} 	;; }

对了，忘了说了。我也不知能它干什么就是有点好奇，如果将来有一天有能力了，再来试一下。


Question: dijstra算法运行一直出错

引用 3 楼 my_live_123 的回复:[quote=引用 2 楼 lelieven 的回复:] [quote=引用 1 楼 my_live_123 的回复:] 严蔚敏数据结构相关算法实现，供参考    /* c7-1.h 图的数组(邻接矩阵)存储表示 */  #define INFINITY INT_MAX /* 用整型最大值代替∞ */  #define MAX_VERTEX_NUM 20 /* 最大顶点个数 */  typedef enum{DG,DN,AG,AN}GraphKind; /* {有向图,有向网,无向图,无向网} */  typedef struct  {    VRType adj; /* 顶点关系类型。对无权图，用1(是)或0(否)表示相邻否； */ 	       /* 对带权图，c则为权值类型 */    InfoType *info; /* 该弧相关信息的指针(可无) */  }ArcCell,AdjMatrix[MAX_VERTEX_NUM][MAX_VERTEX_NUM];  typedef struct  {    VertexType vexs[MAX_VERTEX_NUM]; /* 顶点向量 */    AdjMatrix arcs; /* 邻接矩阵 */    int vexnum,arcnum; /* 图的当前顶点数和弧数 */    GraphKind kind; /* 图的种类标志 */  }MGraph;     /* algo7-6.c 实现算法7.15的程序。迪杰斯特拉算法的实现 */  #include"c1.h"  #define MAX_NAME 5 /* 顶点字符串的最大长度+1 */  #define MAX_INFO 20 /* 相关信息字符串的最大长度+1 */  typedef int VRType;  typedef char InfoType;  typedef char VertexType[MAX_NAME];  #include"c7-1.h"  typedef int PathMatrix[MAX_VERTEX_NUM][MAX_VERTEX_NUM];  typedef int ShortPathTable[MAX_VERTEX_NUM];  #include"bo7-1.c"   void ShortestPath_DIJ(MGraph G,int v0,PathMatrix *P,ShortPathTable *D)  { /* 用Dijkstra算法求有向网G的v0顶点到其余顶点v的最短路径P[v]及带权长度 */    /* D[v]。若P[v][w]为TRUE,则w是从v0到v当前求得最短路径上的顶点。 */    /* final[v]为TRUE当且仅当v∈S,即已经求得从v0到v的最短路径 算法7.15 */    int v,w,i,j,min;    Status final[MAX_VERTEX_NUM];    for(v=0;v<G.vexnum;++v)    {      final[v]=FALSE;      (*D)[v]=G.arcs[v0][v].adj;      for(w=0;w<G.vexnum;++w)        (*P)[v][w]=FALSE; /* 设空路径 */      if((*D)[v]<INFINITY)      {        (*P)[v][v0]=TRUE;        (*P)[v][v]=TRUE;      }    }    (*D)[v0]=0;    final[v0]=TRUE; /* 初始化,v0顶点属于S集 */    for(i=1;i<G.vexnum;++i) /* 其余G.vexnum-1个顶点 */    { /* 开始主循环,每次求得v0到某个v顶点的最短路径,并加v到S集 */      min=INFINITY; /* 当前所知离v0顶点的最近距离 */      for(w=0;w<G.vexnum;++w)        if(!final[w]) /* w顶点在V-S中 */ 	 if((*D)[w]<min) 	 { 	   v=w; 	   min=(*D)[w]; 	 } /* w顶点离v0顶点更近 */      final[v]=TRUE; /* 离v0顶点最近的v加入S集 */      for(w=0;w<G.vexnum;++w) /* 更新当前最短路径及距离 */      {        if(!final[w]&&min<INFINITY&&G.arcs[v][w].adj<INFINITY&&(min+G.arcs[v][w].adj<(*D)[w]))        { /* 修改D[w]和P[w],w∈V-S */          (*D)[w]=min+G.arcs[v][w].adj;          for(j=0;j<G.vexnum;++j)            (*P)[w][j]=(*P)[v][j];          (*P)[w][w]=TRUE;        }      }    }  }   void main()  {    int i,j,v0=0; /* v0为源点 */    MGraph g;    PathMatrix p;    ShortPathTable d;    CreateDN(&g);    ShortestPath_DIJ(g,v0,&p,&d);    printf("最短路径数组p[i][j]如下:\n");    for(i=0;i<g.vexnum;++i)    {      for(j=0;j<g.vexnum;++j)        printf("%2d",p[i][j]);      printf("\n");    }    printf("%s到各顶点的最短路径长度为：\n",g.vexs[0]);    for(i=1;i<g.vexnum;++i)      printf("%s-%s:%d\n",g.vexs[0],g.vexs[i],d[i]);  }    这个void ShortestPath_DIJ(MGraph G,int v0,PathMatrix *P,ShortPathTable *D)  写成void ShortestPath_DIJ(MGraph G,int v0,PathMatrix P,ShortPathTable D)行不？[/quote]  不可以哦，函数对数据操作必须体现到函数之外，如果去掉*号，那么函数内部对数据操作不会体现到函数之外，这样就无意义喽！[/quote]   但是我改过之后运行的结果也没问题啊！

引用 2 楼 lelieven 的回复:[quote=引用 1 楼 my_live_123 的回复:] 严蔚敏数据结构相关算法实现，供参考    /* c7-1.h 图的数组(邻接矩阵)存储表示 */  #define INFINITY INT_MAX /* 用整型最大值代替∞ */  #define MAX_VERTEX_NUM 20 /* 最大顶点个数 */  typedef enum{DG,DN,AG,AN}GraphKind; /* {有向图,有向网,无向图,无向网} */  typedef struct  {    VRType adj; /* 顶点关系类型。对无权图，用1(是)或0(否)表示相邻否； */ 	       /* 对带权图，c则为权值类型 */    InfoType *info; /* 该弧相关信息的指针(可无) */  }ArcCell,AdjMatrix[MAX_VERTEX_NUM][MAX_VERTEX_NUM];  typedef struct  {    VertexType vexs[MAX_VERTEX_NUM]; /* 顶点向量 */    AdjMatrix arcs; /* 邻接矩阵 */    int vexnum,arcnum; /* 图的当前顶点数和弧数 */    GraphKind kind; /* 图的种类标志 */  }MGraph;     /* algo7-6.c 实现算法7.15的程序。迪杰斯特拉算法的实现 */  #include"c1.h"  #define MAX_NAME 5 /* 顶点字符串的最大长度+1 */  #define MAX_INFO 20 /* 相关信息字符串的最大长度+1 */  typedef int VRType;  typedef char InfoType;  typedef char VertexType[MAX_NAME];  #include"c7-1.h"  typedef int PathMatrix[MAX_VERTEX_NUM][MAX_VERTEX_NUM];  typedef int ShortPathTable[MAX_VERTEX_NUM];  #include"bo7-1.c"   void ShortestPath_DIJ(MGraph G,int v0,PathMatrix *P,ShortPathTable *D)  { /* 用Dijkstra算法求有向网G的v0顶点到其余顶点v的最短路径P[v]及带权长度 */    /* D[v]。若P[v][w]为TRUE,则w是从v0到v当前求得最短路径上的顶点。 */    /* final[v]为TRUE当且仅当v∈S,即已经求得从v0到v的最短路径 算法7.15 */    int v,w,i,j,min;    Status final[MAX_VERTEX_NUM];    for(v=0;v<G.vexnum;++v)    {      final[v]=FALSE;      (*D)[v]=G.arcs[v0][v].adj;      for(w=0;w<G.vexnum;++w)        (*P)[v][w]=FALSE; /* 设空路径 */      if((*D)[v]<INFINITY)      {        (*P)[v][v0]=TRUE;        (*P)[v][v]=TRUE;      }    }    (*D)[v0]=0;    final[v0]=TRUE; /* 初始化,v0顶点属于S集 */    for(i=1;i<G.vexnum;++i) /* 其余G.vexnum-1个顶点 */    { /* 开始主循环,每次求得v0到某个v顶点的最短路径,并加v到S集 */      min=INFINITY; /* 当前所知离v0顶点的最近距离 */      for(w=0;w<G.vexnum;++w)        if(!final[w]) /* w顶点在V-S中 */ 	 if((*D)[w]<min) 	 { 	   v=w; 	   min=(*D)[w]; 	 } /* w顶点离v0顶点更近 */      final[v]=TRUE; /* 离v0顶点最近的v加入S集 */      for(w=0;w<G.vexnum;++w) /* 更新当前最短路径及距离 */      {        if(!final[w]&&min<INFINITY&&G.arcs[v][w].adj<INFINITY&&(min+G.arcs[v][w].adj<(*D)[w]))        { /* 修改D[w]和P[w],w∈V-S */          (*D)[w]=min+G.arcs[v][w].adj;          for(j=0;j<G.vexnum;++j)            (*P)[w][j]=(*P)[v][j];          (*P)[w][w]=TRUE;        }      }    }  }   void main()  {    int i,j,v0=0; /* v0为源点 */    MGraph g;    PathMatrix p;    ShortPathTable d;    CreateDN(&g);    ShortestPath_DIJ(g,v0,&p,&d);    printf("最短路径数组p[i][j]如下:\n");    for(i=0;i<g.vexnum;++i)    {      for(j=0;j<g.vexnum;++j)        printf("%2d",p[i][j]);      printf("\n");    }    printf("%s到各顶点的最短路径长度为：\n",g.vexs[0]);    for(i=1;i<g.vexnum;++i)      printf("%s-%s:%d\n",g.vexs[0],g.vexs[i],d[i]);  }    这个void ShortestPath_DIJ(MGraph G,int v0,PathMatrix *P,ShortPathTable *D)  写成void ShortestPath_DIJ(MGraph G,int v0,PathMatrix P,ShortPathTable D)行不？[/quote]  不可以哦，函数对数据操作必须体现到函数之外，如果去掉*号，那么函数内部对数据操作不会体现到函数之外，这样就无意义喽！

引用 1 楼 my_live_123 的回复:严蔚敏数据结构相关算法实现，供参考    /* c7-1.h 图的数组(邻接矩阵)存储表示 */  #define INFINITY INT_MAX /* 用整型最大值代替∞ */  #define MAX_VERTEX_NUM 20 /* 最大顶点个数 */  typedef enum{DG,DN,AG,AN}GraphKind; /* {有向图,有向网,无向图,无向网} */  typedef struct  {    VRType adj; /* 顶点关系类型。对无权图，用1(是)或0(否)表示相邻否； */ 	       /* 对带权图，c则为权值类型 */    InfoType *info; /* 该弧相关信息的指针(可无) */  }ArcCell,AdjMatrix[MAX_VERTEX_NUM][MAX_VERTEX_NUM];  typedef struct  {    VertexType vexs[MAX_VERTEX_NUM]; /* 顶点向量 */    AdjMatrix arcs; /* 邻接矩阵 */    int vexnum,arcnum; /* 图的当前顶点数和弧数 */    GraphKind kind; /* 图的种类标志 */  }MGraph;     /* algo7-6.c 实现算法7.15的程序。迪杰斯特拉算法的实现 */  #include"c1.h"  #define MAX_NAME 5 /* 顶点字符串的最大长度+1 */  #define MAX_INFO 20 /* 相关信息字符串的最大长度+1 */  typedef int VRType;  typedef char InfoType;  typedef char VertexType[MAX_NAME];  #include"c7-1.h"  typedef int PathMatrix[MAX_VERTEX_NUM][MAX_VERTEX_NUM];  typedef int ShortPathTable[MAX_VERTEX_NUM];  #include"bo7-1.c"   void ShortestPath_DIJ(MGraph G,int v0,PathMatrix *P,ShortPathTable *D)  { /* 用Dijkstra算法求有向网G的v0顶点到其余顶点v的最短路径P[v]及带权长度 */    /* D[v]。若P[v][w]为TRUE,则w是从v0到v当前求得最短路径上的顶点。 */    /* final[v]为TRUE当且仅当v∈S,即已经求得从v0到v的最短路径 算法7.15 */    int v,w,i,j,min;    Status final[MAX_VERTEX_NUM];    for(v=0;v<G.vexnum;++v)    {      final[v]=FALSE;      (*D)[v]=G.arcs[v0][v].adj;      for(w=0;w<G.vexnum;++w)        (*P)[v][w]=FALSE; /* 设空路径 */      if((*D)[v]<INFINITY)      {        (*P)[v][v0]=TRUE;        (*P)[v][v]=TRUE;      }    }    (*D)[v0]=0;    final[v0]=TRUE; /* 初始化,v0顶点属于S集 */    for(i=1;i<G.vexnum;++i) /* 其余G.vexnum-1个顶点 */    { /* 开始主循环,每次求得v0到某个v顶点的最短路径,并加v到S集 */      min=INFINITY; /* 当前所知离v0顶点的最近距离 */      for(w=0;w<G.vexnum;++w)        if(!final[w]) /* w顶点在V-S中 */ 	 if((*D)[w]<min) 	 { 	   v=w; 	   min=(*D)[w]; 	 } /* w顶点离v0顶点更近 */      final[v]=TRUE; /* 离v0顶点最近的v加入S集 */      for(w=0;w<G.vexnum;++w) /* 更新当前最短路径及距离 */      {        if(!final[w]&&min<INFINITY&&G.arcs[v][w].adj<INFINITY&&(min+G.arcs[v][w].adj<(*D)[w]))        { /* 修改D[w]和P[w],w∈V-S */          (*D)[w]=min+G.arcs[v][w].adj;          for(j=0;j<G.vexnum;++j)            (*P)[w][j]=(*P)[v][j];          (*P)[w][w]=TRUE;        }      }    }  }   void main()  {    int i,j,v0=0; /* v0为源点 */    MGraph g;    PathMatrix p;    ShortPathTable d;    CreateDN(&g);    ShortestPath_DIJ(g,v0,&p,&d);    printf("最短路径数组p[i][j]如下:\n");    for(i=0;i<g.vexnum;++i)    {      for(j=0;j<g.vexnum;++j)        printf("%2d",p[i][j]);      printf("\n");    }    printf("%s到各顶点的最短路径长度为：\n",g.vexs[0]);    for(i=1;i<g.vexnum;++i)      printf("%s-%s:%d\n",g.vexs[0],g.vexs[i],d[i]);  }    这个void ShortestPath_DIJ(MGraph G,int v0,PathMatrix *P,ShortPathTable *D)  写成void ShortestPath_DIJ(MGraph G,int v0,PathMatrix P,ShortPathTable D)行不？


Question: 请问迅雷里面的网页浏览

如果你用mfc，可以用CHtmlView 。 可以直接用IWebBrowser接口，都是走的ie kernel

引用 1 楼 user-3 的回复:web迅雷？ 不是web迅雷，就是迅雷下载程序中也可以浏览网页，是怎么做的

是不是使用了webkit引擎？ 或者调用了ie内核? 不清楚，你得问迅雷

web迅雷？


Question: gdb提示：No symbol "expression" in current context.

将expression改为myexp再试试看。

引用 1 楼 user-2 的回复:没看到expression有什么问题呢 但是你的strcpy函数拷贝啥？operandString内容是什么？你又没赋值又没初始化！ 还有看看 拷贝会不会越界，每个够不够20个字节 operandString会被赋值的，这个strcpy在if里面的嘛，第一次循环不会进这个if的。  这不是重点，我关心的是gdb为什么说No symbol "expression" in current context.我打印的变量是存在的啊


Question: 打印九九乘法表，要求只能用一个变量

c语言实现打开指定网址谁会？如何实现？

引用 楼主 z542858367 的回复:c语言要求最多只能用一个变量打印出九九乘法表。 顶，不过好想笑啊

学生党，有不足的请不要喷

引用 1 楼 mujiok2003 的回复:九九乘法表是个不变的，何必用变量。  int main() { char const* const tbl = "1×1=1\n"  "1×2=2 2×2=4\n"  "1×3=3 2×3=6 3×3=9 \n"  "1×4=4 2×4=8 3×4=12 4×4=16\n"   "1×5=5 2×5=10 3×5=15 4×5=20 5×5=25\n"   "1×6=6 2×6=12 3×6=18 4×6=24 5×6=30 6×6=36\n"   "1×7=7 2×7=14 3×7=21 4×7=28 5×7=35 6×7=42 7×7=49\n"   "1×8=8 2×8=16 3×8=24 4×8=32 5×8=40 6×8=48 7×8=56 8×8=64\n"   "1×9=9 2×9=18 3×9=27 4×9=36 5×9=45 6×9=54 7×9=63 8×9=72 9×9=81"; puts(tbl);   return 0; }   顶

引用 1 楼 mujiok2003 的回复:九九乘法表是个不变的，何必用变量。  int main() { char const* const tbl = "1×1=1\n"  "1×2=2 2×2=4\n"  "1×3=3 2×3=6 3×3=9 \n"  "1×4=4 2×4=8 3×4=12 4×4=16\n"   "1×5=5 2×5=10 3×5=15 4×5=20 5×5=25\n"   "1×6=6 2×6=12 3×6=18 4×6=24 5×6=30 6×6=36\n"   "1×7=7 2×7=14 3×7=21 4×7=28 5×7=35 6×7=42 7×7=49\n"   "1×8=8 2×8=16 3×8=24 4×8=32 5×8=40 6×8=48 7×8=56 8×8=64\n"   "1×9=9 2×9=18 3×9=27 4×9=36 5×9=45 6×9=54 7×9=63 8×9=72 9×9=81"; puts(tbl);   return 0; }  必须顶这个

15楼的好强

#include <stdio.h> int main() {     for(int a=16;(a>>4)<=9;a+=16)         {             a&=0xF0;             a|=1;             for(;(a&15)<=(a>>4);a++)             {                 printf("%dx%d=%d\t",a>>4,a&15,(a>>4)*(a&15));             }         printf("\n");         }     return 0; }    虽然这问题早已经结束，但拿来练习一下位操作还是蛮不错的

引用 22 楼 jiyy7758521 的回复:#include <stdio.h> main() {     int i;//取一个变量，用变量的十位代表另一变量，注意个位每次要归1     i=0;     for(i=11;i<92;i+=10)    {        for(;i%10<=i/10;i++)        {             printf("%d*%d=%d ",i/10,i%10,(i/10)*(i%10));         }         i=i/10*10+1;         printf("\n");      }  }  #include <iostream> using namespace std; int main() {     int i;   for (i=11;i<100;i++)    {    	if (i%10==0);    	 else if (i/10>=i%10)    	      cout<<i%10<<"*"<<i/10<<"="<<i/10*(i%10)<<"   ";    	if (i%10==9)    	cout<<endl;    }    return 0; }修改了一下，也可以，感觉方法挺好的

{ int i,j; for(i=1;i<10;i++) { for(j=1;j<i+1;j++) 	    printf("%d*%d=%d\t",i,j,i*j);  }  printf("\n",i); }   }

横看成林侧成峰！学习！

std:: cout<<i;  应该是这个也不算什么死循环

引用 16 楼 max_min_ 的回复:[quote=引用 8 楼 vrace 的回复:]  #include <stdio.h> #include <stdlib.h>  int main(void) { 	int a; 	 	for (a = 0x11; a < 0xa0; a++) 	{ 		for (a = (a & 0xf0) + 1; (a & 0x0f) <= ((a & 0xf0) >> 4); a++) 		{ 			printf("%dx%d=%d\t", 				(a & 0x0f), 				(a & 0xf0) >> 4, 				((a & 0xf0) >> 4) * (a & 0x0f)); 		} 		a += 0x10; 		printf("\n"); 	} 	 	return 0; }   这个应该能满足你的要求... [/quote]   膜拜啊！

引用 208 楼 u011371360 的回复:[quote=引用 38 楼 qweiu 的回复:] [quote=引用 23 楼 jiyy7758521 的回复:] //突然想到一个更简单的 这个错的 全部打印： 1*0=0 1*1=1 1*0=0 1*1=1 1*0=0 1*1=1 1*0=0 1*1=1 1*0=0 1*1=1 1*0=0 1*1=1 1*0=0 1*1=1 1*0=0 1*1=1 1*0=0 1*1=1 1*0=0 1*1=1 1*0=0 1*1=1 1*0=0 1*1=1 1*0=0 1*1=1 1*0=0 1*1=1 1*0=0 1*1=1 1*0=0 1*1=1 1*0=0 1*1=1 1*0=0 1*1=1 1*0=0 1*1=1 1*0=0 1*1=1 1*0=0 1*1=1 1*0=0 1*1=1 1*0=0 1*1=1 1*0=0 1*1= 这样就对了嘛！[/quote]  #include <stdio.h> main() {     int i;//取一个变量，用变量的十位代表另一变量，注意个位每次要归1     i=0;     for(i=11;i<100;i++)    {        if(i%10==0||i%10>i/10)        {             printf("\n");             i=(i/10+1)*10+1;         }        printf("%d*%d=%d ",i/10,i%10,(i/10)*(i%10));      } 	printf("\n");  }

引用 38 楼 qweiu 的回复:[quote=引用 23 楼 jiyy7758521 的回复:] //突然想到一个更简单的 #include <stdio.h> main() {     int i;//取一个变量，用变量的十位代表另一变量，注意个位每次要归1     i=0;     for(i=11;i<100;i++)    {        if(i%10==0||i%10>i/10)        {             printf("\n");             i=i/10*10;         }        printf("%d*%d=%d ",i/10,i%10,(i/10)*(i%10));      }  } 这个错的 全部打印： 1*0=0 1*1=1 1*0=0 1*1=1 1*0=0 1*1=1 1*0=0 1*1=1 1*0=0 1*1=1 1*0=0 1*1=1 1*0=0 1*1=1 1*0=0 1*1=1 1*0=0 1*1=1 1*0=0 1*1=1 1*0=0 1*1=1 1*0=0 1*1=1 1*0=0 1*1=1 1*0=0 1*1=1 1*0=0 1*1=1 1*0=0 1*1=1 1*0=0 1*1=1 1*0=0 1*1=1 1*0=0 1*1=1 1*0=0 1*1=1 1*0=0 1*1=1 1*0=0 1*1=1 1*0=0 1*1=1 1*0=0 1*1=[/quote] 这样就对了嘛！

引用 8 楼 vrace 的回复: #include <stdio.h> #include <stdlib.h>  int main(void) { 	int a; 	 	for (a = 0x11; a < 0xa0; a++) 	{ 		for (a = (a & 0xf0) + 1; (a & 0x0f) <= ((a & 0xf0) >> 4); a++)     //这里的a++有啥用？？？倒数第三行的a+=0x10是不是可以放在这里 		{ 			printf("%dx%d=%d\t", 				(a & 0x0f), 				(a & 0xf0) >> 4, 				((a & 0xf0) >> 4) * (a & 0x0f)); 		} 		a += 0x10; 		printf("\n"); 	} 	 	return 0; }   这个应该能满足你的要求...

1楼相当霸气

引用 165 楼 KenZhang1031 的回复:#include <stdio.h>  void main(void) { 	int i;  	for(i=11; i<100; i++) 	{ 		if((i % 10) != 0) 		{ 			if((i % 10) <= (i / 10)) 			{ 				printf("%dx%d=%d   ", i % 10, i / 10, (i % 10) * (i / 10)); 			} 		} 		else 		{ 			printf("\n"); 		} 	} } 神一般的存在，用%d省去小数部分，好聪明的想法

引用 134 楼 gaoshou998 的回复:我还是觉得我这个简单 python写的  def A(n):     if 0< n <= 9:         A(n-1)         for i in range(1,n+1):             print "%2sx%2s=%2s"%(i,n,i*n),         print  A(9)  >>>   1x 1= 1  1x 2= 2  2x 2= 4  1x 3= 3  2x 3= 6  3x 3= 9  1x 4= 4  2x 4= 8  3x 4=12  4x 4=16  1x 5= 5  2x 5=10  3x 5=15  4x 5=20  5x 5=25  1x 6= 6  2x 6=12  3x 6=18  4x 6=24  5x 6=30  6x 6=36  1x 7= 7  2x 7=14  3x 7=21  4x 7=28  5x 7=35  6x 7=42  7x 7=49  1x 8= 8  2x 8=16  3x 8=24  4x 8=32  5x 8=40  6x 8=48  7x 8=56  8x 8=64  1x 9= 9  2x 9=18  3x 9=27  4x 9=36  5x 9=45  6x 9=54  7x 9=63  8x 9=72  9x 9=81 >>>  n和i2个了。。。

九九表无非就是被乘数和乘数均为一位数，我们构造一个两位数的数列x, 则（x/10）得到被乘数，（x%10)得到乘数，跳过乘数为0的不就可以了  for(x=11; x<100; x++) {      if(x%10==0)        continue;     printf("% d", (x/10)*(x%10)); ....... } 格式控制我就不讨论了


Question: 请教从事c语言开发高手的几个问题

操作系统一般是不用测试的。 一个编译器，一般不会在不同操作系统下，使用同一分可执行代码。 而编译器的开发者知道，编译器要在哪个操作系统下运行；  可以编译那个操作系统的代码。 一般都会针对不同操作系统，硬件平台，去开发对应的编译器。  不论如何，你都知道，开发工具，运行在哪个操作系统，硬件平台。 开发出来的程序，运行在哪个操作系统，硬件平台下。  所以，不用检测操作系统，最多来个宏定义。 不过，同一操作系统的不同版本，是可以检测的。 比如Windows NT，Windows 2000，Win8等。  Windows 上，检测当前该操作系统，是否linux 是没有必要的，反之也一样。 因为他们之间是不兼容的，针对不同系统的程序，不能在非对应系统上运行。

引用 18 楼 king_2007 的回复:引用 17 楼 zhao4zhong1 的回复:用WinMain请问那可以移植到liunx上吗？ linux下用Qt

用WinMain

引用 15 楼 zhao4zhong1 的回复:SetLayeredWindowAttributes Function  --------------------------------------------------------------------------------  The SetLayeredWindowAttributes function sets the opacity and transparency color key of a layered window.  Syntax  BOOL SetLayeredWindowAttributes(          HWND hwnd,     COLORREF crKey,     BYTE bAlpha,     DWORD dwFlags ); Parameters  hwnd [in] Handle to the layered window. A layered window is created by specifying WS_EX_LAYERED when creating the window with the CreateWindowEx function or by setting WS_EX_LAYERED via SetWindowLong after the window has been created. crKey [in] COLORREF structure that specifies the transparency color key to be used when composing the layered window. All pixels painted by the window in this color will be transparent. To generate a COLORREF, use the RGB macro. bAlpha [in] Alpha value used to describe the opacity of the layered window. Similar to the SourceConstantAlpha member of the BLENDFUNCTION structure. When bAlpha is 0, the window is completely transparent. When bAlpha is 255, the window is opaque. dwFlags [in] Specifies an action to take. This parameter can be one or more of the following values. LWA_COLORKEY Use crKey as the transparency color. LWA_ALPHA Use bAlpha to determine the opacity of the layered window. Return Value  If the function succeeds, the return value is nonzero.  If the function fails, the return value is zero. To get extended error information, call GetLastError.     Remarks  Note that once SetLayeredWindowAttributes has been called for a layered window, subsequent UpdateLayeredWindow calls will fail until the layering style bit is cleared and set again.  For more information, see Using Layered Windows.  Function Information  Minimum DLL Version user32.dll  Header Declared in Winuser.h, include Windows.h  Import library User32.lib  Minimum operating systems Windows 2000   See Also  Windows Overview, Using Layered Windows, AlphaBlend, CreateWindowEx, SetWindowLong, TransparentBlt, UpdateLayeredWindow, COLORREF, RGB  --------------------------------------------------------------------------------请问高手，第二个问题是用int APIENTRY WinMain(HINSTANCE hlnstance,       HINSTANCE hPrevInstance,       LPSTR lpCmdline,       int nCmdShow)还是用int main()作为主函数？？

引用 12 楼 Liu_peiqi 的回复:[quote=引用 9 楼 alex_my 的回复:] [quote=引用 8 楼 zhao4zhong1 的回复:] 做个可能不太恰当的比喻： 人想让狗帮忙逮只兔子，可是人说话狗听不懂，于是人发明了一种介乎人言和狗语之间的语言，即口令。 人想让电脑帮忙做计算，可是人话电脑听不懂，于是人发明了一种介乎人言和汇编机器码之间的语言，即C语言。 人对狗的口令得让人容易学、也得让狗容易懂。 C语言同样得让人容易学、也得让电脑容易懂。 相比之下C++、Java就是人学得费劲、电脑也经常闹不懂。  最后三句还是非常恰当的。[/quote]又陷入了语言之争。。。。。。。。。。恰当的工具用到恰当的事情上，语言，只是一种工具。。。。。。个人理解，工具无好坏，只有适用不适用。 献丑了[/quote] 每天回帖即可获得10分可用分！

引用 8 楼 zhao4zhong1 的回复:做个可能不太恰当的比喻： 人想让狗帮忙逮只兔子，可是人说话狗听不懂，于是人发明了一种介乎人言和狗语之间的语言，即口令。 人想让电脑帮忙做计算，可是人话电脑听不懂，于是人发明了一种介乎人言和汇编机器码之间的语言，即C语言。 人对狗的口令得让人容易学、也得让狗容易懂。 C语言同样得让人容易学、也得让电脑容易懂。 相比之下C++、Java就是人学得费劲、电脑也经常闹不懂。  最后三句还是非常恰当的。

引用 11 楼 jerry_dqh 的回复:[quote=引用 5 楼 mujiok2003 的回复:] [quote=引用 4 楼 AnYidan 的回复:] [quote=引用 1 楼 mujiok2003 的回复:] 1. 一把利刃，但是面对超大规模应用，产能不足。  2. 条件编译 3. 执行效率主要来自优秀的算法和架构，而不是优化。  目前c 有超大规模的应用？   C 基本上在底层，与硬件密切相关之处[/quote] 因为不合适，所以没有。 [/quote] 也是有超大规模应用的。不过不是桌面应用。[/quote] 后台服务器Linux/UNIX为主！超大规模也就是在这一块了，比如炒的很热的大数据，云，APU杂七杂八的。个人觉得C还是能胜任的，只是不同的语种编码的劳动量，实现的方式不同而已！  执行速度不能靠编译器，算法与架构才是核心！

引用 9 楼 alex_my 的回复:[quote=引用 8 楼 zhao4zhong1 的回复:] 做个可能不太恰当的比喻： 人想让狗帮忙逮只兔子，可是人说话狗听不懂，于是人发明了一种介乎人言和狗语之间的语言，即口令。 人想让电脑帮忙做计算，可是人话电脑听不懂，于是人发明了一种介乎人言和汇编机器码之间的语言，即C语言。 人对狗的口令得让人容易学、也得让狗容易懂。 C语言同样得让人容易学、也得让电脑容易懂。 相比之下C++、Java就是人学得费劲、电脑也经常闹不懂。  最后三句还是非常恰当的。[/quote]又陷入了语言之争。。。。。。。。。。恰当的工具用到恰当的事情上，语言，只是一种工具。。。。。。个人理解，工具无好坏，只有适用不适用。 献丑了

引用 5 楼 mujiok2003 的回复:[quote=引用 4 楼 AnYidan 的回复:] [quote=引用 1 楼 mujiok2003 的回复:] 1. 一把利刃，但是面对超大规模应用，产能不足。  2. 条件编译 3. 执行效率主要来自优秀的算法和架构，而不是优化。  目前c 有超大规模的应用？   C 基本上在底层，与硬件密切相关之处[/quote] 因为不合适，所以没有。 [/quote] 也是有超大规模应用的。不过不是桌面应用。

请各位能不能不要空谈，先把第二个问题的代码贡献出来让我看看,再谈其他两个问题好不好。

1， 开发效率高，堆代码无脑，执行速度不用担心（前提是你的设计和实现细节是靠谱的）。 2， 真不知道。 3， C99都多老的东西了，很难找到不支持的编译器。

1 c语言比较灵活，局限性比较小，用于底层和硬件直接打交道偏多， 2 个人主要工作环境Linux下，为了代码的可移植性性，添加兼容windows的宏定义，   对于图形编程qt比较好用！   现在的语言比较多，各个方面的语言都有自己的独特的一面，所以灵活运用会比较靠谱 3 编译器对代码执行速度没有任何关系，只是源码通过编译器生成执行文件，运行时独立于编译器的！   当然编译器可能会对编译的速度有一定的影响，但是不是关键因素，优化代码才是关键！

引用 4 楼 AnYidan 的回复:[quote=引用 1 楼 mujiok2003 的回复:] 1. 一把利刃，但是面对超大规模应用，产能不足。  2. 条件编译 3. 执行效率主要来自优秀的算法和架构，而不是优化。  目前c 有超大规模的应用？   C 基本上在底层，与硬件密切相关之处[/quote] 因为不合适，所以没有。

引用 1 楼 mujiok2003 的回复:1. 一把利刃，但是面对超大规模应用，产能不足。  2. 条件编译 3. 执行效率主要来自优秀的算法和架构，而不是优化。  目前c 有超大规模的应用？   C 基本上在底层，与硬件密切相关之处

引用 1 楼 mujiok2003 的回复:1. 一把利刃，但是面对超大规模应用，产能不足。  2. 条件编译 3. 执行效率主要来自优秀的算法和架构，而不是优化。说的也不错。。。

俺一名嵌入式码农，搞了快两年了，略述己见，勿怪。 一、在实际工作中，C语言其实开发效率比其他语言稍低，但是对于操作硬件来说是把快刀。其主要的难点基本就在于宏和指针，实际上我搞开发那么长时间了，也没有参透指针，工作中还是会出现很多问题。在linux中，C语言几乎是一统天下的，很多多库，命令都是用C语言实现的，这些都是值得借鉴的。对于我来说，C语言就是入门简单，到后面知道的越多，就感觉越难。 二、一般可移植的库中都有这么一个宏定义：#ifdef WIN32 #else #endif。在linux中实现图形界面可以用第三方库，gtk或者qt。 三、编写可移植的代码建议还是用c89吧。至于编译器，linux上gcc，lc，windows上的就cl，还有intel的一个编译器也比较不错。 现在计算机硬件成本越来越低，cpu的执行速度已经很快了，其实执行速度跟编译器的关系已经很小了。


Question: 大家第一次看《The C programming language》花了多长时间？

好像在大学里作为教科书。。看过大半，目前都忘记完了。。当时感觉读起来很累

十年前看了前面一两章就放下了，至今没再拿起。

引用 楼主 Xuhanyu72 的回复:感觉这本书还是很有难度的，其中的一些课后习题我不知道是翻译的问题还是我的问题，感觉不知道题目在问什么，有时候看好几遍才知道题目的意思，把题目和答案来回对照看才明白。 不知道是我自己太落后了还是大家也是这样，想知道大家的情况。 我第一遍粗略看了谭浩强得书然后再看的这本。  看了好几个月，也没完全搞懂！

引用 12 楼 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对应的汇编并单步执行观察相应内存和寄存器变化。）谢谢您，明白了。

引用 16 楼 leigema 的回复:我是学过C语言后，上课时抽空大概看了一下，感觉不是很难。 一个星期应该可以看完文字部分确实不难都是些概念性的知识点，但是习题部分感觉比较难

我是学过C语言后，上课时抽空大概看了一下，感觉不是很难。 一个星期应该可以看完

第一次看是在9年前，至今未看完。

这本书写得本来就不太属于教材的类型。这本书的权威性，应该是来自于其是C语言的标准的来源。在没有C标准时，好像这个书就是唯一的标准。当然后来的版2就按照c标准修订过了。技术大牛写的书，不会照顾你这些初学者的，平铺直叙，到处是细节，看得初学者不知所云。所以建议你还是看看C primer plus这样的入门教材式的书籍。不过C本身并不是太难。

大概2个月啊

我看完指针那一章之后就没看了，主要是里面的习题和函数例子我都实现不鸟，现在在看C和指针，等看完这本再去看看，我感觉《The C programming language》这本书更像一本标准手册，你要是初学的话还是先看一下C和指针吧，里面的习题也比较贴近初学者一点。

没看过。。。老谭带我入的门

表示是懂了一点C语言之后，才大致浏览了一下！看的时间比较短

没看过，哇咔咔。

引用 7 楼 mujiok2003 的回复:引用 6 楼 Xuhanyu72 的回复:[quote=引用 4 楼 mujiok2003 的回复:] 对照英文原版看吧。 如果英文OK， 直接看原版。之前看的是原版，感觉看原版太慢了，又看回中文版，我感觉自己水平不行，看这书前面文字部分还好，一到后面编程题目就觉得比较难。可能还是前面没吃透吧。  我估计是因为你实践偏少， 你要多动手。 [/quote]嗯嗯，我觉得应该也是这样

引用 6 楼 Xuhanyu72 的回复:引用 4 楼 mujiok2003 的回复:对照英文原版看吧。 如果英文OK， 直接看原版。之前看的是原版，感觉看原版太慢了，又看回中文版，我感觉自己水平不行，看这书前面文字部分还好，一到后面编程题目就觉得比较难。可能还是前面没吃透吧。  我估计是因为你实践偏少， 你要多动手。

那本书好像很久没有更新了。

对照英文原版看吧。 如果英文OK， 直接看原版。

就看了后面的，前面基础的没细看。大概2到3个月吧，我是抽空看的。现在主要看linux系统编程的。。。


Question: 线程响应信号

《Linux C编程一站式学习》

应该会吧，不然整个进程都会出问题吧，起码程序无法正常运行了吧


Question: 请求下面这条C语言中嵌入的汇编指令的意思？

就是把atoi()、atof()的返回值压栈了。

GDB常用命令 调用gdb编译需要在cc后面加 -g参数再加-o； [root@redhat home]#gdb 调试文件：启动gdb (gdb) l ：（字母l）从第一行开始列出源码 (gdb) break n :在第n行处设置断点 (gdb) break func：在函数func()的入口处设置断点 (gdb) info break： 查看断点信息 (gdb) r：运行程序 (gdb) n：单步执行 (gdb) c：继续运行 (gdb) p 变量 ：打印变量的值 (gdb) bt：查看函数堆栈 (gdb) finish：退出函数 (gdb) shell 命令行：执行shell命令行 (gdb) set args 参数:指定运行时的参数 (gdb) show args：查看设置好的参数 (gdb) show paths:查看程序运行路径；            set environment varname [=value] 设置环境变量。如：set env USER=hchen；             show environment [varname] 查看环境变量； (gdb) cd 相当于shell的cd; (gdb)pwd ：显示当前所在目录 (gdb)info program： 来查看程序的是否在运行，进程号，被暂停的原因。 (gdb)clear 行号n：清除第n行的断点 (gdb)delete 断点号n：删除第n个断点 (gdb)disable 断点号n：暂停第n个断点 (gdb)enable 断点号n：开启第n个断点 (gdb)step：单步调试如果有函数调用，则进入函数；与命令n不同，n是不进入调用的函数的 list ：简记为 l ，其作用就是列出程序的源代码，默认每次显示10行。 list 行号：将显示当前文件以“行号”为中心的前后10行代码，如：list 12 list 函数名：将显示“函数名”所在函数的源代码，如：list main list ：不带参数，将接着上一次 list 命令的，输出下边的内容。 注意 ：如果运行list 命令得到类似如下的打印，那是因为在编译程序时没有加入 -g 选项： (gdb) list 1       ../sysdeps/i386/elf/start.S: No such file or directory.         in ../sysdeps/i386/elf/start.S run：简记为 r ，其作用是运行程序，当遇到断点后，程序会在断点处停止运行，等待用户输入下一步的命令。 回车：重复上一条命令。 set args：设置运行程序时的命令行参数，如：set args 33 55 show args：显示命令行参数 continue：简讯为 c ，其作用是继续运行被断点中断的程序。 break：为程序设置断点。 break 行号：在当前文件的“行号”处设置断点，如：break  33 break 函数名：在用户定义的函数“函数名”处设置断点，如：break cb_button info breakpoints：显示当前程序的断点设置情况 disable breakpoints Num：关闭断点“Num”，使其无效，其中“Num”为 info breakpoints 中显示的对应值 enable breakpoints Num：打开断点“Num”，使其重新生效 step：简记为 s ，单步跟踪程序，当遇到函数调用时，则进入此函数体（一般只进入用户自定义函数）。 next：简记为 n，单步跟踪程序，当遇到函数调用时，也不进入此函数体；此命令同 step 的主要区别是，step 遇到用户自定义的函数，将步进到函数中去运行，而 next 则直接调用函数，不会进入到函数体内。 until：当你厌倦了在一个循环体内单步跟踪时，这个命令可以运行程序直到退出循环体。 finish： 运行程序，直到当前函数完成返回，并打印函数返回时的堆栈地址和返回值及参数值等信息。 stepi或nexti：单步跟踪一些机器指令。 print 表达式：简记为 p ，其中“表达式”可以是任何当前正在被测试程序的有效表达式，比如当前正在调试C语言的程序，那么“表达式”可以是任何C语言的有效表达式，包括数字，变量甚至是函数调用。 print a：将显示整数 a 的值 print ++a：将把 a 中的值加1,并显示出来 print name：将显示字符串 name 的值 print gdb_test(22)：将以整数22作为参数调用 gdb_test() 函数 print gdb_test(a)：将以变量 a 作为参数调用 gdb_test() 函数 bt：显示当前程序的函数调用堆栈。 display 表达式：在单步运行时将非常有用，使用display命令设置一个表达式后，它将在每次单步进行指令后，紧接着输出被设置的表达式及值。如： display a watch 表达式：设置一个监视点，一旦被监视的“表达式”的值改变，gdb将强行终止正在被调试的程序。如： watch a kill：将强行终止当前正在调试的程序 help 命令：help 命令将显示“命令”的常用帮助信息 call 函数(参数)：调用“函数”，并传递“参数”，如：call  gdb_test(55) layout：用于分割窗口，可以一边查看代码，一边测试： layout src：显示源代码窗口 layout asm：显示反汇编窗口 layout regs：显示源代码/反汇编和CPU寄存器窗口 layout split：显示源代码和反汇编窗口 Ctrl + L：刷新窗口 quit：简记为 q ，退出gdb 当然，gdb的功能远不止这些，包括多进程/多线程/信号/远程调试等功能在这里均没有提及，有需要的读者可以参考其它信息 本文来自CSDN博客，转载请标明出处：http://blog.csdn.net/pizi0475/archive/2011/03/08/6232749.aspx

gcc-inline-asm.pdf

这是 gcc 扩展的内联汇编语法，不是 Intel 汇编，也不是直接的 AT&T 汇编，参考 http://gcc.gnu.org/onlinedocs/gcc-4.8.1/gcc/Extended-Asm.html#Extended-Asm

引用 2 楼 DelphiGuy 的回复:就是把atoi()、atof()的返回值压栈了。 请问 里面具体每个指令步骤的意思是什么？

引用 1 楼 zhao4zhong1 的回复:    PUSH    把字压入堆栈.     SUB     减法.     FSTP    real8 ptr mem  保存双精度浮点数到mem并出栈      机器码  DD mm011mmm  为什么是 push %0，另外还再加 ::"r"()，这种格式表示什么呢？


Question: C语音读取WAV文件，头文件中DataID为空，求大神帮忙看看

引用 10 楼 yulitingfeng 的回复:#include<stdio.h> #include<stdlib.h> #include<string.h> #include<math.h>  #pragma pack(1)    struct WavHead_ { 	char ChunkID[4]; //ChunkID is "RIFF' 	unsigned int Chunksize; //RIFF WAVE Chunk 大小 	char ChunkType[4]; //Yype is 'WAVE' 	//char Format[4]; 	char FormatID[4]; //FORmatID IS 'fmt' 	int dwFmtlen; 	int Formattag;//编码方式，一般为0x0001 	int ChannelNum; //声道数目，1--单声道；2--双声道 	int SamplePersec; //采样频率 	int AveBytePersec; //每秒平均字节数 	short BitsperSample;//每个采样点的bit 	char FactID[4]; //FactID is 'fact' 	int Factsize; 	int FactData; 	char DataID[4];//DataId is 'data' 	long DataSize; 	long WavData; 	long  SubChun2Size;     //long SampleNum; }WavHead;  //void wave_generator(FILE *fpwav, wav_pcm_header44 *phwav);   int main() {     FILE *fpwav = NULL;     struct WavHead_ hWAV;      fpwav = fopen("test.wav","rb");     if(fpwav == NULL) {         printf("fail to open file");         return -1;     }     printf("open ok\n");     fread(&hWAV, sizeof(WavHead), 1, fpwav);     printf("fread head ok\n");      printf("%s,%s,%s,\n",hWAV.DataID,hWAV.FactID,hWAV.ChunkType);      if ((0 == memcmp(hWAV.ChunkID,"RIFF",4))&&(0 == memcmp(hWAV.FormatID,"fmt",4),4)&&(0 == memcmp(hWAV.DataID,"data",4))) {         printf("wave audio data format:\n");         printf("Channel num:%d\n",hWAV.ChannelNum);         printf("SampleRate:%dHz\n",hWAV.SamplePersec);         printf("BitesperSample:%d bits\n",hWAV.AveBytePersec);         //printf("audio data size : %d",)     }      fclose(fpwav);     fpwav = NULL;     return 0;  }修改后的，可能会有问题，需认真对比wav的数据结构。  输出：open ok fread head ok data串,fact,WAVEfmt , wave audio data format: Channel num:22050 SampleRate:44100Hz BitesperSample:1048578 bits  这个#pragma pack(1) 事至关重要的！ 谢谢！

#include<stdio.h> #include<stdlib.h> #include<string.h> #include<math.h>  #pragma pack(push,1) struct WavHead {     char   ChunkID[4];    //ChunkID is "RIFF'     short  Chunksize;     //RIFF WAVE Chunk 大小     char   ChunkType[4];  //Yype is 'WAVE'     //char Format[4];     char   FormatID[4];   //FORmatID IS 'fmt'     short    dwFmtlen;     short    Formattag;     //编码方式，一般为0x0001     short  ChannelNum;    //声道数目，1--单声道；2--双声道     long   SamplePersec;  //采样频率     long   AveBytePersec; //每秒平均字节数     short  BitsperSample; //每个采样点的bit     char   FactID[4];     //FactID is 'fact'     long   Factsize;     long   FactData;     char   DataID[4];     //DataId is 'data'     long   DataSize;     long   WavData;     long   SubChun2Size;     //long SampleNum; }; #pragma pack(pop)  //void wave_generator(FILE *fpwav, wav_pcm_header44 *phwav);   int main() {     FILE *fpwav = NULL;     struct WavHead hWAV;      fpwav = fopen("test.wav","rb");     if(fpwav == NULL) {         printf("fail to open file");         return -1;     }     printf("open ok\n");     fread(&hWAV, sizeof(WavHead), 1, fpwav);     printf("fread head ok\n");      printf("%s\n",hWAV.DataID);       if ((0 == memcmp(hWAV.ChunkID,"RIFF",4))&&(0 == memcmp(hWAV.FormatID,"fmt",4),4)&&(0 == memcmp(hWAV.DataID,"data",4))) {         printf("wave audio data format:\n");         printf("Channel num:%d\n",hWAV.ChannelNum);         printf("SampleRate:%dHz\n",hWAV.SamplePersec);         printf("BitesperSample:%d bits\n",hWAV.AveBytePersec);         //printf("audio data size : %d",)     }      fclose(fpwav);     fpwav = NULL;     return 0;  }

定义结构体之前配置：  #pragma pack(1)  就是紧凑模式，这样字段就会一个一个的挨着放。  否则的话，编译器会在一些字段后面插入空的字节，用来对齐，以实现较高的处理效率。  引用 2 楼 xinsuixiaofeiyu 的回复:怎样才是紧凑模式呢？如果设定对齐方式，该设定多少字节对齐呢？求大神详细解释下了。[quote=引用 1 楼 turingo 的回复:] 结构体要用紧凑模式，不然又会字节对齐的问题：  #pragma pack(1)   [quote=引用 楼主 xinsuixiaofeiyu 的回复:] c语言写的一个读取wav音频文件的小程序，调试发现DataID内容为空，但应该为'data'，不知道原因，音频文件为一首wav的歌曲，代码如下： #include<stdio.h> #include<stdlib.h> #include <STRING.H> #include<math.h> typedef short DWORD; struct WavHead { 	char ChunkID[4]; //ChunkID is "RIFF' 	DWORD Chunksize; //RIFF WAVE Chunk 大小 	char ChunkType[4]; //Yype is 'WAVE' 	//char Format[4]; 	char FormatID[4]; //FORmatID IS 'fmt' 	int dwFmtlen; 	int Formattag;//编码方式，一般为0x0001 	short ChannelNum; //声道数目，1--单声道；2--双声道 	long SamplePersec; //采样频率 	long AveBytePersec; //每秒平均字节数 	short BitsperSample;//每个采样点的bit 	char FactID[4]; //FactID is 'fact' 	long Factsize; 	long FactData; 	char DataID[4];//DataId is 'data' 	long DataSize; 	long WavData; 	long SubChun2Size; 	//long SampleNum; };  //void wave_generator(FILE *fpwav, wav_pcm_header44 *phwav);   int main() { 	FILE *fpwav = NULL; 	struct WavHead hWAV; 	 	fpwav = fopen("test.wav","rb"); 	if(fpwav == NULL) 	{ 		printf("fail to open file"); 		return -1; 	} 	printf("open ok\n"); 	fread(&hWAV, sizeof(WavHead), 1, fpwav); 	printf("fread head ok\n");  	printf("%s\n",hWAV.DataID);  	 	if ((0 == memcmp(hWAV.ChunkID,"RIFF",4))&&(0 == memcmp(hWAV.FormatID,"fmt",4),4)&&(0 == memcmp(hWAV.DataID,"data",4))) 	{ 		printf("wave audio data format:\n"); 		printf("Channel num:%d\n",hWAV.ChannelNum); 		printf("SampleRate:%dHz\n",hWAV.SamplePersec); 		printf("BitesperSample:%d bits\n",hWAV.AveBytePersec); 		//printf("audio data size : %d",) 	} 	 	fclose(fpwav); 	fpwav = NULL; return 0; 	 }[/quote][/quote]

怎样才是紧凑模式呢？如果设定对齐方式，该设定多少字节对齐呢？求大神详细解释下了。引用 1 楼 turingo 的回复:结构体要用紧凑模式，不然又会字节对齐的问题：  #pragma pack(1)   [quote=引用 楼主 xinsuixiaofeiyu 的回复:] c语言写的一个读取wav音频文件的小程序，调试发现DataID内容为空，但应该为'data'，不知道原因，音频文件为一首wav的歌曲，代码如下： #include<stdio.h> #include<stdlib.h> #include <STRING.H> #include<math.h> typedef short DWORD; struct WavHead { 	char ChunkID[4]; //ChunkID is "RIFF' 	DWORD Chunksize; //RIFF WAVE Chunk 大小 	char ChunkType[4]; //Yype is 'WAVE' 	//char Format[4]; 	char FormatID[4]; //FORmatID IS 'fmt' 	int dwFmtlen; 	int Formattag;//编码方式，一般为0x0001 	short ChannelNum; //声道数目，1--单声道；2--双声道 	long SamplePersec; //采样频率 	long AveBytePersec; //每秒平均字节数 	short BitsperSample;//每个采样点的bit 	char FactID[4]; //FactID is 'fact' 	long Factsize; 	long FactData; 	char DataID[4];//DataId is 'data' 	long DataSize; 	long WavData; 	long SubChun2Size; 	//long SampleNum; };  //void wave_generator(FILE *fpwav, wav_pcm_header44 *phwav);   int main() { 	FILE *fpwav = NULL; 	struct WavHead hWAV; 	 	fpwav = fopen("test.wav","rb"); 	if(fpwav == NULL) 	{ 		printf("fail to open file"); 		return -1; 	} 	printf("open ok\n"); 	fread(&hWAV, sizeof(WavHead), 1, fpwav); 	printf("fread head ok\n");  	printf("%s\n",hWAV.DataID);  	 	if ((0 == memcmp(hWAV.ChunkID,"RIFF",4))&&(0 == memcmp(hWAV.FormatID,"fmt",4),4)&&(0 == memcmp(hWAV.DataID,"data",4))) 	{ 		printf("wave audio data format:\n"); 		printf("Channel num:%d\n",hWAV.ChannelNum); 		printf("SampleRate:%dHz\n",hWAV.SamplePersec); 		printf("BitesperSample:%d bits\n",hWAV.AveBytePersec); 		//printf("audio data size : %d",) 	} 	 	fclose(fpwav); 	fpwav = NULL; return 0; 	 }[/quote]

你可以用ultraedit 来查看wav文件的数据流。

C:\windows_2000_source_code\win2k\private\windows\shell\control\mmsys\sound.c /*    -    -    -    -    -    -    -    -    */ // //    sound.c // //    Copyright (C) 1994 Microsoft Corporation.  All Rights Reserved. // /*    -    -    -    -    -    -    -    -    */  #define STRICT #include <windows.h> #include <windowsx.h> #include <mmsystem.h> #include <mmddk.h> #include "sound.h" #include <tchar.h>  /*    -    -    -    -    -    -    -    -    */ typedef struct tagSOUND FAR *PSOUND; typedef struct tagSOUND {     WAVEHDR        header;     LPBYTE        pbData;     DWORD        cbLength;     LPWAVEFORMATEX    lpwfx;     HGLOBAL        hgData;     HWAVEOUT    hwave;     HWND        hwndNotify; } SOUND;  typedef struct {     FOURCC    fccRiff;     DWORD    cbSize;     FOURCC    fccWave; } FILEHEADER,  *LPFILEHEADER;   typedef struct {     DWORD    dwCKID;     DWORD    dwSize; } CHUNKHEADER,  *LPCHUNKHEADER;  #define    RIFF_FILE    MAKEFOURCC('R','I','F','F') #define    RIFF_WAVE    MAKEFOURCC('W','A','V','E') #define    RIFF_FORMAT    MAKEFOURCC('f','m','t',' ') #define    RIFF_DATA    MAKEFOURCC('d','a','t','a')  /*    -    -    -    -    -    -    -    -    */ #ifdef DEBUG #define    STATIC #else #define    STATIC    static #endif  typedef CHUNKHEADER UNALIGNED FAR *ULPCHUNKHEADER; typedef WAVEFORMATEX UNALIGNED FAR *ULPWAVEFORMATEX;  /*    -    -    -    -    -    -    -    -    */ STATIC MMRESULT NEAR PASCAL soundInitWaveHeader(     PSOUND    ps) {     size_t cbWFX;     ULPWAVEFORMATEX    pwfx;     ULPCHUNKHEADER    pckhdr;     LPFILEHEADER    pfhdr;     LPBYTE        pbData;     DWORD        dwFileSize;     DWORD        dwCurPos;      if (ps->cbLength < sizeof(FILEHEADER))         return MMSYSERR_INVALPARAM;     pfhdr = (LPFILEHEADER)ps->pbData;     if ((pfhdr->fccRiff != RIFF_FILE) || (pfhdr->fccWave != RIFF_WAVE))         return MMSYSERR_NOTSUPPORTED;     dwFileSize = pfhdr->cbSize;     dwCurPos = sizeof(FILEHEADER);     pbData = (LPBYTE)ps->pbData + sizeof(FILEHEADER);     if (ps->cbLength < dwFileSize)         return MMSYSERR_INVALPARAM;     for (;;)     {         pckhdr = (ULPCHUNKHEADER)pbData;         if (pckhdr->dwCKID == RIFF_FORMAT)             break;         dwCurPos += pckhdr->dwSize + sizeof(CHUNKHEADER);         if (dwCurPos >= dwFileSize)             return MMSYSERR_INVALPARAM;         pbData += pckhdr->dwSize + sizeof(CHUNKHEADER);     }     pwfx = (ULPWAVEFORMATEX)(pbData + sizeof(CHUNKHEADER));      cbWFX = sizeof(WAVEFORMATEX);     if (pwfx->wFormatTag!=WAVE_FORMAT_PCM)     {         cbWFX += pwfx->cbSize;     }      if ((ps->lpwfx = (LPWAVEFORMATEX)GlobalAlloc (GMEM_FIXED, cbWFX)) == 0)         return MMSYSERR_NOMEM;      memcpy ((char *)ps->lpwfx, pwfx, cbWFX);      pbData = pbData + ((ULPCHUNKHEADER)pbData)->dwSize + sizeof(CHUNKHEADER);     for (;;)     {         pckhdr = (ULPCHUNKHEADER)pbData;         if (pckhdr->dwCKID == RIFF_DATA)             break;         dwCurPos += pckhdr->dwSize + sizeof(CHUNKHEADER);         if (dwCurPos >= dwFileSize)         {             GlobalFree ((HGLOBAL)ps->lpwfx);             ps->lpwfx = NULL;             return MMSYSERR_INVALPARAM;         }         pbData += pckhdr->dwSize + sizeof(CHUNKHEADER);     }     ps->header.lpData = pbData + sizeof(CHUNKHEADER);     ps->header.dwBufferLength = pckhdr->dwSize;     ps->header.dwBytesRecorded = 0;     ps->header.dwUser = (DWORD_PTR)ps;     ps->header.dwFlags = 0;     ps->header.dwLoops = 0;     ps->header.lpNext = NULL;     ps->header.reserved = 0;     return MMSYSERR_NOERROR; }  /*    -    -    -    -    -    -    -    -    */ STATIC MMRESULT NEAR PASCAL soundLoadFile(     LPCTSTR    pszSound,     HWND    hwndNotify,     PSOUND    ps) {     HFILE        hf;     MMRESULT    mmr;      if ((hf = HandleToUlong(CreateFile(pszSound,GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL))) != HFILE_ERROR)     {         ps->cbLength = _llseek(hf, 0L, SEEK_END);         _llseek(hf, 0L, SEEK_SET);         if (ps->hgData = GlobalAlloc(GMEM_MOVEABLE | GMEM_SHARE, ps->cbLength))         {             if (ps->pbData = GlobalLock(ps->hgData))             {                 if (_hread(hf, ps->pbData, ps->cbLength) == (LONG)ps->cbLength)                 {                     if (!(mmr = soundInitWaveHeader(ps)))                     {                         _lclose(hf);                         ps->hwndNotify = hwndNotify;                         return MMSYSERR_NOERROR;                     }                 }                 else                     mmr = MMSYSERR_ERROR;                 GlobalUnlock(ps->hgData);             }             else                 mmr = MMSYSERR_ERROR;             GlobalFree(ps->hgData);         }         else             mmr = MMSYSERR_NOMEM;         _lclose(hf);     }     else         mmr = MMSYSERR_ERROR;      return mmr; }  /*    -    -    -    -    -    -    -    -    */ void FAR PASCAL soundOnDone(     HSOUND    hs) {     PSOUND        ps;      ps = (PSOUND)hs;     waveOutUnprepareHeader(ps->hwave, &ps->header, sizeof(WAVEHDR));     waveOutClose(ps->hwave);     ps->hwave = NULL; }  /*    -    -    -    -    -    -    -    -    */ MMRESULT FAR PASCAL soundOpen(     LPCTSTR    pszSound,     HWND    hwndNotify,     PHSOUND    phs) {     MMRESULT    mmr;      if (!(*phs = (HSOUND)LocalAlloc(LMEM_FIXED | LMEM_ZEROINIT, sizeof(SOUND))))         return MMSYSERR_NOMEM;     if (mmr = soundLoadFile(pszSound, hwndNotify, (PSOUND)*phs))         LocalFree((HLOCAL)*phs);     return mmr; }  /*    -    -    -    -    -    -    -    -    */ MMRESULT FAR PASCAL soundClose(     HSOUND    hs) {     PSOUND        ps;     MMRESULT    mmr;      if (mmr = soundStop(hs))         return mmr;     ps = (PSOUND)hs;     if (ps->lpwfx != NULL) {         GlobalFree ((HGLOBAL)ps->lpwfx);         ps->lpwfx = NULL;     }     GlobalUnlock(ps->hgData);     GlobalFree(ps->hgData);     LocalFree((HLOCAL)hs);     return MMSYSERR_NOERROR; }  /*    -    -    -    -    -    -    -    -    */ MMRESULT FAR PASCAL soundPlay(     HSOUND    hs) {     PSOUND        ps;     MMRESULT    mmr;      if (mmr = soundStop(hs))         return mmr;     ps = (PSOUND)hs;     if (!(mmr = waveOutOpen(&ps->hwave, WAVE_MAPPER, ps->lpwfx, (DWORD_PTR)ps->hwndNotify, (DWORD_PTR)ps, CALLBACK_WINDOW | WAVE_ALLOWSYNC)))     {         ps->header.dwFlags &= ~WHDR_DONE;         if (!(mmr = waveOutPrepareHeader(ps->hwave, &ps->header, sizeof(WAVEHDR))))         {             if (!(mmr = waveOutWrite(ps->hwave, &ps->header, sizeof(WAVEHDR))))                 return MMSYSERR_NOERROR;             waveOutUnprepareHeader(ps->hwave, &ps->header, sizeof(WAVEHDR));         }         waveOutClose(ps->hwave);         ps->hwave = NULL;     }     return mmr; }  /*    -    -    -    -    -    -    -    -    */ MMRESULT FAR PASCAL soundStop(     HSOUND    hs) {     PSOUND        ps;     MSG        msg;      ps = (PSOUND)hs;     if (ps->hwave)         waveOutReset(ps->hwave);     if (IsWindow(ps->hwndNotify))     while (PeekMessage(&msg, ps->hwndNotify, MM_WOM_OPEN, MM_WOM_DONE, PM_REMOVE))     {         DispatchMessage(&msg);     }     return MMSYSERR_NOERROR; }  /*    -    -    -    -    -    -    -    -    */

参考C:\windows_2000_source_code\win2k\private\windows\shell\control\mmsys\sound.c ... STATIC MMRESULT NEAR PASCAL soundInitWaveHeader(     PSOUND    ps) {     size_t cbWFX;     ULPWAVEFORMATEX    pwfx;     ULPCHUNKHEADER    pckhdr;     LPFILEHEADER    pfhdr;     LPBYTE        pbData;     DWORD        dwFileSize;     DWORD        dwCurPos;      if (ps->cbLength < sizeof(FILEHEADER))         return MMSYSERR_INVALPARAM;     pfhdr = (LPFILEHEADER)ps->pbData;     if ((pfhdr->fccRiff != RIFF_FILE) || (pfhdr->fccWave != RIFF_WAVE))         return MMSYSERR_NOTSUPPORTED;     dwFileSize = pfhdr->cbSize;     dwCurPos = sizeof(FILEHEADER);     pbData = (LPBYTE)ps->pbData + sizeof(FILEHEADER);     if (ps->cbLength < dwFileSize)         return MMSYSERR_INVALPARAM;     for (;;)     {         pckhdr = (ULPCHUNKHEADER)pbData;         if (pckhdr->dwCKID == RIFF_FORMAT)             break;         dwCurPos += pckhdr->dwSize + sizeof(CHUNKHEADER);         if (dwCurPos >= dwFileSize)             return MMSYSERR_INVALPARAM;         pbData += pckhdr->dwSize + sizeof(CHUNKHEADER);     }     pwfx = (ULPWAVEFORMATEX)(pbData + sizeof(CHUNKHEADER));      cbWFX = sizeof(WAVEFORMATEX);     if (pwfx->wFormatTag!=WAVE_FORMAT_PCM)     {         cbWFX += pwfx->cbSize;     }      if ((ps->lpwfx = (LPWAVEFORMATEX)GlobalAlloc (GMEM_FIXED, cbWFX)) == 0)         return MMSYSERR_NOMEM;      memcpy ((char *)ps->lpwfx, pwfx, cbWFX);      pbData = pbData + ((ULPCHUNKHEADER)pbData)->dwSize + sizeof(CHUNKHEADER);     for (;;)     {         pckhdr = (ULPCHUNKHEADER)pbData;         if (pckhdr->dwCKID == RIFF_DATA)             break;         dwCurPos += pckhdr->dwSize + sizeof(CHUNKHEADER);         if (dwCurPos >= dwFileSize)         {             GlobalFree ((HGLOBAL)ps->lpwfx);             ps->lpwfx = NULL;             return MMSYSERR_INVALPARAM;         }         pbData += pckhdr->dwSize + sizeof(CHUNKHEADER);     }     ps->header.lpData = pbData + sizeof(CHUNKHEADER);     ps->header.dwBufferLength = pckhdr->dwSize;     ps->header.dwBytesRecorded = 0;     ps->header.dwUser = (DWORD_PTR)ps;     ps->header.dwFlags = 0;     ps->header.dwLoops = 0;     ps->header.lpNext = NULL;     ps->header.reserved = 0;     return MMSYSERR_NOERROR; } ... STATIC MMRESULT NEAR PASCAL soundLoadFile(     LPCTSTR    pszSound,     HWND    hwndNotify,     PSOUND    ps) {     HFILE        hf;     MMRESULT    mmr;      if ((hf = HandleToUlong(CreateFile(pszSound,GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL))) != HFILE_ERROR)     {         ps->cbLength = _llseek(hf, 0L, SEEK_END);         _llseek(hf, 0L, SEEK_SET);         if (ps->hgData = GlobalAlloc(GMEM_MOVEABLE | GMEM_SHARE, ps->cbLength))         {             if (ps->pbData = GlobalLock(ps->hgData))             {                 if (_hread(hf, ps->pbData, ps->cbLength) == (LONG)ps->cbLength)                 {                     if (!(mmr = soundInitWaveHeader(ps)))                     {                         _lclose(hf);                         ps->hwndNotify = hwndNotify;                         return MMSYSERR_NOERROR;                     }                 }                 else                     mmr = MMSYSERR_ERROR;                 GlobalUnlock(ps->hgData);             }             else                 mmr = MMSYSERR_ERROR;             GlobalFree(ps->hgData);         }         else             mmr = MMSYSERR_NOMEM;         _lclose(hf);     }     else         mmr = MMSYSERR_ERROR;      return mmr; } ...

正解，文件头格式需和文件对应，一般应该是44字节。引用 5 楼 user-5 的回复:wav由若干个块组成，不一定马上就是fmt，也不一定有fact，分析应该时循序读入4byte块名+4byte块的大小，然后推敲出下一个块的位置，多声道的话fmt块也不是你列出的那种格式，所以先找格式规范看看先...

结构体要用紧凑模式，不然又会字节对齐的问题：  #pragma pack(1)  引用 楼主 xinsuixiaofeiyu 的回复:c语言写的一个读取wav音频文件的小程序，调试发现DataID内容为空，但应该为'data'，不知道原因，音频文件为一首wav的歌曲，代码如下： #include<stdio.h> #include<stdlib.h> #include <STRING.H> #include<math.h> typedef short DWORD; struct WavHead { 	char ChunkID[4]; //ChunkID is "RIFF' 	DWORD Chunksize; //RIFF WAVE Chunk 大小 	char ChunkType[4]; //Yype is 'WAVE' 	//char Format[4]; 	char FormatID[4]; //FORmatID IS 'fmt' 	int dwFmtlen; 	int Formattag;//编码方式，一般为0x0001 	short ChannelNum; //声道数目，1--单声道；2--双声道 	long SamplePersec; //采样频率 	long AveBytePersec; //每秒平均字节数 	short BitsperSample;//每个采样点的bit 	char FactID[4]; //FactID is 'fact' 	long Factsize; 	long FactData; 	char DataID[4];//DataId is 'data' 	long DataSize; 	long WavData; 	long SubChun2Size; 	//long SampleNum; };  //void wave_generator(FILE *fpwav, wav_pcm_header44 *phwav);   int main() { 	FILE *fpwav = NULL; 	struct WavHead hWAV; 	 	fpwav = fopen("test.wav","rb"); 	if(fpwav == NULL) 	{ 		printf("fail to open file"); 		return -1; 	} 	printf("open ok\n"); 	fread(&hWAV, sizeof(WavHead), 1, fpwav); 	printf("fread head ok\n");  	printf("%s\n",hWAV.DataID);  	 	if ((0 == memcmp(hWAV.ChunkID,"RIFF",4))&&(0 == memcmp(hWAV.FormatID,"fmt",4),4)&&(0 == memcmp(hWAV.DataID,"data",4))) 	{ 		printf("wave audio data format:\n"); 		printf("Channel num:%d\n",hWAV.ChannelNum); 		printf("SampleRate:%dHz\n",hWAV.SamplePersec); 		printf("BitesperSample:%d bits\n",hWAV.AveBytePersec); 		//printf("audio data size : %d",) 	} 	 	fclose(fpwav); 	fpwav = NULL; return 0; 	 }


Question: 请问各位大侠，用C语言如何实现下图的算法？

不会，刚学C语言，求指点

伪代码都写好了

一步步跟着来就好。


Question: 两张同样的24位bmp图片左右拼接C语言求代码

也可以创建兼容位图 然后通过DC将他们贴在一起

楼上高手啊！

void stiching() {     std::vector<cv::Mat> imgs(2);     imgs[0] = cv::imread("/Users/Qt/program/blogsCodes/pic/panorama_image1.jpg");     imgs[1] = cv::imread("/Users/Qt/program/blogsCodes/pic/panorama_image2.jpg");     if(imgs[0].empty() || imgs[1].empty()){         std::cerr<<"can't read image"<<std::endl;         return;     }      cv::Mat pano;     cv::Stitcher stitcher = cv::Stitcher::createDefault();     stitcher.stitch(imgs, pano);     cv::imwrite("result.jpg", pano); }       原理 http://ramsrigoutham.com/2012/11/22/panorama-image-stitching-in-opencv/  openCV（open source computer vision的defacto standard）已经全面使用c++开发，现已不再开发c的api 未来的openCV3.0会将c的api mark为"deprecated" 建议采用c++的api,简洁得多了  例子  c  double calcGradients(const IplImage *src,                       int aperture_size = 7) {     CvSize sz = cvGetSize(src);          IplImage* img16_x = cvCreateImage(sz, IPL_DEPTH_16S, 1);      IplImage* img16_y = cvCreateImage(sz, IPL_DEPTH_16S, 1);      cvSobel(src, img16_x, 1, 0, aperture_size);     cvSobel(src, img16_y, 0, 1, aperture_size);          IplImage* imgF_x = cvCreateImage(sz, IPL_DEPTH_32F, 1);     IplImage* imgF_y = cvCreateImage(sz, IPL_DEPTH_32F, 1);     cvScale(img16_x, imgF_x);     cvScale(img16_y, imgF_y);          IplImage* magnitude = cvCreateImage(sz, IPL_DEPTH_32F, 1);     cvCartToPolar(imgF_x, imgF_y, magnitude);     double res = cvSum(magnitude).val[0];          cvReleaseImage(&magnitude );     cvReleaseImage(&imgF_x);     cvReleaseImage(&imgF_y);     cvReleaseImage(&img16_x);     cvReleaseImage(&img16_y);          return res; }   c++  double contrast_measure(Mat& img) {     Mat dx, dy;     Sobel(img, dx, 1, 0, 3, CV_32F);     Sobel(img, dy, 0, 1, 3, CV_32F);     magnitude(dx, dy, dx);          return sum(dx)[0]; }   那个容易理解，维护？一目了然

关注一下，等高手现身


Question: 流媒体

h264流服务端rtp组包发送代码 参考下，注意几个步骤就好了！

一块内存里有12345，在开辟个内存头是67，把12345拷过去

我晓得加个RTP头就可以，可问题是怎么加？

加个rtp头就可以了吧


Question: 这个错误在哪   看了很久都没找到

常量也有类型！ C++ Integer Constants Integer constants are constant data elements that have no fractional parts or exponents. They always begin with a digit. You can specify integer constants in decimal, octal, or hexadecimal form. They can specify signed or unsigned types and long or short types.  Syntax  integer-constant :  decimal-constant integer-suffixopt octal-constant integer-suffixopt hexadecimal-constant integer-suffixopt 'c-char-sequence'  decimal-constant :  nonzero-digit decimal-constant digit  octal-constant :  0 octal-constant octal-digit  hexadecimal-constant :  0x hexadecimal-digit 0X hexadecimal-digit hexadecimal-constant hexadecimal-digit  nonzero-digit : one of  1 2 3 4 5 6 7 8 9  octal-digit : one of  0 1 2 3 4 5 6 7  hexadecimal-digit : one of  0 1 2 3 4 5 6 7 8 9 a b c d e f A B C D E F  integer-suffix :  unsigned-suffix long-suffixopt long-suffix unsigned-suffixopt  unsigned-suffix : one of  u U  long-suffix : one of  l L  64-bit integer-suffix :  i64  To specify integer constants using octal or hexadecimal notation, use a prefix that denotes the base. To specify an integer constant of a given integral type, use a suffix that denotes the type.  To specify a decimal constant, begin the specification with a nonzero digit. For example:  int i = 157;   // Decimal constant int j = 0198;  // Not a decimal number; erroneous octal constant int k = 0365;  // Leading zero specifies octal constant, not decimal  To specify an octal constant, begin the specification with 0, followed by a sequence of digits in the range 0 through 7. The digits 8 and 9 are errors in specifying an octal constant. For example:  int i = 0377;   // Octal constant int j = 0397;   // Error: 9 is not an octal digit  To specify a hexadecimal constant, begin the specification with 0x or 0X (the case of the “x” does not matter), followed by a sequence of digits in the range 0 through 9 and a (or A) through f (or F). Hexadecimal digits a (or A) through f (or F) represent values in the range 10 through 15. For example:  int i = 0x3fff;   // Hexadecimal constant int j = 0X3FFF;   // Equal to i  To specify an unsigned type, use either the u or U suffix. To specify a long type, use either the l or L suffix. For example:  unsigned uVal = 328u;             // Unsigned value long lVal = 0x7FFFFFL;            // Long value specified                                    //  as hex constant unsigned long ulVal = 0776745ul;  // Unsigned long value  C++ Floating-Point Constants Floating-point constants specify values that must have a fractional part. These values contain decimal points (.) and can contain exponents.  Syntax  floating-constant :  fractional-constant exponent-partopt floating-suffixopt digit-sequence exponent-part floating-suffixopt  fractional-constant :  digit-sequenceopt . digit-sequence digit-sequence .  exponent-part :  e signopt digit-sequence E signopt digit-sequence  sign : one of  + –  digit-sequence :  digit digit-sequence digit  floating-suffix :one of  f l F L  Floating-point constants have a “mantissa,” which specifies the value of the number, an “exponent,” which specifies the magnitude of the number, and an optional suffix that specifies the constant’s type. The mantissa is specified as a sequence of digits followed by a period, followed by an optional sequence of digits representing the fractional part of the number. For example:  18.46 38.  The exponent, if present, specifies the magnitude of the number as a power of 10, as shown in the following example:  18.46e0      // 18.46 18.46e1      // 184.6  If an exponent is present, the trailing decimal point is unnecessary in whole numbers such as 18E0.  Floating-point constants default to type double. By using the suffixes f or l (or F or L — the suffix is not case sensitive), the constant can be specified as float or long double, respectively.  Although long double and double have the same representation, they are not the same type. For example, you can have overloaded functions like  void func( double );  and   void func( long double );

s=1/2*(zk[j+1][k]-zk[j][k])*(xk[j][k]*zk[j+1][k]-xk[j+1][k]*zk[j][k])             *log((xk[j+1][k]*xk[j+1][k]+zk[j+1][k]*zk[j+1][k])/(xk[j][k]*xk[j][k]+             zk[j][k]*zk[j][k]))/(pow(zk[j+1][k]-zk[j][k],2)+pow(xk[j+1][k]-xk[j][k],2)             +(xk[j+1][k]-xk[j][k])*(xk[j][k]*zk[j+1][k]-xk[j+1][k]*zk[j][k])/             (pow(zk[j+1][k]-zk[j][k],2)+pow(xk[j+1][k]-xk[j][k],2))*(atan1(zk[j][k],xk[j][k]             )-atan1(zk[j+1][k],xk[j+1][k]))); 1)这个式子太长了 2） 1/2 =0  1/2*(zk[j+1][k]-zk[j][k])*(xk[j][k]*zk[j+1][k]-xk[j+1][k]*zk[j][k])             *log((xk[j+1][k]*xk[j+1][k]+zk[j+1][k]*zk[j+1][k])/(xk[j][k]*xk[j][k]+ 这一部分可以省掉了，结果为0 如果 不希望得到0 ;写成1.0/2* ........    引用 5 楼 zhao4zhong1 的回复:将较长的表达式拆为若干步较短的表达式并将其中间结果赋值给中间变量，每步占一行，方便调试。 ++  这一次，赵老师，言简意赅，切中要害，不过标点太少，看着困难。

引用 1 楼 user-4 的回复:for(j=0;j<n+1;j++) { /*这个地方出问题*/ s=1/2*(zk[j+1][k]-zk[j][k])*(xk[j][k]*zk[j+1][k]-xk[j+1][k]*zk[j][k])             *log((xk[j+1][k]*xk[j+1][k]+zk[j+1][k]*zk[j+1][k])/(xk[j][k]*xk[j][k]+             zk[j][k]*zk[j][k]))/(pow(zk[j+1][k]-zk[j][k],2)+pow(xk[j+1][k]-xk[j][k],2)             +(xk[j+1][k]-xk[j][k])*(xk[j][k]*zk[j+1][k]-xk[j+1][k]*zk[j][k])/             (pow(zk[j+1][k]-zk[j][k],2)+pow(xk[j+1][k]-xk[j][k],2))*(atan1(zk[j][k],xk[j][k]             )-atan1(zk[j+1][k],xk[j+1][k])));             s1=+s; }  以上循环执行到j为6时，zk[j+1][k]、xk[j][k]等越界了。LZ要确认究竟是需要for(j=0;j<n+1;j++)还是for(j=0;j<n;j++)？如果是后者则不会越界，如果是前者，则需要增大zk、xk等;  谢谢  只需要执行6次  关键是计算出的值都是0

引用 2 楼 my_live_123 的回复:  for(j=0;j<n+1;j++)  兄台，这是7次循环，确定需要的7次而不是6次？ 嗯   是六次   但是计算出的值都是0 啊