常見單位和資料型別的範圍
bit byte kb mb gb tb pb
#include<stdio.h>
int main(){
printf("%d\n",sizeof(char)); //1 2^8 == 1024
printf("%d\n",sizeof(int)); //4 2^32 == 4294967296
//-2,147,483,648 到 2,147,483,647。10位數
printf("%d\n",sizeof(float)); //4
printf("%d\n",sizeof(double)); //8
printf("%d\n",sizeof(long)); //4
printf("%d\n",sizeof(short)); //2
printf("%d\n",sizeof(long long)); //8
return 0;
}
全域性變數和區域性變數
#include<stdio.h>
int a = 100;//全域性變數
int main(){
int a = 10;//函式里的區域性變數,可以和全域性變數名字相同,但是區域性優先
printf("%d",a);//10
return 0;
}
變數的作用域
區域性變數的作用域
區域性範圍【函式里】
#include<stdio.h>
int main(){
{
int a = 100;
printf("%d",a);
}
printf("%d",a);
return 0;
}
全域性函式的作用域
作用域整個工程
#include<stdio.h>
int a = 100;//全域性變數
int main(){
{
printf("%d ",a);
}
printf("%d",a);
return 0;
}
變數的生命週期 ~= 變數的作用域
區域性變數的生命週期
進入作用域開始,離開作用域結束
全域性變數的生命週期
整個工程
常量
- 字面常量【只有這個常量可以修改】
#include<stdio.h>
int main(){
int a = 20;
a = 50;
printf("%d",a);//50
return 0;
}
可以修改a的值
- const修飾的常變數
#include<stdio.h>
int main(){
const int a = 20;
a = 50;//報錯,常變數 不可更改
printf("%d",a);
return 0;
}
- define定義的識別符號常量
#include<stdio.h>
#define max 100
#define str "qwert"
//沒有資料型別
int main(){
max = 123; //error 不可修改
// a = 50;
printf("%d",max);
printf("%s",str);
return 0;
}
- 列舉常量
#include<stdio.h>
//#define max 100
//#define str "qwert"
enum Color{
RED,//列舉常量
GREEN,//列舉常量
BLUE,//列舉常量
};
int main(){
enum Color c = BLUE;//2
enum Color a = RED;//0
//printf("%s",str); error,其實列舉常量是一個數字,有點像是陣列
printf("%d",c);//2
return 0;
}
字串
C語言裡面沒有字串型別
結尾預設有\0
#include<stdio.h>
#include<string.h>
int main(){
char arr1[] = "abcd";
char arr2[] = {'a','b','c','d'};
char arr3[] = {'a','b','c','d','\0'};
printf("%s ",arr1);
printf("%s ",arr2);//隨機值,沒有\0結束
printf("%s ",arr3);//與arr1等價
printf("%d\n",strlen(arr1));//4 \0不算 strlen 使用需要string.h
printf("%d\n",strlen(arr2));//隨機值
printf("%d\n",strlen(arr3));//4 \0不算
return 0;
}
函式
#include <stdio.h>
int ADD(int a, int b){//ab是形參
int z = 0;
z = a + b;
return z;
//也可以直接 return a + b;
}
int main(){
int num1 = 0;
int num2 = 0;
scanf("%d %d",&num1,&num2);//num1,num2是實參
int sum = ADD(num1,num2);
printf("%d",sum);
return 0;
}
陣列
一個重要思想:透過下標訪問陣列裡的元素,用迴圈產生下標
運算子
單目運算子【對一個變數進行操作】
! - + & sizeof ~ -- ++ * (型別)
- !邏輯非
#include<stdio.h>
int main(){
int a = 22;
int b = 0;
printf("%d ",!a);//0
printf("%d",!b);//1
return 0;
}
- -負值
#include<stdio.h>
int main(){
int a = 22;
printf("%d ",-a);//-22
return 0;
}
- +沒有什麼用,1==+1 -1 == +(-1)
- sizeof
單位byte
#include<stdio.h>
int main(){
int arr[10] = {0};
printf("%d ",sizeof(arr));//40 計算整個陣列大小
printf("%d ",sizeof(arr[0]));//4 計算陣列第一個元素佔的位元組數
printf("%d ",sizeof(arr) / sizeof(arr[0]));//計算陣列元素有多少個
return 0;
}
- ++ --
區別i++ 與 ++i
前者先賦值[原來的值賦給別人],再自增【自己最後在自增改變自己】
後者先自增,再複製
#include<stdio.h>
int main(){
int a = 10;
int b = a++;
// b = 10 a = 11
int c = ++a;
// a = 12 c = 12
printf("%d %d",b,c);//10 12
return 0;
}
#include<stdio.h>
int main(){
int a = 10;
int b = a++;
// b = 10 a = 11
int c = b++;
// c = 10 b = 11
printf("%d %d %d\n",a,b,c)// 11 11 10
return 0;
}
#include<stdio.h>
int main(){
int a = 10;
int b = ++a;
// a = 11 b = 11
int c = ++b;
// b = 12 c = 12
int num1 = 9;
int num2 = --num1;
// num1 = 8 num2 = 8
int num3 = --num2;
// num2 = 7 num3 = 7
int num4 = --num3;
// num3 = 6 num 4 = 6
printf("%d %d %d\n",a,b,c);//11 12 12
printf("%d %d %d %d\n",num1,num2,num3,num4);//8 7 6 6
return 0;
}
- (型別)
強制型別轉化
#include<stdio.h>
int main(){
int a = 21;
int b = 4;
printf("%f ",(double)a/b);//5.25
return 0;
}
逗號運算子
都計算,但是隻列印最遠的那個
#include<stdio.h>
int main(){
int a = 4;
int b = 12;
int c = 6;
int tmp = (a++,b/a,c--);
//都執行了,只是只列印了c--
// a=5
int res = (c=b/a,a=b+c,c-a);
// c = 2 ,a = 14 , c-a==-12
printf("%d %d",res,tmp);//-12 6
return 0;
}
下標引用運算子[]
#include<stdio.h>
int main(){
int arr[10] = {0,1,2,1,3,4,5,6,6,8};//宣告陣列,arr[常量&null]
int n = 4;//呼叫陣列裡的元素,可以寫成a[變數]
printf("%d",arr[n]);//3
return 0;
}
函式呼叫運算子()
#include <stdio.h>
int ADD(int a, int b){//ab是形參
return a + b;
//也可以直接 return a + b;
}
int main(){
int num1 = 0;
int num2 = 0;
scanf("%d %d",&num1,&num2);//num1,num2是實參
int sum = ADD(num1,num2);//ADD(),呼叫函式,()就是函式呼叫運算子
printf("%d",sum);
return 0;
}
條件運算子【三目運算子】
#include<stdio.h>
int main(){
int a = 100;
int b = 20;
int r = a > b? a : b;//第一個是條件,滿足,r = a,反之,r = b
printf("%d",r);
return 0;
}
指標
記憶體
記憶體會分成一個個的記憶體單元(一個記憶體單元大小1byte),每個記憶體單元都有自己的編號【地址,指標】
32位機器上,地址是三十二位,4byte
64……,8byte
之前宣告資料型別很浪費
記憶體地址是2進位制
太長了,用16進位制列印
#include<stdio.h>
int main(){
int a = 10;
// &a;
printf("%p",&a);//列印地址用%p
return 0;
}
指標變數
存放地址的變數
#include<stdio.h>
int main(){
int a = 10;
// &a;
int* p = &a;//p就是指標變數
printf("%p",p);
printf("%p",&a);//二者等價
return 0;
}
解引用運算子*與取地址運算子&【一去一來,呼應】
透過*與&修改變數數值,但是地址不變
#include<stdio.h>
int main(){
int a = 10;
int* p = &a;//p就是指標變數
*p = 20;
printf("%d",a);//20
return 0;
}
指標變數大小
放地址的,只和機器位數有關
#include<stdio.h>
int main(){
printf("%d ",sizeof(char*));//4
printf("%d ",sizeof(int*));//4
printf("%d ",sizeof(float*));//4
printf("%d",sizeof(double*));//4
return 0;
}
結構體
.運算子
結構體物件.成員名
#include<stdio.h>
struct stu//一個型別
{
char name[20];
int age;
char sex[10];
char tele[12];
};//就像是蓋房子的圖紙
int main(){
struct stu s= {"zhangsan", 20, "man", 123457756};
printf("%s %d %s %d",s.name ,s.age ,s.sex ,s.tele);
return 0;
}
->箭頭運算子
結構體指標變數 -> 成員名
#include<stdio.h>
struct stu//一個型別
{
char name[20];
int age;
char sex[10];
char tele[12];
};//就像是蓋房子的圖紙
void functionPrint(struct stu* ps){
printf("%s %d %s %d\n",(*ps).name ,(*ps).age ,(*ps).sex ,(*ps).tele);//囉嗦,與下面等價
printf("%s %d %s %d",ps->name ,ps->age ,ps->sex ,ps->tele);//箭頭運算子
}
int main(){
struct stu s= {"zhangsan", 20, "man", 123457756};
functionPrint(&s);
return 0;
}