C语言数组指针类型的题

img

为什么输出是5 4,括号优先级更高也可以在输出语句优先输出吗??

这个代码的运行结果是不确定的(不同编译器输出结果不同)
原因在于,函数参数求值的顺序是编译器未定义行为,也就是说*p++和(*p)++谁先执行,不确定。

printf 的参数 是 从左往右 入栈, 从右往左出栈计算的
所以先 (*p)++ , 括号内取值就是 4,因为++在后,所以结果 为 4 , 然后p指向的第一个元素值 自增,从 4 变为 5
然后算 *p++, 结果 等于 *p, p指向的值现在为 5
最后打印 5 4

  • 这个问题的回答你可以参考下: https://ask.csdn.net/questions/7458042
  • 我还给你找了一篇非常好的博客,你可以看看是否有帮助,链接:C语言既有高级语言又有低级语言的特点,但为什么它不是低级语言呢?
  • 除此之外, 这篇博客: C语言中的这些经典题目你都会了吗?【一文带你回顾经典】【全程高能】中的 💫关于递归的描述错误的是:( ) 部分也许能够解决你的问题, 你可以仔细阅读以下内容或跳转源博客中阅读:
  • A.存在限制条件,当满足这个限制条件的时候,递归便不再继续

    B.每次递归调用之后越来越接近这个限制条件

    C.递归可以无限递归下去

    D.递归层次太深,会出现栈溢出现象

     错误的回答是c选项,递归需要两个条件,第一个是必须要有限制条件,每次递归调用时越来越接近这个条件,所以c选项自动排除,不能是死递归,第四个选项,层次太深的话是会出现栈溢出的现象也是对的

    int Fun(int n)      
    { 
      if(n==5)   
        return 2;     
      else     
        return 2*Fun(n+1);      
    }

    A.2

    B.4

    C.8

    D.16

    正确答案为D

    传参为2,2不等于5,返回2*fun(3),3不等于5,返回2*fun(4),4不等于5,返回2*fun(5),5等于5,返回2,开始回带,2*fun(2)为4,2*fun(4)为8,2*fun(8)为16,所以最后返回的结果为16

     15cb3444d80746ba8c3e56f4e557037c.png

    用递归的函数的思想是大事化小,并且有一个限制条件,定义一个数,实现打印函数,如果要打印1234这个数, 1234打印4最好打印,可以分为  (123) 4    (12)3 4    (1)2 3 4

    这样就把大事化小了,实现:设定条件,如果大于9,两位数的就拆分,一位数就停下来,,1234/10,调用123,123大于9,123/10,调用12,12大于9,12/10,1,1小于9,开始会带,打印1%10为1,然后2,3,4

    #include<stdio.h>
    int print(int n)
    {
    	if(n>9)
    		print( n / 10);
    	printf("%d", n % 10);
    	return 0;
    }
    int main()
    {
    	int n = 0;
    	scanf("%d", &n);
    	print(n);
    	return 0;
    }

    求n的阶乘有个公式,如果求5的阶乘,那么相当于5*4的阶乘,但是如果是1的时候就不是了,所以实现:当n小于等于1时,返回1,否则返回n*fac(n-1),这件事递归实现,非递归的方式就是利用循环让每个乘积到ret中,最后返回ret就是和

    //递归方式
    #include<stdio.h>
    int fac(int n)
    {
    	if (n <= 1)
    		return 1;
    	else
    		return n* fac(n - 1);
    }
    int main()
    {
    	int n = 0;
    	scanf("%d", &n);
    	int ret = fac(n);
    	printf("%d", ret);
    	return 0;
    }
    //迭代方式-非递归
    #include<stdio.h>
    int fac(int n)
    {
    	int ret = 1;
    	int i = 0;
    	for (i = 1; i <= n; i++)
    	{
    		ret *= i;
    	}
    	return ret;
    }
    int main()
    {
    	int n = 0;
    	scanf("%d", &n);
    	int ret = fac(n);
    	printf("%d", ret);
    	return 0;
    }

    strlen是求字符串的长度,而字符串的长度是由\0来标识的,只要遇到\0就停止,递归实现:如果字符串中不等于\0时,就返回一个1+n+1,因为可以让它指向下一个字符,当等于\0时,返回0,迭代实现,与上面同理,只不过需要定于个ret来接受,如果不等于\0,加加,让字符也加加指向下一个

    //递归实现
    #include<stdio.h>
    int fac(char* n)
    {
    	if (*n != '\0')
    		return 1 + fac(n + 1);
    	else
    		return 0;
    }
    int main()
    {
    	char arr[] = "abcdef";
    	int ret = fac(arr);
    	printf("%d", ret);
    	return 0;
    }
    //非递归
    #include<stdio.h>
    int fac(char* n)
    {
    	int ret = 0;
    	while (*n != '\0')
    	{
    		*n++;
    		ret++;
    	}
    	return ret;
    }
    int main()
    {
    	char arr[] = "abcdef";
    	int ret = fac(arr);
    	printf("%d", ret);
    	return 0;
    }

    内容实现:

    编写一个函数 reverse_string(char * string)(递归实现)

    实现:将参数字符串中的字符反向排列,不是逆序打印。

    要求:不能使用C函数库中的字符串操作函数。

    比如:

    char arr[] = "abcdef";

    逆序之后数组的内容变成:fedcba

    这个题目的要求是将字符串反向打印,而不是逆序,而且不能使用c函数中的字符串操作函数

    既然要反向,那么需要交换两个字符的位置,然后打印即可,递归实现:求一个字符串“abcdef”,在字符串里的是abcdef\0,大事化小,先把a放到临时变量里,然后把f放到a里,然后把\0放入f中,让bcde\0变成新的字符串,而调用自己的时候需要设定条件,如果中间剩下一个的时候就不需要交换了,所以大于等于2的时候调用

    int my_strlen(char* string)
    {
    	int ret = 0;
    	while (*string != '\0')
    	{
    		ret++;
    		string++;
    	}
    	return ret;
    }
    void reverse(char* string)
    {
    	int len = my_strlen(string);
    	char tmp = *string;
    	*string = *(string+len-1);
    	*(string + len - 1) = '\0';
    	if (my_strlen(string + 1) >= 2)
    		reverse(string + 1);
    	*(string + len - 1) = tmp;
    }
    int main()
    {
    	char arr[] = "abcdef";
    	reverse(arr);
    	printf("%s", arr);
    	return 0;
    }

    内容实现

    写一个递归函数DigitSum(n),输入一个非负整数,返回组成它的数字之和

    例如,调用DigitSum(1729),则应该返回1+7+2+9,它的和是19

    输入:1729,输出:19

    求一个非负整数每个位数之和,如1729可以分成 172 + 9,  17 + 2 + 9 , 1 +7+2+9,递归实现,如果是一位数的时候,返回这个数,如果大于一位数,返回 除以10加上摸10的值,1729/10  172  递归递下去,归回来的每位数加上取余的数

    int fac(unsigned int n)
    {
    	if (n > 9)
    	{
    		return fac(n / 10) + n % 10;
    	}
    	return n;
    }
    int main()
    {
    	unsigned int n = 0;
    	scanf("%d", &n);
    	int sum = fac(n);
    	printf("%d", sum);
    	return 0;
    }

    内容实现

    编写一个函数实现n的k次方,使用递归实现。

  • 您还可以看一下 张勇老师的初级到CS开发高手通用权限管理系统全程实录课程中的 讲解和推进客户端智能升级流程小节, 巩固相关知识点

以下内容部分参考ChatGPT模型:


这是因为数组名和指针的本质不同。

数组名是数组在内存中的起始地址,是一个常量指针,所以不能被修改。

而指针变量是一个变量,可以被赋值修改指向的地址。

所以在代码中,a是一个数组名,指向数组的第一个元素,b是一个指针变量,指向数组的第二个元素。在语句b=a时,b指向的元素被赋值为a所指向的元素,即数组的第一个元素,所以输出b指向的元素时,输出的是数组的第一个元素,即5。在语句b++时,b指向了数组的第三个元素,即4,所以输出b时,输出的是数组的第三个元素,即4。

示例代码:

#include <stdio.h>

int main() {
    int a[3] = {5, 3, 4};
    int *b = a + 1;
    *b = *a;
    printf("%d %d", *b, *(b + 1));
    return 0;
}

如果我的建议对您有帮助、请点击采纳、祝您生活愉快