Question: 关于纯C语言+API显示jpg图片的问题

引用 4 楼 qq_18599547 的回复:[quote=引用 3 楼 adlay 的回复:] [quote=引用 2 楼 qq_18599547 的回复:] [quote=引用 1 楼 adlay 的回复:] ppic->get_Width ( &hmWidth ); 是 C++ 里面的写法， 在 C 里面的话， 你得这样写了： ppic->lpVtbl->get_Width(ppic, &hmWidth);  然而我并没有发现有 lpVtbl 这个命令 - - ppic-> 直接是get_Width()[/quote] 你得看定义的 C 接口部分啊，别去看 C++ 的  ocidl.h 的 4297 行 （VC2005）：       interface IPicture     {         CONST_VTBL struct IPictureVtbl *lpVtbl;     };   其中 IPictureVtabl 的定义就在这个接口定义的前面  根据后面定义的几个宏来看，可以用这个宏来简化：  IPicture_get_Width(ppic,  &hmWidth);  宏展开后和 ppic->lpVtbl->get_Width(ppic, &hmWidth); 是等价的[/quote] 表示看不懂 我用的VC6.0         typedef struct IPictureVtbl     {         BEGIN_INTERFACE                  HRESULT ( STDMETHODCALLTYPE __RPC_FAR *QueryInterface )(              IPicture __RPC_FAR * This,             /* [in] */ REFIID riid,             /* [iid_is][out] */ void __RPC_FAR *__RPC_FAR *ppvObject);                  ULONG ( STDMETHODCALLTYPE __RPC_FAR *AddRef )(              IPicture __RPC_FAR * This);                  ULONG ( STDMETHODCALLTYPE __RPC_FAR *Release )(              IPicture __RPC_FAR * This);                  HRESULT ( STDMETHODCALLTYPE __RPC_FAR *get_Handle )(              IPicture __RPC_FAR * This,             /* [out] */ OLE_HANDLE __RPC_FAR *pHandle);                  HRESULT ( STDMETHODCALLTYPE __RPC_FAR *get_hPal )(              IPicture __RPC_FAR * This,             /* [out] */ OLE_HANDLE __RPC_FAR *phPal);                  HRESULT ( STDMETHODCALLTYPE __RPC_FAR *get_Type )(              IPicture __RPC_FAR * This,             /* [out] */ SHORT __RPC_FAR *pType);                  HRESULT ( STDMETHODCALLTYPE __RPC_FAR *get_Width )(              IPicture __RPC_FAR * This,             /* [out] */ OLE_XSIZE_HIMETRIC __RPC_FAR *pWidth);                  HRESULT ( STDMETHODCALLTYPE __RPC_FAR *get_Height )(              IPicture __RPC_FAR * This,             /* [out] */ OLE_YSIZE_HIMETRIC __RPC_FAR *pHeight);                  HRESULT ( STDMETHODCALLTYPE __RPC_FAR *Render )(              IPicture __RPC_FAR * This,             /* [in] */ HDC hDC,             /* [in] */ LONG x,             /* [in] */ LONG y,             /* [in] */ LONG cx,             /* [in] */ LONG cy,             /* [in] */ OLE_XPOS_HIMETRIC xSrc,             /* [in] */ OLE_YPOS_HIMETRIC ySrc,             /* [in] */ OLE_XSIZE_HIMETRIC cxSrc,             /* [in] */ OLE_YSIZE_HIMETRIC cySrc,             /* [in] */ LPCRECT pRcWBounds);                  HRESULT ( STDMETHODCALLTYPE __RPC_FAR *set_hPal )(              IPicture __RPC_FAR * This,             /* [in] */ OLE_HANDLE hPal);                  HRESULT ( STDMETHODCALLTYPE __RPC_FAR *get_CurDC )(              IPicture __RPC_FAR * This,             /* [out] */ HDC __RPC_FAR *phDC);                  HRESULT ( STDMETHODCALLTYPE __RPC_FAR *SelectPicture )(              IPicture __RPC_FAR * This,             /* [in] */ HDC hDCIn,             /* [out] */ HDC __RPC_FAR *phDCOut,             /* [out] */ OLE_HANDLE __RPC_FAR *phBmpOut);                  HRESULT ( STDMETHODCALLTYPE __RPC_FAR *get_KeepOriginalFormat )(              IPicture __RPC_FAR * This,             /* [out] */ BOOL __RPC_FAR *pKeep);                  HRESULT ( STDMETHODCALLTYPE __RPC_FAR *put_KeepOriginalFormat )(              IPicture __RPC_FAR * This,             /* [in] */ BOOL keep);                  HRESULT ( STDMETHODCALLTYPE __RPC_FAR *PictureChanged )(              IPicture __RPC_FAR * This);                  HRESULT ( STDMETHODCALLTYPE __RPC_FAR *SaveAsFile )(              IPicture __RPC_FAR * This,             /* [in] */ LPSTREAM pStream,             /* [in] */ BOOL fSaveMemCopy,             /* [out] */ LONG __RPC_FAR *pCbSize);                  HRESULT ( STDMETHODCALLTYPE __RPC_FAR *get_Attributes )(              IPicture __RPC_FAR * This,             /* [out] */ DWORD __RPC_FAR *pDwAttr);                  END_INTERFACE     } IPictureVtbl;      interface IPicture     {         CONST_VTBL struct IPictureVtbl __RPC_FAR *lpVtbl;     }; [/quote]  在看不懂的宏上跳转到定义去看下这些宏定义就懂了 C 语言的结构体没有成员函数一说，所以这里面都是放的函数指针，函数指针的语法本来也较难。  你先按照我给你说的改就行了。

引用 3 楼 adlay 的回复:[quote=引用 2 楼 qq_18599547 的回复:] [quote=引用 1 楼 adlay 的回复:] ppic->get_Width ( &hmWidth ); 是 C++ 里面的写法， 在 C 里面的话， 你得这样写了： ppic->lpVtbl->get_Width(ppic, &hmWidth);  然而我并没有发现有 lpVtbl 这个命令 - - ppic-> 直接是get_Width()[/quote] 你得看定义的 C 接口部分啊，别去看 C++ 的  ocidl.h 的 4297 行 （VC2005）：       interface IPicture     {         CONST_VTBL struct IPictureVtbl *lpVtbl;     };   其中 IPictureVtabl 的定义就在这个接口定义的前面  根据后面定义的几个宏来看，可以用这个宏来简化：  IPicture_get_Width(ppic,  &hmWidth);  宏展开后和 ppic->lpVtbl->get_Width(ppic, &hmWidth); 是等价的[/quote] 表示看不懂 我用的VC6.0         typedef struct IPictureVtbl     {         BEGIN_INTERFACE                  HRESULT ( STDMETHODCALLTYPE __RPC_FAR *QueryInterface )(              IPicture __RPC_FAR * This,             /* [in] */ REFIID riid,             /* [iid_is][out] */ void __RPC_FAR *__RPC_FAR *ppvObject);                  ULONG ( STDMETHODCALLTYPE __RPC_FAR *AddRef )(              IPicture __RPC_FAR * This);                  ULONG ( STDMETHODCALLTYPE __RPC_FAR *Release )(              IPicture __RPC_FAR * This);                  HRESULT ( STDMETHODCALLTYPE __RPC_FAR *get_Handle )(              IPicture __RPC_FAR * This,             /* [out] */ OLE_HANDLE __RPC_FAR *pHandle);                  HRESULT ( STDMETHODCALLTYPE __RPC_FAR *get_hPal )(              IPicture __RPC_FAR * This,             /* [out] */ OLE_HANDLE __RPC_FAR *phPal);                  HRESULT ( STDMETHODCALLTYPE __RPC_FAR *get_Type )(              IPicture __RPC_FAR * This,             /* [out] */ SHORT __RPC_FAR *pType);                  HRESULT ( STDMETHODCALLTYPE __RPC_FAR *get_Width )(              IPicture __RPC_FAR * This,             /* [out] */ OLE_XSIZE_HIMETRIC __RPC_FAR *pWidth);                  HRESULT ( STDMETHODCALLTYPE __RPC_FAR *get_Height )(              IPicture __RPC_FAR * This,             /* [out] */ OLE_YSIZE_HIMETRIC __RPC_FAR *pHeight);                  HRESULT ( STDMETHODCALLTYPE __RPC_FAR *Render )(              IPicture __RPC_FAR * This,             /* [in] */ HDC hDC,             /* [in] */ LONG x,             /* [in] */ LONG y,             /* [in] */ LONG cx,             /* [in] */ LONG cy,             /* [in] */ OLE_XPOS_HIMETRIC xSrc,             /* [in] */ OLE_YPOS_HIMETRIC ySrc,             /* [in] */ OLE_XSIZE_HIMETRIC cxSrc,             /* [in] */ OLE_YSIZE_HIMETRIC cySrc,             /* [in] */ LPCRECT pRcWBounds);                  HRESULT ( STDMETHODCALLTYPE __RPC_FAR *set_hPal )(              IPicture __RPC_FAR * This,             /* [in] */ OLE_HANDLE hPal);                  HRESULT ( STDMETHODCALLTYPE __RPC_FAR *get_CurDC )(              IPicture __RPC_FAR * This,             /* [out] */ HDC __RPC_FAR *phDC);                  HRESULT ( STDMETHODCALLTYPE __RPC_FAR *SelectPicture )(              IPicture __RPC_FAR * This,             /* [in] */ HDC hDCIn,             /* [out] */ HDC __RPC_FAR *phDCOut,             /* [out] */ OLE_HANDLE __RPC_FAR *phBmpOut);                  HRESULT ( STDMETHODCALLTYPE __RPC_FAR *get_KeepOriginalFormat )(              IPicture __RPC_FAR * This,             /* [out] */ BOOL __RPC_FAR *pKeep);                  HRESULT ( STDMETHODCALLTYPE __RPC_FAR *put_KeepOriginalFormat )(              IPicture __RPC_FAR * This,             /* [in] */ BOOL keep);                  HRESULT ( STDMETHODCALLTYPE __RPC_FAR *PictureChanged )(              IPicture __RPC_FAR * This);                  HRESULT ( STDMETHODCALLTYPE __RPC_FAR *SaveAsFile )(              IPicture __RPC_FAR * This,             /* [in] */ LPSTREAM pStream,             /* [in] */ BOOL fSaveMemCopy,             /* [out] */ LONG __RPC_FAR *pCbSize);                  HRESULT ( STDMETHODCALLTYPE __RPC_FAR *get_Attributes )(              IPicture __RPC_FAR * This,             /* [out] */ DWORD __RPC_FAR *pDwAttr);                  END_INTERFACE     } IPictureVtbl;      interface IPicture     {         CONST_VTBL struct IPictureVtbl __RPC_FAR *lpVtbl;     };

引用 2 楼 qq_18599547 的回复:[quote=引用 1 楼 adlay 的回复:] ppic->get_Width ( &hmWidth ); 是 C++ 里面的写法， 在 C 里面的话， 你得这样写了： ppic->lpVtbl->get_Width(ppic, &hmWidth);  然而我并没有发现有 lpVtbl 这个命令 - - ppic-> 直接是get_Width()[/quote] 你得看定义的 C 接口部分啊，别去看 C++ 的  ocidl.h 的 4297 行 （VC2005）：       interface IPicture     {         CONST_VTBL struct IPictureVtbl *lpVtbl;     };   其中 IPictureVtabl 的定义就在这个接口定义的前面  根据后面定义的几个宏来看，可以用这个宏来简化：  IPicture_get_Width(ppic,  &hmWidth);  宏展开后和 ppic->lpVtbl->get_Width(ppic, &hmWidth); 是等价的

引用 1 楼 adlay 的回复:ppic->get_Width ( &hmWidth ); 是 C++ 里面的写法， 在 C 里面的话， 你得这样写了： ppic->lpVtbl->get_Width(ppic, &hmWidth);  然而我并没有发现有 lpVtbl 这个命令 - - ppic-> 直接是get_Width()


Question: Run-Time Check Failure #2 - Stack around the variable 'tmp' was corrupted怎么办？

谢谢大家的回答，原来问题又是出在了细节之处。 要学习、要注意的问题真的很多啊！ 任重道远啊！ 大家一起加油！

不管是不是数组，你访问的内容超过了变量的长度，就会发生越界。  tmp 是一个 char， 只有 1 个字节大小。 scanf("%d"  中 %d 对应的是 int，它会访问传入的地址开始的 4 个字节的内容，你只有 1 个字节，访问就越界了。

scanf("%d", &tmp); tmp明明是char类型却要充当int, 那句错误信息说得很清楚吧


Question: C语言中关于字符数组的问题

引用 7 楼 q3733353520 的回复:a代表数组的首地址 &a代表数组的地址 虽然两者值相等，但意义不一样。你可以打印a+1和&a+1试试  正解

数组名本身可以理解成指向数组首元素的指针，所以值是一样的（注：数组名不是指针，只是你这种情况下可以这么理解）

打个比方，201班有很多学生，现在有人问你在哪儿上课，你可以说“201班”，也可以说“我上课的地址是2楼的第一个教室”，其实他们所代表的是一个意思。

楼上正解。。

C代表的是 数组C第一个成员的地址 &C 也是获取数组成员的第一个地址 也就是 一个变量首地址

不太理解 c 和 &c 为什么一样

数组名可以代表数组元素的首地址


Question: 为什么加了宏定义，在VS2013中可以使用gets，在VS2015中就不行了呢？

在vc6.0中可以使用gets 在vs中使用gets_s或直接使用fgets

gets很危险，使用fgets代替. gcc也不能用

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

还是提示相同的错误!

不好意思，这才是源码

VC6 for(int i .....) 循环完了还能用i, 旧的东西就是旧的东西. C11 标准中被弃用, 直接搜一下都有了 引用The most recent revision of the C standard (2011) has definitively removed this function from its specification. The function is deprecated in C++ (as of 2011 standard, which follows C99+TC3).

但是VS2013，在源文件中加了宏定义后，就可以使用gets函数了，为什么在VS2015中却不行呢？


Question: 用arcgis engine打开栅格数据 出现的问题 求大神解答

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


(*A).B 等价于 A->B

引用 10 楼 q3733353520 的回复:[quote=引用 9 楼 learnc2015 的回复:] [quote=引用 8 楼 q3733353520 的回复:] [quote=引用 7 楼 learnc2015 的回复:] [quote=引用 6 楼 q3733353520 的回复:] [quote=引用 1 楼 learnc2015 的回复:] 我刚才想了一下，对应红色部分，我是这样理解的，此时的*him表示取him保存的地址指向的内存区域的值，而此时的值包括结构体所有成员的值，因此*him.name也就能解释通顺了，我这样理解对吗?  对了一部分，它此时的值不是说是所有成员的值，就是结构体对象的值，因为它的类型是结构体的指针，编译器是根据类型来决定变量在类存中占用的位置大小的，也可以理解为    type fellow; type* him; him = &fellow;[/quote] "它此时的值不是说是所有成员的值，就是结构体对象的值" 有什么区别吗？[/quote]  对于某个变量的值，那样的说法是错误的[/quote] 变量没有值吗？[/quote]  我的意思是你把结构体变量的值说成是结构体变量所有成员的值这种说法是错误的，虽然意思到了[/quote] 不是每个成员都有自己的值吗？我也糊涂了

引用 9 楼 learnc2015 的回复:[quote=引用 8 楼 q3733353520 的回复:] [quote=引用 7 楼 learnc2015 的回复:] [quote=引用 6 楼 q3733353520 的回复:] [quote=引用 1 楼 learnc2015 的回复:] 我刚才想了一下，对应红色部分，我是这样理解的，此时的*him表示取him保存的地址指向的内存区域的值，而此时的值包括结构体所有成员的值，因此*him.name也就能解释通顺了，我这样理解对吗?  对了一部分，它此时的值不是说是所有成员的值，就是结构体对象的值，因为它的类型是结构体的指针，编译器是根据类型来决定变量在类存中占用的位置大小的，也可以理解为    type fellow; type* him; him = &fellow;[/quote] "它此时的值不是说是所有成员的值，就是结构体对象的值" 有什么区别吗？[/quote]  对于某个变量的值，那样的说法是错误的[/quote] 变量没有值吗？[/quote]  我的意思是你把结构体变量的值说成是结构体变量所有成员的值这种说法是错误的，虽然意思到了

引用 8 楼 q3733353520 的回复:[quote=引用 7 楼 learnc2015 的回复:] [quote=引用 6 楼 q3733353520 的回复:] [quote=引用 1 楼 learnc2015 的回复:] 我刚才想了一下，对应红色部分，我是这样理解的，此时的*him表示取him保存的地址指向的内存区域的值，而此时的值包括结构体所有成员的值，因此*him.name也就能解释通顺了，我这样理解对吗?  对了一部分，它此时的值不是说是所有成员的值，就是结构体对象的值，因为它的类型是结构体的指针，编译器是根据类型来决定变量在类存中占用的位置大小的，也可以理解为    type fellow; type* him; him = &fellow;[/quote] "它此时的值不是说是所有成员的值，就是结构体对象的值" 有什么区别吗？[/quote]  对于某个变量的值，那样的说法是错误的[/quote] 变量没有值吗？

引用 7 楼 learnc2015 的回复:[quote=引用 6 楼 q3733353520 的回复:] [quote=引用 1 楼 learnc2015 的回复:] 我刚才想了一下，对应红色部分，我是这样理解的，此时的*him表示取him保存的地址指向的内存区域的值，而此时的值包括结构体所有成员的值，因此*him.name也就能解释通顺了，我这样理解对吗?  对了一部分，它此时的值不是说是所有成员的值，就是结构体对象的值，因为它的类型是结构体的指针，编译器是根据类型来决定变量在类存中占用的位置大小的，也可以理解为    type fellow; type* him; him = &fellow;[/quote] "它此时的值不是说是所有成员的值，就是结构体对象的值" 有什么区别吗？[/quote]  对于某个变量的值，那样的说法是错误的

引用 6 楼 q3733353520 的回复:[quote=引用 1 楼 learnc2015 的回复:] 我刚才想了一下，对应红色部分，我是这样理解的，此时的*him表示取him保存的地址指向的内存区域的值，而此时的值包括结构体所有成员的值，因此*him.name也就能解释通顺了，我这样理解对吗?  对了一部分，它此时的值不是说是所有成员的值，就是结构体对象的值，因为它的类型是结构体的指针，编译器是根据类型来决定变量在类存中占用的位置大小的，也可以理解为    type fellow; type* him; him = &fellow;[/quote] "它此时的值不是说是所有成员的值，就是结构体对象的值" 有什么区别吗？

引用 1 楼 learnc2015 的回复:我刚才想了一下，对应红色部分，我是这样理解的，此时的*him表示取him保存的地址指向的内存区域的值，而此时的值包括结构体所有成员的值，因此*him.name也就能解释通顺了，我这样理解对吗?  对了一部分，它此时的值不是说是所有成员的值，就是结构体对象的值，因为它的类型是结构体的指针，编译器是根据类型来决定变量在类存中占用的位置大小的，也可以理解为    type fellow; type* him; him = &fellow;

引用 2 楼 sholber 的回复:这位兄台，只要举例，就是mm，这天天想mm都想疯鸟…… 如果一元运算符*的操作数是指向函数的指针，则结果是函数指示符；如果操作数是指向对象的指针，则结果是左值；如果操作数是指向类型T的指针，则结果的类型是T。 就算*运算符的结果是值不是左值，也可以适用于.运算符。如果 . 运算符的左操作数是值，则结果也是值；如果左操作数是左值，则结果也是左值。 谢谢，看了一下，还是不明白你说的左值和函数指示符是啥意思 http://blog.csdn.net/leichelle/article/details/6939138

引用 2 楼 sholber 的回复:这位兄台，只要举例，就是mm，这天天想mm都想疯鸟…… 如果一元运算符*的操作数是指向函数的指针，则结果是函数指示符；如果操作数是指向对象的指针，则结果是左值；如果操作数是指向类型T的指针，则结果的类型是T。 就算*运算符的结果是值不是左值，也可以适用于.运算符。如果 . 运算符的左操作数是值，则结果也是值；如果左操作数是左值，则结果也是左值。 皇上，难道你不想MM？,我是想的啊，那天我也有个MM

him指向的是结构体变量的首地址，假如him=&fellow，则*him==fellow，(*him).等同于fellow.   个人观点


Question: C语言是否有date型

可以通过这段代码获取当前时间：  #include <stdio.h> #include <time.h> #include <sys/timeb.h> #include <windows.h> int main(void) { 	struct tm *now; 	struct timeb tb; 	while (1) 	{ 		ftime(&tb); 		now = localtime(&tb.time); 		printf("%04d-%02d-%02d,%02d:%02d:%02d-%03d\n", now->tm_year + 1900, now->tm_mon + 1, now->tm_mday, now->tm_hour, now->tm_min, now->tm_sec, tb.millitm); 		Sleep(1000); 	} 	return 0; }

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

Date and time utilities

没有，只有一个tm结构体


Question: 一段简单的小程序看不懂求大家帮帮忙解释一下

#include <ctype.h>    /* atof:  convert string s to double */    double atof(char s[])    {        double val, power;        int i, sign;        for (i = 0; isspace(s[i]); i++)  /* skip white space */            ;        sign = (s[i] == '-') ? -1 : 1; //取符号        if (s[i] == '+' || s[i] == '-')            i++;          for (val = 0.0; isdigit(s[i]); i++)            val = 10.0 * val + (s[i] - '0'); //这边的val是整数部分        if (s[i] == '.') //跳过小数点            i++;        for (power = 1.0; isdigit(s[i]); i++) {            val = 10.0 * val + (s[i] - '0');//小数部分            power *= 10;//多一位小数就多乘一次10为最后的除法作准备        }        return sign * val / power;    }

引用 9 楼 u012033027 的回复:[quote=引用 4 楼 czwxp 的回复:] [quote=引用 2 楼 u012033027 的回复:]        for (i = 0; isspace(s[i]); i++)  /* skip white space */            ; 跳过空白符，唯一操作就是i++，所以为空白符的s[i]都被跳过了，接下来的s[i]是第一个非空字符。 而至于求小数部分操作：        for (power = 1.0; isdigit(s[i]); i++) {            val = 10.0 * val + (s[i] - '0');            power *= 10; 这个循环计算结束之后，val是个整数值。power是val要除的数。 例如，小数0.456经过计算之后，val是456，power是1000。456/1000=0/456。  它不是从小数点后面开始算的吗？ 它前面在碰到小数点之前不也是计算了一个val了吗？ 然后又在计算一次？就是这里好乱[/quote]  只有一个val，小数点之后才算完。如果是123.456，那么val＝123456，power＝1000[/quote]  谢谢了

引用 4 楼 czwxp 的回复:[quote=引用 2 楼 u012033027 的回复:]        for (i = 0; isspace(s[i]); i++)  /* skip white space */            ; 跳过空白符，唯一操作就是i++，所以为空白符的s[i]都被跳过了，接下来的s[i]是第一个非空字符。 而至于求小数部分操作：        for (power = 1.0; isdigit(s[i]); i++) {            val = 10.0 * val + (s[i] - '0');            power *= 10; 这个循环计算结束之后，val是个整数值。power是val要除的数。 例如，小数0.456经过计算之后，val是456，power是1000。456/1000=0/456。  它不是从小数点后面开始算的吗？ 它前面在碰到小数点之前不也是计算了一个val了吗？ 然后又在计算一次？就是这里好乱[/quote]  只有一个val，小数点之后才算完。如果是123.456，那么val＝123456，power＝1000

我觉得如果看不过来的时候，可以GDB跟踪 或者加打印看，这样就清楚了

引用 6 楼 yajuie的回复:本新手，推算一下代码思路，不对勿拍  它的思路大约是这样， 123.456，以字符串形式输入， 进入函数后检查字符串，前面是否有空格，和符号，有则跳过符号，把字符串转换成 123456，另外找个变量记算一下有几个位的小数，这里是3位，于是123456/1000=123.456 本新手，推算一下代码思路，不对勿拍  它的思路大约是这样， 123.456，以字符串形式输入， 进入函数后检查字符串，前面是否有空格，和符号，有则跳过符号，把字符串转换成 123456，另外找个变量记算一下有几个位的小数，这里是3位，于是123456/1000=123.456[/quote] 本新手，推算一下代码思路，不对勿拍  它的思路大约是这样， 123.456，以字符串形式输入， 进入函数后检查字符串，前面是否有空格，和符号，有则跳过符号，把字符串转换成 123456，另外找个变量记算一下有几个位的小数，这里是3位，于是123456/1000=123.456[/quote] 前面还有个变量记录了符号是+还是- 最后的结果 123.456*-1=-123.456 或者 123.456*1=123.456

引用 2 楼 u012033027 的回复:for (i = 0; isspace(s[i]); i++)  /* skip white space */            ; 跳过空白符，唯一操作就是i++，所以为空白符的s[i]都被跳过了，接下来的s[i]是第一个非空字符。 而至于求小数部分操作：        for (power = 1.0; isdigit(s[i]); i++) {            val = 10.0 * val + (s[i] - '0');            power *= 10; 这个循环计算结束之后，val是个整数值。power是val要除的数。 例如，小数0.456经过计算之后，val是456，power是1000。456/1000=0/456。  它不是从小数点后面开始算的吗？ 它前面在碰到小数点之前不也是计算了一个val了吗？ 然后又在计算一次？就是这里好乱

[quote=引用 1 楼 walkiz 的回复:] 把语句一条条拆开就容易理解，比如：  for (i = 0; isspace(s[i]); i++)  /* skip white space */     ;  可以拆解为：  i = 0; ]while(isspace(s[i]) {     i++; } [/quote  它是跳过所有空格还是只跳过一个第一个呢？ 这个while执行了多少次

把语句一条条拆开就容易理解，比如：  for (i = 0; isspace(s[i]); i++)  /* skip white space */     ;  可以拆解为：  i = 0; while(isspace(s[i]) {     i++; }


Question: fscanf参数无效

对学习编程者的忠告： 多用小脑和手，少用大脑、眼睛和嘴，会更快地学会编程！ 眼过千遍不如手过一遍！ 书看千行不如手敲一行！ 手敲千行不如单步一行！ 单步源代码千行不如单步Debug版对应汇编一行！ 单步Debug版对应汇编千行不如单步Release版对应汇编一行！

fscanf、fprintf往往是对文本文件读写的，打开方式是r、w，而不是二进制方式的rb、wb，他们与fread、fwrite配套

我猜测不是代码问题  也不是编译器问题。 编译器很少出问题 出问题几乎都是优化导致的异常 你应该接触不到 所以不要怀疑编译器当遇到问题呢时。 别说你刚学 就算学啦2年的C 你问他 在你学习生涯中 你遇到过几个编译器问题 导致程序逻辑异常的换个编译器就正常啦的。 不是特别底层 很少接触这类问题。如果是书上的代码 我感觉错的可能也比较低，写书的也不是白痴，都能写书啦，水准应该 不比你差。只是一般人写说 存在一种信息的不对称性，对于运行这个程序 作者并没有把一个新手在第一次运行这个程序会 出现的惯性思维考虑到，也没有注意提示什么的。 我猜测问题应该是这样的。  1.data.in   , data.out 这俩个文件存在吗？ 2.如果存在 你把他们放置的位置是.exe的同一目录吗?

判断下fopen的返回值

引用 1 楼 hnwyllmm 的回复:图片看不太清，fin是NULL吗？错误报的是这个，但是fin赋值了。

引用 2 楼 dustpg 的回复:"传递了一个无效参数视为严重错误", 这么大的字没看到么, 下面显示_Stream为NULL但是fin赋值了，不知为何是NULL

引用 8 楼 zhao4zhong1 的回复:#include<stdio.h> #include<stdlib.h> #pragma warning(disable:4996) int main() {     FILE *fin, *fout;     fin = fopen("data.in", "rb");     if (NULL==fin) {         printf("Can not open file data.in!\n");         return 1;     }     fout = fopen("data.out", "wb");     const int boundary = 0x7FFFFFFF;     int x, max = -boundary, min = boundary, numbers = 0, sum = 0;     while (fscanf(fin, "%d", &x) == 1)     {         if (x > boundary || x < -boundary) return 6;         if (x < min) min = x;         if (x > max) max = x;         numbers++;         sum += x;     }     fprintf(fout, "%d %d %d", max, min, sum / numbers);     fclose(fin);     fclose(fout);     return 0; } 变量还是被编译器优化了。但是加了volatile修饰依旧是被优化了。。。

引用 5 楼 q3733353520 的回复:判断下fopen的返回值找到问题了，变量被编译器优化了。但是加了volatile修饰依旧是被优化了。。。

图片看不太清，fin是NULL吗？


Question: 请问这样对结构体初始化为什么会出错？

引用 6 楼 均陵鼠侠的回复:[quote=引用 5 楼 ZhangBoyue 的回复:] [quote=引用 4 楼 sholber 的回复:] [quote=引用 3 楼 ZhangBoyue 的回复:] 编译器不是已经说了吗？语法不正确。 １，　struct all a = { .name = "helo" } 中，成员操作符　＂．＂ ２，　还是这一句，花括号对立面为什么写　name="hello" 呢？　按照c++的语法规则，这里的name 只能去两个地方找声明，花括号内和全局作用域。显然都是找不到的。　  再细细读读基本语法吧。  既然楼主问的是，错在哪，我就假设你已经知道正确的写法了。其实这条语句与其说是初始化，不如说是赋值。　c++环境的话，初始化最好用构造函数。  还有一个问题，ａ被分配以后，系统申请了10个byte的内存（即a.name )　指向的内存，楼主研究一下你把常量字符串的地址赋给a.name以后，这些内存怎么办　？　  囧……还是你自己好好读读语法吧。 从C99开始，可以使用指示器 .name = "hello"，这没有问题。 只是楼主的编译器太旧罢了。[/quote] g++  4.4.5 20110214 (Red Hat 4.4.5-6) Copyright (C) 2010 Free Software Foundation, Inc. This is free software; see the source for copying conditions.  There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 不算旧啊，可能是和微软诀别时间长了？　 [/quote]  微软的编译器对C的支持就不要提了。 现在的GCC版本是5.2.1。 我现在用台式机，只有笔记本上有Linux和gcc 只好用MinGW，而且特别旧，将就看吧：  [/quote] 弱弱的问一句，你的代码中为什么没有("%s",t.t),也能打印出字符串，是c99,的特性吗

引用 10 楼 ZhangBoyue 的回复:[quote=引用 8 楼 sholber 的回复:] N1570 Committee Draft — April 12, 2011 ISO/IEC 9899:201x  6.7.9 Initialization Syntax  initializer:           assignment-expression           { initializer-list }           { initializer-list , }      initializer-list:           designationopt initializer           initializer-list , designationopt initializer      designation:           designator-list =      designator-list:           designator           designator-list designator      designator:           [ constant-expression ]           . identifier 学习了，多谢。  另：楼主的程序里把常量字符串赋给数组的做法，虽然能通过编译、能得到预期行为、且没有内存泄露，但是是有问题的。[/quote]  有什么问题？

lz又来问, 不是说VS2015支持么, 这是C标准, 不是C++标准

引用 8 楼 sholber 的回复:N1570 Committee Draft — April 12, 2011 ISO/IEC 9899:201x  6.7.9 Initialization Syntax  initializer:           assignment-expression           { initializer-list }           { initializer-list , }      initializer-list:           designationopt initializer           initializer-list , designationopt initializer      designation:           designator-list =      designator-list:           designator           designator-list designator      designator:           [ constant-expression ]           . identifier 学习了，多谢。  另：楼主的程序里把常量字符串赋给数组的做法，虽然能通过编译、能得到预期行为、且没有内存泄露，但是是有问题的。

引用 6 楼 sholber 的回复:[quote=引用 5 楼 ZhangBoyue 的回复:] [quote=引用 4 楼 sholber 的回复:] [quote=引用 3 楼 ZhangBoyue 的回复:] 编译器不是已经说了吗？语法不正确。 １，　struct all a = { .name = "helo" } 中，成员操作符　＂．＂ ２，　还是这一句，花括号对立面为什么写　name="hello" 呢？　按照c++的语法规则，这里的name 只能去两个地方找声明，花括号内和全局作用域。显然都是找不到的。　  再细细读读基本语法吧。  既然楼主问的是，错在哪，我就假设你已经知道正确的写法了。其实这条语句与其说是初始化，不如说是赋值。　c++环境的话，初始化最好用构造函数。  还有一个问题，ａ被分配以后，系统申请了10个byte的内存（即a.name )　指向的内存，楼主研究一下你把常量字符串的地址赋给a.name以后，这些内存怎么办　？　  囧……还是你自己好好读读语法吧。 从C99开始，可以使用指示器 .name = "hello"，这没有问题。 只是楼主的编译器太旧罢了。[/quote] g++  4.4.5 20110214 (Red Hat 4.4.5-6) Copyright (C) 2010 Free Software Foundation, Inc. This is free software; see the source for copying conditions.  There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 不算旧啊，可能是和微软诀别时间长了？　 [/quote]  微软的编译器对C的支持就不要提了。 现在的GCC版本是5.2.1。 我现在用台式机，只有笔记本上有Linux和gcc 只好用MinGW，而且特别旧，将就看吧：  [/quote]  不好意思，您上条回复没有及时看见。第一次看见这么写，感觉好华丽的样子。

引用 4 楼 sholber 的回复:[quote=引用 3 楼 ZhangBoyue 的回复:] 编译器不是已经说了吗？语法不正确。 １，　struct all a = { .name = "helo" } 中，成员操作符　＂．＂ ２，　还是这一句，花括号对立面为什么写　name="hello" 呢？　按照c++的语法规则，这里的name 只能去两个地方找声明，花括号内和全局作用域。显然都是找不到的。　  再细细读读基本语法吧。  既然楼主问的是，错在哪，我就假设你已经知道正确的写法了。其实这条语句与其说是初始化，不如说是赋值。　c++环境的话，初始化最好用构造函数。  还有一个问题，ａ被分配以后，系统申请了10个byte的内存（即a.name )　指向的内存，楼主研究一下你把常量字符串的地址赋给a.name以后，这些内存怎么办　？　  囧……还是你自己好好读读语法吧。 从C99开始，可以使用指示器 .name = "hello"，这没有问题。 只是楼主的编译器太旧罢了。[/quote]  什么叫指示器？这是标准的语法还是微软自己的feature ？愿闻其详。

引用 5 楼 ZhangBoyue 的回复:[quote=引用 4 楼 sholber 的回复:] [quote=引用 3 楼 ZhangBoyue 的回复:] 编译器不是已经说了吗？语法不正确。 １，　struct all a = { .name = "helo" } 中，成员操作符　＂．＂ ２，　还是这一句，花括号对立面为什么写　name="hello" 呢？　按照c++的语法规则，这里的name 只能去两个地方找声明，花括号内和全局作用域。显然都是找不到的。　  再细细读读基本语法吧。  既然楼主问的是，错在哪，我就假设你已经知道正确的写法了。其实这条语句与其说是初始化，不如说是赋值。　c++环境的话，初始化最好用构造函数。  还有一个问题，ａ被分配以后，系统申请了10个byte的内存（即a.name )　指向的内存，楼主研究一下你把常量字符串的地址赋给a.name以后，这些内存怎么办　？　  囧……还是你自己好好读读语法吧。 从C99开始，可以使用指示器 .name = "hello"，这没有问题。 只是楼主的编译器太旧罢了。[/quote] g++  4.4.5 20110214 (Red Hat 4.4.5-6) Copyright (C) 2010 Free Software Foundation, Inc. This is free software; see the source for copying conditions.  There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 不算旧啊，可能是和微软诀别时间长了？　 [/quote]  微软的编译器对C的支持就不要提了。 现在的GCC版本是5.2.1。 我现在用台式机，只有笔记本上有Linux和gcc 只好用MinGW，而且特别旧，将就看吧：

引用 4 楼 sholber 的回复:[quote=引用 3 楼 ZhangBoyue 的回复:] 编译器不是已经说了吗？语法不正确。 １，　struct all a = { .name = "helo" } 中，成员操作符　＂．＂ ２，　还是这一句，花括号对立面为什么写　name="hello" 呢？　按照c++的语法规则，这里的name 只能去两个地方找声明，花括号内和全局作用域。显然都是找不到的。　  再细细读读基本语法吧。  既然楼主问的是，错在哪，我就假设你已经知道正确的写法了。其实这条语句与其说是初始化，不如说是赋值。　c++环境的话，初始化最好用构造函数。  还有一个问题，ａ被分配以后，系统申请了10个byte的内存（即a.name )　指向的内存，楼主研究一下你把常量字符串的地址赋给a.name以后，这些内存怎么办　？　  囧……还是你自己好好读读语法吧。 从C99开始，可以使用指示器 .name = "hello"，这没有问题。 只是楼主的编译器太旧罢了。[/quote] g++  4.4.5 20110214 (Red Hat 4.4.5-6) Copyright (C) 2010 Free Software Foundation, Inc. This is free software; see the source for copying conditions.  There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 不算旧啊，可能是和微软诀别时间长了？

引用 3 楼 ZhangBoyue 的回复:编译器不是已经说了吗？语法不正确。 １，　struct all a = { .name = "helo" } 中，成员操作符　＂．＂ ２，　还是这一句，花括号对立面为什么写　name="hello" 呢？　按照c++的语法规则，这里的name 只能去两个地方找声明，花括号内和全局作用域。显然都是找不到的。　  再细细读读基本语法吧。  既然楼主问的是，错在哪，我就假设你已经知道正确的写法了。其实这条语句与其说是初始化，不如说是赋值。　c++环境的话，初始化最好用构造函数。  还有一个问题，ａ被分配以后，系统申请了10个byte的内存（即a.name )　指向的内存，楼主研究一下你把常量字符串的地址赋给a.name以后，这些内存怎么办　？　  囧……还是你自己好好读读语法吧。 从C99开始，可以使用指示器 .name = "hello"，这没有问题。 只是楼主的编译器太旧罢了。

需要支持c99


Question: 写了一个测试文本文件的大小 字数的软件

引用 15 楼 qq936237071 的回复:[quote=引用 12 楼 ooolinux的回复:]不错，你们用的C教材是哪本？ 最近对c语言很喜欢！！！所以必须深入下。[/quote] 学校发的应该还是谭浩强？N年没变。

引用 13 楼 qq936237071 的回复:[quote=引用 12 楼 ooolinux的回复:]不错，你们用的C教材是哪本？ 用的那个太基础了   我都是自己图书馆合买  我以前基础很好[/quote] 自己图书馆合买？

C语言教程（附带C语言100例）http://download.csdn.net/detail/zhao4zhong1/8830817

引用 12 楼 ooolinux的回复:不错，你们用的C教材是哪本？ 最近对c语言很喜欢！！！所以必须深入下。

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

引用 12 楼 ooolinux的回复:不错，你们用的C教材是哪本？ 用的那个太基础了   我都是自己图书馆合买  我以前基础很好

不错，你们用的C教材是哪本？

引用 9 楼 弓长羊羽的回复:[quote=引用 8 楼 qq936237071 的回复:] [quote=引用 7 楼 弓长羊羽的回复:]就是获取文件大小…… 就是的  没有别的了  。   我c用的少    求指点  可以加我q  自学了6年了  可是没学c    我q在头像   微信也是q   [/quote] 多多指教！ http://blog.csdn.net/zhangxiangdavaid[/quote] 我才大一  最近对c语言比较感兴趣  以前都做得那种功能性的软件  自从专业课有c最近着迷了 太有魅力了

引用 8 楼 qq936237071 的回复:[quote=引用 7 楼 弓长羊羽的回复:]就是获取文件大小…… 就是的  没有别的了  。   我c用的少    求指点  可以加我q  自学了6年了  可是没学c    我q在头像   微信也是q   [/quote] 多多指教！ http://blog.csdn.net/zhangxiangdavaid

引用 7 楼 弓长羊羽的回复:就是获取文件大小…… 就是的  没有别的了  。   我c用的少    求指点  可以加我q  自学了6年了  可是没学c    我q在头像   微信也是q

就是获取文件大小……

各位大虾，以后c语言就和你们讨论了

这是代码  以后就用电脑账号吧  手机贴的图竟然挂了。。。

引用 1 楼 弓长羊羽的回复:看不清啊…… 图挂了   看我电脑上账号的

这是运行结果      貌似我不会贴代码！！！   将就着看。。。

#include<stdio.h> main() { long aaa;  long bbb; long ccc; printf("作者：企鹅 Q：936237071\n");  printf("路径中的斜杠使用双斜杠来打！\n");  char a[500];  FILE *fp; long size; printf("路径："); scanf("%s",&a); fp = fopen(a,"a+"); if(fp==NULL){ perror("打开文件失败！"); return; }  fseek(fp,0,SEEK_END); size=ftell(fp); fclose(fp); bbb=size/1024; ccc=bbb/1024; printf("文本文件大小是%ld字节，%ldKB，%ldMB",size,bbb,ccc); aaa=size/2; printf("   此文本有%ld个字",aaa);   }   这是我电脑上的号  刚才用的手机  这是代码  嘻嘻 图挂了

看不清啊……


Question: mfc显示文件内容

用下例中的HexDump函数将指定开始地址和长度的若干字节值写到日志文件中辅助调试。 //循环向a函数每次发送200个字节长度（这个是固定的）的buffer, //a函数中需要将循环传进来的buffer，组成240字节（也是固定的）的新buffer进行处理， //在处理的时候每次从新buffer中取两个字节打印 #ifdef WIN32     #pragma warning(disable:4996) #endif #include <stdio.h> #include <stdlib.h> #include <string.h> #ifdef WIN32     #include <windows.h>     #include <process.h>     #include <io.h>     #define  MYVOID             void     #define  vsnprintf          _vsnprintf #else     #include <unistd.h>     #include <sys/time.h>     #include <pthread.h>     #define  CRITICAL_SECTION   pthread_mutex_t     #define  MYVOID             void * #endif //Log{ #define MAXLOGSIZE 20000000 #define MAXLINSIZE 16000 #include <time.h> #include <sys/timeb.h> #include <stdarg.h> char logfilename1[]="MyLog1.log"; char logfilename2[]="MyLog2.log"; static char logstr[MAXLINSIZE+1]; char datestr[16]; char timestr[16]; char mss[4]; CRITICAL_SECTION cs_log; FILE *flog; #ifdef WIN32 void Lock(CRITICAL_SECTION *l) {     EnterCriticalSection(l); } void Unlock(CRITICAL_SECTION *l) {     LeaveCriticalSection(l); } void sleep_ms(int ms) {     Sleep(ms); } #else void Lock(CRITICAL_SECTION *l) {     pthread_mutex_lock(l); } void Unlock(CRITICAL_SECTION *l) {     pthread_mutex_unlock(l); } void sleep_ms(int ms) {     usleep(ms*1000); } #endif void LogV(const char *pszFmt,va_list argp) {     struct tm *now;     struct timeb tb;      if (NULL==pszFmt||0==pszFmt[0]) return;     vsnprintf(logstr,MAXLINSIZE,pszFmt,argp);     ftime(&tb);     now=localtime(&tb.time);     sprintf(datestr,"%04d-%02d-%02d",now->tm_year+1900,now->tm_mon+1,now->tm_mday);     sprintf(timestr,"%02d:%02d:%02d",now->tm_hour     ,now->tm_min  ,now->tm_sec );     sprintf(mss,"%03d",tb.millitm);     printf("%s %s.%s %s",datestr,timestr,mss,logstr);     flog=fopen(logfilename1,"a");     if (NULL!=flog) {         fprintf(flog,"%s %s.%s %s",datestr,timestr,mss,logstr);         if (ftell(flog)>MAXLOGSIZE) {             fclose(flog);             if (rename(logfilename1,logfilename2)) {                 remove(logfilename2);                 rename(logfilename1,logfilename2);             }         } else {             fclose(flog);         }     } } void Log(const char *pszFmt,...) {     va_list argp;      Lock(&cs_log);     va_start(argp,pszFmt);     LogV(pszFmt,argp);     va_end(argp);     Unlock(&cs_log); } //Log} #define ASIZE    200 #define BSIZE    240 #define CSIZE      2 char Abuf[ASIZE]; char Cbuf[CSIZE]; CRITICAL_SECTION cs_HEX ; CRITICAL_SECTION cs_BBB ; struct FIFO_BUFFER {     int  head;     int  tail;     int  size;     char data[BSIZE]; } BBB; int No_Loop=0; void HexDump(int cn,char *buf,int len) {     int i,j,k;     char binstr[80];      Lock(&cs_HEX);     for (i=0;i<len;i++) {         if (0==(i%16)) {             sprintf(binstr,"%03d %04x -",cn,i);             sprintf(binstr,"%s %02x",binstr,(unsigned char)buf[i]);         } else if (15==(i%16)) {             sprintf(binstr,"%s %02x",binstr,(unsigned char)buf[i]);             sprintf(binstr,"%s  ",binstr);             for (j=i-15;j<=i;j++) {                 sprintf(binstr,"%s%c",binstr,('!'<buf[j]&&buf[j]<='~')?buf[j]:'.');             }             Log("%s\n",binstr);         } else {             sprintf(binstr,"%s %02x",binstr,(unsigned char)buf[i]);         }     }     if (0!=(i%16)) {         k=16-(i%16);         for (j=0;j<k;j++) {             sprintf(binstr,"%s   ",binstr);         }         sprintf(binstr,"%s  ",binstr);         k=16-k;         for (j=i-k;j<i;j++) {             sprintf(binstr,"%s%c",binstr,('!'<buf[j]&&buf[j]<='~')?buf[j]:'.');         }         Log("%s\n",binstr);     }     Unlock(&cs_HEX); } int GetFromRBuf(int cn,CRITICAL_SECTION *cs,FIFO_BUFFER *fbuf,char *buf,int len) {     int lent,len1,len2;      lent=0;     Lock(cs);     if (fbuf->size>=len) {         lent=len;         if (fbuf->head+lent>BSIZE) {             len1=BSIZE-fbuf->head;             memcpy(buf     ,fbuf->data+fbuf->head,len1);             len2=lent-len1;             memcpy(buf+len1,fbuf->data           ,len2);             fbuf->head=len2;         } else {             memcpy(buf     ,fbuf->data+fbuf->head,lent);             fbuf->head+=lent;         }         fbuf->size-=lent;     }     Unlock(cs);     return lent; } MYVOID thdB(void *pcn) {     char        *recv_buf;     int          recv_nbytes;     int          cn;     int          wc;     int          pb;      cn=(int)pcn;     Log("%03d thdB              thread begin...\n",cn);     while (1) {         sleep_ms(10);         recv_buf=(char *)Cbuf;         recv_nbytes=CSIZE;         wc=0;         while (1) {             pb=GetFromRBuf(cn,&cs_BBB,&BBB,recv_buf,recv_nbytes);             if (pb) {                 Log("%03d recv %d bytes\n",cn,pb);                 HexDump(cn,recv_buf,pb);                 sleep_ms(1);             } else {                 sleep_ms(1000);             }             if (No_Loop) break;//             wc++;             if (wc>3600) Log("%03d %d==wc>3600!\n",cn,wc);         }         if (No_Loop) break;//     } #ifndef WIN32     pthread_exit(NULL); #endif } int PutToRBuf(int cn,CRITICAL_SECTION *cs,FIFO_BUFFER *fbuf,char *buf,int len) {     int lent,len1,len2;      Lock(cs);     lent=len;     if (fbuf->size+lent>BSIZE) {         lent=BSIZE-fbuf->size;     }     if (fbuf->tail+lent>BSIZE) {         len1=BSIZE-fbuf->tail;         memcpy(fbuf->data+fbuf->tail,buf     ,len1);         len2=lent-len1;         memcpy(fbuf->data           ,buf+len1,len2);         fbuf->tail=len2;     } else {         memcpy(fbuf->data+fbuf->tail,buf     ,lent);         fbuf->tail+=lent;     }     fbuf->size+=lent;     Unlock(cs);     return lent; } MYVOID thdA(void *pcn) {     char        *send_buf;     int          send_nbytes;     int          cn;     int          wc;     int           a;     int          pa;      cn=(int)pcn;     Log("%03d thdA              thread begin...\n",cn);     a=0;     while (1) {         sleep_ms(100);         memset(Abuf,a,ASIZE);         a=(a+1)%256;         if (16==a) {No_Loop=1;break;}//去掉这句可以让程序一直循环直到按Ctrl+C或Ctrl+Break或当前目录下存在文件No_Loop         send_buf=(char *)Abuf;         send_nbytes=ASIZE;         Log("%03d sending %d bytes\n",cn,send_nbytes);         HexDump(cn,send_buf,send_nbytes);         wc=0;         while (1) {             pa=PutToRBuf(cn,&cs_BBB,&BBB,send_buf,send_nbytes);             Log("%03d sent %d bytes\n",cn,pa);             HexDump(cn,send_buf,pa);             send_buf+=pa;             send_nbytes-=pa;             if (send_nbytes<=0) break;//             sleep_ms(1000);             if (No_Loop) break;//             wc++;             if (wc>3600) Log("%03d %d==wc>3600!\n",cn,wc);         }         if (No_Loop) break;//     } #ifndef WIN32     pthread_exit(NULL); #endif } int main() { #ifdef WIN32     InitializeCriticalSection(&cs_log);     InitializeCriticalSection(&cs_HEX );     InitializeCriticalSection(&cs_BBB ); #else     pthread_t threads[2];     int threadsN;     int rc;     pthread_mutex_init(&cs_log,NULL);     pthread_mutex_init(&cs_HEX,NULL);     pthread_mutex_init(&cs_BBB,NULL); #endif     Log("Start===========================================================\n");      BBB.head=0;     BBB.tail=0;     BBB.size=0;  #ifdef WIN32     _beginthread((void(__cdecl *)(void *))thdA,0,(void *)1);     _beginthread((void(__cdecl *)(void *))thdB,0,(void *)2); #else     threadsN=0;     rc=pthread_create(&(threads[threadsN++]),NULL,thdA,(void *)1);if (rc) Log("%d=pthread_create %d error!\n",rc,threadsN-1);     rc=pthread_create(&(threads[threadsN++]),NULL,thdB,(void *)2);if (rc) Log("%d=pthread_create %d error!\n",rc,threadsN-1); #endif      if (!access("No_Loop",0)) {         remove("No_Loop");         if (!access("No_Loop",0)) {             No_Loop=1;         }     }     while (1) {         sleep_ms(1000);         if (No_Loop) break;//         if (!access("No_Loop",0)) {             No_Loop=1;         }     }     sleep_ms(3000);     Log("End=============================================================\n"); #ifdef WIN32     DeleteCriticalSection(&cs_BBB );     DeleteCriticalSection(&cs_HEX );     DeleteCriticalSection(&cs_log); #else     pthread_mutex_destroy(&cs_BBB);     pthread_mutex_destroy(&cs_HEX);     pthread_mutex_destroy(&cs_log); #endif     return 0; }

////////////////我现在改了一下,读取一个结构体//////////////////// if ( IDOK ==campare.DoModal() ) //点击“打开” 	{ 		CString cs_pathname = campare.GetPathName(); 		char *pathname = (LPSTR)(LPCTSTR)cs_pathname; 		CFile i00file; 		i00file.Open(pathname,CFile::modeRead|CFile::typeBinary); 		MriFileHeader myfilehead; 		i00file.Read(&myfilehead,sizeof(MriFileHeader)); //这里发现读出来的结构体是对的 		i00file.Close(); 		char *buffer = new char[sizeof(MriFileHeader)+1]; 		memset(buffer,0,sizeof(MriFileHeader)+1); 		memcpy(buffer,&myfilehead,sizeof(MriFileHeader)); //这里拷贝过来就不对了，只有一行字母，                                                                                字母是对的（结构体里有很多种数据类型） //////////////////////////////////想知道为什么///////////////////////////////////////////////////////

引用 4 楼 user-3 的回复:i00file.Open(pathname,CFile::modeRead|CFile::typeBinary); 直接调用cs_pathname i00file.Open(cs_pathname,CFile::modeRead|CFile::typeBinary);应该就可以了吧  这个我真不知道可以直接用，可是我那样写也没问题，文件途径是对的。

引用 4 楼 user-3 的回复:i00file.Open(pathname,CFile::modeRead|CFile::typeBinary); 直接调用cs_pathname i00file.Open(cs_pathname,CFile::modeRead|CFile::typeBinary);应该就可以了吧 长度是15680，是对的...

long length = i00file.GetLength(); 你看看length的长度就知道了

char *pathname = (LPSTR)(LPCTSTR)cs_pathname; 这个有问题吧，没看明白为什么要将TCHAR的cs_pathname转成char的pathname

引用 楼主 U201212366 的回复:我想把文件内容在edit control中显示出来，代码如下： if ( IDOK ==campare.DoModal() ) //点击“打开” 	{ 		CString cs_pathname = campare.GetPathName(); 		char *pathname = (LPSTR)(LPCTSTR)cs_pathname; 		CFile i00file; 		i00file.Open(pathname,CFile::modeRead|CFile::typeBinary); 		long length = i00file.GetLength(); 		char *buffer = new char[length+1]; 		memset(buffer,0,length+1); 		i00file.Read(buffer,length);  //单步调试到buffer这里发现只有几个字母 		pathname = buffer; 		SetDlgItemText(IDC_EDIT1,pathname); 		i00file.Close(); 		delete []buffer;  	} 请问问题在哪，我又该如何实现 多谢

MSDN98_1.ISO http://pan.baidu.com/s/1dDF41ix,  MSDN98_2.ISO http://pan.baidu.com/s/1bnGo0Vl 先下载安装MSDN98  再参考其自带的相关例子代码。


Question: 文件读取和输入的小问题，指针数组的初始化

我用 gcc 可以编译过去，没问题

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


Question: 请教：空链接到底有什么用？

链接，又称连接（纯属翻译问题），就是程序由源文件，首先编译成obj文件，然后是各个obj文件链接成exe文件。 在编译阶段，变量（包括普通变量，函数也是变量，用类生成的一个对象也是变量）在使用前， 需要有声明（要分清变量的声明与定义，普通变量及类的对象默认是定义，加上extern就是声明；函数原型就是声明，函数原型加函数体就是定义）， 就通过编译。 通过编译后，还需要通过链接，就是声明的变量，要能够找到。 所谓空链接，就是在链接时，变量被隐藏了，链接器找不到，通常一些非全局变量，都是空链接的。 所谓内部链接，就是定义的变量，obj内部可以访问，外部obj无法访问，通常加上static关键字定义的都是内部链接。 所谓外部链接，就是内部外部都可能访问，没有static修饰的全局变量和全局函数都是外部链接  链接是针对变量而言，对于没有实例化的类型而言，由于没有地址，根本谈不上链接。类型定义是给编译器看的，而不是链接器。

引用 6 楼 learnc2015 的回复:[quote=引用 5 楼 sholber 的回复:] [quote=引用 4 楼 learnc2015 的回复:] [quote=引用 2 楼 sholber 的回复:] 没听说过空链接。不知道是啥东西。 参考C PRIMER PLUS 第五版 第321(存储类、链接、和内存管理)、323页[/quote]  链接属性只分有无，不存在是空的还是实的。纯属翻译的问题。 标识符的链接是个讲起来麻烦的东西。 每个无链接的标识符都指示一个单独的实体。如果一个标识符不是被声明为对象或者函数（而是声明为其它一些东西，诸如typedef名、结构标记、联合标记和枚举标记，等等），或者，它被声明为函数参数，又或者，它指示一个对象，但只有块作用域且在声明时不包含存储类指定符extern，那么，它是无链接的。 所以，下例中的标识符F、t、g、e、Male、Female和a都是无链接的。 typedef void F (int, int); struct t {/* …… */}; enum e {Male, Female,}; int f (void g (const char *)) { 	char a [] = "Pride and Prejudice.\n"; g (a);     /* …… */ } [/quote] t是有链接的吧！外部链接[/quote] t仅仅是一个类型标记，不指示任何对象或者函数，仅这一条就已经不符合了。

引用 5 楼 sholber 的回复:[quote=引用 4 楼 learnc2015 的回复:] [quote=引用 2 楼 sholber 的回复:] 没听说过空链接。不知道是啥东西。 参考C PRIMER PLUS 第五版 第321(存储类、链接、和内存管理)、323页[/quote]  链接属性只分有无，不存在是空的还是实的。纯属翻译的问题。 标识符的链接是个讲起来麻烦的东西。 每个无链接的标识符都指示一个单独的实体。如果一个标识符不是被声明为对象或者函数（而是声明为其它一些东西，诸如typedef名、结构标记、联合标记和枚举标记，等等），或者，它被声明为函数参数，又或者，它指示一个对象，但只有块作用域且在声明时不包含存储类指定符extern，那么，它是无链接的。 所以，下例中的标识符F、t、g、e、Male、Female和a都是无链接的。 typedef void F (int, int); struct t {/* …… */}; enum e {Male, Female,}; int f (void g (const char *)) { 	char a [] = "Pride and Prejudice.\n"; g (a);     /* …… */ } [/quote] t是有链接的吧！外部链接

引用 4 楼 learnc2015 的回复:[quote=引用 2 楼 sholber 的回复:] 没听说过空链接。不知道是啥东西。 参考C PRIMER PLUS 第五版 第321(存储类、链接、和内存管理)、323页[/quote]  链接属性只分有无，不存在是空的还是实的。纯属翻译的问题。 标识符的链接是个讲起来麻烦的东西。 每个无链接的标识符都指示一个单独的实体。如果一个标识符不是被声明为对象或者函数（而是声明为其它一些东西，诸如typedef名、结构标记、联合标记和枚举标记，等等），或者，它被声明为函数参数，又或者，它指示一个对象，但只有块作用域且在声明时不包含存储类指定符extern，那么，它是无链接的。 所以，下例中的标识符F、t、g、e、Male、Female和a都是无链接的。 typedef void F (int, int); struct t {/* …… */}; enum e {Male, Female,}; int f (void g (const char *)) { 	char a [] = "Pride and Prejudice.\n"; g (a);     /* …… */ }

引用 2 楼 sholber 的回复:没听说过空链接。不知道是啥东西。 参考C PRIMER PLUS 第五版 第321(存储类、链接、和内存管理)、323页

引用 1 楼 zhangxiangDavaid 的回复:空链接 https://www.baidu.com/s?ie=utf-8&f=8&rsv_bp=1&rsv_idx=1&tn=baidu&wd=空链接&oq=fmod&rsv_pq=fabde15e0003918f&rsv_t=5823AaYN%2B6hrV7gNY%2FjBqN5r%2BigCtYJUjh3cwhlBGI3S4U8IdMKTLosDnw4&rsv_enter=1&inputT=11495&rsv_sug3=15&rsv_sug1=11&rsv_n=2&bs=VC6设置字体大小  参考C PRIMER PLUS 第五版 第321(存储类、链接、和内存管理)、323页

没听说过空链接。不知道是啥东西。


Question: 请教：变量到底是在编译的时候初始化的，还是在运行的时候初始化的？

不是应该打印2，3 吗？为啥是1， 2~！

代码：int f (void) {     static int mm=1;     mm++;     printf("%d\n",mm); }可以理解为：int mm=1; int f (void) {     mm++;     printf("%d\n",mm); }且 mm 仅在函数 f 内可见

引用 5 楼 zhao4zhong1 的回复:有的变量是在编译的时候初始化的，有的变量是在运行的时候初始化的。 通常编译时能够进行的计算编译时就完成了， 如常量计算一类的

引用 42 楼 worldy 的回复:[quote=引用 40 楼 sholber 的回复:] [quote=引用 37 楼 worldy 的回复:] [quote=引用 14 楼 sholber 的回复:] [quote=引用 11 楼 zhao4zhong1 的回复:] 编译的时候没初始化，那代码段汇编指令中的常量是谁写上去的？  1，汇编指令中还有常量，这个没听说过； 2，初始化是什么意思，赵老师学C数十载，竟然到现在还没弄明白。 赵老湿以为朕是外国人，不懂中国话吗！[/quote]  编译器写的，比如函数体中有 static n=100; n=n++;   编译器会将n放到程序读数据段的某个磁盘单元并且将其值设置为100，exe被加载的时候，整个数据段会原封不动的加载到内存，因此和n对应的存储单元就有100的起始值 [/quote]  首先，你所说的，是业界流行的做法，但流行不代表就是确凿证据。人人都走阳关大道和捷径，但驴友就喜欢走没有路的偏僻丛林，你说不行？如果编译器只在EXE里为n保留一个位置，然后在程序开始执行的时候才用mov指针加一个立即数将100写到n对应的存储单元，难道不行？ 其次，初始化这个词本身就没找到完整的定义，讨论起来自然各说各的。就像你说的，整个数据段加载到内存，这个覆盖内存原来东西的操作，不能叫初始化？ 最后，n=n++不是一个有确定行为的表达式，赵老师会让你看置顶帖的。[/quote]  按照你的MOV方法进行初始化，那如果我初始化的是一个表呢？编译器创建一个循环还是一个数据生成一条初始化指令？ n=n++是我写错了，你也不用太在意 [/quote]  干嘛钻牛角尖，我的意思很简单，不要拿C实现的细节，什么段啊、堆啊栈啊说事，解决这个问题不需要这些东西，解决C的问题也不需要钻到这个层次。 好吧，如果是初始化一个表，这个表及其元素都只具有自动存储期，那么，我宁愿使用MOV指令的序列。

引用 40 楼 sholber 的回复:[quote=引用 37 楼 worldy 的回复:] [quote=引用 14 楼 sholber 的回复:] [quote=引用 11 楼 zhao4zhong1 的回复:] 编译的时候没初始化，那代码段汇编指令中的常量是谁写上去的？  1，汇编指令中还有常量，这个没听说过； 2，初始化是什么意思，赵老师学C数十载，竟然到现在还没弄明白。 赵老湿以为朕是外国人，不懂中国话吗！[/quote]  编译器写的，比如函数体中有 static n=100; n=n++;   编译器会将n放到程序读数据段的某个磁盘单元并且将其值设置为100，exe被加载的时候，整个数据段会原封不动的加载到内存，因此和n对应的存储单元就有100的起始值 [/quote]  首先，你所说的，是业界流行的做法，但流行不代表就是确凿证据。人人都走阳关大道和捷径，但驴友就喜欢走没有路的偏僻丛林，你说不行？如果编译器只在EXE里为n保留一个位置，然后在程序开始执行的时候才用mov指针加一个立即数将100写到n对应的存储单元，难道不行？ 其次，初始化这个词本身就没找到完整的定义，讨论起来自然各说各的。就像你说的，整个数据段加载到内存，这个覆盖内存原来东西的操作，不能叫初始化？ 最后，n=n++不是一个有确定行为的表达式，赵老师会让你看置顶帖的。[/quote]  按照你的MOV方法进行初始化，那如果我初始化的是一个表呢？编译器创建一个循环还是一个数据生成一条初始化指令？ n=n++是我写错了，你也不用太在意

静态和全局变量的初始化操作确实是编译后保存在文件中的。 具体实验方法可以用二进制修改器，修改EXE中静态变量的值，然后直接启动EXE看是原来未修改的值，还是修改后的值。  程序加载后，会在main函数之前将各种数据初始化，其中也包括着全局和静态。  PE里面也可以看出来，前面有人讲过了，不阐述了。。  汇编前面看大家讨论了这么多，就不参合了，其实全局变量赋值的形式就是一个偏移地址的值，反汇编看的话其实唯一的区别是main函数前还是main函数后给的，进入main函数前就赋值到内存里了的话，就是说明程序在加载入内存的时候，全局变量已经有值了。 不过这个不具代表性，因为如果是自定义程序入口函数，自己裁剪一下一切皆有可能。

引用 31 楼 zhao4zhong1 的回复:闲来无事去读读gcc或g++源代码killtime吧。  读killtimr？ 赵老师的意思是他很渊博，视野开阔，看了不少源代码。但他忘了，正是他象老婆婆一样，总在劝大家不轻信、不盲从。信别人不信sholber，赵老师看来并不如他自诩的那样客观罢。

闲来无事去读读gcc或g++源代码killtime吧。

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

盲人摸太阳 说是一物即不中

引用 26 楼 user-8 的回复:int a =10； 可以编译为  push eax  mov eax,10  mov  ebp[a],eax //自动变量 ，全局的话 一般是 mov a,eax .。。。。。 pop  eax   int a[]={10,9,8,7,6,5,4} : 就 很难 编译为这种代码 可能就成为  （全局数组 ） a dd 10，9，8，7，6 ,5,4 了 也可能编译为(自动数组) a_tmp dd  10，9，8，7，6 ,5,4  了//数据  然后 //代码 push esi push edi push  ecx mov esi ,a_tmp lea  edi,a[ebp] rep movsd  。。。。  pop ecx pop edi pop esi 常量（表达式），编译成 立即数是很平常的， 变量，某种情况下也可能优化成常量，最终编译成立即数 串字面值 整型，浮点型，数组初始化列表，经常编译成 全局数据 用DB,DW,DD,DF,DQ,TB等伪指令定义 结构,类，可能编译为 结构类型 这一类初始化表，可能用结构定义方式定义 也可能用宏（宏指令）来定义 另外，由于编译器的各种策略，编译选项不同，可以用很多种不同的方法 ，编译同样的C,C++代码 修正一下

引用 26 楼 user-8 的回复:int a =10； 可以编译为 mov  ebp[a],10 int a[]={10,9,8,7,6,5,4} : 就 很难 编译为这种代码 可能就成为  a dd 10，9，8，7，6 ,5,4 了 也可能编译为 a_tmp dd  10，9，8，7，6 ,5,4  了//数据  然后 //代码 push esi push edi push  ecx mov esi ,a_tmp lea  edi,a[ebp] rep movsd   常量（表达式），编译成 立即数是很平常的， 变量，某种情况下也可能优化成常量，最终编译成立即数 串字面值 整型，浮点型，数组初始化列表，经常编译成 全局数据 用DB,DW,DD,DF,DQ,TB等伪指令定义 结构,类，可能编译为 结构类型 这一类初始化表，可能用结构定义方式定义 也可能用宏（宏指令）来定义 另外，由于编译器的各种策略，编译选项不同，可以用很多种不同的方法 ，编译同样的C,C++代码 皇上，我是这么理解，初始化必须在内存里赋值才算是初始化 编译的时候赋值不算真正的初始化 我这样理解是否正确？

引用 38 楼 worldy 的回复:[quote=引用 29 楼 zhao4zhong1 的回复:] 盲人摸太阳 说是一物即不中  赵老师开始摸太阳了啊？[/quote] 太阳他辈子怕是摸不着了，朕建议他摸电烙铁，其实也挺烫的。

引用 37 楼 worldy 的回复:[quote=引用 14 楼 sholber 的回复:] [quote=引用 11 楼 zhao4zhong1 的回复:] 编译的时候没初始化，那代码段汇编指令中的常量是谁写上去的？  1，汇编指令中还有常量，这个没听说过； 2，初始化是什么意思，赵老师学C数十载，竟然到现在还没弄明白。 赵老湿以为朕是外国人，不懂中国话吗！[/quote]  编译器写的，比如函数体中有 static n=100; n=n++;   编译器会将n放到程序读数据段的某个磁盘单元并且将其值设置为100，exe被加载的时候，整个数据段会原封不动的加载到内存，因此和n对应的存储单元就有100的起始值 [/quote]  首先，你所说的，是业界流行的做法，但流行不代表就是确凿证据。人人都走阳关大道和捷径，但驴友就喜欢走没有路的偏僻丛林，你说不行？如果编译器只在EXE里为n保留一个位置，然后在程序开始执行的时候才用mov指针加一个立即数将100写到n对应的存储单元，难道不行？ 其次，初始化这个词本身就没找到完整的定义，讨论起来自然各说各的。就像你说的，整个数据段加载到内存，这个覆盖内存原来东西的操作，不能叫初始化？ 最后，n=n++不是一个有确定行为的表达式，赵老师会让你看置顶帖的。

引用 24 楼 sholber 的回复:[quote=引用 22 楼 learnc2015 的回复:] [quote=引用 20 楼 zhao4zhong1 的回复:] 别跟我说被编译器优化为立即数的取值不变的变量不是变量。 看来皇上错了？[/quote]  你要跟老赵辩论问题，认真就输了。他会胡搅蛮缠，没完没了。[/quote] 回皇上，我对赵老师还是很葱白的，赵老师很热心，很愿意帮助别人， 心里是很感激赵老师的 不过皇上的功力也是非凡，也很热心，让我很感动，真皇恩浩荡啊

引用 22 楼 learnc2015 的回复:[quote=引用 20 楼 zhao4zhong1 的回复:] 别跟我说被编译器优化为立即数的取值不变的变量不是变量。 看来皇上错了？[/quote]  你要跟老赵辩论问题，认真就输了。他会胡搅蛮缠，没完没了。

引用 29 楼 zhao4zhong1 的回复:盲人摸太阳 说是一物即不中  赵老师开始摸太阳了啊？

引用 14 楼 sholber 的回复:[quote=引用 11 楼 zhao4zhong1 的回复:] 编译的时候没初始化，那代码段汇编指令中的常量是谁写上去的？  1，汇编指令中还有常量，这个没听说过； 2，初始化是什么意思，赵老师学C数十载，竟然到现在还没弄明白。 赵老湿以为朕是外国人，不懂中国话吗！[/quote]  编译器写的，比如函数体中有 static n=100; n=n++;   编译器会将n放到程序读数据段的某个磁盘单元并且将其值设置为100，exe被加载的时候，整个数据段会原封不动的加载到内存，因此和n对应的存储单元就有100的起始值


Question: 关于extern和int main（）的结构问题

引用 1 楼 zhangxiangDavaid 的回复:去掉extern声明试试 哦哦哦，明白了，已经解决，谢谢啦～～

引用 1 楼 zhangxiangDavaid 的回复:去掉extern声明试试 额...咋去？直接删掉那两个extern？？

去掉extern声明试试


Question: 为什么VS2015编译不通过？

这种语法是GCC的扩展语法吧，VS貌似没支持

c++没这种语法吧


Question: 请问VS2013在写源码的时候，比如我输入{后面的}和;会自动加上去，那么我括号内的代码打完后，除了鼠标，还有什么办法可以到;后面继续写？

除了这个之外呢？

用键盘上的左右上下键

Ctrl+F打开快速查找 输入 }; ，按F3定位到类定义末尾 Esc关闭快速查找 Ctrl+Shift+Enter插入新行


Question: 今天看到一个题目，是这样的

如果是面试。这应该是故意引导，如果是考试。楼主的题一定抄错了。

测试一下：  int aaa(char * s) { 	char *t = s; 	while (*t++);     //添加分号 	t--; 	return (t - s); } int main(void) { 	char *s = "zhangxiang"; 	printf("%d %d\n", aaa(s), strlen(s)); 	return 0; } //10 10 等同于strlen函数

int aaa(char * s) { 	char *t = s; 	while(*t++); 	t--; 	return (t -s); }  while(*t++);少了一个分号，要不然while()循环是退不出来的

若s非空，死循环了，若s空，程序存在大bug。

首先，你的程序抄都抄错，少了个分号都没发现？ 话回正题，这个程序的目的是计算字符串长度啊。

引用 5 楼 user-7 的回复:while后漏了一个分号就量死循环  如果加上分号就是计算字符串长度  t-- 是为了减去最后判断字符串末尾的0时做的++运算+1


Question: 这个程序为什么运行不出来？哪里错了？求大神

引用 4 楼 github_27756899的回复:楼主代码：  int main() { int i,n,m,sum; int a[200]; a[0]=2; a[1]=3;   scanf("%d,%d",n,m);//n=1,m=2,sum=5 if(n==1&&m==2)	//n=1,m=3,sum=7 sum=5;  else { for(i=n-1;i<m;i++)     a[i]=a[i-1]+2;         sum=sum+a[i];  printf("%d",sum); }   }  修改后的代码：  int main() { int i,n,m,sum; sum=0;  //初始化sum int a[200]; a[0]=2; a[1]=3;   scanf("%d,%d",n,m);//n=1,m=2,sum=5 if(n==1&&m==2)	//n=1,m=3,sum=7 sum=5;  else { for(i=n-1;i<m;i++)    sum=sum+a[i];  //修改后  printf("%d",sum); }   }  这样还知道每个素数是多少吗？a[3].a [i]不知道大小，

Finding prime numbers - Kenneth Haugland  Different schemas for finding prime numbers explained with code  http://www.codeproject.com/Articles/429694/Finding-prime-numbers

引用 10 楼 CGH1995 的回复:[quote=引用 5 楼 zhangxiangDavaid 的回复:] 这样可好：  #include <stdio.h> static int primes[200]; int i, j, v; int m, n; int sum; int main(void) { 	sum = 0; 	scanf("%d%d", &n, &m); 	primes[0] = 2, primes[1] = 3, primes[2] = 5, primes[3] = 7; 	i = 4, v = 8; 	while (1) 	{ 		if (200 == i)break; 		for (j = 0; j < i && v % primes[j]; j++); 		if (j == i) 		{ 			primes[i] = v; 			i++; 		} 		v++; 	} 	for (i = n - 1; i <= m - 1; i++) 		sum += primes[i]; 	printf("sum=%d\n", sum); 	return 0; }  sum总是为i0[/quote] 我测试过，还没发现问题。

引用 5 楼 zhangxiangDavaid 的回复:这样可好：  #include <stdio.h> static int primes[200]; int i, j, v; int m, n; int sum; int main(void) { 	sum = 0; 	scanf("%d%d", &n, &m); 	primes[0] = 2, primes[1] = 3, primes[2] = 5, primes[3] = 7; 	i = 4, v = 8; 	while (1) 	{ 		if (200 == i)break; 		for (j = 0; j < i && v % primes[j]; j++); 		if (j == i) 		{ 			primes[i] = v; 			i++; 		} 		v++; 	} 	for (i = n - 1; i <= m - 1; i++) 		sum += primes[i]; 	printf("sum=%d\n", sum); 	return 0; }    sum总是为i0

参考代码：  bool IsPrime(int num)  //判断是否为素数 { 	int i, mid; 	if(num <= 1) 		return false;  	mid = (int)sqrt(num); 	for(i = 2; i <=  mid; i++) 	{ 		if(num % i == 0) 			return false; 	}  	return true; }  int main() { 	int i,n, m, sum = 0; 	scanf("%d%d", &n, &m); 	for(i = n; i <= m; i++) 	{ 		if(IsPrime(i)) 			sum += i; 	} 	printf("%d\n", sum);     return 0; }

楼主是菜鸟，大家帮帮忙

速度慢了，直接打表

引用 2 楼 ant2012的回复:楼主，你这是什么算法啊，我完全没看懂。还有scanf中两个%d中间有逗号，则在输入时，必须敲逗号进行匹配 我知道，输入的时候加上逗号了


Question: 有个关于指针的问题搞不太明白，请教一下大神

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

指针、指针…… http://blog.csdn.net/zhangxiangdavaid/article/details/37885275

我猜你问的大概是这个： http://bbs.csdn.net/topics/391831773


Question: TCP客户机与服务器的通信

MSDN98_1.ISO http://pan.baidu.com/s/1dDF41ix,  MSDN98_2.ISO http://pan.baidu.com/s/1bnGo0Vl 先下载安装MSDN98  再参考 MSDN98\SAMPLES\VC98\SDK\NETDS\WINSOCK\SIMPLE\SIMPLEC.DSP MSDN98\SAMPLES\VC98\SDK\NETDS\WINSOCK\SIMPLE\SIMPLES.C MSDN98\SAMPLES\VC98\SDK\NETDS\WINSOCK\SIMPLE\SIMPLEC.C MSDN98\SAMPLES\VC98\SDK\NETDS\WINSOCK\SIMPLE\IOCTL.C MSDN98\SAMPLES\VC98\SDK\NETDS\WINSOCK\SIMPLE\README.TXT MSDN98\SAMPLES\VC98\SDK\NETDS\WINSOCK\SIMPLE\MAKEFILE  http://bbs.csdn.net/topics/390374955

嗯，，，看不懂，好高深的c语言

服务端这一句：  if (recv(new_fd,buff,strlen(buff),0) == -1) strlen(buff) 结果为0，也就是不接收任何数据，因此堵塞。 将strlen 改成 sizeof 吧，strlen是用来数字符个数的，不是算缓冲区长度的


Question: C语言编译expected型error，求助

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

引用 6 楼 zhangruo2010的回复:第十一行的右括号是个中文括号，要改为英文半角括号 十二行也是这样的错误

第十一行的右括号是个中文括号，要改为英文半角括号

c语言中没有引用的概念，c++才有。 把.c文件改为.cpp

还有就是你的代码干嘛把声明和定义写到一起，写到一起的话还不如不要声明，直接定义就好了。

根据.c文件看出来你这是c语言，void ClearList(SqList &L)中的形参是按引用来传递的，这个是c++的，c语言没有引用的概念，把取地址符&换成取值符*应该就可以了，是按指针传参的。要使用按引用传参的话，请使用C++编译器来编译，并且文件命名为.cpp.

SqList &是C++引用 C语言编译器不认识

我似乎看到了全角符号


Question: 信号问题

sig_act 的 sa_mask 没有赋值啊 sigemptyset(&sig_act.sa_mask);

木有注释，表示水平不够，看不是很明白。帮顶。

不明觉厉，只能帮顶。


Question: 请问VS2015中，就算加了宏定义，还是不能用gets函数，而VS2013中加了宏定义就可以使用gets函数，请问那再怎么定义呢？

/RTC (Run-Time Error Checks)

你应该把错误的代码贴出来,出错的信息贴出来.因为很可能vs2015中就把fgets作为了一个内置的函数.你的宏定义没准和里面的某个函数冲突了.

不会加错地方，在VC6.0和VS2013中都编译通过并运行了，在VS2015就编译不通过

引用 楼主 u014626834 的回复:请问VS2015中，就算加了宏定义，还是不能用gets函数，而VS2013中加了宏定义就可以使用gets函数，请问那再怎么定义呢？ 你应该把解法告诉我.这样下次碰到了,我也有个准备啊

楼主贴出代码

目测加错地方了

那就使用fgets……


Question: c语言关于二维数组列指针的问题

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

因为sum[i] += *(pScore + i * m + j);//sum[i] += pScore[i][j];效果不同，m<>STUD

非常感谢你，中午再结贴

如果允许用户录入小于数组数据个数的数据时，将你的：  改成  便不影响指针的正常访问。

题主你好： 程序中的指针用于调取数组中的数据。通过宏定义以及数组定义，你已完成了对某一数组（如score[STU][COURSE]）中数据个数的定义。此时若用户输入的m,n值与你的STU、COURSE不一致，便会产生错误。  此处，你定义的学生人数为30，课程数目为5，但我输入的为2和2，不相符；  随后运行结果产生错误。 但如若m、n与STU、COURSE相符（此处我在程序中将STU、COURSE分别定义为5、2）：   未发生数据错误。

题主你好： 你的程序中指针的主要作用是为了便于调取数组中的数据。

关于二级指针以及更多级 http://blog.csdn.net/zhangxiangdavaid/article/details/38111983


Question: 这个程序可以编译但是运行不了

#include<stdio.h> #include<stdlib.h> #define TURE 1 #define FALSE 0 #define OK 1 #define ERROR 0 #define INFEASIBLE -1 #define OVERFLOW -2 typedef int status ; typedef int elemtype ; typedef elemtype*triplet ; status inittriplet(triplet&T,elemtype v1,elemtype v2,elemtype v3) {     T=(elemtype*)malloc(3*sizeof(elemtype));     T[0]=v1 ;     T[1]=v2 ;     T[2]=v3 ;     return OK ; } status get(triplet T,int i,elemtype&e) {     if(i<1||i>3)return ERROR ;     e=T[i-1];     return OK ; } status put(triplet&T,int i,elemtype e) {     if(i<1||i>3)return ERROR ;     T[i-1]=e ;     return OK ; } status max(triplet T,elemtype&e) {     e=(T[0]>=T[1])?((T[0]>=T[2])?T[0]:T[2]):     ((T[1]>=T[2])?T[1]:T[2]);     return OK ; } main() {     triplet*t ;     int a ;     elemtype elem,e1,e2,e3,*p=&elem ;     scanf("%d %d %d",&e1,&e2,&e3);     inittriplet(*t,e1,e2,e3);     printf("%d %d %d",t[1],t[2],t[3]);     max(*t,elem);     printf("the max num is %d\n",elem);     //get      scanf("%d",&a);     if(a>=1&&a<=3)     {         printf("Please input a new number:");         scanf("%d",&elem);         put(*t,a,elem);         printf("%d %d %d",t[1],t[2],t[3]);     }     else      {         printf("Your input not correct!");     } } 没猜错的话，lz写的是 数据结构前面的那个 三元数组的代码

引用是C++内容，用C编译器编译会出错。 你的main没有返回类型，用C++编译器编译会出错。 而且那个get也没写完。

引用 1 楼 zhangxiangDavaid 的回复:代码并不完整……完整的，就是一个功能没有调用，不会写

代码并不完整……


Question: 大端小端对位域成员存放的影响

许多码农这辈子都没用过WinHex

字节序分为大端字节序和小端字节序，通常网络传输数据时候，因为两端的机器平台可能不一样，所以会字节序问题。 大端字节序说通俗一点：即低地址，高字节 小端字节序说通俗一点：即低地址，低字节 楼主不明白字节序是怎么回事，首先说明楼主对于，高地址与低地址，高字节与低字节，还不是很了解。 多字节对象存储在连续的字节序列，对象地址为所使用字节中最小的地址， 如int a的地址为0x100,则a的四个字节存储在0x100,0x101,0x102,0x103的位置 对于高低地址问题，地址数值大的即为高地址，地址数值小的即为低地址，如上例中0x100为低地址，0x103为高地址 对于高低字节问题，高字节在左，低字节在右，例如0x01234567，高字节为0x01，低字节为0x67 所以对于0x01234567的存储，假设其存在0x100起始的地址上，总共占据4字节                              0x100     0x101     0x102     0x103  大端字节序           01             23           45           67             即低地址0x100存放高字节0x12 小端字节序            67             45           23           01             即低地址0x100存放低字节0x67  一般的测试程序 int main() {       int a = 0x12345678;       char b = (char)a;//强制类型转换，将int类型转换为char型，即取变量a低地址部分       if(a == 0x78)           printf("小端\n");//低地址，存放低字节，即小端       if(a == 0x12)           printf("小端\n");//低地址，存放高字节，即大端       return 0; }   希望能帮到你。

把内存编辑器打开看看一个整型是怎么保存的 大端小端问题常见于linux和windows平台之间的位串信息交互，很多时候需要倒置，其余倒是一般不用注意

c11 draft N1570  11 An implementation may allocate any addressable storage unit large enough to hold a bit-field. If enough space remains, a bit-field that immediately follows another bit-field in a structure shall be packed into adjacent bits of the same unit. If insufficient space remains, whether a bit-field that does not fit is put into the next unit or overlaps adjacent units is implementation-defined. The order of allocation of bit-fields within a unit (high-order to low-order or low-order to high-order) is implementation-defined. The alignment of the addressable storage unit is unspecified.  位域的大多数实现细节都是实现相关的。所以即便同是大段或者小段的处理器，位域怎么存都依赖与编译器的实现。

理解和讨论之前请先学会如何观察！  #include <stdio.h> #pragma pack(push,1) union U {     unsigned char byte;     struct BF {         unsigned int b0:1;//a         unsigned int b1:1;//b         unsigned int b2:1;//c     } bf; } u; #pragma pack(pop) unsigned char bt; int a,b,c; int main() {     for (bt=0;bt<8;bt++) {         u.byte=(unsigned char)bt;         a=u.bf.b0;         b=u.bf.b1;         c=u.bf.b2;         printf("byte 0x%02x -- c:%d b:%d a:%d\n",bt,c,b,a);     }     for (c=0;c<2;c++)     for (b=0;b<2;b++)     for (a=0;a<2;a++) {         u.bf.b0=a;         u.bf.b1=b;         u.bf.b2=c;         bt=u.byte;         printf("c:%d b:%d a:%d -- byte 0x%02x\n",c,b,a,bt);     }     return 0; } //byte 0x00 -- c:0 b:0 a:0 //byte 0x01 -- c:0 b:0 a:1 //byte 0x02 -- c:0 b:1 a:0 //byte 0x03 -- c:0 b:1 a:1 //byte 0x04 -- c:1 b:0 a:0 //byte 0x05 -- c:1 b:0 a:1 //byte 0x06 -- c:1 b:1 a:0 //byte 0x07 -- c:1 b:1 a:1 //c:0 b:0 a:0 -- byte 0x00 //c:0 b:0 a:1 -- byte 0x01 //c:0 b:1 a:0 -- byte 0x02 //c:0 b:1 a:1 -- byte 0x03 //c:1 b:0 a:0 -- byte 0x04 //c:1 b:0 a:1 -- byte 0x05 //c:1 b:1 a:0 -- byte 0x06 //c:1 b:1 a:1 -- byte 0x07

这根 Bit 序 和 Bytes序 都有关系  C标准没有规定 Bits顺序和位段声明顺序的关系. 这样，也就无法规定 Bytes 顺序和 字节顺序的关系了

并不是大小端的问题，而是这东西是implementation-defined behavior。即便都是小端，两个编译器上也可能不一样。

例如这个一个例子中各位在内存中是怎么分布的？     struct     {          short bit1:4          short bit2:9          short bit3:3     };

就是不怎么懂大端小端对位域成员存放的影响

int main(void) { 	int n = 0x12345678; 	char *p = (char*)&n; 	printf("%x %x %x %x\n", p[0], p[1], p[2], p[3]); 	return 0; } //78 56 34 12小端 //12 34 56 78大端


Question: c实现md5加密 如何调用这段函数

#pragma comment(lib,"advapi32") #include <windows.h> #include <wincrypt.h> #include <stdio.h> #include <string.h> int main() {     int L;     HCRYPTPROV hProv = 0;     HCRYPTHASH hHash = 0;     BYTE *pbHash = NULL;     DWORD dwHashLen;     #define BUFFER_SIZE 256     BYTE pbBuffer[BUFFER_SIZE];     DWORD dwCount;     DWORD i;  //     Get a handle to the default provider.     if(!CryptAcquireContext(&hProv, NULL, NULL, PROV_RSA_FULL, 0)) {         printf("Error %x during CryptAcquireContext!\n", GetLastError());         goto done;     } //     Create a hash object.     if(!CryptCreateHash(hProv, CALG_MD5, 0, 0, &hHash)) {         printf("Error %x during CryptBeginHash!\n", GetLastError());         goto done;     }  //     Fill the buffer with test data.     printf("Input a string:");fflush(stdout);     fgets((char *)pbBuffer,BUFFER_SIZE,stdin);     L=strlen((char *)pbBuffer);     if ('\n'==pbBuffer[L-1]) {pbBuffer[L-1]=0;L--;}  //     Put the hash in buffer.     if(!CryptHashData(hHash, pbBuffer, L, 0)) {         printf("Error %x during CryptHashData!\n", GetLastError());         goto done;     }  //     Read the hash value size and allocate memory.     dwCount = sizeof(DWORD);     if(!CryptGetHashParam(hHash, HP_HASHSIZE, (BYTE *)&dwHashLen,                           &dwCount, 0)) {         printf("Error %x during reading hash size!\n", GetLastError());         goto done;     }     if((pbHash = (BYTE *)malloc(dwHashLen)) == NULL) {         printf("Out of memory!\n");         goto done;     }  //     Read the hash value.     if(!CryptGetHashParam(hHash, HP_HASHVAL, pbHash, &dwHashLen, 0)) {         printf("Error %x during reading hash value!\n", GetLastError());         goto done;     }  //     Print the hash value.     for(i = 0 ; i < dwHashLen ; i++) {         printf("%2.2x",pbHash[i]);     }     printf("\n");  done:  //     Free memory.     if(pbHash !=NULL) free(pbHash);  //     Destroy the hash object.     if(hHash) CryptDestroyHash(hHash); //     Release the CSP handle.     if(hProv) CryptReleaseContext(hProv,0);      return 0; } //Input a string:abc //900150983cd24fb0d6963f7d28e17f72 //

MD5 算法网上多得是，为什么要用这看起来乱糟糟的代码？ 把我自己用的贴出来，再附上一个例子： #include <stdio.h> #include <stdlib.h> #include <string.h>  /*  * MD5  */  #define F(x, y, z)          ((x & y) | (~x & z)) #define G(x, y, z)          ((x & z) | (y & ~z)) #define H(x, y, z)          (x ^ y ^ z) #define I(x, y, z)          (y ^ (x | ~z)) #define ROTATE_LEFT(x, n)   ((x << n) | (x >> (32 - n))) #define FF(a, b, c, d, x, s, ac) \         do { \             a += F(b, c, d) + x + ac; \             a = ROTATE_LEFT(a, s); \             a += b; \         } while (0) #define GG(a, b, c, d, x, s, ac) \         do { \             a += G(b, c, d) + x + ac; \             a = ROTATE_LEFT(a, s); \             a += b; \         } while (0) #define HH(a, b, c, d, x, s, ac) \         do { \             a += H(b, c, d) + x + ac; \             a = ROTATE_LEFT(a, s); \             a += b; \         } while (0) #define II(a, b, c, d, x, s, ac) \         do { \             a += I(b, c, d) + x + ac; \             a = ROTATE_LEFT(a, s); \             a += b; \         } while (0)  static void MD5Encode(unsigned char *output, const unsigned int *input, unsigned int len); static void MD5Decode(unsigned int *output, const unsigned char *input, unsigned int len); static void MD5Transform(unsigned int state[4], const unsigned char block[64]);  static unsigned char PADDING[] = {     0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,     0,    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,     0,    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,     0,    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };  typedef struct {     unsigned int count[2];     unsigned int state[4];     unsigned char buffer[64]; } MD5_CTX;  void MD5Init(MD5_CTX *ctx) {     ctx->count[0] = 0;     ctx->count[1] = 0;     ctx->state[0] = 0x67452301;     ctx->state[1] = 0xEFCDAB89;     ctx->state[2] = 0x98BADCFE;     ctx->state[3] = 0x10325476; }  void MD5Update(MD5_CTX *ctx, const unsigned char *input, unsigned int len) {     unsigned int i = 0;     unsigned int index = (ctx->count[0] >> 3) & 0x3F;     unsigned int partlen = 64 - index;      ctx->count[0] += len << 3;     if (ctx->count[0] < (len << 3)) {         ctx->count[1]++;     }      ctx->count[1] += len >> 29;      if (len >= partlen) {         memcpy(&ctx->buffer[index], input, partlen);         MD5Transform(ctx->state, ctx->buffer);         for (i = partlen; i + 64 <= len; i += 64) {             MD5Transform(ctx->state, &input[i]);         }         index = 0;     } else {         i = 0;     }      memcpy(&ctx->buffer[index], &input[i], len - i); }  void MD5Final(MD5_CTX *ctx, unsigned char digest[16]) {     unsigned char bits[8] = { 0 };     unsigned int index = (ctx->count[0] >> 3) & 0x3F;     unsigned int padlen = (index < 56) ? (56 - index) : (120 - index);      MD5Encode(bits, ctx->count, 8);     MD5Update(ctx, PADDING, padlen);     MD5Update(ctx, bits, 8);     MD5Encode(digest, ctx->state, 16); }  static void MD5Encode(unsigned char *output, const unsigned int *input, unsigned int len) {     unsigned int i = 0;     unsigned int j = 0;     while (j < len) {         output[j] = input[i] & 0xFF;         output[j + 1] = (input[i] >> 8) & 0xFF;         output[j + 2] = (input[i] >> 16) & 0xFF;         output[j + 3] = (input[i] >> 24) & 0xFF;         i++;         j += 4;     } }  static void MD5Decode(unsigned int *output, const unsigned char *input, unsigned int len) {     unsigned int i = 0;     unsigned int j = 0;     while (j < len) {         output[i] = (input[j]) | (input[j + 1] << 8) | (input[j + 2] << 16) | (input[j + 3] << 24);         i++;         j += 4;     } }  static void MD5Transform(unsigned int state[4], const unsigned char block[64]) {     unsigned int a = state[0];     unsigned int b = state[1];     unsigned int c = state[2];     unsigned int d = state[3];      unsigned int x[16] = { 0 };     MD5Decode(x, block, 64);      /* Round 1 */     FF(a, b, c, d, x[ 0], 7,  0xd76aa478); /* 1 */     FF(d, a, b, c, x[ 1], 12, 0xe8c7b756); /* 2 */     FF(c, d, a, b, x[ 2], 17, 0x242070db); /* 3 */     FF(b, c, d, a, x[ 3], 22, 0xc1bdceee); /* 4 */     FF(a, b, c, d, x[ 4], 7,  0xf57c0faf); /* 5 */     FF(d, a, b, c, x[ 5], 12, 0x4787c62a); /* 6 */     FF(c, d, a, b, x[ 6], 17, 0xa8304613); /* 7 */     FF(b, c, d, a, x[ 7], 22, 0xfd469501); /* 8 */     FF(a, b, c, d, x[ 8], 7,  0x698098d8); /* 9 */     FF(d, a, b, c, x[ 9], 12, 0x8b44f7af); /* 10 */     FF(c, d, a, b, x[10], 17, 0xffff5bb1); /* 11 */     FF(b, c, d, a, x[11], 22, 0x895cd7be); /* 12 */     FF(a, b, c, d, x[12], 7,  0x6b901122); /* 13 */     FF(d, a, b, c, x[13], 12, 0xfd987193); /* 14 */     FF(c, d, a, b, x[14], 17, 0xa679438e); /* 15 */     FF(b, c, d, a, x[15], 22, 0x49b40821); /* 16 */      /* Round 2 */     GG(a, b, c, d, x[ 1], 5,  0xf61e2562); /* 17 */     GG(d, a, b, c, x[ 6], 9,  0xc040b340); /* 18 */     GG(c, d, a, b, x[11], 14, 0x265e5a51); /* 19 */     GG(b, c, d, a, x[ 0], 20, 0xe9b6c7aa); /* 20 */     GG(a, b, c, d, x[ 5], 5,  0xd62f105d); /* 21 */     GG(d, a, b, c, x[10], 9,  0x02441453); /* 22 */     GG(c, d, a, b, x[15], 14, 0xd8a1e681); /* 23 */     GG(b, c, d, a, x[ 4], 20, 0xe7d3fbc8); /* 24 */     GG(a, b, c, d, x[ 9], 5,  0x21e1cde6); /* 25 */     GG(d, a, b, c, x[14], 9,  0xc33707d6); /* 26 */     GG(c, d, a, b, x[ 3], 14, 0xf4d50d87); /* 27 */     GG(b, c, d, a, x[ 8], 20, 0x455a14ed); /* 28 */     GG(a, b, c, d, x[13], 5,  0xa9e3e905); /* 29 */     GG(d, a, b, c, x[ 2], 9,  0xfcefa3f8); /* 30 */     GG(c, d, a, b, x[ 7], 14, 0x676f02d9); /* 31 */     GG(b, c, d, a, x[12], 20, 0x8d2a4c8a); /* 32 */      /* Round 3 */     HH(a, b, c, d, x[ 5], 4,  0xfffa3942); /* 33 */     HH(d, a, b, c, x[ 8], 11, 0x8771f681); /* 34 */     HH(c, d, a, b, x[11], 16, 0x6d9d6122); /* 35 */     HH(b, c, d, a, x[14], 23, 0xfde5380c); /* 36 */     HH(a, b, c, d, x[ 1], 4,  0xa4beea44); /* 37 */     HH(d, a, b, c, x[ 4], 11, 0x4bdecfa9); /* 38 */     HH(c, d, a, b, x[ 7], 16, 0xf6bb4b60); /* 39 */     HH(b, c, d, a, x[10], 23, 0xbebfbc70); /* 40 */     HH(a, b, c, d, x[13], 4,  0x289b7ec6); /* 41 */     HH(d, a, b, c, x[ 0], 11, 0xeaa127fa); /* 42 */     HH(c, d, a, b, x[ 3], 16, 0xd4ef3085); /* 43 */     HH(b, c, d, a, x[ 6], 23, 0x04881d05); /* 44 */     HH(a, b, c, d, x[ 9], 4,  0xd9d4d039); /* 45 */     HH(d, a, b, c, x[12], 11, 0xe6db99e5); /* 46 */     HH(c, d, a, b, x[15], 16, 0x1fa27cf8); /* 47 */     HH(b, c, d, a, x[ 2], 23, 0xc4ac5665); /* 48 */      /* Round 4 */     II(a, b, c, d, x[ 0], 6,  0xf4292244); /* 49 */     II(d, a, b, c, x[ 7], 10, 0x432aff97); /* 50 */     II(c, d, a, b, x[14], 15, 0xab9423a7); /* 51 */     II(b, c, d, a, x[ 5], 21, 0xfc93a039); /* 52 */     II(a, b, c, d, x[12], 6,  0x655b59c3); /* 53 */     II(d, a, b, c, x[ 3], 10, 0x8f0ccc92); /* 54 */     II(c, d, a, b, x[10], 15, 0xffeff47d); /* 55 */     II(b, c, d, a, x[ 1], 21, 0x85845dd1); /* 56 */     II(a, b, c, d, x[ 8], 6,  0x6fa87e4f); /* 57 */     II(d, a, b, c, x[15], 10, 0xfe2ce6e0); /* 58 */     II(c, d, a, b, x[ 6], 15, 0xa3014314); /* 59 */     II(b, c, d, a, x[13], 21, 0x4e0811a1); /* 60 */     II(a, b, c, d, x[ 4], 6,  0xf7537e82); /* 61 */     II(d, a, b, c, x[11], 10, 0xbd3af235); /* 62 */     II(c, d, a, b, x[ 2], 15, 0x2ad7d2bb); /* 63 */     II(b, c, d, a, x[ 9], 21, 0xeb86d391); /* 64 */      state[0] += a;     state[1] += b;     state[2] += c;     state[3] += d; }  /*  * HexToStr  */  static char HexToChar(char hex) {     return (hex < 10) ? (hex + '0') : (hex - 10 + 'A'); }  char *HexToStr(char *ret, const unsigned char *data, int len) {     char *dest = ret;     if (ret != NULL && data != NULL && len > 0) {         while (len-- > 0) {             unsigned char ch = *data++;             *ret++ = HexToChar(ch >> 4);             *ret++ = HexToChar(ch & 0xF);         }         *ret = 0;     }     return dest; }  /*  * main  */  #define MAX_READ_BYTES 256  int main(int argc, char *argv[]) {     unsigned char md5data[16] = { 0 };     unsigned char readbuf[MAX_READ_BYTES] = { 0 };     char md5str[32+4] = { 0 };     char str[] = "Hello, world!";     char file[] = "C:\\WINDOWS\\Notepad.exe";     FILE *fp = NULL;     MD5_CTX ctx = { 0 };      // 计算字符串MD5     MD5Init(&ctx);     MD5Update(&ctx, (unsigned char *)str, strlen(str));     MD5Final(&ctx, md5data);     HexToStr(md5str, md5data, 16);      printf("MD5 of string %s:\n%s\n\n", str, md5str);      // 计算文件MD5     MD5Init(&ctx);     fp = fopen(file, "rb");     if (fp != NULL) {         int readlen = 0;         do {             readlen = fread(readbuf, sizeof(unsigned char), MAX_READ_BYTES, fp);             MD5Update(&ctx, (unsigned char *)readbuf, readlen);         } while (readlen == MAX_READ_BYTES);         fclose(fp);     }     MD5Final(&ctx, md5data);     HexToStr(md5str, md5data, 16);      printf("MD5 of file %s:\n%s\n\n", file, md5str);      return 0; }

引用 10 楼 hashcat的回复:[quote=引用 9 楼 zhao4zhong1 的回复:] 将_asm改为__asm再试试。 VC6中编译毫无违和感。 不同编译器对代码的识别有区别？？ 额.....报错 \5\18346.cpp||In function 'void func(long unsigned int&, long unsigned int, long unsigned int, long unsigned int, long unsigned int, long unsigned int, int, int)':| \5\18346.cpp|46|error: expected '(' before '{' token| \5\18346.cpp|47|error: 'mov' was not declared in this scope| \5\18346.cpp|47|error: expected ';' before 'ecx'| ||=== Build failed: 3 error(s), 0 warning(s) (0 minute(s), 0 second(s)) ===|  [/quote] 话说，正打算换个编译器试试，现在用的codeblocks感觉很别扭，vc太新的我怕跑不了老的标准的代码，太老的我怕跑不了新的，有啥推荐的吗....

引用 9 楼 zhao4zhong1 的回复:将_asm改为__asm再试试。 VC6中编译毫无违和感。 不同编译器对代码的识别有区别？？ 额.....报错 \5\18346.cpp||In function 'void func(long unsigned int&, long unsigned int, long unsigned int, long unsigned int, long unsigned int, long unsigned int, int, int)':| \5\18346.cpp|46|error: expected '(' before '{' token| \5\18346.cpp|47|error: 'mov' was not declared in this scope| \5\18346.cpp|47|error: expected ';' before 'ecx'| ||=== Build failed: 3 error(s), 0 warning(s) (0 minute(s), 0 second(s)) ===|

将_asm改为__asm再试试。 VC6中编译毫无违和感。

引用 6 楼 zhao4zhong1 的回复:引用只有在C++中有，将源代码后缀由.c改为.cpp  或者用这个我刚改的.c版本：#include <stdio.h> #include <math.h> #include <string.h> #include <memory.h> const unsigned int s[4][4]={{7,12,17,22},{5,9,14,20},{4,11,16,23},{6,10,15,21}}; const unsigned long t[64]={//t[i]=4294967296*fabs(sin(i+1));  0xd76aa478,0xe8c7b756,0x242070db,0xc1bdceee,0xf57c0faf,0x4787c62a,0xa8304613,0xfd469501,  0x698098d8,0x8b44f7af,0xffff5bb1,0x895cd7be,0x6b901122,0xfd987193,0xa679438e,0x49b40821,  0xf61e2562,0xc040b340,0x265e5a51,0xe9b6c7aa,0xd62f105d,0x02441453,0xd8a1e681,0xe7d3fbc8,  0x21e1cde6,0xc33707d6,0xf4d50d87,0x455a14ed,0xa9e3e905,0xfcefa3f8,0x676f02d9,0x8d2a4c8a,  0xfffa3942,0x8771f681,0x6d9d6122,0xfde5380c,0xa4beea44,0x4bdecfa9,0xf6bb4b60,0xbebfbc70,  0x289b7ec6,0xeaa127fa,0xd4ef3085,0x04881d05,0xd9d4d039,0xe6db99e5,0x1fa27cf8,0xc4ac5665,  0xf4292244,0x432aff97,0xab9423a7,0xfc93a039,0x655b59c3,0x8f0ccc92,0xffeff47d,0x85845dd1,  0x6fa87e4f,0xfe2ce6e0,0xa3014314,0x4e0811a1,0xf7537e82,0xbd3af235,0x2ad7d2bb,0xeb86d391 }; const int serial[64]={  0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,  1,6,11,0,5,10,15,4,9,14,3,8,13,2,7,12,  5,8,11,14,1,4,7,10,13,0,3,6,9,12,15,2,  0,7,14,5,12,3,10,1,8,15,6,13,4,11,2,9 }; void func(unsigned long *a,           unsigned long b,           unsigned long c,           unsigned long d,           unsigned long M,           unsigned long t,           int s,           int turn) {     unsigned long temp;     switch(turn) {     case 0:         temp=(b&c)|((~b)&d);         break;     case 1:         temp=(d&b)|((~d)&c);         break;     case 2:         temp=b^c^d;         break;     case 3:         temp=c^(b|(~d));         break;     }     temp+=M+t+*a;     _asm {         mov ecx,s         rol temp,cl     }     *a=b+temp; } void MD512(const unsigned long M[16],unsigned long hash[4]) {     int i,j,index=0;     for (i=0;i<4;i++)         for (j=0;j<4;j++) {             func(&hash[0],hash[1],hash[2],hash[3],M[serial[index]],t[index],s[i][0],i);             index++;             func(&hash[3],hash[0],hash[1],hash[2],M[serial[index]],t[index],s[i][1],i);             index++;             func(&hash[2],hash[3],hash[0],hash[1],M[serial[index]],t[index],s[i][2],i);             index++;             func(&hash[1],hash[2],hash[3],hash[0],M[serial[index]],t[index],s[i][3],i);             index++;         } }  void MD5(char* M,int nLen,unsigned long output[4]) {     int i,j;     unsigned long Hash[4]={0x67452301,0xefcdab89,0x98badcfe,0x10325476};     unsigned long hash[4];      //填充     __int64 BitsLen=nLen*8;     int oldlen=nLen;     while(nLen%64!=56) {         M[nLen++]=0;     }     M[oldlen]=0x80u;     *(__int64*)(M+nLen)=BitsLen;     nLen+=8;      //开始处理分组     for (i=0;i<nLen;i+=64) {         memcpy(hash,Hash,sizeof(long)*4);         MD512((const unsigned long*)&M[i],hash);//处理512bits分组         for (j=0;j<4;j++)             Hash[j]+=hash[j];     }      //处理输出。     for (i=0;i<4;i++)         for (j=3;j>=0;j--) {             *((char*)(output+i)+j)=*((char*)(Hash+i)+3-j);         } } int main() {     int i;     char szMessage[1000]={0};     unsigned long output[4];      printf("input a string:\n>>>");     scanf("%s",szMessage);     MD5(szMessage,strlen(szMessage),output);     for (i=0;i<4;i++)         printf("%08lx",output[i]);     printf("\n");     return 0; }   我把之前那个改成.cpp了，可是还是在46行报错... 这是老版本的报错 \5\18346.cpp||In function 'void func(long unsigned int&, long unsigned int, long unsigned int, long unsigned int, long unsigned int, long unsigned int, int, int)':| \5\18346.cpp|46|error: '_asm' was not declared in this scope| \5\18346.cpp|46|error: expected ';' before '{' token| ||=== Build failed: 2 error(s), 0 warning(s) (0 minute(s), 0 second(s)) ===|  这是新版本的报错 5\828.c||In function 'func':| 5\828.c|46|error: '_asm' undeclared (first use in this function)| 5\828.c|46|note: each undeclared identifier is reported only once for each function it appears in| 5\828.c|46|error: expected ';' before '{' token| ||=== Build failed: 2 error(s), 0 warning(s) (0 minute(s), 0 second(s)) ===|

引用 2 楼 walkiz 的回复:参考http://openwall.info/wiki/people/solar/software/public-domain-source-code/md5 里面的c文件，报错 c:\program files (x86)\codeblocks\mingw\bin\..\lib\gcc\mingw32\4.8.1\..\..\..\libmingw32.a(main.o):main.c:(.text.startup+0xa7)||undefined reference to `WinMain@16'|  然后我加了个 int main(){             } 然后就报错C:\md5.c|94|error: invalid storage class for function 'body'|

引用 3 楼 zhao4zhong1 的回复:仅供参考：#include <stdio.h> #include <math.h> #include <string.h> #include <memory.h> const unsigned int s[4][4]={{7,12,17,22},{5,9,14,20},{4,11,16,23},{6,10,15,21}}; const unsigned long t[64]={//t[i]=4294967296*fabs(sin(i+1));  0xd76aa478,0xe8c7b756,0x242070db,0xc1bdceee,0xf57c0faf,0x4787c62a,0xa8304613,0xfd469501,  0x698098d8,0x8b44f7af,0xffff5bb1,0x895cd7be,0x6b901122,0xfd987193,0xa679438e,0x49b40821,  0xf61e2562,0xc040b340,0x265e5a51,0xe9b6c7aa,0xd62f105d,0x02441453,0xd8a1e681,0xe7d3fbc8,  0x21e1cde6,0xc33707d6,0xf4d50d87,0x455a14ed,0xa9e3e905,0xfcefa3f8,0x676f02d9,0x8d2a4c8a,  0xfffa3942,0x8771f681,0x6d9d6122,0xfde5380c,0xa4beea44,0x4bdecfa9,0xf6bb4b60,0xbebfbc70,  0x289b7ec6,0xeaa127fa,0xd4ef3085,0x04881d05,0xd9d4d039,0xe6db99e5,0x1fa27cf8,0xc4ac5665,  0xf4292244,0x432aff97,0xab9423a7,0xfc93a039,0x655b59c3,0x8f0ccc92,0xffeff47d,0x85845dd1,  0x6fa87e4f,0xfe2ce6e0,0xa3014314,0x4e0811a1,0xf7537e82,0xbd3af235,0x2ad7d2bb,0xeb86d391 }; const int serial[64]={  0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,  1,6,11,0,5,10,15,4,9,14,3,8,13,2,7,12,  5,8,11,14,1,4,7,10,13,0,3,6,9,12,15,2,  0,7,14,5,12,3,10,1,8,15,6,13,4,11,2,9 }; void func(unsigned long& a,           unsigned long b,           unsigned long c,           unsigned long d,           unsigned long M,           unsigned long t,           int s,           int turn) {     unsigned long temp;     switch(turn) {     case 0:         temp=(b&c)|((~b)&d);         break;     case 1:         temp=(d&b)|((~d)&c);         break;     case 2:         temp=b^c^d;         break;     case 3:         temp=c^(b|(~d));         break;     }     temp+=M+t+a;     _asm {         mov ecx,s         rol temp,cl     }     a=b+temp; } void MD512(const unsigned long M[16],unsigned long hash[4]) {     int i,j,index=0;     for (i=0;i<4;i++)         for (j=0;j<4;j++) {             func(hash[0],hash[1],hash[2],hash[3],M[serial[index]],t[index],s[i][0],i);             index++;             func(hash[3],hash[0],hash[1],hash[2],M[serial[index]],t[index],s[i][1],i);             index++;             func(hash[2],hash[3],hash[0],hash[1],M[serial[index]],t[index],s[i][2],i);             index++;             func(hash[1],hash[2],hash[3],hash[0],M[serial[index]],t[index],s[i][3],i);             index++;         } }  void MD5(char* M,int nLen,unsigned long output[4]) {     int i,j;     unsigned long Hash[4]={0x67452301,0xefcdab89,0x98badcfe,0x10325476};     unsigned long hash[4];      //填充     __int64 BitsLen=nLen*8;     int oldlen=nLen;     while(nLen%64!=56) {         M[nLen++]=0;     }     M[oldlen]=0x80u;     *(__int64*)(M+nLen)=BitsLen;     nLen+=8;      //开始处理分组     for (i=0;i<nLen;i+=64) {         memcpy(hash,Hash,sizeof(long)*4);         MD512((const unsigned long*)&M[i],hash);//处理512bits分组         for (j=0;j<4;j++)             Hash[j]+=hash[j];     }      //处理输出。     for (i=0;i<4;i++)         for (j=3;j>=0;j--) {             *((char*)(output+i)+j)=*((char*)(Hash+i)+3-j);         } } int main() {     int i;     char szMessage[1000]={0};     printf("input a string:\n>>>");     scanf("%s",szMessage);     unsigned long output[4];     MD5(szMessage,strlen(szMessage),output);     for (i=0;i<4;i++)         printf("%08lx",output[i]);     printf("\n");     return 0; }  出现F:\18346.c|22|error: expected ';', ',' or ')' before '&' token|咋办....

引用 1 楼 zxhuser-4 的回复:上面不都有注释说明了吗 是啊，可是我根据他的注释，不会写啊，我写的这个有问题，虽然不报错...但是出来的命令行窗口里就一个 Process returned 1 (0x1)   execution time : 0.458 s Press any key to continue. 我是这么写的。  #include <stdio.h> #include <stdlib.h> #define MD5_ROTL(a,b) (MD5_tmp=(a),((MD5_tmp>>(32-b))&(0x7fffffff>>(31-b)))|(MD5_tmp<<b))   //循环左移 #define MD5_F(X,Y,Z) ((X&Y)|((~X)&Z)) #define MD5_G(X,Y,Z) ((X&Z)|(Y&(~Z))) #define MD5_H(X,Y,Z) (X^Y^Z) #define MD5_I(X,Y,Z) (Y^(X|(~Z))) #define MD5_FF(a,b,c,d,Mj,s,ti) a=b+MD5_ROTL((a+MD5_F(b,c,d)+Mj+ti),s) #define MD5_GG(a,b,c,d,Mj,s,ti) a=b+MD5_ROTL((a+MD5_G(b,c,d)+Mj+ti),s) #define MD5_HH(a,b,c,d,Mj,s,ti) a=b+MD5_ROTL((a+MD5_H(b,c,d)+Mj+ti),s) #define MD5_II(a,b,c,d,Mj,s,ti) a=b+MD5_ROTL((a+MD5_I(b,c,d)+Mj+ti),s) #define MD5main \ {MD5_FF(a, b, c, d, M[0], 7, 0xd76aa478);\ MD5_FF(d, a, b, c, M[1], 12, 0xe8c7b756);\ MD5_FF(c, d, a, b, M[2], 17, 0x242070db);\ MD5_FF(b, c, d, a, M[3], 22, 0xc1bdceee);\ MD5_FF(a, b, c, d, M[4], 7, 0xf57c0faf);\ MD5_FF(d, a, b, c, M[5], 12, 0x4787c62a);\ MD5_FF(c, d, a, b, M[6], 17, 0xa8304613);\ MD5_FF(b, c, d, a, M[7], 22, 0xfd469501);\ MD5_FF(a, b, c, d, M[8], 7, 0x698098d8);\ MD5_FF(d, a, b, c, M[9], 12, 0x8b44f7af);\ MD5_FF(c, d, a, b, M[10], 17, 0xffff5bb1);\ MD5_FF(b, c, d, a, M[11], 22, 0x895cd7be);\ MD5_FF(a, b, c, d, M[12], 7, 0x6b901122);\ MD5_FF(d, a, b, c, M[13], 12, 0xfd987193);\ MD5_FF(c, d, a, b, M[14], 17, 0xa679438e);\ MD5_FF(b, c, d, a, M[15], 22, 0x49b40821);\ MD5_GG(a, b, c, d, M[1], 5, 0xf61e2562);\ MD5_GG(d, a, b, c, M[6], 9, 0xc040b340);\ MD5_GG(c, d, a, b, M[11], 14, 0x265e5a51);\ MD5_GG(b, c, d, a, M[0], 20, 0xe9b6c7aa);\ MD5_GG(a, b, c, d, M[5], 5, 0xd62f105d);\ MD5_GG(d, a, b, c, M[10], 9, 0x02441453);\ MD5_GG(c, d, a, b, M[15], 14, 0xd8a1e681);\ MD5_GG(b, c, d, a, M[4], 20, 0xe7d3fbc8);\ MD5_GG(a, b, c, d, M[9], 5, 0x21e1cde6);\ MD5_GG(d, a, b, c, M[14], 9, 0xc33707d6);\ MD5_GG(c, d, a, b, M[3], 14, 0xf4d50d87);\ MD5_GG(b, c, d, a, M[8], 20, 0x455a14ed);\ MD5_GG(a, b, c, d, M[13], 5, 0xa9e3e905);\ MD5_GG(d, a, b, c, M[2], 9, 0xfcefa3f8);\ MD5_GG(c, d, a, b, M[7], 14, 0x676f02d9);\ MD5_GG(b, c, d, a, M[12], 20, 0x8d2a4c8a);\ MD5_HH(a, b, c, d, M[5], 4, 0xfffa3942);\ MD5_HH(d, a, b, c, M[8], 11, 0x8771f681);\ MD5_HH(c, d, a, b, M[11], 16, 0x6d9d6122);\ MD5_HH(b, c, d, a, M[14], 23, 0xfde5380c);\ MD5_HH(a, b, c, d, M[1], 4, 0xa4beea44);\ MD5_HH(d, a, b, c, M[4], 11, 0x4bdecfa9);\ MD5_HH(c, d, a, b, M[7], 16, 0xf6bb4b60);\ MD5_HH(b, c, d, a, M[10], 23, 0xbebfbc70);\ MD5_HH(a, b, c, d, M[13], 4, 0x289b7ec6);\ MD5_HH(d, a, b, c, M[0], 11, 0xeaa127fa);\ MD5_HH(c, d, a, b, M[3], 16, 0xd4ef3085);\ MD5_HH(b, c, d, a, M[6], 23, 0x04881d05);\ MD5_HH(a, b, c, d, M[9], 4, 0xd9d4d039);\ MD5_HH(d, a, b, c, M[12], 11, 0xe6db99e5);\ MD5_HH(c, d, a, b, M[15], 16, 0x1fa27cf8);\ MD5_HH(b, c, d, a, M[2], 23, 0xc4ac5665);\ MD5_II(a, b, c, d, M[0], 6, 0xf4292244);\ MD5_II(d, a, b, c, M[7], 10, 0x432aff97);\ MD5_II(c, d, a, b, M[14], 15, 0xab9423a7);\ MD5_II(b, c, d, a, M[5], 21, 0xfc93a039);\ MD5_II(a, b, c, d, M[12], 6, 0x655b59c3);\ MD5_II(d, a, b, c, M[3], 10, 0x8f0ccc92);\ MD5_II(c, d, a, b, M[10], 15, 0xffeff47d);\ MD5_II(b, c, d, a, M[1], 21, 0x85845dd1);\ MD5_II(a, b, c, d, M[8], 6, 0x6fa87e4f);\ MD5_II(d, a, b, c, M[15], 10, 0xfe2ce6e0);\ MD5_II(c, d, a, b, M[6], 15, 0xa3014314);\ MD5_II(b, c, d, a, M[13], 21, 0x4e0811a1);\ MD5_II(a, b, c, d, M[4], 6, 0xf7537e82);\ MD5_II(d, a, b, c, M[11], 10, 0xbd3af235);\ MD5_II(c, d, a, b, M[2], 15, 0x2ad7d2bb);\ MD5_II(b, c, d, a, M[9], 21, 0xeb86d391);\ A = a += A, B = b += B, C = c += C, D = d += D;}  int main(){  long MD5_tmp;   char* StrMD5(const char* str, long length, char* md5){     /*     计算字符串MD5     参数说明：         str         字符串指针         length      字符串长度         md5         用于保存MD5的字符串指针     返回值为参数md5     */     char *pp; printf("\n请你输入一个字符: ");  scanf("%c",&str);  printf("你输入的字符是： %c\n",str);      long l, i, *M, abcdtmp[4], A, B, C, D, a, b, c, d;     a = A = 0x67452301, b = B = 0xEFCDAB89, c = C = 0x98BADCFE, d = D = 0x10325476;     l = length + ((length % 64 > 56) ? (128 - length % 64) : (64 - length % 64));     if(!(pp = (char*)malloc((unsigned long)l))) return 0;     for (i = 0; i < length; pp[i]=str[i],i++);     for (pp[i++] = 128; i < l; pp[i++] = 0);     *((long*)(pp + l - 8)) = length << 3;     for (i = 0; i < l; i += 64){         M = (long*)pp;         MD5main     }     free(pp);     abcdtmp[0] = a, abcdtmp[1] = b, abcdtmp[2] = c, abcdtmp[3] = d;     for (pp = (char*)abcdtmp, i = 0; i < 16; sprintf((md5 + 2 * i), "%02X", (unsigned char)pp[i]), i++);     return md5;   }   char* FileMD5(const char* file, char* md5){     /*     计算文件MD5     参数说明：     file        文件路径字符串指针     md5         用于保存MD5的字符串指针     返回值为参数md5     */      FILE* fh;     char* addlp;     long* temp;     long addlsize, j, M[16], abcdtmp[4], A, B, C, D, a, b, c, d;     long long length, i, cpys;     void *pp, *ppend;      fh = fopen(file, "rb");     fseek(fh, 0, SEEK_END);     length = _ftelli64(fh);     a = A = 0x67452301, b = B = 0xEFCDAB89, c = C = 0x98BADCFE, d = D = 0x10325476;     addlsize = (56 - length % 64 > 0) ? (64) : (128);     if (!(addlp = (char*)malloc(addlsize))) return 0;     cpys = ((length - (56 - length % 64)) > 0) ? (length - length % 64) : (0);     j = (long)(length - cpys);     fseek(fh, -j, SEEK_END);     fread(addlp, 1, j, fh);     for (addlp[j++] = 128; j < addlsize; addlp[j++] = 0);     pp = addlp + addlsize - 8;     *((long long *)pp) = length << 3;     for (rewind(fh); 16 == fread(M, 4, 16, fh);)         MD5main      for (temp = (long*)addlp, ppend = addlp + addlsize; temp < ppend; temp += 16) {         for (i = 0; i < 16; M[i] = ((long*)temp)[i], i++);         MD5main     }     free(addlp);fclose(fh);     abcdtmp[0] = a, abcdtmp[1] = b, abcdtmp[2] = c, abcdtmp[3] = d;     for (addlp = (char*)abcdtmp, i = 0; i < 16; sprintf((md5 + 2 * i), "%02X", (unsigned char)addlp[i]), i++);     printf(md5);     return md5;  }  }

上面不都有注释说明了吗


Question: 编译不通过提示have 'float' and 'int',麻烦各位帮我看看

1.操作符%，只针对整数。 2.浮点数使用fmod(x, y);   等价于x%y

fmod Calculates the floating-point remainder.  double fmod( double x, double y );  Function Required Header Compatibility  fmod <math.h> ANSI, Win 95, Win NT    For additional compatibility information, see Compatibility in the Introduction.  Libraries  LIBC.LIB Single thread static library, retail version  LIBCMT.LIB Multithread static library, retail version  MSVCRT.LIB Import library for MSVCRT.DLL, retail version    Return Value  fmod returns the floating-point remainder of x / y. If the value of y is 0.0, fmod returns a quiet NaN. For information about representation of a quiet NaN by the printf family, see printf.  Parameters  x, y  Floating-point values  Remarks  The fmod function calculates the floating-point remainder f of x / y such that x = i * y + f, where i is an integer, f has the same sign as x, and the absolute value of f is less than the absolute value of y.  Example  /* FMOD.C: This program displays a  * floating-point remainder.  */  #include <math.h> #include <stdio.h>  void main( void ) {    double w = -10.0, x = 3.0, y = 0.0, z;     z = fmod( x, y );    printf( "The remainder of %.2f / %.2f is %f\n", w, x, z );    printf( "The remainder of %.2f / %.2f is %f\n", x, y, z );  }   Output  The remainder of -10.00 / 3.00 is -1.000000   Floating-Point Support Routines  See Also   ceil, fabs, floor

因为没有为float（和double）定义%运算

float不能进行取余运算


Question: 求解这个程序为什么内存冲突了？完全按照书上的答案打的。

for循环里面++i改成--i，另外for循环里面是复合语句，需加大括号{}

代码敲错了 1） ++i ，++j就是错的，二者一个前进，一个后退才能够实现翻转 2）循环中居然， 没有将交换数据的代码，全部包括进去（没写大括号 ｛｝）这个 功能就实现不了了。 3）具体出错原因，是循环里面，越界读写，++i,++j 条件j<i 一直都满足（约等于死循环），于是一直在运行， 4）这个问题解决后，看看那个getline 有没有问题

贴代码，不要贴图……

如题，求大神，刚入门的小菜鸟找不出问题


Question: 请问为什么不能给结构体的元素赋值呢？

原因有二： 1.结构体struct all有一个成员是name，而不是name[20]; 2.在c语言中：  char name1[20] = "zhangxiang";   //初始化，可以 char name2[20]; sprintf(name2, "%s", "zhangxiang");  //赋值，可以

strcpy(look[0].name, "张三");  数组不是frist-class object

但是为什么字符数组就不行呢？


Question: 请问VS2013写C程序，怎么给应用程序加上图标？

用资源文件导入一个图标，或者http://bbs.csdn.net/topics/391110538

CUI程序首次导入的ICO默认作为CUI程序的图标 GUI的话WNDCLASSEX.hIconSm/hIcon 用LoadIcon(arg1:程序实例句柄,arg2:MAKEINTRESOURCE(资源ID)

引用 1 楼 zhangxiangDavaid 的回复:带界面的是MFC、QT之类的……+1，控制台程序没图标这一说

带界面的是MFC、QT之类的……


Question: 请教int变量的最大最小值只和CPU几位(32,64)有关吗？

引用 11 楼 zhao4zhong1 的回复:请楼主亲自打开文件include\limits.h，查看其内容。 好的，我学习一下

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

引用 3 楼 daiqingxun 的回复:int取值范围是取决于CPU，现在电脑都是32位和64位，int是32位的，int一般占4个字节一个字节32位，占4个字节就是4个32位也就是128位，当把128位全部填写2进制1在转换成10进制就可以的到能存入无符号int类型可以存入多少数，int是有符号的所以在除于2就可以得到int可以存入的最大值，相反最大值是负值也就是最小值 字节(byte)都是8位的，字(word)可能是32位的。

这么给你说类型大小是和系统相关的，说白了和程序相关，其实也就和编译器先关，编译器是给cpu服务的，也就和cpu相关了

原则上和CPU寄存器长度有关， 不过也有例外，例如 C51 51寄存器为 8Bits，int 是16 Bits  实现中，往往由编译器决定  因为很多时候， 32 Bits可以跑16Bits 程序  64Bits可以跑 32Bits程序 所以，实际上还和编译器有关 某种情况下，32Bits CPU 也可以跑64Bits程序  所以，具体实现由编译器决定  此外，还有 交叉编译器，A CPU上的编译器，可以编译 BCPU跑的程序  A 操作系统上的编译器，有时候也可以编译 B操作系统上跑的程序  一般来说 CPU（FPU），操作系统，编译器  这三者 的某种组合，决定了 int 等数据类型的长度  CPU只是基本决定，而不是确定能决定了的

和编译器有关，分配多少就是多少

引用 3 楼 daiqingxun的回复:int取值范围是取决于CPU，现在电脑都是32位和64位，int是32位的，int一般占4个字节一个字节32位，占4个字节就是4个32位也就是128位，当把128位全部填写2进制1在转换成10进制就可以的到能存入无符号int类型可以存入多少数，int是有符号的所以在除于2就可以得到int可以存入的最大值，相反最大值是负值也就是最小值 int取值范围是取决编译器，现在电脑都是32位和64位，int是32位的，int一般占4个字节一个字节32位，占4个字节就是4个32位也就是128位，当把128位全部填写2进制1在转换成10进制就可以的到能存入无符号int类型可以存入多少数，int是有符号的所以在除于2就可以得到int可以存入的最大值，相反最大值是负值也就是最小值

引用 3 楼 daiqingxun的回复:int取值范围是取决于CPU，现在电脑都是32位和64位，int是32位的，int一般占4个字节一个字节32位，占4个字节就是4个32位也就是128位，当把128位全部填写2进制1在转换成10进制就可以的到能存入无符号int类型可以存入多少数，int是有符号的所以在除于2就可以得到int可以存入的最大值，相反最大值是负值也就是最小值 int取值范围是取决于CPU，现在电脑都是32位和64位，int是32位的，int一般占4个字节一个字节32位，占4个字节就是4个32位也就是128位，当把128位全部填写2进制1在转换成10进制就可以的到能存入无符号int类型可以存入多少数，int是有符号的所以在除于2就可以得到int可以存入的最大值，相反最大值是负值也就是最小值[/quote] int取值范围是取决于CPU，现在电脑都是32位和64位，int是32位的，int一般占4个字节一个字节32位，占4个字节就是4个32位也就是128位，当把128位全部填写2进制1在转换成10进制就可以的到能存入无符号int类型可以存入多少数，int是有符号的所以在除于2就可以得到int可以存入的最大值，相反最大值是负值也就是最小值[/quote] 不是取决CPU是取决编译器

但是你一般多少位的操作系统就是用的多少位的编译器吧，不然会很麻烦的

其实是和编译器相关的，你编译器是 32 位的，编出来的 int 不管 CPU 是多少位，操作系统是多少位，都只有 32 位


Question: 关于希尔排序的问题，求大神帮忙看一下，谢谢

#include<stdio.h> void Shell(int *a, int n); int main() { 	int a[10] = { 10, 9, 8, 7, 6, 5, 4, 3, 2, 1 }; 	myShell(a, 10); 	for (int j = 0; j < 10; j++) 	{ 		printf("%d ", a[j]); 	} 	printf("\n"); 	return 0; } void Shell(int *a, int n) { 	int i, j, temp; 	int gap = n / 2; 	while (gap >= 1) 	{ 		for (i = gap; i < n; i += gap) 		for (j = i; j >= gap && a[j] < a[j - gap]; j-=gap) 		{ 			temp = a[j - gap]; 			a[j - gap] = a[j]; 			a[j] = temp; 		} 		gap /= 2; 	} }


Question: 请问这到底错哪儿了，还是书上的源码

sypedef啥东西啊？

第二行第一个字母改成t试试


Question: VS2013中VC的使用问题？急死啦！

函数必须指定返回值的类型，包括main函数。

楼主还需多努力看书……

楼主还需多努力看书……

楼主看的啥书啊 int main（void）

引用 4 楼 user-4 的回复:[quote=引用 3 楼 mov1er 的回复:] [quote=引用 2 楼 user-4 的回复:] int main() 这是C++ int main(void) 这是C 注意msvc不能完整支持C99 我看VC++里就直接是 main（）  VS里要int main（）？  好像VS里不分C与C++啊。。。[/quote] 你可以在解决方案管理器里修改后缀名，你现在用的是cpp，所以按C++编译 但不管什么时候，省略返回类型都是个坏习惯[/quote]  好吧，反正多写int也没问题吧？

引用 3 楼 mov1er 的回复:[quote=引用 2 楼 user-4 的回复:] int main() 这是C++ int main(void) 这是C 注意msvc不能完整支持C99 我看VC++里就直接是 main（）  VS里要int main（）？  好像VS里不分C与C++啊。。。[/quote] 你可以在解决方案管理器里修改后缀名，你现在用的是cpp，所以按C++编译 但不管什么时候，省略返回类型都是个坏习惯

引用 2 楼 user-4 的回复:int main() 这是C++ int main(void) 这是C 注意msvc不能完整支持C99 我看VC++里就直接是 main（）  VS里要int main（）？  好像VS里不分C与C++啊。。。

还有个什么找不到系统制定文件的弹框


Question: 求解答

引用 1楼user-3 的回复:C语言版本cout << a++ << a++ ....请查看置顶帖给个链接啊，平时很少逛

修改如下：  #include<stdio.h> int main() { 	struct a 	{ 		char name[10]; 	}aa[3] = { { "abc" },{ "def" },{ "ghi" } }; 	struct a *paa = aa; 	printf("%c %c %c", paa[0].name[0], paa[1].name[1], paa[2].name[2]); 	return 0; } //a e i

有时间写帖子，没时间看置顶吗

C语言版本cout << a++ << a++ ....请查看置顶帖


Question: In ?? () () Cannot find bounds of current function问题

可能是这个地方错吗

那哪错了，求大神解决

我也调试过，能编译，但好像不是那里错了，

应该是函数栈被破坏，但看楼主的代码，那个save函数并没有什么问题


Question: 结构体字节长度计算

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

在结构体中，结构体的长度等于所有类型长度的合计， 并且必须等于其中占用内存长度最大的成员项的整数倍。  #include "stdio.h" struct adeal{  int a;  char *d; }; struct adeal2{   int a; };   struct adeal3{   char *d; };   struct adeal4{   short int a;   char  d;  };   int main(){   int a1;   short int a1_;   unsigned  int a2;   long int a3;   unsigned long int a4;   float a5;   double a6;   char a7;   char *a8=&a6;   struct adeal a9;   struct adeal2 a10;   struct adeal3 a11;    struct adeal4 a12;      printf("整型长度:%d\n",sizeof(a1));   printf("短整型长度:%d\n",sizeof(a1_));   printf("无符号整型长度:%d\n",sizeof(a2));   printf("长整型长度:%d\n",sizeof(a3));    printf("无符号长整型长度:%d\n",sizeof(a4));   printf("浮点型长度:%d\n",sizeof(a5));    printf("双精度长度:%d\n",sizeof(a6));   printf("字符型长度:%d\n",sizeof(a7));   printf("字符型指针长度:%d\n",sizeof(a8));   printf("结构的长度:%d\n",sizeof(a9));   printf("结构的长度:%d\n",sizeof(a10));   printf("结构的长度:%d\n",sizeof(a11));   printf("结构的长度:%d\n",sizeof(a12));   return 1; }  参阅sizeof用法   http://www.maomao365.com/?p=2809

结构对齐，简单的说就是取int的倍数。昨天刚学的，解释不好大神不要见怪。

结构体对齐的问题

引用 4 楼 walkiz 的回复:结构体会有字节对齐问题，如果你想让它紧凑的排列，那么可以这样：  #pragma pack(push, 1) struct node{ 	int a; 	char b;     unsigned short k[3];     unsigned int q; }test1; #pragma pack(pop)   [quote=引用 楼主 a904235765 的回复:] 定义一个如下的结构体： struct node{ 	int a; 	char b;     unsigned short k[3];     unsigned int q; }test1;  int  a; a=sizeof(test1);  请问a的数值怎么是16，不是4+1+3*2+4=15么？？[/quote]  请教一下，一般情况都是结构体字节对齐，在什么情况下使用这种字节紧凑排列呢？？？？

结构体对齐方面的知识

比如你用结构体去读取一个文件头，不紧凑的话中间会有很多字段对应不上。  引用 5 楼 adusuccessfully 的回复:[quote=引用 4 楼 walkiz 的回复:] 结构体会有字节对齐问题，如果你想让它紧凑的排列，那么可以这样：  #pragma pack(push, 1) struct node{ 	int a; 	char b;     unsigned short k[3];     unsigned int q; }test1; #pragma pack(pop)   [quote=引用 楼主 a904235765 的回复:] 定义一个如下的结构体： struct node{ 	int a; 	char b;     unsigned short k[3];     unsigned int q; }test1;  int  a; a=sizeof(test1);  请问a的数值怎么是16，不是4+1+3*2+4=15么？？[/quote]  请教一下，一般情况都是结构体字节对齐，在什么情况下使用这种字节紧凑排列呢？？？？[/quote]

结构体会有字节对齐问题，如果你想让它紧凑的排列，那么可以这样：  #pragma pack(push, 1) struct node{ 	int a; 	char b;     unsigned short k[3];     unsigned int q; }test1; #pragma pack(pop)  引用 楼主 a904235765 的回复:定义一个如下的结构体： struct node{ 	int a; 	char b;     unsigned short k[3];     unsigned int q; }test1;  int  a; a=sizeof(test1);  请问a的数值怎么是16，不是4+1+3*2+4=15么？？

使用sizeof获取类型的字节大小，至于字节对齐问题，知道即可。

CPU访问内存的时候，对访问地址有对齐的要求，一般为2的幂次方。 所以有的数据结构被自动填充，以满足对齐要求。

字节对齐，自动填充成2的幂次方数，这样计算机操作数据会更加快


Question: 关于makefile的问题。利用两个文件输出另一个文件，但没有输出。。。请教大侠们。。。

搜“跟我一起写makefile”？


Question: 请问VS2015在哪里下载？

上百度一下下载个不就好了

话说楼主不结贴 问的问题都能自己解决吧

微软的所有工具和系统  各种版本 MSDN 我告诉你  http://msdn.itellyou.cn/


Question: 数据总线，地址总线，控制总线都是什么，之间有什么关系

总线就是CPU和内存等设备连接的（所有）导线  数据总线用来读写数据， 控制总线用来发布读写命令 地址总线用来传送内存地址 选好地址才能读写数据