一 .指针变量也是变量
首先定义一个指针变量,即在变量名前加*,其前面的类型,指的是该指针变量所存储的地址的类型。当对一个指针变量前加取值运算符 * 时,其所表示的是该指针变量代表的地址下的值。
int a = 2;
int *p = &a;
*p = 2;
指针变量在32位系统上占4个字节,在64位系统上占8个字节。
再如,下面所演示:
#include <stdio.h>
int main() {
int *p1;
double *p2;
char *p3;
int a = 123;
double b = 40.6;
char c = 'h';
p1 = &a, p2 = &b, p3 = &c;
printf("p1 = %p, &a = %p\n", p1, &a);
printf("p2 = %p, &b = %p\n", p2, &b);
printf("p3 = %p, &c = %p\n", p3, &c);
return 0;
}
其结果很明显可以看出:
p1 = 000000000061FE04, &a = 000000000061FE04
p2 = 000000000061FDF8, &b = 000000000061FDF8
p3 = 000000000061FDF7, &c = 000000000061FDF7
*p1 = 123, *p2 = 40.600000, *p3 = h
二.指针的部分用途
先看下面这个例子:
#include <stdio.h>
void add_once(int x) {
x+=1;
return ;
}
int main() {
int a = 123;
printf("%d\n", a);
add_once(a);
printf("%d\n", a);
return 0;
}
学习过函数的同学可以很清楚的知道输出会是什么,显然,二者都是123.原因在于函数中形参值的改变,不会影响实参值的变化。那如何实现类似功能呢?我们只需要在上述代码中稍加修改即可。
#include <stdio.h>
void add_once(int *x) {
*x += 1;
return ;
}
int main() {
int a = 123;
printf("%d\n", a);
add_once(&a);
printf("%d\n", a);
return 0;
}
我们通过一个指针变量,和其取值运算就可以完成上述功能。
另一个用途是指针变量作为传出参数使用。
#include <stdio.h>
void f(int n, int *sum) {
*sum = n * (n+1) / 2;
return ;
}
int main() {
int n, sum;
scanf("%d", &n);
f(n, &sum);
printf("%d", sum);
return 0;
}
该求和函数中sum通过指针变量实现了求和的功能。
还有一个用途就是读入数组数据。
#include <stdio.h>
void output(int *p, int n){
for(int i = 0; i < n; i++){
printf("arr[%d] = %d\n", i, p[i]);
}
return ;
}
int main() {
int arr[10] = {9,0,2,1,4,3,5,7,6,8};
output(arr, 10);
return 0;
}
注:数组名即为数组 第一个元素的地址。上述代码中的p[i],即为p+1。
三.指针的操作和取值原则
首先来理解p+1操作,假设p是一个type类型的指针变量,对其进行加一操作即为对p所存储的地址移动sizeof(type)长度,例如p是一个整型的指针变量,则对其进行加一操作就是将其地址后移4个字节。再如:
int (*p)[10]; //*p代表p是一个指针,
剩下的部分是其所指向的类型,即,10个整型
p+1 //代表p指针所存的地址移动10个整型的长度,即,40个字节
而:
int *p[10]; //此时p代表一个数组,共十位,
//每位存一个整型数据的地址
int *(*p[10])[20];//p是一个十位数组,每一位存储的都是一个指针
//而该指针所指向的类型是20个整型
对于指针取值*,来说,其取值只由指针所指向的类型所决定。
几种指针等价形式:
// p &a
// p+1 1+p &p[1]
//*p p[0] a
// p[n] *(p+n)
再来区分一下表述的区别:
const int *p;//p是一个指针,它所指向的是一个整型常亮的变量,
int const *p;//即,p所存储的地址所存储的数据不能改
int *const P;//指针p它的地址不能改