讀古今文學網 > C語言解惑 > 2.11 指針的困惑 >

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++ 
); }
  

記住:字符數組的指針也不能接受帶空格的輸入。

順便提醒一下:指針比較複雜,本節只是從輸入輸出數據的角度討論,以後將把它分到不同應用場合,結合實例說明。