指针专题一

指针专题一

1.指针的基本用法

掌握指针的基本用法,我学习了很久的指针了,还是不理解,可以想一下为啥还是不理解。
自己并没有那种非常的专注的去学习,最重要的是学习之后,没有进行,总结思考。

c程序设计使用指针可以:

  1. 使程序简洁、紧凑、高效
  2. 有效的表达复杂的数据结构
  3. 动态的分配内存
  4. 得到多于一个的函数返回值

1.1 常见的指针名词:

地址: 在计算机内存中,最小的单位是字节。每一个字节(单元),都有一个编号,称为地址。
指针: 在C语言当中,内存单元的地址称为指针。
指针变量:专门用来存放地址的变量,称为指针变量(也叫做地址变量)。

补充理解

  1. 内存是以字节(1BYTE==8BIT)8位 作为最小的单位的。
    就像一栋楼是以一个房间为最小单位的。比如快递员送快递,送到63栋2单元602 一样,送到602这个门里面。602被认为最小单元,而不是哪一间屋子。(主要是考虑到使用的价值)

  2. 所说的变量的地址,一般的说的是首地址,(起始地址,地址是连续的。)
    在不影响理解的情况中,有时对地址、指针和指针变量不区分,统称为指针。

  3. 再重复一次概念:在内存中每一块内存都有它的编号,(这个编号叫地址,请分清地址和内存的区别,)这个编号叫做指针(如上,内存单元的地址称为指针。)
    4

1.2 指针

指针变量的说明:
一般形式如下:
<存储类型> <数据类型> * <指针变量名>
例如普通变量:
auto int m;
指针变量:
auto int * P; 指针的英语 pointer

说明:
指针指向的内存区域中的数据称为指针目标,
如果他指向的区域是程序中的一个变量的内存空间,则这个变量称为指针的目标变量,简称为指针的目标。
在这里插入图片描述
如上面图片,我定义了一个变量
double x =-126;
int *px;
px=&x;

那么X的数值本来就是 x= -126; &x是变量x在内存中的起始地址, (&x)就是 地址取 ,也是X的数据,

要想获得指针的目标,给他加上*,,也即是 px。。这里的 * 和 int * 的 “ * ” 不是一个意思,int * 是定义了指针的类型。 单纯的 * 是指我通过 我就可以找到我的指针的目标。通过 * 我就可以找到指针指向的地址里面的数值。

  1 #include <stdio.h>
  2 #include <stdlib.h>
  3 
  4 
  5 int main(int argc, const char *argv[])
  6 {
  7     int a=1314;
  8     int * p=NULL;
  9     p=&a;
 10 
 11     printf("a=%d,&a=%p,*(&a)=%d\n",a,&a,*(&a));
 12     printf("p=%p,*p=%d,sizeof(p)=%ld,sizeof(*p)%ld\n",p,*p,sizeof(p),sizeof(*p))
 13 
 14     return 0;
 15 }                                                                               
~         
linux@ubuntu:~/everyday/2020-8-3/poninter_1$ ./test 
a=1314,&a=0x7ffff96aa1dc,*(&a)=1314
p=0x7ffff96aa1dc,*p=1314,sizeof(p)=8,sizeof(*p)4

特别注意:引入指针要注意程序中的  PX*PX&PX三者所代表的意思。

1.  PX----指针变量,他的内容是指向的变量的地址
2. *px ----指针所指向的目标,他的内容是数据
3.  &px ----指针变量的地址,(指针变量占用的存储区域的地址,是个常量)

指针变量自身也是有地址的,(比如快递员自己也会取网购啊)

指针的赋值运算指的是指:通过赋值运算符向指针变量送一个地址数值。
向一个指针变量赋值的时候,送的值必须是地址常量或者指针变量。不能是普通的整数(0除外)。
指着赋值运算,常见的有以下的几种形式。

  1. 把一个普通变量的地址赋值给具有相同数据类型的指针
    double x=3.14 ,*p;
    p=&x;

  2. 把一个已经有了地址值的指针,赋值给具有相同类型的另外的一个指针变量。
    float x ,* px,* py;
    px =&x;
    py=px;

  3. 把一个数组的地址赋值给具有相同数据类型的指针。例如:
    int a[20],*pa;
    pa=a; //他是等价于 pa =&a[0]的。

总结与思考:
主要介绍指针相关的内容,包括指针的概念、理解、指针变量的说明和赋初值。

什么是指针:
内存以字节为最小单位,进行划分,字节的编号,叫做地址,在C语言中,内存的地址就叫做指针。
专门存放地址的变量,就叫做指针变量。也简称指针。

我调了一个代码,但是对指针占多少字节并不是清楚的, 4字节? 8字节??
需要看计算机的操作系统是啥。

2.指针的运算

1. 指针运算是以指针变量所存放的地址量作为运算量而进行的运算。
2. 指针运算的实质就是地址的计算。
3. 指针运算的种类是有限的,他只能够进行赋值运算,算数运算和关系运算。

2.1指针的算数运算 :

(+ px+n : 指针向地址大的地方移动n个字节)
(- px-n : 指针向地址小的地方移动n个数据)
(++ px++ : 指针向地址大的方向移动一个数据)
(-- px-- :指针向地址小的方向移动一个数据)

  1 #include <stdio.h>
  2 
  3 int main(int argc, const char *argv[])
  4 {
  5     int a=10,*p;
  6     double b=3,*q;
  7     p=&a;
  8     q=&b;
  9     
 10     printf("%p %p\n",p,p+2);
 11     printf("%p %p\n",q,q+2);
 12     
 13     return 0;
 14 }
~      
linux@ubuntu:~/everyday/2020-8-3/poninter_2$ ./a.out
0x7ffcb00b64cc 0x7ffcb00b64d4  
0x7ffcb00b64d0 0x7ffcb00b64e0

以上是一个运算 注意:
第一 int 占四个字节
第二 指针指向的是首地址,
第三 不同的数据类型的两个指针实行加减整数的运算是无意义的。
第四 px+n表示的实际位置的地址量是: (px)+sizeof(px的类型)*n

指针做运算的意义是什么?

两个指针相减运算:

  1. px- py 运算的结果是两指针指向的地址位置之间相隔数据的个数。两指针相减不是两指针持有的地址值相减的结果。
  2. 两指针相减的结果值不是地址量,而是一个整数值,表示两个指针之间相隔数据的个数。
1 #include <stdio.h>
2 
3 int main(int argc, const char *argv[])
4 {
5     int a1=10,*p;
6     double b=3,*q;
7     p=&a1;
8     q=&b;
9 
10     int a[5]={1,2,3,4,5};
11     int *px,*py;
12     px=a; //px=&a[0]
13     py=&a[3];
14 
15     printf("%p %p\n",p,p+2);
16     printf("%p %p\n",q,q+2);
17     
18     printf("%p %p\n",px,py);
19     printf("%d %d\n",*px,*py);
20     printf("%d\n",py-px);
21     
22     return 0;
23 }   
~    
linux@ubuntu:~/everyday/2020-8-3/poninter_2$ ./a.out 
0x7ffe1bbd6924 0x7ffe1bbd692c
0x7ffe1bbd6928 0x7ffe1bbd6938
0x7ffe1bbd6950 0x7ffe1bbd695c
1 4
3

2.2指针运算符:

在这里插入图片描述

2.3指针关系运算:

  1. 两个指针之间的关系运算表示他们指向的地址位置之间的关系,指向地址大的指针大于指向地址小的指针。
  2. 指针与一般的整数变量之间的比较没有意义,但是可以和0进行等或者不等的关系运算,判断指针是否为空。
  1 #include <stdio.h>
  4 int main(int argc, const char *argv[])
  5 {
  7     int a[]={5,6,7,8,9,10};
  8     int *p=&a[1],y;
  
 10     y= (*--p)++;
 
 11     printf("y==%d\n",y);
 12     printf("a[0]==%d\n",a[0]);
 14     return 0;
 15 }
linux@ubuntu:~/everyday/2020-8-3/poninter_3$ ./a.out
 y==5
 a[0]==6

这个是一个很好的例子。

程序举例中:注意指针当前的值。
在这里插入图片描述

 1 #include <stdio.h>
 2 
 3 int main(int argc, const char *argv[])
 4 {
 5     int i ,*p,a[7];
 6     p=a;
 7     for(i=0;i<7;i++)
 8     {
 9         scanf("%d",p++);
10         printf("  ");   
11     }
12     p=a;
13     for (i=0;i<7;i++)
14     {
15         printf("%d",*p);
16         printf("  ");   
17         p++;
18     }
19 
20     return 0;
21 }
22 
23 
linux@ubuntu:~/everyday/2020-8-3/poninter_4$ ./a.out 
44 
45
45
47
48
49
45
44  45  45  47  48  49  45  linux@ubuntu:~/everyday/2020-8-3/poninter_4$ 

这是一个很有意思的例子,要时刻注意指针指向的位置,不然就会出现指针在自加的时候出现越界。

思考:

  1. 注意指针在移动的过程当中,要注意指针是否会越界。要注意指针当前的值,需不需要做修正。
  2. 指针运算的本质:对地址的运算
  3. 指针+1移动多少个字节? 移动n个目标数据类型。

3.指针与数组

  1. 指针与数组(指针去访问数组,去遍历数组)

指针与数组

  1. 在C语言中,数组的指针是指数组在内存中的起始地址,数组元素的地址指数组元素在内存中的起始地址。

  2. 一维数组的数组名为一维数组的指针(起始地址)

    例如:double x[8];
    因此,x为x数组的起始地址。
    设指针变量 px的地址值等于数组指针x(也即是指针变量PX指向数组的首元素)
    则:
    x[i] *(px+i) *(x+i) px[i]
    这四种具有完全相同的功能,
    貌似形式上相同的 x[i]和px[i],其实并不相同,一个是常量(x[i]),一个是变量px[i]。

px[i] ======*(px+i);

在这里插入图片描述

  1 #include<stdio.h>
  2 
  3 int main(int argc, const char *argv[])
  4 {
  5 
  6     int a[]={1,2,2,3,5,9,7,99};
  7     int *p ,i,n;
  8     p=a;
  9     n=sizeof(a)/sizeof(int);
 10     for(i=0;i<n;i++)
 11     {
 12         printf("%d  %d  %d  %d",a[i],*(p+i),*(a+i),p[i]);
 13         printf("\n");
 14     }
 15 
 16         printf("\n");
 17         printf("%p  %p  %p  ",a,a+1,a+2);
 18         printf("%p",&a[0]);
 19                                                                            
 20         printf("\n");
 21         printf("a[3]==%d",a[3]);        
 22         printf("\n");
 23         
 24         printf("*(p+3)==%d",*(p+3));
 25         printf("\n");
 26         
 27     //  a++;
 28         p++;
 29     
 30 
 31     return 0;
 32 }
~                                                                              
~                                                                              
~                                                                              
~     

linux@ubuntu:~/everyday/2020-8-3/poninter_5$ ./a.out 
1  1  1  1
2  2  2  2
2  2  2  2
3  3  3  3
5  5  5  5
9  9  9  9
7  7  7  7
99  99  99  99

0x7ffe579ed6b0  0x7ffe579ed6b4  0x7ffe579ed6b8  0x7ffe579ed6b0
a[3]==3
*(p+3)==3

程序举例:

编写一个函数,将整形数组中 n 个数按照反序存放。

  1 /* 编写时间:2020-8-3
  2  * 编写一个函数,将整形数组中 n 个数按照反序存放。
  3  * 使用指针的形式。
  4  * 
  5  */
  6 
  7 #include <stdio.h>                                                         
  8 #define N 10
  9 
 10 int main(int argc, const char *argv[])
 11 {
 12     int a[N]={1,2,3,4,5,6,7,8,9,10};
 13     int *p ,*q;
 14     
 15     p=a;
 16     q=&a[N-1];
 17 
 18     while(p<q)
 19     {
 20      
 21     int t=*p;
 22         *p=*q;
 23         *q=t;
 24         p++;
 25         q--;
 26     }   
 27     
 28     for(int t=0;t<N;t++)
 29     {
 30         printf("%d ",a[t]);
 31     }   
 32     
 33     return 0;
 34 }   
~      
linux@ubuntu:~/everyday/2020-8-3/poninter_6$ ./a.out 
10 9 8 7 6 5 4 3 2 1 linux@ubuntu:~/everyday/2020-8-3/poninter_6$ 

4.指针与二维数组

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值