ssssa
1.指针
官方介绍:指针也就是内存地址,指针变量是用来存放内存地址的变量,在同一CPU构架下,不同类型的指针变量所占用的存储单元长度是相同的,而存放数据的变量因数据的类型不同,所占用的存储空间长度也不同。有了指针以后,不仅可以对数据本身,也可以对存储数据的变量地址进行操作。指针描述了数据在内存中的位置,标示了一个占据存储空间的实体,在这一段空间起始位置的相对距离值。在 C/C++语言中,指针一般被认为是指针变量,指针变量的内容存储的是其指向的对象的首地址,指向的对象可以是变量(指针变量也是变量),数组,函数等占据存储空间的实体。
学习完指针说白了就是一个操作地址空间的东西,他的作用是可以有效地表示复杂的数据结构、动态分配内存、高效地使用数组和字符串、使得调用函数时得到多个返回值等。
1.指针怎么定义
int* p;
这样就定义了一个整数型的指针。
2.指针怎么赋值
int a =10; //创建一个变量
int* p = NULL; //创建一个指针
p = &a; //把a的地址赋值给p
在创建完指针p后,就要给指针赋值,指针不同于int float char这些,指针只能赋值地址,因此把一个地址赋值给指针,就要在改变量前面加取地址符& ,&a的作用就是把a的地址取出来。NULL是什么意思,他是一个空指针,就等于给指针p符一个初值。上面是第一种给指针赋值的方式,还有第二种,在定义指针的时候之间给指针赋值。
int a =10; //给a变量之间赋值
int* p = &a; //与上面类似在定义指针的时候也可以之间给指针赋值
3.怎么获得指针对应那段地址里面的真实值。
这里面有点绕。下来分为两部分说明,第一部分指针里面的值,这个值就是对应的a里面的一个地址。想要查看这个值可以运行下面代码。
#include <iostream>
using namespace std;
int main()
{
int a = 10;
// 1.定义指针
int* p; // 定义指针
p = &a; //& 取a的地址 建立关系
// 也可 int *p =&a
cout << "a的地址 " << &a << endl;
cout << "指针p " << p << endl;
system("pause");
}
通过上面代码我们发现p的值和a的地址的值是一样的。
第二个是指针对应那段地址里面的真实值。这个的意思是说咱们不是得到一个地址(这里就是a的地址)但是这个地址里面的值是多少,看了代码就知道这个值是10。那么我们怎么用指针获得这个值,那么就是在地址前面加*,进行解引用,即*p。也可以通过给*p赋值来改变这个地址里面的真实值。下面代码可以测试。
#include <iostream>
using namespace std;
int main()
{
int a = 10;
// 1.定义指针
int* p; // 定义指针
p = &a; //& 取a的地址 建立关系
// 2.使用指针
// 可以通过解引用的方式找到指针指向的内存
cout <<"*p等于" <<*p<< endl;
cout <<"a等于" <<a<< endl;
*p = 1000; // *p的意思是指向p所指向内存的数据
cout <<"*p等于" <<*p<< endl;
cout <<"a等于" <<a<< endl;
system("pause");
}
通过这个代码我们发现通过修改*p里面的值就可以修改p对应的地址里面的值,也就是修改a的值。
运行结果如下
在最后,我们要声明一下,指针占多少字节,
32位操作系统。指针4个字节 64位操作系统 指针8个字节
#include <iostream>
using namespace std;
int main()
{
cout << "sizeof(int *) = " << sizeof(int*) << endl;
cout << "sizeof(char*) = " << sizeof(char*) << endl;
cout << "sizeof(float*) = " << sizeof(float*) << endl;
cout << "sizeof(double*) = " << sizeof(double*) << endl;
system("pause");
}
运行结果如下
我们发现在32位操作系统里面无论哪种指针都是4个字节。
注意事项:
1. NULL 空指针不能访问, 0-255之间的内存是不能使用的,因为系统用
2. (int *) 0x0110; 意思是把0x0110强制转化为指针
3.int* p = (int*)0x1100; //这种定义是一种错误称为野指针,野指针是一种错误,避免出现野指针。因此在定义指针之前尽量赋值NULL,即int* p = NULL;
4. 空指针和野指针都不是我们申请的空间,因此不要访问,访问就会出错
2.CONST与指针
我们都知道const它限定一个变量不允许被改变。例如:
const int a=10;
那么在后面代码中a就一直等于10,不能被赋予其他值,否则报错。
那么const在指针中又有什么作用。我们下来分为三种进行介绍。
1.const 修饰指针 称为常量指针
首先常量指针怎么定义 const int* p ;
const 防止int 前面这样就代表指针所指的地址对应的数值不能改变,指针对应的地址可以改变。
就是 *p不能改变,p可以重新赋值地址,因为const 在指针int* 前面因此称为常量指针。
int a = 10;
int b = 20;
const int* p = &a;
// 指向的值不可以修改,指针的指向可以修改
// *p = 20; 错误
// p = &b; // 正确
2.const 修饰常量 称为指针常量
指针常量怎么定义 int* const p;
这个对应的指针p就是,指针的地址不可以修改,指针的地址里面对应的值可以修改。因为const在指针前面放着就是在p前面放着,我们又知道p是指针,因此这种形式就是p不可以修改,*p可以修改。 因为 int *指针 const常量,因此称这种方式为指针常量。
int a = 10;
int b = 20;
// 2.const 修饰常量 指针常量
int* const p1 = &b;
// 指向的值可以修改,指针的指向不可以修改
// *p1 = 20; // 正确
// p = &b; 错误
3.const 修饰指针和常量
看了上面那个我们知道谁前面加const,谁的值就不能修改,那么要是我们想指针和值都不修改那么就这样定义。const int* const p 在int前面和指针p前面都加const。这个指向的值不可以修改,指针的指向不可以修改。
#include <iostream>
using namespace std;
int main()
{
// 1.const 修饰指针 常量指针
int a = 10;
int b = 20;
const int* p = &a;
// 指向的值不可以修改,指针的指向可以修改
// *p = 20; 错误
p = &b; // 正确
// 2.const 修饰常量 指针常量
int* const p1 = &b;
// 指向的值可以修改,指针的指向不可以修改
*p1 = 20; // 正确
// p = &b; 错误
// 3.const 修饰指针和常量
const int* const p2 = &a;
// 指向的值不可以修改,指针的指向不可以修改
system("pause");
return 0;
}
3.指针和数组
数组:数组是连续的空间中存放相同类型的元素
数组名就是指针。
接下来我们通过一个例子来演示用指针遍历数组。
#include <iostream>
using namespace std;
int main()
{
int arr[10] = { 0,1,2,3,4,5,6,7,8,9 };
cout << "第一个元素是 " << arr[0] << endl;
int* p = NULL;
p = arr; // arr就是数组的首地址
cout << "第一个元素" << *p << endl;
p++; // 指针p就往后移动四个字节(int是四个字节),因为是int*
cout << "第二个元素" << *p << endl;
cout << "指针便利数组" << endl;
int* p2 = arr;
for (int i = 0; i < 10; i++)
{
cout << *p2 << endl;
p2++;
}
system("pause");
return 0;
}
4.指针和函数
指针和函数,前面我们学习函数的时候传递的都是一个值例如
void print_a(int a)
那我们要往函数里面传递指针应该怎么定义函数
void print_a(int* a)
下面是一个函数指针的实例
#include <iostream>
using namespace std;
int arr[10] = { 9,5,8,6,14,2,98,10,51,16 };
void bubblleSort(int* arr, int len)
{
for (int i = 0; i < len; i++)
{
for (int j = 0; j < len - i-1; j++)
{
if (arr[j] > arr[j + 1])
{
int temp = arr[j];
arr[j] = arr[j + 1];
arr[j + 1] = temp;
}
}
}
}
void print_Arr(int* arr, int len)
{
int* p;
p = arr;
for (int i = 0; i < len; i++)
{
cout << *p << endl;
p++;
}
}
int main()
{
bubblleSort(arr,10);
print_Arr(arr,10);
return 0;
}