自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

深入 C++ 和 C 的指針世界

開發(fā)
?在C和C++編程中,指針是一個(gè)至關(guān)重要的概念。從初學(xué)者到高級(jí)開發(fā)者,掌握指針的使用不僅能提高代碼效率,還能增強(qiáng)對(duì)內(nèi)存管理的理解。

在C和C++編程中,指針是一個(gè)至關(guān)重要的概念。從初學(xué)者到高級(jí)開發(fā)者,掌握指針的使用不僅能提高代碼效率,還能增強(qiáng)對(duì)內(nèi)存管理的理解。

一、初級(jí):指針基礎(chǔ)

1.什么是指針?

指針是一個(gè)變量,其值為另一個(gè)變量的地址。簡單來說,指針存儲(chǔ)的是內(nèi)存地址而不是數(shù)據(jù)本身。

#include <stdio.h>
int main() 
{
  int a = 10;
  int* p = &a; // p 是一個(gè)指向 a 的指針
  
  printf("a 的值: %d\n", a); // 輸出 10
  printf("p 指向的地址: %p\n", p); // 輸出 a 的地址
  printf("*p 的值: %d\n", *p); // 輸出 10 (解引用指針 p 獲取值)
  
  return 0;
}

在上面的例子中,int* p 聲明了一個(gè)指向整型變量的指針 p,并將 a 的地址賦給了它。*p 用于解引用指針,從而獲得 a 的值。

2.指針的基本操作

  • 聲明指針:int* p;
  • 獲取變量地址:p = &a;
  • 解引用指針:*p

3.指針和數(shù)組

指針和數(shù)組密切相關(guān)。在很多情況下,指針可以用來遍歷數(shù)組。

#include <stdio.h>
int main() {
int arr[] = {1, 2, 3, 4, 5};
int* p = arr; // p 指向數(shù)組的第一個(gè)元素

for (int i = 0; i < 5; i++) {
printf("%d ", *(p + i)); // 使用指針遍歷數(shù)組
}

return 0;
}

4.指針數(shù)組 

數(shù)組中的元素是指針類型,可以用來存儲(chǔ)一組指針。

int x = 10, y = 20, z = 30;
int *ptrArr[3] = {&x, &y, &z};
printf("Second element: %d\n", *ptrArr[1]); // 訪問指針數(shù)組的第二個(gè)指針?biāo)赶虻闹?/code>

5.數(shù)組指針(pointer to an array) 

是一種指向數(shù)組的指針,它與指向數(shù)組第一個(gè)元素的普通指針不同。數(shù)組指針的主要用途是在處理多維數(shù)組時(shí)更加方便。這里詳細(xì)介紹數(shù)組指針的定義和使用方法。

數(shù)組指針是指向數(shù)組的指針,其定義方式如下:

int (*ptr)[N]; 其中,N是數(shù)組的大小。ptr是一個(gè)指向包含N個(gè)整型元素的數(shù)組的指針。

數(shù)組指針的使用 以下是一些使用數(shù)組指針的示例:

(1) 一維數(shù)組指針

#include <stdio.h>

int main() {
    int arr[5] = {1, 2, 3, 4, 5};
    int (*ptr)[5] = &arr; // ptr是指向包含5個(gè)整型元素的數(shù)組的指針

    printf("First element: %d\n", (*ptr)[0]);
    printf("Second element: %d\n", (*ptr)[1]);

    return 0;
}

在這個(gè)例子中,ptr指向數(shù)組arr,通過(*ptr)[i]訪問數(shù)組中的元素。

(2) 二維數(shù)組指針 

對(duì)于二維數(shù)組,數(shù)組指針的使用更為常見和有用:

#include <stdio.h>

int main() {
    int arr[3][4] = {
        {1, 2, 3, 4},
        {5, 6, 7, 8},
        {9, 10, 11, 12}
    };

    int (*ptr)[4] = arr; // ptr是指向包含4個(gè)整型元素的數(shù)組的指針

    for (int i = 0; i < 3; ++i) {
        for (int j = 0; j < 4; ++j) {
            printf("%d ", ptr[i][j]);
        }
        printf("\n");
    }

    return 0;
}

在這個(gè)例子中,ptr是一個(gè)指向包含4個(gè)整型元素的數(shù)組的指針,也就是指向二維數(shù)組的每一行。通過ptr[i][j]訪問二維數(shù)組中的元素。

二、中級(jí):指針進(jìn)階

1.指針的指針

指針不僅可以指向數(shù)據(jù),還可以指向另一個(gè)指針,這種情況稱為指針的指針。

#include <stdio.h>
int main()
{
  int a = 10;
  int* p = &a;
  int** pp = &p; // pp 是一個(gè)指向指針 p 的指針
  
  printf("a 的值: %d\n", a); // 輸出 10
  printf("*p 的值: %d\n", *p); // 輸出 10
  printf("**pp 的值: %d\n", **pp); // 輸出 10
  
  return 0;
}

2.函數(shù)指針

函數(shù)指針是指向函數(shù)的指針,可以用來動(dòng)態(tài)調(diào)用函數(shù)。

#include <stdio.h>

int add(int a, int b) {
return a + b;
}

int main() {
int (*func_ptr)(int, int) = &add; // 聲明一個(gè)指向函數(shù)的指針

int result = func_ptr(3, 4); // 調(diào)用函數(shù)
printf("結(jié)果: %d\n", result); // 輸出 7

return 0;
}

3.指針函數(shù) 

是一個(gè)返回指針的函數(shù)。它與函數(shù)指針不同,函數(shù)指針是指向函數(shù)的指針,而指針函數(shù)是返回值為指針類型的函數(shù)。下面詳細(xì)介紹指針函數(shù)的定義、使用方法及一些常見的例子。

定義指針函數(shù),指針函數(shù)的定義方式是指定函數(shù)返回值為指針類型,例如:

int* func();

這表示func是一個(gè)返回int類型指針的函數(shù)。

指針函數(shù)的使用 指針函數(shù)通常用于動(dòng)態(tài)分配內(nèi)存、返回?cái)?shù)組、字符串或結(jié)構(gòu)體等情況。以下是一些使用指針函數(shù)的例子:

(1) 返回指向單個(gè)變量的指針

#include <stdio.h>

int* getNumber() {
    static int num = 42; // 使用static使num的生命周期延續(xù)到函數(shù)之外
    return #
}

int main() {
    int *ptr = getNumber();
    printf("Number: %d\n", *ptr);
    return 0;
}

在這個(gè)例子中,getNumber函數(shù)返回指向num的指針。因?yàn)閚um是靜態(tài)變量,它在函數(shù)返回后依然存在。

(2) 返回動(dòng)態(tài)分配內(nèi)存的指針

#include <stdio.h>
#include <stdlib.h>

int* allocateArray(int size) {
    int *arr = (int *)malloc(size * sizeof(int));
    return arr;
}

int main() {
    int *arr = allocateArray(5);
    if (arr != NULL) {
        for (int i = 0; i < 5; i++) {
            arr[i] = i * 2;
        }
        for (int i = 0; i < 5; i++) {
            printf("%d ", arr[i]);
        }
        printf("\n");
        free(arr); // 別忘了釋放內(nèi)存
    }
    return 0;
}

這個(gè)例子中,allocateArray函數(shù)返回一個(gè)指向動(dòng)態(tài)分配內(nèi)存的指針。

(3) 返回指向數(shù)組的指針

復(fù)制代碼
#include <stdio.h>

int* getArray() {
    static int arr[5] = {1, 2, 3, 4, 5};
    return arr;
}

int main() {
    int *ptr = getArray();
    for (int i = 0; i < 5; i++) {
        printf("%d ", ptr[i]);
    }
    printf("\n");
    return 0;
}

在這個(gè)例子中,getArray函數(shù)返回指向靜態(tài)數(shù)組arr的指針。靜態(tài)數(shù)組在函數(shù)返回后依然存在,所以返回的指針是有效的。

(4) 常見的應(yīng)用場景 

  • 字符串操作:函數(shù)返回指向字符串的指針,例如處理輸入輸出字符串。
  • 鏈表操作:函數(shù)返回指向鏈表節(jié)點(diǎn)的指針,用于創(chuàng)建、插入、刪除鏈表節(jié)點(diǎn)。
  • 動(dòng)態(tài)內(nèi)存管理:函數(shù)返回動(dòng)態(tài)分配的內(nèi)存指針,用于數(shù)組、結(jié)構(gòu)體等的動(dòng)態(tài)創(chuàng)建和管理。

4.動(dòng)態(tài)內(nèi)存分配

動(dòng)態(tài)內(nèi)存分配是指在運(yùn)行時(shí)分配內(nèi)存,而不是在編譯時(shí)。C語言提供了 malloc、calloc 和 free 函數(shù)來進(jìn)行動(dòng)態(tài)內(nèi)存分配和釋放。

#include <stdio.h>
#include <stdlib.h>

int main() {
int* p = (int*)malloc(sizeof(int) * 5); // 分配5個(gè)整數(shù)大小的內(nèi)存

if (p == NULL) {
printf("內(nèi)存分配失敗\n");
return 1;
}

for (int i = 0; i < 5; i++) {
p[i] = i + 1; // 使用分配的內(nèi)存
}

for (int i = 0; i < 5; i++) {
printf("%d ", p[i]);
}

free(p); // 釋放內(nèi)存

return 0;
}

常量指針和指針常量是兩個(gè)非常重要的概念,在C和C++中經(jīng)常被用到。它們分別表示指針和指針指向的內(nèi)容的常量性不同。

5.常量指針(const pointer)

指針本身是常量,不能修改指向的地址,但可以修改指針指向的內(nèi)容。

int x = 10;
int y = 20;
const int *ptr = &x; // 常量指針,指向一個(gè)整型常量
*ptr = 5; // 錯(cuò)誤,不能通過常量指針修改指向的內(nèi)容
ptr = &y; // 正確,可以修改常量指針指向的地址

6.指針常量(pointer to const)

指針指向的內(nèi)容是常量,不能通過指針修改其指向的內(nèi)容,但可以修改指針指向的地址。

int x = 10;
int y = 20;
int *const ptr = &x; // 指針常量,指針本身是常量,指向一個(gè)整型變量
*ptr = 5; // 正確,可以通過指針修改指向的內(nèi)容
ptr = &y; // 錯(cuò)誤,不能修改指針常量指向的地址

總的來說,常量指針用于保護(hù)指向的內(nèi)容不被修改,而指針常量用于保護(hù)指針本身不被修改。在實(shí)際編程中,根據(jù)需求選擇合適的類型可以增強(qiáng)代碼的安全性和可讀性。

7.常量指針常量(const pointer to const)

是指指針本身和指針指向的內(nèi)容都是常量,即既不能通過指針修改指向的地址,也不能通過指針修改指向的內(nèi)容。

int x = 10;
const int y = 20;

const int *const ptr = &x; // 常量指針常量,指針和指向的內(nèi)容都是常量
*ptr = 5; // 錯(cuò)誤,不能通過指針修改指向的內(nèi)容
ptr = &y; // 錯(cuò)誤,不能修改指針指向的地址

在上面的例子中,ptr是一個(gè)指向整型常量的常量指針常量,因此既不能通過ptr修改指向的內(nèi)容,也不能修改ptr指向的地址。這種類型的指針通常用于指向常量數(shù)據(jù),以確保數(shù)據(jù)的不可變性。

三、高級(jí):指針高級(jí)用法

1.指向函數(shù)的指針數(shù)組 

指針數(shù)組可以用來存儲(chǔ)多個(gè)函數(shù)指針,從而實(shí)現(xiàn)動(dòng)態(tài)調(diào)用不同的函數(shù)。

#include <stdio.h>

int add(int a, int b) {
return a + b;
}

int subtract(int a, int b) {
return a - b;
}

int multiply(int a, int b) {
return a * b;
}

int main() {
int (*func_ptr[])(int, int) = {add, subtract, multiply};

int x = 10, y = 5;
for (int i = 0; i < 3; i++) {
printf("結(jié)果: %d\n", func_ptr[i](x, y));
}

return 0;
}

2.指針與數(shù)據(jù)結(jié)構(gòu)* 

在數(shù)據(jù)結(jié)構(gòu)中,指針用于實(shí)現(xiàn)鏈表、樹等結(jié)構(gòu)。以下是單鏈表的簡單實(shí)現(xiàn):


#include <stdio.h>
#include <stdlib.h>

struct Node {
int data;
struct Node* next;
};

void printList(struct Node* n) {
while (n != NULL) {
printf("%d ", n->data);
n = n->next;
}
}

int main() {
struct Node* head = NULL;
struct Node* second = NULL;
struct Node* third = NULL;

head = (struct Node*)malloc(sizeof(struct Node));
second = (struct Node*)malloc(sizeof(struct Node));
third = (struct Node*)malloc(sizeof(struct Node));

head->data = 1;
head->next = second;

second->data = 2;
second->next = third;

third->data = 3;
third->next = NULL;

printList(head);

free(head);
free(second);
free(third);

return 0;
}

3.多維數(shù)組與指針

多維數(shù)組可以使用指針進(jìn)行遍歷和操作。

int main() 
{
int arr[2][3] = {{1, 2, 3}, {4, 5, 6}};
int (*p)[3] = arr; // 指向包含3個(gè)整數(shù)的一維數(shù)組的指針

for (int i = 0; i < 2; i++) 
{
  for (int j = 0; j < 3; j++) 
  {
    printf("%d ", p[i][j]);
  }
  printf("\n");
}

return 0;
}

4.指針的陷阱與安全

指針的使用雖然強(qiáng)大,但也伴隨著潛在的風(fēng)險(xiǎn),如懸空指針、野指針、緩沖區(qū)溢出等。 

  • 懸空指針:指針指向的內(nèi)存已經(jīng)被釋放,但指針本身未被重置為NULL。 
  • 野指針:指針未初始化或指向未分配的內(nèi)存區(qū)域。
#include <stdio.h>
#include <stdlib.h>

int main() {
int* p = (int*)malloc(sizeof(int));
*p = 10;

free(p);
p = NULL; // 避免懸空指針

if (p != NULL) {
*p = 20; // 避免野指針
} else {
printf("指針已被釋放\n");
}

return 0;
}

5.C++中的智能指針 

C++11引入了智能指針,用于自動(dòng)管理內(nèi)存,避免內(nèi)存泄漏。常見的智能指針包括 std::unique_ptr 和 std::shared_ptr。

#include <iostream>
#include <memory>

class Test {
public:
Test() { std::cout << "構(gòu)造函數(shù)\n"; }
~Test() { std::cout << "析構(gòu)函數(shù)\n"; }
};

int main() {
std::unique_ptr<Test> ptr1(new Test());
std::shared_ptr<Test> ptr2 = std::make_shared<Test>();

{
std::shared_ptr<Test> ptr3 = ptr2;
std::cout << "共享計(jì)數(shù): " << ptr2.use_count() << std::endl;
}

std::cout << "共享計(jì)數(shù): " << ptr2.use_count() << std::endl;

return 0;
}

6.指針的最佳實(shí)踐 

  • 初始化指針:聲明指針時(shí)盡量初始化。
  • 使用智能指針:在C++中盡量使用智能指針管理動(dòng)態(tài)內(nèi)存。 
  • 避免懸空指針和野指針:釋放內(nèi)存后將指針置為NULL,使用指針前確保其指向有效內(nèi)存。 
  • 定期檢查內(nèi)存泄漏:使用工具如Valgrind進(jìn)行內(nèi)存檢查。
責(zé)任編輯:趙寧寧 來源: AI讓生活更美好
相關(guān)推薦

2024-04-10 12:14:36

C++指針算術(shù)運(yùn)算

2014-01-24 09:49:01

C++指針

2024-01-25 11:42:00

C++編程指針常量

2011-04-11 11:09:50

this指針

2021-12-21 15:31:10

C++語言指針

2021-06-10 08:51:57

C++指針聲明指針相關(guān)概念

2024-03-28 18:12:28

指針函數(shù)指針C++

2023-11-22 13:22:51

C++函數(shù)

2010-01-26 13:42:28

C++指針

2010-01-18 15:53:27

C++析構(gòu)函數(shù)

2011-07-13 16:14:53

C++引用指針

2011-04-19 16:38:00

對(duì)象指針指針C++

2011-04-19 09:19:09

C++指針

2011-07-15 01:38:56

C++this指針

2024-01-09 09:23:12

指針C++

2011-04-11 14:18:37

CC++指針

2021-10-27 16:27:20

C++指針操控

2010-01-28 13:57:19

C++指針基礎(chǔ)

2011-07-12 13:01:00

CC++

2024-01-29 16:55:38

C++引用開發(fā)
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)