- ベストアンサー
ポインタ
tanteiqの回答
- tanteiq
- ベストアンサー率20% (1/5)
ANo.1さんのようにポインタは難しい!って印章を植え付ける人がやたら多いですがメモリとアドレスを意識すればそんなに難しくありません char str[]; char* str; これだけなら意味は同じです、と言っても char str[] は引数でしか使えませんが char str[] = "ABC"; char* str = "ABC"; これは明確に違います、上の方はstr配列に'A''B''C'という値が入ります これはstr配列と言うメモリに入っているので変更ができます str[0] = 'D'; //DBC 下の方は文字リテラルと言う静的文字列のアドレスが入ります ですので変更ができません str[0] = 'D'; //コンパイルエラー
関連するQ&A
- C言語のポインタと配列について
下のコードについて2つ質問があります。 (1) char *p; p = str; ならわかるのですが、なぜ型が違う char *p = str; のような代入がOKなのでしょうか。文字列をコピーするときの *p = *str; と比較して、とても違和感があります。 str は引数で受けた文字列の先頭アドレス。 (2) char *str; str = " 1 23 4 5"; と char str[] = " 1 23 4 5"; との違いがよくわかりません。 #include <stdio.h> #include <ctype.h> void TrimSpace(char *str) { char *p = str; // (1)型が違うのになぜこんな代入をするのか? while (*str != '\0') { if ( !isspace(*str) ) { *p = *str; // この代入は自然 p++; } str++; } *p = '\0'; } int main(void) { //char *str; //str = " 1 23 4 5"; (2)これでは空白を詰めた後の文字列が表示されないのはなぜか? char str[] = " 1 23 4 5"; //これで OK printf("空白を詰める前:\"%s\"\n", str); TrimSpace(str); printf("空白を詰めた後:\"%s\"\n", str); return 0; }
- ベストアンサー
- C・C++・C#
- ポインタで分からないことがあります。
つい最近C言語の勉強を始め、現在ポインタの勉強をしています。 過去の質問を検索したり、サイトを見てみましたが、一人の力では解決できませんでしたので質問させていただきます。 ポインタのプログラムで、下記のプログラムについて分からないことがありました。 ――――――――――――――――――――――――――――――――― #include <stdio.h> int main (void) { char *str = "abc"; printf ("%s %d %d\n", str, &str, &(*str)); str = "日本語"; printf ("%s %d %d\n", str, &str, &(*str)); return 0; } ――――――――――――――――――――――――――――――――― このプログラムで、「char *str = "abc";」の部分でstrには abcのアドレスが入っていると思っていたのですが、 1度目の「printf ("%s %d %d\n", str, &str, &(*str));」で、 結果が「abc 1245064 4235560」となっているのを見ると 私の見解は間違っている気がします。 「char *str = "abc";」の部分では一体なにが行われているのでしょうか? また、このプログラムをコンパイルして実行した結果が、 abc 1245064 4235560 日本語 1245064 4235574 となったのですが、なぜstrのアドレスは同じなのに、 &(*str)のアドレスは異なるのでしょうか? 質問をまとめますと、以下の2つです。 1.「char *str = "abc";」の部分では一体なにが行われているのでしょうか? 2.「abc」と「日本語」のstrのアドレスは同じなのに、&(*str)のアドレスは異なるのでしょうか? 初心者ですので言葉の足らない部分があるかもしれませんが、ご教授のほどよろしくおねがいします。
- ベストアンサー
- C・C++・C#
- ポインタ
質問なのですが、このソースのchar *str_copy(char *d, const char *s)関数内のchar *p=d;はなんで、*pにdを入れるか分かりません。それと、このdは、*dなのですか?どうして、while (*d++ = *s++) みたいに*dをつけないんですか?教えてください。宜しくお願いします。 #include <stdio.h> char *str_copy(char *d, const char *s) { char *p=d; while (*d++ = *s++) ; return (p); } int main(void) { char tmp[100]; char st1[100], st2[100],st3[100]; printf("文字列を入力してください:"); scanf("%s",tmp); str_copy(st1,str_copy(st2,tmp)); printf("文字列st1は%sです。\n", st1); printf("文字列st2は%sです。\n", st2); printf("文字列st3は%sです。\n", str_copy(st3,tmp)); return (0); }
- 締切済み
- C・C++・C#
- ポインタについて
下記<コード1>ではエラーが出ないのに、 <コード2>のように変更すると、 ”error C2105: '++' には左辺値が必要です。” とエラーが出ます。 どうしてなのか教えて下さい。 <コード1> char *str_copy(char *d , const char *s){ char *t=s2; while(*d++=*s++) ; return (t); } int main(void) { char s1[128]="ABCD"; char s2[128]="EFGH"; str_copy(s2,s1); <コード2> int main(void) { char s1[128]="ABCD"; char s2[128]="EFGH"; // str_copy(s2,s1); while(*s2++=*s1++) ;
- ベストアンサー
- C・C++・C#
- ポインタ
#include "stdafx.h" #include <ctype.h> #include <string.h> #include <stdlib.h> typedef struct { char number[6]; char class_type[20]; char name[8]; char subject[5]; } my; my data[100]; int main(int argc, char* argv[]) { FILE *fp; int field = 0, line = 0; char buf[1000], *str; char bufG[1111]; int i; if((fp=fopen("test.txt","r"))==NULL){ printf("ファイルが開けません"); } while(fgets(buf,1000,fp) !=NULL){ str=buf; while(*str != '\0'){ if(*str != ','){ for(i = 0; *str != ',' && *str != '\0' ; i++){ if(*str == '\n'){ } else{ bufG[i] = *str; } str++; } bufG[i] = '\0'; // printf("%s", bufG); switch(field){ case 0: strcpy(data[line].number, bufG); break; case 1: strcpy(data[line].class_type, bufG); break; case 2: strcpy(data[line].name, bufG); break; case 3: strcpy(data[line].subject, bufG); break; } field++; } else{ str++; } } line++; field = 0; } printf("%s", data[2].subject); fclose(fp); return 0; } このプログラムをベースにしてメモリの無駄を省けるような プログラムに修正したいのですが、 ポインタほんとできなくて困ってます。 教えていただいてメモリを取る位置とかは大体わかりました。 まず構造体のメモリをとります。しかしこのままでは固定長になってるので 構造体を少しいじくりますよね。 構造体の中身なのですが typedef struct{ int number; char *class_type; char *name; char *subject; } my; my *data; にして data = malloc(100); このような形でとります。 文字列の型ですがchar *class_typeのようにポインタで宣言しないと bufGを代入して値を入れるときに型が合いませんので 配列にしないのであればポインタ型宣言でいいと思います。 しかしポインタで宣言してstrcpy(・・)の所を data[line].class_type = bufG にするとエラーはでませんが*strの値が変わる度に data[line].class_typeの値が変動するのでdata[line].class_typeが 国語 とかになったりします。 なんかもうさっぱりわからないんですが どうすればいいのでしょうか? 変換したソースがほしいです。
- ベストアンサー
- C・C++・C#
- C言語 ポインタと配列
#include <stdio.h> /* scanf("%c", &search); ではなく scanf(" %c", &search); であることに注意する */ char *str_chr(const char *str, char c) { char *find; find = NULL; do { if(*str == c) { find = (char*)str; break; } } while(*str++); return(find); } int main(void) { char str[100] = {0}; char search; char *find; printf("文字列を入力してください:"); scanf("%s", str); printf("検索する文字を入力してください:"); scanf(" %c", &search); find = str_chr(str, search); if(find == NULL) { puts("検索した文字は見つかりませんでした。"); } else { printf("検索した文字 %c は\"%p\"にあります。\n", *find , find); } return(0); } このコードのfind = (char*)str;の (char*)str;の部分がどうなっているのかわかりません。 あとこのfindというのは&find[0]という解釈でいいでしょうか? 教えてくださいm(_ _ )m
- ベストアンサー
- C・C++・C#
- C言語のポインタにの動作について
以下のコードで、DelHalfSpc() において引数 str は str++ でカウントされ、ループを抜けた時点では文字列の末尾を指しているはずですが、なぜ呼び出し側の main()の char str[] には正しい値が入るのでしょうか? char *DelHalfSpc(char *str) { //char *dmy = str; → char * という型の変数 dmy の宣言 char *dmy, *Res; Res = dmy = str; // Res は常に先頭アドレスを指す while (*str != '\0') { if ( *str != ' ' ) { *dmy = *str; dmy++; } str++; } //ループを抜けたこの時点で str は文字列の末尾を指しているはず *dmy = '\0'; return Res; //ここを return str とするとヌル文字列を返す } int main(void) { char str[] = " 1 23 4 5"; printf("空白削除前:\"%s\"\n", str); printf("空白削除後:\"%s\"\n", DelHalfSpc(str)); printf("str も変化:\"%s\"\n", str); //なぜ正しい結果が表示されるのか? return 0; } 【結果】 ----------------------- 空白削除前:" 1 23 4 5" 空白削除後:"12345" str も変化:"12345"
- ベストアンサー
- C・C++・C#