• 締切済み

バイトスワップをやりたい

C言語でバイトスワップをやりたいです。voidポインタを使って インプットを受けます。受けたものをHexに変更して、スワップをします。 スワップしたものを表示します。 例えは、 int value(16)が入りました。それをhexに変更すると、intが4バイトですから、 00 00 00 0F に成ります。それをまたスワップすると 0F 00 00 00 に成りたいです。 インプットはdoubleなら 00 00 00 00 00 00 00 0F に成ります。 スワップすると0F 00 00 00 00 00 00 00 に成りたいです。 本当にすみませんですが、出来れば教えてください。 宜しくお願い致します。

  • Suei
  • お礼率33% (2/6)

みんなの回答

回答No.4

回答No.3の「ビット配列のエンディアンを変換する用途を想定するならば、」は誤りで 「バイト配列のエンディアンを変換する用途を想定するならば、」だと思います。 バイトオーダーの切り替え処理に関する質問であってビット・ナンバリングの話ではないと思うので。

  • Ogre7077
  • ベストアンサー率65% (170/258)
回答No.3

ネットワーク出力やファイル出力に使用するために、 ビット配列のエンディアンを変換する用途を想定するならば、 汎用的に実装しては如何でしょうか。 void changeEndian(void* dst, void* src, int size) { int i; unsigned char *p = (unsigned char*)dst; unsigned char *q = (unsigned char*)src; p = p + size; for (i = 0; i < size; i++) *(--p) = *(q++); } // 16ビット整数の変換 short int ax, a = 0x12AB; changeEndian(&ax, &a, sizeof(a)); printf("%04hX, %04hX\n", a, ax); // "12AB, AB12" と表示 // 64ビット整数の変換 long long int cx, c = 0x1234ABCD; changeEndian(&cx, &c, sizeof(c)); printf("%016lX, %016lX\n", c, cx); // "000000001234ABCD, CDAB341200000000" と表示 // 倍精度浮動小数点数の変換 double dx, d = 1.1; changeEndian(&dx, &d, sizeof(d)); printf("%016lX, %016lX\n", *(long*)&d, *(long*)&dx); // "3FF199999999999A, 9A9999999999F13F" と表示(IEEE形式の場合)

Suei
質問者

お礼

どうもありがとうございました。勉強になりました。

noname#208507
noname#208507
回答No.2

下のような事をしたいのでしょうけれど、0x0Fは16ではなく15です。 doubleも何か勘違いをされていますね。 #include <stdio.h> typedef struct {  unsigned char uc0, uc1, uc2, uc3; } uchar4; typedef union {  uchar4 uc4;  int i; } xint; static int value(int num) {  xint y = { .i = num };  unsigned char tmp0 = y.uc4.uc0;  unsigned char tmp1 = y.uc4.uc1;  y.uc4.uc0 = y.uc4.uc3;  y.uc4.uc1 = y.uc4.uc2;  y.uc4.uc2 = tmp1;  y.uc4.uc3 = tmp0;  return y.i; } int main(void) {  int i = value(15);  printf("%08X -> %08X\n", 15, i);  return 0; }

Suei
質問者

お礼

どうもありがとうございました。勉強になりました。

  • Tacosan
  • ベストアンサー率23% (3656/15482)
回答No.1

どこができなくて困っているのですか? ちなみに「インプットはdoubleなら」のところは本気で何を言っているのかさっぱり分からない.

関連するQ&A

  • ビットスワップとバイトスワップとは何ですか??

    こんにちは。 今、C言語でのプログラミングについて勉強しているのですが、 その際の課題で、「32bit値を入力するとビットスワップされた結果とバイトスワップされた結果が 表示されるプログラムを作成して下さい(入力及び表示は16進数)」といったものが出されました。 で、その際のビットスワップとバイトスワップの意味がわからず、困っています。 どんな結果が出力されたら良いのか、ご教授いただけませんでしょうか? どうかよろしくお願いいたします。

  • 【C言語】別関数でポインタの値を変えたのに変わらない。

    【C言語】別関数でポインタの値を変えたのに変わらない。 メイン関数のポインタの値を、別関数で書き換えるプログラムを作りました。 以下がそのプログラムになります。 そのままだと、ダブルポインタを操作する必要があるので分かり辛いです。なので、ダブルポインタをシングルポインタにしてからポインタの書き換えを行うようにしました。その結果、きちんとポインタの書き換えが出来なくなってしまいました。 なぜ出来なくなってしまったのでしょうか。 2つのプログラムの違いは、 >  *pp = &dummy; が >  p = *pp;      // ダブルポインタをシングルポインタにした >  p = &dummy; に変わっただけです。 【参考】http://www.kouno.jp/home/c_faq/c4.html#8 -----------------正しいプログラム---------------- // 以下プログラムは、正しく動作する // 実行結果は、 //   p = 5 // と表示される void func( int **pp ); int main (void){   int *p;   int a = 0;   p = &a;   func( &p );   printf("p = %d\n", *p);   return 0; } void func( int **pp ){   static int dummy = 5;   *pp = &dummy; } ---------------------------------------------- -----------------間違いプログラム---------------- // 以下プログラムは、正しく動作しない // 実行結果は、 //   p = 0 // と表示される void func( int **pp ); int main (void){   int *p;   int a = 0;   p = &a;   func( &p );   printf("p = %d\n", *p);   return 0; } void func( int **pp ){   static int dummy = 5;   int *p;   p = *pp;      // ダブルポインタをシングルポインタにした   p = &dummy; } ----------------------------------------

  • void型へのポインタ

    というのがC言語にありますよね? このvoid型へのポインタというのは、 どのようにイメージすればいいのでしょうか? 例えばchar型へのポインタなら、 指している領域は 1バイトの領域ですよね? ではvoid型は? また malloc関数を 使って char *p; p=(char *)malloc(1000); とするとでchar型にキャストしているから、 1個1バイト分の領域が1000個用意して、 先頭アドレスをpに格納するのですよね? では、 int *q; q=(int *)malloc(1000); としたら、用意されるのは、int型にキャストしているから 1個2バイト分の領域が500個用意されるのでしょうか? お願いします。

  • フルポインタ仕様にしたい。

    プロローグ ポインタはデータがメモリさせれいるアドレスを扱うので、引数では関数を呼び出すたびにデータ本体をコピーせずにすみます。 だから、限られた資源の中比較的高速のプログラムができる… でも、ポインタはスペースシャトルの機内からロボットアームで小さな作業を行う感覚で、結構厄介な存在でもあります。 でも、ポインタを気持ちよく操れないとゲームなど高速なプログラムはできません。 そこで、データのやり取りはアドレスのみというルールで、簡単なプログラム書いてみましたが、コンパイルしてくれるものの、エラーが発生して動いてくれません。どこがおかしいのでしょうかご教授おねがいします。もし、「ポインタのみで作るのは無理があるでしょう?」と思う場合は「そりゃむでっせ」とか書いてください。 #include <iostream> using namespace std; class Bass{ private: int* m_piData; // ポインタ変数(int) double* m_pdData; // ポインタ変数(double) public: void SetData(int* piData, double* pdData); void DataShow(int* piData, double* pdData); int iGatData(){return *m_piData;} double dGatData(){return *m_pdData;} }; void Bass::SetData(int* piData, double* pdData) { *m_piData = *piData; *m_pdData = *pdData; } void Bass::DataShow(int* piData, double* pdData) { cout << *piData << 'と' << *pdData << '\n'; } int main() { int iTestData=1234; // int型データ(表示用) double dTestData=20.5; // double型データ(表示用) int* piTestData; double* pdTestData; Bass* c_pBass; // private変数データ書込み・ポインタ c_pBass->SetData(&iTestData, &dTestData); // インライン関数(private変数関数)・ポインタ *piTestData = c_pBass->iGatData(); // int型 *pdTestData = c_pBass->dGatData(); // double型 // private変数参照 c_pBass->DataShow(piTestData, pdTestData); return 0; }

  • 変数 および ポインタのサイズ(バイト数)について

    sizeof演算子を使ってchar int float double型のバイト数を調べると、char 型については1バイトと決まっていて、int float doubleについては2から8バイト(処理系によって違う)なのは理解できます。しかし、char* int* float* double*型(ポインタ型)のバイト数は2から4バイトになるのが多いとおもいますが、どういう理由でポインタ型のバイト数が決まるのか、その理由をお教え願いたく思います。16ビットcpuあるいは32ビットcpuと言うハードの影響なのかそれとも何かソフトによるのか、その理由を知りたいと思います。なお私の処理系ではポインタは全て4バイトになっています。特に不思議に思うのはchar型は1バイトなのに、char*型が4バイトになっていることです。 宜しく願います。

  • 関数のポインタのポインタ・・・

    main内部を変更してはならない。 関数setとsetsetで、3.140000と表示させよ gcc -Wallでいろいろと探したのですが /bin/などと表示されていて、何を直せばいいのか、わからない状態です。 簡易c言語だと 3.139999 = 3.140000 となります どこかで0.000001を足すのでしょうか? でもxで3.14で出てますしね。むしろなぜ3.13999が出てきたのか。 ただ学校のコンパイラだとセグメントエラが出ます #include <stdio.h> void out(double **); void set(double *,double **); void setset(double **,double ***); int main() { double x; double *p; double **pp; x = 3.14; set(&x, &p); setset(&p, &pp); out(pp); return 0; } void set(double *x,double **p) { *p = x; } void setset(double **p,double ***pp) { **pp = *p; } void out(double **pp) { printf("%f = 3.140000\n", **pp); }

  • x^2+2x+1=0

    x^2+2x+1=0をとく関数プログラムです。 うまくできません。どこが間違っているのでしょうか。 教えて下さい。 #include<stdio.h> #include<math.h> void input_keisuu(double a,double b,double c); void solve(double a,double b,double c); int main(void) { double a,b,c; input_keisuu(a,b,c); solve(a,b,c); return 0; } void input_keisuu(double a,double b,double c) { puts("二次関数a*x^2+b*x+c=0を解きます。"); a=1; b=2; c=1; puts("a=1"); puts("b=2"); puts("c=1"); } void solve(double a,double b,double c) { double d; double x; d=b*b-4*a*c; printf("判別式d= %f\n",d); x=(-b+ sqrt(d))/(2*a); printf("二つの解のうち大きい方はx=%f\n",x); }

  • ■int型の数値から数字文字への変換について

    はじめまして。専門学生のhide1978と申します。 今回、以下のような問題に取り組んでいるのですが、どうしても正しい結果が得られません。どなたか知恵を授けてやってください。よろしくお願いいたします。 ■問題 int型の数値(-32767から32767)を入力して、そのまま10進文字列(char型)として変換する。 ■私が書いたプログラム #include <stdio.h> int NUMtoCHAR(int c){ if(c >= 0 && c <= 9) return (c+'0'); else return c; } void main(void){ signed int i_value; int count, i; double f_value; char c[9]; printf("入力データ:");scanf("%d",&i_value); printf("\n"); for(i = 0; i < 9; i++) c[i] = ' '; if(i_value > 0){ c[0] = '+'; }else if(i_value < 0){ c[0] = '-'; } f_value = (double)i_value; count = 0; while(f_value >= 1){ f_value = f_value / 10.0; count++; } if(count == 0){ c[2] = '0'; }else{ for(i = 2; count > 0 && i < 9; count--, i++){ f_value = f_value * 10.0; i_value = f_value; c[i] = NUMtoCHAR(i_value); f_value = f_value - i_value; } } printf("10進文字 = "); for(i = 0; i < 9; i++) printf("%c", c[i]); printf("\n"); } 上記プログラムを実行して、入力データとして[32767]を入力すると、結果が[32766]となってしまいます。同じように[34]を入力すると[33]という結果になります。 elseの中に入れ子になっているfor文が怪しいということまでは判るのですが、どのように修正してよいか判りません。 大変長い質問で恐縮ですが、よろしくお願いいたします。 ■環境 OS:WindowsXP Compiler:Borland C++ 5.5.1 fowWin32

  • long double型の戻り値を持つ関数について

    文字列を浮動小数点に変換したいと思っています。 StrToFloat()を用いたのですが、有効数値がケタ落ちしてしまいました。 そこで、次のように関数を定義して実行したところ、やはり戻り値の値がケタ落ちしました。 long double StrToValue(AnsiString str) { ・・・・・ return value; } 具体的にはlong doubleの有効数値がdouble型の有効数値にまで落ちてしまっています。 次にポインタを使い、次のように変更したのですが、結果は同じでした。 void StrToValue(AnsiString str, long double *value) { ・・・・・ *value=・・・; ・・・・・ } どなたか、この解決方法と、できれば理由を教えてください。 なお使用した言語は、C++Builder 5 環境はWindows 98 です。

  • C言語のvoid型ポインタ変数について。

    C言語のvoid型ポインタ変数について。 C言語のvoid型ポインタ変数について質問があります。 組み込み系の開発を行っているのですが、現在使用しているシステムで、 提供されている "API" を介してアプリケーション部のソフト作成を行っています。 この "API" ですが、引数の多くはvoid型ポインタとなっています。 ある人がこの引数がvoid型となっているのを見て、 『なんでvoid型なんや??、C言語でアセンブラと違うんやから、void型なんかにしない方が良い』 とおっしゃいました。 この意味がよくわからなかったのですが、なぜ void型はよろしくないんでしょうか? -- 僕が思うに、APIなんやから引数を void型ポインタ にすることでどんな型にも対応できる 汎用的であると感じ、逆にこの方が良いのではと感じたのですが。。 -API例---- int _exApiKannsuu( char in_data, void* out_data ) "in_data" をもとに "out_data" を取得する。 どーやらこの "out_data" が void型 であるのががよくないらしい・・