指针1

函数名在表达式中总是以函数指针的身份呈现,除了取地址运算符以及sizeof。
对于指针,尽最大的限度使用const保护它,无论是传递给函数,还是自己使用。
在编译器中会有两种NULL(每种环境都有唯一确定的NULL):

#define NULL 0
#define NULL ((void*)0)

有什么区别吗?看起来没什么区别都是0,只不过一个是常量,一个是地址为0的指针。

int* temp_int_1 = 0; //无警告
int* temp_int_2 = (void*)0; //无警告
int* temp_int_3 = 10; //出现警告

因为C语言规定当处理上下文的编译器发现常量0出现在指针赋值的语句中,它就作为指针使用,似乎很扯淡,可是却是如此。在字符数组的末尾使用NULL是绝对错误的!虽然它们的本质都是常量0,但由于位置不同所以含义也不同。

对于形参和实参而言两个关系紧密,可以这么理解总是实参将自己的一份拷贝传递给形参,这样形参便能安全的使用实参的值,但也带给我们一些麻烦,最经典的交换两数

void swap_v1(int* val_1, int* val_2)
{
    int temp = *val_1;
    *val_1 = *val_2;
    *val_2 = *val_1;
}

这就是所谓的按址传递,实际上只是将外部指针(实参)的值做一个拷贝,传递给形参val_1与val_2,实际上我们使用:

#define SWAP_V2(a, b) (a += b, b = a - b, a -= b)
#define SWAP_V3(x, y) {x ^= y; y ^= x; x ^= y}

如果输入的两个参数本就指向同一块内存,会发生什么?

SWAP_V2(test_1, test_1);
printf("Now the test_1 is %d\n", test_1);  

会输出Now the test_1 is 0
这是因为当修改test_1上面的值时,test_1上面的值会同时修改。
所以做交换的时候要判断两个参数是不是指向同一块内存。

static inline void swap_final(int* val_1, int* val_2)
{
    if(val_1 == val_2)
        return;
    *val_1 ^= *val_2;
    *val_2 ^= *val_1;
    *val_1 ^= *val_2;
}
#define SWAP(x, y) \
do{                 \
    if(&x == &y)    \
        break;      \
    x ^= y;     \
    y ^= x;     \
    x ^= y;     \
}while(0)

restrict,C语言中的一种类型限定符(Type Qualifiers),用于告诉编译器,对象已经被指针所引用,不能通过除该指针外所有其他直接或间接的方式修改该对象的内容。
要时刻记住,数组与指针是不同的东西。但是为什么下面代码是正确的?

int arr[10] = {10, 9, 8, 7};
int* parr  = arr;

我们还是那句话,结合上下文,编译器推出 arr处于赋值操作符的右侧,默默的将他转换为对应类型的指针,而我们在使用arr时也总是将其当成是指向该数组内存块首位的指针

在char数组中使用指针运算进行操作,提取不同类型的数据,或者是在不同类型数组中,使用char*指针抽取其中内容,才是显示指针运算的用途。但在使用不同类型指针操作内存块的时候需要注意,不要操作无意义的区域或者越界操作。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值