野指针我老熟人了。。。。
基本概念
作用: 通过指针间接访问内存
- 内存编号是从0开始记录的,一般用十六进制数字表示
- 可以利用指针变量保存地址
指针变量的定义和使用
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
| int main(){
int a=10; int * p;
p=&a; cout<<&a<<endl; cout<<p<<endl;
cout<<"*p = "<<*p<<endl;
system("pause");
return 0;
}
|
指针变量和普通变量的区别
- 普通变量存放的是数据,指针变量存放的是地址
- 指针变量可以通过”*”操作符,操作指针变量指向的内存空间,这个过程称为解引用
用&获取变量的地址
指针所占内存空间
Q: 指针也是种数据类型,那么这种数据类型占用多少空间呢?
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| int main() {
int a = 10;
int * p; p = &a;
cout << *p << endl; cout << sizeof(p) << endl; cout << sizeof(char *) << endl; cout << sizeof(float *) << endl; cout << sizeof(double *) << endl;
system("pause");
return 0; }
|
在C++中,指针类型的大小取决于所运行的系统架构。通常情况下:
- 在32位系统中,指针通常占用4个字节。
- 在64位系统中,指针通常占用8个字节。
空指针和野指针
空指针
1 2 3 4 5 6 7 8 9 10 11 12 13
| int main() {
int * p = NULL;
cout << *p << endl;
system("pause");
return 0; }
|
野指针
野指针: 指针变量指向非法的内存空间
1 2 3 4 5 6 7 8 9 10 11 12
| int main() {
int * p = (int *)0x1100;
cout << *p << endl;
system("pause");
return 0; }
|
在编写C++程序时,应确保指针指向有效的内存地址。直接将指针指向一个硬编码的地址,而没有确保该地址是有效和安全的,是一种危险的做法。正确的做法是使用动态内存分配(如new关键字)来获取内存,或者确保指针指向已分配的内存区域。
空指针和野指针都不是我们申请的空间,因此不要访问
const修饰指针
在C++中,当使用const
修饰指针时,它有两种不同的含义,这取决于const
的位置:
const
位于星号(*)之前:这表示指针指向的内容是常量,即不能通过这个指针修改所指向的数据。但指针本身可以改变,指向不同的地址。1 2 3 4 5
| int x = 10; int y = 20; const int* p = &x; p = &y; *p = 30;
|
const
位于星号(*)之后:这表示指针本身是常量,即不能更改指针的值(它所指向的地址)。但可以通过指针修改它所指向的数据。1 2 3 4 5
| int x = 10; int y = 20; int* const p = &x; *p = 30; p = &y;
|
指针和数组
利用指针访问数组中元素
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| int main() {
int a[] = { 1,2,3,4,5,6,7,8,9,10 };
int* p = a; cout << "第一个元素:" << a[0] << endl; cout << "指针访问第一个元素:" << *p << endl;
for (int i = 0; i < 10; i++) {
cout << *p << endl; p++;
}
system("pause");
return 0; }
|
指针和函数
利用指针作函数参数,可以修改实参的值
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
| void swap1(int a ,int b) { int temp = a; a = b; b = temp; }
void swap2(int * p1, int *p2) { int temp = *p1; *p1 = *p2; *p2 = temp; }
int main() {
int a = 10; int b = 20; swap1(a, b);
swap2(&a, &b);
cout << "a = " << a << endl;
cout << "b = " << b << endl;
system("pause");
return 0; }
|
指针、数组、函数
封装一个函数: 利用冒泡排序,实现对整型数组的升序排序
例如数组:int arr[10]={4,3,6,9,1,2,10,8,7,5};
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39
| void bubbleSort(int * arr, int len) { for (int i = 0; i < len - 1; i++) { for (int j = 0; j < len - 1 - i; j++) { if (arr[j] > arr[j + 1]) { int temp = arr[j]; arr[j] = arr[j + 1]; arr[j + 1] = temp; } } } }
void printArray(int arr[], int len) { for (int i = 0; i < len; i++) { cout << arr[i] << endl; } }
int main() {
int arr[10] = { 4,3,6,9,1,2,10,8,7,5 }; int len = sizeof(arr) / sizeof(int);
bubbleSort(arr, len);
printArray(arr, len);
system("pause");
return 0; }
|
当数组名传入到函数作为参数时,被退化为指向首元素的指针
在C++中,当你将数组作为参数传递给函数时,它实际上被转换为一个指向数组首元素的指针。这意味着在函数内部,你没有数组的大小信息。因此,在函数内部无法直接计算数组的长度。