当前位置: 首页 > news >正文

C语言基础6——数组

1.一维数组

概念:具有一定顺序的若干变量的集合

在c语言中,数组可以比作一根绳子,数组内部的元素可以比作线上的每一个点。在使用这条绳之前,我们要定义好自己要取多少长度的绳子,且我们拿到的这跟绳子必须整段粗细相同,粗细也就对应着定义数组时要确定好数据类型,char类型对应的绳子相对细一点,int类型会相对粗一点。

~1格式

定义格式:(存储类型) 数据类型 数组名[元素个数];
eg:int arr[5];

~2数组名

数组名:代表数组首元素的地址,arr是地址常量,不能为左值,不能被赋值

~3访问元素

访问元素:数组名[下标];下标从0开始
访问第一个元素:arr[0]
访问第n个元素:arr[n-1]

1.1初始化

1)全部初始化

全部初始化,就是在数组定义的时候规定好数组的长度,且将数组的元素全部填充完整。

#include <stdio.h>int main()
{int arr[3] = {1, 2, 3};printf("%d\n", arr[0]);printf("%d\n", arr[1]);printf("%d\n", arr[2]);return 0;
}

2)部分初始化

部分初始化是指在数组定义的时候规定好数组的长度。

注意:部分初始化时未初始化的元素值为0。

#include <stdio.h>int main()
{int arr[3] = [1];printf("%d\n", arr[0]);printf("%d\n", arr[1]);printf("%d\n", arr[2]);return 0;
}

3)未初始化

在定义的时候只限制了数组的长度,并没有给数组赋予任何初值,未初始化的元素为随机值,需要对每个元素单独进行赋值

#include <stdio.h>int main()
{    int arr[3];printf("%d\n", arr[0]);printf("%d\n", arr[1]);printf("%d\n", arr[2]);return 0;
}

以上代码打印的三个值是编译器赋予的三个随机值

#include <stdio.h>int main()
{int arr[3];arr[0] = 1;arr[1] = 2;printf("%d\n", arr[0]);printf("%d\n", arr[1]);printf("%d\n", arr[2]);return 0;
}

以上代码给arr数组的前两个之值分别赋值,但由于是未初始化定义,第三个元素依旧是编译器给数组赋予的随机值。

4)定义空数组

*1可以全部初始化
int arr[5] = {0, 0, 0, 0, 0};

*2可以部分初始化
int arr[5] = {0};

*3
int arr[5] = {};

~4引用

1、先定义后引用

2、每次只能引用一个数组元素arr[下标],如果想要引用所有元素可以循环遍历

#include <stdio.h>int mian()
{int arr[5] = {1, 2, 3, 4, 5};int i ; for(i = 0 ; i < 5 ; i ++){printf("%d\n", arr[i]);}return 0;
}

3、引用时防止数组越界,虽然有时编译器不会报错

4、打印数组元素地址用%p格式

#include <stdio.h>int mian()
{int arr[5] = {1, 2, 3, 4, 5};int i ; for(i = 0 ; i < 5 ; i ++){printf("%p\n", &arr[i]);}return 0;
}

~5内存分配

一一对应

~6数组遍历

把循环变量作为数组下标,用for循环遍历(也可以用while、do_while循环)

#include <stdio.h>int mian()
{int arr[5] = {};int i ; for(i = 0 ; i < 5 ; i ++){scanf("%d\n", &arr[i]);    //遍历数组,依次输入数据}printf("--------------------------------")for(i = 0 ; i < 5 ; i ++){printf("%d\n", arr[i]);    //遍历数组,依次打印数据}return 0;
}

~7数组的大小

1、数组元素个数*数据类型大小
2、sizeof(数组名);
int arr[5] = {};
printf("%d\n", sizeof(arr));

计算元素的个数:
1、直接观察
2、sizeof(数组名) / sizeof(数据类型)

练习1:计算斐波那契数列前n项并逆序输出(参考代码见后面)

1 1 2 3 5 8 13 21 .....
int arr[n] = {1, 1};

~8清零函数

1、bzero
注意,使用bzero函数的时候一定要引入头文件<strings.h>

#include <strings.h>

void bzero(void *s, size_t n);

功能:将内存空间设置为0

参数:s:要清空空间的首地址

        n:字节大小

返回值:无

#include <stdio.h>
#include <strings.h>int main()
{int arr[5] = {1, 2, 3, }int i;bzero(arr, sizeof(arr));printf("-------------------------------");for(i = 0 ; i < 5 ; i ++){printf("%d\n", arr[i]);}return 0;
}

2、memset
注意,使用memset函数的时候一定要引入头文件<string.h>

#include <string.h>

void *memset(void *s, int c, size_t n);

功能:将内存空间设置为0

参数:s:要清空空间的首地址

c:要清空的值,设置为0

n:字节大小

返回值:

#include <stdio.h>
#include <string.h>int main()
{int arr[5] = {1, 2, 3, 4, 5};int i;memset(arr, 0, sizeof(arr));printf("-------------------------------");for(i = 0; i < 5 ; i ++){printf("%d\n", arr[i]);}return 0;
}

2.字符数组

字符数组存放字符串

~1概念

元素的数据类型为字符型的数组

~2使用形式

(1)
// 元素个数没有书写的时候,就会以后面实际的元素数量去开辟空间
char c[] = {'a', 'b', 'c'};
char ch[] = {}; // 大小为0,随便加入一个元素就会越界

(2)
char str[] = {"hello"}; // 用字符串赋值 sizeof(str) = 6

(3)
char ch[] = "abc" // 用字符串赋值 sizeof(str) = 4
printf("%c\n", ch[0]
);

(4)
char c[32] = "hello"; // 用字符串赋值 sizeof(str) = 32

注意:字符串赋值常常会省略数组长度,需要注意数组越界问题

2.1 字符数组的输入输出

~3输入

char s[32] = {};
1)  scanf("%s", s);

#include <stdio.h>int main()
{char[32] = {};scanf("%s", s);        //scanf后要跟变量对应的地址,而数组名便是数组首个元素对应的地址for(int i = 0 ; i < 10 ; i ++){printf("%d\n", s[i]);}printf("%s\n", s);return 0;
}

C语言支持一个字符数组在输入数据时直接输入一串字符串,在scanf格式化输入时对应的格式是%s

输入的字符串不能含有空格,因为scanf输入字符串遇到空格或\n都会认为字符串输入结束,空格后面的内容就不会存放到数组里面

如果我们需要输入空格就按以下格式输入
scanf("%[^\n]", s) // 知道输入\n才结束

2)  遍历输入字符

char str[32] = {}
int i;
for(i = 0; i < 32; i++)
{
        scanf("%c", &str[i]);
}

3)  gets

与字符相同,getchar可以吃掉一个字符,C语言中有单独吃掉一串字符串的函数,gets()

char *gets(char *s)

功能:从终端输入字符串

参数:s:目标字符数组的首地址(数组的名字)

返回值:目标字符数组的首地址

gets(s); // gets在输入不关心数组越界问题,使用时会报警告

~4输出

1.  printf("%s\n", s);

2.  for(i = 0; i < 32; i++)

printf("%c\n", str[i]);

3.  puts

int puts(const char *s);

功能:向终端输出字符串

参数:s:要输出字符串的首地址

返回值:输出字符的个数

#include <stdio.h>int main()
{char str[32] = {};gets(str);printf("--------------------\n");int num = puts(str);printf("%d\n", num);return 0;
}

【例】:判断对错

char s[10] = {};s[10] = "world";  // 错误,数组越界
s = "hello";  // 错误,s是地址常量,不能为左值
strcpy(s, "string");  // 正确

练习2:实现字符串大小写的转换(参考代码见本文最后面)

2.2 计算字符串实际长度

~1for循环遍历数组,直到\0为止

#include <stdio.h>int main()
{char str[32] = {"hello"};int len = 0;for(len = 0 ; str [len] != '\0' ; len ++);    //整个for循环无内部代码块,只是为了让len++记录长度printf("%d\n", len);return 0;
}

~2strlen

#include <string.h>                        //必不可少的头文件引用

size_t strlen(const char *s);

功能:计算字符串的实际长度(不包含\0)

参数:s:要计算的字符串的首地址

返回值:字符串的实际长度

#include <stdio.h>
#include <string.h>int main()
{char str[32] = {"hello"};int len = strlen(str);printf("%d\n", len);retunr 0;
}

sizeof(str); // 32 计算的是整个数组的大小,不是实际的个数

~3sizeof和strlen区别?

// 本质上

1.sizeof是关键字,strlen是函数

// 功能上

2.sizeof是计算数据所占空间大小,strlen计算字符串的实际长度

// 使用时

3.sizeof计算式包括\0,strlen是不包含\0;计算字符串长度的时(元素个数省略的情况下),sizeof比strlen大1;

------------------------------------------------------这是一条分割线------------------------------------------------------

天才预设的上一篇跳转路径:C语言基础5——控制语句2(循环)-CSDN博客

天才预设的下一篇跳转路径:未完待续~

天才预设的合集传送路径:C基础_Gu_shiwww的博客-CSDN博客

练习答案

练习1:

计算斐波那契数列前n项并逆序输出(参考代码见后面)

1 1 2 3 5 8 13 21 .....
int arr[n] = {1, 1};

#include <stdio.h>int main(int argc, const char *argv[])
{int n;scanf("%d",&n);        //输入确定要打印的个数n;int a[n];a[0] = 1;a[1] = 1;for (int i = 2 ; i < n ;i ++)a[i] = a[i-1] + a[i-2];for (int j = n - 1 ; j >= 0; j--)    //逆序打印printf("%d\t",a[j]);return 0;
}

此代码在定义数组之前,可以提前输入好前两个数,然后根据前两个数进行求和,元素赋值到下一个位置。

练习2:

实现字符串大小写的转换

#include <stdio.h>int main(int argc, const char *argv[])
{char a[30];gets(a);for(int i = 0 ; i < sizeof(a) ; i ++){if (a[i] >= 'A' && a[i] <= 'Z'){a[i] = a[i] + 32;}else if (a[i] >= 'a' && a[i] <= 'z'){a[i] = a[i] - 32;}}printf("%s",a);return 0;
}

注意在判断的时候可以直接'a'单引号括起来的字符,也可以直接判断对应的ASCII码值。

http://www.dtcms.com/a/285085.html

相关文章:

  • 元宇宙与Web3的深度融合:构建沉浸式数字体验的愿景与挑战
  • 2020717零碎写写
  • Python 异步编程之 async 和 await
  • ThreadLocal源码解析
  • Mac OS上docker desktop 替代方案
  • Linux 下按字节分割与合并文件
  • 压力大为啥想吃甜食
  • wireshark的常用用法
  • C++ Lambda 表达式详解:从入门到实战
  • Leetcode 03 java
  • 设备管理系统横评:预警功能、移动端体验、性价比谁更强?
  • PyTorch图像预处理全解析(transforms)
  • SAP-ABAP:SAP的‘cl_http_utility=>escape_url‘对URL进行安全编码方法详解
  • 6 基于STM32单片机的智能家居系统设计(STM32代码编写+手机APP设计+PCB设计+Proteus仿真)
  • 如何从 iPhone 向Mac使用 AirDrop 传输文件
  • 企业网络运维进入 “AI 托管” 时代:智能分析 + 自动决策,让云、网、端一眼看穿
  • 关于用git上传远程库的一些常见命令使用和常见问题:
  • Redis学习-02安装Redis(Ubuntu版本)、开启远程连接
  • ComfyUI 中RAM内存、VRAM显存、GPU 的占用和原理
  • 基于深度学习的图像识别:从零构建卷积神经网络(CNN)
  • 面对微软AD的安全隐患,宁盾身份域管如何设计安全性
  • Python调用父类方法的三种方式详解 | Python面向对象编程教程
  • 【DOCKER】-5 镜像仓库与容器编排
  • 云服务器如何设置防火墙和安全组规则?
  • Java EE进阶3:SpringBoot 快速上手
  • 【Linux】Makefile(二)-书写规则
  • 【原创】【图像算法】高精密电子仪器组装异常检测
  • 力扣119:杨辉三角Ⅱ
  • Cursor出现This model provider doesn’t serve your region解决方案
  • 【调度算法】