Linux及C语言高级[2](C语言基础)

689 阅读7分钟

“这是我参与8月更文挑战的第2天,活动详情查看:8月更文挑战

学习c语言的境界

境界一:c语言的基本的语法

境界二:通过c语言语法锻炼自己的逻辑思维和编程能力

境界三:通过指针操作内存

一.理解内存

1.1内存划分

图片.png

linux系统的内存的划分见上图,由于32位系统最大能访问的内存2^32(4G),但是用户外接的物理内存大小不确定,所以内核就引入了虚拟内存的概念,mmu(内存映射单元)将物理内存映射成虚拟内存。0-3G属于用户空间,每一个程序的运行都有自己的0-3G的空间,用户空间有多份,但是内存空间只有3-4G一份

用户空间划分.png

刚开始在.ro段这老犯一些错误,

eg: char *p = "hello"; char *q = "world";

在执行strcat(p,q);时就会在Ubuntu内编译时会见到段错误,刚开始不理解,问了老师才明白,因为p指针指向只读段,这样写入会发生段错误。可以把被拼接的的字符串定义成字符数组就解决了。

eg: char arr[] = "hello";

1.2c语言中的内存的分配

1.2.1变量类型:(32位)

基本类型

1.字符类型字节数符号位数据位数据范围
char1字节76---0[-128,127]
unsigned char1字节7---0[0,255]-->[0,0xff]
2.整型字节数数据范围
short2字节[-32768,32767]
unsigned short2字节[0,0xffff]
int4字节[-2147483648,2147483647]
unsigned int4字节[0,0xffffffff]
long(long int)4字节
long long(long long int)8字节
3.实型字节数
float单精度浮点类型4字节
unsigned short双精度的浮点类型8字节

4.枚举类型:enum 4字节

  • 枚举:属于基本类型,在32位操作系统上,枚举占用的大小是4字节,它是有限数据的罗列。
  • 定义格式:
enum aa{
    ONE ,
    TWO,
    THRE=10,
    FOR,
};	
  • 1.枚举类型的成员和成员间是逗号
  • 2.枚举类型中的成员默认第一个是0,后面的成员依次加1
  • 3.枚举类型中的成员被赋值之后,后面的成员依次加1
  • 4.枚举类型占用的大小就是4字节
  • 5.有限数据的罗列
enum {
    ADDSTU=1,
    VEWSTU, 
    SOTSTU,  
    MODSTU,  
    DELSTU, 
    QUTSTU,  
};

5.构造类型:

  • 数组类型 char [2] ; int [3];
  • 结构体 struct
  • 共用体 union

6.指针类型

char * ; int *;

long *; void *;

所有的指针都占4字节

7.空类型

void

1.2.2变量的定义

  • 数字,字母,下划线组成,不能以数字作为开头 int _a12;
  • 不能和关键字重复(例如:int char struct... 32个)
  • 变量区分大小写
  • 见名知义

二.进制转化

进制前缀例如
二进制前缀0b0b 100 0010 = 2^6+2^1=66
十进制66
八进制前缀00102
十六进制前缀0x0x42

1K 0x0400 [2^10]

1M 0x0010 0000 [2^20]

1G 0x4000 0000 [2^30]

2G 0x8000 0000

3G 0xc000 0000

4G 0x0001 0000 0000

5G 0x0001 4000 0000

三.数据存储问题

所有的数据是以补码的格式来存储的,正数的源码,反码,补码都是它本身负数的补码按照如下格式转化

eg:char a = -5;

源码 1000 0101

反码 1111 1010 :除符号位不变,其他位取反

补码 1111 1011 :在反码的基础上加1

补码转化源码和源码转补码的过程是一样。

补码的补码是源码

四.常量的表示

1.字符常量

char a;

man ascii

'A' --->65

'a' --->97

'z' --->122

'n' --->110

'\n'--->\转义,换行 10

'\a' --->bell

'\t' --->Tab

'0' --->48

'\0'--->0

'\101'--->A //对应一个字符

'\x41'--->A

'\0x411'越界,逃出16进制。//一个转义就一个字节,

'\1011'--->A1

转义字符可以转义八进制或者16进制的数,没有十进制转义为字符(ascii表中)

'\101'--->转义为字符'A' 八进制的转义

'\x41'--->转义为字符'A' 十六进制的转义

printf("%c\n",'\101');

printf("%c\n",'\41');

2.整型常量

0b11101

87

0775

0xabc113c

3.实型常量

3.14

3.1e2 //3.1*10^2,e or E

3.1e-2

4.标识常量

define

5.字符串常量(c语言中没有字符串类型,可以存在字符数组)

"helloworld"

五.输出的用法

printf("控制格式",输出的数据)

printf("%c",a); //以%c的型式显示a的值

printf("%u",a); //%u无符号的正数

printf("%d",a); //整数

printf("%04d",a); //打印的数据占四个格,如果不足补充0

//04 是指,输入五位时原样输出

printf("-4d",a); //左对齐

printf("%#o",a); //八进制

printf("%#x",a); //十六进制

printf("%ld",a); //显示的是long int

printf("%lld",a); //显示的是long long int

printf("%#llx",a); //十六进制显示的是long long int

printf("%s",a); //显示字符串

printf("%p",a); //显示地址,变量在内存上的内存单元的编号

printf("%f",a); //显示浮点数,小数点后6位

printf("%.2f",a); //显示浮点数后两位,四舍五入

printf("%lf",a); //显示double

printf("%e",a); //指数的形式显示浮点数

printf("%g",a); //显示小数点后的有效位

六.标准输入

scanf("控制格式",&变量);从终端上读取结果到变量中

scanf("%c",&a); ==>输入字符到a变量

scanf("%d",&a); ==>输入整数到a变量

scanf("%f",&a); ==>输入小数到a变量

scanf("%s",a); ==>输入字符串到a数组中,在输入的时候字符串间 ==>不能有空格,但是gets是可以的。

scanf("%[^\n]",arrary); ==>表示除了'\n'之外的字符都输入到 ==>array数组中,他就可以和gets等价

ret = scanf("%d%*c%c",&a,&b); ===>%*c吃掉任意的一个字符,两个**两个字符

ret = scanf("%d,%d",&a,&b); ===>第一个返回错了就都是0,scanf是返回第一个错误为止的正确的个数

注:scanf的返回值是表示输入成功的项目的个数 可以通过判断返回值来判断,输入的数据是否正确。

返回值的判断实例:

#include <stdio.h>
int main(int argc, char const *argv[])
{
    char w;
    int n;
    int m;
    int ret;
retry:
    ret = scanf("%c,%d,%d",&w,&n,&m);
				
    printf("input()");
    if(ret != 3)//输入成功的个数如果不为3
    {
    while(getchar()!='\n'); //把所有的字符都吃掉
    goto retry;
    }
    printf("ret = %d\n, w = %d,n = %d,m = %d\n",ret,w,n,m);
    return 0;
}	

七.输入或输出字符

int getchar(void); //scanf("%c",&ch); ===> ch=getchar();

功能:从终端上获取一个字符

参数: @无

返回值:读取到的字符对应的数值

int putchar(int c); //putchar(ch) ====>printf("%c",ch);

功能:从程序向终端上输出一个字符

参数: @c :想要输出的字符

返回值:成功返回输出的字符,失败返回EOF(-1)

例子如下:

	/*  
	ch = getchar();
	putchar(ch); 
	*/
	putchar(getchar());
	putchar(10);  ===>'\n'
	putchar('\n'); ===>'\n'
	putchar('\012');===>'\n'  
	putchar('\n');
	putchar(0101);
	putchar('\101');
	putchar('\n');

执行结果

八.输入或输出数组

char array[100];

char [] gets(char s[]);

gets(array);===>scanf("%[^\n]",array)

功能:从终端上读取一个字符数组

参数:

@s:数组的首地址

返回值:数组的首地址

📢注意:gets输入多少就会输出多少,不考虑数组的大小超过执行的时候就会出错。gets可以读取空格。gets会把'\n'替换成'\0' ,'\0'表示字符串结尾 hello world\0

int puts(char s[]); //puts(array) ===>printf("%s",array)

功能:输出一个数组

参数:

@s:被输出的数组

返回值:成功返回输出的字符的个数,失败返回EOF(-1)

注:puts会输出换行

九.c语言中的注释

// 单行注释
/*
*多行注释                                                 
* */
#if 0
多行注释
#else
没有注释的部分
#endif