C语言笔记----指针(一)
程序员文章站
2022-07-15 10:02:48
...
指针(一)
指针的基本概念
根据指针指向的位置的不一样,指针也是有类型。
指针定义和使用
#include<stdio.h>
int main()
{
int x=0;
int* p=&x; //p 与 &x等价
printf("p:%p \t *p:%d\n",p,*p); //%p 打印地址 %d 打印p指向的值*p
getchar();
return 0;
}
int *p;定义一个int *类型指针,p只能指向int型地址
- 指针保存的是变量地址
p:存储的是地址
- 可以通过指针找到变量
*p:对p进行解引用,得到的是p指向地址的值,上述例子中的 0
指针在函数中的简单应用
用指针在函数中修改变量的值
#include<stdio.h>
void fun1(int x,int y) //交换两个变量的值
{
int temp=x;
x=y;
y=temp;
}
void fun2(int* x,int* y) //交换两个变量的值
{
int temp=*x;
*x=*y;
*y=temp;
}
int main()
{
int x=3,y=4; //定义x,y两个变量
printf("原参数:%d,%d\n",x,y);
fun1(x,y); //调用fun1()函数
printf("fun1():%d,%d\n",x,y);
fun2(&x,&y); //调用fun2()函数
printf("fun2():%d,%d\n",x,y);
getchar();
return 0;
}
打印结果:
原参数:3,4
fun1():3,4
fun2():4,3
内存模型
有人说是五区,把全局静态常量区分开,这个我就不深究
内存四区 | |
---|---|
代码区 | 存放代码二进制 |
全局静态常量区 | 全局变量、静态变量,字符串常量 |
栈区 | 函数内部定义的变量,包括主函数里面定义的变量 |
堆区 | 手动申请释放,指针管理malloc、free |
堆区
头文件:#include<stdlib.h>
- malloc 分配内存块
#include <stdlib.h> // For _MAX_PATH definition
#include <stdio.h>
int main()
{
char *p;
p = (char*)malloc( _MAX_PATH ); //#define _MAX_PATH 260
if( p == NULL )
printf( "内存申请失败\n" );
else
{
printf( "内存申请成功\n" );
free( p );
printf( "内存释放成功\n" );
}
return 0;
}
这是一个官方提供的malloc文档介绍
需要说明的是:
- malloc是一个函数,返回值是void*类型的指针,需要强转成其他类型才能使用
- malloc申请了一块内存后需要判断是否申请成功,并且用完之后要释放。
- 头文件#include<stdlib.h>记得加上
- realloc 重新分配内存块
#include <stdio.h>
#include <stdlib.h>
int main()
{
int *p = (int*)malloc(sizeof(int) * 10); //申请10个int大小的空间
int size = _msize(p);//返回在堆中分配的内存块的大小 size_t 原型为 unsigned int
if (p == NULL)
{
exit(1);
}
printf("申请的内存空间大小为:%d\n", size);
p = (int *)realloc(p, sizeof(int) * 100);
size = _msize(p);
printf("重新申请的内存空间大小为:%d", size);
free(p);
return 0;
}
打印结果:
申请的内存空间大小为:40
重新申请的内存空间大小为:400
_msize() 返回在堆中分配的内存块的大小,返回值类型为 size_t
- calloc 申请一块内存 全部初始化为某个值
比malloc多了初始化操作 申请内存是比malloc要慢
用的很少,一般不用,想要了解自行百度
- free 释放内存
free(p);
p=NULL;
野指针:
什么是野指针?野指针就是指针指向的位置是不可知的(随机的、不正确的、没有明确限制的)
- 指针变量在定义时如果未初始化
int *p; //定义之后未初始化是一个野指针
printf("%d",*p);
- 释放完指针所指向的内存之后未置空
int *p = (int*)malloc(sizeof(int));
free(p); //释放完之后未置空 p=NULL;
printf("%d",*p);
规避:
- 初始化时置 NULL
int *p=NULL;
- 释放时置NULL
free(p);
p=NULL;
常量区
常量区内容不可以修改
char *p="hello world"; //定义指针指向常量区 "hello world"在常量区
- 常量区内容不能修改,只能读取
#include <stdio.h>
#include <stdlib.h>
int main()
{
char *p="hello world"; //"hello world"在常量区
char arr[20]="hello world"; //"hello world"在栈区
printf("%s\n",p);
scanf("%s",arr);
scanf("%s",p); //运行这步的时候VS会报错,VC6.0居然没报错,有点懵逼
return 0;
}
栈区
栈区和堆区的区别:
- 内存可以自动分配回收 栈区大小 4M
- 需要手动申请释放 malloc 释放free
所有在函数内部定义的变量,包括主函数里面定义的变量,都存储在栈区。
优点就是自动分配回收,缺点是大小太小
代码区
字面意思,代码存放的区域,了解一下就可以。
常量指针 和 指针常量
关键字:const
const 不可修改
const int y = 2; //const修饰的变量定义的时候必须赋值 并且赋值之后不可修改
常量指针
const 修饰 *p
int const* p;
const int* p;
#include <stdio.h>
int main()
{
int a = 5;
//int const *p;
const int* p; //常量指针 不能通过指针修改p指向的内容(不能修改指向的内容)
p = &a;
*p = 10; //这行代码会报错:无法修改的左值
return 0;
}
指针常量
const 修饰 p
int* const p;
#include <stdio.h>
int main()
{
int a = 5, b = 10;
int* const p = &a; //指针常量 不能修改p的指向
*p = 100;
p = &b; //这行代码会报错:无法修改的左值
return 0;
}
上一篇: MYSQL-事务知识点
下一篇: 写一个函数返回参数二进制中 1 的个数
推荐阅读