前言:一二維陣列字串的使用與創建,字串和陣列如何傳參給函式,字串指標,字串的輸入與輸出,清空輸入緩沖區的方法,選擇排序和冒泡排序,
目錄
一.一維陣列
1.一維陣列的創建與定義
2.一維陣列的使用
3.陣列元素個數的計算和大小的計算
4.一維陣列在記憶體中的儲存
5.避免陣列越界
二.二維陣列
1.二維陣列的定義和初始化
2.二維陣列的使用
3.二維陣列在記憶體中的儲存
三.進階
1.陣列名或字串名到底是什么
2.字串的輸入與輸出
3.函式中的陣列傳參
(1)自己定義一個陣列接收
(2)創建一個指標來接收
4.常量字串(字串指標)
5.字符輸入與輸入緩沖區常見問題&清空輸入緩沖區的方法
四.冒泡排序&選擇排序
1.冒泡排序
2.冒泡排序的優化
3.選擇排序
五.結語
一.一維陣列
1.一維陣列的創建與定義
(1).定義及初始化一維陣列
int arr1[10] = { 1,2,3,4 };//定義陣列可以規定大小也可以不規定大小
int arr2[] = { 1,2,3,4,5 };
int arr3[5] = { 1,2,3,4,5 };
char arr4[3] = { 'a','b','c' };
char arr5[3] = { 'a',93,'c' };//93是ASCII碼值,用%c型別列印會列印出ASCII值所對對應的字串,同理,一個字符'a'用%d型別列印會列印出對應的ASCII碼值,就像下段代碼
char arr6[] = "abcdefg";

一維陣列在創建時可以不規定大小,如果不規定大小,則需要對陣列初始化,即陣列要有內容,這時候陣列的大小(元素個數)就根據初始化的內容來確定,但我們需要注意以下代碼的不同,
char arr1[] = "abc";
char arr2[3] = { 'a','b','c' };
從表面上看,arr1和arr2儲存的內容都是'a' 'b' 'c' 三個字符,但實際上他們在記憶體中是這樣分配的
在字符陣列(字串)的使用和創建中,要特別特別特別注意這個點,
2.一維陣列的使用
int main()
{
int arr[10] = { 0 };//這里陣列不完全初始化
int i = 0;
for (i = 0; i < 10; i++)
{
arr[i] = i;
}
for (i = 0; i < 10; i++)
{
printf("%d ", arr[i]);
}
return 0;
}

這里說明了陣列的下標是從0開始的!!arr[i]就是具體的值,
大家也看到了兩處畫紅線的i<10,建議大家都這么寫,因為i<多少,這個多少就是陣列的元素個數,簡單明了,
一維陣列的列印一般都是用for回圈一個一個列印來實作的,同理,二維陣列就用兩個for回圈
3.陣列元素個數的計算和大小的計算
陣列大小的計算一般用sizeof計算

陣列的元素個數就是陣列的大小(單位是位元組)除以單個元素的大小

4.一維陣列在記憶體中的儲存

一維陣列在記憶體中儲存是連續的,由低地址存到高地址
5.避免陣列越界

當我們這里寫成i<=10,說明會列印總共11個數字,但是我們的陣列大小只定義了10,這時陣列就會越界,所以我們寫程式時一定要
二.二維陣列
1.二維陣列的定義和初始化
二維陣列的創建
int arr1[3][4];
char arr2[3][5];
double arr3[2][4];
二維陣列的初始化
int arr1[3][4];
int arr2[3][4] = { {1,2},{3,4} };
int arr3[][3] = { {1,2,3},{4,5} };//二維陣列只有在有初始化時,行才可以省略,列任何情況都不可省
2.二維陣列的使用

二維陣列就用兩個for回圈去操作,同樣的,陣列下標都是從0開始~
3.二維陣列在記憶體中的儲存

二維陣列在記憶體中儲存也是連續的
三.進階
1.陣列名或字串名到底是什么

很明顯,陣列名和陣列的地址都是首元素的地址,這三者地址的數值相同,但作用不同,

可以看到,str+1和&str[0]+1是一樣的,他們的地址+1只會越過一個元素(4個位元組),陣列名和首元素地址可以等價,但是直接取出陣列的地址再+1,這時候就是直接操作整個陣列了,地址直接越過了整個陣列16個位元組,這一點非常需要注意,函式傳參一般傳的都是陣列名,因為在函式內部我們要操作(改變或使用)這個陣列肯定是一個一個元素使用,
2.字串的輸入與輸出

(1) 注意這里的scanf("%s", str),這里str不用加&,這是因為str是字串名,字串名就是首元素地址,所以這里的str已經是一個地址了,不用我們自己加&,
(2)這里的printf("%s", str),也是同理,在列印字串的時候,我們需要用的是%s型別,而%s需要接收的是地址,我們這里將字串名str傳給%s,也就是字串首元素的地址,也是'a'的地址,printf就會從'a'開始列印,直到遇到'\0'終止符,
(3)而如果我們要列印字串里的某個(單個)字符,就需要注意要用%c,字串的下標也是從0開始的,
3.函式中的陣列傳參
(1)自己定義一個陣列接收
//這里我們自己再定義了一個陣列int a[]來接收傳過來的陣列
void test(int a[])//void是回傳型別,我們這里不需要回傳什么東西,所以用void
{
int i = 0;
for (i = 0; i < 5; i++)
{
printf("%d ", a[i]);
}
}
int main()
{
int arr[5] = { 1,2,3,4,5 };
test(arr);
return 0;
}

我們在函式test中自己創建了一個陣列int a[]來接收,并將陣列a的內容列印出來,
(2)創建一個指標來接收
void test(int* p)//自己定義了一個指標*p來接收
{
int i = 0;
for (i = 0; i < 5; i++)
{
p[i] = 6;
}
}
int main()
{
int i = 0;
int arr[5] = { 1,2,3,4,5 };
test(arr);//嘗試將陣列的每一個值都改成6
for (i = 0; i < 5; i++)
{
printf("%d ", arr[i]);
}
return 0;
}

為什么可以用指標來接收傳過來的陣列呢?因為前面說過,陣列名就是首元素地址,所以也可以用指標來接收~ 學過指標之后,我們就會知道,在陣列中
int arr[5] = { 1,2,3,4,5 };
arr[i]=*(arr+i)
所以在上面test(arr)傳參時,我們將陣列名arr也就是首元素地址傳過去,我們可以用指標int*p接收,在函式中,可以直接把p當作陣列名用,我們用arr[i]時,arr放在arr[i]哪,p就放在哪,也就是p[i],在test中直接用就可以,
4.常量字串(字串指標)

我們知道陣列名或者字串名都表示首元素地址,同理,那這個首元素的地址我們就可以儲存到指標里,所以這里創建了一個指標str1指向了首元素字符'a',所以在printf中,我們知道%s后面需要對應的是一個地址,所以直接將地址(指標)str1放進去就ok了,printf就會從str1開始往后列印,直到遇到'\0',
5.字符輸入與輸入緩沖區常見問題&清空輸入緩沖區的方法
int main()
{
int num;
char ch;
scanf("%d", &num);
scanf("%c", &ch);
return 0;
}
當我們嘗試運行這段代碼
會發現當我們輸入20給num后,按下回車后想要給ch輸入,這時候會發現按下回車后程式就結束了,
在解決這個bug之前,我們需要了解一個概念,叫輸入緩沖區,我們的資料在傳給引數的程序中,要先經過輸入緩沖區,然后再一起傳給引數,
當我們輸入20后,20就被傳入到了輸入緩沖區,按下回車,這時20就順利地從輸入緩沖區賦值給了num,但是這個回車就留在了輸入緩沖區,因為在ascii表中,回車也相當于一個字符,有對應的鍵值(ASCII),是13,所以輪到向ch輸入的時候,scanf直接就從輸入緩沖區把剩下的那個回車給讀取了,所以就跳過了scanf("%s",&ch),這一點要非常注意,回車也相當于是一個字符,
那怎么解決這個bug呢,在我們scanf后,可以把輸入緩沖區給清空,這里介紹幾種辦法,
(1)
int main()
{
int num;
char ch;
scanf("%d", &num);
setbuf(stdin, NULL);
scanf("%c", &ch);
return 0;
}
在一次scanf輸入后,加入一句setbuf(stdin, NULL),stdin是標準輸入流,也就是鍵盤輸入,這句話的意思就是將鍵盤輸入流指標改為空指標,可以理解成將輸入緩沖區置空,個人覺得這個方法比較便捷,
(2)
int main()
{
int num;
char ch;
scanf("%d", &num);
fflush(stdin);
scanf("%c", &ch);
return 0;
}
在一次scanf輸入后,加入一句fflush(stdin),stdin是標準輸入流,也就是鍵盤輸入,fflush就是把標準輸入流清空,這個方法也不錯,但是在vs編譯器中不起作用,其它還是可以的,
(3)
int main()
{
int num;
char ch;
char c;
scanf("%d", &num);
c = getchar();
scanf("%c", &ch);
printf("%d\n", num);
printf("%c\n", ch);
return 0;
}
多定義一個字符c去接收這個回車
四.冒泡排序&選擇排序
1.冒泡排序
冒泡排序就是元素間兩兩比較,較大的就把它往后放
#include <stdio.h>
void Bubble_sort(int* arr,int sz)//這里用指標*arr接收傳過來的陣列名,sz為陣列元素個數
{
for (int i = 0; i < sz - 1; i++)//sz為元素個數,前面講過元素個數為sz,那就i<sz,這里的sz-1是因為有sz個元素,需要sz-1躺排序,-1是因為排到剩下第一個數時就不用繼續排了,
{
for (int j = 0; j < sz - 1 - i; j++)//因為下面對陣列下標會用到j+1,所以這里j<sz-1//可以想象一下,經過0趟排序時,需要比較sz-1-0對數,經過一趟比較后,就變成需要比較sz-1-1=9對數,再經過一趟比較,就變成需要比較sz-1-2對,所以這里j<sz-1-i,也可以理解成一趟排序后減少一個需要排序的數,0趟排序減少0個需要排序的數,
{
if (arr[j] > arr[j + 1])//如果arr[j]比arr[j+1]大,就把它往后放
{
int tmp = arr[j];
arr[j] = arr[j + 1];
arr[j + 1] = tmp;
}
}
}
}
int main()
{
int arr[] = { 2,3,4,3,5,7,9,4,6,7,1,3 };
int sz = sizeof(arr) / sizeof(arr[0]);
Bubble_sort(arr,sz);
for (int i = 0; i < sz; i++)
{
printf("%d ", arr[i]);
}
return 0;
}
10個數,只要比較10-1趟,

2.冒泡排序的優化
假如我們需要排序的陣列有10個元素,則需要排9趟,但我們發現它在排了3趟的時候,它就已經有序了,那我們也沒有再繼續浪費算力去給它排序,我們只需要在每趟排序前,加上一個標志flag
#include <stdio.h>
void Bubble_sort(int* arr,int sz)//這里用指標*arr接收傳過來的陣列名,sz為陣列元素個數
{
for (int i = 0; i < sz - 1; i++)//sz為元素個數,前面講過元素個數為sz,那就i<sz,這里的sz-1是因為有sz個元素,需要sz-1躺排序,-1是因為排到剩下第一個數時就不用繼續排了,
{
int flag = 1;//定義一個標志flag=1
for (int j = 0; j < sz - 1 - i; j++)//因為下面對陣列下標會用到j+1,所以這里j<sz-1//可以想象一下,經過0趟排序時,需要比較sz-1-0對數,經過一趟比較后,就變成需要比較sz-1-1=9對數,再經過一趟比較,就變成需要比較sz-1-2對,所以這里j<sz-1-i,也可以理解成一趟排序后減少一個需要排序的數,0趟排序減少0個需要排序的數,
{
if (arr[j] > arr[j + 1])//如果arr[j]比arr[j+1]大,就把它往后放
{
int tmp = arr[j];
arr[j] = arr[j + 1];
arr[j + 1] = tmp;
flag = 0;//若有排序到,則證明還無序,flag=0
}
}
if (flag == 1)//若flag==1,則證明已經有序
{
break;//跳出回圈,完成排序
}
}
}
int main()
{
int arr[] = { 2,3,4,3,5,7,9,4,6,7,1,3 };
int sz = sizeof(arr) / sizeof(arr[0]);
Bubble_sort(arr,sz);
for (int i = 0; i < sz; i++)
{
printf("%d ", arr[i]);
}
return 0;
}
3.選擇排序
選擇排序和冒泡排序差不多,假設陣列arr有10個元素,選擇排序就是在后9個元素中找出最小值(符合條件)的元素的下標,并和第1個元素交換數值,然后在剩下的9個元素中,進行這樣的操作,

完整代碼
void SelectSort(int* arr)//選擇排序
{
for (int i = 0; i < 10; i++)
{
int min = i;
for (int j = i + 1; j < 10; j++)//在第i個元素的后面開始找最小值
{
if (arr[j] < arr[min])
{
min = j;
}
}
if (i != min)//如果下標min發生了改變,就交換數值
{
int tmp = arr[i];
arr[i] = arr[min];
arr[min] = tmp;
}
}
}
int main()
{
int arr[10] = { 8,3,4,5,7,9,4,6,7,1 };
SelectSort(arr);
for (int i = 0; i < sz; i++)
{
printf("%d ", arr[i]);
}
return 0;
}
五.結語
可能總結的不是很到位,后面的結構體、函式、指標會再提及陣列,陣列和指標、函式的關系還是很大的~
?看完了不妨點個贊收藏吧~
?您的支持就是博主創作的最大動力
?再次感謝您的耐心閱讀!有不懂的歡迎在評論區討論哦~
??感謝您的支持!!!!!
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/398690.html
標籤:其他
