ポインタを返す関数

関数は戻り値としてポインタを返すこともできます。例えばchar型へのポインタを返す関数funcは

char *func(引数,...);

のように宣言します。実用的なプログラムではポインタを返す関数がよく使われます。

では、strcat関数のように、文字列を結合して、戻り値として結合された文字列のポインタを返す関数をつくってみましょう。

ソースコード

源文件
  1|/* mystrcat01.c */                                                                    
  2|
  3|#include <stdio.h>
  4|#include <string.h>
  5|
  6|char *mystrcat(char *, char *);
  7|
  8|
  9|int main(void){
 10|  char str1[16] = "abc";
 11|  char *str2 = "def";
 12|  
 13|  printf( "%s\n", mystrcat(str1, str2) );
 14|
 15|  return 0;
 16|}
 17|
 18|char *mystrcat(char *a, char *b){
 19|  char *ptr;
 20|  int n=0;
 21|
 22|  ptr = a + strlen(a);
 23|
 24|  while( (*(ptr + n) = *(b + n)) != 0 ){
 25|    n++;                                                                              
 26|  }
 27|
 28|  return a;
 29|  
 30|}

実行結果

abcdef

strcat 関数と同様、文字列を追加できましたね。

mystrcat 関数では何をしているのでしょうか。ポインタ ptr は a より strlen(a) だけ進んだアドレスを指しています。つまり、文字列 a の最後の文字(ヌル文字)を指しています。while 文の継続条件式が偽となるまで n++ が実行されます。これが偽になるのは *(ptr + n)に '\0' が代入されたときです。継続条件式が偽になるまで n は1ずつ増えていきます。つまり、文字列 a の後ろに文字列 b を先頭から1文字ずつコピーしています。これが終了するのは、文字列 b のヌル文字がコピーされたときです。

ソースコード

源文件
  1|/* mystrcat02.c */                                                                    
  2|
  3|#include <stdio.h>
  4|
  5|char *mystrcat(char *a, char *b);
  6|
  7|int main(void)
  8|{
  9|  char str1[32] = "Hello, ";
 10|  char str2[16] = "World!\n";
 11|
 12|  printf(mystrcat(str1, str2));
 13|
 14|  return 0;
 15|}
 16|
 17|char *mystrcat(char *a, char *b)
 18|{
 19|  char *aorg;
 20|  aorg = a;
 21|  while(*a)
 22|    a++;
 23|  while(*a++ = *b++);
 24|
 25|  return aorg;                                                                        
 26|}
ワーニングがあります。

実行結果

Hello, World!

なぜこのようなことができるのかわからない人は、もう一度ポインタのろころを読み直してみて下さい。

Chapter10 @ C言語目録 @ HomeWork List @ 昭亮's Homepage