C/C++心得-メモリから

16656 ワード

仕事と自分の各方面の需要のため、再びCを学ぶことを始めて、実は再びあまり正確ではありませんて、もとは大学の中で接触したことがあって、しかもまだあまり精髄がなくて他の開発に転じて、しかしまさにそのためやっと再び学ぶ必要があって、基礎部分の心得は博文を通じて記録して、初心者に対していくつか役に立つべきです;もちろんここはただ心得で、直接Cを学ぶことはできませんが、回り道を少なくすることができるはずです.
多くの資料を見て、最終的に私の個人的な認識は:C/C++の難点はCで、Cの精華はポインタで、ポインタをマスターしたいならコンピュータのメモリをはっきり認識しなければなりません.
1.メモリに関する知識
メモリの紹介はまずストレージ単位から始めます.この文章を書いたのは2014年の冬で、当時日常生活の中で私たちが接触した記憶装置はパソコンのハードディスク、携帯電話のメモリカードだった.最も頻繁に接触する記憶単位はMB(「兆」と読む)とGB(「吉」と読む)である.実際、コンピュータ言語の最小の記憶単位はbit(「ビット」と読む)であり、コンピュータの多くのデータの表現はバイナリ単位であり、1ビットは1つのバイナリ数ビットを表し、0または1しか記憶できない.Byteはコンピュータで最もよく使われる単位で、8 bitは1 byteで、多くの場所で1 bが1 bitを表し、1 Bが1 byteを表す.1 Kilobyteは1000 byteに等しい(コンピュータではバイナリ計算1 kilobyteが2に等しい10乗byte、すなわち1024 byte).他の単位の換算について説明します.
1 kilobyte kB = 1000 (10^3) byte 1 megabyte MB = 1 000 000 (10^6) byte 1 gigabyte GB = 1 000 000 000 (10^9) byte 1 terabyte TB = 1 000 000 000 000 (10^12) byte 1 petabyte PB = 1 000 000 000 000 000 (10^15) byte 1 exabyte EB = 1 000 000 000 000 000 000 (10^18) byte 1 zettabyte ZB = 1 000 000 000 000 000 000 000 (10^21) byte 1 yottabyte YB = 1 000 000 000 000 000 000 000 000 (10^24) byte 1 brontobyte BB = 1 000 000 000 000 000 000 000 000 000 (10^27)byte1 nonabyte NB = 1 000 000 000 000 000 000 000 000 000 000 (10^30) byte 
上記も記憶媒体(ハードディスクなど)メーカーが使用する単位ですが、コンピュータシステムではバイナリを用いた千来換算を認識しているので、認識するときの容量は小さくなります.バイナリ換算は以下のようになります.
1 kilobyte kB = 1024 (2^10) byte 1 megabyte MB = 1 048 576 (2^20) byte 1 gigabyte GB = 1 073 741 824 (2^30) byte 1 terabyte TB = 1 099 511 627 776 (2^40) byte 1 petabyte PB = 1 125 899 906 842 624 (2^50) byte 1 exabyte EB = 1 152 921 504 606 846 976 (2^60) byte 1 zettabyte ZB = 1 180 591 620 717 411 303 424(2^70) byte 1 yottabyte YB = 1 208 925 819 614 629 174 706 176 (2^80) byte 1 brontobyte BB = 1 237 940 039 285 380 274 899 124 224(2^90)byte1 nonabyte NB = 1 267 650 600 228 229 401 496 703 205 376(2^100) byte 
もちろん、実はTBの後ろの単位はほとんど使えません.これらのものを理解して、コンピュータシステムの中で最初のbitとbyteを除いて、後ろの単位はすべて前の1024倍でいいことを覚えてください.
32ビットシステムの32ビットとは、ある意味ではCPUが一度に処理できる最大ビット数を指し、各ビットの単位はbyteであり、バイナリで計算されるため、32ビットシステムのCPUが一度に処理できる値は2の32乗であり、最後に4 GBが得られるため、32ビットシステムがサポートする理論の最大内蔵は4 GBであり、もちろん実際には小さくなる可能性がある.
2.C言語のデータ型
データ型の本質は異なるサイズのメモリブロックの別名であり、異なるデータ型は異なる解析方式に対応している.これは私のデータ型に対する認識であり、以下に例を挙げて紹介する.
1 #include<stdio.h>

2 #include<stdlib.h>

3 

4 void main()

5 {

6    printf("%d
",sizeof(int)); 7 printf("%d
",sizeof(char)); 8 system("pause") ; 9 }

上は比較的完全なコマンドラインウィンドウのコードブロックで、Cを少し習ったことがあるので、上のコードを理解できるはずです.printf関数はコマンドラインに文字列を出力することができ、sizeof関数はタイプや変数がメモリに占めるサイズ(byte単位)を計算することができます.変数は、データ型によって定義されると、そのタイプに対応するメモリサイズが消費されます.32ビットプログラムの下で上記のコードの実行結果は以下の通りであるべきである(他のビット数システムは異なる場合があり、ここでは32ビットシステムのみを例に挙げる).
 
4

1

       . . .

これはintタイプがメモリに4 byte,charが1 byteを占有することを示す.まず数字そのもの、すなわち4と1にはいったい何の意味があるのだろうか.実はこの数字は、intが4バイト、すなわち32 bitを占めるなど、このタイプがどれだけ異なる値を表すことができるかを示していますが、前述したように、1 bitは0と1の2つの値を表すことができ、intは2の32次方種の異なる値、すなわち4294967296の異なる値を表すことができます.もちろん、intタイプは最大4294967296に設定できるわけではありません.intタイプ自体には負の数があるため、実際にはintタイプの値の範囲の負の数がそれぞれ半分を占めていません.つまり、範囲は-2174848648から+2174848647です.負の数が使用されない場合があります.intの前にunsigned、すなわちunsigned intを加えることができます.このタイプの値の範囲は0から+4294967295です.次のコードでテストすることができます.この数に1を足すと、オーバーフローし、変数がそのタイプの最小値になります.
 1 #include<stdio.h>

 2 #include<stdlib.h>

 3 

 4 void main()

 5 {

 6     unsigned int ui = 4294967295;

 7     int i = 2147483647;

 8     printf("i=%d
", i); 9 printf("ui=%u
", ui); 10 system("pause"); 11 }

以上から、charが占有する1 byteメモリ空間が表すことができる値の範囲は-128〜+127であると推定される.同様に、unsigned charが表すことができる値の範囲は0〜255である.ではintとcharは、メモリ容量の違い以外にどのような違いがありますか?まず、次のテストコードを見てください.
 1 #include<stdio.h>

 2 #include<stdlib.h>

 3 

 4 void main()

 5 {

 6     int i = 90;

 7     int j = 'c';

 8     char a = 100;

 9     char b = 'b';

10     printf("");

11     printf("i=%d,j=%d,a=%d,b=%d
", i, j, a, b); 12 printf(""); 13 printf("i=%c,j=%c,a=%c,b=%c
", i, j, a, b); 14 system("pause"); 15 }

まず、上のコードはコンパイルされているはずですが、Cデータ型を見たことがある人はみな知っています.intは整数を格納するデータ型で、charは文字を格納するデータ型ですが、上のコードではint型変数jに文字を付与してもいいし、char型変数aに整数を付与してもいいし、上の4つの変数は%dを整数として出力することができます.%cを文字として出力することもできます.これはいわゆる解析方式であり,データ型は割り当てられたメモリサイズに加えて解析方式も異なり,intとchar型の解析方式は互いに共通している.コンピュータの最後のデータが0と1のバイナリデータに変換されることはよく知られています.0から9の間の数字もバイナリ変換によって来ています.文字も実は数字変換によって来ています.バイナリから10進数までは直接計算できますが、数字から文字への変換は人為的に規定されています.この規定の表はASCII表です.ASCII表の具体的な対応関係はここで貼らないで、各種のC資料の上ですべてあるべきです.上記のコードの実行結果は次のとおりです.
      :i=90,j=99,a=100,b=98

      :i=Z,j=c,a=d,b=b

       . . .


intとcharタイプが互いに変換できるのは、ASCIIテーブルに対応するマッピング関係であり、上のコードのテストデータが境界を越えていない(charタイプ値の範囲を超えていない)ためであり、上の実行結果から、ASCIIにおける整数90は大文字Zに対応し、整数99は小文字cに対応し、整数100は小文字dに対応し、整数98は小文字bに対応することが分かった.テストに使用するためcharとintタイプを使用し、floatまたはdoubleタイプを使用すると、そのマッピング関係に反応する結果が得られない可能性があります.なぜなら、それらの解析はまったく異なるからです.
 
 
 
 
 
メモリ4
本文は主にメモリを使って、以前はすべていくつかのこまごました知識で、今具体的にC言語の中のメモリを言います;C言語でユーザが操作できるメモリは,基本的に変数を定義したりmallocやrellocのような関数で割り当てられたりしており,変数のアドレスを取得する場合は&記号を用いることができる.
C言語プログラムのメモリは、従来の意味では、コード領域、データ領域(グローバル領域、定数領域)、スタック領域(一時領域)、スタック領域の4つの領域に分けられている.
コード領域はコンパイラがC言語プログラムをコンパイルしたバイナリコードを格納し,C言語ではそのアドレスを取得できないため,多くの説明にすぎない.
データ領域は、プログラムのグローバル変数を格納する場所であり、グローバル変数はデータ領域のグローバル領域に配置され、定数はグローバル領域の定数領域に配置され、定数はアドレスを取得できず、グローバル変数は可能である.この領域のメモリは、プログラムが終了すると解放されます.
スタック領域(一時領域)は、プログラムが直接定義した変数がスタック領域に配置され、変数が存在する関数の実行が完了すると、関数内部で定義したスタック変数が解放される(解放の意味は、この変数の値を正しく取得できないことである).各プログラムで使用できるスタックメモリは限られており、一般的には1 Mしかありません.関数呼び出しが完了すると解放される特性であるため、一時領域とも呼ばれる.
ヒープ領域は、mallocやrellocのような関数で割り当てられた内部がヒープ領域に格納されます.一般的にヒープ領域を使用する理由は、大きなメモリを使用する必要があるためです.あるいは、変数がその関数呼び出しが終了しても変数メモリが使用できるようにすると、ヒープ領域に使用されます.ヒープ領域の欠点は、メモリがfree関数を手動で使用して解放する必要があることです.メモリの漏洩が発生しやすい(変数の使用が完了してもメモリ領域を占め、システムや他のプログラムの実行に影響を及ぼす場合を指す).C言語で最も多く使用されるメモリ領域は、スタック領域とスタック領域である.次のコードは、メモリ4領域変数の例です.
 1 #include<stdio.h>

 2 #include<stdlib.h>

 3 

 4 int x = 0; //          

 5 int y;//            x,y            

 6 

 7 

 8 int * ExampleStack()

 9 {

10     int i = 0;

11     int j; // i j     ,   i j         i      j , Example     ,i j     ,     

12     printf("i  :%x,j  :%x
", &i, &j);// 13 return &i; // , 0, 。 14 } 15 16 int *ExampleHeap() 17 { 18 // p , malloc , * , *p 19 int *p = (int *)malloc(sizeof(int)); 20 // ,p q ,p q 21 int *q = (int *)malloc(sizeof(int)); 22 printf("p :%x,q :%x
", p, q);// 23 *p = 20; 24 free(q); 25 q = NULL; 26 return p; // p, 27 } 28 29 void main() 30 { 31 int *p = ExampleStack(); 32 int *q = ExampleHeap(); 33 char *str = "abcd"; // str , "abcd" , str 34 printf(" :%d
", *p); // p , ExampleStack i 35 printf(" :%d
", *q); // 20, q 36 if (q != NULL) free(q); // 37 q = NULL;// 38 p = NULL;// 39 system("pause"); 40 }

コードにはメインmain関数の他にExampleStackとExampleHeap関数が例としてあり、便利に例としてポインタも使用されているので、ポインタ自体はあまり紹介されておらず、分からない場合はポインタの知識を理解してからこのコードを見ることができます.
本文はただ自分のC言語に対するいくつかの認識を総括して、直接教程として使うことはできませんが、初心者が参考にする知識として見ることができます.