C04,C05,数组指针练习

本文深入探讨了数组和指针的基础知识,包括定义、初始化、访问元素的方式,以及数组与指针之间的联系。同时,文章提供了多个编程示例,帮助读者理解字符串处理、数组操作、指针使用等关键概念。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一、数组

1.定义

数组是一个类型的聚合,是相同类型的聚合,数组的下标永远从0开始。

2.注意

数组初始化只有一次机会,在定义时初始化,如何输入不同类型的数据会发生截取,但不会报错。
int arr[5];数组名只能出现赋值的右边,代表首元素的首地址,不能出现在左边

3.常见问题

(1)数组什么时候确定大小

在编译阶段确定大小

(2)数组存放在哪个位置

数组存放在栈中

(3)什么时候给数组分配内存

运行的时候

(4)数组越界的原理

若大于数组定义的大小,会碰到哨兵位(哨兵位都是int类型,有两个,每个变量都有哨兵位)

(5)数组最多分配多大内存

与栈的大小有关,1M-2M之间。

(6)用sizeof求数组的字节数

sizeof(arr)表示整个数组的字节数
求数组长度的公式:int len =sizeof(arr)/sizeof(arr[0])

4.数组与指针

(1)有两种情况数组名表示整个数组

1.sizeof(arr)代表整个数组的字节大小
2.&arr +1;代表最后一个数组元素的后面

(2)访问数组中的元素

1.通过数组的下标
2.指针int*p=arr *(p+3)=arr【3】

(3)字符数组

1.char crr[5] ''中的为字符
2.若没有充满数组会补上\0
如:char crr[5]=‘abcd’ 默认会加上\0
3.数组的整体赋值只有一次机会,即在初始化的时候,arr[5]=arr4是错误的(字符串存储在ready only data 段,只可以读,不可以修改,详见Linux进程空间图)
在这里插入图片描述

(4)字符串数组

注意`

	char ch1 = 0x00;//0
	char ch3 = 0;//0
	char ch4 = '\0';//0
	char ch2 = '0';//48`

char* str=“yamguang”;字符串,默认有\0;
2.注意%s打印字符串,遇到\0停止
strlen 计算字符串的长度,遇到\0停止,不包括\0

#include<stdio.h>
int main()
{
	char crr[5] = {'a','b','c','d','e'};//字符数组,不会添加\0,所以会出错
	char crr2[5] = "abcd";//字符数组 默认会加\0
	char crr3[] = "abcdef";//字符数组 默认会加\0
	char crr4[10] = "abcdef";
	printf("%s\n",crr);//%s遇到\0停止,所以第一个会出错,没有\0
	printf("%s\n",crr2);
	printf("%s\n",crr3);
	printf("%s\n",crr4);
	return 0;
	}

在这里插入图片描述

(5)指针

1.int p,为野指针,·····
2.指针大小都为4个字节
3.int p=Null和p=Null的区别
①定义一个变量p,其指向的内存里保存的是int类型的数据,定义变量时把p的值赋值为0x00000000,这个过程叫初始化,是在编译的时候进行的。
②int * p; * p=Null;定义一个指针变量,保存int类型的数据,p本身的值不确定,现在p保存的有可能是一个非法的地址。第二行给
p赋值为Null,会报错。改为int i=10; int * p=&i; * p=Null; p指向的内存由原来的10 变为了0,而p本身的值即内存地址没有变。
4.int*p=null;0号地址 不能访问0号地址

(5)例题

//记住
strlen 计算字符串的长度,遇到\0停止,不包括\0*
#include<stdio.h>
#include<string.h>
int main()
{
	char str[100] = "abcdef";
	char *str2 = "abcdef";
	char str3[] = "abcdef";
	char str4[100] = "abcdef\0xyz";//strlen 计算字符串的长度,遇到\0停止,不包括\0*\0之后不计算
	char *str5 = "abcdef\0xyz";
	char str6[] = "abcdef\0xyz";
	char str7[] = "abcdef\n\0";
	char *str8 = "abcdef\n\0";
	printf("%d,%d\n",sizeof(str),strlen(str));//100 6
	printf("%d,%d\n",sizeof(str2),strlen(str2));//4  6
	printf("%d,%d\n",sizeof(str3),strlen(str3));//7 6
	printf("%d,%d\n",sizeof(str4),strlen(str4));//100 6
	printf("%d,%d\n",sizeof(str5),strlen(str5));//4 6
	printf("%d,%d\n",sizeof(str6),strlen(str6));//11 6
	printf("%d,%d\n",sizeof(str7),strlen(str7));//9 7
	printf("%d,%d\n",sizeof(str8),strlen(str8));//4   7
	//printf("%d,%d\n",sizeof(str3),strlen(str3));
	return 0;
}


在这里插入图片描述

二、 练习题

//3.输入两个正数m和n,求其最大公约数和最公倍数

#include<stdio.h>
#include<stdlib.h>
#include<math.h>
int GgreatestCommonDivisor(int m,int n)//求两个数的最大公约数,用辗转相除法
{       int divisor;//定义除数
	    int dividend;//定义被除数
		int res=m%n;//定义余数
	
	if(m>0&&n>0&&m>n)
	{
		dividend =m;//把m的值赋给被除数
		divisor =n;//把n的值赋给除数
		res=dividend %divisor ;
		while(res!=0)
		{
			dividend = divisor ;//把除数的值赋给被除数
			divisor =res;//把余数的值赋给除数
			res=dividend %divisor ;//求余数
		}
		printf("这两个数的最大公约数为:%d\n",divisor );
		printf("这两个数的最小公倍数是:%d\n",m*n/divisor);
	}
	else 
	{
		printf("请输入两个正数:\n");
	}
	return 0;
}

5.求sn=a+aa+aaa+…+aaa…aa之值,其中a是一个数字,n表示a的位数,例如,2+22+222+2222+22222(此时n为5)n由键盘输入

  #include<stdio.h>
  #include<stdlib.h>
  #include<math.h>
  int Summation(int a,int n)
{
	int i;
	double sn=0;
	double b=0;
	b=a;//把a的值赋给b
	for(i=1;i<=n;i++)
	{
		sn+=b;//求和
		b=b*10+a;//表示出aaaa的形式,在原来的基础上扩大十倍再加a
	}
	printf("sn=%f\n",sn);
	return 0;
}

8.输出所有的 水仙花数,水仙花数是指一个三位数,其各位数字立方和等于该数的本身,例如,153是一个水仙花数,因为153=13+53+3^3

#include<stdio.h>
#include<stdlib.h>
#include<math.h>
int fun1(int n)
{
	int a=0;
	int b=0;
	int c=0;
	int y=0;
	int i;
	int j=0;
	for (i=100;i<n;i++)
	{
		
		a=i%10;//求a的值,低位例如,153%10为3,即a为3
		j=i/10;//把a去掉,153/10为15
		b=j%10;//求b的值,15%10为5,即b为5,
		//j=i/10;//去掉b,15/10为 1
		c=j/10;//求c的值
		y=a*a*a+b*b*b+c*c*c;
		if(i==y)
		{
			printf("%d\n",i);
		}
		//return 0;
	}
	return 0;
}

9.一个数恰好等于它的因子之和,这个数即成为完数,例如,6的因子是1,2,3而6=1+2+3,因此6是完数,编程做出1000之内的完数,按下面格式输出其因子:6 its factors 1,2,3

void PefectNumber(int n)
{
	int i=0;
	int j=0;
	int k=0;
	for(i=1;i<n;i++)
	{
		int sum=0;
		for(j=1;j<i;j++)
		{
			if(i%j==0)
			{
				sum+=j;
			}
		}
		if(sum==i)
		{
			printf("%d its factors are \n",i);
		}
	}
}

10.有一个分数数列,2/1,3/2,5/3,8/5,13/8,21/13,求出这个数列的前二十项之和。

int Sum(int n)
{
	float a=2;
	float sn=0;
	float b=1;
	float i;
	for(i=1;i<=n;i++)
	{
		float tmp;
		sn+=(a/b);
		tmp=a;
		a=a+b;
		b=tmp;
	}
	printf("sn==%f\n",sn);
	return 0;
}

例如,若 a 所指数组中的数据最初排列为:1,3,6,5,2,7,8,9,删除偶数后,a 所指数组中的数据为:1,3,5,7,9,返回值为 5。

int Fun(int *arr,int len)
{
	int j = 0;//放奇数的下标
	for(int i = 0;i < len;i++) 
	{
		if(arr[i] % 2 != 0) //奇数
		{
			arr[j] = arr[i];
			j++;
		}
	}
	//Show(arr,j);
	return j;
}

猴子吃桃问题。猴子第一天摘了若干个桃子,当即吃了一半,还不过瘾,又多吃了一个。第二天早上又将剩下的吃掉一半,又多吃了一个。
以后每天早上都吃了前一天的剩下的一半零一个,到第十天早上想再吃的时候,就只剩下一个桃子了,求第一天总共摘了多少桃子。

int NumberOfPeacheas(int n)//吃桃子的天数
{
	int peach=0;//桃子的个数
	int rest=1;//第十天剩余桃子的个数
	int day;
	for(day=n-1;day>0;day--)
	{
		rest=(rest+1)*2;
		peach=rest;
	}
	printf("第一天摘桃子数:%d\n",peach);
	return 0;
}

一个球从100m的高度自由下落,每次落地后反跳回原来高度的一半,再下落 ,再反弹。求它在第十次落地时,共经过多少米,第十次反弹多高

int High(int h,int n)//h代表高度,n代表次数
{
	int i;
	int sum=h;
	int tmp=0;
	for ( i=1;i<=n;i++)//i=3时,代表第三次落地时共经过的路程,代表第二次弹起的高度
	{
		tmp=h/2;
		h=tmp;
		sum=sum+2*h;
	}
	printf("%d\n",i);
	printf("%d\n",h);
	printf("%d\n",sum);
	return sum;
	
}

***求连续子数组的最大和?
{10,-1,9,-100,-10} //18 ===> 打印出开始和结束的下标

int MaxNum2(int *arr,int len)
{
	assert(arr != NULL && len > 0);
	int max = 0x80000000;
	int sum = 0;
	for(int i = 0; i < len;i++)
	{
		//sum = 0;
		if(sum <= 0)
		{
			sum = arr[i];//10
		}
		else 
		{
			sum += arr[i];//9  18  -82
		}

		if(sum > max)
		{
			max = sum;//10  18
		}
	}
	return max;
}

将斐波那契数列写入数组

void Fabonacio(int *arr,int len)
{
	assert(arr != NULL && len > 0);
	arr[0] = 1;
	arr[1] = 1;
	for(int i = 2;i < len;i++)
	{
		arr[i] = arr[i-1]+arr[i-2];
	}
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

我的sun&shine

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

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

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

打赏作者

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

抵扣说明:

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

余额充值