1,一维数组的基础
1.1数组的概念和定义方法
数组,批量存储数据 : 类型 数组名 [ 数组长度 ] Tip :数组长度必须是常量,不允许是变量,数组长度不能是0也不能是负数
//错误写法
int size = 0 ;
int arr [size] ;
scanf("%d",&size) ;
//正确写法
int arry [10];//最大数组下标是数组长度减一,因为数组在分配内存的时候是从0开始
int arr1 ['A'];//数组长度为65,ASIIC值是65,数组长度为65
printf("数组名:%p\n",arry);//这个和下面的打印结果是一样的,打印arry实际上打印的是数组的首地址
printf("数组名:%p\n",&arry[0]);//这个和上面的打印结果是一样的
//效果如下图所示
数组的首地址可以用数组名来替代,( 数组名代表的就是数组的首地址 )
1.2创建数组并且初始化
int arr2 [3] = {1,2,3};//{}的数据作为初始化,申请一段内存,把数组一次放进去
int arr3 [] = {1,2,3,4};//在确定数组的具体内容时,不写数组的长度也没关系,数组会默认推导数组长度是3
int arr 4[3] = {1};//数组剩余的两个数默认是0
printf("%d\t%d\t%d\n",arr4[0],arr4[1],arr4[2]);
结果如下图所示:
int arr5[3];//错误代码
arr5[3] = {1,2,3}; //错误写法
1.3,使用数组
使用数组名加下标的方式去访问数组,也可以当作普通变量,只是变量名称比较特殊
数组名 [下标]
2,一维数组的基本操作(增,删,改,查,排序)
//求和
int nums [] = {100,200,300};
int sum = 0 ;
for(int i = 0 ; i < 3 ; i ++ )
{
sum += num[i];
}
printf("sum=%d".sun);
2.1 for 循环的增删改查排序
#include<stdio.h>//用户输入数据,-1为结束标志
int main()
{
printf("input nums:\n");
int arr[100] = { 0 };
int count = 0;
for (int i = 0; i < 100; i++)
{
scanf_s("%d", &arr[i]);
if (arr[i] == -1)
break;
count++;
for (int j = count - 1; j > 0; j--)//实现数组的排序count-1是数组下标的最大值
{
if (arr[j] < arr[j - 1])
{
int temp = 0;
temp = arr[j - 1];
arr[j - 1] = arr[j];
arr[j] = temp;
}
else
{
break;
}
}
}
printf("arr: ");
for (int i = 0; i < count; i++)
{
printf(" %d\t", arr[i]);
}
printf("\n");
printf("count:%d\n", count);
printf("what arr[] do you want to find?:");//这种方法有缺陷,会找到实际数据之外的数值0或者-1
int findpos = 0;
scanf_s("%d", &findpos);
printf("find:%d\n", arr[findpos]);//不够精确
printf("what arr[] do you want to del?:");//依据数组下标实现数组的指定某个数据的删除
int delpos = 0;
scanf_s("%d", &delpos);
for (int i = delpos; i < count; i++)//删除数据思想,找到待删除数据的下标,
{
arr[i] = arr[i + 1];//用后面的数据去覆盖掉前面的数据
}
count--;//实现真正的删除
printf("afterdel: ");
for (int i = 0; i < count; i++)
{
printf(" %d\t", arr[i]);
}
printf("\nwhat arr[] do you want to modify?:");//修改数据
int ipos = 0;
scanf_s("%d", &ipos);
int inum = 0;
printf("\ninum: ");
scanf_s("%d", &inum);
arr[ipos] = inum;
printf("\naftermodify: ");
for (int i = 0; i < count; i++)
{
printf(" %d\t", arr[i]);
}
return 0;
}//代码执行正确结果
2.2 while循环的排序查找和删除
#include<stdio.h>//用户输入数据,-1为结束标志
#include<stdbool.h>
int main()
{
printf("input nums:\n");
int arr[100] = { 0 };
int count = 0;
int Curside = 0;
while (true)
{
int key = 0;
scanf_s("%d", &key);
if (key == -1)
break;
arr[Curside++] = key;
count++;
for (int i = Curside - 1; i > 0; i--)
{//数组下标做了i+n或者i-n的操作,就需要考虑临界值
if ( arr[i]<arr[i-1])
{
int temp = i;
arr[i] = arr[i - 1];
arr[i - 1] = temp;
}
else
{
break;
}
}
}
printf("your arr: \n");
for (int i = 0; i < Curside; i++)
{
printf("%d ", arr[i]);
}
printf("\nnums of arr:\n%d\n",count);//可以避免出现搜出的数值是0的情况
int pos = -1;
int Pos = 0;
printf("what arr[] do you want to find?");
scanf_s("%d",&Pos);
for (int k = 0; k < Curside; k++)
{
if (arr[k] == arr[Pos])
{
pos = arr[Pos];
break;
}
}
printf("\nfind:%d\n",pos);
return 0;
}
2.3 循环中的错误分析
2.4,冒泡排序法
#include<stdio.h>
int main()
{
//冒泡排序法
int arr[10] = { 0 };
printf("请输入数据\n");
for (int i = 0; i < 10; i++)
{
scanf_s("%d",&arr[i]);
}
int len = 10;
for (int i = 0; i < len; i++)//遍历区间上的每个值,区间上一共10个数字就需要遍历十次。
{
//第一次,i=0的时候把最大值找出来,第二次,i=1的时候找到第二大的数字
for (int j = 0; j < len-1; j++)//如果用j<len,用j<len-1-i可以优化算法,优化计算次数
{
if (arr[j] > arr[j + 1])//条件判定的时候会造成数据溢出,arr栈堆损坏,因为会出现arr[9]>arr[10]的情况
{
int temp = 0;
temp = arr[j+1];
arr[j + 1] = arr[j];
arr[j] = temp;
}
}
}
printf("\narr:");
for (int i = 0; i < len; i++)
{
printf("%d\t",arr[i]);
}
return 0;
}
3,有序数组的特殊操作
3.1二分查找法(双指针法)
#include<stdio.h>
int main()
{ //二分查找法,每次找的是中间的位置
//输入数据
int arr[100] = { 0 };
int count = 0;
printf("input arr:");
for (int i = 0; i < 100; i++)
{
scanf_s("%d", &arr[i]);
if (arr[i] == -1)
break;
count++;
}
//对数据进行排序
for (int i = 0; i < count; i++)
{
for (int j = 0; j < count - 1; j++)
{
if (arr[j] > arr[j + 1])
{
int temp = 0;
temp = arr[j + 1];
arr[j + 1] = arr[j];
arr[j] = temp;
}
}
}
//数据的输出
printf("\nafter arrange in order:");
for (int i = 0; i < count; i++)
{
printf("%d\t", arr[i]);
}
int rignt = count - 1;
int left = 0;
//二分查找法-1,下标查找法
int fpos = 0;
printf("\ninput fpos:");
scanf_s("%d", &fpos);
while (left <= rignt)//用=是因为如果经过循环出现left=right的情况(即要查找的数据的下标是最后一位数字),会直接跳过循环,无法输出查找值
{
int mid = (left + rignt) / 2;
if (fpos == mid)
{
printf("find pos:%d", arr[fpos]);
break;
}
else if (fpos < mid)
{
rignt = mid - 1;//mid 要减去 1 是因为mid的值本身不符合要求,直接取mid的前一位(右值)作为数组的下标参与下一轮循环
}
else
{
left = mid + 1;//mid 要加上 1 是因为mid的值本身不符合要求,直接取mid的后一位(左值)作为数组的下标参与下一轮循环
}
}
//二分查找法-2,数据查找法
int Posdata = 0;
printf("\ninput Posdata:");
scanf_s("%d", &Posdata);//输入数组里不存在的数值,结果就是-1
int pos = -1;
while (left <= rignt)
{
int mid = (left + rignt) / 2;
if (arr[mid] == Posdata)
{
pos = mid;
break;
}
else if (arr[mid] < Posdata)
{
left = mid + 1;
}
else
{
rignt = mid - 1;
}
}
printf("pos:%d", pos);
return 0;
}
3.2归并算法
#include<stdio.h>
int main()
{
int arr1[5] = {0,2,4,6,8};
int arr2[6] = {1,3,5,7,9,11};
int len1 = 5;
int len2 = 6;
int i = 0;
int j = 0;
int arry [11] = {0};
int count = 0;
while (i < len1 && j < len2)
{
if (arr1[i]<arr2[j])
{
arry[count++] = arr1[i++];
}
else
{
arry[count++] = arr2[j++];
}
}
while (i < len1)
{
arry[count++] = arr1[i++];
}
while (j < len2)
{
arry[count++] = arr2[j++];
}
for (int k = 0; k < count; k++)
{
printf("%d\t", arry[k]);
}
return 0;
}
4,字符数组操作字符串
4.1字符打印
//字符数组操作字符 和数字类数组没区别
char cNum[3] = { 'A','B','C' };
for (int i = 0; i < 3; i++)
{
printf("%c", cNum[i]);
}
printf("\n");
printf("%s\n", "ILoveyou");
//%s的工作方式,从首地址开始打印到\0;
//1.字符打印
char str1[] = { 'A',' ','B','\0','D','E' };
printf("%s\n", str1);//从字符串的首地址开始打印直到打印到'\0'结束
printf("%s\n", &str1[0]);//打印从str1[0]为起始,打印到'\0'结束,也就是打印出A B
printf("%s\n", &str1[2]);//打印从str1[2]为起始,打印到'\0'结束,打印出B
4.2字符串给字符数组作初始化
char str2[]="Iloveyou";//数组的长度是9
//如何求出字符串的数组长度
printf("数组长度:%zd\n",sizeof(str2)/sizeof(char);
4.3没有’ \0’的打印会怎么样
char str3[]={'a','b','c'};
printf("%s\n",str3);
4.4字符串中的输入输出函数
字符串的输入scanf_s和gets_s函数
//1,输入字符串
char str4[100];
scanf_s("%s",str4,100);//2,只接受空格之前的内容
printf("input:%s\n",str4);
//3,gets函数可以接受带空格的数据,可以忽略空格
get_s(str4,100);
//和gets_s相对应的也有打印函数puts
puts("自带换行");//自带换行符
字符串跳过现象:
输入完数据后按下回车键,\n转义字符仍然在缓冲区里,会送给字符变量DD,所以要想办法把换行符给清除掉
-
写两次scanf函数
-
getchar() 输入字符的函数
while(getchar()!='\n')//读取转义字符,直到读取转义字符结束
4.5字符串的常用操作
//求一个字符串的可见长度
int count = 0;
char str[]="I LOVE YOU"
while(str[count]!='\0')//与while(str[count])效果是一样的
{
count++;
}
printf("可见长度:%d",count);
//字符串做赋值
char str1[]="I love you";
char str2[]="";
str2 = str1;//错误写法,字符串函数无法直接赋值
int i = 0;
while (str1[i]!='\0')
{
str2 [i] = str1 [i];
i++;
}
str2[i] = '\0';
printf("%s",str2);
return 0;
//字符串比较过程
//"1234"
//"13"
//从左往右依次拿出一个字符进行比较,一旦字符不同,字符大小就确定
//'1'=='1'
//'2'<'3' 所以"1234"<"13"
//汉字打印
//一个汉字占用两个字符
char str5[]="我";
//打印方法一:
printf("%c%c\n",str5[0],str[1]);
//打印方法二:
printf("%c\n",str[0]);
printf("%c\n",str[1]);
//汉字的编码是一个负数
printf("汉字编码是一个负数:%d\n", data[0]);