2023-4-27首次编辑
C[数组+函数]
Unit 5:数组
一.定义
将若干个相同数据类型的变量,存放在一个连续的内存空间
最小单位:元素
- 数组中的每一个元素都是一个变量
数组属于构造数据类型
- 一个数组可以分解为多个数组元素
- 这些数组元素可以是基本数据类型或构造类型
按数组元素类型分为:
- 数值数组
- 字符数组
- 指针数组
- 结构数组
按数组维数分为:
- 一维数组
- 多维数组 (二维以上的数组)
二.一维数组
#define _CRT_SECIRE_NO_WARNINGS
#include <stdio.h>
void test()
{
//定义:[]中没有值,此数组的元素个数由{}中的元素个数决定
int num[] = { 1,2,3 };
//初始化:只初始化部分元素,其他元素则被初始化为0
//int num[10] = { 1,2,3,4,5,6,7,8,9,10 };
//int num[10] = { 1,2 };
//int num[10] = { 0 }; //将所有元素初始化为0
//1.求单个元素大小
printf("单个元素大小=%d\n", sizeof(num[0]));
//2.求整个数组大小
printf("整个数组大小=%d\n", sizeof(num));
//3.求数组元素个数
printf("数组元素个数=%d\n", sizeof(num) / sizeof(num[0]));
//打印数组元素
for (int i = 0; i < sizeof(num)/sizeof(num[0]); i++)
{
printf("%d ", num[i]);
}
printf("\n");
}
int main()
{
test();
system("pause");
return 0;
}
三.二维数组
多个一维数组
#define _CRT_SECIRE_NO_WARNINGS
#include <stdio.h>
void test()
{
//定义:可以省略行下标,不能省略列下标
int a[][3] = { 1,2,3,4,5 };
//初始化:部分元素初始化,其他元素为0
//int a[3][4] = { {1,2,3,4},{5,6,7,8},{9,10,11,12} };
//int a[3][4] = { 1,2,3,4,5,6,7,8,9,10,11,12 };
//int a[3][4] = { 1,2,3 };
//1.求元素个数
int n = sizeof(a) / sizeof(a[0][0]);
//2.求行数 = 二维数组总大小 / 一行的大小
int line = sizeof(a) / sizeof(a[0]);
//3.求列数 = 行大小 / 一个元素大小
int clu = sizeof(a[0]) / sizeof(a[0][0]);
printf("元素个数=%d 行数=%d 列数=%d\n", n, line, clu);
//打印
for (int i = 0; i < sizeof(a) / sizeof(a[0]); i++)
{
for (int j = 0; j < sizeof(a[0])/sizeof(a[0][0]); j++)
{
printf("%d ", a[i][j]);
}
printf("\n");
}
}
int main()
{
test();
system("pause");
return 0;
}
四.多维数组
典型 : 三维数组int num[2][3][4]
- 1个三维数组
- 每个三维数组中有2个二维数组
- 每个二维数组中有3个一维数组
- 每个一维数组中有4个元素
#define _CRT_SECIRE_NO_WARNINGS
#include <stdio.h>
void test()
{
//定义与初始化
int num[2][3][4] = {
{
{1,2,3,4},{5,6,7,8},{8,9,10,11}
},
{
{12,13,14,15},{16,17,18,19},{20,21,22,23}
}
};
//1.求元素个数
int n = sizeof(num) / sizeof(num[0][0][0]);
//2.求二维数组个数
int two_num = sizeof(num) / sizeof(num[0]);
//3.求一维数组个数
int one_num = sizeof(num[0]) / sizeof(num[0][0]);
//4.求一维数组中元素个数
int ele = sizeof(num[0][0]) / sizeof(num[0][0][0]);
printf("元素个数=%d 二维数组个数=%d 一维数组个数=%d 一维数组中元素个数=%d\n", n, two_num, one_num, ele);
//打印
for (int i = 0; i < sizeof(num) / sizeof(num[0]); i++)
{
for (int j = 0; j < sizeof(num[0]) / sizeof(num[0][0]); j++)
{
for (int k = 0; k < sizeof(num[0][0]) / sizeof(num[0][0][0]); k++)
{
printf("%d ", num[i][j][k]);
}
printf("\n");
}
printf("\n");
}
}
int main()
{
test();
system("pause");
return 0;
}
五.数组名与地址
一维数组
- a[0] : 第0个元素
- &a[0] : 第0个元素地址
- a : 数组名(首元素地址)
- &a : 整个数组的地址
- &a[0]+1 : 跨过一个元素
- a+1 : 跨过一个元素
- &a+1 : 跨过整个数组
二维数组
- a[0][0] : 第0行第0个元素
- &a[0][0] : 第0行第0个元素地址
- a[0] : 第0行一维数组的数组名
- &a[0] : 第0行一维数组的地址
- a : 二维数组数组名(首行首元素地址)
- &a : 二维数组的地址
- &a[0][0]+1 : 跨过一个元素
- a[0]+1 : 跨过一个元素
- &a[0]+1 : 跨过一行
- a+1 : 跨过一行
- &a+1 : 跨过整个数组
数组名是地址,也是常量,不能被赋值
六.字符数组
每个元素都是char类型的数组
#define _CRT_SECIRE_NO_WARNINGS
#include <stdio.h>
void test()
{
//定义与初始化
//char a[5] = { 'a','b','c','d','e' }; //普通的字符数组
//char a[5] = { 'a','b','c','d','\0' }; //字符串,既字符数组中含有'\0'字符
//char a[5] = "abcd"; //存的是abcd\0
//char a[] = "world"; //有6个元素
//char a[100] = "abcd"; //有100个元素
//char a[100] = "\0"; //所有元素为'\0'
char a[100] = { 0 }; //清0
//打印字符数组
//1.
//for (int i = 0; i < sizeof(a)/sizeof(a[0]); i++)
//{
// printf("%c ", a[i]);
//}
//printf("\n");
//2.
printf("%s\n", a);
}
int main()
{
test();
system("pause");
return 0;
}
七.读取/打印
#define _CRT_SECIRE_NO_WARNINGS
#include <stdio.h>
//scanf读取
void test1()
{
char ch = 0;
char num[5] = "";
//1.读取单个字符
//scanf("%c", &ch);
//printf("%c\n", ch);
//2.读取一个字符串
//遇到'\n',空格结束,不读取空格
//会造成内存污染
scanf("%s", &num);
printf("%s\n", num);
}
//gets读取
void test2()
{
//参数:存放读取字符串的地址
//遇到'\n'结束,但是遇到空格不结束,并读取空格
//会造成内存污染
char num[5] = "";
gets(num);
printf("num=%s\n", num);
}
//fgets读取
void test3()
{
//参数:字符串地址,读取大小,读取位置
//遇到'\n'结束,会将'\n'读取,遇空格不结束,并读取
//不会造成内存污染
char buf[5] = "";
fgets(buf, sizeof(buf), stdin);
printf("%s\n", buf);
}
//输出
void test4()
{
char buf[1024] = "Hello World";
//1.
//printf("%s\n", buf);
//2.
//有换行
//puts(buf);
//3.
//参数:数组地址,输出位置
//无换行
fputs(buf, stdout);
}
int main()
{
//test1();
//test2();
//test3();
test4();
system("pause");
return 0;
}
扩展:产生随机数
#define _CRT_SECIRE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h> //srand(),rand()所需头文件
#include <time.h> //time头文件
void test()
{
int t = time(NULL); //time函数获得当前时间s
//1.设置随机数种子
srand(time(NULL));
//2.获得随机数
int a = rand();
printf("a=%d\n", a);
int b = rand();
printf("a=%d\n", b);
}
int main()
{
test();
system("pause");
return 0;
}
Unit 6:函数
一.作用
- 为了减少重复代码块
- 代码模块清晰
二.类型
#define _CRT_SECIRE_NO_WARNINGS
#include <stdio.h>
//1.无参无返回值
//没有形参,可以不写,也可以写void
//没有返回值,需要写void
void fun1()
{
printf("hello fun\n");
return;
//返回值类型看函数定义时,所需要的类型
}
//2.有参无返回值
//定义函数时,不会给形参开辟空间
//只有在被调用时,才会分配空间
void fun2(int a, int b)
{
int c = 0;
c = a + b;
printf("c=%d\n", c);
return;
}
//3.有参有返回值
//调用时,可以不接返回值,也可以接
//返回的类型和所接受返回值的变量的类型需要相同
//参数的传递,只能是单向传递(实参传给形参)
int fun3(int a, int b)
{
return a + b;
}
void test()
{
int x = 10;
int y = 20;
int sum;
fun1();
fun2(x, y);
sum = fun3(x, y);
printf("sum=%d\n", sum);
}
int main()
{
test();
system("pause");
return 0;
}
三.值传递
实参传给形参,形参的值改变,不影响实参的值
#define _CRT_SECIRE_NO_WARNINGS
#include <stdio.h>
void swap(int a, int b)
{
int c = a;
a = b;
b = c;
printf("a=%d,b=%d\n", a, b);
}
void test()
{
int x = 10;
int y = 20;
swap(x, y);
printf("x=%d,y=%d\n", x, y);
}
int main()
{
test();
system("pause");
return 0;
}
四.声明
- 告诉编译器在其他地方定义
- 把函数的定义形式放在调用之前\
- 声明时,需要加上分号
#define _CRT_SECIRE_NO_WARNINGS
#include <stdio.h>
//1.extern
extern void fun(int a, int b);
//2.不加extern
void fun(int a, int b);
//3.不写形参名
void fun(int, int);
void test()
{
int x = 10, y = 20;
fun(x, y);
}
void fun(int a, int b)
{
printf("fun()\n");
}
int main()
{
test();
system("pause");
return 0;
}
五.return与exit区别
return
- 结束当前所在函数
exit
- 结束整个程序
六.防止头文件重复包含
第一种方式:
#ifndef 宏(宏的名字最好和文件相同,大写)
#define 宏(与上方相同)
...
#endif
第二种方式:
#pragma once
...