**************************
關於%s 和%c的小小的收穫
今天早上偶爾看到一個函數:
定義在string.h中的
char *strstr(char *s1, char *s2)
作用就是找出s2字符串在s1中第一次出現的位置(不是數字位置)
使用舉例:
**************************
*/
#include<stdio.h>
#include<string.h>
int main()
{
char *s1 = "helloWorld";
char *s2 = "llo";
char *p;
p = strstr(s1, s2);
if(p)
printf("%s", p); /*看到這裏就有點迷糊了*/
return 0;
}
/****************************
爲什麼說看到那裏就有點迷糊了?
出現的問題:函數返回的是指向char類型的指針,這是毋庸置疑的。
將返回值賦值給p,也就是說p指向一個字符串,p就是個地址。
直接用printf打印出來的話,那麼按理說打印出來的是地址,不會是p指向的字符串內容,但是現在情況和我分析的剛好相反,
用上面的代碼才能打印出字符串,反而用*p這樣看似打印出指針指向的內容形式還要出錯
也就是用下面的形式還要出錯:
<pre name="code" class="cpp">#include<stdio.h>
#include<string.h>
int main()
{
char *s1 = "helloWorld";
char *s2 = "llo";
char *p;
p = strstr(s1, s2);
if(p)
printf("%s", *p); /*這裏*/
return 0;
}
表面上看起來是打印除了p所指向的的內存單元的內容,符合我們分析,但是實際上編譯會有警告,運行也會出錯
再來看看下面的代碼:
#include<stdio.h>
#include<string.h>
int main()
{
char *s1 = "helloWorld";
char *s2 = "llo";
char *p;
// p = strstr(s1, s2);/*這裏有所變化,但是不影響說明問題*/
if(p)
printf("%c", p); /*關注這裏*/
return 0;
}
這時編譯出現了警告,運行時也出現了錯誤。
但是把printf()那裏的p改爲*p就不會出錯了!!
綜合總結出現的問題:
1,打印字符串時可以直接使用指向其的指針。即:printf("%s", p);
2,打印字符時不能直接使用指向字符的指針,而要使用指針所指向的內容,
即就是:printf( "%c", *p );
這一點對於整形數據也是一樣的。
分析出現的問題:
程序本身是人寫的,出錯肯定由於人造成的!
對於這個造成錯誤的本質原因是由於對字符和字符串的理解有偏差造成的。
首先,在c語言中是沒有字符串這個基本數據類型的,字符串都是以數組的形式儲存的;但是是有字符這個數據類型的(這是毋庸置疑的)。注意了:字符串是以數組的形式儲存的,字符串的名字就行當於數組的名字,數組的名字也就是數組的入口地址,也就相當於指針了。
所以打印字符串時,寫成:printf("%s", p);
而字符是基本的數據類型,有自己的地址。因此就要按照指針的相關操作來正確引用和賦值。可以簡單的理解爲,字符串是一個字符型數組,(應該是可以的)。
總的來說:
%s - 輸出字符串,需要字符串首地址(一般都是指針或者數組) %c - 輸出字符,需要一個字符變量(0-127的整數也可以) char a[]="china"; printf("%s\n", a); printf("%s\n", a+1); printf("%c\n", a[0]); printf("%c\n", a[1]);