プログラミングマガジン

プログラミングを中心にIT技術をできるだけわかりやすくまとめます。

  • ホーム
  • C言語
  • 【C言語】「配列」利用における注意点
 
 
     
  • サーバー言語  
    • Python
    • Ruby
    • PHP
    • SQL
  •  
  • インフラ  
       
    • AWS
    •  
    • 基本
    • Git
  • Web
       
    • Web開発
    • JavaScript
    • Vue.js
    • React
  •  
  • 設計  
       
    • 実装設計
    • DB設計
  • 問い合わせ
  

【C言語】「配列」利用における注意点

03.17

  • miyabisan2
  • コメントを書く

この記事は1分で読めます

本記事は、C言語における「配列」利用における注意点のみ記載します。

配列自体は難しい文法ではないため、基本的な使い方は割愛させていただきます。

配列自身は型である。

C言語(他の言語でもそうかもしれませんが)では配列も一つのデータ型になります。

1
int a[10];

配列は他の配列変数にコピー(代入)をすることができない。

配列は例えば、下記のような代入をすることができません。

1
2
3
4
int a[2] = {1,2};
int b[2];
 
b = a;

もし、配列の内容を他の配列変数にコピーしたい場合は、コピー元の配列から値を一つ一つ取り出して、コピー先の配列に代入する必要があります。ただ、この方法だとメンドクサイと思いますので、別のメモリ領域にコピーしてくれるmemcpy関数を使うのが一般的でしょう。

なぜ代入できないのか?

配列自体は、添え字なしの場合(上記例でいえばaのみ)だとアドレス(&a[0])を指定したことと同じになります。

なので、bのアドレスにaのアドレスを代入するという、コピーではなく同じアドレスを指している二つの変数ができるという意味のない処理になってしまうためです。

関数の引数に配列を渡す場合の注意点(ポインタ渡し)

例えば、下記のように配列を引数にとる関数があったとします。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
void func(int a[1]) {
a[0] = 15;
}
 
int main()
{
int a[1];
a[0] = 2;
 
//関数を呼び出す。
func(a);
//結果は、15と表示される。
printf("%d\n", a[0]);
 
}

その際に、関数の呼び出し先で書き換わった配列の値が、呼び出し元の配列にまで処理結果が影響してしまいます。

基本的に、関数に渡した変数は、呼び出し先と呼び出し元で独立しているため、呼び出し元にまで影響はしないはずですが、なってしまっています。

これは、関数に配列を渡した際は、配列のアドレスを渡したと同じ事になるのです。

プログラムは実際に下記のような変換が行われています。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
void func(int* a) { //★★★★★:ポインタ型を渡すのと同じように読み替えられる。(int* aとint a[1]は同じ意味)
*a = 15; //★★★★★:ポインタでメモリの内容を書き換えるように読み替えられる。(a[0]と*aは同じ意味)
}
 
int main()
{
 
int a[1];
a[0] = 2;
 
//関数を呼び出す。
func(&a[0]); //★★★★★:配列の先頭アドレスを渡すのと同じように読み替えられる。
//結果は、15と表示される。
printf("%d\n", a[0]);
 
}

この事象のことを「ポインタ渡し」と言って、呼び出し元関数と呼び出し先関数で同じメモリ番地にアクセスするため変数の中を書き換えることができるのです。

スポンサーリンク
  • 2019 03.17
  • miyabisan2
  • コメントを書く
  • C言語
  • Tweets Twitter
  • このエントリーをはてなブックマークに追加
  • LINEで送る

関連記事

  1. 2019 03.06

    【C言語】「ビルド」作業の知識と効率化について(make等)

  2. 2019 03.17

    【C言語】ポインタの基本や「ポインタ演算」、「ヌルポインタ」について

  3. 2019 03.17

    【C言語】「ナル文字」について

  4. 2019 03.05

    【C言語】「ヘッダーファイル」、「プリプロセッサ」や「マクロ処理」について

  5. 2019 03.02

    【C言語】変数の型、文字列型について

  6. 2019 03.16

    【C言語】C言語の特徴、標準ライブラリ、C++の特徴、Visual C++の特徴

  • コメント ( 0 )
  • トラックバック ( 0 )
  1. この記事へのコメントはありません。

  1. この記事へのトラックバックはありません。

返信をキャンセルする。

【C言語】C言語の特徴、標準ライブラリ、C++の特徴、…

【C言語】ポインタの基本や「ポインタ演算」、「ヌルポイ…

RETURN TOP

著者プロフィール

エンジニア歴10年で過去に業務系、Webデザイン、インフラ系なども経験あります。現在はWeb系でフロントエンド開発中心です。

詳細なプロフィールはこちら

スポンサーリンク

カテゴリー

  • Android
  • AngularJS
  • API
  • AWS
  • C++
  • CSS
  • C言語
  • DDD
  • DevOps
  • Django
  • Docker
  • Figma
  • Git
  • GitLab
  • GraphQL
  • gRPC
  • Hasura
  • Java
  • JavaScript
  • Kubernetes
  • Laravel
  • linux
  • MySQL
  • Next.js
  • nginx
  • Node.js
  • NoSQL
  • Nuxt.js
  • Oracle
  • PHP
  • Python
  • React
  • Redux
  • Rspec
  • Ruby
  • Ruby on Rails
  • Sass
  • Spring Framework
  • SQL
  • TypeScript
  • Unity
  • Vue.js
  • Webサービス開発
  • Webデザイン
  • Web技術
  • インフラ
  • オブジェクト指向
  • システム開発
  • セキュリティ
  • その他
  • データベース
  • デザインパターン
  • テスト
  • ネットワーク
  • プログラミング全般
  • マイクロサービス
  • マイクロソフト系技術
  • マルチメディア
  • リファクタリング
  • 副業
  • 未分類
  • 業務知識
  • 生成AI
  • 設計
  • 関数型言語
RETURN TOP

Copyright ©  プログラミングマガジン | プライバシーポリシー