当前位置:   article > 正文

C语言——初识指针_c语言中*r=l有什么区别

c语言中*r=l有什么区别

目录

1.指针是什么

2.与指针有关的运算符

3.指针的初始化

4.基本类型指针

5.指针和数组

6.多级指针

7.指针变量的运算


1.指针是什么

       从根本上看,指针(pointer)是一个值为内存地址的变量(或数据对象)。比如char类型变量的值为字符,int 类型变量的值是整数,指针变量的值是地址。例如:

int * p;//定义了一个指针变量p,p的类型为int *,p指向的地址为 int 类型

通俗来讲,指针就是地址,地址就是指针,不过要注意的是,虽然我们在平时会将指针变量简称为指针,但指针变量和指针是有所不同的,指针变量是存放地址的变量,也就是存放指针的变量。

2.与指针有关的运算符

1) *  (星号)

C语言中*可以表示乘号,也可以表示指针符号。这两个用法是毫无关联的,只是恰好用了同一个符号而已,星号在用于指针时有两种用法:

①指针定义时,*结合前面的类型用于表明要定义的指针的类型;

②指针解引用,解引用时*p表示p指向的变量本身。

  1. int *p;//这是星号的第一种用法,定义了一个指针变量 P
  2. int *q ,*r;//当同时想定义两个或者多个指针时,也可以采用这样的语句
  3. int i=5,j;
  4. p = &i; //p保存了i的地址,p指向i
  5. j = *p;//这是星号的第二种用法,把p指向的地址上的值赋给j,此时j=5

2) & (取地址符)

取地址符使用时直接加在一个变量的前面,然后取地址符和变量加起来构成一个新的符号,这个符号表示这个变量的地址。

3.指针的初始化

指针初始化目的就是让指针知道指向那个地址。共有两种方式初始化指针:①在声明指针时便告诉指针指向地址;②不在声明指针的时候初始化,而是把地址直接赋值给指针变量。

注意:不可以在指针不清楚指向地址的情况下给指针赋值(但是char p=0或者p=NULL除外,该语句表示指针为空)。

①在声明指针时便告诉指针指向地址

  1. #include <stdio.h>
  2. int main (void)
  3. {
  4. int i=5;
  5. int *p=&i;
  6. return 0;
  7. }

②不在声明指针的时候初始化,而是把地址直接赋值给指针变量

  1. #include <stdio.h>
  2. int main (void)
  3. {
  4. int i=5;
  5. int *p;
  6. p = &i;
  7. return 0;
  8. }

③不可以在指针不清楚指向地址的情况下给指针赋值(错误

  1. #include <stdio.h>
  2. int main (void)
  3. {
  4. int i=5;
  5. int *p;
  6. *p = 5;
  7. return 0;
  8. }

4.基本类型指针

  1. int * p;
  2. int i=5,j;
  3. p = &i;//一个指针变量指向某个普通变量,则*指针变量等同于普通变量
  4. //对于此处即:*p=i=5 在所有出现 *p 或 i 的位置,两者可相互替换
  5. j = *p;//通过这几步,就可以将 i 的值 5 赋给 j

1)内存泄漏

指针指向一个地址,也就是一个空间,如果只给指针分配空间,而未释放掉分配的空间,就会导致内存泄漏,导致内存越用越少;但如果,有多个指针同时指向同一个空间,而进行多次内存释放,就会使程序崩溃,导致无法运行。

2)空指针NULL

空指针就是值为0的内存逻辑地址,当对逻辑地址0(NULL)所代表的内存进行读写操作时,程序就会崩溃。(返回值为指针的函数通常使用空指针作为失败时的返回值)

3)野指针

指向的位置不可知的指针。

出现原因:①声明指针后并未初始化

                  ②变量内存释放后,指针变量还保存着该变量的内存地址

5.指针和数组

一维数组名,是一个指针常量,他存放的是数组第一个元素的地址,例如:

  1. #include <stdio.h>
  2. int main (void)
  3. {
  4. int a[5];
  5. printf ("%d\n",&a[0]);//此处输出为a[0]的地址
  6. printf ("%d\n",a);//此处输出为数组名a的含义
  7. return 0;
  8. }

若两者输出结果相同,则说明一维数组名存放的是数组第一个元素的地址,运行程序输出结果如下: 

显然,两者输出结果相同,那么说明一维数组名存放的是数组第一个元素的地址。

指针和下标总存在着这样一个关系:如果 p 是一个指针变量,则 p[i] 永远等价于 *(p+i)

  1. # include <stdio.h>
  2. int main(void)
  3. {
  4. int a[5] = { 1,2,3,4,5};
  5. int i;
  6. for( i = 0 ; i < 5 ; i++ )
  7. {
  8. printf("%d " , a[i]);
  9. }
  10. printf ("\n");
  11. for(i = 0 ; i < 5 ; i++ )
  12. {
  13. printf("%d " , *(a+i));
  14. }
  15. return 0 ;
  16. }

运行程序,输出结果如下:

 由此便可以证明该关系,p[i] 等价于 *(p+i)

注意区分:

int (*p[10])的含义是定义了一个数组,数组名为p,其中包含10个指针,指针指向整型类型数据

int (*p)[10]的含义是定义了一个指针,指针指向一个数组,数组中有10个元素,元素类型为整型

6.多级指针

如果一个指针指向的是另一个指针,我们就成他为二级指针,或者指向指针的指针。

那么如果指针指向的是一个二级指针,我们就称他为三级指针.......

那么对于多级指针,我们又该如何操作呢?

  1. #include <stdio.h>
  2. int main (void)
  3. {
  4. int i=10;
  5. int *p = &i;//定义了一个一级指针, p 存放 i 的地址
  6. int **q = &p;//定义了一个二级指针,q 存放 p 的地址
  7. int ***r = &q;//定义了一个三级指针,r 存放 q 的地址 r是int ***类型,所以r只能存放int **类型变量的地址
  8. //r = &p;//这样写是错误的 r是int ***类型,所以r只能存放int **类型变量的地址 不能存放int *类型变量的地址
  9. printf ("%d\n",i);
  10. printf ("%d\n",*p);
  11. printf ("%d\n",**q);
  12. printf ("%d\n",***r);
  13. return 0;
  14. }
  15. /*
  16. ----------------
  17. 输出结果:10
  18. 10
  19. 10
  20. 10
  21. ----------------
  22. */

i p q r 之间的关系可通过下图来理解

7.指针变量的运算

指针变量不能相加 不能相乘 不能相除 

如果两个指针变量指向同一块连续空间中不同的储存单元,则这两个指针变量可以相减。

  1. int i=5;
  2. int j=10;
  3. int *p = &i;
  4. int *q = &j;

此时 p-q 并没有实际意义,若将 p 和 q 放入同一个数组中,p-q 才会有实际意义。

  1. #include <stdio.h>
  2. int main (void)
  3. {
  4. int a[5];
  5. int *p, *q;
  6. p = &a[1];
  7. q = &a[4];
  8. printf ("p和q所指向的单元相隔%d个单元\n",q-p);
  9. return 0;
  10. }

运行结果如下:

以上就是初次学习和了解指针后,我的理解和思考。

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/思考机器4/article/detail/63231
推荐阅读
相关标签
  

闽ICP备14008679号