数组用于存储一系列具有相同数据类型的变量。数组内的元素具有连续的内存位置。
一维数组的声明
声明一个数组时,必须要指明数组的数据类型type, 数组的长度
。长度需为大于0的整数, 数组的长度用中括号包裹。
代码语法为:
type 数组名[数组的长度,即元素个数];
一维数组的初始化
初始化一维数组,若需初始化的数组已事先声明过,则直接将用大括号包裹的数组元素赋值给该数组。若事先并未声明,则在初始化是需要指明数组的数据类型。声明与初始化数组同时进行时,方括号内的数组长度可忽略,直接默认为初始化的数组元素的个数。如 int a[] = {0,0,0,3, 0, 5,0,0}.
代码语法为:
type 数组名[数组长度] = {元素1, 元素2, 元素3,…元素n};
若为稀疏数组且需要经常性更新数组元素,即数组的长度可能不能完全确定,如a[] = {0,0,0,3, 0, 5,0,0},后期还需要添加元素,可写为:
a[] = {[3]=3, [5] = 5}
遍历时,数组的长度可写为sizeof(a)/sizeof(a[0])
即
for(int i = 0; i < sizeof(a)/sizeof(a[0]);i++){
printf("%d", a[i]);
}
【注】
一维数组的索引
索引值从0即基索引至数组长度减1。数组中的元素可以通过数组名与索引值来访问。
【代码实例】
#include
int main ()
{
int n[ 10 ]; /* n 是一个包含 10 个整数的数组 */
int i,j;
/* 初始化数组元素 */
for ( i = 0; i < 10; i++ )
{
n[ i ] = i + 100; /* 设置元素 i 为 i + 100 */
}
/* 输出数组中每个元素的值 */
for (j = 0; j < 10; j++ )
{
printf("Element[%d] = %d\n", j, n[j] );
}
return 0;
}
多维数组的声明同一维数组一样也需要指明数据类型,每一个维度上的长度也需要用中括号来包裹说明。是几维数组就需要几个中括号。代码语法为:
type 多维数组名[size1][size2][size3]…[size n];
多维数组中最简单的形式是二维数组,本质上是一个元素为一维数组的列表。其声明与初始化规则同一维数组,代码语法分别为:
type 数组名[行数][列数];
type 数组名[行数][列数] = {{第一行的一维数组元素},{第二行的一维数组元素},…{第n行的一维数组元素}};
二维数组的索引也需要从两个维度来看,行列索引分别都是从基索引0至行数减1与列数减1.
【代码实例】
#include
int main ()
{
/* 一个带有 5 行 2 列的数组 */
int a[5][2] = { {0,0}, {1,2}, {2,4}, {3,6},{4,8}};
int i, j;
/* 输出数组中每个元素的值 */
for ( i = 0; i < 5; i++ )
{
for ( j = 0; j < 2; j++ )
{
printf("a[%d][%d] = %d\n", i,j, a[i][j] );
}
}
return 0;
}
函数参数表中的数组实际为指针,所以无法得到该数组中元素的个数。sizeof(数组名)==sizeof(数据类型*)
,同时指针可以用数组的运算符[]
进行运算。如
传入函数的数组成了什么? 如如下代码段
int isPrime(int x, int knownPrimes[], int numberOfKnownPrimes)
{
int ret =1;
int i;
for(i=0; i
数组变量为特殊的指针
数组变量本身表达地址
,所以定义指向数组的指针时无需用&
取地址,a==&a[0]
如int a[10]; int *p=a;
但是数组的单元表达的是变量,需要用&
取地址。*a=25
const
的指针,所以不能被赋值,所以数组变量之间不能相互赋值。即int a[]
等价于int * const a
在C语言中,字符串实际上是使用空字符\0
结尾的一维字符数组
。\0
是用于标记字符串的结束。
char 字符串名[字符的个数+1]={'英文字符1','英文字符2',...,'英文字符n','\0'};
例: char logo[9] = {‘h’,‘h’,‘x’,‘x’,‘t’,‘t’,‘x’,‘s’,‘\0’};
char 字符串名[字符的个数+1]="字符串的内容";
例: char logo[] = “hhxxttxs”;
【注】:1,2两种初始化方式中,中括号内的内容都可省略。
#include
int main(){
char list[] = {'h','h','x','x','t','t','x','s','\0'};
for(int i = 0; i < 9;i++){
printf("%c ", list[i]);
}
return 0;
}
#include
int main(){
char list[] = {'h','h','x','x','t','t','x','s','\0'};
printf("%s",list);
return 0;
}
函数声明:
int putchar(int c)
;
把一个无符号字符写入到标准输出中,如发生错误则返回EOF(-1)(end of fail)表示写失败。
与printf()函数的区别:参考文献
1)printf()为发送格式化的输出到标准输出int printf(const char *format, ...)
,可输出各种类型的数据;而putchar()是把一个无符号字符写入到标准输出中,只能输出单个字符。
2)printf()的返回值是正常输出的参数的数量,而putchar()的返回值则是是否正常输出。
3)printf()的时间复杂度是 O ( n l o g ( n ) ) O(nlog(n)) O(nlog(n)), 而putchar()的复杂度为 O ( 1 ) O(1) O(1),输出句子也只有 O ( n ) O(n) O(n)。
4)printf()每执行一次解析一次格式串,而putchar()是编译时尽量优化。
函数声明:
int getchar(void)
从标准输入读入一个无符号字符,该函数以无符号char强制转换为int的形式返回读取的字符,如果到达文件末尾或发生读入错误,则返回EOF(-1)。
与scanf()的区别:参考文献
1)scanf()为格式化输入函数int scanf(const char *format, ...)
,可输入各种类型的数据。而getchar()是键盘输入函数,其功能是从键盘上输入一个字符。
2)scanf()函数在读取数字时会跳过空格、制表符合换行符;getchar()只能输入字符型,输入时遇到回车键才从缓冲区依次提取字符。
3)scanf()以空格、Enter、Tab结束一次输入,不接受空格符
,不会舍弃最后的回车符(即回车符会残留在缓冲区中);getchar()以Enter结束输入,接受空格符
,会舍弃最后的回车符。
【代码演示】
#include
int main(int argc, char const *argv[]){
int ch;
while((ch = getchar())!=EOF){
putchar(ch);
}
return 0;
}
需包含头文件string.h
的字符串库函数
1)strlen()函数
。计算字符串的长度。与sizeof()不同的是该函数返回的字符串长度不包含结束字符。
函数声明: strlen(const char *s);
【代码演示】
/*自写strlen函数:mylen*/
#include
#include
int mylen(const char* s){
//数组写法------------------------------------------
/*
int index = 0;
while(s[index] != '\0'){
index ++;
}
return index;
-------------------------------------------------------------------*/
//指针写法---------------------------------------------------------------
char* t = s;
while(*t!= '\0'){
t++;
}
return (t - s);
}
//------------------------------------------------------------------------------------------
int main(int argc, char const *argv[]){
char str[] = "This is a series of codes";
printf("The number of codes of str is %d\n", mylen(str));
return 0;
}
2)strcmp()函数
。按照ASCII码逐一比较两个字符串的大小关系。
函数声明: int strcmp(char *a, char *b)
。
该函数会对字符串a和b的每个字符,按照ASCII 码值逐一比较,如果二者完全相同返回0;如果字符串a的ASCII码值首先出现较大者,会返回1,否则返回-1。
【代码演示】
//strcmp()函数
/*函数说明
int strcmp(const char *s1, const char *s2);
0: s1==s2
1: s1>s2
-1: s1
#include
/*自写strlen函数:mycmp*/
int mycmp(char *str1, char *str2){
//---------------------------------------------------------------------------
/*数组写法*/
int index = 0;
while( str1[index]==str2[index] && str1[index] != '\0'){
index++;
}
int res = -1;
if(str1[index]==str2[index]){
res = 0;
}else{
res = (str1[index] - str2[index])/(abs(str1[index] - str2[index]));
}
return res;
}
/*指针写法*/
/*
while(*str1==*str2 && *str1 != '\0'){
str1++;
str2++;
}
int res = -1;
if(*str1==*str2){
res = 0;
}else{
res = (*str1 - *str2)/(abs(*str1 - *str2));
}
return res;
}*/
int main(void){
char str_1[] = "abc";
char str_2[] = "ABC";
printf("%d\n", mycmp(str_1,str_2));
if(strcmp(str_1,str_2)==0){
printf("str_1 is equal to str_2\n");
}
return 0;
}
3)strcpy()函数
。strcpy(字符串1,字符串2)复制字符串2到字符串1中。返回的是一个字符指针, 字符串2会将字符串1覆盖。
函数声明: char* strcpy(char *restrict dst, const char *restrict src).
这里 restrict
表明dst与src两个指针所指向的内存空间不重叠。
需要注意的是字符串在复制的过程中遇到\0
也会进行复制,因此若源字符串(字符串2)的字符串长度小于目的字符串(字符串1)的长度的话,使用strcpy函数后新的字符串长度同源字符串一致。
【代码演示】
#include
#include
int mycpy(char *str1, const char *str2){//用于复制一个字符串
//----------------------------------------------------------------------------------
/*数组写法*/
int index = 0;
while( str2[index]!= '\0'){
str1[index]=str2[index];
index++;
}
str1[index] = '\0';
return str1;
}
//-----------------------------------------------------------------------------------------
/*指针写法*/
/*
char* res = str1;
while(*str2 != '\0'){
*str1 = *str2;
str1++;
str2++;
//*str1++=*str2++;
}
*str1 = '\0';
return *res;
*/
//-------------------------------------------------------------------------------------------------
int main(int argc, char const *argv[]){
char str1[] = "abcdefg";
char str2[] = "ABCD";
char str3[] = "abcdefg";
mycpy(str1, str2);
printf("str2 拷贝到 str1 的结果为 %s\n", str1);//(1)长度短的字符串拷贝到长度长的字符串
mycpy(str2, str3);
printf("str3 拷贝到 str2 的结果为 %s\n", str2);//(2)长度长的字符串拷贝到长度短的字符串
return 0;
}
/*
输出结果为:
str2 拷贝到 str1 的结果为 ABCD//(1)
str3 拷贝到 str2 的结果为 abcdefg//(2)
*/
4)strncpy()函数
。strncpy(字符串1,字符串2,个数n)复制字符串2中的n个字符到字符串1中。返回的是一个字符指针, 字符串2会将字符串1覆盖。
函数声明: char *strncpy(char *dest, const char *src, size_t n)
【代码演示】
//strncpy()函数
#include
#include
int myncpy(char *str1, const char *str2, int n){//用于复制一个字符串
//----------------------------------------------------------------------------------
/*数组写法*/
/*
int index = 0;
//while( str2[index]!= '\0'){
while( index < n){
str1[index]=str2[index];
index++;
}
str1[index] = '\0';
return str1;
}*/
//-----------------------------------------------------------------------------------------
/*指针写法*/
char* res = str1;
while(str1 - res < n){
*str1 = *str2;
str1++;
str2++;
//*str1++=*str2++;
}
*str1 = '\0';
return *res;
}
//-------------------------------------------------------------------------------------------------
int main(int argc, char const *argv[]){
char str1[] = "abcdefg";
char str2[] = "ABCD";
char str3[] = "abcdefg";
myncpy(str1, str2, 2);
printf("str2 拷贝到 str1 的结果为 %s\n", str1);
myncpy(str2, str3, 3);
printf("str3 拷贝到 str2 的结果为 %s\n", str2);
return 0;
}
5)strcat()函数
。strat(字符串1,字符串2)将字符串2中的字符连接到字符串1中。返回的是一个字符指针。
函数声明: char *strcat(char *dest, const char *src)
【代码演示】
//strcat()函数
#include
#include
int mycat(char *str1, const char *str2){//用于复制一个字符串
//----------------------------------------------------------------------------------
/*数组写法*/
int lenstr1 = strlen(str1);
int index = 0, lenstr2 = strlen(str2);
//while( str2[index]!= '\0'){
while( index < lenstr2){
str1[lenstr1+index]=str2[index];
index++;
}
//str1[lenstr1+index] = '\0';
str1[lenstr1+index]=str2[index];
return str1;
}
//-----------------------------------------------------------------------------------------
//-----------------------------------------------------------------------------------------
/*指针写法*/
/*
int lenstr1 = strlen(str1);
while(*str2!='\0'){
*(str1 + lenstr1) = *str2;
lenstr1++;
str2++;
//*str1++=*str2++;
}
*(str1 + lenstr1) = *str2;
return *str1;
}*/
//-------------------------------------------------------------------------------------------------
int main(){
char str1[] = "abcdefg";
char str2[] = "ABCD";
mycat(str1, str2);
printf("str2 拼接到 str1 后的结果为: |%s|\n", str1);
return 0;
}
6)strchr()函数
。strchr(字符串1,字符串2)将字符串2中的字符连接到字符串1中。返回的是一个字符指针。
**函数声明: ** char *strchr(const char *str, int c)
【代码演示】
//mychr()
#include
#include
char *mychr(const char *str, int c){
while(*str){
if(*str==c){
return (void *)str;
break;
}
str++;
}
return NULL;
}
int main(){
char *str = "haohaoxuexi,tiantianxiangshang";
char c = 'u';
char *ret = NULL;//没有位置指定时好习惯是先指向空位置
char *res = NULL;
ret = strchr(str, c);
printf("使用库函数strchr的返回结果为%s\n", ret);
res = mychr(str,c);
printf("使用自定义函数mychr的返回结果为%s\n", res);
return 0;
}
7)strrchr()函数
。strrchr(字符串,字符)在参数 str 所指向的字符串中搜索最后一次出现字符 c(一个无符号字符)的位置。
**函数声明: ** char *strrchr(const char *str, int c)
【代码演示】
//mychrr()
#include
#include
char *mychrr(const char *str, int c){
int index= 0;
char *str2 = (char *)str;//保持数据类型的一致性
while(*str){
if(*str==c){
index = (str-str2);
}
str++;
}
if(index==0){
return NULL;
}else{
return (void *)(str2+index);
}
}
int main(){
char *str = "haohaoxuexi,tiantianxiangshang";
char c = 'n';
char *ret = NULL;//没有位置指定时好习惯是先指向空位置
char *res = NULL;
ret = strrchr(str, c);
printf("使用库函数strrchr的返回结果为%s\n", ret);
res = mychrr(str,c);
printf("使用自定义函数mychrr的返回结果为%s\n", res);
return 0;
}
8)strstr()函数
。strstr(字符串1,字符串2)在字符串1中查找第一次出现字符串2的位置,不包含终止符 ‘\0’。
**函数声明: ** char *strstr(const char *first, const char *second)
【代码演示】复制链接
//复制自https://blog.51cto.com/thinkerfans/1351064
#include
#include
char *mystrstr(const char*, const char*);
char *mystrstr(const char *src, const char *find){
if(NULL==src||NULL==find){
return NULL;
}
char *cp = (char *)src;
char *s1, *s2;
while(*cp){
s1 = cp;
s2 = (char *)find;
while(*s1 && *s2 &&(*s1 == *s2)){
s1++, s2++;
}
if(!*s2){
return cp;
}
cp++;
}
return NULL;
}
int main(){
char *src = "hello, china and hello, world";
char *find = ",";
char *re = mystrstr(src, find);
char *res = strstr(src, find);
if(re){
printf("%s\n", re);
}else{
printf("no find\n");
}
printf("%s\n", res);
return 0;
}
9)strcasestr()函数
。strcasestr(字符串1,字符串2)同strstr()函数功能一样,区别是strcasestr将大小写都用小写字符来匹配。在字符串1中查找第一次出现字符串2的位置,不包含终止符 ‘\0’。
**函数声明: ** char *strcasestr(const char *first, const char *second)
【代码演示】复制链接
//复制自https://blog.51cto.com/thinkerfans/1351698
#include
#include //tolower()函数头文件
#include
char * mystrcasestr(const char * ,const char *);
char * mystrcasestr(const char *src, const char *find){
if(NULL == src || NULL == find)
return NULL;
char *cp = (char *)src;
char *s1 , *s2;
while(*cp){
s1 = cp;
s2 = (char * )find;
while(*s2 && *s1 && !(tolower(*s1) - tolower(*s2)))
s1++,s2++;
if(!(*s2))
return cp;
cp++;
}
return NULL;
}
int main(){
char *src = "HeLlO, china and hello,world";
char *find = "hElLo,";
char *re = mystrcasestr(src,find);
if(re)
printf("%s\n",re);
else
printf("no find\n");
return 0;
}
10) tolower()函数
。tolower(int 字符)将大写字符转化为小写字符。头文件为#include
**函数声明: ** int tolower(int c);
//mytolower
//参考自 https://blog.51cto.com/thinkerfans/1351723
#include
#include
#include
int mytolower(int c){
if('A'<=c && 'Z'>=c)
return c-'A'+'a';
return c;
}
char mytolower2(char c){
if('A'<=c && 'Z'>=c)
return 'z'-('Z'-c);
return c;
}
int main(){
char s1[] = "3489 ASDFDF adfdf +-*/";
char s2[] = "3489 ASDFDF adfdf +-*/";
unsigned int i=0;
//int i=0;
for(;i < strlen(s1);i++){
s1[i] = mytolower2(s1[i]);
s2[i] = tolower(s2[i]);
}
printf("s1=%s\n",s1);
printf("s2=%s\n",s2);
return 0;
}
11) toupper
。toupper 字符)将小写字符转化为大写字符。头文件为#include
**函数声明: ** int upper(int c);
//mytoupper
//参考自 https://blog.51cto.com/thinkerfans/1351723
#include
#include
#include
int mytoupper(int c){
if('a'<=c && 'z'>=c)
return c-'a'+'A';
return c;
}
char mytoupper2(char c){
if('a'<=c && 'z'>=c)
return 'Z'-('z'-c);
return c;
}
int main(){
char s1[] = "3489 ASDFDF adfdf +-*/";
char s2[] = "3489 ASDFDF adfdf +-*/";
unsigned int i=0;
//int i=0;
for(;i < strlen(s1);i++){
s1[i] = mytoupper2(s1[i]);
s2[i] = toupper(s2[i]);
}
printf("s1=%s\n",s1);
printf("s2=%s\n",s2);
return 0;
}
由多个字符串构成的数组。
#include
int main(){
printf("请输入月份:");
int month;
scanf("%d",&month);
char *a[]={"January","February","March","April","May","Jane","July","August","September","Octobor","November","December"};
printf("%s\n", a[month-1]);
return 0;
}
1. http://www.jbox.dk/sanos/source/lib/string.c.html
2. http://www.rowleydownload.co.uk/maxq30/documentation/index.htm?http://www.rowleydownload.co.uk/maxq30/documentation/strcasestr.htm
3. http://www.jbox.dk/sanos/source/lib/ctype.c.html
https://blog.51cto.com/thinkerfans
C|菜鸟教程。链接
thinkerfans 博客。链接