嵌入式学习Day7 C语言 --- 数组

一、对齐的方式:

单行对齐:
  命令模式下
  按两下 = 
多行对齐:
  shift+v 选中 
  按一下 =  
  起始行 = 结束行 
全局对齐:
  起始行 = 结束行 
  gg      G(shift + g)  
  

  
二、一维整形数组

1、格式

类型说明符 数组名[常量表达式];
   
(1).类型说明符 
    整型 
       int,short,long ,long long 
    浮点 
    字符  //基本数据类型 
    
(2).数组名 
    代表着 数据集合 (内存空间的一个名字) 
    数据类型角度 
    1. a代表整个数组类型 
    2. a代表一个值 --数组首元素的地址 
    
(3).[]  
    表示此时定义的是一个 数组 
    
(4).常量表达式
    表示数组的长度 --- 变量的个数 
    
    数组长度 与 下标 
    数组长度 --表示几个元素(变量)
    下标 --偏移量 
         [0~数组长度-1]
    int a[10];
    [0~9]
eg:
int array[5]; //定义一个数组,这个数组放了5个 int型变量 
int array[40]; 


2、数组本身也是一种数据类型(数组的定义)

数据类型 变量名;  
int a = 10; //a int型 

int a[10]; //a所代表的类型是 int[10] 
              
int[10] a; //a所代表的类型 int[10] 
              //a数组名 标识符 
              //a ---把名字去掉 ,剩下的就是名字对应的数据类型 


3、数组在内存空间上的特点

a.连续性 --一片连续空间 
b.有序性 --元素依次存储 
c.单一性 --单一类型的元素


4、数组的初始化 

int a[10] = {1,2,3,4,5,6,7,8,9,10}; //全部初始化 
int a[10] = {1,2,3,4,5};  //部分初始化--依次给到数组元素 ,没有给值的元素,默认初始化为0
将数组初始化为0 
int a[10] = {}; //都初始化为0
int a[10] = {0}; //都初始化为0 
数组不初始化 --- 数组中为垃圾值 


5、数组的赋值

注意:  
  a.数组赋值不能整体赋值 
  b.数组赋值,需要一个元素一个元素个给到

6、变长数组 

int n = 10;
scanf("%d",&n);
int a[n];   

注意:
1、变长数组不能赋值
2、没赋值时,数据内部存储的是垃圾值
3、完全未初始化的普通数组a[10],此时数组中存储的值为垃圾值
4、
    int a[10] = {1,2,3};
    这种普通数组不完全赋值,其他位置存储的值默认为是0

a. 变长数组为初始化打印出此时数组存储的值

int n = 0,i = 0;
scanf("%d",&n);
int a[n];

for(i = 0;i < n;i++)
{
	printf("%d ",a[i]);
}

	return 0;
}

b. 完全未初始化的数组直接打印出数组中的结果 --> 随机值

int a[3];
int i = 0;

for(i = 0;i < 3;i++)
{
	printf("%d ",a[i]);
}

	return 0;
}

7、数组的越界问题(eg:a[-5])

1.不是语法问题 --- 编译器不报错,越界位置打印出来随机值 
2.程序员 自己小心 

三、一维字符型数组

1、字符数组的形式:

"english"  //字符串 常量 
           //本质存储时候,是按照 字符数组的形式存储,只不过是后边多存储一个字符串结束标志'\0' 

eg:

unsigned char  s[10] = {'h','e','l','l','o'};//数组考虑 

"hello" -->  unsigned char  s[10] = {'h','e','l','l','o','\0'};  


unsigned char  s[10] = "hello";  //占用了6个字节的内存
unsigned char  s[10] = {'h','e','l','l','o','\0'};  //占用了6个字节的内存
unsigned char  s[10] = {'h','e','l','l','o'};       //占用了5个字节的内存


unsigned char  s[] = {'h','e','l','l','o','\0'};   //[]中可以不放数字
unsigned char  s[] = {'h','e','l','l','o'};  


2、字符数组的作用:

处理字符串数据 


3、注意:

 1.字符串 -- 更关注的是字符串整体,而不是单个字符 
 2.字符串的结束标志 比较重要 ,表示字符串结束 
 3.处理字符串时,常常使用结束标志作为判断 

 
 4、puts函数:

 int puts(const char *s);
 功能
    输出字符串 
 参数
    @s 字符串所在空间的首地址 
 返回值
    int 成功 >0 
        失败 -1 

  特点:
  输出时,自动换行
  
练习:
  定义一个字符数组 
  从键盘输入一个字符串到字符数组中 
  要求:
    一个字符一个字符输入 ,使用scanf("%c",  );

 char s1[10];
 int i = 0;
 
 while ((s1[i] = getchar())!='\n')
 {   
     i++;
 }
 s1[i] = '\0';

 puts(s1);

    
    
5、gets()函数:

 char *gets(char *s);
 功能:
     输入字符串 
 参数:
    @s 存放字符串一块内存空间 
返回值:
    表示的是 存储字符串那块空间首地
练习1:
   统计字符串的长度 
   用gets()获取字符串: 

	char s[] = {1,2,3};  //这里是代表给数组s中放入1 2 3三个数值,且开辟了3个字节的空间
	int i = 0;

	gets(s);//即使这里输入5个字符,也并不能认为是给s中开辟5个字节的空间,因为前边空间已经开辟好了

	while(s[i] != '\0')
	{
		i++;
	}

	printf("strlen = %d\n",i);

  gets函数和scanf函数的区别

  gets ();  //可以输入带空格的字符串
  scanf(); //不能输入带空格的字符串,因为空格作为scanf的一种分割符,scanf识别到空格人数输入结束 

scanf函数给arr数组中输入字符串:

键盘上输入 hello world,计算机输出 hello

gets函数给arr数组中输入字符串:

键盘上输入 hello world,计算机输出 hello world

6、strcpy函数:

char *strcpy(char *dest, const char *src);
   功能:
        实现字符串拷贝 
   参数:
       @dest  目标字符串 
       @src   源字符串 
    
  返回值: 
      成功 返回的是 dest地址 
      失败 NULL 

  练习:

       实现strcpy函数功能

	char s1[6] = "hello";
	char s2[6];
	int i = 0;
	
	for(i = 0;i < 6;i++)
	{
		s2[i] = s1[i];
	}

	puts(s2);

7、strlen函数 

功能:

计算字符串长度(不包括’\0‘)

练习:

实现strlen函数功能: 

	char s[] = {1,2,3};  //这里是代表给数组s中放入1 2 3三个数值,且开辟了3个字节的空间
	int i = 0;

	gets(s);//即使这里输入5个字符,也并不能认为是给s中开辟5个字节的空间,因为前边空间已经开辟好了

	while(s[i] != '\0')
	{
		i++;
	}

	printf("strlen = %d\n",i);

 8、strcmp函数

 格式: 

     int strcmp(const char *s1, const char *s2);
 功能:
     比较两个字符串 
 参数:
    s1  //字符数组名
    s2 
 返回值:
    >0    s1 > s2
    ==0   s1 == s2 
    <0    s1 < s2 
    返回值,实际上是,结束位置上字符的差值 

char s1[10] = "hello";
char s2[10] = "hellp";
printf("strcmp(s1,s2) = %d\n",strcmp(s1,s2)); //输出结果为-1


char s1[10] = "hello";
char s2[10] = "hell";
printf("strcmp(s1,s2) = %d\n",strcmp(s1,s2)); //输出结果为111('o'的ascii-'\0'的ascii)

字符串比较的规则

对两个字符串自左至右逐个字符相比(按ASCII 码值大小比较),直到出现不同的字符或遇到'\0' 为止。如全部字符相同,则认为相等;若出现不相同的字符,则以第一个不相同的字符的比较结果为准。

练习:

实现strcmp函数功能

	char s1[10] = "hello";
	char s2[10] = "hello";
	int i = 0;

	while(s1[i] != '\0' && s2[i] != '\0' && s1[i] == s2[i] )
	{
		i++;
	}

	if(s1[i] > s2[i])
		printf("s1较大\n");
	else if(s1[i] < s2[i])
		printf("s2较大\n");
	else
		printf("s1 = s2\n");

9、strcat函数

   char *strcat(char *dest, const char *src);
   
   功能:
      字符串拼接 
   参数:
      @dest  目标字符串 
      @src   源字符串 
   返回值:
     成功 返回的是dest 
     失败 NULL 

练习 :

实现strcat函数功能

	char s1[20]= "hello";
	char s2[20]= "world";  //这里[]里边可以不写数字,让系统自己匹配数值 (这样的说法是错误的)
	int i = 0,j = 0;

	while(s1[i] != '\0')   //找到s1数组中'\0'的位置
	{
		i++;
	}	
	while(s2[j] != '\0')   //拼接
	{
		s1[i] = s2[j];
		j++;
		i++;
	}
		s2[j] = '\0';

	puts(s1);

四、二维整形数组

1、二维数组定义的一般形式为

 类型说明符 数组名[常量表达式][常量表达式];

 eg:int a[3][4];  //三行,四列

 2、二维数组初始化

int a[3][4] = {1,2,3,4,5,6,7,8,9,10,11,12};  //全部初始化 
int a[3][4] = {1,2,3,4,5,6,7};                       //部分初始化 
int a[3][4] = {{1,2,3,4},{5,6,7,8}};               //按行初始化

 
3、c语言中二维数组的本质 

a. C语言中,不存在真正的二维数组,只有一维数组 
b. 二维数组本质,是一维数组的一维数组

 4、难点:数组类型 

类型说明符 数组名[常量表达式];
 
int a[4];  //一维数组 
              //a的数据类型 int[4] 
           

int[4] a[3];  //一维数组 
                  //一维数组的元素类型 --> 又一个数组类型 
              
int a[3][4];  //二维数组 
                  //a的数据类型 int[3][4] 

5、注意

   int[] a[3];   //error,一维数组的类型不明确了
   int[4] a[];   //true
   int a[3][4];  //二维数组语法角度 ---行数可以省略 列数不能省略 
 

 6、拓展其他维数

 int a[3][4];     // 3行 4列 
 int a[3][4][5]; 
 int a[3][4][5][6]; 
 .....
 
 
 
 int[3][4] a[5]; 
 int a[3][4][5];


 7、练习

练习1:
   int a[3][4];
   从键盘输入值
   要求求出,二维数组边上和   

//四个边上的数值之和

	int s1[3][4];
	int i = 0,j = 0,ret = 0;
	
	for(i = 0;i < 3;i++)    //给数字中的每个元素赋值
	{
		for(j = 0;j < 4;j++)
		{
			scanf("%d",&s1[i][j]); 
		}
	}
	for(i = 0;i < 3;i++)    //找四个边上的数值
	{
		for(j = 0;j < 4;j++)  
		{
			
		    if(i != 1 || j != 1 && j != 2)  //法一
			ret = ret + s1[i][j]; //求和
			

			/*
			if(i == 0 || i == 2 || j == 0 || j == 3)   //法二
				ret = ret + s1[i][j]; //求和
			*/
		}
	}
	printf("%d",ret);

   
练习2:  

   实现矩阵的转置 
eg: 
   1 2 3  
   4 5 6
   7 8 9
   
   1 4 7  
   2 5 8
   3 6 9

//转置矩阵
//思路:找出下表中行标大于列表的数值,之后进行下标互换以实现数值互换

	int s[4][4] = {1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16};
	int i,j,t;

	for(i = 0;i < 4;i++)  
	{
		for(j = 0;j < 4;j++)
		{      if(i > j)      //找出下表中行标大于列表的数值
			{
				t = s[i][j];  //下三行代码实现下标互换
				s[i][j] = s[j][i];
				s[j][i] = t;
			}
		}
	}

	for(i = 0;i < 4;i++)   //打印转置之后的矩阵
	{
		for(j = 0;j < 4;j++)
		{
			printf("%d ",s[i][j]);
		}
		
			printf("\n");
	}


   

五、二维字符型数组

char s[10] = "hello"; //一维
char s[3][10] = {"aaa","bbb","ccc"};  //二维
char s[3][10] = {{a,a,a,\0},{b,b,b,\0},{c,c,c,\0}}; //二维

练习:
  输入三个字符串 
  找出最大字符串 
  strcmp(s[0],s[1]) 
  strcpy(s[0],s[1])

//字符串比较(strcmp)函数的使用
//练习:找出三个字符串中的最大的字符串

char ch1[3][10] = {"ccc","bbb","aaaa"};
int i,t1,t2;

	t1 = strcmp(ch1[0],ch1[1]);
	if(t1 > 0)
	{
		t2 = strcmp(ch1[0],ch1[2]);
		if(t2 > 0)
			printf("0\n");
		else
			printf("2\n");
	}
	if(t1 < 0)
	{
		t2 = strcmp(ch1[1],ch1[2]);
		if(t2 > 0)
			printf("1\n");
		else
			printf("2\n");
	}

练习:
  输入3个字符串 
  分别使用选择排序、冒泡排序、插入排序的方法对根据字符串的大小进行排序
  排序结束后,使用二分查找的方法找出自己想查找的字符串,打印字符串所在位置的下标

  

//字符串选择排序 + 二分查找

	char s1[3][10] = {"aaa","bbb","ccc"};
	int i = 0,j = 0;
	char s2[10],s3[10];
	int begin,end,mid;
	
	for(i = 0;i < 2;i++)
	{
		for(j = 0;j < 3 - i;j++)
		{
			if((strcmp(s1[i],s1[i+j])) > 0)
			{
				strcpy(s2,s1[i]);
				strcpy(s1[i],s1[i+j]);
				strcpy(s1[i+j],s2);
			}

		}
	}
	
	strcpy(s3,s1[2]);
	begin = 0;
	end = 2;

	while(begin <= end)
	{
		mid = end + begin;
		if(strcmp(s1[mid],s3) == 0)
		{
			break;
		}
		else if(strcmp(s1[mid],s3))
		{
			end = mid - 1;
		}
		else
		{
			begin = mid + 1;
		}
	}
	if(begin <= end)
	printf("找到了,下标是%d\n",mid);
	else
	printf("没找到\n");


//字符串冒泡排序 + 二分查找

	char s1[6][10] = {"aaa","bbb","ccc","ddd","eee","fff"};
	int i = 0,j = 0;
	char s2[10],s3[10];
	int begin,end,mid;

	for(i = 0;i < 5;i++)
	{
		for(j = 0;j < 5 - 1 - i;j++)
		{
			if((strcmp(s1[i],s1[i+1])) > 0)
			{
				strcpy(s2,s1[i]);
				strcpy(s1[i],s1[i+1]);
				strcpy(s1[i+1],s2);
			}
		}
	}

	strcpy(s3,s1[5]);
	begin = 0;
	end = 5;

	while(begin <= end)
	{
		mid = end + begin;
		if(strcmp(s1[mid],s3) == 0)
		{
			break;
		}
		else if(strcmp(s1[mid],s3))
		{
			end = mid - 1;
		}
		else=
		{
			begin = mid + 1;
		}
	}
	if(begin <= end)
	printf("找到了,下标是%d\n",mid);
	else
	printf("没找到\n");



//插入排序法对字符串进行排序,后使用二分查找找出自己想要的字符串

	char ch1[6][10] = {"ccc","bbb","aaa","ddd","eee","fff"};
	int	i = 0,j = 0,r = 0;
	char s1[10];
	char s2[10] = "aaa";
	int begin = 0,mid  = 0,end = 5;

	for(i = 0;i < 3;i++)
	{
		strcpy(s1,ch1[i]);
		j = i;

		while(j > 0 && (r = strcmp(ch1[j-1],s1)) > 0)
		{
			strcpy(ch1[j], ch1[j - 1]);
			j--;
		}
		strcpy(ch1[j],s1);
	}
	while(begin <= end)
	{
		mid = begin + end;

		if(strcmp(ch1[mid],s2) > 0)
		{
			end = mid - 1;
		}
		else if(strcmp(ch1[mid],s2) < 0)
		{
			begin = mid + 1;
		}
		else
			break;
	}
	if(begin <= end)
	{
		printf("找到了,下标是%d\n",mid);
	}
	else
		printf("没找到\n");

六、总结:

1.数组概念
2.数组定义
  一维整型
  一维字符型 
  二维整型数组
  二维字符型数组  
  
3.重点
  a.二维数组本质 
  b.二维整型数组操作 ---访问具体的元素 a[i][j]
  c.二维字符型数组 
    放多个字符串 
    char s[3][10];

5.掌握 
  a.排序算法 
    选择
    冒泡
    插入 
    查找 
  b.字符串 
    strlen
    strcpy 
    strcat 
    strcmp 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值