C語言 川大復(fù)試 筆記

命令行, <sublime class="log_commands"></sublime>

if(x == (pow(a,3) + pow(b,3) + pow(c,3))){
        printf("%4d \n", x);
} //必須== ( 有括號把右側(cè)項包裹

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 跳出當(dāng)前層循環(huán)

  • fopen
  • int feof(FILE *stream)
  • void rewind(FILEF * stream)
  • 將文件 內(nèi)部的 位置指針 ,重新指向開頭,等同于fseek(0)
  • putchar()
  • fread()
  • purw()
  • fseek()

定義函數(shù):int fseek(FILE * stream, long offset, int whence);

  1. 欲將讀寫位置移動到文件開頭時:fseek(FILE *stream, 0, SEEK_SET);
  2. 欲將讀寫位置移動到文件尾時:fseek(FILE *stream, 0, 0SEEK_END);
  • int printf(const char *format, ....)
  • strlen(s)

unsigned int strlen (char *s);

【參數(shù)說明】s為指定的字符串。

strlen()用來計算指定的字符串s 的長度,不包括結(jié)束字符"\0"。

  • static char s[20] = "computer";

  • scanf() 為何有的變量加& 有的不加?

    因為char str[10] ,一個數(shù)組,str是內(nèi)存段頭地址

  • fscanf() %[*][width][length]specifier;

  • char *fgets(char *buf, int bufsize, FILE *stream);獲取一行。

如果使用fgets()讀取某個文件,第一次讀取的bufsize為5,而文件的第一行有10個字符(算上'\n'),那么讀取文件的指針會偏移至當(dāng)前讀取完的這個字符之后的位置。也就是第二次再用fgets()讀取文件的時候,則會繼續(xù)讀取其后的字符。而,如果使用fgets() 讀取文件的時候bufsize大于該行的字符總數(shù)加2(多出來的兩個,一個保存文件本身的'\n'換行,一個保存字符串本身的結(jié)束標(biāo)識'\0'),文件并不會繼續(xù)讀下去,僅僅只是這一行讀取完,隨后指向文件的指針會自動偏移至下一行

例:

如果一個文件的當(dāng)前位置的文本如下

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',并自動加上字符串結(jié)束符'\0'),當(dāng)前文件位置移至下一行,雖然23大于當(dāng)前行上字符總和,可是不會繼續(xù)到下一行。而下一次調(diào)用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 --------粘貼過程中保持縮進(jìn)

1.1 整數(shù)類型

(Int)強(qiáng)制類型轉(zhuǎn)換

  • 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表達(dá)式'a'+I*f的類型為
  • 即使是兩個float,都化成double,float的數(shù)據(jù)在運算時一律轉(zhuǎn)化成雙精度模型
  • ?

1.3 void類型

  • void exit(int status);
  • int rand(void);
  • 指針指向void:
  • 類型為void * 的指針,代表對象的地址,而不是類型。
  • 例如:void *malloc(size_tsize); 反悔指向void的指針,可以轉(zhuǎn)換為任何數(shù)據(jù)類型

1.4 前綴

0X 十六進(jìn)制
0 8??進(jìn)制
后綴
ULul

2 變量 & 常量

  • 靜態(tài)局部變量 在靜態(tài)存儲區(qū) 分配存儲單元
  • 'A' 和 "A" 都是字符串常量
  • 'a' 知識編寫整數(shù)的另一種方法
  • "a" 只是編寫一個有 雙引號之間字符 和 一個附加 二進(jìn)制為0的字符 所
  • 初始化的 一個無名數(shù)組的指針 的 一種簡短方法
    char *S = “\ta\017bc”;  //6個字符

已初始化的的全局變量和局部靜態(tài)變量存放在.data段,未初始化的全局變量和局部靜態(tài)變量一般存放在.bss段里,前者在生產(chǎn)可執(zhí)行文件時就分配好內(nèi)存了,后者在加載時才分配

  • 靜態(tài)外部變量可以賦初值,也可以不付初值
  • 靜態(tài)外部變量的作用與外部變量相同 error

2.1 指針

?```python
int p =0;
int
p =0;

含義:
1. p指向 的 內(nèi)存,存放的是 整形數(shù)據(jù);
2. 該內(nèi)存區(qū)域只存放了一個數(shù)據(jù),跨越的內(nèi)存區(qū)域 為4字節(jié),即p+1的效果是跳過4字節(jié)
?```python
    struct a {
        int x1;
        short x2;
        a *next;        
    }
  1. p指向的內(nèi)存區(qū)域依次存放了三種類型的數(shù)據(jù),int\short\指針類型
  2. p指向的內(nèi)存區(qū)域跨越了12個字節(jié),即p+1的效果是跳過了12個字節(jié)
  3. 為何不是10?對齊
    const修飾符
    const int* p; #整形常量(修飾int
    int* const p; #常量指針(修飾p p是指針變量
    const int* const p;   (

函數(shù)與指針

  1. 指向函數(shù)的指針: 可以利用它代替函數(shù)名來調(diào)用函數(shù)。
  2. 如何定義:由于一個程序中可以用多個函數(shù)名相同(重載),因此定義函數(shù)指針的時候必須包含函數(shù)的參數(shù),這樣才能準(zhǔn)確的指向。
  3. int (p)(const char ,int ); 表示p是一個指向函數(shù)的指針,返回int
  4. 若 int* p(const char*,int); 函數(shù)的聲明,函數(shù)名為p,返回一個指向int型的指針.
  5. int* (p)(const char , int);
  6. ?

宏定義

  • 可以引用已經(jīng)定義了的宏名,可以層層置換

  • 宏名的有效范圍定義命令之后到本源文件結(jié)束,可以用#define終止宏定義的作用域

  • #define M 5

    #define N M+M

枚舉類型

  1. 枚舉元素是 常量,不能賦值
  2. 枚舉元素有值,默認(rèn)從0;enum weekday {sun=7,mon=1,tue,wed,thu,fri,sat}day;
  3. 可用作判斷 > 也可
  4. 整數(shù),不可直接賦值 枚舉變量 。 day = (enum weekday)2;(將順序號為2的枚舉元素賦值給day)
  5. ?

Static

最主要有兩點用途。

  1. 讓一個變量長期有效,而不管其是在什么地方被申明。比如:

? int fun1()

? {

? static int s_value = 0;

? ....

? }

? 那么fun1不管在什么地方被調(diào)用,當(dāng)函數(shù)退出后,s_value最后的值將一直會被系統(tǒng)保存(相當(dāng)于一個全局變量),下次s_value再被用到時,也即當(dāng)fun1()再次被調(diào)用時,s_value初始值將是最近被保存過的值(請注意s_value初始化操作只會被執(zhí)行一次,即上述s_value =0 這個語句)。

2.避免多個文件使用了相同的變量名而導(dǎo)致沖突

比如有多個文件,分別由幾個人獨立開發(fā)的。假定他們在各自的文件中定義相同的“全局”變量名(僅僅指在他們獨自的文件中全局),當(dāng)系統(tǒng)集成時,由于他們使用了名字一樣的“全局”變量,導(dǎo)致有難于遇見的問題。解決這個問題方便的做法就是在各自文件中,在相同的全局變量申明前加上static修飾符。這樣系統(tǒng)就會為他們分配不同的內(nèi)存,互不影響了。

當(dāng)一個進(jìn)程的全局變量被聲明為static之后,它的中文名叫靜態(tài)全局變量。靜態(tài)全局變量和其他的全局變量的存儲地點并沒有區(qū)別,都是在.data段(已初始化)或者.bss段(未初始化)內(nèi),但是它只在定義它的源文件內(nèi)有效,其他源文件無法訪問它。所以,普通全局變量穿上static外衣后,它就變成了新娘,已心有所屬,只能被定義它的源文件(新郎)中的變量或函數(shù)訪問。

靜態(tài)局部變量,函數(shù)內(nèi)使用,值保存

3 存儲類

3.1 auto存儲類

3.2 register存儲類

3.3 extern存儲類

3.4

4 運算符

~ ,++>(/*+- >>)>== >&& > ||

(2) a||b+c&&b-c

5 函數(shù) & 作用域

5.1 引用方式調(diào)用函數(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ù)組出來,編譯器也不會為它們分配內(nèi)存,實際的數(shù)組是不存在的,它們最終還是會轉(zhuǎn)換為int *intArr這樣的指針。這就意味著,兩種形式都不能將數(shù)組的所有元素“一股腦”傳遞進(jìn)來,大家還得規(guī)規(guī)矩矩使用數(shù)組指針,所以在函數(shù)內(nèi)不可能知道數(shù)組的大小必須傳遞進(jìn)來。

  • ?

  • ?

  • 用函數(shù)做參數(shù)時,必須在主調(diào)函數(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 結(jié)構(gòu)體

#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:當(dāng)遇到回車,空格和tab鍵會自動在字符串后面添加'\0',但是回車,空格和tab鍵仍會留在輸入的緩沖區(qū)中。要處理。

gets:可接受回車鍵之前輸入的所有字符,并用'\n'替代 '\0'.回車鍵不會留在輸入緩沖區(qū)中。

13.2 printf(%s) puts()

puts只是多個換行

%c 字符
%d 有符號十進(jìn)制整數(shù)
%ld是按長整型輸出,長度是整型的2倍32位,%e %E 使用eE的科學(xué)計數(shù)法

%x %X 無符號十六進(jìn)制 (大小寫字母)
%o 8進(jìn)制

   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 結(jié)果十進(jìn)制,長度為2 ,右對齊,不夠補(bǔ)空格,多了以實際長度輸出
比如結(jié)果是1,輸出:(空格)1
結(jié)果為123(長度大于等于2):輸出:123
補(bǔ)充:
%-2d 左對齊,其余同上
%.2d從執(zhí)行效果來看,和% 02d一樣
%04d,輸出4位(十進(jìn)制),不足在前面補(bǔ)0,如 123-》0123

M %md 以寬度m輸出整型數(shù),不足m時,左補(bǔ)空格
0m %0md 以寬度m輸出整型數(shù),不足m時,左補(bǔ)零
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打開二進(jìn)制文件,允許讀寫。

w 允許寫入,如果與已存在的文件相同,清空重寫

w+ 允許讀寫, 創(chuàng)建空文件。

a 允許寫入,追加內(nèi)容

a+ 允許讀寫,開頭讀,追加

int fclose( FILE *fp);

成功返回0
錯誤返回EOF
實際上,清空緩沖區(qū)中數(shù)據(jù), 關(guān)閉文件,并釋放該文件所有內(nèi)存

  • 使用flcose 關(guān)閉文件時,先寫緩沖區(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() 一般用于二進(jìn)制文件的輸入輸出,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() 相關(guān)概念

  • (參數(shù)) 以Byte記
  • 函數(shù)執(zhí)行完后該塊內(nèi)存并未初始化
  • 成功返回內(nèi)存塊地址
  • 返回類型是void* ,意思是反悔指針類型未知,所以要進(jìn)行強(qiáng)制類型轉(zhuǎn)換
char *ch = (char *)malloc(10);

動態(tài)內(nè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); //字符串結(jié)尾有 \0
    if(buffer == null) exit(1); // 檢測是否分配成功

    //隨機(jī)生成字串
    for(n = 0; n<i; n++){
        buffer[n] = rand()%26 + 'a';
    }
    buffer[i+1] = '\0';

    printf("隨機(jī)生成的字符串為: %s  \n", buffer);
    free(buffer);

    system("pause");
    return 0;
}


int arr[]= {11,22,33,44,55};

數(shù)組名可以認(rèn)為是一個指針,它指向數(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ù)組元素的類型有關(guān)
阿斯頓發(fā)

    int *p = arr, len = sizeof(arr)/ sizeof(int);
    // 編譯器并不知道 p是個數(shù)組,所以不能 sizeof(p) 獲得len

下標(biāo)訪問
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;
    }
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容