• ベストアンサー

引き数がポインタでない関数の戻り値はなぜint型なのか?

toysmithの回答

  • toysmith
  • ベストアンサー率37% (570/1525)
回答No.5

Cでは式の評価時に「char,shortはintへ」、「unsigned char,unsigned shortはunsignedへ」、「floatはdoubleへ」と暗黙の格上げが行われます。 よって、「関数値としてのcharやshort」は無意味です。 long, unsigned long, long doubleを返す関数は存在します。 EOFの取り扱いについては“そういう面もある”という程度です。

関連するQ&A

  • int型ポインタの加算

    void foo() {   int *ptrInt=0;   char *ptrChar=0;   ptrInt++;   ptrChar++; } Windows2000上で、上記を実行すると ptrIntは4になります。 ptrCharは1になります。 なぜでしょうか。 32ビットとはいえ、 ptrIntとptrCharはアドレスを示しますよね。 アドレスに1加算するのだから、 int型、char型に関係なく、 いずれも1になるべきだと思います。 int型のポインタの場合示すデータは4バイトなので、 ポインタ1加算は、4(バイト)加算になるということでしょうか。

  • fgetc()関数の動作について

    Visual Studio 2008(C++) において↓のようなコードを書いてビルドして、デバッグなしで実行すると、 コンソール上でちゃんとファイルの文字がコンソールに表示されます。 ところで、fgetc()関数のリファレンスを見ると、戻り値がint型を返すと書いてあるのに、 このコードだとchar型のバッファで受けています。char型でもfgetc() 関数の戻り値を受けられる理由がわかりません。 これはやはり、fgetc()がShift-JISコードの文字コード番号そのものを返しているのでしょうか。 (int型の配列で各要素にfgetc()の戻り値をみると、ファイル上の文字の文字コード番号が 入っています。) char型で受けると、文字そのものを受けられるのでしょうか? また、char型で受けた時に、char(1バイト)で、EOF(2バイト)をどうやって格納し、識別しているの でしょうか。 初歩的な質問で申し訳ありませんが、ご回答、よろしくお願いします。 #include <iostream> using namespace std; int main(){ FILE *fin = fopen("testa.txt", "r"); if(!fin){ "入力ファイルをオープンできません。"; return 1; } int i=0; char buf[20]; while((buf[i] = fgetc(fin))!=EOF){ i++; } buf[i]='\0'; cout << buf << endl; return 0; }

  • ポインタのポインタの関数渡し

    基本的ですみません。a[10][256]のような配列を関数に渡すためにはどうすれば良いでしょうか b(何を書けばよいでしょうか) { } int main() { char a[10][256]; ←これを渡して値を返したいです。 b(何を書けばよいでしょうか ); }

  • 関数の戻り値が複数ある場合

    C言語初心者です。 関数の戻り値を返す場合、return 変数名;と記述しますよね。 配列を返す場合、ポインタを使用しないで返すにはどうしたらいいですか? 例えば合計と平均を計算する関数があり その結果を配列に入れてmainに返すなど。 以前他の方の質問のコメントに 配列の要素が固定であれば、構造体にして返す方法もあります。 struct array { int x[10]; }; struct array func() {  struct array a;  ...  return a; } -- とあったのですが、構造体の要素が全てint型ならば 配列ではダメなのですか?

  • ポインタを使って構造体の配列を戻り値にするには

    関数の戻り値を構造体の配列(アドレスを受け渡しを利用して)にしたいのですがうまくゆきません。 以下のプログラムではコンパイルはできるのですが、 a0 = 2 a1 = 4198512 a2 = 4329332 と表示されてしまいa1,a2がうまくゆきません。 ********************************************* #include<stdio.h> struct test{ int a; }; struct test *func(void); void main(void) { struct test *data;//構造体ポインタ int i; data = func(); //ポインタにtest関数の戻り値(アドレス)を代入 for(i=0;i<=2;i++){   printf("a%d = %d\n",i,(data+i)->a); //構造体要素を表示 } } struct test *func(void) { struct test data[3]={1,2,3}; //構造体配列を定義 return (&data[0]); //構造体配列の先頭アドレスを返す } ************************************************* test関数から受ける取ったアドレス(&data[0])をポインタ(data)に代入して1づつずらして表示させれば a0=1,a1=2,a=3 となると思ったのですがどこが間違っているのでしょうか? よろしくお願いします。

  • 戻り値について

    プログラミング初心者です。 よろしくお願いします。 C++を使っています。 早速なのですが、以下にプログラムを記載します。 ◎1---------------------------------------- #include<stdio.h> main() { char ss[256]; gets(ss); puts(ss); } ---------------------------------------- ◎1を実行すると、「型指定子がありません - int と仮定しました。メモ: C++ は int を既定値としてサポートしていません」と表示されます。 参考書には、「戻り値のvoidがないと勝手に戻り値の関数をint型と解釈する。関数の宣言と定義が合わないとコンパイル時にエラーとなる」とあったのですが、 ◎2------------------------------------- #include<stdio.h> int main() { char ss[256]; gets(ss); puts(ss); } ------------------------------------- 以上の◎2だと、なぜ実行出来るかよくわかりません。 本当に初心者的な質問ですいませんが、教えていただけると嬉しいです。

  • recvfrom関数の戻り値がおかしいんですが…

    初めて投稿させていただきます。 現在、Cにてあるクライアントプログラムを作成している者です。 構成は以下の通り。 《構成》 サーバ:PLC(シーケンサと書けば大体の方はわかりますか?) クライアント:Linux Ubuntu9.10 通信方式:TCP/IP 《開発環境》 言語:C IDE:eclipse コンパイラ:gcc 4.x 《質問》 クライアントプログラムからASCIIデータをサーバへ送信し、サーバはクライアントから受信したASCIIデータに応答し、ASCIIデータ伝文を返信してきます。 このサーバからのASCIIデータ応答伝文をrecvfrom関数で受信し、応答伝文のASCIIデータを'buf'変数に格納し、標準出力関数で表示させるといったプログラムです。 このプログラムでは、ユーザ関数内でrecvfrom関数をコールしているのですが、ユーザ関数内でrecvfrom関数をコールした場合、受信データの先頭4byteしか受信できておらず、困っています。 ちなみに、main関数内でrecvfrom関数をコールすると、応答伝文全体のデータをきちんと受信できています。 ちなみに、サーバの応答ASCIIデータ伝文は、仕様通り(期待通り)のデータが返信されています。(ネットワークモニタ:wiresharkで確認済み) recvfrom関数をコールする場所によって、変数に格納するデータ量が変わるといったことがあるのでしょうか。 ソースの一部を添付します。 参照の上、アドバイス等いただけないでしょうか。 《ソース》 ◆mainソース #include ... :<-#include定義 int main{   :<-変数定義、変数初期値代入処理等 ユーザ関数1()コール<-ユーザ関数1内でソケット通信処理を動作させている。 ユーザ関数2()コール<-同上 } ◆ユーザ関数用ソース #include...   :<-#include定義 unsigned char ユーザ関数名1;<-ユーザ関数プロトタイプ宣言 unsigned char ユーザ関数名2:<-同上 char 変数1[5]; char s_buf[4096]; char buf[4096]; /*データ受信用バッファ*/ char 変数2[256]; size_t len; long l; int sock_fd; /*ソケット用ファイル記述子*/ struct sockaddr_in cl_addr; /*CPU用ソケットアドレス*/ socklen_t cl_len = 0; /*cl_addrのサイズ格納用*/ ssize_t n = 0; unsigned char ユーザ関数1(char *引数1,…char *引数5){   :送信データ生成処理 //* ソケット作成 *// if ((sock_fd = socket(PF_INET, SOCK_STREAM, 0)) < 0) { perror("socket"); return 1;   } //* 接続先定義*// memset(&cl_addr, 0, sizeof cl_addr); cl_addr.sin_family  = AF_INET; /*プロトコル定義*/ cl_addr.sin_addr.s_addr = inet_addr("***.***.***.***"); /*IPアドレス定義*/ cl_addr.sin_port  = htons(****); /*Port定義*/ //* 接続 *// if (connect(sock_fd, (struct sockaddr *)&cl_addr, sizeof cl_addr) < 0) { perror("connect"); return 1;   } //* データ送信 *// if(send(sock_fd, s_buf, strlen(s_buf), 0) < 0){ fprintf(stderr, "could not send message : %s\n", s_buf); exit(EXIT_FAILURE); } printf("\nSendMessage\n%s\n",s_buf); //* データ受信 *// cl_len = sizeof cl_addr; //*↓↓このrecvfrom関数でbuf内にサーバ応答伝文の先頭4byteのみが格納されている。↓↓*// if (( n = recvfrom(sock_fd, buf, sizeof buf,0, (struct sockaddr *)&cl_addr, &cl_len)) < 0) { perror("recvfrom"); return 1; } fprintf(stderr ,"TCP from addr = %s, port = %d\n", inet_ntoa(cl_addr.sin_addr), ntohs(cl_addr.sin_port) );

  • 関数の戻り値なんですが...

    VC++を使用し以下のような関数additionで文字列を返したいのですが アドレスしか返しません。配列はその先頭のポインタだということは しっているのですが.... additionは、二つの文字列(32や47などの数字のやつ)を引数とし、そ れを整数型に変換し、その加算を行い、その結果を文字列型に変換し 、その文字列をかえす関数です。 関数の定義などが間違っているのですか?? #include<iostream.h> #include<string.h> #include<string> char *addition(char *,char *); void main(){ using namespace std; char a[] = "1000"; char b[] = "456"; cout << addition(a,b) << '\n'; } char *addition(char *a,char *b){ int c = 0; c = atoi(a)+atoi(b); char p[20]; _itoa(c,p,10); cout << p <<'\n'; return (*p); }

  • ポインタの引数について。

    C言語初心者です。 既存のプログラムを直そうとしているのですが、ポインタの概念がいまいち理解できていないのか、修正した箇所がうまく動きません。 どうすればよいかをご教示いただけませんでしょうか。 元のプログラムは void sub() { SOCKET s; struct msg r_msg; int time; int cc; cc = sub_recv(s, &r_msg, time); ・・・ } void sub_recv(s,*msg,time) { unsigned char *pack; int cc; int len; pack = (unsigend char *)msg cc = recv(s, (char *)pack, len, 0); if(cc < 0) return(cc); ・・・ } という感じでr_msg構造体にrecvで受け取ったものを入れて行きます。 ccにはrecv()の戻り値でサイズが返ってきて直後のifにはひっかかりません。 構造体の中でサイズが固定されているため、可変にするために以下のようにしたいです。 extern int buflen; void sub() { SOCKET s; unsigned char *r_msg; int time; int cc; r_msg=(char *)malloc(sizeof(char)*buflen ); cc = sub_recv(s, r_msg, time); free(r_msg); ・・・ } void sub_recv(s,*msg,time) { unsigned char *pack; int cc; int len; pack = (unsigend char *)msg /*ここの代入は無意味と思いますがなくしても同様の結果のなので残してます。*/ cc = recv(s, (char *)pack, len, 0); if(cc < 0) return(cc); ・・・ } しかし、このような修正で*r_msgにはrecv()で受け取った内容が入る気がするのですが、 ccには-1が入ってしまい、ifに引っかかって終了してしまいます。 この時のerrnoを見ても104が入り、connection reset by peerといった感じです。 recv()の第二引数にはこれがバッファが用意されてればいいと解釈しておりますが、 これではバッファが1バイトしかとれていないなどあるのでしょうか。 因に、send()がないからというのはありません。 キャストが間違えているなどもあるかもしれませんが、宜しくお願いします。

  • 2次元配列とポインタの引数受け渡しについて

    2次元配列を関数に渡すときは、引数に渡す2次元配列と同じサイズを指定、もしくは2次元目のサイズのみ合わせて渡す方法がありますが、両方とも違うサイズで同じ関数を使いたいです。 最初は中身が同じで引数で受け取る2次元配列のサイズだけ、それぞれに合わせた引数を持つ関数を2つ作っていたのですが、なんだか冗長な気がしました。 そこで、2次元配列の先頭ポインタとサイズを受け取るようにすればいいのかと思い、テストとして次のプログラムを作成してみました。 #include <stdio.h> void func(unsigned char *a, int y, int x); int main(void) { unsigned char a[10][10]; func(a, 10, 10); printf("%d\n", a[7][4]); return 0; } void func(unsigned char *a, int y, int x) { int i, j; for (i = 0; i < y; i++) { for (j = 0; j < x; j++) { *(a + i*y + j) = i * j; } } } もちろんこれでも動くのですが、やはりこういう書き方はルールにはないので、コンパイルで警告が出ます。 a.c: In function ‘main’: a.c:10: warning: passing argument 1 of ‘func’ from incompatible pointer type a.c:4: note: expected ‘unsigned char *’ but argument is of type ‘unsigned char (*)[10]’ このような書き方はやはりやめたいいのでしょうか。 また、その際はサイズ別に関数を作るしかないのでしょうか。 他にいい方法があれば教えていただけると助かります。