感觉现在的博客并没有什么实质性的意义,只是总结一些之前的学到的知识,做下的笔记。比如今天,就是来记下之前学习到的数组的一些概念,就当作复习吧。
1、)首先,数组的概念:数组是具有相同类型的元素的集合。它的大小不能用变量来定义,比如
int size = 20;
int c[size];
这样的数组定义就是不合法的,虽然在linux红帽下编译运行并没有错误。不过,当你需要从终端输入这个数组的长度时,你可以用const。
2、)数组的初始化,就是简单用{}往里面赋值,可以全部初始化,也可以只赋值一部分其余会自动补0;另外,二维数组的初始化与一维数组相同,只是再用一个{}分隔第一层的各个元素,所以其实二维数组也就可以看成是一个一维数组,只是它其中存放的值是也是一个一维数组罢了。对于二维数组的赋值,就麻烦一些。在遍历时,需要一个两层循环,外层循环遍历行,内层循环控制每一行中的值。打印可以在第一层循环的末尾加上一个换行操作,这样就可以分行打印了。这里加上一个打印每一列的和的小程序:
int a [3][5];
int i,j;
for (j = 0; j < 5; j++)
{
int sum = 0;
for(i = 0; i < 3; i++)
sum += a[i][j];
printf("%8d",sum);
printf("\n");
}
3、)字符数组:这是一个相对复杂的数组类型。首先,初始化,可以不加{},直接用“”赋值。其次,输入输出,用puts和printf都可以逐个扫描输出,直到遇到“\0”,printf用%s来输出(想要输出"\0"这个字符可以在它前面加上一个"\")。输入时scanf用%s输入,以空格或回车结束。不过,这样的输入方式很危险,如果输入参数长度比scanf中定义的数组长度还要长,则会缓冲区溢出,就是我们通常说的越界,会导致程序奔溃。
这里提几个常用的字符数组的操作:
1、字符串逆置:可以int min和max,分别指向数组的开头和末尾,while(min<max)则交换数组元素,并使min自增, max自减。
2、中文字符串逆置:这里需要注意的是,一个中文字符占3个字节(utf-8编码下)。需要同时交换3个字符,并min+=3, max-=3。
3、统计中英文字符串长度:又是一个小知识点,中文字符的地址是负数,小于0的,运用这一特性,我们可以遇到中文字 符时,len+=3即可。
4、去掉字符串右边的空格:字符串从后往前比较,找到第一个非空格的字符,将其后面的字符置为0。
5、去掉字符串左边的空格:当然,你可以找到第一个非空格的字符开始输出即可,但这里要介绍另外一种方法:得到字符 串前面的空格数,将非空格的字符前移这么多。这种方法不能忘了在字符串结尾加上结束标志符"\0"。
这里贴上一个程序,实现将“you are from shanghai”这句话逆序输出,但单词不逆序。这个程序的思路是,先将整个字符串逆序,再对每个单词逆序。需要注意为什么循环结束后还要进行一次逆序。
#include <stdio.h>
#include <string.h>
int main()
{
char a[] = "you are from shanghai";
char *p1 = a;
char *p2 = a + strlen(a) - 1;
char *p3 = NULL;
char tmp;
while (p1 < p2)
{
tmp = *p1;
*(p1++) = *p2;
*(p2--) = tmp;
}
p1 = a;
p2 = a;
while (*p2)
{
if (*p2 == ' ')
{
p3 = p2 - 1;
while (p1 < p3)
{
tmp = *p1;
*(p1++) = *p3;
*(p3--) = tmp;
}
p1 = p2 + 1;
}
p2++;
}
p3 = p2 - 1;
while (p1 < p3)
{
tmp = *p1;
*(p1++) = *p3;
*(p3--) = tmp;
}
puts(a);
return 0;
}