C语言指针(1)

       我们已经学习了一段时间的C语言了,从今天开始,我们就要开始上难度了,就是指针,之前学的都是小儿科,今天开始我们才算真正的学习C语言了,所以,指针的第一部分,就此开始了!!!

       就让我们走进指针,继续提升我们的能力,让我们在C语言的知识中继续遨游吧!!!

什么是指针?

          指针就是内存的地址,指针变量就是保存内存地址的变量。

为了理解指针,就让我们来慢慢了解:

目录

一、指针变量和地址

    1、取地址操作符(&)

2.指针变量与解引用操作符(*)

3.指针变量的大小

    (1)在32位机器上,地址是32个0/1的二进制序列,存储起来需要32个比特位,即4个字节。

   (2) 在64位机器上,地址是64个0/1的二进制序列,存储起来需要64个比特位,即8个字节。

二、指针变量类型的意义

1、指针的解引用

2、指针 +- 整数

3、void*指针

三、const修饰指针

1、const修饰变量

2、const修饰指针变量

        (1)const放在*左边

      (2)const放在*右边

总结:

四、指针运算

1、指针运算

(1)指针 +- 整数

(2)指针 - 指针       

指针 - 指针的应用:

(3)指针的关系运算

五、野指针

       1、什么是野指针?

       2、野指针成因

             (1)指针未初始化

​编辑

             (2)指针越界访问

             (3)指针指向的空间释放

3、如何规避野指针

(1)指针初始化

(2)小心指针越界

(3)指针变量不再使用时,及时置NULL,指针使用之前检查有效性

(4)避免返回局部变量的地址


一、指针变量和地址

    1、取地址操作符(&)

           &a是取出a所占4个字节中地址较小的字节的地址

2.指针变量与解引用操作符(*)

      指针变量也是⼀种变量,这种变量就是⽤来存放地址的,存放在指针变量中的值都会理解为地址。

        在下面的代码中,p是变量,它的类型是int * ,其中,* 说明p是指针变量,int 说明p指向的是整型类型的对象。

* 就是解引用操作符(间接访问操作符),*p 等价于a。

我们用代码来进行验证:

#include<stdio.h>
int main()
{
	int a = 10;
	int* p = &a;
	*p = 100;
	printf("%d", a);
	return 0;
}


//运行结果是100

3.指针变量的大小

        指针变量需要多大空间取决于存放的地址需要多大空间,地址存放需要多大空间,指针变量的大小就是多大。

    (1)在32位机器上,地址是32个0/1的二进制序列,存储起来需要32个比特位,即4个字节。

     代码如下:

   (2) 在64位机器上,地址是64个0/1的二进制序列,存储起来需要64个比特位,即8个字节。

      代码如下:

二、指针变量类型的意义

       我们已经学习了指针,但是为什么要学习指针?学习指针的意义是什么?我们就在这里解答。

1、指针的解引用

           指针的类型决定了对指针解引用的时候有多大的权限(一次能操作几个字节)。
           比如: char* 的指针解引用就只能访问⼀个字节,而int* 的指针的解引用就能访问四个字节。

2、指针 +- 整数

     

        由上面的代码可以看出,char类型的指针+1跳过了1个字节,int 类型的指针+1跳过了4个字节,这就是指针变量类型带来的差异。

        所以,指针的类型决定了指针向前或者向后走一步有多大。

3、void*指针

        这里由于类型不兼容会有以上错误,这时候就该使用void*指针来接收地址了。

        这时候我们就能看出来void*指针可以接收不同类型的指针了。

        现在void*可以接收不同类型的地址,但是无法进行指针运算。至于为什么这样呢?我们会在后面的文章中解释。

三、const修饰指针

1、const修饰变量

        我们看下面的代码,很明显,m和n都是可以被修改的,但是我们加上const呢?

        在加上const以后就会报错了。

        这里的const是常属性的意思,就是不能被修改了。虽然并不能被修改了,但n和m本质还是变量。

2、const修饰指针变量

        (1)const放在*左边

                代码如下:

       在下面的代码中,const放在*的左边,限制的是*p,意思是不能通过p来改变p指向的对象的内容,但是p本身是可以改变的,p可以指向其他对象。

      (2)const放在*右边

               代码如下:

               在下面的代码中,const放在*的右边,限制的是p,意思是不能修改p本身的值,但是p指向的内容是可以通过p来修改的。

总结:

所以,通过以上两个例子,我们可以总结出以下两条规律:

1.const如果放在*的左边,修饰的是指针指向的内容,保证指针指向的内容不能通过指针来改变,
但是指针变量本身的内容可变。

2.const如果放在*的右边,修饰的是指针变量本身,保证了指针变量的内容不能修改,但是指针指
向的内容,可以通过指针改变。

四、指针运算

1、指针运算

(1)指针 +- 整数

#include<stdio.h>
int main()
{
	int arr[] = { 1,2,3,4,5,6,7,8,9,10 };
	int sz = sizeof(arr) / sizeof(arr[0]);
	int* p = &arr[0];
	for (int i = 0; i < sz; i++)
	{
		printf("%d ", *p);
		p++;
	}
	return 0;
}



//运行结果为1 2 3 4 5 6 7 8 9 10

(2)指针 - 指针       

                          运算的前提是两个指针指向同一块空间

#include<stdio.h>
int main()
{
	int arr[10] = { 0 };
	printf("%d\n", &arr[9] - &arr[0]);
	printf("%d\n", &arr[0] - &arr[9]);
	//指针 - 指针的绝对值是指针和指针之间的元素个数
	return 0;
}

//运算结果为:  9
//            -9

指针 - 指针的应用:

       模拟实现strlen

//方法一
#include<stdio.h>
int my_strlen(char*str)
{
	int count = 0;
	while (*str != '\0')
	{
		str++;
		count++;
	}
	return count;
}
int main()
{
	char arr[] = "abcdef";
	int len = my_strlen(arr);
	printf("%d\n", len);
	return 0;
}
//方法二
#include<stdio.h>
int my_strlen(char* p)
{
	char* p1 = p;
	while (*p != '\0')
	{
		p++;
	}
	return p - p1;
}
int main()
{
	char arr[] = "abcdef";
	int len = my_strlen(arr);
	printf("%d\n", len);
	return 0;
}

(3)指针的关系运算

#include<stdio.h>
int main()
{
	int arr[] = { 1,2,3,4,5,6,7,8,9,10 };
	int sz = sizeof(arr) / sizeof(arr[0]);
	int* p = &arr[0];
	while (p < arr + sz)
	{
		printf("%d ", *p);
		p++;
	}
	return 0;
}

五、野指针

       1、什么是野指针?

             野指针就是指针指向位置是不可知的。

       2、野指针成因

             (1)指针未初始化

             (2)指针越界访问

             (3)指针指向的空间释放

#include <stdio.h>
int* test()
{
	int n = 100;
	return &n;
}
int main()
{
	int* p = test();
	printf("%d\n", *p);
	return 0;
}

3、如何规避野指针

(1)指针初始化

#include <stdio.h>
int main()
{
	int n = 10;
	int* p1 = &n;

    int* p = NULL;
	return 0;
}

(2)小心指针越界

         一个程序向内存申请了多少空间,通过指着就访问多少空间,不能超出范围。

(3)指针变量不再使用时,及时置NULL,指针使用之前检查有效性

        当指针变量指向一块区域的时候,我们可以通过指针访问该区域,后期不再使用这个指针访问空间的时候,我们可以把指针置为NULL。

#include<stdio.h>
int main()
{
	int a = 10;
	int* p = &a;
	if (p != NULL)     //检查
	{
		*p = 20;
	}
	printf("%d", a);
	return 0;
}

(4)避免返回局部变量的地址

   到这里,咱们指针的第一部分就结束了,我们也确实可以感觉到指针并不简单,但是我们学习最好的方法就是去不断的复习,最好的是我们可以去找一些视频来学习,它比文章更直观,也更易理解。

  • 47
    点赞
  • 49
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值