【掲示板ご利用上の注意】

 ※題名は具体的に!
 ※学校の課題の丸投げ禁止!
 ※ソースの添付は「HTML変換ツール」で字下げ!
 ※返信の引用は最小限に!
 ※環境(OSとコンパイラ)や症状は具体的に詳しく!
 ※返信付き投稿の削除は禁止!
 ※マルチポスト(多重投稿)は慎んで!

 詳しくはこちら


本当はこんなに大きく書きたくはないのですが、なかなか守っていただけなくて…。
 守ってくださいね。お願いします。(by管理人)

C言語ソース⇒HTML形式ツール掲示板2こちら


管理者用メニュー    ツリーに戻る    携帯用URL    ホームページ    ログ    タグ一覧

No.23179

str[i]はアドレスか?変数か?
投稿者---あきき(2005/09/20 21:49:59)


当サイトの11-2の解答例で疑問があります。

www.geocities.jp/ky_webid/c/030.htmlでは、”配列は引数にできない”と書かれています。11-2の解答例で示すstr[i]は、アドレスなんでしょうか?時々、単なる文字列を指しているだけではと思ってしまいます。
どうかよろしくお願いします。

#include <stdio.h>
#include <ctype.h>

void oomoji( char *st ) ;

int main( void )
{
    char str[3][10] = {
        "computer", 
        "lsi-c", 
        "ms-dos"
    };
    int i;
    
    for ( i = 0; i < 3; i++ ) {
        oomoji( str[i] ); // 文字列の先頭アドレスを渡しているのか
    }
    
    return 0;
}

/* 大文字変換プログラム */
void oomoji( char *st )
{
    int i = 0;
    
    while( *( st+i ) != '\0' ) {
        *( st+i ) = toupper( *( st+i ) );
        i++;
    }
    printf( "%s\n", st );
}



この投稿にコメントする

削除パスワード

発言に関する情報 題名 投稿番号 投稿者名 投稿日時
<子記事> Re:str[i]はアドレスか?変数か? 23180 επιστημη 2005/09/20 21:56:10
<子記事> Re:str[i]はアドレスか?変数か? 23247 きりん 2005/09/23 13:49:36


No.23180

Re:str[i]はアドレスか?変数か?
投稿者---επιστημη(2005/09/20 21:56:10)


>www.geocities.jp/ky_webid/c/030.htmlでは、”配列は引数にできない”と書かれています。11-2の解答例で示すstr[i]は、アドレスなんでしょうか?時々、単なる文字列を指しているだけではと思ってしまいます。

単なる文字列はアドレスです(ちと語弊があるが、そう思ってもらってかまわない)。

const char* str = "ほらね♪";



この投稿にコメントする

削除パスワード

No.23247

Re:str[i]はアドレスか?変数か?
投稿者---きりん(2005/09/23 13:49:36)


>str[i]は、アドレスなんでしょうか?
str[i]は「要素数10の1次元配列」の名前と考えられます。
(C言語の2次元配列は「配列の配列」なので・・・)

添字演算子を伴わない配列名は一部の例外を除いて
配列先頭要素のアドレスと解釈されますよね?


この投稿にコメントする

削除パスワード

No.23248

Re:str[i]はアドレスか?変数か?
投稿者---かずま(2005/09/23 15:51:08)


> str[i]は「要素数10の1次元配列」の名前と考えられます。

str や i は名前ですが、str[i] は名前ではありません。式です。
オブジェクトを参照する式で、これを左辺値と呼びます。

char str[3][10]; という宣言があると、
str は配列。その要素数は 3。要素の型は char [10]。
str[i] は配列。その要素数は 10。要素の型は char。
ところが、配列は式として評価するとき、先頭要素へのポインタに変換され
るので、str[i] は str[i][0] へのポインタとなります。


> 添字演算子を伴わない配列名は一部の例外を除いて
> 配列先頭要素のアドレスと解釈されますよね?

添字演算子を伴う場合でも配列は先頭要素へのポインタに変換されます。
なぜなら、添字演算子 [ ] は、e1[e2] が (*(e1+(e2))) と等価であると定義さ
れているからです。

配列が先頭要素へのポインタに変換されない例外は、次のいずれかです。
1. 単項&演算子のオペランドであるとき
2. sizeof演算子のオペランドであるとき
3. 文字配列を初期化するのに使われる文字列リテラルであるとき

3 の具体例は、char str[] = "ほらね♪";

この文字列リテラル "ほらね♪" は、環境(文字コード)にもよりますが、通常
は、要素数 9 の、char の配列です。そして、ポインタには変換されません。

それから、変換されたポインタは値です。左辺値ではありません。
そのポインタの値のことをアドレスといいます。


この投稿にコメントする

削除パスワード

No.23271

Re:str[i]はアドレスか?変数か?
投稿者---あきき(2005/09/24 01:42:41)


>3 の具体例は、char str[] = "ほらね♪";
>
>この文字列リテラル "ほらね♪" は、環境(文字コード)にもよりますが、通常
>は、要素数 9 の、char の配列です。そして、ポインタには変換されません。
>
>それから、変換されたポインタは値です。左辺値ではありません。
>そのポインタの値のことをアドレスといいます。

下2行はconstの事を指しているのでしょうか


この投稿にコメントする

削除パスワード

No.23277

Re:str[i]はアドレスか?変数か?
投稿者---まきじ(2005/09/24 02:34:31)


>>それから、変換されたポインタは値です。左辺値ではありません。
>>そのポインタの値のことをアドレスといいます。
>
>下2行はconstの事を指しているのでしょうか

ポインタの値はポインタの値。

int x;
int *p;
p = &x;

の &x は int* 型です。

int *p = 0x00 ← これは int 型


この投稿にコメントする

削除パスワード

No.23278

Re:str[i]はアドレスか?変数か?
投稿者---あきき(2005/09/24 09:16:37)


>>>それから、変換されたポインタは値です。左辺値ではありません。
>>>そのポインタの値のことをアドレスといいます。
>>
>>下2行はconstの事を指しているのでしょうか
>
すいません。肝心な部分が引用されていませんでした。以下の部分を追加します

”この文字列リテラル "ほらね♪" は、環境(文字コード)にもよりますが、通常
は、要素数 9 の、char の配列です。そして、ポインタには変換されません。”


この投稿にコメントする

削除パスワード

No.23281

Re:str[i]はアドレスか?変数か?
投稿者---まきじ(2005/09/24 11:36:47)


>>>下2行はconstの事を指しているのでしょうか

ポインタの値が const か否かということですか?
文字列リテラルが const か否かということですか?

どちらも const でない。


この投稿にコメントする

削除パスワード

No.23284

Re:str[i]はアドレスか?変数か?
投稿者---あきき(2005/09/24 13:38:31)


>>>>下2行はconstの事を指しているのでしょうか
>
>ポインタの値が const か否かということですか?
>文字列リテラルが const か否かということですか?
>
>どちらも const でない。

>この文字列リテラル "ほらね♪" は、環境(文字コード)にもよりますが、通常
>は、要素数 9 の、char の配列です。そして、ポインタには変換されません。

かずまさんが仰っている上記の意味が分かりませんので、教えてほしいのですが。例えば、str[]="ほらね♪"はメモリー上ではどこに存在する事になるのですか?ポインタに変換されないというのなら。


この投稿にコメントする

削除パスワード

No.23288

Re:str[i]はアドレスか?変数か?
投稿者---まきじ(2005/09/24 14:32:17)


>例えば、str[]="ほらね♪"はメモリー上ではどこに存在する事になるのですか?

printf("%p",str) とすれば、"ほ" のアドレスが判ります。

>ポインタに変換されないというのなら。

変換される/されないは、規格で定められてることです。

メモリ上に 'ほ' と 'ら' と 'ね' を連続した領域に記憶され
連続した領域に対して、str という名前を付けるので
ポインタに変換される必要がないのでしょう。

で char* buf = "ほらね" だと、buf はポインタを格納するので
連続した領域の先頭アドレスが必要になるので変換される。

# 間違ってらすいません。


この投稿にコメントする

削除パスワード

No.23289

Re:str[i]はアドレスか?変数か?
投稿者---RiSK(2005/09/24 14:36:46)


>かずまさんが仰っている上記の意味が分かりませんので、教えてほしいのですが。
>例えば、str[]="ほらね♪"はメモリー上ではどこに存在する事になるのですか?
>ポインタに変換されないというのなら。

strと"ほらね♪"はそれぞれ別の場所に領域が確保されます。
strもオブジェクトだし,"ほらね♪"もオブジェクトです。

文字列リテラル"ほらね♪"の型はchar[9]です。
おそらく実行ファイルに埋め込まれるでしょう。
constではありませんが,変更すると未定義動作になるので,
変更してはなりません。
# もっとも初期化式で使われているので,ポインタを獲られず
# 変更しようがないけどね。

strの型は"ほらね♪"と同じでchar[9]です。
メモリが確保され,"ほらね♪"で初期化されます。
こちらは変更できるし,安全です。


この投稿にコメントする

削除パスワード

No.23291

Re:str[i]はアドレスか?変数か?
投稿者---あきき(2005/09/24 23:32:00)


str[i]がアドレスであるわけは、かずまさんの説明ですごく理解できました。
ただその説明の中で、配列が先頭要素へのポインタに変換されない例外があり、その中で具体例に、char str[] = "ほらね♪"がありました。

>strと"ほらね♪"はそれぞれ別の場所に領域が確保されます。
>strもオブジェクトだし,"ほらね♪"もオブジェクトです。
>
これって、両方共、アドレスが設定されていると捉えていいのですか?
もしそうなら、理解できます。("ほらね♪"の領域の宣言?)をいつ行ったかを除いては。
ただC言語では、'='は文字列を代入する機能はなかったはずでは?


この投稿にコメントする

削除パスワード

No.23292

Re:str[i]はアドレスか?変数か?
投稿者---まきじ(2005/09/24 23:45:08)


>ただC言語では、'='は文字列を代入する機能はなかったはずでは?

str = "hoge"; とはできないですね。

char str[] = "hoge"; は、X3010 によると
「配列の要素を前から順に初期化する」という事なので
char str[5] ={'h','o','g','e','\0'}; と同じ事になるので
初期化ができます。


この投稿にコメントする

削除パスワード

No.23293

Re:str[i]はアドレスか?変数か?
投稿者---RiSK(2005/09/25 00:01:54)


>>strと"ほらね♪"はそれぞれ別の場所に領域が確保されます。
>>strもオブジェクトだし,"ほらね♪"もオブジェクトです。
>>
>これって、両方共、アドレスが設定されていると捉えていいのですか?

(「アドレスが設定」という表現が妖しいですが)そのとおり。
どこか別々のアドレスにそれぞれのオブジェクトがあるでしょう。


>("ほらね♪"の領域の宣言?)をいつ行ったかを除いては。

文字列リテラルは静的記憶域期間をもちます。
staticで宣言したのと同じですね。


>ただC言語では、'='は文字列を代入する機能はなかったはずでは?

=の機能ではなく,構文の問題です。
代入と初期化は全く別です。まきじさんの説明参照。


この投稿にコメントする

削除パスワード

No.23294

Re:str[i]はアドレスか?変数か?(解決)
投稿者---あきき(2005/09/25 00:58:52)


1.str[i]がアドレスであるか否か、について
2.文字列リテラルについて、
3.初期化時の'='について
の疑問が全て解決に至りました。みなさん、回答して頂きどうもありがとうございます。 


この投稿にコメントする

削除パスワード

管理者用メニュー    ツリーに戻る    携帯用URL    ホームページ    ログ    タグ一覧