C/C++小知識總結

本文大部分知識點來自於互聯網,對這些知識歸納彙總結合自己的理解進行闡述。關於指針、指針數組、數組指針、函數指針、運算符優先級等等基本小知識點剖析。

一、  優先級列表

C優先級列表

Precedence Operator Description Example Associativity
1

()
[]
->
.
::
++
--

Grouping operator
Array access
Member access from a pointer
Member access from an object
Scoping operator
Post-increment
Post-decrement

(a + b) / 4;
array[4] = 2;
ptr->age = 34;
obj.age = 34;
Class::age = 2;
for( i = 0; i < 10; i++ ) ...
for( i = 10; i > 0; i-- ) ...

 

 

left to right

2

!
~
++
--
-
+
*
&
(type)
sizeof

Logical negation
Bitwise complement
Pre-increment
Pre-decrement
Unary minus
Unary plus
Dereference
Address of
Cast to a given type
Return size in bytes

if( !done ) ...
flags = ~flags;
for( i = 0; i < 10; ++i ) ...
for( i = 10; i > 0; --i ) ...
int i = -1;
int i = +1;
data = *ptr;
address = &obj;
int i = (int) floatNum;
int size = sizeof(floatNum);








right to left

3

->*
.*

Member pointer selector
Member pointer selector

ptr->*var = 24;
obj.*var = 24;


left to right
4

*
/
%

Multiplication
Division
Modulus

int i = 2 * 4;
float f = 10 / 3;
int rem = 4 % 3;

left to right

5

+
-

Addition
Subtraction

int i = 2 + 3;
int i = 5 - 1;

left to right

6

<<
>>

Bitwise shift left
Bitwise shift right

int flags = 33 << 1;
int flags = 33 >> 1;

left to right

7

<
<=
>
>=

Comparison less-than
Comparison less-than-or-equal-to
Comparison greater-than
Comparison geater-than-or-equal-to

if( i < 42 ) ...
if( i <= 42 ) ...
if( i > 42 ) ...
if( i >= 42 ) ...

 

 

left to right

8

==
!=

Comparison equal-to
Comparison not-equal-to

if( i == 42 ) ...
if( i != 42 ) ...

left to right

9

&

Bitwise AND

flags = flags & 42;

left to right

10

^

Bitwise exclusive OR

flags = flags ^ 42;

left to right

11

|

Bitwise inclusive (normal) OR

flags = flags | 42;

left to right

12

&&

Logical AND

if( conditionA && conditionB ) ...

left to right

13

||

Logical OR

if( conditionA || conditionB ) ...

left to right

14

? :

Ternary conditional (if-then-else)

int i = (a > b) ? a : b;

right to left

15

=
+=
-=
*=
/=
%=
&=
^=
|=
<<=
>>=

Assignment operator
Increment and assign
Decrement and assign
Multiply and assign
Divide and assign
Modulo and assign
Bitwise AND and assign
Bitwise exclusive OR and assign
Bitwise inclusive (normal) OR and assign
Bitwise shift left and assign
Bitwise shift right and assign

int a = b;
a += 3;
b -= 4;
a *= 5;
a /= 2;
a %= 3;
flags &= new_flags;
flags ^= new_flags;
flags |= new_flags;
flags <<= 2;
flags >>= 2;

 

 

 

 

 

right to left

16

,

Sequential evaluation operator

for( i = 0, j = 0; i < 10; i++, j++ ) ...

left to right


C++優先級列表

Precedence Operator Description Example Associativity
1

()
[]
->
.
::
++
--

Grouping operator
Array access
Member access from a pointer
Member access from an object
Scoping operator
Post-increment
Post-decrement

(a + b) / 4;
array[4] = 2;
ptr->age = 34;
obj.age = 34;
Class::age = 2;
for( i = 0; i < 10; i++ ) ...
for( i = 10; i > 0; i-- ) ...







left to right
2

!
~
++
--
-
+
*
&
(type)
sizeof

Logical negation
Bitwise complement
Pre-increment
Pre-decrement
Unary minus
Unary plus
Dereference
Address of
Cast to a given type
Return size in bytes

if( !done ) ...
flags = ~flags;
for( i = 0; i < 10; ++i ) ...
for( i = 10; i > 0; --i ) ...
int i = -1;
int i = +1;
data = *ptr;
address = &obj;
int i = (int) floatNum;
int size = sizeof(floatNum);








right to left
3

->*
.*

Member pointer selector
Member pointer selector

ptr->*var = 24;
obj.*var = 24;

left to right
4

*
/
%

Multiplication
Division
Modulus

int i = 2 * 4;
float f = 10 / 3;
int rem = 4 % 3;

left to right
5

+
-

Addition
Subtraction

int i = 2 + 3;
int i = 5 - 1;

left to right
6

<<
>>

Bitwise shift left
Bitwise shift right

int flags = 33 << 1;
int flags = 33 >> 1;

left to right
7

<
<=
>
>=

Comparison less-than
Comparison less-than-or-equal-to
Comparison greater-than
Comparison geater-than-or-equal-to

if( i < 42 ) ...
if( i <= 42 ) ...
if( i > 42 ) ...
if( i >= 42 ) ...





left to right
8

==
!=

Comparison equal-to
Comparison not-equal-to

if( i == 42 ) ...
if( i != 42 ) ...

left to right
9 & Bitwise AND flags = flags & 42; left to right
10 ^ Bitwise exclusive OR flags = flags ^ 42; left to right
11 | Bitwise inclusive (normal) OR flags = flags | 42; left to right
12 && Logical AND if( conditionA && conditionB ) ... left to right
13 || Logical OR int i = (a > b) ? a : b left to right
14 ? : Ternary conditional (if-then-else) if( conditionA || conditionB ) ... right to left
15

=
+=
-=
*=
/=
%=
&=
^=
|=
<<=
>>=

Assignment operator
Increment and assign
Decrement and assign
Multiply and assign
Divide and assign
Modulo and assign
Bitwise AND and assign
Bitwise exclusive OR and assign
Bitwise inclusive (normal) OR and assign
Bitwise shift left and assign
Bitwise shift right and assign

int a = b;
a += 3;
b -= 4;
a *= 5;
a /= 2;
a %= 3;
flags &= new_flags;
flags ^= new_flags;
flags |= new_flags;
flags <<= 2;
flags >>= 2












right to left
16 , Sequential evaluation operator for( i = 0, j = 0; i < 10; i++, j++ ) ... left to right

二、  指針數組和數組指針

指針數組:首先它是一個數組,數組的元素都是指針,數組佔多少個字節由數組本身決定。它是“儲存指針的數組”的簡稱。
數組指針:首先它是一個指針,它指向一個數組。在32 位系統下永遠是佔4 個字節,至於它指向的數組佔多少字節,不知道。它是“指向數組的指針”的簡稱。

下面到底哪個是數組指針,哪個是指針數組呢:A)  int *p1[10];  B)  int  (*p2)[10];

        這裏需要明白一個符號之間的優先級問題。優先級參看第一點。“[]”的優先級比“*”要高。p1 先與“[]”結合,構成一個數組的定義,數組名爲p1,int *修飾的是數組的內容,即數組的每個元素。那現在我們清楚,這是一個數組,其包含10 個指向int 類型數據的指針,即指針數組。至於p2 就更好理解了,在這裏“()”的優先級比“[]”高,“*”號和p2 構成一個指針的定義,指針變量名爲p2,int 修飾的是數組的內容,即數組的每個元素。數組在這裏並沒有名字,是個匿名數組。那現在我們清楚p2 是一個指針,它指向一個包含10 個int 類型數據的數組,即數組指針。我們可以藉助下面的圖加深理解:

三、  函數和指針

3.1 指針函數

這個比較簡單此處不做過多闡述。指針函數就是返回指針的函數,一般定義形式如下:

類型名 *函數名(函數參數表列); 

 例: const char* strcpy(char* strDest, const char* strSrc);理解:“()”的優先級高於“*” ,故 strcpy 先於 "()" 結合表明這是一個函數,再與 "*"結合表明返回一個指針。前面 const char 表明函數 strcpy 返回的就是一個 const char 類型指針。

3.2 函數指針

函數指針是指向函數的指針變量,即本質是一個指針變量。一般定義形式如下:

類型名 (*函數名)(參數); 

例 : int (*p_func)(char*);理解:p_func先與“*”結合表明這是一個指針變量,後面“()”表明該指針指向一個函數,char* strdata 是該函數的參數,前面的  int 是該函數的返回值。

關於調用問題:假定有函數 int func(char* strdata); 要調用該函數可直接 func(str) ; 也可用函數指針調用。調用形式如下:

p_func = func;   // 賦值

(*p_func)(str);  // 調用

3.3 返回函數指針的函數

先來看一個表達式,void (*signal(int signo, void (*func)(int)))(int);這是Linux的一個聲明(先不說這是函數還是指針),當然你可以谷歌它。如果你能完全理解並能隨心所欲寫類似代碼那麼你不用看這篇文章了,這是在浪費你時間。

        有一類函數,返回指針不過返回的是指向函數的指針。一般定義形式如下:

類型名  (*函數名(函數參數列表))(函數參數列表);

        例:int (*func(char a, short b))(int); 理解:按優先級來一步一步解析該聲明。func先和右邊的“()”結合表明 func 是一個函數,然後和“*”結合意味着它是一個指針函數。作爲一個指針函數(見3.1)就要有它的返回值。現在來看 func 的返回值,最右邊的“()”表示它要指向一個函數。這個函數的形式是 int funcname(int)

        用 typedef 關鍵字會使該聲明更簡單易懂。int (*p_type)(int); 此處 p_type 是一個函數指針變量。 typedef    int     (*p_type)(int);  此時 p_type 就成爲了一個函數指針類型。int (*func(char a, short b))(int); 就可以寫爲 p_type func(char a, short b);

        然後來看剛剛給出的  void (*signal(int signo, void (*func)(int)))(int); 理解:signal  是一個函數, 第二個參數是一個函數指針,指向 void funcname(int x) 類型的函數, signal 的返回值是一個函數指針,指向 void funcname(int x) 類型的函數。爲什麼要這麼設計?這麼設計有什麼好處?signal 函數是處理信號的函數,作用相當於消息映射。他要指名信號 signo 對應的處理函數即 func 指向的函數。返回值爲什麼要和 func 一樣?看 const char* strcpy(char* strDest, const char* strSrc) 的返回值就一清二楚了。

四、  變量和取址、引用的區別 (a 和 &a)


發佈了34 篇原創文章 · 獲贊 6 · 訪問量 7萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章