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循環(huán)中的語句用;
pArr 與 a 都為地址int*類型
pArr[3]=*(parr+3)與a[3]=*(a+3)是一樣的
a[3]變量內容以十進制輸出
通過修改pArr改變主函數中的值
通過修改f改變主函數中任意一個值
通過指針發(fā)送首元素地址和長度迄薄,可以讓f函數修改b函數中所有的值
a= &a [0];
a = &a [2]'錯誤琅关,a 是常量且存放的是首個元素的地址
pArr[2]=*pArr(a+2)=a[2]=*(a+2)
兩個指針變量要在同一塊連續(xù)空間中的不同存儲單元才可以相減
一個指針變量煮岁,無論指向的變量占幾個字節(jié)讥蔽,該指針變量本身占字節(jié)4個
一個變量的地址使用該變量的首字節(jié)的地址來表示
char 一個字節(jié)
int 4個字節(jié)
double 8個字節(jié)
數據類型size of(int)=4? size of (double) = 8 size of (char) = 1
返回值就是該變量占的字節(jié)數
一個字節(jié)一個編號
32位,4個字節(jié)
動態(tài)內存分配
傳統(tǒng)數組的缺點画机,也是靜態(tài)數組:長度需要事先制定冶伞,且只能是長整數,不能是變量/程序員無法手動釋放內存步氏,只能運行完畢時自動釋放/數組的長度一旦定義就不能變化/A函數在運行期間的數組可以被其他函數使用响禽,但A函數結束,
數組無法被調用,無法跨函數使用
為什么需要動態(tài)分配內存:很好解決了傳統(tǒng)數組的缺陷
動態(tài)數組的構造
靜態(tài)內存和動態(tài)內存的比較
跨函數使用內存的問題
malloc是memory(內存)allocate(分配)的縮寫
要使用mallocz必須要添加malloc.h的頭文件
pree(p)表示把p的內存給釋放掉芋类,但本身的內存不能釋放隆嗅,因為它是靜態(tài)的分配
int main (void)
int * p =(int *) malloc(4)
//malloc 只有一個形式參數,并且形參是整型
4表示請求系統(tǒng)為本程序分配4個字節(jié)
malloc函數只能返回第1個字節(jié)(不知道這個地址指向的變量占幾個字節(jié))前面一定要加(int * ) (char*)(double*)
p占4個字節(jié)(靜態(tài) )p所指向的內存也是4個字節(jié)(動態(tài))
{
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指向四個字節(jié),*q等于四個字節(jié)的內容被釋放贮竟,無法輸出*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個字節(jié)丽焊,則本函數總共包含20個字節(jié),每四個字節(jié)被當作一個int變量來使用
return 0;
}
pArr本身是指向第一個字節(jié)咕别, 但是因為 int * pArr變成指向前四個字節(jié)
pArr = (int *)malloc(4 *len)=pArr[i]
動態(tài)定義數組技健,但是和靜態(tài)數組使用時是一樣的,同樣可以寫成int pArr[i],數組名是parr惰拱,數組長度是len,
#include<stdio.h>
#include<malloc.h>
int main(void)
{
int a[5];
int len雌贱;? ? //由用戶定義數組長度
int * pArr ;
//對動態(tài)的一維數組進行構造
printf("請輸入你要存放的元素的個數”)
scanf("%d\n,&len);
pArr = (int*)malloc(4 * len);
//對一維數組進行操作
//對動態(tài)一維數組進行賦值
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;
}
動態(tài)數組在運行過程中無法動態(tài)的擴充或則縮小
realloc(praa,100);
144動態(tài)與靜態(tài)比較
靜態(tài)內存是在棧分配的
先讓下一個語句的地址發(fā)送給上一個保存偿短,再分配存儲空間
main函數調用函數f帽芽,為f分配空間,在棧里面分配空間翔冀,終止后就出棧导街,空間就沒有了。main函數在最下面纤子,從棧頂開始執(zhí)行
動態(tài)內存由程序員手動分配搬瑰,手動釋放,內存越來越少就是泄露
動態(tài)內存是在堆分配的控硼,以排序的方式分配
排序泽论,查找
找中間的值
動態(tài)內存是在堆里面分配,用完之后不會釋放內存
#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行動態(tài)分配的這四個字節(jié)的內容
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);本語句沒有語法錯誤幔妨,但是邏輯上有錯誤(因為函數執(zhí)行完會釋放空間鹦赎,無法讀取i的空間)
return 0;
}
要想修改p的值,只能發(fā)送p的地址误堡,指針變量地址只能寫**類型既然q存放的是*p 的地址那么*q就是p,把i 的地址發(fā)送給 *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;
}