这些小活动你都参加了吗?快来围观一下吧!>>
电子产品世界 » 论坛首页 » 嵌入式开发 » 软件与操作系统 » 【学习会】一起学习C语言之C了又C。。。

共16条 2/2 1 2 跳转至
院士
2018-05-21 10:42:45     打赏
11楼

麻烦问下楼主,我扫活动那个微信二维码怎么显示过期了呢?


菜鸟
2018-05-22 22:37:46     打赏
12楼

7.4 数据类型转换——有符号整数与无符号整数

       (P230)将有符号整数转换为位数相同的或位数更多的无符号整数时,如果该有符号整数不为负数,则数值不会发生变化。否则,如果无符号整数的位数较大,则先将有符号整数提升为与无符号整数长度相同的有符号整数,然后再与无符号整数类型可表示的最大数加1后的值相加,将有符号整数转换为无符号整数。将整数类数据类型转换为位数更少的无符号整数类型时,除以比位数较少的数据类型可表示的最大无符号数大1的数,所得的非负余数就是转换后的值。将整数类数据类型转换为位数更少的有符号整数时,以及将无符号整数转换为位数相同的有符号整数时,如果不能正确表示转换后的值,则此时的操作由编译器决定。

8.1 宏的弊端

       (P238)函数式宏在使用上必须要小心谨慎,例如对于宏定义为

#define sqr(x) ((x) * (x))

  当使用上面的宏sqr(x++)时,展开后为((x++)*(x++)),即每次展开,x的值都会自增两次,这就是使用函数式宏的副作用。(说句题外话,今天看《Effective C++》,里面对C语言的宏给出的建议是能少用就少用,并建议用const修饰的全局变量代替宏常量定义,用inline修饰函数来代替函数式宏,可见这个宏真是弊端不小。。。)

8-3 关于枚举

       (P247)枚举因为个人不常用,所以接触的比较少。首先枚举名不是类型名,类型名为enum+枚举名,而且枚举值实际上对应着int值,多个枚举值可以对应同一个int值。

   这一章中后面还涉及到了重定向的相关知识,留到后面文件处理部分讨论输入输出流的时候再讨论吧,第八章K.O。



菜鸟
2018-05-27 03:03:22     打赏
13楼

9-1 字符数组初始化

P269对于字符数组,除了初始化赋值的时候,不能将数组的初始值或字符串直接赋予数组变量,在后面修改的时候只能采用依次赋值的方式。这里引用一下书后的练习,

#include "stdafx.h"

 

int main()

{

    char s[] = "ABC\0DEF";

    printf("%s\n", s);

    return 0;

}

这里输出的结果是ABC,而通过断点观察到s字符串实际上存储了全部的数据ABC\0DEF\0,这说明\0对于字符串的终结作用在字符串赋值的时候并没有体现出来,换句话说,手工输入的\0转义字符在字符串的存储中并没有任何作用,在数组初始化的时候仍旧会自动在字符串结尾加上\0作为结束。但当字符串输入到printf等格式化输入输出函数中时,printf函数会自动识别\0转义字符,从而将字符串在ABC后面直接截断,所以得到的输出只有ABC\0

9-1 数组名就是数组首地址

       P271书中说到了在实用scanf函数试图将键盘输入的数据存入到char name[48]中时,在给如目标地址时,不能使用&name而要使用name。这是因为对于char name[48]而言,这是一个char型数组。此时name代表的就是这个数组的第一个元素存储的地址,这和声明一个变量int a之后将&a传入scanf是一样的。(在这里,name也等价于&name[0])。

 

10 printf打印变量地址

       P289表示对象地址的转换说明符是%p,不过经过测试,发现%x也可以用于输出(十六进制)地址的转换说明符。因为&取址得到的实际上就是一个数字。

 

10.1 register修饰的对象取址

       P301对于使用register关键字声明的寄存器对象,不能通过&符号进行取址,因为寄存器通常位于CPU内,所以并不存在地址一说,所以出现&符号进行取址的程序时编译器会报错。

 

10.2 数组名在什么时候不被视为指向起始元素的指针

       这里mark一下,当sizeof(数组)时返回的是整个数组的长度而不是第一个元素占得大小;当作为取址符&的操作数出现时,&数组名不是指向起始元素的指针的指针,而是指向数组整体的指针。

10.3 a[b]b[a]一样么?

       呃,这个结果是一样的,各位可以试试,为什么我也不知道,只是偶然在一本书中看到过,但大家尽量还是好好写代码,毕竟这不是国际C语言混乱代码大赛(IOCCC, The International Obfuscated C Code Contest)。



院士
2018-05-28 09:12:44     打赏
14楼

楼主13楼里面有笔误,宏定义与inline关键字修饰的函数。楼主您写成了 incline~~(不失礼貌的微笑)


院士
2018-05-28 09:13:47     打赏
15楼

关于枚举类型,我在IAR环境下做过测试,其是变长的。

当值小于255时,其就是单字节长度,但是大于255时,其用双字节表示。


菜鸟
2018-06-06 15:00:29     打赏
16楼

1. 请在控制台实现如下功能。

*

**

***

****

答:因为在控制台中,不存在半字符操作(最小显示单位就是字符,一个汉字由占据两个字符的位置),所以我并没有想出半字符缩进的实现方式。

程序:

#include "stdafx.h"

int main()

{

    printf("   *   \n");        //

    printf("  * *  \n");

    printf(" * * * \n");

    printf("* * * *\n");

    return 0;

}

结果截图:

2.效果与第一题结果相同,但是打印的行数由程序运行时确定。

例如:

程序运行时输入2

*

**

程序运行时输入3

*

**

***

答:

程序源码:

#include "stdafx.h"

#include <stdio.h>

void show_stars(int num);

 

int main()

{

    // 变量定义与初始化

    int line_num = 0;  

 

    // 打印输入提示语句

    printf("Please input the lines you wish to show and\n"\

        "press Enter to confirm:");

    // 接收行数变量

    scanf("%d", &line_num);

 

    // 调用打印星号函数

    show_stars(line_num);

 

    return 0;

}

 

void show_stars(int num)

{

    // 判定输入的行数是否为正数,不是则给出错误提示

    if (num <= 0){

        printf("Please input a valid integer that is bigger\n"\

            "than 0 and retry!");

    }

    else{

        // 循环中逐行打印星号

        for (int i = 0; i < num; i++) {

            // 对于第i行,该行的第一个星号之前需要键入空格

            for (int j = 0; j < num - 1 - i; j++) {

                printf(" ");

            }

            // 之后输入星号和空格的组合

            for (int j = 0; j < i; j++) {

                printf("* ");

            }

            // 最后补上每行最后一个星号以及换行符

            printf("*\n");

        }

    }

}

结果截图:

3.请实现2个函数完成BCD码到二进制格式的转换和二进制到BCD转换功能,并自己编写测试。

答:

程序源码:

#include <stdio.h>

#include <stdlib.h>

#include <string.h>

 

int Bin2BCD(char *str);

int BCD2Dec(char *str);

int main(void)

{

    int mode = 0;

    int num_length = 0;

    printf("Please Input the length you wish to convert:");

    scanf("%d", &num_length);

    char *str_input = new char[num_length];

    char *str_output = new char[num_length];

    printf("BCD2Bin press 1 and Bin2BCD press 2 and press Enter to confirm:");

    scanf("%d", &mode);

    if (mode == 1) {

        printf("Now Input the 8421 code you wish to convert to binary:");

        scanf("%s", str_input);

        printf("The result is:\n%s\n", _itoa(BCD2Dec(str_input), str_output, 2));

    }

    else if(mode == 2) {

        printf("Now Input the binary you wish to convert to 8421 code:");

        scanf("%s", str_input);

        printf("The result is:\n%s\n", _itoa(Bin2BCD(str_input), str_output, 2));

    }

    else {

        printf("Wrong Code!");

    }

 

    return 0;

}

 

int Bin2BCD(char *str)

{

    int num_return = 0;

    char *str_local = str;

    while (*str_local != '\0') {

        num_return = (num_return << 1) + (*str_local - 0x30);

        str_local++;

    }

    int num_return2 = 0;

    int index = 1;

    while (num_return != 0) {

        num_return2 += num_return % 10 * index;

        num_return /= 10;

        index *= 16;

    }

    return num_return2;

}

int BCD2Dec(char *str)

{

    char *str_local = str;

    char str_4[4] = { 0 };

    int num_return = 0;

    while (*str_local != '\0') {

        strncpy(str_4, str_local,4);

        num_return = 10 * num_return + 8 * (str_4[0] - 0x30) + 4 * (str_4[1] - 0x30) +

            2 * (str_4[2] - 0x30) + 1 * (str_4[3] - 0x30);

        str_local += 4 * sizeof(char);

    }

    return num_return;

}

结果图:



4.请利用宏来实现3题功能。

答:

程序源码:

#include <stdio.h>

#include <stdlib.h>

#include <string.h>

 

#define ToDec(x)    (x%10 + (x/10%10)*2 + x/100%10*4 + x/1000*8)

#define BCD2Bin(x)   _itoa(ToDec(x%10000) + ToDec(x/10000)*10, str_output, 2)

#define Bin2BCD(x)   _itoa((ToDec(x)>10)?ToDec(x)/10*16+ToDec(x)%10:ToDec(x),str_output,2)

int main(void)

{

    int mode = 0;

    int str_input;

    char str_output[8];

    int x = 10101;

    int y = ToDec(x);

    int z = ToDec(x % 1000) + ToDec(x / 1000) * 10;

    printf("BCD2Bin press 1 and Bin2BCD press 2 and press Enter to confirm:");

    scanf("%d", &mode);

    if (mode == 1) {

        printf("Now Input the 8421 number you wish to convert to binary:");

        scanf("%d", &str_input);

        printf("The result is:\n%04s\n", BCD2Bin(str_input));

    }

    else if(mode == 2) {

        printf("Now Input the binary you wish to convert to 8421 code:");

        scanf("%d", &str_input);

        printf("The result is:\n%08s\n", Bin2BCD(str_input));

    }

    else {

        printf("Wrong Code!");

    }

    return 0;

} 

效果截图:

5.请利用来实现一个抽象数据类型的链表,他可以存放任意自定义数据类型,至少实现指定位置插入和制定位置得到数据,以及制定位置删除。

#include <stdio.h>

struct Node

{

    struct Node* next;

    void* data;

};

 

typedef struct bearList

{

    bearList() {

        head = new Node;

        head->data = 0;

        head->next = NULL;

    }

    ~bearList() { delete head; }

    void createbearList(int n);

    void InsertNode(int position, int d);

    void *GetNode(int position);

    int GetLength();

    void DeleteNode(int position);

    void DeleteList();

    struct Node *head;

} bear;

 

void bearList::createbearList(int n)

{

    if (n < 0) {

        printf("Input Wrong!");

    }

    else

    {

        Node *pnew, *ptemp;

        ptemp = head;

        int i = n;

        while (n-- > 0) {

            pnew = new Node;

            printf("Input No.%d data for the list.", i - n);

            scanf("%d", (int*)&((pnew->data)));

            pnew->next = NULL;

            ptemp->next = pnew;

            ptemp = pnew;

        }

    }

}

 

void bearList::InsertNode(int position, int d)

{

    if (position < 0 || position > GetLength() + 1) {

        printf("Wrong Position!");

    }

    else {

        Node *pnew, *ptemp;

        ptemp = head;

        pnew = new Node;

        (pnew->data) = (void*)d;

        pnew->next = NULL;

        while (position-- > 1) {

            ptemp = ptemp->next;

        }

        pnew->next = ptemp->next;

        ptemp->next = pnew;

    }

}

 

void * bearList::GetNode(int position)

{

    Node *ptemp;

    ptemp = head->next;

    int i = 1;

    while (position - i++) {

        ptemp = ptemp->next;

    }

    return ptemp->data;

}

 

int bearList::GetLength()

{

    Node *p = head->next;

    int n = 0;

    while (p != NULL) {

        n++;

        p = p->next;

    }

    return n;

}

 

void bearList::DeleteNode(int position)

{

    if (position < 0 || position > GetLength()) {

        printf("Wrong Position!");

    }

    else {

        Node *ptemp = head, *pdelete;

        int i = position;

        while (i-- > 1) {

            ptemp = ptemp->next;

        }

        pdelete = ptemp->next;

        ptemp->next = pdelete->next;

        delete pdelete;

        pdelete = NULL;    

    }

}

 

void bearList::DeleteList()

{

    int i = GetLength();

    while (i-- > 0) {

        DeleteNode(i);

    }

}

 

int main(void)

{

    bearList bear;

    bear.createbearList(3);

    bear.InsertNode(2,5);

    int i = (int)bear.GetNode(2);

    bear.DeleteNode(3);

    bear.DeleteList();

    return 0;

}

结果:

1.     初始化链表

2.     在位置2处插入数据5

3.  查询位置2处的数据

4.     删除位置3的数据

    

5. 清空空链表



共16条 2/2 1 2 跳转至

回复

匿名不能发帖!请先 [ 登陆 注册 ]