指针高级运用

指针高级运用

指针基础

内存的最小单位是比特位bit.
内存最小管理单位是字节Byte 1B=8bit.
操作系统会给内存条中的每一个字节的内存段设置一个唯一的编号。
地址:代表一个字节的内存段。首地址:可以代表一段内存段。一般我们把地址和首地址的概念通用。
指针:数据存在的内存段的地址。指针本身也是一个变量,且其大小为4(32位平台)或8(64位平台)
定义变量:变量名绑定内存段。

int a,b;
a=10;
b=20;
int *p=NULL;//绑定的是一个内存段的地址
p=&a;//p绑定的内存段中保存的是a绑定的内存的地址,简单理解为p指向a
*p=11;//解引用,通过地址找到地址绑定的内存段
//此时a的值就是*p的值
//指针变量的数学运算带类型
p=p-3;//指针减小了三个int类型的长度。注意不要有野指针。

指针数组和数组指针

将相同类型的变量存储在一起。

int a[10];//这是一个数组,数组的元素为int类型数据
int *b[10];//这是一个数组,数组元素为int*类型数据 这就是指针数组
int (*pArr)[10];//这是一个数组指针,可以指向一个就有10个int数据的数组
pArr=&a;//给数组指针赋值

指针与数组

指针与一维数组

int a[10]={1,2,3,4};
int *p=a;
a[i],*(a+i),*(p+i)等价

指针与二维数组

//指针指向首行首元素
#include <stdio.h>

int main()
{
	int a[4][4]={1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16};
	int *b=&a[0][0];
	for(int i=0;i<4;i++)
	{
		for(int j=0;j<4;j++)
		{
			printf("%d ",*(b+i*4+j));//取某个元素的值
		}
		printf("\n");
	}
	printf("%p\n",b);
	return 0;
}
//指针指向首行首元素
#include <stdio.h>

int main()
{
	int a[4][4]={1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16};
	int (*c)[4]=&a[0];
	for(int i=0;i<4;i++)
	{
		for(int j=0;j<4;j++)
		{
			//printf("%d ",*(c[i]+j));//取某个元素的值
			printf("%d ",*(*(c+i)+j));
		}
		printf("\n");
	}
	printf("%p\n",c);
	return 0;
}

字符串

本质上就是一个以’\0’结尾的char类型数组。

char *p="hello world!";//存的是字面常量的首地址,*p="hello 世界!"会出错。
char str[20]="hello world!";//将文字常量区的内容拷贝到栈中。str="hello 世界!"没有问题。

指针常量和常量指针

  //const 修饰变量为只读
  const int n=10;
  n=66;//编译器会报错
  //const 修饰变量为只读,可通过指针操作(会开辟一段新的内存)
  const int n=10;
  int *p=(int *)&n;
  *p=666;//编译器不会报错
  printf("n:%d\n",n);//输出n:10
  printf("*p:%d",*p);//输出*p:666

指针常量:顾名思义它就是一个常量,但是是指针修饰的

  int a,b;
  int * const p=&a //指针常量
  //那么分为一下两种操作
  *p=9;//操作成功
  p=&b;//操作错误

常量指针:指向常量的指针。

  int a,b;
  const int *p=&a //常量指针
  //那么分为一下两种操作
  *p=9;//操作错误
  p=&b;//操作成功

指向常量的指针常量:指针本身是常量,且指向的内存也为只读内存

  int a,b;
  const int *const p=&a //常量指针
  //那么分为一下两种操作
  *p=9;//操作错误
  p=&b;//操作错误

函数指针和回掉函数

    int fun(char *); //声明一个函数,有一个char*类型的参数,返回值为int型 
    int a;  
    char str[]="abcdefghijklmn";  
    a=fun(str);//直接调用这个函数  
    /**************************************/
    这是函数得定义
    int fun(char *s)  
    {  
        int num=0;  
        for(int i=0;;)  
        {  
            num+=*s;s++;  
        }  
        return num;  
    }  

回调函数就是一个通过函数指针调用的函数。如果你把函数的指针(地址)作为参数传递给另一个函数,当这个指针被用来调用其所指向的函数时,我们就说这是回调函数。回调函数不是由该函数的实现方直接调用,而是在特定的事件或条件发生时由另外的一方调用的,用于对该事件或条件进行响应。
下面是一个通过函数指针调用函数得简单例子:

#include <stdio.h>
void print();
int main(void)
{
    void (*fuc)(); //定义一个函数指针
    fuc = print ; //给指针赋值
    fuc();//通过指针来调用函数 	
} 
void print()
{
  printf("hello world!\n");
}

但是这个例子并没有将函数指针传递给一个函数去作为参数。

#include <stdio.h>
 
int add_ret() ;
 
int add(int a , int b , int (*add_value)(int,int))//函数指针作为参数
{
	return (*add_value)(a,b);//通过函数指针来调用函数
}
 
int main(void)
{
	int sum = add(3,4,add_ret);
	printf("sum:%d\n",sum);
	return 0 ;
} 
 
int add_ret(int a , int b)
{
	return a+b ;
}

后记

要想理解好指针,关键是要理解好四个要素:指针的类型、指针所指向的内存的类型、指针所指向内存的位置和指针本身所占的位置

其他

大家也可以访问我的个人博客豆浆and油条er、个人公众号搜索:豆浆and油条er

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值