C语言笔记(6)-指针

指针

  1. 指针变量定义

    在计算机内部每一个字节单元都有一个编号,称为地址。

    内存单元的地址称为指针,存放指针的变量称为指针变量。

    请记住上面两句话,因为这就是指针的本质。

    计算机位数对应于地址的字宽,32位计算机的字宽就是32位的,也就是4个字节。(所有类型(int*,char*,struct*,数组等)的指针都是32位的,即4个字节的)
    为什么呢?因为计算机的位数代表了其寻址能力,因为指针变量存放的是指针,也就是32位二进制数据,也就是4个字节。所以在遇到 别人让你求sizeof(指针变量),这个问题就变得很简单了,现在我们知道了32位的机器下面,这个值是4,64位机器下面这个值是8。好了,下次别人再问你这个问题,你可以反问他:你说的是多少位的机器?

指针定义形式如下:

类型说明符* 变量名

  • *表示一个指针变量,类型说明符表示指针所指向的数据类型。
  • 虽然所有的指针都等长,但是还要指明数据宽度,因为对指针变量的其他操作都涉及都涉及指针变量的数据宽度。(即指针所指向数据的类型)
  1. 指针变量的赋值

    ​ 指针变量定义以后,不能随便使用。指针变量的值只能是其所指向的变量的地址。不能是其他数据。

    ​ C语言中变量的地址是有编译系统分配的,用户不知道的。但是变量的地址可以用&运算符来查看变量的地址。形式如下:

    &变量名 // & —>取地址符

  2. 指针变量的引用

    • *------>指针运算符(间接存取运算符)
    • &------>取地址运算符

指针变量P的目标变量m,因此*P,m,*(&m)表达式的含义相同。

  • P-----指针变量,它的内容是地址
  • *P-----指针所指向的对象,它的内容是数据(即其所指向的变量的值)
  • &P------指针变量所在的存储区域的地址(注意这里的说法)
  1. 指针的运算

    ​ 指针运算是以指针变量所存放的值(地址量)作为运算量来进行的运算。指针的运算是指就是地址的计算。定义指针变量P:

    • p+n---->指针向地址方向大的方向移动n个数据

    • p-n----->指针向地址方向小的地方移动n个数据

    • +±----->++p,p++

    • – ------>–p,p–

    • p-q--------->两个指针之间相隔数据元素的个数

      p + x---->实际内存单元的地址量:p+x*sizeof(p指向的数据类型)

    • 注意:两个指针相减的结果值不是地址量,而是两个指针间的元素个数

    指针的关系运算:

    • 具有不同数据类型的指针之间的关系运算没有意义。指向不同独居区域的两个指针之间的,关系运算也没有意义。

    量个重要的表达式:

    • *p++–>同一优先级,从右向左运算,相当于*(p++),表达式的作用是在原p的值的基础上进行间接操作,将p值加1。表达式的值是提取原p的内容。(++在后,p先参与运算*P,再把p值后移一个数据宽度)
  2. 空指针

    空指针即指真指向了零号地址,可以用:int *p = 0;

    C 中一般用NULL来代表0,它可以表明一个指针当前为指向任何变量。

    在定义指针时,最好将指针初始化为0。

  3. 指针和数组

    数组名是一个地址,指针的一次相加是以其所指向的对象的数据宽度为单位进行移动。数组名 +i ---->数组名[i]

    指针的效率要高于数组下标。

    []是变址运算符,*(a+i)和a[i]无条件等价

    假设指针P指向数组a的首元素,那么素组元素有以下几种表达方式:a[i]<—>*a[i]<—>p[i]<—>*(p+i)

    数组名是地址常量,指着是地址变量,数组名可以被作为指针参与运算,但是不能被赋值

  4. 指针与二维数组

    二维数组可以看做是以一维数组为元素的特殊的一维数组。参与运算时以行为单位进行移动,也被称为行地址。二维数组a[3][2]

    • a[]—>第一行第一列元素的地址
    • a---->第一行的首地址,也等于第一行第一列元素的地址
    • a+1—>第二行第一列元素的地址
    • a[1][1]<->*(&(a[1][0])+1)<->*(a[1]+1)<->*(*(a+1)+1)

    当偏移量前的元素单元是整个素组时,偏移的单元是行,当偏移量前的元素单元是行时,偏移的单元是行中的元素。

  5. 多级指针

    指向一级指针变量的指针称为二级指针。

    二级指针: <存储类型> <数据类型> **<指针名>

  6. 指针数组

    指由若干个相同存储类型和数据类型指针变量构成的集合。

    定义形式:<储存类型> <数据类型> *<指针变量名> [<大小>]

    指针数组名实际为二级指针。

  7. const与指针

    const关键字的作用是使得变量常量化,即限制变量为只读。

    const int *a;

    int const *a;

    int *const a;

    const int *const a;

    前两个位限制指针变量a所指向的变量的值不能被修改;第三种形式时限定指针变量a的不能被改动。第四种为限制指针变量的值及其所指向的变量的值都不能修改。

    总结:

    • 1.指针变量名与const之间没有任何修饰符,限制指针变量为只读。即限定指针变量存储的地址值不能被改变
    • *2.指针指向的值为只读,const修饰(int )或者修饰*
  8. void指针

    • void类型的指针变量是一种不确定的指针变量,它可以通过强制类型转换,才能让指针变量指向其他数据类型。
    • 在没有强转之前void *类型的指针不能进行任何数据运算。
  9. 字符指针

    • 字符指针就是存储字符变量的地址
    • 利用字符数组对字符串进行遍历
    • 虽然字符数组名是字符串的首地址,但是数组名是一个常量,其值是不能改变的(不能进行自加、自减、赋值等操作),但如果把字符数组的首地址赋值给一个字符指针变量,就可以移动这个字符指针变量来访问每一个字符。

    字符指针数组:

    • 若数组中存储了若干个字符串的地址,则这个数组就叫做字符指针数组。例如:

      char s1[] = {"welcime"};
      char s2[] = {"to"};
      char s3[] = {"wuhan"};
      
      char *a1[] = {s1,s2,s3};
      char *a2[] = {"welcome","to","wuhan"};
      

      上面这段代码中,a1和a2都是字符指针数组。a1,a2存储的是一维指针的地址,所以,a1,a2也是二级指针。

发布了49 篇原创文章 · 获赞 15 · 访问量 9281

猜你喜欢

转载自blog.csdn.net/wit_732/article/details/97950316