1.指針的定義和使用
int point1(){//定義指針int a = 10;//指針定義語法: 數據類型 * 指針變量名int * p;cout << "sizeof (int(*)) --> " << sizeof(p) << endl;//讓指針記錄變量a的地址 & 取址符p = &a ;cout << "指針p為:" << p << endl;cout << "變量a的地址為:" << &a << endl;cout << "變量a的值為:" << a << endl;/*** 使用指針 通過<br>解引用</br>的方式來找到指針指向的內存* 指針前加 * 代表解引用,找到指針指向的內存中的地址*/*p = 500;int b = *p;cout << "變量b的值為:" << b << endl;cout << "變量a的值為:" << a << endl;cout << "*p的值為:" << *p << endl;cout << "變量a的地址為:" << &a << endl;cout << "變量b的地址為:" << &b << endl;}輸出:sizeof (int(*)) --> 8指針p為:0x16ae5f738
變量a的地址為:0x16ae5f738
變量a的值為:10變量b的值為:500
變量a的值為:500
*p的值為:500
變量a的地址為:0x16ae5f738
變量b的地址為:0x16ae5f72c
2.指針常量和常量指針
指針常量?
?特點:指針的指向不能改,指針指向的值可以改 (內存地址不會變,但是內存地址指向的值會改變)
int a = 20;int b = 30;cout << "變量a的值:" << a << endl;cout << "變量a的地址:" << &a << endl;//指針常量 特點:指針的指向不能改,指針指向的值可以改 (內存地址不會變,但是內存地址指向的值會改變)int * const p1 = &a;cout << "指針p:" << p1 << endl; //輸出的地址cout << "指針p:" << *p1 << endl; // 輸出地址指向的值// p1 = &b; //報錯,*p1 = 50;cout << "指針p:" << p1 << endl; //輸出的地址cout << "指針p:" << *p1 << endl; // 輸出地址指向的值輸出:變量a的值:20
變量a的地址:0x16b303738
指針p:0x16b303738
指針p:20
指針p:0x16b303738
指針p:50
常量指針?
特點: 指針的指向可以改,但是指針指向的值不可以改
int a = 50;int b = 30; //常量指針 特點: 指針的指向可以改,但是指針指向的值不可以改const int * p2 = &a;cout << "變量a的值:" << a << endl;cout << "變量a的地址:" << &a << endl;cout << "指針p2:" << p2 << endl;cout << "指針p2指向的值:" << *p2 << endl;//*p2 = 100; //報錯p2 = &b;cout << "變量a的值:" << a << endl;cout << "變量a的地址:" << &a << endl;cout << "變量b的值:" << b << endl;cout << "變量b的地址:" << &b << endl;cout << "指針p2:" << p2 << endl;cout << "指針p2指向的值:" << *p2 << endl;輸出:變量a的值:50
變量a的地址:0x16b06b738
指針p2:0x16b06b738
指針p2指向的值:50
變量a的值:50
變量a的地址:0x16b06b738
變量b的值:30
變量b的地址:0x16b06b734
指針p2:0x16b06b734
指針p2指向的值:30
?3.指針數組 --》 是一個數組
指針數組 -- 存放指針的數組
int* arr[3]; // 整形指針的數組
char* arr1[10]; // 字符型指針的數組
4.數組指針 --》 是一個指針
int main()
{int* p = NULL; // p是整形指針 -- 指向整形的指針 -- 存放整形的地址char* pc = NULL; // pc是字符指針 -- 指向字符的指針 -- 存放字符的地址// 數組指針 -- 是不是指向數組的指針? -- 存放數組的地址int arr[10] = {0,6,0};printf("數組首元素地址 %p \n",arr);printf("數組首元素地址 %p \n",&arr[0]);printf("整個數組的地址 %p \n",&arr);// 如何存放數組地址呢? &arr 指向整個數組的指針// 想讓 parr 指向整個數組(而不僅僅是第一個元素),你需要聲明 parr 為 int (*)[10] 類型的指針。int (*parr)[10] = &arr;printf("parr %p\n",parr);printf("Second element: %d\n", (*parr)[1]); // 通過數組指針訪問第二個元素char pch[10] = {'w','c'};char (*pch1)[10] = &pch;printf("Second element: %c\n", (*pch1)[1]); // 通過數組指針訪問第二個元素// 定義一個字符型指針數組char* pc1[10];// 字符指針的地址又該如何存放呢?char* (*pa)[10] = &pc1;}
下面代碼哪個是數組指針?
Int* p1[10]; // 存放指針的數組
Int (*p2)[10]; // 存放數組地址的指針 √
?
int arr5[10] = {1,2,3,4,5,6,7,8,9,10};int (*arr5_2)[10] = &arr5;for (int i = 0; i < 10; i++) {printf("%d ",(*arr5_2)[i]); // 不太容易理解}printf("\n");// 第二種寫法for (int i = 0; i < 10; i++) {// *arr5_2 == arr5 ==> 首元素的地址 ==》 arr5_2+i 即表示指針向右移動printf("%d ",*(*arr5_2+i));}printf("\n");
5.函數指針 --》 指向函數的指針?
estimate
函數接受一個整數lines
和一個指向函數的指針pf
,這個函數指針指向一個接受int
類型參數并返回double
的函數。
// 函數示例,符合 estimate 的要求
double myFunction(int x) {return x * 1.5;
}void estimate(int lines,double (*pf)(int))
{cout << (*pf)(lines) << endl; // 調用函數指針 pf
}
在
estimate
函數內部,(*pf)(lines)
用于調用函數指針pf
,并將lines
作為參數傳遞給它。
*pf
是一個函數指針的解引用操作。pf
是一個指向函數的指針,*pf
解引用這個指針,得到指向的函數。例如,如果
pf
是double (*pf)(int)
類型的函數指針,那么*pf
是一個函數,其參數是int
,返回值是double
。你可以用(*pf)(args)
來調用這個函數,傳遞參數args
。
5.1聲明函數指針
函數指針是指向函數的指針,允許你通過指針來調用函數。
// 函數聲明
void printMessage();
void anotherFunction();// 函數定義
void printMessage() {
std::cout << "Hello, World!" << std::endl;
}void anotherFunction() {
std::cout << "This is another function." << std::endl;
}// 定義一個函數指針,指向返回類型為 void、參數為無的函數
void (*funcPtr)();// 指向 printMessage 函數
funcPtr = printMessage;
(*funcPtr)(); // 調用 printMessage// 指向 anotherFunction 函數
funcPtr = anotherFunction;
(*funcPtr)(); // 調用 anotherFunction// ------------------
// 第一種寫法
typedef int (*ptr1)(int,int);int Add(int a,int b)
{int c = a + b;printf("result is %d\n",c);
}// 一個函數,接受一個整數和一個回調函數
void process(int value1, int value2,ptr1 callback) {// 對值進行某種處理value1 *= 2;value2 *= 2;// 調用回調函數callback(value1,value2);
}process(5,7,Add);// 第二種寫法// 指向函數的指針,用于指向一個接受兩個 int 參數并返回 int 的函數(例如 Add 函數)int (*ptr1)(int,int);// 將函數指針指向 Add 函數ptr1 = Add;// 通過函數指針調用 Add 函數ptr1(5,6);
聲明指向某種數據類型的指針時,必須指定指針指向的類型。同時,聲明指向函數的指針時,也必須指定指針指向的函數類型。這意味著聲明應指定函數的返回類型以及函數的特征標(參數列表)。也就是說,聲明應像函數原型那樣指出有關函數的信息。例如,假設Pam leCoder編寫一個估算時間的函數,其原型如下:
double pam(int)
則正確的指針類型聲明如下:
double (*pf)(int)
這與pam()聲明類似,這是將pam替換成了(*pf)。由于pam是函數,因此( *pf)也是函數,而如果( *pf)是函數,則pf就是函數指針