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