----------------------------------------
--------------------
-----------------------------------------------
目录
--------初识指针 --------------------
--------- 指针变量和地址--------
-------------指针变量的大小-------------
---------const修饰指针------------------
------------- 指针的运算---------------------------
---------------指针的传址调用---------------
-------------野指针的问题---------------
--------------assert断言-----------------
初识指针
访问一个变量有两种访问方法:
1.直接访问:通过变量名进行访问(相当于你在我面前,线下直接访问)
2.间接访问:通过指向一个变量a的指针变量进行访问a(我知道你的微信,线上间接访问)
1.指针的介绍:指针是计算机在内存开辟的一个存储单元中存放的地址。举个栗子,你在酒店预订了一个房间2005,你想我来酒店找你玩,首先要告诉我门牌号我才能进行准确的查找并进行访问。
2.我们把内存分为一个个存储单元,每个存储单元的大小是一个字节,也就是八个比特位。
3.每个内存的存储单元都是地址也就是指针,它相当于一个编号让我们更容易的查找。
指针变量和地址
1.取地址操作符(&)
#include<stdio.h>
int main()
{
int a = 10;
&a;
printf("%p\n",&a); //%p取地址的占位符
return 0;
}
照我们上面的这个例子,a,b在内存中存放的地址是:
可见地址在内存中都是以十六进制进行存放的:&a就是取出a的地址,%p就是取地址的占位符。我们知道整形int占用4个字节,在数组中地址都是连续存放的,我们只要知道首地址可以顺藤摸瓜的找到对应的下标地址。
2.解引用操作符(*)
1.当我们利用&拿到一个地址数组的时候,比如010FFC28,这个地址有时候需要存储起来,方便以后的使用。就要把地址存放在指针变量里面。
#include<stdio.h>
int main()
{
int a = 10;
int* pa = &a; //将a的地址存储到指针变量pa中
return 0;
}
1.int* pa:*说明pa是指针变量,而*前面的int是指针变量pa指向的是int类型的变量。
2.我们拿到了地址(指针)就可以访问地址(指针)所指向的对象。
#include<stdio.h>
int main()
{
int a = 100;
int* pa = &a;
*pa = 10;
printf("%d",a);
return 0;
}
1.现在我们用指针变量*pa存储了a的地址,现在*pa就是a变量了,在访问*pa时并赋值了10,此时a的值就是10。
指针变量的大小
#include <stdio.h> int main() { printf("%zd\n", sizeof(char *)); printf("%zd\n", sizeof(short *)); printf("%zd\n", sizeof(int *)); printf("%zd\n", sizeof(double *)); return 0; }
我们发现指针变量的大小取决于地址的大小。
32位平台下地址是4个字节,64的平台下地址是8个字节。
这是X64的环境下
这是X32的环境下
指针变量的大小与数据类型是无关的,只要是指针变量在相同的平台下大小都是相同的。
指针的类型决定了,对指针解引用的时候有多大的权限(一次能操作几个字节)。
如char*指针解引用只能访问一个字节,而int*的指针解引用一次能访问四个字节。
由上图可知:指针的大小与数据类型无关,数据类型决定了指针解引用的权限。
const修饰指针
1.给指针加上const的限制,指针就不能被修改。
但是pa本身就是一个变量,它的值可以修改。
可以这么说,const 放在指针变量*pa的前面限制的就是指针变量,变量pa不受影响。
而 const 放在变量pa的后面限制的就是pa变量,*pa指针变量不受影响。
若想都限制,则需前后都加上const即可。如const int *const pa = &a.
指针的运算
1.指针加减整数:
*pa记入的是数组首元素的地址,(pa+i)相当于每循环一次加上一个整数,也就是四个字节。因为int类型的数组在内存中是连续存放的相隔四个字节,便直接访问数组的下一个元素。
2.指针-指针:(设置一个strlen函数)
#include <stdio.h>
int my_strlen(char *s)
{
char *p = s;
while(*p != '\0' )
p++;
return p-s;
}
int main()
{
printf("%d\n", my_strlen("abc"));
return 0;
}
指针的传址调用
1.设置一个函数进行两个数据的交换:
#include<stdio.h>
void swap(int* a, int* b) //指针接收,让实参和形参直接建立了联系
{
int c = 0;
c = *a;
*a = *b;
*b = c;
}
int main()
{
int a = 0, b = 0;
printf("请输入你需要交换的数据:\n");
scanf_s("%d%d", &a, &b);
printf("交换前:a = %d,b = %d\n",a,b);
swap(&a, &b); //将a,b的地址传给形参
printf("交换后:a = %d,b = %d\n",a,b);
return 0;
}
野指针的问题
1.指针未初始化;
2.指针越界访问;
3.指针指向的空间释放;
解决的办法:
可以给指针赋值NULL, 地址是0,该地址是无法使用的,读写该地址时会报错。
assert断言
1.#include<assert.h>包含了assert()。
2.它的作用是在运行的时候确保程序符合我们的条件,如果不符合就会报错并终止运行。
3.只能在Debug版本里面使用。
4.如果想停止这种操作只需在#include<assert.h>前面加上#define NDEBUG。
#define NDEBUG
#include <assert.h>
int main()
{
int a = 10;
int* pa =&a;
assert(*pa = NULL);
return 0;
}
*pa不符合assert的条件,程序报错!
----------------------------------------------------------
-----------------------------------------
----------------------------------
------------------------
--------------
--------
----
这就是指针(1)的全部内容
--------------------感谢老铁的支持