文章目录
前言
指针提供一种以符号形式使用地址的方法。因为计算机的硬件指令非常依赖地址,指针在某种程度上把程序员想要传达的指令以更接近机器的方式表达。因此,使用指针的程序更有效率。
一、指针
(1)指针变量的定义
指针变量的定义形式如:数据类型 *指针名
(2)指针变量的使用
取地址运算符&:单目运算符&是用来取操作对象的地址。例:&i 为取变量 i 的地址。对于常量表达式、寄存器变量不能取地址(因为它们存储在存储器中,没有地址)。
指针运算符*:与&为逆运算,作用是通过操作对象的地址,获取存储的内容。例:x = &i,x 为 i 的地址,*x 则为通过 i 的地址,获取 i 的内容。
(3)指针和数组
在数组中,数组名即为该数组的首地址,结合上面指针和整数的加减,我们就可以实现指针访问数组元素。
(4)指针和函数
定义函数内部不用sizeof求数组长度,因为数组类型退化成了指针类型,指针大小由系统决定。
void show(char*arr) ;
x86系统(win32):sizeof(arr)--->4字节x64系统(win64):sizeof(arr)--->8字节
二、指针的应用
1.交换函数(实现a,b两数位置相交换)
代码如下(错误示例):
#include<stdio.h>
void Swap(int a, int b); //函数声明
int main() {
int a = 10, b = 20;
Swap(&a,&b); //函数名 函数入口地址
printf("a=%d,b=%d\n",a,b);
return 0;
}
void Swap(int a, int b) {
int temp = a;
a = b;
b = temp;
}
乍一看,可能觉得没什么问题,但执行结果却是a,b两数并没有交换位置。我们可以用函数的知识来解答这个问题,因为形参不能将结果值传递给实参,所以尽管在Swap函数中,两数实现了交换位置,但是等到该函数运行完了之后,所开辟的内存会被释放掉,因而对主函数内数据情况没有起到任何作用。
正确示例:
#include <stdio.h>
void Swap(int* pa, int* pb); //函数声明
int main() {
int a = 10, b = 20;
Swap(&a,&b); //函数名 函数入口地址
printf("a=%d,b=%d\n",a,b);
return 0;
}
void Swap(int* pa, int* pb) {
int temp = *pa;
*pa = *pb;
*pb = temp;
}
如正确示例所示,将变量以指针的类型作为形参,结果却可以实现两数位置相交换。原因是这里的指针的作用是指向a,b两变量所占的内存地址,在Swap函数内实现了a,b两数的地址相交换,从而达到了目的。切忌不能说是形参将结果值传递给了实参才实现了交换。
2.指针+1能力
指针+1能力,简单来说就是指针的偏移量。
代码如下(示例):
int main() {
int arr[] = { 1,2,3,4,5 };
int* p = arr;
printf("%p %p %p\n", p , p + 1, p + 2);
return 0;
}
运行结果(示例):
00F5F898 00F5F89C 00F5F8A0
我们可以看出,指针+1后实际地址移动了4个字节,也就是一个int型的大小。所以我们可以得出这样一个结论:指针+1移动的大小由指针指向的数据类型决定,并不是简单的地址+1。即可记作:p+1的实质是 p+1*sizeof(指向的数据类型)。
3.const和一级指针的结合
const:关键字,限定一个变量不可被修改。
int a = 1, b = 2;
int*pa= &a, *pb = &b;
const int* p = &a;
int* const q = &b;
*p = 10; //错误,表达式必须是可修改的左值
*q = 20; //正确
p = &b; //正确
q = &a; //错误,表达式必须是可修改的左值
const+类型指针:限定指针指向的值不可被修改,指向的地址可以被修改,*p所指向的a的值不能再发生改变,因为*p已经被定义成了一个常量且初始化时候指向了a的值。
类型指针+const:限定指针本身不可被修改,指向的值可以被修改,本身所指的地址不可以被改变,即q所指向的b的地址不能再发生改变,因为q已经被定义成了一个常量且在初始化时指向了b的地址。
4.数组指针和指针数组的区别
指针数组:装着指针的数组
数组指针:指向数组的指针
char arr[] = "hello";
const char* brr[] = { "hello","world","123" }; //指针数组,侧重数组
int(*p)[6] = &arr; //数组指针,侧重指针
指针数组和数组指针,要看谁的优先级更高,则更侧重谁。
指针数组 *p[n]
数组指针 (*p)[n]