2.11 指针的困惑

【例2.17】分析下面程序的运行结果。


#include <stdio.h>
void main 
( 
)
{   
    int a=2
,b
,c
;
    int x=25
,*p
;
    p=&x
; 
    b=a**p
;
    c=b*x/*p
;  
    //***********
    //*  
输出   *
    //**********/
;
    printf
("%d
,%d\n"
,b
,c
);
}
  

这个程序运行后给出一个奇怪的输出“50,1250”。“a**p”的表达式是对的,即“2*25=50”。但“b*x/*p”应是“50*25/25=50”,为何变成1250了呢?原来程序多了一个“;”号,使计算c的表达式变为


c=b*x
;
  

也就是原来“/*”被作为注释语句的开始,一直遇到“*/”才结束注释。如果没有多出的符号“;”,编译系统会给出如下错误信息。


error C2146
: syntax error 
: missing '
;' before identifier 'printf'
  

这个信息也够人琢磨的,其实是“/”遇到“*”,有理说不清。

在碰到含有指针的表达式时,在前后留一个空格就可以有效地避免这类问题。例如,把这两条语句改为


b=a * *p
;
c=b*x / *p
;  
  

或者用括号明确表达式的含义,即


b=a*
(*p
);
c=b*x/
(*p
);  
  

这样既容易理解,又能正确编译。

【例2.18】下面的程序实现将输入字符串给t的内容复制到s中,这个程序能正确实现将输入“You and we”复制到s中吗?


#include <stdio.h>
#include <malloc.h>
void strcpy1 
( char *
, char *
);
void  main 
( 
)
{
    char   *s
, *t
;
    s=
(char*
)malloc
(100
);
    t=
(char*
)malloc
(100
);
    scanf 
( "%s"
, t 
);
    strcpy1 
( s
, t 
);
    printf 
( "%s\n"
, s 
);
  }
  void strcpy1 
( char *s
, char *t
)
  {  while 
( *s++ = *t++ 
); }
  

【解答】不能。理由如2.7节所述。解决的办法之一是使用gets函数。如果需要保留t,可以像下面这样实现。


#include <stdio.h>
#include <malloc.h>
void strcpy1 
( char *
, char *
);
void  main 
( 
)
{
   char   a[100]
, *t
,*s
;
   s=
(char*
)malloc
(100
);
   t=
(char*
)malloc
(100
);
   gets
(a
);
   t=a
;
   strcpy1 
( s
, t 
);
   printf 
( "%s\n"
, s 
);
 }
 void strcpy1 
( char *s
, char *t
)
 { while 
( *s++ = *t++ 
); }
  

如果不需要保留t,可以直接实现复制操作,实现的程序如下。


#include <stdio.h>
#include <malloc.h>
void strcpy1 
( char *
, char *
);
void  main 
( 
)
{
   char   a[100]
, *s
;
   s=
(char*
)malloc
(100
);
   gets
(a
);
   strcpy1 
( s
, a 
);
   printf 
( "%s\n"
, s 
);
 }
 void strcpy1 
( char *s
, char *t
)
 { while 
( *s++ = *t++ 
); }
  

记住:字符数组的指针也不能接受带空格的输入。

顺便提醒一下:指针比较复杂,本节只是从输入输出数据的角度讨论,以后将把它分到不同应用场合,结合实例说明。

《C语言解惑》