Linux嵌入式学习—c语言数组

一、一维数组

1.1一维数组的定义

定义一维数组,首先我们得先让计算机知道,哪些数据可以组成数组,一个数组中有多少元素(长度),以及数据 的类型。
所以在使用数组的时候,必须定义数组。

  1. 一维数组的一般形式

数据类型 数组名[元素个数];

例如:

a[5]

表示数组a中有10个元素,数组的元素长度为10。数组下标是从0开始的,a[0],a[1],a[2],a[3],a[4].没有数组元素a[5]

  1. int a[3+5];是正确的
  2. int a[n];是错误的,不允许对数组大小做动态定义
    以下是错误写法
int n;
scanf("%d",&n);//临时输入数组大小
int a[n];

在定义完数组后,内存会划出一片连续的空间,存放一个有5个元素的数组。

#include<stdio.h>
int main()
{
	int a[5];
	//计算数组大小
	//用sizeof(数组名) 
	printf("%d",sizeof(a));
	return 0; 
 } 

此时的空间大小为4*5=20字节
在这里插入图片描述

【1】对10个数组元素依次赋值为0,1,2,3,4,5,6,7,8,9,要求逆序输出。

  1. 十个元素且还是整型,所以我们确定数组的类型及长度int a[10];
  2. 依次赋值,可以考虑使用循环赋值,且赋值是从0依次增加1.
#include<stdio.h>
int main()
{
	int a[10];
	int i;
	for(i = 0;i<10;i++) //对数组赋值,下标是从0开始的
	a[i] = i;
	for(i = 0;i<10;i++)//打印数组
	printf("%d ",a[i]);
	return 0; 
 } 

1.2一维数组的初始化

  1. 定义数组就初始化。
int a[5] = {0,1,2,3,4};
//a[0]=0;a[1]=1;a[2]=2;a[3]=3;a[4]=4;
  1. 部分初始化,其余默认值为0。
int a[5]={0,1,2};
//a[0]=0;a[1]=1;a[2]=2;a[3]=0;a[4]=0
  1. 数组元素值全部为0。
int a[5]={0,0,0,0,0,0};
int a[5]={0};
  1. 对全部元素赋初值,可以不用写数组的长度。系统会根据数组中数据个数确定数组的长度
int a[]={1,2,3,4,5};

对于没有被初始化的数组,系统会自动初始化为0(数值型),‘\0’(字符型数组),NULL空指针(指针型数组)

1.3一维数组程序举例

用数组来处理Fibonacci数量问题

代码如下:

#include <stdio.h>
int main()
{
	int i;
	int f[20]={1,1};//对f[0]和f[1]赋初值为1,1 ,计算前20个数 
	
	for(i =2;i<20;i++)
		f[i]=f[i-2]+f[i-1];//当i=2时,f[2]=f[0]+f[1]; 
	for(i=0;i<20;i++)
	{
		if(i%5==0)//控制每行输出5个数 
		printf("\n");
		printf("%12d",f[i]);
	}
	printf("\n");
	return -1;
} 

运行结果

在这里插入图片描述

1.4冒泡排序(从小到大排列)

每次将相邻的数字进行比较,把小的调到前面。
n个数字,则要进行n-1趟比较。(总的)
第1次的比较需要进行n-1趟,
如果有第j次则要进行n-j趟

代码:

#include <stdio.h>
int main()
{
	int a[10];
	int i,j,t;
	printf("please 10 numbers:\n  ");
	for(i = 0;i<10;i++)//输入十个数据 
	scanf("%d",&a[i]);
	
	for(i=0;i<10-1;i++)//n个数进行n-1趟比较 
	{
		for(j=0;j<9-j;j++)//每一次的比较是n-j 
		if(a[i]>a[i+1])
		{
			t = a[i];
			a[i] = a[i+1];
			a[i+1] = t;
		}
	}
	 printf("the sort number:\n");
	 for(i=0;i<10;i++)
	 	printf("%d ",a[i]);
	printf("\n");
	return -1;
} 

结果:

在这里插入图片描述

二、二维数组

2.1二维数组的定义

二维数组常称为矩阵,常常用行和列来表示二维数组。
也常常称二维数组是由多个一维数组组成。
二维数组的定义:

数据类型 数组名[行][列]
元素个数=行x列
行序号和列序号都是从下标0开始的
例如:

int a[3][4];
//定义了一个类型为int的,3行4列的二维数组

其中每一行是由四个元素组成,每一行可以看成一维数组。

a[3][4];
a[0]a[1]a[2]是三个一维数组的名字
a[0]-----a[0][0]	a[0][1]	a[0][2]	a[0][3]
a[1]-----a[1][0]	a[1][1]	a[1][2]	a[1][3]
a[2]-----a[2][0]	a[2][1]	a[2][2]	a[2][3]

注意:二维数组的各个元素在内存中是连续存放的,是线性的

2.2二维数组的初始化

  1. 直接赋值
a[3][4]={{1,2,3,4},{5,6,7,8},{9,10,11,12}};
  1. 不用内花括号,元素在内存中的排列顺序对各元素赋初值
a[3][4]={1,2,3,4,5,6,7,8,9,11,10,12};
  1. 对部分元素赋初值,其余元素自动为0.
a[3][4]={{1},{5},{9};
1	0	0	0
5	0	0	0
9	0	0	0
a[3][4]={{1},{},{9}};//对第2行不赋初值
  1. 行数不能省略,列数可以省略。系统会根据元素个数和二维的长度计算一维的长度
a[3][4]={1,2,3,4,5,6,7,8,9,11,10,12};
等价于
a[][4]={1,2,3,4,5,6,7,8,9,11,10,12};

2.3二维数组程序举例

1.将一个二维数组行和列互换,存到另外一个二维数组中。

a = [ 1 2 3 4 5 6 ] a=\begin{bmatrix} 1 & 2&3 \\ 4& 5&6 \end{bmatrix} a=[142536]

转置
b = [ 1 4 2 5 3 6 ] b=\begin{bmatrix} 1 & 4 \\ 2& 5\\ 3&6 \end{bmatrix} b=123456

#include<stdio.h>
int main()
{
	int a[2][3] = {{1,2,3},{4,5,6}};
	int b[3][2],i,j;
	printf("arr a:\n");
	for(i = 0;i<2;i++){//a数组每一行的元素 
		for(j=0;j<3;j++){//每一行的元素 
			printf("%5d",a[i][j]);//输出a数组的元素 
			b[j][i] = a[i][j];//把a数组的值赋值为b数组 
		}
			printf("\n");
	}
	printf("arr b:\n");
		for(i=0;i<3;i++){//打印b数组 
			for(j=0;j<2;j++){
				printf("%5d",b[i][j]);
			}
			printf("\n");
		}
}

2.有一个3x4的矩阵,求出值最大的那个元素值以及下标

#include<stdio.h>
int main()
{
	int a[3][4]={{12,34,45,1},{54,90,32,9},{11,80,67,30}};
	int i,j;
	int max=a[0][0];//假设最大的是a[0][0]
	int nrow,colum;//记录行号和列号 
	
	for(i=0;i<3;i++){
		for(j=0;j<4;j++)
		if(a[i][j]>max){
			max=a[i][j];
			nrow=i;
			colum=j;
		}
	}
	printf("max=%d\nrow=%d\ncolum=%d\n",max,nrow,colum);
	return 0;
 } 

三、字符数组

字符型的数据是以ASCII码存放在存储单元的,一般只占一个字节。
字符串可以存放在字符串数组中。

3.1字符数组的定义和初始化

字符串数组和整数型数组的定义类似。

例如:char[10];
c[0]=‘I’;c[1]=’ ‘;c[2]=‘A’;c[3]=‘M’;c[4]=’ ';c[5]=‘H’;c[6]=‘A’;c[7]=‘P’;c[8]=‘P’;c[9]=‘Y’;

在这里插入图片描述

  1. 各个字符依次初始化
char a[10]={'I',' ','A','M',' ','A',' ','B','O','Y'};
  1. 字符个数小于字符数组的长度,其余元素自动定为空字符(‘\0’)
char a[10]={'H','A','P','P','Y'};

在这里插入图片描述

  1. 字符数组可以省略长度,根据初值个数确定长度。
char a[]={'I',' ','A','M',' ','A',' ','B','O','Y'};
  1. 字符串常量初始化数组,也可以省略花括号
char a[]={"Happy"};//长度不是为5,而是6
char a[]="Happy";
/*=====等价于====*/
char a[]={'H','a','p','p','y'.'\0'};

  1. 也可以定义二维字符数组的初始化,(菱形)
	char a[5][6]={{' ',' ','*'},{' ','*',' ',' ','*'},
			{'*',' ',' ',' ',' ','*'},{' ','*',' ',' ', '*'},{' ',' ','*'}};

1.输出字符串

#include<stdio.h>
int main()
{
	char a[10]={'I',' ','A','M',' ','A',' ','B','O','Y'};
	int i;
	for(i=0;i<10;i++)
	printf("%c",a[i]); //字符输出用%格式
	return 0;
 } 

2.输出一个菱形

#include<stdio.h>
int main()
{
	char a[5][6]={{' ',' ','*'},{' ','*',' ',' ','*'},
			{'*',' ',' ',' ',' ','*'},{' ','*',' ',' ', '*'},{' ',' ','*'}};	
			int i,j;
			for(i=0;i<5;i++){
				for(j=0;j<6;j++){
					printf("%c",a[i][j]);
				}
				printf("\n");
			}
	return 0;
 } 

3.1.2字符串和字符数组的结束标志

在实际的应用中,我们更关注的是字符串的有效长度,并非是数组的长度。
例如:字符串长度与字符串的长度相等。

char a[15]={'i',' ','a','m',' ','a',' ','s','t','u','d','e','n','t','.'};

如果改为charca[100],那字符串的有效长度是多少呢?
c语言规定以字符’\0’作为字符串的结束标志,遇到’\0’,表示字符串结束。
注意:
1.在用字符数组存储字符串常量的时候,系统会自动加一个’\0’作为结束符
2.'\0’的ASCII码为0的字符,是一个空操作符,表示什么也不用做,只提供一个可以辨别的标志。
例如:

printf("Hello world! \n");

系统自动在’\n’的后面加上‘\0’的标志。作为字符串结束的标志,用printf打印输出的时候,每打印一个字符就检查是否是’\0’,如果是就停止打印。

和之前的初始化字符串数组一样

char a[]={"Happy"};//长度不是为5,而是6
char a[]="Happy";//系统会自动分配一个'\0'
/*=====等价于====*/
char a[]={'H','a','p','p','y'.'\0'}; 

Happygirl字符串的存储情况:

在这里插入图片描述
如果在Happygirl字符串前面输入welcome赋值给数组,如果不加’\0’的情况:就会输出welcomerl.新字符串和老字符串无法区分。
在这里插入图片描述
如果在welcome后面加一个’\0’就代替了’r’
在这里插入图片描述
而在输出字符串数组的时候,是遇到’\0’就停止输出,所以最后输出字符串的时候只输出welcom,而不是welcomel

3.2字符数组输入输出

字符输入输出有两种方式:

  1. 用%c逐个输入输出字符

例如:

char a[3]={'B','O','Y'};
int i;
for(i=0;i<3;i++)
	printf("%c",a[i]);//逐个输出字符
  1. 用%s输入整个字符串

例如:

char a[10]={"world"};//字符串长度为5,加上'\0'为6个字节
printf("%s\n",a);//遇到'\0'就停止输出,就只输出world

注意:

  1. 输出的字符不包含’\0’,因为它是空操作符,只起标志作用
  2. printf(“%s”,数组名);是数组名,不是数组元素a[0]
  3. 无论数组长度多大,遇到’\0’就结束

3.用scanf输入字符串,输入的字符串长度应该小于字符串数组的长度

输入多个字符串的时候,应该以空格分隔。
如果输入的是字符数组名,不能加&,因为数组名代表数组的首地址。

例如:从键盘上输入a good boy

#include<stdio.h>
int main()
{
	char s1[5],s2[5],s3[5];
	scanf("%s%s%s",s1,s2,s3);
	puts(s1);
	puts(s2);
	puts(s3);
	return 0;
} 

运行结果:
在这里插入图片描述
数组的状态:
在这里插入图片描述
如果改为:

#include<stdio.h>
int main()
{
 	char a[13];
	scanf("%s",a);
	puts(a);
	return 0;
} 

运行结果:
在这里插入图片描述

因为系统把空格字符串作为输入的字符串之间的分隔符,因此只把空格前的字符"a"送到a数组中,把“a”作为一个字符串处理,在后面加’\0’。

3.3使用字符串处理函数

3.3.1puts函数-输出字符串函数

遇到’\0’停止输出,且自动换行。
一般形式:

puts(数组名)

例如:

char a[]="welcome\nto\nChina";
puts(a);

输出结果:
welcome
to
China

3.3.2gets函数-输入字符串函数

一般形式:
gets获得的函数值是字符数组的起始地址

gets(数组名)

3.3.3strcat函数-字符串连接函数

3.3.3.1函数使用

一般形式:

strcat(字符数组1,字符数组2)

作用:把字符串2连接到字符串1的后面,结果放在字符数组1中,函数调用后得到一个函数值为字符数组1的地址。

注意:

  1. 字符数组1必须足够大;
  2. 在连接两个字符串的时候,字符数组1的’\0’取消,只保留字符数组2的’\0’.因为在打印的时候,遇到’\0’就结束打印,所以字符数组1的’\0’必须取消掉。

例如连接两个字符串:

#include<stdio.h>
#include<string.h>//引用头文件才可以使用strcat函数
int main()
{
 	char s1[30]="This is ";
 	char s2[]="an apple";
	printf("%s",strcat(s1,s2));
	return 0;
} 

运行结果:
在这里插入图片描述

3.3.3.2函数原理

头文件:string.h
函数原型: char *strcat(char *dest,const char *src)
作用:把字符串src连接到字符串dest的后面
参数:src为原串的起始地址,dest为目标串的起始地址
返回值:目标串的起始地址

不用strcat函数实现字符串连接:

#include<stdio.h>
int main()
{
 	char s1[30]="This is ";
 	char s2[10]="an apple";
	char *p,*q;
	p=s1;
	q=s2;
	
	//while(*++p) ;
	while(*p) p++;
	while(*q){
		*p++=*q++;
	}
	*p='\0';
	printf("%s",s1);
	return 0;
} 

说明一下:

while(*p++)while(*p) p++;while(*++P)的区别

1.while(p++)表示:当p=0的时候,退出循环,p++任然执行,因为++是先赋值后运算。
2.while(p) p++;表示的意思是:当p=0的时候,退出while循环体,p++不在执行。
3.while(++p)表示:++优先级高于;先执行++p,在取值,当*p=0时,不再++。

3.3.4strcpy函数和strncpy函数-字符串复制函数

3.3.4.1函数使用

一般形式

strcpy(字符数组1,字符串2)strcpy(str1,str2,n);

1作用:把字符串2复制到字符数组1中去。
2作用:把str2中的前n个字符复制到str1中。

注意:

  1. 字符数组1的空间必须足够大
  2. 字符数组1必须写成数组名的形式,字符串2可以是字符数组名,也可以是一个字符串常量。
  3. 需要对字符数组1的内容初始化或者赋值,否则在进行复制的时候,字符串未被复制的地方的内容是无法预知的。
  4. 字符数组名是一个地址常量,其值是不能改变的,不能直接用赋值语句的。

例如:

char a[10];
char b[]="today";
strcpy(a,b);//字符数组名
strcpy(a,"BOY");//字符串常量
char str1[20];
str1="good";//不能用赋值语句赋值
str1=str2;//也不能用数组名直接赋值
3.3.4.2函数原理

头文件:string.h
函数原型:char *strcpy(char *dest,const char *src)
作用:字符串的复制
参数:src为原串的起始地址,dest为目标串的起始地址
返回值:目标串的起始地址

例如:用程序实现strcpy函数功能。

#include<stdio.h>
int main()
{
 	char s1[50];
 	char s2[10]="an apple";
	char *p,*q;
	p=s1;
	q=s2;
	while(*q){
		*p++=*q++;
	}
	*p='\0';
	printf("%s",s1);
	return 0;
} 

3.3.5strcmp函数-字符串比较函数

3.3.5.1函数使用

一般形式

strcmp(字符串1,字符串2)

作用:从左到右逐个比较字符串的ASCII码,直到出现不同的字符或者’\0’为止。
(1)字符串1=字符串2,函数值为0
(2)字符串1>字符串2,函数值为一个正整数
(3)字符串1<字符串2,函数值为一个负整数

3.3.5.2函数原理

头文件:string.h
函数原型:int strcmp(const char *src,const char *dst)
作用:从左到右逐个比较字符串的ASCII码,直到出现不同的字符或者’\0’为止。
参数:s1和s2为字符串的起始地址。
返回值:
(1)字符串1=字符串2,函数值为0
(2)字符串1>字符串2,函数值为一个正整数
(3)字符串1<字符串2,函数值为一个负整数

例如:用程序实现strcmp函数功能。

#include <stdio.h>
int strcmp_new(const char* src, const char* dst)
//比较两个字符串每一个字符的大小,若相等则比较两者的下一个字符
{
    int ret = 0;
    while( !(ret = *(unsigned char*)src - *(unsigned char*)dst) && *dst)
    {
        src ++;
        dst ++;
    }
    if( ret < 0) ret = -1;
    else if(ret > 0) ret = 1;
    return ret;
}

它的含义是如果两个字符串相等时,(!ret)就是非零,执行while里面的代码,当两个字符串都比较完了要退出时(&&str)或(&&dst)退出while循环;

当两个字符串相减不为0时,直接执行下面的if语句;

int main()
{
    char str[10] = "an apple";
    char str1[10] = "an Apple";

    int ret1 = strcmp_new(str,str1);
    printf("ret=%d\n", ret1);
    getchar();
    return 0;
}

3.3.6strlen函数-字符串长度函数

3.3.6.1函数使用

一般形式:

strlen(字符数组);
返回值为字符串的实际长度(不包括’\0’)

区分sizeof和strlen

  1. sizeof 计算的则是分配的数组所占的内存空间的大小,不受里面存储的内容影响,包括’\0’
  2. strlen 计算字符串的长度,不包括‘\0’

例如:

char a[]="abcdefg";
sizeof(a)sizeof(a[0])=8;计算的是数组的空间大小,包括'\0'
strlen(a)=7;//表示字符串长度,不包括'\0'
3.3.6.2函数原理

头文件:string.h
函数原型:size_t strlen(const char *s)
作用:计算字符串的实际长度,不包括’\0’
参数:s为字符串
返回值:字符串数组的长度,不包括’\0’

函数实现:

#include<stdio.h>
int main()
{
	char s[]="abcdefg";
	char *p;
	p=s;
	int count=0;
	while(*p)
	{
		count++;
		p++;
	}
	printf("%d",count);
	return 0;
 } 

3.3.7strlwr函数-转化为小写的函数

3.3.7.1函数使用

一般形式

strlwr(字符串);
作用:把字符串中的大写转化为小写字母

3.3.7.2函数原理

头文件:string.h
函数原型:exter char *strlwr(char *str)
作用:把字符串中的大写转化为小写字母
参数:str为字符串
返回值:转化后的字符串的指针

函数实现:
大写字母的ASCII比小写字母的ASCII小32;

#include<stdio.h>
#include<string.h>
char* my_strlwr(char *str)
{
	char *s;
	s=str;
	while(*s!='\0')
	{
		if(*s>='A' && *s<='Z')
		{
			*s+=32;
		}
		 s++; 
	} 
	return s;
}
int main()
{
	char str[10]="APPLE";
	my_strlwr(str);
	printf("%s",str);
	return 0;
 } 

3.3.8strupr函数-转化为大写的函数

3.3.8.1函数使用

一般形式

strupr(字符串);
作用:把字符串中的小写转化为大写字母

3.3.8.2函数原理

头文件:string.h
函数原型:exter char *strupr(char *str)
作用:把字符串中的小写转化为大写字母
参数:str为字符串
返回值:转化后的字符串的指针

#include<stdio.h>
#include<string.h>
char* my_strlwr(char *str)
{
	char *s;
	s=str;
	while(*s!='\0')
	{
		if(*s>='a' && *s<='z')
		{
			*s-=32;
		}
		 s++; 
	} 
	return s;
}
int main()
{
	char str[10]="apple";
	my_strlwr(str);
	printf("%s",str);
	return 0;
 } 

3.3.9字符数组举例

题目:输入一行字符,统计有多少个单词,单词之间用空格隔开。

思路:根绝空格来判断是否有新单词的出现,逐个检查字符是否为空格,如果是则进行加一。

#include<stdio.h>
int main()
{
	char str[50];
	int word=0;//标志是否有新单词出现的标志 
	int sum=0;//用于计算单词个数 
	char *p;//使用指针指向字符串数组 
	gets(str);
	p=str;
	while(*p){
		if(*p==' ')//表示没有出现新单词 
		{
			word=0;
		}else if(word==0){
			//前一字符为空格word=0,新单词出现,sum+1,word=1;
			word=1;
			sum++;
		}
		p++;
	} 
	printf("%d",sum);
	return 0;
 } 
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

最没脑子

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值