c语言学习(指针二)

1. const关键字的基本用法

#include<stdio.h>

int main()
{
    const int n = 0;  // const将n变成是一个常量,不能被修改
    n = 100;          // error; 尝试修改常量n会报错
}

2. 通过指针修改const变量

int main()
{
    const int n = 0;
    int* p = &n;
    *p = 100;  // 这样可以将n的值修改为100,因为p是一个指向int的指针
    printf("%d\n", n); 
}

3. const修饰指针(const在*左边)

int main()
{
    const int n = 0;
    // const 放在*左边约束*p
    int const* p = &n;  // 这样就将*p变成了一个常变量
    // *p = 100; 无法修改了;
    int b = 100;
    p = &b;  // *p不能改,但是可以改p的地址,进而指向其他变量
    printf("%d\n", *p);  // 输出100
}

4. const修饰指针(const在*右边)

int main()
{
    const int n = 0;
    int* const p = &n;  // p是一个常量指针
    *p = 100;           // *p是可以改的
    int b = 1000;
    p = &n;             // p是不能改的,指针p的地址不能被修改
}

5. 野指针问题

int main()
{
    int* p;
    *p = 10;  // 这里的*p就是一个野指针,指向一个未定义的内存地址
    printf("%d", *p);
}

6. 指针正确遍历数组

int main()  // 正确打印
{
    int arr1[10] = {0,1,2,3,4,5};
    int i = 0;
    int* p = &arr1[0];
    for (i = 0; i <= 9; i++)
    {
        *p = i;
        printf("%d ", arr1[i]);
        p++;
    }
}

7. 指针越界访问问题

int main()  // 野指针越界访问错误打印
{
    int arr1[10] = { 0,1,2,3,4,5 };
    int i = 0;
    int* p = &arr1[0];
    for (i = 0; i <= 9; i++)
    {
        *(p++) = i;
        printf("%d ", *p);  // 这里的*p就是野指针,而且前面p++把这里搞错位了
    }
}

8. 返回局部变量指针的问题

int* test()
{
    int a = 10;  // 但如果前面加static修饰a,则a的生命周期变成了整个程序运行期间
    return &a;   // 返回局部变量的地址,a在函数结束后会被销毁
}

int main()
{
    int* p = test();  // a只有在test函数内才是有效的,*p变成了野指针
    printf("%d\n", *p);  // 这里会导致未定义行为,因为p指向的内存地址已经无效了
}

9. assert宏的使用

#define NDEBUG  // 定义NDEBUG宏可以禁用assert宏的功能
#include<assert.h>

int main()
{
    int* p = NULL;
    assert(p != NULL);  // assert宏用于调试,检查条件是否为真
    printf("%d", a);
}

10. 使用异或运算交换值

void swap(int* pa, int* pb)
{
    *pa = *pa ^ *pb;  // 异或运算交换值
    *pb = *pa ^ *pb;
    *pa = *pa ^ *pb;
}

int main()
{
    int a = 10;
    int b = 20;
    printf("a=%d,b=%d\n", a, b);
    swap(&a, &b);  // 传地址调用swap函数交换a和b的值
    printf("a=%d,b=%d\n", a, b);
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值