C语言基础--数组
2022/10/24 14:24:18
本文主要是介绍C语言基础--数组,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!
数组
概念:在内存中连续存储的具有相同数据类型的一组数据的集合。
注意:
- 数组中的数据类型必须都是一致的
- 数组在内存中必须是连续的存储空间
定义数组时候的注意事项:
- 定义数组的时候,[]里面的值不能是变量,只能是常量。例如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语言基础--数组的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!
- 2024-11-22怎么实现ansible playbook 备份代码中命名包含时间戳功能?-icode9专业技术文章分享
- 2024-11-22ansible 的archive 参数是什么意思?-icode9专业技术文章分享
- 2024-11-22ansible 中怎么只用archive 排除某个目录?-icode9专业技术文章分享
- 2024-11-22exclude_path参数是什么作用?-icode9专业技术文章分享
- 2024-11-22微信开放平台第三方平台什么时候调用数据预拉取和数据周期性更新接口?-icode9专业技术文章分享
- 2024-11-22uniapp 实现聊天消息会话的列表功能怎么实现?-icode9专业技术文章分享
- 2024-11-22在Mac系统上将图片中的文字提取出来有哪些方法?-icode9专业技术文章分享
- 2024-11-22excel 表格中怎么固定一行显示不滚动?-icode9专业技术文章分享
- 2024-11-22怎么将 -rwxr-xr-x 修改为 drwxr-xr-x?-icode9专业技术文章分享
- 2024-11-22在Excel中怎么将小数向上取整到最接近的整数?-icode9专业技术文章分享