[英]Unable to understand the type casting done in the inet_ntoa function
我了解gethostbyname()
函數。 當時我找到了以下示例程序。
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <netdb.h>
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char *argv[])
{
char *host, **names, **addrs;
struct hostent *hostinfo;
if(argc == 1)
{
char myname[256];
gethostname(myname, 255);
host = myname;
}
else
host = argv[1];
hostinfo = gethostbyname(host);
if(!hostinfo)
{
fprintf(stderr, "cannot get info for host: %s\n", host);
exit(1);
}
printf("results for host %s:\n", host);
printf("Name: %s\n", hostinfo -> h_name);
printf("Aliases:");
names = hostinfo -> h_aliases;
while(*names)
{
printf("%s", *names);
names++;
}
printf("\n");
if(hostinfo -> h_addrtype != AF_INET)
{
fprintf(stderr, "not an IP host!\n");
exit(1);
}
addrs = hostinfo -> h_addr_list;
while(*addrs)
{
printf(" %s", inet_ntoa(*(struct in_addr *)*addrs));
addrs++;
}
printf("\n");
exit(0);
}
現在我在系統上運行它。 一切正常。 有兩件事使我感到困惑:
inet_ntoa(*(struct in_addr *)*addrs)
一樣鍵入大小寫。 但是,如果我們進行類似inet_ntoa((struct in_addr) addrs)
的類型區分的話, inet_ntoa((struct in_addr) addrs)
它將無法正常工作。 我無法理解其背后的原因。 還請向我解釋一下,這里進行了哪種類型的轉換。 當我了解此程序時。 我也無法理解以下while循環。
while(* addrs){printf(“%s”,inet_ntoa(*(struct in_addr *)* addrs)); addrs的++; }
請給我解釋一下。
假設有一個char**test
指向字符串“ india”。 每當Ever進行類似test++
。 根據字符串大小遞增。 在這種情況下,它將增加6(5 + 1(null char。))。 為什么這樣?
I.在inet_ntoa函數中,我們像inet_ntoa(*(struct in_addr *)* addrs)一樣鍵入大小寫。 但是,如果我們進行inet_ntoa((struct in_addr)addrs)這樣的類型區分,那么它就無法正常工作。 我無法理解其背后的原因。 還請向我解釋一下,這里進行了哪種類型的轉換。
為此,您必須知道in_addr
類型的定義是什么。 從MSDN
typedef struct in_addr {
union {
struct {
u_char s_b1,s_b2,s_b3,s_b4;
} S_un_b;
struct {
u_short s_w1,s_w2;
} S_un_w;
u_long S_addr;
} S_un;
} IN_ADDR, *PIN_ADDR, FAR *LPIN_ADDR;
Members:
S_un
S_un_b: An IPv4 address formatted as four u_chars.
S_un_w: An IPv4 address formatted as two u_shorts.
S_addr: An IPv4 address formatted as a u_long.
這里的結構具有一個聯合,我們對chars
感興趣。 由於addrs
的類型為char**
當我們執行*addrs
我們會得到char*
,這是char
數組的衰減類型。 在struct in_addr*
類型轉換中,我們將char*
手動轉換為struct in_addr*
。 但是inet_ntoa按值而不是引用接受in_addr
對象。 因此,我們向強制類型添加了另一個*,以將其從in_addr*
更改為in_addr
。 如果不做這種情況, **addrs
會給出一個char
而不是in_addr
。
II。 while(* addrs){printf(“%s”,inet_ntoa(*(struct in_addr *)* addrs)); addrs的++; }
要理解這個循環你已經看到你加載addrs
距離: struct hostent::h_aliases
再次MSDN文檔作為
A NULL-terminated array of alternate names.
addrs
指向帶有終止NULL元素的字符序列(字符串)數組。 例如, char *addrs[] = { "Delhi", "London", "New York", NULL };
我們知道addrs
是非null的,但是*addrs
只會是非null的三次,當以while(*addrs)
進行檢查時,第四個元素將為NULL。
III。 假設有一個char ** test指向字符串“ india”。 每當Ever,我們都會做類似test ++的事情。 根據字符串大小遞增。 在這種情況下,它將增加6(5 + 1(null char。))。 為什么這樣?
錯誤! char **test = "india";
是非法的。 但是,就像我上面解釋的那樣,它將指向這樣的字符串數組。 當您執行addrs++
,實際發生的情況不是根據字符串的長度增加,而是僅增加一個元素。 當您執行*addrs
它將指向“ Delhi”,然后addrs++
和*addrs
現在將指向“倫敦”,依此類推。
我建議您閱讀C FAQ,以獲得有關數組的詳細信息,包括指針衰減,指針算術等。
1> inet_ntoa()函數將Internet主機地址(以網絡字節順序給出)轉換為IPv4點分十進制表示形式的字符串。 該字符串將在靜態分配的緩沖區中返回,隨后的調用將被覆蓋。
int_ntoa的原型:
char *inet_ntoa(struct in_addr in);
您正在編寫“ inet_ntoa((struct in_addr) addrs)
”的這一行是錯誤的。 如在您的代碼中,addr是double指針。 您將類型轉換地址鍵入“ in_addr對象”,這是錯誤的。
*(struct in_addr *)*addrs
或* ( (struct in_addr *)*addrs )
意思是:
1.>將*addr
值(也是地址)轉換為“ struct in_addr *
”,即“ in_addr *
”類型。
2.>並且* ( (struct in_addr *)*addrs )
表示in_addr類型的對象/值。
2.>第二:
addrs = hostinfo -> h_addr_list;
while(*addrs)
{
printf(" %s", inet_ntoa(*(struct in_addr *)*addrs));
addrs++;
}
在這里,hostinfo-> h_addr_list返回指向數組的指針,即它的第一個元素的地址。
addrs++
意味着移至arry中的下一個元素。 當數組完成時*addr
將為null。
inet_ntoa(*(struct in_addr *)*addrs
,這會將所有字節地址轉換為字符串。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.