C 知识量:16 - 74 - 317
C语言对于指针提供了9种不同的基本操作方法:
赋值:可以把地址赋给指针。例如,用数组名、带地址运算符(&)的变量名、另一个指针进行赋值。
解引用:*运算符给出指针指向地址上储存的值。
取址:和所有变量一样,指针变量也有自己的地址和值。对指针而言,&运算符给出指针本身的地址。
递增指针:递增指向数组元素的指针可以让该指针移动至数组的下一个元素。
递减指针:递减指向数组元素的指针可以让该指针移动至数组的上一个元素。
指针与整数相加:可以使用+运算符把指针与整数相加,或整数与指针相加。无论哪种情况,整数都会和指针所指向类型的大小(以字节为单位)相乘,然后把结果与初始地址相加。
指针减去一个整数:可以使用-运算符从一个指针中减去一个整数。指针必须是第1个运算对象,整数是第2个运算对象。该整数将乘以指针指向类型的大小(以字节为单位),然后用初始地址减去乘积。
指针求差:可以计算两个指针的差值。通常,求差的两个指针分别指向同一个数组的不同元素,通过计算求出两元素之间的距离。差值的单位与数组类型的单位相同。
比较:使用关系运算符可以比较两个指针的值,前提是两个指针都指向相同类型的对象。
下面是一个指针操作的示例:
#include <stdio.h> int main(void) { int number[5] = {100, 200, 300, 400, 500}; int * ptr1, *ptr2, *ptr3; ptr1 = number; // 把一个地址赋值给指针ptr1 ptr2 = &number[2]; // 把一个地址赋值给指针ptr2 // 解引用指针,以及获得指针的地址 printf("pointer value, dereferenced pointer, pointer address:\n"); printf("ptr1 = %p, *ptr1 =%d, &ptr1 = %p\n", ptr1, *ptr1, &ptr1); printf("ptr2 = %p, *ptr2 =%d, &ptr2 = %p\n", ptr2, *ptr2, &ptr2); // 指针与整数相加 ptr3 = ptr1 + 4; printf("\nadding an int to a pointer:\n"); printf("ptr1 + 4 = %p, *(ptr1 + 4) = %d\n", ptr1 + 4, *(ptr1 + 4)); ptr1++; // 递增指针 printf("\nvalues after ptr1++:\n"); printf("ptr1 = %p, *ptr1 = %d, &ptr1 = %p\n", ptr1, *ptr1, &ptr1); ptr2--; // 递减指针 printf("\nvalues after --ptr2:\n"); printf("ptr2 = %p, *ptr2 = %d, &ptr2 = %p\n", ptr2, *ptr2, &ptr2); --ptr1; // 恢复为初始值 ++ptr2; // 恢复为初始值 printf("\nPointers reset to original values:\n"); printf("ptr1 = %p, ptr2 = %p\n", ptr1, ptr2); // 一个指针减去另一个指针 printf("\nsubtracting one pointer from another:\n"); printf("ptr2 = %p, ptr1 = %p, ptr2 - ptr1 = %td\n", ptr2, ptr1, ptr2 - ptr1); // 一个指针减去一个整数 printf("\nsubtracting an int from a pointer:\n"); printf("ptr3 = %p, ptr3 - 2 = %p\n", ptr3, ptr3 - 2); system("pause"); return 0; }
运行结果为:
pointer value, dereferenced pointer, pointer address: ptr1 = 0061ff18, *ptr1 =100, &ptr1 = 0061ff14 ptr2 = 0061ff20, *ptr2 =300, &ptr2 = 0061ff10 adding an int to a pointer: ptr1 + 4 = 0061ff28, *(ptr1 + 4) = 500 values after ptr1++: ptr1 = 0061ff1c, *ptr1 = 200, &ptr1 = 0061ff14 values after --ptr2: ptr2 = 0061ff1c, *ptr2 = 200, &ptr2 = 0061ff10 Pointers reset to original values: ptr1 = 0061ff18, ptr2 = 0061ff20 subtracting one pointer from another: ptr2 = 0061ff20, ptr1 = 0061ff18, ptr2 - ptr1 = 2 subtracting an int from a pointer: ptr3 = 0061ff28, ptr3 - 2 = 0061ff20
以上代码中,用于显示两个指针相减结果的printf()函数转换说明为%td。
需要注意的是:编译器不会检查指针是否仍指向数组元素,即当移动指针时,需要自己确保指针没有超出数组元素范围。
需要格外注意的是:千万不要解引用未初始化的指针。例如:以下代码是错误的。
int * p; //未初始化的指针p *p = 100; //错误的解引用
因为指针p没有初始化,其存储的地址是随机的,将值100赋给*p后,将不会知道值100到底存储到了哪里。这可能不会出什么错,也可能会擦写数据或代码,或者导致程序崩溃。
创建一个指针时,系统只分配储存指针本身的内存,指针内的值(即地址)是随机的。因此,在使用指针之前,必须先用已分配的地址初始化它,使指针指向一个明确的地址。例如:
int n = 100;//创建一个变量n int * p; //创建一个未初始化的指针p p = & n; //初始化指针p,使p指向变量n的地址
当程序创建变量n后,会给变量n分配一个内存空间即变量地址,创建指针p后,也会为指针p自身分配一个地址,但是p的值是随机的。将变量n的地址赋给指针p后,指针p的值就将确定为变量n的地址,这样就可以解引用指针p,会得到变量n的值:100。
Copyright © 2017-Now pnotes.cn. All Rights Reserved.
编程学习笔记 保留所有权利
MARK:3.0.0.20240214.P35
From 2017.2.6