「char* p」と「char *p」の違いを教えてください。

このQ&Aに関連する最新のQ&A

A 回答 (3件)

同じ意味です。


ただ、
char* p, q;
と書いた場合、一見char*型のpとqを定義しているように見えるかもしれません。
しかし、実際はchar*型のpとchar型のqを定義しています。
意図とは違うことが起きるかもしれません。

したがって、私は、型名の最後ではなく変数名の頭に*を付ける
書き方を採用しています。
    • good
    • 0
この回答へのお礼

ご回答ありがとうございます
>char* p, q;
>と書いた場合、一見char*型のpとqを定義しているように見えるかもしれません。
>しかし、実際はchar*型のpとchar型のqを定義しています。
参考になりました

お礼日時:2008/02/09 20:50

違いはありません。


コンパイラはどちらも同じ意味として理解します。

GNU Cでのケースになりますがコンパイルしたオブジェクトファイルを逆アセンブルすると「int* p」と「int *p」は同じ内容が出力されます。
従って違いはないと判断できます。
    • good
    • 0
この回答へのお礼

ご回答ありがとうございます

お礼日時:2008/02/09 20:49

意味は同じです。

でも、見た目が違うので、プログラマの信ずるところでどちらかに決めるようです。たぶん書き方は混ぜないほうがいいと思えます。
    • good
    • 0
この回答へのお礼

ご回答ありがとうございます

お礼日時:2008/02/09 20:48

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!

このQ&Aと関連する良く見られている質問

Qp = (char **)*p の意味

C言語を勉強中です。
ネットで以下のような記述の資料がありました。
どういうことなのかわかりません。
ポインタについて理解しているつもりでいましたが、理解してなかったということのでしょうか。。。
なお、pがポインタとして宣言されているか、値として宣言されているかどうかについては記述がありませんでした。
これだけを見て、理解できる方がいれば、教えてもらえると助かります。

------------------------------------------------------------------------------
レイテンシの算出方法は、以下に示すアドレス更新処理を多数回実行することで行っている。
p = (char **)*p
レイテンシ時間=測定時間 / 実行回数 により算出される。
-------------------------------------------------------------------------------

Aベストアンサー

これ、ベンチマークテストかなんかのですかね?
・pに(char **)でキャストした内容を代入しているので、 char **pと予測される
・↑だとすると *P はchar *型になる。

・*pでpのアドレスからポインタ1つ分のデータ読み出す。
・↑はchar*型なので、char **にキャストしてpに代入する。→pが別のアドレスを示すようになる
・その「別のアドレス」からポインタ1つ分のデータ読み出す
...
とpの内容をメモリから「読み出して代入」を繰り返すもののようです。

Qchar *str; と char* str;

char *str; と char* str;
どっちも同じことを意味しているんですか?

Aベストアンサー

同じことを指している、というのは、先の回答の通りです。

また、ひとつの宣言で変数を複数宣言したときに、char* str という表記は間違い
易いじゃないか、ということが言われているのも事実です。実際、いろいろな C のソースを
見ていても、まずアスタリスクを型につけて書くのは、まずお目にかかれません。

ただ C++ では、char* str という宣言も良く使われています。

C++ に限らずオブジェクト指向の言語は、強く型を意識するので、「文字のポインタ型」と
いう意味で、まとめて書く方が馴染むのでしょう。ちなみにそういう風な人たちは

char *str1, *str2;

とは、書けない体になっています。

char* str1;
char* str2;


変数の宣言だと、C に慣れていれば、char* str というのはちょっと違和感があるのは
私も分かりますが、関数のプロトタイプ宣言だと、どちらの方がすっきりしますか?

extern char *memcpy(char *, const char *);

extern char* memcpy(char*, const char*);


# まあ、どっちが正しい、っていうんじゃ無いんですよね

同じことを指している、というのは、先の回答の通りです。

また、ひとつの宣言で変数を複数宣言したときに、char* str という表記は間違い
易いじゃないか、ということが言われているのも事実です。実際、いろいろな C のソースを
見ていても、まずアスタリスクを型につけて書くのは、まずお目にかかれません。

ただ C++ では、char* str という宣言も良く使われています。

C++ に限らずオブジェクト指向の言語は、強く型を意識するので、「文字のポインタ型」と
いう意味で、まとめて書く方が馴染む...続きを読む

Qchar *name1[4] とchar name2[][4] の違いについて

C言語のことで質問があります。

char *name1[4]は
char *name1[4] = {"abcdefghi","jkl","l","mn"};
と宣言でき,ポインタを4つ確保した形となりました。

char name2[][4]は
char name2[][4] = {"abc","def","ghi","jkl","mno","pqr","stu","vwx"};
と4文字以内の文字列を初期化した数だけ確保した形となりました。

この結果からchar *name1[4]の意味は,char name2[][4]ではなくchar name2[4][]に近いと思いました。
しかし,char name2[4][]ではポインタを4つ確保した事にはならないみたいでコンパイルが通りません。
*name1[4]では4つのポインタを確保できるのに~と思ってしまいます。

ポインタと配列は別物と考えるべきなのでしょうか?
訳の分からない質問かもしれませんが,
何卒ご指導いただくようよろしくお願いします。

Aベストアンサー

ポインタと配列の違いというのは、変数と定数の違いのようなものです。

話を簡単にするために、一次元配列から考えましょう。

char *p1; と定義した時のp1は、いうまでもなくポインタで、
これは変数です。p1は任意の文字列を指すことができます。
char a1[4]; と配列の形で定義した場合のa1については、
a1[0]やa1[1]等を、通常のchar型の変数と全く同じように扱うことが
できます。しかし、a1自体は、例えば a1 = p1; のように値を代入する
ことができません。(逆の p1 = a1; は可能。)つまり、この場合のa1は、
変数ではなく、定数のようなものなのです。

複合的なケースについて見てみましょう。
char **q1; ポインタへのポインタ
 q1,*q1,**q1,q1[0],*q1[0],q1[0][0] のいずれも変数として
 扱うことができます。(値を代入することが文法的に許されます。
 ただし、実行時にはアクセス違反になる場合もあります。)
char q2[4][4]; 二次元配列
 q2,q2[0]は変数として扱うことができません。q2[0][0]のように
 して、初めて変数として扱えるようになります。
char *q3[4]; ポインタの配列
 q3は変数として扱うことができませんが、q3[0],*q3[0],q3[0][0]
 はいずれも変数として扱うことができます。
 なお、この定義は char *(q3[4]); とした場合と全く同じ意味です。
char (*q4)[4]; 配列へのポインタ
 q4,(*q4)[0],q4[0][0]はいずれも変数として扱うことができます。
 しかし、*q4,q4[0]は変数として扱うことができません。

char *name1[4]; と char name2[4][]; は確かに似ています。しかし
違うところもあります。それは、name1[0] が変数として扱えるのに
対し、name2[0] には値を代入できないという点です。(データの
具体的な構造については、inthefloiさんが書いておられる通りです。
> char name2[4][]ではポインタを4つ確保した事にはならないみたい
というのも、全くその通りで、配列の定義では、ポインタ変数の領域
を確保する余地はないのです。

ポインタと配列の違いというのは、変数と定数の違いのようなものです。

話を簡単にするために、一次元配列から考えましょう。

char *p1; と定義した時のp1は、いうまでもなくポインタで、
これは変数です。p1は任意の文字列を指すことができます。
char a1[4]; と配列の形で定義した場合のa1については、
a1[0]やa1[1]等を、通常のchar型の変数と全く同じように扱うことが
できます。しかし、a1自体は、例えば a1 = p1; のように値を代入する
ことができません。(逆の p1 = a1; は可能。)つまり...続きを読む

Qfor(s=p; *p; p++)の*p(ポインタ)の意味

for(s=p; *p; p++)の*p(ポインタ)の意味
C言語初心者です。
今ポインタを勉強しているのですが、
for文で上記のようなものが出てきて、意味が分からず困っています。
*pで*p != NULL と同じような意味になるみたいなのですが…。
どうしてそのような意味になるのでしょうか?

ちなみにsとpはポインタで、
sには配列(入力した文字列)の先頭アドレスが入っています。
pは文字列を指していて○○○○○NULL ←になるから上記のような条件で
回るんだろうなぁとはなんとなく考えているのですが。

Aベストアンサー

念のため:
ヌルポインタは「ビットパターンとして」0 じゃないかもしれませんが, ソースプログラムにおいて「ポインタが要求される場面」で「0」とあれば, それは「ヌルポインタ」です.
もうちょっと厳密に書くと「整定数 0」はヌルポインタに変換される.

Qchar[]とchar*

#include<iostream.h>
main()
{
char str1[] = "AB";
char *str2 = "ab";
*(str1+1) = 'C';
*(str2+1) = 'c';
printf("%s\n", str1);
printf("%s\n", str2);
}
このソースの
*(str2+1) = 'c';
の所はC++では間違った処理ですか?
[]かnewなどの変数なら書き換えてよいのは分かりますが、str2はこれでよいのか教えて下さい。

Aベストアンサー

参考のために、MSの無料ツールVC++ 2005 Expression Editionが生成するアセンブラーコードを紹介させていただきます。

5: char str1[] = "AB";
004113AE 66 A1 04 57 41 00 mov ax,word ptr [string "AB" (415704h)]
004113B4 66 89 45 F8 mov word ptr [str1],ax
004113B8 8A 0D 06 57 41 00 mov cl,byte ptr ds:[415706h]
004113BE 88 4D FA mov byte ptr [ebp-6],cl
6: char* str2 = "ab";
004113C1 C7 45 EC 00 57 41 00 mov dword ptr [str2],offset string "ab" (415700h)
7: *(str1+1) = 'C';
004113C8 C6 45 F9 43 mov byte ptr [ebp-7],43h
8: *(str2+1) = 'c';
004113CC 8B 45 EC mov eax,dword ptr [str2]
004113CF C6 40 01 63 mov byte ptr [eax+1],63h

使用中の処理系の結果と比較してみてください。速度を重視する場合やセキュリティを配慮する必要がある場合など、いろいろ考えることがあるようです。

参考になれば幸いです。

参考のために、MSの無料ツールVC++ 2005 Expression Editionが生成するアセンブラーコードを紹介させていただきます。

5: char str1[] = "AB";
004113AE 66 A1 04 57 41 00 mov ax,word ptr [string "AB" (415704h)]
004113B4 66 89 45 F8 mov word ptr [str1],ax
004113B8 8A 0D 06 57 41 00 mov cl,byte ptr ds:[415706h]
004113BE 88 4D FA mov byte ptr [ebp-6],cl
6: char* str2 = "ab";
004113C1 C7 45 EC 00 57 41 00 mov dw...続きを読む


このカテゴリの人気Q&Aランキング

おすすめ情報