HR's Blog

Swimming 🏊 in the sea🌊of code!

0%

指针

.

Variables that can store addresses are called pointers.

指针一般指向的是这个数据的第一个字节,所以你还需要知道指针所指的类型,这样你才知道数据一共占用多少字节,例如char类型占用一个字节,long占用4个字节。
001

类型名为void表示没有指定类型,所以void*类型的指针可以包含任意类型的数据项地址。类型void*常常用做参数类型,或以独立于类型的方式处理数据的函数的返回值类型。任意类型的指针都可以传送为void*类型的值,在使用它时,再将其转换为合适的类型。例如, int类型变量的地址可以存储在void*类型的指针变量中。要访问存储在void*指针所指地址中的整数值,必须先把指针转化为int *类型。

申明指针

1
2
3
4
5
int *pnumber;
int* pnumber;
int *pnumber = NULL; //指针变量可以和普通变量一起申明。
double value, *pVal, fnum;

指针如果没有初始化比类型没有初始化更危险,因为有可能会覆盖该内存。
NULL被定义在stddef.h,stdlib.h,stdio.h,string.h,time.h,wchar.handlocale.h

给指针对象所指的变量赋值

1
2
3
int number = 99;
int *pnumber = &number;

通过指针访问值

1
2
3
4
5
int number = 15;
int *pointer = &number;
int result = 0;
reuslt = *pointer + 5; //访问指针所指的值,需要在指针前面加*,否则就变成了操作pointer的地址上+5

示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
int number = 0;
int *pnumber = NULL;

number = 10;
printf("number's address: %p\n", &number);
printf("number's value: %d\n\n", number);

pnumber = &number;

printf("pnumber's address:%p\n", (void*)&pnumber);
printf("pnumber's size: %zd bytes\n", sizeof(pnumber));
printf("pnumber's value: %p\n", pnumber);
printf("value pointed to: %d\n", *pnumber);

1
2
3
4
5
6
7
8
number's address: 0x7ffeefbff5c4          //打印number的地址
number's value: 10 //打印number的值

pnumber's address:0x7ffeefbff5b8 //打印pnumber自己本身的地址
pnumber's size: 8 bytes //打印pnumber变量的大小,这里是8是因为用的64位的系统,每个byte是8位
pnumber's value: 0x7ffeefbff5c4 //打印pnumber村粗的值,因为pnumber指向number所以他存储的值就是number的地址。
value pointed to: 10 //打印pnumber所指参数的值。

pnumber 访问是pnumber自己的参数,也就是pnumber所指的参数的地址。
*pnumber访问pnumber所指地址参数的值
&pnumber访问pnumber自己的地址值。
The effect of the * operator is to access the data contained in the address stored at pnumber.
The *operator is called the indirection operator or sometimes the dereferencing operator.

The cast to void* is to prevent a possible warning from the compiler.

使用指针

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
long num1 = 0L;
long num2 = 0L;
long *pnum = NULL;

pnum = &num1;
*pnum = 2L;
++num2;
num2 += *pnum;

pnum = &num2;
++*pnum;

printf("num1 = %ld num2 = %ld *pnum = %ld *pnum + num2 = %ld\n", num1, num2, *pnum, *pnum + num2);
//num1 = 2 num2 = 4 *pnum = 4 *pnum + num2 = 8

表达式++*pnum递增了pnum指向的值。但如果要使用后置的形式,必须写成(*pnum)++。括号很重要,它指定要递增的是数值,而不是地址。这是因为运算符++和一元运算符&的优先级相同,且都是从左到右计算的。

测试NULL指针

1
2
3
int *pvalue = NULL;
int *pvalue = 0;

NULL在C语言中是一个特俗的常量,它相当于数字0的指针。NULL常量定义为((void*))0。给指针赋予0时,就等于它设为NULL

指向常量的指针

1
2
3
long value = 99999L;
const long *pvalue = &value; //定义的pvalue指针无法修改value的值,但是可以改变pvalue指向别的变量地址。通过value还是可以修改。只是不能通过value这个指针修改。

常量指针

1
2
3
int count = 43;
int *const pcount = &count; 指针存储的地址不能改变,但是可以改变pcount所存储地址的变量的值。

1
const long *const kcount = &value:  //定义的kcount指针既不能修改kcount指向的值,也不能修改指向的内存地址。

指针的命名
因为在C中很那区分哪个是指针,哪个是变量。那么如果是指针的话,可以在前面加p作为针名的第一个字母。