目录
生活中有非常多的数据,也可能是一个班的男生身高,每天的花销账单等等,如果我们用简单的方法去记录他就会显得冗长而且不方便,因为这些数据是同一类性质的数据,所以就想着用同样的名字去命名他,称他为数组。当然,不同数据之间有不一样的差距,所以我们就引入下标,比如a1表示学生a的身高,a2表示学生b的身高......以此类推,如果我们有n个数据,就存在n个下标,代表着n个学生的具体情况,这个统一的名字a,就叫做数组名。
数组可以记录一串数据,可以是整型数据,浮点型数据,指针等等,当然这些数据都得有同样的特征。像数组这种的结构还有很多,比如结构体,联合体等等,一切都是为了简化记录数据。
1. 一维数组
当我们要运用一维数组的时候,需要提前定义。提前定义的目的是预通知计算机。一维数组的定义方法为arr[a],arr为数组名,这个数组名可以任意更换,只要在同一程序中运用的时候是同一个数组名就行。a为元素个数,也可以认为是数组长度。
我们在初始化数组的时候,有两种初始化方法,一种是完全初始化,还有一种是不完全初始化。完全初始化的意思是将所有元素都进行初始化,不完全初始化的意思是只将部分数据初始化。
数组名[元素下标]代表的是数组中的元素
数组元素的取名从0开始,然后向后逐渐递增,当然,不能把数组和元素的具体名称搞混,一旦搞混就会使得程序崩溃。
2. 二维数组
二维数组的意思是数组里面的元素是分行和列的。二维数组一般的定义形式是arr[a][b],其中arr为数组名,a,b代表元素个数,其中a表示有多少行,b表示有多少列,当然,二维数组和一维数组的初始化一样,都分为完全初始化和不完全初始化。
这种完全初始化的方式并不是很直观,所以我们可以用不一样的初始化的形式
二维数组也是可以认为是一维数组的集合,里面的元素都是一维数组,而且每一行都认为是一个一维数组,这样我们就很方便的看出其中包含两个一维数组,一个一维数组是{1,2,3},另外一个是{4,5,6}。
二维数组有很多种不同的初始化形式,比如
这样的话其他没有初始化的元素都会自动默认为初始化为0
3. 字符数组
字符数组是用来存放字符数据的数组,在字符数组中的一个元素中存放一个字符。因为ASCII值也属于整数形式,在c99中字符类型也属于整型。
空格其实也属于字符,对字符数组的初始化同样也有完全初始化和不完全初始化两种。比如
我们可以用gets函数输入字符串,用puts输出字符串。
比如
3.1 计算数组(字符串)中字符个数
如果我们定义了一个字符数组,不想一个一个找寻计算元素总数,怎么办?有以下几种方法,当然他们都有自己适用的范围。
3.1.1 sizeof
sizeof是一种操作符,用来计算元素长度,比如int类型为4个字符,char类型为1个字符。如果我们计算数组所占的字符个数然后除以一个类型所占的长度就能得到字符个数
3.1.2 strlen
strlen是一个库函数,包含在string.h的库里面,计算字符串长度。strlen计算方法是从字符串的第一个数开始计算,直到遇到\0,所以如果我们没有\0,就会打印出随机值
3.1.3 循环找寻
因为我们知道,如果一个循环的条件为0,循环就会停止,并且一个数组中如果没有完全初始化的话所在元素都为0。\0的ASCII码值是0,所以如果我们找到这个\0,循环停止。如果进行一次循环就计算一次,那么计算几次就是字符个数。这样我们就引入一个char*类型的指针,让他指向数组的起始地址,然后循环一次就++,就产生了下面的代码
#include <stdio.h>
int main()
{
int count = 0;
char arr[7]= { "abcdef"};
char* s = arr;
while (*s)
{
count++;
s++;
}
printf("%d", count);
return 0;
}
3.1.4 指针-指针
按我们上面的思路,循环一次指针就加一次,那如果我们引入一个指针在起始的位置(arr[0]),当我们指针移动到\0的时候结束进程,然后指针相减也可以得到字符个数,就得到下面这个
#include <stdio.h>
int main()
{
char arr[7]= { "abcdef"};
char* s = arr;
char*start=arr;
while (*s)
{
s++;
}
int sz = s-start;
printf("%d", sz);
return 0;
}
4. 变长数组
变长数组的意思不是字面上感觉的这个数组可以变长,而是意思是数组变量长度没有被定义。c99中引入变长数组,允许我们自己定义数组的长度,而不用死死的固定为某一固定值。这样处理后我们可以更灵活地运用数组,而不会出现空间浪费或者长度不够等问题。如下
#include <stdio.h>
int main()
{
int a = 0;
scanf("%d",&a);
int c = 0;
int arr[a];
for (c=0;c<a;c++)
{
scanf("%d",&arr[c]);
}
for (c=0;c<a;c++)
{
printf("%d",arr[c]);
}
return 0;
}
使用这种方法我们可以自己定义输入的字符个数,然后再投入程序的使用
5. 冒泡排序
如果我们拿到一个无序的数组,我们可以通过循环的方式进行排序。我们先拿出第一个和第二个元素,如果第一个大于第二个,那就进行交换,如果一个n个元素的数组,我们应该进行n-1轮判断,每一轮判断需要判断n-1-已判断的轮数,如下
void bubble_sort(int* arr, int sz)
{
int i = 0;
int j = 0;
for (i = 0; i < sz - 1; i++)
{
for (j = 0; j < sz - 1 - i; j++)
{
if (arr[j] > arr[j + 1])
{
int tmp = arr[j];
arr[j] = arr[j + 1];
arr[j + 1] = tmp;
}
}
}
}
int main()
{
int arr[10] = { 5, 8, 6, 3, 9, 2, 1, 7 };
int sz = sizeof(arr) / sizeof(arr[0]);
bubble_sort(arr, sz);
int i = 0;
for (i = 0; i < 10; i++)
{
printf("%d ", arr[i]);
}
return 0;
}
如果我们需要这个程序随时都可以被使用,每次使用都不用进入源代码修改代码,还记得我在上面说的变长数组吗?我们可以人为定义数组长度,然后输入数组元素进行判断,就不用深入源代码修改了。如下
#include <stdio.h>
int main()
{
int a = 0;
scanf("%d",&a);
int j = 0;
int i = 0;
int c = 0;
int tmp = 0;
int arr[a];
for (c=0;c<a;c++)
{
scanf("%d",&arr[c]);
}
for (i=0;i<a-1;i++)
for (j=0;j<a-i-1;j++)
{
if (arr[j]<arr[j+1])
{
tmp = arr[j];
arr[j]=arr[j+1];
arr[j+1]=tmp;
}
}
for (c=0;c<a;c++)
{
printf("%d",arr[c]);
}
return 0;
}
6. qsort排序
qsort是一种库函数,包含在stdlib库中
我们也可以使用qsort函数,传入数组地址,数组元素个数,数组元素大小,还有一个比较函数即可完成
7. 杨辉三角
杨辉三角是(a+b)n次方展开后的各项系数,那我们可以用以下代码实现
#include <stdio.h>
int main()
{
int j = 0;
int a[10][10];
int i = 0;
for (i=0;i<10;i++)
{
a[i][i]=1;
a[i][0]=1;
}
for (i=2;i<10;i++)
for(j=1;j<=i-1;j++)
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("%5d",a[i][j]);
printf("\n");
}
printf("\n");
return 0;
}
这样,我们就可以输出一个杨辉三角
8. 二分查找
如果我们在一个数组里面查找一个不为重复的数字的位置,我们可以采用循环的写法,一个一个查找。像这样:
#include <stdio.h>
int main()
{
int a = 0;
scanf("%d", &a);
int arr[10] = { 1,2,3,4,5,6,7,8,9,10 };
int count = 1;
int i = 0;
while (i<10)
{
if (arr[i] != a)
{
count++;
}
if (arr[i] == a)
goto result;
i++;
}
result:
printf("找到数字了,是第%d个",count);
return 0;
}
但是这种方法虽然简单粗暴,但是程序非常复杂,一旦是在几万数据里面找一个数据,那么程序将会耗费大量时间。这样,我们就想到猜数字。
猜数字游戏是这样:对面写好一个数字,然后我们猜测数字并告诉对方让对方判断与真实值的大小关系。比如对面写了一个数字70,那如果你猜30,就会告诉你猜小了,相反90会告诉你猜大了。如果我们锁定范围80到90,那么我们是不是喜欢猜85来确定更精确的范围?这就是二分查找的原理。
告诉你一个数字去查找,那么我会先查找中值,如果目标值比中值小,我就将范围缩小到最小值到中值,以此类推,我就得到了这个程序
#include<stdio.h>
int search(int n,int sz)
{
int left = 0;
int right = sz-1;
int mid = left+(right-left)/2;
while(right>=right);
{
if (mid>n)
right=mid-1;
else if(mid < n)
left=mid+1;
else
return mid;
}
}
int main()
{
int arr[10]={1,2,3,4,5,6,7,8,9,10};
int sz = sizeof(arr[10])/sizeof(arr[0]);
int n = 0;
scanf("%d",&n);
int a=search(n,sz);
printf("%d",a);
return 0;
}
但是这个程序有个不好的地方,就是他只能从小到大排列,或者从小到大排列,不能出现一个错序数组。
好了,文章到这边基本上介绍完了常量与变量,作者制作不易,希望能收获你的喜欢和关注
标签:字符,arr,初始化,int,剖析,sz,数组 From: https://blog.csdn.net/2401_86291060/article/details/142175669