1.理解内存
每个内存单位的大小取一个字节
内存单位之间的换算
1byte = 8bit
1kb = 1024byte
1Mb = 1024kb
1Gb = 1024Mb
1Tb = 1024Gb
1Pb = 1024Tb
2.什么是指针?
内存单元的编号=地址=指针
指针变量和地址
取地址操作符
int a=10;
&a;//获得a的地址
int* p=&a;
指针变量
含义
存放地址的变量叫做指针变量
int a=10;
int* p=&a;
//int*代表指向整型的指针变量
大小
32位平台下地址是32个bit位,指针变量⼤⼩是4个字节。
64位平台下地址是64个bit位,指针变量⼤⼩是8个字节。
注意指针变量的⼤⼩和类型是⽆关的,只要指针类型的变量,在相同的平台下,⼤⼩都是相同的。
解引用操作符
int a=10;
int* p=&a;
int b=*p//等价于b=10;
3.指针分类
野指针
成因
指针未初始化
int* p;
指针越界访问
int arr[10]={0};
int* p=&arr[11];
指针指向的空间释放
int* test()
{
int n=100;
return &n;
}
int main()
{
int* p=test();
printf("%d\n",*p);
return 0;
}
二级指针
指针变量的地址存放在二级指针里
int n=10;
int* p=n;
int**pp=p;
字符指针
指向字符的指针叫做字符指针。
书写
char c="ABCDEFG";
char* p=&c;
//此时指针p指向的是常量字符串ABCDEFG的首字母地址
注意
《剑指offer》中一道题区分了直接指向常量字符串和指向存放字符串的数组的指针的区别。
#include <stdio.h>
int main()
{
char str1[] = "hello bit.";
char str2[] = "hello bit.";
const char *str3 = "hello bit.";
const char *str4 = "hello bit.";
if(str1 ==str2)
printf("str1 and str2 are same\n");
else
printf("str1 and str2 are not same\n");
if(str3 ==str4)
printf("str3 and str4 are same\n");
else
printf("str3 and str4 are not same\n");
return 0;
}
实现结果
数组指针
指向数组的指针叫做数组指针。
数组指针的书写
int arr[5]={1,2,3,4,5};
int(*arrp)[5]=&arr;
首先,arrp本质是指针所以加上*并加上括号用于与指针数组区分,然后写出指针所指向的数组的类型,最后在括号后加上元素个数。
函数指针
函数指针变量应该是⽤来存放函数地址的,未来通过地址能够调⽤函数的。
书写
int (*pf)(int,int)=&test();//pf就表示一个指向test的函数指针,指向的函数返回类型是int,参数类型是int。
有趣的代码1
(*(void(*)())0)();
1.将0强制类型转换成一个指向返回为void类型的无参函数的函数指针,然后解引用这个指针得到函数调用,无参数。
有趣的代码2
void (*signal(int,void(*)(int)))(int);
2.signal函数参数为int和一个参数为int,返回类型是void的函数指针。然后其返回类型是一个函数指针,指向的函数参数为int,返回类型是void。
assert断言
含义
assert.h 头⽂件定义了宏 assert() ,⽤于在运⾏时确保程序符合指定条件,如果不符合,就报
错终⽌运⾏。这个宏常常被称为“断⾔”。
使用
#include<assert.h>
assert(p!=NULL);
//用于验证指针变量p是否为空指针
//如果p为空指针,程序就会终止运行,并提示报错。
如何取消assert断言
//在assert.h头文件之前定义一个宏 NDEBUG
#define NDEBUG
#include<assert.h>
assert(p!=NULL);
缺点
引⼊了额外的检查,增加了程序的运⾏时间。
4.指针运算
指针±整数
指针的类型决定了指针向前或者向后⾛⼀步有多⼤(距离)。
arr与&arr
int arr[10]={0};
printf("%d",arr);
printf("%d",&arr);
//在查看arr和&arr时虽然地址名相同
//但是在指针加减时就会体现出不一样
//arr+1代表访问下一个元素的地址
//&arr+1代表跳过整个数组访问下一个空间
//本质是跳过的“步长”不同
指针-指针
相当于指针±整数的逆向运算
指针的关系运算
###strlen的模拟实现