C语言指针笔记_1
内存四大分区
内存中大致分为四个部分,简称内存四区。其中含有:栈区、堆区、全局区/静态区和代码段。
分区 | 存储类型 |
---|---|
堆区 | 局部变量、函数的形参、函数的返回地址 |
栈区 | 程序员通过动态申请内存而分配的(malloc, relloc, calloc, new)这些都必须在调用过后手动释放(new, free) |
全局区/静态区 | 全局变量/静态变量 |
代码段 | 二进制机器指令 |
具体代码的简要分析
取址运算
int main()
{
int a = 10, b = 20, c = 30;
printf("a=%d, b=%d\n", a, b);
return 0;
}
上述小代码中a和b两个变量确切的存储位置为内存中的栈。
& : 取地址运算符, 求出一个变量的存储地址。例如:&a, &b;
printf("a的内存地址=%d, b的内存地址=%d\n", &a, &b);
%p和%d打印的区别在哪里?
对于地址的打印输出,一般情况我们习惯于使用%p来进行16进制输出
%d:是按照十进制方式打印
%p:是按照十六进制方式打印
%x:是按照十六进制方式打印
常量和变量
常量:在程序的运行过程当中,值不可以发生改变的量
变量:在程序的运行过程当中,值可以发生改变的量
指针和地址的关系、指针变量、指针常量
指针和地址的关系是什么?
指针就是地址,地址就是指针。
指针常量
&a, &b
指针变量
问题:指针变量和普通变量有什么区别?
都没区别,都是用来存储数据的
要是硬要说他有区别,那么:
普通变量:存储数值
指针变量:存储地址
char, short , int , long , float, double C语言中6大基本数据类型
指针变量的格式要求
是靠变量名还是靠类型?
都可以 ,或者也可以什么都不靠,也可以什么都靠,因为C语言语法灵活。
char \*p1;
char* p1;
char * p1;
char\*p1;
p1的类型:char*型 , p1读作指向char型指针, 指针类型
short *pshort;
int* pint;
long* plong;
float *pf;
double *pdouble;
变量名到底是什么? pshort,*不属于变量名的一部分,字母,数字,下划线, 类型是什么: short*型
多个指针变量的定义
int* p1, p2, p3, p4, p5, p6;
这里只定义了一个指针类型的变量 (int*) :p1, 其余的都是整型int型变量。
int *p1, *p2, *p3, *p4, *p5, *p6;
这里才表示全部定义的都是指针类型的变量。
#define和typedef的区别
#define 定义一个符号常量, 仅仅只是进行宏替换
宏替换: 编译的预处理阶段, INT替换为int
typedef 起别名,能够重新定义新的数据类型,不是替换,而是定义新类型
#define INT int
#define PINT int*
typedef int MYINT;
typedef int* PMYINT; //这里千万不要忘记了typedef后面有一个分号
INT c = 30, d = 40;
printf("c=%d, d=%d\n", c, d);
PINT p1, p2, p3, p4, p5, p6;
MYINT c = 30, d = 40;
printf("c=%d, d=%d\n", c, d);
PINT替换为int*,所以只定义了一个指针类型的变量 p1
PMYINT p1, p2, p3, p4, p5, p6;
此时这里一共定义了6个指针类型的变量, 都是PMYINT类型, 本质都是int*。
指针的初始化和解引用
指针的初始化
没有初始化的指针变量是不能使用的,不知道指向哪里。存储化就是让他存储一个地址。
int* p;
printf("p=%d\n", p); //此代码会直接报错
int *p = &a; //p指向a
int *p = NULL;
NULL表示空指针, 理解为:内存地址为0的地方, 不指向任何地方。
指针的解引用
间接访问(解引用) :指针指向谁,间接访问(解引用)得到谁 , 指向谁就等价于谁
间接访问运算符/解引用运算符 (*)
printf("*pa=%d, *pb=%d, *pc=%d\n", *pa, *pb, *pc);
注:不能够贵空指针进行解引用(间接访问),所以在执行间接访问(解引用)的时候,一定判断指针是否为NULL,【否则可能会导致系统崩溃】
二级指针: 指向一级指针的指针, 二级指针是存储一级指针的地址