溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點(diǎn)擊 登錄注冊 即表示同意《億速云用戶服務(wù)條款》

C 提高1 內(nèi)存四區(qū) 變量本質(zhì) 棧開口方向 指針鐵律1

發(fā)布時(shí)間:2020-07-25 10:15:04 來源:網(wǎng)絡(luò) 閱讀:637 作者:990487026 欄目:開發(fā)技術(shù)


C 提高第一天復(fù)習(xí)

內(nèi)存四區(qū),變量常量的本質(zhì),函數(shù)調(diào)用模型,棧開口方向,指針鐵律1,指針是一種數(shù)據(jù)類型




C 提高學(xué)員標(biāo)準(zhǔn):寫一個(gè)標(biāo)準(zhǔn)的冒泡排序

選擇法或者冒泡法排序

在一個(gè)函數(shù)內(nèi)排序

通過函數(shù)調(diào)用的方式排序

數(shù)組做函數(shù)參數(shù)的技術(shù)盲點(diǎn)和推演 

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int main()
{
	int i = 0;
	int j = 0;
	int tmp = 0;
	int a[] = {3,66,54,32,11,22,99,2334,32};
	
	for (i = 0; i < sizeof(a) / sizeof(int); i++)
	{
		printf("%d ",a[i]);
	}
	printf("\n", a[i]);

	for (i = 0; i < sizeof(a) / sizeof(int); i++)
	{
		for (j = i+1; j < sizeof(a) / sizeof(int); j++)
		{
			if (a[i] > a[j])
			{
				tmp = a[i];
				a[i] = a[j];
				a[j] = tmp;
			}
		}
	}

	for (i = 0; i < sizeof(a) / sizeof(int); i++)
	{
		printf("%d ", a[i]);
	}
	printf("\n", a[i]);



	system("pause");
}

編譯運(yùn)行:
3 66 54 32 11 22 99 2334 32
3 11 22 32 32 54 66 99 2334
請按任意鍵繼續(xù). . .


冒泡程序,優(yōu)化輸出與排序 與 函數(shù)的數(shù)組參數(shù)問題

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

void printfArray(int array[], int len)
{
	int i;
	for (i = 0; i < len; i++)
	{
		printf("%d ", array[i]);
	}
	printf("\n", array[i]);
}

//數(shù)組做函數(shù)的參數(shù)的退回問題,退回為一個(gè)指針
//結(jié)論:把數(shù)組內(nèi)存的首地址和有效長度傳給被調(diào)用的函數(shù)
//本質(zhì):函數(shù)中的數(shù)組形參,編譯器會(huì)把它當(dāng)成指針處理
void sortArray(int array[], int len)
{
	int i, j, tmp;
	for (i = 0; i <len; i++)
	{
		for (j = i + 1; j < len; j++)
		{
			if (array[i] > array[j])
			{
				tmp = array[i];
				array[i] = array[j];
				array[j] = tmp;
			}
		}
	}
}


int main()
{

	int a[] = {3,66,54,32,11,22,99,2334,32};
	int len = sizeof(a) / sizeof(int);

	printfArray(a, len);
	sortArray(a,len);
	printfArray(a, len);
	
	system("pause");
}



編譯運(yùn)行:
3 66 54 32 11 22 99 2334 32
3 11 22 32 32 54 66 99 2334
請按任意鍵繼續(xù). . .



數(shù)據(jù)類型概念:

“類型”是對數(shù)據(jù)的抽象 

類型相同的數(shù)據(jù)有相同的表示形式、存儲(chǔ)格式以及相關(guān)的操作 

程序中使用的所有數(shù)據(jù)都必定屬于某一種數(shù)據(jù)類型 

C 提高1  內(nèi)存四區(qū) 變量本質(zhì) 棧開口方向 指針鐵律1




基本數(shù)據(jù)類型:typedef 數(shù)組與地址

#include <stdio.h>
#include <stdlib.h>
#include <string.h>


struct teacher1{
	char name[64];
	int age;
}Teacher1;

//使用typedef,以后定義就是這樣了 Teacher2 t2;
typedef struct teacher2{
	char name[64];
	int age;
}Teacher2;


int main()
{
	
	int b[10];
	printf("b:%d , b+1:%d \n", b, b + 1);
	printf("&b:%d, &b+1:%d \n", &b, &b + 1);
	// b 代表數(shù)組首元素的地址
	// &b代表整個(gè)數(shù)組的地址
	// &b+1代表跨過整個(gè)數(shù)組地址


	struct teacher1 t1;
	Teacher1.age = 0;
	Teacher2 t2;

	typedef int u32;
	printf("u32 =%d \n",sizeof(u32));


	system("pause");
}
編譯運(yùn)行:
b:3603504 , b+1:3603508
&b:3603504, &b+1:3603544
u32 =4
請按任意鍵繼續(xù). . .



數(shù)據(jù)類型的本質(zhì)思考

思考數(shù)據(jù)類型和內(nèi)存有關(guān)系嗎?

C/C++為什么會(huì)引入數(shù)據(jù)類型?


數(shù)據(jù)類型的本質(zhì) 

數(shù)據(jù)類型可理解為創(chuàng)建變量的模具(模子);是固定內(nèi)存大小的別名。

數(shù)據(jù)類型的作用:編譯器預(yù)算對象(變量)分配的內(nèi)存空間大小

程序舉例,如何求數(shù)據(jù)類型的大小  sizeof(int *)

請問:數(shù)據(jù)類型可以有別名嗎?數(shù)據(jù)類型可以自定義嗎?(typedef)

C 提高1  內(nèi)存四區(qū) 變量本質(zhì) 棧開口方向 指針鐵律1




數(shù)據(jù)類型大小C程序:

#include <stdio.h>
#include <stdlib.h>

int main()
{
	int a = 10;
	int b[10] ;
	printf("int a:%d \n", sizeof(a));
	printf("int a:%d \n", sizeof(int *));
	printf("int b:%d \n", sizeof(b));
	printf("int b:%d \n", sizeof(b[0]));
	printf("int b:%d \n", sizeof(*b));
	printf("hello.....\n");
	return 0;
} 
編譯運(yùn)行:
C:\Users\chunli>gcc main.c & a
int a:4
int a:4
int b:40
int b:4
int b:4
hello.....



常量的探討:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>


char * getstr1()
{
	char *p = "1234";
	return p;
}

char * getstr2()
{
	char *p = "5678";
	return p;
}

int main()
{
	char *p1 = NULL;
	char *p2 = NULL;
	p1 = getstr1();
	p2 = getstr2();
	printf("%s,%s \n", p1, p2);
	printf("%d,%d \n", p1, p2);
	system("pause");
}

編譯運(yùn)行:
1234,5678
14309464,14309644
請按任意鍵繼續(xù). . .


改一改:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>


char * getstr1()
{
	char *p = "1234";
	return p;
}

char * getstr2()
{
	char *p = "1234";
	return p;
}

int main()
{
	char *p1 = NULL;
	char *p2 = NULL;
	p1 = getstr1();
	p2 = getstr2();
	printf("%s,%s \n", p1, p2);
	printf("%d,%d \n", p1, p2);
	system("pause");
}

編譯運(yùn)行:
1234,1234
2054232,2054232
請按任意鍵繼續(xù). .



堆棧變量,函數(shù)返回一個(gè)被析構(gòu)的內(nèi)存空間塊

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

//堆
char * getmem(int size)
{
	char *p = NULL;
	p = (char *)malloc(size);
	return p;
}

//棧
//return 不是把內(nèi)存塊返回出來,而是把首地址返回了
char * getmem2()
{
	char p[20];
	strcpy(p, "haha2 \n");
	return p;	//【危險(xiǎn)!】p即將釋放,但是地址返回去來了。
}


int main()
{
	char  *p = NULL;
	p = getmem(20);
	strcpy(p, "haha1 \n");
	printf("%s",p);
	free(p);
	p = NULL;
	
	p = getmem2();//返回了一個(gè)被析構(gòu)的數(shù)據(jù)塊
	printf("%s", p);//不應(yīng)該這么做!


	system("pause");
}

編譯運(yùn)行:
haha1
haha2
請按任意鍵繼續(xù). . .




棧的開口方向:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>


int main()
{

	int a;
	int b;
	printf("&a = %d \n", &a);
	printf("&b = %d \n", &b);
	system("pause");
}
編譯運(yùn)行:
C:\Users\chunli>gcc -o main.exe main.c & main
&a = 2686652
&b = 2686648
請按任意鍵繼續(xù). . .

C 提高1  內(nèi)存四區(qū) 變量本質(zhì) 棧開口方向 指針鐵律1

數(shù)組基地址永遠(yuǎn)都是在下面:

C 提高1  內(nèi)存四區(qū) 變量本質(zhì) 棧開口方向 指針鐵律1



指針鐵律1:指針是一種數(shù)據(jù)類型


#include <stdio.h>
#include <stdlib.h>
#include <string.h>

//*p 在等號的左邊 修改內(nèi)存
//*p 在等號的右邊 讀取內(nèi)存


char * getstr()
{
	int *tmp = "hello \n";//	常量區(qū)
	return tmp;
}

int main()
{

	int a;
	char *p1 = 100;//分配4個(gè)字節(jié)
	p1 = &a;
	*p1 = 20;	//*就像一把鑰匙,找到這個(gè)地址,并修改它
	printf("%d  \n", sizeof(p1));
	printf("%d  \n", *p1);

	int b = 0;
	b = *p1;
	printf("%d  \n", b);


	char p2 = (char *)malloc(100);
	char p3 = (char *)malloc(100);

	char *p4 = getstr();
//	*(p4 + 2) = 'K';  因?yàn)榉祷氐氖浅A?,不能修改
	printf("%s",p4);
	system("pause");
}



指針經(jīng)典話語:

1,指針指向誰,就把誰的地址賦給指針;

2,指針變量 和 它指向的內(nèi)存空間變量是兩個(gè)不同的概念

3,理解指針的關(guān)鍵是內(nèi)存,沒有內(nèi)存哪里來的指針


變量的本質(zhì)是一個(gè)固定大小的數(shù)據(jù)塊,變量名就是數(shù)據(jù)塊的編號


內(nèi)存的使用范圍:

main函數(shù)可以在棧分配內(nèi)存/堆分配內(nèi)存/全局分配內(nèi)存,可以給子函數(shù)使用

子函數(shù)在棧分配的內(nèi)存不能給主函數(shù)使用,但是堆內(nèi)存與全局變量是可以給main使用


編譯器會(huì)為每個(gè)程序分配一個(gè)內(nèi)存4區(qū),主函數(shù)與子函數(shù)公用這個(gè)內(nèi)存4區(qū)


建立正確程序運(yùn)行內(nèi)存布局圖是學(xué)好C的關(guān)鍵!


 


指針鐵律1:指針是一種數(shù)據(jù)類型

1)指針也是一種變量,占有內(nèi)存空間,用來保存內(nèi)存地址

2)*p 操作內(nèi)存;

3)*就像一把鑰匙,通過一個(gè)地址(&a),去修改a變量的標(biāo)示的內(nèi)存空間

4)不斷的給指針賦值,相當(dāng)于不停的改變指針的指向。

5) 指針是一種數(shù)據(jù)類型,是指它指向內(nèi)存空間的數(shù)據(jù)類型





向AI問一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI