C语言数组与指针的讲解
数组:数组是一种构造数据类型,我们通常说的数组是指的数组变量。
int [10] 和 int [5]是两种数据类型
char [20] 和 char [5]是两种数据类型
一维数组:
<1>正常的一维数组
(1)数组变量的定义:
<存储类型><数据类型修饰符><数据类型说明符><数组名>[<数组元素个数>];
存储类型:auto、static、register、extern、typedef
auto表明一个变量具有自动存储时期。
register只能用于具有代码块作用域的变量。
static:当用于具有代码块作用域的变量的声明时,使该变量具有静态存储时期,从而得以在程序运行期间存在并保留其值。 变量仍具有代码块作用域和空链接。
static用于具有文件作用域的变量的声明时,表明该变量具有内部链接。
extern表明一个已经在别处定义了的变量。
typedef在计算机编程语言中用来为复杂的声明定义简单的别名,与宏定义有些差异
数据类型修饰符:const
数据类型说明符:signed、unsigned、char、short、int、long、long long、float、double、struct、union、int *
数组名:
static const charbuf[5];
(2)数组变量的初始化:
int arr[] ={1,2,3};
int arr[5] ={1,2,3,4,5};
int arr[5] ={1,2,3};
int arr[5] = {0};
<2>一维char数组
char arr[10];
<3>字符串
char str[] ={"abcd"};
char str1[] ="hello world";
字符串是一种特殊的一维数组:以0为结尾。
0,'\0',NULL是一回事
char str[] ="strlen";
strlen:求字符串长度
冒泡排序:
int i,j,temp;
for(i = 0; i < num-1; i++)
{
for(j = 0;j < num-1-i; j++)
{
if(arr[j]< arr[j+1])
{
temp= arr[j];
arr[j]= arr[j+1];
arr[j+1]= temp;
}
}
}
冒泡排序的核心思想:
两两比较,小(大)的往后放
比较num-1趟,i代表趟数
每一趟比较从0位置开始,比较num-1-i次
二维数组:
<1>int的二维数组:int arr[2][3] = {1,2,3,4,5,6};
12 3 4
56 7 8
9 1011 12
数组名:
(1)代表整个数组
(2)代表数组的首地址
(3)代表第一个元素的地址
注意:数组名是一个指针常量不能为左值
一维组数组作为函数参数:
一维数组作为函数返回值:
二维数组:作为函数参数
二级指针:
首先任何值都有地址 ,一级指针的值虽然是地址,但这个地址做为一个值亦需要空间来存放,是空间就具有地址 ,这就是存放地址这一值的空间所具有的地址,二级指针就是为了获取这个地址。
一级指针所关联的是其值(一个地址)名下空间里的数据,这个数据可以是任意类型并做任意用途,但二级指针所关联的数据只有一个类型一个用途,就是地址,指针就是两个用途提供目标的读取或改写, 那么二级指针就是为了提供对于内存地址的读取或改写
指针的表现形式是地址,核心是指向关系指针,运算符“*”的作用是按照指向关系访问所指向的对象.如果存在A指向B的指向关系,则A是B的地址,“*A”表示通过这个指向关系间接访问B.如果B的值也是一个指针,它指向C,则B是C的地址,“*B”表示间接访问C如果C是整型、实型或者结构体等类型的变量或者是存放这些类型的数据的数组元素,则B(即C的地址)是普通的指针,称为 一级指针,用于存放一级指针的变量称为 一级指针变量。
A(即B的地址)是指向指针的指针,称为 二级指针,用于存放二级指针的变量称为 二级指针变量.根据B的不同情况,二级指针又分为指向指针变量的指针和指向数组的指针.
int arr[][3] = {1,2,3,4};
int (*parr)[3] = arr;
/*不用把一个行指针赋值给一个二级指针*/
int **parr = arr;
char *argv[3]:指针数组:每一个元素都是一个char *,一共有3个
char (*parr)[3]:数组指针:指向一个有3个char元素的数组
char **pp:pp是一个二级指针,指向一个char *,char *有很多种含义(char 数组的首地址, char变量的首地址,字符串的首地址)
int arr[5];
int *p = arr;
p[i] <===> *(p+i)
const *:
char *const p :不能更改p的指向,但是可以更改p指向的内容
const char *p :不能更改p指向的内容,但是可以更改p的指向
char const *p :不能更改p指向的内容,但是可以更改p的指向
const char * const p :即不能更改p的指向,也不能更改p指向的内容
指针操作注意的问题:
(1)注意指针的指向
(2)注意指针操作越界
(3)注意空指针和野指针
(4)注意const
(5)注意指针初始化为一个常量
初始化为 unsigned long 的常量(一般不用)
#define A(*((volatile unsigned int *)(0x0060febc)))
目的是为了操控一些片上系统( Soc )上的一些硬件。这些硬件有一些固定的基地址。
函数:
(1)函数声明:
(2)函数定义:
(3)函数调用:
(4)函数传参:
(5)函数回调:
函数指针:指向函数的指针
intadd(int, int);
int(*pfunc)(int, int); pfunc是函数指针,它指向这样一类函数(返回值为int,有两个int参数的函数)
指针函数:返回值为指针的函数
char*strcat(char *dest, const char *src);
pfunc =add;
pfunc(2,3);
(6)接口封装:
.h:
#ifndef__XXX_H__
#define__XXX_H__
函数声明;
#endif
.c
函数接口的实现
预编译指令:
#if
#ifndef
#endif
#define
#include
#ifdef
#elif
#error
#pragma
#undef
内存四区:
代码段:.text
静态常量区:.rodata
堆区:heap
栈区:stack
内存管理函数:
(1)malloc
(2)calloc
(3)realloc
(4)free
(5)memset