【C语言】指针深度剖析(1)

指针,作为C语言的一个特色,其在C语言当中有着不可或缺的作用。想要学好C语言,指针是必须要掌握的重要知识点。

作为C语言初学者,我们已经知道指针的基本概念:
1.指针是一个变量,用来存放地址,地址唯一标识一块内存空间。
2.指针的大小是4/8个字节(分别为32位/64位操作系统)。
3.指针有类型,指针的类型决定了指针+-整数的步长、指针解引用操作时的权限。
4.指针可以进行运算

当然,指针肯定不仅仅有上面这些内容,今天我们就来一起深入探讨指针。

    • 字符指针

字符指针,顾名思义,就是指向字符的指针,类型为char*

字符指针的取地址解引用操作同整形指针的一样:

int main()
{
  char ch='w';
  char *pc=&ch;
  *pc='w';
  return 0;
}

还有一种使用方式:

int main()
{
  const char* pstr="hello world";  //这里的const可以省略,但是在高版本编译器下可能会报警告
  printf("%S",ptsr);
  return 0;
}

输出结果是这样的:

光看代码我们也许容易误解,误以为是将hello world这一字符串放到字符指针pstr里了,然而,存放进字符指针pstr里的,本质上只是字符串hello world的首字符地址。通过首字符地址,就可以找到一整个字符串。

为什么上面注释说道const可以省略呢?

来看这样一道面试题就能更加透彻的理解:

#include <stdio.h>

int main()
{
  char str1[] = "hel1lo World";
  char str2[] = "hel1lo World";
  const char *str3 = "hello World";
  const char *str4 = "hel1o 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相同。

正是因为常量字符串这一属性,所以正确的写法应该是const char *str3 = "hello World",但我们既然已经知道这里的字符串是常量字符串,为了方便这里的const就可以省略,写成char *str3="hello world"也是正确的。

    • 指针数组

指针数组,就是用来存放指针的数组。

如果能够理解整形数组、字符数组等概念,指针数组也就很好理解。

来看以下几个例子:

int *arr[10]; //可以存放10个整形指针的数组
char *arr2[5]; //可以存放5个字符指针的数组
char **arr3[7]; //可以存放7个一级字符指针的二级字符指针的数组
    • 数组指针

3.1数组指针的定义

顾名思义,数组指针就是能够指向数组的指针。

数组指针的形式是这样的:

int (*p)[10];

这里,p先跟*结合,表示p是一个指针变量,然后指向一个大小为10个整形的整形数组。所以p是一个指向数组的数组指针。

由于[]的优先级高于*,所以必须用()来保证p先于*结合,否则就是这样的

int *p[10];

这样就成了一个指针数组。

数组指针的类型是怎样的呢?

假如我们现在创建一个整形指针int *p1,我们可以很清楚的知道p1是一个指针,类型为int *。

那么类比到数组指针,对于int (*p)[10],p的类型就是int (*)[10];

所以可以得到一个判断变量类型的简单方法,去掉变量名以后剩下的部分就是该变量的类型。

3.2数组指针的使用

数组指针既然指向数组,那么指针中存放的就应该是数组的地址,如下:

#include <stdio.h>
int main()
{
  int arr[10]={1,2,3,4,5,6,7,8,9,10};
  int (*p)[10]=&arr;
  return 0;
}

这样就实现了一个简单的取地址操作。如果想要通过数组指针打印数组内容,代码如下:

#include <stdio.h>
int main()
{
    int arr[10] = { 1,2,3,4,5,6,7,8,9,10 };
    int(*p)[10] = &arr;
    int i = 0;
    for (i = 0; i < 10; i++)
    {
        printf("%d ", *(*p)+i);//*p表示arr,也就是数组首元素地址,*((*p)+i)即是*(arr+i)
    }
    return 0;
}

打印结果如下:

(本篇完)

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值