指针是 C语言的重要组成部分,是 C语言的核心、精髓。
在 C语言中,指针使用得当,能显著提高某些程序的效率,使用不当,则很容易造成系统错误、
一、指针使用
编译系统为每个变量都分配了一个能满足其类型大小的内存单元地址,访问内存地址就可以找到对应的变量。
我们将变量的地址形象化地称为该变量的指针。即通过指针能访问以它为地址的内存单元,从而获取变量的信息。
变量与指针的关系:
变量的地址是变量和指针之间的连接纽带。所谓指向就是通过地址来体现的。
因为指针通常指向一个变量的地址,所以将一个变量的地址赋给指针后,这个指针就指向了该变量。
一个变量的地址就称为该变量的指针。
1、指针变量
1.1 指针变量的定义
C语言中,指针变量就是专门用来存放内存单元地址的变量类型。即指针类型。
定义指针变量的基本格式为:
datatype *var_name;
其中:
- datatype:表示该指针变量所指向的变量的数据类型 。
- *:表示该变量是一个指针变量。
- var_name:变量名,即为定义的指针变量名。
1.2 指针变量的赋值
指针变量和普通变量一样,使用前需要先进行定义并赋予具体的值,未赋值的指针变量是不能使用的。
注意:
指针变量的赋值只能赋予地址,而不能是其他数据,否则将引起错误。
指针变量的赋值方式一般有两种:
// 方式1:定义指针变量的同时进行赋值
int a;
int *p = &a;
// 方式2:先定义指针变量再赋值
int a, *p;
p = &a;
注意:
- C语言使用 “ & 变量名”表示某个变量的地址。
- 如果先定义指针变量之后在赋值时,指针变量前不再加“*”号。
1.3 指针变量的引用
引用指针变量是对变量进行间接访问的一种形式,其含义表示引用指针变量所指向的值(变量的值)。
引用指针变量的一般格式为:*指针变量
示例如下:
int main() {
int a = 18, b = 99, c = 100;
int *p = &a; //定义指针变量
*p = b; //通过指针变量修改内存上的数据
c = *p; //通过指针变量获取内存上的数据
printf("a=%d, b=%d, c=%d, *p=%d, p=%d\n", a, b, c, *p, p);
//输入:a=99, b=99, c=99, *p=99, p=6291020
return 0;
}
2、&与*和&与&的区别
&与*都是单目运算符,两者的优先级相同,按照自右向左的方向结合。
- &:表示取地址运算符,用于返回一个操作数的地址。
- *:表示指针运算符,用于返回指定地址内保存的变量值。
&与&的区别,假设语句如下:
int a, *p, q;
p = &a;
q = *p;
(1)p = &a:是将变量 a的内存地址赋值给了指针变量 p。
(2)q = *p:是将指针 p指向的变量,即变量 a的值赋值给 q。
(3)&*p:先进行 *运行再进行 &运算。*p相当于变量 a,在进行 &运算。所以,&p相当于取变量 a的地址。
(4)&a:先进行 &运行再进行 *运算。&a就是取变量 a的地址,在进行 运算。所以,&a相当于取变量 a所在地址的值,即变量 a的值。
示例如下:
#include <stdio.h>
int main() {
int a, *p, q;
a = 88;
p = &a;
q = *p;
printf("a=%d, &a=%d, p=%d, *p=%d, q=%d\n", a, &a, p, *p, q);
printf("&*p=%d, *&a=%d\n", &*p, *&a);
return 0;
}
二、指针的自增自减运算
指针的自增自减运算是按照它所指向的数据类型的内存长度进行自增或者自减的,
示例如下:
#include <stdio.h>
int main() {
int i, *pi;
double d, *pd;
i = 18;
d = 12.2;
pi = &i;
pd = &d;
printf("i=%d, &i=%d, pi=%d, *pi=%d,\n", i, &i, pi, *pi);
printf("pi++之后\n", i, &i, pi, *pi);
pi++;
printf("i=%d, &i=%d, pi=%d, *pi=%d,\n", i, &i, pi, *pi); // pi++:pi增加4(int类型的4个字节)
printf("===============\n");
printf("d=%E, &d=%d, pd=%d, *pd=%d\n", d, &d, pd, *pd);
pd++;
printf("d=%E, &d=%d, pd=%d, *pd=%d\n", d, &d, pd, *pd); // pd++:pd增加2(double类型的8个字节)
return 0;
}
三、指向指针的指针
一个指针可以指向整型变量、实型变量、字符型变量,也可以指向另一个指针,此时称其为指向指针的指针。
指向指针的指针一般格式如下:datatype **pointer_name;
其中:
- datatype:表示该指针变量所指向另一个指针变量的变量的数据类型 。
- **p:表示指针变量 p指向了另一个指针变量。比如:int **p; 就相当于 int *(*P); 。
示例如下:
#include <stdio.h>
int main() {
int i;
char **p;
char *a[] = {
"周一",
"周二",
"周三",
"周四",
"周五",
"周六",
"周日"
};
for (i = 0; i < 7; i++) {
p = a + i; //将数据个元素的地址赋值为 p
printf("%s ", *p);
}
return 0;
}
四、指针变量做函数中的使用
1、指针变量做函数函数
指针型变量可以作为函数参数使用。
示例如下:
#include <stdio.h>
/* 函数声明 */
void my_swap(int *x, int *y);
int main() {
/* 局部变量定义 */
int a = 100;
int b = 200;
printf("交换前,a 的值: %d\n", a);
printf("交换前,b 的值: %d\n", b);
/* 调用函数来交换值
&a 表示指向 a 的指针,即变量 a 的地址
&b 表示指向 b 的指针,即变量 b 的地址
*/
my_swap(&a, &b);
printf("交换后,a 的值: %d\n", a);
printf("交换后,b 的值: %d\n", b);
return 0;
}
/* 函数定义 */
void my_swap(int *x, int *y) {
int temp;
temp = *x; /* 保存地址 x 的值 */
*x = *y; /* 把 y 赋值给 x */
*y = temp; /* 把 temp 赋值给 y */
return;
}
通过指针传递参数时,传递的是变量的地址,此时地址内存存放的数据会发生改变的。
2、指针变量做函数返回值
返回指针值的函数简称为指针函数。
定义指针函数的一般格式为:函数名迁安加一个 “*” 修饰。
return_dataType *function_name( parameter list )
{
int *p;
//body of the function
return p;
}
示例如下:
#include <stdio.h>
// 声明指针函数
int *f_acreage(int a, int b);
int acreage;
int main() {
int a, b, *p_res;
a = 11;
b = 5;
p_res = f_acreage(a, b);
printf("p_res值 = %d\n", *p_res);
printf("acreage值 = %d\n", acreage);
return 0;
}
// 定义指针函数
int *f_acreage(int a, int b) {
int *p;
p = &acreage;
acreage = (a + b) * 2;
return p; // 返回指针
}
五、指针数组做 main函数的参数
main函数是所有程序运行时的入口,有系统调用,当处于操作命令状态下时,输入 main所在的文件名,即可调用 main函数。同时我们也可以给 main函数传值。
main函数的有参格式为:int main(int argc, char *argv[])
通过操作系统的命令行调用执行文件时,就可以给 main函数传值。
命令行的一般格式为:filename.exe 参数1 参数3 … 参数n
可执行文件名与和其后面的参数之间必须使用空格分隔。
示例如下:
#include <stdio.h>
int main(int argc, char *argv[]) {
int loc, ser;
printf("he argument list for the main function: \n");
printf("Command nam: %s\n", *argv);
printf("Parameter numbe: %d\n", argc);
for (int i = 0; i < argc; i++) {
printf("argv[%d] = %s\n", i, argv[i]);
}
return 0;
}
– 求知若饥,虚心若愚。