俗話説一日不見如隔三秋,可我昨天剛見的你,今天早上起來竟然好像是隔了一個世紀!真的很想見到你!想起你的美麗的臉,想起你可愛的脾氣,VS2020

想我了嗎,朋友們,今天又是學習的一天

1,數組名的理解

在前面的指針中,我們也使用過取數組的地址。那我們取出的數組的地址是個什麼樣的地址呢?

我們可以驗證一下。

#include <stdio.h>
int main()
{
int arr[10] = { 0 };
printf("%p\n", &arr[0]);
printf("%p\n", &arr);
return 0;
}

小白指針(四)---新手_數組名

我們通過上面代碼得知我們所打印的數組名其實是首元素的地址。但是這個準確嗎?

我們再看這樣一串代碼

#include <stdio.h>
int main()
{
int arr[10] = { 0 };
printf("%d\n", sizeof(arr));
return 0;
}

小白指針(四)---新手_數組名_02

我們發現sizeof,我計算出來的大小是40。但是如果我們的arr是首元素的地址,那麼size of計算數組的大小應該是4,但是他並非是,所以數組是數組首元素的地址是對的,但是是有例外的。

1sizeof(數組名)sizeof中單獨放數組名,這⾥的數組名錶⽰整個數組,計算的是整個數組的⼤⼩,單位是字節

2&數組名,這⾥的數組名錶⽰整個數組,取出的是整個數組的地址(整個數組的地址和數組⾸元素的地址是有區別的)除此之外,任何地⽅使⽤數組名,數組名都表⽰⾸元素的地址

1.1有趣的代碼

#include <stdio.h>
int main()
{
int arr[10] = { 1,2,3,4,5,6,7,8,9,10 };
printf("&arr[0] = %p\n", &arr[0]);
printf("arr = %p\n", arr);
printf("&arr = %p\n", &arr);
return 0;
}

小白指針(四)---新手_數組名_03

為什麼他們三個説打印的地址都是一樣的呢?其實第1個就比較容易理解&arr[0]這個就是首個元素的地址。

第2個arr根據上面的理解輸入數組明確打印地址,打印的依舊是所描述的地址。

第3個當我們輸入&arr即使是整個元素的地址。但是整個數組的地址依舊是從第1個地址開始。

1.2數組區別

那他們有什麼區別嗎我們依舊可以用代碼去看。

#include <stdio.h>
int main()
{
int arr[10] = { 1,2,3,4,5,6,7,8,9,10 };
printf("&arr[0] = %p\n", &arr[0]);
printf("&arr[0]+1 = %p\n", &arr[0]+1);
printf("arr = %p\n", arr);
printf("arr+1 = %p\n", arr+1);
printf("&arr = %p\n", &arr);
printf("&arr+1 = %p\n", &arr+1);
return 0;
}

小白指針(四)---新手_數組名_04

這⾥我們發現&arr[0]和&arr[0]+1相差4個字節,arr和arr+1 相差4個字節,是因為&arr[0] 和 arr 都是

⾸元素的地址,+1就是跳過⼀個元素。但是&arr 和 &arr+1相差40個字節,這就是因為&arr是數組的地址,+1 操作是跳過整個數組的。到這⾥⼤家應該搞清楚數組名的意義了吧。

2,複習使⽤指針訪問數組

代碼如下

#include <stdio.h>
int main()
{
int arr[10] = { 1,2,3,4,5,6,7,8,9,10 };
int se = sizeof(arr) / sizeof(arr[0]);
int i = 0;
int* pa = arr;
for (i = 0; i < se; i++)
{
scanf("%d", pa + i);
}
for (i = 0; i < se; i++)
{
printf("%d ", *pa);
pa++;
}
}

小白指針(四)---新手_數組_05

當我們使用上面這張代碼的時候,我們將數組放到了地址裏面。這時候P和arr就是等價的。那麼我們將上面的代碼的PA改成arr

是否依舊能夠幫助我們去初始化數組和打印數組呢?

int main()
{
int arr[10] = { 1,2,3,4,5,6,7,8,9,10 };
int se = sizeof(arr) / sizeof(arr[0]);
int i = 0;
int* pa = arr;
for (i = 0; i < se; i++)
{
scanf("%d", arr + i);
}
for (i = 0; i < se; i++)
{
printf("%d ", arr[i]);//*
(
arr+i
)也行
}
}

小白指針(四)---新手_數組名_06

2.1換個花樣

依舊是上面這樣的一個代碼,通過普通日常生活中,我們所學的加法結合律。他依舊能換個樣子寫。

int main()
{
int arr[10] = { 1,2,3,4,5,6,7,8,9,10 };
int se = sizeof(arr) / sizeof(arr[0]);
int i = 0;
int* pa = arr;
for (i = 0; i < se; i++)
{
scanf("%d", arr + i);
}
for (i = 0; i < se; i++)
{
printf("%d ", i[arr]);
}
}

小白指針(四)---新手_i++_07

2.2結合上的代碼可以總結。

我們打印所使用的。arr[i]*pa+i)和

i[arr],和*arr+i)和p[i]其實都一樣,也就是到我們總結出。

arr[i]==*arr+i)我們根據加法結合律,也能得到*i+arr==i[arr]

這裏無論是【】還是+都是符號不要侷限

又因為我們根據上面代碼得到了PAarr等價

(在我們這個條件下),所以arr也可以換成PA

3,維數組傳參的本質

我們之前講過函數傳參。在其中其實講過數組是可以傳遞給函數的,跟之前也有跟川菜一樣的掃雷小遊戲。今天呢,我們就要講一維數組的傳參的本質

3.1錯誤代碼

#include <stdio.h>
void test(int arr[])
{
int se2 = sizeof(arr) / sizeof(arr[0]);
printf("sa2 = %d\n", se2);
}
//
數組傳參的時候並非是數組,是首元素的地址
int main()
{
int arr[10] = { 1,2,3,4,5,6,7,8,9,10 };
int se1 = sizeof(arr) / sizeof(arr[0]);
printf("sa1 = %d\n", se1);
test(arr);
return 0;
}

小白指針(四)---新手_數組名_08

數組傳參的時候並非是數組,是首元素的地址

我們發現在函數內部是沒有正確獲得數組的元素個數。

數組名是數組⾸元素的地址;那麼在數組傳參的時候,傳遞的是數組名,也就是説本質上數組傳參本質上傳遞的是數組⾸元素的地址。

所以函數形參的部分理論上應該使⽤指針變量來接收⾸元素的地址。

那麼在函數內部我們寫 sizeof(arr) 計算的是⼀個地址的⼤⼩(單位字節)⽽不是數組的⼤⼩(單位字節)。正是因為函數的參數部分是本質是指針,所以在函數內部是沒辦法求的數組元素個數的。

3.2正確代碼

#include <stdio.h>
void print(int* arr[])
{
int i = 0;
for (i = 0; i < 10; i++)
{
printf("%d\n", arr[i]);
}
}
int main()
{
int arr[10] = { 1,2,3,4,5,6,7,8,9,10 };
print(arr);
return 0;
}

小白指針(四)---新手_數組_09

上面的代碼可以修改的計算數組的大小-----建議

3.3總結:

⼀維數組傳參,形參的部分可以寫成數組的形式,也可以寫成指針的形式。

4,冒泡排序

冒泡排序的核⼼思想就是:兩兩相鄰的元素進⾏⽐較。

先來給代碼

#include<stdio.h>
void bubblesort(int arr[], int se)
{
int i = 0;
for (i = 0; i < se-1; i++)
{
//
一次冒泡排序
int j = 0;
for (j = 0; j <se-i-1; j++)
{
if (arr[j] > arr[j + 1])
{
int num = arr[j];
arr[j] = arr[j + 1];
arr[j + 1] = num;
}
}
}
}
int main()
{
int arr[10] = {0 };
int se = sizeof(arr) / sizeof(arr[0]);
//int pa = &arr;
int i = 0;
//
對數組排序
for (i = 0; i < se; i++)
{
scanf("%d", arr + i);
}
bubblesort(arr,se);
for (i = 0; i < se; i++)
{
printf("%d ", arr[i]);
}
return 0;
}

小白指針(四)---新手_i++_10

4.1上面的代碼可以優化

void bubblesort(int arr[], int se)//
參數接收數組元素個數
{
int i = 0;
for (i = 0; i < se - 1; i++)
{
int flag = 1;//
假設這⼀趟已經有序了
int j = 0;
for (j = 0; j < se - i - 1; j++)
{
if (arr[j] > arr[j + 1])
{
flag = 0;//
發⽣交換就説明,⽆序
int tmp = arr[j];
arr[j] = arr[j + 1];
arr[j + 1] = tmp;
}
}
if (flag == 1)//
這⼀趟沒交換就説明已經有序,後續⽆序排序了
break;
}
}
int main()
{
int arr[] = { 3,1,7,5,8,9,0,2,4,6 };
int se = sizeof(arr) / sizeof(arr[0]);
int i = 0;
for (i = 0; i < se; i++)
{
scanf("%d", arr + i);
}
bubblesort(arr, se);
for (i = 0; i < se; i++)
{
printf("%d ", arr[i]);
}
return 0;
}

小白指針(四)---新手_數組_11

冒泡排序的核心思想其實就是對元素進行相互比較。當我們用第n個元素和第n加一個元素。相互比較,通過交換將他和比他大的數組的數的位置進行改變,從而實現排序。

小白指針(四)---新手_數組_12