Question: 关于nm命令（C调用C++的SO动态链接库）

引用 10 楼 bluesky12312388 的回复:已经测试通过:  t.cpp: #include <stdio.h>  int PP(int a, int b) {         printf("a:%d b:%d\n",a ,b);         return 0; } g++ -g -Wall -fPIC -shared -o libt.so t.cpp  m.c  #include <stdio.h>  extern "C++" int PP(int a,int b);  int main(int argc, const char *argv[]) {         int a = 10;         int b = 20;         PP(a,b);         return 0; }  g++ -g -Wall -o m m.c -L./ -lt export LD_LIBRARY_PATH=当前的目录 ./m 结果 a:10 b:20  以上方法确实是可以的，谢谢你。但是我同时希望将m.c也生成so的，应该用什么命令组合呢。我实验用以下方式，但没成功。 gcc -fPIC -shared m.c -L. -lt -o libm.so

这个感觉很简单，就是不知道那地方有问题

这个感觉很简单，就是不知道那地方有问题

10楼没问题大家请参考，18点前接贴  但是 g++ m.c -fPIC -shared -L. -lt -o libm.so 用这种方式我对m.c这个中间层进行了二次封装生成SO。 但是c语言调用这个中间层的函数还是类似   _Z13_XXXX_XXXX 原函数名这种方式。

extern "C" 修饰你的封装函数...

学习学习，回去研究下

g++ m.c -fPIC -shared -L. -lt -o libm.so 用这种方式我对m.c这个中间层进行了二次封装生成SO。 但是c语言调用这个中间层的函数还是需要_Z13_原函数名这种方式。

引用 6 楼 lm_whales 的回复:_InitLGMID的 _ 是C语言的 C调用约定，C生成的函数名就是这样的 InitLGMID就可以了 ，_ 是多余的  我实验了，不行的。

完整例子：  nm命令C++生成的SO：  nm -DC libLGM.so |grep "LGMID"   // 这个也是真实的函数名，但Test.c调用它的时候说找不到 000000000005ec80 T _InitLGMID(char const*, FRMode)  //实际Test.c必须调用它才行， 000000000005ec80 T _Z13_InitLGMIDPKc6WCMode         _InitLGMID(char const*, enum WCMode)是对方提供给我们的libLGM.so调用接口（通过Test.c调用它，说找不到） _Z13_InitLGMIDPKc6WCMode(char const*, enum WCMode); 是我通过nm命令获取到的（通过Test.c调用它，没有问题）  我还是想通过_InitLGMID这种好理解的接口方式调用，可能是我以下哪里写的不对，请各位帮忙了。 ---------------------- Test.h文件  #include <stdio.h>  enum WCMode {DB, TXT};   /* #ifdef __cplusplus extern "C" { #endif */  int callFreeLGMID(int);   int _Z13_InitLGMIDPKc6WCMode(char const*, enum WCMode); //这么写就可以    int _InitLGMID(char const*, enum WCMode);  //这么写就说_InitLGMID没有发现   /* #ifdef __cplusplus } #endif */ -------------------------------------------- Test.c #include <stdio.h> #include "Test.h"  int main(void) {     printf("Hello World!\n");     return 0; }  int callFreeLGMID(int task){	     int init = _Z13_InitLGMIDPKc6WCMode("./INFO",TXT);//这么写就可以    //int init = _InitLGMID("./INFO",TXT);//这么写就说_InitLGMID没有发现   printf("open :%d\n",init);        return 9;  }

引用 3 楼 user-5 的回复:第三方提供的so是c++编译的。 你试试也用c++编译（把.c改为.cpp），最好编译器也一致。 不行

引用 1 楼 bluesky12312388 的回复:具体可以google c++ name mangling 你想直接在test.c调用 so中的UNTHDBID也是可以的， 把这个函数用"extern c++"声明下， 我进行了如下的定义，还是不行。 #include <stdio.h>  enum LGMode {TXT, DB};   #ifdef __cplusplus extern "C" { #endif   int UNTHDBID(enum LGMode);  #ifdef __cplusplus } #endif


Question: 新人求大神深入指导交流！！万分感激

http://pan.baidu.com/s/1mgK7WjI  看下这个视频吧。孙鑫的VC++教程。 觉得好，就多给点分。

MSDN98\SAMPLES\VC98\MFC\TUTORIAL\SCRIBBLE\STEP1～7\*.*

现在才开始学MFC？好吧，我都不想搞MFC了。

引用 2 楼 movsd 的回复:建议先看《Windows程序设计》，再学MFC。 明明是先看《C++ Primer》

建议先看《Windows程序设计》，再学MFC。

放一本Windows程序设计,C++语言参考书,深入浅出MFC在手边,随时翻翻,勤查MSDN,少逛CSDN  建议,仅供参考.


Question: 菜鸟求助

这个程序还有一个问题，只能找出来一个都是一样的单词，如果俩个单词是相同的呢？  看一下我输入的，这个问题没有解决！

#include<stdio.h> #include<string.h> int main() { int n,k,i,num=0;         char a[1000][1000]; printf("请输入你要输入的单词个数\n"); scanf("%d",&n); for(i=0;i<=n;i++) { gets(a[i]);  } for(i=0;i<=n;i++) { k=strcmp(a[i],a[i++]); if(k==0) { num++;  }  } printf("输入的相同的单词的个数：\n"); printf("%d\n",num); }  这样就可以了，嘻嘻！就是把k=strcmp(&a[i],&a[i++]);里面的取地址符去掉，改成k=strcmp(a[i],a[i++]);

引用 5 楼 yangtao5220 的回复:[quote=引用 1 楼 N_sev7 的回复:] 题目本身没搞清楚要做什么？ 与哪个单词相同的单词的个数？ 还是所有输入的单词中有些是存在相同的？如果是这个意思，你这程序起码需要一个双重循环来比较吧题目是这样的。请输入一个数代表你需要输入的单词的个数，每个单词的长度不超过八个，求相同单词的个数。求写代码[/quote]  比如有下列单词： asd sadda fdsa asd fdsa asdda  就是有三个相同的对吧

[quote=引用 2 楼 Bzy_NET 的回复:] k=strcmp(&a[i],&a[i++]);//数组本身就是一个地址，不用加取地址符[/ 这个我知道，，，，，题目是这样的。请输入一个数代表你需要输入的单词的个数，每个单词的长度不超过八个，求相同单词的个数。求写代码

引用 1 楼 N_sev7 的回复:题目本身没搞清楚要做什么？ 与哪个单词相同的单词的个数？ 还是所有输入的单词中有些是存在相同的？如果是这个意思，你这程序起码需要一个双重循环来比较吧题目是这样的。请输入一个数代表你需要输入的单词的个数，每个单词的长度不超过八个，求相同单词的个数。求写代码

1.你要输入单词个数为N，那N就 i 就应该小于N，小于等于就输入n+1个值了 2.字符串不是储存在一个单位里的，gets(a[i])是从a[i[地址开始输入的


Question: 素数的筛选问题

//每次都是从k筛起，因为前面的都已近筛过了。每次加2i才仍旧为奇数。  你的问题在你自己贴的代码的注释里就已经有了了。

i不应该从自身开始啊，他自己如果是素数，就被prim[j]=1;

因為 擁有 小於i的因子的數字已經被篩過了呀。 這代碼的篩選方法是，把n的整數倍的數字篩掉。 比如15，你篩3的整數倍的時候，已經篩掉了。那麼篩5的整數倍的時候顯然沒必要再來一次，對吧。只有大於25的數字才有必要篩嘛。


Question: 整除问题

把a分解质因数来解决这个问题 #include<stdio.h> main() {   int  n=1000, a=75,i,m,s,k=30000,t,x; for(i=2;i<=a;i++)  {  m=0;t=0;      while(a%i==0) { m++;t=1; a/=i;)     if(t)       { s=n; x=0;         while(s>=i)        { x+=s/i; s/=i;}      if(x/m<k) k=x/m;     }  }  printf(" k=%d\n",k); }

我记得这是上海交大的考研题吧？还是清华的来着，忘了。 普通的方法做不了的，数据太大了，时间绝对会超时。我记得有方法是用分解质因素的，你可以去看看。好久没做这些了。

引用 3 楼 u013889450 的回复:请问楼主这是哪里的题目？ 九度Oj的题目

请问楼主这是哪里的题目？

代码问题较多，就不详细解释了，只说一句：对循环的条件还要多加斟酌。你自己diff一下代码  #include <stdio.h> #include <stdlib.h> int main(void) {     long n,a,k = 0;     int i;     int sum = 1;     while(scanf("%ld%ld",&n,&a)!=EOF)       {           for(i=1;i<=n;++i)               {                 sum *=i;               }          while (sum != 0 && sum % a == 0) {             sum = sum / a;             k++;         }         printf("%ld\n",k);      }       return 0; }

这和n！0的个数异曲同工 用二分查找


Question: 定义一个函数来返回平均值，求解哪里错了

像楼上说的，scanf("%d",&a[i]);这句应该改成浮点数输入，不然输入的整数被当成浮点数计算，就会出错，内存中浮点数的存储格式和整数不一样

%d是十进制整数。

scanf("%d",&a[i]) --> scanf("%f",&a[i]);


Question: C语言小问题求解

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

#include "stdio.h" main() { int a=3; a+=(a<1)?a:1;    //a=a+((a<1)?a:1),a<1否故((a<1)?a:1)=1 原式就等于a=a+1=3+1=4 printf("%d",a); }

a = 3 a>1   所以(a<1)?a:1得到1，a+=1  a=4

int a = 5; a += 1; printf("%d", a);为什么最后的结果是6啊？


Question: Socket编程？

引用 8 楼 u013441719 的回复:thefirstz：   包大人，看些什么书呢？ UNP，还有一本我觉得也挺好，中国人写的，Linux高性能服务器编程

不知道有多少前人掉在TCP Socket send(人多)send(病少)send(财富) recv(人多病)recv(少财富) 陷阱里面啊！ http://topic.csdn.net/u/20120210/09/51109ed0-07b9-41f2-b487-a51597f2ca01.html

引用 楼主 u013441719 的回复:IOS招聘： 3、熟悉移动平台网络Socket编程，了解TCP/IP、SOAP协议、HTTP协议，具有linux环境下C 语言开发经验技术者优先；  ---------------- 问题： 1.IOS系统Socket编程，与linux系统有什么不同？  2.IOS系统Socket编程，是开发些什么程序？ 实际上真正在开发中，一般公司都是封装好了，客户端根本不需要去了解什么socket，最终暴露给你的只有收到和发送两个接口。断线重连什么的也都是以消息的方式返回。

主要是API不同, 其他没有明显区别哈。

学校socket编程，推荐《UNIX网络编程》，另外可以参考我的系列博客，里面有现成代码可以参考。 http://blog.csdn.net/coolingcoding/article/details/7346404

引用 3 楼 u013441719 的回复:IOS系统，开发些什么应用程序，会用到Socket编程？ 给个实例！Socket编程，通常开发一些与网络有关的应用，如网络聊天，文件传输，等等

IOS系统，开发些什么应用程序，会用到Socket编程？ 给个实例！

IOS系统，与linux系统，相同么？

网络编程一般需要socket，进程间通信有时候也用socket socket编程除了架构，剩下的就是调用相关平台的api了


Question: fputs（）与fcolse（）的返回值为什么不统一？

实现不一致，没统一 标准除了技术，也包含扯皮在里面。

fclose, _fcloseall Closes a stream (fclose) or closes all open streams (_fcloseall).  int fclose( FILE *stream );  int _fcloseall( void );  Function Required Header Compatibility  fclose <stdio.h> ANSI, Win 95, Win NT  _fcloseall <stdio.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  fclose returns 0 if the stream is successfully closed. _fcloseall returns the total number of streams closed. Both functions return EOF to indicate an error.  Parameter  stream  Pointer to FILE structure  Remarks  The fclose function closes stream. _fcloseall closes all open streams except stdin, stdout, stderr (and, in MS-DOS®, _stdaux and _stdprn). It also closes and deletes any temporary files created by tmpfile. In both functions, all buffers associated with the stream are flushed prior to closing. System-allocated buffers are released when the stream is closed. Buffers assigned by the user with setbuf and setvbuf are not automatically released.  Example  /* FOPEN.C: This program opens files named "data"  * and "data2".It  uses fclose to close "data" and  * _fcloseall to close all remaining files.  */  #include <stdio.h>  FILE *stream, *stream2;  void main( void ) {    int numclosed;     /* Open for read (will fail if file "data" does not exist) */    if( (stream  = fopen( "data", "r" )) == NULL )       printf( "The file 'data' was not opened\n" );    else       printf( "The file 'data' was opened\n" );     /* Open for write */    if( (stream2 = fopen( "data2", "w+" )) == NULL )       printf( "The file 'data2' was not opened\n" );    else       printf( "The file 'data2' was opened\n" );     /* Close stream */    if( fclose( stream ) )       printf( "The file 'data' was not closed\n" );     /* All other files are closed: */    numclosed = _fcloseall( );    printf( "Number of files closed by _fcloseall: %u\n", numclosed ); }   Output  The file 'data' was opened The file 'data2' was opened Number of files closed by _fcloseall: 1     Stream I/O Routines  See Also   _close, _fdopen, fflush, fopen, freopen  fputs, fputws Write a string to a stream.  int fputs( const char *string, FILE *stream );  int fputws( const wchar_t *string, FILE *stream );  Function Required Header Compatibility  fputs <stdio.h> ANSI, Win 95, Win NT  fputws <stdio.h> or <wchar.h> ANSI, Win 95, Win NT    For additional compatibility information, see Compatibility in the Introduction.  Libraries  LIBC.LIB Single thread static library, retail version  LIBCMT.LIB Multithread static library, retail version  MSVCRT.LIB Import library for MSVCRT.DLL, retail version    Return Value  Each of these functions returns a nonnegative value if it is successful. On an error, fputs returns EOF, and fputws returns WEOF.  Parameters  string  Output string  stream  Pointer to FILE structure  Remarks  Each of these functions copies string to the output stream at the current position. fputws copies the wide-character argument string to stream as a multibyte-character string or a wide-character string according to whether stream is opened in text mode or binary mode, respectively. Neither function copies the terminating null character.  Generic-Text Routine Mappings  TCHAR.H Routine  _UNICODE & _MBCS Not Defined _MBCS Defined _UNICODE Defined  _fputts fputs fputs fputws    Example  /* FPUTS.C: This program uses fputs to write  * a single line to the stdout stream.  */  #include <stdio.h>  void main( void ) {    fputs( "Hello world from fputs.\n", stdout ); }   Output  Hello world from fputs.   Stream I/O Routines  See Also   fgets, gets, puts, _putws

标准不是什么都规定死的

我测试过，跟输出多少个字符没关系

引用 2 楼 lm_whales 的回复:统一呀： 0是非负数，EOF是负数 fclose（）只有两种状态：          成功：0，失败：EOF fputs()，有N+1 种状态 ： 成功输出N个数字符：N 失败：EOF  “fputs()，有N+1 种状态 ：成功输出N个数字符”  请问c标准有明确这么说吗？好像没找到这样的文字呢。

要搞清楚函数返回的意义

王八的屁股---规定


Question: 浮点数能使用位运算交换两个数？

2.15.C语言_数据类型_浮点数表示法 http://www.tudou.com/listplay/z5u9lwXuPKU/bQ31mR0D14U.html

位运算是底层操作，跟数据类型没有关系

取指针  强转为char*  [0] [1] [2]......位操作


Question: 将指针变量带入函数时实参变了

如1楼所说, 你应该监视 a  而不是*a   *a就是第一个字符"2"的ASCII码值  0x52

貌似你监控的是*a，不是a，a应该与s3的内容相同的吧


Question: 重大问题，请大家解释。

所以请大神慎重发言，不要满嘴跑火车……

引用 19 楼 zhao4zhong1 的回复:“C语句”和“对应汇编语句”之间的关系如同“表象”和“本质”之间的关系。 不看“本质”，很难或者不可能理解“表象”。  按照大神的说法，C的世界有着无限可能多的“本质”。原因很简单，子表达式的副作用和值的计算是无序的，所以，每个C的实现都可以自己决定这些顺序。所以，同一个表达式的求值，它们的“对应汇编语句”各自不同，所以“本质”也各不相同。

有些东西不是想不想能决定的。 置顶帖也是一沓糊涂的说……

从来不写这种代码，玩玩就行了。。。有些东西由编译器决定

引用 15 楼 lm_whales 的回复:i = 在修改 i,*p=0, 也在修改 i, 不能确定i  应该 = 0+0 还是 0+10086； *q 应该 = 10086 还是 0，是没定义的重新看了下置顶贴，释然了~谢谢

引用 12 楼 lm_whales 的回复:[quote=引用 11 楼 Automation_dmu 的回复:] [quote=引用 8 楼 sholber 的回复:] 再来看看这个：   int i = 10086, * p = & i, * q = & i; i = (* p = 0) + * q 这个没什么问题吧 ， * 的优先级高于 =和+[/quote] 有问题 有个()改变了优先级[/quote]i = ((*p)=0)+ (*p) = 0+0  =0 看不出问题在哪

引用 27 楼 sholber 的回复:[quote=引用 26 楼 u013573183 的回复:] 你这个不能为难编译器,他没办法监测出来  对于求值顺序不确定的解决办法也简单,同一条语句中只修改一个值,那肯定不会存在问题  或者你能明确的明白自己所修改的两个值是不同的变量.  要么就是在C++标准中强制规定  你要弄清语句、副作用和序列点之间的关系。不是说在同一条语句中就不能修改同一个对象的值。下面是个例子：  x = 5, x++;  //（逗号）表达式语句  if (x=y) x++;  //if语句   未定义的行为不单纯和两个副作用有关，也会在一个副作用和一个值的计算之间发生。[/quote  我所表达的观点是用一种简单的方式避免这种错误, 不是说不能,是不这样做可以避免.  有一些运算是定义了求值顺序的 比如 && 的短路特性,但是如果某类重载了此运算符,则短路特性也会消失

引用 26 楼 u013573183 的回复:你这个不能为难编译器,他没办法监测出来  对于求值顺序不确定的解决办法也简单,同一条语句中只修改一个值,那肯定不会存在问题  或者你能明确的明白自己所修改的两个值是不同的变量.  要么就是在C++标准中强制规定  你要弄清语句、副作用和序列点之间的关系。不是说在同一条语句中就不能修改同一个对象的值。下面是个例子：  x = 5, x++;  //（逗号）表达式语句  if (x=y) x++;  //if语句   未定义的行为不单纯和两个副作用有关，也会在一个副作用和一个值的计算之间发生。

他那么菜,很少能看到回答道点子上的答案

他那么菜,很少能看到回答道点子上的答案   是未定义的  主要原因在于 求值顺序不确定

任何问题，首先是一个哲学问题，不是吗？ 参考《黑客帝国》 搜“《黑客帝国》完全解析”

引用 20 楼 sholber 的回复:[quote=引用 19 楼 zhao4zhong1 的回复:] “C语句”和“对应汇编语句”之间的关系如同“表象”和“本质”之间的关系。 不看“本质”，很难或者不可能理解“表象”。  按照大神的说法，C的世界有着无限可能多的“本质”。原因很简单，子表达式的副作用和值的计算是无序的，所以，每个C的实现都可以自己决定这些顺序。所以，同一个表达式的求值，它们的“对应汇编语句”各自不同，所以“本质”也各不相同。[/quote] “世间具体的万事万物”和“对应内部或底层机制或结构”之间的关系如同“表象”和“本质”之间的关系。 不看“本质”，很难或者不可能理解“表象”。 就算自以为理解了“表象”比如引力、电磁力、时间、能量……，等哪天其“本质”被进一步发现后，也会重新理解或者完全推翻以前的理解。

楼上所言不差。

引用 11 楼 Automation_dmu 的回复:[quote=引用 8 楼 sholber 的回复:] 再来看看这个：   int i = 10086, * p = & i, * q = & i; i = (* p = 0) + * q 这个没什么问题吧 ， * 的优先级高于 =和+[/quote] 有问题 有个()改变了优先级

楼上就是这样得到高分并获得华章赠书的啊……学习了……

计算机组成原理→DOS命令→汇编语言→C语言（不包括C++）、代码书写规范→数据结构、编译原理、操作系统→计算机网络、数据库原理、正则表达式→其它语言（包括C++）、架构……  对学习编程者的忠告： 眼过千遍不如手过一遍！ 书看千行不如手敲一行！ 手敲千行不如单步一行！ 单步源代码千行不如单步对应汇编一行！  VC调试时按Alt+8、Alt+7、Alt+6和Alt+5,打开汇编窗口、堆栈窗口、内存窗口和寄存器窗口看每句C对应的汇编、单步执行并观察相应堆栈、内存和寄存器变化，这样过一遍不就啥都明白了吗。 对VC来说，所谓‘调试时’就是编译连接通过以后，按F10或F11键单步执行一步以后的时候，或者在某行按F9设了断点后按F5执行停在该断点处的时候。 （Turbo C或Borland C用Turbo Debugger调试,Linux或Unix下用GDB调试时,看每句C对应的汇编并单步执行观察相应内存和寄存器变化。）  不要迷信书、考题、老师、回帖； 要迷信CPU、编译器、调试器、运行结果。 并请结合“盲人摸太阳”和“驾船出海时一定只带一个指南针。”加以理解。 任何理论、权威、传说、真理、标准、解释、想象、知识……都比不上摆在眼前的事实！  有人说一套做一套，你相信他说的还是相信他做的？ 其实严格来说这个世界上古往今来所有人都是说一套做一套，不是吗？


Question: 关与strstr函数的运用

引用 7 楼 u013869048 的回复:[quote=引用 5 楼 jha334201553 的回复:] 把文件全部读入内存先，或者文件隐射，给其首地址（可能需要类型强转） 文件隐射是什么？？[/quote]由操作系统实现的一种机制，windows上API是 CreateFileMapping

strstr, wcsstr, _mbsstr Find a substring.  char *strstr( const char *string, const char *strCharSet );  wchar_t *wcsstr( const wchar_t *string, const wchar_t *strCharSet );  unsigned char *_mbsstr( const unsigned char *string, const unsigned char *strCharSet );  Routine Required Header Compatibility  strstr <string.h> ANSI, Win 95, Win NT  wcsstr <string.h> or <wchar.h> ANSI, Win 95, Win NT  _mbsstr <mbstring.h> Win 95, Win NT    For additional compatibility information, see Compatibility in the Introduction.  Libraries  LIBC.LIB Single thread static library, retail version  LIBCMT.LIB Multithread static library, retail version  MSVCRT.LIB Import library for MSVCRT.DLL, retail version    Return Value  Each of these functions returns a pointer to the first occurrence of strCharSet in string, or NULL if strCharSet does not appear in string. If strCharSet points to a string of zero length, the function returns string.  Parameters  string  Null-terminated string to search  strCharSet  Null-terminated string to search for  Remarks  The strstr function returns a pointer to the first occurrence of strCharSet in string. The search does not include terminating null characters. wcsstr and _mbsstr are wide-character and multibyte-character versions of strstr. The arguments and return value of wcsstr are wide-character strings; those of _mbsstr are multibyte-character strings. These three functions behave identically otherwise.  Generic-Text Routine Mappings  TCHAR.H Routine  _UNICODE & _MBCS Not Defined _MBCS Defined _UNICODE Defined  _tcsstr strstr  _mbsstr  wcsstr     Example  /* STRSTR.C */  #include <string.h> #include <stdio.h>  char str[] =    "lazy"; char string[] = "The quick brown dog jumps over the lazy fox"; char fmt1[] =   "         1         2         3         4         5"; char fmt2[] =   "12345678901234567890123456789012345678901234567890";  void main( void ) {    char *pdest;    int  result;    printf( "String to be searched:\n\t%s\n", string );    printf( "\t%s\n\t%s\n\n", fmt1, fmt2 );    pdest = strstr( string, str );    result = pdest - string + 1;    if( pdest != NULL )       printf( "%s found at position %d\n\n", str, result );    else       printf( "%s not found\n", str ); }   Output  String to be searched:    The quick brown dog jumps over the lazy fox             1         2         3         4         5    12345678901234567890123456789012345678901234567890  lazy found at position 36   String Manipulation Routines  See Also   strcspn, strcmp, strpbrk, strrchr, strspn

把文件全部读入内存先，或者文件隐射，给其首地址（可能需要类型强转）

引用 5 楼 jha334201553 的回复:把文件全部读入内存先，或者文件隐射，给其首地址（可能需要类型强转） 文件隐射是什么？？

引用 3 楼 buyong 的回复:expected 'const char *' but argument is of type 'struct FILE *' 这是这个问题最好的答案了 这条语句是什么意思？？

strstr第一个参数是一个字符串指针，，，你哪个fp是一个文件指针，，，两者类型不同，你可以强制类型转换看看效果如何

当然不可以 strstr 2个参数都是const char*


Question: [swu]调用外部函数求解

想像库一样，建库， 提供，头文件，库

引用 5 楼 u013990248 的回复:但是我们又是如何实现向<stdio.h>那样   将所有的函数写到一个头文件中呢？  复制函数头部到文件，加分号，存为x.h x.c void print_string(char str[80])  x.h void print_string(char str[80]);

但是我们又是如何实现向<stdio.h>那样   将所有的函数写到一个头文件中呢？

第一个文件  1 #include <stdio.h>   2 void enter_string(char str[80]);   3 void delete_string(char str[80], char ch);   4 void print_string(char str[80]);   5   6 void main()   7 {   8         char str[80];   9         char c;  10         enter_string(str);  11         scanf("%c", &c);  12         delete_string(str, c);  13         print_string(str);  14 } 第二个文件  1 #include <stdio.h>   2 #include <string.h>   3   4 void enter_string(char str[80])   5 {   6         gets(str);   7 } 第三个文件  1 #include <stdio.h>   2 #include <string.h>   3   4 void delete_string(char str[80], char ch)   5 {   6         int i, j;   7   8         for(i=j=0; str[i]!='\0'; i++){   9                 if(str[i]!=ch){  10                         str[j++]        = str[i];  11                 }  12         }  13         str[j]  = '\0';  14 } 第四个文件  1 #include <stdio.h>   2 #include <string.h>   3   4 void print_string(char str[80])   5 {   6         printf("%s\n", str);   7 }

while(str[i]!='\0'){  10                 if(str[i]==ch){  11                         str1[j] = str[i+1];  12                 }  13                 i++;  14                 j++;  15         } 错误明显，自己单步调试

你这个循环有问题，好好检查检查

多文件要在使用该函数的文件中对该函数进行声明后再使用。声明应该放在main函数外，最好是单独用一个头文件来放这个，我记得我上课时说过这个的吧。 至于为什么是乱码，你还是自己调试一下。准备合理的测试数据是基本的。


Question: C语言编写计算器程序，实在不知道错在哪里

崩溃的时候在弹出的对话框按相应按钮进入调试，按Alt+7键查看Call Stack里面从上到下列出的对应从里层到外层的函数调用历史。双击某一行可将光标定位到此次调用的源代码或汇编指令处。  String Manipulation These routines operate on null-terminated single-byte character, wide-character, and multibyte-character strings. Use the buffer-manipulation routines, described in Buffer Manipulation, to work with character arrays that do not end with a null character.  String-Manipulation Routines  Routine Use  _mbscoll, _mbsicoll, _mbsncoll, _mbsnicoll Compare two multibyte-character strings using multibyte code page information (_mbsicoll and _mbsnicoll are case-insensitive)  _mbsdec, _strdec, _wcsdec Move string pointer back one character  _mbsinc, _strinc, _wcsinc Advance string pointer by one character  _mbslen Get number of multibyte characters in multibyte-character string; dependent upon OEM code page  _mbsnbcat Append, at most, first n bytes of one multibyte-character string to another  _mbsnbcmp Compare first n bytes of two multibyte-character strings  _mbsnbcnt Return number of multibyte-character bytes within supplied character count  _mbsnbcpy Copy n bytes of string  _mbsnbicmp Compare n bytes of two multibyte-character strings, ignoring case  _mbsnbset Set first n bytes of multibyte-character string to specified character  _mbsnccnt Return number of multibyte characters within supplied byte count  _mbsnextc, _strnextc, _wcsnextc Find next character in string  _mbsninc. _strninc, _wcsninc  Advance string pointer by n characters  _mbsspnp, _strspnp, _wcsspnp Return pointer to first character in given string that is not in another given string  _mbstrlen Get number of multibyte characters in multibyte-character string; locale-dependent  sprintf, _stprintf Write formatted data to a string  strcat, wcscat, _mbscat Append one string to another  strchr, wcschr, _mbschr Find first occurrence of specified character in string  strcmp, wcscmp, _mbscmp Compare two strings  strcoll, wcscoll, _stricoll, _wcsicoll, _strncoll, _wcsncoll, _strnicoll, _wcsnicoll Compare two strings using current locale code page information (_stricoll, _wcsicoll, _strnicoll, and _wcsnicoll are case-insensitive)  strcpy, wcscpy, _mbscpy Copy one string to another  strcspn, wcscspn, _mbscspn,  Find first occurrence of character from specified character set in string  _strdup, _wcsdup, _mbsdup Duplicate string  strerror Map error number to message string  _strerror Map user-defined error message to string  strftime, wcsftime Format date-and-time string  _stricmp, _wcsicmp, _mbsicmp Compare two strings without regard to case  strlen, wcslen, _mbslen, _mbstrlen Find length of string  _strlwr, _wcslwr, _mbslwr Convert string to lowercase  strncat, wcsncat, _mbsncat Append characters of string  strncmp, wcsncmp, _mbsncmp Compare characters of two strings  strncpy, wcsncpy, _mbsncpy Copy characters of one string to another  _strnicmp, _wcsnicmp, _mbsnicmp Compare characters of two strings without regard to case  _strnset, _wcsnset, _mbsnset Set first n characters of string to specified character  strpbrk, wcspbrk, _mbspbrk Find first occurrence of character from one string in another string  strrchr, wcsrchr,_mbsrchr Find last occurrence of given character in string  _strrev, _wcsrev,_mbsrev Reverse string  _strset, _wcsset, _mbsset Set all characters of string to specified character  strspn, wcsspn, _mbsspn Find first substring from one string in another string  strstr, wcsstr, _mbsstr Find first occurrence of specified string in another string  strtok, wcstok, _mbstok Find next token in string  _strupr, _wcsupr, _mbsupr Convert string to uppercase  strxfrm, wcsxfrm Transform string into collated form based on locale-specific information  vsprintf, _vstprint Write formatted output using a pointer to a list of arguments

有桌面版的吗？我想知道c语言是不是有必要值得一学。现在都是java c#一类的语言。

谢谢楼上 已经可以运行了 我再研究研究

不会用vs，所以没法重现你的问题。代码改了一点，具体哪些你diff一下。用gcc编译，简单的测了一下 代码中小问题不少，不过才学半年来说已经很不错了    1 //#include <stdafx.h>   2 #include <stdlib.h>   3 #include <math.h>   4 #include <string.h>   5 #include <stdio.h>   6 typedef struct Link{   7     char s[20];   8     struct Link *next;   9 }Link, *pLink;  10   11 void Push(pLink top,char* a);  12 void Add(pLink top,char s);  13 char *Calculate(float s1,float s2, char s);  14 bool Pop(pLink top,char *a);  15 char Judge_type(char *s);  16 char Get(pLink top);  17 int Judge(char s1, char s2);  18 bool Evaluate(const char* strFile1,const char* strFile2);  19 void ReleaseLink(pLink top);  20 void Clear(pLink top);  21 bool FirstOutput(const char* strFile, pLink top,int n);  22 bool Output(const char* strFile, pLink top,int n);  23 char  *ftoa(float n);  24   25 int main(){  26     char strFile1[] = "data.txt";  27     char strFile2[] = "output.txt";  28     Evaluate(strFile1,strFile2);  29   30         return 0;  31 }  32   33   34 void Push(pLink top,char* a){  35     pLink Cur = new Link;  36     strcpy(Cur->s,a);  37     Cur->next = top->next;  38     top->next = Cur;  39 }  40   41 void Add(pLink top,char s){  42     char a[20];  43     a[0] = s;  44     strcat(top->next->s,a);  45 }  46   47 char* Calculate(float s1, float s2, char s){  48     //char a[20];  49     int ret = 0;  50     char *a = (char *)malloc(20);  51         if(s=='+') {  52                 ret = sprintf(a,"%.10f",s1+s2);  53         }  54         return a;  55 }  56   57 bool Pop(pLink top,char *a){  58     if(top->next==NULL) return false;  59     pLink next = top->next->next;  60     strcpy(a,top->next->s);  61     delete top->next;  62     top->next = next;  63     return true;  64 }  65 char Judge_type(char *s){  66     int i;  67     for(i=0;i<100;i++){  68         if (*s++ = '.')    return '1';  69     }  70     return '0';  71 }  72 char Get(pLink top){  73     char s = *top->next->s;  74     return s;  75 }  76 int Judge(char s1, char s2){  77     if(s1=='+'||s1=='-'){  78         if(s2=='+'||s2=='-'||s2==')'||s2==10) return 1;  79         else return 2;  80     }  81     if(s1=='*'||s1=='/'){  82         if(s2=='('||s2=='^'||s2=='%') return 2;  83         else return 1;  84     }  85     if(s1=='^'||s1=='%'){  86         if(s2=='(') return 2;  87         else return 1;  88     }  89     if(s1=='('){  90         if(s2==')') return 3;  91         else if(s2==10) return 4;  92         else return 2;  93     }  94     if(s1==')'){  95         if(s2=='(') return 2;  96         else if(s2=='(') return 4;  97         else return 1;  98     }  99     if(s1==10){ 100         if(s2==10) return 3; 101         else if (s2==')') return 4; 102         else return 2; 103     } 104 } 105  106 bool Evaluate(const char* strFile1,const char* strFile2){ 107     FILE* fp = fopen(strFile1,"rt"); 108     if(!fp) { 109         printf("cannot open the file"); 110         return false; 111         } 112     pLink OPTR = new Link, OPND = new Link; 113     OPTR->next = new Link; 114     *OPTR->next->s = 10, OPND->next = NULL, OPTR->next->next = NULL; 115     char c = fgetc(fp); 116     char* a=&c; 117     while(c!=EOF){ 118         int n = 1; 119         int i = 1; 120         char *x=NULL; 121         char s1[20], s2[20], s[20], *s3; 122         while(c!=10||*OPTR->next->s!=10){ 123             if(c<=57&&c>=48){ 124                 Push(OPND,a); 125                 c = fgetc(fp); 126                 while(c<=57&&c>=48){ 127                     Add(OPND,c); 128                     c = fgetc(fp); 129                 } 130                 if(c=='.'){ 131                     Add(OPND,c); 132                     c = fgetc(fp); 133                     while(c<=57&&c>=48){ 134                         Add(OPND,c); 135                         c =    fgetc(fp);} 136                 } 137             } 138             else switch(Judge(Get(OPTR),c)){ 139             case 2 : Push(OPTR,a); c = fgetc(fp); break; 140  141             case 3 : Pop(OPTR,x); c = fgetc(fp); break; 142  143             case 1 : { 144                 if(OPND->next->next==NULL&&OPND->next==NULL) {n=0; break;} 145                 Pop(OPND,s1), Pop(OPND,s2), Pop(OPTR,s); 146                 float a1 = atof(s1), a2 = atof(s2); 147                 s3 = Calculate(a2,a1,*s); 148                 Push(OPND, s3); 149                 break; 150                       } 151             case 4 : n=0; c = fgetc(fp); break; 152             } 153         } 154         if (OPND->next->next!=NULL) n=0; 155             if (i==1) FirstOutput(strFile2,OPND,n); 156             if (i>1) Output(strFile2,OPND,n); 157             Clear(OPTR), Clear(OPND); 158             delete OPND->next; 159             OPND->next = NULL; 160             c = fgetc(fp); 161     } 162     fclose(fp); 163     ReleaseLink(OPTR), ReleaseLink(OPND); 164     return true; 165 } 166  167 void ReleaseLink(pLink top){ 168     pLink Cur = top->next; 169     delete top; 170     while (Cur){ 171         pLink next = Cur->next; 172         delete Cur; 173         Cur = next; 174     } 175 } 176 void Clear(pLink top){ 177     while(top->next!=NULL){ 178         pLink Cur = new Link; 179         Cur = top->next; 180         top->next = top->next->next; 181         delete Cur; 182     } 183     pLink Cur= new Link; 184     *Cur->s = 10; 185     Cur->next = NULL; 186     top->next = Cur; 187 } 188  189 bool FirstOutput(const char* strFile, pLink top,int n){ 190         FILE *fp = fopen(strFile,"wt"); 191         int ret = 0; 192         if(!fp){ 193             printf("ERROR:cannot write the file"); 194             return false; 195         } 196  197     if(n==1){ 198         //ret = fprintf(fp,"%s",top->s); 199         ret = fprintf(fp,"%s",top->next->s); 200         ret = fprintf(fp,"\n"); 201         fclose(fp); 202         return true; 203     } 204     if(n==0){ 205         fprintf(fp,"ERROR"); 206         fprintf(fp,"\n"); 207         fclose(fp); 208         return true; 209     } 210 } 211  212 bool Output(const char* strFile, pLink top,int n){ 213         FILE *fp = fopen(strFile,"at"); 214         if(!fp){ 215             printf("ERROR:cannot write the file"); 216             return false; 217         } 218     if(n==1){ 219         fprintf(fp,"%s",top->s); 220         fprintf(fp,"\n"); 221         fclose(fp); 222         return true; 223     } 224     if(n==0){ 225         fprintf(fp,"ERROR"); 226         fprintf(fp,"\n"); 227         fclose(fp); 228         return true; 229     } 230 } 231  232 char  *ftoa(float n) 233 { 234    char *a=new char[100]; 235    sprintf(a,"%.10f",n); 236    return a; 237 }

错误是这样的

我的编译软件里没有其中的一个头文件，而且我是菜鸟，不好意思帮不到你了

看了以后眼都晕了，程序怎么报错啊，


Question: 一个C语言基础指针的问题

引用 3 楼 baichi4141 的回复:除了在定义的时候可以整体初始化，数组在大多数情况下不能整体使用 楼主你猜[]这个操作符在语言标准里是怎么定义的？是用指针来定义的的！每次你写a[b]，如果a是一个数组，它都首先转化为指向第一个元素的指针pa，然后再执行*(pa+b) 在函数参数列表里，*a和a[]完全一样，前者更本质，后者更适合还不懂指针的初学者 引用 4 楼 gigglesun 的回复:都可以，两种方法一样  谢谢两位

都可以，两种方法一样

引用 1 楼 user-3 的回复:形参使用数组形式也是可以的,但是要指定数组长度吧 你的意思是说，如果用*b，就是不指定它的长度了？b[]指定长度了吗？

形参使用数组形式也是可以的,但是要指定数组长度吧


Question: 求助（一个字符串乱序比较的acm问题）

引用 6 楼 vichare 的回复:都不能改帖子。。。 多次操作和一次是一样的，还是用KMPkmp算法的确可以用，3Q

引用 3 楼 angel_su 的回复:试试取消c数组不要花时间去重组字串，直接strncmpstrncmp不是比较前几位的字符么，拆分比较怎么做到？

都不能改帖子。。。 多次操作和一次是一样的，还是用KMP

不对，X是任意次操作，那岂不是任何顺序都能得到？

用KMP算法

试试取消c数组不要花时间去重组字串，直接strncmp

引用 1 楼 user-3 的回复:上原题吧~ 准确一点原题就代码注释

上原题吧~ 准确一点


Question: 求解八皇后中出现的问题

第二个有解，上面说错了


Question: 求问哪错了

7         scanf("%d",&i);

问题：for循环的使用和scanf中的变量应该是地址哦。

#include<stdio.h>   int main()  { 	int a[]={1,2,3,4,5,6,7,8,9}; 	for (int i=0;i<10;i=i+1) 	 { 		 		 if(a[i]%2==1)          printf("%d",a[i]); 	 } 	return 0; }

朕也来编程了…… #include <stdio.h>  int main (void) {     for(int i = 1; i<10; i++) if (i%2) printf("%d ", i); }

楼主错好多地方啊。。

# include <stdio.h> ///////////stdio.h   int main() {     int i;     for(i=1; i<10; i++)         //    scanf("%d",i);     {         if(i%2 == 1)             printf("%2d\n", i);     }     return 0; } 关于数组，lz可以看看书啊！也可以看看这个——http://blog.csdn.net/u012421456/article/details/18938553

这个 j 该去掉，没用到，忘了去

# include <stdio.h> ///////////stdio.h  int main() { 	int i, j; 	for(i=1; i<10; i++) 		//	scanf("%d",i); 	{ 		if(i%2 == 1) 			printf("%2d\n", i); 	} 	return 0; }  lz应该好好看看书啊

#include<stdio.h> int main() { 	int a[10]={0,1,2,3,4,5,6,7,8,9},i; 	for(i=1;i<10;i++) 	{ 		if(a[i]%2==1) 		printf("%d ",i); 	} 	return 0; } 刚才那个多定义了一个j，现在好了

#include<stdio.h> int main() { 	int a[10]={0,1,2,3,4,5,6,7,8,9},i,j; 	for(i=1;i<10;i++) 	{ 		if(a[i]%2==1) 		printf("%d ",i); 	} 	return 0; }

楼主多看看书吧，这么一个简单的程序，错的地方太多了 int i,; for(i = 0; i < 10; i++) {        if(i % 2 != 0)             printf("%d ", i); } printf("\n");

问题是 编程打印小于10的正奇数。 程序要求 使用if条件判断语句，输出时，每两个数字之间有一空格。 还有如何定义一个数组我现在写的是   1 #include<stdio.h>   2   3 int main()   4 {   5         int i,k,a[k]=   6         for(i=0;i<10;i=i+1){   7   8         if(k%2==1)   9                 printf("%d",k);  10         }  11         return 0;  12 }  13 ~

你要实现什么功能


Question: 求最大递增数遇到的问题

虽然不知道你的最大递增数是求什么的，不过printf("%s\n",maxshu);应该改成printf("%d\n",maxshu);吧，在我这就可以了

求大神指教，不知道哪里错了


Question: [swu]输出结果

恩  好  我输出的结果是  7 8 8 8

确实是毫无意义的问题。不值得大家来费神。 楼主应该首先想想要问什么问题。

一般是不用考虑这些的，即使有特殊的情况，也可以用其他方式避免这种情况出现，这个问题流传已经很广了

VC6.0完整绿色版win8.1下，结果是 8 8 8 7，这个问题没啥意义，不同的机器或编译器得到的结果可能就不同，lz好好看看置顶帖吧——http://bbs.csdn.net/topics/370153775

怎么没有意义？闭上眼睛，客观世界就不存在了吗？

毫无意义的题目

这就有意思吗？

Side effects and value computations of the arguments of the called function are unsequenced.

c++标准没有规定参数的计算顺序，输出结果和编译器相关，楼主看看置顶帖。 http://bbs.csdn.net/topics/370153775


Question: 基础问题，变量值传递问题。

自己顶，。。。。

在a.cpp中定义全局变量CString cstr 在a.h中extern声明 b.cpp中#include "a.h"

不能定义在头文件中，全局变量最好定义到源文件，这样做是为了避免头文件被多个源文件包含，导致编译出现变量重定义  全局变量在源文件定义，在头文件用extern来声明

这么快，刚刚打完字 就解决了～～

.h文件不是独立的编译单元，在预处理时会做复制处理罢了 也就是说，如果在a.h定义了一个cstr，凡是包含了 a.h 都将在预处理时做一次复制，例如你的 a.cpp，b.cpp就都定义了一个 cstr，但是他们的内存地址不一样  所以，.h文件不要定义变量，只定义类型  extern是这样用的： a.cpp定义了一个非static变量cstr，全局的。那么 b.cpp也想用这个变量，就需要 extern CString cstr; 这样做的目的是在编译b.cpp时知道这个变量是在其他文件定义，至于是哪儿定义的，需要在连接时的符号解析时才知道

弄好了，有同样问题的请查阅下面链接： http://developer.51cto.com/art/201104/256820.htm


Question: 关于C语言二级考试中一段冒泡排序的疑问

没有人解答吗？

写的好像有点混乱 当J=2;k=3;i=0时 就是之前K的值为3，执行strcmp程序之后，K被赋值为k=i=0;了，但是执行完冒泡之后K的值是0还是3呢当再次执行for语句i++的时候，我自己测试感觉是k=3可能对这个理解的还不是很透，不过总算是在慢慢啃而且没退步


Question: C编程，新人求助

谢谢各位，可是为什么我改了以后编译通过，但是运行的结果不对呢？ #include <stdio.h> #include <stdlib.h> void main ()  { 	int i,j;  	char a; 	scanf("%s",&a); 	#define m sizeof(a) 	j=m; 	char str1[m],str2[m]; 	scanf("%s",str1); 	for (i=0;i<=j-1;i++) 	 { 		 int t(char x); 		 str2[i]=t(str1[i]); 	 }     printf("%s",str2);  	system("pause"); }  int t(char x) { 	int y; 	if (x>=0&&x<=7) 	{ 		y=x+2; 	    return (y); 	} 	else if (x>7&&x<=9) 	{ 		y=x%10; 	    return (y); 	} 	else printf("error"); }

当做字符串处理，先定义一个char a[MAX],再scanf("%s",a); C++中可以直接定义一个string a;再cin>>a；即可

char str1[j],str2[j];                        //此行报错，怎么改啊，求大神！   这里的申明中“j”不能使变量，必须是常量或者常量表达式   处理！  可以  #define m 10 ... 下面申明就可以了 不知道长度的话，可以写个if来判断长度自适应

#include <stdio.h> #include <stdlib.h> void main ()  { 	int i,j;  	char a; 	scanf("%s",&a); 	j=sizeof (a); 	char str1[j],str2[j];                        //此行报错，怎么改啊，求大神！ 	scanf("%s",str1); 	for (i=0;i<=j-1;i++) 	 { 		 int t(char x); 		 str2[i]=t(str1[i]); 	 }     printf("%s",str2);  	system("pause"); }  int t(char x) { 	int y; 	if (x>=0&&x<=7) 		y=x+2; 	else if (x>7&&x<=9) 		y=x%10; 	else printf("error"); }

你可以指定一个长度, 能体现你的功能就行了. 实际产品中又不是用户从输入字符串, 根据实际情况分配动态内存就可以了

可是我不知道用户输入的字符串长度，怎么确定数组的元素个数？？？

谢谢大家，我终于编出来了，换了一种思路！

读一个字符，加2，输出，再读一个字符，加2，输出…… 根本没必要在内存中保存

那怎么改？？？

第七行定义a是char类型，怎么输入时用%s啊？


Question: 冒泡排序，大神帮我检查代码啊

如果你是在vc中运行的话，局部变量的定义要放在函数的开通部分编译才会通过。 比如： void f() { ..............代码.............. for(int i=0; i<10; i++) } 应该改为 void f() { int i; ..............代码............. for (i=0; i<10; i++) }

10个数只进行9轮排序。所以i<10改成i<9 第1轮至多进行9趟比较，第2轮至多进行8趟比较...。所以应该是j<9-i。 每一趟是从头开始把每相邻的两个数进行比较排序，所以应该是num[j]>num[j+1]而不是num[i]>num[i+1]

int num [] = {10,9,8,7,6,5,4,3,2,1}; 	printf("数组十位数字为："); 	for (int i = 0; i<10; i++) 		printf("%d,",num[i]); 	printf("\n"); 	for (int i =0; i< 9; i++) 	{   		for (int j = 0; j< 9 -i; j++) 		{  			if (num[j]>num[j+1]) 			{  				int tmp = num[j]; 				num[j]=num[j+1]; 				num [j+1]=tmp; 			} 		} 	} 	for (int i=0; i<10; i++) 		printf("%d,",num[i]); 	printf("\n"); 	return 0;


Question: 动态链接库的加载问题

引用 楼主 u014123498 的回复:是否每个程序的地址空间里都有映射kernel32.dll?（哪怕导入表为空）  那么如果我显式加载kernel32.dll，windows是不是就不会再映射一次了？  其实你的工程设置中都已经显示加载了，否则根本不能link。看你的工程设置的link部分

引用 楼主 u014123498 的回复:是否每个程序的地址空间里都有映射kernel32.dll?（哪怕导入表为空）  那么如果我显式加载kernel32.dll，windows是不是就不会再映射一次了？ 是的，一个dll只会被同一个进程加载一次，不管是显示还是隐式，一旦加载后，再加载只是增加引用计数而已。


Question: 01背包问题

因为循环里运算  [i-1]

引用 楼主 tingfengx 的回复:#include<iostream> # include<cstring> # define max(a,b) a>b?a:b using namespace std; int main() {      int dp[101][1001],m,T,w[101],val[101],i,j;     cin>>T>>m;     for(i=1;i<=m;i++)         cin>>w[i]>>val[i];     memset(dp,0,sizeof(dp));     for(i=1;i<=m;i++)      for(j=0;j<=T;j++)//j相当于上面说的V-c[i]          {     if(j>=w[i])         dp[i][j]=max(dp[i-1][j],dp[i-1][j-w[i]]+val[i]);//放还是不放的选择     else dp[i][j]=dp[i-1][j];      }      cout<<dp[m][T]<<endl;      return 0; }  为什么循环是从i=1开始，而j从0开始？数组下标不是都从0开始吗 我没有具体看这个背包问题是解决什么问题的，但是如你所说，i从几开始是和程序设计的逻辑相关的，语法上数组都是从下标0开始，但是可能这个程序的设计需要抛弃0从1开始呢？这个用法没有问题，要看实际的逻辑需要。


Question: 关于VS2010 32位控制台应用程序项目生成的文件夹里的文件的意思

觉得内在的联系是什么啊

ipch是 ip change的缩写

看一下里面有什么文件就差不多知道了，这个问题一般在讲windosw编程的书上会提到


Question: 打神来帮我看一下哪里错了

楼主这是不会用vs2010啊，你新建一个工程吧，然后再敲这些代码

我也覺得樓主是 在做編程練習，在工程裡開了n個.c文件，每個裡面都有int main()

看样子很有可能是编译器问题

楼主，推荐一个编译器给你吧，DEVc++，希望对你有用

很明显,这是一个工程里面有了两个以上的main函数嘛!

引用 15 楼 u014106516 的回复:引用 12 楼 lming_08 的回复:把工程中的jishuai.cpp或jishuai.c移除掉   我重新建了一个工程文件了  还是不行  我重新建了那个都没有你说的你个文件 怎么移除啊  你确定你建立的工程是空工程？

这个根本是刷分贴

引用 16 楼 angel_su 的回复:决定你是新建一个文件，不是新工程，没搞清阿，现在工程里3个main啦... 哦     你是在那里看出3个main的啊

#include<stdio.h> int main(void) {int a;    int b;      int c;        a=10;          b=20;            c=a*b;   printf("c=%d\n",c);     return 0; } 后一个双引号也错了。

printf("c=%d\n,c");  这个改成 prinft("c =%d\n",c); 楼主太马虎了啊。。。

我用vc6变异没有错，直接copy你的代码，。你用的vs容错率更高，应该不会报错，可能就是你的符号的全角半角写错了，还不容易分辨

引用 15 楼 u014106516 的回复:引用 12 楼 lming_08 的回复:把工程中的jishuai.cpp或jishuai.c移除掉   我重新建了一个工程文件了  还是不行  我重新建了那个都没有你说的你个文件 怎么移除啊你VS左侧的解决方案里面项都展开看看有没有jishuai.cpp，有就右键移除

决定你是新建一个文件，不是新工程，没搞清阿，现在工程里3个main啦...

引用 11 楼 angel_su 的回复:认真看错误信息，不是说你的代码有问题，是说你的工程里有两个main函数，链接出错，新建一个工程重做或者把无关的文件剔出。  还是不可以

你们看吧还是不行

把工程中的jishuai.cpp或jishuai.c移除掉

#include<stdio.h> int main(void) {int a;    int b;      int c;        a=10;          b=20;            c=a*b;   printf("c=%d\n,c");     return 0; } 因为你没有贴出报错的具体信息，可能的问题： 1、分号、括号的中英文状态，检查下是否全是英文状态输入的； 2、printf("c=%d\n,c"); 这个分号错了，检查看，改成 printf("c=%d\n",c);    ； 我将你的程序，录入我的VS2010编译没有问题。你得仔细检查下分号括号之类的。不然就贴出错误信息，否则就是编译器没弄好。 给点建议，在写程序时，最好将你声明的变量初始化，这是一个好的习惯，虽然在写这种简单程序影响不到结果，但在做大项目，很多变量时，可能会给你带来很多困扰。

LZ 认真看书~~


Question: 关于超级终端仿真程序的疑问（总是有1个error）

引用 1 楼 user-1 的回复:ComlistenThread，ComListenThread，l没有大写。。。 改了以后出了这个问题


Question: 输出乱码，是不是缓冲区的问题？？

请检查scanf的返回值。 http://bbs.csdn.net/topics/390471779

引用 9 楼 u011779380 的回复:[quote=引用 7 楼 u012421456 的回复:] [quote=引用 2 楼 r_Jimy 的回复:] 楼主的scanf按下面这样用就没问题了，加个,号为什么会有问题跟scanf 的实现有关，期待大神详解  scanf("%d%s%lf",&age,name,&salary);  scanf中一般不要使用非输入控制符（这里指的是逗号），关于这个，lz可以看看——http://blog.csdn.net/u012421456/article/details/18501309[/quote] 我想请教下scanf()的用法二，为什么是输入m123才不出错？[/quote] lz没仔细看吧！m在那儿是非输入控制符，非输入控制符必须原样输入  下面这是那儿的话（重要的地方——红色部分）  scanf（“非输入控制符 输入控制符”，输入参数）； 功能： 将从键盘输入的字符转化为输入控制符所规定格式的数据，然后存入已输入参数的值为地址的变量中（非输入控制符必须原样输入）。

引用 7 楼 u012421456 的回复:[quote=引用 2 楼 r_Jimy 的回复:] 楼主的scanf按下面这样用就没问题了，加个,号为什么会有问题跟scanf 的实现有关，期待大神详解  scanf("%d%s%lf",&age,name,&salary);  scanf中一般不要使用非输入控制符（这里指的是逗号），关于这个，lz可以看看——http://blog.csdn.net/u012421456/article/details/18501309[/quote] 我想请教下scanf()的用法二，为什么是输入m123才不出错？

# include <stdio.h>  int main() {	 	int age; 	char name[20]; 	double salary;  	scanf("%d %s %lf", &age, &name, &salary); 	printf("i am %s, %d years old, salary:%f\n", name, age, salary);  	return 0; }

引用 2 楼 r_Jimy 的回复:楼主的scanf按下面这样用就没问题了，加个,号为什么会有问题跟scanf 的实现有关，期待大神详解  scanf("%d%s%lf",&age,name,&salary);  scanf中一般不要使用非输入控制符（这里指的是逗号），关于这个，lz可以看看——http://blog.csdn.net/u012421456/article/details/18501309

测试了下，使用 scanf("%d,%lf,%s",&age,&salary,name); 在控制台输入时也以,间隔如：1,3.5,jim可以正常读数据 使用 scanf("%d %s %lf",&age,name,&salary); 在控制台输入时以空隔做间隔如：10 jim 3.5也可以正常读数据 由此可以推断如下几点： 1.scanf实现时，格式串不加间隔默认以空格或回车作为间隔符读数据 2.如果我们加了间隔，则以我们加的字符为间隔符 3.我们加了间隔符，如果接收到回车符则结束（楼主的情况就是只输入一个数字，按了回车控制台直接打印内容     不再等待输入） 4.采用"%s"格式串时，可用空格或不使用间隔符而不能用逗号作为间隔符

引用 1 楼 r_Jimy 的回复:%s输出的话，name应以'\0'结尾 建议输出前将name[19]=0;这样试了也不行

引用 2 楼 r_Jimy 的回复:楼主的scanf按下面这样用就没问题了，加个,号为什么会有问题跟scanf 的实现有关，期待大神详解  scanf("%d%s%lf",&age,name,&salary); 用空格也是乱码

%d后面可以加逗号，但这时你输入也要输入逗号，%s后不能加逗号，逗号不能使用%s正确地结束，所以最好用空格  scanf("%d %s %lf",&age,name,&salary);

%s输出的话，name应以'\0'结尾 建议输出前将name[19]=0;


Question: c指针自加问题

P 是指向int型的指针，p++等价于 p = p当前值 + sizeof(int)； 第一个for循环执5次，p++执行了5次，在执行第二个for以前 p已经指向了a[4]之后，即 p == &a + 5*sizeof(int)，明显p指向 的单元已经超出了数组的范围

1：指针是int类型，自加一次应该是增加一个int长度 -------------------------------------------------------------------- 指针是指针，int是int，指针怎么变成int了……

# include<stdio.h> #include <iostream> using namespace std; int main() {     int a[5];     int * p =&a[0]; 	cout<<p<<"  "<<p+1<<endl; 	int *pp =a; 	cout<<pp<<"  "<<pp+1<<endl; 	int (*ppp)[5] =&a; 	cout<<ppp<<"  "<<ppp+1<<endl;       for (int i =0; i<5; i++) 	{		 		scanf("%d",p+i); 	} 	     for (int j=0; j<5; j++) 	{ 		printf("%d ",*(p+j)); 	}     printf("\n");      	 	 	int cc; 	cin>>cc; 	return 0; }     1：指针是int类型，自加一次应该是增加一个int长度 2：楼主的p一直在执行自加操作，不论是一个int长度，还是数组长度，都不可能输出正确结果 3：要想自加一次增加一个数组长度，就要将指针定义为指向数组的指针，

引用 3 楼 zhb111hy 的回复:那指针是int类型，自加一次不应该是增加一个int长度吗？ 按照谭浩强的解释就是增加了一个数组的长度，不明白不明白自加一次是增加一个int长度，数组有5个int长度

引用 2 楼 piaobotudou 的回复:他应该是这个意思，就是第一次循环结束后已经越界 对，他的意思就是这样的，我也就因为这个纠结了……&

他应该是这个意思，就是第一次循环结束后已经越界

第二次循环前p已经等于p+5了，所以已经越界


Question: 编译原理的小证明题  求大神解答

引用 4 楼 user-2 的回复:证明一个language不是regular language用的是标准的pumping lemma。你先把pumping lemma看懂，然后用pumping lemma说明矛盾。 这个的确得仔细看。我当年学的时候班级里大半都花了挺长时间理解的。  好的 谢谢

写出合理的产生式就差不多了，只要能推出你要证明的结果。

引用 1 楼 oYinGui1 的回复:S->AB, A->0A, B->1B  谢谢你啦  这个类型的题我的教材里没有的  不知道怎么下手 是只要证明对应的产生式没有出口就行了吗。。。。。。。。。

S->AB, A->0A, B->1B


Question: c动态分配二维数组地址失败

int getArrayLength(point* pts) {     int length;     length = sizeof(pts)/sizeof(point);     return length; } 1.你没有声明point类型    用typedef struct point{   }point; 2.对指针的sizeof结果为4     如果你声明了类型point    那么sizeof  point =16   你可以打印return  的返回值  为0 3.你代码太长了    实在不想看     recalloc是重新分配一整块内存  如果不能在原malloc分配的内存后面进程扩充就   会重新分配一整块内存   把原内存的数据拷贝到重新分配的内存中   指针指向realloc分配的内存    原内存数据被丢弃掉  这里再检查下

二级指针怎么和二维数组勾搭上了

引用 7 楼 poiu710 的回复:ceterPoints =(point*)realloc(classesDetribution这句有问题，这句把classesDetribution已经是变成了野指针，使用野指针当然报错 额。。。不好意思，这个是我直接复制的时候忘记改变base的变量了。。 我在自己测试一下，不行的话就换个思路来写这个算法了。

引用 4 楼 user-3 的回复:sizeof任何指针大小都一样 我一向建议只使用一维数组  好像是这样的。我测试了一下。隐约记得老师以前说过，结构体使用sizeof的大小好像和结构体变量位数最大的那个相同。

引用 3 楼 poiu710 的回复:从你的程序中看出来，你对值传递和指针传递不明白，不要以为用指针作参数就是指针传递，还有sizof()操作符不明白。 嗯，是这样的。指针用的比较少，现在比较特殊，所以才使用c来写程序的。至于sizeof还是以前上课的时候学数据结构学的用法，前辈能看出来大概问题在哪里呢？

引用 4 楼 user-3 的回复:sizeof任何指针大小都一样 我一向建议只使用一维数组 不会把，int*和double*难道sizeof也一样？我也在思考，是不是二维数组造成的问题，在不行的话就改用一维数组。即便如此，我还是想弄明白具体的原因。二维数组应该是可以动态分布的吧。

sizeof任何指针大小都一样 我一向建议只使用一维数组

引用 1 楼 poiu710 的回复:代码没看完，但这个getArrayLength函数错了   //计算数组的长度 int getArrayLength(point* pts) {     int length;     length = sizeof(pts)/sizeof(point);     return length; }  sizeof(pts) ==4，sizeof(point) 应该是16 我修改成了//计算数组的长度 int getArrayLength(point* pts) { 	int length; 	length = sizeof(pts)/sizeof(pts[0]); 	return length; } 这样应该是对的。我自己还在测试这个问题，第一次循环完全可以，第二次循环就在realloc这里出问题了。不知道什么问题。


Question: 新手求助！！请问这个程序到底哪里错了！

这个for用的不对吧

引用 3 楼 angel_su 的回复:编译器应该会警告a没初始化... 额。。。。没有警告额。。。。

编译器应该会警告a没初始化...

引用 1 楼 user-3 的回复:没有看里面的循环逻辑。不过10的6次方已经可以让int类型已经溢出了，试试long 用了long   依旧没办法解决 。。。。


不会吧，这个在vs上测试了，而且注释了是会内存泄漏？但不影响吧？。。。看来。。。还是我自己看看吧。。

rightJudge被你注释的那些行，不会影响其他功能么？

我在dev c++下debug是没错的，也编译通过了，但一运行就直接弹出一个错误对话框停止了。在vs下没有以上问题。 至于是不是链接出错，应该不会吧，因为只是rightJudge函数出错了，把它注释掉就能通过，而它里面的苦函数在别的函数中也有用到。。 啊，，头疼。。 谢谢了

另外楼主是不是在链接的时候出的错误呢，是不是哪个库函数没有定义？

楼主说的用指针会直接停止具体是什么情况，内存申请成功了吗？


Question: 如何方便查看I/O函数的参数

引用 4 楼 u013921360 的回复:[quote=引用 3 楼 user-1 的回复:] [quote=引用 2 楼 u013921360 的回复:] [quote=引用 1 楼 user-1 的回复:] 常用自然记住，不常用的用的时候查 如果要用的时候不允许查比如说学生要考试，那只能平时多练习 那查的时候去哪查？我的意思是最好能在电脑里找到函数声明[/quote] 好一点的编译环境都可以直接右键跳到函数声明 复杂一点的函数光看声明看不懂，查书查手册上网查资料找老师找领导等等等等[/quote] 如果不用IDE怎么办 [/quote] 如果不用IDE，就自己找到编译器编译所需的头文件放在哪里 不过我觉得连这几个简单函数都记不住的，要记住每个函数所在头文件的位置更没戏

引用 3 楼 user-1 的回复:[quote=引用 2 楼 u013921360 的回复:] [quote=引用 1 楼 user-1 的回复:] 常用自然记住，不常用的用的时候查 如果要用的时候不允许查比如说学生要考试，那只能平时多练习 那查的时候去哪查？我的意思是最好能在电脑里找到函数声明[/quote] 好一点的编译环境都可以直接右键跳到函数声明 复杂一点的函数光看声明看不懂，查书查手册上网查资料找老师找领导等等等等[/quote] 如果不用IDE怎么办

引用 2 楼 u013921360 的回复:[quote=引用 1 楼 user-1 的回复:] 常用自然记住，不常用的用的时候查 如果要用的时候不允许查比如说学生要考试，那只能平时多练习 那查的时候去哪查？我的意思是最好能在电脑里找到函数声明[/quote] 好一点的编译环境都可以直接右键跳到函数声明 复杂一点的函数光看声明看不懂，查书查手册上网查资料找老师找领导等等等等

引用 1 楼 user-1 的回复:常用自然记住，不常用的用的时候查 如果要用的时候不允许查比如说学生要考试，那只能平时多练习 那查的时候去哪查？我的意思是最好能在电脑里找到函数声明


Question: 字符串逆转输出问题

现在懂了，感谢各位的精彩回复

str+1，所以占用了一个，去掉+1

我觉得改成这样更标准更好理解一些 #include<stdio.h> void reverse(char*str){     if(*str!='\0'){         reverse(str+1);         printf("%c",*str);     }    } void main(){     char a[]="dlroW olleH";     char b[]="margorp C a si sihT\n";     char c[]="doog yreV\n";     reverse(a);     reverse(b);     reverse(c);     printf("\n\n\n\n"); }

在reverse(++str)过程中对str进行了++，所以递归返回后下面的printf输出的就是第二个字符了，把第一个字符加过去了，修改如下： void reverse(char*str){     if(*(str)!='\0') 	{         reverse(++str); 	    printf("%c",*(--str));     }    }

在线等大神！


Question: c字符问题

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

第一句就错了

str定义出错，，char str是个字符，不能赋予一个字符串

引用 楼主 zhb111hy 的回复:要求吧字符串中整数打出来（位置左） 不太明白lz的这句话的意思，不知道下面的代码符不符合楼主的意思 # include <stdio.h>  # include <string.h>  int main()  {     char str[9]={'1', '3', '4', 'a', '2', '3', '1', 'b'};   //char是字符类型，不能存放字符串，如果想存放字符串，需要用字符数组   //  char * p = &str[9];     int len = strlen(str);     for (int i=0; i<len ; i++)  	{         if ((str[i]>='A' && str[i]<='Z') || (str[i]>='a' && str[i]<='z')) 		{             str[i] = '0';         }      }      printf("%s\n", str);  	return 0; }

#include<stdio.h>  #include<string.h>  int main()  {      char str[]="134a231b";      char * lp1=str;      char * lp2=str;      int len =   strlen(str);       for (int i =0;i<=len ; i++)      {          if(lp1[i]<'0'||lp1[i]>'9')          {              lp1[i]='\0';              if(lp1>lp2)                   printf("%s\n",lp2);              lp2=lp1+1;           }      } }  这是输出所有数字串的，没有经过测试。

引用 4 楼 PDD123 的回复:[quote=引用 3 楼 user-6 的回复:] [quote=引用 1 楼 PDD123 的回复:] #include<stdio.h> #include<string.h> int main() {     char str[]="134a231b";     int len =   strlen(str);     for (int i =0;i<len ; i++)     {         if(str[i]<'0'||str[i]>'9')         {             str[i]='\0';             break;         }     }     printf("%s",str); } 判断到除0-9以外字符就break，字符串中只有一个这样的字符吗？[/quote]  楼主似乎就只需要输出一个字符串。[/quote] LZ的原文：一个练习题，要求吧字符串中整数打出来（位置左） 所以只是LZ的替换成'\0'的方法不可行而已

引用 3 楼 user-6 的回复:[quote=引用 1 楼 PDD123 的回复:] #include<stdio.h> #include<string.h> int main() {     char str[]="134a231b";     int len =   strlen(str);     for (int i =0;i<len ; i++)     {         if(str[i]<'0'||str[i]>'9')         {             str[i]='\0';             break;         }     }     printf("%s",str); } 判断到除0-9以外字符就break，字符串中只有一个这样的字符吗？[/quote]  楼主似乎就只需要输出一个字符串。

引用 1 楼 PDD123 的回复:#include<stdio.h> #include<string.h> int main() {     char str[]="134a231b";     int len =   strlen(str);     for (int i =0;i<len ; i++)     {         if(str[i]<'0'||str[i]>'9')         {             str[i]='\0';             break;         }     }     printf("%s",str); } 判断到除0-9以外字符就break，字符串中只有一个这样的字符吗？

char str="134a231b";-->定义的是字符，赋的值是字符串 再提示一点，如果你想改成char *str也是错的。


Question: 如何解开这个加密算法

能解出这个加密算法吗？ 我需要前面的10数能得出后面的4位数来

这是不可逆加密


Question: C语言数据结构单向链表问题》问什么这条程序只有查找是对的，删除和插入都错了？

代码有点长… 加点测试语句，找到出问题的代码区域段，贴上来讨论下

所有参数传递本质上是值传递      你传递的只是实参指针值的一份拷贝      形参改变不了实参的值       就像a=5    func(a)    在func中试图改变a是改变不了的一样      所以你的删除和插入错误     而查找不改变链表的结构  所以能够成功     祝你好运能够理解      代码太长实在难看   但是你的错误也是大众问题每个学C的人都会经历

给lz一份自己写的代码参考一下 /*---------------------------------------------- File: G:\soft\02\168.c Date: 2014-3-26 17:55:18 Author: 1174843091@qq.com 利用malloc创建链表，增加、删除或倒序链表 ----------------------------------------------*/ #include<stdio.h> #include<malloc.h>  struct student { 	int num; 	struct student *next; };  //检测链表降序/顺序 int shun(struct student *head) { 	struct student *p,*q; 	for(p=q=head;p!=NULL;) 	{ 		if(p->num<q->num)return 0; 		q=p; 		p=p->next; 	} 	return 1; }  //输出链表 void prf(struct student *head) { 	while(head!=NULL) 	{ 		printf("%3d",head->num); 		head=head->next; 	} 	printf("\n"); }  //倒序链表 struct student *dao(struct student *head) { 	struct student *p,*q,*temp; 	for(p=NULL,q=head;q!=NULL;) 	{ 		temp=q->next; 		q->next=p; 		p=q; 		q=temp; 	} 	head=p; 	return head; }  int main() { 	int n,i=1,num,flag; 	char c[100]; 	struct student *head,*p,*q,*temp; 	printf("请输入要创建的链表数:\n"); 	scanf("%d",&n); 	if(n<1)return 0; 	head=p=q=(struct student *)malloc(sizeof(struct student)); 	q->num=i++; 	for(n--;n>0;n--) 	{ 		q=p; 		p=(struct student *)malloc(sizeof(struct student)); 		p->num=i++; 		q->next=p; 	} 	p->next=NULL; 	q=p=head; 	prf(head); 	getchar(); 	for(i=1;head!=NULL;i=1,q=p=head) 	{ 		if(flag=shun(head))printf("当前链表为升序\n"); 		else printf("当前链表为降序\n"); 		printf(" 你想要插入一个节点(a) 删除一个节点(b) 倒置链表(c) 退出(d)?\n"); 		gets(c); 		switch(c[0]) 		{ 			case 'a': 			{ 				printf("请输入插入节点的数值:\n"); 				temp=(struct student *)malloc(sizeof(struct student)); 				scanf("%d",&temp->num); 				if(flag)for(q=p=head;p!=NULL&&p->num<temp->num;) 				{ 					q=p; 					p=p->next; 				} 				else for(q=p=head;p!=NULL&&p->num>temp->num;) 					p=p->next; 				temp->next=p->next; 				p->next=temp; 				prf(head); 				getchar(); 				break; 			} 			case 'b': 			{ 				printf("请输入删除节点的数值:\n"); 				scanf("%d",&num); 				if(head->num==num)head=head->next; 				for(;p!=NULL&&p->num!=num;) 				{ 					q=p; 					p=p->next; 				} 				if(p==NULL) 				{ 					printf("没有找到!"); 					getchar(); 					break; 				} 				q->next=p->next; 				prf(head); 				getchar(); 				break; 			} 			case 'c':head=dao(head);prf(head);break; 			case 'd':return 0; 	} 	} 	if(c[0]!='c')printf("链表节点已全部删除!"); 	getchar(); 	return 0; }

自己先调试下，整理下代码吧！然后把有问题的部分贴出来！ 不要一下子什么都没有，就一大片代码的，下次就可能被删帖的哦！

http://blog.csdn.net/wonggonghong/article/details/21527577 可以参考这篇文章


Question: C语言排序去重,谁能看一下哪里错了啊??

程序没什么问题吧，应该是输入错误

#include <stdio.h> #include <stdlib.h>  #define N 100  int cmp1(const void* a, const void* b) {     return *(int*)a - *(int*)b; }  int cmp2(const void*a, const void* b) {     return *(int*)b - *(int*)a; } int main() {     char order;     int v[N], n=0, i;     scanf("%c",&order);     while (scanf("%d",&v[n])==1)  n++;//没有退出条件，死循环     if(order =='A')   qsort(v,n,sizeof(int),cmp1);     if(order =='D')   qsort(v,n,sizeof(int),cmp2);     printf("%d ",v[0]);     for(i=1;i<n;i++)         if(v[i]!=v[i-1]) printf("%d ",v[i]);     printf("\n");     return 0; }

int cmp1(const void* a, const void* b) {     return *(int*)a - *(int*)b; }  int cmp2(const void*a, const void* b) {     return *(int*)b - *(int*)a; } 字符串比较使用strcmp(const char* a,constcmp char* b),返回值分别为-1 0 1 表示小于 等于 大于 添加头文件 string.h


Question: c语言数值交换问题

函数的参数传递方式，教科书上一般说有三种：值传递，引用传递，指针传递；其实本质上看，只有两种：值传递和引用传递，指针传递的本质还是值传递。 详细解释，可参见如下视频： 4.03.C语言_函数_值传递 http://www.tudou.com/listplay/z5u9lwXuPKU/JYlkMDiWrIE.html 4.04.C语言_函数_引用传递 http://www.tudou.com/listplay/z5u9lwXuPKU/5Lax5EAM10w.html 4.05.C语言_函数_指针传递 http://www.tudou.com/listplay/z5u9lwXuPKU/_nFpuooNZrU.html

恩 懂了 感谢各位 因为我这分本来就不多 还有各位回答都很到位 我一直心存感激的 因为你们都给我了帮助 分数只好平均着给了   下次不懂得地方我会先查看以前的帖子的  一时心急忘了 没想起来看以前的哈 再次感谢你们！

所谓的值  跟 指针 是相对的  要交换值，需要传它的指针， 要交换指针， 需要穿他的指针，也就是指针的指针

指针变量说白了也还是值传递，只不过是地址的复制，你可以通过地址修改指向数据的值，但是在函数内部交换指针的值，只是将函数内的变量的地址进行了交换，对外面的指针是没有影响的，

我觉得“传值”和“传址”这两种说法本身就是最大的误人子弟 传参就是复制，至于传的指针是用来干嘛的，跟传参本身没关系

其实交换两个数用到的指针的知识在几乎所有的入门书籍中都有讲到，楼主不用急着看一些专业的书，打好基础更要紧。

谭浩强的<C语言程序设计>

关于怎么用指针传值，lz可以看看这个——http://blog.csdn.net/u012421456/article/details/21803797  至于书，我是没看过几本，就不推荐了，看别人吧 其实lz可以搜一些论坛上的帖子，这样的问题有人问过的

恩 看了各位的解释后 才明白我理解的太狭隘了 我也觉得好多细节理解不透，推荐本书呗  感激不尽哈

调用函数时的参数都是实际参数的一个复制品，指针也不例外，当你向一个函数传一个指针时，函数使用的是这个指针的复制品，第一个图中的函数，虽然传进函数的一个指针的值，但是函数是根据这个值找到内存中的地址对应的变量，所以可以修改值，第二个图只是把指针的值复制了一下，没有改变原来变量的值。其实书上都有详细的讲解，楼主可以看看书


Question: JNI 对象数组作为函数参数的问题

[quote=引用 1 楼 N_sev7 的回复:] 你来错板块了貌似！！！[ /quote] JNI的目的使用JAVA调用本地C

你来错板块了貌似！！！


Question: 求大神找出这个中缀表达式转为后缀表达式的错误

测试环境win7  测试例子： 1、 输入：3+4# 输出：  2、 输入：3+4-2# 输出：

#include<iostream.h>   int is_operation(char op) { 	switch(op) 	{ 	case'+': 	case'-': 	case'*': 	case'/':return 1; 	default:return 0; 	} }   int priority(char op) { 	switch(op) 	{ 	case'#':return -1; 	case'(':return 0; 	case'+': 	case'-':return 1; 	case'*': 	case'/':return 2; 	default:return -1; 	} }   void postfix(char e[],char f[]) { 	int i=0,j=0; 	char opst[100]; 	int top,t; 	top=0; 	opst[top]='#';top++; 	while(e[i]!='#') 	{ 		if((e[i]>='0'&&e[i]<='9')||e[i]=='.') 			f[j++]=e[i]; 		else if(e[i]=='(') 		{ 			opst[top]=e[i]; 			top++;} 		else if(e[i]==')') 		{ 			t=top-1; 			while(opst[t]!='('){f[j++]=opst[--top];t=top-1;} 				top--; 		} 		else if(is_operation(e[i])) 		{ 			f[j++]=' '; 			while(priority(opst[top-1])>=priority(e[i])) 				f[j++]=opst[--top]; 			opst[top]=e[i];top++; 		} 		i++; 	} 	while(top) 		f[j++]=opst[--top]; }  void main() { 	char e[10],f[10]; 	memset(e, 0, 10); 	memset(f, 0, 10); 	cin.getline(e,10); 	postfix(e,f); 	cout<<f; }


Question: 请高手解答return的各种用法

return的作用不用多说。麻烦的是如何返回各种各样的类型的数据。 这篇文章总结的不全，但大部分场景都有了： http://www.ilanever.com/article/sitedetail.html?id=264

有时可以用来退出多重循环。

return 退出函数

int fun() return fun();

可以终止函数运行

引用 1 楼 u013545836 的回复:这难道也很能玩出什么新花样？ 我也是这种感觉，无非就是return后面带不带参数，带的是变量、常量还是表达式

return 后面可以接返回值，也可以不接返回值，都是返回上一层，退出该层。

return 顾名思义——返回。就是从一个函数里（返回）退出出来。 如果return的后面可以带值也可以不带，若不带值就是直接退出当前函数，函数内的剩余代码就不会再被继续执行。 若带值，也是从return该行跳出当前函数，函数内剩余代码不再执行。此外带回去一个值给调用此函数的函数。

我只知道可以有返回值，可以结束一个函数，这个lz可以搜到啊——http://wenku.baidu.com/link?url=jE5OTQ38b-3DlTOr7n6-2_2_rG6UuPwGFyCiOj9NCv4tdOS-8jUH3Be3FatfHuwEy1DF_ErBnpYMLgMvRQgxcpiECXJZnx30KKBIWwZ2Fye

// 1 void func1(...) {     if (...)     {            return;     } }  //2 type func2(...) {        if (...)         {             return type(NG);         }          return type(OK); }

这难道也很能玩出什么新花样？


Question: 【请教】【10进制】【16进制】【字节】【双字】【转换】

你定义的是int型吧

引用 2 楼 wwwzys 的回复:负数，前面肯定是fffff,要想去掉，和很简单 让 这个数 与 上 0x000000ff 代码如下  outNun=sourceNum & 0x000000ff 你是对的，


Question: 关于指针的强制类型转换问题

char * lp=new char[40]; 	char * lpchar=lp; 	lpchar++; 	short * lpshort=(short *)lp; 	lpshort++; 	int * lpint=(int *)lp; 	lpint++; 这一段C++代码经编译后是这样的：  push    eax push    offset s_ITTRCore_code  push    28h call    operator new[](uint,char const *,int) add     esp, 0Ch mov     [ebp+var_104], eax  ;char * lp=new char[40]; mov     ecx, [ebp+var_104] mov     [ebp+var_14], ecx   ; mov     eax, [ebp+var_14] mov     [ebp+var_20], eax   ;char * lpchar=lp; mov     eax, [ebp+var_20] add     eax, 1               mov     [ebp+var_20], eax mov     eax, [ebp+var_14] mov     [ebp+var_2C], eax   ;short * lpshort=(short *)lp; mov     eax, [ebp+var_2C] add     eax, 2 mov     [ebp+var_2C], eax mov     eax, [ebp+var_14] mov     [ebp+var_38], eax   int * lpint=(int *)lp; mov     eax, [ebp+var_38] add     eax, 4 mov     [ebp+var_38], eax 编译器自动换算了。

这是编译器的事情，在进行指针类型转换的时候，只不过告诉了编译器，指针是指向什么类型的，然后进行指针运算的时候，编译器就按照类型来计算。  比如在计算指针+n的时候，编译器实际上是计算了+n*类型大小。

指针有效的部分是一个地址。根据地址是无法判断指针类型的。 根据指针类型，可以判断指针运算的伸缩。 变量在声明的时候已经确定了类型。

指针代表指向数据的首地址，指针类型指示了从首地址开始的字节数量。


Question: 这是啥错误？

对的,预编译和编译的问题，预编译的东西不能依赖编译期间的东西； 同样，编译期间的语句也不能依赖运行期的，如定义int b=3;int a[b];一样

sizeof是编译阶段处理的，#if是预编译阶段，知道这个就好.

正如LS所说，预编译问题。  即使你写成    int a = sizeof(int);  #if 2 == a #endif  也是不行的！

引用 楼主 u013921360 的回复: 建议直接复制内容问，这样省得各位大神不屑于回答你。 你这个代码能这么写吗？我是没这么做过。 #if #endif是预处理指令，意味在sizeof还没被计算之前执行的，所以你这样写会报错。


Question: 向函数传递的值为何会改变

其实我的意思是这样的

是想散分吗？！

你传入的是数组的值，和i有什么关系呢？i经过循环累加后变成5了，循环结束，打印i，结果很正常啊

i++执行了5次


Question: 通过JNI调用SO动态链接库的问题

引用 1 楼 cangyingzhijia 的回复:*(void **)(&_THUserID) = dlsym(aslib, "_THUserID"); 这个地方会找不到符号，最好是先判断它是否为空~~ 是不是没有使用extern "C" 声明函数， 可以用nm看看so里面是不是没有这个符号存在  nm发现： _ZN7CDBScan12THUserIDE6FRMode

请朋友们转到 http://bbs.csdn.net/topics/390739648这个贴子，这个我不全了整个编写过程。

引用 3 楼 buyong 的回复:自己看《程序员自我修养》，不用重复发帖  因为这个帖子中例子没全，所以又发送了一边帖子。

自己看《程序员自我修养》，不用重复发帖

引用 1 楼 cangyingzhijia 的回复:*(void **)(&_THUserID) = dlsym(aslib, "_THUserID"); 这个地方会找不到符号，最好是先判断它是否为空~~ 是不是没有使用extern "C" 声明函数， 可以用nm看看so里面是不是没有这个符号存在 以下是整个例子过程  1.有个C++的动态链接库：libLGM.so，里面有 _SayHelloID(int task)函数 -------------- 2.通过C语言调用C++库函数 Test.c #include <stdio.h>  #ifdef __cplusplus extern "C" {  #endif    int callSayHelloID(int task)   {    //程序提示我java: symbol lookup error: ./libTest.so: undefined symbol: _SayHelloID     return _SayHelloID(task);//libLGM.so动态库中的一个函数   }  #ifdef __cplusplus } #endif  3.将Test.c生成libTest.so ------------------------ 3.编写符合JNI规范的C，hello.c #include <jni.h> #include <string.h> #include <stdio.h> #include <stdlib.h> #include <dlfcn.h> #include "comHello.h"  JNIEXPORT jint JNICALL Java_com_Hello_sysHello(JNIEnv *env, jobject obj){  	void *imglib; 	char (*test)(int);//指向函数的指针 	int imghandle;  	imglib = dlopen("./libTest.so", RTLD_LAZY);//打开libTest.so库 	 	//函数指针指向C语言的callSayHelloID函数 	*(void **)(&test) = dlsym(imglib, "callSayHelloID");//最终目的是调用C++的libLGM.so中的_SayHelloID函数 	test(1);//其实就是 _SayHelloID(task);//libLGM.so动态库中的一个函数     	return 1; }  执行这个符合JNI规范的C,程序运行的时候提示我： java: symbol lookup error: ./libTest.so: undefined symbol: _SayHelloID


Question: putchar()是函数还是宏？

引用 楼主 u013921360 的回复:书上有句话： putchar函数定义于stdio.h中，尽管它的内容比较长，但它是作为一个宏实现。 什么意思？ 就是说我们用的时候都是宏的形式

宏的版本 #define getchar()         getc(stdin) #define putchar(_c)       putc((_c),stdout) #define fgetc(_stream)     (--(_stream)->_cnt >= 0 \                 ? 0xff & *(_stream)->_ptr++ : _filbuf(_stream)) #define putc(_c,_stream)  (--(_stream)->_cnt >= 0 \                 ? 0xff & (*(_stream)->_ptr++ = (char)(_c)) :  _flsbuf((_c),(_stream))) #define getc(_stream)    fgetc(_stream)

最终是函数的,封皮是宏，

_CRTIMP int __cdecl putchar(int);

lz可以看看这里——http://blog.csdn.net/tsaiyong_ahnselina/article/details/14209419

引用 楼主 u013921360 的回复:书上有句话： putchar函数定义于stdio.h中，尽管它的内容比较长，但它是作为一个宏实现。 什么意思？  可以是函数，也可以是宏，如果你想调用函数版本，就如下这么写：  ( putchar )( 'a ' );

是函数的，，


Question: c杨辉三角形

引用 1 楼 zhb111hy 的回复:这个我觉得有三种方法 1：有一个for循环控制行数（有三行） 2：有一个for循环控制列数（有5列） 3：有二维数组   好了，我没有想出来任意一个的程序，大神来帮忙 就是这样的，先不看输入的变量F，就只看上面的哪个图，尝试找规律打印出来，然后再改下相关变量就可以了。。。

#include <iostream> #include <iomanip>  using namespace std;   int main() { 	int range = 0; 	int temp = 1; 	cout << "请输入要打印的行数\n" ; 	cin >> range; 	cout << "\n"; //	cout << " "; 	for ( int i = 0; i <= range; i++ ) 	{ 		for ( int l = 0; l < range - i; l++ ) 		{ 			cout << "   "; 		} 		 		if ( temp == 1 ) 		cout << setiosflags(ios::left) << setw(6) << temp ; 		temp = 1; 		for ( int j = 1; j <= i; j++ ) 		{ 			 			for ( int k = i; k > i - j; k-- ) 			{ 				 temp *= k; //求n！/（n-m）！ 			}  			for ( k = j; k > 0; k-- ) 			{ 				temp /= k;//   /m!; 			}  			cout  << setiosflags(ios::left) << setw(6)<<temp ; 			temp = 1; 		} 	 		cout << "\n" ; 	  	} 	cout << endl; }

#include <iostream.h>  void solve(int i,int length);  int main() { 	char c; 	int length,i; 	cout<<"请输入一个大写字母："<<endl; 	cin>>c; 	length = c - 'A'; 	for(i =length;i>=0;--i) 	{ 		solve(i,length); 	} 	for(i = 1;i<=length;++i) 	{ 		solve(i,length); 	} }  void solve(int i,int length) { 	int j; 	for(j = 0;j<i;++j) 		cout<<' '; 	for(;j<length;++j) 		cout<<char('A'+j); 	for(;j>=i;--j) 		cout<<char('A'+j); 	cout<<'\t'<<'\n'; } 把楼上的改成C++了。

楼上是大神，学到了。

改个函数版本 #include<stdio.h>  void solve(int i, int length);  int main(){ 	char c; 	int length, i;  	scanf("%c", &c);   //Select char 	length = c - 'A'; 	for (i = length; i >= 0; --i){   //top 		solve(i, length); 	}  	for (i = 1; i <= length; ++i){   //bottom 		solve(i, length); 	} }  void solve(int i, int length){ 	int j; 	for (j = 0; j < i; ++j) 		putchar(' '); 	for (; j < length; ++j) 		printf("%c", 'A' + j); 	for (; j >= i; --j) 		printf("%c", 'A' + j); 	putchar('\n'); }

#include<stdio.h>  int main(){ 	char c; 	int length; 	int i,j;  	scanf("%c", &c);   //Select char 	length = c - 'A'; 	for (i = length; i >= 0; --i){   //top 		for (j = 0; j < i; ++j) 			putchar(' '); 		for (; j <length;++j) 			printf("%c", 'A' + j); 		for (; j >= i; --j) 			printf("%c", 'A' + j); 		putchar('\n'); 	}  	for (i = 1; i <=length; ++i){   //bottom 		for (j = 0; j < i; ++j) 			putchar(' '); 		for (; j <length; ++j) 			printf("%c", 'A' + j); 		for (; j >= i; --j) 			printf("%c", 'A' + j); 		putchar('\n'); 	} }


Question: 求请教这样一个工具的思路和原理

你这个情况，实际上通过C发起HTTP请求，发现被重定向到了该注销页面就可以提交注销了。


Question: 关于数据类型转换的问题！！！

引用 28 楼 sholber 的回复:谁菜B，谁是超级大菜B，这个版块里的资深C鸟都知道，不用张着口臭的嘴嚷嚷，虚张声势。就尔等这修养，不配学什么知识，趁早洗洗睡吧。本王也乏了，都散了吧。钦此！ 目测你这SB 小学还未毕业吧？？

引用 28 楼 sholber 的回复:谁菜B，谁是超级大菜B，这个版块里的资深C鸟都知道，不用张着口臭的嘴嚷嚷，虚张声势。就尔等这修养，不配学什么知识，趁早洗洗睡吧。本王也乏了，都散了吧。钦此！ 哇我以为你多牛B 呢？原来只是个只会骂人的菜B  ，连个代码都写不出来，还在这瞎BB ,我请你以后不要再侮辱c语言了好吗？ 学c语言需要智商不适合你。真的

引用 27 楼 braveboyny 的回复:[quote=引用 26 楼 sholber 的回复:] [quote=引用 25 楼 braveboyny 的回复:] [quote=引用 24 楼 sholber 的回复:] [quote=引用 23 楼 braveboyny 的回复:] [quote=引用 20 楼 sholber 的回复:] [quote=引用 19 楼 braveboyny 的回复:] [quote=引用 18 楼 sholber 的回复:] [quote=引用 17 楼 braveboyny 的回复:] %d只管取4个字节，它管你什么类型 对于这种说法尽可一笑置之。                     ——幻上帝[/quote]  你哪来得自信？？？[/quote] 哪来的也不可能是来自语文课本。 谁又给了你这种惘顾事实的自信[/quote]  给爸爸举出一个32位下，%d不是取4个字节的例子来看看，毛长齐没？敢来BB 爸爸的回复？？[/quote]  这又冒出个32位来，即使在32下，也未必见得是4个字节。口臭就有理了？你愿错一辈子是你的事，你臭哄哄的，不管你了。我还是离你远点好。[/quote] 例子举出来，瞎B B ，谁不会？？？速度举个例子给爸爸看看[/quote] 就你这德性，还想从朕这里学知识，去去去，口臭撅远点。真烦人。[/quote]     一直在这东扯西扯的不正面回答我的问题，叫你举个例子也举不出来，就知道瞎BB  ，你哪来的自信？？小菜B  [/quote] 谁菜B，谁是超级大菜B，这个版块里的资深C鸟都知道，不用张着口臭的嘴嚷嚷，虚张声势。就尔等这修养，不配学什么知识，趁早洗洗睡吧。本王也乏了，都散了吧。钦此！

引用 26 楼 sholber 的回复:[quote=引用 25 楼 braveboyny 的回复:] [quote=引用 24 楼 sholber 的回复:] [quote=引用 23 楼 braveboyny 的回复:] [quote=引用 20 楼 sholber 的回复:] [quote=引用 19 楼 braveboyny 的回复:] [quote=引用 18 楼 sholber 的回复:] [quote=引用 17 楼 braveboyny 的回复:] %d只管取4个字节，它管你什么类型 对于这种说法尽可一笑置之。                     ——幻上帝[/quote]  你哪来得自信？？？[/quote] 哪来的也不可能是来自语文课本。 谁又给了你这种惘顾事实的自信[/quote]  给爸爸举出一个32位下，%d不是取4个字节的例子来看看，毛长齐没？敢来BB 爸爸的回复？？[/quote]  这又冒出个32位来，即使在32下，也未必见得是4个字节。口臭就有理了？你愿错一辈子是你的事，你臭哄哄的，不管你了。我还是离你远点好。[/quote] 例子举出来，瞎B B ，谁不会？？？速度举个例子给爸爸看看[/quote] 就你这德性，还想从朕这里学知识，去去去，口臭撅远点。真烦人。[/quote]     一直在这东扯西扯的不正面回答我的问题，叫你举个例子也举不出来，就知道瞎BB  ，你哪来的自信？？小菜B

引用 25 楼 braveboyny 的回复:[quote=引用 24 楼 sholber 的回复:] [quote=引用 23 楼 braveboyny 的回复:] [quote=引用 20 楼 sholber 的回复:] [quote=引用 19 楼 braveboyny 的回复:] [quote=引用 18 楼 sholber 的回复:] [quote=引用 17 楼 braveboyny 的回复:] %d只管取4个字节，它管你什么类型 对于这种说法尽可一笑置之。                     ——幻上帝[/quote]  你哪来得自信？？？[/quote] 哪来的也不可能是来自语文课本。 谁又给了你这种惘顾事实的自信[/quote]  给爸爸举出一个32位下，%d不是取4个字节的例子来看看，毛长齐没？敢来BB 爸爸的回复？？[/quote]  这又冒出个32位来，即使在32下，也未必见得是4个字节。口臭就有理了？你愿错一辈子是你的事，你臭哄哄的，不管你了。我还是离你远点好。[/quote] 例子举出来，瞎B B ，谁不会？？？速度举个例子给爸爸看看[/quote] 就你这德性，还想从朕这里学知识，去去去，口臭撅远点。真烦人。

引用 24 楼 sholber 的回复:[quote=引用 23 楼 braveboyny 的回复:] [quote=引用 20 楼 sholber 的回复:] [quote=引用 19 楼 braveboyny 的回复:] [quote=引用 18 楼 sholber 的回复:] [quote=引用 17 楼 braveboyny 的回复:] %d只管取4个字节，它管你什么类型 对于这种说法尽可一笑置之。                     ——幻上帝[/quote]  你哪来得自信？？？[/quote] 哪来的也不可能是来自语文课本。 谁又给了你这种惘顾事实的自信[/quote]  给爸爸举出一个32位下，%d不是取4个字节的例子来看看，毛长齐没？敢来BB 爸爸的回复？？[/quote]  这又冒出个32位来，即使在32下，也未必见得是4个字节。口臭就有理了？你愿错一辈子是你的事，你臭哄哄的，不管你了。我还是离你远点好。[/quote] 例子举出来，瞎B B ，谁不会？？？速度举个例子给爸爸看看

引用 23 楼 braveboyny 的回复:[quote=引用 20 楼 sholber 的回复:] [quote=引用 19 楼 braveboyny 的回复:] [quote=引用 18 楼 sholber 的回复:] [quote=引用 17 楼 braveboyny 的回复:] %d只管取4个字节，它管你什么类型 对于这种说法尽可一笑置之。                     ——幻上帝[/quote]  你哪来得自信？？？[/quote] 哪来的也不可能是来自语文课本。 谁又给了你这种惘顾事实的自信[/quote]    给爸爸举出一个32位下，%d不是取4个字节的例子来看看，毛长齐没？敢来BB 爸爸的回复？？[/quote]  这又冒出个32位来，即使在32下，也未必见得是4个字节。口臭就有理了？你愿错一辈子是你的事，你臭哄哄的，不管你了。我还是离你远点好。

引用 20 楼 sholber 的回复:[quote=引用 19 楼 braveboyny 的回复:] [quote=引用 18 楼 sholber 的回复:] [quote=引用 17 楼 braveboyny 的回复:] %d只管取4个字节，它管你什么类型 对于这种说法尽可一笑置之。                     ——幻上帝[/quote]  你哪来得自信？？？[/quote] 哪来的也不可能是来自语文课本。 谁又给了你这种惘顾事实的自信[/quote]   给爸爸举出一个32位下，%d不是取4个字节的例子来看看，毛长齐没？敢来BB 爸爸的回复？？

说下我的理解思路：usc最后结果为0xff00，（中间数据类型的转换就不说明了）为无符号short型。有个疑问就是：printf的时候为%d，因此usc应该转换为int类型，这样分析的话，结果就不应该是65280了。。  问题在printf("%d", usc); usc是0xff00, 参数入栈的时候要要类型提升为int,作无符号扩展(因为usc是unsigned）, 所以是0x00 00 ff 00入栈。

既然有溢出，那结果就不好说了

引用 19 楼 braveboyny 的回复:[quote=引用 18 楼 sholber 的回复:] [quote=引用 17 楼 braveboyny 的回复:] %d只管取4个字节，它管你什么类型 对于这种说法尽可一笑置之。                     ——幻上帝[/quote]  你哪来得自信？？？[/quote] 哪来的也不可能是来自语文课本。 谁又给了你这种惘顾事实的自信

引用 18 楼 sholber 的回复:[quote=引用 17 楼 braveboyny 的回复:] %d只管取4个字节，它管你什么类型 对于这种说法尽可一笑置之。                     ——幻上帝[/quote]  你哪来得自信？？？

引用 17 楼 braveboyny 的回复:%d只管取4个字节，它管你什么类型 对于这种说法尽可一笑置之。                     ——幻上帝

%d只管取4个字节，它管你什么类型

仅这几句就够了，不需要往下看了：      char  ca;     unsigned char ucb;     unsigned short usc;       ca = 128; 1，char类型的长度是1个字节，但1个字节含有几个比特，没有标准，C只要求大于等于8个比特，128或许能用char表示，或许不能； 2，char可能等价于signed char，也可能等价于unsigned char，取值范围不同。128或许能用char表示，或许不能。 综上所述，ca=128，这个128是否能用char（ca）表示，是实现定义的。

引用 8 楼 u012421456 的回复:char赋128已经溢出了 引用 9 楼 u013163178 的回复:char 能表示的是-128~127， ca = 128；//已经溢出了 楼上说的对 引用 13 楼 halfword1982 的回复:unsigned short类型扩展为int类型时，仅在左边补充16位0，数值不会发生变化。一般来说，短类型向长类型扩展时，仅扩展符号位，数值不变。  开什么玩笑。

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


Question: 形参是结构体数组，请问 我如何再函数体内得到这个形参的长度呢？？

引用 3 楼 lgmsyy 的回复:[quote=引用 1 楼 shiguojie19892 的回复:] int testStudentInfo(struct Student *stu)传入得是指针，不能得到长度，需要加上一个int _length长度也传入函数内。 int testStudentInfo(struct Student *stu，int _length)  struct Student student[100]; 这个不是数组吗？这个数组为100个结构体准备好了空间，然后传给 int testStudentInfo(struct Student *stu)，为什么在这个函数里面不能取得数组的长度呢？？？[/quote] 那你应该这么取得 sizeof(student[100]);

数组退化为指针了，这种情况下是拿不到长度的， 要想拿到可以通过函数模板的方式拿到

传入的只是数组首地址，因为数组的长度在内存中并没有事先存放所以无从获取，只能手动传递

引用 1 楼 shiguojie19892 的回复:int testStudentInfo(struct Student *stu)传入得是指针，不能得到长度，需要加上一个int _length长度也传入函数内。 int testStudentInfo(struct Student *stu，int _length)  struct Student student[100]; 这个不是数组吗？这个数组为100个结构体准备好了空间，然后传给 int testStudentInfo(struct Student *stu)，为什么在这个函数里面不能取得数组的长度呢？？？

加一个入参arraylen，表示数组长度  int testStudentInfo(struct Student *stu, int  arraylen)


Question: 一个C语言小程序问题

void f(int a[]) 形参中的a其实是一个指针变量，sizeof(a)是4，sizeof(a[0])也是4，那么计算的结果就是1了。

这样的结果才是5,5  #include<stdio.h>  void f(int (&a)[5]) { 	printf("%d\n", sizeof(a)/sizeof(a[0])); }  int main() { 	int a[5] = {1,2,3,4,5};  	printf("%d\n", sizeof(a)/sizeof(a[0]));  	f(a);   	return 0; }

#include<stdio.h>  void f(int *b) { 	printf("%d\n", sizeof(b)/sizeof(a[0])); }  int main() { 	int a[] = {1,2,3,4,5};  	printf("%d\n", sizeof(a)/sizeof(a[0]));  	f(a);   	return 0; } 楼主恰好同名，所以误导了楼主，f()函数里面的a是指针啊，指针在32位系统占4个字节和int一样啊，改成上面形式就好理解多了

数组作为参数传递会自动的退化为指针，sizeof只是在计算指针的大小,而指针32位系统下位4字节。所以，当我们用数组作为函数参数的时候，一般都会写成指针+数组长度的方式。  而不作为参数的时候，sizeof就是真正得到数组所占的内存空间了

在main函数里，sizeof可以求一片内存的字节数，但是，函数传参的时候，会把数组退化成一个指针(4字节),所以，结果就是上述结果了。2楼说的并不准确,sizeof既是一个c++操作符也是一个函数，所以，可以这么写sizeof int,也可以这么写sizeof(int)

不错，f中的a是指针，占4个字节，而sizeof(a[0])也是占4个字节，在main中a是个数组，占20个字节——  其实lz这样试试后应该能想到的吧，如果lz想了解sizeof，可以看看这个——http://blog.csdn.net/sword_8367/article/details/4868283

引用 楼主 yuzengyuan 的回复: #include<stdio.h>  void f(int a[]) { 	printf("%d\n", sizeof(a)/sizeof(a[0])); }  int main() { 	int a[] = {1,2,3,4,5};  	printf("%d\n", sizeof(a)/sizeof(a[0]));  	f(a);   	return 0; }  请解释下为什么man函数输出是5，f函数输出是1 main中a是一个数组实体，有大小所以是5/1=5, f中是指针，所有指针大小都是4，a[0]是int型也是4,4/4=1

main函数里 a 是数组处理的！ f函数里 a就是一个指针处理！

sizeof并不是一个函数，在编译后，它实际上是被替换成了一个常量。

sizeof计算的是变量的大小。 在main中，a是一个有五个元素的整型数组，sizeof(a)为20；a[0]是int类型的变量，sizeof(a[0])为4。 在函数f中a是一个指针，一个指针占四个字节，所以就是这样的结果了。


Question: 如何把2个unsigned char类型变量，分别赋给1个unsigned short变量的低8位和高8位？

引用 2 楼 JiMoKuangXiangQu 的回复:char a, b; unsigned short i; i = ((unsigned short)a << 8) | b; 写错了，呵呵，LZ自己可以电脑上验证下。 unsigned char a, b; unsigned short i; i = ((unsigned short)a << 8) | b;

写全点吧 typedef unsigned short      WORD; typedef unsigned char       BYTE; #define MAKEWORD(a, b)      ((WORD)(((BYTE)(a)) | ((WORD)((BYTE)(b))) << 8))

WORD MAKEWORD(     BYTE bLow,     BYTE bHigh );


Question: linux c 如何 通过http发送数据？？

我之前用libcurl做的服务器程序。发现有一点很致命。内存会泄露。不信你top -p pid 看下是不是在一直增长。暂时还没有找到现成的库来做这个。

谢谢各位，已经用libcurl实现

用什么api来发呢

对应http协议来发送呗

libcurl 正解。

最快的办法是直接套接字将需要发送的内容一股脑塞过去，用telnet找个http会话的数据内容看一下就能知道大概了~

libcurl


Question: 关于c中free()的疑惑

malloc和free相当于借和还，不相当于创造和销毁。  其实电脑开机后物理内存的每个字节都是可读写的，区别仅在于操作系统内存管理模块在你读写时是否能发现并是否采取相应动作而已。操作系统管理内存的粒度不是字节而是页，一页通常为4KB。

.希望能让看了这个帖子的人不要再问“内存释放了为什么还能使用”类似问题了。  int* p=new int[10]; //你向房东租了间房子，房东给你一把钥匙p p[0]=1234;          //你开始使用这间房子，扔了一堆你的东西 delete[] p;         //你向房东退房了 //p=NULL;           //你把钥匙还了，如果没有这句就是你没还钥匙 cout <<p[0];        //你明明退了房子，但没有还钥匙。然后还用这把钥匙开门进去。                        //这时有三种结果：（1）房子还是老样子，你扔的东西都还在，就像你没退房一样                        // (2) 房子已经被房东收拾过了，你的东西被扔掉了。                       //  (3) 房子已经被租给其他人了，你被当做小偷暴打了一顿。 最后，请记住：退房记得还钥匙。

所以删完之后赶紧赋值NULL，防止被误用

在有的编译器里面这样是可以的     不只你看的那本书  好像C专家编程里面也介绍过     但这种代码不具有可移植性

这个如果运气好的话就能运行成功

free（），只能释放掉，使用malloc函数族，分配的内存指针，

free()释放后，只是标记处这段内存空闲的，最终如何使用这段内存是操作系统决定的， 所以free(current);后最好还要加上 current = NULL;这样有两个好处1、防止对没有再次给current分配内存就调用 current=current->next;； 2、防止一次malloc后，多次调用free(current);导致程序崩溃。

引用 1 楼 starytx 的回复:这样是不可以的，必须在释放current前先保存其next指针，释放后再将保存的next赋给current+1

不明觉历

难道 C primer plus 中说这么写是对的？

lz,你是对的.

lz,你是对的.

lz,你是对的. 程序猿面试宝典里面有个题差不多，曾经做过测试结果打印出来是乱码

书上错了！！


Question: 这句话哪里错了？

这个#后面跟个东西还真不懂，我以为是&取地址用的呢！而且双引号在字符串中怎么不用那个\呢？

引用 2 楼 user-2 的回复:你把expr打成epxr了。 至于这个#是干什么用的，自己翻开一本C教材看宏定义有什么特殊语法。 你说的也对，但正确答案应该是这样 printf(#expr "="fmt"\n",expr)


Question: 关于C语言数据结构双向链表问题   来大神啊！帮我改改吧！为什么输出的数据都不正确啊？

如果这个是 严蔚敏 的数据结构，习题答案网上有！

http://blog.csdn.net/wonggonghong/article/details/21605423 http://blog.csdn.net/wonggonghong/article/details/21619771 这里有两篇双链表的文章，可以参考

输入问题：   插入问题：   自己调试一下吧！新手，请多多指教！


Question: 嵌入式C中字长的问题，望大神指点~

unsigned int compzero=-1; 应该也可以

因为int可能的位数对于不同的平台可能是不同的，而0xffff只适合16位的compzero，32位是0xffffffff才对，所以~0才是正确的。  引用 楼主 wang554366136 的回复:在程序员面试宝典上看到这样一个程序片段：     unsigned int zero=0;                    unsigned int compzero=0xFFFF;     说这样写是不对的，不懂得处理器字长的重要性，应该写成下面的：    unsigned int compzero=~0;    希望能解释的详细些~


Question: c语言-字符串数组的输入

引用 5 楼 qq283802332 的回复:这是一个指针数组。  这用使用是正确的， 没有错啊。  是不是编译器出问题了？ 今天就可以正常运行了，看来是编译器的问题。。

这是一个指针数组。  这用使用是正确的， 没有错啊。  是不是编译器出问题了？

#include <stdio.h> #include <iostream.h> int main() { 	char *a[4]; 	a[0] = "ab"; 	a[1] = "ab"; 	a[2] = "ab"; 	a[3] = "ab"; 	for (int i = 0;i<4;i++) 	{ 		cout<<a[i]<<'\t'; 		cout<<'\n'; 	} 	return 0; } 我运行了一下，没有问题啊。。。

不可能segment fault

看错了  数组的数组   2维都要有确定的大小   char a[4][3];

一个char放一个字母吧    a[0] = 'a';


Question: visual studio新手

#include "stdafx.h" #include"iostream" using namespace std; int main() { 	int a, b; 	cin>> a >> b; 	return 0;  }  请问为什么像这样子的程序，visual studio 中会出现	 2	IntelliSense: identifier "cin" is undefined	e:\wpapplication\aaa\aaa\aaa.cpp	7	2	aaa 这样的错误。。其实我一开始就是想问这个的。。谢谢。。

引用 2 楼 chen_xinjia 的回复:问个问题好了，visual studio 中有什么复制所有错误信息的快捷键吗？ 复制所有错误信息的快捷键？

Error	1	error C2065: 'priority_queue' :   #include<queue>

问个问题好了，visual studio 中有什么复制所有错误信息的快捷键吗？

呃。。知道了


Question: C语言新人  求救！！

但就是free语句出错了，我把它注释掉，程序后续就能运行了。

if p!=NULL //free(NULL)有些编译器过不去,有的能过去 free(p);

if(p->coefficient+pa->coefficient==0){ free(p); free(pa); p=p->next; //free了就不能用这么用了,p会报段错误     pa=pa->next; }

单步调试,加打印输出.

引用 4 楼 u014138473 的回复:加入p是指针，并且已经指向某一具体数值，那么，free（p）， 是吧p所指空间的地址释放呢，还是释放储存在里面的数据？？？求指教 是释放指向的地址空间，没问题 你的代码贴上来时应该选 C/C++ 格式，不然太难读，就没人看了

while(p)     pc->next=p; while(pa)     pc->next=pa; 以上两句p、pa 与pc都没有往前走，while(p)会一直为真。修改为以下试试： while(p) { 	pc->next=p; 	pc=pc->next; 	p=p->next; } while(pa) {         pc->next=pa; 	pa=pa->next; 	pc=pc->next; }

这个可以自己好好调试一下啊，把各个参数打印出来，跟踪一下

改了，还是不行。后来有发现，改了if判断句还是不行。


Question: 刚开始学数据结构,觉得太难了,求大神.利用两个线性表LA和LB分别表示两个集合A和B，现要求一个新的集合A=A并B。

如何A和B的元素是相同类型的，可以用memcpy函数把B放到A的后面，memcpy是针对字节的COPY

线性表？是单链表么


Question: [swu]fgets函数

fgets获取的字符串，如果结尾有\n, 表明完整地读取了一行， 没有的话，可以由程序自行选择拼接、无视等操作

data文件的行末尾没有空格，因为fgets函数遇到新的一行或者文件结束符（EOF）就会结束。 我把它视为以行读取字符。

你得看看你所用的data文件的第一行是不是本来在行末有个空格？此外fgets我记得是把换行符也包含进去了的。

为什么会有换行呢？


Question: 咨询一下这个函数有什么用处

引用 15 楼 truexf 的回复:[quote=引用 10 楼 Adol1111 的回复:] [quote=引用 9 楼 turingo 的回复:] 可否帮忙指正一下？感谢！  [quote=引用 6 楼 supermegaboy 的回复:] [quote=引用 2 楼 turingo 的回复:] 返回局部变量非常危险。  [quote=引用 楼主 huyisu 的回复:] 有一个面试题，问下面这个函数有什么用处？  char *hanshu（void） {     char *p=“hello”；     return p； }  求解答。[/quote]  你又错得一塌糊涂。[/quote][/quote] 返回的是p的地址，也就是“hello”的地址，而非p自身地址。 p虽然是局部变量，会因为离开函数而释放，但“hello”是分配在常量区的，不会因为离开函数而释放，所以这里这样用是没问题的，返回的地址是有效的。 但个人认为还是不要这样写比较好，理由同4楼，返回类型为非常量指针，但实际返回的是一个常量指针！而且这样写本身会给看得人带来一种歧义（虽然没有错！） 如果char *p=“hello”；改为char p[]=“hello”;反而就有问题了！！[/quote]  但“hello”是分配在常量区的，不会因为离开函数而释放，所以这里这样用是没问题的，返回的地址是有效的。 这句话是非常严重的错误。请大侠不要误人子弟。没有编译器会保证遵循你这个规则。“hello”在离开作用域后，其内存很有可能被回收。[/quote]  引用 16 楼 truexf 的回复:不要返回局部的变量或常量，除非他是static的  瞎扯蛋，自己就打脸了。 string literal有什么storage class都不知道？ 还有什么局部常量。

char * hanshu (void) {     return "hello"; }

引用 26 楼 wanren13 的回复:[quote=引用 18 楼 zhxianbin 的回复:] char *hanshu（void） {     char p[]=“hello”；     return p； }  也许出题人的本意是上面的函数，可能自己都没搞明白  和原题的区别在哪里？[/quote] 原型是一个指针指向常量区域的“hello”,而你的是定义了一个变量里面存的是字符串“hello”而且反悔了变量的地址

如果不是出题的人自己犯迷糊了的话，这个函数的作用就是为了后续可以用 hanshu() 代替 (char*)"hello"

返回存储在常量区里面的“hello”的第一个元素的地址，代码这么写，侥幸没问题，如果是放回栈区的地址，问题就来了

引用 6 楼 supermegaboy 的回复:[quote=引用 2 楼 turingo 的回复:] 返回局部变量非常危险。  [quote=引用 楼主 huyisu 的回复:] 有一个面试题，问下面这个函数有什么用处？  char *hanshu（void） {     char *p=“hello”；     return p； }  求解答。[/quote]  你又错得一塌糊涂。[/quote] 支持，估计是没细看，乱说的

没有任何问题啊，这个是可以的，应为“hello”在常量存储区，返回的地址没有问题啊

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

引用 2 楼 turingo 的回复:返回局部变量非常危险。  [quote=引用 楼主 huyisu 的回复:] 有一个面试题，问下面这个函数有什么用处？  char *hanshu（void） {     char *p=“hello”；     return p； }  求解答。[/quote] 返回局部变量可以的，返回局部变量的地址是危险的。。。

引用 楼主 huyisu 的回复:有一个面试题，问下面这个函数有什么用处？  char *hanshu（void） {     char *p=“hello”；     return p； }  求解答。 在新老编译器（CB和TC）上编译都没报错，这里返回的值不是指针变量*p，而是其所指向的静态字符串的地址（该地址并不是hanshu函数的局部变量），所以是不违法的。 PS: 请楼主敲代码时不要用全角，否则网友们测试你的代码还得该半天标点。

#pragma comment(linker,"/SECTION:.rdata,RW") char *hanshu（void） {     char *p=“hello”；     return p； }

引用 1 楼 zhxianbin 的回复:不知道考点是什么我也没看出来到底想考啥，最后也没去成

***************************** char *hanshu（void） {     char *p=“hello”；     return p； } ***************************** 虽然编译的时候没有问题,但是这样写感觉不对，毕竟返回的是一个局部变量嘛，使用动态内存分配后返回才对吧。 //下面是我改的。 char *hanshu(void) {     char *p=(char *)malloc(sizeof(char));      p="hello";     return p; }

还没结帖给分，朕踢你屁股

这个问题..................

分都给朕哈，朕会感谢你滴。。。

楼主赶紧结贴给分吧。59楼已经说得很清楚了，你的做法合理合法，串字面值"hello"是静态存储的。再不结贴，奇谈怪论更多了。

引用 3 楼 lm_whales 的回复:这里,返回(静态)常量字符串, “hello”的存储地址。  char *p =hanshu() ; //相当于 char *p ="hello";  char *p; p =hanshu() ; //相当于  char *p; p ="hello"; 就是这样啊。   jiu shi zhe yang

引用 58 楼 k_badboy 的回复:这什么公司，出这么无聊低级的题。这种公司请你也不要去。 无聊低级？ 不是吧，能出这道题的公司里面水平可不一般啊

嗯，感觉这句话的用处就是管理各国语言用的，打个比方，英语跟中文 char *hanshu（int i） {     char *p=“hello”；     char *p1="你好"   if(i ==1)     return p； return p1; } 然后在main函数中根据需要去调用函数 Int main(argc , char *argv[]) { char *q ;//语言选择 q = hanshu(argc);//在函数运行的时候 根据传参确定到底选择哪一种语言     return 0; } 感觉就是干这个用的 但其实这种语言管理的做法很一般，一般都是封装成动态库实现的


Question: union的问题

上机实验分析，别在这问是多少，如果不理解，看汇编，还不理解，把结果贴出来

我想了下，按位来操作，要不要考虑大端，小端的问题》？？？？

但是，编译器应该不会给变量初始化为0吧，

楼上的应该正确

你应该问的是u.i（或者p->i）的值多少吧,下面简单的分析一下，union类型的意思是让几个变量共享一段内存，当定义一union类型的变量时，它所分配的内存空间大小等于union体内所需空间最大的那个变量的大小。具体到本例union型变量共分配了4个字节的变量（int i占4字节，char a[2]占两个字节，所以分配4个字节）。又因为union型变量是全局变量所以在程序运行前会先将这段内存初始化为零。因此赋值p->a[0] = 0x39;p->a[1] = 0x38后；union变量的内存值为为0x39 ，0x38,0x00,0x00,当用u.i即以int方式解释这段内存时结果为：u.i=0x00003839(16进制表示)=3×16^3+8×16^2+3×16+9=14393。

u一共四个字节，i和a共享这四个字节。i使用全部四个字节，a使用前两个字节。给a赋值后内存应该是0x38，0x39，0x??，0x??，后两个字节如果变量是全局的则是0x00，如果是局部的则不确定。i值如果是大端则是0x3938????，如果是小端则是0x????3839


Question: 指针和数组的问题。

哥们难不成是看到C语言深度解剖里面的题？我记得有个差不多的  可能你没理解 1.p1指向arr[5]最后一个元素的下一个内存位置，所以*p1是段错误，非法访问内存     书上输出的是*(p1-1)的值 2.p2指向整个数组的第二个字节的内存位置，X86架构支持不对齐访问，p2是整型指针，     小端模式下                                                       00                                                                              00                                                                              00                                                                               02                                                                              00                                                                              00                                          p2        ----->              00                                                                              01     小端模式读取数据是从高地址开始读  所以是2000000  十六进制

楼上所言，何其荒谬！你能输出3就说明程序正确了？老夫的输出还不是3呢！ 1，因为a的类型是int [5]，所以，&a的类型是int (*) [5]，而&a+1指向下一个相邻的int [5]，而(int *)(&a+1)的效果相当于指向数组a最后一个元素的下一个元素。因此，除了将*p1用于等性判断之类的操作外，对这样的指针解除引用的行为是未定义的。 2，除非做为sizeof和一元&运算符的操作数，数组名将被转换为指向其首元素的指针，比如这里的(int)a。但是将指针转换成整型和将整型转换为指针的行为是实现定义的，可能未正确对齐，也可能无法正确表示。 这样的程序可以用做研究，这是有益的。但是你在公司里这么写，I am afraid 老板会开了你……

引用 10 楼 ws_yqr 的回复:[quote=引用 4 楼 wjjll123 的回复:] [quote=引用 3 楼 zhxianbin 的回复:] int a[5] = {1,2,3,4,5}; int *p1 = (int*)(&a + 1); int *p2 = (int*)((int)a + 1); printf("%d,%d,%d\n", *p1, (*p2), a);  代码就是这样的，敲代码的时候错了，我本地运行代码没有敲错，帖子里面手动敲的，没有复制，所以有点错误，麻烦各位回答一下问题，不要抓着笔误不放[/quote] 1. 首先看p1，&a产生的类型是int (*p)[5]，一个指向五个int型数组的指针，由于指针运算的步长是其指向类型的大小，指针加1就到了下一个五个int型数组的首地址，再用(int*)强制转换，p1就是指向数组a后四个字节组成int了。 2. 再讲p2，(int)a是将数组首地址强制转换成int型，(int)a+1就是数值+1，p2指向的就是数组a空间里面第1个字节开始的int型变量。也就是a[0]的后三个字节和a[1]的第一个字节组成的int变量。这个时候要考虑大小端了。[/quote]# include <stdio.h> void main() { 	int b = 3,a[5] = {1,2,3,4,5}; 	int *p1 = (int*)(&a + 1);		//输出3 	int *p2 = (int*)((int)a + 1); 	printf("%d,%d,%d\n", *p1, (*p2), a); } 恩，这里输出3了，学习了。哈哈。

引用 4 楼 wjjll123 的回复:[quote=引用 3 楼 zhxianbin 的回复:] int a[5] = {1,2,3,4,5}; int *p1 = (int*)(&a + 1); int *p2 = (int*)((int)a + 1); printf("%d,%d,%d\n", *p1, (*p2), a);  代码就是这样的，敲代码的时候错了，我本地运行代码没有敲错，帖子里面手动敲的，没有复制，所以有点错误，麻烦各位回答一下问题，不要抓着笔误不放[/quote] 1. 首先看p1，&a产生的类型是int (*p)[5]，一个指向五个int型数组的指针，由于指针运算的步长是其指向类型的大小，指针加1就到了下一个五个int型数组的首地址，再用(int*)强制转换，p1就是指向数组a后四个字节组成int了。 2. 再讲p2，(int)a是将数组首地址强制转换成int型，(int)a+1就是数值+1，p2指向的就是数组a空间里面第1个字节开始的int型变量。也就是a[0]的后三个字节和a[1]的第一个字节组成的int变量。这个时候要考虑大小端了。

引用 14 楼 sholber 的回复:#13楼所说的“越界，行为就未定义”，这要分什么情况。  int a, * p = & a, * q = &a + 1; if (p == q) {/* …… */}  这里不存在任何未定义的行为。除非是   * q = 0;这种行为。  后面的分析一大堆，但没有任何用处，因为对一个实现定义的行为（外加未定义的行为，如果转换后未对齐，也或者数据无法表示）加以分析是不有任何意义的。 是滴 是滴  我也是这样想的  ,没所谓的答案  代码是错误的  整数转指针有一定限制

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

int *p1 = (int*)(&a + 1);  如12楼所说,  因为&a是int (*) [5],   你以前的a[5]相当于a[0][5]  再+1, 就是a[1][5]了, 因为这是未知的内存, 已经越界, 行为就未定义,  在某些编译器中什么出错, 那就是正常的了.  int *p2 = (int*)((int)a + 1);    因为a被你强制转换成int, 比如a原来的地址是a = 0x12345678 ,   (int)a+1 = 0x12345679 相当于你把一个整型数据的4Bytes起始位置移动了一位.  如果a数组中数据为1,2,3,4,5, 那么其内存为: 01 00 00 00 02 00 00 00 03 00 00 00 04 00 00 00 05 00 00 00 然后在 (int)a+1后p2指向的数据为:                       00 00 00 02 00 00 00 03 00 00 00 04 00 00 00 05 00 00 00 xx 这时取 *p2 就应该是  0x02000000 = 33554432

这个问题真不好回答，但 p1  不是 a[1] 地址，p2如果没有 (int)a 这个转换那就是  a[1] 地址，最后一个输出a是没有问题的就是一个地址值，但值不确定

我电脑上什么都没装，看程序推测，首先p1肯定是2；p2如果能运行应该输出一个不能理解或者是2的9次方的结果，如果不能运行那么需要理解到内存总是32位分配的，因此它从保护角度讲不能随意的取数，这一点在《深入理解计算机系统》内可以找到，linux内存保护得好，因此造成了跨界的错误。 我猜测下面这个程序 char  a[5]； int b; 依此取这6个值的地址，那么前5个值是连续的，而b的地址是跳过了3个字节！

引用什么编译器的结果是确保正确 对于你这里的代码  没有所谓的正确  指针可以转换为整数  但是整数转换为指针 就不保证能随意转了  涉及内存对齐等外部环境约束 (int*)((int)a + 1) 这个结果不做保证 没有正确的

引用 1 楼 ws_yqr 的回复:楼主你a变量是个啥，arr? 就是arr，笔误，请不要纠结于这个。

引用 2 楼 u013697891 的回复:int*p1=(int*)(&a+1)有这个语法吗 大哥，我是来请人帮忙回答的，如果觉得没有这样的语法，可以打开你的编译器试试看就知道了。

引用 3 楼 zhxianbin 的回复:int a[5] = {1,2,3,4,5}; int *p1 = (int*)(&a + 1); int *p2 = (int*)((int)a + 1); printf("%d,%d,%d\n", *p1, (*p2), a);  代码就是这样的，敲代码的时候错了，我本地运行代码没有敲错，帖子里面手动敲的，没有复制，所以有点错误，麻烦各位回答一下问题，不要抓着笔误不放

楼主你a变量是个啥，arr?


Question: C中有连接符吗？

4楼是正解。

printf....改成 printf("%s + %d %s +%d %s+ %d  =%d ",StrOf(Symb(x,y)),3,StrOf(x),4, StrOf(y),1,Symb(x,y)+3* x +4* y + 1); 输出: xy + 3 x +4 y+ 1  =75

printf....改成 printf("%s + %d %s +%d %s+ %d  =%d ",StrOf(Symb(x,y)),3,StrOf(x),4, StrOf(y),1,Symb(x,y)+ 4* x +4* y + 1); 输出: xy + 3 x +4 y+ 1  =85  直接连接字符串，strcat , 输出字符串连接，可以用 %s%s 另外sprintf (s,"%s%s",s1,s2);可以用两个或者以上的字符串s1,s2...，合成新的字符串s;

VB6里有符号，在C中要用函数连接字符串

有呀 1）续行符 \  表示两行代码，其实是一行代码  2）或者 串连接符号 空白（空格，换行，制表符等） 或者直接连接（引号之间无空格） 3）预编译的符号连接符，把两个不同符号，连接成一个新的符号 比如 x,y---->x##y ---> xy    例如  x =  10,y =11  求  xy +3 x+4y+1  #include<stdio.h> #define  Paste(a,b)  a##b #define StrSymb(a) #a #define Symb(x,y) Paste(x,y)  #define StrOf(a) StrSymb(a)  int Symb(x,y)  ; int x,y;  int main(int argc, char* argv[]) { 	int x=10,y=11; 	printf("%s + %d %s +%d %s+ %d",StrOf(Symb(x,y)),3,StrOf(x),4, StrOf(y),1); 	 	return 0; }  输出: xy + 3 x +4 y+ 1

用strcat函数。  引用 楼主 u011293816 的回复:在C程序中有数字或则文本连接符号吗？求解！！

举个例子说明你想要的结果

连接符号指？


Question: 关于指针的函数功能问题

这个函数其实是不合法的  不应该通过编译


Question: 新手不会用BMP做天空盒，跪求指导

交给美工去做，然后把那个半球模型导入就行了。


Question: c编程，用什么办法可以直接读取某个文件的最后21个字节？？

引用 1 楼 turingo 的回复:fseek(fp,-21L,SEEK_END);  引用 楼主 waldmer 的回复:c编程，用什么办法可以直接读取某个文件的最后21个字节？？ lseek, fseek 具体调用， 怎么实现的？？ +1

引用 1 楼 turingo 的回复:fseek(fp,-21L,SEEK_END);  引用 楼主 waldmer 的回复:c编程，用什么办法可以直接读取某个文件的最后21个字节？？ lseek, fseek 具体调用， 怎么实现的？？ 正解！

仅供参考#include <stdio.h> #include <io.h> #include <fcntl.h> #include <share.h> #include <conio.h> int fh; int c,r; __int64 offset,offset1,i64,n64,l64,r64; char ln[16000+1]; int main(int argc,char **argv) {     if (argc<2) {         fprintf(stderr,"Usage:%s filename.txt [10]\nto reverse lines of file [default the last 10 lines,-1 for all lines].\n",argv[0]);         return 1;     }     if (argc==2) n64=10i64;     if (argc>2) sscanf(argv[2],"%I64d",&n64);     fh=_sopen(argv[1],_O_BINARY|_O_RDONLY|_O_RANDOM,_SH_DENYNO);     if (-1==fh) {         fprintf(stderr,"Can not _sopen file %s!\n",argv[1]);         return 2;     }     l64=_filelengthi64(fh);if (l64==0i64) {_close(fh);return 0;}     offset=l64;     offset1=_lseeki64(fh,-1i64,SEEK_END);     if (offset1==-1i64) {_close(fh);return 3;}     i64=0i64;     while (1) {         if (_read(fh,&c,1)<1) break;//         if (('\n'==c && offset1<l64-1i64) || offset1==0i64) {             if (offset1!=0i64) offset1++;             if (_lseeki64(fh,offset1,SEEK_SET)==-1i64) break;//             r64=offset-offset1;             if (r64<=16000i64) {                 r=_read(fh,ln,(unsigned int)r64);                 if (r<=0) break;//             } else {                 r=16000;                 while (1) {                     if (r64>(__int64)r) {                         r64-=(__int64)r;                         if (1i64==r64 || 2i64==r64) {                             r=8000;                             r64+=(__int64)r;                         }                     } else {                         r=(int)r64;                         r64=0i64;                     }                     r=_read(fh,ln,r);                     if (r<=0) break;//                     if (0i64==r64) break;//                     ln[r]=0;                     printf("%s",ln);                     r=16000;                 }                 if (r<=0) break;//             }             ln[r]=0;             if (r>=2 && ln[r-1]=='\n' && ln[r-2]=='\r') {ln[r-2]='\n';ln[r-1]=0;r--;}//避免输出重定向到文件时行尾多出'\r'             if (i64==0I64) {                 if ('\n'!=ln[r-1]) printf("%s\n",ln);                 else               printf("%s",ln);             } else {                 printf("%s",ln);             }             i64++;             if ((i64%10000)==0) cprintf("\r%I64d/%I64d",offset1,l64);             if (n64>0i64 && i64>=n64) break;//             offset=offset1;             _lseeki64(fh,offset1-2i64,SEEK_SET);             offset1-=2i64;         } else {             _lseeki64(fh,-2i64,SEEK_CUR);             offset1--;         }     }     _close(fh);     return 0; }


Question: 求助（关于此程序实现的功能）

代替学生上厕所的老师……是……小jj

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

学生受教了，谢谢

引用 2 楼 zhao4zhong1 的回复:纠正楼上： int i; i=0; if (ch == '\n') {     printf("\n");//    ？？？？？  //这边我不懂怎么办了     i=0; } else if (ch < '0' || '9' < ch) {     putchar(ch);     continue; } else {     printf("%s:%c ", c[i], ch);   //我又不会输出了     i=(i+1)%7; } 可是我想要的功能还是没有实现

char c[7][10]={"length","width","height","pos x","pos y","pos z","lot"};  //这样定义对不对？ 也可以 char* c[]={"length","width","height","pos x","pos y","pos z","lot"};  sizeof(c)/sizeof(char*)就是数组维数，数组每个元素是一个char*也就是字符串常量。

if (ch == '\n') {     printf("\n");//    ？？？？？  //这边我不懂怎么办了 } else if (ch < '0' || '9' < ch) {     putchar(ch);     continue; } else {     printf("%s:%c ", c[ch-'0'], ch);   //我又不会输出了 }


Question: XMLSTRU 结构体和DeleteXml()是在哪个lib或.h？

引用 6 楼 user-1 的回复:[quote=引用 5 楼 ally0910 的回复:] [quote=引用 4 楼 user-1 的回复:] 是自定义的吧  不知道，前人写的代码，现在要改，编译不过[/quote]  搜索一下啊 整个solution[/quote]  找过了，没有，没办法  只好从外围看得到的地方重写了

引用 5 楼 ally0910 的回复:[quote=引用 4 楼 user-1 的回复:] 是自定义的吧  不知道，前人写的代码，现在要改，编译不过[/quote]  搜索一下啊 整个solution

引用 4 楼 user-1 的回复:是自定义的吧  不知道，前人写的代码，现在要改，编译不过

是自定义的吧

不是吧，没人看啊~~~~~~~~

这样就成沉下去了吗？？？？？

自己顶起来~~~~~


Question: [SWU]如何读取来自数据文件的m行n列的矩阵

主要考的就是矩阵转置

1 #include <stdio.h>   2 #include <string.h>   3   4 int main()   5 {   6         FILE*   fp;   7         fp      = fopen("data.in", "r");   8   9         if(fp==NULL){  10                 // Failed to open file  11                 return -1;  12         }  13  14         // line buffer  15         int     line_number     = 0;  16         char    buffer[100];  17  18         // Gain file line number  19         while(1){  20                 fgets(buffer, 100, fp);  21                 if(feof(fp))  22                         break;  23                 line_number++;  24         }  25         printf("%s", buffer);  26         printf("%d\n", line_number);  27  28         // back the first line  29         rewind(fp);  30         int k;  31         k       = strlen(buffer)/2;  32         printf("%d\n", k);  33  34 } 此部分只是读取矩阵的行数和列数，至于矩阵转置楼上已经讲得很清楚了。

引用 8 楼 arthuryangsh 的回复:m和n必须要通过某种方法来通知才行，比如文件第一行是m和n两个数。 有m,n 比较好读取 没有，可以让数据动态生长 或者干脆，先让每行不一样长，读一行转换一行。 最后，按照最长的一行数据的长度，重组矩阵。 不过这样就太麻烦了。  可以，让每行一样长，读取第一行数据，创建列数相同的矩阵。 以后逐行读取，行数动态增长即可。

偶  那现在我说的fgets哪里为什么会有换行？

m和n必须要通过某种方法来通知才行，比如文件第一行是m和n两个数。

如果数据列间隔不是空格，参考下面：#include <stdio.h> char s[]="123 ab 4"; char *p; int v,n,k; void main() {     p=s;     while (1) {         k=sscanf(p,"%d%n",&v,&n);         printf("k,v,n=%d,%d,%d\n",k,v,n);         if (1==k) {             p+=n;         } else if (0==k) {             printf("skip char[%c]\n",p[0]);             p++;         } else {//EOF==k             break;         }     }     printf("End.\n"); } //k,v,n=1,123,3 //k,v,n=0,123,3 //skip char[ ] //k,v,n=0,123,3 //skip char[a] //k,v,n=0,123,3 //skip char[b] //k,v,n=1,4,2 //k,v,n=-1,4,2 //End.

没实际编译链接调试，不保证对。仅供参考： //读取数据文件的m行n列的矩阵，将矩阵转置之后输出到标准输出。 #include <stdio.h> #define MAXMN 100 #define MAXC 1000 FILE *f; int y,x,m,n,k,v; int A[MAXMN][MAXMN]; char ln[MAXC],*p; int main() {     f=fopen("data.txt","r");     if (NULL==f) {         fprintf(stderr,"Can not open file data.txt!\n");         return 1;     }     if (NULL==fgets(ln,MAXC,f)) {         fclose(f);         fprintf(stderr,"no data in data.txt!\n");         return 3;     }     n=0;     p=ln;     while (1) {         if (1==sscanf(p,"%d%n",&v,&k)) {             p+=k;             n++;             if (n>=MAXMN) {                 fprintf(stderr,"Too many columns(>%d truncked.\n",MAXMN);                 break;             }         } else break;     }     rewind(f);     y=0;     while (1) {         if (NULL==fgets(ln,MAXC,f)) break;         p=ln;         for (x=0;x<n;x++) {             if (1!=sscanf(p,"%d%n",&A[y][x],&k)) {                 fprintf(stderr,"Can not read A[%d][%d]!\n",y,x);                 fclose(f);                 return 2;             } else {                 p+=k;             }         }         y++;         if (y>=MAXMN) {             fprintf(stderr,"Too many rows(>%d truncked.\n",MAXMN);             break;         }     }     m=y;     fclose(f);     for (x=0;x<n;x++) {         for (y=0;y<m;y++) {             printf("%d ",A[y][x]);         }         printf("\n");     }     return 0; }

我就是想写一个程序，这个程序去读取数据文件的m*n的矩阵，然后将矩阵转置输出出来。 m和n的值我提前试不知道的。

1#include <stdio.h>   2   3 void main()   4 {   5         int i, j, a[10][10];   6         FILE *fp;   7         fp      = fopen("data.in", "r");   8         for(i=0; i<10; i++){   9                 for(j=0; j<10; j++){  10                                 fscanf(fp, "%d", &a[i][j]);  11                                 if(feof(fp)){  12                                         printf("%d %d\n", i, j);  13                                         return;  14                                 }  15                 }  16         }  17 } 我写的数据文件是    1 2 3 4 5 6 想要他输出的结果是   2 3  但是结果是   0 6   也就是说他将这些元素读成了一维数组，不知何解？？？？

但是如果我的数据文件里面不是一个三行四列的矩阵，而是五行六列  再或者是其他的呢？有没有一种方法可以实现，将这个矩阵变成动态的矩?

第5行int A[m][n];应改为int A[3][4]; 第18行前应加一句fclose(f); 如果嫌m和n是写死不能动态修改的话，参考： //在堆中开辟一个4×5的二维int数组 #include <stdio.h> #include <malloc.h> int **p; int i,j; void main() {     p=(int **)malloc(4*sizeof(int *));     if (NULL==p) return;     for (i=0;i<4;i++) {         p[i]=(int *)malloc(5*sizeof(int));         if (NULL==p[i]) return;     }     for (i=0;i<4;i++) {         for (j=0;j<5;j++) {             p[i][j]=i*5+j;         }     }     for (i=0;i<4;i++) {         for (j=0;j<5;j++) {             printf(" %2d",p[i][j]);         }         printf("\n");     }     for (i=0;i<4;i++) {         free(p[i]);     }     free(p); } //  0  1  2  3  4 //  5  6  7  8  9 // 10 11 12 13 14 // 15 16 17 18 19

没实际编译链接调试，不保证对。仅供参考： //读取数据文件的m行n列的矩阵，将矩阵转置之后输出到标准输出。 #include <stdio.h> FILE *f; int y,x,m,n; int A[m][n]; int main() {     m=3;     n=4;     f=fopen("data.txt","r");     if (NULL==f) {         fprintf(stderr,"Can not open file data.txt!\n");         return 1;     }     for (y=0;y<m;y++) {         for (x=0;x<n;x++) {             if (1!=fscanf(f,"%d",&A[y][x])) {                 fprintf(stderr,"Can not read A[%d][%d]!\n",y,x);                 return 2;             }         }     }     fclose(f);     for (x=0;x<n;x++) {         for (y=0;y<m;y++) {             printf("%d ",A[y][x]);         }         printf("\n");     }     return 0; }


Question: 一个俄罗斯方块 求指教

不懂这个。不过这个也太。。。——  lz可以向这位讨教讨教http://bbs.csdn.net/topics/390734193

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


Question: sizeof的问题

引用 56 楼 china_ssl 的回复:现在一般浏览器中int都是4byte的你数组中有100个元素所以大小是4*100 第三个我也没看明白 和浏览器没什么关系  第三个是vc bug

哇。。回帖好多啊。。。看来大家都知道了

引用 52 楼 lpcads 的回复:[quote=引用 36 楼 u011169549 的回复:] 首先30楼的回答基本正确 1.a[100]数组下表访问已越界，但是对于c语言不会进行差错。因此可以编译运行。 2.数组的定义例如int a[100]实际上在编译器或者说是计算机看来是int[100] a，即int[100]类型的变量a，或者可以理解为是没有数组这个概念的。 3.sizeof（a）计算a的大小，也就是400。 4.第三个 sizeof（&a）表示对数组a取地址，即指针类型，所以sizeof（type*） =  sizeof (int[100]*) = 400。 至于其他编译器和系统，相信聪明的楼主会在其他编译器上类比理解的。  第一个也不要误人子弟。。。 sizeof(x)又不是函数，它只关心x的数据类型，给出数据大小，才不会管x的值到底是多少、越不越界。 [/quote] 如果是变量长度数组呢？ void f (int n) {     printf("%d\n", sizeof (  float [n] ) );     /* ...... */ }

1.对所有指针sizeof的值都是4    &a也是4    2. sizeof(a[100])=4； 可以这么写，sizeof关键字并不对这个表达式求值      也就是说并没有取a[100]的值    只是简单的类型大小检查

学习了学习了。

数组名是该数组首个元素的指针，也就是说a是一个指向数组首元素的指针，对指针使用sizeof（）操作将会返回指针所指向的空间的大小，在这里也就是数组的大小，4*100  --------------------------------------------------------------------------------------------------- 这个回答有三个地方很荒谬： 1，数组名并非总是首个元素的指针。“除非是作为sizeof和一元&运算符的操作数，数组名将被转换为指向其首元素的指针”。 2，sizeof ( )操作？sizeof是运算符，但sizeof ( )不是。括号是用于包住类型名，而不是运算符的一部分； 3，对指针使用sizeof会返回“所指向空间的大小”？头一次听说。指针有指针有大小，它和指向的空间大小不相干吧？这sizeof管得也太宽了。

引用 36 楼 u011169549 的回复:首先30楼的回答基本正确 1.a[100]数组下表访问已越界，但是对于c语言不会进行差错。因此可以编译运行。 2.数组的定义例如int a[100]实际上在编译器或者说是计算机看来是int[100] a，即int[100]类型的变量a，或者可以理解为是没有数组这个概念的。 3.sizeof（a）计算a的大小，也就是400。 4.第三个 sizeof（&a）表示对数组a取地址，即指针类型，所以sizeof（type*） =  sizeof (int[100]*) = 400。 至于其他编译器和系统，相信聪明的楼主会在其他编译器上类比理解的。  第一个也不要误人子弟。。。 sizeof(x)又不是函数，它只关心x的数据类型，给出数据大小，才不会管x的值到底是多少、越不越界。

名称       类型 a            int [100] a[100]    int &a          int [100]* &a[0]      int * 这样就一目了然了

,&a和a是等价的，所以sizefo(&a)等价sizeof(&a)。 ---------------------------------------------------------------- 考虑 int a [100]; &a的类型是int (*) [100]，它怎么会和a等价？

int a[100] ;   	printf("sizeof(a)=%d\n", sizeof(a)); 	printf("sizeof(a[100])=%d\n", sizeof(a[100])); 	printf("sizeof(&a)=%d\n", sizeof(&a)); 	printf("sizeof(&a[0])=%d\n", sizeof(&a[0]));  第一个不解释，返回数组所占内存的大小，第二个，a[100]不检查数组越界 sizeof(a[100])相当于sizeof(int)，所以返回值是4. 至于sizeof(&a),在只是在很久以前不是编译不通过的，以为数组名a不是一个对象，不像指针可以在内存里面找到对应地址，数组名a在内训里面是不存在的。为了保证对象完整性，后来允许使用&a，不过这里可以不是取地址的意思，而是引用数组a,&a和a是等价的，所以sizefo(&a)等价sizeof(&a)。 ----------------------------------------------------------------------------------------------------------------------------------------------------- 数组地址和对数组取地址的区别参考下面文章 http://blog.csdn.net/daniel_ice/article/details/6857019

这个问题居然还能引起这么热烈的讨论，匪夷所思……导致大家争论的原因其实是两方面的：1，很多C的实现未采用新的标准；2，指针和int类型以字节为单位的长度是实现定义的。 sizeof(a));              //等效于sizeof (int [100])，结果是100*(int类型的大小)。 sizeof(a[100]));      //等效于sizeof (int)，结果取决于int类型的大小。 sizeof(&a));            //等效于sizeof (int (*) [100])，结果取决于指针类型的大小。 sizeof(&a[0]));        //等效于sizeof (int *)，结果取决于指针类型的大小。 版主居然让大家上机实验……汗……

楼上解释得很清楚，~~~~~，，弄懂这几个例子，，sizeof 基本上会用了

引用 40 楼 lin5161678 的回复:[quote=引用 39 楼 u011169549 的回复:] 楼主的运行环境是vc6.0我是基于编译器解释的，没有错误。至于你说的无论怎样都是地址码，我感觉在vc底下并不一定成立。&a的&在此编译器中表示为引用，注意编译器是vc++...不多说了自己去想。 至于其他编译器另有解释。胡说八道  sizeof &数组名 得到不是一个指针大小 那就是一个BUG   &a的一元运算符& 在C++ 一样表示 得到一个指向操作数的指针  写在声明的时候 &才有引用的意义[/quote]  所言极是，即使C++里将&作用拓展了，但是声明引用的时候必须有初始化。所以在其它地方看到&都解释为取地址

lz可以看看这个——http://blog.csdn.net/sword_8367/article/details/4868283

第三个结果的问题是VC6的BUG

1）VC6 确实不是很标准 2） VC6 把sizeof(&a) 当成        int (&r)[100] =a;         sizeof(r ) 来处理了，确实比较奇怪。。

我的结果是

sizeof表示的是数据类型长度


Question: 我就想用codeblocks创建一个文件并存储数据，怎么就不行了，给跪了...

试试 "wt"  引用 2 楼 u014217598 的回复:[quote=引用 1 楼 turingo 的回复:] 输入CTRL + Z 组合键才是EOF字符。  [quote=引用 楼主 u014217598 的回复:] 大家帮帮我吧 我就想创建一个文件并存储数据，怎么就不行了，跪求啊~~~~ 我的版本号是13.12，系统是win7 64位  文件是创建了，但是里面一点信息也没有，肿么了？[/quote]  谢了，可是问题还是存在，ctrl+c才是结束标志，我发现是有东西存到文件的，可是无法显示，你看看怎么回事？ [/quote]

引用 1 楼 turingo 的回复:输入CTRL + Z 组合键才是EOF字符。  [quote=引用 楼主 u014217598 的回复:] 大家帮帮我吧 我就想创建一个文件并存储数据，怎么就不行了，跪求啊~~~~ 我的版本号是13.12，系统是win7 64位  文件是创建了，但是里面一点信息也没有，肿么了？[/quote]  谢了，可是问题还是存在，ctrl+c才是结束标志，我发现是有东西存到文件的，可是无法显示，你看看怎么回事？

输入CTRL + Z 组合键才是EOF字符。  引用 楼主 u014217598 的回复:大家帮帮我吧 我就想创建一个文件并存储数据，怎么就不行了，跪求啊~~~~ 我的版本号是13.12，系统是win7 64位  文件是创建了，但是里面一点信息也没有，肿么了？


Question: 关于windows下回车键的问题！

引用 5 楼 u011636566 的回复:网友zjq9931，我知道getch和getchar有区别啊，所以getch才能用于密码输入的问题啊，我想应该是应为getch在遇到回车键是依然单布吸收字符，所以会吸收到\r，而getchar在遇到回车键时会将\r\n一起吸收并作为\n记录吧 这个，根据实验来看，应当是的。 但我的研究的没有这么深，等待高手回答。

楼主，getch，是getch，getchar是getchar。 getch是在按键的时候就有响应。 getchar是在按回车后才有响应，两个是不一样的。

不要把 fopen("...","...");fscanf,fprintf,fgets,fgetc,fclose //读时把\r\n替换成\n，写时把\n替换成\r\n;读到\x1a就设置EOF;读写的内容当字符看待 和 fopen("...","...b");fread,fwrite,fgetc,fclose  //不作以上替换，遇到\x1a仍继续读;读写的内容当字节看待 弄混了

MSDN中的例子：  #include <stdio.h>  void main( void ) {    char buffer[81];    int i, ch;     printf( "Enter a line: " );     /* Read in single line from "stdin": */    for( i = 0; (i < 80) &&  ((ch = getchar()) != EOF)                          && (ch != '\n'); i++ )      //EOF ，\n，没有一\r判断结束的。       buffer[i] = (char)ch;     /* Terminate string with null character: */    buffer[i] = '\0';    printf( "%s\n", buffer ); }

网友zhao4zhong1，你的意思是：getch是直接吸收'\r'   而getchar()是把'\r\n'一起吸收并作为'\n'么？


Question: 命令行参数中的argv是如何实现++argv就能指向下一个字符串的？

Addition (+) The addition operator (+) causes its two operands to be added. Both operands can be either integral or floating types, or one operand can be a pointer and the other an integer.    When an integer is added to a pointer, the integer value (i) is converted by multiplying it by the size of the value that the pointer addresses. After conversion, the integer value represents i memory positions, where each position has the length specified by the pointer type. When the converted integer value is added to the pointer value, the result is a new pointer value representing the address i positions from the original address. The new pointer value addresses a value of the same type as the original pointer value and therefore is the same as array indexing (see One-Dimensional Arrays and Multidimensional Arrays). If the sum pointer points outside the array, except at the first location beyond the high end, the result is undefined. For more information, see Pointer Arithmetic.

你们没说出关键，而且说错了，不是指针数组，而是数组指针，而且应该这样说：

回顾一下：地址加法运算

引用 4 楼 tuzhutuzhu 的回复:[quote=引用 3 楼 lin5161678 的回复:] [quote=引用 2 楼 tuzhutuzhu 的回复:] argv是个指针数组，数组的成员就是各个参数不是数组  char** 二维指针[/quote] char **argv跟char *argv[]，有啥区别吗[/quote]如果是作为函数形参  那么 这两个没有区别都是 char** 如果不是 作为函数形参 那么前者是指针类型 后者是数组类型 不一样

引用 3 楼 lin5161678 的回复:[quote=引用 2 楼 tuzhutuzhu 的回复:] argv是个指针数组，数组的成员就是各个参数不是数组  char** 二维指针[/quote] char **argv跟char *argv[]，有啥区别吗

引用 2 楼 tuzhutuzhu 的回复:argv是个指针数组，数组的成员就是各个参数不是数组  char** 二维指针

argv是个指针数组，数组的成员就是各个参数

建议lz巩固一下指针的基础知识


Question: 关于memcpy的问题

void *代表是一个指向无类型的指针 void代表无返回值

是 void *类型  不是 void类型

后边还有个 *

void * 表示返回值是无类型的指针 void 表示没有返回值

void *memcpy 返回值不是“void *”吗？

void *为“无类型指针”，可以指向任何数据类型 void才是“无类型”

明白了，基础不扎实啊   ~~~


Question: 新人求助！！

好神奇，我的vs2013就没有这种情况

事实上你这个程序在Visual c++里是可以运行的，至于你的问题报错上都提示了，你试着用scanf_s代替scanf 试试，我没用过这个，我想是不同的编译器所以有不同的规定造成的。

缺头文件，#include <stdlib.h>