C语言 指针 指针数组 数组指针 函数指针 无类型指针 内存泄漏 示例
程序员文章站
2022-07-07 11:38:22
...
指针
#include <stdio.h>
/*
变量的访问方式:
1.变量名 int a = 10;
2.地址 *(&a)
int *p; //指针变量,存放的是地址
p=&a; //给指针变量赋值
指针只有在定义一个指针变量的时候,才是指针的标识符
其他情况,都是一个运算符,此时*代表的是一个运算符,跟+-x/运算符类似,功能是取地址
*/
int main()
{
int ju=10;
int mei=9;
int *p1=&ju; //标签,代表一个指针变量
int *p2=&mei;
printf("ju=%d\n",ju);
printf("mei=%d\n",mei);
printf("ju的地址是%p\n",p1);
printf("mei的地址是%p\n",p2);
printf("通过地址来获取ju=%d\n",*p1);
printf("通过地址来获取mei=%d\n",*p2);
int array[3]={1,2,3};
printf("第一个元素的地址%p\n",&array[0]);
printf("第二个元素的地址%p\n",&array[1]);
printf("第三个元素的地址%p\n",&array[2]);
int i;
for(i=0;i<3;i++){
printf(" %d ",array[i]);
}
putchar('\n');
int *parray;
//parray=&array[0];//指针访问数组,等于下面这句
parray=array;
for(i=0;i<3;i++){
printf(" %d ",*parray);
parray++;
}
putchar('\n');
return 0;
}
指针数组
#include <stdio.h>
int main()
{
int a=1;
int b=2;
int c=3;
int *parray[3]; //定义指针数组,元素是指针变量,指针变量是存放地址的变量
parray[0]=&a; //地址存入指针数组
parray[1]=&b;
parray[2]=&c;
int i;
for(i=0;i<3;i++){
printf(" %d ",*(parray[i]));
}
return 0;
}
指针死怼这些事
#include <stdio.h>
/*
1.指向谁(类型) p=&a
2.偏移后指向谁(p++) int *p; p++偏移了4个字节 char *p; p++偏移了1个字节
*/
int main()
{
int a;
a=10;
char c;
c='A';
int *p1;
p1=&a;
char *p2;
p2=&c;
printf("变量名a=%d\n",a); //10
printf("地址a=%d\n",*(&a)); //10
printf("指针a=%d\n",*p1); //10
printf("指针c=%c\n",*p2); //A
int array[3]={1,2,3};
int *p3;
p3=array;//p3=&(array[0])
int i;
for(i=0;i<3;i++){
printf(" %d ",array[i]);
}
printf("\n====================\n");
for(i=0;i<3;i++){
printf(" %d ",*p3);
p3++;
}
putchar('\n');
return 0;
}
为什么要用指针
#include <stdio.h>
//为什么要用指针
//1.让a(10),强制保存在我要的地址 0060ff00
void swap(int *a, int *b) //把地址中的值拿来做变换
{
int tmp;
tmp=*a;
*a=*b;
*b=tmp;
}
void jiajiaA1(int *p) //把地址中的值加1
{
*p=*p+1;
printf("jia1:a=%d\n",*p);
}
void jiajiaA2(int q)
{
q=q+1;
printf("jia2:a=%d\n",q);
}
int main()
{
int a; //a的地址由系统随机分配
a=10;
int b;
b=5;
int *p;
p=&a;
printf("a address is %p\n",p);
int *p2=(int *)0x0060ff00; //常用在ARM架构,裸机编程 ARM驱动
*p2=10;
printf("在内存%p的位置,存放值是%d\n",p2,*p2);
// volatile int *p2=(volatile int *)0x0060ff00; //类型修饰符,不用寄存器
swap(&a,&b); //把地址传给swap函数,改变地址中的值
printf("a=%d\n",a); //5
printf("b=%d\n",b); //10
int q=10;
jiajiaA1(&q); //jia1:q=11
printf("jiajiaA1:a=%d\n",q); //q=11
q=10;
jiajiaA2(q); //jia2:q=11
printf("jiajiaA2:a=%d\n",q); // q=10
return 0;
}
数组指针
#include <stdio.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);
//上面四个都一样
printf("=========区别来了喔==========\n");
printf("p++结果是%p\n",++p); //+12
printf("p2++结果是%p\n",++p2); //+4
return 0;
}
函数指针
#include <stdio.h>
void printWelcome()
{
printf("欢迎来到函数指针\n");
}
int add(int a,int b)
{
return a+b;
}
int main()
{
//1.定义
void (*p1)();
//2.赋值
p1=printWelcome; //函数名就是地址,就像数组一样,数组名就是地址
//3.调用
p1(); //直接通过指针名字+()
(*p1)(); //取内容(*指针名字)()
int (*padd)(int a,int b); //格式要求很强(参数类型,个数,返回值)
padd=add;
int ret1=padd(1,2);
int ret2=(*padd)(2,3);
printf("ret1=%d ret2=%d\n",ret1,ret2); //3 5
return 0;
}
无类型指针
#include <stdio.h>
int main()
{
/*
int *a=(int *)malloc(3*sizeof(int));
int i;
for(i=0;i<3;i++){
a[i]=i;
}
for(i=0;i<3;i++){
printf("%d ",a[i]);
}
*/
int n;
printf("请输入整型数组元素个数:\n");
scanf("%d",&n);
printf("n=%d\n",n);
//int parray[n]; //4种方法:3合法,最后一种教材说非法,就是上面输入n再int参数带n
int *parray = (int *)malloc(n*sizeof(int)); //数组,这个总可以了吧
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++);
}
return 0;
}
内存泄漏
/*
内存泄漏*
1.现象:
程序刚跑起来很好,跑几个小时或几周程序崩溃
while(1){
sleep(1);
int *p=malloc(1024); //malloc申请的空间,程序不会主动释放;Linux中,程序结束后,系统会回收这个空间
}
2.避免:
1.注意循环中有没有一直申请
2.及时合理的释放 free(p); p=NULL;
*/
//定义时最好初始化: int a=0; int*p=NULL;
指针收官
//1.定义整型变量i
int i;
//2.定义p为指向整形数据的指针变量
int *p;
//3.定义整型数组a,他有5个元素
int a[5];
//4.定义指针数组p,他由4个指向整型数据的指针元素组成
int *p[4]; //指针数组
//5.p为指向包含4个元素的一维数组的指针变量
int (*p)[4]; //数组指针 p++
//6.f为返回整型函数值的函数
int f();
//7.p为返回一个指针的函数,该指针指向整型数据
int *p();
//8.p为指向函数的指针,该函数返回一个整型值
int (*p)();
//9.p是一个指针变量,它指向一个指向整型数据的指针变量
int **p;
//10.p是一个指针变量,基类型为void(空类型),不指向具体的对象
void *p;