次のような問題がわからなくて困っています。

まず、キーボード入力により配列の大きさを決め、
その後、先ほど入力した個数のデータをキ-ボードから入力するというものです。
これだけならわかるのですが、条件があって、入力は次のようにするとあります。
2 3 ←配列の大きさ(2行3列)
1 2 3 ←配列に入れるデータ 1行目
4 5 6 ←配列に入れるデータ 2行目

Cプログラミングを始めて間もない初心者です。どなたかよろしくお願いします。

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

A 回答 (2件)

領域の動的確保のやり方と、それを二次元配列に適用するあたりが分からない


んですよね?

大きさが決っていない配列を扱うには malloc() を使います。

また、二次元配列を扱うときには、一次元の配列の配列を順次獲得する
必要があることに注意が必要です。

多分、実物を見た方が分かりが早いんじゃないかなと思います。


#include <stdio.h>
#include <stdlib.h>

int main(void)
{
  int** ar; /* 行列 */
  int row;  /* 行数 */
  int col;  /* 列数 */
  int i, j;

  /* 行列の入力 */
  scanf("%d %d", &row, &col);
  ar = malloc(row * sizeof(int*));
  for (i = 0 ; i < row ; ++i)
  {
    ar[i] = malloc(col * sizeof(int));
    for (j = 0 ; j < col ; ++j)
    {
      scanf("%d", &ar[i][j]);
    }
  }

  /* 行列の確認 */
  printf("\n");
  for (i = 0 ; i < row ; ++i)
  {
    for (j = 0 ; j < col ; ++j)
    {
      printf("%d ", ar[i][j]);
    }
    printf("\n");
  }

  /* 確保した領域を開放 */
  for (i = 0 ; i < row ; ++i)
  {
    free(ar[i]);
  }
  free(ar);

  return 0;
}

この実物では、動作上、必須ではないのですが、malloc() で確保した領域を
free() で開放しています。開放は確保した順と逆に行うことに注意して。

分からないところがあれば、補足して下さい。
    • good
    • 0
この回答へのお礼

回答ありがとうございます。ソースまで書いていただいたおかげで、何とか理解できました。実は領域の動的確保よりももっと初歩的なところでつまずいていたのですが、それも解決しました。重ねて御礼申し上げます。

お礼日時:2001/08/07 19:17

領域の動的確保と、ポインタ操作ができれば、問題なく解けます。



条件の例でいっているのは、キーボードで2,3,1,2,3,4,5,6と数字キーを押すと、
最初の2個が行と列のサイズ(配列領域として[2][3]分を動的に確保)を指定し、
3個目が1行1列目(配列表現だと[0][0]に位置する箇所)、
4個目が1行2列目(配列表現だと[0][1]に位置する箇所)、
5個目が1行3列目(配列表現だと[0][2]に位置する箇所)、
6個目が2行1列目(配列表現だと[1][0]に位置する箇所)、
7個目が2行2列目(配列表現だと[1][1]に位置する箇所)、
8個目が2行3列目(配列表現だと[1][2]に位置する箇所)
に入る(入れる)様にするということです。
    • good
    • 0
この回答へのお礼

回答ありがとうございます。質問の言葉が足りなくて申し訳ありません、わからないところはキーボード入力により、1行目の数値、1 2 3を一度に取り込むというところです。領域の動的確保はだいたい解ると思います。

お礼日時:2001/08/07 18:16

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

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

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

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

QC++ 数値データファイルから2次元配列への格納法

C++ 初心者です。

以下のような半角スペースと+ 又は - の符号付きの数値データファイル"data"を読み込んで2次元配列に収納するプログラムを教えて頂きたいです。
(アンダーバー"_"で、半角スペースを表します)

___-10.2__20.1_
_30.3___________-50.3___
______3.1____-9.2__

なお、C++の参考書に、「通常の配列はあらかじめサイズを決めて作成しなければならないが、vectorにはメモリが許す範囲でいくつでも要素を追加できる」と書いてあり、この点を活かしたプログラムを作成したいので、最初にデータ数を決めないで、データファイルの最後にくるまで読み込めるようなプログラムにしたいです。

プログラム中で、

for 又は while () {
___________for 又は while() {
______________________cout << "n[" << i << "][" << j << "]= " << n[i][j] << endl;
___________}
}

のように記述して以下のように出力されるようにしたいです。

n[0][0]= -10.2
n[0][1]= 20.1
n[1][0]= 30.3
n[1][1]= -50.3
n[2][0]= 3.1
n[2][1]= -9.2

すみませんが、わかる方がいらっしゃいましたら、宜しくお願いします。

C++ 初心者です。

以下のような半角スペースと+ 又は - の符号付きの数値データファイル"data"を読み込んで2次元配列に収納するプログラムを教えて頂きたいです。
(アンダーバー"_"で、半角スペースを表します)

___-10.2__20.1_
_30.3___________-50.3___
______3.1____-9.2__

なお、C++の参考書に、「通常の配列はあらかじめサイズを決めて作成しなければならないが、vectorにはメモリが許す範囲でいくつでも要素を追加できる」と書いてあり、この点を活かしたプログラムを作成したいので、最初にデータ数を決...続きを読む

Aベストアンサー

やはり、安直に置き換えるとダメですね。

「配列風」のほうは、こんな感じに修正(出力結果は同じ)
pair を使ったソースも、inner は、while() のループの中で定義した方がいい気がする。


#include <vector>
#include <fstream>
#include <iostream>

int main()
{
std::vector<std::vector<double> > n;

std::ifstream inf("test.txt");

while(1)
{
std::vector<double> inner;
double a;
double b;

inf >> a >> b;
if (inf.eof()) break;

inner.push_back(a);
inner.push_back(b);
n.push_back(inner);
}

for (int i = 0; i < n.size(); i++)
std::cout << "[" << i << "] = " << n[i][0] << ", " << n[i][1] << "\n";

}

やはり、安直に置き換えるとダメですね。

「配列風」のほうは、こんな感じに修正(出力結果は同じ)
pair を使ったソースも、inner は、while() のループの中で定義した方がいい気がする。


#include <vector>
#include <fstream>
#include <iostream>

int main()
{
std::vector<std::vector<double> > n;

std::ifstream inf("test.txt");

while(1)
{
std::vector<double> inner;
double a;
double b;

inf >> a >> b;
if (inf.eof()) break;

inner.push_back(a);
inner.push_back(b);
n.push_back(inner);...続きを読む

Q大きな配列データを複数ある場合のデータ保持の方法

indowsXP VC++.net2003で開発をしています。

100*100程度の2次元配列が20から50程度ある場合、データはどう保持しているのが良いのでしょうか?
同時に使うのは1個のみですので、すべて宣言するのはメモリの無駄だと思っています。
思いついた方法は
1.テキストファイルに保持しておく
2.データベースに保持しておく
の2つですが、ユーザーに配列の中身が見られたり変更されたりするのも困るので1の方法は却下しました。
2の方法ですがデータベースを用意するのは無理なのであきらめました。

また、配列データはツールから作成しており、以下のように宣言しやすいように表示されます。
値をひとつひとつ代入して初期化するのも大変なので、できればこの表示をいかしたまま、
必要な配列を取り出して扱うということをしたいのですが、何か良い方法はないでしょうか?

それともint型の100*100の2次元配列 50個程度なら宣言したほうがいいのでしょうか?


int test[32][32] = {
{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},

以下省略

indowsXP VC++.net2003で開発をしています。

100*100程度の2次元配列が20から50程度ある場合、データはどう保持しているのが良いのでしょうか?
同時に使うのは1個のみですので、すべて宣言するのはメモリの無駄だと思っています。
思いついた方法は
1.テキストファイルに保持しておく
2.データベースに保持しておく
の2つですが、ユーザーに配列の中身が見られたり変更されたりするのも困るので1の方法は却下しました。
2の方法ですがデータベースを用意するのは無理なのであきらめました。

...続きを読む

Aベストアンサー

int型の100×100の2次元配列50個程度なら数MBだと思うので,
メモリが厳しい環境でなければ宣言してしまっても問題ないと思います.

メモリの事を気にするのであれば,
動的に宣言するのが一般的だと思います.

Q整数データの配列から同じ値のデータを削除する関数

C言語で整数データの配列から同じ値のデータを削除する関数 int remove_same_data(int a[],int size)を作成する。
但し、この関数は重複したデータを削除して残った個数(整数)を関数の戻り値として返すものとする。

ちなみにここまで出来ました。
下にある途中の1,2,3ができればこのプログラミングができると思うんですが…
分かる方は知恵を貸してください。よろしくお願いします。

#include<stdio.h>
void swap_array(int a[], int size, int i)
{
int t;
if(i>=0 && i<size-1){
t=a[i];a[i]=a[i+1];a[i+1]=t;
}
}

void mysort(int a[], int size)
{
int i,j;
for(j=size-1;j>0;j--){
for(i=0;i<j;i++){
if(a[i]>a[i+1])
swap_array(a,size,i);
}
}
}

int remove_same_data(int a[], int size)
{
1.sort
2.重複部分を削除する
3.残ったデータの個数を返す
}
int main()
{
int a[]={3,5,2,3,4,2,3,3,6,6,1,2,2,3,5,8,2,9}, size=18;
int i,newsize;

newsize = remove_same_data(a, 18);


for(i=0;i<newsize;i++){
printf(" %d ", a[i]);
}

return(0);
}



1はこれを使えば出来るらしいのですがよく分かりません。
void swap_array(int a[], int size, int i)
{
int t;
if(i>=0 && i<size-1){
t=a[i];a[i]=a[i+1];a[i+1]=t;
}
}

void mysort(int a[], int size)
{
int i,j;
for(j=size-1;j>0;j--){
for(i=0;i<j;i++){
if(a[i]>a[i+1])
swap_array(a,size,i);
}
}
}



2はこれを使えばできるらしいのですがなかなかできません。
#include<stdio.h>
int main()
{
int a[8]={1,3,3,4,4,5,6,6},size=8;

//ソート済みデータの重複の削除
int i,j,p;
p=a[0];//前のデータの記憶
j=0;//削除するデータ数を数える
for(i=1;i<size;i++){
if(p==a[i]){
j=j+1;
}
else{
a[i-j]=a[i];//削除するデータ数分前へ
p=a[i];
}
}


//配列の表示
for(i=0;i<size-j;i++){
printf("%3d ", a[i]);//ここで1,3,4,5,6と表示される
}
return(0);
}

C言語で整数データの配列から同じ値のデータを削除する関数 int remove_same_data(int a[],int size)を作成する。
但し、この関数は重複したデータを削除して残った個数(整数)を関数の戻り値として返すものとする。

ちなみにここまで出来ました。
下にある途中の1,2,3ができればこのプログラミングができると思うんですが…
分かる方は知恵を貸してください。よろしくお願いします。

#include<stdio.h>
void swap_array(int a[], int size, int i)
{
int t;
if(i>=0 && i<size-1){
t=a[i];a[...続きを読む

Aベストアンサー

★質問者さんへ。
>ちなみにここまで出来ました。
>下にある途中の1,2,3ができればこのプログラミングができると思うんですが…
>分かる方は知恵を貸してください。よろしくお願いします。
 ↑
 swap_array()…正しい
 mysort()…正しい
 remove_same_data()…1.2.3 の通りに処理を記述すればよいだけです。
 処理手順は
>2はこれを使えばできるらしいのですがなかなかできません。
 ↑
 これで良いと思います。
・よってもう正しく重複データを削除できると思います。
 何をアドバイスすればよいのでしょうか?
 私も『補足要求』しますね。
・ちなみに remove_same_data() 関数は 1.2.3 の手順どおりに
 int remove_same_data( int a[], int size )
 {
  int i, j, p;
  
  // ソート
  mysort( a, size );
  
  //ソート済みデータの重複の削除
  p = a[0]; //前のデータの記憶
  j = 0; //削除するデータ数を数える
  for ( i = 1 ; i < size ; i++ ){
   if( p == a[i] ){
    j = j + 1;
   }
   else{
    a[ i - j ] = a[ i ];//削除するデータ数分前へ
    p = a[ i ];
   }
  }
  return size - j;
 }
 ↑
 で良いでしょう。
・それでは。また。

★質問者さんへ。
>ちなみにここまで出来ました。
>下にある途中の1,2,3ができればこのプログラミングができると思うんですが…
>分かる方は知恵を貸してください。よろしくお願いします。
 ↑
 swap_array()…正しい
 mysort()…正しい
 remove_same_data()…1.2.3 の通りに処理を記述すればよいだけです。
 処理手順は
>2はこれを使えばできるらしいのですがなかなかできません。
 ↑
 これで良いと思います。
・よってもう正しく重複データを削除できると思います。
 何をアドバイスす...続きを読む

Q配列のポインタ配列のポインタから元の配列を参照する方法について

C初心者です。下記の様に配列のポインタ配列を作って、そのポインタ配列のポインタを返すコードを書いて、main関数で元の配列の値を参照したいのですが、上手く参照できずに困っています。下記のコードの問題点も含めて、配列のポインタ配列のポインタから、元の配列の値を参照する方法を教えてください。お願い致します。

short int *motion_data(void)
{
short int data1[5][7] = {
{2377,2174,0,0,0,0,0},
{2377,2377,2784,2648,2648,2648,2377},
{2377,2377,2784,2648,2648,2648,2377},
{2377,2377,2377,2377,2377,0,0},
{2377,2377,2377,2377,2377,0,0},
};
short int data2[5][7] = {
{2377,2174,0,0,0,0,0},
{2377,2377,2919,2784,2784,2784,2377},
{2377,2377,2919,2784,2784,2784,2377},
{2377,2377,2377,2377,2377,0,0},
{2377,2377,2377,2377,2377,0,0},
};

short int *po_data[2];

po_data[0] = data1[0];
po_data[1] = data2[0];

return *po_data;
}

C初心者です。下記の様に配列のポインタ配列を作って、そのポインタ配列のポインタを返すコードを書いて、main関数で元の配列の値を参照したいのですが、上手く参照できずに困っています。下記のコードの問題点も含めて、配列のポインタ配列のポインタから、元の配列の値を参照する方法を教えてください。お願い致します。

short int *motion_data(void)
{
short int data1[5][7] = {
{2377,2174,0,0,0,0,0},
{2377,2377,2784,2648,2648,2648,2377},
{2377,2377,2784,2648,2648,2648,2377},
{2377,2377,2...続きを読む

Aベストアンサー

>元の配列の値を参照する方法を教えてください。

 下のようにすると「元の配列の値を参照」できました。
  (BorlandC++5.5.1)

 No.3 さんの言われるように、
 
>関数を抜けると変数自体無くなってしまいます

 「中身自体」は、その番地をいじくらない限り、「ずっと」残っていてくれればいいんだけど・・。
 やっぱ、static かな。

#include <stdio.h>

short **motion_data( void )
{
 short data1[ 5 ][ 7 ] = {
  { 100, 101, 102, 103, 104, 105, 106 },
  { 110, 111, 112, 113, 114, 115, 116 },
  { 120, 121, 122, 123, 124, 125, 126 },
  { 130, 131, 132, 133, 134, 135, 136 },
  { 140, 141, 142, 143, 144, 145, 146 }
 };
 short data2[ 5 ][ 7 ] = {
  { 200, 201, 202, 203, 204, 205, 206 },
  { 210, 211, 212, 213, 214, 215, 216 },
  { 220, 221, 222, 223, 224, 225, 226 },
  { 230, 231, 232, 233, 234, 235, 236 },
  { 240, 241, 242, 243, 244, 245, 246 }
 };
 short *po_data[ 2 ];

 po_data[ 0 ] = &data1[ 0 ][ 0 ]; // もち = data1[ 0 ]; でも
 po_data[ 1 ] = &data2[ 0 ][ 0 ];

 return( &po_data[ 0 ] );
}
void main( void )
{
 short **po_data, *p1, *p2;

 po_data = motion_data();

 p1 = po_data[ 0 ] + 13; // 任意の「元の配列の値を参照」
 p2 = po_data[ 1 ] + 34; //   〃

 printf( "%d\n", *p1 );
 printf( "%d\n", *p2 );
}
注:インデントに全角空白を用いています。コピペ後、タブに一括変換して下さい。

>元の配列の値を参照する方法を教えてください。

 下のようにすると「元の配列の値を参照」できました。
  (BorlandC++5.5.1)

 No.3 さんの言われるように、
 
>関数を抜けると変数自体無くなってしまいます

 「中身自体」は、その番地をいじくらない限り、「ずっと」残っていてくれればいいんだけど・・。
 やっぱ、static かな。

#include <stdio.h>

short **motion_data( void )
{
 short data1[ 5 ][ 7 ] = {
  { 100, 101, 102, 103, 104, 105, 106 },
  { 110, 111,...続きを読む

Q2次元配列の数値管理をポインター操作で行いたい

こんにちは。ちょっとわかりにくい説明かと思います。

行いたいイメージは
byte test[2][X]= {{0,0,0,0,0},{1,1,1,1,1} };
というデータ配列Xの数が変動するので
Mallocを使用して動的にメモリを確保したい。(ここでは例として5つとってますが)
それをポインター変数により管理したいと考えています。

byte *test;
byte num= 5;
test = (byte *)MALLOC(sizeof(byte)*(2*(num)));

というようにメモリを確保した後
ある文字列("01001"というような文字列)をこの配列にコピーしたい。
配列のイメージでは
test[0]={{0,1,0,0,1}};
test[1]={{1,0,0,1,1}};
というような形で管理したいと思ってます。

pBuffer="01001";
memcpy(pBuffer, test[0], 5);
pBuffer="10011";
memcpy(pBuffer, test[1], 5);

このように実装しました。
これであってますでしょうか?

さらに、ここからデータを取得したい場合
例えば二次元配列でいう
test[0][1]に入っている(この例題では)1を取り出すには
どのような記述になるのでしょうか?

わかりにくい記述で申し訳ないですが、
ご存知の方、よろしくご教授ください。

こんにちは。ちょっとわかりにくい説明かと思います。

行いたいイメージは
byte test[2][X]= {{0,0,0,0,0},{1,1,1,1,1} };
というデータ配列Xの数が変動するので
Mallocを使用して動的にメモリを確保したい。(ここでは例として5つとってますが)
それをポインター変数により管理したいと考えています。

byte *test;
byte num= 5;
test = (byte *)MALLOC(sizeof(byte)*(2*(num)));

というようにメモリを確保した後
ある文字列("01001"というような文字列)をこの配列にコピーしたい。
配列のイメ...続きを読む

Aベストアンサー

やりたいことがよくわからないのでメモリ確保のところだけですが,

byte *test[2];
int num = 5;
test[0] = malloc(sizeof (test[0][0])*num);
test[1] = malloc(sizeof (test[1][0])*num);

とすれば普通の 2次元配列と同じアクセスできます.


人気Q&Aランキング

おすすめ情報