一、一级指针
1. 指针的介绍
指针是内存中一个最小单元的编号,也就是地址;指针,通常指的是指针变量,是用来存放内存地址的变量;内存划分为很多个内存单元,一个内存单元的大小是一个字节,一个内存单元给一个地址。
指针的大小(也就是地址)在32位平台(×86)是4个字节,在64位平台是8个字节.
只要是地址,判断大小就用这个方法.
2. 指针类型的意义
(1)指针的类型决定了指针进行解引用操作时,能够访问空间的大小
int* p, *p能够访问4个字节 char* p, *p能够访问1个字节 double* p, *p能够访问8个字节
(2)指针的类型决定了指针走一步走多远(指针的步长)
int* p; p+1--> 4 char* p; p+1-->1 double* p; p+1-->8
3. 野指针 ----- 指针指向的位置不可知
(1)指针未初始化 (2)指针越界访问 (3)指针指向的空间释放
4. 指针±整数
如下代码,指针-整数的应用,将数组中偶数打印出来,使用指针p -= 2的操作
int main() { int arr[] = { 1,2,3,4,5,6,7,8,9,10 }; int i = 0; int sz = sizeof(arr) / sizeof(arr[0]); int* p = &arr[9]; for (i = 0; i < sz/2; i++) { printf("%d ", *p); p-=2; } return 0; }
结论:指针±整数还是一个指针.
5. 指针-指针
如下代码,指针-指针的应用,用my_strlen()函数模拟实现求字符串长度,最后返回两个指针相减的值,即为字符串长度.
int my_strlen(char* str) { char* start = str; char* end = str; while (*end) { end++; } return end - start; } int main() { char arr[] = "abcde"; printf("%d\n", my_strlen(arr)); return 0; }
结论:指针-指针是一个整数;而且结果是两个指针相差的元素个数.
二、二级指针
如下,ppa就是二级指针,存放pa的地址;
int main() { int a = 10; int* pa = &a; int** ppa = &pa; **ppa = 20; printf("%d\n", **ppa); printf("%d\n", a); return 0; }
三、指针数组
区分指针数组和数组指针,实际上,指针数组是数组;数组指针是指针;
指针数组是存放指针的数组;数组指针是指向数组的指针;
如下,arr是一个数组,有三个元素,每个元素是一个整形指针;
int main() { int a = 10; int b = 20; int c = 30; //指针数组 - 存放指针 int* arr[3] = { &a,&b,&c }; //指针数组 int i = 0; for (i = 0; i < 3; i++) { printf("%d ", *(arr2[i])); } return 0; }
四、const修饰指针的作用
const 放在指针变量的左边时,修饰的是 * p,也就是说:不能通过p来改变 * p的值
const 放在指针变量的右边时,修饰的是指针变量p本身,p不能被改变
int main() { const int num = 10; int n = 100; //err const int* p = &n; *p = 100; //err int* const p = # *p = 20; //p = &n; //err printf("%d\n", num); return 0; }
最后,介绍一个断言操作----assert(str !=NULL);
传指针首地址的时候加这句,防止传空指针过来,若是空指针会报错----保证指针的有效性(要引用头文件#include <assert.h>)