浅析部分指针笔试题

目录

1.前言

2.关于指针

2.题目具体解析


1:前言

  有关c语言的学习,许多小伙伴们最害怕的应该莫过于指针了吧,而同时指针却也是我们笔试面试中较为常见的一类题型,那么在本篇文章,我将尽力为大家解决有关指针的问题,克服大家对指针的恐惧感。

2:关于指针

  那么什么是指针呢?我们首先带大家理清一些基本概念。

1.指针就是个变量,用来存放地址,地址唯一标识一块内存空间。

2.指针的大小是固定的4/8个字节(32位平台/64位平台)。

3.指针是有类型,指针的类型决定了指针的+-整数的步长,指针解引用操作的时候的权限。

4. 指针的运算。

3.相关题目

  那么我想先请大家看看下面一串代码,想想程序会输出什么样的结果。

#include <stdio.h>
int main()
{
    char str1[] = "hello world.";
    char str2[] = "hello world.";
    char *str3 = "hello world.";
    char *str4 = "hello world.";
    if(str1 ==str2)
 printf("str1 and str2 are same\n");
    else
 printf("str1 and str2 are not same\n");
       
    if(str3 ==str4)
 printf("str3 and str4 are same\n");
    else
 printf("str3 and str4 are not same\n");
       
    return 0;
}

这里最终会输出一下结果

 有的小伙伴可能会好奇为什么会输出这样的结果呢?这四个字符串的内容不是完全一致的吗?

而实际上这里str3和str4指向的是一个同一个常量字符串。C/C++会把常量字符串存储到单独的一个内存区域, 当几个指针指向同一个字符串的时候,他们实际会指向同一块内存但是用相同的常量字符串去初始 化不同的数组的时候就会开辟出不同的内存块。所以str1和str2不同,str3和str4不同。就是说这里strcmp函数实际比较的是他们的地址。

接下来我们看点有意思的东西

关于"&数组名"与”数组名”

大家应该都很清楚的知道数组名是代表是数组首元素的地址,那么&数组名呢?

我们来看看下面的代码,他们会输出什么?

#include <stdio.h>
int main()
{
    int arr[10] = {0};
    printf("%p\n", arr);
    printf("%p\n", &arr);
    return 0;
}

直接放出结果

 看起来是不是完全一致呢?接下来再看看下面这串代码。

#include <stdio.h>
int main()
{
  int arr[10] = { 0 };
  printf("arr = %p\n", arr);
  printf("&arr= %p\n", &arr);
  printf("arr+1 = %p\n", arr+1);
  printf("&arr+1= %p\n", &arr+1);
  return 0;
}

输出结果如下

 但实际上根据上面两串代码我们可以发现虽然arr和&arr的值是一样的,但是其所代表的意义却是截然不同的。

实际上: &arr 表示的是数组的地址,而不是数组首元素的地址。大家可以发现数组的地址+1,跳过整个数组的大小,所以 &arr+1 相对于 &arr 的差值是40

有了上面的一些知识铺垫,我们再来看看下面的这串代码。

#include <stdio.h>
int main()
{
  int a[] = {1,2,3,4};
  printf("%d\n",sizeof(a));
  printf("%d\n",sizeof(a+0));
  printf("%d\n",sizeof(*a));
  printf("%d\n",sizeof(a+1));
  printf("%d\n",sizeof(a[1]));
  printf("%d\n",sizeof(&a));
  printf("%d\n",sizeof(*&a));
  printf("%d\n",sizeof(&a+1));
  printf("%d\n",sizeof(&a[0]));
  printf("%d\n",sizeof(&a[0]+1));
  return 0;
}

可以看到,这里我们首先定义了一个int的一维数组,对于接下来的几个printf,我们分别做如下解释

1.数组名a单独放在sizeof内部,计算的是整个数组的大小,4*4=16

2.a表示首元素的地址,a+0依然表示首元素地址,故输出4/8

3.a表示首元素地址,*代表对a解引用,得到第一个元素,类型为int,故输出4

4.a表示首元素的地址,a+1表示第二个元素的地址,故输出4/8

5.a[1]代表数组第二个元素,输出4

6.&a代表整个数组的地址,但也是地址,故大小为4/8

7.可理解为*和&相互抵消,实际相当于sizeof(a),输出4*4=16

8.&a+1相当于跳过了一个a数组的大小,但实际上还是一个地址,故输出4/8

9.&a[0]相当于是一个二级指针,指向数组首元素的地址,故输出4/8

10.&a[0]+1相当于二级指针跳过了一个一级指针int*的大小(4字节),本质上还是一个地址,但是不指向原数组的任何一个元素,输出4/8

  本期指针的题目解析到此结束,之前也是因为期末考咕咕了很久,时隔2月再度更新,感谢大家的支持,相信我们很快会在下一篇文章见面。对于本文有任何意见也可在评论区下方提出。

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值