1、int二维数组初始化方式
int A[2][3] = { 1, 2, 3, 4, 5, 6};
对应顺序是
A[0][0]=1; A[0][1]=2; A[0][2]=3;
A[1][0]=4; A[1][1]=5; A[1][2]=6;
int A[2][3] = { 1, 2, 3, 4};
其中剩余的未赋值元素编译器自动初始化为0。
数组元素值对应顺序是
A[0][0]=1; A[0][1]=2; A[0][2]=3;
A[1][0]=4; A[1][1]=0; A[1][2]=0;
int A[2][3] = { { 1, 2, 3}, { 4}};
其中剩余的未赋值元素编译器自动初始化为0。
数组元素值对应顺序是
A[0][0]=1; A[0][1]=2; A[0][2]=3;
A[1][0]=4; A[1][1]=0; A[1][2]=0;
int A[][3] = { { 1, 2, 3}, { 4}};
省略行数,切记列数无法省略。其中剩余的未赋值元素编译器自动初始化为0。
数组元素值对应顺序是
A[0][0]=1; A[0][1]=2; A[0][2]=3;
A[1][0]=4; A[1][1]=0; A[1][2]=0;
2、char二维数组初始化方式
char A[2][3] = { 'a', 'b', 'c', 'd'};
其中未初始化的部分,编译器自动初始为'0'(NULL)。
printf("%s\n", A);
输出"abcd"
char A[2][3] = { { 'a'}, { 'd', 'e', 'f'}};
其中未初始化的部分,编译器自动初始为'0'(NULL)。
printf("%s\n", A);
输出"a",输出第一行时遇到结束符导致停止输出。
char A[2][3] = { { 'a', 'b', 'c'}, { 'd', 'e', 'f'}};
printf("%s\n", A);
输出"abcdef"
char A[][3] = { { 'a', 'b'}, { 'd'}};
省略行数,切记列数无法省略。
printf("%s\n", A);
输出"ab"
3、二维数组作为形参
想要在函数中传递一个一维数组作为参数,必须以下面三种方式来声明函数形式参数,这三种声明方式的结果是一样的,因为每种方式都会告诉编译器将要接收一个整型指针。
方式1,形式参数是一个指针
void myFunction1(int *param)
方式2,形式参数是一个已定义大小的数组
void myFunction2(int param[10])
方式3,形式参数是一个未定义大小的数组
void myFunction3(int param[])
int param[3] = { 0};
myFunction1(param);
myFunction2(param);
myFunction3(param);
int *param2;
myFunction1(param2);
myFunction2(param2);
myFunction3(param2);
就函数而言,一维数组作为形参时的长度是无关紧要的,因为 C 不会对形式参数执行边界检查。
同样的方式也可以传递一个多维数组作为形式参数?
方式1,形式参数是一个指针
void myFunction1(int **param)
方式2,形式参数是一个已定义大小的数组
void myFunction2(int param[2][10])
void myFunction2(int param[2][3])
方式3,形式参数是一个未定义一维宽度的数组
void myFunction3(int param[][3])
方式4
void myFunction4(int (*a)[3])
方式5
void myFunction5(int *a[3])
int param[2][3] = { 0};
myFunction1(param);
错误,[Error] cannot convert 'int (*)[3]' to 'int**' for argument '1' to 'void myFunction(int**)'
即int param[2][3]中param其实是"int (*)[3]"类型,不是"int**"类型,这两者不能混用
myFunction2(param);
二维宽度为10的错误,[Error] cannot convert 'int (*)[3]' to 'int (*)[10]' for argument '1' to 'void myFunction2(int (*)[10])',可以理解为"int (*)[3]"和"int (*)[10]"不是一种类型
为3的正确,二维数组作为函数形参会进行边界检查,所以第二个维度必须一致
myFunction3(param);
myFunction4(param);
myFunction5(param);
错误,注意如果是int *a[3],因为"[]"的优先级比"*"高,所以会导致该形参被编译器识别为"int**"
int **param2 = (int **)malloc(sizeof(int *) * 2);
myFunction1(param);
myFunction2(param);
myFunction3(param);
myFunction4(param);
myFunction5(param);
只有myFunction1和myFunction5正确,其余的形参都不是"int**"类型
注意myFunction5中的"a[3]"类似一维数组作形参的效果,不管数组大小都被当作"int *"
4、综合例子
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
// 二维数组作为函数的形式参数会进行边界检查,所以第二个维度必须为5
void example(char acHello[][5])
{
printf("%d\n", sizeof(char (*)[5])); // 输出8
printf("%d\n", sizeof(acHello)); // 输出8,为sizeof(char (*)[5]),指针为8
printf("%d\n", strlen(acHello[0])); // 输出9,因为acHello[0]并没有'\0'结束符,所以是acHello的总长度
acHello[0][0] = 'c';
return;
}
int main(void)
{
char str[] = "\\\\";
printf("%d\n", sizeof(str)); // 输出3,\\其实是转义,所以2个'\'加字符串自带的1个'\0'是3
printf("%d\n", strlen(str)); // 输出2,即2个'\'
char *str2 = "\\\\";
printf("%d\n", sizeof(str2)); // 输出8,str是char*类型的指针,指针在64位下都是8
printf("%d\n\n", strlen(str2)); // 输出2,即2个'\'
char str3[2][3] = { "qw", "er"};
printf("%c ", *(*(str3 + 0) + 0));
printf("%c ", *(*(str3 + 0) + 1));
printf("%c ", *(*(str3 + 1) + 0));
printf("%c\n", *(*(str3 + 1) + 1));
printf("%c ", *(str3[0] + 0));
printf("%c ", *(str3[0] + 1));
printf("%c ", *(str3[1] + 0));
printf("%c\n", *(str3[1] + 1));
printf("%c ", str3[0][0]);
printf("%c ", str3[0][1]);
printf("%c ", str3[1][0]);
printf("%c\n\n", str3[1][1]);
// *(str3 + 0)等效于str3[0],*(*(str3 + 0) + 0)等效于str3[0][0]
char *szStr = "abcde";
printf("%c\n", szStr[0]); // 输出a
printf("%llu\n", szStr); // 输出4210713,该值为"abcde"这个常串中字符a所在的地址
szStr += 2;
printf("%c\n", szStr[0]); // 输出c
printf("%llu\n\n", szStr); // 输出4210715,该值为"abcde"这个常串中字符c所在的地址
char dqq[][10] = { { 'h', 'e', 'l', 'l', 'o'}, { 'q', 'w', 'e'}};
printf("%s\n", dqq); // 输出hello,因为第一维多的部分被自动初始化为'\0',所以输出的时候截断了
printf("%s\n", dqq[1]); // 将第二维输出,所以是输出qwe
printf("%c\n\n", dqq[1][0]); // 输出q
char acHello[][5] = { { 'h', 'e', 'l', 'l', 'o'}, { 'h', 'e', 'l', 'l'}};
example(acHello);
printf("%s\n\n", acHello); // 输出cellohell,由于是传的指针,所以第一个字符被修改为c
return 0;
}