總有人說c語言的三座大山及,指針,函數,數組,在學習當中給我們帶來了很大的困擾,對抽象問題無法了解,好,很高興我翻越了其中一座山,接下來我會分享這三個問題的學習方法,每個章節後面都會附有練習題,需要着重強調的是,題一定要自己想辦法敲一下,對概念的了解和發現問題有很大的幫助,好了,祝大家盡快渡過難關!!!
-
指針的定義:
格式: <存儲類型> <資料類型> * 變量名稱;
eg: char * pc;
==》資料類型用于辨別目标存儲空間大小
==》* 表示該類型是一個指針
==》變量名稱則用于存儲位址的值。
2 “&”用以擷取一個變量的位址,“ * ”取出一個位址内的值
px+n指針向下偏移一個單元,不改變指針的值,
px++改變指針的值
注意:數組名稱是常量,不能指派(++用的時候會報錯)
if(pa = NULL) :pa變量指派,且值為假,不執行
if(pa == NULL):邏輯判斷,看pa内部是不是為空
3.指針初始化
char * pc = NULL;
作用 避免野指針,沒有任何初始化的指針。
指針的變量位址初始化: char *pc = &c;
用其他指針初始化: char *pc = &c;
用絕對位址初始化:char *pc = 0x23423423; 注意:該位址必須是可以通路的位址。一般不建議采用
5.數組與指針
-
相同點啊a[i] = pa[i]
(pa + i) =(a+i)
a[i] = pa[i] = *(pa+i) = *(a+i);
數組名稱是一個指針常量,不允許改變。
pa指針是指針變量,可以随時修改。
char buff[] ="aasdfadsf"; ===>buff是本地記憶體
137 char *pa = &buff[0]; ==>pa 指向本地記憶體,可以修改。
138 char *pb = "asdfadf"; ==>pb 指向靜态常量區資料,不允許修改。
char buf[5] = {"a,b,c,d,e,f};
char *p = "a,b,c,d,e,f"
差別: 記住所有帶雙引号的字元串都存儲在靜态常量區,前者可操作,後者不可操作,因為前者是把字元常量區的字元串拿到了棧區,變成了可操作數,而後者是直接定義了一個指針,指向了文本區,所有靜态常量區的都是隻讀的!!!
面試題:
141 int main()
142 {
143 int a[5]= {1,2,3,4,5};:
144 int *p = (int *)(&a+1);
145 printf("%d %d \n",*(a+1),*(p-1));
146 }
列印結果 2,5
*(a+1) :首位址向下偏移一個int類型機關,到了a[1]的位置
(&a+1) :&a為取數組名的位址,即為整個數組的位址,它的類型為數組類型,指針偏移到數組後面的元素上-1剛好到數組最後一個元素即5
練習題:
1、輸入一行文字,找出其中大寫字母,小寫字母,空格,數字以其他的字元各有多少
int main(int argc, char *argv[])
{
char buf[N] = {0};
char * pf = &buf[0];
int da = 0,xiao = 0,kong = 0,num = 0,other = 0;
printf("請輸入字元串以檢測\n");
gets(pf);
printf("%s\n",pf);
while(*pf != '\0')
{
if(*pf >= 'A' && *pf <= 'Z')
da++;
else if((*pf >= 'a') && (*pf <= 'z'))
xiao++;
else if(*pf == ' ')
kong++;
else if((*pf >= '0') && (*pf <= '9'))
num++;
else
other++;
pf++;
}printf("大寫字母;%d\n小寫字母:%d\n空格:%d\n數字%d\n其他%d\n",da,xiao,kong,num,other);
return 0;
}
2、輸入一個字元串,用指針求出字元串的長度。
int main(int argc, char *argv[])
{
char buf[N] = {0};
char * pf = &buf[0];
int count = 0;
printf("請輸入字元串以檢測\n");
scanf("%s",pf);
while(*pf++ != '\0');
printf("%ld\n",(long int)pf-(long int)&buf[0]-1);
return 0;
}
3、 main()
{
int a[5]={1,2,3,4,5};
int ptr=(int )(&a+1);
printf("%d,%d",(a+1),(ptr-1));
}
輸出結果是什麼?
2,5,上面概念處講過了
4、請問以下代碼有什麼問題:
int main()
{
char a;
char *str=&a;
strcpy(str,“hello”);
printf(str);
return 0;
}
main函數内部第一行和第三行沖突,定義的是一個字元變量,而非一個字元串常量
5、 char* s=“AAA”;
printf("%s",s);
s[0]=‘B’;
printf("%s",s);
有什麼錯?
第一行的意思為把字元串常量存放在靜态常量區,不可修改
6、編寫一個程式實作功能:将兩個字元串合并為一個字元串并且輸出,用指針實作。
char str1[20]={“Hello ”}, str2[20]={“World ”};
int main(int argc,char *argv[])
{
char str1[20] = {"Hello"};
char str2[20] = {"World"};
char *p1 = str1;
char *p2 = str2;
while(*p1 != '\0'){
p1++;
}
//p1--;
while(*p2 != '\0'){
*(p1++) = *(p2++);
}
*p1 = '\0';
p1 = str1;
p2 = str2;
printf("str1 = %s\nstr2 = %s\n",p1,p2); //在main函數的時候,不可以拿p1,p2直接列印值,重新定義一個函數就可以?
???
return 0;
}
7、編寫一個程式實作功能:将字元串”Computer Secience”賦給一個字元數組,然後從第一個字母開始間隔的輸>出該串,用指針完成。
int main(int argc,char *argv[])
{
char src[128] = {"Computer Secience"};
char dest[128] = {0};
char *ps = src;
char *pd = dest;
while(*ps != '\0'){
*pd++ = *ps++;
*pd++ = ' ';
}
printf("dest = %s\n",dest);
return 0;
}
8、使用C語言實作字元串中子字元串的替換
描述:編寫一個字元串替換函數,如函數名為 StrReplace(char* strSrc, char* strFind, char* strReplace)>,strSrc為原字元串,strFind是待替換的字元串,strReplace為替換字元串。
舉個直覺的例子吧,如:“ABCDEFGHIJKLMNOPQRSTUVWXYZ”這個字元串,把其中的“RST”替換為“ggg”這個字元串,>結果就變成了:
ABCDEFGHIJKLMNOPQgggUVWXYZ
void StrReplace(char * strSrc,char *strFind,char *strReplace)
{
char *ps = strSrc;
char *pf = strFind;
char *pr = strReplace;
char cat[128] = {0};
char *pc = cat;
char *p1 = NULL;char *p2 = NULL;char *p3 = NULL;
while(*ps++ != '\0')
{
if( (*(ps) == *(pf)) &&
(*(ps+1) == *(pf+1)) &&
( *(ps+2) == *(pf+2) ))
{
#if 0
p1 = ps;
while(*p1 != '\0')
{
*pc++ = *p1++;
}
#endif //這段沒作用
#if 0
*ps = *pr;
*(ps+1) = *(pr+1);
*(ps+2) = *(pr+2);
printf("find it\n");
#endif
while(*pr != '\0')
{
*ps++ = *pr++;
}
}
}
strcat(cat,strSrc);
}
int main(int argc,char *argv[])
{
char src[128] = {"ABCDEFGHIJKLMNOPQRSTUVWXYZ"};
char dest[128] = {"RST"};
char place[128] = {"ggg"};
printf("替換前:%s\n",src);
StrReplace(src,dest,place);
printf("替換後:%s\n",src);
return 0;
}