学习笔记—C语言基础篇07

作用域:
局部变量:在函数内部定义的变量称为局部变量(auto),作用域为局部变量创建到函数结束;
全局变量:在函数外部定义的变量,作用于整个程序;
如果在代码中全局变量与局部变量有相同变量名,局部变量覆盖全局变量;
static:如果没初始化默认设置的值为0
静态局部变量:程序创建之初定义,只能在程序创建时被初始化一次,作用域 为函数内部;
静态全局变量:程序创建之初定义,只能在程序创建时被初始化一次,作用域缩小为只在本文件有效;
全局函数:在程序中声明的函数默认为全局函数,作用于整个项目;
静态函数:加static修饰,作用域缩小为只在本文件有效,如果和全局函数重名那么在该文件中使用static修饰的函数;
内存布局
内存可执行程序四区模型

代码区:
存放计算机程序指令
只读,共享

数据区:
1.字符串常量 char* s = "hello";
2.初始化数据区:
全局变量,全局常量,static修饰的全局,局部变量
3.未初始化数据区:(bss段)
全局变量,全局常量,static修饰的全局,局部变量
栈区:
在程序加载到内存中,系统自动分配给每个程序一定的空间(一般情况windos下一般为1-8M,linux下一般为1-16M)用来存储数据,当程序执行完成,系统自动回收
存放:局部变量,const修饰的常量(必须是局部变量),指针,结构体,联合体,枚举,函数的形参
堆区:
由程序员自己分配和释放的空间。
堆空间开辟
malloc / calloc / realloc
释放
free
内存模型
                                                                    合称数据区
代码区 data区 bss区 
堆区
栈区
开辟二级指针空间
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>

int main()
{
      //先开辟外层空间存储一级指针
      int **p = (int**)malloc(sizeof(int*)* 3);

      for(int i = 0; i < 3;i++)
      {
            //开辟一级指针存变量地址
            p[i] = (int*)malloc(sizeof(int*)*3);
      }

      for(int i = 0; i < 3;i++)
      {
            int sum = 0;
            for(int j = 0; j < 3; j++)
            {
                  scanf("%d",&p[i][j]);
                  sum += p[i][j];
            }
            printf("总成绩 %d\n",sum);
      }
//释放内存空间
      for(int i = 0; i < 3;i++)
      {
            free(p[i]);//先释放内层
            p[i] = NULL;
      }
      free(p);//再释放外层
      p = NULL;
      system("pause");
      return 0;
}
memset
#include <string.h>
void * memset ( void * s 地址 , int c , size_t n );
功能:将s的内存区域的前n个字节以参数c填入
参数:
       s:需要操作内存s的首地址
       c:填充的字符,c虽然参数为int,但必须是 unsigned char , 范围为0~255
       n:指定需要设置的大小
返回值:s的首地址
strcpy(操作的字符串
#include <string.h>
char * strcpy ( char * dest , const char * src );
功能:把src所指向的字符串复制到dest所指向的空间中, '\0'也会拷贝过
参数:
       dest:目的字符串首地址
       src:源字符首地址
返回值:
       成功:返回dest字符串的首地址
       失败:NULL
注意: 如果参数dest所指的内存空间不够大,可能会造成缓冲溢出的错误
strncpy
#include <string.h>
char * strncpy ( char * dest , const char * src , size_t n );
功能:把src指向字符串的前n个字符复制到dest所指向的空间中, 是否拷贝结束符看指定的长度是否包含 '\0'
参数:
       dest:目的字符串首地址
       src:源字符首地址
       n:指定需要拷贝字符串个数
返回值:
       成功:返回dest字符串的首地址
       失败:NULL
memcpy(操作的一块内存空间以字节为单位
#include <string.h>
void * memcpy ( void * dest , const void * src , size_t n );
功能:拷贝src所指的内存内容的前n个字节到dest所指的内存地址上。
参数:
       dest:目的内存首地址
       src:源内存首地址, 注意:dest和src所指的内存空间不可重叠
       n:需要拷贝的字节数
返回值:dest的首地址
注意:当拷贝源和目标发生冲突时会可能会拷贝失败
memmove:相比memcpy更安全
memmove()功能用法和memcpy()一样,区别在于:dest和src所指的内存空间重叠时,memmove()仍然能处理,不过执行效率比memcpy()低些(如果 dest和src 内存 有冲突memmove会去开辟一个临时的空间,存储src所指的内存空间 的内容 )。

memcmp
#include <string.h>
int memcmp ( const void * s1 , const void * s2 , size_t n );
功能:比较s1和s2所指向内存区域的前n个字节
参数:                                                        返回值:
       s1:内存首地址1                                相等:=0
       s2:内存首地址2                                大于:>0
       n:需比较的前n个字节                      小于:<0

开辟堆空间易错点
char* s = NULL;
s = (char*)malloc(sizeof(char)*10); //堆区
s = "hello"; //此时s被修改到了字符串常量区了
printf("%p",s);
free(s); //此时找不到s的地址,会报错

开辟堆空间大小易错点
1、
int main()
{
     int* p = (int*)malloc(0);//开辟0个空间大小 程序不会报错 但是个野指针
     *P = 100;//操作野指针 可能会报错
     free(p);
}

2、
int main()
{
     int* p = (int*)malloc(2);//申请2个字节
     *P = 100;//操作4个字节
     free(p); //操作额外空间会出错
}
 
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值