質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.50%
C

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

Q&A

解決済

4回答

506閲覧

Cで先頭アドレスを指定して宣言されたDoubleの配列を連結したい

TSH1984

総合スコア22

C

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

0グッド

0クリップ

投稿2018/05/28 12:31

編集2018/05/28 12:33

現状の説明

表題の通りだとちょっとよく分からないかもしれませんが、現在、以下のように2種類の先頭をメモリ番地の直接指定で決め打ちしている配列が2つあります。

c

1double* A = (double*)(0xaaaa); 2double* B = (double*)(0xbbbb); 3

実際にやりたいこと

A,Bは先頭からdoubleで100個分にデータが入っていて、
最終的には配列A,Bを連結した長さ200の配列Xを使えるようにしたいです。

困っていること

以下のように書いてA,Bを連結してみたのですがエラーが出てうまくいきません。
正しいやり方をご教授いただけたら幸いです。

c

1double* X; 2&X[0] = (double*)(0xaaaa); 3&X[100] = (double*)(0xbbbb);

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答4

0

ベストアンサー

C

1double *A = (double*)(0xaaaa); 2double *B = (double*)(0xbbbb); 3double x[200]; 4 5bcopy(A, X, sizeof(double)*100); 6bcopy(B, X+100, sizeof(double)*100);

では?

あるいは、

C

1double *A = (double*)(0xaaaa); 2double *B = (double*)(0xbbbb); 3double *x[200]; 4int i; 5 6for(i=0; i<100; i++){ 7 x[i] = A+i; 8} 9for(i=0; i<100; i++){ 10 x[100+i] = B+i; 11}

投稿2018/05/28 12:50

otn

総合スコア84423

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

TSH1984

2018/05/28 12:56

ありがとうございます。 bcopyが用意されてない環境なので、2つめのコードで試してきます。
otn

2018/05/28 13:06

データのコピーで良いなら、別にbcopyなんて自分で書けば良いと思いますが。書けませんか?であれば、初心者マークを付けておいた方が良かったと思います。 2つ目のコードは、データをコピーせずに、データへのポインタを配列にしていますので、 「連結した配列のi番目の要素の値」は、*x[i] で参照します。
TSH1984

2018/05/28 13:14

すみません。遅くならないうちにすぐに検証して動かそうと思っていたので上記コメントをしました。 2つめのコードで動きました。ありがとうございます。
guest

0

こんにちは。

最終的には配列A,Bを連結した長さ200の配列Xを使えるようにしたいです。

  1. double 200個分のメモリを用意してそこへコピーするのが、最も一般的な解と思います。
  2. もしも運良くAとBの間がdoubleちょうど100個分だったら、普通にAで連続アクセスできます。例えば、A[100]はB[0]です。
  3. ありえないと思いますが、もしも仮想メモリをいじることができ、かつ、double 100個分単位でアドレスを割り振れるならば、A+100のアドレスにB+0のメモリを割り当てることで可能です。

でも、ごめんなさい。アドレス決め打ちで配列の先頭アドレスを指定しているということは、小さな組み込み用CPU上のプログラムと思います。この場合、上記の1.と3.は適用できない可能性が高いです。

投稿2018/05/28 12:50

Chironian

総合スコア23272

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

TSH1984

2018/05/28 12:55

回答ありがとうございます。 2はダメだと思います。100個ちょうどではないです。 3も仮想メモリはいじれないので、すみません。 1で試してみます。 ただ、もう1人の方の2つめのコードと同じだと思うので、もしこれで解決するようだったら、もう1人の方がコードも載せてくださっているので、そちらをBAにさせて頂きます。 (普通にiを足すのではなくsizeof(double)*iだとは思いますが) 試してくるので少し時間をください。コメントありがとうございました。
guest

0

無理です。

&X[0] = (double*)(0xaaaa);

&X[0] は、X の先頭アドレスを示します。(変数ではありません)
&X[100] も同様。

また、配列 or ポインタは、連続したアドレスが前提となっています。
連続した領域にコピーして使用すべきです。
もっとも物理/論理アドレスのマッピングを変更してなんてのがありならば、可能ですが、それは普通しないと思います。

投稿2018/05/28 13:04

pepperleaf

総合スコア6383

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

最終的には配列A,Bを連結した長さ200の配列Xを使えるようにしたいです。

TSH1984さんが意図されたようなシンプルな書き方では、できません。

(double*)(0xaaaa)と固定の値で宣言されたメモリ空間は移動できないこと、
&X[0]といったアドレス表現にたいする代入はC言語の文法ではないことが理由です。

もしやるとするなら、メモリを管理するリスト構造体をつくり、連結させたうえで手動でメモリ空間を管理しつつ、値をゲット・セットしてやる必要がありそうです。

C

1struct MemoryManager; 2 3typedef struct MemoryManager { 4 double *ptr; 5 size_t size; 6 struct MemoryManager *next; 7} MemoryManager; 8 9double MemoryManager_Get(MemoryManager *mm, size_t index) 10{ 11 do { 12 if(mm->size < index) { 13 index -= mm->size; 14 mm = mm->next; 15 } 16 else { 17 break; 18 } 19 }while(mm != NULL); 20 return mm->ptr[index]; 21} 22 23Set関数は省略☆(ゝω・)v

投稿2018/05/28 12:57

kazto

総合スコア7196

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.50%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問