C語言指針收藏

指針是什麼

》》每個內存單元只能同時存儲一個數據,如何保證內存單元同時只能存儲一個數據,可使用編號的方式實現內存單元標記,此編號就是指針。小程序

》》指針是一個變量,指針是存放着一個數據的內存地址而不是數據自己的值,其是查找數據的另外一種方式數組

相關運算符

【&】在變量中取地址函數

【*】在地址中取變量測試

測試小程序:spa

#include<stdio.h>
void main() {
    int i = 10;//定義一個變量,並賦初始值爲10
    int *p = &i;//定義一個指針變量,並賦初始值爲i的地址
    *p = 199;
    printf("%d=%d", *p,i);//輸出199=199
    printf("---%d---", p);//獲得變量i的地址
}

指針變量的類型

》》指針類型:int *、float*、long*、double*、char*等等3d

》》指針變量的類型須要與存儲的數據類型相同指針

》》肯定類型能夠方便指針變量肯定存儲數據的大小,爲數據尋找到結束符,如int類型佔四個字節、char佔一個字節。也方便指針使用加1或減1操做,如int加減1會跳動4個字節,char加減1會跳動兩個字節。code

指針的賦值

int i=10;  int *p=&i;blog

int *pp;ip

pp=p;

指針運算符:

*p++

等同於*(p++),運算優先級爲從右到左,應該是先*p取值,而後地址移動一位,要區別與*(++p)。

指針變量做爲函數參數

#include<stdio.h>
//int *a1=&b1;
void fun(int *a1, int* a2) {
    
    *a1 = 100;
    int ii = 99;
    a2 = &ii;//讓指針從新指向另一個地址
    printf("獲得的數據:%d,%d", *a1, *a2);//輸出100,99
}
void main() {
    int b1 = 1, b2 = 2;
    fun(&b1, &b2);
    printf("調用函數後:%d,%d", b1, b2);//輸出100,2
}

輸出b2的結果並非相同的值,是由於執行調用函數改變了實參指針變量的值,並非改變了實參指針變量所指變量的值

一維數組指針變量

數組名(如arr)表明元素的首地址,數組第一個元素的地址也是這個數組的首地址(如&arr[0])。

數組指針中使用加減1將跳到下一個或者上一個數組元素地址,與使用 &arr[n+1] 基本相同。

若是整數數組名爲arr,運行int *p=arr,則*(p+3)、p[3]、*(arr+3)、arr[3]效果均是取出數組arr的第三個元素,在編譯時arr[3]其實是*(arr+3)處理的。

#include<stdio.h>
void main() {
    int arr[] = { 5,4,3,2,0 };
    int *p = arr;
    int *pp = &arr[0];
    printf("%d", *(p+3));//輸出2
}

函數數組參數

#include<stdio.h>
//等價於void fun(char a1[]) {
void fun(char *a1) {
    *(a1 + 2) = 'c';//改變第二個值的內容
}
void main() {
    char b1[] = { "123456789" };
    fun(b1);
    printf("調用函數後:%s", b1);//輸出: 12c456789
}

二維數組指針變量

#include<stdio.h>
void main() {
    int a1[][3] = { {10,11,12},{100,110,120} };
    int a[][3] = { 10,11,12,100,110,120 };
    printf("地址:%d==%d==%d==%d", a[0], &a[0][0],*(a+0),a+0);//輸出地址
    printf("%d===%d==%d", a[0][1], *(*(a + 0)+1),*(a[0]+1));//獲得值
}

指針引用字符串

字符串常量【char *ch = "dong xiao dong";】表示其指向地址的內容不可變,但指向的地址是可變的;

字符串變量【char ch[] = "dong xiao dong";】其指向地址的內容可變。

#include<stdio.h>
void main() {
    //char *ch = "dong xiao dong"; //字符串常量,不可變 
    char ch[] = "dong xiao dong";  //字符數組,可變
    ch[2] = '2';//字符串常量運行這條將報錯
    printf("%s\n", ch);
}

可變格式的輸出函數:

#include<stdio.h>
void main() {
    char *ch = "dong xiao %d\n";
    printf(ch, 10);
    ch = "xiaoxiao%d\n";
    printf(ch, 10);
    char chh[] = "dongdong %d\n";
    printf(ch, 100);
}

指向函數的指針

【int(*p)(int, int);//定義一個函數指針變量p】,第一個int表示返回值類型,第二個int和第三個int表示函數的參數類型。注意*p兩側的括號不能省略,表示p先與*結合,是指針變量,而後再於後面的()結合,()表示是函數,即該指針變量不是指向通常的變量,而是指向函數。若是寫成「int * p(int,int);」,因爲()優先級高於*,它至關於「int *(p(int,int))」,就成了聲明一個p函數,而且這個函數的返回值是指向整型變量的指針。

返回值爲int

#include<stdio.h>
void main() {
    int minto(int a, int b);//函數聲明
    int(*p)(int, int);//定義一個函數指針變量p
    p = minto;//函數指針指向函數minto首地址
    int cc = (*p)(11, 55);//調用函數
    printf("Min===%d", cc);
}

int minto(int a, int b) {
    if(a > b) return b;
    else return a;
}

無返回值:

#include<stdio.h>
void main() {
    void fun(int a);//函數聲明
    void (*p)(int);//定義一個函數指針變量p
    p = fun;//函數指針指向函數fun首地址
    (*p)(11);//調用函數
}
void fun(int a) {
    printf("%d\n", a);  
}

指向函數指針做爲函數的參數

#include<stdio.h>
void main() {
    int fun(int(*addpp)(int, int), int x, int y);//函數聲明
    int add(int i, int j);

    int ii=fun(add, 11, 12);//傳遞函數名和參數便可
    printf("輸出相加的值爲:%d", ii);
  }

//int (*addpp)(int,int);addpp=add;
int fun(int (*addpp)(int,int),int x,int y){
    int cc = (*addpp)(x, y);
    return cc;
}

int add(int i, int j) {
    return i + j;
}

返回指針的函數

#include<stdio.h>
void main() {
    int* add(int i, int j);
    int *p = add(10, 4);
    printf("輸出相加的值爲:%d", *p);
  }

int* add(int i, int j) {
    int aa = i + j;
    return &aa;//返回地址
}

指針數組

一個數組其所有元素都存放着指針,就是指針數組【int * p[5];】

#include<stdio.h>
void main() {
    //指針數組
    char * p[] = { "dong1","xiao2","dong3","dong4" };
    printf("%s\n", p[2]);
  }

進階版

#include<stdio.h>
void main() {
    //指針數組(字符串)
    char * p[] = { "dong1","xiao2","dong3","dong4" };
    char **pp;
    pp = p;
    printf("%s\n", *(pp+1));//轉換一次就能夠拿到對應字符串的首地址經過%s打印

    //指針數組(整數)
    int a[5]= {10,11,12,13 };
    int * ip[] = { &a[0],&a[1],&a[2],&a[3],&a[4]};
    int **ppp = ip;
    printf("%d\n", *(*ppp+1));//轉換第一次獲得存儲的指針,再次轉換獲得值
  }

錯誤示範

一、

int *p=10; //等同於:int *p; p=10;

分析:非法操做,內存地址不能用戶自定義。10至關於一個內存地址,該內存地址的值不肯定且也不明確該地址是否能夠直接訪問,正確的應該是使用【&變量名】獲得內存地址。

 

二、

int f = 12.3;
int *p;
*p = &f;  //錯誤1
int ff = &f; //錯誤2

分析:指針(地址)必須賦值給指針變量

相關文章
相關標籤/搜索