char short int float long double
所占字节 32和64位系统有所区别 sizeof()
数组、链表、栈、队列、tree
++i
i++
--i
if(a<1){
xxx
}else if(a==1){
xxx
}else{
xxx
}
switch(a){ //a整形数据
case 1:
xxx
case 2:
xxx
case 3:
xxx
default:
xxx
}
for(int i=0;i<100;i++){
xxx
}
while(i<100){
xxxx
}
do{
xxx
}while(i<100)
int *p[]= {};
内存的地址,C语言允许用一个变量来存放指针,这种变量称为指针变量。指针变量可以存放基本类型数据的地址,也可以存放数组、函数以及其他指针变量的地址。
struct Stu{
char *name;
int num;
int age;
char group;
float score;
};
或
typedef struct{
char *name;
int num;
int age;
char group;
float score;
}Stu;
结构体变量必须初始化,malloc、new
C
Stu *stu = malloc(sizeof(Stu))
C++
Stu *stu = new Stu()
stu->age
stu.age
一个程序本质上都是由 Bss 段、Data段、Text段三个组成的
通常是指用来存放程序执行二进制代码
一般是指用来存放程序中未初始化的全局变量
包括三部分 heap(堆)、stack(栈)和静态数据区。
int a = 0; //全局初始化区,静态数据区
char *p1; //全局未初始化区 bss段
char* func(){//写法正确
char *str = "hello,world";
return str;
}
char* func1(){//写法错误,数组是不能作为函数返回值的,编译器把数组名认为是局部变量(数组)的地址,所以要用指针代替
char str[20] = "hello,world";//如果非要返回,可以用static修饰
return str;
}
char* func2(){
char *str = (char*)malloc(20);
str = "hello,world";
return str;//返回堆内存的指针
}
int main(int argc, const char*argv[])
{
static int a = 0; //全局(静态)初始化区,静态数据区
int b; //栈
char s[10] = "abc"; //字符串和s都是栈区,字符数组s在栈区分配内存
char *p3 = "bilei"; //"bilei"在常量区,p3在栈区
p2 = (char *)malloc(20); //分配成功堆区
//p2用完后必须主动释放
free(p2);
p2=NULL;//防止产生野指针。所谓野指针,即它指向的内存已被释放,单指针本身未释放,它指向的一块“垃圾”
}
push、pop、add、sub、mov、lea、ldr、str、cmp、bl、blx、call(x86)
ret
push 压栈 pusb rbp
pop 出站. pop rbp
add :add eax,2 //eax = eax+2
sub :sub eax,2 //eax = eax-2
mov :赋值指令
ldr :读取
str :存储
mov R0, 1 //将0赋值给寄存器r0
LDR R0,[R1] // 将存储器地址为R1的字数据读入寄存器R0
LDR R0,[R1,R2] // 将存储器地址为R1+R2的字数据读入寄存器R0
LDR R0,[R1,#8] // 将存储器地址为R1+8的字数据读入寄存器R0
LDR R0,[R1,R2]! // 将存储器地址为R1+R2的字数据读入寄存器R0,并将新地址R1+R2写入R1
LDR R0,[R1,#8]! // 将存储器地址为R1+8的字数据读入寄存器R0,并将新地址R1+8写入R1
LDR R0,[R1],R2 // 将存储器地址为R1的字数据读入寄存器R0,并将新地址R1+R2写入R1
LDR R0,[R1,R2,LSL#2]! // 将存储器地址为R1+R2×4的字数据读入寄存器R0,并将新地址R1+R2×4写入R1
LDR R0,[R1],R2,LSL#2 // 将存储器地址为R1的字数据读入寄存器R0,并将新地址R1+R2×4写入R1
STR R0,[R1],#8 // 将R0中的字数据写入以R1为地址的存储器中,并将新地址R1+8写入R1
STR R0,[R1,#8] // 将R0中的字数据写入以R1+8为地址的存储器中
函数执行前后,函数里面的堆栈要保持不变,如果变了,也就是用了push、sub sp ,0x10,那么一定要在函数ret之前,恢复对栈原来的样子 (pop, add sp, 0x10). 如果堆栈不平衡,程序就会崩溃
rax,rbx,rcx,rdx,esi,edi,rbp,rsp,r8,r9,r10,r11,r12,r13,r14,r15。其中:
rax 作为函数返回值使用。
rsp 栈指针寄存器,指向栈顶
rdi,rsi,rdx,rcx,r8,r9 用作函数参数,依次对应第1参数,第2参数。。。
rbx,rbp,r12,r13,14,15 用作数据存储,调用子函数之前要备份它,以防他被修改
r10,r11 用作数据存储,使用之前要先保存原值
main: # @main
push rbp //压栈
mov rbp, rsp
sub rsp, 48 //分配栈空间 rsp栈顶指针
mov dword ptr [rbp - 4], edi
mov qword ptr [rbp - 16], rsi
mov eax, dword ptr [.L__const.main.s]
mov dword ptr [rbp - 24], eax
movabs rax, offset .L.str
mov qword ptr [rbp - 40], rax
mov edi, 20
call malloc
mov qword ptr [rbp - 32], rax
mov rdi, qword ptr [rbp - 32]
call free
mov qword ptr [rbp - 32], 0
xor eax, eax
add rsp, 48 //堆栈平衡
pop rbp //出站
ret
a:
.long 0 # 0x0
p1:
.quad 0
.L__const.main.s:
.asciz "abc"
.L.str:
.asciz "bilei"
main:
push {r11, lr}
mov r11, sp
sub sp, sp, #24
str r0, [r11, #-4]
str r1, [r11, #-8]
ldr r0, .LCPI0_0
str r0, [sp, #8]
ldr r0, .LCPI0_1
str r0, [sp]
mov r0, #20
bl malloc
str r0, [sp, #4]
ldr r0, [sp, #4]
bl free
mov r0, #0
str r0, [sp, #4]
mov sp, r11
pop {r11, lr}
bx lr
.LCPI0_0:
.long 6513249 @ 0x636261
.LCPI0_1:
.long .L.str
a:
.long 0 @ 0x0
p1:
.long 0
.L.str:
.asciz "bilei"
main: // @main
sub sp, sp, #64 // =64
stp x29, x30, [sp, #48] // 16-byte Folded Spill
add x29, sp, #48 // =48
stur w0, [x29, #-4]
stur x1, [x29, #-16]
adrp x8, .L__const.main.s
add x8, x8, :lo12:.L__const.main.s
ldr w9, [x8]
str w9, [sp, #24]
adrp x8, .L.str
add x8, x8, :lo12:.L.str
str x8, [sp, #8]
mov x0, #20
bl malloc
str x0, [sp, #16]
ldr x0, [sp, #16]
bl free
str xzr, [sp, #16]
mov w9, wzr
mov w0, w9
ldp x29, x30, [sp, #48] // 16-byte Folded Reload
add sp, sp, #64 // =64
ret
a:
.word 0 // 0x0
p1:
.xword 0
.L__const.main.s:
.asciz "abc"
.L.str:
.asciz "bilei"
学习网站:https://godbolt.org/ https://files.cnblogs.com/files/pythonywy/测试so.zip
#include <stdlib.h>
#include <stdio.h>
typedef struct{
int age;
char *name;
int grade;
short fenshu;
}Student;
struct Test{
int num;
char c;
short data;
};
int sum(int a, int b){
return a+b;
}
void sum1(int *a){
a[1] = 2;
}
int main(int argc, const char * argv[]) {
// char *result_func = func();
for(int i=0;i<100;i++){
printf("%s\n",func3());
}
for(int i=0;i<100;i++){
printf("%s\n",func1());
}
for(int i=0;i<100;i++){
printf("%d\n",func2());
}
int a=2;
int array[8] = {1,2,3,4,5,6,7,8};
int array1[8] = {1,2,3,4,5,6,7,8};
int array2[8] = {1,2,3,4,5,6,7,8};
int array3[][3] = {{1,2,3},{4,5,6},{7,8,9}};
int *p_array[8] = {array,array1,array2};
int (*q_array)[3] = &array3[0];
int (*fun_p)(int a, int b);//函数指针
fun_p = sum;//将函数的首地址赋值给fun_p
int size1 =(int) sizeof(Test);
Student *stu = new Student();//申请内存空间,也可以mac
int size =(int) sizeof(Student);
stu->name = "bilei";
stu->age = 8;
stu->grade = 2;
int a = (*fun_p)(1,2);
char *q = (char*)malloc(8);
q = (stu->name);
int aa = *(q +1);
a = stu->name[1];
if(a>0){
a = sum(a, stu->age);
}
switch (a){
case 1:
a = a<<1;
case 2:
a = a<<2;
case 3:
a = a<<3;
case 4:
a = a<<4;
default:
a = a;
}
stu->grade = a;
short b = 2;
long l = 3;
char c = 'v';
char *p = "hello,world";
char q1 = *(p+1);
char s = *p+1;
sum1(array);
}