PA0:关于练习题 1-10

网页浏览体验很差,希望下次不要再找广告满天飞的网站搭翻译博客。

网页做的很好,以后别做了。

 

 不使用stdio库。gcc在make时会提示存在implicit declaration(隐式声明)

--------------------------------------------

makefile基本指令解释:

CFLAGS=-Wall -g

 clean:

    rm -f ex1                                       -Wall表示要显示所有报错和warning信息,-g表示加入调试信息   clean后则表示需要清理掉哪些内容

 

在附加题里提到了一个all:ex1。 all表示指定ex1作为依赖。在构建all时,ex1也会被构建。直接make就相当于make ex1 。此外,文件夹里只有ex1.c一个文件时,make会隐含地发现ex1.c就是它的目标。并使用gcc -o ex1 ex1.c来编译。all里面也可以用空格隔开多个文件,clean时对应也可使用make clean all。

------------------------------

 练习4:  curl是一个http相关的工具,发送http请求,获取http相应,也需要进行安装。

在用网页下载方式安装valgrind时,由于下载下来是一个ascii text,tar无法解压

curl -O http://valgrind.org/downloads/valgrind-3.6.1.tar.bz2  指令存在问题。 最后实在没办法,用apt-get安装了。

安装好以后,valgrind 去分析有错文件,提示permission denied。检查发现,直接用valgrind ex4即可。

 

在用make时,发现-Wall -g并没有被自动加入编译参数,检查发现,Makefile里面的FLAGS是错的,要写成CFLAGS才行。

---------------------------------------

C语言里,单引号用来框字符,双引号用来框字符串。

%d  输出整型  %ld 长整型   %f  浮点   %c  字符   %s  字符串   %e科学计数法

 

空字节字符\字符串结尾符号:  \0  ,对应就是数字0.(这一点以前没发现)

C语言的字符串就是字符数组,不管有没有显式声明,末尾一定都有一个\0用来标记结束,所以实际占用空间要+1。 此外,输入字符串以后,字符串就会被作为字符数组处理。假如把一个字符串放到远大于它长度的字符数组里,那么数组的对应位置以及之后就都是\0,打印时这一部分即使用数组下标也是打不出来的。

 

注意:手动逐个录入字符数组时,末尾要手动增加\0,不会像字符串录入时一样自动加上\0。不加会导致程序崩溃。

 

练习8的后续附加:

1)把字符赋值进int数组,还是可以打印的,打印的就是字符的对应ASCII码。如果就是用%d的话,那编译器不应该报警告,如果用%c的话,那就对应输出ascii字符。

2)关于字符数组和int型同为4字节时的情况。这个问题说的有点模糊,什么叫“像整数一样使用整个name”? 如果是说直接试图用%d打印,那确实是可以的。四个字符的ascii码拼在一起,视作完整补码,用%d得到的就是这个补码对应的真值。大小端就不考虑了。

 

------------试图用%c输出数字时,如果数字在0-255,那就直接按ascii码表对应转换。如果不在,那就先截断,取低部分,再将真值在ascii表内转换。如果不考虑计算机内的原码补码转换,直观地看,就是数字取余255,然后再转换,比如43和299、555对应的都是加号。(如果考虑,那就需要把补码转为原码,再截断原码的低位)

 

------------------------练习10--------------

char states[]和char * states[]的含义是不一样的。前者表示了一个字符数组,里面每个元素都是一个字符;后者则是一个字符指针数组,数组里每个元素都是一个字符串/字符数组指针,又指向了一个字符数组,也就是说整体来看是一个二维数组。

 

关于main函数的参数。我尝试用更短的程序:

int main(int argc,char *argv[])
{
    int i=0;
    for(i=1;i<argc;i++)
    {
        printf("%d  %s\n",argc,argv[i]);
    }    
    return 0;
}

  如果i=0 那argc打出来是1,argv对应输出的就是当前文件的路径。如果i从1开始,那什么都打不出来。因为argv[0]记录的就是文件路径,从1开始记录的就是使用文件时输入的命令行参数,我没有输入参数,所以从1开始全为空。

  关于能否通过传入过多参数来让程序崩溃,我觉得这和程序自己实现有关,设计的不好,比如总大小有限的数组,又不处理参数过多的情况,有可能导致崩溃。

 

练习10附加题:

1)假设其他位置没有出现循环所需的条件初始化,for循环条件1是null时,循环变量没有初始化,报错;或者循环变量可能出现意外初始值;条件2是null,没有退出条件,需要手动在循环体内写;条件3是null,每次循环,循环变量不改变,需要在循环体内手动写。其实for(;;) 也不是不行,写出来就是个死循环。

2)如果用NULL做states的一个元素,程序可以编译,但会警告warning: converting to non-pointer type `char' from NULL,打印出来也是空。NULL是一个指针型的变量,表示空指针。这段报错表示char和NULL不兼容,如果把NULL改成\0就可以兼容了。

posted @ 2024-01-15 17:46  namezhyp  阅读(11)  评论(0编辑  收藏  举报