201905-计算机系统基础-编程日志合集

编程日志1(show-bytes.c)

代码说明

将数val=12345各种不同的类型强制转换,并在屏幕上输出每个字节在计算机内部所占地址值

代码"showbytes.c"

/* show-bytes - prints byte representation of data */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

typedef unsigned char *byte_pointer;
//typedef char *byte_pointer;
//typedef int *byte_pointer;

void show_bytes(byte_pointer start, size_t len) {
    size_t i;
    for (i=0;i<len;i++)
	printf("%p\t0x%.2x\n", &start[i], start[i]); 
    printf("\n");
}

void show_int(int x) {
    show_bytes((byte_pointer) &x, sizeof(int)); 
}

void show_float(float x) {
    show_bytes((byte_pointer) &x, sizeof(float));
}

void show_pointer(void *x) {
    show_bytes((byte_pointer) &x, sizeof(void *));
}

void test_show_bytes(int val) {
    int ival = val;
    //float fval = (float) ival;
	double fval = (double) ival;
    int *pval = &ival;
    printf("Stack variable ival = %d\n", ival);
    printf("(int)ival:\n");
    show_int(ival);
    printf("(float)ival:\n");
    show_float(fval);
    printf("&ival:\n");
    show_pointer(pval);
}

void simple_show_a() {
	int val = 0x87654321;
	byte_pointer valp = (byte_pointer) &val;
	show_bytes(valp, 1); /* A. */
	show_bytes(valp, 2); /* B. */
	show_bytes(valp, 3); /* C. */
}

void simple_show_b() {
	int val = 0x12345678;
	byte_pointer valp = (byte_pointer) &val;
	show_bytes(valp, 1); /* A. */
	show_bytes(valp, 2); /* B. */
	show_bytes(valp, 3); /* C. */
}

void float_eg() {
	int x = 3490593;
	float f = (float) x;
	printf("For x = %d\n", x);
	show_int(x);
	show_float(f);

	x = 3510593;
	f = (float) x;
	printf("For x = %d\n", x);
	show_int(x);
	show_float(f);

}

void string_ueg() {
	const char *s = "ABCDEF";
	show_bytes((byte_pointer) s, strlen(s)); 
}

void string_leg() {
	const char *s = "abcdef";
	show_bytes((byte_pointer) s, strlen(s));
}

void show_twocomp() {
    short x = 12345; 
    short mx = -x; 
    
    show_bytes((byte_pointer) &x, sizeof(short)); 
    show_bytes((byte_pointer) &mx, sizeof(short)); 
}

int main(int argc, char *argv[])
{
    int val = 12345;
    if (argc > 1) {
        val = strtol(argv[1], NULL, 0);
		printf("calling test_show_bytes\n");
		test_show_bytes(val);
    } 
    else {
		printf("calling show_twocomp\n");
		show_twocomp();
		printf("Calling simple_show_a\n");
		simple_show_a();
		printf("Calling simple_show_b\n");
		simple_show_b();
		printf("Calling float_eg\n");
		float_eg();
		printf("Calling string_ueg\n");
		string_ueg();
		printf("Calling string_leg\n");
		string_leg(); 
    }
    return 0;
}

代码解释

各个类型变量在计算机中储存字节不同,相同的数强制转换为不同数据类型后,其储存结果可能在计算机内部发生变化,因而在声明变量类型时需要注意类型变化引起的各种后果。

gcc运行结果

show-bytes(1)
show-bytes(2)
show-bytes(3)

编程日志2(fsum.c)

代码

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define BUFSIZE 256

int main(int argc, char *argv[]) {
	char prefix[BUFSIZE];
	char next[BUFSIZE];
	int i;
    float sum = 0.0;
    for (i = 1; i < argc; i++) {
		float x = atof(argv[i]);
		sum += x;
		if (i == 1) 
	  		sprintf(prefix, "%.4g", x);
	  	else {
	  		sprintf(next, " + %.4g", x);
	  		strcat(prefix, next);
	  		printf("%s = %.4g\n", prefix, sum);
		}
    }
    return 0;
}

调试

测试输入1:	1e20 -1e20 3.14
测试输入2:	-1e20 3.14
测试输入3:	-1e20 3.14 1e20

调试结果如下:
fsum.c

代码解释

3.14在加上1e20时会舍去,太小了

编程日志3(struct.c)

代码

#include <stdio.h>
#include <stdlib.h>

typedef struct {
    int a[2];
    double d;
} struct_t;

double fun(int i) {
    volatile struct_t s;
    s.d = 3.14;
    s.a[i] = 1073741824; /* Possibly out of bounds */
    return s.d; /* Should be 3.14 */
}

int main(int argc, char *argv[]) {
    int i = 0;
    if (argc >= 2)
		i = atoi(argv[1]);
    double d = fun(i);
    printf("fun(%d) --> %.10f\n", i, d);
    
    return 0;
}

调试

测试输入:0; 1;2;3;4;
运行结果:
struct.c

代码解释

int a[2]在程序运行超过三次后会溢出,超过数组范围输出的数据应该是随机数

结论

写程序时需注意数组的溢出,理解栈内数据存放方式,防止因为数据溢出而产生的隐患

编程日志4(sq.c)

输出一个数的平方

代码

#include <stdio.h>
#include <stdlib.h>

int sq(int x) {
    return x*x;
}

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

调试

测试输入:12;133;2333;4000;5000;65535;400000;500000;
运行结果:
sq.c
其对应相反数(负数)运行结果与正数相同,如下:
-sq.c

代码解释

当测试数据超过4000–5000中的一个数时,其平方储存(double类型)会发生溢出

编程日志5(locate.c)

输出16MB和1GB在内存中存在的地址与内容,并且增加存储,用不同的64位移位函数输出

代码

#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>

static void show_pointer(void *p, char *descr) {
    //    printf("Pointer for %s at %p\n", descr, p);
    printf("%s\t%p\t%lu\n", descr, p, (unsigned long) p);
}

char big_array[1L<<24];    /*  16 MB */
//char huge_array[1L<<31];   /*   2 GB */
char huge_array[1L<<30];/*   1 GB */
int global = 0;

int useless() { return 0; }

int main ()
{
    void *p1, *p2, *p3, *p4;
    int local = 0;
    p1 = malloc(1L << 28);
    p2 = malloc(1L << 8);
    //p3 = malloc(1L << 32);
	p3 = malloc(1L << 16);
    p4 = malloc(1L << 8);

    show_pointer((void *) big_array, "big array");
    show_pointer((void *) huge_array, "huge array");
    show_pointer((void *) &local, "local");
    show_pointer((void *) &global, "global");
    show_pointer((void *) p1, "p1");
    show_pointer((void *) p2, "p2");
    show_pointer((void *) p3, "p3");
    show_pointer((void *) p4, "p4");
    show_pointer((void *) useless, "useless");
    show_pointer((void *) exit, "exit");
    show_pointer((void *) malloc, "malloc");
    
    return 0;
}

运行结果

locate.c

编程日志6(runaway.c)

设立栈 从100挨个递减

代码

#include <stdio.h>
#include <stdlib.h>

int recurse(int x) {
    int a[1<<15];  /* 4 * 2^15 =  64 KiB */
    printf("x = %d.  a at %p\n", x, a); 
    a[0] = (1<<14)-1;
    a[a[0]] = x-1;
    if (a[a[0]] == 0)
	return -1;
    return recurse(a[a[0]]) - 1;
}

int main(int argc, char *argv[]) {
    int x = 100;
    if (argc > 1)
	x = atoi(argv[1]);
    int v = recurse(x);
    printf("x = %d.  recurse(x) = %d\n", x, v);
    return 0;
}

调试

运行结果:
runaway.c(1)
runaway.c(2)

编程日志7(bufdemo.c)

代码

/* Demonstration of buffer overflow */
#include <stdio.h>
#include <stdlib.h>

/* Implementation of library function gets() */
char *gets(char *dest)
{
	int c = getchar();
	char *p = dest;
	while (c != EOF && c != '\n') {
    	*p++ = c;
    	c = getchar();
  	}
  	*p = '\0';
  	return dest;
}

/* Read input line and write it back */
void echo()
{
    char buf[4];  /* Way too small! */
    gets(buf);
    puts(buf);
}

void call_echo() {	echo();	}

/*void smash() 
{
    printf("I've been smashed!\n");
    exit(0);
}*/

int main()
{
    printf("Type a string:");
    call_echo();
    return 0;
}

调试结果

bufdemo.c

编程日志8(hexify.c)

代码

/* Convert sequence of hex digits on command line into a string, terminated by \n */
#include <stdio.h>

int main(int argc, char *argv[]) {
    int i;
    for (i = 1; i < argc; i++) {
	unsigned long dig = strtoul(argv[i], NULL, 16);
	putchar((char) dig);
    }
    putchar('\n');
    return 0;
}

运行结果hexify.c

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值