教育行業(yè)A股IPO第一股(股票代碼 003032)

全國咨詢/投訴熱線:400-618-4000

c/c++培訓(xùn)C語言核心知識總結(jié)(五、六)

更新時間:2016年10月21日16時34分 來源:傳智播客C++培訓(xùn)學(xué)院 瀏覽次數(shù):

五、指針 和 數(shù)組的用法
 
int num[5] = {10, 20, 30, 40, 50};
int *p = num;
 
打印的值 打印后*p的值是 數(shù)組里的原值
// 操作地址
*p++ 10   20 10
*(p++)
*和++的優(yōu)先級相同,根據(jù)結(jié)合性(從右往左),那么p先和后自增運(yùn)算符++結(jié)合,
++操作將在表達(dá)式完成后進(jìn)行自增,也就取出p指向的值之后,p指向的下標(biāo)后移一位(4個字節(jié))。
 
*++p 20   20 10
*(++p)
*和++優(yōu)先級相同,根據(jù)結(jié)合性(從右往左),那么p先和前自增運(yùn)算符++結(jié)合,
++操作將會立即完成,p指向的下標(biāo)后移一位(4個字節(jié)),然后再取出p指向的值。
 
 
// 操作數(shù)值
(*p)++ 10 11 11
根據(jù)優(yōu)先級()小括號優(yōu)先級最高,p先和*相結(jié)合,然后再和后自增運(yùn)算符++結(jié)合,
因為是后自增,所以先打印當(dāng)前下標(biāo)的值,然后在原值的基礎(chǔ)上自增 1,此時原值已被改變
 
 
++*p 11 11 11
++(*p)
根據(jù)結(jié)合性/優(yōu)先級,*和p先結(jié)合,然后再和前自增運(yùn)算符++結(jié)合,
因為是前自增,所以先在原值的基礎(chǔ)上自增1,然后在打印這個值,此時原值已被改變。
 
 
總結(jié):如果一個表達(dá)式里有多個運(yùn)算符,則先進(jìn)行優(yōu)先級比較,先執(zhí)行優(yōu)先級高的運(yùn)算符;
如果優(yōu)先級相同,那就看結(jié)合性,根據(jù)結(jié)合方向來做運(yùn)算。
 
 
結(jié)合性:
從左往右:
小括號()、數(shù)組括號[]、成員選擇 . 和 ->,雙目運(yùn)算符,逗號運(yùn)算符
 
從右往左:
單目運(yùn)算符、三目運(yùn)算符、賦值類運(yùn)算符
 
/*
++a:  是直接從變量 a 所在的內(nèi)存地址中取值,并進(jìn)行加1操作,再執(zhí)行表達(dá)式剩余部分。
a++: 先把變量的值保存在一個臨時寄存器里,然后再執(zhí)行整個表達(dá)式,執(zhí)行完之后,再把a(bǔ)的值自增1,再返回內(nèi)存里。
 
CPU -》 寄存器 -》 緩存(L1\L2\L3) -》 來自于內(nèi)存
CPU只和寄存器做數(shù)據(jù)交換,對于重復(fù)操作的數(shù)據(jù)會放在緩存里。
但是不管寄存器還是緩存,他們的數(shù)據(jù)都來自于內(nèi)存。
*/
 
 
六、指針數(shù)組 和 數(shù)組指針
 
1. 指針數(shù)組:
定義形式:
int *p[n] = { 0 };
[]的優(yōu)先級高于*,那么p先和[]結(jié)合,說明這是一個數(shù)組。
再和int *結(jié)合,說明這個數(shù)組里的每個元素都是一個指針,每個元素都能保存一個地址。
 
1) 使用指針數(shù)組保存多個數(shù)據(jù)的地址
int main(void)
{
int a[3] = { 10, 20, 30};
int *p[3] = { 0 };
for (int i = 0; i < 3; ++i)
p[i] = &a[i];
 
for (int i = 0; i < 3; ++i)
{
printf("%p\n", p[i]);
printf("%d\n", *p[i]);
    }
}
 
 
2) 使用指針數(shù)組保存多個字符串的首地址
#include <stdio.h>
 
int main(void)
{
char *str[5] =
{
"ISO/IEC9899:2011",
"Programming",
"Dennis Ritchie",
"c",
"bell ssss"
};
 
char *str1 = str[1]; // 取出 第2行的字符串
char *str2 = *(str + 3); // 取出 第4行的字符串
char ch1 = *(*(str + 4) + 2); //取出 第5行的字符串的第3個字符
char ch2 = (*str + 5)[7]; // 取出第1個字符串的第6個字符,并以此做數(shù)組首元素,向后遍歷到第7個。
char ch3 = *str[0] + 6;  // 取出第1個字符串的第1個字符,然后把這個字符ASCII碼加上6,再用%c打印出來
 
printf("str1 = %s\n",  str1); // Programming
printf("str2 = %s\n",  str2); // c
printf("ch1 = %c\n",  ch1); // l
printf("ch2 = %c\n",  ch2); // 2
printf("ch3 = %c\n",  ch3); // O (不是0)
 
return 0;
}
 
2. 數(shù)組指針(行指針)
定義形式: int *p;  int (*p)[n];   int (*p)[n][m];
()和[]的優(yōu)先級相同,但是結(jié)合性是從左往右,那么p先和*相結(jié)合,說明這是一個指針。
然后再和[]結(jié)合,說明這個指針指向了一個數(shù)組。
 
示例:
1)
#include <stdio.h>
 
void func(int (*p)[3], int n);
int main(void)
{
int a[2][3] = {10, 20, 30, 40, 50, 60};
// 行:    0    1
// 列:    0   1   2   0   1   2
func(a, sizeof(a));
return 0;
}
 
void func(int p[2][3], int n);
// 明確行和列的數(shù)量
 
void func(int p[][3], int n);
//明確列的數(shù)量
 
void func(int (*p)[3], int n)  //明確列的數(shù)組指針
{
printf("%d\n", p[1][2]);
// 取出第2行的第3個元素:60
 
printf("%d\n", **p);
//p是行指針,先是取出當(dāng)前行的列地址,再取出這個列地址里的值: 10
 
printf("%d\n", (*p + 1)[2]);
// 先取出列地址,然后往后移動一個int(4個字節(jié)),再以這一列的下標(biāo)為起點,取出后面第2個元素的值:40
 
printf("%d\n", *(*p + 1));
// 先取出列地址,往后移動1位(1個int),再取出這個下標(biāo)的值:20
 
printf("%d\n", *(p[1] + 2));
// 先取出p[1]的列下標(biāo)地址,再往后移動2位(2個int),再取出這個下標(biāo)的值:60
 
printf("%d\n", *(*(p + 1)));
// 先將行指針p后移一位(3個int),再取出這一行的這一列的下標(biāo)地址,再根據(jù)這個下標(biāo)取值:40
 
printf("%d\n", *((*p + 1) + 2));
//這個表達(dá)式相當(dāng)于 *(*p + 3),先取出列下標(biāo)地址,然后往后移動3位(3個int),再取值:40
 
printf("%d\n", *(*p + 1) + 2);
// 先取出列下標(biāo)的地址,然后往后移動一位(1個int),再進(jìn)行取值得出20,再加2,結(jié)果是:22
 
}
 
// 三維數(shù)組同理
void func(int (*p)[3][4])
{
printf("%d\n", *(*(*(p + 0) + 1 ) + 2);  //70
}
 
int main(void)
{
int a[2][3][4] =
{
{{10, 20, 30, 40}, {50, 60, 70, 80}, {90, 100, 110, 120}},
{{11, 22, 33, 44}, {55, 66, 77, 88}, {99, 101, 111, 121}}
};
 
func(a);
return 0;
}
 
總結(jié):
1.指針數(shù)組:就是一個數(shù)組,這個數(shù)組里的每個元素都是一個指針,這個數(shù)組在內(nèi)存空間中占用了n個指針的大小。
 
2.數(shù)組指針:就是一個指針,這個指針指向一個數(shù)組,這個指針在內(nèi)存空間中占用一個指針的大小。
 
3.二級指針p 和 二維數(shù)組名p 的區(qū)別:
int **p; 這個是一個整型的二級指針,p是一個可變句柄/鑰匙,我們可以讓這個指針指向任何我們希望它指向的地方。
這個句柄不需要指定內(nèi)存空間的大小。
int p[n][m]; 這個是一個整型的二維數(shù)組,p是引用了這塊內(nèi)存空間的句柄/鑰匙,數(shù)組在定義的時候,
就被固定指向某個內(nèi)存空間了,這個空間大小是 sizeof(int) * n * m,而且不可修改p的指向,
p就是一個不可變的常量,永遠(yuǎn)的都只能指向這里了。
 
如果想確定某個一維數(shù)組的值: * 、 []
如果想確定某個二維數(shù)組的值:** 、 [][] 、 *[]

本文版權(quán)歸傳智播客C++培訓(xùn)學(xué)院所有,歡迎轉(zhuǎn)載,轉(zhuǎn)載請注明作者出處。謝謝!
作者:傳智播客C/C++培訓(xùn)學(xué)院
首發(fā):http://oisangadgets.com/c/ 

 

0 分享到:
和我們在線交談!