【C/C++筆記-0】題目彙總

1、判斷‘x’是小寫字母符的C表達式:
	if(’a’<=’x’<=’z’)
2、設有定義“char buffer[x]”,將字符串“abcd”賦值給buffer的安全解語句是:
	strcpy(buffer, "abcd");
	wsprint(buffer, "abcd");
	char* p = "abcd";
	strcpy(buffer, p);

錯誤解:

	char buffer[5];
	buffer = "abcd";
	//賦值類型錯誤
	/* 	buffer[5]是已經分配空間的
	 *	而“abcd”是一個常量字符串,他的地址是固定的
	 */
  • 數組的本質是指針(地址),如buffer[5]是一個數組變量,buffer是一個指向數組首元素的指針(首地址),其值與&buffer[0]相等,即是說:"buffer實際上是一個地址常量,對地址常量的賦值buffer = "abcd"必然是不可行的
  • 實際上“abcd”這樣的字符串,也是一個地址,他指向一塊連續的內存,所以strcpy能將指針變量作爲第二個參數使用strcpy(buffer, p),因爲在本質上指針p和“abcd”都是地址(指針)。

我們可做如下實驗驗證上述問題

	char* a="abcd";
	char* b="abcd";
	printf("0x%p\n0x%p\n", a, b);;

此時a與b的值是相等的,即a與b指向了同一個地址(a和b是一對相等的指針),即是說,在第一次定義“abcd”時,系統已經爲該字符串分配了一個連續的地址空間,而“abcd”這樣一個“表達式”指向了這個地址空間,所以在char* b = "abcd"時,只是將剛剛定義的地址賦值給了b指針而已。

  • 總結:數組名、指針名、字符串都是指針(地址),但數組名只能指向數組的首地址,而字符串指向的一定以一塊連續的地址空間,指針名可以指向一個地址也可以指向一塊地址空間
3、Linux32位C程序,請計算以下sizeof的值
	char str[] = "HelloWo";
 	char* p = str;
 	int n = strlen(p);

答案:8;4;4

sizeof有兩種語法形式:

	sizeof(type_name);	//sizeof(類型);
	sizeof object;		//sizeof 對象;

sizeof計算對象的大小也是轉換成對對象類型的計算,即

	sizeof p	//p爲char*類型
	sizeof(p)
	sizeof(char*)
	sizeof(int*)
	sizeof(int**)

這5種寫法得出的sizeof大小均爲指針變量的大小,在32位機器中指針變量的返回值爲4,64位機器中爲8,單位爲字節。

再看char str[] = "HelloWo";雖然數組長度爲8,sizeof也爲8,但實際上,sizeof並不能直接求數組長度,一般求數組長度用strlen,若用sizeof通常有如下兩種寫法:

	int a = sizeof(str) / sizeof(char);
	//用數組總內存大小 除 數組類型內存大小
	int b = sizeof(str) / sizeof(str[0]);
	//用數組總內存大小 除 任意元素內存大小

擴展:結構體的sizeof

	struct S1{char c;int i;};
	printf("sizeof(S1) = %d\n", sizeof(S1));

此時char佔1字節,int佔4字節,相加爲5字節,但輸出結果卻爲8
我們先定義如下變量:

	S1 s1 = {'a', 0xFFFFFFFF};

進入debug,當執行到變量定義後用GDB命令:x/8xb &s1查看內存,可以得到:

->->post-prompt
0x70fe40: 0x61 0x00 0x00 0x00 0xff 0xff 0xff 0xff

在0x61與0xFFFFFFFF中間夾雜了三個0x00,這就是計算機的字節對齊

字節對齊的細節和具體編譯器實現相關,但一般而言,滿足三個準則:

  1. 結構體變量的首地址能夠被其最寬基本類型成員的大小所整除;
  2. 結構體每個成員相對於結構體首地址的偏移量都是成員大小的整數倍,如有需要編譯器會在成員之間加上填充字節;例如上面第二個結構體變量的地址空間。
  3. 結構體的總大小爲結構體最寬基本類型成員大小的整數倍,如有需要編譯器會在最末一個成員之後加上填充字節。

附:GDB命令相關:https://blog.csdn.net/haifeng_gu/article/details/73928545

4、h頭文件中的ifndef/define/endif的作用?
	#ifndef x	//if (x is) not define
	#define x
		//如果x沒有被宏定義過,定義x,並編譯程序段 1
	#endif   
		//如果x已經定義,則編譯程序段2的語句

條件指示符#ifndef最主要目的是防止頭文件的重複包含和編譯。

條件編譯當然也可以用條件語句來實現。 但是用條件語句將會對整個源程序進行編譯,生成的目標程序程序很長。如果條件選擇的程序段很長,採用條件編譯的方法是十分必要的。

5、#include<file.h>與#include"file.h"

標準規定,包含C++提供的標準頭文件或系統頭文件時應使用尖括號,包含自定義頭文件時可使用雙引號。

當使用<>包含頭文件時,編譯器將在系統目錄查找
當使用""包含頭文件時,編譯器將按照“用戶目錄 - 安裝路徑 - 系統目錄”的順序查找

7、宏定義求數組元素個數
#define tablen(table) (sizeof(table) / sizeof(table[0]))
8、定義:int a[][3]={1,2,3,4,5,6,7,8,9,10},則*(*a+1)+2)的值爲:
在這裏插入代碼片
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章