本节知识点概要:
一.一维数组
必备知识:
数组为构造数据类型之一,有一定顺序的数据类型相同的变量集合,通过下标进行访问。
一般形式:
存储类型 数据类型 数组名【表达式】
int a[6] //编译时分配连续内存
数组名是地址常量。(不能修改)
c语言不对数组做越界检查(要格外注意)
printf(“%p\n”,&a[0]); //取地址用%p,用取址符得到地址
printf(“%p\n”,a); //取地址用%p,用取址符得到地址
数组赋初值
int a[5]={1,2,3,4,5};//不初始化,元素值随机。//auto的存储类型
也可以部分赋初值
int a[4]={1,2,3}; 等价于 a[0]=1;a[1]=2;a[3]=3;a[4]=0;
编译器可以根据初始值个数,确认数组维数
int a[]={1,2,3};
元素个数可以这么求:
n=sizeof(a) / sizeof(int);
练习:冒泡排序法(对相邻的元素进行两两比较,顺序相反则进行交换,这样,每一趟会将最小或最大的元素“浮”到顶端,最终达到完全有序)
简单排序法(冒泡排序的优化,每一趟确定最小元素的时候会通过不断地比较交换来使得首位置为当前最小,交换是个比较耗时的操作。其实我们很容易发现,在还未完全确定当前最小元素之前,这些交换都是无意义的。我们可以通过设置一个变量min,每一次比较仅存储较小元素的数组下标,当轮循环结束之后,那这个变量存储的就是当前最小元素的下标,此时再执行交换操作即可)
二.二维数组
1.
声明时列数不能省略,行数可以。
数组名代表数组起始地址(常量)
数组名sizeof,为数组的总空间
int a[3][4] //三行四列
按行序优先进行存储(例:a[0][0], a[0][1], a[1][0],a[1][1]
验证数组的内存存储地址 一维数组名大小是多少,怎么操作。
printf(“%p”,&a[i][j]); //打印地址
数组名sizeof,为数组的总空间
printf("%p %d\n",a,sizeof(a));
a[3][4] 可以抽象出三个一维数组名a[0],a[1],a[2],具有一维数组名特性
printf("%p %d\n",a[1],sizeof(a[1])); //0xxx, 12
2.二.维元素初始化
分行初始化
按元素排列顺序初始化
int a[2][3]={{123},{456}}
还可以这么定义:int a[][3]={{12},{4}} // 1,2,0,4,0,0 //行可省,元素省略的补0
int a[2][3] = {{1,2}}; //1,2,0,0,0,0
行号可省略,列数不能省略
如何计算数组的行数(行号省略了)?
三.多维数组
一维线性 二维平面 三位空间立体
四.字符数组
字符数组(字符型数组),字符串
char ch[2][3];
初始化方式
1.逐个字符赋值 char ch[5]={‘H’,’L’};//部分赋值,剩余补’\0’(0)小技巧可用补充\0表示是字符串
2.用字符串常量char ch[6]=”Hello”;
计算数组个数 n=sizeof(arr) / sizeof(char);
char arr[] = {‘a’,’b’,’c’}
printf %s打印字符串,打印单个字符赋值的数组异常,不看见\0不算结束。
字符串结束标志:‘\0’
使用数组灵活存储字符串
char [][7]={“apple”,”pear”,”peach”};
二维数组如何计算行,列?
fruit[][10];
n=sizeof(fruit) /sizeof(fruit[0]);
m =sizeof(fruit[0])/sizeof(char);
输入一个字符串,然后逆序输出。
如何获得一个用户字符串?
逆序可以改变数据存储,改变打印方式等。
gets获取数据时,注意定义的数组长度,防止越界。
如何求用户输入字符串长度?
l=strlen(arr)//<string.h>
如何字符串反转存储
从两头开始线中间集合,交换数据,直到相等。
n=strlen(arr);
i=0;
j=n-1;
while(i<j)
{
ch =arr[i]
arr[i]=arr[j];
arr[j]=ch;
i++;
j--;
}
五.字符串函数
函数的学习及使用,注意输入参数格式,返回类型
和函数本身的一些注意事项。
字符串函数 头文件<string.h>
常用的几个字符串函数
strlen //求字符串长度,不包括‘\0’
strcpy //字符串拷贝
strcat //字符串连接
strcmp //字符串比较
1.
格式:strlen(字符数组)
返回的长度,不包括‘\0’
\xhh 表示十六进制数
\ddd 表示八进制数
例求一下字符串的strlen(s)的值
char s[10]={‘A’,‘\0’,‘B’,‘C’,‘D’};//1
char s[]= “\t\v\\\0will\n”;//3
char s[]=”\x69\141\n”//3
char s[10]={‘A’,‘0’,‘B’,‘\0’,‘D’};//3
解释:
- ‘\0’为结束符,所以第一个长度为1.
2.\t(通过看ascii可以发现这些为特殊符号,\为转意符)“\\”代表反斜线字符
3.十六进制+八进制+\0 长度为3.
4.0和\0不是一回事,ASCII值不一样
char s[10]={‘A’,‘0’,‘B’,‘\0’,‘D’};
strlen(s); //3
sizeof(s)/;//10
char s[] =”hello”;
strlen(s); //5
sizeof(s);//6(双引号隐藏\0)
2.
strcpy(字符数组1,字符串2)
注:字符数组1必须足够大
拷贝时‘\0’一同拷贝。
本质就是相当于将字符串一个字符一个字符赋值给另外一个数组
puts字符串输出函数输出要以\0结束。
3.
strcat(字符数组1,字符数组2) //2连接到1后面
注:
两个必须是字符串
字符数组1必须够大
连接之前两串均以‘\0’结束,连接后,串1的\0取消,新串最后加’\0’;
这个函数检测的时候是以’\0’来判断结束的,如果不是字符串,它就不知道从哪停止,就会导致出错,直到在内存中检测到’\0’才截止。
例如:
char dest[100]={‘a’,‘b’,‘c’};
char src[]=”com”;
strcat(dest,src);
puts(dest);
你会发现程序打印为abccomcom //恰好他们内存连续,前串没有\0检测到com的\0后截止,所以为这个结果,此操作错误。
4.
strcmp(字符串1,字符串2);
对两串从左到右依次比较(ASCII),直到遇到不同字符,或‘\0’截止
若字符串1<字符串2,返回-1
若字符串1>字符串2 返回+1
相等,返回0
5.
strncpy(p,p1,n)//复制指定长度字符串
strncat(p,p1,n)//附加指定长度的字符串
strncmp(p,p1,n)//比较指定长度的字符串
strcasecmp(p,p1,n)//忽略大小写比较字符串
strchr(p,c)//在字符串中查找指定字符
strstr(p,p1)//查找字符串
char dest[]=”hehe”
char src[]=”.com.cn”
strncpy(src,dest,4);//hehe.cn,小技巧可以通过这个来进行字符串替换,完成组包
strchr(p,c)
返回值为,字符在字符串中的地址。//可以通过起始地址与返回地址做操作,得到在字符串中的位置(数组下标)。注:%P 数组名就为起始地址
strrchr(p,c) //反向查找
strstr(p,p1) //返回一个子串的地址
6.
isalpha()检查是否为字母字符
isupper()检查是否为大写字母字符
islower()检查是否为小写字母字符
isdigit()检查是否为数字形式字符(ascII)
E0F(ctrl D,scanf用户输入时结束符)
int ch;
while((ch =getchar())!=EOF)//判断用户输入不为ctrl D操作
{
if(isalpha(ch))
{
}
}
ch = tolower(ch);//将大写字母转为小写,返回值为小写字母