無題

フォーラム(掲示板)ルール
フォーラム(掲示板)ルールはこちら  ※コードを貼り付ける場合は [code][/code] で囲って下さい。詳しくはこちら
すぷりんたー

無題

#1

投稿記事 by すぷりんたー » 18年前

はじめまして!!!!!大学の課題で~ポインタ,構造体,関数分割,ファイル分割のすべてを利用した自作ツールをひとつ作成して下さい.テーマは自由!!!
ってレポート課題がでました。。。
んで自分は
1:関数分割、ファイル分割が何かわからないし使い方がわからない
2:ポインタ、構造体のプログラムはあるが、4つを使用したプログラムの組み立て方を教えてもらいたい

ちなみにポインタのプログラムは
#include <stdio.h>

int main(void)
{
char *clubname = "deson.z";

printf("clubname = \"%s\"\n", clubname);

return(0);
}

構造体のプログラムは#include <stdio.h>

struct gstudent{
char name[20]; /*名前*/
int height; /*身長*/
float weight; /*体重*/
float speed; /*速度*/
};

int main(void)
{

struct gstudent masanao = {"Masao", 162, 60.5, 11.78};

printf("めんばー: %s\n", masao.name);
printf("身  長: %d\n", masao.height);
printf("体  重: %f\n", masao.weight);
printf("100M: %f\n", masao.speed);

return(0);
}

です!!!!
てつだってくれませんか?????

バグ

Re:無題

#2

投稿記事 by バグ » 18年前

えっと、作るうえの条件ばかりで、結局は何をするプログラムを組みたくて、あなたが何について聞きたいのかが全く分かりません…(;^_^A
質問はもう少し具体的にお願いします…これでは答えようがありません。

すぷりんたー

Re:無題

#3

投稿記事 by すぷりんたー » 18年前

申し訳ないです。。。。
この4つの条件さえ使ったプログラムならなんでもいいので~

特にわからないのが~関数分割とファイル分割です。。。

どうやって使うのかが知りたいです↓

バグ

Re:関数分割について

#4

投稿記事 by バグ » 18年前

とりあえず、関数分割から…

関数の分割というのは、あらかじめ宣言だけをしておいて、関数の中身を別の場所で実装することを言います。例えば、余りにも長いコードを書く必要がある場合に、1ヶ所に関数をまとめて宣言しておけば確認が容易になり、名前の重複なども防ぐことができます。
#include	<stdio.h>

int	Calc( int , int );

void	main()
{
	int	a , b , c;
	
	a = 1;
	b = 2;
	c = Calc( a , b );
	
	printf( "a + b = %d" , c );
}

int	Calc( int d , int e )
{
	return( d + e );
}
例えば、こんな感じです。Calcというint型の引き数を2つもった関数の宣言だけを前もって行っているのが分かるでしょうか?実際の関数の中身は、main関数の下で書かれています。
この程度の規模のプログラムならば、あまり必要性を感じないとは思いますが、関数が数十個などになってくるとこの方法の有難みが理解できると思います。

バグ

Re:ファイル分割について

#5

投稿記事 by バグ » 18年前

次に、ファイル分割についてですが、これも基本的な考え方は先ほどの関数分割と同じです。ただ、関数や変数の宣言や定義がファイルを跨いでいるだけのことです。#include文で別のファイルから取り込む事ができます。ただし、標準関数以外の自作のヘッダーファイルを取り込みたい時には< >ではなく、" "でファイル名を囲む事に注意してください。
// Kadai.cpp(ファイル名です)
// これがメインのファイルの中身です。
#include	<stdio.h>
#include	"Calc.h"

void	main()
{
	int	a , b , c;
	
	a = 1;
	b = 2;
	c = Calc( a , b );
	
	printf( "a + b = %d" , c );
}
// ここまでが1つのファイルです


// Calc.h(ファイル名です)
// このファイル先ほどの関数分割でいうところのプロトタイプ宣言部になります
int	Calc( int , int );
// ここまでが1つのファイルです


// Calc.cpp(ファイル名です)
// これが関数の実装部分です
#include	"Calc.h"

int	Calc( int d , int e )
{
	return( d + e );
}
// ここまでが1つのファイルです

同じような処理を行う関数などを同じファイルで管理したりすれば、管理が楽になると思います。

すぷりんたー

Re:ファイル分割について

#6

投稿記事 by すぷりんたー » 18年前

解説していただいてありがとうございます!!!!

ただファイル分割だけコンパイルリンクの実行ができないみたいです。。。

原因がわからないです。。。

ちなみに

C:\C06>gcc p0083.c -o p0083
p0083.c:2:25: Calc.h: No such file or directory
p0083.c: In function `main':
p0083.c:5: warning: return type of `main' is not `int'
p0083.c:15:25: Calc.h: No such file or directory

C:\C06>p0083
'p0083' は、内部コマンドまたは外部コマンド、
操作可能なプログラムまたはバッチ ファイルとして認識されていません。

と出てきました↓↓

バグ

Re:無題

#7

投稿記事 by バグ » 18年前

ファイル名~ここまで

を1つのファイルにしていますか?

今回の場合、Kadai.cpp、Calc.h、Calc.cppの合計3つのファイルになりますが、同じフォルダ内にこの3つのファイルが入ってますか?

box

Re:ファイル分割について

#8

投稿記事 by box » 18年前

> p0083.c: In function `main':
> p0083.c:5: warning: return type of `main' is not `int'

この警告は、main関数の型がintでないために出ています。
C言語の規格上、main関数の型はintと決まっています。

それに反したコードを書くと、gccではこんな風に
警告するようになっているのでありましょう。

バグ

Re:無題

#9

投稿記事 by バグ » 18年前

なるほど、gccは触った事がなかったので、勉強になります(^-^)

>>Calc.h: No such file or directory

>>Calc.h: No such file or directory

ただ、この2つの文章はファイルが存在してないことを示していますよね?

すぷりんたー

Re:無題

#10

投稿記事 by すぷりんたー » 18年前

>BOXさん
この警告は、main関数の型がintでないために出ています。
C言語の規格上、main関数の型はintと決まっています

とコメントいただきありがとうございました!!!
ただ、どこをかえればいいのか全くわからないです↓
お手数ですが、ソースをおしえてもらえないでしょうか???

>バグさん
Kadai.cpp、Calc.h、Calc.cppと3つに分けて、ファイルを保存すればいいのでしょうか??

管理人

Re:無題

#11

投稿記事 by 管理人 » 18年前

すぷりんたーさん、

void main

でメイン関数を書き始めていませんか?

boxさんはこれを

int main

で書き出しなさいとおっしゃっています。

#include <stdio.h>

void main(){

int a,b,c....


こんな感じでメイン関数の書き出しがありますよね?

すぷりんたー

Re:無題

#12

投稿記事 by すぷりんたー » 18年前

あっ!!!!!できました★管理人さんありがとうございます!!!!

ただ~

C:\C06>gcc p0083.c -o p0083
p0083.c:2:25: Calc.h: No such file or directory
p0083.c:15:25: Calc.h: No such file or directory

って表示されるって事は、やはりファイルを分けて保存しないといけないってことですよね????

Hermit

Re:無題

#13

投稿記事 by Hermit » 18年前

>>やはりファイルを分けて保存しないといけないってことですよね????

バグさんの書かれている通りにプログラムを書いているなら、
Kadai.cpp
Calc.cpp
Calc.h
の、3個のファイルに分けて保存するように読み取れますが、
それをコンパイルするには、
gcc Kadai.cpp Calc.cpp -o 出力プログラム名
としなければいけないはず。

vi や、emacs などで、各ファイル名で新規作成しましょう。

すぷりんたー

Re:無題

#14

投稿記事 by すぷりんたー » 18年前

>vi や、emacs などで、各ファイル名で新規作成しましょう
すみませんが、それはファイル名の1例ですか??

あとアホなことを言ってると思うのですが~
ポインタの使ったファイルは↓

#include <stdio.h>

int main(void)
{
char *clubname = "deson.z";

printf("clubname = \"%s\"\n", clubname);

return(0);
}

構造体を使ったファイルは↓

#include <stdio.h>

struct gstudent{
char name[20]; /*名前*/
int height; /*身長*/
float weight; /*体重*/
float speed; /*速度*/
};

int main(void)
{

struct gstudent masao = {"Masao", 162, 60.5, 11.12};

printf("めんばー: %s\n", masao.name);
printf("身  長: %d\n", masao.height);
printf("体  重: %f\n", masao.weight);
printf("100M: %f\n", masao.speed);

return(0);
}

そして、関数分割のファイルが↓

#include <stdio.h>

int Calc( int , int , int);

int main(void)
{
int a , b , c , d;

a = 40;
b = 42;
c = 41;
d = Calc( a , b ,c);

printf( "やり投げコントロールテストの合計結果:a槍 + b槍 + c槍 = %dメートル" , d );
}

int Calc( int e , int f , int g)
{
return( e + f + g);
}

この3つのファイルを使っってファイル分割のプログラムってできませんか???
本当にファイル分割がわからないから、むちゃくちゃ馬鹿な質問してるかも
しれないですが。。。

大工

逆ポーランド記法電卓のプログラム

#15

投稿記事 by 大工 » 18年前

逆ポーランド記法電卓のプログラムを本を見ながら書いてコンパイルしたんですが
エラーをどう処理していいかワカリマセン。
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include "stack.h"//自作ヘッダーファイル.

#define STACK_SIZE 100
#define NUM        256
#define DONE       257

stack_t *creat_stack(unsigned int sz);
void puch(stack_t *stack, int num);
int pop(stack_t *stack);
static int token(int *val);
static void error_recover(stack_t *stack, char *msg);


int main ( void ){
	stack_t *stack;
	int tok;
	int val, x, y;

	//スタックを作成する.

	if( (stack = create_stack(STACK_SIZE)) == NULL ){
		fprintf(stderr, "failed to create stack.\n");
		exit(EXIT_FAILURE);
	}
	printf("> ");
	for(;;){
		if((tok = token(&val)) == DONE){
			break;
		}
		switch(tok){
			case NUM:
				push(stack, val);
				break;
			case '+':
				y = pop(stack); x = pop(stack);
				push(stack, x + y);
				break;
			case '-':
				y = pop(stack); x = pop(stack);
				push(stack, x - y);
				break;
			case '*':
				y = pop(stack); x = pop(stack);
				push(stack, x * y);
				break;
			case '/':
				y = pop(stack); x = pop(stack);
				if(y == 0){
					error_recover(stack, "divide by zero");
					continue;
				}
				push(stack, x / y);
				break;
			case '\n':
				if(sp_read(stack) == 1){
					printf("%d\n", pop(stack));
					printf("> ");
					break;
				}
				ungetc(tok, stdin);
			default: //不正なトークンを検出.s
				error_recover(stack, "invalid input");
				printf("> ");
				break;
			}
		}
		free(stack);

	return EXIT_SUCCESS;
}

stack_t *creat_stack(unsigned int sz){
	stack_t *new_stack;
	//スタックデータの確保.
	new_stack = (stack_t*)malloc( sizeof(stack_t) + sizeof(int)*(sz - 1) );
	if(new_stack == NULL){
		return NULL;
	}
	new_stack->top = 0;
	new_stack->size = sz;

	return new_stack;
}
/*
  push:
	引数で指定したスタックstackに値numをプッシュする.
*/
void push(stack_t *stack, int num){
//スタックが満杯の場合はメッセージを出力して終了する.
	if(is_full(stack)){
		fprintf(stderr, "stack overflow.\nss");
		exit(EXIT_FAILURE);
	}
	stack->data[stack->top++] = num;
}
/*
  pop:
	引数で指定したスタックstackから値をポップする.
*/
int pop(stack_t *stack){
	//スタックが空の場合はメッセージを出力して終了する.
	if(is_empty(stack)){
		fprintf(stderr, "stack underflow.\n");
		exit(EXIT_FAILURE);
	}
	return stack->data[--stack->top];
}
//token: トークンを取得する.
static int token(int *val){
	int ch;

	while ((ch = getchar()) != EOF){
		if(ch == ' ' || ch == '\t'){
			continue;
		}
		else if(isdigit(ch)){
			ungetc(ch, stdin);
			scanf(" %d", val);
			return NUM;
		}
		else{
			return ch;
		}
	}
	return DONE;
}
//error_recover: エラーからの回復処理.
static void error_recover(stack_t *stack, char *msg){

	int ch;

	fprintf(stderr, "ERROR: %s.\n", msg);
	init_stack(stack);
	while((ch = getchar()) != EOF){
		if(ch == '\n') return;
	}
	exit(EXIT_FAILURE);
}
自作ヘッダファイル.
typedef struct stack{
	int top;       //スタックトップの位置.
	int size;      //データ部の大きさ.
	int data[1];   //データ部.
} stack_t;

//スタックの状態を判定するマクロ.
#define is_empty(st)   ((st)->top == 0)
#define is_full(st)    ((st)->top == (st)->size)
#define sp_read(st)    ((st)->top)
#define init_stack(st) ((st)->top = 0)

//スタック操作関数のプロトタイプ宣言.
extern stack_t *create_stack(unsigned int sz);
extern void push(stack_t *st, int num);
extern int pop(stack_t *st)
エラー
stack.c: In function `pop':
stack.c:13: error: storage class specified for parameter `token'
stack.c:14: error: storage class specified for parameter `error_recover'
stack.c:17: error: parse error before '{' token
stack.c:17: error: old-style parameter declarations in prototyped function definit
ion
stack.c: At top level:
stack.c:103: error: redefinition of 'pop'
stack.c:17: error: previous definition of 'pop' was here
stack.c:131: error: conflicting types for 'error_recover'
stack.c:52: error: previous implicit declaration of 'error_recover' was here

box

Re:逆ポーランド記法電卓のプログラム

#16

投稿記事 by box » 18年前

>extern int pop(stack_t *st)

セミコロンが抜けています。

それから、関数名で
creat_stack
create_stack
が混在しています。

大工

Re:逆ポーランド記法電卓のプログラム

#17

投稿記事 by 大工 » 18年前

あちゃ~・・・

お恥ずかしいエラーですil:il|;l|;il:i(-ω-`;)ll|l|il|;:il|!

ありがとうございます。

閉鎖

“C言語何でも質問掲示板” へ戻る