C语言指针模块(通俗易懂)

每次都是在指针模块花费很多时间,就是不懂。看了很多大佬的博客,很多都很详细(我们不一定全都掌握,真正掌握的是我们常见的),同时作为一个比较懒的人来说,这实在是看的好累,为了使C语言指针更通俗易懂,专门写下这篇文章,可能有些理解地不是太深入,希望大家多多指出。

一、指针的基本概念

计算机中所有的数据都必须放在内存中,不同类型的数据占用的字节数都不一样。例如int占用4个字节。为了正确地范围这些数据,必须为内存区每个字节(每个内存单元)都唯一编号(如门牌号),我们将内存中每个字节地编号成为地址(Address)或指针(Pointer)。指针也是一种保存变量地址的变量

如一个4g(=4096MB,现实4g内存条=4X0.93G)内存中地每个字节地编号(16进制表示):

二、指针的用途

CPU 访问内存时需要的是地址,而不是变量名和函数名!变量名和函数名只是地址的一种助记符,当源文件被编译和链接成可执行程序后,它们都会被替换成地址。编译和链接过程的一项重要任务就是找到这些名称所对应的地址。然而指针保存就是地址。

例如:

(1)如果你想通过函数改变一个变量的值,就得用指针而不能用值传递。

(2)当对象的数据量实在太大,程序员就会用指针来做形参,只需要传递一个地址就行,大大提高了效率。

三、指针的声明

(1)在对指针进行间接访问之前,指针必须初始化(分配内存、指向现有的内存),也就是给指针一个合法的地址,让程序清楚指针指向哪儿。

///常见的指针声明
int *p;//指针p指向的内容类型为int型

char *p;//指针p指向的内容类型为char型

int *p[10];//数组里的元素是指针类型,p是一个指向内容类型为int型的数组(p是一个由返回整型数据的指针所组成的数组)

int (*p)[10];//指针所指向的内容是一个数组,p是一个指向由整型数据组成的数组的指针(区别是指针与数组的优先级)

int **p;//指针所指向的元素是指针

p=(int *)malloc(sizeof(int)*10);//malloc函数动态分配10个单元给p

(2)运算符“*”和“&”的区别

取地址运算符:&(变量名),获取变量的地址。

取值运算符:*(变量名或指针),将变量(指针)当做地址,到相应地址取值。

int *p;//指针变量
int a=10;
int **ptr;

p=&a;//p代表指针,指向变量a的地址,在这里也可以充当初始化指针变量p

*p=a;//*p代表整型,*p获取地址p中的内容(元素)

ptr=&p;//&p是个指针,指针类型是p的类型加个*(int **),该指针所指向的类型是p的类型(int *),所指向的地址是指针p自己的地址

*ptr=&b;//*ptr、&b都是指针,用&b给*ptr赋值。也就是说指针类型统一才能成立,(如*p=&a是不成立的)

**ptr=11;//原本*ptr的结果就是ptr所指向的内容,在这里*ptr是一个指针,对指针再做一次*运算,得到一个int类型的变量。

四、指针与(数组、结构类型、函数)的关系

(1)指针与数组的关系

   1)运用指针与数组的效率:在C语言中,指针与数组之间关系密切,一般来说,用指针编写的程序比用数组编写的执行速度快。

      如:int array[10]; int *p=array。

       

    2)定义数组时,要给出数组名和数组长度,数组名可以认为是一个指针,它指向数组的第一个元素。因此,在C语言中,我们可以称第一个元素的地址为首地址。

//以指针遍历数组
int arr[] = {5,6,1,9,8};
int len = sizeof(arr)/sizeof(int);//求数组的长度
for(int i=0;i<len;i++) 
  printf("%d ",*(arr+i));//*(arr+i)==arr[i];

3)讨论一下*++p、*p++、(*p)++、*(p++),它们的结果如何?

*++p:先进行地址p相加,然后再在新地址取值。

int a[3]={3,1,2};
int b=10;
int *p;
p=a;///先定义后初始化,等同于int *p=a;直接初始化

printf("%d\n",p);///初始化的地址
printf("%d\n",*++p);///输出1,*++p==*(++p)
printf("%d\n",p);///新的地址

p=&b;
printf("%d\n",*(++p));///输出3,按正常说,*()输出的是值,如果当前地址没有值,就只能输出当前地址
printf("%d\n",&b);///地址635632
printf("%d\n",p);///地址635632+4=635636
printf("%d\n",&a[0]);///地址635636

*p++==(*p)++==*(p++):*与++优先级等同,所以先取指向p的地址的元素,再++。

int a[3]={3,1,2};
int *p=a;

printf("%d\n",p);///初始化的地址
printf("%d\n",*p++);///输出3,
printf("%d\n",p);///新的地址

(2)指针与结构类型的关系

#include<stdio.h>
struct My{
   int a;
   int b;
};
int main(){
    struct My s = {3,2};
    struct My *ptr = &s;///声明了一个指向结构类型s的指针
    printf("%d\n",ptr->a);///指向运算符,p->a==*ptr
    printf("%d\n",ptr->b);///p->a==*(ptr+1)
}

(3)指针与函数的关系

//指针作为函数的参数
void swap(int *a,int *b){///地址不变,指针变量的内容发生改变
  int temp;
  temp=*a;
  *a=*b;
  *b=temp;
}
//指向函数的指针
返回值类型 (* 指针变量名)(形参);

int *fun(int x,int y);//返回值是指针
int (*fun)(int x,int y);//指向函数的指针

#include<stdio.h>
int max(int a,int b){
   return a>b?a:b;
}
int main(){
    ///int max(int ,int );//如果此函数在主函数后面,就不能省略
    int (*p)(int ,int );///定义一个指向函数的指针变量p
    int a,b,c;
    p=max;///获取函数的地址,给函数指针赋地址
    a=888,b=999;
    c=(*p)(a,b);
    printf("%d\n",max);///输出地址
    printf("%d\n",c);
}

 

  • 2
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值