嵌入式学习LV1-C语言- D5. 数组与字符串

D5 数组与字符串


如果出现图片无法查看可能是网络问题,我用的GitHub+图床保存的图片,用uu加速器说不定能解决,可以参考我另外一篇文章GitHub的使用方法
GitHub使用教程含网络问题_github加速器_肉丸子QAQ的博客-CSDN博客

关注后私信获取笔记资料


数组

  • 构造数据类型之一

  • 数组是具有一定顺序关系的若干个变量的集合,组成数组的各个变量称为数组的元素

  • 数组中各元素的数据类型要求相同,用数组名和下标确定。数组可以是一维的,也可以是多维的。

  • 大小为:数据类型 x 空间大小

1. 一维数组

  • 定义:只有一个下标的数组。它在计算机的内存中是连续存储的。

  • 结构

    <存储类型> <数据类型 > <数组名>[<表达式>] ;

    存储类型默认是auto,可以省略不写

  • 注意事项:

    • C语言对数组不作越界检查,使用时要注意

    ​ 编译代码的时候,是不会报错的,要注意数组越界的这种情况

  • 一维数组的引用

    • 数组必须先定义,后使用

    • 只能逐个引用数组元素,不能一次引用整个数组

    • 数组元素表示形式:数组名[下标]

      • 下标可以是常量或整型表达式
  • 一维数组的初始化

    • 初始化方式:在定义数组时,为数组元素赋初值 int a[5]={1,2,3,4,5};\

    注意:

    • 数组不初始化(赋初值),其元素值为随机数

    • 对static数组元素不赋初值,系统会自动赋以0值

    • 只给部分数组元素赋初值

嵌入式学习LV1-C语言- D5. 数组与字符串_第1张图片

2. 冒泡排序

#include 

int main()
{
	int i,j,tem;
	int a[10] = {};
	printf("请输入10个数字进行排序:\n");
	for(i = 0; i<10; i++)
	{
		printf(">");
		scanf("%d", &a[i]);
		
	}

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

	for(i = 0; i < 10; i++)//这里第一层循环是为了能够完全,如果只有一个循环体的话,只能选出最大的,随着i的加大,倒数最大的第几个数会依次比较出来
	{
		for(j = 0; j < 10 - i -1; j++)//为了避免资源浪费,第一轮最大值已经比较出来,后面的轮次就不需要比较
		{//10个数只用比较9次所以减一,避免浪费资源再减i次,i是指已经轮完的个数
		if(a[j] > a[j+1])
		{
			tem = a[j];
			a[j] = a[j+1];
			a[j+1] = tem;

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

实验现象:

嵌入式学习LV1-C语言- D5. 数组与字符串_第2张图片

3. 二维数组

二维数组的定义

  • 定义方式:(声明时列数不能省略,行数可以

    不写行号的时候根据实际定义的自动检测

    格式:数据类型 数组名[行] [列]

int a[2][2]
  • 数组元素的存放顺序

    • 原因:内存是一维的,物理上内存是连续存放

    • 二维数组:按行序优先

4. 杨辉三角

设计程序的时候不能总想着一次性写完,要试着将程序分解成小部分或者将程序的雏形写出再慢慢修剪

我们先将思路分解成三步

  • 首先先实现矩形打印
  • 再先办法打印下三角

每行打印的个数刚好和行数相同

  • 最后面想办法将对应的值修改

数组不初始化(赋初值),其元素值为随机数

#include 

int main()
{
	int a[10][10] = {{0}};//数组一定要初始化!!!!
	int i, j;

	for(i = 0; i < 10; i++)
	{
		a[i][0] = 1;
		for(j = 1; j <= i; j++)//j = 1s是为了不干扰第一列这里上限改成i是为了把上三角变为0
							  //这样子的话可以让下三角最右边达成杨辉三角的规律
							  //我们只需要将第一列特殊赋值就行
		{
			a[i][j] = a[i-1][j-1] + a[i - 1][j];//杨辉三角运算规则
		}

	}

	for(i = 0; i < 10; i++)
	{

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

		}
		printf("\n");

	}

	return 0;
}

实验现象:

嵌入式学习LV1-C语言- D5. 数组与字符串_第3张图片

5. 思考:求二维矩阵最大值以及其行列号

个人:

#include 

int main()
{

	int a[3][4] = {{0}};
	int i, j, max;
	int hang,lie;
/*
键盘输入二维数组
*/
	for(i = 0; i<3; i++)
	{
		for(j = 0; j < 4; j++)
		{
			printf("a[%d][%d]=", i, j);
			scanf("%d",&a[i][j]);
		
		}
		
	
	}

	max = a[0][0];//将第一个值存入最大值
    
	for(i = 0; i<3; i++)
	{
		for(j = 0; j < 4; j++)
		{
			if(a[i][j] > max)//当有更大值的时候覆盖原来最大值
			{
				max = a[i][j];
				hang = i;//保存行号
				lie = j;//保存列号
			
			}
			printf("a[%d][%d]=%d ", i, j, a[i][j]);//用来查看输入的二维数组
					
		}
			putchar('\n');
		
	}

    
	printf("max=%d,行:%d 列:%d\n", max, hang, lie);


return 0;
}

参考答案:

思路:通过保存行列号来的方式来保存最大值,自己写的是通过中间变量保存最大值和行列号,相比于参考答案,我的耗费内存

#include 

int main(int argc, char *argv[])
{
        int a[2][3] = {{2, 5, 8}, {21, 56, 9}};
        int i, j, row, column;

        row = column = 0;

        for (i = 0; i < 2; i++)  {
                for (j = 0; j < 3; j++) {
                        if (a[row][column] < a[i][j]) {
                                row = i;
                                column = j;
                        }
                }
        }

        for (i = 0; i < 2; i++)  {
                for (j = 0; j < 3; j++)
                        printf("%5d ", a[i][j]);
                putchar('\n');
        }

        printf("max=%d %d %d\n", a[row][column], row, column);

        return 0;
}

字符串数组和字符串

1. 字符串数组

字符数组是元素的数据类型为字符类型的数组

char c[10], ch[3][4];

一维二维都有

2. 字符数组的初始化

  • 逐个字符赋值

  • 用字符串常量

一维数组:

二维数组:

#include 

int main()
{
	char a1[] = {'a', 'b', 'c'};
	char a2[6] = {'d', 'e', 'f'};

	int i,n;

	//实验二:使用printf简化
	printf("a1:%s %p\n", a1, &a1[2]);
	printf("a2:%s %p\n", a2, a2);

	//实验一:原始的打印方式
#if 0
	n = sizeof(a1) / sizeof(char);
	for(i = 0; i < n; i++)
	{
		putchar(a1[i]);
	}
	putchar('\n');
	
	n = sizeof(a2) / sizeof(char);
	for(i = 0; i < n; i++)
	{
		putchar(a2[i]);
	}
	putchar('\n');
#endif

	return 0;
}

实验一:最原始的打印方式

image-20230518224936329

实验二:

image-20230518225009742

从结果来看发现a1的打印结果出现了错误

分析原因:由于char a1[] = {'a', 'b', 'c'};赋值没有以\0结尾,打印字符串的原理是%s已经告诉系统要打印字符串,但是由于a1没有结尾符号,系统会认为没有打印完。但是为什么会把a2也打印出来呢?

从结果图片能得出结果a1与a2的地址是连续的,所以a1没有结束符会一直等到a2的结束符停止打印,a2的结束符是系统给的,如下图:在初始化确定空间后多余的空间会被赋予\0

3. 思考

输入一个字符串,然后将其逆序输出

思路1:倒叙打印

#include 
#include 
#define N 20
int main()
{
	int i,n;
	char a[N] = {0};
	printf("输入一个字符串:");
	gets(a);
	n = strlen(a);//通过字符串函数获取输入的字符串长度(包括了\0)
	printf("%d\n", n);
	for(i = n-1; i >= 0; i--)
	{
		putchar(a[i]);
	}
	putchar('\n');

	return 0;
}

思路2:改变数组内容

#include 
#include 

#define N 20

int main(int argc, char *argv[])
{
        char arr[N] = {0};
        int i, j, n, ch;

        printf("请输入:");
        gets(arr);

        n = strlen(arr);
        i = 0;
        j = n-1;
        while (i < j) {
                ch = arr[i];
                arr[i] = arr[j];
                arr[j] = ch;
                i++;
                j--;
        }

        puts(arr);

        return 0;
}

字符串函数

C库中实现了很多字符串处理函数

头文件: #include

几个常见的字符串处理函数

  • 求字符串长度的函数strlen

  • 字符串拷贝函数strcpy

  • 字符串连接函数at

  • 字符串比较函数

1. 字符串长度函数strlen

  • 格式:strlen(字符数组)

  • 功能:计算字符串长度

  • 返值:返回字符串实际长度,不包括‘\0’在内

  • \xhh表示十六进制数代表的符号

  • \ddd表示8进制的

例:对于以下字符串,strlen(s)的值为:

char s[10]={‘A’,‘\0’,‘B’,‘C’,‘\0’,‘D’};

char s[ ]=“\t\v\\0will\n”;

char s[ ]=“\x69\141\n”; //i,a

答案:1 3 3

#include 
#include 

int main(int argc, char *argv[])
{
        char s1[] = "\tab\nc\vd\\e";
        char s2[]= "\x69\141";

        printf("%d\n", strlen(s1));
        printf("%d\n", sizeof(s1)/sizeof(char));

        printf("\n%d\n", strlen(s2));
        printf("%d\n", sizeof(s2)/sizeof(char));
        puts(s2);

        return 0;
}


2. 字符串拷贝函数strcpy

  • 格式:strcpy(字符数组1,字符串2)

  • 功能:将字符串2,拷贝到字符数组1中去

  • 返值:返回字符数组1的首地址

  • 说明:

    • 字符数组1必须足够大
    • 拷贝时**‘\0’一同拷贝**

3. 字符串连接函数strcat

  • 格式:strcat(字符数组1,字符数组2)

  • 功能:把字符数组2连到字符数组1后面

  • 返值:返回字符数组1的首地址

  • 说明:

    • 字符数组1必须足够大
    • 连接前,两串均以‘\0’结束;连接后,串1的 ‘\0’取消,新串最后加‘\0’
#include 
#include 

#define N 100

int main(int argc, char *argv[])
{
        char dest[] = "www.makeru";
        char src[N] = ".com.cn";

        strcat(dest, src);

        puts(src);
        puts(dest);

        return 0;
}


4. 字符串比较函数strcmp

  • 格式:strcmp(字符串1,字符串2)

  • 功能:比较两个字符串

  • 比较规则:对两串从左向右逐个字符比较

​ (ASCII码),直到遇到不同字符或‘\0’为止

  • 返值:返回int型整数
  1. 若字符串1< 字符串2, 返回负整数

  2. 若字符串1> 字符串2, 返回正整数

  3. 若字符串1== 字符串2, 返回零


4. 扩展用法

  • strncpy(p, p1, n) 复制指定长度字符串

  • strncat(p, p1, n) 附加指定长度字符串

  • strcasecmp忽略大小写比较字符串

  • strncmp(p, p1, n) 比较指定长度字符串

  • strchr(p, c) 在字符串中查找指定字符

  • strrchr(p, c)反向查找

  • strstr(p, p1) 查找字符串
  • isalpha() 检查是否为字母字符
  • isupper() 检查是否为大写字母字符
  • islower() 检查是否为小写字母字符
  • isdigit() 检查是否为数字

作业

1.编程题:从终端输入10个数字(乱序),利用简单选择排序法对这10个数字排序,结果从小到大排列。
(温馨提示:冒泡排序和简单选择排序是两个不同的原理。这里考察我们的自学能力,如果不会,可以上网查阅资料)

#include
int main()
{
	int shu = 10;
	int a,b,c,tem;
	int d[shu];
	printf("请输入随机10个数:\n");
	for(a = 0; a < shu; a++){
		printf("第%d位:",a+1);
		scanf("%d",&d[a]);

	}

	for(a = 0; a < shu; a++){
		c = a;
		for(b = a+1;b < shu;b++){
			if(d[b] < d[c]){
				c = b;
			}
			if(c!=a){
				tem = d[a];
				d[a] = d[c];
				d[c] = tem;
			}
		}

	}
	printf("从小到大排序为:\n");
	for(b = 0; b < shu; b++){
		printf("%d ",d[b]);
	}
	return 0;





}

你可能感兴趣的:(学习,c语言,算法,linux,github)