野指针我老熟人了。。。。
基本概念
作用: 通过指针间接访问内存
- 内存编号是从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++中,当你将数组作为参数传递给函数时,它实际上被转换为一个指向数组首元素的指针。这意味着在函数内部,你没有数组的大小信息。因此,在函数内部无法直接计算数组的长度。