内存
1. 内存四区
a) 代码区。 代码
b) 全局区。 全局的常量字符串“abc” 变量
c) 栈区。系统自动开辟,系统自动释放。并不是很大
d) 堆区。动态开辟的内存,手动开辟,手动释放。很大
地址
地址:把内存以单个字节为单位,分开。对每个字节编号,这个编号就是地址
a)编号时连续的
b)唯一的(不可改变)
c)取地址运算符:& 单目运算符 优先级() [].结合性从右往左 (->,&属于第二级:还没验证)
首地址
一段内存空间中第一个存储单元的地址。存储单元
1. int a 变量:
2. int a[5]一维数组:第一个元素(a[0])地址中第一个存储单元的地址
3. int a[2][2] 二维数组:
a 第一个一维数组的地址 首地址指向一个一维数组
一维数组 第一个元素的地址
4. int a[2][2][2] 三维数组:
首地址:a -> a[2](二维数组) -> a[2][2](一维数组)
指针变量
1. 用来存放地址的变量。
2. 内存大小4B(B:字节)
地址是一些编号,一种数据
整数 int a;
字符 char c;
小数 float b;(单精度浮点型)
地址 指针变量
a)指针变量的定义:
数据类型 + 变量名
int *p;
// 定义一个指针变量 p。存的是地址!!!!
// int 指明指针指向的数据类型
// * 指明 p 这个变量是一个指针变量
b)指针变量的赋值
float a;
float *p;
p = &a;// p指向a
c)指针变量的引用
访问这个int变量
1. 使用变量名
printf("a=%d\n",a);
2. 指针访问:* 指针变量。*是取值运算符。返回某一个地址中的值。单目运算符 结合性 从右到左
注意:
定义时:int *p;*表示p是一个指针变量
非定义时:*p;表示取值p指向的内存值
-> 是专门给结构体指针访问变量用的,主要是为了省事,也可以 (*p).x进行访问
!!!!可以直接由指针通过地址直接获取变量的值
printf("p指向的内存中的值:%d\n",*p);
野指针
不能明确指向的指针变量;不能存放重要数据
int *p; // p 里面保存的地址不确定的,p指向是不明确的
int *p = NULL;
int a;
printf("%d\n",a);
// 执行会让编译器报错
//注意:要使用NULL时;
c语言必须在开头写一个#include<stdlib.h>
C++必须在开头写一个#include<cstdlib>
空指针 void*
当不确定当前地址存储数据时,可以使用空指针,后续转换成其他数据类型
动态内存分配: malloc new 会解释为什么时空指针类型
指针变量的运算
运算符
+
-
++ 自增
– 自减
指针偏移,去访问地址旁边的一些内存
指针变量的加减,以指针所指向的类型为空间单位进行偏移
char *p ; //char 1B ; p+1 多加1B
int *p; //int 4B ; p+1 多加1B
double *p;//double 8B ; p+1 多家1B
数组与指针
一维数组与指针
1. 定义一个一维数组,数组名是这个数组的 “首地址”
int a[5];
a 指向 a[0] , a[0] int的元素,a的类型就是int*
a 这个地址指向 a[0] int元素 int* ;偏移量是4B
&a 这个地址**指向整个数组**;&a 的类型是 int(*)[5]; 偏移量4B * 5 = 20B
int a[5];
printf("a = %d\n",a);
printf("a + 1 = %d\n",a); //偏移量4B
printf("&a = %d\n",a);
printf("&a + 1 = %d\n",a); //偏移量20B
2. 访问数组元素
a)下标法:a[i] (eg:a[0])
b)指针法
数组名a是数组的首地址,不可改变的,只能a+i不能a++
int a[5] = {1,2,3,4,5};
int *p = a; // p 指向a[0]
*p; // a[0]
*(p+1); // a[1]
*(p+2); // a[2]
for(int i = 0; i < 5; i++)
{
printf("%d', *( p + i ));
//用数组名访问是只能a+i 不能a++
//a是数组名不能改变
}
return 0;
二维数组与指针
多维数组的地址依旧是连续的,不存在几行几列(第一行元素地址后面接第二行,一次排序)
``
int a[3][4] = {1,2,3,4,5,6,7,8,9,10,11,12};
拆分为:3个一维数组
4个int元素
数组名: a
a 是二维数组的首地址
a 指向二维数组的第一个存储单元(一维数组)
a是指向a[0]这个一维数组。a的类型是int(*)[4]; a+1 的偏移量16B
a[0]是一维数组的数组名
a[0]指向a[0][0]这个元素; a[0]的类型是int* ; a[0]+1的偏移量是4B
//a就是数组的第0行;a+1就是数组第1行...
&a: int(*)[3][4]; &a+1偏移量为48B
二维数组的引用
m行n列的元素
下标法:a[m-1][n-1];
指针法*(a[m]+n);
数组名*(*(a+m)+n);
总结
a int()[4]
&a int()[3][4];
a[0] int*;
a[0][0] int
指针数组: int*[ ]
数组指针:int(*)[ ]
函数指针:
指针形参的函数:
结构体指针:
字符串与指针:
指向指针的指针:
数据结构:链表、树、栈、队列
C语言面向过程。指针面向对象