字元、字元陣列(字串)與指向字串的指標
阿新 • • 發佈:2019-02-16
今天在寫一個簡單的面向連線的TCP Socket程式時(UNIX Network Programming上的時間伺服器和客戶端例子)。有個簡單的改變是將從伺服器返回的日期字串 改成一個字元一個字元的返回。
修改之前是這樣子的:
//
ticks = time(NULL);
snprintf(buff, sizeof(buff), "%.24s\r\n", ctime(&ticks));
if( write(connfd, buff, strlen(buff)) < 0)
perror("write error\n");
buff是一個字元陣列,其定義為:char buff[MAXLINE];
write 函式的第二個引數需要傳遞 char *型別的資料。這裡將字元陣列賦值給char *或者傳遞給char *是正確的。
需要注意的是sizeof(buff)的數值時MAXLINE而strlen(buff)的數值是其實際佔用的空間(字元數且不包括最後的AISCII碼為0 的'\0')。
那麼如何將一個字元傳遞給write函式呢?
學習過C語言,我們知道buff指向的是buff字元陣列第一個字元。也就是說假如buff的內容是"I am Chinese" ,則(*buff)的值為I,同理(buff+i)指向的是buff字元陣列中的第i個字元。
於是下面的程式碼可以完成一個字元一個字元傳遞給write的功能:
int i = 0;
char * s = "I am Chinese";
while( *(s+i) != '\0') {
if( write(connfd, s+i, 1) < 0)
perror("write error\n");
i ++;
}
請注意,write的第二個引數s+i是一個地址。該地址是“I am Chinese”的第一個字元I的地址(或者指標)。第三個引數1表示由write寫進s+i地址開始的1個字元。
/*-----------------------*/
在繼續看下面的程式:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(int argc, char **argv) {
char c[20] ="I am Chinese";
char c1[20] = {'H','E',' ','I','S',' ','A',' ','B','O','Y'};
printf("c is :%s, the sizeof c is: %d, the strlen of c is: %d\n", c, sizeof(c), strlen(c));
printf("c1 is :%s, the sizeof c1 is: %d, the strlen of c1 is: %d\n", c1, sizeof(c1), strlen(c1));
int i = 0;
for(i = 0; c[i] != 0; i ++) /* c[i] !='\0'起到的效果是一致的*/
printf("%c\n",c[i]);
return 0;
}
該程式的輸出結果是:
c is :I am Chinese, the sizeof c is: 20, the strlen of c is: 12
c1 is :HE IS A BOY, the sizeof c1 is: 20, the strlen of c1 is: 11
I
a
m
C
h
i
n
e
s
e
該例子再一次的闡述了sizeof和strlen的區別。
假如將兩個字元陣列的宣告修改成下面的方式:
char c[] ="I am Chinese";
char c1[] = {'H','E',' ','I','S',' ','A',' ','B','O','Y'};
printf("c is :%s, the sizeof c is: %d, the strlen of c is: %d\n", c, sizeof(c), strlen(c));
printf("c1 is :%s, the sizeof c1 is: %d, the strlen of c1 is: %d\n", c1, sizeof(c1), strlen(c1));
其執行結果是:
c is :I am Chinese, the sizeof c is: 13, the strlen of c is: 12
c1 is :HE IS A BOYI am Chinese, the sizeof c1 is: 11, the strlen of c1 is: 23
I
a
m
C
h
i
n
e
s
e
需要注意的是the sizeof c is: 13, the strlen of c is: 12,其原因就是最後有個'\0'佔一個字元空間。
但是c1的輸出結果有點神奇。。。
下面的例子更加的闡述了字元陣列(字串),指向字串的指標與字元的關係
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(int argc, char **argv) {
char c[20] ="I am Chinese";
char c1[30] = {'H','E',' ','I','S',' ','A',' ','B','O','Y'};
printf("c is :%s, the sizeof c is: %d, the strlen of c is: %d\n", c, sizeof(c), strlen(c));
printf("c1 is :%s, the sizeof c1 is: %d, the strlen of c1 is: %d\n", c1, sizeof(c1), strlen(c1));
int i = 0;
for(i = 0; c[i] != 0; i ++)
printf("%c\n",c[i]);
printf("from third element of char-array c is : %s\n", c+2);
int j = 0;
char c2[] = "hello world!";
char c3[30];
for(j =0; *(c2+j) != '\0'; j++)
*(c3+j) = *(c2+j);
*(c3+j) = 0;
printf("c3 is :%s\n", c3);
char *c4 = "I am serving on char";
char c5[50];
int k = 0;
while(*(c4+k) != 0) {
*(c5+k) = *(c4+k);
k ++;
}
*(c5+k) = '\0';
printf("c5 is :%s\n", c5);
return 0;
}
該程式的輸出是:
c is :I am Chinese, the sizeof c is: 20, the strlen of c is: 12
c1 is :HE IS A BOY, the sizeof c1 is: 30, the strlen of c1 is: 11
I
a
m
C
h
i
n
e
s
e
from third element of char-array c is : am Chinese
c3 is :hello world!
c5 is :I am serving on char
還需要注意的是不建議使用下面這種宣告 char c[] = "I am Chinese",而是使用char c[30] = "I am Chinese";也不建議使用char * str; 而是建議使用char str[100]這種宣告。其原因是c[] 或者 *str這種使得程式在執行是往往不知道會訪問到記憶體的哪裡去。因為編譯器並不知曉你需要多大的空間,很有可能這些變數在處理的過程中會將以c或者str開始的記憶體塊訪問到不該訪問的區域去。