ページ 1 / 1
無題
Posted: 2007年1月19日(金) 23:49
by すぷりんたー
はじめまして!!!!!大学の課題で~ポインタ,構造体,関数分割,ファイル分割のすべてを利用した自作ツールをひとつ作成して下さい.テーマは自由!!!
ってレポート課題がでました。。。
んで自分は
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:無題
Posted: 2007年1月20日(土) 07:58
by バグ
えっと、作るうえの条件ばかりで、結局は何をするプログラムを組みたくて、あなたが何について聞きたいのかが全く分かりません…(;^_^A
質問はもう少し具体的にお願いします…これでは答えようがありません。
Re:無題
Posted: 2007年1月20日(土) 09:32
by すぷりんたー
申し訳ないです。。。。
この4つの条件さえ使ったプログラムならなんでもいいので~
特にわからないのが~関数分割とファイル分割です。。。
どうやって使うのかが知りたいです↓
Re:関数分割について
Posted: 2007年1月20日(土) 10:15
by バグ
とりあえず、関数分割から…
関数の分割というのは、あらかじめ宣言だけをしておいて、関数の中身を別の場所で実装することを言います。例えば、余りにも長いコードを書く必要がある場合に、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:ファイル分割について
Posted: 2007年1月20日(土) 10:29
by バグ
次に、ファイル分割についてですが、これも基本的な考え方は先ほどの関数分割と同じです。ただ、関数や変数の宣言や定義がファイルを跨いでいるだけのことです。#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:ファイル分割について
Posted: 2007年1月20日(土) 15:46
by すぷりんたー
解説していただいてありがとうございます!!!!
ただファイル分割だけコンパイルリンクの実行ができないみたいです。。。
原因がわからないです。。。
ちなみに
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:無題
Posted: 2007年1月20日(土) 18:12
by バグ
ファイル名~ここまで
を1つのファイルにしていますか?
今回の場合、Kadai.cpp、Calc.h、Calc.cppの合計3つのファイルになりますが、同じフォルダ内にこの3つのファイルが入ってますか?
Re:ファイル分割について
Posted: 2007年1月20日(土) 18:23
by box
> p0083.c: In function `main':
> p0083.c:5: warning: return type of `main' is not `int'
この警告は、main関数の型がintでないために出ています。
C言語の規格上、main関数の型はintと決まっています。
それに反したコードを書くと、gccではこんな風に
警告するようになっているのでありましょう。
Re:無題
Posted: 2007年1月20日(土) 19:10
by バグ
なるほど、gccは触った事がなかったので、勉強になります(^-^)
>>Calc.h: No such file or directory
>>Calc.h: No such file or directory
ただ、この2つの文章はファイルが存在してないことを示していますよね?
Re:無題
Posted: 2007年1月20日(土) 23:53
by すぷりんたー
>BOXさん
この警告は、main関数の型がintでないために出ています。
C言語の規格上、main関数の型はintと決まっています
とコメントいただきありがとうございました!!!
ただ、どこをかえればいいのか全くわからないです↓
お手数ですが、ソースをおしえてもらえないでしょうか???
>バグさん
Kadai.cpp、Calc.h、Calc.cppと3つに分けて、ファイルを保存すればいいのでしょうか??
Re:無題
Posted: 2007年1月21日(日) 00:45
by 管理人
すぷりんたーさん、
void main
でメイン関数を書き始めていませんか?
boxさんはこれを
int main
で書き出しなさいとおっしゃっています。
#include <stdio.h>
void main(){
int a,b,c....
こんな感じでメイン関数の書き出しがありますよね?
Re:無題
Posted: 2007年1月21日(日) 08:24
by すぷりんたー
あっ!!!!!できました★管理人さんありがとうございます!!!!
ただ~
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
って表示されるって事は、やはりファイルを分けて保存しないといけないってことですよね????
Re:無題
Posted: 2007年1月21日(日) 10:52
by Hermit
>>やはりファイルを分けて保存しないといけないってことですよね????
バグさんの書かれている通りにプログラムを書いているなら、
Kadai.cpp
Calc.cpp
Calc.h
の、3個のファイルに分けて保存するように読み取れますが、
それをコンパイルするには、
gcc Kadai.cpp Calc.cpp -o 出力プログラム名
としなければいけないはず。
vi や、emacs などで、各ファイル名で新規作成しましょう。
Re:無題
Posted: 2007年1月22日(月) 00:16
by すぷりんたー
>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つのファイルを使っってファイル分割のプログラムってできませんか???
本当にファイル分割がわからないから、むちゃくちゃ馬鹿な質問してるかも
しれないですが。。。
逆ポーランド記法電卓のプログラム
Posted: 2007年2月09日(金) 23:36
by 大工
逆ポーランド記法電卓のプログラムを本を見ながら書いてコンパイルしたんですが
エラーをどう処理していいかワカリマセン。
#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
Re:逆ポーランド記法電卓のプログラム
Posted: 2007年2月09日(金) 23:55
by box
>extern int pop(stack_t *st)
セミコロンが抜けています。
それから、関数名で
creat_stack
create_stack
が混在しています。
Re:逆ポーランド記法電卓のプログラム
Posted: 2007年2月10日(土) 00:00
by 大工
あちゃ~・・・
お恥ずかしいエラーですil:il|;l|;il:i(-ω-`;)ll|l|il|;:il|!
ありがとうございます。