指针进阶 - 字符串与指针 & 数组与指针

Posted life-long-learner-xly

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了指针进阶 - 字符串与指针 & 数组与指针相关的知识,希望对你有一定的参考价值。

昨天的随笔里忘记提的重要一点:

    指针指向的地址是有长度的,但是指针就是个针,一个针只有一个针尖,只能指向一个地址。

    当我们用这种方式测量指针长度时

 

      char *pstring;

      printf("%d ", sizeof(*pstring));

    实际上我们测的不是指针占据的内存大小,而是指针指向的数据占据的内存大小,哪怕为空。由于代码中是char型,所以输出结果为1。

 

    当我们测量却忘记带 * 号时,如:

      printf("%d ", sizeof(pstring));

    这就是系统指针的大小了,如果你是32位的编辑器,那地址总线宽度是4 bytes,你得到的结果就是4  如果你是64位的编辑器,那地址总线宽度是8 bytes,你得到的结果就是8

指针进阶:

访问一个字符串 有两种方式 

  第一种:使用字符数组存放一个字符串,字符数组是变量的集合,可以通过对字符数组的元素进行修改而实现对字符串的修改。

    例子:char string[] = "Hello world!"; 就是一个一维数组,里面有12个字符。可以通过替换指定位置的值而修改字符串的值。

  第二种:定义字符指针,令其指向一个字符串的地址而非字符数组。此时由于指针指向常量,指针只能调用不能修改

    例子:char *string = "Hello world!"; 即为指向常量的字符指针。一般不这么用。

使用指针访问字符数组:

1. 定义一个字符指针并将其初始化为空

  例子:char *pstring = NULL;

  或者将其初始化为指向字符数组

  例子:char string[] = "Happy New Year!";

     char *pstring = string;

 

2. 使用指针指向存放字符串的字符数组,方法如下:

#include <stdio.h>
int main()
{
  char string[] = "Happy New Year!";  //定义一维数组
  char *pstring = NULL;                      //定义指针并将其初始化为空

  pstring = string;                                //指针指向数组地址,这里涉及一个知识点。数组是变量的集合,因此可以简单地使用数组的名字进行表示数组地址,而不用取地址符&。

  //或者如果不用取地址符不舒服的话,也可以这么用:

  //pstring = &string[0];    这么麻烦,何必呢。

  printf("%s ", pstring);                      //打印字符指针所指地址的值
  return 0;
}

 

3. 通过指针来复制字符串

#include <stdio.h>
#include <string.h>
int main()
{
  char str1[] = "Happy New Year!", str2[20], *p1, *p2;
  p1 = str1;
  p2 = str2;

  while(*p1 != ‘‘)      //将指针p1指向的数据,除终止符 ‘‘ 外,复制到指针p2中
  {
    *p2 = *p1;
    p1++;
    p2++;
  }

  printf("%d ", strlen(str2)); //输出为19,而非15,数组str2的字符串后面缺少终止符,因指针p2未将终止符一起复制

  *p2 = ‘‘;         //此时指针p2指向str2的字符串后面一位,为str2的字符串末尾添加终止符
  puts (str2);         //正常输出Happy New Year!
  printf(" %d ", strlen(str2)); //测得结果为15,str1中的字符串通过两个指针完整复制到字符串str2
  return 0;
} //书上原题

如果使用sizeof 测试字符串长度,结果都是20。这是定义时数组的长度,而非数组中的字符串对应的长度。具体sizeof和strlen的区别,读者可以去网上搜索,很多大佬讲得很细了。我就不赘述了。

 

4. 多维字符数组与指针数组,例子如下:

#include <stdio.h>

int main()
{
  int i;
  char string[4][10] =
  {
    "China",
    "Japan",
    "Canada",
    "America",
  };                                               //定义完多维字符数组
  for (i = 0; i < 4; i++)
    printf("%s ", string[i]);      //打印多维字符数组

  char *pstring[4];       //定义指针数组

  for (i = 0; i < 4; i++)
    pstring[i] = string[i];    //对指针数组赋初值
  for (i = 0; i < 4; i++)
    printf("%s ", pstring[i]);  //打印指针数组

  return 0;
}

我在网上搜了一下,可能很少会用到指针数组,这个,由于经验太少,我不清楚。

 

5. 关于昨天的指针入门,我从书上看到个例子,对指针的理解有些帮助。如下:

#include <stdio.h>

void change(int * a, int * b)
{
  int t;
  t = *a;
  *a = *b;
  *b = t;
}
int main()
{
  int a = 3, b = 5;
  change(&a, &b);
  printf("%d, %d ", a, b);
  return 0;
}

这里书上的题目定义了交换的函数,如果change函数不用指针来写的话,你在编译器里敲一下就知道了,交换失败。

书上没说为啥,我琢磨着函数调用之后,交换的值的地址是系统分配给change函数的内存地址,函数用完就会销毁。交换了的值不会返回。

如果你照我说的敲了,可能在change里面打印一下就会换了,但是在main里面没换,因为地址上的值没有被处理,传递到change函数的是值而不是地址,地址的值没变,那自然也就不会交换了。

 

加油,希望明天能看链表。

以上是关于指针进阶 - 字符串与指针 & 数组与指针的主要内容,如果未能解决你的问题,请参考以下文章

C语言进阶——指针进阶(字符指针指针数组数组指针)

指针的这些知识你知道吗?C语言超硬核指针进阶版3w+字详解+指针笔试题画图+文字详细讲解

C语言进阶笔记深入了解进阶指针

C语言进阶笔记深入了解进阶指针

C语言进阶笔记深入了解进阶指针

C语言进阶笔记深入了解进阶指针