struct in_addr A;
(struct in_addr)型のAがありまして、Aにデータを代入するとき、よく
A.s_addr = ?????;
というように、「s_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;

となっていて、「s_addr」のメンバはどこにもないんですよね。。
これはどういうことなんでしょう。
ちなみに自分の発想でアクセスするとしたら、例えばu_longとしてだったら、
A.S_un.S_addr
というようなものしか思いつきません。

あと、ネットワークプログラミング初心者の自分にもわかるような、WinSockについてやさしく、しかもくわしいサイトやおすすめの書籍がありましたら、是非とも教えてください。

このQ&Aに関連する最新のQ&A

A 回答 (3件)

bcc32のwinsonk.hをみたら



#define s_addr S_un.S_addr

のようになっていました。
A.S_un.S_addr
って打つのが面倒くさいってことでしょうね。
    • good
    • 0
この回答へのお礼

本当ですね。。
すみません、調べたはずが、見逃してました。
しかしs_addrの表現だと頭がこんがらかるような気がしてなりません。。

どうもありがとうございます。

お礼日時:2005/04/04 09:50

有名どころで”ねこでもわかる”のサイト


http://www.kumei.ne.jp/c_lang/intro/no_91.htm

もうひとつ有名どころで”wisdomsoft”のサイト
http://wisdom.sakura.ne.jp/system/winapi/winsock …

書籍だと”ねこでもわかる”の”ネットワークプログラミング”の本がTCPやUDP通信について詳しかった.

これらは,プログラミングの基本的なことでもとてもお世話になっています.
    • good
    • 0
この回答へのお礼

アドバイスどうもです。
しかしながら、どちらのサイトも、すでに知っていたのでした。

猫のほうは、昔から知っているのですが、出だしにはあまりむかないと思います。。サンプルソースばかりで、途中の”細かい”解説がないように思えます。入門者にとっては必要です(ええ)。ここが有名なのは、「幅広い知識を扱っている」からですし。

萌えゲー用語ばかり使っているほうのサイトは、WinAPI関数編では解説が丁寧だったのが、WinSock編では読者のレベルが高いと想定してか、表現からして難しく感じます。

高望みをしているのかもしれませんが、これらの有名所よりも仕様説明が丁寧な場所を探しています。。

最近見つけたところだと
http://www.mars.dti.ne.jp/~torao/program/
とかあります。
有名であれば必ずしもいいというわけではないと思うので、WinSockだけにこだわったようなサイトはないでしょうか。

お礼日時:2005/04/04 09:59

winsonk.hになってしまいました:-)


winsock.hの間違いです。

サイト・書籍はわかりません、
winsock関連の本は一応もってますが、かなり古いし・
    • good
    • 0

このQ&Aに関連する人気のQ&A

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!

このQ&Aを見た人が検索しているワード

このQ&Aと関連する良く見られている質問

Q[C言語]コンソールからのデータ入力時の誤動作の回避方法

趣味でプログラミングをしております。
環境は、以下です。
Windows10
Mingw-w64
gcc version 5.2.0 (Rev4, Built by MSYS2 project)

https://oshiete.goo.ne.jp/qa/9287118.htmlの回答2にて、
3つの数字を入力し、数字でない場合は再入力を促すプログラムを提示しました。
これについて、他の回答者様より「fflush(stdin); は一般にはやっていけない操作」との回答をいただきました。

私の環境では、fflush(stdin)を使用しないと以下の様に1回目に誤ったデータを入力すると、再入力時のメッセージが2回繰り返し表示されます。
(推測ですが、windowsで改行コードが2Byteであることから発生しているのではと考えています)

fflush(stdin)を使用しないで、この問題を回避する適切な方法がありましたらご教示ください。

よろしくお願いします。


----------実行結果(fflush(stdin)を使用しない場合)
$ ./a.exe
重複しない3つの数字:abc
重複しない3つの数字:重複しない3つの数字:abc
重複しない3つの数字:重複しない3つの数字:
----------


----------ソース
#include <ctype.h>

#define BUF_SIZE 3 // 3文字

int main(void){
char buf[BUF_SIZE + 1];
int user;

while(1){
fflush(stdin);
printf("重複しない3つの数字:");
fflush(stdout);

fgets(buf, BUF_SIZE + 1, stdin);
if(!isdigit(buf[0])) continue; // 1文字目が数字かチェック
if(!isdigit(buf[1])) continue; // 2文字目が数字かチェック
if(!isdigit(buf[2])) continue; // 3文字目が数字かチェック
break;
}
user = atoi(buf);
printf("number : %d", user);

return 0;
}
----------

趣味でプログラミングをしております。
環境は、以下です。
Windows10
Mingw-w64
gcc version 5.2.0 (Rev4, Built by MSYS2 project)

https://oshiete.goo.ne.jp/qa/9287118.htmlの回答2にて、
3つの数字を入力し、数字でない場合は再入力を促すプログラムを提示しました。
これについて、他の回答者様より「fflush(stdin); は一般にはやっていけない操作」との回答をいただきました。

私の環境では、fflush(stdin)を使用しないと以下の様に1回目に誤ったデータを入力すると、再入力時のメッセージが2...続きを読む

Aベストアンサー

>他の回答者様より「fflush(stdin); は一般にはやっていけない操作」との回答をいただきました。

規格にstdinに対して実施した場合の動作が明記されていないから。
だったかと。
実装依存する。ということです。


>推測ですが、windowsで改行コードが2Byteであることから発生しているのではと考えています

ライブラリー依存でしょうかね。
¥rと¥nの両方をfgets()が改行として処理したのかも知れません。
gccだし。

>fflush(stdin)を使用しないで、この問題を回避する適切な方法がありましたらご教示ください。

読み込み用のバッファをもう少し大きく用意する。でしょうか。

1回目、"abc"を読み込みます。
第2引数で指定した3バイトに達したため。
stdinのバッファには¥rと¥nが残ってます。

2回目、¥rを読み込みます。
fgets()の仕様により改行コードに到達したため。

1回目の読み込みで残るのに注意です。
# 2回目で¥rだけなのか¥r¥nなのか、はたまた¥r¥nが¥nに変換されるのか…はfgets()の後で内容確認してください。

>他の回答者様より「fflush(stdin); は一般にはやっていけない操作」との回答をいただきました。

規格にstdinに対して実施した場合の動作が明記されていないから。
だったかと。
実装依存する。ということです。


>推測ですが、windowsで改行コードが2Byteであることから発生しているのではと考えています

ライブラリー依存でしょうかね。
¥rと¥nの両方をfgets()が改行として処理したのかも知れません。
gccだし。

>fflush(stdin)を使用しないで、この問題を回避する適切な方法がありましたらご教示ください。...続きを読む

Qstruct tanka_kosuu kosuu[10];に付いているアンダーバー"_"の意味

以下のプログラムで質問がございます。
C言語の構造体であるstructの変数であるtanka_kosuuですが
アンダーバー"_"を付けてあります。
(※struct tanka_kosuu kosuu[10];)
 これは、なんでつける必要があるのですか!?
  ご教授ができるお方がおられましたらよろしくお願いいたします。

#include <stdio.h>
struct tanka_kosuu {
int tanka;
int kosuu;
int kingaku;
};
int goukei_kingaku(struct tanka_kosuu kosuu[], int nyuuryoku_kosuu);
int main()
{
struct tanka_kosuu kosuu[10];
struct tanka_kosuu kari_nyuuryoku = {-1, 0, 0};
int nyuuryoku_kosuu = 0;
int i;
while(kari_nyuuryoku.tanka != 0){
scanf("%d %d", &kari_nyuuryoku.tanka,
&kari_nyuuryoku.kosuu);
kosuu[nyuuryoku_kosuu] = kari_nyuuryoku;
nyuuryoku_kosuu++;
}
for ( i = 0; i < nyuuryoku_kosuu-1; i++ ){
kosuu[i].kingaku = kosuu[i].tanka * kosuu[i].kosuu;
printf("%d\t%d\t%d\n", kosuu[i].tanka,
kosuu[i].kosuu, kosuu[i].kingaku);
}
printf("goukei=%d\n",goukei_kingaku(kosuu, nyuuryoku_kosuu-1));
return 0;
}
int goukei_kingaku(struct tanka_kosuu kosuu[], int nyuuryoku_kosuu)
{
int i;
int goukei = 0;
for ( i = 0; i < nyuuryoku_kosuu; i++ ){
goukei += kosuu[i].kingaku;
}
return goukei;
}

以下のプログラムで質問がございます。
C言語の構造体であるstructの変数であるtanka_kosuuですが
アンダーバー"_"を付けてあります。
(※struct tanka_kosuu kosuu[10];)
 これは、なんでつける必要があるのですか!?
  ご教授ができるお方がおられましたらよろしくお願いいたします。

#include <stdio.h>
struct tanka_kosuu {
int tanka;
int kosuu;
int kingaku;
};
int goukei_kingaku(struct tanka_kosuu kosuu[], int nyuuryoku_kosuu);
int main()
{
struct tanka_kosuu kosuu[10...続きを読む

Aベストアンサー

変数や型などの識別名は、プログラム言語仕様により使用できる文字が制限されています。

多くの言語で空白文字は認められないので、複数の英単語からなる名前をつづる場合に
tankakosuu
では読みづらいので、以下の様な命名規則で単語間の区切りを表します。
tanka_kosuu // 下線で区切る "スネークケース"
tanka-kosuu // ハイフンで区切る "チェインケース"
tankaKosuu // 単語頭を大文字にする "キャメルケース"
TankaKosuu // 全ての単語頭を大文字にする "パスカルケース"
TANKA_KOSUU // 全て大文字で下線で区切る "アッパーケース"

C言語の構造体の場合ですが、
慣習として スネークケース または キャメルケース あたりが一般的な様です。

というわけで質問の回答としては、
そのプログラムを作った人の命名規則が、構造体名はスネークケースだった。

ちなみに、
言語仕様的に使えないチェインケースを除いて、どの命名規則でもコンパイルエラーになることはありません。
ただし、コンパイラーとは別に静的コード解析をしている場合は、変な命名だと警告されるかもしれません。


以下参考です。

慣習の由来はたぶんこれ
http://www.amazon.co.jp/dp/4320026926

命名規則が パスカルケース または アッパーケース の例
https://msdn.microsoft.com/ja-jp/library/kbt00480.aspx

言語によっては、この手の命名規則についての公式ガイドラインがあります
http://www.oracle.com/technetwork/java/codeconventions-135099.html
https://msdn.microsoft.com/ja-jp/library/ms229043.aspx

変数や型などの識別名は、プログラム言語仕様により使用できる文字が制限されています。

多くの言語で空白文字は認められないので、複数の英単語からなる名前をつづる場合に
tankakosuu
では読みづらいので、以下の様な命名規則で単語間の区切りを表します。
tanka_kosuu // 下線で区切る "スネークケース"
tanka-kosuu // ハイフンで区切る "チェインケース"
tankaKosuu // 単語頭を大文字にする "キャメルケース"
TankaKosuu // 全ての単語頭を大文字にする "パスカルケース"
TANKA_KOSUU // 全て大文字で下線...続きを読む

QC言語Char型配列に小数値を入れる方法

C言語Char型配列に小数値を入れる方法について質問なんですが、
分からなく質問させていただきました。

(例)23.8を

float f = 23.8
char c[100];

cの配列の中に23.8を入れる

c[0] = '2'
c[1] = '3'
c[2] = '.'
c[4] = '8'
c[5] = '\0'


上記みたいに入ってほしいんですが、そういうC言語の関数ありますか?
itoaやsprintfを使わないでお願いします。

Aベストアンサー

> いえ、HEWで作成していて itoaとsprintfが使用できなくて質問しました

マイコンが何か、またツールチェインが何か知りませんが、いずれにせよsprintfが使えるはずです。
メモリが足りないということでしょうか?

必要な情報は小出しにせず、すべて明らかにしてください。

Qtry{}catch(){}とデストラクタの関係を教えてください。

try-catchでメモリ確保を含むクラスをスローした場合、デストラクタはどの時点で働くのか、教えてください。たとえば、↓の使いかたは大丈夫でしょうか?

【1】
try{
 throw(CError(100, "エラー情報"));
}catch(CError& err){
 //ここでerrを参照しても問題ないのでしょうか?
}

【2】
try{
 CError err(100, "エラー情報");
 throw(err); // (1)
}catch(CError& err){
 //ここでerrを参照しても問題ないのでしょうか?
 //まだデストラクタはちゃんと動作するのでしょうか?
 //catchが呼び出し元のメンバであったりしても大丈夫なのでしょうか?
}

宜しくお願いします。

Aベストアンサー

【1】【2】どちらの場合も問題がありません。
コンパイラが必要に応じてerrオブジェクトのコピーを作成します。
デストラクタが呼び出されるタイミングはコンパイラに依存するところもあると思いますが、
例えばVC7.1では【2】は以下のように動作します。
(1) errオブジェクトのコンストラクタが呼び出される
(2) CErrorクラスのテンポラリオブジェクト(以下a)のコピーコンストラクタが呼び出される。
(3) errオブジェクトのデストラクタが呼び出される
(4) catch文まで到達
(5) aオブジェクトのデストラクタが呼び出される。

VC7.1では、【1】は以下のように動作します。
(1) errオブジェクトのコンストラクタが呼び出される
(2) catch文まで到達
(3) errオブジェクトのデストラクタが呼び出される。

コンパイラがオブジェクトのコピーを省略しているようです。

QC言語 配列で座標

C言語で二次元の配列a[11][11]を考えたとき、a[1][0]はxy座標の(1,0)を、a[0][5]はxy座標の(0, 5)を表しているという風な考えはあっているのでしょうか?
また、C言語で、xy座標で(0.5, 3.1)などの小数を表そうとしたらどうしたら良いのでしょうか?

Aベストアンサー

もう少し数の小さい例で説明します。
以下のように配列を宣言したとします。

***************
//配列宣言
int a[3][4];
***************

この場合 int型の値を格納できる変数が3×4=12個
作られたと考えることができます。

配列の使い方は以下のようになります。

*********************
//配列の扱い方の例
a[0][0]=1;
a[0][1]=234;
a[0][2]=-123;
a[0][3]=5;

a[1][0]=a[0][2];



*******************
つまり普通のint型の変数とそれぞれが同じ扱い方ができます。
どの様に使うかは様々です。

イメージとしては

  [0][1][2][3]
[0] □ □ □ □
[1] □ □ □ □
[2] □ □ □ □

このようなint型の値が格納できる箱が用意されるような感じです。

ここからは主観ですが
配列で座標を扱うといった概念はあまりないように思います。
たくさんの座標を扱うのであれば便利かもしれません。


少数の座標を表現する方法ですが

****************
//double型で座標を表現
double x = 0.5;
double y = 3.1;
****************

のように扱うといいかもしれません。
構造体を知っているのであれば
それで記述するとまとまって見やすいかもしれません。

もう少し数の小さい例で説明します。
以下のように配列を宣言したとします。

***************
//配列宣言
int a[3][4];
***************

この場合 int型の値を格納できる変数が3×4=12個
作られたと考えることができます。

配列の使い方は以下のようになります。

*********************
//配列の扱い方の例
a[0][0]=1;
a[0][1]=234;
a[0][2]=-123;
a[0][3]=5;

a[1][0]=a[0][2];



*******************
つまり普通のint型の変数とそれぞれが同じ扱い方ができます。
どの...続きを読む

Q{x = x>y ? x:y; return x;}

#include <iostream>
using namespace std;

inline int max(int x, int y){x = x>y ? x:y; return x;}

int main()
{
int num1, num2, ans;

cout << "2つの整数を入力して。\n";
cin >> num1 >> num2;

ans = max(num1, num2);

cout << "最大値は" << ans << "です。\n";

return 0;
}
の{x = x>y ? x:y; return x;}の部分の意味が解りません。

Aベストアンサー

inline int max(int x, int y){x = x>y ? x:y; return x;}
これを普通に関数で書くと

int max(int x, int y)
{
x = x>y ? x:y;
return x;
}

です。

x = 部分は右辺の結果が代入されます。これはわかりますよね。
x>y?x:y;
と書くと?より左にある条件式を判定し、その結果が真である場合は:で区切られた左側の値を、偽である場合は右の値を帰します。
x>yが真であればxを、偽であればyを返します。
それが、左辺値xに代入され、関数の戻り値として帰ります。

従って、2つの値をこの関数に入れると、大きいほうの値が帰ることになります。

QC言語 ポインタと配列

C言語で配列をあつかう場合、ポインタをつかうか、配列の添え字を使って処理するか迷うのですが、どちらが良いのでしょうか?
処理速度ではどちらが上でしょうか?

Aベストアンサー

いきなり
a[x]
と書いた場合は、他の回答のように
*(a+x)
と同じ処理速度です。

しかし
for(i=0;i<1000;) {
ホゲホゲ=a[i++];
}

型 *p = a;
for(i=0;i<1000;) {
ホゲホゲ=*p++;
}
では、処理速度に差が出ます。

前者では「毎回、aとiを加算して実効アドレス値を求め、値の取り出し後、iをインクリメントする」と言う処理が行われます。

しかし、後者では「毎回のアドレスの計算はせず、pから直接に実効アドレスをロードして使い、値の取り出し後、pに一定値を加算する」と言う処理が行われます。

「どちらが早いか?」は、コンパイラごと、実行するCPUごとに違うので、どちらと明言する事は出来ませんが、明らかに言えるのは「前者と後者では、異なる機械語コードが生成される筈だから、速度に差が出る筈」と言う事。

ま、どう考えても「毎回、加算を行ってアドレス値を作る」のと「アドレス値を持って来るだけ」なら、後者の方が早いでしょう(断言はしませんが)

そう言った訳で「連続したアドレスから順番に中身を取り出す」とか「連続したアドレスに順番に中身を詰め込む」なら、ポインタを用いるべきでしょう。

いきなり
a[x]
と書いた場合は、他の回答のように
*(a+x)
と同じ処理速度です。

しかし
for(i=0;i<1000;) {
ホゲホゲ=a[i++];
}

型 *p = a;
for(i=0;i<1000;) {
ホゲホゲ=*p++;
}
では、処理速度に差が出ます。

前者では「毎回、aとiを加算して実効アドレス値を求め、値の取り出し後、iをインクリメントする」と言う処理が行われます。

しかし、後者では「毎回のアドレスの計算はせず、pから直接に実効アドレスをロードして使い、値の取り出し後、pに一定値を加算する」と言う処理が行わ...続きを読む

Qint kosuu; とstruct tanka_kosuu kosuu[10]; の関係は

同プログラムの内容で現在3個の質問をしておりますが!
 その質問を解決する上で4つ目の質問をさせていただきます。
 悪しからず・・・
 さて
以下のサイトのプログラムで 些細な疑問がございます。
https://oshiete.goo.ne.jp/qa/9062058.html
 で
 struct tanka_kosuu {
int tanka; 
int kosuu; 
int kingaku; /
以上の中にあるkosuuと
 struct tanka_kosuu kosuu[10];のkosuu[10]とは直接関係がありますか?
 馬鹿な質問ばかりで申し訳ございませんがよろしくお願いいたします。

Aベストアンサー

#No.1です。

>kosuu[10];をakb[10];変えたところ 以下の errorでてコンパイルできません!?
> example10.c(15) : error C2065: 'kosuu' : 定義されていない識別子です。


宣言している変数名を変更したら、その変数を利用している場所(エラーメッセージで15行目と書かれています)の変数名も変更する必要があると思いませんか?

下の例で、1行目も変数をaからbに変えたら、2行目,3行目のaも、bに変える必要があのはご理解いただけますよね?
01: int a;
02: a = 10;
03: printf("a=%d\n", a);

QC言語 配列の長さの上限

C言語で配列Array[N]の長さNの上限っていくらなんでしょうか?
もし可能なのであれば上限を2147483647にしたいのですが、方法を教えてください。

Aベストアンサー

そもそもWindowsの32bit版はアプリが仮想メモリ空間を2GBしか使えません。2GBを超えるには64bit版が必要です。
たとえ64bit版OSだとしても添え字が2147483647って、単純なintの配列だとしても4x2147483647=8GB必要ですね。実メモリ16GBとかのPCを用意しますか?
そもそも配列で2147483647個必要なアルゴリズムに問題ありだと思います。

Qstruct tanka_kosuu kosuu[10];の[10]て何

#include <stdio.h>
struct tanka_kosuu {
int tanka;
int kosuu;
int kingaku;
};
int main()
{
         struct tanka_kosuu kosuu[10];
       構造体宣言 構造体名  変数名
struct tanka_kosuu kari_nyuuryoku = {-1, 0, 0};
int nyuuryoku_kosuu = 0;
while(kari_nyuuryoku.tanka != 0){
scanf("%d %d", &kari_nyuuryoku.tanka,
&kari_nyuuryoku.kosuu);
kosuu[nyuuryoku_kosuu] = kari_nyuuryoku;
nyuuryoku_kosuu++;
}
return 0;
}
以上ですが、
 struct tanka_kosuu {
int tanka;
int kosuu;
int kingaku;
以上と
struct tanka_kosuu kosuu[10];は
 以下
int tanka;
int kosuu[10];
int kingaku;
 と同じ意味ですか?
 それとも
  int tanka[10];
int kosuu[10];
int kingaku[10]; 
 と同じ意味ですか?
int tanka[10];と
 int kingaku[10];の
 合計に[10]は必要ないですよね
以上すべて私の考え方が間違っていたならごめんなさい。
 以上よろしくお願いいたします。

#include <stdio.h>
struct tanka_kosuu {
int tanka;
int kosuu;
int kingaku;
};
int main()
{
         struct tanka_kosuu kosuu[10];
       構造体宣言 構造体名  変数名
struct tanka_kosuu kari_nyuuryoku = {-1, 0, 0};
int nyuuryoku_kosuu = 0;
while(kari_nyuuryoku.tanka != 0){
scanf("%d %d", &kari_nyuuryoku.tanka,
&kari_nyuuryoku.kosuu);
kosuu[nyuuryoku_kosuu] = kari_nyuuryoku;
nyuuryoku_kosuu++;
}
return 0;
}
以上です...続きを読む

Aベストアンサー

#1です。

>struct tanka_ data { ・・・・(1)
>  int tanka;
>  int kosuu;
>  int kingaku;
>};
・・・途中省略
>} これでいいでしょうか

(1)のところは、変えてはいけません。
struct tanka_kosuu { 
のままにして下さい。
他は、問題ありません。


人気Q&Aランキング

おすすめ情報