日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

4、C语言面试笔试--内存操作-指针

發布時間:2025/4/5 编程问答 23 豆豆
生活随笔 收集整理的這篇文章主要介紹了 4、C语言面试笔试--内存操作-指针 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

文章目錄

  • 1、指針變量
    • 1.1 基本概念
    • 1.2 指針運算
    • 1.3 面試題
  • 2、 常量和常量指針
    • 2.1 字面常量和符號常量
    • 2.2 const指針常量
      • 2.2.1 常量指針
      • 2.2.2 常量指針變量
      • 2.2.3 指針常量
  • 3、總結
  • 1、多級指針
  • 2、void * 的含義與void **
    • 面試 1
    • 面試2
    • 面試3

1、指針變量

1.1 基本概念

與普通變量不同,指針定義時的數據類型并不是指針變量本身的數據類型,而是其所指目標數據的數據類型,稱之為基類型。指針初始化的一般形式如下:

數據類型 * 指針名=初始地址值;

其中指針變量名前的僅僅是一個說明符,表示其后的名稱是一個指針變量名。這里的并沒有訪問指針目標的含義。
有關指針的注意事項如下:
在定義指針變量后系統為該指針變量分配一個地址大小的存儲單元,指針變量中存放的是地址值。特別注意,無論指針變量的基類型是何種數據類型,占用的內存大小都是相同的,例如“char *p1;double *p2”,在32位系統中有sizeof(p1)=sizeof(p2)=4,即p1和p2兩個指針變量均占用4個字節。

盡管任何指針變量中存放的都是地址值,但一個指針變量只能存放相同基類型的數據地址。

一個指針變量本身占用的空間很小,但可以指向一整塊很大的連續控件,這個一整塊的連續控件通常是采用動態分配函數malloc分配,存放在堆空間中。

指針和地址有什么區別?指針意味著已經有一個指針變量存在,其值是一個地址,指針變量本身也有地址,而地址本身并不代表任何變量存在,地址僅表示內存空間的一個位置。

1.2 指針運算

指針與整數的加減:p±n 以該地址量為基點的其阿芳或后方的第n個數據的地址。例如,對于基類型為type的指針p,p±n的結果是地址值p±n*sizeof(type),其中sizeof(type)稱之為步長,顯然步長是與指針變量的基類型有關。
指針++和–:++代表運算后指向下一個數據的位置,指針–代表運算后指向上一個數據的位置,運算后指針地址值的變化量取決于滋鎮的基類型。
兩個指針相減:并非他們的兩個地址值直接做減法運算,而是兩指針所指地址之間的數據個數。
NULL(與0等效):一旦某個指針賦值為NULL,就將該指針值設置為0,表示真真變量沒有意義,就不能再存儲數據,如int *p=NULL, *p=10,是錯誤的。

也就是說我們一定要記住,指針運算指的是針對指針的基類型進行的運算,而不是地址的加加減減


野指針:一個指針變量的值(地址值)為垃圾值的指針變量稱之為野指針;
產生野指針的原因及其解決辦法如下:
指針變量定義時沒有被初始化,解決辦法是在定義指針時初始化,可以是具體的地址值,也可以是NULL。
指針p被free或者delete之后沒有置為NULL,后面又去使用。解決辦法就是釋放指針指向的內存空間,然后將指針指向NULL。
指針操作超越了所指變量的作用域,解決辦法是在所指變量的作用域結束之前釋放掉變量的紙質空間,并讓指針指向NULL。

1.3 面試題

以下程序的輸出是()

int *pint=0; pint+=6; printf("%d\n",pint);

答案:24
首先題中在定義指針的時候p=0,也就是相當于p=NULL.
其次,+6,其實也就是相當于+6*sizeof(pint);所以輸出的地址值是24
以下程序的輸出結果是什么?

#include <stdio.h> void main() {int*p1,*p2;int value;p1=(int *)0x500;p2=(int *)0x508;value=p2-p1;printf("%d\n",value); }

輸出結果是2
解析:8/4=2

以下程序執行會輸出什么?

#include<stdio.h> int main() {char *p="Linux";printf("[%c]",*p++);printf("[%c]",*p);return 0;}

請問執行Test函數會有什么樣的結果? #include<stdio.h> #include <malloc.h> #include <string.h>void test (void) {char *str=(char*)malloc(100);strcpy(str,"hello");free(str);if(str!=NULL){strcpy(str,"world");printf(str);} }void main() {test();}

因為執行free(str)語句后,str會成為野指針,其中地址值是不為NULL的垃圾地址,將world字符串存放在垃圾地址空間中,后果難以預料,非常危險。

2、 常量和常量指針

2.1 字面常量和符號常量

常量分為字面常量和符號常量。字面常量只能引用不能修改,字面常量通常保存在靜態數據區,由p指針指向它,不能通過p指針修改該常量。

char *p="abc";

像上面這種寫法,在C語言中是在太多了,只能由p指針指向它,不能通過p指針修改該常量。
其中“abc”為常量,程序員最好采用const char *p="abc"定義。這樣在后面執行 *p='x’就會發生錯誤,也能一眼找到原因。
另外,如果p指向的常量字符串不是通過malloc函數分配的,執行free§,會導致程序崩潰。

使用const定義,const的意思是“一個不能被改變的變量”
注意對于define只是替換語句,不是指令,所以沒有;分號,但是,const是指令,所以有;分號。
const常量有數據類型,而宏常量沒有數據類型。

可以把const常量的地址賦給指針變量,例如:const int i=10;int *p=&i ;
C中默認這種隱式轉換,但是在C++中,“cannot convert from ‘const int *’ to ‘int *’”編譯錯誤,需要采用強制轉換,即 int *p=(int *)&i ;

2.2 const指針常量

3類:常量指針、常量指針變量、指針變量

2.2.1 常量指針

在定義指針時用const關鍵字進行修飾,稱為const指針常量。

const char *p

用const修飾 * 時稱為常量指針,這樣就不能通過該指針變量修改指向的內容。

2.2.2 常量指針變量

在C++中還可以用const修飾指針變量名,稱之為常量指針變量。
char *const p;
表示指針p是一個常量指針變量,p的值不能再法神改變,所以必須初始化,一旦初始化,p不能指向其他數據,但可以通過指針p修改所指的內容。

#include<stdio.h> #include <malloc.h> #include <string.h> int main() {int a=10; int *p=&a; int * const q=p; *q=56;printf("shuchu %d",*p); printf("chuchu %d",*q); }


解釋:也就是常量指針變量是在指針的前面加上const,這樣,這個指針變量其實也就是初始值代表的指針變量,所以更改這個指針變量的內容,也會導致賦予的指針變量的內容改變。

2.2.3 指針常量

指針變量即為常量指針,又是常量指針變量,例如:

const char * const p;

指針常量,前一個const修飾指針變量的定義,后一個const修飾變量名,指針p必須初始化,并且p的值和指向的內容都不能修改。

#include<stdio.h> #include <malloc.h> #include <string.h> int main() {int a=10; int *p=&a; const int * const q=p; *q=56;printf("shuchu %d",*p); printf("chuchu %d",*q); }

如上圖,編譯錯誤

3、總結

注意,

const int *p=&a; int const *p=&a;

以上這兩個表達式是相同的,都是常量指針,兩個const 都是針對*p。
所以值不能改變,而指向地址可以改變。

int * const p ;

const是去修飾 p指針的,所以指針地址不能改變,但是指向的內容值是可以改變的,故稱之為常量指針變量。
最后一種

const int * const p

是同時針對地址和值,所以都不能改變。

1、多級指針

在C中指針還可以指向另外的指針,這種指向指針的指針就稱之為多級指針。(這一點,只要理解了,指針變量存儲了指向的地址,另外指針變量自身也有自己的地址)

int x=10; int *p=&x; int **pp=&p; int ***ppp=&pp; //三級指針

理解:也就是說,**p取p的地址,(注意不是,p指向的地址,如果寫成p,那就成了p的指向地址了,所以需要寫成 **pp=&p)

2、void * 的含義與void **

void *p; int *p; p1=p2;

"無類型”可以包含“有類型”,void *可以指向任何類型的數據。

void ** 可以看做 (void * *)
也就是類型void * 的類型轉換。
(void *) 相當于一個轉換成一個無類型的地址。

int n=10; int *p=& n; printf("%d\n",*(void ** )p);

(void **)p 相當于(int *) (void *p)
也就是說,( void ** )p相當于轉換成空指針類型,再強制類型轉成p的基類型。

面試 1

int main() {char * p="hello ,world";return 0; }

上面程序中p和“hello,world”分別存儲在內存中的哪個區域?
p指針變量是在??丶峙涞?#xff0c;
它指向的常量字符串“hello,world”是在靜態數據區分配的。

面試2

以下程序有什么問題?

#include<stdio.h> #include <malloc.h> #include <string.h> void main() {int i,*p;p=(int *)malloc(3*sizeof(int));for(i=0;i<3;i++){*(p+i)=i+1;printf("%d\n",*(p+i));} p++;free(p); }

由于釋放程序的時候,free釋放的不是分配時候的起始地址,所以會導致程序崩潰。
把p++注釋掉即可

面試3

以下程序有什么問題

#include <stdio.h> #include <malloc.h> void main() {int i,*p,**pp=&p;p=(int *)malloc(3*sizeof(int));for(i=0;i<3;i++)*(p+i)=i+1;printf("%d\n",**(++pp));free(p);}

對于表達式**(++pp),先執行++pp,是增加pp的地址值,此時pp的地址值加1,會指向一個垃圾地址,應該是讓p的地址加1,所以應該是 **++pp

#include <stdio.h> #include <malloc.h>t void main() {int i,*p,**pp=&p;p=(int *)malloc(3*sizeof(int));for(i=0;i<3;i++)*(p+i)=i+1;printf("%d\n",++**pp);free(p);}

總結

以上是生活随笔為你收集整理的4、C语言面试笔试--内存操作-指针的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。