前提・実現したいこと
※初投稿です。不手際がありましたら申し訳ございません。
①2つの文字列(char *a,char *b)に対して、辞書順を判定する関数int hantei(char *a,char *b)を作成せよ。この関数の戻り値として、aがbより前(辞書順で)にくる場合は1、aとbが同じ文字列の場合は0、それ以外の場合は-1とする。
②バブルソートを用いて文字列配列(char **argv)を辞書順に並び替える関数void sort(char **argv,int n)を作成せよ。また、引数nは文字列の個数を表し、①のhantei関数を用いること。
バブルソートの参考として以下のコードが書いてありました。
C
1void bubble(int list[],int n) 2{ 3 int i,t; 4 5 for(n=n-1;n>=0;n--){ 6 for(i=0;i<n;i++){ 7 if(list[i]>list[i+1]){ 8 t=list[i]; 9 list[i]=list[i+1]; 10 list[i+1]=t; 11 } 12 } 13 } 14} 15
発生している問題・エラーメッセージ
①については自力でコードをかけました。(一度間違えましたが)
C
1#include<stdio.h> 2 3#define N 100 4 5int hantei(char *a,char *b); 6 7int main(void) 8{ 9 int ans; 10 char a[N],b[N]; 11 12 printf("辞書順を判定するぞー!\n"); 13 printf("文字列aを入力してくれ。"); 14 gets(a); 15 printf("文字列bを入力してくれ。"); 16 gets(b); 17 18 ans=comp_d(a,b); 19 if(ans==1){ 20 printf("aの文字列の方が前だぞ。\n"); 21 } 22 else if(ans==0){ 23 printf("aとbは同じ文字列だぞ。\n"); 24 } 25 else if(ans==-1){ 26 printf("bの方が前だぞ。\n"); 27 } 28 29 return 0; 30} 31 32int hantei(char *a,char *b) 33{ 34 int i; 35 for ( i = 0; *(a+i) != '\0' && *(b+i) != '\0'; i++ ) { 36 if(*(a+i)<*(b+i)){ 37 return 1; 38 } 39 if(*(a+i)>*(b+i)){ 40 return -1; 41 } 42 } 43 if(*(a+i)!='\0'){ 44 return 1; 45 } 46 if(*(b+i)!='\0'){ 47 return -1; 48 } 49 return 0; 50} 51 52
②についてが、正直に言うとほとんどわかりませんでしたが、回答者の皆様のおかげですこしずつイメージ自体はつかめるようになってきました。そこで、コードを書いてみましたがいくつかエラーが出てしまいました。
具体的な書き方がつかめておらず、何点か不明な点があります。
〇わからないこと
・//str=(char *)malloc(sizeof(char)*n);では、エラーがでなかったがその直下にあるようにfor文でループさせるとエラーがでます。なぜでしょうか?また、このnは文字列の個数(何個の文字列を入力するか)なのですが、本来は1つ1つの文字列の長さ(文字が何個あるか)を入れるべきなのですが、文字列の長さを計算するにはまず文字列を入力しなければならないわけで、??となっております。
・sort関数内で、tはint型で宣言されています。ここに代入するには文字列の先頭アドレスを代入すればいい、という認識であっているのでしょうか?(問題には参考としてバブルソートが書かれているだけなので無理して合わせる必要はない、とは思いますが)
〇わかったこと
・//str=(char *)malloc(sizeof(char)*n);の意味
char型のサイズ(1バイト)×n(ここでは文字列の個数(何個の文字列を入力するか)ですが)分のメモリをmalloc関数で確保し、それを(char *)に明示的に変換している。(左辺のポインタ変数strにあわせている?)
・関数sortの引数にポインタのポインタ(アドレス)があるが、そこにはポインタ変数のアドレスを渡せばよい。
・参考として↑にあるバブルソートには文字列がint型に入っているが、そこにはポインタのアドレスを渡せばよい。
C
1#include<stdio.h> 2#include<stdlib.h> 3 4int hantei(char *a, char *b); 5void sort(char **argv,int n); 6 7int main(void) 8{ 9 char *str; 10 char enter; 11 int i,n; 12 13 printf("複数の文字列配列を辞書順に並び替えるぞ\n"); 14 printf("文字列の個数入力して→"); 15 scanf("%d",&n); 16 17 enter=getchar(); 18 19 //str=(char *)malloc(sizeof(char)*n); //下記にて説明有り 20 for(i=0;i<n;i++){ 21 (str+i)=(char *)malloc(sizeof(char)*n); //「左辺値が必要」とエラーがでます 22 } 23 24 for(i=0;i<n;i++){ 25 printf("%dつ目の文字列を入力しよ> ",i+1); 26 scanf("%s",str+i); 27 } 28 29 sort(&str,n); 30 31 for(i=0;i<n;i++){ 32 printf("辞書順に文字列を出力します。\n"); 33 printf("%s\n",str+i); 34 } 35 36 return 0; 37} 38 39void sort(char **argv,int n) 40{ 41 int i,j,t; 42 43 if(n==1){ 44 printf("データ1個しかないですよ\n"); 45 } 46 else{ 47 for(i=n-1;i>=0;i--){ //「char *型はint型に変換できない」とエラーが出ます。 48 for(j=0;j<n;j++){ 49 if(hantei(*(argv+j),*(argv+j+1))==-1){ 50 t=*(argv+j); 51 *(argv+j)=*(argv+j+1); 52 *(argv+j+1)=t; 53 } 54 } 55 } 56 } 57} 58 59int hantei(char *a,char *b) 60{ 61 int i; 62 63 for(i=0;*(a+i)!='\0' && *(b+i)!='\0';i++){ 64 if(*(a+i)<*(b+i)){ 65 return 1; 66 } 67 else if(*(a+i)>*(b+i)){ 68 return -1; 69 } 70 } 71 if(*(a+i)!='\0'){ 72 return -1; 73 } 74 else if(*(b+i)!='\0'){ 75 return 1; 76 } 77 return 0; 78}
試したこと
まずポインタのポインタ(ダブルポインタ)のイメージがわかなかったため以下のようなコードを拾ってて、どのような動きをしているのか自分で図を描いて理解しました。(以下参照)
C
1#include<stdio.h> 2 3#define N 50 4 5int main(void) 6{ 7 //普通のポインタ 8 int t; 9 char *str1,*str2,*str3; 10 char fig[]="abcdefghijk"; 11 12 str1=fig; 13 printf("%c\n",*str1); //文字の出力 14 15 str2=fig; 16 for(t=0;*(str2+t)!='\0';t++){ 17 printf("%c",*(str2+t)); //文字列の出力 18 } 19 printf("\n"); 20 21 str3=fig; 22 printf("%s\n",fig); //文字列の出力 23 24 //ダブルポインタの理解1 25 char *figure1,**figure2; 26 char buf1[N]="あいうえお"; 27 char buf2[N]="かきくけこ"; 28 29 figure1=buf1; 30 figure2=&figure1; 31 *figure2=buf2; 32 33 printf("%s\n",figure1); 34 35 //ダブルポインタの理解2 36 char *month[3]={"January","February","March"}; 37 char **p1,**p2,**p3; 38 int i,j; 39 40 p1=month; 41 p2=month; 42 p3=month; 43 44 for(i=0;i<3;i++){ 45 printf("%s\n",*(p1+i)); 46 } 47 48 for(i=0;i<3;i++){ 49 printf("%s\n",*p2); 50 p2++; 51 } 52}
![
↑上のプログラム内の //ダブルポインタの理解1 の図解
他にも様々なサイトを見ましたが、よくわからず
・配列だと要素数を宣言しないといけないが、ポインタのポインタとmalloc関数を使えばメモリを余分に使うことなく処理できる。
ということくらいしかわかりませんでした。
また、普通のポインタについてはアドレスなど、動きが理解しやすいのですがポインタのポインタについてはどのような考えをしながらコードを追っていけばいいのかがわかりません。
未熟者ですがどうかご指導よろしくお願いします。
補足情報(FW/ツールのバージョンなど)
使用しているツールは、BCC Developerで、コンパイラはBorland C++ Compilerを使用しています。
回答3件
あなたの回答
tips
プレビュー
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2018/05/15 15:05 編集