国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

C語言深入理解指針(非常詳細)(二)

這篇具有很好參考價值的文章主要介紹了C語言深入理解指針(非常詳細)(二)。希望對大家有所幫助。如果存在錯誤或未考慮完全的地方,請大家不吝賜教,您也可以點擊"舉報違法"按鈕提交疑問。

指針運算

指針的基本運算有三種,分別是:
? 指針±整數(shù)
? 指針-指針
? 指針的關系運算

指針±整數(shù)

因為數(shù)組在內(nèi)存中是連續(xù)存放的,比如int類型的數(shù)組,每個元素相差4個字節(jié),因此我們只需要知道首元素的地址就可以通過加減的方式找到后面元素的地址

int arr[10] = {1,2,3,4,5,6,7,8,9,10}
#include <stdio.h>
//指針+- 整數(shù)
int main()
{
int arr[10] = {1,2,3,4,5,6,7,8,9,10};
int *p = &arr[0];
int i = 0;
int sz = sizeof(arr)/sizeof(arr[0]);
for(i=0; i<sz; i++)
{
printf("%d ", *(p+i));//p+i 這?就是指針+整數(shù) i每增加1就往后移動4個字節(jié)
}
return 0;
}

指針-指針

/指針-指針
#include <stdio.h>
int my_strlen(char *s)
{
char *p = s;
while(*p != '\0' )//遇到\0就代表字符串結束
p++;
return p-s;//同過著兩個指針相減我們可以得到這個指針的總長度
}
int main()
{
printf("%d\n", my_strlen("abc"));
return 0;
}

指針的關系運算

//指針的關系運算
#include <stdio.h>
int main()
{
int arr[10] = {1,2,3,4,5,6,7,8,9,10};
int *p = &arr[0];//取數(shù)組首元素地址
int i = 0;
int sz = sizeof(arr)/sizeof(arr[0]);
while(p<arr+sz) //指針的???較
{
printf("%d ", *p);
p++;//p沒加1就增加4個字節(jié)
}
return 0;
}

野指針

概念:野指針就是指針指向的位置是不可知的(隨機的、不正確的、沒有明確限制的

野指針成因

指針未初始化

#include <stdio.h>
int main()
{
int *p;//局部變量指針未初始化,默認為隨機值
*p = 20;
return 0;
}

指針越界訪問

#include <stdio.h>
int main()
{
int arr[10] = {0};
int *p = &arr[0];
int i = 0;
for(i=0; i<=11; i++)//i=10和i=11時越界了
{
//當指針指向的范圍超出數(shù)組arr的范圍時,p就是野指針
*(p++) = i;
}
return 0;
}

指針指向的空間釋放

#include <stdio.h>
int* test()
{
int n = 100;
return &n;//不是全局變量,在函數(shù)結束后地址就會消失
}
int main()
{
int*p = test();
printf("%d\n", *p);
return 0;
}

如何規(guī)避野指針

指針初始化

如果明確知道指針指向哪里就直接賦值地址,如果不知道指針應該指向哪里,可以給指針賦值NULL(空指針,也可以理解為0,但是不完全是0,因為0有整形和char類型,只是有那個意思)
NULL 是C語言中定義的?個標識符常量,值是0,0也是地址,這個地址是無法使用的,讀寫該地址會報錯

#ifdef __cplusplus
#define NULL 0
#else
#define NULL ((void *)0)
#endi

初始化如下

#include <stdio.h>
int main()
{
int num = 10;
int*p1 = &num;
int*p2 = NULL;
return 0;
}

注意指針越界

?個程序向內(nèi)存申請了哪些空間,通過指針也就只能訪問哪些空間,不能超出范圍訪問,超出了就是越界訪問

指針不使用時就用NULL

當指針變量指向?塊區(qū)域的時候,我們可以通過指針訪問該區(qū)域,后期不再使用這個指針訪問空間的時候,我們可以把該指針置為NULL。因為約定俗成的一個規(guī)則就是:只要是NULL指針就不去訪問
因此使用指針之前可以判斷指針是否為NULL。
這里就是用if語句判斷

int main()
{
int arr[10] = {1,2,3,4,5,67,7,8,9,10};
int *p = &arr[0];
for(i=0; i<10; i++)
{
*(p++) = i;
}
//此時p已經(jīng)越界了,可以把p置為NULL
p = NULL;
//下次使?的時候,判斷p不為NULL的時候再使?
//...
p = &arr[0];//重新讓p獲得地址
if(p != NULL) //判斷
{
//...
}
return 0;
}

避免返回局部變量的地址

我們就需要創(chuàng)建的變量不是局部變量,也就是說我們可以創(chuàng)建全局變量,當然你可以在mian函數(shù)里面創(chuàng)建變量,然后將變量的地址傳入函數(shù)中,再通過函數(shù)進行一系列操作,結束時可以將變量的地址傳出,這樣就可以避免返回局部變量了。

assert斷言

assert.h 頭文件定義了宏 assert() ,用于在運行時確保程序符合指定條件,如果不符合,就報錯終止運行。這個宏常常被稱為“斷言”
可以理解為進行了一次安檢,在通過時會對這個變量進行檢測,判斷是否符合條件

 assert(p != NULL);

上面代碼在程序運行到這?行語句時,驗證變量 p 是否等于 NULL 。
如果確實不等于 NULL ,程序繼續(xù)運行,否則就會終止運行,并且給出報錯信息提示。
assert() 宏接受?個表達式作為參數(shù)。如果該表達式為真(返回值非零), assert() 不會產(chǎn)生任何作用,程序繼續(xù)運行。
如果該表達式為假(返回值為零),assert() 就會報錯,在標準錯誤流 stderr 中寫入?條錯誤信息,顯示沒有通過的表達式,以及包含這個表達式的文件名和行號。
assert() 的使用對程序員是非常友好的,使用 assert() 有幾個好處:它不僅能自動標識文件和出問題的行號,還有?種無需更改代碼就能開啟或關閉 assert() 的機制。
如果已經(jīng)確認程序沒有問題,不需要再做斷言,就在 #include <assert.h> 語句的前面,定義?個NDEBUG

#define NDEBUG
#include <assert.h>

然后,重新編譯程序,編譯器就會禁用文件中所有的 assert() 語句。如果程序又出現(xiàn)問題,可以移除這條 #define NDBUG 指令(或者把它注釋掉),再次編譯,這樣就重新啟用了 assert() 語句。
assert() 的缺點是,因為引入了額外的檢查,增加了程序的運行時間。
?般我們可以在debug中使用,在release版本中選擇禁用assert就行,在VS這樣的集成開發(fā)環(huán)境中,在release版本中,直接就是優(yōu)化掉了。這樣在debug版本寫有利于程序員排查問題,在release版本不影響用戶使用時程序的效率

指針的使用和傳址調(diào)用

傳址調(diào)用

學習指針的目的是使用指針解決問題,那什么問題,非指針不可呢?
例如:寫?個函數(shù),交換兩個整型變量的值

#include <stdio.h>
void Swap1(int x, int y)
{
int tmp = x;
x = y;
y = tmp;
}
int main()
{
int a = 0;
int b = 0;
scanf("%d %d", &a, &b);
printf("交換前:a=%d b=%d\n", a, b);
Swap1(a, b);
printf("交換后:a=%d b=%d\n", a, b);
return 0;
}

代碼運行入下:
C語言深入理解指針(非常詳細)(二),C語言,c語言,算法,數(shù)據(jù)結構,開發(fā)語言,學習方法,經(jīng)驗分享,筆記
在main函數(shù)內(nèi)部,創(chuàng)建了a和b,a的地址是在調(diào)用Swap1函數(shù)時,將a和b傳遞給了Swap1函數(shù),在Swap1函數(shù)內(nèi)部創(chuàng)建了形參x和y接收a和b的值,但是
x和y確實接收到了a和b的值,不過x的地址和a的地址不一樣,y的地址和b的地址不一樣,相當于x和y是獨立的空間,那么在Swap1函數(shù)內(nèi)部交換x和y的值,自然不會影響a和b,當Swap1函數(shù)調(diào)用結束后回到main數(shù),a和b的沒法交換。Swap1函數(shù)在使用的時候,是把變量本?直接傳遞給了函數(shù),這種調(diào)用函數(shù)的方式我們之前在函數(shù)的時候就知道了,這種叫傳值調(diào)用
。因此當我們傳入內(nèi)存后,運行結果如下:
C語言深入理解指針(非常詳細)(二),C語言,c語言,算法,數(shù)據(jù)結構,開發(fā)語言,學習方法,經(jīng)驗分享,筆記
我們可以看到實現(xiàn)成Swap2的方式,順利完成了任務,這里調(diào)用Swap2函數(shù)的時候是將變量的地址傳
遞給了函數(shù),這種函數(shù)調(diào)用方式叫:傳址調(diào)用

結論:實參傳遞給形參的時候,形參會單獨創(chuàng)建?份臨時空間來接收實參,對形參的修改不影響實參。所以Swap是失敗的了文章來源地址http://www.zghlxwxcb.cn/news/detail-693013.html

例子(strlen函數(shù)的實現(xiàn))

//計數(shù)器?式
int my_strlen(const char * str)
{
int count = 0;
assert(str);
while(*str)
{
count++;
str++;
}
return count;
}
int main()
{
int len = my_strlen("abcdef");
printf("%d\n", len);
return 0;
}

到了這里,關于C語言深入理解指針(非常詳細)(二)的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來自互聯(lián)網(wǎng)用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。如若轉(zhuǎn)載,請注明出處: 如若內(nèi)容造成侵權/違法違規(guī)/事實不符,請點擊違法舉報進行投訴反饋,一經(jīng)查實,立即刪除!

領支付寶紅包贊助服務器費用

相關文章

  • C語言——深入理解指針

    C語言——深入理解指針

    實數(shù)組名就是數(shù)組?元素(第?個元素)的地址,但是有兩個例外: ? sizeof(數(shù)組名) ,sizeof中單獨放數(shù)組名,這?的數(shù)組名表? 整個數(shù)組 ,計算的是整個數(shù)組的??,單位是字節(jié) ? 數(shù)組名 ,這?的數(shù)組名表?整個數(shù)組, 取出的是整個數(shù)組的地址 (整個數(shù)組的地址和數(shù)組?

    2024年04月10日
    瀏覽(27)
  • 深入理解指針(c語言)

    深入理解指針(c語言)

    可以使用指針來訪問數(shù)組元素。例如,可以聲明一個指針變量并將其指向數(shù)組的第一個元素,然后通過遞增指針的方式來訪問數(shù)組的其他元素: 輸出結果: 在C語言中, 數(shù)組名有時代表數(shù)組中首元素的地址,有時代表整個數(shù)組 ,視情況而定。 1、數(shù)組首元素的地址 例1: 定義

    2024年02月22日
    瀏覽(19)
  • 【C語言:深入理解指針二】

    【C語言:深入理解指針二】

    我們知道,指針變量也是變量,它也有自己的地址,使用什么來存放它的地址呢?答案是:二級指針。 關于二級指針的運算 *pp先解引用,對pp中的地址進行訪問,訪問的就是p **pp, 先通過*pp找到p,再對p進行解引用,訪問的就是a 指針數(shù)組,顧名思義,它應該是一個數(shù)組,是用

    2024年02月04日
    瀏覽(64)
  • C語言——深入理解指針(3)

    C語言——深入理解指針(3)

    目錄 1. 字符指針 2. 數(shù)組指針 2.1 數(shù)組指針變量 2.2 數(shù)組指針變量的初始化 3.二維數(shù)組傳參(本質(zhì)) 4. 函數(shù)指針 4.1 函數(shù)指針變量的創(chuàng)建 4.2 函數(shù)指針的使用 4.3 typedef? 5. 函數(shù)指針數(shù)組 6. 轉(zhuǎn)移表(函數(shù)指針數(shù)組的使用) 在指針的類型中有一種指針類型為字符指針? char* ? ?舉例

    2024年02月05日
    瀏覽(33)
  • C語言——從頭開始——深入理解指針(1)

    C語言——從頭開始——深入理解指針(1)

    ?一.內(nèi)存和地址 我們知道計算上CPU(中央處理器)在處理數(shù)據(jù)的時候,是通過地址總線把需要的數(shù)據(jù)從內(nèi)存中讀取的,后通過數(shù)據(jù)總線把處理后的數(shù)據(jù)放回內(nèi)存中。如下圖所示: 計算機把內(nèi)存劃分為?個個的 內(nèi)存單元 ,每個內(nèi)存單元的大小取1個字節(jié)( 1個字節(jié)(Byte)=8個比特

    2024年02月21日
    瀏覽(25)
  • 【C語言基礎】:深入理解指針(三)

    【C語言基礎】:深入理解指針(三)

    指針系列回顧 : 【C語言基礎】:深入理解指針(一) 【C語言基礎】:深入理解指針(二) 一、冒泡排序 冒泡排序的核心思想就是:兩兩相鄰的元素進行比較。 可以看到,這段代碼對arr數(shù)組進行了排序,但這個代碼還有一些缺陷,那就是無論數(shù)組內(nèi)部的元素是否有序,他都會循

    2024年03月10日
    瀏覽(26)
  • 【C語言】指針的入門篇2,深入理解指針和數(shù)組的關系

    【C語言】指針的入門篇2,深入理解指針和數(shù)組的關系

    歡迎來CILMY23的博客喔,本期系列為【C語言】指針的入門篇2,深入理解指針和數(shù)組的關系,圖文講解指針和數(shù)組關系的知識,帶大家理解指針和數(shù)組的關系,以及指針+數(shù)組的用法,感謝觀看,支持的可以給個贊哇。 前言 在上一篇博客中,我們了解了指針就是地址,并且把地

    2024年02月20日
    瀏覽(30)
  • C語言指針(適合C語言進階者):一道題帶你深入理解數(shù)組與指針的關系

    ??個人主頁:JAMES別扣了 ??在校大學生一枚。對IT有著極其濃厚的興趣 ?系列專欄目前為C語言初階、后續(xù)會更新c語言的學習方法以及c題目分享. ??希望我的文章對大家有著不一樣的幫助,歡迎大家關注我,我也會回關,大家一起交流一起互動,感謝大家的多多支持哈! ??

    2024年04月16日
    瀏覽(19)
  • (一)深入理解Mysql底層數(shù)據(jù)結構和算法

    (一)深入理解Mysql底層數(shù)據(jù)結構和算法

    索引是幫助MySQL高效獲取數(shù)據(jù)的排好序的數(shù)據(jù)結構 數(shù)據(jù)結構模擬網(wǎng)站:Data Structure Visualization 二叉樹 不適合做自增ID的數(shù)據(jù)結構。如下示意圖,假設采用二叉樹作為表自增主鍵ID的數(shù)據(jù)存儲結果如下:當查詢id為5的數(shù)據(jù)時,其查詢次數(shù)為5次 紅黑樹 不適合做mysql的索引,因為當

    2024年01月25日
    瀏覽(27)
  • Mysql性能調(diào)優(yōu)——1.深入理解Mysql索引數(shù)據(jù)結構和算法

    Mysql性能調(diào)優(yōu)——1.深入理解Mysql索引數(shù)據(jù)結構和算法

    本系列所說的Mysql性能調(diào)優(yōu),主要是針對開發(fā)者在實際環(huán)境中的sql調(diào)優(yōu),代碼層面上的優(yōu)化。不涉及到mysql底層代碼的調(diào)優(yōu)。 我們知道,一個mysql數(shù)據(jù)表,數(shù)據(jù)量小的時候,可能簡單的查詢耗時不會太久,性能也可以接受。但當數(shù)據(jù)量大的時候,查詢速度會很緩慢。這時候我們

    2024年02月09日
    瀏覽(22)

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請作者喝杯咖啡吧~博客贊助

支付寶掃一掃領取紅包,優(yōu)惠每天領

二維碼1

領取紅包

二維碼2

領紅包