数组:
1、定义数组时,数组大小不能用变量定义,C语言并不支持,即使是const修饰的变量也不行,我们要杜绝这种定义方式。
错误示例:
int size = 20;
int c[size];
2、数组越界问题,数组不能越界,数组的元素可以通过下标访问,越界在语法层面是合法的,但我们不能这样使用,可能会导致访问非法内存,引起程序崩溃。
错误示例:
int a[10];
a[10] = 1;
3、二维数组的结构,二维数组本质上是一个一维数组,它每个元素都是一个一维数组。它在内存中是连续存储的,并不是形象上的矩阵。
图示:
int a[3][4] = {{1,2,3,4},{1,3,5,7},{2,3,5,6}};
4、scanf()、gets()、fgets()读取字符串时都不需要对数组名加&,但scanf() 无法读取空格和换行符,gets()无法读取换行符,前两者都可能导致数组的越界,fgets()可以读取空格与换行符,且不会导致数组越界。
用法示例:
char str1[100];
char str2[100];
char str3[100];
scanf ("%s",str1);
gets (str2);
fgets (str3,100,stdin);
5、不可以给数组整个赋值,这是不合法的,要么定义时初始化,要么对一个一个单独赋值。
错误示例:
char str[100];
str = "hello";
6、
int a[5];
&a是数组的地址,要和数组首个元素的地址区分开。
a、&a[0]、&a在数值上相等,但&a意义不同。a+1或&a[0]+1跳过4个字节(跳过一个元素),&a+1跳过20个字节(跳过整个数组)。
7、数组指针与数组名的差异
(1)
int a[5];
int *p = a;
sizeof(a)的值为20;sizeof(p)的值为4。
数组指针不能代替数组名求数组长度。
(2)
int a[5] = {1,2,3,4,5};
int *p = a;
a++是无效的,p++可以使用。
数组名是一个常量,不能被改变。
8、定义指针时必须给它初始化,可以指向NULL,否则会成为野指针。
错误示例:
char *p;
9、指针可以指向一个字符串,但不可以改变它的值,字符串是一个常量,只能使用,代表该字符串首元素的地址,代表的是char *类型的指针。
错误示例:
char *p = "hello";
*p = 'w';
10、需要区分指针数组和数组指针。指针数组是一个数组,每个元素都是一个指针;数组指针是一个指针,指向一个数组。
指针数组可以定义为int *a[10],二维数组指针可以定义为int (*p)[10],指向int a[3][10]。