一、内存 地址 和指针变量
(1)定义
内存:bit(比特)、byte(字节)、Kb、Mb……
地址:内存的编号
指针:即地址
注:1.创建变量的实质是在内存申请一块空间(存放数据)
2.地址在内存中是由高到低
3.”&“:取得一个变量的地址
4.指针变量:解引用符号取得一个变量的地址,需存放在另一个变量中,即指针变量
正确解引用格式如下:
#include <stdio.h>
int main()
{
int a = 10;
int* pa = &a;//取出a的地址并存储到指针变量pa中
return 0;
}
(2)指针变量的大小
二、指针变量类型
例:
int a = 10;
int* pa = &a;
1.* 表示是指针变量
2.int表示指针所指向的变量类型是int
(1)指针类型的意义
1.指针的解引用
#include <stdio.h>
//代码一
int main()
{
int n = 0x11223344;
int *pi = &n;
*pi = 0;
return 0;
}
//代码二
int main()
{
int n = 0x11223344;
char *pc = (char *)&n;//强制转换为char*类型
*pc = 0;
return 0;
}
代码一n的四个字节被全部改为0,代码二中仅第一个字节被改为0;
结论:指针的类型决定了,对指针解引⽤的时候有多⼤的权限(⼀次能操作⼏个字节)。
2.viod* 指针
可接受不同类型的地址(指针),但不能进行指针运算和解引用。
3.const修饰变量和指针变量
test1(); //测试⽆const修饰的情况
test2(); //测试const放在*的左边情况
test3(); //测试const放在*的右边情况
test4(); //测试*的左右两边都有const
(2)指针性质
1.指针 ± 整数
即指针移动
int n = 10;
char *pc = (char*)&n;
int *pi = &n;
printf("%p\n", &n);
printf("%p\n", pc);
printf("%p\n", pc+1);
printf("%p\n", pi);
printf("%p\n", pi+1);
、
可以发现,char* 类型的指针变量+1跳过1个字节, int* 类型的指针变量+1跳过了4个字节。
注:在数组中元素在内存中按顺序排列,知道首位即可知道整个数组。
结论:指针类型影响指针移动距离。
2.指针 - 指针
仅在数组中有意义,其结果是两指针间元素的个数
3.指针的关系运算
4.野指针
指针未初始化;指针空置——int * pa = NULL
指针越界访问;
指针指向的空间释放。
(3)各种类型的指针变量
1.字符指针变量
形式:
char c = 'w';
char *pc = &c;
*pc = 'w';
char str = "hello world";
char *pstr = &str;//实际上存储的是字符串首字符的地址
*pstr = "hello world";
2.数组指针变量
定义:
即指向数组的指针变量,存放的是数组的地址
形式:
int(*p)[n];
3.函数指针变量
定义:
即指向函数的指针变量,存放的是函数的地址
形式:
int Fun(int x,int y)
{
……
return z;
}
int main()
{
int (*Fun)(int x,int y)=&Fun;
//或者 int(*Fun)(int,int)=Fun;
//这就是函数指针变量的格式
//它的类型是:int(*)(int x,int y)
return 0;
}
4.typedef关键字
可以将类型重命名,达到简化的作用
格式:
a.
typedef unsigned int uint;
//将unsigned int 重命名为uint
b.
typedef int* ptr_t;
//整型指针类型:int* 》ptr-t
typedef int(*parr_t)[5];
//数组指针类型:int(*)[5] 》parr-t
typedef void(*pfun_t)(int);
//函数指针类型:void(*)(int) 》pfun-t
三、assert断言
(1)条件
1.需要头文件<assert.h>
2.格式:assert(判断语句)
如果语句为真,则程序继续运行,如果语句为假,则程序结束运行。
3.assert可随时停用,在文件开头加入:
#define NDEBUG
#include <assert.h>
(2)作用
自动标识文件和出问题的行号
四、更多的指针
(1)二级指针
int a=10;
int *pa =&a;
int **ppa=&pa;
int **ppa既是二级指针,存放的是pa的地址;*ppa得到pa的地址,**ppa得到是a的地址。
以此类推可以得到多级指针,但通常用不上。、
(2)指针数组
定义:
即存放指针(地址)的数组,本质还是数组,每个元素都是地址。
形式:
int *arr[n] 或 char *arr[n] 等(取决于所存储的数据类型)
(3)函数指针数组
定义:
存放函数指针(地址)的数组,每个元素是一个对应函数的地址。
形式:
int *arr[10];
int (*parr[]) ();
//类型为 int (*) ()