C语言_(11)_指针的高级用法

目录

1 指针的基本概念 

2 二级指针 

3 指针的算术运算

4 void 指针

5 const 指针

6 指针数组和数组指针

1 指针数组

2 数组指针

​7 指针和数组的关系

 1 指针和一维数组的关系

 2 指针和二维数组的关系

 3 访问数组元素的方式


1 指针的基本概念 

1 地址:用来区分内存中不同字节的编号

2 指针:地址就是指针,指针就是地址

3 指针变量:一个存储地址的变量

4 &:这个符号是用来获得一个变量在内存空间中的首地址,并且让表达式类型升级。                    例如int型--->>int*型。

5 *:这个符号如果在表达式=右边,表示取指针指向空间的值(所取得的空间大小取决于指针的类型)。如果在表达式=左边,表示将右边的值放入指针指向的空间。也有让表达式类型降级的作用。例如int*型--->>int型。

如 下图,四个字节来存储整型100,八个字节来存储指向这个整型变量首地址的指针。

2 二级指针 

我们称作指针为存储一个变量地址的变量,但是我们要存储指针的指针呢?那就要用到二级指针了。

int num = 0;

int *pnum = #

int **ppnum = &pnum;                                                                                                               

下面用一个程序来解释

#include <stdio.h>

int main(int argc, char const *argv[])
{
          int num = 100;
          int *pnum = &num;
          int **ppnum = &pnum;

          printf("num = %d\n",num);
          printf("*pnum = %d\n",*pnum);
          printf("**ppnum = %d\n",**ppnum);
          printf("&num = %p\n",&num);
          printf("pnum = %p\n",pnum);
          printf("*ppnum = %p\n",*ppnum);
          printf("&pnum = %p\n",&pnum);
          printf("ppnum = %p\n",ppnum); 
        
          return 0;
}

 

然而二级指针在C语言中两个地方使用:

 1 函数体内部想修改函数体外部指针变量值的时候,传指针变量的地址也就是二级指针。

 2 指针数组传参时,数组的数组名是指向数组第一个指针元素的指针。

3 指针的算术运算

+         -         ++          --

指针偏移量为指向的数据类型大小个字节空间

int* :4

char* :1

double* :8

int** :8

4 void 指针

void *p;

常用来指向一个存储内存地址,没有指向空间大小的含义。

void*类型的指针不要用来使用取*或者++ --的相关操作。

void *型指针和其余类型指针的转换,不需要做强制类型转换。

用途

用在作为函数参数,或者函数返回值表示兼容所有类型的指针。

1 memcpy(void *dest,const void *src, size_t n);内存拷贝函数的参数定义

2 memcmp(const void *s1,const void *s2,size_t n);

一个例题:将内存地址为0x2000的空间赋值一个整型100 (0x2000是一个void *类型的地址)

           (*(int *)((void*)0x2000)) = 100;  或者(* (int *)0x2000) = 100;

5 const 指针

1. const int *p;

2. int const *p;

3. int *const p;

4. const int *const p;

5. int const *const p;

1和2是等价的,const修饰的是*p,及p指向的空间不能改变(只读),但是p可以修改。(比如strcpy函数的const char *src参数,及我们不能修改源)。可以用,不能改。

3中const修饰的是p,及p不能改变,但是*p可以改变,所以一定要初始化,因为在程序中p只能指向初始化时的空间,无法指向其他空间,但可以利用指针修改p指向空间的值。(比如数组的数组名,永远指向第一个元素的首地址,我们可以修改第一个元素的值)。

4和5是等价的,const修饰的是p和*p,地址和指针指向的空间都不能改变。必须初始化。

6 指针数组和数组指针

1 指针数组

指针数组:

指针数组是一个数组,也就是指针的数组,这个数组里面每一个元素都是指针。

int *p[5];

比如上面,定义一个数组p,数组里面有五个元素,每个元素8个字节,总共40个字节,每个元素都是指向整型变量的指针。

整型的指针数组一般用的较少,在C语言中一般用的多的是字符型指针数组(char *pstr[5])

代码理解一下

#include <stdio.h>

int main(int argc, char const *argv[])
{
          char *pstr[5] = {"hello","world","how","are","you",};
          for(int i = 0;i < 5;i++)
          {
                    printf("str[%d] = %s\n",i,pstr[i]);
          }
          return 0;
}

一般情况,存储字符串用二维数组,操作字符串用指针数组。

比如我们用冒泡排序来排序字符串数组,其中交换的是地址,而不是改变字符串。

如下例代码说明

in(int argc, char const *argv[])
{
          char *pstr[5] = {"hello","world","how","are","you",};
          int i = 0;
          int j = 0;
          char *ptmp = NULL;
          for(i = 0;i < 5 -1;i++)
          {
                    for(j = 0;j < 5 -1 - i;j ++)
                    {
                              if(strcmp(pstr[j],pstr[j + 1]) > 0)
                              {
                                        ptmp = pstr[j];
                                        pstr[j] = pstr[j + 1];
                                        pstr[j +1] = ptmp;
                              }
                    }
          }

          for(i = 0; i < 5; i++)
          {
                    printf("%s\n",pstr[i]);
          }
          return 0;
}

2 数组指针

 数组指针是一个指针,指针指向数组,指针占八个字节。

int (*a)[5];

int a[5];

&a:int (*)[5]

1 对一维数组数组名&操作,值不变类型升级为数组指针。

2 对数组指针取*操作,值不变类型降级为指向数组第一个元素的指针

代码说明一下

#include <stdio.h>

int main(int argc, char const *argv[])
{
          int (*p)[5] = NULL;
          int a[5] = {1,2,3,4,5,};
          p = &a;

          printf("a = %p\n",a);
          printf("&a = %p\n",&a);
          printf("*a = %d\n",*a); 
          printf("*&a = %p\n",*&a);
          printf("========================\n");
          printf("p = %p\n",p);
          printf("p + 1 = %p\n", p+1);
          printf("*p = %p\n",*p);
          printf("*p + 1 = %p\n", *p+1); 
          return 0;
}

 7 指针和数组的关系

 1 指针和一维数组的关系

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

数组的数组名是指向数组第一个元素的指针。

a = &a[0]

访问数组元素的方式:a[n] = *(a + n) 

 2 指针和二维数组的关系

二维数组的数组名a是指向数组第一行元素的数组指针。

#include <stdio.h>

int main(int argc, char const *argv[])
{
          int a[2][3] = {1,2,3,4,5,6};

          printf("================================\n");
          printf("&a[0][0] = %p\n",&a[0][0]);
          printf("&a[0][1] = %p\n",&a[0][1]);
          printf("&a[0][2] = %p\n",&a[0][2]);
          printf("&a[1][0] = %p\n",&a[1][0]);
          printf("&a[1][1] = %p\n",&a[1][1]);
          printf("&a[1][2] = %p\n",&a[1][2]);
          printf("================================\n");
          printf("a = %p\n",a);
          printf("a + 1 = %p\n",a + 1);
          printf("================================\n");
          printf("a[0] = %p\n",a[0]);
          printf("a[0] + 1 = %p\n",a[0] + 1);
          printf("a[1] = %p\n",a[1]);
          printf("a[1] + 1 = %p\n",a[1] + 1);
          printf("================================\n");
          printf("*a[0] = %d\n",*a[0]);
          printf("*(a[0] + 1)= %d\n",*(a[0] + 1));
          printf("*a[1] = %d\n",*a[1]);
          printf("*(a[1] + 1) = %d\n",*(a[1] + 1));
          printf("================================\n");
          printf("*a = %p\n",*a);
          printf("*(a + 1) = %p\n",*(a + 1));
          return 0;
}

 

 3 访问数组元素的方式

a[m][n] = *(a[m] + n) = *(*(a + m) + n)

*(p + m * N + n)

猜你喜欢

转载自blog.csdn.net/m0_58193842/article/details/128369481