黑馬程式設計師—C語言筆記—記憶體剖析
一、進位制
1、定義:是一種計數的方式,數值的表示形式。
2、常用的4種進位制:
二進位制以0b/0B開頭如int num1 = 0b1100;
八進位制以0開頭如int num2 = 014;
十進位制如 int num3 = 12;
十六進位制以0x/0X開頭如int num4=0xc;
3、輸出格式符
4、進位制的轉換
a、二進位制轉十進位制 0b1100=1*2的3次方+1*2的2次方+0*2的1次方+0*2的0次方=12
b、十進位制轉二進位制 56=32+16+8=2的5次方+2的4次方+2的3次方=0b111000
5、n位二進位制的取值範圍:0 ~ 2的n次方-1。
二、變數的記憶體分析
1、記憶體是由大到小定址,只儲存二進位制形式。
a、數值在記憶體中的儲存:例:12是0000 0000 0000 0000 0000 0000 0000 1100
b、負值在記憶體中的儲存:例:-12是1111 1111 1111 1111 1111 1111 1111 0100
c、最前位是符號位,是0則為正數,是1則為負數。
d、負數的儲存涉及到了原碼、反碼、補碼。
2、基本資料型別的取值範圍:
3、例:
int main()
{
// 一個int型別資料佔據4個位元組、32bit
// 0000 0000 0000 0000 0000 0000 0000 1100
int number = 12; // 1100
// 0000 0000 0000 0000 0000 0000 0000 1101
int number2 = 13; // 1101
return 0;
}
三、型別說明符
1、short 2個位元組 %d輸出
short == short int;short a = 1和short int a = 1;是相同的;
2、long 8個位元組(擴充整型資料,擴充為8個位元組) %ld輸出
long == long int;一般有l來修飾說明是long型別;如long int a = 12345678901234l;
3、longlong8個位元組 %lld輸出
long long == long long int
4、signed代表有符號 最高位是符號位 -2的31次方~ 2的31次方-1 %d輸出;
5、unsigned代表無符號 最高位不是符號位 0 ~ 2的32次方-1 %u輸出;
signed和unsigned都是4個位元組,signed和int是一樣的,unsigned的最高位不要當做符號位。
long unsigned int a = 23894234;
四、位運算
1、&按位與:只有對應的兩個二進位均為1時,結果位才為1,否則為0。
12&5結果是4;
1100
0101 =>0100是4的二進位制。
作用:可以精確的獲取某一個精確位;
使用位與&運算子變數的奇偶性:
a&1 == 1; //a為奇數
a&1 == 0; //a為偶數
2、|按位或:只要對應的二個二進位有一個為1時,結果位就為1,否則為0。
16|5結果是13
1100
0101 =>1101是13的二進位制。
3、^按位異或:當對應的二進位相異(不相同)時,結果為1,否則為0。
12^5結果是9
1100
0101 =>1001是9的二進位制。
規律:
- 相同整數相^的結果是0;5^5==0;
- 多個整數相^的結果跟順序無關;5^6^7==5^7^6
- 任何數值和0進行^,結果還是原來的數值;5^0==5
- a^b^a==b;
例:不引入其他變數的情況下,使用異或^運算子實現兩個變數值的互換:
#include <stdio.h>
int main()
{
int a =10,b=12;
a=a^b;
b=a^b;
a=a^b;
printf(“a=%d,b=%d\n”,a,b)
return 0;
}
4、~按位取反
~0000 0000 0000 0000 0000 0000 0000 1001
1111 1111 1111 1111 1111 1111 1111 0110
printf(“%d\n”,~9);輸出的是-10;
5、<<左移
a << n => a * 2的n次方;
a、把整數a的各二進位全部左移n位,高位丟棄,低位補0。左移n位其實就是乘以2的n次方;b、由於左移是丟棄最高位,0補最低位,所以符號位也會被丟棄。
b、左移出來的結果值可能會改變正負性;
6、>>右移
a >> n => a /2的n次方;
a、把整數a的各二進位全部右移n位,保持符號位不變。右移n位其實就是除以2的n次方。
b、為正數時, 符號位為0,最高位補0;為負數時,符號位為1,最高位補1。
7、例:編寫一個函式,用來輸出整數在記憶體中的二進位制形式:
void printBinary(int number)
{
//記錄現在挪到第幾位
int temp = (sizeof(number)<<3) - 1;//相當於sizeof(number) * 8 - 1
while (temp >= 0) {
// 先挪位,再&1,取出對應位的值
int value = (number >> temp) & 1;
printf(“%d",value);
// 每輸出4位,就輸出一個空格
if( temp % 4 == 0)
{
printf(" ");
}
temp--;
}
printf("\n");
}
五、char型別
1、字元的儲存是參照ASCII碼錶轉成數值然後將二進位制存入記憶體;
a、char c= ‘A’ 存在記憶體中是佔1個位元組 存入的形式是0100 0001;
b、大寫字母與小寫字母差值固定32;’A’是65,’a’是97;
2、int num=6;存入記憶體為6的二進位制:0000 0000 0000 0000 0000 0000 0000 0110;
char a = ‘6’;存入記憶體為’6’的ASCII碼值:是54的二進位制:00110110;
3、注意
a、單引號只能括住單位元組的字元。
b、錯誤的寫法:char c = A;char c = "A";char c = 'ABCD';char c = '男';
c、正確的寫法:char c= ‘A’; char c = 65;
d、例:
#include <stdio.h>
int main()
{
char c = ‘A’;
switch(c)
{
case ‘A’ : printf(“1\n”);break;
case ‘B’ : printf(“2\n”);break;
//case 65 : printf(“3\n”);break;//這個和case ‘A’是重複的,都寫會報錯
default: printf(“4\n”);break;
}
return 0;
}
4、當做整型使用:在-128~127範圍內,可以當做整數來用
5、轉義字元 \
\n回車換行10;
\tTAB9;
\\一個反斜線字元92;
\'一個單引號字元39;
\”一個雙引號字元34;
\0空字元0;
6、例項:小寫轉大寫
#include <stdio.h>
int main()
{
char upper(char);
char c = upper(‘A’);
printf(“%c\n”,c);
return 0;
}
char upper(char c)
{
if(c >= ‘a’ && c<=’z’)
{
return c – (‘a’ - ‘A’);
}
return c;
}