原创 数组与指针

2014-8-28 20:51 697 7 7 分类: MCU/ 嵌入式

-------------------------------------------指针操作-----------------------------------------------------------

   ·指针变量:是一种记录地址的变量(相应类型变量: char  int  float...

·定义:

      类型名 * 变量名   ---->  所装载地址上对应的变量类型  ---->  通过声明 * 标识指针

E.g

       int A = 5;

       int *pA   = &A;   --->  pA  记录变量 A的地址,*pA在声明处表示地址

       pA  ----->  在进行指针运算时,不用加,表示地址

       *pA   ----->  获取该指针对应的变量的值,即*pA = 5

 

·指针初始化:

           1) 定义时初始化: int A = 5 ;  int *pA = &A;

           2) 先定义后初始化:  int  A ;  int *pA ; pA = &A;

    

     指针也是变量,那么指针变量也是有大小的。在当前32位系统中,CPU寻址大小32位,即4字节

 

·指针运算:

   ★指针参与运算时,增减的大小为其所对应的数据类型的单元大小。

 

  int *pA = &A   pA + 1  ----->  A地址上偏移4个字节,因为int4个字节

 

   应用:通过指针可以访问当前地址前后内存上的数据。

   

   -----------------------------------------------数组----------------------------------------------------

·数组是具有相同类型数据的组合。

   int  A,B,C;      ---> 定义了三个整型元素;

   int arryA[3];    ----> 定义了一个整型数组,里面有3个同类型成员;-----> 一维数组

 

  特殊情况下:根据内存对齐或者内存管理的因素,第一种情况所分配的数据存储空间可以不连续。第二种情况所分配的数据存储空间必须连续。(就像是3个人去饭馆吃饭,第一种情况可能3人不坐在一起,而第二种情况3人必须坐在一起)

 

★找到数组的首元素地址,即可访问全部数组的数据。

 

·数组初始化:

    1)定义时可进行整体初始化   int a[10] = {1234};  表示a[0]a[1]a[2a[3]分别赋值1234a[4]~a[9]未完成赋值的元素,系统自动赋0

    2)定义后,需逐个赋值:       a[0]  = 1;  a[1]  = 2; a[2]  = 3;  a[3]  = 4;

  数组元素的访问,从下标为0开始  ----> 一般情况下,可以越界读取数据(主要看内存的访问权限)

 

·数组与指针的关系:

       数组名等价与数组首元素的地址  -----> 数组名指向当前数组存储空间的地址

E.g

    int arryA[10]={1,2…};

    &arryA[0]就相当于对arryA数组的寻址

 

·指针访问数组:

                                   *(pA+ 1) = pA[1]

Demo

       int arryA[10] = {1,2};

      int *pA = arryA;

       *(pA + 1)  = 100;      

等价于:

        pA[1]  = 100;

  ------------------------------------------------二维数组------------------------------------------------

  int arryB[3][4];     arryB[0][0]  arryB[0][1]   arryB[0][2]   arryB[0][3]

                       arryB[1][0]  arryB[1][1]   arryB[1][2]   arryB[1][3]

                       arryB[2][0]  arryB[2][1]   arryB[2][2]   arryB[2][3]


  arryB 34列共12 int 元素

 

  ·二维数组在内存中,也是连续存储;

---------------------------------------- 一维数组与指针 -----------------------------------------------

  字符数组定义:

  1char arryC[10] = 0xFF,0xF1,…;   ---> 整数赋值,对应于ascii码表

  2char arryC[10] = "hello";     ---> 使用字符串常量对数组赋值 ----> "hello" 字符串,系统自动添加'\0' --> 字符串结束符总长度: 5+1=6

  3char  arryC[10] = {'h','e','l','l','o','\0'} ;

·在C语言中,"..."  字符串常量    'A'  字符常量

E.g

  char *pC = ;  ---->   char *pC = &arryC[0];   ---->   char *pC = arryC;

 

所以有:

  scanf("%s",pC);等价于

 scanf("%s",arryC);

 

--------------------------------------- 二维数组与指针 --------------------------------------------

 E.g

设:int arryC[3][4] = {"ABC","BCD","CDE"};

 

Linux中断下可看到

(gdb) p arryC

$1 = {"ABC", "BCD", "CDE"}

(gdb) p pC

$2 = (char (*)[4]) 0xbffff30c

(gdb) p &arryC[0]

$3 = (char (*)[4]) 0xbffff30c

可以看到 pC arryC[0]是同一类型指针,且指向的是同一地址

 

(gdb) p arryC[0]

$4 = "ABC"

(gdb) p *&arryC[0]      ----------------->  int A ;  *&A ---->  A(相当与取逆反操作)

$5 = "ABC"

(gdb) p *pC            -----> 等价于  arryC[0]  ----> 一维数组  --->  char *

$6 = "ABC

(gdb) p *(pC+1)

$14 = "BCD"

(gdb) p pC[0]

$15 = "ABC"

(gdb) p pC[1]

$16 = "BCD"

      

   ·二维数组指针?

 

   char (*p)[4]  -----> 数组指针   ----> 指向数组地址的指针(存放数组地址)

   char  *p[4]   -----> 指针数组   ----> 每个成员都是指针

 

  char (*p)[4]

   char (*p)[4]  ---> 二维数组数组名

 

   char arryD[10];

 

  设有char *p[4]  

     p[0]    ---->  类型  char *  ===>  一维字符数组名  ====>   p[0]  = arryD;

 

   char arryE[3][4];   --------> arryE[0]     arryE[1]    arryE[2]   ---> 成员为一维数组

   char *pE[3]         -------->   pE[0] = arryE[0] 

类型分别为----> char *    char *

 

     指针定义后必须准确赋值初始化才可使用,否则成为野指针。

----------------------------------------二级指针-----------------------------------------

  char *(*p);       -----> 存放指针地址的变量 


  char  A;

  char *pA = &A;

  char **ppA = &pA;

 

  char *pE[3];

  char **ppE  = pE;

 

  char A[5];

  char *pA = A;

 

  //替换分析

  *(pA+1)  == A[1]     == char ===  pA[1]

 

  //替换分析

  *(ppE+1) == ppE[1]  == char * === pE[1]


---------------------------------------指针函数与函数指针----------------------------------------------

 

  指针函数  ----->   返回值为指针的函数

 

  函数指针  ----->   指向函数的指针  ----->  存放函数地址的指针

E.g

 int  addint x ,int y   ---->   整型函数

 {

       return  x+y;

 }

 

 //指针函数  -----> 在函数体内开辟一段内存空间,然后返回该内存空间的地址。

 //          -----> 调用系统中分配内存的函数,完成空间申请

 //          ----->  malloc   &&  free

 //      void *malloc(size_t size);    ----> 堆内存,手动分配,手动释放----不释放导致内存泄漏

 //      void free(void *ptr);

 

 char* alloc_xxint size   ---->   整型指针函数  ----> 返回值为整型指针

 {

       char *p;

       p = (char *)malloc(size);  ---->  分配内存  ----> 记得使用完毕后释放内存!!!!!

 

       return p;

 }

 

 free(p);

 

 void *   ---->  空类型指针,当分配的空间不知道采用何种数据类型操作时,是辅助指针运算使用的。如果已经明确分配的地址空间存放的数据类型,则需要类型转换。

 

//函数指针   ----> 在原始的函数类型声明的基础上,增加(*p) ---> 声明为指针类型

 

PARTNER CONTENT

文章评论0条评论)

登录后参与讨论
我要评论
0
7
关闭 站长推荐上一条 /3 下一条