有机反应机理的书...吧 关注:13贴子:101
  • 8回复贴,共1

C/C++的一些疑问与想法

只看楼主收藏回复



IP属地:广东1楼2016-01-23 20:45回复
    左移和右移
    分为算数左移/右移和逻辑左移/右移,在GCC的编译器中有符号数都是采用的算数左移/右移;
    移动的是二进制的补码,左移操作,算数移位和逻辑移位相同;右移时,填入符号位的是算数右移;统一填入0的是逻辑右移;
    由于计算机移动的是反码,所以-1算数右移一位还是-1,-3算数右移一位是-2,负数的移位要特别小心;


    IP属地:广东2楼2016-01-23 21:07
    回复
      常量指针作为返回值
      常量指针在作为返回值或者返回值的一部分时,会发生警告。指针函数返回常量指针时会出现这个问题,而普通函数返回常量指针所指向的常量则不会出现该警告;
      “ [Warning] return discards 'const' qualifier from pointer target type”


      IP属地:广东3楼2016-01-23 21:18
      回复
        递归与迭代
        尾部递归的函数可以很方便地转换成一个简单循环,完成相同的任务。
        例如算n的阶乘:
        /*
        **用递归方式算n的阶乘
        */
        long factorial(int n)
        {
        if(n <= 0)
        return 1;
        else
        return n*factorial(n - 1);
        }
        /*
        **用迭代方法计算n的阶乘
        */
        long factorial(int n)
        {
        int result = 1;
        while(n > 1)
        {
        result *= n;
        n -= 1;
        }
        return result;
        }
        计算斐波拉契数列时,如果用递归可以增加代码的可读性,但是同时也会增加冗余的计算开销。使用迭代不容易看出斐波拉契定义,但是可以显著提高特别是高位的斐波拉契数的计算效率。
        /*
        **利用迭代计算第n个斐波拉契数的值
        */
        long fibonacci(int n)
        {
        long result;
        long previous_result;
        long next_order_result;
        result = previous_result = 1; //初始化第一位
        while(n > 2)
        {
        n -= 1;
        next_order_result = previous_result;
        previous_result = result; //上次计算的结果被本次直接使用
        result = previous_result + next_order_result;
        }
        return result;
        }


        IP属地:广东4楼2016-01-24 14:48
        回复
          链表
          链结数据可以是一个整数,也可以是一个结构体。
          typdef struct{
          /*some data*/
          }Data
          typedef struct Node{
          Data nodeData; /*数据内容*/
          struct Node* nextNode; /*指向下一个链节的指针*/
          }sll_type
          这样实例化sll_type后就可以这样
          sll_type* SL;
          SL = (sll_type)malloc(sizeof(sll_type));
          然后就可以通过“->”访问,此时最好验证malloc函数是否成功申请到了内存。
          ※强制类型转换在C语言中不是必须的


          IP属地:广东6楼2016-02-18 00:27
          回复
            整数拆分成各位
            用递归可以很好地做:
            void decimal_divide(unsigned int value, unsigned int time = 0)
            {
            if(time == 0)
            unsigned int i = 0;
            unsigned int quotient;
            quotient = value / 10;
            if(quotient != 0)
            decimal_divide(quotient, 1);
            arr + i = value % 10;
            i += 1;
            }
            有一个参数有默认值所以参数直接传你要分的整数就行。arr定义成全局变量吧,或者定义成指针函数返回arr,这样的话吧arr在if(time == 0)下面和i一起声明,最后返回一个指针。
            char *decimal_divide(unsigned int value, unsigned int time = 0)
            {
            if(time == 0)
            {
            unsigned int i = 0;
            char arr[10];
            }
            unsigned int quotient;
            quotient = value / 10;
            if(quotient != 0)
            decimal_divide(quotient, 1);
            arr + i = value % 10;
            i += 1;
            return arr;
            }
            还有一个暴力的方法就是用sprintf()函数直接格式化输出成字符串,在用字符串各个位-'0'就是值,同时用判断'\0'来判断转换是否完成。对于浮点数也可以处理,不失是一个好方法。


            IP属地:广东来自Android客户端7楼2016-02-22 02:41
            收起回复
              整数拆分成各位(续)
              上次的程序有诸多错误,比如C语言不支持参数初始化等。所以修改了一下,再增加一种,现在有三种方法。
              法一:顺序表法
              法二:sprintf函数
              法三:链表法
              下面是代码:
              #include <stdio.h>
              #include <stdlib.h>
              #include <math.h>
              typedef struct NODE/*构造一个链表节点*/
              {
              struct NODE *link;
              int value;
              } Node;
              void decimal_divide_1(unsigned int value, char *arr)
              {
              unsigned int value_length, i;/*value_length数字总共位数,i循环标志*/
              value_length = (char)log10(value);/*获取位数*/
              for(i=0;i<=value_length;i++)
              {
              *(arr + value_length - i) = value % 10;/**/
              value /= 10;
              }
              }
              void decimal_divide_2(unsigned int value, char *arr)
              {
              int i = 0;
              sprintf(arr, "%d", value);/*用sprintf将数字打印到arr中*/
              while(arr[i] != '\0')/*字符串的有效值减去‘0’即为真值*/
              {
              arr[i] -= '0';
              i += 1;
              }
              }
              Node *decimal_divide_3(unsigned int num)/*返回值是root地址的值*/
              {
              Node *current = NULL;
              while(num)
              {
              Node *newone;
              newone = (Node*)malloc(sizeof(Node));
              newone->value = num % 10;
              newone->link = current;
              current = newone;
              num /= 10;
              }
              return current;
              }
              链接math.h是用了log()函数计算十进制位数(这个有待考虑)。stdlib.h是因为malloc()函数。stdio.h是sprintf()函数。


              IP属地:广东8楼2016-02-28 08:10
              收起回复