二級(jí)指針相對(duì)于一級(jí)指針弊仪,顯得更難熙卡,難在于指針和數(shù)組的混合,定義不同類型的二級(jí)指針励饵,在使用的時(shí)候有著很大的區(qū)別
第一種內(nèi)存模型char *arr[]
若有如下定義
char *arr[] = {"abc", "def", "ghi"};
這種模型為二級(jí)指針的第一種內(nèi)存模型驳癌,在理解的時(shí)候應(yīng)該這樣理解:定義了一個(gè)指針數(shù)組(char * []),數(shù)組的每個(gè)元素都是一個(gè)地址役听。
其實(shí)做為一個(gè)學(xué)習(xí)者颓鲜,有一個(gè)學(xué)習(xí)的氛圍跟一個(gè)交流圈子特別重要這里我推薦一個(gè)C語言C++交流群1075673198,不管你是小白還是轉(zhuǎn)行人士歡迎入駐禾嫉,大家一起交流成長(zhǎng)。
在使用的時(shí)候蚊丐,若要使用中間量操作元素熙参,那么此時(shí)中間量應(yīng)該定義為
char *tmp = NULL;
如果要打印這個(gè)數(shù)組,那么可以使用以下函數(shù)
int i = 0;
if (pArray == NULL)
{
return -1;
}
for (i = 0; i < num; i++)
{
printf("%s \n", pArray[i]);
}
return 0;
}
第二種內(nèi)存模型char arr[][]
若有如下定義
char arr[3][5] = {"abc", "def", "ghi"};
種模型為二級(jí)指針的第二種內(nèi)存模型麦备,在理解的時(shí)候應(yīng)該這樣理解:定義了一個(gè)二維數(shù)組孽椰,有3個(gè)(5個(gè)char)空間的存儲(chǔ)變量昭娩。
在使用的時(shí)候,若要使用中間量操作元素黍匾,那么此時(shí)中間量應(yīng)該定義為
char tmp[5] = { 0 };
如果要打印這個(gè)數(shù)組栏渺,那么可以使用以下函數(shù)
nt printAarray(char pArray[][5], int num) {
int i = 0;
if (pArray == NULL)
{
return -1;
}
for (i = 0; i < num; i++)
{
printf("%s \n", pArray[i]);
}
return 0;
}
第三種內(nèi)存模型char **arr
若有如下定義
char **arr = (char *)malloc(100 * sizeof(char *));//char arr[400]
arr[0] = (char *)malloc(100 * sizeof(char));//char buf[100]
arr[1] = (char *)malloc(100 * sizeof(char));
arr[2] = (char *)malloc(100 * sizeof(char));
strcpy(arr[0], "abc");
strcpy(arr[1], "def");
strcpy(arr[2], "ghi");
···
for(int i = 0; i < 3; i++)
if(arr[i] != NULL)
free(arr[i]);
free(arr);
這種模型為二級(jí)指針的第二種內(nèi)存模型,在理解的時(shí)候應(yīng)該這樣理解:定義了一個(gè)二級(jí)指針锐涯,二級(jí)指針就是指向指針的指針磕诊,其實(shí)就是開辟了100個(gè)指針空間,存放了100個(gè)地址纹腌。這種寫法是第一種的簡(jiǎn)化寫法
其實(shí)做為一個(gè)學(xué)習(xí)者霎终,有一個(gè)學(xué)習(xí)的氛圍跟一個(gè)交流圈子特別重要這里我推薦一個(gè)C語言C++交流群1075673198,不管你是小白還是轉(zhuǎn)行人士歡迎入駐升薯,大家一起交流成長(zhǎng)莱褒。
在使用的時(shí)候,若要使用中間量操作元素涎劈,那么此時(shí)中間量應(yīng)該定義為
char *tmp = NULL
如果要打印這個(gè)數(shù)組广凸,那么可以使用以下函數(shù)
{
int i = 0;
if (pArray == NULL)
{
return -1;
}
for (i = 0; i < num; i++)
{
printf("%s \n", pArray[i]);
}
return 0;
}
例子
把第一種內(nèi)存模型的數(shù)據(jù)排序,運(yùn)算結(jié)果放到第三種內(nèi)存模型中
include "stdio.h"
#include "string.h"
#include "stdlib.h"
char **SortArrayAndGen3Mem(const char ** const myArray1, int num, char *str, int *myNum) {
char **p = NULL;
p= (char **)malloc(num*sizeof(char *));
if (myArray1==NULL || str==NULL|| myNum==NULL)
{
printf("傳入?yún)?shù)錯(cuò)誤\n");
p = NULL;
goto END;
}
*myNum = num;
for (int i = 0; i < num;i++)
{
p[i] = NULL;
p[i] = (char)malloc(50 * sizeof(char));
memset(p[i], 0, sizeof(p[i]));
if (p[i]==NULL)
{
printf("內(nèi)存分配錯(cuò)誤!\n");
goto END;
}
strcpy(p[i], myArray1[i]);
}
char *tmp;
for (int i = 0; i < num; i++)
{
for (int j = i + 1; j < num; j++)
{
if (strcmp(p[i],p[j])>0)
{
char *tmp = p[i];
p[i] = p[j];
p[j] = tmp;
}
}
}
for (int i = 0; i < num; i++)
{
printf("%s \n", myArray1[i]);
}
END:
return p;
}
//釋放內(nèi)存函數(shù)
void main() {
int i = 0;
char **myArray3 = NULL;
int num3 = 0;
//第一種內(nèi)存模型
char *myArray[] = {"bbbbb", "aaaaa", "cccccc"};
char *myp = "111111111111";
myArray3 = SortArrayAndGen3Mem(myArray, 3, myp, &num3);
for (i=0; i<num3; i++)
{
printf("%s \n", myArray3[i]);
}
system("pause");
}
#include "stdio.h"
#include "stdlib.h"
#include "string.h"
char **SortArrayAndGet3Mem(const char* const myArray1,int num,char *str,int *myNum);
int getArray(char ***newp,int num) ;
int freeArray(char ***newpfree,int num);
int sortTArray(char *p, int num);
void main() {
char **myArray3=NULL;
int num3=0;
char *myArray[]={"bbbb","aaa","cccc"};
char *myp="111111111";
myArray3=SortArrayAndGet3Mem(myArray,3,myp,&num3);
system("pause");
}
char **SortArrayAndGet3Mem(const char** const myArray1,int num,char *str,int *myNum) {
int ret=0;
char **p=NULL;
int i=0;
char **p1=NULL;
p1=(char **)myArray1;
ret=getArray(&p,num +1);
for (i=0;i<num;i++)
{
strcpy(p[i],p1[i]);
}
strcpy(p[i], str);
ret=sortTArray(p,num +1);
for (i=0;i<num +1;i++)
{
printf("%s\n",p[i]);
}
ret=freeArray(&p,num +1);
*myNum = num +1;
return p;
}
int getArray(char ***newp,int num) {
int i=0;
int ret=0;
char **tmp = NULL;
tmp = (char **)malloc(num*sizeof(char *));
for (i=0;i<num;i++)
{
tmp[i]=(char*)malloc(sizeof(char)*100);
}
*newp = tmp; //
return 0;
}
//
int freeArray(char ***newpfree,int num) {
char **p=NULL;
int i=0;
int ret=0;
p=*newpfree;
for (i=0;i<num;i++)
{
free(p[i]);
}
free(p);
*newpfree = NULL; //
return ret;
}
//int sortTArray(char ***Arraystr, int num)
int sortTArray(char **Arraystr, int num) {
int i , j = 0;
for (i=0; i<num; i++)
{
for (j=i+1; j<num; j++)
{
if (strcmp((Arraystr)[i],(Arraystr)[j])>0)
{
char tmp[100];
strcpy(tmp,(Arraystr)[i]);
strcpy((Arraystr)[i],(Arraystr)[j]);
strcpy((Arraystr)[j],tmp);
}
}
}
for (i=0;i<num;i++)
{
printf("%s\n",(Arraystr)[i]);
}
return 0;
}
時(shí)間:2020-06-09
本文實(shí)例講述了javascript 內(nèi)存模型.分享給大家供大家參考,具體如下: 我對(duì)于 JavaScript 的內(nèi)存模型一直都比較困惑,很想了解在操作變量的時(shí)候,JS 是如何工作的.如果你和我有同樣的困惑,希望這篇文章能給你一些啟發(fā). 譯文,喜歡原文的可以直接拉到底部 當(dāng)我們聲明變量.初始化變量.更改變量值的時(shí)候,到底會(huì)發(fā)生什么?JavaScript 是如何實(shí)現(xiàn)這些基本的功能?最重要的是,我們?nèi)绾尾拍芾斫膺@些基礎(chǔ)知識(shí)? 本文將覆蓋以下 4 個(gè)方面: JavaScript 原始數(shù)據(jù)類型的變量聲明和
前言 正常情況下,通過分析界面以及 class-dump 出來頭文件就能對(duì)某個(gè)功能的實(shí)現(xiàn)猜個(gè)八九不離十.但是 Block 這種特殊的類型在頭文件中是看不出它的聲明的,一些有 Block 回調(diào)的方法名 dump 出來是類似這樣的: - (void)FM_GetSubscribeList:(long long)arg1 pageSize:(long long)arg2 callBack:(CDUnknownBlockType)arg3; 因?yàn)檫@種回調(diào)看不到它的方法簽名,我們無法知道這個(gè) Block
Java8內(nèi)存模型PermGen Metaspace實(shí)例解析
一.JVM 內(nèi)存模型 根據(jù) JVM 規(guī)范,JVM 內(nèi)存共分為虛擬機(jī)棧.堆.方法區(qū).程序計(jì)數(shù)器.本地方法棧五個(gè)部分. 1.虛擬機(jī)棧:每個(gè)線程有一個(gè)私有的棧,隨著線程的創(chuàng)建而創(chuàng)建.棧里面存著的是一種叫"棧幀"的東西,每個(gè)方法會(huì)創(chuàng)建一個(gè)棧幀,棧幀中存放了局部變量表(基本數(shù)據(jù)類型和對(duì)象引用).操作數(shù)棧.方法出口等信息.棧的大小可以固定也可以動(dòng)態(tài)擴(kuò)展.當(dāng)棧調(diào)用深度大于JVM所允許的范圍,會(huì)拋出StackOverflowError的錯(cuò)誤,不過這個(gè)深度范圍不是一個(gè)恒定的值,我們通過下面這段程序可以測(cè)
詳解C語言中的內(nèi)存四區(qū)模型及結(jié)構(gòu)體對(duì)內(nèi)存的使用
內(nèi)存四區(qū) 1.代碼區(qū) 代碼區(qū)code,程序被操作系統(tǒng)加載到內(nèi)存的時(shí)候,所有的可執(zhí)行代碼都加載到代碼區(qū),也叫代碼段,這塊內(nèi)存是不可以在運(yùn)行期間修改的. 2.靜態(tài)區(qū) 所有的全局變量以及程序中的靜態(tài)變量都存儲(chǔ)到靜態(tài)區(qū). 3.棧區(qū) 棧stack是一種先進(jìn)后出的內(nèi)存結(jié)構(gòu),所有的自動(dòng)變量,函數(shù)的形參都是由編譯器自動(dòng)放出棧中,當(dāng)一個(gè)自動(dòng)變量超出其作用域時(shí),自動(dòng)從棧中彈出.對(duì)于自動(dòng)變量,什么時(shí)候入棧,什么時(shí)候出棧,是不需要程序控制的,由C語言編譯器.實(shí)現(xiàn)棧不會(huì)很大,一般都是以K為單位的. 當(dāng)椫朊叮空間以滿,但還往棧
詳解Java語言中一個(gè)字符占幾個(gè)字節(jié)谅海?
題主要區(qū)分清楚內(nèi)碼(internal encoding)和外碼(external encoding)就好了. 內(nèi)碼是程序內(nèi)部使用的字符編碼,特別是某種語言實(shí)現(xiàn)其char或String類型在內(nèi)存里用的內(nèi)部編碼: 外碼是程序與外部交互時(shí)外部使用的字符編碼."外部"相對(duì)"內(nèi)部"而言:不是char或String在內(nèi)存里用的內(nèi)部編碼的地方都可以認(rèn)為是"外部".例如,外部可以是序列化之后的char或String,或者外部的文件.命令行參數(shù)之類的. Java語
各種數(shù)據(jù)存放在磁盤或內(nèi)存中都有其不同的存放格式,因此就存在不同的數(shù)據(jù)類型.了解各種數(shù)據(jù)的特性,對(duì)編程開發(fā)來說是十分重要. 程序中經(jīng)常會(huì)進(jìn)行一些運(yùn)算,易語言中的運(yùn)算都要使用運(yùn)算符進(jìn)行識(shí)別處理,并通過運(yùn)算表達(dá)式來完成運(yùn)算操作.程序中對(duì)各數(shù)據(jù)之間的關(guān)系的描述也要通過運(yùn)算符. 1.易語言的數(shù)據(jù)類型 一個(gè)程序內(nèi)部應(yīng)包括兩個(gè)方面的內(nèi)容:1.數(shù)據(jù)的描述.2.操作步驟,即對(duì)程序動(dòng)作的描述. 數(shù)據(jù)是程序操作的對(duì)象,操作的結(jié)果會(huì)改變數(shù)據(jù)的內(nèi)容.打個(gè)比方:要做一道菜,做菜前先選擇烹飪的原材料(即對(duì)數(shù)據(jù)進(jìn)行描述),然后
類 在 Swift 中類是建立靈活的構(gòu)建塊.類似于常量,變量和函數(shù),用戶可以定義的類的屬性和方法.Swift給我們提供了聲明類,而無需用戶創(chuàng)建接口和實(shí)現(xiàn)文件的功能.Swift 允許我們創(chuàng)建類作為單個(gè)文件和外部接口,將默認(rèn)在類一次初始化來創(chuàng)建. 使用類的好處: 繼承獲得一個(gè)類的屬性到其他類 類型轉(zhuǎn)換使用戶能夠在運(yùn)行時(shí)檢查類的類型 初始化器需要處理釋放內(nèi)存資源 引用計(jì)數(shù)允許類實(shí)例有一個(gè)以上的參考 類和結(jié)構(gòu)的共同特征: 屬性被定義為存儲(chǔ)值 下標(biāo)被定義為提供訪問值 方法被初始化來改善功能 初始狀態(tài)是由初
1.函數(shù):當(dāng)程序很小的時(shí)候,我們可以使用一個(gè)main函數(shù)就能搞定,但當(dāng)程序變大的時(shí)候,就超出了人的大腦承受范圍,邏輯不清了,這時(shí)候就需要把一個(gè)大程序分成許多小的模塊來組織,于是就出現(xiàn)了函數(shù)概念: 函數(shù)是C語言代碼的基本組成部分,它是一個(gè)小的模塊,整個(gè)程序由很多個(gè)功能獨(dú)立的模塊(函數(shù))組成.這就是程序設(shè)計(jì)的基本分化方法: (1) 寫一個(gè)函數(shù)的關(guān)鍵: 函數(shù)定義:函數(shù)的定義是這個(gè)函數(shù)的實(shí)現(xiàn),函數(shù)定義中包含了函數(shù)體,函數(shù)體中的代碼段決定了這個(gè)函數(shù)的功能: 函數(shù)聲明:函數(shù)聲明也稱函數(shù)原型聲明,函數(shù)的原
結(jié)構(gòu)體的自引用(self reference),就是在結(jié)構(gòu)體內(nèi)部,包含指向自身類型結(jié)構(gòu)體的指針. 結(jié)構(gòu)體的相互引用(mutual reference),就是說在多個(gè)結(jié)構(gòu)體中,都包含指向其他結(jié)構(gòu)體的指針. 1. 自引用 結(jié)構(gòu)體 1.1 不使用typedef時(shí) 錯(cuò)誤的方式: struct tag_1{ struct tag_1 A; /* 結(jié)構(gòu)體 */ int value; }; 這種聲明是錯(cuò)誤的,因?yàn)檫@種聲明實(shí)際上是一個(gè)無限循環(huán),成員b是一個(gè)結(jié)構(gòu)體,b的內(nèi)部還會(huì)有成員是結(jié)構(gòu)體,依次下去,無線循環(huán).
詳解c語言中的 strcpy和strncpy字符串函數(shù)使用
strcpy 和strcnpy函數(shù)--字符串復(fù)制函數(shù). 1.strcpy函數(shù) 函數(shù)原型:char *strcpy(char *dst,char const *src) 必須保證dst字符的空間足以保存src字符,否則多余的字符仍然被復(fù)制,覆蓋原先存儲(chǔ)在數(shù)組后面的內(nèi)存空間的數(shù)值,strcpy無法判斷這個(gè)問題因?yàn)樗麩o法判斷字符數(shù)組的長(zhǎng)度. #include <stdio.h> #include<string.h> int main() { char message
這篇文章專注于 6 個(gè)操作符,==,!=,<,<=,> 和 >=.我們將深入探討它們的語法和用法的細(xì)微差別.對(duì)很多人來說,這聽起來不像是吸引人的事,或者他們可能已經(jīng)從其他編程語言獲得了糟糕的經(jīng)驗(yàn).然而,在 Go 中它們定義的很好并簡(jiǎn)潔.下面討論的主題,如可比性將出現(xiàn)在其他場(chǎng)合,如 maps.為了使用上述操作符,至少有一個(gè)操作數(shù)需要可賦值給第二個(gè)操作數(shù): package main import "fmt" type T struct { name string }
指針的特點(diǎn) 他就是內(nèi)存中的一個(gè)地址 指針本身運(yùn)算 指針?biāo)赶虻膬?nèi)容是可以操作的 操作系統(tǒng)是如何管理內(nèi)存的 椑ず颍空間 4M~8m的大小 當(dāng)進(jìn)入函數(shù)的時(shí)候會(huì)進(jìn)行壓棧數(shù)據(jù) 堆空間 4g的大小 1g是操作系統(tǒng) 全局變量 內(nèi)存映射 可以對(duì)內(nèi)存的內(nèi)容修改修改硬盤的內(nèi)容 一般在數(shù)據(jù)庫(kù)中經(jīng)常使用 內(nèi)存的分配與釋放 c語言分配內(nèi)存的方法 // malloc(需要分配的大小): 這里的分配的大小需要對(duì)齊的2的指數(shù) void *mem = malloc(size); 釋放內(nèi)存 // 一般分配的內(nèi)容都是在堆空間中的 //
詳解C語言中的符號(hào)常量胁赢、變量與算術(shù)表達(dá)式
C語言中的符號(hào)常量 在結(jié)束討論溫度轉(zhuǎn)換程序前,我們?cè)賮砜匆幌路?hào)常量.在程序中使用 300.20 等類似的"幻數(shù)"并不是一個(gè)好習(xí)慣,它們幾乎無法向以后閱讀該程序的人提供什么信息,而且使程序的修改變得更加困難.處理這種幻數(shù)的一種方法是賦予它們有意義的名字.#define 指令可以把符號(hào)名(或稱為符號(hào)常量)定義為一個(gè)特定的字符串: #define 名字 替換文本 在該定義之后,程序中出現(xiàn)的所有在 #define 中定義的名字(既沒有用引號(hào)引起來,也不是其它名字的一部分)都將用相應(yīng)的替換文本.