前言
C语言指针学习笔记
定义一个指针
- 在变量名前加
*
,表示指针变量
- 指针类型与数据的类型要匹配
为指针赋值
1 2 3 4
| int 变量名 = 0; int *指针变量名;
指针变量名 = &变量名;
|
*指针变量名
:表示指针变量指向的值
指针变量名
:表示指针存储的地址值
输出指针的数据
输出地址
输出指向的值
指针占用的大小
- 不论是存储什么类型数据的指针,其占用的内存大小都是一样的
野指针
- 没有初始化过值的指针,这种指针叫野指针
- 程序中不要出现野指针
空指针
- 如果一个指针变量没有明确的指向一块内存,那么就把这个变量指向NULL
NULL
指针常量和指向常量的指针
指向常量的指针
1 2 3 4 5 6 7
| int a = 0; a = 1;
const int *p = &a;
printf("%d\n", *p);
|
1 2 3 4 5 6 7
| const int a = 0;
int *p = &a; *p = 1;
printf("%d\n", *p);
|
防止警告
1 2 3 4 5 6 7
| const int a = 0;
int *p = (int *)&a; *p = 1;
printf("%d\n", *p);
|
C语言的常量
- 因为有这样的漏洞,所以相比于使用
const
定义常量,最好使用#define
来定义常量
指针常量
常量指针指的是指针存储的内存地址是常量
p只能指向a的地址,并且不能改变
1 2 3 4 5
| int a; int b;
int *count p = &a;
|
指向数组
- 当指针变量指向数组的时候,C语言语法规定指针变量名可以当数组名使用
1 2 3 4 5 6 7 8
| int *p; int a[1] = { 0 };
p = a;
p[0] = 1;
|
指针运算
- 指针变量可以计算
- 例如:如果是
int *
类型的指针+1,那么增加4个整数位
指针数组
定义一组空指针
1
| int *指针变量名[1] = { NULL }
|
为指针数组赋值
1 2 3
| int *指针变量名[1]; int 变量名; 指针变量名[0] = &变量名;
|
二级指针
1 2 3 4 5 6
| int a; int *b; int **c;
b = &a c = &b
|
c
的值是*b
的地址
*c
的值是b
的值,也就是a
的地址
**c
的值是a
的值
多级指针
- 多个层级的指针
- 能用少的层级即决问题的程序,不要使用多级指针
指针作为形参
数组作为形参
1 2 3 4 5 6 7 8 9 10
| void fun(int *a) { ... }
int main() { int a[1]; fun(a); }
|
- 如果一个数组作为函数的参数,那么数组的成员数量在函数内部是不可见的
- 在传递一个数组时,同时提供另外一个参数,标明这个数组有几个成员变量
main函数的形参
argc
:指针数组的长度,代表参数的数量
**args
:指针数组,代表命令行的参数
1 2 3 4
| int main(int argc, char **args) { ... }
|
不修改实参内部的值
1 2 3 4 5 6 7 8 9 10
| void fun(const int *a) { ... }
int main() { int a[1]; fun(a); }
|
指针作为返回值
memset 函数
引入头文件
<point>
:指定要置空内存的首地址,如果是数组可以指定数组名
0
:表示置空
sizeof(<point>)
:这块内存的大小
1
| memset(<point>, 0, sizeof(<point>));
|
memcpy 函数
arrFull
:有数据的数组
arrNull
:没有数据的数组,需要被复制
size(arrNull)
:赋值的内存大小
1 2 3 4
| int arrFull[3] = {1, 2, 3}; int arrNull[3] = { 0 };
memcpy(arrNull, arrFull, sizeof(arrNull));
|
memmove 函数
1 2 3 4
| int arrFull[3] = {1, 2, 3}; int arrNull[3] = { 0 };
memmov(arrNull, arrFull, sizeof(arrNull));
|
完成