c语言基础知识记录
一、数据类型
数据类型:本质是固定大小内存块的别名 变量:本质为一段连续内存空间的别名
int a;
int b[10];
printf("b:%d, b+1:%d, &b:%d, &b+1:%d\n", b, b+1, &b, &b+1);
sizeof:计算数据类型占内存空间的大小,返回类型为unsigned int typedef:给已经存在的数据类型起别名,自定义类型
typedef long long UU_LONG;
二、内存模型
1.几个区
栈区:自动申请自动释放,主要是局部变量(函数参数形参)、数组(char str[]=“hello world”)
堆区:手动申请,手动释放
(1)c语言:malloc/free (函数)malloc不一定能分配成功,返回void *
注意: free释放的是ret指针指向的内存空间,但是ret指针本身是没有变化的
free(ret);
ret=NULL;
图解: (2)c++:new/delete (操作符)new一定能分配成功
全局区:
int a = 100;
extern int a = 100;
static int b = 100;
2.方向
(1)栈的生长方向:取决于开口方向 (2)内存的生长方向 大端模式:低位字节——>高位字节 (下图右) 小端模式:低位字节——>高位字节 (下图左)
三、指针 指针变量
1.概念
- 指针是一种数据类型,用来保存内存地址
- 不管几级(
* ** *** )、指向什么样的类型的数据,指针变量都是占4个字节 - 指针的意义:间接赋值
2.野指针
野指针:是指指向一个已经删除的对象,或者是未申请访问权限内存区域的指针 后果:内存泄漏 具体情况: (1)指针变量没有初始化
int* p;
printf("%d",*p);
所以一拿到指针变量就直接置空
(2)指针指向的内存释放了,但是指针没有置空 free(p) 只释放p指向的内存释放掉了,但是对p没有任何操作
free(p);
p=NULL;
(3) 越界访问
char str[3] = "abc";
字符串最后有一个\0
3.指针的步长
指针步长:指针+1(加了多少字节),取决于指针指向的数据的类型
char *p = NULL;
printf("%d\n",p);
printf("%d\n",p+1);
int *q = NULL;
printf("%d\n",q);
printf("%d\n",q+1);
char buf[1024] = { 0 };
printf("%d\n",buf);
printf("%d\n",&buf);
printf("%d\n",buf+1);
printf("%d\n",&buf+1);
几个常用的库函数: memcpy :void *memcpy(void *str1, const void *str2, size_t n) 从存储区 str2 复制 n 个字节到存储区 str1 memset :void *memset(void *str, int c, size_t n) 复制字符 c(一个无符号字符)到参数 str 所指向的字符串的前 n 个字符
4.指针的特性
(1)输入特性
void p_intArray(int* arr , int len );
(2)输出特性
分配空间
void allocateSpace(char** p );
四、引用(变量的别名)[c++]
int a;
int *p=&a;
int &b=a;
(int &b=a和int* const pp=&a;一样不能改变指向的对象,但能改变指向对象的值)
符号表存放内容: 变量名 变量地址 【符号表生成后不再改变】
int a a a的地址
指针p: 指针名 指针地址 而指针指向的a地址(存放的数据)可以改变 【不安全】
引用b: 引用名b 引用对象a的地址→→→故引用对象不能改变 【安全】
1.数组引用
先定义数组类型,再创建引用
typedef int ARR_TYPE[3];
ARR_TYPE[3]& arrRef = arr;
或者直接给数组取别名:
int(&rf)[3] = arr
2.函数中引用
函数中的引用:函数的参数、函数的返回值 (1)在函数作传参使用 传递一个引用→→必然存在且有效【安全但没有指针快,一个地址总比复杂数据传递快】(用的) 传递一个指针→→指针不一定有效【需要判断所传递指针是否非空】
|