C基础笔记一
Posted 城子特讯
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了C基础笔记一相关的知识,希望对你有一定的参考价值。
内存分区
1、数据类型基本概念
类型是对数据的抽象; 类型相同的数据具有相同的表示形式、存储格式以及相关操作; 数据类型可以理解为创建变量的模具: 固定大小内存的别名;
1.1、数据类型的别名
typedef unsigned int u64;
typedef struct _PERSON
char name[32];
int age;
Person;
void example()
u64 val; //相当于 unsigned int val;
Person person; //相当于 struct PERSON_person;
1.2、void类型
void是”无类型”,void* 无类型指针,无类型指针可以指向任何类型的数据。
//1. void修饰函数参数和函数返回
void example1(void)
printf("charles");
//2. void* 可以指向任何类型的数据,被称为万能指针
void example2()
int x = 10;
void* p = NULL;
p = &x;
printf("x:%d\\n",*(int*)p);
//3. void* 常用于数据类型的封装
void example3()
void * memcpy(void * _Dst, const void * _Src, size_t _Size);
1.3、void类型
sizeof为某一特定数据或者某一个类型的数据在内存中分配空间时分配的大小(字节为单位)。sizeof返回的占用空间大小是为这个变量开辟的大小,而不只是它用到的空间。
对数组名用sizeof返回的是整个数组的大小,而对指针变量进行操作的时候返回的则是指针变量本身所占得空间。而且当数组名作为函数参数时,在函数内部,形参也就是个指针,所以不再返回数组的大小。
//1. sizeof
void example1()
int a = 10;
printf("len:%d\\n", sizeof(a));
printf("len:%d\\n", sizeof(int));
printf("len:%d\\n", sizeof a);
//2. sizeof 数组
void Array(int arr[])
printf("Array arr size:%d\\n",sizeof(arr));
//数组名在某些情况下等价于指针
int arr[] = 10, 20, 30, 40, 50 ;
int* pArr = arr;
printf("arr[2]:%d\\n",pArr[2]);
printf("array size: %d\\n", sizeof(pArr));
2、内存分区
1 预处理:宏定义展开、头文件展开、条件编译,这里并不会检查语法
2 编译:检查语法,将预处理后文件编译生成汇编文件
3 汇编:将汇编文件生成目标文件(二进制文件)
4 链接:将目标文件链接为可执行程序
内存分区:代码区(text)、数据区(data)和未初始化数据区(bss)、堆区和栈区。
代码区。存放 CPU 执行的机器指令。通常代码区是可共享的,其目的是对于频繁被执行的程序,只需要在内存中有一份代码即可。 全局初始化数据区/静态数据区(data段)。该区包含了在程序中明确被初始化的全局变量、已经初始化的静态变量(包括全局静态变量)和常量数据(如字符串常量)。 未初始化数据区(bss区)。该区存入的是全局未初始化变量和未初始化静态变量。未初始化数据区的数据在程序开始执行之前被内核初始化为 0 或者NULL。 栈区(stack)。栈是一种先进后出的内存结构,由编译器自动分配释放,存放函数的参数值、返回值、局部变量等。在程序运行过程中实时加载和释放。 堆区(heap)。堆是一个大容器,用于动态内存分配。堆在内存中位于BSS区和栈区之间。一般由程序员分配和释放,若程序员不释放,程序结束时由操作系统回收。 |
2.1、栈区和堆区
栈区主要存放函数的参数以及局部变量。在函数完成执行,系统自行释放栈区内存。栈保存一个函数调用所需要维护的信息,这通常被称为堆栈帧;一个函数调用过程所需要的信息一般包括以下几个方面:函数参数、函数返回地址、临时变量等。
void example1()
int a = 10;
int b = 20;
printf("a = %d\\n", &a);
printf("b = %d\\n", &b);
//a的地址大于b的地址,故而生长方向向下
堆区由程序员手动申请,手动释放,若不手动释放,程序结束后由系统回收,生命周期是整个程序运行期间。使用malloc或者new进行堆的申请。
char* func()
char* str = malloc(100);
strcpy(str, "charles!");
printf("%s\\n",str);
return str;
void example1()
char* p = NULL;
p = func();
printf("%s\\n",p);
2.2、全局、静态区
全局静态区内的变量在编译阶段已经分配好内存空间并初始化。这块内存在程序运行期间一直存在,它主要存储全局变量、静态变量和常量。
1、静态存储区内的变量若不显示初始化,则编译器会自动以默认的方式进行初始化。
2、全局静态存储区内的常量分为常变量和字符串常量。静态存储区内的常变量是全局变量,与局部常变量不同,区别在于局部常变量存放于栈,实际可间接通过指针或者引用进行修改,而全局常变量存放于静态常量区则不可以间接修改;字符串常量存储在全局/静态存储区的常量区。
位运算
3、位运算基础
3.1、按位取反
一元运算符~将每个1变为0,将每个0变为1。
unsigned char a = 2; //00000010
unsigned char b = ~a; //11111101
printf("ret = %d\\n", a); //ret = 2
printf("ret = %d\\n", b); //ret = 253
3.2、按位与
对于每个位,只有两个操作数的对应位都是1时结果才为1,否则为0。
(10010011) & (00111101)
//(00010001)
3.3、按位或
对于每个位,如果其中任意操作数中对应的位为1,那么结果位就为1。
(10010011)| (00111101)
//(10111111)
3.4、按位异或
二进制运算符^对两个操作数逐位进行比较。两数相同为0,相反为1。
(10010011)^ (00111101)
//10101110)
两数之间的交换可以用异或实现。如
int a = 10;
int b = 30;
a ^ b = temp;
a ^ temp = b;
b ^ temp = a
3.5、左移
左移运算符<<将其左侧操作数的值的每位向左移动,移动的位数由其右侧操作数指定。左移一位相当于原值*2。
(10001010) << 2
//(00101000)
2 << 1 = 4;
4 << 1 = 8;
8 << 2 = 32
3.6、右移
右移运算符>>将其左侧的操作数的值每位向右移动,移动的位数由其右侧的操作数指定。左移一位相当于原值/2。
(10001010) >> 2
//(00100010)
number << n | number乘以2的n次幂 |
number >> n | 如果number非负,则用number除以2的n次幂 |
以上是关于C基础笔记一的主要内容,如果未能解决你的问题,请参考以下文章