文章概述

本文章讲述关于C语言的主要内容如下:
  1.字符数组、2.一维数组与指针、3.二维数组与指针、4.字符串与指针、5.字符串指针数组

一、字符数组

  定义一维数组时,系统会在内存中为其分配一段存储空间,数组名就是数组在内存中的首地址。数组中的元素类型为字符型时,称为字符数组。字符数组中的每个元素可以存放一个字符。
注意单引号‘’用来表示字符,双引号“”用来表示字符串

1、字符数组定义和引用

定义形式如下:
char 数组标识符[常量表达式]

示例:

char cArray[5];
// 字符数组的引用
cArray[0]='H',cArray[1]='e',cArray[2]='l',cArray[3]='l',cArray[4]='o';

对字符数组进行初始化操作时,有以下几种方法:
(1)逐个字符赋给数组中的元素,例如:

char cArray[5]={'H','e','l','l','o'};

定义字符数组的同时进行初始化,此时可以省略数组长度,系统会自动根据初值个数来确定数组长度:

char cArray[]={'H','e','l','l','o'};

(2)利用字符串给字符数组赋值,例如:

char cArray[]={"Hello"};

或者将“{}”去掉,写成:

char cArray[]="Hello";

2、字符数组的结束标志

在C语言中,使用字符数组保存字符串时,系统会自动为其添加“\0”作为结束符。即用字符串方式赋值比用字符逐个赋值要多占一个字节。
char cArray[]=“Hello”;
等价于:
char cArray[]={‘H’,‘e’,‘l’,‘l’,‘o’,‘\0’};  //此时,占用6个字节

3、字符数组的输入和输出

字符数组的输入和输出可以使用两种格式字符:“%c”和“%s”:
  1)%c可实现数组中字符的逐个输入与输出;
  2)%s可将整个字符串输入或输出;

使用格式字符“%s”输出字符串时,需要注意以下几种情况:

  1. 输出字符中不包括结束符“\0”;
  2. printf函数中的输出项是字符数组名cArray,而不是数组中的元素名cArray[0]等;
  3. 即使数组长度大于字符串实际长度,也只会输出到“\0”为止;

二、数组与指针

  使用数组是,系统需要提供一段连续的内存来存储数组中的各元素,如果把数组的地址赋给指针变量,就可以通过指针变量来引用数组。

1、一维数组与指针

将数组的首地址传给指针变量,则该指针就指向了这个一维数组。例如:

int *p,a[5];
p=a

这里a是数组名,即数组的首地址,将它赋给指针变量p,即将a的首地址赋给p,也可以写成如下形式:

int *p,a[5];
p=&a[0];

上述两条赋值语句的操作效果完全相同。基于上述语句,有以下几种描述:

  • p+n与a+n都用于表示数组元素a[n]的地址,即&a[n]
  • *(p+n)和*(a+n)都用于表示数组元素a[n]的值

2、指针的移动“++”与“–”

采用指针自增运算实现时,需要注意:
  p++与p–可用于表示数组的输入
  *p++与*p–可用于表示数组的输出,

示例代码:

#include<stdio.h>
int main()
{int *p,a[5],i;p=a;printf("please input array a:\n");for(i=0;i<5;i++){scanf("%d",p++);    //利用p++形式输入数组a}printf("%d\n",p);p=a;       /* 注意这一行 */printf("%d\n",p);printf("array a is:\n");for(i=0;i<5;i++){printf("%5d",*p++);    //利用*p++形式输出数组a}printf("\n");return 0;
}

返回结果,如下:

需要注意的地方:
  如果在给数组元素赋值时使用了指针自增运算,而在后续步骤中也使用指针变量,此时的指针p指向数组a+4的地址。
  因此,需要再一次使用<p=a;>语句,将指针p重新指向数组a的首地址。

3、二维数组与指针

对于一个m行n列的二维数组,其元素地址的表示方法如下:

  • a表示二维数组的首地址,a+i表示第i+1行的首地址;
  • a[i]+j表示数组第i+1行第j+1个元素的地址;
  • &a[0]表示数组第1行的首地址;
  • &a[0][0]既可以表示数组第1行第1列的首地址,也可以看作整个数组的首地址;

指针也可表示地址,因此通过指针可以引用二维数组中的元素:

  • *(*(a+m)+n)和*(a[m]+n)含义相同,都表示数组第m+1行第n+1列元素
  • *(a+m)+n和a[m]+n含义相同,都表示数组第m+1行第n+1列元素的地址

代码示例:
将一个3行2列的二维数组打印出来:

#include<stdio.h>
int main()
{int i,j,(*p)[2];int a[3][2]={{1,'a'},{2,'b'},{3,'c'}};p=a;for(i=0;i<3;i++){for(j=0;j<2;j++){if(j==0){printf("%d, ",*(*(p+i)+j));}else{printf("%c",*(*(p+i)+j));}}printf("\n");}return 0;
}

运行结果如下:

1, a
2, b
3, c

三、字符串指针数组

1、字符串与指针

可以通过两种方式访问字符串,一是使用字符数组,二是使用字符指针。
利用字符型指针输出字符串“hello”,具体代码如下:

#include <stdio.h>
int main()
{char *myStr="hello";printf("%s\n",myStr);printf("%c\n",myStr[1]);    //输出该字符串中第2个字符return 0;
}

运行结果如下:

hello
e

2、字符串数组

  字符串数组有别与字符数组。字符数组是一个一维数组,而字符串数组是以字符串作为数组元素的数组,可以将其看成一个二维字符数组

代码示例:

char cName[5][20]=
{"zhangsan","lisi","wangwu","luliu","hongqi"
}

上述代码中,字符串数组变量cName被定义为含有5个字符串的数组,每个字符串的长度都必须小于20(这里需要考虑字符串最后的“\0”,也要占一个字节)

3、字符串指针数组

  基于上述字符串数组的代码示例,可以发现,像“lisi”这样的字符串的长度仅为4,加上字符串结束符也仅为6。而内存中却要给它们各分配一个20字节的空间,空间浪费很大。
  为了解决这个问题,可以使用指针数组,使每个指针指向所需要的字符常量。这种方法需要在数组中保存字符指针,虽然也占用空间,但要远少于字符串数组占用的空间

指针数组的定义:
  一个数组,如果其元素均为指针类型数据,则该数组称为指针数组。即指针数组中的每一个元素都相当于一个指针变量。一维指针数组的定义如下:

类型名* 数组名[数组长度]

代码示例:

#include <stdio.h>
int main()
{int i;char *cName[]={"zhangsan","lisi","wangwu","luliu","hongqi"};for(i=0;i<5;i++){printf("%s\n",cName[i]);}return 0;
}

运行结果,如下:

zhangsan
lisi
wangwu
luliu
hongqi

4、字符串数组与字符串指针数组的区别

举个栗子:
char a[2][2] = {“hello”, “world”};  //字符串数组,存放的是字符
char *b[] = {“hello”, “world”};   //字符串指针数组,存放的是指针即元素地址,指针指向其中的元素

char arra[5][20];
char *arrb[5];

两者在内存分配上的区别:

  • arra是一个字符串数组,分配内存5*20=100个字节
  • arrb是一个指针数组,分配内存5*8=40个字节

两者在元素访问上的区别:

  1. arra[2][0];
    *arrb[2];
    都是用于访问各自数组中第3行的首字符;
  2. arra[2];
    arrb[2];
    都是用于表示第3行的字符串
    arra[2]是字符指针常量,arrb[2]是字符指针变量;
  3. char (*parra)[20];
    char **parrb;
    parra=arra+2;
    parrb=arrb+2;
    定义了两个变量parra、parrb,分别接收了两个数组第3行的数据
    parra指向第3行占20个字符的一维数组
    parrb指向第3行的一个指针
    **parrb指向第3行的首字符,*(*parrb+i)指向第3行第i+1个字符

代码示例:

#include <stdio.h>
int main()
{char *cName[]={"zhangsan","lisi","wangwu","luliu","hongqi"};printf("%c\n",*cName[2]);printf("%s\n",cName[2]);char **pcName;pcName=cName+2;printf("%c\n",**pcName);printf("%c\n",*(*pcName+2));return 0;
}

运行结果,如下:

w
wangwu
w
n

5、字符串数组与指针数组的运用

代码示例:

#include <stdio.h>
int main()
{char cName[5][20]={"zhangsan","lisi","wangwu","luliu","hongqi"};     // 指针数组定义了5个元素char *iArray[5];      // 指针数组定义了5个元素iArray[1]=cName[1];// strcpy(iArray,"luliu");     // 当iArray[0]未指向字符串变量的地址时,该行代码是错误的写法strcpy(iArray[1],"xiaoer");printf("%s\n",cName[0]);printf("%s\n",cName[1]);printf("%s\n",iArray[1]);return 0;
}

注意:当iArray[i]未指向任何字符串变量的地址时,不能将其拿来调用!

运行结果,如下:

zhangsan
xiaoer
xiaoer

C语言:数组与指针详解相关推荐

  1. C语言数组之间赋值详解

    数组之间的赋值,C语言数组之间赋值详解 (biancheng.net)

  2. C++ 数组与指针详解之终极无惑

    代码编译运行环境:VS2017+Debug+Win32 文章目录 1.数组 1.1数组名的意义 1.2数组的初始化 2.指针 2.1指针的定义 2.2定义指针的形式 2.3指针的初始化 2.4指针可以 ...

  3. 终于学会数组的使用啦~~~------C语言数组学习笔记详解

    本篇文章是对C语言数组内容的学习,将为初学数组的小伙伴们详细剖析数组,相信大家一定可以有所收获,接下来让我们一起学习吧!

  4. C语言指针结构体详解,结构体指针,C语言结构体指针详解

    结构体指针,可细分为指向结构体变量的指针和指向结构体数组的指针. 指向结构体变量的指针 前面我们通过"结构体变量名.成员名"的方式引用结构体变量中的成员,除了这种方法之外还可以使用 ...

  5. c语言结构体指针详解,结构体指针,C语言结构体指针详解

    结构体指针,可细分为指向结构体变量的指针和指向结构体数组的指针. 指向结构体变量的指针 前面我们通过"结构体变量名.成员名"的方式引用结构体变量中的成员,除了这种方法之外还可以使用 ...

  6. C语言访问数组的常用方法,C语言数组基本知识点详解

    数组基本知识点: 1,数组初始化,命名 2.数组大小,数组类型 3.数组访问方法 4.字符数组 5.数组下标越界 6.数组作为函数参数问题 7.二维数组基本概念以及多维数组 以后还会有关于指针数组问题 ...

  7. c语言char数组和short数组的区别,详解C语言中Char型指针数组与字符数组的区别

    详解C语言中Char型指针数组与字符数组的区别 详解C语言中Char型指针数组与字符数组的区别 1.char 类型的指针数组:每个元素都指向一个字符串,指向可以改变 char *name[3] = { ...

  8. c语言的指针详解ppt,最全的C语言指针详解.ppt

    最全的C语言指针详解.ppt 第6章 指针,6.1 指针定义与使用 6.2 指针与函数 6.3 指针与数组 6.4 指针与字符串 6.5 指针数组与多级指针 6.6 指针与动态内存分配 6.7 指针的 ...

  9. C语言结构体中定义函数指针详解

    C语言结构体中定义函数指针详解 结构体指针函数应用场景之一--驱动程序编写 结构体的一些基本用法 形式1:先定义结构体类型,再定义变量 形式2:在定义类型的同时定义变量 形式3:直接定义变量,用无名结 ...

最新文章

  1. Qt中文手册 之 QTableWidget
  2. 两种 js下载文件的方法(转)
  3. python基础教程:对象之间的交互
  4. Word2019上面的MathType7.4插件忽然消失了【终极解决办法记录】
  5. linux下定时重启tomcat
  6. 黑客攻防技术宝典Web实战篇第2版—第3章 Web应用程序技术
  7. 8备份sqlserver_关于SQL server 巡检的要点你都知道吗?
  8. JAVA常用工具类→Date、SimpleDateFormat、Calendar、System、Math
  9. 深入讲解防火墙的概念原理与实现
  10. CB Loss:基于有效样本的类别不平衡损失
  11. LeetCode题解之Missing Number
  12. 通过CuteFTP用VBScript使用SFTP,实现Win与Linux的文件传输
  13. 新入手了台IBM Thinkpad T60笔记本 重装系统
  14. Unexpected reserved word ‘await‘
  15. 天地图key的申请步骤
  16. Linux(centos)增加账户内存(Resource temporarily unavailable问题)
  17. 基于jsp+java+ssm的大学生缴费系统
  18. chrome打开链接隐私设置错误_解决用谷歌浏览器访问https网站遇到的“隐私设置错误 您的连接不是私密连接”问题...
  19. Deity is on the struggling road too!
  20. 中国悍马“猛士”登场,国产电动车为啥掀起了硬派越野风?

热门文章

  1. 23种设计模式介绍以及在Java中的实现
  2. 死亡计算机在线使用,死亡计算器免费使用
  3. 微天使联盟成立 创业者与投资者的利好
  4. mysql alter添加列
  5. js / jquery 使用val()赋值监控事件失效
  6. 跟着米其林指南,打卡曼谷唐人街街头美食
  7. Eclipse的Debug各种视图介绍(二)
  8. HFSS入门学习(二)
  9. 荣耀x10更新鸿蒙计划,【系统】鸿蒙OS适配计划:百机焕新,荣耀老用户可以放心了...
  10. nodejs+vue大学招聘求职网站