C言語を学ぶなら新版 明解C言語 入門編がおすすめ!

このQ&Aのポイント
  • C言語の学習には新版 明解C言語 入門編がおすすめです。自主的に学習する際に役立ちます。
  • 演習問題11-1では、添字演算子なしで入力文字列を出力するプログラムを作成します。
  • (1)const指定されている変数のインクリメントで値が変わらない理由について、(2)main関数でない関数で全ての*を外すとエラーが出る理由について疑問があります。
回答を見る
  • ベストアンサー

C言語について質問です

新版 明解C言語 入門編 この本でC言語を勉強しています。 授業とかではなく自主的にやっています。 入力した文字を出力するプログラムを添字演算子なしで作る問題(演習11-1)を解いてみました。 void put_string(const char *s) { while(*s) putchar(*s++); } int main (void) { char s1[128]; printf("type something: "); scanf("%s", s1); put_string(s1); return(0); } これについて二つの疑問があります。 (1)constと指定されているのにインクリメントされていたら値が変わってエラーが出ないのはなぜか (2)main関数でないほうの関数で*を全て外すと 「パラメータ 's' は const signed char 型として定義されているので signed char * は渡せない(関数 main )」といったエラーが出るのですがなぜか

  • guhan
  • お礼率88% (15/17)

質問者が選んだベストアンサー

  • ベストアンサー
  • honor
  • ベストアンサー率35% (25/71)
回答No.3

(1) 定数なのは*sです。 *s++は優先順位の関係で*(s++)と解釈され、sは定数ではないのでエラーになりません。 (2) put_string(s1); このs1はchar*型です。要はポインタです。 宣言がchar型なら渡せません。

guhan
質問者

お礼

丁寧にありがとうございます。 どちらの疑問も理解できました。

その他の回答 (2)

  • TT414
  • ベストアンサー率18% (72/384)
回答No.2

>void put_string(const char *s) のconstは文字列がput_stringによって壊されないということを示しています。ポインタを変更しないという意味ではありません。 Cのライブラリには「char*strcpy(char*dst,const char*src);」というものがありますが、src側の文字型の配列は変更しない、dst側は変更するかもしれないと宣言しています。 >main関数でないほうの関数で*を全て外すと char型になるからです。*が付いているときはcharのポインタ型です。

guhan
質問者

お礼

ありがとうございます

  • Tacosan
  • ベストアンサー率23% (3656/15482)
回答No.1

演習までの部分をきちんと理解していれば (1) のような疑問は出てこないはずです. 実際にこのような使い方をしている関数が出ていますよ. (2) は単に「そのような変換が (デフォルトでは) できない」から.

関連するQ&A

  • C言語 ポインタ エラー

    文字列を入力後改行して入力した文字列を出力したいのですが、エラーがでます。 ハンドルされない例外が 0xFEFEFEFE (helloworld.exe) で発生しました: 0xC00001A5: 無効な例外ハンドラー ルーチンが検出されました。 (パラメーター: 0x00000003)。 調べてみましたが、理解できません 何卒よろしくお願いします。 #include <stdio.h> void put_string(const char *str) { while (*str) putchar(*str++); } int main(void) { char str[100]; printf("文字列を入力してください"); scanf_s("%s", str); put_string(str); putchar('\n'); return(0); }

  • c言語

    (c++ではなくC89準拠) c言語について質問 (1) 関数名()と関数名(void)は違う意味 (2) mainの引数の型は(void)か(int argc, char *argv[]) (3) K&Rは標準c準拠でmain()という表記があります ということは、(1)の関数名とはmain以外の関数名で、 main()とmain(void)は同じなんでしょうか。

  • C言語のint型の配列が分かりません

    #include<stdio.h> int main(void) { int str[ ]={0,1,2} printf("%s\n", str); return 0; } というプログラムをC言語でつくってみましたが動きません.(012と表示されて欲しかったのですが) int str[ ]={1,2,3}の部分をchar str[ ]={'0','1','2'}とすれば動きます. そこで質問なのですが, printf("~%s~", (配列名));  はchar型の配列にしか適応できないのですか? ※追記 puts関数の定義は int puts (const char *str); であるそうなので char型の仮引数にはchar型のアドレスを渡さなければいけません. ではprintf関数の定義は一体どんなものなのですか?

  • C言語

    文字列を逆順にするプログラムを考えているのですが分かりません。(例)qwerならrewqです。入力終了は、EOFです。考えたのですが、分かりません。(コンパイルエラーです。)教えてください。宜しくお願いします。#include <stdio.h> unsigned str_length(const char str[]) { unsigned len=0; while (str[len]) len++; return (len); } void put_rstring(const char str[]) { unsigned i = str_length(str): while (i-- >0) putchar(str[i]); } int main(void) { char str[30]; int ch; printf("文字列を入力\n"); /* ----この文字列を入力したあとに、Ctrl+Zを押すと、逆から表示               で反対から、文字列が表示----*/ while (1) { ch=getchar(); if (ch==EOF) break; } printf("逆から表示"); put_rstring(str); puts("です。"); return(0); }

  • C言語のプログラミングでつまずいてます

    ポインタをりようする。string.hとctype.hに含まれる関数は使用しないこと。 以下の実行例のように、文字列を受け取り、アルファベットの大文字を小文字にして表示する関数を作成したいのですが 実行例: Original string is <AbCdE1f2> Modified string is <abcde1f2> #include <stdio.h> #define NUMOFCHAR 10 void print_char(char *ptr); int main(void) { char string[NUMOFCHAR+1]; printf("Input a sentence (# of letters <= %d): ", NUMOFCHAR); fflush(stdout); scanf("%s", string); string[NUMOFCHAR] = '\0'; printf("Original string is <%s>\n", string); printf("Modified string is <"); print_char(string); printf(">\n"); return 0; } void print_char(char *ptr) { int i=0; for(i=0 ; i<NUMOFCHAR+1 ; i++){ if( *ptr>='A' && *ptr<='Z'){ *ptr += 'A'-'a' ; } ptr++ ; } printf("%s",ptr); } よ書いたのですがビルドえらーがおこります。 どこがだめなのかわかりません。。。 C言語に詳しい人でわかるかた、どこがいけないのか、なぜいけないのか、どうすればいいのか詳しくおしえてください。 お願いします

  • c言語関数の(1)~(5)までの部分が何をやっているのかよく分からない

    c言語関数の(1)~(5)までの部分が何をやっているのかよく分からないので、どなたか解説をお願いします。 int memcmp(const void *s1, const void *s2, size_t n) { const unsigned char *p1 = (const unsigned char *)s1; const unsigned char *p2 = (const unsigned char *)s2; while (n-- > 0) { if (*p1 != *p2) return (*p1 - *p2); p1++; p2++; } return (0); } return (*p1 - *p2); > (1) ---------------------------------------------------------------------- char *strcat(char *s1, const char *s2) { char *p = s1; while (*s1) s1++; /* s1を末尾まで進める */ while (*s1++ = *s2++) ; /* '\0'が見つかるまでs2をコピー */ return (p); } while (*s1++ = *s2++) ; > (2) ---------------------------------------------------------------------- char *strstr(const char *s1, const char *s2) { const char *p1 = s1; const char *p2 = s2; while (*p1 && *p2) { if (*p1 == *p2) { p1++; p2++; } else { p1 -= p2 - s2 - 1; p2 = s2; } } return (*p2 ? NULL : (char *)(p1 - (p2 - s2))); } while (*p1 && *p2) > (3) p1 -= p2 - s2 - 1; > (4) ---------------------------------------------------------------------- char *strcpy(char *s1, const char *s2) { char *p = s1; while (*s1++ = *s2++) ; return (p); } while (*s1++ = *s2++)   > (5) ;          > (5) ----------------------------------------------------------------------

  • 要素数を100個にしろといわれたのですが

    要素数を100個にしろといわれたのですが int main(void){ char str="100"; printf("文字列を入力してください:"); scanf_s("%s",str); put_string(str); putchar('n'); return (0); } この『char str="100";』の部分を『char str[100];』にしたらいいんでしょうか? 教科書をみてやってみたのですがイマイチ理解できずお手上げ状態です 因みにC++です

  • 文字列strの中から文字cを探すプログラム(C言語)がわからない

    文字列strの中から文字cを探すプログラム(C言語)がわからない 柴田望洋さんの「[新版]明解C言語」という本の演習11-2なんですがどうしてもわかりません。間違いは無いと思うのにコンパイルすると警告を吐かれます。 僕が書いたプログラムを載せます。 /* 文字列strの中に、文字cが含まれていれば(複数ある場合は、最も先頭側とする)、 その文字へのポインタを返し、含まれていなければNULLを返す関数 char *str_chr(const char *str, int c) {} を作成せよ。 */ #include<stdio.h> char *str_chr(const char *str, int c){ while(*str){ if(*str==c) return str; str++; }     return NULL; } int main(){ char *str; char c; scanf("%s",str); scanf(" %c",c);     printf("%d",str_chr(str,c)); return 0; } コンパイラは「関数str_chrのif分の中のreturn strの型変換に問題がある」と言っているんです。 型変換はしるつもりは無いのにコンパイラはなぜそのように認識するのでしょうか。 またネット答えを探しましたがどうやらこのreturn strの部分はreturn (char*)strが正解のようです。意味がわかりません。strはポインタなのになぜまたわざわざchar型に変換しているのですか?といか(char*)の意味が根本的にわかりません。 質問ばかりですみません。初心者でポインタがどうにも理解できないんです。 誰か詳しい人教えてください。 お願いします。

  • C言語のソートについて

    C言語で下記のファイルの中身を昇順と降順で出力しようとしているのですが、ソートが上手くいっていない状況です。 どなたか修正点を教えて頂けないでしょうか? 「ファイルの中身」 2022/11/14 16:19:56 4+4,8.000000 2022/11/14 16:20:14 7+7,14.000000 2022/11/14 16:20:18 8+8,16.000000 2022/11/15 16:19:56 4+4,8.000000 2022/11/14 16:20:14 7+7,14.000000 2022/11/18 16:20:18 8+8,16.000000 2022/11/17 16:19:56 4+4,8.000000 2022/11/14 16:20:14 7+7,14.000000 2022/11/14 16:20:18 8+8,16.000000 「ソースコード」 #include <stdio.h> #include <string.h> #include <stdlib.h> int cmp_u(const void* a, const void* d) { return *(char*)a - *(char*)d; } int cmp_d(const void* a, const void* d) { return *(char*)d - *(char*)a; } int main() { int r,i,n; FILE* fp; char sin[9][1000]; fp = fopen("log.txt", "r"); if (fp == NULL) { printf("ファイルオープン失敗\n"); return -1; } for (i = 0; i < 9; i++) { fscanf(fp, "%s", &(sin[i])); } fclose(fp); printf("ASC or DESC: "); scanf(" %s", &ad); if (strcmp(ad, "ASC") == 0) { qsort(sin, 9, sizeof(char), cmp_u); } else { qsort(sin, 9, sizeof(char), cmp_d); } for (i = 0; i < 9; i++) { printf("%s\n", sin[i]); } return 0; }

  • 関数ポインタについて

    C言語によるUNIXシステムにプログラミング入門という本を読みながらC言語を勉強しています。 しかし、サンプルとして提示された下記の内容の意味がわかりません。 分からない箇所が「関数ポインタ」と呼ばれるものがついているということが分かった程度で、どういう意図で記述されているのかがわかりません。 分からないプログラムの処理内容は、ファイル内のデータを16進数で表示するというものです。 分からない箇所を記します。 #include <stdio.h> #define BUFF 17 /*buffer*/ #define ERR -1 /*system call error*/ void usage(void); /*put usage message*/ char *command_name /*command name*/ FILE *fpin; /*file pointer*/ main(int argc,char *argv[ ]){ char *rindex(const char*s,int c); /*末尾から文字列検索*/ void hexdump(void); ... ... } void hexdump(void){ ... ... } void usage(){ ... ... } 不明なのは、main関数の中の char *rindex(const char*s,int c); /*末尾から文字列検索*/ void hexdump(void); です。 Cについて、不明なところが多いので、利用する関数は使う前に宣言しなければいけない程度の理解ですが、そうだとしてもusageメソッドはmain関数の外であるのに、rindexとhexdumpは何故main関数の中で宣言されているのでしょうか。 上記の不明点とは別で、rindexの前にポインタが付いていると思うのですが、hexdumpやusageにはついていません。 知人からは、関数までのポインタを返すとのことでしたが、用途もいまいち理解できません。 全てではなくてもいいので、ヒントをいただけるとうれしいです。 よろしくお願いします。

専門家に質問してみよう