C语言--如何交换两个数与对于递归的理解以及数组赋值的注意事项

目录

 一、swap的理解

二、函数递归

三、数组赋值注意事项


while(scanf("%d",&n) != EOF)重复输入,牛客IO题。

 一、swap的理解

C语言指针值传递和地址传递_c语言地址传递-CSDN博客icon-default.png?t=N7T8https://blog.csdn.net/lanhuazui10/article/details/107144276交换两个数:

 发现这样并没有交换a和b的值,只是交换了x和y的值,这是因为:

        //当实参传递给形参的时候,形参是实参的一份临时拷贝
        //对形参的修改不能改变实参

       实参与形参是什么? 

        实参:真是传递给函数的参数,在进行函数调用时,必须有确切的值;形参:指的是函数名括号中的变量,因为形参只在函数调用的时候才实例化(分配内存单元)。形参在函数调用完成之后就自动销毁(局部变量),因此形参只在函数中才有效。形参实例化之后相当于实参的一份临时拷贝。

那如何交换a和b?

交换方法:

//形参 - 形式参数
//当实参传递给形参的时候,形参是实参的一份临时拷贝
//对形参的修改不能改变实参
void Swap(int* x, int* y)
{
	int z = 0;
	z = *x;
	*x = *y;
	*y = z;
}
int main()
{
	int a = 0;
	int b = 0;
	scanf("%d%d", &a, &b);
	printf("交换前:a = %d b = %d\n", a, b);
	Swap(&a, &b);//实参
	printf("交换后:a = %d b = %d\n", a, b);
	return 0;
}

 注意:int*接收int,int**接收int*

 但是为什么下面这种不用传地址?见调试图:,ret会临时拷贝到寄存器中,再返回,所以对于内存是否销毁释放无关。

 扩展:printf函数:

注意:printf函数的返回值是:

返回值

        如果成功,则返回写入的字符总数,否则返回一个负数。


int main()
{
	printf("%d\n", 43);//43
	printf("%d", printf("%d", printf("%d", 43)));
	/*当执行最外层的printf的时候,其打印内容是printf("%d",43)的返回值,
	而在最外层printf函数得到printf("%d",43)的返回值之前,会先执行printf("%d",43)
	也就是会先打印 43
	43共2个字符,所以printf("%d",43)返回整型2*/
	//printf函数返回值返回的是打印的字符的个数
	return 0;
}

特别注意的是:printf函数处理方式 从右至左 

二、函数递归

求5的阶乘 

/*利用递归函数实现5!*/
/*
5! = 5*4*3*2*1
5! = 5*4!
4! = 4*3!
3! = 3*2!
2! = 2*1!

*/
int fac(int num)//fac(4)//fac(3)//fac(2)//fac(1)
{
	if (num == 0 || num == 1)
	{
		return num;//return 1//即fac(1)的结果是1,递归完开始返回//
	}
	else 
	{
		return  num * fac(num - 1);//5*fac(4)
		//4*fac(3)
		//3*fac(2)
		//2*fac(1)
		//之前没走完的函数接着走,返回2*1 = 2
		//返回3*2
		//返回4*3*2
		//返回5*4*3*2
	}
}//当fac(1)返回值后到了这里,fac(1) == 1
int main()
{
	int ret = fac(5);
	printf("%d\n", ret);
	return 0;
}

三、数组赋值注意事项

 去除数组中的重复数字:(必须使用qsort)直接结合的力扣的题

#include<stdio.h>
#include<assert.h>
int removeDuplicates(int* nums, int numsSize) 
{
    assert(nums);
    if (numsSize == 0)
    {
        return 0;
    }   
    int slow = 0;
    for (int fast = 0; fast < numsSize - 1; fast++)
    {
        if (nums[fast] != nums[fast + 1])
        {
            slow++;
            nums[slow] = nums[fast + 1];
        }
    }
    return slow + 1;
}
int cmp(const void* a, const void* b)
{
    return *(int*)a - *(int*)b;
}
int main(int argc,const char* argv[])
{
	int arr[] = { 1,1,2,2,2,3,3,4,4,5,5,5,2,5,6,1,3,2 };
	int sz = sizeof(arr) / sizeof(arr[0]);
    qsort(arr, sz, sizeof(int), cmp);
    int ret = removeDuplicates(arr, sz);
    int i = 0;
    for (i = 0; i < ret; i++)
    {
        printf("%d ", arr[i]);
    }
	return 0;
}

通过赋初值的方式给一维字符数组赋字符串
1、用给一般数组赋初值的相同方式给一维字符组赋初值
        char str[10]={‘s’,‘t’,‘r’,‘i’,‘i’,‘n’,‘j’,’\0’}
        字符数组str共有10个元素,但str作为字符串,其长度为7,虽然最后一个字符是‘\0’,但它并不是结束标识因为系统会自动的给其分配一个结束标识。
2、在赋值时直接赋字符串常量
        char str[10]={“string”};
        习惯上省略花括号
        char str[10]=“string!”(这种方式会自动给字符串的末尾添加结束标识,但需要注意的是字符串数组的长度一定要比赋值的长度多一个)

注意:长度是存在区别的


用一维字符数组存放字符串-CSDN博客icon-default.png?t=N7T8https://blog.csdn.net/m0_46170663/article/details/104295429

 注意下图情况的数组分布:所以数组中必须确定的是列数

为什么多维数组必须声明列数,而对行数没有要求???_数组函数在定义时要制定行列吗-CSDN博客icon-default.png?t=N7T8https://blog.csdn.net/shouxindejava/article/details/21331107#:~:text=%E8%BF%99%E4%B9%9F%E5%B0%B1%E8%A7%A3%E9%87%8A%E4%BA%86%E4%B8%BA%E4%BB%80%E4%B9%88%E5%A3%B0%E6%98%8E%E5%A4%9A%E7%BB%B4%E6%95%B0%E7%BB%84%E7%9A%84%E6%97%B6%E5%80%99%E5%AF%B9%E8%A1%8C%E6%95%B0%E6%B2%A1%E6%9C%89%E8%A6%81%E6%B1%82%EF%BC%8C%E4%BD%86%E6%98%AF%E5%BF%85%E9%A1%BB%E5%A3%B0%E6%98%8E%E5%88%97%E6%95%B0%E3%80%82%20%E5%9B%A0%E4%B8%BA%E5%A6%82%E6%9E%9C%E4%B8%8D%E5%A3%B0%E6%98%8E%E5%88%97%E6%95%B0%EF%BC%8C%E5%BD%93%E6%89%A7%E8%A1%8Carray,%2B%201%3B%E8%BF%99%E6%A0%B7%E7%9A%84%E6%93%8D%E4%BD%9C%E7%9A%84%E6%97%B6%E5%80%99%EF%BC%8C%E6%95%B0%E7%BB%84%E4%B8%8D%E7%9F%A5%E9%81%93%E6%8C%87%E9%92%88%E8%AF%A5%E7%A7%BB%E5%8A%A8%E5%A4%9A%E5%B0%91%E4%BD%8D%E3%80%82

 

扩展:数组名的注意事项

 数组名表示首元素的地址,但是有两个例外:

1.sizeof(数组名),这个数组名表示整个数组

2.&数组名,这个数组名也表示整个数组,取出的是整个数组的地址

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值