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