指针
定义
访问内存地址 操控硬件
指针:
指针+基本数据据类
指针+数组
指针+函数
指针+指针
1.指针:就是地址-----就是内存的单元的编号
2.指针变量
语法:
基类型* 指针变量名;
基类型-------数据类型//基础数据类型 //数组类 //基类型表示指针变量 指向的目标的数据类型
* --------表示此时定义的白变量是一个指针类型的变量
指针变量名------标识符命名规则+见名知意
int *p;//表示定义了一个指针类型的变量
int *p = &a; //指针变量 p 指向 了 int型变量a
p变量的数据类型 int * //指针类型
&b --地址值 ---类型?
float
b有一块内存空间 -- 放的是float类型的数据
&b ---得到了一块 存放着 float类型数据的 空间的地址
指针访问变量.
间接访问 通过地址访问到的
指针的运算
* 指针运算符
* 单目运算
运算数必须是指针类型的值(地址)
*p 过程
1.首先拿出p指针变量中的值(地址) 到内存中定位
2.从定位处开始,偏移出sizeof(基类型)大小的一块空间
3.把这块空间当做一个 基类型的 变量来看
想实现:
被调修改主调
1.想修改谁,就把谁的地址传过去
2.必须要做*运算(间接访问),实现修改
练习:
求两个数的和 --函数
int add(int a,int b){return a + b; //只能带出一个结果 }#include <stdio.h>void Sum(int a,int b,int *sum) // 指针求和函数
{*sum=*a + *b;return ;
}int main (void)
{int a=2;int b=3;int sum=0;Sum(&a,&b,&sum);printf("sum=%d\n",sum);return 0;
}
练习:
找出两个数中最大值 最小值
#include <stdio.h>void compure(int a,int b,int *max,int *min) //比较函数
{if (a>b){*max=a;*min=b;}else{*max=b;*min=a;}
}int main(void)
{int a=0;int b=0;int max=0;int min=0;scanf("%d%d",&a,&b);compure(a,b,&max,&min);printf("MAX=%d\n",max);printf("MIN=%d\n",min);
}
练习:
main函数中有两个数据
交换a b的值
#include <stdio.h>void jiaohuan(int *a,int *b) //换位函数
{int c=*a;*a=*b;*b=c;
}int main(void)
{int a=0;int b=0;printf("a=");scanf("%d",&a);printf("b=");scanf("%d",&b);jiaohuan(&a,&b);printf("a=%d \nb=%d\n",a,b);return 0;
指针 + 数组
一维整型数组
int a[5]; //a首元素的地址
//a[0] -- int型
//&a[0] -- int *
int *p = &a[0];
= a;
a[i] <=> *(a+i) //指针运算
练习:
找最大值 ,指针的方式访问
#include <stdio.h>int Max(int *p,int len) // 擂台法求最大值函数
{int i=0;int t=*p;for (i=1;i<len;++i){if (*(p+i)>t){t=*(p+i);}}return t;
}int main (void)
{int a[10]={6,5,12,3,4,98,10};int *p=a;int q=Max(a,10);printf("Max=%d\n",q);return 0;
}
指针小总结
1.指针概念
a.指针 --- 地址 ---内存单元编号 //值
b.指针 --- 数据类型 ---指针类型 //类型
不同语境:
定义一个指针? //指针类型的变量
打印某个变量的指针? //指针 --地址
2.指针变量的定义
基类型 * 变量名
a.基类型
数据类型
基本数据类型
数组类型
指针类型
b. * //定义时候的 * 表示定义的是一个 指针类型的变量
c. 变量名
eg:
int a,b,*p,*q; //p和q都是指针类型的变量 *是修饰指针变量名的
int *p,q; //p是指针变量 q int型变量
注意:
1.指针变量的 大小 64位(8字节) 32位(4字节)
2.指针类型 --- 存储的是 地址 这种特殊的数据
指针变量的给值:
int *p; //野指针 --- 随机值 ---被当做了地址
//避免野指针 -- 一般初始化为NULL
*p 的执行顺序
step1: 拿p中地址值 到内存中定位
step2: 从定位处开始,偏移基类型大小的一块空间sizeof(基类型)
step3: 被当做了基类型变量来看
*p 整体就是一个基类型的变量
3.核心用途(80%)
被调修改主调
修改:
1.修改谁,就传谁的地址
2.*p(间接访问)运算
4.指针 + 一维整型数组
指针 操作 一维整型数组
int a[10];
int *p = a;
//1.数组本身的特点 (连续性,单一性,有序性)
//2.p+1 --- 偏移了一个积累性
通过指针访问到数组元素:
*(p+i) <=> int型的变量 <=> a[i] <=>p[i]<=> *(a + i)
5.指针运算
&
*
p+1
p++
p-1
p--
关系运算
> >= < <= == !=
p>q
指针运算 :指针互相不可做加法 +
指针同类型互相可以做减法-
非同类型 不可以
p-q
前提: 同一类型的指针
表示之间差了几个基类型
p+q //指针不能做加法运算
迭代
b
e
1 2 3 4 5 6 7 8 9 10
mid = begin + (e-b+1)/2;
int puts(const char *s);
const char * s;
const int a; //只读变量
int a = 10;
const int *p = &a; //表示 基类型 为只读
p --- 指针变量 --本身的类型 int *
a --- int型变量 --本身类型 int
p = &a;
const int *p = &a;
int const *p = &a; //就近原则 -- 离谁近,就限定谁的
int *const p = &a; //限定p为只读
const int * const p = &a; //p不能被修改,指向的目标类型不能被修改
//(是不能通过*p)
int puts(const char *s)
{
}//const char *s --在函数里面 不能通过*s修改到外面的数据
好处:
1.可以接收 字符数组名 //char *
也可以接收 字符串常量 //const char *
提高了参数的适用性
2.避免了 可能出现的修改的操作
可以将 运行时的错误,提前到 编译时发现
const char * p 可以用来保存字符串常量的地址
快速排序
const可以修饰任何一个变量名,使其变为只读类型的变量,在指针中,常有这两种用法:
int *const p = &a; const int *p = &a;我们可以通过就近原则去区分const修饰的是什么,前一个const修饰的是p,使指针变量p为只读类型,后一个限定的是指针指向的基类型,不能通过*p去修改指针指向的值。。但是要注意的是,c语言中的const有一定的局限性,const int *p=&a,虽然不能用*p去修改,但可以通过a=1;对原数赋值进行值的修改。
好处:
1.可以接收 字符数组名 //char *
也可以接收 字符串常量 //const char *
提高了参数的适用性
2.避免了 可能出现的修改的操作
可以将 运行时的错误,提前到 编译时发现