指针
1、 变量的两种访问方式
- 变量名:花店名
- 地址:花店的地址
2、 &取地址,取变量名所代表的的变量地址
int a;
&a(0x660cff0)
3、
*代表的是一种字符,跟+ - X /运算符类似,该运算符的功能是取出内存地址中
数据的值(取内容)
4、指针=地址
指针变量
- 存放指针的变量
- 存放地址的变量
5、变量
- 整型变量,存放的是整数:int a ; a=10;
- 字符变量,存放的是字符:char c; c=‘A’;
- 指针变量,存放的是指针:int *p; p=&a; char *p 1; p1=&c;
6、指针的作用
- 指针分类型
- 指针根据类型不同,偏移地址也不同
- 指针和数组:数组首地址
//数组名
int array[10]; int *p; p=array;
//第一个元素的地址
int array[10]; int *p; p=array[0];
eg:
#include<stdio.h>
#include<stdlib.h>
int main()
{
int a = 10;
int *p;
p = &a;
ptintf("a address is %p\n",p);
volatile int *p2 = (volatile int *)0x60ff00;
*p2 =10;
printf("在内存中的%p位置,存放的值为%d\n",p2,*p2);
system("pause");
return 0;
//volatile和编译器的优化有关:
//在本次线程中每当读取一个变量时,为了提高读取速度,编译器进行优化时
//会先把变量读取到一个寄存器中,以后再读取变量值时,就直接从寄存器中
//读取;当变量值在本线程中改变时会同时把变量的心值copy到寄存器中,以保持一致
//当变量因呗的线程值发生改变,上面的寄存器值就不会改变,从而造成应用程序
//读取的值与实际的变量值不一致;当寄存器因别的线程改变了值,原变量的值也不会
//改变,也会造成应用程序读取的值和实际的变量值不一致。
}
eg2:
#include<stdio.h>
#include<stdlib.h>
void swap(int *a,int *b)
{
int tmp;
tmp = *a;
*a = *b;
*b = tmp;
}
int main()
{
int a=10;
int b=5;
swap(&a,&b);
printf("a =%d\n",a);
printf("b = %d\n",b);
system("pause");
return 0;
}
输出结果:
a=5
b=10
7、指针数组:指针的数组,好多指针存放在一起,是一个数组,数组中的每一个元素都是一个指针变量;白话就是好多变量的地址的集合
#include<stdio.h>
#include<stdlib.h>
int main()
{
int a = 2;
int b = 3;
int c = 4;
int i;
int *parray[3];
parray[0] = &a;
parray[1] = &b;
parray[2] = &c;
for(i=0;i<3;i++){
printf("%d ",*(parray[i]));
}
system("pause");
return 0;
}
输出结果:
2 3 4
8、数组指针:一个指针变量,真正指向某个类型数组的指针,以前我们的指针指向数组的头,此指针明确规定了要指向数组的类型个大小。
数组的指针,强调的是类型,数组的个数,偏移值是偏移了整个数组的大小
#include<stdio.h>
#include<stdlib.h>
int main()
{
int a[3]={1,2,3};
int (*p)[3];//数组指针
p = a;
int *p2;//指针
p2 = a;
printf("数组的地址是%p\n",a);//数组名
printf("数组的地址是%p\n",&a[0]);//数组的第一个元素的地址
printf("p数组的地址是%p\n",p);
printf("p2的地址是%p\n",p2);//0x60FEEC
printf("--------------区别来了-------------\n");
printf("p++的地址%p\n",++p);//0x60FEF8
printf("p2++的地址是%p\n",++p2);//0x60FEF0
system("pause");
return 0;
}
9、函数指针:一个指针变量,存放的是函数的地址;
eg:
void (*introduce)(char *name,char *address,char sex,int num );
void *p2();//定义
p2 = printfWelcome;//赋值
p2();//调用
include <stdio.h>
#include <stdlib.h>
int add (int a,int b)
{
return a+b;
}
//如何表示指针:* ;如何知道是函数:();函数指针是专用的,格式要求很强(参数类型,个数,返回值),就像数组指针一样
int main()
{
int (*padd)(int a,int b);//定义一个函数指针
padd = add;//赋值
int ret = (*padd)(1,2);//函数调用
printf("ret=%d\n",ret);
system("pause");
return 0;
}
10、无类型的指针:一个指针变量,不知道指向的空间是什么属性
#include <stdio.h>
#include <stdlib.h>
int main()
{
int n;
printf("请输入学生的个数\n");
scanf("%d",&n);
printf("n=%d\n",n);
int *parray = (int *)malloc(n * sizeof(int));//开辟n*4个空间
if(parray == NULL)
{
printf("开辟空间失败\n");
}
int i;
for(i=0;i<n;i++){
printf("请输入第%d个学生的成绩:\n",(i+1));
scanf("%d",&parray[i]);
}
for(i=0;i<n;i++)
{
printf("第%d个学生的成绩是:%d\n",(i+1),*parray++);
}
system("pause");
return 0;
}
malloc:申请的空间,程序不会主动释放,Linux中的话,程序结束后,系统会自动回收这个空间;
内存泄漏:程序刚爬起来没啥事,跑了一段时间后程序就崩溃了
如何避免:
- 注意循环中有没有 一直申请
- 及时合理的释放;free ( p) ; p = NULL;