有這樣一句話“對于C語言的學習者來說,如果不懂指針,可以說相當于沒學”,由此可見,指針究竟有多麼重要,毫不誇張的說,指針是C語言的靈魂。指針是C語言中較為進階的部分,并且,不單單在C語言之中被運用,在OC語言之中也經常用到,要進行IOS程式的開發,指針是必須要掌握的東西。 //指針的定義:本質是一個變量,隻不過此變量是用來存儲位址的
//位址:記憶體單元的編号,隻是一個編号而已,是一個0x開頭的 16 進制數
//定義一個整型指針
int a = 10;
int *p = NULL;//NULL恒等于零
p = &a; //将變量a的位址指派給指針變量a
printf("&a = %p\n",&a);
printf("p = %p\n",p);
// 直接通路a變量的值
printf("a = %d\n",a);
// 間接通路a變量的值,此時*p ( * + 變量名稱)是取值操作,取來的變量p存儲的位址對應的記憶體空間
//p --- 取址 *p --- 取值
printf("*p = %d\n",*p);
a = 20;
printf("a = %d\n",a);
printf("*p = %d\n",*p);
// *p = 指派操作 為*p所對應的記憶體裡面的值指派
*p = 34; //先通過p找到位址,然後在*p位址裡指派
printf("a = %d\n",a);
printf("*p = %d\n",*p);
//定義一個整型變量,初始值為30,通過指針變量為其指派和取值
int b = 30;
int *bp = NULL;
bp = &b;
*bp = 60;
printf("*p = %d\n",*bp);
//定義三個整型變量,定義一個指針變量指向第二個變量
int y = 2,z = 3;
int *p2 = NULL;
p2 = &y;//把y的位址指派給p2
*p2 = 4;//給p2所在的記憶體空間重新指派為4,即把值賦給y
printf("y = %d\n",y);
p2 = &z;//重新把z的位址指派給p2,此時p2指針重新指向一個新的位址&z
*p2 = 6;//給p2指向的記憶體空間重新指派為6
printf("z = %d\n",z);
//定義兩個整型變量,初始值為30 50,
int n1 = 30,n2 = 50;
int *pn1 = &n1;
int *pn2 = &n2;
//第一種方法
int temp = *pn1;
*pn1 = *pn2;
*pn2 = temp;
printf("n1 = %d,n2 = %d\n",*pn1,*pn2);
//第二種方法
int *tempP = pn1;
pn1 = pn2;
pn2 = tempP;
printf("n1 = %d,n2 = %d",n1,n2);
//指針的算術運算
int a = 12,b = 15,c = 18;
//定義一個整型指針
int *p = &b;
printf("*p = %d\n",*p);
printf("b = %d\n",b);
printf("*(p + 1) = %d\n",*(p + 1));
printf("a = %d\n",a);
printf("*(p - 1) = %d\n",*(p - 1));
printf("c = %d\n",c);
//p + 1 加一個機關意味着加4個位元組(加幾個位元組取決于這個指針變量類型所占的位元組數),因為此時a的位址比b的位址高,是以加4個位元組,也就是此時指針指向的時a的位址,然後通過(*位址)取值
//p++ //向高位移動一個位址 n個位元組
//p-- //向低位移動一個位址 n個位元組
//數組與指針的關系
int array[5] = {1,2,3,4,5};
int *pArr = array;//因為數組的首位址就是該數組的數組名,是以直接把數組名給指針變量pArr
//如何求數組array第一個元素的值
printf("array[0] = %d\n",array[0]);
//首位址為數組名,是以 *數組名|*指針變量名所取得的都是數組的第一個元素的值
printf("*pArr = %d\n",*pArr);
printf("*array = %d\n",*array);
//取數組中第三個元素的值
printf("*(pArr + 2) = %d\n",*(pArr + 2));
//重新指派
*(pArr + 2) = 8;
printf("*(pArr + 2) = %d\n",*(pArr + 2));
//取第二個元素的幾種方法
printf("array[1] = %d\n",array[1]);
printf("1[array] = %d\n",1[array]);
//下面這兩種是最常用的
printf("*(pArr + 1) = %d\n",*(pArr + 1));
printf("*(array + 1) = %d\n",*(array + 1));
printf("*(&array[0] + 1) = %d\n",*(&array[0] + 1));
printf("pArr[1] = %d\n",pArr[1]);
printf("1[pArr] = %d\n",1[pArr]);
//輸出數組array的所有的值
printf("array數組裡的所有的元素分别為:");
for (int i = 0; i < 5; i++) {
printf("%d ",*(pArr + i));
}
//定義一個有十個元素的整型數組,定義指針變量存儲數組首位址,通過指針完成元素的随機指派[20 40],然後升序排列
int arr[10] = {0};
int *parr = arr;
printf("數組的元素為:");
for (int i = 0; i < 10; i++) {
*(parr + i) = arc4random() % 21 + 20;
printf("%d ",*(parr + i));
}
printf("\n升序完成之後的數組的元素分别為:");
for (int i = 0; i < 10 - 1; i++) {
for (int j = 0 ; j < 10 - 1 - i; j++) {
if (*(parr + j) > *(parr + j + 1)) {
int temp = *(parr + j);
*(parr + j) = *(parr + j + 1);
*(parr + j + 1) = temp;
}
}
}
for (int i = 0; i < 10; i++) {
printf("%d ",*(parr + i));
}
//指針和字元串
char Symbol[] = "Tonight i will close to you!";
char *pSymbol = Symbol;//把數組名也就是首位址指派給指針變量pSymbol
long charStrlen = strlen(Symbol);
for (int i = 0; i < charStrlen; i++) {
printf("%c ",*(pSymbol + i));
}
//%s 的工作原理就是從我們給定的位址開始輸出字元,遇到\0結束
printf("\n%s",Symbol);//首位址
printf("\n%s",Symbol + 8);//首位址往上(高位址)平移8個機關
printf("\n%s",Symbol + 2);
//輸出其中某一段字元
*(pSymbol + 20) = '\0';//找到首位址往上平移20個機關的位置,然後将其值修改為'\0'
printf("\n%s",Symbol + 10);
//将所有的空格改為* 'o'換成'O'
char changechar[] = "You Can You Up,No Can No BB!";
char *pFunny = changechar;//将字元串的名稱指派給我們的字元指針變量.因為字元串的名字就是首位址
int i = 0;
//取到'\0'是則結束循環 *位址就是取值
while (*(pFunny + i) != '\0') {
//取到空格,則是使用 *p 取值,然後重新指派
if (*(pFunny + i) == ' ') {
*(pFunny + i) = '*';
}
if (*(pFunny + i) == 'o') {
*(pFunny + i) = 'O';
}
i++;
}
printf("\n%s",changechar);
return 0;
}
//總結
指針和數組的關系
1.數組所占的空間大小:元素個數 * 每個元素所占的記憶體大小(位元組數)
2.指針所占的記憶體大小隻與作業系統的位數有關,32位---4個位元組,,64位---8個位元組
3.可修改性:數組的首位址是數組名,記憶體的配置設定原則是從(位址)高到低配置設定,從(位址)低到高存儲,是以數組中越靠後的元素位址越高,此時我們使用 首位址 + (數組名) + n (n代表單元,單元的位元組取決于該指針變量的類型)
4.首位址是常量位址,不可指派更改
5.指針本質上是一個變量,隻不過該變量是用來存儲位址,值可以更改,也就是位址可以更改(又叫做指針重定向)
6.使用 p--是位址 *p--是取值 *p = --是指派,賦的值是指向的變量類型所對應的值
今天的練習作業: // 1.定義一個整型數組,包含20個元素,通過指針随機指派[15, 30],請通過指針求數組中所有元素的最大值,最小值,和,平均值
int array[20] = {0},max = 0,min = 30,sum = 0,avg = 0;
int *pArray = array;
printf("數組中的元素為:\n");
for (int i = 0; i < 20; i++) {
*(pArray + i) = arc4random() % 16 + 15;
sum = sum + *(pArray + i);
printf("%d ",*(pArray + i));
if (max < *(pArray + i)) {
max = *(pArray + i);
}
if (min > *(pArray + i)) {
min = *(pArray + i);
}
}
avg = sum / 20;
printf("\n元素的最大值為:%d 最小值為:%d 和為:%d 平均值為:%d",max,min,sum,avg);
// 2.定義六個字元串,即六行的二維字元數組,分别找出六個字元串首位址, 用冒泡排序(升序),然後列印出排序好的字元串
// 例如: //定義六個字元串,即六行的二維字元數組
// char a[6][100]={“chi","hong","huang","lv","lan","dian"};
char a[6][100] = {"chi","hong","huang","lv","lan","dian"};
char *p[6] = {0};
for (int i = 0; i < 6; i++) {
p[i] = a[i];
}
for (int i = 0; i < 6 - 1; i++) {
for (int j = 0; j < 6 - 1 - i; j++) {
if (strcmp(p[j], p[j + 1]) > 0) {
char *temp = {0};
temp = p[j];
p[j] = p[j + 1];
p[j + 1] = temp;
}
}
}
printf("排序好的數組各個元素為:");
for (int i = 0; i < 6; i++) {
printf("%s \n",p[i]);
}
return 0; }