建站宝盒手机版下载,页面模板怎么修改,制作网站可用性监控,宿迁优化推广目录 1.内存和地址2. 指针变量和地址2.1 取地址操作符#xff08;#xff09;2.2 指针变量和解引用操作符#xff08;*#xff09;2.2.1 指针变量2.2.2 解引用操作符#xff08;*#xff09; 2.3 指针变量的大小 3.指针变量的类型和意义3.1 指针的解引用3.2 指针 -指… 目录 1.内存和地址2. 指针变量和地址2.1 取地址操作符2.2 指针变量和解引用操作符*2.2.1 指针变量2.2.2 解引用操作符* 2.3 指针变量的大小 3.指针变量的类型和意义3.1 指针的解引用3.2 指针 -指针3.3 void*指针 4.const修饰指针4.1 const修饰变量4.2 const修饰指针变量 5.传值调用和传址调用 1.内存和地址
在生活中我们住的房子一般都有门牌号学生一般都有学号注册一个软件账户一般都有账户编号可见给一些事物编上号可以方便我们的生活。 计算机也是这样计算机中处理数据的机器时CPU中央处理器它在处理数据的时候是在内存中读取数据处理后将数据放回内存。在内存中将其划分为一个一个的内存单元每个内存单元的大小取一个字节8个bite每个内存单元也有一个编号就相当于门牌号一样这样CPU就可以快速访问内存中需要的数据了。 内存单元就相当一间学生宿舍一个字节能存放8个比特位就相当于一间宿舍住了8个人。 1byte 8bite 1kb 1024byte 1mb 1024kb 1Gb 1024mb 1Tb 1024Gb 1Pb 1024Tb 生活中我们也把门牌号叫做地址在计算机中我们把内存单元的编号也叫做地址还可叫做指针 所以内存单元编号 地址 指针
2. 指针变量和地址
2.1 取地址操作符
取地址操作符和按位与操作符是同一种符号但是功能完全不一样而且取地址符是单目操作符按位与操作符是双目操作符。 在C语言中创建变量其实就是向内存申请一块空间比如
int a 10;这段代码就是向内存中申请4个字节int类型占用4个字节用于存放整数10那如何得到这个地址呢那么就要用到取地址操作符比如 这里的地址是用16进制表示 而int类型的数据会占用4个字节的大小所以**a取出的是所占4个字节中地址较小的字节的地址。** 十六进制的a表示的数就是10当我们知道了第一个字节的地址就可以往下顺藤摸瓜找到其他的地址
2.2 指针变量和解引用操作符*
2.2.1 指针变量
当我们用取地址操作符拿到一个地址后就可以将这个地址存放到指针变量中比如
int main() {int a 10;int* pa a;return 0;
}指针变量是一种变量这种变量是用来存放地址的存放在指针变量的值都会被理解为地址 pa是指针变量int*是指针变量的类型 *表示pa是指针变量int表示pa指向的类型是int类型。这里的 int和星号中间加不加空格都表示指针变量没有去区别。
2.2.2 解引用操作符*
指针变量用来保存地址而解引用操作符*用来使用地址 在C语言中我们拿到了指针就可以通过指针找到指针指向的对象这里就需要*解引用操作符
int main() {int a 10;int* pa a;*pa 0;return 0;
*pa的意思就是通过指针变量pa找到pa指向的对象a然后改变它的值上述代码就是将a的值由10改为0.
*pa 0的效果和a 0;的效果一样都是将a的值置为0但是使用指针提供了一种新的修改途径。
2.3 指针变量的大小
在32位计算机中有32根地址总线相关知识可以自行学习每根地址总线都可以使用电信号来表示0和1这样就由32根地址总线产生的二进制序列就可以当作地址那么一个地址就是32个bite位需要4个字节来存储。 所以任何指针变量的大小都是4个字节64位机是8个字节
int main() {printf(%zd\n, sizeof(char*));printf(%zd\n, sizeof(int*));printf(%zd\n, sizeof(double*));printf(%zd\n, sizeof(short*));printf(%zd\n, sizeof(long int*));return 0;
}3.指针变量的类型和意义
既然在相同平台下所有的指针类型的大小都是一样的那么为什么还要设置这么多的指针变量呢。
3.1 指针的解引用
对比以下代码
int main() {int a 0x11223344;int* pa a;*pa 0;return 0;
}int main() {int a 0x11223344;char* pa a;*pa 0;return 0;
}通过调试中的内存监控可知代码1会将0x11223344中的4个字节全部置为0而代码2只会将第一个字节44置为0其他不变。 结论指针的类型决定了对指针解引用的时候有多大的权限一次能操作几个字节 比如int类型的指针变量可以解引用4个字节而char类型的指针变量只能访问1个字节
3.2 指针 -指针
int main() {int n 10;int* pi n;char* pc n;printf(%p\n, n);printf(%p\n, pi);printf(%p\n, pc);printf(%p\n, pi 1);printf(%p\n, pc 1);return 0;
}运行结果如下 这里的pi和pc都指向变量n而pi1加了4个字节因为pi是int*类型的指针变量而pc1只加
了1个字节因为pc是char* 的指针变量。 结论指针的类型决定了指针想前或者其向后走一步有多少距离。
3.3 void*指针
在指针类型中有一种特殊的指针类型是void*类型它是无具体类型的指针泛型指针它可以用来接收任何类型的地址但也有局限性不能进行和-和解引用的操作
int main() {int a 0x11223344;void* pa a;*pa 0;//错误操作return 0;
}void*指针可以接受不同类型的地址但是无法直接进行指针运算
4.const修饰指针
变量是可以修改的而在变量前面加上const修饰那么该变量就不能被修改了
4.1 const修饰变量
int main() {const int a 10;a 29;return 0;
}可以看到变量a被const修饰过后那么改值就不能修改了而这个限制只是在语法层面加上限制我们可以用指针来越过这个限制比如 上面用指针变量pa来读取a的地址而用解引用操作符操作指针变量a使其修改值为20那么有什么办法能让指针也不能改变其值呢
4.2 const修饰指针变量
int main() {const int a 10;const int* pa a;*pa 20;//错误printf(%d\n, a);return 0;
}可以看出在指针变量pa前面加上const那么该指针变量就无法进行去引用操作并赋值的操作 注意const int* pa a;的效果和 int const * pa a;的效果一致
那const放在a的右边呢
int main() {const int a 10;int* const pa a;*pa 20;printf(%d\n, a);return 0;
}这样就对pa的值没有限制作用了加在右边的作用是限制指针变量的内容不能修改。 这里必须要弄懂三个概念的含义 1.pa存放的是a的地址 2.pa是指针变量也是一种变量他有自己的地址 3.*pa是pa指向的空间即a的值 上述代码就是限制了变量pa里面存放的值不能改变
int main() {const int a 10;int* const pa a;*pa 20;printf(%d\n, a);int b 0;pa b;//错误return 0;
}结论
const放在*的左边修饰的是指针指向的内容保证指针指向的内容不能通过指针改变但是指针变量本身的内容可以改变const放在*的右边修饰的是指针本身的内容保证指针变量本身的内容不可以改变但是但是指针指向的内容可以改变
5.传值调用和传址调用
传值调用就是调用函数参数是值。而传址调用就是传的地址 比如 用函数实现交换两个数 void Swap(int x, int y) {int type x;x y;y type;
}
int main() {int a 10;int b 20;printf(交换前%d %d\n, a, b);Swap(a, b);printf(交换后%d %d\n, a, b);return 0;
}这里可以看到交换值不成功这是因为实参传递给形参时形参会单独创建一分临时空间来接受实参对形参的修改不影响实参 可以使用指针来实现两个数的交换
void Swap(int *x, int *y) {int type 0;type *x;*x *y;*y type;
}
int main() {int a 10;int b 20;printf(交换前%d %d\n, a, b);Swap(a, b);printf(交换后%d %d\n, a, b);return 0;
}传址调用可以让函数和主调函数建立真正的联系在函数内部可以修改主调函数的变量所以只是需要主调函数中的值进行计算那么就可以使用传值调用如果函数内部要修改主调函数中变量的值那么就要传址调用。
/考研势在必行/