C语言:对指针的一些总结

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;
}

 

 

 

 

 

       

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值