C/C++学习之路_六: 指针
生活随笔
收集整理的這篇文章主要介紹了
C/C++学习之路_六: 指针
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
C/C++學習之路_第六章: 指針
目錄
1. 概述
1. 內存
內存含義:
內存是溝通CPU與硬盤的橋梁:
2. 物理存儲器和存儲地址空間
有關內存的兩個概念:物理存儲器和存儲地址空間。
物理存儲器:實際存在的具體存儲器芯片。
存儲地址空間:對存儲器編碼的范圍,我們在軟件上常說的內存是指這一層含義。
3. 內存地址
4. 指針和指針變量
2. 指針基礎知識
1. 指針變量的定義和使用
2. 通過指針間接修改變量的值
int a = 0;int b = 11;int *p = &a;*p = 100;printf("a = %d, *p = %d\n", a, *p);p = &b;*p = 22;printf("b = %d, *p = %d\n", b, *p);3. 指針大小
4. 野指針和空指針
5. 萬能指針void *
6. const修飾的指針變量
3. 指針和數組
1. 數組名
2. 指針操作數組元素
3. 指針加減運算
1. 加法運算
2. 減法運算
4. 指針數組
4. 多級指針
5. 指針和函數
1. 函數形參改變實參的值
void swap1(int x, int y) {int tmp;tmp = x;x = y;y = tmp;printf("x = %d, y = %d\n", x, y); }void swap2(int *x, int *y) {int tmp;tmp = *x;*x = *y;*y = tmp; }int main() {int a = 3;int b = 5;swap1(a, b); //值傳遞printf("a = %d, b = %d\n", a, b);a = 3;b = 5;swap2(&a, &b); //地址傳遞printf("a2 = %d, b2 = %d\n", a, b);return 0; }2. 數組名做函數參數
3. 指針做為函數的返回值
int a = 10;int *getA() {return &a; }int main() {*(getA()) = 111;printf("a = %d\n", a);return 0; }6. 指針和字符串
1. 字符指針
char str[] = "hello world";char *p = str;*p = 'm';p++;*p = 'i';printf("%s\n", str);p = "mike jiang";printf("%s\n", p);char *q = "test";printf("%s\n", q);2. 字符指針做函數參數
void mystrcat(char *dest, const char *src) {int len1 = 0;int len2 = 0;while (dest[len1]) {len1++;}while (src[len2]) {len2++;}int i;for (i = 0; i < len2; i++) {dest[len1 + i] = src[i];} }int main() {char dst[100] = "hello mike";char src[] = "123456";mystrcat(dst, src);printf("dst = %s\n", dst);return 0; }3. const修飾的指針變量
int main() {//const修飾一個變量為只讀const int a = 10;//a = 100; //err//指針變量, 指針指向的內存, 2個不同概念char buf[] = "aklgjdlsgjlkds";//從左往右看,跳過類型,看修飾哪個字符//如果是*, 說明指針指向的內存不能改變//如果是指針變量,說明指針的指向不能改變,指針的值不能修改const char *p = buf;// 等價于上面 char const *p1 = buf;//p[1] = '2'; //errp = "agdlsjaglkdsajgl"; //okchar *const p2 = buf;p2[1] = '3';//p2 = "salkjgldsjaglk"; //err//p3為只讀,指向不能變,指向的內存也不能變const char *const p3 = buf;return 0; }4. 字符指針數組
char *num[3] = {"heihei", "haha", "xixi"};printf("%c\n", *num[0]); //num[0]表示"heihei"char數組首元素地址,*num[0]='h'printf("%s\n", num[0]); //num[0]表示"heihei"char數組首元素地址,可以輸出"heihei"//num[1]表示"haha"char數組首元素地址,num[1]+1表示a的地址,*(num[1]+1)輸出char'a'printf("%c\n", *(num[1] + 1));//定義一個指針p保存num數組首元素的地址,&num[0] numchar **p = num; //p表示數組首元素地址,num[0],即"heihei"的地址for (int i = 0; i < 3; i++) {//printf("%s\n",*(p+i));printf("%s\n", p[i]); // 打印數組元素}// p+1表示"haha"的地址,即num[1]的地址// *(p + 1)表示num[1]數組首元素地址,即'h',//*(p + 1) + 3表示'h'的地址后移3個的地址,即'a'的地址//*(*(p + 1) + 3)表示用'a'的地址,取char 'a'printf("%c\n", *(*(p + 1) + 3));// *(p[1]+3) == p[1][3]5. 指針數組做為main函數的形參
int main(int argc, char *argv[]);6. 項目開發常用字符串應用
1. strstr中的while和do-while模型
1. while模型
char *p = "11abcd111122abcd333abcd3322abcd3333322qqq";int n = 0;while ((p = strstr(p, "abcd")) != NULL) {//能進來,肯定有匹配的子串//重新設置起點位置p = p + strlen("abcd");n++;if (*p == 0) { //如果到結束符break;}}printf("n = %d\n", n);2. do-while模型
char *p = "11abcd111122abcd333abcd3322abcd3333322qqq";int n = 0;do {p = strstr(p, "abcd");if (p != NULL) {n++; //累計個數//重新設置查找的起點p = p + strlen("abcd");} else { //如果沒有匹配的字符串,跳出循環break;}} while (*p != 0); //如果沒有到結尾printf("n = %d\n", n);2. 兩頭堵模型
3. 字符串反轉模型(逆置)
int inverse(char *p) {if (p == NULL) {return -1;}char *str = p;int begin = 0;int end = strlen(str) - 1;char tmp;while (begin < end) {//交換元素tmp = str[begin];str[begin] = str[end];str[end] = tmp;begin++; //往右移動位置end--; //往左移動位置}return 0; }int main(void) {//char *str = "abcdefg"; //文件常量區,內容不允許修改char str[] = "abcdef";int ret = inverse(str);if (ret != 0) {return ret;}printf("str ========== %s\n", str);return 0; }7. 字符串處理函數
1. strcpy()
#include <string.h> char *strcpy(char *dest, const char *src); 功能:把src所指向的字符串復制到dest所指向的空間中,'\0'也會拷貝過去 參數:dest:目的字符串首地址src:源字符首地址 返回值:成功:返回dest字符串的首地址失敗:NULL2. strncpy()
#include <string.h> char *strncpy(char *dest, const char *src, size_t n); 功能:把src指向字符串的前n個字符復制到dest所指向的空間中,是否拷貝結束符看指定的長度是否包含'\0'。 參數:dest:目的字符串首地址src:源字符首地址n:指定需要拷貝字符串個數 返回值:成功:返回dest字符串的首地址失敗:NULL3. strcat()
#include <string.h> char *strcat(char *dest, const char *src); 功能:將src字符串連接到dest的尾部,‘\0’也會追加過去 參數:dest:目的字符串首地址src:源字符首地址 返回值:成功:返回dest字符串的首地址失敗:NULLchar str[20] = "123";char *src = "hello world";printf("%s\n", strcat(str, src));4. strcmp()
#include <string.h> int strcmp(const char *s1, const char *s2); 功能:比較 s1 和 s2 的大小,比較的是字符ASCII碼大小。 參數:s1:字符串1首地址s2:字符串2首地址 返回值:相等:0大于:>0 在不同操作系統strcmp結果會不同 返回ASCII差值小于:<0char *str1 = "hello world";char *str2 = "hello mike";if (strcmp(str1, str2) == 0) {printf("str1==str2\n");} else if (strcmp(str1, str2) > 0) {printf("str1>str2\n");} else {printf("str1<str2\n");}5. strncmp()
#include <string.h> int strncmp(const char *s1, const char *s2, size_t n); 功能:比較 s1 和 s2 前n個字符的大小,比較的是字符ASCII碼大小。 參數:s1:字符串1首地址s2:字符串2首地址n:指定比較字符串的數量 返回值:相等:0大于: > 0小于: < 0char *str1 = "hello world";char *str2 = "hello mike";if (strncmp(str1, str2, 5) == 0) {printf("str1==str2\n");} else if (strcmp(str1, "hello world") > 0) {printf("str1>str2\n");} else {printf("str1<str2\n");}6. sprintf()
#include <stdio.h> int sprintf(char *str, const char *format, ...); 功能:根據參數format字符串來轉換并格式化數據,然后將結果輸出到str指定的空間中,直到出現字符串結束符 '\0' 為止。 參數:str:字符串首地址format:字符串格式,用法和printf()一樣 返回值:成功:實際格式化的字符個數失敗: - 1char dst[100] = { 0 };int a = 10;char src[] = "hello world";printf("a = %d, src = %s", a, src);printf("\n");int len = sprintf(dst, "a = %d, src = %s", a, src);printf("dst = \" %s\"\n", dst);printf("len = %d\n", len);7. sscanf
#include <stdio.h> int sscanf(const char *str, const char *format, ...); 功能:從str指定的字符串讀取數據,并根據參數format字符串來轉換并格式化數據。 參數:str:指定的字符串首地址format:字符串格式,用法和scanf()一樣 返回值:成功:參數數目,成功轉換的值的個數失敗: - 1int year =0 ;int month = 0;int day = 0;char buf[1024] = "beijing:2018:t:10:20";//scanf("%d:%d:%d",&year,&month,&day);//從鍵盤按照相應的格式獲取數據sscanf(buf, "beijing:%d:t:%d:%d", &year, &month, &day);//從buf中按照`相應的格式獲取數據printf("%d %d %d\n",year,month,day);8. strchr()
#include <string.h> char *strchr(const char *s, int c); 功能:在字符串s中查找字母c出現的位置 參數:s:字符串首地址c:匹配字母(字符) 返回值:成功:返回第一次出現的c地址失敗:NULLchar src[] = "ddda123abcd";char *p = strchr(src, 'a');printf("p = %s\n", p);9. strstr()
#include <string.h> char *strstr(const char *haystack, const char *needle); 功能:在字符串haystack中查找字符串needle出現的位置 參數:haystack:源字符串首地址needle:匹配字符串首地址 返回值:成功:返回第一次出現的needle地址失敗:NULLchar src[] = "ddddabcd123abcd333abcd";char *p = strstr(src, "abcd");printf("p = %s\n", p);10. strtok()
#include <string.h> char *strtok(char *str, const char *delim); 功能:來將字符串分割成一個個片段。當strtok()在參數s的字符串中發現參數delim中包含的分割字符時, 則會將該字符改為\0 字符,當連續出現多個時只替換第一個為\0。 參數:str:指向欲分割的字符串delim:為分割字符串中包含的所有字符 返回值:成功:分割后字符串首地址失敗:NULL11. atoi()
#include <stdlib.h> int atoi(const char *nptr); 功能:atoi()會掃描nptr字符串,跳過前面的空格字符,直到遇到數字或正負號才開始做轉換,而遇到非數字或字符串結束符('\0')才結束轉換,并將結果返回返回值。 參數:nptr:待轉換的字符串 返回值:成功轉換后整數7. 指針小結
| int i | 定義整形變量 |
| int *p | 定義一個指向int的指針變量 |
| int a[10] | 定義一個有10個元素的數組,每個元素類型為int |
| int *p[10] | 定義一個有10個元素的數組,每個元素類型為int* |
| int func() | 定義一個函數,返回值為int型 |
| int *func() | 定義一個函數,返回值為int *型 |
| int **p | 定義一個指向int的指針的指針,二級指針 |
總結
以上是生活随笔為你收集整理的C/C++学习之路_六: 指针的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: sync.Map低层工作原理详解
- 下一篇: C/C++学习之路_七: 内存管理