1.一级指针
指针的用途:传递和偏移
#include <stdio.h>
#include <stdlib.h>
//指针的本质是:间接访问!!!!!
int main() {
int i = 3;
int *iPointer;//指针变量,int*型的
scanf("%d", &i);
printf("%d\n", i);//直接访问
iPointer = &i;// 取地址或者说引用
printf("%d\n", *iPointer);//间接访问,*是取值的意思,对地址进行取值,或者说解引用
return 0;
}
指针的值传递
(1)这种情况不会改变,相当于:
i=10;
j=i;
j=5;
但是i并不会变成5,i还是10
#include <stdio.h>
#include <stdlib.h>
//函数调用的本质是值传递
void change(int j) {
j = j / 2;
}
int main() {
int i = 10;
printf("before:i=%d\n", i);//10
change(i);//change函数传进去的是变量i的值,而不是地址
printf("after:i=%d\n", i);//10
return 0;
}
(2)这种情况才可以
i=10;
j=&i;
*j=i=10的值,也就是说通过通过取地址拿到变量i的空间,如果修改了这个空间的值,i肯定变
#include <stdio.h>
#include <stdlib.h>
//一级指针的值传递
//函数调用的本质是值传递
void change(int *j) {//在这里定义一个指针变量j
*j = *j / 2; //此处,j=&i,*j=i;拿到了变量i的空间
}
//指针的传递
int main() {
int i = 10;
printf("before:i=%d\n", i);//10
change(&i);//传进去的不是变量i的值,而是变量i的地址
printf("after:i=%d\n", i);//5
return 0;
}
指针的偏移
#include <stdio.h>
#include <stdlib.h>
//一级指针的值传递
//函数调用的本质是值传递
//要想改变一个变量的值就要把这个变量的地址传进去
void change(int *j) {//在这里定义一个指针变量j
*j = *j / 2; //此处,j=&i,*j=i;拿到了变量i的空间
}
//指针的传递
void changeagain(int **p2,int *pj) {
*p2 = pj;//p2=&p,要想改变p的值,即*p2=p,对p进行操作,使其不知向i,指向其他的
//
}
int main() { //p=&i,*p=i,
int i = 10;
int j = 3;
int *p,*pj;
pj = &j;
p = &i;//
int **p2;//定义一个二级指针
p2 = &p;
//printf("before:i=%d\n", i);//10
//printf("%d %d %d %d %d\n", i,&i,p,*p,&p);
printf("i=%d,&i=%d, p=%d ,*p=%d ,&p=%d ,p2=%d, **p2=%d ,*p2=%d\n", i, &i, p, *p, &p,p2,**p2,*p2);
//i=10 &i=9698968 p=9698968 *p=10 &p=9698956 p2=9698956 **p2=10 *p2=9698968
//结论:i=*p=**p2,&i=p=*p2,&p=p2
printf("\n-----------------\n");
//change(&i);//传进去的不是变量i的值,而是变量i的地址
//printf("after:i=%d\n", i);//5
//printf("%d %d %d %d %d\n", i, &i, p, *p, &p);
printf("i=%d,&i=%d, p=%d ,*p=%d ,&p=%d ,p2=%d, **p2=%d ,*p2=%d\n", i, &i, p, *p, &p, p2, **p2, *p2);
changeagain(&p,&j);//要改变p的值,就是不让让存i的地址了,&p=p2,p2是二级指针
printf("\n-----------------\n");
printf("i=%d,&i=%d, p=%d ,*p=%d ,&p=%d ,p2=%d, **p2=%d ,*p2=%d\n", i, &i, p, *p, &p, p2, **p2, *p2);
return 0;
}
2.二级指针
(1)值传递
整型指针pi指向整形变量i,整形指针pj指向整型变量j,通过子函数change(),我们
想改变指针变量pi的值,让它指向j
#include <stdio.h>
#include <stdlib.h>
//要想在子函数内改变一个变量的值,必须把该变量的地址传进去
//要想在子函数内改变一个指针变量的值,必须把该指针变量的地址传进去
void change(int **p, int* pj) {
*p = pj;// 这样分析对吗?pj=&j,*p=&j,**p=j=5?
}
int main(){
int i = 10;//变量i是int类型,所以存放的是int数据,变量pi是int *类型de指针,所以存放的是指向int类型的地址
int j = 5;
int *pi;//指针p是int*型的指针,指针所指向的类型是int,指针pi的值,
//或者说指针所指向的内存区或者地址,是变量i的地址
//只是为指针变量pi申请了一块内存地址,假设它的内存地址为 "0x7000",此时变量pi中存放的内容为nil
int *pj;
pi = &i;//表示将变量i的地址赋值给指针pi所存放的内容
pj = &j;
printf("i存放的内容的值:%d,i自己所在的地址:%p\n", i, &i);// i=10 ,i的地址是00EDF890
printf("pi存放的地址的值:%p; pi自己所在的地址:%p; pi存放的地址所指所存放内容的值:%d\n",pi,&pi,*pi);
//i 存放的内容的值:10, i自己所在的地址: 00EDF890
//pi 存放的地址的值: 0093FB0C; pi 自己所在的地址: 0093FAF4; pi 存放的地址所指所存放内容的值: 10
printf("\n--------------------------------------------------\n");
printf("i=%d,*pi=%d,*pj=%d\n", i, *pi, *pj);//10 10 5 i=10,*pi=10,*pj=5
//change(&pi, pj);//要改变的*pi的值????
change(&pi, &j);
printf("改变后的值:i=%d,*pi=%d,*pj=%d\n", i, *pi, *pj);//10 5 5 改变后的值: i=10,*pi=5,*pj=5
return 0;
}
(2)偏移
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define N 5
//排序排指针数组
//增量编译
//我的目的是按字母顺序,把字符数组里面的几个名字按字母表顺序重新排一遍
void print(char(*p)[12]) {//数组指针
int i;
for (i = 0; i < N; i++) {
puts(p[i]);//p[0]就是第一行
}
}
void printpArr(char **p1) {
int i;
for (i = 0; i < N; i++) {
puts(p1[i]);//p[0]就是第一行
}
}
//二级指针的初始化是某个一级指针变量去地址
//在子函数需要修改主函数内某个一个指针的值,需要二级指针
int main() {
//char *pArr[N];
char b[N][12] = { "zhousi","chang'e","erlangshen","weinasi","liubei" };
int i, j;
char **p2 = (char**)malloc(sizeof(char*)*N);//动态的指针数组才需要在主函数中定义二级指针
char *pTmp;//用于交换的中间变量,是一个指向char的指针
for (i = 0; i < N; i++) {//让指针数组中的每一个指针都指向一个字符串
p2[i] = b[i];
}
/*for (i = 0; i < N; i++) {
puts(b[i]);
}*/
//puts(b[0]);//打印zhousi
print(b);//打印,b[0]到b[4],b[0]="zhousi"
//b是二维数组名
for (i = 1; i < N; i++) {
for (j = 0; j < N - i; j++) {
if (strcmp(p2[j], p2[j + 1]) > 0) {
pTmp = p2[j];
p2[j] = p2[j + 1];
p2[j + 1] = pTmp;
}
}
}
printf("\n--------------------\n");
printpArr(p2);//
printf("\n--------------------\n");
print(b);//这个是不会变的
return 0;
}