a[3][4]表示的是第4行第5列
a[i]表示的是第i=1个
从0开始,i表示个数
为了解决大量的同类型数据的存储和使用问题
为了模拟现实世界
数组有很多问题
数组长度是死的值
数组有很多功能是没有的
自己通常不定义数组
int[a]
int[b];
a=b
错误,因为ab都为常量,不能给常量赋值
int %d
long int %Ld
char c
float f
double lf
八进制 o
十六进制 #x
printf ("%#X\n",&a[0];
printf("%#X\n,a);
是一样的,
总结:一维数组名,一维数组名是第一个指针常量,它存放的是一维数组的第一个元素的地址
下标和指针的关系:如果p是个指针变量,则p[i]永远等价于*(p+i)
确定一维数组需要几个参数:数组名和长度(字符串可以,因为10不存在)
p是指针,Arr是数组名的意思
数组名是地址,是 int*,所以定义形式参数时使用地址
for循环中的语句用;
pArr 与 a 都为地址int*类型
pArr[3]=*(parr+3)与a[3]=*(a+3)是一样的
a[3]变量内容以十进制输出
通过修改pArr改变主函数中的值
通过修改f改变主函数中任意一个值
通过指针发送首元素地址和长度,可以让f函数修改b函数中所有的值
a= &a [0];
a = &a [2]'错误,a 是常量且存放的是首个元素的地址
pArr[2]=*pArr(a+2)=a[2]=*(a+2)
两个指针变量要在同一块连续空间中的不同存储单元才可以相减
一个指针变量,无论指向的变量占几个字节,该指针变量本身占字节4个
一个变量的地址使用该变量的首字节的地址来表示
char 一个字节
int 4个字节
double 8个字节
数据类型size of(int)=4 size of (double) = 8 size of (char) = 1
返回值就是该变量占的字节数
一个字节一个编号
32位,4个字节
动态内存分配
传统数组的缺点,也是静态数组:长度需要事先制定,且只能是长整数,不能是变量/程序员无法手动释放内存,只能运行完毕时自动释放/数组的长度一旦定义就不能变化/A函数在运行期间的数组可以被其他函数使用,但A函数结束,
数组无法被调用,无法跨函数使用
为什么需要动态分配内存:很好解决了传统数组的缺陷
动态数组的构造
静态内存和动态内存的比较
跨函数使用内存的问题
malloc是memory(内存)allocate(分配)的缩写
要使用mallocz必须要添加malloc.h的头文件
pree(p)表示把p的内存给释放掉,但本身的内存不能释放,因为它是静态的分配
int main (void)
int * p =(int *) malloc(4)
//malloc 只有一个形式参数,并且形参是整型
4表示请求系统为本程序分配4个字节
malloc函数只能返回第1个字节(不知道这个地址指向的变量占几个字节)前面一定要加(int * ) (char*)(double*)
p占4个字节(静态 )p所指向的内存也是4个字节(动态)
{
int i = 5 ;
int * p =(int*)malloc(4);
*p = 5;
free(p);
printf("同志们好\n");
return 0;
}
#include <stdio.h>
#include<malloc.h>
void f(int *q)
{
*q=200;(不能写**p因为*p是整型,整型前面不能加*)
free(q)错误(q指向四个字节,*q等于四个字节的内容被释放,无法输出*p)
int main (void)
{
int * p=int(*)malloc(sizeof(int));
*p=10;
printf("%d\n".*p);
f(p);
printf("%d\n",*p);
return 0;
}
143
#include <stdio,h>
int main (void)
{
int = [5];//int占4个字节,则本函数总共包含20个字节,每四个字节被当作一个int变量来使用
return 0;
}
pArr本身是指向第一个字节, 但是因为 int * pArr变成指向前四个字节
pArr = (int *)malloc(4 *len)=pArr[i]
动态定义数组,但是和静态数组使用时是一样的,同样可以写成int pArr[i],数组名是parr,数组长度是len,
#include<stdio.h>
#include<malloc.h>
int main(void)
{
int a[5];
int len; //由用户定义数组长度
int * pArr ;
//对动态的一维数组进行构造
printf("请输入你要存放的元素的个数”)
scanf("%d\n,&len);
pArr = (int*)malloc(4 * len);
//对一维数组进行操作
//对动态一维数组进行赋值
for(i=0;i<len;++i);
scanf("%d",&parr[i]);(格式控制,地址表列)
//对一维数组进行输出
printf("一维数组的内容是:\n");
for (i=0; i<len;++i)
printf("%d\n,parr[i]);
return 0;
}
动态数组在运行过程中无法动态的扩充或则缩小
realloc(praa,100);
144动态与静态比较
静态内存是在栈分配的
先让下一个语句的地址发送给上一个保存,再分配存储空间
main函数调用函数f,为f分配空间,在栈里面分配空间,终止后就出栈,空间就没有了。main函数在最下面,从栈顶开始执行
动态内存由程序员手动分配,手动释放,内存越来越少就是泄露
动态内存是在堆分配的,以排序的方式分配
排序,查找
找中间的值
动态内存是在堆里面分配,用完之后不会释放内存
#include <stdio.h>
int main (void)
{
int i =10 ;
int * p =&i;
int **q =&p;
int ***r =&q;
//r=&p;//因为r是int***的类型,r只能存放int **类型变量的地址
void f(int **q)
void g (int ** p)
g(&p);
printf("i = %d\n,***r);
return 0;
}
{
//*q是p,**q是&p
}
void g()
[
int i =10;
int * p = &i;
f(&p);
}
int main (void)
{
g()
return 0 ;
}
int i = 10;
int * p=&i;
int **q = &p;
int***r = &q;
void f (int **q)
{
//*q就是p **q是&p
void g ()
{
int i =10;
int * p = &i;
f(&p);
}
int main (void)
{
g()
return 0 ;
}
146
//可以成功修改17行动态分配的这四个字节的内容
void f(int *q)
{
*q = 10
}
{
}
int main (void )
{
int * p = (int *)malloc(4);//17行 *p=10
printf ("*p=%d\n",*p);
printf("*p=%d\n,*p);
return 0 ;
}
跨函数指针
#include<stdio.h>
void f (**q)
{
int i = 5;
//*q=p,
//*q = i(错误,因为*q=p,p=i)不成立
*q=&i;//p = & i
}
int main (void)
{
int * p;
f (&p)
printf("%d\n,*p);本语句没有语法错误,但是逻辑上有错误(因为函数执行完会释放空间,无法读取i的空间)
return 0;
}
要想修改p的值,只能发送p的地址,指针变量地址只能写**类型既然q存放的是*p 的地址那么*q就是p,把i 的地址发送给 *q=p,p是i的地址,*p就是i
p可以存放i的地址
#include <stdio.h>
#include<malloc.h>
void f(int **q)
{
*q = (int *)malloc(sizeof(int));
**q=5;
}
int main(void)
{
int * p;(p为地址)
f(&p);
printf("%d\n",*p);
return 0;
}