嵌軟八股大全4 - C 數(shù)組與指針
Array
1、一維數(shù)組
1.1、初始化
// 1
int a[5] = {1,2,3,4,5};
// 2
int a[]={1,2,3,4,5};
1.2、元素訪問
兩種方式
- 數(shù)組下標
- 指針計算 (
+
與*
同等優(yōu)先級,從右向左結合)
#include <stdio.h>
#define arr_length(a) (sizeof(a)/sizeof(a[0]))
int main()
{
int a[4] = {1,2,3,4};
int *p1 = a;
int (*p2)[4] = &a;
for(int i = 0;i < arr_length(a);i++)
{
// 1. 數(shù)組下標的方式
printf("%d ", a[i]);
// 2. 指針計算的方式
printf("%d ", *a+i);
printf("%d ", *p1+i);
printf("%d ", *(*p2+i));
printf("\n");
}
}
2、二維數(shù)組
2.1、初始化
// 1
int a[3][2] = {1,2,3,4,5,6};
// 2
int a[3][2] = {{1,2},{3,4},{5,6}};
// 3
int a[][2] = {1,2,3,4,5,6};
// 4
int a[][2] = {{1,2},{3,4},{5,6}};
2.2、元素訪問
同樣也是兩種方式
- 數(shù)組下標
- 指針計算
直接看程序
#include <stdio.h>
int main()
{
int a[3][2] = {1,2,3,4,5,6};
int *p1 = &a[0][0];
int (*p3)[3][2] = &a;
for(int i = 0;i < 3;i++)
for(int j = 0;j < 2;j++)
{
// 1. 數(shù)組下標的方式
printf("%d ", a[i][j]);
// 2. 指針計算的方式
// 一維指針
printf("%d ", *(p1+i*2+j));
// 二維指針
printf("%d ", *(*(a+i)+j));
printf("%d ", *(*(*p3+i)+j));
printf("\n");
}
}
3、問題
3.1、數(shù)組名 num / &num 的區(qū)別?
- num 和 &num 一樣,均表示數(shù)組的起始地址
- 對于一維數(shù)組,num+1 表示偏移到數(shù)組內(nèi)下個元素,&num + 1 則表示偏移整個數(shù)組
- 對于二維數(shù)組,num+1 表示偏移一個一維數(shù)組,&num + 1 則表示偏移整個數(shù)組
#include <stdio.h>
int main(void)
{
//一維數(shù)組
int array_1[3]={1,2,3};
// array = &array, 均表示數(shù)組起始地址
printf("array_1=%p,&array_1=%p\n",array_1,&array_1);
printf("array_1+1=%p,&array_1+1=%p\n",array_1+1,&array_1+1);
//二維數(shù)組
int array_2[3][3]={{1,2,3},{4,5,6},{7,8,9}};
printf("array_2=%p,&array_2=%p\n",array_2,&array_2);
printf("array_2+1=%p,&array_2+1=%p\n",array_2+1,&array_2+1);
return 0;
}
output:
array_1=00000022d47ffba4,&array_1=00000022d47ffba4
array_1+1=00000022d47ffba8,&array_1+1=00000022d47ffbb0
array_2=00000022d47ffb80,&array_2=00000022d47ffb80
array_2+1=00000022d47ffb8c,&array_2+1=00000022d47ffba4
從輸出可以得出
- array_1 = &array_1,array_2 = &array_2
- array_1+1 偏移了 4 字節(jié),也即一維數(shù)組 array_1 內(nèi)一個元素
- &array_1+1 偏移了 12 字節(jié),也即一維數(shù)組 array_1 所占字節(jié)數(shù)
- array_2+1 偏移了 12 字節(jié),也即二維數(shù)組 array_2 第一行一位數(shù)組
- &array_2+1 偏移了 36 字節(jié),也即二維數(shù)組 array_2 所占字節(jié)數(shù)
Pointer
1、基本概念
1.1、指針類型、指針指向類型、指針值、指針地址
- 指針 ptr 類型為 int*
- 指針 ptr 指向類型為 int
- 指針 ptr 的值為 &a(變量 a 的地址),就是地址
- 指針 ptr 地址為 &ptr
#include <stdio.h>
int main(void)
{
int a = 99;
int* ptr =& a;
printf("&a=%p,&ptr=%p,ptr=0x%x,a=%d,*ptr=%d\n", &a, &ptr, a, ptr, *ptr);
}
pc output:
&a=0x605ff6e8,&ptr=0x605ff6e0,ptr=0x605ff6e8,a=99,*ptr=99
stm32f407 output:
&a=0x20000564,&ptr=0x20000560,ptr=0x20000564,a=99,*ptr=99
1.2、求指針占據(jù)內(nèi)存大小
- 在 32 位系統(tǒng)中,一個指針變量在內(nèi)存中占據(jù) 4 個字節(jié)的空間
- 在 64 位系統(tǒng)中,一個指針變量在內(nèi)存中占據(jù) 8 個字節(jié)的空間
#include <stdio.h>
int main(void)
{
char *a;
printf("%llu",sizeof(a));
}
output:
8
2、相關操作
2.1、const 屬性 (指針常量、常量指針)
const 屬性表示只讀,不可修改
2.1.1、指針常量 int* const ptr;
const 修飾指針 ptr,表示指針變量內(nèi)容為只讀,不可修改(指針常量),因此只能指向第一次賦值的變量
#include <stdio.h>
int main(void)
{
int a = 99;
int b = 11;
int* const ptr = &a;
// ?,指針指向的地址不可修改
ptr = &b;
// ?
*ptr = 22;
}
2.1.2、常量指針 const int *ptr;
const 修飾指針 ptr 指向的那個變量,表示指針指向的變量內(nèi)容為只讀,不可修改(常量指針),因此可以更改指針 ptr 指向的地址,但是不能修改指針指向地址變量的內(nèi)容
#include <stdio.h>
int main(void)
{
int a = 99;
int b = 11;
const int *ptr = &a;
//int const *ptr = &a;
// ?
ptr = &b;
// ?,指針指向的變量值不可修改
*ptr = 22;
}
指針常量常常被用在函數(shù)參數(shù)上,這個函數(shù)只需要讀取原始數(shù)據(jù),不需要(也不可以)改變原始數(shù)據(jù)
void getData(const int* ptr)
{
//do somethings
}
2.1.3、簡單記憶
- 指針本身是一個常量 -> 指針常量 -> 地址不可以修改(error: ptr=&b;)
- 指向常量的一個指針 -> 常量指針 -> 值不可以修改(error: *ptr=2;)
2.2、void * 類型指針
- 任意類型的指針均可直接賦值給空指針 ptr
- 空指針 ptr 賦值給其他類型的指針時需要強制類型轉換
void *ptr;
2.3、空指針、野指針
2.3.1、空指針
不指向任何東西的指針 -> 空指針
int *ptr = NULL;
NULL 在 C 中實質為 void* 類型,在 C++ 中實質為 0
#ifdef __cplusplus
#define NULL 0
#else
#define NULL ((void *)0)
#endif
2.3.2、野指針
地址已經(jīng)失效的指針 -> 野指針
#include <stdio.h>
#include <stdlib.h>
int main(void)
{
// 申請一字節(jié)內(nèi)存寫入20
int *p = (int *)malloc(4);
*p = 20;
printf("*p=%d\n",*p);
// 釋放掉申請的內(nèi)存
free(p);
// 查看野指針
剩余60%內(nèi)容,訂閱專欄后可繼續(xù)查看/也可單篇購買
歡迎來到我的專欄,在這里,我將整理并分享2024年各大企業(yè)的真實筆試/面試真題,同時還整理了嵌入式軟件相關的八股知識。專欄內(nèi)容涵蓋C/C++基礎、嵌軟常見通信協(xié)議、ARM、FreeRTOS、Linux OS相關問題匯總,希望能幫助求職者了解考試趨勢和嵌入式常見考點。無論你是準備面試,還是希望提升自己的專業(yè)知識,這里都能為你提供寶貴的參考和學習資源。