数组指针基础:
指针变量的定义
数据类型* 变量名;
2、注意事项
(1)定义指针变量时的 星号起到标志性的作用,除此情况以外, 星号+指针变量表示指针指向的内存
(2)星号+指针变量: 指针指向的内存, 本质就是访问指针变量保存的地址开始n个连续单元的内存
(3)星号+指针变量: 可以作左值也可以作右值
(4)在同一个系统中, 指针变量的大小是一样的,32位:4字节 64位:8字节
(5)指针变量要与保存的地址匹配, 如果不匹配的化,保存地址一点问题都没有,
但是通过指针访问数据存在问题
(6)没有指向的指针称为野指针.
在编程中不要出现野指针,很危险, 如果不确定指针指向,让指针指向NULL
一位数组指针:
数组指针: 本质还是一个指针变量, 保存数组的起始地址
语法: 类型 (*p)[元素个数];
int(*p)[10]; ===>p是一个数组指针,保存有10个元素,每个元素是整型的数组地址
数组指针的表达方式:
1、数组名表示数组首元素的起始地址,并且等价于一个常量,不可以发生改变!
2、数组每个元素的起始地址:
(1)&a[0] &a[1] &a[2] ....&a[i]---->表示第i+1个元素的起始地址
(2) a a+1 a+2 .... a+i
3、数组的起始地址: &a
&a +1 :偏移一个数组的大小
4、数组每个元素:
a[0] a[1] a[2] .... a[i]
ps: 地址加1,表示加1个单位,1个单位取决与地址的类型
二维数组指针:
int a[3][4]: a 是数组名, 3表示有3个元素, 每一个元素是4个元素的整型数组
1、每一行的起始地址:
a[0] a[1] a[2] .... a[i] :表示外层数组的每一个元素
&a[0] &a[1] &a[2] .... &a[i]: 外层数组每一个元素的起始地址(每一行的起始地址)
a a+1 a+2 .... a+i :每一行的起始地址
2、每一行每一个元素的起始地址
a[0] :第一行的一维数组的数组名
a[0][0] a[0][1] a[0][2] a[0][3] : 第一行一维数组的每一个元素
&a[0][0] &a[0][1] &a[0][2] &a[0][3] : 第一行一维数组的每一个元素地址
a[0] a[0]+1 a[0]+2 a[0]+3 :第一行每个元素的起始地址
。。。。
3, 总结
&a: 二维数组的起始地址
a: 第一行的地址地址
a[i]: 第i+1行的第一个元素的起始地址
指针和数组的异同:
不同点:指针是变量,可以发生改变的, 数组名是常量不可以发生改变
相同点: 如果指针指向数组的第一个元素, 指针和数组名的本质是一样的,都表示地址,
因此,数组名可以访问元素的方式指针都是支持的。
函数指针:
数指针: 本质还是指针变量
语法: 返回值类型(*pfun)(参数表类型);
void (*pfun)(int, double) = NULL; // pfun是函数指针,保存有两个参数,分别是整型和浮点类型,返回值是void类型函数的入口地址
函数调用方法:
(1)函数名(...)
(2)函数指针(...)
指针数组:
本质是一个数组,数组的每一个元素都指向一个地址。
函数:
内置函数的调用分三步:
1.函数的定义
2.函数的声明
3.函数的调用
多文件编辑:
多文件编程:
1、 xx.c称为源文件, 存放函数定义
xx.h称为头文件, 存放函数声明
2、一个模块包含两部分: 头文件+源文件, 文件相同,仅仅只是后缀不同
3、如果A.c调用B.c文件中的函数,要做到以下两件事:
(1)在A.c中包含B.h头文件
(2)A.c和B.c要交叉编译: gcc A.c B.c -o x
全局变量和局部变量:
全局变量:
生存期: 程序开始---》程序结束
作用域: 在所有.c文件中都可以访问
ps:
局部变量和全局变量可以同名, 默认采用就近的方式访问!!!