美文网首页编程ing
C语言的灵魂——指针

C语言的灵魂——指针

作者: 指尖极光 | 来源:发表于2017-03-04 17:53 被阅读73次

一、指针简介

1、什么是指针?

指针是一个变量,其值为另一个变量的地址,即内存地址的直接地址。做个比喻,假设将你比作变量,那么你身份证上的住址就是指针,根据你身份证上的地址可以找到你,即指针存的内容是你身份证上的住址。

指针有两种含义,一是作为数据类型,二是作为实体。

指针作为实体,是一个用来保存一个内存地址的计算机语言中的变量。指针一般出现在比较底层的程序设计语言中,如C语言。高级语言如Java一般避免用指针,而是引用。指针作为数据类型,可以从一个函数类型、一个对象类型或者一个不完备类型中导出。从中导出的数据类型称之为被引用类型(referenced type)。指针类型描述了一种对象,其值为对被引用类型的实体的引用。

指针可以用来有效地表示复杂的数据结构,可以用于函数参数传递并达到更加灵活使用函数的目的。使C语言程序的设计具有灵活、实用、高效的特点。

2、*与&操作符

取地址运算符(&):取变量的地址,即返回操作数的内存地址。&var 读作"var 的地址"。

间接寻址运算符(*):返回操作数所指定地址的变量的值。

3、如何使用指针?

使用指针时会频繁进行以下几个操作:

  1. 定义一个指针变量;
  2. 把变量地址赋值给指针;
  3. 访问指针变量中可用地址的值。

这些是通过使用一元运算符 * 来返回位于操作数所指定地址的变量的值。

#include <stdio.h>
int main (){
   int  var = 20;   /* 实际变量的声明 */
   int  *ip;/* 指针变量的声明 */
   ip = &var;  /* 在指针变量中存储 var 的地址 */
   printf("Address of var variable: %x\n", &var  );
   /* 在指针变量中存储的地址 */
   printf("Address stored in ip variable: %x\n", ip );
   /* 使用指针访问值 */
   printf("Value of *ip variable: %d\n", *ip );
   return 0;
}

当上面的代码被编译和执行时,它会产生下列结果:

Address of var variable: bffd8b3c
Address stored in ip variable: bffd8b3c
Value of *ip variable: 20

4、指针运算符

C 指针是一个用数值表示的地址。因此,您可以对指针执行算术运算。可以对指针进行四种算术运算:++、--、+、-。

假设 ptr 是一个指向地址 1000 的整型指针,是一个 32 位的整数,让我们对该指针执行下列的算术运算:

ptr++

在执行完上述的运算之后,ptr 将指向位置 1004,因为 ptr 每增加一次,它都将指向下一个整数位置,即当前位置往后移 4 个字节。这个运算会在不影响内存位置中实际值的情况下,移动指针到下一个内存位置。如果 ptr 指向一个地址为 1000 的字符,上面的运算会导致指针指向位置 1001,因为下一个字符位置是在 1001。

5、NULL 指针

在变量声明的时候,如果没有确切的地址可以赋值,为指针变量赋一个 NULL 值是一个良好的编程习惯。赋为 NULL 值的指针被称为空指针。NULL 指针是一个定义在标准库中的值为零的常量。请看下面的程序:
#include <stdio.h>
int main (){
int *ptr = NULL;
printf("ptr 的值是 %x\n", ptr );
return 0;
}

当上面的代码被编译和执行时,它会产生下列结果:

ptr 的值是 0

二、指针与数组

1、区别

C++/C程序中,指针和数组在不少地方可以相互替换着用,让人产生一种错觉,以为两者是等价的。数组是连续分配一串单元,数目开始定义的时候就必须固定下来,看起来整洁,但是写的程序是死程序,容易浪费内存。指针是存放一个地址值,表示指向某一个单元,可以用指针来索引单元。数组可以完成栈,堆,树等等的操作,它在编程时候的好处是非常的灵活,在构建思路的时候有很大的灵活性。

2、指针数组与数组指针

指针数组:array of pointers,即用于存储指针的数组,也就是数组元素都是指针。

数组指针:a pointer to an array,数组名本身就是一个指针,指向数组的首地址,即指向数组的指针。

int* a[4] ;   /* 指针数组      
                 表示:数组a中的元素都为int型指针     
                 元素表示:*a[i]   *(a[i])是一样的,因为[]优先级高于*/
int (*a)[4]  ;/* 数组指针      
                 表示:指向数组a的指针
                 元素表示:(*a)[i]   */

#include <stdio.h>
int main(void)
{
    int c[4]={1,2,3,4};
    int *a[4]; //指针数组
    int (*b)[4]; //数组指针
    b=&c;
    //将数组c中元素赋给数组a
    for(int i=0;i<4;i++)
    {
        a[i]=&c[i];
    }
    //输出看下结果
    printf("%d",*a[1]);//输出2就对
    printf("%d",(*b)[2]);//输出3就对
    return 0;
}

三、指针与字符串

C语言中没有特定的字符串类型,我们通常是将字符串放在一个字符数组中。字符数组归根结底还是一个数组,使用指针的方式来输出字符串:

#include <stdio.h>
int main(){
    char str[] = "http://www.jianshu.com/";
    char *pstr = str;
    int len = strlen(str), i;
    //使用*(pstr+i)
    for(i=0; i<len; i++){
        printf("%c", *(pstr+i));
    }
    printf("\n");
    //使用pstr[i]
    for(i=0; i<len; i++){
        printf("%c", pstr[i]);
    }
    printf("\n");
    //使用*(str+i)
    for(i=0; i<len; i++){
        printf("%c", *(str+i));
    }
    printf("\n");
    return 0;
}

四、指针与函数

函数指针:本身是一个指针,指向一个函数入口地址,通过该指针可调用其指向的函数,使用函数指针可实现回调函数。

#include <stdio.h>
void inc(int *val)
{
    (*val)++;
}
int main(void)
{
    void (*fun)(int *);
    int a=3;
    fun=inc;//fun是一个函数指针
    (*fun)(&a);
    printf("%d" , a);
}

指针函数:本身是一个函数,其返回值是一个指针。

#include <stdio.h>
float *find(float(*pionter)[4],int n);//函数声明
int main(void)
{
     static float score[][4]={{60,70,80,90},{56,89,34,45},{34,23,56,45}};
     float *p;
     int i,m;
     printf("Enter the number to be found:");
     scanf("%d",&m);
     printf("the score of NO.%d are:\n",m);
     p=find(score,m-1);
     for(i=0;i<4;i++)
         printf("%5.2f\t",*(p+i));
     return 0;
 }
float *find(float(*pionter)[4],int n)/*定义指针函数*/
 {
     float *pt;
     pt=*(pionter+n);
     return(pt);
 }

五、指针与引用

  1. 引用总是指向一个对象,没有所谓的 null reference 。所有当有可能指向一个对象也有可能不指向对象则必须使用指针。由于C++ 要求 reference 总是指向一个对象所以 reference要求有初值.由于没有所谓的 null reference 所以在使用前不需要进行测试其是否有值,而使用指针则需要测试其的有效性。
  2. 指针可以被重新赋值而reference则总是指向最初或地的对象。
  3. 必须使用reference的场合.Operator[]操作符由于该操作符很特别地必须返回 [能够被当做ssignment 赋值对象] 的东西,所以需要给他返回一个 reference。
  4. 其实引用在函数的参数中使用很经常。格式如下:
    void Get***(const int& a){} //这样使用了引用又可以保证不修改被引用的值

区别:

  • 指针是一个实体指向一块内存,它的内容是所指内存的地址;引用是某块内存的别名;
  • 引用使用时无需解引用(*),指针需要解引用;
  • 引用只能在定义时被初始化一次,之后不可变;指针可变;
  • 引用“从一而终”;
  • 引用没有 const,指针有 const,const 的指针不可变;
  • 引用不能为空,指针可以为空;
  • sizeof 引用”得到的是所指向的变量(对象)的大小,而“sizeof 指针”得到的是指针本身(所指向的变量或对象的地址)的大小;typeid(T) == typeid(T&) 恒为真,sizeof(T) == sizeof(T&) 恒为真,但是当引用作为成员时,其占用空间与指针相同(没找到标准的规定);
  • 指针和引用的自增(++)运算意义不一样。

相关文章

  • 1+1 不等于2? 来看这道奇怪的C语言题目

    对于很多C语言初学者来说,指针是一大难题! 但是指针也是c语言的灵魂,离开指针,可能c语言就只能处理小学数学题了。...

  • 浅谈C语言数组与指针的关系

    浅谈指针定义细节及其与数组的关系 前言 翁恺老师曾经说过,指针是 C 语言的灵魂,是使 C 语言成为 “C语言” ...

  • C语言的灵魂——指针

    一、指针简介 1、什么是指针? 指针是一个变量,其值为另一个变量的地址,即内存地址的直接地址。做个比喻,假设将你比...

  • C语言的灵魂-指针

    const指针: int const *p1;int *const p2 ;const int * const ;...

  • C语言05- 指针

    C语言05- 指针 13:指针 指针是C语言中的精华,也是C语言程序的重点和难点。 13.1:指针定义与使用 指针...

  • iOS Runtime之指针和结构体

    GitHub原文      有句话说: 指针是c语言的灵魂,无论学习任何一门编程语言,都绕不开指针这个话题,本文主...

  • 02-C语言的指针

    02-C语言的指针 目标 C语言指针释义 指针用法 指针与数组 指针与函数的参数 二级指针 函数指针 指针在C中很...

  • C语言指针总结大学霸IT达人

    C语言指针总结大学霸IT达人 C语言的指针是C语言区别其它语言的最主要的特定之一。有了指针,C语言就可以抛开所有束...

  • 带小白学C语言指针

    C语言里指针才是C语言的开始和指针;C语言里基本所有东西都是由指针演变而成; 指针是指向地址的变量,类型就是指针...

  • 在Swift中使用C语言的指针

    在Swift中使用C语言的指针 在Swift中使用C语言的指针

网友评论

    本文标题: C语言的灵魂——指针

    本文链接:https://www.haomeiwen.com/subject/vnfjgttx.html