C语言指针类型,指针定义、用法

        在C语言中,指针是一个非常核心和强大的概念。

        指针是一个变量,它存储了另一个变量的内存地址。

        通过指针,程序能够直接操作内存中的数据,这为编程提供了极大的灵活性。

1、指针的声明

    (1)类型+*+变量名
int *p;
double *d;
char *c;
string *str;

class red;
read* r;
      (2)有相同的2个指针吗
// 定义
int a;
int b;

int *p1;
int *p2;


// 初始化整数
a = 10;
b = 10;

// 初始化指针
p1=&a;
p2=&a;

        如上图,定义了int类型的变量a和b,那么a和b是相同的变量吗?

                很简单他们是2个变量,a和b都有自己的地址,地址内存储的整数值都未初始化;

        指针p1和p2是相同的指针吗?        

                他俩是不同的指针,p1和p2,他俩都有独属于自己的地址,地址内存储的值未初始化

        再次思考,初始化整数执行后,a=b=10;a和b是相同的变量吗?

                依然不是相同的变量,只是他们拥有相同值,a和b各自地址内都存储了相同的整数10;因为修改a并不影响b的值。即后续如果a=20,他不影响b=10。他俩不是同一个变量。

        再次思考,初始化指针后,p1和p2是相同的指针吗?

                依然不是相同的变量,只是他们拥有相同的指向,都指向a的地址;因为修改p1的指向并不影响p2的指向。即后续如果p1=&b,他不影响p2。他俩不是同一个变量。

        结论:声明几个指针,就有几个指针,即便指向相同,他们也不是同一个指针。方便理解当指针做函数参数时,不混淆。

2、指针初始化

        (1)使用其它变量的地址初始化

        使用变量n的地址来初始化指针p

int n=10;
int*p = &n;
        (2)数组名初始化指针

        数组名代表数字首元素的地址

int arr[10];

int*p = arr;
        (3)动态分配内存初始化

        使用 malloc函数 或 new可以在堆上分配内存,并返回一个指向这块内存的指针。

class Test;

Test* p;
p = new Test();
        (4)使用空初始化
class Test;

Test*p;
p = NULL;
p = nullptr;

3、地址操作符号&

        在一个变量前+&可以取他的地址。

int n =10;

int *p;

// 打印整数变量n的地址
cout<<&n;
// 打印指针变量P的地址
cout<<&p;

4、间接引用操作符*

        在指针前+*可以取他指向的地址里的值

int n = 10;
int*p = &n;

// 输出指针p指向的地址里的值,10
cout<<*p;
        (1)char*类型指针

        *p和p是等价的都输出 字符 a

        char c = 'a';
        char* p = &c;
        cout << *p << endl;
        cout << p << endl;

       (2) int*类型的 直接输出p会输出n的地址,等价于&n

int n = 10;
int*p = &n;

// 输出指针p指向的地址里的值,10
cout<<*p;

// 2者相同
cout<<p;
cout<<&n;

5、指针的算数计算

        指针可以进行++、--、等运算

int arr[10];

int *p = arr;

int *p1 = p++;
int *p2 = P++;

6、指针的安全性       

        由于指针操作的低级特性,不正确的使用可能导致程序错误,如访问无效的内存地址

        例如:使用未初始化的指针、使用指向已经被释放的指针等。

7、函数参数

        指针可以作为函数参数

        判断2次打印结果是否相同。

int n1=10;
int n2=20;

void func(int*p)
{
    p=&n2;
}

main()
{
    int* p = &n1;
    cout<<*p<<endl;
    func(p);
    cout<<*p<<endl;
}

        打印:10         10。参考指针声明里的解释

8、指针日常开发中的一些注意事项

(1)初始化指针:
           确保所有指针在使用前都被初始化。未初始化的指针可能包含任意内存地址,使用它们可能导致未定义行为。

(2)使用 `NULL` 指针:
           在声明指针后,将其设置为 `NULL`,直到你为其分配了有效的内存地址。

(3) 检查指针有效性:
           在通过指针访问内存之前,检查它是否指向一个有效的内存区域。

(4)避免越界访问:
           访问数组时,确保不会超出数组的边界,这可能会导致数组越界错误。

(5)使用 `sizeof` 操作符:
           使用 `sizeof` 来确定数据类型的大小,避免硬编码值,这有助于防止错误的计算。

(6)谨慎使用 `malloc` 和 `free`:
           使用 `malloc` 分配内存后,确保使用 `free` 释放内存,避免内存泄漏。同时,检查 `malloc` 返回的指针是否为 `NULL`。

(7)避免重复释放内存:
           一旦内存被释放,就不应该再次释放它,这会导致未定义行为。

(8)使用指针数组时要小心:
           当使用指针数组存储多个指针时,确保每个指针都被正确初始化。

(9)注意指针的生命周期:
           动态分配的内存应该在不再需要时及时释放,避免内存泄漏。

(10)使用引用传递时要小心:
            当函数通过指针参数修改变量时,确保调用者了解这种影响。

(11)避免使用悬空指针:
            一旦内存被释放,相应的指针应立即设置为 `NULL`,避免成为悬空指针。

(12)类型安全:
            在将数据类型转换为指针类型时,确保这种转换是安全的。

(13)理解指针和数组的关系:
            数组名是指向数组首元素的指针,对数组名的操作实际上是对指针的操作。

        

        指针声明时要初始化为NULL,使用前先判断是否为NULL。

  • 11
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值