指针类型
char*-指向字符的指针–解引用访问1个字节
short*-指向短整型的指针-解引用访问2个字节
int*-指向整型的指针-解引用访问4个字节
float*-指向单精度浮点型的指针-解引用访问4个字节
…
void*–无具体类型的指针-不能进行指针±整数和解引用操作
#include<stdio.h>
int main()
{
int a = 0;
void *p=&a;
float f = 0.0f;
p = &f;
return 0;
}
void*类型的指针,什么类型的地址都能接收
const修饰指针
被const修饰的变量只是具有常量的属性,并不是常量
注意:在C++的环境下,const修饰的变量就是常量了
a不能直接改,但可以通过指针修改a
就相当于违反规则了,我本来就是不想让a改变的
那就有了另一种写法
#const修饰指针变量
const可以放在*的左边或者右边,意义不同
const限制了p
const修饰p,p不能改但是*p可以改,限制的是指针变量
修饰的是*p那么指针变量p可以修改,但是指针指向的内容不能改
指针的运算
指针的作用就是访问内存
1.指针±整数
2.指针-指针
3.指针的关系运算
如果用下标法打印数组
int main()
{
int arr[10] = { 0,1,2,3,4,5,6,7,8,9 };
int i = 0;
int sz = sizeof(arr) / sizeof(arr[0]);
for (i = 0; i < sz; i++)
{
printf("%d ", arr[i]);
}
return 0;
}
指针法:
指针-指针相当于
日期-日期=中间的天数
指针-指针的绝对值=整数(两个指针之间的元素个数)有大小关系,正负
没有指针+指针这种写法
两个指针间的元素个数为9
注意:指针-指针的前提条件:两个指针必须指向同一块空间
回顾一下strlen计算字符串长度
——strlen统计的是字符串中\0之前的字符个数;包含头文件string.h
指针±整数实现strlen功能
指针-指针实现strlen功能
指针的关系运算(指针和指针比较大小)
利用指针的关系,遍历数组
i<=arr[9]的位置,不要忘记等于
指针的关系运算(p<arr+sz)指针比大小
野指针
野指针:指针指向的位置是不可知的,不正确的,没有明确限制的
##野指针的成因
1.指针未初始化
2.指针访问数组越界
最后一个为野指针,出现随机值
3.指针指向的地址已经没有访问权限了
a就像就像酒店的房间,只交了一晚上的钱,第二天就没有访问权限了,不代表这个变量消失了,只是你没有访问权限了
注意:
指针一定要初始化,有明确的指向最好,没有的话初始化成NULL(空指针)
assert断言
需要包含头文件<assert.h>,运行时确保程序符合特定条件,aeesrt()这个宏接收一个表达式作为条件,条件为假时,就会终止程序并且报错,报错位置
assert会告诉你错误的程序在那个文件,在程序的第几行
assert可以判断任何条件,只要错误就会告诉你出错误的位置
其实利用if语句也可以判断程序是否出错
但是我们为什么用assert呢
assert的好处:可以关闭,if语句必须把语句删除才可以,取消判断,assert可以直接关闭
怎么关闭:在头文件前面加上#define NDEBUG
关于strlen的模拟实现更加严谨的写法
strlen所返回的值的类型可以写成size_t类型
size_t类型的值打印用%zd
传值调用和传址调用
有一些问题是必须通过指针来解决的
比如:写一个函数,交换两个整数的值
注意:第18行就叫传值调用,传的是a,b变量本身的值
这里的函数调用就是传址调用
如果需要修改或是改变主函数里面变量的值,就需要用到传址调用