变长数组是声明的时候不知道个数的数组,声明时使用变量来表示个数。变长数组是C99标准中提出的,在C89标准中不支持。这种数组应该使用循环来进行初始化。
二维数组是对一维数组进行分组管理的方式,也可以看成是由多个组构成的的数组。声明语法
int shu[3][4];
其中3表示组的个数,4表示每个组中变量的个数
二维数组里每个组中的变量个数必须一样
二维数组使用时要提供两个下标,前一个称为组下标后一个称为组内下标。这两个下标都不能越界。
C语言程序的基本组成单元是函数,函数代表了对某些数据的一个处理过程,这些处理过程用若干语句来描述。函数之间通过互相调用共同协作完成特定的工作,在调用中发起者的角色叫调用函数,被动接受者的角色叫被调用函数。
函数声明语法如下
int add(int value_1, int value_2) {
处理语句
}
add表示函数名(不同函数的名字不能相同),前面的int表示返回值类型。value_1和value_2是函数的参数,他们在函数内部就作为变量使用,他们的数值由调用函数决定。小括号里的内容叫做函数的参数列表。用return语句指定结果数据(返回值)。整个函数调用语句可以当成数据使用,数据就是函数调用的返回值。
形参和实参的关系参考练习09param.c。
gcc会对函数调用进行隐式声明,参考例子10add.c。
声明函数时如果没有明确描述参数信息,则调用函数的时候
实参会被进行隐式类型提升,所有整数提升成int类型,所有带小数点的数字被提升成double类型。
数组做函数的参数可以在调用函数和被调用函数之间共享数组中的所有变量,也就是说被调用函数可以直接修改数组中变量的内容。数组做参数时不需要指定数组中变量的个数。
当使用数组作为函数参数使用的时候需要另外使用参数来表示数组中变量的个数。
/*
数组初始化练习
*/
#include <stdio.h>
int main() {
//int shu_zi[3] = {1, 2, 3}/*数组初始化基本语法*/, xun_huan = 0;
//int shu_zi[3] = {1, 2, 3, 4, 5}/*多余的初始化数据会被丢弃*/, xun_huan = 0;
//int shu_zi[3] = {1}/*没有对应初始化数据的变量自动被初始化成0*/, xun_huan = 0;
//int shu_zi[] = {1, 2, 3, 4, 5}/*数组中变量个数由初始化数据的个数决定*/, xun_huan = 0;
int shu_zi[5] = {[3] = 3, [1] = 1}/*C99标准中支持指定初始化,顺序任意*/, xun_huan = 0;
int ge_shu = sizeof(shu_zi) / sizeof(shu_zi[0]);
printf("数组中变量个数是%d\n", ge_shu);
for (xun_huan = 0; xun_huan <= (ge_shu - 1); xun_huan++) {
printf("%d ", shu_zi[xun_huan]);
}
printf("\n");
return 0;
}
/*
字符个数统计练习
*/
#include <stdio.h>
int main() {
int shu = 0, ci_shu[10] = {0}, xun_huan = 0;
printf("请输入一个数字:");
scanf("%d", &shu);
do {
ci_shu[shu % 10]++;
shu /= 10;
} while(shu);
for (xun_huan = 0; xun_huan <= 9; xun_huan++) {
printf("数字%d出现的次数是%d\n", xun_huan, ci_shu[xun_huan]);
}
return 0;
}
/*
利率练习
*/
#include <stdio.h>
int main() {
int li_lv = 0, nian = 0, xun_huan = 0, xun_huan_1 = 0, ge_shu = 0;
printf("请输入利率数字,个数和年限:");
scanf("%d %d %d", &li_lv, &ge_shu, &nian);
float qian[ge_shu];
for (xun_huan = 0; xun_huan <= (ge_shu - 1); xun_huan++) {
qian[xun_huan] = 100.0f;
}
//打印表头
printf("年");
for (xun_huan = li_lv; xun_huan <= (li_lv + ge_shu - 1); xun_huan++) {
printf("%7d%%", 100 + xun_huan);
}
printf("\n");
//打印表内容
for (xun_huan = 1; xun_huan <= nian; xun_huan++) {
printf("%2d", xun_huan);
for (xun_huan_1 = li_lv; xun_huan_1 <= (li_lv + ge_shu - 1); xun_huan_1++) {
// (100+xun_huan_1)/100.0是利率加本金
qian[xun_huan_1 - li_lv] *= (100 + xun_huan_1) / 100.0f;
printf("%8.2f", qian[xun_huan_1 - li_lv]);
}
printf("\n");
}
return 0;
}
/*
二维数组练习
*/
#include <stdio.h>
int main() {
//int shu[3][4]; //二维数组声明语法,不能写成shu[3,4]
//int shu[3][4] = {{1, 2, 3, 4}, {5, 6, 7, 8}, {9, 10, 11, 12}};
//int shu[][4] = {{1, 2, 3, 4}, {5, 6, 7, 8}, {9, 10, 11, 12}}; //提供了初始化数据就可以省略组的个数
//int shu[3][4] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12};
//int shu[][4] = {{1, 2}, {5}, {9, 10, 11}}; //没有提供初始化数据的变量自动被初始化成0
int shu[3][4] = {1, 2, 5, 9, 10, 11}; //和上一行的初始化结果不同
//int shu[3][4] = {[2][2] = 2, [1][1] = 1}; //C99标准中支持指定初始化,顺序任意
int hang = 0, lie = 0;
printf("变量个数是%d\n", sizeof(shu) / sizeof(shu[0][0]));
for (hang = 0; hang <= 2; hang++) {
for(lie = 0; lie <= 3; lie++) {
printf("%d ", shu[hang][lie]);
}
printf("\n");
}
printf("shu[0]是%p,shu是%p\n", shu[0], shu);
printf("shu[0] + 1是%p,shu + 1是%p\n", shu[0] + 1, shu + 1);
return 0;
}
/*
单位矩阵练习
*/
#include <stdio.h>
int main() {
int shu[4][4] = {{1}, {0, 1}, {0, 0, 1}, {0, 0, 0, 1}}, hang = 0, lie = 0;
for (hang = 0; hang <= 3; hang++) {
for (lie = 0; lie <= 3; lie++) {
printf("%d ", shu[hang][lie]);
}
printf("\n");
}
return 0;
}
/*
函数练习
*/
#include <stdio.h>
int add(int value_1, int value_2) {
return value_1 + value_2;
}
int main() {
int shu = 0;
shu = add(2, 3); //函数调用
shu = add(shu, 4); //函数调用
printf("%d\n", shu);
return 0;
}
/*
计算立方体体积的函数练习
*/
#include <stdio.h>
int cube(int length, int width, int height) {
return length * width * height;
}
int main() {
printf("体积是%d\n", cube(2, 3, 4));
return 0;
}
/*
函数练习
*/
#include <stdio.h>
//没有声明返回值类型的函数缺省按照返回值类型为
//int处理
f1() {
return 3;
}
//没有返回值的函数要用void表示返回值类型
void f2() {
}
//没有使用return语句指定返回数值的函数会
//返回任意一个数据
int f3() {
}
//返回数值和返回值类型不匹配会被自动转换
int f4() {
return 4.7;
}
void f5() {
return ; //没有返回值的函数也可以使用return语句,但是不可以指定返回数值
}
//没有参数的函数要用void表示参数列表,如果什么都
//不写表示接受任意个数,任意类型的参数
void f6(void) {
}
int main() {
printf("结果是%d\n", f1());
//printf("结果是%d\n", f2()); //没有返回值的函数不可以当数字使用
printf("结果是%d\n", f3());
printf("结果是%d\n", f4());
return 0;
}
/*
参数练习
*/
#include <stdio.h>
/*
形参和实参在内存中占据不同的位置,
在函数开始执行之前计算机用实参对
形参进行了一次赋值操作,以后他们
之间就没有关系了。
函数中对形参的修改不会影响实参
函数执行过程中形参有效,函数结束后
形参消失
*/
void neg(int value/*形参*/) {
value = 0 - value;
}
int main() {
int value = 4;
//value = 0 - value;
neg(value/*实参*/);
printf("结果是%d\n", value);
return 0;
}
隐式声明练习
*/
#include <stdio.h>
//int add(); 函数的隐式声明格式
int add(double, double); //显式函数声明可以避免错误,显示声明中可以省略参数的名称
int main() {
int shu = add(2, 3);
shu = add(shu, 4);
/*int shu = add(2.0f, 3.0f);
shu = add(5.0f, 4.0f);*/
printf("结果是%d\n", shu);
f();
return 0;
}
/*int add(int value_1, int value_2) {
return value_1 + value_2;
}*/
int add(double value_1, double value_2) {
return value_1 + value_2;
}
//与隐式声明格式不符,编译报警告
void f() {
}
/*
数组做参数的练习
*/
#include <stdio.h>
void neg(int value[]) {
value[0] = 0 - value[0];
}
int main() {
int value[1] = {5};
neg(value);
printf("结果是%d\n", value[0]);
return 0;
}
/*
用函数交换数组中变量树枝
*/
#include <stdio.h>
void swap(int value[]) {
int value_1 = value[0];
value[0] = value[1];
value[1] = value_1;
}
int main() {
int value[2] = {3, 7};
swap(value);
printf("%d %d\n", value[0], value[1]);
return 0;
}
/*
打印数组中变量的练习
*/
#include <stdio.h>
void show(int value[], int num) {
int loop = 0;
for (loop = 0; loop <= (num - 1); loop++) {
printf("%d ", value[loop]);
}
printf("\n");
}
int main() {
int value_1[3] = {1, 2, 3};
int value_2[5] = {4, 5, 6, 7, 8};
show(value_1, 3);
show(value_2, 5);
return 0;
}
/*
随机数练习
*/
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
int main() {
srand(time(0));
printf("%d\n", rand());
printf("%d\n", rand());
printf("%d\n", rand());
return 0;
}