全面学习C语言【三】:函数、本地变量、数组(一维数组、二维数组)

八、函数

在C中 函数是这样的:

void hello(int id)
{
	printf("Hello!%d",id);
}

C不像Java 在C中定义函数的时候不需要权限修饰符 只有返回类型函数名

和Java一样 在C中也是使用return来返回值

int calc(int count)
{
	int newCount=count-1;
	return newCount;
}

🎈函数的先后关系

C的编译器是按照代码书写顺序自上而下按顺序分析代码的
因此 要将函数定义在主函数(main)的上面 使得C先知道代码中的函数
这样 当main中需要调用的时候 才能执行对应的函数
否则 若是main函数在上面 函数书写在下面 那么在执行函数的时候 C是不知道下面有没有对应的函数的 在编译的时候可能会报错

因此 若想让主函数(main)写在代码的上面 必须让C先了解代码中有哪些函数 需将函数的原型声明放在main的上面

比如:

#include <stdio.h>

// 函数的原型声明 以分号结尾
int calc(int count);

int main()
{
	int a=5;
	int b;
	b=calc(a);
	printf("%d",b);
}

// 函数的定义
int calc(int count)
{
	int newCount=count-1;
	return newCount;
}

声明并不是函数 只是先告诉C编译器有这么一个函数
在编译到了函数的定义的时候还会再对声明进行一次校验
因此 必须保证函数的声明和定义完全一致

在函数的原型声明中还可以不带有入参的名称 只要有参数类型即可

比如:

int calc(int);

但为了方便阅读代码 最好还是带上参数的名称

如果函数没有参数 建议在参数里面写上void 而不要留空
留空意味着并不一定是没有参数 而是函数的参数表未知
因此 当参数留空时 C会进行猜测 从而导致可能会产生一些类型转换的问题

🚩当参数的类型不匹配时

在C语言中 调用函数时所给的值与参数的类型可以不匹配
编译器会自动将类型进行转换可能不会给出错误提示 因此可能会出现一些问题

C语言在调用函数时 永远只能传给函数 而不是传变量

🎈本地变量的规则

  • 本地变量定义在块中 可以是函数的块 语句的块 甚至是随意一对花括号
    在程序运行进入到这个快的区域内之前 其中的变量是不存在的
    在离开这个块之后 其中的变量就消失了

  • 块的外部定义的变量在块的里面仍然是有效的 仍然可以使用

  • 在块的内部 若定义了一个和外部同名的变量 那么会掩盖外面的变量 (个人觉得掩盖比覆盖用词更为妥当)
    在块内部使用时 使用的是在块内部定义的那个变量 而不是外部的同名变量 (然而在Java中就不行了 因此这是C和Java的一个区别)
    当到了块的外部后 则外面的变量又会生效了

另 需要注意的是 在C语言中 不允许函数的嵌套
也就是不允许在一个函数的函数体内放入另外一个函数的函数体
但是可以放入另一个函数的声明

main() 是程序的入口 也是一个函数
同样 在main中 需要返回一个值 作为程序的状态码
在传统程序中 若返回0 则代表正常运行 若返回非0 则代表出现了一些异常

int main()
{
	return 0;
}

九、数组

🎈一维数组

🚩定义数组

格式:<类型> 变量名[数量];

例如:

int count[100]; // 定义一个长度100的类型为int的名称为count的数组
double height[20]; // 定义一个长度20的类型为double的名称为height的数组

:在C99之前 元素数量必须是编译时确定的字面量 不能是变量

数组一旦创建 无法改变数组的大小
数组中的元素在内存中是紧密地依次排列的

如果定义一个数组:int i[100];
那么 每个单元就是i[n]
在赋值号=的左边的是左值 在右边的是右值

在C语言中 无论是编译器还是运行环境 都不会检查代码中的数组下标是否越界(无论是读操作还是写操作)
因此 一旦程序运行了 则越界的数组操作可能导致程序出现问题

数组集成初始化

对于数组 还有一种初始化的方式 就是在创建数组的时候给定数组中所有的值
比如:

 int i[]={1,2,3,4,5,6,7,8};

(当然 在Java中也有这种初始化的方式)

如果这么定义:

int i[10]={1};

那么 数组 i 的内部是这样的:1 0 0 0 0 0 0 0 0 0
若未设置值 那么默认会将数组中值设为0

集成初始化的定位

C99中 还可以使用定位来给数组赋初始值
比如:

int i[10]={
	[1]=12,[3]=21,36
}

上述代码的意思是:为数组 i 中的第二项赋初始值为12 为第四项赋初始值为21 为第五项赋初始值为36

🚩数组的大小和长度

在C中 使用sizeof来获取整个数组所占据的内容的大小(单位为字节)

在C中不像Java有length能直接获取数组的长度 但可以间接获得
数组的大小除以数组中第一个单位的大小 (因为数组中每个单位的大小都是相同的)

int i[6];
// 数组的大小 
printf("%d\n",sizeof(i)); // 24
// 数组中第一个单位的大小 
printf("%d\n",sizeof(i[0])); // 4

// 数组的长度
printf("%d\n",sizeof(i)/sizeof(i[0])); // 6

🚩数组的赋值

数组不能直接赋值 比如:

int a[]={1,2,3};
int b[]=a;

数组变量本身不能被赋值
若要将一个数组中的所有元素交给另一个数组 那么必须采用遍历 这是唯一的方式

在C中 数组在作为函数的参数传入时 必须再用另一个参数来传入该数组的大小
因为 在函数中 不能再使用sizeof来计算数组的元素个数了

🎈二维数组

🚩定义数组

格式:<类型> 变量名[行数量][列数量];

例如:

int count[3][5]; // 定义一个3行5列的类型为int的名称为count的数组(矩阵)
数组集成初始化
int i[][5]=[
	{1,2,3,4,5},
	{6,7,8,9,10}
];

在初始化的时候 必须给出列数

若省略 则表示后面的值补为默认的0

也可以写成一行 就像一维数组一样:
但是不方便阅读

int i[][3] = {1,2,3,4,5,6,7,8,9};
相当于
int i[][3]=[
	{1,2,3},
	{4,5,6},
	{7,8,9}
];

当然 在C99中 也可以可以使用定位来给二维数组赋初始值


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章