指針篇(7)- 指針運算筆試題(阿里巴巴)

目錄

  • 一、指針運算筆試題解析
    • 3.1 題目1:
    • 3.2 題目2:
    • 3.3 指針3:
    • 3.4 題目4:
    • 3.5 題目5:
    • 3.6 題目6:
    • 3.7 題目7:
  • 總結


一、指針運算筆試題解析

3.1 題目1:

#include<stdio.h>
int main()
{int a[5] = { 1,2,3,4,5 };int* ptr = (int*)(&a + 1);printf("%d %d", *(a + 1), *(ptr - 1));return 0;
}

程序的運行結果是什么?
結合這個程序的內存布局來講
在這里插入圖片描述
這里把int(*)[5]類型的數組指針強制類型轉換為int *類型賦值給ptr,因為類型一樣才可以賦值,ptr是int *型指針,int *指針減1,向前挪動一個整型,所以 *(ptr - 1)打印結果是5。另一個打印原理很簡單,看了我指針6前面的原理講解就懂了。
在這里插入圖片描述

3.2 題目2:

在這里插入圖片描述
該結構體在x86環境下,大小確實為20個字節,在x64下就不是了。
這里結構體類型加了一個*,這是結構體指針類型,結構體指針創建了個變量叫p,p里有地址,0x100000是個整數,把整數賦給結構體指針,要強制類型轉換。

第一個printf:指針加減整數與指針類型有關,結構體指針加1跳過一個結構體,一個結構體20個字節,這是16進制,也就是0x100014。只有指針變量+1,才可以說加幾個字節。
第二個printf:這里p本是指針變量,p被強制類型轉換為unsigned long,無符號長整型,整數類型,整數加1就是加1,也就是0x100001.
第三個printf:p被強制類型轉換為unsigned int*,這時加1,跳過一個無符號整型,4個字節。這時地址是0x100004,這時用%p打印在x86環境下要打印夠8個16進制位,32個比特位,前面補兩個0,%p不打印0x。

3.3 指針3:

#include <stdio.h>
int main()
{int a[3][2] = { (0, 1), (2, 3), (4, 5) };int* p;p = a[0];printf("%d", p[0]);return 0;
}

依據這串代碼你所想的結果是什么呢?是不是0呢?而且所設想的初始化情況是不是這樣
在這里插入圖片描述

特別要注意:(0, 1)這是一個逗號表達式。在C語言中,逗號運算符會先對左邊的操作數求值,然后直接丟棄這個值,最終返回右邊操作數的值。

進監視看初始化情況也確實如此:
在這里插入圖片描述
所以該數組的初始化結果如圖:
在這里插入圖片描述
一般情況的初始化要使用大括號的

int a[3][2] = { {0, 1}, {2, 3}, {4, 5} };

在這里插入圖片描述
所以改代碼的輸出結果是1
在這里插入圖片描述

3.4 題目4:

在這里插入圖片描述

*(ptr1 - 1)

這里第一個打印沒啥好說的,直接說第二個* (ptr2 - 1),aa數組名表示首元素地址,因為是二維數組,所以aa是第一行的地址,(aa + 1)是第二行一維數組的地址,* (aa + 1)拿到第二行整個數組,相當于數組名,aa[1]數組名又相當于首元素地址。
補充一下:這里(*(aa+1))指向6,6的地址已經是整型地址,這里也不需要強制類型轉換了。
打印結果:
在這里插入圖片描述

3.5 題目5:

在這里插入圖片描述
這里把a的地址賦給p,兩者類型不同,但p其實還是可以接收的,只不過會報警告。類似于下面的代碼

int num = 10;
int* p1 = &num;
char* p2 = &num;//類型差異

由于p指向的數組是4個元素,所以p接收的是第一個黑框,這里p也訪問的是二維數組。

注意:這里要區分p和a的角度,這些黑框都是以p為單位+1,+2指向的地址。地址減地址,得到的是兩個地址之間的元素個數。且隨著數組下標的增長,地址是由低到高變化的。

紅塊是&p[4][2],綠塊是&a[4][2],打印的兩個值都是小地址減大地址,得到的是一個負數(-4)。

打印的時候
%d - 按照10進制的形式,打印有符號的整數。
%d認為內存中存放的是有符號整數的補碼。

%p - 打印地址的
%p認為內存中存放的補碼就是地址
%p打印地址是以16進制的形式打印的

//假設環境是x86環境,程序輸出的結果是啥?
#include <stdio.h>int main()
{int a[5][5];int(*p)[4];p = a;printf("%p, %d\n", &p[4][2] - &a[4][2], &p[4][2] - &a[4][2]);//-4//10000000 00000000 00000000 00000100 - 原碼//11111111 11111111 11111111 11111011 - 反碼//11111111 11111111 11111111 11111100 - 補碼//FF       FF       FF       FCreturn 0;
}

在這里插入圖片描述

3.6 題目6:

#include <stdio.h>
int main()
{char* a[] = { "work","at","alibaba" };char** pa = a;pa++;printf("%s\n", *pa);return 0;
}

這里創建了一個char* 的指針數組,數組的每個元素為char* ,是否每個元素對應一個字符串呢?
實則不然

char* p={“abcdef"};

這個代碼p里存放的是字符串的首字符地址,對應過來,這里char* 的指針數組,每個元素存放一個字符串首字符的地址,a數組的每個元素都為char* 類型。

結合圖來看:
在這里插入圖片描述

pa是一個二級指針,char** pa = a相當于把一個一級指針的地址放到二級指針變量里去了,pa++跳過一個char* 的元素,指向第二個元素。* pa拿到at里a的地址,a的地址交給%s打印,有了起始地址向后打印,遇到\0停下來。

3.7 題目7:

接下來的題目是這一章里最難的一題了

#include <stdio.h>
int main()
{char* c[] = { "ENTER","NEW","POINT","FIRST" };char** cp[] = { c + 3,c + 2,c + 1,c };char*** cpp = cp;printf("%s\n", **++cpp);printf("%s\n", *-- * ++cpp + 3);printf("%s\n", *cpp[-2] + 3);printf("%s\n", cpp[-1][-1] + 1);return 0;
}

先看第一個printf內存布局圖:
在這里插入圖片描述

printf("%s\n", **++cpp);

++cpp指向c+2的地址,* ++cpp拿出c+2的地址,c+2的地址又指向c
數組里P的地址,再解引用拿到P的地址,所以第一個printf打印出POINT。

第二個printf內存布局圖:
在這里插入圖片描述

printf("%s\n", *-- * ++cpp + 3);

前面++cpp已經把cpp的指向改了,cp改為cp+1。這里++的優先級高于加法運算符,這里++cpp指向c+1的地址,* ++cpp拿到c+1的地址,也可以理解為拿到c+1這個元素再- -,c+1變c,這時就只想了c數組里E的地址,再解引用拿到E的地址,+3拿到ENTER\0里第二個E的地址,此時打印ER。

第三個printf內存布局圖:
在這里插入圖片描述

printf("%s\n", *cpp[-2] + 3);

*cpp[-2]不好理解拆解換算一下,cpp[-2]就是cpp+(-2)再解引用,再把原來的 * 加上就是 * * (cpp-2),再+3。
在這里插入圖片描述
cpp-2就是cp+1+1-2,即cp。意思為cpp里的變量值-2,cp為c+3的地址,解引用拿到c+3的地址,c+3指向指向c數組里的F,再解引用拿到F的地址,+3指向S,打印結果為ST。

第四個printf內存布局圖:
在這里插入圖片描述

printf("%s\n", cpp[-1][-1] + 1);

拆解換算之后如圖:
在這里插入圖片描述

這里cpp里的值沒變,只有加加,減減才會改變里面的值,依舊是cp+2,(cpp-1)之后變為cp+1,相當于指向c+2處的地址,第一次解引用拿到c
+2的地址,c+2指向P處位置的地址,再-1,指向N處,解引用拿到N的地址,+1指向N后E的地址,打印結果為EW。

總結

以上就是筆試題的全部內容了,不得不說有些筆試題確實出的非常刁鉆,但總的來說還是考察指針地址的理解,還是挺有意思的。喜歡的靚仔靚女們不要忘記一鍵三連支持一下~

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/pingmian/87482.shtml
繁體地址,請注明出處:http://hk.pswp.cn/pingmian/87482.shtml
英文地址,請注明出處:http://en.pswp.cn/pingmian/87482.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

homebrew的一些常用方法

前言 因本人工作換到mac電腦&#xff0c;對包管理器homebrew的需求增加&#xff0c;因此將一些常用命令做如下記錄&#xff0c;本博客主要用作記錄用。 官網 macOS&#xff08;或 Linux&#xff09;缺失的軟件包的管理器 — Homebrew 常用命令 如果腳本因網絡問題無法下載…

【Python面試題】Python面試之基礎知識常見面試題3-匯總篇(精選30個)

目錄專欄導讀前言1. 字典的內存管理機制是什么&#xff1f;2. 列表的內存管理機制是什么&#xff1f;3. 元組和列表的區別4. 字符串插值的方法5. 閉包、裝飾器的原理閉包&#xff08;Closure&#xff09;裝飾器&#xff08;Decorator&#xff09;6. map、filter的區別7. range(…

【免費.NET方案】CSV到PDF與DataTable的快速轉換

CSV作為輕量級數據載體&#xff0c;在數據傳輸中占比超過70%。但其原生格式存在三大痛點&#xff1a; 可視化缺陷&#xff1a;無法直接生成可打印的報表結構限制&#xff1a;缺乏數據類型定義和關系約束安全風險&#xff1a;易被意外修改導致數據失真 因此&#xff0c;我們常…

connect的斷線重連

connect的短線重連 客戶端代碼的編寫服務器代碼的編寫總結 客戶端代碼的編寫 #include <iostream> #include <string> #include <cstring> #include <cstdlib> #include <unistd.h> #include <sys/types.h> #include <sys/socket.h>…

通過觀看數百個外科手術視頻講座來學習多模態表征|文獻速遞-最新論文分享

Title題目Learning multi-modal representations by watching hundreds of surgical video lectures通過觀看數百個外科手術視頻講座來學習多模態表征01文獻速遞介紹外科計算機視覺領域的最新進展&#xff0c;已開始為手術室&#xff08;OR&#xff09;的新一代人工智能輔助支…

微信小程序如何實現再多個頁面共享數據

在微信小程序中&#xff0c;實現多個頁面共享數據有以下幾種常用方式&#xff0c;根據場景選擇最適合的方案&#xff1a; 全局變量&#xff08;App.js&#xff09; 適用場景&#xff1a;簡單數據共享&#xff08;非響應式&#xff09; 實現方式&#xff1a; javascript // ap…

PCIE5.0 TAG說明(ima回答)

在PCIe 5.0規范中&#xff0c;TLP&#xff08;Transaction Layer Packet&#xff09;報文的Tag字段用于標識和管理事務。以下是關于Tag的生成和使用規則和定義的詳細描述&#xff1a; Tag字段的定義 Tag字段&#xff1a;位于TLP報文的Header中&#xff0c;占用8位&#xff08…

Type-C PD快充協議智能芯片S312L詳解

1. 芯片概述 S312L 是一款智能Type-C PD協議觸發芯片&#xff0c;支持**PD3.0&#xff08;含PPS&#xff09;**及多種A口快充協議&#xff08;如QC/PE等&#xff09;&#xff0c;可自動識別并申請5V/9V/12V電壓&#xff0c;適用于快充適配器、移動電源等場景。 核心優勢&…

stm32學到什么程度可以找工作?

我重新為你寫一篇更加詳細深入的回答&#xff1a; STM32學到什么程度可以找工作&#xff1f;一個十年老兵的血淚史 寫在前面的話&#xff1a;這些年踩過的坑&#xff0c;都是血淋淋的教訓 剛看到這個問題&#xff0c;我就想起了2014年那個炎熱的夏天。 當時我剛從廈門某馬離…

基于 Elasticsearch 實現地圖點聚合

在地圖類應用中&#xff0c;當需要展示大量地理興趣點時&#xff0c;直接將所有點渲染在地圖上會導致視覺混亂&#xff0c;影響用戶體驗。為此&#xff0c;我基于 Elasticsearch 提供的 geotile_grid 和 geo_bounding_box 查詢能力&#xff0c;實現了一套高效的 POI 聚合展示方…

【Prometheus 】通過 Pushgateway 上報指標數據

Prometheus 是目前最流行的開源監控系統之一&#xff0c;其拉取&#xff08;pull&#xff09;模型非常適合服務發現和靜態目標的監控。然而&#xff0c;在某些場景下&#xff0c;例如短生命周期任務、批處理作業或無法暴露 HTTP 接口的服務&#xff0c;傳統的拉取方式并不適用。…

服務器 - - QPS與TPS介紹

1、QPS&#xff08;Queries Per Second 每秒查詢數&#xff09; 定義&#xff1a;常用于表示每秒的請求次數&#xff0c;衡量接口請求、數據庫查詢等動作的吞吐量&#xff08;單位時間內處理的數據量&#xff09; 計算&#xff1a;總請求數/請求時間&#xff0c;如&#xff1…

Cot2:思維鏈提示激發大型語言模型的推理能力

摘要 我們探討了生成思維鏈——一系列中間推理步驟——如何顯著提升大型語言模型執行復雜推理的能力。特別地&#xff0c;我們展示了在足夠大的語言模型中&#xff0c;這種推理能力如何通過一種簡單的方法——思維鏈提示&#xff08;chain-of-thought prompting&#xff09;自…

go交易數據后端

地址 https://gitee.com/EEPPEE_admin/go-stock-line-trading-datahttps://github.com/jerryshell/midas 需求 為了替代rust后端爬蟲端: 爬取東方財富數據到index-data目錄server端: 項目主要內容 todo 替代https://github.com/jerryshell/midas的前端量化概念性理解擴展: 存儲…

靈巧手概覽

第一章 靈巧手的技術演進與核心價值 1.1 技術演進的五個階段 仿生學啟蒙階段&#xff08;1960-1980&#xff09; 1968年斯坦福大學首臺3自由度機械夾爪標志機器人操作技術開端&#xff0c;1973年MIT提出"仿生手"概念&#xff0c;但受限于材料和控制技術&#xff0c;…

在設計提示詞(Prompt)時,關于信息位置的安排z怎么 結合模型特性和任務目標

在設計提示詞(Prompt)時,關于信息位置的安排z怎么 結合模型特性和任務目標 在設計提示詞(Prompt)時,關于信息位置的安排確實需要結合模型特性和任務目標。從自注意力機制的原理及應用場景來看,關鍵信息的位置選擇需遵循以下啟示,并結合具體場景靈活調整: 一、核心啟示…

七、性能優化

目錄 1. 如何檢測Flutter應用的性能問題&#xff1f;2. 什么是重繪邊界&#xff08;Repaint Boundary&#xff09;&#xff1f;3. 如何避免不必要的重建&#xff1f;4. const 構造函數在優化中起什么作用&#xff1f;5. 如何優化長列表的性能&#xff1f;6. 如何減少應用啟動時…

Webpack優化詳解

Webpack 5提供了一系列工具和功能,可以在本地開發和線上構建過程中進行優化,以提高開發效率和構建性能。 1. 本地開發優化 1.1. 開啟模塊熱替換(HMR) 模塊熱替換可以在不刷新整個頁面的情況下更新模塊,提高開發效率。 const webpack = require(webpack);module.export…

latency 對功耗的影響

文章目錄 1、Connection Interval(連接間隔) vs. Latency(從機延遲)2、為什么不能完全依賴 Connection Interval?3、什么時候可以不用 Latency?4、如何正確配置?5、結論調節連接間隔(Connection Interval)確實可以直接影響通信頻率和功耗,但 Latency(從機延遲)仍然…

10分鐘搭建 PHP 開發環境教程

下載、安裝 Xserver 下載 php 過程中如果提示需要安裝 vc 運行環境&#xff0c;按照引導下載安裝即可 安裝 nginx 安裝 Mysql 支持多個版本同時安裝 下載 php 過程中如果提示需要安裝 vc 運行環境&#xff0c;按照引導下載安裝即可mysql 默認用戶名為 root&#xff0c;默認密…