C指针的学习之路

一、指针的简单使用

#include <stdio.h>
void main()
{
	int a = 10;  //定义一个整型变量a
	int* p;  //定义整型指针p
	p = &a;  //指针p指向变量a的地址
    //分别打印不同信息
	printf("指针P的地址为 : %d\n", p);
	printf("指针P的值为 : %d\n", *p);
	printf("integer 类型所占用的内存大小为 : %d\n", sizeof(int));
	printf("指针(p+1)的地址为 : %d\n", (p + 1));
	printf("指针(p+1)的值为 : %d\n", *(p + 1));
}

运行结果如下:

以上代码可实现定义一个整型的指针p 并实现打印

因为指针p指向了变量a的地址 因此p的值也是a的值

由第三段打印信息可得知 整型结构类型占用的内存大小为4字节

但由于整型占用四个字节 因此指针p+1的地址往后推4 为6224988

指针p+1称为 野指针  指向的数据值即为  脏数据

  野指针就是指针指向的位置是不可知的(随机的、不正确的、没有明确限制的)指针变量在定义时如果未初始化,其值是随机的,指针变量的值是别的变量的地址,意味着指针指向了一个地址是不确定的变量,此时去解引用就是去访问了一个不确定的地址,所以结果是不可知的。

该地址没有值因此出现 脏数据 如图第五行

  脏数据(Dirty Read)是指源系统中的数据不在给定的范围内或对于实际业务毫无意义,或是数据格式非法,以及在源系统中存在不规范的编码和含糊的业务逻辑。

二、指针类型、算术运算、void指针

1.不同数据类型储存信息的方式

整型为例

        通过之前所学可知,整型占用四个字节,如图:byte0、byte1、byte2、byte3,假设a的首地址为200,则byte0、byte1、byte2、byte3分别如上图所示。

        则整型变量a赋值为1025,在byte0内二进制转化为00000001,byte1内二进制存储为00000100,byte2中二进制存储为00000000、byte3中二进制存存储为00000000,在byte3中第一位表示正负号。 则1025=1*2^10+1*2^0.

        若指针p取a的地址则为200.代码如下:

#include <stdio.h>
void main()
{
	int a = 1025;
	int* p;
	p = &a;
	printf("指针P的地址为 : %d\n", p);
	printf("指针P的值为 : %d\n", *p);
	printf("integer 类型所占用的内存大小为 : %d\n\n", sizeof(int));
	char* p0;
	p0 = (char*)p; //强制类型转换
	printf("指针p0的地址为 : %d\n", p0);
	printf("指针p0的值为 : %d\n", *p0);
	printf("char 类型所占用的内存大小为 : %d\n", sizeof(char));
}

运行结果如下:

        让我们来分析各个数据是如何得出的:

                1.指针p因为指向了变量a,因此指针p的地址也就是变量a的首地址。

                2.指针p的地址即变量a的地址,因此其值也对应变量a的值,即1025。

                3.整型占用的字节空间为4。

                4.指针p0为char(字符型),其指向指针p并且将(int)p进行强制类型转换,转换为(char)p。因此指针p0的首地址与p的首地址相同均为10483832.

                5.指针p0的值为1,解释如下:

                        因为变量a = 1025 :00000000 00000000 00000100 00000001

                        字符型指针p0指向p时进行强制类型转换,char类型占用一个字节 因此p0只指向了byte0即(00000001),因此 *p0 = 1*2^0 = 1。

                6.char类型占用1个字节。

2.定义空指针

代码如下:

#include <stdio.h>
void main()
{
	int a = 1025;
	int* p;
	p = &a;
	printf("指针P的地址为 : %d\n", p);
	printf("指针P的值为 : %d\n", *p);
	void* p0;
	p0 = p;
	printf("指针p0的地址为 : %d", p0);
}

三、函数的传值与传址

1.函数传值

代码如下:

#include "stdio.h"
void increment(int a)
{
    a = a+1;
    printf("a的地址为 : %d\n",&a);
    printf("a的值为:%d\n",a);
}
int main()
{
    int a = 10;
    increment(a);
    printf("a的地址为 : %d\n",&a);
    printf("a的值为:%d\n",a);
}

运行结果如下:

 内存底层理解,视频地址(精准空降):【强烈推荐】4小时彻底掌握C指针 - 顶尖程序员图文讲解 - UP主翻译校对 (已完结)_哔哩哔哩_bilibiliicon-default.png?t=LBL2https://www.bilibili.com/video/BV1bo4y1Z7xf?p=5&t=264.12.函数传址:

代码如下:

#include "stdio.h"
void increment(int *p)
{
    *p = *p+1;
    printf("increment函数中信息如下:\n");
    printf("a的地址为 : %d\n",p);
    printf("a的值为:%d\n",*p);
}
int main()
{
    int a = 10;
    printf("a的值为 : %d\n",a);
    increment(&a);
    printf("函数传递后a的信息:\n");
    printf("a的地址为 : %d\n",&a);
    printf("a的值为:%d\n",a);
}

运行结果如下:

 内存层理解,视频地址(精准空降):

【强烈推荐】4小时彻底掌握C指针 - 顶尖程序员图文讲解 - UP主翻译校对 (已完结)_哔哩哔哩_bilibiliicon-default.png?t=LBL2https://www.bilibili.com/video/BV1bo4y1Z7xf?p=5&t=689.2

四、指针和数组

        如上图,我们定义一个整型数组A[5],已知int类型占用4个字节,因此数组A占用5*4=20个字节,假设数组A的首地址为200,则数组A的占用地址如上图A[0]-200,A[1]-204,A[2]-208``````

        定义一个整型变量x = 5,整型指针p,p指向x假设x的地址为300,则打印p的地址即为300,*p为5,p+1为304,*(p+1)为脏数据

 

 

         但若我们令指针p指向数组a的首地址,即p = A,则打印p即200,*p即即2,p+1 == (A+1) == &A[1] = 204,*(p+1) == *(A+1) == A[1] = 4``````

代码如下:

#include <stdio.h>
void main()
{
    int A[5] = {2,4,5,8,1};
    int *p;
    p = A;
    printf("指针P的地址为 : %d\n",p);
    printf("数组A的首地址为 : %d\n",A);
    printf("指针P的值为 : %d\n",*p);
    printf("数组A[0]的值为 : %d\n",A[0]);
    printf("\n");
    printf("指针P+1的地址为 : %d\n",p+1);
    printf("数组A[1]的地址为 : %d\n",A+1);
    printf("指针P+1的值为 : %d\n",*(p+1));
    printf("数组A[1]的值为 : %d\n",A[1]);
}

运行结果如下:

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值