IPv4 でマルチキャストのパケットを送出する際、デフォルトのままでは TTL が 1 になってしまう。ルータ越えの必要がある場合は以下のようにして、送信に使用するソケットのオプションを変更する。(下記は TTL を 32 に変更した例)
// #include <Winsock2.h> int ttl = 32; int result = setsockopt (socket, IPPROTO_IP, IP_MULTICAST_TTL, (char *)&ttl, sizeof ttl); if (SOCKET_ERROR == result) { // エラー処理は省略... }
C# の場合はこんなの。
// using System.Net.Sockets; int ttl = 32; socket.SetSocketOption (SocketOptionLevel.IP, SocketOptionName.MulticastTimeToLive, ttl);
いわゆる TRIM 関数です。
//------------------------------------------------------------------------ // trim (文字列からホワイトスペースを取り除く) //------------------------------------------------------------------------ // 戻り値 : 先頭ポインタ //------------------------------------------------------------------------ char *trim( char *lpszString ) // (in) 処理対象の文字列 { char *ps; // 空白文字を除いた先頭 char *pe; // 空白文字を除いた最後尾 char *p; // ワークポインタ // 先頭を見つける for ( ps = lpszString; *ps; ps++ ) { if ( ( 0x81 == *ps ) && ( 0x40 == *( ps + 1 ) ) ) { // 全角スペース ps++; } else if ( 0x20 < *ps ) { // ホワイトスペース以外→先頭 break; } } // 最後を見つける for ( p = pe = ps; *p; p++ ) { if ( ( 0x81 == *p ) && ( 0x40 == *( p + 1 ) ) ) { // 全角スペース p++; } else if ( 0x20 < *p ) { // ホワイトスペース以外→最後尾? pe = p; } } // コピー for ( p = lpszString; ps <= pe; ) { *p++ = *ps++; } *p = '\0'; return lpszString; }
2chのどっかで拾ったコード。なるほどーと思ったので貼ってみる。
#ifdef _DEBUG #define debug_printf printf #else // _DEBUG #define debug_printf 1? (void)0: printf #endif // _DEBUG
今日、こんな古いソースの中にこんな関数定義を見かけました。
int func (foo, bar) unsigned char *foo, *bar; { /* 処理・・・ */ ・・・
注目すべきは引数の宣言部分なのですが、調べてみると「伝統形式」と呼ばれるものらしいです。
ANSI C標準以前の宣言方法を伝統形式や旧方式というように呼ばれています
この方式による宣言は現代のコンパイラでも可能です
さらに、過去のC言語のソースで伝統形式が使われているものを見かけることがあるかもしれません
ここで、伝統形式の仮引数宣言を覚えておきましょう
(中略)
大きく違うのは、引数リストで仮引数となる変数名しか宣言しないということです
その後、コードブロックに入る前にそれぞれの仮引数に型を宣言するという形になっています
switch文の閉じカッコの位置で"error C2143: 構文エラー : ';' が '}' の前に必要です。"とコンパイルエラーになることがある。それはたとえばこんな場合。
switch ( foo )
{
case 'A':
// 処理...
break;
case 'B':
}
実はこれは、case 'B':ラベルと}の間に有効なステートメントが存在しないと起こるエラーである。回避策としては、break;でも書いとくか、なんなら;(セミコロン)だけの行でもよい。
VBからコール可能なDLLの作成 ででてきた、DLL作成のための標準的なDEFファイル
LIBRARY [library][BASE=address] EXPORTS entryname1[=internalname1] [@ordinal1[NONAME]] [DATA] [PRIVATE] entryname2[=internalname2] [@ordinal2[NONAME]] [DATA] [PRIVATE] entryname3[=internalname3] [@ordinal3[NONAME]] [DATA] [PRIVATE]
EXPORTS 文[MSDN ライブラリ Visual Studio 6.0]のところに載ってるけど、エントリの内容についてはあまり載ってないです。
以前から思っていたことだが、VC++で1つワークスペースを開いてて、別のDSWファイルををダブルクリックして開くと、先に開いてたのと同じVC++のウインドウで開いてしまい、最初に開いてたワークスペースは結果として閉じてしまう。複数VC++起動したのになーって。複数のワークスペースを開くには?に回答を発見した。
エクスプローラのメニューから [ツール]-[フォルダオプション] でプロジェクトワークスペースの設定をDDEを使用しないように変更すればOKです。
Windows Xpの場合はフォルダオプションの「ファイルの種類」で、拡張子DSWを選択し、「詳細設定」ボタンを押下、出てきたウインドウの「MSDEVで開く」をダブルクリックして、「DDEを使う」のチェックをはずせば期待の動作をするようになった。
Cの宣言はよみにくい。MSDNのヘルプを見ても???だったのでちょっと整理してみました。基本的な読み方は以下の順です。
char *( *(*var)() )[10];を例にとると
var文字定数と文字列リテラルの大きな違いとして、シングルクオートで括ったら\0が付かない、ダブルクオートなら付く、ってことらしい。Perlとは違うのね。
参考:プログラミング演習III ~C言語中級編~
関数あれこれ
strchr 文字列から文字を探す
strstr 文字列から文字列を探す
strrchr 文字列の中に文字が含まれている最後の場所を探す
_snprintf 引数にsprintfする
sscanf 文字列よりscanfみたいにして値を取り出す。
実数型の内部表現で一般に用いられる形式、IEEE754 floating-point standard について。
先頭より、以下のようにビットを割り当てる。
±1.M * 2E-127
0.375f = 1.5 * 2-2 - ---+---- 1----+----2----+----3-- 0 01111101 00000000000000000000101 S└ E ┘ └──── M ────┘
あと、指数部と仮数部の特別な組み合わせが存在する。
| 値 | 指数部(S) | 仮数部(M) |
|---|---|---|
| ±0 | 全部0 | 0 |
| ±Infinity | 全部1 | 0 |
| NaN | 全部1 | 0以外 |
IEEE754 倍精度浮動小数点数のフォーマットに詳しく解説したものがあります。
Cの標準関数のsrand, randはPerlの同名の関数と動きが違う。つまり、min_val~max_valの乱数を求める場合はこんな感じ?(間違ってたら言ってください。)
srand( (unsigned)time( NULL ) ); n = min_val + ( ( max_val - min_val ) * ( (double)rand() / (double)RAND_MAX ) );
でも、max_val - min_valがRAND_MAXより小さいなら、これもありかも。
srand( (unsigned)time( NULL ) ); n = rand() % ( max_val - min_val ) + min_val;
VC++のヘルプで「C の switch ステートメント」(HTMLヘルプへのリンクです)をひいてみると、「switch expression と case constant-expression には整数型を指定する必要があります。」と記述がある。C++は文字列も指定できたような・・・という気がして、C++の方も見てみたが、「整数で」って書いてあるな・・・サンプルも文字はあっても文字列はない。
法大奥山研究室:C言語:14.4. switch文
で見ても定数に限るってあるし、整数らしい。VBから入った人間にはえ?って感じ。