### 数据类型的本质

> 数据类型可理解为创建变量的模具(模子);是固定大小内存的别名.

> 变量本质:( 一段连续)内存空间的别名、内存空间的标号.

> 数据类型的作用 :编译器预算对象(变量)分配的内存;也间接指出了变量的解析方式.

### 指针铁律

a.指针是一种数据类型,是指向它指向的内存空间的数据类型.

> 指针也是一种变量 ,占用内存空间,保存内存地址.<指针变量与它所指向内存空间是两个不同的概念>

& 站在编译器的角度,形参如果是指针类型,C编译器只会分配4个字节的内存.

void function(char ***pt);

& 当我们使用指针的时候,我们才关心这个内存块是一维的,还是二维的。

> 指针指向谁,就把谁的地址赋给指针: pt = &a;

> 指针的步长,根据它所指向的内存空间的类型来决定的.<类型决定解析方式>

b.通过*pt来访问和修改实参的值是指针存在的最大意义

& 在函数调用的时候

用1级指针形参,去间接修改 0级指针(实参)的值。

用2级指针形参,去间接修改 1级指针(实参)的值。

用3级指针形参,去间接修改 2级指针(实参)的值。

用n级指针形参,去间接修改 n-1级指针(实参)的值。

c.辅助指针:处理业务逻辑时常添加一个或两个辅助指针(px,py)来解决问题

uint8_t *pt = (uint8_t *)[data bytes];// uint8_t占1个字节.

### 函数指针与指针函数

void (*foo)(int num);//指向参数为int,返回值为void的函数的指针,函数指针

void func(int);//func是函数的入口地址;&func是函数指针,类型是void(*)(int)

void *foo(int num);//指针函数,返回值为指针的函数

const int *pci; //指向const int的指针就是指向整数常量的指针

int* const pci; //指向int型变量的常量指针,指针地址不可修改.

### 数组指针和指针数组

int (*p)[10] ;//数组指针,p指向的是一个带10个int型元素的数组.

int* arr[5];//指针数组,数组中每一个元素都是指针.

a[i] 等价于 *(a+i);//数组的本质是一段连续的存储空间;

1)数组首元素的地址和数组地址是两个不同的概念

2)数组名代表数组首元素的地址,它是个常量

3)数组首元素的地址和数组的地址值相等

比如int a[10] => a是数组首元素的地址;&a是数组指针,类型是int(*)[10].//&a+1按照步长去理解

typedef int MyArrayType[10];//定义一个int a[10]的数组类型

typedef int (*MyPArrayType)[10];//定义一个指针类型,定义一个指向数组(int a[10])的指针类型.

扩展: int myarr[3][5];# myarr是一个数组指针。

理解: *(*(myarr+i)+j);// *(myarr+i)表示到第几行,记住指针的步长就ok.

### 数组作函数的参数

> C语言中只会以机械式的值拷贝的方式传递参数(实参把值传给形参)

数组参数                           等效的指针参数

一维数组 char a[30] <=>     指针 char*

指针数组 char *a[30] <=>  指针的指针 char **a

二维数组 char a[10][30] <=> 数组指针 char(*a)[30]

& 当数组作函数参数的时候会退化为指针.

& 总结:函数调用的时候,把数组首地址和有效数据长度传给被调函数才是最正确的做法.

### 二级指针的3种内存模型

a.第一种内存模型

// char *arr[] = {"cmc","abc","ycs","1111"};

// arr是个二级指针,和int a[10] 级指针不一样,sizeof(arr)=32; []相当于一个指针

void printArray(char **arr,int len){ for (int i = 0; i < len; i++) {

printf("%s,",arr[i]);// *(arr+i) }

}

b.第二种内存模型

// char pArray[10][30] = {"cmc","abc","ycs","1111"};

int printAarray02(char pArray[10][30], int num)

{

for (int i=0; i<num; i++) {

printf("%s \n", pArray[i]); }

return 0; }

c.第三种内存模型

char **pArray = (char**)malloc(10*sizeof(char*));

for (int i = 0; i < 10; i++) {

pArray[i] = (char *)malloc(16*sizeof(char));//分别赋值,可以让字符串长度不一样

}

for (int i = 0; i < 10; i++) {

free(pArray[i]);//释放内存 }

free(pArray);

### 多维数组的本质

// arr的本质是一个数组指针,每次往后跳一维的维数,这里是5*4个字节

int arr[3][5];// arr+i相当于跳到第i行

int (*pArray)[5];

pArray = arr;

int temp = 0;

for (int i=0; i<3; i++) {

for (int j=0; j<5; j++) {

pArray[i][j] = ++temp;

} }

### 数组指针的使用

typedef int MyArrayType[5];

int a[5];

MyArrayType *pArray = &a;//定义一个数组类型的指针

//我通过数组指针的方式来操作a[5]这块内存

for (int i=0; i<5; i++)

{

(*pArray)[i] = i+1; //a[i] = i+1;

}

### 结构体内存对齐

字节对齐的细节和编译器实现相关,但一般而言,满足三个准则:
1) 结构体变量的首地址能够被其最宽基本类型成员的大小所整除;
2) 结构体每个成员相对于结构体首地址的偏移量(offset)都是成员大小的整数倍,如有需要编译器会在成员之间加上填充字节(internal adding);
3) 结构体的总大小为结构体最宽基本类型成员大小的整数倍,如有需要编译器会在最末一个成员之后加上填充字节(trailing padding)。

**说明:

字节对齐第3条准则提及最宽基本类型的概念,所谓基本类型是指像char、short、int、float、double这样的内置数据类型。“数据宽度”就是指其sizeof的大小。诸如结构体、共用体和数组等都不是基本数据类型。除结构体的第一个成员外,其他所有的成员的地址相对于结构体地址(即它首个成员的地址)的偏移量必须为实际对齐单位或自身大小的整数倍(取两者中小的那个)

struct A
{char c;short a;int i;
}; 

sizeof(A) = 8;

C语言基础总结Part相关推荐

  1. 【python语言基础】疑难点整理2

    [python语言基础]疑难点整理1 第五章 在python语法中,循环体中的语句没有做限制,因此,可以是任何合法语句,当然也可以是循环语句.这样就形成了循环语句的嵌套. while循环语句和for循 ...

  2. r语言 断轴 画图_R语言基础画图/绘图/作图

    R语言基础画图 R语言免费且开源,其强大和自由的画图功能,深受广大学生和可视化工作人员喜爱,这篇文章对如何使用R语言作基本的图形,如直方图,点图,饼状图以及箱线图进行简单介绍. 0 结构 每种图形构成 ...

  3. fig r函数_R语言基础绘图函数散点图~跟着Nature Communications学画图~Figure1

    今天继续 跟着Nature Communications学画图系列第二篇.学习R语言基础绘图函数画散点图. 对应的 Nature Communications 的论文是 Fecal pollution ...

  4. 学单片机需要多少C语言基础,C语言单片机编程教程

    很多学员和朋友经常找我给他们推荐C语言的书,他们可能想和我当年一样,闷头大干一场,学个几个月的C语言,把C语言吃透,再开始单片机程序开发! 别!别!别! 大家千万别这么干,我当年自学了3个月的C语言, ...

  5. %3c- r语言运算符,R语言基础教程之运算符

    原标题:R语言基础教程之运算符 运算符类型 在R编程中有以下类型的运算符 - 算术运算符 关系运算符 逻辑运算符 赋值运算符 其他运算符1.算术运算符 下表显示了R语言支持的算术运算符.运算符对向量的 ...

  6. c++把数组所有元素剔除_C语言基础之数组,第一节,C语言必学知识点剖析

    本文约1600字,主要讲了C语言基础之数组.数组又可分为数值数组.字符数组.指针数组.结构数组等各种类别.本文主要讲了数组的基础概念,一维数组的定义和引用. 带你进入C语言的世界,入门C语言,后边将持 ...

  7. matlab语言实验二,实验二 MATLAB语言基础

    实验二 MATLAB 语言基础 一.实验目的 基本掌握 MATLAB 向量.矩阵.数组的生成及其基本运算(区分数组运算和矩阵运算).常用的数学函数.了解字符串的操作. 二.实验内容 (1) 向量的生成 ...

  8. R语言基础知识详解及概括

    R语言基础知识详解及概括 目录 R语言基础知识详解及概括 R数据可视化示例 R语言进行数据创建

  9. 实验四 数据库SQL语言基础编程

    -- 实验四 数据库SQL语言基础编程 -- 实验目的: --  掌握数据库查询语句的编写方法 --  掌握利用查询语言完成基本查询 --  掌握利用SQL语句完成数据的添加.删除.修改操作 -- 实 ...

  10. 数据分析必备:掌握这个R语言基础包1%的功能让你事半功倍!(附代码)

    来源:大数据 本文约7100字,建议阅读15分钟. 本文介绍了utils包在R语言基础的用途. [ 导读 ]无论数据分析的目的是什么,将数据导入R中的过程都是不可或缺的.毕竟巧妇难为无米之炊.util ...

最新文章

  1. burn android images with fastboot
  2. python自动化办公入门书籍推荐-盘点使用Python进行自动化办公所需要的知识点
  3. (转)MySQL索引原理及慢查询优化
  4. Windows10 UWP开发 - 响应式设计
  5. python数据结构与算法第10讲_python数据结构与算法(10)
  6. Hanoi(汉诺)塔问题
  7. JDK 18 / Java 18 GA 发布
  8. Elasticsearch学习系列-搜索技术基本知识
  9. 基于JAVA+SpringMVC+Mybatis+MYSQL的软件办公管理系统
  10. Java抽象类/接口
  11. 干货| 掌握这种逻辑思维,大厂面试成功率可提升90%
  12. 大量字段表单在PHP便捷处理分享
  13. 超级外链工具-在线SEO超级外链群发工具免费
  14. win10读不到移动硬盘
  15. moment 计算日期差
  16. 每位开发人员都应铭记的10句编程谚语
  17. 计算机硬盘里没有内容却显示有,为什么电脑磁盘里头明明没有东西,也没隐藏文件,却显示用了12个G。求解!...
  18. 【C++学习笔记】标准库类型vector
  19. CC00027.hadoop——|HadoopHive.V27|——|Hive.v27|Hive优化策略|实战.v03|
  20. Python 习题 老虎、棒棒、鸡、虫

热门文章

  1. (软件工程复习核心重点)第二章可行性研究-第一节:可行性研究基本介绍
  2. Linux系统编程1:基础篇之Linux中使用率最高的一些命令
  3. glibc free 死锁
  4. SGCheck:一个实验堆栈和全局数组溢出检测器
  5. Qt之线程同步(生产者消费者模式 - QWaitCondition)
  6. C/C++ getopt()函数的介绍及使用
  7. python判断进程是否存在
  8. 图:图的邻接表创建、深度优先遍历和广度优先遍历代码实现
  9. 【洛谷习题】填涂颜色
  10. dedecns 表结构