命令行勿负, <sublime class="log_commands"></sublime>
if(x == (pow(a,3) + pow(b,3) + pow(c,3))){
printf("%4d \n", x);
} //必須== ( 有括號把右側項包裹
6_11 迭代法平方根e
6_12牛頓法求方程根
6_13二分法求fangchenggen
6_1 最大公約數(shù)丐谋,最小公倍數(shù)
segment fault。 scanf 沒加 & 除破。數(shù)組越界绊困。循環(huán)錯誤
7_1 素數(shù)
8_8 char num = 48 + 9int = ‘9’
10_4 傳遞float *p
10_5 一圈,123報數(shù)抡诞,剩下的一個
常用庫函數(shù)
0.1 <stdio.h>
Break 跳出當前層循環(huán)
- fopen
- int feof(FILE *stream)
- void rewind(FILEF * stream)
- 將文件 內部的 位置指針 穷蛹,重新指向開頭土陪,等同于fseek(0)
- putchar()
- fread()
- purw()
- fseek()
定義函數(shù):int fseek(FILE * stream, long offset, int whence);
- 欲將讀寫位置移動到文件開頭時:fseek(FILE *stream, 0, SEEK_SET);
- 欲將讀寫位置移動到文件尾時:fseek(FILE *stream, 0, 0SEEK_END);
- int printf(const char *format, ....)
- strlen(s)
unsigned int strlen (char *s);
【參數(shù)說明】s為指定的字符串。
strlen()用來計算指定的字符串s 的長度肴熏,不包括結束字符"\0"鬼雀。
static char s[20] = "computer";
-
scanf() 為何有的變量加& 有的不加?
因為char str[10] ,一個數(shù)組蛙吏,str是內存段頭地址
fscanf()
%[*][width][length]specifier
;char *fgets(char *buf, int bufsize, FILE *stream);獲取一行源哩。
如果使用fgets()讀取某個文件,第一次讀取的bufsize為5鸦做,而文件的第一行有10個字符(算上'\n')励烦,那么讀取文件的指針會偏移至當前讀取完的這個字符之后的位置。也就是第二次再用fgets()讀取文件的時候馁龟,則會繼續(xù)讀取其后的字符崩侠。而漆魔,如果使用fgets() 讀取文件的時候bufsize大于該行的字符總數(shù)加2(多出來的兩個坷檩,一個保存文件本身的'\n'換行,一個保存字符串本身的結束標識'\0')改抡,文件并不會繼續(xù)讀下去矢炼,僅僅只是這一行讀取完,隨后指向文件的指針會自動偏移至下一行
例:
如果一個文件的當前位置的文本如下
Love, I Have
Since you can do it.
如果用fgets(str1,6,file1);去讀取
則執(zhí)行后str1 = "Love," 阿纤,讀取了6-1=5個字符
這個時候再執(zhí)行fgets(str1,20,file1)則執(zhí)行后str1 = " I Have\n"
而如果
fgets(str1,23,file1);
則執(zhí)行str1="Love ,I Have"句灌,讀取了一行(包括行尾的'\n',并自動加上字符串結束符'\0'),當前文件位置移至下一行欠拾,雖然23大于當前行上字符總和胰锌,可是不會繼續(xù)到下一行。而下一次調用fgets()繼續(xù)讀取的時候是從下一行開始讀藐窄。
- strstr()
strstr()函數(shù)用來檢索子串在字符串中首次出現(xiàn)的位置资昧,其原型為:
? char *strstr( char *str, char * substr );【參數(shù)說明】str為要檢索的字符串,substr為要檢索的子串荆忍。
【返回值】返回字符串str中第一次出現(xiàn)子串substr的地址格带;如果沒有檢索到子串,則返回NULL刹枉。
#include<stdio.h> #include<string.h> int main(){ // 也可以改成 char str[] = "http://see.xidian.edu.cn/cpp/u/xitong/"; char *str = "http://see.xidian.edu.cn/cpp/u/xitong/"; char *substr = "see"; char *s = strstr(str, substr); printf("%s\n", s); return 0; }
- Strcmp strcpy
#include <string.h> main(){ char *a = "aBcDeF"; char *b = "AbCdEf"; char *c = "aacdef"; char *d = "aBcDeF"; printf("strcmp(a, b) : %d\n", strcmp(a, b)); printf("strcmp(a, c) : %d\n", strcmp(a, c)); printf("strcmp(a, d) : %d\n", strcmp(a, d)); }
char str1[15]; char str2[15]; int ret; strcpy(str1, "abcdef"); strcpy(str2, "ABCDEF");
10的n次方可以表示為pow(10, n)
1數(shù)據(jù)類型
Ctrl + Shift +V --------粘貼過程中保持縮進
1.1 整數(shù)類型
(Int)強制類型轉換
- char 1 -128-127 / 0-255
- unsigned char 1 0-255
- int 2or4 -32768~32767
- short 2 -32768~32767
- long 4 -2147483648~2147483647
1.2浮點類型
- float 4 6位小數(shù)
- double 8 15位小數(shù)
- long double 16 19位小數(shù)
#include <stdio.h>
#include <float.h>
int main(){
printf("float 存儲最大字節(jié)數(shù) : %lu \n", sizeof(float));
printf("float 最小值:%E \n" , FLT_MIN);
printf("float 最大值:%E \n",FLT_MAX);
printf("精度值: %d \n", FLT_DIG);
return 0;
}/
- 如果I為整型變量叽唱,f為float型變量,c表達式'a'+I*f的類型為
- 即使是兩個float微宝,都化成double,float的數(shù)據(jù)在運算時一律轉化成雙精度模型
- ?
1.3 void類型
- void exit(int status);
- int rand(void);
- 指針指向void:
- 類型為void * 的指針棺亭,代表對象的地址,而不是類型蟋软。
- 例如:void *malloc(size_tsize); 反悔指向void的指針镶摘,可以轉換為任何數(shù)據(jù)類型
1.4 前綴
0X 十六進制
0 8??進制
后綴
ULul
2 變量 & 常量
- 靜態(tài)局部變量 在靜態(tài)存儲區(qū) 分配存儲單元
- 'A' 和 "A" 都是字符串常量
- 'a' 知識編寫整數(shù)的另一種方法
- "a" 只是編寫一個有 雙引號之間字符 和 一個附加 二進制為0的字符 所
- 初始化的 一個無名數(shù)組的指針 的 一種簡短方法
char *S = “\ta\017bc”; //6個字符
已初始化的的全局變量和局部靜態(tài)變量存放在.data段专甩,未初始化的全局變量和局部靜態(tài)變量一般存放在.bss段里,前者在生產可執(zhí)行文件時就分配好內存了钉稍,后者在加載時才分配
- 靜態(tài)外部變量可以賦初值涤躲,也可以不付初值
- 靜態(tài)外部變量的作用與外部變量相同 error
2.1 指針
?```python
int p =0;
int p =0;
含義:
1. p指向 的 內存,存放的是 整形數(shù)據(jù)贡未;
2. 該內存區(qū)域只存放了一個數(shù)據(jù)种樱,跨越的內存區(qū)域 為4字節(jié),即p+1的效果是跳過4字節(jié)
?```python
struct a {
int x1;
short x2;
a *next;
}
- p指向的內存區(qū)域依次存放了三種類型的數(shù)據(jù)俊卤,int\short\指針類型
- p指向的內存區(qū)域跨越了12個字節(jié)嫩挤,即p+1的效果是跳過了12個字節(jié)
- 為何不是10?對齊
const修飾符
const int* p; #整形常量(修飾int
int* const p; #常量指針(修飾p p是指針變量
const int* const p; (
函數(shù)與指針
- 指向函數(shù)的指針: 可以利用它代替函數(shù)名來調用函數(shù)消恍。
- 如何定義:由于一個程序中可以用多個函數(shù)名相同(重載)岂昭,因此定義函數(shù)指針的時候必須包含函數(shù)的參數(shù)蝎亚,這樣才能準確的指向兴溜。
- int (p)(const char ,int ); 表示p是一個指向函數(shù)的指針,返回int
- 若 int* p(const char*,int); 函數(shù)的聲明另玖,函數(shù)名為p,返回一個指向int型的指針.
- int* (p)(const char , int);
- ?
宏定義
可以引用已經定義了的宏名佣赖,可以層層置換
宏名的有效范圍定義命令之后到本源文件結束恰矩,可以用#define終止宏定義的作用域
-
#define M 5
#define N M+M
枚舉類型
- 枚舉元素是 常量,不能賦值
- 枚舉元素有值憎蛤,默認從0外傅;enum weekday {sun=7,mon=1,tue,wed,thu,fri,sat}day;
- 可用作判斷 > 也可
- 整數(shù),不可直接賦值 枚舉變量 俩檬。 day = (enum weekday)2;(將順序號為2的枚舉元素賦值給day)
- ?
Static
最主要有兩點用途萎胰。
- 讓一個變量長期有效,而不管其是在什么地方被申明棚辽。比如:
? int fun1()
? {
? static int s_value = 0;
? ....
? }
? 那么fun1不管在什么地方被調用技竟,當函數(shù)退出后,s_value最后的值將一直會被系統(tǒng)保存(相當于一個全局變量)晚胡,下次s_value再被用到時灵奖,也即當fun1()再次被調用時,s_value初始值將是最近被保存過的值(請注意s_value初始化操作只會被執(zhí)行一次估盘,即上述s_value =0 這個語句)瓷患。
2.避免多個文件使用了相同的變量名而導致沖突
比如有多個文件,分別由幾個人獨立開發(fā)的遣妥。假定他們在各自的文件中定義相同的“全局”變量名(僅僅指在他們獨自的文件中全局)擅编,當系統(tǒng)集成時,由于他們使用了名字一樣的“全局”變量,導致有難于遇見的問題爱态。解決這個問題方便的做法就是在各自文件中谭贪,在相同的全局變量申明前加上static修飾符。這樣系統(tǒng)就會為他們分配不同的內存锦担,互不影響了俭识。
當一個進程的全局變量被聲明為static之后,它的中文名叫靜態(tài)全局變量洞渔。靜態(tài)全局變量和其他的全局變量的存儲地點并沒有區(qū)別套媚,都是在.data段(已初始化)或者.bss段(未初始化)內,但是它只在定義它的源文件內有效磁椒,其他源文件無法訪問它堤瘤。所以,普通全局變量穿上static外衣后浆熔,它就變成了新娘本辐,已心有所屬,只能被定義它的源文件(新郎)中的變量或函數(shù)訪問医增。
靜態(tài)局部變量慎皱,函數(shù)內使用,值保存
3 存儲類
3.1 auto存儲類
3.2 register存儲類
3.3 extern存儲類
3.4
4 運算符
~ ,++>(/*+- >>)>== >&& > ||
(2) a||b+c&&b-c
5 函數(shù) & 作用域
5.1 引用方式調用函數(shù)
void swap(int *x, int *y){
int temp;
temp = *x;
*x = *y;
*y = temp;
return;
}
#include<stdio.h>
void swap(int *x, int *y);
int main(){
int a = 100;
int b = 200;
swap(&a, &b);
return;
}
6 數(shù)組
- 字符數(shù)組最后不必是'\0'
6.1 多維數(shù)組
6.2 傳遞數(shù)組給函數(shù)
- 方式一
void myFunc(int *param){}
- 方式二
void myFunc(int param[10]){}
- 方式三
void myFunc(int param[]){}
實例
double getAverage(int arr[], int size){
int i;
double avg;
double sum;
for(i = 0; i<size; ++i){
sum += arr[i];
}
avg = sum / size;
return avg;
}
#include<stdio.h>
double getAverage(int arr[],int size);
int main(){
int balance[5] = {1,2,3,4};
double avg = getAverage(balance , 4);
return 0;
}
不管是
int intArr[6]
還是int intArr[]
都不會創(chuàng)建一個數(shù)組出來调窍,編譯器也不會為它們分配內存宝冕,實際的數(shù)組是不存在的张遭,它們最終還是會轉換為int *intArr
這樣的指針邓萨。這就意味著,兩種形式都不能將數(shù)組的所有元素“一股腦”傳遞進來菊卷,大家還得規(guī)規(guī)矩矩使用數(shù)組指針,所以在函數(shù)內不可能知道數(shù)組的大小必須傳遞進來缔恳。?
?
用函數(shù)做參數(shù)時,必須在主調函數(shù)和被盜函數(shù)中分別定義數(shù)組洁闰?
型參數(shù)組長度可以大于實參數(shù)組長度
數(shù)組名做參數(shù)屬于值傳遞
6.2.傳遞二維數(shù)組給函數(shù)
6.3 從函數(shù)返回數(shù)組
6.4 指向數(shù)組的指針
Double *p;
Double balance[10];
p= balance
7 指針
8 字符串
9 結構體
#include <stdio.h>
struct m{
int x;
int *y;
}*p;
int a[4]={11,22,33,44};
struct m b[4] = {55,&a[2],66,&a[0],77,&a[1]};
int main (){
p= b;
printf("%d \n", ++p->x); // ->優(yōu)先級大于++
printf("%d \n",(++p)->x);
printf("%d \n", ++(*p->y)); // *的優(yōu)先級高于->
return 0;
}
10 共用體(
11 位域(
12 typedef
13 輸入 & 輸出
13.1 scarf & gets
Scanf(%c) 時歉甚。會吧換行符接受
scanf %s:當遇到回車,空格和tab鍵會自動在字符串后面添加'\0'扑眉,但是回車纸泄,空格和tab鍵仍會留在輸入的緩沖區(qū)中。要處理腰素。
gets:可接受回車鍵之前輸入的所有字符聘裁,并用'\n'替代 '\0'.回車鍵不會留在輸入緩沖區(qū)中。
13.2 printf(%s) puts()
puts只是多個換行
%c 字符
%d 有符號十進制整數(shù)
%ld是按長整型輸出弓千,長度是整型的2倍32位衡便,%e %E 使用eE的科學計數(shù)法
%x %X 無符號十六進制 (大小寫字母)
%o 8進制
unsigned a,b,x
int n;
a=0x763;
n=6;
b=a<<(12-n);
x=(a>>n-2)^b; //+,-,的優(yōu)先級比<<,>>高。
printf(“\n b=%x, \n x=%x”,b,x);
%2d 結果十進制,長度為2 ,右對齊,不夠補空格,多了以實際長度輸出
比如結果是1,輸出:(空格)1
結果為123(長度大于等于2):輸出:123
補充:
%-2d 左對齊,其余同上
%.2d從執(zhí)行效果來看,和% 02d一樣
%04d,輸出4位(十進制),不足在前面補0,如 123-》0123
M %md 以寬度m輸出整型數(shù)镣陕,不足m時谴餐,左補空格
0m %0md 以寬度m輸出整型數(shù),不足m時呆抑,左補零
m,n %m.nf 以寬度m輸出實型小數(shù)岂嗓,小數(shù)位為n位double i = 12.3,
printf("%2f"鹊碍,i摄闸,a ) ;
輸出:12.300000
printf("%2.1f",i妹萨,a ) ;
輸出:12.3
14 文件讀寫
FILE *fopen( const char *filename, const char *mode);
r 允許讀取年枕,
r+ 允許讀寫,文件必須存在乎完。2000——1
rb打開二進制文件熏兄,允許讀寫。
w 允許寫入树姨,如果與已存在的文件相同摩桶,清空重寫
w+ 允許讀寫, 創(chuàng)建空文件帽揪。
a 允許寫入硝清,追加內容
a+ 允許讀寫,開頭讀转晰,追加
int fclose( FILE *fp);
成功返回0
錯誤返回EOF
實際上芦拿,清空緩沖區(qū)中數(shù)據(jù), 關閉文件查邢,并釋放該文件所有內存
- 使用flcose 關閉文件時蔗崎,先寫緩沖區(qū)到文件,再釋放指針扰藕。
fread()函數(shù)用于從文件流中讀取數(shù)據(jù)缓苛,其原型為:
? size_t fread(void *buffer, size_t size, size_t count, FILE * stream);
【參數(shù)】buffer為接收數(shù)據(jù)的地址,size為一個單元的大小邓深,count為單元個數(shù)未桥,stream為文件流。
fread() 和 fwrite() 一般用于二進制文件的輸入輸出芥备,ASCII文件還是不要考慮了冬耿。
Dangling pointer & Wild pointer
void func()
{
char *dp = malloc(A_CONST);
/* ... */
free(dp); /* dp now becomes a dangling pointer */
dp = NULL; /* dp is no longer dangling */
/* ... */
}
and the wild pointer is the one not initialized
How to avoid ?
void safefree(void **pp)
{
if (pp != NULL) { /* safety check */
free(*pp); /* deallocate chunk, note that free(NULL) is valid */
*pp = NULL; /* reset original pointer */
}
}
int f(int i)
{
char *p = NULL, *p2;
p = (char *)malloc(1000); /* get a chunk */
p2 = p; /* copy the pointer */
/* use the chunk here */
safefree(&p); /* safety freeing; does not affect p2 variable */
safefree(&p); /* this second call won't fail */
char c = *p2; /* p2 is still a dangling pointer, so this is undefined behavior. */
}
malloc() 相關概念
- (參數(shù)) 以Byte記
- 函數(shù)執(zhí)行完后該塊內存并未初始化
- 成功返回內存塊地址
- 返回類型是void* ,意思是反悔指針類型未知门躯,所以要進行強制類型轉換
char *ch = (char *)malloc(10);
動態(tài)內存分配:
#include <stdio.h> // printf, scanf, NULL
#include <stdlib.h> // malloc free rand symtem
int main(){
int i,n;
char *buffer;
printf("請輸入字符串的長度:");
scanf("%d", $i);
buffer = (char *)malloc(i+1); //字符串結尾有 \0
if(buffer == null) exit(1); // 檢測是否分配成功
//隨機生成字串
for(n = 0; n<i; n++){
buffer[n] = rand()%26 + 'a';
}
buffer[i+1] = '\0';
printf("隨機生成的字符串為: %s \n", buffer);
free(buffer);
system("pause");
return 0;
}
int arr[]= {11,22,33,44,55};
數(shù)組名可以認為是一個指針淆党,它指向數(shù)組的第0個元素
如何以指針的方式遍歷數(shù)組
?
#include<stdio.h>
int main(){
int arr[] = {11,22,33,44,55};
int len = sizeof(arr) / sizeof(int);
int i;
for(i= 0;i<len;i++){
print("%d", *(arr+i));
}
printf("\n");
return 0;
}
- sizeof() 數(shù)組占用字節(jié)數(shù)
- sizeof(int) 數(shù)組元素占用字節(jié)數(shù)
- arr 是int* 類型的指針 , 每次加 1,即 增加sizeof(int)
- *(arr+i)
指向數(shù)組的指針
int arr[] = {11,22,33,44}
int *p = arr;
* arr本身就是一個指針染乌, 可以直接賦值給 指針變
* 也可 int *p = &arr[0];
數(shù)組指針指向的是數(shù)組中的一個具體元素山孔,不是整個數(shù)組,所以數(shù)組指針的類型和數(shù)組元素的類型有關
阿斯頓發(fā)
int *p = arr, len = sizeof(arr)/ sizeof(int);
// 編譯器并不知道 p是個數(shù)組荷憋,所以不能 sizeof(p) 獲得len
下標訪問
p是指向數(shù)組arr的指針台颠, 可以 p[i];
使用指針
*(p+i)
#include <stdio.h>
int main(){
int arr[] = {11,22,33,44};
int i, *p = arr, len = sizeof(arr)/sizeof(int);
for(i= 0; i< len; i++){
printf("%d", *p++);
}
print("\n");
return 0;
}
// eual *(p++)
// wrong *(arr++)
main函數(shù)的參數(shù)
main() 可選兩個參數(shù),命令行下傳入勒庄, argc 是安參數(shù)十幾個數(shù)自動賦予串前。
main(int argc,char *argv){
while(argc-- >1)
{
printf("%s", *argv++);
}
}
多維數(shù)組的地址##
int a[3][4] = {{0,1,2,3,4},{4,5,6,7},{8,9,10,11}}
可以分成3個數(shù)組,
然而是 a[0], a[1], a[2]
a是 a[0]的首地址
a, a[0], *(a+0), *a , &a[0][0] 是相等的
a[1] 是第二個一位數(shù)組的數(shù)組名实蔽, 和首地址
&a[i] 不能被理解為a[i]的地址荡碾, 因為不存在元素a[i]
a[0] 可以看成是a[0]+0 , 是一維數(shù)組a[0]的 0號元素的首地址。a[0]+1 是1號元素首地址
#include <stdio.h>
int main(){
int a[3][4] = {{0,1,2,3},{4,5,6,7},{8,9,10,11}};
//printf("%d", a);
//printf("%d", &a[2]);
printf("%d \n", *(a[0]+2));
printf("%d \n", *(*(a+1)));
printf("%d \n", **(a+2) );
printf("%d,%d \n",*(a[1]+1),*(*(a+1)+1));
return 0;
}