全面解析网站建设及报价,wordpress 批量上传图片,微网站建设套餐,清远建网站的公司文章目录7 指针7.1 指针的基本概念7.2 指针变量的定义和使用7.3 指针所占内存空间7.4 空指针7.5 野指针7.6 void*指针7.7 指向指针的指针7.8 const修饰指针7.9 指针和数组7.10 指针和函数7 指针
指针是指向另外一种类型的符合类型#xff0c;和引用类似#xff0c;指针也实现…
文章目录7 指针7.1 指针的基本概念7.2 指针变量的定义和使用7.3 指针所占内存空间7.4 空指针7.5 野指针7.6 void*指针7.7 指向指针的指针7.8 const修饰指针7.9 指针和数组7.10 指针和函数7 指针
指针是指向另外一种类型的符合类型和引用类似指针也实现了对其他对象的间接访问。注意我们这里使用的是类似说明之间还是有差异。
指针本身就是一个对象允许对指针复制和拷贝而且在指针存在的情况下它可以前后指向不同的数据类型指针无需在定义时就赋值和其他内置类型一样如果在初始化的时候没有复制那么它也会拥有一个不确定的值
7.1 指针的基本概念
指针的作用可以通过指针间接访问内存
内存编号是0开始记录的一般用十六进制数字表示可以利用指针变量保存地址 7.2 指针变量的定义和使用
指针变量定义语法数据类型 *变量名;
指针定义范例
int * a,*b;//说明a和b都是指向int数据类型的指针*的靠近 有些人总不能理解*这个标志在定义中靠近哪边。其实靠近哪边都没错如果你靠近变量名说明你理解为该变量不是基本变量而是一种指针类型这样的话如果你写成以下形式是可以的 int *p1,p2;你也可以靠近int但是这样的话每条语句中就只能定义一个变量如下所示 int* a;
int* b;我们在前面注意的两点提到过指针需要指向不同的数据类型那么如果我想要取一个变量的地址该怎么取我们要用到取地址符。
如果我们指向某变量后想要取得地址对应的元素那么我们可以使用解引用符*来访问该对象。
让我们试着使用一下指针的定义仔细体会其中的含义代码如下所示
#include iostream
using namespace std;int main()
{//1、定义指针int a 10;//指针定义的语法数据类型*指针变量名int* p a;cout a的地址为 a endl;cout 指针p为 p endl;//2、使用指针//可以通过解引用的方式来找到指针指向的内存//指针前面加*代表解引用找到指针指向的内存中的数据*p 1000;cout a a endl;cout *p *p endl;system(pause);return 0;
}某些符号有多个含义 对于没有学过编程语言的来说如果是首次接触C很容易被一堆符号搞晕。像和*这些符号实际上有多个含义。下面我们用一些例子来看看它们在不同位置表示的不同含义。 int i 42;
int r i; //紧跟着类型名因此是声明的一部分而r是一个引用相当于42的别名42的本名叫ir和i都可以操纵42这个数据
int *p; //紧跟类型名出现因此是声明的一部分p是一个指针
p i; //出现在表达式中是一个取地址符
*p i; //*出现在表达式中是一个解引用符
int r2 *p; //是声明的一部分*是一个解引用符7.3 指针所占内存空间
指针也是数据类型那么这种数据类型占用多少内存呢通过下面的演示我们可以知道指针占有多少内存。
示例
#include iostream
using namespace std;int main()
{//指针所占内存空间int a 10;int* p a;//在32位操作系统下指针是占4个字节空间大小不管是什么数据类型//在64位操作系统下指针是占8个字节空间大小cout sizeof(int *) sizeof(int*) endl;system(pause);return 0;
}7.4 空指针
空指针不指向任何对象你可以理解为它指向一块未知的区域而实际上该指针变量指向内存中编号为0的空间。其通常用于初始化指针变量。需要注意的是在没有指向任何实质性的东西时你可以查看空指针的地址但是空指针所指向的内存数据是不可以访问的。
让我们试着敲一下下面的例子
#include iostream
using namespace std;int main()
{//空指针//1、控制怎用于给指针变量进行初始化int* p NULL;//2、空指针是不可以进行访问的//0~255之间的内存编号是系统占用的不可以进行访问//*p 100;system(pause);return 0;
}tip 在C11中我们可以让字面值nullptr来初始化指针当然由于空指针指向的是内存中的0号位故我们指向让指针指向字面值0也可以达到空指针的效果。
int *p1 nullptr;
int * p2 NULL;
in * p3 0;NULL还是nullptr 在以后的C程序书写中我们应该避免使用NULL而多使用nullptr。 7.5 野指针
野指针通常指的是指针变量指向非法的内存空间。一般来说指针都需要初始化如果你没有初始化那么在访问指针的时候就会出现问题。
示例
#include iostream
using namespace std;int main()
{//野指针int* p (int*)0x1100;cout *p endl;system(pause);return 0;
}tip 【总结空指针和野指针都不是我们申请的空间因此不要访问。】
7.6 void*指针
void*指针也叫通用指针或泛指针。对于这类指针其可以存放任意数据对象。但是注意的是不要试图去访问它因为你不知道void *指针指向的是什么数据类型。
#include iostream
using namespace std;int main()
{//void*指针int a 11;void* p a;cout *p endl;system(pause);return 0;
}out 7.7 指向指针的指针
指针变量本质上也是对象故指针变量也是个地址。
#include iostream
using namespace std;int main()
{//void*指针int a 11;int* p a;cout a的地址 a endl;cout p指向的地址 p endl;cout p的地址p endl;system(pause);return 0;
}out 7.8 const修饰指针
当一个变量被const修饰符限定时那么他会变成常量其值不能改变。在指针这一块内容中const修饰指针会出现三种情况
const修饰指针——常量指针const修饰常量——指针常量const既修饰指针又修饰常量
上面显有点绕我来总结一下。
让我们来看第一种情况常量指针。
const int *p a;
实际上其等于
const(int *p) a;
实际上等于:
const a;在这种情况下指针中存有的内容只能是常量也就是说指针的性质被保留了还是可以随便指那是指的内容他必须保证是一个常量不能随便修改。 让我们来看第二种情况指针常量。
int const *p a;如果是指针常量这种情况说明指针变量名被const修饰了此时这个指针变量变成指针常量了那么指针就不能随便改了而内容可以随便改因为没有限制。
综上所述那么const int * const p就是即修饰指针又修饰常量那么指针的指向不能该指针指的内容也不能改了。 示例
#include iostream
using namespace std;int main()
{//1、常量指针int a 10;int b 10;const int* p a;//指针指向的值不可以改但是指向可以改//*p 20错误p b;//正确//2、const修饰常量int* const p2 a;*p2 100;//p2 b;错误指针的指向不可以改//3、const修饰指针和常量const int* const p3 a;//p3 b;错误//*p3 100;错误system(pause);return 0;
}顶层const 从上面的常量指针我们看出const是修饰的是指针变量指向的数据而指针常量const修饰的是指针变量本身。为此我们用术语顶层const表示指针本身是个常量而用底层const表示指针所指的对象是一个常量。 从上面所学我们也可以得知指针类型既可以是顶层const也可以是底层const。 7.9 指针和数组
作用利用指针访问数组中元素
示例
#include iostream
using namespace std;int main()
{//指针和数组//利用指针访问数组中的元素int arr[10] { 1,2,3,4,5,6,7,8,9,10 };cout 第一个元素为 arr[0] endl;int* p arr;//arr就是数组的首地址cout 利用指针访问第一个元素 *p endl;p;//让指针向后偏移4个字节cout 利用指针访问第二个元素 *p endl;system(pause);return 0;
}7.10 指针和函数
作用利用指针作为函数参数可以修改实参的值
原理: 示例
#include iostream
using namespace std;//值传递交换函数
void swap01(int a, int b)
{int temp a;a b;b temp;cout swap01 a a endl;cout swap01 b b endl;
}void swappoint(int *p1, int *p2)
{int temp1 *p1;*p1 *p2;*p2 temp1;cout swappoint *p1 *p1 endl;cout swappoint *p2 *p2 endl;
}int main()
{//指针和函数//1、值传递int a 10;int b 20;swap01(a, b);cout a a endl;cout b b endl;//分界线cout ------------ endl;//2、地址传递int* p1 a;int* p2 b;swappoint(a, b);cout a a endl;cout b b endl;system(pause);return 0;
}