#include<stdio.h>
#include<string.h>
int main() {
//注意int*和int *
//字符指针的简单运算
{int* px, * py, * pz, x;
px = &x;
py = px;//可相互赋值
//定义三个变量,假设它们地址为连续的,分别为 4000、4004、4008,地址连续是下面计算的前提
int x, y, z;
//定义一个指针,指向 x
int* px = &x;
//利用指针变量 px 加减整数,分别输出 x、y、z
printf("x = %d", *px);
//px + 1,表示,向前移动一个单元(从 4000 到 4004)
//这里要先(px + 1),以(px+1)作为y的地址,再*(px + 1)获取内容,因为单目运算符“*”优先级高于双目运算符“+”
printf("y = %d", *(px + 1));
printf("z = %d", *(px + 2));
}
//对于指针地址的加减
{int num[2] = { 1, 3 };//定义一个数组,数组中相邻元素地址默认间隔一个单元
//将数组中第一个元素地址和第二个元素的地址赋值给 px、py
int* px = &num[0], * py = &num[1];
int* pz = &num[0];
int* pn;
//则 py > px,因为py所指向的元素在px之后嘛
if (py > px) {
printf("py 指向的存储地址大于 px 所指向的存储地址");
}
//pz 和 px 都指向 num[0]
if (pz == px) {
printf("px 和 pz 指向同一个地址");
}
//pn 没有初始化,下边这两个其实是一个意思
if (pn == NULL || pn == 0) {
printf("pn 是一个空指针");
}
}
//定义一个整形数组,并初始化
//循环输出数值指针
{ int nums[5] = { 4, 5, 3, 2, 7 };
//定义一个指针变量 p,将数组 nums 的首地址赋值给 p,也可以用p = &nums[0]赋值,两者其实是一样的
int* p = nums, i; //i 作为循环变量
//p 指向数组第一个元素(数组首地址),我们可以直接用间接寻址符,获取第一个元素的内容
printf("nums[0] = %d\n", *p); //输出结果为 nums[0] = 4
//我们可以通过“p + 整数”来移动指针所指向的地址,所以 p + 1 要扩起来
printf("nums[1] = %d\n", *(p + 1)); //输出结果为 nums[1] = 5
//由上面推导出*(p + i) = nums[i],所以我们可以通过 for 循环变量元素
for (i = 0; i < 5; i++) {
printf("nums[%d] = %d", i, *(p + i));
}//这个就很巧妙了
}
//字符串数组指针应用
//除了定义一个字符数组外,还可以直接定义一个字符指针存储字符串
const char* sentence = "Do not go gentle into that good night!";//这里加一个const是因为VS不让直接以这种形式定义一个字符指针
//不要温和的走进那个良夜233
//输出
printf("%s", sentence);
//通过下标取字符,也就是D
printf("%c", sentence[0]);
printf("%d", strlen(sentence)); //strlen用于获取字符串长度
//定义赋值字符数组 sentence 和 word
char sentence[] = "Do not go gentle into that good night!", word[100];
char* ch = word;
int i;
//循环赋值,直到数组最后的\0
for (i = 0; sentence[i] != '\0'; i++) {
*(ch + i) = sentence[i];
}
//在当 i 等于 sentence 的长度(sentence 的长度不包含'\0')时,
//i 继续自增,此时判断 sentence[0] != '\0'不符合,跳出循环,则 i 比 sentence 长度大 1
//输出字符串,因为 ch 指向 word,所以输出结果是一样的
printf("ch = %s, word = %s", ch, word);
//二级指针
int* pi, i = 10;
//定义二级指针变量,就是int**类型的
int** ppi;
//给指针变量赋初值
pi = &i;
//给二级指针变量赋初值
ppi = π
//我们可以直接用二级指针做普通指针的操作,并获取 i 的内容
printf("i = %d", **ppi);
//获取 i 的地址
printf("i 的地址为%d", *ppi);//这时候带着一个*的二级指针就是一个地址了,两个则是指向的数值
//指针数组
int nums[5] = { 2, 3, 4, 5, 2 }, i;
int* p[5];//定义一个指针数组
//定义一个二级指针
int** pp;
//循环给指针数组赋值
for (i = 0; i < 5; i++) {
p[i] = &nums[i];
}
//将指针数组的首地址赋值给 pp,数组 p 的数组名作为 p 的首地址,也作为 p 中第一个元素的地址。
//数组存放的内容为普通变量,则数组名为变量的指针;数组存放的内容为指针,则数组名为指针的指针。
pp = p;
//利用二级指针 pp 输出数组元素,这里也可以直接输出的其实
for (i = 0; i < 5; i++) {
//pp == &p[0] == &&nums[0],nums[0] == *p[0] == **pp
printf("%d", **pp);
//指针变量+整数的操作,即移动指针至下一个单元,做到数组中的延申
pp++;
}
}