C语言--指针
文章目录
- 一、指针是什么?
- 指针的四个要点:
- 1、指针的类型
- 2、指针所指向的类型
- 3、指针的值----或者叫指针所指向的内存区或地址
- 4、指针本身所占据的内存区
- 二、指针变量
- 三、指针变量的引用
- 四、指针的算术运算
- 五、指针与字符串
- 六、指针的其它用法
- 1、多级指针 (Multi-level Pointers):
- 2、函数指针 (Function Pointers):
- 3、const与指针:
- 七、指针的常见错误与注意事项
- 1、野指针 (Uninitialized Pointer):
- 2、空指针解引用 (NULL Dereference):
- 3、内存泄漏 (Memory Leak):
- 4、悬垂指针 (Dangling Pointer):
- 5、指针越界访问 (Out-of-Bounds Access):
一、指针是什么?
指针是一个特殊的变量,它里面存储的数值被解释成为内存里的一个地址。
通过这个地址,可以间接地访问和修改该变量的值。
指针的四个要点:
指针的类型、指针所指向的类型、指针的值或者叫指针所指向的内存区、指针本身所占据的内存区。
例:
(1)intptr;
(2)charptr;
(3)int**ptr;
(4)int(ptr)[3];
(5)int(*ptr)[4];
1、指针的类型
把指针声明语句里的指针名字去掉,剩下的部分就是这个指针的类型。
(1)int* ptr; //指针的类型是int*
(2)char* ptr; //指针的类型是char*
(3)int** ptr; //指针的类型是int**
(4)int(ptr)[3];//指针的类型是int()[3]
(5)int*(ptr)[4];//指针的类型是int(*)[4]
2、指针所指向的类型
把指针声明语句中的指针名字和名字左边的指针声明符 * 去掉,剩下的就是指针所指向的类型。
(1)int*ptr; //指针所指向的类型是int
(2)char*ptr; //指针所指向的的类型是char
(3)int*ptr; //指针所指向的的类型是int
(4)int(*ptr)[3]; //指针所指向的的类型是int()[3]
(5)int*(*ptr)[4]; //指针所指向的的类型是int*()[4]
3、指针的值----或者叫指针所指向的内存区或地址
指针的值是指针本身存储的数值,这个值将被编译器当作一个地址,而不是一个一般的数值。
在32 位程序里,所有类型的指针的值都是一个32 位整数,因为32 位程序里内存地址全都是32 位长。
指针所指向的内存区就是从指针的值所代表的那个内存地址开始,长度为sizeof(指针所指向的类型)的一片内存区。
4、指针本身所占据的内存区
指针本身占了多大的内存?你只要用函数sizeof(指针的类型)测一下就知道了。
在32 位平台里,指针本身占据了4 个字节的长度。
二、指针变量
指针变量定义的一般形式为:
类型名: *指针变量名
int *pNums;
注意:
A.变量名前面的“ * ”是一个说明符,用来说明该变量是指针变量,这个“ * ”不能省略.
B.类型名表示指针变量所指向的变量类型,而且只能是指向这种类型的变量.
指针变量允许在定义的时候初始化,如:
int nNumA,nNumB;
Int *pA=&nNumA,*pB=&nNumB;
表示:
定义了两个指向int型变量的指针变量pA和pB,pA的初值为变量nNumA的地址,&nNumA,pB的初值为变量nNumB的地址&nNumB,不是表示*pA的初值为*nNumA,*pB的初值为&nNumB.
三、指针变量的引用
指针变量有两个有关的运算符
A:& 取地址运算符
B:* 指针运算符
例:
&a表示变量a的地址
*p表示指针变量p指向的变量.
指针变量是用来存放地址的,不要给指针变量赋常数值,例如:
int *p=100;
指针变量没有指向确定的地址前,不要对它所指向的对象赋值,
例:int nNum=5,*p=nNum;
如果对指针进行加1操作,会使指针指向下一个元素,例如:将一个int型的指针加1,它指向的地址就会加4,快速理解指针的秘诀是,将指针的类型分为两个概念,一个是指针自身的类型,一个是指针指向的数据的类型。
四、指针的算术运算
指针可以加上或减去一个整数。
指针的这种运算的意义和通常的数值的加减运算的意义是不一样的,以单元为单位。
例:
char a[20];
int *ptr=(int *)a; //强制类型转换并不会改变a 的类型
ptr++;
上例中:
指针ptr 的类型是int*,它指向的类型是int,它被初始化为指向整型变量a。
第3句中,指针ptr被加了1,编译器是这样处理的:
它把指针ptr 的值加上了sizeof(int),在32 位程序中,是被加上了4,因为在32 位程序中,int 占4 个字节。由于地址是用字节做单位的,故ptr 所指向的地址由原来的变量a 的地址向高地址方向增加了4 个字节。由于char 类型的长度是一个字节,所以,原来ptr 是指向数组a 的第0 号单元开始的四个字节,此时指向了数组a 中从第4 号单元开始的四个字节。
即指针的加法或减法都是对指针指向的地址进行加减,prtnew = prtold(+|-) n(sizeof(指针所指向的类型))。
五、指针与字符串
C语言中字符串是通过一维数组来存储的,因此可以使指向字符数组的指针变量来实现字符串的操作,例:用指针变量输出字符串.
char *pszStr=“Hello”;
Printf(“%s\n”,pszStr);
也可写成
Char *string;
String = “Hello”;
一个字符指针变量只能指向一个字符数据,不能同时指向多个字符数据,更不能把字符串全部放到指针变量里,因此写成如下形式的定义语句是错误的
Char *string;
*string = “hello”;
由于字符串是按照字符数组形式存储的,所以对字符串中字符的引用阴阳怪气可以用下标法或指针法.
六、指针的其它用法
1、多级指针 (Multi-level Pointers):
指向指针的指针,例如 int **pp;。常用于动态二维数组或需要修改指针本身的情况。
2、函数指针 (Function Pointers):
指向函数的指针,可以像普通函数一样被调用。常用于实现回调函数和策略模式。
3、const与指针:
const可以修饰指针本身或指针所指向的数据,用于保护数据不被意外修改。
const int *p;:指针指向的数据是常量,不能通过 p修改。
int * const p;:指针本身是常量,不能指向其他地址。
const int * const p;:指针本身和其指向的数据都是常量。
七、指针的常见错误与注意事项
指针的不当使用是C语言程序中最常见的错误来源之一,主要包括:
1、野指针 (Uninitialized Pointer):
指针在声明后未初始化,其值是一个随机地址。解引用野指针会导致未定义行为,通常导致程序崩溃。
解决方法:声明指针时立即初始化为 NULL或一个有效地址。
2、空指针解引用 (NULL Dereference):
解引用值为 NULL的指针会导致程序崩溃。
解决方法:在使用指针前检查其是否为 NULL。
3、内存泄漏 (Memory Leak):
使用 malloc等函数分配内存后,忘记使用 free释放,导致程序占用的内存越来越多。
解决方法:确保每个 malloc都有对应的 free,并在释放后将指针置为 NULL。
4、悬垂指针 (Dangling Pointer):
指针指向的内存已经被释放,但指针本身未被置为 NULL,继续使用该指针会导致错误。
解决方法:释放内存后,立即将指针置为 NULL。
5、指针越界访问 (Out-of-Bounds Access):
通过指针访问了数组或动态分配内存之外的内存区域,可能导致数据损坏或程序崩溃。
解决方法:在操作指针时,确保其地址在合法范围内。