指针初识与交换函数的实现

32位操作系统为什么是4g运行内存?

32根地址总线,它的寻址能力为2^32,单位是字节,换算下来,就是4GB

0x0000 0000 是多少个比特位?

比特位是二进制位,0x是16进制,8x4, 所以是32个比特位

地址不存在负数,1Byte,它可以存储-128~+127,对于地址而言,没有所谓的负数地址,只有正数,会牵扯到一个叫“无符号位”的东西。 对于整型 int,它有正负,在int 前加 unsigned

一字节为例,     unsigned  char (无符号类型)它的最小值 0000 0000,最大值1111 1111

 对于有符号类型,    char,  它的最小值1000 0000 是-128,最大值,0111 1111,无符号位是指首位本来用来表示正负的数字0,1现在就按正常的位权展开来算。

32位操作系统最大寻址能力,地址不存在负数,所以用无符号位来表示,它的最小值用16进制来表示,0x0000 到最大值0xf f f f (转换为2进制是 1111……1111共32个1)

指针,什么类型的指针变量,一定保存的是,相同类型的变量的地址

int main(){
int*arr = (int*)100;
//在这,指针指向一个常量,通过强转骗过编译器,语法无错误
但是,在系统某一块特殊的内存,内存有一个范围,假设为1~1000,超出这块的内存不允许用户访问和修改,通过强转的常量,可以被修改,引起系统崩盘等
*p = 2;  
// 指针可以通过解引用来修改这块内存的值

所以,什么类型的指针变量,一定保存的是相同类型的  变量的地址,

无论什么类型的指针变量,char* 还是 int*,在32位操作系统中,都占4字节

 *解引用,上述图片中,b变量的值是a变量的地址,通过地址访问a格子的值,*b即为解引用

就像上述图片中,改变a变量的值有两种方法,1.a = 200;  2.*b = 200;

指针,计算机中的所有数据,都必须存放在内存当中,其中 int 整型占4字节,char 类型占一字节,为了正确访问这些数据,给每一个字节进行编号,每一个字节的编号是唯一的,就像门牌号一样,这个编号就是指针或者地址,地址从0开始往上加,对于32位操作系统来说,它的运行内存是4G,从0x0000 0000 到0xFFFF FFFF

* 的作用,1.做乘法,2.声明指针,3.解引用

野指针(悬挂指针),int *p; 定义指针不赋值,定义变量不赋值时,系统会给一个随机值,但在指针中,如果给一个随机的地址,解引用后万一访问到了不能访问的数据,程序就会报错。所以,一般定义指针没有指向的值的时候, int  *arr = NULL; NULL在头文件<stdio.h> 中

c 语言中的0,1. int a = 0; 2. 字符中的 '\0',ASCLL 表中也是0,3.bool 类型中的 false

交换函数的实现方式

1;定义一个额外的变量temp用于交换

void swap(int a, int b) {
	int temp;
	temp = a;
	a = b;
	b = temp;
}int main() {
	int a = 10, b = 20;
	swap(a, b);
	printf("%d,%d\n", a, b);
	return 0;
}

上述代码中,a,b的值并没有发生交换,是因为a,b作用域的问题。在swap函数中a,b的值已经发生交换,但在主函数中,a,b的值并没有交换,a,b作用域不同,如果在swap函数中进行打印的话,a,b会交换成功,但swap 是功能函数,不允许打印。另外,主函数中调用的swap函数语句一结束,局部变量就会被回收。

交换实现方式2,加法实现,

a = a + b; //a = 20, b = 10;
b = a - b;
a = a - b;

交换方式3. 异或运算或者位运算

a = a ^ b; //a = 20, 0001 0100  b = 10, 0000 1010
b = a ^ b;
a = a ^ b;

异或运算与二进制有关,a ^ b 遵循的规则是相同位为0,不同位为1,例如上述a ^ b = 0001 1110 

上述三种形式的交换,因为作用域的问题,都不能够实现封装函数。

函数封装

可以考虑通过传递指针,解引用,通过改变形式参数的值来改变实际参数

1(函数中传递指针,但没有解引用)

2.改变实参 

void swap(int* p1, int* p2) {
	int temp = *p1;
	*p1 = *p2;
	*p2 = temp;

}
int main() {
	int a = 10, b = 20;
	int* p1 = &a, * p2 = &b;
	swap(&a, &b);
	printf("%d,%d\n", a, b);
	return 0;
}

 要想通过形参,来改变实参,必须在函数内传指针,解引用。

野指针,也叫悬挂指针,它随机指向一个地址,这个地址可能不存在,也有可能你没有权限访问。

NULL空指针,它是一个无效指针,与野指针并不同。

scanf函数为什么要有取地址符?

定义一个变量 int a;   scanf("%d",&a); scanf函数与变量a 在两个不同的作用域里。 定义变量a时,a是一个随机值,要想把键盘上输入的一个值(实际参数)赋值给a 变量 的随机值;就得把实际参数传递给scanf函数中的形参,scanf 函数中的形参有一个整型,还有一个指针,在scanf函数内部进行解引用,从而赋值给变量a。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值