数组

概念:在内存中连续存储的具有相同数据类型的一组数据的集合。

注意:

  • 数组中的数据类型必须都是一致的
  • 数组在内存中必须是连续的存储空间

定义数组时候的注意事项:

  • 定义数组的时候,[]里面的值不能是变量,只能是常量。例如int num[n]。
  • 使用数组的时候,[]里面的值可以是常量也可以是变量。例如已经定义了数组num[10],利用for循环遍历的时候可以用num[i]来遍历。

数组名的含义

如图可以看出,数组元素在内存中的存储地址是连续的,尤其注意以下内容的区分。

  • a[0]代表第0个元素
  • &a[0]代表的是第0个元素的地址,在本例中&a[0]=01
  • 数组名a代表数组,也代表着第0个元素的地址--->a == &a[0] ==01,所以说数组名是一个常量(常量不能被赋值),也就是第0个元素的首地址。
  • &a代表整个数组的地址,在数值上 &a == &a[0] == a ,但是意义上不同,&a代表的是整个数组的地址,而a和&a[0]是第0个元素的地址,下一条会介绍具体区别。
  • &a[0]+1 代表元素的地址+1,跨过一个元素,此时指向的是a[1]的首地址也就是05
  • a+1 也代表元素的地址+1,跨过一个元素
  • 而&a代表的是整个数组的地址,&a+1则表示跨过整个数组,此时地址变成21,这就是上面整个数组地址第0个元素地址的区别,他们跨过的元素个数不同

总结:数组名是一个地址常量(第0个元素的首地址);&a[0]代表第0个元素的首地址;&a代表的是整个数组的地址。

一维数组

初始化:在定义数组的同时进行赋值,成为初始化。

  • 全局数组如果不初始化,编译器将将数组元素初始化为0.
  • 局部数组如果不初始化,内容将会是随机的。

示例:

#include<stdio.h>
int num1[5]; int main()
{
int num2[5];
for (int i = 0; i < 5; i++)
{
printf("%d ", num1[i]);
}
printf("\n");
for (int i = 0; i < 5; i++)
{
printf("%d ", num2[i]);
}
return 0; }

运行结果如下

注意:

  • 若元素没有全部被赋值,那么未被赋值的元素默认会被赋值为0。例如 int num[3]={1},那么此时num中的元素其实是 1,0,0。
  • []中不定义元素个数,定义的时候必须初始化,因为数组需要知道具体要开辟几个元素的空间。例如int num[];int num[] = {1,2,3},此时num默认有三个元素,元素个数由{}里面的个数来定。

二维数组

定义:类型说明符 数组名[常量表达式1] [常量表达式2]

二维数组名

int a[2] [3]

  • a[0] [0] 代表第0行第0个元素
  • &a[0] [0]代表第0行第0个元素的地址,也就是01
  • a[0]代表第0行一维数组的数组名 a[0] = &a[0] [0]
  • &a[0]第0行的地址01
  • a 二维数组数组名,代表二维数组,也代表首行地址 &a[0]
  • &a 二维数组的地址
  • &a[0] [0] +1 元素地址+1,跨过一个元素
  • a[0] +1 元素地址+1,跨过一个元素
  • &a[0] +1 行地址+1,跨过一行
  • a+1 行地址+1,跨过一行
  • &a + 1 二维数组地址+1,跨过整个数组

字符数组

字符数组和字符串的区别

  • 首先,在C语言中,没有字符串这种数据类型,C语言中的字符串其实上是char数组。
  • 在C++中有字符串类型,实际上是类模板,是一个类。
  • 字符串一定是一个char的数组,但是char数组未必是字符串。
  • 数组0(和字符串‘\0’等价)结尾的char数组就是一个字符串,但是如果char数组没有以数字0结尾,那么就不是一个字符串,只是普通数组,所以字符串是一种特殊的char数组。
#include<stdio.h>

int main()
{
char c[] = {'a','b','c'};//普通的字符数组
printf("%s\n", c);//乱码,因为没有'\0'结尾,用%s打印出错
//有'\0'结尾的字符数组就是字符串
char c1[] = { 'a','b','c','\0'};
printf("%s\n", c1);
char c2[]= { 'a','b','c','\0' ,'d','e','f'};
printf("%s\n", c2);// \0后面的部分不会被打印
return 0;
}

运行结果如下:



打印字符串的时候遇到'\0'就停止打印,字符数组含有'\0'就是字符串。

注意:char c[] = "hello",用" "括起来的就是字符串,此时编译器会自动在后面加上\0,在内部其实是这样的额char c[] = {'h','e','l','l','o','\0'}。

scanf和gets

scanf 遇到空格结束,遇到\n结束,所以用scanf这种方式并不是很好,有时候想要读取一个hello world遇到空格结束,只能读取到hello。

  • gets(str)允许输入的字符串有空格
  • scanf不允许含有空格
  • 但是scanf和gets都有一个很致命的缺点,就是如果存放读取字符的空间不足,会自动向后存储,会造成内存污染,假设给定的字符空间是num[5]大小是5,但是如果输入的字符大小超过5,依旧会存储,此时会自动覆盖后面空间的内容,会造成内存污染

fgets

示例:

#include<stdio.h>

int main()
{
char buf[5] = "";
fgets(buf, sizeof(buf), stdin);
printf("%s\n", buf);
return 0;
}

运行结果如下:

fgets会把回车键\n读取,但是scanf和gets遇到\n会结束读取。

有一种情况,定义了一个数组char a[3];,输入的时候输入的是a+回车,那么此时用fgets获取char数组内的内容就是a[3] = {'a','回车','\0'};

如何去掉\n?

只需要将\n替换成\0

示例:

char buf[128] = "helloA";//buf[5]=0;
int i=0;
while(buf[i]!='\0')
{
i++;
}
buf[i-1] = '\0';
printf("%s\n",buf);

strlen

size_tn strlen(const char s);

功能:计算指定指定字符串s的长度,不包含字符串结束符‘\0’

参数:s:字符串首地址

返回值:字符串s的长度,size_t为unsigned int类型

fgets相对于scanf和gets不会污染内存(安全),但是fgets会读取\n,所以只需要将\n去掉就可以了。

字符数组输出函数

printf

char buf[1024] = "hello world";
printf("%s\n",buf)

打印字符串的时候遇到'\0'就停止打印。

puts

*int puts(const char s);

功能:标准设备输出s字符串,在输出完成后自动输出一个'\n'。

char buf[1024] = "hello world";
puts(buf);//数组首元素地址,有换行

fputs

**int fputs(const char str,FILE stream);

功能:将str所指定的字符串写入stream指定的文件中,字符串结束符'\0'不写入文件。

参数:str:字符串

​ stream:文件指针,如果把字符串输出到屏幕,就固定写为stdout

char  buf[1024] = "hello world";
fputs(buf,stdout);//第一个参数,数组元素首地址,第二个参数stdout标准输出

C语言基础--数组的更多相关文章

  1. day05<Java语言基础--数组>

    Java语言基础(数组概述和定义格式说明) Java语言基础(数组的初始化动态初始化) Java语言基础(Java中的内存分配以及栈和堆的区别) Java语言基础(数组的内存图解1一个数组) Java ...

  2. Java语言基础(数组)

    Java语言基础(数组概述和定义格式说明) A:为什么要有数组(容器) 为了存储同种数据类型的多个值 B:数组概念 数组是存储同一种数据类型多个元素的集合.也可以看成是一个容器. 数组既可以存储基本数 ...

  3. C语言基础--数组及相关

    概念: 一堆相同类型的数据的有序集合 格式: 元素类型  数组名称[ 元素个数 ] 定义数组: // 定义了一个名称叫做scores的数组, 数组中可以存放3个int类型的数据 ]; // 只要定义一 ...

  4. iOS开发环境C语言基础 数组 函数

    1 求数组元素的最大值 1.1 问题 创建程序,实现查询数组中最大值的功能,需求为:创建一个长度为10的数组,数组内放置10个0~99之间(包含0,包含99)的随机数作为数组内容,要求查询出数组中的最 ...

  5. [C语言基础] 数组与指针之间的引用

    通过指针引用数组,通过数组引用指针,你搞明白了么?通过下面3种情形来了解一下数组和指针 Case 1. unsigned char arry[10]; unsigned char *ptr; unsi ...

  6. C#语言基础——数组

    数组 一.一位数组 数组初始化,创建数组,数组长度为5 int[] array = new int[5]; array[0] = 1; array[1] = 2; array[2] = 3; arra ...

  7. C语言基础:数组 分类: iOS学习 c语言基础 2015-06-10 21:40 7人阅读 评论(0) 收藏

    数组:是由一组具有相同数据类型的数据组合而来. 数组定义:元素类型修饰符 数组名[数组个数]={元素1,元素2....};  int arr[ 2 ]={1,2};    //正确 int arr[ ...

  8. R语言基础-数组和列表

    数组(array) 一维数据是向量,二维数据是矩阵,数组是向量和矩阵的直接推广,是由三维或三维以上的数据构成的. 数组函数是array(),语法是:array(dadta, dim),当中data必须 ...

  9. 【搬砖】安卓入门(4)- Java开发编程基础--数组

    05.01_Java语言基础(数组概述和定义格式说明)(了解) A:为什么要有数组(容器) 为了存储同种数据类型的多个值 B:数组概念 数组是存储同一种数据类型多个元素的集合.也可以看成是一个容器. ...

随机推荐

  1. STC8H开发(十五): GPIO驱动Ci24R1无线模块

    目录 STC8H开发(一): 在Keil5中配置和使用FwLib_STC8封装库(图文详解) STC8H开发(二): 在Linux VSCode中配置和使用FwLib_STC8封装库(图文详解) ST ...

  2. Docker 容器虚拟化

    Docker 容器虚拟化 1.虚拟化网络 Network Namespace 是 Linux 内核提供的功能,是实现网络虚拟化的重要功能,它能创建多个隔离的网络空间,它们有独自网络栈信息.不管是虚拟机 ...

  3. MyBatis 04 实战

    增删改查实现 在实际使用中,MyBatis 的使用遵从一定的规范. 常用的增删改查的 MyBatis 实现如下: Mapper.xml <?xml version="1.0" ...

  4. java学习第一天.day03

    运行程序数据存储 ASCII Unicode(万国码) A在码表的顺序是65,a在码表的顺序是97,1代表49 变量 定义一个变量声明数据类型是开辟一个空间存储数据,java对数据的定义比较严格,比如 ...

  5. HCNP Routing&Switching之MAC安全

    前文我们了解了GRE over IPSec 相关话题,回顾请参考https://www.cnblogs.com/qiuhom-1874/p/16601491.html:今天我们来聊一聊mac安全相关话 ...

  6. day25--Java集合08

    Java集合08 15.HashTable 15.1HashTable的基本介绍 存放的元素是键值对:即K-V HashTable的键和值都不能为null HashTable的使用方法基本上和Hash ...

  7. 回溯、贪心、DP的区别和联系

    四大常用算法:分治.贪心.回溯.动态规划 回溯算法是个"万金油".基本上能用跟动态规划.贪心解决的问题,都可以用回溯去解决.回溯算法相当于穷举搜索,穷举所有情况,然后得到最优解.不 ...

  8. FFT快速傅立叶变换:解析wav波频图、Time Domain、Frequency Domain

    您好,此教程将教大家使用scipy.fft分析wav文件的波频图.Time Domain.Frequency Domain. 实际案例:声音降噪,去除高频. 结果: 波频图: Time Domain:

  9. 员工离职困扰?来看AI如何解决,基于人力资源分析的 ML 模型构建全方案 ⛵

    作者:韩信子@ShowMeAI 数据分析实战系列:https://www.showmeai.tech/tutorials/40 机器学习实战系列:https://www.showmeai.tech/t ...

  10. JS中如何删除某个父元素下的所有子元素?

    JS中如何删除某个父元素下的所有子元素?这里我介绍几种方法: 1.通过元素的 innerHTML 属性来删除 这种方式我觉得是最有方便的,直接找到你想要的父元素,直接令其 element.innerH ...