深レビューでC言語学習:配列とポインタ

C列

アレイをするために使用されるものと同じタイプのシリーズを格納するコレクションの変数順序。すべての配列は、連続したメモリ位置で構成されています。

配列を宣言します

必須の要素は、要素の種類や数を指定します

type arrayName [ arraySize ];

配列の初期化

//大括号 { } 之间的值的数目不能大于我们在数组声明时在方括号 [ ] 中指定的元素数目。
double balance[5] = {1000.0, 2.0, 3.4, 7.0, 50.0};
//省略掉了数组的大小,数组的大小则为初始化时元素的个数。
double balance[] = {1000.0, 2.0, 3.4, 7.0, 50.0};
//为数组中某个元素赋值
balance[4] = 50.0;

配列要素は、索引付け配列名を介してアクセスすることができます。

多次元配列

次のように多次元配列宣言の一般的な形態です。

type name[size1][size2]...[sizeN];

二次元アレイは、本質的に、一次元アレイ、その宣言および初期化のリストです。

int a[3][4] = {  
 {0, 1, 2, 3} ,   /*  初始化索引号为 0 的行 */
 {4, 5, 6, 7} ,   /*  初始化索引号为 1 的行 */
 {8, 9, 10, 11}   /*  初始化索引号为 2 的行 */
};
//内部嵌套的括号是可选的,下面的初始化与上面是等同的
int a[3][4] = {0,1,2,3,4,5,6,7,8,9,10,11};

関数に配列を渡します

関数のパラメータとして配列を渡すと、関数パラメータの形で次の三つの方法で宣言されなければなりません。コンパイラを教えてくれます各メソッドが整数ポインタを受け取ることになっているため、これらの3つのステートメントの結果は、同じ方法です。

1.パラメータは、の形のポインタです。

void myFunction(int *param) 
{ 
body of function
 }

2.仮パラメータが定義された配列のサイズであります:

void myFunction(int param[]) 
{ 
body of function
 }

3.仮パラメータは未定義配列のサイズであります:

void myFunction(int *param) 
{ 
body of function
 }

関数から配列を返します

1次元配列から関数が戻ると、あなたは、関数を宣言しなければならないポインタを返します。

int * myFunction()
{
 body of function
}

ローカル変数が定義されない限り、Cは、関数の戻りアドレス外部ローカル変数をサポートしていない  静的  変数を。

例:

/*
从函数返回一个由10个随机数构成的数组
*/
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
 
/* 要生成和返回随机数的函数 */
int * getRandom( )
{
  static int  r[10];
  int i;
 
  /* 设置种子 */
  srand( (unsigned)time( NULL ) );
  for ( i = 0; i < 10; ++i)
  {
     r[i] = rand();
     printf( "r[%d] = %d\n", i, r[i]);
 
  }
 
  return r;
}
 
/* 要调用上面定义函数的主函数 */
int main ()
{
   /* 一个指向整数的指针 */
   int *p;
   int i;
 
   p = getRandom();
   for ( i = 0; i < 10; i++ )
   {
       printf( "*(p + %d) : %d\n", i, *(p + i));
   }
 
   return 0;
}

配列へのポインタ

配列名は、配列の最初の要素を指す定数ポインタです。

double *p;
double balance[10];

p = balance;

バランスが  ポイント・バランス[0]のポインタ、すなわち、バランスの配列の最初のエレメントのアドレスです。 pは  に割り当てられた  バランス  最初のエレメントのアドレス。定数ポインタ配列名として使用することは法律上、およびその逆です。したがって、*(バランス+ 4)はバランス[4]データ・モードへの正当なアクセスです。

注意:

1. * P + 4ポインタの(バランス&[0])(&フェッチアドレスを表す。)、pはバランスの配列を指している第一のアドレスを参照し、P *は、最初の要素(割当の右側*及び表現のアドレス値です。値+ 4バランスである指示値)、[0] +4 

2 *(p + 4)はポインタの(バランス&[0])(&フェッチアドレスが表す)点Pが配列バランスの最初のアドレスであることを意味し、pは再び、4 + P *値をアドレス+ 4 + 4を表しますしたがって、*(p + 4)はバランス[4](5つの要素の値)を表します。

 

C列挙

列挙は、C言語での基本的なデータ型です。列挙構文定義フォーマット:

enum enumName {enum1,enum2,……};

列挙型列挙要素を定義するときに列挙要素指定された値、1の値を加えた前の要素なしに、変更することができます。デフォルト値は、最初の整数0列挙部材、前面部材1を加えた上で、その後の列挙体の値です。

列挙の定義

列挙を定義するための3つの方法があります。

1.列挙型を定義し、次に列挙を定義します

enum DAY
{
      MON=1, TUE, WED, THU, FRI, SAT, SUN
};
enum DAY day;

列挙型を定義します。2.また、列挙を定義します

enum DAY
{
      MON=1, TUE, WED, THU, FRI, SAT, SUN
};
enum DAY day;

図3は、列挙の名前を省略し、列挙を直接定義しました

enum
{
      MON=1, TUE, WED, THU, FRI, SAT, SUN
} day;

列挙型は、unsigned int型のintまたは取り扱うそのままC言語では、それはC言語仕様に従って列挙型を横断する方法はありません。しかし、いくつかの特別な状況では、列挙型連続値は、連続条件トラバーサルを達成することができます。

(トラバース要素の列挙に使用)例:

#include<stdio.h>
 
enum DAY
{
      MON=1, TUE, WED, THU, FRI, SAT, SUN
} day;
int main()
{
    // 遍历枚举元素
    for (day = MON; day <= SUN; day++) {
        printf("枚举元素:%d \n", day);
    }
}

列挙型不連続、この列挙することはできませんトラバース、例:

enum
{
    ENUM_0,
    ENUM_10 = 10,
    ENUM_11
};

 

Cのポインタ

学びポインタC言語が必要です。それが唯一のタスクを簡素化することができないだけでなく、そのような動的なメモリ割り当てのように、何のポインタは法的強制力はありません。変数のメモリ位置は、変数できハイフンアクセスアドレス演算子(&)を定義しています。

ポインタとは何ですか?

ポインタは、その値が直接別の変数のアドレス、即ちメモリ位置にアドレス指定された変数です。したがって、ポインタ変数の値は、それがアドレスを指すこと。

ポインタ変数の宣言の一般的な形態です。

type *var-name;

すべてのポインタの値のタイプが同じで、それは代表的な16進数のメモリアドレスです。異なる定数又は可変データ型へのポインタポイント。

どのようにポインタを使用するには?

ポインタ変数を定義します。1.

2.変数のポインタに割り当てられたアドレス

アクセスポインタ変数で使用可能なアドレスの3値。

これらの単項使用して  *をオペランド変数指定されたアドレスの値を返します。例としては、次のとおりです:

#include <stdio.h>
 
int main ()
{
   int  var = 20;   /* 实际变量的声明 */
   int  *ip;        /* 指针变量的声明 */
 
   ip = &var;  /* 在指针变量中存储 var 的地址 */

   /*取变量地址使用& */
   printf("Address of var variable: %p\n", &var  );
 
   /* 在指针变量中存储的地址 */
   printf("Address stored in ip variable: %p\n", ip );
 
   /* 使用指针访问值(*是取对应内存地址的值) */
   printf("Value of *ip variable: %d\n", *ip );
 
   return 0;
}

CにおけるNULLポインタ

正確なアドレスを割り当てることができない場合は、ポインタ変数を宣言ポインタ変数にNULL値を割り当てることは良いプログラミングの練習です。フーNULLポインタ値が呼び出され、ヌルポインタ、NULLポインタのアドレス0x0。

ヌルポインタが標準ライブラリゼロ定数で定義されています。メモリは、オペレーティングシステム用に予約されているため、ほとんどのオペレーティングシステムでは、プログラムは、メモリアドレス0へのアクセスを許可していません。

ただし、メモリアドレス0は、それがポインタがアクセス可能なメモリの場所を指していないことを示し、特別な意味を持っています。しかし、慣例により、ポインタがヌルが(ゼロ値(NULL))であれば、何を指していないことが想定されます。

ポインタ演算

Cは数値化ポインタのアドレスです。そのため、あなたはポインタに対して算術演算を実行することができます。それは、4つの算術演算へのポインタであってもよいです:+、 - 、+、 - 。

ptr++

 仮定する  PTRは  整数、32ビット整数、各追加のPTRである、それは場合は、次の整数の位置をポイントするアドレス1000を示すポインタである  PTR  文字アドレス1000を指し、上記動作はへのポインタを引き起こすであろう場所1001年、1001年の次の文字位置からです。

ポインタ変数を増減

アレイ内の各要素にアクセスします。

/*指针递增遍历*/
#include <stdio.h>
 
const int MAX = 3;
 
int main ()
{
   int  var[] = {10, 100, 200};
   int  i, *ptr;
 
   /* 指针中的数组地址 */
   ptr = var;
   for ( i = 0; i < MAX; i++)
   {
 
      printf("存储地址:var[%d] = %x\n", i, ptr );
      printf("存储值:var[%d] = %d\n", i, *ptr );
 
      /* 移动到下一个位置 */
      ptr++;
   }
   return 0;
}

/*指针递减遍历*/
#include <stdio.h>
 
const int MAX = 3;
 
int main ()
{
   int  var[] = {10, 100, 200};
   int  i, *ptr;
 
   /* 指针中最后一个元素的地址 */
   ptr = &var[MAX-1];
   for ( i = MAX; i > 0; i--)
   {
 
      printf("存储地址:var[%d] = %x\n", i-1, ptr );
      printf("存储值:var[%d] = %d\n", i-1, *ptr );
 
      /* 移动到下一个位置 */
      ptr--;
   }
   return 0;
}

ポインタの比較

ポインタは、==、<と>のような関係演算子と比較することができます。直接比較アドレスポインタのサイズ比較。次いで、使用アスタリスクであってもよい変数値へのポインタのポイントを比較した後、所望の値とを比較します。配列要素にアクセスアドレス変更子コードをインクリメント、可変アドレスポインタは、または配列&VAR [MAX - 1]の最後の要素に等しい未満であるとして、以下、インクリメントされ、ポインタ変数を置きます。

#include <stdio.h>
 
const int MAX = 3;
 
int main ()
{
   int  var[] = {10, 100, 200};
   int  i, *ptr;
 
   /* 指针中第一个元素的地址 */
   ptr = var;
   i = 0;
   while ( ptr <= &var[MAX - 1] )
   {
 
      printf("Address of var[%d] = %x\n", i, ptr );
      printf("Value of var[%d] = %d\n", i, *ptr );
 
      /* 指向上一个位置 */
      ptr++;
      i++;
   }
   return 0;
}

ポインタ配列

ポインタ文の配列:

type *pointerArrayName[size];

//例如,声明一个由10个指向整数的指针构成的指针数组:
/*int *ptr[10];*/

次の例では、三つの整数を使用して次のように、それは、ポインタの配列に格納されます。

#include <stdio.h>
 
const int MAX = 3;
 
int main ()
{
   int  var[] = {10, 100, 200};
   int i, *ptr[MAX];
 
   for ( i = 0; i < MAX; i++)
   {
      ptr[i] = &var[i]; /* 赋值为整数的地址 */
   }
   for ( i = 0; i < MAX; i++)
   {
      //ptr[i]是指针数组中的指针,是整数的地址;*对指针指向整数的地址取出值
      printf("Value of var[%d] = %d\n", i, *ptr[i] );
   }
   return 0;
}

次のようにポインタの配列はまた、文字列のリストの文字を格納するために使用することができる:(少し疑い、フォローアップ調査)

#include <stdio.h>
 
const int MAX = 4;
 
int main ()
{
   const char *names[] = {
                   "Zara Ali",
                   "Hina Ali",
                   "Nuha Ali",
                   "Sara Ali",
   };
   int i = 0;
 
   for ( i = 0; i < MAX; i++)
   {
      //names[i]是指针数值*names[]中的元素,是字符指针,names[i]所指向的变量的地址存放的值是字符串的首字母
      printf("Value of names[%d] = %s\n", i, names[i] );
   }
   return 0;
}

ポインタへのポインタ

これは、変数のアドレスへのポインタが含まれています。我々は、ポインタへのポインタを定義する場合、最初のポインタは、第2のポインタのアドレス、実際の位置の値に対する第2のポインタを含みます。つまり、変数名の前に2つのアスタリスクを配置し、次のようにポインタ変数へのポインタを宣言する必要があります。

type **pointerName;

目標値は、間接的に別のポインタを指し示すポインタである場合、値にアクセスするためには、2つの演算子のアスタリスクを必要とします。

#include <stdio.h>
 
int main ()
{
   int  var,*ptr, **pptr;
   var = 3000;
   /* 获取 var 的地址 */
   ptr = &var;
   /* 使用运算符 & 获取 指向变量的指针ptr 的地址 */
   pptr = &ptr;
   printf("Value of var = %d\n", var );
   printf("Value available at *ptr = %d\n", *ptr );
   /* 使用 **pptr 获取值 */
   printf("Value available at **pptr = %d\n", **pptr);
   return 0;
}

関数へのポインタを渡します

C言語を使用すると、関数へのポインタを渡すことができます、単純に関数の引数の型へのポインタです宣言する。

#include <stdio.h>
#include <time.h>
 
void getSeconds(unsigned long *par);

//也可以将数组名作为指针传递给函数,数组名就是数组的首地址。

int main ()
{
   unsigned long sec;
   getSeconds( &sec );//传递指针给函数,是传递的地址
   /* 输出实际值 */
   printf("Number of seconds: %ld\n", sec );
   return 0;
}
void getSeconds(unsigned long *par)
{
   /* 获取当前的秒数 */
   *par = time( NULL );//par指针指向的sec地址存储的值赋值为当前时间秒数
   return;
}

関数からポインタを返します。

Cは、関数ポインタから戻ることができます。したがって、我々は関数を宣言しなければならない、次のように、ポインタを返します。

int * myFunction()
{
body of function
}

また、C言語では、ローカル変数は静的変数として定義されていない限り、あなたは、関数のアドレスを呼び出して、ローカル変数の戻りをサポートしていません。

ローカル変数は、その関数が終了すると、関数呼び出しの終わりには、ローカル変数の共有メモリアドレスは、リリースされる際に、メモリのスタック領域に格納されているので、関数内の変数は、もはやそのメモリアドレスを持っていないだろう、したがって、それはポインタを返すことはできません。

それは、変数、静的変数として定義されていない限り、ない機能の実行の終わりとして、メモリ領域に格納された静的データの値がクリアされた静的変数は、それがそのアドレスに戻すことができます。

公開された161元の記事 ウォン称賛90 ビュー50000 +

おすすめ

転載: blog.csdn.net/qq_42415326/article/details/104027363