ふと、疑問に思ったのですが、
プログラムの設計をするときにPAD図を書いたりしますよね?

ループから抜けるような時はどうすれば良いのでしょうか?
ここだと図がかけないので説明しづらいと思いますがお願いします。

int a=0;
while(1) {
if( a==10 ) {
break;
}
a++;
}

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

A 回答 (2件)

すんごく、説明しづらいです :-)


ブラウザでプロポーショナルフォントではない(例えば、MSゴシック)ものを
指定すると、少しマシかも。

│                Y ┌───\
├┬──────┐ ┌──────┬─┤break  >
││無限ループ ├─┤a== 10? <  └───/
├┴──────┘ ├──────┘
│         ├──────┐
│         │a を1増やす│
│         └──────┘

PAD は、いろいろ方言があるようなのですが、私が教えられたのは、
縦長の家の形のような五角形を横倒しにしたもの、もしくは、
細長い二等辺三角形を横倒しにしたものの中に "break" とか
"ループ中断" などと記入するやつです。
    • good
    • 0

ループの書き方は普通while、until、forのタイプで下記


ループの中に、whileだったらループ条件、
untileだったら、終了条件を書きます。
無限ループの書き方は出来るだけ使わないように教わりました。
本当に無限ループでないならば、必ず終了条件があると言う事です。
今回の例では、aが10以外の時処理を行うループとして書きました。

-----
a=0|
-----

------- -------
while||--|a=a+1|
a<>10|| -------
-------
    • good
    • 1

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

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

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

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

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

Qint型配列の一括初期化

現在、ある配列をfor()でループさせて初期化させていますが、もっと高速に初期化できる方法はないでしょうか?

//配列の初期化
int Xi[256];

for(i = 0; i < 256; i++){
   Xi[i] = 0;
}

今後、配列数を増やす予定なので高速に初期化できるものはないか探しています。
速度重視でよろしくお願いします。

Aベストアンサー

全ての要素が0で初期化された配列を確保したいのであれば、calloc()を使うというのはどうでしょうか? 上記のコードより速いという保証はありませんが。

#include <stdlib.h>
int *Xi = (int *)calloc(256, sizeof(int));

配列が不要になった時点でfree(Xi)するのをお忘れなく。また、初期値が0以外の場合にはこの手は使えません。

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 ポインタを使って関数の値のやり取り

c言語の問題なのですが、2つの異なる1次元配列の積をseki関数を使って計算してもうひとつの配列に入れてmain関数で表示するのですが、うまく走りません原因がわかる人がいた教えてください。
作った実行文は、
#include<stdio.h>
int seki(int *pa,int *pb,int *pc);
main(){
int a[]={5,2,3,5,3,2,4,8,9,9,7},b[]={4,3,8,4,6,2,8,9,1,6,4},c[11]={0};
int i,*pa,*pb,*pc;

pa=&a;
pb=&b;
pc=&c;

seki(pa,pb,pc);
for(i=0;i<11;i++)
printf("%d,",*(pc+i));

}
int seki(int *pa,int *pb,int *pc){
int j;
for(j=0;j<11;j++)
*(pc+j)=*(pa+j) * *(pb+j);
}
こんな表示が出てきます。
toi2.c: In function `main':
toi2.c:7: warning: assignment from incompatible pointer type
toi2.c:8: warning: assignment from incompatible pointer type
toi2.c:9: warning: assignment from incompatible pointer type
たぶんmain関数内で書いたseki関数の引数の型に問題があると思うのですが。

c言語の問題なのですが、2つの異なる1次元配列の積をseki関数を使って計算してもうひとつの配列に入れてmain関数で表示するのですが、うまく走りません原因がわかる人がいた教えてください。
作った実行文は、
#include<stdio.h>
int seki(int *pa,int *pb,int *pc);
main(){
int a[]={5,2,3,5,3,2,4,8,9,9,7},b[]={4,3,8,4,6,2,8,9,1,6,4},c[11]={0};
int i,*pa,*pb,*pc;

pa=&a;
pb=&b;
pc=&c;

seki(pa,pb,pc);
for(i=0;i<11;i++)
printf("%d,",*(pc+i));

}
int seki(int *pa,int *pb,i...続きを読む

Aベストアンサー

質問の下に書かれているコンパイルエラーと思われる表示から
そのエラーの原因が読み取ることが出来ます。
ここでの原因は、プログラム中次の3行がエラーであると指摘されています。
7行目:pa=&a;
8行目:pb=&b;
9行目:pc=&c;
それぞれ、どういう状況かというと、
エラーをそのまま訳せば
『ポインタとしての割り当て方がおかしいですよ』
という風に捉えられます。
まず、整数型配列として宣言してあるaという変数があります。
これは、これ自身がポインタであるので
&aという表記では、『ポインタ変数aのポインタ』ということになり、
純粋なポインタ変数paには代入する事ができません。
よって、上のエラーを解消するには、
pa = a;
とすればよいでしょう。
(8,9行目も同様)

Qscanfでの読み込み文字数制限

scanf( "%10s" , file_name );
とすればfile_nameに読み込む文字数を10バイトに制限できるそうですが、10のところに定数(defineで定義したもの)を指定することはできないのでしょうか?

普通に
#define NUM 10
scanf( "%NUMs" , file_name );
としてもできないようでした。

Aベストアンサー

#define NUM 10 のままで

sprintf(fmt, "%%%ds", NUM);
scanf(fmt , file_name);

という方法もあります。

QエクセルVBAでテキストボックスの値の取得と変更について

エクセルのVBAを使ってシート上のテキストボックスのテキストを取得・変更するマクロを作成したいと思っていますがうまく行きませんので、お知恵を拝借したいとおもいます。

環境:WindowsXPでオフィス2002
状況:
エクセルブックa.xlsのシートに「コントロールツールボックス」のテキストボックスを配置(オブジェクト名はTEXTBOX_C)
エクセルブックb.xlsにコードを書き、a.xlsのTEXTBOX_CのプロパティのValueかTextを取りだしたい

試した事:
コントロールを配置したシートに次のマクロ
TEXTBOX_C.Text = "これはコントロールのテキストボックス"
を書くとテキストボックスに文字を入れ込めますが、別のエクセルブックからだと上手く行きません。

また、オートシェイプのテキストボックスの場合は簡単に出きるのですが、コントロールツールボックスではどうしても上手く行きませんので、対象法などご存知の方いらっしゃいましたら教えてください

Aベストアンサー

エクセルを新規に開きました。
そのSheet1に(コントロールツールボックスの)TextBoxを貼りつけました。
そのBook1から、ファイル-開くで別ブックを開きました。
別ブックのMojule1側に下記を書いて
Sub test02()
MsgBox Workbooks("book1").Worksheets("sheet1").textbox1.Text
End Sub
を実行すると、Book1のTextBoxに入れた文字列が表示
されました。
がそんな質問ではないのですか。

Q加減剰余のオーバーフローについて

今C言語で加減剰余のプログラムを作っていて、
オーバーフローのチェックだけが上手くいきません。
limits.hをインクルードして、オーバーフローのチェック
を行いたいのですがどうすればよいのでしょうか?
扱いたい範囲はint型の-2147483648~2147483647です。
ちなみに開発環境はvc++2005です。

一応ソースを載せておきますので、よろしくお願いします。
#pragma warning ( disable : 4996 )

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <ctype.h>
#include <limits.h>

int main ( int argc, char *argv[] )
{
int start;//最初に入力する値(引数1)
int end;//最後に入力する値(引数3)
int kekka;//計算結果を格納
int amari;//除算の余りを格納
int max = INT_MAX;//表すことが出来る最大値
int min = INT_MIN;//表すことが出来る最小値

char enzansi;//入力する演算子 (引数2)
char str1[512];//格納用の配列を宣言(start用)
char str2[512];//格納用の配列を宣言(end用)

/*引数の個数チェック */
if ( argc != 4 ) {
printf ( "usage : %s start enzansi end\n", argv[0] );
exit ( 0 );
}

/*引数を取得して整数型に変換*/
start = atoi ( argv[1] );
end = atoi ( argv[3] );

/*引数の取得*/
enzansi = ( argv[2][0] );

sprintf ( str1, "%d", start );//str1に値を格納
sprintf ( str2, "%d", end );//str2に値を格納

/*str1とargv[1]による文字列の比較 */
if ( strcmp ( str1, argv[1] ) ) {
printf ( "error : 整数を入力して下さい。\n" );
exit ( 0 );

/*str2とargv[3]による文字列の比較 */
} else if ( strcmp ( str2, argv[3] ) ) {
printf ( "error : 整数を入力して下さい。\n" );
exit ( 0 );

/*argv[2]が2文字以上の場合 */
} else if ( strlen ( argv[2] ) >= 2 ) {
printf ( "error : 演算子を正しく入力して下さい。\n" );
exit ( 0 );
}

/*入力された演算子の条件ごとに計算 */
if ( enzansi == '+' ) {
kekka = start + end;
} else if ( enzansi == '-' ) {
kekka = start - end;
} else if ( enzansi == '*' ) {
kekka = start * end;
} else if ( enzansi == '/' ) {

/*startの値を0で除算する場合 */
if ( end == 0 ) {
printf ( "error : 0による除算は禁止です。\n" );
exit ( 0 );
}

kekka = start % end;//剰余を求める

/*割り算の結果として余りが出なかった場合 */
if ( kekka == 0 ) {
kekka = start / end;
printf ( "%d %c %d = %d", start, enzansi, end, kekka );
exit ( 0 );

/*割り算の結果として余りが出た場合 */
} else if ( kekka != 0 ) {
kekka = start / end;
amari = start % end;
printf ( "%d %c %d = %d余り%d", start, enzansi, end, kekka, amari );
exit ( 0 );
}



/*入力された演算子が異なる場合*/
} else {
printf ( "error : '+' '-' '*' '/'のいずれかの演算子を入力して下さい。\n" );
exit ( 0 );
}

/*数値1 演算子 数値2 = 演算結果の形式で出力する */
printf ( "%d %c %d = %d", start, enzansi, end, kekka );
exit ( 0 );
}

もし変な部分がありましたら指摘お願いします。
一応四則演算は問題なくできます。

今C言語で加減剰余のプログラムを作っていて、
オーバーフローのチェックだけが上手くいきません。
limits.hをインクルードして、オーバーフローのチェック
を行いたいのですがどうすればよいのでしょうか?
扱いたい範囲はint型の-2147483648~2147483647です。
ちなみに開発環境はvc++2005です。

一応ソースを載せておきますので、よろしくお願いします。
#pragma warning ( disable : 4996 )

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <ctype.h>
#include <limits...続きを読む

Aベストアンサー

★Werner さん、そうですね。注意書きするよりは goto を使うべきでしたね。
・それで追記としてサブ関数にした方が見やすいと付けましたが言葉が足りませんでしたね。
 質問者さんへ。main() 関数の for(;;) の部分がトリッキーでしたので書き直してみました。
 エラー表示の switch 文を void error_print(int errno); というサブ関数にしました。

// エラー表示
void error_print( int errno )
{
 char *errmsg; // エラー文字列を格納
 
 switch ( errno ){
  case ERR_USAGE:
   errmsg = "usage : %s start enzansi end";
   break;
  case ERR_INTEGER:
   errmsg = "整数を入力して下さい。";
   break;
  case ERR_INTOVER:
   errmsg = "整数型の範囲を超えました。";
   break;
  case ERR_ENZAN:
   errmsg = "演算子を正しく入力して下さい。";
   break;
  case ERR_DIVID:
   errmsg = "0による除算は禁止です。";
   break;
  case ERR_OVERFLOW:
   errmsg = "オーバーフローが起こります。";
   break;
 }
 puts( errmsg );
}

// main 関数
int main( int argc, char *argv[] )
{
 int kekka; // 計算結果を格納
 int ret; // 戻り値を受け取る
 
 /* (1)引数のチェック */
 if ( (ret = param_check(argc,argv)) != ERR_SUCCESS ){
  error_print( ret ); ←ここを関数にした。
  return ret;
 }
 
 /* (2)オーバーフローのチェック */
 if ( (ret = overflow_check(INT_MIN,INT_MAX)) != ERR_SUCCESS ){
  error_print( ret ); ←ここを関数にした。
  return ret;
 }
 
 /* (3)演算子による四則演算 */
 kekka = calc( start, enzansi, end );
 
 /* (4)演算結果を表示 */
 printf ( "%d %c %d = %d", start, enzansi, end, kekka );
 return 0;
}

その他:
・引き算のオーバーフローのロジックを整理すると
 (1)正数 - 正数
 (2)正数 - 負数
 (3)負数 - 正数
 (4)負数 - 負数
 の4タイプしかありません。
 このうち、(1)、(4)は int 型の範囲に納まるためチェックは不要です。
 あとは(2)、(3)の符号が異なるときに、それぞれオーバーフローのチェックを分けて
 記述すれば良い。詳しくは回答者 No.13 さんのアドバイスをどうぞ。
・以上。

★Werner さん、そうですね。注意書きするよりは goto を使うべきでしたね。
・それで追記としてサブ関数にした方が見やすいと付けましたが言葉が足りませんでしたね。
 質問者さんへ。main() 関数の for(;;) の部分がトリッキーでしたので書き直してみました。
 エラー表示の switch 文を void error_print(int errno); というサブ関数にしました。

// エラー表示
void error_print( int errno )
{
 char *errmsg; // エラー文字列を格納
 
 switch ( errno ){
  case ERR_USAGE:
   errm...続きを読む

Q数字の入った配列をファイルへ出力。

今、hist[256]というint型の配列に数字が入っているとします。
これを、テキストファイルに出力して、

0
242
5654
232
3123
756



こんな感じで、ファイルに出力したいです。

文字としての出力になるのでhist[256]配列を、int型からchar型に変換しないとダメでしょうか?
また、変換するとしたら、char型だと unsigned char にしても 0~256の値までしか1つの配列に保存できませんよね?
もっと大きい数字も入っているので何とかする方法も教えて下さい。

初歩的な質問で申し訳ありませんが、よろしくお願いします。

Aベストアンサー

fprintf()関数を使えば簡単です。
簡単に言えば、printf()関数のファイル出力版です。
画面ではなく、ファイルに文字列を出力します。

サンプル
------------------------
FILE *fp;
int i;
if((fp = fopen("data.txt", "w")) != NULL){
 for(i = 0; i < 256; i++){
  if(fprintf(fp, "%d\n", hist[i]) < 0){
   //書き込みエラー
   break;
  }
 }
 fclose(fp);
}else{
 //ファイルオープンエラー
}
------------------------

%d で int型の整数を文字として表示、
\n で改行です。printf()関数と同じですね。

#サンプルはインデントに全角スペースを使っています。

-----------------------------------------------------------
>int型からchar型に変換しないとダメでしょうか?
>また、変換するとしたら、char型だと unsigned char にしても 0~256の値までしか1つの配列に保存できませんよね?

ちょっと勘違いしているようなので、説明しますが・・・

C言語の文字列は、文字の配列です。
char型は1文字を表わします。
文字列は、char型の配列になります。

例えば、整数の 123 を文字列で表現する場合、
文字数は3文字で、終端にヌル文字('\0')が入りますので、
4文字の配列になります。

unsigned char c[] = {'1','2','3','\0'};

一つ一つは文字コード(0~255)ですので、char型で問題ありません。

fprintf()関数を使えば簡単です。
簡単に言えば、printf()関数のファイル出力版です。
画面ではなく、ファイルに文字列を出力します。

サンプル
------------------------
FILE *fp;
int i;
if((fp = fopen("data.txt", "w")) != NULL){
 for(i = 0; i < 256; i++){
  if(fprintf(fp, "%d\n", hist[i]) < 0){
   //書き込みエラー
   break;
  }
 }
 fclose(fp);
}else{
 //ファイルオープンエラー
}
------------------------

%d で int型の整数を文字として表示、
\n で...続きを読む

Qgetchar()をつける意味

Visual C++ 2005 Express Edition
でC言語を習っている者です。

「getchar()はおまじないのようなものだから」と言う風にしか説明してくれず、付ける意味がわかりません。

なぜgetcharをつけるのでしょうか。
また、つけないと支障はありますか。

Aベストアンサー

「おまじない」とのことなので、scanfの後で改行を読み飛ばすような話ではない気がします(getcharを入れるだけでは確実ではないですし)。
多分、

#include <stdio.h>
int main(void)
{
 puts("Hello, World!");
 getchar(); /* ← おまじない */
 return 0;
}

こうしておかないと、IDEからプログラムを起動した場合、一瞬だけコンソールが現れてすぐに消えてしまうからとか、そういうことではないでしょうか?
実際にはこんな姑息な対応はするより、return 0;のところにブレークポイントでも貼っておく方がずっとましです。

いずれにせよ、質問者さんが補足してくれないことにはどうしようもありません。

Q配列のNULL初期化について

C言語についての課題の一部です。
int型の配列 iArrayをNULL初期化したいのですが、
課題では下のように書かれています。
&iArray[] = NULL;
このような書き方でNULL初期化することは可能なのでしょうか?

Aベストアンサー

>NULL初期化することは可能なのでしょうか?
できません。文法上間違っています。

また、NULLはint型の値ではないので、「NULLで初期化する」とは言いません。
ちなみにiArrayを0で初期化する場合は下記のようになります。
int iArray[5];
int i;
for (i=0; i<sizeof(iArray)/sizeof(i); i++) {
iArray[i] = 0;
}
他にも色々な方法があります。参考まで。

QC言語での改行コードの扱いについて教えてください。

改行コードは一般的に、
Windows・・・「CR+LF」
UNIX or Linux・・・「LF」

だと思うのですが、改行コードが「LF」のファイルをWindows上で、C言語で編集したらどういった改行コードになるのでしょうか。
(例えば、単純にファイルを1レコードずつ読み込んで別ファイルに書き込むといった処理)

出力時に「CR+LF」になってくるのでしょうか?それともまったく別のものになってしまうのでしょうか?

詳しい方、ぜひ教えてください。


※改行コード「LF」のテキストファイルは、UNIXサーバから「HULFT」というファイル転送ソフトの「バイナリ転送モード」でWindowsサーバに送られてくる予定です。

Aベストアンサー

実行環境にWindowsを想定している処理系では、ファイルをオープンする際のオープンモードには「テキスト」と「バイナリ」の区別があります。

テキストタイプでオープンすると、ファイルストリーム中の改行コードが自動的に加工されます。

具体的には、
・アプリケーションでストリームを読み込むと、ファイル中のCR+LFがLFに置き換わって読み込まれる。
・アプリケーションからストリームに書き込むと、データ中のLFがCR+LFに置き換わって書き込まれる。
という加工が行われます。

一方、バイナリタイプでオープンした場合、加工は一切行われません。

つまり「ソースコード上では、改行は\nの1文字のみ。実ファイル上で改行がどんな文字コードになっているか考慮する必要はない」と言う事です。

なので、ファイルのデフォルトのオープンモードが「テキスト」になっている場合は、
ofp=open("textfile.txt","w");
fprintf(ofp,"It is text\nHello world\n");
fclose(ofp);
と言うプログラムは、WindowsでもUNIX/Linuxでも、どちらも正しく動作します。(明示的にテキストモードでオープンする場合は、オープンモードの"w"を"wt"にすること)

質問者さんのケースでは、
・Windowsサーバにファイルが届いた時点で、改行はLFのみ⇒このファイルは「バイナリタイプ」でオープンする。
・普通に「1行読む」と言う処理をする⇒ストリームから読む際は「LFまでが1行」として読まれる。
・別ファイルは「テキスト」でオープンする。
・読み込んだ1行を、何も加工せずに別ファイルに改行付き(\n付き)で書き出す⇒改行が勝手にCR+LFに変換されてファイルに書き出される。
・ファイルの最後まで繰り返す。
という処理をすればOKです。

なお、ファイル転送ソフトでバイナリモードのままWindowsサーバに届いたファイルは、Windows上では「改行の無いファイル」として扱われますから、Windows上のメモ帖やテキストエディタでは正常に開けません。

実行環境にWindowsを想定している処理系では、ファイルをオープンする際のオープンモードには「テキスト」と「バイナリ」の区別があります。

テキストタイプでオープンすると、ファイルストリーム中の改行コードが自動的に加工されます。

具体的には、
・アプリケーションでストリームを読み込むと、ファイル中のCR+LFがLFに置き換わって読み込まれる。
・アプリケーションからストリームに書き込むと、データ中のLFがCR+LFに置き換わって書き込まれる。
という加工が行われます。

一方、バイナリタイ...続きを読む


人気Q&Aランキング