【2015/10/18】C学习日志_Day8 数据类型及其位表示,指针,内存状态

D8:
    《深入理解计算机系统》
    objdump -s -d <程序> : 可以看到在内存中的段等信息
    
    内存布局:
    由高到低:
        1.内核空间
        2.stack
        3.share lib
        4.heap
        5.rw
        6.ro
        7.保留区reservation


/*************************************************************************
    > File Name: class.c
    > Author: khalil
    > Mail: hsgwpj@gmail.com 
    > Created Time: Sun 18 Oct 2015 09:11:28 AM CST
 ************************************************************************/
#if 0 

#include<stdio.h>

int main(int argc ,char ** argv)
{
	//定点数
	char a = 10 ;	//字符 1byte 	
	short b = 20 ;	//2 bytes
	int c = 30;		//4 bytes
	long d = 40;	//4 bytes   32位操作系统-4 64位-8 (等同于指针大小)
	long long int e = 50;	//8 byetes
	
	//有符号数与无符号数
	signed int aa = 10 ;
			//其位表示为		
			//eg:000000000 00000000 00000000 00001010
			//
			//	对于正数:原码和补码相等
			//
			//	对于负数:
			//		-1 = 1000 0001 (原码: 人对于负数的认识)
			//
			//* 计算机只识别补码
			//
			//	- x = 0 - x = 0000 0000 - x(向上借位) 
			//
			//* 负数(原码)除符号位外,其他位按位取反,末位加1
			//	
			//	-1 = 1000 0001 = 1111 1110 = 1111 1111
			//	0 - x = x(反) + 1
			//
			//无符号数:
			//
			//	unsigned char a ;	( 0 - 255 )
			//	char b ;			( -128 - 127)
			//
			//	unisigned char c = 0;
			//	c-- = 255 ;
			//
			//	size_t == unsigned int 
			
	//浮点数
	float f = 12.25;		//4 bytes
	double g = 2.5;			//8 bytes

	printf("size of char :\t %d\n",sizeof(a));
	printf("size of short :\t %d\n",sizeof(b));
	printf("size of int:\t %d\n",sizeof(c));
	printf("size of long :\t %d\n",sizeof(d));
	printf("size of long long int :\t %d\n",sizeof(e));
	printf("size of float :\t %d\n",sizeof(f));
	printf("size of double :\t %d\n",sizeof(g));



	return 0 ;
}
#endif

#if 0

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

int comp_len(const char *str1,const char *str2);

int comp_len(const char *str1,const char *str2)
{
	//return strlen(str1) - strlen(str2) > 0 ;  // wrong ver

	// size_t strlen(const char *s); 返回值是一个无符号类型!
	return strlen(str1) > strlen(str2);

	// size_t  - size_t
	// 《深入理解计算机系统》
}


int main(int argc , char ** argv)
{
	char *str1 = "wafawf";
	char *str2 = "afiuwabfiawfbiawf";

	comp_len(str1,str2);

	return 0;
}

#endif

#if 0  
#include<stdio.h>
int main(int argc , char ** argv)
{	
	float a = 12.25;

	//浮点数的位存储形式:
	//
	//	12.25 => 1100.01(二进制) = 1.10001 * 2^3 (二进制科学技术法)
	//			 2*3+ 2*2 + 2^-2
	//
	//		3		-> 指数位
	//		10001	-> 尾数
	//		0		-> 符号位
	
	//规则如下:
	//	12.25:
	//	0 0000001 |1  
	//	  1111111 |1 
	//	0 1000001 |0 100001 00 |00000000 |00000000
	//	f zzzzzzz |z wwwwww ---|----补零-|--------
	//	f符号位 z指数位 w尾数位
	//	(1)左1位符号位,正数0,负数1
	//	(2)指数位占8位 如果是正数 需要加127
	//	(3)尾数位32-1-8=23位
	//	
	//	精度: 尾数位 : 2^23约等于7位 
	//
	//	大端机器:数值上的高位放在内存上的低位 (服务器)
	//
	//	小端机器:........高..............高.. (PC)
	//
	//* 通过对位表示的理解 将浮点数转化为整形数
	
	double b = 233.333;
	//double 的位表示:
	//(1)符号位	-> 1
	//(2)指数位	-> 11
	//(3) 尾数位	-> 52
	//
	//2^52 约等于15,16位

	return 0;
}
#endif

#if 0  

#include<stdio.h>
#include<stdlib.h>
int main(int argc ,char ** argv)
{
	int a = 10;
//	int * p = (int *)malloc(sizeof(int));
//	int ** q = (int **)malloc(sizeof(int **));
//	p = &a;
//	q = &p;
	int *q = &a;
	int **p  = &q;


	//void s; 变量进行定义的时候一定要告诉编译器变量的大小
	void * m;	//指针类型的大小是固定的

		//void * 可以接受任意类型的指针,它是泛型编程的基础
		//


	//1.指针是一个变量,它在内存中也有地址
	//2.指针的功能是记录地址
	//3.指针具有类型限定(指类)
	//
	//指针的大小:	32位下 4bytes
	//				64位下 8bytes
	//					* 与long类型同步!

	printf("%d",**q);

	return 0;
}
#endif

#if 0 

#include<stdio.h>

int main(int argc , char ** argv)
{
	char *str1		= "hello,world!";
	char str2[]		= "hello,world!";
//	char str3[100]	= "hello,world!";
	char str3[6]	= {0};

	//第一个不能修改字符串的字符	在内存的常量区
	//第二三个可以修改				在栈中的开辟空间中由下而上存储
	//
	//str1为指针(栈上),指向常量区的一个字符串,该字符串不可修改
	//str2,str3为字符数组,在栈上
	
	//练习:通过直接更改 str3[*] = ‘'l' 将str2改为hlllo
	//
	
	int i;
	
	printf("before:%s\n",str2);

	printf("str 1 地址: %p\n",str1);
	printf("str 2 地址: %p\n",str2);
	printf("str 3 地址: %p\n",str3);
	
	for (i = 0 ; i < 30 ; i++)
	{
		printf("This is %d : %c\n",i,str3[i]);
	}
	
	str3[17] = 'l';
						//内存对齐的缘故!
	printf("after :%s\n",str2);

	return 0;
}
#endif

#if 0
#include<stdio.h>

//使用方法: 对位置进行标记
//
//如果进行部分初始化,未初始化的值从已经初始化的值开始向后加一,如果第一个
//元素都没有初始化,则从0开始
//

enum flag{
	INDEX1,
	INDEX2,
	INDEX3 = 10,
	INDEX4,
	INDEX5 = 21,
	INDEX6
};


int main(int argc , char ** argv)
{
	enum flag a ;
	
	//枚举类型的大小是4字节(和int相同)
	printf("%d\n",sizeof (a));
	
	return 0;
}


#endif

#if 0 

#include<stdio.h>

int b = 10 ;				//定义式
//extern int b ;			//外部声明!
extern void function();		//从其他.c查找是否有外部函数声明!
//

int main(int argc , char ** argv)
{
	int a = 10 ; //这称为定义:即分配内存,由告诉内存的标记
	int b,c;	//wrong ver. 同时要注意变量一定要进行初始化
				//
				//习惯:
				//
				//1.变量定义一定要初始化 尤其是指针;
				//	eg.	定点数初始化为0,浮点数初始化为0.0,指针初始化为NULL,
				//		数组初始化为0(char类型为{0});
				//2.每一行只做一个操作;
				//3.不允许隐式声明,所有变量必须是显式声明;
				//
				//

	function();

	return 0; 
}

#endif

#if 0

#include<stdio.h>

#define P_CHAR	char * //定义类型的时候不能加括号!
typedef int *p_int;

#define TRUE	(1)
#define FALSE	(0)

typedef unsigned char Boolean ; //0-255 True 1 / False 0
		//类型重定义,例如布尔类型的定义

int main(int argc , char ** argv )
{
	P_CHAR	a,b;	// == char* a,b ; == char  *a , b;
	p_int	c,d;	// == int * c ; int * d;

	Boolean ok =FALSE;
	printf("%d",ok);
	return 0 ;
}


#endif

#if 0  

#include<stdio.h>

int main (int argc , char ** argv)
{
	int a = 10 ;
	const int b = 20;	//const修饰变量代表是 常变量 在内存中占有空尽阿 
						//常变量是可以被修改的!
	
	9;					//常量 常量在内存中没有空间

	int const c = 20;	//他们是一样的

	const int *p		= &a;	//p指向的对象的值不可引用*p更改
	int const *q		= &a;	//
	int * const m		= &a;	//int * m 所指向的地址不可改变
	const int * const n = &a;	//上述两个都不能改

	//修改常变量:(可以通过指针来修改) - 然而最好不要改 这是编译器的漏洞
	int *y = (int *) &b;	//如果没有 (int *) 进行强制转换  会有warning
	*y = 200;
	printf("%d",*y);


	return 0 ;
}



#endif

#if 0
#include<stdio.h>

int a ;							//声明式 如果没有这一步 func1() 报错(找不到a)

void func1(void);

void func1(void)
{
	printf("a = %d\n",a);
}

int a = 10;						//定义式

int main(int argc , char ** argv )
{
	int a = 20;
	{
		int a = 10;
		a++;
		printf("a = %d\n",a);
	}
	printf("a = %d\n",a);
	func1();

	return 0 ;

}

#endif 

#if 0

#include<stdio.h>
#include<stdlib.h>
													//下面列出我们可以操作的内存
#define SIZE (10)

int global_value = 10;								//全局区
static int static_value = 20;						//静态区

int * func1(void);

int * func1(void)
{
	//自动变量:
	//
	//函数调用时定义,函数结束时回收

	int a = 10;
	int array[] = {12,23,45,67};
	int i =0;

	for ( ; i < (sizeof(array) / sizeof(array[0])) ; ++i)
	{
		printf("%d\n",array[i]);
	}
	
	a++;
	
	return array;		//自动变量array在func1()结束后会被回收 这样会warning
}

int main(int argc , char ** argv)
{
	int a = 10;										//stack
	int *p_int = (int * )malloc(sizeof(int)*SIZE);	//p_int 在stack上 
													//而malloc申请的空间在heap上
	if (p_int == NULL){
		fprintf(stderr,"the memory is full! \n");
		exit(1);
	}

	p_int[0] = 1;
	free(p_int);
	
	func1();

	return 0;
}
#endif


#if 1
//作业1:escape() unescape()


#include<stdio.h>
#include<stdlib.h>
char * escape ( char *dest , char *src);
char * unescape ( char *dest , char *src);


int main(int argc , char ** argv)
{
	char * str1 = "hello\n,world\t\neveryone!";
	char * str2 = "233";
	
	printf("样本:\n%s\n\n",str1);

	printf("defore:\n%s\n\n",str2);
	
	str2 = escape(str2,str1);

	printf("escape:\n%s\n\n",str2);
	
	str2 = unescape(str2,str2);

	printf("unescapde:\n%s\n\n",str2);

	return 0 ;
}

char * escape ( char *dest_str , char *src_str)
{
	char *dest = (char * )malloc(sizeof(dest_str));
	char *result = dest;
	char *src  = src_str;

	char ch = '\0'; 

	if ( dest_str == NULL || src_str == NULL )
	{
		return dest_str;
	}

//	while(( *dest++  = *src++ ) != '\0')
	while( *src != '\0')
	{
		ch = *src ;
		switch(ch)
		{
			case('\t'):	*dest++ = '\\';
						*dest++ = 't';
						break;
			case('\n'):	*dest++ = '\\';
						*dest++ = 'n';
						break;
			default:
						*dest++ = ch;
						break;
		}
		src ++ ;
	}
	*dest = '\0';
	return result;
}

char * unescape ( char *dest_str , char *src_str)
{
	char *dest = (char * )malloc(sizeof(dest_str));
	char *result = dest;
	char *src  = src_str;

	char *ch_next ='\0';
	char ch = '\0'; 

	if ( dest_str == NULL || src_str == NULL )
	{
		return dest_str;
	}

//	while(( *dest++  = *src++ ) != '\0')
	while( *src != '\0')
	{
		ch = *src ;
		ch_next = src+1;
		
		switch(ch)
		{
			case('\\'):	
				if(*ch_next == 'n')
				{
					*dest++ = '\n';
					src++;
				}
				else if(*ch_next == 't')
				{
					*dest++ = '\t';
					src++;
				}
					break;
			default:
					*dest++ = ch;
					break;
		}
		src++ ;
	}
	*dest = '\0';
	return result;
}

#endif

#if 0
#include<stdio.h>

int main(int argc , char ** argv)
{
	int i = 0;
	int j = 0;
	for ( ; i < 1000000 ; i++ )
	{
		for( j = 0 ; j < i ; j++ )
		{
			if( i % j == 0)
			{
				print("%d\n",i);
				break;
			}
		}

	}
}

#endif


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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值