C语言之指针知识(1)

1.指针的理解

2.解引用

3.指针变量的大小

4.指针的类型

5.const修饰变量

注:下文如若不做说明,均是在32位环境下。

1.指针的理解

#指针就是地址,地址就是指针。存放地址(或指针)的变量就是指针变量。

#我们用一个具体的例子来说明一下:

  int main()

{

    int a=10;

    int* p=&a;

    return 0;

}

变量p就是指针变量,它的类型是int*,又可以理解为是存放int类型地址的类型,指向int(存放的谁的地址就指向谁)。

    int** pp=&p;

    这里pp指向p(int*类型),pp的变量类型为int**。

#所有指针的大小都是4/8个字节(32位或64位)。

2.解引用

我们还是以上面的例子来看:

int main()

{

  int a=10;

  int* p=&a;

  return 0;

}

在  int* p=&a; 中,*是为了说明p是一个指针;而在 int** pp=&p; 中,*是为了说明pp是一个int**的指针。

*也可以是一个操作符,是解引用操作符。变量p存放着a的地址,我们对p解引用,就可以访问a的内存空间。

eg:*p==10;

实际上,解引用和取地址操作是互逆的运算,二者共同运算时,会相互抵消。

eg:*&p==p;

3.指针变量的大小

#取决于你的机器是32位还是64位。

4.指针的类型

这个知识点是重点。

先来看几个例子:

  int* p1 ->大小是四个字节,解引用访问四个字节;

  char* p2 ->大小是四个字节,解引用访问一个字节;

我们也知道指针加减整数。对于以上两个例子有:

  p1+1 -> 跳过四个字节,

  p2+1 -> 跳过一个字节。

从以上的举例中可以得知,指针类型具有丰富的意义。

#1.决定了解引用访问多大的空间;

#2.决定了指针的步长(+1或-1跳过几个字节);

#3.决定了解引用访问的是什么类型的变量(如int,int*等);

同样,指针的类型也可以用于强转中,比如:

想让int*访问一个字节,可以强转为char*;

低地址                                              高地址

——————————————————>

            1                            2                          3                          4

(表示编号,下同)

如图为以上int的数据,每一个方格代表一个字节;

  每一个字节有一个对应的地址编号。那这里第一个问题出现了:一个int* 只能放一个地址,而它又是指向整个整型,那它究竟放的是那个字节的地址呢?

  结果:是最低地址的字节的地址。对于其他数据类型(如short,float,double等)都适用。

  我们进行强转之后,只是改变了它的类型,但没有改变它存放的值(地址),所以解引用之后,只访问第一个字节。

上述的例子是大转小,那么小转大呢?

#我们就试着转成一个double类型。众所周知的是,double类型的大小是8个字节,所以我们需要再开辟4个字节以保证不会越界访问。

                             

                                    低地址                                                     高地址

                                    ————————————————————>

                           1             2            3            4             5            6            7            8

  上文的 int* 存放的是1号字节的地址,当我们强转成double类型时,它(指针)就认为从1号字节往后到8号字节共8个字节都是它所指向的一个double类型,所以当对其解引用时,它会直接从最左边向后访问8个字节。

#泛型指针

void*,无类型,可以用来接收任意类型的指针;

但不可以解引用和进行整数的相加减。

那到底有什么用呢?

#通常:别人要给你传一个未知类型的指针,可以用 void* 来接收。当我们确定它的具体类型时,进行一下强转就可以了。

好了,关于指针的类型我们就讲到这里~

5.const指针

5.1 const修饰变量

我们先用一个例子来引入:

  C语言中有几种变量类型,如int,float,那它们为什么叫变量呢?

#是因为它们可以被修改。如:int a=10; 我也可以通过赋值把它改成20,这就是可修改。

同样,常量就不可以被修改,如:3=5;这种操作就是非法的,因为3是个常量。

#当我们在上述例子的前面加上const时——>const int a=10;  ,这时我们再去修改,会发现编译系统报错了,提示你a不可被修改。这里变量a就被赋予了常属性。

当然,这里的a还是一个变量,那么如何验证呢?

eg:int arr[a]={0};

然后我们运行一下,就会发现问题。说明a还是一个变量(但在C++中就是常量)。

这里又出现一个问题:直接修改不可以,那能不能间接修改,比如指针呢?

eg:int* p=&n;

        *p=20;

我们发现此方法可行。但这样的方式有问题。const本来就是为了保护变量不被修改,但却被指针通过间接的方式给修改了。所以,引出我们第二部分的问题。

5.2 const修饰指针

要想真正做到保护变量,要从指针入手。

(1)const放在*的左边

eg:int main()

{

    int a=10;

    const int* p=&a;

}

放在左边,限制的是 *p ,也就是变量本身,但不限制p;

#即不能改变变量的值,但可以改变所指的对象;

(2)const放在*的右边

还是以上面的例子为例。

int main()

{

  int a=10;

  int* const p=&a;

}

放在右边,限制的是p,不限制 *p ;

#即不能改变所指向的对象,但可以改变变量的值。

今天就先到这里吧,真写累了,对文章内容有异议的宝子在评论区留言哈~

  • 17
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值