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

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

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

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

      char *pstring;

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

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

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

      printf("%d\n", 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\n", 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 != ‘\0‘)      //将指针p1指向的数据,除终止符 ‘\0‘ 外,复制到指针p2中
  {
    *p2 = *p1;
    p1++;
    p2++;
  }

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

  *p2 = ‘\0‘;         //此时指针p2指向str2的字符串后面一位,为str2的字符串末尾添加终止符
  puts (str2);         //正常输出Happy New Year!
  printf("\n%d\n", 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\n", string[i]);      //打印多维字符数组

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

  for (i = 0; i < 4; i++)
    pstring[i] = string[i];    //对指针数组赋初值
  for (i = 0; i < 4; i++)
    printf("%s\n", 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\n", a, b);
  return 0;
}

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

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

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

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

原文地址:https://www.cnblogs.com/life-long-learner-xly/p/12222858.html

时间: 2024-11-01 12:39:27

指针进阶 - 字符串与指针 & 数组与指针的相关文章

《征服 C 指针》摘录3:数组 与 指针

一.数组 和 指针 的微妙关系 数组 是指将固定个数.相同类型的变量排列起来的对象. 正如之前说明的那样,给指针加 N,指针前进“当前指针指向的变量类型的长度 X N”. 因此,给指向数组的某个元素的指针加 N 后,指针会指向 N 个之后的元素. #include <stdio.h> int main(void) { int array[5]; int *p; int i; /* 给数组 array 的各元素设定值 */ for (i = 0; i < 5; i++) { array[i

指针知识梳理10-指向数组的指针

一.指向数组的指针 1.所谓指向的意思:我们通常说指针变量指向某个变量或者某块内存,意思是这个指针变量存储了某个变量的地址或者某块内存的地址. 2.一个变量可以占多个字节,我们通常所说某个 的地址指的是这块内存的起始地址.比如int  a,变量a栈 0x10 0x11 0x12 0x13这四个字节,那么a的地址是0x10. 3.(1)以前我们定义一个数组的时候,通常是把这个数组当做同种类型的变量的集合来看的,即数组的每个元素,用法为a[i]. (2)我们也可以把数组当做一个整体来看,int  a

c++核心-字符串、向量和数组及指针详解

关于STL的内容后面再详细介绍,string和vector都是标准模板库的内容. 数组是C的复合类型(可能只有我这么叫),一组数据,空间连续,所以由开始也有结束,从0开始,到n-1结束.注意别越界,因为是从0开始的. string和vector内部的保存数据的空间也是一个数组,所以空间也是连续的,可以看做数组的封装,同时提供了很多便利的操作,因为便利,所以也会一定程度减少自己犯错误的机会. 空间连续所以可以通过下标(随机,所谓随机,就是可以直接访问,不需要从头一个一个找下来才能找到)访问.因为跟

字符串?字符数组?指针?傻傻分不清楚

首先我们来看一下下面这个程序,不妨先猜猜它会输出什么哟. #include<stdio.h> #include<string.h> int main(void) { int a[5] = {1,2,3,4,5}; int i = 1; char str1[] = "HelloWorld\n";//数组除了在被运算符sizeof操作的时候不是直接看作地址外,其余都是可以直接等同于这个数组首元素的地址的.即一个指向首元素的指针 char *str2 = "

C语言关于数组与指针内容小结

数组的基本概念 什么是数组:数组就是:数组是相同类型的元素的一个集合       类型说明符 数组名 [常量表达式]: 其中,类型说明符是任一种基本数据类型或构造数据类型.数组名是用户定义的数组标识符.方括号中的常量表达式表示数据元素的个数,也称为数组的长度.例如: int a[10]; /* 说明整型数组a,有10个元素 */ float b[10], c[20]; /* 说明实型数组b,有10个元素,实型数组c,有20个元素 */ char ch[20]; /* 说明字符数组ch,有20个元

C语言核心之数组和指针详解

寒假要开始猛刷<剑指offer>,先回顾一下C语言基础做个热身. 指针 相信大家对下面的代码不陌生: 1 int i=2; 2 int *p; 3 p=&i; 这是最简单的指针应用,也是最基本的用法.再来熟悉一下什么是指针:首先指针是一个变量,它保存的并不是平常的数据,而是变量的地址.如上代码,指针p中保存的是整型变量i的地址信息. 接下来看如何定义一个指针,既然指针也是一个变量,那么它的定义也和其它变量一样定义:如: int *p: .'*' 是间接寻址或间接引用运算符.上例中我们还

基于arm的C++反汇编 数组和指针的寻址

数组在函数内 数组作为参数 数组作为返回值 下标寻址和指针寻址 下标值为整型常量的寻址 下标值为整型变量的寻址 下标值为整型表达式的寻址 数组越界 多维数组 存放指针类型数据的数组 指向数组的指针变量 函数指针 ??虽然数组和指针都是针对地址操作,但它们有许多不同之处.数组是相同数据类型的数 据集合,以线性方式连续存储在内存中:而指针只是一个保存地址值的4字节变量.在使用中,数组名是一个地址常量值,保存数组首元素地址不可修改,只能以此为基地址访问内 存数据:而指针却是一个变量,只要修改指针中所保

浅谈数组与指针

对于一维数组与指针: 对于二维数组与指针:

直观理解C语言中指向一位数组与二维数组的指针

一维数组和指针: 对于一位数组和指针是很好理解的: 一维数组名: 对于这样的一维数组:int a[5];  a作为数组名就是我们数组的首地址, a是一个地址常量 . 首先说说常量和变量的关系, 对于变量来说, 用箱子去比喻再好不过了, 声明一个变量就声明一个箱子,比如我们开辟出一个苹果类型的箱子, 给这个变量赋值就是把盛放苹果的箱子中放入一个实实在在的苹果, 这就是变量的赋值.  而对于数组来说, 就是一组类型相同的箱子中,一组苹果箱子, 可以放入不同的苹果. 一维数组空间: 变量被声明后, 我