二维数组定义
形式:int a[2][2] = {{1,2}, {3,4}} int a[][2] = {1,2,3,4} char s[][10] = {"hello", "world"}
注:第一个方括号[]内可以省略,编译器会自动排布,但是第二个不可以省略
与一维数组和字符型数组相同,不足时补0,超出则会越界访问,同样的,第一个元素为a[0][0]。
二维数组性质
与一维数组相同,二维数组依然保证了连续性单一性和有序性,在内存以行来按照一维数组的存储方式存储,所以对于二维数组,可以理解为几个一维数组,以a[3][4]为例,可以作为一个一维数组,里面存放三个元素,元素为三个含有四个元素的数组
通过一维数组我们可以知道,a<=>&a[0][0],而同样在二维数,a[0]<=>&a[0][0],虽然它们的指针相同,但是所表达的含义却不同,a表示的是这个数组的地址,a[0]表示第0行这一维数组的地址,a[0][0]表示的是二维数组第一个元素的地址,所以我们可以进行类似一维数组的操作,以及应用string系列函数,如下。
对数组边界元素求和
#include <stdio.h>
int main()
{
int a[][4] = {1,2,3,4,5,6,7,8,9,10,11};
int rows = sizeof(a) / sizeof(a[0]);
int cols = sizeof(a[0]) / sizeof(a[0][0]);
int sum = 0;
for(int i = 0; i < rows; ++i)
{
for(int j = 0; j < cols; ++j)
{
if(i == 0 || j == 0 || i == rows - 1 || j == cols - 1)
{
sum += a[i][j];
}
}
}
printf("%d\n", sum);
}
二维数组的逆序
整型数组
#include <stdio.h>
int main()
{
int a[][4] = {1,2,3,4,5,6,7,8,9};
int rows = sizeof(a) / sizeof(a[0]);
int cols = sizeof(a[0]) / sizeof(a[0][0]);
for(int i = 0; i < rows; ++i)
{
for(int j = 0; j < cols / 2; ++j)
{
int t = a[i][j];
a[i][j] = a[i][cols - 1 - j];
a[i][cols - 1 - j] = t;
}
}
for(int i = 0; i < rows; ++i)
{
for(int j = 0; j < cols; ++j)
{
printf("%3d", a[i][j]);
}
puts("");
}
}
字符型数组
#include <stdio.h>
#include <string.h>
int main()
{
char s[][10] = {"Hello", "World", "China"};
int rows = sizeof(s) / sizeof(s[0]);
for(int i = 0; i < rows / 2; ++i)
{
char t[100];
strcpy(t, s[i]);
strcpy(s[i],s[rows - 1 - i]);
strcpy(s[rows - 1 - i], t);
}
for(int j = 0;j < rows; ++j)
{
puts(s[j]);
}
}
查找(在此之前先排序)
#include <stdio.h>
#include <string.h>
int main()
{
char s[][6] = {"Hello", "World", "China"};
int rows = sizeof(s) / sizeof(s[0]);
int cols = sizeof(s[0]) / sizeof(s[0][0]);
for(int i = 0; i < rows - 1; ++i)
{
for(int j = i + 1; j < rows; ++j)
{
if(strcmp(s[i],s[j]) > 0)
{
char t[100];
strcpy(t, s[i]);
strcpy(s[i], s[j]);
strcpy(s[j], t);
}
}
}
char n[] = "Hello";
int begin = 0;
int end = rows - 1;
while(begin <= end)
{
int mid = (begin + end) / 2;
if(strcmp(s[mid], n) > 0)
{
end = mid - 1;
}
else if(strcmp(s[mid], n) < 0)
{
begin = mid + 1;
}
else
{
break;
}
}
if(begin <= end)
{
printf("Found\n");
}
else
{
printf("Not Found\n");
}
}
函数
函数定义
形式:
被调函数必须写在主函数之前
例:比较二者最大值函数
int max(int a, int b)
{
return a > b ? a : b
}
其中所有形参的类型不可省略,每个形参的类型独立给出,return用来返回函数值,不可返回数组 ,如果没有return,则会返回随机值,而之中有一个特殊类型——void。
例:打出******
void printstars(void)
{
printf("******");
}
该类型的函数可以不带return,而括号()内部的void表明不需要参数,而且可以省略,但是开头的void不可省略,否则会默认为int型,而在引用该函数的时候,括号()也是必须要有的
函数的调用
函数不能嵌套定义,但是函数函数可以嵌套调用,如下
比较三个数的最大值
#include <stdio.h>
int max2(int a, int b)
{
return a > b ? a : b;
}
int max3(int a, int b, int c)
{
return c > max2(a, b) ? c : max2(a, b);
}
int main()
{
printf("%d\n", max3(3, 1, 2));
}
void类型:求出一定年份区间的闰年
#include <stdio.h>
int runnian(int year)
{
if(year % 4 == 0 && year % 100 != 0 || year % 400 == 0)
{
return 1;
}
else
{
return 0;
}
}
void printfrun(int begin, int end)
{
for(int i = begin; i <= end; ++i)
{
if(runnian(i))
{
printf("%d\t", i);
}
}
}
int main()
{
printfrun(1900, 2000);
}