void类型指针
void -> 空类型
void* -> 空类型指针,只存储地址的值,丢失类型,无法访问,要访问里面的值
我们必须对指针进行正确的类型转换,然后再间接引用指针
所有其它类型的指针都可以隐式自动转换成 void 类型指针,反之需要强制转换。
cpp
int arr[] = { 1, 2, 3, 4, 5 };
char ch = 'a';
void* ptr = arr;
printf("0x%p\n", ptr);
printf("%d\n", *(int*)ptr);
而且 **void***指针 不允许算术运算
常见错误总结
1.使用未初始化指针
这里面去描述两种场景说明使用未初始化指针的场景
第一种场景 未初始化就使用
int x, * p;
x = 10;
printf("%p\n", p);
p = &x;
第二种场景 比较常见
void func(int* p) {
static int count = 50;
p = &count;
}
int main() {
int x, * p;
func(p);
cout << "p = " << p << endl;
}
怎么解决上面的问题 之前的笔记有提到过 使用二级指针
cpp
#include <iostream>
using namespace std;
void func(int** p) {
static int count = 50;
*p = &count;
}
int main() {
int x, * p;
func(&p);
cout << "p = " << p << endl;
}
2.将值当作地址赋值给指针
怎么解决
1)*p = x;
2)p = &x;
3.忘记解引直接访问内存
cpp
char input[64] = { 'h', 'e', 'l', 'l', 'o' };
char* p1, * p2;
p1 = &input[0];
p2 = &input[1];
if (p1 > p2) {
cout << "p1 is greater than p2" << endl;
}
else {
cout << "p2 is greater than p1" << endl;
}
return 0;
这种情况下 会打印 "p2 is greater than p1"
cpp
#include <iostream>
using namespace std;
int main() {
char input[64] = { 'h', 'e', 'l', 'l', 'o' };
char* p1, * p2;
p1 = &input[0];
p2 = &input[1];
if (*p1 > *p2) {
cout << "p1 is greater than p2" << endl;
}
else {
cout << "p2 is greater than p1" << endl;
}
return 0;
}
4.常见的错误4:再次使用忽略重新赋初值
cpp
#include <iostream>
#include <string>
using namespace std;
int main() {
char input[64];
char* p1 = input;
do {
gets_s(input, 64);
while (*p1 != '\0') printf("%c", *p1++);
} while (strcmp(input, "exit") != 0);
return 0;
}
这种只能打印第一个数字 因为p1没有被重新赋值给input
正确的做法是
cpp
#include <iostream>
#include <string>
using namespace std;
int main() {
char input[64];
char* p1;
do {
printf("Enter a string: ");
gets_s(input, 64);
p1 = input;
while (*p1 != '\0') printf("%c", *p1++);
printf("\n");
} while (strcmp(input, "exit") != 0);
return 0;
}
常量引用
在C++中可以声明const引用
语法:const Type&name = var;
const引用让变量拥有只读属性
|---------------|
| 分两种情况: |
| 1.用变量初始化常引用 |
| 2.用字面量初始化常量引用 |
cpp
// 使用变量初始化常量引用
int a = 10;
const int& b = a;
// 用字面量初始化常量引用
const int& c = 20;//会给引用分配内存空间
函数指针
我们来探究一下 函数有没有指针
cpp
#include <iostream>
#include <string>
using namespace std;
int compare_int(const void* a, const void* b) {
int* pa = (int*)a;
int* pb = (int*)b;
cout << "pa地址:" << &pa << endl;
cout << "pb地址:" << &pb << endl;
return *pa - *pb;
}
int main() {
// 函数有没有地址?
cout << "compare_int: " << &compare_int << endl;
int x = 10, y = 20;
compare_int(&x, &y);
return 0;
}
函数指针的定义
cpp
#include <iostream>
#include <string>
using namespace std;
int compare_int(const void* a, const void* b) {
int* pa = (int*)a;
int* pb = (int*)b;
cout << "pa地址:" << &pa << endl;
cout << "pb地址:" << &pb << endl;
return *pa - *pb;
}
int main() {
// 函数有没有地址?
int(*ptr)(const void*, const void*) = &compare_int;
int x = 10, y = 20;
//函数指针有两种调用方式
//1.解引用方式调用
(*ptr)(&x, &y);
//2.直接调用
ptr(&x, &y);
return 0;
}
上面这个是函数指针和void*指针的应用
cpp
#include <iostream>
#include <string>
using namespace std;
int compare_int(const void* a, const void* b) {
int* pa = (int*)a;
int* pb = (int*)b;
return *pa - *pb;
}
int main() {
// 函数有没有地址?
int arr[12] = { 1, 3, 5, 7, 9, 2, 4, 6, 8, 10, 11, 12 };
int(*ptr)(const void*, const void*) = &compare_int;
int x = 10, y = 20;
qsort(arr, sizeof(arr) / sizeof(arr[0]), sizeof(arr[0]), ptr);
cout << "After sorting: ";
for (int i = 0; i < sizeof(arr) / sizeof(arr[0]); i++) {
cout << arr[i] << " ";
}
return 0;
}
qsort也可以对char数组进行排序
cpp
#include <iostream>
#include <string>
using namespace std;
int compare_int(const void* a, const void* b) {
int* pa = (int*)a;
int* pb = (int*)b;
return *pa - *pb;
}
int compare_char(const void* a, const void* b) {
char* pa = (char*)a;
char* pb = (char*)b;
return *pa - *pb;
}
int main() {
// 函数有没有地址?
char charArray[] = "asodifoadfjdvn";
int(*pCompare)(const void*, const void*) = &compare_char;
qsort(charArray, sizeof(charArray) / sizeof(char), sizeof(char), pCompare);
for (int i = 0; i < sizeof(charArray) / sizeof(char); i++) {
cout << charArray[i];
}
return 0;
}