出産前後の痔にはご注意!

C言語初心者なのですが課題で出されたポインタを用いた平均,分散を求めるプログラムを組んでみたのですが,以下のようなエラーが出て正しく出力できません。

Undefined symbols for architecture x86_64:
"_main", referenced from:
implicit entry/start for main executable
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)

ソースプログラムは以下のとおりです。詳しい方よろしくお願いいたします。

#include<stdio.h>

double in_data[5] ={1.0,2.0,3.0,4.0,5.0};
double mean = 0.0;
double var =0.0;



void variance(double in_data[],int n,double *mean,double *var){

double sum = 0.0;
for(int i=0;i<n;i++){

sum += in_data[i];

}

*mean = sum / n;

for(int i=0;i<n;i++){
*var += (in_data[i] - *mean)*(in_data[i] - *mean);
}



printf("平均:%f\n",mean);
printf("分散:%f\n",var);

}

A 回答 (3件)

*var を計算する for ループの前で


*var=0;
と初期化しておくのが大人のプログラムだと思う.

あと分散の計算を間違えてる.
    • good
    • 0

以下のようにしてください。


修正個所はコメントを入れています。
内容はチェックしていません。
-----------------------------------
#include<stdio.h>

double in_data[5] ={1.0,2.0,3.0,4.0,5.0};
double mean = 0.0;
double var =0.0;



void variance(double in_data[],int n,double *mean,double *var){

double sum = 0.0;
for(int i=0;i<n;i++){

sum += in_data[i];

}

*mean = sum / n;

for(int i=0;i<n;i++){
*var += (in_data[i] - *mean)*(in_data[i] - *mean);
}

//削除開始
// printf("平均:%f\n",mean);
// printf("分散:%f\n",var);
//削除終了

}

//追加開始
int main(){
variance(in_data,5,&mean,&var);
printf("平均:%f\n",mean);
printf("分散:%f\n",var);
return 0;
}
//追加終了
    • good
    • 0

エラーメッセージを読みとく訓練をしましょう。


上達のコツです。


C言語から実行ファイルができるまでは大きく3つの段階があります。
・マクロの展開や #includeの処理等を行う「前処理」
・前処理されたソースコードを機械語に変換する「(狭義の)コンパイル」
・複数のファイルにちらばっている機械語を一つに結び付ける「リンク」

例えば、 printf ですが、これは純粋な意味では「C言語ではありません」
このプログラムの variance 関数と同じで、誰かがC言語用に作ったものです。
それを、あなたのプログラムと「リンク」させることで、思い通りに出力させることができています。

このときの、関数名等の総称が「Symbol(シンボル)」です。
Undefined symbols というメッセージは、「シンボルが定義されていない」ということです。

リンク先があるかどうかは、実際リンクするときでないとはっきりしません。
なので、(狭義の)コンパイルではエラーにならず、リンク時にはじめて判明します。


この場合、 _main というシンボルが見つからない、と言っています。
コンパイルされた時に、関数名は、 _ を付けたシンボルになります。
つまり、 このメッセージは「 mainをリンクさせようとしたけど見つからない」 と言っています。


このメッセージを元に、プログラムを眺めてみると、確かに main 関数がありません。
C言語では、 実行のスタート地点である main 関数が無ければ、実行ファイルにはできません。
/* この言い方は正確ではありませんが、今は混乱のもとなのでそういうことにしておきます */

「ポインタを用いた平均,分散の求め方」とは無関係です。

・もし、他のファイルに main 関数が記述されているのなら、コンパイルのコマンドラインを変えて、その別ファイルのmain関数を含めるようにする必要があります
(分割コンパイル という手法です)
・もし、このファイルだけで完結するのなら、main関数を追加します。
    • good
    • 2

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

このQ&Aを見た人はこんなQ&Aも見ています

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

Q分散を求めるプログラム

n人の点数を読み込みそれらの平均、分散を計算するプログラムを作りたいのですが分散の式がよく分かりません。
分散を求める式は第i番目の点数をxi、平均をμとすると

分散=1/nΣxi^2-μ^2

で、プラグラムを作ってみると

#include<stdio.h>
int main (void)
{
int i;
int sum=0;
int num,tmp;

printf("何人ですか");
scanf("%d",&num);

for(i=0; i<num; i++)
{
print("No. %d ", i+1)
scanf("%d",&tmp);

sum += tmp;
}
printf("平均:%.3f\n",(double)sum/num);
printf("分散:%.3f\n",(double){(sum-sum/num)*(sum+sum/num)}/num);
return(0);
}

というプログラムを作ってみたのですが分散の計算がうまくいきません。どなたか分散の計算のプログラムを教えて下さい。

C言語初めてまもないので不備があったらすみません。

n人の点数を読み込みそれらの平均、分散を計算するプログラムを作りたいのですが分散の式がよく分かりません。
分散を求める式は第i番目の点数をxi、平均をμとすると

分散=1/nΣxi^2-μ^2

で、プラグラムを作ってみると

#include<stdio.h>
int main (void)
{
int i;
int sum=0;
int num,tmp;

printf("何人ですか");
scanf("%d",&num);

for(i=0; i<num; i++)
{
print("No. %d ", i+1)
scanf("%d",&tmp);

sum += tmp;
}
printf("平均:%.3f\n",(double)sum/num);
printf("分散:%.3f\n...続きを読む

Aベストアンサー

こんばんわ。
ぱっとみでおかしいなと思った部分は、

Σxi^2の部分だと思います。
Σxi^2っていうのは、
Σxi^2=Σx1^2+Σx2^2+・・・+Σxnum^2
っていうことです。
dogtaisiさんはΣxi^2をsum^2と計算しているので
分散の計算がおかしくなっているんじゃないでしょうか?

for文の中に、Σxi^2を計算する式を改めて作ってみるのはどうでしょう?
for(i=0; i<num; i++)
{
print("No. %d ", i+1)
scanf("%d",&tmp);

sum += tmp;
sigmax2 += tmp*tmp;
}
みたいな感じで。

自分自身も初心者なんで、的外れならごめんなさいね。

Q配列 平均値と分散値

#include <stdio.h>

void mean_vari(int *s, int n, double *mean, double *variance);

int main(void)
{
int i, n;
int a[]={34, 54, 21, 80, 60, 90, 15, 24, 100};
double heikin, bunsan;

mean_vari(&i,n,&heikin,&bunsan);

printf("平均=%f 分散=%f\n",heikin,bunsan);

return (0);
}

/* 合計を求める関数 */
void mean_vari(int *s, int n, double *mean, double *variance)
{
int i;
int sum=0;/* 合計の初期化 */
double sum2=0;

for (i = 0; i < n; i++)
sum += s[i];
????=sum/(double)????;

for (i = 0; i < n; i++){
sum2 +=????;
}
????=????;
}

平均値と分散値を求めたいのですが、????の部分になりをいれていいかわかりません。 教えてください。

#include <stdio.h>

void mean_vari(int *s, int n, double *mean, double *variance);

int main(void)
{
int i, n;
int a[]={34, 54, 21, 80, 60, 90, 15, 24, 100};
double heikin, bunsan;

mean_vari(&i,n,&heikin,&bunsan);

printf("平均=%f 分散=%f\n",heikin,bunsan);

return (0);
}

/* 合計を求める関数 */
void mean_vari(int *s, int n, double *mean, double *variance)
{
int i;
int sum=0;/* 合計の初期化 */
double sum2=0;

for (i = 0; i < n; i++)
sum += s[...続きを読む

Aベストアンサー

void mean_vari(int *s, int n, double *mean, double *variance)
{
int i;
int sum=0; /* 合計の初期化 */
double sum2=0;

for (i = 0; i < n; i++)
sum += s[i];
*mean=sum/(double)n;

for (i = 0; i < n; i++){
sum2 +=s[i]-*mean;
}
*variance=sum2;
}

とできませんんか?

Q標準偏差・分散

標準偏差と分散を求めるプログラムで

#include <stdio.h>
#include <math.h>

int main(void){
int i;
double data[10];
double heikin, total = 0.0, variance = 0.0, deviation = 0.0;

for ( i = 0; i < 10; i++ ){

printf("%d番目の値を入力:",i + 1);
scanf( "%lf",&data[i] );
total += data[i];
}

heikin = total / 10.0;

for(i = 0; i < 10; i++ ){

variance += ((data[i]-heikin)*(data[i] - heikin))/10.0;
}
deviation += sqrt(variance); printf("平均値は%f\n" , heikin );
printf("分散は%fです。\n",variance);
printf("標準偏差は%fです\n",deviation);


getchar();
getchar();
return(0);
}
という感じでいいのでしょうか?
分散と標準偏差の式はこれであっているとおもうのですが・・・・。

標準偏差と分散を求めるプログラムで

#include <stdio.h>
#include <math.h>

int main(void){
int i;
double data[10];
double heikin, total = 0.0, variance = 0.0, deviation = 0.0;

for ( i = 0; i < 10; i++ ){

printf("%d番目の値を入力:",i + 1);
scanf( "%lf",&data[i] );
total += data[i];
}

heikin = total / 10.0;

for(i = 0; i < 10; i++ ){

variance += ((data[i]-heikin)*(data[i] - heikin))/10.0;
}
deviation += sqrt(variance); printf("平均値は%f\n"...続きを読む

Aベストアンサー

ん, そんなところ.
あとは気分の問題ですが, 「無駄だ」と思っても, variance を 0 クリアするコードを (variance を積算する) for の前に入れた方がよいかも.

Qポインタで平均(C言語)

こんにちは。大学のプログラミングの講義で
「4名の身長に追加する形でキーボード(標準入力)から自分の身長を入力し、計5名の身長の平均をポインタを使って求めるC言語プログラムを作成せよ」という課題が出されました。
なかなかわからず、現段階では以下のようになっていますが実行すると途中で停止し終了してしまいます。どうすれば正常に作動できますか?

#include <stdio.h>

void hiroko(int *height)
{
if(*height<180)
*height=180;
}

int main(void)
{
int sato=178;
int sanaka=175;
int hiraki=165;
int masaki=179;
double my;

hiroko(&masaki);


puts("身長を入力\n");

printf("自分の身長:");scanf("%f",my);
printf("佐藤君の身長:%d\n",sato);
printf("佐中君の身長:%d\n",sanaka);
printf("平木君の身長:%d\n",hiraki);
printf("真崎君の身長:%d\n",masaki);
printf("5人の身長平均:%f",(my+sato+sanaka+hiraki+masaki)/5);

return 0;

}

こんにちは。大学のプログラミングの講義で
「4名の身長に追加する形でキーボード(標準入力)から自分の身長を入力し、計5名の身長の平均をポインタを使って求めるC言語プログラムを作成せよ」という課題が出されました。
なかなかわからず、現段階では以下のようになっていますが実行すると途中で停止し終了してしまいます。どうすれば正常に作動できますか?

#include <stdio.h>

void hiroko(int *height)
{
if(*height<180)
*height=180;
}

int main(void)
{
int sato=178;
int sanaka=175;
int hiraki=165...続きを読む

Aベストアンサー

変数 my が double なので、scanf() で対応する書式指定子は "%lf" になります。
scanf("%lf", &my);

※ちなみに、printf() における double に対応する書式指定子は、"%f" です。

そもそも、hiroko() という関数が何をしているか説明できますか?
あと、4人の身長が int なのに、自分の身長だけ double なのはなぜか、説明できますか?

QC言語 平均を求めるプログラム

はじめまして。

C言語初学者です。

参考書に、平均を求めるプログラムとして下記が紹介されていますが、疑問点があります。




#include <stdio.h>

int main(void)
{
int data[] = {79,42,39,79,13,75,19};
int i,sum = 0,avg;

for (i = 0;i < sizeof(data) / sizeof(data[0]);i++) {
sum += data[i];
}

avg = sum / (sizeof(data) / sizeof(data[0]));

printf("%d\n",avg);

return 0;
}



・疑問点1
int i,sum = 0,avgの部分
変数【i,sum】に値【0,avg】をそれぞれ代入しているのかと思いますが、【i=0】はわかっても、【sum=avg】の意味が分かりません(合計=平均?)。

・疑問点2
sum += data[i]の部分
【+=】は複合代入演算子で【sum=sum+data】という意味でしょうか。
また、for文で{sum += data[i];}が繰り返す文になっていますが、具体的に何の計算を繰り返しているのでしょうか。

どうか教えていただきたく、お願い致します。

はじめまして。

C言語初学者です。

参考書に、平均を求めるプログラムとして下記が紹介されていますが、疑問点があります。




#include <stdio.h>

int main(void)
{
int data[] = {79,42,39,79,13,75,19};
int i,sum = 0,avg;

for (i = 0;i < sizeof(data) / sizeof(data[0]);i++) {
sum += data[i];
}

avg = sum / (sizeof(data) / sizeof(data[0]));

printf("%d\n",avg);

return 0;
}



・疑問点1
int i,sum = 0,avgの部分
変数【i,sum】に値【0,avg】をそれぞれ代入しているのかと思いますが、【i=0...続きを読む

Aベストアンサー

ついでだから疑問2も解説しよう。

個数が6個だと判ってて普通に平均を求めるなら、

int data[6] = {79,42,39,79,13,75,19};
int sum,avg;

sum = 0;
sum = sum + data[0];
sum = sum + data[1];
sum = sum + data[2];
sum = sum + data[3];
sum = sum + data[4];
sum = sum + data[5];

avg = sum / 6;

で良い。

sum = sum + data[0];



sum += data[0];

と書けるから、そう書き変えると

int data[6] = {79,42,39,79,13,75,19};
int sum,avg;

sum = 0;
sum += data[0];
sum += data[1];
sum += data[2];
sum += data[3];
sum += data[4];
sum += data[5];

avg = sum / 6;

となる。

sumにdataの0番から5番までを順に足す

sum += data[0];
sum += data[1];
sum += data[2];
sum += data[3];
sum += data[4];
sum += data[5];

は、for 文でループに出来るから、そう書き換えると

int data[6] = {79,42,39,79,13,75,19};
int i,sum,avg;

sum = 0;

for (i=0;i < 6;i++) {
sum += data[i];
}

avg = sum / 6;

になる。

sumを0にするのは宣言文で宣言と同時に行えるので、そう書き換えると

int data[6] = {79,42,39,79,13,75,19};
int i,sum=0,avg;

for (i=0;i < 6;i++) {
sum += data[i];
}

avg = sum / 6;

になる。

配列宣言の時に、要素の個数を書かないと、要素の個数は、初期化の為に並べた「初期化子の個数」になる。

初期化子の個数によって要素の個数を決める場合、個数を「5」とか「6」とか固定にしておくと後で困るので、ちょっと工夫します。

「sizeof(data)」と書くと、配列全体の大きさ(バイト数)を返します。

「sizeof(data[0])」と書くと、要素1つ分の大きさ(バイト数)を返します。

配列全体の大きさは、要素全部の分の大きさです。

「要素全部の分」を「要素1個の分」で割れば、要素の個数が判ります。

つまり sizeof(data)/sizeof(data[0]) の式で、要素の個数が求まります。

100バイトのメモリが6つあったら、全体は600バイトで、1つは100バイト。600÷100=6で、無事に個数の「6」が求まります。

要素数が5に減っても、7に増えても、式は変わりません。

コードの中に「6」と直接に書いてあったのを、上記の式に書きかえると

int data[] = {79,42,39,79,13,75,19};
int i,sum = 0,avg;

for (i = 0;i < sizeof(data) / sizeof(data[0]);i++) {
sum += data[i];
}

avg = sum / (sizeof(data) / sizeof(data[0]));

となります。

どうですか?参考書とまったく同じになってませんか?

ついでだから疑問2も解説しよう。

個数が6個だと判ってて普通に平均を求めるなら、

int data[6] = {79,42,39,79,13,75,19};
int sum,avg;

sum = 0;
sum = sum + data[0];
sum = sum + data[1];
sum = sum + data[2];
sum = sum + data[3];
sum = sum + data[4];
sum = sum + data[5];

avg = sum / 6;

で良い。

sum = sum + data[0];



sum += data[0];

と書けるから、そう書き変えると

int data[6] = {79,42,39,79,13,75,19};
int sum,avg;

sum = 0;
sum += data[0];
sum += data[1];
sum += data[2...続きを読む

Q構造体から平均点を求める方法

構造体が(名前、数学の点数、英語の点数、理科の点数)という形で、100人分のデータがあった場合。
この構造体を関数で受け取り、各科目の平均点をパラメタで返し、全体の平均を復帰値にするにはどのような関数にすれば良いのでしょうか。参考のソースを示していただけると助かります。よろしくお願いします。

Aベストアンサー

がるです。

> このような場合、関数の呼び出しと関数内部ではどのようなプログラムにすれば良いのでしょうか。初心者でわからないのでよろしくお願いします。
んっと…どのあたりが分からないのでしょうか?
基本的には「ここまで分かる」部分を提示していただけると、以降のお話がしやすくなるのですが。

ただまぁ、今回の場合概ね予測はできるのですが。多分「構造体の配列の作り方」と「受け取った関数でどうやって"構造体の配列"から"構造体"を取り出すか」の2点だと思われます。

構造体の配列は、「事前にデータ量が明確に分かっている」場合、
構造体名 構造体配列[サイズ];
で固定的に宣言が可能です。
で、もうちょっと高度な手法ですと、

構造体名 *構造体配列; // これは「ポインタ用の変数」を規定します

構造体配列 = (構造体名 *)malloc( sizeof(構造体名) * サイズ );
// または
構造体配列 = (構造体名 *)calloc( sizeof(構造体名), サイズ );

で、動的にサイズを確保します。
アクセス自体は
int i;
for(i = 0; i < サイズ; i ++) {
構造体配列[i].数学の点数 = XX;
}
みたいな感じでOKです。

で、前述の「nullつかって最後をあらわす」場合。
まず構造体の確保サイズを「サイズ+1」にして、後はデータを全部入れた後に
構造体配列[サイズ] = null;
としておくと、判定が楽かと思います。

で、call先の関数内では、

int i;
for(; 構造体配列[i] != null; i++) {
構造体配列[i].数学の点数
}
とかって感じのループにするとよろしいかと。

かな~り大雑把にはしょってますが、欠けている部分は少し調べれば色々出てくるかと思います。
また分からなくなったら質問してください ^^

がるです。

> このような場合、関数の呼び出しと関数内部ではどのようなプログラムにすれば良いのでしょうか。初心者でわからないのでよろしくお願いします。
んっと…どのあたりが分からないのでしょうか?
基本的には「ここまで分かる」部分を提示していただけると、以降のお話がしやすくなるのですが。

ただまぁ、今回の場合概ね予測はできるのですが。多分「構造体の配列の作り方」と「受け取った関数でどうやって"構造体の配列"から"構造体"を取り出すか」の2点だと思われます。

構造体の配列は、...続きを読む

Q複数桁10進数の*桁目だけを抽出したい

タイトルがすべてと言えてしまうのですが、
例えば、int宣言された"4287"(この値は変動します)という数値があったとして、1桁目の"7"だけを別の変数へ引き抜きたいのですが、その場合にはANDによるマスク処理による演算で処理可能なのでしょうか?
また、他に良い方法などありましたら教えていただけますでしょうか?

Aベストアンサー

★10進数ですので AND は使えませんね。
・簡単なサンプルを載せますので読み取って下さい。

サンプル1:
int value = 4287;
int a[ 4 ];

a[0] = (value % 10); value /= 10; // 1桁目を取り出す
a[1] = (value % 10); value /= 10; // 2桁目を取り出す
a[2] = (value % 10); value /= 10; // 3桁目を取り出す
a[3] = (value % 10); value /= 10; // 4桁目を取り出す

サンプル2:
int value = 4287;
int a;

a = (value % 10);
value -= a;

value → 4280
a → 7
になります。

QC言語のポインターに関する警告

line[100]で
「1」が格納されていたら「a」
「2」が格納されていたら「b」
「3」が格納されていたら「c」
とout[100]に代入する関数を作りたいのですが
コンパイルすると関数の部分で
warning: assignment makes integer from pointer without a cast
という警告がでます。
ポインターは使っていないのですが、ポインターに関する警告が出ているようで困っています。
どこが悪いのかまったくわからなくて作業が完全に止まってしまいました。
解決法をおしえてください。お願いします。

/*宣言*/
int=i; /*main関数内のfor文で使用*/
char line[100], out[100];
void change(int);

/*関数*/
void change(int i)
  {
   if(line[i]=='1'){
    out[10]="a\0"
   }if(line[i]=='2'){
    out[10]="b\0";
   }if(line[i]=='3'){
    out[10]="c\0"
}
}

line[100]で
「1」が格納されていたら「a」
「2」が格納されていたら「b」
「3」が格納されていたら「c」
とout[100]に代入する関数を作りたいのですが
コンパイルすると関数の部分で
warning: assignment makes integer from pointer without a cast
という警告がでます。
ポインターは使っていないのですが、ポインターに関する警告が出ているようで困っています。
どこが悪いのかまったくわからなくて作業が完全に止まってしまいました。
解決法をおしえてください。お願いします。

/*宣言*/
int...続きを読む

Aベストアンサー

>    out[10]="a\0"
>    out[10]="b\0";
>    out[10]="c\0"

"a\0"や"b\0"や"c\0"は「charへのポインタ」ですよ。

out[10]は「char」ですから「記憶域が小さい整数(つまり、charに)に、ポインタを代入すると、値が失われるぞ」と警告が出ます。

void change(int i)
  {
   if(line[i]=='1'){
    out[10]='a';
   }if(line[i]=='2'){
    out[10]='b';
   }if(line[i]=='3'){
    out[10]='c';
}
}
または
void change(int i)
  {
   if(line[i]=='1'){
    out[10]=0x61; /* aのASCIIコード */
   }if(line[i]=='2'){
    out[10]=0x62; /* bのASCIIコード */
   }if(line[i]=='3'){
    out[10]=0x63; /* cのASCIIコード */
}
}
と書きましょう。

>    out[10]="a\0"
>    out[10]="b\0";
>    out[10]="c\0"

"a\0"や"b\0"や"c\0"は「charへのポインタ」ですよ。

out[10]は「char」ですから「記憶域が小さい整数(つまり、charに)に、ポインタを代入すると、値が失われるぞ」と警告が出ます。

void change(int i)
  {
   if(line[i]=='1'){
    out[10]='a';
   }if(line[i]=='2'){
    out[10]='b';
   }if(line[i]=='3'){
    out[10]='c';
}
}
または
void change(int i)
  {
   if(l...続きを読む

Q数字の位ごとの値を表示するプログラム

scanfで入力した数字の位ごとの値を表示するプログラムを作りたいのですがどうしたらいいですか?

例えば1234という数字を入れたら
10の位・・・3
1の位・・・4
という感じです

Aベストアンサー

> 10の位・・・3

1234を10で割って小数点以下を切り捨て。→123.4→123
123を10で割った余りを求める。→3

> 1の位・・・4

1234を1で割って小数点以下を切り捨て。→1234
1234を10で割った余りを求める。→4

とか。

Q配列の要素数に変数を入れたいときには

よろしくお願いします。
配列の要素数には定数しか入れられないのですが,どうしても変数を入れたいときは,それを引数として関数を呼び出すしか方法はないでしょうか。
具体的には,scanfで手に入れたint型の変数を要素数とする配列を宣言したいのですが,どうすれば良いでしょうか。
ご教授ください。

Aベストアンサー

c99と呼ばれる最近の規格では、配列の大きさに変数を使用できます。
bccはc99に対応していないようです。

それ以前の規格では、動的領域確保関数 malloc や callocを使って領域を確保するか、効率等を無視してバカデカい配列を用意しておくかです。
「それを引数として関数を呼び出す」っていうのは、malloc/callocのことですか?


人気Q&Aランキング