欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

C++編程中指針的聲明與基本使用講解

 更新時間:2016年01月25日 16:10:07   投稿:goldensun  
這篇文章主要介紹了詳解C++編程中C++編程中指針的聲明與基本使用講解,文中舉了簡單的例子來講如何在基本的數(shù)據(jù)結(jié)構(gòu)中使用指針,以及固定和可變指針的介紹,需要的朋友可以參考下

使用以下序列聲明指針。

[storage-class-specifiers] [cv-qualifiers] type-specifiers 
[ms-modifier] declarator ;

其中,任何有效指針聲明符均可用于 declarator。簡單指針聲明符的語法如下所示:

* [cv-qualifiers] identifier [= expression]

1.聲明說明符:
可選存儲類說明符。
應用于要指向的對象的類型的可選 const 或 volatile 關鍵字。
類型說明符:可表示要指向的對象的類型的類型名稱。
2.聲明符:
可選的 Microsoft 專用修飾符。

* 運算符。
應用于指針本身的可選 const 或 volatile 關鍵字。
標識符。
可選初始值設定項。
指向函數(shù)的指針的聲明符類似于以下形式:

(* [cv-qualifiers] identifier )( argument-list ) [cv-qualifers]
[exception specification] [= expression];

對于指針數(shù)組,語法如下所示:

* identifier [ [ constant-expression ] ]

但是,指針聲明符可能更復雜。
多個聲明符及其初始值設定項可能同時出現(xiàn)在前面有聲明說明符且以逗號分隔的列表中的一個聲明中。
指針聲明的簡單示例如下:

char *pch;

前面的聲明指定 pch 指向 char 類型的對象。
更復雜的示例是

static unsigned int * const ptr;

前面的聲明指定 ptr 是一個指向 unsigned int 類型(帶靜態(tài)存儲持續(xù)時間)的對象的常量指針。
下一個示例演示如何聲明和初始化多個指針:

static int *p = &i, *q = &j;

在前面的示例中,指針 p 和 q 都指向類型 int 的對象并分別初始化為 i 和 j 的地址。存儲類說明符 static 應用于這兩個指針。

// pointer.cpp
// compile with: /EHsc
#include <iostream>
int main() {
 int i = 1, j = 2; // local variables on the stack
 int *p;

 // a pointer may be assigned to "point to" the value of
 // another variable using the & (address of) operator
 p = & j; 

 // since j was on the stack, this address will be somewhere
 // on the stack. Pointers are printed in hex format using
 // %p and conventionally marked with 0x. 
 printf_s("0x%p\n", p);

 // The * (indirection operator) can be read as "the value
 // pointed to by".
 // Since p is pointing to j, this should print "2"
 printf_s("0x%p %d\n", p, *p);

 // changing j will change the result of the indirection
 // operator on p.
 j = 7;
 printf_s("0x%p %d\n", p, *p );

 // The value of j can also be changed through the pointer
 // by making an assignment to the dereferenced pointer
 *p = 10;
 printf_s("j is %d\n", j); // j is now 10

 // allocate memory on the heap for an integer,
 // initialize to 5
 p = new int(5);

 // print the pointer and the object pointed to
 // the address will be somewhere on the heap
 printf_s("0x%p %d\n", p, *p);

 // free the memory pointed to by p
 delete p;

 // At this point, dereferencing p with *p would trigger
 // a runtime access violation.

 // Pointer arithmetic may be done with an array declared
 // on the stack or allocated on the heap with new.
 // The increment operator takes into account the size 
 // of the objects pointed to.
 p = new int[5];
 for (i = 0; i < 5; i++, p++) {
 *p = i * 10;
 printf_s("0x%p %d\n", p, *p);
 }

 // A common expression seen is dereferencing in combination
 // with increment or decrement operators, as shown here.
 // The indirection operator * takes precedence over the 
 // increment operator ++. 
 // These are particularly useful in manipulating char arrays.
 char s1[4] = "cat";
 char s2[4] = "dog";
 char* p1 = s1;
 char* p2 = s2;

 // the following is a string copy operation
 while (*p1++ = *p2++);

 // s2 was copied into s1, so now they are both equal to "dog"
 printf_s("%s %s", s1, s2);
}

輸出:

0x0012FEC8
0x0012FEC8 2
0x0012FEC8 7
j is 10
0x00320850 5
0x00320850 0
0x00320854 10
0x00320858 20
0x0032085C 30
0x00320860 40
dog dog

另一個示例演示如何在數(shù)據(jù)結(jié)構(gòu)中使用指針;本例中采用鏈接列表。

// pointer_linkedlist.cpp
// compile with: /EHsc
#include <iostream>
using namespace std;

struct NewNode {
 NewNode() : node(0){}
 int i;
 NewNode * node;
};

void WalkList(NewNode * ptr) {
 if (ptr != 0) {
 int i = 1;
 while (ptr->node != 0 ) {
  cout << "node " << i++ << " = " << ptr->i << endl;
  ptr = ptr->node;
 }
 cout << "node " << i++ << " = " << ptr->i << endl;
 }
}

void AddNode(NewNode ** ptr) {
 NewNode * walker = 0;
 NewNode * MyNewNode = new NewNode;
 cout << "enter a number: " << endl;
 cin >> MyNewNode->i;

 if (*ptr == 0)
 *ptr = MyNewNode;
 else {
 walker = *ptr;
 while (walker->node != 0)
  walker = walker->node;

 walker->node = MyNewNode;
 }
}

int main() {
 char ans = ' ';
 NewNode * ptr = 0;
 do {
 cout << "a (add node) d (display list) q (quit)" << endl;
 cin >> ans;
 switch (ans) {
 case 'a':
  AddNode(&ptr);
  break;
 case 'd':
  WalkList(ptr);
  break;
 }
 } while (ans != 'q');
}

輸出:

a
45
d
a
789
d
qa (add node) d (display list) q (quit)
enter a number:
a (add node) d (display list) q (quit)
node 1 = 45
a (add node) d (display list) q (quit)
enter a number:
a (add node) d (display list) q (quit)
node 1 = 45
node 2 = 789
a (add node) d (display list) q (quit)

固定和可變指針

const 和 volatile 關鍵字用于更改處理指針的方式。 const 關鍵字指定指針在初始化后無法修改;此后指針將受到保護,防止進行修改。
volatile 關鍵字指定與后跟的名稱關聯(lián)的值可由用戶應用程序中的操作以外的操作修改。因此,volatile 關鍵字對于聲明共享內(nèi)存中可由多個進程訪問的對象或用于與中斷服務例程通信的全局數(shù)據(jù)區(qū)域很有用。
如果某個名稱被聲明為 volatile,則每當程序訪問該名稱時,編譯器都會重新加載內(nèi)存中的值。這將顯著減少可能的優(yōu)化。但是,當對象的狀態(tài)可能意外更改時,這是保證可預見的程序性能的唯一方法。
若要將指針指向的對象聲明為 const 或 volatile,請使用以下形式的聲明:

const char *cpch;
volatile char *vpch;

若要將指針的值(即指針中存儲的實際地址)聲明為 const 或 volatile,請使用以下形式的聲明:

char * const pchc;
char * volatile pchv;

C++ 語言會阻止將允許修改聲明為 const 的對象或指針的賦值。此類賦值會移除用來聲明對象或指針的信息,從而違反原始聲明的意圖。請考慮以下聲明:

const char cch = 'A';
char ch = 'B';

假定前面聲明了兩個對象(const char 類型的 cch 和 char 類型的 ch),以下聲明/初始化將是有效的:

const char *pch1 = &cch;
const char *const pch4 = &cch;
const char *pch5 = &ch;
char *pch6 = &ch;
char *const pch7 = &ch;
const char *const pch8 = &ch;

以下聲明/初始化存在錯誤。

char *pch2 = &cch;  // Error
char *const pch3 = &cch;  // Error

pch2 的聲明聲明了一個可以用來修改常量對象的指針,因此不允許使用。 pch3 的聲明指定 pointer 是常量,而不是對象;與不允許使用 pch2 的原因相同,也不允許使用該聲明。
以下八個賦值顯示了通過指針進行的賦值以及對前面的聲明的指針值的更改;現(xiàn)在,假設 pch1 到 pch8 的初始化是正確的。

*pch1 = 'A'; // Error: object declared const
pch1 = &ch;  // OK: pointer not declared const
*pch2 = 'A'; // OK: normal pointer
pch2 = &ch;  // OK: normal pointer
*pch3 = 'A'; // OK: object not declared const
pch3 = &ch;  // Error: pointer declared const
*pch4 = 'A'; // Error: object declared const
pch4 = &ch;  // Error: pointer declared const

聲明為 volatile 或 const 和 volatile 的組合的指針遵循相同的規(guī)則。
指向 const 對象的指針通常用于函數(shù)聲明中,如下所示:

errno_t strcpy_s( char *strDestination, size_t numberOfElements, const char *strSource );

前面的語句聲明了函數(shù) strcpy_s,其中,三個參數(shù)中的兩個是指向 char 的類型指針。由于參數(shù)是按引用而不是按值傳遞的,因此,如果未將 strSource 聲明為 const,則該函數(shù)可以自由修改 strDestination 和 strSource。將 strSource 聲明為 const 可向調(diào)用方保證調(diào)用的函數(shù)無法更改 strSource。
注意
由于存在從 typename * 到 const typename * 的標準轉(zhuǎn)換,因此將 char * 類型的參數(shù)傳遞到 strcpy_s 是合法的。但是,反之則不行;不存在從對象或指針中移除 const 特性的隱式轉(zhuǎn)換。
給定類型的 const 指針可以分配給同一類型的指針。但是,非 const 類型的指針不能賦給 const 指針。以下代碼顯示了正確和錯誤的賦值:

// const_pointer.cpp
int *const cpObject = 0;
int *pObject;

int main() {
pObject = cpObject;
cpObject = pObject;  // C3892
}

以下示例顯示了當有指針指向某個指向?qū)ο蟮闹羔槙r如何將對象聲明為 const。

// const_pointer2.cpp
struct X {
  X(int i) : m_i(i) { }
  int m_i;
};

int main() {
  // correct
  const X cx(10);
  const X * pcx = &cx;
  const X ** ppcx = &pcx;

  // also correct
  X const cx2(20);
  X const * pcx2 = &cx2;
  X const ** ppcx2 = &pcx2;
}

相關文章

  • Qt TCP實現(xiàn)簡單通信功能

    Qt TCP實現(xiàn)簡單通信功能

    這篇文章主要為大家詳細介紹了Qt TCP實現(xiàn)簡單通信功能,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2022-08-08
  • error LNK2019: 無法解析的外部符號 問題的解決辦法

    error LNK2019: 無法解析的外部符號 問題的解決辦法

    error LNK2019: 無法解析的外部符號 問題的解決辦法,需要的朋友可以參考一下
    2013-05-05
  • C語言實現(xiàn)隨機抽取紙牌程序

    C語言實現(xiàn)隨機抽取紙牌程序

    這篇文章主要為大家詳細介紹了C語言實現(xiàn)隨機抽取紙牌程序,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2022-03-03
  • Qt控件之QLabel用法及技巧

    Qt控件之QLabel用法及技巧

    QLabel是Qt中的一個控件類,用于顯示文本或圖像的控件類之一,本文主要介紹了Qt控件之QLabel用法及技巧,具有一定的參考價值,感興趣的可以了解一下
    2023-10-10
  • c++11新特性多線程操作實戰(zhàn)

    c++11新特性多線程操作實戰(zhàn)

    這篇文章主要介紹了c++11新特性多線程操作實戰(zhàn),文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2020-09-09
  • C++基于easyx圖形庫實現(xiàn)打磚塊游戲

    C++基于easyx圖形庫實現(xiàn)打磚塊游戲

    這篇文章主要為大家詳細介紹了C++基于easyx圖形庫實現(xiàn)打磚塊游戲,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2022-05-05
  • C/C++?Qt?數(shù)據(jù)庫QSql增刪改查組件應用教程

    C/C++?Qt?數(shù)據(jù)庫QSql增刪改查組件應用教程

    Qt?SQL模塊是Qt中用來操作數(shù)據(jù)庫的類,該類封裝了各種SQL數(shù)據(jù)庫接口,可以很方便的鏈接并使用。本文主要介紹了Qt數(shù)據(jù)庫QSql增刪改查組件的應用教程,感興趣的同學可以學習一下
    2021-12-12
  • C++十六進制宏的用法詳解

    C++十六進制宏的用法詳解

    C++十六進制宏的用法;本文將詳細介紹
    2012-11-11
  • C語言安全編碼之數(shù)組索引位的合法范圍

    C語言安全編碼之數(shù)組索引位的合法范圍

    這篇文章主要介紹了C語言安全編碼的數(shù)組索引位合法范圍剖析,對于編碼安全非常重要!需要的朋友可以參考下
    2014-07-07
  • c/c++實現(xiàn)獲取域名的IP地址

    c/c++實現(xiàn)獲取域名的IP地址

    本文給大家匯總介紹了使用c/c++實現(xiàn)獲取域名的IP地址的幾種方法以及這些方法的核心函數(shù)gethostbyname的詳細用法,非常的實用,有需要的小伙伴可以參考下。
    2015-11-11

最新評論